From ed1381103abe0b5b892fdda4b129e4693289f5d6 Mon Sep 17 00:00:00 2001 From: azivner Date: Sun, 29 Jul 2018 18:39:10 +0200 Subject: [PATCH] #125, implementation of inheritable relations --- src/public/javascripts/services/bundle.js | 11 ++++++++- .../javascripts/services/note_detail.js | 7 ++---- .../javascripts/services/note_detail_code.js | 4 +--- src/public/javascripts/services/tooltip.js | 2 +- src/routes/api/script.js | 23 +++++++++++++++++-- src/routes/routes.js | 1 + src/services/relations.js | 16 ++++++++++++- src/services/script.js | 8 ++++++- 8 files changed, 58 insertions(+), 14 deletions(-) diff --git a/src/public/javascripts/services/bundle.js b/src/public/javascripts/services/bundle.js index a1b0ae76c..d5fc5e1b2 100644 --- a/src/public/javascripts/services/bundle.js +++ b/src/public/javascripts/services/bundle.js @@ -23,8 +23,17 @@ async function executeStartupBundles() { } } +async function executeRelationBundles(note, relationName) { + const bundlesToRun = await server.get("script/relation/" + note.noteId + "/" + relationName); + + for (const bundle of bundlesToRun) { + await executeBundle(bundle, note); + } +} + export default { executeBundle, getAndExecuteBundle, - executeStartupBundles + executeStartupBundles, + executeRelationBundles } \ No newline at end of file diff --git a/src/public/javascripts/services/note_detail.js b/src/public/javascripts/services/note_detail.js index 7394e8023..4a1a9ece6 100644 --- a/src/public/javascripts/services/note_detail.js +++ b/src/public/javascripts/services/note_detail.js @@ -190,12 +190,9 @@ async function loadNoteDetail(noteId) { const hideChildrenOverview = labels.some(label => label.name === 'hideChildrenOverview'); await showChildrenOverview(hideChildrenOverview); - const relations = await loadRelationList(); - const relationsToRun = relations.filter(relation => relation.name === 'runOnNoteView'); + await loadRelationList(); - for (const relationToRun of relationsToRun) { - await bundleService.getAndExecuteBundle(relationToRun.targetNoteId, getCurrentNote()); - } + await bundleService.executeRelationBundles(getCurrentNote(), 'runOnNoteView'); } async function showChildrenOverview(hideChildrenOverview) { diff --git a/src/public/javascripts/services/note_detail_code.js b/src/public/javascripts/services/note_detail_code.js index 00ed4ca6b..8748e4539 100644 --- a/src/public/javascripts/services/note_detail_code.js +++ b/src/public/javascripts/services/note_detail_code.js @@ -75,9 +75,7 @@ async function executeCurrentNote() { const currentNote = noteDetailService.getCurrentNote(); if (currentNote.mime.endsWith("env=frontend")) { - const bundle = await server.get('script/bundle/' + noteDetailService.getCurrentNoteId()); - - bundleService.executeBundle(bundle); + await bundleService.getAndExecuteBundle(noteDetailService.getCurrentNoteId()); } if (currentNote.mime.endsWith("env=backend")) { diff --git a/src/public/javascripts/services/tooltip.js b/src/public/javascripts/services/tooltip.js index f2ac105e8..459be59df 100644 --- a/src/public/javascripts/services/tooltip.js +++ b/src/public/javascripts/services/tooltip.js @@ -12,7 +12,7 @@ function setupTooltip() { notePath = $(this).attr("note-path"); } - if (notePath !== null) { + if (notePath) { const noteId = treeUtils.getNoteIdFromNotePath(notePath); noteDetailService.loadNote(noteId).then(note => callback(note.content)); diff --git a/src/routes/api/script.js b/src/routes/api/script.js index a6aadd7f3..de50c753e 100644 --- a/src/routes/api/script.js +++ b/src/routes/api/script.js @@ -2,6 +2,7 @@ const labelService = require('../../services/labels'); const scriptService = require('../../services/script'); +const relationService = require('../../services/relations'); const repository = require('../../services/repository'); async function exec(req) { @@ -35,14 +36,32 @@ async function getStartupBundles() { return bundles; } +async function getRelationBundles(req) { + const noteId = req.params.noteId; + const relationName = req.params.relationName; + + const relations = await relationService.getEffectiveRelations(noteId); + const filtered = relations.filter(relation => relation.name === relationName); + const targetNoteIds = filtered.map(relation => relation.targetNoteId); + const uniqueNoteIds = Array.from(new Set(targetNoteIds)); + + const bundles = []; + + for (const noteId of uniqueNoteIds) { + bundles.push(await scriptService.getScriptBundleForNoteId(noteId)); + } + + return bundles; +} + async function getBundle(req) { - const note = await repository.getNote(req.params.noteId); - return await scriptService.getScriptBundle(note); + return await scriptService.getScriptBundleForNoteId(req.params.noteId); } module.exports = { exec, run, getStartupBundles, + getRelationBundles, getBundle }; \ No newline at end of file diff --git a/src/routes/routes.js b/src/routes/routes.js index 8d2169dcb..b422fac0d 100644 --- a/src/routes/routes.js +++ b/src/routes/routes.js @@ -185,6 +185,7 @@ function register(app) { apiRoute(POST, '/api/script/run/:noteId', scriptRoute.run); apiRoute(GET, '/api/script/startup', scriptRoute.getStartupBundles); apiRoute(GET, '/api/script/bundle/:noteId', scriptRoute.getBundle); + apiRoute(GET, '/api/script/relation/:noteId/:relationName', scriptRoute.getRelationBundles); route(POST, '/api/sender/login', [], senderRoute.login, apiResultHandler); route(POST, '/api/sender/image', [auth.checkSenderToken], senderRoute.uploadImage, apiResultHandler); diff --git a/src/services/relations.js b/src/services/relations.js index ce1e6e71b..6f259e805 100644 --- a/src/services/relations.js +++ b/src/services/relations.js @@ -36,9 +36,23 @@ async function createRelation(sourceNoteId, name, targetNoteId) { }).save(); } +async function getEffectiveRelations(noteId) { + return await repository.getEntities(` + WITH RECURSIVE tree(noteId) AS ( + SELECT ? + UNION + SELECT branches.parentNoteId FROM branches + JOIN tree ON branches.noteId = tree.noteId + JOIN notes ON notes.noteId = branches.parentNoteId + WHERE notes.isDeleted = 0 AND branches.isDeleted = 0 + ) + SELECT relations.* FROM relations JOIN tree ON relations.sourceNoteId = tree.noteId WHERE relations.isDeleted = 0 AND relations.name IN ('runOnNoteView')`, [noteId]); +} + module.exports = { + BUILTIN_RELATIONS, getNotesWithRelation, getNoteWithRelation, createRelation, - BUILTIN_RELATIONS + getEffectiveRelations }; \ No newline at end of file diff --git a/src/services/script.js b/src/services/script.js index 9b6d47210..d2888a4c2 100644 --- a/src/services/script.js +++ b/src/services/script.js @@ -139,8 +139,14 @@ function sanitizeVariableName(str) { return str.replace(/[^a-z0-9_]/gim, ""); } +async function getScriptBundleForNoteId(noteId) { + const note = await repository.getNote(noteId); + return await getScriptBundle(note); +} + module.exports = { executeNote, executeScript, - getScriptBundle + getScriptBundle, + getScriptBundleForNoteId }; \ No newline at end of file