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>
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 { __ } from '~/locale';
import autofocusonshow from '~/vue_shared/directives/autofocusonshow';
......@@ -10,7 +18,12 @@ import flash from '~/flash';
export default {
headerHeight: process.env.NODE_ENV === 'development' ? '75px' : '40px',
listSettingsText: __('List Settings'),
labelListText: __('List Label'),
assignee: 'assignee',
milestone: 'milestone',
label: 'label',
labelListText: __('Label'),
labelMilestoneText: __('Milestone'),
labelAssigneeText: __('Assignee'),
editLinkText: __('Edit'),
noneText: __('None'),
wipLimitText: __('Work in Progress Limit'),
......@@ -19,6 +32,9 @@ export default {
GlLabel,
GlButton,
GlFormInput,
GlAvatarLink,
GlAvatarLabeled,
GlLink,
},
directives: {
autofocusonshow,
......@@ -46,11 +62,36 @@ export default {
activeListLabel() {
return this.activeList.label;
},
activeListMilestone() {
return this.activeList.milestone;
},
activeListAssignee() {
return this.activeList.assignee;
},
activeListWipLimit() {
return this.activeList.maxIssueCount === 0
? this.$options.noneText
: 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: {
...mapActions(['setActiveListId', 'updateListWipLimit']),
......@@ -105,12 +146,29 @@ export default {
<template #header>{{ $options.listSettingsText }}</template>
<template v-if="isSidebarOpen">
<div class="d-flex flex-column align-items-start">
<label>{{ $options.labelListText }}</label>
<label class="js-list-label">{{ listTypeTitle }}</label>
<template v-if="boardListType === $options.label">
<gl-label
:title="activeListLabel.title"
: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 class="d-flex justify-content-between">
<div>
......@@ -128,9 +186,9 @@ export default {
/>
<p v-else class="js-wip-limit bold">{{ activeListWipLimit }}</p>
</div>
<gl-button class="h-100 border-0 gl-line-height-14" variant="link" @click="showInput">{{
$options.editLinkText
}}</gl-button>
<gl-button class="h-100 border-0 gl-line-height-14" variant="link" @click="showInput">
{{ $options.editLinkText }}
</gl-button>
</div>
</template>
</gl-drawer>
......
......@@ -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 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';
import axios from 'axios';
import Vuex from 'vuex';
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 boardsStore from 'ee_else_ce/boards/stores/boards_store_ee';
import getters from 'ee_else_ce/boards/stores/getters';
......@@ -203,6 +210,74 @@ describe('BoardSettingsSideBar', () => {
});
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`
num
${1}
......
......@@ -10959,9 +10959,6 @@ msgstr ""
msgid "List"
msgstr ""
msgid "List Label"
msgstr ""
msgid "List Settings"
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