diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-12-21 06:15:00 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-12-21 06:15:00 +0300 |
commit | e3ecb7dc093db47b9491e20d9f20de02b4ac2b6d (patch) | |
tree | e87e5dd85e9c33644b3eddcd47a6214e5537d2c9 /app/assets | |
parent | 4aa6fba6d825b88d23ff37668e78c851bec102b0 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
3 files changed, 28 insertions, 6 deletions
diff --git a/app/assets/javascripts/ci/catalog/components/list/catalog_header.vue b/app/assets/javascripts/ci/catalog/components/list/catalog_header.vue index 3a9ec341789..001e3ec3720 100644 --- a/app/assets/javascripts/ci/catalog/components/list/catalog_header.vue +++ b/app/assets/javascripts/ci/catalog/components/list/catalog_header.vue @@ -1,5 +1,6 @@ <script> import { GlBanner, GlLink } from '@gitlab/ui'; +import ChatBubbleSvg from '@gitlab/svgs/dist/illustrations/chat-sm.svg?url'; import { __, s__ } from '~/locale'; import { helpPagePath } from '~/helpers/help_page_helper'; import BetaBadge from '~/vue_shared/components/badges/beta_badge.vue'; @@ -44,6 +45,7 @@ export default { learnMore: __('Learn more'), }, learnMorePath: helpPagePath('ci/components/index'), + ChatBubbleSvg, }; </script> <template> @@ -54,6 +56,7 @@ export default { :title="$options.i18n.banner.title" :button-text="$options.i18n.banner.btnText" button-link="https://gitlab.com/gitlab-org/gitlab/-/issues/407556" + :svg-path="$options.ChatBubbleSvg" @close="handleDismissBanner" > <p> diff --git a/app/assets/javascripts/content_editor/extensions/copy_paste.js b/app/assets/javascripts/content_editor/extensions/copy_paste.js index 23f2da7bc28..1164e7ead33 100644 --- a/app/assets/javascripts/content_editor/extensions/copy_paste.js +++ b/app/assets/javascripts/content_editor/extensions/copy_paste.js @@ -172,6 +172,8 @@ export default Extension.create({ return true; } + if (!textContent) return false; + const hasHTML = clipboardData.types.some((type) => type === HTML_FORMAT); const hasVsCode = clipboardData.types.some((type) => type === VS_CODE_FORMAT); const vsCodeMeta = hasVsCode ? JSON.parse(clipboardData.getData(VS_CODE_FORMAT)) : {}; diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js index b11f7b1ba76..f1e46262b2f 100644 --- a/app/assets/javascripts/gfm_auto_complete.js +++ b/app/assets/javascripts/gfm_auto_complete.js @@ -3,6 +3,7 @@ import '~/lib/utils/jquery_at_who'; import { escape as lodashEscape, sortBy, template, escapeRegExp } from 'lodash'; import * as Emoji from '~/emoji'; import axios from '~/lib/utils/axios_utils'; +import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; import { loadingIconForLegacyJS } from '~/loading_icon_for_legacy_js'; import { s__, __, sprintf } from '~/locale'; import { isUserBusy } from '~/set_status_modal/utils'; @@ -26,6 +27,8 @@ export const CONTACT_STATE_ACTIVE = 'active'; export const CONTACTS_ADD_COMMAND = '/add_contacts'; export const CONTACTS_REMOVE_COMMAND = '/remove_contacts'; +const useMentionsBackendFiltering = window.gon.features?.mentionAutocompleteBackendFiltering; + /** * Escapes user input before we pass it to at.js, which * renders it as HTML in the autocomplete dropdown. @@ -62,6 +65,8 @@ export function showAndHideHelper($input, alias = '') { }); } +// This should be kept in sync with the backend filtering in +// `User#gfm_autocomplete_search` and `Namespace#gfm_autocomplete_search` function createMemberSearchString(member) { return `${member.name.replace(/ /g, '')} ${member.username}`; } @@ -344,6 +349,7 @@ class GfmAutoComplete { } setupMembers($input) { + const instance = this; const fetchData = this.fetchData.bind(this); const MEMBER_COMMAND = { ASSIGN: '/assign', @@ -383,6 +389,7 @@ class GfmAutoComplete { // eslint-disable-next-line no-template-curly-in-string insertTpl: '${atwho-at}${username}', limit: 10, + delay: useMentionsBackendFiltering ? DEFAULT_DEBOUNCE_AND_THROTTLE_MS : null, searchKey: 'search', alwaysHighlightFirst: true, skipSpecialCharacterTest: true, @@ -409,16 +416,19 @@ class GfmAutoComplete { const match = GfmAutoComplete.defaultMatcher(flag, subtext, this.app.controllers); return match && match.length ? match[1] : null; }, - filter(query, data, searchKey) { - if (GfmAutoComplete.isLoading(data)) { + filter(query, data) { + if (useMentionsBackendFiltering) { + if (GfmAutoComplete.isLoading(data) || instance.previousQuery !== query) { + instance.previousQuery = query; + + fetchData(this.$inputor, this.at, query); + return data; + } + } else if (GfmAutoComplete.isLoading(data)) { fetchData(this.$inputor, this.at); return data; } - if (data === GfmAutoComplete.defaultLoadingData) { - return $.fn.atwho.default.callbacks.filter(query, data, searchKey); - } - if (command === MEMBER_COMMAND.ASSIGN) { // Only include members which are not assigned to Issuable currently return data.filter((member) => !assignees.includes(member.search)); @@ -988,6 +998,11 @@ GfmAutoComplete.atTypeMap = { }; GfmAutoComplete.typesWithBackendFiltering = ['vulnerabilities']; + +if (useMentionsBackendFiltering) { + GfmAutoComplete.typesWithBackendFiltering.push('members'); +} + GfmAutoComplete.isTypeWithBackendFiltering = (type) => GfmAutoComplete.typesWithBackendFiltering.includes(GfmAutoComplete.atTypeMap[type]); @@ -1040,6 +1055,8 @@ GfmAutoComplete.Members = { // `member.search` is a name:username string like `MargeSimpson msimpson` return member.search.toLowerCase().includes(query); }, + // This should be kept in sync with the backend sorting in + // `User#gfm_autocomplete_search` and `Namespace#gfm_autocomplete_search` sort(query, members) { const lowercaseQuery = query.toLowerCase(); const { nameOrUsernameStartsWith, nameOrUsernameIncludes } = GfmAutoComplete.Members; |