Commit 70b72322 authored by Brandon Labuschagne's avatar Brandon Labuschagne

Merge branch '322755-add-type-filtering-to-issues-refactor' into 'master'

Add issue type filtering to issues list refactor

See merge request gitlab-org/gitlab!67534
parents 8314833c 9ee41002
...@@ -35,6 +35,7 @@ import { ...@@ -35,6 +35,7 @@ import {
TOKEN_TYPE_LABEL, TOKEN_TYPE_LABEL,
TOKEN_TYPE_MILESTONE, TOKEN_TYPE_MILESTONE,
TOKEN_TYPE_MY_REACTION, TOKEN_TYPE_MY_REACTION,
TOKEN_TYPE_TYPE,
TOKEN_TYPE_WEIGHT, TOKEN_TYPE_WEIGHT,
UPDATED_DESC, UPDATED_DESC,
urlSortParams, urlSortParams,
...@@ -63,6 +64,7 @@ import { ...@@ -63,6 +64,7 @@ import {
TOKEN_TITLE_LABEL, TOKEN_TITLE_LABEL,
TOKEN_TITLE_MILESTONE, TOKEN_TITLE_MILESTONE,
TOKEN_TITLE_MY_REACTION, TOKEN_TITLE_MY_REACTION,
TOKEN_TITLE_TYPE,
TOKEN_TITLE_WEIGHT, TOKEN_TITLE_WEIGHT,
} from '~/vue_shared/components/filtered_search_bar/constants'; } from '~/vue_shared/components/filtered_search_bar/constants';
import AuthorToken from '~/vue_shared/components/filtered_search_bar/tokens/author_token.vue'; import AuthorToken from '~/vue_shared/components/filtered_search_bar/tokens/author_token.vue';
...@@ -317,6 +319,18 @@ export default { ...@@ -317,6 +319,18 @@ export default {
defaultLabels: DEFAULT_NONE_ANY, defaultLabels: DEFAULT_NONE_ANY,
fetchLabels: this.fetchLabels, fetchLabels: this.fetchLabels,
}, },
{
type: TOKEN_TYPE_TYPE,
title: TOKEN_TITLE_TYPE,
icon: 'issues',
token: GlFilteredSearchToken,
operators: OPERATOR_IS_ONLY,
options: [
{ icon: 'issue-type-issue', title: 'issue', value: 'issue' },
{ icon: 'issue-type-incident', title: 'incident', value: 'incident' },
{ icon: 'issue-type-test-case', title: 'test_case', value: 'test_case' },
],
},
]; ];
if (this.isSignedIn) { if (this.isSignedIn) {
......
...@@ -204,6 +204,7 @@ export const TOKEN_TYPE_AUTHOR = 'author_username'; ...@@ -204,6 +204,7 @@ export const TOKEN_TYPE_AUTHOR = 'author_username';
export const TOKEN_TYPE_ASSIGNEE = 'assignee_username'; export const TOKEN_TYPE_ASSIGNEE = 'assignee_username';
export const TOKEN_TYPE_MILESTONE = 'milestone'; export const TOKEN_TYPE_MILESTONE = 'milestone';
export const TOKEN_TYPE_LABEL = 'labels'; export const TOKEN_TYPE_LABEL = 'labels';
export const TOKEN_TYPE_TYPE = 'type';
export const TOKEN_TYPE_MY_REACTION = 'my_reaction_emoji'; export const TOKEN_TYPE_MY_REACTION = 'my_reaction_emoji';
export const TOKEN_TYPE_CONFIDENTIAL = 'confidential'; export const TOKEN_TYPE_CONFIDENTIAL = 'confidential';
export const TOKEN_TYPE_ITERATION = 'iteration'; export const TOKEN_TYPE_ITERATION = 'iteration';
...@@ -270,6 +271,18 @@ export const filters = { ...@@ -270,6 +271,18 @@ export const filters = {
}, },
}, },
}, },
[TOKEN_TYPE_TYPE]: {
[API_PARAM]: {
[NORMAL_FILTER]: 'types',
[SPECIAL_FILTER]: 'types',
},
[URL_PARAM]: {
[OPERATOR_IS]: {
[NORMAL_FILTER]: 'type[]',
[SPECIAL_FILTER]: 'type[]',
},
},
},
[TOKEN_TYPE_MY_REACTION]: { [TOKEN_TYPE_MY_REACTION]: {
[API_PARAM]: { [API_PARAM]: {
[NORMAL_FILTER]: 'myReactionEmoji', [NORMAL_FILTER]: 'myReactionEmoji',
......
...@@ -13,6 +13,7 @@ query getProjectIssues( ...@@ -13,6 +13,7 @@ query getProjectIssues(
$labelName: [String] $labelName: [String]
$milestoneTitle: [String] $milestoneTitle: [String]
$milestoneWildcardId: MilestoneWildcardId $milestoneWildcardId: MilestoneWildcardId
$types: [IssueType!]
$not: NegatedIssueFilterInput $not: NegatedIssueFilterInput
$beforeCursor: String $beforeCursor: String
$afterCursor: String $afterCursor: String
...@@ -30,6 +31,7 @@ query getProjectIssues( ...@@ -30,6 +31,7 @@ query getProjectIssues(
labelName: $labelName labelName: $labelName
milestoneTitle: $milestoneTitle milestoneTitle: $milestoneTitle
milestoneWildcardId: $milestoneWildcardId milestoneWildcardId: $milestoneWildcardId
types: $types
not: $not not: $not
before: $beforeCursor before: $beforeCursor
after: $afterCursor after: $afterCursor
......
...@@ -8,6 +8,7 @@ query getProjectIssuesCount( ...@@ -8,6 +8,7 @@ query getProjectIssuesCount(
$labelName: [String] $labelName: [String]
$milestoneTitle: [String] $milestoneTitle: [String]
$milestoneWildcardId: MilestoneWildcardId $milestoneWildcardId: MilestoneWildcardId
$types: [IssueType!]
$not: NegatedIssueFilterInput $not: NegatedIssueFilterInput
) { ) {
project(fullPath: $projectPath) { project(fullPath: $projectPath) {
...@@ -20,6 +21,7 @@ query getProjectIssuesCount( ...@@ -20,6 +21,7 @@ query getProjectIssuesCount(
labelName: $labelName labelName: $labelName
milestoneTitle: $milestoneTitle milestoneTitle: $milestoneTitle
milestoneWildcardId: $milestoneWildcardId milestoneWildcardId: $milestoneWildcardId
types: $types
not: $not not: $not
) { ) {
count count
......
...@@ -24,6 +24,7 @@ import { ...@@ -24,6 +24,7 @@ import {
TOKEN_TYPE_ASSIGNEE, TOKEN_TYPE_ASSIGNEE,
TOKEN_TYPE_ITERATION, TOKEN_TYPE_ITERATION,
TOKEN_TYPE_MILESTONE, TOKEN_TYPE_MILESTONE,
TOKEN_TYPE_TYPE,
UPDATED_ASC, UPDATED_ASC,
UPDATED_DESC, UPDATED_DESC,
URL_PARAM, URL_PARAM,
...@@ -192,10 +193,13 @@ const getFilterType = (data, tokenType = '') => ...@@ -192,10 +193,13 @@ const getFilterType = (data, tokenType = '') =>
? SPECIAL_FILTER ? SPECIAL_FILTER
: NORMAL_FILTER; : NORMAL_FILTER;
const requiresUpperCaseValue = (tokenType, value) => const isWildcardValue = (tokenType, value) =>
(tokenType === TOKEN_TYPE_ITERATION || tokenType === TOKEN_TYPE_MILESTONE) && (tokenType === TOKEN_TYPE_ITERATION || tokenType === TOKEN_TYPE_MILESTONE) &&
SPECIAL_FILTER_VALUES.includes(value); SPECIAL_FILTER_VALUES.includes(value);
const requiresUpperCaseValue = (tokenType, value) =>
tokenType === TOKEN_TYPE_TYPE || isWildcardValue(tokenType, value);
const formatData = (token) => const formatData = (token) =>
requiresUpperCaseValue(token.type, token.value.data) requiresUpperCaseValue(token.type, token.value.data)
? token.value.data.toUpperCase() ? token.value.data.toUpperCase()
......
...@@ -46,6 +46,7 @@ export const TOKEN_TITLE_AUTHOR = __('Author'); ...@@ -46,6 +46,7 @@ export const TOKEN_TITLE_AUTHOR = __('Author');
export const TOKEN_TITLE_ASSIGNEE = __('Assignee'); export const TOKEN_TITLE_ASSIGNEE = __('Assignee');
export const TOKEN_TITLE_MILESTONE = __('Milestone'); export const TOKEN_TITLE_MILESTONE = __('Milestone');
export const TOKEN_TITLE_LABEL = __('Label'); export const TOKEN_TITLE_LABEL = __('Label');
export const TOKEN_TITLE_TYPE = __('Type');
export const TOKEN_TITLE_MY_REACTION = __('My-Reaction'); export const TOKEN_TITLE_MY_REACTION = __('My-Reaction');
export const TOKEN_TITLE_CONFIDENTIAL = __('Confidential'); export const TOKEN_TITLE_CONFIDENTIAL = __('Confidential');
export const TOKEN_TITLE_ITERATION = __('Iteration'); export const TOKEN_TITLE_ITERATION = __('Iteration');
......
...@@ -13,6 +13,7 @@ query getProjectIssues( ...@@ -13,6 +13,7 @@ query getProjectIssues(
$labelName: [String] $labelName: [String]
$milestoneTitle: [String] $milestoneTitle: [String]
$milestoneWildcardId: MilestoneWildcardId $milestoneWildcardId: MilestoneWildcardId
$types: [IssueType!]
$epicId: String $epicId: String
$iterationId: [ID] $iterationId: [ID]
$iterationWildcardId: IterationWildcardId $iterationWildcardId: IterationWildcardId
...@@ -34,6 +35,7 @@ query getProjectIssues( ...@@ -34,6 +35,7 @@ query getProjectIssues(
labelName: $labelName labelName: $labelName
milestoneTitle: $milestoneTitle milestoneTitle: $milestoneTitle
milestoneWildcardId: $milestoneWildcardId milestoneWildcardId: $milestoneWildcardId
types: $types
epicId: $epicId epicId: $epicId
iterationId: $iterationId iterationId: $iterationId
iterationWildcardId: $iterationWildcardId iterationWildcardId: $iterationWildcardId
......
...@@ -8,6 +8,7 @@ query getProjectIssuesCount( ...@@ -8,6 +8,7 @@ query getProjectIssuesCount(
$labelName: [String] $labelName: [String]
$milestoneTitle: [String] $milestoneTitle: [String]
$milestoneWildcardId: MilestoneWildcardId $milestoneWildcardId: MilestoneWildcardId
$types: [IssueType!]
$epicId: String $epicId: String
$iterationId: [ID] $iterationId: [ID]
$iterationWildcardId: IterationWildcardId $iterationWildcardId: IterationWildcardId
...@@ -24,6 +25,7 @@ query getProjectIssuesCount( ...@@ -24,6 +25,7 @@ query getProjectIssuesCount(
labelName: $labelName labelName: $labelName
milestoneTitle: $milestoneTitle milestoneTitle: $milestoneTitle
milestoneWildcardId: $milestoneWildcardId milestoneWildcardId: $milestoneWildcardId
types: $types
epicId: $epicId epicId: $epicId
iterationId: $iterationId iterationId: $iterationId
iterationWildcardId: $iterationWildcardId iterationWildcardId: $iterationWildcardId
......
...@@ -36,6 +36,7 @@ import { ...@@ -36,6 +36,7 @@ import {
TOKEN_TYPE_LABEL, TOKEN_TYPE_LABEL,
TOKEN_TYPE_MILESTONE, TOKEN_TYPE_MILESTONE,
TOKEN_TYPE_MY_REACTION, TOKEN_TYPE_MY_REACTION,
TOKEN_TYPE_TYPE,
TOKEN_TYPE_WEIGHT, TOKEN_TYPE_WEIGHT,
urlSortParams, urlSortParams,
} from '~/issues_list/constants'; } from '~/issues_list/constants';
...@@ -557,6 +558,7 @@ describe('IssuesListApp component', () => { ...@@ -557,6 +558,7 @@ describe('IssuesListApp component', () => {
{ type: TOKEN_TYPE_ASSIGNEE, preloadedAuthors }, { type: TOKEN_TYPE_ASSIGNEE, preloadedAuthors },
{ type: TOKEN_TYPE_MILESTONE }, { type: TOKEN_TYPE_MILESTONE },
{ type: TOKEN_TYPE_LABEL }, { type: TOKEN_TYPE_LABEL },
{ type: TOKEN_TYPE_TYPE },
{ type: TOKEN_TYPE_MY_REACTION }, { type: TOKEN_TYPE_MY_REACTION },
{ type: TOKEN_TYPE_CONFIDENTIAL }, { type: TOKEN_TYPE_CONFIDENTIAL },
{ type: TOKEN_TYPE_ITERATION }, { type: TOKEN_TYPE_ITERATION },
......
...@@ -107,6 +107,8 @@ export const locationSearch = [ ...@@ -107,6 +107,8 @@ export const locationSearch = [
export const locationSearchWithSpecialValues = [ export const locationSearchWithSpecialValues = [
'assignee_id=123', 'assignee_id=123',
'assignee_username=bart', 'assignee_username=bart',
'type[]=issue',
'type[]=incident',
'my_reaction_emoji=None', 'my_reaction_emoji=None',
'iteration_id=Current', 'iteration_id=Current',
'milestone_title=Upcoming', 'milestone_title=Upcoming',
...@@ -142,6 +144,8 @@ export const filteredTokens = [ ...@@ -142,6 +144,8 @@ export const filteredTokens = [
export const filteredTokensWithSpecialValues = [ export const filteredTokensWithSpecialValues = [
{ type: 'assignee_username', value: { data: '123', operator: OPERATOR_IS } }, { type: 'assignee_username', value: { data: '123', operator: OPERATOR_IS } },
{ type: 'assignee_username', value: { data: 'bart', operator: OPERATOR_IS } }, { type: 'assignee_username', value: { data: 'bart', operator: OPERATOR_IS } },
{ type: 'type', value: { data: 'issue', operator: OPERATOR_IS } },
{ type: 'type', value: { data: 'incident', operator: OPERATOR_IS } },
{ type: 'my_reaction_emoji', value: { data: 'None', operator: OPERATOR_IS } }, { type: 'my_reaction_emoji', value: { data: 'None', operator: OPERATOR_IS } },
{ type: 'iteration', value: { data: 'Current', operator: OPERATOR_IS } }, { type: 'iteration', value: { data: 'Current', operator: OPERATOR_IS } },
{ type: 'milestone', value: { data: 'Upcoming', operator: OPERATOR_IS } }, { type: 'milestone', value: { data: 'Upcoming', operator: OPERATOR_IS } },
...@@ -173,6 +177,7 @@ export const apiParams = { ...@@ -173,6 +177,7 @@ export const apiParams = {
export const apiParamsWithSpecialValues = { export const apiParamsWithSpecialValues = {
assigneeId: '123', assigneeId: '123',
assigneeUsernames: 'bart', assigneeUsernames: 'bart',
types: ['ISSUE', 'INCIDENT'],
myReactionEmoji: 'None', myReactionEmoji: 'None',
iterationWildcardId: 'CURRENT', iterationWildcardId: 'CURRENT',
milestoneWildcardId: 'UPCOMING', milestoneWildcardId: 'UPCOMING',
...@@ -202,6 +207,7 @@ export const urlParams = { ...@@ -202,6 +207,7 @@ export const urlParams = {
export const urlParamsWithSpecialValues = { export const urlParamsWithSpecialValues = {
assignee_id: '123', assignee_id: '123',
'assignee_username[]': 'bart', 'assignee_username[]': 'bart',
'type[]': ['issue', 'incident'],
my_reaction_emoji: 'None', my_reaction_emoji: 'None',
iteration_id: 'Current', iteration_id: 'Current',
milestone_title: 'Upcoming', milestone_title: 'Upcoming',
......
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