added runOnAttributeChange event

This commit is contained in:
azivner
2018-08-09 20:08:00 +02:00
parent 5b15424498
commit ac25770c0e
11 changed files with 80 additions and 30 deletions

View File

@@ -2,16 +2,21 @@ const eventService = require('./events');
const scriptService = require('./script');
const treeService = require('./tree');
const messagingService = require('./messaging');
const repository = require('./repository');
eventService.subscribe(eventService.NOTE_TITLE_CHANGED, async note => {
async function runAttachedRelations(note, relationName, workEntity) {
const attributes = await note.getAttributes();
const runRelations = attributes.filter(relation => relation.type === 'relation' && relation.name === 'runOnNoteTitleChange');
const runRelations = attributes.filter(relation => relation.type === 'relation' && relation.name === relationName);
for (const relation of runRelations) {
const scriptNote = await relation.getTargetNote();
await scriptService.executeNote(scriptNote, scriptNote, note);
await scriptService.executeNote(scriptNote, scriptNote, workEntity);
}
}
eventService.subscribe(eventService.NOTE_TITLE_CHANGED, async note => {
await runAttachedRelations(note, 'runOnNoteTitleChange', note);
if (!note.isRoot()) {
const parents = await note.getParentNotes();
@@ -24,4 +29,12 @@ eventService.subscribe(eventService.NOTE_TITLE_CHANGED, async note => {
}
}
}
});
eventService.subscribe(eventService.ENTITY_CHANGED, async ({ entityId, entityName }) => {
if (entityName === 'attributes') {
const attribute = await repository.getEntityFromName(entityName, entityId);
await runAttachedRelations(await attribute.getNote(), 'runOnAttributeChange', attribute);
}
});

View File

@@ -9,10 +9,16 @@ async function setEntityConstructor(constructor) {
entityConstructor = constructor;
}
async function getEntityFromName(entityName, entityId) {
const entityConstructor = entityConstructor.getEntityFromTableName(entityName);
return await getEntity(`SELECT * FROM ${entityConstructor.tableName()} WHERE ${entityConstructor.primaryKeyName()} = ?`, [entityId]);
}
async function getEntities(query, params = []) {
const rows = await sql.getRows(query, params);
return rows.map(entityConstructor);
return rows.map(entityConstructor.createEntityFromRow);
}
async function getEntity(query, params = []) {
@@ -22,7 +28,7 @@ async function getEntity(query, params = []) {
return null;
}
return entityConstructor(row);
return entityConstructor.createEntityFromRow(row);
}
async function getNote(noteId) {
@@ -73,6 +79,7 @@ async function updateEntity(entity) {
}
module.exports = {
getEntityFromName,
getEntities,
getEntity,
getNote,

View File

@@ -4,17 +4,17 @@ const repository = require('./repository');
const cls = require('./cls');
const sourceIdService = require('./source_id');
async function executeNote(note, targetNote) {
async function executeNote(note, workEntity) {
if (!note.isJavaScript()) {
return;
}
const bundle = await getScriptBundle(note);
await executeBundle(bundle, note, targetNote);
await executeBundle(bundle, note, workEntity);
}
async function executeBundle(bundle, startNote, workNote = null) {
async function executeBundle(bundle, startNote, workEntity = null) {
if (!startNote) {
// this is the default case, the only exception is when we want to preserve frontend startNote
startNote = bundle.note;
@@ -23,7 +23,7 @@ async function executeBundle(bundle, startNote, workNote = null) {
// last \r\n is necessary if script contains line comment on its last line
const script = "async function() {\r\n" + bundle.script + "\r\n}";
const ctx = new ScriptContext(startNote, bundle.allNotes, workNote);
const ctx = new ScriptContext(startNote, bundle.allNotes, workEntity);
if (await bundle.note.hasLabel('manualTransactionHandling')) {
return await execute(ctx, script, '');
@@ -37,10 +37,10 @@ async function executeBundle(bundle, startNote, workNote = null) {
* This method preserves frontend startNode - that's why we start execution from currentNote and override
* bundle's startNote.
*/
async function executeScript(script, params, startNoteId, currentNoteId, targetNoteId) {
async function executeScript(script, params, startNoteId, currentNoteId, workEntityName, workEntityId) {
const startNote = await repository.getNote(startNoteId);
const currentNote = await repository.getNote(currentNoteId);
const targetNote = await repository.getNote(targetNoteId);
const workEntity = await repository.getEntityFromName(workEntityName, workEntityId);
currentNote.content = `return await (${script}\r\n)(${getParams(params)})`;
currentNote.type = 'code';
@@ -48,7 +48,7 @@ async function executeScript(script, params, startNoteId, currentNoteId, targetN
const bundle = await getScriptBundle(currentNote);
return await executeBundle(bundle, startNote, targetNote);
return await executeBundle(bundle, startNote, workEntity);
}
async function execute(ctx, script, paramsStr) {

View File

@@ -10,10 +10,10 @@ const config = require('./config');
const repository = require('./repository');
const axios = require('axios');
function ScriptContext(startNote, allNotes, workNote = null) {
function ScriptContext(startNote, allNotes, workEntity = null) {
this.modules = {};
this.notes = utils.toObject(allNotes, note => [note.noteId, note]);
this.apis = utils.toObject(allNotes, note => [note.noteId, new ScriptApi(startNote, note, workNote)]);
this.apis = utils.toObject(allNotes, note => [note.noteId, new ScriptApi(startNote, note, workEntity)]);
this.require = moduleNoteIds => {
return moduleName => {
const candidates = allNotes.filter(note => moduleNoteIds.includes(note.noteId));
@@ -28,10 +28,10 @@ function ScriptContext(startNote, allNotes, workNote = null) {
};
}
function ScriptApi(startNote, currentNote, workNote) {
function ScriptApi(startNote, currentNote, workEntity) {
this.startNote = startNote;
this.currentNote = currentNote;
this.workNote = workNote;
this.workEntity = workEntity;
this.axios = axios;