diff --git a/.gitlab/ci/docs.gitlab-ci.yml b/.gitlab/ci/docs.gitlab-ci.yml index 10d4a17c045..74ba579310b 100644 --- a/.gitlab/ci/docs.gitlab-ci.yml +++ b/.gitlab/ci/docs.gitlab-ci.yml @@ -41,7 +41,7 @@ review-docs-cleanup: .docs-markdown-lint-image: # When updating the image version here, update it in /scripts/lint-doc.sh too. - image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-docs/lint-markdown:alpine-3.20-vale-3.6.1-markdownlint2-0.13.0-lychee-0.15.1 + image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-docs/lint-markdown:alpine-3.20-vale-3.7.1-markdownlint2-0.13.0-lychee-0.15.1 docs-lint markdown: extends: @@ -52,7 +52,6 @@ docs-lint markdown: stage: lint needs: [] script: - - apk add libuuid - source ./scripts/utils.sh - yarn_install_script - install_gitlab_gem diff --git a/Gemfile b/Gemfile index c903057722f..6bbf9d4ab33 100644 --- a/Gemfile +++ b/Gemfile @@ -256,7 +256,7 @@ gem 'asciidoctor-kroki', '~> 0.10.0', require: false # rubocop:todo Gemfile/Miss gem 'rouge', '~> 4.3.0', feature_category: :shared gem 'truncato', '~> 0.7.12' # rubocop:todo Gemfile/MissingFeatureCategory gem 'nokogiri', '~> 1.16' # rubocop:todo Gemfile/MissingFeatureCategory -gem 'gitlab-glfm-markdown', '~> 0.0.19', feature_category: :team_planning +gem 'gitlab-glfm-markdown', '~> 0.0.20', feature_category: :team_planning # Calendar rendering gem 'icalendar', '~> 2.10.1', feature_category: :system_access diff --git a/Gemfile.checksum b/Gemfile.checksum index 7cf3c16dc83..07008d3e09c 100644 --- a/Gemfile.checksum +++ b/Gemfile.checksum @@ -213,11 +213,11 @@ {"name":"gitlab-dangerfiles","version":"4.8.0","platform":"ruby","checksum":"b327d079552ec974a63bf34d749a0308425af6ebf51d01064f1a6ff216a523db"}, {"name":"gitlab-experiment","version":"0.9.1","platform":"ruby","checksum":"f230ee742154805a755d5f2539dc44d93cdff08c5bbbb7656018d61f93d01f48"}, {"name":"gitlab-fog-azure-rm","version":"2.1.0","platform":"ruby","checksum":"f5becd9e412a8c8f18f8ac061b8bc2562a354fb7a9f63d8cc1b301e6e6aa0bdd"}, -{"name":"gitlab-glfm-markdown","version":"0.0.19","platform":"aarch64-linux","checksum":"7cc4272cddb60c62745ac01e90368f1f11a5efbe8308a6df466eb3cca00b2c1a"}, -{"name":"gitlab-glfm-markdown","version":"0.0.19","platform":"arm64-darwin","checksum":"1aef2fe4ec251fdd00fe19c163f6ce94111128edd61623e7123b67bac0c74aed"}, -{"name":"gitlab-glfm-markdown","version":"0.0.19","platform":"ruby","checksum":"17a83a7ad1a63f2483a3c7fa75ecbc97467ec00123811793587995074f95811a"}, -{"name":"gitlab-glfm-markdown","version":"0.0.19","platform":"x86_64-darwin","checksum":"370a5706058219acaad5e856f4dafd3b6f76ac45222ed53d6edd0b284dc99dde"}, -{"name":"gitlab-glfm-markdown","version":"0.0.19","platform":"x86_64-linux","checksum":"d7d6e06e22669bd02c4fa5fbbca091e0f43a263bfd74fedb1fd974a5150d6fec"}, +{"name":"gitlab-glfm-markdown","version":"0.0.20","platform":"aarch64-linux","checksum":"3ef33ad9374467c309e1ca318f42379ec01cf72ffffeb8f1a7eb3919416db619"}, +{"name":"gitlab-glfm-markdown","version":"0.0.20","platform":"arm64-darwin","checksum":"2e97dcd7d23b9ada3db3bc5eaa3a39d710ef9df93ad68d438df92e835c64c19e"}, +{"name":"gitlab-glfm-markdown","version":"0.0.20","platform":"ruby","checksum":"8c5057f980d7c6c5bf78de3673eddf825095433f923cdab21603f715da63acd2"}, +{"name":"gitlab-glfm-markdown","version":"0.0.20","platform":"x86_64-darwin","checksum":"58396e74002e514ff1ad87b8e97d6e69e735ca4c6cd57f1d233c9b06ff95a045"}, +{"name":"gitlab-glfm-markdown","version":"0.0.20","platform":"x86_64-linux","checksum":"20138aeaa968450897cbfdc67c351c87fa8d514c1bef667424cbcb10ed7c5cbe"}, {"name":"gitlab-kas-grpc","version":"17.4.0.pre.rc1","platform":"ruby","checksum":"37679435a3e71b830b215741e78714984c3392fbc09d660b3102e4a5e6ab92ca"}, {"name":"gitlab-labkit","version":"0.36.1","platform":"ruby","checksum":"04fb6941b7e5fc1fdcee8f9971fa2086a4dc442e39e67a74b992403dd580c300"}, {"name":"gitlab-license","version":"2.5.0","platform":"ruby","checksum":"4c166c469c2ad17876ca43188a4ccebe3feb0726c4c1770047f8dcef96573f4d"}, diff --git a/Gemfile.lock b/Gemfile.lock index 7c1cd623cd7..26b70c050ad 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -724,7 +724,7 @@ GEM mime-types net-http-persistent (~> 4.0) nokogiri (~> 1, >= 1.10.8) - gitlab-glfm-markdown (0.0.19) + gitlab-glfm-markdown (0.0.20) rb_sys (= 0.9.94) gitlab-kas-grpc (17.4.0.pre.rc1) grpc (~> 1.0) @@ -2054,7 +2054,7 @@ DEPENDENCIES gitlab-duo-workflow-service-client (~> 0.1)! gitlab-experiment (~> 0.9.1) gitlab-fog-azure-rm (~> 2.1.0) - gitlab-glfm-markdown (~> 0.0.19) + gitlab-glfm-markdown (~> 0.0.20) gitlab-housekeeper! gitlab-http! gitlab-kas-grpc (~> 17.4.0.pre.rc1) diff --git a/app/assets/javascripts/merge_request_dashboard/components/collapsible_section.vue b/app/assets/javascripts/merge_request_dashboard/components/collapsible_section.vue index c1bc254bfec..4263edcb0b3 100644 --- a/app/assets/javascripts/merge_request_dashboard/components/collapsible_section.vue +++ b/app/assets/javascripts/merge_request_dashboard/components/collapsible_section.vue @@ -75,7 +75,7 @@ export default { @click="toggleOpen" /> {{ title }} - {{ + {{ count }} diff --git a/app/assets/javascripts/merge_request_dashboard/components/merge_requests_query.vue b/app/assets/javascripts/merge_request_dashboard/components/merge_requests_query.vue index fb945d57612..573b7afcf32 100644 --- a/app/assets/javascripts/merge_request_dashboard/components/merge_requests_query.vue +++ b/app/assets/javascripts/merge_request_dashboard/components/merge_requests_query.vue @@ -18,7 +18,7 @@ export default { return QUERIES[this.query]; }, update(d) { - return d.currentUser?.[this.query] || {}; + return d.currentUser?.mergeRequests || {}; }, variables() { return { diff --git a/app/assets/javascripts/merge_request_dashboard/index.js b/app/assets/javascripts/merge_request_dashboard/index.js index 1020ef320f2..10a37d133fb 100644 --- a/app/assets/javascripts/merge_request_dashboard/index.js +++ b/app/assets/javascripts/merge_request_dashboard/index.js @@ -9,6 +9,16 @@ export function initMergeRequestDashboard(el) { const { lists, switch_dashboard_path: switchDashboardPath } = JSON.parse(el.dataset.initialData); + const keyArgs = [ + 'state', + 'reviewState', + 'reviewStates', + 'reviewerWildcardId', + 'mergedAfter', + 'assignedReviewStates', + 'reviewerReviewStates', + ]; + return new Vue({ el, apolloProvider: new VueApollo({ @@ -18,19 +28,15 @@ export function initMergeRequestDashboard(el) { cacheConfig: { typePolicies: { CurrentUser: { - merge: true, fields: { - reviewRequestedMergeRequests: { - keyArgs: ['state', 'reviewState', 'reviewStates', 'mergedAfter'], - }, assignedMergeRequests: { - keyArgs: [ - 'state', - 'reviewState', - 'reviewStates', - 'reviewerWildcardId', - 'mergedAfter', - ], + keyArgs, + }, + reviewRequestedMergeRequests: { + keyArgs, + }, + assigneeOrReviewerMergeRequests: { + keyArgs, }, }, }, @@ -39,10 +45,8 @@ export function initMergeRequestDashboard(el) { nodes: concatPagination(), }, }, - UserMergeRequestInteraction: { - merge(a) { - return a; - }, + MergeRequestReviewer: { + keyFields: false, }, }, }, diff --git a/app/assets/javascripts/merge_request_dashboard/queries/assignee.query.graphql b/app/assets/javascripts/merge_request_dashboard/queries/assignee.query.graphql index 5633512062a..25dc21a07b2 100644 --- a/app/assets/javascripts/merge_request_dashboard/queries/assignee.query.graphql +++ b/app/assets/javascripts/merge_request_dashboard/queries/assignee.query.graphql @@ -12,7 +12,7 @@ query requestingReview( ) { currentUser { id - assignedMergeRequests( + mergeRequests: assignedMergeRequests( state: $state reviewState: $reviewState reviewStates: $reviewStates diff --git a/app/assets/javascripts/merge_request_dashboard/queries/assignee_or_reviewer.query.graphql b/app/assets/javascripts/merge_request_dashboard/queries/assignee_or_reviewer.query.graphql index fc217c2e4c4..5a743656a19 100644 --- a/app/assets/javascripts/merge_request_dashboard/queries/assignee_or_reviewer.query.graphql +++ b/app/assets/javascripts/merge_request_dashboard/queries/assignee_or_reviewer.query.graphql @@ -11,7 +11,7 @@ query assigneeOrReviewer( ) { currentUser { id - assigneeOrReviewerMergeRequests( + mergeRequests: assigneeOrReviewerMergeRequests( state: $state assignedReviewStates: $assignedReviewStates reviewerReviewStates: $reviewerReviewStates diff --git a/app/assets/javascripts/merge_request_dashboard/queries/reviewer.query.graphql b/app/assets/javascripts/merge_request_dashboard/queries/reviewer.query.graphql index 875edd3a539..fbdfcb46c06 100644 --- a/app/assets/javascripts/merge_request_dashboard/queries/reviewer.query.graphql +++ b/app/assets/javascripts/merge_request_dashboard/queries/reviewer.query.graphql @@ -11,7 +11,7 @@ query reviewRequests( ) { currentUser { id - reviewRequestedMergeRequests( + mergeRequests: reviewRequestedMergeRequests( state: $state reviewState: $reviewState reviewStates: $reviewStates diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue index a08a41f8393..d3b69cfc488 100644 --- a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue +++ b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue @@ -416,7 +416,7 @@ export default { }, }, showDuoSettings() { - return this.licensedAiFeaturesAvailable && this.glFeatures.aiSettingsVueProject; + return this.licensedAiFeaturesAvailable; }, }, diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/view/index.vue b/app/assets/javascripts/projects/settings/branch_rules/components/view/index.vue index 96522fca2a7..3c3c8b4477b 100644 --- a/app/assets/javascripts/projects/settings/branch_rules/components/view/index.vue +++ b/app/assets/javascripts/projects/settings/branch_rules/components/view/index.vue @@ -443,19 +443,6 @@ export default { @edit="openAllowedToMergeDrawer" /> - - + + import('ee_component/projects/settings/branch_rules/components/view/items_selector.vue'), }, + inject: { + showEnterpriseAccessLevels: { default: false }, + }, props: { isOpen: { type: Boolean, @@ -78,6 +81,11 @@ export default { type: Boolean, required: true, }, + isPushAccessLevels: { + type: Boolean, + required: false, + default: false, + }, }, data() { return { @@ -193,20 +201,23 @@ export default { }} + - - this.openCreateRuleModal() }, ]; - [this.$options.i18n.allBranches, this.$options.i18n.allProtectedBranches].forEach( - (branch) => { - if (!this.hasPredefinedBranchRule(branch)) { - items.push(this.createPredefinedBrachRulesItem(branch)); - } - }, - ); + if (this.showApprovers || this.showStatusChecks) { + [this.$options.i18n.allBranches, this.$options.i18n.allProtectedBranches].forEach( + (branch) => { + if (!this.hasPredefinedBranchRule(branch)) { + items.push(this.createPredefinedBrachRulesItem(branch)); + } + }, + ); + } return items; }, diff --git a/app/assets/javascripts/search/sidebar/components/label_filter/data.js b/app/assets/javascripts/search/sidebar/components/label_filter/data.js index 654357da902..2d1e52d256f 100644 --- a/app/assets/javascripts/search/sidebar/components/label_filter/data.js +++ b/app/assets/javascripts/search/sidebar/components/label_filter/data.js @@ -8,16 +8,8 @@ export const SEARCH_INPUT_DESCRIPTION = 'label-search-input-description'; export const SEARCH_RESULTS_DESCRIPTION = 'label-search-results-description'; -const header = __('Labels'); +export const LABEL_FILTER_HEADER = __('Labels'); -const scopes = { - ISSUES: 'issues', -}; +export const LABEL_FILTER_PARAM = 'label_name'; -const filterParam = 'labels'; - -export const labelFilterData = { - header, - scopes, - filterParam, -}; +export const LABEL_AGREGATION_NAME = 'labels'; diff --git a/app/assets/javascripts/search/sidebar/components/label_filter/index.vue b/app/assets/javascripts/search/sidebar/components/label_filter/index.vue index b75c966be48..da77e87b274 100644 --- a/app/assets/javascripts/search/sidebar/components/label_filter/index.vue +++ b/app/assets/javascripts/search/sidebar/components/label_filter/index.vue @@ -12,7 +12,7 @@ import { } from '@gitlab/ui'; // eslint-disable-next-line no-restricted-imports import { mapActions, mapState, mapGetters } from 'vuex'; -import { uniq } from 'lodash'; +import { difference, uniq } from 'lodash'; import { rgbFromHex } from '@gitlab/ui/dist/utils/utils'; import { slugify } from '~/lib/utils/text_utility'; @@ -26,7 +26,8 @@ import { SEARCH_BOX_INDEX, SEARCH_RESULTS_DESCRIPTION, SEARCH_INPUT_DESCRIPTION, - labelFilterData, + LABEL_FILTER_PARAM, + LABEL_FILTER_HEADER, } from './data'; import { trackSelectCheckbox, trackOpenDropdown } from './tracking'; @@ -50,6 +51,7 @@ export default { return { currentFocusIndex: SEARCH_BOX_INDEX, isFocused: false, + combinedSelectedLabels: [], }; }, i18n: I18N, @@ -83,7 +85,6 @@ export default { combinedSelectedFilters() { const appliedSelectedLabelKeys = this.appliedSelectedLabels.map((label) => label.key); const { labels = [] } = this.query; - return uniq([...appliedSelectedLabelKeys, ...labels]); }, searchLabels: { @@ -96,16 +97,30 @@ export default { }, selectedLabels: { get() { - return this.combinedSelectedFilters; + return this.combinedSelectedLabels; }, set(value) { - this.setQuery({ key: this.$options.labelFilterData?.filterParam, value }); + const labelName = this.getLabelNameById(value); + this.setQuery({ key: this.$options.LABEL_FILTER_PARAM, value: labelName }); trackSelectCheckbox(value); }, }, }, + watch: { + combinedSelectedFilters(newLabels, oldLabels) { + const hasDifference = difference(newLabels, oldLabels).length > 0; + if (hasDifference) { + this.combinedSelectedLabels = newLabels; + } + }, + filteredAppliedSelectedLabels(newCount, oldCount) { + if (newCount.length !== oldCount.length) { + this.currentFocusIndex = FIRST_DROPDOWN_INDEX; + } + }, + }, async created() { - if (this.urlQuery?.[labelFilterData.filterParam]?.length > 0) { + if (this.urlQuery?.[LABEL_FILTER_PARAM]?.length > 0) { await this.fetchAllAggregation(); } }, @@ -136,24 +151,34 @@ export default { return; } - const { key } = event.target.closest('.gl-label').dataset; - this.closeLabel({ key }); + const { title } = event.target.closest('.gl-label').dataset; + this.closeLabel({ title }); }, inactiveLabelColor(label) { return `rgba(${rgbFromHex(label.color)}, 0.3)`; }, + getLabelNameById(labelIds) { + const labelNames = labelIds.map((id) => { + const label = this.filteredLabels.find((filteredLabel) => { + return filteredLabel.key === String(id); + }); + return label?.title; + }); + return labelNames; + }, }, FIRST_DROPDOWN_INDEX, SEARCH_RESULTS_DESCRIPTION, SEARCH_INPUT_DESCRIPTION, - labelFilterData, + LABEL_FILTER_PARAM, + LABEL_FILTER_HEADER, };