Commit b66de395 authored by Florie Guibert's avatar Florie Guibert

Swimlanes - Generate default labels lists

- Remove welcome list
- Create To Do and Doing lists using labels
parent 031cd454
......@@ -38,12 +38,11 @@ export default {
},
mounted() {
if (this.glFeatures.graphqlBoardLists) {
this.fetchLists();
this.showPromotionList();
}
},
methods: {
...mapActions(['fetchLists', 'showPromotionList']),
...mapActions(['showPromotionList']),
},
};
</script>
......
......@@ -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,
};
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();
}
},
......
#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
}
}
}
}
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: (
......
......@@ -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';
......
......@@ -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();
},
......
......@@ -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 ""
......
......@@ -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', () => {
......
......@@ -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);
});
......
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