summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/vue_shared/components/markdown
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/markdown')
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/editor_mode_dropdown.vue58
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/field.vue7
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/header.vue11
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue38
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/toolbar.vue21
5 files changed, 96 insertions, 39 deletions
diff --git a/app/assets/javascripts/vue_shared/components/markdown/editor_mode_dropdown.vue b/app/assets/javascripts/vue_shared/components/markdown/editor_mode_dropdown.vue
new file mode 100644
index 00000000000..6702a81e747
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/markdown/editor_mode_dropdown.vue
@@ -0,0 +1,58 @@
+<script>
+import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
+import { __ } from '~/locale';
+
+export default {
+ components: {
+ GlDropdown,
+ GlDropdownItem,
+ },
+ props: {
+ size: {
+ type: String,
+ required: false,
+ default: 'medium',
+ },
+ value: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ markdownEditorSelected() {
+ return this.value === 'markdown';
+ },
+ text() {
+ return this.markdownEditorSelected ? __('View rich text') : __('View markdown');
+ },
+ },
+};
+</script>
+<template>
+ <gl-dropdown
+ category="tertiary"
+ data-qa-selector="editing_mode_switcher"
+ :size="size"
+ :text="text"
+ right
+ >
+ <gl-dropdown-item
+ is-check-item
+ :is-checked="!markdownEditorSelected"
+ @click="$emit('input', 'richText')"
+ ><div class="gl-font-weight-bold">{{ __('Rich text') }}</div>
+ <div class="gl-text-secondary">
+ {{ __('View the formatted output in real-time as you edit.') }}
+ </div>
+ </gl-dropdown-item>
+ <gl-dropdown-item
+ is-check-item
+ :is-checked="markdownEditorSelected"
+ @click="$emit('input', 'markdown')"
+ ><div class="gl-font-weight-bold">{{ __('Markdown') }}</div>
+ <div class="gl-text-secondary">
+ {{ __('View and edit markdown, with the option to preview the formatted output.') }}
+ </div></gl-dropdown-item
+ >
+ </gl-dropdown>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue
index b5f2602af5e..7b76fc3fc6d 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/field.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue
@@ -122,6 +122,11 @@ export default {
required: false,
default: () => [],
},
+ showContentEditorSwitcher: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
return {
@@ -364,6 +369,8 @@ export default {
:quick-actions-docs-path="quickActionsDocsPath"
:can-attach-file="canAttachFile"
:show-comment-tool-bar="showCommentToolBar"
+ :show-content-editor-switcher="showContentEditorSwitcher"
+ @enableContentEditor="$emit('enableContentEditor')"
/>
</div>
</div>
diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue
index 89fffdedbfd..e83441e59a2 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/header.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue
@@ -10,6 +10,7 @@ import {
INDENT_LINE,
OUTDENT_LINE,
} from '~/behaviors/shortcuts/keybindings';
+import { getModifierKey } from '~/constants';
import { getSelectedFragment } from '~/lib/utils/common_utils';
import { s__, __ } from '~/locale';
import { CopyAsGFM } from '~/behaviors/markdown/copy_as_gfm';
@@ -66,6 +67,7 @@ export default {
return {
tag: '> ',
suggestPopoverVisible: false,
+ modifierKey: getModifierKey(),
};
},
computed: {
@@ -90,15 +92,6 @@ export default {
const expandText = s__('MarkdownEditor|Click to expand');
return [`<details><summary>${expandText}</summary>`, `{text}`, '</details>'].join('\n');
},
- isMac() {
- // Accessing properties using ?. to allow tests to use
- // this component without setting up window.gl.client.
- // In production, window.gl.client should always be present.
- return Boolean(window.gl?.client?.isMac);
- },
- modifierKey() {
- return this.isMac ? '⌘' : s__('KeyboardKey|Ctrl+');
- },
},
watch: {
showSuggestPopover() {
diff --git a/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue b/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue
index d01eae0308f..c53118b9f62 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue
@@ -1,16 +1,13 @@
<script>
-import { GlSegmentedControl } from '@gitlab/ui';
-import { __ } from '~/locale';
-import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
import axios from '~/lib/utils/axios_utils';
+import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
import { EDITING_MODE_MARKDOWN_FIELD, EDITING_MODE_CONTENT_EDITOR } from '../../constants';
import MarkdownField from './field.vue';
export default {
components: {
- MarkdownField,
LocalStorageSync,
- GlSegmentedControl,
+ MarkdownField,
ContentEditor: () =>
import(
/* webpackChunkName: 'content_editor' */ '~/content_editor/components/content_editor.vue'
@@ -91,7 +88,6 @@ export default {
data() {
return {
editingMode: EDITING_MODE_MARKDOWN_FIELD,
- switchEditingControlEnabled: true,
autofocused: false,
};
},
@@ -114,19 +110,16 @@ export default {
updateMarkdownFromMarkdownField({ target }) {
this.$emit('input', target.value);
},
- enableSwitchEditingControl() {
- this.switchEditingControlEnabled = true;
- },
- disableSwitchEditingControl() {
- this.switchEditingControlEnabled = false;
- },
renderMarkdown(markdown) {
return axios.post(this.renderMarkdownPath, { text: markdown }).then(({ data }) => data.body);
},
onEditingModeChange(editingMode) {
+ this.editingMode = editingMode;
this.notifyEditingModeChange(editingMode);
},
onEditingModeRestored(editingMode) {
+ this.editingMode = editingMode;
+ this.$emit(editingMode);
this.notifyEditingModeChange(editingMode);
},
notifyEditingModeChange(editingMode) {
@@ -142,25 +135,10 @@ export default {
this.autofocused = true;
},
},
- switchEditingControlOptions: [
- { text: __('Source'), value: EDITING_MODE_MARKDOWN_FIELD },
- { text: __('Rich text'), value: EDITING_MODE_CONTENT_EDITOR },
- ],
};
</script>
<template>
<div>
- <div class="gl-display-flex gl-justify-content-start gl-mb-3">
- <gl-segmented-control
- v-model="editingMode"
- data-testid="toggle-editing-mode-button"
- data-qa-selector="editing_mode_button"
- class="gl-display-flex"
- :options="$options.switchEditingControlOptions"
- :disabled="!enableContentEditor || !switchEditingControlEnabled"
- @change="onEditingModeChange"
- />
- </div>
<local-storage-sync
v-model="editingMode"
storage-key="gl-wiki-content-editor-enabled"
@@ -176,7 +154,9 @@ export default {
:quick-actions-docs-path="quickActionsDocsPath"
:uploads-path="uploadsPath"
:enable-preview="enablePreview"
+ show-content-editor-switcher
class="bordered-box"
+ @enableContentEditor="onEditingModeChange('contentEditor')"
>
<template #textarea>
<textarea
@@ -205,10 +185,8 @@ export default {
:use-bottom-toolbar="useBottomToolbar"
@initialized="setEditorAsAutofocused"
@change="updateMarkdownFromContentEditor"
- @loading="disableSwitchEditingControl"
- @loadingSuccess="enableSwitchEditingControl"
- @loadingError="enableSwitchEditingControl"
@keydown="$emit('keydown', $event)"
+ @enableMarkdownEditor="onEditingModeChange('markdownField')"
/>
<input
:id="formFieldId"
diff --git a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
index b5640e12541..e8be242f660 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue
@@ -1,5 +1,6 @@
<script>
import { GlButton, GlLink, GlLoadingIcon, GlSprintf, GlIcon } from '@gitlab/ui';
+import EditorModeDropdown from './editor_mode_dropdown.vue';
export default {
components: {
@@ -8,6 +9,7 @@ export default {
GlLoadingIcon,
GlSprintf,
GlIcon,
+ EditorModeDropdown,
},
props: {
markdownDocsPath: {
@@ -29,12 +31,24 @@ export default {
required: false,
default: true,
},
+ showContentEditorSwitcher: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
computed: {
hasQuickActionsDocsPath() {
return this.quickActionsDocsPath !== '';
},
},
+ methods: {
+ handleEditorModeChanged(mode) {
+ if (mode === 'richText') {
+ this.$emit('enableContentEditor');
+ }
+ },
+ },
};
</script>
@@ -121,5 +135,12 @@ export default {
{{ __('Cancel') }}
</gl-button>
</span>
+ <editor-mode-dropdown
+ v-if="showContentEditorSwitcher"
+ size="small"
+ class="gl-float-right gl-line-height-28 gl-display-block"
+ value="markdown"
+ @input="handleEditorModeChanged"
+ />
</div>
</template>