Commit 35af9a19 authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'use-swimlanes-sidebar-for-group-boards' into 'master'

Use swimlanes sidebar for group boards [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!51480
parents 51823053 b904a794
<script>
import { mapActions, mapGetters } from 'vuex';
import IssueCardInner from './issue_card_inner.vue';
import IssueCardInnerDeprecated from './issue_card_inner_deprecated.vue';
import boardsStore from '../stores/boards_store';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { ISSUABLE } from '~/boards/constants';
export default {
name: 'BoardCardLayout',
components: {
IssueCardInner: gon.features?.graphqlBoardLists ? IssueCardInner : IssueCardInnerDeprecated,
},
mixins: [glFeatureFlagMixin()],
props: {
list: {
type: Object,
......@@ -42,11 +46,13 @@ export default {
};
},
computed: {
...mapGetters(['isSwimlanesOn']),
multiSelectVisible() {
return this.multiSelect.list.findIndex((issue) => issue.id === this.issue.id) > -1;
},
},
methods: {
...mapActions(['setActiveId']),
mouseDown() {
this.showDetail = true;
},
......@@ -57,6 +63,11 @@ export default {
// Don't do anything if this happened on a no trigger element
if (e.target.classList.contains('js-no-trigger')) return;
if (this.glFeatures.graphqlBoardLists || this.isSwimlanesOn) {
this.setActiveId({ id: this.issue.id, sidebarType: ISSUABLE });
return;
}
const isMultiSelect = e.ctrlKey || e.metaKey;
if (this.showDetail || isMultiSelect) {
......
......@@ -109,14 +109,14 @@ export default {
/>
</component>
<template v-else>
<epics-swimlanes
ref="swimlanes"
:lists="boardListsToUse"
:can-admin-list="canAdminList"
:disabled="disabled"
/>
<board-content-sidebar />
</template>
<epics-swimlanes
v-else
ref="swimlanes"
:lists="boardListsToUse"
:can-admin-list="canAdminList"
:disabled="disabled"
/>
<board-content-sidebar v-if="isSwimlanesOn || glFeatures.graphqlBoardLists" />
</div>
</template>
......@@ -6,7 +6,6 @@ import defaultSortableConfig from '~/sortable/sortable_config';
import BoardCardLayout from '~/boards/components/board_card_layout.vue';
import eventHub from '~/boards/eventhub';
import BoardNewIssue from '~/boards/components/board_new_issue.vue';
import { ISSUABLE } from '~/boards/constants';
export default {
components: {
......@@ -90,7 +89,7 @@ export default {
eventHub.$off(`toggle-issue-form-${this.list.id}`, this.toggleForm);
},
methods: {
...mapActions(['setActiveId', 'moveIssue', 'moveIssueEpic', 'fetchIssuesForList']),
...mapActions(['moveIssue', 'moveIssueEpic', 'fetchIssuesForList']),
toggleForm() {
this.showIssueForm = !this.showIssueForm;
if (this.showIssueForm && this.isUnassignedIssuesLane) {
......@@ -100,9 +99,6 @@ export default {
isActiveIssue(issue) {
return this.activeId === issue.id;
},
showIssue(issue) {
this.setActiveId({ id: issue.id, sidebarType: ISSUABLE });
},
handleDragOnStart() {
document.body.classList.add('is-dragging');
},
......@@ -180,7 +176,6 @@ export default {
:issue="issue"
:disabled="disabled || !canAdminEpic"
:is-active="isActiveIssue(issue)"
@show="showIssue(issue)"
/>
<gl-loading-icon v-if="isLoadingMore && isUnassignedIssuesLane" size="sm" class="gl-py-3" />
</component>
......
/* global List */
/* global ListLabel */
import { shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import waitForPromises from 'helpers/wait_for_promises';
......@@ -10,20 +11,35 @@ import axios from '~/lib/utils/axios_utils';
import '~/boards/models/label';
import '~/boards/models/assignee';
import '~/boards/models/list';
import store from '~/boards/stores';
import boardsVuexStore from '~/boards/stores';
import boardsStore from '~/boards/stores/boards_store';
import BoardCardLayout from '~/boards/components/board_card_layout.vue';
import issueCardInner from '~/boards/components/issue_card_inner.vue';
import { listObj, boardsMockInterceptor, setMockEndpoints } from '../mock_data';
import { ISSUABLE } from '~/boards/constants';
describe('Board card layout', () => {
let wrapper;
let mock;
let list;
let store;
const localVue = createLocalVue();
localVue.use(Vuex);
const createStore = ({ getters = {}, actions = {} } = {}) => {
store = new Vuex.Store({
...boardsVuexStore,
actions,
getters,
});
};
// this particular mount component needs to be used after the root beforeEach because it depends on list being initialized
const mountComponent = (propsData) => {
const mountComponent = ({ propsData = {}, provide = {} } = {}) => {
wrapper = shallowMount(BoardCardLayout, {
localVue,
stubs: {
issueCardInner,
},
......@@ -39,6 +55,7 @@ describe('Board card layout', () => {
groupId: null,
rootPath: '/',
scopedLabelsAvailable: false,
...provide,
},
});
};
......@@ -75,6 +92,7 @@ describe('Board card layout', () => {
describe('mouse events', () => {
it('sets showDetail to true on mousedown', async () => {
createStore();
mountComponent();
wrapper.trigger('mousedown');
......@@ -84,6 +102,7 @@ describe('Board card layout', () => {
});
it('sets showDetail to false on mousemove', async () => {
createStore();
mountComponent();
wrapper.trigger('mousedown');
await wrapper.vm.$nextTick();
......@@ -92,5 +111,49 @@ describe('Board card layout', () => {
await wrapper.vm.$nextTick();
expect(wrapper.vm.showDetail).toBe(false);
});
it("calls 'setActiveId' when 'graphqlBoardLists' feature flag is turned on", async () => {
const setActiveId = jest.fn();
createStore({
actions: {
setActiveId,
},
});
mountComponent({
provide: {
glFeatures: { graphqlBoardLists: true },
},
});
wrapper.trigger('mouseup');
await wrapper.vm.$nextTick();
expect(setActiveId).toHaveBeenCalledTimes(1);
expect(setActiveId).toHaveBeenCalledWith(expect.any(Object), {
id: list.issues[0].id,
sidebarType: ISSUABLE,
});
});
it("calls 'setActiveId' when epic swimlanes is active", async () => {
const setActiveId = jest.fn();
const isSwimlanesOn = () => true;
createStore({
getters: { isSwimlanesOn },
actions: {
setActiveId,
},
});
mountComponent();
wrapper.trigger('mouseup');
await wrapper.vm.$nextTick();
expect(setActiveId).toHaveBeenCalledTimes(1);
expect(setActiveId).toHaveBeenCalledWith(expect.any(Object), {
id: list.issues[0].id,
sidebarType: ISSUABLE,
});
});
});
});
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