Commit 7583b286 authored by Coung Ngo's avatar Coung Ngo Committed by Jose Ivan Vargas

Make iteration cadence code DRY

parent 99594281
......@@ -12,3 +12,31 @@ export function getIterationPeriod({ startDate, dueDate }) {
const due = formatDate(dueDate, PERIOD_DATE_FORMAT, true);
return `${start} - ${due}`;
}
/**
* Group a list of iterations by cadence.
*
* @param iterations A list of iterations
* @return {Array} A list of cadences
*/
export function groupByIterationCadences(iterations) {
const cadences = [];
iterations.forEach((iteration) => {
if (!iteration.iterationCadence) {
return;
}
const { title } = iteration.iterationCadence;
const cadenceIteration = {
id: iteration.id,
title: iteration.title,
period: getIterationPeriod(iteration),
};
const cadence = cadences.find((c) => c.title === title);
if (cadence) {
cadence.iterations.push(cadenceIteration);
} else {
cadences.push({ title, iterations: [cadenceIteration] });
}
});
return cadences;
}
......@@ -8,10 +8,10 @@ import {
GlTooltipDirective,
GlLoadingIcon,
} from '@gitlab/ui';
import IterationPeriod from 'ee/iterations/components/iteration_period.vue';
import { groupByIterationCadences } from 'ee/iterations/utils';
import { __ } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import IterationPeriod from 'ee/iterations/components/iteration_period.vue';
import { getIterationPeriod } from 'ee/iterations/utils';
import { iterationSelectTextMap, iterationDisplayState } from '../constants';
import groupIterationsQuery from '../queries/iterations.query.graphql';
......@@ -70,25 +70,7 @@ export default {
return this.currentIteration?.iterationCadence?.title;
},
iterationCadences() {
const cadences = [];
this.iterations.forEach((iteration) => {
if (!iteration.iterationCadence) {
return;
}
const { title } = iteration.iterationCadence;
const cadenceIteration = {
id: iteration.id,
title: iteration.title,
period: getIterationPeriod(iteration),
};
const cadence = cadences.find((cad) => cad.title === title);
if (cadence) {
cadence.iterations.push(cadenceIteration);
} else {
cadences.push({ title, iterations: [cadenceIteration] });
}
});
return cadences;
return groupByIterationCadences(this.iterations);
},
title() {
return this.currentIteration?.title || __('Select iteration');
......
......@@ -8,8 +8,8 @@ import {
} from '@gitlab/ui';
import SidebarDropdownWidget from 'ee/sidebar/components/sidebar_dropdown_widget.vue';
import IterationPeriod from 'ee/iterations/components/iteration_period.vue';
import { getIterationPeriod, groupByIterationCadences } from 'ee/iterations/utils';
import { IssuableType } from '~/issue_show/constants';
import { getIterationPeriod } from 'ee/iterations/utils';
import { IssuableAttributeType } from '../constants';
export default {
......@@ -51,26 +51,8 @@ export default {
getIterationPeriod(iteration) {
return getIterationPeriod({ startDate: iteration?.startDate, dueDate: iteration?.dueDate });
},
getIterationCadences(iterations) {
const cadences = [];
iterations.forEach((iteration) => {
if (!iteration.iterationCadence) {
return;
}
const { title } = iteration.iterationCadence;
const cadenceIteration = {
id: iteration.id,
title: iteration.title,
period: this.getIterationPeriod(iteration),
};
const cadence = cadences.find((cad) => cad.title === title);
if (cadence) {
cadence.iterations.push(cadenceIteration);
} else {
cadences.push({ title, iterations: [cadenceIteration] });
}
});
return cadences;
groupByIterationCadences(iterations) {
return groupByIterationCadences(iterations);
},
},
};
......@@ -101,7 +83,7 @@ export default {
</gl-link>
</template>
<template #list="{ attributesList = [], isAttributeChecked, updateAttribute }">
<template v-for="(cadence, index) in getIterationCadences(attributesList)">
<template v-for="(cadence, index) in groupByIterationCadences(attributesList)">
<gl-dropdown-divider v-if="index !== 0" :key="index" />
<gl-dropdown-section-header :key="cadence.title">
{{ cadence.title }}
......
<script>
import { GlDropdownDivider, GlDropdownSectionHeader, GlFilteredSearchSuggestion } from '@gitlab/ui';
import { groupByIterationCadences } from 'ee/iterations/utils';
import createFlash from '~/flash';
import { __ } from '~/locale';
import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
import { formatDate } from '~/lib/utils/datetime_utility';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { DEFAULT_ITERATIONS } from '../constants';
......@@ -45,25 +45,7 @@ export default {
return iterations.find((iteration) => iteration.id === data);
},
groupIterationsByCadence(iterations) {
const cadences = [];
iterations.forEach((iteration) => {
if (!iteration.iterationCadence) {
return;
}
const { title } = iteration.iterationCadence;
const cadenceIteration = {
id: iteration.id,
title: iteration.title,
period: this.getIterationPeriod(iteration),
};
const cadence = cadences.find((cad) => cad.title === title);
if (cadence) {
cadence.iterations.push(cadenceIteration);
} else {
cadences.push({ title, iterations: [cadenceIteration] });
}
});
return cadences;
return groupByIterationCadences(iterations);
},
fetchIterations(searchTerm) {
this.loading = true;
......@@ -79,16 +61,6 @@ export default {
this.loading = false;
});
},
/**
* TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/344619
* This method also exists as a utility function in ee/../iterations/utils.js
* Remove the duplication when iteration token is moved to EE.
*/
getIterationPeriod({ startDate, dueDate }) {
const start = formatDate(startDate, 'mmm d, yyyy', true);
const due = formatDate(dueDate, 'mmm d, yyyy', true);
return `${start} - ${due}`;
},
},
};
</script>
......
......@@ -111,3 +111,57 @@ export const readCadenceSuccess = {
},
},
};
export const mockIterationsWithoutCadences = [
{
id: 1,
title: 'iteration 1',
startDate: '2021-11-23T12:34:56',
dueDate: '2021-11-30T12:34:56',
},
{
id: 2,
title: 'iteration 2',
startDate: '2021-11-23T12:34:56',
dueDate: '2021-11-30T12:34:56',
},
];
export const mockIterationsWithCadences = [
{
id: 1,
title: 'iteration 1',
startDate: '2021-11-23T12:34:56',
dueDate: '2021-11-30T12:34:56',
iterationCadence: {
title: 'cadence 1',
},
},
{
id: 2,
title: 'iteration 2',
startDate: '2021-11-23T12:34:56',
dueDate: '2021-11-30T12:34:56',
iterationCadence: {
title: 'cadence 2',
},
},
{
id: 3,
title: 'iteration 3',
startDate: '2021-11-23T12:34:56',
dueDate: '2021-11-30T12:34:56',
iterationCadence: {
title: 'cadence 2',
},
},
{
id: 4,
title: 'iteration 4',
startDate: '2021-11-23T12:34:56',
dueDate: '2021-11-30T12:34:56',
iterationCadence: {
title: 'cadence 1',
},
},
];
import { getIterationPeriod, groupByIterationCadences } from 'ee/iterations/utils';
import {
mockIterationNode,
mockIterationsWithCadences,
mockIterationsWithoutCadences,
} from './mock_data';
describe('getIterationPeriod', () => {
it('returns time period given an iteration', () => {
expect(getIterationPeriod(mockIterationNode)).toBe('Feb 10, 2021 - Feb 17, 2021');
});
});
describe('groupByIterationCadences', () => {
const period = 'Nov 23, 2021 - Nov 30, 2021';
const expected = [
{
title: 'cadence 1',
iterations: [
{ id: 1, title: 'iteration 1', period },
{ id: 4, title: 'iteration 4', period },
],
},
{
title: 'cadence 2',
iterations: [
{ id: 2, title: 'iteration 2', period },
{ id: 3, title: 'iteration 3', period },
],
},
];
it('groups iterations by cadence', () => {
expect(groupByIterationCadences(mockIterationsWithCadences)).toStrictEqual(expected);
});
it('returns empty array when iterations do not have cadences', () => {
expect(groupByIterationCadences(mockIterationsWithoutCadences)).toEqual([]);
});
it('returns empty array when passed an empty array', () => {
expect(groupByIterationCadences([])).toEqual([]);
});
});
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