Commit c74f114e authored by Florie Guibert's avatar Florie Guibert Committed by Kushal Pandya

Display Swimlanes Epic Title

- Fetch epics on board swimlanes
- Display epic information
parent 7b4340f1
...@@ -75,10 +75,7 @@ export default { ...@@ -75,10 +75,7 @@ export default {
ref="swimlanes" ref="swimlanes"
:lists="lists" :lists="lists"
:can-admin-list="canAdminList" :can-admin-list="canAdminList"
:group-id="groupId"
:disabled="disabled" :disabled="disabled"
:issue-link-base="issueLinkBase"
:root-path="rootPath"
:board-id="boardId" :board-id="boardId"
/> />
</div> </div>
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
import { import {
GlButton, GlButton,
GlButtonGroup, GlButtonGroup,
GlDeprecatedButton,
GlLabel, GlLabel,
GlTooltip, GlTooltip,
GlIcon, GlIcon,
...@@ -23,7 +22,6 @@ export default { ...@@ -23,7 +22,6 @@ export default {
BoardDelete, BoardDelete,
GlButtonGroup, GlButtonGroup,
GlButton, GlButton,
GlDeprecatedButton,
GlLabel, GlLabel,
GlTooltip, GlTooltip,
GlIcon, GlIcon,
...@@ -89,9 +87,12 @@ export default { ...@@ -89,9 +87,12 @@ export default {
return sprintf(__('%{issuesSize} issues'), { issuesSize }); return sprintf(__('%{issuesSize} issues'), { issuesSize });
}, },
caretTooltip() { chevronTooltip() {
return this.list.isExpanded ? s__('Boards|Collapse') : s__('Boards|Expand'); return this.list.isExpanded ? s__('Boards|Collapse') : s__('Boards|Expand');
}, },
chevronIcon() {
return this.list.isExpanded ? 'chevron-right' : 'chevron-down';
},
isNewIssueShown() { isNewIssueShown() {
return this.listType === ListType.backlog || this.showListHeaderButton; return this.listType === ListType.backlog || this.showListHeaderButton;
}, },
...@@ -160,20 +161,16 @@ export default { ...@@ -160,20 +161,16 @@ export default {
}" }"
class="board-title gl-m-0 gl-display-flex js-board-handle" class="board-title gl-m-0 gl-display-flex js-board-handle"
> >
<div <gl-button
v-if="list.isExpandable" v-if="list.isExpandable"
v-gl-tooltip.hover.bottom v-gl-tooltip.hover
:aria-label="caretTooltip" :aria-label="chevronTooltip"
:title="caretTooltip" :title="chevronTooltip"
aria-hidden="true" :icon="chevronIcon"
class="board-title-caret no-drag" class="board-title-caret no-drag"
variant="link"
@click="toggleExpanded" @click="toggleExpanded"
> />
<i
:class="{ 'fa-caret-right': list.isExpanded, 'fa-caret-down': !list.isExpanded }"
class="fa fa-fw"
></i>
</div>
<!-- The following is only true in EE and if it is a milestone --> <!-- The following is only true in EE and if it is a milestone -->
<span <span
v-if="list.type === 'milestone' && list.milestone" v-if="list.type === 'milestone' && list.milestone"
...@@ -232,7 +229,7 @@ export default { ...@@ -232,7 +229,7 @@ export default {
v-gl-tooltip.hover.bottom v-gl-tooltip.hover.bottom
:class="{ 'gl-display-none': !list.isExpanded }" :class="{ 'gl-display-none': !list.isExpanded }"
:aria-label="__('Delete list')" :aria-label="__('Delete list')"
class="board-delete no-drag gl-pr-0 gl-shadow-none" class="board-delete no-drag gl-pr-0 gl-shadow-none gl-mr-3"
:title="__('Delete list')" :title="__('Delete list')"
icon="remove" icon="remove"
size="small" size="small"
...@@ -263,32 +260,30 @@ export default { ...@@ -263,32 +260,30 @@ export default {
v-if="isNewIssueShown || isSettingsShown" v-if="isNewIssueShown || isSettingsShown"
class="board-list-button-group pl-2" class="board-list-button-group pl-2"
> >
<gl-deprecated-button <gl-button
v-if="isNewIssueShown" v-if="isNewIssueShown"
ref="newIssueBtn" ref="newIssueBtn"
v-gl-tooltip.hover
:class="{ :class="{
'gl-display-none': !list.isExpanded, 'gl-display-none': !list.isExpanded,
}" }"
:aria-label="__(`New issue`)" :aria-label="__('New issue')"
:title="__('New issue')"
class="issue-count-badge-add-button no-drag" class="issue-count-badge-add-button no-drag"
type="button" icon="plus"
@click="showNewIssueForm" @click="showNewIssueForm"
> />
<i aria-hidden="true" data-hidden="true" class="fa fa-plus"></i>
</gl-deprecated-button>
<gl-tooltip :target="() => $refs.newIssueBtn">{{ __('New Issue') }}</gl-tooltip>
<gl-deprecated-button <gl-button
v-if="isSettingsShown" v-if="isSettingsShown"
ref="settingsBtn" ref="settingsBtn"
:aria-label="__(`List settings`)" v-gl-tooltip.hover
:aria-label="__('List settings')"
class="no-drag js-board-settings-button" class="no-drag js-board-settings-button"
title="List settings" :title="__('List settings')"
type="button" icon="settings"
@click="openSidebarSettings" @click="openSidebarSettings"
> />
<gl-icon name="settings" />
</gl-deprecated-button>
<gl-tooltip :target="() => $refs.settingsBtn">{{ __('List settings') }}</gl-tooltip> <gl-tooltip :target="() => $refs.settingsBtn">{{ __('List settings') }}</gl-tooltip>
</gl-button-group> </gl-button-group>
</h3> </h3>
......
...@@ -144,7 +144,9 @@ const mixins = { ...@@ -144,7 +144,9 @@ const mixins = {
return 'merge-request-status closed issue-token-state-icon-closed'; return 'merge-request-status closed issue-token-state-icon-closed';
} }
return this.isOpen ? 'issue-token-state-icon-open' : 'issue-token-state-icon-closed'; return this.isOpen
? 'issue-token-state-icon-open gl-text-green-500'
: 'issue-token-state-icon-closed gl-text-blue-500';
}, },
computedLinkElementType() { computedLinkElementType() {
return this.path.length > 0 ? 'a' : 'span'; return this.path.length > 0 ? 'a' : 'span';
......
...@@ -34,14 +34,6 @@ $item-remove-button-space: 42px; ...@@ -34,14 +34,6 @@ $item-remove-button-space: 42px;
position: relative; position: relative;
line-height: $gl-line-height; line-height: $gl-line-height;
.issue-token-state-icon-open {
color: $green-500;
}
.issue-token-state-icon-closed {
color: $blue-500;
}
.merge-request-status.closed { .merge-request-status.closed {
color: $red-500; color: $red-500;
} }
......
...@@ -84,17 +84,22 @@ ...@@ -84,17 +84,22 @@
.board-title-caret { .board-title-caret {
cursor: pointer; cursor: pointer;
border-radius: $border-radius-default; border-radius: $border-radius-default;
padding: 4px; line-height: $gl-spacing-scale-5;
height: $gl-spacing-scale-5;
&.btn svg {
top: 0;
}
&:hover { &:hover {
background-color: $gray-dark; background-color: $gray-50;
transition: background-color 0.1s linear; transition: background-color 0.1s linear;
} }
} }
&:not(.is-collapsed) { &:not(.is-collapsed) {
.board-title-caret { .board-title-caret {
margin: 0 $gl-padding-4 0 -10px; margin-right: $gl-padding-4;
} }
} }
...@@ -155,7 +160,7 @@ ...@@ -155,7 +160,7 @@
.board-inner { .board-inner {
font-size: $issue-boards-font-size; font-size: $issue-boards-font-size;
background: $gray-light; background: $gray-light;
border: 1px solid $border-color; border: 1px solid $gray-100;
} }
.board-header { .board-header {
...@@ -186,8 +191,8 @@ ...@@ -186,8 +191,8 @@
.board-title { .board-title {
align-items: center; align-items: center;
font-size: 1em; font-size: 1em;
border-bottom: 1px solid $border-color; border-bottom: 1px solid $gray-100;
padding: $gl-padding-8 $gl-padding; padding: $gl-padding-8;
.js-max-issue-size::before { .js-max-issue-size::before {
content: '/'; content: '/';
...@@ -199,7 +204,6 @@ ...@@ -199,7 +204,6 @@
} }
.board-delete { .board-delete {
margin-right: 10px;
color: $gray-darkest; color: $gray-darkest;
background-color: transparent; background-color: transparent;
outline: 0; outline: 0;
...@@ -247,7 +251,7 @@ ...@@ -247,7 +251,7 @@
.board-card { .board-card {
background: $white; background: $white;
border: 1px solid $gray-200; border: 1px solid $gray-100;
box-shadow: 0 1px 2px $issue-boards-card-shadow; box-shadow: 0 1px 2px $issue-boards-card-shadow;
line-height: $gl-padding; line-height: $gl-padding;
list-style: none; list-style: none;
......
---
title: Update board header icons
merge_request: 34366
author:
type: changed
<script>
import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
export default {
components: {
GlIcon,
},
directives: {
GlTooltip: GlTooltipDirective,
},
props: {
epic: {
type: Object,
required: true,
},
},
computed: {
stateText() {
return this.epic.state === 'opened' ? __('Opened') : __('Closed');
},
stateIconClass() {
return this.epic.state === 'opened' ? 'gl-text-green-500' : 'gl-text-blue-500';
},
issuesCount() {
const { openedIssues, closedIssues } = this.epic.descendantCounts;
return openedIssues + closedIssues;
},
issuesCountTooltipText() {
return sprintf(__(`%{issuesCount} issues in this group`), { issuesCount: this.issuesCount });
},
},
};
</script>
<template>
<div class="board-epic-lane gl-py-5 gl-px-3 gl-display-flex gl-align-items-center">
<gl-icon
class="gl-mr-2 gl-flex-shrink-0"
:class="stateIconClass"
name="epic"
:aria-label="stateText"
/>
<span
v-gl-tooltip.hover
:title="epic.title"
class="gl-mr-3 gl-font-weight-bold gl-white-space-nowrap gl-text-overflow-ellipsis gl-overflow-hidden"
>
{{ epic.title }}
</span>
<span
v-gl-tooltip.hover
:title="issuesCountTooltipText"
class="gl-display-flex gl-align-items-center gl-text-gray-700"
tabindex="0"
:aria-label="issuesCountTooltipText"
data-testid="epic-lane-issue-count"
>
<gl-icon class="gl-mr-2 gl-flex-shrink-0" name="issues" aria-hidden="true" />
<span aria-hidden="true">{{ issuesCount }}</span>
</span>
</div>
</template>
<script> <script>
import { mapState } from 'vuex';
import BoardListHeader from 'ee_else_ce/boards/components/board_list_header.vue'; import BoardListHeader from 'ee_else_ce/boards/components/board_list_header.vue';
import EpicLane from './epic_lane.vue';
export default { export default {
components: { components: {
BoardListHeader, BoardListHeader,
EpicLane,
}, },
props: { props: {
lists: { lists: {
...@@ -14,14 +17,6 @@ export default { ...@@ -14,14 +17,6 @@ export default {
type: Boolean, type: Boolean,
required: true, required: true,
}, },
issueLinkBase: {
type: String,
required: true,
},
rootPath: {
type: String,
required: true,
},
boardId: { boardId: {
type: String, type: String,
required: true, required: true,
...@@ -31,11 +26,9 @@ export default { ...@@ -31,11 +26,9 @@ export default {
required: false, required: false,
default: false, default: false,
}, },
groupId: {
type: Number,
required: false,
default: null,
}, },
computed: {
...mapState(['epics']),
}, },
}; };
</script> </script>
...@@ -62,5 +55,6 @@ export default { ...@@ -62,5 +55,6 @@ export default {
:is-swimlanes-header="true" :is-swimlanes-header="true"
/> />
</div> </div>
<epic-lane v-for="epic in epics" :key="epic.id" :epic="epic" />
</div> </div>
</template> </template>
query groupEpics($fullPath: ID!) {
group(fullPath: $fullPath) {
epics(first: 10) {
nodes {
id
iid
title
state
webUrl
descendantCounts {
openedIssues
closedIssues
}
}
}
}
}
...@@ -5,6 +5,7 @@ import * as types from './mutation_types'; ...@@ -5,6 +5,7 @@ import * as types from './mutation_types';
import createDefaultClient from '~/lib/graphql'; import createDefaultClient from '~/lib/graphql';
import epicsSwimlanes from '../queries/epics_swimlanes.query.graphql'; import epicsSwimlanes from '../queries/epics_swimlanes.query.graphql';
import groupEpics from '../queries/group_epics.query.graphql';
const notImplemented = () => { const notImplemented = () => {
/* eslint-disable-next-line @gitlab/require-i18n-strings */ /* eslint-disable-next-line @gitlab/require-i18n-strings */
...@@ -32,6 +33,25 @@ const fetchEpicsSwimlanes = ({ endpoints }) => { ...@@ -32,6 +33,25 @@ const fetchEpicsSwimlanes = ({ endpoints }) => {
}); });
}; };
const fetchEpics = ({ endpoints }) => {
const { fullPath } = endpoints;
const query = groupEpics;
const variables = {
fullPath,
};
return gqlClient
.query({
query,
variables,
})
.then(({ data }) => {
const { group } = data;
return group?.epics.nodes || [];
});
};
export default { export default {
...actionsCE, ...actionsCE,
...@@ -80,9 +100,15 @@ export default { ...@@ -80,9 +100,15 @@ export default {
commit(types.TOGGLE_EPICS_SWIMLANES); commit(types.TOGGLE_EPICS_SWIMLANES);
if (state.isShowingEpicsSwimlanes) { if (state.isShowingEpicsSwimlanes) {
fetchEpicsSwimlanes(state) Promise.all([fetchEpicsSwimlanes(state), fetchEpics(state)])
.then(swimlanes => { .then(([swimlanes, epics]) => {
if (swimlanes) {
dispatch('receiveSwimlanesSuccess', swimlanes); dispatch('receiveSwimlanesSuccess', swimlanes);
}
if (epics) {
dispatch('receiveEpicsSuccess', epics);
}
}) })
.catch(() => dispatch('receiveSwimlanesFailure')); .catch(() => dispatch('receiveSwimlanesFailure'));
} }
...@@ -95,4 +121,8 @@ export default { ...@@ -95,4 +121,8 @@ export default {
receiveSwimlanesFailure: ({ commit }) => { receiveSwimlanesFailure: ({ commit }) => {
commit(types.RECEIVE_SWIMLANES_FAILURE); commit(types.RECEIVE_SWIMLANES_FAILURE);
}, },
receiveEpicsSuccess: ({ commit }, swimlanes) => {
commit(types.RECEIVE_EPICS_SUCCESS, swimlanes);
},
}; };
...@@ -15,4 +15,5 @@ export const TOGGLE_LABELS = 'TOGGLE_LABELS'; ...@@ -15,4 +15,5 @@ export const TOGGLE_LABELS = 'TOGGLE_LABELS';
export const TOGGLE_EPICS_SWIMLANES = 'TOGGLE_EPICS_SWIMLANES'; export const TOGGLE_EPICS_SWIMLANES = 'TOGGLE_EPICS_SWIMLANES';
export const RECEIVE_SWIMLANES_SUCCESS = 'RECEIVE_SWIMLANES_SUCCESS'; export const RECEIVE_SWIMLANES_SUCCESS = 'RECEIVE_SWIMLANES_SUCCESS';
export const RECEIVE_SWIMLANES_FAILURE = 'RECEIVE_SWIMLANES_FAILURE'; export const RECEIVE_SWIMLANES_FAILURE = 'RECEIVE_SWIMLANES_FAILURE';
export const RECEIVE_EPICS_SUCCESS = 'RECEIVE_EPICS_SUCCESS';
export const SET_ACTIVE_LIST_ID = 'SET_ACTIVE_LIST_ID'; export const SET_ACTIVE_LIST_ID = 'SET_ACTIVE_LIST_ID';
...@@ -81,4 +81,8 @@ export default { ...@@ -81,4 +81,8 @@ export default {
state.epicsSwimlanesFetchFailure = true; state.epicsSwimlanesFetchFailure = true;
state.epicsSwimlanesFetchInProgress = false; state.epicsSwimlanesFetchInProgress = false;
}, },
[mutationTypes.RECEIVE_EPICS_SUCCESS]: (state, epics) => {
state.epics = epics;
},
}; };
...@@ -7,4 +7,5 @@ export default () => ({ ...@@ -7,4 +7,5 @@ export default () => ({
epicsSwimlanesFetchInProgress: false, epicsSwimlanesFetchInProgress: false,
epicsSwimlanesFetchFailure: false, epicsSwimlanesFetchFailure: false,
epicsSwimlanes: {}, epicsSwimlanes: {},
epics: {},
}); });
...@@ -83,7 +83,9 @@ export default { ...@@ -83,7 +83,9 @@ export default {
return this.item.type === ChildType.Epic ? 'epic' : 'issues'; return this.item.type === ChildType.Epic ? 'epic' : 'issues';
}, },
stateIconClass() { stateIconClass() {
return this.isOpen ? 'issue-token-state-icon-open' : 'issue-token-state-icon-closed'; return this.isOpen
? 'issue-token-state-icon-open gl-text-green-500'
: 'issue-token-state-icon-closed gl-text-blue-500';
}, },
itemId() { itemId() {
return this.itemReference.split(this.item.pathIdSeparator).pop(); return this.itemReference.split(this.item.pathIdSeparator).pop();
......
import { shallowMount } from '@vue/test-utils';
import EpicLane from 'ee/boards/components/epic_lane.vue';
import { GlIcon } from '@gitlab/ui';
import { mockEpic } from '../mock_data';
describe('EpicLane', () => {
let wrapper;
const defaultProps = { epic: mockEpic };
const createComponent = (props = {}) => {
wrapper = shallowMount(EpicLane, {
propsData: {
...defaultProps,
...props,
},
});
};
afterEach(() => {
wrapper.destroy();
});
describe('template', () => {
beforeEach(() => {
createComponent();
});
it('icon aria label is Opened when epic is opened', () => {
expect(wrapper.find(GlIcon).attributes('aria-label')).toEqual('Opened');
});
it('icon aria label is Closed when epic is closed', () => {
createComponent({ epic: { ...mockEpic, state: 'closed' } });
expect(wrapper.find(GlIcon).attributes('aria-label')).toEqual('Closed');
});
it('displays total count of issues in epic', () => {
expect(wrapper.find('[data-testid="epic-lane-issue-count"]').text()).toContain(5);
});
it('displays 2 icons', () => {
expect(wrapper.findAll(GlIcon).length).toEqual(2);
});
it('displays epic title', () => {
expect(wrapper.text()).toContain(mockEpic.title);
});
});
});
export const mockSwimlanes = [
{
id: 'gid://gitlab/List/1',
title: 'Backlog',
position: null,
listType: 'backlog',
collapsed: false,
label: null,
maxIssueCount: 0,
assignee: null,
milestone: null,
},
{
id: 'gid://gitlab/List/10',
title: 'To Do',
position: 0,
listType: 'label',
collapsed: false,
label: {
id: 'gid://gitlab/GroupLabel/121',
title: 'To Do',
color: '#F0AD4E',
textColor: '#FFFFFF',
description: null,
},
maxIssueCount: 0,
assignee: null,
milestone: null,
},
];
const defaultDescendantCounts = {
openedIssues: 0,
closedIssues: 0,
};
export const mockEpic = {
id: 1,
iid: 1,
title: 'Epic title',
state: 'opened',
webUrl: '/groups/gitlab-org/-/epics/1',
descendantCounts: {
openedIssues: 3,
closedIssues: 2,
},
};
export const mockEpics = [
{
id: 41,
iid: 2,
description: null,
title: 'Another marketing',
group_id: 56,
group_name: 'Marketing',
group_full_name: 'Gitlab Org / Marketing',
start_date: '2017-12-26',
end_date: '2018-03-10',
web_url: '/groups/gitlab-org/marketing/-/epics/2',
descendantCounts: defaultDescendantCounts,
hasParent: true,
parent: {
id: '40',
},
},
{
id: 40,
iid: 1,
description: null,
title: 'Marketing epic',
group_id: 56,
group_name: 'Marketing',
group_full_name: 'Gitlab Org / Marketing',
start_date: '2017-12-25',
end_date: '2018-03-09',
web_url: '/groups/gitlab-org/marketing/-/epics/1',
descendantCounts: defaultDescendantCounts,
hasParent: false,
},
{
id: 39,
iid: 12,
description: null,
title: 'Epic with end in first timeframe month',
group_id: 2,
group_name: 'Gitlab Org',
group_full_name: 'Gitlab Org',
start_date: '2017-04-02',
end_date: '2017-11-30',
web_url: '/groups/gitlab-org/-/epics/12',
descendantCounts: defaultDescendantCounts,
hasParent: false,
},
{
id: 38,
iid: 11,
description: null,
title: 'Epic with end date out of range',
group_id: 2,
group_name: 'Gitlab Org',
group_full_name: 'Gitlab Org',
start_date: '2018-01-15',
end_date: '2020-01-03',
web_url: '/groups/gitlab-org/-/epics/11',
descendantCounts: defaultDescendantCounts,
hasParent: false,
},
{
id: 37,
iid: 10,
description: null,
title: 'Epic with timeline in same month',
group_id: 2,
group_name: 'Gitlab Org',
group_full_name: 'Gitlab Org',
start_date: '2018-01-01',
end_date: '2018-01-31',
web_url: '/groups/gitlab-org/-/epics/10',
descendantCounts: defaultDescendantCounts,
hasParent: false,
},
];
import mutations from 'ee/boards/stores/mutations'; import mutations from 'ee/boards/stores/mutations';
import { inactiveListId } from '~/boards/constants'; import { inactiveListId } from '~/boards/constants';
import { mockSwimlanes, mockEpics } from '../mock_data';
const expectNotImplemented = action => { const expectNotImplemented = action => {
it('is not implemented', () => { it('is not implemented', () => {
...@@ -114,4 +115,54 @@ describe('TOGGLE_EPICS_SWIMLANES', () => { ...@@ -114,4 +115,54 @@ describe('TOGGLE_EPICS_SWIMLANES', () => {
expect(state.isShowingEpicsSwimlanes).toBe(true); expect(state.isShowingEpicsSwimlanes).toBe(true);
}); });
it('sets epicsSwimlanesFetchInProgress to true', () => {
const state = {
epicsSwimlanesFetchInProgress: false,
};
mutations.TOGGLE_EPICS_SWIMLANES(state);
expect(state.epicsSwimlanesFetchInProgress).toBe(true);
});
});
describe('RECEIVE_SWIMLANES_SUCCESS', () => {
it('sets epicsSwimlanesFetchInProgress to false and populates epicsSwimlanes with payload', () => {
const state = {
epicsSwimlanesFetchInProgress: true,
epicsSwimlanes: {},
};
mutations.RECEIVE_SWIMLANES_SUCCESS(state, mockSwimlanes);
expect(state.epicsSwimlanesFetchInProgress).toBe(false);
expect(state.epicsSwimlanes).toEqual(mockSwimlanes);
});
});
describe('RECEIVE_SWIMLANES_FAILURE', () => {
it('sets epicsSwimlanesFetchInProgress to false and epicsSwimlanesFetchFailure to true', () => {
const state = {
epicsSwimlanesFetchInProgress: true,
epicsSwimlanesFetchFailure: false,
};
mutations.RECEIVE_SWIMLANES_FAILURE(state);
expect(state.epicsSwimlanesFetchInProgress).toBe(false);
expect(state.epicsSwimlanesFetchFailure).toBe(true);
});
});
describe('RECEIVE_EPICS_SUCCESS', () => {
it('populates epics with payload', () => {
const state = {
epics: {},
};
mutations.RECEIVE_EPICS_SUCCESS(state, mockEpics);
expect(state.epics).toEqual(mockEpics);
});
}); });
...@@ -191,23 +191,25 @@ describe('RelatedItemsTree', () => { ...@@ -191,23 +191,25 @@ describe('RelatedItemsTree', () => {
}); });
describe('stateIconClass', () => { describe('stateIconClass', () => {
it('returns string `issue-token-state-icon-open` when `item.state` value is `opened`', () => { it('returns string `issue-token-state-icon-open gl-text-green-500` when `item.state` value is `opened`', () => {
wrapper.setProps({ wrapper.setProps({
item: { ...mockItem, state: ChildState.Open }, item: { ...mockItem, state: ChildState.Open },
}); });
return wrapper.vm.$nextTick(() => { return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.stateIconClass).toBe('issue-token-state-icon-open'); expect(wrapper.vm.stateIconClass).toBe('issue-token-state-icon-open gl-text-green-500');
}); });
}); });
it('returns string `issue-token-state-icon-closed` when `item.state` value is `closed`', () => { it('returns string `issue-token-state-icon-closed gl-text-blue-500` when `item.state` value is `closed`', () => {
wrapper.setProps({ wrapper.setProps({
item: { ...mockItem, state: ChildState.Closed }, item: { ...mockItem, state: ChildState.Closed },
}); });
return wrapper.vm.$nextTick(() => { return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.stateIconClass).toBe('issue-token-state-icon-closed'); expect(wrapper.vm.stateIconClass).toBe(
'issue-token-state-icon-closed gl-text-blue-500',
);
}); });
}); });
}); });
......
...@@ -380,6 +380,9 @@ msgstr "" ...@@ -380,6 +380,9 @@ msgstr ""
msgid "%{issuableType} will be removed! Are you sure?" msgid "%{issuableType} will be removed! Are you sure?"
msgstr "" msgstr ""
msgid "%{issuesCount} issues in this group"
msgstr ""
msgid "%{issuesSize} issues" msgid "%{issuesSize} issues"
msgstr "" msgstr ""
......
...@@ -107,7 +107,7 @@ describe('Board List Header Component', () => { ...@@ -107,7 +107,7 @@ describe('Board List Header Component', () => {
createComponent(); createComponent();
expect(isCollapsed()).toBe(false); expect(isCollapsed()).toBe(false);
wrapper.find('[data-testid="board-list-header"]').trigger('click'); wrapper.find('[data-testid="board-list-header"]').vm.$emit('click');
return wrapper.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(isCollapsed()).toBe(false); expect(isCollapsed()).toBe(false);
...@@ -118,7 +118,7 @@ describe('Board List Header Component', () => { ...@@ -118,7 +118,7 @@ describe('Board List Header Component', () => {
createComponent(); createComponent();
expect(isExpanded()).toBe(true); expect(isExpanded()).toBe(true);
findCaret().trigger('click'); findCaret().vm.$emit('click');
return wrapper.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(isCollapsed()).toBe(true); expect(isCollapsed()).toBe(true);
...@@ -129,7 +129,7 @@ describe('Board List Header Component', () => { ...@@ -129,7 +129,7 @@ describe('Board List Header Component', () => {
createComponent({ collapsed: true }); createComponent({ collapsed: true });
expect(isCollapsed()).toBe(true); expect(isCollapsed()).toBe(true);
findCaret().trigger('click'); findCaret().vm.$emit('click');
return wrapper.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(isCollapsed()).toBe(false); expect(isCollapsed()).toBe(false);
...@@ -142,7 +142,7 @@ describe('Board List Header Component', () => { ...@@ -142,7 +142,7 @@ describe('Board List Header Component', () => {
createComponent({ withLocalStorage: false }); createComponent({ withLocalStorage: false });
findCaret().trigger('click'); findCaret().vm.$emit('click');
return wrapper.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.list.update).toHaveBeenCalledTimes(1); expect(wrapper.vm.list.update).toHaveBeenCalledTimes(1);
...@@ -155,7 +155,7 @@ describe('Board List Header Component', () => { ...@@ -155,7 +155,7 @@ describe('Board List Header Component', () => {
createComponent(); createComponent();
findCaret().trigger('click'); findCaret().vm.$emit('click');
return wrapper.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(wrapper.vm.list.update).not.toHaveBeenCalled(); expect(wrapper.vm.list.update).not.toHaveBeenCalled();
......
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