Commit 85ae815c authored by Natalia Tepluhina's avatar Natalia Tepluhina

Merge branch '9838-hide-labels-from-issue-board-cards' into 'master'

Hide labels from issue board cards

See merge request gitlab-org/gitlab!18533
parents 558b7dd2 cec262fc
<script> <script>
import _ from 'underscore'; import _ from 'underscore';
import { mapState } from 'vuex';
import { GlTooltipDirective } from '@gitlab/ui'; import { GlTooltipDirective } from '@gitlab/ui';
import { sprintf, __ } from '~/locale'; import { sprintf, __ } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
...@@ -63,6 +64,7 @@ export default { ...@@ -63,6 +64,7 @@ export default {
}; };
}, },
computed: { computed: {
...mapState(['isShowingLabels']),
numberOverLimit() { numberOverLimit() {
return this.issue.assignees.length - this.limitBeforeCounter; return this.issue.assignees.length - this.limitBeforeCounter;
}, },
...@@ -92,7 +94,7 @@ export default { ...@@ -92,7 +94,7 @@ export default {
return false; return false;
}, },
showLabelFooter() { showLabelFooter() {
return this.issue.labels.find(l => this.showLabel(l)) !== undefined; return this.isShowingLabels && this.issue.labels.find(this.showLabel);
}, },
issueReferencePath() { issueReferencePath() {
const { referencePath, groupId } = this.issue; const { referencePath, groupId } = this.issue;
......
...@@ -13,6 +13,7 @@ import 'ee_else_ce/boards/models/issue'; ...@@ -13,6 +13,7 @@ import 'ee_else_ce/boards/models/issue';
import 'ee_else_ce/boards/models/list'; import 'ee_else_ce/boards/models/list';
import '~/boards/models/milestone'; import '~/boards/models/milestone';
import '~/boards/models/project'; import '~/boards/models/project';
import store from '~/boards/stores';
import boardsStore from '~/boards/stores/boards_store'; import boardsStore from '~/boards/stores/boards_store';
import ModalStore from '~/boards/stores/modal_store'; import ModalStore from '~/boards/stores/modal_store';
import BoardService from 'ee_else_ce/boards/services/board_service'; import BoardService from 'ee_else_ce/boards/services/board_service';
...@@ -29,6 +30,7 @@ import { ...@@ -29,6 +30,7 @@ import {
} from '~/lib/utils/common_utils'; } from '~/lib/utils/common_utils';
import boardConfigToggle from 'ee_else_ce/boards/config_toggle'; import boardConfigToggle from 'ee_else_ce/boards/config_toggle';
import toggleFocusMode from 'ee_else_ce/boards/toggle_focus'; import toggleFocusMode from 'ee_else_ce/boards/toggle_focus';
import toggleLabels from 'ee_else_ce/boards/toggle_labels';
import { import {
setPromotionState, setPromotionState,
setWeigthFetchingState, setWeigthFetchingState,
...@@ -67,6 +69,7 @@ export default () => { ...@@ -67,6 +69,7 @@ export default () => {
BoardSidebar, BoardSidebar,
BoardAddIssuesModal, BoardAddIssuesModal,
}, },
store,
data: { data: {
state: boardsStore.state, state: boardsStore.state,
loading: true, loading: true,
...@@ -314,5 +317,6 @@ export default () => { ...@@ -314,5 +317,6 @@ export default () => {
} }
toggleFocusMode(ModalStore, boardsStore, $boardApp); toggleFocusMode(ModalStore, boardsStore, $boardApp);
toggleLabels();
mountMultipleBoardsSwitcher(); mountMultipleBoardsSwitcher();
}; };
export default {
getLabelToggleState: state => (state.isShowingLabels ? 'on' : 'off'),
};
import Vue from 'vue'; import Vue from 'vue';
import Vuex from 'vuex'; import Vuex from 'vuex';
import state from 'ee_else_ce/boards/stores/state'; import state from 'ee_else_ce/boards/stores/state';
import getters from 'ee_else_ce/boards/stores/getters';
import actions from 'ee_else_ce/boards/stores/actions'; import actions from 'ee_else_ce/boards/stores/actions';
import mutations from 'ee_else_ce/boards/stores/mutations'; import mutations from 'ee_else_ce/boards/stores/mutations';
Vue.use(Vuex); Vue.use(Vuex);
export default () => export const createStore = () =>
new Vuex.Store({ new Vuex.Store({
state, state,
getters,
actions, actions,
mutations, mutations,
}); });
export default createStore();
export default () => ({ export default () => ({
// ... isShowingLabels: true,
}); });
...@@ -545,3 +545,15 @@ ...@@ -545,3 +545,15 @@
.board-issue-path.js-show-tooltip { .board-issue-path.js-show-tooltip {
cursor: help; cursor: help;
} }
.board-labels-toggle-wrapper {
/**
* Make the wrapper the same height as a button so it aligns properly when the
* filtered-search-box input element increases in size on Linux smaller breakpoints
*/
height: 34px;
@include media-breakpoint-down(sm) {
margin-bottom: 10px;
}
}
...@@ -147,6 +147,7 @@ ...@@ -147,6 +147,7 @@
%button.clear-search.hidden{ type: 'button' } %button.clear-search.hidden{ type: 'button' }
= icon('times') = icon('times')
#js-board-labels-toggle
.filter-dropdown-container.d-flex.flex-column.flex-md-row .filter-dropdown-container.d-flex.flex-column.flex-md-row
- if type == :boards - if type == :boards
.js-board-config{ data: { can_admin_list: user_can_admin_list, has_scope: board.scoped? } } .js-board-config{ data: { can_admin_list: user_can_admin_list, has_scope: board.scoped? } }
......
import actionsCE from '~/boards/stores/actions'; import actionsCE from '~/boards/stores/actions';
import * as types from './mutation_types';
const notImplemented = () => { const notImplemented = () => {
/* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */ /* eslint-disable-next-line @gitlab/i18n/no-non-i18n-strings */
...@@ -8,6 +9,10 @@ const notImplemented = () => { ...@@ -8,6 +9,10 @@ const notImplemented = () => {
export default { export default {
...actionsCE, ...actionsCE,
toggleShowLabels({ commit }) {
commit(types.TOGGLE_LABELS);
},
fetchAllBoards: () => { fetchAllBoards: () => {
notImplemented(); notImplemented();
}, },
......
import gettersCE from '~/boards/stores/getters';
export default {
...gettersCE,
};
...@@ -11,3 +11,4 @@ export const REQUEST_REMOVE_BOARD = 'REQUEST_REMOVE_BOARD'; ...@@ -11,3 +11,4 @@ export const REQUEST_REMOVE_BOARD = 'REQUEST_REMOVE_BOARD';
export const RECEIVE_REMOVE_BOARD_SUCCESS = 'RECEIVE_REMOVE_BOARD_SUCCESS'; export const RECEIVE_REMOVE_BOARD_SUCCESS = 'RECEIVE_REMOVE_BOARD_SUCCESS';
export const RECEIVE_REMOVE_BOARD_ERROR = 'RECEIVE_REMOVE_BOARD_ERROR'; export const RECEIVE_REMOVE_BOARD_ERROR = 'RECEIVE_REMOVE_BOARD_ERROR';
export const TOGGLE_PROMOTION_STATE = 'TOGGLE_PROMOTION_STATE'; export const TOGGLE_PROMOTION_STATE = 'TOGGLE_PROMOTION_STATE';
export const TOGGLE_LABELS = 'TOGGLE_LABELS';
...@@ -6,6 +6,10 @@ const notImplemented = () => { ...@@ -6,6 +6,10 @@ const notImplemented = () => {
}; };
export default { export default {
[mutationTypes.TOGGLE_LABELS]: state => {
state.isShowingLabels = !state.isShowingLabels;
},
[mutationTypes.REQUEST_AVAILABLE_BOARDS]: () => { [mutationTypes.REQUEST_AVAILABLE_BOARDS]: () => {
notImplemented(); notImplemented();
}, },
......
import Vue from 'vue';
import { mapState, mapGetters, mapActions } from 'vuex';
import { GlToggle } from '@gitlab/ui';
import { __ } from '~/locale';
import Tracking from '~/tracking';
import store from '~/boards/stores';
export default () =>
new Vue({
el: document.getElementById('js-board-labels-toggle'),
components: {
GlToggle,
},
store,
computed: {
...mapState(['isShowingLabels']),
...mapGetters(['getLabelToggleState']),
toggleOnLabel() {
return __('Showing all labels');
},
toggleOffLabel() {
return __('Hiding all labels');
},
},
methods: {
...mapActions(['toggleShowLabels']),
onToggle() {
this.toggleShowLabels();
Tracking.event(document.body.dataset.page, 'toggle', {
label: 'show_labels',
property: this.getLabelToggleState,
});
},
},
template: `
<div class="board-labels-toggle-wrapper d-flex align-items-center prepend-left-10">
<span id="board-labels-toggle-text">
{{ __('Show labels') }}
</span>
<gl-toggle
:value="isShowingLabels"
class="prepend-left-10 mb-0"
:label-on="toggleOnLabel"
:label-off="toggleOffLabel"
aria-describedby="board-labels-toggle-text"
data-qa-selector="show_labels_toggle"
@change="onToggle"
/>
</div>
`,
});
---
title: Hide labels from issue board cards
merge_request: 18533
author:
type: added
...@@ -3,14 +3,16 @@ import ListLabel from '~/boards/models/label'; ...@@ -3,14 +3,16 @@ import ListLabel from '~/boards/models/label';
import IssueCardInner from '~/boards/components/issue_card_inner.vue'; import IssueCardInner from '~/boards/components/issue_card_inner.vue';
import IssueCardWeight from 'ee/boards/components/issue_card_weight.vue'; import IssueCardWeight from 'ee/boards/components/issue_card_weight.vue';
import ListIssueEE from 'ee/boards/models/issue'; import ListIssueEE from 'ee/boards/models/issue';
import defaultStore from '~/boards/stores';
describe('Issue card component', () => { describe('Issue card component', () => {
let wrapper; let wrapper;
let issue; let issue;
let list; let list;
const createComponent = (props = {}) => { const createComponent = (props = {}, store = defaultStore) => {
wrapper = mount(IssueCardInner, { wrapper = mount(IssueCardInner, {
store,
propsData: { propsData: {
list, list,
issue, issue,
...@@ -87,6 +89,19 @@ describe('Issue card component', () => { ...@@ -87,6 +89,19 @@ describe('Issue card component', () => {
expect(wrapper.findAll('.badge').length).toBe(3); expect(wrapper.findAll('.badge').length).toBe(3);
expect(wrapper.text()).toContain(title); expect(wrapper.text()).toContain(title);
}); });
it('shows no labels when the isShowingLabels state is false', () => {
const store = {
...defaultStore,
state: {
...defaultStore.state,
isShowingLabels: false,
},
};
createComponent({}, store);
expect(wrapper.findAll('.board-card-labels').length).toBe(0);
});
}); });
describe('weight', () => { describe('weight', () => {
......
import actions from 'ee/boards/stores/actions'; import actions from 'ee/boards/stores/actions';
import * as types from 'ee/boards/stores/mutation_types';
import testAction from 'helpers/vuex_action_helper';
const expectNotImplemented = action => { const expectNotImplemented = action => {
it('is not implemented', () => { it('is not implemented', () => {
...@@ -6,6 +8,16 @@ const expectNotImplemented = action => { ...@@ -6,6 +8,16 @@ const expectNotImplemented = action => {
}); });
}; };
describe('toggleShowLabels', () => {
it('should commit mutation TOGGLE_LABELS', done => {
const state = {
isShowingLabels: true,
};
testAction(actions.toggleShowLabels, null, state, [{ type: types.TOGGLE_LABELS }], [], done);
});
});
describe('fetchAllBoards', () => { describe('fetchAllBoards', () => {
expectNotImplemented(actions.fetchAllBoards); expectNotImplemented(actions.fetchAllBoards);
}); });
......
...@@ -6,6 +6,28 @@ const expectNotImplemented = action => { ...@@ -6,6 +6,28 @@ const expectNotImplemented = action => {
}); });
}; };
describe('TOGGLE_LABELS', () => {
it('toggles isShowingLabels from true to false', () => {
const state = {
isShowingLabels: true,
};
mutations.TOGGLE_LABELS(state);
expect(state.isShowingLabels).toBe(false);
});
it('toggles isShowingLabels from false to true', () => {
const state = {
isShowingLabels: false,
};
mutations.TOGGLE_LABELS(state);
expect(state.isShowingLabels).toBe(true);
});
});
describe('REQUEST_AVAILABLE_BOARDS', () => { describe('REQUEST_AVAILABLE_BOARDS', () => {
expectNotImplemented(mutations.REQUEST_AVAILABLE_BOARDS); expectNotImplemented(mutations.REQUEST_AVAILABLE_BOARDS);
}); });
......
...@@ -8656,6 +8656,9 @@ msgstr[1] "" ...@@ -8656,6 +8656,9 @@ msgstr[1] ""
msgid "Hide values" msgid "Hide values"
msgstr "" msgstr ""
msgid "Hiding all labels"
msgstr ""
msgid "Highest number of requests per minute for each raw path, default to 300. To disable throttling set to 0." msgid "Highest number of requests per minute for each raw path, default to 300. To disable throttling set to 0."
msgstr "" msgstr ""
...@@ -15181,6 +15184,9 @@ msgstr "" ...@@ -15181,6 +15184,9 @@ msgstr ""
msgid "Showing all issues" msgid "Showing all issues"
msgstr "" msgstr ""
msgid "Showing all labels"
msgstr ""
msgid "Showing last %{size} of log -" msgid "Showing last %{size} of log -"
msgstr "" msgstr ""
......
import getters from '~/boards/stores/getters';
describe('Boards - Getters', () => {
describe('getLabelToggleState', () => {
it('should return "on" when isShowingLabels is true', () => {
const state = {
isShowingLabels: true,
};
expect(getters.getLabelToggleState(state)).toBe('on');
});
it('should return "off" when isShowingLabels is false', () => {
const state = {
isShowingLabels: false,
};
expect(getters.getLabelToggleState(state)).toBe('off');
});
});
});
...@@ -10,6 +10,7 @@ import eventHub from '~/boards/eventhub'; ...@@ -10,6 +10,7 @@ import eventHub from '~/boards/eventhub';
import '~/boards/models/label'; import '~/boards/models/label';
import '~/boards/models/assignee'; import '~/boards/models/assignee';
import '~/boards/models/list'; import '~/boards/models/list';
import store from '~/boards/stores';
import boardsStore from '~/boards/stores/boards_store'; import boardsStore from '~/boards/stores/boards_store';
import boardCard from '~/boards/components/board_card.vue'; import boardCard from '~/boards/components/board_card.vue';
import { listObj, boardsMockInterceptor, mockBoardService } from './mock_data'; import { listObj, boardsMockInterceptor, mockBoardService } from './mock_data';
...@@ -40,6 +41,7 @@ describe('Board card', () => { ...@@ -40,6 +41,7 @@ describe('Board card', () => {
list.issues[0].labels.push(label1); list.issues[0].labels.push(label1);
vm = new BoardCardComp({ vm = new BoardCardComp({
store,
propsData: { propsData: {
list, list,
issue: list.issues[0], issue: list.issues[0],
......
...@@ -10,6 +10,7 @@ import BoardList from '~/boards/components/board_list.vue'; ...@@ -10,6 +10,7 @@ import BoardList from '~/boards/components/board_list.vue';
import '~/boards/models/issue'; import '~/boards/models/issue';
import '~/boards/models/list'; import '~/boards/models/list';
import { listObj, boardsMockInterceptor, mockBoardService } from './mock_data'; import { listObj, boardsMockInterceptor, mockBoardService } from './mock_data';
import store from '~/boards/stores';
import boardsStore from '~/boards/stores/boards_store'; import boardsStore from '~/boards/stores/boards_store';
window.Sortable = Sortable; window.Sortable = Sortable;
...@@ -39,6 +40,7 @@ export default function createComponent({ done, listIssueProps = {}, componentPr ...@@ -39,6 +40,7 @@ export default function createComponent({ done, listIssueProps = {}, componentPr
const component = new BoardListComp({ const component = new BoardListComp({
el, el,
store,
propsData: { propsData: {
disabled: false, disabled: false,
list, list,
......
...@@ -10,6 +10,7 @@ import '~/boards/models/issue'; ...@@ -10,6 +10,7 @@ import '~/boards/models/issue';
import '~/boards/models/list'; import '~/boards/models/list';
import IssueCardInner from '~/boards/components/issue_card_inner.vue'; import IssueCardInner from '~/boards/components/issue_card_inner.vue';
import { listObj } from './mock_data'; import { listObj } from './mock_data';
import store from '~/boards/stores';
describe('Issue card component', () => { describe('Issue card component', () => {
const user = new ListAssignee({ const user = new ListAssignee({
...@@ -50,6 +51,7 @@ describe('Issue card component', () => { ...@@ -50,6 +51,7 @@ describe('Issue card component', () => {
component = new Vue({ component = new Vue({
el: document.querySelector('.test-container'), el: document.querySelector('.test-container'),
store,
components: { components: {
'issue-card': IssueCardInner, 'issue-card': IssueCardInner,
}, },
......
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