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-10-20 12:40:42 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-10-20 12:40:42 +0300
commitee664acb356f8123f4f6b00b73c1e1cf0866c7fb (patch)
treef8479f94a28f66654c6a4f6fb99bad6b4e86a40e /app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
parent62f7d5c5b69180e82ae8196b7b429eeffc8e7b4f (diff)
Add latest changes from gitlab-org/gitlab@15-5-stable-eev15.5.0-rc42
Diffstat (limited to 'app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue')
-rw-r--r--app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue221
1 files changed, 91 insertions, 130 deletions
diff --git a/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue b/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
index 9acc1cb62a1..7b9656de362 100644
--- a/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
+++ b/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
@@ -8,21 +8,19 @@ import {
GlFormGroup,
GlFormInput,
GlFormSelect,
- GlSegmentedControl,
} from '@gitlab/ui';
-import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
-import axios from '~/lib/utils/axios_utils';
+import { getDraft, clearDraft, updateDraft } from '~/lib/utils/autosave';
import csrf from '~/lib/utils/csrf';
import { setUrlFragment } from '~/lib/utils/url_utility';
import { s__, sprintf } from '~/locale';
import Tracking from '~/tracking';
-import MarkdownField from '~/vue_shared/components/markdown/field.vue';
+import MarkdownEditor from '~/vue_shared/components/markdown/markdown_editor.vue';
import {
- CONTENT_EDITOR_LOADED_ACTION,
SAVED_USING_CONTENT_EDITOR_ACTION,
WIKI_CONTENT_EDITOR_TRACKING_LABEL,
WIKI_FORMAT_LABEL,
WIKI_FORMAT_UPDATED_ACTION,
+ CONTENT_EDITOR_LOADED_ACTION,
} from '../constants';
const trackingMixin = Tracking.mixin({
@@ -36,6 +34,29 @@ const MARKDOWN_LINK_TEXT = {
org: '[[page-slug]]',
};
+function getPagePath(pageInfo) {
+ return pageInfo.persisted ? pageInfo.path : pageInfo.createPath;
+}
+
+const autosaveKey = (pageInfo, field) => {
+ const path = pageInfo.persisted ? pageInfo.path : pageInfo.createPath;
+
+ return `${path}/${field}`;
+};
+
+const titleAutosaveKey = (pageInfo) => autosaveKey(pageInfo, 'title');
+const formatAutosaveKey = (pageInfo) => autosaveKey(pageInfo, 'format');
+const contentAutosaveKey = (pageInfo) => autosaveKey(pageInfo, 'content');
+const commitAutosaveKey = (pageInfo) => autosaveKey(pageInfo, 'commit');
+
+const getTitle = (pageInfo) => getDraft(titleAutosaveKey(pageInfo)) || pageInfo.title?.trim() || '';
+const getFormat = (pageInfo) =>
+ getDraft(formatAutosaveKey(pageInfo)) || pageInfo.format || 'markdown';
+const getContent = (pageInfo) => getDraft(contentAutosaveKey(pageInfo)) || pageInfo.content || '';
+const getCommitMessage = (pageInfo) =>
+ getDraft(commitAutosaveKey(pageInfo)) || pageInfo.commitMessage || '';
+const getIsFormDirty = (pageInfo) => Boolean(getDraft(titleAutosaveKey(pageInfo)));
+
export default {
i18n: {
title: {
@@ -74,10 +95,6 @@ export default {
},
cancel: s__('WikiPage|Cancel'),
},
- switchEditingControlOptions: [
- { text: s__('Wiki Page|Source'), value: 'source' },
- { text: s__('Wiki Page|Rich text'), value: 'richText' },
- ],
components: {
GlIcon,
GlForm,
@@ -87,26 +104,21 @@ export default {
GlSprintf,
GlLink,
GlButton,
- GlSegmentedControl,
- MarkdownField,
- LocalStorageSync,
- ContentEditor: () =>
- import(
- /* webpackChunkName: 'content_editor' */ '~/content_editor/components/content_editor.vue'
- ),
+ MarkdownEditor,
},
mixins: [trackingMixin],
inject: ['formatOptions', 'pageInfo'],
data() {
return {
editingMode: 'source',
- title: this.pageInfo.title?.trim() || '',
- format: this.pageInfo.format || 'markdown',
- content: this.pageInfo.content || '',
- commitMessage: '',
- isDirty: false,
+ title: getTitle(this.pageInfo),
+ format: getFormat(this.pageInfo),
+ content: getContent(this.pageInfo),
+ commitMessage: getCommitMessage(this.pageInfo),
contentEditorEmpty: false,
+ isContentEditorActive: false,
switchEditingControlDisabled: false,
+ isFormDirty: getIsFormDirty(this.pageInfo),
};
},
computed: {
@@ -117,7 +129,7 @@ export default {
return csrf.token;
},
formAction() {
- return this.pageInfo.persisted ? this.pageInfo.path : this.pageInfo.createPath;
+ return getPagePath(this.pageInfo);
},
helpPath() {
return setUrlFragment(
@@ -162,15 +174,9 @@ export default {
disableSubmitButton() {
return this.noContent || !this.title;
},
- isContentEditorActive() {
- return this.isMarkdownFormat && this.useContentEditor;
- },
- useContentEditor() {
- return this.editingMode === 'richText';
- },
},
mounted() {
- this.updateCommitMessage();
+ if (!this.commitMessage) this.updateCommitMessage();
window.addEventListener('beforeunload', this.onPageUnload);
},
@@ -178,51 +184,45 @@ export default {
window.removeEventListener('beforeunload', this.onPageUnload);
},
methods: {
- renderMarkdown(content) {
- return axios
- .post(this.pageInfo.markdownPreviewPath, { text: content })
- .then(({ data }) => data.body);
- },
-
- setEditingMode(editingMode) {
- this.editingMode = editingMode;
- },
-
async handleFormSubmit(e) {
- e.preventDefault();
+ this.isFormDirty = false;
- if (this.useContentEditor) {
- this.trackFormSubmit();
- }
+ e.preventDefault();
+ this.trackFormSubmit();
this.trackWikiFormat();
// Wait until form field values are refreshed
await this.$nextTick();
e.target.submit();
+ },
- this.isDirty = false;
+ updateDrafts() {
+ updateDraft(titleAutosaveKey(this.pageInfo), this.title);
+ updateDraft(formatAutosaveKey(this.pageInfo), this.format);
+ updateDraft(contentAutosaveKey(this.pageInfo), this.content);
+ updateDraft(commitAutosaveKey(this.pageInfo), this.commitMessage);
},
- handleContentChange() {
- this.isDirty = true;
+ clearDrafts() {
+ clearDraft(titleAutosaveKey(this.pageInfo));
+ clearDraft(formatAutosaveKey(this.pageInfo));
+ clearDraft(contentAutosaveKey(this.pageInfo));
+ clearDraft(commitAutosaveKey(this.pageInfo));
},
- handleContentEditorChange({ empty, markdown, changed }) {
+ handleContentEditorChange({ empty, markdown }) {
this.contentEditorEmpty = empty;
- this.isDirty = changed;
this.content = markdown;
},
- onPageUnload(event) {
- if (!this.isDirty) return undefined;
-
- event.preventDefault();
-
- // eslint-disable-next-line no-param-reassign
- event.returnValue = '';
- return '';
+ onPageUnload() {
+ if (this.isFormDirty) {
+ this.updateDrafts();
+ } else {
+ this.clearDrafts();
+ }
},
updateCommitMessage() {
@@ -235,8 +235,13 @@ export default {
this.commitMessage = newCommitMessage;
},
- trackContentEditorLoaded() {
- this.track(CONTENT_EDITOR_LOADED_ACTION);
+ notifyContentEditorActive() {
+ this.isContentEditorActive = true;
+ this.trackContentEditorLoaded();
+ },
+
+ notifyContentEditorInactive() {
+ this.isContentEditorActive = false;
},
trackFormSubmit() {
@@ -256,12 +261,12 @@ export default {
});
},
- enableSwitchEditingControl() {
- this.switchEditingControlDisabled = false;
+ trackContentEditorLoaded() {
+ this.track(CONTENT_EDITOR_LOADED_ACTION);
},
- disableSwitchEditingControl() {
- this.switchEditingControlDisabled = true;
+ submitFormWithShortcut() {
+ this.$refs.form.submit();
},
},
};
@@ -269,10 +274,12 @@ export default {
<template>
<gl-form
+ ref="form"
:action="formAction"
method="post"
class="wiki-form common-note-form gl-mt-3 js-quick-submit"
@submit="handleFormSubmit"
+ @input="isFormDirty = true"
>
<input :value="csrfToken" type="hidden" name="authenticity_token" />
<input v-if="pageInfo.persisted" type="hidden" name="_method" value="put" />
@@ -329,74 +336,23 @@ export default {
<div class="row" data-testid="wiki-form-content-fieldset">
<div class="col-sm-12 row-sm-5">
<gl-form-group>
- <div v-if="isMarkdownFormat" class="gl-display-flex gl-justify-content-start gl-mb-3">
- <gl-segmented-control
- data-testid="toggle-editing-mode-button"
- data-qa-selector="editing_mode_button"
- class="gl-display-flex"
- :checked="editingMode"
- :options="$options.switchEditingControlOptions"
- :disabled="switchEditingControlDisabled"
- @input="setEditingMode"
- />
- </div>
- <local-storage-sync
- storage-key="gl-wiki-content-editor-enabled"
- :value="editingMode"
- @input="setEditingMode"
- />
- <markdown-field
- v-if="!isContentEditorActive"
- :markdown-preview-path="pageInfo.markdownPreviewPath"
- :can-attach-file="true"
- :enable-autocomplete="true"
- :textarea-value="content"
+ <markdown-editor
+ v-model="content"
+ :render-markdown-path="pageInfo.markdownPreviewPath"
:markdown-docs-path="pageInfo.markdownHelpPath"
:uploads-path="pageInfo.uploadsPath"
+ :enable-content-editor="isMarkdownFormat"
:enable-preview="isMarkdownFormat"
- class="bordered-box"
- >
- <template #textarea>
- <textarea
- id="wiki_content"
- ref="textarea"
- v-model="content"
- name="wiki[content]"
- class="note-textarea js-gfm-input js-autosize markdown-area"
- dir="auto"
- data-supports-quick-actions="false"
- data-qa-selector="wiki_content_textarea"
- :autofocus="pageInfo.persisted"
- :aria-label="$options.i18n.content.label"
- :placeholder="$options.i18n.content.placeholder"
- @input="handleContentChange"
- >
- </textarea>
- </template>
- </markdown-field>
- <div v-if="isContentEditorActive">
- <content-editor
- :render-markdown="renderMarkdown"
- :uploads-path="pageInfo.uploadsPath"
- :markdown="content"
- @initialized="trackContentEditorLoaded"
- @change="handleContentEditorChange"
- @loading="disableSwitchEditingControl"
- @loadingSuccess="enableSwitchEditingControl"
- @loadingError="enableSwitchEditingControl"
- />
- <input
- id="wiki_content"
- v-model.trim="content"
- type="hidden"
- name="wiki[content]"
- data-qa-selector="wiki_hidden_content"
- />
- </div>
-
- <div class="clearfix"></div>
- <div class="error-alert"></div>
-
+ :init-on-autofocus="pageInfo.persisted"
+ :form-field-placeholder="$options.i18n.content.placeholder"
+ :form-field-aria-label="$options.i18n.content.label"
+ form-field-id="wiki_content"
+ form-field-name="wiki[content]"
+ @contentEditor="notifyContentEditorActive"
+ @markdownField="notifyContentEditorInactive"
+ @keydown.ctrl.enter="submitFormShortcut"
+ @keydown.meta.enter="submitFormShortcut"
+ />
<div class="form-text gl-text-gray-600">
<gl-sprintf
v-if="displayWikiSpecificMarkdownHelp"
@@ -447,9 +403,14 @@ export default {
:disabled="disableSubmitButton"
>{{ submitButtonText }}</gl-button
>
- <gl-button data-testid="wiki-cancel-button" :href="cancelFormPath" class="float-right">{{
- $options.i18n.cancel
- }}</gl-button>
+ <gl-button
+ data-testid="wiki-cancel-button"
+ :href="cancelFormPath"
+ class="float-right"
+ @click="isFormDirty = false"
+ >
+ {{ $options.i18n.cancel }}</gl-button
+ >
</div>
</gl-form>
</template>