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:
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/markdown/header.vue')
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/header.vue163
1 files changed, 98 insertions, 65 deletions
diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue
index af0b34f1389..0907e064e01 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/header.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue
@@ -13,13 +13,13 @@ import {
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { getModifierKey } from '~/constants';
import { getSelectedFragment } from '~/lib/utils/common_utils';
-import { s__, __ } from '~/locale';
+import { truncateSha } from '~/lib/utils/text_utility';
+import { s__, __, sprintf } from '~/locale';
import { CopyAsGFM } from '~/behaviors/markdown/copy_as_gfm';
import { updateText } from '~/lib/utils/text_markdown';
import ToolbarButton from './toolbar_button.vue';
import DrawioToolbarButton from './drawio_toolbar_button.vue';
import CommentTemplatesDropdown from './comment_templates_dropdown.vue';
-import EditorModeSwitcher from './editor_mode_switcher.vue';
export default {
components: {
@@ -29,7 +29,6 @@ export default {
DrawioToolbarButton,
CommentTemplatesDropdown,
AiActionsDropdown: () => import('ee_component/ai/components/ai_actions_dropdown.vue'),
- EditorModeSwitcher,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -40,6 +39,7 @@ export default {
default: null,
},
editorAiActions: { default: () => [] },
+ mrGeneratedContent: { default: null },
},
props: {
previewMarkdown: {
@@ -91,17 +91,19 @@ export default {
required: false,
default: false,
},
- showContentEditorSwitcher: {
+ supportsQuickActions: {
type: Boolean,
required: false,
default: false,
},
},
data() {
+ const modifierKey = getModifierKey();
return {
tag: '> ',
suggestPopoverVisible: false,
- modifierKey: getModifierKey(),
+ modifierKey,
+ shiftKey: modifierKey === '⌘' ? '⇧' : 'Shift+',
};
},
computed: {
@@ -126,9 +128,6 @@ export default {
const expandText = s__('MarkdownEditor|Click to expand');
return [`<details><summary>${expandText}</summary>`, `{text}`, '</details>'].join('\n');
},
- showEditorModeSwitcher() {
- return this.showContentEditorSwitcher && !this.previewMarkdown;
- },
},
watch: {
showSuggestPopover() {
@@ -199,17 +198,25 @@ export default {
insertIntoTextarea(text) {
const textArea = this.$el.closest('.md-area')?.querySelector('textarea');
if (textArea) {
- const generatedByText = `${text}\n\n---\n\n_${__('This comment was generated by AI')}_`;
updateText({
textArea,
- tag: generatedByText,
+ tag: text,
cursorOffset: 0,
wrap: false,
});
}
},
- handleEditorModeChanged() {
- this.$emit('enableContentEditor');
+ replaceTextarea(text) {
+ const { description, descriptionForSha } = this.$options.i18n;
+ const headSha = document.getElementById('merge_request_diff_head_sha').value;
+ const addendum = headSha
+ ? sprintf(descriptionForSha, { revision: truncateSha(headSha) })
+ : description;
+
+ if (this.mrGeneratedContent) {
+ this.mrGeneratedContent.setGeneratedContent(`${text}\n\n---\n\n_${addendum}_`);
+ this.mrGeneratedContent.showWarning();
+ }
},
switchPreview() {
if (this.previewMarkdown) {
@@ -218,6 +225,12 @@ export default {
this.showMarkdownPreview();
}
},
+ insertAIAction(text) {
+ this.insertIntoTextarea(`${text}\n\n---\n\n_${__('This comment was generated by AI')}_`);
+ },
+ insertSavedReply(savedReply) {
+ this.insertIntoTextarea(savedReply);
+ },
},
shortcuts: {
bold: keysFor(BOLD_TEXT),
@@ -228,27 +241,36 @@ export default {
outdent: keysFor(OUTDENT_LINE),
},
i18n: {
- preview: __('Preview'),
+ comment: __('This comment was generated by AI'),
+ description: s__('MergeRequest|This description was generated using AI'),
+ descriptionForSha: s__(
+ 'MergeRequest|This description was generated for revision %{revision} using AI',
+ ),
hidePreview: __('Continue editing'),
+ preview: __('Preview'),
},
};
</script>
<template>
- <div class="md-header gl-bg-gray-50 gl-px-2 gl-rounded-base gl-mx-2 gl-mt-2">
- <div
- class="gl-display-flex gl-align-items-center gl-flex-wrap"
- :class="{
- 'gl-justify-content-end': previewMarkdown,
- 'gl-justify-content-space-between': !previewMarkdown,
- }"
- >
+ <div class="md-header gl-border-b gl-border-gray-100 gl-px-3">
+ <div class="gl-display-flex gl-align-items-center gl-flex-wrap">
<div
data-testid="md-header-toolbar"
- class="md-header-toolbar gl-display-flex gl-py-2 gl-flex-wrap"
- :class="{ 'gl-display-none!': previewMarkdown }"
+ class="md-header-toolbar gl-display-flex gl-py-3 gl-flex-wrap gl-row-gap-3"
>
- <template v-if="canSuggest">
+ <gl-button
+ v-if="enablePreview"
+ data-testid="preview-toggle"
+ value="preview"
+ :label="$options.i18n.previewTabTitle"
+ class="js-md-preview-button gl-flex-direction-row-reverse gl-align-items-center gl-font-weight-normal! gl-mr-2"
+ size="small"
+ category="tertiary"
+ @click="switchPreview"
+ >{{ previewMarkdown ? $options.i18n.hidePreview : $options.i18n.preview }}</gl-button
+ >
+ <template v-if="!previewMarkdown && canSuggest">
<toolbar-button
ref="suggestButton"
:tag="mdSuggestion"
@@ -289,11 +311,13 @@ export default {
</gl-popover>
</template>
<ai-actions-dropdown
- v-if="editorAiActions.length"
+ v-if="!previewMarkdown && editorAiActions.length"
:actions="editorAiActions"
- @input="insertIntoTextarea"
+ @input="insertAIAction"
+ @replace="replaceTextarea"
/>
<toolbar-button
+ v-show="!previewMarkdown"
tag="**"
:button-title="
/* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */
@@ -305,6 +329,7 @@ export default {
icon="bold"
/>
<toolbar-button
+ v-show="!previewMarkdown"
tag="_"
:button-title="
/* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */
@@ -317,11 +342,13 @@ export default {
/>
<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}⇧X)'), {
- modifierKey /* eslint-enable @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"
@@ -329,14 +356,22 @@ export default {
/>
<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 tag="`" tag-block="```" :button-title="__('Insert code')" icon="code" />
<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="
@@ -350,6 +385,7 @@ export default {
/>
<toolbar-button
v-if="!restrictedToolBarItems.includes('bullet-list')"
+ v-show="!previewMarkdown"
:prepend="true"
tag="- "
:button-title="__('Add a bullet list')"
@@ -357,6 +393,7 @@ export default {
/>
<toolbar-button
v-if="!restrictedToolBarItems.includes('numbered-list')"
+ v-show="!previewMarkdown"
:prepend="true"
tag="1. "
:button-title="__('Add a numbered list')"
@@ -364,6 +401,7 @@ export default {
/>
<toolbar-button
v-if="!restrictedToolBarItems.includes('task-list')"
+ v-show="!previewMarkdown"
:prepend="true"
tag="- [ ] "
:button-title="__('Add a checklist')"
@@ -371,6 +409,7 @@ export default {
/>
<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 */
@@ -384,6 +423,7 @@ export default {
/>
<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 */
@@ -397,6 +437,7 @@ export default {
/>
<toolbar-button
v-if="!restrictedToolBarItems.includes('collapsible-section')"
+ v-show="!previewMarkdown"
:tag="mdCollapsibleSection"
:prepend="true"
tag-select="Click to expand"
@@ -405,17 +446,18 @@ export default {
/>
<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="!restrictedToolBarItems.includes('attach-file')"
+ 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-2"
+ class="gl-mr-3"
data-testid="button-attach-file"
category="tertiary"
icon="paperclip"
@@ -423,46 +465,37 @@ export default {
@click="handleAttachFile"
/>
<drawio-toolbar-button
- v-if="drawioEnabled"
+ 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="newCommentTemplatePath && glFeatures.savedReplies"
+ v-if="!previewMarkdown && newCommentTemplatePath && glFeatures.savedReplies"
:new-comment-template-path="newCommentTemplatePath"
+ @select="insertSavedReply"
/>
- </div>
- <div class="switch-preview gl-py-2 gl-display-flex gl-align-items-center gl-ml-auto">
- <editor-mode-switcher
- v-if="showEditorModeSwitcher"
- size="small"
- class="gl-mr-2"
- value="markdown"
- @input="handleEditorModeChanged"
- />
- <gl-button
- v-if="enablePreview"
- data-testid="preview-toggle"
- value="preview"
- :label="$options.i18n.previewTabTitle"
- class="js-md-preview-button gl-flex-direction-row-reverse gl-align-items-center gl-font-weight-normal!"
- size="small"
- category="tertiary"
- @click="switchPreview"
- >{{ previewMarkdown ? $options.i18n.hidePreview : $options.i18n.preview }}</gl-button
- >
- <gl-button
- v-if="!restrictedToolBarItems.includes('full-screen')"
- v-gl-tooltip
- :class="{ 'gl-display-none!': previewMarkdown }"
- class="js-zen-enter gl-ml-2"
- category="tertiary"
- icon="maximize"
- size="small"
- :title="__('Go full screen')"
- :prepend="true"
- :aria-label="__('Go full screen')"
- />
+ <div v-if="!previewMarkdown" 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>
</div>
</div>
</div>