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:
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.checksum13
-rw-r--r--Gemfile.lock6
-rw-r--r--app/assets/javascripts/feature_flags/components/form.vue20
-rw-r--r--app/assets/javascripts/merge_request.js6
-rw-r--r--app/assets/javascripts/mr_more_dropdown.js57
-rw-r--r--app/assets/javascripts/pages/projects/merge_requests/show/index.js2
-rw-r--r--app/assets/javascripts/sidebar/components/lock/issuable_lock_form.vue115
-rw-r--r--app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue35
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merging.vue1
-rw-r--r--app/assets/javascripts/vue_shared/components/mr_more_dropdown.vue361
-rw-r--r--app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml68
-rw-r--r--config/metrics/counts_28d/20210216180308_personal_snippets.yml1
-rw-r--r--config/metrics/counts_28d/20210216180310_project_snippets.yml1
-rw-r--r--config/metrics/counts_28d/20210216180312_snippets.yml1
-rw-r--r--config/metrics/counts_all/20210216180239_personal_snippets.yml1
-rw-r--r--config/metrics/counts_all/20210216180241_project_snippets.yml1
-rw-r--r--config/metrics/counts_all/20210216180306_snippets.yml1
-rw-r--r--doc/administration/auth/ldap/ldap-troubleshooting.md9
-rw-r--r--doc/administration/auth/ldap/ldap_synchronization.md6
-rw-r--r--doc/administration/geo/disaster_recovery/background_verification.md12
-rw-r--r--doc/administration/geo/disaster_recovery/planned_failover.md15
-rw-r--r--doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md12
-rw-r--r--doc/administration/geo/disaster_recovery/runbooks/planned_failover_single_node.md9
-rw-r--r--doc/administration/geo/index.md4
-rw-r--r--doc/administration/geo/replication/configuration.md9
-rw-r--r--doc/administration/geo/replication/container_registry.md3
-rw-r--r--doc/administration/geo/replication/disable_geo.md3
-rw-r--r--doc/administration/geo/replication/object_storage.md3
-rw-r--r--doc/administration/geo/replication/remove_geo_site.md3
-rw-r--r--doc/administration/geo/replication/troubleshooting.md18
-rw-r--r--doc/administration/geo/replication/tuning.md3
-rw-r--r--doc/administration/gitaly/praefect.md3
-rw-r--r--doc/administration/gitaly/troubleshooting.md3
-rw-r--r--doc/administration/integration/diagrams_net.md3
-rw-r--r--doc/administration/integration/kroki.md3
-rw-r--r--doc/administration/integration/mailgun.md3
-rw-r--r--doc/administration/integration/plantuml.md3
-rw-r--r--doc/administration/integration/terminal.md6
-rw-r--r--doc/administration/maintenance_mode/index.md9
-rw-r--r--doc/administration/monitoring/performance/gitlab_configuration.md3
-rw-r--r--doc/administration/monitoring/performance/grafana_configuration.md3
-rw-r--r--doc/administration/monitoring/performance/performance_bar.md3
-rw-r--r--doc/administration/monitoring/prometheus/gitlab_metrics.md3
-rw-r--r--doc/administration/operations/fast_ssh_key_lookup.md6
-rw-r--r--doc/administration/packages/container_registry.md3
-rw-r--r--doc/administration/pages/source.md3
-rw-r--r--doc/administration/pages/troubleshooting.md3
-rw-r--r--doc/administration/raketasks/storage.md3
-rw-r--r--doc/administration/sidekiq/extra_sidekiq_processes.md3
-rw-r--r--doc/user/clusters/agent/vulnerabilities.md35
-rw-r--r--doc/user/project/integrations/telegram.md5
-rw-r--r--lib/gitlab/error_tracking/processor/grpc_error_processor.rb3
-rw-r--r--lib/gitlab/usage/metrics/instrumentations/count_personal_snippets_metric.rb17
-rw-r--r--lib/gitlab/usage/metrics/instrumentations/count_project_snippets_metric.rb17
-rw-r--r--lib/gitlab/usage/metrics/instrumentations/count_snippets_metric.rb35
-rw-r--r--lib/gitlab/usage_data.rb12
-rw-r--r--locale/gitlab.pot31
-rw-r--r--spec/features/merge_request/close_reopen_report_toggle_spec.rb46
-rw-r--r--spec/features/merge_request/merge_request_discussion_lock_spec.rb4
-rw-r--r--spec/features/merge_request/user_manages_subscription_spec.rb6
-rw-r--r--spec/features/merge_request/user_marks_merge_request_as_draft_spec.rb8
-rw-r--r--spec/frontend/merge_request_spec.js17
-rw-r--r--spec/frontend/sidebar/components/lock/issuable_lock_form_spec.js8
-rw-r--r--spec/frontend/sidebar/components/subscriptions/sidebar_subscriptions_widget_spec.js5
-rw-r--r--spec/frontend/vue_shared/components/mr_more_dropdown_spec.js137
-rw-r--r--spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js22
-rw-r--r--spec/lib/gitlab/usage/metrics/instrumentations/count_personal_snippets_metric_spec.rb22
-rw-r--r--spec/lib/gitlab/usage/metrics/instrumentations/count_project_snippets_metric_spec.rb22
-rw-r--r--spec/lib/gitlab/usage/metrics/instrumentations/count_snippets_metric_spec.rb25
-rw-r--r--spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb4
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb8
-rw-r--r--spec/support/helpers/usage_data_helpers.rb3
-rw-r--r--spec/support/rspec_order_todo.yml1
-rw-r--r--spec/support/shared_contexts/issuable/merge_request_shared_context.rb24
-rw-r--r--spec/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml_spec.rb34
-rw-r--r--spec/views/projects/merge_requests/show.html.haml_spec.rb45
78 files changed, 1097 insertions, 368 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 3982254e492..8855008082f 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-3ee3de216e2e3d0fe4c6abe35481b41af0c68223
+d3bb9a8fe1d9ff265edf3920c348b2d5993ca0a8
diff --git a/Gemfile b/Gemfile
index e73172d34a5..4e311135281 100644
--- a/Gemfile
+++ b/Gemfile
@@ -514,7 +514,7 @@ gem 'gitaly', '~> 16.1.0-rc1'
# KAS GRPC protocol definitions
gem 'kas-grpc', '~> 0.1.0'
-gem 'grpc', '~> 1.55.0'
+gem 'grpc', '~> 1.42.0'
gem 'google-protobuf', '~> 3.23', '>= 3.23.2'
diff --git a/Gemfile.checksum b/Gemfile.checksum
index 216acff381b..17e0167bb38 100644
--- a/Gemfile.checksum
+++ b/Gemfile.checksum
@@ -267,13 +267,12 @@
{"name":"graphql","version":"1.13.12","platform":"ruby","checksum":"1d82666cf201193a8d0cb54cea38576b820418db4869b549f61a35f3a2d97ac3"},
{"name":"graphql-client","version":"0.17.0","platform":"ruby","checksum":"5aaf02ce8f2dbc8e3ba05a7eaeb3ad9336762c4424c6093f4438fbb9490eeb5d"},
{"name":"graphql-docs","version":"2.1.0","platform":"ruby","checksum":"7eb82402f8fda455104b2b60364e9ada145d79d3121a8f915790d49da38bb576"},
-{"name":"grpc","version":"1.55.0","platform":"ruby","checksum":"529332f8e5e98f5b138afd5c4a9c7bdc9e247f4c10c84c1adbf1a114eba161ae"},
-{"name":"grpc","version":"1.55.0","platform":"x64-mingw-ucrt","checksum":"6b5c7b7358476469c5ecb46f35e1eff6983efc9395d9db8db0a2eb4207c82ffb"},
-{"name":"grpc","version":"1.55.0","platform":"x64-mingw32","checksum":"73755c256fc0fe5361a979cd609414ebdaa5862f5821fba20ea31110f1d87405"},
-{"name":"grpc","version":"1.55.0","platform":"x86-linux","checksum":"37c20569a17b1cff91155f193b0df41eb42fd0aed9051fa91ccca273a259e393"},
-{"name":"grpc","version":"1.55.0","platform":"x86-mingw32","checksum":"6b4144b5af8086b46b2e62b5fbda50fc19105a4efefafaca63e15b0384c42274"},
-{"name":"grpc","version":"1.55.0","platform":"x86_64-darwin","checksum":"d7f57eb84811d7ea2a9464ec88d9296a92801f643a4d7cf76cf4896edf12a25c"},
-{"name":"grpc","version":"1.55.0","platform":"x86_64-linux","checksum":"4ee73555759774db22ba23ff79c332cce7ae08b0ba4d4b33ab4747e83e0a8518"},
+{"name":"grpc","version":"1.42.0","platform":"ruby","checksum":"b3d2649e67c6a636544996843d9ec191699c54c1aca797dbfea4dff36c14584a"},
+{"name":"grpc","version":"1.42.0","platform":"x64-mingw32","checksum":"6aac1b6576134b0a83e000b1269f60d502eb24aee96c64e2658c3f24f8e32ac0"},
+{"name":"grpc","version":"1.42.0","platform":"x86-linux","checksum":"4aa50538aa929f1f3bcefb11c65ee1a1606b5aef838ea4d4e93c100b5f4263a5"},
+{"name":"grpc","version":"1.42.0","platform":"x86-mingw32","checksum":"eeb2a9381bea43fafe879b6ddaa011351a44d0894d48bdc965a07bcb67c6eb56"},
+{"name":"grpc","version":"1.42.0","platform":"x86_64-darwin","checksum":"20fa202d46d8a055628260622e98fb6439529fbac283f0552af620b909f78535"},
+{"name":"grpc","version":"1.42.0","platform":"x86_64-linux","checksum":"92e2ceb2aca335d5755163dd8030082091d5b0e63c117b1ca07051b66c53eb2e"},
{"name":"gssapi","version":"1.3.1","platform":"ruby","checksum":"c51cf30842ee39bd93ce7fc33e20405ff8a04cda9dec6092071b61258284aee1"},
{"name":"guard","version":"2.16.2","platform":"ruby","checksum":"71ba7abaddecc8be91ab77bbaf78f767246603652ebbc7b976fda497ebdc8fbb"},
{"name":"guard-compat","version":"1.2.1","platform":"ruby","checksum":"3ad21ab0070107f92edfd82610b5cdc2fb8e368851e72362ada9703443d646fe"},
diff --git a/Gemfile.lock b/Gemfile.lock
index dfddd61fdc1..6868c807042 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -753,8 +753,8 @@ GEM
graphql (~> 1.12)
html-pipeline (~> 2.9)
sass (~> 3.4)
- grpc (1.55.0)
- google-protobuf (~> 3.23)
+ grpc (1.42.0)
+ google-protobuf (~> 3.18)
googleapis-common-protos-types (~> 1.0)
gssapi (1.3.1)
ffi (>= 1.0.1)
@@ -1789,7 +1789,7 @@ DEPENDENCIES
graphlyte (~> 1.0.0)
graphql (~> 1.13.12)
graphql-docs (~> 2.1.0)
- grpc (~> 1.55.0)
+ grpc (~> 1.42.0)
gssapi (~> 1.3.1)
guard-rspec
haml_lint (~> 0.40.0)
diff --git a/app/assets/javascripts/feature_flags/components/form.vue b/app/assets/javascripts/feature_flags/components/form.vue
index 8b79c661b12..35abcc3d561 100644
--- a/app/assets/javascripts/feature_flags/components/form.vue
+++ b/app/assets/javascripts/feature_flags/components/form.vue
@@ -157,16 +157,18 @@ export default {
<template>
<form class="feature-flags-form">
<fieldset>
- <div class="row">
- <div class="form-group col-md-4">
- <label for="feature-flag-name" class="label-bold">{{ s__('FeatureFlags|Name') }} *</label>
+ <div class="gl-display-flex gl-flex-wrap gl-mx-n5">
+ <div class="gl-mb-5 gl-px-5 gl-w-full col-md-4">
+ <label for="feature-flag-name" class="gl-font-weight-bold"
+ >{{ s__('FeatureFlags|Name') }} *</label
+ >
<input id="feature-flag-name" v-model="formName" class="form-control" />
</div>
</div>
- <div class="row">
- <div class="form-group col-md-4">
- <label for="feature-flag-description" class="label-bold">
+ <div class="gl-display-flex gl-flex-wrap gl-mx-n5">
+ <div class="gl-mb-5 gl-px-5 gl-w-full col-md-4">
+ <label for="feature-flag-description" class="gl-font-weight-bold">
{{ s__('FeatureFlags|Description') }}
</label>
<textarea
@@ -185,8 +187,8 @@ export default {
:show-categorized-issues="false"
/>
- <div class="row">
- <div class="col-md-12">
+ <div class="gl-display-flex gl-flex-wrap gl-mx-n5">
+ <div class="gl-mb-5 gl-px-5 gl-w-full">
<h4>{{ s__('FeatureFlags|Strategies') }}</h4>
<div class="gl-display-flex gl-align-items-baseline gl-justify-content-space-between">
<p class="gl-mr-5">{{ $options.translations.newHelpText }}</p>
@@ -206,7 +208,7 @@ export default {
@delete="deleteStrategy(strategy)"
/>
</div>
- <div v-else class="gl-display-flex gl-justify-content-center gl-border-t gl-py-6 w-100">
+ <div v-else class="gl-display-flex gl-justify-content-center gl-border-t gl-py-6 gl-w-full">
<span>{{ $options.translations.noStrategiesText }}</span>
</div>
</fieldset>
diff --git a/app/assets/javascripts/merge_request.js b/app/assets/javascripts/merge_request.js
index 4277e535d20..1e02703cbe7 100644
--- a/app/assets/javascripts/merge_request.js
+++ b/app/assets/javascripts/merge_request.js
@@ -145,12 +145,6 @@ MergeRequest.decreaseCounter = function (by = 1) {
$el.text(addDelimiter(count));
};
-MergeRequest.hideCloseButton = function () {
- const el = document.querySelector('.merge-request .js-issuable-actions');
- // Dropdown for mobile screen
- el.querySelector('li.js-close-item').classList.add('hidden');
-};
-
MergeRequest.toggleDraftStatus = function (title, isReady) {
if (!window.gon?.features?.realtimeMrStatusChange) {
eventHub.$emit('MRWidgetUpdateRequested');
diff --git a/app/assets/javascripts/mr_more_dropdown.js b/app/assets/javascripts/mr_more_dropdown.js
new file mode 100644
index 00000000000..720619b72ae
--- /dev/null
+++ b/app/assets/javascripts/mr_more_dropdown.js
@@ -0,0 +1,57 @@
+import Vue from 'vue';
+import MrMoreDropdown from '~/vue_shared/components/mr_more_dropdown.vue';
+
+export const initMrMoreDropdown = () => {
+ const el = document.querySelector('.js-mr-more-dropdown');
+
+ if (!el) {
+ return false;
+ }
+
+ const {
+ mergeRequest,
+ projectPath,
+ editUrl,
+ isCurrentUser,
+ isLoggedIn,
+ canUpdateMergeRequest,
+ open,
+ merged,
+ sourceProjectMissing,
+ clipboardText,
+ reportedUserId,
+ reportedFromUrl,
+ } = el.dataset;
+
+ let mr;
+
+ try {
+ mr = JSON.parse(mergeRequest);
+ } catch {
+ mr = {};
+ }
+
+ return new Vue({
+ el,
+ provide: {
+ reportAbusePath: el.dataset.reportAbusePath,
+ },
+ render: (createElement) =>
+ createElement(MrMoreDropdown, {
+ props: {
+ mr,
+ projectPath,
+ editUrl,
+ isCurrentUser,
+ isLoggedIn: Boolean(isLoggedIn),
+ canUpdateMergeRequest,
+ open,
+ isMerged: merged,
+ sourceProjectMissing,
+ clipboardText,
+ reportedUserId: Number(reportedUserId),
+ reportedFromUrl,
+ },
+ }),
+ });
+};
diff --git a/app/assets/javascripts/pages/projects/merge_requests/show/index.js b/app/assets/javascripts/pages/projects/merge_requests/show/index.js
index 38cc4337047..67dc3782a24 100644
--- a/app/assets/javascripts/pages/projects/merge_requests/show/index.js
+++ b/app/assets/javascripts/pages/projects/merge_requests/show/index.js
@@ -1,7 +1,9 @@
import mountNotesApp from 'ee_else_ce/mr_notes/mount_app';
import { initReportAbuse } from '~/projects/report_abuse';
+import { initMrMoreDropdown } from '~/mr_more_dropdown';
import { initMrPage } from '../page';
initMrPage();
mountNotesApp();
initReportAbuse();
+initMrMoreDropdown();
diff --git a/app/assets/javascripts/sidebar/components/lock/issuable_lock_form.vue b/app/assets/javascripts/sidebar/components/lock/issuable_lock_form.vue
index 06876546fa4..1d9233db361 100644
--- a/app/assets/javascripts/sidebar/components/lock/issuable_lock_form.vue
+++ b/app/assets/javascripts/sidebar/components/lock/issuable_lock_form.vue
@@ -1,9 +1,14 @@
<script>
-import { GlIcon, GlTooltipDirective, GlOutsideDirective as Outside } from '@gitlab/ui';
+import {
+ GlIcon,
+ GlLoadingIcon,
+ GlDisclosureDropdownItem,
+ GlTooltipDirective,
+ GlOutsideDirective as Outside,
+} from '@gitlab/ui';
import { mapGetters, mapActions } from 'vuex';
import { TYPE_ISSUE } from '~/issues/constants';
import { __, sprintf } from '~/locale';
-import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { createAlert } from '~/alert';
import toast from '~/vue_shared/plugins/global_toast';
@@ -15,17 +20,17 @@ export default {
icon: 'lock',
class: 'value',
iconClass: 'is-active',
- displayText: __('Locked'),
},
unlocked: {
class: ['no-value hide-collapsed'],
icon: 'lock-open',
iconClass: '',
- displayText: __('Unlocked'),
},
components: {
EditForm,
GlIcon,
+ GlLoadingIcon,
+ GlDisclosureDropdownItem,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -39,8 +44,23 @@ export default {
type: Boolean,
},
},
+ i18n: {
+ issue: __('issue'),
+ issueCapitalized: __('Issue'),
+ mergeRequest: __('merge request'),
+ mergeRequestCapitalized: __('Merge request'),
+ locked: __('Locked'),
+ unlocked: __('Unlocked'),
+ lockingMergeRequest: __('Locking %{issuableDisplayName}'),
+ unlockingMergeRequest: __('Unlocking %{issuableDisplayName}'),
+ lockMergeRequest: __('Lock %{issuableDisplayName}'),
+ unlockMergeRequest: __('Unlock %{issuableDisplayName}'),
+ lockedMessage: __('%{issuableDisplayName} locked.'),
+ unlockedMessage: __('%{issuableDisplayName} unlocked.'),
+ },
data() {
return {
+ isLoading: false,
isLockDialogOpen: false,
};
},
@@ -49,18 +69,61 @@ export default {
isMovedMrSidebar() {
return this.glFeatures.movedMrSidebar;
},
+ isIssuable() {
+ return this.getNoteableData.targetType === TYPE_ISSUE;
+ },
issuableDisplayName() {
- const isInIssuePage = this.getNoteableData.targetType === TYPE_ISSUE;
- return isInIssuePage ? __('issue') : __('merge request');
+ return this.isIssuable ? this.$options.i18n.issue : this.$options.i18n.mergeRequest;
+ },
+ issuableDisplayNameCapitalized() {
+ return this.isIssuable
+ ? this.$options.i18n.issueCapitalized
+ : this.$options.i18n.mergeRequestCapitalized;
},
isLocked() {
return this.getNoteableData.discussion_locked;
},
lockStatus() {
- return this.isLocked ? this.$options.locked : this.$options.unlocked;
+ return this.isLocked ? this.$options.i18n.locked : this.$options.i18n.unlocked;
},
tooltipLabel() {
- return this.isLocked ? __('Locked') : __('Unlocked');
+ return this.isLocked ? this.$options.i18n.locked : this.$options.i18n.unlocked;
+ },
+ lockToggleInProgressText() {
+ return this.isLocked ? this.unlockingMergeRequestText : this.lockingMergeRequestText;
+ },
+ lockToggleText() {
+ return this.isLocked ? this.unlockMergeRequestText : this.lockMergeRequestText;
+ },
+ lockingMergeRequestText() {
+ return sprintf(this.$options.i18n.lockingMergeRequest, {
+ issuableDisplayName: this.issuableDisplayName,
+ });
+ },
+ unlockingMergeRequestText() {
+ return sprintf(this.$options.i18n.unlockingMergeRequest, {
+ issuableDisplayName: this.issuableDisplayName,
+ });
+ },
+ lockMergeRequestText() {
+ return sprintf(this.$options.i18n.lockMergeRequest, {
+ issuableDisplayName: this.issuableDisplayName,
+ });
+ },
+ unlockMergeRequestText() {
+ return sprintf(this.$options.i18n.unlockMergeRequest, {
+ issuableDisplayName: this.issuableDisplayName,
+ });
+ },
+ lockedMessageText() {
+ return sprintf(this.$options.i18n.lockedMessage, {
+ issuableDisplayName: this.issuableDisplayNameCapitalized,
+ });
+ },
+ unlockedMessageText() {
+ return sprintf(this.$options.i18n.unlockedMessage, {
+ issuableDisplayName: this.issuableDisplayNameCapitalized,
+ });
},
},
@@ -88,12 +151,7 @@ export default {
})
.then(() => {
if (this.isMovedMrSidebar) {
- toast(
- sprintf(__('%{issuableDisplayName} %{lockStatus}.'), {
- issuableDisplayName: capitalizeFirstCharacter(this.issuableDisplayName),
- lockStatus: this.isLocked ? __('locked') : __('unlocked'),
- }),
- );
+ toast(this.isLocked ? this.lockedMessageText : this.unlockedMessageText);
}
})
.catch(() => {
@@ -116,18 +174,35 @@ export default {
</script>
<template>
- <li v-if="isMovedMrSidebar" class="gl-dropdown-item">
+ <li v-if="isMovedMrSidebar && isIssuable" class="gl-dropdown-item">
<button type="button" class="dropdown-item" data-testid="issuable-lock" @click="toggleLocked">
<span class="gl-dropdown-item-text-wrapper">
- <template v-if="isLocked">
- {{ sprintf(__('Unlock %{issuableType}'), { issuableType: issuableDisplayName }) }}
+ <template v-if="isLoading">
+ <gl-loading-icon inline size="sm" /> {{ lockToggleInProgressText }}
</template>
<template v-else>
- {{ sprintf(__('Lock %{issuableType}'), { issuableType: issuableDisplayName }) }}
+ {{ lockToggleText }}
</template>
</span>
</button>
</li>
+ <gl-disclosure-dropdown-item v-else-if="isMovedMrSidebar">
+ <button
+ type="button"
+ class="gl-new-dropdown-item-content"
+ data-testid="issuable-lock"
+ @click="toggleLocked"
+ >
+ <span class="gl-new-dropdown-item-text-wrapper">
+ <template v-if="isLoading">
+ <gl-loading-icon inline size="sm" /> {{ lockToggleInProgressText }}
+ </template>
+ <template v-else>
+ {{ lockToggleText }}
+ </template>
+ </span>
+ </button>
+ </gl-disclosure-dropdown-item>
<div v-else class="block issuable-sidebar-item lock">
<div
v-gl-tooltip.left.viewport="{ title: tooltipLabel }"
@@ -139,7 +214,7 @@ export default {
</div>
<div class="hide-collapsed gl-line-height-20 gl-mb-2 gl-text-gray-900 gl-font-weight-bold">
- {{ sprintf(__('Lock %{issuableDisplayName}'), { issuableDisplayName: issuableDisplayName }) }}
+ {{ lockMergeRequestText }}
<a
v-if="isEditable"
class="float-right lock-edit btn gl-text-gray-900! gl-ml-auto hide-collapsed btn-default btn-sm gl-button btn-default-tertiary gl-mr-n2"
@@ -164,7 +239,7 @@ export default {
/>
<div data-testid="lock-status" class="sidebar-item-value" :class="lockStatus.class">
- {{ lockStatus.displayText }}
+ {{ lockStatus }}
</div>
</div>
</div>
diff --git a/app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue b/app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue
index f2b960ed02c..d6e1847aecb 100644
--- a/app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue
+++ b/app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue
@@ -1,7 +1,14 @@
<script>
-import { GlDropdownForm, GlIcon, GlLoadingIcon, GlToggle, GlTooltipDirective } from '@gitlab/ui';
+import {
+ GlDisclosureDropdownItem,
+ GlDropdownForm,
+ GlIcon,
+ GlLoadingIcon,
+ GlToggle,
+ GlTooltipDirective,
+} from '@gitlab/ui';
import { createAlert } from '~/alert';
-import { TYPE_EPIC, WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
+import { TYPE_ISSUE, TYPE_EPIC, WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
import { isLoggedIn } from '~/lib/utils/common_utils';
import { __, sprintf } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
@@ -22,6 +29,7 @@ export default {
GlTooltip: GlTooltipDirective,
},
components: {
+ GlDisclosureDropdownItem,
GlDropdownForm,
GlIcon,
GlLoadingIcon,
@@ -89,6 +97,9 @@ export default {
isMovedMrSidebar() {
return this.glFeatures.movedMrSidebar;
},
+ isIssuable() {
+ return this.issuableType === TYPE_ISSUE;
+ },
isLoading() {
return this.$apollo.queries?.subscribed?.loading || this.loading;
},
@@ -182,18 +193,32 @@ export default {
</script>
<template>
- <gl-dropdown-form v-if="isMovedMrSidebar" class="gl-dropdown-item">
+ <gl-dropdown-form v-if="isMovedMrSidebar && isIssuable" class="gl-dropdown-item">
<div class="gl-px-5 gl-pb-2 gl-pt-1">
<gl-toggle
:value="subscribed"
- :label="__('Notifications')"
+ :label="$options.i18n.notifications"
class="merge-request-notification-toggle"
label-position="left"
- data-testid="notifications-toggle"
+ data-testid="notification-toggle"
@change="toggleSubscribed"
/>
</div>
</gl-dropdown-form>
+ <gl-disclosure-dropdown-item
+ v-else-if="isMovedMrSidebar"
+ data-testid="notification-toggle"
+ @action="toggleSubscribed"
+ >
+ <template #list-item>
+ <gl-toggle
+ :value="subscribed"
+ :label="__('Notifications')"
+ class="merge-request-notification-toggle"
+ label-position="left"
+ />
+ </template>
+ </gl-disclosure-dropdown-item>
<sidebar-editable-item
v-else
ref="editable"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merging.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merging.vue
index 17c51bc4e6e..9258bc39bcb 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merging.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_merging.vue
@@ -55,7 +55,6 @@ export default {
// If state is merged we should update the widget and stop the polling
eventHub.$emit('MRWidgetUpdateRequested');
eventHub.$emit('FetchActionsContent');
- MergeRequest.hideCloseButton();
MergeRequest.decreaseCounter();
stopPolling();
diff --git a/app/assets/javascripts/vue_shared/components/mr_more_dropdown.vue b/app/assets/javascripts/vue_shared/components/mr_more_dropdown.vue
new file mode 100644
index 00000000000..064458cfc1f
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/mr_more_dropdown.vue
@@ -0,0 +1,361 @@
+<script>
+import {
+ GlLoadingIcon,
+ GlButton,
+ GlIcon,
+ GlDisclosureDropdown,
+ GlDisclosureDropdownItem,
+ GlDisclosureDropdownGroup,
+ GlTooltipDirective,
+} from '@gitlab/ui';
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import { apolloProvider } from '~/graphql_shared/issuable_client';
+import { __, s__ } from '~/locale';
+import api from '~/api';
+import axios from '~/lib/utils/axios_utils';
+import { createAlert } from '~/alert';
+import MergeRequest from '~/merge_request';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import SidebarSubscriptionsWidget from '~/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue';
+import AbuseCategorySelector from '~/abuse_reports/components/abuse_category_selector.vue';
+import NewHeaderActionsPopover from '~/issues/show/components/new_header_actions_popover.vue';
+import { TYPE_MERGE_REQUEST } from '~/issues/constants';
+
+Vue.use(VueApollo);
+
+export default {
+ apolloProvider,
+ i18n: {
+ edit: __('Edit'),
+ copyReferenceText: __('Copy reference'),
+ errorMessage: __('Something went wrong. Please try again.'),
+ issuableName: __('merge request'),
+ reportAbuse: __('Report abuse'),
+ markAsReady: __('Mark as ready'),
+ markAsDraft: __('Mark as draft'),
+ close: __('Close %{issuableType}'),
+ closing: __('Closing %{issuableType}...'),
+ reopen: __('Reopen %{issuableType}'),
+ reopening: __('Reopening %{issuableType}...'),
+ lock: __('Lock %{issuableType}'),
+ mergeRequestActions: __('Merge request actions'),
+ },
+ components: {
+ GlLoadingIcon,
+ GlButton,
+ GlIcon,
+ GlDisclosureDropdown,
+ GlDisclosureDropdownItem,
+ GlDisclosureDropdownGroup,
+ SidebarSubscriptionsWidget,
+ AbuseCategorySelector,
+ NewHeaderActionsPopover,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ mixins: [glFeatureFlagMixin()],
+ inject: {
+ reportAbusePath: {
+ default: '',
+ },
+ },
+ props: {
+ mr: {
+ type: Object,
+ required: true,
+ },
+ projectPath: {
+ type: String,
+ default: '',
+ required: false,
+ },
+ editUrl: {
+ type: String,
+ default: '',
+ required: false,
+ },
+ isCurrentUser: {
+ type: Boolean,
+ default: false,
+ required: true,
+ },
+ isLoggedIn: {
+ type: Boolean,
+ defauilt: false,
+ required: false,
+ },
+ canUpdateMergeRequest: {
+ type: Boolean,
+ default: false,
+ required: false,
+ },
+ open: {
+ type: Boolean,
+ default: false,
+ required: false,
+ },
+ isMerged: {
+ type: Boolean,
+ default: false,
+ required: false,
+ },
+ sourceProjectMissing: {
+ type: Boolean,
+ default: false,
+ required: false,
+ },
+ clipboardText: {
+ type: String,
+ default: '',
+ required: false,
+ },
+ reportedUserId: {
+ type: Number,
+ default: 0,
+ required: false,
+ },
+ reportedFromUrl: {
+ type: String,
+ default: '',
+ required: false,
+ },
+ },
+ data() {
+ return {
+ isOpen: this.open,
+ draft: this.mr.draft,
+ issuableType: TYPE_MERGE_REQUEST,
+ fullPath: this.projectPath,
+ isLoading: false,
+ isLoadingDraft: false,
+ isLoadingClipboard: false,
+ isReportAbuseDrawerOpen: false,
+ };
+ },
+ computed: {
+ isMovedMrSidebar() {
+ return this.glFeatures.movedMrSidebar;
+ },
+ draftLabel() {
+ return this.draft ? this.$options.i18n.markAsReady : this.$options.i18n.markAsDraft;
+ },
+ draftState() {
+ return this.draft ? 'ready' : 'draft';
+ },
+ editItem() {
+ return {
+ text: this.$options.i18n.edit,
+ href: this.editUrl,
+ };
+ },
+ },
+ methods: {
+ draftAction() {
+ this.isLoadingDraft = true;
+
+ axios
+ .put(`?merge_request[wip_event]=${this.draftState}`, null, {
+ params: { format: 'json' },
+ })
+ .then(({ data }) => {
+ MergeRequest.toggleDraftStatus(data.title, this.draft);
+ })
+ .catch(() => {
+ createAlert({
+ message: this.$options.i18n.errorMessage,
+ });
+ })
+ .finally(() => {
+ this.draft = !this.draft;
+ this.isLoadingDraft = false;
+ this.closeActionsDropdown();
+ });
+ },
+ stateAction(state) {
+ this.isLoading = true;
+
+ api
+ .updateMergeRequest(this.mr.target_project_id, this.mr.iid, { state_event: state })
+ .then(() => {
+ window.location.reload();
+ })
+ .catch(() => {
+ createAlert({
+ message: this.$options.i18n.errorMessage,
+ });
+ })
+ .finally(() => {
+ this.isOpen = !this.isOpen;
+ this.isLoading = false;
+ this.closeActionsDropdown();
+ });
+ },
+ copyClipboardAction() {
+ this.$toast.show(s__('MergeRequests|Reference copied'));
+ this.closeActionsDropdown();
+ },
+ reportAbuseAction(isOpen) {
+ if (isOpen) {
+ this.closeActionsDropdown();
+ }
+
+ this.isReportAbuseDrawerOpen = isOpen;
+ },
+ closeActionsDropdown() {
+ this.$refs.mrMoreActionsDropdown.close();
+ },
+ showReopenMergeRequestOption() {
+ return !this.sourceProjectMissing && !this.isOpen;
+ },
+ },
+};
+</script>
+
+<template>
+ <div
+ class="gl-display-flex gl-justify-content-end gl-w-full gl-relative"
+ data-testid="merge-request-actions"
+ >
+ <gl-disclosure-dropdown
+ id="new-actions-header-dropdown"
+ ref="mrMoreActionsDropdown"
+ data-testid="dropdown-toggle"
+ placement="right"
+ :auto-close="false"
+ >
+ <template #toggle>
+ <div class="gl-min-h-7 gl-mb-2 gl-md-mb-0!" :aria-label="$options.i18n.mergeRequestActions">
+ <gl-button
+ class="gl-md-display-none! gl-new-dropdown-toggle gl-absolute gl-top-0 gl-left-0 gl-w-full"
+ category="secondary"
+ >
+ <span class="">{{ $options.i18n.mergeRequestActions }}</span>
+ <gl-icon class="dropdown-chevron" name="chevron-down" />
+ </gl-button>
+ <gl-button
+ class="gl-display-none gl-md-display-flex! gl-new-dropdown-toggle gl-new-dropdown-icon-only gl-new-dropdown-toggle-no-caret gl-ml-3"
+ category="tertiary"
+ icon="ellipsis_v"
+ />
+ </div>
+ </template>
+ <gl-disclosure-dropdown-group v-if="isLoggedIn && isMovedMrSidebar">
+ <sidebar-subscriptions-widget
+ :iid="String(mr.iid)"
+ :full-path="fullPath"
+ :issuable-type="issuableType"
+ data-testid="notification-toggle"
+ />
+ </gl-disclosure-dropdown-group>
+
+ <gl-disclosure-dropdown-group
+ bordered
+ :class="{ 'gl-mt-0! gl-pt-0! gl-border-t-0!': !(isLoggedIn && isMovedMrSidebar) }"
+ >
+ <gl-disclosure-dropdown-item
+ v-if="canUpdateMergeRequest"
+ class="gl-md-display-none!"
+ data-testid="edit-merge-request"
+ :item="editItem"
+ />
+
+ <gl-disclosure-dropdown-item
+ v-if="isOpen && canUpdateMergeRequest"
+ data-testid="ready-and-draft-action"
+ @action="draftAction"
+ >
+ <template #list-item>
+ <gl-loading-icon v-if="isLoadingDraft" inline size="sm" />
+ {{ draftLabel }}
+ </template>
+ </gl-disclosure-dropdown-item>
+
+ <gl-disclosure-dropdown-item
+ v-if="isOpen && canUpdateMergeRequest"
+ data-testid="close-merge-request"
+ @action="stateAction('close')"
+ >
+ <template #list-item>
+ <template v-if="isLoading">
+ <gl-loading-icon inline size="sm" />
+ {{
+ sprintf($options.i18n.closing, {
+ issuableType: $options.i18n.issuableName,
+ })
+ }}
+ </template>
+ <template v-else>
+ {{ sprintf($options.i18n.close, { issuableType: $options.i18n.issuableName }) }}
+ </template>
+ </template>
+ </gl-disclosure-dropdown-item>
+
+ <gl-disclosure-dropdown-item
+ v-else-if="!isMerged && showReopenMergeRequestOption && canUpdateMergeRequest"
+ data-testid="reopen-merge-request"
+ @action="stateAction('reopen')"
+ >
+ <template #list-item>
+ <template v-if="isLoading">
+ <gl-loading-icon inline size="sm" />
+ {{
+ sprintf($options.i18n.reopening, {
+ issuableType: $options.i18n.issuableName,
+ })
+ }}
+ </template>
+ <template v-else>
+ {{ sprintf($options.i18n.reopen, { issuableType: $options.i18n.issuableName }) }}
+ </template>
+ </template>
+ </gl-disclosure-dropdown-item>
+
+ <gl-disclosure-dropdown-item v-if="isMovedMrSidebar" class="js-sidebar-lock-root">
+ <template #list-item>
+ {{ sprintf($options.i18n.lock, { issuableType: $options.i18n.issuableName }) }}
+ </template>
+ </gl-disclosure-dropdown-item>
+
+ <gl-disclosure-dropdown-item
+ v-if="isMovedMrSidebar"
+ class="js-copy-reference"
+ :data-clipboard-text="clipboardText"
+ data-testid="copy-reference"
+ @action="copyClipboardAction"
+ >
+ <template #list-item>
+ {{ $options.i18n.copyReferenceText }}
+ </template>
+ </gl-disclosure-dropdown-item>
+ </gl-disclosure-dropdown-group>
+
+ <gl-disclosure-dropdown-group
+ v-if="!isCurrentUser"
+ bordered
+ :class="{ 'gl-mt-0! gl-pt-0! gl-border-t-0!': !canUpdateMergeRequest }"
+ >
+ <gl-disclosure-dropdown-item
+ class="js-report-abuse-dropdown-item"
+ data-testid="report-abuse-option"
+ @action="reportAbuseAction(true)"
+ >
+ <template #list-item>
+ {{ $options.i18n.reportAbuse }}
+ </template>
+ </gl-disclosure-dropdown-item>
+ </gl-disclosure-dropdown-group>
+ </gl-disclosure-dropdown>
+
+ <new-header-actions-popover v-if="isMovedMrSidebar" :issue-type="issuableType" />
+
+ <abuse-category-selector
+ v-if="!isCurrentUser && isReportAbuseDrawerOpen"
+ :reported-user-id="reportedUserId"
+ :reported-from-url="reportedFromUrl"
+ :show-drawer="isReportAbuseDrawerOpen"
+ @close-drawer="reportAbuseAction(false)"
+ />
+ </div>
+</template>
diff --git a/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml b/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml
index 9bfa0e7a309..a3536ead240 100644
--- a/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml
+++ b/app/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml
@@ -1,53 +1,15 @@
-- display_issuable_type = issuable_display_type(@merge_request)
-
-.btn-group.gl-md-ml-3.gl-display-flex.dropdown.gl-dropdown.gl-md-w-auto.gl-w-full
- %span.js-sidebar-header-popover
- = button_tag type: 'button', id: "new-actions-header-dropdown", class: "btn dropdown-toggle btn-default btn-md gl-button gl-dropdown-toggle btn-default-tertiary dropdown-icon-only dropdown-toggle-no-caret gl-display-none! gl-md-display-inline-flex!", title: _('Merge request actions'), 'aria-label': _('Merge request actions'), data: { toggle: 'dropdown', testid: 'merge-request-actions' } do
- = sprite_icon "ellipsis_v", size: 16, css_class: "dropdown-icon gl-icon"
- = button_tag type: 'button', class: "btn dropdown-toggle btn-default btn-md btn-block gl-button gl-dropdown-toggle gl-md-display-none!", data: { 'toggle' => 'dropdown' } do
- %span.gl-dropdown-button-text= _('Merge request actions')
- = sprite_icon "chevron-down", size: 16, css_class: "dropdown-icon gl-icon"
- .dropdown-menu.dropdown-menu-right
- .gl-dropdown-inner
- .gl-dropdown-contents
- %ul
- - if current_user && moved_mr_sidebar_enabled?
- %li.gl-dropdown-item.js-sidebar-subscriptions-widget-root
- %li.gl-dropdown-divider
- %hr.dropdown-divider
- - if can?(current_user, :update_merge_request, @merge_request)
- %li.gl-dropdown-item{ class: "gl-md-display-none!" }
- = link_to edit_project_merge_request_path(@project, @merge_request), class: 'dropdown-item' do
- .gl-dropdown-item-text-wrapper
- = _('Edit')
- - if @merge_request.open?
- %li.gl-dropdown-item
- = link_to toggle_draft_merge_request_path(@merge_request), method: :put, class: 'dropdown-item js-draft-toggle-button' do
- .gl-dropdown-item-text-wrapper
- = @merge_request.draft? ? _('Mark as ready') : _('Mark as draft')
- %li.gl-dropdown-item.js-close-item
- = link_to close_issuable_path(@merge_request), method: :put, class: 'dropdown-item' do
- .gl-dropdown-item-text-wrapper
- = _('Close')
- = display_issuable_type
- - elsif !@merge_request.source_project_missing? && @merge_request.closed?
- %li.gl-dropdown-item
- = link_to reopen_issuable_path(@merge_request), method: :put, class: 'dropdown-item' do
- .gl-dropdown-item-text-wrapper
- = _('Reopen')
- = display_issuable_type
- - if moved_mr_sidebar_enabled?
- %li.gl-dropdown-item.js-sidebar-lock-root
- %li.gl-dropdown-item
- %button.dropdown-item.js-copy-reference{ type: "button", data: { 'clipboard-text': @merge_request.to_reference(full: true) } }
- .gl-dropdown-item-text-wrapper
- = _('Copy reference')
-
- - unless current_controller?('conflicts')
- - unless issuable_author_is_current_user(@merge_request)
- - if moved_mr_sidebar_enabled?
- %li.gl-dropdown-divider
- %hr.dropdown-divider
- .js-report-abuse-dropdown-item{ data: { report_abuse_path: add_category_abuse_reports_path, reported_user_id: @merge_request.author.id, reported_from_url: merge_request_url(@merge_request) } }
-
-#js-report-abuse-drawer
+.js-mr-more-dropdown{ data: {
+ merge_request: @merge_request.to_json,
+ project_path: @project.full_path,
+ edit_url: edit_project_merge_request_path(@project, @merge_request),
+ is_current_user: issuable_author_is_current_user(@merge_request),
+ is_logged_in: current_user,
+ can_update_merge_request: can?(current_user, :update_merge_request, @merge_request),
+ open: @merge_request.open?,
+ merged: @merge_request.merged?,
+ source_project_missing: @merge_request.source_project_missing?,
+ clipboard_text: @merge_request.to_reference(full: true),
+ report_abuse_path: add_category_abuse_reports_path,
+ reported_user_id: @merge_request.author.id,
+ reported_from_url: merge_request_url(@merge_request),
+} }
diff --git a/config/metrics/counts_28d/20210216180308_personal_snippets.yml b/config/metrics/counts_28d/20210216180308_personal_snippets.yml
index 99893caa053..bcdc8f20e23 100644
--- a/config/metrics/counts_28d/20210216180308_personal_snippets.yml
+++ b/config/metrics/counts_28d/20210216180308_personal_snippets.yml
@@ -9,6 +9,7 @@ value_type: number
status: active
time_frame: 28d
data_source: database
+instrumentation_class: CountPersonalSnippetsMetric
distribution:
- ce
- ee
diff --git a/config/metrics/counts_28d/20210216180310_project_snippets.yml b/config/metrics/counts_28d/20210216180310_project_snippets.yml
index e7c66f90a3d..bdf7375e569 100644
--- a/config/metrics/counts_28d/20210216180310_project_snippets.yml
+++ b/config/metrics/counts_28d/20210216180310_project_snippets.yml
@@ -8,6 +8,7 @@ product_group: source_code
value_type: number
status: active
time_frame: 28d
+instrumentation_class: CountProjectSnippetsMetric
data_source: database
distribution:
- ce
diff --git a/config/metrics/counts_28d/20210216180312_snippets.yml b/config/metrics/counts_28d/20210216180312_snippets.yml
index e9a091c507b..7592ab4b461 100644
--- a/config/metrics/counts_28d/20210216180312_snippets.yml
+++ b/config/metrics/counts_28d/20210216180312_snippets.yml
@@ -9,6 +9,7 @@ value_type: number
status: active
time_frame: 28d
data_source: database
+instrumentation_class: CountSnippetsMetric
distribution:
- ce
- ee
diff --git a/config/metrics/counts_all/20210216180239_personal_snippets.yml b/config/metrics/counts_all/20210216180239_personal_snippets.yml
index 4a031b6a7b4..872913c85bc 100644
--- a/config/metrics/counts_all/20210216180239_personal_snippets.yml
+++ b/config/metrics/counts_all/20210216180239_personal_snippets.yml
@@ -9,6 +9,7 @@ value_type: number
status: active
time_frame: all
data_source: database
+instrumentation_class: CountPersonalSnippetsMetric
distribution:
- ce
- ee
diff --git a/config/metrics/counts_all/20210216180241_project_snippets.yml b/config/metrics/counts_all/20210216180241_project_snippets.yml
index cd35e388a4e..89adcbdf877 100644
--- a/config/metrics/counts_all/20210216180241_project_snippets.yml
+++ b/config/metrics/counts_all/20210216180241_project_snippets.yml
@@ -9,6 +9,7 @@ value_type: number
status: active
time_frame: all
data_source: database
+instrumentation_class: CountProjectSnippetsMetric
distribution:
- ce
- ee
diff --git a/config/metrics/counts_all/20210216180306_snippets.yml b/config/metrics/counts_all/20210216180306_snippets.yml
index 88b7ae413d8..f2baffe86dc 100644
--- a/config/metrics/counts_all/20210216180306_snippets.yml
+++ b/config/metrics/counts_all/20210216180306_snippets.yml
@@ -8,6 +8,7 @@ product_group: source_code
value_type: number
status: active
time_frame: all
+instrumentation_class: CountSnippetsMetric
data_source: database
distribution:
- ce
diff --git a/doc/administration/auth/ldap/ldap-troubleshooting.md b/doc/administration/auth/ldap/ldap-troubleshooting.md
index fe4430fd235..9fb3888b995 100644
--- a/doc/administration/auth/ldap/ldap-troubleshooting.md
+++ b/doc/administration/auth/ldap/ldap-troubleshooting.md
@@ -167,7 +167,8 @@ may see the following message: `Access denied for your LDAP account`.
We have a workaround, based on toggling the access level of affected users:
-1. As an administrator, on the top bar, select **Main menu > Admin**.
+1. As an administrator, on the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Overview > Users**.
1. Select the name of the affected user.
1. In the upper-right corner, select **Edit**.
@@ -224,7 +225,8 @@ field contains no data:
To resolve this:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, go to **Settings > General**.
1. Expand both of the following:
- **Account and limit**.
@@ -367,7 +369,8 @@ things to debug the situation.
- Ensure the correct [LDAP group link is added to the GitLab group](ldap_synchronization.md#add-group-links).
- Check that the user has an LDAP identity:
1. Sign in to GitLab as an administrator user.
- 1. On the top bar, select **Main menu > Admin**.
+ 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+ 1. Select **Admin Area**.
1. On the left sidebar, select **Overview > Users**.
1. Search for the user.
1. Open the user by selecting their name. Do not select **Edit**.
diff --git a/doc/administration/auth/ldap/ldap_synchronization.md b/doc/administration/auth/ldap/ldap_synchronization.md
index cc788d6d4c8..e4b43feacc2 100644
--- a/doc/administration/auth/ldap/ldap_synchronization.md
+++ b/doc/administration/auth/ldap/ldap_synchronization.md
@@ -501,7 +501,8 @@ When global group memberships lock is enabled:
To enable global group memberships lock:
1. [Configure LDAP](index.md#configure-ldap).
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
1. Ensure the **Lock memberships to LDAP synchronization** checkbox is selected.
@@ -513,7 +514,8 @@ By default, group members with the Owner role can manage [LDAP group synchroniza
GitLab administrators can remove this permission from group Owners:
1. [Configure LDAP](index.md#configure-ldap).
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Settings > General**.
1. Expand **Visibility and access controls**.
1. Ensure the **Allow group owners to manage LDAP-related settings** checkbox is not checked.
diff --git a/doc/administration/geo/disaster_recovery/background_verification.md b/doc/administration/geo/disaster_recovery/background_verification.md
index ea4523c66e6..6d7240a9f92 100644
--- a/doc/administration/geo/disaster_recovery/background_verification.md
+++ b/doc/administration/geo/disaster_recovery/background_verification.md
@@ -49,7 +49,8 @@ Feature.enable('geo_repository_verification')
On the **primary** site:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Geo > Sites**.
1. Expand **Verification information** tab for that site to view automatic checksumming
status for repositories and wikis. Successes are shown in green, pending work
@@ -59,7 +60,8 @@ On the **primary** site:
On the **secondary** site:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Geo > Sites**.
1. Expand **Verification information** tab for that site to view automatic checksumming
status for repositories and wikis. Successes are shown in green, pending work
@@ -87,7 +89,8 @@ increase load and vice versa.
On the **primary** site:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Geo > Sites**.
1. Select **Edit** for the **primary** site to customize the minimum
re-verification interval:
@@ -135,7 +138,8 @@ sudo gitlab-rake geo:verification:wiki:reset
If the **primary** and **secondary** sites have a checksum verification mismatch, the cause may not be apparent. To find the cause of a checksum mismatch:
1. On the **primary** site:
- 1. On the top bar, select **Main menu > Admin**.
+ 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+ 1. Select **Admin Area**.
1. On the left sidebar, select **Overview > Projects**.
1. Find the project that you want to check the checksum differences and
select its name.
diff --git a/doc/administration/geo/disaster_recovery/planned_failover.md b/doc/administration/geo/disaster_recovery/planned_failover.md
index a52bdc759a2..13e0938fa59 100644
--- a/doc/administration/geo/disaster_recovery/planned_failover.md
+++ b/doc/administration/geo/disaster_recovery/planned_failover.md
@@ -149,7 +149,8 @@ ensure these processes are close to 100% as possible during active use.
On the **secondary** site:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Geo > Sites**.
Replicated objects (shown in green) should be close to 100%,
and there should be no failures (shown in red). If a large proportion of
@@ -177,7 +178,8 @@ This [content was moved to another location](background_verification.md).
On the **primary** site:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Messages**.
1. Add a message notifying users on the maintenance window.
You can check under **Geo > Sites** to estimate how long it
@@ -190,7 +192,8 @@ To ensure that all data is replicated to a secondary site, updates (write reques
be disabled on the **primary** site:
1. Enable [maintenance mode](../../maintenance_mode/index.md) on the **primary** site.
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dashboard, select **Cron**.
1. Select `Disable All` to disable non-Geo periodic background jobs.
@@ -206,7 +209,8 @@ GitLab 13.9 through GitLab 14.3 are affected by a bug in which the Geo secondary
1. If you are manually replicating any data not managed by Geo, trigger the
final replication process now.
1. On the **primary** site:
- 1. On the top bar, select **Main menu > Admin**.
+ 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+ 1. Select **Admin Area**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dashboard, select **Queues**, and wait for all queues except
those with `geo` in the name to drop to 0.
@@ -221,7 +225,8 @@ GitLab 13.9 through GitLab 14.3 are affected by a bug in which the Geo secondary
- The Geo log cursor is up to date (0 events behind).
1. On the **secondary** site:
- 1. On the top bar, select **Main menu > Admin**.
+ 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+ 1. Select **Admin Area**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dashboard, select **Queues**, and wait for all the `geo`
queues to drop to 0 queued and 0 running jobs.
diff --git a/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md b/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md
index 4cd332d6250..9ec9e791f59 100644
--- a/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md
+++ b/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md
@@ -68,7 +68,8 @@ GitLab 13.9 through GitLab 14.3 are affected by a bug in which the Geo secondary
On the **secondary** site:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Geo > Sites** to see its status.
Replicated objects (shown in green) should be close to 100%,
and there should be no failures (shown in red). If a large proportion of
@@ -133,7 +134,8 @@ follow these steps to avoid unnecessary data loss:
connection.
1. On the **primary** site:
- 1. On the top bar, select **Main menu > Admin**.
+ 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+ 1. Select **Admin Area**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dashboard, select **Cron**.
1. Select `Disable All` to disable any non-Geo periodic background jobs.
@@ -151,7 +153,8 @@ follow these steps to avoid unnecessary data loss:
[data not managed by Geo](../../replication/datatypes.md#limitations-on-replicationverification),
trigger the final replication process now.
1. On the **primary** site:
- 1. On the top bar, select **Main menu > Admin**.
+ 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+ 1. Select **Admin Area**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dashboard, select **Queues**, and wait for all queues except
those with `geo` in the name to drop to 0.
@@ -166,7 +169,8 @@ follow these steps to avoid unnecessary data loss:
- The Geo log cursor is up to date (0 events behind).
1. On the **secondary** site:
- 1. On the top bar, select **Main menu > Admin**.
+ 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+ 1. Select **Admin Area**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dashboard, select **Queues**, and wait for all the `geo`
queues to drop to 0 queued and 0 running jobs.
diff --git a/doc/administration/geo/disaster_recovery/runbooks/planned_failover_single_node.md b/doc/administration/geo/disaster_recovery/runbooks/planned_failover_single_node.md
index ecece40f85a..7f94d6e4c1a 100644
--- a/doc/administration/geo/disaster_recovery/runbooks/planned_failover_single_node.md
+++ b/doc/administration/geo/disaster_recovery/runbooks/planned_failover_single_node.md
@@ -118,7 +118,8 @@ follow these steps to avoid unnecessary data loss:
connection.
1. On the **primary** site:
- 1. On the top bar, select **Main menu > Admin**.
+ 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+ 1. Select **Admin Area**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dashboard, select **Cron**.
1. Select `Disable All` to disable any non-Geo periodic background jobs.
@@ -136,7 +137,8 @@ follow these steps to avoid unnecessary data loss:
[data not managed by Geo](../../replication/datatypes.md#limitations-on-replicationverification),
trigger the final replication process now.
1. On the **primary** site:
- 1. On the top bar, select **Main menu > Admin**.
+ 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+ 1. Select **Admin Area**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dashboard, select **Queues**, and wait for all queues except
those with `geo` in the name to drop to 0.
@@ -151,7 +153,8 @@ follow these steps to avoid unnecessary data loss:
- The Geo log cursor is up to date (0 events behind).
1. On the **secondary** site:
- 1. On the top bar, select **Main menu > Admin**.
+ 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+ 1. Select **Admin Area**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. On the Sidekiq dashboard, select **Queues**, and wait for all the `geo`
queues to drop to 0 queued and 0 running jobs.
diff --git a/doc/administration/geo/index.md b/doc/administration/geo/index.md
index e29ebb1bb64..ae2cc262160 100644
--- a/doc/administration/geo/index.md
+++ b/doc/administration/geo/index.md
@@ -160,7 +160,9 @@ public URL of the primary site is used.
To update the internal URL of the primary Geo site:
-1. On the top bar, select **Main menu > Admin > Geo > Sites**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. On the left sidebar, select **Geo > Sites**.
1. Select **Edit** on the primary site.
1. Change the **Internal URL**, then select **Save changes**.
diff --git a/doc/administration/geo/replication/configuration.md b/doc/administration/geo/replication/configuration.md
index 5aee9bc5b83..0eba666979e 100644
--- a/doc/administration/geo/replication/configuration.md
+++ b/doc/administration/geo/replication/configuration.md
@@ -202,7 +202,8 @@ keys must be manually replicated to the **secondary** site.
```
1. Navigate to the Primary Node GitLab Instance:
- 1. On the top bar, select **Main menu > Admin**.
+ 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+ 1. Select **Admin Area**.
1. On the left sidebar, select **Geo > Sites**.
1. Select **Add site**.
![Add secondary site](img/adding_a_secondary_v15_8.png)
@@ -311,7 +312,8 @@ method to be enabled. This is enabled by default, but if converting an existing
On the **primary** site:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Settings > General**.
1. Expand **Visibility and access controls**.
1. If using Git over SSH, then:
@@ -324,7 +326,8 @@ On the **primary** site:
You can sign in to the **secondary** site with the same credentials you used with
the **primary** site. After you sign in:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Geo > Sites**.
1. Verify that it's correctly identified as a **secondary** Geo site, and that
Geo is enabled.
diff --git a/doc/administration/geo/replication/container_registry.md b/doc/administration/geo/replication/container_registry.md
index 1c1d9074a04..6dde611a20d 100644
--- a/doc/administration/geo/replication/container_registry.md
+++ b/doc/administration/geo/replication/container_registry.md
@@ -166,7 +166,8 @@ For each application and Sidekiq node on the **secondary** site:
To verify Container Registry replication is working, on the **secondary** site:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Geo > Nodes**.
The initial replication, or "backfill", is probably still in progress.
diff --git a/doc/administration/geo/replication/disable_geo.md b/doc/administration/geo/replication/disable_geo.md
index abd6fd941af..bedcca7e311 100644
--- a/doc/administration/geo/replication/disable_geo.md
+++ b/doc/administration/geo/replication/disable_geo.md
@@ -36,7 +36,8 @@ to do that.
To remove the **primary** site:
1. [Remove all secondary Geo sites](remove_geo_site.md)
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Geo > Nodes**.
1. Select **Remove** for the **primary** node.
1. Confirm by selecting **Remove** when the prompt appears.
diff --git a/doc/administration/geo/replication/object_storage.md b/doc/administration/geo/replication/object_storage.md
index b39acf2466d..86db8186a13 100644
--- a/doc/administration/geo/replication/object_storage.md
+++ b/doc/administration/geo/replication/object_storage.md
@@ -41,7 +41,8 @@ whether they are stored on the local file system or in object storage.
To enable GitLab replication:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Geo > Nodes**.
1. Select **Edit** on the **secondary** site.
1. In the **Synchronization Settings** section, find the **Allow this secondary node to replicate content on Object Storage**
diff --git a/doc/administration/geo/replication/remove_geo_site.md b/doc/administration/geo/replication/remove_geo_site.md
index 9d92652daf4..de0ad3fe2fb 100644
--- a/doc/administration/geo/replication/remove_geo_site.md
+++ b/doc/administration/geo/replication/remove_geo_site.md
@@ -9,7 +9,8 @@ type: howto
**Secondary** sites can be removed from the Geo cluster using the Geo administration page of the **primary** site. To remove a **secondary** site:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Geo > Nodes**.
1. For the **secondary** site you want to remove, select **Remove**.
1. Confirm by selecting **Remove** when the prompt appears.
diff --git a/doc/administration/geo/replication/troubleshooting.md b/doc/administration/geo/replication/troubleshooting.md
index 1766b1bef8b..f326a6940d5 100644
--- a/doc/administration/geo/replication/troubleshooting.md
+++ b/doc/administration/geo/replication/troubleshooting.md
@@ -27,7 +27,8 @@ Before attempting more advanced troubleshooting:
On the **primary** site:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Geo > Sites**.
We perform the following health checks on each **secondary** site
@@ -854,8 +855,11 @@ to start again from scratch, there are a few steps that can help you:
### Design repository failures on mirrored projects and project imports
-On the top bar, under **Main menu > Admin > Geo > Sites**,
-if the Design repositories progress bar shows
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. On the left sidebar, select **Geo > Sites**.
+
+If the Design repositories progress bar shows
`Synced` and `Failed` greater than 100%, and negative `Queued`, the instance
is likely affected by
[a bug in GitLab 13.2 and 13.3](https://gitlab.com/gitlab-org/gitlab/-/issues/241668).
@@ -1190,7 +1194,8 @@ site's URL matches its external URL.
On the **primary** site:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Geo > Sites**.
1. Find the affected **secondary** site and select **Edit**.
1. Ensure the **URL** field matches the value found in `/etc/gitlab/gitlab.rb`
@@ -1396,8 +1401,9 @@ If you have updated the value of `external_url` in `/etc/gitlab/gitlab.rb` for t
In this case, make sure to update the changed URL on all your sites:
-1. On the top bar, select **Main menu > Admin**.
-1. On the left sidebar, select **Admin > Geo > Sites**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. On the left sidebar, select **Geo > Sites**.
1. Change the URL and save the change.
## Fixing non-PostgreSQL replication failures
diff --git a/doc/administration/geo/replication/tuning.md b/doc/administration/geo/replication/tuning.md
index 4dc3ba93d66..9e1638643cb 100644
--- a/doc/administration/geo/replication/tuning.md
+++ b/doc/administration/geo/replication/tuning.md
@@ -14,7 +14,8 @@ in the background.
On the **primary** site:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Geo > Sites**.
1. Select **Edit** of the secondary site you want to tune.
1. Under **Tuning settings**, there are several variables that can be tuned to
diff --git a/doc/administration/gitaly/praefect.md b/doc/administration/gitaly/praefect.md
index 02c1c933a06..d5c01d4e1c1 100644
--- a/doc/administration/gitaly/praefect.md
+++ b/doc/administration/gitaly/praefect.md
@@ -1335,7 +1335,8 @@ Particular attention should be shown to:
1. Check that the Praefect storage is configured to store new repositories:
- 1. On the top bar, select **Main menu > Admin**.
+ 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+ 1. Select **Admin Area**.
1. On the left sidebar, select **Settings > Repository**.
1. Expand the **Repository storage** section.
diff --git a/doc/administration/gitaly/troubleshooting.md b/doc/administration/gitaly/troubleshooting.md
index f95d7f44e3c..d383ebfe3e8 100644
--- a/doc/administration/gitaly/troubleshooting.md
+++ b/doc/administration/gitaly/troubleshooting.md
@@ -20,7 +20,8 @@ and our advice on [parsing the `gitaly/current` file](../logs/log_parsing.md#par
When using standalone Gitaly servers, you must make sure they are the same version
as GitLab to ensure full compatibility:
-1. On the top bar, select **Main menu > Admin** on your GitLab instance.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Overview > Gitaly Servers**.
1. Confirm all Gitaly servers indicate that they are up to date.
diff --git a/doc/administration/integration/diagrams_net.md b/doc/administration/integration/diagrams_net.md
index fe5e730a064..a4e8528fb25 100644
--- a/doc/administration/integration/diagrams_net.md
+++ b/doc/administration/integration/diagrams_net.md
@@ -43,7 +43,8 @@ For more information, see [Run your own diagrams.net server with Docker](https:/
## Enable Diagrams.net integration
1. Sign in to GitLab as an [Administrator](../../user/permissions.md) user.
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Settings > General**.
1. Expand **Diagrams.net**.
1. Select the **Enable Diagrams.net** checkbox.
diff --git a/doc/administration/integration/kroki.md b/doc/administration/integration/kroki.md
index f90458200b3..0356212d6dd 100644
--- a/doc/administration/integration/kroki.md
+++ b/doc/administration/integration/kroki.md
@@ -61,7 +61,8 @@ read the [Kroki installation](https://docs.kroki.io/kroki/setup/install/#_images
You need to enable Kroki integration from Settings under Admin Area.
To do that, sign in with an administrator account and follow these steps:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. Go to **Settings > General**.
1. Expand the **Kroki** section.
1. Select **Enable Kroki** checkbox.
diff --git a/doc/administration/integration/mailgun.md b/doc/administration/integration/mailgun.md
index 218b2888033..87428d27c66 100644
--- a/doc/administration/integration/mailgun.md
+++ b/doc/administration/integration/mailgun.md
@@ -43,7 +43,8 @@ After configuring your Mailgun domain for the webhook endpoints,
you're ready to enable the Mailgun integration:
1. Sign in to GitLab as an [Administrator](../../user/permissions.md) user.
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, go to **Settings > General** and expand the **Mailgun** section.
1. Select the **Enable Mailgun** checkbox.
1. Enter the Mailgun HTTP webhook signing key as described in
diff --git a/doc/administration/integration/plantuml.md b/doc/administration/integration/plantuml.md
index 0e625590262..bb72d7070be 100644
--- a/doc/administration/integration/plantuml.md
+++ b/doc/administration/integration/plantuml.md
@@ -308,7 +308,8 @@ stop;
After configuring your local PlantUML server, you're ready to enable the PlantUML integration:
1. Sign in to GitLab as an [Administrator](../../user/permissions.md) user.
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, go to **Settings > General** and expand the **PlantUML** section.
1. Select the **Enable PlantUML** checkbox.
1. Set the PlantUML instance as `https://gitlab.example.com/-/plantuml/`,
diff --git a/doc/administration/integration/terminal.md b/doc/administration/integration/terminal.md
index df9bb6b6e17..bea389a8f0a 100644
--- a/doc/administration/integration/terminal.md
+++ b/doc/administration/integration/terminal.md
@@ -114,7 +114,7 @@ they receive a `Connection failed` message.
By default, terminal sessions do not expire. To limit the terminal session
lifetime in your GitLab instance:
-1. On the top bar, select **Main menu > Admin**.
-1. Select
- [**Settings > Web terminal**](../../user/admin_area/settings/index.md#general).
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
+1. Select [**Settings > Web terminal**](../../user/admin_area/settings/index.md#general).
1. Set a `max session time`.
diff --git a/doc/administration/maintenance_mode/index.md b/doc/administration/maintenance_mode/index.md
index 8347015a8a3..3bbebe7ecce 100644
--- a/doc/administration/maintenance_mode/index.md
+++ b/doc/administration/maintenance_mode/index.md
@@ -21,7 +21,8 @@ Maintenance Mode allows most external actions that do not change internal state.
Enable Maintenance Mode as an administrator in one of these ways:
- **Web UI**:
- 1. On the top bar, select **Main menu > Admin**.
+ 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+ 1. Select **Admin Area**.
1. On the left sidebar, select **Settings > General**.
1. Expand **Maintenance Mode**, and toggle **Enable Maintenance Mode**.
You can optionally add a message for the banner as well.
@@ -45,7 +46,8 @@ Enable Maintenance Mode as an administrator in one of these ways:
Disable Maintenance Mode in one of three ways:
- **Web UI**:
- 1. On the top bar, select **Main menu > Admin**.
+ 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+ 1. Select **Admin Area**.
1. On the left sidebar, select **Settings > General**.
1. Expand **Maintenance Mode**, and toggle **Enable Maintenance Mode**.
You can optionally add a message for the banner as well.
@@ -173,7 +175,8 @@ you should disable all cron jobs except for those related to Geo.
To monitor queues and disable jobs:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
### Incident management
diff --git a/doc/administration/monitoring/performance/gitlab_configuration.md b/doc/administration/monitoring/performance/gitlab_configuration.md
index cb5852a7dac..0d2037f3a92 100644
--- a/doc/administration/monitoring/performance/gitlab_configuration.md
+++ b/doc/administration/monitoring/performance/gitlab_configuration.md
@@ -9,7 +9,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
GitLab Performance Monitoring is disabled by default. To enable it and change any of its
settings:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Settings > Metrics and profiling**
(`/admin/application_settings/metrics_and_profiling`).
1. Add the necessary configuration changes.
diff --git a/doc/administration/monitoring/performance/grafana_configuration.md b/doc/administration/monitoring/performance/grafana_configuration.md
index 4045e06fbff..b448ac461c8 100644
--- a/doc/administration/monitoring/performance/grafana_configuration.md
+++ b/doc/administration/monitoring/performance/grafana_configuration.md
@@ -86,7 +86,8 @@ repository.
After setting up Grafana, you can enable a link to access it from the
GitLab sidebar:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Settings > Metrics and profiling**
and expand **Metrics - Grafana**.
1. Select the **Add a link to Grafana** checkbox.
diff --git a/doc/administration/monitoring/performance/performance_bar.md b/doc/administration/monitoring/performance/performance_bar.md
index fc6318922f1..3fdd4c24177 100644
--- a/doc/administration/monitoring/performance/performance_bar.md
+++ b/doc/administration/monitoring/performance/performance_bar.md
@@ -108,7 +108,8 @@ The performance bar is disabled by default for non-administrators. To enable it
for a given group:
1. Sign in as a user with administrator access.
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Settings > Metrics and profiling**
(`admin/application_settings/metrics_and_profiling`), and expand
**Profiling - Performance bar**.
diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md
index 26b9fac8b79..5d6827b79ee 100644
--- a/doc/administration/monitoring/prometheus/gitlab_metrics.md
+++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md
@@ -9,7 +9,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
To enable the GitLab Prometheus metrics:
1. Log in to GitLab as a user with administrator access.
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Settings > Metrics and profiling**.
1. Find the **Metrics - Prometheus** section, and select **Enable GitLab Prometheus metrics endpoint**.
1. [Restart GitLab](../../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
diff --git a/doc/administration/operations/fast_ssh_key_lookup.md b/doc/administration/operations/fast_ssh_key_lookup.md
index 1e887d8bd67..d54d286c19d 100644
--- a/doc/administration/operations/fast_ssh_key_lookup.md
+++ b/doc/administration/operations/fast_ssh_key_lookup.md
@@ -121,7 +121,8 @@ users as long as a large file exists.
To disable writes to the `authorized_keys` file:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Settings > Network**.
1. Expand **Performance optimization**.
1. Clear the **Use authorized_keys file to authenticate SSH keys** checkbox.
@@ -140,7 +141,8 @@ This overview is brief. Refer to the above instructions for more context.
1. [Rebuild the `authorized_keys` file](../raketasks/maintenance.md#rebuild-authorized_keys-file).
1. Enable writes to the `authorized_keys` file.
- 1. On the top bar, select **Main menu > Admin**.
+ 1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+ 1. Select **Admin Area**.
1. On the left sidebar, select **Settings > Network**.
1. Expand **Performance optimization**.
1. Select the **Use authorized_keys file to authenticate SSH keys** checkbox.
diff --git a/doc/administration/packages/container_registry.md b/doc/administration/packages/container_registry.md
index 53ae7046292..e3867a25846 100644
--- a/doc/administration/packages/container_registry.md
+++ b/doc/administration/packages/container_registry.md
@@ -325,7 +325,8 @@ the Container Registry by themselves, follow the steps below.
In GitLab, tokens for the Container Registry expire every five minutes.
To increase the token duration:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand **Container Registry**.
1. For the **Authorization token duration (minutes)**, update the value.
diff --git a/doc/administration/pages/source.md b/doc/administration/pages/source.md
index b36b87f3b1d..2ee9dd653f0 100644
--- a/doc/administration/pages/source.md
+++ b/doc/administration/pages/source.md
@@ -483,7 +483,8 @@ The default for the maximum size of unpacked archives per project is 100 MB.
To change this value:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Settings > Preferences**.
1. Expand **Pages**.
1. Update the value for **Maximum size of pages (MB)**.
diff --git a/doc/administration/pages/troubleshooting.md b/doc/administration/pages/troubleshooting.md
index 27322c2a537..e829943f270 100644
--- a/doc/administration/pages/troubleshooting.md
+++ b/doc/administration/pages/troubleshooting.md
@@ -170,7 +170,8 @@ Upgrading to an [officially supported operating system](https://about.gitlab.com
This problem comes from the permissions of the GitLab Pages OAuth application. To fix it:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Applications > GitLab Pages**.
1. Edit the application.
1. Under **Scopes**, ensure that the `api` scope is selected.
diff --git a/doc/administration/raketasks/storage.md b/doc/administration/raketasks/storage.md
index d740aaa9c96..3664a79bf43 100644
--- a/doc/administration/raketasks/storage.md
+++ b/doc/administration/raketasks/storage.md
@@ -109,7 +109,8 @@ sudo gitlab-rake gitlab:storage:migrate_to_hashed ID_FROM=50 ID_TO=100
To monitor the progress in GitLab:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. Watch how long the `hashed_storage:hashed_storage_project_migrate` queue
takes to finish. After it reaches zero, you can confirm every project
diff --git a/doc/administration/sidekiq/extra_sidekiq_processes.md b/doc/administration/sidekiq/extra_sidekiq_processes.md
index 7959d1a5ce7..31e713bbf06 100644
--- a/doc/administration/sidekiq/extra_sidekiq_processes.md
+++ b/doc/administration/sidekiq/extra_sidekiq_processes.md
@@ -48,7 +48,8 @@ to all available queues:
To view the Sidekiq processes in GitLab:
-1. On the top bar, select **Main menu > Admin**.
+1. On the left sidebar, expand the top-most chevron (**{chevron-down}**).
+1. Select **Admin Area**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
## Concurrency
diff --git a/doc/user/clusters/agent/vulnerabilities.md b/doc/user/clusters/agent/vulnerabilities.md
index cb12b23bcfb..74676e31d22 100644
--- a/doc/user/clusters/agent/vulnerabilities.md
+++ b/doc/user/clusters/agent/vulnerabilities.md
@@ -15,11 +15,11 @@ You can also configure your agent so the vulnerabilities are displayed with othe
## Enable operational container scanning
You can use operational container scanning to scan container images in your cluster for security vulnerabilities. You
-can enable the scanner to run on a cadence as configured via the agent, or setup scan execution policies within a
+can enable the scanner to run on a cadence as configured via the `agent config`, or setup `scan execution policies` within a
project that houses the agent.
NOTE:
-In GitLab 15.0 and later, you do not need to install Starboard operator in the Kubernetes cluster.
+If both `agent config` and `scan execution policies` are configured, the configuration from `scan execution policy` takes precedence.
### Enable via agent configuration
@@ -56,7 +56,7 @@ container_scanning:
- kube-system
```
-## Enable via scan execution policies
+### Enable via scan execution policies
To enable scanning of all images within your Kubernetes cluster via scan execution policies, we can use the
[scan execution policy editor](../../application_security/policies/scan-execution-policies.md#scan-execution-policy-editor)
@@ -96,6 +96,35 @@ The CRON expression is evaluated in [UTC](https://www.timeanddate.com/worldclock
You can view the complete schema within the [scan execution policy documentation](../../application_security/policies/scan-execution-policies.md#scan-execution-policies-schema).
+## Configure scanner resource requirements
+
+By default the scanner pod's default resource requirements are:
+
+```yaml
+requests:
+ cpu: 100m
+ memory: 100Mi
+limits:
+ cpu: 500m
+ memory: 500Mi
+```
+
+You can customize it with a `resource_requirements` field.
+
+```yaml
+container_scanning:
+ resource_requirements:
+ requests:
+ cpu: 200m
+ memory: 200Mi
+ limits:
+ cpu: 700m
+ memory: 700Mi
+```
+
+NOTE:
+Resource requirements can only be set up using the agent configuration. If you enabled `Operational Container Scanning` through `scan execution policies`, you would need to define the resource requirements within the agent configuration file.
+
## View cluster vulnerabilities
To view vulnerability information in GitLab:
diff --git a/doc/user/project/integrations/telegram.md b/doc/user/project/integrations/telegram.md
index d2e402d0bd0..fabea52629d 100644
--- a/doc/user/project/integrations/telegram.md
+++ b/doc/user/project/integrations/telegram.md
@@ -31,6 +31,8 @@ To configure the bot in Telegram:
1. Add the bot as an administrator to a new or existing channel.
1. Assign the bot `Post Messages` rights to receive events.
1. Create an identifier for the channel.
+ - For public channels, enter a public link and copy the channel identifier (for example, `https:/t.me/MY_IDENTIFIER`).
+ - For private channels, use the [`getUpdates`](https://telegram-bot-sdk.readme.io/reference/getupdates) method with your API token and copy the channel identifier.
## Set up the Telegram integration in GitLab
@@ -47,8 +49,7 @@ After you invite the bot to a Telegram channel, you can configure GitLab to send
1. In **Enable integration**, select the **Active** checkbox.
1. In **New token**, [paste the token value from the Telegram bot](#create-a-telegram-bot).
1. In the **Trigger** section, select the checkboxes for the GitLab events you want to receive in Telegram.
-1. In **Channel identifier**, [paste the channel identifier from the Telegram channel](#configure-the-telegram-bot).
- - To get a private channel ID, use the [`getUpdates`](https://core.telegram.org/bots/api#getupdates) method.
+1. In **Channel identifier**, [paste the Telegram channel identifier](#configure-the-telegram-bot).
1. Optional. Select **Test settings**.
1. Select **Save changes**.
diff --git a/lib/gitlab/error_tracking/processor/grpc_error_processor.rb b/lib/gitlab/error_tracking/processor/grpc_error_processor.rb
index c141398bee0..ab0df39e512 100644
--- a/lib/gitlab/error_tracking/processor/grpc_error_processor.rb
+++ b/lib/gitlab/error_tracking/processor/grpc_error_processor.rb
@@ -6,8 +6,7 @@ module Gitlab
module GrpcErrorProcessor
extend Gitlab::ErrorTracking::Processor::Concerns::ProcessesExceptions
- # Braces added by gRPC Ruby code: https://github.com/grpc/grpc/blob/0e38b075ffff72ab2ad5326e3f60ba6dcc234f46/src/ruby/lib/grpc/errors.rb#L46
- DEBUG_ERROR_STRING_REGEX = RE2('(.*) debug_error_string:\{(.*)\}')
+ DEBUG_ERROR_STRING_REGEX = RE2('(.*) debug_error_string:(.*)')
class << self
def call(event)
diff --git a/lib/gitlab/usage/metrics/instrumentations/count_personal_snippets_metric.rb b/lib/gitlab/usage/metrics/instrumentations/count_personal_snippets_metric.rb
new file mode 100644
index 00000000000..9a34c535676
--- /dev/null
+++ b/lib/gitlab/usage/metrics/instrumentations/count_personal_snippets_metric.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Usage
+ module Metrics
+ module Instrumentations
+ class CountPersonalSnippetsMetric < DatabaseMetric
+ operation :count
+
+ relation do
+ PersonalSnippet
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/usage/metrics/instrumentations/count_project_snippets_metric.rb b/lib/gitlab/usage/metrics/instrumentations/count_project_snippets_metric.rb
new file mode 100644
index 00000000000..af25a32592c
--- /dev/null
+++ b/lib/gitlab/usage/metrics/instrumentations/count_project_snippets_metric.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Usage
+ module Metrics
+ module Instrumentations
+ class CountProjectSnippetsMetric < DatabaseMetric
+ operation :count
+
+ relation do
+ ProjectSnippet
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/usage/metrics/instrumentations/count_snippets_metric.rb b/lib/gitlab/usage/metrics/instrumentations/count_snippets_metric.rb
new file mode 100644
index 00000000000..342ba802fd8
--- /dev/null
+++ b/lib/gitlab/usage/metrics/instrumentations/count_snippets_metric.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Usage
+ module Metrics
+ module Instrumentations
+ class CountSnippetsMetric < DatabaseMetric
+ operation :count
+ # Relation and operation are not used, but are included to satisfy expectations
+ # of other metric generation logic.
+ relation { Snippet }
+
+ def value
+ count(project_snippet_relation) + count(personal_snippet_relation)
+ end
+
+ def project_snippet_relation
+ ProjectSnippet.where(time_constraints)
+ end
+
+ def personal_snippet_relation
+ PersonalSnippet.where(time_constraints)
+ end
+
+ def to_sql
+ project_snippet_relation_sql = Gitlab::Usage::Metrics::Query.for(:count, project_snippet_relation)
+ personal_snippet_relation_sql = Gitlab::Usage::Metrics::Query.for(:count, personal_snippet_relation)
+
+ "SELECT (#{project_snippet_relation_sql}) + (#{personal_snippet_relation_sql})"
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index ae6e111da62..3c810be04c8 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -122,8 +122,6 @@ module Gitlab
protected_branches_except_default: count(ProtectedBranch.where.not(name: ['main', 'master', Gitlab::CurrentSettings.default_branch_name])),
releases: count(Release),
remote_mirrors: count(RemoteMirror),
- personal_snippets: count(PersonalSnippet),
- project_snippets: count(ProjectSnippet),
suggestions: count(Suggestion),
terraform_reports: count(::Ci::JobArtifact.of_report_type(:terraform)),
terraform_states: count(::Terraform::State),
@@ -137,9 +135,7 @@ module Gitlab
integrations_usage,
user_preferences_usage,
service_desk_counts
- ).tap do |data|
- data[:snippets] = add(data[:personal_snippets], data[:project_snippets])
- end
+ )
}
end
# rubocop: enable Metrics/AbcSize
@@ -154,12 +150,8 @@ module Gitlab
# rubocop: enable UsageData/LargeTable:
projects: count(Project.where(monthly_time_range_db_params), start: minimum_id(Project), finish: maximum_id(Project)),
packages: count(::Packages::Package.where(monthly_time_range_db_params)),
- personal_snippets: count(PersonalSnippet.where(monthly_time_range_db_params)),
- project_snippets: count(ProjectSnippet.where(monthly_time_range_db_params)),
projects_with_alerts_created: distinct_count(::AlertManagement::Alert.where(monthly_time_range_db_params), :project_id)
- }.tap do |data|
- data[:snippets] = add(data[:personal_snippets], data[:project_snippets])
- end
+ }
}
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 95c704dc06c..69a59255ae1 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -778,7 +778,10 @@ msgstr ""
msgid "%{integrations_link_start}Integrations%{link_end} enable you to make third-party applications part of your GitLab workflow. If the available integrations don't meet your needs, consider using a %{webhooks_link_start}webhook%{link_end}."
msgstr ""
-msgid "%{issuableDisplayName} %{lockStatus}."
+msgid "%{issuableDisplayName} locked."
+msgstr ""
+
+msgid "%{issuableDisplayName} unlocked."
msgstr ""
msgid "%{issuableType} will be removed! Are you sure?"
@@ -10009,6 +10012,9 @@ msgstr ""
msgid "Close"
msgstr ""
+msgid "Close %{issuableType}"
+msgstr ""
+
msgid "Close %{issueType}"
msgstr ""
@@ -10066,6 +10072,9 @@ msgstr ""
msgid "Closes this issue. Marks as related to, and a duplicate of, %{duplicate_reference}."
msgstr ""
+msgid "Closing %{issuableType}..."
+msgstr ""
+
msgid "Cloud Run"
msgstr ""
@@ -27391,6 +27400,9 @@ msgstr ""
msgid "Locked the discussion."
msgstr ""
+msgid "Locking %{issuableDisplayName}"
+msgstr ""
+
msgid "Locks the discussion."
msgstr ""
@@ -38334,6 +38346,9 @@ msgstr ""
msgid "Reopen"
msgstr ""
+msgid "Reopen %{issuableType}"
+msgstr ""
+
msgid "Reopen %{issueType}"
msgstr ""
@@ -38358,6 +38373,9 @@ msgstr ""
msgid "Reopened this %{quick_action_target}."
msgstr ""
+msgid "Reopening %{issuableType}..."
+msgstr ""
+
msgid "Reopening..."
msgstr ""
@@ -48681,7 +48699,7 @@ msgstr ""
msgid "Unlock"
msgstr ""
-msgid "Unlock %{issuableType}"
+msgid "Unlock %{issuableDisplayName}"
msgstr ""
msgid "Unlock account"
@@ -48702,6 +48720,9 @@ msgstr ""
msgid "Unlocked the discussion."
msgstr ""
+msgid "Unlocking %{issuableDisplayName}"
+msgstr ""
+
msgid "Unlocks the discussion."
msgstr ""
@@ -54414,9 +54435,6 @@ msgstr ""
msgid "loading"
msgstr ""
-msgid "locked"
-msgstr ""
-
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -55333,9 +55351,6 @@ msgstr ""
msgid "unicode domains should use IDNA encoding"
msgstr ""
-msgid "unlocked"
-msgstr ""
-
msgid "updated"
msgstr ""
diff --git a/spec/features/merge_request/close_reopen_report_toggle_spec.rb b/spec/features/merge_request/close_reopen_report_toggle_spec.rb
index 9b8e50a31e3..07d9ddde910 100644
--- a/spec/features/merge_request/close_reopen_report_toggle_spec.rb
+++ b/spec/features/merge_request/close_reopen_report_toggle_spec.rb
@@ -15,6 +15,7 @@ RSpec.describe 'Issuables Close/Reopen/Report toggle', feature_category: :code_r
before do
project.add_maintainer(user)
login_as user
+ stub_feature_flags(moved_mr_sidebar: false)
end
context 'when user has permission to update', :js do
@@ -24,15 +25,16 @@ RSpec.describe 'Issuables Close/Reopen/Report toggle', feature_category: :code_r
context 'close/reopen/report toggle' do
it 'opens a dropdown when toggle is clicked' do
- find('[data-testid="merge-request-actions"]').click
+ find('#new-actions-header-dropdown button').click
- expect(container).to have_link("Close merge request")
- expect(container).to have_button('Report abuse to administrator')
+ expect(container).to have_button("Close merge request")
+ expect(container).to have_button('Report abuse')
end
it 'links to Report Abuse' do
- find('[data-testid="merge-request-actions"]').click
- click_button 'Report abuse to administrator'
+ find('#new-actions-header-dropdown button').click
+
+ click_button 'Report abuse'
expect(page).to have_content('Report abuse to administrator')
end
@@ -42,13 +44,13 @@ RSpec.describe 'Issuables Close/Reopen/Report toggle', feature_category: :code_r
let(:issuable) { create(:merge_request, :opened, source_project: project) }
it 'shows the `Edit` and `Mark as draft` buttons' do
- find('[data-testid="merge-request-actions"]').click
+ find('#new-actions-header-dropdown button').click
expect(container).to have_link('Edit')
- expect(container).to have_link('Mark as draft')
- expect(container).to have_link('Close merge request')
- expect(container).to have_button('Report abuse to administrator')
- expect(container).not_to have_link('Reopen merge request')
+ expect(container).to have_button('Mark as draft')
+ expect(container).to have_button('Close merge request')
+ expect(container).to have_button('Report abuse')
+ expect(container).not_to have_button('Reopen merge request')
end
end
@@ -56,24 +58,24 @@ RSpec.describe 'Issuables Close/Reopen/Report toggle', feature_category: :code_r
let(:issuable) { create(:merge_request, :closed, source_project: project) }
it 'shows both the `Edit` and `Reopen` button' do
- find('[data-testid="merge-request-actions"]').click
+ find('#new-actions-header-dropdown button').click
expect(container).to have_link('Edit')
- expect(container).to have_button('Report abuse to administrator')
- expect(container).to have_link('Reopen merge request')
- expect(container).not_to have_link('Close merge request')
+ expect(container).to have_button('Report abuse')
+ expect(container).to have_button('Reopen merge request')
+ expect(container).not_to have_button('Close merge request')
end
context 'when the merge request author is the current user' do
let(:issuable) { create(:merge_request, :closed, source_project: project, author: user) }
it 'shows both the `Edit` and `Reopen` button' do
- find('[data-testid="merge-request-actions"]').click
+ find('#new-actions-header-dropdown button').click
expect(container).to have_link('Edit')
- expect(container).to have_link('Reopen merge request')
- expect(container).not_to have_link('Close merge request')
- expect(container).not_to have_button('Report abuse to administrator')
+ expect(container).to have_button('Reopen merge request')
+ expect(container).not_to have_button('Close merge request')
+ expect(container).not_to have_button('Report abuse')
end
end
end
@@ -83,7 +85,7 @@ RSpec.describe 'Issuables Close/Reopen/Report toggle', feature_category: :code_r
it 'shows only the `Edit` button' do
expect(container).to have_link(exact_text: 'Edit')
- expect(container).not_to have_button('Report abuse to administrator')
+ expect(container).not_to have_button('Report abuse')
expect(container).not_to have_button('Close merge request')
expect(container).not_to have_button('Reopen merge request')
end
@@ -93,7 +95,7 @@ RSpec.describe 'Issuables Close/Reopen/Report toggle', feature_category: :code_r
it 'shows only the `Edit` button' do
expect(container).to have_link(exact_text: 'Edit')
- expect(container).not_to have_button('Report abuse to administrator')
+ expect(container).not_to have_button('Report abuse')
expect(container).not_to have_button('Close merge request')
expect(container).not_to have_button('Reopen merge request')
end
@@ -112,9 +114,9 @@ RSpec.describe 'Issuables Close/Reopen/Report toggle', feature_category: :code_r
end
it 'only shows a `Report abuse` button' do
- find('[data-testid="merge-request-actions"]').click
+ find('#new-actions-header-dropdown button').click
- expect(container).to have_button('Report abuse to administrator')
+ expect(container).to have_button('Report abuse')
expect(container).not_to have_button('Close merge request')
expect(container).not_to have_button('Reopen merge request')
expect(container).not_to have_link(exact_text: 'Edit')
diff --git a/spec/features/merge_request/merge_request_discussion_lock_spec.rb b/spec/features/merge_request/merge_request_discussion_lock_spec.rb
index 11ec2a86b43..782c4af58ac 100644
--- a/spec/features/merge_request/merge_request_discussion_lock_spec.rb
+++ b/spec/features/merge_request/merge_request_discussion_lock_spec.rb
@@ -90,7 +90,7 @@ RSpec.describe 'Merge Request Discussion Lock', :js, feature_category: :code_rev
end
it 'the user can lock the merge_request' do
- find('[data-testid="merge-request-actions"]').click
+ find('#new-actions-header-dropdown button').click
expect(page).to have_content('Lock merge request')
end
@@ -103,7 +103,7 @@ RSpec.describe 'Merge Request Discussion Lock', :js, feature_category: :code_rev
end
it 'the user can unlock the merge_request' do
- find('[data-testid="merge-request-actions"]').click
+ find('#new-actions-header-dropdown button').click
expect(page).to have_content('Unlock merge request')
end
diff --git a/spec/features/merge_request/user_manages_subscription_spec.rb b/spec/features/merge_request/user_manages_subscription_spec.rb
index 3bcc8255ab7..84387965989 100644
--- a/spec/features/merge_request/user_manages_subscription_spec.rb
+++ b/spec/features/merge_request/user_manages_subscription_spec.rb
@@ -45,15 +45,15 @@ RSpec.describe 'User manages subscription', :js, feature_category: :code_review_
it 'toggles subscription' do
wait_for_requests
- find('[data-testid="merge-request-actions"]').click
+ find('#new-actions-header-dropdown button').click
expect(page).to have_selector('.gl-toggle:not(.is-checked)')
- find('[data-testid="notifications-toggle"] .gl-toggle').click
+ find('[data-testid="notification-toggle"] .gl-toggle').click
wait_for_requests
expect(page).to have_selector('.gl-toggle.is-checked')
- find('[data-testid="notifications-toggle"] .gl-toggle').click
+ find('[data-testid="notification-toggle"] .gl-toggle').click
wait_for_requests
diff --git a/spec/features/merge_request/user_marks_merge_request_as_draft_spec.rb b/spec/features/merge_request/user_marks_merge_request_as_draft_spec.rb
index 8cbc2b975e4..70962890bc5 100644
--- a/spec/features/merge_request/user_marks_merge_request_as_draft_spec.rb
+++ b/spec/features/merge_request/user_marks_merge_request_as_draft_spec.rb
@@ -16,15 +16,15 @@ RSpec.describe 'Merge request > User marks merge request as draft', :js, feature
end
it 'toggles draft status' do
- find('[data-testid="merge-request-actions"]').click
- click_link 'Mark as draft'
+ find('#new-actions-header-dropdown button').click
+ click_button 'Mark as draft'
expect(page).to have_content("Draft: #{merge_request.title}")
- find('[data-testid="merge-request-actions"]').click
+ find('#new-actions-header-dropdown button').click
page.within('.detail-page-header-actions') do
- click_link 'Mark as ready'
+ click_button 'Mark as ready'
end
expect(page).to have_content(merge_request.title)
diff --git a/spec/frontend/merge_request_spec.js b/spec/frontend/merge_request_spec.js
index 6f80f8e6aab..a119ca8272e 100644
--- a/spec/frontend/merge_request_spec.js
+++ b/spec/frontend/merge_request_spec.js
@@ -1,7 +1,6 @@
import MockAdapter from 'axios-mock-adapter';
import $ from 'jquery';
import htmlMergeRequestWithTaskList from 'test_fixtures/merge_requests/merge_request_with_task_list.html';
-import htmlMergeRequestOfCurrentUser from 'test_fixtures/merge_requests/merge_request_of_current_user.html';
import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import { TEST_HOST } from 'spec/test_constants';
import waitForPromises from 'helpers/wait_for_promises';
@@ -110,20 +109,4 @@ describe('MergeRequest', () => {
});
});
});
-
- describe('hideCloseButton', () => {
- describe('merge request of current_user', () => {
- beforeEach(() => {
- setHTMLFixture(htmlMergeRequestOfCurrentUser);
- test.el = document.querySelector('.js-issuable-actions');
- MergeRequest.hideCloseButton();
- });
-
- it('hides the close button', () => {
- const smallCloseItem = test.el.querySelector('.js-close-item');
-
- expect(smallCloseItem).toHaveClass('hidden');
- });
- });
- });
});
diff --git a/spec/frontend/sidebar/components/lock/issuable_lock_form_spec.js b/spec/frontend/sidebar/components/lock/issuable_lock_form_spec.js
index 5e766e9a41c..47f68e1fe83 100644
--- a/spec/frontend/sidebar/components/lock/issuable_lock_form_spec.js
+++ b/spec/frontend/sidebar/components/lock/issuable_lock_form_spec.js
@@ -7,6 +7,7 @@ import createStore from '~/notes/stores';
import EditForm from '~/sidebar/components/lock/edit_form.vue';
import IssuableLockForm from '~/sidebar/components/lock/issuable_lock_form.vue';
import toast from '~/vue_shared/plugins/global_toast';
+import waitForPromises from 'helpers/wait_for_promises';
import { ISSUABLE_TYPE_ISSUE, ISSUABLE_TYPE_MR } from './constants';
jest.mock('~/vue_shared/plugins/global_toast');
@@ -27,6 +28,7 @@ describe('IssuableLockForm', () => {
const findLockStatus = () => wrapper.find('[data-testid="lock-status"]');
const findEditLink = () => wrapper.find('[data-testid="edit-link"]');
const findEditForm = () => wrapper.findComponent(EditForm);
+ const findLockButton = () => wrapper.find('[data-testid="issuable-lock"]');
const findSidebarLockStatusTooltip = () =>
getBinding(findSidebarCollapseIcon().element, 'gl-tooltip');
const findIssuableLockClickable = () => wrapper.find('[data-testid="issuable-lock"]');
@@ -172,7 +174,9 @@ describe('IssuableLockForm', () => {
createComponent({ movedMrSidebar: true });
- await wrapper.find('.dropdown-item').trigger('click');
+ await findLockButton().trigger('click');
+
+ await waitForPromises();
expect(toast).toHaveBeenCalledWith(message);
});
@@ -187,7 +191,7 @@ describe('IssuableLockForm', () => {
});
describe('when the flag is on', () => {
- it('does not show the non editable lock status', () => {
+ it('shows the non editable lock status', () => {
createComponent({ movedMrSidebar: true });
expect(findIssuableLockClickable().exists()).toBe(true);
});
diff --git a/spec/frontend/sidebar/components/subscriptions/sidebar_subscriptions_widget_spec.js b/spec/frontend/sidebar/components/subscriptions/sidebar_subscriptions_widget_spec.js
index 7275557e7f2..39b80c1d886 100644
--- a/spec/frontend/sidebar/components/subscriptions/sidebar_subscriptions_widget_spec.js
+++ b/spec/frontend/sidebar/components/subscriptions/sidebar_subscriptions_widget_spec.js
@@ -1,4 +1,4 @@
-import { GlIcon, GlToggle } from '@gitlab/ui';
+import { GlDisclosureDropdownItem, GlIcon, GlToggle } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
@@ -28,6 +28,7 @@ describe('Sidebar Subscriptions Widget', () => {
const findEditableItem = () => wrapper.findComponent(SidebarEditableItem);
const findToggle = () => wrapper.findComponent(GlToggle);
const findIcon = () => wrapper.findComponent(GlIcon);
+ const findDropdownToggleItem = () => wrapper.findComponent(GlDisclosureDropdownItem);
const createComponent = ({
subscriptionsQueryHandler = jest.fn().mockResolvedValue(issueSubscriptionsResponse()),
@@ -155,7 +156,7 @@ describe('Sidebar Subscriptions Widget', () => {
});
await waitForPromises();
- await wrapper.find('[data-testid="notifications-toggle"]').vm.$emit('change');
+ await findDropdownToggleItem().vm.$emit('action');
await waitForPromises();
diff --git a/spec/frontend/vue_shared/components/mr_more_dropdown_spec.js b/spec/frontend/vue_shared/components/mr_more_dropdown_spec.js
new file mode 100644
index 00000000000..41639725f66
--- /dev/null
+++ b/spec/frontend/vue_shared/components/mr_more_dropdown_spec.js
@@ -0,0 +1,137 @@
+import { shallowMount } from '@vue/test-utils';
+import MRMoreActionsDropdown from '~/vue_shared/components/mr_more_dropdown.vue';
+
+describe('MR More actions sidebar', () => {
+ let wrapper;
+
+ const findNotificationToggle = () => wrapper.find('[data-testid="notification-toggle"]');
+ const findEditMergeRequestOption = () => wrapper.find('[data-testid="edit-merge-request"]');
+ const findMarkAsReadyAndDraftOption = () =>
+ wrapper.find('[data-testid="ready-and-draft-action"]');
+ const findCopyReferenceButton = () => wrapper.find('[data-testid="copy-reference"]');
+ const findReopenMergeRequestOption = () => wrapper.find('[data-testid="reopen-merge-request"]');
+ const findReportAbuseOption = () => wrapper.find('[data-testid="report-abuse-option"]');
+
+ const createComponent = ({
+ movedMrSidebarFlag = false,
+ isCurrentUser = true,
+ isLoggedIn = true,
+ open = false,
+ canUpdateMergeRequest = false,
+ } = {}) => {
+ wrapper = shallowMount(MRMoreActionsDropdown, {
+ propsData: {
+ mr: {
+ iid: 1,
+ },
+ isCurrentUser,
+ isLoggedIn,
+ open,
+ canUpdateMergeRequest,
+ },
+ provide: {
+ glFeatures: { movedMrSidebar: movedMrSidebarFlag },
+ },
+ });
+ };
+
+ describe('Notifications toggle', () => {
+ it.each`
+ movedMrSidebarFlag | isLoggedIn | showNotificationToggle
+ ${false} | ${false} | ${false}
+ ${false} | ${true} | ${false}
+ ${true} | ${false} | ${false}
+ ${true} | ${true} | ${true}
+ `(
+ "when the movedMrSidebar flag is '$movedMrSidebarFlag' and is isLoggedIn as '$isLoggedIn'",
+ ({ movedMrSidebarFlag, isLoggedIn, showNotificationToggle }) => {
+ createComponent({
+ isLoggedIn,
+ movedMrSidebarFlag,
+ });
+
+ expect(findNotificationToggle().exists()).toBe(showNotificationToggle);
+ },
+ );
+ });
+
+ describe('Edit/Draft/Reopen MR', () => {
+ it('should not have the edit option when `canUpdateMergeRequest` is false', () => {
+ createComponent();
+
+ expect(findEditMergeRequestOption().exists()).toBe(false);
+ });
+
+ it('should have the edit option when `canUpdateMergeRequest` is true', () => {
+ createComponent({
+ canUpdateMergeRequest: true,
+ });
+
+ expect(findEditMergeRequestOption().exists()).toBe(true);
+ });
+
+ it('should not have the ready and draft option when the the MR is open and `canUpdateMergeRequest` is false', () => {
+ createComponent({
+ open: true,
+ canUpdateMergeRequest: false,
+ });
+
+ expect(findMarkAsReadyAndDraftOption().exists()).toBe(false);
+ });
+
+ it('should have the ready and draft option when the the MR is open and `canUpdateMergeRequest` is true', () => {
+ createComponent({
+ open: true,
+ canUpdateMergeRequest: true,
+ });
+
+ expect(findMarkAsReadyAndDraftOption().exists()).toBe(true);
+ });
+
+ it('should have the reopen option when the the MR is closed and `canUpdateMergeRequest` is true', () => {
+ createComponent({
+ open: false,
+ canUpdateMergeRequest: true,
+ });
+
+ expect(findReopenMergeRequestOption().exists()).toBe(true);
+ });
+
+ it('should not have the reopen option when the the MR is closed and `canUpdateMergeRequest` is false', () => {
+ createComponent({
+ open: false,
+ canUpdateMergeRequest: false,
+ });
+
+ expect(findReopenMergeRequestOption().exists()).toBe(false);
+ });
+ });
+
+ describe('Copy reference', () => {
+ it('should not be visible by default', () => {
+ createComponent();
+
+ expect(findCopyReferenceButton().exists()).toBe(false);
+ });
+
+ it('should be visible when the movedMrSidebarFlag is on', () => {
+ createComponent({ movedMrSidebarFlag: true });
+
+ expect(findCopyReferenceButton().exists()).toBe(true);
+ });
+ });
+
+ describe('Report abuse action', () => {
+ it('should not have the option by default', () => {
+ createComponent();
+
+ expect(findReportAbuseOption().exists()).toBe(false);
+ });
+
+ it('should have the option when not the current user', () => {
+ createComponent({ isCurrentUser: false });
+
+ expect(findReportAbuseOption().exists()).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js b/spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js
index 9b6f5ae3e38..a27877e7ba8 100644
--- a/spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js
+++ b/spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js
@@ -94,16 +94,15 @@ describe('AlertManagementEmptyState', () => {
const ItemsTable = () => wrapper.find('.gl-table');
const ErrorAlert = () => wrapper.findComponent(GlAlert);
const Pagination = () => wrapper.findComponent(GlPagination);
- const Tabs = () => wrapper.findComponent(GlTabs);
const ActionButton = () => wrapper.find('.header-actions > button');
- const Filters = () => wrapper.findComponent(FilteredSearchBar);
+ const findFilteredSearchBar = () => wrapper.findComponent(FilteredSearchBar);
const findPagination = () => wrapper.findComponent(GlPagination);
const findStatusFilterTabs = () => wrapper.findAllComponents(GlTab);
const findStatusTabs = () => wrapper.findComponent(GlTabs);
const findStatusFilterBadge = () => wrapper.findAllComponents(GlBadge);
const handleFilterItems = (filters) => {
- Filters().vm.$emit('onFilter', filters);
+ findFilteredSearchBar().vm.$emit('onFilter', filters);
return nextTick();
};
@@ -140,7 +139,7 @@ describe('AlertManagementEmptyState', () => {
},
});
- expect(Tabs().exists()).toBe(true);
+ expect(findStatusTabs().exists()).toBe(true);
});
it('renders the header action buttons if present', () => {
@@ -176,7 +175,7 @@ describe('AlertManagementEmptyState', () => {
props: { filterSearchTokens: [TOKEN_TYPE_ASSIGNEE] },
});
- expect(Filters().exists()).toBe(true);
+ expect(findFilteredSearchBar().exists()).toBe(true);
});
});
@@ -291,8 +290,9 @@ describe('AlertManagementEmptyState', () => {
});
it('renders the search component for incidents', () => {
- expect(Filters().props('searchInputPlaceholder')).toBe('Search or filter results…');
- expect(Filters().props('tokens')).toEqual([
+ const filteredSearchBar = findFilteredSearchBar();
+ expect(filteredSearchBar.props('searchInputPlaceholder')).toBe('Search or filter results…');
+ expect(filteredSearchBar.props('tokens')).toEqual([
{
type: TOKEN_TYPE_AUTHOR,
icon: 'user',
@@ -316,14 +316,14 @@ describe('AlertManagementEmptyState', () => {
fetchUsers: expect.any(Function),
},
]);
- expect(Filters().props('recentSearchesStorageKey')).toBe('items');
+ expect(filteredSearchBar.props('recentSearchesStorageKey')).toBe('items');
});
it('returns correctly applied filter search values', async () => {
const searchTerm = 'foo';
await handleFilterItems([{ type: 'filtered-search-term', value: { data: searchTerm } }]);
await nextTick();
- expect(Filters().props('initialFilterValue')).toEqual([searchTerm]);
+ expect(findFilteredSearchBar().props('initialFilterValue')).toEqual([searchTerm]);
});
it('updates props tied to getIncidents GraphQL query', async () => {
@@ -337,7 +337,7 @@ describe('AlertManagementEmptyState', () => {
value: { data: assigneeUsername },
},
searchTerm,
- ] = Filters().props('initialFilterValue');
+ ] = findFilteredSearchBar().props('initialFilterValue');
expect(authorUsername).toBe('root');
expect(assigneeUsername).toEqual('root2');
@@ -346,7 +346,7 @@ describe('AlertManagementEmptyState', () => {
it('updates props `searchTerm` and `authorUsername` with empty values when passed filters param is empty', async () => {
await handleFilterItems([]);
- expect(Filters().props('initialFilterValue')).toEqual([]);
+ expect(findFilteredSearchBar().props('initialFilterValue')).toEqual([]);
});
});
});
diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_personal_snippets_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_personal_snippets_metric_spec.rb
new file mode 100644
index 00000000000..cfd2fcabae6
--- /dev/null
+++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_personal_snippets_metric_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountPersonalSnippetsMetric, feature_category: :service_ping do
+ before_all do
+ create(:personal_snippet, created_at: 5.days.ago)
+ create(:personal_snippet, created_at: 1.year.ago)
+ end
+
+ context 'with a time_frame of 28 days' do
+ let(:expected_value) { 1 }
+
+ it_behaves_like 'a correct instrumented metric value', { time_frame: '28d', data_source: 'database' }
+ end
+
+ context 'with a timeframe of all' do
+ let(:expected_value) { 2 }
+
+ it_behaves_like 'a correct instrumented metric value', { time_frame: 'all', data_source: 'database' }
+ end
+end
diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_project_snippets_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_project_snippets_metric_spec.rb
new file mode 100644
index 00000000000..a82726ccf44
--- /dev/null
+++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_project_snippets_metric_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountProjectSnippetsMetric, feature_category: :service_ping do
+ before_all do
+ create(:project_snippet, created_at: 5.days.ago)
+ create(:project_snippet, created_at: 1.year.ago)
+ end
+
+ context 'with a time_frame of 28 days' do
+ let(:expected_value) { 1 }
+
+ it_behaves_like 'a correct instrumented metric value', { time_frame: '28d', data_source: 'database' }
+ end
+
+ context 'with a timeframe of all' do
+ let(:expected_value) { 2 }
+
+ it_behaves_like 'a correct instrumented metric value', { time_frame: 'all', data_source: 'database' }
+ end
+end
diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_snippets_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_snippets_metric_spec.rb
new file mode 100644
index 00000000000..daacea83833
--- /dev/null
+++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_snippets_metric_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountSnippetsMetric, feature_category: :service_ping do
+ before_all do
+ create(:personal_snippet, created_at: 5.days.ago)
+ create(:personal_snippet, created_at: 1.year.ago)
+
+ create(:project_snippet, created_at: 1.year.ago)
+ create(:project_snippet, created_at: 5.days.ago)
+ end
+
+ context 'with a time_frame of 28 days' do
+ let(:expected_value) { 2 }
+
+ it_behaves_like 'a correct instrumented metric value', { time_frame: '28d', data_source: 'database' }
+ end
+
+ context 'with a timeframe of all' do
+ let(:expected_value) { 4 }
+
+ it_behaves_like 'a correct instrumented metric value', { time_frame: 'all', data_source: 'database' }
+ end
+end
diff --git a/spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb b/spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb
index 271e9595703..5002ee7599f 100644
--- a/spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb
+++ b/spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb
@@ -68,6 +68,10 @@ RSpec.describe Gitlab::Usage::Metrics::NamesSuggestions::Generator, feature_cate
end
context 'for add metrics' do
+ before do
+ pending 'https://gitlab.com/gitlab-org/gitlab/-/issues/414887'
+ end
+
it_behaves_like 'name suggestion' do
# corresponding metric is collected with add(data[:personal_snippets], data[:project_snippets])
let(:key_path) { 'counts.snippets' }
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 72147721b4e..ae3635fb5b1 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -574,9 +574,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures, feature_category: :servic
expect(count_data[:successful_deployments]).to eq(2)
expect(count_data[:failed_deployments]).to eq(2)
expect(count_data[:feature_flags]).to eq(1)
- expect(count_data[:snippets]).to eq(6)
- expect(count_data[:personal_snippets]).to eq(2)
- expect(count_data[:project_snippets]).to eq(4)
expect(count_data[:projects_creating_incidents]).to eq(2)
expect(count_data[:projects_with_packages]).to eq(2)
@@ -636,8 +633,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures, feature_category: :servic
deployment_options = { created_at: n.days.ago, project: env.project, environment: env }
create(:deployment, :failed, deployment_options)
create(:deployment, :success, deployment_options)
- create(:project_snippet, project: project, created_at: n.days.ago)
- create(:personal_snippet, created_at: n.days.ago)
create(:alert_management_alert, project: project, created_at: n.days.ago)
end
@@ -654,9 +649,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures, feature_category: :servic
expect(counts_monthly[:deployments]).to eq(2)
expect(counts_monthly[:successful_deployments]).to eq(1)
expect(counts_monthly[:failed_deployments]).to eq(1)
- expect(counts_monthly[:snippets]).to eq(2)
- expect(counts_monthly[:personal_snippets]).to eq(1)
- expect(counts_monthly[:project_snippets]).to eq(1)
expect(counts_monthly[:projects_with_alerts_created]).to eq(1)
expect(counts_monthly[:projects]).to eq(1)
expect(counts_monthly[:packages]).to eq(1)
diff --git a/spec/support/helpers/usage_data_helpers.rb b/spec/support/helpers/usage_data_helpers.rb
index a1c25338312..050a2780af4 100644
--- a/spec/support/helpers/usage_data_helpers.rb
+++ b/spec/support/helpers/usage_data_helpers.rb
@@ -70,9 +70,6 @@ module UsageDataHelpers
protected_branches_except_default
releases
remote_mirrors
- snippets
- personal_snippets
- project_snippets
suggestions
terraform_reports
terraform_states
diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml
index 96cdf5adec8..354d175d825 100644
--- a/spec/support/rspec_order_todo.yml
+++ b/spec/support/rspec_order_todo.yml
@@ -9923,7 +9923,6 @@
- './spec/views/projects/merge_requests/_commits.html.haml_spec.rb'
- './spec/views/projects/merge_requests/creations/_new_submit.html.haml_spec.rb'
- './spec/views/projects/merge_requests/edit.html.haml_spec.rb'
-- './spec/views/projects/merge_requests/show.html.haml_spec.rb'
- './spec/views/projects/milestones/index.html.haml_spec.rb'
- './spec/views/projects/notes/_more_actions_dropdown.html.haml_spec.rb'
- './spec/views/projects/pages_domains/show.html.haml_spec.rb'
diff --git a/spec/support/shared_contexts/issuable/merge_request_shared_context.rb b/spec/support/shared_contexts/issuable/merge_request_shared_context.rb
deleted file mode 100644
index 35c1511c96a..00000000000
--- a/spec/support/shared_contexts/issuable/merge_request_shared_context.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.shared_context 'merge request show action' do
- include Features::MergeRequestHelpers
-
- let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project, :public, :repository) }
- let_it_be(:merge_request) { create(:merge_request, :opened, source_project: project, author: user) }
- let_it_be(:note) { create(:note_on_merge_request, project: project, noteable: merge_request) }
-
- before do
- allow(view).to receive(:experiment_enabled?).and_return(false)
- allow(view).to receive(:current_user).and_return(user)
- allow(view).to receive(:can_admin_project_member?)
- assign(:project, project)
- assign(:merge_request, merge_request)
- assign(:note, note)
- assign(:noteable, merge_request)
- assign(:number_of_pipelines, 0)
- assign(:issuable_sidebar, serialize_issuable_sidebar(user, project, merge_request))
-
- preload_view_requirements(merge_request, note)
- end
-end
diff --git a/spec/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml_spec.rb b/spec/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml_spec.rb
deleted file mode 100644
index 99339e956cc..00000000000
--- a/spec/views/projects/merge_requests/_close_reopen_draft_report_toggle.html.haml_spec.rb
+++ /dev/null
@@ -1,34 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'projects/merge_requests/_close_reopen_draft_report_toggle.html.haml' do
- let_it_be(:merge_request) { create(:merge_request, state: :merged) }
-
- before do
- assign(:merge_request, merge_request)
- assign(:project, merge_request.target_project)
-
- allow(view).to receive(:moved_mr_sidebar_enabled?).and_return(true)
- end
-
- describe 'notifcations toggle' do
- context 'when mr merged and logged in' do
- it 'is present' do
- allow(view).to receive(:current_user).and_return(merge_request.author)
-
- render
-
- expect(rendered).to have_css('li', class: 'js-sidebar-subscriptions-widget-root')
- end
- end
-
- context 'when mr merged and not logged in' do
- it 'is not present' do
- render
-
- expect(rendered).not_to have_css('li', class: 'js-sidebar-subscriptions-widget-root')
- end
- end
- end
-end
diff --git a/spec/views/projects/merge_requests/show.html.haml_spec.rb b/spec/views/projects/merge_requests/show.html.haml_spec.rb
deleted file mode 100644
index 86a4b25f746..00000000000
--- a/spec/views/projects/merge_requests/show.html.haml_spec.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'projects/merge_requests/show.html.haml', :aggregate_failures do
- using RSpec::Parameterized::TableSyntax
-
- include_context 'merge request show action'
-
- before do
- merge_request.reload
- end
-
- context 'when the merge request is open' do
- it 'shows the "Mark as draft" button' do
- render
-
- expect(rendered).to have_css('a', visible: true, text: 'Mark as draft')
- expect(rendered).to have_css('a', visible: true, text: 'Close')
- end
- end
-
- context 'when the merge request is closed' do
- before do
- merge_request.close!
- end
-
- it 'shows the "Reopen" button' do
- render
-
- expect(rendered).not_to have_css('a', visible: true, text: 'Mark as draft')
- expect(rendered).to have_css('a', visible: true, text: 'Reopen')
- end
-
- context 'when source project does not exist' do
- it 'does not show the "Reopen" button' do
- allow(merge_request).to receive(:source_project).and_return(nil)
-
- render
-
- expect(rendered).not_to have_css('a', visible: false, text: 'Reopen')
- end
- end
- end
-end