Commit 1217e2ee authored by Axel Garcia's avatar Axel Garcia Committed by Phil Hughes

Add event to handle closing all board sidebars

This was made to avoid having to _manually_ close all sidebars (to open
a new one for example), and to prevent having two or more sidebars open
at the same time.

Each of the sidebars components are listening to a 'sidebars.closeAll'
event that has an optional `omit` property to avoid closing a sidebar
if not needed, for example, when browsing through issues.
parent 858c3de9
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
/* eslint-disable vue/require-default-prop */ /* eslint-disable vue/require-default-prop */
import IssueCardInner from './issue_card_inner.vue'; import IssueCardInner from './issue_card_inner.vue';
import eventHub from '../eventhub'; import eventHub from '../eventhub';
import sidebarEventHub from '~/sidebar/event_hub';
import boardsStore from '../stores/boards_store'; import boardsStore from '../stores/boards_store';
export default { export default {
...@@ -73,6 +74,11 @@ export default { ...@@ -73,6 +74,11 @@ export default {
showIssue(e) { showIssue(e) {
if (e.target.classList.contains('js-no-trigger')) return; if (e.target.classList.contains('js-no-trigger')) return;
// If no issues are opened, close all sidebars first
if (!boardsStore.detail?.issue?.id) {
sidebarEventHub.$emit('sidebar.closeAll');
}
// If CMD or CTRL is clicked // If CMD or CTRL is clicked
const isMultiSelect = this.canMultiSelect && (e.ctrlKey || e.metaKey); const isMultiSelect = this.canMultiSelect && (e.ctrlKey || e.metaKey);
......
...@@ -103,12 +103,14 @@ export default Vue.extend({ ...@@ -103,12 +103,14 @@ export default Vue.extend({
eventHub.$on('sidebar.addAssignee', this.addAssignee); eventHub.$on('sidebar.addAssignee', this.addAssignee);
eventHub.$on('sidebar.removeAllAssignees', this.removeAllAssignees); eventHub.$on('sidebar.removeAllAssignees', this.removeAllAssignees);
eventHub.$on('sidebar.saveAssignees', this.saveAssignees); eventHub.$on('sidebar.saveAssignees', this.saveAssignees);
eventHub.$on('sidebar.closeAll', this.closeSidebar);
}, },
beforeDestroy() { beforeDestroy() {
eventHub.$off('sidebar.removeAssignee', this.removeAssignee); eventHub.$off('sidebar.removeAssignee', this.removeAssignee);
eventHub.$off('sidebar.addAssignee', this.addAssignee); eventHub.$off('sidebar.addAssignee', this.addAssignee);
eventHub.$off('sidebar.removeAllAssignees', this.removeAllAssignees); eventHub.$off('sidebar.removeAllAssignees', this.removeAllAssignees);
eventHub.$off('sidebar.saveAssignees', this.saveAssignees); eventHub.$off('sidebar.saveAssignees', this.saveAssignees);
eventHub.$off('sidebar.closeAll', this.closeSidebar);
}, },
mounted() { mounted() {
new IssuableContext(this.currentUser); new IssuableContext(this.currentUser);
......
import { mapActions } from 'vuex'; import { mapActions, mapState } from 'vuex';
import boardPromotionState from 'ee/boards/components/board_promotion_state'; import boardPromotionState from 'ee/boards/components/board_promotion_state';
import { GlTooltip } from '@gitlab/ui'; import { GlTooltip } from '@gitlab/ui';
import Board from '~/boards/components/board'; import Board from '~/boards/components/board';
import { __, sprintf, s__ } from '~/locale'; import { __, sprintf, s__ } from '~/locale';
import boardsStore from '~/boards/stores/boards_store'; import boardsStore from '~/boards/stores/boards_store';
import eventHub from '~/sidebar/event_hub';
/** /**
* Please have a look at: * Please have a look at:
...@@ -22,6 +23,7 @@ export default Board.extend({ ...@@ -22,6 +23,7 @@ export default Board.extend({
boardPromotionState, boardPromotionState,
}, },
computed: { computed: {
...mapState(['activeListId']),
issuesTooltip() { issuesTooltip() {
const { issuesSize, maxIssueCount } = this.list; const { issuesSize, maxIssueCount } = this.list;
...@@ -48,6 +50,10 @@ export default Board.extend({ ...@@ -48,6 +50,10 @@ export default Board.extend({
methods: { methods: {
...mapActions(['setActiveListId']), ...mapActions(['setActiveListId']),
openSidebarSettings() { openSidebarSettings() {
// If no list is opened, close all sidebars first
if (!this.activeListId) {
eventHub.$emit('sidebar.closeAll');
}
this.setActiveListId(this.list.id); this.setActiveListId(this.list.id);
}, },
}, },
......
...@@ -12,6 +12,7 @@ import { mapActions, mapState } from 'vuex'; ...@@ -12,6 +12,7 @@ import { mapActions, mapState } from 'vuex';
import { __, n__ } from '~/locale'; import { __, n__ } from '~/locale';
import autofocusonshow from '~/vue_shared/directives/autofocusonshow'; import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
import boardsStoreEE from '../stores/boards_store_ee'; import boardsStoreEE from '../stores/boards_store_ee';
import eventHub from '~/sidebar/event_hub';
import flash from '~/flash'; import flash from '~/flash';
import { isScopedLabel } from '~/lib/utils/common_utils'; import { isScopedLabel } from '~/lib/utils/common_utils';
...@@ -99,6 +100,12 @@ export default { ...@@ -99,6 +100,12 @@ export default {
} }
}, },
}, },
created() {
eventHub.$on('sidebar.closeAll', this.closeSidebar);
},
beforeDestroy() {
eventHub.$off('sidebar.closeAll', this.closeSidebar);
},
methods: { methods: {
...mapActions(['setActiveListId', 'updateListWipLimit']), ...mapActions(['setActiveListId', 'updateListWipLimit']),
closeSidebar() { closeSidebar() {
......
...@@ -8,6 +8,7 @@ import BoardSettingsSidebar from 'ee/boards/components/board_settings_sidebar.vu ...@@ -8,6 +8,7 @@ import BoardSettingsSidebar from 'ee/boards/components/board_settings_sidebar.vu
import boardsStore from 'ee_else_ce/boards/stores/boards_store_ee'; import boardsStore from 'ee_else_ce/boards/stores/boards_store_ee';
import getters from 'ee_else_ce/boards/stores/getters'; import getters from 'ee_else_ce/boards/stores/getters';
import bs from '~/boards/stores/boards_store'; import bs from '~/boards/stores/boards_store';
import sidebarEventHub from '~/sidebar/event_hub';
import flash from '~/flash'; import flash from '~/flash';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
...@@ -100,6 +101,20 @@ describe('BoardSettingsSideBar', () => { ...@@ -100,6 +101,20 @@ describe('BoardSettingsSideBar', () => {
); );
}); });
}); });
it('calls closeSidebar on sidebar.closeAll event', () => {
createComponent({ activeListId: 0 }, { setActiveListId: jest.fn() });
sidebarEventHub.$emit('sidebar.closeAll');
return wrapper.vm.$nextTick().then(() => {
expect(storeActions.setActiveListId).toHaveBeenCalledWith(
expect.anything(),
0,
undefined,
);
});
});
}); });
describe('when activeListId is zero', () => { describe('when activeListId is zero', () => {
......
...@@ -9,6 +9,7 @@ import axios from '~/lib/utils/axios_utils'; ...@@ -9,6 +9,7 @@ import axios from '~/lib/utils/axios_utils';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import eventHub from '~/boards/eventhub'; import eventHub from '~/boards/eventhub';
import sidebarEventHub from '~/sidebar/event_hub';
import '~/boards/models/label'; import '~/boards/models/label';
import '~/boards/models/assignee'; import '~/boards/models/assignee';
import '~/boards/models/list'; import '~/boards/models/list';
...@@ -201,7 +202,8 @@ describe('Board card', () => { ...@@ -201,7 +202,8 @@ describe('Board card', () => {
it('resets detail issue to empty if already set', () => { it('resets detail issue to empty if already set', () => {
jest.spyOn(eventHub, '$emit').mockImplementation(() => {}); jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
[boardsStore.detail.issue] = list.issues; const [issue] = list.issues;
boardsStore.detail.issue = issue;
mountComponent(); mountComponent();
wrapper.trigger('mousedown'); wrapper.trigger('mousedown');
...@@ -210,4 +212,27 @@ describe('Board card', () => { ...@@ -210,4 +212,27 @@ describe('Board card', () => {
expect(eventHub.$emit).toHaveBeenCalledWith('clearDetailIssue', undefined); expect(eventHub.$emit).toHaveBeenCalledWith('clearDetailIssue', undefined);
}); });
}); });
describe('sidebarHub events', () => {
it('closes all sidebars before showing an issue if no issues are opened', () => {
jest.spyOn(sidebarEventHub, '$emit').mockImplementation(() => {});
boardsStore.detail.issue = {};
mountComponent();
wrapper.trigger('mouseup');
expect(sidebarEventHub.$emit).toHaveBeenCalledWith('sidebar.closeAll');
});
it('it does not closes all sidebars before showing an issue if an issue is opened', () => {
jest.spyOn(sidebarEventHub, '$emit').mockImplementation(() => {});
const [issue] = list.issues;
boardsStore.detail.issue = issue;
mountComponent();
wrapper.trigger('mousedown');
expect(sidebarEventHub.$emit).not.toHaveBeenCalledWith('sidebar.closeAll');
});
});
}); });
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