Commit 9006f8ed authored by Jacques Erasmus's avatar Jacques Erasmus

Merge branch 'cngo-iteration-cadences' into 'master'

Group iterations by cadence on issue filter bar

See merge request gitlab-org/gitlab!72796
parents 599bda6d c8f28972
fragment Iteration on Iteration { fragment Iteration on Iteration {
id id
title title
iterationCadence {
id
title
}
} }
<script> <script>
import { GlFilteredSearchSuggestion } from '@gitlab/ui'; import { GlDropdownDivider, GlDropdownSectionHeader, GlFilteredSearchSuggestion } from '@gitlab/ui';
import createFlash from '~/flash'; import createFlash from '~/flash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { __ } from '~/locale'; import { __ } from '~/locale';
...@@ -9,6 +9,8 @@ import { DEFAULT_ITERATIONS } from '../constants'; ...@@ -9,6 +9,8 @@ import { DEFAULT_ITERATIONS } from '../constants';
export default { export default {
components: { components: {
BaseToken, BaseToken,
GlDropdownDivider,
GlDropdownSectionHeader,
GlFilteredSearchSuggestion, GlFilteredSearchSuggestion,
}, },
props: { props: {
...@@ -40,6 +42,23 @@ export default { ...@@ -40,6 +42,23 @@ export default {
getActiveIteration(iterations, data) { getActiveIteration(iterations, data) {
return iterations.find((iteration) => this.getValue(iteration) === data); return iterations.find((iteration) => this.getValue(iteration) === data);
}, },
groupIterationsByCadence(iterations) {
const cadences = [];
iterations.forEach((iteration) => {
if (!iteration.iterationCadence) {
return;
}
const { title } = iteration.iterationCadence;
const cadenceIteration = { id: iteration.id, title: iteration.title };
const cadence = cadences.find((cad) => cad.title === title);
if (cadence) {
cadence.iterations.push(cadenceIteration);
} else {
cadences.push({ title, iterations: [cadenceIteration] });
}
});
return cadences;
},
fetchIterations(searchTerm) { fetchIterations(searchTerm) {
this.loading = true; this.loading = true;
this.config this.config
...@@ -77,13 +96,23 @@ export default { ...@@ -77,13 +96,23 @@ export default {
{{ activeTokenValue ? activeTokenValue.title : inputValue }} {{ activeTokenValue ? activeTokenValue.title : inputValue }}
</template> </template>
<template #suggestions-list="{ suggestions }"> <template #suggestions-list="{ suggestions }">
<gl-filtered-search-suggestion <template v-for="(cadence, index) in groupIterationsByCadence(suggestions)">
v-for="iteration in suggestions" <gl-dropdown-divider v-if="index !== 0" :key="index" />
:key="iteration.id" <gl-dropdown-section-header
:value="getValue(iteration)" :key="cadence.title"
> class="gl-overflow-hidden"
{{ iteration.title }} :title="cadence.title"
</gl-filtered-search-suggestion> >
{{ cadence.title }}
</gl-dropdown-section-header>
<gl-filtered-search-suggestion
v-for="iteration in cadence.iterations"
:key="iteration.id"
:value="getValue(iteration)"
>
{{ iteration.title }}
</gl-filtered-search-suggestion>
</template>
</template> </template>
</base-token> </base-token>
</template> </template>
...@@ -8,8 +8,12 @@ RSpec.describe 'Filter issues by iteration', :js do ...@@ -8,8 +8,12 @@ RSpec.describe 'Filter issues by iteration', :js do
let_it_be(:group) { create(:group, :public) } let_it_be(:group) { create(:group, :public) }
let_it_be(:project) { create(:project, :public, group: group) } let_it_be(:project) { create(:project, :public, group: group) }
let_it_be(:iteration_1) { create(:iteration, group: group, start_date: Date.today) } let_it_be(:cadence_1) { create(:iterations_cadence, group: group) }
let_it_be(:iteration_2) { create(:iteration, group: group) } let_it_be(:cadence_2) { create(:iterations_cadence, group: group) }
let_it_be(:iteration_1) { create(:iteration, group: group, iterations_cadence: cadence_1, start_date: Date.today) }
let_it_be(:iteration_2) { create(:iteration, group: group, iterations_cadence: cadence_2) }
let_it_be(:iteration_3) { create(:iteration, group: group, iterations_cadence: cadence_1) }
let_it_be(:iteration_1_issue) { create(:issue, project: project, iteration: iteration_1) } let_it_be(:iteration_1_issue) { create(:issue, project: project, iteration: iteration_1) }
let_it_be(:iteration_2_issue) { create(:issue, project: project, iteration: iteration_2) } let_it_be(:iteration_2_issue) { create(:issue, project: project, iteration: iteration_2) }
...@@ -107,12 +111,40 @@ RSpec.describe 'Filter issues by iteration', :js do ...@@ -107,12 +111,40 @@ RSpec.describe 'Filter issues by iteration', :js do
end end
end end
shared_examples 'shows iterations when using iteration token' do
context 'when viewing list of iterations' do
before do
stub_feature_flags(vue_issues_list: true)
visit page_path
find_field('Search or filter results...').click
click_link 'Iteration'
click_link '= is'
end
it 'shows cadence titles and iteration titles', :aggregate_failures do
within '.gl-filtered-search-suggestion-list' do
# cadence 1 grouping
expect(page).to have_css('li:nth-child(5)', text: cadence_1.title)
expect(page).to have_css('li:nth-child(6)', text: iteration_1.title)
expect(page).to have_css('li:nth-child(7)', text: iteration_3.title)
# cadence 2 grouping
expect(page).to have_css('li:nth-child(9)', text: cadence_2.title)
expect(page).to have_css('li:nth-child(10)', text: iteration_2.title)
end
end
end
end
context 'project issues list' do context 'project issues list' do
let(:page_path) { project_issues_path(project) } let(:page_path) { project_issues_path(project) }
let(:issue_title_selector) { '.issue .title' } let(:issue_title_selector) { '.issue .title' }
it_behaves_like 'filters by iteration' it_behaves_like 'filters by iteration'
it_behaves_like 'shows iterations when using iteration token'
context 'when vue_issuables_list is disabled' do context 'when vue_issuables_list is disabled' do
before do before do
stub_feature_flags(vue_issuables_list: false) stub_feature_flags(vue_issuables_list: false)
...@@ -128,6 +160,8 @@ RSpec.describe 'Filter issues by iteration', :js do ...@@ -128,6 +160,8 @@ RSpec.describe 'Filter issues by iteration', :js do
it_behaves_like 'filters by iteration' it_behaves_like 'filters by iteration'
it_behaves_like 'shows iterations when using iteration token'
context 'when vue_issuables_list is disabled' do context 'when vue_issuables_list is disabled' do
before do before do
stub_feature_flags(vue_issuables_list: false) stub_feature_flags(vue_issuables_list: false)
......
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