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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-07-18 00:10:31 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-07-18 00:10:31 +0300
commit9c2ea7751419fb5e50708ea3ef3677cd16c43c7c (patch)
tree39dcd6fef621203e39388391d86eec8acfb3a0b0 /app/assets/javascripts
parent16964a4834ac976228b3ad69c4eff813d8230d7a (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts')
-rw-r--r--app/assets/javascripts/admin/users/components/users_table.vue2
-rw-r--r--app/assets/javascripts/behaviors/preview_markdown.js4
-rw-r--r--app/assets/javascripts/content_editor/extensions/copy_paste.js8
-rw-r--r--app/assets/javascripts/tracking/constants.js1
-rw-r--r--app/assets/javascripts/tracking/index.js2
-rw-r--r--app/assets/javascripts/tracking/internal_events.js20
-rw-r--r--app/assets/javascripts/tracking/utils.js18
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/header.vue417
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>