Commit d1d2eb67 authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Clean up components by using constants

This moves the board list type labels into the constants file
parent 95e6eead
...@@ -5,17 +5,13 @@ import { __ } from '~/locale'; ...@@ -5,17 +5,13 @@ import { __ } from '~/locale';
import boardsStore from '~/boards/stores/boards_store'; import boardsStore from '~/boards/stores/boards_store';
import eventHub from '~/sidebar/event_hub'; import eventHub from '~/sidebar/event_hub';
import { isScopedLabel } from '~/lib/utils/common_utils'; import { isScopedLabel } from '~/lib/utils/common_utils';
import { LIST } from '~/boards/constants'; import { LIST, ListType, ListTypeTitles } from '~/boards/constants';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
// NOTE: need to revisit how we handle headerHeight, because we have so many different header and footer options. // NOTE: need to revisit how we handle headerHeight, because we have so many different header and footer options.
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'),
assignee: 'assignee',
milestone: 'milestone',
label: 'label',
labelListText: __('Label'),
components: { components: {
GlButton, GlButton,
GlDrawer, GlDrawer,
...@@ -33,6 +29,11 @@ export default { ...@@ -33,6 +29,11 @@ export default {
default: false, default: false,
}, },
}, },
data() {
return {
ListType,
};
},
computed: { computed: {
...mapGetters(['isSidebarOpen', 'shouldUseGraphQL']), ...mapGetters(['isSidebarOpen', 'shouldUseGraphQL']),
...mapState(['activeId', 'sidebarType', 'boardLists']), ...mapState(['activeId', 'sidebarType', 'boardLists']),
...@@ -56,7 +57,7 @@ export default { ...@@ -56,7 +57,7 @@ export default {
return this.activeList.type || this.activeList.listType || null; return this.activeList.type || this.activeList.listType || null;
}, },
listTypeTitle() { listTypeTitle() {
return this.$options.labelListText; return ListTypeTitles[ListType.label];
}, },
showSidebar() { showSidebar() {
return this.sidebarType === LIST; return this.sidebarType === LIST;
...@@ -98,7 +99,7 @@ export default { ...@@ -98,7 +99,7 @@ export default {
> >
<template #header>{{ $options.listSettingsText }}</template> <template #header>{{ $options.listSettingsText }}</template>
<template v-if="isSidebarOpen"> <template v-if="isSidebarOpen">
<div v-if="boardListType === $options.label"> <div v-if="boardListType === ListType.label">
<label class="js-list-label gl-display-block">{{ listTypeTitle }}</label> <label class="js-list-label gl-display-block">{{ listTypeTitle }}</label>
<gl-label <gl-label
:title="activeListLabel.title" :title="activeListLabel.title"
......
import { __ } from '~/locale';
export const BoardType = { export const BoardType = {
project: 'project', project: 'project',
group: 'group', group: 'group',
...@@ -12,6 +14,13 @@ export const ListType = { ...@@ -12,6 +14,13 @@ export const ListType = {
label: 'label', label: 'label',
}; };
export const ListTypeTitles = {
assignee: __('Assignee'),
milestone: __('Milestone'),
iteration: __('Iteration'),
label: __('Label'),
};
export const inactiveId = 0; export const inactiveId = 0;
export const ISSUABLE = 'issuable'; export const ISSUABLE = 'issuable';
......
...@@ -2,13 +2,8 @@ export default class ListIteration { ...@@ -2,13 +2,8 @@ export default class ListIteration {
constructor(obj) { constructor(obj) {
this.id = obj.id; this.id = obj.id;
this.title = obj.title; this.title = obj.title;
this.state = obj.state;
if (IS_EE) { this.webUrl = obj.web_url || obj.webUrl;
this.state = obj.state; this.description = obj.description;
this.webUrl = obj.web_url || obj.webUrl;
this.description = obj.description;
}
} }
} }
window.ListIteration = ListIteration;
<script> <script>
import { GlAvatarLink, GlAvatarLabeled, GlLink } from '@gitlab/ui'; import { GlAvatarLink, GlAvatarLabeled, GlLink } from '@gitlab/ui';
import { __ } from '~/locale'; import { ListType, ListTypeTitles } from '~/boards/constants';
export default { export default {
milestone: 'milestone',
iteration: 'iteration',
assignee: 'assignee',
labelMilestoneText: __('Milestone'),
labelIterationText: __('Iteration'),
labelAssigneeText: __('Assignee'),
components: { components: {
GlLink, GlLink,
GlAvatarLink, GlAvatarLink,
...@@ -24,31 +18,17 @@ export default { ...@@ -24,31 +18,17 @@ export default {
required: true, required: true,
}, },
}, },
data() {
return {
ListType,
};
},
computed: { computed: {
activeListAssignee() { activeListObject() {
return this.activeList.assignee; return this.activeList[this.boardListType];
},
activeListMilestone() {
return this.activeList.milestone;
}, },
activeListIteration() { listTypeHeader() {
return this.activeList.iteration; return ListTypeTitles[this.boardListType] || '';
},
listTypeTitle() {
switch (this.boardListType) {
case this.$options.milestone: {
return this.$options.labelMilestoneText;
}
case this.$options.assignee: {
return this.$options.labelAssigneeText;
}
case this.$options.iteration: {
return this.$options.labelIterationText;
}
default: {
return '';
}
}
}, },
}, },
}; };
...@@ -56,27 +36,21 @@ export default { ...@@ -56,27 +36,21 @@ export default {
<template> <template>
<div> <div>
<label class="js-list-label gl-display-block">{{ listTypeTitle }}</label> <label class="js-list-label gl-display-block">{{ listTypeHeader }}</label>
<gl-link
v-if="boardListType === $options.milestone"
class="js-milestone"
:href="activeListMilestone.webUrl"
>{{ activeListMilestone.title }}</gl-link
>
<gl-link v-else-if="boardListType === $options.iteration" :href="activeListIteration.webUrl">{{
activeListIteration.title
}}</gl-link>
<gl-avatar-link <gl-avatar-link
v-else-if="boardListType === $options.assignee" v-if="boardListType === ListType.assignee"
class="js-assignee" class="js-assignee"
:href="activeListAssignee.webUrl" :href="activeListObject.webUrl"
> >
<gl-avatar-labeled <gl-avatar-labeled
:size="32" :size="32"
:label="activeListAssignee.name" :label="activeListObject.name"
:sub-label="`@${activeListAssignee.username}`" :sub-label="`@${activeListObject.username}`"
:src="activeListAssignee.avatar" :src="activeListObject.avatar"
/> />
</gl-avatar-link> </gl-avatar-link>
<gl-link v-else class="js-list-title" :href="activeListObject.webUrl">
{{ activeListObject.title }}
</gl-link>
</div> </div>
</template> </template>
...@@ -9,6 +9,10 @@ describe('BoardSettingsListType', () => { ...@@ -9,6 +9,10 @@ describe('BoardSettingsListType', () => {
webUrl: 'https://gitlab.com/h5bp/html5-boilerplate/-/milestones/1', webUrl: 'https://gitlab.com/h5bp/html5-boilerplate/-/milestones/1',
title: 'Backlog', title: 'Backlog',
}, },
iteration: {
webUrl: 'https://gitlab.com/h5bp/-/iterations/1',
title: 'Sprint 1',
},
assignee: { webUrl: 'https://gitlab.com/root', name: 'root', username: 'root' }, assignee: { webUrl: 'https://gitlab.com/root', name: 'root', username: 'root' },
}; };
const createComponent = (props) => { const createComponent = (props) => {
...@@ -25,7 +29,7 @@ describe('BoardSettingsListType', () => { ...@@ -25,7 +29,7 @@ describe('BoardSettingsListType', () => {
it('renders the correct milestone text', () => { it('renders the correct milestone text', () => {
createComponent({ activeId: 1, boardListType: 'milestone' }); createComponent({ activeId: 1, boardListType: 'milestone' });
expect(wrapper.find('.js-milestone').text()).toBe('Backlog'); expect(wrapper.find('.js-list-title').text()).toBe('Backlog');
}); });
it('renders the correct list type text', () => { it('renders the correct list type text', () => {
...@@ -35,6 +39,20 @@ describe('BoardSettingsListType', () => { ...@@ -35,6 +39,20 @@ describe('BoardSettingsListType', () => {
}); });
}); });
describe('when list type is "iteration"', () => {
it('renders the correct milestone text', () => {
createComponent({ activeId: 1, boardListType: 'iteration' });
expect(wrapper.find('.js-list-title').text()).toBe('Sprint 1');
});
it('renders the correct list type text', () => {
createComponent({ activeId: 1, boardListType: 'iteration' });
expect(wrapper.find('.js-list-label').text()).toBe('Iteration');
});
});
describe('when list type is "assignee"', () => { describe('when list type is "assignee"', () => {
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
......
...@@ -4,6 +4,7 @@ import Issue from 'ee/boards/models/issue'; ...@@ -4,6 +4,7 @@ import Issue from 'ee/boards/models/issue';
import List from 'ee/boards/models/list'; import List from 'ee/boards/models/list';
import { listObj } from 'jest/boards/mock_data'; import { listObj } from 'jest/boards/mock_data';
import CeList from '~/boards/models/list'; import CeList from '~/boards/models/list';
import { ListType } from '~/boards/constants';
describe('List model', () => { describe('List model', () => {
let list; let list;
...@@ -15,16 +16,6 @@ describe('List model', () => { ...@@ -15,16 +16,6 @@ describe('List model', () => {
// We need to mock axios since `new List` below makes a network request // We need to mock axios since `new List` below makes a network request
axiosMock.onGet().replyOnce(200); axiosMock.onGet().replyOnce(200);
list = new List(listObj);
issue = new Issue({
title: 'Testing',
id: 2,
iid: 2,
labels: [],
assignees: [],
weight: 5,
});
}); });
afterEach(() => { afterEach(() => {
...@@ -33,67 +24,98 @@ describe('List model', () => { ...@@ -33,67 +24,98 @@ describe('List model', () => {
axiosMock.restore(); axiosMock.restore();
}); });
it('inits totalWeight', () => { describe('label lists', () => {
expect(list.totalWeight).toBe(0); beforeEach(() => {
}); list = new List(listObj);
issue = new Issue({
title: 'Testing',
id: 2,
iid: 2,
labels: [],
assignees: [],
weight: 5,
});
});
it('inits totalWeight', () => {
expect(list.totalWeight).toBe(0);
});
describe('getIssues', () => { describe('getIssues', () => {
it('calls CE getIssues', () => { it('calls CE getIssues', () => {
const ceGetIssues = jest const ceGetIssues = jest
.spyOn(CeList.prototype, 'getIssues') .spyOn(CeList.prototype, 'getIssues')
.mockReturnValue(Promise.resolve({})); .mockReturnValue(Promise.resolve({}));
return list.getIssues().then(() => { return list.getIssues().then(() => {
expect(ceGetIssues).toHaveBeenCalled(); expect(ceGetIssues).toHaveBeenCalled();
});
}); });
});
it('sets total weight', () => { it('sets total weight', () => {
jest.spyOn(CeList.prototype, 'getIssues').mockReturnValue( jest.spyOn(CeList.prototype, 'getIssues').mockReturnValue(
Promise.resolve({ Promise.resolve({
total_weight: 11, total_weight: 11,
}), }),
); );
return list.getIssues().then(() => { return list.getIssues().then(() => {
expect(list.totalWeight).toBe(11); expect(list.totalWeight).toBe(11);
});
}); });
}); });
});
describe('addIssue', () => { describe('addIssue', () => {
it('updates totalWeight', () => { it('updates totalWeight', () => {
list.addIssue(issue); list.addIssue(issue);
expect(list.totalWeight).toBe(5); expect(list.totalWeight).toBe(5);
}); });
it('calls CE addIssue with all args', () => { it('calls CE addIssue with all args', () => {
const ceAddIssue = jest.spyOn(CeList.prototype, 'addIssue'); const ceAddIssue = jest.spyOn(CeList.prototype, 'addIssue');
list.addIssue(issue, list, 2); list.addIssue(issue, list, 2);
expect(ceAddIssue).toHaveBeenCalledWith(issue, list, 2); expect(ceAddIssue).toHaveBeenCalledWith(issue, list, 2);
});
}); });
});
describe('removeIssue', () => { describe('removeIssue', () => {
beforeEach(() => { beforeEach(() => {
list.addIssue(issue); list.addIssue(issue);
}); });
it('updates totalWeight', () => { it('updates totalWeight', () => {
list.removeIssue(issue); list.removeIssue(issue);
expect(list.totalWeight).toBe(0); expect(list.totalWeight).toBe(0);
});
it('calls CE removeIssue', () => {
const ceRemoveIssue = jest.spyOn(CeList.prototype, 'removeIssue');
list.removeIssue(issue);
expect(ceRemoveIssue).toHaveBeenCalledWith(issue);
});
}); });
});
it('calls CE removeIssue', () => { describe('iteration lists', () => {
const ceRemoveIssue = jest.spyOn(CeList.prototype, 'removeIssue'); const iteration = {
id: 1000,
title: 'Sprint 1',
webUrl: 'https://gitlab.com/h5bp/-/iterations/1',
};
list.removeIssue(issue); beforeEach(() => {
list = new List({ list_type: ListType.iteration, iteration });
});
expect(ceRemoveIssue).toHaveBeenCalledWith(issue); it('sets the iteration and title', () => {
expect(list.iteration.id).toBe(iteration.id);
expect(list.title).toBe(iteration.title);
}); });
}); });
}); });
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