Commit dffaa093 authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Merge branch 'psi-board-cadences' into 'master'

Group iterations by cadence on board add list form

See merge request gitlab-org/gitlab!71623
parents 160cb9ba 97150de3
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
import { import {
GlAvatar, GlAvatar,
GlAvatarLabeled, GlAvatarLabeled,
GlDropdownDivider,
GlDropdownSectionHeader,
GlDropdownText,
GlIcon, GlIcon,
GlFormGroup, GlFormGroup,
GlFormRadio, GlFormRadio,
...@@ -14,7 +17,7 @@ import { ListType } from '~/boards/constants'; ...@@ -14,7 +17,7 @@ import { ListType } from '~/boards/constants';
import { isScopedLabel } from '~/lib/utils/common_utils'; import { isScopedLabel } from '~/lib/utils/common_utils';
import { __ } from '~/locale'; import { __ } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { getIterationPeriod } from 'ee/iterations/utils'; import { groupByIterationCadences } from 'ee/iterations/utils';
import IterationPeriod from 'ee/iterations/components/iteration_period.vue'; import IterationPeriod from 'ee/iterations/components/iteration_period.vue';
export const listTypeInfo = { export const listTypeInfo = {
...@@ -56,6 +59,9 @@ export default { ...@@ -56,6 +59,9 @@ export default {
BoardAddNewColumnForm, BoardAddNewColumnForm,
GlAvatar, GlAvatar,
GlAvatarLabeled, GlAvatarLabeled,
GlDropdownDivider,
GlDropdownSectionHeader,
GlDropdownText,
GlIcon, GlIcon,
GlFormGroup, GlFormGroup,
GlFormRadio, GlFormRadio,
...@@ -96,6 +102,10 @@ export default { ...@@ -96,6 +102,10 @@ export default {
return listTypeInfo[this.columnType] || {}; return listTypeInfo[this.columnType] || {};
}, },
iterationCadences() {
return groupByIterationCadences(this.items);
},
items() { items() {
return this[this.info.listPropertyName] || []; return this[this.info.listPropertyName] || [];
}, },
...@@ -130,6 +140,10 @@ export default { ...@@ -130,6 +140,10 @@ export default {
return this.assigneeTypeSelected && this.selectedItem; return this.assigneeTypeSelected && this.selectedItem;
}, },
shouldShowIterationCadence() {
return this.glFeatures.iterationCadences && this.iterationTypeSelected;
},
columnForSelected() { columnForSelected() {
if (!this.columnType || !this.selectedId) { if (!this.columnType || !this.selectedId) {
return false; return false;
...@@ -226,7 +240,6 @@ export default { ...@@ -226,7 +240,6 @@ export default {
this.selectedItem = { ...item }; this.selectedItem = { ...item };
} }
}, },
getIterationPeriod,
}, },
}; };
</script> </script>
...@@ -294,6 +307,32 @@ export default { ...@@ -294,6 +307,32 @@ export default {
<template v-if="hasItems" #items> <template v-if="hasItems" #items>
<gl-form-radio-group <gl-form-radio-group
v-if="shouldShowIterationCadence"
class="gl-overflow-hidden"
data-testid="selectItem"
@change="setSelectedItem"
>
<div v-for="(cadence, index) in iterationCadences" :key="cadence.id">
<gl-dropdown-divider v-if="index !== 0" :key="index" />
<gl-dropdown-section-header :id="cadence.id">
<div data-testid="cadence" class="gl-text-truncate">
{{ cadence.title }}
</div>
</gl-dropdown-section-header>
<gl-dropdown-text v-for="iteration in cadence.iterations" :key="iteration.id">
<gl-form-radio :value="iteration.id" :aria-describedby="cadence.id">
{{ iteration.title }}
<div class="gl-display-inline-block">
<IterationPeriod data-testid="new-column-iteration-period">{{
iteration.period
}}</IterationPeriod>
</div>
</gl-form-radio>
</gl-dropdown-text>
</div>
</gl-form-radio-group>
<gl-form-radio-group
v-else
class="gl-overflow-y-auto gl-px-5" class="gl-overflow-y-auto gl-px-5"
:checked="selectedId" :checked="selectedId"
data-testid="selectItem" data-testid="selectItem"
...@@ -326,11 +365,6 @@ export default { ...@@ -326,11 +365,6 @@ export default {
/> />
<div v-else class="gl-display-inline-block"> <div v-else class="gl-display-inline-block">
{{ item.title }} {{ item.title }}
<IterationPeriod
v-if="iterationTypeSelected && glFeatures.iterationCadences"
data-testid="new-column-iteration-period"
>{{ getIterationPeriod(item) }}</IterationPeriod
>
</div> </div>
</label> </label>
</gl-form-radio-group> </gl-form-radio-group>
......
...@@ -249,9 +249,17 @@ describe('BoardAddNewColumn', () => { ...@@ -249,9 +249,17 @@ describe('BoardAddNewColumn', () => {
expect(findIterationPeriod(labels.at(1)).exists()).toBe(false); expect(findIterationPeriod(labels.at(1)).exists()).toBe(false);
}); });
}); });
});
describe('iteration_cadences feature flag is on', () => { describe('iteration_cadences feature flag is on', () => {
it('displays iteration period', async () => { const iterationMountOptions = {
iterations: mockIterations,
actions: {
fetchIterations: jest.fn(),
},
};
beforeEach(async () => {
mountComponent({ mountComponent({
...iterationMountOptions, ...iterationMountOptions,
glFeatures: { glFeatures: {
...@@ -260,13 +268,24 @@ describe('BoardAddNewColumn', () => { ...@@ -260,13 +268,24 @@ describe('BoardAddNewColumn', () => {
}); });
await selectIteration(); await selectIteration();
});
const labels = findLabels(); it('finds a cadence in the dropdown', () => {
expect(labels.at(0).text()).toContain('Oct 5, 2021 - Oct 10, 2021'); const { iterations } = iterationMountOptions;
expect(findIterationPeriod(labels.at(0)).isVisible()).toBe(true); const getCadenceTitleFromMocks = (idx) => iterations[idx].iterationCadence.title;
expect(labels.at(1).text()).toContain('Oct 12, 2021 - Oct 17, 2021'); const cadenceTitles = wrapper
expect(findIterationPeriod(labels.at(1)).isVisible()).toBe(true); .findAll('[data-testid="cadence"]')
.wrappers.map((x) => x.text());
expect(cadenceTitles).toEqual(cadenceTitles.map((_, idx) => getCadenceTitleFromMocks(idx)));
}); });
it('displays iteration period', async () => {
const iterations = wrapper.findAllByTestId('new-column-iteration-period');
expect(iterations.at(0).text()).toContain('Oct 5, 2021 - Oct 10, 2021');
expect(findIterationPeriod(iterations.at(0)).isVisible()).toBe(true);
expect(iterations.at(1).text()).toContain('Oct 12, 2021 - Oct 17, 2021');
expect(findIterationPeriod(iterations.at(1)).isVisible()).toBe(true);
}); });
}); });
}); });
...@@ -122,12 +122,20 @@ export const mockIterations = [ ...@@ -122,12 +122,20 @@ export const mockIterations = [
{ {
id: 'gid://gitlab/Iteration/1', id: 'gid://gitlab/Iteration/1',
title: 'Iteration 1', title: 'Iteration 1',
iterationCadence: {
id: 'gid://gitlab/Iterations::Cadence/1',
title: 'GitLab.org Iterations',
},
startDate: '2021-10-05', startDate: '2021-10-05',
dueDate: '2021-10-10', dueDate: '2021-10-10',
}, },
{ {
id: 'gid://gitlab/Iteration/2', id: 'gid://gitlab/Iteration/2',
title: 'Iteration 2', title: 'Iteration 2',
iterationCadence: {
id: 'gid://gitlab/Iterations::Cadence/2',
title: 'GitLab.org Iterations: Volume II',
},
startDate: '2021-10-12', startDate: '2021-10-12',
dueDate: '2021-10-17', dueDate: '2021-10-17',
}, },
......
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