From 3d8ebbb15d166571f53c7c3ad38542bbee2c62fe Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 24 Jan 2024 15:08:34 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- app/assets/javascripts/constants.js | 2 + app/assets/javascripts/gl_form.js | 19 ++++++- app/assets/javascripts/mr_notes/init_notes.js | 4 ++ app/assets/javascripts/notes/index.js | 4 ++ .../vue_shared/components/markdown/field.vue | 8 +++ app/controllers/projects/issues_controller.rb | 1 + .../projects/merge_requests_controller.rb | 1 + ...reload_autocomplete_members_issues_mrs.yml | 8 +++ db/docs/ci_group_variables.yml | 2 + db/docs/ci_secure_files.yml | 2 + db/docs/ci_variables.yml | 2 + db/schema_migrations/20240123155252 | 2 +- .../backup_restore/backup_gitlab.md | 52 +++++++++++++------ .../geo/disaster_recovery/planned_failover.md | 2 +- doc/administration/object_storage.md | 41 +++++++++++++++ .../operations/moving_repositories.md | 2 +- doc/api/commits.md | 35 +++++++++++++ doc/api/graphql/reference/index.md | 31 +++++++++++ doc/install/aws/index.md | 2 +- .../compliance/compliance_center/index.md | 5 +- lib/api/commits.rb | 21 ++++++++ lib/api/entities/commit_sequence.rb | 9 ++++ qa/qa/page/component/issue_board/show.rb | 2 +- qa/qa/page/project/web_ide/vscode.rb | 2 +- .../user_comments_on_merge_request_spec.rb | 4 +- spec/frontend/gl_form_spec.js | 38 ++++++++++++++ .../components/markdown/field_spec.js | 10 ++++ spec/requests/api/commits_spec.rb | 40 ++++++++++++++ .../internal/upload/artifacts_upload_test.go | 14 ++--- 29 files changed, 326 insertions(+), 39 deletions(-) create mode 100644 config/feature_flags/development/preload_autocomplete_members_issues_mrs.yml create mode 100644 lib/api/entities/commit_sequence.rb diff --git a/app/assets/javascripts/constants.js b/app/assets/javascripts/constants.js index f43a2d5d8ff..631968ff531 100644 --- a/app/assets/javascripts/constants.js +++ b/app/assets/javascripts/constants.js @@ -3,3 +3,5 @@ export const getModifierKey = (removeSuffix = false) => { const winKey = `Ctrl${removeSuffix ? '' : '+'}`; return window.gl?.client?.isMac ? '⌘' : winKey; }; + +export const PRELOAD_THROTTLE_TIMEOUT_MS = 4000; diff --git a/app/assets/javascripts/gl_form.js b/app/assets/javascripts/gl_form.js index f4008fe3cc9..ed2d1dbb7d2 100644 --- a/app/assets/javascripts/gl_form.js +++ b/app/assets/javascripts/gl_form.js @@ -5,6 +5,7 @@ import GfmAutoComplete, { defaultAutocompleteConfig } from 'ee_else_ce/gfm_auto_ import { disableButtonIfEmptyField } from '~/lib/utils/common_utils'; import dropzoneInput from './dropzone_input'; import { addMarkdownListeners, removeMarkdownListeners } from './lib/utils/text_markdown'; +import { PRELOAD_THROTTLE_TIMEOUT_MS } from './constants'; export default class GLForm { /** @@ -17,10 +18,11 @@ export default class GLForm { * By default, the backend embeds these in the global object gl.GfmAutocomplete.dataSources. * Use this param to override them. */ - constructor(form, enableGFM = {}, forceNew = false, gfmDataSources = {}) { + constructor(form, enableGFM = {}, forceNew = false, gfmDataSources = {}, preloadMembers = false) { this.form = form; this.textarea = this.form.find('textarea.js-gfm-input'); this.enableGFM = { ...defaultAutocompleteConfig, ...enableGFM }; + this.preloadMembers = preloadMembers; // Disable autocomplete for keywords which do not have dataSources available let dataSources = (gl.GfmAutoComplete && gl.GfmAutoComplete.dataSources) || {}; @@ -68,6 +70,21 @@ export default class GLForm { ); this.autoComplete = new GfmAutoComplete(dataSources); this.autoComplete.setup(this.form.find('.js-gfm-input'), this.enableGFM); + + if (this.preloadMembers && dataSources?.members) { + // for now the preload is only implemented for the members + // timeout helping to trottle the preloads in the case content_editor + // is set as main comment editor and support for rspec tests + // https://gitlab.com/gitlab-org/gitlab/-/issues/427437 + + requestIdleCallback(() => + setTimeout( + () => this.autoComplete?.fetchData($('.js-gfm-input'), '@'), + PRELOAD_THROTTLE_TIMEOUT_MS, + ), + ); + } + this.formDropzone = dropzoneInput(this.form, { parallelUploads: 1 }); if (this.form.is(':not(.js-no-autosize)')) { diff --git a/app/assets/javascripts/mr_notes/init_notes.js b/app/assets/javascripts/mr_notes/init_notes.js index 265e2a2f880..c9e56a6161f 100644 --- a/app/assets/javascripts/mr_notes/init_notes.js +++ b/app/assets/javascripts/mr_notes/init_notes.js @@ -12,6 +12,7 @@ import discussionNavigator from '../notes/components/discussion_navigator.vue'; import NotesApp from '../notes/components/notes_app.vue'; import { getNotesFilterData } from '../notes/utils/get_notes_filter_data'; import initWidget from '../vue_merge_request_widget'; +import { MERGE_REQUEST_NOTEABLE_TYPE } from '../notes/constants'; export default () => { requestIdleCallback( @@ -45,6 +46,9 @@ export default () => { newCommentTemplatePath: notesDataset.newCommentTemplatePath, mrFilter: true, newCustomEmojiPath: notesDataset.newCustomEmojiPath, + preloadMembers: + notesDataset?.noteableType === MERGE_REQUEST_NOTEABLE_TYPE && + gon?.features?.preloadAutocompleteMembersIssuesMrs, }, data() { const noteableData = JSON.parse(notesDataset.noteableData); diff --git a/app/assets/javascripts/notes/index.js b/app/assets/javascripts/notes/index.js index f9fbe6659ee..cc9a3d87939 100644 --- a/app/assets/javascripts/notes/index.js +++ b/app/assets/javascripts/notes/index.js @@ -7,6 +7,7 @@ import { getLocationHash } from '~/lib/utils/url_utility'; import NotesApp from './components/notes_app.vue'; import { store } from './stores'; import { getNotesFilterData } from './utils/get_notes_filter_data'; +import { ISSUE_NOTEABLE_TYPE } from './constants'; export default ({ editorAiActions = [] } = {}) => { const el = document.getElementById('js-vue-notes'); @@ -63,6 +64,9 @@ export default ({ editorAiActions = [] } = {}) => { resourceGlobalId: convertToGraphQLId(noteableData.noteableType, noteableData.id), editorAiActions: editorAiActions.map((factory) => factory(noteableData)), newCustomEmojiPath: notesDataset.newCustomEmojiPath, + preloadMembers: + notesDataset.noteableType === ISSUE_NOTEABLE_TYPE && + gon?.features?.preloadAutocompleteMembersIssuesMrs, }, data() { return { diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue index e80f5c7f092..034d591b6ca 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/field.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue @@ -33,6 +33,13 @@ export default { GlTooltip: GlTooltipDirective, }, mixins: [glFeatureFlagsMixin()], + inject: { + preloadMembers: { + type: Boolean, + required: false, + default: false, + }, + }, props: { /** * This prop should be bound to the value of the `