diff --git a/apps/client/src/layouts/desktop_layout.tsx b/apps/client/src/layouts/desktop_layout.tsx
index 35de1a868..79e8d2da4 100644
--- a/apps/client/src/layouts/desktop_layout.tsx
+++ b/apps/client/src/layouts/desktop_layout.tsx
@@ -11,7 +11,6 @@ import NoteListWidget from "../widgets/note_list.js";
import SqlResultWidget from "../widgets/sql_result.js";
import SqlTableSchemasWidget from "../widgets/sql_table_schemas.js";
import NoteIconWidget from "../widgets/note_icon.jsx";
-import SearchResultWidget from "../widgets/search_result.js";
import ScrollingContainer from "../widgets/containers/scrolling_container.js";
import RootContainer from "../widgets/containers/root_container.js";
import WatchedFileUpdateStatusWidget from "../widgets/watched_file_update_status.js";
@@ -42,6 +41,7 @@ import { applyModals } from "./layout_commons.js";
import Ribbon from "../widgets/ribbon/Ribbon.jsx";
import FloatingButtons from "../widgets/FloatingButtons.jsx";
import { DESKTOP_FLOATING_BUTTONS } from "../widgets/FloatingButtonsDefinitions.jsx";
+import SearchResult from "../widgets/search_result.jsx";
export default class DesktopLayout {
@@ -139,7 +139,7 @@ export default class DesktopLayout {
.child(new SqlTableSchemasWidget())
.child(new NoteDetailWidget())
.child(new NoteListWidget(false))
- .child(new SearchResultWidget())
+ .child()
.child(new SqlResultWidget())
.child()
)
diff --git a/apps/client/src/widgets/react/Alert.tsx b/apps/client/src/widgets/react/Alert.tsx
index 8b8afb68b..e57960157 100644
--- a/apps/client/src/widgets/react/Alert.tsx
+++ b/apps/client/src/widgets/react/Alert.tsx
@@ -4,11 +4,12 @@ interface AlertProps {
type: "info" | "danger" | "warning";
title?: string;
children: ComponentChildren;
+ className?: string;
}
-export default function Alert({ title, type, children }: AlertProps) {
+export default function Alert({ title, type, children, className }: AlertProps) {
return (
-
+
{title &&
{title}
}
{children}
diff --git a/apps/client/src/widgets/search_result.css b/apps/client/src/widgets/search_result.css
new file mode 100644
index 000000000..5142bd776
--- /dev/null
+++ b/apps/client/src/widgets/search_result.css
@@ -0,0 +1,16 @@
+.search-result-widget {
+ flex-grow: 100000;
+ flex-shrink: 100000;
+ min-height: 0;
+ overflow: auto;
+ contain: none !important;
+}
+
+.search-result-widget .note-list {
+ padding: 10px;
+}
+
+.search-no-results, .search-not-executed-yet {
+ margin: 20px;
+ padding: 20px !important;
+}
\ No newline at end of file
diff --git a/apps/client/src/widgets/search_result.ts b/apps/client/src/widgets/search_result.ts
deleted file mode 100644
index 6fa69ae13..000000000
--- a/apps/client/src/widgets/search_result.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import { t } from "../services/i18n.js";
-import NoteContextAwareWidget from "./note_context_aware_widget.js";
-import NoteListRenderer from "../services/note_list_renderer.js";
-import type FNote from "../entities/fnote.js";
-import type { EventData } from "../components/app_context.js";
-
-const TPL = /*html*/`
-
`;
-
-export default class SearchResultWidget extends NoteContextAwareWidget {
-
- private $content!: JQuery
;
- private $noResults!: JQuery;
- private $notExecutedYet!: JQuery;
-
- isEnabled() {
- return super.isEnabled() && this.note?.type === "search";
- }
-
- doRender() {
- this.$widget = $(TPL);
- this.contentSized();
- this.$content = this.$widget.find(".search-result-widget-content");
- this.$noResults = this.$widget.find(".search-no-results");
- this.$notExecutedYet = this.$widget.find(".search-not-executed-yet");
- }
-
- async refreshWithNote(note: FNote) {
- const noResults = note.getChildNoteIds().length === 0 && !!note.searchResultsLoaded;
-
- this.$content.empty();
- this.$noResults.toggle(noResults);
- this.$notExecutedYet.toggle(!note.searchResultsLoaded);
-
- if (noResults || !note.searchResultsLoaded) {
- return;
- }
-
- const noteListRenderer = new NoteListRenderer({
- $parent: this.$content,
- parentNote: note,
- showNotePath: true
- });
- await noteListRenderer.renderList();
- }
-
- searchRefreshedEvent({ ntxId }: EventData<"searchRefreshed">) {
- if (!this.isNoteContext(ntxId)) {
- return;
- }
-
- this.refresh();
- }
-
- notesReloadedEvent({ noteIds }: EventData<"notesReloaded">) {
- if (this.noteId && noteIds.includes(this.noteId)) {
- this.refresh();
- }
- }
-}
diff --git a/apps/client/src/widgets/search_result.tsx b/apps/client/src/widgets/search_result.tsx
new file mode 100644
index 000000000..3392fbc69
--- /dev/null
+++ b/apps/client/src/widgets/search_result.tsx
@@ -0,0 +1,63 @@
+import { useEffect, useRef, useState } from "preact/hooks";
+import { t } from "../services/i18n";
+import Alert from "./react/Alert";
+import { useNoteContext, useNoteProperty, useTriliumEvent } from "./react/hooks";
+import "./search_result.css";
+import NoteListRenderer from "../services/note_list_renderer";
+
+enum SearchResultState {
+ NO_RESULTS,
+ NOT_EXECUTED,
+ GOT_RESULTS
+}
+
+export default function SearchResult() {
+ const { note, ntxId } = useNoteContext();
+ const [ state, setState ] = useState();
+ const searchContainerRef = useRef(null);
+
+ function refresh() {
+ searchContainerRef.current?.replaceChildren();
+
+ if (!note?.searchResultsLoaded) {
+ setState(SearchResultState.NOT_EXECUTED);
+ } else if (note.getChildNoteIds().length === 0) {
+ setState(SearchResultState.NO_RESULTS);
+ } else if (searchContainerRef.current) {
+ setState(SearchResultState.GOT_RESULTS);
+
+ const noteListRenderer = new NoteListRenderer({
+ $parent: $(searchContainerRef.current),
+ parentNote: note,
+ showNotePath: true
+ });
+ noteListRenderer.renderList();
+ }
+ }
+
+ useEffect(() => refresh(), [ note ]);
+ useTriliumEvent("searchRefreshed", ({ ntxId: eventNtxId }) => {
+ if (eventNtxId === ntxId) {
+ refresh();
+ }
+ });
+ useTriliumEvent("notesReloaded", ({ noteIds }) => {
+ if (note?.noteId && noteIds.includes(note.noteId)) {
+ refresh();
+ }
+ });
+
+ return (
+
+ {state === SearchResultState.NOT_EXECUTED && (
+
{t("search_result.search_not_executed")}
+ )}
+
+ {state === SearchResultState.NO_RESULTS && (
+
{t("search_result.no_notes_found")}
+ )}
+
+
+
+ );
+}
\ No newline at end of file