Commit 755a0df3 authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch...

Merge branch '322725-display-labels-when-editing-labels-in-the-new-sidebar-and-reflect-in-boards' into 'master'

Board sidebar - Migrate labels select to widget [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!71791
parents 4e4ba490 06c996d8
...@@ -3,15 +3,18 @@ import { GlDrawer } from '@gitlab/ui'; ...@@ -3,15 +3,18 @@ import { GlDrawer } from '@gitlab/ui';
import { MountingPortal } from 'portal-vue'; import { MountingPortal } from 'portal-vue';
import { mapState, mapActions, mapGetters } from 'vuex'; import { mapState, mapActions, mapGetters } from 'vuex';
import SidebarDropdownWidget from 'ee_else_ce/sidebar/components/sidebar_dropdown_widget.vue'; import SidebarDropdownWidget from 'ee_else_ce/sidebar/components/sidebar_dropdown_widget.vue';
import { __, sprintf } from '~/locale';
import BoardSidebarLabelsSelect from '~/boards/components/sidebar/board_sidebar_labels_select.vue'; import BoardSidebarLabelsSelect from '~/boards/components/sidebar/board_sidebar_labels_select.vue';
import BoardSidebarTimeTracker from '~/boards/components/sidebar/board_sidebar_time_tracker.vue'; import BoardSidebarTimeTracker from '~/boards/components/sidebar/board_sidebar_time_tracker.vue';
import BoardSidebarTitle from '~/boards/components/sidebar/board_sidebar_title.vue'; import BoardSidebarTitle from '~/boards/components/sidebar/board_sidebar_title.vue';
import { ISSUABLE } from '~/boards/constants'; import { ISSUABLE } from '~/boards/constants';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import SidebarAssigneesWidget from '~/sidebar/components/assignees/sidebar_assignees_widget.vue'; import SidebarAssigneesWidget from '~/sidebar/components/assignees/sidebar_assignees_widget.vue';
import SidebarConfidentialityWidget from '~/sidebar/components/confidential/sidebar_confidentiality_widget.vue'; import SidebarConfidentialityWidget from '~/sidebar/components/confidential/sidebar_confidentiality_widget.vue';
import SidebarDateWidget from '~/sidebar/components/date/sidebar_date_widget.vue'; import SidebarDateWidget from '~/sidebar/components/date/sidebar_date_widget.vue';
import SidebarSubscriptionsWidget from '~/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue'; import SidebarSubscriptionsWidget from '~/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue';
import SidebarTodoWidget from '~/sidebar/components/todo_toggle/sidebar_todo_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 glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default { export default {
...@@ -23,6 +26,7 @@ export default { ...@@ -23,6 +26,7 @@ export default {
SidebarConfidentialityWidget, SidebarConfidentialityWidget,
BoardSidebarTimeTracker, BoardSidebarTimeTracker,
BoardSidebarLabelsSelect, BoardSidebarLabelsSelect,
SidebarLabelsWidget,
SidebarSubscriptionsWidget, SidebarSubscriptionsWidget,
SidebarDropdownWidget, SidebarDropdownWidget,
SidebarTodoWidget, SidebarTodoWidget,
...@@ -46,16 +50,20 @@ export default { ...@@ -46,16 +50,20 @@ export default {
weightFeatureAvailable: { weightFeatureAvailable: {
default: false, default: false,
}, },
allowLabelEdit: {
default: false,
},
}, },
inheritAttrs: false, inheritAttrs: false,
computed: { computed: {
...mapGetters([ ...mapGetters([
'isGroupBoard',
'isSidebarOpen', 'isSidebarOpen',
'activeBoardItem', 'activeBoardItem',
'groupPathForActiveIssue', 'groupPathForActiveIssue',
'projectPathForActiveIssue', 'projectPathForActiveIssue',
]), ]),
...mapState(['sidebarType', 'issuableType']), ...mapState(['sidebarType', 'issuableType', 'isSettingLabels']),
isIssuableSidebar() { isIssuableSidebar() {
return this.sidebarType === ISSUABLE; return this.sidebarType === ISSUABLE;
}, },
...@@ -65,17 +73,48 @@ export default { ...@@ -65,17 +73,48 @@ export default {
fullPath() { fullPath() {
return this.activeBoardItem?.referencePath?.split('#')[0] || ''; return this.activeBoardItem?.referencePath?.split('#')[0] || '';
}, },
createLabelTitle() {
return sprintf(__('Create %{workspace} label'), {
workspace: this.isGroupBoard ? 'group' : 'project',
});
},
manageLabelTitle() {
return sprintf(__('Manage %{workspace} labels'), {
workspace: this.isGroupBoard ? 'group' : 'project',
});
},
attrWorkspacePath() {
return this.isGroupBoard ? this.groupPathForActiveIssue : undefined;
},
}, },
methods: { methods: {
...mapActions([ ...mapActions([
'toggleBoardItem', 'toggleBoardItem',
'setAssignees', 'setAssignees',
'setActiveItemConfidential', 'setActiveItemConfidential',
'setActiveBoardItemLabels',
'setActiveItemWeight', 'setActiveItemWeight',
]), ]),
handleClose() { handleClose() {
this.toggleBoardItem({ boardItem: this.activeBoardItem, sidebarType: this.sidebarType }); this.toggleBoardItem({ boardItem: this.activeBoardItem, sidebarType: this.sidebarType });
}, },
handleUpdateSelectedLabels(input) {
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),
});
},
handleLabelRemove(input) {
this.setActiveBoardItemLabels({
iid: this.activeBoardItem.iid,
projectPath: this.projectPathForActiveIssue,
removeLabelIds: [input],
});
},
}, },
}; };
</script> </script>
...@@ -160,7 +199,28 @@ export default { ...@@ -160,7 +199,28 @@ export default {
:issuable-type="issuableType" :issuable-type="issuableType"
data-testid="sidebar-due-date" data-testid="sidebar-due-date"
/> />
<board-sidebar-labels-select class="block labels" /> <sidebar-labels-widget
v-if="glFeatures.labelsWidget"
class="block labels"
data-testid="sidebar-labels"
:iid="activeBoardItem.iid"
: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"
@onLabelRemove="handleLabelRemove"
@updateSelectedLabels="handleUpdateSelectedLabels"
>
{{ __('None') }}
</sidebar-labels-widget>
<board-sidebar-labels-select v-else class="block labels" />
<sidebar-weight-widget <sidebar-weight-widget
v-if="weightFeatureAvailable" v-if="weightFeatureAvailable"
:iid="activeBoardItem.iid" :iid="activeBoardItem.iid"
......
...@@ -87,6 +87,9 @@ function mountBoardApp(el) { ...@@ -87,6 +87,9 @@ function mountBoardApp(el) {
iterationListsAvailable: parseBoolean(el.dataset.iterationListsAvailable), iterationListsAvailable: parseBoolean(el.dataset.iterationListsAvailable),
issuableType: issuableTypes.issue, issuableType: issuableTypes.issue,
emailsDisabled: parseBoolean(el.dataset.emailsDisabled), emailsDisabled: parseBoolean(el.dataset.emailsDisabled),
allowLabelCreate: parseBoolean(el.dataset.canUpdate),
allowLabelEdit: parseBoolean(el.dataset.canUpdate),
allowScopedLabels: parseBoolean(el.dataset.scopedLabels),
}, },
render: (createComponent) => createComponent(BoardApp), render: (createComponent) => createComponent(BoardApp),
}); });
......
...@@ -656,6 +656,7 @@ export default { ...@@ -656,6 +656,7 @@ export default {
}, },
setActiveIssueLabels: async ({ commit, getters }, input) => { setActiveIssueLabels: async ({ commit, getters }, input) => {
commit(types.SET_LABELS_LOADING, true);
const { activeBoardItem } = getters; const { activeBoardItem } = getters;
const { data } = await gqlClient.mutate({ const { data } = await gqlClient.mutate({
mutation: issueSetLabelsMutation, mutation: issueSetLabelsMutation,
...@@ -669,6 +670,8 @@ export default { ...@@ -669,6 +670,8 @@ export default {
}, },
}); });
commit(types.SET_LABELS_LOADING, false);
if (data.updateIssue?.errors?.length > 0) { if (data.updateIssue?.errors?.length > 0) {
throw new Error(data.updateIssue.errors); throw new Error(data.updateIssue.errors);
} }
......
...@@ -28,6 +28,7 @@ export const ADD_BOARD_ITEM_TO_LIST = 'ADD_BOARD_ITEM_TO_LIST'; ...@@ -28,6 +28,7 @@ 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 REMOVE_BOARD_ITEM_FROM_LIST = 'REMOVE_BOARD_ITEM_FROM_LIST';
export const SET_ACTIVE_ID = 'SET_ACTIVE_ID'; export const SET_ACTIVE_ID = 'SET_ACTIVE_ID';
export const UPDATE_BOARD_ITEM_BY_ID = 'UPDATE_BOARD_ITEM_BY_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 SET_ASSIGNEE_LOADING = 'SET_ASSIGNEE_LOADING';
export const RESET_ISSUES = 'RESET_ISSUES'; export const RESET_ISSUES = 'RESET_ISSUES';
export const REQUEST_GROUP_PROJECTS = 'REQUEST_GROUP_PROJECTS'; export const REQUEST_GROUP_PROJECTS = 'REQUEST_GROUP_PROJECTS';
......
...@@ -195,6 +195,10 @@ export default { ...@@ -195,6 +195,10 @@ export default {
Vue.set(state.boardItems[itemId], prop, value); Vue.set(state.boardItems[itemId], prop, value);
}, },
[mutationTypes.SET_LABELS_LOADING](state, isLoading) {
state.isSettingLabels = isLoading;
},
[mutationTypes.SET_ASSIGNEE_LOADING](state, isLoading) { [mutationTypes.SET_ASSIGNEE_LOADING](state, isLoading) {
state.isSettingAssignees = isLoading; state.isSettingAssignees = isLoading;
}, },
......
...@@ -12,6 +12,7 @@ export default () => ({ ...@@ -12,6 +12,7 @@ export default () => ({
listsFlags: {}, listsFlags: {},
boardItemsByListId: {}, boardItemsByListId: {},
backupItemsList: [], backupItemsList: [],
isSettingLabels: false,
isSettingAssignees: false, isSettingAssignees: false,
pageInfoByListId: {}, pageInfoByListId: {},
boardItems: {}, boardItems: {},
......
...@@ -36,6 +36,7 @@ export default { ...@@ -36,6 +36,7 @@ export default {
'allowLabelEdit', 'allowLabelEdit',
'allowScopedLabels', 'allowScopedLabels',
'iid', 'iid',
'fullPath',
'initiallySelectedLabels', 'initiallySelectedLabels',
'issuableType', 'issuableType',
'labelsFetchPath', 'labelsFetchPath',
...@@ -145,6 +146,8 @@ export default { ...@@ -145,6 +146,8 @@ export default {
<labels-select-widget <labels-select-widget
v-if="glFeatures.labelsWidget" v-if="glFeatures.labelsWidget"
class="block labels js-labels-block" class="block labels js-labels-block"
:iid="iid"
:full-path="fullPath"
:allow-label-remove="allowLabelEdit" :allow-label-remove="allowLabelEdit"
:allow-multiselect="true" :allow-multiselect="true"
:footer-create-label-title="__('Create project label')" :footer-create-label-title="__('Create project label')"
......
...@@ -57,6 +57,15 @@ export default { ...@@ -57,6 +57,15 @@ export default {
required: false, required: false,
default: false, default: false,
}, },
fullPath: {
type: String,
required: true,
},
attrWorkspacePath: {
type: String,
required: false,
default: undefined,
},
}, },
data() { data() {
return { return {
...@@ -182,6 +191,8 @@ export default { ...@@ -182,6 +191,8 @@ export default {
:selected-labels="selectedLabels" :selected-labels="selectedLabels"
:allow-multiselect="allowMultiselect" :allow-multiselect="allowMultiselect"
:issuable-type="issuableType" :issuable-type="issuableType"
:full-path="fullPath"
:attr-workspace-path="attrWorkspacePath"
@hideCreateView="toggleDropdownContentsCreateView" @hideCreateView="toggleDropdownContentsCreateView"
/> />
</template> </template>
......
...@@ -19,16 +19,20 @@ export default { ...@@ -19,16 +19,20 @@ export default {
directives: { directives: {
GlTooltip: GlTooltipDirective, GlTooltip: GlTooltipDirective,
}, },
inject: {
fullPath: {
default: '',
},
},
props: { props: {
issuableType: { issuableType: {
type: String, type: String,
required: true, required: true,
}, },
fullPath: {
type: String,
required: true,
},
attrWorkspacePath: {
type: String,
required: false,
default: undefined,
},
}, },
data() { data() {
return { return {
...@@ -46,11 +50,19 @@ export default { ...@@ -46,11 +50,19 @@ export default {
return Object.keys(colorsMap).map((color) => ({ [color]: colorsMap[color] })); return Object.keys(colorsMap).map((color) => ({ [color]: colorsMap[color] }));
}, },
mutationVariables() { mutationVariables() {
return this.issuableType === IssuableType.Epic if (this.issuableType === IssuableType.Epic) {
return {
title: this.labelTitle,
color: this.selectedColor,
groupPath: this.fullPath,
};
}
return this.attrWorkspacePath !== undefined
? { ? {
title: this.labelTitle, title: this.labelTitle,
color: this.selectedColor, color: this.selectedColor,
groupPath: this.fullPath, groupPath: this.attrWorkspacePath,
} }
: { : {
title: this.labelTitle, title: this.labelTitle,
......
...@@ -24,7 +24,6 @@ export default { ...@@ -24,7 +24,6 @@ export default {
GlIntersectionObserver, GlIntersectionObserver,
LabelItem, LabelItem,
}, },
inject: ['fullPath'],
model: { model: {
prop: 'localSelectedLabels', prop: 'localSelectedLabels',
}, },
...@@ -45,6 +44,10 @@ export default { ...@@ -45,6 +44,10 @@ export default {
type: Array, type: Array,
required: true, required: true,
}, },
fullPath: {
type: String,
required: true,
},
}, },
data() { data() {
return { return {
...@@ -84,7 +87,7 @@ export default { ...@@ -84,7 +87,7 @@ export default {
return this.$apollo.queries.labels.loading; return this.$apollo.queries.labels.loading;
}, },
localSelectedLabelsIds() { localSelectedLabelsIds() {
return this.localSelectedLabels.map((label) => label.id); return this.localSelectedLabels.map((label) => getIdFromGraphQLId(label.id));
}, },
visibleLabels() { visibleLabels() {
if (this.searchKey) { if (this.searchKey) {
...@@ -130,7 +133,9 @@ export default { ...@@ -130,7 +133,9 @@ export default {
updateSelectedLabels(label) { updateSelectedLabels(label) {
let labels; let labels;
if (this.isLabelSelected(label)) { if (this.isLabelSelected(label)) {
labels = this.localSelectedLabels.filter(({ id }) => id !== getIdFromGraphQLId(label.id)); labels = this.localSelectedLabels.filter(
({ id }) => id !== getIdFromGraphQLId(label.id) && id !== label.id,
);
} else { } else {
labels = [ labels = [
...this.localSelectedLabels, ...this.localSelectedLabels,
......
...@@ -21,15 +21,20 @@ export default { ...@@ -21,15 +21,20 @@ export default {
SidebarEditableItem, SidebarEditableItem,
}, },
inject: { inject: {
iid: {
default: '',
},
allowLabelEdit: { allowLabelEdit: {
default: false, default: false,
}, },
fullPath: {},
}, },
props: { props: {
iid: {
type: String,
required: false,
default: '',
},
fullPath: {
type: String,
required: true,
},
allowLabelRemove: { allowLabelRemove: {
type: Boolean, type: Boolean,
required: false, required: false,
...@@ -99,6 +104,11 @@ export default { ...@@ -99,6 +104,11 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
attrWorkspacePath: {
type: String,
required: false,
default: undefined,
},
}, },
data() { data() {
return { return {
...@@ -206,6 +216,8 @@ export default { ...@@ -206,6 +216,8 @@ export default {
:variant="variant" :variant="variant"
:issuable-type="issuableType" :issuable-type="issuableType"
:is-visible="edit" :is-visible="edit"
:full-path="fullPath"
:attr-workspace-path="attrWorkspacePath"
@setLabels="handleDropdownClose" @setLabels="handleDropdownClose"
@closeDropdown="collapseEditableItem" @closeDropdown="collapseEditableItem"
/> />
...@@ -224,6 +236,7 @@ export default { ...@@ -224,6 +236,7 @@ export default {
:selected-labels="selectedLabels" :selected-labels="selectedLabels"
:variant="variant" :variant="variant"
:issuable-type="issuableType" :issuable-type="issuableType"
:full-path="fullPath"
@setLabels="handleDropdownClose" @setLabels="handleDropdownClose"
/> />
</div> </div>
......
...@@ -11,6 +11,7 @@ class Groups::BoardsController < Groups::ApplicationController ...@@ -11,6 +11,7 @@ class Groups::BoardsController < Groups::ApplicationController
push_frontend_feature_flag(:board_multi_select, group, default_enabled: :yaml) push_frontend_feature_flag(:board_multi_select, group, default_enabled: :yaml)
push_frontend_feature_flag(:swimlanes_buffered_rendering, group, default_enabled: :yaml) push_frontend_feature_flag(:swimlanes_buffered_rendering, group, default_enabled: :yaml)
push_frontend_feature_flag(:iteration_cadences, group, default_enabled: :yaml) push_frontend_feature_flag(:iteration_cadences, group, default_enabled: :yaml)
push_frontend_feature_flag(:labels_widget, group, default_enabled: :yaml)
end end
feature_category :boards feature_category :boards
......
...@@ -11,6 +11,7 @@ class Projects::BoardsController < Projects::ApplicationController ...@@ -11,6 +11,7 @@ class Projects::BoardsController < Projects::ApplicationController
push_frontend_feature_flag(:issue_boards_filtered_search, project, default_enabled: :yaml) push_frontend_feature_flag(:issue_boards_filtered_search, project, default_enabled: :yaml)
push_frontend_feature_flag(:board_multi_select, project, default_enabled: :yaml) push_frontend_feature_flag(:board_multi_select, project, default_enabled: :yaml)
push_frontend_feature_flag(:iteration_cadences, project&.group, default_enabled: :yaml) push_frontend_feature_flag(:iteration_cadences, project&.group, default_enabled: :yaml)
push_frontend_feature_flag(:labels_widget, project, default_enabled: :yaml)
end end
feature_category :boards feature_category :boards
......
...@@ -31,6 +31,7 @@ export default { ...@@ -31,6 +31,7 @@ export default {
}, },
mixins: [glFeatureFlagMixin()], mixins: [glFeatureFlagMixin()],
inject: [ inject: [
'iid',
'groupPath', 'groupPath',
'groupEpicsPath', 'groupEpicsPath',
'labelsFetchPath', 'labelsFetchPath',
...@@ -189,6 +190,8 @@ export default { ...@@ -189,6 +190,8 @@ export default {
<labels-select-widget <labels-select-widget
v-if="glFeatures.labelsWidget" v-if="glFeatures.labelsWidget"
class="block labels js-labels-block" class="block labels js-labels-block"
:iid="iid"
:full-path="groupPath"
:allow-label-create="true" :allow-label-create="true"
:allow-multiselect="true" :allow-multiselect="true"
:allow-scoped-labels="false" :allow-scoped-labels="false"
......
...@@ -295,15 +295,15 @@ RSpec.describe 'Issue Boards', :js do ...@@ -295,15 +295,15 @@ RSpec.describe 'Issue Boards', :js do
wait_for_requests wait_for_requests
click_link scoped_label_1.title click_button scoped_label_1.title
wait_for_requests wait_for_requests
click_link scoped_label_2.title click_button scoped_label_2.title
wait_for_requests wait_for_requests
find('[data-testid="close-icon"]').click click_button 'Close'
page.within('.value') do page.within('.value') do
aggregate_failures do aggregate_failures do
...@@ -335,11 +335,11 @@ RSpec.describe 'Issue Boards', :js do ...@@ -335,11 +335,11 @@ RSpec.describe 'Issue Boards', :js do
wait_for_requests wait_for_requests
click_link scoped_label_2.title click_button scoped_label_2.title
wait_for_requests wait_for_requests
find('[data-testid="close-icon"]').click click_button 'Close'
page.within('.value') do page.within('.value') do
aggregate_failures do aggregate_failures do
......
...@@ -22,6 +22,7 @@ describe('ee/epic/components/epic_form.vue', () => { ...@@ -22,6 +22,7 @@ describe('ee/epic/components/epic_form.vue', () => {
const createWrapper = ({ mutationResult = TEST_NEW_EPIC } = {}) => { const createWrapper = ({ mutationResult = TEST_NEW_EPIC } = {}) => {
wrapper = shallowMount(EpicForm, { wrapper = shallowMount(EpicForm, {
provide: { provide: {
iid: '1',
groupPath: TEST_GROUP_PATH, groupPath: TEST_GROUP_PATH,
groupEpicsPath: TEST_HOST, groupEpicsPath: TEST_HOST,
labelsFetchPath: TEST_HOST, labelsFetchPath: TEST_HOST,
......
...@@ -9546,6 +9546,9 @@ msgstr "" ...@@ -9546,6 +9546,9 @@ msgstr ""
msgid "Create %{type}" msgid "Create %{type}"
msgstr "" msgstr ""
msgid "Create %{workspace} label"
msgstr ""
msgid "Create New Directory" msgid "Create New Directory"
msgstr "" msgstr ""
...@@ -20769,6 +20772,9 @@ msgstr "" ...@@ -20769,6 +20772,9 @@ msgstr ""
msgid "Makes this issue confidential." msgid "Makes this issue confidential."
msgstr "" msgstr ""
msgid "Manage %{workspace} labels"
msgstr ""
msgid "Manage Web IDE features." msgid "Manage Web IDE features."
msgstr "" msgstr ""
......
...@@ -29,12 +29,11 @@ RSpec.describe 'Project issue boards sidebar labels', :js do ...@@ -29,12 +29,11 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
end end
context 'labels' do context 'labels' do
# https://gitlab.com/gitlab-org/gitlab/-/issues/322725 it 'shows current labels when editing' do
xit 'shows current labels when editing' do
click_card(card) click_card(card)
page.within('.labels') do page.within('.labels') do
click_link 'Edit' click_button 'Edit'
wait_for_requests wait_for_requests
...@@ -54,9 +53,9 @@ RSpec.describe 'Project issue boards sidebar labels', :js do ...@@ -54,9 +53,9 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
wait_for_requests wait_for_requests
click_link bug.title click_on bug.title
find('[data-testid="close-icon"]').click click_button 'Close'
wait_for_requests wait_for_requests
...@@ -79,11 +78,11 @@ RSpec.describe 'Project issue boards sidebar labels', :js do ...@@ -79,11 +78,11 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
wait_for_requests wait_for_requests
click_link bug.title click_on bug.title
click_link regression.title click_on regression.title
find('[data-testid="close-icon"]').click click_button 'Close'
wait_for_requests wait_for_requests
...@@ -108,9 +107,9 @@ RSpec.describe 'Project issue boards sidebar labels', :js do ...@@ -108,9 +107,9 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
wait_for_requests wait_for_requests
click_link stretch.title click_button stretch.title
find('[data-testid="close-icon"]').click click_button 'Close'
wait_for_requests wait_for_requests
...@@ -125,43 +124,22 @@ RSpec.describe 'Project issue boards sidebar labels', :js do ...@@ -125,43 +124,22 @@ RSpec.describe 'Project issue boards sidebar labels', :js do
expect(card).not_to have_content(stretch.title) expect(card).not_to have_content(stretch.title)
end end
# https://gitlab.com/gitlab-org/gitlab/-/issues/324290 it 'creates project label' do
xit 'creates project label' do
click_card(card) click_card(card)
page.within('.labels') do page.within('.labels') do
click_link 'Edit' click_button 'Edit'
wait_for_requests wait_for_requests
click_link 'Create project label' click_on 'Create project label'
fill_in 'new_label_name', with: 'test label' fill_in 'Name new label', with: 'test label'
first('.suggest-colors-dropdown a').click first('.suggest-colors-dropdown a').click
click_button 'Create' click_button 'Create'
wait_for_requests wait_for_requests
expect(page).to have_link 'test label' expect(page).to have_button 'test label'
end end
expect(page).to have_selector('.board', count: 3) expect(page).to have_selector('.board', count: 3)
end end
# https://gitlab.com/gitlab-org/gitlab/-/issues/324290
xit 'creates project label and list' do
click_card(card)
page.within('.labels') do
click_link 'Edit'
wait_for_requests
click_link 'Create project label'
fill_in 'new_label_name', with: 'test label'
first('.suggest-colors-dropdown a').click
first('.js-add-list').click
click_button 'Create'
wait_for_requests
expect(page).to have_link 'test label'
end
expect(page).to have_selector('.board', count: 4)
end
end end
end end
...@@ -1577,7 +1577,7 @@ describe('setActiveIssueLabels', () => { ...@@ -1577,7 +1577,7 @@ describe('setActiveIssueLabels', () => {
projectPath: 'h/b', projectPath: 'h/b',
}; };
it('should assign labels on success', (done) => { it('should assign labels on success, and sets loading state for labels', (done) => {
jest jest
.spyOn(gqlClient, 'mutate') .spyOn(gqlClient, 'mutate')
.mockResolvedValue({ data: { updateIssue: { issue: { labels: { nodes: labels } } } } }); .mockResolvedValue({ data: { updateIssue: { issue: { labels: { nodes: labels } } } } });
...@@ -1593,6 +1593,14 @@ describe('setActiveIssueLabels', () => { ...@@ -1593,6 +1593,14 @@ describe('setActiveIssueLabels', () => {
input, input,
{ ...state, ...getters }, { ...state, ...getters },
[ [
{
type: types.SET_LABELS_LOADING,
payload: true,
},
{
type: types.SET_LABELS_LOADING,
payload: false,
},
{ {
type: types.UPDATE_BOARD_ITEM_BY_ID, type: types.UPDATE_BOARD_ITEM_BY_ID,
payload, payload,
......
...@@ -27,6 +27,7 @@ describe('sidebar labels', () => { ...@@ -27,6 +27,7 @@ describe('sidebar labels', () => {
labelsManagePath: '/gitlab-org/gitlab-test/-/labels', labelsManagePath: '/gitlab-org/gitlab-test/-/labels',
projectIssuesPath: '/gitlab-org/gitlab-test/-/issues', projectIssuesPath: '/gitlab-org/gitlab-test/-/issues',
projectPath: 'gitlab-org/gitlab-test', projectPath: 'gitlab-org/gitlab-test',
fullPath: 'gitlab-org/gitlab-test',
}; };
const $apollo = { const $apollo = {
......
...@@ -67,6 +67,7 @@ describe('DropdownContentsCreateView', () => { ...@@ -67,6 +67,7 @@ describe('DropdownContentsCreateView', () => {
apolloProvider: mockApollo, apolloProvider: mockApollo,
propsData: { propsData: {
issuableType, issuableType,
fullPath: '',
}, },
}); });
}; };
......
...@@ -50,8 +50,6 @@ describe('DropdownContentsLabelsView', () => { ...@@ -50,8 +50,6 @@ describe('DropdownContentsLabelsView', () => {
localVue, localVue,
apolloProvider: mockApollo, apolloProvider: mockApollo,
provide: { provide: {
fullPath: 'test',
iid: 1,
variant: DropdownVariant.Sidebar, variant: DropdownVariant.Sidebar,
...injected, ...injected,
}, },
......
...@@ -38,6 +38,7 @@ describe('DropdownContent', () => { ...@@ -38,6 +38,7 @@ describe('DropdownContent', () => {
dropdownButtonText: 'Labels', dropdownButtonText: 'Labels',
variant: 'sidebar', variant: 'sidebar',
issuableType: 'issue', issuableType: 'issue',
fullPath: 'test',
...props, ...props,
}, },
data() { data() {
......
...@@ -46,8 +46,6 @@ describe('LabelsSelectRoot', () => { ...@@ -46,8 +46,6 @@ describe('LabelsSelectRoot', () => {
SidebarEditableItem, SidebarEditableItem,
}, },
provide: { provide: {
iid: '1',
fullPath: 'test',
canUpdate: true, canUpdate: true,
allowLabelEdit: true, allowLabelEdit: true,
allowLabelCreate: true, allowLabelCreate: true,
......
...@@ -34,6 +34,8 @@ export const mockLabels = [ ...@@ -34,6 +34,8 @@ export const mockLabels = [
]; ];
export const mockConfig = { export const mockConfig = {
iid: '1',
fullPath: 'test',
allowMultiselect: true, allowMultiselect: true,
labelsListTitle: 'Assign labels', labelsListTitle: 'Assign labels',
labelsCreateTitle: 'Create label', labelsCreateTitle: 'Create label',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment