Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-06-21 15:07:45 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-06-21 15:07:45 +0300
commitd4c968c95c4b966a58d3fe76c25aeb6e97d84925 (patch)
treeb3d9237b97a50d813437d53eb9fbfd406417031f /app/assets/javascripts
parent3ab7e70965fd198aafefc5c1a0eaf7b695f6cabc (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts')
-rw-r--r--app/assets/javascripts/environments/components/environments_app.vue2
-rw-r--r--app/assets/javascripts/environments/mixins/environments_mixin.js3
-rw-r--r--app/assets/javascripts/issues_list/components/issues_list_app.vue61
-rw-r--r--app/assets/javascripts/issues_list/constants.js218
-rw-r--r--app/assets/javascripts/issues_list/utils.js54
-rw-r--r--app/assets/javascripts/nav/components/top_nav_dropdown_menu.vue4
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/epic_token.vue19
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/iteration_token.vue10
-rw-r--r--app/assets/javascripts/vue_shared/components/user_select/user_select.vue23
9 files changed, 134 insertions, 260 deletions
diff --git a/app/assets/javascripts/environments/components/environments_app.vue b/app/assets/javascripts/environments/components/environments_app.vue
index 1ceb3cb9828..e4cf5760987 100644
--- a/app/assets/javascripts/environments/components/environments_app.vue
+++ b/app/assets/javascripts/environments/components/environments_app.vue
@@ -135,7 +135,7 @@ export default {
>{{ $options.i18n.newEnvironmentButtonLabel }}</gl-button
>
</div>
- <gl-tabs content-class="gl-display-none">
+ <gl-tabs :value="activeTab" content-class="gl-display-none">
<gl-tab
v-for="(tab, idx) in tabs"
:key="idx"
diff --git a/app/assets/javascripts/environments/mixins/environments_mixin.js b/app/assets/javascripts/environments/mixins/environments_mixin.js
index 280f5799503..c80839a117f 100644
--- a/app/assets/javascripts/environments/mixins/environments_mixin.js
+++ b/app/assets/javascripts/environments/mixins/environments_mixin.js
@@ -208,6 +208,9 @@ export default {
},
];
},
+ activeTab() {
+ return this.tabs.findIndex(({ isActive }) => isActive) ?? 0;
+ },
},
/**
diff --git a/app/assets/javascripts/issues_list/components/issues_list_app.vue b/app/assets/javascripts/issues_list/components/issues_list_app.vue
index 921af766796..051512e9a66 100644
--- a/app/assets/javascripts/issues_list/components/issues_list_app.vue
+++ b/app/assets/javascripts/issues_list/components/issues_list_app.vue
@@ -16,7 +16,6 @@ import IssuableByEmail from '~/issuable/components/issuable_by_email.vue';
import IssuableList from '~/issuable_list/components/issuable_list_root.vue';
import { IssuableListTabs, IssuableStates } from '~/issuable_list/constants';
import {
- API_PARAM,
CREATED_DESC,
i18n,
initialPageParams,
@@ -25,7 +24,7 @@ import {
PARAM_DUE_DATE,
PARAM_SORT,
PARAM_STATE,
- RELATIVE_POSITION_DESC,
+ RELATIVE_POSITION_ASC,
TOKEN_TYPE_ASSIGNEE,
TOKEN_TYPE_AUTHOR,
TOKEN_TYPE_CONFIDENTIAL,
@@ -36,12 +35,12 @@ import {
TOKEN_TYPE_MILESTONE,
TOKEN_TYPE_WEIGHT,
UPDATED_DESC,
- URL_PARAM,
urlSortParams,
} from '~/issues_list/constants';
import {
- convertToParams,
+ convertToApiParams,
convertToSearchQuery,
+ convertToUrlParams,
getDueDateValue,
getFilterTokens,
getSortKey,
@@ -192,10 +191,10 @@ export default {
...this.apiFilterParams,
};
},
- update: ({ project }) => project.issues.nodes,
+ update: ({ project }) => project?.issues.nodes ?? [],
result({ data }) {
- this.pageInfo = data.project.issues.pageInfo;
- this.totalIssues = data.project.issues.count;
+ this.pageInfo = data.project?.issues.pageInfo ?? {};
+ this.totalIssues = data.project?.issues.count ?? 0;
this.exportCsvPathWithQuery = this.getExportCsvPathWithQuery();
},
error(error) {
@@ -215,32 +214,30 @@ export default {
return this.showBulkEditSidebar || !this.issues.length;
},
isManualOrdering() {
- return this.sortKey === RELATIVE_POSITION_DESC;
+ return this.sortKey === RELATIVE_POSITION_ASC;
},
isOpenTab() {
return this.state === IssuableStates.Opened;
},
apiFilterParams() {
- return convertToParams(this.filterTokens, API_PARAM);
+ return convertToApiParams(this.filterTokens);
},
urlFilterParams() {
- return convertToParams(this.filterTokens, URL_PARAM);
+ return convertToUrlParams(this.filterTokens);
},
searchQuery() {
return convertToSearchQuery(this.filterTokens) || undefined;
},
searchTokens() {
- let preloadedAuthors = [];
+ const preloadedAuthors = [];
if (gon.current_user_id) {
- preloadedAuthors = [
- {
- id: gon.current_user_id,
- name: gon.current_user_fullname,
- username: gon.current_username,
- avatar_url: gon.current_user_avatar_url,
- },
- ];
+ preloadedAuthors.push({
+ id: gon.current_user_id,
+ name: gon.current_user_fullname,
+ username: gon.current_username,
+ avatar_url: gon.current_user_avatar_url,
+ });
}
const tokens = [
@@ -252,6 +249,7 @@ export default {
dataType: 'user',
unique: true,
defaultAuthors: [],
+ operators: OPERATOR_IS_ONLY,
fetchAuthors: this.fetchUsers,
preloadedAuthors,
},
@@ -280,7 +278,7 @@ export default {
title: TOKEN_TITLE_LABEL,
icon: 'labels',
token: LabelToken,
- defaultLabels: [],
+ defaultLabels: DEFAULT_NONE_ANY,
fetchLabels: this.fetchLabels,
},
];
@@ -329,6 +327,7 @@ export default {
token: EpicToken,
unique: true,
idProperty: 'id',
+ useIdValue: true,
fetchEpics: this.fetchEpics,
});
}
@@ -346,7 +345,7 @@ export default {
return tokens;
},
showPaginationControls() {
- return this.issues.length > 0;
+ return this.issues.length > 0 && (this.pageInfo.hasNextPage || this.pageInfo.hasPreviousPage);
},
sortOptions() {
return getSortOptions(this.hasIssueWeightsFeature, this.hasBlockedIssuesFeature);
@@ -361,22 +360,12 @@ export default {
);
},
urlParams() {
- const filterParams = {
- ...this.urlFilterParams,
- };
-
- if (filterParams.epic_id) {
- filterParams.epic_id = encodeURIComponent(filterParams.epic_id);
- } else if (filterParams['not[epic_id]']) {
- filterParams['not[epic_id]'] = encodeURIComponent(filterParams['not[epic_id]']);
- }
-
return {
due_date: this.dueDateFilter,
search: this.searchQuery,
+ sort: urlSortParams[this.sortKey],
state: this.state,
- ...urlSortParams[this.sortKey],
- ...filterParams,
+ ...this.urlFilterParams,
};
},
},
@@ -424,7 +413,10 @@ export default {
return this.fetchWithCache(this.projectMilestonesPath, 'milestones', 'title', search, true);
},
fetchIterations(search) {
- return axios.get(this.projectIterationsPath, { params: { search } });
+ const id = Number(search);
+ return !search || Number.isNaN(id)
+ ? axios.get(this.projectIterationsPath, { params: { search } })
+ : axios.get(this.projectIterationsPath, { params: { id } });
},
fetchUsers(search) {
return axios.get(this.autocompleteUsersPath, { params: { search } });
@@ -471,6 +463,7 @@ export default {
this.state = state;
},
handleFilter(filter) {
+ this.pageParams = initialPageParams;
this.filterTokens = filter;
},
handleNextPage() {
diff --git a/app/assets/javascripts/issues_list/constants.js b/app/assets/javascripts/issues_list/constants.js
index 76006f9081d..6337ccc4926 100644
--- a/app/assets/javascripts/issues_list/constants.js
+++ b/app/assets/javascripts/issues_list/constants.js
@@ -128,21 +128,21 @@ export const CREATED_ASC = 'CREATED_ASC';
export const CREATED_DESC = 'CREATED_DESC';
export const DUE_DATE_ASC = 'DUE_DATE_ASC';
export const DUE_DATE_DESC = 'DUE_DATE_DESC';
+export const LABEL_PRIORITY_ASC = 'LABEL_PRIORITY_ASC';
export const LABEL_PRIORITY_DESC = 'LABEL_PRIORITY_DESC';
export const MILESTONE_DUE_ASC = 'MILESTONE_DUE_ASC';
export const MILESTONE_DUE_DESC = 'MILESTONE_DUE_DESC';
export const POPULARITY_ASC = 'POPULARITY_ASC';
export const POPULARITY_DESC = 'POPULARITY_DESC';
+export const PRIORITY_ASC = 'PRIORITY_ASC';
export const PRIORITY_DESC = 'PRIORITY_DESC';
-export const RELATIVE_POSITION_DESC = 'RELATIVE_POSITION_DESC';
+export const RELATIVE_POSITION_ASC = 'RELATIVE_POSITION_ASC';
export const UPDATED_ASC = 'UPDATED_ASC';
export const UPDATED_DESC = 'UPDATED_DESC';
export const WEIGHT_ASC = 'WEIGHT_ASC';
export const WEIGHT_DESC = 'WEIGHT_DESC';
-const SORT_ASC = 'asc';
-const SORT_DESC = 'desc';
-
+const PRIORITY_ASC_SORT = 'priority_asc';
const CREATED_DATE_SORT = 'created_date';
const CREATED_ASC_SORT = 'created_asc';
const UPDATED_DESC_SORT = 'updated_desc';
@@ -150,129 +150,30 @@ const UPDATED_ASC_SORT = 'updated_asc';
const MILESTONE_SORT = 'milestone';
const MILESTONE_DUE_DESC_SORT = 'milestone_due_desc';
const DUE_DATE_DESC_SORT = 'due_date_desc';
+const LABEL_PRIORITY_ASC_SORT = 'label_priority_asc';
const POPULARITY_ASC_SORT = 'popularity_asc';
const WEIGHT_DESC_SORT = 'weight_desc';
const BLOCKING_ISSUES_DESC_SORT = 'blocking_issues_desc';
-const BLOCKING_ISSUES = 'blocking_issues';
-
-export const apiSortParams = {
- [PRIORITY_DESC]: {
- order_by: PRIORITY,
- sort: SORT_DESC,
- },
- [CREATED_ASC]: {
- order_by: CREATED_AT,
- sort: SORT_ASC,
- },
- [CREATED_DESC]: {
- order_by: CREATED_AT,
- sort: SORT_DESC,
- },
- [UPDATED_ASC]: {
- order_by: UPDATED_AT,
- sort: SORT_ASC,
- },
- [UPDATED_DESC]: {
- order_by: UPDATED_AT,
- sort: SORT_DESC,
- },
- [MILESTONE_DUE_ASC]: {
- order_by: MILESTONE_DUE,
- sort: SORT_ASC,
- },
- [MILESTONE_DUE_DESC]: {
- order_by: MILESTONE_DUE,
- sort: SORT_DESC,
- },
- [DUE_DATE_ASC]: {
- order_by: DUE_DATE,
- sort: SORT_ASC,
- },
- [DUE_DATE_DESC]: {
- order_by: DUE_DATE,
- sort: SORT_DESC,
- },
- [POPULARITY_ASC]: {
- order_by: POPULARITY,
- sort: SORT_ASC,
- },
- [POPULARITY_DESC]: {
- order_by: POPULARITY,
- sort: SORT_DESC,
- },
- [LABEL_PRIORITY_DESC]: {
- order_by: LABEL_PRIORITY,
- sort: SORT_DESC,
- },
- [RELATIVE_POSITION_DESC]: {
- order_by: RELATIVE_POSITION,
- per_page: 100,
- sort: SORT_ASC,
- },
- [WEIGHT_ASC]: {
- order_by: WEIGHT,
- sort: SORT_ASC,
- },
- [WEIGHT_DESC]: {
- order_by: WEIGHT,
- sort: SORT_DESC,
- },
- [BLOCKING_ISSUES_DESC]: {
- order_by: BLOCKING_ISSUES,
- sort: SORT_DESC,
- },
-};
export const urlSortParams = {
- [PRIORITY_DESC]: {
- sort: PRIORITY,
- },
- [CREATED_ASC]: {
- sort: CREATED_ASC_SORT,
- },
- [CREATED_DESC]: {
- sort: CREATED_DATE_SORT,
- },
- [UPDATED_ASC]: {
- sort: UPDATED_ASC_SORT,
- },
- [UPDATED_DESC]: {
- sort: UPDATED_DESC_SORT,
- },
- [MILESTONE_DUE_ASC]: {
- sort: MILESTONE_SORT,
- },
- [MILESTONE_DUE_DESC]: {
- sort: MILESTONE_DUE_DESC_SORT,
- },
- [DUE_DATE_ASC]: {
- sort: DUE_DATE,
- },
- [DUE_DATE_DESC]: {
- sort: DUE_DATE_DESC_SORT,
- },
- [POPULARITY_ASC]: {
- sort: POPULARITY_ASC_SORT,
- },
- [POPULARITY_DESC]: {
- sort: POPULARITY,
- },
- [LABEL_PRIORITY_DESC]: {
- sort: LABEL_PRIORITY,
- },
- [RELATIVE_POSITION_DESC]: {
- sort: RELATIVE_POSITION,
- per_page: 100,
- },
- [WEIGHT_ASC]: {
- sort: WEIGHT,
- },
- [WEIGHT_DESC]: {
- sort: WEIGHT_DESC_SORT,
- },
- [BLOCKING_ISSUES_DESC]: {
- sort: BLOCKING_ISSUES_DESC_SORT,
- },
+ [PRIORITY_ASC]: PRIORITY_ASC_SORT,
+ [PRIORITY_DESC]: PRIORITY,
+ [CREATED_ASC]: CREATED_ASC_SORT,
+ [CREATED_DESC]: CREATED_DATE_SORT,
+ [UPDATED_ASC]: UPDATED_ASC_SORT,
+ [UPDATED_DESC]: UPDATED_DESC_SORT,
+ [MILESTONE_DUE_ASC]: MILESTONE_SORT,
+ [MILESTONE_DUE_DESC]: MILESTONE_DUE_DESC_SORT,
+ [DUE_DATE_ASC]: DUE_DATE,
+ [DUE_DATE_DESC]: DUE_DATE_DESC_SORT,
+ [POPULARITY_ASC]: POPULARITY_ASC_SORT,
+ [POPULARITY_DESC]: POPULARITY,
+ [LABEL_PRIORITY_ASC]: LABEL_PRIORITY_ASC_SORT,
+ [LABEL_PRIORITY_DESC]: LABEL_PRIORITY,
+ [RELATIVE_POSITION_ASC]: RELATIVE_POSITION,
+ [WEIGHT_ASC]: WEIGHT,
+ [WEIGHT_DESC]: WEIGHT_DESC_SORT,
+ [BLOCKING_ISSUES_DESC]: BLOCKING_ISSUES_DESC_SORT,
};
export const MAX_LIST_SIZE = 10;
@@ -297,12 +198,7 @@ export const TOKEN_TYPE_WEIGHT = 'weight';
export const filters = {
[TOKEN_TYPE_AUTHOR]: {
[API_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'author_username',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[author_username]',
- },
+ [NORMAL_FILTER]: 'authorUsername',
},
[URL_PARAM]: {
[OPERATOR_IS]: {
@@ -315,13 +211,8 @@ export const filters = {
},
[TOKEN_TYPE_ASSIGNEE]: {
[API_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'assignee_username',
- [SPECIAL_FILTER]: 'assignee_id',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[assignee_username]',
- },
+ [NORMAL_FILTER]: 'assigneeUsernames',
+ [SPECIAL_FILTER]: 'assigneeId',
},
[URL_PARAM]: {
[OPERATOR_IS]: {
@@ -336,12 +227,7 @@ export const filters = {
},
[TOKEN_TYPE_MILESTONE]: {
[API_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'milestone',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[milestone]',
- },
+ [NORMAL_FILTER]: 'milestoneTitle',
},
[URL_PARAM]: {
[OPERATOR_IS]: {
@@ -354,16 +240,13 @@ export const filters = {
},
[TOKEN_TYPE_LABEL]: {
[API_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'labels',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[labels]',
- },
+ [NORMAL_FILTER]: 'labelName',
+ [SPECIAL_FILTER]: 'labelName',
},
[URL_PARAM]: {
[OPERATOR_IS]: {
[NORMAL_FILTER]: 'label_name[]',
+ [SPECIAL_FILTER]: 'label_name[]',
},
[OPERATOR_IS_NOT]: {
[NORMAL_FILTER]: 'not[label_name][]',
@@ -372,10 +255,8 @@ export const filters = {
},
[TOKEN_TYPE_MY_REACTION]: {
[API_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'my_reaction_emoji',
- [SPECIAL_FILTER]: 'my_reaction_emoji',
- },
+ [NORMAL_FILTER]: 'myReactionEmoji',
+ [SPECIAL_FILTER]: 'myReactionEmoji',
},
[URL_PARAM]: {
[OPERATOR_IS]: {
@@ -386,9 +267,7 @@ export const filters = {
},
[TOKEN_TYPE_CONFIDENTIAL]: {
[API_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'confidential',
- },
+ [NORMAL_FILTER]: 'confidential',
},
[URL_PARAM]: {
[OPERATOR_IS]: {
@@ -398,33 +277,23 @@ export const filters = {
},
[TOKEN_TYPE_ITERATION]: {
[API_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'iteration_title',
- [SPECIAL_FILTER]: 'iteration_id',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[iteration_title]',
- },
+ [NORMAL_FILTER]: 'iterationId',
+ [SPECIAL_FILTER]: 'iterationWildcardId',
},
[URL_PARAM]: {
[OPERATOR_IS]: {
- [NORMAL_FILTER]: 'iteration_title',
+ [NORMAL_FILTER]: 'iteration_id',
[SPECIAL_FILTER]: 'iteration_id',
},
[OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[iteration_title]',
+ [NORMAL_FILTER]: 'not[iteration_id]',
},
},
},
[TOKEN_TYPE_EPIC]: {
[API_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'epic_id',
- [SPECIAL_FILTER]: 'epic_id',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[epic_id]',
- },
+ [NORMAL_FILTER]: 'epicId',
+ [SPECIAL_FILTER]: 'epicId',
},
[URL_PARAM]: {
[OPERATOR_IS]: {
@@ -438,13 +307,8 @@ export const filters = {
},
[TOKEN_TYPE_WEIGHT]: {
[API_PARAM]: {
- [OPERATOR_IS]: {
- [NORMAL_FILTER]: 'weight',
- [SPECIAL_FILTER]: 'weight',
- },
- [OPERATOR_IS_NOT]: {
- [NORMAL_FILTER]: 'not[weight]',
- },
+ [NORMAL_FILTER]: 'weight',
+ [SPECIAL_FILTER]: 'weight',
},
[URL_PARAM]: {
[OPERATOR_IS]: {
diff --git a/app/assets/javascripts/issues_list/utils.js b/app/assets/javascripts/issues_list/utils.js
index b5ec44198da..49f937cc453 100644
--- a/app/assets/javascripts/issues_list/utils.js
+++ b/app/assets/javascripts/issues_list/utils.js
@@ -1,4 +1,5 @@
import {
+ API_PARAM,
BLOCKING_ISSUES_DESC,
CREATED_ASC,
CREATED_DESC,
@@ -6,29 +7,36 @@ import {
DUE_DATE_DESC,
DUE_DATE_VALUES,
filters,
+ LABEL_PRIORITY_ASC,
LABEL_PRIORITY_DESC,
MILESTONE_DUE_ASC,
MILESTONE_DUE_DESC,
NORMAL_FILTER,
POPULARITY_ASC,
POPULARITY_DESC,
+ PRIORITY_ASC,
PRIORITY_DESC,
- RELATIVE_POSITION_DESC,
+ RELATIVE_POSITION_ASC,
SPECIAL_FILTER,
SPECIAL_FILTER_VALUES,
TOKEN_TYPE_ASSIGNEE,
+ TOKEN_TYPE_ITERATION,
UPDATED_ASC,
UPDATED_DESC,
+ URL_PARAM,
urlSortParams,
WEIGHT_ASC,
WEIGHT_DESC,
} from '~/issues_list/constants';
import { isPositiveInteger } from '~/lib/utils/number_utils';
import { __ } from '~/locale';
-import { FILTERED_SEARCH_TERM } from '~/vue_shared/components/filtered_search_bar/constants';
+import {
+ FILTERED_SEARCH_TERM,
+ OPERATOR_IS_NOT,
+} from '~/vue_shared/components/filtered_search_bar/constants';
export const getSortKey = (sort) =>
- Object.keys(urlSortParams).find((key) => urlSortParams[key].sort === sort);
+ Object.keys(urlSortParams).find((key) => urlSortParams[key] === sort);
export const getDueDateValue = (value) => (DUE_DATE_VALUES.includes(value) ? value : undefined);
@@ -38,7 +46,7 @@ export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature)
id: 1,
title: __('Priority'),
sortDirection: {
- ascending: PRIORITY_DESC,
+ ascending: PRIORITY_ASC,
descending: PRIORITY_DESC,
},
},
@@ -86,7 +94,7 @@ export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature)
id: 7,
title: __('Label priority'),
sortDirection: {
- ascending: LABEL_PRIORITY_DESC,
+ ascending: LABEL_PRIORITY_ASC,
descending: LABEL_PRIORITY_DESC,
},
},
@@ -94,8 +102,8 @@ export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature)
id: 8,
title: __('Manual'),
sortDirection: {
- ascending: RELATIVE_POSITION_DESC,
- descending: RELATIVE_POSITION_DESC,
+ ascending: RELATIVE_POSITION_ASC,
+ descending: RELATIVE_POSITION_ASC,
},
},
];
@@ -128,7 +136,7 @@ export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature)
const tokenTypes = Object.keys(filters);
const getUrlParams = (tokenType) =>
- Object.values(filters[tokenType].urlParam).flatMap((filterObj) => Object.values(filterObj));
+ Object.values(filters[tokenType][URL_PARAM]).flatMap((filterObj) => Object.values(filterObj));
const urlParamKeys = tokenTypes.flatMap(getUrlParams);
@@ -136,7 +144,7 @@ const getTokenTypeFromUrlParamKey = (urlParamKey) =>
tokenTypes.find((tokenType) => getUrlParams(tokenType).includes(urlParamKey));
const getOperatorFromUrlParamKey = (tokenType, urlParamKey) =>
- Object.entries(filters[tokenType].urlParam).find(([, filterObj]) =>
+ Object.entries(filters[tokenType][URL_PARAM]).find(([, filterObj]) =>
Object.values(filterObj).includes(urlParamKey),
)[0];
@@ -178,12 +186,36 @@ const getFilterType = (data, tokenType = '') =>
? SPECIAL_FILTER
: NORMAL_FILTER;
-export const convertToParams = (filterTokens, paramType) =>
+const isIterationSpecialValue = (tokenType, value) =>
+ tokenType === TOKEN_TYPE_ITERATION && SPECIAL_FILTER_VALUES.includes(value);
+
+export const convertToApiParams = (filterTokens) => {
+ const params = {};
+ const not = {};
+
+ filterTokens
+ .filter((token) => token.type !== FILTERED_SEARCH_TERM)
+ .forEach((token) => {
+ 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;
+ Object.assign(obj, {
+ [field]: obj[field] ? [obj[field], data].flat() : data,
+ });
+ });
+
+ return Object.keys(not).length ? Object.assign(params, { not }) : params;
+};
+
+export const convertToUrlParams = (filterTokens) =>
filterTokens
.filter((token) => token.type !== FILTERED_SEARCH_TERM)
.reduce((acc, token) => {
const filterType = getFilterType(token.value.data, token.type);
- const param = filters[token.type][paramType][token.value.operator]?.[filterType];
+ const param = filters[token.type][URL_PARAM][token.value.operator]?.[filterType];
return Object.assign(acc, {
[param]: acc[param] ? [acc[param], token.value.data].flat() : token.value.data,
});
diff --git a/app/assets/javascripts/nav/components/top_nav_dropdown_menu.vue b/app/assets/javascripts/nav/components/top_nav_dropdown_menu.vue
index cac8fecb6b1..97856eaf256 100644
--- a/app/assets/javascripts/nav/components/top_nav_dropdown_menu.vue
+++ b/app/assets/javascripts/nav/components/top_nav_dropdown_menu.vue
@@ -72,7 +72,7 @@ export default {
<template>
<div class="gl-display-flex gl-align-items-stretch">
<div
- class="gl-w-grid-size-30 gl-flex-shrink-0 gl-bg-gray-10 gl-py-3 gl-px-5"
+ class="gl-w-grid-size-30 gl-flex-shrink-0 gl-bg-gray-10 gl-p-3"
:class="menuClass"
data-testid="menu-sidebar"
>
@@ -81,7 +81,7 @@ export default {
<keep-alive-slots
v-show="activeView"
:slot-key="activeView"
- class="gl-w-grid-size-40 gl-overflow-hidden gl-py-3 gl-px-5"
+ class="gl-w-grid-size-40 gl-overflow-hidden gl-p-3"
data-testid="menu-subview"
data-qa-selector="menu_subview_container"
>
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/epic_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/epic_token.vue
index d21fa9a344a..5b05187955c 100644
--- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/epic_token.vue
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/epic_token.vue
@@ -56,7 +56,7 @@ export default {
}
// Current value is a string.
- const [groupPath, idProperty] = this.currentValue?.split('::&');
+ const [groupPath, idProperty] = this.currentValue?.split(this.$options.separator);
return this.epics.find(
(epic) =>
epic.group_full_path === groupPath &&
@@ -65,6 +65,9 @@ export default {
}
return null;
},
+ displayText() {
+ return `${this.activeEpic?.title}${this.$options.separator}${this.activeEpic?.iid}`;
+ },
},
watch: {
active: {
@@ -103,8 +106,10 @@ export default {
this.fetchEpicsBySearchTerm({ epicPath, search: data });
}, DEBOUNCE_DELAY),
- getEpicDisplayText(epic) {
- return `${epic.title}${this.$options.separator}${epic.iid}`;
+ getValue(epic) {
+ return this.config.useIdValue
+ ? String(epic[this.idProperty])
+ : `${epic.group_full_path}${this.$options.separator}${epic[this.idProperty]}`;
},
},
};
@@ -118,7 +123,7 @@ export default {
@input="searchEpics"
>
<template #view="{ inputValue }">
- {{ activeEpic ? getEpicDisplayText(activeEpic) : inputValue }}
+ {{ activeEpic ? displayText : inputValue }}
</template>
<template #suggestions>
<gl-filtered-search-suggestion
@@ -131,11 +136,7 @@ export default {
<gl-dropdown-divider v-if="defaultEpics.length" />
<gl-loading-icon v-if="loading" />
<template v-else>
- <gl-filtered-search-suggestion
- v-for="epic in epics"
- :key="epic.id"
- :value="`${epic.group_full_path}::&${epic[idProperty]}`"
- >
+ <gl-filtered-search-suggestion v-for="epic in epics" :key="epic.id" :value="getValue(epic)">
{{ epic.title }}
</gl-filtered-search-suggestion>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/iteration_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/iteration_token.vue
index 7b6a590279a..cdb04ea79e1 100644
--- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/iteration_token.vue
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/iteration_token.vue
@@ -30,7 +30,6 @@ export default {
data() {
return {
iterations: this.config.initialIterations || [],
- defaultIterations: this.config.defaultIterations || DEFAULT_ITERATIONS,
loading: true,
};
},
@@ -39,7 +38,10 @@ export default {
return this.value.data;
},
activeIteration() {
- return this.iterations.find((iteration) => iteration.title === this.currentValue);
+ return this.iterations.find((iteration) => iteration.id === Number(this.currentValue));
+ },
+ defaultIterations() {
+ return this.config.defaultIterations || DEFAULT_ITERATIONS;
},
},
watch: {
@@ -99,8 +101,8 @@ export default {
<template v-else>
<gl-filtered-search-suggestion
v-for="iteration in iterations"
- :key="iteration.title"
- :value="iteration.title"
+ :key="iteration.id"
+ :value="String(iteration.id)"
>
{{ iteration.title }}
</gl-filtered-search-suggestion>
diff --git a/app/assets/javascripts/vue_shared/components/user_select/user_select.vue b/app/assets/javascripts/vue_shared/components/user_select/user_select.vue
index 04e44aa2ed1..b85cae0c64f 100644
--- a/app/assets/javascripts/vue_shared/components/user_select/user_select.vue
+++ b/app/assets/javascripts/vue_shared/components/user_select/user_select.vue
@@ -96,9 +96,6 @@ export default {
},
},
searchUsers: {
- // TODO Remove error policy
- // https://gitlab.com/gitlab-org/gitlab/-/issues/329750
- errorPolicy: 'all',
query: searchUsers,
variables() {
return {
@@ -111,28 +108,10 @@ export default {
return !this.isEditing;
},
update(data) {
- // TODO Remove null filter (BE fix required)
- // https://gitlab.com/gitlab-org/gitlab/-/issues/329750
return data.workspace?.users?.nodes.filter((x) => x?.user).map(({ user }) => user) || [];
},
debounce: ASSIGNEES_DEBOUNCE_DELAY,
- error({ graphQLErrors }) {
- // TODO This error suppression is temporary (BE fix required)
- // https://gitlab.com/gitlab-org/gitlab/-/issues/329750
- const isNullError = ({ message }) => {
- return message === 'Cannot return null for non-nullable field GroupMember.user';
- };
-
- if (graphQLErrors?.length > 0 && graphQLErrors.every(isNullError)) {
- // only null-related errors exist, suppress them.
- // eslint-disable-next-line no-console
- console.error(
- "Suppressing the error 'Cannot return null for non-nullable field GroupMember.user'. Please see https://gitlab.com/gitlab-org/gitlab/-/issues/329750",
- );
- this.isSearching = false;
- return;
- }
-
+ error() {
this.$emit('error');
this.isSearching = false;
},