Commit 67d753f4 authored by Miguel Rincon's avatar Miguel Rincon

Merge branch 'ss/mv-swimlanes-comp-to-ee' into 'master'

Split board_conent logic between ee and ce compoents

See merge request gitlab-org/gitlab!38724
parents 9639e7a3 fd395c47
<script> <script>
import { mapState } from 'vuex'; import BoardContentLayout from '~/boards/components/board_content_layout.vue';
import BoardColumn from 'ee_else_ce/boards/components/board_column.vue'; import BoardColumn from '~/boards/components/board_column.vue';
import EpicsSwimlanes from 'ee_component/boards/components/epics_swimlanes.vue';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default { export default {
components: { components: {
BoardContentLayout,
BoardColumn, BoardColumn,
EpicsSwimlanes,
},
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', 'boardLists']),
isSwimlanesOn() {
return this.glFeatures.boardsWithSwimlanes && this.isShowingEpicsSwimlanes;
},
}, },
}; };
</script> </script>
<template> <template>
<div> <board-content-layout v-bind="$attrs">
<div <template
v-if="!isSwimlanesOn" #board-content-decoration="{ lists, canAdminList, groupId, disabled, issueLinkBase, rootPath, boardId }"
class="boards-list gl-w-full gl-py-5 gl-px-3 gl-white-space-nowrap"
data-qa-selector="boards_list"
> >
<board-column <board-column
v-for="list in lists" v-for="list in lists"
...@@ -69,16 +27,6 @@ export default { ...@@ -69,16 +27,6 @@ export default {
:root-path="rootPath" :root-path="rootPath"
:board-id="boardId" :board-id="boardId"
/> />
</div> </template>
<epics-swimlanes </board-content-layout>
v-else
ref="swimlanes"
:lists="boardLists"
:can-admin-list="canAdminList"
:disabled="disabled"
:board-id="boardId"
:group-id="groupId"
:root-path="rootPath"
/>
</div>
</template> </template>
<script>
export default {
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,
},
isSwimlanesOff: {
type: Boolean,
required: false,
default: false,
},
},
};
</script>
<template>
<div
:class="{ 'boards-list gl-w-full gl-py-5 gl-px-3 gl-white-space-nowrap': isSwimlanesOff }"
data-qa-selector="boards_list"
data-testid="boards_list"
>
<slot name="board-content-decoration" v-bind="$props"></slot>
</div>
</template>
...@@ -4,6 +4,7 @@ import { mapActions } from 'vuex'; ...@@ -4,6 +4,7 @@ import { mapActions } from 'vuex';
import 'ee_else_ce/boards/models/issue'; import 'ee_else_ce/boards/models/issue';
import 'ee_else_ce/boards/models/list'; import 'ee_else_ce/boards/models/list';
import BoardContent from 'ee_else_ce/boards/components/board_content.vue';
import BoardSidebar from 'ee_else_ce/boards/components/board_sidebar'; import BoardSidebar from 'ee_else_ce/boards/components/board_sidebar';
import initNewListDropdown from 'ee_else_ce/boards/components/new_list_dropdown'; import initNewListDropdown from 'ee_else_ce/boards/components/new_list_dropdown';
import boardConfigToggle from 'ee_else_ce/boards/config_toggle'; import boardConfigToggle from 'ee_else_ce/boards/config_toggle';
...@@ -18,7 +19,6 @@ import { ...@@ -18,7 +19,6 @@ import {
} from 'ee_else_ce/boards/ee_functions'; } from 'ee_else_ce/boards/ee_functions';
import VueApollo from 'vue-apollo'; import VueApollo from 'vue-apollo';
import BoardContent from '~/boards/components/board_content.vue';
import createDefaultClient from '~/lib/graphql'; import createDefaultClient from '~/lib/graphql';
import Flash from '~/flash'; import Flash from '~/flash';
import { __ } from '~/locale'; import { __ } from '~/locale';
......
<script>
import { mapState } from 'vuex';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import EpicsSwimlanes from 'ee_component/boards/components/epics_swimlanes.vue';
import BoardContentLayout from '~/boards/components/board_content_layout.vue';
import BoardColumn from 'ee_component/boards/components/board_column.vue';
export default {
components: {
BoardColumn,
BoardContentLayout,
EpicsSwimlanes,
},
mixins: [glFeatureFlagMixin()],
computed: {
...mapState(['isShowingEpicsSwimlanes', 'boardLists']),
isSwimlanesOn() {
return this.glFeatures.boardsWithSwimlanes && this.isShowingEpicsSwimlanes;
},
},
};
</script>
<template>
<board-content-layout v-bind="$attrs" :is-swimlanes-off="!isSwimlanesOn">
<template
#board-content-decoration="{ lists, canAdminList, disabled, boardId, groupId, issueLinkBase, rootPath }"
>
<epics-swimlanes
v-if="isSwimlanesOn"
ref="swimlanes"
:lists="boardLists"
:can-admin-list="canAdminList"
:disabled="disabled"
:board-id="boardId"
:group-id="groupId"
:root-path="rootPath"
/>
<board-column
v-for="list in lists"
v-else
: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"
/>
</template>
</board-content-layout>
</template>
import { mount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import BoardContent from 'ee_component/boards/components/board_content.vue';
import List from '~/boards/models/list';
import BoardColumn from 'ee_component/boards/components/board_column.vue';
import EpicsSwimlanes from 'ee_component/boards/components/epics_swimlanes.vue';
import defaultState from 'ee_component/boards/stores/state';
import { mockLists } from '../mock_data';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('ee/BoardContent', () => {
let store;
let wrapper;
let mock;
const createStore = (state = defaultState()) => {
store = new Vuex.Store({
state,
actions: {
fetchIssuesForAllLists: () => {},
},
});
};
const createComponent = (boardsWithSwimlanes = false) => {
wrapper = mount(BoardContent, {
localVue,
store,
propsData: {
lists: mockLists.map(listMock => new List(listMock)),
canAdminList: true,
groupId: 1,
disabled: false,
issueLinkBase: '',
rootPath: '',
boardId: '',
},
provide: {
glFeatures: {
boardsWithSwimlanes,
},
},
});
};
beforeEach(() => {
mock = new MockAdapter(axios);
});
afterEach(() => {
mock.restore();
});
describe('when isSwimlanes and boardsWithSwimlanes', () => {
beforeEach(() => {
createStore();
store.state.isShowingEpicsSwimlanes = true;
createComponent(true);
});
it('renders EpicsSwimlanes', () => {
expect(wrapper.find(EpicsSwimlanes).exists()).toBe(true);
});
});
it('finds BoardColumns', () => {
createStore();
createComponent();
expect(wrapper.findAll(BoardColumn).length).toBe(mockLists.length);
});
});
import { mount } from '@vue/test-utils';
import BoardContentLayout from '~/boards/components/board_content_layout.vue';
const TestComponent = {
components: { BoardContentLayout },
template: `
<div>
<board-content-layout v-bind="$attrs">
<template v-slot:board-content-decoration="{ groupId }">
<p data-testid="child">{{ groupId }}</p>
</template>
</board-content-layout>
</div>
`,
};
describe('BoardContentLayout', () => {
let wrapper;
const groupId = 1;
const createComponent = props => {
wrapper = mount(TestComponent, {
propsData: {
lists: [],
canAdminList: true,
groupId,
disabled: false,
issueLinkBase: '',
rootPath: '',
boardId: '',
...props,
},
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('renders children in the slot', () => {
createComponent();
expect(wrapper.find('[data-testid="child"]').exists()).toBe(true);
});
it('renders groupId from the scoped slot', () => {
createComponent();
expect(wrapper.find('[data-testid="child"]').text()).toContain(groupId);
});
describe('when isSwimlanesOff', () => {
it('renders the correct class on the root div', () => {
createComponent({ isSwimlanesOff: true });
expect(wrapper.find('[data-testid="boards_list"]').classes()).toEqual([
'boards-list',
'gl-w-full',
'gl-py-5',
'gl-px-3',
'gl-white-space-nowrap',
]);
});
});
});
import { mount } from '@vue/test-utils';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import BoardContent from '~/boards/components/board_content.vue';
import BoardColumn from '~/boards/components/board_column.vue';
import List from '~/boards/models/list';
import { listObj } from '../mock_data';
describe('BoardContent', () => {
let wrapper;
let mock;
const createComponent = () => {
wrapper = mount(BoardContent, {
propsData: {
lists: [new List(listObj)],
canAdminList: true,
groupId: 1,
disabled: false,
issueLinkBase: '',
rootPath: '',
boardId: '',
},
});
};
beforeEach(() => {
mock = new MockAdapter(axios);
});
afterEach(() => {
mock.restore();
});
it('finds BoardColumns', () => {
createComponent();
expect(wrapper.findAll(BoardColumn).length).toBe(1);
});
});
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