From 3dbf20af520685ab1f4f3cadd395d0a12aeba5f9 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Fri, 19 Sep 2025 18:08:21 +0300 Subject: [PATCH] chore(react/type_widget): port empty search --- apps/client/src/widgets/NoteDetail.tsx | 20 +++++- .../client/src/widgets/type_widgets/Empty.css | 38 ++++++++++ .../client/src/widgets/type_widgets/Empty.tsx | 57 +++++++++++++++ .../src/widgets/type_widgets_old/empty.ts | 72 +------------------ 4 files changed, 115 insertions(+), 72 deletions(-) create mode 100644 apps/client/src/widgets/type_widgets/Empty.css diff --git a/apps/client/src/widgets/NoteDetail.tsx b/apps/client/src/widgets/NoteDetail.tsx index bdc35bf61..bb4a3444f 100644 --- a/apps/client/src/widgets/NoteDetail.tsx +++ b/apps/client/src/widgets/NoteDetail.tsx @@ -4,6 +4,8 @@ import FNote from "../entities/fnote"; import protected_session_holder from "../services/protected_session_holder"; import { useEffect, useState } from "preact/hooks"; import NoteContext from "../components/note_context"; +import Empty from "./type_widgets/Empty"; +import { VNode } from "preact"; /** * A `NoteType` altered by the note detail widget, taking into consideration whether the note is editable or not and adding special note types such as an empty one, @@ -16,8 +18,15 @@ type ExtendedNoteType = Exclude | "empty */ export default function NoteDetail() { const { note, type } = useNoteInfo(); + const [ correspondingWidget, setCorrespondingWidget ] = useState(); - return

Note detail goes here! {note?.title} of {type}

+ useEffect(() => setCorrespondingWidget(getCorrespondingWidget(type)), [ type ]); + + return ( +
+ {correspondingWidget ||

Note detail goes here! {note?.title} of {type}

} +
+ ); } /** Manages both note changes and changes to the widget type, which are asynchronous. */ @@ -36,6 +45,15 @@ function useNoteInfo() { return { note, type }; } +function getCorrespondingWidget(noteType: ExtendedNoteType | undefined) { + switch (noteType) { + case "empty": + return + default: + break; + } +} + async function getWidgetType(note: FNote | null | undefined, noteContext: NoteContext | undefined): Promise { if (!note) { return "empty"; diff --git a/apps/client/src/widgets/type_widgets/Empty.css b/apps/client/src/widgets/type_widgets/Empty.css new file mode 100644 index 000000000..c207f6524 --- /dev/null +++ b/apps/client/src/widgets/type_widgets/Empty.css @@ -0,0 +1,38 @@ +.workspace-notes { + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: space-evenly; +} + +.workspace-notes .workspace-note { + width: 130px; + text-align: center; + margin: 10px; + border: 1px transparent solid; +} + +.workspace-notes .workspace-note:hover { + cursor: pointer; + border: 1px solid var(--main-border-color); +} + +.note-detail-empty-results .aa-dropdown-menu { + max-height: 50vh; + overflow: scroll; + border: var(--bs-border-width) solid var(--bs-border-color); + border-top: 0; +} + +.empty-tab-search .note-autocomplete-input { + border-bottom-left-radius: 0; +} + +.empty-tab-search .input-clearer-button { + border-bottom-right-radius: 0; +} + +.workspace-icon { + text-align: center; + font-size: 500%; +} \ No newline at end of file diff --git a/apps/client/src/widgets/type_widgets/Empty.tsx b/apps/client/src/widgets/type_widgets/Empty.tsx index e69de29bb..739731bf9 100644 --- a/apps/client/src/widgets/type_widgets/Empty.tsx +++ b/apps/client/src/widgets/type_widgets/Empty.tsx @@ -0,0 +1,57 @@ +import { useEffect, useRef } from "preact/hooks"; +import { t } from "../../services/i18n"; +import FormGroup from "../react/FormGroup"; +import NoteAutocomplete from "../react/NoteAutocomplete"; +import "./Empty.css"; +import { refToJQuerySelector } from "../react/react_utils"; +import note_autocomplete from "../../services/note_autocomplete"; +import appContext from "../../components/app_context"; + +export default function Empty() { + return ( +
+
+ + +
+ ) +} + +function NoteSearch() { + const resultsContainerRef = useRef(null); + const autocompleteRef = useRef(null); + + // Show recent notes. + useEffect(() => { + const $autoComplete = refToJQuerySelector(autocompleteRef); + note_autocomplete.showRecentNotes($autoComplete); + }, []); + + return ( + <> + + { + if (!suggestion?.notePath) { + return false; + } + + const activeContext = appContext.tabManager.getActiveContext(); + if (activeContext) { + activeContext.setNote(suggestion.notePath); + } + }} + /> + +
+ + ); +} diff --git a/apps/client/src/widgets/type_widgets_old/empty.ts b/apps/client/src/widgets/type_widgets_old/empty.ts index 3aed05d5f..55487cdac 100644 --- a/apps/client/src/widgets/type_widgets_old/empty.ts +++ b/apps/client/src/widgets/type_widgets_old/empty.ts @@ -5,57 +5,7 @@ import searchService from "../../services/search.js"; import { t } from "../../services/i18n.js"; const TPL = /*html*/` -
- - -
- -
-
`; +`; export default class EmptyTypeWidget extends TypeWidget { @@ -73,28 +23,8 @@ export default class EmptyTypeWidget extends TypeWidget { this.$widget = $(TPL); this.$autoComplete = this.$widget.find(".note-autocomplete"); this.$results = this.$widget.find(".note-detail-empty-results"); - - noteAutocompleteService - .initNoteAutocomplete(this.$autoComplete, { - hideGoToSelectedNoteButton: true, - allowCreatingNotes: true, - allowJumpToSearchNotes: true, - container: this.$results[0] - }) - .on("autocomplete:noteselected", function (event, suggestion, dataset) { - if (!suggestion.notePath) { - return false; - } - - const activeContext = appContext.tabManager.getActiveContext(); - if (activeContext) { - activeContext.setNote(suggestion.notePath); - } - }); - this.$workspaceNotes = this.$widget.find(".workspace-notes"); - noteAutocompleteService.showRecentNotes(this.$autoComplete); super.doRender(); }