mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-07-31 15:24:31 +03:00
Page Drafts: Added new "Delete Draft" action to draft menu
Provides a way for users to actually delte their user drafts where required. For #3927 Added test to cover new endpoint. Makes update to MD editor #setText so that new selection is within new range, otherwise it errors and fails operation.
This commit is contained in:
@ -19,18 +19,23 @@ export class PageEditor extends Component {
|
||||
this.saveDraftButton = this.$refs.saveDraft;
|
||||
this.discardDraftButton = this.$refs.discardDraft;
|
||||
this.discardDraftWrap = this.$refs.discardDraftWrap;
|
||||
this.deleteDraftButton = this.$refs.deleteDraft;
|
||||
this.deleteDraftWrap = this.$refs.deleteDraftWrap;
|
||||
this.draftDisplay = this.$refs.draftDisplay;
|
||||
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;
|
||||
this.deleteDraftDialogContainer = this.$refs.deleteDraftDialog;
|
||||
|
||||
// Translations
|
||||
this.draftText = this.$opts.draftText;
|
||||
this.autosaveFailText = this.$opts.autosaveFailText;
|
||||
this.editingPageText = this.$opts.editingPageText;
|
||||
this.draftDiscardedText = this.$opts.draftDiscardedText;
|
||||
this.draftDeleteText = this.$opts.draftDeleteText;
|
||||
this.draftDeleteFailText = this.$opts.draftDeleteFailText;
|
||||
this.setChangelogText = this.$opts.setChangelogText;
|
||||
|
||||
// State data
|
||||
@ -75,6 +80,7 @@ export class PageEditor extends Component {
|
||||
// Draft Controls
|
||||
onSelect(this.saveDraftButton, this.saveDraft.bind(this));
|
||||
onSelect(this.discardDraftButton, this.discardDraft.bind(this));
|
||||
onSelect(this.deleteDraftButton, this.deleteDraft.bind(this));
|
||||
|
||||
// Change editor controls
|
||||
onSelect(this.changeEditorButtons, this.changeEditor.bind(this));
|
||||
@ -119,7 +125,8 @@ export class PageEditor extends Component {
|
||||
try {
|
||||
const resp = await window.$http.put(`/ajax/page/${this.pageId}/save-draft`, data);
|
||||
if (!this.isNewDraft) {
|
||||
this.toggleDiscardDraftVisibility(true);
|
||||
this.discardDraftWrap.toggleAttribute('hidden', false);
|
||||
this.deleteDraftWrap.toggleAttribute('hidden', false);
|
||||
}
|
||||
|
||||
this.draftNotifyChange(`${resp.data.message} ${Dates.utcTimeStampToLocalTime(resp.data.timestamp)}`);
|
||||
@ -154,7 +161,7 @@ export class PageEditor extends Component {
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
async discardDraft() {
|
||||
async discardDraft(notify = true) {
|
||||
let response;
|
||||
try {
|
||||
response = await window.$http.get(`/ajax/page/${this.pageId}`);
|
||||
@ -168,7 +175,7 @@ export class PageEditor extends Component {
|
||||
}
|
||||
|
||||
this.draftDisplay.innerText = this.editingPageText;
|
||||
this.toggleDiscardDraftVisibility(false);
|
||||
this.discardDraftWrap.toggleAttribute('hidden', true);
|
||||
window.$events.emit('editor::replace', {
|
||||
html: response.data.html,
|
||||
markdown: response.data.markdown,
|
||||
@ -178,7 +185,30 @@ export class PageEditor extends Component {
|
||||
window.setTimeout(() => {
|
||||
this.startAutoSave();
|
||||
}, 1000);
|
||||
window.$events.emit('success', this.draftDiscardedText);
|
||||
|
||||
if (notify) {
|
||||
window.$events.success(this.draftDiscardedText);
|
||||
}
|
||||
}
|
||||
|
||||
async deleteDraft() {
|
||||
/** @var {ConfirmDialog} * */
|
||||
const dialog = window.$components.firstOnElement(this.deleteDraftDialogContainer, 'confirm-dialog');
|
||||
const confirmed = await dialog.show();
|
||||
if (!confirmed) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const discard = this.discardDraft(false);
|
||||
const draftDelete = window.$http.delete(`/page-revisions/user-drafts/${this.pageId}`);
|
||||
await Promise.all([discard, draftDelete]);
|
||||
window.$events.success(this.draftDeleteText);
|
||||
this.deleteDraftWrap.toggleAttribute('hidden', true);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
window.$events.error(this.draftDeleteFailText);
|
||||
}
|
||||
}
|
||||
|
||||
updateChangelogDisplay() {
|
||||
@ -191,10 +221,6 @@ export class PageEditor extends Component {
|
||||
this.changelogDisplay.innerText = summary;
|
||||
}
|
||||
|
||||
toggleDiscardDraftVisibility(show) {
|
||||
this.discardDraftWrap.classList.toggle('hidden', !show);
|
||||
}
|
||||
|
||||
async changeEditor(event) {
|
||||
event.preventDefault();
|
||||
|
||||
|
@ -433,7 +433,9 @@ export class Actions {
|
||||
*/
|
||||
#setText(text, selectionRange = null) {
|
||||
selectionRange = selectionRange || this.#getSelectionRange();
|
||||
this.#dispatchChange(0, this.editor.cm.state.doc.length, text, selectionRange.from);
|
||||
const newDoc = this.editor.cm.state.toText(text);
|
||||
const newSelectFrom = Math.min(selectionRange.from, newDoc.length);
|
||||
this.#dispatchChange(0, this.editor.cm.state.doc.length, text, newSelectFrom);
|
||||
this.focus();
|
||||
}
|
||||
|
||||
|
@ -27,13 +27,22 @@
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
<li refs="page-editor@discardDraftWrap" class="{{ $isDraftRevision ? '' : 'hidden' }}">
|
||||
<button refs="page-editor@discardDraft" type="button" class="text-neg icon-item">
|
||||
<li refs="page-editor@discard-draft-wrap" {{ $isDraftRevision ? '' : 'hidden' }}>
|
||||
<button refs="page-editor@discard-draft" type="button" class="text-warn icon-item">
|
||||
@icon('cancel')
|
||||
<div>{{ trans('entities.pages_edit_discard_draft') }}</div>
|
||||
</button>
|
||||
</li>
|
||||
<li refs="page-editor@delete-draft-wrap" {{ $isDraftRevision ? '' : 'hidden' }}>
|
||||
<button refs="page-editor@delete-draft" type="button" class="text-neg icon-item">
|
||||
@icon('delete')
|
||||
<div>{{ trans('entities.pages_edit_delete_draft') }}</div>
|
||||
</button>
|
||||
</li>
|
||||
@if(userCan('editor-change'))
|
||||
<li>
|
||||
<hr>
|
||||
</li>
|
||||
<li>
|
||||
@if($editor === 'wysiwyg')
|
||||
<a href="{{ $model->getUrl($isDraft ? '' : '/edit') }}?editor=markdown-clean" refs="page-editor@changeEditor" class="icon-item">
|
||||
|
@ -13,6 +13,8 @@
|
||||
option:page-editor:autosave-fail-text="{{ trans('errors.page_draft_autosave_fail') }}"
|
||||
option:page-editor:editing-page-text="{{ trans('entities.pages_editing_page') }}"
|
||||
option:page-editor:draft-discarded-text="{{ trans('entities.pages_draft_discarded') }}"
|
||||
option:page-editor:draft-delete-text="{{ trans('entities.pages_draft_deleted') }}"
|
||||
option:page-editor:draft-delete-fail-text="{{ trans('errors.page_draft_delete_fail') }}"
|
||||
option:page-editor:set-changelog-text="{{ trans('entities.pages_edit_set_changelog') }}">
|
||||
|
||||
{{--Header Toolbar--}}
|
||||
@ -47,7 +49,7 @@
|
||||
class="text-link text-button hide-over-m page-save-mobile-button">@icon('save')</button>
|
||||
|
||||
{{--Editor Change Dialog--}}
|
||||
@component('common.confirm-dialog', ['title' => trans('entities.pages_editor_switch_title'), 'ref' => 'page-editor@switchDialog'])
|
||||
@component('common.confirm-dialog', ['title' => trans('entities.pages_editor_switch_title'), 'ref' => 'page-editor@switch-dialog'])
|
||||
<p>
|
||||
{{ trans('entities.pages_editor_switch_are_you_sure') }}
|
||||
<br>
|
||||
@ -60,4 +62,11 @@
|
||||
<li>{{ trans('entities.pages_editor_switch_consideration_c') }}</li>
|
||||
</ul>
|
||||
@endcomponent
|
||||
|
||||
{{--Delete Draft Dialog--}}
|
||||
@component('common.confirm-dialog', ['title' => trans('entities.pages_edit_delete_draft'), 'ref' => 'page-editor@delete-draft-dialog'])
|
||||
<p>
|
||||
{{ trans('entities.pages_edit_delete_draft_confirm') }}
|
||||
</p>
|
||||
@endcomponent
|
||||
</div>
|
Reference in New Issue
Block a user