Commit ac46d494 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'swimlanes-fetch-boards-issues-vuex-graphql' into 'master'

Fetch epics swimlanes action

See merge request gitlab-org/gitlab!33469
parents 809937c0 b5e99b73
<script>
import { mapState } from 'vuex';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import BoardColumn from 'ee_else_ce/boards/components/board_column.vue';
export default {
components: {
BoardColumn,
},
mixins: [glFeatureFlagMixin()],
props: {
lists: {
type: Array,
required: true,
},
canAdminList: {
type: Boolean,
required: true,
},
groupId: {
type: Number,
required: false,
default: null,
},
disabled: {
type: Boolean,
required: true,
},
issueLinkBase: {
type: String,
required: true,
},
rootPath: {
type: String,
required: true,
},
boardId: {
type: String,
required: true,
},
},
computed: {
...mapState(['isShowingEpicsSwimlanes']),
isSwimlanesOn() {
return this.glFeatures.boardsWithSwimlanes && this.isShowingEpicsSwimlanes;
},
},
};
</script>
<template>
<div
v-if="!isSwimlanesOn"
class="boards-list w-100 py-3 px-2 text-nowrap"
data-qa-selector="boards_list"
>
<board-column
v-for="list in lists"
:key="list.id"
ref="board"
:can-admin-list="canAdminList"
:group-id="groupId"
:list="list"
:disabled="disabled"
:issue-link-base="issueLinkBase"
:root-path="rootPath"
:board-id="boardId"
/>
</div>
</template>
import $ from 'jquery';
import Vue from 'vue';
import { mapActions } from 'vuex';
import 'ee_else_ce/boards/models/issue';
import 'ee_else_ce/boards/models/list';
import BoardContent from '~/boards/components/board_content.vue';
import BoardSidebar from 'ee_else_ce/boards/components/board_sidebar';
import initNewListDropdown from 'ee_else_ce/boards/components/new_list_dropdown';
import boardConfigToggle from 'ee_else_ce/boards/config_toggle';
......@@ -77,6 +79,7 @@ export default () => {
issueBoardsApp = new Vue({
el: $boardApp,
components: {
BoardContent,
Board: () =>
window?.gon?.features?.sfcIssueBoards
? import('ee_else_ce/boards/components/board_column.vue')
......@@ -115,14 +118,16 @@ export default () => {
},
},
created() {
boardsStore.setEndpoints({
const endpoints = {
boardsEndpoint: this.boardsEndpoint,
recentBoardsEndpoint: this.recentBoardsEndpoint,
listsEndpoint: this.listsEndpoint,
bulkUpdatePath: this.bulkUpdatePath,
boardId: this.boardId,
fullPath: $boardApp.dataset.fullPath,
});
};
this.setEndpoints(endpoints);
boardsStore.setEndpoints(endpoints);
boardsStore.rootPath = this.boardsEndpoint;
eventHub.$on('updateTokens', this.updateTokens);
......@@ -193,6 +198,7 @@ export default () => {
}
},
methods: {
...mapActions(['setEndpoints']),
updateTokens() {
this.filterManager.updateTokens();
},
......
import * as types from './mutation_types';
const notImplemented = () => {
/* eslint-disable-next-line @gitlab/require-i18n-strings */
throw new Error('Not implemented!');
};
export default {
setEndpoints: () => {
notImplemented();
setEndpoints: ({ commit }, endpoints) => {
commit(types.SET_ENDPOINTS, endpoints);
},
fetchLists: () => {
......
......@@ -6,8 +6,8 @@ const notImplemented = () => {
};
export default {
[mutationTypes.SET_ENDPOINTS]: () => {
notImplemented();
[mutationTypes.SET_ENDPOINTS]: (state, endpoints) => {
state.endpoints = endpoints;
},
[mutationTypes.REQUEST_ADD_LIST]: () => {
......
import { inactiveListId } from '~/boards/constants';
export default () => ({
endpoints: {},
isShowingLabels: true,
activeListId: inactiveListId,
});
......@@ -9,6 +9,7 @@ class Groups::BoardsController < Groups::ApplicationController
before_action do
push_frontend_feature_flag(:multi_select_board, default_enabled: true)
push_frontend_feature_flag(:sfc_issue_boards, default_enabled: true)
push_frontend_feature_flag(:boards_with_swimlanes, group, default_enabled: false)
end
private
......
......@@ -20,20 +20,31 @@
#board-app.boards-app.position-relative{ "v-cloak" => "true", data: board_data, ":class" => "{ 'is-compact': detailIssueVisible }" }
= render 'shared/issuable/search_bar', type: :boards, board: board
.boards-list.w-100.py-3.px-2.text-nowrap{ data: { qa_selector: "boards_list" } }
.boards-app-loading.w-100.text-center{ "v-if" => "loading" }
= icon("spinner spin 2x")
%board{ "v-cloak" => "true",
"v-for" => "list in state.lists",
"ref" => "board",
- if Feature.enabled?(:boards_with_swimlanes, current_board_parent)
%board-content{ "v-cloak" => "true",
"ref" => "board_content",
":lists" => "state.lists",
":can-admin-list" => can_admin_list,
":group-id" => group_id,
":list" => "list",
":disabled" => "disabled",
":issue-link-base" => "issueLinkBase",
":root-path" => "rootPath",
":board-id" => "boardId",
":key" => "list.id" }
":board-id" => "boardId" }
- else
.boards-list.w-100.py-3.px-2.text-nowrap{ data: { qa_selector: "boards_list" } }
.boards-app-loading.w-100.text-center{ "v-if" => "loading" }
= icon("spinner spin 2x")
%board{ "v-cloak" => "true",
"v-for" => "list in state.lists",
"ref" => "board",
":can-admin-list" => can_admin_list,
":group-id" => group_id,
":list" => "list",
":disabled" => "disabled",
":issue-link-base" => "issueLinkBase",
":root-path" => "rootPath",
":board-id" => "boardId",
":key" => "list.id" }
= render "shared/boards/components/sidebar", group: group
= render_if_exists 'shared/boards/components/board_settings_sidebar'
- if @project
......
#import "ee_else_ce/boards/queries/board_list.fragment.graphql"
query GroupBoard($fullPath: ID!, $boardId: ID!) {
group(fullPath: $fullPath) {
board(id: $boardId) {
lists {
nodes {
...BoardListFragment
}
}
}
}
}
......@@ -3,11 +3,35 @@ import actionsCE from '~/boards/stores/actions';
import boardsStoreEE from './boards_store_ee';
import * as types from './mutation_types';
import createDefaultClient from '~/lib/graphql';
import epicsSwimlanes from '../queries/epics_swimlanes.query.graphql';
const notImplemented = () => {
/* eslint-disable-next-line @gitlab/require-i18n-strings */
throw new Error('Not implemented!');
};
const gqlClient = createDefaultClient();
const fetchEpicsSwimlanes = ({ endpoints }) => {
const { fullPath, boardId } = endpoints;
const query = epicsSwimlanes;
const variables = {
fullPath,
boardId: `gid://gitlab/Board/${boardId}`,
};
return gqlClient
.query({
query,
variables,
})
.then(({ data }) => {
return data;
});
};
export default {
...actionsCE,
......@@ -52,7 +76,23 @@ export default {
notImplemented();
},
toggleEpicSwimlanes: ({ commit }) => {
toggleEpicSwimlanes: ({ state, commit, dispatch }) => {
commit(types.TOGGLE_EPICS_SWIMLANES);
if (state.isShowingEpicsSwimlanes) {
fetchEpicsSwimlanes(state)
.then(swimlanes => {
dispatch('receiveSwimlanesSuccess', swimlanes);
})
.catch(() => dispatch('receiveSwimlanesFailure'));
}
},
receiveSwimlanesSuccess: ({ commit }, swimlanes) => {
commit(types.RECEIVE_SWIMLANES_SUCCESS, swimlanes);
},
receiveSwimlanesFailure: ({ commit }) => {
commit(types.RECEIVE_SWIMLANES_FAILURE);
},
};
......@@ -13,4 +13,6 @@ export const RECEIVE_REMOVE_BOARD_ERROR = 'RECEIVE_REMOVE_BOARD_ERROR';
export const TOGGLE_PROMOTION_STATE = 'TOGGLE_PROMOTION_STATE';
export const TOGGLE_LABELS = 'TOGGLE_LABELS';
export const TOGGLE_EPICS_SWIMLANES = 'TOGGLE_EPICS_SWIMLANES';
export const RECEIVE_SWIMLANES_SUCCESS = 'RECEIVE_SWIMLANES_SUCCESS';
export const RECEIVE_SWIMLANES_FAILURE = 'RECEIVE_SWIMLANES_FAILURE';
export const SET_ACTIVE_LIST_ID = 'SET_ACTIVE_LIST_ID';
import mutationsCE from '~/boards/stores/mutations';
import * as mutationTypes from './mutation_types';
const notImplemented = () => {
......@@ -6,6 +7,7 @@ const notImplemented = () => {
};
export default {
...mutationsCE,
[mutationTypes.TOGGLE_LABELS]: state => {
state.isShowingLabels = !state.isShowingLabels;
},
......@@ -67,5 +69,16 @@ export default {
[mutationTypes.TOGGLE_EPICS_SWIMLANES]: state => {
state.isShowingEpicsSwimlanes = !state.isShowingEpicsSwimlanes;
state.epicsSwimlanesFetchInProgress = true;
},
[mutationTypes.RECEIVE_SWIMLANES_SUCCESS]: (state, swimlanes) => {
state.epicsSwimlanes = swimlanes;
state.epicsSwimlanesFetchInProgress = false;
},
[mutationTypes.RECEIVE_SWIMLANES_FAILURE]: state => {
state.epicsSwimlanesFetchFailure = true;
state.epicsSwimlanesFetchInProgress = false;
},
};
......@@ -4,4 +4,7 @@ export default () => ({
...createStateCE(),
isShowingEpicsSwimlanes: false,
epicsSwimlanesFetchInProgress: false,
epicsSwimlanesFetchFailure: false,
epicsSwimlanes: {},
});
......@@ -92,17 +92,46 @@ describe('togglePromotionState', () => {
});
describe('toggleEpicSwimlanes', () => {
it('should commit mutation TOGGLE_EPICS_SWIMLANES', done => {
it('should commit mutation TOGGLE_EPICS_SWIMLANES', () => {
const state = {
isShowingEpicsSwimlanes: true,
isShowingEpicsSwimlanes: false,
endpoints: {
fullPath: 'gitlab-org',
boardId: 1,
},
};
testAction(
return testAction(
actions.toggleEpicSwimlanes,
null,
state,
[{ type: types.TOGGLE_EPICS_SWIMLANES }],
[],
);
});
});
describe('receiveSwimlanesSuccess', () => {
it('should commit mutation RECEIVE_SWIMLANES_SUCCESS', done => {
testAction(
actions.receiveSwimlanesSuccess,
{},
{},
[{ type: types.RECEIVE_SWIMLANES_SUCCESS, payload: {} }],
[],
done,
);
});
});
describe('receiveSwimlanesFailure', () => {
it('should commit mutation RECEIVE_SWIMLANES_SUCCESS', done => {
testAction(
actions.receiveSwimlanesFailure,
null,
{},
[{ type: types.RECEIVE_SWIMLANES_FAILURE }],
[],
done,
);
});
......
import actions from '~/boards/stores/actions';
import * as types from '~/boards/stores/mutation_types';
import testAction from 'helpers/vuex_action_helper';
const expectNotImplemented = action => {
it('is not implemented', () => {
......@@ -7,7 +9,20 @@ const expectNotImplemented = action => {
};
describe('setEndpoints', () => {
expectNotImplemented(actions.setEndpoints);
it('sets endpoints object', () => {
const mockEndpoints = {
foo: 'bar',
bar: 'baz',
};
return testAction(
actions.setEndpoints,
mockEndpoints,
{},
[{ type: types.SET_ENDPOINTS, payload: mockEndpoints }],
[],
);
});
});
describe('fetchLists', () => {
......
import mutations from '~/boards/stores/mutations';
import * as types from '~/boards/stores/mutation_types';
import defaultState from '~/boards/stores/state';
const expectNotImplemented = action => {
it('is not implemented', () => {
......@@ -6,86 +8,107 @@ const expectNotImplemented = action => {
});
};
describe('SET_ENDPOINTS', () => {
expectNotImplemented(mutations.SET_ENDPOINTS);
});
describe('Board Store Mutations', () => {
let state;
describe('REQUEST_ADD_LIST', () => {
expectNotImplemented(mutations.REQUEST_ADD_LIST);
});
beforeEach(() => {
state = defaultState();
});
describe('RECEIVE_ADD_LIST_SUCCESS', () => {
expectNotImplemented(mutations.RECEIVE_ADD_LIST_SUCCESS);
});
describe('SET_ENDPOINTS', () => {
it('Should set initial Boards data to state', () => {
const endpoints = {
boardsEndpoint: '/boards/',
recentBoardsEndpoint: '/boards/',
listsEndpoint: '/boards/lists',
bulkUpdatePath: '/boards/bulkUpdate',
boardId: 1,
fullPath: 'gitlab-org',
};
mutations[types.SET_ENDPOINTS](state, endpoints);
expect(state.endpoints).toEqual(endpoints);
});
});
describe('RECEIVE_ADD_LIST_ERROR', () => {
expectNotImplemented(mutations.RECEIVE_ADD_LIST_ERROR);
});
describe('REQUEST_ADD_LIST', () => {
expectNotImplemented(mutations.REQUEST_ADD_LIST);
});
describe('REQUEST_UPDATE_LIST', () => {
expectNotImplemented(mutations.REQUEST_UPDATE_LIST);
});
describe('RECEIVE_ADD_LIST_SUCCESS', () => {
expectNotImplemented(mutations.RECEIVE_ADD_LIST_SUCCESS);
});
describe('RECEIVE_UPDATE_LIST_SUCCESS', () => {
expectNotImplemented(mutations.RECEIVE_UPDATE_LIST_SUCCESS);
});
describe('RECEIVE_ADD_LIST_ERROR', () => {
expectNotImplemented(mutations.RECEIVE_ADD_LIST_ERROR);
});
describe('RECEIVE_UPDATE_LIST_ERROR', () => {
expectNotImplemented(mutations.RECEIVE_UPDATE_LIST_ERROR);
});
describe('REQUEST_UPDATE_LIST', () => {
expectNotImplemented(mutations.REQUEST_UPDATE_LIST);
});
describe('REQUEST_REMOVE_LIST', () => {
expectNotImplemented(mutations.REQUEST_REMOVE_LIST);
});
describe('RECEIVE_UPDATE_LIST_SUCCESS', () => {
expectNotImplemented(mutations.RECEIVE_UPDATE_LIST_SUCCESS);
});
describe('RECEIVE_REMOVE_LIST_SUCCESS', () => {
expectNotImplemented(mutations.RECEIVE_REMOVE_LIST_SUCCESS);
});
describe('RECEIVE_UPDATE_LIST_ERROR', () => {
expectNotImplemented(mutations.RECEIVE_UPDATE_LIST_ERROR);
});
describe('RECEIVE_REMOVE_LIST_ERROR', () => {
expectNotImplemented(mutations.RECEIVE_REMOVE_LIST_ERROR);
});
describe('REQUEST_REMOVE_LIST', () => {
expectNotImplemented(mutations.REQUEST_REMOVE_LIST);
});
describe('REQUEST_ADD_ISSUE', () => {
expectNotImplemented(mutations.REQUEST_ADD_ISSUE);
});
describe('RECEIVE_REMOVE_LIST_SUCCESS', () => {
expectNotImplemented(mutations.RECEIVE_REMOVE_LIST_SUCCESS);
});
describe('RECEIVE_ADD_ISSUE_SUCCESS', () => {
expectNotImplemented(mutations.RECEIVE_ADD_ISSUE_SUCCESS);
});
describe('RECEIVE_REMOVE_LIST_ERROR', () => {
expectNotImplemented(mutations.RECEIVE_REMOVE_LIST_ERROR);
});
describe('RECEIVE_ADD_ISSUE_ERROR', () => {
expectNotImplemented(mutations.RECEIVE_ADD_ISSUE_ERROR);
});
describe('REQUEST_ADD_ISSUE', () => {
expectNotImplemented(mutations.REQUEST_ADD_ISSUE);
});
describe('REQUEST_MOVE_ISSUE', () => {
expectNotImplemented(mutations.REQUEST_MOVE_ISSUE);
});
describe('RECEIVE_ADD_ISSUE_SUCCESS', () => {
expectNotImplemented(mutations.RECEIVE_ADD_ISSUE_SUCCESS);
});
describe('RECEIVE_MOVE_ISSUE_SUCCESS', () => {
expectNotImplemented(mutations.RECEIVE_MOVE_ISSUE_SUCCESS);
});
describe('RECEIVE_ADD_ISSUE_ERROR', () => {
expectNotImplemented(mutations.RECEIVE_ADD_ISSUE_ERROR);
});
describe('RECEIVE_MOVE_ISSUE_ERROR', () => {
expectNotImplemented(mutations.RECEIVE_MOVE_ISSUE_ERROR);
});
describe('REQUEST_MOVE_ISSUE', () => {
expectNotImplemented(mutations.REQUEST_MOVE_ISSUE);
});
describe('REQUEST_UPDATE_ISSUE', () => {
expectNotImplemented(mutations.REQUEST_UPDATE_ISSUE);
});
describe('RECEIVE_MOVE_ISSUE_SUCCESS', () => {
expectNotImplemented(mutations.RECEIVE_MOVE_ISSUE_SUCCESS);
});
describe('RECEIVE_UPDATE_ISSUE_SUCCESS', () => {
expectNotImplemented(mutations.RECEIVE_UPDATE_ISSUE_SUCCESS);
});
describe('RECEIVE_MOVE_ISSUE_ERROR', () => {
expectNotImplemented(mutations.RECEIVE_MOVE_ISSUE_ERROR);
});
describe('RECEIVE_UPDATE_ISSUE_ERROR', () => {
expectNotImplemented(mutations.RECEIVE_UPDATE_ISSUE_ERROR);
});
describe('REQUEST_UPDATE_ISSUE', () => {
expectNotImplemented(mutations.REQUEST_UPDATE_ISSUE);
});
describe('SET_CURRENT_PAGE', () => {
expectNotImplemented(mutations.SET_CURRENT_PAGE);
});
describe('RECEIVE_UPDATE_ISSUE_SUCCESS', () => {
expectNotImplemented(mutations.RECEIVE_UPDATE_ISSUE_SUCCESS);
});
describe('TOGGLE_EMPTY_STATE', () => {
expectNotImplemented(mutations.TOGGLE_EMPTY_STATE);
describe('RECEIVE_UPDATE_ISSUE_ERROR', () => {
expectNotImplemented(mutations.RECEIVE_UPDATE_ISSUE_ERROR);
});
describe('SET_CURRENT_PAGE', () => {
expectNotImplemented(mutations.SET_CURRENT_PAGE);
});
describe('TOGGLE_EMPTY_STATE', () => {
expectNotImplemented(mutations.TOGGLE_EMPTY_STATE);
});
});
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