From 3361a2e4ab3da620e6e08c0ed8531cead33d78c5 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 3 Aug 2025 13:28:40 +0300 Subject: [PATCH 1/6] feat(react): set up client to support Preact with JSX --- apps/client/package.json | 1 + apps/client/tsconfig.app.json | 6 +++++- apps/client/vite.config.mts | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/client/package.json b/apps/client/package.json index 67fcb5c4f..e9c9a9de6 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -59,6 +59,7 @@ }, "devDependencies": { "@ckeditor/ckeditor5-inspector": "5.0.0", + "@preact/preset-vite": "2.10.2", "@types/bootstrap": "5.2.10", "@types/jquery": "3.5.32", "@types/leaflet": "1.9.20", diff --git a/apps/client/tsconfig.app.json b/apps/client/tsconfig.app.json index 20119a29f..f823b8cba 100644 --- a/apps/client/tsconfig.app.json +++ b/apps/client/tsconfig.app.json @@ -4,9 +4,13 @@ "lib": [ "ESNext" ], "outDir": "dist", "types": [ - "node" + "node", + "preact" ], "rootDir": "src", + "jsx": "preserve", + "jsxFactory": "h", + "jsxImportSource": "preact", "module": "esnext", "moduleResolution": "bundler", "tsBuildInfoFile": "dist/tsconfig.app.tsbuildinfo" diff --git a/apps/client/vite.config.mts b/apps/client/vite.config.mts index 81f9cf9a7..640313bff 100644 --- a/apps/client/vite.config.mts +++ b/apps/client/vite.config.mts @@ -4,6 +4,7 @@ import { defineConfig, type Plugin } from 'vite'; import { viteStaticCopy } from 'vite-plugin-static-copy' import asset_path from './src/asset_path'; import webpackStatsPlugin from 'rollup-plugin-webpack-stats'; +import preact from "@preact/preset-vite"; const assets = [ "assets", "stylesheets", "fonts", "translations" ]; @@ -20,6 +21,7 @@ export default defineConfig(() => ({ host: 'localhost', }, plugins: [ + preact(), viteStaticCopy({ targets: assets.map((asset) => ({ src: `src/${asset}/*`, From efeb9b90cac600868f027cef18e16d2af4e45fa2 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 3 Aug 2025 13:39:23 +0300 Subject: [PATCH 2/6] feat(react): basic integration for basic widget & modal --- apps/client/src/widgets/react/Modal.tsx | 11 +++++++++++ apps/client/src/widgets/react/ReactBasicWidget.ts | 14 ++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 apps/client/src/widgets/react/Modal.tsx create mode 100644 apps/client/src/widgets/react/ReactBasicWidget.ts diff --git a/apps/client/src/widgets/react/Modal.tsx b/apps/client/src/widgets/react/Modal.tsx new file mode 100644 index 000000000..718bc23a2 --- /dev/null +++ b/apps/client/src/widgets/react/Modal.tsx @@ -0,0 +1,11 @@ +export default function Modal({ children }) { + return ( +
+
+
+ {children} +
+
+
+ ); +} \ No newline at end of file diff --git a/apps/client/src/widgets/react/ReactBasicWidget.ts b/apps/client/src/widgets/react/ReactBasicWidget.ts new file mode 100644 index 000000000..c55564857 --- /dev/null +++ b/apps/client/src/widgets/react/ReactBasicWidget.ts @@ -0,0 +1,14 @@ +import { JSX, render } from "preact"; +import BasicWidget from "../basic_widget.js"; + +export default abstract class ReactBasicWidget extends BasicWidget { + + abstract get component(): JSX.Element; + + doRender() { + const renderContainer = new DocumentFragment(); + render(this.component, renderContainer); + this.$widget = $(renderContainer.firstChild as HTMLElement); + } + +} From a7f5702221aded983f8389917c86ae148e44d927 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 3 Aug 2025 15:29:57 +0300 Subject: [PATCH 3/6] feat(react): port about dialog --- .../src/translations/en/translation.json | 3 + apps/client/src/widgets/dialogs/about.ts | 117 ------------------ apps/client/src/widgets/dialogs/about.tsx | 98 +++++++++++++++ apps/client/src/widgets/react/Modal.tsx | 38 +++++- 4 files changed, 135 insertions(+), 121 deletions(-) delete mode 100644 apps/client/src/widgets/dialogs/about.ts create mode 100644 apps/client/src/widgets/dialogs/about.tsx diff --git a/apps/client/src/translations/en/translation.json b/apps/client/src/translations/en/translation.json index c59057709..09c336115 100644 --- a/apps/client/src/translations/en/translation.json +++ b/apps/client/src/translations/en/translation.json @@ -2005,5 +2005,8 @@ }, "content_renderer": { "open_externally": "Open externally" + }, + "modal": { + "close": "Close" } } diff --git a/apps/client/src/widgets/dialogs/about.ts b/apps/client/src/widgets/dialogs/about.ts deleted file mode 100644 index 2276a5214..000000000 --- a/apps/client/src/widgets/dialogs/about.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { formatDateTime } from "../../utils/formatters.js"; -import { t } from "../../services/i18n.js"; -import BasicWidget from "../basic_widget.js"; -import openService from "../../services/open.js"; -import server from "../../services/server.js"; -import utils from "../../services/utils.js"; -import { openDialog } from "../../services/dialog.js"; - -interface AppInfo { - appVersion: string; - dbVersion: number; - syncVersion: number; - buildDate: string; - buildRevision: string; - dataDirectory: string; -} - -const TPL = /*html*/` - - - -`; - -export default class AboutDialog extends BasicWidget { - private $appVersion!: JQuery; - private $dbVersion!: JQuery; - private $syncVersion!: JQuery; - private $buildDate!: JQuery; - private $buildRevision!: JQuery; - private $dataDirectory!: JQuery; - - doRender(): void { - this.$widget = $(TPL); - this.$appVersion = this.$widget.find(".app-version"); - this.$dbVersion = this.$widget.find(".db-version"); - this.$syncVersion = this.$widget.find(".sync-version"); - this.$buildDate = this.$widget.find(".build-date"); - this.$buildRevision = this.$widget.find(".build-revision"); - this.$dataDirectory = this.$widget.find(".data-directory"); - } - - async refresh() { - const appInfo = await server.get("app-info"); - - this.$appVersion.text(appInfo.appVersion); - this.$dbVersion.text(appInfo.dbVersion.toString()); - this.$syncVersion.text(appInfo.syncVersion.toString()); - this.$buildDate.text(formatDateTime(appInfo.buildDate)); - this.$buildRevision.text(appInfo.buildRevision); - this.$buildRevision.attr("href", `https://github.com/TriliumNext/Trilium/commit/${appInfo.buildRevision}`); - if (utils.isElectron()) { - this.$dataDirectory.html( - $("", { - href: "#", - class: "tn-link", - text: appInfo.dataDirectory - }).prop("outerHTML") - ); - this.$dataDirectory.find("a").on("click", (event: JQuery.ClickEvent) => { - event.preventDefault(); - openService.openDirectory(appInfo.dataDirectory); - }); - } else { - this.$dataDirectory.text(appInfo.dataDirectory); - } - } - - async openAboutDialogEvent() { - await this.refresh(); - openDialog(this.$widget); - } -} diff --git a/apps/client/src/widgets/dialogs/about.tsx b/apps/client/src/widgets/dialogs/about.tsx new file mode 100644 index 000000000..7d784627a --- /dev/null +++ b/apps/client/src/widgets/dialogs/about.tsx @@ -0,0 +1,98 @@ +import { openDialog } from "../../services/dialog.js"; +import ReactBasicWidget from "../react/ReactBasicWidget.js"; +import Modal from "../react/Modal.js"; +import { t } from "../../services/i18n.js"; +import { formatDateTime } from "../../utils/formatters.js"; +import { useState } from "react"; +import server from "../../services/server.js"; +import utils from "../../services/utils.js"; +import openService from "../../services/open.js"; + +interface AppInfo { + appVersion: string; + dbVersion: number; + syncVersion: number; + buildDate: string; + buildRevision: string; + dataDirectory: string; +} + +function AboutDialogComponent() { + let [appInfo, setAppInfo] = useState(null); + + async function onShown() { + const appInfo = await server.get("app-info"); + setAppInfo(appInfo); + } + + const forceWordBreak = { wordBreak: "break-all" }; + + return ( + + {(appInfo !== null) ? ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{t("about.homepage")}https://github.com/TriliumNext/Trilium
{t("about.app_version")}{appInfo.appVersion}
{t("about.db_version")}{appInfo.dbVersion}
{t("about.sync_version")}{appInfo.syncVersion}
{t("about.build_date")}{formatDateTime(appInfo.buildDate)}
{t("about.build_revision")} + {appInfo.buildRevision} +
{t("about.data_directory")} + +
+ ) : ( +
+ )} +
+ ); +} + +function DirectoryLink({ directory, style }: { directory: string, style?: React.CSSProperties }) { + if (utils.isElectron()) { + const onClick = (e: React.MouseEvent) => { + e.preventDefault(); + openService.openDirectory(directory); + }; + + return + } else { + return {directory}; + } +} + +export default class AboutDialog extends ReactBasicWidget { + + get component() { + return ; + } + + async openAboutDialogEvent() { + openDialog(this.$widget); + } +} \ No newline at end of file diff --git a/apps/client/src/widgets/react/Modal.tsx b/apps/client/src/widgets/react/Modal.tsx index 718bc23a2..1522a3947 100644 --- a/apps/client/src/widgets/react/Modal.tsx +++ b/apps/client/src/widgets/react/Modal.tsx @@ -1,9 +1,39 @@ -export default function Modal({ children }) { +import { useEffect, useRef } from "preact/hooks"; +import { t } from "../../services/i18n"; +import { ComponentChildren } from "preact"; + +interface ModalProps { + className: string; + title: string; + size: "lg" | "sm"; + children: ComponentChildren; + onShown?: () => void; +} + +export default function Modal({ children, className, size, title, onShown }: ModalProps) { + const modalRef = useRef(null); + + if (onShown) { + useEffect(() => { + const modalElement = modalRef.current; + if (modalElement) { + modalElement.addEventListener("shown.bs.modal", onShown); + } + }); + } + return ( -
-
+
+
- {children} +
+
{title}
+ +
+ +
+ {children} +
From 6eb650bb22d040c18ed350764cd8e53351d3af12 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 3 Aug 2025 15:30:01 +0300 Subject: [PATCH 4/6] chore(deps): update package lock --- pnpm-lock.yaml | 193 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 157 insertions(+), 36 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dfee16668..696f07752 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -301,6 +301,9 @@ importers: '@ckeditor/ckeditor5-inspector': specifier: 5.0.0 version: 5.0.0 + '@preact/preset-vite': + specifier: 2.10.2 + version: 2.10.2(@babel/core@7.28.0)(preact@10.27.0)(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)) '@types/bootstrap': specifier: 5.2.10 version: 5.2.10 @@ -897,7 +900,7 @@ importers: version: 8.38.0(eslint@9.32.0(jiti@2.5.1))(typescript@5.9.2) '@vitest/browser': specifier: ^3.0.5 - version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.1.0)(typescript@5.9.2))(playwright@1.54.2)(utf-8-validate@6.0.5)(vite@7.0.0(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))(vitest@3.2.4)(webdriverio@9.18.4(bufferutil@4.0.9)(utf-8-validate@6.0.5)) + version: 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.1.0)(typescript@5.9.2))(playwright@1.54.2)(utf-8-validate@6.0.5)(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))(vitest@3.2.4)(webdriverio@9.18.4(bufferutil@4.0.9)(utf-8-validate@6.0.5)) '@vitest/coverage-istanbul': specifier: ^3.0.5 version: 3.2.4(vitest@3.2.4) @@ -930,7 +933,7 @@ importers: version: 5.9.2 vite-plugin-svgo: specifier: ~2.0.0 - version: 2.0.0(typescript@5.9.2)(vite@7.0.0(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)) + version: 2.0.0(typescript@5.9.2)(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)) vitest: specifier: ^3.0.5 version: 3.2.4(@types/debug@4.1.12)(@types/node@24.1.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.1.0)(typescript@5.9.2))(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) @@ -1575,6 +1578,10 @@ packages: resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.27.2': resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} @@ -2047,6 +2054,18 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-react-jsx-development@7.27.1': + resolution: {integrity: sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx@7.27.1': + resolution: {integrity: sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-regenerator@7.27.0': resolution: {integrity: sha512-LX/vCajUJQDqE7Aum/ELUMZAY19+cDpghxrnyt5I1tV6X5PyC86AOoWXWFYFeIvauyeSA6/ktn4tQVn/3ZifsA==} engines: {node: '>=6.9.0'} @@ -4287,6 +4306,29 @@ packages: '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + '@preact/preset-vite@2.10.2': + resolution: {integrity: sha512-K9wHlJOtkE+cGqlyQ5v9kL3Ge0Ql4LlIZjkUTL+1zf3nNdF88F9UZN6VTV8jdzBX9Fl7WSzeNMSDG7qECPmSmg==} + peerDependencies: + '@babel/core': 7.x + vite: 2.x || 3.x || 4.x || 5.x || 6.x || 7.x + + '@prefresh/babel-plugin@0.5.2': + resolution: {integrity: sha512-AOl4HG6dAxWkJ5ndPHBgBa49oo/9bOiJuRDKHLSTyH+Fd9x00shTXpdiTj1W41l6oQIwUOAgJeHMn4QwIDpHkA==} + + '@prefresh/core@1.5.5': + resolution: {integrity: sha512-H6GTXUl4V4fe3ijz7yhSa/mZ+pGSOh7XaJb6uP/sQsagBx9yl0D1HKDaeoMQA8Ad2Xm27LqvbitMGSdY9UFSKQ==} + peerDependencies: + preact: 10.27.0 + + '@prefresh/utils@1.2.1': + resolution: {integrity: sha512-vq/sIuN5nYfYzvyayXI4C2QkprfNaHUQ9ZX+3xLD8nL3rWyzpxOm1+K7RtMbhd+66QcaISViK7amjnheQ/4WZw==} + + '@prefresh/vite@2.4.8': + resolution: {integrity: sha512-H7vlo9UbJInuRbZhRQrdgVqLP7qKjDoX7TgYWWwIVhEHeHO0hZ4zyicvwBrV1wX5A3EPOmArgRkUaN7cPI2VXQ==} + peerDependencies: + preact: 10.27.0 + vite: '>=2.0.0' + '@promptbook/utils@0.69.5': resolution: {integrity: sha512-xm5Ti/Hp3o4xHrsK9Yy3MS6KbDxYbq485hDsFvxqaNA7equHLPdo8H8faTitTeb14QCDfLW4iwCxdVYu5sn6YQ==} @@ -6781,6 +6823,11 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + babel-plugin-transform-hook-names@1.0.2: + resolution: {integrity: sha512-5gafyjyyBTTdX/tQQ0hRgu4AhNHG/hqWi0ZZmg2xvs2FgRkJXzDNKBZCyoYqgFkovfDrgM8OoKg8karoUvWeCw==} + peerDependencies: + '@babel/core': ^7.12.10 + babel-plugin-transform-typescript-metadata@0.3.2: resolution: {integrity: sha512-mWEvCQTgXQf48yDqgN7CH50waTyYBeP2Lpqx4nNWab9sxEpdXVeKgfj1qYI2/TgUPQtNFZ85i3PemRtnXVYYJg==} peerDependencies: @@ -11274,6 +11321,9 @@ packages: engines: {node: '>= 10.12.0'} hasBin: true + node-html-parser@6.1.13: + resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==} + node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} @@ -13574,6 +13624,9 @@ packages: resolution: {integrity: sha512-ZpzWAFHIFqyFE56dXqgX/DkDRZdz+rRcjoIk/RQU4IX0wiCv1l8S7ZrXDHcCc+uaf+6o7w3h2l3g6GYG5TKN9Q==} engines: {node: ^18.17.0 || >=20.5.0} + simple-code-frame@1.3.0: + resolution: {integrity: sha512-MB4pQmETUBlNs62BBeRjIFGeuy/x6gGKh7+eRUemn1rCFhqo7K+4slPqsyizCbcbYLnaYqaoZ2FWsZ/jN06D8w==} + simple-concat@1.0.1: resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} @@ -13764,6 +13817,10 @@ packages: stack-chain@1.3.7: resolution: {integrity: sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug==} + stack-trace@1.0.0-pre2: + resolution: {integrity: sha512-2ztBJRek8IVofG9DBJqdy2N5kulaacX30Nz7xmkYF6ale9WBVmIy6mFBchvGX7Vx/MyjBhx+Rcxqrj+dbOnQ6A==} + engines: {node: '>=16'} + stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} @@ -14814,6 +14871,11 @@ packages: typescript: '>=4.9.4' vite: '>=4.0.2' + vite-prerender-plugin@0.5.11: + resolution: {integrity: sha512-xWOhb8Ef2zoJIiinYVunIf3omRfUbEXcPEvrkQcrDpJ2yjDokxhvQ26eSJbkthRhymntWx6816jpATrJphh+ug==} + peerDependencies: + vite: 5.x || 6.x || 7.x + vite@7.0.0: resolution: {integrity: sha512-ixXJB1YRgDIw2OszKQS9WxGHKwLdCsbQNkpJN171udl6szi/rIySHL6/Os3s2+oE4P/FLD4dxg4mD7Wust+u5g==} engines: {node: ^20.19.0 || >=22.12.0} @@ -15880,6 +15942,10 @@ snapshots: dependencies: '@babel/types': 7.28.1 + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.28.1 + '@babel/helper-compilation-targets@7.27.2': dependencies: '@babel/compat-data': 7.28.0 @@ -15996,7 +16062,7 @@ snapshots: '@babel/parser@7.27.5': dependencies: - '@babel/types': 7.28.0 + '@babel/types': 7.28.1 '@babel/parser@7.28.0': dependencies: @@ -16402,6 +16468,24 @@ snapshots: '@babel/core': 7.28.0 '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.0)': + dependencies: + '@babel/core': 7.28.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.0) + '@babel/types': 7.28.1 + transitivePeerDependencies: + - supports-color + '@babel/plugin-transform-regenerator@7.27.0(@babel/core@7.28.0)': dependencies: '@babel/core': 7.28.0 @@ -16608,7 +16692,7 @@ snapshots: '@babel/generator': 7.27.0 '@babel/parser': 7.27.5 '@babel/template': 7.27.0 - '@babel/types': 7.28.0 + '@babel/types': 7.28.1 debug: 4.4.1(supports-color@6.0.0) globals: 11.12.0 transitivePeerDependencies: @@ -16829,8 +16913,6 @@ snapshots: '@ckeditor/ckeditor5-core': 46.0.0 '@ckeditor/ckeditor5-utils': 46.0.0 ckeditor5: 46.0.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41) - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-code-block@46.0.0(patch_hash=2361d8caad7d6b5bddacc3a3b4aa37dbfba260b1c1b22a450413a79c1bb1ce95)': dependencies: @@ -17083,6 +17165,8 @@ snapshots: '@ckeditor/ckeditor5-utils': 46.0.0 ckeditor5: 46.0.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41) es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-editor-multi-root@46.0.0': dependencies: @@ -17105,6 +17189,8 @@ snapshots: '@ckeditor/ckeditor5-table': 46.0.0 '@ckeditor/ckeditor5-utils': 46.0.0 ckeditor5: 46.0.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41) + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-emoji@46.0.0': dependencies: @@ -17130,8 +17216,6 @@ snapshots: '@ckeditor/ckeditor5-core': 46.0.0 '@ckeditor/ckeditor5-engine': 46.0.0 '@ckeditor/ckeditor5-utils': 46.0.0 - transitivePeerDependencies: - - supports-color '@ckeditor/ckeditor5-essentials@46.0.0': dependencies: @@ -17278,6 +17362,8 @@ snapshots: '@ckeditor/ckeditor5-widget': 46.0.0 ckeditor5: 46.0.0(patch_hash=8331a09d41443b39ea1c784daaccfeb0da4f9065ed556e7de92e9c77edd9eb41) es-toolkit: 1.39.5 + transitivePeerDependencies: + - supports-color '@ckeditor/ckeditor5-icons@46.0.0': {} @@ -20237,6 +20323,42 @@ snapshots: '@popperjs/core@2.11.8': {} + '@preact/preset-vite@2.10.2(@babel/core@7.28.0)(preact@10.27.0)(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))': + dependencies: + '@babel/core': 7.28.0 + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.0) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.0) + '@prefresh/vite': 2.4.8(preact@10.27.0)(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)) + '@rollup/pluginutils': 4.2.1 + babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.28.0) + debug: 4.4.1(supports-color@6.0.0) + picocolors: 1.1.1 + vite: 7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + vite-prerender-plugin: 0.5.11(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)) + transitivePeerDependencies: + - preact + - supports-color + + '@prefresh/babel-plugin@0.5.2': {} + + '@prefresh/core@1.5.5(preact@10.27.0)': + dependencies: + preact: 10.27.0 + + '@prefresh/utils@1.2.1': {} + + '@prefresh/vite@2.4.8(preact@10.27.0)(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))': + dependencies: + '@babel/core': 7.28.0 + '@prefresh/babel-plugin': 0.5.2 + '@prefresh/core': 1.5.5(preact@10.27.0) + '@prefresh/utils': 1.2.1 + '@rollup/pluginutils': 4.2.1 + preact: 10.27.0 + vite: 7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + transitivePeerDependencies: + - supports-color + '@promptbook/utils@0.69.5': dependencies: spacetrim: 0.11.59 @@ -22295,26 +22417,6 @@ snapshots: - vite optional: true - '@vitest/browser@3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.1.0)(typescript@5.9.2))(playwright@1.54.2)(utf-8-validate@6.0.5)(vite@7.0.0(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))(vitest@3.2.4)(webdriverio@9.18.4(bufferutil@4.0.9)(utf-8-validate@6.0.5))': - dependencies: - '@testing-library/dom': 10.4.0 - '@testing-library/user-event': 14.6.1(@testing-library/dom@10.4.0) - '@vitest/mocker': 3.2.4(msw@2.7.5(@types/node@24.1.0)(typescript@5.9.2))(vite@7.0.0(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)) - '@vitest/utils': 3.2.4 - magic-string: 0.30.17 - sirv: 3.0.1 - tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.1.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.1.0)(typescript@5.9.2))(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) - ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5) - optionalDependencies: - playwright: 1.54.2 - webdriverio: 9.18.4(bufferutil@4.0.9)(utf-8-validate@6.0.5) - transitivePeerDependencies: - - bufferutil - - msw - - utf-8-validate - - vite - '@vitest/browser@3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.1.0)(typescript@5.9.2))(playwright@1.54.2)(utf-8-validate@6.0.5)(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))(vitest@3.2.4)(webdriverio@9.18.4(bufferutil@4.0.9)(utf-8-validate@6.0.5))': dependencies: '@testing-library/dom': 10.4.0 @@ -22446,7 +22548,7 @@ snapshots: sirv: 3.0.1 tinyglobby: 0.2.14 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.1.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@24.1.0)(typescript@5.9.2))(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.17.0)(@vitest/browser@3.2.4)(@vitest/ui@3.2.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.1.3)(lightningcss@1.30.1)(msw@2.7.5(@types/node@22.17.0)(typescript@5.9.2))(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) '@vitest/utils@3.2.4': dependencies: @@ -23043,6 +23145,10 @@ snapshots: transitivePeerDependencies: - supports-color + babel-plugin-transform-hook-names@1.0.2(@babel/core@7.28.0): + dependencies: + '@babel/core': 7.28.0 + babel-plugin-transform-typescript-metadata@0.3.2(@babel/core@7.28.0)(@babel/traverse@7.28.0): dependencies: '@babel/core': 7.28.0 @@ -28833,6 +28939,11 @@ snapshots: - supports-color optional: true + node-html-parser@6.1.13: + dependencies: + css-select: 5.2.2 + he: 1.2.0 + node-int64@0.4.0: {} node-machine-id@1.1.12: {} @@ -31401,6 +31512,10 @@ snapshots: transitivePeerDependencies: - supports-color + simple-code-frame@1.3.0: + dependencies: + kolorist: 1.8.0 + simple-concat@1.0.1: {} simple-get@4.0.1: @@ -31634,6 +31749,8 @@ snapshots: stack-chain@1.3.7: {} + stack-trace@1.0.0-pre2: {} + stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 @@ -32977,18 +33094,22 @@ snapshots: tinyglobby: 0.2.14 vite: 7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) - vite-plugin-svgo@2.0.0(typescript@5.9.2)(vite@7.0.0(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)): - dependencies: - svgo: 3.3.2 - typescript: 5.9.2 - vite: 7.0.0(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) - vite-plugin-svgo@2.0.0(typescript@5.9.2)(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)): dependencies: svgo: 3.3.2 typescript: 5.9.2 vite: 7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + vite-prerender-plugin@0.5.11(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0)): + dependencies: + kolorist: 1.8.0 + magic-string: 0.30.17 + node-html-parser: 6.1.13 + simple-code-frame: 1.3.0 + source-map: 0.7.6 + stack-trace: 1.0.0-pre2 + vite: 7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0) + vite@7.0.0(@types/node@22.17.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0): dependencies: esbuild: 0.25.8 @@ -33147,7 +33268,7 @@ snapshots: optionalDependencies: '@types/debug': 4.1.12 '@types/node': 24.1.0 - '@vitest/browser': 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.1.0)(typescript@5.9.2))(playwright@1.54.2)(utf-8-validate@6.0.5)(vite@7.0.0(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))(vitest@3.2.4)(webdriverio@9.18.4(bufferutil@4.0.9)(utf-8-validate@6.0.5)) + '@vitest/browser': 3.2.4(bufferutil@4.0.9)(msw@2.7.5(@types/node@24.1.0)(typescript@5.9.2))(playwright@1.54.2)(utf-8-validate@6.0.5)(vite@7.0.6(@types/node@24.1.0)(jiti@2.5.1)(less@4.1.3)(lightningcss@1.30.1)(sass-embedded@1.87.0)(sass@1.87.0)(terser@5.43.1)(tsx@4.20.3)(yaml@2.8.0))(vitest@3.2.4)(webdriverio@9.18.4(bufferutil@4.0.9)(utf-8-validate@6.0.5)) '@vitest/ui': 3.2.4(vitest@3.2.4) happy-dom: 18.0.1 jsdom: 26.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) From 8f99ce7d14d7bdee9ca3527af0fd9172068f0cdc Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 3 Aug 2025 16:04:19 +0300 Subject: [PATCH 5/6] fix(react): type errors --- apps/client/src/widgets/dialogs/about.tsx | 9 +++++---- apps/client/tsconfig.app.json | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/client/src/widgets/dialogs/about.tsx b/apps/client/src/widgets/dialogs/about.tsx index 7d784627a..b8b9ad0e1 100644 --- a/apps/client/src/widgets/dialogs/about.tsx +++ b/apps/client/src/widgets/dialogs/about.tsx @@ -3,10 +3,11 @@ import ReactBasicWidget from "../react/ReactBasicWidget.js"; import Modal from "../react/Modal.js"; import { t } from "../../services/i18n.js"; import { formatDateTime } from "../../utils/formatters.js"; -import { useState } from "react"; import server from "../../services/server.js"; import utils from "../../services/utils.js"; import openService from "../../services/open.js"; +import { useState } from "preact/hooks"; +import type { CSSProperties } from "preact/compat"; interface AppInfo { appVersion: string; @@ -25,7 +26,7 @@ function AboutDialogComponent() { setAppInfo(appInfo); } - const forceWordBreak = { wordBreak: "break-all" }; + const forceWordBreak: CSSProperties = { wordBreak: "break-all" }; return ( @@ -73,9 +74,9 @@ function AboutDialogComponent() { ); } -function DirectoryLink({ directory, style }: { directory: string, style?: React.CSSProperties }) { +function DirectoryLink({ directory, style }: { directory: string, style?: CSSProperties }) { if (utils.isElectron()) { - const onClick = (e: React.MouseEvent) => { + const onClick = (e: MouseEvent) => { e.preventDefault(); openService.openDirectory(directory); }; diff --git a/apps/client/tsconfig.app.json b/apps/client/tsconfig.app.json index f823b8cba..16b93e1ce 100644 --- a/apps/client/tsconfig.app.json +++ b/apps/client/tsconfig.app.json @@ -37,6 +37,7 @@ ], "include": [ "src/**/*.ts", + "src/**/*.tsx", "src/**/*.json" ], "references": [ From b645d21fcdf8fe448dc14454ddee9705ddf93861 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sun, 3 Aug 2025 16:22:54 +0300 Subject: [PATCH 6/6] refactor(client): deduplicate app info type --- apps/client/src/widgets/dialogs/about.tsx | 10 +--------- apps/server/src/services/app_info.ts | 5 +++-- packages/commons/src/index.ts | 1 + packages/commons/src/lib/server_api.ts | 12 ++++++++++++ 4 files changed, 17 insertions(+), 11 deletions(-) create mode 100644 packages/commons/src/lib/server_api.ts diff --git a/apps/client/src/widgets/dialogs/about.tsx b/apps/client/src/widgets/dialogs/about.tsx index b8b9ad0e1..b315d52cd 100644 --- a/apps/client/src/widgets/dialogs/about.tsx +++ b/apps/client/src/widgets/dialogs/about.tsx @@ -8,15 +8,7 @@ import utils from "../../services/utils.js"; import openService from "../../services/open.js"; import { useState } from "preact/hooks"; import type { CSSProperties } from "preact/compat"; - -interface AppInfo { - appVersion: string; - dbVersion: number; - syncVersion: number; - buildDate: string; - buildRevision: string; - dataDirectory: string; -} +import type { AppInfo } from "@triliumnext/commons"; function AboutDialogComponent() { let [appInfo, setAppInfo] = useState(null); diff --git a/apps/server/src/services/app_info.ts b/apps/server/src/services/app_info.ts index 0def56253..2837e8de7 100644 --- a/apps/server/src/services/app_info.ts +++ b/apps/server/src/services/app_info.ts @@ -2,6 +2,7 @@ import path from "path"; import build from "./build.js"; import packageJson from "../../package.json" with { type: "json" }; import dataDir from "./data_dir.js"; +import { AppInfo } from "@triliumnext/commons"; const APP_DB_VERSION = 233; const SYNC_VERSION = 36; @@ -16,5 +17,5 @@ export default { buildRevision: build.buildRevision, dataDirectory: path.resolve(dataDir.TRILIUM_DATA_DIR), clipperProtocolVersion: CLIPPER_PROTOCOL_VERSION, - utcDateTime: new Date().toISOString() // for timezone inference -}; + utcDateTime: new Date().toISOString() +} satisfies AppInfo; diff --git a/packages/commons/src/index.ts b/packages/commons/src/index.ts index 5340e06d6..151924c8f 100644 --- a/packages/commons/src/index.ts +++ b/packages/commons/src/index.ts @@ -6,3 +6,4 @@ export * from "./lib/rows.js"; export * from "./lib/test-utils.js"; export * from "./lib/mime_type.js"; export * from "./lib/bulk_actions.js"; +export * from "./lib/server_api.js"; diff --git a/packages/commons/src/lib/server_api.ts b/packages/commons/src/lib/server_api.ts new file mode 100644 index 000000000..de91281db --- /dev/null +++ b/packages/commons/src/lib/server_api.ts @@ -0,0 +1,12 @@ +export interface AppInfo { + appVersion: string; + dbVersion: number; + nodeVersion: string; + syncVersion: number; + buildDate: string; + buildRevision: string; + dataDirectory: string; + clipperProtocolVersion: string; + /** for timezone inference */ + utcDateTime: string; +}