diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS
index 5eb96d1addd..71e4571b603 100644
--- a/.gitlab/CODEOWNERS
+++ b/.gitlab/CODEOWNERS
@@ -6,161 +6,6 @@
*.rb @gitlab-org/maintainers/rails-backend
*.rake @gitlab-org/maintainers/rails-backend
-[Documentation Directories]
-.markdownlint.yml @marcel.amirault @eread @aqualls @cnorris
-/doc/.markdownlint @marcel.amirault @eread @aqualls @cnorris
-/doc/ @gl-docsteam
-/doc/.vale/ @marcel.amirault @eread @aqualls @cnorris
-/doc/administration/geo/ @axil
-/doc/administration/gitaly/ @eread
-/doc/administration/lfs/ @aqualls
-/doc/administration/monitoring/ @ngaskill
-/doc/administration/operations/ @axil @eread @marcia
-/doc/administration/packages/ @ngaskill
-/doc/administration/pages/ @rdickenson @kpaizee
-/doc/administration/postgresql/ @marcia
-/doc/administration/raketasks/ @axil @eread
-/doc/administration/redis/ @axil
-/doc/administration/reference_architectures/ @axil
-/doc/administration/snippets/ @aqualls
-/doc/administration/troubleshooting @axil @marcia @eread
-/doc/api/graphql/ @msedlakjakubowski @kpaizee
-/doc/api/graphql/reference/ @kpaizee
-/doc/api/group_activity_analytics.md @fneill
-/doc/api/vulnerabilities.md @fneill
-/doc/ci/ @marcel.amirault @sselhorn
-/doc/ci/environments/ @rdickenson
-/doc/ci/services/ @sselhorn
-/doc/ci/test_cases/ @msedlakjakubowski
-/doc/development/ @marcia
-/doc/development/documentation/ @cnorris @dianalogan
-/doc/development/i18n/ @ngaskill
-/doc/development/value_stream_analytics.md @fneill
-/doc/gitlab-basics/ @aqualls
-/doc/install/ @axil
-/doc/operations/ @ngaskill @rdickenson
-/doc/push_rules/ @aqualls
-/doc/security/ @eread
-/doc/ssh/ @eread
-/doc/subscriptions/ @sselhorn
-/doc/topics/autodevops/ @marcia
-/doc/topics/git/ @aqualls
-/doc/update/ @axil @marcia
-/doc/user/analytics/ @fneill @ngaskill
-/doc/user/application_security/ @rdickenson
-/doc/user/application_security/container_scanning/ @ngaskill
-/doc/user/application_security/cluster_image_scanning/ @ngaskill
-/doc/user/application_security/cve_id_request.md @fneill
-/doc/user/application_security/security_dashboard @fneill
-/doc/user/application_security/vulnerabilities @fneill
-/doc/user/application_security/vulnerability_report @fneill
-/doc/user/clusters/ @marcia
-/doc/user/compliance/ @rdickenson @eread
-/doc/user/group/ @msedlakjakubowski
-/doc/user/group/devops_adoption/ @fneill
-/doc/user/group/epics/ @msedlakjakubowski
-/doc/user/group/insights/ @fneill
-/doc/user/group/iterations/ @msedlakjakubowski
-/doc/user/group/roadmap/ @msedlakjakubowski
-/doc/user/group/value_stream_analytics/ @fneill
-/doc/user/infrastructure/ @marcia
-/doc/user/packages/ @ngaskill
-/doc/user/packages/infrastructure_registry/ @marcia
-/doc/user/packages/terraform_module_registry/ @marcia
-/doc/user/profile/ @msedlakjakubowski @eread
-/doc/user/project/ @aqualls @rdickenson @eread @msedlakjakubowski @ngaskill
-/doc/user/project/clusters/ @marcia
-/doc/user/project/import/ @ngaskill @msedlakjakubowski
-/doc/user/project/issues/ @msedlakjakubowski
-/doc/user/project/merge_requests/ @aqualls @eread
-/doc/user/project/milestones/ @msedlakjakubowski
-/doc/user/project/pages/ @rdickenson
-/doc/user/project/repository/ @aqualls
-/doc/user/project/settings/ @aqualls @eread
-/doc/user/project/static_site_editor/index.md @aqualls
-/doc/user/project/web_ide/index.md @aqualls
-/doc/user/project/wiki/index.md @aqualls
-/doc/user/search/ @marcia @aqualls
-/doc/user/workspace/ @fneill
-
-[Docs Create]
-/doc/administration/file_hooks.md @aqualls
-/doc/administration/git_protocol.md @aqualls
-/doc/administration/invalidate_markdown_cache.md @aqualls
-/doc/administration/issue_closing_pattern.md @aqualls
-/doc/administration/merge_request_diffs.md @aqualls
-/doc/administration/repository_checks.md @aqualls
-/doc/administration/static_objects_external_storage.md @aqualls
-/doc/api/access_requests.md @aqualls
-/doc/api/branches.md @aqualls
-/doc/api/commits.md @aqualls
-/doc/api/discussions.md @aqualls
-/doc/api/group_wikis.md @aqualls
-/doc/api/keys.md @aqualls
-/doc/api/markdown.md @aqualls
-/doc/api/merge_request_approvals.md @aqualls
-/doc/api/merge_request_context_commits.md @aqualls
-/doc/api/merge_requests.md @aqualls
-/doc/api/project_aliases.md @aqualls
-/doc/api/project_badges.md @aqualls
-/doc/api/project_import_export.md @aqualls
-/doc/api/project_level_variables.md @aqualls
-/doc/api/project_snippets.md @aqualls
-/doc/api/project_statistics.md @aqualls
-/doc/api/project_templates.md @aqualls
-/doc/api/project_vulnerabilities.md @aqualls
-/doc/api/protected_branches.md @aqualls
-/doc/api/protected_tags.md @aqualls
-/doc/api/remote_mirrors.md @aqualls
-/doc/api/repositories.md @aqualls
-/doc/api/repository_files.md @aqualls
-/doc/api/repository_submodules.md @aqualls
-/doc/api/search.md @aqualls
-/doc/api/services.md @aqualls
-/doc/api/snippets.md @aqualls
-/doc/api/suggestions.md @aqualls
-/doc/api/tags.md @aqualls
-/doc/api/visual_review_discussions.md @aqualls
-/doc/api/wikis.md @aqualls
-/doc/intro/index.md @aqualls
-/doc/topics/gitlab_flow.md @aqualls
-/doc/user/admin_area/settings/account_and_limit_settings.md @aqualls
-/doc/user/admin_area/settings/instance_template_repository.md @aqualls
-/doc/user/admin_area/settings/project_integration_management.md @aqualls
-/doc/user/admin_area/settings/push_event_activities_limit.md @aqualls
-/doc/user/admin_area/settings/visibility_and_access_controls.md @aqualls
-/doc/user/asciidoc.md @aqualls
-/doc/user/index.md @aqualls
-/doc/user/markdown.md @aqualls
-/doc/user/project/autocomplete_characters.md @aqualls
-/doc/user/project/badges.md @aqualls
-/doc/user/project/code_intelligence.md @aqualls
-/doc/user/project/code_owners.md @aqualls
-/doc/user/project/file_lock.md @aqualls
-/doc/user/project/git_attributes.md @aqualls
-/doc/user/project/highlighting.md @aqualls
-/doc/user/project/index.md @aqualls
-/doc/user/project/protected_branches.md @aqualls
-/doc/user/project/protected_tags.md @aqualls
-/doc/user/project/push_options.md @aqualls
-/doc/user/project/settings/import_export.md @aqualls
-/doc/user/snippets.md @aqualls
-
-[Docs Ecosystem]
-/doc/administration/integration/ @kpaizee
-/doc/integration/ @kpaizee
-/doc/user/project/integrations/ @kpaizee
-/doc/user/project/integrations/prometheus_library/ @ngaskill
-
-[Docs Growth]
-/doc/administration/instance_review.md @kpaizee
-/doc/api/invitations.md @kpaizee
-/doc/api/experiments.md @kpaizee
-/doc/development/experiment_guide/ @kpaizee
-/doc/development/snowplow/ @fneill
-/doc/development/service_ping/ @fneill
-/doc/user/admin_area/license.md @kpaizee
-
[Frontend]
*.scss @annabeldunstone @gitlab-org/maintainers/frontend
*.js @gitlab-org/maintainers/frontend
@@ -357,3 +202,158 @@ ee/lib/ee/gitlab/git_access.rb @proglottis @toon @zj-gitlab
ee/lib/ee/gitlab/git_access_*.rb @proglottis @toon @zj-gitlab
ee/lib/ee/gitlab/checks/** @proglottis @toon @zj-gitlab
lib/gitlab/checks/** @proglottis @toon @zj-gitlab
+
+[Documentation Directories]
+.markdownlint.yml @marcel.amirault @eread @aqualls @cnorris
+/doc/.markdownlint @marcel.amirault @eread @aqualls @cnorris
+/doc/ @gl-docsteam
+/doc/.vale/ @marcel.amirault @eread @aqualls @cnorris
+/doc/administration/geo/ @axil
+/doc/administration/gitaly/ @eread
+/doc/administration/lfs/ @aqualls
+/doc/administration/monitoring/ @ngaskill
+/doc/administration/operations/ @axil @eread @marcia
+/doc/administration/packages/ @ngaskill
+/doc/administration/pages/ @rdickenson @kpaizee
+/doc/administration/postgresql/ @marcia
+/doc/administration/raketasks/ @axil @eread
+/doc/administration/redis/ @axil
+/doc/administration/reference_architectures/ @axil
+/doc/administration/snippets/ @aqualls
+/doc/administration/troubleshooting @axil @marcia @eread
+/doc/api/graphql/ @msedlakjakubowski @kpaizee
+/doc/api/graphql/reference/ @kpaizee
+/doc/api/group_activity_analytics.md @fneill
+/doc/api/vulnerabilities.md @fneill
+/doc/ci/ @marcel.amirault @sselhorn
+/doc/ci/environments/ @rdickenson
+/doc/ci/services/ @sselhorn
+/doc/ci/test_cases/ @msedlakjakubowski
+/doc/development/ @marcia
+/doc/development/documentation/ @cnorris @dianalogan
+/doc/development/i18n/ @ngaskill
+/doc/development/value_stream_analytics.md @fneill
+/doc/gitlab-basics/ @aqualls
+/doc/install/ @axil
+/doc/operations/ @ngaskill @rdickenson
+/doc/push_rules/ @aqualls
+/doc/security/ @eread
+/doc/ssh/ @eread
+/doc/subscriptions/ @sselhorn
+/doc/topics/autodevops/ @marcia
+/doc/topics/git/ @aqualls
+/doc/update/ @axil @marcia
+/doc/user/analytics/ @fneill @ngaskill
+/doc/user/application_security/ @rdickenson
+/doc/user/application_security/container_scanning/ @ngaskill
+/doc/user/application_security/cluster_image_scanning/ @ngaskill
+/doc/user/application_security/cve_id_request.md @fneill
+/doc/user/application_security/security_dashboard @fneill
+/doc/user/application_security/vulnerabilities @fneill
+/doc/user/application_security/vulnerability_report @fneill
+/doc/user/clusters/ @marcia
+/doc/user/compliance/ @rdickenson @eread
+/doc/user/group/ @msedlakjakubowski
+/doc/user/group/devops_adoption/ @fneill
+/doc/user/group/epics/ @msedlakjakubowski
+/doc/user/group/insights/ @fneill
+/doc/user/group/iterations/ @msedlakjakubowski
+/doc/user/group/roadmap/ @msedlakjakubowski
+/doc/user/group/value_stream_analytics/ @fneill
+/doc/user/infrastructure/ @marcia
+/doc/user/packages/ @ngaskill
+/doc/user/packages/infrastructure_registry/ @marcia
+/doc/user/packages/terraform_module_registry/ @marcia
+/doc/user/profile/ @msedlakjakubowski @eread
+/doc/user/project/ @aqualls @rdickenson @eread @msedlakjakubowski @ngaskill
+/doc/user/project/clusters/ @marcia
+/doc/user/project/import/ @ngaskill @msedlakjakubowski
+/doc/user/project/issues/ @msedlakjakubowski
+/doc/user/project/merge_requests/ @aqualls @eread
+/doc/user/project/milestones/ @msedlakjakubowski
+/doc/user/project/pages/ @rdickenson
+/doc/user/project/repository/ @aqualls
+/doc/user/project/settings/ @aqualls @eread
+/doc/user/project/static_site_editor/index.md @aqualls
+/doc/user/project/web_ide/index.md @aqualls
+/doc/user/project/wiki/index.md @aqualls
+/doc/user/search/ @marcia @aqualls
+/doc/user/workspace/ @fneill
+
+[Docs Create]
+/doc/administration/file_hooks.md @aqualls
+/doc/administration/git_protocol.md @aqualls
+/doc/administration/invalidate_markdown_cache.md @aqualls
+/doc/administration/issue_closing_pattern.md @aqualls
+/doc/administration/merge_request_diffs.md @aqualls
+/doc/administration/repository_checks.md @aqualls
+/doc/administration/static_objects_external_storage.md @aqualls
+/doc/api/access_requests.md @aqualls
+/doc/api/branches.md @aqualls
+/doc/api/commits.md @aqualls
+/doc/api/discussions.md @aqualls
+/doc/api/group_wikis.md @aqualls
+/doc/api/keys.md @aqualls
+/doc/api/markdown.md @aqualls
+/doc/api/merge_request_approvals.md @aqualls
+/doc/api/merge_request_context_commits.md @aqualls
+/doc/api/merge_requests.md @aqualls
+/doc/api/project_aliases.md @aqualls
+/doc/api/project_badges.md @aqualls
+/doc/api/project_import_export.md @aqualls
+/doc/api/project_level_variables.md @aqualls
+/doc/api/project_snippets.md @aqualls
+/doc/api/project_statistics.md @aqualls
+/doc/api/project_templates.md @aqualls
+/doc/api/project_vulnerabilities.md @aqualls
+/doc/api/protected_branches.md @aqualls
+/doc/api/protected_tags.md @aqualls
+/doc/api/remote_mirrors.md @aqualls
+/doc/api/repositories.md @aqualls
+/doc/api/repository_files.md @aqualls
+/doc/api/repository_submodules.md @aqualls
+/doc/api/search.md @aqualls
+/doc/api/services.md @aqualls
+/doc/api/snippets.md @aqualls
+/doc/api/suggestions.md @aqualls
+/doc/api/tags.md @aqualls
+/doc/api/visual_review_discussions.md @aqualls
+/doc/api/wikis.md @aqualls
+/doc/intro/index.md @aqualls
+/doc/topics/gitlab_flow.md @aqualls
+/doc/user/admin_area/settings/account_and_limit_settings.md @aqualls
+/doc/user/admin_area/settings/instance_template_repository.md @aqualls
+/doc/user/admin_area/settings/project_integration_management.md @aqualls
+/doc/user/admin_area/settings/push_event_activities_limit.md @aqualls
+/doc/user/admin_area/settings/visibility_and_access_controls.md @aqualls
+/doc/user/asciidoc.md @aqualls
+/doc/user/index.md @aqualls
+/doc/user/markdown.md @aqualls
+/doc/user/project/autocomplete_characters.md @aqualls
+/doc/user/project/badges.md @aqualls
+/doc/user/project/code_intelligence.md @aqualls
+/doc/user/project/code_owners.md @aqualls
+/doc/user/project/file_lock.md @aqualls
+/doc/user/project/git_attributes.md @aqualls
+/doc/user/project/highlighting.md @aqualls
+/doc/user/project/index.md @aqualls
+/doc/user/project/protected_branches.md @aqualls
+/doc/user/project/protected_tags.md @aqualls
+/doc/user/project/push_options.md @aqualls
+/doc/user/project/settings/import_export.md @aqualls
+/doc/user/snippets.md @aqualls
+
+[Docs Ecosystem]
+/doc/administration/integration/ @kpaizee
+/doc/integration/ @kpaizee
+/doc/user/project/integrations/ @kpaizee
+/doc/user/project/integrations/prometheus_library/ @ngaskill
+
+[Docs Growth]
+/doc/administration/instance_review.md @kpaizee
+/doc/api/invitations.md @kpaizee
+/doc/api/experiments.md @kpaizee
+/doc/development/experiment_guide/ @kpaizee
+/doc/development/snowplow/ @fneill
+/doc/development/service_ping/ @fneill
+/doc/user/admin_area/license.md @kpaizee
diff --git a/.markdownlint.yml b/.markdownlint.yml
index a2259618d8a..77da3b22fbd 100644
--- a/.markdownlint.yml
+++ b/.markdownlint.yml
@@ -26,6 +26,7 @@ proper-names:
names: [
"Akismet",
"Alertmanager",
+ "AlmaLinux",
"API",
"Asana",
"Auth0",
diff --git a/Gemfile b/Gemfile
index fad1abdd00b..aaa095dfcd7 100644
--- a/Gemfile
+++ b/Gemfile
@@ -443,7 +443,8 @@ end
gem 'octokit', '~> 4.15'
-# https://gitlab.com/gitlab-org/gitlab/issues/207207
+# Updating this gem version here is deprecated. See:
+# https://docs.gitlab.com/ee/development/emails.html#mailroom-gem-updates
gem 'gitlab-mail_room', '~> 0.0.9', require: 'mail_room'
gem 'email_reply_trimmer', '~> 0.1'
diff --git a/Gemfile.lock b/Gemfile.lock
index 896fcc165ff..45c916bbf76 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -124,14 +124,14 @@ GEM
aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.1)
aws-eventstream (~> 1, >= 1.0.2)
- azure-storage-blob (2.0.1)
+ azure-storage-blob (2.0.3)
azure-storage-common (~> 2.0)
- nokogiri (~> 1.11.0.rc2)
- azure-storage-common (2.0.2)
+ nokogiri (~> 1, >= 1.10.8)
+ azure-storage-common (2.0.4)
faraday (~> 1.0)
- faraday_middleware (~> 1.0.0.rc1)
+ faraday_middleware (~> 1.0, >= 1.0.0.rc1)
net-http-persistent (~> 4.0)
- nokogiri (~> 1.11.0.rc2)
+ nokogiri (~> 1, >= 1.10.8)
babosa (1.0.4)
backport (1.2.0)
base32 (0.3.2)
diff --git a/app/assets/javascripts/content_editor/services/track_input_rules_and_shortcuts.js b/app/assets/javascripts/content_editor/services/track_input_rules_and_shortcuts.js
index 9b1cb76f845..eb1e4885ba6 100644
--- a/app/assets/javascripts/content_editor/services/track_input_rules_and_shortcuts.js
+++ b/app/assets/javascripts/content_editor/services/track_input_rules_and_shortcuts.js
@@ -35,31 +35,33 @@ const trackInputRule = (contentType, inputRule) => {
};
const trackInputRulesAndShortcuts = (tiptapExtension) => {
- return tiptapExtension.extend({
- addKeyboardShortcuts() {
- const shortcuts = this.parent?.() || {};
- const { name } = this;
- /**
- * We don’t want to track keyboard shortcuts
- * that are not deliberately executed to create
- * new types of content
- */
- const dotNotTrackKeys = [ENTER_KEY, BACKSPACE_KEY];
- const decorated = mapValues(shortcuts, (commandFn, shortcut) =>
- dotNotTrackKeys.includes(shortcut)
- ? commandFn
- : trackKeyboardShortcut(name, commandFn, shortcut),
- );
+ return tiptapExtension
+ .extend({
+ addKeyboardShortcuts() {
+ const shortcuts = this.parent?.() || {};
+ const { name } = this;
+ /**
+ * We don’t want to track keyboard shortcuts
+ * that are not deliberately executed to create
+ * new types of content
+ */
+ const dotNotTrackKeys = [ENTER_KEY, BACKSPACE_KEY];
+ const decorated = mapValues(shortcuts, (commandFn, shortcut) =>
+ dotNotTrackKeys.includes(shortcut)
+ ? commandFn
+ : trackKeyboardShortcut(name, commandFn, shortcut),
+ );
- return decorated;
- },
- addInputRules() {
- const inputRules = this.parent?.() || [];
- const { name } = this;
+ return decorated;
+ },
+ addInputRules() {
+ const inputRules = this.parent?.() || [];
+ const { name } = this;
- return inputRules.map((inputRule) => trackInputRule(name, inputRule));
- },
- });
+ return inputRules.map((inputRule) => trackInputRule(name, inputRule));
+ },
+ })
+ .configure(tiptapExtension.options);
};
export default trackInputRulesAndShortcuts;
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/empty_state.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/empty_state.vue
deleted file mode 100644
index a16d95a6b30..00000000000
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/empty_state.vue
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue
index 2d32295b537..4fda4058711 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue
@@ -1,28 +1,38 @@
+
-
+
-import { GlResizeObserverDirective } from '@gitlab/ui';
+import { GlResizeObserverDirective, GlEmptyState } from '@gitlab/ui';
import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
@@ -9,7 +9,6 @@ import DeleteImage from '../components/delete_image.vue';
import DeleteAlert from '../components/details_page/delete_alert.vue';
import DeleteModal from '../components/details_page/delete_modal.vue';
import DetailsHeader from '../components/details_page/details_header.vue';
-import EmptyState from '../components/details_page/empty_state.vue';
import PartialCleanupAlert from '../components/details_page/partial_cleanup_alert.vue';
import StatusAlert from '../components/details_page/status_alert.vue';
import TagsList from '../components/details_page/tags_list.vue';
@@ -26,6 +25,8 @@ import {
MISSING_OR_DELETED_IMAGE_BREADCRUMB,
ROOT_IMAGE_TEXT,
GRAPHQL_PAGE_SIZE,
+ MISSING_OR_DELETED_IMAGE_TITLE,
+ MISSING_OR_DELETED_IMAGE_MESSAGE,
} from '../constants/index';
import deleteContainerRepositoryTagsMutation from '../graphql/mutations/delete_container_repository_tags.mutation.graphql';
import getContainerRepositoryDetailsQuery from '../graphql/queries/get_container_repository_details.query.graphql';
@@ -34,13 +35,13 @@ import getContainerRepositoryTagsQuery from '../graphql/queries/get_container_re
export default {
name: 'RegistryDetailsPage',
components: {
+ GlEmptyState,
DeleteAlert,
PartialCleanupAlert,
DetailsHeader,
DeleteModal,
TagsList,
TagsLoader,
- EmptyState,
StatusAlert,
DeleteImage,
},
@@ -49,6 +50,10 @@ export default {
},
mixins: [Tracking.mixin()],
inject: ['breadCrumbState', 'config'],
+ i18n: {
+ MISSING_OR_DELETED_IMAGE_TITLE,
+ MISSING_OR_DELETED_IMAGE_MESSAGE,
+ },
apollo: {
containerRepository: {
query: getContainerRepositoryDetailsQuery,
@@ -230,6 +235,12 @@ export default {
@cancel="track('cancel_delete')"
/>
-
+
diff --git a/app/assets/javascripts/packages_and_registries/shared/components/persisted_search.vue b/app/assets/javascripts/packages_and_registries/shared/components/persisted_search.vue
new file mode 100644
index 00000000000..9b2de1a1b84
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/shared/components/persisted_search.vue
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
diff --git a/app/views/projects/_merge_request_merge_commit_template.html.haml b/app/views/projects/_merge_request_merge_commit_template.html.haml
index 869d2d5d9ec..1c023ae6ceb 100644
--- a/app/views/projects/_merge_request_merge_commit_template.html.haml
+++ b/app/views/projects/_merge_request_merge_commit_template.html.haml
@@ -3,15 +3,12 @@
.form-group
%b= s_('ProjectSettings|Merge commit message template')
%p.text-secondary
- - configure_the_merge_commit_message_help_link_url = help_page_path('user/project/merge_requests/commit_templates.md')
- - configure_the_merge_commit_message_help_link_start = ''.html_safe % { url: configure_the_merge_commit_message_help_link_url }
- = s_('ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}').html_safe % { link_start: configure_the_merge_commit_message_help_link_start, link_end: ''.html_safe }
+ = s_('ProjectSettings|The commit message used when merging, if the merge method creates a merge commit.')
.mb-2
- default_merge_commit_template = "Merge branch '%{source_branch}' into '%{target_branch}'\n\n%{title}\n\n%{issues}\n\nSee merge request %{reference}"
= form.text_area :merge_commit_template, class: 'form-control gl-form-input', rows: 8, maxlength: 500, placeholder: default_merge_commit_template
%p.form-text.text-muted
= s_('ProjectSettings|Maximum 500 characters.')
- = s_('ProjectSettings|Supported variables:')
- - Gitlab::MergeRequests::CommitMessageGenerator::PLACEHOLDERS.keys.each do |placeholder|
- %code
- = "%{#{placeholder}}".html_safe
+ - configure_the_merge_commit_message_help_link_url = help_page_path('user/project/merge_requests/commit_templates.md')
+ - configure_the_merge_commit_message_help_link_start = ''.html_safe % { url: configure_the_merge_commit_message_help_link_url }
+ = s_('ProjectSettings|%{link_start}What variables can I use?%{link_end}').html_safe % { link_start: configure_the_merge_commit_message_help_link_start, link_end: ''.html_safe }
diff --git a/app/views/projects/_merge_request_merge_suggestions_settings.html.haml b/app/views/projects/_merge_request_merge_suggestions_settings.html.haml
index 6e3c366da82..9ed21593203 100644
--- a/app/views/projects/_merge_request_merge_suggestions_settings.html.haml
+++ b/app/views/projects/_merge_request_merge_suggestions_settings.html.haml
@@ -3,13 +3,10 @@
.form-group
%b= s_('ProjectSettings|Merge suggestions')
%p.text-secondary
- - configure_the_commit_message_for_applied_suggestions_help_link_url = help_page_path('user/project/merge_requests/reviews/suggestions.md', anchor: 'configure-the-commit-message-for-applied-suggestions')
- - configure_the_commit_message_for_applied_suggestions_help_link_start = ''.html_safe % { url: configure_the_commit_message_for_applied_suggestions_help_link_url }
- = s_('ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}').html_safe % { link_start: configure_the_commit_message_for_applied_suggestions_help_link_start, link_end: ''.html_safe }
+ = s_('ProjectSettings|The commit message used when applying merge request suggestions.')
.mb-2
= form.text_field :suggestion_commit_message, class: 'form-control mb-2', placeholder: Gitlab::Suggestions::CommitMessage::DEFAULT_SUGGESTION_COMMIT_MESSAGE
%p.form-text.text-muted
- = s_('ProjectSettings|Supported variables:')
- - Gitlab::Suggestions::CommitMessage::PLACEHOLDERS.keys.each do |placeholder|
- %code
- = "%{#{placeholder}}".html_safe
+ - configure_the_commit_message_for_applied_suggestions_help_link_url = help_page_path('user/project/merge_requests/reviews/suggestions.md', anchor: 'configure-the-commit-message-for-applied-suggestions')
+ - configure_the_commit_message_for_applied_suggestions_help_link_start = ''.html_safe % { url: configure_the_commit_message_for_applied_suggestions_help_link_url }
+ = s_('ProjectSettings|%{link_start}What variables can I use?%{link_end}').html_safe % { link_start: configure_the_commit_message_for_applied_suggestions_help_link_start, link_end: ''.html_safe }
diff --git a/app/views/projects/_merge_request_squash_commit_template.html.haml b/app/views/projects/_merge_request_squash_commit_template.html.haml
index 81e4bbed166..be1d78154c6 100644
--- a/app/views/projects/_merge_request_squash_commit_template.html.haml
+++ b/app/views/projects/_merge_request_squash_commit_template.html.haml
@@ -3,14 +3,11 @@
.form-group
%b= s_('ProjectSettings|Squash commit message template')
%p.text-secondary
- - configure_the_squash_commit_message_help_link_url = help_page_path('user/project/merge_requests/commit_templates.md')
- - configure_the_squash_commit_message_help_link_start = ''.html_safe % { url: configure_the_squash_commit_message_help_link_url }
- = s_('ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}').html_safe % { link_start: configure_the_squash_commit_message_help_link_start, link_end: ''.html_safe }
+ = s_('ProjectSettings|The commit message used when squashing commits.')
.mb-2
= form.text_area :squash_commit_template, class: 'form-control gl-form-input', rows: 8, maxlength: 500, placeholder: '%{title}'
%p.form-text.text-muted
= s_('ProjectSettings|Maximum 500 characters.')
- = s_('ProjectSettings|Supported variables:')
- - Gitlab::MergeRequests::CommitMessageGenerator::PLACEHOLDERS.keys.each do |placeholder|
- %code
- = "%{#{placeholder}}".html_safe
+ - configure_the_squash_commit_message_help_link_url = help_page_path('user/project/merge_requests/commit_templates.md')
+ - configure_the_squash_commit_message_help_link_start = ''.html_safe % { url: configure_the_squash_commit_message_help_link_url }
+ = s_('ProjectSettings|%{link_start}What variables can I use?%{link_end}').html_safe % { link_start: configure_the_squash_commit_message_help_link_start, link_end: ''.html_safe }
diff --git a/app/views/projects/merge_requests/invalid.html.haml b/app/views/projects/merge_requests/invalid.html.haml
index eb8de425f61..28fd0b83824 100644
--- a/app/views/projects/merge_requests/invalid.html.haml
+++ b/app/views/projects/merge_requests/invalid.html.haml
@@ -1,11 +1,8 @@
- page_title "#{@merge_request.title} (#{@merge_request.to_reference}", _("Merge requests")
-- badge_start = ''.html_safe
-- badge_end = ''.html_safe
-
- err_fork_project_removed = s_("MergeRequest|Can't show this merge request because the fork project was deleted.")
-- err_source_branch = s_("MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch.")
-- err_target_branch = s_("MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch.")
+- err_source_branch = s_("MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch.")
+- err_target_branch = s_("MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch.")
- err_internal = s_("MergeRequest|Can't show this merge request because of an internal error. Contact your administrator.")
.merge-request
@@ -20,8 +17,8 @@
- if @merge_request.for_fork? && !@merge_request.source_project
= err_fork_project_removed
- elsif !@merge_request.source_branch_exists?
- = err_source_branch.html_safe % { badge_start: badge_start, badge_end: badge_end, source_branch: @merge_request.source_branch, project_path: @merge_request.source_project_path }
+ = err_source_branch.html_safe % { branch_badge: gl_badge_tag(@merge_request.source_branch, variant: :info, size: :sm), path_badge: gl_badge_tag(@merge_request.source_project_path, variant: :info, size: :sm) }
- elsif !@merge_request.target_branch_exists?
- = err_target_branch.html_safe % { badge_start: badge_start, badge_end: badge_end, target_branch: @merge_request.target_branch, project_path: @merge_request.source_project_path }
+ = err_target_branch.html_safe % { branch_badge: gl_badge_tag(@merge_request.target_branch, variant: :info, size: :sm), path_badge: gl_badge_tag(@merge_request.source_project_path, variant: :info, size: :sm) }
- else
= err_internal
diff --git a/app/views/registrations/welcome/show.html.haml b/app/views/registrations/welcome/show.html.haml
index 47fb8f9d253..7e9fb2db5dc 100644
--- a/app/views/registrations/welcome/show.html.haml
+++ b/app/views/registrations/welcome/show.html.haml
@@ -22,7 +22,7 @@
.row
.form-group.col-sm-12
= f.label :role, _('Role'), class: 'label-bold'
- = f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, {}, class: 'form-control js-user-role-dropdown', autofocus: true
+ = f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, { include_blank: _('Select a role') }, class: 'form-control js-user-role-dropdown', autofocus: true, required: true
- if Feature.enabled?(:user_other_role_details)
.row
.form-group.col-sm-12.js-other-role-group.hidden
diff --git a/doc/.vale/gitlab/spelling-exceptions.txt b/doc/.vale/gitlab/spelling-exceptions.txt
index 5ed8dc92249..1503348fee1 100644
--- a/doc/.vale/gitlab/spelling-exceptions.txt
+++ b/doc/.vale/gitlab/spelling-exceptions.txt
@@ -9,6 +9,7 @@ allowlist
allowlisted
allowlisting
allowlists
+AlmaLinux
anonymization
anonymized
Ansible
diff --git a/doc/administration/incoming_email.md b/doc/administration/incoming_email.md
index 4727ce3f0da..84b30724dff 100644
--- a/doc/administration/incoming_email.md
+++ b/doc/administration/incoming_email.md
@@ -170,6 +170,15 @@ Reply by email should now be working.
cd /home/git/gitlab
```
+1. Install the `gitlab-mail_room` gem manually:
+
+ ```shell
+ gem install gitlab-mail_room
+ ```
+
+ NOTE: This step is necessary to avoid thread deadlocks and to support the latest MailRoom features. See
+ [this explanation](../development/emails.md#mailroom-gem-updates) for more details.
+
1. Find the `incoming_email` section in `config/gitlab.yml`, enable the feature
and fill in the details for your specific IMAP server and email account (see [examples](#configuration-examples) below).
diff --git a/doc/administration/package_information/supported_os.md b/doc/administration/package_information/supported_os.md
index fcc2fef3e63..78f496a3998 100644
--- a/doc/administration/package_information/supported_os.md
+++ b/doc/administration/package_information/supported_os.md
@@ -17,6 +17,7 @@ The following lists the currently supported OSs and their possible EOL dates.
| OS Version | First supported GitLab version | Arch | OS EOL | Details |
| ---------------- | ------------------------------ | --------------- | ------------- | ------------------------------------------------------------ |
+| AlmaLinux 8 | GitLab CE / GitLab EE 14.5.0 | x86_64, aarch64 | 2029 | |
| CentOS 7 | GitLab CE / GitLab EE 7.10.0 | x86_64 | June 2024 | |
| CentOS 8 | GitLab CE / GitLab EE 12.8.1 | x86_64, aarch64 | Dec 2021 | |
| Debian 9 | GitLab CE / GitLab EE 9.3.0 | amd64 | 2022 | |
diff --git a/doc/development/emails.md b/doc/development/emails.md
index f99b914e2de..811619bb0ff 100644
--- a/doc/development/emails.md
+++ b/doc/development/emails.md
@@ -139,6 +139,44 @@ These are the only valid legacy formats for an email handler:
In GitLab, the handler for the Service Desk feature is `path/to/project`.
+### MailRoom Gem updates
+
+We use [`gitlab-mail_room`](https://gitlab.com/gitlab-org/gitlab-mail_room), a
+fork of [`MailRoom`](https://github.com/tpitale/mail_room/), to ensure
+that we can make updates quickly to the gem if necessary. We try to upstream
+changes as soon as possible and keep the two projects in sync.
+
+Updating the `gitlab-mail_room` dependency in `Gemfile` is deprecated at
+the moment in favor of updating the version in
+[Omnibus](https://gitlab.com/gitlab-org/omnibus-gitlab/-/blob/master/config/software/mail_room.rb)
+(see [example merge request](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/5816))
+and Helm Chart configuration (see [example merge request](https://gitlab.com/gitlab-org/build/CNG/-/merge_requests/854)).
+
+#### Rationale
+
+This was done because to avoid [thread deadlocks](https://github.com/ruby/net-imap/issues/14), `MailRoom` needs
+an updated version of the `net-imap` gem. However, this [version of the net-imap cannot be installed by an unprivileged
+user](https://github.com/ruby/net-imap/issues/14) due to [an error installing the digest
+gem](https://github.com/ruby/digest/issues/14). [This bug in the Ruby interpreter](https://bugs.ruby-lang.org/issues/17761) was fixed in Ruby
+3.0.2.
+
+Updating the gem directly in the GitLab Rails `Gemfile` caused a [production incident](https://gitlab.com/gitlab-com/gl-infra/production/-/issues/4053)
+since Kubernetes pods do not run as privileged users.
+
+Note that Omnibus GitLab runs `/opt/gitlab/embedded/bin/mail_room`
+instead of `bundle exec rake` to avoid loading the older version. With a
+Kubernetes install, the MailRoom version has always been explicitly set
+in the Helm Chart configuration rather than the `Gemfile`.
+
+#### Preserving backwards compatibility
+
+Removing the `Gemfile` would break incoming e-mail processing for source
+installs. For now, source installs are advised to upgrade manually to
+the version specified in Omnibus and run `bin/mail_room` directly as
+done with Omnibus.
+
+We can reconsider this deprecation once we upgrade to Ruby 3.0.
+
---
[Return to Development documentation](index.md)
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index 037fbd7063d..6d2e34e3baa 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -15,12 +15,13 @@ as the hardware requirements that are needed to install and use GitLab.
- Ubuntu (16.04/18.04/20.04)
- Debian (9/10)
-- CentOS (7/8)
+- AlmaLinux (8)
+- CentOS (7)
- openSUSE Leap (15.2)
- SUSE Linux Enterprise Server (12 SP2/12 SP5)
-- Red Hat Enterprise Linux (please use the CentOS packages and instructions)
-- Scientific Linux (please use the CentOS packages and instructions)
-- Oracle Linux (please use the CentOS packages and instructions)
+- Red Hat Enterprise Linux (use the AlmaLinux or CentOS instructions)
+- Scientific Linux (use the CentOS instructions)
+- Oracle Linux (use the CentOS instructions)
For the installation options, see [the main installation page](index.md).
diff --git a/doc/update/plan_your_upgrade.md b/doc/update/plan_your_upgrade.md
index 82b92d89d50..665d2f6783e 100644
--- a/doc/update/plan_your_upgrade.md
+++ b/doc/update/plan_your_upgrade.md
@@ -60,6 +60,16 @@ to ensure the major components of GitLab are working:
1. If using Elasticsearch, verify that searches are successful.
+1. If you are using [Reply by Email](../administration/reply_by_email.md) or [Service Desk](../user/project/service_desk.md),
+ manually install the latest version of `gitlab-mail_room`:
+
+ ```shell
+ gem install gitlab-mail_room
+ ```
+
+ NOTE: This step is necessary to avoid thread deadlocks and to support the latest MailRoom features. See
+ [this explanation](../development/emails.md#mailroom-gem-updates) for more details.
+
If in any case something goes wrong, see [how to troubleshoot](#troubleshooting).
## Rollback plan
diff --git a/doc/user/project/integrations/discord_notifications.md b/doc/user/project/integrations/discord_notifications.md
index c8a3037aedc..7ffc9d9c50a 100644
--- a/doc/user/project/integrations/discord_notifications.md
+++ b/doc/user/project/integrations/discord_notifications.md
@@ -15,10 +15,12 @@ and configure it in GitLab.
1. Open the Discord channel you want to receive GitLab event notifications.
1. From the channel menu, select **Edit channel**.
-1. Click on **Webhooks** menu item.
-1. Click the **Create Webhook** button and fill in the name of the bot to post the messages. Optionally, edit the avatar.
-1. Note the URL from the **WEBHOOK URL** field.
-1. Click the **Save** button.
+1. Select **Integrations**.
+1. If there are no existing webhooks, select **Create Webhook**. Otherwise, select **View Webhooks** then **New Webhook**.
+1. Enter the name of the bot to post the message.
+1. Optional. Edit the avatar.
+1. Copy the URL from the **WEBHOOK URL** field.
+1. Select **Save**.
## Configure created webhook in GitLab
diff --git a/doc/user/project/integrations/slack.md b/doc/user/project/integrations/slack.md
index 87f38c3482b..870554100b7 100644
--- a/doc/user/project/integrations/slack.md
+++ b/doc/user/project/integrations/slack.md
@@ -59,20 +59,20 @@ Your Slack team now starts receiving GitLab event notifications as configured.
The following triggers are available for Slack notifications:
-| Trigger name | Trigger event |
-| ------------------------ | ------------------------------------------------------ |
-| **Push** | A push to the repository. |
-| **Issue** | An issue is created, updated, or closed. |
-| **Confidential issue** | A confidential issue is created, updated, or closed. |
-| **Merge request** | A merge request is created, updated, or merged. |
-| **Note** | A comment is added. |
-| **Confidential note** | A confidential note is added. |
-| **Tag push** | A new tag is pushed to the repository. |
-| **Pipeline** | A pipeline status changed. |
-| **Wiki page** | A wiki page is created or updated. |
-| **Deployment** | A deployment starts or finishes. |
-| **Alert** | A new, unique alert is recorded. |
-| **Vulnerability** | **(ULTIMATE)** A new, unique vulnerability is recorded. |
+| Trigger name | Trigger event |
+|--------------------------------------------------------------------------|------------------------------------------------------|
+| **Push** | A push to the repository. |
+| **Issue** | An issue is created, updated, or closed. |
+| **Confidential issue** | A confidential issue is created, updated, or closed. |
+| **Merge request** | A merge request is created, updated, or merged. |
+| **Note** | A comment is added. |
+| **Confidential note** | A confidential note is added. |
+| **Tag push** | A new tag is pushed to the repository. |
+| **Pipeline** | A pipeline status changed. |
+| **Wiki page** | A wiki page is created or updated. |
+| **Deployment** | A deployment starts or finishes. |
+| **Alert** | A new, unique alert is recorded. |
+| [**Vulnerability**](../../application_security/vulnerabilities/index.md) | A new, unique vulnerability is recorded. |
## Troubleshooting
diff --git a/doc/user/project/merge_requests/reviews/img/suggestions_custom_commit_messages_v13_1.jpg b/doc/user/project/merge_requests/reviews/img/suggestions_custom_commit_messages_v13_1.jpg
deleted file mode 100644
index a4c9df0ebb9..00000000000
Binary files a/doc/user/project/merge_requests/reviews/img/suggestions_custom_commit_messages_v13_1.jpg and /dev/null differ
diff --git a/doc/user/project/merge_requests/reviews/img/suggestions_custom_commit_messages_v14_7.png b/doc/user/project/merge_requests/reviews/img/suggestions_custom_commit_messages_v14_7.png
new file mode 100644
index 00000000000..2805ef19f2d
Binary files /dev/null and b/doc/user/project/merge_requests/reviews/img/suggestions_custom_commit_messages_v14_7.png differ
diff --git a/doc/user/project/merge_requests/reviews/suggestions.md b/doc/user/project/merge_requests/reviews/suggestions.md
index c25b9e15974..1b2a35ba139 100644
--- a/doc/user/project/merge_requests/reviews/suggestions.md
+++ b/doc/user/project/merge_requests/reviews/suggestions.md
@@ -89,7 +89,7 @@ These commit messages can be customized to follow any guidelines you might have.
To do so, expand the **Merge requests** tab within your project's **General**
settings and change the **Merge suggestions** text:
-![Custom commit message for applied suggestions](img/suggestions_custom_commit_messages_v13_1.jpg)
+![Custom commit message for applied suggestions](img/suggestions_custom_commit_messages_v14_7.png)
You can also use following variables besides static text:
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 793758a4c85..6d59d625225 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -9383,6 +9383,9 @@ msgstr ""
msgid "ContainerRegistry|Note: Any policy update will result in a change to the scheduled run date and time"
msgstr ""
+msgid "ContainerRegistry|Please try different search criteria"
+msgstr ""
+
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr ""
@@ -9472,6 +9475,9 @@ msgstr ""
msgid "ContainerRegistry|The cleanup policy timed out before it could delete all tags. An administrator can %{adminLinkStart}manually run cleanup now%{adminLinkEnd} or you can wait for the cleanup policy to automatically run again. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
+msgid "ContainerRegistry|The filter returned no results"
+msgstr ""
+
msgid "ContainerRegistry|The image repository could not be found."
msgstr ""
@@ -22341,10 +22347,10 @@ msgstr ""
msgid "MergeRequest|Can't show this merge request because the fork project was deleted."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the source branch %{badge_start}%{source_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the source branch."
+msgid "MergeRequest|Can't show this merge request because the source branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the source branch."
msgstr ""
-msgid "MergeRequest|Can't show this merge request because the target branch %{badge_start}%{target_branch}%{badge_end} is missing from project %{badge_start}%{project_path}%{badge_end}. Close this merge request or update the target branch."
+msgid "MergeRequest|Can't show this merge request because the target branch %{branch_badge} is missing from project %{path_badge}. Close this merge request or update the target branch."
msgstr ""
msgid "MergeRequest|Compare %{target} and %{source}"
@@ -27694,6 +27700,9 @@ msgstr ""
msgid "ProjectSettings|%{link_start}What are description templates?%{link_end}"
msgstr ""
+msgid "ProjectSettings|%{link_start}What variables can I use?%{link_end}"
+msgstr ""
+
msgid "ProjectSettings|Additional settings that influence how and when merges are done."
msgstr ""
@@ -27946,19 +27955,16 @@ msgstr ""
msgid "ProjectSettings|Submit changes to be merged upstream."
msgstr ""
-msgid "ProjectSettings|Supported variables:"
-msgstr ""
-
msgid "ProjectSettings|Target project"
msgstr ""
-msgid "ProjectSettings|The commit message used when applying merge request suggestions. %{link_start}Learn more about suggestions.%{link_end}"
+msgid "ProjectSettings|The commit message used when applying merge request suggestions."
msgstr ""
-msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when merging, if the merge method creates a merge commit."
msgstr ""
-msgid "ProjectSettings|The commit message used when squashing commits. %{link_start}Learn more about syntax and variables.%{link_end}"
+msgid "ProjectSettings|The commit message used when squashing commits."
msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
diff --git a/package.json b/package.json
index c3e6512091c..739735df20f 100644
--- a/package.json
+++ b/package.json
@@ -63,36 +63,36 @@
"@rails/ujs": "6.1.4-1",
"@sentry/browser": "5.30.0",
"@sourcegraph/code-host-integration": "0.0.60",
- "@tiptap/core": "^2.0.0-beta.143",
- "@tiptap/extension-blockquote": "^2.0.0-beta.25",
- "@tiptap/extension-bold": "^2.0.0-beta.24",
- "@tiptap/extension-bullet-list": "^2.0.0-beta.23",
- "@tiptap/extension-code": "^2.0.0-beta.25",
- "@tiptap/extension-code-block-lowlight": "2.0.0-beta.57",
+ "@tiptap/core": "^2.0.0-beta.160",
+ "@tiptap/extension-blockquote": "^2.0.0-beta.26",
+ "@tiptap/extension-bold": "^2.0.0-beta.25",
+ "@tiptap/extension-bullet-list": "^2.0.0-beta.26",
+ "@tiptap/extension-code": "^2.0.0-beta.26",
+ "@tiptap/extension-code-block-lowlight": "2.0.0-beta.63",
"@tiptap/extension-document": "^2.0.0-beta.15",
"@tiptap/extension-dropcursor": "^2.0.0-beta.25",
- "@tiptap/extension-gapcursor": "^2.0.0-beta.33",
+ "@tiptap/extension-gapcursor": "^2.0.0-beta.34",
"@tiptap/extension-hard-break": "^2.0.0-beta.30",
- "@tiptap/extension-heading": "^2.0.0-beta.23",
+ "@tiptap/extension-heading": "^2.0.0-beta.24",
"@tiptap/extension-history": "^2.0.0-beta.21",
"@tiptap/extension-horizontal-rule": "^2.0.0-beta.30",
"@tiptap/extension-image": "^2.0.0-beta.24",
- "@tiptap/extension-italic": "^2.0.0-beta.24",
- "@tiptap/extension-link": "^2.0.0-beta.28",
- "@tiptap/extension-list-item": "^2.0.0-beta.19",
- "@tiptap/extension-ordered-list": "^2.0.0-beta.24",
- "@tiptap/extension-paragraph": "^2.0.0-beta.22",
- "@tiptap/extension-strike": "^2.0.0-beta.26",
- "@tiptap/extension-subscript": "^2.0.0-beta.9",
- "@tiptap/extension-superscript": "^2.0.0-beta.9",
- "@tiptap/extension-table": "^2.0.0-beta.43",
+ "@tiptap/extension-italic": "^2.0.0-beta.25",
+ "@tiptap/extension-link": "^2.0.0-beta.34",
+ "@tiptap/extension-list-item": "^2.0.0-beta.20",
+ "@tiptap/extension-ordered-list": "^2.0.0-beta.27",
+ "@tiptap/extension-paragraph": "^2.0.0-beta.23",
+ "@tiptap/extension-strike": "^2.0.0-beta.27",
+ "@tiptap/extension-subscript": "^2.0.0-beta.10",
+ "@tiptap/extension-superscript": "^2.0.0-beta.10",
+ "@tiptap/extension-table": "^2.0.0-beta.46",
"@tiptap/extension-table-cell": "^2.0.0-beta.20",
"@tiptap/extension-table-header": "^2.0.0-beta.22",
"@tiptap/extension-table-row": "^2.0.0-beta.19",
- "@tiptap/extension-task-item": "^2.0.0-beta.29",
- "@tiptap/extension-task-list": "^2.0.0-beta.23",
+ "@tiptap/extension-task-item": "^2.0.0-beta.30",
+ "@tiptap/extension-task-list": "^2.0.0-beta.26",
"@tiptap/extension-text": "^2.0.0-beta.15",
- "@tiptap/vue-2": "^2.0.0-beta.69",
+ "@tiptap/vue-2": "^2.0.0-beta.74",
"@toast-ui/editor": "^2.5.2",
"@toast-ui/vue-editor": "^2.5.2",
"apollo-cache-inmemory": "^1.6.6",
@@ -162,11 +162,11 @@
"popper.js": "^1.16.1",
"portal-vue": "^2.1.7",
"prismjs": "^1.21.0",
- "prosemirror-markdown": "^1.6.0",
- "prosemirror-model": "^1.15.0",
+ "prosemirror-markdown": "1.6.0",
+ "prosemirror-model": "^1.16.1",
"prosemirror-state": "^1.3.4",
"prosemirror-tables": "^1.1.1",
- "prosemirror-view": "^1.23.3",
+ "prosemirror-view": "^1.23.5",
"raphael": "^2.2.7",
"raw-loader": "^4.0.2",
"scrollparent": "^2.0.1",
diff --git a/qa/qa/page/component/invite_members_modal.rb b/qa/qa/page/component/invite_members_modal.rb
index fecd61fb410..138224cee9e 100644
--- a/qa/qa/page/component/invite_members_modal.rb
+++ b/qa/qa/page/component/invite_members_modal.rb
@@ -68,7 +68,10 @@ module QA
fill_element :access_level_dropdown, with: group_access
click_button 'Select a group'
- fill_element :group_select_dropdown_search_field, group_name
+
+ # Helps stabilize race condition with concurrent group API calls while searching
+ # TODO: Replace with `fill_element :group_select_dropdown_search_field, group_name` when this bug is resolved: https://gitlab.com/gitlab-org/gitlab/-/issues/349379
+ send_keys_to_element(:group_select_dropdown_search_field, group_name)
Support::WaitForRequests.wait_for_requests
diff --git a/qa/qa/page/project/members.rb b/qa/qa/page/project/members.rb
index eeb589d6ca8..1102abd6646 100644
--- a/qa/qa/page/project/members.rb
+++ b/qa/qa/page/project/members.rb
@@ -41,6 +41,11 @@ module QA
click_button 'Remove group'
end
end
+
+ def has_group?(group_name)
+ click_element :groups_list_tab
+ has_element?(:group_row, text: group_name)
+ end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb
new file mode 100644
index 00000000000..fd1e8fee280
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+module QA
+ # Tagging with issue for a transient invite group modal search bug, but does not require quarantine at this time
+ RSpec.describe 'Manage', :requires_admin, :transient, issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/349379' do
+ describe 'Invite group' do
+ shared_examples 'invites group to project' do
+ it 'verifies group is added and members can access project' do
+ Page::Project::Menu.perform(&:click_members)
+ Page::Project::Members.perform do |project_members|
+ project_members.invite_group(group.path)
+
+ expect(project_members).to have_group(group.path)
+ end
+
+ Flow::Login.sign_in(as: @user)
+
+ Page::Dashboard::Projects.perform do |projects|
+ expect(projects).to have_project_with_access_role(project.name, 'Guest')
+ end
+
+ project.visit!
+
+ Page::Project::Show.perform do |project_page|
+ expect(project_page).to have_name(project.name)
+ end
+ end
+ end
+
+ before(:context) do
+ @user = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
+ end
+
+ before do
+ Runtime::Feature.enable(:invite_members_group_modal)
+ Flow::Login.sign_in
+ group.add_member(@user, Resource::Members::AccessLevel::GUEST)
+ project.visit!
+ end
+
+ context 'to personal namespace project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349223' do
+ let(:group) do
+ Resource::Group.fabricate_via_api! do |group|
+ group.path = "group-for-personal-project-#{SecureRandom.hex(8)}"
+ end
+ end
+
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'personal-namespace-project'
+ project.personal_namespace = Runtime::User.username
+ project.visibility = :private
+ project.description = 'test personal namespace project'
+ end
+ end
+
+ it_behaves_like 'invites group to project'
+ end
+
+ context 'to group project', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349340' do
+ let(:group) do
+ Resource::Group.fabricate_via_api! do |group|
+ group.path = "group-for-group-project-#{SecureRandom.hex(8)}"
+ end
+ end
+
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'group-project'
+ project.visibility = :private
+ project.description = 'test group project'
+ end
+ end
+
+ it_behaves_like 'invites group to project'
+ end
+
+ after do
+ project&.remove_via_api!
+ group&.remove_via_api!
+ Runtime::Feature.disable(:invite_members_group_modal)
+ end
+ end
+ end
+end
diff --git a/spec/frontend/content_editor/extensions/link_spec.js b/spec/frontend/content_editor/extensions/link_spec.js
index ead898554d1..bb841357d37 100644
--- a/spec/frontend/content_editor/extensions/link_spec.js
+++ b/spec/frontend/content_editor/extensions/link_spec.js
@@ -33,7 +33,7 @@ describe('content_editor/extensions/link', () => {
${'documentation](readme.md'} | ${() => p('documentation](readme.md')}
${'http://example.com '} | ${() => p(link({ href: 'http://example.com' }, 'http://example.com'))}
${'https://example.com '} | ${() => p(link({ href: 'https://example.com' }, 'https://example.com'))}
- ${'www.example.com '} | ${() => p(link({ href: 'www.example.com' }, 'www.example.com'))}
+ ${'www.example.com '} | ${() => p(link({ href: 'http://www.example.com' }, 'www.example.com'))}
${'example.com/ab.html '} | ${() => p('example.com/ab.html')}
${'https://www.google.com '} | ${() => p(link({ href: 'https://www.google.com' }, 'https://www.google.com'))}
`('with input=$input, then should insert a $insertedNode', ({ input, insertedNode }) => {
diff --git a/spec/frontend/invite_members/mock_data/api_responses.js b/spec/frontend/invite_members/mock_data/api_responses.js
index dd84b4fd78f..a3e426376d8 100644
--- a/spec/frontend/invite_members/mock_data/api_responses.js
+++ b/spec/frontend/invite_members/mock_data/api_responses.js
@@ -26,7 +26,7 @@ const INVITATIONS_API_MULTIPLE_EMAIL_RESTRICTED = {
const INVITATIONS_API_EMAIL_TAKEN = {
message: {
- 'email@example2.com': 'Invite email has already been taken',
+ 'email@example.org': 'Invite email has already been taken',
},
status: 'error',
};
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/empty_state_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/empty_state_spec.js
deleted file mode 100644
index f14284e9efe..00000000000
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/empty_state_spec.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import { GlEmptyState } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import component from '~/packages_and_registries/container_registry/explorer/components/details_page/empty_state.vue';
-import {
- NO_TAGS_TITLE,
- NO_TAGS_MESSAGE,
- MISSING_OR_DELETED_IMAGE_TITLE,
- MISSING_OR_DELETED_IMAGE_MESSAGE,
-} from '~/packages_and_registries/container_registry/explorer/constants';
-
-describe('EmptyTagsState component', () => {
- let wrapper;
-
- const findEmptyState = () => wrapper.find(GlEmptyState);
-
- const mountComponent = (propsData) => {
- wrapper = shallowMount(component, {
- stubs: {
- GlEmptyState,
- },
- propsData,
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- it('contains gl-empty-state', () => {
- mountComponent();
- expect(findEmptyState().exists()).toBe(true);
- });
-
- it.each`
- isEmptyImage | title | description
- ${false} | ${NO_TAGS_TITLE} | ${NO_TAGS_MESSAGE}
- ${true} | ${MISSING_OR_DELETED_IMAGE_TITLE} | ${MISSING_OR_DELETED_IMAGE_MESSAGE}
- `(
- 'when isEmptyImage is $isEmptyImage has the correct props',
- ({ isEmptyImage, title, description }) => {
- mountComponent({
- noContainersImage: 'foo',
- isEmptyImage,
- });
-
- expect(findEmptyState().props()).toMatchObject({
- title,
- description,
- svgPath: 'foo',
- });
- },
- );
-});
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js
index 56f12e2f0bb..0dcf988c814 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js
@@ -1,16 +1,25 @@
import { shallowMount, createLocalVue } from '@vue/test-utils';
import { nextTick } from 'vue';
+import { GlEmptyState } from '@gitlab/ui';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { stripTypenames } from 'helpers/graphql_helpers';
-import EmptyTagsState from '~/packages_and_registries/container_registry/explorer/components/details_page/empty_state.vue';
+
import component from '~/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue';
import TagsListRow from '~/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue';
import TagsLoader from '~/packages_and_registries/container_registry/explorer/components/details_page/tags_loader.vue';
import RegistryList from '~/packages_and_registries/shared/components/registry_list.vue';
+import PersistedSearch from '~/packages_and_registries/shared/components/persisted_search.vue';
import getContainerRepositoryTagsQuery from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags.query.graphql';
-import { GRAPHQL_PAGE_SIZE } from '~/packages_and_registries/container_registry/explorer/constants/index';
+import {
+ GRAPHQL_PAGE_SIZE,
+ NO_TAGS_TITLE,
+ NO_TAGS_MESSAGE,
+ NO_TAGS_MATCHING_FILTERS_TITLE,
+ NO_TAGS_MATCHING_FILTERS_DESCRIPTION,
+} from '~/packages_and_registries/container_registry/explorer/constants/index';
+import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants';
import { tagsMock, imageTagsMock, tagsPageInfo } from '../../mock_data';
const localVue = createLocalVue();
@@ -21,11 +30,20 @@ describe('Tags List', () => {
let resolver;
const tags = [...tagsMock];
+ const defaultConfig = {
+ noContainersImage: 'noContainersImage',
+ };
+
+ const findPersistedSearch = () => wrapper.findComponent(PersistedSearch);
const findTagsListRow = () => wrapper.findAllComponents(TagsListRow);
const findRegistryList = () => wrapper.findComponent(RegistryList);
- const findEmptyState = () => wrapper.findComponent(EmptyTagsState);
+ const findEmptyState = () => wrapper.findComponent(GlEmptyState);
const findTagsLoader = () => wrapper.findComponent(TagsLoader);
+ const fireFirstSortUpdate = () => {
+ findPersistedSearch().vm.$emit('update', { sort: 'NAME_ASC', filters: [] });
+ };
+
const waitForApolloRequestRender = async () => {
await waitForPromises();
await nextTick();
@@ -44,7 +62,7 @@ describe('Tags List', () => {
stubs: { RegistryList },
provide() {
return {
- config: {},
+ config: defaultConfig,
};
},
});
@@ -61,10 +79,23 @@ describe('Tags List', () => {
describe('registry list', () => {
beforeEach(() => {
mountComponent();
-
+ fireFirstSortUpdate();
return waitForApolloRequestRender();
});
+ it('has a persisted search', () => {
+ expect(findPersistedSearch().props()).toMatchObject({
+ defaultOrder: 'NAME',
+ defaultSort: 'asc',
+ sortableFields: [
+ {
+ label: 'Name',
+ orderBy: 'NAME',
+ },
+ ],
+ });
+ });
+
it('binds the correct props', () => {
expect(findRegistryList().props()).toMatchObject({
title: '2 tags',
@@ -75,11 +106,13 @@ describe('Tags List', () => {
});
describe('events', () => {
- it('prev-page fetch the previous page', () => {
+ it('prev-page fetch the previous page', async () => {
findRegistryList().vm.$emit('prev-page');
expect(resolver).toHaveBeenCalledWith({
first: null,
+ name: '',
+ sort: 'NAME_ASC',
before: tagsPageInfo.startCursor,
last: GRAPHQL_PAGE_SIZE,
id: '1',
@@ -92,6 +125,8 @@ describe('Tags List', () => {
expect(resolver).toHaveBeenCalledWith({
after: tagsPageInfo.endCursor,
first: GRAPHQL_PAGE_SIZE,
+ name: '',
+ sort: 'NAME_ASC',
id: '1',
});
});
@@ -108,6 +143,7 @@ describe('Tags List', () => {
describe('list rows', () => {
it('one row exist for each tag', async () => {
mountComponent();
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
@@ -116,6 +152,7 @@ describe('Tags List', () => {
it('the correct props are bound to it', async () => {
mountComponent({ propsData: { disabled: true, id: 1 } });
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
@@ -130,7 +167,7 @@ describe('Tags List', () => {
describe('events', () => {
it('select event update the selected items', async () => {
mountComponent();
-
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
findTagsListRow().at(0).vm.$emit('select');
@@ -142,7 +179,7 @@ describe('Tags List', () => {
it('delete event emit a delete event', async () => {
mountComponent();
-
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
findTagsListRow().at(0).vm.$emit('delete');
@@ -154,32 +191,45 @@ describe('Tags List', () => {
describe('when the list of tags is empty', () => {
beforeEach(() => {
resolver = jest.fn().mockResolvedValue(imageTagsMock([]));
+ mountComponent();
+ fireFirstSortUpdate();
+ return waitForApolloRequestRender();
});
- it('has the empty state', async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
-
- expect(findEmptyState().exists()).toBe(true);
- });
-
- it('does not show the loader', async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
-
+ it('does not show the loader', () => {
expect(findTagsLoader().exists()).toBe(false);
});
- it('does not show the list', async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
-
+ it('does not show the list', () => {
expect(findRegistryList().exists()).toBe(false);
});
+
+ describe('empty state', () => {
+ it('default empty state', () => {
+ expect(findEmptyState().props()).toMatchObject({
+ svgPath: defaultConfig.noContainersImage,
+ title: NO_TAGS_TITLE,
+ description: NO_TAGS_MESSAGE,
+ });
+ });
+
+ it('when filtered shows a filtered message', async () => {
+ findPersistedSearch().vm.$emit('update', {
+ sort: 'NAME_ASC',
+ filters: [{ type: FILTERED_SEARCH_TERM, value: { data: 'foo' } }],
+ });
+
+ await waitForApolloRequestRender();
+
+ expect(findEmptyState().props()).toMatchObject({
+ svgPath: defaultConfig.noContainersImage,
+ title: NO_TAGS_MATCHING_FILTERS_TITLE,
+ description: NO_TAGS_MATCHING_FILTERS_DESCRIPTION,
+ });
+ });
+ });
});
+
describe('loading state', () => {
it.each`
isImageLoading | queryExecuting | loadingVisible
@@ -191,7 +241,7 @@ describe('Tags List', () => {
'when the isImageLoading is $isImageLoading, and is $queryExecuting that the query is still executing is $loadingVisible that the loader is shown',
async ({ isImageLoading, queryExecuting, loadingVisible }) => {
mountComponent({ propsData: { isImageLoading, isMobile: false, id: 1 } });
-
+ fireFirstSortUpdate();
if (!queryExecuting) {
await waitForApolloRequestRender();
}
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js
index 9b821ba8ef3..7992bead60a 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js
@@ -1,4 +1,4 @@
-import { GlKeysetPagination } from '@gitlab/ui';
+import { GlKeysetPagination, GlEmptyState } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import { nextTick } from 'vue';
@@ -8,7 +8,6 @@ import axios from '~/lib/utils/axios_utils';
import DeleteImage from '~/packages_and_registries/container_registry/explorer/components/delete_image.vue';
import DeleteAlert from '~/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue';
import DetailsHeader from '~/packages_and_registries/container_registry/explorer/components/details_page/details_header.vue';
-import EmptyTagsState from '~/packages_and_registries/container_registry/explorer/components/details_page/empty_state.vue';
import PartialCleanupAlert from '~/packages_and_registries/container_registry/explorer/components/details_page/partial_cleanup_alert.vue';
import StatusAlert from '~/packages_and_registries/container_registry/explorer/components/details_page/status_alert.vue';
import TagsList from '~/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue';
@@ -20,6 +19,8 @@ import {
ALERT_DANGER_IMAGE,
MISSING_OR_DELETED_IMAGE_BREADCRUMB,
ROOT_IMAGE_TEXT,
+ MISSING_OR_DELETED_IMAGE_TITLE,
+ MISSING_OR_DELETED_IMAGE_MESSAGE,
} from '~/packages_and_registries/container_registry/explorer/constants';
import deleteContainerRepositoryTagsMutation from '~/packages_and_registries/container_registry/explorer/graphql/mutations/delete_container_repository_tags.mutation.graphql';
import getContainerRepositoryDetailsQuery from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_details.query.graphql';
@@ -50,7 +51,7 @@ describe('Details Page', () => {
const findTagsList = () => wrapper.find(TagsList);
const findDeleteAlert = () => wrapper.find(DeleteAlert);
const findDetailsHeader = () => wrapper.find(DetailsHeader);
- const findEmptyState = () => wrapper.find(EmptyTagsState);
+ const findEmptyState = () => wrapper.find(GlEmptyState);
const findPartialCleanupAlert = () => wrapper.find(PartialCleanupAlert);
const findStatusAlert = () => wrapper.find(StatusAlert);
const findDeleteImage = () => wrapper.find(DeleteImage);
@@ -61,6 +62,10 @@ describe('Details Page', () => {
updateName: jest.fn(),
};
+ const defaultConfig = {
+ noContainersImage: 'noContainersImage',
+ };
+
const cleanTags = tagsMock.map((t) => {
const result = { ...t };
// eslint-disable-next-line no-underscore-dangle
@@ -78,7 +83,7 @@ describe('Details Page', () => {
mutationResolver = jest.fn().mockResolvedValue(graphQLDeleteImageRepositoryTagsMock),
tagsResolver = jest.fn().mockResolvedValue(graphQLImageDetailsMock(imageTagsMock)),
options,
- config = {},
+ config = defaultConfig,
} = {}) => {
localVue.use(VueApollo);
@@ -154,7 +159,11 @@ describe('Details Page', () => {
await waitForApolloRequestRender();
- expect(findEmptyState().exists()).toBe(true);
+ expect(findEmptyState().props()).toMatchObject({
+ description: MISSING_OR_DELETED_IMAGE_MESSAGE,
+ svgPath: defaultConfig.noContainersImage,
+ title: MISSING_OR_DELETED_IMAGE_TITLE,
+ });
});
});
diff --git a/spec/frontend/packages_and_registries/shared/components/persisted_search_spec.js b/spec/frontend/packages_and_registries/shared/components/persisted_search_spec.js
new file mode 100644
index 00000000000..bd492a5ae8f
--- /dev/null
+++ b/spec/frontend/packages_and_registries/shared/components/persisted_search_spec.js
@@ -0,0 +1,145 @@
+import { nextTick } from 'vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
+import component from '~/packages_and_registries/shared/components/persisted_search.vue';
+import UrlSync from '~/vue_shared/components/url_sync.vue';
+import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
+import { getQueryParams, extractFilterAndSorting } from '~/packages_and_registries/shared/utils';
+
+jest.mock('~/packages_and_registries/shared/utils');
+
+useMockLocationHelper();
+
+describe('Persisted Search', () => {
+ let wrapper;
+
+ const defaultQueryParamsMock = {
+ filters: ['foo'],
+ sorting: { sort: 'desc', orderBy: 'test' },
+ };
+
+ const defaultProps = {
+ sortableFields: [
+ { orderBy: 'test', label: 'test' },
+ { orderBy: 'foo', label: 'foo' },
+ ],
+ defaultOrder: 'test',
+ defaultSort: 'asc',
+ };
+
+ const findRegistrySearch = () => wrapper.findComponent(RegistrySearch);
+ const findUrlSync = () => wrapper.findComponent(UrlSync);
+
+ const mountComponent = (propsData = defaultProps) => {
+ wrapper = shallowMountExtended(component, {
+ propsData,
+ stubs: {
+ UrlSync,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ extractFilterAndSorting.mockReturnValue(defaultQueryParamsMock);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('has a registry search component', async () => {
+ mountComponent();
+
+ await nextTick();
+
+ expect(findRegistrySearch().exists()).toBe(true);
+ });
+
+ it('registry search is mounted after mount', async () => {
+ mountComponent();
+
+ expect(findRegistrySearch().exists()).toBe(false);
+ });
+
+ it('has a UrlSync component', () => {
+ mountComponent();
+
+ expect(findUrlSync().exists()).toBe(true);
+ });
+
+ it('on sorting:changed emits update event and update internal sort', async () => {
+ const payload = { sort: 'desc', orderBy: 'test' };
+
+ mountComponent();
+
+ await nextTick();
+
+ findRegistrySearch().vm.$emit('sorting:changed', payload);
+
+ await nextTick();
+
+ expect(findRegistrySearch().props('sorting')).toMatchObject(payload);
+
+ // there is always a first call on mounted that emits up default values
+ expect(wrapper.emitted('update')[1]).toEqual([
+ {
+ filters: ['foo'],
+ sort: 'TEST_DESC',
+ },
+ ]);
+ });
+
+ it('on filter:changed updates the filters', async () => {
+ const payload = ['foo'];
+
+ mountComponent();
+
+ await nextTick();
+
+ findRegistrySearch().vm.$emit('filter:changed', payload);
+
+ await nextTick();
+
+ expect(findRegistrySearch().props('filter')).toEqual(['foo']);
+ });
+
+ it('on filter:submit emits update event', async () => {
+ mountComponent();
+
+ await nextTick();
+
+ findRegistrySearch().vm.$emit('filter:submit');
+
+ expect(wrapper.emitted('update')[1]).toEqual([
+ {
+ filters: ['foo'],
+ sort: 'TEST_DESC',
+ },
+ ]);
+ });
+
+ it('on query:changed calls updateQuery from UrlSync', async () => {
+ jest.spyOn(UrlSync.methods, 'updateQuery').mockImplementation(() => {});
+
+ mountComponent();
+
+ await nextTick();
+
+ findRegistrySearch().vm.$emit('query:changed');
+
+ expect(UrlSync.methods.updateQuery).toHaveBeenCalled();
+ });
+
+ it('sets the component sorting and filtering based on the querystring', async () => {
+ mountComponent();
+
+ await nextTick();
+
+ expect(getQueryParams).toHaveBeenCalled();
+
+ expect(findRegistrySearch().props()).toMatchObject({
+ filter: defaultQueryParamsMock.filters,
+ sorting: defaultQueryParamsMock.sorting,
+ });
+ });
+});
diff --git a/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_identifier_paragraph_spec.js b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_identifier_paragraph_spec.js
index 6a2b89a8dcf..ddc96ed6832 100644
--- a/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_identifier_paragraph_spec.js
+++ b/spec/frontend/static_site_editor/rich_content_editor/services/renderers/render_identifier_paragraph_spec.js
@@ -13,7 +13,7 @@ const normalParagraphNode = buildMockParagraphNode(
'This is just normal paragraph. It has multiple sentences.',
);
const identifierParagraphNode = buildMockParagraphNode(
- `[another-identifier]: https://example.com "This example has a title" [identifier]: http://example1.com [this link]: http://example2.com`,
+ `[another-identifier]: https://example.com "This example has a title" [identifier]: http://example1.com [this link]: http://example.org`,
);
describe('rich_content_editor/renderers_render_identifier_paragraph', () => {
diff --git a/spec/models/concerns/triggerable_hooks_spec.rb b/spec/models/concerns/triggerable_hooks_spec.rb
index 10a6c1aa821..90c88c888ff 100644
--- a/spec/models/concerns/triggerable_hooks_spec.rb
+++ b/spec/models/concerns/triggerable_hooks_spec.rb
@@ -46,7 +46,7 @@ RSpec.describe TriggerableHooks do
describe '.select_active' do
it 'returns hooks that match the active filter' do
TestableHook.create!(url: 'http://example1.com', push_events: true)
- TestableHook.create!(url: 'http://example2.com', push_events: true)
+ TestableHook.create!(url: 'http://example.org', push_events: true)
filter1 = double(:filter1)
filter2 = double(:filter2)
allow(ActiveHookFilter).to receive(:new).twice.and_return(filter1, filter2)
diff --git a/spec/models/integration_spec.rb b/spec/models/integration_spec.rb
index de47fb3839a..50975674472 100644
--- a/spec/models/integration_spec.rb
+++ b/spec/models/integration_spec.rb
@@ -683,7 +683,7 @@ RSpec.describe Integration do
it "returns initial value when the property has been assigned multiple values" do
service.bamboo_url = "http://example.com"
- service.bamboo_url = "http://example2.com"
+ service.bamboo_url = "http://example.org"
expect(service.bamboo_url_was).to eq('http://gitlab.com')
end
diff --git a/spec/support/shared_examples/models/application_setting_shared_examples.rb b/spec/support/shared_examples/models/application_setting_shared_examples.rb
index 60a02d85a1e..38f5c7be393 100644
--- a/spec/support/shared_examples/models/application_setting_shared_examples.rb
+++ b/spec/support/shared_examples/models/application_setting_shared_examples.rb
@@ -94,7 +94,7 @@ RSpec.shared_examples 'application settings examples' do
'1:2:3:4:5::7:8',
'[1:2:3:4:5::7:8]',
'[2001:db8:85a3:8d3:1319:8a2e:370:7348]:443',
- 'www.example2.com:8080',
+ 'www.example.org:8080',
'example.com:8080'
]
@@ -114,7 +114,7 @@ RSpec.shared_examples 'application settings examples' do
an_object_having_attributes(domain: 'example.com'),
an_object_having_attributes(domain: 'subdomain.example.com'),
an_object_having_attributes(domain: 'www.example.com'),
- an_object_having_attributes(domain: 'www.example2.com', port: 8080),
+ an_object_having_attributes(domain: 'www.example.org', port: 8080),
an_object_having_attributes(domain: 'example.com', port: 8080)
]
diff --git a/spec/views/projects/edit.html.haml_spec.rb b/spec/views/projects/edit.html.haml_spec.rb
index ee1bb0e9541..11f542767f4 100644
--- a/spec/views/projects/edit.html.haml_spec.rb
+++ b/spec/views/projects/edit.html.haml_spec.rb
@@ -29,19 +29,6 @@ RSpec.describe 'projects/edit' do
end
context 'merge suggestions settings' do
- it 'displays all possible variables' do
- render
-
- expect(rendered).to have_content('%{branch_name}')
- expect(rendered).to have_content('%{files_count}')
- expect(rendered).to have_content('%{file_paths}')
- expect(rendered).to have_content('%{project_name}')
- expect(rendered).to have_content('%{project_path}')
- expect(rendered).to have_content('%{user_full_name}')
- expect(rendered).to have_content('%{username}')
- expect(rendered).to have_content('%{suggestions_count}')
- end
-
it 'displays a placeholder if none is set' do
render
@@ -58,20 +45,6 @@ RSpec.describe 'projects/edit' do
end
context 'merge commit template' do
- it 'displays all possible variables' do
- render
-
- expect(rendered).to have_content('%{source_branch}')
- expect(rendered).to have_content('%{target_branch}')
- expect(rendered).to have_content('%{title}')
- expect(rendered).to have_content('%{issues}')
- expect(rendered).to have_content('%{description}')
- expect(rendered).to have_content('%{reference}')
- expect(rendered).to have_content('%{approved_by}')
- expect(rendered).to have_content('%{url}')
- expect(rendered).to have_content('%{merged_by}')
- end
-
it 'displays a placeholder if none is set' do
render
diff --git a/yarn.lock b/yarn.lock
index c7ecc390d1b..15f7f745d9b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1492,73 +1492,73 @@
dom-accessibility-api "^0.5.1"
pretty-format "^26.4.2"
-"@tiptap/core@^2.0.0-beta.143":
- version "2.0.0-beta.143"
- resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.143.tgz#e1eb470351867eb13a8f2169958f2231138a6dc1"
- integrity sha512-3AoKMZmuc+Lh/ZsM7dj+mSQvRMFANgLVAT0Fza9DaEMREnbpS6nDZlpcbb0HnoExbd7ZLobuwDGxEIZG5uo3Lw==
+"@tiptap/core@^2.0.0-beta.160":
+ version "2.0.0-beta.160"
+ resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.160.tgz#98f0625dc12a3498c6bbe2ae4aed4667b62a2a11"
+ integrity sha512-oKtx4vn4ew+mCH3kiBeD4UdPa5IVLLBCuSgGNnqdoIuRv397uh5SwOz7TiL5A+vTa6yke0xLSKxZ+QNR2qfVXg==
dependencies:
"@types/prosemirror-commands" "^1.0.4"
"@types/prosemirror-keymap" "^1.0.4"
"@types/prosemirror-model" "^1.13.2"
"@types/prosemirror-schema-list" "^1.0.3"
"@types/prosemirror-state" "^1.2.8"
- "@types/prosemirror-transform" "^1.1.4"
- "@types/prosemirror-view" "^1.19.1"
+ "@types/prosemirror-transform" "^1.1.5"
+ "@types/prosemirror-view" "^1.19.2"
prosemirror-commands "^1.1.12"
prosemirror-keymap "^1.1.5"
- prosemirror-model "^1.15.0"
+ prosemirror-model "^1.16.1"
prosemirror-schema-list "^1.1.6"
prosemirror-state "^1.3.4"
prosemirror-transform "^1.3.3"
- prosemirror-view "^1.23.1"
+ prosemirror-view "^1.23.5"
-"@tiptap/extension-blockquote@^2.0.0-beta.25":
+"@tiptap/extension-blockquote@^2.0.0-beta.26":
+ version "2.0.0-beta.26"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.0.0-beta.26.tgz#e5ae4b7bd9376db37407a23e22080c7b11287f3b"
+ integrity sha512-A6yjcYovONJfOjQFk6vDYXswaCdCtCwjL7w9VTB0R2DLTuJvvRt9DWN0IDcMrj5G+aMgDq4GUUTitv+2Y8krDg==
+
+"@tiptap/extension-bold@^2.0.0-beta.25":
version "2.0.0-beta.25"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.0.0-beta.25.tgz#f133381163b92b34d9dc6e0d78a52cf56098eb40"
- integrity sha512-994bQQhyOmPGCNTnzHY5UwZceBh42Xcr6MEB3XnnYk5kgfNnOlrnHHt3l8mJeSnC78Bs1cRSs1BKmDF8WufauQ==
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.0.0-beta.25.tgz#ec19e7c862d25bae49609c5d6a873f372c506dee"
+ integrity sha512-ZNdgFYDxKo8lAp0Pqzu45I0JH3ah8/X5TCYg9zNg3QwLUFT16g2LlWDMUDGT5pH9aXxgtFaEdoVacu0EyhlPnQ==
-"@tiptap/extension-bold@^2.0.0-beta.24":
- version "2.0.0-beta.24"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.0.0-beta.24.tgz#a8d1076922580db528cc6988fde08f731dcfe733"
- integrity sha512-2VTCtY2JI0wpDwWT0a2fMFkjbgxDpwD3wvtY3/ndh5pyNX0JQCXtJarFzfZZurWvLNQ8QPRRel73182RBYUOHQ==
-
-"@tiptap/extension-bubble-menu@^2.0.0-beta.50":
- version "2.0.0-beta.50"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.0-beta.50.tgz#96c09e71d84473c018fa63dc072fa3732c2b3e88"
- integrity sha512-UYnIaUTbI1K759z3A44dahp/NyHKjSaRvIptMnAv7q312l5n+czGwBcjZo41YUxjLPhnwGk1Siny1V+b5+4yBA==
+"@tiptap/extension-bubble-menu@^2.0.0-beta.54":
+ version "2.0.0-beta.54"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.0.0-beta.54.tgz#90ac838cb7899317207037abb74ed2f68528bd22"
+ integrity sha512-jSvNy+ZVHIzEvf8BY/pLpir7CB4lWL4RNUWLT6YMmGCzdzYJK3RZ6Qp0Yoo7UMTjA5JDGn3Ax1lDj4qcsoXwzA==
dependencies:
prosemirror-state "^1.3.4"
- prosemirror-view "^1.23.1"
+ prosemirror-view "^1.23.5"
tippy.js "^6.3.7"
-"@tiptap/extension-bullet-list@^2.0.0-beta.23":
- version "2.0.0-beta.23"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.0-beta.23.tgz#64698c98039ad301c94a9041bbd117e82957be21"
- integrity sha512-ReoUiz9f1IX87RX+GRE+fCaLEzNNwmiP4kli3QH8/qrLK3qxvZYr9N31fUeOHecCctUofPSbQB79B39zSo9Ouw==
+"@tiptap/extension-bullet-list@^2.0.0-beta.26":
+ version "2.0.0-beta.26"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.0.0-beta.26.tgz#b42126d2d984c04041b14037e8d3ec1bcf16e7ec"
+ integrity sha512-1n5HV8gY1tLjPk4x48nva6SZlFHoPlRfF6pqSu9JcJxPO7FUSPxUokuz4swYNe0LRrtykfyNz44dUcxKVhoFow==
-"@tiptap/extension-code-block-lowlight@2.0.0-beta.57":
- version "2.0.0-beta.57"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.0.0-beta.57.tgz#afaa3a59da8d688f4f402d31ad6e5bea6ff87390"
- integrity sha512-HbUkhJkTiDusLX+qqaJsqCiTKpWR6LPWScKP/Sk7744EnjMmyiqbmNwyqSx538Z8GIS89TKj1vERLUAAAOGCIQ==
+"@tiptap/extension-code-block-lowlight@2.0.0-beta.63":
+ version "2.0.0-beta.63"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.0.0-beta.63.tgz#5d99e7693c2181d15f6599b4a20aa386efdc9c00"
+ integrity sha512-Eam+j5YO7ulytOL+NMIhoEPZsAQag9hL19q17ctgl1k1yPwdLuUtU0lkIr0P+qxSzWXUGWX6q/nXM92Vb4hVPA==
dependencies:
- "@tiptap/extension-code-block" "^2.0.0-beta.29"
+ "@tiptap/extension-code-block" "^2.0.0-beta.33"
"@types/lowlight" "^0.0.3"
lowlight "^1.20.0"
- prosemirror-model "^1.15.0"
+ prosemirror-model "^1.16.1"
prosemirror-state "^1.3.4"
- prosemirror-view "^1.23.1"
+ prosemirror-view "^1.23.5"
-"@tiptap/extension-code-block@^2.0.0-beta.29":
- version "2.0.0-beta.29"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.0.0-beta.29.tgz#ad7f537bc1f12decf027d66c7328f36a8b07795c"
- integrity sha512-IoBJxqZ4F7dApRL3NisvMCBJmzpV0LmfJlFQacgm64Li15dP/QyDuvXpku03gT3y9e4f9Gv/KTKwJizXEVABhw==
+"@tiptap/extension-code-block@^2.0.0-beta.33":
+ version "2.0.0-beta.33"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.0.0-beta.33.tgz#963b06ec88f97f79e1c90b3b830eff826a4bad88"
+ integrity sha512-zKiGxbbnZJrKXr0DtBd0B7yXvY3wRk5Y5BsJqe0ZsyXR8lCEY4+DcOPpr6dja2gpgQIB9+vtqZvgBfnnUXXTcw==
dependencies:
prosemirror-state "^1.3.4"
-"@tiptap/extension-code@^2.0.0-beta.25":
- version "2.0.0-beta.25"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.0.0-beta.25.tgz#055dc8dc6d19d3f0439f57dd8ba6433e2f2fd733"
- integrity sha512-kXBR4Zp79lpUEfqJtBGv9tO1mj9jFQLMj0iVhj8e8ZporNKei5JfDOY83kwFcKAE60i7tiRDtV3OizpAKMeqDg==
+"@tiptap/extension-code@^2.0.0-beta.26":
+ version "2.0.0-beta.26"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.0.0-beta.26.tgz#bbfa600a252ee2cded6947b56b6c4c33d998e53a"
+ integrity sha512-QcFWdEFfbJ1n5UFFBD17QPPAJ3J5p/b7XV484u0shCzywO7aNPV32QeHy1z0eMoyZtCbOWf6hg/a7Ugv8IwpHw==
"@tiptap/extension-document@^2.0.0-beta.15":
version "2.0.0-beta.15"
@@ -1573,32 +1573,32 @@
"@types/prosemirror-dropcursor" "^1.0.3"
prosemirror-dropcursor "^1.4.0"
-"@tiptap/extension-floating-menu@^2.0.0-beta.45":
- version "2.0.0-beta.45"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.0-beta.45.tgz#0ccba4bc376171ff4cb0ad9b6e032bfa69488010"
- integrity sha512-UjAXhdrcVInCydCoRq+9IOEHQC2lR6BSNACFiTzgzObY7aFaNmMus/9MZ/WZKSN3Rw8Mk4lr8PXFP/3zuNqbYA==
+"@tiptap/extension-floating-menu@^2.0.0-beta.49":
+ version "2.0.0-beta.49"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.0.0-beta.49.tgz#36682849f50e217137775d7f738af952a0434113"
+ integrity sha512-VY0d+fJmz8FP1CxqB9u09xCZe/9Wtwff+SxY+LGpflVf0JjS+CWcaVIDNF8zHG13SMobQ5xH6RRnSuTzlS2bRA==
dependencies:
prosemirror-state "^1.3.4"
- prosemirror-view "^1.23.1"
+ prosemirror-view "^1.23.5"
tippy.js "^6.3.7"
-"@tiptap/extension-gapcursor@^2.0.0-beta.33":
- version "2.0.0-beta.33"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.0-beta.33.tgz#99414204e61655d4df61efc27823732176719532"
- integrity sha512-Yu6BJ1bseyXIgLlcw/2R/2wWe1mIQilMwW7hhfDJPLbFwLJrMINtA9hxd2qY7mtW19/CveT5HOihQS6QEk59iw==
+"@tiptap/extension-gapcursor@^2.0.0-beta.34":
+ version "2.0.0-beta.34"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.0.0-beta.34.tgz#0e4971affb1621934422dd5fc4bf2dd7a84f70f7"
+ integrity sha512-Vm8vMWWQ2kJcUOLfB5CEo5pYgyudI7JeeiZvX9ScPmUmgKVYhEpt3EAICY9pUYJ41aAVH35gZLXkUtsz2f9GHw==
dependencies:
"@types/prosemirror-gapcursor" "^1.0.4"
- prosemirror-gapcursor "^1.2.0"
+ prosemirror-gapcursor "^1.2.1"
"@tiptap/extension-hard-break@^2.0.0-beta.30":
version "2.0.0-beta.30"
resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.0.0-beta.30.tgz#165494f1194a7bad08907e6d64d349dd15851b72"
integrity sha512-X9xj/S+CikrbIE7ccUFVwit5QHEbflnKVxod+4zPwr1cxogFbE9AyLZE2MpYdx3z9LcnTYYi9leBqFrP4T/Olw==
-"@tiptap/extension-heading@^2.0.0-beta.23":
- version "2.0.0-beta.23"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.0.0-beta.23.tgz#8aafadc58a8d536b7f7885e4ff0f64d30908a868"
- integrity sha512-/WLymJjY+MMvee79rWHSKDBGVRw4dbBUMrFLqKLjQQBS1xS8+UW2TYzRrAH6HAH4Tc6WO39ZDbd9K9kc9wqPnA==
+"@tiptap/extension-heading@^2.0.0-beta.24":
+ version "2.0.0-beta.24"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.0.0-beta.24.tgz#52ba163c8d16985739387682d5e5b28ddf242661"
+ integrity sha512-5a3vgdO7Cf2+z7sulCGs/1j23gBcKiZe3pA1FrC5h6blwLu86hA1xnMAVBVNilP9b6c9f3lN9yxMzEWsp6ZEkA==
"@tiptap/extension-history@^2.0.0-beta.21":
version "2.0.0-beta.21"
@@ -1620,48 +1620,49 @@
resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.0.0-beta.24.tgz#1010676f79925cbe11a44b6d8eee1251910fbc1d"
integrity sha512-7oiX/Ovj9WN4xTBqWbQWd4H3SUO2eNzOiKHebVo3eqWG8NxzOGfuU0iRCENtEa7vTiRrFgyeBotneMALDpDnTQ==
-"@tiptap/extension-italic@^2.0.0-beta.24":
- version "2.0.0-beta.24"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.0.0-beta.24.tgz#0a08d06dbd8dbf10f18ed17f019aa42d7ac9dbe0"
- integrity sha512-pMAWFaLFb0Z0SC5pjoTKzC6m4CQOdUYeVlHvTS/550Z9lf8cqMawQ8H6Yk6brIuANyh7iUi4/zpq4H4rAdUCuw==
+"@tiptap/extension-italic@^2.0.0-beta.25":
+ version "2.0.0-beta.25"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.0.0-beta.25.tgz#c2ec95cc5baf855134883c5e261da4ab0d3b9479"
+ integrity sha512-7PvhioTX9baVp5+AmmZU0qna+dFPZCRlSEN/GciH57N77d2uhJ/ZW5iQWTbvy5HBNddQB4Jts1UDIaC7WASrGA==
-"@tiptap/extension-link@^2.0.0-beta.28":
- version "2.0.0-beta.28"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.0.0-beta.28.tgz#4385f36b6bb31fab34a86fb7c686ca05a37ed572"
- integrity sha512-dZNaEjoDhgjmts44KqgtOYObCdDYZq/yFhsZ8QfqEgNHJMvBNTDaPXwBDW9i3BTkkyLTmwR/qwWxqDrfDdKh2A==
+"@tiptap/extension-link@^2.0.0-beta.34":
+ version "2.0.0-beta.34"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.0.0-beta.34.tgz#9f07b9db6a3b62192b0162afdab5480fcd93e731"
+ integrity sha512-v9qqPWyKfJ9BbV2eWR4a+za1cepZywV/2Rng+1gTivzLpfBgy6Q50vgUyMe7KTZpNZw5MuZO4sBwlvangmj6Vg==
dependencies:
- linkifyjs "^3.0.3"
+ linkifyjs "^3.0.5"
+ prosemirror-model "^1.16.1"
prosemirror-state "^1.3.4"
-"@tiptap/extension-list-item@^2.0.0-beta.19":
- version "2.0.0-beta.19"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.0.0-beta.19.tgz#657f2c5624a30f3effff723f4fadb0851a61dab8"
- integrity sha512-z/5NrRKwwJc2ZkgoGxRQmA/VENxQugZoxKhUu2qoUdg5cJRcW+ERoKTiY1/AR+4M2k1izNWQMIz3nQNWMx1kQA==
+"@tiptap/extension-list-item@^2.0.0-beta.20":
+ version "2.0.0-beta.20"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.0.0-beta.20.tgz#7169528b226dee4590e013bdf6e5fc6d83729b0f"
+ integrity sha512-5IPEspJt38t9ROj4xLUesOVEYlTT/R9Skd9meHRxJQZX1qrzBICs5PC/WRIsnexrvTBhdxpYgCYjpvpsJBlKuQ==
-"@tiptap/extension-ordered-list@^2.0.0-beta.24":
- version "2.0.0-beta.24"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.0-beta.24.tgz#69c56e2cfbf582b338d5dbc94c5eda4593775cb5"
- integrity sha512-pXgwV+vuBAHMBGnUPa8fjxHapGCitfBJ1k8o3XvhotO7243Y7KOfYT7kg6XrY6dmTwCX2WLkIc912PP/E60y3A==
+"@tiptap/extension-ordered-list@^2.0.0-beta.27":
+ version "2.0.0-beta.27"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.0.0-beta.27.tgz#ed48a53a9b012d578613b68375db31e8664bfdc9"
+ integrity sha512-apFDeignxdZb3cA3p1HJu0zw1JgJdBYUBz1r7f99qdNybYuk3I/1MPUvlOuOgvIrBB/wydoyVDP+v9F7QN3tfQ==
-"@tiptap/extension-paragraph@^2.0.0-beta.22":
- version "2.0.0-beta.22"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.0.0-beta.22.tgz#7740fb6393296ec58e98332b2855ebdc3fd05226"
- integrity sha512-BY6GWHlMvGiXLgPHcfZRUHKzMi1jKw3i1JrpMEQ8JLwYD3koI/6UOB/qphwUJkCkIPQXNkZw4/aSBxL9uChRDg==
+"@tiptap/extension-paragraph@^2.0.0-beta.23":
+ version "2.0.0-beta.23"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.0.0-beta.23.tgz#2ab77308519494994d7a9e5a4acd14042f45f28c"
+ integrity sha512-VWAxyzecErYWk97Kv/Gkghh97zAQTcaVOisEnYYArZAlyYDaYM48qVssAC/vnRRynP2eQxb1EkppbAxE+bMHAA==
-"@tiptap/extension-strike@^2.0.0-beta.26":
- version "2.0.0-beta.26"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.0.0-beta.26.tgz#19eda1a61706ac9690ecbc794c711deb4e1efc3e"
- integrity sha512-BA+oqqYOZzRLiMYlHX6BJXlIGaNIR9LObgkHEXAj/JPK7do4wDOcuVaw+dlWS+tzvTebLbC9GYAALfNqVBlTwA==
+"@tiptap/extension-strike@^2.0.0-beta.27":
+ version "2.0.0-beta.27"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.0.0-beta.27.tgz#c5187bf3c28837f95a5c0c0617d0dd31c318353d"
+ integrity sha512-2dmCgtesuDdivM/54Q+Y6Tc3JbGz1SkHP6c62piuqBiYLWg3xa16zChZOhfN8szbbQlBgLT6XRTDt3c2Ux+Dug==
-"@tiptap/extension-subscript@^2.0.0-beta.9":
- version "2.0.0-beta.9"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-subscript/-/extension-subscript-2.0.0-beta.9.tgz#4d86e904ec081384696562a5f550e81a1ddf2c76"
- integrity sha512-wrmcDbXeilBW9HjJi34KpUioBCYD5zyaRu1hnIymVRwmfLNrwGpNyo/8VZTfNDdvliyMYHiRVFI4Mott6OzmgA==
+"@tiptap/extension-subscript@^2.0.0-beta.10":
+ version "2.0.0-beta.10"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-subscript/-/extension-subscript-2.0.0-beta.10.tgz#177e9501f805d3cdcb359411b80b54dc7d77373e"
+ integrity sha512-er8/1lp0Rb+SKwEioW0w4oVf3EkdQZ0WS/5kPBG4W0DncfUMT+bw5de76S3kRL9PLZ9UShAL7wuXtuiSi5QsMw==
-"@tiptap/extension-superscript@^2.0.0-beta.9":
- version "2.0.0-beta.9"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-superscript/-/extension-superscript-2.0.0-beta.9.tgz#be43b0e85f6440ed200831309060c3f0691811f2"
- integrity sha512-BxXvCDGtIiuPmY9JbgIEjNbrFzXN3SBj178CfmDcu/FrQimwcqmsfLP3JOu1ZbUwQJuNwubx026vHXPzHlLXDA==
+"@tiptap/extension-superscript@^2.0.0-beta.10":
+ version "2.0.0-beta.10"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-superscript/-/extension-superscript-2.0.0-beta.10.tgz#f91c19c2d30aabe3f8c21e87f8e5e8b2e6a55893"
+ integrity sha512-TUUBS8XsD2MorGORYVlhGDH7wcc9diSbHscD4Dnz8pKWVR0JPUd/od4h5qSffDzAOKxtphTiX9LOFWk6zVooKg==
"@tiptap/extension-table-cell@^2.0.0-beta.20":
version "2.0.0-beta.20"
@@ -1678,37 +1679,37 @@
resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.0.0-beta.19.tgz#b45e82f29dfcc7405440ba237b069dbb93d1a94a"
integrity sha512-ldEVDpIUX7ZqbViTy4c/RfyNGRv++O/r3A/Ivuon1PykaDDTbPlp5JM89FunAD39cLAbo2HKtweqdmzCMlZsqA==
-"@tiptap/extension-table@^2.0.0-beta.43":
- version "2.0.0-beta.43"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.0.0-beta.43.tgz#12fc8513f05dd49cba5f1a0d9dd14df9efc2050a"
- integrity sha512-PALo2WCf/4RpICfJzBvbTaEOf6rpwmQK78jC3tR8kE9Sz6xOSydZmmbl4vovklXCHy3euaW9LCuyiiX+fjJDxw==
+"@tiptap/extension-table@^2.0.0-beta.46":
+ version "2.0.0-beta.46"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.0.0-beta.46.tgz#cce4d64fe58479031eb975626cc42e3ca9ae26bd"
+ integrity sha512-JP0eYb2gS9RW1xzB1yCAgcSX4eg1MvhnYNLOxL6VCKvoHf33RW7zQEGx11W/Lrc3lh5qaMjkWcCdQYq5d8qJOA==
dependencies:
prosemirror-tables "^1.1.1"
- prosemirror-view "^1.23.1"
+ prosemirror-view "^1.23.5"
-"@tiptap/extension-task-item@^2.0.0-beta.29":
- version "2.0.0-beta.29"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.0.0-beta.29.tgz#789bd2012fd9e89623c29a347da02c9cd6e34906"
- integrity sha512-6pkY2NoLMJQxfaJsK8XY5Lv/fx0LVJBJ/J15RE8glUEzkDipNhHTBnHWcfzsa4Qzi6UcSy7NJKtT8ixiyqkRmw==
+"@tiptap/extension-task-item@^2.0.0-beta.30":
+ version "2.0.0-beta.30"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-task-item/-/extension-task-item-2.0.0-beta.30.tgz#54c97d2dd84e0ff40689e02f7361dbd903a40161"
+ integrity sha512-56hS7vP/Hgv5R6otEPInTnd8z5n6UCBFm4sbMPA8d7yWWJDskkfuMp9YDEu2zgHZtTghPyGkw3wO6yxouGWlkg==
-"@tiptap/extension-task-list@^2.0.0-beta.23":
- version "2.0.0-beta.23"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.0.0-beta.23.tgz#ca29039de53f7315e5612bfd1fb4ca6d471b9a2f"
- integrity sha512-NjAQhtWDtkDpeKtJPItNeLi1fLLVACBFMq2yRCtKBXDGYg2X5w9CYPqXzh8gAIM2qs11wIgS60UtvF2No7Crxg==
+"@tiptap/extension-task-list@^2.0.0-beta.26":
+ version "2.0.0-beta.26"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-task-list/-/extension-task-list-2.0.0-beta.26.tgz#75a20795429c40c3b12544483ea63014487d71c7"
+ integrity sha512-7zPpz9eOUCnFyWNDFYPCUJ39gjID+mCI5BuXyXrjJjDfm8wxg/xTgg9+KC6xakczos7DypnhzlRKSs4EFczeUg==
"@tiptap/extension-text@^2.0.0-beta.15":
version "2.0.0-beta.15"
resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.0.0-beta.15.tgz#f08cff1b78f1c6996464dfba1fef8ec1e107617f"
integrity sha512-S3j2+HyV2gsXZP8Wg/HA+YVXQsZ3nrXgBM9HmGAxB0ESOO50l7LWfip0f3qcw1oRlh5H3iLPkA6/f7clD2/TFA==
-"@tiptap/vue-2@^2.0.0-beta.69":
- version "2.0.0-beta.69"
- resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.0.0-beta.69.tgz#65ed98e966c28c9614d4c5a6218e99397a2e0a26"
- integrity sha512-Adm+YvhaihW3mpFIBgPH/3qlxG3hY7/g52gM3Kg0f//SNg/bDqK+AMLroZB5Je06ihCqBaRb1hrSD0/gTVMJ1g==
+"@tiptap/vue-2@^2.0.0-beta.74":
+ version "2.0.0-beta.74"
+ resolved "https://registry.yarnpkg.com/@tiptap/vue-2/-/vue-2-2.0.0-beta.74.tgz#da9e56113018525d0cb55812a2452d57b9710d26"
+ integrity sha512-OY6RhR2DSvP4iIxtoWeg2qmQ1uYP4kJkdMT5ePQBFqVzs6l5+FpSjETskS8EwZVgM/IrLTMp5lHfKboP/YacOA==
dependencies:
- "@tiptap/extension-bubble-menu" "^2.0.0-beta.50"
- "@tiptap/extension-floating-menu" "^2.0.0-beta.45"
- prosemirror-view "^1.23.1"
+ "@tiptap/extension-bubble-menu" "^2.0.0-beta.54"
+ "@tiptap/extension-floating-menu" "^2.0.0-beta.49"
+ prosemirror-view "^1.23.5"
"@toast-ui/editor@^2.5.2":
version "2.5.2"
@@ -1944,17 +1945,17 @@
"@types/prosemirror-transform" "*"
"@types/prosemirror-view" "*"
-"@types/prosemirror-transform@*", "@types/prosemirror-transform@^1.1.4":
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/@types/prosemirror-transform/-/prosemirror-transform-1.1.4.tgz#c3565e81b2ef3ce3254e6927d6f63eb8d7bb20d0"
- integrity sha512-HP1PauvkqSgDquZut8HaLOTUDQ6jja/LAy4OA7tTS1XG7wqRnX3gLUyEj0mD6vFd4y8BPkNddNdOh/BeGHlUjg==
+"@types/prosemirror-transform@*", "@types/prosemirror-transform@^1.1.5":
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/@types/prosemirror-transform/-/prosemirror-transform-1.1.5.tgz#e6949398c64a5d3ca53e6081352751aa9e9ce76e"
+ integrity sha512-Wr2HXaEF4JPklWpC17RTxE6PxyU54Taqk5FMhK1ojgcN93J+GpkYW8s0mD3rl7KfTmlhVwZPCHE9o0cYf2Go5A==
dependencies:
"@types/prosemirror-model" "*"
-"@types/prosemirror-view@*", "@types/prosemirror-view@^1.19.1":
- version "1.19.1"
- resolved "https://registry.yarnpkg.com/@types/prosemirror-view/-/prosemirror-view-1.19.1.tgz#f12309ef07dfb701d20c2e4d0292d42ba34a081b"
- integrity sha512-fyQ4NVxAdfISWrE2qT8cpZdosXoH/1JuVYMBs9CdaXPbvi/8R2L2tkkcMRM314piKrO8nfYH5OBZKzP2Ax3jtA==
+"@types/prosemirror-view@*", "@types/prosemirror-view@^1.19.2":
+ version "1.19.2"
+ resolved "https://registry.yarnpkg.com/@types/prosemirror-view/-/prosemirror-view-1.19.2.tgz#1bab4daf0f1f14313fe0d3f6b57f0a3b4ef6c50d"
+ integrity sha512-pmh2DuMJzva4D7SxspRKIzkV6FK2o52uAqGjq2dPYcQFPwu4+5RcS1TMjFVCh1R+Ia1Rx8wsCNIId/5+6DB0Bg==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
@@ -7927,10 +7928,10 @@ linkify-it@^3.0.1:
dependencies:
uc.micro "^1.0.1"
-linkifyjs@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-3.0.3.tgz#51ea2160b4c60c2c87c27757a1e9eacd422c6076"
- integrity sha512-ba5opS5wRHSbDC8VaiDdN14nPGm6LqyRsIPQZGG4qXV4scFdrPneT/uoZOaq9QAPBf6W9I9D/6tNSzWH//815Q==
+linkifyjs@^3.0.5:
+ version "3.0.5"
+ resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-3.0.5.tgz#99e51a3a0c0e232fcb63ebb89eea3ff923378f34"
+ integrity sha512-1Y9XQH65eQKA9p2xtk+zxvnTeQBG7rdAXSkUG97DmuI/Xhji9uaUzaWxRj6rf9YC0v8KKHkxav7tnLX82Sz5Fg==
load-json-file@^2.0.0:
version "2.0.0"
@@ -9796,10 +9797,10 @@ prosemirror-dropcursor@^1.3.2, prosemirror-dropcursor@^1.4.0:
prosemirror-transform "^1.1.0"
prosemirror-view "^1.1.0"
-prosemirror-gapcursor@^1.1.5, prosemirror-gapcursor@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.2.0.tgz#28fb60bf3d9baf1f920907d2c3e613137204e8f3"
- integrity sha512-yCLy5+0rVqLir/KcHFathQj4Rf8aRHi80FmEfKtM0JmyzvwdomslLzDZ/pX4oFhFKDgjl/WBBBFNqDyNifWg7g==
+prosemirror-gapcursor@^1.1.5, prosemirror-gapcursor@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.2.1.tgz#02365e1bcc1ad25d390b0fb7f0e94a7fc173ad75"
+ integrity sha512-PHa9lj27iM/g4C46gxVzsefuXVfy/LrGQH4QjMRht7VDBgw77iWYWn8ZHMWSFkwtr9jQEuxI5gccHHHwWG80nw==
dependencies:
prosemirror-keymap "^1.0.0"
prosemirror-model "^1.0.0"
@@ -9831,7 +9832,7 @@ prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.1.4,
prosemirror-state "^1.0.0"
w3c-keyname "^2.2.0"
-prosemirror-markdown@^1.6.0:
+prosemirror-markdown@1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/prosemirror-markdown/-/prosemirror-markdown-1.6.0.tgz#141c88e03c8892f2e93cf58b1382ab0b6088d012"
integrity sha512-y/gRpJIIrNArtkyMax7ypYafb+ZMjddbVHI+AwlcUfCLCCXK57cOmfBMKYVq9kdEKJYVdYHdoyWsVNn1nWLHUg==
@@ -9839,10 +9840,10 @@ prosemirror-markdown@^1.6.0:
markdown-it "^10.0.0"
prosemirror-model "^1.0.0"
-prosemirror-model@^1.0.0, prosemirror-model@^1.13.1, prosemirror-model@^1.14.3, prosemirror-model@^1.15.0, prosemirror-model@^1.2.0, prosemirror-model@^1.8.1:
- version "1.15.0"
- resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.15.0.tgz#23bc09098daa7c309dba90a76a1b989ce6f61405"
- integrity sha512-hQJv7SnIhlAy9ga3lhPPgaufhvCbQB9tHwscJ9E1H1pPHmN8w5V/lURueoYv9Kc3/bpNWoyHa8r3g//m7N0ChQ==
+prosemirror-model@^1.0.0, prosemirror-model@^1.13.1, prosemirror-model@^1.16.0, prosemirror-model@^1.16.1, prosemirror-model@^1.2.0, prosemirror-model@^1.8.1:
+ version "1.16.1"
+ resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.16.1.tgz#fb388270bc9609b66298d6a7e15d0cc1d6c61253"
+ integrity sha512-r1/w0HDU40TtkXp0DyKBnFPYwd8FSlUSJmGCGFv4DeynfeSlyQF2FD0RQbVEMOe6P3PpUSXM6LZBV7W/YNZ4mA==
dependencies:
orderedmap "^1.1.0"
@@ -9896,12 +9897,12 @@ prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transfor
dependencies:
prosemirror-model "^1.0.0"
-prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.16.5, prosemirror-view@^1.23.1, prosemirror-view@^1.23.3:
- version "1.23.3"
- resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.23.3.tgz#9ba85fefaf45e813c46562b694fc5f6f9a5cba9c"
- integrity sha512-89icyMdXXwxmTxYj0TIuG5M/d0iKeu79tr+PVtC/4qtCOoHrPSPrblJcFOuOWcxGlA/Ei8PqJB4g5HkKR8jWvQ==
+prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.16.5, prosemirror-view@^1.23.5:
+ version "1.23.5"
+ resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.23.5.tgz#0f4af48fa9d30aa0b945816e2b8e6cb1c82ac674"
+ integrity sha512-GlcCtoFdW17KNOKjOl7OZTU3btENgVfzN/i0RBvy1SEKAZfo88PdvcFrWTraNZHH+y/uhYR3PAdMiDK9DlN5UA==
dependencies:
- prosemirror-model "^1.14.3"
+ prosemirror-model "^1.16.0"
prosemirror-state "^1.0.0"
prosemirror-transform "^1.1.0"