diff --git a/src/public/app/dialogs/export.js b/src/public/app/dialogs/export.js deleted file mode 100644 index a62a7fa18..000000000 --- a/src/public/app/dialogs/export.js +++ /dev/null @@ -1,137 +0,0 @@ -import treeService from "../services/tree.js"; -import utils from "../services/utils.js"; -import ws from "../services/ws.js"; -import toastService from "../services/toast.js"; -import froca from "../services/froca.js"; -import openService from "../services/open.js"; - -const $dialog = $("#export-dialog"); -const $form = $("#export-form"); -const $noteTitle = $dialog.find(".export-note-title"); -const $subtreeFormats = $("#export-subtree-formats"); -const $singleFormats = $("#export-single-formats"); -const $subtreeType = $("#export-type-subtree"); -const $singleType = $("#export-type-single"); -const $exportButton = $("#export-button"); -const $opmlVersions = $("#opml-versions"); - -let taskId = ''; -let branchId = null; - -export async function showDialog(notePath, defaultType) { - // each opening of the dialog resets the taskId so we don't associate it with previous exports anymore - taskId = ''; - $exportButton.removeAttr("disabled"); - - if (defaultType === 'subtree') { - $subtreeType.prop("checked", true).trigger('change'); - - // to show/hide OPML versions - $("input[name=export-subtree-format]:checked").trigger('change'); - } - else if (defaultType === 'single') { - $singleType.prop("checked", true).trigger('change'); - } - else { - throw new Error("Unrecognized type " + defaultType); - } - - $("#opml-v2").prop("checked", true); // setting default - - utils.openDialog($dialog); - - const {noteId, parentNoteId} = treeService.getNoteIdAndParentIdFromNotePath(notePath); - - branchId = await froca.getBranchId(parentNoteId, noteId); - - const noteTitle = await treeService.getNoteTitle(noteId); - - $noteTitle.html(noteTitle); -} - -$form.on('submit', () => { - $dialog.modal('hide'); - - const exportType = $dialog.find("input[name='export-type']:checked").val(); - - if (!exportType) { - // this shouldn't happen as we always choose default export type - alert("Choose export type first please"); - return; - } - - const exportFormat = exportType === 'subtree' - ? $("input[name=export-subtree-format]:checked").val() - : $("input[name=export-single-format]:checked").val(); - - const exportVersion = exportFormat === 'opml' ? $dialog.find("input[name='opml-version']:checked").val() : "1.0"; - - exportBranch(branchId, exportType, exportFormat, exportVersion); - - return false; -}); - -function exportBranch(branchId, type, format, version) { - taskId = utils.randomString(10); - - const url = openService.getUrlForDownload(`api/notes/${branchId}/export/${type}/${format}/${version}/${taskId}`); - - openService.download(url); -} - -$('input[name=export-type]').on('change', function () { - if (this.value === 'subtree') { - if ($("input[name=export-subtree-format]:checked").length === 0) { - $("input[name=export-subtree-format]:first").prop("checked", true); - } - - $subtreeFormats.slideDown(); - $singleFormats.slideUp(); - } - else { - if ($("input[name=export-single-format]:checked").length === 0) { - $("input[name=export-single-format]:first").prop("checked", true); - } - - $subtreeFormats.slideUp(); - $singleFormats.slideDown(); - } -}); - -$('input[name=export-subtree-format]').on('change', function () { - if (this.value === 'opml') { - $opmlVersions.slideDown(); - } - else { - $opmlVersions.slideUp(); - } -}); - -function makeToast(id, message) { - return { - id: id, - title: "Export status", - message: message, - icon: "arrow-square-up-right" - }; -} - -ws.subscribeToMessages(async message => { - if (message.taskType !== 'export') { - return; - } - - if (message.type === 'taskError') { - toastService.closePersistent(message.taskId); - toastService.showError(message.message); - } - else if (message.type === 'taskProgressCount') { - toastService.showPersistent(makeToast(message.taskId, "Export in progress: " + message.progressCount)); - } - else if (message.type === 'taskSucceeded') { - const toast = makeToast(message.taskId, "Export finished successfully."); - toast.closeAfter = 5000; - - toastService.showPersistent(toast); - } -}); diff --git a/src/public/app/layouts/desktop_layout.js b/src/public/app/layouts/desktop_layout.js index e92ac7609..cf7e50436 100644 --- a/src/public/app/layouts/desktop_layout.js +++ b/src/public/app/layouts/desktop_layout.js @@ -66,6 +66,7 @@ import AddLinkDialog from "../widgets/dialogs/add_link.js"; import CloneToDialog from "../widgets/dialogs/clone_to.js"; import MoveToDialog from "../widgets/dialogs/move_to.js"; import ImportDialog from "../widgets/dialogs/import.js"; +import ExportDialog from "../widgets/dialogs/export.js"; export default class DesktopLayout { constructor(customWidgets) { @@ -206,6 +207,7 @@ export default class DesktopLayout { .child(new AddLinkDialog()) .child(new CloneToDialog()) .child(new MoveToDialog()) - .child(new ImportDialog()); + .child(new ImportDialog()) + .child(new ExportDialog()); } } diff --git a/src/public/app/widgets/buttons/note_actions.js b/src/public/app/widgets/buttons/note_actions.js index 89bac66df..fe486f299 100644 --- a/src/public/app/widgets/buttons/note_actions.js +++ b/src/public/app/widgets/buttons/note_actions.js @@ -53,7 +53,10 @@ export default class NoteActionsWidget extends NoteContextAwareWidget { return; } - import('../../dialogs/export.js').then(d => d.showDialog(this.noteContext.notePath, 'single')); + this.triggerCommand("showExportDialog", { + notePath: this.noteContext.notePath, + defaultType: "single" + }); }); this.$importNoteButton = this.$widget.find('.import-files-button'); diff --git a/src/public/app/widgets/dialogs/export.js b/src/public/app/widgets/dialogs/export.js new file mode 100644 index 000000000..fe85a9c62 --- /dev/null +++ b/src/public/app/widgets/dialogs/export.js @@ -0,0 +1,256 @@ +import treeService from "../../services/tree.js"; +import utils from "../../services/utils.js"; +import ws from "../../services/ws.js"; +import toastService from "../../services/toast.js"; +import froca from "../../services/froca.js"; +import openService from "../../services/open.js"; +import BasicWidget from "../basic_widget.js"; + +const TPL = ` +`; + +export default class ExportDialog extends BasicWidget { + constructor() { + super(); + + this.taskId = ''; + this.branchId = null; + } + + doRender() { + this.$widget = $(TPL); + this.$form = this.$widget.find(".export-form"); + this.$noteTitle = this.$widget.find(".export-note-title"); + this.$subtreeFormats = this.$widget.find(".export-subtree-formats"); + this.$singleFormats = this.$widget.find(".export-single-formats"); + this.$subtreeType = this.$widget.find(".export-type-subtree"); + this.$singleType = this.$widget.find(".export-type-single"); + this.$exportButton = this.$widget.find(".export-button"); + this.$opmlVersions = this.$widget.find(".opml-versions"); + + this.$form.on('submit', () => { + this.$widget.modal('hide'); + + const exportType = this.$widget.find("input[name='export-type']:checked").val(); + + if (!exportType) { + // this shouldn't happen as we always choose default export type + alert("Choose export type first please"); + return; + } + + const exportFormat = exportType === 'subtree' + ? this.$widget.find("input[name=export-subtree-format]:checked").val() + : this.$widget.find("input[name=export-single-format]:checked").val(); + + const exportVersion = exportFormat === 'opml' + ? this.$widget.find("input[name='opml-version']:checked").val() + : "1.0"; + + this.exportBranch(this.branchId, exportType, exportFormat, exportVersion); + + return false; + }); + + this.$widget.find('input[name=export-type]').on('change', e => { + if (e.currentTarget.value === 'subtree') { + if (this.$widget.find("input[name=export-subtree-format]:checked").length === 0) { + this.$widget.find("input[name=export-subtree-format]:first").prop("checked", true); + } + + this.$subtreeFormats.slideDown(); + this.$singleFormats.slideUp(); + } + else { + if (this.$widget.find("input[name=export-single-format]:checked").length === 0) { + this.$widget.find("input[name=export-single-format]:first").prop("checked", true); + } + + this.$subtreeFormats.slideUp(); + this.$singleFormats.slideDown(); + } + }); + + this.$widget.find('input[name=export-subtree-format]').on('change', e => { + if (e.currentTarget.value === 'opml') { + this.$opmlVersions.slideDown(); + } + else { + this.$opmlVersions.slideUp(); + } + }); + } + + async showExportDialogEvent({notePath, defaultType}) { + // each opening of the dialog resets the taskId, so we don't associate it with previous exports anymore + this.taskId = ''; + this.$exportButton.removeAttr("disabled"); + + if (defaultType === 'subtree') { + this.$subtreeType.prop("checked", true).trigger('change'); + + // to show/hide OPML versions + this.$widget.find("input[name=export-subtree-format]:checked").trigger('change'); + } + else if (defaultType === 'single') { + this.$singleType.prop("checked", true).trigger('change'); + } + else { + throw new Error("Unrecognized type " + defaultType); + } + + this.$widget.find(".opml-v2").prop("checked", true); // setting default + + utils.openDialog(this.$widget); + + const {noteId, parentNoteId} = treeService.getNoteIdAndParentIdFromNotePath(notePath); + + this.branchId = await froca.getBranchId(parentNoteId, noteId); + + const noteTitle = await treeService.getNoteTitle(noteId); + + this.$noteTitle.html(noteTitle); + } + + exportBranch(branchId, type, format, version) { + this.taskId = utils.randomString(10); + + const url = openService.getUrlForDownload(`api/notes/${branchId}/export/${type}/${format}/${version}/${this.taskId}`); + + openService.download(url); + } +} + +ws.subscribeToMessages(async message => { + const makeToast = (id, message) => ({ + id: id, + title: "Export status", + message: message, + icon: "arrow-square-up-right" + }); + + if (message.taskType !== 'export') { + return; + } + + if (message.type === 'taskError') { + toastService.closePersistent(message.taskId); + toastService.showError(message.message); + } + else if (message.type === 'taskProgressCount') { + toastService.showPersistent(makeToast(message.taskId, "Export in progress: " + message.progressCount)); + } + else if (message.type === 'taskSucceeded') { + const toast = makeToast(message.taskId, "Export finished successfully."); + toast.closeAfter = 5000; + + toastService.showPersistent(toast); + } +}); diff --git a/src/public/app/widgets/note_tree.js b/src/public/app/widgets/note_tree.js index a5fdb0fb0..88104379c 100644 --- a/src/public/app/widgets/note_tree.js +++ b/src/public/app/widgets/note_tree.js @@ -1451,10 +1451,9 @@ export default class NoteTreeWidget extends NoteContextAwareWidget { } async exportNoteCommand({node}) { - const exportDialog = await import('../dialogs/export.js'); const notePath = treeService.getNotePath(node); - exportDialog.showDialog(notePath,"subtree"); + this.triggerCommand("showExportDialog", {notePath, defaultType: "subtree"}); } async importIntoNoteCommand({node}) { diff --git a/src/public/stylesheets/style.css b/src/public/stylesheets/style.css index 60b6ac1e2..e84186be9 100644 --- a/src/public/stylesheets/style.css +++ b/src/public/stylesheets/style.css @@ -540,25 +540,6 @@ div[data-notify="container"] { font-size: 150%; } -#export-form .form-check { - padding-top: 10px; - padding-bottom: 10px; -} - -#export-form .format-choice { - padding-left: 40px; - display: none; -} - -#export-form #opml-versions { - padding-left: 60px; - display: none; -} - -#export-form .form-check-label { - padding: 2px; -} - .ck-editor__is-empty.ck-content.ck-editor__editable::before { content: 'You can start writing note here ...'; position: absolute; diff --git a/src/views/desktop.ejs b/src/views/desktop.ejs index f93d173bd..568fd80cf 100644 --- a/src/views/desktop.ejs +++ b/src/views/desktop.ejs @@ -17,7 +17,6 @@ -<%- include('dialogs/export.ejs') %> <%- include('dialogs/markdown_import.ejs') %> <%- include('dialogs/note_revisions.ejs') %> <%- include('dialogs/options.ejs') %> diff --git a/src/views/dialogs/export.ejs b/src/views/dialogs/export.ejs deleted file mode 100644 index 4c09a2213..000000000 --- a/src/views/dialogs/export.ejs +++ /dev/null @@ -1,79 +0,0 @@ -