diff --git a/app/assets/javascripts/boards/components/board_content_sidebar.vue b/app/assets/javascripts/boards/components/board_content_sidebar.vue index 9bbb8a1a1b2edd03c43844707fbc832aadcfa300..ae7d82d439672d92abb665832328ddad6c6f88d4 100644 --- a/app/assets/javascripts/boards/components/board_content_sidebar.vue +++ b/app/assets/javascripts/boards/components/board_content_sidebar.vue @@ -15,6 +15,7 @@ import SidebarDateWidget from '~/sidebar/components/date/sidebar_date_widget.vue import SidebarSubscriptionsWidget from '~/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue'; import SidebarTodoWidget from '~/sidebar/components/todo_toggle/sidebar_todo_widget.vue'; import SidebarLabelsWidget from '~/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue'; +import { LabelType } from '~/vue_shared/components/sidebar/labels_select_widget/constants'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; export default { @@ -63,7 +64,7 @@ export default { 'groupPathForActiveIssue', 'projectPathForActiveIssue', ]), - ...mapState(['sidebarType', 'issuableType', 'isSettingLabels']), + ...mapState(['sidebarType', 'issuableType']), isIssuableSidebar() { return this.sidebarType === ISSUABLE; }, @@ -84,7 +85,10 @@ export default { }); }, attrWorkspacePath() { - return this.isGroupBoard ? this.groupPathForActiveIssue : undefined; + return this.isGroupBoard ? this.groupPathForActiveIssue : this.projectPathForActiveIssue; + }, + labelType() { + return this.isGroupBoard ? LabelType.group : LabelType.project; }, }, methods: { @@ -102,10 +106,8 @@ export default { this.setActiveBoardItemLabels({ iid: this.activeBoardItem.iid, projectPath: this.projectPathForActiveIssue, - addLabelIds: input.map((label) => getIdFromGraphQLId(label.id)), - removeLabelIds: this.activeBoardItem.labels - .filter((label) => !input.find((selected) => selected.id === label.id)) - .map((label) => label.id), + labelsIds: input.map((label) => getIdFromGraphQLId(label.id)), + labels: input, }); }, handleLabelRemove(input) { @@ -207,14 +209,13 @@ export default { :full-path="projectPathForActiveIssue" :allow-label-remove="allowLabelEdit" :allow-multiselect="true" - :selected-labels="activeBoardItem.labels" - :labels-select-in-progress="isSettingLabels" :footer-create-label-title="createLabelTitle" :footer-manage-label-title="manageLabelTitle" :labels-create-title="createLabelTitle" :labels-filter-base-path="projectPathForActiveIssue" :attr-workspace-path="attrWorkspacePath" :issuable-type="issuableType" + :label-type="labelType" @onLabelRemove="handleLabelRemove" @updateSelectedLabels="handleUpdateSelectedLabels" > diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js index ca993e75cf94d014a83852db5e5e89b496751dcd..30fcc390c926db616e8066c243ed3a8c2f887806 100644 --- a/app/assets/javascripts/boards/stores/actions.js +++ b/app/assets/javascripts/boards/stores/actions.js @@ -656,31 +656,43 @@ export default { }, setActiveIssueLabels: async ({ commit, getters }, input) => { - commit(types.SET_LABELS_LOADING, true); const { activeBoardItem } = getters; - const { data } = await gqlClient.mutate({ - mutation: issueSetLabelsMutation, - variables: { - input: { - iid: input.iid || String(activeBoardItem.iid), - addLabelIds: input.addLabelIds ?? [], - removeLabelIds: input.removeLabelIds ?? [], - projectPath: input.projectPath, + + if (!gon.features?.labelsWidget) { + const { data } = await gqlClient.mutate({ + mutation: issueSetLabelsMutation, + variables: { + input: { + iid: input.iid || String(activeBoardItem.iid), + labelsIds: input.labelsIds ?? [], + removeLabelIds: input.removeLabelIds ?? [], + projectPath: input.projectPath, + }, }, - }, - }); + }); - commit(types.SET_LABELS_LOADING, false); + if (data.updateIssue?.errors?.length > 0) { + throw new Error(data.updateIssue.errors); + } - if (data.updateIssue?.errors?.length > 0) { - throw new Error(data.updateIssue.errors); + commit(types.UPDATE_BOARD_ITEM_BY_ID, { + itemId: data.updateIssue?.issue?.id || activeBoardItem.id, + prop: 'labels', + value: data.updateIssue?.issue?.labels.nodes, + }); + } else { + let labels = input?.labels || []; + if (input.removeLabelIds) { + labels = activeBoardItem.labels.filter( + (label) => input.removeLabelIds[0] !== getIdFromGraphQLId(label.id), + ); + } + commit(types.UPDATE_BOARD_ITEM_BY_ID, { + itemId: activeBoardItem.id, + prop: 'labels', + value: labels, + }); } - - commit(types.UPDATE_BOARD_ITEM_BY_ID, { - itemId: data.updateIssue?.issue?.id || activeBoardItem.id, - prop: 'labels', - value: data.updateIssue.issue.labels.nodes, - }); }, setActiveItemSubscribed: async ({ commit, getters, state }, input) => { diff --git a/app/assets/javascripts/boards/stores/mutation_types.js b/app/assets/javascripts/boards/stores/mutation_types.js index 26b785932bbbebe94bd2b46bec93b15c02c046bf..928cece19f72a5f0645b09eb0ccc8258446ea972 100644 --- a/app/assets/javascripts/boards/stores/mutation_types.js +++ b/app/assets/javascripts/boards/stores/mutation_types.js @@ -28,7 +28,6 @@ export const ADD_BOARD_ITEM_TO_LIST = 'ADD_BOARD_ITEM_TO_LIST'; export const REMOVE_BOARD_ITEM_FROM_LIST = 'REMOVE_BOARD_ITEM_FROM_LIST'; export const SET_ACTIVE_ID = 'SET_ACTIVE_ID'; export const UPDATE_BOARD_ITEM_BY_ID = 'UPDATE_BOARD_ITEM_BY_ID'; -export const SET_LABELS_LOADING = 'SET_LABELS_LOADING'; export const SET_ASSIGNEE_LOADING = 'SET_ASSIGNEE_LOADING'; export const RESET_ISSUES = 'RESET_ISSUES'; export const REQUEST_GROUP_PROJECTS = 'REQUEST_GROUP_PROJECTS'; diff --git a/app/assets/javascripts/boards/stores/mutations.js b/app/assets/javascripts/boards/stores/mutations.js index d381c076c19b5e1a05aa77063b24268d8f6a5991..ef5b84b45751aed36537e129e37e1b05093a16ea 100644 --- a/app/assets/javascripts/boards/stores/mutations.js +++ b/app/assets/javascripts/boards/stores/mutations.js @@ -195,10 +195,6 @@ export default { Vue.set(state.boardItems[itemId], prop, value); }, - [mutationTypes.SET_LABELS_LOADING](state, isLoading) { - state.isSettingLabels = isLoading; - }, - [mutationTypes.SET_ASSIGNEE_LOADING](state, isLoading) { state.isSettingAssignees = isLoading; }, diff --git a/app/assets/javascripts/boards/stores/state.js b/app/assets/javascripts/boards/stores/state.js index 2a6605e687b613887b5c68a5b1d65ecd97d6c6bd..80c51c966d206346a5db91a8210557df2afeeab2 100644 --- a/app/assets/javascripts/boards/stores/state.js +++ b/app/assets/javascripts/boards/stores/state.js @@ -12,7 +12,6 @@ export default () => ({ listsFlags: {}, boardItemsByListId: {}, backupItemsList: [], - isSettingLabels: false, isSettingAssignees: false, pageInfoByListId: {}, boardItems: {}, diff --git a/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue b/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue index d5647619ea3dc7e9fe0cb8cf64537808c42cb540..4c08419bb8808df770ae51a61c5cf7f88ec230b1 100644 --- a/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue +++ b/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue @@ -11,6 +11,7 @@ import { toLabelGid } from '~/sidebar/utils'; import { DropdownVariant } from '~/vue_shared/components/sidebar/labels_select_vue/constants'; import LabelsSelect from '~/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue'; import LabelsSelectWidget from '~/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue'; +import { LabelType } from '~/vue_shared/components/sidebar/labels_select_widget/constants'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; const mutationMap = { @@ -48,6 +49,7 @@ export default { return { isLabelsSelectInProgress: false, selectedLabels: this.initiallySelectedLabels, + LabelType, }; }, methods: { @@ -154,13 +156,11 @@ export default { :footer-manage-label-title="__('Manage project labels')" :labels-create-title="__('Create project label')" :labels-filter-base-path="projectIssuesPath" - :labels-select-in-progress="isLabelsSelectInProgress" - :selected-labels="selectedLabels" :variant="$options.variant" :issuable-type="issuableType" + :attr-workspace-path="fullPath" + :label-type="LabelType.project" data-qa-selector="labels_block" - @onLabelRemove="handleLabelRemove" - @updateSelectedLabels="handleUpdateSelectedLabels" > {{ __('None') }} </labels-select-widget> diff --git a/app/assets/javascripts/sidebar/constants.js b/app/assets/javascripts/sidebar/constants.js index e593973da824605da773cc62291ec8e4cc267d9d..02843dd3c5b7f7d83e52829353ca759d5905798c 100644 --- a/app/assets/javascripts/sidebar/constants.js +++ b/app/assets/javascripts/sidebar/constants.js @@ -1,3 +1,4 @@ +import updateIssueLabelsMutation from '~/boards/graphql/issue_set_labels.mutation.graphql'; import { IssuableType } from '~/issue_show/constants'; import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; import epicConfidentialQuery from '~/sidebar/queries/epic_confidential.query.graphql'; @@ -29,6 +30,7 @@ import updateIssueConfidentialMutation from '~/sidebar/queries/update_issue_conf import updateIssueDueDateMutation from '~/sidebar/queries/update_issue_due_date.mutation.graphql'; import updateIssueSubscriptionMutation from '~/sidebar/queries/update_issue_subscription.mutation.graphql'; import mergeRequestMilestoneMutation from '~/sidebar/queries/update_merge_request_milestone.mutation.graphql'; +import updateMergeRequestLabelsMutation from '~/sidebar/queries/update_merge_request_labels.mutation.graphql'; import updateMergeRequestSubscriptionMutation from '~/sidebar/queries/update_merge_request_subscription.mutation.graphql'; import updateAlertAssigneesMutation from '~/vue_shared/alert_details/graphql/mutations/alert_set_assignees.mutation.graphql'; import epicLabelsQuery from '~/vue_shared/components/sidebar/labels_select_widget/graphql/epic_labels.query.graphql'; @@ -120,6 +122,17 @@ export const labelsQueries = { }, }; +export const labelsMutations = { + [IssuableType.Issue]: { + mutation: updateIssueLabelsMutation, + mutationName: 'updateIssue', + }, + [IssuableType.MergeRequest]: { + mutation: updateMergeRequestLabelsMutation, + mutationName: 'mergeRequestSetLabels', + }, +}; + export const dateTypes = { start: 'startDate', due: 'dueDate', diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/constants.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/constants.js index 389eb174c0e60f5e74d17931230fc7f51b303f86..3e5d1d6d7d76bfc84c70b3c2d156cd50e983ffc6 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/constants.js +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/constants.js @@ -5,3 +5,8 @@ export const DropdownVariant = { Standalone: 'standalone', Embedded: 'embedded', }; + +export const LabelType = { + group: 'GroupLabel', + project: 'ProjectLabel', +}; diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue index ae27109d3b8eb751d1b868191282156e933edc47..7891765d8d64d37c450e34e8027a92d636380770 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue @@ -68,8 +68,11 @@ export default { }, attrWorkspacePath: { type: String, - required: false, - default: undefined, + required: true, + }, + labelType: { + type: String, + required: true, }, }, data() { @@ -193,11 +196,11 @@ export default { :is="dropdownContentsView" v-model="localSelectedLabels" :search-key="searchKey" - :selected-labels="selectedLabels" :allow-multiselect="allowMultiselect" :issuable-type="issuableType" :full-path="fullPath" :attr-workspace-path="attrWorkspacePath" + :label-type="labelType" @hideCreateView="toggleDropdownContentsCreateView" /> </template> diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue index a2ed08e6b280da25ae14e0b4f6c1981d31f8d0b4..10743d8564b0afefbe641adf3a6dd4315f74a4d1 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue @@ -2,10 +2,10 @@ import { GlTooltipDirective, GlButton, GlFormInput, GlLink, GlLoadingIcon } from '@gitlab/ui'; import produce from 'immer'; import createFlash from '~/flash'; -import { IssuableType } from '~/issue_show/constants'; import { __ } from '~/locale'; import { labelsQueries } from '~/sidebar/constants'; import createLabelMutation from './graphql/create_label.mutation.graphql'; +import { LabelType } from './constants'; const errorMessage = __('Error creating label.'); @@ -30,8 +30,11 @@ export default { }, attrWorkspacePath: { type: String, - required: false, - default: undefined, + required: true, + }, + labelType: { + type: String, + required: true, }, }, data() { @@ -50,25 +53,13 @@ export default { return Object.keys(colorsMap).map((color) => ({ [color]: colorsMap[color] })); }, mutationVariables() { - if (this.issuableType === IssuableType.Epic) { - return { - title: this.labelTitle, - color: this.selectedColor, - groupPath: this.fullPath, - }; - } + const attributePath = this.labelType === LabelType.group ? 'groupPath' : 'projectPath'; - return this.attrWorkspacePath !== undefined - ? { - title: this.labelTitle, - color: this.selectedColor, - groupPath: this.attrWorkspacePath, - } - : { - title: this.labelTitle, - color: this.selectedColor, - projectPath: this.fullPath, - }; + return { + title: this.labelTitle, + color: this.selectedColor, + [attributePath]: this.attrWorkspacePath, + }; }, }, methods: { diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue index 9885d05b335a011e3452ead094372671cf0e69e4..2b44219a95b78c2231d762abff5093defc5ee938 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue @@ -19,10 +19,6 @@ export default { prop: 'localSelectedLabels', }, props: { - selectedLabels: { - type: Array, - required: true, - }, allowMultiselect: { type: Boolean, required: true, diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue index 6bd43da2203fb635e88f868c82377efbbed8aa89..e0f052938ba86c971c28fb361e91cec6ccad4892 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue @@ -1,8 +1,10 @@ <script> +import { MutationOperationMode } from '~/graphql_shared/utils'; import createFlash from '~/flash'; +import { IssuableType } from '~/issue_show/constants'; import { __ } from '~/locale'; import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue'; -import { labelsQueries } from '~/sidebar/constants'; +import { labelsQueries, labelsMutations } from '~/sidebar/constants'; import { DropdownVariant } from './constants'; import DropdownContents from './dropdown_contents.vue'; import DropdownValue from './dropdown_value.vue'; @@ -50,16 +52,6 @@ export default { required: false, default: DropdownVariant.Sidebar, }, - selectedLabels: { - type: Array, - required: false, - default: () => [], - }, - labelsSelectInProgress: { - type: Boolean, - required: false, - default: false, - }, labelsFilterBasePath: { type: String, required: false, @@ -106,14 +98,18 @@ export default { }, attrWorkspacePath: { type: String, - required: false, - default: undefined, + required: true, + }, + labelType: { + type: String, + required: true, }, }, data() { return { contentIsOnViewport: true, issuableLabels: [], + labelsSelectInProgress: false, }; }, computed: { @@ -136,7 +132,9 @@ export default { }; }, update(data) { - return data.workspace?.issuable?.labels.nodes || []; + const labels = data.workspace?.issuable?.labels.nodes || []; + this.selected = labels; + return labels; }, error() { createFlash({ message: __('Error fetching labels.') }); @@ -145,6 +143,10 @@ export default { }, methods: { handleDropdownClose(labels) { + if (this.iid !== '') { + this.updateSelectedLabels(this.getUpdateVariables(labels)); + } + this.$emit('updateSelectedLabels', labels); this.collapseEditableItem(); }, @@ -154,6 +156,72 @@ export default { handleCollapsedValueClick() { this.$emit('toggleCollapse'); }, + getUpdateVariables(labels) { + let labelIds = []; + + labelIds = labels.map(({ id }) => id); + + switch (this.issuableType) { + case IssuableType.Issue: + return { + iid: this.iid, + projectPath: this.fullPath, + labelIds, + }; + case IssuableType.MergeRequest: + return { + iid: this.iid, + labelIds, + operationMode: MutationOperationMode.Replace, + projectPath: this.fullPath, + }; + default: + return {}; + } + }, + updateSelectedLabels(inputVariables) { + this.labelsSelectInProgress = true; + + this.$apollo + .mutate({ + mutation: labelsMutations[this.issuableType].mutation, + variables: { input: inputVariables }, + }) + .then(({ data }) => { + const { mutationName } = labelsMutations[this.issuableType]; + + if (data[mutationName]?.errors?.length) { + throw new Error(); + } + }) + .catch(() => createFlash({ message: __('An error occurred while updating labels.') })) + .finally(() => { + this.labelsSelectInProgress = false; + }); + }, + getRemoveVariables(labelId) { + switch (this.issuableType) { + case IssuableType.Issue: + return { + iid: this.iid, + projectPath: this.fullPath, + removeLabelIds: [labelId], + }; + case IssuableType.MergeRequest: + return { + iid: this.iid, + labelIds: [labelId], + operationMode: MutationOperationMode.Remove, + projectPath: this.fullPath, + }; + default: + return {}; + } + }, + handleLabelRemove(labelId) { + this.updateSelectedLabels(this.getRemoveVariables(labelId)); + this.$emit('onLabelRemove', labelId); + }, isDropdownVariantSidebar, isDropdownVariantStandalone, isDropdownVariantEmbedded, @@ -188,7 +256,7 @@ export default { :allow-label-remove="allowLabelRemove" :labels-filter-base-path="labelsFilterBasePath" :labels-filter-param="labelsFilterParam" - @onLabelRemove="$emit('onLabelRemove', $event)" + @onLabelRemove="handleLabelRemove" > <slot></slot> </dropdown-value> @@ -201,7 +269,7 @@ export default { :labels-filter-base-path="labelsFilterBasePath" :labels-filter-param="labelsFilterParam" class="gl-mb-2" - @onLabelRemove="$emit('onLabelRemove', $event)" + @onLabelRemove="handleLabelRemove" > <slot></slot> </dropdown-value> @@ -212,12 +280,13 @@ export default { :footer-create-label-title="footerCreateLabelTitle" :footer-manage-label-title="footerManageLabelTitle" :labels-create-title="labelsCreateTitle" - :selected-labels="selectedLabels" + :selected-labels="issuableLabels" :variant="variant" :issuable-type="issuableType" :is-visible="edit" :full-path="fullPath" :attr-workspace-path="attrWorkspacePath" + :label-type="labelType" @setLabels="handleDropdownClose" @closeDropdown="collapseEditableItem" /> @@ -233,10 +302,12 @@ export default { :footer-create-label-title="footerCreateLabelTitle" :footer-manage-label-title="footerManageLabelTitle" :labels-create-title="labelsCreateTitle" - :selected-labels="selectedLabels" + :selected-labels="issuableLabels" :variant="variant" :issuable-type="issuableType" :full-path="fullPath" + :attr-workspace-path="attrWorkspacePath" + :label-type="labelType" @setLabels="handleDropdownClose" /> </div> diff --git a/ee/app/assets/javascripts/epic/components/epic_form.vue b/ee/app/assets/javascripts/epic/components/epic_form.vue index 8099709b11e5d41bb01e277f3a841e456903f9fd..b2e497175fa6b0d88b3131ea6fe24ea435c58e8b 100644 --- a/ee/app/assets/javascripts/epic/components/epic_form.vue +++ b/ee/app/assets/javascripts/epic/components/epic_form.vue @@ -14,6 +14,7 @@ import { s__ } from '~/locale'; import MarkdownField from '~/vue_shared/components/markdown/field.vue'; import LabelsSelectVue from '~/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue'; import LabelsSelectWidget from '~/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue'; +import { LabelType } from '~/vue_shared/components/sidebar/labels_select_widget/constants'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import createEpic from '../queries/createEpic.mutation.graphql'; @@ -31,7 +32,6 @@ export default { }, mixins: [glFeatureFlagMixin()], inject: [ - 'iid', 'groupPath', 'groupEpicsPath', 'labelsFetchPath', @@ -48,6 +48,7 @@ export default { startDateFixed: null, dueDateFixed: null, loading: false, + LabelType, }; }, computed: { @@ -190,13 +191,13 @@ export default { <labels-select-widget v-if="glFeatures.labelsWidget" class="block labels js-labels-block" - :iid="iid" :full-path="groupPath" :allow-label-create="true" :allow-multiselect="true" :allow-scoped-labels="false" :labels-filter-base-path="groupEpicsPath" - :selected-labels="labels" + :attr-workspace-path="groupPath" + :label-type="LabelType.group" issuable-type="epic" variant="embedded" data-qa-selector="labels_block" diff --git a/ee/spec/features/labels_hierarchy_spec.rb b/ee/spec/features/labels_hierarchy_spec.rb index 48105bb83bbfdfd3fd4afe21ad4491905cf7a1de..8f677ecddc301234ce75e178ca6228a387333939 100644 --- a/ee/spec/features/labels_hierarchy_spec.rb +++ b/ee/spec/features/labels_hierarchy_spec.rb @@ -11,12 +11,11 @@ RSpec.describe 'Labels Hierarchy', :js do let!(:grandparent_group_label) { create(:group_label, group: grandparent, title: 'Label_1') } let!(:parent_group_label) { create(:group_label, group: parent, title: 'Label_2') } - let!(:child_group_label) { create(:group_label, group: child, title: 'Label_3') } - let!(:project_label_1) { create(:label, project: project_1, title: 'Label_4') } + let!(:project_label_1) { create(:label, project: project_1, title: 'Label_3') } - let!(:labeled_issue_1) { create(:labeled_issue, project: project_1, labels: [grandparent_group_label, parent_group_label, child_group_label]) } + let!(:labeled_issue_1) { create(:labeled_issue, project: project_1, labels: [grandparent_group_label, parent_group_label]) } let!(:labeled_issue_2) { create(:labeled_issue, project: project_1, labels: [grandparent_group_label, parent_group_label]) } - let!(:labeled_issue_3) { create(:labeled_issue, project: project_1, labels: [grandparent_group_label, parent_group_label, child_group_label, project_label_1]) } + let!(:labeled_issue_3) { create(:labeled_issue, project: project_1, labels: [grandparent_group_label, parent_group_label, project_label_1]) } let!(:not_labeled) { create(:issue, project: project_1) } before do @@ -26,8 +25,8 @@ RSpec.describe 'Labels Hierarchy', :js do end shared_examples 'filter for scoped boards' do |project = false| - it 'scopes board to ancestor and descendant labels' do - labels = [grandparent_group_label, parent_group_label, child_group_label] + it 'scopes board to ancestor and current group labels' do + labels = [grandparent_group_label, parent_group_label] labels.push(project_label_1) if project labels.each do |label| diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js index 0b90912a584a396da65c33d93c5ea9d823ce1186..c9e3e100354aff999df3de146b7a75b94102437f 100644 --- a/spec/frontend/boards/stores/actions_spec.js +++ b/spec/frontend/boards/stores/actions_spec.js @@ -1572,12 +1572,13 @@ describe('setActiveIssueLabels', () => { const getters = { activeBoardItem: mockIssue }; const testLabelIds = labels.map((label) => label.id); const input = { - addLabelIds: testLabelIds, + labelsIds: testLabelIds, removeLabelIds: [], projectPath: 'h/b', + labels, }; - it('should assign labels on success, and sets loading state for labels', (done) => { + it('should assign labels on success', (done) => { jest .spyOn(gqlClient, 'mutate') .mockResolvedValue({ data: { updateIssue: { issue: { labels: { nodes: labels } } } } }); @@ -1593,14 +1594,6 @@ describe('setActiveIssueLabels', () => { input, { ...state, ...getters }, [ - { - type: types.SET_LABELS_LOADING, - payload: true, - }, - { - type: types.SET_LABELS_LOADING, - payload: false, - }, { type: types.UPDATE_BOARD_ITEM_BY_ID, payload, diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js index 8931584e12cd91cdaddc0e4d783ada287e2100e8..03d015b562447217490f1b8a3654920742bfc644 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view_spec.js @@ -51,6 +51,7 @@ describe('DropdownContentsCreateView', () => { const createComponent = ({ mutationHandler = createLabelSuccessHandler, issuableType = IssuableType.Issue, + labelType = 'ProjectLabel', } = {}) => { const mockApollo = createMockApollo([[createLabelMutation, mutationHandler]]); mockApollo.clients.defaultClient.cache.writeQuery({ @@ -68,6 +69,8 @@ describe('DropdownContentsCreateView', () => { propsData: { issuableType, fullPath: '', + attrWorkspacePath: '', + labelType, }, }); }; @@ -174,7 +177,7 @@ describe('DropdownContentsCreateView', () => { }); it('calls a mutation with `groupPath` variable on the epic', () => { - createComponent({ issuableType: IssuableType.Epic }); + createComponent({ issuableType: IssuableType.Epic, labelType: 'GroupLabel' }); fillLabelAttributes(); findCreateButton().vm.$emit('click'); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js index cdb1581b0d1e1f0ddd63c05a9ab2c96f90946598..3b5ef4a8c90533d9b1323c4926c514e08cd82578 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js @@ -41,6 +41,8 @@ describe('DropdownContent', () => { variant: 'sidebar', issuableType: 'issue', fullPath: 'test', + labelType: 'ProjectLabel', + attrWorkspacePath: 'path', ...props, }, data() { diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js index b5441d711a59b81b411d2f293ae317648efd8021..b72813e53a558284795a487c873d2e412692e231 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js @@ -41,6 +41,7 @@ describe('LabelsSelectRoot', () => { propsData: { ...config, issuableType: IssuableType.Issue, + labelType: 'ProjectLabel', }, stubs: { SidebarEditableItem, diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js index 23a457848d9ea93e813e5b46acc67682ac846ddb..92f3549b3985234bb59fce0fedde5fc3ff951385 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js @@ -40,12 +40,12 @@ export const mockConfig = { labelsListTitle: 'Assign labels', labelsCreateTitle: 'Create label', variant: 'sidebar', - selectedLabels: [mockRegularLabel, mockScopedLabel], labelsSelectInProgress: false, labelsFilterBasePath: '/gitlab-org/my-project/issues', labelsFilterParam: 'label_name', footerCreateLabelTitle: 'create', footerManageLabelTitle: 'manage', + attrWorkspacePath: 'test', }; export const mockSuggestedColors = {