Commit ff32b924 authored by Paul Slaughter's avatar Paul Slaughter

Merge branch 'ss/add-milestone-and-assignee-to-wiplimits' into 'master'

Add support for milestone and assignee

See merge request gitlab-org/gitlab!23016
parents a1b4efcc f11779b1
<script> <script>
import { GlDrawer, GlLabel, GlButton, GlFormInput } from '@gitlab/ui'; import {
GlDrawer,
GlLabel,
GlButton,
GlFormInput,
GlAvatarLink,
GlAvatarLabeled,
GlLink,
} from '@gitlab/ui';
import { mapActions, mapState } from 'vuex'; import { mapActions, mapState } from 'vuex';
import { __ } from '~/locale'; import { __ } from '~/locale';
import autofocusonshow from '~/vue_shared/directives/autofocusonshow'; import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
...@@ -10,7 +18,12 @@ import flash from '~/flash'; ...@@ -10,7 +18,12 @@ import flash from '~/flash';
export default { export default {
headerHeight: process.env.NODE_ENV === 'development' ? '75px' : '40px', headerHeight: process.env.NODE_ENV === 'development' ? '75px' : '40px',
listSettingsText: __('List Settings'), listSettingsText: __('List Settings'),
labelListText: __('List Label'), assignee: 'assignee',
milestone: 'milestone',
label: 'label',
labelListText: __('Label'),
labelMilestoneText: __('Milestone'),
labelAssigneeText: __('Assignee'),
editLinkText: __('Edit'), editLinkText: __('Edit'),
noneText: __('None'), noneText: __('None'),
wipLimitText: __('Work in Progress Limit'), wipLimitText: __('Work in Progress Limit'),
...@@ -19,6 +32,9 @@ export default { ...@@ -19,6 +32,9 @@ export default {
GlLabel, GlLabel,
GlButton, GlButton,
GlFormInput, GlFormInput,
GlAvatarLink,
GlAvatarLabeled,
GlLink,
}, },
directives: { directives: {
autofocusonshow, autofocusonshow,
...@@ -46,11 +62,36 @@ export default { ...@@ -46,11 +62,36 @@ export default {
activeListLabel() { activeListLabel() {
return this.activeList.label; return this.activeList.label;
}, },
activeListMilestone() {
return this.activeList.milestone;
},
activeListAssignee() {
return this.activeList.assignee;
},
activeListWipLimit() { activeListWipLimit() {
return this.activeList.maxIssueCount === 0 return this.activeList.maxIssueCount === 0
? this.$options.noneText ? this.$options.noneText
: this.activeList.maxIssueCount; : this.activeList.maxIssueCount;
}, },
boardListType() {
return this.activeList.type || null;
},
listTypeTitle() {
switch (this.boardListType) {
case this.$options.milestone: {
return this.$options.labelMilestoneText;
}
case this.$options.label: {
return this.$options.labelListText;
}
case this.$options.assignee: {
return this.$options.labelAssigneeText;
}
default: {
return '';
}
}
},
}, },
methods: { methods: {
...mapActions(['setActiveListId', 'updateListWipLimit']), ...mapActions(['setActiveListId', 'updateListWipLimit']),
...@@ -105,12 +146,29 @@ export default { ...@@ -105,12 +146,29 @@ export default {
<template #header>{{ $options.listSettingsText }}</template> <template #header>{{ $options.listSettingsText }}</template>
<template v-if="isSidebarOpen"> <template v-if="isSidebarOpen">
<div class="d-flex flex-column align-items-start"> <div class="d-flex flex-column align-items-start">
<label>{{ $options.labelListText }}</label> <label class="js-list-label">{{ listTypeTitle }}</label>
<gl-label <template v-if="boardListType === $options.label">
:title="activeListLabel.title" <gl-label
:background-color="activeListLabel.color" :title="activeListLabel.title"
color="light" :background-color="activeListLabel.color"
/> color="light"
/>
</template>
<template v-else-if="boardListType === $options.assignee">
<gl-avatar-link class="js-assignee" :href="activeListAssignee.webUrl">
<gl-avatar-labeled
:size="32"
:label="activeListAssignee.name"
:sub-label="`@${activeListAssignee.username}`"
:src="activeListAssignee.avatar"
/>
</gl-avatar-link>
</template>
<template v-else-if="boardListType === $options.milestone">
<gl-link class="js-milestone" :href="activeListMilestone.webUrl">{{
activeListMilestone.title
}}</gl-link>
</template>
</div> </div>
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">
<div> <div>
...@@ -128,9 +186,9 @@ export default { ...@@ -128,9 +186,9 @@ export default {
/> />
<p v-else class="js-wip-limit bold">{{ activeListWipLimit }}</p> <p v-else class="js-wip-limit bold">{{ activeListWipLimit }}</p>
</div> </div>
<gl-button class="h-100 border-0 gl-line-height-14" variant="link" @click="showInput">{{ <gl-button class="h-100 border-0 gl-line-height-14" variant="link" @click="showInput">
$options.editLinkText {{ $options.editLinkText }}
}}</gl-button> </gl-button>
</div> </div>
</template> </template>
</gl-drawer> </gl-drawer>
......
...@@ -5,3 +5,9 @@ exports[`BoardSettingsSideBar when activeList is present when activeListWipLimit ...@@ -5,3 +5,9 @@ exports[`BoardSettingsSideBar when activeList is present when activeListWipLimit
exports[`BoardSettingsSideBar when activeList is present when activeListWipLimit is greater than 0 it renders 1 1`] = `"1"`; exports[`BoardSettingsSideBar when activeList is present when activeListWipLimit is greater than 0 it renders 1 1`] = `"1"`;
exports[`BoardSettingsSideBar when activeList is present when activeListWipLimit is greater than 0 it renders 11 1`] = `"11"`; exports[`BoardSettingsSideBar when activeList is present when activeListWipLimit is greater than 0 it renders 11 1`] = `"11"`;
exports[`BoardSettingsSideBar when activeList is present when activeListWipLimit is greater than 0 when list type is "assignee" renders the correct list type text 1`] = `"Assignee"`;
exports[`BoardSettingsSideBar when activeList is present when activeListWipLimit is greater than 0 when list type is "milestone" renders the correct list type text 1`] = `"Milestone"`;
exports[`BoardSettingsSideBar when activeList is present when activeListWipLimit is greater than 0 when list type is "milestone" renders the correct milestone text 1`] = `"Backlog"`;
...@@ -3,7 +3,14 @@ import MockAdapter from 'axios-mock-adapter'; ...@@ -3,7 +3,14 @@ import MockAdapter from 'axios-mock-adapter';
import axios from 'axios'; import axios from 'axios';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { shallowMount, createLocalVue } from '@vue/test-utils'; import { shallowMount, createLocalVue } from '@vue/test-utils';
import { GlDrawer, GlLabel, GlButton, GlFormInput } from '@gitlab/ui'; import {
GlDrawer,
GlLabel,
GlButton,
GlFormInput,
GlAvatarLink,
GlAvatarLabeled,
} from '@gitlab/ui';
import BoardSettingsSidebar from 'ee/boards/components/board_settings_sidebar.vue'; import BoardSettingsSidebar from 'ee/boards/components/board_settings_sidebar.vue';
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';
...@@ -203,6 +210,74 @@ describe('BoardSettingsSideBar', () => { ...@@ -203,6 +210,74 @@ describe('BoardSettingsSideBar', () => {
}); });
describe('when activeListWipLimit is greater than 0', () => { describe('when activeListWipLimit is greater than 0', () => {
describe('when list type is "milestone"', () => {
beforeEach(() => {
boardsStore.store.addList({
id: 1,
milestone: {
webUrl: 'https://gitlab.com/h5bp/html5-boilerplate/-/milestones/1',
title: 'Backlog',
},
max_issue_count: 1,
list_type: 'milestone',
});
});
afterEach(() => {
boardsStore.store.removeList(1, 'milestone');
wrapper.destroy();
});
it('renders the correct milestone text', () => {
createComponent({ activeListId: 1 });
expect(wrapper.find('.js-milestone').text()).toMatchSnapshot();
});
it('renders the correct list type text', () => {
createComponent({ activeListId: 1 });
expect(wrapper.find('.js-list-label').text()).toMatchSnapshot();
});
});
describe('when list type is "assignee"', () => {
beforeEach(() => {
boardsStore.store.addList({
id: 1,
user: { username: 'root', avatar: '', name: 'Test', webUrl: 'https://gitlab.com/root' },
max_issue_count: 1,
list_type: 'assignee',
});
});
afterEach(() => {
boardsStore.store.removeList(1, 'assignee');
wrapper.destroy();
});
it('renders gl-avatar-link with correct href', () => {
createComponent({ activeListId: 1 });
expect(wrapper.find(GlAvatarLink).exists()).toBe(true);
expect(wrapper.find(GlAvatarLink).attributes('href')).toEqual('https://gitlab.com/root');
});
it('renders gl-avatar-labeled with "root" as username and name as "Test"', () => {
createComponent({ activeListId: 1 });
expect(wrapper.find(GlAvatarLabeled).exists()).toBe(true);
expect(wrapper.find(GlAvatarLabeled).attributes('label')).toEqual('Test');
expect(wrapper.find(GlAvatarLabeled).attributes('sublabel')).toEqual('@root');
});
it('renders the correct list type text', () => {
createComponent({ activeListId: 1 });
expect(wrapper.find('.js-list-label').text()).toMatchSnapshot();
});
});
it.each` it.each`
num num
${1} ${1}
......
...@@ -10959,9 +10959,6 @@ msgstr "" ...@@ -10959,9 +10959,6 @@ msgstr ""
msgid "List" msgid "List"
msgstr "" msgstr ""
msgid "List Label"
msgstr ""
msgid "List Settings" msgid "List Settings"
msgstr "" msgstr ""
......
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