X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/2f6ff0734773c4ac009de699a2661971fd585b22..refs/pull/3693/head:/resources/js/components/page-editor.js diff --git a/resources/js/components/page-editor.js b/resources/js/components/page-editor.js index 4fb472e7e..ce123e987 100644 --- a/resources/js/components/page-editor.js +++ b/resources/js/components/page-editor.js @@ -12,7 +12,7 @@ class PageEditor { this.editorType = this.$opts.editorType; this.pageId = Number(this.$opts.pageId); this.isNewDraft = this.$opts.pageNewDraft === 'true'; - this.hasDefaultTitle = this.$opts.isDefaultTitle || false; + this.hasDefaultTitle = this.$opts.hasDefaultTitle || false; // Elements this.container = this.$el; @@ -24,6 +24,8 @@ class PageEditor { this.draftDisplayIcon = this.$refs.draftDisplayIcon; this.changelogInput = this.$refs.changelogInput; this.changelogDisplay = this.$refs.changelogDisplay; + this.changeEditorButtons = this.$manyRefs.changeEditor; + this.switchDialogContainer = this.$refs.switchDialog; // Translations this.draftText = this.$opts.draftText; @@ -40,7 +42,7 @@ class PageEditor { frequency: 30000, last: 0, }; - this.draftHasError = false; + this.shownWarningsCache = new Set(); if (this.pageId !== 0 && this.draftsEnabled) { window.setTimeout(() => { @@ -72,6 +74,9 @@ class PageEditor { // Draft Controls onSelect(this.saveDraftButton, this.saveDraft.bind(this)); onSelect(this.discardDraftButton, this.discardDraft.bind(this)); + + // Change editor controls + onSelect(this.changeEditorButtons, this.changeEditor.bind(this)); } setInitialFocus() { @@ -113,21 +118,32 @@ class PageEditor { data.markdown = this.editorMarkdown; } + let didSave = false; try { const resp = await window.$http.put(`/ajax/page/${this.pageId}/save-draft`, data); - this.draftHasError = false; if (!this.isNewDraft) { this.toggleDiscardDraftVisibility(true); } + this.draftNotifyChange(`${resp.data.message} ${Dates.utcTimeStampToLocalTime(resp.data.timestamp)}`); this.autoSave.last = Date.now(); - } catch (err) { - if (!this.draftHasError) { - this.draftHasError = true; - window.$events.emit('error', this.autosaveFailText); + if (resp.data.warning && !this.shownWarningsCache.has(resp.data.warning)) { + window.$events.emit('warning', resp.data.warning); + this.shownWarningsCache.add(resp.data.warning); } + + didSave = true; + } catch (err) { + // Save the editor content in LocalStorage as a last resort, just in case. + try { + const saveKey = `draft-save-fail-${(new Date()).toISOString()}`; + window.localStorage.setItem(saveKey, JSON.stringify(data)); + } catch (err) {} + + window.$events.emit('error', this.autosaveFailText); } + return didSave; } draftNotifyChange(text) { @@ -152,8 +168,10 @@ class PageEditor { this.draftDisplay.innerText = this.editingPageText; this.toggleDiscardDraftVisibility(false); - window.$events.emit('editor-html-update', response.data.html || ''); - window.$events.emit('editor-markdown-update', response.data.markdown || response.data.html); + window.$events.emit('editor::replace', { + html: response.data.html, + markdown: response.data.markdown, + }); this.titleElem.value = response.data.name; window.setTimeout(() => { @@ -177,6 +195,18 @@ class PageEditor { this.discardDraftWrap.classList.toggle('hidden', !show); } + async changeEditor(event) { + event.preventDefault(); + + const link = event.target.closest('a').href; + const dialog = this.switchDialogContainer.components['confirm-dialog']; + const [saved, confirmed] = await Promise.all([this.saveDraft(), dialog.show()]); + + if (saved && confirmed) { + window.location = link; + } + } + } export default PageEditor; \ No newline at end of file