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>2022-09-23 15:13:18 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-09-23 15:13:18 +0300
commit1ccebc7b3f091ef585dc87a91847aa35f7ae2130 (patch)
tree2e7970962dd429c3dd98ca09e52004df6b3aaa30 /app/assets/javascripts/vue_shared/components/markdown
parentfd767b7d65e0e9cb6f313b1803b859b8a7c0da57 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/vue_shared/components/markdown')
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue178
1 files changed, 178 insertions, 0 deletions
diff --git a/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue b/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue
new file mode 100644
index 00000000000..fd8496fa313
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/markdown/markdown_editor.vue
@@ -0,0 +1,178 @@
+<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 { EDITING_MODE_MARKDOWN_FIELD, EDITING_MODE_CONTENT_EDITOR } from '../../constants';
+import MarkdownField from './field.vue';
+
+export default {
+ components: {
+ MarkdownField,
+ LocalStorageSync,
+ GlSegmentedControl,
+ ContentEditor: () =>
+ import(
+ /* webpackChunkName: 'content_editor' */ '~/content_editor/components/content_editor.vue'
+ ),
+ },
+ props: {
+ value: {
+ type: String,
+ required: true,
+ },
+ renderMarkdownPath: {
+ type: String,
+ required: true,
+ },
+ markdownDocsPath: {
+ type: String,
+ required: true,
+ },
+ uploadsPath: {
+ type: String,
+ required: true,
+ },
+ enableContentEditor: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
+ formFieldId: {
+ type: String,
+ required: true,
+ },
+ formFieldName: {
+ type: String,
+ required: true,
+ },
+ enablePreview: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
+ enableAutocomplete: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
+ autofocus: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ formFieldPlaceholder: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ formFieldAriaLabel: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ },
+ data() {
+ return {
+ editingMode: EDITING_MODE_MARKDOWN_FIELD,
+ switchEditingControlEnabled: true,
+ };
+ },
+ computed: {
+ isContentEditorActive() {
+ return this.enableContentEditor && this.editingMode === EDITING_MODE_CONTENT_EDITOR;
+ },
+ },
+ methods: {
+ updateMarkdownFromContentEditor({ markdown }) {
+ this.$emit('input', markdown);
+ },
+ 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);
+ },
+ notifyEditingModeChange(editingMode) {
+ this.$emit(editingMode);
+ },
+ },
+ 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="notifyEditingModeChange"
+ />
+ </div>
+ <local-storage-sync
+ v-model="editingMode"
+ storage-key="gl-wiki-content-editor-enabled"
+ @input="notifyEditingModeChange"
+ />
+ <markdown-field
+ v-if="!isContentEditorActive"
+ :markdown-preview-path="renderMarkdownPath"
+ can-attach-file
+ :enable-autocomplete="enableAutocomplete"
+ :textarea-value="value"
+ :markdown-docs-path="markdownDocsPath"
+ :uploads-path="uploadsPath"
+ :enable-preview="enablePreview"
+ class="bordered-box"
+ >
+ <template #textarea>
+ <textarea
+ :id="formFieldId"
+ ref="textarea"
+ :value="value"
+ :name="formFieldName"
+ class="note-textarea js-gfm-input js-autosize markdown-area"
+ dir="auto"
+ data-supports-quick-actions="false"
+ data-qa-selector="markdown_editor_form_field"
+ :autofocus="autofocus"
+ :aria-label="formFieldAriaLabel"
+ :placeholder="formFieldPlaceholder"
+ @input="updateMarkdownFromMarkdownField"
+ >
+ </textarea>
+ </template>
+ </markdown-field>
+ <div v-else>
+ <content-editor
+ :render-markdown="renderMarkdown"
+ :uploads-path="uploadsPath"
+ :markdown="value"
+ @change="updateMarkdownFromContentEditor"
+ @loading="disableSwitchEditingControl"
+ @loadingSuccess="enableSwitchEditingControl"
+ @loadingError="enableSwitchEditingControl"
+ />
+ <input
+ :id="formFieldId"
+ :value="value"
+ :name="formFieldName"
+ data-qa-selector="markdown_editor_form_field"
+ type="hidden"
+ />
+ </div>
+ </div>
+</template>