Compare commits

...

477 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
18810bb86f Address code review feedback - improve outputSubDir handling
Improved the importAndExportDocs function to better handle the empty outputSubDir case:
- Use meaningful name for temporary zip file ('user-guide' instead of '')
- Explicitly handle empty outputSubDir for root directory output
- Added comments to clarify the behavior

Co-authored-by: eliandoran <21236836+eliandoran@users.noreply.github.com>
2025-11-02 22:31:25 +00:00
copilot-swe-agent[bot]
4f442551a9 Integrate Developer Guide into documentation build process
Added Developer Guide to the documentation build process alongside the User Guide.
- Modified build-docs.ts to import and export both User Guide and Developer Guide
- Created importAndExportDocs helper function to handle multiple documentation sources
- Developer Guide is exported to /site/developer-guide/ subdirectory
- Updated GitHub workflow to validate Developer Guide is built
- Added build-docs app to workflow triggers

The documentation build now produces:
- User Guide at /site/ (root) and /site/user-guide/
- Developer Guide at /site/developer-guide/
- Script API at /site/script-api/{backend,frontend}/
- REST API at /site/rest-api/{internal,etapi}/

Co-authored-by: eliandoran <21236836+eliandoran@users.noreply.github.com>
2025-11-02 22:28:24 +00:00
copilot-swe-agent[bot]
a8f565d912 Remove build artifacts from git and update .gitignore 2025-11-02 22:23:43 +00:00
copilot-swe-agent[bot]
0c6a57d3bb Fix documentation build system - resolve becca module instance issue
Fixed the issue where multiple becca instances were being created due to inconsistent module import paths. The solution was to export becca from becca_loader and access it from there, ensuring a single instance is used throughout the build process.

Co-authored-by: eliandoran <21236836+eliandoran@users.noreply.github.com>
2025-11-02 22:18:49 +00:00
copilot-swe-agent[bot]
01deab9c79 Initial plan 2025-11-02 21:57:43 +00:00
Elian Doran
a5a90b582a Translations update from Hosted Weblate (#7597) 2025-11-02 23:05:06 +02:00
Hosted Weblate
510601037d Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/
2025-11-02 20:35:51 +00:00
Eugene
b312b6f3bc Translated using Weblate (Russian)
Currently translated at 15.1% (23 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/ru/
2025-11-02 20:35:47 +00:00
Eugene
0c1efd3402 Translated using Weblate (Russian)
Currently translated at 64.4% (76 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/ru/
2025-11-02 20:35:46 +00:00
Elian Doran
69182a1a42 feat(mermaid): add link to docs (closes #5378) 2025-11-02 22:32:36 +02:00
Elian Doran
8a63f2028c docs(user): update link to ETAPI 2025-11-02 22:20:41 +02:00
Elian Doran
947330ed73 chore(options/etapi): update help 2025-11-02 22:08:42 +02:00
Elian Doran
4526455486 fix(help): webview source not updating 2025-11-02 21:40:21 +02:00
Elian Doran
1d259aab9d Improve documentation building & static Swagger (#7570) 2025-11-02 20:24:58 +02:00
Elian Doran
5171675dee chore(build-docs): fix URL 2025-11-02 20:13:10 +02:00
Elian Doran
6bc54892a3 Update apps/build-docs/src/swagger.ts
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-02 20:12:50 +02:00
Elian Doran
0a6670ce5e Update apps/build-docs/src/backend_script_entrypoint.ts
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-11-02 20:05:44 +02:00
Elian Doran
beb7c66ff5 feat(build-docs): rewrite URLs for in-app help 2025-11-02 19:45:16 +02:00
Elian Doran
966e5a2ef3 chore(build-docs): update meta 2025-11-02 18:33:13 +02:00
Elian Doran
4f5be54030 chore(build-docs): generate types for doc 2025-11-02 18:28:31 +02:00
Elian Doran
68c6260e45 chore(build-docs): relocate OpenAPI location 2025-11-02 18:14:03 +02:00
Elian Doran
85bfd49d1c Merge remote-tracking branch 'origin/main' into feature/api_docs
; Conflicts:
;	_regroup/package.json
;	pnpm-lock.yaml
2025-11-02 18:05:02 +02:00
Elian Doran
23f2e1eb45 chore(deps): update dependency eslint-plugin-playwright to v2.3.0 (#7585) 2025-11-02 12:15:15 +02:00
Elian Doran
9bbd6d146b fix(deps): update dependency globals to v16.5.0 (#7591) 2025-11-02 12:14:40 +02:00
Elian Doran
37aa8ec176 chore(deps): update node.js to v24 (#7593) 2025-11-02 12:14:22 +02:00
renovate[bot]
05f3f9627d chore(deps): update node.js to v24 2025-11-02 09:31:25 +00:00
Elian Doran
a9fa99cadf chore(deps): update dependency @smithy/middleware-retry to v4.4.6 (#7574) 2025-11-02 11:30:19 +02:00
Elian Doran
d5c1604a58 chore(deps): update dependency axios to v1.13.1 (#7575) 2025-11-02 11:29:30 +02:00
Elian Doran
e99f821e88 chore(deps): update dependency chardet to v2.1.1 (#7576) 2025-11-02 11:29:19 +02:00
renovate[bot]
6571ff9d84 fix(deps): update dependency globals to v16.5.0 2025-11-02 09:29:14 +00:00
Elian Doran
9d63ef20fb chore(deps): update dependency esbuild to v0.25.12 (#7577) 2025-11-02 11:29:06 +02:00
renovate[bot]
71a3cf0cfe chore(deps): update dependency eslint-plugin-playwright to v2.3.0 2025-11-02 09:28:29 +00:00
Elian Doran
e5e55e1cf1 chore(deps): update dependency happy-dom to v20.0.10 (#7578) 2025-11-02 11:28:12 +02:00
Elian Doran
83b13cae92 chore(deps): update dependency ollama to v0.6.2 (#7579) 2025-11-02 11:27:57 +02:00
Elian Doran
6663c3abc1 fix(deps): update dependency dayjs to v1.11.19 (#7581) 2025-11-02 11:27:37 +02:00
renovate[bot]
738b28c2b3 chore(deps): update dependency esbuild to v0.25.12 2025-11-02 09:27:32 +00:00
Elian Doran
4eec6021c3 fix(deps): update dependency react-i18next to v16.2.3 (#7582) 2025-11-02 11:27:12 +02:00
Elian Doran
39bda30853 chore(deps): update dependency @anthropic-ai/sdk to v0.68.0 (#7583) 2025-11-02 11:26:57 +02:00
Elian Doran
6adcaca5e0 chore(deps): update dependency electron to v38.5.0 (#7584) 2025-11-02 11:26:49 +02:00
Elian Doran
5a5f71fc71 chore(deps): update dependency express-rate-limit to v8.2.1 (#7586) 2025-11-02 11:26:01 +02:00
Elian Doran
f3765f95b5 chore(deps): update dependency node-abi to v4.17.0 (#7587) 2025-11-02 11:25:45 +02:00
Elian Doran
6ebb0eb03e chore(deps): update dependency rimraf to v6.1.0 (#7588) 2025-11-02 11:25:30 +02:00
Elian Doran
b42aa32b72 chore(deps): update pnpm to v10.20.0 (#7589) 2025-11-02 11:25:13 +02:00
Elian Doran
11e1ea7ea5 fix(deps): update dependency eslint-linter-browserify to v9.39.0 (#7590) 2025-11-02 11:24:51 +02:00
Elian Doran
5f6fac994f fix(deps): update eslint monorepo to v9.39.0 (#7592) 2025-11-02 11:24:15 +02:00
Elian Doran
d7460e9fe5 chore(renovate): ignore legacy Dockerfile from Renovate updates 2025-11-02 11:22:29 +02:00
renovate[bot]
89585e38ce fix(deps): update eslint monorepo to v9.39.0 2025-11-02 02:03:29 +00:00
renovate[bot]
938c6e356b fix(deps): update dependency eslint-linter-browserify to v9.39.0 2025-11-02 02:01:50 +00:00
renovate[bot]
b7dd806d07 chore(deps): update pnpm to v10.20.0 2025-11-02 02:01:05 +00:00
renovate[bot]
a1d86cef58 chore(deps): update dependency rimraf to v6.1.0 2025-11-02 02:00:54 +00:00
renovate[bot]
1fec5bb564 chore(deps): update dependency node-abi to v4.17.0 2025-11-02 02:00:49 +00:00
renovate[bot]
35e98addc8 chore(deps): update dependency express-rate-limit to v8.2.1 2025-11-02 01:59:58 +00:00
renovate[bot]
79290633b1 chore(deps): update dependency electron to v38.5.0 2025-11-02 01:58:25 +00:00
renovate[bot]
ffc9e715ef chore(deps): update dependency @anthropic-ai/sdk to v0.68.0 2025-11-02 01:57:40 +00:00
renovate[bot]
8f8302c4a3 fix(deps): update dependency react-i18next to v16.2.3 2025-11-02 01:56:54 +00:00
renovate[bot]
136b449f60 fix(deps): update dependency dayjs to v1.11.19 2025-11-02 01:56:07 +00:00
renovate[bot]
61319c3a14 chore(deps): update dependency ollama to v0.6.2 2025-11-02 01:55:13 +00:00
renovate[bot]
104a1f0c3a chore(deps): update dependency happy-dom to v20.0.10 2025-11-02 01:54:26 +00:00
renovate[bot]
16200312ce chore(deps): update dependency chardet to v2.1.1 2025-11-02 01:52:16 +00:00
renovate[bot]
664de68d53 chore(deps): update dependency axios to v1.13.1 2025-11-02 01:51:29 +00:00
renovate[bot]
6190949dcc chore(deps): update dependency @smithy/middleware-retry to v4.4.6 2025-11-02 01:50:40 +00:00
Elian Doran
3ac248169f chore(build-docs): fix typecheck issues 2025-11-01 23:40:27 +02:00
Elian Doran
15e240ac33 refactor(build-docs): remove old Swagger integration 2025-11-01 23:37:17 +02:00
Elian Doran
d30fc09e73 chore(build-docs): fix link to FNote 2025-11-01 23:13:35 +02:00
Elian Doran
6a2b9b748f chore(build-docs): add project names to typedoc 2025-11-01 23:03:14 +02:00
Elian Doran
b5e2187c0d chore(build-docs): update meta 2025-11-01 23:00:14 +02:00
Elian Doran
d9a349a531 refactor(build-docs): define output for typedoc at script level 2025-11-01 22:54:42 +02:00
Elian Doran
2c1cebfbc3 feat(build-docs): split documentation in two 2025-11-01 22:51:33 +02:00
Elian Doran
c6738ac52f feat(build-docs): generate script API 2025-11-01 22:42:27 +02:00
Elian Doran
604f2abf5a chore(build-docs): fix wrong mkdir 2025-11-01 21:47:07 +02:00
Elian Doran
617703899f chore(build-docs): relocate to /rest-api 2025-11-01 21:35:18 +02:00
Elian Doran
6322ca11c9 feat(share): improve webview layout 2025-11-01 21:28:31 +02:00
Elian Doran
d62aecc551 fix(build-docs): crash in clean environment 2025-11-01 21:15:34 +02:00
Elian Doran
953b376ce3 refactor(build-docs): trigger build of share theme internally 2025-11-01 20:58:32 +02:00
Elian Doran
80f1707d8b chore(build-docs): integrate with docs:build 2025-11-01 20:52:28 +02:00
Elian Doran
4f9f8652e2 fix(build-docs): links to API reference 2025-11-01 20:47:00 +02:00
Elian Doran
6e06d7169f refactor(build-docs): integrate with original build-docs script 2025-11-01 20:37:03 +02:00
Elian Doran
ecf12a4063 feat(build-docs): build both docs 2025-11-01 20:22:17 +02:00
Elian Doran
64428ae761 feat(build-docs): clean before building 2025-11-01 20:16:59 +02:00
Elian Doran
3524c34ff9 feat(build-docs): switch to redocly 2025-11-01 20:15:38 +02:00
Elian Doran
3f99c8b337 feat(build-docs): copy swagger UI 2025-11-01 20:03:53 +02:00
Elian Doran
27d9ae885f Merge branch 'main' of github.com:TriliumNext/Trilium 2025-11-01 19:36:11 +02:00
Elian Doran
35efd2a680 test(server): broken test due to CLS 2025-11-01 16:48:49 +02:00
Elian Doran
19c6ae6fe5 Keyboard shortcut for today note button (#7549) 2025-11-01 16:17:24 +02:00
SngAbc
bf0761a303 Fix: activate the nearest path when opening a cloned note (#7552) 2025-11-01 16:06:26 +02:00
Weblate (bot)
8391fd7534 Translations update from Hosted Weblate (#7566)
* Update translation files

Updated by "Cleanup translation files" add-on in Weblate.

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/

* Translated using Weblate (Portuguese)

Currently translated at 9.2% (14 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/pt/

---------

Co-authored-by: Francisco Machado <kikomachado089@gmail.com>
2025-11-01 16:04:10 +02:00
SngAbc
6d4b87888a fix(electron): allow extra window to reload (#7567) 2025-11-01 16:02:17 +02:00
Weblate (bot)
3f0b0f9b62 Translations update from Hosted Weblate (#7565) 2025-11-01 14:09:26 +02:00
Elian Doran
859d9dcd04 docs(user): document system requirements 2025-10-31 11:52:40 +02:00
Elian Doran
76dd9baea8 docs(user): document adjusting borders 2025-10-31 11:21:17 +02:00
Elian Doran
82ff5f6660 docs(user): sync 2025-10-31 11:07:22 +02:00
Elian Doran
b52d30c55a chore(dialog/export): strange order with OPML 2025-10-31 11:05:40 +02:00
Elian Doran
99fd088ff5 chore(share): use same sandbox features for iframe 2025-10-31 10:12:56 +02:00
Elian Doran
945f29c759 feat(share): render webviews using iframe 2025-10-31 10:12:15 +02:00
Elian Doran
98f42887d8 Translations update from Hosted Weblate (#7562) 2025-10-31 09:09:29 +02:00
Eduard Frigola
a1b589148b Translated using Weblate (Catalan)
Currently translated at 17.8% (69 of 387 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/ca/
2025-10-31 08:04:01 +01:00
Elian Doran
66bb639a15 docs(user): port patterns of personal knowledge 2025-10-30 22:50:14 +02:00
Elian Doran
1784b50990 docs(user): port privacy policy 2025-10-30 22:37:59 +02:00
Elian Doran
5e9c271bfd docs(release): port v0.48 changelog 2025-10-30 22:36:41 +02:00
Elian Doran
70837fdc69 Translations update from Hosted Weblate (#7559) 2025-10-30 16:07:11 +02:00
Hosted Weblate
67d80512f6 Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/
2025-10-30 13:46:35 +00:00
Elian Doran
dd8a1e8aca docs(user): document all share theme attributes 2025-10-30 15:46:13 +02:00
Elian Doran
99f43e2280 docs(user): improve fine-grained directory path documentation 2025-10-30 12:02:32 +02:00
Elian Doran
bcffa77c90 docs(user): index page for import/export 2025-10-30 11:54:44 +02:00
Elian Doran
8ab2069411 docs(user): fix empty section in kanban board 2025-10-30 11:43:48 +02:00
Elian Doran
21fc61d132 docs(user): restructure LLM section 2025-10-30 11:42:46 +02:00
Elian Doran
552df50fe4 docs(user): add icons to most notes 2025-10-30 11:40:07 +02:00
Elian Doran
c058b663ee Translations update from Hosted Weblate (#7556) 2025-10-30 09:05:27 +02:00
Francis C
6c19370235 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (152 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/zh_Hant/
2025-10-30 07:50:44 +01:00
Francis C
d332bb57ba Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (152 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/zh_Hans/
2025-10-30 07:50:44 +01:00
Antonio Sanchez Castellón
3ef38e7f4e Translated using Weblate (Spanish)
Currently translated at 100.0% (152 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/es/
2025-10-30 07:50:43 +01:00
Francis C
1abc3b5534 Translated using Weblate (Japanese)
Currently translated at 100.0% (1621 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ja/
2025-10-30 07:50:42 +01:00
Francis C
ddcd27ddf6 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (387 of 387 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/zh_Hant/
2025-10-30 07:50:41 +01:00
Francis C
ff385c8c88 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (1621 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hant/
2025-10-30 07:50:40 +01:00
Antonio Sanchez Castellón
a641e452ce Translated using Weblate (Spanish)
Currently translated at 100.0% (387 of 387 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/es/
2025-10-30 07:50:39 +01:00
Francis C
5f4fa25da5 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (387 of 387 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/zh_Hans/
2025-10-30 07:50:38 +01:00
Antonio Sanchez Castellón
ea177e972e Translated using Weblate (Spanish)
Currently translated at 100.0% (1621 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/es/
2025-10-30 07:50:38 +01:00
Manfred Manni
7e3013bfdc Translated using Weblate (German)
Currently translated at 100.0% (1621 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2025-10-30 07:50:37 +01:00
Francis C
5115baeb21 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (1621 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hans/
2025-10-30 07:50:36 +01:00
Hosted Weblate
35a924a05a Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/
2025-10-30 07:50:36 +01:00
Elian Doran
78f067965f fix(share): TOC indicator no longer working due to layout changes 2025-10-30 08:49:48 +02:00
Elian Doran
413b16b51c chore(collections): rename Board to Kanban Board 2025-10-30 08:42:00 +02:00
Elian Doran
59586c53b2 chore(website): rename Board to Kanban Board 2025-10-30 08:34:28 +02:00
Elian Doran
70ed1d7abb chore(website): fix URLs pointing to documentation 2025-10-30 08:33:54 +02:00
Elian Doran
67de6c614c docs(user): change alias for server documentation 2025-10-30 08:31:26 +02:00
Elian Doran
faf030ab3a docs(user): minor improvements to the collection main page 2025-10-30 08:18:13 +02:00
Elian Doran
6e20d4b5dd docs(user): rename Board to Kanban Board 2025-10-30 08:15:57 +02:00
Elian Doran
10e809af75 docs(user): rename and reorder collection pages 2025-10-30 08:14:22 +02:00
Elian Doran
f1478f8149 docs(user): change presentation method for collections 2025-10-30 08:13:34 +02:00
Elian Doran
9087adf254 docs(user): move collections one level up 2025-10-30 08:07:09 +02:00
Elian Doran
f944c6d8e2 docs(user): add slug + tips on how to identify pages without one easily 2025-10-30 08:03:09 +02:00
Elian Doran
444e103047 docs(dev): document exporting functionality 2025-10-29 22:36:45 +02:00
Elian Doran
1d6ab64ae5 docs(guide): document exporting for web publishing 2025-10-29 22:21:15 +02:00
Elian Doran
0bc86d7c75 docs(guide): deduplicate home page with quick start 2025-10-29 22:00:31 +02:00
Elian Doran
cfd55147df Deploy share-based static documentation (#7548) 2025-10-29 21:27:49 +02:00
Elian Doran
754bb61a52 feat(export/share): render 404 page 2025-10-29 21:05:50 +02:00
Elian Doran
4f103375b5 fix(share): 404 not rendering in dev mode 2025-10-29 20:20:35 +02:00
Elian Doran
496091677b style(share): overflow on wrong element 2025-10-29 20:14:32 +02:00
Elian Doran
618b67f551 fix(share): redesign layout to avoid jumping on tablets 2025-10-29 20:02:02 +02:00
contributor
9c791df0ed open today note in current tab #7472
https://github.com/TriliumNext/Trilium/pull/7549#issuecomment-3458822614
2025-10-29 19:22:13 +02:00
Elian Doran
ce4f46c226 chore(share): fix relative imports 2025-10-29 19:13:11 +02:00
Elian Doran
44cfbcf7f4 refactor(share): move icon loading in CSS rather than in JS 2025-10-29 19:11:43 +02:00
Elian Doran
a317331551 fix(share): theme toggle flashing while switching between notes 2025-10-29 19:05:23 +02:00
Elian Doran
eeec3e440d fix(share): flash while theme is loading 2025-10-29 19:00:09 +02:00
Elian Doran
b06aa29ea3 chore(share): remove leftover color management logic 2025-10-29 18:46:55 +02:00
Elian Doran
9c3f9a524e fix(share): flash of dark color on light theme 2025-10-29 18:46:24 +02:00
Elian Doran
1c832182d6 refactor(share): reduce duplication in theme management 2025-10-29 18:40:31 +02:00
Elian Doran
b58e1f146c fix(share): light theme not properly restored 2025-10-29 18:35:27 +02:00
Elian Doran
bc86fb95b5 feat(share): add dev mode 2025-10-29 18:27:43 +02:00
Elian Doran
6c43db692e fix(client): boxicons missing in prod 2025-10-29 18:16:25 +02:00
Elian Doran
6ffce824d1 fix(docker): incorrect version for arm v7 2025-10-29 17:43:10 +02:00
Elian Doran
f1f8f34ef8 fix(export/share): load search index once per page 2025-10-29 15:33:38 +02:00
Elian Doran
a0b19ce526 fix(export/share): search not working on root 2025-10-29 15:26:48 +02:00
Elian Doran
4cc9ba824d chore(export/share): tweak search results 2025-10-29 15:24:25 +02:00
Elian Doran
08e66c18e7 fix(export/share): navigation in search not working 2025-10-29 14:57:53 +02:00
Elian Doran
cf8089b07f feat(export/share): functional full-text search 2025-10-29 13:58:37 +02:00
Elian Doran
f8c61ecde9 feat(export/share): use better content parsing for search 2025-10-29 08:45:47 +02:00
Elian Doran
6d51da9b88 feat(export/share): generate search index 2025-10-29 08:41:07 +02:00
Elian Doran
0ad95d00dc chore(ci): try to fix arm v6/v7 build 2025-10-29 08:08:16 +02:00
Elian Doran
9819a92b48 docs(guide): remove a missing note link 2025-10-28 23:01:56 +02:00
Elian Doran
55a7017e92 docs(guide): document the zoom function 2025-10-28 22:55:52 +02:00
Elian Doran
1581568741 docs(guide): add promoted attribute for alias 2025-10-28 22:31:59 +02:00
Elian Doran
d7982c65dd docs(guide): add alias for most pages 2025-10-28 22:30:46 +02:00
Elian Doran
39608a2815 docs(guide): home page & third party hosting + sync 2025-10-28 22:07:05 +02:00
Elian Doran
f656c2caaa fix(export/zip): links breaking down in markdown export 2025-10-28 21:32:05 +02:00
Elian Doran
bd3e92f091 fix(export/zip): export options not considered 2025-10-28 20:40:53 +02:00
Elian Doran
7ce7c66463 chore(build-docs): address requested changes 2025-10-28 19:31:57 +02:00
Elian Doran
61d26fec60 refactor(build-docs): use proper await when building documentation 2025-10-28 19:30:55 +02:00
Elian Doran
1822eea77c chore: remove remaining references to mkdocs 2025-10-28 19:19:39 +02:00
Elian Doran
28c0e4e802 chore(client): remove no longer relevant input 2025-10-28 19:15:01 +02:00
Elian Doran
5b7e9d4c12 Revision history: two fixes (#7544) 2025-10-28 18:30:50 +02:00
contributor
bee2fdb22f chore: remove dead translation 2025-10-28 18:26:35 +02:00
contributor
5c46a0dfa8 chore: remove dead code
https://github.com/TriliumNext/Trilium/pull/7544#issuecomment-3456187575
2025-10-28 18:26:35 +02:00
Elian Doran
88d90fdedd fix(export/share): favicon working only on top-level 2025-10-28 18:23:11 +02:00
Elian Doran
2a1ecdbdca feat(share): display admonition icons (closes #6733) 2025-10-28 18:18:03 +02:00
Elian Doran
5772046674 chore(share): remove redundant file 2025-10-28 18:17:06 +02:00
Elian Doran
1e2c8b2ac4 fix(export/share): ckcontent CSS missing 2025-10-28 18:16:37 +02:00
Elian Doran
955b202b8a chore(export/share): hide last updated 2025-10-28 17:59:12 +02:00
Elian Doran
be98a27439 feat(export/share): prefer #shareAlias 2025-10-28 17:57:48 +02:00
Elian Doran
54200fa0cb chore(export/share): disable non-functional search 2025-10-28 17:33:36 +02:00
Elian Doran
5d82a26c87 fix(build-docs): missing favicon 2025-10-28 17:23:31 +02:00
Elian Doran
e51070e389 chore(share): handle BAttachments too 2025-10-28 17:16:34 +02:00
Elian Doran
e0dc4fee20 fix(share): reference links not working 2025-10-28 17:14:33 +02:00
contributor
e683dc1d66 add openTodayNote to CommandMappings #7472 2025-10-28 16:59:46 +02:00
contributor
14a3438a20 move shortcut definition to "Note navigation" section #7472 2025-10-28 16:59:41 +02:00
contributor
dd483fccbc use common translation for openTodayNote #7472 2025-10-28 16:59:36 +02:00
contributor
5620e7f4a7 feat: add command openTodayNote with empty keyboard shortcut #7472 2025-10-28 16:59:28 +02:00
Elian Doran
187e9b57de fix(share): note tree not visible on mobile 2025-10-28 16:57:04 +02:00
Elian Doran
d6d67e7957 fix(docs/share): share theme not built 2025-10-28 16:45:27 +02:00
Elian Doran
bde03e8378 feat(docs/share): integrate in the CI 2025-10-28 16:42:52 +02:00
Elian Doran
4c3fcdba4a fix(share): images appearing stretched 2025-10-28 16:34:38 +02:00
Elian Doran
7a5c1277f1 feat(docs/share): set up script to build documentation 2025-10-28 16:24:55 +02:00
Elian Doran
69b262040a Translations update from Hosted Weblate (#7547) 2025-10-28 16:22:15 +02:00
Manfred Manni
8731fa6c31 Translated using Weblate (German)
Currently translated at 59.3% (70 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/de/
2025-10-28 13:50:36 +00:00
Elian Doran
f4e8fc4d83 Export with share theme (#5830) 2025-10-28 15:50:21 +02:00
Elian Doran
dd5b3a3c1c chore(server): address requested changes 2025-10-28 15:44:00 +02:00
Elian Doran
17319d25e8 chore(server): fix a few type issues 2025-10-28 14:51:03 +02:00
Elian Doran
2f189b6961 chore(share): remove now redundant project 2025-10-28 14:47:51 +02:00
Elian Doran
b1f8d44576 Merge remote-tracking branch 'origin/main' into feature/export_with_share_theme 2025-10-28 14:29:37 +02:00
Elian Doran
7f22532a0a fix: import markdown to text note (#7538) 2025-10-28 14:15:29 +02:00
Elian Doran
c7beb87980 Update dependency node to v24 (#7537) 2025-10-28 14:14:00 +02:00
Elian Doran
5cd1fd53d4 Translations update from Hosted Weblate (#7546) 2025-10-28 14:11:20 +02:00
Elian Doran
2eadbe3f01 Translated using Weblate (German)
Currently translated at 44.9% (53 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/de/
2025-10-28 13:10:51 +01:00
Hosted Weblate
4e7493f648 Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/
2025-10-28 13:06:25 +01:00
Elian Doran
b9d54a44f6 Translations update from Hosted Weblate (#7545) 2025-10-28 14:06:08 +02:00
Elian Doran
a1ad8be02b Apply suggestion from @gemini-code-assist[bot]
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-10-28 14:05:06 +02:00
Elian Doran
b02514f395 Apply suggestion from @gemini-code-assist[bot]
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-10-28 14:04:47 +02:00
Elian Doran
dcef3f2be5 Apply suggestion from @gemini-code-assist[bot]
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-10-28 14:04:39 +02:00
Rugved Inamdar
585fdabd27 Translated using Weblate (Hindi)
Currently translated at 0.6% (1 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/hi/
2025-10-28 12:02:42 +00:00
Rugved Inamdar
71fcb77a22 Translated using Weblate (Hindi)
Currently translated at 0.8% (1 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/hi/
2025-10-28 12:02:41 +00:00
Rugved Inamdar
33ecf6aa6d Translated using Weblate (Hindi)
Currently translated at 0.1% (1 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/hi/
2025-10-28 12:02:40 +00:00
Rugved Inamdar
1f75de83c6 Added translation using Weblate (Marathi) 2025-10-28 12:02:39 +00:00
Rugved Inamdar
31b52f72d2 Added translation using Weblate (Marathi) 2025-10-28 12:02:39 +00:00
Rugved Inamdar
01aaf81196 Added translation using Weblate (Marathi) 2025-10-28 12:02:38 +00:00
Rugved Inamdar
3ecfdd62e8 Added translation using Weblate (Marathi) 2025-10-28 12:02:38 +00:00
Rugved Inamdar
3c74d0714a Added translation using Weblate (Hindi) 2025-10-28 12:02:37 +00:00
Rugved Inamdar
f58d9adff2 Added translation using Weblate (Hindi) 2025-10-28 12:02:36 +00:00
Rugved Inamdar
0eecf5b132 Added translation using Weblate (Hindi) 2025-10-28 12:02:36 +00:00
Rugved Inamdar
9e3cca333a Added translation using Weblate (Hindi) 2025-10-28 12:02:35 +00:00
Manfred Manni
81c233463e Translated using Weblate (German)
Currently translated at 44.9% (53 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/de/
2025-10-28 12:02:34 +00:00
DerVogel101
87946e7e85 Translated using Weblate (German)
Currently translated at 100.0% (1621 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2025-10-28 12:02:33 +00:00
Elian Doran
c3768a051d Fix some CSS issues (#7543) 2025-10-28 14:02:24 +02:00
contributor
c579cd3ce7 fix: no note on edited notes view if a revision made between note created/modified date 2025-10-28 12:55:34 +02:00
contributor
945e2625d3 fix: wrong dates in “Note Revisions” view 2025-10-28 12:55:13 +02:00
Elian Doran
ff36414a55 chore(deps): update dependency @types/serve-static to v2 (#7535) 2025-10-28 08:24:02 +02:00
renovate[bot]
8f184c5b10 chore(deps): update dependency node to v24 2025-10-28 06:23:07 +00:00
Elian Doran
c027a2bbfa chore(deps): update dependency @types/archiver to v7 (#7534) 2025-10-28 08:22:36 +02:00
Elian Doran
91adc2258d fix(deps): update dependency react-i18next to v16.2.1 (#7532) 2025-10-28 08:22:12 +02:00
Elian Doran
6701e83927 chore(deps): update dependency axios to v1.13.0 (#7533) 2025-10-28 08:21:44 +02:00
Elian Doran
3f54e589d8 fix(deps): update dependency mermaid to v11.12.1 (#7531) 2025-10-28 08:21:09 +02:00
Elian Doran
f65be73f71 chore(deps): update dependency @types/express to v5.0.5 (#7530) 2025-10-28 08:20:33 +02:00
Elian Doran
346e9282bd Translations update from Hosted Weblate (#7528) 2025-10-28 08:19:57 +02:00
SiriusXT
8f8ea7adc3 fix(types): correct CommandMappings key for pasteMarkdownIntoText 2025-10-28 14:10:11 +08:00
SiriusXT
4affd3a955 fix: note map button overlapping menu 2025-10-28 11:28:36 +08:00
SiriusXT
bcce05cc4d fix(zen): Show fixed toolbar in Zen mode 2025-10-28 11:20:36 +08:00
SiriusXT
ac16c42e23 Merge branch 'main' into patch_import_markdown 2025-10-28 11:03:41 +08:00
SiriusXT
5025329e92 fix: restore editor focus after inserting markdown 2025-10-28 11:00:53 +08:00
SiriusXT
507910b0ce fix: import markdown to text note 2025-10-28 10:17:37 +08:00
renovate[bot]
b59fab9dba chore(deps): update dependency @types/serve-static to v2 2025-10-28 01:53:53 +00:00
renovate[bot]
ac7e4580f6 chore(deps): update dependency @types/archiver to v7 2025-10-28 01:53:07 +00:00
renovate[bot]
27d1044ba8 chore(deps): update dependency axios to v1.13.0 2025-10-28 01:52:22 +00:00
renovate[bot]
96c949b2fc fix(deps): update dependency react-i18next to v16.2.1 2025-10-28 01:51:32 +00:00
renovate[bot]
927cd0255e fix(deps): update dependency mermaid to v11.12.1 2025-10-28 01:50:45 +00:00
renovate[bot]
c2c8417c42 chore(deps): update dependency @types/express to v5.0.5 2025-10-28 01:49:55 +00:00
migraine-user
3bb224e682 Translated using Weblate (Korean)
Currently translated at 1.3% (2 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/ko/
2025-10-27 20:43:03 +00:00
Elian Doran
6f126ea17b Fix typo in German translation for 'copy-link' (#7527) 2025-10-27 22:42:52 +02:00
DerVogel101
61a5cf1452 Fix typo in German translation for 'copy-link'
Fixed a missing character in the German translation of the context menu action copy-link.
2025-10-27 21:25:08 +01:00
Elian Doran
14b8d0a47e chore(share): bring back syntax highlight 2025-10-27 22:18:08 +02:00
Elian Doran
12df6a0d6e chore(uikit): create empty project 2025-10-27 20:53:13 +02:00
Elian Doran
21d243eec1 fix(desktop): share not working 2025-10-27 20:29:56 +02:00
Elian Doran
161238ca11 fix(windows script): add -command flag (#7513) 2025-10-27 18:47:03 +02:00
Elian Doran
4d5267e18b fix (empty tab): recent notes not showing when creating a empty tab (#7523) 2025-10-27 18:43:31 +02:00
Elian Doran
0fa52907b3 Website static fixes (#7525) 2025-10-27 18:39:20 +02:00
Elian Doran
c4f57f3d15 refactor(website): simplify loop 2025-10-27 18:34:26 +02:00
Elian Doran
6bde264156 fix(website): lang/dir not updating after switching language 2025-10-27 18:31:03 +02:00
Elian Doran
4f72f81a95 chore(website): fix typecheck issues 2025-10-27 18:19:35 +02:00
Elian Doran
c212c5d6ff Merge remote-tracking branch 'origin/main' into fix/website_static 2025-10-27 18:11:39 +02:00
Elian Doran
f24880d42c fix(website): incorrect default language 2025-10-27 18:10:21 +02:00
Elian Doran
ee9bf1d47b fix(website): incorrect lang tag 2025-10-27 18:04:49 +02:00
Elian Doran
b069fab82f chore(website): use static loading of translations 2025-10-27 17:17:37 +02:00
Elian Doran
d5ce01a65b Revert "fix(website): missing suspense"
This reverts commit dbfa94a9ee.
2025-10-27 16:45:52 +02:00
Elian Doran
dbfa94a9ee fix(website): missing suspense 2025-10-27 16:35:26 +02:00
Elian Doran
86aaa97809 fix(website): language-specific pages not properly determined 2025-10-27 16:30:03 +02:00
Elian Doran
c4c8fe23a9 fix(website): pages not prerendered 2025-10-27 16:29:44 +02:00
Elian Doran
715fe77db3 Translations update from Hosted Weblate (#7519) 2025-10-27 16:20:42 +02:00
Francis C
40f5abd6e3 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (152 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/zh_Hant/
2025-10-27 14:18:09 +00:00
Giovi
f3f7e5900b Translated using Weblate (Italian)
Currently translated at 100.0% (152 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/it/
2025-10-27 14:18:08 +00:00
green
f4402a6d81 Translated using Weblate (Japanese)
Currently translated at 100.0% (152 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/ja/
2025-10-27 14:18:08 +00:00
green
6966efd374 Translated using Weblate (Japanese)
Currently translated at 98.0% (149 of 152 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/ja/
2025-10-27 14:18:07 +00:00
Hosted Weblate
cd3e025fdc Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/
2025-10-27 14:18:06 +00:00
marc hooijschuur
a224b774d3 Translated using Weblate (Dutch)
Currently translated at 2.9% (48 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/nl/
2025-10-27 14:18:05 +00:00
Elian Doran
f20078f3b0 fix(print): some images not loading 2025-10-27 16:17:51 +02:00
SiriusXT
56019e5449 fix (empty tab): recent notes not showing when creating a empty tab 2025-10-27 16:59:28 +08:00
SiriusXT
7dd517d8f7 fix (empty tab): recent notes not showing when creating a empty tab 2025-10-27 14:42:22 +08:00
Elian Doran
b2f1b3c910 chore(deps): update dependency @types/turndown to v5.0.6 (#7521) 2025-10-27 08:13:12 +02:00
renovate[bot]
2197fae700 chore(deps): update dependency @types/turndown to v5.0.6 2025-10-27 01:55:23 +00:00
Elian Doran
3661733f07 chore(server): remove duplicate math handling 2025-10-26 22:00:11 +02:00
Elian Doran
52a6f2597e fix(share): template directory in production 2025-10-26 21:38:16 +02:00
Elian Doran
d8e9cad23d feat(website): describe presentation collection 2025-10-26 19:24:43 +02:00
Elian Doran
6ed333d222 style(website): redesign list with screenshot 2025-10-26 19:11:11 +02:00
Elian Doran
ba26c478d6 fix(export/share): assets incorrectly rewritten 2025-10-26 12:15:35 +02:00
Elian Doran
055fcb7b2a fix(export/share): handling of fonts 2025-10-26 11:34:09 +02:00
Elian Doran
f4468706ef fix(export/share): asset path for styles and scripts 2025-10-26 11:07:08 +02:00
Elian Doran
212956201a chore(export/share): export full share script & styles 2025-10-26 11:02:19 +02:00
Elian Doran
1182592fc5 chore(share): fix another typecheck issue 2025-10-26 10:07:42 +02:00
Elian Doran
d534db29c9 feat(note_icon): add an empty option (closes #7370) 2025-10-26 10:03:51 +02:00
Elian Doran
40edd42740 Translations update from Hosted Weblate (#7516) 2025-10-25 23:57:24 +03:00
Newcomer1989
d2c7011735 Translated using Weblate (German)
Currently translated at 20.5% (30 of 146 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/de/
2025-10-25 20:54:49 +00:00
Manfred Manni
a050d1741b Translated using Weblate (German)
Currently translated at 22.8% (27 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/de/
2025-10-25 20:54:48 +00:00
greenfork
18982865da Translated using Weblate (Russian)
Currently translated at 99.1% (1607 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ru/
2025-10-25 20:54:48 +00:00
Newcomer1989
3aa810fed7 Translated using Weblate (German)
Currently translated at 100.0% (1621 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2025-10-25 20:54:47 +00:00
Elian Doran
c5ecc22c67 chore(website): update macOS requirement 2025-10-25 23:54:37 +03:00
Elian Doran
252f8ccb1f Internationalization improvements for the website (#7515) 2025-10-25 23:46:43 +03:00
Elian Doran
e1bb704383 fix(website/i18n): language list fit on mobile 2025-10-25 23:33:54 +03:00
Elian Doran
dce0d9400b chore(website/i18n): bring back root-level pages 2025-10-25 23:11:02 +03:00
Elian Doran
615c783fe3 chore(website/i18n): add t to list of deps 2025-10-25 22:52:38 +03:00
Elian Doran
f29411baf7 fix(website/i18n): header link not indicating active 2025-10-25 22:49:22 +03:00
Elian Doran
be5e70130c feat(website/i18n): highlight current language 2025-10-25 22:39:04 +03:00
Elian Doran
9ba1e9d732 feat(website/i18n): swap locale when footer 2025-10-25 22:36:27 +03:00
Elian Doran
e1dc4d1433 chore(website/i18n): another missing translation 2025-10-25 22:18:07 +03:00
Elian Doran
d0d268496c Update apps/website/src/components/Header.tsx
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-10-25 22:16:50 +03:00
Elian Doran
8a6950c945 Merge branch 'main' into feature/website_i18n 2025-10-25 22:03:18 +03:00
Elian Doran
477592d176 fix(website/i18n): language detection not always working 2025-10-25 21:55:53 +03:00
Elian Doran
7e5c2ed79d chore(website): set up testing 2025-10-25 21:54:30 +03:00
Elian Doran
bc580f2a88 feat(website/i18n): language auto-detection 2025-10-25 21:39:02 +03:00
Elian Doran
71cd92e0b5 fix(website/i18n): header sometimes not correctly translated 2025-10-25 21:13:48 +03:00
Elian Doran
a4d92e12be chore(website/i18n): add more CJK fonts 2025-10-25 21:05:54 +03:00
Elian Doran
c40279b480 chore(website): missing a translation 2025-10-25 20:40:05 +03:00
Elian Doran
4c7e7c157c chore(website): solve a warning about sectioned h1 size 2025-10-25 20:31:08 +03:00
Elian Doran
c08386450a chore(website/i18n): different load mechanism for translations 2025-10-25 20:27:42 +03:00
Elian Doran
eb93762ecc chore(website/i18n): missing translations in header 2025-10-25 20:27:23 +03:00
Elian Doran
2697f9a25d fix(website/i18n): get started in download button not working 2025-10-25 20:00:09 +03:00
Elian Doran
9515e2099b feat(website/i18n): set right dir and lang tags 2025-10-25 19:58:31 +03:00
Elian Doran
966c08da87 fix(website/i18n): home page link not working 2025-10-25 19:53:36 +03:00
Elian Doran
ea04446e81 chore(website/i18n): handle Chinese 2025-10-25 19:17:26 +03:00
Elian Doran
e4f806ed14 feat(website/i18n): get translation to actually render 2025-10-25 19:13:28 +03:00
Elian Doran
49cf7ae1a3 feat(website/i18n): render pages by locale 2025-10-25 18:54:24 +03:00
Elian Doran
1a6f5a027f chore(website/i18n): add English too 2025-10-25 18:21:52 +03:00
Elian Doran
f4796f0f9e feat(website/i18n): footer navigation 2025-10-25 18:18:47 +03:00
Elian Doran
30480b2c23 chore(website/i18n): start generating routes 2025-10-25 17:25:58 +03:00
Elian Doran
b7b1d17817 chore(website): add list of locales 2025-10-25 16:41:10 +03:00
Elian Doran
c4e5494c14 chore(deps): update dependency @types/express to v5.0.4 (#7487) 2025-10-25 16:37:47 +03:00
Elian Doran
b0f63c02c9 chore(deps): update dependency vite to v7.1.12 (#7495) 2025-10-25 16:37:20 +03:00
Elian Doran
2480509811 chore(deps): update dependency electron to v38.4.0 (#7500) 2025-10-25 16:28:45 +03:00
Elian Doran
7872193ed0 chore(deps): update dependency node-abi to v4.15.0 (#7501) 2025-10-25 16:28:37 +03:00
Ryan Keane
1a68bdfe02 fix(windows script): add -command flag
I don't know why if I replace old, system builtin powershell executable
with powershell 7, scripts fail with this error:

The argument 'Set-Item -Path ...' is not recognized as the name of a
script file. Check the spelling of the name, or if a path was included,
verify that the path is correct and try again.

Adding -Command at the end of flags just fixed it.

Signed-off-by: Ryan Keane <the.ra2.ifv@gmail.com>
2025-10-25 01:07:28 -07:00
Elian Doran
14e06c4555 chore(dev): add entry point for starting web site in dev mode 2025-10-25 09:34:53 +03:00
Elian Doran
b8e17959ae Translations update from Hosted Weblate (#7512) 2025-10-25 09:19:43 +03:00
Sarah Hussein
c16a135efc Translated using Weblate (Arabic)
Currently translated at 55.4% (81 of 146 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/ar/
2025-10-25 06:18:55 +00:00
Sarah Hussein
cbc756ba06 Translated using Weblate (Arabic)
Currently translated at 85.7% (332 of 387 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/ar/
2025-10-25 06:18:54 +00:00
Sarah Hussein
64daeb0826 Translated using Weblate (Arabic)
Currently translated at 65.0% (1055 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ar/
2025-10-25 06:18:53 +00:00
Hosted Weblate
e15839db47 Update translation files
Updated by "Cleanup translation files" add-on in Weblate.

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/
2025-10-25 06:18:53 +00:00
Elian Doran
dcdffed003 chore(deps): remove unused types for session-file-store 2025-10-25 09:18:41 +03:00
renovate[bot]
48e85fad43 chore(deps): update dependency node-abi to v4.15.0 2025-10-25 06:17:51 +00:00
renovate[bot]
189071deb8 chore(deps): update dependency electron to v38.4.0 2025-10-25 06:17:20 +00:00
Elian Doran
354f1d65c1 chore(deps): update dependency eslint-plugin-react-hooks to v7.0.1 (#7491) 2025-10-25 09:14:40 +03:00
renovate[bot]
b78893b106 chore(deps): update dependency vite to v7.1.12 2025-10-25 06:14:32 +00:00
Elian Doran
9310315c6a chore(deps): update dependency @types/tabulator-tables to v6.3.0 (#7499) 2025-10-25 09:13:38 +03:00
renovate[bot]
1794f8546d chore(deps): update dependency @types/express to v5.0.4 2025-10-25 06:12:41 +00:00
Elian Doran
b3bc0572e5 chore(deps): update ckeditor5 config packages to v12.2.0 (#7498) 2025-10-25 09:12:04 +03:00
Elian Doran
253ce1f223 fix(deps): update dependency preact-render-to-string to v6.6.3 (#7497) 2025-10-25 09:11:45 +03:00
Elian Doran
2f3bf94b47 fix(deps): update dependency mind-elixir to v5.3.4 (#7496) 2025-10-25 09:11:26 +03:00
Elian Doran
d802caa03b chore(deps): update dependency turndown to v7.2.2 (#7494) 2025-10-25 09:10:35 +03:00
renovate[bot]
e69751a8b3 fix(deps): update dependency preact-render-to-string to v6.6.3 2025-10-25 06:10:07 +00:00
Elian Doran
0760ea22fb chore(deps): update dependency lint-staged to v16.2.6 (#7493) 2025-10-25 09:09:27 +03:00
Elian Doran
8a8f407e99 chore(deps): update dependency happy-dom to v20.0.8 (#7492) 2025-10-25 09:09:09 +03:00
renovate[bot]
e030dd96da chore(deps): update dependency eslint-plugin-react-hooks to v7.0.1 2025-10-25 06:08:45 +00:00
Elian Doran
01abfc2528 chore(deps): update dependency @types/yargs to v17.0.34 (#7490) 2025-10-25 09:08:36 +03:00
Elian Doran
042b929dc5 chore(deps): update dependency @types/serve-static to v1.15.10 (#7488) 2025-10-25 09:08:03 +03:00
Elian Doran
ab1d5e31fb chore(deps): update dependency @types/cookie-parser to v1.4.10 (#7486) 2025-10-25 09:07:41 +03:00
Elian Doran
d073e4c37f chore(deps): update dependency @types/archiver to v6.0.4 (#7485) 2025-10-25 09:07:29 +03:00
Elian Doran
d60d965a42 chore(deps): update dependency @smithy/middleware-retry to v4.4.5 (#7484) 2025-10-25 09:07:13 +03:00
Elian Doran
1c87cfbbd9 chore(deps): update dependency ini to v6 (#7507) 2025-10-25 09:06:21 +03:00
Elian Doran
fee333512a chore(deps): update dependency openai to v6.7.0 (#7502) 2025-10-25 09:05:53 +03:00
Elian Doran
38a3f46506 chore(deps): update node.js to v22.21.0 (#7503) 2025-10-25 09:05:35 +03:00
Elian Doran
bf7506fcd8 chore(deps): update pnpm to v10.19.0 (#7504) 2025-10-25 09:05:05 +03:00
Elian Doran
6fbba426de fix(deps): update codemirror (#7505) 2025-10-25 09:04:29 +03:00
Elian Doran
d5bdec13b5 fix(deps): update dependency react-i18next to v16.2.0 (#7506) 2025-10-25 09:04:02 +03:00
Elian Doran
cc1b6eb42d chore(deps): update github artifact actions (major) (#7508) 2025-10-25 09:03:36 +03:00
renovate[bot]
8baf496f96 chore(deps): update github artifact actions 2025-10-25 01:23:17 +00:00
renovate[bot]
23a20c4490 chore(deps): update dependency ini to v6 2025-10-25 01:23:11 +00:00
renovate[bot]
c8b98f2db6 fix(deps): update dependency react-i18next to v16.2.0 2025-10-25 01:22:39 +00:00
renovate[bot]
3f36f515db fix(deps): update codemirror 2025-10-25 01:22:07 +00:00
renovate[bot]
892eb5b95d chore(deps): update pnpm to v10.19.0 2025-10-25 01:21:37 +00:00
renovate[bot]
62a69a0da0 chore(deps): update node.js to v22.21.0 2025-10-25 01:21:29 +00:00
renovate[bot]
3588e38543 chore(deps): update dependency openai to v6.7.0 2025-10-25 01:21:24 +00:00
renovate[bot]
41450ab85a chore(deps): update dependency @types/tabulator-tables to v6.3.0 2025-10-25 01:19:49 +00:00
renovate[bot]
0526d99560 chore(deps): update ckeditor5 config packages to v12.2.0 2025-10-25 01:19:14 +00:00
renovate[bot]
557d576b85 fix(deps): update dependency mind-elixir to v5.3.4 2025-10-25 01:18:06 +00:00
renovate[bot]
041c961cfa chore(deps): update dependency turndown to v7.2.2 2025-10-25 01:16:54 +00:00
renovate[bot]
dcc35bd507 chore(deps): update dependency lint-staged to v16.2.6 2025-10-25 01:16:19 +00:00
renovate[bot]
09c3e5b56e chore(deps): update dependency happy-dom to v20.0.8 2025-10-25 01:15:41 +00:00
renovate[bot]
950793377d chore(deps): update dependency @types/yargs to v17.0.34 2025-10-25 01:13:27 +00:00
renovate[bot]
7dac61dc26 chore(deps): update dependency @types/serve-static to v1.15.10 2025-10-25 01:11:50 +00:00
renovate[bot]
42dcb8f141 chore(deps): update dependency @types/cookie-parser to v1.4.10 2025-10-25 01:10:08 +00:00
renovate[bot]
43dc8a4b87 chore(deps): update dependency @types/archiver to v6.0.4 2025-10-25 01:09:20 +00:00
renovate[bot]
35316a4c45 chore(deps): update dependency @smithy/middleware-retry to v4.4.5 2025-10-25 01:08:32 +00:00
Elian Doran
1366489f99 Translations update from Hosted Weblate (#7479) 2025-10-24 23:31:57 +03:00
Elian Doran
0c399a676a chore(share): fix typecheck issue 2025-10-24 23:28:42 +03:00
brtkcs
31ee78b1aa Translated using Weblate (Hungarian)
Currently translated at 21.2% (31 of 146 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/hu/
2025-10-24 20:14:05 +00:00
brtkcs
808ba75ee0 Translated using Weblate (Hungarian)
Currently translated at 27.1% (32 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/hu/
2025-10-24 20:14:04 +00:00
brtkcs
ac1399a139 Translated using Weblate (Hungarian)
Currently translated at 8.2% (32 of 387 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/hu/
2025-10-24 20:14:04 +00:00
brtkcs
1e4793351a Translated using Weblate (Hungarian)
Currently translated at 1.9% (32 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/hu/
2025-10-24 20:14:03 +00:00
Sarah Hussein
f502fe41c7 Translated using Weblate (Arabic)
Currently translated at 52.7% (77 of 146 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/ar/
2025-10-24 20:14:02 +00:00
brtkcs
0ec0091357 Translated using Weblate (Hungarian)
Currently translated at 19.1% (28 of 146 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/hu/
2025-10-24 20:14:02 +00:00
brtkcs
0e2196f872 Translated using Weblate (Hungarian)
Currently translated at 24.5% (29 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/hu/
2025-10-24 20:14:01 +00:00
Sarah Hussein
32dee254cd Translated using Weblate (Arabic)
Currently translated at 82.4% (319 of 387 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/ar/
2025-10-24 20:14:01 +00:00
Sarah Hussein
d4a6a297f4 Translated using Weblate (Arabic)
Currently translated at 64.3% (1043 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ar/
2025-10-24 20:14:00 +00:00
brtkcs
a64d8cd8e2 Translated using Weblate (Hungarian)
Currently translated at 7.4% (29 of 387 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/hu/
2025-10-24 20:14:00 +00:00
brtkcs
bf4cfb9c02 Translated using Weblate (Hungarian)
Currently translated at 1.7% (29 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/hu/
2025-10-24 20:13:59 +00:00
Manfred Manni
a99dfecf43 Translated using Weblate (German)
Currently translated at 100.0% (387 of 387 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/de/
2025-10-24 20:13:59 +00:00
Manfred Manni
1530d96eca Translated using Weblate (German)
Currently translated at 99.8% (1619 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/de/
2025-10-24 20:13:58 +00:00
Elian Doran
5dc066f4c6 chore(dev): add work-around to run on Ubuntu
See https://github.com/electron/electron/issues/42510.
2025-10-24 23:03:20 +03:00
Elian Doran
395f33cd5b chore(share): bring back boxicons 2025-10-24 22:32:42 +03:00
Elian Doran
21b20cf575 chore(share): bring back most of the logic 2025-10-24 21:18:06 +03:00
Elian Doran
e3dd25b591 chore(share): set up math 2025-10-24 21:13:40 +03:00
Elian Doran
b9a4e7ab11 chore(share): enable code splitting 2025-10-24 20:52:54 +03:00
Elian Doran
6ae67c410c chore(share): load Mermaid only when necessary 2025-10-24 20:52:47 +03:00
Elian Doran
4ef7667484 chore(share): bring back inline mermaid rendering 2025-10-24 19:09:19 +03:00
Elian Doran
3660e2f127 refactor(share): store assets at /share/asset level 2025-10-24 19:00:26 +03:00
Elian Doran
357d294f2d chore(export/share): address review 2025-10-24 18:25:16 +03:00
Elian Doran
bb636128b0 fix(export/share): missing files and wrong meta handling 2025-10-24 16:02:20 +03:00
Elian Doran
aa102ab393 fix(export/share): missing templates after merge 2025-10-24 14:54:20 +03:00
Elian Doran
ea53665e64 Merge remote-tracking branch 'origin/main' into feature/export_with_share_theme 2025-10-24 14:43:20 +03:00
Elian Doran
1e8f179f81 Translations update from Hosted Weblate (#7469) 2025-10-23 20:37:39 +03:00
Elian Doran
54c906de8d Apply suggestion from @gemini-code-assist[bot]
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-10-23 20:35:34 +03:00
Elian Doran
114b3ef4d1 Apply suggestion from @gemini-code-assist[bot]
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-10-23 20:33:43 +03:00
Elian Doran
f6fa1e69b3 Apply suggestion from @gemini-code-assist[bot]
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-10-23 20:33:03 +03:00
Elian Doran
fcc8086f9c Apply suggestion from @gemini-code-assist[bot]
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-10-23 20:32:21 +03:00
Bond
7eefff0a74 Translated using Weblate (Vietnamese)
Currently translated at 10.9% (16 of 146 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/vi/
2025-10-23 19:28:31 +02:00
Микола Копитін
1b842e35ff Translated using Weblate (Ukrainian)
Currently translated at 26.0% (38 of 146 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/uk/
2025-10-23 19:28:30 +02:00
Bond
c9021ca742 Translated using Weblate (Vietnamese)
Currently translated at 55.9% (66 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/vi/
2025-10-23 19:28:29 +02:00
Микола Копитін
b229ab3c02 Translated using Weblate (Ukrainian)
Currently translated at 32.2% (38 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/uk/
2025-10-23 19:28:29 +02:00
Bond
6825f28ba0 Translated using Weblate (Vietnamese)
Currently translated at 3.0% (50 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/vi/
2025-10-23 19:28:28 +02:00
Микола Копитін
5e72f271ea Translated using Weblate (Ukrainian)
Currently translated at 21.9% (32 of 146 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/uk/
2025-10-23 19:28:27 +02:00
Микола Копитін
9ad6dfd5e9 Translated using Weblate (Ukrainian)
Currently translated at 27.9% (33 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/uk/
2025-10-23 19:28:27 +02:00
Marc
81031673c3 Translated using Weblate (French)
Currently translated at 100.0% (146 of 146 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/fr/
2025-10-23 19:28:26 +02:00
Микола Копитін
1a6423fd36 Translated using Weblate (Ukrainian)
Currently translated at 20.5% (30 of 146 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/uk/
2025-10-23 19:28:26 +02:00
onlyfranz
9b872617e6 Translated using Weblate (German)
Currently translated at 2.7% (4 of 146 strings)

Translation: Trilium Notes/Website
Translate-URL: https://hosted.weblate.org/projects/trilium/website/de/
2025-10-23 19:28:25 +02:00
Sarah Hussein
57be2e2474 Translated using Weblate (Arabic)
Currently translated at 25.4% (30 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/ar/
2025-10-23 19:28:25 +02:00
Микола Копитін
1d65afef53 Translated using Weblate (Ukrainian)
Currently translated at 26.2% (31 of 118 strings)

Translation: Trilium Notes/README
Translate-URL: https://hosted.weblate.org/projects/trilium/readme/uk/
2025-10-23 19:28:24 +02:00
Sarah Hussein
b6385618d1 Translated using Weblate (Arabic)
Currently translated at 63.5% (1030 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ar/
2025-10-23 19:28:23 +02:00
Giovi
e3d7c7419f Translated using Weblate (Italian)
Currently translated at 100.0% (387 of 387 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/it/
2025-10-23 19:28:22 +02:00
Giovi
2a6c295967 Translated using Weblate (Italian)
Currently translated at 100.0% (1621 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/it/
2025-10-23 19:28:22 +02:00
green
f5f32df847 Translated using Weblate (Japanese)
Currently translated at 100.0% (1621 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/ja/
2025-10-23 19:28:21 +02:00
Francis C
1f350b2730 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (1621 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/zh_Hant/
2025-10-23 19:28:20 +02:00
Marc
386992255e Translated using Weblate (French)
Currently translated at 100.0% (387 of 387 strings)

Translation: Trilium Notes/Server
Translate-URL: https://hosted.weblate.org/projects/trilium/server/fr/
2025-10-23 19:28:20 +02:00
Bilal Janati
eb505c4615 Translated using Weblate (French)
Currently translated at 100.0% (1621 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/fr/
2025-10-23 19:28:19 +02:00
Marc
003d2b5354 Translated using Weblate (French)
Currently translated at 100.0% (1621 of 1621 strings)

Translation: Trilium Notes/Client
Translate-URL: https://hosted.weblate.org/projects/trilium/client/fr/
2025-10-23 19:28:19 +02:00
Elian Doran
b452f78242 feat(mobile/search): search definitions always shown 2025-10-23 20:24:16 +03:00
Elian Doran
7d1abee8e4 feat(mobile/search): show results (closes #5655) 2025-10-23 20:16:17 +03:00
Elian Doran
d503993a74 chore(mobile/search): further improve the layout 2025-10-23 20:03:44 +03:00
Elian Doran
fe98ba8c8c chore(mobile/search): improve actions fit 2025-10-23 19:15:38 +03:00
Elian Doran
18608ecb34 feat(mobile): render search definition 2025-10-23 19:07:40 +03:00
Elian Doran
ab6da26a25 refactor(client): standalone rendering mechanism for ribbon 2025-10-23 18:09:32 +03:00
Elian Doran
f95082ccdb fix(server): calendar tooltip positioning (closes #5675) 2025-10-23 16:57:48 +03:00
Elian Doran
e94b5ac07a fix(server): edited notes listing automatically generated hidden notes (closes #5683) 2025-10-23 16:42:27 +03:00
Elian Doran
5d0669b464 fix(canvas): images appearing muted in dark mode (closes #5708) 2025-10-23 16:11:05 +03:00
Elian Doran
af95d85b73 chore(client): disable import/export for help notes 2025-10-23 14:43:04 +03:00
Elian Doran
aae90ede19 chore(share): keep diacritics in slug instead of stripping them in 2025-10-23 14:29:47 +03:00
Elian Doran
0fa1c0f5c4 chore(share): improve slugification to strip diacritics cleanly 2025-10-23 14:26:15 +03:00
Elian Doran
d2b6014b49 fix(share): HTML tags displayed escaped in headings 2025-10-23 14:19:54 +03:00
Elian Doran
94d62f810a fix(share): heading and navigation not supporting CJK (closes #6430) 2025-10-23 14:06:13 +03:00
Elian Doran
e953f0cc1a Merge branch 'main' of https://github.com/TriliumNext/Trilium 2025-10-23 13:22:26 +03:00
Elian Doran
347da8abde fix(collections/list): excessive spacing in empty note content (closes #7319) 2025-10-23 08:16:26 +03:00
Elian Doran
9cf7fa1997 fix(export/share): use right extension for clones 2025-06-24 22:14:15 +03:00
Elian Doran
fded714f18 fix(export/share): use right extension for images 2025-06-24 19:53:21 +03:00
Elian Doran
06de06b501 refactor(export/share): share type for format 2025-06-24 19:21:09 +03:00
Elian Doran
9abdbbbc5b refactor(export/share): fix type 2025-06-24 19:06:18 +03:00
Elian Doran
3ebfee8bd2 fix(export/share): tree error in prod 2025-06-24 18:49:19 +03:00
Elian Doran
6d446c5b27 fix(export/share): asset path in prod 2025-06-24 18:49:11 +03:00
Elian Doran
3a55490bbf refactor(share): use a string cache for templates 2025-06-24 18:08:29 +03:00
Elian Doran
bc4643fed2 refactor(share): use internal rendering method for subtemplates 2025-06-24 17:48:52 +03:00
Elian Doran
a2110ca631 fix(export/share): tree not expanding properly 2025-06-24 17:45:06 +03:00
Elian Doran
413137ac64 chore(nx): sync tsconfig 2025-06-23 21:23:44 +03:00
Elian Doran
9bc966491d fix(edit-docs): import error 2025-06-23 21:22:45 +03:00
Elian Doran
61dbc15fc6 feat(export/share): use translation 2025-06-23 20:14:13 +03:00
Elian Doran
b475037127 feat(export/share): render non-text note types 2025-06-23 20:00:40 +03:00
Elian Doran
35622a2122 feat(export/share): always render empty files 2025-06-23 19:38:47 +03:00
Elian Doran
77e4c3d0ec refactor(export/share): use different URL rewriting mechanism 2025-06-23 19:28:45 +03:00
Elian Doran
8523050ab2 fix(export/share): note children preview links not working 2025-06-23 19:00:20 +03:00
Elian Doran
0efdf65202 refactor(export/share): build index file 2025-06-23 18:46:21 +03:00
Elian Doran
acb0991d05 refactor(export/zip): separate building provider into own method 2025-06-23 18:24:59 +03:00
Elian Doran
a9f68f5487 feat(export/zip): add option to export with share theme 2025-06-23 18:13:47 +03:00
Elian Doran
55bb2fdb9b refactor(export/zip): extract prepare content into providers 2025-06-23 16:22:42 +03:00
Elian Doran
e529633b8b chore(export/zip): bring back markdown exporter 2025-06-23 16:17:29 +03:00
Elian Doran
dfd575b6eb refactor(export/zip): extract into separate provider 2025-06-23 16:08:31 +03:00
Elian Doran
c5196721d4 chore(nx): sync tsconfig 2025-06-23 15:36:10 +03:00
Elian Doran
968c75b618 Merge remote-tracking branch 'origin/main' into feature/export_with_share_theme 2025-06-23 15:35:30 +03:00
Elian Doran
01beebf660 feat(export/zip): load script as well 2025-06-14 01:23:02 +03:00
Elian Doran
d3115e834a feat(export/zip): get logo to work 2025-06-14 01:01:12 +03:00
Elian Doran
01a552ceb5 feat(export/zip): get boxicons to work 2025-06-14 00:52:56 +03:00
Elian Doran
d8958adea5 feat(export/zip): basic tree navigation 2025-06-14 00:07:55 +03:00
Elian Doran
4d5e866db6 feat(export/zip): get CSS to load 2025-06-13 23:47:04 +03:00
Elian Doran
f189deb415 feat(export/zip): get tree to render 2025-06-13 23:22:44 +03:00
Elian Doran
9c460dbc87 feat(export/zip): get same rendering engine as share 2025-06-13 23:10:14 +03:00
Elian Doran
2c6ba9ba2c refactor(share): extract note rendering logic 2025-06-13 17:48:19 +03:00
578 changed files with 13401 additions and 6334 deletions

View File

@@ -12,7 +12,7 @@ runs:
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:
node-version: 22
node-version: 24
cache: "pnpm"
- name: Install dependencies
shell: bash

View File

@@ -1,6 +1,4 @@
# GitHub Actions workflow for deploying MkDocs documentation to Cloudflare Pages
# This workflow builds and deploys your MkDocs site when changes are pushed to main
name: Deploy MkDocs Documentation
name: Deploy Documentation
on:
# Trigger on push to main branch
@@ -11,11 +9,9 @@ on:
# Only run when docs files change
paths:
- 'docs/**'
- 'README.md' # README is synced to docs/index.md
- 'mkdocs.yml'
- 'requirements-docs.txt'
- '.github/workflows/deploy-docs.yml'
- 'scripts/fix-mkdocs-structure.ts'
- 'apps/edit-docs/**'
- 'apps/build-docs/**'
- 'packages/share-theme/**'
# Allow manual triggering from Actions tab
workflow_dispatch:
@@ -27,15 +23,13 @@ on:
- master
paths:
- 'docs/**'
- 'README.md' # README is synced to docs/index.md
- 'mkdocs.yml'
- 'requirements-docs.txt'
- '.github/workflows/deploy-docs.yml'
- 'scripts/fix-mkdocs-structure.ts'
- 'apps/edit-docs/**'
- 'apps/build-docs/**'
- 'packages/share-theme/**'
jobs:
build-and-deploy:
name: Build and Deploy MkDocs
name: Build and Deploy Documentation
runs-on: ubuntu-latest
timeout-minutes: 10
@@ -49,72 +43,27 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v5
with:
fetch-depth: 0 # Fetch all history for git info and mkdocs-git-revision-date plugin
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: '3.14'
cache: 'pip'
cache-dependency-path: 'requirements-docs.txt'
- name: Install MkDocs and Dependencies
run: |
pip install --upgrade pip
pip install -r requirements-docs.txt
env:
PIP_DISABLE_PIP_VERSION_CHECK: 1
# Setup pnpm before fixing docs structure
- name: Setup pnpm
uses: pnpm/action-setup@v4
# Setup Node.js with pnpm
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '22'
node-version: '24'
cache: 'pnpm'
# Install Node.js dependencies for the TypeScript script
- name: Install Dependencies
run: |
pnpm install --frozen-lockfile
run: pnpm install --frozen-lockfile
- name: Fix Documentation Structure
run: |
# Fix duplicate navigation entries by moving overview pages to index.md
pnpm run chore:fix-mkdocs-structure
- name: Build MkDocs Site
run: |
# Build with strict mode but allow expected warnings
mkdocs build --verbose || {
EXIT_CODE=$?
# Check if the only issue is expected warnings
if mkdocs build 2>&1 | grep -E "WARNING.*(README|not found)" && \
[ $(mkdocs build 2>&1 | grep -c "ERROR") -eq 0 ]; then
echo "✅ Build succeeded with expected warnings"
mkdocs build --verbose
else
echo "❌ Build failed with unexpected errors"
exit $EXIT_CODE
fi
}
- name: Fix HTML Links
run: |
# Remove .md extensions from links in generated HTML
pnpm tsx ./scripts/fix-html-links.ts site
- name: Trigger build of documentation
run: pnpm docs:build
- name: Validate Built Site
run: |
# Basic validation that important files exist
test -f site/index.html || (echo "ERROR: site/index.html not found" && exit 1)
test -f site/sitemap.xml || (echo "ERROR: site/sitemap.xml not found" && exit 1)
test -d site/assets || (echo "ERROR: site/assets directory not found" && exit 1)
echo "✅ Site validation passed"
test -f site/developer-guide/index.html || (echo "ERROR: site/developer-guide/index.html not found" && exit 1)
echo "✓ User Guide and Developer Guide built successfully"
- name: Deploy
uses: ./.github/actions/deploy-to-cloudflare-pages

View File

@@ -30,7 +30,7 @@ jobs:
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:
node-version: 22
node-version: 24
cache: "pnpm"
- run: pnpm install --frozen-lockfile

View File

@@ -46,7 +46,7 @@ jobs:
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:
node-version: 22
node-version: 24
cache: "pnpm"
- name: Install npm dependencies
@@ -86,12 +86,12 @@ jobs:
- name: Upload Playwright trace
if: failure()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: Playwright trace (${{ matrix.dockerfile }})
path: test-output/playwright/output
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v5
if: ${{ !cancelled() }}
with:
name: Playwright report (${{ matrix.dockerfile }})
@@ -116,10 +116,10 @@ jobs:
- dockerfile: Dockerfile
platform: linux/arm64
image: ubuntu-24.04-arm
- dockerfile: Dockerfile
- dockerfile: Dockerfile.legacy
platform: linux/arm/v7
image: ubuntu-24.04-arm
- dockerfile: Dockerfile
- dockerfile: Dockerfile.legacy
platform: linux/arm/v8
image: ubuntu-24.04-arm
runs-on: ${{ matrix.image }}
@@ -146,7 +146,7 @@ jobs:
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:
node-version: 22
node-version: 24
cache: 'pnpm'
- name: Install dependencies
@@ -209,7 +209,7 @@ jobs:
touch "/tmp/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: digests-${{ env.PLATFORM_PAIR }}-${{ matrix.dockerfile }}
path: /tmp/digests/*
@@ -223,7 +223,7 @@ jobs:
- build
steps:
- name: Download digests
uses: actions/download-artifact@v5
uses: actions/download-artifact@v6
with:
path: /tmp/digests
pattern: digests-*

View File

@@ -52,7 +52,7 @@ jobs:
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:
node-version: 22
node-version: 24
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
@@ -89,7 +89,7 @@ jobs:
name: Nightly Build
- name: Publish artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
if: ${{ github.event_name == 'pull_request' }}
with:
name: TriliumNotes ${{ matrix.os.name }} ${{ matrix.arch }}

View File

@@ -24,7 +24,7 @@ jobs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v6
with:
node-version: 22
node-version: 24
cache: 'pnpm'
- name: Install dependencies
@@ -35,7 +35,7 @@ jobs:
- name: Upload test report
if: failure()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: e2e report
path: apps/server-e2e/test-output

View File

@@ -50,7 +50,7 @@ jobs:
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:
node-version: 22
node-version: 24
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
@@ -73,7 +73,7 @@ jobs:
GPG_SIGNING_KEY: ${{ secrets.GPG_SIGN_KEY }}
- name: Upload the artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: release-desktop-${{ matrix.os.name }}-${{ matrix.arch }}
path: apps/desktop/upload/*.*
@@ -100,7 +100,7 @@ jobs:
arch: ${{ matrix.arch }}
- name: Upload the artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: release-server-linux-${{ matrix.arch }}
path: upload/*.*
@@ -120,7 +120,7 @@ jobs:
docs/Release Notes
- name: Download all artifacts
uses: actions/download-artifact@v5
uses: actions/download-artifact@v6
with:
merge-multiple: true
pattern: release-*

View File

@@ -30,7 +30,7 @@ jobs:
- name: Set up node & dependencies
uses: actions/setup-node@v6
with:
node-version: 22
node-version: 24
cache: "pnpm"
- name: Install dependencies

2
.nvmrc
View File

@@ -1 +1 @@
22.21.0
24.11.0

View File

@@ -37,20 +37,18 @@
"devDependencies": {
"@playwright/test": "1.56.1",
"@stylistic/eslint-plugin": "5.5.0",
"@types/express": "5.0.3",
"@types/node": "22.18.12",
"@types/yargs": "17.0.33",
"@types/express": "5.0.5",
"@types/node": "24.9.2",
"@types/yargs": "17.0.34",
"@vitest/coverage-v8": "3.2.4",
"eslint": "9.38.0",
"eslint": "9.39.0",
"eslint-plugin-simple-import-sort": "12.1.1",
"esm": "3.2.25",
"jsdoc": "4.0.5",
"lorem-ipsum": "2.0.8",
"rcedit": "4.0.1",
"rimraf": "6.0.1",
"tslib": "2.8.1",
"typedoc": "0.28.14",
"typedoc-plugin-missing-exports": "4.1.2"
"rimraf": "6.1.0",
"tslib": "2.8.1"
},
"optionalDependencies": {
"appdmg": "0.6.6"

View File

@@ -1,15 +0,0 @@
{
"entryPoints": [
"src/services/backend_script_entrypoint.ts",
"src/public/app/services/frontend_script_entrypoint.ts"
],
"plugin": [
"typedoc-plugin-missing-exports"
],
"outputs": [
{
"name": "html",
"path": "./docs/Script API"
}
]
}

View File

@@ -0,0 +1,22 @@
{
"name": "build-docs",
"version": "1.0.0",
"description": "",
"main": "src/main.ts",
"scripts": {
"start": "tsx ."
},
"keywords": [],
"author": "Elian Doran <contact@eliandoran.me>",
"license": "AGPL-3.0-only",
"packageManager": "pnpm@10.19.0",
"devDependencies": {
"@redocly/cli": "2.10.0",
"archiver": "7.0.1",
"fs-extra": "11.3.2",
"react": "19.2.0",
"react-dom": "19.2.0",
"typedoc": "0.28.14",
"typedoc-plugin-missing-exports": "4.1.2"
}
}

View File

@@ -0,0 +1,36 @@
/**
* The backend script API is accessible to code notes with the "JS (backend)" language.
*
* The entire API is exposed as a single global: {@link api}
*
* @module Backend Script API
*/
/**
* This file creates the entrypoint for TypeDoc that simulates the context from within a
* script note on the server side.
*
* Make sure to keep in line with backend's `script_context.ts`.
*/
export type { default as AbstractBeccaEntity } from "../../server/src/becca/entities/abstract_becca_entity.js";
export type { default as BAttachment } from "../../server/src/becca/entities/battachment.js";
export type { default as BAttribute } from "../../server/src/becca/entities/battribute.js";
export type { default as BBranch } from "../../server/src/becca/entities/bbranch.js";
export type { default as BEtapiToken } from "../../server/src/becca/entities/betapi_token.js";
export type { BNote };
export type { default as BOption } from "../../server/src/becca/entities/boption.js";
export type { default as BRecentNote } from "../../server/src/becca/entities/brecent_note.js";
export type { default as BRevision } from "../../server/src/becca/entities/brevision.js";
import BNote from "../../server/src/becca/entities/bnote.js";
import BackendScriptApi, { type Api } from "../../server/src/services/backend_script_api.js";
export type { Api };
const fakeNote = new BNote();
/**
* The `api` global variable allows access to the backend script API, which is documented in {@link Api}.
*/
export const api: Api = new BackendScriptApi(fakeNote, {});

View File

@@ -0,0 +1,146 @@
process.env.TRILIUM_INTEGRATION_TEST = "memory-no-store";
process.env.TRILIUM_RESOURCE_DIR = "../server/src";
process.env.NODE_ENV = "development";
import cls from "@triliumnext/server/src/services/cls.js";
import { dirname, join, resolve } from "path";
import * as fs from "fs/promises";
import * as fsExtra from "fs-extra";
import archiver from "archiver";
import { WriteStream } from "fs";
import { execSync } from "child_process";
import BuildContext from "./context.js";
const DOCS_ROOT = "../../../docs";
const OUTPUT_DIR = "../../site";
async function importAndExportDocs(sourcePath: string, outputSubDir: string) {
const note = await importData(sourcePath);
// Use a meaningful name for the temporary zip file
const zipName = outputSubDir || "user-guide";
const zipFilePath = `output-${zipName}.zip`;
try {
const { exportToZip } = (await import("@triliumnext/server/src/services/export/zip.js")).default;
const branch = note.getParentBranches()[0];
const taskContext = new (await import("@triliumnext/server/src/services/task_context.js")).default(
"no-progress-reporting",
"export",
null
);
const fileOutputStream = fsExtra.createWriteStream(zipFilePath);
await exportToZip(taskContext, branch, "share", fileOutputStream);
await waitForStreamToFinish(fileOutputStream);
// Output to root directory if outputSubDir is empty, otherwise to subdirectory
const outputPath = outputSubDir ? join(OUTPUT_DIR, outputSubDir) : OUTPUT_DIR;
await extractZip(zipFilePath, outputPath);
} finally {
if (await fsExtra.exists(zipFilePath)) {
await fsExtra.rm(zipFilePath);
}
}
}
async function buildDocsInner() {
const i18n = await import("@triliumnext/server/src/services/i18n.js");
await i18n.initializeTranslations();
const sqlInit = (await import("../../server/src/services/sql_init.js")).default;
await sqlInit.createInitialDatabase(true);
// Wait for becca to be loaded before importing data
const beccaLoader = await import("../../server/src/becca/becca_loader.js");
await beccaLoader.beccaLoaded;
// Build User Guide
console.log("Building User Guide...");
await importAndExportDocs(join(__dirname, DOCS_ROOT, "User Guide"), "");
// Build Developer Guide
console.log("Building Developer Guide...");
await importAndExportDocs(join(__dirname, DOCS_ROOT, "Developer Guide"), "developer-guide");
// Copy favicon.
await fs.copyFile("../../apps/website/src/assets/favicon.ico", join(OUTPUT_DIR, "favicon.ico"));
console.log("Documentation built successfully!");
}
export async function importData(path: string) {
const buffer = await createImportZip(path);
const importService = (await import("../../server/src/services/import/zip.js")).default;
const TaskContext = (await import("../../server/src/services/task_context.js")).default;
const context = new TaskContext("no-progress-reporting", "importNotes", null);
const beccaLoader = (await import("../../server/src/becca/becca_loader.js")).default;
const becca = beccaLoader.becca;
const rootNote = becca.getRoot();
if (!rootNote) {
throw new Error("Missing root note for import.");
}
return await importService.importZip(context, buffer, rootNote, {
preserveIds: true
});
}
async function createImportZip(path: string) {
const inputFile = "input.zip";
const archive = archiver("zip", {
zlib: { level: 0 }
});
console.log("Archive path is ", resolve(path))
archive.directory(path, "/");
const outputStream = fsExtra.createWriteStream(inputFile);
archive.pipe(outputStream);
archive.finalize();
await waitForStreamToFinish(outputStream);
try {
return await fsExtra.readFile(inputFile);
} finally {
await fsExtra.rm(inputFile);
}
}
function waitForStreamToFinish(stream: WriteStream) {
return new Promise<void>((res, rej) => {
stream.on("finish", () => res());
stream.on("error", (err) => rej(err));
});
}
export async function extractZip(zipFilePath: string, outputPath: string, ignoredFiles?: Set<string>) {
const { readZipFile, readContent } = (await import("@triliumnext/server/src/services/import/zip.js"));
await readZipFile(await fs.readFile(zipFilePath), async (zip, entry) => {
// We ignore directories since they can appear out of order anyway.
if (!entry.fileName.endsWith("/") && !ignoredFiles?.has(entry.fileName)) {
const destPath = join(outputPath, entry.fileName);
const fileContent = await readContent(zip, entry);
await fsExtra.mkdirs(dirname(destPath));
await fs.writeFile(destPath, fileContent);
}
zip.readEntry();
});
}
export default async function buildDocs({ gitRootDir }: BuildContext) {
// Build the share theme.
execSync(`pnpm run --filter share-theme build`, {
stdio: "inherit",
cwd: gitRootDir
});
// Trigger the actual build.
await new Promise((res, rej) => {
cls.init(() => {
buildDocsInner()
.catch(rej)
.then(res);
});
});
}

View File

@@ -0,0 +1,4 @@
export default interface BuildContext {
gitRootDir: string;
baseDir: string;
}

View File

@@ -0,0 +1,28 @@
/**
* The front script API is accessible to code notes with the "JS (frontend)" language.
*
* The entire API is exposed as a single global: {@link api}
*
* @module Frontend Script API
*/
/**
* This file creates the entrypoint for TypeDoc that simulates the context from within a
* script note.
*
* Make sure to keep in line with frontend's `script_context.ts`.
*/
export type { default as BasicWidget } from "../../client/src/widgets/basic_widget.js";
export type { default as FAttachment } from "../../client/src/entities/fattachment.js";
export type { default as FAttribute } from "../../client/src/entities/fattribute.js";
export type { default as FBranch } from "../../client/src/entities/fbranch.js";
export type { default as FNote } from "../../client/src/entities/fnote.js";
export type { Api } from "../../client/src/services/frontend_script_api.js";
export type { default as NoteContextAwareWidget } from "../../client/src/widgets/note_context_aware_widget.js";
export type { default as RightPanelWidget } from "../../client/src/widgets/right_panel_widget.js";
import FrontendScriptApi, { type Api } from "../../client/src/services/frontend_script_api.js";
//@ts-expect-error
export const api: Api = new FrontendScriptApi();

View File

@@ -0,0 +1,26 @@
import { join } from "path";
import BuildContext from "./context";
import buildSwagger from "./swagger";
import { existsSync, mkdirSync, rmSync } from "fs";
import buildDocs from "./build-docs";
import buildScriptApi from "./script-api";
const context: BuildContext = {
gitRootDir: join(__dirname, "../../../"),
baseDir: join(__dirname, "../../../site")
};
async function main() {
// Clean input dir.
if (existsSync(context.baseDir)) {
rmSync(context.baseDir, { recursive: true });
}
mkdirSync(context.baseDir);
// Start building.
await buildDocs(context);
buildSwagger(context);
buildScriptApi(context);
}
main();

View File

@@ -0,0 +1,15 @@
import { execSync } from "child_process";
import BuildContext from "./context";
import { join } from "path";
export default function buildScriptApi({ baseDir, gitRootDir }: BuildContext) {
// Generate types
execSync(`pnpm typecheck`, { stdio: "inherit", cwd: gitRootDir });
for (const config of [ "backend", "frontend" ]) {
const outDir = join(baseDir, "script-api", config);
execSync(`pnpm typedoc --options typedoc.${config}.json --html "${outDir}"`, {
stdio: "inherit"
});
}
}

View File

@@ -0,0 +1,32 @@
import BuildContext from "./context";
import { join } from "path";
import { execSync } from "child_process";
import { mkdirSync } from "fs";
interface BuildInfo {
specPath: string;
outDir: string;
}
const DIR_PREFIX = "rest-api";
const buildInfos: BuildInfo[] = [
{
// Paths are relative to Git root.
specPath: "apps/server/internal.openapi.yaml",
outDir: `${DIR_PREFIX}/internal`
},
{
specPath: "apps/server/etapi.openapi.yaml",
outDir: `${DIR_PREFIX}/etapi`
}
];
export default function buildSwagger({ baseDir, gitRootDir }: BuildContext) {
for (const { specPath, outDir } of buildInfos) {
const absSpecPath = join(gitRootDir, specPath);
const targetDir = join(baseDir, outDir);
mkdirSync(targetDir, { recursive: true });
execSync(`pnpm redocly build-docs ${absSpecPath} -o ${targetDir}/index.html`, { stdio: "inherit" });
}
}

View File

@@ -0,0 +1,36 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler",
"target": "ES2020",
"outDir": "dist",
"strict": false,
"types": [
"node",
"express"
],
"rootDir": "src",
"tsBuildInfoFile": "dist/tsconfig.app.tsbuildinfo"
},
"include": [
"src/**/*.ts",
"../server/src/*.d.ts"
],
"exclude": [
"eslint.config.js",
"eslint.config.cjs",
"eslint.config.mjs"
],
"references": [
{
"path": "../server/tsconfig.app.json"
},
{
"path": "../desktop/tsconfig.app.json"
},
{
"path": "../client/tsconfig.app.json"
}
]
}

View File

@@ -0,0 +1,15 @@
{
"extends": "../../tsconfig.base.json",
"include": [],
"references": [
{
"path": "../server"
},
{
"path": "../client"
},
{
"path": "./tsconfig.app.json"
}
]
}

View File

@@ -0,0 +1,10 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Trilium Backend API",
"entryPoints": [
"src/backend_script_entrypoint.ts"
],
"plugin": [
"typedoc-plugin-missing-exports"
]
}

View File

@@ -0,0 +1,10 @@
{
"$schema": "https://typedoc.org/schema.json",
"name": "Trilium Frontend API",
"entryPoints": [
"src/frontend_script_entrypoint.ts"
],
"plugin": [
"typedoc-plugin-missing-exports"
]
}

View File

@@ -15,7 +15,7 @@
"circular-deps": "dpdm -T src/**/*.ts --tree=false --warning=false --skip-dynamic-imports=circular"
},
"dependencies": {
"@eslint/js": "9.38.0",
"@eslint/js": "9.39.0",
"@excalidraw/excalidraw": "0.18.0",
"@fullcalendar/core": "6.1.19",
"@fullcalendar/daygrid": "6.1.19",
@@ -37,12 +37,12 @@
"bootstrap": "5.3.8",
"boxicons": "2.1.4",
"color": "5.0.2",
"dayjs": "1.11.18",
"dayjs": "1.11.19",
"dayjs-plugin-utc": "0.1.2",
"debounce": "2.2.0",
"draggabilly": "3.0.0",
"force-graph": "1.51.0",
"globals": "16.4.0",
"globals": "16.5.0",
"i18next": "25.6.0",
"i18next-http-backend": "3.0.2",
"jquery": "3.7.1",
@@ -54,12 +54,12 @@
"leaflet-gpx": "2.2.0",
"mark.js": "8.11.1",
"marked": "16.4.1",
"mermaid": "11.12.0",
"mind-elixir": "5.3.3",
"mermaid": "11.12.1",
"mind-elixir": "5.3.4",
"normalize.css": "8.0.1",
"panzoom": "9.4.3",
"preact": "10.27.2",
"react-i18next": "16.1.2",
"react-i18next": "16.2.3",
"reveal.js": "5.2.1",
"svg-pan-zoom": "3.6.2",
"tabulator-tables": "6.3.1",
@@ -74,9 +74,9 @@
"@types/leaflet-gpx": "1.3.8",
"@types/mark.js": "8.11.12",
"@types/reveal.js": "5.2.1",
"@types/tabulator-tables": "6.2.11",
"@types/tabulator-tables": "6.3.0",
"copy-webpack-plugin": "13.0.1",
"happy-dom": "20.0.7",
"happy-dom": "20.0.10",
"script-loader": "0.7.2",
"vite-plugin-static-copy": "3.1.4"
}

View File

@@ -218,12 +218,12 @@ export type CommandMappings = {
/** Works only in the electron context menu. */
replaceMisspelling: CommandData;
importMarkdownInline: CommandData;
showPasswordNotSet: CommandData;
showProtectedSessionPasswordDialog: CommandData;
showUploadAttachmentsDialog: CommandData & { noteId: string };
showIncludeNoteDialog: CommandData & { textTypeWidget: EditableTextTypeWidget };
showAddLinkDialog: CommandData & { textTypeWidget: EditableTextTypeWidget, text: string };
showPasteMarkdownDialog: CommandData & { textTypeWidget: EditableTextTypeWidget };
closeProtectedSessionPasswordDialog: CommandData;
copyImageReferenceToClipboard: CommandData;
copyImageToClipboard: CommandData;
@@ -270,6 +270,7 @@ export type CommandMappings = {
closeThisNoteSplit: CommandData;
moveThisNoteSplit: CommandData & { isMovingLeft: boolean };
jumpToNote: CommandData;
openTodayNote: CommandData;
commandPalette: CommandData;
// Keyboard shortcuts

View File

@@ -159,6 +159,16 @@ export default class Entrypoints extends Component {
this.openInWindowCommand({ notePath: "", hoistedNoteId: "root" });
}
async openTodayNoteCommand() {
const todayNote = await dateNoteService.getTodayNote();
if (!todayNote) {
console.warn("Missing today note.");
return;
}
await appContext.tabManager.openInSameTab(todayNote.noteId);
}
async runActiveNoteCommand() {
const noteContext = appContext.tabManager.getActiveContext();
if (!noteContext) {

View File

@@ -417,7 +417,7 @@ export default class FNote {
return notePaths;
}
getSortedNotePathRecords(hoistedNoteId = "root"): NotePathRecord[] {
getSortedNotePathRecords(hoistedNoteId = "root", activeNotePath: string | null = null): NotePathRecord[] {
const isHoistedRoot = hoistedNoteId === "root";
const notePaths: NotePathRecord[] = this.getAllNotePaths().map((path) => ({
@@ -428,7 +428,23 @@ export default class FNote {
isHidden: path.includes("_hidden")
}));
// Calculate the length of the prefix match between two arrays
const prefixMatchLength = (path: string[], target: string[]) => {
const diffIndex = path.findIndex((seg, i) => seg !== target[i]);
return diffIndex === -1 ? Math.min(path.length, target.length) : diffIndex;
};
notePaths.sort((a, b) => {
if (activeNotePath) {
const activeSegments = activeNotePath.split('/');
const aOverlap = prefixMatchLength(a.notePath, activeSegments);
const bOverlap = prefixMatchLength(b.notePath, activeSegments);
// Paths with more matching prefix segments are prioritized
// when the match count is equal, other criteria are used for sorting
if (bOverlap !== aOverlap) {
return bOverlap - aOverlap;
}
}
if (a.isInHoistedSubTree !== b.isInHoistedSubTree) {
return a.isInHoistedSubTree ? -1 : 1;
} else if (a.isArchived !== b.isArchived) {
@@ -449,10 +465,11 @@ export default class FNote {
* Returns the note path considered to be the "best"
*
* @param {string} [hoistedNoteId='root']
* @param {string|null} [activeNotePath=null]
* @return {string[]} array of noteIds constituting the particular note path
*/
getBestNotePath(hoistedNoteId = "root") {
return this.getSortedNotePathRecords(hoistedNoteId)[0]?.notePath;
getBestNotePath(hoistedNoteId = "root", activeNotePath: string | null = null) {
return this.getSortedNotePathRecords(hoistedNoteId, activeNotePath)[0]?.notePath;
}
/**

View File

@@ -29,8 +29,9 @@ import PromotedAttributesWidget from "../widgets/promoted_attributes.js";
import NoteDetailWidget from "../widgets/note_detail.js";
import CallToActionDialog from "../widgets/dialogs/call_to_action.jsx";
import NoteTitleWidget from "../widgets/note_title.jsx";
import { PopupEditorFormattingToolbar } from "../widgets/ribbon/FormattingToolbar.js";
import FormattingToolbar from "../widgets/ribbon/FormattingToolbar.js";
import NoteList from "../widgets/collections/NoteList.jsx";
import StandaloneRibbonAdapter from "../widgets/ribbon/components/StandaloneRibbonAdapter.jsx";
export function applyModals(rootContainer: RootContainer) {
rootContainer
@@ -63,7 +64,7 @@ export function applyModals(rootContainer: RootContainer) {
.cssBlock(".title-row > * { margin: 5px; }")
.child(<NoteIconWidget />)
.child(<NoteTitleWidget />))
.child(<PopupEditorFormattingToolbar />)
.child(<StandaloneRibbonAdapter component={FormattingToolbar} />)
.child(new PromotedAttributesWidget())
.child(new NoteDetailWidget())
.child(<NoteList media="screen" displayOnlyCollections />))

View File

@@ -24,6 +24,9 @@ import CloseZenModeButton from "../widgets/close_zen_button.js";
import NoteWrapperWidget from "../widgets/note_wrapper.js";
import MobileDetailMenu from "../widgets/mobile_widgets/mobile_detail_menu.js";
import NoteList from "../widgets/collections/NoteList.jsx";
import StandaloneRibbonAdapter from "../widgets/ribbon/components/StandaloneRibbonAdapter.jsx";
import SearchDefinitionTab from "../widgets/ribbon/SearchDefinitionTab.jsx";
import SearchResult from "../widgets/search_result.jsx";
const MOBILE_CSS = `
<style>
@@ -155,6 +158,8 @@ export default class MobileLayout {
.contentSized()
.child(new NoteDetailWidget())
.child(<NoteList media="screen" />)
.child(<StandaloneRibbonAdapter component={SearchDefinitionTab} />)
.child(<SearchResult />)
.child(<FilePropertiesWrapper />)
)
.child(<MobileEditorToolbar />)

View File

@@ -56,7 +56,20 @@ function SingleNoteRenderer({ note, onReady }: RendererProps) {
await import("@triliumnext/ckeditor5/src/theme/ck-content.css");
}
const { $renderedContent } = await content_renderer.getRenderedContent(note, { noChildrenList: true });
containerRef.current?.replaceChildren(...$renderedContent);
const container = containerRef.current!;
container.replaceChildren(...$renderedContent);
// Wait for all images to load.
const images = Array.from(container.querySelectorAll("img"));
await Promise.all(
images.map(img => {
if (img.complete) return Promise.resolve();
return new Promise<void>(resolve => {
img.addEventListener("load", () => resolve(), { once: true });
img.addEventListener("error", () => resolve(), { once: true });
});
})
);
}
load().then(() => requestAnimationFrame(onReady))

View File

@@ -1,28 +0,0 @@
/**
* The front script API is accessible to code notes with the "JS (frontend)" language.
*
* The entire API is exposed as a single global: {@link api}
*
* @module Frontend Script API
*/
/**
* This file creates the entrypoint for TypeDoc that simulates the context from within a
* script note.
*
* Make sure to keep in line with frontend's `script_context.ts`.
*/
export type { default as BasicWidget } from "../widgets/basic_widget.js";
export type { default as FAttachment } from "../entities/fattachment.js";
export type { default as FAttribute } from "../entities/fattribute.js";
export type { default as FBranch } from "../entities/fbranch.js";
export type { default as FNote } from "../entities/fnote.js";
export type { Api } from "./frontend_script_api.js";
export type { default as NoteContextAwareWidget } from "../widgets/note_context_aware_widget.js";
export type { default as RightPanelWidget } from "../widgets/right_panel_widget.js";
import FrontendScriptApi, { type Api } from "./frontend_script_api.js";
//@ts-expect-error
export const api: Api = new FrontendScriptApi();

View File

@@ -20,9 +20,6 @@ function setupGlobs() {
window.glob.froca = froca;
window.glob.treeCache = froca; // compatibility for CKEditor builds for a while
// for CKEditor integration (button on block toolbar)
window.glob.importMarkdownInline = async () => appContext.triggerCommand("importMarkdownInline");
window.onerror = function (msg, url, lineNo, columnNo, error) {
const string = String(msg).toLowerCase();

View File

@@ -10,7 +10,7 @@ export const byNoteType: Record<Exclude<NoteType, "book">, string | null> = {
file: null,
image: null,
launcher: null,
mermaid: null,
mermaid: "s1aBHPd79XYj",
mindMap: null,
noteMap: null,
relationMap: null,

View File

@@ -26,21 +26,12 @@ async function resolveNotePathToSegments(notePath: string, hoistedNoteId = "root
}
const path = notePath.split("/").reverse();
if (!path.includes("root")) {
path.push("root");
}
const effectivePathSegments: string[] = [];
let childNoteId: string | null = null;
let i = 0;
while (true) {
if (i >= path.length) {
break;
}
const parentNoteId = path[i++];
for (let i = 0; i < path.length; i++) {
const parentNoteId = path[i];
if (childNoteId !== null) {
const child = await froca.getNote(childNoteId, !logErrors);
@@ -65,7 +56,7 @@ async function resolveNotePathToSegments(notePath: string, hoistedNoteId = "root
return null;
}
if (!parents.some((p) => p.noteId === parentNoteId)) {
if (!parents.some(p => p.noteId === parentNoteId) || (i === path.length - 1 && parentNoteId !== 'root')) {
if (logErrors) {
const parent = froca.getNoteFromCache(parentNoteId);
@@ -77,7 +68,8 @@ async function resolveNotePathToSegments(notePath: string, hoistedNoteId = "root
);
}
const bestNotePath = child.getBestNotePath(hoistedNoteId);
const activeNotePath = appContext.tabManager.getActiveContextNotePath();
const bestNotePath = child.getBestNotePath(hoistedNoteId, activeNotePath);
if (bestNotePath) {
const pathToRoot = bestNotePath.reverse().slice(1);
@@ -108,7 +100,9 @@ async function resolveNotePathToSegments(notePath: string, hoistedNoteId = "root
if (!note) {
throw new Error(`Unable to find note: ${notePath}.`);
}
const bestNotePath = note.getBestNotePath(hoistedNoteId);
const activeNotePath = appContext.tabManager.getActiveContextNotePath();
const bestNotePath = note.getBestNotePath(hoistedNoteId, activeNotePath);
if (!bestNotePath) {
throw new Error(`Did not find any path segments for '${note.toString()}', hoisted note '${hoistedNoteId}'`);

View File

@@ -11,7 +11,11 @@ export function reloadFrontendApp(reason?: string) {
logInfo(`Frontend app reload: ${reason}`);
}
window.location.reload();
if (isElectron()) {
dynamicRequire("@electron/remote").BrowserWindow.getFocusedWindow()?.reload();
} else {
window.location.reload();
}
}
export function restartDesktopApp() {

View File

@@ -1,84 +0,0 @@
import "normalize.css";
import "boxicons/css/boxicons.min.css";
import "@triliumnext/ckeditor5/src/theme/ck-content.css";
import "@triliumnext/share-theme/styles/index.css";
import "@triliumnext/share-theme/scripts/index.js";
async function ensureJQuery() {
const $ = (await import("jquery")).default;
(window as any).$ = $;
}
async function applyMath() {
const anyMathBlock = document.querySelector("#content .math-tex");
if (!anyMathBlock) {
return;
}
const renderMathInElement = (await import("./services/math.js")).renderMathInElement;
renderMathInElement(document.getElementById("content"));
}
async function formatCodeBlocks() {
const anyCodeBlock = document.querySelector("#content pre");
if (!anyCodeBlock) {
return;
}
await ensureJQuery();
const { formatCodeBlocks } = await import("./services/syntax_highlight.js");
await formatCodeBlocks($("#content"));
}
async function setupTextNote() {
formatCodeBlocks();
applyMath();
const setupMermaid = (await import("./share/mermaid.js")).default;
setupMermaid();
}
/**
* Fetch note with given ID from backend
*
* @param noteId of the given note to be fetched. If false, fetches current note.
*/
async function fetchNote(noteId: string | null = null) {
if (!noteId) {
noteId = document.body.getAttribute("data-note-id");
}
const resp = await fetch(`api/notes/${noteId}`);
return await resp.json();
}
document.addEventListener(
"DOMContentLoaded",
() => {
const noteType = determineNoteType();
if (noteType === "text") {
setupTextNote();
}
const toggleMenuButton = document.getElementById("toggleMenuButton");
const layout = document.getElementById("layout");
if (toggleMenuButton && layout) {
toggleMenuButton.addEventListener("click", () => layout.classList.toggle("showMenu"));
}
},
false
);
function determineNoteType() {
const bodyClass = document.body.className;
const match = bodyClass.match(/type-([^\s]+)/);
return match ? match[1] : null;
}
// workaround to prevent webpack from removing "fetchNote" as dead code:
// add fetchNote as property to the window object
Object.defineProperty(window, "fetchNote", {
value: fetchNote
});

View File

@@ -2034,9 +2034,9 @@ body.zen #right-pane,
body.zen #mobile-sidebar-wrapper,
body.zen .tab-row-container,
body.zen .tab-row-widget,
body.zen .ribbon-container:not(:has(.classic-toolbar-widget.visible)),
body.zen .ribbon-container:has(.classic-toolbar-widget.visible) .ribbon-top-row,
body.zen .ribbon-container .ribbon-body:not(:has(.classic-toolbar-widget.visible)),
body.zen .ribbon-container:not(:has(.classic-toolbar-widget)),
body.zen .ribbon-container:has(.classic-toolbar-widget) .ribbon-top-row,
body.zen .ribbon-container .ribbon-body:not(:has(.classic-toolbar-widget)),
body.zen .note-icon-widget,
body.zen .title-row .icon-action,
body.zen .floating-buttons-children > *:not(.bx-edit-alt),
@@ -2432,4 +2432,8 @@ iframe.print-iframe {
bottom: 0;
width: 0;
height: 0;
}
.excalidraw.theme--dark canvas {
--theme-filter: invert(100%) hue-rotate(180deg);
}

View File

@@ -63,7 +63,7 @@
/* Button bar */
.search-definition-widget .search-setting-table tbody:last-child div {
justify-content: flex-end !important;
justify-content: flex-end;
gap: 8px;
}

View File

@@ -12,6 +12,9 @@
"toast": {
"critical-error": {
"title": "خطأ فادح"
},
"widget-error": {
"title": "فشل في البدء بعنصر الواجهة"
}
},
"add_link": {
@@ -26,7 +29,8 @@
"edit_branch_prefix": "تعديل بادئة الفرع",
"prefix": "البادئة: ",
"save": "حفظ",
"help_on_tree_prefix": "مساعدة حول بادئة الشجرة"
"help_on_tree_prefix": "مساعدة حول بادئة الشجرة",
"branch_prefix_saved": "تم حفظ بادئة الفرع."
},
"bulk_actions": {
"bulk_actions": "اجراءات جماعية",
@@ -83,7 +87,8 @@
"workspace_calendar_root": "‎تحديد جذر التقويم لكل مساحة عمل",
"hide_highlight_widget": "اخفاء عنصر واجهة قائمة التمييزات",
"is_owned_by_note": "تخص الملاحظة",
"and_more": "... و {{count}}مرات اكثر."
"and_more": "... و {{count}}مرات اكثر.",
"related_notes_title": "ملاحظات اخرى بنفس التسمية"
},
"rename_label": {
"to": "الى",
@@ -127,7 +132,9 @@
"delete_attachment": "حذف المرفق",
"upload_new_revision": "رفع مراجعة جديدة",
"copy_link_to_clipboard": "نسخ الرابط الى الحافظة",
"convert_attachment_into_note": "تحويل المرفق الى ملاحظة"
"convert_attachment_into_note": "تحويل المرفق الى ملاحظة",
"delete_success": "تم حذف المرفق \"{{title}}\" .",
"enter_new_name": "ادخل اسم مرفق جديد"
},
"calendar": {
"week": "أسبوع",
@@ -259,7 +266,8 @@
"note_paths": {
"search": "بحث",
"archived": "مؤرشف",
"title": "مسارات الملاحظة"
"title": "مسارات الملاحظة",
"clone_button": "جار نسخ الملاحظة الى مكان جديد..."
},
"script_executor": {
"query": "استعلام",
@@ -372,7 +380,8 @@
"export_note_title": "تصدير الملاحظة",
"export_status": "حالة التصدير",
"export_finished_successfully": "اكتمل التصدير بنجاح.",
"export_in_progress": "جار التصدير: {{progressCount}}"
"export_in_progress": "جار التصدير: {{progressCount}}",
"choose_export_type": "اختر نوع التصدير اولا من فضلك"
},
"help": {
"troubleshooting": "أستكشاف الاخطاء واصلاحها",
@@ -402,7 +411,10 @@
"movingCloningNotes": "نقل/ استنساخ الملاحظات",
"deleteNotes": "حذف الملاحظة/ الشجرة الفرعية",
"collapseWholeTree": "طي شجرة الملاحظة باكملها",
"followLink": "اتبع تلرابط تحت المؤشر"
"followLink": "اتبع تلرابط تحت المؤشر",
"onlyInDesktop": "في سطح المكتب فقط(Electron build)",
"createEditLink": "انشاء/ تحرير رابط خارجي",
"quickSearch": "الانتقال الى مربع البحث السريع"
},
"import": {
"options": "خيارات",
@@ -465,7 +477,13 @@
"delete_all_button": "حذف كل المراجعات",
"settings": "اعدادات مراجعة الملاحظة",
"diff_not_available": "المقارنة غير متوفرة.",
"help_title": "مساعدة حول مراجعات الملاحظة"
"help_title": "مساعدة حول مراجعات الملاحظة",
"diff_off_hint": "انقر لعرض محتويات الملاحظة",
"revisions_deleted": "تم حذف جميع نسخ المراجعات للملاحظة.",
"revision_restored": "تم استعادة نسخ المراجعة للملاحظة.",
"revision_deleted": "تم حذف مراجعة الملاحظة.",
"snapshot_interval": "فاصل زمني لحفظ لقطات اصدارات المراجعة: {{seconds}}",
"maximum_revisions": "حد عدد لقطات اصدارات الملاحظة: {{number}}"
},
"sort_child_notes": {
"title": "عنوان",
@@ -479,13 +497,15 @@
"sorting_direction": "اتجاه الترتيب",
"natural_sort": "الترتيب الطبيعي",
"natural_sort_language": "لغات الترتيب الطبيعي",
"sort_children_by": "ترتيب العناصر الفرعية حسب..."
"sort_children_by": "ترتيب العناصر الفرعية حسب...",
"sort_folders_at_top": "ترتيب المجلدات في الاعلى"
},
"recent_changes": {
"undelete_link": "الغاء الحذف",
"title": "التغيرات الاخيرة",
"no_changes_message": "لايوجد تغيير لحد الان...",
"erase_notes_button": "مسح الملاحظات المحذوفة الان"
"erase_notes_button": "مسح الملاحظات المحذوفة الان",
"deleted_notes_message": "تم حذف الملاحظات نهائيا."
},
"edited_notes": {
"deleted": "(حذف)",
@@ -655,7 +675,11 @@
"google": "جوجل",
"save_button": "حفظ",
"baidu": "Baidu",
"title": "محرك البحث"
"title": "محرك البحث",
"predefined_templates_label": "قوالب محرك البحث المعرفة مسبقا",
"custom_name_label": "اسم محرك البحث المخصص",
"custom_name_placeholder": "اسم محرك البحث المخصص",
"custom_url_placeholder": "تخصيص عنوان URL لمحرك البحث"
},
"heading_style": {
"plain": "بسيط",
@@ -676,7 +700,8 @@
"wednesday": "الاربعاء",
"thursday": "الخميس",
"friday": "الجمعة",
"saturday": "السبت"
"saturday": "السبت",
"formatting-locale": "تنسيق التاريخ والارقام"
},
"backup": {
"path": "مسار",
@@ -691,7 +716,6 @@
"backup_database_now": "نسخ اختياطي لقاعدة البيانات الان"
},
"etapi": {
"wiki": "ويكي",
"created": "تم الأنشاء",
"actions": "أجراءات",
"title": "ETAPI",
@@ -699,7 +723,10 @@
"token_name": "اسم الرمز",
"default_token_name": "رمز جديد",
"rename_token_title": "اعادة تسمية الرمز",
"rename_token": "اعادة تسمية هذا الرمز"
"rename_token": "اعادة تسمية هذا الرمز",
"create_token": "انشاء رمز PEAPI جديد",
"new_token_title": "رمز ETAPI جديد",
"token_created_title": "انشاء رمز ETAPI"
},
"password": {
"heading": "كلمة المرور",
@@ -731,7 +758,8 @@
"timeout": "انتهاء مهلة المزامنة",
"test_title": "اختبار المزامنة",
"test_button": "اختبار المزامنة",
"server_address": "عنوان نسخة الخادم"
"server_address": "عنوان نسخة الخادم",
"proxy_label": "خادم وكيل المزامنة (اخياري)"
},
"api_log": {
"close": "أغلاق"
@@ -751,7 +779,8 @@
"new_tab": "تبويب جديد",
"close_all_tabs": "اغلاق كل علامات التبويب",
"add_new_tab": "اضافة علامة تبويب جديدة",
"close_other_tabs": "اغلاق علامات التبويب الاخرى"
"close_other_tabs": "اغلاق علامات التبويب الاخرى",
"reopen_last_tab": "اعادة فتح اخر علامة تبويب مغلقة"
},
"toc": {
"options": "خيارات",
@@ -791,7 +820,8 @@
},
"call_to_action": {
"dismiss": "تجاهل",
"background_effects_button": "تفعيل مؤثرات الخلفية"
"background_effects_button": "تفعيل مؤثرات الخلفية",
"next_theme_button": "جرب النسق الجديد"
},
"units": {
"percentage": "%"
@@ -802,7 +832,8 @@
"help_on_links": "مساعدة حول الارتباطات التشعبية",
"notes_to_clone": "ملاحظات للنسخ",
"target_parent_note": "الملاحظة الاصلية الهدف",
"clone_to_selected_note": "استنساخ الى الملاحظة المحددة"
"clone_to_selected_note": "استنساخ الى الملاحظة المحددة",
"no_path_to_clone_to": "لايوجد مسار لنسخ المحتوى الية."
},
"table_of_contents": {
"unit": "عناوين",
@@ -835,7 +866,8 @@
"search-in-subtree": "‍البحث في الشجرة الفرعية",
"edit-branch-prefix": "تعديل بادئة الفرع",
"convert-to-attachment": "التحويل الى مرفق",
"apply-bulk-actions": "‌تطبيق الاجراءات الجماعية"
"apply-bulk-actions": "‌تطبيق الاجراءات الجماعية",
"recent-changes-in-subtree": "التغييرات الاخيرة في الشجرة الفرعية"
},
"note_types": {
"text": "نص",
@@ -884,7 +916,8 @@
"quick-search": {
"searching": "جار البحث...",
"placeholder": "البحث السريع",
"no-results": "لم يتم العثور على نتائج"
"no-results": "لم يتم العثور على نتائج",
"show-in-full-search": "عرض في البحث الكامل"
},
"note_tree": {
"unhoist": "ارجاع الى الترتيب الطبيعي",
@@ -893,7 +926,12 @@
"collapse-title": "طي شجرة الملاحظة",
"hide-archived-notes": "اخفاء الملاحظات المؤرشفة",
"automatically-collapse-notes": "طي الملاحظات تلقائيا",
"create-child-note": "انشاء ملاحظة فرعية"
"create-child-note": "انشاء ملاحظة فرعية",
"scroll-active-title": "تمرير الى الملاحظة النشطة",
"save-changes": "حفظ وتطبيق التغييرات",
"saved-search-note-refreshed": "تم تحديث ملاحظة البحث المحفوظة.",
"hoist-this-note-workspace": "تثبيت هذه الملاحظة (مساحة العمل)",
"refresh-saved-search-results": "تحديث نتائج البحث المحفوظة"
},
"sql_table_schemas": {
"tables": "جداول"
@@ -901,7 +939,13 @@
"launcher_context_menu": {
"reset": "اعادة ضبط",
"add-spacer": "اضافة فاصل",
"delete": "حذف\n<kbd data-command=\"deleteNotes\">"
"delete": "حذف\n<kbd data-command=\"deleteNotes\">",
"add-note-launcher": "اضافة مشغل الملاحظة",
"add-script-launcher": "اضافة مشغل السكريبت",
"add-custom-widget": "اضافة عنصر واجهة مخصص",
"move-to-visible-launchers": "نقل الى المشغلات المرئية",
"move-to-available-launchers": "نقل الى المشغلات المتوفرة",
"duplicate-launcher": "تكرار المشغل <kbd data-command=\"duplicateSubtree\">"
},
"editable-text": {
"auto-detect-language": "تم اكتشافه تلقائيا"
@@ -927,7 +971,9 @@
"cut": "قص",
"copy": "نسخ",
"paste": "لصق",
"copy-link": "نسخ الرابط"
"copy-link": "نسخ الرابط",
"add-term-to-dictionary": "اضافة \"{{term}}\" الى القاموس",
"paste-as-plain-text": "لصق كنص عادي"
},
"promoted_attributes": {
"url_placeholder": "http://website...",
@@ -977,7 +1023,11 @@
"totp_secret_regenerate": "اعادة توليد TOTP السري",
"totp_secret_generated": "تم انشاء TOTP السري",
"oauth_missing_vars": "اعدادات مفقودة: {{-variables}}",
"totp_secret_title": "توليد TOTP سري"
"totp_secret_title": "توليد TOTP سري",
"totp_title": "كلمة مرور لمرة واحدة معتمدة على الوقت (TOTP)",
"recovery_keys_title": "مفاتيح استرداد تسجيل الدخول الاحادي",
"recovery_keys_error": "حدث خطأ اثناء توليد رموز الاسترجاع",
"recovery_keys_no_key_set": "لاتوجد رموز استرجاع معينة"
},
"execute_script": {
"execute_script": "تنفيذ السكريبت"
@@ -1001,7 +1051,8 @@
},
"delete_note": {
"delete_note": "حذف الملاحظة",
"delete_matched_notes": "حف الملاحظات المطابقة"
"delete_matched_notes": "حف الملاحظات المطابقة",
"delete_matched_notes_description": "سوف يؤدي هذا الى حذف الملاحظات المطابقة."
},
"rename_note": {
"rename_note": "اعادة تسمية الملاحظة",
@@ -1119,7 +1170,12 @@
"title": "اخفاء هوية البيانات",
"full_anonymization": "الاخفاء الكامل للهوية",
"light_anonymization": "الاخفاء الجزئي للهوية",
"existing_anonymized_databases": "قواعد البيانات المجهولة الحالية"
"existing_anonymized_databases": "قواعد البيانات المجهولة الحالية",
"save_fully_anonymized_database": "حفظ قاعدة البيانات بعد اخفاء كل الهويات",
"save_lightly_anonymized_database": "حفظ قاعدةةبيانات مخفية جزئيا",
"creating_fully_anonymized_database": "انشاء قاعدة بيانات مجهولة بالكامل",
"creating_lightly_anonymized_database": "انشاء قاعدةة بيانات مجهولة جزئيا...",
"no_anonymized_database_yet": "لاتوجد قاعدة بيانات مجهولة بعد."
},
"vacuum_database": {
"title": "تحرير مساحة قاعدة البيانات",
@@ -1146,7 +1202,8 @@
"italic": "نص مائل",
"underline": "خط تحت النص",
"color": "نص ملون",
"visibility_title": "اظهار قائمة التضليلات"
"visibility_title": "اظهار قائمة التضليلات",
"bg_color": "نص مع لون خلفية"
},
"revisions_button": {
"note_revisions": "مراجعات الملاحظة"
@@ -1163,7 +1220,8 @@
"title": "التدقيق الاملائي",
"enable": "تفعيل التدقيق الاملائي",
"language_code_label": "رمز اللغة او رموز اللغات",
"available_language_codes_label": "رموز اللغات المتاحة:"
"available_language_codes_label": "رموز اللغات المتاحة:",
"language_code_placeholder": "على سبيل المثال \"en-US\", \"de-AI\""
},
"note-map": {
"button-link-map": "خريطة الروابط",
@@ -1177,7 +1235,9 @@
},
"branches": {
"delete-status": "حالة الحذف",
"delete-finished-successfully": "تم الحذف بنجاح."
"delete-finished-successfully": "تم الحذف بنجاح.",
"cannot-move-notes-here": "لايمكن نقل الملاحظات الى هنا.",
"undeleting-notes-finished-successfully": "تم استرجاع الملاحظات بنجاح."
},
"highlighting": {
"title": "كتل الكود",
@@ -1199,14 +1259,16 @@
"native-title-bar": "شريط العنوان الاصلي"
},
"note_tooltip": {
"quick-edit": "التحرير السريع"
"quick-edit": "التحرير السريع",
"note-has-been-deleted": "تم حذف الملاحظة."
},
"geo-map-context": {
"open-location": "فتح الموقع",
"remove-from-map": "ازالة من الخريطة"
},
"share": {
"title": "اعدادات المشاركة"
"title": "اعدادات المشاركة",
"check_share_root": "التحقق من حالة جذر المشاركة"
},
"note_language": {
"not_set": "غير محدد",
@@ -1251,7 +1313,8 @@
"search_subtree_title": "بحث في الشجرة الفرعية",
"search_history_title": "عرص سجل البحث",
"search_history_description": "عرض البحث السابق",
"configure_launch_bar_title": "تكوين شريط الاطلاق"
"configure_launch_bar_title": "تكوين شريط الاطلاق",
"search_subtree_description": "البحث ضمن الشجرة الفرعية الحالية"
},
"content_renderer": {
"open_externally": "فتح خارجيا"
@@ -1272,7 +1335,8 @@
"notes_to_move": "الملاحظات المراد نقلها",
"target_parent_note": "ملاحظة الاصل الهدف",
"dialog_title": "انقل الملاحظات الى...",
"move_button": "نقل الىالملاحظة المحددة"
"move_button": "نقل الىالملاحظة المحددة",
"error_no_path": "لايوجد مسار لنقل العنصر الية."
},
"delete_revisions": {
"delete_note_revisions": "حذف مراجعات الملاحظة"
@@ -1295,7 +1359,8 @@
"database_integrity_check": {
"title": "فحص سلامة قاعدة البيانات",
"check_button": "التحقق من سلامة قاعدة البيانات",
"checking_integrity": "جار التحقق من سلامة قاعدة البيانات..."
"checking_integrity": "جار التحقق من سلامة قاعدة البيانات...",
"integrity_check_failed": "فشل التحقق من السلامة: {{results}}"
},
"watched_file_update_status": {
"upload_modified_file": "رفع الملف المعدل",
@@ -1322,13 +1387,15 @@
"save_attributes": "حفظ السمات <enter>",
"add_a_new_attribute": "اضافة سمة جديدة",
"add_new_label_definition": "اضافة تعريف لتسمية جديدة",
"add_new_relation_definition": "اضافة تعريف لعلاقة جديدة"
"add_new_relation_definition": "اضافة تعريف لعلاقة جديدة",
"add_new_relation": "اضافة علاقة جديدة <kbd data-command=\"addNewRelation\">"
},
"zen_mode": {
"button_exit": "الخروج من وضع Zen"
},
"attachment_erasure_timeout": {
"attachment_erasure_timeout": "مهلة مسح المرفقات"
"attachment_erasure_timeout": "مهلة مسح المرفقات",
"erase_attachments_after": "حذف المرفقات الغير مستخدمة بعد:"
},
"note_erasure_timeout": {
"note_erasure_timeout_title": "مهلة مسح الملاحظة",
@@ -1366,5 +1433,34 @@
},
"revisions_snapshot_interval": {
"note_revisions_snapshot_interval_title": "الفاصل الزمني لنسخ الملاحظات الاحتياطية"
},
"note_detail": {
"printing": "جار الطباعة ..."
},
"attachment_detail_2": {
"role_and_size": "الدور: {{role}}، الحجم: {{size}}",
"unrecognized_role": "دور المرفق '{{role}}'الغير معروف."
},
"title_bar_buttons": {
"window-on-top": "ابقاء النافذة في الاعلى"
},
"note_title": {
"placeholder": "اكتب عنوان الملاحظة هنا..."
},
"image_context_menu": {
"copy_reference_to_clipboard": "نسخ المرجع الى الحافظة",
"copy_image_to_clipboard": "نسخ الصورة الى الحافظة"
},
"geo-map": {
"unable-to-load-map": "تعذر تحميل الخريطة."
},
"content_widget": {
"unknown_widget": "عنصر واجهة غير معروف للمعرف \"{{id}}\"."
},
"png_export_button": {
"button_title": "تصدير المخطط كملف PNG"
},
"protected_session_status": {
"inactive": "انقر للدخول الى جلسة محمية"
}
}

View File

@@ -51,7 +51,7 @@
"bulk_actions_executed": "批量操作已成功执行。",
"none_yet": "暂无操作 ... 通过点击上方的可用操作添加一个操作。",
"labels": "标签",
"relations": "关联关系",
"relations": "关系",
"notes": "笔记",
"other": "其它"
},
@@ -104,7 +104,8 @@
"export_status": "导出状态",
"export_in_progress": "导出进行中:{{progressCount}}",
"export_finished_successfully": "导出成功完成。",
"format_pdf": "PDF - 用于打印或共享目的。"
"format_pdf": "PDF - 用于打印或共享目的。",
"share-format": "HTML 网页发布——采用与共享笔记相同的主题,但可发布为静态网站。"
},
"help": {
"noteNavigation": "笔记导航",
@@ -184,7 +185,8 @@
},
"import-status": "导入状态",
"in-progress": "导入进行中:{{progress}}",
"successful": "导入成功完成。"
"successful": "导入成功完成。",
"importZipRecommendation": "导入 ZIP 文件时,笔记层级将反映压缩文件内的子目录结构。"
},
"include_note": {
"dialog_title": "包含笔记",
@@ -259,7 +261,6 @@
"delete_all_revisions": "删除此笔记的所有修订版本",
"delete_all_button": "删除所有修订版本",
"help_title": "关于笔记修订版本的帮助",
"revision_last_edited": "此修订版本上次编辑于 {{date}}",
"confirm_delete_all": "您是否要删除此笔记的所有修订版本?",
"no_revisions": "此笔记暂无修订版本...",
"restore_button": "恢复",
@@ -1288,10 +1289,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI 是一个 REST API用于以编程方式访问 Trilium 实例,而无需 UI。",
"see_more": "有关更多详细信息,请参见 {{- link_to_wiki}} 和 {{- link_to_openapi_spec}} 或 {{- link_to_swagger_ui}}。",
"wiki": "维基",
"openapi_spec": "ETAPI OpenAPI 规范",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "创建新的 ETAPI 令牌",
"existing_tokens": "现有令牌",
"no_tokens_yet": "目前还没有令牌。点击上面的按钮创建一个。",
@@ -1558,7 +1555,9 @@
"window-on-top": "保持此窗口置顶"
},
"note_detail": {
"could_not_find_typewidget": "找不到类型为 '{{type}}' 的 typeWidget"
"could_not_find_typewidget": "找不到类型为 '{{type}}' 的 typeWidget",
"printing": "正在打印…",
"printing_pdf": "正在导出为PDF…"
},
"note_title": {
"placeholder": "请输入笔记标题..."

View File

@@ -4,7 +4,7 @@
"homepage": "Startseite:",
"app_version": "App-Version:",
"db_version": "DB-Version:",
"sync_version": "Synch-version:",
"sync_version": "Sync-Version:",
"build_date": "Build-Datum:",
"build_revision": "Build-Revision:",
"data_directory": "Datenverzeichnis:"
@@ -104,7 +104,8 @@
"export_status": "Exportstatus",
"export_in_progress": "Export läuft: {{progressCount}}",
"export_finished_successfully": "Der Export wurde erfolgreich abgeschlossen.",
"format_pdf": "PDF - für Ausdrucke oder Teilen."
"format_pdf": "PDF - für Ausdrucke oder Teilen.",
"share-format": "HTML für die Web-Veröffentlichung verwendet dasselbe Theme wie bei freigegebenen Notizen, kann jedoch als statische Website veröffentlicht werden."
},
"help": {
"noteNavigation": "Notiz Navigation",
@@ -184,7 +185,8 @@
},
"import-status": "Importstatus",
"in-progress": "Import läuft: {{progress}}",
"successful": "Import erfolgreich abgeschlossen."
"successful": "Import erfolgreich abgeschlossen.",
"importZipRecommendation": "Beim Import einer ZIP-Datei wird die Notizhierarchie aus der Ordnerstruktur im Archiv übernommen."
},
"include_note": {
"dialog_title": "Notiz beifügen",
@@ -259,7 +261,6 @@
"delete_all_revisions": "Lösche alle Revisionen dieser Notiz",
"delete_all_button": "Alle Revisionen löschen",
"help_title": "Hilfe zu Notizrevisionen",
"revision_last_edited": "Diese Revision wurde zuletzt am {{date}} bearbeitet",
"confirm_delete_all": "Möchtest du alle Revisionen dieser Notiz löschen?",
"no_revisions": "Für diese Notiz gibt es noch keine Revisionen...",
"confirm_restore": "Möchtest du diese Revision wiederherstellen? Dadurch werden der aktuelle Titel und Inhalt der Notiz mit dieser Revision überschrieben.",
@@ -647,7 +648,8 @@
"logout": "Abmelden",
"show-cheatsheet": "Cheatsheet anzeigen",
"toggle-zen-mode": "Zen Modus",
"new-version-available": "Neues Update verfügbar"
"new-version-available": "Neues Update verfügbar",
"download-update": "Version {{latestVersion}} herunterladen"
},
"sync_status": {
"unknown": "<p>Der Synchronisations-Status wird bekannt, sobald der nächste Synchronisierungsversuch gestartet wird.</p><p>Klicke, um eine Synchronisierung jetzt auszulösen.</p>",
@@ -989,7 +991,7 @@
"enter_password_instruction": "Um die geschützte Notiz anzuzeigen, musst du dein Passwort eingeben:",
"start_session_button": "Starte eine geschützte Sitzung <kbd>Eingabetaste</kbd>",
"started": "Geschützte Sitzung gestartet.",
"wrong_password": "Passwort flasch.",
"wrong_password": "Passwort falsch.",
"protecting-finished-successfully": "Geschützt erfolgreich beendet.",
"unprotecting-finished-successfully": "Ungeschützt erfolgreich beendet.",
"protecting-in-progress": "Schützen läuft: {{count}}",
@@ -1284,10 +1286,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI ist eine REST-API, die für den programmgesteuerten Zugriff auf die Trilium-Instanz ohne Benutzeroberfläche verwendet wird.",
"see_more": "Weitere Details können im {{- link_to_wiki}} und in der {{- link_to_openapi_spec}} oder der {{- link_to_swagger_ui }} gefunden werden.",
"wiki": "Wiki",
"openapi_spec": "ETAPI OpenAPI-Spezifikation",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "Erstelle ein neues ETAPI-Token",
"existing_tokens": "Vorhandene Token",
"no_tokens_yet": "Es sind noch keine Token vorhanden. Klicke auf die Schaltfläche oben, um eine zu erstellen.",
@@ -1521,7 +1519,9 @@
"window-on-top": "Dieses Fenster immer oben halten"
},
"note_detail": {
"could_not_find_typewidget": "Konnte typeWidget für Typ {{type}} nicht finden"
"could_not_find_typewidget": "Konnte typeWidget für Typ {{type}} nicht finden",
"printing": "Druckvorgang läuft…",
"printing_pdf": "PDF-Export läuft…"
},
"note_title": {
"placeholder": "Titel der Notiz hier eingeben…"
@@ -1654,7 +1654,7 @@
"add-term-to-dictionary": "Begriff \"{{term}}\" zum Wörterbuch hinzufügen",
"cut": "Ausschneiden",
"copy": "Kopieren",
"copy-link": "Link opieren",
"copy-link": "Link kopieren",
"paste": "Einfügen",
"paste-as-plain-text": "Als unformatierten Text einfügen",
"search_online": "Suche nach \"{{term}}\" mit {{searchEngine}} starten"
@@ -2079,6 +2079,7 @@
},
"presentation_view": {
"edit-slide": "Folie bearbeiten",
"start-presentation": "Präsentation starten"
"start-presentation": "Präsentation starten",
"slide-overview": "Übersicht der Folien ein-/ausblenden"
}
}

View File

@@ -104,7 +104,8 @@
"export_status": "Export status",
"export_in_progress": "Export in progress: {{progressCount}}",
"export_finished_successfully": "Export finished successfully.",
"format_pdf": "PDF - for printing or sharing purposes."
"format_pdf": "PDF - for printing or sharing purposes.",
"share-format": "HTML for web publishing - uses the same theme that is used shared notes, but can be published as a static website."
},
"help": {
"title": "Cheatsheet",
@@ -260,7 +261,6 @@
"delete_all_revisions": "Delete all revisions of this note",
"delete_all_button": "Delete all revisions",
"help_title": "Help on Note Revisions",
"revision_last_edited": "This revision was last edited on {{date}}",
"confirm_delete_all": "Do you want to delete all revisions of this note?",
"no_revisions": "No revisions for this note yet...",
"restore_button": "Restore",
@@ -1453,10 +1453,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI is a REST API used to access Trilium instance programmatically, without UI.",
"see_more": "See more details in the {{- link_to_wiki}} and the {{- link_to_openapi_spec}} or the {{- link_to_swagger_ui }}.",
"wiki": "wiki",
"openapi_spec": "ETAPI OpenAPI spec",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "Create new ETAPI token",
"existing_tokens": "Existing tokens",
"no_tokens_yet": "There are no tokens yet. Click on the button above to create one.",

View File

@@ -104,7 +104,8 @@
"export_status": "Estado de exportación",
"export_in_progress": "Exportación en curso: {{progressCount}}",
"export_finished_successfully": "La exportación finalizó exitosamente.",
"format_pdf": "PDF - para propósitos de impresión o compartición."
"format_pdf": "PDF - para propósitos de impresión o compartición.",
"share-format": "HTML para publicación web: utiliza el mismo tema que se utiliza en las notas compartidas, pero se puede publicar como un sitio web estático."
},
"help": {
"noteNavigation": "Navegación de notas",
@@ -184,7 +185,8 @@
},
"import-status": "Estado de importación",
"in-progress": "Importación en progreso: {{progress}}",
"successful": "Importación finalizada exitosamente."
"successful": "Importación finalizada exitosamente.",
"importZipRecommendation": "Al importar un archivo ZIP, la jerarquía de notas reflejará la estructura de subdirectorios dentro del archivo comprimido."
},
"include_note": {
"dialog_title": "Incluir nota",
@@ -259,7 +261,6 @@
"delete_all_revisions": "Eliminar todas las revisiones de esta nota",
"delete_all_button": "Eliminar todas las revisiones",
"help_title": "Ayuda sobre revisiones de notas",
"revision_last_edited": "Esta revisión se editó por última vez en {{date}}",
"confirm_delete_all": "¿Quiere eliminar todas las revisiones de esta nota?",
"no_revisions": "Aún no hay revisiones para esta nota...",
"restore_button": "Restaurar",
@@ -1445,10 +1446,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI es una REST API que se utiliza para acceder a la instancia de Trilium mediante programación, sin interfaz de usuario.",
"see_more": "Véa más detalles en el {{- link_to_wiki}} y el {{- link_to_openapi_spec}} o el {{- link_to_swagger_ui }}.",
"wiki": "wiki",
"openapi_spec": "Especificación ETAPI OpenAPI",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "Crear nuevo token ETAPI",
"existing_tokens": "Tokens existentes",
"no_tokens_yet": "Aún no hay tokens. Dé clic en el botón de arriba para crear uno.",
@@ -1715,7 +1712,9 @@
"window-on-top": "Mantener esta ventana en la parte superior"
},
"note_detail": {
"could_not_find_typewidget": "No se pudo encontrar typeWidget para el tipo '{{type}}'"
"could_not_find_typewidget": "No se pudo encontrar typeWidget para el tipo '{{type}}'",
"printing": "Impresión en curso...",
"printing_pdf": "Exportando a PDF en curso.."
},
"note_title": {
"placeholder": "escriba el título de la nota aquí..."

View File

@@ -260,7 +260,6 @@
"delete_all_revisions": "Supprimer toutes les versions de cette note",
"delete_all_button": "Supprimer toutes les versions",
"help_title": "Aide sur les versions de notes",
"revision_last_edited": "Cette version a été modifiée pour la dernière fois le {{date}}",
"confirm_delete_all": "Voulez-vous supprimer toutes les versions de cette note ?",
"no_revisions": "Aucune version pour cette note pour l'instant...",
"confirm_restore": "Voulez-vous restaurer cette version ? Le titre et le contenu actuels de la note seront écrasés par cette version.",
@@ -280,8 +279,8 @@
"delete_button": "Supprimer",
"diff_on": "Afficher les différences",
"diff_off": "Afficher le contenu",
"diff_on_hint": "Cliquez pour afficher les différences de la note d'origine",
"diff_off_hint": "Cliquez pour afficher le contenu de la note",
"diff_on_hint": "Cliquer pour afficher les différences avec la note d'origine",
"diff_off_hint": "Cliquer pour afficher le contenu de la note",
"diff_not_available": "La comparaison n'est pas disponible."
},
"sort_child_notes": {
@@ -647,7 +646,9 @@
"about": "À propos de Trilium Notes",
"logout": "Déconnexion",
"show-cheatsheet": "Afficher l'aide rapide",
"toggle-zen-mode": "Zen Mode"
"toggle-zen-mode": "Zen Mode",
"new-version-available": "Nouvelle mise à jour disponible",
"download-update": "Obtenir la version {{latestVersion}}"
},
"zen_mode": {
"button_exit": "Sortir du Zen mode"
@@ -674,7 +675,7 @@
"search_in_note": "Rechercher dans la note",
"note_source": "Code source",
"note_attachments": "Pièces jointes",
"open_note_externally": "Ouverture externe",
"open_note_externally": "Ouvrir la note en externe",
"open_note_externally_title": "Le fichier sera ouvert dans une application externe et les modifications apportées seront surveillées. Vous pourrez ensuite téléverser la version modifiée dans Trilium.",
"open_note_custom": "Ouvrir la note avec",
"import_files": "Importer des fichiers",
@@ -767,7 +768,8 @@
"table": "Tableau",
"geo-map": "Carte géographique",
"board": "Tableau de bord",
"include_archived_notes": "Afficher les notes archivées"
"include_archived_notes": "Afficher les notes archivées",
"presentation": "Présentation"
},
"edited_notes": {
"no_edited_notes_found": "Aucune note modifiée ce jour-là...",
@@ -1142,7 +1144,8 @@
"code_auto_read_only_size": {
"title": "Taille pour la lecture seule automatique",
"description": "La taille pour la lecture seule automatique est le seuil au-delà de laquelle les notes seront affichées en mode lecture seule (pour optimiser les performances).",
"label": "Taille pour la lecture seule automatique (notes de code)"
"label": "Taille pour la lecture seule automatique (notes de code)",
"unit": "caractères"
},
"code_mime_types": {
"title": "Types MIME disponibles dans la liste déroulante"
@@ -1285,8 +1288,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI est une API REST utilisée pour accéder à l'instance Trilium par programme, sans interface utilisateur.",
"wiki": "wiki",
"openapi_spec": "Spec ETAPI OpenAPI",
"create_token": "Créer un nouveau jeton ETAPI",
"existing_tokens": "Jetons existants",
"no_tokens_yet": "Il n'y a pas encore de jetons. Cliquez sur le bouton ci-dessus pour en créer un.",
@@ -1303,9 +1304,7 @@
"delete_token": "Supprimer/désactiver ce token",
"rename_token_title": "Renommer le jeton",
"rename_token_message": "Veuillez saisir le nom du nouveau jeton",
"delete_token_confirmation": "Êtes-vous sûr de vouloir supprimer le jeton ETAPI « {{name}} » ?",
"see_more": "Voir plus de détails dans le {{- link_to_wiki}} et le {{- link_to_openapi_spec}} ou le {{- link_to_swagger_ui }}.",
"swagger_ui": "Interface utilisateur ETAPI Swagger"
"delete_token_confirmation": "Êtes-vous sûr de vouloir supprimer le jeton ETAPI « {{name}} » ?"
},
"options_widget": {
"options_status": "Statut des options",
@@ -1435,8 +1434,8 @@
"open-in-popup": "Modification rapide"
},
"shared_info": {
"shared_publicly": "Cette note est partagée publiquement sur {{- link}}",
"shared_locally": "Cette note est partagée localement sur {{- link}}",
"shared_publicly": "Cette note est partagée publiquement sur {{- link}}.",
"shared_locally": "Cette note est partagée localement sur {{- link}}.",
"help_link": "Pour obtenir de l'aide, visitez le <a href=\"https://triliumnext.github.io/Docs/Wiki/sharing.html\">wiki</a>."
},
"note_types": {
@@ -1460,7 +1459,9 @@
"beta-feature": "Beta",
"task-list": "Liste de tâches",
"book": "Collection",
"ai-chat": "Chat IA"
"ai-chat": "Chat IA",
"new-feature": "Nouveau",
"collections": "Collections"
},
"protect_note": {
"toggle-on": "Protéger la note",
@@ -1513,13 +1514,16 @@
"hoist-this-note-workspace": "Focus cette note (espace de travail)",
"refresh-saved-search-results": "Rafraîchir les résultats de recherche enregistrée",
"create-child-note": "Créer une note enfant",
"unhoist": "Désactiver le focus"
"unhoist": "Désactiver le focus",
"toggle-sidebar": "Basculer la barre latérale"
},
"title_bar_buttons": {
"window-on-top": "Épingler cette fenêtre au premier plan"
},
"note_detail": {
"could_not_find_typewidget": "Impossible de trouver typeWidget pour le type '{{type}}'"
"could_not_find_typewidget": "Impossible de trouver typeWidget pour le type '{{type}}'",
"printing": "Impression en cours...",
"printing_pdf": "Export au format PDF en cours..."
},
"note_title": {
"placeholder": "saisir le titre de la note ici..."
@@ -1570,7 +1574,9 @@
},
"clipboard": {
"cut": "Les note(s) ont été coupées dans le presse-papiers.",
"copied": "Les note(s) ont été coupées dans le presse-papiers."
"copied": "Les note(s) ont été coupées dans le presse-papiers.",
"copy_failed": "Impossible de copier dans le presse-papiers en raison de problèmes d'autorisation.",
"copy_success": "Copié dans le presse-papiers."
},
"entrypoints": {
"note-revision-created": "La version de la note a été créée.",
@@ -1592,7 +1598,9 @@
"ws": {
"sync-check-failed": "Le test de synchronisation a échoué !",
"consistency-checks-failed": "Les tests de cohérence ont échoué ! Consultez les journaux pour plus de détails.",
"encountered-error": "Erreur \"{{message}}\", consultez la console."
"encountered-error": "Erreur \"{{message}}\", consultez la console.",
"lost-websocket-connection-title": "Connexion au serveur perdue",
"lost-websocket-connection-message": "Vérifiez la configuration de votre proxy inverse (par exemple nginx ou Apache) pour vous assurer que les connexions WebSocket sont correctement autorisées et ne sont pas bloquées."
},
"hoisted_note": {
"confirm_unhoisting": "La note demandée «{{requestedNote}}» est en dehors du sous-arbre de la note focus «{{hoistedNote}}». Le focus doit être désactivé pour accéder à la note. Voulez-vous enlever le focus ?"
@@ -1614,13 +1622,15 @@
},
"highlighting": {
"description": "Contrôle la coloration syntaxique des blocs de code à l'intérieur des notes texte, les notes de code ne seront pas affectées.",
"color-scheme": "Jeu de couleurs"
"color-scheme": "Jeu de couleurs",
"title": "Blocs de code"
},
"code_block": {
"word_wrapping": "Saut à la ligne automatique suivant la largeur",
"theme_none": "Pas de coloration syntaxique",
"theme_group_light": "Thèmes clairs",
"theme_group_dark": "Thèmes sombres"
"theme_group_dark": "Thèmes sombres",
"copy_title": "Copier dans le presse-papiers"
},
"classic_editor_toolbar": {
"title": "Mise en forme"
@@ -1679,7 +1689,8 @@
"full-text-search": "Recherche dans le texte"
},
"note_tooltip": {
"note-has-been-deleted": "La note a été supprimée."
"note-has-been-deleted": "La note a été supprimée.",
"quick-edit": "Edition rapide"
},
"geo-map": {
"create-child-note-title": "Créer une nouvelle note enfant et l'ajouter à la carte",
@@ -1688,7 +1699,8 @@
},
"geo-map-context": {
"open-location": "Ouvrir la position",
"remove-from-map": "Retirer de la carte"
"remove-from-map": "Retirer de la carte",
"add-note": "Ajouter un marqueur à cet endroit"
},
"help-button": {
"title": "Ouvrir la page d'aide correspondante"
@@ -1748,7 +1760,8 @@
"oauth_user_not_logged_in": "Pas connecté!"
},
"modal": {
"close": "Fermer"
"close": "Fermer",
"help_title": "Afficher plus d'informations sur cet écran"
},
"ai_llm": {
"not_started": "Non démarré",
@@ -1828,13 +1841,76 @@
"reprocessing_index": "Mise à jour...",
"reprocess_index_started": "L'optimisation de l'indice de recherche à commencer en arrière-plan",
"reprocess_index_error": "Erreur dans le rafraichissement de l'indice de recherche",
"failed_notes": "Notes échouées",
"failed_notes": "Notes en erreur",
"last_processed": "Dernier traitement",
"restore_provider": "Restaurer le fournisseur de la recherche",
"restore_provider": "Restaurer le fournisseur de recherche",
"index_rebuild_progress": "Progression de la reconstruction de l'index",
"index_rebuilding": "Optimisation de l'index ({{percentage}}%)",
"index_rebuild_complete": "Optimisation de l'index terminée",
"index_rebuild_status_error": "Erreur lors de la vérification de l'état de reconstruction de l'index"
"index_rebuild_status_error": "Erreur lors de la vérification de l'état de reconstruction de l'index",
"provider_precedence": "Priorité du fournisseur",
"never": "Jamais",
"processing": "Traitement en cours ({{percentage}}%)",
"incomplete": "Incomplet ({{percentage}}%)",
"complete": "Terminé (100%)",
"refreshing": "Mise à jour...",
"auto_refresh_notice": "Actualisation automatique toutes les {{seconds}} secondes",
"note_queued_for_retry": "Note mise en file d'attente pour une nouvelle tentative",
"failed_to_retry_note": "Échec de la nouvelle tentative de note",
"all_notes_queued_for_retry": "Toutes les notes ayant échoué sont mises en file d'attente pour une nouvelle tentative",
"failed_to_retry_all": "Échec du ré essai des notes",
"ai_settings": "Paramètres IA",
"api_key_tooltip": "Clé API pour accéder au service",
"empty_key_warning": {
"anthropic": "La clé API Anthropic est vide. Veuillez saisir une clé API valide.",
"openai": "La clé API OpenAI est vide. Veuillez saisir une clé API valide.",
"voyage": "La clé API Voyage est vide. Veuillez saisir une clé API valide.",
"ollama": "La clé API Ollama est vide. Veuillez saisir une clé API valide."
},
"agent": {
"processing": "Traitement...",
"thinking": "Réflexion...",
"loading": "Chargement...",
"generating": "Génération..."
},
"name": "IA",
"openai": "OpenAI",
"use_enhanced_context": "Utiliser un contexte amélioré",
"enhanced_context_description": "Fournit à l'IA plus de contexte à partir de la note et de ses notes associées pour de meilleures réponses",
"show_thinking": "Montrer la réflexion",
"show_thinking_description": "Montrer la chaîne de pensée de l'IA",
"enter_message": "Entrez votre message...",
"error_contacting_provider": "Erreur lors de la connexion au fournisseur d'IA. Veuillez vérifier vos paramètres et votre connexion Internet.",
"error_generating_response": "Erreur lors de la génération de la réponse de l'IA",
"index_all_notes": "Indexer toutes les notes",
"index_status": "Statut de l'index",
"indexed_notes": "Notes indexées",
"indexing_stopped": "Arrêt de l'indexation",
"indexing_in_progress": "Indexation en cours...",
"last_indexed": "Dernière indexée",
"note_chat": "Note discussion",
"sources": "Sources",
"start_indexing": "Démarrage de l'indexation",
"use_advanced_context": "Utiliser le contexte avancé",
"ollama_no_url": "Ollama n'est pas configuré. Veuillez saisir une URL valide.",
"chat": {
"root_note_title": "Discussions IA",
"root_note_content": "Cette note contient vos conversations de chat IA enregistrées.",
"new_chat_title": "Nouvelle discussion",
"create_new_ai_chat": "Créer une nouvelle discussion IA"
},
"create_new_ai_chat": "Créer une nouvelle discussion IA",
"configuration_warnings": "Il y a quelques problèmes avec la configuration de votre IA. Veuillez vérifier vos paramètres.",
"experimental_warning": "La fonctionnalité LLM est actuellement expérimentale vous êtes prévenu.",
"selected_provider": "Fournisseur sélectionné",
"selected_provider_description": "Choisissez le fournisseur dIA pour les fonctionnalités de discussion et de complétion",
"select_model": "Sélectionner le modèle...",
"select_provider": "Sélectionnez un fournisseur...",
"ai_enabled": "Fonctionnalités d'IA activées",
"ai_disabled": "Fonctionnalités d'IA désactivées",
"no_models_found_online": "Aucun modèle trouvé. Veuillez vérifier votre clé API et vos paramètres.",
"no_models_found_ollama": "Aucun modèle Ollama trouvé. Veuillez vérifier si Ollama est en cours d'exécution.",
"error_fetching": "Erreur lors de la récupération des modèles : {{error}}"
},
"ui-performance": {
"title": "Performance",
@@ -1846,8 +1922,165 @@
},
"custom_date_time_format": {
"title": "Format de date/heure personnalisé",
"description": "Personnalisez le format de la date et de l'heure insérées via <shortcut /> ou la barre d'outils. Consultez la <doc>documentation Day.js</doc> pour connaître les formats disponibles.",
"description": "Personnalisez le format de la date et de l'heure insérées via <shortcut /> ou la barre d'outils. Consultez la <doc>Day.js docs</doc> pour connaître les formats disponibles.",
"format_string": "Chaîne de format :",
"formatted_time": "Date/heure formatée :"
},
"table_view": {
"delete_column_confirmation": "Êtes-vous sûr de vouloir supprimer cette colonne ? L'attribut correspondant sera supprimé de toutes les notes.",
"delete-column": "Supprimer la colonne",
"new-column-label": "Étiquette",
"new-column-relation": "Relation",
"edit-column": "Editer la colonne",
"add-column-to-the-right": "Ajouter une colonne à droite",
"new-row": "Nouvelle ligne",
"new-column": "Nouvelle colonne",
"sort-column-by": "Trier par « {{title}} »",
"sort-column-ascending": "Ascendant",
"sort-column-descending": "Descendant",
"sort-column-clear": "Annuler le tri",
"hide-column": "Masquer la colonne \"{{title}}\"",
"show-hide-columns": "Afficher/masquer les colonnes",
"row-insert-above": "Insérer une ligne au-dessus",
"row-insert-below": "Insérer une ligne au-dessous",
"row-insert-child": "Insérer une note enfant",
"add-column-to-the-left": "Ajouter une colonne à gauche"
},
"book_properties_config": {
"hide-weekends": "Masquer les week-ends",
"display-week-numbers": "Afficher les numéros de semaine",
"map-style": "Style de carte :",
"max-nesting-depth": "Profondeur d'imbrication maximale :",
"raster": "Trame",
"vector_light": "Vecteur (clair)",
"vector_dark": "Vecteur (foncé)",
"show-scale": "Afficher l'échelle"
},
"table_context_menu": {
"delete_row": "Supprimer la ligne"
},
"board_view": {
"delete-note": "Supprimer la note...",
"remove-from-board": "Retirer du tableau",
"archive-note": "Note archivée",
"unarchive-note": "Note désarchivée",
"move-to": "Déplacer vers",
"insert-above": "Insérer au-dessus",
"insert-below": "Insérer au-dessous",
"delete-column": "Supprimer la colonne",
"delete-column-confirmation": "Êtes-vous sûr de vouloir supprimer cette colonne? L'attribut correspondant sera également supprimé dans les notes sous cette colonne.",
"new-item": "Nouvel article",
"new-item-placeholder": "Entrez le titre de note...",
"add-column": "Ajouter une colonne",
"add-column-placeholder": "Entrez le nom de la colonne...",
"edit-note-title": "Cliquez pour modifier le titre de la note",
"edit-column-title": "Cliquez pour modifier le titre de la colonne"
},
"presentation_view": {
"edit-slide": "Modifier cette diapositive",
"start-presentation": "Démarrer la présentation",
"slide-overview": "Afficher un aperçu des diapositives"
},
"command_palette": {
"tree-action-name": "Arborescence : {{name}}",
"export_note_title": "Exporter la note",
"export_note_description": "Exporter la note actuelle",
"show_attachments_title": "Afficher les pièces jointes",
"show_attachments_description": "Afficher les pièces jointes des notes",
"search_notes_title": "Rechercher des notes",
"search_notes_description": "Ouvrir la recherche avancée",
"search_subtree_title": "Rechercher dans la sous-arborescence",
"search_subtree_description": "Rechercher dans la sous-arborescence actuelle",
"search_history_title": "Afficher l'historique de recherche",
"search_history_description": "Afficher les recherches précédentes",
"configure_launch_bar_title": "Configurer la barre de lancement",
"configure_launch_bar_description": "Ouvrir la configuration de la barre de lancement pour ajouter ou supprimer des éléments."
},
"content_renderer": {
"open_externally": "Ouverture externe"
},
"call_to_action": {
"next_theme_title": "Essayez le nouveau thème Trilium",
"next_theme_message": "Vous utilisez actuellement le thème hérité de l'ancienne version, souhaitez-vous essayer le nouveau thème?",
"next_theme_button": "Essayez le nouveau thème",
"background_effects_title": "Les effets d'arrière-plan sont désormais stables",
"background_effects_message": "Sur les appareils Windows, les effets d'arrière-plan sont désormais parfaitement stables. Ils ajoutent une touche de couleur à l'interface utilisateur en floutant l'arrière-plan. Cette technique est également utilisée dans d'autres applications comme l'Explorateur Windows.",
"background_effects_button": "Activer les effets d'arrière-plan",
"dismiss": "Rejeter"
},
"settings": {
"related_settings": "Paramètres associés"
},
"settings_appearance": {
"related_code_blocks": "Schéma de coloration syntaxique pour les blocs de code dans les notes de texte",
"related_code_notes": "Schéma de couleurs pour les notes de code"
},
"units": {
"percentage": "%"
},
"pagination": {
"page_title": "Page de {{startIndex}} - {{endIndex}}",
"total_notes": "{{count}} notes"
},
"collections": {
"rendering_error": "Impossible d'afficher le contenu en raison d'une erreur."
},
"code-editor-options": {
"title": "Éditeur"
},
"tasks": {
"due": {
"today": "Aujourd'hui",
"tomorrow": "Demain",
"yesterday": "Hier"
}
},
"content_widget": {
"unknown_widget": "Widget inconnu pour « {{id}} »."
},
"note_language": {
"not_set": "Non défini",
"configure-languages": "Configurer les langues..."
},
"content_language": {
"title": "Contenu des langues",
"description": "Sélectionnez une ou plusieurs langues à afficher dans la section « Propriétés de base » d'une note textuelle en lecture seule ou modifiable. Cela permettra d'utiliser des fonctionnalités telles que la vérification orthographique ou la prise en charge de l'écriture de droite à gauche."
},
"switch_layout_button": {
"title_vertical": "Déplacer le volet d'édition vers le bas",
"title_horizontal": "Déplacer le panneau d'édition vers la gauche"
},
"toggle_read_only_button": {
"unlock-editing": "Déverrouiller l'édition",
"lock-editing": "Verrouiller l'édition"
},
"png_export_button": {
"button_title": "Exporter le diagramme au format PNG"
},
"svg": {
"export_to_png": "Le diagramme n'a pas pu être exporté au format PNG."
},
"code_theme": {
"title": "Apparence",
"word_wrapping": "retour à la ligne automatique",
"color-scheme": "Jeu de couleurs"
},
"cpu_arch_warning": {
"title": "Veuillez télécharger la version ARM64",
"message_macos": "TriliumNext fonctionne actuellement sous Rosetta 2, ce qui signifie que vous utilisez la version Intel (x64) sur un Mac Apple Silicon. Cela aura un impact significatif sur les performances et l'autonomie de la batterie.",
"message_windows": "TriliumNext fonctionne actuellement en mode émulation, ce qui signifie que vous utilisez la version Intel (x64) sur un appareil Windows sur ARM. Cela aura un impact significatif sur les performances et l'autonomie de la batterie.",
"recommendation": "Pour une expérience optimale, veuillez télécharger la version ARM64 native de TriliumNext depuis notre page de versions.",
"download_link": "Télécharger la version native",
"continue_anyway": "Continuer quand même",
"dont_show_again": "Ne plus afficher cet avertissement"
},
"editorfeatures": {
"title": "Caractéristiques",
"emoji_completion_enabled": "Activer la saisie semi-automatique des emojis",
"emoji_completion_description": "Si cette option est activée, les emojis peuvent être facilement insérés dans le texte en tapant `:` , suivi du nom d'un emoji.",
"note_completion_enabled": "Activer la saisie semi-automatique des notes",
"note_completion_description": "Si cette option est activée, des liens vers des notes peuvent être créés en tapant `@` suivi du titre d'une note.",
"slash_commands_enabled": "Activer les commandes slash",
"slash_commands_description": "Si cette option est activée, les commandes d'édition telles que l'insertion de sauts de ligne ou d'en-têtes peuvent être activées en tapant `/`."
}
}

View File

@@ -0,0 +1,5 @@
{
"about": {
"title": "ट्रिलियम नोट्स के बारें में"
}
}

View File

@@ -1 +1,50 @@
{}
{
"about": {
"title": "A Trilium Notes-ról",
"homepage": "Kezdőlap:",
"app_version": "Alkalmazás verziója:",
"db_version": "Adatbázis verzió:",
"sync_version": "Verzió szinkronizálás :",
"build_revision": "Build revízió:",
"data_directory": "Adatkönyvtár:",
"build_date": "Build dátum:"
},
"toast": {
"critical-error": {
"title": "Kritikus hiba",
"message": "Kritikus hiba történt, amely megakadályozza a kliensalkalmazás indítását:\n\n{{message}}\n\nEzt valószínűleg egy váratlan szkripthiba okozza. Próbálja meg biztonságos módban elindítani az alkalmazást, és hárítsa el a problémát."
},
"widget-error": {
"title": "Nem sikerült inicializálni egy widgetet",
"message-custom": "A(z) \"{{id}}\" azonosítójú, \"{{title}}\" című jegyzetből származó egyéni widget inicializálása sikertelen volt a következő ok miatt:\n\n{{message}}",
"message-unknown": "Ismeretlen widget inicializálása sikertelen volt a következő ok miatt:\n\n{{message}}"
},
"bundle-error": {
"title": "Nem sikerült betölteni az egyéni szkriptet",
"message": "A(z) \"{{id}}\" azonosítójú, \"{{title}}\" című jegyzetből származó szkript nem hajtható végre a következő ok miatt:\n\n{{message}}"
}
},
"add_link": {
"add_link": "Link hozzáadása",
"help_on_links": "Segítség a linkekhez",
"note": "Jegyzet",
"search_note": "név szerinti jegyzetkeresés",
"link_title_mirrors": "A link cím tükrözi a jegyzet aktuális címét",
"link_title_arbitrary": "link cím önkényesen módosítható",
"link_title": "Link cím",
"button_add_link": "Link hozzáadása"
},
"branch_prefix": {
"edit_branch_prefix": "Az elágazás előtagjának szerkesztése",
"help_on_tree_prefix": "Segítség a fa előtagján",
"prefix": "Az előtag: ",
"save": "Mentés"
},
"bulk_actions": {
"bulk_actions": "Tömeges akciók",
"affected_notes": "Érintett jegyzetek",
"labels": "Címkék",
"relations": "Kapcsolatok",
"notes": "Jegyzetek"
}
}

View File

@@ -132,10 +132,6 @@
"new_token_message": "Inserisci il nome del nuovo token",
"title": "ETAPI",
"description": "ETAPI è un'API REST utilizzata per accedere alle istanze di Trilium in modo programmatico, senza interfaccia utente.",
"see_more": "Per maggiori dettagli consulta {{- link_to_wiki}} e {{- link_to_openapi_spec}} o {{- link_to_swagger_ui}}.",
"wiki": "wiki",
"openapi_spec": "Specifiche ETAPI OpenAPI",
"swagger_ui": "Interfaccia utente ETAPI Swagger",
"create_token": "Crea un nuovo token ETAPI",
"existing_tokens": "Token esistenti",
"no_tokens_yet": "Non ci sono ancora token. Clicca sul pulsante qui sopra per crearne uno.",
@@ -221,7 +217,7 @@
"emoji_completion_description": "Se abilitata, è possibile inserire facilmente gli emoji nel testo digitando `:`, seguito dal nome dell'emoji.",
"note_completion_description": "Se abilitato, è possibile creare collegamenti alle note digitando `@` seguito dal titolo di una nota.",
"slash_commands_enabled": "Abilita i comandi slash",
"slash_commands_description": "Se abilitato, i comandi di modifica come l'inserimento di interruzioni di riga o intestazioni possono essere attivati digitando `/`."
"slash_commands_description": "Se abilitato, i comandi di modifica come l'inserimento di interruzioni di riga o intestazioni possono essere attivati digitando `/`."
},
"table_view": {
"new-row": "Nuova riga",
@@ -381,8 +377,8 @@
},
"attachment_detail": {
"open_help_page": "Apri la pagina di aiuto sugli allegati",
"owning_note": "Nota di proprietà:",
"you_can_also_open": ", puoi anche aprire il",
"owning_note": "Nota di proprietà: ",
"you_can_also_open": ", puoi anche aprire il ",
"list_of_all_attachments": "Elenco di tutti gli allegati",
"attachment_deleted": "Questo allegato è stato eliminato."
},
@@ -703,7 +699,7 @@
"last_attempt": "Ultimo tentativo",
"actions": "Azioni",
"retry": "Riprova",
"partial": "{{ percentuale }}% completato",
"partial": "{{ percentage }}% completato",
"retry_queued": "Nota in coda per un nuovo tentativo",
"retry_failed": "Impossibile mettere in coda la nota per un nuovo tentativo",
"max_notes_per_llm_query": "Numero massimo di note per query",
@@ -719,12 +715,12 @@
"reprocess_index_started": "Ottimizzazione dell'indice di ricerca avviata in background",
"reprocess_index_error": "Errore durante la ricostruzione dell'indice di ricerca",
"index_rebuild_progress": "Progresso nella ricostruzione dell'indice",
"index_rebuilding": "Indice di ottimizzazione ({{percentuale}}%)",
"index_rebuilding": "Indice di ottimizzazione ({{percentage}}%)",
"index_rebuild_complete": "Ottimizzazione dell'indice completata",
"index_rebuild_status_error": "Errore durante il controllo dello stato di ricostruzione dell'indice",
"never": "Mai",
"processing": "Elaborazione ({{percentuale}}%)",
"incomplete": "Incompleto ({{percentuale}}%)",
"processing": "Elaborazione ({{percentage}}%)",
"incomplete": "Incompleto ({{percentage}}%)",
"complete": "Completato (100%)",
"refreshing": "Rinfrescante...",
"auto_refresh_notice": "Si aggiorna automaticamente ogni {{seconds}} secondi",
@@ -761,9 +757,7 @@
"indexing_stopped": "Indicizzazione interrotta",
"indexing_in_progress": "Indicizzazione in corso...",
"last_indexed": "Ultimo indicizzato",
"n_notes_queued": "{{ count }} nota in coda per l'indicizzazione",
"note_chat": "Nota Chat",
"notes_indexed": "{{ count }} nota indicizzata",
"sources": "Fonti",
"start_indexing": "Avvia l'indicizzazione",
"use_advanced_context": "Usa contesto avanzato",
@@ -811,7 +805,8 @@
"codeImportedAsCode": "Importa i file di codice riconosciuti (ad esempio <code>.json</code>) come note di codice se non è chiaro dai metadati",
"replaceUnderscoresWithSpaces": "Sostituisci i trattini bassi con spazi nei nomi delle note importate",
"import": "Importa",
"failed": "Importazione fallita: {{message}}."
"failed": "Importazione fallita: {{message}}.",
"importZipRecommendation": "Quando si importa un file ZIP, la gerarchia delle note rifletterà la struttura delle sottodirectory all'interno dell'archivio."
},
"include_note": {
"dialog_title": "Includi nota",
@@ -868,7 +863,6 @@
"delete_all_revisions": "Elimina tutte le revisioni di questa nota",
"delete_all_button": "Elimina tutte le revisioni",
"help_title": "Aiuto sulle revisioni delle note",
"revision_last_edited": "Questa revisione è stata modificata l'ultima volta il {{date}}",
"confirm_delete_all": "Vuoi eliminare tutte le revisioni di questa nota?",
"no_revisions": "Ancora nessuna revisione per questa nota...",
"restore_button": "Ripristina",
@@ -1478,7 +1472,7 @@
},
"attachment_list": {
"open_help_page": "Apri la pagina di aiuto sugli allegati",
"owning_note": "Nota di proprietà:",
"owning_note": "Nota di proprietà: ",
"upload_attachments": "Carica allegati",
"no_attachments": "Questa nota non ha allegati."
},
@@ -1710,7 +1704,7 @@
"for_more_info": "per maggiori informazioni.",
"protected_session_timeout_label": "Timeout della sessione protetta:",
"reset_confirmation": "Reimpostando la password perderai per sempre l'accesso a tutte le tue note protette. Vuoi davvero reimpostare la password?",
"reset_success_message": "La password è stata reimpostata. Imposta una nuova password.",
"reset_success_message": "La password è stata resettata. Imposta una nuova password",
"change_password_heading": "Cambiare la password",
"set_password_heading": "Imposta password",
"set_password": "Imposta password",
@@ -1740,14 +1734,14 @@
"recovery_keys_no_key_set": "Nessun codice di ripristino impostato",
"recovery_keys_generate": "Genera codici di recupero",
"recovery_keys_regenerate": "Rigenera i codici di recupero",
"recovery_keys_used": "Utilizzato: {{data}}",
"recovery_keys_used": "Utilizzato: {{date}}",
"recovery_keys_unused": "Il codice di ripristino {{index}} non è utilizzato",
"oauth_title": "OAuth/OpenID",
"oauth_description": "OpenID è un metodo standardizzato che ti consente di accedere ai siti web utilizzando un account di un altro servizio, come Google, per verificare la tua identità. L'emittente predefinito è Google, ma puoi cambiarlo con qualsiasi altro provider OpenID. Per ulteriori informazioni, consulta <a href=\"#root/_hidden/_help/_help_Otzi9La2YAUX/_help_WOcw2SLH6tbX/_help_7DAiwaf8Z7Rz\">qui</a>. Segui queste <a href=\"https://developers.google.com/identity/openid-connect/openid-connect\">istruzioni</a> per configurare un servizio OpenID tramite Google.",
"oauth_description_warning": "Per abilitare OAuth/OpenID, è necessario impostare l'URL di base di OAuth/OpenID, l'ID client e il segreto client nel file config.ini e riavviare l'applicazione. Per impostare le variabili d'ambiente, impostare TRILIUM_OAUTH_BASE_URL, TRILIUM_OAUTH_CLIENT_ID e TRILIUM_OAUTH_CLIENT_SECRET.",
"oauth_missing_vars": "Impostazioni mancanti: {{-variabili}}",
"oauth_user_account": "Account utente:",
"oauth_user_email": "Email utente:",
"oauth_missing_vars": "Impostazioni mancanti: {{-variables}}",
"oauth_user_account": "Account utente: ",
"oauth_user_email": "Email utente: ",
"oauth_user_not_logged_in": "Non hai effettuato l'accesso!"
},
"spellcheck": {
@@ -1756,7 +1750,7 @@
"enable": "Abilita il controllo ortografico",
"language_code_label": "Codice/i della lingua",
"language_code_placeholder": "ad esempio \"en-US\", \"de-AT\"",
"multiple_languages_info": "È possibile separare più lingue con una virgola, ad esempio \"en-US, de-DE, cs\".",
"multiple_languages_info": "È possibile separare più lingue con una virgola, ad esempio \"en-US, de-DE, cs\". ",
"available_language_codes_label": "Codici lingua disponibili:",
"restart-required": "Le modifiche alle opzioni di controllo ortografico avranno effetto dopo il riavvio dell'applicazione."
},
@@ -1858,7 +1852,9 @@
"window-on-top": "Mantieni la finestra in primo piano"
},
"note_detail": {
"could_not_find_typewidget": "Impossibile trovare typeWidget per il tipo '{{type}}'"
"could_not_find_typewidget": "Impossibile trovare typeWidget per il tipo '{{type}}'",
"printing": "Stampa in corso...",
"printing_pdf": "Esportazione in PDF in corso..."
},
"note_title": {
"placeholder": "scrivi qui il titolo della nota..."
@@ -1909,7 +1905,7 @@
},
"frontend_script_api": {
"async_warning": "Stai passando una funzione asincrona a `api.runOnBackend()` che probabilmente non funzionerà come previsto.\\nRendi la funzione sincrona (rimuovendo la parola chiave `async`) oppure usa `api.runAsyncOnBackendWithManualTransactionHandling()`.",
"sync_warning": "Stai passando una funzione sincrona a `api.runAsyncOnBackendWithManualTransactionHandling()`, mentre probabilmente dovresti usare `api.runOnBackend()`."
"sync_warning": "Stai passando una funzione sincrona a `api.runAsyncOnBackendWithManualTransactionHandling()`, \\nmentre probabilmente dovresti usare `api.runOnBackend()`."
},
"ws": {
"sync-check-failed": "Controllo di sincronizzazione fallito!",
@@ -2044,7 +2040,7 @@
"slide-overview": "Attiva/disattiva una panoramica delle diapositive"
},
"command_palette": {
"tree-action-name": "Albero: {{nome}}",
"tree-action-name": "Albero: {{name}}",
"export_note_title": "Nota di esportazione",
"export_note_description": "Esporta la nota corrente",
"show_attachments_title": "Mostra allegati",
@@ -2087,4 +2083,4 @@
"collections": {
"rendering_error": "Impossibile mostrare il contenuto a causa di un errore."
}
}
}

View File

@@ -73,7 +73,7 @@
},
"left_pane_toggle": {
"show_panel": "パネルを表示",
"hide_panel": "パネルを隠す"
"hide_panel": "パネルを非表示"
},
"move_pane_button": {
"move_left": "左に移動",
@@ -254,7 +254,8 @@
"export_status": "エクスポート状況",
"export_in_progress": "エクスポート処理中: {{progressCount}}",
"export_finished_successfully": "エクスポートが正常に完了しました。",
"format_pdf": "PDF - 印刷または共有目的に。"
"format_pdf": "PDF - 印刷または共有目的に。",
"share-format": "Web 公開用の HTML - 共有ノートで使用されるのと同じテーマを使用しますが、静的 Web サイトとして公開できます。"
},
"help": {
"title": "チートシート",
@@ -610,7 +611,6 @@
"delete_all_revisions": "このノートの変更履歴をすべて削除",
"delete_all_button": "変更履歴をすべて削除",
"help_title": "変更履歴のヘルプ",
"revision_last_edited": "この変更は{{date}}に行われました",
"confirm_delete_all": "このノートのすべての変更履歴を削除しますか?",
"no_revisions": "このノートに変更履歴はまだありません...",
"restore_button": "復元",
@@ -657,10 +657,6 @@
"created": "作成日時",
"title": "ETAPI",
"description": "ETAPI は、Trilium インスタンスに UI なしでプログラム的にアクセスするための REST API です。",
"see_more": "詳細は{{- link_to_wiki}}と{{- link_to_openapi_spec}}または{{- link_to_swagger_ui }}を参照してください。",
"wiki": "wiki",
"openapi_spec": "ETAPI OpenAPIの仕様",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "新しくETAPIトークンを作成",
"existing_tokens": "既存のトークン",
"no_tokens_yet": "トークンはまだありません。上のボタンをクリックして作成してください。",
@@ -741,7 +737,7 @@
"new-column": "新しい列",
"sort-column-by": "\"{{title}}\" で並べ替え",
"sort-column-clear": "並べ替えをクリア",
"hide-column": "列 \"{{title}}\" を隠す",
"hide-column": "列 \"{{title}}\" を非表示",
"show-hide-columns": "列を表示/非表示",
"row-insert-above": "上に行を挿入",
"row-insert-below": "下に行を挿入",
@@ -1200,7 +1196,7 @@
"collapse-title": "ノートツリーを折りたたむ",
"scroll-active-title": "アクティブノートまでスクロール",
"tree-settings-title": "ツリーの設定",
"hide-archived-notes": "アーカイブノートを隠す",
"hide-archived-notes": "アーカイブノートを非表示",
"automatically-collapse-notes": "ノートを自動的に折りたたむ",
"automatically-collapse-notes-title": "一定期間使用されないと、ツリーを整理するためにノートは折りたたまれます。",
"save-changes": "変更を保存して適用",

View File

@@ -13,6 +13,13 @@
"critical-error": {
"title": "Kritische Error",
"message": "Een kritieke fout heeft plaatsgevonden waardoor de cliënt zich aanmeldt vanaf het begin:\n\n84X\n\nDit is waarschijnlijk veroorzaakt door een script dat op een onverwachte manier faalt. Probeer de sollicitatie in veilige modus te starten en de kwestie aan te spreken."
},
"widget-error": {
"title": "Starten widget mislukt",
"message-unknown": "Onbekende widget kan niet gestart worden omdat:\n\n{{message}}"
},
"bundle-error": {
"title": "Custom script laden mislukt"
}
},
"add_link": {

View File

@@ -912,7 +912,6 @@
"delete_all_revisions": "Usuń wszystkie wersje tej notatki",
"delete_all_button": "Usuń wszystkie wersje",
"help_title": "Pomoc dotycząca wersji notatki",
"revision_last_edited": "Ta wersja była ostatnio edytowana {{date}}",
"confirm_delete_all": "Czy chcesz usunąć wszystkie wersje tej notatki?",
"no_revisions": "Brak wersji dla tej notatki...",
"restore_button": "Przywróć",
@@ -1664,10 +1663,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI to interfejs API REST używany do programowego dostępu do instancji Trilium, bez interfejsu użytkownika.",
"see_more": "Zobacz więcej szczegółów w {{- link_to_wiki}} oraz w {{- link_to_openapi_spec}} lub {{- link_to_swagger_ui }}.",
"wiki": "wiki",
"openapi_spec": "specyfikacja ETAPI OpenAPI",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "Utwórz nowy token ETAPI",
"existing_tokens": "Istniejące tokeny",
"no_tokens_yet": "Nie ma jeszcze żadnych tokenów. Kliknij przycisk powyżej, aby utworzyć jeden.",

View File

@@ -259,7 +259,6 @@
"delete_all_revisions": "Apagar todas as versões desta nota",
"delete_all_button": "Apagar todas as versões",
"help_title": "Ajuda sobre as versões da nota",
"revision_last_edited": "Esta versão foi editada pela última vez em {{date}}",
"confirm_delete_all": "Quer apagar todas as versões desta nota?",
"no_revisions": "Ainda não há versões para esta nota...",
"restore_button": "Recuperar",
@@ -1423,10 +1422,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI é uma API REST usada para aceder a instância do Trilium programaticamente, sem interface gráfica.",
"see_more": "Veja mais pormenores no {{- link_to_wiki}}, na {{- link_to_openapi_spec}} ou na {{- link_to_swagger_ui}}.",
"wiki": "wiki",
"openapi_spec": "Especificação OpenAPI do ETAPI",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "Criar token ETAPI",
"existing_tokens": "Tokens existentes",
"no_tokens_yet": "Ainda não existem tokens. Clique no botão acima para criar um.",

View File

@@ -415,7 +415,6 @@
"delete_all_revisions": "Excluir todas as versões desta nota",
"delete_all_button": "Excluir todas as versões",
"help_title": "Ajuda sobre as versões da nota",
"revision_last_edited": "Esta versão foi editada pela última vez em {{date}}",
"confirm_delete_all": "Você quer excluir todas as versões desta nota?",
"no_revisions": "Ainda não há versões para esta nota...",
"restore_button": "Recuperar",
@@ -1933,10 +1932,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI é uma API REST usada para acessar a instância do Trilium programaticamente, sem interface gráfica.",
"see_more": "Veja mais detalhes no {{- link_to_wiki}}, na {{- link_to_openapi_spec}} ou na {{- link_to_swagger_ui}}.",
"wiki": "wiki",
"openapi_spec": "Especificação OpenAPI do ETAPI",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "Criar novo token ETAPI",
"existing_tokens": "Tokens existentes",
"no_tokens_yet": "Ainda não existem tokens. Clique no botão acima para criar um.",

View File

@@ -507,17 +507,13 @@
"new_token_message": "Introduceți denumirea noului token",
"new_token_title": "Token ETAPI nou",
"no_tokens_yet": "Nu există încă token-uri. Clic pe butonul de deasupra pentru a crea una.",
"openapi_spec": "Specificația OpenAPI pentru ETAPI",
"swagger_ui": "UI-ul Swagger pentru ETAPI",
"rename_token": "Redenumește token-ul",
"rename_token_message": "Introduceți denumirea noului token",
"rename_token_title": "Redenumire token",
"see_more": "Vedeți mai multe detalii în {{- link_to_wiki}} și în {{- link_to_openapi_spec}} sau în {{- link_to_swagger_ui }}.",
"title": "ETAPI",
"token_created_message": "Copiați token-ul creat în clipboard. Trilium stochează token-ul ca hash așadar această valoare poate fi văzută doar acum.",
"token_created_title": "Token ETAPI creat",
"token_name": "Denumire token",
"wiki": "wiki"
"token_name": "Denumire token"
},
"execute_script": {
"example_1": "De exemplu, pentru a adăuga un șir de caractere la titlul unei notițe, se poate folosi acest mic script:",
@@ -1090,7 +1086,6 @@
"preview_not_available": "Nu este disponibilă o previzualizare pentru acest tip de notiță.",
"restore_button": "Restaurează",
"revision_deleted": "Revizia notiței a fost ștearsă.",
"revision_last_edited": "Revizia a fost ultima oară modificată pe {{date}}",
"revision_restored": "Revizia notiței a fost restaurată.",
"revisions_deleted": "Notița reviziei a fost ștearsă.",
"maximum_revisions": "Numărul maxim de revizii pentru notița curentă: {{number}}.",

View File

@@ -320,7 +320,8 @@
"explodeArchivesTooltip": "Если этот флажок установлен, Trilium будет читать файлы <code>.zip</code>, <code>.enex</code> и <code>.opml</code> и создавать заметки из файлов внутри этих архивов. Если флажок не установлен, Trilium будет прикреплять сами архивы к заметке.",
"explodeArchives": "Прочитать содержимое архивов <code>.zip</code>, <code>.enex</code> и <code>.opml</code>.",
"shrinkImagesTooltip": "<p>Если этот параметр включен, Trilium попытается уменьшить размер импортируемых изображений путём масштабирования и оптимизации, что может повлиять на воспринимаемое качество изображения. Если этот параметр не установлен, изображения будут импортированы без изменений.</p><p>Это не относится к импорту файлов <code>.zip</code> с метаданными, поскольку предполагается, что эти файлы уже оптимизированы.</p>",
"codeImportedAsCode": "Импортировать распознанные файлы кода (например, <code>.json</code>) в виде заметок типа \"код\", если это неясно из метаданных"
"codeImportedAsCode": "Импортировать распознанные файлы кода (например, <code>.json</code>) в виде заметок типа \"код\", если это неясно из метаданных",
"importZipRecommendation": "При импорте ZIP файла иерархия заметок будет отражена в структуре папок внутри архива."
},
"markdown_import": {
"dialog_title": "Импорт Markdown",
@@ -365,7 +366,6 @@
"delete_all_button": "Удалить все версии",
"help_title": "Помощь по версиям заметок",
"confirm_delete_all": "Вы хотите удалить все версии этой заметки?",
"revision_last_edited": "Эта версия последний раз редактировалась {{date}}",
"confirm_restore": "Хотите восстановить эту версию? Текущее название и содержание заметки будут перезаписаны этой версией.",
"confirm_delete": "Вы хотите удалить эту версию?",
"revisions_deleted": "Версии заметки были удалены.",
@@ -980,7 +980,8 @@
"open_sql_console_history": "Открыть историю консоли SQL",
"show_shared_notes_subtree": "Поддерево общедоступных заметок",
"switch_to_mobile_version": "Перейти на мобильную версию",
"switch_to_desktop_version": "Переключиться на версию для ПК"
"switch_to_desktop_version": "Переключиться на версию для ПК",
"new-version-available": "Доступно обновление"
},
"zpetne_odkazy": {
"backlink": "{{count}} ссылки",
@@ -1439,7 +1440,6 @@
},
"etapi": {
"title": "ETAPI",
"wiki": "вики",
"created": "Создано",
"actions": "Действия",
"existing_tokens": "Существующие токены",
@@ -1447,10 +1447,7 @@
"default_token_name": "новый токен",
"rename_token_title": "Переименовать токен",
"description": "ETAPI — это REST API, используемый для программного доступа к экземпляру Trilium без пользовательского интерфейса.",
"see_more": "Более подробную информацию смотрите в {{- link_to_wiki}} и {{- link_to_openapi_spec}} или {{- link_to_swagger_ui }}.",
"create_token": "Создать новый токен ETAPI",
"openapi_spec": "Спецификация ETAPI OpenAPI",
"swagger_ui": "Пользовательский интерфейс ETAPI Swagger",
"new_token_title": "Новый токен ETAPI",
"token_created_title": "Создан токен ETAPI",
"rename_token": "Переименовать этот токен",

View File

@@ -256,7 +256,6 @@
"delete_all_revisions": "Obriši sve revizije ove beleške",
"delete_all_button": "Obriši sve revizije",
"help_title": "Pomoć za Revizije beleški",
"revision_last_edited": "Ova revizija je poslednji put izmenjena {{date}}",
"confirm_delete_all": "Da li želite da obrišete sve revizije ove beleške?",
"no_revisions": "Još uvek nema revizija za ovu belešku...",
"restore_button": "Vrati",

View File

@@ -104,7 +104,8 @@
"export_in_progress": "正在匯出:{{progressCount}}",
"export_finished_successfully": "成功匯出。",
"format_html": "HTML - 推薦,因為它保留了所有格式",
"format_pdf": "PDF - 用於列印或與他人分享。"
"format_pdf": "PDF - 用於列印或與他人分享。",
"share-format": "HTML 網頁發佈——使用與共享筆記相同的佈景主題,但可發佈為靜態網站。"
},
"help": {
"noteNavigation": "筆記導航",
@@ -184,7 +185,8 @@
},
"import-status": "匯入狀態",
"in-progress": "正在匯入:{{progress}}",
"successful": "匯入成功。"
"successful": "匯入成功。",
"importZipRecommendation": "匯入 ZIP 檔案時,筆記層級將反映壓縮檔內的子目錄結構。"
},
"include_note": {
"dialog_title": "內嵌筆記",
@@ -259,7 +261,6 @@
"delete_all_revisions": "刪除此筆記的所有歷史版本",
"delete_all_button": "刪除所有歷史版本",
"help_title": "關於筆記歷史版本的說明",
"revision_last_edited": "此歷史版本上次於 {{date}} 編輯",
"confirm_delete_all": "您是否要刪除此筆記的所有歷史版本?",
"no_revisions": "此筆記暫無歷史版本…",
"confirm_restore": "您是否要還原此歷史版本?這將使用此歷史版本覆寫筆記的目前標題和內容。",
@@ -1280,8 +1281,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI 是一個 REST API用於以編程方式訪問 Trilium 實例,而無需 UI。",
"wiki": "維基",
"openapi_spec": "ETAPI OpenAPI 規範",
"create_token": "新增 ETAPI 令牌",
"existing_tokens": "現有令牌",
"no_tokens_yet": "目前還沒有令牌。點擊上面的按鈕新增一個。",
@@ -1298,9 +1297,7 @@
"delete_token": "刪除 / 停用此令牌",
"rename_token_title": "重新命名令牌",
"rename_token_message": "請輸入新的令牌名稱",
"delete_token_confirmation": "您確定要刪除 ETAPI 令牌 \"{{name}}\" 嗎?",
"see_more": "有關更多詳細資訊,請參閱 {{- link_to_wiki}} 和 {{- link_to_openapi_spec}} 或 {{- link_to_swagger_ui}}。",
"swagger_ui": "ETAPI Swagger UI"
"delete_token_confirmation": "您確定要刪除 ETAPI 令牌 \"{{name}}\" 嗎?"
},
"options_widget": {
"options_status": "選項狀態",

View File

@@ -309,7 +309,6 @@
"delete_all_revisions": "Видалити всі версії цієї нотатки",
"delete_all_button": "Видалити всі версії",
"help_title": "Довідка щодо Версій нотаток",
"revision_last_edited": "Цю версію востаннє редагували {{date}}",
"confirm_delete_all": "Ви хочете видалити всі версії цієї нотатки?",
"no_revisions": "Поки що немає версій цієї нотатки...",
"restore_button": "Відновити",
@@ -1403,10 +1402,6 @@
"etapi": {
"title": "ETAPI",
"description": "ETAPI — це REST API, який використовується для програмного доступу до екземпляра Trilium без інтерфейсу користувача.",
"see_more": "Див. докладнішу інформацію у {{- link_to_wiki}} та {{- link_to_openapi_spec}} або {{- link_to_swagger_ui }}.",
"wiki": "вікі",
"openapi_spec": "ETAPI OpenAPI spec",
"swagger_ui": "ETAPI Swagger UI",
"create_token": "Створити новий токен ETAPI",
"existing_tokens": "Існуючі токени",
"no_tokens_yet": "Токенів поки що немає. Натисніть кнопку вище, щоб створити його.",

View File

@@ -11,7 +11,8 @@
},
"add_link": {
"add_link": "Thêm liên kết",
"button_add_link": "Thêm liên kết"
"button_add_link": "Thêm liên kết",
"help_on_links": "Trợ giúp về các liên kết"
},
"bulk_actions": {
"other": "Khác"
@@ -41,7 +42,13 @@
"message": "Đã xảy ra lỗi nghiêm trọng ngăn ứng dụng client khởi động\n\n{{message}}\n\nĐiều này có khả năng bị gây ra bởi một script hoạt động không như mong đợi. Hãy thử khởi động ứng dụng ở chế độ an toàn và giải quyết vấn đề."
},
"widget-error": {
"title": "Khởi tạo widget thất bại"
"title": "Khởi tạo widget thất bại",
"message-custom": "Tiện ích tùy chỉnh từ ghi chú với ID \"{{id}}\", tiêu đề \"{{title}}\" không thể khởi tạo vì:\n\n{{message}}",
"message-unknown": "Tiện ích chưa biết không thể được khởi tạo vì:\n\n{{message}}"
},
"bundle-error": {
"title": "Tải script tùy chọn thất bại",
"message": "Script từ ghi chú ID \"{{id}}\", tiêu đề \"{{title}}\" không thể chạy được vì:\n\n{{message}}"
}
},
"import": {

View File

@@ -26,7 +26,6 @@ interface CustomGlobals {
appContext: AppContext;
froca: Froca;
treeCache: Froca;
importMarkdownInline: () => Promise<unknown>;
SEARCH_HELP_TEXT: string;
activeDialog: JQuery<HTMLElement> | null;
componentId: string;

View File

@@ -47,8 +47,9 @@ export default class RightDropdownButtonWidget extends BasicWidget {
}
});
this.$tooltip = this.$widget.find(".tooltip-trigger").attr("title", this.title);
this.tooltip = new Tooltip(this.$tooltip[0], {
this.$widget.attr("title", this.title);
this.tooltip = Tooltip.getOrCreateInstance(this.$widget[0], {
trigger: "hover",
placement: handleRightToLeftPlacement(this.settings.titlePlacement),
fallbackPlacements: [ handleRightToLeftPlacement(this.settings.titlePlacement) ]
});
@@ -56,9 +57,7 @@ export default class RightDropdownButtonWidget extends BasicWidget {
this.$widget
.find(".right-dropdown-button")
.addClass(this.iconClass)
.on("click", () => this.tooltip.hide())
.on("mouseenter", () => this.tooltip.show())
.on("mouseleave", () => this.tooltip.hide());
.on("click", () => this.tooltip.hide());
this.$widget.on("show.bs.dropdown", async () => {
await this.dropdownShown();

View File

@@ -141,7 +141,11 @@ function NoteContent({ note, trim, noChildrenList, highlightedTokens }: { note:
})
.then(({ $renderedContent, type }) => {
if (!contentRef.current) return;
contentRef.current.replaceChildren(...$renderedContent);
if ($renderedContent[0].innerHTML) {
contentRef.current.replaceChildren(...$renderedContent);
} else {
contentRef.current.replaceChildren();
}
contentRef.current.classList.add(`type-${type}`);
highlightSearch(contentRef.current);
})

View File

@@ -79,6 +79,7 @@ export default function ExportDialog() {
values={[
{ value: "html", label: t("export.format_html_zip") },
{ value: "markdown", label: t("export.format_markdown") },
{ value: "share", label: t("export.share-format") },
{ value: "opml", label: t("export.format_opml") }
]}
/>

View File

@@ -7,6 +7,7 @@ import utils from "../../services/utils";
import Modal from "../react/Modal";
import Button from "../react/Button";
import { useTriliumEvent } from "../react/hooks";
import EditableTextTypeWidget from "../type_widgets/editable_text";
interface RenderMarkdownResponse {
htmlContent: string;
@@ -14,39 +15,34 @@ interface RenderMarkdownResponse {
export default function MarkdownImportDialog() {
const markdownImportTextArea = useRef<HTMLTextAreaElement>(null);
const [textTypeWidget, setTextTypeWidget] = useState<EditableTextTypeWidget>();
const [ text, setText ] = useState("");
const [ shown, setShown ] = useState(false);
const triggerImport = useCallback(() => {
if (appContext.tabManager.getActiveContextNoteType() !== "text") {
return;
}
useTriliumEvent("showPasteMarkdownDialog", ({ textTypeWidget }) => {
setTextTypeWidget(textTypeWidget);
if (utils.isElectron()) {
const { clipboard } = utils.dynamicRequire("electron");
const text = clipboard.readText();
convertMarkdownToHtml(text);
convertMarkdownToHtml(text, textTypeWidget);
} else {
setShown(true);
}
}, []);
useTriliumEvent("importMarkdownInline", triggerImport);
useTriliumEvent("pasteMarkdownIntoText", triggerImport);
async function sendForm() {
await convertMarkdownToHtml(text);
setText("");
setShown(false);
}
});
return (
<Modal
className="markdown-import-dialog" title={t("markdown_import.dialog_title")} size="lg"
footer={<Button className="markdown-import-button" text={t("markdown_import.import_button")} onClick={sendForm} keyboardShortcut="Ctrl+Space" />}
footer={<Button className="markdown-import-button" text={t("markdown_import.import_button")} onClick={() => setShown(false)} keyboardShortcut="Ctrl+Enter" />}
onShown={() => markdownImportTextArea.current?.focus()}
onHidden={() => setShown(false) }
onHidden={async () => {
if (textTypeWidget) {
await convertMarkdownToHtml(text, textTypeWidget);
}
setShown(false);
setText("");
}}
show={shown}
>
<p>{t("markdown_import.modal_body_text")}</p>
@@ -56,26 +52,17 @@ export default function MarkdownImportDialog() {
onKeyDown={(e) => {
if (e.key === "Enter" && e.ctrlKey) {
e.preventDefault();
sendForm();
setShown(false);
}
}}></textarea>
</Modal>
)
}
async function convertMarkdownToHtml(markdownContent: string) {
async function convertMarkdownToHtml(markdownContent: string, textTypeWidget: EditableTextTypeWidget) {
const { htmlContent } = await server.post<RenderMarkdownResponse>("other/render-markdown", { markdownContent });
const textEditor = await appContext.tabManager.getActiveContext()?.getTextEditor();
if (!textEditor) {
return;
}
const viewFragment = textEditor.data.processor.toView(htmlContent);
const modelFragment = textEditor.data.toModel(viewFragment);
textEditor.model.insertContent(modelFragment, textEditor.model.document.selection);
textEditor.editing.view.focus();
await textTypeWidget.addHtmlToEditor(htmlContent);
toast.showMessage(t("markdown_import.import_success"));
}

View File

@@ -155,6 +155,11 @@ export default class PopupEditorDialog extends Container<BasicWidget> {
return Promise.resolve();
}
// Avoid not showing recent notes when creating a new empty tab.
if ("noteContext" in data && data.noteContext.ntxId !== "_popup-editor") {
return Promise.resolve();
}
return super.handleEventInChildren(name, data);
}

View File

@@ -140,11 +140,10 @@ function RevisionsList({ revisions, onSelect, currentRevision }: { revisions: Re
<FormList onSelect={onSelect} fullHeight>
{revisions.map((item) =>
<FormListItem
title={t("revisions.revision_last_edited", { date: item.dateLastEdited })}
value={item.revisionId}
active={currentRevision && item.revisionId === currentRevision.revisionId}
>
{item.dateLastEdited && item.dateLastEdited.substr(0, 16)} ({item.contentLength && utils.formatSize(item.contentLength)})
{item.dateCreated && item.dateCreated.substr(0, 16)} ({item.contentLength && utils.formatSize(item.contentLength)})
</FormListItem>
)}
</FormList>);

View File

@@ -147,6 +147,12 @@ const categories: Category[] = [
];
const icons: Icon[] = [
{
name: "empty",
slug: "empty",
category_id: 113,
type_of_icon: "REGULAR"
},
{
name: "child",
slug: "child-regular",

View File

@@ -56,4 +56,16 @@
.note-icon-widget .icon-list span:hover {
border: 1px solid var(--main-border-color);
}
.note-icon-widget .icon-list span.bx-empty {
width: unset;
}
.note-icon-widget .icon-list span.bx-empty::before {
display: inline-block;
content: "";
border: 1px dashed var(--muted-text-color);
width: 1em;
height: 1em;
}

View File

@@ -1,4 +1,5 @@
import { useNoteContext, useTriliumOption } from "../react/hooks";
import { useTriliumOption } from "../react/hooks";
import { TabContext } from "./ribbon-interface";
/**
* Handles the editing toolbar when the CKEditor is in decoupled mode.
@@ -6,19 +7,13 @@ import { useNoteContext, useTriliumOption } from "../react/hooks";
* This toolbar is only enabled if the user has selected the classic CKEditor.
*
* The ribbon item is active by default for text notes, as long as they are not in read-only mode.
*
*
* ! The toolbar is not only used in the ribbon, but also in the quick edit feature.
*/
export default function FormattingToolbar({ hidden }: { hidden?: boolean }) {
export default function FormattingToolbar({ hidden }: TabContext) {
const [ textNoteEditorType ] = useTriliumOption("textNoteEditorType");
return (textNoteEditorType === "ckeditor-classic" &&
<div className={`classic-toolbar-widget ${hidden ? "hidden-ext" : ""}`} />
)
};
export function PopupEditorFormattingToolbar() {
// TODO: Integrate this directly once we migrate away from class components.
const { note } = useNoteContext();
return <FormattingToolbar hidden={note?.type !== "text"} />;
}

View File

@@ -46,7 +46,7 @@ function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: Not
const parentComponent = useContext(ParentComponent);
const canBeConvertedToAttachment = note?.isEligibleForConversionToAttachment();
const isSearchable = ["text", "code", "book", "mindMap", "doc"].includes(note.type);
const isInOptions = note.noteId.startsWith("_options");
const isInOptionsOrHelp = note?.noteId.startsWith("_options") || note?.noteId.startsWith("_help");
const isPrintable = ["text", "code"].includes(note.type) || (note.type === "book" && note.getLabelValue("viewType") === "presentation");
const isElectron = getIsElectron();
const isMac = getIsMac();
@@ -69,10 +69,10 @@ function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: Not
<FormDropdownDivider />
<CommandItem icon="bx bx-import" text={t("note_actions.import_files")}
disabled={isInOptions || note.type === "search"}
disabled={isInOptionsOrHelp || note.type === "search"}
command={() => parentComponent?.triggerCommand("showImportDialog", { noteId: note.noteId })} />
<CommandItem icon="bx bx-export" text={t("note_actions.export_note")}
disabled={isInOptions || note.noteId === "_backendLog"}
disabled={isInOptionsOrHelp || note.noteId === "_backendLog"}
command={() => noteContext?.notePath && parentComponent?.triggerCommand("showExportDialog", {
notePath: noteContext.notePath,
defaultType: "single"
@@ -84,14 +84,14 @@ function NoteContextMenu({ note, noteContext }: { note: FNote, noteContext?: Not
<CommandItem command="showNoteSource" icon="bx bx-code" disabled={!hasSource} text={t("note_actions.note_source")} />
<FormDropdownDivider />
<CommandItem command="forceSaveRevision" icon="bx bx-save" disabled={isInOptions} text={t("note_actions.save_revision")} />
<CommandItem command="forceSaveRevision" icon="bx bx-save" disabled={isInOptionsOrHelp} text={t("note_actions.save_revision")} />
<CommandItem icon="bx bx-trash destructive-action-icon" text={t("note_actions.delete_note")} destructive
disabled={isInOptions}
disabled={isInOptionsOrHelp}
command={() => branches.deleteNotes([note.getParentBranches()[0].branchId])}
/>
<FormDropdownDivider />
<CommandItem command="showAttachments" icon="bx bx-paperclip" disabled={isInOptions} text={t("note_actions.note_attachments")} />
<CommandItem command="showAttachments" icon="bx bx-paperclip" disabled={isInOptionsOrHelp} text={t("note_actions.note_attachments")} />
</Dropdown>
);
}

View File

@@ -1,163 +1,15 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "preact/hooks";
import { t } from "../../services/i18n";
import { useNoteContext, useNoteProperty, useStaticTooltipWithKeyboardShortcut, useTriliumEvents } from "../react/hooks";
import "./style.css";
import { VNode } from "preact";
import BasicPropertiesTab from "./BasicPropertiesTab";
import FormattingToolbar from "./FormattingToolbar";
import { numberObjectsInPlace } from "../../services/utils";
import { TabContext } from "./ribbon-interface";
import options from "../../services/options";
import { EventNames } from "../../components/app_context";
import FNote from "../../entities/fnote";
import ScriptTab from "./ScriptTab";
import EditedNotesTab from "./EditedNotesTab";
import NotePropertiesTab from "./NotePropertiesTab";
import NoteInfoTab from "./NoteInfoTab";
import SimilarNotesTab from "./SimilarNotesTab";
import FilePropertiesTab from "./FilePropertiesTab";
import ImagePropertiesTab from "./ImagePropertiesTab";
import NotePathsTab from "./NotePathsTab";
import NoteMapTab from "./NoteMapTab";
import OwnedAttributesTab from "./OwnedAttributesTab";
import InheritedAttributesTab from "./InheritedAttributesTab";
import CollectionPropertiesTab from "./CollectionPropertiesTab";
import SearchDefinitionTab from "./SearchDefinitionTab";
import NoteActions from "./NoteActions";
import { KeyboardActionNames } from "@triliumnext/commons";
import { RIBBON_TAB_DEFINITIONS } from "./RibbonDefinition";
import { TabConfiguration, TitleContext } from "./ribbon-interface";
interface TitleContext {
note: FNote | null | undefined;
}
interface TabConfiguration {
title: string | ((context: TitleContext) => string);
icon: string;
content: (context: TabContext) => VNode | false;
show: boolean | ((context: TitleContext) => boolean | null | undefined);
toggleCommand?: KeyboardActionNames;
activate?: boolean | ((context: TitleContext) => boolean);
/**
* By default the tab content will not be rendered unless the tab is active (i.e. selected by the user). Setting to `true` will ensure that the tab is rendered even when inactive, for cases where the tab needs to be accessible at all times (e.g. for the detached editor toolbar) or if event handling is needed.
*/
stayInDom?: boolean;
}
const TAB_CONFIGURATION = numberObjectsInPlace<TabConfiguration>([
{
title: t("classic_editor_toolbar.title"),
icon: "bx bx-text",
show: ({ note }) => note?.type === "text" && options.get("textNoteEditorType") === "ckeditor-classic",
toggleCommand: "toggleRibbonTabClassicEditor",
content: FormattingToolbar,
activate: true,
stayInDom: true
},
{
title: ({ note }) => note?.isTriliumSqlite() ? t("script_executor.query") : t("script_executor.script"),
icon: "bx bx-play",
content: ScriptTab,
activate: true,
show: ({ note }) => note &&
(note.isTriliumScript() || note.isTriliumSqlite()) &&
(note.hasLabel("executeDescription") || note.hasLabel("executeButton"))
},
{
title: t("search_definition.search_parameters"),
icon: "bx bx-search",
content: SearchDefinitionTab,
activate: true,
show: ({ note }) => note?.type === "search"
},
{
title: t("edited_notes.title"),
icon: "bx bx-calendar-edit",
content: EditedNotesTab,
show: ({ note }) => note?.hasOwnedLabel("dateNote"),
activate: ({ note }) => (note?.getPromotedDefinitionAttributes().length === 0 || !options.is("promotedAttributesOpenInRibbon")) && options.is("editedNotesOpenInRibbon")
},
{
title: t("book_properties.book_properties"),
icon: "bx bx-book",
content: CollectionPropertiesTab,
show: ({ note }) => note?.type === "book" || note?.type === "search",
toggleCommand: "toggleRibbonTabBookProperties"
},
{
title: t("note_properties.info"),
icon: "bx bx-info-square",
content: NotePropertiesTab,
show: ({ note }) => !!note?.getLabelValue("pageUrl"),
activate: true
},
{
title: t("file_properties.title"),
icon: "bx bx-file",
content: FilePropertiesTab,
show: ({ note }) => note?.type === "file",
toggleCommand: "toggleRibbonTabFileProperties",
activate: ({ note }) => note?.mime !== "application/pdf"
},
{
title: t("image_properties.title"),
icon: "bx bx-image",
content: ImagePropertiesTab,
show: ({ note }) => note?.type === "image",
toggleCommand: "toggleRibbonTabImageProperties",
activate: true,
},
{
// BasicProperties
title: t("basic_properties.basic_properties"),
icon: "bx bx-slider",
content: BasicPropertiesTab,
show: ({note}) => !note?.isLaunchBarConfig(),
toggleCommand: "toggleRibbonTabBasicProperties"
},
{
title: t("owned_attribute_list.owned_attributes"),
icon: "bx bx-list-check",
content: OwnedAttributesTab,
show: ({note}) => !note?.isLaunchBarConfig(),
toggleCommand: "toggleRibbonTabOwnedAttributes",
stayInDom: true
},
{
title: t("inherited_attribute_list.title"),
icon: "bx bx-list-plus",
content: InheritedAttributesTab,
show: ({note}) => !note?.isLaunchBarConfig(),
toggleCommand: "toggleRibbonTabInheritedAttributes"
},
{
title: t("note_paths.title"),
icon: "bx bx-collection",
content: NotePathsTab,
show: true,
toggleCommand: "toggleRibbonTabNotePaths"
},
{
title: t("note_map.title"),
icon: "bx bxs-network-chart",
content: NoteMapTab,
show: true,
toggleCommand: "toggleRibbonTabNoteMap"
},
{
title: t("similar_notes.title"),
icon: "bx bx-bar-chart",
show: ({ note }) => note?.type !== "search" && !note?.isLabelTruthy("similarNotesWidgetDisabled"),
content: SimilarNotesTab,
toggleCommand: "toggleRibbonTabSimilarNotes"
},
{
title: t("note_info_widget.title"),
icon: "bx bx-info-circle",
show: ({ note }) => !!note,
content: NoteInfoTab,
toggleCommand: "toggleRibbonTabNoteInfo"
}
]);
const TAB_CONFIGURATION = numberObjectsInPlace<TabConfiguration>(RIBBON_TAB_DEFINITIONS);
export default function Ribbon() {
const { note, ntxId, hoistedNoteId, notePath, noteContext, componentId } = useNoteContext();

View File

@@ -0,0 +1,134 @@
import ScriptTab from "./ScriptTab";
import EditedNotesTab from "./EditedNotesTab";
import NotePropertiesTab from "./NotePropertiesTab";
import NoteInfoTab from "./NoteInfoTab";
import SimilarNotesTab from "./SimilarNotesTab";
import FilePropertiesTab from "./FilePropertiesTab";
import ImagePropertiesTab from "./ImagePropertiesTab";
import NotePathsTab from "./NotePathsTab";
import NoteMapTab from "./NoteMapTab";
import OwnedAttributesTab from "./OwnedAttributesTab";
import InheritedAttributesTab from "./InheritedAttributesTab";
import CollectionPropertiesTab from "./CollectionPropertiesTab";
import SearchDefinitionTab from "./SearchDefinitionTab";
import BasicPropertiesTab from "./BasicPropertiesTab";
import FormattingToolbar from "./FormattingToolbar";
import options from "../../services/options";
import { t } from "../../services/i18n";
import { TabConfiguration } from "./ribbon-interface";
export const RIBBON_TAB_DEFINITIONS: TabConfiguration[] = [
{
title: t("classic_editor_toolbar.title"),
icon: "bx bx-text",
show: ({ note }) => note?.type === "text" && options.get("textNoteEditorType") === "ckeditor-classic",
toggleCommand: "toggleRibbonTabClassicEditor",
content: FormattingToolbar,
activate: true,
stayInDom: true
},
{
title: ({ note }) => note?.isTriliumSqlite() ? t("script_executor.query") : t("script_executor.script"),
icon: "bx bx-play",
content: ScriptTab,
activate: true,
show: ({ note }) => note &&
(note.isTriliumScript() || note.isTriliumSqlite()) &&
(note.hasLabel("executeDescription") || note.hasLabel("executeButton"))
},
{
title: t("search_definition.search_parameters"),
icon: "bx bx-search",
content: SearchDefinitionTab,
activate: true,
show: ({ note }) => note?.type === "search"
},
{
title: t("edited_notes.title"),
icon: "bx bx-calendar-edit",
content: EditedNotesTab,
show: ({ note }) => note?.hasOwnedLabel("dateNote"),
activate: ({ note }) => (note?.getPromotedDefinitionAttributes().length === 0 || !options.is("promotedAttributesOpenInRibbon")) && options.is("editedNotesOpenInRibbon")
},
{
title: t("book_properties.book_properties"),
icon: "bx bx-book",
content: CollectionPropertiesTab,
show: ({ note }) => note?.type === "book" || note?.type === "search",
toggleCommand: "toggleRibbonTabBookProperties"
},
{
title: t("note_properties.info"),
icon: "bx bx-info-square",
content: NotePropertiesTab,
show: ({ note }) => !!note?.getLabelValue("pageUrl"),
activate: true
},
{
title: t("file_properties.title"),
icon: "bx bx-file",
content: FilePropertiesTab,
show: ({ note }) => note?.type === "file",
toggleCommand: "toggleRibbonTabFileProperties",
activate: ({ note }) => note?.mime !== "application/pdf"
},
{
title: t("image_properties.title"),
icon: "bx bx-image",
content: ImagePropertiesTab,
show: ({ note }) => note?.type === "image",
toggleCommand: "toggleRibbonTabImageProperties",
activate: true,
},
{
// BasicProperties
title: t("basic_properties.basic_properties"),
icon: "bx bx-slider",
content: BasicPropertiesTab,
show: ({note}) => !note?.isLaunchBarConfig(),
toggleCommand: "toggleRibbonTabBasicProperties"
},
{
title: t("owned_attribute_list.owned_attributes"),
icon: "bx bx-list-check",
content: OwnedAttributesTab,
show: ({note}) => !note?.isLaunchBarConfig(),
toggleCommand: "toggleRibbonTabOwnedAttributes",
stayInDom: true
},
{
title: t("inherited_attribute_list.title"),
icon: "bx bx-list-plus",
content: InheritedAttributesTab,
show: ({note}) => !note?.isLaunchBarConfig(),
toggleCommand: "toggleRibbonTabInheritedAttributes"
},
{
title: t("note_paths.title"),
icon: "bx bx-collection",
content: NotePathsTab,
show: true,
toggleCommand: "toggleRibbonTabNotePaths"
},
{
title: t("note_map.title"),
icon: "bx bxs-network-chart",
content: NoteMapTab,
show: true,
toggleCommand: "toggleRibbonTabNoteMap"
},
{
title: t("similar_notes.title"),
icon: "bx bx-bar-chart",
show: ({ note }) => note?.type !== "search" && !note?.isLabelTruthy("similarNotesWidgetDisabled"),
content: SimilarNotesTab,
toggleCommand: "toggleRibbonTabSimilarNotes"
},
{
title: t("note_info_widget.title"),
icon: "bx bx-info-circle",
show: ({ note }) => !!note,
content: NoteInfoTab,
toggleCommand: "toggleRibbonTabNoteInfo"
}
];

View File

@@ -115,7 +115,7 @@ function SearchOption({ note, title, titleIcon, children, help, attributeName, a
additionalAttributesToDelete?: { type: "label" | "relation", name: string }[]
}) {
return (
<tr>
<tr className={attributeName}>
<td className="title-column">
{titleIcon && <><Icon icon={titleIcon} />{" "}</>}
{title}

View File

@@ -0,0 +1,174 @@
.search-setting-table {
margin-top: 0;
margin-bottom: 7px;
width: 100%;
border-collapse: separate;
border-spacing: 10px;
}
.search-setting-table div {
white-space: nowrap;
}
.search-setting-table .title-column {
/* minimal width so that table remains static sized and most space remains for middle column with settings */
width: 50px;
white-space: nowrap;
}
.search-setting-table .button-column {
/* minimal width so that table remains static sized and most space remains for middle column with settings */
width: 50px;
white-space: nowrap;
text-align: end;
vertical-align: middle;
}
.search-setting-table .button-column .dropdown {
display: inline-block !important;
}
.search-setting-table .button-column .dropdown-menu {
white-space: normal;
}
.search-setting-table .button-column > * {
vertical-align: middle;
}
.attribute-list hr {
height: 1px;
border-color: var(--main-border-color);
position: relative;
top: 4px;
margin-top: 5px;
margin-bottom: 0;
}
.search-definition-widget input:invalid {
border: 3px solid red;
}
.add-search-option button {
margin: 3px;
}
.dropdown-header {
background-color: var(--accented-background-color);
}
.search-actions-container {
display: flex;
justify-content: space-evenly;
}
body.mobile .search-definition-widget {
contain: none;
}
@media (max-width: 720px) {
.search-setting-table {
display: block;
font-size: 0.9em;
}
.search-setting-table tr {
padding: 0.5em 0;
border-bottom: 1px solid var(--main-border-color);
}
.search-setting-table tr,
.search-setting-table td {
display: block;
}
.search-setting-table tbody {
display: block;
padding: 0 1em;
}
.search-setting-table tbody:first-of-type {
display: block;
overflow: auto;
}
.search-setting-table .add-search-option {
display: flex;
}
.search-setting-table .add-search-option button {
font-size: 0.75em;
}
.search-options tr,
.action-options tr {
display: flex;
align-items: center;
}
.action-options tr > td > div {
flex-wrap: wrap;
gap: 0.5em 0;
}
.action-options input {
max-width: 75vw;
}
.search-setting-table .title-column {
width: unset;
margin-right: 0.5em;
min-width: 30%;
flex-shrink: 0;
}
.search-setting-table .button-column {
flex-grow: 1;
justify-content: end;
overflow: hidden;
flex-shrink: 0;
}
.search-setting-table .button-column .bx-help-circle {
display: none;
}
.search-setting-table tr.orderBy td:nth-of-type(2) {
display: flex;
flex-direction: column;
overflow: hidden;
gap: 0.5em;
}
.search-setting-table tr.searchString td:nth-of-type(2) {
flex-grow: 1;
}
.search-setting-table tr.searchString .button-column {
flex-grow: 0;
flex-shrink: 0;
width: 64px;
}
.search-setting-table tr.ancestor > td > div {
flex-direction: column;
align-items: flex-start !important;
}
.search-actions tr {
border-bottom: 0;
}
.search-actions-container {
align-items: center;
justify-content: center !important;
}
.search-result-widget,
.note-list.list-view,
.note-list-wrapper {
overflow: unset;
height: unset !important;
}
}

View File

@@ -20,8 +20,9 @@ import bulk_action, { ACTION_GROUPS } from "../../services/bulk_action";
import { FormListHeader, FormListItem } from "../react/FormList";
import RenameNoteBulkAction from "../bulk_actions/note/rename_note";
import { getErrorMessage } from "../../services/utils";
import "./SearchDefinitionTab.css";
export default function SearchDefinitionTab({ note, ntxId }: TabContext) {
export default function SearchDefinitionTab({ note, ntxId, hidden }: TabContext) {
const parentComponent = useContext(ParentComponent);
const [ searchOptions, setSearchOptions ] = useState<{ availableOptions: SearchOption[], activeOptions: SearchOption[] }>();
const [ error, setError ] = useState<{ message: string }>();
@@ -75,7 +76,7 @@ export default function SearchDefinitionTab({ note, ntxId }: TabContext) {
return (
<div className="search-definition-widget">
<div className="search-settings">
{note &&
{note && !hidden &&
<table className="search-setting-table">
<tbody>
<tr>
@@ -110,10 +111,10 @@ export default function SearchDefinitionTab({ note, ntxId }: TabContext) {
})}
</tbody>
<BulkActionsList note={note} />
<tbody>
<tbody className="search-actions">
<tr>
<td colSpan={3}>
<div style={{ display: "flex", justifyContent: "space-evenly" }}>
<div className="search-actions-container">
<Button
icon="bx bx-search"
text={t("search_definition.search_button")}

View File

@@ -0,0 +1,43 @@
import { ComponentChildren } from "preact";
import { useNoteContext } from "../../react/hooks";
import { TabContext, TitleContext } from "../ribbon-interface";
import { useEffect, useMemo, useState } from "preact/hooks";
import { RIBBON_TAB_DEFINITIONS } from "../RibbonDefinition";
interface StandaloneRibbonAdapterProps {
component: (props: TabContext) => ComponentChildren;
}
/**
* Takes in any ribbon tab component and renders it in standalone mod using the note context, thus requiring no inputs.
* Especially useful on mobile to detach components that would normally fit in the ribbon.
*/
export default function StandaloneRibbonAdapter({ component }: StandaloneRibbonAdapterProps) {
const Component = component;
const { note, ntxId, hoistedNoteId, notePath, noteContext, componentId } = useNoteContext();
const definition = useMemo(() => RIBBON_TAB_DEFINITIONS.find(def => def.content === component), [ component ]);
const [ shown, setShown ] = useState(unwrapShown(definition?.show, { note }));
useEffect(() => {
setShown(unwrapShown(definition?.show, { note }));
}, [ note ]);
return (
<Component
note={note}
hidden={!shown}
ntxId={ntxId}
hoistedNoteId={hoistedNoteId}
notePath={notePath}
noteContext={noteContext}
componentId={componentId}
activate={() => {}}
/>
);
}
function unwrapShown(value: boolean | ((context: TitleContext) => boolean | null | undefined) | undefined, context: TitleContext) {
if (!value) return true;
if (typeof value === "boolean") return value;
return !!value(context);
}

View File

@@ -1,5 +1,7 @@
import { KeyboardActionNames } from "@triliumnext/commons";
import NoteContext from "../../components/note_context";
import FNote from "../../entities/fnote";
import { VNode } from "preact";
export interface TabContext {
note: FNote | null | undefined;
@@ -11,3 +13,20 @@ export interface TabContext {
componentId: string;
activate(): void;
}
export interface TitleContext {
note: FNote | null | undefined;
}
export interface TabConfiguration {
title: string | ((context: TitleContext) => string);
icon: string;
content: (context: TabContext) => VNode | false;
show: boolean | ((context: TitleContext) => boolean | null | undefined);
toggleCommand?: KeyboardActionNames;
activate?: boolean | ((context: TitleContext) => boolean);
/**
* By default the tab content will not be rendered unless the tab is active (i.e. selected by the user). Setting to `true` will ensure that the tab is rendered even when inactive, for cases where the tab needs to be accessible at all times (e.g. for the detached editor toolbar) or if event handling is needed.
*/
stayInDom?: boolean;
}

View File

@@ -264,7 +264,6 @@
position: absolute;
inset-inline-end: 5px;
bottom: 5px;
z-index: 1000;
}
.style-resolver {
@@ -376,67 +375,6 @@ body[dir=rtl] .attribute-list-editor {
}
/* #endregion */
/* #region Search definition */
.search-setting-table {
margin-top: 0;
margin-bottom: 7px;
width: 100%;
border-collapse: separate;
border-spacing: 10px;
}
.search-setting-table div {
white-space: nowrap;
}
.search-setting-table .title-column {
/* minimal width so that table remains static sized and most space remains for middle column with settings */
width: 50px;
white-space: nowrap;
}
.search-setting-table .button-column {
/* minimal width so that table remains static sized and most space remains for middle column with settings */
width: 50px;
white-space: nowrap;
text-align: end;
vertical-align: middle;
}
.search-setting-table .button-column .dropdown {
display: inline-block !important;
}
.search-setting-table .button-column .dropdown-menu {
white-space: normal;
}
.search-setting-table .button-column > * {
vertical-align: middle;
}
.attribute-list hr {
height: 1px;
border-color: var(--main-border-color);
position: relative;
top: 4px;
margin-top: 5px;
margin-bottom: 0;
}
.search-definition-widget input:invalid {
border: 3px solid red;
}
.add-search-option button {
margin: 3px;
}
.dropdown-header {
background-color: var(--accented-background-color);
}
/* #endregion */
/* #region Note actions */
.note-actions {
width: 35px;

View File

@@ -329,6 +329,30 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
});
}
async addHtmlToEditor(html: string) {
await this.initialized;
const editor = this.watchdog.editor;
if (!editor) return;
editor.model.change((writer) => {
const viewFragment = editor.data.processor.toView(html);
const modelFragment = editor.data.toModel(viewFragment);
const insertPosition = editor.model.document.selection.getLastPosition();
if (insertPosition) {
const range = editor.model.insertContent(modelFragment, insertPosition);
if (range) {
writer.setSelection(range.end);
}
}
});
editor.editing.view.focus();
}
addTextToActiveEditorEvent({ text }: EventData<"addTextToActiveEditor">) {
if (!this.isActive()) {
return;
@@ -385,6 +409,10 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
this.triggerCommand("showAddLinkDialog", { textTypeWidget: this, text: selectedText });
}
pasteMarkdownIntoTextCommand() {
this.triggerCommand("showPasteMarkdownDialog", { textTypeWidget: this });
}
getSelectedText() {
const range = this.watchdog.editor?.model.document.selection.getFirstRange();
let text = "";

View File

@@ -2,7 +2,7 @@ import type { ComponentChildren } from "preact";
import { CSSProperties } from "preact/compat";
interface OptionsSectionProps {
title?: string;
title?: ComponentChildren;
children: ComponentChildren;
noCard?: boolean;
style?: CSSProperties;

View File

@@ -11,6 +11,7 @@ import dialog from "../../../services/dialog";
import { formatDateTime } from "../../../utils/formatters";
import ActionButton from "../../react/ActionButton";
import { useTriliumEvent } from "../../react/hooks";
import HelpButton from "../../react/HelpButton";
type RenameTokenCallback = (tokenId: string, oldName: string) => Promise<void>;
type DeleteTokenCallback = (tokenId: string, name: string ) => Promise<void>;
@@ -48,19 +49,13 @@ export default function EtapiSettings() {
message: t("etapi.token_created_message"),
defaultValue: authToken
});
}, []);
}, []);
return (
<OptionsSection title={t("etapi.title")}>
<FormText>
{t("etapi.description")}<br />
<RawHtml
html={t("etapi.see_more", {
link_to_wiki: `<a class="tn-link" href="https://triliumnext.github.io/Docs/Wiki/etapi.html">${t("etapi.wiki")}</a>`,
// TODO: We use window.open src/public/app/services/link.ts -> prevents regular click behavior on "a" element here because it's a relative path
link_to_openapi_spec: `<a class="tn-link" onclick="window.open('etapi/etapi.openapi.yaml')" href="etapi/etapi.openapi.yaml">${t("etapi.openapi_spec")}</a>`,
link_to_swagger_ui: `<a class="tn-link" href="#_help_f3xpgx6H01PW">${t("etapi.swagger_ui")}</a>`
})} />
{t("etapi.description")}
<HelpButton helpPage="pgxEVkzLl1OP" />
</FormText>
<Button
@@ -68,6 +63,7 @@ export default function EtapiSettings() {
text={t("etapi.create_token")}
onClick={createTokenCallback}
/>
<hr />
<h5>{t("etapi.existing_tokens")}</h5>
@@ -123,7 +119,7 @@ function TokenList({ tokens }: { tokens: EtapiToken[] }) {
text={t("etapi.rename_token")}
onClick={() => renameCallback(etapiTokenId, name)}
/>
<ActionButton
icon="bx bx-trash"
text={t("etapi.delete_token")}

View File

@@ -74,7 +74,6 @@ export default defineConfig(() => ({
mobile: join(__dirname, "src", "mobile.ts"),
login: join(__dirname, "src", "login.ts"),
setup: join(__dirname, "src", "setup.ts"),
share: join(__dirname, "src", "share.ts"),
set_password: join(__dirname, "src", "set_password.ts"),
runtime: join(__dirname, "src", "runtime.ts"),
print: join(__dirname, "src", "print.tsx")
@@ -84,7 +83,8 @@ export default defineConfig(() => ({
chunkFileNames: "src/[name].js",
assetFileNames: "src/[name].[ext]",
manualChunks: {
"ckeditor5": [ "@triliumnext/ckeditor5" ]
"ckeditor5": [ "@triliumnext/ckeditor5" ],
"boxicons": [ "../../node_modules/boxicons/css/boxicons.min.css" ]
},
},
onwarn(warning, rollupWarn) {

View File

@@ -6,7 +6,7 @@ WHERE powershell.exe > NUL 2>&1
IF %ERRORLEVEL% NEQ 0 GOTO BATCH ELSE GOTO POWERSHELL
:POWERSHELL
powershell -ExecutionPolicy Bypass -NonInteractive -NoLogo "Set-Item -Path Env:NODE_TLS_REJECT_UNAUTHORIZED -Value 0; ./trilium.exe"
powershell -ExecutionPolicy Bypass -NonInteractive -NoLogo -Command "Set-Item -Path Env:NODE_TLS_REJECT_UNAUTHORIZED -Value 0; ./trilium.exe"
GOTO END
:BATCH

View File

@@ -6,7 +6,7 @@ WHERE powershell.exe > NUL 2>&1
IF %ERRORLEVEL% NEQ 0 GOTO BATCH ELSE GOTO POWERSHELL
:POWERSHELL
powershell -ExecutionPolicy Bypass -NonInteractive -NoLogo "Set-Item -Path Env:TRILIUM_DATA_DIR -Value './trilium-data'; ./trilium.exe"
powershell -ExecutionPolicy Bypass -NonInteractive -NoLogo -Command "Set-Item -Path Env:TRILIUM_DATA_DIR -Value './trilium-data'; ./trilium.exe"
GOTO END
:BATCH

View File

@@ -6,7 +6,7 @@ WHERE powershell.exe > NUL 2>&1
IF %ERRORLEVEL% NEQ 0 GOTO BATCH ELSE GOTO POWERSHELL
:POWERSHELL
powershell -ExecutionPolicy Bypass -NonInteractive -NoLogo "Set-Item -Path Env:TRILIUM_SAFE_MODE -Value 1; ./trilium.exe --disable-gpu"
powershell -ExecutionPolicy Bypass -NonInteractive -NoLogo -Command "Set-Item -Path Env:TRILIUM_SAFE_MODE -Value 1; ./trilium.exe --disable-gpu"
GOTO END
:BATCH

View File

@@ -35,7 +35,7 @@
"@triliumnext/commons": "workspace:*",
"@triliumnext/server": "workspace:*",
"copy-webpack-plugin": "13.0.1",
"electron": "38.3.0",
"electron": "38.5.0",
"@electron-forge/cli": "7.10.2",
"@electron-forge/maker-deb": "7.10.2",
"@electron-forge/maker-dmg": "7.10.2",

View File

@@ -11,6 +11,7 @@ async function main() {
// Copy assets.
build.copy("src/assets", "assets/");
build.copy("/apps/server/src/assets", "assets/");
build.triggerBuildAndCopyTo("packages/share-theme", "share-theme/assets/");
build.copy("/packages/share-theme/src/templates", "share-theme/templates/");
// Copy node modules dependencies

View File

@@ -13,7 +13,7 @@
"devDependencies": {
"@types/better-sqlite3": "7.6.13",
"@types/mime-types": "3.0.1",
"@types/yargs": "17.0.33"
"@types/yargs": "17.0.34"
},
"scripts": {
"dev": "tsx src/main.ts",

View File

@@ -12,7 +12,7 @@
"@triliumnext/desktop": "workspace:*",
"@types/fs-extra": "11.0.4",
"copy-webpack-plugin": "13.0.1",
"electron": "38.3.0",
"electron": "38.5.0",
"fs-extra": "11.3.2"
},
"scripts": {

View File

@@ -6,7 +6,7 @@ import { initializeTranslations } from "@triliumnext/server/src/services/i18n.js
import debounce from "@triliumnext/client/src/services/debounce.js";
import { extractZip, importData, initializeDatabase, startElectron } from "./utils.js";
import cls from "@triliumnext/server/src/services/cls.js";
import type { AdvancedExportOptions } from "@triliumnext/server/src/services/export/zip.js";
import type { AdvancedExportOptions, ExportFormat } from "@triliumnext/server/src/services/export/zip/abstract_provider.js";
import { parseNoteMetaFile } from "@triliumnext/server/src/services/in_app_help.js";
import type NoteMeta from "@triliumnext/server/src/services/meta/note_meta.js";
@@ -23,6 +23,8 @@ if (!DOCS_ROOT || !USER_GUIDE_ROOT) {
throw new Error("Missing DOCS_ROOT or USER_GUIDE_ROOT environment variable.");
}
const BASE_URL = "https://docs.triliumnotes.org";
const NOTE_MAPPINGS: NoteMapping[] = [
{
rootNoteId: "pOsGYCXsbNQG",
@@ -75,7 +77,7 @@ async function setOptions() {
optionsService.setOption("compressImages", "false");
}
async function exportData(noteId: string, format: "html" | "markdown", outputPath: string, ignoredFiles?: Set<string>) {
async function exportData(noteId: string, format: ExportFormat, outputPath: string, ignoredFiles?: Set<string>) {
const zipFilePath = "output.zip";
try {
@@ -158,6 +160,14 @@ async function cleanUpMeta(outputPath: string, minify: boolean) {
}
el.isExpanded = false;
// Rewrite web view URLs that point to root.
if (el.type === "webView" && minify) {
const srcAttr = el.attributes.find(attr => attr.name === "webViewSrc");
if (srcAttr.value.startsWith("/")) {
srcAttr.value = BASE_URL + srcAttr.value;
}
}
}
if (minify) {

View File

@@ -1,4 +1,4 @@
FROM node:22.20.0-bullseye-slim AS builder
FROM node:24.11.0-bullseye-slim AS builder
RUN corepack enable
# Install native dependencies since we might be building cross-platform.
@@ -7,7 +7,7 @@ COPY ./docker/package.json ./docker/pnpm-workspace.yaml /usr/src/app/
# We have to use --no-frozen-lockfile due to CKEditor patches
RUN pnpm install --no-frozen-lockfile --prod && pnpm rebuild
FROM node:22.20.0-bullseye-slim
FROM node:24.11.0-bullseye-slim
# Install only runtime dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends \

View File

@@ -1,4 +1,4 @@
FROM node:22.20.0-alpine AS builder
FROM node:24.11.0-alpine AS builder
RUN corepack enable
# Install native dependencies since we might be building cross-platform.
@@ -7,7 +7,7 @@ COPY ./docker/package.json ./docker/pnpm-workspace.yaml /usr/src/app/
# We have to use --no-frozen-lockfile due to CKEditor patches
RUN pnpm install --no-frozen-lockfile --prod && pnpm rebuild
FROM node:22.20.0-alpine
FROM node:24.11.0-alpine
# Install runtime dependencies
RUN apk add --no-cache su-exec shadow

View File

@@ -1,4 +1,4 @@
FROM node:22.20.0-alpine AS builder
FROM node:24.11.0-alpine AS builder
RUN corepack enable
# Install native dependencies since we might be building cross-platform.
@@ -7,7 +7,7 @@ COPY ./docker/package.json ./docker/pnpm-workspace.yaml /usr/src/app/
# We have to use --no-frozen-lockfile due to CKEditor patches
RUN pnpm install --no-frozen-lockfile --prod && pnpm rebuild
FROM node:22.20.0-alpine
FROM node:24.11.0-alpine
# Create a non-root user with configurable UID/GID
ARG USER=trilium
ARG UID=1001

View File

@@ -0,0 +1,28 @@
FROM node:22.21.0-bullseye-slim AS builder
RUN corepack enable
# Install native dependencies since we might be building cross-platform.
WORKDIR /usr/src/app/build
COPY ./docker/package.json ./docker/pnpm-workspace.yaml /usr/src/app/
# We have to use --no-frozen-lockfile due to CKEditor patches
RUN pnpm install --no-frozen-lockfile --prod && pnpm rebuild
FROM node:22.21.0-bullseye-slim
# Install only runtime dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends \
gosu && \
rm -rf \
/var/lib/apt/lists/* \
/var/cache/apt/*
WORKDIR /usr/src/app
COPY ./dist /usr/src/app
RUN rm -rf /usr/src/app/node_modules/better-sqlite3
COPY --from=builder /usr/src/app/node_modules/better-sqlite3 /usr/src/app/node_modules/better-sqlite3
COPY ./start-docker.sh /usr/src/app
# Configure container
EXPOSE 8080
CMD [ "sh", "./start-docker.sh" ]
HEALTHCHECK --start-period=10s CMD exec gosu node node /usr/src/app/docker_healthcheck.cjs

View File

@@ -1,4 +1,4 @@
FROM node:22.20.0-bullseye-slim AS builder
FROM node:24.11.0-bullseye-slim AS builder
RUN corepack enable
# Install native dependencies since we might be building cross-platform.
@@ -7,7 +7,7 @@ COPY ./docker/package.json ./docker/pnpm-workspace.yaml /usr/src/app/
# We have to use --no-frozen-lockfile due to CKEditor patches
RUN pnpm install --no-frozen-lockfile --prod && pnpm rebuild
FROM node:22.20.0-bullseye-slim
FROM node:24.11.0-bullseye-slim
# Create a non-root user with configurable UID/GID
ARG USER=trilium
ARG UID=1001

View File

@@ -4,12 +4,12 @@ info:
title: ETAPI
description: External Trilium API
contact:
name: zadam
email: zadam.apps@gmail.com
url: https://github.com/zadam/trilium
name: Trilium Notes Team
email: contact@eliandoran.me
url: https://triliumnotes.org
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
name: GNU Affero General Public License v3.0 only
url: https://www.gnu.org/licenses/agpl-3.0.en.html
servers:
- url: http://localhost:37740/etapi
- url: http://localhost:8080/etapi

View File

@@ -1,7 +1,7 @@
openapi: 3.1.0
info:
title: Trilium Notes Internal API
version: 0.98.0
title: Internal Trilium API
version: 0.99.3
description: |
This is the internal API used by the Trilium Notes client application.
@@ -24,11 +24,12 @@ info:
State-changing operations require CSRF tokens when using session authentication.
contact:
name: TriliumNext Issue Tracker
url: https://github.com/TriliumNext/Trilium/issues
name: Trilium Notes Team
email: contact@eliandoran.me
url: https://triliumnotes.org
license:
name: GNU Affero General Public License v3.0
url: https://www.gnu.org/licenses/agpl-3.0.html
name: GNU Affero General Public License v3.0 only
url: https://www.gnu.org/licenses/agpl-3.0.en.html
servers:
- url: http://localhost:8080

View File

@@ -26,21 +26,23 @@
},
"dependencies": {
"better-sqlite3": "12.4.1",
"html-to-text": "9.0.5",
"node-html-parser": "7.0.1"
},
"devDependencies": {
"@anthropic-ai/sdk": "0.67.0",
"@anthropic-ai/sdk": "0.68.0",
"@braintree/sanitize-url": "7.1.1",
"@electron/remote": "2.1.3",
"@preact/preset-vite": "2.10.2",
"@triliumnext/commons": "workspace:*",
"@triliumnext/express-partial-content": "workspace:*",
"@triliumnext/highlightjs": "workspace:*",
"@triliumnext/turndown-plugin-gfm": "workspace:*",
"@types/archiver": "6.0.3",
"@types/archiver": "7.0.0",
"@types/better-sqlite3": "7.6.13",
"@types/cls-hooked": "4.3.9",
"@types/compression": "1.8.1",
"@types/cookie-parser": "1.4.9",
"@types/cookie-parser": "1.4.10",
"@types/debounce": "1.2.4",
"@types/ejs": "3.1.5",
"@types/escape-html": "1.0.4",
@@ -56,39 +58,37 @@
"@types/sanitize-html": "2.16.0",
"@types/sax": "1.2.7",
"@types/serve-favicon": "2.5.7",
"@types/serve-static": "1.15.9",
"@types/session-file-store": "1.2.5",
"@types/serve-static": "2.2.0",
"@types/stream-throttle": "0.1.4",
"@types/supertest": "6.0.3",
"@types/swagger-ui-express": "4.1.8",
"@types/tmp": "0.2.6",
"@types/turndown": "5.0.5",
"@types/turndown": "5.0.6",
"@types/ws": "8.18.1",
"@types/xml2js": "0.4.14",
"archiver": "7.0.1",
"async-mutex": "0.5.0",
"axios": "1.12.2",
"axios": "1.13.1",
"bindings": "1.5.0",
"bootstrap": "5.3.8",
"chardet": "2.1.0",
"chardet": "2.1.1",
"cheerio": "1.1.2",
"chokidar": "4.0.3",
"cls-hooked": "4.2.2",
"compression": "1.8.1",
"cookie-parser": "1.4.7",
"csrf-csrf": "3.2.2",
"dayjs": "1.11.18",
"dayjs": "1.11.19",
"debounce": "2.2.0",
"debug": "4.4.3",
"ejs": "3.1.10",
"electron": "38.3.0",
"electron": "38.5.0",
"electron-debug": "4.1.0",
"electron-window-state": "5.0.3",
"escape-html": "1.0.3",
"express": "5.1.0",
"express-http-proxy": "2.1.2",
"express-openid-connect": "2.19.2",
"express-rate-limit": "8.1.0",
"express-rate-limit": "8.2.1",
"express-session": "1.18.2",
"file-uri-to-path": "2.0.0",
"fs-extra": "11.3.2",
@@ -100,7 +100,7 @@
"i18next": "25.6.0",
"i18next-fs-backend": "2.6.0",
"image-type": "6.0.0",
"ini": "5.0.0",
"ini": "6.0.0",
"is-animated": "2.0.2",
"is-svg": "6.1.0",
"jimp": "1.6.0",
@@ -109,8 +109,8 @@
"mime-types": "3.0.1",
"multer": "2.0.2",
"normalize-strings": "1.1.1",
"ollama": "0.6.0",
"openai": "6.6.0",
"ollama": "0.6.2",
"openai": "6.7.0",
"rand-token": "1.0.1",
"safe-compare": "1.1.4",
"sanitize-filename": "1.6.3",
@@ -122,12 +122,11 @@
"striptags": "3.2.0",
"supertest": "7.1.4",
"swagger-jsdoc": "6.2.8",
"swagger-ui-express": "5.0.1",
"time2fa": "1.4.2",
"tmp": "0.2.5",
"turndown": "7.2.1",
"turndown": "7.2.2",
"unescape": "1.0.1",
"vite": "7.1.11",
"vite": "7.1.12",
"ws": "8.18.3",
"xml2js": "0.6.2",
"yauzl": "3.2.0"

View File

@@ -7,6 +7,7 @@ async function main() {
// Copy assets
build.copy("src/assets", "assets/");
build.triggerBuildAndCopyTo("packages/share-theme", "share-theme/assets/");
build.copy("/packages/share-theme/src/templates", "share-theme/templates/");
// Copy node modules dependencies

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More