From 47f0214fe3f6dc1be6b6b9c692c25373ed0f295d Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Fri, 2 Jan 2026 21:02:48 +0100 Subject: [PATCH 01/18] =?UTF-8?q?Add=20rudimentary=20support=20for=20autom?= =?UTF-8?q?atic=20breadcrumbs=20=E2=80=94=20currently=20only=20with=20Acti?= =?UTF-8?q?onName=20as=20labels?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 44 ++++++++-------- package.json | 2 +- src/back/html.tsx | 6 +-- src/back/routes/common/breadcrumbs.css | 56 ++++++++++++++++++++ src/back/routes/common/breadcrumbs.tsx | 71 ++++++++++++++++++++++++++ src/back/routes/common/navbar.ts | 34 ++++++------ src/back/routes/url-tree.ts | 24 +++++++++ 7 files changed, 195 insertions(+), 42 deletions(-) create mode 100644 src/back/routes/common/breadcrumbs.css create mode 100644 src/back/routes/common/breadcrumbs.tsx create mode 100644 src/back/routes/url-tree.ts diff --git a/package-lock.json b/package-lock.json index 9a3d2a9..850eee2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.3", "@sealcode/jdd-editor": "^0.2.9", - "@sealcode/sealgen": "^0.19.6", + "@sealcode/sealgen": "^0.19.17", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", "@sealcode/sortable": "^0.0.1", @@ -1342,9 +1342,9 @@ } }, "node_modules/@sealcode/file-manager": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@sealcode/file-manager/-/file-manager-1.0.2.tgz", - "integrity": "sha512-BOMgC90QffE9cVFKkLVTjDbUJ5WB9YqcmS4fwqFxgnnC3YlH9xb9rff3iGXSkKOHm0kCeSjq0Ohasxtq/z72WQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@sealcode/file-manager/-/file-manager-1.0.3.tgz", + "integrity": "sha512-S2E1Yh7an8i9LEnX1FNvGXZwiHeWmg4dwXhMZR62xaRP7JjUve/2630aIYdiL7Ci6WLOsI7XsPhEQDlbQvQTDA==", "dependencies": { "@types/mime-types": "^2.1.4", "@types/uuid": "^9.0.8", @@ -1462,9 +1462,9 @@ "integrity": "sha512-pDsGlk2KokQkwzsJDBUWJFDRpEoxxth6TMQGDJyCTmWnd1Vn+cQb5moXDKaf7cXnWb9Y6QtdNX/fPzM/3RH2Cg==" }, "node_modules/@sealcode/sealgen": { - "version": "0.19.6", - "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.6.tgz", - "integrity": "sha512-dUccXEGSTlZrkrzkta2cObQUDBzbTrfYLZkbZer6E9nyYKB/7Jbj03R+C3wGxfwvrsewGfHiar+v8JHjOiguyQ==", + "version": "0.19.17", + "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.17.tgz", + "integrity": "sha512-QDhtLhgEwRDgaLx2efTZZII1jq5PGLVUlGOF6S4vIcSl4jA9UGrljPbw0JE5Opk8LY1oZE/Xkjz5rz8tsSFe3A==", "dependencies": { "@koa/router": "^12.0.1", "@sealcode/file-manager": "^1.0.2", @@ -1500,7 +1500,7 @@ "peerDependencies": { "koa": "^2.13.0", "koa-responsive-image-router": "^0.2.24", - "sealious": "^0.21.20", + "sealious": "^0.21.36", "stimulus": "^3.2.2" } }, @@ -12093,12 +12093,12 @@ "peer": true }, "node_modules/sealious": { - "version": "0.21.30", - "resolved": "https://registry.npmjs.org/sealious/-/sealious-0.21.30.tgz", - "integrity": "sha512-EWmqqFpDdgMvBmqAnaoX3FN2TmWdEgA1MgCUoQNB0iwUSl5m2Ghpd3W3eoM4H0Nr6bTr1ogJaOsAZJJFlIdc0Q==", + "version": "0.21.36", + "resolved": "https://registry.npmjs.org/sealious/-/sealious-0.21.36.tgz", + "integrity": "sha512-K1Gm7nM/fg8AEnd9QAJBSpoF6qJSuuwNlWjpCvz69sJkQ9FR8N3uRoX5t+gOPu7xqmBsrlNOx7JyF3sg3WQsFQ==", "dependencies": { "@koa/router": "^12.0.1", - "@sealcode/file-manager": "^1.0.1", + "@sealcode/file-manager": "^1.0.3", "@sealcode/ts-predicates": "^0.4.3", "@types/boom": "^7.3.0", "@types/clone": "^0.1.30", @@ -15954,9 +15954,9 @@ } }, "@sealcode/file-manager": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@sealcode/file-manager/-/file-manager-1.0.2.tgz", - "integrity": "sha512-BOMgC90QffE9cVFKkLVTjDbUJ5WB9YqcmS4fwqFxgnnC3YlH9xb9rff3iGXSkKOHm0kCeSjq0Ohasxtq/z72WQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@sealcode/file-manager/-/file-manager-1.0.3.tgz", + "integrity": "sha512-S2E1Yh7an8i9LEnX1FNvGXZwiHeWmg4dwXhMZR62xaRP7JjUve/2630aIYdiL7Ci6WLOsI7XsPhEQDlbQvQTDA==", "requires": { "@types/mime-types": "^2.1.4", "@types/uuid": "^9.0.8", @@ -16061,9 +16061,9 @@ "integrity": "sha512-pDsGlk2KokQkwzsJDBUWJFDRpEoxxth6TMQGDJyCTmWnd1Vn+cQb5moXDKaf7cXnWb9Y6QtdNX/fPzM/3RH2Cg==" }, "@sealcode/sealgen": { - "version": "0.19.6", - "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.6.tgz", - "integrity": "sha512-dUccXEGSTlZrkrzkta2cObQUDBzbTrfYLZkbZer6E9nyYKB/7Jbj03R+C3wGxfwvrsewGfHiar+v8JHjOiguyQ==", + "version": "0.19.17", + "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.17.tgz", + "integrity": "sha512-QDhtLhgEwRDgaLx2efTZZII1jq5PGLVUlGOF6S4vIcSl4jA9UGrljPbw0JE5Opk8LY1oZE/Xkjz5rz8tsSFe3A==", "requires": { "@koa/router": "^12.0.1", "@sealcode/file-manager": "^1.0.2", @@ -24023,12 +24023,12 @@ } }, "sealious": { - "version": "0.21.30", - "resolved": "https://registry.npmjs.org/sealious/-/sealious-0.21.30.tgz", - "integrity": "sha512-EWmqqFpDdgMvBmqAnaoX3FN2TmWdEgA1MgCUoQNB0iwUSl5m2Ghpd3W3eoM4H0Nr6bTr1ogJaOsAZJJFlIdc0Q==", + "version": "0.21.36", + "resolved": "https://registry.npmjs.org/sealious/-/sealious-0.21.36.tgz", + "integrity": "sha512-K1Gm7nM/fg8AEnd9QAJBSpoF6qJSuuwNlWjpCvz69sJkQ9FR8N3uRoX5t+gOPu7xqmBsrlNOx7JyF3sg3WQsFQ==", "requires": { "@koa/router": "^12.0.1", - "@sealcode/file-manager": "^1.0.1", + "@sealcode/file-manager": "^1.0.3", "@sealcode/ts-predicates": "^0.4.3", "@types/boom": "^7.3.0", "@types/clone": "^0.1.30", diff --git a/package.json b/package.json index 83d4c25..7ef020a 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.3", "@sealcode/jdd-editor": "^0.2.9", - "@sealcode/sealgen": "^0.19.6", + "@sealcode/sealgen": "^0.19.17", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", "@sealcode/sortable": "^0.0.1", diff --git a/src/back/html.tsx b/src/back/html.tsx index ef025ca..438c15a 100644 --- a/src/back/html.tsx +++ b/src/back/html.tsx @@ -1,10 +1,10 @@ import type { HTMLArgs, HTMLOptions } from "@sealcode/sealgen"; -import { tempstreamAsync } from "tempstream"; -import type { Readable } from "stream"; import { toKebabCase } from "js-convert-case"; +import type { Readable } from "stream"; +import { tempstreamAsync } from "tempstream"; import { DEFAULT_HTML_LANG } from "./config.js"; -import { default_navbar } from "./routes/common/navbar.js"; import { defaultHead } from "./defaultHead.js"; +import { default_navbar } from "./routes/common/navbar.js"; const default_html_options: Partial = { showFooter: true, diff --git a/src/back/routes/common/breadcrumbs.css b/src/back/routes/common/breadcrumbs.css new file mode 100644 index 0000000..f782103 --- /dev/null +++ b/src/back/routes/common/breadcrumbs.css @@ -0,0 +1,56 @@ +.breadcrumbs { + --bg: var(--color-brand-accent); + display: flex; + --height: 2rem; + --padding: 0px 16px; + flex-flow: row wrap; + align-items: center; + row-gap: 8px; + + span { + padding: var(--padding); + } + + a, + & > span { + display: inline-block; + line-height: var(--height); + font-size: 1rem; + } + + a { + text-decoration: none; + display: flex; + flex-flow: row nowrap; + color: var(--color-brand-text-on-accent); + + span { + background-color: var(--bg); + } + + .arrow-right, + .arrow-left { + width: 0; + height: 0; + } + + .arrow-right { + border-top: calc(var(--height) / 2) solid transparent; + border-bottom: calc(var(--height) / 2) solid transparent; + + border-left: calc(var(--height) / 2) solid var(--bg); + } + + .arrow-left { + width: 0; + height: 0; + border-top: calc(var(--height) / 2) solid var(--bg); + border-bottom: calc(var(--height) / 2) solid var(--bg); + border-left: calc(var(--height) / 2) solid transparent; + } + + &:hover { + filter: brightness(1.1); + } + } +} diff --git a/src/back/routes/common/breadcrumbs.tsx b/src/back/routes/common/breadcrumbs.tsx new file mode 100644 index 0000000..a41e954 --- /dev/null +++ b/src/back/routes/common/breadcrumbs.tsx @@ -0,0 +1,71 @@ +import type { Context } from "koa"; +import { TempstreamJSX } from "tempstream"; +import { get_breadcrumbs_from_path } from "../url-tree.js"; + +const arrow_width = 8; +const arrow_height = 28; + +function arrow_tail() { + return ( + + { + /* HTML */ `` + } + + ); +} + +function arrow_head() { + return ( + + { + /* HTML */ `` + } + + ); +} + +export function breadcrumbs(ctx: Context) { + return ( + + ); +} diff --git a/src/back/routes/common/navbar.ts b/src/back/routes/common/navbar.ts index 853ce3f..d10cc0f 100644 --- a/src/back/routes/common/navbar.ts +++ b/src/back/routes/common/navbar.ts @@ -1,9 +1,10 @@ -import type { BaseContext } from "koa"; +import type { Context } from "koa"; import { button } from "src/back/elements/button.js"; import { tempstream } from "tempstream"; import type { FlatTemplatable } from "tempstream"; +import { breadcrumbs } from "./breadcrumbs.js"; -export async function default_navbar(ctx: BaseContext): Promise { +export async function default_navbar(ctx: Context): Promise { const { items: navbar_items } = await ctx.$app.collections["navbar-links"] .list(ctx.$context) .fetch(); @@ -25,18 +26,19 @@ export async function default_navbar(ctx: BaseContext): Promise ) .join("\n"); - return /* HTML */ ``; + return /* HTML */ tempstream` + ${breadcrumbs(ctx)} `; } diff --git a/src/back/routes/url-tree.ts b/src/back/routes/url-tree.ts new file mode 100644 index 0000000..864bf82 --- /dev/null +++ b/src/back/routes/url-tree.ts @@ -0,0 +1,24 @@ +import { url_tree } from "./routes.js"; +import type { URLTree } from "./routes.js"; + +export function get_breadcrumbs_from_path(url: string) { + let position: URLTree = url_tree; + const elements = url.split("/").filter((e) => e != ""); + const breadcrumbs: { actionName?: string; url?: string }[] = [ + { actionName: "Home", url: "/" }, + ]; + let path_so_far = ""; + for (const element of elements) { + if (position.children[element]) { + position = position.children[element]; + } else if (Object.keys(position.children).find((e) => e.startsWith(":"))) { + const key = Object.keys(position.children).find((e) => e.startsWith(":")); + position = position.children[key!]!; + } else { + break; + } + path_so_far += "/" + element; + breadcrumbs.push({ actionName: position.actionName, url: path_so_far }); + } + return breadcrumbs; +} From 6b6dfee3319d5760277ce1f2ff1b9be724891ec2 Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Wed, 7 Jan 2026 13:07:46 +0100 Subject: [PATCH 02/18] Update JDD and JDD-editor --- package-lock.json | 29 ++++++++++++++--------------- package.json | 4 ++-- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 850eee2..4143e4f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,8 +14,8 @@ "@koa/router": "^12.0.1", "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", - "@sealcode/jdd": "^0.8.3", - "@sealcode/jdd-editor": "^0.2.9", + "@sealcode/jdd": "^0.8.5", + "@sealcode/jdd-editor": "^0.2.10", "@sealcode/sealgen": "^0.19.17", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", @@ -1354,10 +1354,9 @@ } }, "node_modules/@sealcode/jdd": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.3.tgz", - "integrity": "sha512-IsLxqjVL8OHAb8LmkiStuYu2xrkvxxMPv7oKK6edq56L5ZMIGaKd4fcNbYdLuEmCtLOuIoIwdHaK2+mPeGb0cw==", - "license": "ISC", + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.5.tgz", + "integrity": "sha512-M2rTC2Iqd3fy1giAJ5j083r3T3exM5N6zWxbZ4NRdJnyZuPH7LGTwq5Rza0HGqbkvKDyAYa2Eb4EW9khYu0mCw==", "dependencies": { "@sealcode/file-manager": "^1.0.2", "@sealcode/ts-predicates": "^0.5.3", @@ -1378,9 +1377,9 @@ } }, "node_modules/@sealcode/jdd-editor": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.9.tgz", - "integrity": "sha512-5/95i5ZiENX46irBHkiug3brNlrXYhpr+1nAX1OtqWKFQahgeERUExJUfjiTerwWs2N5HzpL/5VuElCR5wx49Q==", + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.10.tgz", + "integrity": "sha512-D3nJwm7bYl9TjliuoKzSTrRynYrC8rY+Lo04GqhSP9ixOCRXnOw+Y+cNz9wfIVfO8COjjvbceE41zDfp675K4g==", "dependencies": { "@koa/router": "^13.1.0", "@sealcode/jdd": "^0.8.3", @@ -15966,9 +15965,9 @@ } }, "@sealcode/jdd": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.3.tgz", - "integrity": "sha512-IsLxqjVL8OHAb8LmkiStuYu2xrkvxxMPv7oKK6edq56L5ZMIGaKd4fcNbYdLuEmCtLOuIoIwdHaK2+mPeGb0cw==", + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.5.tgz", + "integrity": "sha512-M2rTC2Iqd3fy1giAJ5j083r3T3exM5N6zWxbZ4NRdJnyZuPH7LGTwq5Rza0HGqbkvKDyAYa2Eb4EW9khYu0mCw==", "requires": { "@sealcode/file-manager": "^1.0.2", "@sealcode/ts-predicates": "^0.5.3", @@ -15998,9 +15997,9 @@ } }, "@sealcode/jdd-editor": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.9.tgz", - "integrity": "sha512-5/95i5ZiENX46irBHkiug3brNlrXYhpr+1nAX1OtqWKFQahgeERUExJUfjiTerwWs2N5HzpL/5VuElCR5wx49Q==", + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.10.tgz", + "integrity": "sha512-D3nJwm7bYl9TjliuoKzSTrRynYrC8rY+Lo04GqhSP9ixOCRXnOw+Y+cNz9wfIVfO8COjjvbceE41zDfp675K4g==", "requires": { "@koa/router": "^13.1.0", "@sealcode/jdd": "^0.8.3", diff --git a/package.json b/package.json index 7ef020a..1c9471b 100644 --- a/package.json +++ b/package.json @@ -93,8 +93,8 @@ "@koa/router": "^12.0.1", "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", - "@sealcode/jdd": "^0.8.3", - "@sealcode/jdd-editor": "^0.2.9", + "@sealcode/jdd": "^0.8.5", + "@sealcode/jdd-editor": "^0.2.10", "@sealcode/sealgen": "^0.19.17", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", From 2e03dbc957e0373f3a1285e98f1f3bd4509183da Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Mon, 19 Jan 2026 14:14:43 +0100 Subject: [PATCH 03/18] Fix FAQ component not previewing --- src/back/jdd-components/faq-component/faq-component.jdd.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/back/jdd-components/faq-component/faq-component.jdd.tsx b/src/back/jdd-components/faq-component/faq-component.jdd.tsx index 1265ec3..c852d83 100644 --- a/src/back/jdd-components/faq-component/faq-component.jdd.tsx +++ b/src/back/jdd-components/faq-component/faq-component.jdd.tsx @@ -55,7 +55,7 @@ export class FaqComponent extends Component { > {element.question}
-

