diff --git a/apps/client/src/translations/cn/translation.json b/apps/client/src/translations/cn/translation.json index 06cbe505b..5eb6608a5 100644 --- a/apps/client/src/translations/cn/translation.json +++ b/apps/client/src/translations/cn/translation.json @@ -226,7 +226,7 @@ "notes_to_move": "需要移动的笔记", "target_parent_note": "目标父笔记", "search_placeholder": "通过名称搜索笔记", - "move_button": "移动到选定的笔记 回车", + "move_button": "移动到选定的笔记", "error_no_path": "没有可以移动到的路径。", "move_success_message": "所选笔记已移动到" }, diff --git a/apps/client/src/translations/de/translation.json b/apps/client/src/translations/de/translation.json index 5c4cba217..81277edb3 100644 --- a/apps/client/src/translations/de/translation.json +++ b/apps/client/src/translations/de/translation.json @@ -226,7 +226,7 @@ "notes_to_move": "Notizen zum Verschieben", "target_parent_note": "Ziel-Elternnotiz", "search_placeholder": "Suche nach einer Notiz anhand ihres Namens", - "move_button": "Zur ausgewählten Notiz wechseln Eingabetaste", + "move_button": "Zur ausgewählten Notiz wechseln", "error_no_path": "Kein Weg, auf den man sich bewegen kann.", "move_success_message": "Ausgewählte Notizen wurden verschoben" }, diff --git a/apps/client/src/translations/en/translation.json b/apps/client/src/translations/en/translation.json index 6084e007c..e76012cf3 100644 --- a/apps/client/src/translations/en/translation.json +++ b/apps/client/src/translations/en/translation.json @@ -228,7 +228,7 @@ "notes_to_move": "Notes to move", "target_parent_note": "Target parent note", "search_placeholder": "search for note by its name", - "move_button": "Move to selected note enter", + "move_button": "Move to selected note", "error_no_path": "No path to move to.", "move_success_message": "Selected notes have been moved into " }, diff --git a/apps/client/src/translations/es/translation.json b/apps/client/src/translations/es/translation.json index 1161e521a..fd0326ce4 100644 --- a/apps/client/src/translations/es/translation.json +++ b/apps/client/src/translations/es/translation.json @@ -227,7 +227,7 @@ "notes_to_move": "Notas a mover", "target_parent_note": "Nota padre de destino", "search_placeholder": "buscar nota por su nombre", - "move_button": "Mover a la nota seleccionada enter", + "move_button": "Mover a la nota seleccionada", "error_no_path": "No hay ruta a donde mover.", "move_success_message": "Las notas seleccionadas se han movido a " }, diff --git a/apps/client/src/translations/fr/translation.json b/apps/client/src/translations/fr/translation.json index 671d44f27..fe6869abc 100644 --- a/apps/client/src/translations/fr/translation.json +++ b/apps/client/src/translations/fr/translation.json @@ -226,7 +226,7 @@ "notes_to_move": "Notes à déplacer", "target_parent_note": "Note parent cible", "search_placeholder": "rechercher une note par son nom", - "move_button": "Déplacer vers la note sélectionnée entrer", + "move_button": "Déplacer vers la note sélectionnée", "error_no_path": "Aucun chemin vers lequel déplacer.", "move_success_message": "Les notes sélectionnées ont été déplacées dans " }, diff --git a/apps/client/src/translations/ro/translation.json b/apps/client/src/translations/ro/translation.json index c121badc3..7c1c326a2 100644 --- a/apps/client/src/translations/ro/translation.json +++ b/apps/client/src/translations/ro/translation.json @@ -817,7 +817,7 @@ "move_to": { "dialog_title": "Mută notițele în...", "error_no_path": "Nicio cale la care să poată fi mutate.", - "move_button": "Mută la notița selectată enter", + "move_button": "Mută la notița selectată", "move_success_message": "Notițele selectate au fost mutate în", "notes_to_move": "Notițe de mutat", "search_placeholder": "căutați notița după denumirea ei", diff --git a/apps/client/src/translations/sr/translation.json b/apps/client/src/translations/sr/translation.json index 5e678a481..816c2f89d 100644 --- a/apps/client/src/translations/sr/translation.json +++ b/apps/client/src/translations/sr/translation.json @@ -228,7 +228,7 @@ "notes_to_move": "Beleške za premeštanje", "target_parent_note": "Ciljana nadbeleška", "search_placeholder": "potraži belešku po njenom imenu", - "move_button": "Pređi na izabranu belešku enter", + "move_button": "Pređi na izabranu belešku", "error_no_path": "Nema putanje za premeštanje.", "move_success_message": "Izabrane beleške su premeštene u " }, diff --git a/apps/client/src/translations/tw/translation.json b/apps/client/src/translations/tw/translation.json index b327471cf..59eec1d0b 100644 --- a/apps/client/src/translations/tw/translation.json +++ b/apps/client/src/translations/tw/translation.json @@ -207,7 +207,7 @@ "notes_to_move": "需要移動的筆記", "target_parent_note": "目標上級筆記", "search_placeholder": "通過名稱搜尋筆記", - "move_button": "移動到選定的筆記 Enter", + "move_button": "移動到選定的筆記", "error_no_path": "沒有可以移動到的路徑。", "move_success_message": "已移動所選筆記到 " }, diff --git a/apps/client/src/widgets/dialogs/clone_to.tsx b/apps/client/src/widgets/dialogs/clone_to.tsx index b86b231f4..f81a0c242 100644 --- a/apps/client/src/widgets/dialogs/clone_to.tsx +++ b/apps/client/src/widgets/dialogs/clone_to.tsx @@ -1,4 +1,4 @@ -import { CSSProperties, useRef, useState } from "preact/compat"; +import { useRef, useState } from "preact/compat"; import appContext, { EventData } from "../../components/app_context"; import { closeActiveDialog, openDialog } from "../../services/dialog"; import { t } from "../../services/i18n"; @@ -6,8 +6,6 @@ import Modal from "../react/Modal"; import ReactBasicWidget from "../react/ReactBasicWidget"; import NoteAutocomplete from "../react/NoteAutocomplete"; import froca from "../../services/froca"; -import { useEffect } from "react"; -import FNote from "../../entities/fnote"; import FormGroup from "../react/FormGroup"; import FormTextBox from "../react/FormTextBox"; import Button from "../react/Button"; @@ -16,6 +14,7 @@ import { logError } from "../../services/ws"; import tree from "../../services/tree"; import branches from "../../services/branches"; import toast from "../../services/toast"; +import NoteList from "../react/NoteList"; interface CloneToDialogProps { clonedNoteIds: string[]; @@ -66,26 +65,6 @@ function CloneToDialogComponent({ clonedNoteIds }: CloneToDialogProps) { ) } -function NoteList({ noteIds, style }: { noteIds?: string[], style: CSSProperties }) { - const [ notes, setNotes ] = useState([]); - - useEffect(() => { - if (noteIds) { - froca.getNotes(noteIds).then((notes) => setNotes(notes)); - } - }, [noteIds]); - - return (notes && - - ); -} - export default class CloneToDialog extends ReactBasicWidget { private props: CloneToDialogProps; diff --git a/apps/client/src/widgets/dialogs/move_to.ts b/apps/client/src/widgets/dialogs/move_to.ts deleted file mode 100644 index 49e016f15..000000000 --- a/apps/client/src/widgets/dialogs/move_to.ts +++ /dev/null @@ -1,120 +0,0 @@ -import noteAutocompleteService from "../../services/note_autocomplete.js"; -import toastService from "../../services/toast.js"; -import froca from "../../services/froca.js"; -import branchService from "../../services/branches.js"; -import treeService from "../../services/tree.js"; -import BasicWidget from "../basic_widget.js"; -import { t } from "../../services/i18n.js"; -import type { EventData } from "../../components/app_context.js"; -import { openDialog } from "../../services/dialog.js"; - -const TPL = /*html*/` -`; - -export default class MoveToDialog extends BasicWidget { - - private movedBranchIds: string[] | null; - private $form!: JQuery; - private $noteAutoComplete!: JQuery; - private $noteList!: JQuery; - - constructor() { - super(); - - this.movedBranchIds = null; - } - - doRender() { - this.$widget = $(TPL); - this.$form = this.$widget.find(".move-to-form"); - this.$noteAutoComplete = this.$widget.find(".move-to-note-autocomplete"); - this.$noteList = this.$widget.find(".move-to-note-list"); - - this.$form.on("submit", () => { - const notePath = this.$noteAutoComplete.getSelectedNotePath(); - - if (notePath) { - this.$widget.modal("hide"); - - const { noteId, parentNoteId } = treeService.getNoteIdAndParentIdFromUrl(notePath); - if (parentNoteId) { - froca.getBranchId(parentNoteId, noteId).then((branchId) => { - if (branchId) { - this.moveNotesTo(branchId); - } - }); - } - } else { - logError(t("move_to.error_no_path")); - } - - return false; - }); - } - - async moveBranchIdsToEvent({ branchIds }: EventData<"moveBranchIdsTo">) { - this.movedBranchIds = branchIds; - - openDialog(this.$widget); - - this.$noteAutoComplete.val("").trigger("focus"); - - this.$noteList.empty(); - - for (const branchId of this.movedBranchIds) { - const branch = froca.getBranch(branchId); - if (!branch) { - continue; - } - - const note = await froca.getNote(branch.noteId); - if (!note) { - continue; - } - - this.$noteList.append($("
  • ").text(note.title)); - } - - noteAutocompleteService.initNoteAutocomplete(this.$noteAutoComplete); - noteAutocompleteService.showRecentNotes(this.$noteAutoComplete); - } - - async moveNotesTo(parentBranchId: string) { - if (this.movedBranchIds) { - await branchService.moveToParentNote(this.movedBranchIds, parentBranchId); - } - - const parentBranch = froca.getBranch(parentBranchId); - const parentNote = await parentBranch?.getNote(); - - toastService.showMessage(`${t("move_to.move_success_message")} ${parentNote?.title}`); - } -} diff --git a/apps/client/src/widgets/dialogs/move_to.tsx b/apps/client/src/widgets/dialogs/move_to.tsx new file mode 100644 index 000000000..0038af598 --- /dev/null +++ b/apps/client/src/widgets/dialogs/move_to.tsx @@ -0,0 +1,95 @@ +import ReactBasicWidget from "../react/ReactBasicWidget"; +import Modal from "../react/Modal"; +import { t } from "../../services/i18n"; +import { closeActiveDialog, openDialog } from "../../services/dialog"; +import { EventData } from "../../components/app_context"; +import NoteList from "../react/NoteList"; +import FormGroup from "../react/FormGroup"; +import NoteAutocomplete from "../react/NoteAutocomplete"; +import Button from "../react/Button"; +import { useRef, useState } from "preact/compat"; +import note_autocomplete, { Suggestion } from "../../services/note_autocomplete"; +import tree from "../../services/tree"; +import froca from "../../services/froca"; +import branches from "../../services/branches"; +import toast from "../../services/toast"; + +interface MoveToDialogProps { + movedBranchIds?: string[]; +} + +function MoveToDialogComponent({ movedBranchIds }: MoveToDialogProps) { + const [ suggestion, setSuggestion ] = useState(null); + const autoCompleteRef = useRef(null); + + async function onSubmit() { + const notePath = suggestion?.notePath; + if (!notePath) { + logError(t("move_to.error_no_path")); + return; + } + + closeActiveDialog(); + const { noteId, parentNoteId } = tree.getNoteIdAndParentIdFromUrl(notePath); + if (!parentNoteId) { + return; + } + + const branchId = await froca.getBranchId(parentNoteId, noteId); + if (branchId) { + moveNotesTo(movedBranchIds, branchId); + } + } + + return ( + } + onSubmit={onSubmit} + onShown={() => { + autoCompleteRef.current?.focus(); + note_autocomplete.showRecentNotes($(autoCompleteRef.current)); + }} + > +
    {t("move_to.notes_to_move")}
    + + + + + +
    + ) +} + +export default class MoveToDialog extends ReactBasicWidget { + + private props: MoveToDialogProps = {}; + + get component() { + return ; + } + + async moveBranchIdsToEvent({ branchIds }: EventData<"moveBranchIdsTo">) { + const movedBranchIds = branchIds; + this.props = { movedBranchIds }; + this.doRender(); + openDialog(this.$widget); + } + +} + +async function moveNotesTo(movedBranchIds: string[] | undefined, parentBranchId: string) { + if (movedBranchIds) { + await branches.moveToParentNote(movedBranchIds, parentBranchId); + } + + const parentBranch = froca.getBranch(parentBranchId); + const parentNote = await parentBranch?.getNote(); + + toast.showMessage(`${t("move_to.move_success_message")} ${parentNote?.title}`); +} \ No newline at end of file diff --git a/apps/client/src/widgets/react/NoteList.tsx b/apps/client/src/widgets/react/NoteList.tsx new file mode 100644 index 000000000..db84995c0 --- /dev/null +++ b/apps/client/src/widgets/react/NoteList.tsx @@ -0,0 +1,36 @@ +import { useEffect, useState } from "preact/hooks"; +import type FNote from "../../entities/fnote"; +import froca from "../../services/froca"; +import { CSSProperties } from "preact/compat"; + +interface NoteListProps { + noteIds?: string[]; + branchIds?: string[]; + style?: CSSProperties; +} + +export default function NoteList({ noteIds, branchIds, style }: NoteListProps) { + const [ notes, setNotes ] = useState([]); + + useEffect(() => { + let notesToLoad: string[]; + if (noteIds) { + notesToLoad = noteIds; + } else if (branchIds) { + notesToLoad = froca.getBranches(branchIds).map(b => b.noteId); + } else { + notesToLoad = []; + } + froca.getNotes(notesToLoad).then((notes) => setNotes(notes)); + }, [noteIds, branchIds]); + + return (notes && +
      + {notes.map(note => ( +
    • + {note.title} +
    • + ))} +
    + ); +} \ No newline at end of file