From 3a258f5e9065ada64ad8112ea828f1ffd3e833aa Mon Sep 17 00:00:00 2001 From: FliegendeWurst <2012gdwu+github@posteo.de> Date: Fri, 23 Apr 2021 10:48:42 +0200 Subject: [PATCH] Export the necessary scripts instead of copy+paste --- notes/!!!meta.json | 511 ++++++++++++++++++ notes/Implementation/CSS.css | 7 + notes/Implementation/attribute changed.js | 48 ++ .../attribute changed/reconcileAssignments.js | 25 + notes/Implementation/attribute sync button.js | 44 ++ .../reconcileAssignments.clone.html | 16 + notes/Implementation/button.js | 19 + .../daily reminder template.html | 15 + notes/Implementation/event template.html | 15 + .../Implementation/event_alerts handler.js | 10 +- notes/Implementation/new_event handler.js | 54 ++ .../Implementation/new_reminder handler.js | 11 +- notes/Implementation/reminder template.html | 15 + notes/Implementation/task template.html | 15 + notes/Implementation/task_alerts handler.js | 56 ++ notes/index.html | 11 + notes/navigation.html | 49 ++ notes/style.css | 339 ++++++++++++ task_alerts.js | 29 - 19 files changed, 1242 insertions(+), 47 deletions(-) create mode 100644 notes/!!!meta.json create mode 100644 notes/Implementation/CSS.css create mode 100644 notes/Implementation/attribute changed.js create mode 100644 notes/Implementation/attribute changed/reconcileAssignments.js create mode 100644 notes/Implementation/attribute sync button.js create mode 100644 notes/Implementation/attribute sync button/reconcileAssignments.clone.html create mode 100644 notes/Implementation/button.js create mode 100644 notes/Implementation/daily reminder template.html create mode 100644 notes/Implementation/event template.html rename event_alerts.js => notes/Implementation/event_alerts handler.js (55%) create mode 100644 notes/Implementation/new_event handler.js rename new_reminder.js => notes/Implementation/new_reminder handler.js (81%) create mode 100644 notes/Implementation/reminder template.html create mode 100644 notes/Implementation/task template.html create mode 100644 notes/Implementation/task_alerts handler.js create mode 100644 notes/index.html create mode 100644 notes/navigation.html create mode 100644 notes/style.css delete mode 100644 task_alerts.js diff --git a/notes/!!!meta.json b/notes/!!!meta.json new file mode 100644 index 0000000..863f4dc --- /dev/null +++ b/notes/!!!meta.json @@ -0,0 +1,511 @@ +{ + "formatVersion": 1, + "appVersion": "0.46.9", + "files": [ + { + "isClone": false, + "noteId": "vP5DkrdHVvv0", + "notePath": [ + "vP5DkrdHVvv0" + ], + "title": "Implementation", + "notePosition": 50, + "prefix": null, + "isExpanded": 1, + "type": "text", + "mime": "text/html", + "attributes": [], + "format": "html", + "dirFileName": "Implementation", + "children": [ + { + "isClone": false, + "noteId": "dDCKmKnFWfrk", + "notePath": [ + "vP5DkrdHVvv0", + "dDCKmKnFWfrk" + ], + "title": "attribute changed", + "notePosition": 0, + "prefix": null, + "isExpanded": 0, + "type": "code", + "mime": "application/javascript;env=backend", + "attributes": [], + "dataFileName": "attribute changed.js", + "dirFileName": "attribute changed", + "children": [ + { + "isClone": false, + "noteId": "Xv1GdWl4UvVO", + "notePath": [ + "vP5DkrdHVvv0", + "dDCKmKnFWfrk", + "Xv1GdWl4UvVO" + ], + "title": "reconcileAssignments", + "notePosition": 0, + "prefix": null, + "isExpanded": 0, + "type": "code", + "mime": "application/javascript;env=backend", + "attributes": [], + "dataFileName": "reconcileAssignments.js" + } + ] + }, + { + "isClone": false, + "noteId": "1d9ya4XfzQP2", + "notePath": [ + "vP5DkrdHVvv0", + "1d9ya4XfzQP2" + ], + "title": "button", + "notePosition": 10, + "prefix": null, + "isExpanded": 0, + "type": "code", + "mime": "application/javascript;env=frontend", + "attributes": [ + { + "type": "label", + "name": "run", + "value": "frontendStartup", + "isInheritable": false, + "position": 0 + } + ], + "dataFileName": "button.js" + }, + { + "isClone": false, + "noteId": "hvYOnJwamlAm", + "notePath": [ + "vP5DkrdHVvv0", + "hvYOnJwamlAm" + ], + "title": "CSS", + "notePosition": 20, + "prefix": null, + "isExpanded": 0, + "type": "code", + "mime": "text/css", + "attributes": [ + { + "type": "label", + "name": "appCss", + "value": "", + "isInheritable": false, + "position": 0 + } + ], + "dataFileName": "CSS.css" + }, + { + "isClone": false, + "noteId": "wYT6EyWoF0Qg", + "notePath": [ + "vP5DkrdHVvv0", + "wYT6EyWoF0Qg" + ], + "title": "task template", + "notePosition": 30, + "prefix": null, + "isExpanded": 0, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "label:tag", + "value": "promoted,multi,text", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "cssClass", + "value": "todo", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "label:location", + "value": "promoted,single,text", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "label:todoDate", + "value": "promoted,single,date", + "isInheritable": false, + "position": 40 + }, + { + "type": "label", + "name": "label:todoTime", + "value": "promoted,single,text", + "isInheritable": false, + "position": 50 + }, + { + "type": "label", + "name": "label:doneDate", + "value": "promoted,single,date", + "isInheritable": false, + "position": 60 + }, + { + "type": "label", + "name": "label:canceled", + "value": "promoted,single,boolean", + "isInheritable": false, + "position": 70 + } + ], + "format": "html", + "dataFileName": "task template.html" + }, + { + "isClone": false, + "noteId": "zzJx2J4CLv9y", + "notePath": [ + "vP5DkrdHVvv0", + "zzJx2J4CLv9y" + ], + "title": "new_reminder handler", + "notePosition": 40, + "prefix": null, + "isExpanded": 0, + "type": "code", + "mime": "application/javascript;env=backend", + "attributes": [ + { + "type": "label", + "name": "customRequestHandler", + "value": "new_reminder", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "targetTemplate", + "value": "LBDjD6rGxw6I", + "isInheritable": false, + "position": 10 + } + ], + "dataFileName": "new_reminder handler.js" + }, + { + "isClone": false, + "noteId": "UNuCNmOMROgz", + "notePath": [ + "vP5DkrdHVvv0", + "UNuCNmOMROgz" + ], + "title": "task_alerts handler", + "notePosition": 50, + "prefix": null, + "isExpanded": 0, + "type": "code", + "mime": "application/javascript;env=backend", + "attributes": [ + { + "type": "label", + "name": "customRequestHandler", + "value": "task_alerts", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "targetTemplate", + "value": "wYT6EyWoF0Qg", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "targetTemplateReminder", + "value": "LBDjD6rGxw6I", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "targetTemplateReminderDaily", + "value": "7Wzjk70ySoKm", + "isInheritable": false, + "position": 40 + } + ], + "dataFileName": "task_alerts handler.js" + }, + { + "isClone": false, + "noteId": "LBDjD6rGxw6I", + "notePath": [ + "vP5DkrdHVvv0", + "LBDjD6rGxw6I" + ], + "title": "reminder template", + "notePosition": 60, + "prefix": null, + "isExpanded": 0, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "template", + "value": "wYT6EyWoF0Qg", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "reminder", + "value": "true", + "isInheritable": true, + "position": 20 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-alarm", + "isInheritable": true, + "position": 30 + }, + { + "type": "label", + "name": "cssClass", + "value": "reminder", + "isInheritable": false, + "position": 40 + } + ], + "format": "html", + "dataFileName": "reminder template.html" + }, + { + "isClone": false, + "noteId": "7Wzjk70ySoKm", + "notePath": [ + "vP5DkrdHVvv0", + "7Wzjk70ySoKm" + ], + "title": "daily reminder template", + "notePosition": 61, + "prefix": null, + "isExpanded": 0, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "iconClass", + "value": "bx bx-alarm", + "isInheritable": true, + "position": 10 + }, + { + "type": "label", + "name": "cssClass", + "value": "reminder", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "label:todoTime", + "value": "promoted,single,text", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "reminder", + "value": "true", + "isInheritable": true, + "position": 40 + } + ], + "format": "html", + "dataFileName": "daily reminder template.html" + }, + { + "isClone": false, + "noteId": "XE5kBjusNVkY", + "notePath": [ + "vP5DkrdHVvv0", + "XE5kBjusNVkY" + ], + "title": "attribute sync button", + "notePosition": 80, + "prefix": null, + "isExpanded": 0, + "type": "code", + "mime": "application/javascript;env=frontend", + "attributes": [ + { + "type": "label", + "name": "run", + "value": "frontendStartup", + "isInheritable": false, + "position": 10 + } + ], + "dataFileName": "attribute sync button.js", + "dirFileName": "attribute sync button", + "children": [ + { + "isClone": true, + "noteId": "Xv1GdWl4UvVO", + "notePath": [ + "vP5DkrdHVvv0", + "XE5kBjusNVkY", + "Xv1GdWl4UvVO" + ], + "title": "reconcileAssignments", + "prefix": "", + "dataFileName": "reconcileAssignments.clone.html", + "type": "text", + "format": "html" + } + ] + }, + { + "isClone": false, + "noteId": "X5pzYZriILAz", + "notePath": [ + "vP5DkrdHVvv0", + "X5pzYZriILAz" + ], + "title": "event template", + "notePosition": 90, + "prefix": null, + "isExpanded": 0, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "label", + "name": "label:location", + "value": "promoted,single,text", + "isInheritable": false, + "position": 10 + }, + { + "type": "label", + "name": "label:startTime", + "value": "promoted,single,text", + "isInheritable": false, + "position": 20 + }, + { + "type": "label", + "name": "label:endTime", + "value": "promoted,single,text", + "isInheritable": false, + "position": 30 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-calendar-event", + "isInheritable": true, + "position": 40 + }, + { + "type": "label", + "name": "label:uid", + "value": "single,text", + "isInheritable": false, + "position": 50 + } + ], + "format": "html", + "dataFileName": "event template.html" + }, + { + "isClone": false, + "noteId": "Qfv3H8TfLqzA", + "notePath": [ + "vP5DkrdHVvv0", + "Qfv3H8TfLqzA" + ], + "title": "new_event handler", + "notePosition": 100, + "prefix": null, + "isExpanded": 0, + "type": "code", + "mime": "application/javascript;env=backend", + "attributes": [ + { + "type": "label", + "name": "customRequestHandler", + "value": "new_event", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "targetTemplate", + "value": "X5pzYZriILAz", + "isInheritable": false, + "position": 20 + } + ], + "dataFileName": "new_event handler.js" + }, + { + "isClone": false, + "noteId": "rvu9Tix6GYYx", + "notePath": [ + "vP5DkrdHVvv0", + "rvu9Tix6GYYx" + ], + "title": "event_alerts handler", + "notePosition": 110, + "prefix": null, + "isExpanded": 0, + "type": "code", + "mime": "application/javascript;env=backend", + "attributes": [ + { + "type": "label", + "name": "customRequestHandler", + "value": "event_alerts", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "targetTemplateEvent", + "value": "X5pzYZriILAz", + "isInheritable": false, + "position": 10 + } + ], + "dataFileName": "event_alerts handler.js" + } + ] + }, + { + "noImport": true, + "dataFileName": "navigation.html" + }, + { + "noImport": true, + "dataFileName": "index.html" + }, + { + "noImport": true, + "dataFileName": "style.css" + } + ] +} \ No newline at end of file diff --git a/notes/Implementation/CSS.css b/notes/Implementation/CSS.css new file mode 100644 index 0000000..4d4b43b --- /dev/null +++ b/notes/Implementation/CSS.css @@ -0,0 +1,7 @@ +span.fancytree-node.todo .fancytree-title { + color: red !important; +} + +span.fancytree-node.done .fancytree-title { + color: green !important; +} \ No newline at end of file diff --git a/notes/Implementation/attribute changed.js b/notes/Implementation/attribute changed.js new file mode 100644 index 0000000..a734304 --- /dev/null +++ b/notes/Implementation/attribute changed.js @@ -0,0 +1,48 @@ +if (!["task", "location", "tag", "todoDate", "doneDate"].includes(api.originEntity.name)) { + return; +} + +const note = await api.originEntity.getNote(); + +const attributes = await note.getAttributes(); + +if (attributes.filter(attr => attr.type === 'label' && attr.name === 'reminder').map(attr => attr.value).length() > 0) { + api.log("ignoring"); + return; +} + +const todoDate = await note.getLabelValue('todoDate'); +const doneDate = await note.getLabelValue('doneDate'); +const canceled = !!(await note.getLabelValue('canceled')); +const isTaskDone = !!doneDate; + +const canceledRootNote = await api.getNoteWithLabel('taskDoneRoot'); +await api.toggleNoteInParent(canceled, note.noteId, canceledRootNote.noteId); + +const doneRootNote = await api.getNoteWithLabel('taskDoneRoot'); +await api.toggleNoteInParent(isTaskDone && !canceled, note.noteId, doneRootNote.noteId); + +const todoRootNote = await api.getNoteWithLabel('taskTodoRoot'); +await api.toggleNoteInParent(!isTaskDone && !canceled, note.noteId, todoRootNote.noteId); + +const location = await note.getLabelValue('location'); +const locationRootNote = await api.getNoteWithLabel('taskLocationRoot'); + +await reconcileAssignments(note, locationRootNote, location ? [location] : [], 'taskLocationNote', isTaskDone); + +const tags = attributes.filter(attr => attr.type === 'label' && attr.name === 'tag').map(attr => attr.value); +const tagRootNote = await api.getNoteWithLabel('taskTagRoot'); + +await reconcileAssignments(note, tagRootNote, tags, 'taskTagNote', isTaskDone); + +await note.toggleLabel(isTaskDone || canceled, "cssClass", "done"); + +const doneTargetNoteId = isTaskDone ? (await api.getDateNote(doneDate)).noteId : null; +await api.setNoteToParent(note.noteId, 'DONE', doneTargetNoteId); + +await note.toggleLabel(!isTaskDone && !canceled, "cssClass", "todo"); + +const todoTargetNoteId = (!isTaskDone && !canceled && todoDate) ? (await api.getDateNote(todoDate)).noteId : null; +await api.setNoteToParent(note.noteId, 'TODO', todoTargetNoteId); + +api.refreshTree(); \ No newline at end of file diff --git a/notes/Implementation/attribute changed/reconcileAssignments.js b/notes/Implementation/attribute changed/reconcileAssignments.js new file mode 100644 index 0000000..310f219 --- /dev/null +++ b/notes/Implementation/attribute changed/reconcileAssignments.js @@ -0,0 +1,25 @@ +module.exports = async function(note, categoryRootNote, assignedCategories, labelName, isTaskDone) { + const found = {}; + + for (const categoryNote of await categoryRootNote.getChildNotes()) { + const label = await categoryNote.getLabel(labelName); + + if (label) { + found[label.value] = !isTaskDone && assignedCategories.includes(label.value); + + await api.toggleNoteInParent(found[label.value], note.noteId, categoryNote.noteId); + } + } + + if (!isTaskDone) { + for (const assignedCategory of assignedCategories) { + if (!found[assignedCategory]) { + const categoryNote = (await api.createNote(categoryRootNote.noteId, assignedCategory, "", { + attributes: [ { type: "label", name: labelName, value: assignedCategory } ] + })).note; + + await api.ensureNoteIsPresentInParent(note.noteId, categoryNote.noteId); + } + } + } +} \ No newline at end of file diff --git a/notes/Implementation/attribute sync button.js b/notes/Implementation/attribute sync button.js new file mode 100644 index 0000000..807d4a7 --- /dev/null +++ b/notes/Implementation/attribute sync button.js @@ -0,0 +1,44 @@ +api.addButtonToToolbar({ + title: 'Sync task', + icon: 'sync', + action: async () => { + await api.runOnBackend(async (noteId) => { +const note = await api.getNote(noteId); +const attributes = await note.getAttributes(); +const todoDate = await note.getLabelValue('todoDate'); +const doneDate = await note.getLabelValue('doneDate'); +const canceled = !!(await note.getLabelValue('canceled')); +api.log(canceled); +const isTaskDone = !!doneDate; + +const canceledRootNote = await api.getNoteWithLabel('taskCanceledRoot'); +await api.toggleNoteInParent(canceled, note.noteId, canceledRootNote.noteId); + +const doneRootNote = await api.getNoteWithLabel('taskDoneRoot'); +await api.toggleNoteInParent(isTaskDone && !canceled, note.noteId, doneRootNote.noteId); + +const todoRootNote = await api.getNoteWithLabel('taskTodoRoot'); +await api.toggleNoteInParent(!isTaskDone && !canceled, note.noteId, todoRootNote.noteId); + +const location = await note.getLabelValue('location'); +const locationRootNote = await api.getNoteWithLabel('taskLocationRoot'); + +await reconcileAssignments(note, locationRootNote, location ? [location] : [], 'taskLocationNote', isTaskDone); + +const tags = attributes.filter(attr => attr.type === 'label' && attr.name === 'tag').map(attr => attr.value); +const tagRootNote = await api.getNoteWithLabel('taskTagRoot'); + +await reconcileAssignments(note, tagRootNote, tags, 'taskTagNote', isTaskDone); + +await note.toggleLabel(isTaskDone || canceled, "cssClass", "done"); + +const doneTargetNoteId = (isTaskDone && !canceled) ? (await api.getDateNote(doneDate)).noteId : null; +await api.setNoteToParent(note.noteId, 'DONE', doneTargetNoteId); + +await note.toggleLabel(!isTaskDone && !canceled, "cssClass", "todo"); + +const todoTargetNoteId = ((!isTaskDone || canceled) && todoDate) ? (await api.getDateNote(todoDate)).noteId : null; +await api.setNoteToParent(note.noteId, 'TODO', todoTargetNoteId); + }, [api.getActiveTabNote().noteId]); + } +}); \ No newline at end of file diff --git a/notes/Implementation/attribute sync button/reconcileAssignments.clone.html b/notes/Implementation/attribute sync button/reconcileAssignments.clone.html new file mode 100644 index 0000000..f0e986b --- /dev/null +++ b/notes/Implementation/attribute sync button/reconcileAssignments.clone.html @@ -0,0 +1,16 @@ + + +
+ + + +This is a clone of a note. Go to its primary location.
+ + + \ No newline at end of file diff --git a/notes/Implementation/button.js b/notes/Implementation/button.js new file mode 100644 index 0000000..e81217d --- /dev/null +++ b/notes/Implementation/button.js @@ -0,0 +1,19 @@ +api.addButtonToToolbar({ + title: 'New task', + icon: 'check', + shortcut: 'alt+n', + action: async () => { + // creating notes is backend (server) responsibility so we need to pass + // the control there + const taskNoteId = await api.runOnServer(async () => { + const todoRootNote = await api.getNoteWithLabel('taskTodoRoot'); + const resp = await api.createTextNote(todoRootNote.noteId, 'new task', ''); + + return resp.note.noteId; + }); + + await api.waitUntilSynced(); + // we got an ID of newly created note and we want to immediatelly display it + await api.activateNewNote(taskNoteId); + } +}); \ No newline at end of file diff --git a/notes/Implementation/daily reminder template.html b/notes/Implementation/daily reminder template.html new file mode 100644 index 0000000..85f51e1 --- /dev/null +++ b/notes/Implementation/daily reminder template.html @@ -0,0 +1,15 @@ + + + + + + +