Commit 5beb2e4c authored by Kushal Pandya's avatar Kushal Pandya

Merge branch 'count-weight' into 'master'

Add recursive weight to epic tree

See merge request gitlab-org/gitlab!60990
parents dc61d15f cc93dbef
...@@ -16,6 +16,10 @@ fragment RelatedTreeBaseEpic on Epic { ...@@ -16,6 +16,10 @@ fragment RelatedTreeBaseEpic on Epic {
adminEpic adminEpic
createEpic createEpic
} }
descendantWeightSum {
closedIssues
openedIssues
}
descendantCounts { descendantCounts {
__typename __typename
openedEpics openedEpics
......
...@@ -17,6 +17,7 @@ export default { ...@@ -17,6 +17,7 @@ export default {
computed: { computed: {
...mapState([ ...mapState([
'parentItem', 'parentItem',
'weightSum',
'descendantCounts', 'descendantCounts',
'healthStatus', 'healthStatus',
'allowSubEpics', 'allowSubEpics',
...@@ -31,6 +32,9 @@ export default { ...@@ -31,6 +32,9 @@ export default {
showHealthStatus() { showHealthStatus() {
return this.healthStatus && this.allowIssuableHealthStatus; return this.healthStatus && this.allowIssuableHealthStatus;
}, },
totalWeight() {
return this.weightSum.openedIssues + this.weightSum.closedIssues;
},
}, },
methods: { methods: {
...mapActions([ ...mapActions([
...@@ -72,7 +76,7 @@ export default { ...@@ -72,7 +76,7 @@ export default {
<gl-tooltip :target="() => $refs.countBadge"> <gl-tooltip :target="() => $refs.countBadge">
<p v-if="allowSubEpics" class="font-weight-bold m-0"> <p v-if="allowSubEpics" class="font-weight-bold m-0">
{{ __('Epics') }} &#8226; {{ __('Epics') }} &#8226;
<span class="text-secondary-400 font-weight-normal" <span class="font-weight-normal"
>{{ >{{
sprintf(__('%{openedEpics} open, %{closedEpics} closed'), { sprintf(__('%{openedEpics} open, %{closedEpics} closed'), {
openedEpics: descendantCounts.openedEpics, openedEpics: descendantCounts.openedEpics,
...@@ -83,7 +87,7 @@ export default { ...@@ -83,7 +87,7 @@ export default {
</p> </p>
<p class="font-weight-bold m-0"> <p class="font-weight-bold m-0">
{{ __('Issues') }} &#8226; {{ __('Issues') }} &#8226;
<span class="text-secondary-400 font-weight-normal" <span class="font-weight-normal"
>{{ >{{
sprintf(__('%{openedIssues} open, %{closedIssues} closed'), { sprintf(__('%{openedIssues} open, %{closedIssues} closed'), {
openedIssues: descendantCounts.openedIssues, openedIssues: descendantCounts.openedIssues,
...@@ -92,6 +96,10 @@ export default { ...@@ -92,6 +96,10 @@ export default {
}} }}
</span> </span>
</p> </p>
<p class="font-weight-bold m-0">
{{ __('Total weight') }} &#8226;
<span class="font-weight-normal">{{ totalWeight }} </span>
</p>
</gl-tooltip> </gl-tooltip>
<div <div
ref="countBadge" ref="countBadge"
...@@ -105,6 +113,10 @@ export default { ...@@ -105,6 +113,10 @@ export default {
<gl-icon name="issues" class="mr-1" /> <gl-icon name="issues" class="mr-1" />
{{ totalIssuesCount }} {{ totalIssuesCount }}
</span> </span>
<span class="d-inline-flex align-items-center" :class="{ 'ml-3': allowSubEpics }">
<gl-icon name="weight" class="mr-1" />
{{ totalWeight }}
</span>
</div> </div>
<epic-health-status v-if="showHealthStatus" :health-status="healthStatus" /> <epic-health-status v-if="showHealthStatus" :health-status="healthStatus" />
</div> </div>
......
...@@ -71,6 +71,7 @@ export const setItemChildrenFlags = ({ commit }, data) => ...@@ -71,6 +71,7 @@ export const setItemChildrenFlags = ({ commit }, data) =>
export const setEpicPageInfo = ({ commit }, data) => commit(types.SET_EPIC_PAGE_INFO, data); export const setEpicPageInfo = ({ commit }, data) => commit(types.SET_EPIC_PAGE_INFO, data);
export const setIssuePageInfo = ({ commit }, data) => commit(types.SET_ISSUE_PAGE_INFO, data); export const setIssuePageInfo = ({ commit }, data) => commit(types.SET_ISSUE_PAGE_INFO, data);
export const setWeightSum = ({ commit }, data) => commit(types.SET_WEIGHT_SUM, data);
export const requestItems = ({ commit }, data) => commit(types.REQUEST_ITEMS, data); export const requestItems = ({ commit }, data) => commit(types.REQUEST_ITEMS, data);
export const receiveItemsSuccess = ({ commit }, data) => commit(types.RECEIVE_ITEMS_SUCCESS, data); export const receiveItemsSuccess = ({ commit }, data) => commit(types.RECEIVE_ITEMS_SUCCESS, data);
...@@ -123,6 +124,8 @@ export const fetchItems = ({ dispatch }, { parentItem, isSubItem = false }) => { ...@@ -123,6 +124,8 @@ export const fetchItems = ({ dispatch }, { parentItem, isSubItem = false }) => {
pageInfo: data.group.epic.issues.pageInfo, pageInfo: data.group.epic.issues.pageInfo,
}); });
dispatch('setWeightSum', data.group.epic.descendantWeightSum);
if (!isSubItem) { if (!isSubItem) {
dispatch('setChildrenCount', data.group.epic.descendantCounts); dispatch('setChildrenCount', data.group.epic.descendantCounts);
dispatch('setHealthStatus', data.group.epic.healthStatus); dispatch('setHealthStatus', data.group.epic.healthStatus);
......
...@@ -8,6 +8,7 @@ export const SET_ITEM_CHILDREN_FLAGS = 'SET_ITEM_CHILDREN_FLAGS'; ...@@ -8,6 +8,7 @@ export const SET_ITEM_CHILDREN_FLAGS = 'SET_ITEM_CHILDREN_FLAGS';
export const SET_EPIC_PAGE_INFO = 'SET_EPIC_PAGE_INFO'; export const SET_EPIC_PAGE_INFO = 'SET_EPIC_PAGE_INFO';
export const SET_ISSUE_PAGE_INFO = 'SET_ISSUE_PAGE_INFO'; export const SET_ISSUE_PAGE_INFO = 'SET_ISSUE_PAGE_INFO';
export const SET_HEALTH_STATUS = 'SET_HEALTH_STATUS'; export const SET_HEALTH_STATUS = 'SET_HEALTH_STATUS';
export const SET_WEIGHT_SUM = 'SET_WEIGHT_SUM';
export const REQUEST_ITEMS = 'REQUEST_ITEMS'; export const REQUEST_ITEMS = 'REQUEST_ITEMS';
export const RECEIVE_ITEMS_SUCCESS = 'RECEIVE_ITEMS_SUCCESS'; export const RECEIVE_ITEMS_SUCCESS = 'RECEIVE_ITEMS_SUCCESS';
......
...@@ -73,6 +73,10 @@ export default { ...@@ -73,6 +73,10 @@ export default {
parentFlags.hasMoreIssues = pageInfo.hasNextPage; parentFlags.hasMoreIssues = pageInfo.hasNextPage;
}, },
[types.SET_WEIGHT_SUM](state, data) {
state.weightSum = data;
},
[types.REQUEST_ITEMS](state, { parentItem, isSubItem }) { [types.REQUEST_ITEMS](state, { parentItem, isSubItem }) {
if (isSubItem) { if (isSubItem) {
state.childrenFlags[parentItem.reference].itemChildrenFetchInProgress = true; state.childrenFlags[parentItem.reference].itemChildrenFetchInProgress = true;
......
...@@ -10,6 +10,10 @@ export default () => ({ ...@@ -10,6 +10,10 @@ export default () => ({
childrenFlags: {}, childrenFlags: {},
epicsCount: 0, epicsCount: 0,
issuesCount: 0, issuesCount: 0,
weightSum: {
openedIssues: 0,
closedIssues: 0,
},
descendantCounts: { descendantCounts: {
openedEpics: 0, openedEpics: 0,
closedEpics: 0, closedEpics: 0,
......
---
title: Add recursive weight to epic tree
merge_request: 60990
author:
type: added
...@@ -29,6 +29,10 @@ const createComponent = ({ slots } = {}) => { ...@@ -29,6 +29,10 @@ const createComponent = ({ slots } = {}) => {
isSubItem: false, isSubItem: false,
children, children,
}); });
store.dispatch('setWeightSum', {
openedIssues: 10,
closedIssues: 5,
});
store.dispatch('setChildrenCount', mockParentItem.descendantCounts); store.dispatch('setChildrenCount', mockParentItem.descendantCounts);
return shallowMount(RelatedItemsTreeHeader, { return shallowMount(RelatedItemsTreeHeader, {
...@@ -64,6 +68,16 @@ describe('RelatedItemsTree', () => { ...@@ -64,6 +68,16 @@ describe('RelatedItemsTree', () => {
}); });
}); });
describe('totalWeight', () => {
beforeEach(() => {
wrapper = createComponent();
});
it('total of openedIssues and closedIssues weight', () => {
expect(wrapper.vm.totalWeight).toBe(15);
});
});
describe('epic issue actions split button', () => { describe('epic issue actions split button', () => {
beforeEach(() => { beforeEach(() => {
wrapper = createComponent(); wrapper = createComponent();
...@@ -235,6 +249,15 @@ describe('RelatedItemsTree', () => { ...@@ -235,6 +249,15 @@ describe('RelatedItemsTree', () => {
expect(issueIcon.isVisible()).toBe(true); expect(issueIcon.isVisible()).toBe(true);
expect(issueIcon.props('name')).toBe('issues'); expect(issueIcon.props('name')).toBe('issues');
}); });
it('renders totalWeight count and gl-icon', () => {
const weightEl = wrapper.findAll('.issue-count-badge > span').at(2);
const weightIcon = weightEl.find(GlIcon);
expect(weightEl.text().trim()).toContain('15');
expect(weightIcon.isVisible()).toBe(true);
expect(weightIcon.props('name')).toBe('weight');
});
}); });
}); });
}); });
...@@ -284,6 +284,10 @@ export const mockQueryResponse = { ...@@ -284,6 +284,10 @@ export const mockQueryResponse = {
}, },
}, },
descendantCounts: mockParentItem.descendantCounts, descendantCounts: mockParentItem.descendantCounts,
descendantWeightSum: {
openedIssues: 10,
closedIssues: 5,
},
healthStatus: { healthStatus: {
atRisk: 0, atRisk: 0,
needsAttention: 1, needsAttention: 1,
......
...@@ -280,6 +280,24 @@ describe('RelatedItemTree', () => { ...@@ -280,6 +280,24 @@ describe('RelatedItemTree', () => {
}); });
}); });
describe('setWeightSum', () => {
it('set weightSum', () => {
const descendantWeightSum = mockQueryResponse.data.group.epic;
testAction(
actions.setWeightSum,
descendantWeightSum,
{},
[
{
type: types.SET_WEIGHT_SUM,
payload: descendantWeightSum,
},
],
[],
);
});
});
describe('requestItems', () => { describe('requestItems', () => {
it('should set `state.itemsFetchInProgress` to true', () => { it('should set `state.itemsFetchInProgress` to true', () => {
testAction( testAction(
...@@ -359,6 +377,7 @@ describe('RelatedItemTree', () => { ...@@ -359,6 +377,7 @@ describe('RelatedItemTree', () => {
children: { pageInfo: epicPageInfo }, children: { pageInfo: epicPageInfo },
issues: { pageInfo: issuesPageInfo }, issues: { pageInfo: issuesPageInfo },
descendantCounts: epicDescendantCounts, descendantCounts: epicDescendantCounts,
descendantWeightSum,
healthStatus, healthStatus,
} = mockQueryResponse.data.group.epic; } = mockQueryResponse.data.group.epic;
...@@ -409,6 +428,10 @@ describe('RelatedItemTree', () => { ...@@ -409,6 +428,10 @@ describe('RelatedItemTree', () => {
pageInfo: issuesPageInfo, pageInfo: issuesPageInfo,
}, },
}, },
{
type: 'setWeightSum',
payload: descendantWeightSum,
},
{ {
type: 'setChildrenCount', type: 'setChildrenCount',
payload: { payload: {
......
...@@ -35,6 +35,10 @@ describe('RelatedItemsTree', () => { ...@@ -35,6 +35,10 @@ describe('RelatedItemsTree', () => {
issuesAtRisk: 0, issuesAtRisk: 0,
issuesOnTrack: 0, issuesOnTrack: 0,
}); });
expect(state).toHaveProperty('weightSum', {
openedIssues: 0,
closedIssues: 0,
});
}); });
}); });
...@@ -700,6 +704,15 @@ describe('RelatedItemsTree', () => { ...@@ -700,6 +704,15 @@ describe('RelatedItemsTree', () => {
expect(state.projectsFetchInProgress).toBe(false); expect(state.projectsFetchInProgress).toBe(false);
}); });
}); });
describe(types.SET_WEIGHT_SUM, () => {
it('should set `weightSum` within state', () => {
const payload = { openedIssues: 10, closedIssues: 5 };
mutations[types.SET_WEIGHT_SUM](state, payload);
expect(state.weightSum).toBe(payload);
});
});
}); });
}); });
}); });
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