mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 10:26:08 +01:00 
			
		
		
		
	fixes, separation of notefull from noteshort
This commit is contained in:
		| @@ -172,8 +172,6 @@ function AttributesModel() { | |||||||
|  |  | ||||||
|         toastService.showMessage("Attributes have been saved."); |         toastService.showMessage("Attributes have been saved."); | ||||||
|  |  | ||||||
|         appContext.getActiveTabContext().attributes.refreshAttributes(); |  | ||||||
|  |  | ||||||
|         // FIXME detail should be also reloaded |         // FIXME detail should be also reloaded | ||||||
|         appContext.trigger('reloadTree'); |         appContext.trigger('reloadTree'); | ||||||
|     }; |     }; | ||||||
|   | |||||||
| @@ -16,13 +16,13 @@ export function showDialog() { | |||||||
|  |  | ||||||
|     $dialog.modal(); |     $dialog.modal(); | ||||||
|  |  | ||||||
|     const activeNote = appContext.getActiveTabNote(); |     const {note, noteFull} = appContext.getActiveTabContext(); | ||||||
|  |  | ||||||
|     $noteId.text(activeNote.noteId); |     $noteId.text(note.noteId); | ||||||
|     $dateCreated.text(activeNote.dateCreated); |     $dateCreated.text(noteFull.dateCreated); | ||||||
|     $dateModified.text(activeNote.dateModified); |     $dateModified.text(noteFull.dateModified); | ||||||
|     $type.text(activeNote.type); |     $type.text(note.type); | ||||||
|     $mime.text(activeNote.mime); |     $mime.text(note.mime); | ||||||
| } | } | ||||||
|  |  | ||||||
| $okButton.on('click', () => $dialog.modal('hide')); | $okButton.on('click', () => $dialog.modal('hide')); | ||||||
|   | |||||||
| @@ -3,10 +3,8 @@ import NoteShort from './note_short.js'; | |||||||
| /** | /** | ||||||
|  * Represents full note, specifically including note's content. |  * Represents full note, specifically including note's content. | ||||||
|  */ |  */ | ||||||
| class NoteFull extends NoteShort { | class NoteFull { | ||||||
|     constructor(treeCache, row, noteShort) { |     constructor(row) { | ||||||
|         super(treeCache, row, []); |  | ||||||
|  |  | ||||||
|         /** @param {string} */ |         /** @param {string} */ | ||||||
|         this.content = row.content; |         this.content = row.content; | ||||||
|  |  | ||||||
| @@ -21,12 +19,6 @@ class NoteFull extends NoteShort { | |||||||
|  |  | ||||||
|         /** @param {string} */ |         /** @param {string} */ | ||||||
|         this.utcDateModified = row.utcDateModified; |         this.utcDateModified = row.utcDateModified; | ||||||
|  |  | ||||||
|         /* ugly */ |  | ||||||
|         this.parents = noteShort.parents; |  | ||||||
|         this.parentToBranch = noteShort.parentToBranch; |  | ||||||
|         this.children = noteShort.children; |  | ||||||
|         this.childToBranch = noteShort.childToBranch; |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -15,12 +15,10 @@ function getActiveEditor() { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| async function loadNote(noteId) { | async function loadNoteFull(noteId) { | ||||||
|     const row = await server.get('notes/' + noteId); |     const row = await server.get('notes/' + noteId); | ||||||
|  |  | ||||||
|     const noteShort = await treeCache.getNote(noteId); |     return new NoteFull(row); | ||||||
|  |  | ||||||
|     return new NoteFull(treeCache, row, noteShort); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| function focusOnTitle() { | function focusOnTitle() { | ||||||
| @@ -65,7 +63,7 @@ $(window).on('beforeunload', () => { | |||||||
|  }); |  }); | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|     loadNote, |     loadNoteFull, | ||||||
|     focusOnTitle, |     focusOnTitle, | ||||||
|     focusAndSelectTitle, |     focusAndSelectTitle, | ||||||
|     getActiveEditor, |     getActiveEditor, | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ import noteDetailService from "./note_detail.js"; | |||||||
| import treeService from "./tree.js"; | import treeService from "./tree.js"; | ||||||
| import linkService from "./link.js"; | import linkService from "./link.js"; | ||||||
| import server from "./server.js"; | import server from "./server.js"; | ||||||
|  | import treeCache from "./tree_cache.js"; | ||||||
|  |  | ||||||
| function setupGlobalTooltip() { | function setupGlobalTooltip() { | ||||||
|     $(document).on("mouseenter", "a", mouseEnterHandler); |     $(document).on("mouseenter", "a", mouseEnterHandler); | ||||||
| @@ -42,12 +43,10 @@ async function mouseEnterHandler() { | |||||||
|  |  | ||||||
|     const noteId = treeService.getNoteIdFromNotePath(notePath); |     const noteId = treeService.getNoteIdFromNotePath(notePath); | ||||||
|  |  | ||||||
|     const notePromise = noteDetailService.loadNote(noteId); |     const note = await treeCache.getNote(noteId); | ||||||
|     const attributePromise = server.get(`notes/${noteId}/attributes`); |     const noteFull = await noteDetailService.loadNoteFull(noteId); | ||||||
|  |  | ||||||
|     const [note, attributes] = await Promise.all([notePromise, attributePromise]); |     const html = await renderTooltip(note, noteFull); | ||||||
|  |  | ||||||
|     const html = await renderTooltip(note, attributes); |  | ||||||
|  |  | ||||||
|     // we need to check if we're still hovering over the element |     // we need to check if we're still hovering over the element | ||||||
|     // since the operation to get tooltip content was async, it is possible that |     // since the operation to get tooltip content was async, it is possible that | ||||||
| @@ -72,7 +71,9 @@ function mouseLeaveHandler() { | |||||||
|     $(this).tooltip('dispose'); |     $(this).tooltip('dispose'); | ||||||
| } | } | ||||||
|  |  | ||||||
| async function renderTooltip(note, attributes) { | async function renderTooltip(note, noteFull) { | ||||||
|  |     const attributes = await note.getAttributes(); | ||||||
|  |  | ||||||
|     let content = ''; |     let content = ''; | ||||||
|     const promoted = attributes.filter(attr => |     const promoted = attributes.filter(attr => | ||||||
|         (attr.type === 'label-definition' || attr.type === 'relation-definition') |         (attr.type === 'label-definition' || attr.type === 'relation-definition') | ||||||
| @@ -116,11 +117,11 @@ async function renderTooltip(note, attributes) { | |||||||
|     if (note.type === 'text') { |     if (note.type === 'text') { | ||||||
|         // surround with <div> for a case when note's content is pure text (e.g. "[protected]") which |         // surround with <div> for a case when note's content is pure text (e.g. "[protected]") which | ||||||
|         // then fails the jquery non-empty text test |         // then fails the jquery non-empty text test | ||||||
|         content += '<div>' + note.content + '</div>'; |         content += '<div>' + noteFull.content + '</div>'; | ||||||
|     } |     } | ||||||
|     else if (note.type === 'code') { |     else if (note.type === 'code') { | ||||||
|         content += $("<pre>") |         content += $("<pre>") | ||||||
|             .text(note.content) |             .text(noteFull.content) | ||||||
|             .prop('outerHTML'); |             .prop('outerHTML'); | ||||||
|     } |     } | ||||||
|     else if (note.type === 'image') { |     else if (note.type === 'image') { | ||||||
|   | |||||||
| @@ -1,13 +1,13 @@ | |||||||
| import protectedSessionHolder from "./protected_session_holder.js"; | import protectedSessionHolder from "./protected_session_holder.js"; | ||||||
| import server from "./server.js"; | import server from "./server.js"; | ||||||
| import bundleService from "./bundle.js"; | import bundleService from "./bundle.js"; | ||||||
| import Attributes from "./attributes.js"; |  | ||||||
| import utils from "./utils.js"; | import utils from "./utils.js"; | ||||||
| import optionsService from "./options.js"; | import optionsService from "./options.js"; | ||||||
| import appContext from "./app_context.js"; | import appContext from "./app_context.js"; | ||||||
| import treeService from "./tree.js"; | import treeService from "./tree.js"; | ||||||
| import noteDetailService from "./note_detail.js"; | import noteDetailService from "./note_detail.js"; | ||||||
| import Component from "../widgets/component.js"; | import Component from "../widgets/component.js"; | ||||||
|  | import treeCache from "./tree_cache.js"; | ||||||
|  |  | ||||||
| let showSidebarInNewTab = true; | let showSidebarInNewTab = true; | ||||||
|  |  | ||||||
| @@ -28,10 +28,6 @@ class TabContext extends Component { | |||||||
|         this.tabId = state.tabId || utils.randomString(4); |         this.tabId = state.tabId || utils.randomString(4); | ||||||
|         this.state = state; |         this.state = state; | ||||||
|  |  | ||||||
|         this.attributes = new Attributes(this.appContext, this); |  | ||||||
|  |  | ||||||
|         this.children.push(this.attributes); |  | ||||||
|  |  | ||||||
|         this.trigger('tabOpened', {tabId: this.tabId}); |         this.trigger('tabOpened', {tabId: this.tabId}); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -52,8 +48,11 @@ class TabContext extends Component { | |||||||
|         this.notePath = notePath; |         this.notePath = notePath; | ||||||
|         const noteId = treeService.getNoteIdFromNotePath(notePath); |         const noteId = treeService.getNoteIdFromNotePath(notePath); | ||||||
|  |  | ||||||
|  |         /** @property {NoteShort} */ | ||||||
|  |         this.note = await treeCache.getNote(noteId); | ||||||
|  |  | ||||||
|         /** @property {NoteFull} */ |         /** @property {NoteFull} */ | ||||||
|         this.note = await noteDetailService.loadNote(noteId); |         this.noteFull = await noteDetailService.loadNoteFull(noteId); | ||||||
|  |  | ||||||
|         //this.cleanup(); // esp. on windows autocomplete is not getting closed automatically |         //this.cleanup(); // esp. on windows autocomplete is not getting closed automatically | ||||||
|  |  | ||||||
| @@ -85,30 +84,6 @@ class TabContext extends Component { | |||||||
|         this.trigger('tabRemoved', {tabId: this.tabId}); |         this.trigger('tabRemoved', {tabId: this.tabId}); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async saveNote() { |  | ||||||
|         return; // FIXME |  | ||||||
|  |  | ||||||
|         if (this.note.isProtected && !protectedSessionHolder.isProtectedSessionAvailable()) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         this.note.title = this.$noteTitle.val(); |  | ||||||
|         this.note.content = this.getComponent().getContent(); |  | ||||||
|  |  | ||||||
|         // it's important to set the flag back to false immediatelly after retrieving title and content |  | ||||||
|         // otherwise we might overwrite another change (especially async code) |  | ||||||
|         this.isNoteChanged = false; |  | ||||||
|  |  | ||||||
|         const resp = await server.put('notes/' + this.note.noteId, this.note.dto); |  | ||||||
|  |  | ||||||
|         this.note.dateModified = resp.dateModified; |  | ||||||
|         this.note.utcDateModified = resp.utcDateModified; |  | ||||||
|  |  | ||||||
|         if (this.note.isProtected) { |  | ||||||
|             protectedSessionHolder.touchProtectedSession(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     isActive() { |     isActive() { | ||||||
|         return this.appContext.activeTabId === this.tabId; |         return this.appContext.activeTabId === this.tabId; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -23,9 +23,9 @@ class AttributesWidget extends StandardWidget { | |||||||
|         return [$showFullButton]; |         return [$showFullButton]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async refreshWithNote() { |     async refreshWithNote(note) { | ||||||
|         const attributes = await this.tabContext.attributes.getAttributes(); |         const attributes = await note.getAttributes(); | ||||||
|         const ownedAttributes = attributes.filter(attr => attr.noteId === this.tabContext.note.noteId); |         const ownedAttributes = note.getOwnedAttributes(); | ||||||
|  |  | ||||||
|         if (attributes.length === 0) { |         if (attributes.length === 0) { | ||||||
|             this.$body.text("No attributes yet..."); |             this.$body.text("No attributes yet..."); | ||||||
|   | |||||||
| @@ -36,16 +36,19 @@ export default class NoteDetailWidget extends TabAwareWidget { | |||||||
|         this.typeWidgetPromises = {}; |         this.typeWidgetPromises = {}; | ||||||
|  |  | ||||||
|         this.spacedUpdate = new SpacedUpdate(async () => { |         this.spacedUpdate = new SpacedUpdate(async () => { | ||||||
|             const note = this.tabContext.note; |             const {noteFull} = this.tabContext; | ||||||
|             note.content = this.getTypeWidget().getContent(); |             const {noteId} = this.tabContext.note; | ||||||
|  |  | ||||||
|             const resp = await server.put('notes/' + note.noteId, note.dto); |             const dto = note.dto; | ||||||
|  |             dto.content = noteFull.content = this.getTypeWidget().getContent(); | ||||||
|  |  | ||||||
|  |             const resp = await server.put('notes/' + noteId, dto); | ||||||
|  |  | ||||||
|             // FIXME: minor - does not propagate to other tab contexts with this note though |             // FIXME: minor - does not propagate to other tab contexts with this note though | ||||||
|             note.dateModified = resp.dateModified; |             noteFull.dateModified = resp.dateModified; | ||||||
|             note.utcDateModified = resp.utcDateModified; |             noteFull.utcDateModified = resp.utcDateModified; | ||||||
|  |  | ||||||
|             this.trigger('noteChangesSaved', {noteId: note.noteId}) |             this.trigger('noteChangesSaved', {noteId}) | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -156,7 +159,7 @@ export default class NoteDetailWidget extends TabAwareWidget { | |||||||
|         let type = note.type; |         let type = note.type; | ||||||
|  |  | ||||||
|         if (type === 'text' && !disableAutoBook |         if (type === 'text' && !disableAutoBook | ||||||
|             && utils.isHtmlEmpty(note.content) |             && utils.isHtmlEmpty(this.tabContext.noteFull.content) | ||||||
|             && note.hasChildren()) { |             && note.hasChildren()) { | ||||||
|  |  | ||||||
|             type = 'book'; |             type = 'book'; | ||||||
|   | |||||||
| @@ -49,14 +49,16 @@ class NoteInfoWidget extends StandardWidget { | |||||||
|         const $type = this.$body.find(".note-info-type"); |         const $type = this.$body.find(".note-info-type"); | ||||||
|         const $mime = this.$body.find(".note-info-mime"); |         const $mime = this.$body.find(".note-info-mime"); | ||||||
|  |  | ||||||
|  |         const {noteFull} = this.tabContext; | ||||||
|  |  | ||||||
|         $noteId.text(note.noteId); |         $noteId.text(note.noteId); | ||||||
|         $dateCreated |         $dateCreated | ||||||
|             .text(note.dateCreated) |             .text(noteFull.dateCreated) | ||||||
|             .attr("title", note.dateCreated); |             .attr("title", noteFull.dateCreated); | ||||||
|  |  | ||||||
|         $dateModified |         $dateModified | ||||||
|             .text(note.dateModified) |             .text(noteFull.dateModified) | ||||||
|             .attr("title", note.dateCreated); |             .attr("title", noteFull.dateCreated); | ||||||
|  |  | ||||||
|         $type.text(note.type); |         $type.text(note.type); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -35,10 +35,10 @@ export default class PromotedAttributesWidget extends TabAwareWidget { | |||||||
|         return this.$widget; |         return this.$widget; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async refreshWithNote() { |     async refreshWithNote(note) { | ||||||
|         this.$container.empty(); |         this.$container.empty(); | ||||||
|  |  | ||||||
|         const attributes = await this.tabContext.attributes.getAttributes(); |         const attributes = await note.getAttributes(); | ||||||
|  |  | ||||||
|         const promoted = attributes.filter(attr => |         const promoted = attributes.filter(attr => | ||||||
|             (attr.type === 'label-definition' || attr.type === 'relation-definition') |             (attr.type === 'label-definition' || attr.type === 'relation-definition') | ||||||
|   | |||||||
| @@ -75,7 +75,7 @@ export default class CodeTypeWidget extends TypeWidget { | |||||||
|         this.spacedUpdate.allowUpdateWithoutChange(() => { |         this.spacedUpdate.allowUpdateWithoutChange(() => { | ||||||
|             // CodeMirror breaks pretty badly on null so even though it shouldn't happen (guarded by consistency check) |             // CodeMirror breaks pretty badly on null so even though it shouldn't happen (guarded by consistency check) | ||||||
|             // we provide fallback |             // we provide fallback | ||||||
|             this.codeEditor.setValue(note.content || ""); |             this.codeEditor.setValue(this.tabContext.noteFull.content || ""); | ||||||
|  |  | ||||||
|             const info = CodeMirror.findModeByMIME(note.mime); |             const info = CodeMirror.findModeByMIME(note.mime); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -118,7 +118,7 @@ export default class FileTypeWidget extends TypeWidget { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async doRefresh(note) { |     async doRefresh(note) { | ||||||
|         const attributes = await server.get('notes/' + note.noteId + '/attributes'); |         const attributes = await note.getAttributes(); | ||||||
|         const attributeMap = utils.toObject(attributes, l => [l.name, l.value]); |         const attributeMap = utils.toObject(attributes, l => [l.name, l.value]); | ||||||
|  |  | ||||||
|         this.$widget.show(); |         this.$widget.show(); | ||||||
| @@ -128,9 +128,9 @@ export default class FileTypeWidget extends TypeWidget { | |||||||
|         this.$fileSize.text(note.contentLength + " bytes"); |         this.$fileSize.text(note.contentLength + " bytes"); | ||||||
|         this.$fileType.text(note.mime); |         this.$fileType.text(note.mime); | ||||||
|  |  | ||||||
|         if (note.content) { |         if (this.tabContext.noteFull.content) { | ||||||
|             this.$previewContent.show(); |             this.$previewContent.show(); | ||||||
|             this.$previewContent.text(note.content); |             this.$previewContent.text(this.tabContext.noteFull.content); | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|             this.$previewContent.empty().hide(); |             this.$previewContent.empty().hide(); | ||||||
|   | |||||||
| @@ -123,7 +123,7 @@ class NoteDetailImage extends TypeWidget { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async doRefresh(note) { |     async doRefresh(note) { | ||||||
|         const attributes = await server.get('notes/' + note.noteId + '/attributes'); |         const attributes = await note.getAttributes(); | ||||||
|         const attributeMap = utils.toObject(attributes, l => [l.name, l.value]); |         const attributeMap = utils.toObject(attributes, l => [l.name, l.value]); | ||||||
|  |  | ||||||
|         this.$widget.show(); |         this.$widget.show(); | ||||||
| @@ -132,7 +132,7 @@ class NoteDetailImage extends TypeWidget { | |||||||
|         this.$fileSize.text(note.contentLength + " bytes"); |         this.$fileSize.text(note.contentLength + " bytes"); | ||||||
|         this.$fileType.text(note.mime); |         this.$fileType.text(note.mime); | ||||||
|  |  | ||||||
|         const imageHash = note.utcDateModified.replace(" ", "_"); |         const imageHash = this.tabContext.noteFull.utcDateModified.replace(" ", "_"); | ||||||
|  |  | ||||||
|         this.$imageView.prop("src", `api/images/${note.noteId}/${note.title}?${imageHash}`); |         this.$imageView.prop("src", `api/images/${note.noteId}/${note.title}?${imageHash}`); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -254,9 +254,9 @@ export default class RelationMapTypeWidget extends TypeWidget { | |||||||
|             } |             } | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         if (this.tabContext.note.content) { |         if (this.tabContext.noteFull.content) { | ||||||
|             try { |             try { | ||||||
|                 this.mapData = JSON.parse(this.tabContext.note.content); |                 this.mapData = JSON.parse(this.tabContext.noteFull.content); | ||||||
|             } catch (e) { |             } catch (e) { | ||||||
|                 console.log("Could not parse content: ", e); |                 console.log("Could not parse content: ", e); | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -45,7 +45,7 @@ export default class SearchTypeWidget extends TypeWidget { | |||||||
|         this.$component.show(); |         this.$component.show(); | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
|             const json = JSON.parse(note.content); |             const json = JSON.parse(this.tabContext.noteFull.content); | ||||||
|  |  | ||||||
|             this.$searchString.val(json.searchString); |             this.$searchString.val(json.searchString); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -137,10 +137,10 @@ export default class TextTypeWidget extends TypeWidget { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async doRefresh(note) { |     async doRefresh(note) { | ||||||
|         this.textEditor.isReadOnly = await this.isReadOnly(); |         this.textEditor.isReadOnly = await note.hasLabel('readOnly'); | ||||||
|  |  | ||||||
|         this.spacedUpdate.allowUpdateWithoutChange(() => { |         this.spacedUpdate.allowUpdateWithoutChange(() => { | ||||||
|             this.textEditor.setData(note.content); |             this.textEditor.setData(this.tabContext.noteFull.content); | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -160,12 +160,6 @@ export default class TextTypeWidget extends TypeWidget { | |||||||
|             && !content.includes("<section") |             && !content.includes("<section") | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async isReadOnly() { |  | ||||||
|         const attributes = await this.tabContext.attributes.getAttributes(); |  | ||||||
|  |  | ||||||
|         return attributes.some(attr => attr.type === 'label' && attr.name === 'readOnly'); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     focus() { |     focus() { | ||||||
|         this.$editor.trigger('focus'); |         this.$editor.trigger('focus'); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ export default class TypeWidget extends TabAwareWidget { | |||||||
|     static getType() {} |     static getType() {} | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @param {NoteFull} note |      * @param {NoteShort} note | ||||||
|      */ |      */ | ||||||
|     doRefresh(note) {} |     doRefresh(note) {} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,14 +8,7 @@ async function getNotesAndBranchesAndAttributes(noteIds) { | |||||||
|     noteIds = Array.from(new Set(noteIds)); |     noteIds = Array.from(new Set(noteIds)); | ||||||
|     const notes = await treeService.getNotes(noteIds); |     const notes = await treeService.getNotes(noteIds); | ||||||
|  |  | ||||||
|     const noteMap = {}; |     noteIds = notes.map(note => note.noteId); | ||||||
|     noteIds = []; |  | ||||||
|  |  | ||||||
|     for (const note of notes) { |  | ||||||
|         note.attributes = []; |  | ||||||
|         noteMap[note.noteId] = note; |  | ||||||
|         noteIds.push(note.noteId); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // joining child note to filter out not completely synchronised notes which would then cause errors later |     // joining child note to filter out not completely synchronised notes which would then cause errors later | ||||||
|     // cannot do that with parent because of root note's 'none' parent |     // cannot do that with parent because of root note's 'none' parent | ||||||
| @@ -37,14 +30,19 @@ async function getNotesAndBranchesAndAttributes(noteIds) { | |||||||
|  |  | ||||||
|     const attributes = await sql.getManyRows(` |     const attributes = await sql.getManyRows(` | ||||||
|         SELECT |         SELECT | ||||||
|  |             attributeId, | ||||||
|             noteId, |             noteId, | ||||||
|             type, |             type, | ||||||
|             name, |             name, | ||||||
|             value, |             value, | ||||||
|  |             position, | ||||||
|             isInheritable |             isInheritable | ||||||
|         FROM attributes |         FROM attributes | ||||||
|         WHERE isDeleted = 0 AND noteId IN (???)`, noteIds); |         WHERE isDeleted = 0 AND noteId IN (???)`, noteIds); | ||||||
|  |  | ||||||
|  |     // sorting in memory is faster | ||||||
|  |     attributes.sort((a, b) => a.position - b.position < 0 ? -1 : 1); | ||||||
|  |  | ||||||
|     return { |     return { | ||||||
|         branches, |         branches, | ||||||
|         notes, |         notes, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user