From c1127ec4293143e9ff6080cbe9c14a8366a132bd Mon Sep 17 00:00:00 2001 From: zadam Date: Sat, 22 Oct 2022 21:34:38 +0200 Subject: [PATCH] fix running of runOnNoteCreation hook, #3219 --- .../attribute_widgets/attribute_detail.js | 8 +-- src/services/cls.js | 5 ++ src/services/notes.js | 71 +++++++++++++------ 3 files changed, 59 insertions(+), 25 deletions(-) diff --git a/src/public/app/widgets/attribute_widgets/attribute_detail.js b/src/public/app/widgets/attribute_widgets/attribute_detail.js index a43c99bb8..fb15b92ef 100644 --- a/src/public/app/widgets/attribute_widgets/attribute_detail.js +++ b/src/public/app/widgets/attribute_widgets/attribute_detail.js @@ -240,15 +240,15 @@ const ATTR_HELP = { "keyboardShortcut": "Defines a keyboard shortcut which will immediately jump to this note. Example: 'ctrl+alt+e'. Requires frontend reload for the change to take effect." }, "relation": { - "runOnNoteCreation": "executes when note is created on backend", + "runOnNoteCreation": "executes when note is created on backend. Use this relation if you want to run the script for all notes created under a specific subtree. In that case, create it on the subtree root note and make it inheritable. A new note created within the subtree (any depth) will trigger the script.", + "runOnChildNoteCreation": "executes when new note is created under the note where this relation is defined", "runOnNoteTitleChange": "executes when note title is changed (includes note creation as well)", "runOnNoteChange": "executes when note is changed (includes note creation as well)", "runOnNoteDeletion": "executes when note is being deleted", "runOnBranchCreation": "executes when a branch is created. Branch is a link between parent note and child note and is created e.g. when cloning or moving note.", "runOnBranchDeletion": "executes when a branch is deleted. Branch is a link between parent note and child note and is deleted e.g. when moving note (old branch/link is deleted).", - "runOnChildNoteCreation": "executes when new note is created under this note", - "runOnAttributeCreation": "executes when new attribute is created under this note", - "runOnAttributeChange": "executes when attribute is changed under this note", + "runOnAttributeCreation": "executes when new attribute is created for the note which defines this relation", + "runOnAttributeChange": " executes when the attribute is changed of a note which defines this relation. This is triggered also when the attribute is deleted", "template": "attached note's attributes will be inherited even without parent-child relationship. See template for details.", "renderNote": 'notes of type "render HTML note" will be rendered using a code note (HTML or script) and it is necessary to point using this relation to which note should be rendered', "widget": "target of this relation will be executed and rendered as a widget in the sidebar", diff --git a/src/services/cls.js b/src/services/cls.js index 29ea06778..ac564b70f 100644 --- a/src/services/cls.js +++ b/src/services/cls.js @@ -40,6 +40,10 @@ function disableEntityEvents() { namespace.set('disableEntityEvents', true); } +function enableEntityEvents() { + namespace.set('disableEntityEvents', false); +} + function isEntityEventsDisabled() { return !!namespace.get('disableEntityEvents'); } @@ -83,6 +87,7 @@ module.exports = { getComponentId, getLocalNowDateTime, disableEntityEvents, + enableEntityEvents, isEntityEventsDisabled, reset, getAndClearEntityChangeIds, diff --git a/src/services/notes.js b/src/services/notes.js index 5cbb694fa..cbc3952fb 100644 --- a/src/services/notes.js +++ b/src/services/notes.js @@ -33,10 +33,6 @@ function getNewNotePosition(parentNoteId) { return maxNotePos + 10; } -function triggerChildNoteCreated(childNote, parentNote) { - eventService.emit(eventService.CHILD_NOTE_CREATED, { childNote, parentNote }); -} - function triggerNoteTitleChanged(note) { eventService.emit(eventService.NOTE_TITLE_CHANGED, note); } @@ -140,24 +136,43 @@ function createNewNote(params) { } return sql.transactional(() => { - const note = new Note({ - noteId: params.noteId, // optionally can force specific noteId - title: params.title, - isProtected: !!params.isProtected, - type: params.type, - mime: deriveMime(params.type, params.mime) - }).save(); + let note, branch, isEntityEventsDisabled; - note.setContent(params.content); + try { + isEntityEventsDisabled = cls.isEntityEventsDisabled(); - const branch = new Branch({ - branchId: params.branchId, - noteId: note.noteId, - parentNoteId: params.parentNoteId, - notePosition: params.notePosition !== undefined ? params.notePosition : getNewNotePosition(params.parentNoteId), - prefix: params.prefix, - isExpanded: !!params.isExpanded - }).save(); + if (!isEntityEventsDisabled) { + // it doesn't make sense to run note creation events on a partially constructed note, so + // defer them until note creation is completed + cls.disableEntityEvents(); + } + + note = new Note({ + noteId: params.noteId, // optionally can force specific noteId + title: params.title, + isProtected: !!params.isProtected, + type: params.type, + mime: deriveMime(params.type, params.mime) + }).save(); + + note.setContent(params.content); + + branch = new Branch({ + branchId: params.branchId, + noteId: note.noteId, + parentNoteId: params.parentNoteId, + notePosition: params.notePosition !== undefined ? params.notePosition : getNewNotePosition(params.parentNoteId), + prefix: params.prefix, + isExpanded: !!params.isExpanded + }).save(); + } + finally { + if (!isEntityEventsDisabled) { + // re-enable entity events only if there were previously enabled + // (they can be disabled in case of import) + cls.enableEntityEvents(); + } + } scanForLinks(note); @@ -175,7 +190,21 @@ function createNewNote(params) { } triggerNoteTitleChanged(note); - triggerChildNoteCreated(note, parentNote); + + eventService.emit(eventService.ENTITY_CREATED, { + entityName: 'notes', + entity: note + }); + + eventService.emit(eventService.ENTITY_CREATED, { + entityName: 'branches', + entity: branch + }); + + eventService.emit(eventService.CHILD_NOTE_CREATED, { + childNote: note, + parentNote: parentNote + }); log.info(`Created new note '${note.noteId}', branch '${branch.branchId}' of type '${note.type}', mime '${note.mime}'`);