Compare commits

...

90 Commits

Author SHA1 Message Date
zadam
fdce218e88 release 0.46.5 2021-03-14 22:56:27 +01:00
zadam
6c8d20288d fix 0.46 regression to set up sync from client, fixes #1742 2021-03-13 22:54:00 +01:00
zadam
88d04772c4 make sure the CLS entity changes are cleared after roll backed transaction, #1736 2021-03-12 23:48:14 +01:00
zadam
9fd26a9b9f when creating new note into inbox use current hoisted note in new tab as well 2021-03-12 21:47:26 +01:00
zadam
98f02c3c9a added "hoistedInbox" label 2021-03-12 21:29:50 +01:00
zadam
584fea1992 Revert "delete notes skeleton dialog"
This reverts commit 03a11e6f
2021-03-12 20:44:19 +01:00
zadam
af50a1ec52 Merge remote-tracking branch 'origin/stable' into stable 2021-03-12 20:39:51 +01:00
zadam
4e76d1fa85 hide some "boring" attributes from book listing view 2021-03-12 20:39:42 +01:00
zadam
03a11e6f77 delete notes skeleton dialog 2021-03-11 22:35:53 +01:00
zadam
e1a16b4a9f defensive check, #1736 2021-03-11 20:28:07 +01:00
zadam
12b468d3dc release 0.46.4-beta 2021-03-10 23:35:12 +01:00
zadam
6f901e6852 use icons instead of plain text to differentiate between different paths in note paths widget 2021-03-10 23:11:48 +01:00
zadam
09e9ac4d00 prevent cycles in resolving the notepath, fixes #1730 2021-03-10 22:54:55 +01:00
zadam
a33ac65fdf fix focus on moving notes with keyboard 2021-03-09 22:24:59 +01:00
zadam
f8fb071a6f added option to bring back plain (non-markdown) headings, closes #1678 2021-03-09 22:06:40 +01:00
zadam
a654078e56 fix broken template copy, closes #1724 2021-03-09 20:51:57 +01:00
zadam
fba68681aa when resolving note path check if there's a hoisted note in it, if not, try again to find some path with hoisted note, closes #1718 2021-03-09 20:37:56 +01:00
zadam
50c84e0f5f release 0.46.3-beta 2021-03-08 23:11:11 +01:00
zadam
f27370d44f fix putting focus back to the note tree after note deletion 2021-03-08 23:10:34 +01:00
zadam
c6c9202c00 fix note icon color in dark mode 2021-03-08 22:06:26 +01:00
zadam
2cafda5f66 note paths visually distinguishes between different note paths, closes #1669 2021-03-08 22:04:52 +01:00
zadam
873953cbaf fix bug 2021-03-08 00:09:48 +01:00
zadam
d51744ce19 make note paths current path underlined 2021-03-08 00:07:00 +01:00
zadam
7df8c940b6 have paths in "note paths" widget also sorted by priority 2021-03-08 00:04:43 +01:00
zadam
9bac2a4819 refresh inherited attribute list after attr change, closes #1717 2021-03-07 23:31:56 +01:00
zadam
88147f7a0a fixed "create note after" position issue 2021-03-06 23:53:10 +01:00
zadam
ca77211b38 improved template code with better heuristics on when to copy things from the template 2021-03-06 21:34:03 +01:00
zadam
4606e8d118 non-search notes should have no children limit, #1673 2021-03-06 20:31:12 +01:00
zadam
9f002fa802 change the heuristics to choose the best note path when ambiguous/incomplete/just noteId is provided, #1711 2021-03-06 20:23:29 +01:00
zadam
060d4fc27b fix duplication of hoisted note tree when hoisted note has clones 2021-03-04 23:19:27 +01:00
zadam
bf0fbe201e hack when hoisted note is cloned then it could be filtered multiple times while we want only 1 2021-03-03 23:00:16 +01:00
zadam
721e5da672 use notePath instead of noteId for note creation to correctly work with cloned ancestors 2021-03-03 22:48:06 +01:00
zadam
8192b51b8a cleanup of createTopLevelNote 2021-03-03 22:27:57 +01:00
zadam
73514a63d8 when resolving note path attempt to find one going through hoisted note 2021-03-03 21:49:57 +01:00
zadam
f8c310eb8f added license mention into the README noting AGPL v3+, #1708 2021-03-03 21:41:44 +01:00
zadam
b9422b0efd cssClass is now added also to link map and relation map, closes #1702 2021-03-02 23:20:53 +01:00
zadam
14ced949a9 fix modifying index in note cache when deleting attribute, closes #1706 2021-03-02 23:10:42 +01:00
zadam
5b5c2a2dbb fix null utcDateChanged in entity_changes, closes #1705 2021-03-02 22:08:29 +01:00
zadam
2c958eaacb Merge branch 'sort-by' 2021-02-28 23:40:37 +01:00
zadam
4aa27b6033 added "sort by" dialog 2021-02-28 23:40:15 +01:00
zadam
89a0c5a1c9 fix "no data" when switching between tabs with different hoisted notes, closes #1699 2021-02-28 19:46:04 +01:00
zadam
78e48095e6 prompt user when there are unsaved changes, #1692 2021-02-27 23:39:02 +01:00
zadam
02016ed031 fix create full search note 2021-02-27 21:19:54 +01:00
zadam
cb91dadeca add possibility to define search home for hoisted notes, #1694 2021-02-27 21:18:10 +01:00
zadam
2c755bcc38 don't fail (immediatelly) when sql insert doesn't return lastInsertRowid, #1665 2021-02-27 21:09:13 +01:00
zadam
3c7a6bc1e4 use longer update interval for web 2021-02-27 21:08:27 +01:00
zadam
3fe87259e2 if search note would end up outside of current hoisting, save it under the hoisted note, closes #1694 2021-02-26 23:33:22 +01:00
zadam
d476dfc53b fix searching the second time in quick search, #1694 2021-02-26 23:20:49 +01:00
zadam
19821b634f release 0.46.2-beta 2021-02-25 22:41:35 +01:00
zadam
cde41b268e allow copying type, mime, content from template only for text and code note types, fixes #1689 2021-02-25 22:33:26 +01:00
zadam
1c59bc4d3c sort child notes by ... WIP 2021-02-25 22:26:46 +01:00
zadam
cb6d35236c update correctly "multi-parent" node status, fixes #1688 2021-02-25 21:16:21 +01:00
zadam
7572ee284b set search note title correctly during creation 2021-02-25 20:02:49 +01:00
zadam
d0eaf623a8 activate node after calling "scroll to active note", fixes #1685 2021-02-24 22:41:24 +01:00
zadam
25c2db6c3a sort parent relationships so that clones in search notes appear last, fixes #1686 2021-02-24 22:38:26 +01:00
zadam
5a173ff14e quick search now allows clicking anywhere 2021-02-24 22:19:09 +01:00
zadam
7fab75b085 Merge remote-tracking branch 'origin/master' 2021-02-23 22:01:10 +01:00
zadam
0f065536d0 use 100 children limit on only search notes (as was initially intended), fixes #1673 2021-02-23 22:01:02 +01:00
sigaloid
d0747abded no h1 headings (#1679)
#1552
2021-02-23 21:23:23 +01:00
Mirwaisse Djanbaz
f62b4a581e Typo in export.js (#1682) 2021-02-23 21:20:19 +01:00
Mirwaisse Djanbaz
dcf1c62ec1 Typo in appearance settings (#1683) 2021-02-23 21:19:57 +01:00
zadam
93d55b3e7b put back waiting for sync after frontend API backend request 2021-02-22 22:43:54 +01:00
zadam
90c6852423 hide auto links by default in relation map, allow configuring displayed relations, fixes #1674 2021-02-22 22:34:33 +01:00
zadam
208baa56e9 error handling 2021-02-22 21:59:37 +01:00
zadam
ddf8438b22 fix edited notes widget note transitions, fixes #1672 2021-02-21 22:45:32 +01:00
zadam
6008dc891f fix note activation right after creation from calendar 2021-02-21 21:54:16 +01:00
zadam
cc887a00f2 runOnBackend now does not automatically wait for the maxSyncId since it can easily result in infinite cycle 2021-02-21 21:28:00 +01:00
zadam
fbbd51d0b1 small changes for better debugging infos 2021-02-20 23:17:29 +01:00
zadam
081b8b126a fix note_reordering not updating note cache 2021-02-20 21:28:22 +01:00
zadam
7a6bb81345 display note path in search results 2021-02-20 20:10:45 +01:00
zadam
1d5714c411 release 0.46.1-beta 2021-02-19 23:15:18 +01:00
zadam
56506d33a7 small fixes 2021-02-19 22:58:53 +01:00
zadam
c94fb7a62d created a specific widget for search result to add "no results" message 2021-02-19 22:15:56 +01:00
zadam
4160da70be implemented "targetRelationCount" and exposed more of them in order by widget, fixes #1658 2021-02-19 20:42:34 +01:00
zadam
2cfd093cae allow search result to be moved from tree to relation map, fixes #1650 2021-02-18 22:30:55 +01:00
zadam
859465841d add possibility to debug search queries by logging expression tree, #1655 2021-02-18 22:10:49 +01:00
zadam
0c9a11db6f bring back "create and link note" into more places, fixes #1653 2021-02-18 20:10:44 +01:00
zadam
4cbf9c2e86 show "reset to default icon" button only when there is an explicit icon 2021-02-18 20:06:14 +01:00
zadam
1f7997eeed added "reset to default icon" button to icon picker 2021-02-18 19:33:12 +01:00
zadam
8e730c6ecf add frontend API method openTabWithNote, #1645 2021-02-17 23:55:51 +01:00
zadam
600a312b2a fix parsing of "!=" operator, #1651 2021-02-17 23:41:15 +01:00
zadam
ec2e973165 allow only valid attr name characters for relation map relations, closes #1649 2021-02-17 23:22:14 +01:00
zadam
faeb55bc90 don't allow to bring up delete dialog on saved search results (consistency with context menu) 2021-02-17 23:03:34 +01:00
zadam
23ebe360a6 small fixes 2021-02-17 20:59:44 +01:00
zadam
d905335935 correct placement of imported root note (at the end) 2021-02-16 23:38:05 +01:00
zadam
f49f510459 fixes in "other notes with relation..." 2021-02-16 23:07:40 +01:00
zadam
e78b495bd3 reduce flickering of import by disabling entityChanges notification of frontend 2021-02-16 22:51:00 +01:00
zadam
5542c9dc57 fixed saved note migration - need to be migrated as last, #1647 2021-02-16 21:40:17 +01:00
zadam
2388da7cfb fixed "show in full search" click and keyboard shortcuts for collapse tree and scroll to active note actions, #1647 2021-02-16 21:19:07 +01:00
zadam
3b4fa0c5fc update section container on attribute change, closes #1646 2021-02-16 20:58:17 +01:00
128 changed files with 2772 additions and 1062 deletions

View File

@@ -55,3 +55,7 @@ npm run start-server
* [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://github.com/zadam/trilium/wiki/Relation-map) and [link maps](https://github.com/zadam/trilium/wiki/Link-map)
## License
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

View File

@@ -15,6 +15,8 @@ module.exports = () => {
note.mime = 'text/plain';
note.save();
console.log(`Migrated search note ${note.noteId}`);
}
catch (e) {
console.log(`Changing note content for note ${note.noteId} failed with: ${e.message} ${e.stack}`);

View File

@@ -298,29 +298,6 @@
<tr>
<td class="name"><code>utcDateCreated</code></td>
<td class="type">
<span class="param-type">string</span>
</td>
<td class="description last"></td>
</tr>
<tr>
<td class="name"><code>utcDateModified</code></td>
@@ -378,7 +355,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_attribute.js.html">entities/attribute.js</a>, <a href="entities_attribute.js.html#line26">line 26</a>
<a href="entities_attribute.js.html">entities/attribute.js</a>, <a href="entities_attribute.js.html#line25">line 25</a>
</li></ul></dd>
@@ -493,7 +470,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_attribute.js.html">entities/attribute.js</a>, <a href="entities_attribute.js.html#line40">line 40</a>
<a href="entities_attribute.js.html">entities/attribute.js</a>, <a href="entities_attribute.js.html#line43">line 43</a>
</li></ul></dd>
@@ -598,7 +575,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_attribute.js.html">entities/attribute.js</a>, <a href="entities_attribute.js.html#line47">line 47</a>
<a href="entities_attribute.js.html">entities/attribute.js</a>, <a href="entities_attribute.js.html#line50">line 50</a>
</li></ul></dd>
@@ -703,7 +680,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_attribute.js.html">entities/attribute.js</a>, <a href="entities_attribute.js.html#line62">line 62</a>
<a href="entities_attribute.js.html">entities/attribute.js</a>, <a href="entities_attribute.js.html#line65">line 65</a>
</li></ul></dd>

View File

@@ -619,7 +619,7 @@ JSON MIME type. See also createNewNote() for more options.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line205">line 205</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line207">line 207</a>
</li></ul></dd>
@@ -782,7 +782,7 @@ JSON MIME type. See also createNewNote() for more options.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line232">line 232</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line234">line 234</a>
</li></ul></dd>
@@ -1068,7 +1068,7 @@ JSON MIME type. See also createNewNote() for more options.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line260">line 260</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line262">line 262</a>
</li></ul></dd>
@@ -1273,7 +1273,7 @@ JSON MIME type. See also createNewNote() for more options.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line189">line 189</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line191">line 191</a>
</li></ul></dd>
@@ -1451,7 +1451,7 @@ JSON MIME type. See also createNewNote() for more options.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line160">line 160</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line162">line 162</a>
</li></ul></dd>
@@ -1652,7 +1652,7 @@ JSON MIME type. See also createNewNote() for more options.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line150">line 150</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line152">line 152</a>
</li></ul></dd>
@@ -1754,7 +1754,7 @@ JSON MIME type. See also createNewNote() for more options.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line397">line 397</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line399">line 399</a>
</li></ul></dd>
@@ -2224,7 +2224,7 @@ JSON MIME type. See also createNewNote() for more options.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line318">line 318</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line320">line 320</a>
</li></ul></dd>
@@ -2847,7 +2847,7 @@ if some action needs to happen on only one specific instance.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line345">line 345</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line347">line 347</a>
</li></ul></dd>
@@ -3202,7 +3202,7 @@ if some action needs to happen on only one specific instance.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line129">line 129</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line131">line 131</a>
</li></ul></dd>
@@ -3400,7 +3400,7 @@ if some action needs to happen on only one specific instance.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line139">line 139</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line141">line 141</a>
</li></ul></dd>
@@ -3509,7 +3509,7 @@ if some action needs to happen on only one specific instance.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line309">line 309</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line311">line 311</a>
</li></ul></dd>
@@ -3618,7 +3618,7 @@ if some action needs to happen on only one specific instance.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line326">line 326</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line328">line 328</a>
</li></ul></dd>
@@ -3799,7 +3799,7 @@ if some action needs to happen on only one specific instance.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line336">line 336</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line338">line 338</a>
</li></ul></dd>
@@ -3957,7 +3957,7 @@ if some action needs to happen on only one specific instance.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line354">line 354</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line356">line 356</a>
</li></ul></dd>
@@ -4110,7 +4110,7 @@ if some action needs to happen on only one specific instance.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line301">line 301</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line303">line 303</a>
</li></ul></dd>
@@ -4196,7 +4196,7 @@ if some action needs to happen on only one specific instance.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line392">line 392</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line394">line 394</a>
</li></ul></dd>
@@ -4334,7 +4334,7 @@ if some action needs to happen on only one specific instance.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line115">line 115</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line117">line 117</a>
</li></ul></dd>
@@ -4391,7 +4391,7 @@ if some action needs to happen on only one specific instance.
<h4 class="name" id="searchForNotes"><span class="type-signature"></span>searchForNotes<span class="signature">(query, searchContext<span class="signature-attributes">opt</span>)</span><span class="type-signature"> &rarr; {Array.&lt;<a href="Note.html">Note</a>>}</span></h4>
<h4 class="name" id="searchForNotes"><span class="type-signature"></span>searchForNotes<span class="signature">(query, searchParams<span class="signature-attributes">opt</span>)</span><span class="type-signature"> &rarr; {Array.&lt;<a href="Note.html">Note</a>>}</span></h4>
@@ -4469,13 +4469,13 @@ if some action needs to happen on only one specific instance.
<tr>
<td class="name"><code>searchContext</code></td>
<td class="name"><code>searchParams</code></td>
<td class="type">
<span class="param-type">SearchContext</span>
<span class="param-type">Object</span>
@@ -4745,7 +4745,7 @@ This method looks similar to toggleNoteInParent() but differs because we're look
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line374">line 374</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line376">line 376</a>
</li></ul></dd>
@@ -4878,7 +4878,7 @@ This method looks similar to toggleNoteInParent() but differs because we're look
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line360">line 360</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line362">line 362</a>
</li></ul></dd>
@@ -5084,7 +5084,7 @@ This method looks similar to toggleNoteInParent() but differs because we're look
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line172">line 172</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line174">line 174</a>
</li></ul></dd>
@@ -5240,7 +5240,7 @@ exists, then we'll use that transaction.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line384">line 384</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line386">line 386</a>
</li></ul></dd>

View File

@@ -296,29 +296,6 @@
<tr>
<td class="name"><code>isErased</code></td>
<td class="type">
<span class="param-type">boolean</span>
</td>
<td class="description last">true if note's content is erased after it has been deleted</td>
</tr>
<tr>
<td class="name"><code>dateCreated</code></td>
@@ -445,7 +422,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line32">line 32</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line31">line 31</a>
</li></ul></dd>
@@ -560,7 +537,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line531">line 531</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line537">line 537</a>
</li></ul></dd>
@@ -662,7 +639,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line855">line 855</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line861">line 861</a>
</li></ul></dd>
@@ -840,7 +817,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line430">line 430</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line436">line 436</a>
</li></ul></dd>
@@ -1040,7 +1017,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line268">line 268</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line274">line 274</a>
</li></ul></dd>
@@ -1218,7 +1195,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line441">line 441</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line447">line 447</a>
</li></ul></dd>
@@ -1327,7 +1304,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line801">line 801</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line807">line 807</a>
</li></ul></dd>
@@ -1429,7 +1406,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line829">line 829</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line835">line 835</a>
</li></ul></dd>
@@ -1535,7 +1512,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line815">line 815</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line821">line 821</a>
</li></ul></dd>
@@ -1641,7 +1618,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line71">line 71</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line70">line 70</a>
</li></ul></dd>
@@ -1743,7 +1720,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line107">line 107</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line106">line 106</a>
</li></ul></dd>
@@ -1845,7 +1822,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line701">line 701</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line707">line 707</a>
</li></ul></dd>
@@ -2078,7 +2055,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line724">line 724</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line730">line 730</a>
</li></ul></dd>
@@ -2276,7 +2253,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line762">line 762</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line768">line 768</a>
</li></ul></dd>
@@ -2474,7 +2451,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line771">line 771</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line777">line 777</a>
</li></ul></dd>
@@ -2576,7 +2553,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line118">line 118</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line117">line 117</a>
</li></ul></dd>
@@ -2727,7 +2704,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line584">line 584</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line590">line 590</a>
</li></ul></dd>
@@ -2897,7 +2874,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line291">line 291</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line297">line 297</a>
</li></ul></dd>
@@ -3052,7 +3029,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line608">line 608</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line614">line 614</a>
</li></ul></dd>
@@ -3167,7 +3144,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line788">line 788</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line794">line 794</a>
</li></ul></dd>
@@ -3269,7 +3246,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line250">line 250</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line256">line 256</a>
</li></ul></dd>
@@ -3476,7 +3453,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line226">line 226</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line232">line 232</a>
</li></ul></dd>
@@ -3654,7 +3631,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line452">line 452</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line458">line 458</a>
</li></ul></dd>
@@ -3812,7 +3789,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line590">line 590</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line596">line 596</a>
</li></ul></dd>
@@ -3982,7 +3959,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line299">line 299</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line305">line 305</a>
</li></ul></dd>
@@ -4137,7 +4114,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line614">line 614</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line620">line 620</a>
</li></ul></dd>
@@ -4295,7 +4272,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line602">line 602</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line608">line 608</a>
</li></ul></dd>
@@ -4465,7 +4442,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line315">line 315</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line321">line 321</a>
</li></ul></dd>
@@ -4620,7 +4597,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line642">line 642</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line648">line 648</a>
</li></ul></dd>
@@ -4778,7 +4755,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line626">line 626</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line632">line 632</a>
</li></ul></dd>
@@ -4887,7 +4864,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line841">line 841</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line847">line 847</a>
</li></ul></dd>
@@ -5042,7 +5019,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line596">line 596</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line602">line 602</a>
</li></ul></dd>
@@ -5212,7 +5189,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line307">line 307</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line313">line 313</a>
</li></ul></dd>
@@ -5367,7 +5344,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line632">line 632</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line638">line 638</a>
</li></ul></dd>
@@ -5537,7 +5514,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line323">line 323</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line329">line 329</a>
</li></ul></dd>
@@ -5688,7 +5665,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line620">line 620</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line626">line 626</a>
</li></ul></dd>
@@ -5801,7 +5778,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line778">line 778</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line784">line 784</a>
</li></ul></dd>
@@ -5903,7 +5880,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line197">line 197</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line203">line 203</a>
</li></ul></dd>
@@ -6009,7 +5986,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line259">line 259</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line265">line 265</a>
</li></ul></dd>
@@ -6187,7 +6164,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line412">line 412</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line418">line 418</a>
</li></ul></dd>
@@ -6293,7 +6270,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line808">line 808</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line814">line 814</a>
</li></ul></dd>
@@ -6448,7 +6425,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line560">line 560</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line566">line 566</a>
</li></ul></dd>
@@ -6626,7 +6603,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line421">line 421</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line427">line 427</a>
</li></ul></dd>
@@ -6781,7 +6758,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line566">line 566</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line572">line 572</a>
</li></ul></dd>
@@ -6936,7 +6913,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line578">line 578</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line584">line 584</a>
</li></ul></dd>
@@ -7091,7 +7068,7 @@ Use when inheritance is not needed and/or in batch/performance sensitive operati
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line572">line 572</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line578">line 578</a>
</li></ul></dd>
@@ -7202,7 +7179,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line338">line 338</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line344">line 344</a>
</li></ul></dd>
@@ -7330,7 +7307,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line886">line 886</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line892">line 892</a>
</li></ul></dd>
@@ -7436,7 +7413,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line187">line 187</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line193">line 193</a>
</li></ul></dd>
@@ -7542,7 +7519,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line179">line 179</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line185">line 185</a>
</li></ul></dd>
@@ -7648,7 +7625,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line174">line 174</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line180">line 180</a>
</li></ul></dd>
@@ -7754,7 +7731,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line169">line 169</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line175">line 175</a>
</li></ul></dd>
@@ -7860,7 +7837,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line192">line 192</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line198">line 198</a>
</li></ul></dd>
@@ -8093,7 +8070,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line515">line 515</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line521">line 521</a>
</li></ul></dd>
@@ -8273,7 +8250,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line688">line 688</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line694">line 694</a>
</li></ul></dd>
@@ -8453,7 +8430,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line696">line 696</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line702">line 702</a>
</li></ul></dd>
@@ -8664,7 +8641,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line482">line 482</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line488">line 488</a>
</li></ul></dd>
@@ -8844,7 +8821,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line672">line 672</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line678">line 678</a>
</li></ul></dd>
@@ -9024,7 +9001,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line680">line 680</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line686">line 686</a>
</li></ul></dd>
@@ -9266,7 +9243,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line466">line 466</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line472">line 472</a>
</li></ul></dd>
@@ -9477,7 +9454,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line655">line 655</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line661">line 661</a>
</li></ul></dd>
@@ -9688,7 +9665,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line664">line 664</a>
<a href="entities_note.js.html">entities/note.js</a>, <a href="entities_note.js.html#line670">line 670</a>
</li></ul></dd>

View File

@@ -198,29 +198,6 @@
<td class="description last"></td>
</tr>
<tr>
<td class="name"><code>isErased</code></td>
<td class="type">
<span class="param-type">boolean</span>
</td>
<td class="description last"></td>
</tr>
@@ -398,7 +375,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_revision.js.html">entities/note_revision.js</a>, <a href="entities_note_revision.js.html#line28">line 28</a>
<a href="entities_note_revision.js.html">entities/note_revision.js</a>, <a href="entities_note_revision.js.html#line27">line 27</a>
</li></ul></dd>
@@ -513,7 +490,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_revision.js.html">entities/note_revision.js</a>, <a href="entities_note_revision.js.html#line68">line 68</a>
<a href="entities_note_revision.js.html">entities/note_revision.js</a>, <a href="entities_note_revision.js.html#line66">line 66</a>
</li></ul></dd>
@@ -615,7 +592,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_revision.js.html">entities/note_revision.js</a>, <a href="entities_note_revision.js.html#line54">line 54</a>
<a href="entities_note_revision.js.html">entities/note_revision.js</a>, <a href="entities_note_revision.js.html#line52">line 52</a>
</li></ul></dd>

View File

@@ -136,30 +136,7 @@
<tr>
<td class="name"><code>isDeleted</code></td>
<td class="type">
<span class="param-type">boolean</span>
</td>
<td class="description last"></td>
</tr>
<tr>
<td class="name"><code>utcDateModified</code></td>
<td class="name"><code>utcDateCreated</code></td>
<td class="type">
@@ -214,7 +191,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_recent_note.js.html">entities/recent_note.js</a>, <a href="entities_recent_note.js.html#line16">line 16</a>
<a href="entities_recent_note.js.html">entities/recent_note.js</a>, <a href="entities_recent_note.js.html#line15">line 15</a>
</li></ul></dd>

View File

@@ -46,7 +46,6 @@ const promotedAttributeDefinitionParser = require("../services/promoted_attribut
* @property {boolean} isInheritable - immutable
* @property {boolean} isDeleted
* @property {string|null} deleteId - ID identifying delete transaction
* @property {string} utcDateCreated
* @property {string} utcDateModified
*
* @extends Entity
@@ -54,7 +53,7 @@ const promotedAttributeDefinitionParser = require("../services/promoted_attribut
class Attribute extends Entity {
static get entityName() { return "attributes"; }
static get primaryKeyName() { return "attributeId"; }
static get hashedProperties() { return ["attributeId", "noteId", "type", "name", "value", "isInheritable", "isDeleted", "utcDateCreated"]; }
static get hashedProperties() { return ["attributeId", "noteId", "type", "name", "value", "isInheritable", "isDeleted"]; }
constructor(row) {
super(row);
@@ -62,6 +61,10 @@ class Attribute extends Entity {
this.isInheritable = !!this.isInheritable;
}
isAutoLink() {
return this.type === 'relation' &amp;&amp; ['internalLink', 'imageLink', 'relationMapLink', 'includeNoteLink'].includes(this.name);
}
/**
* @returns {Note|null}
*/
@@ -127,16 +130,10 @@ class Attribute extends Entity {
this.isDeleted = false;
}
if (!this.utcDateCreated) {
this.utcDateCreated = dateUtils.utcNowDateTime();
}
super.beforeSaving();
if (this.isChanged) {
this.utcDateModified = dateUtils.utcNowDateTime();
}
}
createClone(type, name, value, isInheritable) {
return new Attribute({
@@ -147,7 +144,6 @@ class Attribute extends Entity {
position: this.position,
isInheritable: isInheritable,
isDeleted: false,
utcDateCreated: this.utcDateCreated,
utcDateModified: this.utcDateModified
});
}

View File

@@ -66,7 +66,7 @@ class Branch extends Entity {
}
beforeSaving() {
if (this.notePosition === undefined) {
if (this.notePosition === undefined || this.notePosition === null) {
const maxNotePos = sql.getValue('SELECT MAX(notePosition) FROM branches WHERE parentNoteId = ? AND isDeleted = 0', [this.parentNoteId]);
this.notePosition = maxNotePos === null ? 0 : maxNotePos + 10;
}
@@ -85,10 +85,8 @@ class Branch extends Entity {
super.beforeSaving();
if (this.isChanged) {
this.utcDateModified = dateUtils.utcNowDateTime();
}
}
createClone(parentNoteId, notePosition) {
return new Branch({

View File

@@ -43,18 +43,13 @@ class Entity {
}
}
if ('isDeleted' in this) {
if ('isDeleted' in this &amp;&amp; this.constructor.entityName !== 'recent_notes') {
this.isDeleted = !!this.isDeleted;
}
}
beforeSaving() {
this.generateIdIfNecessary();
const origHash = this.hash;
this.hash = this.generateHash();
this.isChanged = origHash !== this.hash;
}
generateIdIfNecessary() {
@@ -73,6 +68,10 @@ class Entity {
return utils.hash(contentToHash).substr(0, 10);
}
getUtcDateChanged() {
return this.utcDateModified;
}
get repository() {
if (!repo) {
repo = require('../services/repository');

View File

@@ -49,7 +49,6 @@ const RELATION = 'relation';
* @property {boolean} isProtected - true if note is protected
* @property {boolean} isDeleted - true if note is deleted
* @property {string|null} deleteId - ID identifying delete transaction
* @property {boolean} isErased - true if note's content is erased after it has been deleted
* @property {string} dateCreated - local date time (with offset)
* @property {string} dateModified - local date time (with offset)
* @property {string} utcDateCreated
@@ -98,9 +97,9 @@ class Note extends Entity {
/** @returns {*} */
getContent(silentNotFoundError = false) {
if (this.content === undefined) {
const res = sql.getRow(`SELECT content, hash FROM note_contents WHERE noteId = ?`, [this.noteId]);
const row = sql.getRow(`SELECT content FROM note_contents WHERE noteId = ?`, [this.noteId]);
if (!res) {
if (!row) {
if (silentNotFoundError) {
return undefined;
}
@@ -109,7 +108,7 @@ class Note extends Entity {
}
}
this.content = res.content;
this.content = row.content;
if (this.isProtected) {
if (this.isContentAvailable) {
@@ -171,8 +170,7 @@ class Note extends Entity {
noteId: this.noteId,
content: content,
dateModified: dateUtils.localNowDateTime(),
utcDateModified: dateUtils.utcNowDateTime(),
hash: utils.hash(this.noteId + "|" + content.toString())
utcDateModified: dateUtils.utcNowDateTime()
};
if (this.isProtected) {
@@ -186,7 +184,15 @@ class Note extends Entity {
sql.upsert("note_contents", "noteId", pojo);
entityChangesService.addNoteContentEntityChange(this.noteId);
const hash = utils.hash(this.noteId + "|" + content.toString());
entityChangesService.addEntityChange({
entityName: 'note_contents',
entityId: this.noteId,
hash: hash,
isErased: false,
utcDateChanged: this.getUtcDateChanged()
}, null);
}
setJsonContent(content) {
@@ -834,7 +840,7 @@ class Note extends Entity {
* @returns {boolean} - true if note has children
*/
hasChildren() {
return (this.getChildNotes()).length > 0;
return this.getChildNotes().length > 0;
}
/**
@@ -932,11 +938,9 @@ class Note extends Entity {
super.beforeSaving();
if (this.isChanged) {
this.dateModified = dateUtils.localNowDateTime();
this.utcDateModified = dateUtils.utcNowDateTime();
}
}
// cannot be static!
updatePojo(pojo) {

View File

@@ -43,7 +43,6 @@ const entityChangesService = require('../services/entity_changes.js');
* @property {string} type
* @property {string} mime
* @property {string} title
* @property {boolean} isErased
* @property {boolean} isProtected
* @property {string} dateLastEdited
* @property {string} dateCreated
@@ -56,12 +55,11 @@ const entityChangesService = require('../services/entity_changes.js');
class NoteRevision extends Entity {
static get entityName() { return "note_revisions"; }
static get primaryKeyName() { return "noteRevisionId"; }
static get hashedProperties() { return ["noteRevisionId", "noteId", "title", "isErased", "isProtected", "dateLastEdited", "dateCreated", "utcDateLastEdited", "utcDateCreated", "utcDateModified"]; }
static get hashedProperties() { return ["noteRevisionId", "noteId", "title", "isProtected", "dateLastEdited", "dateCreated", "utcDateLastEdited", "utcDateCreated", "utcDateModified"]; }
constructor(row) {
super(row);
this.isErased = !!this.isErased;
this.isProtected = !!this.isProtected;
if (this.isProtected) {
@@ -95,7 +93,7 @@ class NoteRevision extends Entity {
/** @returns {*} */
getContent(silentNotFoundError = false) {
if (this.content === undefined) {
const res = sql.getRow(`SELECT content, hash FROM note_revision_contents WHERE noteRevisionId = ?`, [this.noteRevisionId]);
const res = sql.getRow(`SELECT content FROM note_revision_contents WHERE noteRevisionId = ?`, [this.noteRevisionId]);
if (!res) {
if (silentNotFoundError) {
@@ -107,7 +105,6 @@ class NoteRevision extends Entity {
}
this.content = res.content;
if (this.isProtected) {
if (protectedSessionService.isProtectedSessionAvailable()) {
this.content = protectedSessionService.decrypt(this.content);
@@ -134,8 +131,7 @@ class NoteRevision extends Entity {
const pojo = {
noteRevisionId: this.noteRevisionId,
content: content,
utcDateModified: dateUtils.utcNowDateTime(),
hash: utils.hash(this.noteRevisionId + "|" + content)
utcDateModified: dateUtils.utcNowDateTime()
};
if (this.isProtected) {
@@ -149,16 +145,22 @@ class NoteRevision extends Entity {
sql.upsert("note_revision_contents", "noteRevisionId", pojo);
entityChangesService.addNoteRevisionContentEntityChange(this.noteRevisionId);
const hash = utils.hash(this.noteRevisionId + "|" + content);
entityChangesService.addEntityChange({
entityName: 'note_revision_contents',
entityId: this.noteRevisionId,
hash: hash,
isErased: false,
utcDateChanged: this.getUtcDateChanged()
}, null);
}
beforeSaving() {
super.beforeSaving();
if (this.isChanged) {
this.utcDateModified = dateUtils.utcNowDateTime();
}
}
// cannot be static!
updatePojo(pojo) {

View File

@@ -60,13 +60,12 @@ class Option extends Entity {
super.beforeSaving();
if (this.isChanged) {
this.utcDateModified = dateUtils.utcNowDateTime();
}
}
}
module.exports = Option;</code></pre>
module.exports = Option;
</code></pre>
</article>
</section>

View File

@@ -36,21 +36,15 @@ const dateUtils = require('../services/date_utils');
*
* @property {string} noteId
* @property {string} notePath
* @property {boolean} isDeleted
* @property {string} utcDateModified
* @property {string} utcDateCreated
*
* @extends Entity
*/
class RecentNote extends Entity {
static get entityName() { return "recent_notes"; }
static get primaryKeyName() { return "noteId"; }
static get hashedProperties() { return ["noteId", "notePath", "utcDateCreated", "isDeleted"]; }
beforeSaving() {
if (!this.isDeleted) {
this.isDeleted = false;
}
if (!this.utcDateCreated) {
this.utcDateCreated = dateUtils.utcNowDateTime();
}
@@ -59,7 +53,8 @@ class RecentNote extends Entity {
}
}
module.exports = RecentNote;</code></pre>
module.exports = RecentNote;
</code></pre>
</article>
</section>

View File

@@ -391,7 +391,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line213">line 213</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line215">line 215</a>
</li></ul></dd>
@@ -579,7 +579,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line174">line 174</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line176">line 176</a>
</li></ul></dd>
@@ -767,7 +767,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line234">line 234</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line236">line 236</a>
</li></ul></dd>
@@ -1053,7 +1053,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line241">line 241</a>
<a href="services_backend_script_api.js.html">services/backend_script_api.js</a>, <a href="services_backend_script_api.js.html#line243">line 243</a>
</li></ul></dd>

View File

@@ -120,13 +120,15 @@ function BackendScriptApi(currentNote, apiParams) {
*
* @method
* @param {string} query
* @param {SearchContext} [searchContext]
* @param {Object} [searchParams]
* @returns {Note[]}
*/
this.searchForNotes = (query, searchContext) => {
searchContext = searchContext || new SearchContext();
this.searchForNotes = (query, searchParams = {}) => {
if (searchParams.includeArchivedNotes === undefined) {
searchParams.includeArchivedNotes = true;
}
const noteIds = searchService.findNotesWithQuery(query, searchContext)
const noteIds = searchService.findNotesWithQuery(query, new SearchContext(searchParams))
.map(sr => sr.noteId);
return repository.getNotes(noteIds);

View File

@@ -201,7 +201,7 @@
<h4 class="name" id="isDeleted"><span class="type-signature"></span>isDeleted<span class="type-signature"></span></h4>
<h4 class="name" id="fromSearchNote"><span class="type-signature"></span>fromSearchNote<span class="type-signature"></span></h4>
@@ -259,6 +259,64 @@
<h4 class="name" id="isDeleted"><span class="type-signature"></span>isDeleted<span class="type-signature"></span></h4>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line25">line 25</a>
</li></ul></dd>
</dl>
<h4 class="name" id="isExpanded"><span class="type-signature"></span>isExpanded<span class="type-signature"></span></h4>
@@ -607,7 +665,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line27">line 27</a>
<a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line29">line 29</a>
</li></ul></dd>
@@ -709,7 +767,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line32">line 32</a>
<a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line34">line 34</a>
</li></ul></dd>
@@ -811,7 +869,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line37">line 37</a>
<a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line39">line 39</a>
</li></ul></dd>
@@ -913,7 +971,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line42">line 42</a>
<a href="entities_branch.js.html">entities/branch.js</a>, <a href="entities_branch.js.html#line44">line 44</a>
</li></ul></dd>

View File

@@ -81,7 +81,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line24">line 24</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line22">line 22</a>
</li></ul></dd>
@@ -223,7 +223,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line28">line 28</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line26">line 26</a>
</li></ul></dd>
@@ -329,7 +329,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line50">line 50</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line48">line 48</a>
</li></ul></dd>
@@ -435,7 +435,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line41">line 41</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line39">line 39</a>
</li></ul></dd>
@@ -545,7 +545,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line33">line 33</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line31">line 31</a>
</li></ul></dd>
@@ -658,7 +658,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line35">line 35</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line33">line 33</a>
</li></ul></dd>
@@ -768,7 +768,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line31">line 31</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line29">line 29</a>
</li></ul></dd>
@@ -874,7 +874,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line44">line 44</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line42">line 42</a>
</li></ul></dd>
@@ -980,7 +980,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line47">line 47</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line45">line 45</a>
</li></ul></dd>
@@ -1109,7 +1109,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line69">line 69</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line67">line 67</a>
</li></ul></dd>
@@ -1264,7 +1264,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line59">line 59</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line57">line 57</a>
</li></ul></dd>
@@ -1419,7 +1419,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line89">line 89</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line101">line 101</a>
</li></ul></dd>
@@ -1556,7 +1556,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line287">line 287</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line302">line 302</a>
</li></ul></dd>
@@ -1712,7 +1712,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line392">line 392</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line413">line 413</a>
</li></ul></dd>
@@ -1748,7 +1748,7 @@
<h4 class="name" id="createNoteLink"><span class="type-signature"></span>createNoteLink<span class="signature">(notePath, noteTitle<span class="signature-attributes">opt</span>)</span><span class="type-signature"></span></h4>
<h4 class="name" id="createNoteLink"><span class="type-signature"></span>createNoteLink<span class="signature">(notePath, params<span class="signature-attributes">opt</span>, title=<span class="signature-attributes">opt</span>)</span><span class="type-signature"></span></h4>
@@ -1825,7 +1825,148 @@
<tr>
<td class="name"><code>noteTitle</code></td>
<td class="name"><code>params</code></td>
<td class="type">
<span class="param-type">object</span>
</td>
<td class="attributes">
&lt;optional><br>
</td>
<td class="description last">
<h6>Properties</h6>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Attributes</th>
<th>Default</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>showTooltip</code></td>
<td class="type">
<span class="param-type">boolean</span>
</td>
<td class="attributes">
&lt;optional><br>
</td>
<td class="default">
true
</td>
<td class="description last">enable/disable tooltip on the link</td>
</tr>
<tr>
<td class="name"><code>showNotePath</code></td>
<td class="type">
<span class="param-type">boolean</span>
</td>
<td class="attributes">
&lt;optional><br>
</td>
<td class="default">
false
</td>
<td class="description last">show also whole note's path as part of the link</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td class="name"><code>title=</code></td>
<td class="type">
@@ -1851,7 +1992,7 @@
<td class="description last">if not present we'll use note title</td>
<td class="description last">custom link tile with note's title as default</td>
</tr>
@@ -1892,7 +2033,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line279">line 279</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line294">line 294</a>
</li></ul></dd>
@@ -2025,7 +2166,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line241">line 241</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line253">line 253</a>
</li></ul></dd>
@@ -2131,7 +2272,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line293">line 293</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line308">line 308</a>
</li></ul></dd>
@@ -2237,7 +2378,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line307">line 307</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line322">line 322</a>
</li></ul></dd>
@@ -2391,7 +2532,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line301">line 301</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line316">line 316</a>
</li></ul></dd>
@@ -2528,7 +2669,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line358">line 358</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line373">line 373</a>
</li></ul></dd>
@@ -2635,7 +2776,7 @@ if some action needs to happen on only one specific instance.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line234">line 234</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line246">line 246</a>
</li></ul></dd>
@@ -2790,7 +2931,7 @@ if some action needs to happen on only one specific instance.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line367">line 367</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line382">line 382</a>
</li></ul></dd>
@@ -2946,7 +3087,7 @@ if some action needs to happen on only one specific instance.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line206">line 206</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line218">line 218</a>
</li></ul></dd>
@@ -3147,7 +3288,7 @@ otherwise (by e.g. createNoteLink())
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line218">line 218</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line230">line 230</a>
</li></ul></dd>
@@ -3253,7 +3394,7 @@ otherwise (by e.g. createNoteLink())
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line349">line 349</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line364">line 364</a>
</li></ul></dd>
@@ -3408,7 +3549,7 @@ otherwise (by e.g. createNoteLink())
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line376">line 376</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line391">line 391</a>
</li></ul></dd>
@@ -3462,6 +3603,184 @@ otherwise (by e.g. createNoteLink())
<h4 class="name" id="openTabWithNote"><span class="type-signature"></span>openTabWithNote<span class="signature">(notePath, activate)</span><span class="type-signature"> &rarr; {Promise.&lt;void>}</span></h4>
<div class="description">
Open a note in a new tab.
</div>
<h5>Parameters:</h5>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>notePath</code></td>
<td class="type">
<span class="param-type">string</span>
</td>
<td class="description last">(or noteId)</td>
</tr>
<tr>
<td class="name"><code>activate</code></td>
<td class="type">
<span class="param-type">boolean</span>
</td>
<td class="description last">set to true to activate the new tab, false to stay on the current tab</td>
</tr>
</tbody>
</table>
<dl class="details">
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line81">line 81</a>
</li></ul></dd>
</dl>
<h5>Returns:</h5>
<dl>
<dt>
Type
</dt>
<dd>
<span class="param-type">Promise.&lt;void></span>
</dd>
</dl>
<h4 class="name" id="parseDate"><span class="type-signature"></span>parseDate<span class="signature">(str)</span><span class="type-signature"> &rarr; {Date}</span></h4>
@@ -3559,7 +3878,7 @@ otherwise (by e.g. createNoteLink())
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line248">line 248</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line260">line 260</a>
</li></ul></dd>
@@ -3667,7 +3986,7 @@ otherwise (by e.g. createNoteLink())
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line319">line 319</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line334">line 334</a>
</li></ul></dd>
@@ -3823,7 +4142,7 @@ otherwise (by e.g. createNoteLink())
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line330">line 330</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line345">line 345</a>
</li></ul></dd>
@@ -3979,7 +4298,7 @@ otherwise (by e.g. createNoteLink())
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line339">line 339</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line354">line 354</a>
</li></ul></dd>
@@ -4111,7 +4430,7 @@ otherwise (by e.g. createNoteLink())
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line410">line 410</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line431">line 431</a>
</li></ul></dd>
@@ -4197,7 +4516,7 @@ otherwise (by e.g. createNoteLink())
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line270">line 270</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line282">line 282</a>
</li></ul></dd>
@@ -4334,7 +4653,7 @@ otherwise (by e.g. createNoteLink())
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line226">line 226</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line238">line 238</a>
</li></ul></dd>
@@ -4495,7 +4814,7 @@ Internally this serializes the anonymous function into string and sends it to ba
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line139">line 139</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line151">line 151</a>
</li></ul></dd>
@@ -4603,7 +4922,7 @@ Internally this serializes the anonymous function into string and sends it to ba
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line168">line 168</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line180">line 180</a>
</li></ul></dd>
@@ -4741,7 +5060,7 @@ Internally this serializes the anonymous function into string and sends it to ba
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line194">line 194</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line206">line 206</a>
</li></ul></dd>
@@ -4897,7 +5216,7 @@ Internally this serializes the anonymous function into string and sends it to ba
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line178">line 178</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line190">line 190</a>
</li></ul></dd>
@@ -4959,7 +5278,7 @@ Internally this serializes the anonymous function into string and sends it to ba
<div class="description">
Hoist note. See https://github.com/zadam/trilium/wiki/Note-hoisting
Hoist note in the current tab. See https://github.com/zadam/trilium/wiki/Note-hoisting
</div>
@@ -5052,7 +5371,7 @@ Internally this serializes the anonymous function into string and sends it to ba
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line385">line 385</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line400">line 400</a>
</li></ul></dd>
@@ -5203,7 +5522,7 @@ Internally this serializes the anonymous function into string and sends it to ba
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line313">line 313</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line328">line 328</a>
</li></ul></dd>
@@ -5340,7 +5659,7 @@ Internally this serializes the anonymous function into string and sends it to ba
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line264">line 264</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line276">line 276</a>
</li></ul></dd>
@@ -5477,7 +5796,7 @@ Internally this serializes the anonymous function into string and sends it to ba
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line256">line 256</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line268">line 268</a>
</li></ul></dd>
@@ -5569,7 +5888,7 @@ Typical use case is when new note has been created, we should wait until it is s
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line403">line 403</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line424">line 424</a>
</li></ul></dd>

View File

@@ -167,7 +167,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line13">line 13</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line24">line 24</a>
</li></ul></dd>
@@ -267,7 +267,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line22">line 22</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line33">line 33</a>
</li></ul></dd>
@@ -335,7 +335,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line30">line 30</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line41">line 41</a>
</li></ul></dd>
@@ -403,7 +403,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line36">line 36</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line47">line 47</a>
</li></ul></dd>
@@ -461,7 +461,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line53">line 53</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line64">line 64</a>
</li></ul></dd>
@@ -519,7 +519,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line47">line 47</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line58">line 58</a>
</li></ul></dd>
@@ -577,7 +577,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line51">line 51</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line62">line 62</a>
</li></ul></dd>
@@ -635,7 +635,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line43">line 43</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line54">line 54</a>
</li></ul></dd>
@@ -703,7 +703,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line28">line 28</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line39">line 39</a>
</li></ul></dd>
@@ -771,7 +771,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line33">line 33</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line44">line 44</a>
</li></ul></dd>
@@ -839,7 +839,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line25">line 25</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line36">line 36</a>
</li></ul></dd>
@@ -897,7 +897,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line45">line 45</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line56">line 56</a>
</li></ul></dd>
@@ -955,7 +955,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line49">line 49</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line60">line 60</a>
</li></ul></dd>
@@ -1103,7 +1103,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line307">line 307</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line377">line 377</a>
</li></ul></dd>
@@ -1303,7 +1303,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line176">line 176</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line189">line 189</a>
</li></ul></dd>
@@ -1481,7 +1481,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line329">line 329</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line399">line 399</a>
</li></ul></dd>
@@ -1587,7 +1587,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line119">line 119</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line132">line 132</a>
</li></ul></dd>
@@ -1689,7 +1689,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line114">line 114</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line127">line 127</a>
</li></ul></dd>
@@ -1791,7 +1791,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line131">line 131</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line144">line 144</a>
</li></ul></dd>
@@ -1893,7 +1893,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line149">line 149</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line162">line 162</a>
</li></ul></dd>
@@ -1995,7 +1995,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line154">line 154</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line167">line 167</a>
</li></ul></dd>
@@ -2146,7 +2146,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line369">line 369</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line439">line 439</a>
</li></ul></dd>
@@ -2313,7 +2313,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line253">line 253</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line266">line 266</a>
</li></ul></dd>
@@ -2468,7 +2468,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line393">line 393</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line463">line 463</a>
</li></ul></dd>
@@ -2578,7 +2578,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line495">line 495</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line588">line 588</a>
</li></ul></dd>
@@ -2752,7 +2752,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line296">line 296</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line366">line 366</a>
</li></ul></dd>
@@ -2952,7 +2952,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line163">line 163</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line176">line 176</a>
</li></ul></dd>
@@ -3130,7 +3130,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line318">line 318</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line388">line 388</a>
</li></ul></dd>
@@ -3285,7 +3285,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line363">line 363</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line433">line 433</a>
</li></ul></dd>
@@ -3452,7 +3452,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line245">line 245</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line258">line 258</a>
</li></ul></dd>
@@ -3607,7 +3607,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line387">line 387</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line457">line 457</a>
</li></ul></dd>
@@ -3762,7 +3762,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line375">line 375</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line445">line 445</a>
</li></ul></dd>
@@ -3929,7 +3929,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line261">line 261</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line331">line 331</a>
</li></ul></dd>
@@ -4084,7 +4084,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line399">line 399</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line469">line 469</a>
</li></ul></dd>
@@ -4190,7 +4190,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line139">line 139</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line152">line 152</a>
</li></ul></dd>
@@ -4292,7 +4292,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line144">line 144</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line157">line 157</a>
</li></ul></dd>
@@ -4443,7 +4443,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line381">line 381</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line451">line 451</a>
</li></ul></dd>
@@ -4610,7 +4610,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line269">line 269</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line339">line 339</a>
</li></ul></dd>
@@ -4765,7 +4765,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line411">line 411</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line481">line 481</a>
</li></ul></dd>
@@ -4935,7 +4935,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line421">line 421</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line491">line 491</a>
</li></ul></dd>
@@ -5086,7 +5086,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line405">line 405</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line475">line 475</a>
</li></ul></dd>
@@ -5196,7 +5196,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line474">line 474</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line567">line 567</a>
</li></ul></dd>
@@ -5302,7 +5302,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line484">line 484</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line577">line 577</a>
</li></ul></dd>
@@ -5404,7 +5404,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line435">line 435</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line505">line 505</a>
</li></ul></dd>
@@ -5578,7 +5578,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line278">line 278</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line348">line 348</a>
</li></ul></dd>
@@ -5684,7 +5684,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line126">line 126</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line139">line 139</a>
</li></ul></dd>
@@ -5835,7 +5835,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line345">line 345</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line415">line 415</a>
</li></ul></dd>
@@ -6013,7 +6013,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line287">line 287</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line357">line 357</a>
</li></ul></dd>
@@ -6168,7 +6168,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line339">line 339</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line409">line 409</a>
</li></ul></dd>
@@ -6323,7 +6323,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line351">line 351</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line421">line 421</a>
</li></ul></dd>
@@ -6478,7 +6478,7 @@ This note's representation is used in note tree and is kept in TreeCache.</div>
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line357">line 357</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line427">line 427</a>
</li></ul></dd>
@@ -6589,7 +6589,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line465">line 465</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line558">line 558</a>
</li></ul></dd>
@@ -6673,7 +6673,7 @@ Cache is note instance scoped.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line89">line 89</a>
<a href="entities_note_short.js.html">entities/note_short.js</a>, <a href="entities_note_short.js.html#line102">line 102</a>
</li></ul></dd>

View File

@@ -50,6 +50,8 @@ class Attribute {
this.position = row.position;
/** @param {boolean} isInheritable */
this.isInheritable = !!row.isInheritable;
/** @param {boolean} */
this.isDeleted = !!row.isDeleted;
}
/** @returns {NoteShort} */
@@ -114,6 +116,17 @@ class Attribute {
getDefinition() {
return promotedAttributeDefinitionParser.parse(this.value);
}
isDefinitionFor(attr) {
return this.type === 'label' &amp;&amp; this.name === `${attr.type}:${attr.name}`;
}
get dto() {
const dto = Object.assign({}, this);
delete dto.treeCache;
return dto;
}
}
export default Attribute;

View File

@@ -48,6 +48,8 @@ class Branch {
/** @param {boolean} */
this.isExpanded = !!row.isExpanded;
/** @param {boolean} */
this.fromSearchNote = !!row.fromSearchNote;
/** @param {boolean} */
this.isDeleted = !!row.isDeleted;
}
@@ -76,7 +78,8 @@ class Branch {
}
}
export default Branch;</code></pre>
export default Branch;
</code></pre>
</article>
</section>

View File

@@ -27,12 +27,23 @@
<section>
<article>
<pre class="prettyprint source linenums"><code>import server from '../services/server.js';
import Attribute from './attribute.js';
import noteAttributeCache from "../services/note_attribute_cache.js";
import ws from "../services/ws.js";
import options from "../services/options.js";
const LABEL = 'label';
const RELATION = 'relation';
const NOTE_TYPE_ICONS = {
"file": "bx bx-file",
"image": "bx bx-image",
"code": "bx bx-code",
"render": "bx bx-extension",
"search": "bx bx-file-find",
"relation-map": "bx bx-map-alt",
"book": "bx bx-book"
};
/**
* FIXME: since there's no "full note" anymore we can rename this to Note
*
@@ -78,7 +89,7 @@ class NoteShort {
/** @param {string} content-type, e.g. "application/json" */
this.mime = row.mime;
/** @param {boolean} */
this.isDeleted = row.isDeleted;
this.isDeleted = !!row.isDeleted;
}
addParent(parentNoteId, branchId) {
@@ -93,15 +104,17 @@ class NoteShort {
this.parentToBranch[parentNoteId] = branchId;
}
addChild(childNoteId, branchId) {
if (!this.children.includes(childNoteId)) {
addChild(childNoteId, branchId, sort = true) {
if (!(childNoteId in this.childToBranch)) {
this.children.push(childNoteId);
}
this.childToBranch[childNoteId] = branchId;
if (sort) {
this.sortChildren();
}
}
sortChildren() {
const branchIdPos = {};
@@ -282,6 +295,63 @@ class NoteShort {
return this.getAttributes(LABEL, name);
}
getIcon() {
const iconClassLabels = this.getLabels('iconClass');
const workspaceIconClass = this.getWorkspaceIconClass();
if (iconClassLabels.length > 0) {
return iconClassLabels.map(l => l.value).join(' ');
}
else if (workspaceIconClass) {
return workspaceIconClass;
}
else if (this.noteId === 'root') {
return "bx bx-chevrons-right";
}
else if (this.type === 'text') {
if (this.isFolder()) {
return "bx bx-folder";
}
else {
return "bx bx-note";
}
}
else if (this.type === 'code' &amp;&amp; this.mime.startsWith('text/x-sql')) {
return "bx bx-data";
}
else {
return NOTE_TYPE_ICONS[this.type];
}
}
isFolder() {
return this.type === 'search'
|| this.getFilteredChildBranches().length > 0;
}
getFilteredChildBranches() {
let childBranches = this.getChildBranches();
if (!childBranches) {
ws.logError(`No children for ${parentNote}. This shouldn't happen.`);
return;
}
if (options.is("hideIncludedImages_main")) {
const imageLinks = this.getRelations('imageLink');
// image is already visible in the parent note so no need to display it separately in the book
childBranches = childBranches.filter(branch => !imageLinks.find(rel => rel.value === branch.noteId));
}
// we're not checking hideArchivedNotes since that would mean we need to lazy load the child notes
// which would seriously slow down everything.
// we check this flag only once user chooses to expand the parent. This has the negative consequence that
// note may appear as folder but not contain any children when all of them are archived
return childBranches;
}
/**
* @param {string} [name] - relation name to filter
* @returns {Attribute[]} all note's relations (attributes with type relation), including inherited ones
@@ -466,19 +536,42 @@ class NoteShort {
return relations.map(rel => this.treeCache.notes[rel.value]);
}
hasAncestor(ancestorNote) {
getPromotedDefinitionAttributes() {
if (this.hasLabel('hidePromotedAttributes')) {
return [];
}
return this.getAttributes()
.filter(attr => attr.isDefinition())
.filter(attr => {
const def = attr.getDefinition();
return def &amp;&amp; def.isPromoted;
});
}
hasAncestor(ancestorNote, visitedNoteIds) {
if (this.noteId === ancestorNote.noteId) {
return true;
}
if (!visitedNoteIds) {
visitedNoteIds = new Set();
} else if (visitedNoteIds.has(this.noteId)) {
// to avoid infinite cycle when template is descendent of the instance
return false;
}
visitedNoteIds.add(this.noteId);
for (const templateNote of this.getTemplateNotes()) {
if (templateNote.hasAncestor(ancestorNote)) {
if (templateNote.hasAncestor(ancestorNote, visitedNoteIds)) {
return true;
}
}
for (const parentNote of this.getParentNotes()) {
if (parentNote.hasAncestor(ancestorNote)) {
if (parentNote.hasAncestor(ancestorNote, visitedNoteIds)) {
return true;
}
}
@@ -539,6 +632,16 @@ class NoteShort {
const labels = this.getLabels('cssClass');
return labels.map(l => l.value).join(' ');
}
getWorkspaceIconClass() {
const labels = this.getLabels('workspaceIconClass');
return labels.length > 0 ? labels[0].value : "";
}
getWorkspaceTabBackgroundColor() {
const labels = this.getLabels('workspaceTabBackgroundColor');
return labels.length > 0 ? labels[0].value : "";
}
}
export default NoteShort;

View File

@@ -156,7 +156,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="widgets_collapsible_widget.js.html">widgets/collapsible_widget.js</a>, <a href="widgets_collapsible_widget.js.html#line93">line 93</a>
<a href="widgets_collapsible_widget.js.html">widgets/collapsible_widget.js</a>, <a href="widgets_collapsible_widget.js.html#line124">line 124</a>
</li></ul></dd>
@@ -244,7 +244,7 @@
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="widgets_collapsible_widget.js.html">widgets/collapsible_widget.js</a>, <a href="widgets_collapsible_widget.js.html#line96">line 96</a>
<a href="widgets_collapsible_widget.js.html">widgets/collapsible_widget.js</a>, <a href="widgets_collapsible_widget.js.html#line127">line 127</a>
</li></ul></dd>
@@ -333,7 +333,7 @@ separately but should behave uniformly for the user.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="widgets_collapsible_widget.js.html">widgets/collapsible_widget.js</a>, <a href="widgets_collapsible_widget.js.html#line86">line 86</a>
<a href="widgets_collapsible_widget.js.html">widgets/collapsible_widget.js</a>, <a href="widgets_collapsible_widget.js.html#line117">line 117</a>
</li></ul></dd>
@@ -572,7 +572,7 @@ separately but should behave uniformly for the user.
<dt class="tag-source">Source:</dt>
<dd class="tag-source"><ul class="dummy"><li>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line76">line 76</a>
<a href="services_frontend_script_api.js.html">services/frontend_script_api.js</a>, <a href="services_frontend_script_api.js.html#line88">line 88</a>
</li></ul></dd>

View File

@@ -26,8 +26,7 @@
<section>
<article>
<pre class="prettyprint source linenums"><code>import treeService from './tree.js';
import server from './server.js';
<pre class="prettyprint source linenums"><code>import server from './server.js';
import utils from './utils.js';
import toastService from './toast.js';
import linkService from './link.js';
@@ -37,7 +36,6 @@ import protectedSessionService from './protected_session.js';
import dateNotesService from './date_notes.js';
import CollapsibleWidget from '../widgets/collapsible_widget.js';
import ws from "./ws.js";
import hoistedNoteService from "./hoisted_note.js";
import appContext from "./app_context.js";
import TabAwareWidget from "../widgets/tab_aware_widget.js";
import TabCachingWidget from "../widgets/tab_caching_widget.js";
@@ -101,6 +99,20 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
appContext.triggerEvent('focusAndSelectTitle');
};
/**
* Open a note in a new tab.
*
* @param {string} notePath (or noteId)
* @param {boolean} activate - set to true to activate the new tab, false to stay on the current tab
* @return {Promise&lt;void>}
*/
this.openTabWithNote = async (notePath, activate) => {
await ws.waitForMaxKnownEntityChangeId();
await appContext.tabManager.openTabWithNote(notePath, activate);
appContext.triggerEvent('focusAndSelectTitle');
};
/**
* @typedef {Object} ToolbarButtonOptions
* @property {string} title
@@ -117,7 +129,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
this.addButtonToToolbar = opts => {
const buttonId = "toolbar-button-" + opts.title.replace(/\s/g, "-");
const button = $('&lt;button>')
const button = $('&lt;button class="noborder">')
.addClass("btn btn-sm")
.on('click', opts.action);
@@ -302,7 +314,10 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
*
* @method
* @param {string} notePath (or noteId)
* @param {string} [noteTitle] - if not present we'll use note title
* @param {object} [params]
* @param {boolean} [params.showTooltip=true] - enable/disable tooltip on the link
* @param {boolean} [params.showNotePath=false] - show also whole note's path as part of the link
* @param {string} [title=] - custom link tile with note's title as default
*/
this.createNoteLink = linkService.createNoteLink;
@@ -404,13 +419,19 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
this.getYearNote = dateNotesService.getYearNote;
/**
* Hoist note. See https://github.com/zadam/trilium/wiki/Note-hoisting
* Hoist note in the current tab. See https://github.com/zadam/trilium/wiki/Note-hoisting
*
* @method
* @param {string} noteId - set hoisted note. 'root' will effectively unhoist
* @return {Promise}
*/
this.setHoistedNoteId = hoistedNoteService.setHoistedNoteId;
this.setHoistedNoteId = (noteId) => {
const activeTabContext = appContext.tabManager.getActiveTabContext();
if (activeTabContext) {
activeTabContext.setHoistedNoteId(noteId);
}
};
/**
* @method

View File

@@ -33,14 +33,23 @@ const WIDGET_TPL = `
&lt;div class="card widget">
&lt;div class="card-header">
&lt;div>
&lt;button class="btn btn-sm widget-title" data-toggle="collapse" data-target="#[to be set]">
Collapsible Group Item
&lt;/button>
&lt;a class="widget-toggle-button no-arrow"
title="Minimize/maximize widget"
data-toggle="collapse" data-target="#[to be set]">
&lt;a class="widget-help external no-arrow bx bx-info-circle">&lt;/a>
&lt;span class="widget-toggle-icon bx">&lt;/span>
&lt;span class="widget-title">
Collapsible Group Item
&lt;/span>
&lt;/a>
&lt;span class="widget-header-actions">&lt;/span>
&lt;/div>
&lt;div class="widget-header-actions">&lt;/div>
&lt;div>
&lt;a class="widget-help external no-arrow bx bx-info-circle">&lt;/a>
&lt;/div>
&lt;/div>
&lt;div id="[to be set]" class="collapse body-wrapper" style="transition: none; ">
@@ -66,13 +75,19 @@ export default class CollapsibleWidget extends TabAwareWidget {
// not using constructor name because of webpack mangling class names ...
this.widgetName = this.widgetTitle.replace(/[^[a-zA-Z0-9]/g, "_");
if (!options.is(this.widgetName + 'Collapsed')) {
this.$toggleButton = this.$widget.find('.widget-toggle-button');
this.$toggleIcon = this.$widget.find('.widget-toggle-icon');
const collapsed = options.is(this.widgetName + 'Collapsed');
if (!collapsed) {
this.$bodyWrapper.collapse("show");
}
this.updateToggleIcon(collapsed);
// using immediate variants of the event so that the previous collapse is not caught
this.$bodyWrapper.on('hide.bs.collapse', () => this.saveCollapsed(true));
this.$bodyWrapper.on('show.bs.collapse', () => this.saveCollapsed(false));
this.$bodyWrapper.on('hide.bs.collapse', () => this.toggleCollapsed(true));
this.$bodyWrapper.on('show.bs.collapse', () => this.toggleCollapsed(false));
this.$body = this.$bodyWrapper.find('.card-body');
@@ -94,19 +109,35 @@ export default class CollapsibleWidget extends TabAwareWidget {
}
this.$headerActions = this.$widget.find('.widget-header-actions');
this.$headerActions.append(...this.headerActions);
this.$headerActions.append(this.headerActions);
this.initialized = this.doRenderBody();
this.decorateWidget();
}
saveCollapsed(collapse) {
toggleCollapsed(collapse) {
this.updateToggleIcon(collapse);
options.save(this.widgetName + 'Collapsed', collapse.toString());
this.triggerEvent(`widgetCollapsedStateChanged`, {widgetName: this.widgetName, collapse});
}
updateToggleIcon(collapse) {
if (collapse) {
this.$toggleIcon
.addClass("bx-chevron-right")
.removeClass("bx-chevron-down")
.attr("title", "Show");
} else {
this.$toggleIcon
.addClass("bx-chevron-down")
.removeClass("bx-chevron-right")
.attr("title", "Hide");
}
}
/**
* This event is used to synchronize collapsed state of all the tab-cached widgets since they are all rendered
* separately but should behave uniformly for the user.

984
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
"name": "trilium",
"productName": "Trilium Notes",
"description": "Trilium Notes",
"version": "0.46.0-beta",
"version": "0.46.5",
"license": "AGPL-3.0-only",
"main": "electron.js",
"bin": {
@@ -24,7 +24,7 @@
"test-all": "npm run test && npm run test-es6"
},
"dependencies": {
"async-mutex": "0.3.0",
"async-mutex": "0.3.1",
"axios": "0.21.1",
"better-sqlite3": "7.1.2",
"body-parser": "1.19.0",
@@ -35,7 +35,7 @@
"dayjs": "1.10.4",
"ejs": "3.1.6",
"electron-debug": "3.2.0",
"electron-dl": "3.0.3",
"electron-dl": "3.2.0",
"electron-find": "1.0.6",
"electron-window-state": "5.0.3",
"express": "4.17.1",
@@ -51,11 +51,11 @@
"is-animated": "^2.0.1",
"is-svg": "4.2.1",
"jimp": "0.16.1",
"jsdom": "^16.4.0",
"mime-types": "2.1.28",
"jsdom": "16.5.0",
"mime-types": "2.1.29",
"multer": "1.4.2",
"node-abi": "2.19.3",
"open": "7.4.1",
"node-abi": "2.21.0",
"open": "7.4.2",
"portscanner": "2.2.0",
"rand-token": "1.0.1",
"request": "^2.88.2",
@@ -70,16 +70,16 @@
"striptags": "3.1.1",
"tmp": "^0.2.1",
"turndown": "7.0.0",
"turndown-plugin-gfm": "1.0.2",
"joplin-turndown-plugin-gfm": "1.0.12",
"unescape": "1.0.1",
"ws": "7.4.3",
"ws": "7.4.4",
"yauzl": "2.10.0",
"yazl": "2.5.1"
},
"devDependencies": {
"cross-env": "7.0.3",
"electron": "9.4.3",
"electron-builder": "22.9.1",
"electron": "9.4.4",
"electron-builder": "22.10.5",
"electron-packager": "15.2.0",
"electron-rebuild": "2.3.5",
"esm": "3.2.25",
@@ -87,7 +87,7 @@
"jsdoc": "3.6.6",
"lorem-ipsum": "2.0.3",
"rcedit": "3.0.0",
"webpack": "5.21.2",
"webpack": "5.24.4",
"webpack-cli": "4.5.0"
},
"optionalDependencies": {

View File

@@ -41,7 +41,7 @@ class Entity {
}
getUtcDateChanged() {
return this.utcDateModified;
return this.utcDateModified || this.utcDateCreated;
}
get repository() {

View File

@@ -681,7 +681,7 @@ class Note extends Entity {
* Update's given relation's value or creates it if it doesn't exist
*
* @param {string} name - relation name
* @param {string} [value] - relation value (noteId)
* @param {string} value - relation value (noteId)
*/
setRelation(name, value) { return this.setAttribute(RELATION, name, value); }

View File

@@ -41,7 +41,10 @@ export async function showDialog(widget, text = '') {
$linkTitle.val(noteTitle);
}
noteAutocompleteService.initNoteAutocomplete($autoComplete, { allowExternalLinks: true });
noteAutocompleteService.initNoteAutocomplete($autoComplete, {
allowExternalLinks: true,
allowCreatingNotes: true
});
$autoComplete.on('autocomplete:noteselected', (event, suggestion, dataset) => {
if (!suggestion.notePath) {

View File

@@ -129,7 +129,7 @@ ws.subscribeToMessages(async message => {
toastService.showPersistent(makeToast(message.taskId, "Export in progress: " + message.progressCount));
}
else if (message.type === 'task-succeeded') {
const toast = makeToast(message.taskId, "Import finished successfully.");
const toast = makeToast(message.taskId, "Export finished successfully.");
toast.closeAfter = 5000;
toastService.showPersistent(toast);

View File

@@ -17,7 +17,10 @@ export async function showDialog(widget) {
utils.openDialog($dialog);
noteAutocompleteService.initNoteAutocomplete($autoComplete, { hideGoToSelectedNoteButton: true });
noteAutocompleteService.initNoteAutocomplete($autoComplete, {
hideGoToSelectedNoteButton: true,
allowCreatingNotes: true
});
noteAutocompleteService.showRecentNotes($autoComplete);
}

View File

@@ -29,7 +29,17 @@ const TPL = `
</div>
</div>
<p>Zooming can be controlled with CTRL-+ and CTRL-= shortcuts as well.</p>
<div class="form-group row">
<div class="col-4">
<label for="heading-style">Heading style</label>
<select class="form-control" id="heading-style">
<option value="plain">Plain</option>
<option value="markdown">Markdown-style</option>
</select>
</div>
</div>
<p>Zooming can be controlled with CTRL+- and CTRL+= shortcuts as well.</p>
<h4>Font sizes</h4>
@@ -78,6 +88,7 @@ export default class ApperanceOptions {
this.$themeSelect = $("#theme-select");
this.$zoomFactorSelect = $("#zoom-factor-select");
this.$nativeTitleBarSelect = $("#native-title-bar-select");
this.$headingStyle = $("#heading-style");
this.$mainFontSize = $("#main-font-size");
this.$treeFontSize = $("#tree-font-size");
this.$detailFontSize = $("#detail-font-size");
@@ -86,11 +97,7 @@ export default class ApperanceOptions {
this.$themeSelect.on('change', () => {
const newTheme = this.$themeSelect.val();
for (const clazz of Array.from(this.$body[0].classList)) { // create copy to safely iterate over while removing classes
if (clazz.startsWith("theme-")) {
this.$body.removeClass(clazz);
}
}
this.toggleBodyClass("theme-", newTheme);
const noteId = $(this).find(":selected").attr("data-note-id");
@@ -100,8 +107,6 @@ export default class ApperanceOptions {
libraryLoader.requireCss(`api/notes/download/${noteId}`);
}
this.$body.addClass("theme-" + newTheme);
server.put('options/theme/' + newTheme);
});
@@ -113,6 +118,14 @@ export default class ApperanceOptions {
server.put('options/nativeTitleBarVisible/' + nativeTitleBarVisible);
});
this.$headingStyle.on('change', () => {
const newHeadingStyle = this.$headingStyle.val();
this.toggleBodyClass("heading-style-", newHeadingStyle);
server.put('options/headingStyle/' + newHeadingStyle);
});
this.$mainFontSize.on('change', async () => {
await server.put('options/mainFontSize/' + this.$mainFontSize.val());
@@ -132,6 +145,16 @@ export default class ApperanceOptions {
});
}
toggleBodyClass(prefix, value) {
for (const clazz of Array.from(this.$body[0].classList)) { // create copy to safely iterate over while removing classes
if (clazz.startsWith(prefix)) {
this.$body.removeClass(clazz);
}
}
this.$body.addClass(prefix + value);
}
async optionsLoaded(options) {
const themes = [
{ val: 'white', title: 'White' },
@@ -159,6 +182,8 @@ export default class ApperanceOptions {
this.$nativeTitleBarSelect.val(options.nativeTitleBarVisible === 'true' ? 'show' : 'hide');
this.$headingStyle.val(options.headingStyle);
this.$mainFontSize.val(options.mainFontSize);
this.$treeFontSize.val(options.treeFontSize);
this.$detailFontSize.val(options.detailFontSize);

View File

@@ -0,0 +1,24 @@
import server from "../services/server.js";
import utils from "../services/utils.js";
const $dialog = $("#sort-child-notes-dialog");
const $form = $("#sort-child-notes-form");
let parentNoteId = null;
$form.on('submit', async () => {
const sortBy = $form.find("input[name='sort-by']:checked").val();
const sortDirection = $form.find("input[name='sort-direction']:checked").val();
await server.put(`notes/${parentNoteId}/sort-children`, {sortBy, sortDirection});
utils.closeActiveDialog();
});
export async function showDialog(noteId) {
parentNoteId = noteId;
utils.openDialog($dialog);
$form.find('input:first').focus();
}

View File

@@ -2,6 +2,7 @@ import server from '../services/server.js';
import noteAttributeCache from "../services/note_attribute_cache.js";
import ws from "../services/ws.js";
import options from "../services/options.js";
import treeCache from "../services/tree_cache.js";
const LABEL = 'label';
const RELATION = 'relation';
@@ -158,6 +159,26 @@ class NoteShort {
return this.treeCache.getNotesFromCache(this.parents);
}
// will sort the parents so that non-search & non-archived are first and archived at the end
// this is done so that non-search & non-archived paths are always explored as first when looking for note path
resortParents() {
this.parents.sort((aNoteId, bNoteId) => {
const aBranchId = this.parentToBranch[aNoteId];
if (aBranchId && aBranchId.startsWith('virt-')) {
return 1;
}
const aNote = this.treeCache.getNoteFromCache([aNoteId]);
if (aNote.hasLabel('archived')) {
return 1;
}
return -1;
});
}
/** @returns {string[]} */
getChildNoteIds() {
return this.children;
@@ -233,6 +254,72 @@ class NoteShort {
return noteAttributeCache.attributes[this.noteId];
}
getAllNotePaths(encounteredNoteIds = null) {
if (this.noteId === 'root') {
return [['root']];
}
if (!encounteredNoteIds) {
encounteredNoteIds = new Set();
}
encounteredNoteIds.add(this.noteId);
const parentNotes = this.getParentNotes();
let paths;
if (parentNotes.length === 1) { // optimization for the most common case
if (encounteredNoteIds.has(parentNotes[0].noteId)) {
return [];
}
else {
paths = parentNotes[0].getAllNotePaths(encounteredNoteIds);
}
}
else {
paths = [];
for (const parentNote of parentNotes) {
if (encounteredNoteIds.has(parentNote.noteId)) {
continue;
}
const newSet = new Set(encounteredNoteIds);
paths.push(...parentNote.getAllNotePaths(newSet));
}
}
for (const path of paths) {
path.push(this.noteId);
}
return paths;
}
getSortedNotePaths(hoistedNotePath = 'root') {
const notePaths = this.getAllNotePaths().map(path => ({
notePath: path,
isInHoistedSubTree: path.includes(hoistedNotePath),
isArchived: path.find(noteId => treeCache.notes[noteId].hasLabel('archived')),
isSearch: path.find(noteId => treeCache.notes[noteId].type === 'search')
}));
notePaths.sort((a, b) => {
if (a.isInHoistedSubTree !== b.isInHoistedSubTree) {
return a.isInHoistedSubTree ? -1 : 1;
} else if (a.isSearch !== b.isSearch) {
return a.isSearch ? 1 : -1;
} else if (a.isArchived !== b.isArchived) {
return a.isArchived ? 1 : -1;
} else {
return a.notePath.length - b.notePath.length;
}
});
return notePaths;
}
__filterAttrs(attributes, type, name) {
if (!type && !name) {
return attributes;
@@ -522,7 +609,7 @@ class NoteShort {
});
}
hasAncestor(ancestorNote, visitedNoteIds) {
hasAncestor(ancestorNote, visitedNoteIds = null) {
if (this.noteId === ancestorNote.noteId) {
return true;
}

View File

@@ -22,6 +22,7 @@ import ImagePropertiesWidget from "../widgets/type_property_widgets/image_proper
import NotePropertiesWidget from "../widgets/type_property_widgets/note_properties.js";
import NoteIconWidget from "../widgets/note_icon.js";
import NotePathsWidget from "../widgets/note_paths.js";
import SearchResultWidget from "../widgets/search_result.js";
export default class DesktopExtraWindowLayout {
constructor(customWidgets) {
@@ -69,6 +70,7 @@ export default class DesktopExtraWindowLayout {
.child(new TabCachingWidget(() => new SqlTableSchemasWidget()))
.child(new TabCachingWidget(() => new NoteDetailWidget()))
.child(new TabCachingWidget(() => new NoteListWidget()))
.child(new TabCachingWidget(() => new SearchResultWidget()))
.child(new TabCachingWidget(() => new SqlResultWidget()))
)
.child(...this.customWidgets.get('center-pane'))

View File

@@ -32,6 +32,7 @@ import FilePropertiesWidget from "../widgets/type_property_widgets/file_properti
import ImagePropertiesWidget from "../widgets/type_property_widgets/image_properties.js";
import NotePropertiesWidget from "../widgets/type_property_widgets/note_properties.js";
import NoteIconWidget from "../widgets/note_icon.js";
import SearchResultWidget from "../widgets/search_result.js";
const RIGHT_PANE_CSS = `
<style>
@@ -179,6 +180,7 @@ export default class DesktopMainWindowLayout {
.child(new TabCachingWidget(() => new SqlTableSchemasWidget()))
.child(new TabCachingWidget(() => new NoteDetailWidget()))
.child(new TabCachingWidget(() => new NoteListWidget()))
.child(new TabCachingWidget(() => new SearchResultWidget()))
.child(new TabCachingWidget(() => new SqlResultWidget()))
)
.child(new TabCachingWidget(() => new SimilarNotesWidget()))

View File

@@ -12,6 +12,7 @@ import keyboardActionsService from "./keyboard_actions.js";
import MobileScreenSwitcherExecutor from "../widgets/mobile_widgets/mobile_screen_switcher.js";
import MainTreeExecutors from "./main_tree_executors.js";
import protectedSessionHolder from "./protected_session_holder.js";
import toast from "./toast.js";
class AppContext extends Component {
constructor(isMainWindow) {
@@ -19,6 +20,7 @@ class AppContext extends Component {
this.isMainWindow = isMainWindow;
this.executors = [];
this.beforeUnloadListeners = [];
}
setLayout(layout) {
@@ -104,6 +106,15 @@ class AppContext extends Component {
getComponentByEl(el) {
return $(el).closest(".component").prop('component');
}
addBeforeUnloadListener(obj) {
if (typeof WeakRef !== "function") {
// older browsers don't support WeakRef
return;
}
this.beforeUnloadListeners.push(new WeakRef(obj));
}
}
const appContext = new AppContext(window.glob.isMainWindow);
@@ -112,7 +123,29 @@ const appContext = new AppContext(window.glob.isMainWindow);
$(window).on('beforeunload', () => {
protectedSessionHolder.resetSessionCookie();
appContext.triggerEvent('beforeUnload');
let allSaved = true;
appContext.beforeUnloadListeners = appContext.beforeUnloadListeners.filter(wr => !!wr.deref());
for (const weakRef of appContext.beforeUnloadListeners) {
const component = weakRef.deref();
if (!component) {
continue;
}
if (!component.beforeUnloadEvent()) {
console.log(`Component ${component.componentId} is not finished saving its state.`);
toast.showMessage("Please wait for a couple of seconds for the save to finish, then you can try again.", 10000);
allSaved = false;
}
}
if (!allSaved) {
return "some string";
}
});
function isNotePathInAddress() {

View File

@@ -1,3 +1,5 @@
import utils from "./utils.js";
function lex(str) {
str = str.trim();
@@ -105,14 +107,12 @@ function lex(str) {
return tokens;
}
const attrNameMatcher = new RegExp("^[\\p{L}\\p{N}_:]+$", "u");
function checkAttributeName(attrName) {
if (attrName.length === 0) {
throw new Error("Attribute name is empty, please fill the name.");
}
if (!attrNameMatcher.test(attrName)) {
if (!utils.isValidAttributeName(attrName)) {
throw new Error(`Attribute name "${attrName}" contains disallowed characters, only alphanumeric characters, colon and underscore are allowed.`);
}
}

View File

@@ -79,6 +79,15 @@ async function renderAttributes(attributes, renderIsInheritable) {
return $container;
}
const HIDDEN_ATTRIBUTES = [
'originalFileName',
'template',
'cssClass',
'iconClass',
'pageSize',
'viewType'
];
async function renderNormalAttributes(note) {
const promotedDefinitionAttributes = note.getPromotedDefinitionAttributes();
let attrs = note.getAttributes();
@@ -90,6 +99,7 @@ async function renderNormalAttributes(note) {
attrs = attrs.filter(
attr => !attr.isDefinition()
&& !attr.isAutoLink
&& !HIDDEN_ATTRIBUTES.includes(attr.name)
&& attr.noteId === note.noteId
);
}

View File

@@ -7,6 +7,7 @@ import ws from "./ws.js";
async function moveBeforeBranch(branchIdsToMove, beforeBranchId) {
branchIdsToMove = filterRootNote(branchIdsToMove);
branchIdsToMove = filterSearchBranches(branchIdsToMove);
if (beforeBranchId === 'root') {
alert('Cannot move notes before root note.');
@@ -25,6 +26,7 @@ async function moveBeforeBranch(branchIdsToMove, beforeBranchId) {
async function moveAfterBranch(branchIdsToMove, afterBranchId) {
branchIdsToMove = filterRootNote(branchIdsToMove);
branchIdsToMove = filterSearchBranches(branchIdsToMove);
const afterNote = await treeCache.getBranch(afterBranchId).getNote();
@@ -123,7 +125,7 @@ async function deleteNotes(branchIdsToDelete) {
}
async function moveNodeUpInHierarchy(node) {
if (hoistedNoteService.isRootNode(node)
if (hoistedNoteService.isHoistedNode(node)
|| hoistedNoteService.isTopLevelNode(node)
|| node.getParent().data.noteType === 'search') {
return;
@@ -142,6 +144,10 @@ async function moveNodeUpInHierarchy(node) {
}
}
function filterSearchBranches(branchIds) {
return branchIds.filter(branchId => !branchId.startsWith('virt-'));
}
function filterRootNote(branchIds) {
const hoistedNoteId = hoistedNoteService.getHoistedNoteId();

View File

@@ -18,6 +18,8 @@ async function getTodayNote() {
async function getDateNote(date) {
const note = await server.get('date-notes/date/' + date, "date-note");
await ws.waitForMaxKnownEntityChangeId();
return await treeCache.getNote(note.noteId);
}
@@ -25,6 +27,8 @@ async function getDateNote(date) {
async function getMonthNote(month) {
const note = await server.get('date-notes/month/' + month, "date-note");
await ws.waitForMaxKnownEntityChangeId();
return await treeCache.getNote(note.noteId);
}
@@ -32,6 +36,8 @@ async function getMonthNote(month) {
async function getYearNote(year) {
const note = await server.get('date-notes/year/' + year, "date-note");
await ws.waitForMaxKnownEntityChangeId();
return await treeCache.getNote(note.noteId);
}
@@ -39,21 +45,14 @@ async function getYearNote(year) {
async function createSqlConsole() {
const note = await server.post('sql-console');
await ws.waitForMaxKnownEntityChangeId();
return await treeCache.getNote(note.noteId);
}
/** @return {NoteShort} */
async function createSearchNote(opts = {}) {
const note = await server.post('search-note');
const attrsToUpdate = [
opts.ancestorNoteId ? { type: 'relation', name: 'ancestor', value: opts.ancestorNoteId } : undefined,
{ type: 'label', name: 'searchString', value: opts.searchString }
].filter(attr => !!attr);
if (attrsToUpdate.length > 0) {
await server.put(`notes/${note.noteId}/attributes`, attrsToUpdate);
}
const note = await server.post('search-note', opts);
await ws.waitForMaxKnownEntityChangeId();

View File

@@ -74,7 +74,11 @@ export default class Entrypoints extends Component {
await ws.waitForMaxKnownEntityChangeId();
await appContext.tabManager.openTabWithNote(note.noteId, true);
const hoistedNoteId = appContext.tabManager.getActiveTabContext()
? appContext.tabManager.getActiveTabContext().hoistedNoteId
: 'root';
await appContext.tabManager.openTabWithNote(note.noteId, true, null, hoistedNoteId);
appContext.triggerEvent('focusAndSelectTitle');
}
@@ -182,8 +186,6 @@ export default class Entrypoints extends Component {
utils.reloadApp();
}
createTopLevelNoteCommand() { noteCreateService.createNewTopLevelNote(); }
async openInWindowCommand({notePath, hoistedNoteId}) {
if (!hoistedNoteId) {
hoistedNoteId = 'root';

View File

@@ -71,6 +71,23 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
appContext.triggerEvent('focusAndSelectTitle');
};
/**
* Open a note in a new tab.
*
* @param {string} notePath (or noteId)
* @param {boolean} activate - set to true to activate the new tab, false to stay on the current tab
* @return {Promise<void>}
*/
this.openTabWithNote = async (notePath, activate) => {
await ws.waitForMaxKnownEntityChangeId();
await appContext.tabManager.openTabWithNote(notePath, activate);
if (activate) {
appContext.triggerEvent('focusAndSelectTitle');
}
};
/**
* @typedef {Object} ToolbarButtonOptions
* @property {string} title
@@ -149,8 +166,7 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain
}, "script");
if (ret.success) {
// wait until all the changes done in the script has been synced to frontend before continuing
await ws.waitForEntityChangeId(ret.maxEntityChangeId);
await ws.waitForMaxKnownEntityChangeId();
return ret.executionResult;
}

View File

@@ -16,19 +16,17 @@ async function unhoist() {
}
function isTopLevelNode(node) {
return isRootNode(node.getParent());
return isHoistedNode(node.getParent());
}
function isRootNode(node) {
function isHoistedNode(node) {
// even though check for 'root' should not be necessary, we keep it just in case
return node.data.noteId === "root"
|| node.data.noteId === getHoistedNoteId();
}
async function checkNoteAccess(notePath, tabContext) {
// notePath argument can contain only noteId which is not good when hoisted since
// then we need to check the whole note path
const resolvedNotePath = await treeService.resolveNotePath(notePath);
const resolvedNotePath = await treeService.resolveNotePath(notePath, tabContext.hoistedNoteId);
if (!resolvedNotePath) {
console.log("Cannot activate " + notePath);
@@ -37,7 +35,7 @@ async function checkNoteAccess(notePath, tabContext) {
const hoistedNoteId = tabContext.hoistedNoteId;
if (hoistedNoteId !== 'root' && !resolvedNotePath.includes(hoistedNoteId)) {
if (!resolvedNotePath.includes(hoistedNoteId)) {
const confirmDialog = await import('../dialogs/confirm.js');
if (!await confirmDialog.confirm("Requested note is outside of hoisted note subtree and you must unhoist to access the note. Do you want to proceed with unhoisting?")) {
@@ -55,6 +53,6 @@ export default {
getHoistedNoteId,
unhoist,
isTopLevelNode,
isRootNode,
isHoistedNode,
checkNoteAccess
}

View File

@@ -117,7 +117,8 @@ export default class LinkMap {
const $noteBox = $("<div>")
.addClass("note-box")
.prop("id", noteBoxId);
.prop("id", noteBoxId)
.addClass(note.getCssClass());
const $link = $linkTitles[noteId];

View File

@@ -27,28 +27,28 @@ export default class MainTreeExecutors extends Component {
}
async createNoteIntoCommand() {
const activeNote = appContext.tabManager.getActiveTabNote();
const activeTabContext = appContext.tabManager.getActiveTabContext();
if (!activeNote) {
if (!activeTabContext) {
return;
}
await noteCreateService.createNote(activeNote.noteId, {
isProtected: activeNote.isProtected,
await noteCreateService.createNote(activeTabContext.notePath, {
isProtected: activeTabContext.note.isProtected,
saveSelection: false
});
}
async createNoteAfterCommand() {
const node = this.tree.getActiveNode();
const parentNoteId = node.data.parentNoteId;
const parentNotePath = treeService.getNotePath(node.getParent());
const isProtected = await treeService.getParentProtectedStatus(node);
if (node.data.noteId === 'root' || node.data.noteId === hoistedNoteService.getHoistedNoteId()) {
return;
}
await noteCreateService.createNote(parentNoteId, {
await noteCreateService.createNote(parentNotePath, {
target: 'after',
targetBranchId: node.data.branchId,
isProtected: isProtected,

View File

@@ -1,19 +1,13 @@
import hoistedNoteService from "./hoisted_note.js";
import appContext from "./app_context.js";
import utils from "./utils.js";
import protectedSessionHolder from "./protected_session_holder.js";
import server from "./server.js";
import ws from "./ws.js";
import treeCache from "./tree_cache.js";
import treeService from "./tree.js";
import toastService from "./toast.js";
async function createNewTopLevelNote() {
const hoistedNoteId = hoistedNoteService.getHoistedNoteId();
await createNote(hoistedNoteId);
}
async function createNote(parentNoteId, options = {}) {
async function createNote(parentNotePath, options = {}) {
options = Object.assign({
activate: true,
focus: 'title',
@@ -36,6 +30,8 @@ async function createNote(parentNoteId, options = {}) {
const newNoteName = options.title || "new note";
const parentNoteId = treeService.getNoteIdFromNotePath(parentNotePath);
const {note, branch} = await server.post(`notes/${parentNoteId}/children?target=${options.target}&targetBranchId=${options.targetBranchId}`, {
title: newNoteName,
content: options.content || "",
@@ -53,7 +49,7 @@ async function createNote(parentNoteId, options = {}) {
if (options.activate) {
const activeTabContext = appContext.tabManager.getActiveTabContext();
await activeTabContext.setNote(note.noteId);
await activeTabContext.setNote(`${parentNotePath}/${note.noteId}`);
if (options.focus === 'title') {
appContext.triggerEvent('focusAndSelectTitle');
@@ -88,12 +84,13 @@ function parseSelectedHtml(selectedHtml) {
}
}
async function duplicateSubtree(noteId, parentNoteId) {
async function duplicateSubtree(noteId, parentNotePath) {
const parentNoteId = treeService.getNoteIdFromNotePath(parentNotePath);
const {note} = await server.post(`notes/${noteId}/duplicate/${parentNoteId}`);
await ws.waitForMaxKnownEntityChangeId();
await appContext.tabManager.activateOrOpenNote(note.noteId);
await appContext.tabManager.activateOrOpenNote(`${parentNotePath}/${note.noteId}`);
const origNote = await treeCache.getNote(noteId);
toastService.showMessage(`Note "${origNote.title}" has been duplicated`);
@@ -101,6 +98,5 @@ async function duplicateSubtree(noteId, parentNoteId) {
export default {
createNote,
createNewTopLevelNote,
duplicateSubtree
};

View File

@@ -56,6 +56,14 @@ const TPL = `
.note-book-title {
margin-bottom: 0;
word-break: break-all;
}
/* not-expanded title is limited to one line only */
.note-book-card:not(.expanded) .note-book-title {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.note-book-title .rendered-note-attributes {
@@ -148,7 +156,7 @@ class NoteListRenderer {
/*
* We're using noteIds so that it's not necessary to load all notes at once when paging
*/
constructor($parent, parentNote, noteIds) {
constructor($parent, parentNote, noteIds, showNotePath = false) {
this.$noteList = $(TPL);
// note list must be added to the DOM immediatelly, otherwise some functionality scripting (canvas) won't work
@@ -200,6 +208,8 @@ class NoteListRenderer {
await this.renderList();
});
this.showNotePath = showNotePath;
}
/** @return {Set<string>} list of noteIds included (images, included notes) into a parent note and which
@@ -298,7 +308,7 @@ class NoteListRenderer {
.append(
$('<h5 class="note-book-title">')
.append($expander)
.append(await linkService.createNoteLink(note.noteId, {showTooltip: false}))
.append(await linkService.createNoteLink(note.noteId, {showTooltip: false, showNotePath: this.showNotePath}))
.append($renderedAttributes)
);

View File

@@ -15,9 +15,25 @@ export default class SpacedUpdate {
async updateNowIfNecessary() {
if (this.changed) {
this.changed = false;
this.changed = false; // optimistic...
try {
await this.updater();
}
catch (e) {
this.changed = true;
throw e;
}
}
}
isAllSavedAndTriggerUpdate() {
const allSaved = !this.changed;
this.updateNowIfNecessary();
return allSaved;
}
triggerUpdate() {

View File

@@ -79,7 +79,7 @@ class TabContext extends Component {
return inputNotePath;
}
const resolvedNotePath = await treeService.resolveNotePath(inputNotePath);
const resolvedNotePath = await treeService.resolveNotePath(inputNotePath, this.hoistedNoteId);
if (!resolvedNotePath) {
logError(`Cannot resolve note path ${inputNotePath}`);

View File

@@ -27,6 +27,8 @@ export default class TabManager extends Component {
openTabs: JSON.stringify(openTabs)
});
});
appContext.addBeforeUnloadListener(this);
}
/** @type {TabContext[]} */
@@ -203,7 +205,7 @@ export default class TabManager extends Component {
let hoistedNoteId = 'root';
if (tabContext) {
const resolvedNotePath = await treeService.resolveNotePath(notePath);
const resolvedNotePath = await treeService.resolveNotePath(notePath, tabContext.hoistedNoteId);
if (resolvedNotePath.includes(tabContext.hoistedNoteId)) {
hoistedNoteId = tabContext.hoistedNoteId;
@@ -329,6 +331,8 @@ export default class TabManager extends Component {
beforeUnloadEvent() {
this.tabsUpdate.updateNowIfNecessary();
return true; // don't block closing the tab, this metadata is not that important
}
openNewTabCommand() {

View File

@@ -8,8 +8,8 @@ import appContext from "./app_context.js";
/**
* @return {string|null}
*/
async function resolveNotePath(notePath) {
const runPath = await resolveNotePathToSegments(notePath);
async function resolveNotePath(notePath, hoistedNoteId = 'root') {
const runPath = await resolveNotePathToSegments(notePath, hoistedNoteId);
return runPath ? runPath.join("/") : null;
}
@@ -21,7 +21,7 @@ async function resolveNotePath(notePath) {
*
* @return {string[]}
*/
async function resolveNotePathToSegments(notePath, logErrors = true) {
async function resolveNotePathToSegments(notePath, hoistedNoteId = 'root', logErrors = true) {
utils.assertArguments(notePath);
// we might get notePath with the tabId suffix, remove it if present
@@ -37,7 +37,7 @@ async function resolveNotePathToSegments(notePath, logErrors = true) {
path.push('root');
}
const effectivePath = [];
const effectivePathSegments = [];
let childNoteId = null;
let i = 0;
@@ -56,6 +56,8 @@ async function resolveNotePathToSegments(notePath, logErrors = true) {
return;
}
child.resortParents();
const parents = child.getParentNotes();
if (!parents.length) {
@@ -73,13 +75,13 @@ async function resolveNotePathToSegments(notePath, logErrors = true) {
console.log(utils.now(), `Did not find parent ${parentNoteId} (${parent ? parent.title : 'n/a'}) for child ${childNoteId} (${child.title}), available parents: ${parents.map(p => `${p.noteId} (${p.title})`)}`);
}
const someNotePath = getSomeNotePath(parents[0]);
const someNotePath = getSomeNotePath(child, hoistedNoteId);
if (someNotePath) { // in case it's root the path may be empty
const pathToRoot = someNotePath.split("/").reverse();
const pathToRoot = someNotePath.split("/").reverse().slice(1);
for (const noteId of pathToRoot) {
effectivePath.push(noteId);
effectivePathSegments.push(noteId);
}
}
@@ -87,36 +89,37 @@ async function resolveNotePathToSegments(notePath, logErrors = true) {
}
}
effectivePath.push(parentNoteId);
effectivePathSegments.push(parentNoteId);
childNoteId = parentNoteId;
}
return effectivePath.reverse();
effectivePathSegments.reverse();
if (effectivePathSegments.includes(hoistedNoteId)) {
return effectivePathSegments;
}
else {
const note = await treeCache.getNote(getNoteIdFromNotePath(notePath));
const someNotePathSegments = getSomeNotePathSegments(note, hoistedNoteId);
// if there isn't actually any note path with hoisted note then return the original resolved note path
return someNotePathSegments.includes(hoistedNoteId) ? someNotePathSegments : effectivePathSegments;
}
}
function getSomeNotePath(note) {
function getSomeNotePathSegments(note, hoistedNotePath = 'root') {
utils.assertArguments(note);
const path = [];
const notePaths = note.getSortedNotePaths(hoistedNotePath);
let cur = note;
return notePaths[0].notePath;
}
while (cur.noteId !== 'root') {
path.push(cur.noteId);
function getSomeNotePath(note, hoistedNotePath = 'root') {
const notePath = getSomeNotePathSegments(note, hoistedNotePath);
const parents = cur.getParentNotes().filter(note => note.type !== 'search');
if (!parents.length) {
logError(`Can't find parents for note ${cur.noteId}`);
return;
}
cur = parents[0];
}
path.push('root');
return path.reverse().join('/');
return notePath.join('/');
}
async function sortAlphabetically(noteId) {
@@ -136,7 +139,7 @@ ws.subscribeToMessages(message => {
});
function getParentProtectedStatus(node) {
return hoistedNoteService.isRootNode(node) ? 0 : node.getParent().data.isProtected;
return hoistedNoteService.isHoistedNode(node) ? 0 : node.getParent().data.isProtected;
}
function getNoteIdFromNotePath(notePath) {
@@ -196,7 +199,7 @@ function getNotePath(node) {
const path = [];
while (node && !hoistedNoteService.isRootNode(node)) {
while (node) {
if (node.data.noteId) {
path.push(node.data.noteId);
}
@@ -204,10 +207,6 @@ function getNotePath(node) {
node = node.getParent();
}
if (node) { // null node can happen directly after unhoisting when tree is still hoisted but option has been changed already
path.push(node.data.noteId); // root or hoisted noteId
}
return path.reverse().join("/");
}
@@ -311,6 +310,7 @@ export default {
resolveNotePath,
resolveNotePathToSegments,
getSomeNotePath,
getSomeNotePathSegments,
getParentProtectedStatus,
getNotePath,
getNoteIdFromNotePath,

View File

@@ -195,6 +195,8 @@ class TreeCache {
branches,
attributes: []
});
treeCache.notes[note.noteId].searchResultsLoaded = true;
}
}

View File

@@ -75,7 +75,7 @@ class TreeContextMenu {
{ title: 'Expand subtree <kbd data-command="expandSubtree"></kbd>', command: "expandSubtree", uiIcon: "expand", enabled: noSelectedNotes },
{ title: 'Collapse subtree <kbd data-command="collapseSubtree"></kbd>', command: "collapseSubtree", uiIcon: "collapse", enabled: noSelectedNotes },
{ title: "Force note sync", command: "forceNoteSync", uiIcon: "refresh", enabled: noSelectedNotes },
{ title: 'Sort alphabetically <kbd data-command="sortChildNotes"></kbd>', command: "sortChildNotes", uiIcon: "empty", enabled: noSelectedNotes && notSearch },
{ title: 'Sort by ... <kbd data-command="sortChildNotes"></kbd>', command: "sortChildNotes", uiIcon: "empty", enabled: noSelectedNotes && notSearch },
{ title: 'Recent changes in subtree', command: "recentChangesInSubtree", uiIcon: "history", enabled: noSelectedNotes }
] },
{ title: "----" },
@@ -112,10 +112,10 @@ class TreeContextMenu {
appContext.tabManager.openTabWithNoteWithHoisting(notePath);
}
else if (command === "insertNoteAfter") {
const parentNoteId = this.node.data.parentNoteId;
const parentNotePath = treeService.getNotePath(this.node.getParent());
const isProtected = await treeService.getParentProtectedStatus(this.node);
noteCreateService.createNote(parentNoteId, {
noteCreateService.createNote(parentNotePath, {
target: 'after',
targetBranchId: this.node.data.branchId,
type: type,
@@ -123,14 +123,14 @@ class TreeContextMenu {
});
}
else if (command === "insertChildNote") {
noteCreateService.createNote(noteId, {
const parentNotePath = treeService.getNotePath(this.node);
noteCreateService.createNote(parentNotePath, {
type: type,
isProtected: this.node.data.isProtected
});
}
else {
console.log("Triggering", command, notePath);
this.treeWidget.triggerCommand(command, {node: this.node, notePath: notePath});
}
}

View File

@@ -193,6 +193,10 @@ function getNoteTypeClass(type) {
}
function getMimeTypeClass(mime) {
if (!mime) {
return "";
}
const semicolonIdx = mime.indexOf(';');
if (semicolonIdx !== -1) {
@@ -296,9 +300,13 @@ function dynamicRequire(moduleName) {
}
}
function timeLimit(promise, limitMs) {
function timeLimit(promise, limitMs, errorMessage) {
if (!promise || !promise.then) { // it's not actually a promise
return promise;
}
// better stack trace if created outside of promise
const error = new Error('Process exceeded time limit ' + limitMs);
const error = new Error(errorMessage || `Process exceeded time limit ${limitMs}`);
return new Promise((res, rej) => {
let resolved = false;
@@ -334,6 +342,16 @@ function initHelpButtons($el) {
});
}
function filterAttributeName(name) {
return name.replace(/[^\p{L}\p{N}_:]/ug, "");
}
const ATTR_NAME_MATCHER = new RegExp("^[\\p{L}\\p{N}_:]+$", "u");
function isValidAttributeName(name) {
return ATTR_NAME_MATCHER.test(name);
}
export default {
reloadApp,
parseDate,
@@ -374,5 +392,7 @@ export default {
dynamicRequire,
timeLimit,
initHelpDropdown,
initHelpButtons
initHelpButtons,
filterAttributeName,
isValidAttributeName
};

View File

@@ -43,7 +43,6 @@ const processedEntityChangeIds = new Set();
function logRows(entityChanges) {
const filteredRows = entityChanges.filter(row =>
!processedEntityChangeIds.has(row.id)
&& row.entityName !== 'recent_notes'
&& (row.entityName !== 'options' || row.entityId !== 'openTabs'));
if (filteredRows.length > 0) {
@@ -103,7 +102,7 @@ function waitForEntityChangeId(desiredEntityChangeId) {
return Promise.resolve();
}
console.debug("Waiting for", desiredEntityChangeId, 'current is', lastProcessedEntityChangeId);
console.debug(`Waiting for ${desiredEntityChangeId}, last processed is ${lastProcessedEntityChangeId}, last accepted ${lastAcceptedEntityChangeId}`);
return new Promise((res, rej) => {
entityChangeIdReachedListeners.push({
@@ -127,7 +126,7 @@ function checkEntityChangeIdListeners() {
.filter(l => l.desiredEntityChangeId > lastProcessedEntityChangeId);
entityChangeIdReachedListeners.filter(l => Date.now() > l.start - 60000)
.forEach(l => console.log(`Waiting for entityChangeId ${l.desiredEntityChangeId} while current is ${lastProcessedEntityChangeId} for ${Math.floor((Date.now() - l.start) / 1000)}s`));
.forEach(l => console.log(`Waiting for entityChangeId ${l.desiredEntityChangeId} while last processed is ${lastProcessedEntityChangeId} (last accepted ${lastAcceptedEntityChangeId}) for ${Math.floor((Date.now() - l.start) / 1000)}s`));
}
async function runSafely(syncHandler, syncData) {
@@ -230,25 +229,6 @@ subscribeToMessages(message => {
});
async function processEntityChanges(entityChanges) {
const missingNoteIds = [];
for (const {entityName, entity} of entityChanges) {
if (entityName === 'branches' && !(entity.parentNoteId in treeCache.notes)) {
missingNoteIds.push(entity.parentNoteId);
}
else if (entityName === 'attributes'
&& entity.type === 'relation'
&& entity.name === 'template'
&& !(entity.noteId in treeCache.notes)) {
missingNoteIds.push(entity.value);
}
}
if (missingNoteIds.length > 0) {
await treeCache.reloadNotes(missingNoteIds);
}
const loadResults = new LoadResults(treeCache);
for (const ec of entityChanges.filter(ec => ec.entityName === 'notes')) {
@@ -391,6 +371,25 @@ async function processEntityChanges(entityChanges) {
loadResults.addOption(ec.entity.name);
}
const missingNoteIds = [];
for (const {entityName, entity} of entityChanges) {
if (entityName === 'branches' && !(entity.parentNoteId in treeCache.notes)) {
missingNoteIds.push(entity.parentNoteId);
}
else if (entityName === 'attributes'
&& entity.type === 'relation'
&& entity.name === 'template'
&& !(entity.value in treeCache.notes)) {
missingNoteIds.push(entity.value);
}
}
if (missingNoteIds.length > 0) {
await treeCache.reloadNotes(missingNoteIds);
}
if (!loadResults.isEmpty()) {
if (loadResults.hasAttributeRelatedChanges()) {
noteAttributeCache.invalidate();

View File

@@ -172,8 +172,6 @@ const ATTR_TITLES = {
"relation-definition": "Relation definition detail"
};
const ATTR_NAME_MATCHER = new RegExp("^[\\p{L}\\p{N}_:]+$", "u");
const ATTR_HELP = {
"label": {
"disableVersioning": "disables auto-versioning. Useful for e.g. large, but unimportant notes - e.g. large JS libraries used for scripting",
@@ -196,9 +194,18 @@ const ATTR_HELP = {
"appTheme": "marks CSS notes which are full Trilium themes and are thus available in Trilium options.",
"cssClass": "value of this label is then added as CSS class to the node representing given note in the tree. This can be useful for advanced theming. Can be used in template notes.",
"iconClass": "value of this label is added as a CSS class to the icon on the tree which can help visually distinguish the notes in the tree. Example might be bx bx-home - icons are taken from boxicons. Can be used in template notes.",
"bookZoomLevel": 'applies only to book note and sets the "zoom level" (how many notes fit on 1 row)',
"pageSize": "number of items per page in note listing",
"customRequestHandler": 'see <a href="javascript:" data-help-page="Custom request handler">Custom request handler</a>',
"customResourceProvider": 'see <a href="javascript:" data-help-page="Custom request handler">Custom request handler</a>'
"customResourceProvider": 'see <a href="javascript:" data-help-page="Custom request handler">Custom request handler</a>',
"widget": "marks this note as a custom widget which will be added to the Trilium component tree",
"workspace": "marks this note as a workspace which allows easy hoisting",
"workspaceIconClass": "defines box icon CSS class which will be used in tab when hoisted to this note",
"workspaceTabBackgroundColor": "CSS color used in the note tab when hoisted to this note",
"searchHome": "new search notes will be created as children of this note",
"hoistedSearchHome": "new search notes will be created as children of this note when hoisted to some ancestor of this note",
"inbox": "default inbox location for new notes",
"hoistedInbox": "default inbox location for new notes when hoisted to some ancestor of this note",
"sqlConsoleHome": "default location of SQL console notes",
},
"relation": {
"runOnNoteCreation": "executes when note is created on backend",
@@ -281,7 +288,7 @@ export default class AttributeDetailWidget extends TabAwareWidget {
this.$rowTargetNote = this.$widget.find('.attr-row-target-note');
this.$inputTargetNote = this.$widget.find('.attr-input-target-note');
noteAutocompleteService.initNoteAutocomplete(this.$inputTargetNote)
noteAutocompleteService.initNoteAutocomplete(this.$inputTargetNote, {allowCreatingNotes: true})
.on('autocomplete:noteselected', (event, suggestion, dataset) => {
if (!suggestion.notePath) {
return false;
@@ -573,9 +580,9 @@ export default class AttributeDetailWidget extends TabAwareWidget {
updateAttributeInEditor() {
let attrName = this.$inputName.val();
if (!ATTR_NAME_MATCHER.test(attrName)) {
if (!utils.isValidAttributeName(attrName)) {
// invalid characters are simply ignored (from user perspective they are not even entered)
attrName = attrName.replace(/[^\p{L}\p{N}_:]/ug, "");
attrName = utils.filterAttributeName(attrName);
this.$inputName.val(attrName);
}

View File

@@ -491,7 +491,7 @@ export default class AttributeEditorWidget extends TabAwareWidget {
}
async createNoteForReferenceLink(title) {
const {note} = await noteCreateService.createNote(this.noteId, {
const {note} = await noteCreateService.createNote(this.notePath, {
activate: false,
title: title
});

View File

@@ -122,7 +122,7 @@ export default class CollapsibleSectionContainer extends TabAwareWidget {
});
}
async refreshWithNote(note) {
async refreshWithNote(note, noExplicitActivation = false) {
let $sectionToActivate, $lastActiveSection;
this.$titleContainer.empty().append('<div class="section-title section-title-empty">');
@@ -141,7 +141,7 @@ export default class CollapsibleSectionContainer extends TabAwareWidget {
this.$titleContainer.append($sectionTitle);
this.$titleContainer.append('<div class="section-title section-title-empty">');
if (ret.activate && !$sectionToActivate) {
if (ret.activate && !$sectionToActivate && !noExplicitActivation) {
$sectionToActivate = $sectionTitle;
}
@@ -161,4 +161,8 @@ export default class CollapsibleSectionContainer extends TabAwareWidget {
this.$bodyContainer.find('.section-body').removeClass("active");
}
}
refreshSectionContainerCommand() {
this.refreshWithNote(this.note, true);
}
}

View File

@@ -12,6 +12,10 @@ const TPL = `
text-overflow: ellipsis;
}
</style>
<div class="no-edited-notes-found">No edited notes on this day yet ...</div>
<div class="edited-notes-list"></div>
</div>
`;
@@ -31,18 +35,20 @@ export default class EditedNotesWidget extends CollapsibleWidget {
async doRenderBody() {
this.$body.html(TPL);
this.$editedNotes = this.$body.find('.edited-notes-widget');
this.$list = this.$body.find('.edited-notes-list');
this.$noneFound = this.$body.find('.no-edited-notes-found');
}
async refreshWithNote(note) {
// remember which title was when we found the similar notes
this.title = note.title;
let editedNotes = await server.get('edited-notes/' + note.getLabelValue("dateNote"));
editedNotes = editedNotes.filter(n => n.noteId !== note.noteId);
this.$list.empty();
this.$noneFound.hide();
if (editedNotes.length === 0) {
this.$body.text("No edited notes on this day yet ...");
this.$noneFound.show();
return;
}
@@ -50,8 +56,6 @@ export default class EditedNotesWidget extends CollapsibleWidget {
await treeCache.getNotes(noteIds, true); // preload all at once
const $list = $('<div>'); // not using <ul> because it's difficult to style correctly with text-overflow
for (const editedNote of editedNotes) {
const $item = $('<div class="edited-note-line">');
@@ -67,9 +71,7 @@ export default class EditedNotesWidget extends CollapsibleWidget {
$item.append(editedNote.notePath ? await linkService.createNoteLink(editedNote.notePath.join("/"), {showNotePath: true}) : editedNote.title);
}
$list.append($item);
this.$list.append($item);
}
this.$editedNotes.empty().append($list);
}
}

View File

@@ -91,7 +91,13 @@ export default class Component {
console.log(`Call to ${fun.name} in ${this.componentId} took ${took}ms`);
}
if (glob.isDev) {
await utils.timeLimit(promise, 20000, `Time limit failed on ${this.constructor.name} with ${fun.name}`);
}
else {
// cheaper and in non-dev the extra reporting is lost anyway through reload
await promise;
}
return true;
}

View File

@@ -26,7 +26,7 @@ class MobileDetailMenuWidget extends BasicWidget {
],
selectMenuItemHandler: async ({command}) => {
if (command === "insertChildNote") {
noteCreateService.createNote(note.noteId);
noteCreateService.createNote(appContext.tabManager.getActiveTabNotePath());
}
else if (command === "delete") {
const notePath = appContext.tabManager.getActiveTabNotePath();

View File

@@ -13,7 +13,7 @@ const WIDGET_TPL = `
}
</style>
<a data-trigger-command="createTopLevelNote" title="Create new top level note" class="icon-action bx bx-folder-plus"></a>
<a data-trigger-command="createNoteIntoInbox" title="New note" class="icon-action bx bx-folder-plus"></a>
<a data-trigger-command="collapseTree" title="Collapse note tree" class="icon-action bx bx-layer-minus"></a>

View File

@@ -65,6 +65,8 @@ export default class NoteDetailWidget extends TabAwareWidget {
await server.put('notes/' + noteId, dto, this.componentId);
});
appContext.addBeforeUnloadListener(this);
}
isEnabled() {
@@ -276,7 +278,7 @@ export default class NoteDetailWidget extends TabAwareWidget {
const label = attrs.find(attr =>
attr.type === 'label'
&& ['readOnly', 'autoReadOnlyDisabled', 'cssClass', 'bookZoomLevel'].includes(attr.name)
&& ['readOnly', 'autoReadOnlyDisabled', 'cssClass', 'displayRelations'].includes(attr.name)
&& attr.isAffecting(this.note));
const relation = attrs.find(attr =>
@@ -293,7 +295,7 @@ export default class NoteDetailWidget extends TabAwareWidget {
}
beforeUnloadEvent() {
this.spacedUpdate.updateNowIfNecessary();
return this.spacedUpdate.isAllSavedAndTriggerUpdate();
}
textPreviewDisabledEvent({tabContext}) {
@@ -316,7 +318,7 @@ export default class NoteDetailWidget extends TabAwareWidget {
}
// without await as this otherwise causes deadlock through component mutex
noteCreateService.createNote(note.noteId, {
noteCreateService.createNote(appContext.tabManager.getActiveTabNotePath(), {
isProtected: note.isProtected,
saveSelection: true
});

View File

@@ -1,5 +1,4 @@
import TabAwareWidget from "./tab_aware_widget.js";
import server from "../services/server.js";
import attributeService from "../services/attributes.js";
const TPL = `
@@ -11,14 +10,16 @@ const TPL = `
margin-right: 0;
}
.note-icon-container button {
.note-icon-container button.note-icon {
font-size: 180%;
background: transparent;
border: 1px solid transparent;
cursor: pointer;
padding: 6px;
color: var(--main-text-color);
}
.note-icon-container button:hover {
.note-icon-container button.note-icon:hover {
border: 1px solid var(--main-border-color);
}
@@ -47,7 +48,6 @@ const TPL = `
.note-icon-container .icon-list {
height: 500px;
overflow: auto;
font-size: 180%;
}
.note-icon-container .icon-list span {
@@ -55,6 +55,7 @@ const TPL = `
padding: 10px;
cursor: pointer;
border: 1px solid transparent;
font-size: 180%;
}
.note-icon-container .icon-list span:hover {
@@ -62,7 +63,7 @@ const TPL = `
}
</style>
<button class="btn dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="Change note icon"></button>
<button class="btn dropdown-toggle note-icon" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="Change note icon"></button>
<div class="dropdown-menu" aria-labelledby="note-path-list-button" style="width: 610px;">
<div class="filter-row">
<span>Category:</span> <select name="icon-category" class="form-control"></select>
@@ -74,14 +75,11 @@ const TPL = `
</div>
</div>`;
let icons = [];
let categories = [];
export default class NoteIconWidget extends TabAwareWidget {
doRender() {
this.$widget = $(TPL);
this.overflowing();
this.$icon = this.$widget.find('button');
this.$icon = this.$widget.find('button.note-icon');
this.$iconList = this.$widget.find('.icon-list');
this.$iconList.on('click', 'span', async e => {
const clazz = $(e.target).attr('class');
@@ -120,7 +118,7 @@ export default class NoteIconWidget extends TabAwareWidget {
}
async refreshWithNote(note) {
this.$icon.removeClass().addClass(note.getIcon());
this.$icon.removeClass().addClass(note.getIcon() + " note-icon");
}
async entitiesReloadedEvent({loadResults}) {
@@ -145,6 +143,18 @@ export default class NoteIconWidget extends TabAwareWidget {
async renderDropdown(categoryId, search) {
this.$iconList.empty();
if (this.getIconLabels().length > 0) {
this.$iconList.append(
$(`<div style="text-align: center">`)
.append(
$('<button class="btn btn-sm">Reset to default icon</button>')
.on('click', () => this.getIconLabels()
.forEach(label => attributeService.removeAttributeById(this.noteId, label.attributeId))
)
)
);
}
const {icons} = (await import('./icon_list.js')).default;
for (const icon of icons) {
@@ -164,6 +174,11 @@ export default class NoteIconWidget extends TabAwareWidget {
}
}
getIconLabels() {
return this.note.getOwnedLabels()
.filter(label => ['workspaceIconClass', 'iconClass'].includes(label.name));
}
getIconClass(icon) {
if (icon.type_of_icon === 'LOGO') {
return "bx bxl-" + icon.name;

View File

@@ -23,11 +23,9 @@ const TPL = `
export default class NoteListWidget extends TabAwareWidget {
isEnabled() {
return super.isEnabled()
&& ['book', 'text', 'code'].includes(this.note.type)
&& this.note.mime !== 'text/x-sqlite;schema=trilium'
&& (
['book', 'search', 'code'].includes(this.note.type)
|| (this.note.type === 'text' && this.note.hasChildren())
)
&& this.note.hasChildren()
&& !this.note.hasLabel('hideChildrenOverview');
}
@@ -89,17 +87,6 @@ export default class NoteListWidget extends TabAwareWidget {
setTimeout(() => this.checkRenderStatus(), 100);
}
searchRefreshedEvent({tabId}) {
if (!this.isTab(tabId)) {
return;
}
this.noteIdRefreshed = this.noteId;
this.shownNoteId = null;
this.checkRenderStatus();
}
notesReloadedEvent({noteIds}) {
if (noteIds.includes(this.noteId)) {
this.refresh();

View File

@@ -15,9 +15,21 @@ const TPL = `
}
.note-path-list {
max-height: 600px;
max-height: 700px;
overflow-y: auto;
}
.note-path-list .path-current {
font-weight: bold;
}
.note-path-list .path-archived {
color: var(--muted-text-color) !important;
}
.note-path-list .path-search {
font-style: italic;
}
</style>
<button class="btn dropdown-toggle note-path-list-button bx bx-collection" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="Note paths"></button>
@@ -43,20 +55,12 @@ export default class NotePathsWidget extends TabAwareWidget {
);
if (this.noteId === 'root') {
await this.addPath('root', true);
await this.addPath('root');
return;
}
const pathSegments = treeService.parseNotePath(this.notePath);
const activeNoteParentNoteId = pathSegments[pathSegments.length - 2]; // we know this is not root so there must be a parent
for (const parentNote of this.note.getParentNotes()) {
const parentNotePath = treeService.getSomeNotePath(parentNote);
// this is to avoid having root notes leading '/'
const notePath = parentNotePath ? (parentNotePath + '/' + this.noteId) : this.noteId;
const isCurrent = activeNoteParentNoteId === parentNote.noteId;
await this.addPath(notePath, isCurrent);
for (const notePathRecord of this.note.getSortedNotePaths(this.hoistedNoteId)) {
await this.addPath(notePathRecord);
}
const cloneLink = $("<div>")
@@ -70,7 +74,9 @@ export default class NotePathsWidget extends TabAwareWidget {
this.$notePathList.append(cloneLink);
}
async addPath(notePath, isCurrent) {
async addPath(notePathRecord) {
const notePath = notePathRecord.notePath.join('/');
const title = await treeService.getNotePathTitle(notePath);
const $noteLink = await linkService.createNoteLink(notePath, {title});
@@ -82,8 +88,33 @@ export default class NotePathsWidget extends TabAwareWidget {
.find('a')
.addClass("no-tooltip-preview");
if (isCurrent) {
$noteLink.addClass("current");
const icons = [];
if (this.notePath === notePath) {
$noteLink.addClass("path-current");
}
if (notePathRecord.isInHoistedSubTree) {
$noteLink.addClass("path-in-hoisted-subtree");
}
else {
icons.push(`<span class="bx bx-trending-up" title="This path is outside of hoisted note and you would have to unhoist."></span>`);
}
if (notePathRecord.isArchived) {
$noteLink.addClass("path-archived");
icons.push(`<span class="bx bx-archive" title="Archived"></span>`);
}
if (notePathRecord.isSearch) {
$noteLink.addClass("path-search");
icons.push(`<span class="bx bx-search" title="Search"></span>`);
}
if (icons.length > 0) {
$noteLink.append(` ${icons.join(' ')}`);
}
this.$notePathList.append($noteLink);
@@ -96,4 +127,10 @@ export default class NotePathsWidget extends TabAwareWidget {
this.refresh();
}
}
async refresh() {
await super.refresh();
this.$widget.find('.dropdown-toggle').dropdown('hide');
}
}

View File

@@ -3,6 +3,7 @@ import utils from "../services/utils.js";
import protectedSessionHolder from "../services/protected_session_holder.js";
import server from "../services/server.js";
import SpacedUpdate from "../services/spaced_update.js";
import appContext from "../services/app_context.js";
const TPL = `
<div class="note-title-container">
@@ -37,6 +38,8 @@ export default class NoteTitleWidget extends TabAwareWidget {
await server.put(`notes/${this.noteId}/change-title`, {title});
});
appContext.addBeforeUnloadListener(this);
}
doRender() {
@@ -101,6 +104,6 @@ export default class NoteTitleWidget extends TabAwareWidget {
}
beforeUnloadEvent() {
this.spacedUpdate.updateNowIfNecessary();
return this.spacedUpdate.isAllSavedAndTriggerUpdate();
}
}

View File

@@ -203,8 +203,9 @@ export default class NoteTreeWidget extends TabAwareWidget {
this.$tree.on("mousedown", ".refresh-search-button", e => this.refreshSearch(e));
this.$tree.on("mousedown", ".add-note-button", e => {
const node = $.ui.fancytree.getNode(e);
const parentNotePath = treeService.getNotePath(node);
noteCreateService.createNote(node.data.noteId, {
noteCreateService.createNote(parentNotePath, {
isProtected: node.data.isProtected
});
});
@@ -392,12 +393,6 @@ export default class NoteTreeWidget extends TabAwareWidget {
autoExpandMS: 600,
preventLazyParents: false,
dragStart: (node, data) => {
// don't allow dragging root node
if (node.data.noteId === hoistedNoteService.getHoistedNoteId()
|| node.getParent().data.noteType === 'search') {
return false;
}
const notes = this.getSelectedOrActiveNodes(node).map(node => ({
noteId: node.data.noteId,
branchId: node.data.branchId,
@@ -482,7 +477,7 @@ export default class NoteTreeWidget extends TabAwareWidget {
let childNoteIds = note.getChildNoteIds();
if (childNoteIds.length > MAX_SEARCH_RESULTS_IN_TREE) {
if (note.type === 'search' && childNoteIds.length > MAX_SEARCH_RESULTS_IN_TREE) {
childNoteIds = childNoteIds.slice(0, MAX_SEARCH_RESULTS_IN_TREE);
}
@@ -600,7 +595,7 @@ export default class NoteTreeWidget extends TabAwareWidget {
let childBranches = parentNote.getFilteredChildBranches();
if (childBranches.length > MAX_SEARCH_RESULTS_IN_TREE) {
if (parentNote.type === 'search' && childBranches.length > MAX_SEARCH_RESULTS_IN_TREE) {
childBranches = childBranches.slice(0, MAX_SEARCH_RESULTS_IN_TREE);
}
@@ -624,6 +619,17 @@ export default class NoteTreeWidget extends TabAwareWidget {
updateNode(node) {
const note = treeCache.getNoteFromCache(node.data.noteId);
const branch = treeCache.getBranch(node.data.branchId);
if (!note) {
console.log(`Node update not possible because note ${node.data.noteId} was not found.`);
return;
}
if (!branch) {
console.log(`Node update not possible because branch ${node.data.branchId} was not found.`);
return;
}
const title = (branch.prefix ? (branch.prefix + " - ") : "") + note.title;
node.data.isProtected = note.isProtected;
@@ -759,7 +765,7 @@ export default class NoteTreeWidget extends TabAwareWidget {
await this.setExpandedStatusForSubtree(node, false);
}
collapseTreeCommand() { this.collapseTree(); }
collapseTreeEvent() { this.collapseTree(); }
/**
* @return {FancytreeNode|null}
@@ -783,7 +789,7 @@ export default class NoteTreeWidget extends TabAwareWidget {
}
}
async scrollToActiveNoteCommand() {
async scrollToActiveNoteEvent() {
const activeContext = appContext.tabManager.getActiveTabContext();
if (activeContext && activeContext.notePath) {
@@ -792,19 +798,17 @@ export default class NoteTreeWidget extends TabAwareWidget {
const node = await this.expandToNote(activeContext.notePath);
await node.makeVisible({scrollIntoView: true});
node.setFocus(true);
node.setActive(true, {noEvents: true, noFocus: false});
}
}
/** @return {FancytreeNode} */
async getNodeFromPath(notePath, expand = false, logErrors = true) {
utils.assertArguments(notePath);
/** @let {FancytreeNode} */
let parentNode = this.getNodesByNoteId('root')[0];
const hoistedNoteId = hoistedNoteService.getHoistedNoteId();
/** @const {FancytreeNode} */
let parentNode = null;
const resolvedNotePathSegments = await treeService.resolveNotePathToSegments(notePath, logErrors);
let resolvedNotePathSegments = await treeService.resolveNotePathToSegments(notePath, this.hoistedNoteId, logErrors);
if (!resolvedNotePathSegments) {
if (logErrors) {
@@ -814,14 +818,9 @@ export default class NoteTreeWidget extends TabAwareWidget {
return;
}
resolvedNotePathSegments = resolvedNotePathSegments.slice(1);
for (const childNoteId of resolvedNotePathSegments) {
if (childNoteId === hoistedNoteId) {
// there must be exactly one node with given hoistedNoteId
parentNode = this.getNodesByNoteId(childNoteId)[0];
continue;
}
// we expand only after hoisted note since before then nodes are not actually present in the tree
if (parentNode) {
if (!parentNode.isLoaded()) {
@@ -852,7 +851,7 @@ export default class NoteTreeWidget extends TabAwareWidget {
// these are real notes with real notePath, user can display them in a detail
// but they don't have a node in the tree
ws.logError(`Can't find node for child node of noteId=${childNoteId} for parent of noteId=${parentNode.data.noteId} and hoistedNoteId=${hoistedNoteId}, requested path is ${notePath}`);
ws.logError(`Can't find node for child node of noteId=${childNoteId} for parent of noteId=${parentNode.data.noteId} and hoistedNoteId=${hoistedNoteService.getHoistedNoteId()}, requested path is ${notePath}`);
}
return;
@@ -994,6 +993,7 @@ export default class NoteTreeWidget extends TabAwareWidget {
const activeNodeFocused = activeNode && activeNode.hasFocus();
const nextNode = activeNode ? (activeNode.getNextSibling() || activeNode.getPrevSibling() || activeNode.getParent()) : null;
const activeNotePath = activeNode ? treeService.getNotePath(activeNode) : null;
const nextNotePath = nextNode ? treeService.getNotePath(nextNode) : null;
const activeNoteId = activeNode ? activeNode.data.noteId : null;
@@ -1025,6 +1025,9 @@ export default class NoteTreeWidget extends TabAwareWidget {
}
for (const branch of loadResults.getBranches()) {
// adding noteId itself to update all potential clones
noteIdsToUpdate.add(branch.noteId);
for (const node of this.getNodesByBranchId(branch.branchId)) {
if (branch.isDeleted) {
if (node.isActive()) {
@@ -1043,9 +1046,6 @@ export default class NoteTreeWidget extends TabAwareWidget {
noteIdsToUpdate.add(branch.parentNoteId);
}
else {
noteIdsToUpdate.add(branch.noteId);
}
}
if (!branch.isDeleted) {
@@ -1114,22 +1114,31 @@ export default class NoteTreeWidget extends TabAwareWidget {
}
if (node) {
node.setActive(true, {noEvents: true, noFocus: true});
node.setActive(true, {noEvents: true, noFocus: !activeNodeFocused});
if (activeNodeFocused) {
node.setFocus(true);
}
}
else {
// this is used when original note has been deleted and we want to move the focus to the note above/below
node = await this.expandToNote(nextNotePath, false);
if (node) {
await appContext.tabManager.getActiveTabContext().setNote(nextNotePath);
}
}
// FIXME: this is conceptually wrong
// here note tree is responsible for updating global state of the application
// this should be done by tabcontext / tabmanager and note tree should only listen to
// changes in active note and just set the "active" state
// We don't await since that can bring up infinite cycles when e.g. custom widget does some backend requests which wait for max sync ID processed
appContext.tabManager.getActiveTabContext().setNote(nextNotePath).then(() => {
const newActiveNode = this.getActiveNode();
// return focus if the previously active node was also focused
if (newActiveNode && activeNodeFocused) {
await newActiveNode.setFocus(true);
if (newActiveNode && activeNodeFocused) {console.log("FOCUSING!!!");
newActiveNode.setFocus(true);
}
});
}
}
}
@@ -1197,13 +1206,20 @@ export default class NoteTreeWidget extends TabAwareWidget {
}
}
filterHoistedBranch() {
async filterHoistedBranch() {
if (this.tabContext) {
// make sure the hoisted node is loaded (can be unloaded e.g. after tree collapse in another tab)
const hoistedNotePath = await treeService.resolveNotePath(this.tabContext.hoistedNoteId);
await this.getNodeFromPath(hoistedNotePath);
if (this.tabContext.hoistedNoteId === 'root') {
this.tree.clearFilter();
}
else {
this.tree.filterBranches(node => node.data.noteId === this.tabContext.hoistedNoteId);
// hack when hoisted note is cloned then it could be filtered multiple times while we want only 1
this.tree.filterBranches(node =>
node.data.noteId === this.tabContext.hoistedNoteId // optimization to not having always resolve the node path
&& treeService.getNotePath(node) === hoistedNotePath);
}
}
}
@@ -1241,7 +1257,12 @@ export default class NoteTreeWidget extends TabAwareWidget {
}
async deleteNotesCommand({node}) {
const branchIds = this.getSelectedOrActiveBranchIds(node);
const branchIds = this.getSelectedOrActiveBranchIds(node)
.filter(branchId => !branchId.startsWith('virt-')); // search results can't be deleted
if (!branchIds.length) {
return;
}
await branchService.deleteNotes(branchIds);
@@ -1355,7 +1376,7 @@ export default class NoteTreeWidget extends TabAwareWidget {
}
sortChildNotesCommand({node}) {
treeService.sortAlphabetically(node.data.noteId);
import("../dialogs/sort_child_notes.js").then(d => d.showDialog(node.data.noteId));
}
async recentChangesInSubtreeCommand({node}) {

View File

@@ -49,7 +49,11 @@ export default class QuickSearchWidget extends BasicWidget {
this.$widget.find('.input-group-append').on('shown.bs.dropdown', () => this.search());
utils.bindElShortcut(this.$searchString, 'return', () => {
if (this.$dropdownMenu.is(":visible")) {
this.search(); // just update already visible dropdown
} else {
this.$dropdownToggle.dropdown('show');
}
this.$searchString.focus();
});
@@ -90,12 +94,18 @@ export default class QuickSearchWidget extends BasicWidget {
const $link = await linkService.createNoteLink(note.noteId, {showNotePath: true});
$link.addClass('dropdown-item');
$link.attr("tabIndex", "0");
$link.on('click', () => this.$dropdownToggle.dropdown("hide"));
utils.bindElShortcut($link, 'return', () => {
$link.find('a').trigger({
type: 'click',
which: 1 // left click
$link.on('click', e => {
this.$dropdownToggle.dropdown("hide");
if (!e.target || e.target.nodeName !== 'A') {
// click on the link is handled by link handling but we want the whole item clickable
appContext.tabManager.getActiveTabContext().setNote(note.noteId);
}
});
utils.bindElShortcut($link, 'return', () => {
this.$dropdownToggle.dropdown("hide");
appContext.tabManager.getActiveTabContext().setNote(note.noteId);
});
this.$dropdownMenu.append($link);
@@ -110,17 +120,21 @@ export default class QuickSearchWidget extends BasicWidget {
this.$dropdownMenu.append($showInFullButton);
utils.bindElShortcut($showInFullButton, 'return', async () => {
const searchNote = await dateNotesService.createSearchNote({searchString: this.$searchString.val()});
$showInFullButton.on('click', () => this.showInFullSearch());
await appContext.tabManager.getActiveTabContext().setNote(searchNote.noteId);
});
utils.bindElShortcut($showInFullButton, 'return', () => this.showInFullSearch());
utils.bindElShortcut(this.$dropdownMenu.find('.dropdown-item:first'), 'up', () => this.$searchString.focus());
this.$dropdownToggle.dropdown('update');
}
async showInFullSearch() {
const searchNote = await dateNotesService.createSearchNote({searchString: this.$searchString.val()});
await appContext.tabManager.getActiveTabContext().setNote(searchNote.noteId);
}
quickSearchEvent() {
this.$searchString.focus();
}

View File

@@ -0,0 +1,35 @@
import AbstractSearchOption from "./abstract_search_option.js";
const TPL = `
<tr data-search-option-conf="debug">
<td colSpan="2">
<span class="bx bx-bug"></span>
Debug
</td>
<td class="button-column">
<div class="dropdown help-dropdown">
<span class="bx bx-help-circle icon-action" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></span>
<div class="dropdown-menu dropdown-menu-right p-4">
<p>Debug will print extra debugging information into the console to aid in debugging complex queries.</p>
<p>To access the debug information, execute query and click on "Show backend log" in top left corner.</p>
</div>
</div>
<span class="bx bx-x icon-action search-option-del"></span>
</td>
</tr>`;
export default class Debug extends AbstractSearchOption {
static get optionName() { return "debug" };
static get attributeType() { return "label" };
static async create(noteId) {
await AbstractSearchOption.setAttribute(noteId,'label', 'debug');
}
doRender() {
return $(TPL);
}
}

View File

@@ -16,6 +16,11 @@ const TPL = `
<option value="contentSize">Note content size</option>
<option value="noteSize">Note content size including revisions</option>
<option value="revisionCount">Number of revisions</option>
<option value="childrenCount">Number of children notes</option>
<option value="parentCount">Number of clones</option>
<option value="ownedLabelCount">Number of labels</option>
<option value="ownedRelationCount">Number of relations</option>
<option value="targetRelationCount">Number of relations targeting the note</option>
</select>
<select name="orderDirection" class="form-control w-auto d-inline">

View File

@@ -50,7 +50,7 @@ export default class SearchScript extends AbstractSearchOption {
doRender() {
const $option = $(TPL);
const $searchScript = $option.find('.search-script');
noteAutocompleteService.initNoteAutocomplete($searchScript);
noteAutocompleteService.initNoteAutocomplete($searchScript, {allowCreatingNotes: true});
$searchScript.on('autocomplete:closed', async () => {
const searchScriptNoteId = $searchScript.getSelectedNoteId();

View File

@@ -0,0 +1,72 @@
import TabAwareWidget from "./tab_aware_widget.js";
import NoteListRenderer from "../services/note_list_renderer.js";
const TPL = `
<div class="search-result-widget">
<style>
.search-result-widget {
flex-grow: 100000;
flex-shrink: 100000;
min-height: 0;
overflow: auto;
}
.search-result-widget .note-list {
padding: 10px;
}
.search-no-results, .search-not-executed-yet {
margin: 20px;
padding: 20px;
}
</style>
<div class="search-no-results alert alert-info">
No notes have been found for given search parameters.
</div>
<div class="search-not-executed-yet alert alert-info">
Search has not been executed yet. Click on "Search" button above to see the results.
</div>
<div class="search-result-widget-content">
</div>
</div>`;
export default class SearchResultWidget extends TabAwareWidget {
isEnabled() {
return super.isEnabled()
&& this.note.type === 'search';
}
doRender() {
this.$widget = $(TPL);
this.$content = this.$widget.find('.search-result-widget-content');
this.$noResults = this.$widget.find('.search-no-results');
this.$notExecutedYet = this.$widget.find('.search-not-executed-yet');
this.contentSized();
}
async refreshWithNote(note) {
this.$content.empty();
this.$noResults.toggle(note.getChildNoteIds().length === 0 && !!note.searchResultsLoaded);
this.$notExecutedYet.toggle(!note.searchResultsLoaded);
const noteListRenderer = new NoteListRenderer(this.$content, note, note.getChildNoteIds(), true);
await noteListRenderer.renderList();
}
searchRefreshedEvent({tabId}) {
if (!this.isTab(tabId)) {
return;
}
this.refresh();
}
notesReloadedEvent({noteIds}) {
if (noteIds.includes(this.noteId)) {
this.refresh();
}
}
}

View File

@@ -22,6 +22,10 @@ export default class TabAwareWidget extends BasicWidget {
return this.tabContext && this.tabContext.notePath;
}
get hoistedNoteId() {
return this.tabContext && this.tabContext.hoistedNoteId;
}
isEnabled() {
return !!this.note;
}

View File

@@ -83,4 +83,10 @@ export default class InheritedAttributesWidget extends TabAwareWidget {
getInheritedAttributes(note) {
return note.getAttributes().filter(attr => attr.noteId !== this.noteId);
}
entitiesReloadedEvent({loadResults}) {
if (loadResults.getAttributes(this.componentId).find(attr => attr.isAffecting(this.note))) {
this.refresh();
}
}
}

View File

@@ -210,7 +210,7 @@ export default class PromotedAttributesWidget extends TabAwareWidget {
}
// no need to wait for this
noteAutocompleteService.initNoteAutocomplete($input);
noteAutocompleteService.initNoteAutocomplete($input, {allowCreatingNotes: true});
$input.on('autocomplete:noteselected', (event, suggestion, dataset) => {
this.promotedAttributeChanged(event);
@@ -293,6 +293,7 @@ export default class PromotedAttributesWidget extends TabAwareWidget {
this.refresh();
this.renderTitle(this.note);
this.triggerCommand('refreshSectionContainer');
}
}
}

View File

@@ -20,6 +20,7 @@ import OrderBy from "../search_options/order_by.js";
import SearchScript from "../search_options/search_script.js";
import Limit from "../search_options/limit.js";
import DeleteNoteRevisionsSearchAction from "../search_actions/delete_note_revisions.js";
import Debug from "../search_options/debug.js";
const TPL = `
<div class="search-definition-widget">
@@ -113,6 +114,11 @@ const TPL = `
limit
</button>
<button type="button" class="btn btn-sm" data-search-option-add="debug" title="Debug will print extra debugging information into the console to aid in debugging complex queries">
<span class="bx bx-bug"></span>
debug
</button>
<div class="dropdown" style="display: inline-block;">
<button class="btn btn-sm dropdown-toggle action-add-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="bx bxs-zap"></span>
@@ -173,7 +179,8 @@ const OPTION_CLASSES = [
FastSearch,
IncludeArchivedNotes,
OrderBy,
Limit
Limit,
Debug
];
const ACTION_CLASSES = {};

View File

@@ -49,15 +49,16 @@ const TPL = `
}
.note-detail-editable-text h2 { font-size: 1.8em; }
.note-detail-editable-text h2::before { content: "##\\2004"; color: var(--muted-text-color); }
.note-detail-editable-text h3 { font-size: 1.6em; }
.note-detail-editable-text h3::before { content: "###\\2004"; color: var(--muted-text-color); }
.note-detail-editable-text h4 { font-size: 1.4em; }
.note-detail-editable-text h4:not(.include-note-title)::before { content: "####\\2004"; color: var(--muted-text-color); }
.note-detail-editable-text h5 { font-size: 1.2em; }
.note-detail-editable-text h5::before { content: "#####\\2004"; color: var(--muted-text-color); }
.note-detail-editable-text h6 { font-size: 1.1em; }
.note-detail-editable-text h6::before { content: "######\\2004"; color: var(--muted-text-color); }
body.heading-style-markdown .note-detail-editable-text h2::before { content: "##\\2004"; color: var(--muted-text-color); }
body.heading-style-markdown .note-detail-editable-text h3::before { content: "###\\2004"; color: var(--muted-text-color); }
body.heading-style-markdown .note-detail-editable-text h4:not(.include-note-title)::before { content: "####\\2004"; color: var(--muted-text-color); }
body.heading-style-markdown .note-detail-editable-text h5::before { content: "#####\\2004"; color: var(--muted-text-color); }
body.heading-style-markdown .note-detail-editable-text h6::before { content: "######\\2004"; color: var(--muted-text-color); }
.note-detail-editable-text-editor {
padding-top: 10px;
@@ -274,7 +275,7 @@ export default class EditableTextTypeWidget extends AbstractTextTypeWidget {
}
async createNoteForReferenceLink(title) {
const {note} = await noteCreateService.createNote(this.noteId, {
const {note} = await noteCreateService.createNote(this.notePath, {
activate: false,
title: title
});

View File

@@ -22,7 +22,10 @@ export default class EmptyTypeWidget extends TypeWidget {
this.contentSized();
this.$autoComplete = this.$widget.find(".note-autocomplete");
noteAutocompleteService.initNoteAutocomplete(this.$autoComplete, { hideGoToSelectedNoteButton: true })
noteAutocompleteService.initNoteAutocomplete(this.$autoComplete, {
hideGoToSelectedNoteButton: true,
allowCreatingNotes: true
})
.on('autocomplete:noteselected', function(event, suggestion, dataset) {
if (!suggestion.notePath) {
return false;

View File

@@ -14,16 +14,11 @@ const TPL = `
.note-detail-readonly-text h5 { font-size: 1.2em; }
.note-detail-readonly-text h6 { font-size: 1.1em; }
.note-detail-readonly-text h2 { font-size: 1.8em; }
.note-detail-readonly-text h2::before { content: "##\\2004"; color: var(--muted-text-color); }
.note-detail-readonly-text h3 { font-size: 1.6em; }
.note-detail-readonly-text h3::before { content: "###\\2004"; color: var(--muted-text-color); }
.note-detail-readonly-text h4 { font-size: 1.4em; }
.note-detail-readonly-text h4:not(.include-note-title)::before { content: "####\\2004"; color: var(--muted-text-color); }
.note-detail-readonly-text h5 { font-size: 1.2em; }
.note-detail-readonly-text h5::before { content: "#####\\2004"; color: var(--muted-text-color); }
.note-detail-readonly-text h6 { font-size: 1.1em; }
.note-detail-readonly-text h6::before { content: "######\\2004"; color: var(--muted-text-color); }
body.heading-style-markdown .note-detail-readonly-text h2::before { content: "##\\2004"; color: var(--muted-text-color); }
body.heading-style-markdown .note-detail-readonly-text h3::before { content: "###\\2004"; color: var(--muted-text-color); }
body.heading-style-markdown .note-detail-readonly-text h4:not(.include-note-title)::before { content: "####\\2004"; color: var(--muted-text-color); }
body.heading-style-markdown .note-detail-readonly-text h5::before { content: "#####\\2004"; color: var(--muted-text-color); }
body.heading-style-markdown .note-detail-readonly-text h6::before { content: "######\\2004"; color: var(--muted-text-color); }
.note-detail-readonly-text {
padding-left: 22px;

View File

@@ -7,6 +7,7 @@ import attributeAutocompleteService from "../../services/attribute_autocomplete.
import TypeWidget from "./type_widget.js";
import appContext from "../../services/app_context.js";
import utils from "../../services/utils.js";
import treeCache from "../../services/tree_cache.js";
const uniDirectionalOverlays = [
[ "Arrow", {
@@ -285,7 +286,7 @@ export default class RelationMapTypeWidget extends TypeWidget {
async loadNotesAndRelations() {
const noteIds = this.mapData.notes.map(note => note.noteId);
const data = await server.post("notes/relation-map", {noteIds});
const data = await server.post("notes/relation-map", {noteIds, relationMapNoteId: this.noteId});
this.relations = [];
@@ -471,14 +472,22 @@ export default class RelationMapTypeWidget extends TypeWidget {
}
const promptDialog = await import("../../dialogs/prompt.js");
const name = await promptDialog.ask({
message: "Specify new relation name:",
shown: ({ $answer }) =>
let name = await promptDialog.ask({
message: "Specify new relation name (allowed characters: alphanumeric, colon and underscore):",
shown: ({ $answer }) => {
$answer.on('keyup', () => {
// invalid characters are simply ignored (from user perspective they are not even entered)
const attrName = utils.filterAttributeName($answer.val());
$answer.val(attrName);
});
attributeAutocompleteService.initAttributeNameAutocomplete({
$el: $answer,
attributeType: "relation",
open: true
})
});
}
});
if (!name || !name.trim()) {
@@ -487,6 +496,8 @@ export default class RelationMapTypeWidget extends TypeWidget {
return;
}
name = utils.filterAttributeName(name);
const targetNoteId = this.idToNoteId(connection.target.id);
const sourceNoteId = this.idToNoteId(connection.source.id);
@@ -521,8 +532,11 @@ export default class RelationMapTypeWidget extends TypeWidget {
linkService.goToLink(e);
});
const note = await treeCache.getNote(noteId);
const $noteBox = $("<div>")
.addClass("note-box")
.addClass(note.getCssClass())
.prop("id", this.noteIdToId(noteId))
.append($("<span>").addClass("title").append($link))
.append($("<div>").addClass("endpoint").attr("title", "Start dragging relations from here and drop them on another note."))

View File

@@ -5,7 +5,7 @@
.note-detail-relation-map {
height: 100%;
overflow: hidden !important;
padding-top: 10px;
padding: 10px;
position: relative;
}

View File

@@ -54,9 +54,17 @@ function moveBranchBeforeNote(req) {
const {branchId, beforeBranchId} = req.params;
const branchToMove = repository.getBranch(branchId);
const beforeNote = repository.getBranch(beforeBranchId);
const beforeBranch = repository.getBranch(beforeBranchId);
const validationResult = treeService.validateParentChild(beforeNote.parentNoteId, branchToMove.noteId, branchId);
if (!branchToMove) {
return [404, `Can't find branch ${branchId}`];
}
if (!beforeBranch) {
return [404, `Can't find branch ${beforeBranchId}`];
}
const validationResult = treeService.validateParentChild(beforeBranch.parentNoteId, branchToMove.noteId, branchId);
if (!validationResult.success) {
return [200, validationResult];
@@ -65,16 +73,16 @@ function moveBranchBeforeNote(req) {
// we don't change utcDateModified so other changes are prioritized in case of conflict
// also we would have to sync all those modified branches otherwise hash checks would fail
sql.execute("UPDATE branches SET notePosition = notePosition + 10 WHERE parentNoteId = ? AND notePosition >= ? AND isDeleted = 0",
[beforeNote.parentNoteId, beforeNote.notePosition]);
[beforeBranch.parentNoteId, beforeBranch.notePosition]);
entityChangesService.addNoteReorderingEntityChange(beforeNote.parentNoteId);
entityChangesService.addNoteReorderingEntityChange(beforeBranch.parentNoteId);
if (branchToMove.parentNoteId === beforeNote.parentNoteId) {
branchToMove.notePosition = beforeNote.notePosition;
if (branchToMove.parentNoteId === beforeBranch.parentNoteId) {
branchToMove.notePosition = beforeBranch.notePosition;
branchToMove.save();
}
else {
const newBranch = branchToMove.createClone(beforeNote.parentNoteId, beforeNote.notePosition);
const newBranch = branchToMove.createClone(beforeBranch.parentNoteId, beforeBranch.notePosition);
newBranch.save();
branchToMove.isDeleted = true;

View File

@@ -106,7 +106,7 @@ function processContent(images, note, content) {
for (const {src, dataUrl, imageId} of images) {
const filename = path.basename(src);
if (!dataUrl.startsWith("data:image")) {
if (!dataUrl || !dataUrl.startsWith("data:image")) {
log.info("Image could not be recognized as data URL:", dataUrl.substr(0, Math.min(100, dataUrl.length)));
continue;
}

View File

@@ -5,10 +5,31 @@ const sql = require('../../services/sql');
const dateUtils = require('../../services/date_utils');
const noteService = require('../../services/notes');
const attributeService = require('../../services/attributes');
const cls = require('../../services/cls');
const repository = require('../../services/repository');
function getInboxNote(req) {
return attributeService.getNoteWithLabel('inbox')
const hoistedNote = getHoistedNote();
let inbox;
if (hoistedNote) {
([inbox] = hoistedNote.getDescendantNotesWithLabel('hoistedInbox'));
if (!inbox) {
([inbox] = hoistedNote.getDescendantNotesWithLabel('inbox'));
}
if (!inbox) {
inbox = hoistedNote;
}
}
else {
inbox = attributeService.getNoteWithLabel('inbox')
|| dateNoteService.getDateNote(req.params.date);
}
return inbox;
}
function getDateNote(req) {
@@ -59,24 +80,60 @@ function createSqlConsole() {
return note;
}
function createSearchNote() {
function createSearchNote(req) {
const params = req.body;
const searchString = params.searchString || "";
let ancestorNoteId = params.ancestorNoteId;
const hoistedNote = getHoistedNote();
let searchHome;
if (hoistedNote) {
([searchHome] = hoistedNote.getDescendantNotesWithLabel('hoistedSearchHome'));
if (!searchHome) {
([searchHome] = hoistedNote.getDescendantNotesWithLabel('searchHome'));
}
if (!searchHome) {
searchHome = hoistedNote;
}
if (!ancestorNoteId) {
ancestorNoteId = hoistedNote.noteId;
}
}
else {
const today = dateUtils.localNowDate();
const searchHome =
attributeService.getNoteWithLabel('searchHome')
searchHome = attributeService.getNoteWithLabel('searchHome')
|| dateNoteService.getDateNote(today);
}
const {note} = noteService.createNewNote({
parentNoteId: searchHome.noteId,
title: 'Search: ',
title: 'Search: ' + searchString,
content: "",
type: 'search',
mime: 'application/json'
});
note.setLabel('searchString', searchString);
if (ancestorNoteId) {
note.setRelation('ancestor', ancestorNoteId);
}
return note;
}
function getHoistedNote() {
return cls.getHoistedNoteId() && cls.getHoistedNoteId() !== 'root'
? repository.getNote(cls.getHoistedNoteId())
: null;
}
module.exports = {
getInboxNote,
getDateNote,

View File

@@ -42,6 +42,9 @@ async function importToBranch(req) {
// and may produce unintended consequences
cls.disableEntityEvents();
// eliminate flickering during import
cls.ignoreEntityChanges();
let note; // typically root of the import - client can show it after finishing the import
const taskContext = TaskContext.getInstance(taskId, 'import', options);

View File

@@ -4,6 +4,7 @@ const noteService = require('../../services/notes');
const treeService = require('../../services/tree');
const repository = require('../../services/repository');
const utils = require('../../services/utils');
const log = require('../../services/log');
const TaskContext = require('../../services/task_context');
function getNote(req) {
@@ -85,10 +86,20 @@ function undeleteNote(req) {
taskContext.taskSucceeded();
}
function sortNotes(req) {
function sortChildNotes(req) {
const noteId = req.params.noteId;
const {sortBy, sortDirection} = req.body;
treeService.sortNotesAlphabetically(noteId);
log.info(`Sorting ${noteId} children with ${sortBy} ${sortDirection}`);
const reverse = sortDirection === 'desc';
if (sortBy === 'title') {
treeService.sortNotesByTitle(noteId, false, reverse);
}
else {
treeService.sortNotes(noteId, sortBy, reverse);
}
}
function protectNote(req) {
@@ -117,7 +128,8 @@ function setNoteTypeMime(req) {
}
function getRelationMap(req) {
const noteIds = req.body.noteIds;
const {relationMapNoteId, noteIds} = req.body;
const resp = {
// noteId => title
noteTitles: {},
@@ -134,12 +146,23 @@ function getRelationMap(req) {
const questionMarks = noteIds.map(noteId => '?').join(',');
const relationMapNote = repository.getNote(relationMapNoteId);
const displayRelationsVal = relationMapNote.getLabelValue('displayRelations');
const displayRelations = !displayRelationsVal ? [] : displayRelationsVal
.split(",")
.map(token => token.trim());
console.log("displayRelations", displayRelations);
const notes = repository.getEntities(`SELECT * FROM notes WHERE isDeleted = 0 AND noteId IN (${questionMarks})`, noteIds);
for (const note of notes) {
resp.noteTitles[note.noteId] = note.title;
resp.relations = resp.relations.concat(note.getRelations()
.filter(relation => !relation.isAutoLink() || displayRelations.includes(relation.name))
.filter(relation => displayRelations.length === 0 || displayRelations.includes(relation.name))
.filter(relation => noteIds.includes(relation.value))
.map(relation => ({
attributeId: relation.attributeId,
@@ -203,7 +226,7 @@ module.exports = {
deleteNote,
undeleteNote,
createNote,
sortNotes,
sortChildNotes,
protectNote,
setNoteTypeMime,
getRelationMap,

View File

@@ -40,7 +40,8 @@ const ALLOWED_OPTIONS = new Set([
'nativeTitleBarVisible',
'attributeListExpanded',
'promotedAttributesExpanded',
'similarNotesExpanded'
'similarNotesExpanded',
'headingStyle'
]);
function getOptions() {

View File

@@ -24,6 +24,7 @@ async function search(note) {
orderBy: note.getLabelValue('orderBy'),
orderDirection: note.getLabelValue('orderDirection'),
limit: note.getLabelValue('limit'),
debug: note.hasLabel('debug'),
fuzzyAttributeSearch: false
});
@@ -232,7 +233,9 @@ function getRelatedNotes(req) {
const results = [];
for (const record of matchingNameAndValue.concat(matchingName)) {
const allResults = matchingNameAndValue.concat(matchingName);
for (const record of allResults) {
if (results.length >= 20) {
break;
}
@@ -245,7 +248,7 @@ function getRelatedNotes(req) {
}
return {
count: matchingName.length,
count: allResults.length,
results
};
}
@@ -266,6 +269,10 @@ function formatAttrForSearch(attr, searchWithValue) {
searchStr += attr.name;
if (searchWithValue && attr.value) {
if (attr.type === 'relation') {
searchStr += ".noteId";
}
searchStr += '=';
searchStr += formatValue(attr.value);
}

View File

@@ -1,6 +1,7 @@
"use strict";
const noteCache = require('../../services/note_cache/note_cache');
const log = require('../../services/log');
function getNotesAndBranchesAndAttributes(noteIds) {
noteIds = new Set(noteIds);
@@ -76,6 +77,11 @@ function getNotesAndBranchesAndAttributes(noteIds) {
for (const branchId of collectedBranchIds) {
const branch = noteCache.branches[branchId];
if (!branch) {
log.error(`Could not find branch for branchId=${branchId}`);
continue;
}
branches.push({
branchId: branch.branchId,
noteId: branch.noteId,
@@ -129,6 +135,10 @@ function getTree(req) {
}
}
if (!(subTreeNoteId in noteCache.notes)) {
return [404, `Note ${subTreeNoteId} not found in the cache`];
}
collect(noteCache.notes[subTreeNoteId]);
return getNotesAndBranchesAndAttributes(collectedNoteIds);

View File

@@ -19,6 +19,7 @@ function index(req, res) {
res.render(view, {
csrfToken: csrfToken,
theme: options.theme,
headingStyle: options.headingStyle,
mainFontSize: parseInt(options.mainFontSize),
treeFontSize: parseInt(options.treeFontSize),
detailFontSize: parseInt(options.detailFontSize),

View File

@@ -150,7 +150,7 @@ function register(app) {
apiRoute(DELETE, '/api/notes/:noteId', notesApiRoute.deleteNote);
apiRoute(PUT, '/api/notes/:noteId/undelete', notesApiRoute.undeleteNote);
apiRoute(POST, '/api/notes/:parentNoteId/children', notesApiRoute.createNote);
apiRoute(PUT, '/api/notes/:noteId/sort', notesApiRoute.sortNotes);
apiRoute(PUT, '/api/notes/:noteId/sort-children', notesApiRoute.sortChildNotes);
apiRoute(PUT, '/api/notes/:noteId/protect/:isProtected', notesApiRoute.protectNote);
apiRoute(PUT, /\/api\/notes\/(.*)\/type\/(.*)\/mime\/(.*)/, notesApiRoute.setNoteTypeMime);
apiRoute(GET, '/api/notes/:noteId/revisions', noteRevisionsApiRoute.getNoteRevisions);

View File

@@ -4,7 +4,7 @@ const build = require('./build');
const packageJson = require('../../package');
const {TRILIUM_DATA_DIR} = require('./data_dir');
const APP_DB_VERSION = 182;
const APP_DB_VERSION = 183;
const SYNC_VERSION = 20;
const CLIPPER_PROTOCOL_VERSION = "1.0";

View File

@@ -27,7 +27,6 @@ const BUILTIN_ATTRIBUTES = [
{ type: 'label', name: 'run', isDangerous: true },
{ type: 'label', name: 'customRequestHandler', isDangerous: true },
{ type: 'label', name: 'customResourceProvider', isDangerous: true },
{ type: 'label', name: 'bookZoomLevel', isDangerous: false },
{ type: 'label', name: 'widget', isDangerous: true },
{ type: 'label', name: 'noteInfoWidgetDisabled' },
{ type: 'label', name: 'linkMapWidgetDisabled' },
@@ -38,8 +37,12 @@ const BUILTIN_ATTRIBUTES = [
{ type: 'label', name: 'workspaceIconClass' },
{ type: 'label', name: 'workspaceTabBackgroundColor' },
{ type: 'label', name: 'searchHome' },
{ type: 'label', name: 'hoistedInbox' },
{ type: 'label', name: 'hoistedSearchHome' },
{ type: 'label', name: 'sqlConsoleHome' },
{ type: 'label', name: 'datePattern' },
{ type: 'label', name: 'pageSize' },
{ type: 'label', name: 'viewType' },
// relation names
{ type: 'relation', name: 'runOnNoteCreation', isDangerous: true },

View File

@@ -359,7 +359,7 @@ function BackendScriptApi(currentNote, apiParams) {
* @method
* @param {string} parentNoteId - this note's child notes will be sorted
*/
this.sortNotesAlphabetically = treeService.sortNotesAlphabetically;
this.sortNotesByTitle = treeService.sortNotesByTitle;
/**
* This method finds note by its noteId and prefix and either sets it to the given parentNoteId

View File

@@ -1 +1 @@
module.exports = { buildDate:"2021-02-15T22:29:35+01:00", buildRevision: "c0edcc1bfe621eff7fbc976172fd0897bc065f6c" };
module.exports = { buildDate:"2021-03-14T22:56:27+01:00", buildRevision: "6c8d20288df302f3a415bd1bdcace98bf29d4bf6" };

View File

@@ -44,15 +44,23 @@ function isEntityEventsDisabled() {
return !!namespace.get('disableEntityEvents');
}
function clearEntityChanges() {
namespace.set('entityChanges', []);
}
function getAndClearEntityChanges() {
const entityChanges = namespace.get('entityChanges') || [];
namespace.set('entityChanges', []);
clearEntityChanges();
return entityChanges;
}
function addEntityChange(entityChange) {
if (namespace.get('ignoreEntityChanges')) {
return;
}
const entityChanges = namespace.get('entityChanges') || [];
entityChanges.push(entityChange);
@@ -69,7 +77,11 @@ function getEntityFromCache(entityName, entityId) {
}
function setEntityToCache(entityName, entityId, entity) {
return namespace.set(entityName + '-' + entityId, entity);
namespace.set(entityName + '-' + entityId, entity);
}
function ignoreEntityChanges() {
namespace.set('ignoreEntityChanges', true);
}
module.exports = {
@@ -84,8 +96,10 @@ module.exports = {
disableEntityEvents,
isEntityEventsDisabled,
reset,
clearEntityChanges,
getAndClearEntityChanges,
addEntityChange,
getEntityFromCache,
setEntityToCache
setEntityToCache,
ignoreEntityChanges
};

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