diff --git a/app/assets/javascripts/boards/components/board_content.vue b/app/assets/javascripts/boards/components/board_content.vue index 2515f47137920c10844c94db48bb588e2756a565..201b2b2350f89cc8f565f6ebba2e40b93fadb7fc 100644 --- a/app/assets/javascripts/boards/components/board_content.vue +++ b/app/assets/javascripts/boards/components/board_content.vue @@ -38,12 +38,11 @@ export default { }, mounted() { if (this.glFeatures.graphqlBoardLists) { - this.fetchLists(); this.showPromotionList(); } }, methods: { - ...mapActions(['fetchLists', 'showPromotionList']), + ...mapActions(['showPromotionList']), }, }; </script> diff --git a/app/assets/javascripts/boards/constants.js b/app/assets/javascripts/boards/constants.js index 2f64014a949ecab53dc99e6a677ad29098ff97e5..49cb560594c2cd7c66a9e8cbc59d1142830d08d3 100644 --- a/app/assets/javascripts/boards/constants.js +++ b/app/assets/javascripts/boards/constants.js @@ -18,7 +18,11 @@ export const inactiveId = 0; export const ISSUABLE = 'issuable'; export const LIST = 'list'; +/* eslint-disable-next-line @gitlab/require-i18n-strings */ +export const DEFAULT_LABELS = ['to do', 'doing']; + export default { BoardType, ListType, + DEFAULT_LABELS, }; diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js index 887abe79059ff370b703be71bbbd1de56fac9fe3..9641f9d556443135b3fd8dad946a1a41c9a23069 100644 --- a/app/assets/javascripts/boards/index.js +++ b/app/assets/javascripts/boards/index.js @@ -1,5 +1,5 @@ import Vue from 'vue'; -import { mapActions, mapState } from 'vuex'; +import { mapActions, mapGetters, mapState } from 'vuex'; import 'ee_else_ce/boards/models/issue'; import 'ee_else_ce/boards/models/list'; @@ -108,6 +108,7 @@ export default () => { }, computed: { ...mapState(['isShowingEpicsSwimlanes']), + ...mapGetters(['shouldUseGraphQL']), detailIssueVisible() { return Object.keys(this.detailIssue.issue).length; }, @@ -153,7 +154,7 @@ export default () => { boardsStore.disabled = this.disabled; - if (!gon.features.graphqlBoardLists) { + if (!this.shouldUseGraphQL) { this.initialBoardLoad(); } }, diff --git a/app/assets/javascripts/boards/queries/board_labels.query.graphql b/app/assets/javascripts/boards/queries/board_labels.query.graphql new file mode 100644 index 0000000000000000000000000000000000000000..42a94419a97754ec930ad067c0c8916950db9aa2 --- /dev/null +++ b/app/assets/javascripts/boards/queries/board_labels.query.graphql @@ -0,0 +1,23 @@ +#import "~/graphql_shared/fragments/label.fragment.graphql" + +query BoardLabels( + $fullPath: ID! + $searchTerm: String + $isGroup: Boolean = false + $isProject: Boolean = false +) { + group(fullPath: $fullPath) @include(if: $isGroup) { + labels(searchTerm: $searchTerm) { + nodes { + ...Label + } + } + } + project(fullPath: $fullPath) @include(if: $isProject) { + labels(searchTerm: $searchTerm) { + nodes { + ...Label + } + } + } +} diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js index 1fed1228106d463c707cf1e4e333ef59b1fa849b..f61bd3e6d6866569b47db30b12ba39fff130cee0 100644 --- a/app/assets/javascripts/boards/stores/actions.js +++ b/app/assets/javascripts/boards/stores/actions.js @@ -1,12 +1,9 @@ -import Cookies from 'js-cookie'; import { pick } from 'lodash'; import boardListsQuery from 'ee_else_ce/boards/queries/board_lists.query.graphql'; -import { __ } from '~/locale'; -import { parseBoolean } from '~/lib/utils/common_utils'; import createGqClient, { fetchPolicies } from '~/lib/graphql'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; -import { BoardType, ListType, inactiveId } from '~/boards/constants'; +import { BoardType, ListType, inactiveId, DEFAULT_LABELS } from '~/boards/constants'; import * as types from './mutation_types'; import { formatBoardLists, @@ -17,6 +14,7 @@ import { import boardStore from '~/boards/stores/boards_store'; import listsIssuesQuery from '../queries/lists_issues.query.graphql'; +import boardLabelsQuery from '../queries/board_labels.query.graphql'; import createBoardListMutation from '../queries/board_list_create.mutation.graphql'; import updateBoardListMutation from '../queries/board_list_update.mutation.graphql'; import issueMoveListMutation from '../queries/issue_move_list.mutation.graphql'; @@ -83,7 +81,7 @@ export default { if (!lists.nodes.find(l => l.listType === ListType.backlog) && !hideBacklogList) { dispatch('createList', { backlog: true }); } - dispatch('showWelcomeList'); + dispatch('generateDefaultLists'); }) .catch(() => commit(types.RECEIVE_BOARD_LISTS_FAILURE)); }, @@ -121,7 +119,32 @@ export default { ); }, - showWelcomeList: ({ state, dispatch }) => { + showPromotionList: () => {}, + + fetchLabels: ({ state, commit }, searchTerm) => { + const { endpoints, boardType } = state; + const { fullPath } = endpoints; + + const variables = { + fullPath, + searchTerm, + isGroup: boardType === BoardType.group, + isProject: boardType === BoardType.project, + }; + + return gqlClient + .query({ + query: boardLabelsQuery, + variables, + }) + .then(({ data }) => { + const labels = data[boardType]?.labels; + return labels.nodes; + }) + .catch(() => commit(types.RECEIVE_LABELS_FAILURE)); + }, + + generateDefaultLists: async ({ state, commit, dispatch }) => { if (state.disabled) { return; } @@ -132,22 +155,18 @@ export default { ) { return; } - if (parseBoolean(Cookies.get('issue_board_welcome_hidden'))) { - return; - } - dispatch('addList', { - id: 'blank', - listType: ListType.blank, - title: __('Welcome to your issue board!'), - position: 0, - }); - }, - - showPromotionList: () => {}, + const fetchLabelsAndCreateList = label => { + return dispatch('fetchLabels', label) + .then(res => { + if (res.length > 0) { + dispatch('createList', { labelId: res[0].id }); + } + }) + .catch(() => commit(types.GENERATE_DEFAULT_LISTS_FAILURE)); + }; - generateDefaultLists: () => { - notImplemented(); + await Promise.all(DEFAULT_LABELS.map(fetchLabelsAndCreateList)); }, moveList: ( diff --git a/app/assets/javascripts/boards/stores/mutation_types.js b/app/assets/javascripts/boards/stores/mutation_types.js index 09ab08062dfcc8416d8d9d1728d8a38264965422..d5ddba710a9247f1b407a8e6c5a7e38a4cffa652 100644 --- a/app/assets/javascripts/boards/stores/mutation_types.js +++ b/app/assets/javascripts/boards/stores/mutation_types.js @@ -2,6 +2,8 @@ export const SET_INITIAL_BOARD_DATA = 'SET_INITIAL_BOARD_DATA'; export const SET_FILTERS = 'SET_FILTERS'; export const CREATE_LIST_SUCCESS = 'CREATE_LIST_SUCCESS'; export const CREATE_LIST_FAILURE = 'CREATE_LIST_FAILURE'; +export const RECEIVE_LABELS_FAILURE = 'RECEIVE_LABELS_FAILURE'; +export const GENERATE_DEFAULT_LISTS_FAILURE = 'GENERATE_DEFAULT_LISTS_FAILURE'; export const RECEIVE_BOARD_LISTS_SUCCESS = 'RECEIVE_BOARD_LISTS_SUCCESS'; export const RECEIVE_BOARD_LISTS_FAILURE = 'RECEIVE_BOARD_LISTS_FAILURE'; export const SHOW_PROMOTION_LIST = 'SHOW_PROMOTION_LIST'; diff --git a/app/assets/javascripts/boards/stores/mutations.js b/app/assets/javascripts/boards/stores/mutations.js index 0c7dbc0d2ef6e203590cae1aec3fce9e26f77689..361bb94abe0e0a3c0d2519871612884a18383b24 100644 --- a/app/assets/javascripts/boards/stores/mutations.js +++ b/app/assets/javascripts/boards/stores/mutations.js @@ -62,6 +62,14 @@ export default { state.error = s__('Boards|An error occurred while creating the list. Please try again.'); }, + [mutationTypes.RECEIVE_LABELS_FAILURE]: state => { + state.error = s__('Boards|An error occurred while fetching labels. Please reload the page.'); + }, + + [mutationTypes.GENERATE_DEFAULT_LISTS_FAILURE]: state => { + state.error = s__('Boards|An error occurred while generating lists. Please reload the page.'); + }, + [mutationTypes.REQUEST_ADD_LIST]: () => { notImplemented(); }, diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 4f41df0e22bb133cfdddb96fee22e2dc354f5e89..40799480e81bf06a63e86883f881ae2ec3efb693 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -4265,6 +4265,9 @@ msgstr "" msgid "Boards|An error occurred while fetching issues. Please reload the page." msgstr "" +msgid "Boards|An error occurred while fetching labels. Please reload the page." +msgstr "" + msgid "Boards|An error occurred while fetching the board issues. Please reload the page." msgstr "" @@ -4274,6 +4277,9 @@ msgstr "" msgid "Boards|An error occurred while fetching the board swimlanes. Please reload the page." msgstr "" +msgid "Boards|An error occurred while generating lists. Please reload the page." +msgstr "" + msgid "Boards|An error occurred while moving the issue. Please try again." msgstr "" @@ -29695,9 +29701,6 @@ msgstr "" msgid "Welcome to the guided GitLab tour" msgstr "" -msgid "Welcome to your issue board!" -msgstr "" - msgid "What are you searching for?" msgstr "" diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js index 78e7016112172f2f2c0bfcd9f36e594fe09144a0..97b2039b24b9573f727af6118c3288125021dd93 100644 --- a/spec/frontend/boards/stores/actions_spec.js +++ b/spec/frontend/boards/stores/actions_spec.js @@ -11,7 +11,7 @@ import { } from '../mock_data'; import actions, { gqlClient } from '~/boards/stores/actions'; import * as types from '~/boards/stores/mutation_types'; -import { inactiveId, ListType } from '~/boards/constants'; +import { inactiveId } from '~/boards/constants'; import issueMoveListMutation from '~/boards/queries/issue_move_list.mutation.graphql'; import { fullBoardId, formatListIssues, formatBoardLists } from '~/boards/boards_util'; @@ -116,7 +116,7 @@ describe('fetchLists', () => { payload: formattedLists, }, ], - [{ type: 'showWelcomeList' }], + [{ type: 'generateDefaultLists' }], done, ); }); @@ -146,14 +146,15 @@ describe('fetchLists', () => { payload: formattedLists, }, ], - [{ type: 'createList', payload: { backlog: true } }, { type: 'showWelcomeList' }], + [{ type: 'createList', payload: { backlog: true } }, { type: 'generateDefaultLists' }], done, ); }); }); -describe('showWelcomeList', () => { - it('should dispatch addList action', done => { +describe('generateDefaultLists', () => { + let store; + beforeEach(() => { const state = { endpoints: { fullPath: 'gitlab-org', boardId: '1' }, boardType: 'group', @@ -161,26 +162,19 @@ describe('showWelcomeList', () => { boardLists: [{ type: 'backlog' }, { type: 'closed' }], }; - const blankList = { - id: 'blank', - listType: ListType.blank, - title: 'Welcome to your issue board!', - position: 0, - }; - - testAction( - actions.showWelcomeList, - {}, + store = { + commit: jest.fn(), + dispatch: jest.fn(() => Promise.resolve()), state, - [], - [{ type: 'addList', payload: blankList }], - done, - ); + }; }); -}); -describe('generateDefaultLists', () => { - expectNotImplemented(actions.generateDefaultLists); + it('should dispatch fetchLabels', () => { + return actions.generateDefaultLists(store).then(() => { + expect(store.dispatch.mock.calls[0]).toEqual(['fetchLabels', 'to do']); + expect(store.dispatch.mock.calls[1]).toEqual(['fetchLabels', 'doing']); + }); + }); }); describe('createList', () => { diff --git a/spec/frontend/boards/stores/mutations_spec.js b/spec/frontend/boards/stores/mutations_spec.js index 6e53f184bb3ade366cc82fc1c5e2dd14adea8ef8..86056b922bee5c615ae5280e47c62dcb9224a2a0 100644 --- a/spec/frontend/boards/stores/mutations_spec.js +++ b/spec/frontend/boards/stores/mutations_spec.js @@ -82,7 +82,7 @@ describe('Board Store Mutations', () => { mutations.SET_ACTIVE_ID(state, expected); }); - it('updates aciveListId to be the value that is passed', () => { + it('updates activeListId to be the value that is passed', () => { expect(state.activeId).toBe(expected.id); }); @@ -101,6 +101,34 @@ describe('Board Store Mutations', () => { }); }); + describe('CREATE_LIST_FAILURE', () => { + it('sets error message', () => { + mutations.CREATE_LIST_FAILURE(state); + + expect(state.error).toEqual('An error occurred while creating the list. Please try again.'); + }); + }); + + describe('RECEIVE_LABELS_FAILURE', () => { + it('sets error message', () => { + mutations.RECEIVE_LABELS_FAILURE(state); + + expect(state.error).toEqual( + 'An error occurred while fetching labels. Please reload the page.', + ); + }); + }); + + describe('GENERATE_DEFAULT_LISTS_FAILURE', () => { + it('sets error message', () => { + mutations.GENERATE_DEFAULT_LISTS_FAILURE(state); + + expect(state.error).toEqual( + 'An error occurred while generating lists. Please reload the page.', + ); + }); + }); + describe('REQUEST_ADD_LIST', () => { expectNotImplemented(mutations.REQUEST_ADD_LIST); });