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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-09-20 15:11:43 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-09-20 15:11:43 +0300
commitf80dee91829a985dbf7d07b606179e06e87166a6 (patch)
tree144131834302ded35f593ab4f9ba25f82b04c2e8
parent6c4f8ad2d99cf2716e62bd5a0c2ecea9e15505b2 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.gitlab/ci/rules.gitlab-ci.yml2
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js50
-rw-r--r--app/assets/javascripts/super_sidebar/components/help_center.vue2
-rw-r--r--app/services/ci/retry_pipeline_service.rb8
-rw-r--r--app/views/layouts/nav/_ask_duo_button.html.haml2
-rw-r--r--db/post_migrate/20230907020936_sync_index_for_ci_pipelines_pipeline_id_bigint.rb17
-rw-r--r--db/post_migrate/20230908065605_validate_foreign_key_for_ci_pipeline_messages_pipeline_id_bigint.rb15
-rw-r--r--db/schema_migrations/202309070209361
-rw-r--r--db/schema_migrations/202309080656051
-rw-r--r--db/structure.sql4
-rw-r--r--doc/api/api_resources.md2
-rw-r--r--doc/api/award_emoji.md380
-rw-r--r--doc/api/emoji_reactions.md377
-rw-r--r--doc/api/graphql/custom_emoji.md2
-rw-r--r--doc/api/merge_request_approvals.md14
-rw-r--r--doc/api/projects.md6
-rw-r--r--doc/architecture/blueprints/cells/index.md4
-rw-r--r--doc/architecture/blueprints/gitlab_ml_experiments/index.md2
-rw-r--r--doc/operations/incident_management/status_page.md2
-rw-r--r--doc/update/versions/gitlab_16_changes.md2
-rw-r--r--doc/user/award_emojis.md71
-rw-r--r--doc/user/emoji_reactions.md68
-rw-r--r--doc/user/group/epics/index.md2
-rw-r--r--doc/user/markdown.md2
-rw-r--r--doc/user/project/integrations/webhook_events.md8
-rw-r--r--doc/user/project/issues/sorting_issue_lists.md2
-rw-r--r--doc/user/project/merge_requests/reviews/data_usage.md2
-rw-r--r--doc/user/project/merge_requests/reviews/index.md8
-rw-r--r--locale/gitlab.pot29
-rw-r--r--spec/controllers/admin/groups_controller_spec.rb90
-rw-r--r--spec/frontend/gfm_auto_complete_spec.js38
-rw-r--r--spec/frontend/super_sidebar/components/help_center_spec.js6
-rw-r--r--spec/frontend/vue_merge_request_widget/mr_widget_options_spec.js75
-rw-r--r--spec/helpers/sorting_helper_spec.rb17
-rw-r--r--spec/models/group_spec.rb141
-rw-r--r--spec/views/shared/groups/_dropdown.html.haml_spec.rb28
-rw-r--r--workhorse/internal/dependencyproxy/dependencyproxy_test.go14
37 files changed, 926 insertions, 568 deletions
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml
index d8cc67a966a..20902d3641b 100644
--- a/.gitlab/ci/rules.gitlab-ci.yml
+++ b/.gitlab/ci/rules.gitlab-ci.yml
@@ -477,7 +477,7 @@
- "Rakefile"
- "tests.yml"
- "config.ru"
- - "{,ee/,jh/}{app,bin,config,db,generator_templates,haml_lint,lib,locale,public,scripts,symbol,vendor}/**/*"
+ - "{,ee/,jh/}{app,bin,config,db,generator_templates,haml_lint,lib,locale,public,scripts,storybook,symbol,vendor}/**/*"
- "doc/api/graphql/reference/*" # Files in this folder are auto-generated
# CI changes
- ".gitlab-ci.yml"
diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js
index 264427f5806..99d22b1330b 100644
--- a/app/assets/javascripts/gfm_auto_complete.js
+++ b/app/assets/javascripts/gfm_auto_complete.js
@@ -129,7 +129,7 @@ class GfmAutoComplete {
this.dataSources = dataSources;
this.cachedData = {};
this.isLoadingData = {};
- this.previousQuery = '';
+ this.previousQuery = undefined;
}
setup(input, enableMap = defaultAutocompleteConfig) {
@@ -776,15 +776,19 @@ class GfmAutoComplete {
return $.fn.atwho.default.callbacks.sorter(query, items, searchKey);
},
filter(query, data, searchKey) {
+ if (GfmAutoComplete.isTypeWithBackendFiltering(this.at)) {
+ if (GfmAutoComplete.isLoading(data) || self.previousQuery !== query) {
+ self.previousQuery = query;
+ self.fetchData(this.$inputor, this.at, query);
+ return data;
+ }
+ }
+
if (GfmAutoComplete.isLoading(data)) {
self.fetchData(this.$inputor, this.at);
return data;
}
- if (GfmAutoComplete.isTypeWithBackendFiltering(this.at) && self.previousQuery !== query) {
- self.fetchData(this.$inputor, this.at, query);
- self.previousQuery = query;
- return data;
- }
+
return $.fn.atwho.default.callbacks.filter(query, data, searchKey);
},
beforeInsert(value) {
@@ -828,14 +832,18 @@ class GfmAutoComplete {
const dataSource = this.dataSources[GfmAutoComplete.atTypeMap[at]];
if (GfmAutoComplete.isTypeWithBackendFiltering(at)) {
- axios
- .get(dataSource, { params: { search } })
- .then(({ data }) => {
- this.loadData($input, at, data);
- })
- .catch(() => {
- this.isLoadingData[at] = false;
- });
+ if (this.cachedData[at]?.[search]) {
+ this.loadData($input, at, this.cachedData[at][search], { search });
+ } else {
+ axios
+ .get(dataSource, { params: { search } })
+ .then(({ data }) => {
+ this.loadData($input, at, data, { search });
+ })
+ .catch(() => {
+ this.isLoadingData[at] = false;
+ });
+ }
} else if (this.cachedData[at]) {
this.loadData($input, at, this.cachedData[at]);
} else if (GfmAutoComplete.atTypeMap[at] === 'emojis') {
@@ -853,9 +861,19 @@ class GfmAutoComplete {
}
}
- loadData($input, at, data) {
+ loadData($input, at, data, { search } = {}) {
this.isLoadingData[at] = false;
- this.cachedData[at] = data;
+
+ if (search !== undefined) {
+ if (this.cachedData[at] === undefined) {
+ this.cachedData[at] = {};
+ }
+
+ this.cachedData[at][search] = data;
+ } else {
+ this.cachedData[at] = data;
+ }
+
$input.atwho('load', at, data);
// This trigger at.js again
// otherwise we would be stuck with loading until the user types
diff --git a/app/assets/javascripts/super_sidebar/components/help_center.vue b/app/assets/javascripts/super_sidebar/components/help_center.vue
index 8ce82116194..069987d4006 100644
--- a/app/assets/javascripts/super_sidebar/components/help_center.vue
+++ b/app/assets/javascripts/super_sidebar/components/help_center.vue
@@ -38,7 +38,7 @@ export default {
shortcuts: __('Keyboard shortcuts'),
version: __('Your GitLab version'),
whatsnew: __("What's new"),
- chat: s__('TanukiBot|Ask GitLab Duo'),
+ chat: s__('TanukiBot|GitLab Duo Chat'),
},
props: {
sidebarData: {
diff --git a/app/services/ci/retry_pipeline_service.rb b/app/services/ci/retry_pipeline_service.rb
index 85f910d05d7..f6b2c90c6ec 100644
--- a/app/services/ci/retry_pipeline_service.rb
+++ b/app/services/ci/retry_pipeline_service.rb
@@ -26,9 +26,7 @@ module Ci
.new(project: project, current_user: current_user)
.close_all(pipeline)
- Ci::ProcessPipelineService
- .new(pipeline)
- .execute
+ start_pipeline(pipeline)
ServiceResponse.success
rescue Gitlab::Access::AccessDeniedError => e
@@ -52,6 +50,10 @@ module Ci
def can_be_retried?(build)
can?(current_user, :update_build, build)
end
+
+ def start_pipeline(pipeline)
+ Ci::PipelineCreation::StartPipelineService.new(pipeline).execute
+ end
end
end
diff --git a/app/views/layouts/nav/_ask_duo_button.html.haml b/app/views/layouts/nav/_ask_duo_button.html.haml
index f17ccfc8afe..e37ce50352c 100644
--- a/app/views/layouts/nav/_ask_duo_button.html.haml
+++ b/app/views/layouts/nav/_ask_duo_button.html.haml
@@ -1,5 +1,5 @@
- if Gitlab.ee? && ::Gitlab::Llm::TanukiBot.show_breadcrumbs_entry_point_for?(user: current_user)
- - label = s_('TanukiBot|Ask GitLab Duo')
+ - label = s_('TanukiBot|GitLab Duo Chat')
= render Pajamas::ButtonComponent.new(variant: :confirm,
category: :secondary,
icon: 'tanuki-ai',
diff --git a/db/post_migrate/20230907020936_sync_index_for_ci_pipelines_pipeline_id_bigint.rb b/db/post_migrate/20230907020936_sync_index_for_ci_pipelines_pipeline_id_bigint.rb
new file mode 100644
index 00000000000..8263318a775
--- /dev/null
+++ b/db/post_migrate/20230907020936_sync_index_for_ci_pipelines_pipeline_id_bigint.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class SyncIndexForCiPipelinesPipelineIdBigint < Gitlab::Database::Migration[2.1]
+ disable_ddl_transaction!
+
+ TABLE_NAME = :ci_pipelines
+ INDEX_NAME = 'index_ci_pipelines_on_auto_canceled_by_id_bigint'
+ COLUMN_NAME = :auto_canceled_by_id_convert_to_bigint
+
+ def up
+ add_concurrent_index TABLE_NAME, COLUMN_NAME, name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name TABLE_NAME, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20230908065605_validate_foreign_key_for_ci_pipeline_messages_pipeline_id_bigint.rb b/db/post_migrate/20230908065605_validate_foreign_key_for_ci_pipeline_messages_pipeline_id_bigint.rb
new file mode 100644
index 00000000000..b1951942fed
--- /dev/null
+++ b/db/post_migrate/20230908065605_validate_foreign_key_for_ci_pipeline_messages_pipeline_id_bigint.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class ValidateForeignKeyForCiPipelineMessagesPipelineIdBigint < Gitlab::Database::Migration[2.1]
+ TABLE_NAME = :ci_pipeline_messages
+ COLUMN_NAME = :pipeline_id_convert_to_bigint
+ FK_NAME = :fk_0946fea681
+
+ def up
+ validate_foreign_key TABLE_NAME, COLUMN_NAME, name: FK_NAME
+ end
+
+ def down
+ # Can be safely a no-op if we don't roll back the inconsistent data.
+ end
+end
diff --git a/db/schema_migrations/20230907020936 b/db/schema_migrations/20230907020936
new file mode 100644
index 00000000000..cdfb809472c
--- /dev/null
+++ b/db/schema_migrations/20230907020936
@@ -0,0 +1 @@
+4b0b98c85f2845a2c989141ae21ac0dd48b5a5f4a8c1044e8c8e9a942bf35535 \ No newline at end of file
diff --git a/db/schema_migrations/20230908065605 b/db/schema_migrations/20230908065605
new file mode 100644
index 00000000000..4b4cffc58d1
--- /dev/null
+++ b/db/schema_migrations/20230908065605
@@ -0,0 +1 @@
+72fec3e0a682cfeda05e54019dd7d720e18d1bb00a4d390bd64ff582c1313d32 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 9283a0c4800..0245fe85add 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -31384,6 +31384,8 @@ CREATE INDEX index_ci_pipelines_for_ondemand_dast_scans ON ci_pipelines USING bt
CREATE INDEX index_ci_pipelines_on_auto_canceled_by_id ON ci_pipelines USING btree (auto_canceled_by_id);
+CREATE INDEX index_ci_pipelines_on_auto_canceled_by_id_bigint ON ci_pipelines USING btree (auto_canceled_by_id_convert_to_bigint);
+
CREATE INDEX index_ci_pipelines_on_ci_ref_id_and_more ON ci_pipelines USING btree (ci_ref_id, id DESC, source, status) WHERE (ci_ref_id IS NOT NULL);
CREATE INDEX index_ci_pipelines_on_external_pull_request_id ON ci_pipelines USING btree (external_pull_request_id) WHERE (external_pull_request_id IS NOT NULL);
@@ -36343,7 +36345,7 @@ ALTER TABLE ONLY merge_request_assignment_events
ADD CONSTRAINT fk_08f7602bfd FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
ALTER TABLE ONLY ci_pipeline_messages
- ADD CONSTRAINT fk_0946fea681 FOREIGN KEY (pipeline_id_convert_to_bigint) REFERENCES ci_pipelines(id) ON DELETE CASCADE NOT VALID;
+ ADD CONSTRAINT fk_0946fea681 FOREIGN KEY (pipeline_id_convert_to_bigint) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
ALTER TABLE ONLY remote_development_agent_configs
ADD CONSTRAINT fk_0a3c0ada56 FOREIGN KEY (cluster_agent_id) REFERENCES cluster_agents(id) ON DELETE CASCADE;
diff --git a/doc/api/api_resources.md b/doc/api/api_resources.md
index 9f2a57dd84f..3c3430dead4 100644
--- a/doc/api/api_resources.md
+++ b/doc/api/api_resources.md
@@ -40,7 +40,7 @@ The following API resources are available in the project context:
| [Deployments](deployments.md) | `/projects/:id/deployments` |
| [Discussions](discussions.md) (threaded comments) | `/projects/:id/issues/.../discussions`, `/projects/:id/snippets/.../discussions`, `/projects/:id/merge_requests/.../discussions`, `/projects/:id/commits/.../discussions` (also available for groups) |
| [Draft Notes](draft_notes.md) (comments) | `/projects/:id/merge_requests/.../draft_notes`
-| [Emoji reactions](award_emoji.md) | `/projects/:id/issues/.../award_emoji`, `/projects/:id/merge_requests/.../award_emoji`, `/projects/:id/snippets/.../award_emoji` |
+| [Emoji reactions](emoji_reactions.md) | `/projects/:id/issues/.../award_emoji`, `/projects/:id/merge_requests/.../award_emoji`, `/projects/:id/snippets/.../award_emoji` |
| [Environments](environments.md) | `/projects/:id/environments` |
| [Error Tracking](error_tracking.md) | `/projects/:id/error_tracking/settings` |
| [Events](events.md) | `/projects/:id/events` (also available for users and standalone) |
diff --git a/doc/api/award_emoji.md b/doc/api/award_emoji.md
index 1ccc59601a0..09f7b4c77fa 100644
--- a/doc/api/award_emoji.md
+++ b/doc/api/award_emoji.md
@@ -1,377 +1,11 @@
---
-stage: Plan
-group: Project Management
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
+redirect_to: 'emoji_reactions.md'
+remove_date: '2023-12-20'
---
-# Emoji reactions API **(FREE ALL)**
+This document was moved to [another location](emoji_reactions.md).
-> [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/409884) from "award emoji" to "emoji reactions" in GitLab 16.0.
-
-An [emoji reaction](../user/award_emojis.md) tells a thousand words.
-
-We call GitLab objects on which you can react with an emoji "awardables".
-You can react with emoji on the following:
-
-- [Epics](../user/group/epics/index.md) ([API](epics.md)). **(PREMIUM ALL)**
-- [Issues](../user/project/issues/index.md) ([API](issues.md)).
-- [Merge requests](../user/project/merge_requests/index.md) ([API](merge_requests.md)).
-- [Snippets](../user/snippets.md) ([API](snippets.md)).
-- [Comments](../user/award_emojis.md#emoji-reactions-for-comments) ([API](notes.md)).
-
-## Issues, merge requests, and snippets
-
-For information on using these endpoints with comments, see [Add reactions to comments](#add-reactions-to-comments).
-
-### List an awardable's emoji reactions
-
-> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/335068) in GitLab 15.1 to allow unauthenticated access to public awardables.
-
-Get a list of all emoji reactions for a specified awardable. This endpoint can
-be accessed without authentication if the awardable is publicly accessible.
-
-```plaintext
-GET /projects/:id/issues/:issue_iid/award_emoji
-GET /projects/:id/merge_requests/:merge_request_iid/award_emoji
-GET /projects/:id/snippets/:snippet_id/award_emoji
-```
-
-Parameters:
-
-| Attribute | Type | Required | Description |
-|:---------------|:---------------|:---------|:-----------------------------------------------------------------------------|
-| `id` | integer/string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
-| `issue_iid`/`merge_request_iid`/`snippet_id` | integer | yes | ID (`iid` for merge requests/issues, `id` for snippets) of an awardable. |
-
-Example request:
-
-```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji"
-```
-
-Example response:
-
-```json
-[
- {
- "id": 4,
- "name": "1234",
- "user": {
- "name": "Administrator",
- "username": "root",
- "id": 1,
- "state": "active",
- "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- "web_url": "http://gitlab.example.com/root"
- },
- "created_at": "2016-06-15T10:09:34.206Z",
- "updated_at": "2016-06-15T10:09:34.206Z",
- "awardable_id": 80,
- "awardable_type": "Issue"
- },
- {
- "id": 1,
- "name": "microphone",
- "user": {
- "name": "User 4",
- "username": "user4",
- "id": 26,
- "state": "active",
- "avatar_url": "http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon",
- "web_url": "http://gitlab.example.com/user4"
- },
- "created_at": "2016-06-15T10:09:34.177Z",
- "updated_at": "2016-06-15T10:09:34.177Z",
- "awardable_id": 80,
- "awardable_type": "Issue"
- }
-]
-```
-
-### Get single emoji reaction
-
-> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/335068) in GitLab 15.1 to allow unauthenticated access to public awardables.
-
-Get a single emoji reaction from an issue, snippet, or merge request. This endpoint can
-be accessed without authentication if the awardable is publicly accessible.
-
-```plaintext
-GET /projects/:id/issues/:issue_iid/award_emoji/:award_id
-GET /projects/:id/merge_requests/:merge_request_iid/award_emoji/:award_id
-GET /projects/:id/snippets/:snippet_id/award_emoji/:award_id
-```
-
-Parameters:
-
-| Attribute | Type | Required | Description |
-|:---------------|:---------------|:---------|:-----------------------------------------------------------------------------|
-| `id` | integer/string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
-| `issue_iid`/`merge_request_iid`/`snippet_id` | integer | yes | ID (`iid` for merge requests/issues, `id` for snippets) of an awardable. |
-| `award_id` | integer | yes | ID of the emoji reaction. |
-
-Example request:
-
-```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji/1"
-```
-
-Example response:
-
-```json
-{
- "id": 1,
- "name": "microphone",
- "user": {
- "name": "User 4",
- "username": "user4",
- "id": 26,
- "state": "active",
- "avatar_url": "http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon",
- "web_url": "http://gitlab.example.com/user4"
- },
- "created_at": "2016-06-15T10:09:34.177Z",
- "updated_at": "2016-06-15T10:09:34.177Z",
- "awardable_id": 80,
- "awardable_type": "Issue"
-}
-```
-
-### Add a new emoji reaction
-
-Add an emoji reaction on the specified awardable.
-
-```plaintext
-POST /projects/:id/issues/:issue_iid/award_emoji
-POST /projects/:id/merge_requests/:merge_request_iid/award_emoji
-POST /projects/:id/snippets/:snippet_id/award_emoji
-```
-
-Parameters:
-
-| Attribute | Type | Required | Description |
-|:---------------|:---------------|:---------|:-----------------------------------------------------------------------------|
-| `id` | integer/string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
-| `issue_iid`/`merge_request_iid`/`snippet_id` | integer | yes | ID (`iid` for merge requests/issues, `id` for snippets) of an awardable. |
-| `name` | string | yes | Name of the emoji without colons. |
-
-```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji?name=blowfish"
-```
-
-Example Response:
-
-```json
-{
- "id": 344,
- "name": "blowfish",
- "user": {
- "name": "Administrator",
- "username": "root",
- "id": 1,
- "state": "active",
- "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- "web_url": "http://gitlab.example.com/root"
- },
- "created_at": "2016-06-17T17:47:29.266Z",
- "updated_at": "2016-06-17T17:47:29.266Z",
- "awardable_id": 80,
- "awardable_type": "Issue"
-}
-```
-
-### Delete an emoji reaction
-
-Sometimes it's just not meant to be and you need to remove your reaction.
-
-Only an administrator or the author of the reaction can delete an emoji reaction.
-
-```plaintext
-DELETE /projects/:id/issues/:issue_iid/award_emoji/:award_id
-DELETE /projects/:id/merge_requests/:merge_request_iid/award_emoji/:award_id
-DELETE /projects/:id/snippets/:snippet_id/award_emoji/:award_id
-```
-
-Parameters:
-
-| Attribute | Type | Required | Description |
-|:---------------|:---------------|:---------|:-----------------------------------------------------------------------------|
-| `id` | integer/string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
-| `issue_iid`/`merge_request_iid`/`snippet_id` | integer | yes | ID (`iid` for merge requests/issues, `id` for snippets) of an awardable. |
-| `award_id` | integer | yes | ID of an emoji reaction. |
-
-```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji/344"
-```
-
-## Add reactions to comments
-
-Comments (also known as notes) are a sub-resource of issues, merge requests, and snippets.
-
-NOTE:
-The examples below describe working with emoji reactions on an issue's comments, but can be
-adapted to comments on merge requests and snippets. Therefore, you have to replace
-`issue_iid` either with `merge_request_iid` or with the `snippet_id`.
-
-### List a comment's emoji reactions
-
-> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/335068) in GitLab 15.1 to allow unauthenticated access to public comments.
-
-Get all emoji reactions for a comment (note). This endpoint can
-be accessed without authentication if the comment is publicly accessible.
-
-```plaintext
-GET /projects/:id/issues/:issue_iid/notes/:note_id/award_emoji
-```
-
-Parameters:
-
-| Attribute | Type | Required | Description |
-|:------------|:---------------|:---------|:-----------------------------------------------------------------------------|
-| `id` | integer/string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
-| `issue_iid` | integer | yes | Internal ID of an issue. |
-| `note_id` | integer | yes | ID of a comment (note). |
-
-Example request:
-
-```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/notes/1/award_emoji"
-```
-
-Example response:
-
-```json
-[
- {
- "id": 2,
- "name": "mood_bubble_lightning",
- "user": {
- "name": "User 4",
- "username": "user4",
- "id": 26,
- "state": "active",
- "avatar_url": "http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon",
- "web_url": "http://gitlab.example.com/user4"
- },
- "created_at": "2016-06-15T10:09:34.197Z",
- "updated_at": "2016-06-15T10:09:34.197Z",
- "awardable_id": 1,
- "awardable_type": "Note"
- }
-]
-```
-
-### Get an emoji reaction for a comment
-
-> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/335068) in GitLab 15.1 to allow unauthenticated access to public comments.
-
-Get a single emoji reaction for a comment (note). This endpoint can
-be accessed without authentication if the comment is publicly accessible.
-
-```plaintext
-GET /projects/:id/issues/:issue_iid/notes/:note_id/award_emoji/:award_id
-```
-
-Parameters:
-
-| Attribute | Type | Required | Description |
-|:------------|:---------------|:---------|:-----------------------------------------------------------------------------|
-| `id` | integer/string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
-| `issue_iid` | integer | yes | Internal ID of an issue. |
-| `note_id` | integer | yes | ID of a comment (note). |
-| `award_id` | integer | yes | ID of the emoji reaction. |
-
-Example request:
-
-```shell
-curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/notes/1/award_emoji/2"
-```
-
-Example response:
-
-```json
-{
- "id": 2,
- "name": "mood_bubble_lightning",
- "user": {
- "name": "User 4",
- "username": "user4",
- "id": 26,
- "state": "active",
- "avatar_url": "http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon",
- "web_url": "http://gitlab.example.com/user4"
- },
- "created_at": "2016-06-15T10:09:34.197Z",
- "updated_at": "2016-06-15T10:09:34.197Z",
- "awardable_id": 1,
- "awardable_type": "Note"
-}
-```
-
-### Award a new emoji on a comment
-
-Create an emoji reaction on the specified comment (note).
-
-```plaintext
-POST /projects/:id/issues/:issue_iid/notes/:note_id/award_emoji
-```
-
-Parameters:
-
-| Attribute | Type | Required | Description |
-|:------------|:---------------|:---------|:-----------------------------------------------------------------------------|
-| `id` | integer/string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
-| `issue_iid` | integer | yes | Internal ID of an issue. |
-| `note_id` | integer | yes | ID of a comment (note). |
-| `name` | string | yes | Name of the emoji without colons. |
-
-Example request:
-
-```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/notes/1/award_emoji?name=rocket"
-```
-
-Example response:
-
-```json
-{
- "id": 345,
- "name": "rocket",
- "user": {
- "name": "Administrator",
- "username": "root",
- "id": 1,
- "state": "active",
- "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
- "web_url": "http://gitlab.example.com/root"
- },
- "created_at": "2016-06-17T19:59:55.888Z",
- "updated_at": "2016-06-17T19:59:55.888Z",
- "awardable_id": 1,
- "awardable_type": "Note"
-}
-```
-
-### Delete an emoji reaction from a comment
-
-Sometimes it's just not meant to be and you need to remove the reaction.
-
-Only an administrator or the author of the reaction can delete an emoji reaction.
-
-```plaintext
-DELETE /projects/:id/issues/:issue_iid/notes/:note_id/award_emoji/:award_id
-```
-
-Parameters:
-
-| Attribute | Type | Required | Description |
-|:------------|:---------------|:---------|:-----------------------------------------------------------------------------|
-| `id` | integer/string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
-| `issue_iid` | integer | yes | Internal ID of an issue. |
-| `note_id` | integer | yes | ID of a comment (note). |
-| `award_id` | integer | yes | ID of an emoji reaction. |
-
-Example request:
-
-```shell
-curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji/345"
-```
+<!-- This redirect file can be deleted after <2023-12-20>. -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/api/emoji_reactions.md b/doc/api/emoji_reactions.md
new file mode 100644
index 00000000000..f9e44a1337a
--- /dev/null
+++ b/doc/api/emoji_reactions.md
@@ -0,0 +1,377 @@
+---
+stage: Plan
+group: Project Management
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
+---
+
+# Emoji reactions API **(FREE ALL)**
+
+> [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/409884) from "award emoji" to "emoji reactions" in GitLab 16.0.
+
+An [emoji reaction](../user/emoji_reactions.md) tells a thousand words.
+
+We call GitLab objects on which you can react with an emoji "awardables".
+You can react with emoji on the following:
+
+- [Epics](../user/group/epics/index.md) ([API](epics.md)). **(PREMIUM ALL)**
+- [Issues](../user/project/issues/index.md) ([API](issues.md)).
+- [Merge requests](../user/project/merge_requests/index.md) ([API](merge_requests.md)).
+- [Snippets](../user/snippets.md) ([API](snippets.md)).
+- [Comments](../user/emoji_reactions.md#emoji-reactions-for-comments) ([API](notes.md)).
+
+## Issues, merge requests, and snippets
+
+For information on using these endpoints with comments, see [Add reactions to comments](#add-reactions-to-comments).
+
+### List an awardable's emoji reactions
+
+> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/335068) in GitLab 15.1 to allow unauthenticated access to public awardables.
+
+Get a list of all emoji reactions for a specified awardable. This endpoint can
+be accessed without authentication if the awardable is publicly accessible.
+
+```plaintext
+GET /projects/:id/issues/:issue_iid/award_emoji
+GET /projects/:id/merge_requests/:merge_request_iid/award_emoji
+GET /projects/:id/snippets/:snippet_id/award_emoji
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+|:---------------|:---------------|:---------|:-----------------------------------------------------------------------------|
+| `id` | integer/string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
+| `issue_iid`/`merge_request_iid`/`snippet_id` | integer | yes | ID (`iid` for merge requests/issues, `id` for snippets) of an awardable. |
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji"
+```
+
+Example response:
+
+```json
+[
+ {
+ "id": 4,
+ "name": "1234",
+ "user": {
+ "name": "Administrator",
+ "username": "root",
+ "id": 1,
+ "state": "active",
+ "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
+ "web_url": "http://gitlab.example.com/root"
+ },
+ "created_at": "2016-06-15T10:09:34.206Z",
+ "updated_at": "2016-06-15T10:09:34.206Z",
+ "awardable_id": 80,
+ "awardable_type": "Issue"
+ },
+ {
+ "id": 1,
+ "name": "microphone",
+ "user": {
+ "name": "User 4",
+ "username": "user4",
+ "id": 26,
+ "state": "active",
+ "avatar_url": "http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon",
+ "web_url": "http://gitlab.example.com/user4"
+ },
+ "created_at": "2016-06-15T10:09:34.177Z",
+ "updated_at": "2016-06-15T10:09:34.177Z",
+ "awardable_id": 80,
+ "awardable_type": "Issue"
+ }
+]
+```
+
+### Get single emoji reaction
+
+> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/335068) in GitLab 15.1 to allow unauthenticated access to public awardables.
+
+Get a single emoji reaction from an issue, snippet, or merge request. This endpoint can
+be accessed without authentication if the awardable is publicly accessible.
+
+```plaintext
+GET /projects/:id/issues/:issue_iid/award_emoji/:award_id
+GET /projects/:id/merge_requests/:merge_request_iid/award_emoji/:award_id
+GET /projects/:id/snippets/:snippet_id/award_emoji/:award_id
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+|:---------------|:---------------|:---------|:-----------------------------------------------------------------------------|
+| `id` | integer/string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
+| `issue_iid`/`merge_request_iid`/`snippet_id` | integer | yes | ID (`iid` for merge requests/issues, `id` for snippets) of an awardable. |
+| `award_id` | integer | yes | ID of the emoji reaction. |
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji/1"
+```
+
+Example response:
+
+```json
+{
+ "id": 1,
+ "name": "microphone",
+ "user": {
+ "name": "User 4",
+ "username": "user4",
+ "id": 26,
+ "state": "active",
+ "avatar_url": "http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon",
+ "web_url": "http://gitlab.example.com/user4"
+ },
+ "created_at": "2016-06-15T10:09:34.177Z",
+ "updated_at": "2016-06-15T10:09:34.177Z",
+ "awardable_id": 80,
+ "awardable_type": "Issue"
+}
+```
+
+### Add a new emoji reaction
+
+Add an emoji reaction on the specified awardable.
+
+```plaintext
+POST /projects/:id/issues/:issue_iid/award_emoji
+POST /projects/:id/merge_requests/:merge_request_iid/award_emoji
+POST /projects/:id/snippets/:snippet_id/award_emoji
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+|:---------------|:---------------|:---------|:-----------------------------------------------------------------------------|
+| `id` | integer/string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
+| `issue_iid`/`merge_request_iid`/`snippet_id` | integer | yes | ID (`iid` for merge requests/issues, `id` for snippets) of an awardable. |
+| `name` | string | yes | Name of the emoji without colons. |
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji?name=blowfish"
+```
+
+Example Response:
+
+```json
+{
+ "id": 344,
+ "name": "blowfish",
+ "user": {
+ "name": "Administrator",
+ "username": "root",
+ "id": 1,
+ "state": "active",
+ "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
+ "web_url": "http://gitlab.example.com/root"
+ },
+ "created_at": "2016-06-17T17:47:29.266Z",
+ "updated_at": "2016-06-17T17:47:29.266Z",
+ "awardable_id": 80,
+ "awardable_type": "Issue"
+}
+```
+
+### Delete an emoji reaction
+
+Sometimes it's just not meant to be and you need to remove your reaction.
+
+Only an administrator or the author of the reaction can delete an emoji reaction.
+
+```plaintext
+DELETE /projects/:id/issues/:issue_iid/award_emoji/:award_id
+DELETE /projects/:id/merge_requests/:merge_request_iid/award_emoji/:award_id
+DELETE /projects/:id/snippets/:snippet_id/award_emoji/:award_id
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+|:---------------|:---------------|:---------|:-----------------------------------------------------------------------------|
+| `id` | integer/string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
+| `issue_iid`/`merge_request_iid`/`snippet_id` | integer | yes | ID (`iid` for merge requests/issues, `id` for snippets) of an awardable. |
+| `award_id` | integer | yes | ID of an emoji reaction. |
+
+```shell
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji/344"
+```
+
+## Add reactions to comments
+
+Comments (also known as notes) are a sub-resource of issues, merge requests, and snippets.
+
+NOTE:
+The examples below describe working with emoji reactions on an issue's comments, but can be
+adapted to comments on merge requests and snippets. Therefore, you have to replace
+`issue_iid` either with `merge_request_iid` or with the `snippet_id`.
+
+### List a comment's emoji reactions
+
+> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/335068) in GitLab 15.1 to allow unauthenticated access to public comments.
+
+Get all emoji reactions for a comment (note). This endpoint can
+be accessed without authentication if the comment is publicly accessible.
+
+```plaintext
+GET /projects/:id/issues/:issue_iid/notes/:note_id/award_emoji
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+|:------------|:---------------|:---------|:-----------------------------------------------------------------------------|
+| `id` | integer/string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
+| `issue_iid` | integer | yes | Internal ID of an issue. |
+| `note_id` | integer | yes | ID of a comment (note). |
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/notes/1/award_emoji"
+```
+
+Example response:
+
+```json
+[
+ {
+ "id": 2,
+ "name": "mood_bubble_lightning",
+ "user": {
+ "name": "User 4",
+ "username": "user4",
+ "id": 26,
+ "state": "active",
+ "avatar_url": "http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon",
+ "web_url": "http://gitlab.example.com/user4"
+ },
+ "created_at": "2016-06-15T10:09:34.197Z",
+ "updated_at": "2016-06-15T10:09:34.197Z",
+ "awardable_id": 1,
+ "awardable_type": "Note"
+ }
+]
+```
+
+### Get an emoji reaction for a comment
+
+> [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/335068) in GitLab 15.1 to allow unauthenticated access to public comments.
+
+Get a single emoji reaction for a comment (note). This endpoint can
+be accessed without authentication if the comment is publicly accessible.
+
+```plaintext
+GET /projects/:id/issues/:issue_iid/notes/:note_id/award_emoji/:award_id
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+|:------------|:---------------|:---------|:-----------------------------------------------------------------------------|
+| `id` | integer/string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
+| `issue_iid` | integer | yes | Internal ID of an issue. |
+| `note_id` | integer | yes | ID of a comment (note). |
+| `award_id` | integer | yes | ID of the emoji reaction. |
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/notes/1/award_emoji/2"
+```
+
+Example response:
+
+```json
+{
+ "id": 2,
+ "name": "mood_bubble_lightning",
+ "user": {
+ "name": "User 4",
+ "username": "user4",
+ "id": 26,
+ "state": "active",
+ "avatar_url": "http://www.gravatar.com/avatar/7e65550957227bd38fe2d7fbc6fd2f7b?s=80&d=identicon",
+ "web_url": "http://gitlab.example.com/user4"
+ },
+ "created_at": "2016-06-15T10:09:34.197Z",
+ "updated_at": "2016-06-15T10:09:34.197Z",
+ "awardable_id": 1,
+ "awardable_type": "Note"
+}
+```
+
+### Add a new emoji reaction to a comment
+
+Create an emoji reaction on the specified comment (note).
+
+```plaintext
+POST /projects/:id/issues/:issue_iid/notes/:note_id/award_emoji
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+|:------------|:---------------|:---------|:-----------------------------------------------------------------------------|
+| `id` | integer/string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
+| `issue_iid` | integer | yes | Internal ID of an issue. |
+| `note_id` | integer | yes | ID of a comment (note). |
+| `name` | string | yes | Name of the emoji without colons. |
+
+Example request:
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/notes/1/award_emoji?name=rocket"
+```
+
+Example response:
+
+```json
+{
+ "id": 345,
+ "name": "rocket",
+ "user": {
+ "name": "Administrator",
+ "username": "root",
+ "id": 1,
+ "state": "active",
+ "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
+ "web_url": "http://gitlab.example.com/root"
+ },
+ "created_at": "2016-06-17T19:59:55.888Z",
+ "updated_at": "2016-06-17T19:59:55.888Z",
+ "awardable_id": 1,
+ "awardable_type": "Note"
+}
+```
+
+### Delete an emoji reaction from a comment
+
+Sometimes it's just not meant to be and you need to remove the reaction.
+
+Only an administrator or the author of the reaction can delete an emoji reaction.
+
+```plaintext
+DELETE /projects/:id/issues/:issue_iid/notes/:note_id/award_emoji/:award_id
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+|:------------|:---------------|:---------|:-----------------------------------------------------------------------------|
+| `id` | integer/string | yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding). |
+| `issue_iid` | integer | yes | Internal ID of an issue. |
+| `note_id` | integer | yes | ID of a comment (note). |
+| `award_id` | integer | yes | ID of an emoji reaction. |
+
+Example request:
+
+```shell
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/issues/80/award_emoji/345"
+```
diff --git a/doc/api/graphql/custom_emoji.md b/doc/api/graphql/custom_emoji.md
index 7efadb7e9dd..c1caf4f90b1 100644
--- a/doc/api/graphql/custom_emoji.md
+++ b/doc/api/graphql/custom_emoji.md
@@ -14,7 +14,7 @@ On self-managed GitLab, by default this feature is not available. To make it ava
On GitLab.com, this feature is available.
This feature is ready for production use.
-To use [custom emoji](../../user/award_emojis.md) in comments and descriptions, you can add them to a top-level group using the GraphQL API.
+To use [custom emoji](../../user/emoji_reactions.md) in comments and descriptions, you can add them to a top-level group using the GraphQL API.
Parameters:
diff --git a/doc/api/merge_request_approvals.md b/doc/api/merge_request_approvals.md
index d00252da207..fd8026d3077 100644
--- a/doc/api/merge_request_approvals.md
+++ b/doc/api/merge_request_approvals.md
@@ -601,20 +601,6 @@ Supported attributes:
}
```
-<!--- start_remove The following content will be removed on remove_date: '2023-08-17' -->
-
-### Change approval configuration (removed)
-
-> - Endpoint `/approvals` [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/11132) in GitLab 12.3.
-> - Endpoint `approvals` [disabled](https://gitlab.com/gitlab-org/gitlab/-/issues/353097) in GitLab 16.0 [with a flag](../administration/feature_flags.md) named `remove_deprecated_approvals`. Disabled by default.
-
-The endpoint `POST /projects/:id/merge_requests/:merge_request_iid/approvals` was
-deprecated in GitLab 12.3, and removed in GitLab 16.0. To change the approvals
-required for a merge request, use the `/approval_rules` endpoint described in
-[Create merge request level rule](#create-merge-request-level-rule) on this page.
-
-<!--- end_remove -->
-
### Get the approval state of merge requests
> Moved to GitLab Premium in 13.9.
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 2c00e1cbdc8..232ef56a20a 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -1551,7 +1551,7 @@ curl --request POST --header "PRIVATE-TOKEN: <your-token>" \
| `resolve_outdated_diff_discussions` | boolean | No | Automatically resolve merge request diffs discussions on lines changed with a push. |
| `security_and_compliance_access_level` | string | No | (GitLab 14.9 and later) Security and compliance access level. One of `disabled`, `private`, or `enabled`. |
| `shared_runners_enabled` | boolean | No | Enable shared runners for this project. |
-| `show_default_award_emojis` | boolean | No | Show default award emojis. |
+| `show_default_award_emojis` | boolean | No | Show default emoji reactions. |
| `snippets_access_level` | string | No | One of `disabled`, `private`, or `enabled`. |
| `snippets_enabled` | boolean | No | _(Deprecated)_ Enable snippets for this project. Use `snippets_access_level` instead. |
| `squash_option` | string | No | One of `never`, `always`, `default_on`, or `default_off`. |
@@ -1639,7 +1639,7 @@ POST /projects/user/:user_id
| `resolve_outdated_diff_discussions` | boolean | No | Automatically resolve merge request diffs discussions on lines changed with a push. |
| `security_and_compliance_access_level` | string | No | (GitLab 14.9 and later) Security and compliance access level. One of `disabled`, `private`, or `enabled`. |
| `shared_runners_enabled` | boolean | No | Enable shared runners for this project. |
-| `show_default_award_emojis` | boolean | No | Show default award emojis. |
+| `show_default_award_emojis` | boolean | No | Show default emoji reactions. |
| `snippets_access_level` | string | No | One of `disabled`, `private`, or `enabled`. |
| `snippets_enabled` | boolean | No | _(Deprecated)_ Enable snippets for this project. Use `snippets_access_level` instead. |
| `issue_branch_template` | string | No | Template used to suggest names for [branches created from issues](../user/project/merge_requests/creating_merge_requests.md#from-an-issue). _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21243) in GitLab 15.6.)_ |
@@ -1755,7 +1755,7 @@ Supported attributes:
| `security_and_compliance_access_level` | string | No | (GitLab 14.9 and later) Security and compliance access level. One of `disabled`, `private`, or `enabled`. |
| `service_desk_enabled` | boolean | No | Enable or disable Service Desk feature. |
| `shared_runners_enabled` | boolean | No | Enable shared runners for this project. |
-| `show_default_award_emojis` | boolean | No | Show default award emojis. |
+| `show_default_award_emojis` | boolean | No | Show default emoji reactions. |
| `snippets_access_level` | string | No | One of `disabled`, `private`, or `enabled`. |
| `snippets_enabled` | boolean | No | _(Deprecated)_ Enable snippets for this project. Use `snippets_access_level` instead. |
| `issue_branch_template` | string | No | Template used to suggest names for [branches created from issues](../user/project/merge_requests/creating_merge_requests.md#from-an-issue). _([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21243) in GitLab 15.6.)_ |
diff --git a/doc/architecture/blueprints/cells/index.md b/doc/architecture/blueprints/cells/index.md
index 28414f9b68c..5ffd2f07a61 100644
--- a/doc/architecture/blueprints/cells/index.md
+++ b/doc/architecture/blueprints/cells/index.md
@@ -265,12 +265,12 @@ One iteration describes one quarter's worth of work.
- Data access layer: Initial Admin Area settings are shared across cluster.
- Essential workflows: Allow to share cluster-wide data with database-level data access layer
-1. [Iteration 2](https://gitlab.com/groups/gitlab-org/-/epics/9813) - Expected delivery: 16.2 FY24Q2 | Actual delivery: 16.4 FY24Q3 - In progress
+1. [Iteration 2](https://gitlab.com/groups/gitlab-org/-/epics/9813) - Expected delivery: 16.2 FY24Q2, Actual delivery: 16.4 FY24Q3 - Complete
- Essential workflows: User accounts are shared across cluster.
- Essential workflows: User can create Group.
-1. [Iteration 3](https://gitlab.com/groups/gitlab-org/-/epics/10997) - Expected delivery: 16.7 FY24Q4 - Planned
+1. [Iteration 3](https://gitlab.com/groups/gitlab-org/-/epics/10997) - Expected delivery: 16.7 FY24Q4 - In Progress
- Essential workflows: User can create Project.
- Routing: Technology.
diff --git a/doc/architecture/blueprints/gitlab_ml_experiments/index.md b/doc/architecture/blueprints/gitlab_ml_experiments/index.md
index 90adfc41257..e0675bb5be6 100644
--- a/doc/architecture/blueprints/gitlab_ml_experiments/index.md
+++ b/doc/architecture/blueprints/gitlab_ml_experiments/index.md
@@ -69,7 +69,7 @@ Instead of embedding these applications directly into the Rails and/or Sidekiq c
![use services instead of fat containers](https://docs.google.com/drawings/d/e/2PACX-1vSRrPo0TNtXG8Yqj37TO2PaND9PojGZzNRs2rcTA37-vBZm5WZlfxLDCKVJD1vYHTbGy1KY1rDYHwlg/pub?w=1008&h=564)\
[source](https://docs.google.com/drawings/d/1ZPprcSYH5Oqp8T46I0p1Hhr-GD55iREDvFWcpQq9dTQ/edit)
-The service-integration approach has already been used for the [Suggested Reviewers feature](https://gitlab.com/gitlab-com/gl-infra/readiness/-/merge_requests/114) that has been deployed to GitLab.com.
+The service-integration approach has already been used for the [GitLab Duo Suggested Reviewers feature](https://gitlab.com/gitlab-com/gl-infra/readiness/-/merge_requests/114) that has been deployed to GitLab.com.
This approach would have many advantages:
diff --git a/doc/operations/incident_management/status_page.md b/doc/operations/incident_management/status_page.md
index 682b2ffd705..1d376301250 100644
--- a/doc/operations/incident_management/status_page.md
+++ b/doc/operations/incident_management/status_page.md
@@ -159,7 +159,7 @@ To publish comments to the Status Page Incident:
- Create a comment on the incident issue.
- When you're ready to publish the comment, mark the comment for publication by
- adding a microphone [emoji reaction](../../user/award_emojis.md)
+ adding a microphone [emoji reaction](../../user/emoji_reactions.md)
reaction (`:microphone:` 🎤) to the comment.
- Any files attached to the comment (up to 5000 per issue) are also published.
([Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/205166) in GitLab 13.1.)
diff --git a/doc/update/versions/gitlab_16_changes.md b/doc/update/versions/gitlab_16_changes.md
index 04581a88a93..8fe2f46c170 100644
--- a/doc/update/versions/gitlab_16_changes.md
+++ b/doc/update/versions/gitlab_16_changes.md
@@ -304,7 +304,7 @@ configuration. Some `gitaly['..']` configuration options continue to be used by
- `consul_service_name`
- `consul_service_meta`
-Migrate by moving your existing configuration under the new structure. The new structure is supported from GitLab 15.10.
+Migrate by moving your existing configuration under the new structure. `git_data_dirs` is supported [until GitLab 17.0](https://gitlab.com/gitlab-org/gitaly/-/issues/5133). The new structure is supported from GitLab 15.10.
**Migrate to the new structure**
diff --git a/doc/user/award_emojis.md b/doc/user/award_emojis.md
index 26cccd7584e..09f7b4c77fa 100644
--- a/doc/user/award_emojis.md
+++ b/doc/user/award_emojis.md
@@ -1,68 +1,11 @@
---
-stage: Plan
-group: Project Management
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
+redirect_to: 'emoji_reactions.md'
+remove_date: '2023-12-20'
---
-# Emoji reactions **(FREE ALL)**
+This document was moved to [another location](emoji_reactions.md).
-> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/409884) from "award emoji" to "emoji reactions" in GitLab 16.0.
-> - Reacting with emoji on work items (such as tasks, objectives, and key results) [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/393599) in GitLab 16.0.
-> - Reacting with emoji on design discussion comments [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29756) in GitLab 16.2.
-
-When you're collaborating online, you get fewer opportunities for high-fives
-and thumbs-ups. React with emoji on:
-
-- [Issues](project/issues/index.md).
-- [Tasks](tasks.md).
-- [Merge requests](project/merge_requests/index.md),
-[snippets](snippets.md).
-- [Epics](../user/group/epics/index.md).
-- [Objectives and key results](okrs.md).
-- Anywhere else you can have a comment thread.
-
-![Emoji reactions](img/award_emoji_select_v14_6.png)
-
-Emoji reactions make it much easier to give and receive feedback without a long
-comment thread.
-
-"Thumbs up" and "thumbs down" emoji are used to calculate an issue or merge request's position when
-[sorting by popularity](project/issues/sorting_issue_lists.md#sorting-by-popularity).
-
-For information on the relevant API, see [Emoji reactions API](../api/award_emoji.md).
-
-## Emoji reactions for comments
-
-Emoji reactions can also be applied to individual comments when you want to
-celebrate an accomplishment or agree with an opinion.
-
-To add an emoji reaction:
-
-1. In the upper-right corner of the comment, select the smile (**{slight-smile}**).
-1. Select an emoji from the emoji picker.
-
-To remove an emoji reaction, select the emoji again.
-
-## Custom emoji
-
-> - [Introduced for GraphQL API](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37911) in GitLab 13.6 [with a flag](../administration/feature_flags.md) named `custom_emoji`. Disabled by default.
-> - Enabled on GitLab.com in GitLab 14.0.
-> - UI to add emoji [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/333095) in GitLab 16.2.
-
-Custom emoji show in the emoji picker everywhere you can react with emoji.
-To add an emoji reaction to a comment or description:
-
-1. Select **Add reaction** (**{slight-smile}**).
-1. Select the GitLab logo (**{tanuki}**) or scroll down to the **Custom** section.
-1. Select an emoji from the emoji picker.
-
-![Custom emoji in emoji picker](img/custom_emoji_reactions_v16_2.png)
-
-To use them in a text box, type the filename between two colons.
-For example, `:thank-you:`.
-
-You can upload custom emoji to a GitLab instance with the GraphQL API.
-For more information, see [Use custom emoji with GraphQL](../api/graphql/custom_emoji.md).
-
-For a list of custom emoji available for GitLab.com, see
-[the `custom_emoji` project](https://gitlab.com/custom_emoji/custom_emoji/-/tree/main/img).
+<!-- This redirect file can be deleted after <2023-12-20>. -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/user/emoji_reactions.md b/doc/user/emoji_reactions.md
new file mode 100644
index 00000000000..1b2c1bcd2e5
--- /dev/null
+++ b/doc/user/emoji_reactions.md
@@ -0,0 +1,68 @@
+---
+stage: Plan
+group: Project Management
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
+---
+
+# Emoji reactions **(FREE ALL)**
+
+> - [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/409884) from "award emoji" to "emoji reactions" in GitLab 16.0.
+> - Reacting with emoji on work items (such as tasks, objectives, and key results) [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/393599) in GitLab 16.0.
+> - Reacting with emoji on design discussion comments [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29756) in GitLab 16.2.
+
+When you're collaborating online, you get fewer opportunities for high-fives
+and thumbs-ups. React with emoji on:
+
+- [Issues](project/issues/index.md).
+- [Tasks](tasks.md).
+- [Merge requests](project/merge_requests/index.md),
+[snippets](snippets.md).
+- [Epics](../user/group/epics/index.md).
+- [Objectives and key results](okrs.md).
+- Anywhere else you can have a comment thread.
+
+![Emoji reactions](img/award_emoji_select_v14_6.png)
+
+Emoji reactions make it much easier to give and receive feedback without a long
+comment thread.
+
+"Thumbs up" and "thumbs down" emoji are used to calculate an issue or merge request's position when
+[sorting by popularity](project/issues/sorting_issue_lists.md#sorting-by-popularity).
+
+For information on the relevant API, see [Emoji reactions API](../api/emoji_reactions.md).
+
+## Emoji reactions for comments
+
+Emoji reactions can also be applied to individual comments when you want to
+celebrate an accomplishment or agree with an opinion.
+
+To add an emoji reaction:
+
+1. In the upper-right corner of the comment, select the smile (**{slight-smile}**).
+1. Select an emoji from the emoji picker.
+
+To remove an emoji reaction, select the emoji again.
+
+## Custom emoji
+
+> - [Introduced for GraphQL API](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37911) in GitLab 13.6 [with a flag](../administration/feature_flags.md) named `custom_emoji`. Disabled by default.
+> - Enabled on GitLab.com in GitLab 14.0.
+> - UI to add emoji [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/333095) in GitLab 16.2.
+
+Custom emoji show in the emoji picker everywhere you can react with emoji.
+To add an emoji reaction to a comment or description:
+
+1. Select **Add reaction** (**{slight-smile}**).
+1. Select the GitLab logo (**{tanuki}**) or scroll down to the **Custom** section.
+1. Select an emoji from the emoji picker.
+
+![Custom emoji in emoji picker](img/custom_emoji_reactions_v16_2.png)
+
+To use them in a text box, type the filename between two colons.
+For example, `:thank-you:`.
+
+You can upload custom emoji to a GitLab instance with the GraphQL API.
+For more information, see [Use custom emoji with GraphQL](../api/graphql/custom_emoji.md).
+
+For a list of custom emoji available for GitLab.com, see
+[the `custom_emoji` project](https://gitlab.com/custom_emoji/custom_emoji/-/tree/main/img).
diff --git a/doc/user/group/epics/index.md b/doc/user/group/epics/index.md
index 7b977dc2026..83d38dbc70b 100644
--- a/doc/user/group/epics/index.md
+++ b/doc/user/group/epics/index.md
@@ -66,7 +66,7 @@ have a start or due date, a visual
- Link [related epics](linked_epics.md) based on a type of relationship.
- Create workflows with [epic boards](epic_boards.md).
- [Turn on notifications](../../profile/notifications.md) for about epic events.
-- [Add an emoji reaction](../../award_emojis.md) to an epic or its comments.
+- [Add an emoji reaction](../../emoji_reactions.md) to an epic or its comments.
- Collaborate on an epic by posting comments in a [thread](../../discussions/index.md).
- Use [health status](../../project/issues/managing_issues.md#health-status) to track your progress.
diff --git a/doc/user/markdown.md b/doc/user/markdown.md
index c996b29c9a2..7f097891e92 100644
--- a/doc/user/markdown.md
+++ b/doc/user/markdown.md
@@ -262,7 +262,7 @@ this font installed by default.
<!-- vale gitlab.Spelling = YES -->
-To learn more about adding custom emoji, see [Custom emoji](award_emojis.md#custom-emoji).
+To learn more about adding custom emoji, see [Custom emoji](emoji_reactions.md#custom-emoji).
### Front matter
diff --git a/doc/user/project/integrations/webhook_events.md b/doc/user/project/integrations/webhook_events.md
index 269fdf304a8..204452a072d 100644
--- a/doc/user/project/integrations/webhook_events.md
+++ b/doc/user/project/integrations/webhook_events.md
@@ -24,7 +24,7 @@ Event type | Trigger
[Subgroup event](#subgroup-events) | A subgroup is created or removed from a group.
[Feature flag event](#feature-flag-events) | A feature flag is turned on or off.
[Release event](#release-events) | A release is created or updated.
-[Emoji event](#emoji-events) | An emoji is awarded or revoked.
+[Emoji event](#emoji-events) | An emoji reaction is added or removed.
NOTE:
If an author has no public email listed in their
@@ -1891,7 +1891,7 @@ On self-managed GitLab, by default this feature is available. To hide the featur
NOTE:
To have the `emoji_webhooks` flag enabled on GitLab.com, see [issue 417288](https://gitlab.com/gitlab-org/gitlab/-/issues/417288).
-An emoji event is triggered when an emoji is awarded or revoked on:
+An emoji event is triggered when an [emoji reaction](../../emoji_reactions.md) is added or removed on:
- Issues
- Merge requests
@@ -1904,8 +1904,8 @@ An emoji event is triggered when an emoji is awarded or revoked on:
The available values for `object_attributes.action` in the payload are:
-- `award`
-- `revoke`
+- `award` to add a reaction
+- `revoke` to remove a reaction
Request header:
diff --git a/doc/user/project/issues/sorting_issue_lists.md b/doc/user/project/issues/sorting_issue_lists.md
index c365bfa5a52..f2ecfc1f24b 100644
--- a/doc/user/project/issues/sorting_issue_lists.md
+++ b/doc/user/project/issues/sorting_issue_lists.md
@@ -73,7 +73,7 @@ then issues with a milestone without a due date.
## Sorting by popularity
When you sort by **Popularity**, the issue order changes to sort descending by the
-number of upvotes ([emoji reactions](../../award_emojis.md) with the "thumbs up")
+number of upvotes ([emoji reactions](../../emoji_reactions.md) with the "thumbs up")
on each issue. You can use this to identify issues that are in high demand.
The total number of votes is not summed up. An issue with 18 upvotes and 5
diff --git a/doc/user/project/merge_requests/reviews/data_usage.md b/doc/user/project/merge_requests/reviews/data_usage.md
index 24e3b6a5667..b4b9b19c932 100644
--- a/doc/user/project/merge_requests/reviews/data_usage.md
+++ b/doc/user/project/merge_requests/reviews/data_usage.md
@@ -9,7 +9,7 @@ type: index, reference
## How it works
-Suggested Reviewers is the first user-facing GitLab machine learning (ML) powered feature. It leverages a project's contribution graph to generate suggestions. This data already exists within GitLab including merge request metadata, source code files, and GitLab user account metadata.
+GitLab Duo Suggested Reviewers is the first user-facing GitLab machine learning (ML) powered feature. It leverages a project's contribution graph to generate suggestions. This data already exists within GitLab including merge request metadata, source code files, and GitLab user account metadata.
### Enabling the feature
diff --git a/doc/user/project/merge_requests/reviews/index.md b/doc/user/project/merge_requests/reviews/index.md
index c09071e856c..0a3efa38440 100644
--- a/doc/user/project/merge_requests/reviews/index.md
+++ b/doc/user/project/merge_requests/reviews/index.md
@@ -40,12 +40,12 @@ GitLab Duo Suggested Reviewers also integrates with Code Owners, profile status,
For more information, see [Data usage in GitLab Duo Suggested Reviewers](data_usage.md).
-### Enable suggested reviewers
+### Enable Suggested Reviewers
-Project Maintainers or Owners can enable suggested reviewers by visiting
+Project Maintainers or Owners can enable Suggested Reviewers by visiting
the [project settings](../../settings/index.md).
-Enabling suggested reviewers triggers GitLab to create an ML model for your
+Enabling Suggested Reviewers triggers GitLab to create an ML model for your
project that is used to generate reviewers. The larger your project, the longer
this process can take. Usually, the model is ready to generate suggestions
within a few hours.
@@ -199,7 +199,7 @@ If you have a review in progress, you can also add a comment from the **Overview
When editing the **Reviewers** field in a new or existing merge request, GitLab
displays the name of the matching [approval rule](../approvals/rules.md)
-below the name of each suggested reviewer. [Code Owners](../../codeowners/index.md) are displayed as `Codeowner` without group detail.
+below the name of each reviewer. [Code Owners](../../codeowners/index.md) are displayed as `Codeowner` without group detail.
This example shows reviewers and approval rules when creating a new merge request:
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 8d1697b4a8e..188a6cd5e42 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -1911,9 +1911,6 @@ msgstr ""
msgid "AI|Apply AI-generated description"
msgstr ""
-msgid "AI|Ask GitLab Duo"
-msgstr ""
-
msgid "AI|Ask a question"
msgstr ""
@@ -1956,6 +1953,9 @@ msgstr ""
msgid "AI|GitLab Duo"
msgstr ""
+msgid "AI|GitLab Duo Chat"
+msgstr ""
+
msgid "AI|Give feedback on AI content"
msgstr ""
@@ -4671,9 +4671,6 @@ msgstr ""
msgid "All"
msgstr ""
-msgid "All %{replicableType} are being scheduled for %{action}"
-msgstr ""
-
msgid "All (default)"
msgstr ""
@@ -20817,6 +20814,9 @@ msgid_plural "Geo|%d shards selected"
msgstr[0] ""
msgstr[1] ""
+msgid "Geo|%{action} %{replicableType}"
+msgstr ""
+
msgid "Geo|%{boldStart}Not applicable%{boldEnd}: Geo does not verify this component yet. See the %{linkStart}data types we plan to support%{linkEnd}."
msgstr ""
@@ -20856,6 +20856,9 @@ msgstr ""
msgid "Geo|All"
msgstr ""
+msgid "Geo|All %{replicableType} are being scheduled for %{action}"
+msgstr ""
+
msgid "Geo|All %{replicable_name}"
msgstr ""
@@ -21159,9 +21162,6 @@ msgstr ""
msgid "Geo|Resync all %{projects_count} projects"
msgstr ""
-msgid "Geo|Resync all %{total}%{replicableType}"
-msgstr ""
-
msgid "Geo|Resync project"
msgstr ""
@@ -21279,13 +21279,16 @@ msgstr ""
msgid "Geo|There was an error saving this Geo Site"
msgstr ""
+msgid "Geo|There was an error scheduling action %{action} for %{replicableType}"
+msgstr ""
+
msgid "Geo|There was an error updating the Geo Settings"
msgstr ""
msgid "Geo|This GitLab instance is subscribed to the %{insufficient_license} tier. Geo is only available for users who have at least a Premium subscription."
msgstr ""
-msgid "Geo|This will resync all %{replicableType}. It may take some time to complete. Are you sure you want to continue?"
+msgid "Geo|This will %{action} %{replicableType}. It may take some time to complete. Are you sure you want to continue?"
msgstr ""
msgid "Geo|This will resync all projects. It may take some time to complete. Are you sure you want to continue?"
@@ -46643,9 +46646,6 @@ msgstr ""
msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
msgstr ""
-msgid "TanukiBot|Ask GitLab Duo"
-msgstr ""
-
msgid "TanukiBot|Ask a question about GitLab"
msgstr ""
@@ -48012,9 +48012,6 @@ msgstr ""
msgid "There was an error syncing project %{name}"
msgstr ""
-msgid "There was an error syncing the %{replicableType}"
-msgstr ""
-
msgid "There was an error trying to validate your query"
msgstr ""
diff --git a/spec/controllers/admin/groups_controller_spec.rb b/spec/controllers/admin/groups_controller_spec.rb
index c534cf14327..01b96c2eb81 100644
--- a/spec/controllers/admin/groups_controller_spec.rb
+++ b/spec/controllers/admin/groups_controller_spec.rb
@@ -11,6 +11,96 @@ RSpec.describe Admin::GroupsController do
sign_in(admin)
end
+ describe 'GET #index' do
+ let!(:group_2) { create(:group, name: 'Ygroup') }
+ let!(:group_3) { create(:group, name: 'Jgroup', created_at: 2.days.ago, updated_at: 1.day.ago) }
+
+ render_views
+
+ it 'lists available groups' do
+ get :index
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to render_template(:index)
+ expect(assigns(:groups)).to match_array([group, group_2, group_3])
+ end
+
+ it 'renders a correct list of sort by options' do
+ get :index
+
+ html_rendered = Nokogiri::HTML(response.body)
+ sort_options = Gitlab::Json.parse(html_rendered.css('div.dropdown')[0]['data-items'])
+
+ expect(response).to render_template('shared/groups/_dropdown')
+
+ expect(sort_options.size).to eq(7)
+ expect(sort_options[0]['value']).to eq('name_asc')
+ expect(sort_options[0]['text']).to eq(s_('SortOptions|Name'))
+
+ expect(sort_options[1]['value']).to eq('name_desc')
+ expect(sort_options[1]['text']).to eq(s_('SortOptions|Name, descending'))
+
+ expect(sort_options[2]['value']).to eq('created_desc')
+ expect(sort_options[2]['text']).to eq(s_('SortOptions|Last created'))
+
+ expect(sort_options[3]['value']).to eq('created_asc')
+ expect(sort_options[3]['text']).to eq(s_('SortOptions|Oldest created'))
+
+ expect(sort_options[4]['value']).to eq('latest_activity_desc')
+ expect(sort_options[4]['text']).to eq(_('Updated date'))
+
+ expect(sort_options[5]['value']).to eq('latest_activity_asc')
+ expect(sort_options[5]['text']).to eq(s_('SortOptions|Oldest updated'))
+
+ expect(sort_options[6]['value']).to eq('storage_size_desc')
+ expect(sort_options[6]['text']).to eq(s_('SortOptions|Largest group'))
+ end
+
+ context 'when a sort param is present' do
+ it 'returns a sorted by name_asc result' do
+ get :index, params: { sort: 'name_asc' }
+
+ expect(assigns(:groups)).to match_array([group, group_3, group_2])
+ end
+ end
+
+ context 'when a name param is present' do
+ it 'returns a search by name result' do
+ get :index, params: { name: 'Ygr' }
+
+ expect(assigns(:groups)).to match_array([group_2])
+ end
+
+ it 'returns an empty list if no match' do
+ get :index, params: { name: 'nomatch' }
+
+ expect(assigns(:groups)).to be_empty
+ end
+ end
+
+ context 'when page is specified' do
+ before do
+ allow(Kaminari.config).to receive(:default_per_page).and_return(1)
+ end
+
+ it 'redirects to the page' do
+ get :index, params: { page: 1 }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(assigns(:groups).current_page).to eq(1)
+ expect(assigns(:groups)).to eq([group])
+ end
+
+ it 'redirects to the page' do
+ get :index, params: { page: 2 }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(assigns(:groups).current_page).to eq(2)
+ expect(assigns(:groups)).to eq([group_2])
+ end
+ end
+ end
+
describe 'DELETE #destroy' do
it 'schedules a group destroy' do
Sidekiq::Testing.fake! do
diff --git a/spec/frontend/gfm_auto_complete_spec.js b/spec/frontend/gfm_auto_complete_spec.js
index 2d19c9871b6..da465552db3 100644
--- a/spec/frontend/gfm_auto_complete_spec.js
+++ b/spec/frontend/gfm_auto_complete_spec.js
@@ -55,14 +55,14 @@ describe('GfmAutoComplete', () => {
describe('assets loading', () => {
beforeEach(() => {
- atwhoInstance = { setting: {}, $inputor: 'inputor', at: '[vulnerability:' };
+ atwhoInstance = { setting: {}, $inputor: 'inputor', at: '~' };
items = ['loading'];
filterValue = gfmAutoCompleteCallbacks.filter.call(atwhoInstance, '', items);
});
it('should call the fetchData function without query', () => {
- expect(fetchDataMock.fetchData).toHaveBeenCalledWith('inputor', '[vulnerability:');
+ expect(fetchDataMock.fetchData).toHaveBeenCalledWith('inputor', '~');
});
it('should not call the default atwho filter', () => {
@@ -80,6 +80,29 @@ describe('GfmAutoComplete', () => {
items = [];
});
+ describe('when loading', () => {
+ beforeEach(() => {
+ items = ['loading'];
+ filterValue = gfmAutoCompleteCallbacks.filter.call(atwhoInstance, 'oldquery', items);
+ });
+
+ it('should call the fetchData function with query', () => {
+ expect(fetchDataMock.fetchData).toHaveBeenCalledWith(
+ 'inputor',
+ '[vulnerability:',
+ 'oldquery',
+ );
+ });
+
+ it('should not call the default atwho filter', () => {
+ expect($.fn.atwho.default.callbacks.filter).not.toHaveBeenCalled();
+ });
+
+ it('should return the passed unfiltered items', () => {
+ expect(filterValue).toEqual(items);
+ });
+ });
+
describe('when previous query is different from current one', () => {
beforeEach(() => {
gfmAutoCompleteCallbacks = GfmAutoComplete.prototype.getDefaultCallbacks.call({
@@ -173,7 +196,7 @@ describe('GfmAutoComplete', () => {
context = {
isLoadingData: { '[vulnerability:': false },
dataSources: { vulnerabilities: 'vulnerabilities_autocomplete_url' },
- cachedData: {},
+ cachedData: { '[vulnerability:': { other_query: [] } },
};
});
@@ -206,15 +229,14 @@ describe('GfmAutoComplete', () => {
const context = {
isLoadingData: { '[vulnerability:': false },
dataSources: { vulnerabilities: 'vulnerabilities_autocomplete_url' },
- cachedData: { '[vulnerability:': [{}] },
+ cachedData: { '[vulnerability:': { query: [] } },
+ loadData: () => {},
};
fetchData.call(context, {}, '[vulnerability:', 'query');
});
- it('should anyway call axios with query ignoring cache', () => {
- expect(axios.get).toHaveBeenCalledWith('vulnerabilities_autocomplete_url', {
- params: { search: 'query' },
- });
+ it('should not call axios', () => {
+ expect(axios.get).not.toHaveBeenCalled();
});
});
});
diff --git a/spec/frontend/super_sidebar/components/help_center_spec.js b/spec/frontend/super_sidebar/components/help_center_spec.js
index c92f8a68678..39537b65fa5 100644
--- a/spec/frontend/super_sidebar/components/help_center_spec.js
+++ b/spec/frontend/super_sidebar/components/help_center_spec.js
@@ -104,7 +104,7 @@ describe('HelpCenter component', () => {
createWrapper({ ...sidebarData, show_tanuki_bot: true });
});
- it('shows Ask GitLab Duo with the help items', () => {
+ it('shows GitLab Duo Chat with the help items', () => {
expect(findDropdownGroup(0).props('group').items).toEqual([
expect.objectContaining({
icon: 'tanuki-ai',
@@ -115,9 +115,9 @@ describe('HelpCenter component', () => {
]);
});
- describe('when Ask GitLab Duo button is clicked', () => {
+ describe('when GitLab Duo Chat button is clicked', () => {
beforeEach(() => {
- findButton('Ask GitLab Duo').click();
+ findButton('GitLab Duo Chat').click();
});
it('sets helpCenterState.showTanukiBotChatDrawer to true', () => {
diff --git a/spec/frontend/vue_merge_request_widget/mr_widget_options_spec.js b/spec/frontend/vue_merge_request_widget/mr_widget_options_spec.js
index 68af4feffb7..eb3d624dc04 100644
--- a/spec/frontend/vue_merge_request_widget/mr_widget_options_spec.js
+++ b/spec/frontend/vue_merge_request_widget/mr_widget_options_spec.js
@@ -79,23 +79,13 @@ describe('MrWidgetOptions', () => {
const COLLABORATION_MESSAGE = 'Members who can merge are allowed to add commits';
- const setInitialData = (data) => {
- gl.mrWidgetData = { ...mockData, ...data };
- mock
- .onGet(mockData.merge_request_widget_path)
- .reply(() => [HTTP_STATUS_OK, { ...mockData, ...data }]);
- mock
- .onGet(mockData.merge_request_cached_widget_path)
- .reply(() => [HTTP_STATUS_OK, { ...mockData, ...data }]);
- };
-
const createComponent = ({
updatedMrData = {},
options = {},
data = {},
mountFn = shallowMountExtended,
} = {}) => {
- setInitialData(updatedMrData);
+ gl.mrWidgetData = { ...mockData, ...updatedMrData };
const mrData = { ...mockData, ...updatedMrData };
const mockedApprovalsSubscription = createMockApolloSubscription();
queryResponse = {
@@ -173,8 +163,10 @@ describe('MrWidgetOptions', () => {
const findWidgetContainer = () => wrapper.findComponent(WidgetContainer);
beforeEach(() => {
- gon.features = { asyncMrWidget: true };
+ gon.features = {};
mock = new MockAdapter(axios);
+ mock.onGet(mockData.merge_request_widget_path).reply(HTTP_STATUS_OK, {});
+ mock.onGet(mockData.merge_request_cached_widget_path).reply(HTTP_STATUS_OK, {});
});
afterEach(() => {
@@ -325,13 +317,23 @@ describe('MrWidgetOptions', () => {
describe('methods', () => {
describe('checkStatus', () => {
+ const updatedMrData = { foo: 1 };
+ beforeEach(() => {
+ mock
+ .onGet(mockData.merge_request_widget_path)
+ .reply(HTTP_STATUS_OK, { ...mockData, ...updatedMrData });
+ mock
+ .onGet(mockData.merge_request_cached_widget_path)
+ .reply(HTTP_STATUS_OK, { ...mockData, ...updatedMrData });
+ });
+
it('checks the status of the pipelines', async () => {
const callback = jest.fn();
- await createComponent({ updatedMrData: { foo: 1 } });
+ await createComponent({ updatedMrData });
await waitForPromises();
eventHub.$emit('MRWidgetUpdateRequested', callback);
await waitForPromises();
- expect(callback).toHaveBeenCalledWith(expect.objectContaining({ foo: 1 }));
+ expect(callback).toHaveBeenCalledWith(expect.objectContaining(updatedMrData));
});
it('notifies the user of the pipeline status', async () => {
@@ -504,29 +506,42 @@ describe('MrWidgetOptions', () => {
});
describe('handleNotification', () => {
+ const updatedMrData = { gitlabLogo: 'logo.png' };
beforeEach(() => {
jest.spyOn(notify, 'notifyMe').mockImplementation(() => {});
});
- it('should call notifyMe', async () => {
- const logoFilename = 'logo.png';
- await createComponent({ updatedMrData: { gitlabLogo: logoFilename } });
- expect(notify.notifyMe).toHaveBeenCalledWith(
- `Pipeline passed`,
- `Pipeline passed for "${mockData.title}"`,
- logoFilename,
- );
- });
+ describe('when pipeline has passed', () => {
+ beforeEach(() => {
+ mock
+ .onGet(mockData.merge_request_widget_path)
+ .reply(HTTP_STATUS_OK, { ...mockData, ...updatedMrData });
+ mock
+ .onGet(mockData.merge_request_cached_widget_path)
+ .reply(HTTP_STATUS_OK, { ...mockData, ...updatedMrData });
+ });
- it('should not call notifyMe if the status has not changed', async () => {
- await createComponent({ updatedMrData: { ci_status: undefined } });
- await eventHub.$emit('MRWidgetUpdateRequested');
- expect(notify.notifyMe).not.toHaveBeenCalled();
+ it('should call notifyMe', async () => {
+ await createComponent({ updatedMrData });
+ expect(notify.notifyMe).toHaveBeenCalledWith(
+ `Pipeline passed`,
+ `Pipeline passed for "${mockData.title}"`,
+ updatedMrData.gitlabLogo,
+ );
+ });
});
- it('should not notify if no pipeline provided', async () => {
- await createComponent({ updatedMrData: { pipeline: undefined } });
- expect(notify.notifyMe).not.toHaveBeenCalled();
+ describe('when pipeline has not passed', () => {
+ it('should not call notifyMe if the status has not changed', async () => {
+ await createComponent({ updatedMrData: { ci_status: undefined } });
+ await eventHub.$emit('MRWidgetUpdateRequested');
+ expect(notify.notifyMe).not.toHaveBeenCalled();
+ });
+
+ it('should not notify if no pipeline provided', async () => {
+ await createComponent({ updatedMrData: { pipeline: undefined } });
+ expect(notify.notifyMe).not.toHaveBeenCalled();
+ });
});
});
diff --git a/spec/helpers/sorting_helper_spec.rb b/spec/helpers/sorting_helper_spec.rb
index d625b46e286..f4974c8b7b2 100644
--- a/spec/helpers/sorting_helper_spec.rb
+++ b/spec/helpers/sorting_helper_spec.rb
@@ -156,6 +156,23 @@ RSpec.describe SortingHelper do
end
end
+ describe '#groups_sort_options_hash' do
+ let(:expected_options) do
+ {
+ sort_value_name => sort_title_name,
+ sort_value_name_desc => sort_title_name_desc,
+ sort_value_recently_created => sort_title_recently_created,
+ sort_value_oldest_created => sort_title_oldest_created,
+ sort_value_latest_activity => sort_title_recently_updated,
+ sort_value_oldest_activity => sort_title_oldest_updated
+ }
+ end
+
+ it 'returns a hash of available sorting options for the groups' do
+ expect(groups_sort_options_hash).to eq(expected_options)
+ end
+ end
+
describe 'with `projects` controller' do
before do
stub_controller_path 'projects'
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index 3f671fc3f70..9d3359cf633 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -921,6 +921,147 @@ RSpec.describe Group, feature_category: :groups_and_projects do
end
end
+ describe '.sort_by_attribute' do
+ before do
+ group.destroy!
+ end
+
+ let!(:group_1) { create(:group, name: 'Y group') }
+ let!(:group_2) { create(:group, name: 'J group', created_at: 2.days.ago, updated_at: 1.day.ago) }
+ let!(:group_3) { create(:group, name: 'A group') }
+ let!(:group_4) { create(:group, name: 'F group', created_at: 1.day.ago, updated_at: 1.day.ago) }
+
+ subject { described_class.with_statistics.with_route.sort_by_attribute(sort) }
+
+ context 'when sort by is not provided (id desc by default)' do
+ let(:sort) { nil }
+
+ it { is_expected.to match_array([group_1, group_2, group_3, group_4]) }
+ end
+
+ context 'when sort by name_asc' do
+ let(:sort) { 'name_asc' }
+
+ it { is_expected.to match_array([group_3, group_4, group_2, group_1]) }
+ end
+
+ context 'when sort by name_desc' do
+ let(:sort) { 'name_desc' }
+
+ it { is_expected.to match_array([group_1, group_2, group_4, group_3]) }
+ end
+
+ context 'when sort by recently_created' do
+ let(:sort) { 'created_desc' }
+
+ it { is_expected.to match_array([group_3, group_1, group_4, group_2]) }
+ end
+
+ context 'when sort by oldest_created' do
+ let(:sort) { 'created_asc' }
+
+ it { is_expected.to match_array([group_2, group_4, group_1, group_3]) }
+ end
+
+ context 'when sort by latest_activity' do
+ let(:sort) { 'latest_activity_desc' }
+
+ # this should be expected if latest_activity is based on updated_at
+ # it { is_expected.to match_array([group_3, group_1, group_4, group_2]) }
+ it { is_expected.to match_array([group_1, group_2, group_3, group_4]) }
+ end
+
+ context 'when sort by oldest_activity' do
+ let(:sort) { 'latest_activity_asc' }
+
+ # this should be expected if latest_activity is based on updated_at
+ # it { is_expected.to match_array([group_2, group_4, group_1, group_3]) }
+ it { is_expected.to match_array([group_1, group_2, group_3, group_4]) }
+ end
+
+ context 'when sort by storage_size_desc' do
+ let!(:project_1) do
+ create(:project,
+ namespace: group_1,
+ statistics: build(
+ :project_statistics,
+ namespace: group_1,
+ repository_size: 2178370,
+ storage_size: 1278370,
+ wiki_size: 505,
+ lfs_objects_size: 202,
+ build_artifacts_size: 303,
+ pipeline_artifacts_size: 707,
+ packages_size: 404,
+ snippets_size: 605,
+ uploads_size: 808
+ )
+ )
+ end
+
+ let!(:project_2) do
+ create(:project,
+ namespace: group_2,
+ statistics: build(
+ :project_statistics,
+ namespace: group_2,
+ repository_size: 3178370,
+ storage_size: 3178370,
+ wiki_size: 505,
+ lfs_objects_size: 202,
+ build_artifacts_size: 303,
+ pipeline_artifacts_size: 707,
+ packages_size: 404,
+ snippets_size: 605,
+ uploads_size: 808
+ )
+ )
+ end
+
+ let!(:project_3) do
+ create(:project,
+ namespace: group_3,
+ statistics: build(
+ :project_statistics,
+ namespace: group_3,
+ repository_size: 1278370,
+ storage_size: 1178370,
+ wiki_size: 505,
+ lfs_objects_size: 202,
+ build_artifacts_size: 303,
+ pipeline_artifacts_size: 707,
+ packages_size: 404,
+ snippets_size: 605,
+ uploads_size: 808
+ )
+ )
+ end
+
+ let!(:project_4) do
+ create(:project,
+ namespace: group_4,
+ statistics: build(
+ :project_statistics,
+ namespace: group_4,
+ repository_size: 2178370,
+ storage_size: 2278370,
+ wiki_size: 505,
+ lfs_objects_size: 202,
+ build_artifacts_size: 303,
+ pipeline_artifacts_size: 707,
+ packages_size: 404,
+ snippets_size: 605,
+ uploads_size: 808
+ )
+ )
+ end
+
+ let(:sort) { 'storage_size_desc' }
+
+ it { is_expected.to match_array([group_2, group_4, group_1, group_3]) }
+ end
+ end
+
describe 'scopes' do
let_it_be(:private_group) { create(:group, :private) }
let_it_be(:internal_group) { create(:group, :internal) }
diff --git a/spec/views/shared/groups/_dropdown.html.haml_spec.rb b/spec/views/shared/groups/_dropdown.html.haml_spec.rb
index 71fa3a30711..2c6f3b4370e 100644
--- a/spec/views/shared/groups/_dropdown.html.haml_spec.rb
+++ b/spec/views/shared/groups/_dropdown.html.haml_spec.rb
@@ -5,11 +5,37 @@ require 'spec_helper'
RSpec.describe 'shared/groups/_dropdown.html.haml' do
describe 'render' do
describe 'when a sort option is not selected' do
- it 'renders a default sort option' do
+ before do
render 'shared/groups/dropdown'
+ end
+ it 'renders a default sort option' do
expect(rendered).to have_content 'Last created'
end
+
+ it 'renders correct sort by options' do
+ html_rendered = Nokogiri::HTML(rendered)
+ sort_options = Gitlab::Json.parse(html_rendered.css('div.dropdown')[0]['data-items'])
+
+ expect(sort_options.size).to eq(6)
+ expect(sort_options[0]['value']).to eq('name_asc')
+ expect(sort_options[0]['text']).to eq(s_('SortOptions|Name'))
+
+ expect(sort_options[1]['value']).to eq('name_desc')
+ expect(sort_options[1]['text']).to eq(s_('SortOptions|Name, descending'))
+
+ expect(sort_options[2]['value']).to eq('created_desc')
+ expect(sort_options[2]['text']).to eq(s_('SortOptions|Last created'))
+
+ expect(sort_options[3]['value']).to eq('created_asc')
+ expect(sort_options[3]['text']).to eq(s_('SortOptions|Oldest created'))
+
+ expect(sort_options[4]['value']).to eq('latest_activity_desc')
+ expect(sort_options[4]['text']).to eq(_('Updated date'))
+
+ expect(sort_options[5]['value']).to eq('latest_activity_asc')
+ expect(sort_options[5]['text']).to eq(s_('SortOptions|Oldest updated'))
+ end
end
describe 'when a sort option is selected' do
diff --git a/workhorse/internal/dependencyproxy/dependencyproxy_test.go b/workhorse/internal/dependencyproxy/dependencyproxy_test.go
index bee74ce0a9e..18d08ef162c 100644
--- a/workhorse/internal/dependencyproxy/dependencyproxy_test.go
+++ b/workhorse/internal/dependencyproxy/dependencyproxy_test.go
@@ -257,20 +257,6 @@ func TestInvalidUploadConfiguration(t *testing.T) {
sendData map[string]interface{}
}{
{
- desc: "with an invalid overriden method",
- sendData: mergeMap(baseSendData, map[string]interface{}{
- "UploadConfig": map[string]string{
- "Method": "TEAPOT",
- },
- }),
- }, {
- desc: "with an invalid url",
- sendData: mergeMap(baseSendData, map[string]interface{}{
- "UploadConfig": map[string]string{
- "Url": "invalid_url",
- },
- }),
- }, {
desc: "with an invalid headers",
sendData: mergeMap(baseSendData, map[string]interface{}{
"UploadConfig": map[string]interface{}{