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
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-11-25 09:12:46 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-11-25 09:12:46 +0300
commit8d2c267efcdb6adbf69ce60d84ad7a73b18a5eb6 (patch)
tree73a25e3d9c5441e4ce70ae82f6d0697a1872d7d6 /app
parent2a6724602aebe899c405c84d1b309558c25b18f7 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/boards/components/board_filtered_search.vue21
-rw-r--r--app/assets/javascripts/boards/components/issue_board_filtered_search.vue35
-rw-r--r--app/assets/javascripts/boards/index.js3
-rw-r--r--app/assets/javascripts/boards/mount_filtered_search_issue_boards.js3
-rw-r--r--app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue69
-rw-r--r--app/assets/javascripts/sidebar/constants.js33
-rw-r--r--app/helpers/boards_helper.rb9
7 files changed, 124 insertions, 49 deletions
diff --git a/app/assets/javascripts/boards/components/board_filtered_search.vue b/app/assets/javascripts/boards/components/board_filtered_search.vue
index 6fa5f018875..f66bc7887dc 100644
--- a/app/assets/javascripts/boards/components/board_filtered_search.vue
+++ b/app/assets/javascripts/boards/components/board_filtered_search.vue
@@ -44,6 +44,7 @@ export default {
weight,
epicId,
myReactionEmoji,
+ releaseTag,
} = this.filterParams;
const filteredSearchValue = [];
@@ -105,6 +106,13 @@ export default {
});
}
+ if (releaseTag) {
+ filteredSearchValue.push({
+ type: 'release',
+ value: { data: releaseTag, operator: '=' },
+ });
+ }
+
if (epicId) {
filteredSearchValue.push({
type: 'epic_id',
@@ -177,6 +185,13 @@ export default {
});
}
+ if (this.filterParams['not[releaseTag]']) {
+ filteredSearchValue.push({
+ type: 'release',
+ value: { data: this.filterParams['not[releaseTag]'], operator: '!=' },
+ });
+ }
+
if (search) {
filteredSearchValue.push(search);
}
@@ -195,6 +210,7 @@ export default {
epicId,
myReactionEmoji,
iterationId,
+ releaseTag,
} = this.filterParams;
let notParams = {};
@@ -210,6 +226,7 @@ export default {
'not[epic_id]': this.filterParams.not.epicId,
'not[my_reaction_emoji]': this.filterParams.not.myReactionEmoji,
'not[iteration_id]': this.filterParams.not.iterationId,
+ 'not[release_tag]': this.filterParams.not.releaseTag,
},
undefined,
);
@@ -227,6 +244,7 @@ export default {
weight,
epic_id: getIdFromGraphQLId(epicId),
my_reaction_emoji: myReactionEmoji,
+ release_tag: releaseTag,
};
},
},
@@ -290,6 +308,9 @@ export default {
case 'my_reaction_emoji':
filterParams.myReactionEmoji = filter.value.data;
break;
+ case 'release':
+ filterParams.releaseTag = filter.value.data;
+ break;
case 'filtered-search-term':
if (filter.value.data) plainText.push(filter.value.data);
break;
diff --git a/app/assets/javascripts/boards/components/issue_board_filtered_search.vue b/app/assets/javascripts/boards/components/issue_board_filtered_search.vue
index aa6ffa500ea..b5270c9d5fa 100644
--- a/app/assets/javascripts/boards/components/issue_board_filtered_search.vue
+++ b/app/assets/javascripts/boards/components/issue_board_filtered_search.vue
@@ -5,6 +5,7 @@ import { mapActions } from 'vuex';
import BoardFilteredSearch from 'ee_else_ce/boards/components/board_filtered_search.vue';
import { BoardType } from '~/boards/constants';
import axios from '~/lib/utils/axios_utils';
+import { joinPaths } from '~/lib/utils/url_utility';
import issueBoardFilters from '~/boards/issue_board_filters';
import { TYPE_USER } from '~/graphql_shared/constants';
import { convertToGraphQLId } from '~/graphql_shared/utils';
@@ -18,6 +19,7 @@ import AuthorToken from '~/vue_shared/components/filtered_search_bar/tokens/auth
import EmojiToken from '~/vue_shared/components/filtered_search_bar/tokens/emoji_token.vue';
import LabelToken from '~/vue_shared/components/filtered_search_bar/tokens/label_token.vue';
import MilestoneToken from '~/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue';
+import ReleaseToken from '~/vue_shared/components/filtered_search_bar/tokens/release_token.vue';
export default {
types: {
@@ -34,9 +36,10 @@ export default {
incident: __('Incident'),
issue: __('Issue'),
milestone: __('Milestone'),
+ release: __('Release'),
},
components: { BoardFilteredSearch },
- inject: ['isSignedIn'],
+ inject: ['isSignedIn', 'releasesFetchPath'],
props: {
fullPath: {
type: String,
@@ -57,7 +60,16 @@ export default {
: this.fullPath.slice(0, this.fullPath.lastIndexOf('/'));
},
tokensCE() {
- const { label, author, assignee, issue, incident, type, milestone } = this.$options.i18n;
+ const {
+ label,
+ author,
+ assignee,
+ issue,
+ incident,
+ type,
+ milestone,
+ release,
+ } = this.$options.i18n;
const { types } = this.$options;
const { fetchAuthors, fetchLabels } = issueBoardFilters(
this.$apollo,
@@ -144,6 +156,25 @@ export default {
{ icon: 'issue-type-incident', value: types.INCIDENT, title: incident },
],
},
+ {
+ type: 'release',
+ title: release,
+ icon: 'rocket',
+ token: ReleaseToken,
+ fetchReleases: (search) => {
+ // TODO: Switch to GraphQL query when backend is ready: https://gitlab.com/gitlab-org/gitlab/-/issues/337686
+ return axios
+ .get(joinPaths(gon.relative_url_root, this.releasesFetchPath))
+ .then(({ data }) => {
+ if (search) {
+ return fuzzaldrinPlus.filter(data, search, {
+ key: ['tag'],
+ });
+ }
+ return data;
+ });
+ },
+ },
];
},
tokens() {
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index 6fa8dd63245..ded3bfded86 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -110,7 +110,8 @@ export default () => {
});
if (gon?.features?.issueBoardsFilteredSearch) {
- initBoardsFilteredSearch(apolloProvider, isLoggedIn());
+ const { releasesFetchPath } = $boardApp.dataset;
+ initBoardsFilteredSearch(apolloProvider, isLoggedIn(), releasesFetchPath);
}
mountBoardApp($boardApp);
diff --git a/app/assets/javascripts/boards/mount_filtered_search_issue_boards.js b/app/assets/javascripts/boards/mount_filtered_search_issue_boards.js
index 1ea74d5685c..a8ade58e316 100644
--- a/app/assets/javascripts/boards/mount_filtered_search_issue_boards.js
+++ b/app/assets/javascripts/boards/mount_filtered_search_issue_boards.js
@@ -4,7 +4,7 @@ import store from '~/boards/stores';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { queryToObject } from '~/lib/utils/url_utility';
-export default (apolloProvider, isSignedIn) => {
+export default (apolloProvider, isSignedIn, releasesFetchPath) => {
const el = document.getElementById('js-issue-board-filtered-search');
const rawFilterParams = queryToObject(window.location.search, { gatherArrays: true });
@@ -21,6 +21,7 @@ export default (apolloProvider, isSignedIn) => {
provide: {
initialFilterParams,
isSignedIn,
+ releasesFetchPath,
},
store, // TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/324094
apolloProvider,
diff --git a/app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue b/app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue
index 0ba8c4f8907..a5e39e31024 100644
--- a/app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue
+++ b/app/assets/javascripts/sidebar/components/sidebar_dropdown_widget.vue
@@ -14,9 +14,10 @@ import createFlash from '~/flash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { IssuableType } from '~/issue_show/constants';
import { timeFor } from '~/lib/utils/datetime_utility';
-import { __, s__, sprintf } from '~/locale';
+import { __ } from '~/locale';
import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
import {
+ dropdowni18nText,
Tracking,
IssuableAttributeState,
IssuableAttributeType,
@@ -24,14 +25,11 @@ import {
noAttributeId,
defaultEpicSort,
epicIidPattern,
-} from '~/sidebar/constants';
+} from 'ee_else_ce/sidebar/constants';
export default {
noAttributeId,
- IssuableAttributeState,
- issuableAttributesQueries,
i18n: {
- [IssuableAttributeType.Milestone]: __('Milestone'),
expired: __('(expired)'),
none: __('None'),
},
@@ -53,14 +51,24 @@ export default {
isClassicSidebar: {
default: false,
},
+ issuableAttributesQueries: {
+ default: issuableAttributesQueries,
+ },
+ issuableAttributesState: {
+ default: IssuableAttributeState,
+ },
+ widgetTitleText: {
+ default: {
+ [IssuableAttributeType.Milestone]: __('Milestone'),
+ expired: __('(expired)'),
+ none: __('None'),
+ },
+ },
},
props: {
issuableAttribute: {
type: String,
required: true,
- validator(value) {
- return [IssuableAttributeType.Milestone].includes(value);
- },
},
workspacePath: {
required: true,
@@ -132,13 +140,13 @@ export default {
return {
fullPath: this.attrWorkspacePath,
title: this.searchTerm,
- state: this.$options.IssuableAttributeState[this.issuableAttribute],
+ state: this.issuableAttributesState[this.issuableAttribute],
};
}
const variables = {
fullPath: this.attrWorkspacePath,
- state: this.$options.IssuableAttributeState[this.issuableAttribute],
+ state: this.issuableAttributesState[this.issuableAttribute],
sort: defaultEpicSort,
};
@@ -180,7 +188,7 @@ export default {
},
computed: {
issuableAttributeQuery() {
- return this.$options.issuableAttributesQueries[this.issuableAttribute];
+ return this.issuableAttributesQueries[this.issuableAttribute];
},
attributeTitle() {
return this.currentAttribute?.title || this.i18n.noAttribute;
@@ -189,9 +197,7 @@ export default {
return this.currentAttribute?.webUrl;
},
dropdownText() {
- return this.currentAttribute
- ? this.currentAttribute?.title
- : this.$options.i18n[this.issuableAttribute];
+ return this.currentAttribute ? this.currentAttribute?.title : this.attributeTypeTitle;
},
loading() {
return this.$apollo.queries.currentAttribute.loading;
@@ -200,7 +206,7 @@ export default {
return this.attributesList.length === 0;
},
attributeTypeTitle() {
- return this.$options.i18n[this.issuableAttribute];
+ return this.widgetTitleText[this.issuableAttribute];
},
attributeTypeIcon() {
return this.icon || this.issuableAttribute;
@@ -209,37 +215,10 @@ export default {
return timeFor(this.currentAttribute?.dueDate);
},
i18n() {
- return {
- noAttribute: sprintf(s__('DropdownWidget|No %{issuableAttribute}'), {
- issuableAttribute: this.issuableAttribute,
- }),
- assignAttribute: sprintf(s__('DropdownWidget|Assign %{issuableAttribute}'), {
- issuableAttribute: this.issuableAttribute,
- }),
- noAttributesFound: sprintf(s__('DropdownWidget|No %{issuableAttribute} found'), {
- issuableAttribute: this.issuableAttribute,
- }),
- updateError: sprintf(
- s__(
- 'DropdownWidget|Failed to set %{issuableAttribute} on this %{issuableType}. Please try again.',
- ),
- { issuableAttribute: this.issuableAttribute, issuableType: this.issuableType },
- ),
- listFetchError: sprintf(
- s__(
- 'DropdownWidget|Failed to fetch the %{issuableAttribute} for this %{issuableType}. Please try again.',
- ),
- { issuableAttribute: this.issuableAttribute, issuableType: this.issuableType },
- ),
- currentFetchError: sprintf(
- s__(
- 'DropdownWidget|An error occurred while fetching the assigned %{issuableAttribute} of the selected %{issuableType}.',
- ),
- { issuableAttribute: this.issuableAttribute, issuableType: this.issuableType },
- ),
- };
+ return dropdowni18nText(this.issuableAttribute, this.issuableType);
},
isEpic() {
+ // MV to EE https://gitlab.com/gitlab-org/gitlab/-/issues/345311
return this.issuableAttribute === IssuableType.Epic;
},
},
@@ -252,7 +231,7 @@ export default {
const selectedAttribute =
Boolean(attributeId) && this.attributesList.find((p) => p.id === attributeId);
- this.selectedTitle = selectedAttribute ? selectedAttribute.title : this.$options.i18n.none;
+ this.selectedTitle = selectedAttribute ? selectedAttribute.title : this.widgetTitleText.none;
const { current } = this.issuableAttributeQuery;
const { mutation } = current[this.issuableType];
diff --git a/app/assets/javascripts/sidebar/constants.js b/app/assets/javascripts/sidebar/constants.js
index ac34a75ac5c..c2e16bbe6f9 100644
--- a/app/assets/javascripts/sidebar/constants.js
+++ b/app/assets/javascripts/sidebar/constants.js
@@ -1,3 +1,4 @@
+import { s__, sprintf } from '~/locale';
import updateIssueLabelsMutation from '~/boards/graphql/issue_set_labels.mutation.graphql';
import { IssuableType, WorkspaceType } from '~/issue_show/constants';
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
@@ -272,3 +273,35 @@ export const todoMutations = {
[TodoMutationTypes.Create]: todoCreateMutation,
[TodoMutationTypes.MarkDone]: todoMarkDoneMutation,
};
+
+export function dropdowni18nText(issuableAttribute, issuableType) {
+ return {
+ noAttribute: sprintf(s__('DropdownWidget|No %{issuableAttribute}'), {
+ issuableAttribute,
+ }),
+ assignAttribute: sprintf(s__('DropdownWidget|Assign %{issuableAttribute}'), {
+ issuableAttribute,
+ }),
+ noAttributesFound: sprintf(s__('DropdownWidget|No %{issuableAttribute} found'), {
+ issuableAttribute,
+ }),
+ updateError: sprintf(
+ s__(
+ 'DropdownWidget|Failed to set %{issuableAttribute} on this %{issuableType}. Please try again.',
+ ),
+ { issuableAttribute, issuableType },
+ ),
+ listFetchError: sprintf(
+ s__(
+ 'DropdownWidget|Failed to fetch the %{issuableAttribute} for this %{issuableType}. Please try again.',
+ ),
+ { issuableAttribute, issuableType },
+ ),
+ currentFetchError: sprintf(
+ s__(
+ 'DropdownWidget|An error occurred while fetching the assigned %{issuableAttribute} of the selected %{issuableType}.',
+ ),
+ { issuableAttribute, issuableType },
+ ),
+ };
+}
diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb
index c26a73028b9..57da04b38cc 100644
--- a/app/helpers/boards_helper.rb
+++ b/app/helpers/boards_helper.rb
@@ -23,6 +23,7 @@ module BoardsHelper
labels_filter_base_path: build_issue_link_base,
labels_fetch_path: labels_fetch_path,
labels_manage_path: labels_manage_path,
+ releases_fetch_path: releases_fetch_path,
board_type: board.to_type
}
end
@@ -65,6 +66,14 @@ module BoardsHelper
end
end
+ def releases_fetch_path
+ if board.group_board?
+ group_releases_path(@group)
+ else
+ project_releases_path(@project)
+ end
+ end
+
def board_base_url
if board.group_board?
group_boards_url(@group)