Commit 64f31cb5 authored by Jose Ivan Vargas's avatar Jose Ivan Vargas

Merge branch 'ss/add-issue-type-token-to-issue-boards' into 'master'

Add issue type filtering to issue boards (behind ff) [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!67194
parents b171057d 5df53356
...@@ -204,6 +204,9 @@ export const FiltersInfo = { ...@@ -204,6 +204,9 @@ export const FiltersInfo = {
releaseTag: { releaseTag: {
negatedSupport: true, negatedSupport: true,
}, },
types: {
negatedSupport: true,
},
search: { search: {
negatedSupport: false, negatedSupport: false,
}, },
......
...@@ -33,6 +33,7 @@ export default { ...@@ -33,6 +33,7 @@ export default {
assigneeUsername, assigneeUsername,
search, search,
milestoneTitle, milestoneTitle,
types,
} = this.filterParams; } = this.filterParams;
let notParams = {}; let notParams = {};
...@@ -42,6 +43,7 @@ export default { ...@@ -42,6 +43,7 @@ export default {
'not[label_name][]': this.filterParams.not.labelName, 'not[label_name][]': this.filterParams.not.labelName,
'not[author_username]': this.filterParams.not.authorUsername, 'not[author_username]': this.filterParams.not.authorUsername,
'not[assignee_username]': this.filterParams.not.assigneeUsername, 'not[assignee_username]': this.filterParams.not.assigneeUsername,
'not[types]': this.filterParams.not.types,
'not[milestone_title]': this.filterParams.not.milestoneTitle, 'not[milestone_title]': this.filterParams.not.milestoneTitle,
}, },
undefined, undefined,
...@@ -55,6 +57,7 @@ export default { ...@@ -55,6 +57,7 @@ export default {
assignee_username: assigneeUsername, assignee_username: assigneeUsername,
milestone_title: milestoneTitle, milestone_title: milestoneTitle,
search, search,
types,
}; };
}, },
}, },
...@@ -78,6 +81,7 @@ export default { ...@@ -78,6 +81,7 @@ export default {
assigneeUsername, assigneeUsername,
search, search,
milestoneTitle, milestoneTitle,
types,
} = this.filterParams; } = this.filterParams;
const filteredSearchValue = []; const filteredSearchValue = [];
...@@ -95,6 +99,13 @@ export default { ...@@ -95,6 +99,13 @@ export default {
}); });
} }
if (types) {
filteredSearchValue.push({
type: 'types',
value: { data: types, operator: '=' },
});
}
if (labelName?.length) { if (labelName?.length) {
filteredSearchValue.push( filteredSearchValue.push(
...labelName.map((label) => ({ ...labelName.map((label) => ({
...@@ -141,6 +152,13 @@ export default { ...@@ -141,6 +152,13 @@ export default {
); );
} }
if (this.filterParams['not[types]']) {
filteredSearchValue.push({
type: 'types',
value: { data: this.filterParams['not[types]'], operator: '!=' },
});
}
if (search) { if (search) {
filteredSearchValue.push(search); filteredSearchValue.push(search);
} }
...@@ -168,6 +186,9 @@ export default { ...@@ -168,6 +186,9 @@ export default {
case 'assignee_username': case 'assignee_username':
filterParams.assigneeUsername = filter.value.data; filterParams.assigneeUsername = filter.value.data;
break; break;
case 'types':
filterParams.types = filter.value.data;
break;
case 'label_name': case 'label_name':
labels.push(filter.value.data); labels.push(filter.value.data);
break; break;
......
<script> <script>
import { GlFilteredSearchToken } from '@gitlab/ui';
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
import BoardFilteredSearch from '~/boards/components/board_filtered_search.vue'; import BoardFilteredSearch from '~/boards/components/board_filtered_search.vue';
import issueBoardFilters from '~/boards/issue_board_filters'; import issueBoardFilters from '~/boards/issue_board_filters';
...@@ -10,11 +11,18 @@ import LabelToken from '~/vue_shared/components/filtered_search_bar/tokens/label ...@@ -10,11 +11,18 @@ import LabelToken from '~/vue_shared/components/filtered_search_bar/tokens/label
import MilestoneToken from '~/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue'; import MilestoneToken from '~/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue';
export default { export default {
types: {
ISSUE: 'ISSUE',
INCIDENT: 'INCIDENT',
},
i18n: { i18n: {
search: __('Search'), search: __('Search'),
label: __('Label'), label: __('Label'),
author: __('Author'), author: __('Author'),
assignee: __('Assignee'), assignee: __('Assignee'),
type: __('Type'),
incident: __('Incident'),
issue: __('Issue'),
milestone: __('Milestone'), milestone: __('Milestone'),
is: __('is'), is: __('is'),
isNot: __('is not'), isNot: __('is not'),
...@@ -32,7 +40,18 @@ export default { ...@@ -32,7 +40,18 @@ export default {
}, },
computed: { computed: {
tokens() { tokens() {
const { label, is, isNot, author, assignee, milestone } = this.$options.i18n; const {
label,
is,
isNot,
author,
assignee,
issue,
incident,
type,
milestone,
} = this.$options.i18n;
const { types } = this.$options;
const { fetchAuthors, fetchLabels } = issueBoardFilters( const { fetchAuthors, fetchLabels } = issueBoardFilters(
this.$apollo, this.$apollo,
this.fullPath, this.fullPath,
...@@ -80,6 +99,18 @@ export default { ...@@ -80,6 +99,18 @@ export default {
fetchAuthors, fetchAuthors,
preloadedAuthors: this.preloadedAuthors(), preloadedAuthors: this.preloadedAuthors(),
}, },
{
icon: 'issues',
title: type,
type: 'types',
operators: [{ value: '=', description: is }],
token: GlFilteredSearchToken,
unique: true,
options: [
{ icon: 'issue-type-issue', value: types.ISSUE, title: issue },
{ icon: 'issue-type-incident', value: types.INCIDENT, title: incident },
],
},
{ {
type: 'milestone_title', type: 'milestone_title',
title: milestone, title: milestone,
......
...@@ -109,6 +109,7 @@ export const FilterFields = { ...@@ -109,6 +109,7 @@ export const FilterFields = {
'myReactionEmoji', 'myReactionEmoji',
'releaseTag', 'releaseTag',
'search', 'search',
'types',
], ],
}; };
......
...@@ -116,6 +116,7 @@ describe('BoardFilteredSearch', () => { ...@@ -116,6 +116,7 @@ describe('BoardFilteredSearch', () => {
{ type: 'label_name', value: { data: 'label', operator: '=' } }, { type: 'label_name', value: { data: 'label', operator: '=' } },
{ type: 'label_name', value: { data: 'label2', operator: '=' } }, { type: 'label_name', value: { data: 'label2', operator: '=' } },
{ type: 'milestone_title', value: { data: 'New Milestone', operator: '=' } }, { type: 'milestone_title', value: { data: 'New Milestone', operator: '=' } },
{ type: 'types', value: { data: 'INCIDENT', operator: '=' } },
]; ];
jest.spyOn(urlUtility, 'updateHistory'); jest.spyOn(urlUtility, 'updateHistory');
findFilteredSearch().vm.$emit('onFilter', mockFilters); findFilteredSearch().vm.$emit('onFilter', mockFilters);
...@@ -124,7 +125,7 @@ describe('BoardFilteredSearch', () => { ...@@ -124,7 +125,7 @@ describe('BoardFilteredSearch', () => {
title: '', title: '',
replace: true, replace: true,
url: url:
'http://test.host/?author_username=root&label_name[]=label&label_name[]=label2&milestone_title=New+Milestone', 'http://test.host/?author_username=root&label_name[]=label&label_name[]=label2&milestone_title=New+Milestone&types=INCIDENT',
}); });
}); });
}); });
......
/* global List */ /* global List */
import { GlFilteredSearchToken } from '@gitlab/ui';
import { keyBy } from 'lodash'; import { keyBy } from 'lodash';
import Vue from 'vue'; import Vue from 'vue';
import '~/boards/models/list'; import '~/boards/models/list';
...@@ -584,6 +585,18 @@ export const mockTokens = (fetchLabels, fetchAuthors, fetchMilestones) => [ ...@@ -584,6 +585,18 @@ export const mockTokens = (fetchLabels, fetchAuthors, fetchMilestones) => [
fetchAuthors, fetchAuthors,
preloadedAuthors: [], preloadedAuthors: [],
}, },
{
icon: 'issues',
title: __('Type'),
type: 'types',
operators: [{ value: '=', description: 'is' }],
token: GlFilteredSearchToken,
unique: true,
options: [
{ icon: 'issue-type-issue', value: 'ISSUE', title: 'Issue' },
{ icon: 'issue-type-incident', value: 'INCIDENT', title: 'Incident' },
],
},
{ {
icon: 'clock', icon: 'clock',
title: __('Milestone'), title: __('Milestone'),
......
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