{render_markdown(language, element.answer)}

+ {render_markdown(language, element.answer)}
))} From c5e1c705f45864e4a3210a444d4b4c241c22e3ef Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Wed, 21 Jan 2026 15:46:53 +0100 Subject: [PATCH 04/18] Update jdd-editor to fix the 320px resize of preview --- package-lock.json | 18 +++++++++--------- package.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4143e4f..bb6f0d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.5", - "@sealcode/jdd-editor": "^0.2.10", + "@sealcode/jdd-editor": "^0.2.11", "@sealcode/sealgen": "^0.19.17", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", @@ -1377,12 +1377,12 @@ } }, "node_modules/@sealcode/jdd-editor": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.10.tgz", - "integrity": "sha512-D3nJwm7bYl9TjliuoKzSTrRynYrC8rY+Lo04GqhSP9ixOCRXnOw+Y+cNz9wfIVfO8COjjvbceE41zDfp675K4g==", + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.11.tgz", + "integrity": "sha512-GNWj6DQGgIgdBLqWU+TKz3CJyLhq24LG7SdhfzjUDNtBo1nuaQhGGLsPP7W5fkcQqow37Yhvu4MUZRVkxAC+Kw==", "dependencies": { "@koa/router": "^13.1.0", - "@sealcode/jdd": "^0.8.3", + "@sealcode/jdd": "^0.8.5", "@sealcode/monaco-wrapper": "^0.0.3", "@sealcode/sealcodemirror": "^5.70.0-beta5", "@sealcode/sealgen": "^0.19.6", @@ -15997,12 +15997,12 @@ } }, "@sealcode/jdd-editor": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.10.tgz", - "integrity": "sha512-D3nJwm7bYl9TjliuoKzSTrRynYrC8rY+Lo04GqhSP9ixOCRXnOw+Y+cNz9wfIVfO8COjjvbceE41zDfp675K4g==", + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.11.tgz", + "integrity": "sha512-GNWj6DQGgIgdBLqWU+TKz3CJyLhq24LG7SdhfzjUDNtBo1nuaQhGGLsPP7W5fkcQqow37Yhvu4MUZRVkxAC+Kw==", "requires": { "@koa/router": "^13.1.0", - "@sealcode/jdd": "^0.8.3", + "@sealcode/jdd": "^0.8.5", "@sealcode/monaco-wrapper": "^0.0.3", "@sealcode/sealcodemirror": "^5.70.0-beta5", "@sealcode/sealgen": "^0.19.6", diff --git a/package.json b/package.json index 1c9471b..ad2ae6e 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.5", - "@sealcode/jdd-editor": "^0.2.10", + "@sealcode/jdd-editor": "^0.2.11", "@sealcode/sealgen": "^0.19.17", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", From 0815c11302033f384a8303cf43d41f4ff32fd7fc Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Thu, 22 Jan 2026 13:28:43 +0100 Subject: [PATCH 05/18] Configure and increase the image router cache sizes --- src/back/config.ts | 4 ++++ src/back/image-router.ts | 11 ++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/back/config.ts b/src/back/config.ts index 8936892..105c18d 100644 --- a/src/back/config.ts +++ b/src/back/config.ts @@ -40,6 +40,10 @@ export const IMAGE_CACHE_FS_DIR = process.env.IMAGE_CACHE_FS_DIR || locreq.resolve("cache/images"); export const SMARTCROP_CACHE_FS_DIR = process.env.IMAGE_CACHE_FS_DIR || locreq.resolve("cache/smartcrop"); +export const IMAGE_CACHE_SIZE = parseInt(process.env.IMAGE_CACHE_SIZE || "1000"); +export const IMAGE_SMARTCROP_CACHE_SIZE = parseInt(process.env.IMAGE_CACHE_SIZE || "500"); +export const IMAGE_THUMBNAIL_CACHE_SIZE = parseInt(process.env.IMAGE_CACHE_SIZE || "500"); + export const UPLOADS_FS_DIR = process.env.UPLOADS_FS_DIR || locreq.resolve("uploaded_files"); export const MEILISEARCH_MASTER_KEY = process.env.MEILISEARCH_MASTER_KEY || "qwerty"; diff --git a/src/back/image-router.ts b/src/back/image-router.ts index 0e5ff68..ef6cea3 100644 --- a/src/back/image-router.ts +++ b/src/back/image-router.ts @@ -1,5 +1,11 @@ import { KoaResponsiveImageRouter } from "koa-responsive-image-router"; -import { IMAGE_CACHE_FS_DIR, SMARTCROP_CACHE_FS_DIR } from "./config.js"; +import { + IMAGE_CACHE_FS_DIR, + SMARTCROP_CACHE_FS_DIR, + IMAGE_CACHE_SIZE, + IMAGE_SMARTCROP_CACHE_SIZE, + IMAGE_THUMBNAIL_CACHE_SIZE, +} from "./config.js"; export const RESPONSIVE_IMAGES_URL_PATH = "/images"; @@ -11,4 +17,7 @@ export const imageRouter = new KoaResponsiveImageRouter({ smartCropStoragePath: SMARTCROP_CACHE_FS_DIR, formatsForLossy: ["webp"], formatsForLossless: ["webp"], + diskImageCacheSize: IMAGE_CACHE_SIZE, + smartCropCacheSize: IMAGE_SMARTCROP_CACHE_SIZE, + thumbnailMaxCacheSize: IMAGE_THUMBNAIL_CACHE_SIZE, }); From 56e9d20488a8084f3b4a1ea9fa798c908d451b34 Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Sat, 31 Jan 2026 18:52:10 +0100 Subject: [PATCH 06/18] Update jdd editor to fix scrollbars in table --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index bb6f0d0..d73f7fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.5", - "@sealcode/jdd-editor": "^0.2.11", + "@sealcode/jdd-editor": "^0.2.14", "@sealcode/sealgen": "^0.19.17", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", @@ -1377,9 +1377,9 @@ } }, "node_modules/@sealcode/jdd-editor": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.11.tgz", - "integrity": "sha512-GNWj6DQGgIgdBLqWU+TKz3CJyLhq24LG7SdhfzjUDNtBo1nuaQhGGLsPP7W5fkcQqow37Yhvu4MUZRVkxAC+Kw==", + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.14.tgz", + "integrity": "sha512-HExO1bg5f1SODz8KoF/4ZSQ3kUqpRZEdg58I3tlJzSPny+kHXZwvGLpNWY73Aj4AU+pv7qDe8mr2g2KiIvXhHg==", "dependencies": { "@koa/router": "^13.1.0", "@sealcode/jdd": "^0.8.5", @@ -15997,9 +15997,9 @@ } }, "@sealcode/jdd-editor": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.11.tgz", - "integrity": "sha512-GNWj6DQGgIgdBLqWU+TKz3CJyLhq24LG7SdhfzjUDNtBo1nuaQhGGLsPP7W5fkcQqow37Yhvu4MUZRVkxAC+Kw==", + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.14.tgz", + "integrity": "sha512-HExO1bg5f1SODz8KoF/4ZSQ3kUqpRZEdg58I3tlJzSPny+kHXZwvGLpNWY73Aj4AU+pv7qDe8mr2g2KiIvXhHg==", "requires": { "@koa/router": "^13.1.0", "@sealcode/jdd": "^0.8.5", diff --git a/package.json b/package.json index ad2ae6e..2024e0b 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.5", - "@sealcode/jdd-editor": "^0.2.11", + "@sealcode/jdd-editor": "^0.2.14", "@sealcode/sealgen": "^0.19.17", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", From 67c8e6e40681f3d7e3ae13b14db9a52f272034e7 Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Sat, 31 Jan 2026 19:38:57 +0100 Subject: [PATCH 07/18] Correct title for the signup form --- src/back/routes/login.form.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/back/routes/login.form.ts b/src/back/routes/login.form.ts index 751d775..48329f7 100644 --- a/src/back/routes/login.form.ts +++ b/src/back/routes/login.form.ts @@ -67,7 +67,7 @@ export default new (class LoginForm extends Form { async render(ctx: Context, data: FormData, show_field_errors: boolean) { return html({ ctx, - title: "Form", + title: "Sign in", description: "", css_clumps: ["admin-forms"], body: super.render(ctx, data, show_field_errors) as Promise, From 86742545d1daf56040b9452b839cf14bf9bee17a Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Sat, 31 Jan 2026 20:26:07 +0100 Subject: [PATCH 08/18] Update jdd-editor --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index d73f7fd..d4ee1e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,7 @@ "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.5", - "@sealcode/jdd-editor": "^0.2.14", + "@sealcode/jdd-editor": "^0.2.15", "@sealcode/sealgen": "^0.19.17", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", @@ -1377,9 +1377,9 @@ } }, "node_modules/@sealcode/jdd-editor": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.14.tgz", - "integrity": "sha512-HExO1bg5f1SODz8KoF/4ZSQ3kUqpRZEdg58I3tlJzSPny+kHXZwvGLpNWY73Aj4AU+pv7qDe8mr2g2KiIvXhHg==", + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.15.tgz", + "integrity": "sha512-v9TMjIuwm4igBFqXykJ1QToX8UHwRDOh0Dao124kojtx7a7MDhojummAdgy9NPmSVD7cr8BDhS+JY5nkRUzq+A==", "dependencies": { "@koa/router": "^13.1.0", "@sealcode/jdd": "^0.8.5", @@ -15997,9 +15997,9 @@ } }, "@sealcode/jdd-editor": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.14.tgz", - "integrity": "sha512-HExO1bg5f1SODz8KoF/4ZSQ3kUqpRZEdg58I3tlJzSPny+kHXZwvGLpNWY73Aj4AU+pv7qDe8mr2g2KiIvXhHg==", + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.15.tgz", + "integrity": "sha512-v9TMjIuwm4igBFqXykJ1QToX8UHwRDOh0Dao124kojtx7a7MDhojummAdgy9NPmSVD7cr8BDhS+JY5nkRUzq+A==", "requires": { "@koa/router": "^13.1.0", "@sealcode/jdd": "^0.8.5", diff --git a/package.json b/package.json index 2024e0b..25b8e2b 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.5", - "@sealcode/jdd-editor": "^0.2.14", + "@sealcode/jdd-editor": "^0.2.15", "@sealcode/sealgen": "^0.19.17", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", From 6a259c8e4fc60e800cf9d076d88f668487c80547 Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Sun, 1 Feb 2026 15:24:15 +0100 Subject: [PATCH 09/18] Try to fix small thumbnails not persisting on disk --- src/back/image-router.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/back/image-router.ts b/src/back/image-router.ts index ef6cea3..2946449 100644 --- a/src/back/image-router.ts +++ b/src/back/image-router.ts @@ -12,7 +12,7 @@ export const RESPONSIVE_IMAGES_URL_PATH = "/images"; export const imageRouter = new KoaResponsiveImageRouter({ staticPath: RESPONSIVE_IMAGES_URL_PATH, thumbnailSize: 20, - cacheManagerResolutionThreshold: 50, + cacheManagerResolutionThreshold: 21, imageStoragePath: IMAGE_CACHE_FS_DIR, smartCropStoragePath: SMARTCROP_CACHE_FS_DIR, formatsForLossy: ["webp"], From 7dfaf103b82055e6479b10521c49f92af4d346bf Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Sat, 7 Feb 2026 16:07:35 +0100 Subject: [PATCH 10/18] Ensure full URL is used for og:image --- src/back/defaultHead.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/back/defaultHead.tsx b/src/back/defaultHead.tsx index b2a1221..2f4ef06 100644 --- a/src/back/defaultHead.tsx +++ b/src/back/defaultHead.tsx @@ -30,7 +30,9 @@ export function defaultHead({ ${ctx.$app.getFeedHTMLMetatags(ctx)} - ${metaImage ? `` : ""} + ${metaImage + ? `` + : ""} ${[ "default", "page", From a32944b809de33a767c77c329947f3c7f611936e Mon Sep 17 00:00:00 2001 From: PrzZiomek2 Date: Sun, 8 Feb 2026 09:41:30 +0100 Subject: [PATCH 11/18] Create code snippet jdd component Summary: Ref T2994 Reviewers: kuba-orlik Reviewed By: kuba-orlik Maniphest Tasks: T2994 Differential Revision: https://hub.sealcode.org/D1667 --- package-lock.json | 28 +++++++--- package.json | 1 + .../code-snippet/code-snippet.css | 22 ++++++++ .../code-snippet/code-snippet.jdd.tsx | 54 +++++++++++++++++++ 4 files changed, 98 insertions(+), 7 deletions(-) create mode 100644 src/back/jdd-components/code-snippet/code-snippet.css create mode 100644 src/back/jdd-components/code-snippet/code-snippet.jdd.tsx diff --git a/package-lock.json b/package-lock.json index d4ee1e4..6da6b55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,7 @@ "escape-goat": "^4.0.0", "get-port": "^7.0.0", "glob": "^11.0.3", + "highlight.js": "^11.11.1", "js-convert-case": "^4.2.0", "koa-mount": "^4.2.0", "koa-qs": "^3.0.0", @@ -6887,11 +6888,11 @@ } }, "node_modules/highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", "engines": { - "node": "*" + "node": ">=12.0.0" } }, "node_modules/hookable": { @@ -14214,6 +14215,14 @@ "node": ">=6 <7 || >=8" } }, + "node_modules/typedoc/node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "engines": { + "node": "*" + } + }, "node_modules/typedoc/node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -20126,9 +20135,9 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, "highlight.js": { - "version": "10.7.3", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", - "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==" }, "hookable": { "version": "5.5.3", @@ -25539,6 +25548,11 @@ "universalify": "^0.1.0" } }, + "highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" + }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", diff --git a/package.json b/package.json index 25b8e2b..c294756 100644 --- a/package.json +++ b/package.json @@ -110,6 +110,7 @@ "escape-goat": "^4.0.0", "get-port": "^7.0.0", "glob": "^11.0.3", + "highlight.js": "^11.11.1", "js-convert-case": "^4.2.0", "koa-mount": "^4.2.0", "koa-qs": "^3.0.0", diff --git a/src/back/jdd-components/code-snippet/code-snippet.css b/src/back/jdd-components/code-snippet/code-snippet.css new file mode 100644 index 0000000..e1e0628 --- /dev/null +++ b/src/back/jdd-components/code-snippet/code-snippet.css @@ -0,0 +1,22 @@ +.code-snippet { + display: flex; + flex-direction: column; + padding: 0 16px 16px 16px; +} + +.code-snippet pre { + margin: 0; +} + +.code-snippet__language-error { + color: red; + font-size: 16px; +} + +.code-snippet__language { + display: flex; + justify-content: flex-start; + margin: 0; + margin-top: 20px; + gap: 8px; +} \ No newline at end of file diff --git a/src/back/jdd-components/code-snippet/code-snippet.jdd.tsx b/src/back/jdd-components/code-snippet/code-snippet.jdd.tsx new file mode 100644 index 0000000..734226c --- /dev/null +++ b/src/back/jdd-components/code-snippet/code-snippet.jdd.tsx @@ -0,0 +1,54 @@ +import { TempstreamJSX } from "tempstream"; +import type { ComponentToHTMLArgs } from "@sealcode/jdd"; +import { Component, ComponentArguments } from "@sealcode/jdd"; +import hljs from "highlight.js"; + +const component_arguments = { + codeWithLanguage: new ComponentArguments.CodeWithCustomLanguage(), +} as const; + +export class CodeSnippet extends Component { + getArguments() { + return component_arguments; + } + + async toHTML({ + args: { codeWithLanguage }, + classes, + }: ComponentToHTMLArgs): Promise { + let highlightedCode: string; + let languageNotFoundMessage: string = ""; + + const language = codeWithLanguage.language?.toLowerCase() || "plaintext"; + + if (hljs.getLanguage(language)) { + highlightedCode = hljs.highlight(codeWithLanguage.code, { + language, + }).value; + } else { + highlightedCode = hljs.highlight(codeWithLanguage.code, { + language: "plaintext", + }).value; + languageNotFoundMessage = `Language "${language}" not found`; + } + + return ( +
+

CodeSnippet

+ {languageNotFoundMessage ? ( +

{languageNotFoundMessage}

+ ) : ( + <> +
+							{highlightedCode}
+						
+
+ {codeWithLanguage.language} + +
+ + )} +
+ ); + } +} From 3199ef257748224374ff18f07ccfbb5444d0f7b3 Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Mon, 9 Feb 2026 19:25:09 +0100 Subject: [PATCH 12/18] Update JDD and jdd-editor --- package-lock.json | 32 ++++++++++++++++---------------- package.json | 4 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6da6b55..9d3043f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,8 +14,8 @@ "@koa/router": "^12.0.1", "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", - "@sealcode/jdd": "^0.8.5", - "@sealcode/jdd-editor": "^0.2.15", + "@sealcode/jdd": "^0.8.6", + "@sealcode/jdd-editor": "^0.2.16", "@sealcode/sealgen": "^0.19.17", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", @@ -1355,9 +1355,9 @@ } }, "node_modules/@sealcode/jdd": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.5.tgz", - "integrity": "sha512-M2rTC2Iqd3fy1giAJ5j083r3T3exM5N6zWxbZ4NRdJnyZuPH7LGTwq5Rza0HGqbkvKDyAYa2Eb4EW9khYu0mCw==", + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.6.tgz", + "integrity": "sha512-IPntFEG/pi/ut85Fz0+eFCb0416uFYmugUKaiHyH2VQ0TKBo3MLQj7V6v8mWLNeOKAEkvejROUs0zbaJuTpgvA==", "dependencies": { "@sealcode/file-manager": "^1.0.2", "@sealcode/ts-predicates": "^0.5.3", @@ -1378,12 +1378,12 @@ } }, "node_modules/@sealcode/jdd-editor": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.15.tgz", - "integrity": "sha512-v9TMjIuwm4igBFqXykJ1QToX8UHwRDOh0Dao124kojtx7a7MDhojummAdgy9NPmSVD7cr8BDhS+JY5nkRUzq+A==", + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.16.tgz", + "integrity": "sha512-S6WTSJh82yer1ZX5RPx1GFUWwa8BysUnCsoByUNubGXbWRemu52LZ/MH/myv27x9biB4Ug/Oj/5pyYqw+lwcDg==", "dependencies": { "@koa/router": "^13.1.0", - "@sealcode/jdd": "^0.8.5", + "@sealcode/jdd": "^0.8.6", "@sealcode/monaco-wrapper": "^0.0.3", "@sealcode/sealcodemirror": "^5.70.0-beta5", "@sealcode/sealgen": "^0.19.6", @@ -15974,9 +15974,9 @@ } }, "@sealcode/jdd": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.5.tgz", - "integrity": "sha512-M2rTC2Iqd3fy1giAJ5j083r3T3exM5N6zWxbZ4NRdJnyZuPH7LGTwq5Rza0HGqbkvKDyAYa2Eb4EW9khYu0mCw==", + "version": "0.8.6", + "resolved": "https://registry.npmjs.org/@sealcode/jdd/-/jdd-0.8.6.tgz", + "integrity": "sha512-IPntFEG/pi/ut85Fz0+eFCb0416uFYmugUKaiHyH2VQ0TKBo3MLQj7V6v8mWLNeOKAEkvejROUs0zbaJuTpgvA==", "requires": { "@sealcode/file-manager": "^1.0.2", "@sealcode/ts-predicates": "^0.5.3", @@ -16006,12 +16006,12 @@ } }, "@sealcode/jdd-editor": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.15.tgz", - "integrity": "sha512-v9TMjIuwm4igBFqXykJ1QToX8UHwRDOh0Dao124kojtx7a7MDhojummAdgy9NPmSVD7cr8BDhS+JY5nkRUzq+A==", + "version": "0.2.16", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.16.tgz", + "integrity": "sha512-S6WTSJh82yer1ZX5RPx1GFUWwa8BysUnCsoByUNubGXbWRemu52LZ/MH/myv27x9biB4Ug/Oj/5pyYqw+lwcDg==", "requires": { "@koa/router": "^13.1.0", - "@sealcode/jdd": "^0.8.5", + "@sealcode/jdd": "^0.8.6", "@sealcode/monaco-wrapper": "^0.0.3", "@sealcode/sealcodemirror": "^5.70.0-beta5", "@sealcode/sealgen": "^0.19.6", diff --git a/package.json b/package.json index c294756..b98c44f 100644 --- a/package.json +++ b/package.json @@ -93,8 +93,8 @@ "@koa/router": "^12.0.1", "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", - "@sealcode/jdd": "^0.8.5", - "@sealcode/jdd-editor": "^0.2.15", + "@sealcode/jdd": "^0.8.6", + "@sealcode/jdd-editor": "^0.2.16", "@sealcode/sealgen": "^0.19.17", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", From 4fbdda344a4cd9472531f002f32a44a94f227174 Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Sat, 14 Feb 2026 20:59:28 +0100 Subject: [PATCH 13/18] Update sealgen to get sortable tables --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9d3043f..170dd3c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.6", "@sealcode/jdd-editor": "^0.2.16", - "@sealcode/sealgen": "^0.19.17", + "@sealcode/sealgen": "^0.19.18", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", "@sealcode/sortable": "^0.0.1", @@ -1462,9 +1462,9 @@ "integrity": "sha512-pDsGlk2KokQkwzsJDBUWJFDRpEoxxth6TMQGDJyCTmWnd1Vn+cQb5moXDKaf7cXnWb9Y6QtdNX/fPzM/3RH2Cg==" }, "node_modules/@sealcode/sealgen": { - "version": "0.19.17", - "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.17.tgz", - "integrity": "sha512-QDhtLhgEwRDgaLx2efTZZII1jq5PGLVUlGOF6S4vIcSl4jA9UGrljPbw0JE5Opk8LY1oZE/Xkjz5rz8tsSFe3A==", + "version": "0.19.18", + "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.18.tgz", + "integrity": "sha512-bdEDaSKtvMGH8JT7dIwhxJI9ZaJd1d7eMzWZIQay/du3KYqLcnAhx6eFPBRXskaWJBwGkyJZiLQJgRQ+06+EqQ==", "dependencies": { "@koa/router": "^12.0.1", "@sealcode/file-manager": "^1.0.2", @@ -16069,9 +16069,9 @@ "integrity": "sha512-pDsGlk2KokQkwzsJDBUWJFDRpEoxxth6TMQGDJyCTmWnd1Vn+cQb5moXDKaf7cXnWb9Y6QtdNX/fPzM/3RH2Cg==" }, "@sealcode/sealgen": { - "version": "0.19.17", - "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.17.tgz", - "integrity": "sha512-QDhtLhgEwRDgaLx2efTZZII1jq5PGLVUlGOF6S4vIcSl4jA9UGrljPbw0JE5Opk8LY1oZE/Xkjz5rz8tsSFe3A==", + "version": "0.19.18", + "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.18.tgz", + "integrity": "sha512-bdEDaSKtvMGH8JT7dIwhxJI9ZaJd1d7eMzWZIQay/du3KYqLcnAhx6eFPBRXskaWJBwGkyJZiLQJgRQ+06+EqQ==", "requires": { "@koa/router": "^12.0.1", "@sealcode/file-manager": "^1.0.2", diff --git a/package.json b/package.json index b98c44f..1b8eb5b 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.6", "@sealcode/jdd-editor": "^0.2.16", - "@sealcode/sealgen": "^0.19.17", + "@sealcode/sealgen": "^0.19.18", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", "@sealcode/sortable": "^0.0.1", From 021783e2d3cb07689dcf5186ccbc5c467d5e239b Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Thu, 26 Feb 2026 19:48:22 +0100 Subject: [PATCH 14/18] Update jdd-editor and monaco in order to get the markdown editor --- package-lock.json | 66 ++++++++++++++++++++++++++-------------- package.json | 3 +- src/front/controllers.ts | 13 +++++--- 3 files changed, 53 insertions(+), 29 deletions(-) diff --git a/package-lock.json b/package-lock.json index 170dd3c..2ebc420 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,8 @@ "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.6", - "@sealcode/jdd-editor": "^0.2.16", + "@sealcode/jdd-editor": "^0.2.17", + "@sealcode/monaco-wrapper": "^0.0.4", "@sealcode/sealgen": "^0.19.18", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", @@ -1378,9 +1379,9 @@ } }, "node_modules/@sealcode/jdd-editor": { - "version": "0.2.16", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.16.tgz", - "integrity": "sha512-S6WTSJh82yer1ZX5RPx1GFUWwa8BysUnCsoByUNubGXbWRemu52LZ/MH/myv27x9biB4Ug/Oj/5pyYqw+lwcDg==", + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.17.tgz", + "integrity": "sha512-Zc2cg0PpVIgls5Egub0oJZIPjCCKw+f66ZtmMmwJzb+rfYzs8W2uGhC0MZyAyzWpsybH1cTHOJe7W1p4douwxw==", "dependencies": { "@koa/router": "^13.1.0", "@sealcode/jdd": "^0.8.6", @@ -1413,14 +1414,22 @@ "node": ">= 18" } }, - "node_modules/@sealcode/jdd-editor/node_modules/highlight.js": { - "version": "11.11.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", - "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", - "engines": { - "node": ">=12.0.0" + "node_modules/@sealcode/jdd-editor/node_modules/@sealcode/monaco-wrapper": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@sealcode/monaco-wrapper/-/monaco-wrapper-0.0.3.tgz", + "integrity": "sha512-EAmcW5lDVeEMpdVfhxJM9psuBFgrD1Wr2JJrBg3ifkut4y5mTHuaHfkut3BrzgifuPeukUJZuyX+sncFs26c7g==", + "dependencies": { + "@sealcode/add-to-head": "^1.0.0", + "monaco-editor": "^0.52.2", + "stimulus": "^3.2.2", + "throttle-debounce": "^5.0.2" } }, + "node_modules/@sealcode/jdd-editor/node_modules/monaco-editor": { + "version": "0.52.2", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz", + "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==" + }, "node_modules/@sealcode/jdd/node_modules/@sealcode/ts-predicates": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/@sealcode/ts-predicates/-/ts-predicates-0.5.3.tgz", @@ -1441,9 +1450,9 @@ } }, "node_modules/@sealcode/monaco-wrapper": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@sealcode/monaco-wrapper/-/monaco-wrapper-0.0.3.tgz", - "integrity": "sha512-EAmcW5lDVeEMpdVfhxJM9psuBFgrD1Wr2JJrBg3ifkut4y5mTHuaHfkut3BrzgifuPeukUJZuyX+sncFs26c7g==", + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@sealcode/monaco-wrapper/-/monaco-wrapper-0.0.4.tgz", + "integrity": "sha512-oRksJVfCLPVabExFF4hbzUBS/LVCLRfdqsJp4VbTcd0NPa6kmRs/hDxD+XL1kZ0xkt3EeFeH5gHRmRMtPDAmtA==", "dependencies": { "@sealcode/add-to-head": "^1.0.0", "monaco-editor": "^0.52.2", @@ -16006,9 +16015,9 @@ } }, "@sealcode/jdd-editor": { - "version": "0.2.16", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.16.tgz", - "integrity": "sha512-S6WTSJh82yer1ZX5RPx1GFUWwa8BysUnCsoByUNubGXbWRemu52LZ/MH/myv27x9biB4Ug/Oj/5pyYqw+lwcDg==", + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.17.tgz", + "integrity": "sha512-Zc2cg0PpVIgls5Egub0oJZIPjCCKw+f66ZtmMmwJzb+rfYzs8W2uGhC0MZyAyzWpsybH1cTHOJe7W1p4douwxw==", "requires": { "@koa/router": "^13.1.0", "@sealcode/jdd": "^0.8.6", @@ -16038,17 +16047,28 @@ "path-to-regexp": "^6.3.0" } }, - "highlight.js": { - "version": "11.11.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", - "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==" + "@sealcode/monaco-wrapper": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@sealcode/monaco-wrapper/-/monaco-wrapper-0.0.3.tgz", + "integrity": "sha512-EAmcW5lDVeEMpdVfhxJM9psuBFgrD1Wr2JJrBg3ifkut4y5mTHuaHfkut3BrzgifuPeukUJZuyX+sncFs26c7g==", + "requires": { + "@sealcode/add-to-head": "^1.0.0", + "monaco-editor": "^0.52.2", + "stimulus": "^3.2.2", + "throttle-debounce": "^5.0.2" + } + }, + "monaco-editor": { + "version": "0.52.2", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz", + "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==" } } }, "@sealcode/monaco-wrapper": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@sealcode/monaco-wrapper/-/monaco-wrapper-0.0.3.tgz", - "integrity": "sha512-EAmcW5lDVeEMpdVfhxJM9psuBFgrD1Wr2JJrBg3ifkut4y5mTHuaHfkut3BrzgifuPeukUJZuyX+sncFs26c7g==", + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@sealcode/monaco-wrapper/-/monaco-wrapper-0.0.4.tgz", + "integrity": "sha512-oRksJVfCLPVabExFF4hbzUBS/LVCLRfdqsJp4VbTcd0NPa6kmRs/hDxD+XL1kZ0xkt3EeFeH5gHRmRMtPDAmtA==", "requires": { "@sealcode/add-to-head": "^1.0.0", "monaco-editor": "^0.52.2", diff --git a/package.json b/package.json index 1b8eb5b..22d90cb 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,8 @@ "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.6", - "@sealcode/jdd-editor": "^0.2.16", + "@sealcode/jdd-editor": "^0.2.17", + "@sealcode/monaco-wrapper": "^0.0.4", "@sealcode/sealgen": "^0.19.18", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", diff --git a/src/front/controllers.ts b/src/front/controllers.ts index 11519b8..752a071 100644 --- a/src/front/controllers.ts +++ b/src/front/controllers.ts @@ -19,6 +19,9 @@ application.register("horizontal-scroller", HorizontalScroller); import { default as AutogrowTextarea } from "./../../node_modules/@sealcode/jdd-editor/src/controllers/autogrow-textarea.stimulus.js"; application.register("autogrow-textarea", AutogrowTextarea); +import { default as CodeSnippet } from "./../../node_modules/@sealcode/jdd-editor/src/controllers/code-snippet.stimulus.js"; +application.register("code-snippet", CodeSnippet); + import { default as ComponentDebugger } from "./../../node_modules/@sealcode/jdd-editor/src/controllers/component-debugger.stimulus.js"; application.register("component-debugger", ComponentDebugger); @@ -34,9 +37,6 @@ application.register("jdd-table-paste", JddTablePaste); import { default as JsonEditor } from "./../../node_modules/@sealcode/jdd-editor/src/controllers/json-editor.stimulus.js"; application.register("json-editor", JsonEditor); -import { default as MarkdownTextarea } from "./../../node_modules/@sealcode/jdd-editor/src/controllers/markdown-textarea.stimulus.js"; -application.register("markdown-textarea", MarkdownTextarea); - import { default as RefreshOnTsChanges } from "./../../node_modules/@sealcode/jdd-editor/src/controllers/refresh-on-ts-changes.stimulus.js"; application.register("refresh-on-ts-changes", RefreshOnTsChanges); @@ -52,8 +52,11 @@ application.register("toast", Toast); import { default as Monaco } from "./../../node_modules/@sealcode/monaco-wrapper/src/controllers/monaco.stimulus.js"; application.register("monaco", Monaco); -import { default as TableAddButton } from "./../../node_modules/@sealcode/sealgen/src/controllers/table-add-button.stimulus.js"; -application.register("table-add-button", TableAddButton); +import { default as PasswordGenerateButton } from "./../../node_modules/@sealcode/sealgen/src/controllers/password-generate-button.stimulus.js"; +application.register("password-generate-button", PasswordGenerateButton); + +import { default as SealgenTable } from "./../../node_modules/@sealcode/sealgen/src/controllers/sealgen-table.stimulus.js"; +application.register("sealgen-table", SealgenTable); import { default as Sortable } from "./../../node_modules/@sealcode/sortable/src/controllers/sortable.stimulus.js"; application.register("sortable", Sortable); From ee2368c68647ab7b342b1ec18bb32311e3c045ac Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Thu, 26 Mar 2026 18:55:10 +0100 Subject: [PATCH 15/18] add a11y css to project when not in prod mode Summary: Ref T3078 Reviewers: kuba-orlik Maniphest Tasks: T3078 Differential Revision: https://hub.sealcode.org/D1687 --- package-lock.json | 11 +++++++++++ package.json | 5 +++++ src/back/a11y_overrides.css | 11 +++++++++++ src/back/config.ts | 1 + src/back/defaultHead.tsx | 4 +++- src/back/html.tsx | 4 +++- 6 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 src/back/a11y_overrides.css diff --git a/package-lock.json b/package-lock.json index 2ebc420..06947cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "@types/leaflet": "^1.9.8", "@types/object-hash": "^3.0.6", "@types/simplemde": "^1.11.11", + "a11y.css": "^5.3.0", "c8": "^10.1.3", "colord": "^2.9.3", "dotenv": "^16.4.5", @@ -2478,6 +2479,11 @@ "dev": true, "peer": true }, + "node_modules/a11y.css": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/a11y.css/-/a11y.css-5.3.0.tgz", + "integrity": "sha512-WBEnwAT3NHyJFN0ejedhc4Q0U4yX2fNWmoee8Ai6TWIICjrocTNugXm8XFuIC8dI8goaIoqxnSd4PlnljJ8dxw==" + }, "node_modules/abbrev": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", @@ -16967,6 +16973,11 @@ "dev": true, "peer": true }, + "a11y.css": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/a11y.css/-/a11y.css-5.3.0.tgz", + "integrity": "sha512-WBEnwAT3NHyJFN0ejedhc4Q0U4yX2fNWmoee8Ai6TWIICjrocTNugXm8XFuIC8dI8goaIoqxnSd4PlnljJ8dxw==" + }, "abbrev": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", diff --git a/package.json b/package.json index 22d90cb..7417227 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,10 @@ { "from": "node_modules/@sealcode/sealcodemirror/mode/javascript/javascript.js", "to": "dist/codemirror-javascript-mode.js" + }, + { + "from": "node_modules/a11y.css/css", + "to": "dist/a11y.css" } ] }, @@ -105,6 +109,7 @@ "@types/leaflet": "^1.9.8", "@types/object-hash": "^3.0.6", "@types/simplemde": "^1.11.11", + "a11y.css": "^5.3.0", "c8": "^10.1.3", "colord": "^2.9.3", "dotenv": "^16.4.5", diff --git a/src/back/a11y_overrides.css b/src/back/a11y_overrides.css new file mode 100644 index 0000000..ae442c7 --- /dev/null +++ b/src/back/a11y_overrides.css @@ -0,0 +1,11 @@ +/* we properly embed charset metadata, but Turbo changes the order of elements in and this rule gives a false positive */ +head :first-child:not([charset]) { + &, + &::after { + display: none !important; + } +} + +head :first-child:not([charset]) ~ link:last-of-type::before { + display: none !important; +} diff --git a/src/back/config.ts b/src/back/config.ts index 105c18d..b46967d 100644 --- a/src/back/config.ts +++ b/src/back/config.ts @@ -48,3 +48,4 @@ export const UPLOADS_FS_DIR = process.env.UPLOADS_FS_DIR || locreq.resolve("uploaded_files"); export const MEILISEARCH_MASTER_KEY = process.env.MEILISEARCH_MASTER_KEY || "qwerty"; export const MEILISEARCH_HOST = process.env.MEILISEARCH_HOST || "http://localhost:1098"; +export const SCAN_A11Y = false; diff --git a/src/back/defaultHead.tsx b/src/back/defaultHead.tsx index 2f4ef06..e9fb9f6 100644 --- a/src/back/defaultHead.tsx +++ b/src/back/defaultHead.tsx @@ -3,6 +3,7 @@ import type { Readable } from "stream"; import type { Context } from "koa"; import type { HTMLOptions } from "@sealcode/sealgen"; import { htmlEscape } from "escape-goat"; +import { SCAN_A11Y } from "./config.js"; export const start_timestamp = Date.now(); @@ -24,7 +25,8 @@ export function defaultHead({ description: string; }): JSX.Element | Readable { const origin = ctx.URL.origin; - return tempstream /* HTML */ `${title} + return tempstream /* HTML */ ` ${title} + ${SCAN_A11Y ? `` : ""} diff --git a/src/back/html.tsx b/src/back/html.tsx index 438c15a..9b13cf3 100644 --- a/src/back/html.tsx +++ b/src/back/html.tsx @@ -40,6 +40,8 @@ export default function html({ controllers.push("refresh-on-ts-changes"); } + const classes = (htmlOptions?.bodyClasses || []).join(" "); + return tempstreamAsync /* HTML */ ` ${!hideNavigation ? (htmlOptions?.navbar || default_navbar)(ctx) : ""} ${body} From c62adb475279a5a7a8f3b3be62648460f6b59edf Mon Sep 17 00:00:00 2001 From: PrzZiomek2 Date: Thu, 2 Apr 2026 17:13:31 +0200 Subject: [PATCH 16/18] allow custom breadcrumbs label Summary: Ref T3092 Reviewers: kuba-orlik Reviewed By: kuba-orlik Maniphest Tasks: T3092 Differential Revision: https://hub.sealcode.org/D1681 --- src/back/routes/common/breadcrumbs.tsx | 48 +++++++++++++------------- src/back/routes/hello-page.page.tsx | 3 ++ src/back/routes/url-tree.ts | 33 +++++++++++++++--- 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/src/back/routes/common/breadcrumbs.tsx b/src/back/routes/common/breadcrumbs.tsx index a41e954..f0a9c84 100644 --- a/src/back/routes/common/breadcrumbs.tsx +++ b/src/back/routes/common/breadcrumbs.tsx @@ -43,29 +43,29 @@ function arrow_head() { ); } -export function breadcrumbs(ctx: Context) { - return ( - +export async function breadcrumbs(ctx: Context) { + const breadcrumbs = await Promise.all( + get_breadcrumbs_from_path(ctx.path).map(async (e, i, all) => { + if (!e.actionName) { + return ""; + } + + const breadcrumbLabel = e.breadcrumbLabel?.({ ...ctx }); + const breadcrumbLabelResult = await breadcrumbLabel; + + if (i == all.length - 1) { + return {breadcrumbLabelResult || e.actionName}; + } + return ( + <> + + {i !== 0 ? arrow_tail() : ""} + {breadcrumbLabelResult || e.actionName} + {arrow_head()} + + + ); + }) ); + return ; } diff --git a/src/back/routes/hello-page.page.tsx b/src/back/routes/hello-page.page.tsx index 34bf7f7..244a612 100644 --- a/src/back/routes/hello-page.page.tsx +++ b/src/back/routes/hello-page.page.tsx @@ -2,9 +2,12 @@ import type { Context } from "koa"; import { TempstreamJSX } from "tempstream"; import { Page } from "@sealcode/sealgen"; +import type { BreadcrumbLabel } from "@sealcode/sealgen"; + import html from "src/back/html.js"; export const actionName = "HelloPage"; +export const breadcrumbLabel: BreadcrumbLabel = "Witaj"; export default new (class HelloPagePage extends Page { // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/src/back/routes/url-tree.ts b/src/back/routes/url-tree.ts index 864bf82..9b5f92c 100644 --- a/src/back/routes/url-tree.ts +++ b/src/back/routes/url-tree.ts @@ -1,12 +1,17 @@ +import * as path from "path"; +import type { Context } from "koa"; import { url_tree } from "./routes.js"; import type { URLTree } from "./routes.js"; +import type { BreadcrumbLabel } from "@sealcode/sealgen"; export function get_breadcrumbs_from_path(url: string) { let position: URLTree = url_tree; const elements = url.split("/").filter((e) => e != ""); - const breadcrumbs: { actionName?: string; url?: string }[] = [ - { actionName: "Home", url: "/" }, - ]; + const breadcrumbs: { + actionName?: string; + url?: string; + breadcrumbLabel?: (ctx: Context) => Promise; + }[] = [{ actionName: "Home", url: "/" }]; let path_so_far = ""; for (const element of elements) { if (position.children[element]) { @@ -18,7 +23,27 @@ export function get_breadcrumbs_from_path(url: string) { break; } path_so_far += "/" + element; - breadcrumbs.push({ actionName: position.actionName, url: path_so_far }); + const actionName = position.actionName; + const modulePath = position.module_path; + + breadcrumbs.push({ + actionName: actionName, + url: path_so_far, + breadcrumbLabel: async (ctx: Context) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/consistent-type-assertions + const module = (await import(path.resolve(modulePath || "") || "")) as { + breadcrumbLabel: BreadcrumbLabel; + }; + + if (!module.breadcrumbLabel) return actionName || ""; + + if (typeof module.breadcrumbLabel === "function") { + return module.breadcrumbLabel(ctx); + } else { + return module.breadcrumbLabel; + } + }, + }); } return breadcrumbs; } From f10bc895107bbcfe0b6dc3669a4e387b0accee72 Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Thu, 16 Apr 2026 18:22:36 +0200 Subject: [PATCH 17/18] Update jdd-editor and sealgen to fix markdown editor freezing --- package-lock.json | 28 ++++++++++++++-------------- package.json | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 06947cb..dafb579 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,9 +15,9 @@ "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.6", - "@sealcode/jdd-editor": "^0.2.17", + "@sealcode/jdd-editor": "^0.2.18", "@sealcode/monaco-wrapper": "^0.0.4", - "@sealcode/sealgen": "^0.19.18", + "@sealcode/sealgen": "^0.19.20", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", "@sealcode/sortable": "^0.0.1", @@ -1380,9 +1380,9 @@ } }, "node_modules/@sealcode/jdd-editor": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.17.tgz", - "integrity": "sha512-Zc2cg0PpVIgls5Egub0oJZIPjCCKw+f66ZtmMmwJzb+rfYzs8W2uGhC0MZyAyzWpsybH1cTHOJe7W1p4douwxw==", + "version": "0.2.18", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.18.tgz", + "integrity": "sha512-14oT7FDjKWuH5aMm5C2jsdpFAGjz+cQjomj4aLMrMkPUtPSYtKV7CUxseM+OJKynSJl05iPTAtc1FebydqlRHQ==", "dependencies": { "@koa/router": "^13.1.0", "@sealcode/jdd": "^0.8.6", @@ -1472,9 +1472,9 @@ "integrity": "sha512-pDsGlk2KokQkwzsJDBUWJFDRpEoxxth6TMQGDJyCTmWnd1Vn+cQb5moXDKaf7cXnWb9Y6QtdNX/fPzM/3RH2Cg==" }, "node_modules/@sealcode/sealgen": { - "version": "0.19.18", - "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.18.tgz", - "integrity": "sha512-bdEDaSKtvMGH8JT7dIwhxJI9ZaJd1d7eMzWZIQay/du3KYqLcnAhx6eFPBRXskaWJBwGkyJZiLQJgRQ+06+EqQ==", + "version": "0.19.20", + "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.20.tgz", + "integrity": "sha512-x7sI3/C7WtaM23v2lF540Dn0FNw1cAvBfi14Mw4cNHjZKQS7JOv2PjODwm+DOMCTsFtUrz/ElNBCvos0H34tjw==", "dependencies": { "@koa/router": "^12.0.1", "@sealcode/file-manager": "^1.0.2", @@ -16021,9 +16021,9 @@ } }, "@sealcode/jdd-editor": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.17.tgz", - "integrity": "sha512-Zc2cg0PpVIgls5Egub0oJZIPjCCKw+f66ZtmMmwJzb+rfYzs8W2uGhC0MZyAyzWpsybH1cTHOJe7W1p4douwxw==", + "version": "0.2.18", + "resolved": "https://registry.npmjs.org/@sealcode/jdd-editor/-/jdd-editor-0.2.18.tgz", + "integrity": "sha512-14oT7FDjKWuH5aMm5C2jsdpFAGjz+cQjomj4aLMrMkPUtPSYtKV7CUxseM+OJKynSJl05iPTAtc1FebydqlRHQ==", "requires": { "@koa/router": "^13.1.0", "@sealcode/jdd": "^0.8.6", @@ -16095,9 +16095,9 @@ "integrity": "sha512-pDsGlk2KokQkwzsJDBUWJFDRpEoxxth6TMQGDJyCTmWnd1Vn+cQb5moXDKaf7cXnWb9Y6QtdNX/fPzM/3RH2Cg==" }, "@sealcode/sealgen": { - "version": "0.19.18", - "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.18.tgz", - "integrity": "sha512-bdEDaSKtvMGH8JT7dIwhxJI9ZaJd1d7eMzWZIQay/du3KYqLcnAhx6eFPBRXskaWJBwGkyJZiLQJgRQ+06+EqQ==", + "version": "0.19.20", + "resolved": "https://registry.npmjs.org/@sealcode/sealgen/-/sealgen-0.19.20.tgz", + "integrity": "sha512-x7sI3/C7WtaM23v2lF540Dn0FNw1cAvBfi14Mw4cNHjZKQS7JOv2PjODwm+DOMCTsFtUrz/ElNBCvos0H34tjw==", "requires": { "@koa/router": "^12.0.1", "@sealcode/file-manager": "^1.0.2", diff --git a/package.json b/package.json index 7417227..e840429 100644 --- a/package.json +++ b/package.json @@ -98,9 +98,9 @@ "@sealcode/add-to-head": "^1.0.0", "@sealcode/file-manager": "^1.0.2", "@sealcode/jdd": "^0.8.6", - "@sealcode/jdd-editor": "^0.2.17", + "@sealcode/jdd-editor": "^0.2.18", "@sealcode/monaco-wrapper": "^0.0.4", - "@sealcode/sealgen": "^0.19.18", + "@sealcode/sealgen": "^0.19.20", "@sealcode/show-first-row": "^0.1.0", "@sealcode/simplemde": "^1.12.1", "@sealcode/sortable": "^0.0.1", From da327a633b9769496ff501a21bf859f8b9be15ab Mon Sep 17 00:00:00 2001 From: Kuba Orlik Date: Sun, 3 May 2026 18:54:26 +0200 Subject: [PATCH 18/18] Make border-box the default box-sizing to avoid weird unpredictable layout behaviors --- src/main.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main.css b/src/main.css index b78685e..43e001b 100644 --- a/src/main.css +++ b/src/main.css @@ -1,3 +1,7 @@ +* { + box-sizing: border-box; +} + html { background: var(--color-brand-canvas); font-family: var(--font-sans-serif);