diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-18 00:10:31 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-18 00:10:31 +0300 |
commit | 9c2ea7751419fb5e50708ea3ef3677cd16c43c7c (patch) | |
tree | 39dcd6fef621203e39388391d86eec8acfb3a0b0 /app/assets | |
parent | 16964a4834ac976228b3ad69c4eff813d8230d7a (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
8 files changed, 266 insertions, 206 deletions
diff --git a/app/assets/javascripts/admin/users/components/users_table.vue b/app/assets/javascripts/admin/users/components/users_table.vue index 2d2c598f953..65737be1e67 100644 --- a/app/assets/javascripts/admin/users/components/users_table.vue +++ b/app/assets/javascripts/admin/users/components/users_table.vue @@ -109,7 +109,7 @@ export default { :empty-text="s__('AdminUsers|No users found')" show-empty stacked="md" - :tbody-tr-attr="{ 'data-qa-selector': 'user_row_content' }" + :tbody-tr-attr="{ 'data-testid': 'user-row-content' }" > <template #cell(name)="{ item: user }"> <user-avatar :user="user" :admin-user-path="paths.adminUser" /> diff --git a/app/assets/javascripts/behaviors/preview_markdown.js b/app/assets/javascripts/behaviors/preview_markdown.js index 6b50abe7014..ce77ede9fe4 100644 --- a/app/assets/javascripts/behaviors/preview_markdown.js +++ b/app/assets/javascripts/behaviors/preview_markdown.js @@ -4,7 +4,6 @@ import $ from 'jquery'; import { renderGFM } from '~/behaviors/markdown/render_gfm'; import { createAlert } from '~/alert'; import axios from '~/lib/utils/axios_utils'; -import { addMarkdownListeners, removeMarkdownListeners } from '~/lib/utils/text_markdown'; import { __ } from '~/locale'; // MarkdownPreview @@ -129,8 +128,6 @@ $(document).on('markdown-preview:show', (e, $form) => { return; } - removeMarkdownListeners($form); - lastTextareaPreviewed = $form.find('textarea.markdown-area'); lastTextareaHeight = lastTextareaPreviewed.height(); @@ -168,7 +165,6 @@ $(document).on('markdown-preview:hide', (e, $form) => { $form.find('.haml-markdown-button, .js-zen-enter').removeClass('gl-display-none!'); markdownPreview.hideReferencedCommands($form); - addMarkdownListeners($form); }); $(document).on('markdown-preview:toggle', (e, keyboardEvent) => { diff --git a/app/assets/javascripts/content_editor/extensions/copy_paste.js b/app/assets/javascripts/content_editor/extensions/copy_paste.js index 45a89cc08cf..f484ce98e90 100644 --- a/app/assets/javascripts/content_editor/extensions/copy_paste.js +++ b/app/assets/javascripts/content_editor/extensions/copy_paste.js @@ -8,6 +8,7 @@ import { VARIANT_DANGER } from '~/alert'; import createMarkdownDeserializer from '../services/gl_api_markdown_deserializer'; import { ALERT_EVENT, EXTENSION_PRIORITY_HIGHEST } from '../constants'; import CodeBlockHighlight from './code_block_highlight'; +import CodeSuggestion from './code_suggestion'; import Diagram from './diagram'; import Frontmatter from './frontmatter'; @@ -15,7 +16,12 @@ const TEXT_FORMAT = 'text/plain'; const GFM_FORMAT = 'text/x-gfm'; const HTML_FORMAT = 'text/html'; const VS_CODE_FORMAT = 'vscode-editor-data'; -const CODE_BLOCK_NODE_TYPES = [CodeBlockHighlight.name, Diagram.name, Frontmatter.name]; +const CODE_BLOCK_NODE_TYPES = [ + CodeBlockHighlight.name, + CodeSuggestion.name, + Diagram.name, + Frontmatter.name, +]; function parseHTML(schema, html) { const parser = new DOMParser(); diff --git a/app/assets/javascripts/tracking/constants.js b/app/assets/javascripts/tracking/constants.js index 0e440750fdb..d0447fa167c 100644 --- a/app/assets/javascripts/tracking/constants.js +++ b/app/assets/javascripts/tracking/constants.js @@ -19,6 +19,7 @@ export const DEFAULT_SNOWPLOW_OPTIONS = { export const ACTION_ATTR_SELECTOR = '[data-track-action]'; export const LOAD_ACTION_ATTR_SELECTOR = '[data-track-action="render"]'; +export const INTERNAL_EVENTS_SELECTOR = '[data-event-tracking]'; export const URLS_CACHE_STORAGE_KEY = 'gl-snowplow-pseudonymized-urls'; diff --git a/app/assets/javascripts/tracking/index.js b/app/assets/javascripts/tracking/index.js index 6494838abac..7c2cd6fde27 100644 --- a/app/assets/javascripts/tracking/index.js +++ b/app/assets/javascripts/tracking/index.js @@ -69,4 +69,6 @@ export function initDefaultTrackers() { Tracking.bindDocument(); Tracking.trackLoadEvents(); + + InternalEvents.bindInternalEventDocument(); } diff --git a/app/assets/javascripts/tracking/internal_events.js b/app/assets/javascripts/tracking/internal_events.js index 56453373bbf..16cbb3e86e1 100644 --- a/app/assets/javascripts/tracking/internal_events.js +++ b/app/assets/javascripts/tracking/internal_events.js @@ -2,6 +2,8 @@ import API from '~/api'; import Tracking from './tracking'; import { GITLAB_INTERNAL_EVENT_CATEGORY, SERVICE_PING_SCHEMA } from './constants'; +import { Tracker } from './tracker'; +import { InternalEventHandler } from './utils'; const InternalEvents = { /** @@ -33,6 +35,24 @@ const InternalEvents = { }, }; }, + /** + * Attaches event handlers for data-attributes powered events. + * + * @param {HTMLElement} parent - element containing data-attributes + * @returns {Object} handler - object containing name of the event and its corresponding function + */ + bindInternalEventDocument(parent = document) { + if (!Tracker.enabled() || parent.internalEventsTrackingBound) { + return []; + } + + // eslint-disable-next-line no-param-reassign + parent.internalEventsTrackingBound = true; + + const handler = { name: 'click', func: (e) => InternalEventHandler(e, this.track_event) }; + parent.addEventListener(handler.name, handler.func); + return handler; + }, }; export default InternalEvents; diff --git a/app/assets/javascripts/tracking/utils.js b/app/assets/javascripts/tracking/utils.js index cc0d7e7a44a..7cbc0f1843e 100644 --- a/app/assets/javascripts/tracking/utils.js +++ b/app/assets/javascripts/tracking/utils.js @@ -6,6 +6,7 @@ import { LOAD_ACTION_ATTR_SELECTOR, URLS_CACHE_STORAGE_KEY, REFERRER_TTL, + INTERNAL_EVENTS_SELECTOR, } from './constants'; export const addExperimentContext = (opts) => { @@ -69,6 +70,23 @@ export const createEventPayload = (el, { suffix = '' } = {}) => { }; }; +export const createInternalEventPayload = (el) => { + const { eventTracking } = el?.dataset || {}; + + return eventTracking; +}; + +export const InternalEventHandler = (e, func) => { + const el = e.target.closest(INTERNAL_EVENTS_SELECTOR); + + if (!el) { + return; + } + const event = createInternalEventPayload(el); + + func(event); +}; + export const eventHandler = (e, func, opts = {}) => { const actionSelector = `${ACTION_ATTR_SELECTOR}:not(${LOAD_ACTION_ATTR_SELECTOR})`; const el = e.target.closest(actionSelector); diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue index 0c6a9c2fa98..a53d5049752 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/header.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue @@ -275,215 +275,232 @@ export default { @click="switchPreview" >{{ previewMarkdown ? $options.i18n.hidePreview : $options.i18n.preview }}</gl-button > - <template v-if="!previewMarkdown"> - <template v-if="canSuggest"> - <toolbar-button - ref="suggestButton" - :tag="mdSuggestion" - :prepend="true" - :button-title="__('Insert suggestion')" - :cursor-offset="4" - :tag-content="lineContent" - icon="doc-code" - data-qa-selector="suggestion_button" - class="js-suggestion-btn" - @click="handleSuggestDismissed" - /> - <gl-popover - v-if="suggestPopoverVisible" - :target="$refs.suggestButton.$el" - :css-classes="['diff-suggest-popover']" - placement="bottom" - :show="suggestPopoverVisible" - triggers="" - > - <strong>{{ __('New! Suggest changes directly') }}</strong> - <p class="mb-2"> - {{ - __( - 'Suggest code changes which can be immediately applied in one click. Try it out!', - ) - }} - </p> - <gl-button - variant="confirm" - category="primary" - size="small" - data-qa-selector="dismiss_suggestion_popover_button" - @click="handleSuggestDismissed" - > - {{ __('Got it') }} - </gl-button> - </gl-popover> - </template> - <ai-actions-dropdown - v-if="editorAiActions.length" - :actions="editorAiActions" - @input="insertAIAction" - @replace="replaceTextarea" - /> - <toolbar-button - tag="**" - :button-title=" - /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ - sprintf(s__('MarkdownEditor|Add bold text (%{modifierKey}B)'), { - modifierKey, - }) /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */ - " - :shortcuts="$options.shortcuts.bold" - icon="bold" - /> - <toolbar-button - tag="_" - :button-title=" - /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ - sprintf(s__('MarkdownEditor|Add italic text (%{modifierKey}I)'), { - modifierKey, - }) /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */ - " - :shortcuts="$options.shortcuts.italic" - icon="italic" - /> - <toolbar-button - v-if="!restrictedToolBarItems.includes('strikethrough')" - tag="~~" - :button-title=" - /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ - sprintf(s__('MarkdownEditor|Add strikethrough text (%{modifierKey}%{shiftKey}X)'), { - modifierKey, - shiftKey /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */, - }) - " - :shortcuts="$options.shortcuts.strikethrough" - icon="strikethrough" - /> + <template v-if="!previewMarkdown && canSuggest"> <toolbar-button - v-if="!restrictedToolBarItems.includes('quote')" + ref="suggestButton" + :tag="mdSuggestion" :prepend="true" - :tag="tag" - :button-title="__('Insert a quote')" - icon="quote" - @click="handleQuote" - /> - <toolbar-button tag="`" tag-block="```" :button-title="__('Insert code')" icon="code" /> - <toolbar-button - tag="[{text}](url)" - tag-select="url" - :button-title=" - /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ - sprintf(s__('MarkdownEditor|Add a link (%{modifierKey}K)'), { - modifierKey, - }) /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */ - " - :shortcuts="$options.shortcuts.link" - icon="link" - /> - <toolbar-button - v-if="!restrictedToolBarItems.includes('bullet-list')" - :prepend="true" - tag="- " - :button-title="__('Add a bullet list')" - icon="list-bulleted" - /> - <toolbar-button - v-if="!restrictedToolBarItems.includes('numbered-list')" - :prepend="true" - tag="1. " - :button-title="__('Add a numbered list')" - icon="list-numbered" - /> - <toolbar-button - v-if="!restrictedToolBarItems.includes('task-list')" - :prepend="true" - tag="- [ ] " - :button-title="__('Add a checklist')" - icon="list-task" - /> - <toolbar-button - v-if="!restrictedToolBarItems.includes('indent')" - class="gl-display-none" - :button-title=" - /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ - sprintf(s__('MarkdownEditor|Indent line (%{modifierKey}])'), { - modifierKey /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */, - }) - " - :shortcuts="$options.shortcuts.indent" - command="indentLines" - icon="list-indent" - /> - <toolbar-button - v-if="!restrictedToolBarItems.includes('outdent')" - class="gl-display-none" - :button-title=" - /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ - sprintf(s__('MarkdownEditor|Outdent line (%{modifierKey}[)'), { - modifierKey /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */, - }) - " - :shortcuts="$options.shortcuts.outdent" - command="outdentLines" - icon="list-outdent" - /> - <toolbar-button - v-if="!restrictedToolBarItems.includes('collapsible-section')" - :tag="mdCollapsibleSection" - :prepend="true" - tag-select="Click to expand" - :button-title="__('Add a collapsible section')" - icon="details-block" - /> - <toolbar-button - v-if="!restrictedToolBarItems.includes('table')" - :tag="mdTable" - :prepend="true" - :button-title="__('Add a table')" - icon="table" + :button-title="__('Insert suggestion')" + :cursor-offset="4" + :tag-content="lineContent" + icon="doc-code" + data-qa-selector="suggestion_button" + class="js-suggestion-btn" + @click="handleSuggestDismissed" /> + <gl-popover + v-if="suggestPopoverVisible" + :target="$refs.suggestButton.$el" + :css-classes="['diff-suggest-popover']" + placement="bottom" + :show="suggestPopoverVisible" + triggers="" + > + <strong>{{ __('New! Suggest changes directly') }}</strong> + <p class="mb-2"> + {{ + __( + 'Suggest code changes which can be immediately applied in one click. Try it out!', + ) + }} + </p> + <gl-button + variant="confirm" + category="primary" + size="small" + data-qa-selector="dismiss_suggestion_popover_button" + @click="handleSuggestDismissed" + > + {{ __('Got it') }} + </gl-button> + </gl-popover> + </template> + <ai-actions-dropdown + v-if="!previewMarkdown && editorAiActions.length" + :actions="editorAiActions" + @input="insertAIAction" + @replace="replaceTextarea" + /> + <toolbar-button + v-show="!previewMarkdown" + tag="**" + :button-title=" + /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ + sprintf(s__('MarkdownEditor|Add bold text (%{modifierKey}B)'), { + modifierKey, + }) /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */ + " + :shortcuts="$options.shortcuts.bold" + icon="bold" + /> + <toolbar-button + v-show="!previewMarkdown" + tag="_" + :button-title=" + /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ + sprintf(s__('MarkdownEditor|Add italic text (%{modifierKey}I)'), { + modifierKey, + }) /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */ + " + :shortcuts="$options.shortcuts.italic" + icon="italic" + /> + <toolbar-button + v-if="!restrictedToolBarItems.includes('strikethrough')" + v-show="!previewMarkdown" + tag="~~" + :button-title=" + /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ + sprintf(s__('MarkdownEditor|Add strikethrough text (%{modifierKey}%{shiftKey}X)'), { + modifierKey, + shiftKey /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */, + }) + " + :shortcuts="$options.shortcuts.strikethrough" + icon="strikethrough" + /> + <toolbar-button + v-if="!restrictedToolBarItems.includes('quote')" + v-show="!previewMarkdown" + :prepend="true" + :tag="tag" + :button-title="__('Insert a quote')" + icon="quote" + @click="handleQuote" + /> + <toolbar-button + v-show="!previewMarkdown" + tag="`" + tag-block="```" + :button-title="__('Insert code')" + icon="code" + /> + <toolbar-button + v-show="!previewMarkdown" + tag="[{text}](url)" + tag-select="url" + :button-title=" + /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ + sprintf(s__('MarkdownEditor|Add a link (%{modifierKey}K)'), { + modifierKey, + }) /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */ + " + :shortcuts="$options.shortcuts.link" + icon="link" + /> + <toolbar-button + v-if="!restrictedToolBarItems.includes('bullet-list')" + v-show="!previewMarkdown" + :prepend="true" + tag="- " + :button-title="__('Add a bullet list')" + icon="list-bulleted" + /> + <toolbar-button + v-if="!restrictedToolBarItems.includes('numbered-list')" + v-show="!previewMarkdown" + :prepend="true" + tag="1. " + :button-title="__('Add a numbered list')" + icon="list-numbered" + /> + <toolbar-button + v-if="!restrictedToolBarItems.includes('task-list')" + v-show="!previewMarkdown" + :prepend="true" + tag="- [ ] " + :button-title="__('Add a checklist')" + icon="list-task" + /> + <toolbar-button + v-if="!restrictedToolBarItems.includes('indent')" + v-show="!previewMarkdown" + class="gl-display-none" + :button-title=" + /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ + sprintf(s__('MarkdownEditor|Indent line (%{modifierKey}])'), { + modifierKey /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */, + }) + " + :shortcuts="$options.shortcuts.indent" + command="indentLines" + icon="list-indent" + /> + <toolbar-button + v-if="!restrictedToolBarItems.includes('outdent')" + v-show="!previewMarkdown" + class="gl-display-none" + :button-title=" + /* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ + sprintf(s__('MarkdownEditor|Outdent line (%{modifierKey}[)'), { + modifierKey /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */, + }) + " + :shortcuts="$options.shortcuts.outdent" + command="outdentLines" + icon="list-outdent" + /> + <toolbar-button + v-if="!restrictedToolBarItems.includes('collapsible-section')" + v-show="!previewMarkdown" + :tag="mdCollapsibleSection" + :prepend="true" + tag-select="Click to expand" + :button-title="__('Add a collapsible section')" + icon="details-block" + /> + <toolbar-button + v-if="!restrictedToolBarItems.includes('table')" + v-show="!previewMarkdown" + :tag="mdTable" + :prepend="true" + :button-title="__('Add a table')" + icon="table" + /> + <gl-button + v-if="!previewMarkdown && !restrictedToolBarItems.includes('attach-file')" + v-gl-tooltip + :aria-label="__('Attach a file or image')" + :title="__('Attach a file or image')" + class="gl-mr-3" + data-testid="button-attach-file" + category="tertiary" + icon="paperclip" + size="small" + @click="handleAttachFile" + /> + <drawio-toolbar-button + v-if="!previewMarkdown && drawioEnabled" + :uploads-path="uploadsPath" + :markdown-preview-path="markdownPreviewPath" + /> + <!-- TODO Add icon and trigger functionality from here --> + <toolbar-button + v-if="supportsQuickActions" + v-show="!previewMarkdown" + :prepend="true" + tag="/" + :button-title="__('Add a quick action')" + icon="quick-actions" + /> + <comment-templates-dropdown + v-if="!previewMarkdown && newCommentTemplatePath && glFeatures.savedReplies" + :new-comment-template-path="newCommentTemplatePath" + @select="insertSavedReply" + /> + <div v-if="!previewMarkdown" class="full-screen"> <gl-button - v-if="!restrictedToolBarItems.includes('attach-file')" + v-if="!restrictedToolBarItems.includes('full-screen')" v-gl-tooltip - :aria-label="__('Attach a file or image')" - :title="__('Attach a file or image')" - class="gl-mr-3" - data-testid="button-attach-file" + class="js-zen-enter" category="tertiary" - icon="paperclip" + icon="maximize" size="small" - @click="handleAttachFile" - /> - <drawio-toolbar-button - v-if="drawioEnabled" - :uploads-path="uploadsPath" - :markdown-preview-path="markdownPreviewPath" - /> - <!-- TODO Add icon and trigger functionality from here --> - <toolbar-button - v-if="supportsQuickActions" + :title="__('Go full screen')" :prepend="true" - tag="/" - :button-title="__('Add a quick action')" - icon="quick-actions" - /> - <comment-templates-dropdown - v-if="newCommentTemplatePath && glFeatures.savedReplies" - :new-comment-template-path="newCommentTemplatePath" - @select="insertSavedReply" + :aria-label="__('Go full screen')" /> - <div class="full-screen"> - <gl-button - v-if="!restrictedToolBarItems.includes('full-screen')" - v-gl-tooltip - class="js-zen-enter" - category="tertiary" - icon="maximize" - size="small" - :title="__('Go full screen')" - :prepend="true" - :aria-label="__('Go full screen')" - /> - </div> - </template> + </div> </div> </div> </div> |