diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-09-20 14:18:08 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-09-20 14:18:08 +0300 |
commit | 5afcbe03ead9ada87621888a31a62652b10a7e4f (patch) | |
tree | 9918b67a0d0f0bafa6542e839a8be37adf73102d /app/assets/javascripts/issuable | |
parent | c97c0201564848c1f53226fe19d71fdcc472f7d0 (diff) |
Add latest changes from gitlab-org/gitlab@16-4-stable-eev16.4.0-rc42
Diffstat (limited to 'app/assets/javascripts/issuable')
10 files changed, 134 insertions, 265 deletions
diff --git a/app/assets/javascripts/issuable/components/csv_export_modal.vue b/app/assets/javascripts/issuable/components/csv_export_modal.vue index c1de507cd80..fd279a6a451 100644 --- a/app/assets/javascripts/issuable/components/csv_export_modal.vue +++ b/app/assets/javascripts/issuable/components/csv_export_modal.vue @@ -47,7 +47,7 @@ export default { href: this.exportCsvPath, variant: 'confirm', 'data-method': 'post', - 'data-qa-selector': `export_issues_button`, + 'data-testid': 'export-issues-button', 'data-track-action': 'click_button', 'data-track-label': this.dataTrackLabel, }, @@ -78,7 +78,7 @@ export default { :action-cancel="$options.actionCancel" body-class="gl-p-0!" :title="exportText" - data-qa-selector="export_issuable_modal" + data-testid="export-issuable-modal" > <div class="gl-justify-content-start gl-align-items-center gl-p-4 gl-border-b-solid gl-border-1 gl-border-gray-50" diff --git a/app/assets/javascripts/issuable/components/csv_import_export_buttons.vue b/app/assets/javascripts/issuable/components/csv_import_export_buttons.vue index 872e1d4269d..8e2ed63613d 100644 --- a/app/assets/javascripts/issuable/components/csv_import_export_buttons.vue +++ b/app/assets/javascripts/issuable/components/csv_import_export_buttons.vue @@ -76,7 +76,6 @@ export default { v-if="showExportButton" v-gl-modal="exportModalId" data-testid="export-as-csv-button" - data-qa-selector="export_as_csv_button" :item="dropdownItems.exportAsCSV" /> <gl-disclosure-dropdown-item @@ -88,7 +87,6 @@ export default { <gl-disclosure-dropdown-item v-if="showImportButton && canEdit" data-testid="import-from-jira-link" - data-qa-selector="import_from_jira_link" :item="dropdownItems.importFromJIRA" /> diff --git a/app/assets/javascripts/issuable/components/issuable_header_warnings.vue b/app/assets/javascripts/issuable/components/issuable_header_warnings.vue deleted file mode 100644 index a0854be099d..00000000000 --- a/app/assets/javascripts/issuable/components/issuable_header_warnings.vue +++ /dev/null @@ -1,87 +0,0 @@ -<script> -import { GlIcon, GlTooltipDirective } from '@gitlab/ui'; -// eslint-disable-next-line no-restricted-imports -import { mapGetters } from 'vuex'; -import { sprintf, __ } from '~/locale'; -import { TYPE_ISSUE, TYPE_MERGE_REQUEST, WORKSPACE_PROJECT } from '~/issues/constants'; -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; -import ConfidentialityBadge from '~/vue_shared/components/confidentiality_badge.vue'; - -const noteableTypeText = { - issue: __('issue'), - merge_request: __('merge request'), -}; - -export default { - TYPE_ISSUE, - WORKSPACE_PROJECT, - components: { - GlIcon, - ConfidentialityBadge, - }, - directives: { - GlTooltip: GlTooltipDirective, - }, - mixins: [glFeatureFlagMixin()], - inject: ['hidden'], - computed: { - ...mapGetters(['getNoteableData']), - isLocked() { - return this.getNoteableData.discussion_locked; - }, - isConfidential() { - return this.getNoteableData.confidential; - }, - isMergeRequest() { - return this.getNoteableData.targetType === TYPE_MERGE_REQUEST; - }, - warningIconsMeta() { - return [ - { - iconName: 'lock', - visible: this.isLocked, - dataTestId: 'locked', - tooltip: sprintf(__('This %{issuable} is locked. Only project members can comment.'), { - issuable: noteableTypeText[this.getNoteableData.targetType], - }), - }, - { - iconName: 'spam', - visible: this.hidden, - dataTestId: 'hidden', - tooltip: sprintf(__('This %{issuable} is hidden because its author has been banned'), { - issuable: noteableTypeText[this.getNoteableData.targetType], - }), - }, - ]; - }, - }, -}; -</script> - -<template> - <div class="gl-display-inline-block"> - <confidentiality-badge - v-if="isConfidential" - data-testid="confidential" - :workspace-type="$options.WORKSPACE_PROJECT" - :issuable-type="$options.TYPE_ISSUE" - /> - <template v-for="meta in warningIconsMeta"> - <div - v-if="meta.visible" - :key="meta.iconName" - v-gl-tooltip.bottom - :data-testid="meta.dataTestId" - :title="meta.tooltip || null" - :class="{ - 'gl-mr-3 gl-mt-2 gl-display-flex gl-justify-content-center gl-align-items-center': isMergeRequest, - 'gl-display-inline-block': !isMergeRequest, - }" - class="issuable-warning-icon" - > - <gl-icon :name="meta.iconName" class="icon" /> - </div> - </template> - </div> -</template> diff --git a/app/assets/javascripts/issuable/components/issue_assignees.vue b/app/assets/javascripts/issuable/components/issue_assignees.vue index d8cbc45684b..2181b4e1a40 100644 --- a/app/assets/javascripts/issuable/components/issue_assignees.vue +++ b/app/assets/javascripts/issuable/components/issue_assignees.vue @@ -89,7 +89,7 @@ export default { :img-size="iconSize" class="js-no-trigger author-link" tooltip-placement="bottom" - data-qa-selector="assignee_link" + data-testid="assignee-link" > <span class="js-assignee-tooltip"> <span class="bold d-block">{{ s__('Label|Assignee') }}</span> {{ assignee.name }} @@ -101,7 +101,7 @@ export default { v-gl-tooltip.bottom :title="assigneesCounterTooltip" class="avatar-counter" - data-qa-selector="avatar_counter_content" + data-testid="avatar-counter-content" >{{ assigneeCounterLabel }}</span > </div> diff --git a/app/assets/javascripts/issuable/components/issue_milestone.vue b/app/assets/javascripts/issuable/components/issue_milestone.vue index c7da3e59098..3340ef2338c 100644 --- a/app/assets/javascripts/issuable/components/issue_milestone.vue +++ b/app/assets/javascripts/issuable/components/issue_milestone.vue @@ -42,7 +42,8 @@ export default { milestoneDatesAbsolute() { if (this.milestoneDue) { return `(${dateInWords(this.milestoneDue)})`; - } else if (this.milestoneStart) { + } + if (this.milestoneStart) { return `(${dateInWords(this.milestoneStart)})`; } return ''; diff --git a/app/assets/javascripts/issuable/components/status_badge.vue b/app/assets/javascripts/issuable/components/status_badge.vue new file mode 100644 index 00000000000..949fb3c1ce5 --- /dev/null +++ b/app/assets/javascripts/issuable/components/status_badge.vue @@ -0,0 +1,98 @@ +<script> +import { GlBadge, GlIcon } from '@gitlab/ui'; +import { __ } from '~/locale'; +import { + STATUS_CLOSED, + STATUS_LOCKED, + STATUS_MERGED, + STATUS_OPEN, + TYPE_EPIC, + TYPE_ISSUE, + TYPE_MERGE_REQUEST, +} from '~/issues/constants'; + +const badgePropertiesMap = { + [TYPE_EPIC]: { + [STATUS_OPEN]: { + icon: 'epic', + text: __('Open'), + variant: 'success', + }, + [STATUS_CLOSED]: { + icon: 'epic-closed', + text: __('Closed'), + variant: 'info', + }, + }, + [TYPE_ISSUE]: { + [STATUS_OPEN]: { + icon: 'issues', + text: __('Open'), + variant: 'success', + }, + [STATUS_CLOSED]: { + icon: 'issue-closed', + text: __('Closed'), + variant: 'info', + }, + [STATUS_LOCKED]: { + icon: 'issues', + text: __('Open'), + variant: 'success', + }, + }, + [TYPE_MERGE_REQUEST]: { + [STATUS_OPEN]: { + icon: 'merge-request-open', + text: __('Open'), + variant: 'success', + }, + [STATUS_CLOSED]: { + icon: 'merge-request-close', + text: __('Closed'), + variant: 'danger', + }, + [STATUS_MERGED]: { + icon: 'merge', + text: __('Merged'), + variant: 'info', + }, + [STATUS_LOCKED]: { + icon: 'merge-request-open', + text: __('Open'), + variant: 'success', + }, + }, +}; + +export default { + components: { + GlBadge, + GlIcon, + }, + props: { + issuableType: { + type: String, + required: false, + default: '', + }, + state: { + type: String, + required: false, + default: null, + }, + }, + computed: { + badgeProperties() { + return badgePropertiesMap[this.issuableType][this.state]; + }, + }, +}; +</script> + +<template> + <gl-badge :variant="badgeProperties.variant" :aria-label="badgeProperties.text"> + <gl-icon :name="badgeProperties.icon" /> + <span class="gl-display-none gl-sm-display-block gl-ml-2">{{ badgeProperties.text }}</span> + </gl-badge> +</template> diff --git a/app/assets/javascripts/issuable/components/status_box.vue b/app/assets/javascripts/issuable/components/status_box.vue deleted file mode 100644 index 0d7d0f020dd..00000000000 --- a/app/assets/javascripts/issuable/components/status_box.vue +++ /dev/null @@ -1,146 +0,0 @@ -<script> -import { GlBadge, GlIcon } from '@gitlab/ui'; -import Vue from 'vue'; -import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; -import { fetchPolicies } from '~/lib/graphql'; -import { __ } from '~/locale'; -import { - STATUS_CLOSED, - STATUS_OPEN, - TYPE_ISSUE, - TYPE_MERGE_REQUEST, - TYPE_EPIC, -} from '~/issues/constants'; - -export const badgeState = Vue.observable({ - state: '', - updateStatus: null, -}); - -const CLASSES = { - opened: 'issuable-status-badge-open', - locked: 'issuable-status-badge-open', - closed: 'issuable-status-badge-closed', - merged: 'issuable-status-badge-merged', -}; - -const ICONS = { - [TYPE_EPIC]: { - opened: 'epic', - closed: 'epic-closed', - }, - [TYPE_ISSUE]: { - opened: 'issues', - locked: 'issues', - closed: 'issue-closed', - }, - [TYPE_MERGE_REQUEST]: { - opened: 'merge-request-open', - locked: 'merge-request-open', - closed: 'merge-request-close', - merged: 'merge', - }, -}; - -const STATUS = { - opened: __('Open'), - locked: __('Open'), - closed: __('Closed'), - merged: __('Merged'), -}; - -export default { - components: { - GlBadge, - GlIcon, - }, - mixins: [glFeatureFlagMixin()], - inject: { - query: { default: null }, - projectPath: { default: null }, - iid: { default: null }, - }, - props: { - initialState: { - type: String, - required: false, - default: null, - }, - issuableType: { - type: String, - required: false, - default: '', - }, - }, - data() { - if (!this.iid) return { state: this.initialState }; - - if (this.initialState && !badgeState.state) { - badgeState.state = this.initialState; - } - - return badgeState; - }, - computed: { - badgeClass() { - return [ - CLASSES[this.state], - { - 'gl-vertical-align-bottom': this.issuableType === TYPE_MERGE_REQUEST, - }, - ]; - }, - badgeVariant() { - if (this.state === STATUS_OPEN) { - return 'success'; - } else if (this.state === STATUS_CLOSED) { - return this.issuableType === TYPE_MERGE_REQUEST ? 'danger' : 'info'; - } - return 'info'; - }, - badgeText() { - return STATUS[this.state]; - }, - badgeIcon() { - const type = this.issuableType || TYPE_MERGE_REQUEST; - return ICONS[type][this.state]; - }, - }, - created() { - if (!badgeState.updateStatus) { - badgeState.updateStatus = this.fetchState; - } - }, - beforeDestroy() { - if (badgeState.updateStatus && this.query) { - badgeState.updateStatus = null; - } - }, - methods: { - async fetchState() { - const { data } = await this.$apollo.query({ - query: this.query, - variables: { - projectPath: this.projectPath, - iid: this.iid, - }, - fetchPolicy: fetchPolicies.NO_CACHE, - }); - - badgeState.state = data?.workspace?.issuable?.state; - }, - }, -}; -</script> - -<template> - <gl-badge - class="issuable-status-badge gl-mr-3 gl-align-self-center" - :class="badgeClass" - :variant="badgeVariant" - :aria-label="badgeText" - > - <gl-icon :name="badgeIcon" class="gl-badge-icon" /> - <span class="gl-display-none gl-sm-display-block gl-ml-2">{{ badgeText }}</span> - </gl-badge> -</template> diff --git a/app/assets/javascripts/issuable/index.js b/app/assets/javascripts/issuable/index.js index acc0161bf6a..40f92763b29 100644 --- a/app/assets/javascripts/issuable/index.js +++ b/app/assets/javascripts/issuable/index.js @@ -5,7 +5,6 @@ import Sidebar from '~/right_sidebar'; import { getSidebarOptions } from '~/sidebar/mount_sidebar'; import CsvImportExportButtons from './components/csv_import_export_buttons.vue'; import IssuableByEmail from './components/issuable_by_email.vue'; -import IssuableHeaderWarnings from './components/issuable_header_warnings.vue'; import issuableBulkUpdateActions from './issuable_bulk_update_actions'; import IssuableBulkUpdateSidebar from './issuable_bulk_update_sidebar'; import IssuableContext from './issuable_context'; @@ -97,24 +96,6 @@ export function initIssuableByEmail() { }); } -export function initIssuableHeaderWarnings(store) { - const el = document.getElementById('js-issuable-header-warnings'); - - if (!el) { - return null; - } - - const { hidden } = el.dataset; - - return new Vue({ - el, - name: 'IssuableHeaderWarningsRoot', - store, - provide: { hidden: parseBoolean(hidden) }, - render: (createElement) => createElement(IssuableHeaderWarnings), - }); -} - export function initIssuableSidebar() { const el = document.querySelector('.js-sidebar-options'); diff --git a/app/assets/javascripts/issuable/issuable_context.js b/app/assets/javascripts/issuable/issuable_context.js index 8c2e2a5df67..ef49bd29a40 100644 --- a/app/assets/javascripts/issuable/issuable_context.js +++ b/app/assets/javascripts/issuable/issuable_context.js @@ -8,6 +8,29 @@ export default class IssuableContext { this.userSelect = new UsersSelect(currentUser); this.reviewersSelect = new UsersSelect(currentUser, '.js-reviewer-search'); + this.reviewersSelect.dropdowns.forEach((glDropdownInstance) => { + const jQueryWrapper = glDropdownInstance.dropdown; + const domElement = jQueryWrapper[0]; + const content = domElement.querySelector('.dropdown-content'); + const loader = domElement.querySelector('.dropdown-loading'); + const spinner = loader.querySelector('.gl-spinner-container'); + const realParent = loader.parentNode; + + domElement.classList.add('non-blocking-loader'); + spinner.classList.remove('gl-mt-7'); + spinner.classList.add('gl-mt-2'); + + jQueryWrapper.on('shown.bs.dropdown', () => { + glDropdownInstance.filterInput.focus(); + }); + jQueryWrapper.on('toggle.on.loading.gl.dropdown filtering.gl.dropdown', () => { + content.appendChild(loader); + }); + jQueryWrapper.on('done.remote.loading.gl.dropdown done.filtering.gl.dropdown', () => { + realParent.appendChild(loader); + }); + }); + $('.issuable-sidebar .inline-update').on('change', 'select', function onClickSelect() { return $(this).submit(); }); diff --git a/app/assets/javascripts/issuable/popover/components/issue_popover.vue b/app/assets/javascripts/issuable/popover/components/issue_popover.vue index 044a1bba7ad..12d76ec4b54 100644 --- a/app/assets/javascripts/issuable/popover/components/issue_popover.vue +++ b/app/assets/javascripts/issuable/popover/components/issue_popover.vue @@ -3,12 +3,13 @@ import { GlIcon, GlPopover, GlSkeletonLoader, GlTooltipDirective } from '@gitlab import query from 'ee_else_ce/issuable/popover/queries/issue.query.graphql'; import IssueDueDate from '~/boards/components/issue_due_date.vue'; import IssueMilestone from '~/issuable/components/issue_milestone.vue'; -import StatusBox from '~/issuable/components/status_box.vue'; -import { STATUS_CLOSED } from '~/issues/constants'; +import StatusBadge from '~/issuable/components/status_badge.vue'; +import { STATUS_CLOSED, TYPE_ISSUE } from '~/issues/constants'; import timeagoMixin from '~/vue_shared/mixins/timeago'; import WorkItemTypeIcon from '~/work_items/components/work_item_type_icon.vue'; export default { + TYPE_ISSUE, components: { GlIcon, GlPopover, @@ -16,7 +17,7 @@ export default { IssueDueDate, IssueMilestone, IssueWeight: () => import('ee_component/boards/components/issue_card_weight.vue'), - StatusBox, + StatusBadge, WorkItemTypeIcon, }, directives: { @@ -82,14 +83,14 @@ export default { <gl-skeleton-loader v-if="$apollo.queries.issue.loading" :height="15"> <rect width="250" height="15" rx="4" /> </gl-skeleton-loader> - <div v-else-if="showDetails" class="gl-display-flex gl-align-items-center"> - <status-box issuable-type="issue" :initial-state="issue.state" /> + <div v-else-if="showDetails" class="gl-display-flex gl-align-items-center gl-gap-2"> + <status-badge :issuable-type="$options.TYPE_ISSUE" :state="issue.state" /> <gl-icon v-if="issue.confidential" v-gl-tooltip name="eye-slash" :title="__('Confidential')" - class="gl-text-orange-500 gl-mr-2" + class="gl-text-orange-500" :aria-label="__('Confidential')" /> <span class="gl-text-secondary"> |