From f8000760f7030bdb41e4adb14b9189bb796a5450 Mon Sep 17 00:00:00 2001 From: Thomas Randolph Date: Fri, 7 Jun 2024 12:47:02 -0600 Subject: [PATCH 1/5] Add Label filter token to the MR list Vue app --- .../components/merge_requests_list_app.vue | 33 +++++++++++++++++++ .../javascripts/merge_requests/list/index.js | 2 ++ .../queries/get_merge_requests.query.graphql | 2 ++ .../list/queries/search_labels.query.graphql | 15 +++++++++ 4 files changed, 52 insertions(+) create mode 100644 app/assets/javascripts/merge_requests/list/queries/search_labels.query.graphql diff --git a/app/assets/javascripts/merge_requests/list/components/merge_requests_list_app.vue b/app/assets/javascripts/merge_requests/list/components/merge_requests_list_app.vue index 482578217a0948..bde04aa3ee641d 100644 --- a/app/assets/javascripts/merge_requests/list/components/merge_requests_list_app.vue +++ b/app/assets/javascripts/merge_requests/list/components/merge_requests_list_app.vue @@ -29,6 +29,8 @@ import { TOKEN_TYPE_REVIEWER, TOKEN_TITLE_MILESTONE, TOKEN_TYPE_MILESTONE, + TOKEN_TITLE_LABEL, + TOKEN_TYPE_LABEL, } from '~/vue_shared/components/filtered_search_bar/constants'; import { convertToApiParams, @@ -53,6 +55,7 @@ import setSortPreferenceMutation from '~/issues/list/queries/set_sort_preference import { i18n } from '../constants'; import getMergeRequestsQuery from '../queries/get_merge_requests.query.graphql'; import getMergeRequestsCountsQuery from '../queries/get_merge_requests_counts.query.graphql'; +import searchLabelsQuery from '../queries/search_labels.query.graphql'; import MergeRequestStatistics from './merge_request_statistics.vue'; import MergeRequestMoreActionsDropdown from './more_actions_dropdown.vue'; @@ -61,6 +64,8 @@ const BranchToken = () => import('~/vue_shared/components/filtered_search_bar/tokens/branch_token.vue'); const MilestoneToken = () => import('~/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue'); +const LabelToken = () => + import('~/vue_shared/components/filtered_search_bar/tokens/label_token.vue'); export default { i18n, @@ -75,6 +80,7 @@ export default { inject: [ 'fullPath', 'hasAnyMergeRequests', + 'hasScopedLabelsFeature', 'initialSort', 'isPublicVisibilityRestricted', 'isSignedIn', @@ -269,6 +275,15 @@ export default { isProject: true, fetchBranches: this.fetchBranches, }, + { + type: TOKEN_TYPE_LABEL, + title: TOKEN_TITLE_LABEL, + icon: 'labels', + token: LabelToken, + operators: OPERATORS_IS, + fetchLabels: this.fetchLabels, + recentSuggestionsStorageKey: `${this.fullPath}-merge_requests-recent-tokens-label`, + }, ]; }, showPaginationControls() { @@ -330,6 +345,23 @@ export default { }); }); }, + fetchLabelsWithFetchPolicy(search, fetchPolicy = fetchPolicies.CACHE_FIRST) { + return this.$apollo + .query({ + query: searchLabelsQuery, + variables: { fullPath: this.fullPath, search }, + fetchPolicy, + }) + .then(({ data }) => data.project.labels.nodes) + .then((labels) => + // TODO remove once we can search by title-only on the backend + // https://gitlab.com/gitlab-org/gitlab/-/issues/346353 + labels.filter((label) => label.title.toLowerCase().includes(search.toLowerCase())), + ); + }, + fetchLabels(search) { + return this.fetchLabelsWithFetchPolicy(search); + }, getStatus(mergeRequest) { if (mergeRequest.state === STATUS_CLOSED) { return this.$options.i18n.closed; @@ -428,6 +460,7 @@ export default { :namespace="fullPath" recent-searches-storage-key="merge_requests" :search-tokens="searchTokens" + :has-scoped-labels-feature="hasScopedLabelsFeature" :initial-filter-value="filterTokens" :sort-options="sortOptions" :initial-sort-by="sortKey" diff --git a/app/assets/javascripts/merge_requests/list/index.js b/app/assets/javascripts/merge_requests/list/index.js index 320d1f29fab99d..bccf220c8dda91 100644 --- a/app/assets/javascripts/merge_requests/list/index.js +++ b/app/assets/javascripts/merge_requests/list/index.js @@ -19,6 +19,7 @@ export async function mountMergeRequestListsApp() { const { fullPath, hasAnyMergeRequests, + hasScopedLabelsFeature, initialSort, isPublicVisibilityRestricted, isSignedIn, @@ -45,6 +46,7 @@ export async function mountMergeRequestListsApp() { provide: { fullPath, hasAnyMergeRequests: parseBoolean(hasAnyMergeRequests), + hasScopedLabelsFeature: parseBoolean(hasScopedLabelsFeature), initialSort, isPublicVisibilityRestricted: parseBoolean(isPublicVisibilityRestricted), isSignedIn: parseBoolean(isSignedIn), diff --git a/app/assets/javascripts/merge_requests/list/queries/get_merge_requests.query.graphql b/app/assets/javascripts/merge_requests/list/queries/get_merge_requests.query.graphql index ea81f5ea2baa0d..1bef7386a5d5fb 100644 --- a/app/assets/javascripts/merge_requests/list/queries/get_merge_requests.query.graphql +++ b/app/assets/javascripts/merge_requests/list/queries/get_merge_requests.query.graphql @@ -13,6 +13,7 @@ query getMergeRequests( $reviewerWildcardId: ReviewerWildcardId $authorUsername: String $draft: Boolean + $labelName: [String!] $milestoneTitle: String $milestoneWildcardId: MilestoneWildcardId $sourceBranches: [String!] @@ -33,6 +34,7 @@ query getMergeRequests( reviewerWildcardId: $reviewerWildcardId authorUsername: $authorUsername draft: $draft + labelName: $labelName milestoneTitle: $milestoneTitle milestoneWildcardId: $milestoneWildcardId sourceBranches: $sourceBranches diff --git a/app/assets/javascripts/merge_requests/list/queries/search_labels.query.graphql b/app/assets/javascripts/merge_requests/list/queries/search_labels.query.graphql new file mode 100644 index 00000000000000..ec4ff5119a5f04 --- /dev/null +++ b/app/assets/javascripts/merge_requests/list/queries/search_labels.query.graphql @@ -0,0 +1,15 @@ +query searchLabelsForMergeRequests($fullPath: ID!, $search: String) { + project(fullPath: $fullPath) @persist { + id + labels(searchTerm: $search, includeAncestorGroups: true) { + __persist + nodes { + __persist + id + color + textColor + title + } + } + } +} -- GitLab From 09add8ee0583cea139d2512035f0f8aff04025d3 Mon Sep 17 00:00:00 2001 From: Thomas Randolph Date: Wed, 19 Jun 2024 19:52:59 -0600 Subject: [PATCH 2/5] Match the IS/NOT filter of the non-Vue MR list --- .../merge_requests/list/components/merge_requests_list_app.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/merge_requests/list/components/merge_requests_list_app.vue b/app/assets/javascripts/merge_requests/list/components/merge_requests_list_app.vue index bde04aa3ee641d..22688bcda0dacf 100644 --- a/app/assets/javascripts/merge_requests/list/components/merge_requests_list_app.vue +++ b/app/assets/javascripts/merge_requests/list/components/merge_requests_list_app.vue @@ -15,6 +15,7 @@ import IssuableList from '~/vue_shared/issuable/list/components/issuable_list_ro import { DEFAULT_PAGE_SIZE, mergeRequestListTabs } from '~/vue_shared/issuable/list/constants'; import { OPERATORS_IS, + OPERATORS_IS_NOT, TOKEN_TITLE_AUTHOR, TOKEN_TYPE_AUTHOR, TOKEN_TITLE_DRAFT, @@ -280,7 +281,7 @@ export default { title: TOKEN_TITLE_LABEL, icon: 'labels', token: LabelToken, - operators: OPERATORS_IS, + operators: OPERATORS_IS_NOT, fetchLabels: this.fetchLabels, recentSuggestionsStorageKey: `${this.fullPath}-merge_requests-recent-tokens-label`, }, -- GitLab From 778619729a3d520fccfe793c8339582c736f95c9 Mon Sep 17 00:00:00 2001 From: Thomas Randolph Date: Wed, 19 Jun 2024 20:03:48 -0600 Subject: [PATCH 3/5] Test that the label token is available and used properly --- .../list/components/merge_requests_list_app_spec.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/frontend/merge_requests/list/components/merge_requests_list_app_spec.js b/spec/frontend/merge_requests/list/components/merge_requests_list_app_spec.js index 295631bfbcdd23..4ab42f1d9aeaf2 100644 --- a/spec/frontend/merge_requests/list/components/merge_requests_list_app_spec.js +++ b/spec/frontend/merge_requests/list/components/merge_requests_list_app_spec.js @@ -10,6 +10,7 @@ import { convertToGraphQLId } from '~/graphql_shared/utils'; import { TOKEN_TYPE_AUTHOR, TOKEN_TYPE_DRAFT, + TOKEN_TYPE_LABEL, TOKEN_TYPE_MILESTONE, TOKEN_TYPE_SOURCE_BRANCH, TOKEN_TYPE_TARGET_BRANCH, @@ -117,6 +118,7 @@ describe('Merge requests list app', () => { { type: TOKEN_TYPE_MILESTONE }, { type: TOKEN_TYPE_TARGET_BRANCH }, { type: TOKEN_TYPE_SOURCE_BRANCH }, + { type: TOKEN_TYPE_LABEL }, ]); }); }); @@ -126,6 +128,7 @@ describe('Merge requests list app', () => { assignee_username: 'bob', reviewer_username: 'bill', draft: 'yes', + 'label_name[]': 'fluff', milestone_title: 'milestone', 'target_branches[]': 'branch-a', 'source_branches[]': 'branch-b', @@ -163,6 +166,7 @@ describe('Merge requests list app', () => { { type: TOKEN_TYPE_MILESTONE }, { type: TOKEN_TYPE_TARGET_BRANCH }, { type: TOKEN_TYPE_SOURCE_BRANCH }, + { type: TOKEN_TYPE_LABEL }, ]); }); -- GitLab From 7af0be849378e8ed3b07bc482a8ce38e03523e91 Mon Sep 17 00:00:00 2001 From: Thomas Randolph Date: Wed, 19 Jun 2024 20:56:43 -0600 Subject: [PATCH 4/5] Fix missing scoped labels feature injection for tests --- .../list/components/merge_requests_list_app_spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/frontend/merge_requests/list/components/merge_requests_list_app_spec.js b/spec/frontend/merge_requests/list/components/merge_requests_list_app_spec.js index 4ab42f1d9aeaf2..04ab854a945a50 100644 --- a/spec/frontend/merge_requests/list/components/merge_requests_list_app_spec.js +++ b/spec/frontend/merge_requests/list/components/merge_requests_list_app_spec.js @@ -40,6 +40,7 @@ function createComponent({ provide = {} } = {}) { provide: { fullPath: 'gitlab-org/gitlab', hasAnyMergeRequests: true, + hasScopedLabelsFeature: false, initialSort: '', isPublicVisibilityRestricted: false, isSignedIn: true, -- GitLab From d37d57a338374e042a1bf814ffc84e973194f05a Mon Sep 17 00:00:00 2001 From: Thomas Randolph Date: Tue, 25 Jun 2024 17:11:59 -0600 Subject: [PATCH 5/5] Add missing label token to the pre-rendered tokens test --- .../list/components/merge_requests_list_app_spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/frontend/merge_requests/list/components/merge_requests_list_app_spec.js b/spec/frontend/merge_requests/list/components/merge_requests_list_app_spec.js index 04ab854a945a50..8cd993169648f0 100644 --- a/spec/frontend/merge_requests/list/components/merge_requests_list_app_spec.js +++ b/spec/frontend/merge_requests/list/components/merge_requests_list_app_spec.js @@ -176,6 +176,7 @@ describe('Merge requests list app', () => { { type: TOKEN_TYPE_ASSIGNEE }, { type: TOKEN_TYPE_REVIEWER }, { type: TOKEN_TYPE_DRAFT }, + { type: TOKEN_TYPE_LABEL }, { type: TOKEN_TYPE_MILESTONE }, { type: TOKEN_TYPE_TARGET_BRANCH }, { type: TOKEN_TYPE_SOURCE_BRANCH }, -- GitLab