From 8d27a5aa39ba888160e00dc323314ecbcb7c859a Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Thu, 7 Aug 2025 19:20:35 +0300 Subject: [PATCH] feat(react/dialogs): port import --- apps/client/src/widgets/dialogs/import.ts | 180 ------------------ apps/client/src/widgets/dialogs/import.tsx | 109 +++++++++++ .../client/src/widgets/react/FormCheckbox.tsx | 3 +- apps/client/src/widgets/react/FormGroup.tsx | 2 +- 4 files changed, 112 insertions(+), 182 deletions(-) delete mode 100644 apps/client/src/widgets/dialogs/import.ts create mode 100644 apps/client/src/widgets/dialogs/import.tsx diff --git a/apps/client/src/widgets/dialogs/import.ts b/apps/client/src/widgets/dialogs/import.ts deleted file mode 100644 index c8cd66a27..000000000 --- a/apps/client/src/widgets/dialogs/import.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { escapeQuotes } from "../../services/utils.js"; -import treeService from "../../services/tree.js"; -import importService, { type UploadFilesOptions } from "../../services/import.js"; -import options from "../../services/options.js"; -import BasicWidget from "../basic_widget.js"; -import { t } from "../../services/i18n.js"; -import { Modal, Tooltip } from "bootstrap"; -import type { EventData } from "../../components/app_context.js"; -import { openDialog } from "../../services/dialog.js"; - -const TPL = /*html*/` -`; - -export default class ImportDialog extends BasicWidget { - - private parentNoteId: string | null; - - private $form!: JQuery; - private $noteTitle!: JQuery; - private $fileUploadInput!: JQuery; - private $importButton!: JQuery; - private $safeImportCheckbox!: JQuery; - private $shrinkImagesCheckbox!: JQuery; - private $textImportedAsTextCheckbox!: JQuery; - private $codeImportedAsCodeCheckbox!: JQuery; - private $explodeArchivesCheckbox!: JQuery; - private $replaceUnderscoresWithSpacesCheckbox!: JQuery; - - constructor() { - super(); - - this.parentNoteId = null; - } - - doRender() { - this.$widget = $(TPL); - Modal.getOrCreateInstance(this.$widget[0]); - - this.$form = this.$widget.find(".import-form"); - this.$noteTitle = this.$widget.find(".import-note-title"); - this.$fileUploadInput = this.$widget.find(".import-file-upload-input"); - this.$importButton = this.$widget.find(".import-button"); - this.$safeImportCheckbox = this.$widget.find(".safe-import-checkbox"); - this.$shrinkImagesCheckbox = this.$widget.find(".shrink-images-checkbox"); - this.$textImportedAsTextCheckbox = this.$widget.find(".text-imported-as-text-checkbox"); - this.$codeImportedAsCodeCheckbox = this.$widget.find(".code-imported-as-code-checkbox"); - this.$explodeArchivesCheckbox = this.$widget.find(".explode-archives-checkbox"); - this.$replaceUnderscoresWithSpacesCheckbox = this.$widget.find(".replace-underscores-with-spaces-checkbox"); - - this.$form.on("submit", () => { - // disabling so that import is not triggered again. - this.$importButton.attr("disabled", "disabled"); - - if (this.parentNoteId) { - this.importIntoNote(this.parentNoteId); - } - - return false; - }); - - this.$fileUploadInput.on("change", () => { - if (this.$fileUploadInput.val()) { - this.$importButton.removeAttr("disabled"); - } else { - this.$importButton.attr("disabled", "disabled"); - } - }); - - let _ = [...this.$widget.find('[data-bs-toggle="tooltip"]')].forEach((element) => { - Tooltip.getOrCreateInstance(element, { - html: true - }); - }); - } - - async showImportDialogEvent({ noteId }: EventData<"showImportDialog">) { - this.parentNoteId = noteId; - - this.$fileUploadInput.val("").trigger("change"); // to trigger Import button disabling listener below - - this.$safeImportCheckbox.prop("checked", true); - this.$shrinkImagesCheckbox.prop("checked", options.is("compressImages")); - this.$textImportedAsTextCheckbox.prop("checked", true); - this.$codeImportedAsCodeCheckbox.prop("checked", true); - this.$explodeArchivesCheckbox.prop("checked", true); - this.$replaceUnderscoresWithSpacesCheckbox.prop("checked", true); - - this.$noteTitle.text(await treeService.getNoteTitle(this.parentNoteId)); - - openDialog(this.$widget); - } - - async importIntoNote(parentNoteId: string) { - const files = Array.from(this.$fileUploadInput[0].files ?? []); // shallow copy since we're resetting the upload button below - - const boolToString = ($el: JQuery) => ($el.is(":checked") ? "true" : "false"); - - const options: UploadFilesOptions = { - safeImport: boolToString(this.$safeImportCheckbox), - shrinkImages: boolToString(this.$shrinkImagesCheckbox), - textImportedAsText: boolToString(this.$textImportedAsTextCheckbox), - codeImportedAsCode: boolToString(this.$codeImportedAsCodeCheckbox), - explodeArchives: boolToString(this.$explodeArchivesCheckbox), - replaceUnderscoresWithSpaces: boolToString(this.$replaceUnderscoresWithSpacesCheckbox) - }; - - this.$widget.modal("hide"); - - await importService.uploadFiles("notes", parentNoteId, files, options); - } -} diff --git a/apps/client/src/widgets/dialogs/import.tsx b/apps/client/src/widgets/dialogs/import.tsx new file mode 100644 index 000000000..2e587c013 --- /dev/null +++ b/apps/client/src/widgets/dialogs/import.tsx @@ -0,0 +1,109 @@ +import { useState } from "preact/hooks"; +import { EventData } from "../../components/app_context"; +import { closeActiveDialog, openDialog } from "../../services/dialog"; +import { t } from "../../services/i18n"; +import tree from "../../services/tree"; +import Button from "../react/Button"; +import FormCheckbox from "../react/FormCheckbox"; +import FormFileUpload from "../react/FormFileUpload"; +import FormGroup from "../react/FormGroup"; +import Modal from "../react/Modal"; +import RawHtml from "../react/RawHtml"; +import ReactBasicWidget from "../react/ReactBasicWidget"; +import importService, { UploadFilesOptions } from "../../services/import"; + +interface ImportDialogComponentProps { + parentNoteId?: string; + noteTitle?: string; +} + +function ImportDialogComponent({ parentNoteId, noteTitle }: ImportDialogComponentProps) { + const [ files, setFiles ] = useState(null); + const [ safeImport, setSafeImport ] = useState(true); + const [ explodeArchives, setExplodeArchives ] = useState(true); + const [ shrinkImages, setShrinkImages ] = useState(true); + const [ textImportedAsText, setTextImportedAsText ] = useState(true); + const [ codeImportedAsCode, setCodeImportedAsCode ] = useState(true); + const [ replaceUnderscoresWithSpaces, setReplaceUnderscoresWithSpaces ] = useState(true); + + return (parentNoteId && + { + if (!files) { + return; + } + + const options: UploadFilesOptions = { + safeImport: boolToString(safeImport), + shrinkImages: boolToString(shrinkImages), + textImportedAsText: boolToString(textImportedAsText), + codeImportedAsCode: boolToString(codeImportedAsCode), + explodeArchives: boolToString(explodeArchives), + replaceUnderscoresWithSpaces: boolToString(replaceUnderscoresWithSpaces) + }; + + closeActiveDialog(); + await importService.uploadFiles("notes", parentNoteId, Array.from(files), options); + }} + footer={