Commit d42bd491 authored by Olena Horal-Koretska's avatar Olena Horal-Koretska

Merge branch '220867-hide-status-labels-for-closed-issues-on-epics-tree' into 'master'

Hide health status labels for closed issues on epics tree

See merge request gitlab-org/gitlab!37561
parents 24b25c6c 874c0cc2
...@@ -65,7 +65,8 @@ to add an issue to an epic, reorder issues, move issues between epics, or promot ...@@ -65,7 +65,8 @@ to add an issue to an epic, reorder issues, move issues between epics, or promot
## Issue health status in Epic tree **(ULTIMATE)** ## Issue health status in Epic tree **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/199184) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.10. > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/199184) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.10.
> - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/220867) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.3. The health status of a closed issue will be hidden.
You can report on and quickly respond to the health of individual issues and epics by setting a You can report on and quickly respond to the health of individual issues and epics by setting a
red, amber, or green [health status on an issue](../../project/issues/index.md#health-status-ultimate), red, amber, or green [health status on an issue](../../project/issues/index.md#health-status-ultimate),
......
...@@ -127,6 +127,13 @@ export default { ...@@ -127,6 +127,13 @@ export default {
showHealthStatus() { showHealthStatus() {
return this.item.healthStatus && this.allowIssuableHealthStatus; return this.item.healthStatus && this.allowIssuableHealthStatus;
}, },
showIssueHealthStatus() {
return this.isIssue && this.isOpen && this.showHealthStatus;
},
showEpicHealthStatus() {
const { descendantCounts: { openedIssues = 0 } = {} } = this.item;
return this.isEpic && this.showHealthStatus && openedIssues > 0;
},
}, },
methods: { methods: {
...mapActions(['setRemoveItemModalProps']), ...mapActions(['setRemoveItemModalProps']),
...@@ -143,20 +150,22 @@ export default { ...@@ -143,20 +150,22 @@ export default {
</script> </script>
<template> <template>
<div class="card card-slim sortable-row flex-grow-1"> <div class="card card-slim sortable-row gl-flex-grow-1">
<div <div
class="item-body card-body d-flex align-items-center pr-1 pl-2 py-1" class="item-body card-body gl-display-flex gl-align-items-center gl-pr-2 gl-pl-3 gl-py-2"
:class="{ :class="{
'item-logged-out': !userSignedIn, 'item-logged-out': !userSignedIn,
'item-closed': isClosed, 'item-closed': isClosed,
}" }"
> >
<div class="item-contents d-flex align-items-center flex-wrap flex-grow-1 flex-xl-nowrap"> <div
<div class="item-title-wrapper flex-grow-1 mr-2"> class="item-contents gl-display-flex gl-align-items-center gl-flex-wrap gl-flex-grow-1 flex-xl-nowrap"
<div class="item-title d-flex mb-0 pt-1 pb-1"> >
<div class="item-title-wrapper gl-flex-grow-1 gl-mr-3">
<div class="item-title gl-display-flex gl-mb-0 gl-pt-2 gl-pb-2">
<gl-icon <gl-icon
ref="stateIconMd" ref="stateIconMd"
class="d-block mr-2" class="gl-display-block gl-mr-3"
:class="stateIconClass" :class="stateIconClass"
:name="stateIconName" :name="stateIconName"
:aria-label="stateText" :aria-label="stateText"
...@@ -188,13 +197,13 @@ export default { ...@@ -188,13 +197,13 @@ export default {
</div> </div>
<div <div
class="item-meta d-flex flex-wrap mt-xl-0 flex-xl-nowrap align-items-center pb-1 pt-1 ml-4" class="item-meta gl-display-flex gl-flex-wrap mt-xl-0 flex-xl-nowrap gl-align-items-center gl-py-2 gl-ml-6"
> >
<span class="mr-3">{{ itemHierarchy }}</span> <span class="gl-mr-4">{{ itemHierarchy }}</span>
<gl-tooltip v-if="isEpic" :target="() => $refs.countBadge"> <gl-tooltip v-if="isEpic" :target="() => $refs.countBadge">
<p v-if="allowSubEpics" class="font-weight-bold m-0"> <p v-if="allowSubEpics" class="gl-font-weight-bold gl-m-0">
{{ __('Epics') }} &#8226; {{ __('Epics') }} &#8226;
<span class="text-secondary-400 font-weight-normal" <span class="text-secondary-400 gl-font-weight-normal"
>{{ >{{
sprintf(__('%{openedEpics} open, %{closedEpics} closed'), { sprintf(__('%{openedEpics} open, %{closedEpics} closed'), {
openedEpics: item.descendantCounts && item.descendantCounts.openedEpics, openedEpics: item.descendantCounts && item.descendantCounts.openedEpics,
...@@ -203,9 +212,9 @@ export default { ...@@ -203,9 +212,9 @@ export default {
}} }}
</span> </span>
</p> </p>
<p class="font-weight-bold m-0"> <p class="gl-font-weight-bold gl-m-0">
{{ __('Issues') }} &#8226; {{ __('Issues') }} &#8226;
<span class="text-secondary-400 font-weight-normal" <span class="text-secondary-400 gl-font-weight-normal"
>{{ >{{
sprintf(__('%{openedIssues} open, %{closedIssues} closed'), { sprintf(__('%{openedIssues} open, %{closedIssues} closed'), {
openedIssues: item.descendantCounts && item.descendantCounts.openedIssues, openedIssues: item.descendantCounts && item.descendantCounts.openedIssues,
...@@ -219,17 +228,20 @@ export default { ...@@ -219,17 +228,20 @@ export default {
<div <div
v-if="isEpic" v-if="isEpic"
ref="countBadge" ref="countBadge"
class="issue-count-badge gl-display-inline-flex text-secondary py-0 p-lg-0" class="issue-count-badge text-secondary gl-display-inline-flex gl-py-0 p-lg-0"
> >
<span v-if="allowSubEpics" class="d-inline-flex align-items-center mr-2"> <span
<gl-icon name="epic" class="mr-1" /> v-if="allowSubEpics"
class="gl-display-inline-flex gl-align-items-center gl-mr-3"
>
<gl-icon name="epic" class="gl-mr-2" />
{{ totalEpicsCount }} {{ totalEpicsCount }}
</span> </span>
<span <span
class="d-inline-flex align-items-center mr-2" class="gl-display-inline-flex gl-align-items-center gl-mr-3"
:class="{ 'ml-2': allowSubEpics }" :class="{ 'ml-2': allowSubEpics }"
> >
<gl-icon name="issues" class="mr-1" /> <gl-icon name="issues" class="gl-mr-2" />
{{ totalIssuesCount }} {{ totalIssuesCount }}
</span> </span>
</div> </div>
...@@ -237,33 +249,39 @@ export default { ...@@ -237,33 +249,39 @@ export default {
<item-milestone <item-milestone
v-if="hasMilestone" v-if="hasMilestone"
:milestone="item.milestone" :milestone="item.milestone"
class="d-flex align-items-center item-milestone mr-3" class="item-milestone gl-display-flex gl-align-items-center gl-mr-4"
/> />
<item-due-date <item-due-date
v-if="item.dueDate" v-if="item.dueDate"
:date="item.dueDate" :date="item.dueDate"
tooltip-placement="top" tooltip-placement="top"
css-class="item-due-date d-flex align-items-center mr-3" css-class="item-due-date gl-display-flex gl-align-items-center gl-mr-4"
/> />
<item-weight <item-weight
v-if="item.weight" v-if="item.weight"
:weight="item.weight" :weight="item.weight"
class="item-weight d-flex align-items-center mr-3" class="item-weight gl-display-flex gl-align-items-center gl-mr-4"
tag-name="span" tag-name="span"
/> />
<item-assignees <item-assignees
v-if="hasAssignees" v-if="hasAssignees"
:assignees="item.assignees" :assignees="item.assignees"
class="item-assignees d-inline-flex align-items-center mr-3 mb-md-0 flex-xl-grow-0" class="item-assignees gl-display-inline-flex gl-align-items-center gl-mr-4 mb-md-0 flex-xl-grow-0"
/> />
<div v-if="showHealthStatus" class="item-health-status"> <epic-health-status
<epic-health-status v-if="isEpic" :health-status="item.healthStatus" /> v-if="showEpicHealthStatus"
<issue-health-status v-else-if="isIssue" :health-status="item.healthStatus" /> :health-status="item.healthStatus"
</div> data-testid="epic-health-status"
/>
<issue-health-status
v-if="showIssueHealthStatus"
:health-status="item.healthStatus"
data-testid="issue-health-status"
/>
</div> </div>
</div> </div>
...@@ -273,12 +291,12 @@ export default { ...@@ -273,12 +291,12 @@ export default {
v-gl-modal-directive="$options.itemRemoveModalId" v-gl-modal-directive="$options.itemRemoveModalId"
:title="__('Remove')" :title="__('Remove')"
:disabled="itemActionInProgress" :disabled="itemActionInProgress"
class="btn-svg btn-item-remove js-issue-item-remove-button qa-remove-issue-button align-self-start" class="btn-svg btn-item-remove js-issue-item-remove-button qa-remove-issue-button gl-align-self-start"
@click="handleRemoveClick" @click="handleRemoveClick"
> >
<gl-icon name="close" class="btn-item-remove-icon" /> <gl-icon name="close" class="btn-item-remove-icon" />
</gl-deprecated-button> </gl-deprecated-button>
<span v-if="showEmptySpacer" class="p-3"></span> <span v-if="showEmptySpacer" class="gl-p-3"></span>
</div> </div>
</div> </div>
</div> </div>
......
---
title: Hide health status labels for closed issues on epics tree
merge_request: 37561
author:
type: changed
...@@ -61,7 +61,7 @@ describe('RelatedItemsTree', () => { ...@@ -61,7 +61,7 @@ describe('RelatedItemsTree', () => {
it('returns string containing issue count based on available direct children within state', () => { it('returns string containing issue count based on available direct children within state', () => {
expect(wrapper.find(GlTooltip).text()).toContain(`Issues • expect(wrapper.find(GlTooltip).text()).toContain(`Issues •
1 open, 1 closed`); 2 open, 1 closed`);
}); });
}); });
...@@ -232,7 +232,7 @@ describe('RelatedItemsTree', () => { ...@@ -232,7 +232,7 @@ describe('RelatedItemsTree', () => {
const issuesEl = wrapper.findAll('.issue-count-badge > span').at(1); const issuesEl = wrapper.findAll('.issue-count-badge > span').at(1);
const issueIcon = issuesEl.find(GlIcon); const issueIcon = issuesEl.find(GlIcon);
expect(issuesEl.text().trim()).toContain('2'); expect(issuesEl.text().trim()).toContain('3');
expect(issueIcon.isVisible()).toBe(true); expect(issueIcon.isVisible()).toBe(true);
expect(issueIcon.props('name')).toBe('issues'); expect(issueIcon.props('name')).toBe('issues');
}); });
......
...@@ -15,16 +15,40 @@ import ItemAssignees from '~/vue_shared/components/issue/issue_assignees.vue'; ...@@ -15,16 +15,40 @@ import ItemAssignees from '~/vue_shared/components/issue/issue_assignees.vue';
import ItemDueDate from '~/boards/components/issue_due_date.vue'; import ItemDueDate from '~/boards/components/issue_due_date.vue';
import ItemMilestone from '~/vue_shared/components/issue/issue_milestone.vue'; import ItemMilestone from '~/vue_shared/components/issue/issue_milestone.vue';
import { mockParentItem, mockInitialConfig, mockQueryResponse, mockIssue1 } from '../mock_data'; import {
mockParentItem,
mockInitialConfig,
mockQueryResponse,
mockIssue1,
mockClosedIssue,
mockEpic1 as mockOpenEpic,
mockEpic2 as mockClosedEpic,
mockEpicMeta1,
mockEpicMeta2,
mockEpicMeta3,
} from '../mock_data';
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
const mockItem = { let mockItem;
...mockIssue1,
const createIssueItem = (mockIssue = mockIssue1) => {
return {
...mockIssue,
type: ChildType.Issue, type: ChildType.Issue,
pathIdSeparator: PathIdSeparator.Issue, pathIdSeparator: PathIdSeparator.Issue,
assignees: epicUtils.extractIssueAssignees(mockIssue1.assignees), assignees: epicUtils.extractIssueAssignees(mockIssue.assignees),
};
};
const createEpicItem = (mockEpic = mockOpenEpic, mockEpicMeta = mockEpicMeta1) => {
return {
...mockEpic,
type: ChildType.Epic,
pathIdSeparator: PathIdSeparator.Epic,
...mockEpicMeta,
};
}; };
const createComponent = (parentItem = mockParentItem, item = mockItem) => { const createComponent = (parentItem = mockParentItem, item = mockItem) => {
...@@ -53,27 +77,22 @@ const createComponent = (parentItem = mockParentItem, item = mockItem) => { ...@@ -53,27 +77,22 @@ const createComponent = (parentItem = mockParentItem, item = mockItem) => {
}); });
}; };
const createEpicComponent = () => {
const mockEpicItem = {
...mockItem,
type: ChildType.Epic,
healthStatus: mockParentItem.healthStatus,
descendantCounts: {
openedEpics: 0,
closedEpics: 0,
openedIssues: 0,
closedIssues: 0,
},
};
return createComponent(mockParentItem, mockEpicItem);
};
describe('RelatedItemsTree', () => { describe('RelatedItemsTree', () => {
describe('TreeItemBody', () => { describe('TreeItemBody', () => {
let wrapper; let wrapper;
const findCountBadge = () => wrapper.find({ ref: 'countBadge' });
const findIssueHealthStatus = () => wrapper.find('[data-testid="issue-health-status"]');
const findEpicHealthStatus = () => wrapper.find('[data-testid="epic-health-status"]');
const enableHealthStatus = () => {
wrapper.vm.$store.commit('SET_INITIAL_CONFIG', {
...mockInitialConfig,
allowIssuableHealthStatus: true,
});
};
beforeEach(() => { beforeEach(() => {
mockItem = createIssueItem();
wrapper = createComponent(); wrapper = createComponent();
}); });
...@@ -170,26 +189,6 @@ describe('RelatedItemsTree', () => { ...@@ -170,26 +189,6 @@ describe('RelatedItemsTree', () => {
}); });
}); });
describe('stateIconName', () => {
it('returns string `issues` when `item.type` value is `issue`', () => {
wrapper.setProps({
item: { ...mockItem, type: ChildType.Issue },
});
return wrapper.vm.$nextTick(() => {
expect(wrapper.vm.stateIconName).toBe('issues');
});
});
it('returns string `epic` when `item.type` value is `epic`', () => {
const epicItemWrapper = createEpicComponent();
expect(epicItemWrapper.vm.stateIconName).toBe('epic');
epicItemWrapper.destroy();
});
});
describe('stateIconClass', () => { describe('stateIconClass', () => {
it('returns string `issue-token-state-icon-open gl-text-green-500` 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({
...@@ -242,17 +241,28 @@ describe('RelatedItemsTree', () => { ...@@ -242,17 +241,28 @@ describe('RelatedItemsTree', () => {
}); });
}); });
describe('isEpic', () => { describe.each`
it('returns false when item type is issue', () => { createItem | itemType | isEpic | stateIconName
expect(wrapper.vm.isEpic).toBe(false); ${createEpicItem} | ${'epic'} | ${true} | ${'epic'}
${createIssueItem} | ${'issue'} | ${false} | ${'issues'}
`(`when dependent on item type`, ({ createItem, isEpic, stateIconName, itemType }) => {
beforeEach(() => {
mockItem = createItem();
wrapper = createComponent();
}); });
it('returns true when item type is epic', () => { describe('isEpic', () => {
const epicItemWrapper = createEpicComponent(); it(`returns ${isEpic} when item type is ${itemType}`, () => {
expect(wrapper.vm.isEpic).toBe(isEpic);
});
});
expect(epicItemWrapper.vm.isEpic).toBe(true); describe('stateIconName', () => {
it(`returns string ${stateIconName}`, async () => {
await wrapper.vm.$nextTick();
epicItemWrapper.destroy(); expect(wrapper.vm.stateIconName).toBe(stateIconName);
});
}); });
}); });
}); });
...@@ -354,35 +364,72 @@ describe('RelatedItemsTree', () => { ...@@ -354,35 +364,72 @@ describe('RelatedItemsTree', () => {
expect(removeButton.attributes('title')).toBe('Remove'); expect(removeButton.attributes('title')).toBe('Remove');
}); });
it('does not render issue count badge when item is issue', () => { describe.each`
expect(wrapper.find('.issue-count-badge').exists()).toBe(false); createItem | countBadgeExists | itemType
${createEpicItem} | ${true} | ${'epic'}
${createIssueItem} | ${false} | ${'issue'}
`('issue count badge', ({ createItem, countBadgeExists, itemType }) => {
beforeEach(() => {
mockItem = createItem();
wrapper = createComponent();
});
it(`${
countBadgeExists ? 'renders' : 'does not render'
} issue count badge when item type is ${itemType}`, () => {
expect(findCountBadge().exists()).toBe(countBadgeExists);
});
}); });
it('render issue count badge when item is epic', () => { describe('health status', () => {
const epicWrapper = createEpicComponent(); it('renders when feature is available', async () => {
expect(findIssueHealthStatus().exists()).toBe(false);
expect(epicWrapper.find('.issue-count-badge').exists()).toBe(true); enableHealthStatus();
epicWrapper.destroy(); await wrapper.vm.$nextTick();
expect(findIssueHealthStatus().exists()).toBe(true);
}); });
it('renders health status when feature', () => { describe.each`
function testExistence(exists) { mockIssue | showHealthStatus
const healthStatus = wrapper.find('.item-health-status').exists(); ${mockIssue1} | ${true}
${mockClosedIssue} | ${false}
`("for '$mockIssue.state' issue", ({ mockIssue, showHealthStatus }) => {
beforeEach(() => {
mockItem = createIssueItem(mockIssue);
wrapper = createComponent();
enableHealthStatus();
});
expect(healthStatus).toBe(exists); it(`${showHealthStatus ? 'renders' : 'does not render'} health status`, () => {
} expect(findIssueHealthStatus().exists()).toBe(showHealthStatus);
});
});
testExistence(false); describe.each`
mockEpic | mockEpicMeta | childIssues | showHealthStatus
${mockOpenEpic} | ${mockEpicMeta1} | ${'open issue(s)'} | ${true}
${mockOpenEpic} | ${mockEpicMeta2} | ${'closed'} | ${false}
${mockClosedEpic} | ${mockEpicMeta1} | ${'open issue(s)'} | ${true}
${mockClosedEpic} | ${mockEpicMeta2} | ${'closed issues'} | ${false}
${mockClosedEpic} | ${mockEpicMeta3} | ${'no issues'} | ${false}
`(
"for '$mockEpic.state' epic with '$childIssues'",
({ mockEpic, mockEpicMeta, showHealthStatus }) => {
beforeEach(() => {
mockItem = createEpicItem(mockEpic, mockEpicMeta);
wrapper.vm.$store.commit('SET_INITIAL_CONFIG', { wrapper = createComponent();
...mockInitialConfig, enableHealthStatus();
allowIssuableHealthStatus: true,
}); });
return wrapper.vm.$nextTick(() => { it(`${showHealthStatus ? 'renders' : 'does not render'} health status`, () => {
testExistence(true); expect(findEpicHealthStatus().exists()).toBe(showHealthStatus);
}); });
},
);
}); });
}); });
}); });
......
import { TEST_HOST } from 'spec/test_constants'; import { TEST_HOST } from 'spec/test_constants';
import { ChildState } from 'ee/related_items_tree/constants';
export const mockInitialConfig = { export const mockInitialConfig = {
epicsEndpoint: `${TEST_HOST}/epics`, epicsEndpoint: `${TEST_HOST}/epics`,
...@@ -24,7 +25,7 @@ export const mockParentItem = { ...@@ -24,7 +25,7 @@ export const mockParentItem = {
descendantCounts: { descendantCounts: {
openedEpics: 1, openedEpics: 1,
closedEpics: 1, closedEpics: 1,
openedIssues: 1, openedIssues: 2,
closedIssues: 1, closedIssues: 1,
}, },
healthStatus: { healthStatus: {
...@@ -62,7 +63,7 @@ export const mockEpic1 = { ...@@ -62,7 +63,7 @@ export const mockEpic1 = {
id: 'gid://gitlab/Epic/4', id: 'gid://gitlab/Epic/4',
iid: '4', iid: '4',
title: 'Quo ea ipsa enim perferendis at omnis officia.', title: 'Quo ea ipsa enim perferendis at omnis officia.',
state: 'opened', state: ChildState.Open,
webPath: '/groups/gitlab-org/-/epics/4', webPath: '/groups/gitlab-org/-/epics/4',
reference: '&4', reference: '&4',
relationPath: '/groups/gitlab-org/-/epics/1/links/4', relationPath: '/groups/gitlab-org/-/epics/1/links/4',
...@@ -88,7 +89,7 @@ export const mockEpic2 = { ...@@ -88,7 +89,7 @@ export const mockEpic2 = {
id: 'gid://gitlab/Epic/3', id: 'gid://gitlab/Epic/3',
iid: '3', iid: '3',
title: 'A nisi mollitia explicabo quam soluta dolor hic.', title: 'A nisi mollitia explicabo quam soluta dolor hic.',
state: 'closed', state: ChildState.Closed,
webPath: '/groups/gitlab-org/-/epics/3', webPath: '/groups/gitlab-org/-/epics/3',
reference: '&3', reference: '&3',
relationPath: '/groups/gitlab-org/-/epics/1/links/3', relationPath: '/groups/gitlab-org/-/epics/1/links/3',
...@@ -110,12 +111,57 @@ export const mockEpic2 = { ...@@ -110,12 +111,57 @@ export const mockEpic2 = {
}, },
}; };
// Epic meta data for having some open issues
export const mockEpicMeta1 = {
descendantCounts: {
openedEpics: 1,
closedEpics: 1,
openedIssues: 2,
closedIssues: 1,
},
healthStatus: {
issuesOnTrack: 1,
issuesAtRisk: 0,
issuesNeedingAttention: 1,
},
};
// Epic meta data for having no open issues
export const mockEpicMeta2 = {
descendantCounts: {
openedEpics: 0,
closedEpics: 1,
openedIssues: 0,
closedIssues: 2,
},
healthStatus: {
issuesOnTrack: 0,
issuesAtRisk: 0,
issuesNeedingAttention: 0,
},
};
// Epic meta data for having no child issues
export const mockEpicMeta3 = {
descendantCounts: {
openedEpics: 0,
closedEpics: 1,
openedIssues: 0,
closedIssues: 0,
},
healthStatus: {
issuesOnTrack: 0,
issuesAtRisk: 0,
issuesNeedingAttention: 0,
},
};
export const mockIssue1 = { export const mockIssue1 = {
iid: '8', iid: '8',
epicIssueId: 'gid://gitlab/EpicIssue/3', epicIssueId: 'gid://gitlab/EpicIssue/3',
title: 'Nostrum cum mollitia quia recusandae fugit deleniti voluptatem delectus.', title: 'Nostrum cum mollitia quia recusandae fugit deleniti voluptatem delectus.',
closedAt: null, closedAt: null,
state: 'opened', state: ChildState.Open,
createdAt: '2019-02-18T14:06:41Z', createdAt: '2019-02-18T14:06:41Z',
confidential: true, confidential: true,
dueDate: '2019-06-14', dueDate: '2019-06-14',
...@@ -149,7 +195,7 @@ export const mockIssue2 = { ...@@ -149,7 +195,7 @@ export const mockIssue2 = {
epicIssueId: 'gid://gitlab/EpicIssue/4', epicIssueId: 'gid://gitlab/EpicIssue/4',
title: 'Dismiss Cipher with no integrity', title: 'Dismiss Cipher with no integrity',
closedAt: null, closedAt: null,
state: 'opened', state: ChildState.Open,
createdAt: '2019-02-18T14:13:05Z', createdAt: '2019-02-18T14:13:05Z',
confidential: false, confidential: false,
dueDate: null, dueDate: null,
...@@ -164,12 +210,12 @@ export const mockIssue2 = { ...@@ -164,12 +210,12 @@ export const mockIssue2 = {
healthStatus: 'needsAttention', healthStatus: 'needsAttention',
}; };
export const mockIssue3 = { export const mockClosedIssue = {
iid: '42', iid: '42',
epicIssueId: 'gid://gitlab/EpicIssue/5', epicIssueId: 'gid://gitlab/EpicIssue/5',
title: 'View closed issues in epic', title: 'View closed issues in epic',
closedAt: null, closedAt: null,
state: 'closed', state: ChildState.Closed,
createdAt: '2019-02-18T14:13:05Z', createdAt: '2019-02-18T14:13:05Z',
confidential: false, confidential: false,
dueDate: null, dueDate: null,
...@@ -186,7 +232,7 @@ export const mockIssue3 = { ...@@ -186,7 +232,7 @@ export const mockIssue3 = {
export const mockEpics = [mockEpic1, mockEpic2]; export const mockEpics = [mockEpic1, mockEpic2];
export const mockIssues = [mockIssue1, mockIssue2]; export const mockIssues = [mockIssue1, mockIssue2, mockClosedIssue];
export const mockQueryResponse = { export const mockQueryResponse = {
data: { data: {
...@@ -225,6 +271,9 @@ export const mockQueryResponse = { ...@@ -225,6 +271,9 @@ export const mockQueryResponse = {
{ {
node: mockIssue2, node: mockIssue2,
}, },
{
node: mockClosedIssue,
},
], ],
pageInfo: { pageInfo: {
endCursor: 'def', endCursor: 'def',
...@@ -233,9 +282,9 @@ export const mockQueryResponse = { ...@@ -233,9 +282,9 @@ export const mockQueryResponse = {
}, },
descendantCounts: mockParentItem.descendantCounts, descendantCounts: mockParentItem.descendantCounts,
healthStatus: { healthStatus: {
atRisk: 1, atRisk: 0,
needsAttention: 1, needsAttention: 1,
onTrack: 0, onTrack: 1,
}, },
}, },
}, },
...@@ -274,7 +323,7 @@ export const mockQueryResponse2 = { ...@@ -274,7 +323,7 @@ export const mockQueryResponse2 = {
issues: { issues: {
edges: [ edges: [
{ {
node: mockIssue3, node: mockClosedIssue,
}, },
{ {
node: mockIssue1, node: mockIssue1,
......
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