From 41e78ef065a76627743876cf982bcfd68bfc8759 Mon Sep 17 00:00:00 2001 From: Chad Lavimoniere <clavimoniere@gitlab.com> Date: Fri, 1 Dec 2023 10:51:05 +0000 Subject: [PATCH] Adjust styling of md editor header - Add dividers between groups of related buttons - Ensure fullscreen button is in top left corner of header toolbar Changelog: fixed --- .../markdown/comment_templates_dropdown.vue | 2 +- .../vue_shared/components/markdown/header.vue | 498 +++++++++--------- .../components/markdown/header_divider.vue | 16 + .../components/markdown/toolbar_button.vue | 2 +- .../ai/components/ai_actions_dropdown.vue | 2 +- 5 files changed, 280 insertions(+), 240 deletions(-) create mode 100644 app/assets/javascripts/vue_shared/components/markdown/header_divider.vue diff --git a/app/assets/javascripts/vue_shared/components/markdown/comment_templates_dropdown.vue b/app/assets/javascripts/vue_shared/components/markdown/comment_templates_dropdown.vue index d99b90fa5618c..a7dfc1e2cdb1a 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/comment_templates_dropdown.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/comment_templates_dropdown.vue @@ -88,7 +88,7 @@ export default { placement="right" searchable size="small" - class="comment-template-dropdown gl-mr-3" + class="comment-template-dropdown gl-mr-2" positioning-strategy="fixed" :searching="$apollo.queries.savedReplies.loading" @shown="fetchCommentTemplates" diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue index 2d088aa2200b8..8b9600b2f07db 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/header.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue @@ -21,6 +21,7 @@ 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 HeaderDivider from './header_divider.vue'; export default { components: { @@ -30,6 +31,7 @@ export default { DrawioToolbarButton, CommentTemplatesDropdown, AiActionsDropdown: () => import('ee_component/ai/components/ai_actions_dropdown.vue'), + HeaderDivider, }, directives: { GlTooltip: GlTooltipDirective, @@ -261,249 +263,271 @@ export default { <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-3 gl-flex-wrap gl-row-gap-3" + class="md-header-toolbar gl-display-flex gl-py-3 gl-row-gap-2 gl-flex-grow-1 gl-align-items-flex-start" > - <gl-button - v-if="enablePreview" - data-testid="preview-toggle" - :value="previewMarkdown ? 'preview' : 'edit'" - :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"> + <div class="gl-display-flex gl-flex-wrap gl-row-gap-2"> + <gl-button + v-if="enablePreview" + data-testid="preview-toggle" + :value="previewMarkdown ? 'preview' : 'edit'" + :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 + > + <template v-if="!previewMarkdown && canSuggest"> + <div class="gl-display-flex gl-row-gap-2"> + <header-divider :preview-markdown="previewMarkdown" /> + <toolbar-button + ref="suggestButton" + :tag="mdSuggestion" + :prepend="true" + :button-title="__('Insert suggestion')" + :cursor-offset="4" + :tag-content="lineContent" + tracking-property="codeSuggestion" + icon="doc-code" + data-testid="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-testid="dismiss-suggestion-popover-button" + @click="handleSuggestDismissed" + > + {{ __('Got it') }} + </gl-button> + </gl-popover> + </div> + </template> + <div class="gl-display-flex gl-row-gap-2"> + <div + v-if="!previewMarkdown && editorAiActions.length" + class="gl-display-flex gl-row-gap-2" + > + <header-divider :preview-markdown="previewMarkdown" /> + <ai-actions-dropdown + :actions="editorAiActions" + @input="insertAIAction" + @replace="replaceTextarea" + /> + </div> + <header-divider :preview-markdown="previewMarkdown" /> + </div> + <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" + tracking-property="bold" + /> <toolbar-button - ref="suggestButton" - :tag="mdSuggestion" + 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" + tracking-property="italic" + /> + <div class="gl-display-flex gl-row-gap-2"> + <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" + tracking-property="strike" + /> + <header-divider :preview-markdown="previewMarkdown" /> + </div> + <toolbar-button + v-if="!restrictedToolBarItems.includes('quote')" + v-show="!previewMarkdown" :prepend="true" - :button-title="__('Insert suggestion')" - :cursor-offset="4" - :tag-content="lineContent" - tracking-property="codeSuggestion" - icon="doc-code" - data-testid="suggestion-button" - class="js-suggestion-btn" - @click="handleSuggestDismissed" + :tag="tag" + :button-title="__('Insert a quote')" + icon="quote" + tracking-property="blockquote" + @click="handleQuote" /> - <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-testid="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" - tracking-property="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" - tracking-property="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" - tracking-property="strike" - /> - <toolbar-button - v-if="!restrictedToolBarItems.includes('quote')" - v-show="!previewMarkdown" - :prepend="true" - :tag="tag" - :button-title="__('Insert a quote')" - icon="quote" - tracking-property="blockquote" - @click="handleQuote" - /> - <toolbar-button - v-show="!previewMarkdown" - tag="`" - tag-block="```" - :button-title="__('Insert code')" - icon="code" - tracking-property="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" - tracking-property="link" - /> - <toolbar-button - v-if="!restrictedToolBarItems.includes('bullet-list')" - v-show="!previewMarkdown" - :prepend="true" - tag="- " - :button-title="__('Add a bullet list')" - icon="list-bulleted" - tracking-property="bulletList" - /> - <toolbar-button - v-if="!restrictedToolBarItems.includes('numbered-list')" - v-show="!previewMarkdown" - :prepend="true" - tag="1. " - :button-title="__('Add a numbered list')" - icon="list-numbered" - tracking-property="orderedList" - /> - <toolbar-button - v-if="!restrictedToolBarItems.includes('task-list')" - v-show="!previewMarkdown" - :prepend="true" - tag="- [ ] " - :button-title="__('Add a checklist')" - icon="list-task" - tracking-property="taskList" - /> - <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" - tracking-property="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" - tracking-property="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" - tracking-property="details" - /> - <toolbar-button - v-if="!restrictedToolBarItems.includes('table')" - v-show="!previewMarkdown" - :tag="mdTable" - :prepend="true" - :button-title="__('Add a table')" - icon="table" - tracking-property="table" - /> - <toolbar-button - v-if="!previewMarkdown && !restrictedToolBarItems.includes('attach-file')" - data-testid="button-attach-file" - data-button-type="attach-file" - :button-title="__('Attach a file or image')" - icon="paperclip" - class="gl-mr-3" - tracking-property="upload" - @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" - tracking-property="quickAction" - /> - <comment-templates-dropdown - v-if="!previewMarkdown && newCommentTemplatePath" - :new-comment-template-path="newCommentTemplatePath" - @select="insertSavedReply" - /> - <div v-if="!previewMarkdown" class="full-screen"> + <toolbar-button + v-show="!previewMarkdown" + tag="`" + tag-block="```" + :button-title="__('Insert code')" + icon="code" + tracking-property="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" + tracking-property="link" + /> + <toolbar-button + v-if="!restrictedToolBarItems.includes('bullet-list')" + v-show="!previewMarkdown" + :prepend="true" + tag="- " + :button-title="__('Add a bullet list')" + icon="list-bulleted" + tracking-property="bulletList" + /> + <toolbar-button + v-if="!restrictedToolBarItems.includes('numbered-list')" + v-show="!previewMarkdown" + :prepend="true" + tag="1. " + :button-title="__('Add a numbered list')" + icon="list-numbered" + tracking-property="orderedList" + /> + <toolbar-button + v-if="!restrictedToolBarItems.includes('task-list')" + v-show="!previewMarkdown" + :prepend="true" + tag="- [ ] " + :button-title="__('Add a checklist')" + icon="list-task" + tracking-property="taskList" + /> + <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" + tracking-property="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" + tracking-property="outdent" + /> + <div class="gl-display-flex gl-row-gap-2"> + <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" + tracking-property="details" + /> + <header-divider :preview-markdown="previewMarkdown" /> + </div> + <toolbar-button + v-if="!restrictedToolBarItems.includes('table')" + v-show="!previewMarkdown" + :tag="mdTable" + :prepend="true" + :button-title="__('Add a table')" + icon="table" + tracking-property="table" + /> + <toolbar-button + v-if="!previewMarkdown && !restrictedToolBarItems.includes('attach-file')" + data-testid="button-attach-file" + data-button-type="attach-file" + :button-title="__('Attach a file or image')" + icon="paperclip" + class="gl-mr-2" + tracking-property="upload" + @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" + tracking-property="quickAction" + /> + <comment-templates-dropdown + v-if="!previewMarkdown && newCommentTemplatePath" + :new-comment-template-path="newCommentTemplatePath" + @select="insertSavedReply" + /> + </div> + <div + v-if="!previewMarkdown" + class="full-screen gl-flex-grow-1 gl-justify-content-end gl-display-flex" + > <toolbar-button v-if="!restrictedToolBarItems.includes('full-screen')" - class="js-zen-enter" + class="js-zen-enter gl-mr-0!" icon="maximize" :button-title="__('Go full screen')" :prepend="true" diff --git a/app/assets/javascripts/vue_shared/components/markdown/header_divider.vue b/app/assets/javascripts/vue_shared/components/markdown/header_divider.vue new file mode 100644 index 0000000000000..d08a3d4cd3449 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/markdown/header_divider.vue @@ -0,0 +1,16 @@ +<script> +export default { + props: { + previewMarkdown: { + type: Boolean, + required: false, + default: false, + }, + }, +}; +</script> +<template> + <div v-if="!previewMarkdown" class="md-toolbar-divider gl-display-flex gl-py-2"> + <div class="gl-border-l gl-pl-3 gl-ml-2"></div> + </div> +</template> diff --git a/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue b/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue index cf484443c0708..182da7945ffba 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/toolbar_button.vue @@ -111,7 +111,7 @@ export default { type="button" category="tertiary" size="small" - class="js-md gl-mr-3" + class="js-md gl-mr-2" data-container="body" @click="$emit('click', $event)" /> diff --git a/ee/app/assets/javascripts/ai/components/ai_actions_dropdown.vue b/ee/app/assets/javascripts/ai/components/ai_actions_dropdown.vue index 3f1663f74ad73..a1eddcb8aec16 100644 --- a/ee/app/assets/javascripts/ai/components/ai_actions_dropdown.vue +++ b/ee/app/assets/javascripts/ai/components/ai_actions_dropdown.vue @@ -178,7 +178,7 @@ export default { :aria-label="__('AI actions')" category="tertiary" size="small" - class="gl-mr-3 gl-px-2!" + class="gl-mr-2 gl-px-2!" > <gl-loading-icon v-if="loading" /> <gl-icon v-else name="tanuki" /> -- GitLab