diff --git a/CLAUDE.md b/CLAUDE.md index be265e5bd0..c4375259b7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -118,6 +118,8 @@ Trilium provides powerful user scripting capabilities: ### Internationalization - Translation files in `apps/client/src/translations/` - Supported languages: English, German, Spanish, French, Romanian, Chinese +- **Only add new translation keys to `en/translation.json`** — translations for other languages are managed via Weblate and will be contributed by the community +- Third-party components (e.g., mind-map context menu) should use i18next `t()` for their labels, with the English strings added to `en/translation.json` under a dedicated namespace (e.g., `"mind-map"`) ### Security Considerations - Per-note encryption with granular protected sessions diff --git a/apps/client/package.json b/apps/client/package.json index d6c6544a6a..a0a90ec9f6 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -65,7 +65,7 @@ "mark.js": "8.11.1", "marked": "17.0.5", "mermaid": "11.13.0", - "mind-elixir": "5.9.3", + "mind-elixir": "5.10.0", "normalize.css": "8.0.1", "panzoom": "9.4.4", "preact": "10.29.0", diff --git a/apps/client/src/translations/en/translation.json b/apps/client/src/translations/en/translation.json index 8cbf27d4d9..0ee627e9da 100644 --- a/apps/client/src/translations/en/translation.json +++ b/apps/client/src/translations/en/translation.json @@ -2277,6 +2277,20 @@ "sample_venn": "Venn", "sample_ishikawa": "Ishikawa" }, + "mind-map": { + "addChild": "Add child", + "addParent": "Add parent", + "addSibling": "Add sibling", + "removeNode": "Remove node", + "focus": "Focus Mode", + "cancelFocus": "Cancel Focus Mode", + "moveUp": "Move up", + "moveDown": "Move down", + "link": "Link", + "linkBidirectional": "Bidirectional Link", + "clickTips": "Please click the target node", + "summary": "Summary" + }, "llm": { "settings_title": "AI / LLM", "settings_description": "Configure AI and Large Language Model integrations.", diff --git a/apps/client/src/widgets/type_widgets/MindMap.tsx b/apps/client/src/widgets/type_widgets/MindMap.tsx index a728398560..d4a3ff1841 100644 --- a/apps/client/src/widgets/type_widgets/MindMap.tsx +++ b/apps/client/src/widgets/type_widgets/MindMap.tsx @@ -4,9 +4,10 @@ import "./MindMap.css"; // allow node-menu plugin css to be bundled by webpack import nodeMenu from "@mind-elixir/node-menu"; -import { DISPLAYABLE_LOCALE_IDS } from "@triliumnext/commons"; import { snapdom } from "@zumer/snapdom"; -import { DARK_THEME, default as VanillaMindElixir, MindElixirData, MindElixirInstance, Operation, Options, THEME as LIGHT_THEME } from "mind-elixir"; +import { t } from "i18next"; +import { DARK_THEME, default as VanillaMindElixir, MindElixirData, MindElixirInstance, Operation, THEME as LIGHT_THEME } from "mind-elixir"; +import type { LangPack } from "mind-elixir/i18n"; import { HTMLAttributes, RefObject } from "preact"; import { useCallback, useEffect, useRef } from "preact/hooks"; @@ -25,27 +26,22 @@ interface MindElixirProps { onChange?: () => void; } -const LOCALE_MAPPINGS: Record = { - ar: null, - cn: "zh_CN", - de: null, - en: "en", - en_rtl: "en", - "en-GB": "en", - es: "es", - fr: "fr", - ga: null, - it: "it", - hi: null, - ja: "ja", - pt: "pt", - pl: null, - pt_br: "pt", - ro: "ro", - ru: "ru", - tw: "zh_TW", - uk: null -}; +function buildMindElixirLangPack(): LangPack { + return { + addChild: t("mind-map.addChild"), + addParent: t("mind-map.addParent"), + addSibling: t("mind-map.addSibling"), + removeNode: t("mind-map.removeNode"), + focus: t("mind-map.focus"), + cancelFocus: t("mind-map.cancelFocus"), + moveUp: t("mind-map.moveUp"), + moveDown: t("mind-map.moveDown"), + link: t("mind-map.link"), + linkBidirectional: t("mind-map.linkBidirectional"), + clickTips: t("mind-map.clickTips"), + summary: t("mind-map.summary") + }; +} export default function MindMap({ note, ntxId, noteContext }: TypeWidgetProps) { const apiRef = useRef(null); @@ -161,8 +157,8 @@ function MindElixir({ containerRef: externalContainerRef, containerProps, apiRef const mind = new VanillaMindElixir({ el: containerRef.current, - locale: LOCALE_MAPPINGS[locale as DISPLAYABLE_LOCALE_IDS] ?? undefined, editable, + contextMenu: { locale: buildMindElixirLangPack() }, theme: defaultColorScheme.current === "dark" ? DARK_THEME : LIGHT_THEME }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f0e8dbbda0..2ef2ef74a3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -218,7 +218,7 @@ importers: version: 0.2.1(mermaid@11.13.0) '@mind-elixir/node-menu': specifier: 5.0.1 - version: 5.0.1(mind-elixir@5.9.3) + version: 5.0.1(mind-elixir@5.10.0) '@popperjs/core': specifier: 2.11.8 version: 2.11.8 @@ -334,8 +334,8 @@ importers: specifier: 11.13.0 version: 11.13.0 mind-elixir: - specifier: 5.9.3 - version: 5.9.3 + specifier: 5.10.0 + version: 5.10.0 normalize.css: specifier: 8.0.1 version: 8.0.1 @@ -11846,8 +11846,8 @@ packages: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} - mind-elixir@5.9.3: - resolution: {integrity: sha512-OTTO6ofvDuzN4fxuBngqhQLJmIqModr2NgQb4OY+5DGRt54B+YNAvNnlspYwUXXGq2Rbht1DhXgeU4dr4CUy6Q==} + mind-elixir@5.10.0: + resolution: {integrity: sha512-AY/tDXz8stMbx0MIutdn63Dz0uwY1VVMKIxCqOOA2hg5WGdCGm2qqEZF498deLDxoZbL+hDf1SwBWzvWADBoPA==} mini-css-extract-plugin@2.9.4: resolution: {integrity: sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ==} @@ -19961,9 +19961,9 @@ snapshots: '@microsoft/tsdoc@0.15.1': {} - '@mind-elixir/node-menu@5.0.1(mind-elixir@5.9.3)': + '@mind-elixir/node-menu@5.0.1(mind-elixir@5.10.0)': dependencies: - mind-elixir: 5.9.3 + mind-elixir: 5.10.0 '@mixmark-io/domino@2.2.0': {} @@ -30188,7 +30188,7 @@ snapshots: mimic-response@3.1.0: {} - mind-elixir@5.9.3: {} + mind-elixir@5.10.0: {} mini-css-extract-plugin@2.9.4(webpack@5.101.3(@swc/core@1.11.29(@swc/helpers@0.5.17))(esbuild@0.27.4)): dependencies: