Compare commits

...

641 Commits

Author SHA1 Message Date
perf3ct
72dbf7f31d feat(docs): try a "smarter" way of fetching the assets path
debug(docs): try something new for swagger ui

debug(docs): try something else for swagger ui

debug(docs): try something else for swagger ui, again

debug(docs): try something else for swagger ui, again again

Revert "debug(docs): try something else for swagger ui, again again"

This reverts commit 0f17a076282611c1305dc073c6fd513b6a0acbcc.

Revert "debug(docs): try something else for swagger ui, again"

This reverts commit dd9970b0b013ad940b9041979ea97a0a330aa500.

Revert "debug(docs): try something else for swagger ui"

This reverts commit ffbedbb60b80458fb094a7545c69a7b2c6691b35.

Revert "debug(docs): try something new for swagger ui"

This reverts commit 944f1dad2e1322a991563d1085ca6fb86b098da6.

asdf

asdfasdf

asdfasdfasdf
2025-07-11 20:29:05 +00:00
perf3ct
755254d037 feat(tests): create tests for swagger ui 2025-07-09 17:50:43 +00:00
perf3ct
7963f03e71 fix(docs): resolve incorrect dir path for swaggerui 2025-07-09 17:29:34 +00:00
Elian Doran
035b72a08d feat(insert_note): add dedicated section for collections 2025-07-09 18:55:08 +03:00
Elian Doran
fc4a595725 feat(insert_note): display on two columns 2025-07-09 18:37:09 +03:00
Elian Doran
444969bcf4 chore(deps): update dependency @types/node to v22.16.2 (#6267) 2025-07-09 08:47:37 +03:00
renovate[bot]
2cb6b14eca chore(deps): update dependency @types/node to v22.16.2 2025-07-09 05:23:39 +00:00
Elian Doran
468b5022a4 chore(deps): update dependency @types/express-serve-static-core to v5.0.7 (#6265) 2025-07-09 08:20:41 +03:00
Elian Doran
c1897563ca chore(deps): update dependency @types/leaflet to v1.9.20 (#6266) 2025-07-09 08:20:28 +03:00
Elian Doran
5e533896b9 chore(deps): update dependency openai to v5.8.3 (#6268) 2025-07-09 08:20:11 +03:00
Elian Doran
d3ceb7cfc1 chore(deps): update dependency vite to v7.0.3 (#6269) 2025-07-09 08:19:59 +03:00
Elian Doran
731f74f421 chore(deps): update dependency is-svg to v6.1.0 (#6270) 2025-07-09 08:19:40 +03:00
renovate[bot]
46d82651a3 chore(deps): update dependency is-svg to v6.1.0 2025-07-09 02:08:18 +00:00
renovate[bot]
b3108c7e2b chore(deps): update dependency vite to v7.0.3 2025-07-09 02:07:23 +00:00
renovate[bot]
0cb988470e chore(deps): update dependency openai to v5.8.3 2025-07-09 02:06:29 +00:00
renovate[bot]
5a030014b0 chore(deps): update dependency @types/leaflet to v1.9.20 2025-07-09 02:04:53 +00:00
renovate[bot]
2a43ef4dae chore(deps): update dependency @types/express-serve-static-core to v5.0.7 2025-07-09 02:04:03 +00:00
Elian Doran
6b5f9fc6ff Merge branch 'main' of https://github.com/TriliumNext/trilium 2025-07-08 22:33:44 +03:00
Elian Doran
b3a156c20d Update docker-compose.yml with new container image (#6263) 2025-07-08 21:33:51 +03:00
Elian Doran
24340d3a8e refactor(next): remove use of :has for performance reasons 2025-07-08 21:24:18 +03:00
Elian Doran
2fac2a8c5e chore(next): improve performance of a specific selector 2025-07-08 21:09:13 +03:00
Elian Doran
decb0c702d chore(nx): disable cache for rebuild-deps 2025-07-08 20:54:14 +03:00
Elian Doran
d45ff6cca5 fix(next): another non-performant CSS selector 2025-07-08 20:53:06 +03:00
DeveloperCrocodiles
83833e668c Update docker-compose.yml with new container image
Update docker-compose.yml to use the new container image triliumnext/trilium rather than triliumnext/notes.
2025-07-08 16:51:10 +01:00
Elian Doran
2cc181d1ac fix(tree): pasting in editor on middle click (closes #5812) 2025-07-08 15:51:19 +03:00
Elian Doran
a946ce3534 chore(deps): update dependency dotenv to v17.1.0 (#6255) 2025-07-08 09:05:40 +03:00
renovate[bot]
3e9f476b37 chore(deps): update dependency dotenv to v17.1.0 2025-07-08 05:21:18 +00:00
Elian Doran
de65c748a4 chore(deps): update dependency esbuild to v0.25.6 (#6249) 2025-07-08 08:18:57 +03:00
Elian Doran
8a2bfb9d7b chore(deps): update dependency supertest to v7.1.3 (#6250) 2025-07-08 08:18:20 +03:00
Elian Doran
a1ced31fea chore(deps): update dependency svelte to v5.35.4 (#6251) 2025-07-08 08:18:08 +03:00
Elian Doran
989a9f506e fix(deps): update dependency @electron/remote to v2.1.3 (#6252) 2025-07-08 08:17:58 +03:00
Elian Doran
59d55e2489 fix(deps): update dependency mermaid to v11.8.1 (#6253) 2025-07-08 08:17:47 +03:00
Elian Doran
2b312a9234 chore(deps): update typescript-eslint monorepo to v8.36.0 (#6256) 2025-07-08 08:17:31 +03:00
Elian Doran
16d9b982c2 chore(deps): update dependency dotenv to v17.1.0 (#6254) 2025-07-08 08:17:19 +03:00
renovate[bot]
a5600e75f5 chore(deps): update typescript-eslint monorepo to v8.36.0 2025-07-08 02:01:43 +00:00
renovate[bot]
f91dea62b6 chore(deps): update dependency dotenv to v17.1.0 2025-07-08 01:59:19 +00:00
renovate[bot]
4915ffcf2a fix(deps): update dependency mermaid to v11.8.1 2025-07-08 01:58:31 +00:00
renovate[bot]
9dbea2aa18 fix(deps): update dependency @electron/remote to v2.1.3 2025-07-08 01:57:38 +00:00
renovate[bot]
45f6a70fb8 chore(deps): update dependency svelte to v5.35.4 2025-07-08 01:56:42 +00:00
renovate[bot]
96b4c611cc chore(deps): update dependency supertest to v7.1.3 2025-07-08 01:55:48 +00:00
renovate[bot]
4e559d6594 chore(deps): update dependency esbuild to v0.25.6 2025-07-08 01:54:54 +00:00
Elian Doran
db1a599f95 fix(deps): update dependency mind-elixir to v5 (#6239) 2025-07-07 22:12:14 +03:00
Elian Doran
040964bbb7 chore(env): add variable for inspector 2025-07-07 22:10:07 +03:00
Elian Doran
dc6a303154 fix(mindmap): update deps to reintegrate features 2025-07-07 20:59:31 +03:00
Elian Doran
f88f14c983 Merge remote-tracking branch 'origin/main' into renovate/mind-elixir-5.x 2025-07-07 20:50:23 +03:00
Elian Doran
f870649256 Geomap improvements & conversion to book type (#6241) 2025-07-07 20:27:07 +03:00
Elian Doran
ed4dc30a6e refator(client): type error 2025-07-07 20:07:04 +03:00
Elian Doran
ce9010ff13 chore(client): add some documentation 2025-07-07 20:04:17 +03:00
Elian Doran
994e9fa852 docs(views/geomap): update user manual to reflect newly added features 2025-07-07 19:54:06 +03:00
Elian Doran
9df7d6227e Merge branch 'feature/geomap_collection' of https://github.com/TriliumNext/trilium into feature/geomap_collection 2025-07-07 19:20:24 +03:00
Elian Doran
242a576548 refactor(views/geomap): solve type errors 2025-07-07 19:15:38 +03:00
Elian Doran
c1a5808f37 feat(views/geomap): allow disabling editing 2025-07-07 19:04:47 +03:00
Elian Doran
5c6bb99d78 refactor(views/geomap): integrate drag into editing 2025-07-07 18:04:17 +03:00
Elian Doran
63c408c45b feat(views/geomap): dragging notes that are not children 2025-07-07 18:02:32 +03:00
Elian Doran
2a665dffbc feat(views/geomap): dragging notes that are children 2025-07-07 17:55:16 +03:00
Elian Doran
6509acd6ee feat(views/geomap): add open location to blank item as well 2025-07-07 17:24:42 +03:00
Elian Doran
4853d45609 chore(nix): switch to master for electron 37 (closes #6217) 2025-07-07 14:28:50 +03:00
Jon Fuller
fe78c1fee3 fix(api): implement better rate limiting controls for pre-auth endpoints (#6243) 2025-07-06 14:15:24 -07:00
Elian Doran
8102172557 feat(views/geomap): display geolocation in both context menus 2025-07-06 23:48:51 +03:00
Elian Doran
a1341e6036 feat(views/geomap): display geolocation in empty menu 2025-07-06 23:48:29 +03:00
Elian Doran
d31af2ddc2 feat(views/geomap): add a context menu for empty area 2025-07-06 23:34:07 +03:00
Elian Doran
a563330136 feat(import/zip): improve geomap compatibility 2025-07-06 23:05:21 +03:00
Elian Doran
a58e5789bc feat(import/zip): backward compatibility 2025-07-06 22:33:19 +03:00
Elian Doran
68e258f23b fix(views/geomap): unable to change note type to geomap 2025-07-06 22:32:24 +03:00
Elian Doran
dd18866156 refactor(server): convert to switch 2025-07-06 22:22:19 +03:00
Elian Doran
1b1f1957c3 chore(views/help): reintroduce help button 2025-07-06 22:11:03 +03:00
Elian Doran
ff6b4effbd fix(views/geomap): tooltip not showing 2025-07-06 21:29:42 +03:00
Elian Doran
06fa59239c chore(views/geomap): remove old files 2025-07-06 21:12:05 +03:00
Elian Doran
557bfbd1d6 feat(views/geomap): remove old geo map type 2025-07-06 20:23:50 +03:00
Elian Doran
f5a6dfa629 feat(views/geomap): migrate db to new collection type 2025-07-06 20:17:15 +03:00
Elian Doran
ce33dfb003 feat(views): delete duplicate attachments 2025-07-06 20:16:47 +03:00
Elian Doran
7b1c058d29 feat(views/geomap): add template 2025-07-06 19:21:53 +03:00
perf3ct
04c8f8a123 fix(api): implement better rate limiting controls for pre-auth endpoints 2025-07-06 16:19:08 +00:00
Elian Doran
d15fccb1d8 chore(views/geomap): integrate context menu options 2025-07-06 18:36:36 +03:00
Elian Doran
229dd9cd18 chore(views/geomap): integrate touchbar 2025-07-06 18:25:53 +03:00
Elian Doran
a4faaa406b fix(views/geomap): proper refresh 2025-07-06 17:54:13 +03:00
Elian Doran
b6d2de54b2 chore(views/geomap): reintroduce adding notes 2025-07-06 17:51:57 +03:00
Elian Doran
d5e81d77a2 refactor(views/geomap): move context menu 2025-07-06 12:28:24 +03:00
Elian Doran
939e99637f chore(views/geomap): reintroduce moving markers 2025-07-06 12:22:51 +03:00
Elian Doran
579a261612 chore(views/geomap): reintroduce display of tracks 2025-07-06 12:19:09 +03:00
Elian Doran
6d03304cbb chore(views/geomap): reintroduce display of markers 2025-07-06 12:12:59 +03:00
Elian Doran
b8d41b3421 chore(views/geomap): reintroduce viewport storage 2025-07-06 11:47:37 +03:00
Elian Doran
6a5bb1f5c8 chore(views/geomap): reintroduce map init 2025-07-06 11:36:59 +03:00
Elian Doran
cd742a4617 chore(views/geomap): basic initialization 2025-07-06 11:30:24 +03:00
Elian Doran
54063b97ad feat(views/geomap): display even if empty 2025-07-06 11:22:49 +03:00
Elian Doran
7abb67e737 feat(views/geomap): display in view type 2025-07-06 11:21:25 +03:00
Elian Doran
00fd1ba137 feat(views/geomap): make full-height 2025-07-06 11:15:28 +03:00
Elian Doran
7ea37b9eb9 feat(views/geomap): create empty view type 2025-07-06 11:13:17 +03:00
Elian Doran
b749de8fe1 fix(mind_map): styles no longer loading after major update 2025-07-06 10:08:45 +03:00
Elian Doran
8efef6842d Note Type Badges (#6229) 2025-07-06 09:54:27 +03:00
renovate[bot]
dc206f38d5 fix(deps): update dependency mind-elixir to v5 2025-07-06 01:15:10 +00:00
Elian Doran
29a00a6c0e Merge branch 'main' of github.com:TriliumNext/trilium 2025-07-05 22:31:08 +03:00
Elian Doran
fe678230a8 feat(webview): allow popups (closes #5698) 2025-07-05 22:31:04 +03:00
Adorian Doran
9cdbeb061f Merge branch 'main' of https://github.com/TriliumNext/Trilium into feat/context-menu/menu-items-badge-support 2025-07-05 22:06:39 +03:00
Adorian Doran
6c308f35c1 style(next)/badges: tweak appearance 2025-07-05 21:35:00 +03:00
Adorian Doran
34b89cf2e8 style/badges: tweak appearance 2025-07-05 20:46:45 +03:00
Elian Doran
b566a188dc chore(client): crash during serialization for CKEditor errors 2025-07-05 20:31:48 +03:00
Elian Doran
998432e236 chore(deps): update dependency @ckeditor/ckeditor5-package-tools to v4.0.1 (#6178) 2025-07-05 20:20:02 +03:00
Adorian Doran
1af8edfe4d client/note type chooser: add support for badges 2025-07-05 19:31:59 +03:00
Adorian Doran
5bf01106c5 client/context menus/insert note: refactor 2025-07-05 19:13:34 +03:00
Adorian Doran
a45289e385 client/context menus/insert note: fix a typo again 2025-07-05 18:54:22 +03:00
Adorian Doran
4ffd005b09 client/context menus/insert note: fix a typo 2025-07-05 18:53:40 +03:00
Adorian Doran
e6ca89fea8 client/context menus/insert note: fix a comment 2025-07-05 18:53:03 +03:00
Adorian Doran
2225aea756 client/context menus/insert note: fix a console log 2025-07-05 18:49:22 +03:00
Adorian Doran
bfc4a84020 client/context menus/insert note: avoid highlighting predefined templates as "new" 2025-07-05 18:46:52 +03:00
Elian Doran
5390bfdcab fix(help): ligatures in code causing confusion (closes #6224) 2025-07-05 18:32:55 +03:00
Elian Doran
301211ff41 chore(client): remove comment 2025-07-05 18:25:52 +03:00
renovate[bot]
64139e4e08 chore(deps): update dependency @ckeditor/ckeditor5-package-tools to v4.0.1 2025-07-05 15:22:56 +00:00
Elian Doran
e6485cde92 chore(deps): update dependency webdriverio to v9.16.2 (#6193) 2025-07-05 18:20:30 +03:00
Adorian Doran
891f6ba66f client/context menus/insert note: highlight new templates based on their creation date 2025-07-05 18:10:36 +03:00
Elian Doran
5d3c1e3fec chore(client,website): bypass issue with plugins 2025-07-05 17:58:36 +03:00
Elian Doran
087e755390 Revert "chore(client): bypass issue with plugins"
This reverts commit 025dc1ce75.
2025-07-05 17:48:53 +03:00
Elian Doran
025dc1ce75 chore(client): bypass issue with plugins 2025-07-05 17:44:54 +03:00
Elian Doran
703200338d Merge remote-tracking branch 'origin/main' into renovate/webdriverio-monorepo 2025-07-05 17:15:39 +03:00
Elian Doran
377c93ca0b chore(deps): update dependency @anthropic-ai/sdk to v0.56.0 (#6211) 2025-07-05 14:50:20 +03:00
renovate[bot]
69394ffe29 chore(deps): update dependency webdriverio to v9.16.2 2025-07-05 11:38:36 +00:00
renovate[bot]
f85231d74a chore(deps): update dependency @anthropic-ai/sdk to v0.56.0 2025-07-05 11:37:47 +00:00
Elian Doran
b93d8b0159 chore(deps): update dependency @types/tabulator-tables to v6.2.7 (#6220) 2025-07-05 10:16:45 +03:00
Elian Doran
67b9329903 chore(deps): update dependency vite to v7.0.2 (#6221) 2025-07-05 10:16:10 +03:00
Elian Doran
c0edd4ea4f fix(deps): update dependency i18next to v25.3.1 (#6222) 2025-07-05 10:15:41 +03:00
renovate[bot]
8eaf2786e8 fix(deps): update dependency i18next to v25.3.1 2025-07-05 02:42:27 +00:00
renovate[bot]
25622df464 chore(deps): update dependency vite to v7.0.2 2025-07-05 02:41:34 +00:00
renovate[bot]
a48900e178 chore(deps): update dependency @types/tabulator-tables to v6.2.7 2025-07-05 02:40:46 +00:00
Elian Doran
ac8b0535d2 Introduce the table view (#6097) 2025-07-04 23:34:34 +03:00
Elian Doran
6ce25a825b feat(help): link table note type 2025-07-04 23:19:33 +03:00
Elian Doran
b3f56851b8 docs(guide): document table functionality 2025-07-04 23:03:50 +03:00
Elian Doran
4b86fedce1 Merge remote-tracking branch 'origin/main' into feature/table_view
; Conflicts:
;	pnpm-lock.yaml
2025-07-04 21:47:26 +03:00
Elian Doran
1ebb70c4d2 fix(views/table): refresh when relation changes 2025-07-04 21:43:56 +03:00
Elian Doran
3de7b81be8 refactor(views/table): fix some type errors 2025-07-04 21:31:43 +03:00
Elian Doran
d08225339c style(views/table): reintroduce horizontal padding 2025-07-04 21:27:45 +03:00
Elian Doran
ba22d0706f chore(views/table): unnecessary code 2025-07-04 21:25:27 +03:00
Elian Doran
ef80f104c0 fix(views/table): scroll lost when updating data 2025-07-04 21:22:13 +03:00
Elian Doran
af296a1e4e refactor(views/table): split column & rows into separate file 2025-07-04 21:18:52 +03:00
Elian Doran
28a755306a feat(views/table): deduplicate columns 2025-07-04 21:15:10 +03:00
Elian Doran
461e085eff fix(views/table): column width or visibility lost after adding new column 2025-07-04 21:11:50 +03:00
Elian Doran
fbda049c32 fix(views/table): column context menu disappearing after update 2025-07-04 20:57:39 +03:00
Elian Doran
4ded5e2b98 feat(views/table): hide footer in search 2025-07-04 20:56:10 +03:00
Elian Doran
63537aff20 feat(views/table): disable reordering in search 2025-07-04 20:43:16 +03:00
Elian Doran
0f7a2adf15 feat(views/table): improve layout 2025-07-04 20:38:48 +03:00
Elian Doran
60963abe2c refactor(views/table): reduce duplication 2025-07-04 20:33:48 +03:00
Elian Doran
08cf95aa38 feat(views/table): merge open note and icon into title 2025-07-04 20:22:55 +03:00
Elian Doran
e5b10ab16a feat(views/table): set up relations not as a link 2025-07-04 20:08:41 +03:00
Elian Doran
7f5a1ee45a feat(ribbon): stop focusing book tab by default 2025-07-04 19:47:52 +03:00
Elian Doran
15c593f68e feat(views/table): automatically focus on title when creating new row 2025-07-04 19:46:37 +03:00
Elian Doran
5f8ef0395b feat(views/table): improve default layout 2025-07-04 19:37:05 +03:00
Elian Doran
513636e1e0 feat(views/table): hide column titles for small ones 2025-07-04 19:32:22 +03:00
Elian Doran
ae9b2c08a9 feat(views/table): hide context menu for small columns 2025-07-04 19:29:33 +03:00
Elian Doran
d5327b3b4a feat(views/table): get rid of note position column 2025-07-04 19:26:06 +03:00
Elian Doran
323e3d3cac feat(views/table): hide note ID by default 2025-07-04 19:25:08 +03:00
Elian Doran
01b2257063 feat(views/table): relocate new row/column buttons 2025-07-04 19:23:26 +03:00
Elian Doran
c69ef611a0 feat(views/table): basic reordering mechanism 2025-07-04 18:53:31 +03:00
Elian Doran
dcad23316d style(views/table): improve autocomplete styling 2025-07-04 18:26:24 +03:00
Elian Doran
e411f9932f feat(views/table): display note title when editing relation 2025-07-04 18:13:07 +03:00
Elian Doran
854969e1b8 feat(views/table): react to external attribute changes 2025-07-04 18:05:24 +03:00
Elian Doran
4ac7b6e9e8 feat(views/table): allow creation of new notes 2025-07-04 17:17:39 +03:00
Elian Doran
ac70908c5a feat(views/table): integrate reference-like for relations 2025-07-04 16:14:14 +03:00
Elian Doran
45ac70b78f feat(views/table): proper storage of relations 2025-07-04 15:07:40 +03:00
Elian Doran
a4664576fe feat(views/table): separate data model for relations 2025-07-04 15:05:00 +03:00
Elian Doran
b293643398 feat(views/table): basic formatter for relations 2025-07-04 15:02:10 +03:00
Elian Doran
a2e197facd feat(views/table): set up relation editor 2025-07-04 14:50:07 +03:00
Elian Doran
8614d39ef4 chore(views/table): remove unnecessary log 2025-07-04 14:42:04 +03:00
Elian Doran
6456bb34ae chore(views/table): start implementing a relation editor 2025-07-04 14:29:40 +03:00
Elian Doran
f5dc4de1c1 feat(views/table): parse relations 2025-07-04 14:12:36 +03:00
Adorian Doran
d869056910 client/note types mapping: add a way to highlight newly introduced types 2025-07-04 13:47:50 +03:00
Adorian Doran
821e4b17cb client/refactor: de-duplicate the note type mapping 2025-07-04 13:38:02 +03:00
Elian Doran
d8cb5efd2d Merge remote-tracking branch 'origin/main' into feature/table_view 2025-07-04 12:59:03 +03:00
Adorian Doran
f90e2fb484 client/tree context menu/insert note: mark the beta note types with a badge 2025-07-04 11:46:10 +03:00
Adorian Doran
2c9a7144da Merge branch 'main' of https://github.com/TriliumNext/Trilium into feat/context-menu/menu-items-badge-support 2025-07-04 11:36:43 +03:00
Adorian Doran
88d1af7210 style/refactor: make the current badge style to be global 2025-07-04 11:33:29 +03:00
Elian Doran
300e5a5528 chore(deps): update dependency svelte to v5.35.2 (#6209) 2025-07-04 09:36:34 +03:00
renovate[bot]
4418fefe4b chore(deps): update dependency svelte to v5.35.2 2025-07-04 06:15:18 +00:00
Elian Doran
fe5d1cac9a Feature/note map filter (#6104) 2025-07-04 09:12:20 +03:00
Elian Doran
49d17fff9b chore(deps): update dependency globals to v16.3.0 (#6190) 2025-07-04 09:11:53 +03:00
Elian Doran
557c6d2d8b chore(deps): update dependency stylelint to v16.21.1 (#6208) 2025-07-04 09:11:40 +03:00
Elian Doran
45fc62357d chore(deps): update dependency vite to v7.0.1 (#6210) 2025-07-04 09:11:26 +03:00
Elian Doran
840e3cc22f fix(deps): update dependency force-graph to v1.50.1 (#6212) 2025-07-04 09:11:16 +03:00
Elian Doran
c158c7fc88 fix(deps): update dependency mermaid to v11.8.0 (#6213) 2025-07-04 09:09:37 +03:00
renovate[bot]
bc6f8fc2dd fix(deps): update dependency mermaid to v11.8.0 2025-07-04 01:40:34 +00:00
renovate[bot]
117730acb2 fix(deps): update dependency force-graph to v1.50.1 2025-07-04 01:39:40 +00:00
renovate[bot]
595a7dac83 chore(deps): update dependency vite to v7.0.1 2025-07-04 01:38:08 +00:00
renovate[bot]
64a4d70df4 chore(deps): update dependency stylelint to v16.21.1 2025-07-04 01:36:34 +00:00
renovate[bot]
be36199fe1 chore(deps): update dependency globals to v16.3.0 2025-07-03 21:26:15 +00:00
Elian Doran
e46ad25677 Merge branch 'main' into feat/note-map-filter 2025-07-04 00:20:44 +03:00
Elian Doran
d5ee663922 Tree context menu: reorder the note types of "Insert (child) note..." (#6206) 2025-07-04 00:16:52 +03:00
Elian Doran
a7ab4be055 chore(deps): update vitest monorepo to v3.2.4 (#6186) 2025-07-03 23:39:37 +03:00
Elian Doran
6bbf29e75a Merge branch 'main' into renovate/vitest-monorepo 2025-07-03 23:39:08 +03:00
Adorian Doran
0a06c60cb7 client/context menus: add support to display badges for menu items 2025-07-03 23:27:02 +03:00
Adorian Doran
03658575eb client/context menu/insert note: reorder note types 2025-07-03 22:45:49 +03:00
Adorian Doran
38114bddb9 style(next)/ribbon/file & image properties: tweak the vertical alignment of properties 2025-07-03 21:36:37 +03:00
Adorian Doran
0711a197db style(next): tweak the "Delete notes preview" dialog width 2025-07-03 20:52:38 +03:00
Adorian Doran
f8f818b211 style(next): fix a performance-heavy selector 2025-07-03 20:00:46 +03:00
Elian Doran
988932209c chore(deps): update dependency svelte to v5.35.1 (#6192) 2025-07-03 11:53:59 +03:00
Elian Doran
2aa56cec30 chore(deps): update typescript-eslint monorepo to v8.35.1 (#6194) 2025-07-03 11:53:45 +03:00
renovate[bot]
93d493650c chore(deps): update typescript-eslint monorepo to v8.35.1 2025-07-03 08:25:21 +00:00
renovate[bot]
c6162ddcb4 chore(deps): update dependency svelte to v5.35.1 2025-07-03 08:24:09 +00:00
renovate[bot]
038517eda4 chore(deps): update vitest monorepo to v3.2.4 2025-07-03 08:23:31 +00:00
Elian Doran
30a9db73ab chore(deps): update dependency stylelint to v16.21.0 (#6191) 2025-07-03 11:21:09 +03:00
Elian Doran
a50aa41bdb fix(deps): update eslint monorepo to v9.30.1 (#6198) 2025-07-03 11:20:43 +03:00
renovate[bot]
cbb322fdb8 fix(deps): update eslint monorepo to v9.30.1 2025-07-03 06:23:39 +00:00
renovate[bot]
026e2a020d chore(deps): update dependency stylelint to v16.21.0 2025-07-03 06:20:49 +00:00
Elian Doran
07aab1d005 chore(deps): update ckeditor5 config packages to v11 (major) (#6199) 2025-07-03 09:14:38 +03:00
Elian Doran
26f0f7b188 fix(deps): update dependency tsx to v4.20.3 (#6197) 2025-07-03 09:13:57 +03:00
Elian Doran
1efde3b86b fix(deps): update dependency better-sqlite3 to v12.2.0 (#6196) 2025-07-03 09:13:23 +03:00
Elian Doran
8c1318f379 fix(deps): update dependency @inlang/paraglide-js to v2.2.0 (#6195) 2025-07-03 09:13:10 +03:00
Elian Doran
40e67e8e17 chore(deps): update dependency eslint-plugin-svelte to v3.10.1 (#6189) 2025-07-03 09:12:33 +03:00
Elian Doran
04466f52fd chore(deps): update dependency electron to v37.2.0 (#6188) 2025-07-03 09:11:59 +03:00
Elian Doran
06baa5fb57 chore(deps): update dependency @sveltejs/kit to v2.22.2 (#6187) 2025-07-03 09:11:23 +03:00
Elian Doran
04e1657628 chore(deps): update tailwindcss monorepo to v4.1.11 (#6185) 2025-07-03 09:10:31 +03:00
Elian Doran
7816c8cab0 chore(deps): update nx monorepo to v21.2.2 (#6184) 2025-07-03 09:10:18 +03:00
Elian Doran
6636e658a4 chore(deps): update dependency svelte-check to v4.2.2 (#6183) 2025-07-03 09:09:59 +03:00
Elian Doran
2a06f0daef chore(deps): update dependency lint-staged to v16.1.2 (#6182) 2025-07-03 09:09:43 +03:00
Elian Doran
883cfa588c chore(deps): update dependency dotenv to v17.0.1 (#6181) 2025-07-03 09:09:23 +03:00
Elian Doran
68011a0b5a Merge pull request #6180 from TriliumNext/renovate/mime-types-3.x-lockfile
chore(deps): update dependency @types/mime-types to v3.0.1
2025-07-03 09:08:59 +03:00
Elian Doran
5247d1a371 Merge pull request #6179 from TriliumNext/renovate/eslint-compat-1.x-lockfile
chore(deps): update dependency @eslint/compat to v1.3.1
2025-07-03 09:08:20 +03:00
renovate[bot]
cabdd528d4 chore(deps): update ckeditor5 config packages to v11 2025-07-03 00:19:09 +00:00
renovate[bot]
2bacbb796b fix(deps): update dependency tsx to v4.20.3 2025-07-03 00:17:08 +00:00
renovate[bot]
aa0ed6434a fix(deps): update dependency better-sqlite3 to v12.2.0 2025-07-03 00:16:25 +00:00
renovate[bot]
5b2215d646 fix(deps): update dependency @inlang/paraglide-js to v2.2.0 2025-07-03 00:15:46 +00:00
renovate[bot]
0e760e25f2 chore(deps): update dependency eslint-plugin-svelte to v3.10.1 2025-07-03 00:10:18 +00:00
renovate[bot]
acbb85b409 chore(deps): update dependency electron to v37.2.0 2025-07-03 00:09:29 +00:00
renovate[bot]
ea1d4b97ad chore(deps): update dependency @sveltejs/kit to v2.22.2 2025-07-03 00:08:38 +00:00
renovate[bot]
a81839c13f chore(deps): update tailwindcss monorepo to v4.1.11 2025-07-03 00:06:48 +00:00
renovate[bot]
b9d4668d4d chore(deps): update nx monorepo to v21.2.2 2025-07-03 00:05:55 +00:00
renovate[bot]
42b27f5965 chore(deps): update dependency svelte-check to v4.2.2 2025-07-03 00:05:03 +00:00
renovate[bot]
9cc8222b1c chore(deps): update dependency lint-staged to v16.1.2 2025-07-03 00:04:08 +00:00
renovate[bot]
e8479338df chore(deps): update dependency dotenv to v17.0.1 2025-07-03 00:03:19 +00:00
renovate[bot]
fa9e6c9fc0 chore(deps): update dependency @types/mime-types to v3.0.1 2025-07-03 00:02:32 +00:00
renovate[bot]
5366173b52 chore(deps): update dependency @eslint/compat to v1.3.1 2025-07-03 00:01:45 +00:00
Elian Doran
63520c55b3 Merge branch 'main' into feat/note-map-filter 2025-07-02 23:37:56 +03:00
Elian Doran
86f6d9b14a feat(export/zip): handle empty title for archive 2025-07-02 22:28:19 +03:00
Elian Doran
5270cf6284 feat(export/zip): handle empty notes for subtree 2025-07-02 22:28:03 +03:00
Elian Doran
4f46d81e1b fix(export/zip): missing note meta for empty file (closes #6146) 2025-07-02 21:59:58 +03:00
Elian Doran
294a2e6fdb feat(export/zip): improve error handling 2025-07-02 21:56:22 +03:00
Elian Doran
b20a8bc90b chore(backend_api): document week note behaviour 2025-07-02 21:41:12 +03:00
Elian Doran
68bdd1336f Merge pull request #6168 from TriliumNext/renovate/node-22.x
chore(deps): update dependency @types/node to v22.16.0
2025-07-02 20:35:02 +03:00
renovate[bot]
e62ccd932d chore(deps): update dependency @types/node to v22.16.0 2025-07-02 13:54:50 +00:00
Elian Doran
d6c188df6e Merge pull request #6170 from TriliumNext/renovate/i18next-25.x 2025-07-02 16:53:00 +03:00
Elian Doran
004000b5d2 Merge pull request #6171 from TriliumNext/renovate/eslint-monorepo 2025-07-02 16:52:25 +03:00
renovate[bot]
633c8a3444 fix(deps): update eslint monorepo to v9.30.1 2025-07-02 08:28:18 +00:00
renovate[bot]
2f59a20b6b fix(deps): update dependency i18next to v25.3.0 2025-07-02 08:27:21 +00:00
Elian Doran
593c435f75 Merge pull request #6172 from TriliumNext/renovate/multer-2.x
chore(deps): update dependency @types/multer to v2
2025-07-02 11:24:18 +03:00
Elian Doran
20ec45be57 Merge pull request #6169 from TriliumNext/renovate/globals-16.x
fix(deps): update dependency globals to v16.3.0
2025-07-02 11:23:17 +03:00
Elian Doran
d2a0e12409 Merge pull request #6167 from TriliumNext/renovate/fullcalendar-monorepo
fix(deps): update fullcalendar monorepo to v6.1.18
2025-07-02 11:22:51 +03:00
Elian Doran
33eebe117b Merge pull request #6166 from TriliumNext/renovate/eslint-linter-browserify-9.x
fix(deps): update dependency eslint-linter-browserify to v9.30.1
2025-07-02 11:22:29 +03:00
Elian Doran
ef0cfc2e7c Merge pull request #6165 from TriliumNext/renovate/dotenv-17.x
chore(deps): update dependency dotenv to v17.0.1
2025-07-02 11:22:07 +03:00
Elian Doran
b6e17ae543 Merge pull request #6164 from TriliumNext/renovate/playwright-monorepo
chore(deps): update dependency @playwright/test to v1.53.2
2025-07-02 11:21:51 +03:00
Elian Doran
8a33e2be89 Merge pull request #6163 from TriliumNext/renovate/anthropic-ai-sdk-0.x
chore(deps): update dependency @anthropic-ai/sdk to v0.55.1
2025-07-02 11:21:36 +03:00
renovate[bot]
5f91097987 chore(deps): update dependency @types/multer to v2 2025-07-02 02:56:29 +00:00
renovate[bot]
0fd4f02951 fix(deps): update dependency globals to v16.3.0 2025-07-02 02:52:17 +00:00
renovate[bot]
106e78ed62 fix(deps): update fullcalendar monorepo to v6.1.18 2025-07-02 02:47:34 +00:00
renovate[bot]
8855868b27 fix(deps): update dependency eslint-linter-browserify to v9.30.1 2025-07-02 02:46:36 +00:00
renovate[bot]
bfc3e8a907 chore(deps): update dependency dotenv to v17.0.1 2025-07-02 02:44:43 +00:00
renovate[bot]
154371e052 chore(deps): update dependency @playwright/test to v1.53.2 2025-07-02 02:43:47 +00:00
renovate[bot]
ab4a4d3d72 chore(deps): update dependency @anthropic-ai/sdk to v0.55.1 2025-07-02 02:42:29 +00:00
Elian Doran
5a4de02db7 Merge pull request #6105 from TriliumNext/renovate/ckeditor-monorepo
chore(deps): update dependency @ckeditor/ckeditor5-package-tools to v4.0.1
2025-07-01 22:22:05 +03:00
renovate[bot]
43cbc8c6e8 chore(deps): update dependency @ckeditor/ckeditor5-package-tools to v4.0.1 2025-07-01 19:09:31 +00:00
Elian Doran
5938aa7b50 Merge pull request #6110 from TriliumNext/renovate/openai-5.x
chore(deps): update dependency openai to v5.8.2
2025-07-01 22:06:06 +03:00
Elian Doran
a49252b2f5 Merge pull request #6121 from TriliumNext/renovate/codemirror
fix(deps): update dependency @codemirror/view to v6.38.0
2025-07-01 22:05:55 +03:00
Elian Doran
0be885d9bf Merge pull request #6123 from TriliumNext/renovate/eslint-linter-browserify-9.x
fix(deps): update dependency eslint-linter-browserify to v9.30.0
2025-07-01 22:05:14 +03:00
renovate[bot]
ae1e8353f2 fix(deps): update dependency eslint-linter-browserify to v9.30.0 2025-07-01 18:50:46 +00:00
renovate[bot]
98fe88581f fix(deps): update dependency @codemirror/view to v6.38.0 2025-07-01 18:49:50 +00:00
renovate[bot]
d66475576f chore(deps): update dependency openai to v5.8.2 2025-07-01 18:48:54 +00:00
Elian Doran
65ff7be776 Merge pull request #6093 from TriliumNext/renovate/vite-7.x
chore(deps): update dependency vite to v7
2025-07-01 21:31:57 +03:00
Elian Doran
190b079494 fix(website): typecheck dependency not well set 2025-07-01 21:30:59 +03:00
renovate[bot]
b020a30bd4 chore(deps): update dependency vite to v7 2025-07-01 18:08:46 +00:00
Elian Doran
81f8453c38 fix(client): type error due to use of intersection 2025-07-01 21:01:54 +03:00
Elian Doran
533e3cf42d Merge pull request #6125 from TriliumNext/renovate/eslint-monorepo
fix(deps): update eslint monorepo to v9.30.0
2025-07-01 20:55:26 +03:00
Elian Doran
69ee73492d Merge pull request #6142 from TriliumNext/renovate/rollup-plugin-webpack-stats-2.x
chore(deps): update dependency rollup-plugin-webpack-stats to v2.1.0
2025-07-01 20:55:16 +03:00
renovate[bot]
4a902d04b2 fix(deps): update eslint monorepo to v9.30.0 2025-07-01 17:18:00 +00:00
renovate[bot]
2e48e316c2 chore(deps): update dependency rollup-plugin-webpack-stats to v2.1.0 2025-07-01 17:16:31 +00:00
Elian Doran
bbe5dddb83 Merge pull request #6131 from TriliumNext/renovate/node-22.x
chore(deps): update dependency @types/node to v22.15.34
2025-07-01 20:14:23 +03:00
Elian Doran
7c943fe4ac chore(view/table): leftover files 2025-07-01 12:10:01 +03:00
Elian Doran
2cbb49681a fix(view/table): most type errors 2025-07-01 12:09:13 +03:00
Elian Doran
84db4ed57c docs(release): fix link 2025-07-01 11:56:05 +03:00
Elian Doran
e155642ce4 Merge remote-tracking branch 'origin/main' into feature/table_view 2025-07-01 11:55:45 +03:00
Elian Doran
87c4df60d3 Merge pull request #6126 from TriliumNext/renovate/major-ckeditor5-config-packages
chore(deps): update ckeditor5 config packages to v11 (major)
2025-07-01 11:45:01 +03:00
Elian Doran
ff412835e4 Merge pull request #6119 from TriliumNext/renovate/webdriverio-monorepo
chore(deps): update dependency webdriverio to v9.16.2
2025-07-01 11:44:39 +03:00
Elian Doran
ad15828157 Merge pull request #6111 from TriliumNext/renovate/svelte-5.x-lockfile
chore(deps): update dependency svelte to v5.34.9
2025-07-01 11:43:34 +03:00
renovate[bot]
b2fc7f934e chore(deps): update dependency @types/node to v22.15.34 2025-07-01 08:43:30 +00:00
Elian Doran
2fac4d91d6 Merge pull request #6112 from TriliumNext/renovate/svelte-check-4.x-lockfile
chore(deps): update dependency svelte-check to v4.2.2
2025-07-01 11:43:22 +03:00
Elian Doran
125cd96354 Merge pull request #6113 from TriliumNext/renovate/typedoc-0.x
chore(deps): update dependency typedoc to v0.28.7
2025-07-01 11:43:03 +03:00
Elian Doran
af02e6b714 Merge pull request #6116 from TriliumNext/renovate/dotenv-16.x-lockfile
chore(deps): update dependency dotenv to v16.6.1
2025-07-01 11:42:55 +03:00
Elian Doran
0c87b25244 Merge pull request #6117 from TriliumNext/renovate/eslint-plugin-svelte-3.x-lockfile
chore(deps): update dependency eslint-plugin-svelte to v3.10.1
2025-07-01 11:42:41 +03:00
Elian Doran
e87ada6e79 Merge pull request #6118 from TriliumNext/renovate/stylelint-16.x-lockfile
chore(deps): update dependency stylelint to v16.21.0
2025-07-01 11:42:33 +03:00
Elian Doran
282c8e58bd Merge pull request #6120 from TriliumNext/renovate/typescript-eslint-monorepo
chore(deps): update typescript-eslint monorepo to v8.35.1
2025-07-01 11:42:17 +03:00
Elian Doran
475b66b115 Merge pull request #6122 from TriliumNext/renovate/better-sqlite3-12.x-lockfile
fix(deps): update dependency better-sqlite3 to v12.2.0
2025-07-01 11:42:02 +03:00
Elian Doran
5bb971e61a Merge pull request #6124 from TriliumNext/renovate/tsx-4.x-lockfile
fix(deps): update dependency tsx to v4.20.3
2025-07-01 11:41:36 +03:00
Elian Doran
ebad9ba723 Merge pull request #6127 from TriliumNext/renovate/dotenv-17.x
chore(deps): update dependency dotenv to v17
2025-07-01 11:41:20 +03:00
Elian Doran
6ece2a839e Merge pull request #6128 from TriliumNext/renovate/marked-16.x
fix(deps): update dependency marked to v16
2025-07-01 11:40:55 +03:00
Elian Doran
8d6527fb75 Merge pull request #6132 from TriliumNext/renovate/ws-8.x
chore(deps): update dependency ws to v8.18.3
2025-07-01 11:40:27 +03:00
Elian Doran
6bfff38182 Merge pull request #6115 from TriliumNext/renovate/sveltejs-kit-2.x-lockfile
chore(deps): update dependency @sveltejs/kit to v2.22.2
2025-07-01 11:39:54 +03:00
Elian Doran
9e446717fa Merge pull request #6114 from TriliumNext/renovate/tailwindcss-monorepo
chore(deps): update tailwindcss monorepo to v4.1.11
2025-07-01 11:39:42 +03:00
Elian Doran
408b48f606 Merge pull request #6133 from TriliumNext/renovate/better-sqlite3-12.x
fix(deps): update dependency better-sqlite3 to v12.2.0
2025-07-01 11:39:32 +03:00
renovate[bot]
8d077ad46d chore(deps): update dependency dotenv to v17 2025-07-01 08:39:18 +00:00
Elian Doran
db72465e0b Merge pull request #6140 from TriliumNext/renovate/mind-elixir-4.x
fix(deps): update dependency mind-elixir to v4.6.2
2025-07-01 11:38:22 +03:00
Elian Doran
ba9f5e1688 Merge pull request #6141 from TriliumNext/renovate/eslint-stylistic-monorepo
chore(deps): update dependency @stylistic/eslint-plugin to v5.1.0
2025-07-01 11:37:57 +03:00
Elian Doran
caf40cd272 Merge pull request #6109 from TriliumNext/renovate/lint-staged-16.x-lockfile
chore(deps): update dependency lint-staged to v16.1.2
2025-07-01 11:37:02 +03:00
Elian Doran
3edccd224a Merge pull request #6107 from TriliumNext/renovate/mime-types-3.x-lockfile
chore(deps): update dependency @types/mime-types to v3.0.1
2025-07-01 11:36:28 +03:00
Elian Doran
f48931a969 Merge pull request #6106 from TriliumNext/renovate/eslint-compat-1.x-lockfile
chore(deps): update dependency @eslint/compat to v1.3.1
2025-07-01 11:36:12 +03:00
Elian Doran
84f23aa997 Merge pull request #6092 from TriliumNext/renovate/electron-37.x
chore(deps): update dependency electron to v37
2025-07-01 11:35:46 +03:00
Elian Doran
1965da6a85 docs(release): mention docker image changing 2025-07-01 10:15:10 +03:00
Elian Doran
57649d47ec fix(release): discussion category name 2025-07-01 10:13:35 +03:00
Elian Doran
089ae04542 chore(release): prepare for v0.96.0 2025-06-30 23:02:31 +03:00
renovate[bot]
441ae3e25b chore(deps): update typescript-eslint monorepo to v8.35.1 2025-06-30 18:35:19 +00:00
Elian Doran
1016f98867 docs(release): v0.96.0 2025-06-30 21:29:48 +03:00
Elian Doran
1f022aea4e chore(rebrand): update GitHub repo in source files 2025-06-30 20:39:29 +03:00
renovate[bot]
7f612711a0 chore(deps): update dependency typedoc to v0.28.7 2025-06-30 04:54:36 +00:00
renovate[bot]
92eb4aa822 chore(deps): update dependency @stylistic/eslint-plugin to v5.1.0 2025-06-30 01:36:17 +00:00
renovate[bot]
08ec522ae7 fix(deps): update dependency mind-elixir to v4.6.2 2025-06-30 01:36:11 +00:00
Elian Doran
c5cc1fcc1e feat(views/table): introduce hiding of columns 2025-06-29 22:26:25 +03:00
Elian Doran
cedf91ea1a chore(views/table): reintroduce column reordering 2025-06-29 16:56:34 +03:00
Elian Doran
51b462f043 chore(views/table): bring back restore state 2025-06-29 16:16:15 +03:00
Elian Doran
727eeb6c74 chore(views/table): bring back persistence 2025-06-29 16:08:27 +03:00
Elian Doran
a114fba062 chore(views/table): set up frozen columns 2025-06-29 15:11:09 +03:00
Elian Doran
cf322b5c2a chore(views/table): back to bootstrap5 theme 2025-06-29 10:09:39 +03:00
renovate[bot]
92116f1671 fix(deps): update dependency better-sqlite3 to v12.2.0 2025-06-29 00:37:40 +00:00
renovate[bot]
bc479248d7 chore(deps): update dependency ws to v8.18.3 2025-06-29 00:35:22 +00:00
Elian Doran
8ee12f2950 chore(views/table): bring back resizing columns 2025-06-28 23:50:54 +03:00
Elian Doran
dcea4c30ef chore(views/table): improve editing for date types 2025-06-28 23:33:52 +03:00
Elian Doran
e7ca56e061 chore(views/table): support more data types 2025-06-28 23:29:31 +03:00
Elian Doran
09b800b9ad chore(views/table): bring back editing attributes 2025-06-28 23:23:29 +03:00
Elian Doran
9a6a8580de chore(views/table): bring back editing title 2025-06-28 23:19:54 +03:00
Elian Doran
a31ac17792 chore(views/table): set row ID as index 2025-06-28 22:49:40 +03:00
Elian Doran
0e27cd0801 feat(views/table): add row number 2025-06-28 22:47:49 +03:00
Elian Doran
bc36676fa1 chore(views/table): disable sorting for note action button 2025-06-28 17:45:11 +03:00
Elian Doran
3d2db23f33 fix(views/table): use a more stable loading mechanism 2025-06-28 17:24:18 +03:00
Elian Doran
56d366a286 feat(views/table): add column to open note 2025-06-28 17:23:42 +03:00
Elian Doran
4a26f30d65 feat(views/table): render note icon 2025-06-28 17:07:11 +03:00
Elian Doran
8e51469de5 chore(views/table): re-enable sorting 2025-06-28 16:56:36 +03:00
Elian Doran
50ebcd552c fix(views/table): error when adding a new column 2025-06-28 16:51:24 +03:00
Elian Doran
ada39cd3c7 fix(views/table): error when adding a new row 2025-06-28 16:48:01 +03:00
Elian Doran
b2d20af51a fix(views/table): refreshing of columns 2025-06-28 16:39:24 +03:00
Elian Doran
f528fa25d1 feat(views/table): switch to bootstrap theme 2025-06-28 12:51:19 +03:00
Elian Doran
e09a7fb6e0 chore(views/table): reintroduce rows 2025-06-28 12:24:40 +03:00
Elian Doran
30f7939616 chore(views/table): reintroduce column definitions 2025-06-28 12:18:24 +03:00
Elian Doran
16b9375b9d chore(views/table): add types 2025-06-28 12:18:17 +03:00
Elian Doran
4ef93569a1 refactor(views/table): start switching to tabulator 2025-06-28 12:00:50 +03:00
renovate[bot]
1ce2aaeaf1 fix(deps): update dependency marked to v16 2025-06-28 02:47:26 +00:00
renovate[bot]
6bfe8dfcf0 chore(deps): update ckeditor5 config packages to v11 2025-06-28 02:45:32 +00:00
renovate[bot]
8d8f4795e2 fix(deps): update dependency tsx to v4.20.3 2025-06-28 02:42:36 +00:00
renovate[bot]
6f6d06377b fix(deps): update dependency better-sqlite3 to v12.1.1 2025-06-28 02:40:39 +00:00
renovate[bot]
f22823fcf6 chore(deps): update dependency webdriverio to v9.16.2 2025-06-28 02:37:40 +00:00
renovate[bot]
93ce57ee1a chore(deps): update dependency stylelint to v16.21.0 2025-06-28 02:36:39 +00:00
renovate[bot]
97dd747252 chore(deps): update dependency eslint-plugin-svelte to v3.10.1 2025-06-28 02:35:40 +00:00
renovate[bot]
bc8c136458 chore(deps): update dependency dotenv to v16.6.1 2025-06-28 02:34:42 +00:00
renovate[bot]
0774252dc1 chore(deps): update dependency @sveltejs/kit to v2.22.2 2025-06-28 02:33:38 +00:00
renovate[bot]
ae30ae4be6 chore(deps): update tailwindcss monorepo to v4.1.11 2025-06-28 02:32:27 +00:00
renovate[bot]
a2b8935763 chore(deps): update dependency svelte-check to v4.2.2 2025-06-28 02:31:19 +00:00
renovate[bot]
703efb74d3 chore(deps): update dependency svelte to v5.34.8 2025-06-28 02:30:18 +00:00
renovate[bot]
b2c6062e9a chore(deps): update dependency lint-staged to v16.1.2 2025-06-28 02:28:22 +00:00
renovate[bot]
c9e7e461b1 chore(deps): update dependency @types/mime-types to v3.0.1 2025-06-28 02:26:47 +00:00
renovate[bot]
6aaddfc5a4 chore(deps): update dependency @eslint/compat to v1.3.1 2025-06-28 02:25:51 +00:00
Elian Doran
7f2c41940d feat(views/table): add basic row creation mechanism 2025-06-28 00:07:14 +03:00
Elian Doran
d31ba39a91 feat(views/table): basic dark mode support 2025-06-27 23:40:00 +03:00
Elian Doran
c058673e33 feat(views/table): smooth column update 2025-06-27 23:01:15 +03:00
Elian Doran
44ce6a5169 feat(views/table): refresh on attribute change 2025-06-27 22:50:27 +03:00
Elian Doran
0fb0be4ffc feat(views/table): actually add attributes 2025-06-27 22:43:29 +03:00
Kieran
e70ba00929 docs(map): document relation filtering 2025-06-27 20:25:09 +01:00
Elian Doran
fe1dbb4cbf feat(views/table): display a dialog to add a new column 2025-06-27 22:19:09 +03:00
Kieran
31df2341c3 feat(map): add mapIncludeRelation and mapExcludeRelation to builtin_attributes 2025-06-27 20:18:28 +01:00
Kieran
9d99da14e1 feat(map): add mapIncludeRelation and mapExcludeRelation to include only or exclude specific relation types 2025-06-27 20:15:59 +01:00
Elian Doran
f8e10f36db refactor(note_list): use object for constructor arg 2025-06-27 21:51:38 +03:00
Elian Doran
bb0f384a39 feat(views/table): disable drag if sorted 2025-06-27 20:30:36 +03:00
Elian Doran
6a0b24f032 chore(views/table): remove logs 2025-06-27 20:08:41 +03:00
Elian Doran
80d5536503 feat(views/table): basic drag support 2025-06-27 19:53:40 +03:00
Elian Doran
9dcd79bd94 feat(views/table): add debouncing 2025-06-27 17:58:25 +03:00
Elian Doran
c5020b8884 refactor(views/table): move table view into its own folder 2025-06-27 17:44:29 +03:00
Elian Doran
0b74de275c refactor(views/table): integrate parser into data 2025-06-27 17:43:19 +03:00
Elian Doran
e66aef17df refactor(views/table): merge storage into table view 2025-06-27 17:40:56 +03:00
Elian Doran
19eff5e6d6 refactor(views/table): merge renderer into table view 2025-06-27 17:39:57 +03:00
Elian Doran
88b4fc73de chore(views/table): remove placeholder text 2025-06-27 17:22:47 +03:00
Elian Doran
70694542eb feat(views/table): allow in search 2025-06-27 17:18:52 +03:00
Elian Doran
360e5e3102 Merge remote-tracking branch 'origin/main' into feature/table_view 2025-06-27 17:08:23 +03:00
Elian Doran
06b507fdc5 Merge pull request #6085 from TriliumNext/renovate/ckeditor-monorepo
fix(deps): update ckeditor monorepo
2025-06-27 16:00:17 +03:00
Elian Doran
256ffe39f2 fix(server): saving revision of note with empty title not supported (closes #6103) 2025-06-27 14:22:08 +03:00
renovate[bot]
6e89a232e6 chore(deps): update dependency electron to v37 2025-06-27 06:48:15 +00:00
Elian Doran
45a3fb15e6 Merge pull request #6101 from TriliumNext/renovate/electron-36.x
chore(deps): update dependency electron to v36.6.0
2025-06-27 09:45:39 +03:00
renovate[bot]
4139a401e6 chore(deps): update dependency electron to v36.6.0 2025-06-27 06:30:28 +00:00
Elian Doran
4d617ccdb3 Merge pull request #6099 from TriliumNext/renovate/pnpm-10.x
chore(deps): update pnpm to v10.12.4
2025-06-27 09:28:51 +03:00
Elian Doran
57039ae8f2 Merge pull request #6102 from TriliumNext/renovate/openai-5.x
chore(deps): update dependency openai to v5.8.1
2025-06-27 09:28:26 +03:00
Elian Doran
9a4dcda985 Merge pull request #6100 from TriliumNext/renovate/dotenv-16.x
chore(deps): update dependency dotenv to v16.6.0
2025-06-27 09:27:59 +03:00
renovate[bot]
c13ae40ea4 chore(deps): update dependency openai to v5.8.1 2025-06-27 01:57:11 +00:00
renovate[bot]
0b963db405 chore(deps): update dependency dotenv to v16.6.0 2025-06-27 01:53:59 +00:00
renovate[bot]
78b946b208 chore(deps): update pnpm to v10.12.4 2025-06-27 01:51:41 +00:00
JYC333
4e8ddef915 Merge branch 'main' into renovate/ckeditor-monorepo 2025-06-26 23:17:52 +02:00
Elian Doran
0aa08cd297 Merge pull request #6091 from TriliumNext/renovate/node-22.x
chore(deps): update node.js to v22.17.0
2025-06-26 22:10:39 +03:00
Elian Doran
a89ce5d931 chore(rebrand): adjust artifact names 2025-06-26 20:18:31 +03:00
Elian Doran
fe3350f39f feat(server/script): enable a few dayjs plugins (closes #6080) 2025-06-26 20:13:01 +03:00
Elian Doran
f32f9d4326 test(server/script): dayjs is available 2025-06-26 18:34:00 +03:00
renovate[bot]
2ed24e8f9c fix(deps): update ckeditor monorepo 2025-06-26 08:48:14 +00:00
Elian Doran
537c282156 chore(renovate): mark premium features of ckeditor as group 2025-06-26 11:45:31 +03:00
renovate[bot]
61f253787a chore(deps): update node.js to v22.17.0 2025-06-26 06:52:50 +00:00
Elian Doran
ddad800771 Merge pull request #6090 from TriliumNext/renovate/eslint-monorepo
chore(deps): update eslint monorepo to v9.29.0
2025-06-26 09:48:47 +03:00
Elian Doran
69c24ef806 Merge pull request #6089 from TriliumNext/renovate/vite-plugin-static-copy-3.x
chore(deps): update dependency vite-plugin-static-copy to v3.1.0
2025-06-26 09:48:32 +03:00
Elian Doran
df7fe2bf13 Merge pull request #6088 from TriliumNext/renovate/anthropic-ai-sdk-0.x
chore(deps): update dependency @anthropic-ai/sdk to v0.55.0
2025-06-26 09:47:45 +03:00
Elian Doran
c47d3514be Merge pull request #6086 from TriliumNext/renovate/better-sqlite3-12.x
fix(deps): update dependency better-sqlite3 to v12.1.1
2025-06-26 09:47:25 +03:00
Elian Doran
2b979f46ab Merge pull request #6084 from TriliumNext/renovate/vitest-monorepo
chore(deps): update vitest monorepo to v3.2.4
2025-06-26 09:45:36 +03:00
Elian Doran
edc47eba05 Merge pull request #6083 from TriliumNext/renovate/pnpm-10.x
chore(deps): update pnpm to v10.12.3
2025-06-26 09:44:49 +03:00
Elian Doran
f3b46d6bc7 Merge pull request #6082 from TriliumNext/renovate/leaflet-1.x
chore(deps): update dependency @types/leaflet to v1.9.19
2025-06-26 09:44:26 +03:00
renovate[bot]
69d6d6a4fd chore(deps): update eslint monorepo to v9.29.0 2025-06-26 01:24:05 +00:00
renovate[bot]
5916b7d2a3 chore(deps): update dependency vite-plugin-static-copy to v3.1.0 2025-06-26 01:23:00 +00:00
renovate[bot]
fbb2c67edb chore(deps): update dependency @anthropic-ai/sdk to v0.55.0 2025-06-26 01:21:27 +00:00
renovate[bot]
7e1712712e fix(deps): update dependency better-sqlite3 to v12.1.1 2025-06-26 01:20:15 +00:00
renovate[bot]
aa846e9703 chore(deps): update vitest monorepo to v3.2.4 2025-06-26 01:18:54 +00:00
renovate[bot]
6ed9ec0851 chore(deps): update pnpm to v10.12.3 2025-06-26 01:18:05 +00:00
renovate[bot]
3a0a79119d chore(deps): update dependency @types/leaflet to v1.9.19 2025-06-26 01:14:26 +00:00
Elian Doran
ecd3b7039f feat(book/table): add template 2025-06-25 19:31:25 +03:00
Elian Doran
4a22e3d2d4 feat(book/table): hide promoted attributes 2025-06-25 19:25:01 +03:00
Elian Doran
dcb4ebe5d9 feat(book/table): display even if empty 2025-06-25 18:31:45 +03:00
Elian Doran
dd379bf18d refactor(book/table): fix some lack of generics 2025-06-25 18:30:44 +03:00
Elian Doran
c9b556160f feat(book/table): support changing note title 2025-06-25 17:56:47 +03:00
Elian Doran
168e224d3e refactor(book/table): make clear what kind of attribute is being changed 2025-06-25 17:54:00 +03:00
Elian Doran
9e57c14130 feat(attachments): add pretty formatting to JSON 2025-06-25 17:45:11 +03:00
Elian Doran
9c137a1c48 feat(book/table): display attachment JSON 2025-06-25 17:43:58 +03:00
Elian Doran
ccb9b7e5fb feat(book/table): store hidden columns 2025-06-25 16:18:34 +03:00
Elian Doran
c7b16cd043 feat(book/table): allow show/hide columns 2025-06-25 13:52:53 +03:00
Elian Doran
7e20e41521 feat(book/table): allow editing cell values 2025-06-25 13:06:38 +03:00
Elian Doran
66761a69d3 refactor(book/table): clean up 2025-06-25 12:10:08 +03:00
Elian Doran
fb32d26479 feat(book/table): support boolean type 2025-06-25 12:05:10 +03:00
Elian Doran
b6398fdb5d refactor(book/table): extract gathering definitions 2025-06-25 12:03:17 +03:00
Elian Doran
d9443527ee feat(book/table): support date type 2025-06-25 11:56:30 +03:00
Elian Doran
7c175da9f1 chore(book/table): ignore multi attributes 2025-06-25 11:45:46 +03:00
Elian Doran
05aa087851 feat(book/table): support basic text columns 2025-06-25 11:23:34 +03:00
Elian Doran
592e968f9f feat(book/table): display note titles 2025-06-25 11:06:49 +03:00
Elian Doran
894a26cc67 feat(book/table): set up sample grid 2025-06-25 10:49:33 +03:00
Elian Doran
1b5dd4638d chore(book/table): install ag-grid 2025-06-25 10:40:11 +03:00
Elian Doran
a19186c508 feat(book/table): set full height 2025-06-25 10:40:04 +03:00
Elian Doran
5450bdeae9 feat(book/table): hide no children warning 2025-06-25 10:34:03 +03:00
Elian Doran
fcd71957ff feat(book/table): create new view type 2025-06-25 10:31:41 +03:00
Elian Doran
1ff7228ca5 feat(scripts): add script to port discussions 2025-06-24 23:18:34 +03:00
Elian Doran
f0f79b65e2 Merge pull request #5860 from TriliumNext/renovate/openai-5.x
chore(deps): update dependency openai to v5.7.0
2025-06-24 09:06:32 +03:00
Elian Doran
63610fd579 chore(deps): sync package lock 2025-06-24 08:54:09 +03:00
Elian Doran
eab84bd34e Merge branch 'main' into renovate/openai-5.x 2025-06-24 08:52:59 +03:00
Elian Doran
72f4c40a8a Merge pull request #5862 from TriliumNext/renovate/better-sqlite3-12.x
fix(deps): update dependency better-sqlite3 to v12.1.0
2025-06-24 08:52:00 +03:00
Elian Doran
482356206b chore(deps): remove override 2025-06-24 08:51:41 +03:00
Elian Doran
5aa09fd881 Merge pull request #5861 from TriliumNext/renovate/typescript-eslint-monorepo
chore(deps): update typescript-eslint monorepo to v8.35.0
2025-06-24 08:50:14 +03:00
renovate[bot]
81f50c46ed fix(deps): update dependency better-sqlite3 to v12.1.0 2025-06-24 02:10:12 +00:00
renovate[bot]
938dfe7f38 chore(deps): update typescript-eslint monorepo to v8.35.0 2025-06-24 02:08:32 +00:00
renovate[bot]
ea71439f27 chore(deps): update dependency openai to v5.7.0 2025-06-24 02:04:04 +00:00
Elian Doran
9dc157b970 chore(options): use translations 2025-06-23 23:30:13 +03:00
Elian Doran
b7f5c0e07a feat(mention): disable auto-completion 2025-06-23 23:20:51 +03:00
Elian Doran
3988bb5321 feat(emoji): disable auto-completion only 2025-06-23 22:40:57 +03:00
Elian Doran
ba94616b87 feat(emoji): add an option to disable them (closes #5852) 2025-06-23 22:10:41 +03:00
Elian Doran
1ac086b88e fix(release): build on ubuntu-22.04 for compatibility 2025-06-23 15:33:37 +03:00
Elian Doran
3b4efef4f0 Merge pull request #5850 from TriliumNext/renovate/pnpm-10.x
chore(deps): update pnpm to v10.12.2
2025-06-23 14:08:43 +03:00
Elian Doran
9dc0807f78 Merge pull request #5851 from TriliumNext/renovate/major-eslint-stylistic-monorepo
chore(deps): update dependency @stylistic/eslint-plugin to v5
2025-06-23 14:08:04 +03:00
renovate[bot]
22783662c5 chore(deps): update dependency @stylistic/eslint-plugin to v5 2025-06-23 09:56:52 +00:00
renovate[bot]
64086592ef chore(deps): update pnpm to v10.12.2 2025-06-23 09:50:30 +00:00
Elian Doran
2bebed1b0f fix(desktop): share theme not loaded 2025-06-23 12:17:47 +03:00
Elian Doran
2262d300f7 e2e(desktop): sharing 2025-06-23 08:43:05 +03:00
Elian Doran
dba98d6fc1 test(desktop): test onboarding 2025-06-23 08:43:04 +03:00
Elian Doran
d8b85aad7c chore(rebrand): change product name 2025-06-23 08:43:04 +03:00
Elian Doran
5a3503c577 Merge pull request #5840 from TriliumNext/renovate/express-rate-limit-7.x
chore(deps): update dependency express-rate-limit to v7.5.1
2025-06-22 14:29:06 +03:00
Elian Doran
18c96cd2bc Merge branch 'main' into renovate/express-rate-limit-7.x 2025-06-22 14:12:21 +03:00
Elian Doran
b1bb1ed9af Merge pull request #5841 from TriliumNext/renovate/mermaid-js-layout-elk-0.x
fix(deps): update dependency @mermaid-js/layout-elk to v0.1.8
2025-06-22 14:11:44 +03:00
renovate[bot]
bc1ea98827 fix(deps): update dependency @mermaid-js/layout-elk to v0.1.8 2025-06-22 11:11:20 +00:00
Elian Doran
b984d612fd Merge pull request #5842 from TriliumNext/renovate/openai-5.x
chore(deps): update dependency openai to v5.6.0
2025-06-22 14:10:20 +03:00
Elian Doran
f53eecbf88 Merge pull request #5843 from TriliumNext/renovate/mermaid-11.x
fix(deps): update dependency mermaid to v11.7.0
2025-06-22 14:08:50 +03:00
Elian Doran
1a2c2dbfb8 Merge pull request #5844 from TriliumNext/renovate/better-sqlite3-12.x
fix(deps): update dependency better-sqlite3 to v12
2025-06-22 14:05:10 +03:00
renovate[bot]
78a0637283 fix(deps): update dependency better-sqlite3 to v12 2025-06-22 08:23:25 +00:00
renovate[bot]
e01858c86b fix(deps): update dependency mermaid to v11.7.0 2025-06-22 08:21:46 +00:00
renovate[bot]
ee080638be chore(deps): update dependency openai to v5.6.0 2025-06-22 08:20:13 +00:00
renovate[bot]
6db7ef415d chore(deps): update dependency express-rate-limit to v7.5.1 2025-06-22 08:15:35 +00:00
Elian Doran
cf171ff0b1 chore(ci): disable RelativeCI until project switch 2025-06-22 10:15:26 +03:00
Elian Doran
fdddc29092 fix(ci): don't run failing electron-based tests 2025-06-22 09:31:44 +03:00
Elian Doran
d6545e1280 Merge branch 'main' of https://github.com/TriliumNext/trilium 2025-06-22 09:17:57 +03:00
Elian Doran
759fe04e37 fix(docker): repository name 2025-06-22 09:17:50 +03:00
Elian Doran
e0c5f15480 Merge remote-tracking branch 'next/develop' 2025-06-21 23:21:48 +03:00
Elian Doran
f529cfd928 chore(i18n): update Spanish translation (#2371) 2025-06-21 23:18:28 +03:00
Elian Doran
2a1a099dc9 feat(scripts): add script used to migrate releases 2025-06-21 22:18:09 +03:00
hasecilu
26d0ba04ab chore(i18n): update Spanish translation 2025-06-21 11:19:57 -06:00
hasecilu
f85ef444f4 fix(script): paths on translation script 2025-06-21 11:19:55 -06:00
Elian Doran
87aa4422c0 chore(rebrand): change references from develop to main 2025-06-21 17:52:47 +03:00
Elian Doran
f497b71d37 chore(rebrand): change references from master to main 2025-06-21 17:51:34 +03:00
Elian Doran
24ba17b3f3 docs(readme): fix leftover merge marker 2025-06-21 17:24:06 +03:00
Elian Doran
e8cbce855e Merge remote-tracking branch 'old/develop' 2025-06-21 17:22:40 +03:00
Elian Doran
f97bd77117 Update README.md 2025-06-21 17:11:25 +03:00
Elian Doran
962066fd60 chore(scripts): add script used to port issues 2025-06-21 16:38:22 +03:00
Elian Doran
ff917e93c9 e2e(desktop): fix process leak 2025-06-21 14:28:57 +03:00
Elian Doran
a7091779b7 e2e(desktop): create empty project 2025-06-21 14:23:47 +03:00
Elian Doran
520b862551 Revert "feat(ci): experiment with building Windows on same runner"
This reverts commit ce305f0f45.
2025-06-21 14:18:41 +03:00
Elian Doran
5fbd34c7c1 Revert "chore(forge): add an arbitrary wait to see if it solves some CI errors"
This reverts commit 4f6729857b.
2025-06-21 14:18:36 +03:00
Elian Doran
c827b20e26 Revert "chore(forge): add a pre-make wait as well"
This reverts commit a150047432.
2025-06-21 14:18:31 +03:00
Elian Doran
a150047432 chore(forge): add a pre-make wait as well 2025-06-21 13:40:47 +03:00
Elian Doran
4f6729857b chore(forge): add an arbitrary wait to see if it solves some CI errors 2025-06-21 13:19:35 +03:00
Elian Doran
ce305f0f45 feat(ci): experiment with building Windows on same runner 2025-06-21 10:57:45 +03:00
Elian Doran
3a50ffede1 refactor(forge): add types to config 2025-06-21 10:46:12 +03:00
Elian Doran
41e88614d7 docs(guide): improve and update supported syntax for Markdown import 2025-06-21 09:49:26 +03:00
Elian Doran
002c567ae9 feat(ci): display trace if playwright fails in docker 2025-06-21 09:26:05 +03:00
Elian Doran
a9c07af402 fix(client): failing with duplicate modules 2025-06-21 09:00:07 +03:00
Elian Doran
3048c39877 Revert "chore(env): remove 4GB override"
This reverts commit 3280123414.
2025-06-21 01:20:41 +03:00
Elian Doran
a95dc14d24 test(import/zip): test silverbullet import 2025-06-21 01:09:03 +03:00
Elian Doran
24c82fa7b6 fix(import/zip): regression in normal import 2025-06-20 22:13:36 +03:00
Elian Doran
02a0624e8f feat(import/zip): support image with absolute path 2025-06-20 21:59:11 +03:00
Elian Doran
e6e276a0cf feat(import/markdown): support image via wikilink 2025-06-20 21:40:23 +03:00
Elian Doran
8d90231f76 fix(import/markdown): support wikilinks in other elements other than paragraphs 2025-06-20 21:00:39 +03:00
Elian Doran
4a40b22c9a feat(import/zip): support root-relative paths 2025-06-20 20:56:25 +03:00
Elian Doran
79b3b92ec9 chore(client): skip dynamic imports in cyclic check 2025-06-20 18:32:32 +03:00
Elian Doran
ae1a4fbbf6 fix(client): cyclic dependency server <-> ws 2025-06-20 18:32:20 +03:00
Elian Doran
3190aa6fe6 feat(import/markdown): start parsing wikilinks 2025-06-20 18:28:08 +03:00
Elian Doran
1c3cd9e7ca chore(deps): update vitest monorepo to v3.2.4 (#2364) 2025-06-20 15:52:42 +03:00
Elian Doran
c61713333d Merge remote-tracking branch 'origin/develop' into renovate/vitest-monorepo 2025-06-20 15:35:27 +03:00
Elian Doran
a861defbee feat(server): lint for trailing slashes in sync URL and extra slashes… (#2345) 2025-06-20 10:55:46 +03:00
Elian Doran
ea0b570910 chore(deps): update dependency @playwright/test to v1.53.1 (#2362) 2025-06-20 09:51:22 +03:00
renovate[bot]
8d46ab3806 chore(deps): update dependency @playwright/test to v1.53.1 2025-06-20 06:28:12 +00:00
Elian Doran
058b3f8241 chore(deps): update nx monorepo to v21.2.1 (#2363) 2025-06-20 08:27:22 +03:00
Elian Doran
57a688b6b6 fix(deps): update codemirror to v6.0.2 (#2365) 2025-06-20 08:26:16 +03:00
Elian Doran
ad18d853e2 chore(deps): update dependency electron to v36.5.0 (#2366) 2025-06-20 08:25:12 +03:00
renovate[bot]
8f5be936a7 chore(deps): update dependency electron to v36.5.0 2025-06-20 02:47:20 +00:00
renovate[bot]
f2c02f869e fix(deps): update codemirror to v6.0.2 2025-06-20 02:46:24 +00:00
renovate[bot]
cf28777119 chore(deps): update nx monorepo to v21.2.1 2025-06-20 02:43:32 +00:00
Elian Doran
cca8504796 refactor(client): circular dep in utils 2025-06-19 22:44:02 +03:00
Elian Doran
09391a92e5 refactor(client): circular dep: toast <-> ws 2025-06-19 22:29:44 +03:00
Elian Doran
50db8ef9c3 refactor(client): circular dependency in fnote 2025-06-19 22:23:17 +03:00
Elian Doran
8ab21f3bab chore(client): add tool to view circular deps 2025-06-19 22:03:01 +03:00
Elian Doran
efdf79feaa refactor(client): circular dependency causing test failure 2025-06-19 22:01:01 +03:00
Elian Doran
9418055b69 chore(test): fix imports 2025-06-19 21:30:42 +03:00
Elian Doran
5070633257 refactor(client): remove unnecessary files 2025-06-19 21:30:26 +03:00
Elian Doran
764917562e chore(test): fix set up 2025-06-19 21:30:10 +03:00
Elian Doran
54290a1373 chore(tsconfig): remove src for forge config 2025-06-19 21:01:23 +03:00
Elian Doran
0325bee425 feat(ckeditor): fallback to GPL if license key fails 2025-06-19 19:38:10 +03:00
Elian Doran
e280968271 feat(ckeditor): allow use of GPL license 2025-06-19 18:55:02 +03:00
Elian Doran
b809137c93 refactor(text): move license key management to config 2025-06-19 18:47:41 +03:00
Elian Doran
248f6d6a7d refactor(forge): switch to TypeScript 2025-06-19 15:45:39 +03:00
Elian Doran
0744a85421 feat(flake): handle StartupWMClass 2025-06-19 15:34:09 +03:00
Elian Doran
e5a6f53f98 Revert "feat(flake); set up overlay"
This reverts commit 751de1d43c.
2025-06-19 12:55:04 +03:00
Elian Doran
751de1d43c feat(flake); set up overlay 2025-06-19 12:49:26 +03:00
perf3ct
2704b1546b feat(server): fix lint type errors for normalizing server URLs 2025-06-18 21:07:12 +00:00
perf3ct
acd68817e9 feat(server): fix lint type errors for normalizing server URLs 2025-06-18 20:46:11 +00:00
Elian Doran
8b841c5aa7 feat(autocomplete): support specifying path when creating a new note (#2342) 2025-06-18 23:14:46 +03:00
Elian Doran
a37af29c6c fix(client): link to API documentation (#2356) 2025-06-18 23:10:00 +03:00
Elian Doran
ade0d4bb1a fix(website): update README.md instructions (#2357) 2025-06-18 23:08:56 +03:00
Arne Keller
d79c491777 fix(website): update README.md instructions 2025-06-18 19:08:24 +02:00
FliegendeWurst
f9cf542e66 fix(client): link to API documentation
Fixes https://github.com/TriliumNext/Notes/issues/1779
2025-06-18 17:58:29 +02:00
Elian Doran
609ed6274e fix(code): respect user font selection 2025-06-18 17:42:03 +03:00
Elian Doran
7faaefee20 feat(help): display contextual button text snippets 2025-06-18 15:35:56 +03:00
Elian Doran
578310a1c0 test(ckeditor5): add check for translation override 2025-06-18 14:44:56 +03:00
Elian Doran
93f544a221 feat(text-snippets): rewrite CKEditor translations 2025-06-18 13:13:59 +03:00
Elian Doran
9c80ab22af chore(client): use production ckeditor key for dev as well 2025-06-18 11:06:57 +03:00
Elian Doran
7decbc34c7 chore(deps): update dependency @types/node to v22.15.32 (#2347) 2025-06-18 11:02:07 +03:00
Elian Doran
e606276f19 chore(deps): update typescript-eslint monorepo to v8.34.1 (#2348) 2025-06-18 11:01:42 +03:00
SiriusXT
a78e4d7a58 chore(i18n): update path selection prompt 2025-06-18 14:28:43 +08:00
renovate[bot]
426c9a377a chore(deps): update typescript-eslint monorepo to v8.34.1 2025-06-18 06:16:35 +00:00
renovate[bot]
d2a3ae2a6f chore(deps): update dependency @types/node to v22.15.32 2025-06-18 06:15:35 +00:00
renovate[bot]
fbd6b7d22b chore(deps): update vitest monorepo to v3.2.4 2025-06-18 06:11:31 +00:00
Elian Doran
a42375931f chore(deps): update vitest monorepo to v3.2.4 (#2349) 2025-06-18 09:08:41 +03:00
Elian Doran
d894bff2a0 fix(deps): update dependency bootstrap to v5.3.7 (#2350) 2025-06-18 09:07:48 +03:00
Elian Doran
4515ed600c fix(deps): update dependency mind-elixir to v4.6.1 (#2351) 2025-06-18 09:07:10 +03:00
Elian Doran
4df3cdd975 chore(deps): update dependency openai to v5.5.1 (#2352) 2025-06-18 09:06:31 +03:00
SiriusXT
5fc0a0460d Merge branch 'develop' into note-create 2025-06-18 11:21:32 +08:00
renovate[bot]
74851a859b chore(deps): update dependency openai to v5.5.1 2025-06-18 02:56:07 +00:00
renovate[bot]
9bb94513ca fix(deps): update dependency mind-elixir to v4.6.1 2025-06-18 02:55:10 +00:00
renovate[bot]
bb74aa7976 fix(deps): update dependency bootstrap to v5.3.7 2025-06-18 02:54:19 +00:00
renovate[bot]
12318b38ee chore(deps): update vitest monorepo to v3.2.4 2025-06-18 02:53:25 +00:00
Jon Fuller
bb70c2a3fa Merge branch 'develop' into fix/lint-server-url 2025-06-17 16:00:36 -07:00
perf3ct
b47180a219 feat(server): create unit tests for normalizing server URL, and fix logic based on feedback 2025-06-17 21:32:27 +00:00
Elian Doran
4eb64357a1 chore(website): add macos screenshots 2025-06-17 23:39:25 +03:00
perf3ct
0fe89115d1 feat(server): lint for trailing slashes in sync URL and extra slashes in customRequestHandler 2025-06-17 19:37:40 +00:00
Elian Doran
330932adde fix(website): script errors due to double body 2025-06-17 22:08:34 +03:00
Elian Doran
b9daca5b9c website: favicon / dark mode / more content (#2343) 2025-06-17 21:38:24 +03:00
Elian Doran
c6c48d84ab flake: fix Electron version, fix Wayland support, fix source filter (#2329) 2025-06-17 21:33:45 +03:00
Elian Doran
2c87721953 docs(guide): premium features 2025-06-17 21:01:01 +03:00
Elian Doran
45a446d0f6 chore(text): set up production key 2025-06-17 20:55:38 +03:00
Elian Doran
40086434ec refactor(subtree): duplicate bx in icon name 2025-06-17 20:55:38 +03:00
Elian Doran
bde3f0a55c fix(nx): revert infinite watching causing severe issues with the daemon
See https://github.com/TriliumNext/Notes/pull/2285#issuecomment-2981118813
2025-06-17 20:55:37 +03:00
Elian Doran
9adae105e2 docs: regex search / Nix flake / restore dev docs (#2341) 2025-06-17 20:53:43 +03:00
Elian Doran
60dbf9dd67 Text snippets (#2344) 2025-06-17 19:29:53 +03:00
Elian Doran
374309a40c fix(templates): description displayed on separate lines 2025-06-17 19:21:21 +03:00
Elian Doran
dcccb5ad30 feat(builtin_templates): add icon for text snippets 2025-06-17 19:21:21 +03:00
Elian Doran
47eaee8b70 feat(builtin_templates): add description field for text snippets 2025-06-17 19:21:21 +03:00
Elian Doran
9687a9d8ff refactor(note_types): separate user templates into own method 2025-06-17 19:21:21 +03:00
Elian Doran
fa11295693 feat(templates): add support for built-in templates 2025-06-17 19:21:21 +03:00
Elian Doran
7e399cc10c feat(text-snippets): support description 2025-06-17 19:21:20 +03:00
Elian Doran
59e0857bb5 feat(text-snippets): add default icon for templates 2025-06-17 19:21:20 +03:00
Elian Doran
4f9bd970af feat(text-snippets): better reaction to removing templates 2025-06-17 19:21:20 +03:00
Elian Doran
3e40a35c19 feat(text-snippets): reload when a new template is added 2025-06-17 19:21:20 +03:00
Elian Doran
97799bfacc feat(text-snippets): handle renames by refreshing the editor 2025-06-17 19:21:20 +03:00
Elian Doran
fb1a74a96d feat(text-snippets): debounce updates to avoid duplication 2025-06-17 19:21:20 +03:00
Elian Doran
9f82e0a6d6 refactor(text-snippets): use a map instead of an object 2025-06-17 19:21:20 +03:00
Elian Doran
421e125882 feat(text-snippets): handle content changes 2025-06-17 19:21:20 +03:00
Elian Doran
17ede00fb2 feat(text-snippets): reload editors when templates change 2025-06-17 19:21:20 +03:00
Elian Doran
502638bae7 feat(text-snippets): add toolbar entry 2025-06-17 19:21:20 +03:00
Elian Doran
af8a905150 feat(text-snippets): basic integration 2025-06-17 19:21:20 +03:00
FliegendeWurst
6c2a228267 fix(website): feature block descriptions 2025-06-17 18:10:56 +02:00
FliegendeWurst
f9ecfd1ad0 feat(website): dark mode 2025-06-17 18:10:56 +02:00
FliegendeWurst
2c3cbcb1f9 website: refactor feature blocks, add more 2025-06-17 18:10:56 +02:00
FliegendeWurst
d1583ca091 fix(website): normal link styling 2025-06-17 18:10:56 +02:00
FliegendeWurst
3c21d97a8a fix(website): page titles 2025-06-17 18:10:56 +02:00
FliegendeWurst
8f7468cd60 website: link to distribution packages 2025-06-17 18:10:56 +02:00
FliegendeWurst
6668e639d5 fix(website): proper favicon 2025-06-17 18:10:56 +02:00
SiriusXT
bcc689cae3 Merge branch 'develop' into note-create 2025-06-17 21:18:06 +08:00
SiriusXT
20173d544b feat(autocomple): support specifying path when creating a new note 2025-06-17 20:41:23 +08:00
Arne Keller
e90d4cf86f docs: add section on Nix flake 2025-06-17 13:05:20 +02:00
Arne Keller
1de02b85b3 chore(docs): restore dev docs 2025-06-17 13:05:20 +02:00
FliegendeWurst
dab43d9372 docs: mention escaped backslashes in regex search 2025-06-17 13:05:20 +02:00
Elian Doran
3b579a3b7b Slash commands (#2336) 2025-06-17 12:49:26 +03:00
Elian Doran
a4a5e0bdf0 refactor(ckeditor5): class name 2025-06-16 23:52:16 +03:00
Elian Doran
9cb227c1ca fix(context menu): not auto-closing on mobile (#2331) 2025-06-16 23:49:41 +03:00
Elian Doran
c4c7321f60 fix(slash): layout on legacy theme 2025-06-16 23:06:34 +03:00
Elian Doran
cce27900b8 feat(slash): add a few aliases 2025-06-16 22:57:47 +03:00
Elian Doran
32f4d7be39 fix(slash): adding links not focusing box 2025-06-16 22:52:54 +03:00
Elian Doran
bbeb4e25f3 refactor(ckeditor): use vite environment variables for inspector 2025-06-16 22:01:05 +03:00
Elian Doran
88f78f3e32 feat(slash): better icons for admonitions 2025-06-16 21:42:31 +03:00
Adorian Doran
36581ba882 style(next)/dialogs/note type chooser: stop highlighting the default item 2025-06-16 21:30:34 +03:00
Elian Doran
1a64b3ce8e feat(slash): alignment 2025-06-16 21:21:42 +03:00
Elian Doran
32ee75ea43 feat(slash): markdown import 2025-06-16 21:14:46 +03:00
Elian Doran
06ebe0a9b3 feat(slash): include page break 2025-06-16 21:11:03 +03:00
Elian Doran
6069518749 feat(slash): include note 2025-06-16 20:58:42 +03:00
Elian Doran
c09a9aa7d3 feat(slash): insert math 2025-06-16 20:55:02 +03:00
Elian Doran
13afcb8a49 feat(slash): insert internal link 2025-06-16 20:48:01 +03:00
Elian Doran
9bfff03cff feat(slash): insert date/time 2025-06-16 20:42:55 +03:00
Adorian Doran
8780debc90 style(next)/dialogs/note type chooser: improve appearance 2025-06-16 20:31:57 +03:00
Elian Doran
6f386f50ff chore(slash): change title of admonitions 2025-06-16 20:22:37 +03:00
Elian Doran
43eff08004 feat(slash): insert footnote command 2025-06-16 20:21:54 +03:00
Elian Doran
3a0b616800 feat(slash): admonition types 2025-06-16 20:15:44 +03:00
Adorian Doran
cb65d02dc6 style(next)/quick search: avoid text shadow for the focused search result items 2025-06-16 20:11:38 +03:00
Adorian Doran
bef485c676 style: switch to the new link style 2025-06-16 20:01:41 +03:00
Adorian Doran
9e4d350848 style(next)/launcher calendar: fix the hover state for the month field 2025-06-16 19:46:20 +03:00
Adorian Doran
ccc7a8010e style(next)/combo box: properly handle the hover state when the dropdown arrow is not defined 2025-06-16 19:44:07 +03:00
Adorian Doran
7269c46de3 style(next): note attachments page: tweak header font size 2025-06-16 19:32:05 +03:00
Elian Doran
178df38377 chore(text): increase mention list max height 2025-06-16 19:25:06 +03:00
Elian Doran
1201f7138a style(next): slash commands layout 2025-06-16 19:24:42 +03:00
Elian Doran
9ff4be8871 feat(text): set up slash commands 2025-06-16 19:24:23 +03:00
Adorian Doran
0a17fb586c Merge branch 'develop' of https://github.com/TriliumNext/Notes into develop 2025-06-16 19:08:08 +03:00
Adorian Doran
1f8713f57e style(next): tweak the note icon selection button 2025-06-16 19:07:56 +03:00
Elian Doran
507fc17701 feat(text): set up license key for development 2025-06-16 18:38:06 +03:00
Elian Doran
26ad428b24 Merge branch 'jshprentz/develop' into develop 2025-06-16 17:51:22 +03:00
Elian Doran
26af3a9d68 Highlight Elixir in code notes (#2327) 2025-06-16 17:50:51 +03:00
Elian Doran
8ecf6ad78e feat(codemirror): add elixir support 2025-06-16 17:48:20 +03:00
SiriusXT
45977efd5f fix(context menu): not auto-closing on mobile 2025-06-16 17:21:44 +08:00
FliegendeWurst
c0b746e03f fix(desktop): proper icon path
The previous value points to a file that no longer exists in the
release builds. This file also only exists in the flake build.
2025-06-16 08:34:46 +02:00
FliegendeWurst
a13e4d5d79 fix(flake): set resourceDir explicitly 2025-06-16 08:28:44 +02:00
FliegendeWurst
e8f2f0f577 feat(flake): Wayland support 2025-06-16 08:08:04 +02:00
FliegendeWurst
f56ba7295a chore(flake): note differences to electron-forge build 2025-06-16 08:04:43 +02:00
FliegendeWurst
8cdb1859e3 fix(flake): use same Electron version as normal build
Also fix the source filtering logic to work properly.
2025-06-16 07:51:26 +02:00
Joel Shprentz
6bfc78e148 Merge branch 'develop' of https://github.com/jshprentz/TriliumNextNotes into develop 2025-06-16 02:28:50 +00:00
Joel Shprentz
cc97ec332d Codemirror does not support Elixir. Remove Elixir from the list. 2025-06-16 02:25:57 +00:00
Joel Shprentz
f2e4dad318 Merge branch 'TriliumNext:develop' into develop 2025-06-15 22:12:08 -04:00
Joel Shprentz
9c45e9fa1a Support highlighting Elixir code notes. 2025-06-16 01:54:31 +00:00
Elian Doran
e1e2afc3cd docs(release): sync description with GitHub 2025-06-16 00:14:52 +03:00
Elian Doran
8349204982 chore(docs): mention upcoming changes to branding 2025-06-05 09:03:57 +03:00
477 changed files with 15568 additions and 7468 deletions

1
.env Normal file
View File

@@ -0,0 +1 @@
NODE_OPTIONS=--max_old_space_size=4096

View File

@@ -85,7 +85,7 @@ runs:
APPLE_ID: ${{ env.APPLE_ID }}
APPLE_ID_PASSWORD: ${{ env.APPLE_ID_PASSWORD }}
WINDOWS_SIGN_EXECUTABLE: ${{ env.WINDOWS_SIGN_EXECUTABLE }}
TRILIUM_ARTIFACT_NAME_HINT: TriliumNextNotes-${{ github.ref_name }}-${{ inputs.os }}-${{ inputs.arch }}
TRILIUM_ARTIFACT_NAME_HINT: TriliumNotes-${{ github.ref_name }}-${{ inputs.os }}-${{ inputs.arch }}
run: pnpm nx --project=desktop electron-forge:make -- --arch=${{ inputs.arch }} --platform=${{ inputs.forge_platform }}
# Add DMG signing step

View File

@@ -30,4 +30,4 @@ runs:
mkdir -p upload
file=$(find ./apps/server/out -name '*.tar.xz' -print -quit)
name=${{ github.ref_name }}
cp "$file" "upload/TriliumNextNotes-Server-${name//\//-}-${{ inputs.os }}-${{ inputs.arch }}.tar.xz"
cp "$file" "upload/TriliumNotes-Server-${name//\//-}-${{ inputs.os }}-${{ inputs.arch }}.tar.xz"

View File

@@ -13,9 +13,9 @@ name: "CodeQL Advanced"
on:
push:
branches: [ "develop" ]
branches: [ "main" ]
pull_request:
branches: [ "develop" ]
branches: [ "main" ]
schedule:
- cron: '20 7 * * 0'

View File

@@ -1,9 +1,9 @@
name: Dev
on:
push:
branches: [ develop ]
branches: [ main ]
pull_request:
branches: [ develop ]
branches: [ main ]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -12,8 +12,8 @@ concurrency:
env:
GHCR_REGISTRY: ghcr.io
DOCKERHUB_REGISTRY: docker.io
IMAGE_NAME: ${{ github.repository_owner }}/notes
TEST_TAG: ${{ github.repository_owner }}/notes:test
IMAGE_NAME: ${{ github.repository}}
TEST_TAG: ${{ github.repository}}:test
permissions:
pull-requests: write # for PR comments
@@ -77,6 +77,7 @@ jobs:
- name: Trigger client build
run: pnpm nx run client:build
- name: Send client bundle stats to RelativeCI
if: false
uses: relative-ci/agent-action@v3
with:
webpackStatsFile: ./apps/client/dist/webpack-stats.json

View File

@@ -1,7 +1,7 @@
on:
push:
branches:
- "develop"
- "main"
- "feature/update**"
- "feature/server_esm**"
paths-ignore:
@@ -14,8 +14,8 @@ on:
env:
GHCR_REGISTRY: ghcr.io
DOCKERHUB_REGISTRY: docker.io
IMAGE_NAME: ${{ github.repository_owner }}/notes
TEST_TAG: ${{ github.repository_owner }}/notes:test
IMAGE_NAME: ${{ github.repository}}
TEST_TAG: ${{ github.repository}}:test
permissions:
contents: read
@@ -83,6 +83,14 @@ jobs:
- name: Run Playwright tests
run: TRILIUM_DOCKER=1 TRILIUM_PORT=8082 pnpm exec nx run server-e2e:e2e
- name: Upload Playwright trace
if: failure()
uses: actions/upload-artifact@v4
with:
name: Playwright trace (${{ matrix.dockerfile }})
path: test-output/playwright/output
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:

View File

@@ -12,7 +12,7 @@ on:
paths:
- .github/actions/build-electron/*
- .github/workflows/nightly.yml
- forge.config.cjs
- forge.config.ts
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -92,7 +92,7 @@ jobs:
uses: actions/upload-artifact@v4
if: ${{ github.event_name == 'pull_request' }}
with:
name: TriliumNextNotes ${{ matrix.os.name }} ${{ matrix.arch }}
name: TriliumNotes ${{ matrix.os.name }} ${{ matrix.arch }}
path: apps/desktop/upload
nightly-server:

View File

@@ -3,7 +3,7 @@ name: playwright
on:
push:
branches:
- master
- main
pull_request:
permissions:
@@ -40,4 +40,4 @@ jobs:
# - run: npx nx-cloud record -- echo Hello World
# Nx Affected runs only tasks affected by the changes in this PR/commit. Learn more: https://nx.dev/ci/features/affected
# When you enable task distribution, run the e2e-ci task instead of e2e
- run: pnpm exec nx affected -t e2e
- run: pnpm exec nx affected -t e2e --exclude desktop-e2e

View File

@@ -23,7 +23,7 @@ jobs:
shell: bash
forge_platform: darwin
- name: linux
image: ubuntu-latest
image: ubuntu-22.04
shell: bash
forge_platform: linux
- name: windows
@@ -120,7 +120,7 @@ jobs:
body_path: docs/Release Notes/Release Notes/${{ github.ref_name }}.md
fail_on_unmatched_files: true
files: upload/*.*
discussion_category_name: Announcements
discussion_category_name: Releases
make_latest: ${{ !contains(github.ref, 'rc') }}
prerelease: ${{ contains(github.ref, 'rc') }}
token: ${{ secrets.RELEASE_PAT }}

6
.gitignore vendored
View File

@@ -1,11 +1,5 @@
# See https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files for more about ignoring files.
# Workaround for Nx bug: parent .gitignore files with '*' can cause
# `nx show projects` to return nothing by ignoring subprojects.
# See: https://github.com/nrwl/nx/issues/27368
# Unignore everything to ensure Nx detects all projects
!*
# compiled output
dist
tmp

2
.nvmrc
View File

@@ -1 +1 @@
22.16.0
22.17.0

View File

@@ -1,4 +1,4 @@
# TriliumNext Notes
# Trilium Notes
![GitHub Sponsors](https://img.shields.io/github/sponsors/eliandoran?style=flat-square)
![Docker Pulls](https://img.shields.io/docker/pulls/triliumnext/notes?style=flat-square)
@@ -7,7 +7,7 @@
[English](./README.md) | [Chinese](./docs/README-ZH_CN.md) | [Russian](./docs/README.ru.md) | [Japanese](./docs/README.ja.md) | [Italian](./docs/README.it.md) | [Spanish](./docs/README.es.md)
TriliumNext Notes is a free and open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases.
Trilium Notes is a free and open-source, cross-platform hierarchical note taking application with focus on building large personal knowledge bases.
See [screenshots](https://triliumnext.github.io/Docs/Wiki/screenshot-tour) for quick overview:
@@ -153,7 +153,7 @@ Please view the [documentation guide](./docs/Developer%20Guide/Developer%20Guide
## 👏 Shoutouts
* [CKEditor 5](https://github.com/ckeditor/ckeditor5) - best WYSIWYG editor on the market, very interactive and listening team
* [FancyTree](https://github.com/mar10/fancytree) - very feature rich tree library without real competition. TriliumNext Notes would not be the same without it.
* [FancyTree](https://github.com/mar10/fancytree) - very feature rich tree library without real competition. Trilium Notes would not be the same without it.
* [CodeMirror](https://github.com/codemirror/CodeMirror) - code editor with support for huge amount of languages
* [jsPlumb](https://github.com/jsplumb/jsplumb) - visual connectivity library without competition. Used in [relation maps](https://triliumnext.github.io/Docs/Wiki/relation-map.html) and [link maps](https://triliumnext.github.io/Docs/Wiki/note-map.html#link-map)

View File

@@ -91,5 +91,5 @@ async function start() {
}
// @TriliumNextTODO sqlInit.dbReady never seems to resolve so program hangs
// see https://github.com/TriliumNext/Notes/issues/1020
// see https://github.com/TriliumNext/Trilium/issues/1020
sqlInit.dbReady.then(cls.wrap(start)).catch((err) => console.error(err));

View File

@@ -24,7 +24,7 @@ if ! git diff-index --quiet HEAD --; then
exit 1
fi
BASE_BRANCH=master
BASE_BRANCH=main
if [[ "$VERSION" == *"beta"* ]]; then
BASE_BRANCH=beta

View File

@@ -47,11 +47,3 @@ echo "Tagging commit with $TAG"
git tag $TAG
git push origin $TAG
echo "Updating master"
git fetch
git checkout master
git reset --hard origin/master
git merge origin/develop
git push

View File

@@ -25,15 +25,16 @@ stats() {
# Print the number of existing strings on the JSON files for each locale
s=$(number_of_keys "${paths[0]}/en/server.json")
c=$(number_of_keys "${paths[1]}/en/translation.json")
echo "| locale |server strings |client strings |"
echo "|--------|---------------|---------------|"
echo "| en | ${s} | ${c} |"
echo "| locale | server strings | client strings |"
echo "|--------|----------------|----------------|"
echo "| en | ${s} | ${c} |"
echo "|--------|----------------|----------------|"
for locale in "${locales[@]}"; do
s=$(number_of_keys "${paths[0]}/${locale}/server.json")
c=$(number_of_keys "${paths[1]}/${locale}/translation.json")
n1=$(((8 - ${#locale}) / 2))
n2=$((n1 == 1 ? n1 + 1 : n1))
echo "|$(printf "%${n1}s")${locale}$(printf "%${n2}s")| ${s} | ${c} |"
echo "|$(printf "%${n1}s")${locale}$(printf "%${n2}s")| ${s} | ${c} |"
done
}
@@ -78,7 +79,10 @@ file_path="$(
cd -- "$(dirname "${0}")" >/dev/null 2>&1 || exit
pwd -P
)"
paths=("${file_path}/../translations/" "${file_path}/../src/public/translations/")
paths=(
"${file_path}/../../apps/server/src/assets/translations/"
"${file_path}/../../apps/client/src/translations/"
)
locales=(cn de es fr pt_br ro tw)
if [ $# -eq 1 ]; then

View File

@@ -8,5 +8,5 @@ test("Displays update badge when there is a version available", async ({ page })
await page.getByText(`Version ${expectedVersion} is available,`).click();
const page1 = await page.waitForEvent("popup");
expect(page1.url()).toBe(`https://github.com/TriliumNext/Notes/releases/tag/v${expectedVersion}`);
expect(page1.url()).toBe(`https://github.com/TriliumNext/Trilium/releases/tag/v${expectedVersion}`);
});

View File

@@ -35,13 +35,13 @@
"chore:generate-openapi": "tsx bin/generate-openapi.js"
},
"devDependencies": {
"@playwright/test": "1.53.0",
"@stylistic/eslint-plugin": "4.4.1",
"@playwright/test": "1.53.2",
"@stylistic/eslint-plugin": "5.1.0",
"@types/express": "5.0.3",
"@types/node": "22.15.31",
"@types/node": "22.16.2",
"@types/yargs": "17.0.33",
"@vitest/coverage-v8": "3.2.3",
"eslint": "9.29.0",
"@vitest/coverage-v8": "3.2.4",
"eslint": "9.30.1",
"eslint-plugin-simple-import-sort": "12.1.1",
"esm": "3.2.25",
"jsdoc": "4.0.4",
@@ -49,7 +49,7 @@
"rcedit": "4.0.1",
"rimraf": "6.0.1",
"tslib": "2.8.1",
"typedoc": "0.28.5",
"typedoc": "0.28.7",
"typedoc-plugin-missing-exports": "4.0.0"
},
"optionalDependencies": {

5
apps/client/.env Normal file
View File

@@ -0,0 +1,5 @@
# The development license key for premium CKEditor features.
# Note: This key must only be used for the Trilium Notes project.
# Expires on: 2025-09-13
VITE_CKEDITOR_KEY=eyJhbGciOiJFUzI1NiJ9.eyJleHAiOjE3NTc3MjE1OTksImp0aSI6ImFiN2E0NjZmLWJlZGMtNDNiYy1iMzU4LTk0NGQ0YWJhY2I3ZiIsImRpc3RyaWJ1dGlvbkNoYW5uZWwiOlsic2giLCJkcnVwYWwiXSwid2hpdGVMYWJlbCI6dHJ1ZSwiZmVhdHVyZXMiOlsiRFJVUCIsIkNNVCIsIkRPIiwiRlAiLCJTQyIsIlRPQyIsIlRQTCIsIlBPRSIsIkNDIiwiTUYiLCJTRUUiLCJFQ0giLCJFSVMiXSwidmMiOiI1MzlkOWY5YyJ9.2rvKPql4hmukyXhEtWPZ8MLxKvzPIwzCdykO653g7IxRRZy2QJpeRszElZx9DakKYZKXekVRAwQKgHxwkgbE_w
VITE_CKEDITOR_ENABLE_INSPECTOR=false

View File

@@ -0,0 +1 @@
VITE_CKEDITOR_ENABLE_INSPECTOR=false

View File

@@ -1,25 +1,25 @@
{
"name": "@triliumnext/client",
"version": "0.95.0",
"version": "0.96.0",
"description": "JQuery-based client for TriliumNext, used for both web and desktop (via Electron)",
"private": true,
"license": "AGPL-3.0-only",
"author": {
"name": "TriliumNext Notes Team",
"name": "Trilium Notes Team",
"email": "contact@eliandoran.me",
"url": "https://github.com/TriliumNext/Notes"
},
"dependencies": {
"@eslint/js": "9.29.0",
"@eslint/js": "9.30.1",
"@excalidraw/excalidraw": "0.18.0",
"@fullcalendar/core": "6.1.17",
"@fullcalendar/daygrid": "6.1.17",
"@fullcalendar/interaction": "6.1.17",
"@fullcalendar/list": "6.1.17",
"@fullcalendar/multimonth": "6.1.17",
"@fullcalendar/timegrid": "6.1.17",
"@mermaid-js/layout-elk": "0.1.7",
"@mind-elixir/node-menu": "1.0.5",
"@fullcalendar/core": "6.1.18",
"@fullcalendar/daygrid": "6.1.18",
"@fullcalendar/interaction": "6.1.18",
"@fullcalendar/list": "6.1.18",
"@fullcalendar/multimonth": "6.1.18",
"@fullcalendar/timegrid": "6.1.18",
"@mermaid-js/layout-elk": "0.1.8",
"@mind-elixir/node-menu": "5.0.0",
"@popperjs/core": "2.11.8",
"@triliumnext/ckeditor5": "workspace:*",
"@triliumnext/codemirror": "workspace:*",
@@ -27,15 +27,15 @@
"@triliumnext/highlightjs": "workspace:*",
"@triliumnext/share-theme": "workspace:*",
"autocomplete.js": "0.38.1",
"bootstrap": "5.3.6",
"bootstrap": "5.3.7",
"boxicons": "2.1.4",
"dayjs": "1.11.13",
"dayjs-plugin-utc": "0.1.2",
"debounce": "2.2.0",
"draggabilly": "3.0.0",
"force-graph": "1.49.6",
"globals": "16.2.0",
"i18next": "25.2.1",
"force-graph": "1.50.1",
"globals": "16.3.0",
"i18next": "25.3.1",
"i18next-http-backend": "3.0.2",
"jquery": "3.7.1",
"jquery-hotkeys": "0.2.2",
@@ -46,27 +46,29 @@
"leaflet": "1.9.4",
"leaflet-gpx": "2.2.0",
"mark.js": "8.11.1",
"marked": "15.0.12",
"mermaid": "11.6.0",
"mind-elixir": "4.6.0",
"marked": "16.0.0",
"mermaid": "11.8.1",
"mind-elixir": "5.0.1",
"normalize.css": "8.0.1",
"panzoom": "9.4.3",
"preact": "10.26.9",
"split.js": "1.6.5",
"svg-pan-zoom": "3.6.2",
"tabulator-tables": "6.3.1",
"vanilla-js-wheel-zoom": "9.0.4"
},
"devDependencies": {
"@ckeditor/ckeditor5-inspector": "4.1.0",
"@types/bootstrap": "5.2.10",
"@types/jquery": "3.5.32",
"@types/leaflet": "1.9.18",
"@types/leaflet": "1.9.20",
"@types/leaflet-gpx": "1.3.7",
"@types/mark.js": "8.11.12",
"@types/tabulator-tables": "6.2.7",
"copy-webpack-plugin": "13.0.0",
"happy-dom": "18.0.1",
"script-loader": "0.7.2",
"vite-plugin-static-copy": "3.0.2"
"vite-plugin-static-copy": "3.1.0"
},
"nx": {
"name": "client",
@@ -75,6 +77,9 @@
"dependsOn": [
"^build"
]
},
"circular-deps": {
"command": "pnpx dpdm -T {projectRoot}/src/**/*.ts --tree=false --warning=false --skip-dynamic-imports=circular"
}
}
}

View File

@@ -1,424 +0,0 @@
/*
* Remove template code below
*/
html {
-webkit-text-size-adjust: 100%;
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
'Noto Color Emoji';
line-height: 1.5;
tab-size: 4;
scroll-behavior: smooth;
}
body {
font-family: inherit;
line-height: inherit;
margin: 0;
}
h1,
h2,
p,
pre {
margin: 0;
}
*,
::before,
::after {
box-sizing: border-box;
border-width: 0;
border-style: solid;
border-color: currentColor;
}
h1,
h2 {
font-size: inherit;
font-weight: inherit;
}
a {
color: inherit;
text-decoration: inherit;
}
pre {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
'Liberation Mono', 'Courier New', monospace;
}
svg {
display: block;
vertical-align: middle;
}
svg {
shape-rendering: auto;
text-rendering: optimizeLegibility;
}
pre {
background-color: rgba(55, 65, 81, 1);
border-radius: 0.25rem;
color: rgba(229, 231, 235, 1);
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
'Liberation Mono', 'Courier New', monospace;
overflow: scroll;
padding: 0.5rem 0.75rem;
}
.shadow {
box-shadow: 0 0 #0000, 0 0 #0000, 0 10px 15px -3px rgba(0, 0, 0, 0.1),
0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.rounded {
border-radius: 1.5rem;
}
.wrapper {
width: 100%;
}
.container {
margin-left: auto;
margin-right: auto;
max-width: 768px;
padding-bottom: 3rem;
padding-left: 1rem;
padding-right: 1rem;
color: rgba(55, 65, 81, 1);
width: 100%;
}
#welcome {
margin-top: 2.5rem;
}
#welcome h1 {
font-size: 3rem;
font-weight: 500;
letter-spacing: -0.025em;
line-height: 1;
}
#welcome span {
display: block;
font-size: 1.875rem;
font-weight: 300;
line-height: 2.25rem;
margin-bottom: 0.5rem;
}
#hero {
align-items: center;
background-color: hsla(214, 62%, 21%, 1);
border: none;
box-sizing: border-box;
color: rgba(55, 65, 81, 1);
display: grid;
grid-template-columns: 1fr;
margin-top: 3.5rem;
}
#hero .text-container {
color: rgba(255, 255, 255, 1);
padding: 3rem 2rem;
}
#hero .text-container h2 {
font-size: 1.5rem;
line-height: 2rem;
position: relative;
}
#hero .text-container h2 svg {
color: hsla(162, 47%, 50%, 1);
height: 2rem;
left: -0.25rem;
position: absolute;
top: 0;
width: 2rem;
}
#hero .text-container h2 span {
margin-left: 2.5rem;
}
#hero .text-container a {
background-color: rgba(255, 255, 255, 1);
border-radius: 0.75rem;
color: rgba(55, 65, 81, 1);
display: inline-block;
margin-top: 1.5rem;
padding: 1rem 2rem;
text-decoration: inherit;
}
#hero .logo-container {
display: none;
justify-content: center;
padding-left: 2rem;
padding-right: 2rem;
}
#hero .logo-container svg {
color: rgba(255, 255, 255, 1);
width: 66.666667%;
}
#middle-content {
align-items: flex-start;
display: grid;
gap: 4rem;
grid-template-columns: 1fr;
margin-top: 3.5rem;
}
#learning-materials {
padding: 2.5rem 2rem;
}
#learning-materials h2 {
font-weight: 500;
font-size: 1.25rem;
letter-spacing: -0.025em;
line-height: 1.75rem;
padding-left: 1rem;
padding-right: 1rem;
}
.list-item-link {
align-items: center;
border-radius: 0.75rem;
display: flex;
margin-top: 1rem;
padding: 1rem;
transition-property: background-color, border-color, color, fill, stroke,
opacity, box-shadow, transform, filter, backdrop-filter,
-webkit-backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
width: 100%;
}
.list-item-link svg:first-child {
margin-right: 1rem;
height: 1.5rem;
transition-property: background-color, border-color, color, fill, stroke,
opacity, box-shadow, transform, filter, backdrop-filter,
-webkit-backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
width: 1.5rem;
}
.list-item-link > span {
flex-grow: 1;
font-weight: 400;
transition-property: background-color, border-color, color, fill, stroke,
opacity, box-shadow, transform, filter, backdrop-filter,
-webkit-backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
.list-item-link > span > span {
color: rgba(107, 114, 128, 1);
display: block;
flex-grow: 1;
font-size: 0.75rem;
font-weight: 300;
line-height: 1rem;
transition-property: background-color, border-color, color, fill, stroke,
opacity, box-shadow, transform, filter, backdrop-filter,
-webkit-backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
.list-item-link svg:last-child {
height: 1rem;
transition-property: all;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
width: 1rem;
}
.list-item-link:hover {
color: rgba(255, 255, 255, 1);
background-color: hsla(162, 47%, 50%, 1);
}
.list-item-link:hover > span {
}
.list-item-link:hover > span > span {
color: rgba(243, 244, 246, 1);
}
.list-item-link:hover svg:last-child {
transform: translateX(0.25rem);
}
#other-links {
}
.button-pill {
padding: 1.5rem 2rem;
transition-duration: 300ms;
transition-property: background-color, border-color, color, fill, stroke,
opacity, box-shadow, transform, filter, backdrop-filter,
-webkit-backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
align-items: center;
display: flex;
}
.button-pill svg {
transition-property: background-color, border-color, color, fill, stroke,
opacity, box-shadow, transform, filter, backdrop-filter,
-webkit-backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
flex-shrink: 0;
width: 3rem;
}
.button-pill > span {
letter-spacing: -0.025em;
font-weight: 400;
font-size: 1.125rem;
line-height: 1.75rem;
padding-left: 1rem;
padding-right: 1rem;
}
.button-pill span span {
display: block;
font-size: 0.875rem;
font-weight: 300;
line-height: 1.25rem;
}
.button-pill:hover svg,
.button-pill:hover {
color: rgba(255, 255, 255, 1) !important;
}
#nx-console:hover {
background-color: rgba(0, 122, 204, 1);
}
#nx-console svg {
color: rgba(0, 122, 204, 1);
}
#nx-console-jetbrains {
margin-top: 2rem;
}
#nx-console-jetbrains:hover {
background-color: rgba(255, 49, 140, 1);
}
#nx-console-jetbrains svg {
color: rgba(255, 49, 140, 1);
}
#nx-repo:hover {
background-color: rgba(24, 23, 23, 1);
}
#nx-repo svg {
color: rgba(24, 23, 23, 1);
}
#nx-cloud {
margin-bottom: 2rem;
margin-top: 2rem;
padding: 2.5rem 2rem;
}
#nx-cloud > div {
align-items: center;
display: flex;
}
#nx-cloud > div svg {
border-radius: 0.375rem;
flex-shrink: 0;
width: 3rem;
}
#nx-cloud > div h2 {
font-size: 1.125rem;
font-weight: 400;
letter-spacing: -0.025em;
line-height: 1.75rem;
padding-left: 1rem;
padding-right: 1rem;
}
#nx-cloud > div h2 span {
display: block;
font-size: 0.875rem;
font-weight: 300;
line-height: 1.25rem;
}
#nx-cloud p {
font-size: 1rem;
line-height: 1.5rem;
margin-top: 1rem;
}
#nx-cloud pre {
margin-top: 1rem;
}
#nx-cloud a {
color: rgba(107, 114, 128, 1);
display: block;
font-size: 0.875rem;
line-height: 1.25rem;
margin-top: 1.5rem;
text-align: right;
}
#nx-cloud a:hover {
text-decoration: underline;
}
#commands {
padding: 2.5rem 2rem;
margin-top: 3.5rem;
}
#commands h2 {
font-size: 1.25rem;
font-weight: 400;
letter-spacing: -0.025em;
line-height: 1.75rem;
padding-left: 1rem;
padding-right: 1rem;
}
#commands p {
font-size: 1rem;
font-weight: 300;
line-height: 1.5rem;
margin-top: 1rem;
padding-left: 1rem;
padding-right: 1rem;
}
details {
align-items: center;
display: flex;
margin-top: 1rem;
padding-left: 1rem;
padding-right: 1rem;
width: 100%;
}
details pre > span {
color: rgba(181, 181, 181, 1);
}
summary {
border-radius: 0.5rem;
display: flex;
font-weight: 400;
padding: 0.5rem;
cursor: pointer;
transition-property: background-color, border-color, color, fill, stroke,
opacity, box-shadow, transform, filter, backdrop-filter,
-webkit-backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
summary:hover {
background-color: rgba(243, 244, 246, 1);
}
summary svg {
height: 1.5rem;
margin-right: 1rem;
width: 1.5rem;
}
#love {
color: rgba(107, 114, 128, 1);
font-size: 0.875rem;
line-height: 1.25rem;
margin-top: 3.5rem;
opacity: 0.6;
text-align: center;
}
#love svg {
color: rgba(252, 165, 165, 1);
width: 1.25rem;
height: 1.25rem;
display: inline;
margin-top: -0.25rem;
}
@media screen and (min-width: 768px) {
#hero {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
#hero .logo-container {
display: flex;
}
#middle-content {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}

View File

@@ -1,21 +0,0 @@
import { AppElement } from './app.element';
describe('AppElement', () => {
let app: AppElement;
beforeEach(() => {
app = new AppElement();
});
it('should create successfully', () => {
expect(app).toBeTruthy();
});
it('should have a greeting', () => {
app.connectedCallback();
expect(app.querySelector('h1').innerHTML).toContain(
'Welcome @triliumnext/client'
);
});
});

View File

@@ -1,409 +0,0 @@
import './app.element.css';
export class AppElement extends HTMLElement {
public static observedAttributes = [
];
connectedCallback() {
const title = '@triliumnext/client';
this.innerHTML = `
<div class="wrapper">
<div class="container">
<!-- WELCOME -->
<div id="welcome">
<h1>
<span> Hello there, </span>
Welcome ${title} 👋
</h1>
</div>
<!-- HERO -->
<div id="hero" class="rounded">
<div class="text-container">
<h2>
<svg
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 12l2 2 4-4M7.835 4.697a3.42 3.42 0 001.946-.806 3.42 3.42 0 014.438 0 3.42 3.42 0 001.946.806 3.42 3.42 0 013.138 3.138 3.42 3.42 0 00.806 1.946 3.42 3.42 0 010 4.438 3.42 3.42 0 00-.806 1.946 3.42 3.42 0 01-3.138 3.138 3.42 3.42 0 00-1.946.806 3.42 3.42 0 01-4.438 0 3.42 3.42 0 00-1.946-.806 3.42 3.42 0 01-3.138-3.138 3.42 3.42 0 00-.806-1.946 3.42 3.42 0 010-4.438 3.42 3.42 0 00.806-1.946 3.42 3.42 0 013.138-3.138z"
/>
</svg>
<span>You&apos;re up and running</span>
</h2>
<a href="#commands"> What&apos;s next? </a>
</div>
<div class="logo-container">
<svg
fill="currentColor"
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M11.987 14.138l-3.132 4.923-5.193-8.427-.012 8.822H0V4.544h3.691l5.247 8.833.005-3.998 3.044 4.759zm.601-5.761c.024-.048 0-3.784.008-3.833h-3.65c.002.059-.005 3.776-.003 3.833h3.645zm5.634 4.134a2.061 2.061 0 0 0-1.969 1.336 1.963 1.963 0 0 1 2.343-.739c.396.161.917.422 1.33.283a2.1 2.1 0 0 0-1.704-.88zm3.39 1.061c-.375-.13-.8-.277-1.109-.681-.06-.08-.116-.17-.176-.265a2.143 2.143 0 0 0-.533-.642c-.294-.216-.68-.322-1.18-.322a2.482 2.482 0 0 0-2.294 1.536 2.325 2.325 0 0 1 4.002.388.75.75 0 0 0 .836.334c.493-.105.46.36 1.203.518v-.133c-.003-.446-.246-.55-.75-.733zm2.024 1.266a.723.723 0 0 0 .347-.638c-.01-2.957-2.41-5.487-5.37-5.487a5.364 5.364 0 0 0-4.487 2.418c-.01-.026-1.522-2.39-1.538-2.418H8.943l3.463 5.423-3.379 5.32h3.54l1.54-2.366 1.568 2.366h3.541l-3.21-5.052a.7.7 0 0 1-.084-.32 2.69 2.69 0 0 1 2.69-2.691h.001c1.488 0 1.736.89 2.057 1.308.634.826 1.9.464 1.9 1.541a.707.707 0 0 0 1.066.596zm.35.133c-.173.372-.56.338-.755.639-.176.271.114.412.114.412s.337.156.538-.311c.104-.231.14-.488.103-.74z"
/>
</svg>
</div>
</div>
<!-- MIDDLE CONTENT -->
<div id="middle-content">
<div id="learning-materials" class="rounded shadow">
<h2>Learning materials</h2>
<a href="https://nx.dev/getting-started/intro?utm_source=nx-project" target="_blank" rel="noreferrer" class="list-item-link">
<svg
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"
/>
</svg>
<span>
Documentation
<span> Everything is in there </span>
</span>
<svg
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5l7 7-7 7"
/>
</svg>
</a>
<a href="https://nx.dev/blog/?utm_source=nx-project" target="_blank" rel="noreferrer" class="list-item-link">
<svg
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z"
/>
</svg>
<span>
Blog
<span> Changelog, features & events </span>
</span>
<svg
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5l7 7-7 7"
/>
</svg>
</a>
<a href="https://www.youtube.com/@NxDevtools/videos?utm_source=nx-project&sub_confirmation=1" target="_blank" rel="noreferrer" class="list-item-link">
<svg
role="img"
viewBox="0 0 24 24"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<title>YouTube</title>
<path
d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"
/>
</svg>
<span>
YouTube channel
<span> Nx Show, talks & tutorials </span>
</span>
<svg
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5l7 7-7 7"
/>
</svg>
</a>
<a href="https://nx.dev/react-tutorial/1-code-generation?utm_source=nx-project" target="_blank" rel="noreferrer" class="list-item-link">
<svg
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M15 15l-2 5L9 9l11 4-5 2zm0 0l5 5M7.188 2.239l.777 2.897M5.136 7.965l-2.898-.777M13.95 4.05l-2.122 2.122m-5.657 5.656l-2.12 2.122"
/>
</svg>
<span>
Interactive tutorials
<span> Create an app, step-by-step </span>
</span>
<svg
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5l7 7-7 7"
/>
</svg>
</a>
<a href="https://nxplaybook.com/?utm_source=nx-project" target="_blank" rel="noreferrer" class="list-item-link">
<svg
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M12 14l9-5-9-5-9 5 9 5z" />
<path
d="M12 14l6.16-3.422a12.083 12.083 0 01.665 6.479A11.952 11.952 0 0012 20.055a11.952 11.952 0 00-6.824-2.998 12.078 12.078 0 01.665-6.479L12 14z"
/>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 14l9-5-9-5-9 5 9 5zm0 0l6.16-3.422a12.083 12.083 0 01.665 6.479A11.952 11.952 0 0012 20.055a11.952 11.952 0 00-6.824-2.998 12.078 12.078 0 01.665-6.479L12 14zm-4 6v-7.5l4-2.222"
/>
</svg>
<span>
Video courses
<span> Nx custom courses </span>
</span>
<svg
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 5l7 7-7 7"
/>
</svg>
</a>
</div>
<div id="other-links">
<a id="nx-console" class="button-pill rounded shadow" href="https://marketplace.visualstudio.com/items?itemName=nrwl.angular-console&utm_source=nx-project" target="_blank" rel="noreferrer">
<svg
fill="currentColor"
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<title>Visual Studio Code</title>
<path
d="M23.15 2.587L18.21.21a1.494 1.494 0 0 0-1.705.29l-9.46 8.63-4.12-3.128a.999.999 0 0 0-1.276.057L.327 7.261A1 1 0 0 0 .326 8.74L3.899 12 .326 15.26a1 1 0 0 0 .001 1.479L1.65 17.94a.999.999 0 0 0 1.276.057l4.12-3.128 9.46 8.63a1.492 1.492 0 0 0 1.704.29l4.942-2.377A1.5 1.5 0 0 0 24 20.06V3.939a1.5 1.5 0 0 0-.85-1.352zm-5.146 14.861L10.826 12l7.178-5.448v10.896z"
/>
</svg>
<span>
Install Nx Console for VSCode
<span>The official VSCode extension for Nx.</span>
</span>
</a>
<a
id="nx-console-jetbrains"
class="button-pill rounded shadow"
href="https://plugins.jetbrains.com/plugin/21060-nx-console"
target="_blank"
rel="noreferrer"
>
<svg
height="48"
width="48"
viewBox="20 20 60 60"
xmlns="http://www.w3.org/2000/svg"
>
<path d="m22.5 22.5h60v60h-60z" />
<g fill="#fff">
<path d="m29.03 71.25h22.5v3.75h-22.5z" />
<path d="m28.09 38 1.67-1.58a1.88 1.88 0 0 0 1.47.87c.64 0 1.06-.44 1.06-1.31v-5.98h2.58v6a3.48 3.48 0 0 1 -.87 2.6 3.56 3.56 0 0 1 -2.57.95 3.84 3.84 0 0 1 -3.34-1.55z" />
<path d="m36 30h7.53v2.19h-5v1.44h4.49v2h-4.42v1.49h5v2.21h-7.6z" />
<path d="m47.23 32.29h-2.8v-2.29h8.21v2.27h-2.81v7.1h-2.6z" />
<path d="m29.13 43.08h4.42a3.53 3.53 0 0 1 2.55.83 2.09 2.09 0 0 1 .6 1.53 2.16 2.16 0 0 1 -1.44 2.09 2.27 2.27 0 0 1 1.86 2.29c0 1.61-1.31 2.59-3.55 2.59h-4.44zm5 2.89c0-.52-.42-.8-1.18-.8h-1.29v1.64h1.24c.79 0 1.25-.26 1.25-.81zm-.9 2.66h-1.57v1.73h1.62c.8 0 1.24-.31 1.24-.86 0-.5-.4-.87-1.27-.87z" />
<path d="m38 43.08h4.1a4.19 4.19 0 0 1 3 1 2.93 2.93 0 0 1 .9 2.19 3 3 0 0 1 -1.93 2.89l2.24 3.27h-3l-1.88-2.84h-.87v2.84h-2.56zm4 4.5c.87 0 1.39-.43 1.39-1.11 0-.75-.54-1.12-1.4-1.12h-1.44v2.26z" />
<path d="m49.59 43h2.5l4 9.44h-2.79l-.67-1.69h-3.63l-.67 1.69h-2.71zm2.27 5.73-1-2.65-1.06 2.65z" />
<path d="m56.46 43.05h2.6v9.37h-2.6z" />
<path d="m60.06 43.05h2.42l3.37 5v-5h2.57v9.37h-2.26l-3.53-5.14v5.14h-2.57z" />
<path d="m68.86 51 1.45-1.73a4.84 4.84 0 0 0 3 1.13c.71 0 1.08-.24 1.08-.65 0-.4-.31-.6-1.59-.91-2-.46-3.53-1-3.53-2.93 0-1.74 1.37-3 3.62-3a5.89 5.89 0 0 1 3.86 1.25l-1.26 1.84a4.63 4.63 0 0 0 -2.62-.92c-.63 0-.94.25-.94.6 0 .42.32.61 1.63.91 2.14.46 3.44 1.16 3.44 2.91 0 1.91-1.51 3-3.79 3a6.58 6.58 0 0 1 -4.35-1.5z" />
</g>
</svg>
<span>
Install Nx Console for JetBrains
<span>
Available for WebStorm, Intellij IDEA Ultimate and more!
</span>
</span>
</a>
<div id="nx-cloud" class="rounded shadow">
<div>
<svg id="nx-cloud-logo" role="img" xmlns="http://www.w3.org/2000/svg" stroke="currentColor" fill="transparent" viewBox="0 0 24 24">
<path stroke-width="2" d="M23 3.75V6.5c-3.036 0-5.5 2.464-5.5 5.5s-2.464 5.5-5.5 5.5-5.5 2.464-5.5 5.5H3.75C2.232 23 1 21.768 1 20.25V3.75C1 2.232 2.232 1 3.75 1h16.5C21.768 1 23 2.232 23 3.75Z" />
<path stroke-width="2" d="M23 6v14.1667C23 21.7307 21.7307 23 20.1667 23H6c0-3.128 2.53867-5.6667 5.6667-5.6667 3.128 0 5.6666-2.5386 5.6666-5.6666C17.3333 8.53867 19.872 6 23 6Z" />
</svg>
<h2>
Nx Cloud
<span>
Enable faster CI & better DX
</span>
</h2>
</div>
<p>
You can activate distributed tasks executions and caching by
running:
</p>
<pre>nx connect</pre>
<a href="https://nx.app/?utm_source=nx-project" target="_blank" rel="noreferrer"> What is Nx Cloud? </a>
</div>
<a id="nx-repo" class="button-pill rounded shadow" href="https://github.com/nrwl/nx?utm_source=nx-project" target="_blank" rel="noreferrer">
<svg
fill="currentColor"
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"
/>
</svg>
<span>
Nx is open source
<span> Love Nx? Give us a star! </span>
</span>
</a>
</div>
</div>
<!-- COMMANDS -->
<div id="commands" class="rounded shadow">
<h2>Next steps</h2>
<p>Here are some things you can do with Nx:</p>
<details>
<summary>
<svg
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
/>
</svg>
Add UI library
</summary>
<pre><span># Generate UI lib</span>
nx g @nx/angular:lib ui
<span># Add a component</span>
nx g @nx/angular:component ui/src/lib/button</pre>
</details>
<details>
<summary>
<svg
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
/>
</svg>
View interactive project graph
</summary>
<pre>nx graph</pre>
</details>
<details>
<summary>
<svg
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
/>
</svg>
Run affected commands
</summary>
<pre><span># see what&apos;s been affected by changes</span>
nx affected:graph
<span># run tests for current changes</span>
nx affected:test
<span># run e2e tests for current changes</span>
nx affected:e2e</pre>
</details>
</div>
<p id="love">
Carefully crafted with
<svg
fill="currentColor"
stroke="none"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"
/>
</svg>
</p>
</div>
</div>
`;
}
}
customElements.define('triliumnext-root', AppElement);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,14 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Client</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</head>
<body>
<triliumnext-root></triliumnext-root>
</body>
</html>

View File

@@ -1 +0,0 @@
import './app/app.element';

View File

@@ -1 +0,0 @@
/* You can add global styles to this file, and also import other style files */

View File

@@ -1,5 +1,4 @@
import froca from "../services/froca.js";
import bundleService from "../services/bundle.js";
import RootCommandExecutor from "./root_command_executor.js";
import Entrypoints, { type SqlExecuteResults } from "./entrypoints.js";
import options from "../services/options.js";
@@ -262,7 +261,6 @@ export type CommandMappings = {
// Geomap
deleteFromMap: { noteId: string };
openGeoLocation: { noteId: string; event: JQuery.MouseDownEvent };
toggleZenMode: CommandData;
@@ -281,6 +279,7 @@ export type CommandMappings = {
buildIcon(name: string): NativeImage;
};
refreshTouchBar: CommandData;
reloadTextEditor: CommandData;
};
type EventMappings = {
@@ -469,6 +468,7 @@ export class AppContext extends Component {
this.tabManager.loadTabs();
const bundleService = (await import("../services/bundle.js")).default;
setTimeout(() => bundleService.executeStartupBundles(), 2000);
}

View File

@@ -93,11 +93,7 @@ export class TypedComponent<ChildT extends TypedComponent<ChildT>> {
if (fun) {
return this.callMethod(fun, data);
} else {
if (!this.parent) {
throw new Error(`Component "${this.componentId}" does not have a parent attached to propagate a command.`);
}
} else if (this.parent) {
return this.parent.triggerCommand(name, data);
}
}

View File

@@ -12,6 +12,7 @@ import type FNote from "../entities/fnote.js";
import type TypeWidget from "../widgets/type_widgets/type_widget.js";
import type { CKTextEditor } from "@triliumnext/ckeditor5";
import type CodeMirror from "@triliumnext/codemirror";
import { closeActiveDialog } from "../services/dialog.js";
export interface SetNoteOpts {
triggerSwitchEvent?: unknown;
@@ -83,7 +84,7 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded">
await this.triggerEvent("beforeNoteSwitch", { noteContext: this });
utils.closeActiveDialog();
closeActiveDialog();
this.notePath = resolvedNotePath;
this.viewScope = opts.viewScope;
@@ -314,14 +315,38 @@ class NoteContext extends Component implements EventListener<"entitiesReloaded">
}
hasNoteList() {
return (
this.note &&
["default", "contextual-help"].includes(this.viewScope?.viewMode ?? "") &&
(this.note.hasChildren() || this.note.getLabelValue("viewType") === "calendar") &&
["book", "text", "code"].includes(this.note.type) &&
this.note.mime !== "text/x-sqlite;schema=trilium" &&
!this.note.isLabelTruthy("hideChildrenOverview")
);
const note = this.note;
if (!note) {
return false;
}
if (!["default", "contextual-help"].includes(this.viewScope?.viewMode ?? "")) {
return false;
}
// Some book types must always display a note list, even if no children.
if (["calendar", "table", "geoMap"].includes(note.getLabelValue("viewType") ?? "")) {
return true;
}
if (!note.hasChildren()) {
return false;
}
if (!["book", "text", "code"].includes(note.type)) {
return false;
}
if (note.mime === "text/x-sqlite;schema=trilium") {
return false;
}
if (note.isLabelTruthy("hideChildrenOverview")) {
return false;
}
return true;
}
async getTextEditor(callback?: GetTextEditorCallback) {

View File

@@ -688,7 +688,7 @@ export default class TabManager extends Component {
const titleFragments = [
// it helps to navigate in history if note title is included in the title
await activeNoteContext.getNavigationTitle(),
"TriliumNext Notes"
"Trilium Notes"
].filter(Boolean);
document.title = titleFragments.join(" - ");

View File

@@ -1,7 +1,6 @@
import server from "../services/server.js";
import noteAttributeCache from "../services/note_attribute_cache.js";
import ws from "../services/ws.js";
import froca from "../services/froca.js";
import protectedSessionHolder from "../services/protected_session_holder.js";
import cssClassManager from "../services/css_class_manager.js";
import type { Froca } from "../services/froca-interface.js";
@@ -28,7 +27,6 @@ const NOTE_TYPE_ICONS = {
doc: "bx bxs-file-doc",
contentWidget: "bx bxs-widget",
mindMap: "bx bx-sitemap",
geoMap: "bx bx-map-alt",
aiChat: "bx bx-bot"
};
@@ -37,7 +35,7 @@ const NOTE_TYPE_ICONS = {
* end user. Those types should be used only for checking against, they are
* not for direct use.
*/
export type NoteType = "file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code" | "mindMap" | "geoMap" | "aiChat";
export type NoteType = "file" | "image" | "search" | "noteMap" | "launcher" | "doc" | "contentWidget" | "text" | "relationMap" | "render" | "canvas" | "mermaid" | "book" | "webView" | "code" | "mindMap" | "aiChat";
export interface NotePathRecord {
isArchived: boolean;
@@ -410,8 +408,8 @@ class FNote {
const notePaths: NotePathRecord[] = this.getAllNotePaths().map((path) => ({
notePath: path,
isInHoistedSubTree: isHoistedRoot || path.includes(hoistedNoteId),
isArchived: path.some((noteId) => froca.notes[noteId].isArchived),
isSearch: path.some((noteId) => froca.notes[noteId].type === "search"),
isArchived: path.some((noteId) => this.froca.notes[noteId].isArchived),
isSearch: path.some((noteId) => this.froca.notes[noteId].type === "search"),
isHidden: path.includes("_hidden")
}));
@@ -982,7 +980,7 @@ class FNote {
continue;
}
const parentNote = froca.notes[parentNoteId];
const parentNote = this.froca.notes[parentNoteId];
if (!parentNote || parentNote.type === "search") {
continue;

View File

@@ -2,7 +2,7 @@ import keyboardActionService from "../services/keyboard_actions.js";
import note_tooltip from "../services/note_tooltip.js";
import utils from "../services/utils.js";
interface ContextMenuOptions<T> {
export interface ContextMenuOptions<T> {
x: number;
y: number;
orientation?: "left";
@@ -17,17 +17,25 @@ interface MenuSeparatorItem {
title: "----";
}
export interface MenuItemBadge {
title: string;
className?: string;
}
export interface MenuCommandItem<T> {
title: string;
command?: T;
type?: string;
uiIcon?: string;
badges?: MenuItemBadge[];
templateNoteId?: string;
enabled?: boolean;
handler?: MenuHandler<T>;
items?: MenuItem<T>[] | null;
shortcut?: string;
spellingSuggestion?: string;
checked?: boolean;
columns?: number;
}
export type MenuItem<T> = MenuCommandItem<T> | MenuSeparatorItem;
@@ -146,10 +154,13 @@ class ContextMenu {
} else {
const $icon = $("<span>");
if ("uiIcon" in item && item.uiIcon) {
$icon.addClass(item.uiIcon);
} else {
$icon.append("&nbsp;");
if ("uiIcon" in item || "checked" in item) {
const icon = (item.checked ? "bx bx-check" : item.uiIcon);
if (icon) {
$icon.addClass(icon);
} else {
$icon.append("&nbsp;");
}
}
const $link = $("<span>")
@@ -157,6 +168,18 @@ class ContextMenu {
.append(" &nbsp; ") // some space between icon and text
.append(item.title);
if ("badges" in item && item.badges) {
for (let badge of item.badges) {
const badgeElement = $(`<span class="badge">`).text(badge.title);
if (badge.className) {
badgeElement.addClass(badge.className);
}
$link.append(badgeElement);
}
}
if ("shortcut" in item && item.shortcut) {
$link.append($("<kbd>").text(item.shortcut));
}
@@ -194,14 +217,15 @@ class ContextMenu {
return false;
});
if (!this.isMobile) {
$item.on("mouseup", (e) =>{
$item.on("mouseup", (e) => {
// Prevent submenu from failing to expand on mobile
if (!this.isMobile || !("items" in item && item.items)) {
e.stopPropagation();
// Hide the content menu on mouse up to prevent the mouse event from propagating to the elements below.
this.hide();
return false;
});
}
}
});
if ("enabled" in item && item.enabled !== undefined && !item.enabled) {
$item.addClass("disabled");
@@ -212,6 +236,9 @@ class ContextMenu {
$link.addClass("dropdown-toggle");
const $subMenu = $("<ul>").addClass("dropdown-menu");
if (!this.isMobile && item.columns) {
$subMenu.css("column-count", item.columns);
}
this.addItems($subMenu, item.items);

View File

@@ -92,7 +92,8 @@ export default class TreeContextMenu implements SelectMenuItemEventListener<Tree
command: "insertNoteAfter",
uiIcon: "bx bx-plus",
items: insertNoteAfterEnabled ? await noteTypesService.getNoteTypeItems("insertNoteAfter") : null,
enabled: insertNoteAfterEnabled && noSelectedNotes && notOptionsOrHelp
enabled: insertNoteAfterEnabled && noSelectedNotes && notOptionsOrHelp,
columns: 2
},
{
@@ -100,7 +101,8 @@ export default class TreeContextMenu implements SelectMenuItemEventListener<Tree
command: "insertChildNote",
uiIcon: "bx bx-plus",
items: notSearch ? await noteTypesService.getNoteTypeItems("insertChildNote") : null,
enabled: notSearch && noSelectedNotes && notOptionsOrHelp
enabled: notSearch && noSelectedNotes && notOptionsOrHelp,
columns: 2
},
{ title: "----" },

View File

@@ -3,15 +3,16 @@ import froca from "./froca.js";
import type FNote from "../entities/fnote.js";
import type { AttributeRow } from "./load_results.js";
async function addLabel(noteId: string, name: string, value: string = "") {
async function addLabel(noteId: string, name: string, value: string = "", isInheritable = false) {
await server.put(`notes/${noteId}/attribute`, {
type: "label",
name: name,
value: value
value: value,
isInheritable
});
}
async function setLabel(noteId: string, name: string, value: string = "") {
export async function setLabel(noteId: string, name: string, value: string = "") {
await server.put(`notes/${noteId}/set-attribute`, {
type: "label",
name: name,
@@ -49,7 +50,7 @@ function removeOwnedLabelByName(note: FNote, labelName: string) {
* @param name the name of the attribute to set.
* @param value the value of the attribute to set.
*/
async function setAttribute(note: FNote, type: "label" | "relation", name: string, value: string | null | undefined) {
export async function setAttribute(note: FNote, type: "label" | "relation", name: string, value: string | null | undefined) {
if (value) {
// Create or update the attribute.
await server.put(`notes/${note.noteId}/set-attribute`, { type, name, value });

View File

@@ -1,6 +1,6 @@
import ScriptContext from "./script_context.js";
import server from "./server.js";
import toastService from "./toast.js";
import toastService, { showError } from "./toast.js";
import froca from "./froca.js";
import utils from "./utils.js";
import { t } from "./i18n.js";
@@ -37,7 +37,9 @@ async function executeBundle(bundle: Bundle, originEntity?: Entity | null, $cont
} catch (e: any) {
const note = await froca.getNote(bundle.noteId);
toastService.showAndLogError(`Execution of JS note "${note?.title}" with ID ${bundle.noteId} failed with error: ${e?.message}`);
const message = `Execution of JS note "${note?.title}" with ID ${bundle.noteId} failed with error: ${e?.message}`;
showError(message);
logError(message);
}
}

View File

@@ -4,7 +4,7 @@ import froca from "./froca.js";
import linkService from "./link.js";
import utils from "./utils.js";
import { t } from "./i18n.js";
import toast from "./toast.js";
import { throwError } from "./ws.js";
let clipboardBranchIds: string[] = [];
let clipboardMode: string | null = null;
@@ -37,7 +37,7 @@ async function pasteAfter(afterBranchId: string) {
// copy will keep clipboardBranchIds and clipboardMode, so it's possible to paste into multiple places
} else {
toastService.throwError(`Unrecognized clipboard mode=${clipboardMode}`);
throwError(`Unrecognized clipboard mode=${clipboardMode}`);
}
}
@@ -69,7 +69,7 @@ async function pasteInto(parentBranchId: string) {
// copy will keep clipboardBranchIds and clipboardMode, so it's possible to paste into multiple places
} else {
toastService.throwError(`Unrecognized clipboard mode=${clipboardMode}`);
throwError(`Unrecognized clipboard mode=${clipboardMode}`);
}
}

View File

@@ -118,8 +118,17 @@ async function renderText(note: FNote | FAttachment, $renderedContent: JQuery<HT
async function renderCode(note: FNote | FAttachment, $renderedContent: JQuery<HTMLElement>) {
const blob = await note.getBlob();
let content = blob?.content || "";
if (note.mime === "application/json") {
try {
content = JSON.stringify(JSON.parse(content), null, 4);
} catch (e) {
// Ignore JSON parsing errors.
}
}
const $codeBlock = $("<code>");
$codeBlock.text(blob?.content || "");
$codeBlock.text(content);
$renderedContent.append($("<pre>").append($codeBlock));
await applySingleBlockSyntaxHighlight($codeBlock, normalizeMimeTypeForCKEditor(note.mime));
}
@@ -301,7 +310,7 @@ function getRenderingType(entity: FNote | FAttachment) {
if (type === "file" && mime === "application/pdf") {
type = "pdf";
} else if (type === "file" && mime && CODE_MIME_TYPES.has(mime)) {
} else if ((type === "file" || type === "viewConfig") && mime && CODE_MIME_TYPES.has(mime)) {
type = "code";
} else if (type === "file" && mime && mime.startsWith("audio/")) {
type = "audio";

View File

@@ -1,6 +1,41 @@
import { Modal } from "bootstrap";
import appContext from "../components/app_context.js";
import type { ConfirmDialogOptions, ConfirmDialogResult, ConfirmWithMessageOptions } from "../widgets/dialogs/confirm.js";
import type { PromptDialogOptions } from "../widgets/dialogs/prompt.js";
import { focusSavedElement, saveFocusedElement } from "./focus.js";
export async function openDialog($dialog: JQuery<HTMLElement>, closeActDialog = true) {
if (closeActDialog) {
closeActiveDialog();
glob.activeDialog = $dialog;
}
saveFocusedElement();
Modal.getOrCreateInstance($dialog[0]).show();
$dialog.on("hidden.bs.modal", () => {
const $autocompleteEl = $(".aa-input");
if ("autocomplete" in $autocompleteEl) {
$autocompleteEl.autocomplete("close");
}
if (!glob.activeDialog || glob.activeDialog === $dialog) {
focusSavedElement();
}
});
const keyboardActionsService = (await import("./keyboard_actions.js")).default;
keyboardActionsService.updateDisplayedShortcuts($dialog);
return $dialog;
}
export function closeActiveDialog() {
if (glob.activeDialog) {
Modal.getOrCreateInstance(glob.activeDialog[0]).hide();
glob.activeDialog = null;
}
}
async function info(message: string) {
return new Promise((res) => appContext.triggerCommand("showInfoDialog", { message, callback: res }));

View File

@@ -0,0 +1,29 @@
let $lastFocusedElement: JQuery<HTMLElement> | null;
// perhaps there should be saved focused element per tab?
export function saveFocusedElement() {
$lastFocusedElement = $(":focus");
}
export function focusSavedElement() {
if (!$lastFocusedElement) {
return;
}
if ($lastFocusedElement.hasClass("ck")) {
// must handle CKEditor separately because of this bug: https://github.com/ckeditor/ckeditor5/issues/607
// the bug manifests itself in resetting the cursor position to the first character - jumping above
const editor = $lastFocusedElement.closest(".ck-editor__editable").prop("ckeditorInstance");
if (editor) {
editor.editing.view.focus();
} else {
console.log("Could not find CKEditor instance to focus last element");
}
} else {
$lastFocusedElement.focus();
}
$lastFocusedElement = null;
}

View File

@@ -245,6 +245,10 @@ class FrocaImpl implements Froca {
}
async getNotes(noteIds: string[] | JQuery<string>, silentNotFoundError = false): Promise<FNote[]> {
if (noteIds.length === 0) {
return [];
}
noteIds = Array.from(new Set(noteIds)); // make unique
const missingNoteIds = noteIds.filter((noteId) => !this.notes[noteId]);

View File

@@ -49,6 +49,13 @@ function setupGlobs() {
const string = e?.reason?.message?.toLowerCase();
let message = "Uncaught error: ";
let errorObjectString;
try {
errorObjectString = JSON.stringify(e.reason)
} catch (error: any) {
errorObjectString = error.toString();
}
if (string?.includes("script error")) {
message += "No details available";
@@ -57,7 +64,7 @@ function setupGlobs() {
`Message: ${e.reason.message}`,
`Line: ${e.reason.lineNumber}`,
`Column: ${e.reason.columnNumber}`,
`Error object: ${JSON.stringify(e.reason)}`,
`Error object: ${errorObjectString}`,
`Stack: ${e.reason && e.reason.stack}`
].join(", ");
}

View File

@@ -1,6 +1,7 @@
import { LOCALES } from "@triliumnext/commons";
import { readFileSync } from "fs";
import { join } from "path";
import { describe, expect, it } from "vitest";
describe("i18n", () => {
it("translations are valid JSON", () => {

View File

@@ -1,5 +1,5 @@
import { t } from "./i18n.js";
import toastService from "./toast.js";
import toastService, { showError } from "./toast.js";
function copyImageReferenceToClipboard($imageWrapper: JQuery<HTMLElement>) {
try {
@@ -11,7 +11,9 @@ function copyImageReferenceToClipboard($imageWrapper: JQuery<HTMLElement>) {
if (success) {
toastService.showMessage(t("image.copied-to-clipboard"));
} else {
toastService.showAndLogError(t("image.cannot-copy"));
const message = t("image.cannot-copy");
showError(message);
logError(message);
}
} finally {
window.getSelection()?.removeAllRanges();

View File

@@ -277,13 +277,21 @@ function goToLink(evt: MouseEvent | JQuery.ClickEvent | JQuery.MouseDownEvent) {
return goToLinkExt(evt, hrefLink, $link);
}
function goToLinkExt(evt: MouseEvent | JQuery.ClickEvent | JQuery.MouseDownEvent | React.PointerEvent<HTMLCanvasElement>, hrefLink: string | undefined, $link?: JQuery<HTMLElement> | null) {
/**
* Handles navigation to a link, which can be an internal note path (e.g., `#root/1234`) or an external URL (e.g., `https://example.com`).
*
* @param evt the event that triggered the link navigation, or `null` if the link was clicked programmatically. Used to determine if the link should be opened in a new tab/window, based on the button presses.
* @param hrefLink the link to navigate to, which can be a note path (e.g., `#root/1234`) or an external URL with any supported protocol (e.g., `https://example.com`).
* @param $link the jQuery element of the link that was clicked, used to determine if the link is an anchor link (e.g., `#fn1` or `#fnref1`) and to handle it accordingly.
* @returns `true` if the link was handled (i.e., the element was found and scrolled to), or a falsy value otherwise.
*/
function goToLinkExt(evt: MouseEvent | JQuery.ClickEvent | JQuery.MouseDownEvent | React.PointerEvent<HTMLCanvasElement> | null, hrefLink: string | undefined, $link?: JQuery<HTMLElement> | null) {
if (hrefLink?.startsWith("data:")) {
return true;
}
evt.preventDefault();
evt.stopPropagation();
evt?.preventDefault();
evt?.stopPropagation();
if (hrefLink && hrefLink.startsWith("#") && !hrefLink.startsWith("#root/") && $link) {
if (handleAnchor(hrefLink, $link)) {
@@ -293,14 +301,14 @@ function goToLinkExt(evt: MouseEvent | JQuery.ClickEvent | JQuery.MouseDownEvent
const { notePath, viewScope } = parseNavigationStateFromUrl(hrefLink);
const ctrlKey = utils.isCtrlKey(evt);
const shiftKey = evt.shiftKey;
const isLeftClick = "which" in evt && evt.which === 1;
const isMiddleClick = "which" in evt && evt.which === 2;
const ctrlKey = evt && utils.isCtrlKey(evt);
const shiftKey = evt?.shiftKey;
const isLeftClick = !evt || ("which" in evt && evt.which === 1);
const isMiddleClick = evt && "which" in evt && evt.which === 2;
const targetIsBlank = ($link?.attr("target") === "_blank");
const openInNewTab = (isLeftClick && ctrlKey) || isMiddleClick || targetIsBlank;
const activate = (isLeftClick && ctrlKey && shiftKey) || (isMiddleClick && shiftKey);
const openInNewWindow = isLeftClick && evt.shiftKey && !ctrlKey;
const openInNewWindow = isLeftClick && evt?.shiftKey && !ctrlKey;
if (notePath) {
if (openInNewWindow) {
@@ -311,7 +319,7 @@ function goToLinkExt(evt: MouseEvent | JQuery.ClickEvent | JQuery.MouseDownEvent
viewScope
});
} else if (isLeftClick) {
const ntxId = $(evt.target as any)
const ntxId = $(evt?.target as any)
.closest("[data-ntx-id]")
.attr("data-ntx-id");
@@ -384,7 +392,7 @@ function linkContextMenu(e: PointerEvent) {
linkContextMenuService.openContextMenu(notePath, e, viewScope, null);
}
async function loadReferenceLinkTitle($el: JQuery<HTMLElement>, href: string | null | undefined = null) {
export async function loadReferenceLinkTitle($el: JQuery<HTMLElement>, href: string | null | undefined = null) {
const $link = $el[0].tagName === "A" ? $el : $el.find("a");
href = href || $link.attr("href");

View File

@@ -289,13 +289,11 @@ function initNoteAutocomplete($el: JQuery<HTMLElement>, options?: Options) {
}
if (suggestion.action === "create-note") {
const { success, noteType, templateNoteId } = await noteCreateService.chooseNoteType();
const { success, noteType, templateNoteId, notePath } = await noteCreateService.chooseNoteType();
if (!success) {
return;
}
const { note } = await noteCreateService.createNote(suggestion.parentNoteId, {
const { note } = await noteCreateService.createNote( notePath || suggestion.parentNoteId, {
title: suggestion.noteTitle,
activate: false,
type: noteType,

View File

@@ -116,7 +116,7 @@ async function chooseNoteType() {
}
async function createNoteWithTypePrompt(parentNotePath: string, options: CreateNoteOpts = {}) {
const { success, noteType, templateNoteId } = await chooseNoteType();
const { success, noteType, templateNoteId, notePath } = await chooseNoteType();
if (!success) {
return;
@@ -125,7 +125,7 @@ async function createNoteWithTypePrompt(parentNotePath: string, options: CreateN
options.type = noteType;
options.templateNoteId = templateNoteId;
return await createNote(parentNotePath, options);
return await createNote(notePath || parentNotePath, options);
}
/* If the first element is heading, parse it out and use it as a new heading. */

View File

@@ -1,38 +1,44 @@
import type FNote from "../entities/fnote.js";
import CalendarView from "../widgets/view_widgets/calendar_view.js";
import GeoView from "../widgets/view_widgets/geo_view/index.js";
import ListOrGridView from "../widgets/view_widgets/list_or_grid_view.js";
import TableView from "../widgets/view_widgets/table_view/index.js";
import type { ViewModeArgs } from "../widgets/view_widgets/view_mode.js";
import type ViewMode from "../widgets/view_widgets/view_mode.js";
export type ViewTypeOptions = "list" | "grid" | "calendar";
export type ViewTypeOptions = "list" | "grid" | "calendar" | "table" | "geoMap";
export default class NoteListRenderer {
private viewType: ViewTypeOptions;
public viewMode: ViewMode | null;
public viewMode: ViewMode<any> | null;
constructor($parent: JQuery<HTMLElement>, parentNote: FNote, noteIds: string[], showNotePath: boolean = false) {
this.viewType = this.#getViewType(parentNote);
const args: ViewModeArgs = {
$parent,
parentNote,
noteIds,
showNotePath
};
constructor(args: ViewModeArgs) {
this.viewType = this.#getViewType(args.parentNote);
if (this.viewType === "list" || this.viewType === "grid") {
this.viewMode = new ListOrGridView(this.viewType, args);
} else if (this.viewType === "calendar") {
this.viewMode = new CalendarView(args);
} else {
this.viewMode = null;
switch (this.viewType) {
case "list":
case "grid":
this.viewMode = new ListOrGridView(this.viewType, args);
break;
case "calendar":
this.viewMode = new CalendarView(args);
break;
case "table":
this.viewMode = new TableView(args);
break;
case "geoMap":
this.viewMode = new GeoView(args);
break;
default:
this.viewMode = null;
}
}
#getViewType(parentNote: FNote): ViewTypeOptions {
const viewType = parentNote.getLabelValue("viewType");
if (!["list", "grid", "calendar"].includes(viewType || "")) {
if (!["list", "grid", "calendar", "table", "geoMap"].includes(viewType || "")) {
// when not explicitly set, decide based on the note type
return parentNote.type === "search" ? "list" : "grid";
} else {

View File

@@ -14,6 +14,7 @@ let dismissTimer: ReturnType<typeof setTimeout>;
function setupGlobalTooltip() {
$(document).on("mouseenter", "a", mouseEnterHandler);
$(document).on("mouseenter", "[data-href]", mouseEnterHandler);
// close any note tooltip after click, this fixes the problem that sometimes tooltips remained on the screen
$(document).on("click", (e) => {

View File

@@ -1,43 +1,234 @@
import server from "./server.js";
import froca from "./froca.js";
import { t } from "./i18n.js";
import type { MenuItem } from "../menus/context_menu.js";
import froca from "./froca.js";
import server from "./server.js";
import type { MenuCommandItem, MenuItem, MenuItemBadge } from "../menus/context_menu.js";
import type { NoteType } from "../entities/fnote.js";
import type { TreeCommandNames } from "../menus/tree_context_menu.js";
export interface NoteTypeMapping {
type: NoteType;
mime?: string;
title: string;
icon?: string;
/** Indicates whether this type should be marked as a newly introduced feature. */
isNew?: boolean;
/** Indicates that this note type is part of a beta feature. */
isBeta?: boolean;
/** Indicates that this note type cannot be created by the user. */
reserved?: boolean;
/** Indicates that once a note of this type is created, its type can no longer be changed. */
static?: boolean;
}
export const NOTE_TYPES: NoteTypeMapping[] = [
// The suggested note type ordering method: insert the item into the corresponding group,
// then ensure the items within the group are ordered alphabetically.
// The default note type (always the first item)
{ type: "text", mime: "text/html", title: t("note_types.text"), icon: "bx-note" },
// Text notes group
{ type: "book", mime: "", title: t("note_types.book"), icon: "bx-book" },
// Graphic notes
{ type: "canvas", mime: "application/json", title: t("note_types.canvas"), icon: "bx-pen" },
{ type: "mermaid", mime: "text/mermaid", title: t("note_types.mermaid-diagram"), icon: "bx-selection" },
// Map notes
{ type: "mindMap", mime: "application/json", title: t("note_types.mind-map"), icon: "bx-sitemap" },
{ type: "noteMap", mime: "", title: t("note_types.note-map"), icon: "bxs-network-chart", static: true },
{ type: "relationMap", mime: "application/json", title: t("note_types.relation-map"), icon: "bxs-network-chart" },
// Misc note types
{ type: "render", mime: "", title: t("note_types.render-note"), icon: "bx-extension" },
{ type: "search", title: t("note_types.saved-search"), icon: "bx-file-find", static: true },
{ type: "webView", mime: "", title: t("note_types.web-view"), icon: "bx-globe-alt" },
// Code notes
{ type: "code", mime: "text/plain", title: t("note_types.code"), icon: "bx-code" },
// Reserved types (cannot be created by the user)
{ type: "contentWidget", mime: "", title: t("note_types.widget"), reserved: true },
{ type: "doc", mime: "", title: t("note_types.doc"), reserved: true },
{ type: "file", title: t("note_types.file"), reserved: true },
{ type: "image", title: t("note_types.image"), reserved: true },
{ type: "launcher", mime: "", title: t("note_types.launcher"), reserved: true },
{ type: "aiChat", mime: "application/json", title: t("note_types.ai-chat"), reserved: true }
];
/** The maximum age in days for a template to be marked with the "New" badge */
const NEW_TEMPLATE_MAX_AGE = 3;
/** The length of a day in milliseconds. */
const DAY_LENGTH = 1000 * 60 * 60 * 24;
/** The menu item badge used to mark new note types and templates */
const NEW_BADGE: MenuItemBadge = {
title: t("note_types.new-feature"),
className: "new-note-type-badge"
};
/** The menu item badge used to mark note types that are part of a beta feature */
const BETA_BADGE = {
title: t("note_types.beta-feature")
};
const SEPARATOR = { title: "----" };
const creationDateCache = new Map<string, Date>();
let rootCreationDate: Date | undefined;
async function getNoteTypeItems(command?: TreeCommandNames) {
const items: MenuItem<TreeCommandNames>[] = [
{ title: t("note_types.text"), command, type: "text", uiIcon: "bx bx-note" },
{ title: t("note_types.code"), command, type: "code", uiIcon: "bx bx-code" },
{ title: t("note_types.saved-search"), command, type: "search", uiIcon: "bx bx-file-find" },
{ title: t("note_types.relation-map"), command, type: "relationMap", uiIcon: "bx bxs-network-chart" },
{ title: t("note_types.note-map"), command, type: "noteMap", uiIcon: "bx bxs-network-chart" },
{ title: t("note_types.render-note"), command, type: "render", uiIcon: "bx bx-extension" },
{ title: t("note_types.book"), command, type: "book", uiIcon: "bx bx-book" },
{ title: t("note_types.mermaid-diagram"), command, type: "mermaid", uiIcon: "bx bx-selection" },
{ title: t("note_types.canvas"), command, type: "canvas", uiIcon: "bx bx-pen" },
{ title: t("note_types.web-view"), command, type: "webView", uiIcon: "bx bx-globe-alt" },
{ title: t("note_types.mind-map"), command, type: "mindMap", uiIcon: "bx bx-sitemap" },
{ title: t("note_types.geo-map"), command, type: "geoMap", uiIcon: "bx bx-map-alt" },
...getBlankNoteTypes(command),
...await getBuiltInTemplates("Collections", command, true),
...await getBuiltInTemplates(null, command, false),
...await getUserTemplates(command)
];
return items;
}
function getBlankNoteTypes(command): MenuItem<TreeCommandNames>[] {
return NOTE_TYPES.filter((nt) => !nt.reserved).map((nt) => {
const menuItem: MenuCommandItem<TreeCommandNames> = {
title: nt.title,
command,
type: nt.type,
uiIcon: "bx " + nt.icon,
badges: []
}
if (nt.isNew) {
menuItem.badges?.push(NEW_BADGE);
}
if (nt.isBeta) {
menuItem.badges?.push(BETA_BADGE);
}
return menuItem;
});
}
async function getUserTemplates(command?: TreeCommandNames) {
const templateNoteIds = await server.get<string[]>("search-templates");
const templateNotes = await froca.getNotes(templateNoteIds);
if (templateNotes.length === 0) {
return [];
}
if (templateNotes.length > 0) {
items.push({ title: "----" });
const items: MenuItem<TreeCommandNames>[] = [
SEPARATOR
];
for (const templateNote of templateNotes) {
items.push({
title: templateNote.title,
uiIcon: templateNote.getIcon(),
command: command,
type: templateNote.type,
templateNoteId: templateNote.noteId
});
for (const templateNote of templateNotes) {
const item: MenuItem<TreeCommandNames> = {
title: templateNote.title,
uiIcon: templateNote.getIcon(),
command: command,
type: templateNote.type,
templateNoteId: templateNote.noteId
};
if (await isNewTemplate(templateNote.noteId)) {
item.badges = [NEW_BADGE];
}
items.push(item);
}
return items;
}
async function getBuiltInTemplates(title: string | null, command: TreeCommandNames | undefined, filterCollections: boolean) {
const templatesRoot = await froca.getNote("_templates");
if (!templatesRoot) {
console.warn("Unable to find template root.");
return [];
}
const childNotes = await templatesRoot.getChildNotes();
if (childNotes.length === 0) {
return [];
}
const items: MenuItem<TreeCommandNames>[] = [
SEPARATOR
];
if (title) {
items.push({
title: title,
enabled: false
});
}
for (const templateNote of childNotes) {
if (templateNote.hasLabel("collection") !== filterCollections) {
continue;
}
const item: MenuItem<TreeCommandNames> = {
title: templateNote.title,
uiIcon: templateNote.getIcon(),
command: command,
type: templateNote.type,
templateNoteId: templateNote.noteId
};
if (await isNewTemplate(templateNote.noteId)) {
item.badges = [NEW_BADGE];
}
items.push(item);
}
return items;
}
async function isNewTemplate(templateNoteId) {
if (rootCreationDate === undefined) {
// Retrieve the root note creation date
try {
let rootNoteInfo: any = await server.get("notes/root");
if ("dateCreated" in rootNoteInfo) {
rootCreationDate = new Date(rootNoteInfo.dateCreated);
}
} catch (ex) {
console.error(ex);
}
}
return items;
// Try to retrieve the template's creation date from the cache
let creationDate: Date | undefined = creationDateCache.get(templateNoteId);
if (creationDate === undefined) {
// The creation date isn't available in the cache, try to retrieve it from the server
try {
const noteInfo: any = await server.get("notes/" + templateNoteId);
if ("dateCreated" in noteInfo) {
creationDate = new Date(noteInfo.dateCreated);
creationDateCache.set(templateNoteId, creationDate);
}
} catch (ex) {
console.error(ex);
}
}
if (creationDate) {
if (rootCreationDate && creationDate.getTime() - rootCreationDate.getTime() < 30000) {
// Ignore templates created within 30 seconds after the root note is created.
// This is useful to prevent predefined templates from being marked
// as 'New' after setting up a new database.
return false;
}
// Determine the difference in days between now and the template's creation date
const age = (new Date().getTime() - creationDate.getTime()) / DAY_LENGTH;
// Return true if the template is at most NEW_TEMPLATE_MAX_AGE days old
return (age <= NEW_TEMPLATE_MAX_AGE);
} else {
return false;
}
}
export default {

View File

@@ -1,4 +1,4 @@
type LabelType = "text" | "number" | "boolean" | "date" | "datetime" | "time" | "url";
export type LabelType = "text" | "number" | "boolean" | "date" | "datetime" | "time" | "url";
type Multiplicity = "single" | "multi";
export interface DefinitionObject {

View File

@@ -1,4 +1,4 @@
import FrontendScriptApi, { type Entity } from "./frontend_script_api.js";
import type { Entity } from "./frontend_script_api.js";
import utils from "./utils.js";
import froca from "./froca.js";
@@ -14,6 +14,8 @@ async function ScriptContext(startNoteId: string, allNoteIds: string[], originEn
throw new Error(`Could not find start note ${startNoteId}.`);
}
const FrontendScriptApi = (await import("./frontend_script_api.js")).default;
return {
modules: modules,
notes: utils.toObject(allNotes, (note) => [note.noteId, note]),

View File

@@ -276,7 +276,8 @@ async function reportError(method: string, url: string, statusCode: number, resp
} else {
const title = `${statusCode} ${method} ${url}`;
toastService.showErrorTitleAndMessage(title, messageStr);
toastService.throwError(`${title} - ${message}`);
const { throwError } = await import("./ws.js");
throwError(`${title} - ${message}`);
}
}

View File

@@ -78,13 +78,7 @@ function showMessage(message: string, delay = 2000) {
});
}
function showAndLogError(message: string, delay = 10000) {
showError(message, delay);
ws.logError(message);
}
function showError(message: string, delay = 10000) {
export function showError(message: string, delay = 10000) {
console.log(utils.now(), "error: ", message);
toast({
@@ -108,18 +102,10 @@ function showErrorTitleAndMessage(title: string, message: string, delay = 10000)
});
}
function throwError(message: string) {
ws.logError(message);
throw new Error(message);
}
export default {
showMessage,
showError,
showErrorTitleAndMessage,
showAndLogError,
throwError,
showPersistent,
closePersistent
};

View File

@@ -1,5 +1,4 @@
import dayjs from "dayjs";
import { Modal } from "bootstrap";
import type { ViewScope } from "./link.js";
const SVG_MIME = "image/svg+xml";
@@ -275,71 +274,6 @@ function getMimeTypeClass(mime: string) {
return `mime-${mime.toLowerCase().replace(/[\W_]+/g, "-")}`;
}
function closeActiveDialog() {
if (glob.activeDialog) {
Modal.getOrCreateInstance(glob.activeDialog[0]).hide();
glob.activeDialog = null;
}
}
let $lastFocusedElement: JQuery<HTMLElement> | null;
// perhaps there should be saved focused element per tab?
function saveFocusedElement() {
$lastFocusedElement = $(":focus");
}
function focusSavedElement() {
if (!$lastFocusedElement) {
return;
}
if ($lastFocusedElement.hasClass("ck")) {
// must handle CKEditor separately because of this bug: https://github.com/ckeditor/ckeditor5/issues/607
// the bug manifests itself in resetting the cursor position to the first character - jumping above
const editor = $lastFocusedElement.closest(".ck-editor__editable").prop("ckeditorInstance");
if (editor) {
editor.editing.view.focus();
} else {
console.log("Could not find CKEditor instance to focus last element");
}
} else {
$lastFocusedElement.focus();
}
$lastFocusedElement = null;
}
async function openDialog($dialog: JQuery<HTMLElement>, closeActDialog = true) {
if (closeActDialog) {
closeActiveDialog();
glob.activeDialog = $dialog;
}
saveFocusedElement();
Modal.getOrCreateInstance($dialog[0]).show();
$dialog.on("hidden.bs.modal", () => {
const $autocompleteEl = $(".aa-input");
if ("autocomplete" in $autocompleteEl) {
$autocompleteEl.autocomplete("close");
}
if (!glob.activeDialog || glob.activeDialog === $dialog) {
focusSavedElement();
}
});
// TODO: Fix once keyboard_actions is ported.
// @ts-ignore
const keyboardActionsService = (await import("./keyboard_actions.js")).default;
keyboardActionsService.updateDisplayedShortcuts($dialog);
return $dialog;
}
function isHtmlEmpty(html: string) {
if (!html) {
return true;
@@ -825,10 +759,6 @@ export default {
setCookie,
getNoteTypeClass,
getMimeTypeClass,
closeActiveDialog,
openDialog,
saveFocusedElement,
focusSavedElement,
isHtmlEmpty,
clearBrowserCache,
copySelectionToClipboard,

View File

@@ -17,7 +17,7 @@ let lastProcessedEntityChangeId = window.glob.maxEntityChangeIdAtLoad;
let lastPingTs: number;
let frontendUpdateDataQueue: EntityChange[] = [];
function logError(message: string) {
export function logError(message: string) {
console.error(utils.now(), message); // needs to be separate from .trace()
if (ws && ws.readyState === 1) {
@@ -301,6 +301,12 @@ setTimeout(() => {
setInterval(sendPing, 1000);
}, 0);
export function throwError(message: string) {
logError(message);
throw new Error(message);
}
export default {
logError,
subscribeToMessages,

View File

@@ -25,6 +25,7 @@
--bs-body-font-weight: var(--main-font-weight) !important;
--bs-body-color: var(--main-text-color) !important;
--bs-body-bg: var(--main-background-color) !important;
--ck-mention-list-max-height: 500px;
}
.table {
@@ -191,6 +192,13 @@ samp {
font-family: var(--monospace-font-family) !important;
}
.badge {
--bs-badge-color: var(--muted-text-color);
margin-left: 8px;
background: var(--accented-background-color);
}
.input-group-text {
background-color: var(--accented-background-color) !important;
color: var(--muted-text-color) !important;
@@ -391,7 +399,7 @@ body.desktop .dropdown-menu {
}
body.desktop .dropdown-menu:not(#context-menu-container) .dropdown-item,
body.desktop #context-menu-container .dropdown-item > span {
body #context-menu-container .dropdown-item > span {
display: flex;
align-items: center;
}
@@ -439,10 +447,11 @@ body.desktop #context-menu-container .dropdown-item > span {
border-radius: 6px;
overflow: hidden;
margin: 4px;
font-size: var(--monospace-font-size);
}
body .cm-editor {
font-size: var(--monospace-font-size);
.cm-scroller {
font-family: var(--monospace-font-family) !important;
}
body .cm-editor .cm-gutters {
@@ -1273,6 +1282,29 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
white-space: normal !important;
}
/* Slash commands */
.ck.ck-slash-command-button {
padding: 0.5em 1em !important;
}
.ck.ck-slash-command-button__text-part,
.ck.ck-template-form__text-part {
margin-left: 0.5em;
line-height: 1.2em !important;
}
.ck.ck-slash-command-button__text-part > span,
.ck.ck-template-form__text-part > span {
line-height: inherit !important;
}
.ck.ck-slash-command-button__text-part .ck.ck-slash-command-button__description,
.ck.ck-template-form__text-part .ck-template-form__description {
display: block;
opacity: 0.8;
}
.area-expander {
display: flex;
flex-direction: row;

View File

@@ -178,6 +178,9 @@
--alert-bar-background: #6b6b6b3b;
--badge-background-color: #ffffff1a;
--badge-text-color: var(--muted-text-color);
--promoted-attribute-card-background-color: var(--card-background-color);
--promoted-attribute-card-shadow-color: #000000b3;

View File

@@ -171,6 +171,9 @@
--alert-bar-background: #32637b29;
--badge-background-color: #00000011;
--badge-text-color: var(--muted-text-color);
--promoted-attribute-card-background-color: var(--card-background-color);
--promoted-attribute-card-shadow-color: #00000033;

View File

@@ -171,6 +171,16 @@ html body .dropdown-item[disabled] {
opacity: var(--menu-item-disabled-opacity);
}
/* Badges */
:root .badge {
--bs-badge-color: var(--badge-text-color);
--bs-badge-font-weight: 500;
background: var(--badge-background-color);
text-transform: uppercase;
letter-spacing: .2pt;
}
/* Menu item icon */
.dropdown-item .bx {
transform: translateY(var(--menu-item-icon-vert-offset));

View File

@@ -382,6 +382,10 @@ div.tn-tool-dialog {
/* DELETE NOTE PREVIEW DIALOG */
.delete-notes-dialog .modal-dialog {
--bs-modal-width: fit-content;
}
.delete-notes-list .note-path {
padding-left: 8px;
}
@@ -395,4 +399,20 @@ div.tn-tool-dialog {
padding-right: 12px;
font-weight: normal;
white-space: nowrap;
}
/*
* NOTE TYPE CHOOSER DIALOG
*/
.note-type-chooser-dialog div.note-type-dropdown {
/* Disable the active item highlighting since there is no use for it here */
--active-item-text-color: initial;
--active-item-background-color: initial;
font-size: unset;
}
.note-type-chooser-dialog div.note-type-dropdown .dropdown-item span.bx {
margin-right: .25em;
}

View File

@@ -267,7 +267,7 @@ input::selection,
}
.input-group button:focus-visible,
.input-group a:focus-visible {
.input-group a:focus-visible:not(.dropdown-item) {
box-shadow: unset;
outline: transparent;
border: transparent;
@@ -349,7 +349,7 @@ select:hover,
select.form-select:hover,
select.form-control:hover,
.select-button.dropdown-toggle.btn:hover {
background: var(--input-hover-background) var(--dropdown-arrow);
background: var(--input-hover-background) var(--dropdown-arrow,);
color: var(--input-hover-color);
}

View File

@@ -201,6 +201,11 @@
color: var(--menu-item-icon-color);
}
/* Slash commands */
.ck.ck-slash-command-button__text-part .ck.ck-button__label {
font-weight: bold;
}
/* Separator */
:root .ck .ck-list__separator {
margin: .5em 0;

View File

@@ -142,6 +142,12 @@ div.note-detail-empty {
border: unset;
}
/* NOTE ATTACHMENTS */
.attachment-list div.links-wrapper {
font-size: unset;
}
/*
* OPTIONS PAGES
*/

View File

@@ -46,6 +46,12 @@ div.promoted-attributes-container {
.image-properties > div:first-child > span > strong {
opacity: 0.65;
font-weight: 500;
vertical-align: top;
}
.note-info-widget-table td,
.file-properties-widget .file-table td {
vertical-align: top;
}
.file-properties-widget {

View File

@@ -71,12 +71,13 @@ body.background-effects.platform-win32.layout-vertical #vertical-main-container
/* #endregion */
/* Matches when the left pane is collapsed */
:has(.layout-vertical #left-pane.hidden-int) {
#horizontal-main-container.left-pane-hidden {
--center-pane-border-radius: 0;
--tab-first-item-horiz-offset: 5px;
}
:has(#left-pane.hidden-int) #launcher-pane.vertical {
/* Add a border to the vertical launch bar if collapsed. */
body.layout-vertical #horizontal-main-container.left-pane-hidden #launcher-pane.vertical {
border-right: 2px solid var(--left-pane-collapsed-border-color);
}
@@ -354,7 +355,7 @@ body.layout-horizontal > .horizontal {
}
.calendar-dropdown-widget .calendar-header .calendar-month-selector .select-button {
--select-arrow-svg: ""; /* Disable the dropdown arrow */
--select-arrow-svg: initial; /* Disable the dropdown arrow */
}
@media (max-width: 992px) {
@@ -1145,12 +1146,18 @@ body.mobile .note-title {
/* The "Change note icon" button */
.note-icon-widget .note-icon {
:root .note-icon-widget button.note-icon,
:root .note-icon-widget button.note-icon:hover {
border: none;
border-radius: 8px;
}
.note-icon-widget .note-icon:hover {
/* Dropdown open */
:root .note-icon-widget button.note-icon.show {
background: var(--ck-editor-toolbar-dropdown-button-open-background);
}
:root .note-icon-widget button.note-icon:not(:disabled):hover {
background: var(--icon-button-hover-background);
color: var(--icon-button-hover-color);
}
@@ -1294,9 +1301,9 @@ div.promoted-attribute-cell .tn-checkbox {
height: 1cap;
}
/* The <div> containing the checkbox for a promoted boolean attribute */
div.promoted-attribute-cell div:has(input[type="checkbox"]) {
order: -1; /* Relocate the checkbox before the label */
/* Relocate the checkbox before the label */
div.promoted-attribute-cell.promoted-attribute-label-boolean > div:first-of-type {
order: -1;
margin-right: 1.5em;
}

View File

@@ -1,6 +1,6 @@
{
"about": {
"title": "关于 TriliumNext Notes",
"title": "关于 Trilium Notes",
"close": "关闭",
"homepage": "项目主页:",
"app_version": "应用版本:",

View File

@@ -1,6 +1,6 @@
{
"about": {
"title": "Über TriliumNext Notes",
"title": "Über Trilium Notes",
"close": "Schließen",
"homepage": "Startseite:",
"app_version": "App-Version:",
@@ -639,7 +639,7 @@
"reload_frontend": "Frontend neu laden",
"show_hidden_subtree": "Versteckten Teilbaum anzeigen",
"show_help": "Hilfe anzeigen",
"about": "Über TriliumNext Notes",
"about": "Über Trilium Notes",
"logout": "Abmelden",
"show-cheatsheet": "Cheatsheet anzeigen",
"toggle-zen-mode": "Zen Modus"

View File

@@ -1,6 +1,6 @@
{
"about": {
"title": "About TriliumNext Notes",
"title": "About Trilium Notes",
"close": "Close",
"homepage": "Homepage:",
"app_version": "App version:",
@@ -233,6 +233,8 @@
"move_success_message": "Selected notes have been moved into "
},
"note_type_chooser": {
"change_path_prompt": "Change where to create the new note:",
"search_placeholder": "search path by name (default if empty)",
"modal_title": "Choose note type",
"close": "Close",
"modal_body": "Choose note type / template of the new note:",
@@ -641,7 +643,7 @@
"reload_frontend": "Reload Frontend",
"show_hidden_subtree": "Show Hidden Subtree",
"show_help": "Show Help",
"about": "About TriliumNext Notes",
"about": "About Trilium Notes",
"logout": "Logout",
"show-cheatsheet": "Show Cheatsheet",
"toggle-zen-mode": "Zen Mode"
@@ -758,7 +760,9 @@
"expand": "Expand",
"book_properties": "Book Properties",
"invalid_view_type": "Invalid view type '{{type}}'",
"calendar": "Calendar"
"calendar": "Calendar",
"table": "Table",
"geo-map": "Geo Map"
},
"edited_notes": {
"no_edited_notes_found": "No edited notes on this day yet...",
@@ -1195,7 +1199,6 @@
"restore_provider": "Restore provider to search",
"similarity_threshold": "Similarity Threshold",
"similarity_threshold_description": "Minimum similarity score (0-1) for notes to be included in context for LLM queries",
"reprocess_index": "Rebuild Search Index",
"reprocessing_index": "Rebuilding...",
"reprocess_index_started": "Search index optimization started in the background",
@@ -1625,7 +1628,8 @@
"geo-map": "Geo Map",
"beta-feature": "Beta",
"ai-chat": "AI Chat",
"task-list": "Task List"
"task-list": "Task List",
"new-feature": "New"
},
"protect_note": {
"toggle-on": "Protect the note",
@@ -1856,7 +1860,8 @@
},
"geo-map-context": {
"open-location": "Open location",
"remove-from-map": "Remove from map"
"remove-from-map": "Remove from map",
"add-note": "Add a marker at this location"
},
"help-button": {
"title": "Open the relevant help page"
@@ -1927,5 +1932,14 @@
"download_link": "Download Native Version",
"continue_anyway": "Continue Anyway",
"dont_show_again": "Don't show this warning again"
},
"editorfeatures": {
"title": "Features",
"emoji_completion_enabled": "Enable Emoji auto-completion",
"note_completion_enabled": "Enable note auto-completion"
},
"table_view": {
"new-row": "New row",
"new-column": "New column"
}
}

View File

@@ -1,6 +1,6 @@
{
"about": {
"title": "Acerca de TriliumNext Notes",
"title": "Acerca de Trilium Notes",
"close": "Cerrar",
"homepage": "Página principal:",
"app_version": "Versión de la aplicación:",
@@ -16,7 +16,7 @@
"message": "Ha ocurrido un error crítico que previene que el cliente de la aplicación inicie:\n\n{{message}}\n\nMuy probablemente es causado por un script que falla de forma inesperada. Intente iniciar la aplicación en modo seguro y atienda el error."
},
"widget-error": {
"title": "No se pudo inicializar un widget",
"title": "Hubo un fallo al inicializar un widget",
"message-custom": "El widget personalizado de la nota con ID \"{{id}}\", titulada \"{{title}}\" no pudo ser inicializado debido a:\n\n{{message}}",
"message-unknown": "Un widget no pudo ser inicializado debido a:\n\n{{message}}"
},
@@ -127,6 +127,7 @@
"collapseSubTree": "colapsar subárbol",
"tabShortcuts": "Atajos de pestañas",
"newTabNoteLink": "<kbd>CTRL+clic</kbd> - (o clic central del mouse) en el enlace de la nota abre la nota en una nueva pestaña",
"newTabWithActivationNoteLink": "<kbd>Ctrl+Shift+clic</kbd> - (o <kbd>Shift+clic de rueda de ratón</kbd>) en el enlace de la nota abre y activa la nota en una nueva pestaña",
"onlyInDesktop": "Solo en escritorio (compilación con Electron)",
"openEmptyTab": "abrir pestaña vacía",
"closeActiveTab": "cerrar pestaña activa",
@@ -232,6 +233,8 @@
"move_success_message": "Las notas seleccionadas se han movido a "
},
"note_type_chooser": {
"change_path_prompt": "Cambiar donde se creará la nueva nota:",
"search_placeholder": "ruta de búsqueda por nombre (por defecto si está vacío)",
"modal_title": "Elija el tipo de nota",
"close": "Cerrar",
"modal_body": "Elija el tipo de nota/plantilla de la nueva nota:",
@@ -274,9 +277,9 @@
"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": "",
"restore_button": "Restaurar",
"confirm_restore": "¿Quiere restaurar esta revisión? Esto sobrescribirá el título actual y el contenido de la nota con esta revisión.",
"delete_button": "",
"delete_button": "Eliminar",
"confirm_delete": "¿Quieres eliminar esta revisión?",
"revisions_deleted": "Se han eliminado las revisiones de nota.",
"revision_restored": "Se ha restaurado la revisión de nota.",
@@ -588,6 +591,7 @@
"sat": "Sáb",
"sun": "Dom",
"cannot_find_day_note": "No se puede encontrar la nota del día",
"cannot_find_week_note": "No se puede encontrar la nota de la semana",
"january": "Enero",
"febuary": "Febrero",
"march": "Marzo",
@@ -639,7 +643,7 @@
"reload_frontend": "Recargar interfaz",
"show_hidden_subtree": "Mostrar subárbol oculto",
"show_help": "Mostrar ayuda",
"about": "Acerca de TriliumNext Notes",
"about": "Acerca de Trilium Notes",
"logout": "Cerrar sesión",
"show-cheatsheet": "Mostrar hoja de trucos",
"toggle-zen-mode": "Modo Zen"
@@ -1121,6 +1125,148 @@
"layout-vertical-description": "la barra del lanzador está en la izquierda (por defecto)",
"layout-horizontal-description": "la barra de lanzamiento está debajo de la barra de pestañas, la barra de pestañas ahora tiene ancho completo."
},
"ai_llm": {
"not_started": "No iniciado",
"title": "IA y ajustes de embeddings",
"processed_notes": "Notas procesadas",
"total_notes": "Notas totales",
"progress": "Progreso",
"queued_notes": "Notas en fila",
"failed_notes": "Notas fallidas",
"last_processed": "Última procesada",
"refresh_stats": "Recargar estadísticas",
"enable_ai_features": "Habilitar características IA/LLM",
"enable_ai_description": "Habilitar características de IA como resumen de notas, generación de contenido y otras capacidades LLM",
"openai_tab": "OpenAI",
"anthropic_tab": "Anthropic",
"voyage_tab": "Voyage AI",
"ollama_tab": "Ollama",
"enable_ai": "Habilitar características IA/LLM",
"enable_ai_desc": "Habilitar características de IA como resumen de notas, generación de contenido y otras capacidades LLM",
"provider_configuration": "Configuración de proveedor de IA",
"provider_precedence": "Precedencia de proveedor",
"provider_precedence_description": "Lista de proveedores en orden de precedencia separada por comas (p.e., 'openai,anthropic,ollama')",
"temperature": "Temperatura",
"temperature_description": "Controla la aleatoriedad de las respuestas (0 = determinista, 2 = aleatoriedad máxima)",
"system_prompt": "Mensaje de sistema",
"system_prompt_description": "Mensaje de sistema predeterminado utilizado para todas las interacciones de IA",
"openai_configuration": "Configuración de OpenAI",
"openai_settings": "Ajustes de OpenAI",
"api_key": "Clave API",
"url": "URL base",
"model": "Modelo",
"openai_api_key_description": "Tu clave API de OpenAI para acceder a sus servicios de IA",
"anthropic_api_key_description": "Tu clave API de Anthropic para acceder a los modelos Claude",
"default_model": "Modelo por defecto",
"openai_model_description": "Ejemplos: gpt-4o, gpt-4-turbo, gpt-3.5-turbo",
"base_url": "URL base",
"openai_url_description": "Por defecto: https://api.openai.com/v1",
"anthropic_settings": "Ajustes de Anthropic",
"anthropic_url_description": "URL base para la API de Anthropic (por defecto: https://api.anthropic.com)",
"anthropic_model_description": "Modelos Claude de Anthropic para el completado de chat",
"voyage_settings": "Ajustes de Voyage AI",
"ollama_settings": "Ajustes de Ollama",
"ollama_url_description": "URL para la API de Ollama (por defecto: http://localhost:11434)",
"ollama_model_description": "Modelo de Ollama a usar para el completado de chat",
"anthropic_configuration": "Configuración de Anthropic",
"voyage_configuration": "Configuración de Voyage AI",
"voyage_url_description": "Por defecto: https://api.voyageai.com/v1",
"ollama_configuration": "Configuración de Ollama",
"enable_ollama": "Habilitar Ollama",
"enable_ollama_description": "Habilitar Ollama para uso de modelo de IA local",
"ollama_url": "URL de Ollama",
"ollama_model": "Modelo de Ollama",
"refresh_models": "Refrescar modelos",
"refreshing_models": "Refrescando...",
"enable_automatic_indexing": "Habilitar indexado automático",
"rebuild_index": "Recrear índice",
"rebuild_index_error": "Error al comenzar la reconstrucción del índice. Consulte los registros para más detalles.",
"note_title": "Título de nota",
"error": "Error",
"last_attempt": "Último intento",
"actions": "Acciones",
"retry": "Reintentar",
"partial": "{{ percentage }}% completado",
"retry_queued": "Nota en la cola para reintento",
"retry_failed": "Hubo un fallo al poner en la cola a la nota para reintento",
"max_notes_per_llm_query": "Máximo de notas por consulta",
"max_notes_per_llm_query_description": "Número máximo de notas similares a incluir en el contexto IA",
"active_providers": "Proveedores activos",
"disabled_providers": "Proveedores deshabilitados",
"remove_provider": "Eliminar proveedor de la búsqueda",
"restore_provider": "Restaurar proveedor a la búsqueda",
"similarity_threshold": "Bias de similaridad",
"similarity_threshold_description": "Puntuación de similaridad mínima (0-1) para incluir notas en el contexto para consultas LLM",
"reprocess_index": "Reconstruir el índice de búsqueda",
"reprocessing_index": "Reconstruyendo...",
"reprocess_index_started": "La optimización de índice de búsqueda comenzó en segundo plano",
"reprocess_index_error": "Error al reconstruir el índice de búsqueda",
"index_rebuild_progress": "Progreso de reconstrucción de índice",
"index_rebuilding": "Optimizando índice ({{percentage}}%)",
"index_rebuild_complete": "Optimización de índice completa",
"index_rebuild_status_error": "Error al comprobar el estado de reconstrucción del índice",
"never": "Nunca",
"processing": "Procesando ({{percentage}}%)",
"incomplete": "Incompleto ({{percentage}}%)",
"complete": "Completo (100%)",
"refreshing": "Refrescando...",
"auto_refresh_notice": "Refrescar automáticamente cada {{seconds}} segundos",
"note_queued_for_retry": "Nota en la cola para reintento",
"failed_to_retry_note": "Hubo un fallo al reintentar nota",
"all_notes_queued_for_retry": "Todas las notas con fallo agregadas a la cola para reintento",
"failed_to_retry_all": "Hubo un fallo al reintentar notas",
"ai_settings": "Ajustes de IA",
"api_key_tooltip": "Clave API para acceder al servicio",
"empty_key_warning": {
"anthropic": "La clave API de Anthropic está vacía. Por favor, ingrese una clave API válida.",
"openai": "La clave API de OpenAI está vacía. Por favor, ingrese una clave API válida.",
"voyage": "La clave API de Voyage está vacía. Por favor, ingrese una clave API válida.",
"ollama": "La clave API de Ollama está vacía. Por favor, ingrese una clave API válida."
},
"agent": {
"processing": "Procesando...",
"thinking": "Pensando...",
"loading": "Cargando...",
"generating": "Generando..."
},
"name": "IA",
"openai": "OpenAI",
"use_enhanced_context": "Utilizar contexto mejorado",
"enhanced_context_description": "Provee a la IA con más contexto de la nota y sus notas relacionadas para obtener mejores respuestas",
"show_thinking": "Mostrar pensamiento",
"show_thinking_description": "Mostrar la cadena del proceso de pensamiento de la IA",
"enter_message": "Ingrese su mensaje...",
"error_contacting_provider": "Error al contactar con su proveedor de IA. Por favor compruebe sus ajustes y conexión a internet.",
"error_generating_response": "Error al generar respuesta de IA",
"index_all_notes": "Indexar todas las notas",
"index_status": "Estado de índice",
"indexed_notes": "Notas indexadas",
"indexing_stopped": "Indexado detenido",
"indexing_in_progress": "Indexado en progreso...",
"last_indexed": "Último indexado",
"n_notes_queued": "{{ count }} nota agregada a la cola para indexado",
"n_notes_queued_plural": "{{ count }} notas agregadas a la cola para indexado",
"note_chat": "Chat de nota",
"notes_indexed": "{{ count }} nota indexada",
"notes_indexed_plural": "{{ count }} notas indexadas",
"sources": "Fuentes",
"start_indexing": "Comenzar indexado",
"use_advanced_context": "Usar contexto avanzado",
"ollama_no_url": "Ollama no está configurado. Por favor ingrese una URL válida.",
"chat": {
"root_note_title": "Chats de IA",
"root_note_content": "Esta nota contiene tus conversaciones de chat de IA guardadas.",
"new_chat_title": "Nuevo chat",
"create_new_ai_chat": "Crear nuevo chat de IA"
},
"create_new_ai_chat": "Crear nuevo chat de IA",
"configuration_warnings": "Hay algunos problemas con su configuración de IA. Por favor compruebe sus ajustes.",
"experimental_warning": "La característica de LLM aún es experimental - ha sido advertido.",
"selected_provider": "Proveedor seleccionado",
"selected_provider_description": "Elija el proveedor de IA para el chat y características de completado",
"select_model": "Seleccionar modelo...",
"select_provider": "Seleccionar proveedor..."
},
"zoom_factor": {
"title": "Factor de zoom (solo versión de escritorio)",
"description": "El zoom también se puede controlar con los atajos CTRL+- y CTRL+=."
@@ -1236,12 +1382,26 @@
"label": "Tamaño para modo de solo lectura automático (notas de texto)",
"unit": "caracteres"
},
"custom_date_time_format": {
"title": "Formato de fecha/hora personalizada",
"description": "Personalizar el formado de fecha y la hora insertada vía <kbd></kbd> o la barra de herramientas. Véa la <a href=\"https://day.js.org/docs/en/display/format\" target=\"_blank\" rel=\"noopener noreferrer\">documentación de Day.js</a> para más tokens de formato disponibles.",
"format_string": "Cadena de formato:",
"formatted_time": "Fecha/hora personalizada:"
},
"i18n": {
"title": "Localización",
"language": "Idioma",
"first-day-of-the-week": "Primer día de la semana",
"sunday": "Domingo",
"monday": "Lunes"
"monday": "Lunes",
"first-week-of-the-year": "Primer semana del año",
"first-week-contains-first-day": "Primer semana que contiene al primer día del año",
"first-week-contains-first-thursday": "Primer semana que contiene al primer jueves del año",
"first-week-has-minimum-days": "Primer semana que contiene un mínimo de días",
"min-days-in-first-week": "Días mínimos en la primer semana",
"first-week-info": "Primer semana que contiene al primer jueves del año está basado en el estándar<a href=\"https://en.wikipedia.org/wiki/ISO_week_date#First_week\">ISO 8601</a>.",
"first-week-warning": "Cambiar las opciones de primer semana puede causar duplicados con las Notas Semanales existentes y las Notas Semanales existentes no serán actualizadas respectivamente.",
"formatting-locale": "Fecha y formato de número"
},
"backup": {
"automatic_backup": "Copia de seguridad automática",
@@ -1308,6 +1468,39 @@
"password_mismatch": "Las nuevas contraseñas no son las mismas.",
"password_changed_success": "La contraseña ha sido cambiada. Trilium se recargará después de presionar Aceptar."
},
"multi_factor_authentication": {
"title": "Autenticación Multi-Factor",
"description": "La autenticación multifactor (MFA) agrega una capa adicional de seguridad a su cuenta. En lugar de solo ingresar una contraseña para iniciar sesión, MFA requiere que proporcione una o más pruebas adicionales para verificar su identidad. De esta manera, incluso si alguien se apodera de su contraseña, aún no puede acceder a su cuenta sin la segunda pieza de información. Es como agregar una cerradura adicional a su puerta, lo que hace que sea mucho más difícil para cualquier otra persona entrar.<br><br>Por favor siga las instrucciones a continuación para habilitar MFA. Si no lo configura correctamente, el inicio de sesión volverá a solo contraseña.",
"mfa_enabled": "Habilitar la autenticación multifactor",
"mfa_method": "Método MFA",
"electron_disabled": "Actualmente la autenticación multifactor no está soportada en la compilación de escritorio.",
"totp_title": "Contraseña de un solo uso basada en el tiempo (TOTP)",
"totp_description": "TOTP (contraseña de un solo uso basada en el tiempo) es una característica de seguridad que genera un código temporal único que cambia cada 30 segundos. Utiliza este código, junto con su contraseña para iniciar sesión en su cuenta, lo que hace que sea mucho más difícil para cualquier otra persona acceder a ella.",
"totp_secret_title": "Generar secreto TOTP",
"totp_secret_generate": "Generar secreto TOTP",
"totp_secret_regenerate": "Regenerar secreto TOTP",
"no_totp_secret_warning": "Para habilitar TOTP, primero debe de generar un secreto TOTP.",
"totp_secret_description_warning": "Después de generar un nuevo secreto TOTP, le será requerido que inicie sesión otra vez con el nuevo secreto TOTP.",
"totp_secret_generated": "Secreto TOTP generado",
"totp_secret_warning": "Por favor guarde el secreto generado en una ubicación segura. No será mostrado de nuevo.",
"totp_secret_regenerate_confirm": "¿Está seguro que desea regenerar el secreto TOTP? Esto va a invalidar el secreto TOTP previo y todos los códigos de recuperación existentes.",
"recovery_keys_title": "Claves de recuperación para un solo inicio de sesión",
"recovery_keys_description": "Las claves de recuperación para un solo inicio de sesión son usadas para iniciar sesión incluso cuando no puede acceder a los códigos de su autentificador.",
"recovery_keys_description_warning": "Las claves de recuperación no son mostrada de nuevo después de dejar esta página, manténgalas en un lugar seguro.<br>Después de que una clave de recuperación es utilizada ya no puede utilizarse de nuevo.",
"recovery_keys_error": "Error al generar códigos de recuperación",
"recovery_keys_no_key_set": "No hay códigos de recuperación establecidos",
"recovery_keys_generate": "Generar códigos de recuperación",
"recovery_keys_regenerate": "Regenerar códigos de recuperación",
"recovery_keys_used": "Usado: {{date}}",
"recovery_keys_unused": "El código de recuperación {{index}} está sin usar",
"oauth_title": "OAuth/OpenID",
"oauth_description": "OpenID es una forma estandarizada de permitirle iniciar sesión en sitios web utilizando una cuenta de otro servicio, como Google, para verificar su identidad. Siga estas <a href = \"https://developers.google.com/identity/openid-connect/openid-connect\">instrucciones</a> para configurar un servicio OpenID a través de Google.",
"oauth_description_warning": "Para habilitar OAuth/OpenID, necesita establecer la URL base de OAuth/OpenID, ID de cliente y secreto de cliente en el archivo config.ini y reiniciar la aplicación. Si desea establecerlas desde variables de ambiente, por favor establezca TRILIUM_OAUTH_BASE_URL, TRILIUM_OAUTH_CLIENT_ID y TRILIUM_OAUTH_CLIENT_SECRET.",
"oauth_missing_vars": "Ajustes faltantes: {{variables}}",
"oauth_user_account": "Cuenta de usuario: ",
"oauth_user_email": "Correo electrónico de usuario: ",
"oauth_user_not_logged_in": "¡No ha iniciado sesión!"
},
"shortcuts": {
"keyboard_shortcuts": "Atajos de teclado",
"multiple_shortcuts": "Varios atajos para la misma acción se pueden separar mediante comas.",
@@ -1431,7 +1624,9 @@
"widget": "Widget",
"confirm-change": "No es recomendado cambiar el tipo de nota cuando el contenido de la nota no está vacío. ¿Desea continuar de cualquier manera?",
"geo-map": "Mapa Geo",
"beta-feature": "Beta"
"beta-feature": "Beta",
"ai-chat": "Chat de IA",
"task-list": "Lista de tareas"
},
"protect_note": {
"toggle-on": "Proteger la nota",
@@ -1541,7 +1736,9 @@
},
"clipboard": {
"cut": "La(s) notas(s) han sido cortadas al portapapeles.",
"copied": "La(s) notas(s) han sido copiadas al portapapeles."
"copied": "La(s) notas(s) han sido copiadas al portapapeles.",
"copy_failed": "No se puede copiar al portapapeles debido a problemas de permisos.",
"copy_success": "Copiado al portapapeles."
},
"entrypoints": {
"note-revision-created": "Una revisión de nota ha sido creada.",
@@ -1584,7 +1781,7 @@
"auto-detect-language": "Detectado automáticamente"
},
"highlighting": {
"title": "",
"title": "Bloques de código",
"description": "Controla el resaltado de sintaxis para bloques de código dentro de las notas de texto, las notas de código no serán afectadas.",
"color-scheme": "Esquema de color"
},
@@ -1592,7 +1789,8 @@
"word_wrapping": "Ajuste de palabras",
"theme_none": "Sin resaltado de sintaxis",
"theme_group_light": "Temas claros",
"theme_group_dark": "Temas oscuros"
"theme_group_dark": "Temas oscuros",
"copy_title": "Copiar al portapapeles"
},
"classic_editor_toolbar": {
"title": "Formato"
@@ -1713,5 +1911,22 @@
},
"png_export_button": {
"button_title": "Exportar diagrama como PNG"
},
"svg": {
"export_to_png": "El diagrama no pudo ser exportado a PNG."
},
"code_theme": {
"title": "Apariencia",
"word_wrapping": "Ajuste de palabras",
"color-scheme": "Esquema de color"
},
"cpu_arch_warning": {
"title": "Por favor descargue la versión ARM64",
"message_macos": "TriliumNext está siendo ejecutado bajo traducción Rosetta 2, lo que significa que está usando la versión Intel (x64) en Apple Silicon Mac. Esto impactará significativamente en el rendimiento y la vida de la batería.",
"message_windows": "TriliumNext está siendo ejecutado bajo emulación, lo que significa que está usando la version Intel (x64) en Windows en un dispositivo ARM. Esto impactará significativamente en el rendimiento y la vida de la batería.",
"recommendation": "Para la mejor experiencia, por favor descargue la versión nativa ARM64 de TriliumNext desde nuestra página de lanzamientos.",
"download_link": "Descargar versión nativa",
"continue_anyway": "Continuar de todas maneras",
"dont_show_again": "No mostrar esta advertencia otra vez"
}
}

View File

@@ -1,6 +1,6 @@
{
"about": {
"title": "À propos de TriliumNext Notes",
"title": "À propos de Trilium Notes",
"close": "Fermer",
"homepage": "Page d'accueil :",
"app_version": "Version de l'application :",
@@ -639,7 +639,7 @@
"reload_frontend": "Recharger l'interface",
"show_hidden_subtree": "Afficher le Sous-arbre caché",
"show_help": "Afficher l'aide",
"about": "À propos de TriliumNext Notes",
"about": "À propos de Trilium Notes",
"logout": "Déconnexion",
"show-cheatsheet": "Afficher l'aide rapide",
"toggle-zen-mode": "Zen Mode"

View File

@@ -1,6 +1,6 @@
{
"about": {
"title": "Despre TriliumNext Notes",
"title": "Despre Trilium Notes",
"homepage": "Site web:",
"app_version": "Versiune aplicație:",
"db_version": "Versiune bază de date:",
@@ -572,7 +572,7 @@
"system-default": "Fontul predefinit al sistemului"
},
"global_menu": {
"about": "Despre TriliumNext Notes",
"about": "Despre Trilium Notes",
"advanced": "Opțiuni avansate",
"configure_launchbar": "Configurează bara de lansare",
"logout": "Deautentificare",

View File

@@ -1,6 +1,6 @@
{
"about": {
"title": "關於 TriliumNext Notes",
"title": "關於 Trilium Notes",
"homepage": "項目主頁:",
"app_version": "軟件版本:",
"db_version": "資料庫版本:",

View File

@@ -8,4 +8,9 @@ declare module "*?url" {
export default path;
}
declare module "*?raw" {
var content: string;
export default content;
}
declare module "boxicons/css/boxicons.min.css" { }

16
apps/client/src/vite-env.d.ts vendored Normal file
View File

@@ -0,0 +1,16 @@
/// <reference types="vite/client" />
interface ViteTypeOptions {
strictImportMetaEnv: unknown
}
interface ImportMetaEnv {
/** The license key for CKEditor premium features. */
readonly VITE_CKEDITOR_KEY?: string;
/** Whether to enable the CKEditor inspector (see https://ckeditor.com/docs/ckeditor5/latest/framework/develpment-tools/inspector.html). */
readonly VITE_CKEDITOR_ENABLE_INSPECTOR?: "true" | "false";
}
interface ImportMeta {
readonly env: ImportMetaEnv
}

View File

@@ -11,6 +11,7 @@ import utils from "../../services/utils.js";
import shortcutService from "../../services/shortcuts.js";
import appContext from "../../components/app_context.js";
import type { Attribute } from "../../services/attribute_parser.js";
import { focusSavedElement, saveFocusedElement } from "../../services/focus.js";
const TPL = /*html*/`
<div class="attr-detail tn-tool-dialog">
@@ -483,7 +484,7 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget {
return;
}
utils.saveFocusedElement();
saveFocusedElement();
this.attrType = this.getAttrType(attribute);
@@ -605,7 +606,7 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget {
this.hide();
utils.focusSavedElement();
focusSavedElement();
}
async cancelAndClose() {
@@ -613,7 +614,7 @@ export default class AttributeDetailWidget extends NoteContextAwareWidget {
this.hide();
utils.focusSavedElement();
focusSavedElement();
}
userEditedAttribute() {

View File

@@ -424,7 +424,7 @@ export default class GlobalMenuWidget extends BasicWidget {
}
downloadLatestVersionCommand() {
window.open("https://github.com/TriliumNext/Notes/releases/latest");
window.open("https://github.com/TriliumNext/Trilium/releases/latest");
}
activeContextChangedEvent() {

View File

@@ -189,7 +189,7 @@ export default class NoteActionsWidget extends NoteContextAwareWidget {
this.toggleDisabled(this.$findInTextButton, ["text", "code", "book", "mindMap"].includes(note.type));
this.toggleDisabled(this.$showAttachmentsButton, !isInOptions);
this.toggleDisabled(this.$showSourceButton, ["text", "code", "relationMap", "mermaid", "canvas", "mindMap", "geoMap"].includes(note.type));
this.toggleDisabled(this.$showSourceButton, ["text", "code", "relationMap", "mermaid", "canvas", "mindMap"].includes(note.type));
const canPrint = ["text", "code"].includes(note.type);
this.toggleDisabled(this.$printActiveNoteButton, canPrint);

View File

@@ -5,7 +5,7 @@ import type Component from "../../components/component.js";
export default class LeftPaneContainer extends FlexContainer<Component> {
private currentLeftPaneVisible: boolean;
constructor() {
super("column");
@@ -24,6 +24,7 @@ export default class LeftPaneContainer extends FlexContainer<Component> {
this.currentLeftPaneVisible = leftPaneVisible ?? !this.currentLeftPaneVisible;
const visible = this.isEnabled();
this.toggleInt(visible);
this.parent?.$widget.toggleClass("left-pane-hidden", !visible);
if (visible) {
this.triggerEvent("focusTree", {});

View File

@@ -4,6 +4,7 @@ import BasicWidget from "../basic_widget.js";
import openService from "../../services/open.js";
import server from "../../services/server.js";
import utils from "../../services/utils.js";
import { openDialog } from "../../services/dialog.js";
interface AppInfo {
appVersion: string;
@@ -26,7 +27,7 @@ const TPL = /*html*/`
<table class="table table-borderless">
<tr>
<th>${t("about.homepage")}</th>
<td><a class="tn-link" href="https://github.com/TriliumNext/Notes" class="external">https://github.com/TriliumNext/Notes</a></td>
<td><a class="tn-link" href="https://github.com/TriliumNext/Trilium" class="external">https://github.com/TriliumNext/Trilium</a></td>
</tr>
<tr>
<th>${t("about.app_version")}</th>
@@ -91,7 +92,7 @@ export default class AboutDialog extends BasicWidget {
this.$syncVersion.text(appInfo.syncVersion.toString());
this.$buildDate.text(formatDateTime(appInfo.buildDate));
this.$buildRevision.text(appInfo.buildRevision);
this.$buildRevision.attr("href", `https://github.com/TriliumNext/Notes/commit/${appInfo.buildRevision}`);
this.$buildRevision.attr("href", `https://github.com/TriliumNext/Trilium/commit/${appInfo.buildRevision}`);
if (utils.isElectron()) {
this.$dataDirectory.html(
$("<a></a>", {
@@ -111,6 +112,6 @@ export default class AboutDialog extends BasicWidget {
async openAboutDialogEvent() {
await this.refresh();
utils.openDialog(this.$widget);
openDialog(this.$widget);
}
}

View File

@@ -1,11 +1,11 @@
import { t } from "../../services/i18n.js";
import treeService from "../../services/tree.js";
import noteAutocompleteService from "../../services/note_autocomplete.js";
import utils from "../../services/utils.js";
import BasicWidget from "../basic_widget.js";
import type { Suggestion } from "../../services/note_autocomplete.js";
import type { default as TextTypeWidget } from "../type_widgets/editable_text.js";
import type { EventData } from "../../components/app_context.js";
import { openDialog } from "../../services/dialog.js";
const TPL = /*html*/`
<div class="add-link-dialog modal mx-auto" tabindex="-1" role="dialog">
@@ -111,7 +111,7 @@ export default class AddLinkDialog extends BasicWidget {
this.updateTitleSettingsVisibility();
utils.openDialog(this.$widget);
await openDialog(this.$widget);
this.$autoComplete.val("");
this.$linkTitle.val("");

View File

@@ -2,11 +2,11 @@ import treeService from "../../services/tree.js";
import server from "../../services/server.js";
import froca from "../../services/froca.js";
import toastService from "../../services/toast.js";
import utils from "../../services/utils.js";
import BasicWidget from "../basic_widget.js";
import appContext from "../../components/app_context.js";
import { t } from "../../services/i18n.js";
import { Modal } from "bootstrap";
import { openDialog } from "../../services/dialog.js";
const TPL = /*html*/`<div class="branch-prefix-dialog modal fade mx-auto" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document">
@@ -93,7 +93,7 @@ export default class BranchPrefixDialog extends BasicWidget {
}
await this.refresh(notePath);
utils.openDialog(this.$widget);
openDialog(this.$widget);
}
async savePrefix() {

View File

@@ -1,11 +1,11 @@
import BasicWidget from "../basic_widget.js";
import froca from "../../services/froca.js";
import bulkActionService from "../../services/bulk_action.js";
import utils from "../../services/utils.js";
import server from "../../services/server.js";
import toastService from "../../services/toast.js";
import { t } from "../../services/i18n.js";
import type { EventData } from "../../components/app_context.js";
import { closeActiveDialog, openDialog } from "../../services/dialog.js";
const TPL = /*html*/`
@@ -104,7 +104,7 @@ export default class BulkActionsDialog extends BasicWidget {
});
toastService.showMessage(t("bulk_actions.bulk_actions_executed"), 3000);
utils.closeActiveDialog();
closeActiveDialog();
});
}
@@ -170,6 +170,6 @@ export default class BulkActionsDialog extends BasicWidget {
this.$includeDescendants.prop("checked", false);
await this.refresh();
utils.openDialog(this.$widget);
openDialog(this.$widget);
}
}

View File

@@ -1,5 +1,4 @@
import noteAutocompleteService from "../../services/note_autocomplete.js";
import utils from "../../services/utils.js";
import treeService from "../../services/tree.js";
import toastService from "../../services/toast.js";
import froca from "../../services/froca.js";
@@ -8,6 +7,7 @@ import appContext from "../../components/app_context.js";
import BasicWidget from "../basic_widget.js";
import { t } from "../../services/i18n.js";
import type { EventData } from "../../components/app_context.js";
import { openDialog } from "../../services/dialog.js";
const TPL = /*html*/`
@@ -94,7 +94,7 @@ export default class CloneToDialog extends BasicWidget {
}
}
utils.openDialog(this.$widget);
openDialog(this.$widget);
this.$noteAutoComplete.val("").trigger("focus");
this.$noteList.empty();

View File

@@ -1,10 +1,10 @@
import server from "../../services/server.js";
import froca from "../../services/froca.js";
import linkService from "../../services/link.js";
import utils from "../../services/utils.js";
import BasicWidget from "../basic_widget.js";
import { t } from "../../services/i18n.js";
import type { FAttributeRow } from "../../entities/fattribute.js";
import { closeActiveDialog, openDialog } from "../../services/dialog.js";
// TODO: Use common with server.
interface Response {
@@ -119,13 +119,13 @@ export default class DeleteNotesDialog extends BasicWidget {
this.$widget.on("shown.bs.modal", () => this.$okButton.trigger("focus"));
this.$cancelButton.on("click", () => {
utils.closeActiveDialog();
closeActiveDialog();
this.resolve({ proceed: false });
});
this.$okButton.on("click", () => {
utils.closeActiveDialog();
closeActiveDialog();
this.resolve({
proceed: true,
@@ -179,7 +179,7 @@ export default class DeleteNotesDialog extends BasicWidget {
await this.renderDeletePreview();
utils.openDialog(this.$widget);
openDialog(this.$widget);
this.$deleteAllClones.prop("checked", !!forceDeleteAllClones).prop("disabled", !!forceDeleteAllClones);

View File

@@ -8,6 +8,7 @@ import BasicWidget from "../basic_widget.js";
import { t } from "../../services/i18n.js";
import type { EventData } from "../../components/app_context.js";
import { Modal } from "bootstrap";
import { openDialog } from "../../services/dialog.js";
const TPL = /*html*/`
<div class="export-dialog modal fade mx-auto" tabindex="-1" role="dialog">
@@ -214,7 +215,7 @@ export default class ExportDialog extends BasicWidget {
this.$widget.find(".opml-v2").prop("checked", true); // setting default
utils.openDialog(this.$widget);
openDialog(this.$widget);
const { noteId, parentNoteId } = treeService.getNoteIdAndParentIdFromUrl(notePath);

View File

@@ -1,6 +1,6 @@
import utils from "../../services/utils.js";
import BasicWidget from "../basic_widget.js";
import { t } from "../../services/i18n.js";
import { openDialog } from "../../services/dialog.js";
const TPL = /*html*/`
<div class="help-dialog modal use-tn-links" tabindex="-1" role="dialog">
@@ -155,6 +155,6 @@ export default class HelpDialog extends BasicWidget {
}
showCheatsheetEvent() {
utils.openDialog(this.$widget);
openDialog(this.$widget);
}
}

View File

@@ -1,4 +1,4 @@
import utils, { escapeQuotes } from "../../services/utils.js";
import { escapeQuotes } from "../../services/utils.js";
import treeService from "../../services/tree.js";
import importService, { type UploadFilesOptions } from "../../services/import.js";
import options from "../../services/options.js";
@@ -6,6 +6,7 @@ import BasicWidget from "../basic_widget.js";
import { t } from "../../services/i18n.js";
import { Modal, Tooltip } from "bootstrap";
import type { EventData } from "../../components/app_context.js";
import { openDialog } from "../../services/dialog.js";
const TPL = /*html*/`
<div class="import-dialog modal fade mx-auto" tabindex="-1" role="dialog">
@@ -155,7 +156,7 @@ export default class ImportDialog extends BasicWidget {
this.$noteTitle.text(await treeService.getNoteTitle(this.parentNoteId));
utils.openDialog(this.$widget);
openDialog(this.$widget);
}
async importIntoNote(parentNoteId: string) {

View File

@@ -1,12 +1,12 @@
import { t } from "../../services/i18n.js";
import treeService from "../../services/tree.js";
import noteAutocompleteService from "../../services/note_autocomplete.js";
import utils from "../../services/utils.js";
import froca from "../../services/froca.js";
import BasicWidget from "../basic_widget.js";
import { Modal } from "bootstrap";
import type { EventData } from "../../components/app_context.js";
import type EditableTextTypeWidget from "../type_widgets/editable_text.js";
import { openDialog } from "../../services/dialog.js";
const TPL = /*html*/`
<div class="include-note-dialog modal mx-auto" tabindex="-1" role="dialog">
@@ -83,7 +83,7 @@ export default class IncludeNoteDialog extends BasicWidget {
async showIncludeNoteDialogEvent({ textTypeWidget }: EventData<"showIncludeDialog">) {
this.textTypeWidget = textTypeWidget;
await this.refresh();
utils.openDialog(this.$widget);
openDialog(this.$widget);
this.$autoComplete.trigger("focus").trigger("select"); // to be able to quickly remove entered text
}

View File

@@ -41,9 +41,9 @@ export default class IncorrectCpuArchDialog extends BasicWidget {
// Open the releases page where users can download the correct version
if (utils.isElectron()) {
const { shell } = utils.dynamicRequire("electron");
shell.openExternal("https://github.com/TriliumNext/Notes/releases/latest");
shell.openExternal("https://github.com/TriliumNext/Trilium/releases/latest");
} else {
window.open("https://github.com/TriliumNext/Notes/releases/latest", "_blank");
window.open("https://github.com/TriliumNext/Trilium/releases/latest", "_blank");
}
});

View File

@@ -1,9 +1,9 @@
import type { EventData } from "../../components/app_context.js";
import { t } from "../../services/i18n.js";
import utils from "../../services/utils.js";
import BasicWidget from "../basic_widget.js";
import { Modal } from "bootstrap";
import type { ConfirmDialogCallback } from "./confirm.js";
import { openDialog } from "../../services/dialog.js";
const TPL = /*html*/`
<div class="info-dialog modal mx-auto" tabindex="-1" role="dialog" style="z-index: 2000;">
@@ -72,7 +72,7 @@ export default class InfoDialog extends BasicWidget {
}
utils.openDialog(this.$widget);
openDialog(this.$widget);
this.resolve = callback;
}

View File

@@ -5,6 +5,7 @@ import appContext from "../../components/app_context.js";
import BasicWidget from "../basic_widget.js";
import shortcutService from "../../services/shortcuts.js";
import { Modal } from "bootstrap";
import { openDialog } from "../../services/dialog.js";
const TPL = /*html*/`<div class="jump-to-note-dialog modal mx-auto" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg" role="document">
@@ -54,7 +55,7 @@ export default class JumpToNoteDialog extends BasicWidget {
}
async jumpToNoteEvent() {
const dialogPromise = utils.openDialog(this.$widget);
const dialogPromise = openDialog(this.$widget);
if (utils.isMobile()) {
dialogPromise.then(($dialog) => {
const el = $dialog.find(">.modal-dialog")[0];

View File

@@ -6,6 +6,7 @@ import BasicWidget from "../basic_widget.js";
import shortcutService from "../../services/shortcuts.js";
import server from "../../services/server.js";
import { Modal } from "bootstrap";
import { openDialog } from "../../services/dialog.js";
const TPL = /*html*/`
<div class="markdown-import-dialog modal fade mx-auto" tabindex="-1" role="dialog">
@@ -89,7 +90,7 @@ export default class MarkdownImportDialog extends BasicWidget {
this.convertMarkdownToHtml(text);
} else {
utils.openDialog(this.$widget);
openDialog(this.$widget);
}
}

View File

@@ -1,5 +1,4 @@
import noteAutocompleteService from "../../services/note_autocomplete.js";
import utils from "../../services/utils.js";
import toastService from "../../services/toast.js";
import froca from "../../services/froca.js";
import branchService from "../../services/branches.js";
@@ -7,6 +6,7 @@ import treeService from "../../services/tree.js";
import BasicWidget from "../basic_widget.js";
import { t } from "../../services/i18n.js";
import type { EventData } from "../../components/app_context.js";
import { openDialog } from "../../services/dialog.js";
const TPL = /*html*/`
<div class="move-to-dialog modal mx-auto" tabindex="-1" role="dialog">
@@ -83,7 +83,7 @@ export default class MoveToDialog extends BasicWidget {
async moveBranchIdsToEvent({ branchIds }: EventData<"moveBranchIdsTo">) {
this.movedBranchIds = branchIds;
utils.openDialog(this.$widget);
openDialog(this.$widget);
this.$noteAutoComplete.val("").trigger("focus");

View File

@@ -2,6 +2,7 @@ import type { CommandNames } from "../../components/app_context.js";
import type { MenuCommandItem } from "../../menus/context_menu.js";
import { t } from "../../services/i18n.js";
import noteTypesService from "../../services/note_types.js";
import noteAutocompleteService from "../../services/note_autocomplete.js";
import BasicWidget from "../basic_widget.js";
import { Dropdown, Modal } from "bootstrap";
@@ -13,6 +14,11 @@ const TPL = /*html*/`
z-index: 1100 !important;
}
.note-type-chooser-dialog .input-group {
margin-top: 15px;
margin-bottom: 15px;
}
.note-type-chooser-dialog .note-type-dropdown {
position: relative;
font-size: large;
@@ -30,6 +36,12 @@ const TPL = /*html*/`
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="${t("note_type_chooser.close")}"></button>
</div>
<div class="modal-body">
${t("note_type_chooser.change_path_prompt")}
<div class="input-group">
<input class="choose-note-path form-control" placeholder="${t("note_type_chooser.search_placeholder")}">
</div>
${t("note_type_chooser.modal_body")}
<div class="dropdown" style="display: flex;">
@@ -37,7 +49,7 @@ const TPL = /*html*/`
data-bs-toggle="dropdown" data-bs-display="static">
</button>
<div class="note-type-dropdown dropdown-menu"></div>
<div class="note-type-dropdown dropdown-menu static"></div>
</div>
</div>
</div>
@@ -48,6 +60,7 @@ export interface ChooseNoteTypeResponse {
success: boolean;
noteType?: string;
templateNoteId?: string;
notePath?: string;
}
type Callback = (data: ChooseNoteTypeResponse) => void;
@@ -57,6 +70,7 @@ export default class NoteTypeChooserDialog extends BasicWidget {
private dropdown!: Dropdown;
private modal!: Modal;
private $noteTypeDropdown!: JQuery<HTMLElement>;
private $autoComplete!: JQuery<HTMLElement>;
private $originalFocused: JQuery<HTMLElement> | null;
private $originalDialog: JQuery<HTMLElement> | null;
@@ -71,7 +85,8 @@ export default class NoteTypeChooserDialog extends BasicWidget {
doRender() {
this.$widget = $(TPL);
this.modal = Modal.getOrCreateInstance(this.$widget[0]);
this.$autoComplete = this.$widget.find(".choose-note-path");
this.$noteTypeDropdown = this.$widget.find(".note-type-dropdown");
this.dropdown = Dropdown.getOrCreateInstance(this.$widget.find(".note-type-dropdown-trigger")[0]);
@@ -116,9 +131,20 @@ export default class NoteTypeChooserDialog extends BasicWidget {
});
}
async refresh() {
noteAutocompleteService
.initNoteAutocomplete(this.$autoComplete, {
allowCreatingNotes: false,
hideGoToSelectedNoteButton: true,
allowJumpToSearchNotes: false,
})
}
async chooseNoteTypeEvent({ callback }: { callback: Callback }) {
this.$originalFocused = $(":focus");
await this.refresh();
const noteTypes = await noteTypesService.getNoteTypeItems();
this.$noteTypeDropdown.empty();
@@ -128,13 +154,21 @@ export default class NoteTypeChooserDialog extends BasicWidget {
this.$noteTypeDropdown.append($('<h6 class="dropdown-header">').append(t("note_type_chooser.templates")));
} else {
const commandItem = noteType as MenuCommandItem<CommandNames>;
this.$noteTypeDropdown.append(
$('<a class="dropdown-item" tabindex="0">')
.attr("data-note-type", commandItem.type || "")
.attr("data-template-note-id", commandItem.templateNoteId || "")
.append($("<span>").addClass(commandItem.uiIcon || ""))
.append(` ${noteType.title}`)
);
const listItem = $('<a class="dropdown-item" tabindex="0">')
.attr("data-note-type", commandItem.type || "")
.attr("data-template-note-id", commandItem.templateNoteId || "")
.append($("<span>").addClass(commandItem.uiIcon || ""))
.append(` ${noteType.title}`);
if (commandItem.badges) {
for (let badge of commandItem.badges) {
listItem.append($(`<span class="badge">`)
.addClass(badge.className || "")
.text(badge.title));
}
}
this.$noteTypeDropdown.append(listItem);
}
}
@@ -153,12 +187,14 @@ export default class NoteTypeChooserDialog extends BasicWidget {
const $item = $(e.target).closest(".dropdown-item");
const noteType = $item.attr("data-note-type");
const templateNoteId = $item.attr("data-template-note-id");
const notePath = this.$autoComplete.getSelectedNotePath() || undefined;
if (this.resolve) {
this.resolve({
success: true,
noteType,
templateNoteId
templateNoteId,
notePath
});
}
this.resolve = null;

View File

@@ -1,5 +1,5 @@
import { openDialog } from "../../services/dialog.js";
import { t } from "../../services/i18n.js";
import utils from "../../services/utils.js";
import BasicWidget from "../basic_widget.js";
import { Modal } from "bootstrap";
@@ -37,6 +37,6 @@ export default class PasswordNoteSetDialog extends BasicWidget {
}
showPasswordNotSetEvent() {
utils.openDialog(this.$widget);
openDialog(this.$widget);
}
}

View File

@@ -1,5 +1,5 @@
import { openDialog } from "../../services/dialog.js";
import { t } from "../../services/i18n.js";
import utils from "../../services/utils.js";
import BasicWidget from "../basic_widget.js";
import { Modal } from "bootstrap";
@@ -110,6 +110,6 @@ export default class PromptDialog extends BasicWidget {
this.$dialogBody.empty().append($("<div>").addClass("form-group").append(this.$question).append(this.$answer));
utils.openDialog(this.$widget, false);
openDialog(this.$widget, false);
}
}

View File

@@ -1,6 +1,6 @@
import { openDialog } from "../../services/dialog.js";
import { t } from "../../services/i18n.js";
import protectedSessionService from "../../services/protected_session.js";
import utils from "../../services/utils.js";
import BasicWidget from "../basic_widget.js";
import { Modal } from "bootstrap";
@@ -49,7 +49,7 @@ export default class ProtectedSessionPasswordDialog extends BasicWidget {
}
showProtectedSessionPasswordDialogEvent() {
utils.openDialog(this.$widget);
openDialog(this.$widget);
this.$passwordInput.trigger("focus");
}

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