Commit 317c3a6e authored by Andrew Fontaine's avatar Andrew Fontaine Committed by GitLab Release Tools Bot

Fix assignee filtering on group/project issues list

See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87164

Changelog: fixed
parent ee335705
...@@ -56,6 +56,7 @@ export const ISSUE_REFERENCE = /^#\d+$/; ...@@ -56,6 +56,7 @@ export const ISSUE_REFERENCE = /^#\d+$/;
export const MAX_LIST_SIZE = 10; export const MAX_LIST_SIZE = 10;
export const PAGE_SIZE = 20; export const PAGE_SIZE = 20;
export const PAGE_SIZE_MANUAL = 100; export const PAGE_SIZE_MANUAL = 100;
export const PARAM_ASSIGNEE_ID = 'assignee_id';
export const PARAM_PAGE_AFTER = 'page_after'; export const PARAM_PAGE_AFTER = 'page_after';
export const PARAM_PAGE_BEFORE = 'page_before'; export const PARAM_PAGE_BEFORE = 'page_before';
export const PARAM_STATE = 'state'; export const PARAM_STATE = 'state';
...@@ -112,7 +113,8 @@ export const URL_PARAM = 'urlParam'; ...@@ -112,7 +113,8 @@ export const URL_PARAM = 'urlParam';
export const NORMAL_FILTER = 'normalFilter'; export const NORMAL_FILTER = 'normalFilter';
export const SPECIAL_FILTER = 'specialFilter'; export const SPECIAL_FILTER = 'specialFilter';
export const ALTERNATIVE_FILTER = 'alternativeFilter'; export const ALTERNATIVE_FILTER = 'alternativeFilter';
export const SPECIAL_FILTER_VALUES = [
export const specialFilterValues = [
FILTER_NONE, FILTER_NONE,
FILTER_ANY, FILTER_ANY,
FILTER_CURRENT, FILTER_CURRENT,
......
import { isPositiveInteger } from '~/lib/utils/number_utils'; import { isPositiveInteger } from '~/lib/utils/number_utils';
import { getParameterByName } from '~/lib/utils/url_utility';
import { __ } from '~/locale'; import { __ } from '~/locale';
import { import {
FILTERED_SEARCH_TERM, FILTERED_SEARCH_TERM,
...@@ -20,13 +21,14 @@ import { ...@@ -20,13 +21,14 @@ import {
NORMAL_FILTER, NORMAL_FILTER,
PAGE_SIZE, PAGE_SIZE,
PAGE_SIZE_MANUAL, PAGE_SIZE_MANUAL,
PARAM_ASSIGNEE_ID,
POPULARITY_ASC, POPULARITY_ASC,
POPULARITY_DESC, POPULARITY_DESC,
PRIORITY_ASC, PRIORITY_ASC,
PRIORITY_DESC, PRIORITY_DESC,
RELATIVE_POSITION_ASC, RELATIVE_POSITION_ASC,
SPECIAL_FILTER, SPECIAL_FILTER,
SPECIAL_FILTER_VALUES, specialFilterValues,
TITLE_ASC, TITLE_ASC,
TITLE_DESC, TITLE_DESC,
TOKEN_TYPE_ASSIGNEE, TOKEN_TYPE_ASSIGNEE,
...@@ -202,16 +204,19 @@ export const getFilterTokens = (locationSearch) => { ...@@ -202,16 +204,19 @@ export const getFilterTokens = (locationSearch) => {
return filterTokens.concat(searchTokens); return filterTokens.concat(searchTokens);
}; };
const getFilterType = (data, tokenType = '') => const getFilterType = (data, tokenType = '') => {
SPECIAL_FILTER_VALUES.includes(data) || const isAssigneeIdParam =
(tokenType === TOKEN_TYPE_ASSIGNEE && isPositiveInteger(data)) tokenType === TOKEN_TYPE_ASSIGNEE &&
? SPECIAL_FILTER isPositiveInteger(data) &&
: NORMAL_FILTER; getParameterByName(PARAM_ASSIGNEE_ID) === data;
return specialFilterValues.includes(data) || isAssigneeIdParam ? SPECIAL_FILTER : NORMAL_FILTER;
};
const wildcardTokens = [TOKEN_TYPE_ITERATION, TOKEN_TYPE_MILESTONE, TOKEN_TYPE_RELEASE]; const wildcardTokens = [TOKEN_TYPE_ITERATION, TOKEN_TYPE_MILESTONE, TOKEN_TYPE_RELEASE];
const isWildcardValue = (tokenType, value) => const isWildcardValue = (tokenType, value) =>
wildcardTokens.includes(tokenType) && SPECIAL_FILTER_VALUES.includes(value); wildcardTokens.includes(tokenType) && specialFilterValues.includes(value);
const requiresUpperCaseValue = (tokenType, value) => const requiresUpperCaseValue = (tokenType, value) =>
tokenType === TOKEN_TYPE_TYPE || isWildcardValue(tokenType, value); tokenType === TOKEN_TYPE_TYPE || isWildcardValue(tokenType, value);
......
...@@ -117,6 +117,7 @@ export const locationSearch = [ ...@@ -117,6 +117,7 @@ export const locationSearch = [
'not[author_username]=marge', 'not[author_username]=marge',
'assignee_username[]=bart', 'assignee_username[]=bart',
'assignee_username[]=lisa', 'assignee_username[]=lisa',
'assignee_username[]=5',
'not[assignee_username][]=patty', 'not[assignee_username][]=patty',
'not[assignee_username][]=selma', 'not[assignee_username][]=selma',
'milestone_title=season+3', 'milestone_title=season+3',
...@@ -165,6 +166,7 @@ export const filteredTokens = [ ...@@ -165,6 +166,7 @@ export const filteredTokens = [
{ type: 'author_username', value: { data: 'marge', operator: OPERATOR_IS_NOT } }, { type: 'author_username', value: { data: 'marge', operator: OPERATOR_IS_NOT } },
{ type: 'assignee_username', value: { data: 'bart', operator: OPERATOR_IS } }, { type: 'assignee_username', value: { data: 'bart', operator: OPERATOR_IS } },
{ type: 'assignee_username', value: { data: 'lisa', operator: OPERATOR_IS } }, { type: 'assignee_username', value: { data: 'lisa', operator: OPERATOR_IS } },
{ type: 'assignee_username', value: { data: '5', operator: OPERATOR_IS } },
{ type: 'assignee_username', value: { data: 'patty', operator: OPERATOR_IS_NOT } }, { type: 'assignee_username', value: { data: 'patty', operator: OPERATOR_IS_NOT } },
{ type: 'assignee_username', value: { data: 'selma', operator: OPERATOR_IS_NOT } }, { type: 'assignee_username', value: { data: 'selma', operator: OPERATOR_IS_NOT } },
{ type: 'milestone', value: { data: 'season 3', operator: OPERATOR_IS } }, { type: 'milestone', value: { data: 'season 3', operator: OPERATOR_IS } },
...@@ -212,7 +214,7 @@ export const filteredTokensWithSpecialValues = [ ...@@ -212,7 +214,7 @@ export const filteredTokensWithSpecialValues = [
export const apiParams = { export const apiParams = {
authorUsername: 'homer', authorUsername: 'homer',
assigneeUsernames: ['bart', 'lisa'], assigneeUsernames: ['bart', 'lisa', '5'],
milestoneTitle: ['season 3', 'season 4'], milestoneTitle: ['season 3', 'season 4'],
labelName: ['cartoon', 'tv'], labelName: ['cartoon', 'tv'],
releaseTag: ['v3', 'v4'], releaseTag: ['v3', 'v4'],
...@@ -251,7 +253,7 @@ export const apiParamsWithSpecialValues = { ...@@ -251,7 +253,7 @@ export const apiParamsWithSpecialValues = {
export const urlParams = { export const urlParams = {
author_username: 'homer', author_username: 'homer',
'not[author_username]': 'marge', 'not[author_username]': 'marge',
'assignee_username[]': ['bart', 'lisa'], 'assignee_username[]': ['bart', 'lisa', '5'],
'not[assignee_username][]': ['patty', 'selma'], 'not[assignee_username][]': ['patty', 'selma'],
milestone_title: ['season 3', 'season 4'], milestone_title: ['season 3', 'season 4'],
'not[milestone_title]': ['season 20', 'season 30'], 'not[milestone_title]': ['season 20', 'season 30'],
......
import setWindowLocation from 'helpers/set_window_location_helper';
import { TEST_HOST } from 'helpers/test_constants';
import { import {
apiParams, apiParams,
apiParamsWithSpecialValues, apiParamsWithSpecialValues,
...@@ -127,21 +129,33 @@ describe('getFilterTokens', () => { ...@@ -127,21 +129,33 @@ describe('getFilterTokens', () => {
}); });
describe('convertToApiParams', () => { describe('convertToApiParams', () => {
beforeEach(() => {
setWindowLocation(TEST_HOST);
});
it('returns api params given filtered tokens', () => { it('returns api params given filtered tokens', () => {
expect(convertToApiParams(filteredTokens)).toEqual(apiParams); expect(convertToApiParams(filteredTokens)).toEqual(apiParams);
}); });
it('returns api params given filtered tokens with special values', () => { it('returns api params given filtered tokens with special values', () => {
setWindowLocation('?assignee_id=123');
expect(convertToApiParams(filteredTokensWithSpecialValues)).toEqual(apiParamsWithSpecialValues); expect(convertToApiParams(filteredTokensWithSpecialValues)).toEqual(apiParamsWithSpecialValues);
}); });
}); });
describe('convertToUrlParams', () => { describe('convertToUrlParams', () => {
beforeEach(() => {
setWindowLocation(TEST_HOST);
});
it('returns url params given filtered tokens', () => { it('returns url params given filtered tokens', () => {
expect(convertToUrlParams(filteredTokens)).toEqual(urlParams); expect(convertToUrlParams(filteredTokens)).toEqual(urlParams);
}); });
it('returns url params given filtered tokens with special values', () => { it('returns url params given filtered tokens with special values', () => {
setWindowLocation('?assignee_id=123');
expect(convertToUrlParams(filteredTokensWithSpecialValues)).toEqual(urlParamsWithSpecialValues); expect(convertToUrlParams(filteredTokensWithSpecialValues)).toEqual(urlParamsWithSpecialValues);
}); });
}); });
......
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