From 3229b7d106e81b1909a6e1c25b81843ed0b46bd9 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 30 Aug 2025 11:31:49 +0300 Subject: [PATCH] feat(react/widgets): port api_log --- apps/client/src/layouts/desktop_layout.tsx | 5 +- apps/client/src/widgets/api_log.css | 26 +++++++ apps/client/src/widgets/api_log.ts | 80 ---------------------- apps/client/src/widgets/api_log.tsx | 41 +++++++++++ 4 files changed, 69 insertions(+), 83 deletions(-) create mode 100644 apps/client/src/widgets/api_log.css delete mode 100644 apps/client/src/widgets/api_log.ts create mode 100644 apps/client/src/widgets/api_log.tsx diff --git a/apps/client/src/layouts/desktop_layout.tsx b/apps/client/src/layouts/desktop_layout.tsx index fd2d6a5c4..8c2df7dda 100644 --- a/apps/client/src/layouts/desktop_layout.tsx +++ b/apps/client/src/layouts/desktop_layout.tsx @@ -13,7 +13,6 @@ import WatchedFileUpdateStatusWidget from "../widgets/watched_file_update_status import SpacerWidget from "../widgets/spacer.js"; import QuickSearchWidget from "../widgets/quick_search.js"; import SplitNoteContainer from "../widgets/containers/split_note_container.js"; -import LeftPaneToggleWidget from "../widgets/buttons/left_pane_toggle.js"; import CreatePaneButton from "../widgets/buttons/create_pane_button.js"; import ClosePaneButton from "../widgets/buttons/close_pane_button.js"; import RightPaneContainer from "../widgets/containers/right_pane_container.js"; @@ -24,7 +23,6 @@ import TocWidget from "../widgets/toc.js"; import HighlightsListWidget from "../widgets/highlights_list.js"; import PasswordNoteSetDialog from "../widgets/dialogs/password_not_set.js"; import LauncherContainer from "../widgets/containers/launcher_container.js"; -import ApiLogWidget from "../widgets/api_log.js"; import MovePaneButton from "../widgets/buttons/move_pane_button.js"; import UploadAttachmentsDialog from "../widgets/dialogs/upload_attachments.js"; import ScrollPadding from "../widgets/scroll_padding.js"; @@ -43,6 +41,7 @@ import SqlResults from "../widgets/sql_result.js"; import SqlTableSchemas from "../widgets/sql_table_schemas.js"; import TitleBarButtons from "../widgets/title_bar_buttons.jsx"; import LeftPaneToggle from "../widgets/buttons/left_pane_toggle.js"; +import ApiLog from "../widgets/api_log.jsx"; export default class DesktopLayout { @@ -144,7 +143,7 @@ export default class DesktopLayout { .child() .child() ) - .child(new ApiLogWidget()) + .child() .child(new FindWidget()) .child( ...this.customWidgets.get("node-detail-pane"), // typo, let's keep it for a while as BC diff --git a/apps/client/src/widgets/api_log.css b/apps/client/src/widgets/api_log.css new file mode 100644 index 000000000..26ab835bd --- /dev/null +++ b/apps/client/src/widgets/api_log.css @@ -0,0 +1,26 @@ +.api-log-widget { + padding: 15px; + flex-grow: 1; + max-height: 40%; + position: relative; +} + +.api-log-container { + overflow: auto; + height: 100%; + font-family: var(--monospace-font-family); + font-size: 0.8em; + white-space: pre; +} + +.close-api-log-button { + padding: 5px; + border: 1px solid var(--button-border-color); + background-color: var(--button-background-color); + border-radius: var(--button-border-radius); + color: var(--button-text-color); + position: absolute; + top: 10px; + right: 40px; + cursor: pointer; +} \ No newline at end of file diff --git a/apps/client/src/widgets/api_log.ts b/apps/client/src/widgets/api_log.ts deleted file mode 100644 index 02f7563e6..000000000 --- a/apps/client/src/widgets/api_log.ts +++ /dev/null @@ -1,80 +0,0 @@ -import type { EventData } from "../components/app_context.js"; -import type FNote from "../entities/fnote.js"; -import { t } from "../services/i18n.js"; -import NoteContextAwareWidget from "./note_context_aware_widget.js"; - -const TPL = /*html*/` -
- - -
- -
-
`; - -export default class ApiLogWidget extends NoteContextAwareWidget { - - private $logContainer!: JQuery; - private $closeButton!: JQuery; - - isEnabled() { - return !!this.note && this.note.mime.startsWith("application/javascript;env=") && super.isEnabled(); - } - - doRender() { - this.$widget = $(TPL); - this.toggle(false); - - this.$logContainer = this.$widget.find(".api-log-container"); - this.$closeButton = this.$widget.find(".close-api-log-button"); - this.$closeButton.on("click", () => this.toggle(false)); - } - - async refreshWithNote(note: FNote) { - this.$logContainer.empty(); - } - - apiLogMessagesEvent({ messages, noteId }: EventData<"apiLogMessages">) { - if (!this.isNote(noteId)) { - return; - } - - this.toggle(true); - - for (const message of messages) { - this.$logContainer.append(message).append($("
")); - } - } - - toggle(show: boolean) { - this.$widget.toggleClass("hidden-api-log", !show); - } -} diff --git a/apps/client/src/widgets/api_log.tsx b/apps/client/src/widgets/api_log.tsx new file mode 100644 index 000000000..ba0f8e095 --- /dev/null +++ b/apps/client/src/widgets/api_log.tsx @@ -0,0 +1,41 @@ +import { useEffect, useState } from "preact/hooks"; +import "./api_log.css"; +import { useNoteContext, useTriliumEvent } from "./react/hooks"; +import ActionButton from "./react/ActionButton"; +import { t } from "../services/i18n"; + +/** + * Displays the messages that are logged by the current note via `api.log`, for frontend and backend scripts. + */ +export default function ApiLog() { + const { note, noteId } = useNoteContext(); + const [ messages, setMessages ] = useState(); + + useTriliumEvent("apiLogMessages", ({ messages, noteId: eventNoteId }) => { + if (eventNoteId !== noteId) return; + setMessages(messages); + }); + + // Clear when navigating away. + useEffect(() => setMessages(undefined), [ note ]); + + const isEnabled = note?.mime.startsWith("application/javascript;env=") && messages?.length; + return ( +
+ {isEnabled && ( + <> + setMessages(undefined)} + /> + +
+ {messages.join("\n")} +
+ + )} +
+ ) +}