Commit abef98ec authored by Jose Ivan Vargas's avatar Jose Ivan Vargas

Merge branch '322755-add-milestone-wildcard-filters' into 'master'

Add milestone wildcard filters and MR count to issues page refactor

See merge request gitlab-org/gitlab!67438
parents daaa4bf6 15c06897
......@@ -305,7 +305,6 @@ export default {
icon: 'clock',
token: MilestoneToken,
unique: true,
defaultMilestones: [],
fetchMilestones: this.fetchMilestones,
},
{
......
......@@ -5,6 +5,8 @@ import {
FILTER_ANY,
FILTER_CURRENT,
FILTER_NONE,
FILTER_STARTED,
FILTER_UPCOMING,
OPERATOR_IS,
OPERATOR_IS_NOT,
} from '~/vue_shared/components/filtered_search_bar/constants';
......@@ -186,7 +188,13 @@ export const URL_PARAM = 'urlParam';
export const NORMAL_FILTER = 'normalFilter';
export const SPECIAL_FILTER = 'specialFilter';
export const ALTERNATIVE_FILTER = 'alternativeFilter';
export const SPECIAL_FILTER_VALUES = [FILTER_NONE, FILTER_ANY, FILTER_CURRENT];
export const SPECIAL_FILTER_VALUES = [
FILTER_NONE,
FILTER_ANY,
FILTER_CURRENT,
FILTER_UPCOMING,
FILTER_STARTED,
];
export const TOKEN_TYPE_AUTHOR = 'author_username';
export const TOKEN_TYPE_ASSIGNEE = 'assignee_username';
......@@ -231,10 +239,12 @@ export const filters = {
[TOKEN_TYPE_MILESTONE]: {
[API_PARAM]: {
[NORMAL_FILTER]: 'milestoneTitle',
[SPECIAL_FILTER]: 'milestoneWildcardId',
},
[URL_PARAM]: {
[OPERATOR_IS]: {
[NORMAL_FILTER]: 'milestone_title',
[SPECIAL_FILTER]: 'milestone_title',
},
[OPERATOR_IS_NOT]: {
[NORMAL_FILTER]: 'not[milestone_title]',
......
......@@ -12,6 +12,7 @@ query getProjectIssues(
$authorUsername: String
$labelName: [String]
$milestoneTitle: [String]
$milestoneWildcardId: MilestoneWildcardId
$not: NegatedIssueFilterInput
$beforeCursor: String
$afterCursor: String
......@@ -28,6 +29,7 @@ query getProjectIssues(
authorUsername: $authorUsername
labelName: $labelName
milestoneTitle: $milestoneTitle
milestoneWildcardId: $milestoneWildcardId
not: $not
before: $beforeCursor
after: $afterCursor
......
......@@ -7,6 +7,7 @@ query getProjectIssuesCount(
$authorUsername: String
$labelName: [String]
$milestoneTitle: [String]
$milestoneWildcardId: MilestoneWildcardId
$not: NegatedIssueFilterInput
) {
project(fullPath: $projectPath) {
......@@ -18,6 +19,7 @@ query getProjectIssuesCount(
authorUsername: $authorUsername
labelName: $labelName
milestoneTitle: $milestoneTitle
milestoneWildcardId: $milestoneWildcardId
not: $not
) {
count
......
......@@ -7,6 +7,7 @@ fragment IssueFragment on Issue {
downvotes
dueDate
humanTimeEstimate
mergeRequestsCount
moved
title
updatedAt
......
......@@ -21,6 +21,7 @@ import {
SPECIAL_FILTER_VALUES,
TOKEN_TYPE_ASSIGNEE,
TOKEN_TYPE_ITERATION,
TOKEN_TYPE_MILESTONE,
UPDATED_ASC,
UPDATED_DESC,
URL_PARAM,
......@@ -186,8 +187,14 @@ const getFilterType = (data, tokenType = '') =>
? SPECIAL_FILTER
: NORMAL_FILTER;
const isIterationSpecialValue = (tokenType, value) =>
tokenType === TOKEN_TYPE_ITERATION && SPECIAL_FILTER_VALUES.includes(value);
const requiresUpperCaseValue = (tokenType, value) =>
(tokenType === TOKEN_TYPE_ITERATION || tokenType === TOKEN_TYPE_MILESTONE) &&
SPECIAL_FILTER_VALUES.includes(value);
const formatData = (token) =>
requiresUpperCaseValue(token.type, token.value.data)
? token.value.data.toUpperCase()
: token.value.data;
export const convertToApiParams = (filterTokens) => {
const params = {};
......@@ -199,9 +206,7 @@ export const convertToApiParams = (filterTokens) => {
const filterType = getFilterType(token.value.data, token.type);
const field = filters[token.type][API_PARAM][filterType];
const obj = token.value.operator === OPERATOR_IS_NOT ? not : params;
const data = isIterationSpecialValue(token.type, token.value.data)
? token.value.data.toUpperCase()
: token.value.data;
const data = formatData(token);
Object.assign(obj, {
[field]: obj[field] ? [obj[field], data].flat() : data,
});
......
......@@ -7,6 +7,8 @@ export const WEIGHT_TOKEN_SUGGESTIONS_SIZE = 21;
export const FILTER_NONE = 'None';
export const FILTER_ANY = 'Any';
export const FILTER_CURRENT = 'Current';
export const FILTER_UPCOMING = 'Upcoming';
export const FILTER_STARTED = 'Started';
export const OPERATOR_IS = '=';
export const OPERATOR_IS_TEXT = __('is');
......@@ -28,8 +30,8 @@ export const DEFAULT_ITERATIONS = DEFAULT_NONE_ANY.concat([
export const DEFAULT_LABELS = [DEFAULT_LABEL_NONE, DEFAULT_LABEL_ANY];
export const DEFAULT_MILESTONES = DEFAULT_NONE_ANY.concat([
{ value: 'Upcoming', text: __('Upcoming') }, // eslint-disable-line @gitlab/require-i18n-strings
{ value: 'Started', text: __('Started') }, // eslint-disable-line @gitlab/require-i18n-strings
{ value: FILTER_UPCOMING, text: __(FILTER_UPCOMING) },
{ value: FILTER_STARTED, text: __(FILTER_STARTED) },
]);
export const SortDirection = {
......
......@@ -12,6 +12,7 @@ query getProjectIssues(
$authorUsername: String
$labelName: [String]
$milestoneTitle: [String]
$milestoneWildcardId: MilestoneWildcardId
$epicId: String
$iterationId: [ID]
$iterationWildcardId: IterationWildcardId
......@@ -32,6 +33,7 @@ query getProjectIssues(
authorUsername: $authorUsername
labelName: $labelName
milestoneTitle: $milestoneTitle
milestoneWildcardId: $milestoneWildcardId
epicId: $epicId
iterationId: $iterationId
iterationWildcardId: $iterationWildcardId
......
......@@ -7,6 +7,7 @@ query getProjectIssuesCount(
$authorUsername: String
$labelName: [String]
$milestoneTitle: [String]
$milestoneWildcardId: MilestoneWildcardId
$epicId: String
$iterationId: [ID]
$iterationWildcardId: IterationWildcardId
......@@ -22,6 +23,7 @@ query getProjectIssuesCount(
authorUsername: $authorUsername
labelName: $labelName
milestoneTitle: $milestoneTitle
milestoneWildcardId: $milestoneWildcardId
epicId: $epicId
iterationId: $iterationId
iterationWildcardId: $iterationWildcardId
......
......@@ -23,6 +23,7 @@ export const getIssuesQueryResponse = {
downvotes: 2,
dueDate: '2021-05-29',
humanTimeEstimate: null,
mergeRequestsCount: false,
moved: false,
title: 'Issue title',
updatedAt: '2021-05-22T04:08:01Z',
......@@ -108,6 +109,7 @@ export const locationSearchWithSpecialValues = [
'assignee_username=bart',
'my_reaction_emoji=None',
'iteration_id=Current',
'milestone_title=Upcoming',
'epic_id=None',
'weight=None',
].join('&');
......@@ -142,6 +144,7 @@ export const filteredTokensWithSpecialValues = [
{ type: 'assignee_username', value: { data: 'bart', operator: OPERATOR_IS } },
{ type: 'my_reaction_emoji', value: { data: 'None', operator: OPERATOR_IS } },
{ type: 'iteration', value: { data: 'Current', operator: OPERATOR_IS } },
{ type: 'milestone', value: { data: 'Upcoming', operator: OPERATOR_IS } },
{ type: 'epic_id', value: { data: 'None', operator: OPERATOR_IS } },
{ type: 'weight', value: { data: 'None', operator: OPERATOR_IS } },
];
......@@ -172,6 +175,7 @@ export const apiParamsWithSpecialValues = {
assigneeUsernames: 'bart',
myReactionEmoji: 'None',
iterationWildcardId: 'CURRENT',
milestoneWildcardId: 'UPCOMING',
epicId: 'None',
weight: 'None',
};
......@@ -200,6 +204,7 @@ export const urlParamsWithSpecialValues = {
'assignee_username[]': 'bart',
my_reaction_emoji: 'None',
iteration_id: 'Current',
milestone_title: 'Upcoming',
epic_id: 'None',
weight: 'None',
};
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