Export the necessary scripts instead of copy+paste

This commit is contained in:
FliegendeWurst 2021-04-23 10:48:42 +02:00
parent f63d078831
commit 3a258f5e90
19 changed files with 1242 additions and 47 deletions

511
notes/!!!meta.json Normal file
View File

@ -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"
}
]
}

View File

@ -0,0 +1,7 @@
span.fancytree-node.todo .fancytree-title {
color: red !important;
}
span.fancytree-node.done .fancytree-title {
color: green !important;
}

View File

@ -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();

View File

@ -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);
}
}
}
}

View File

@ -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]);
}
});

View File

@ -0,0 +1,16 @@
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../../style.css">
<base target="_parent">
</head>
<body class="ck-content">
<h1>reconcileAssignments</h1>
<p>This is a clone of a note. Go to its <a href="../attribute%20changed/reconcileAssignments.js">primary location</a>.</p>
</body>
</html>

View File

@ -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);
}
});

View File

@ -0,0 +1,15 @@
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../style.css">
<base target="_parent">
</head>
<body class="ck-content">
<h1>daily reminder template</h1>
</body>
</html>

View File

@ -0,0 +1,15 @@
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../style.css">
<base target="_parent">
</head>
<body class="ck-content">
<h1>event template</h1>
</body>
</html>

View File

@ -1,11 +1,3 @@
// Create as JS Backend note and add these attributes:
// ~targetTemplateEvent=@event template (this note is described below)
// #customRequestHandler=event_alerts
// Create another note (event template) with this promoted attributes:
// startTime
// Optionally add:
// endTime, location
const {req, res} = api;
const targetTemplate = await api.currentNote.getRelationValue("targetTemplateEvent");
@ -21,4 +13,4 @@ for (const event of events) {
});
}
res.send(eventsData);
res.send(eventsData);

View File

@ -0,0 +1,54 @@
function formatTime(startTime) {
return startTime.getFullYear().toString() + "-" + (startTime.getMonth() + 1).toString().padStart(2, "0") + "-" + startTime.getDate().toString().padStart(2, "0") + "T" + startTime.getHours().toString().padStart(2, "0") + ":" + startTime.getMinutes().toString().padStart(2, "0") + ":" + startTime.getSeconds().toString().padStart(2, "0");
}
const {req, res} = api;
const uid = req.body["uid"];
const name = req.body["name"];
const summary = req.body["summary"];
const location = req.body["location"];
const fileName = req.body["fileName"];
const fileData = req.body["fileData"];
const startTime = new Date(req.body["startTime"]);
const endTime = new Date(req.body["endTime"]);
const year = startTime.getFullYear();
var month = startTime.getMonth() + 1;
var day = startTime.getDate();
if (month < 10) {
month = '0' + month;
}
if (day < 10) {
day = '0' + day;
}
const eventDateStr = year + "-" + month + "-" + day;
const dayNote = await api.getDateNote(eventDateStr);
const targetTemplate = await api.currentNote.getRelationValue('targetTemplate');
const options = {
"parentNoteId": dayNote.noteId,
"title": name,
"content": summary,
"type": "text"
};
const resp = await api.createNewNote(options);
const note = resp.note;
await note.setAttribute("relation", "template", targetTemplate);
await note.setAttribute("label", "uid", uid);
await note.setAttribute("label", "location", location);
const startTimeStr = formatTime(startTime);
await note.setAttribute("label", "startTime", startTimeStr);
await note.setAttribute("label", "endTime", formatTime(endTime));
const fileOptions = {
"parentNoteId": note.noteId,
"title": fileName,
"content": fileData,
"type": "file",
"mime": "text/calendar"
};
await api.createNewNote(fileOptions);
res.sendStatus(200);

View File

@ -1,12 +1,3 @@
// Create as JS Backend note with these attributes:
// ~targetTemplate=@reminder template
// #customRequestHandler=new_reminder
// Create a new note (reminder template) with these promoted attributes:
// todoDate: date
// todoTime: text
// doneDate: date
// reminder = true
Date.prototype.addHours = function(h) {
this.setTime(this.getTime() + (h*60*60*1000));
return this;
@ -46,6 +37,8 @@ if (day < 10) {
const todayDateStr = year + "-" + month + "-" + day;
const todayNote = await api.getDateNote(todayDateStr);
//const templateNoteId = 'LBDjD6rGxw6I';
//const templateNote = await api.getNote('LBDjD6rGxw6I');
const targetTemplate = await api.currentNote.getAttributeValue('relation', 'targetTemplate');
const resp = await api.createNote(
todayNote.noteId,

View File

@ -0,0 +1,15 @@
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../style.css">
<base target="_parent">
</head>
<body class="ck-content">
<h1>reminder template</h1>
</body>
</html>

View File

@ -0,0 +1,15 @@
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="../style.css">
<base target="_parent">
</head>
<body class="ck-content">
<h1>task template</h1>
</body>
</html>

View File

@ -0,0 +1,56 @@
const {req, res} = api;
const today = new Date().toISOString().substr(0, 10);
const targetTemplate = await api.currentNote.getRelationValue('targetTemplate');
const tasks = await api.getNotesWithLabel("template", targetTemplate);
let tasksData = [];
for (const task of tasks) {
const todoDate = task.getAttribute("label", "todoDate");
if (!todoDate || todoDate["value"] < today) {
continue;
}
tasksData.push({
attributes: await task.getAttributes(),
...task
});
}
const targetTemplateReminder = await api.currentNote.getRelationValue('targetTemplateReminder');
const reminders = await api.getNotesWithLabel("template", targetTemplateReminder);
for (const task of reminders) {
const todoDate = task.getAttribute("label", "todoDate");
if (!todoDate || todoDate["value"] < today) {
continue;
}
tasksData.push({
attributes: await task.getAttributes(),
...task
});
}
const targetTemplateReminderDaily = await api.currentNote.getRelationValue('targetTemplateReminderDaily');
const remindersDaily = await api.getNotesWithLabel("template", targetTemplateReminderDaily);
for (const task of remindersDaily) {
const attributes = await task.getAttributes();
attributes.push({
"type": "label",
"name": "todoDate",
"value": today,
// API compliance
"attributeId": "",
"noteId": "",
"position": 0,
"utcDateModified": "2021-04-23 08:20:14.295Z",
"isDeleted": false,
"isInheritable": false
});
tasksData.push({
attributes: attributes,
...task
});
}
res.send(tasksData);

11
notes/index.html Normal file
View File

@ -0,0 +1,11 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<frameset cols="25%,75%">
<frame name="navigation" src="navigation.html">
<frame name="detail" src="Implementation/attribute%20changed.js">
</frameset>
</html>

49
notes/navigation.html Normal file
View File

@ -0,0 +1,49 @@
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<ul>
<li>Implementation
<ul>
<li><a href="Implementation/attribute%20changed.js" target="detail">attribute changed</a>
<ul>
<li><a href="Implementation/attribute%20changed/reconcileAssignments.js" target="detail">reconcileAssignments</a>
</li>
</ul>
</li>
<li><a href="Implementation/button.js" target="detail">button</a>
</li>
<li><a href="Implementation/CSS.css" target="detail">CSS</a>
</li>
<li><a href="Implementation/task%20template.html" target="detail">task template</a>
</li>
<li><a href="Implementation/new_reminder%20handler.js" target="detail">new_reminder handler</a>
</li>
<li><a href="Implementation/task_alerts%20handler.js" target="detail">task_alerts handler</a>
</li>
<li><a href="Implementation/reminder%20template.html" target="detail">reminder template</a>
</li>
<li><a href="Implementation/daily%20reminder%20template.html" target="detail">daily reminder template</a>
</li>
<li><a href="Implementation/attribute%20sync%20button.js" target="detail">attribute sync button</a>
<ul>
<li><a href="Implementation/attribute%20changed/reconcileAssignments.js" target="detail">reconcileAssignments</a>
</li>
</ul>
</li>
<li><a href="Implementation/event%20template.html" target="detail">event template</a>
</li>
<li><a href="Implementation/new_event%20handler.js" target="detail">new_event handler</a>
</li>
<li><a href="Implementation/event_alerts%20handler.js" target="detail">event_alerts handler</a>
</li>
</ul>
</li>
</ul>
</body>
</html>

339
notes/style.css Normal file
View File

@ -0,0 +1,339 @@
/* !!!!!! TRILIUM CUSTOM CHANGES !!!!!! */
.printed-content .ck-widget__selection-handle, .printed-content .ck-widget__type-around { /* gets rid of triangles: https://github.com/zadam/trilium/issues/1129 */
display: none;
}
/*
* CKEditor 5 (v24.0.0) content styles.
* Generated on Thu, 10 Dec 2020 08:15:26 GMT.
* For more information, check out https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/content-styles.html
*/
:root {
--ck-color-mention-background: hsla(341, 100%, 30%, 0.1);
--ck-color-mention-text: hsl(341, 100%, 30%);
--ck-highlight-marker-blue: hsl(201, 97%, 72%);
--ck-highlight-marker-green: hsl(120, 93%, 68%);
--ck-highlight-marker-pink: hsl(345, 96%, 73%);
--ck-highlight-marker-yellow: hsl(60, 97%, 73%);
--ck-highlight-pen-green: hsl(112, 100%, 27%);
--ck-highlight-pen-red: hsl(0, 85%, 49%);
--ck-image-style-spacing: 1.5em;
--ck-todo-list-checkmark-size: 16px;
}
/* ckeditor5-image/theme/imageresize.css */
.ck-content .image.image_resized {
max-width: 100%;
display: block;
box-sizing: border-box;
}
/* ckeditor5-image/theme/imageresize.css */
.ck-content .image.image_resized img {
width: 100%;
}
/* ckeditor5-image/theme/imageresize.css */
.ck-content .image.image_resized > figcaption {
display: block;
}
/* ckeditor5-image/theme/imagestyle.css */
.ck-content .image-style-side {
float: right;
margin-left: var(--ck-image-style-spacing);
max-width: 50%;
}
/* ckeditor5-image/theme/imagestyle.css */
.ck-content .image-style-align-left {
float: left;
margin-right: var(--ck-image-style-spacing);
}
/* ckeditor5-image/theme/imagestyle.css */
.ck-content .image-style-align-center {
margin-left: auto;
margin-right: auto;
}
/* ckeditor5-image/theme/imagestyle.css */
.ck-content .image-style-align-right {
float: right;
margin-left: var(--ck-image-style-spacing);
}
/* ckeditor5-image/theme/image.css */
.ck-content .image {
display: table;
clear: both;
text-align: center;
margin: 1em auto;
}
/* ckeditor5-image/theme/image.css */
.ck-content .image img {
display: block;
margin: 0 auto;
max-width: 100%;
min-width: 50px;
}
/* ckeditor5-image/theme/imagecaption.css */
.ck-content .image > figcaption {
display: table-caption;
caption-side: bottom;
word-break: break-word;
color: hsl(0, 0%, 20%);
background-color: hsl(0, 0%, 97%);
padding: .6em;
font-size: .75em;
outline-offset: -1px;
}
/* ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-yellow {
background-color: var(--ck-highlight-marker-yellow);
}
/* ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-green {
background-color: var(--ck-highlight-marker-green);
}
/* ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-pink {
background-color: var(--ck-highlight-marker-pink);
}
/* ckeditor5-highlight/theme/highlight.css */
.ck-content .marker-blue {
background-color: var(--ck-highlight-marker-blue);
}
/* ckeditor5-highlight/theme/highlight.css */
.ck-content .pen-red {
color: var(--ck-highlight-pen-red);
background-color: transparent;
}
/* ckeditor5-highlight/theme/highlight.css */
.ck-content .pen-green {
color: var(--ck-highlight-pen-green);
background-color: transparent;
}
/* ckeditor5-font/theme/fontsize.css */
.ck-content .text-tiny {
font-size: .7em;
}
/* ckeditor5-font/theme/fontsize.css */
.ck-content .text-small {
font-size: .85em;
}
/* ckeditor5-font/theme/fontsize.css */
.ck-content .text-big {
font-size: 1.4em;
}
/* ckeditor5-font/theme/fontsize.css */
.ck-content .text-huge {
font-size: 1.8em;
}
/* ckeditor5-block-quote/theme/blockquote.css */
.ck-content blockquote {
overflow: hidden;
padding-right: 1.5em;
padding-left: 1.5em;
margin-left: 0;
margin-right: 0;
font-style: italic;
border-left: solid 5px hsl(0, 0%, 80%);
}
/* ckeditor5-block-quote/theme/blockquote.css */
.ck-content[dir="rtl"] blockquote {
border-left: 0;
border-right: solid 5px hsl(0, 0%, 80%);
}
/* ckeditor5-basic-styles/theme/code.css */
.ck-content code {
background-color: hsla(0, 0%, 78%, 0.3);
padding: .15em;
border-radius: 2px;
}
/* ckeditor5-table/theme/table.css */
.ck-content .table {
margin: 1em auto;
display: table;
}
/* ckeditor5-table/theme/table.css */
.ck-content .table table {
border-collapse: collapse;
border-spacing: 0;
width: 100%;
height: 100%;
border: 1px double hsl(0, 0%, 70%);
}
/* ckeditor5-table/theme/table.css */
.ck-content .table table td,
.ck-content .table table th {
min-width: 2em;
padding: .4em;
border: 1px solid hsl(0, 0%, 75%);
}
/* ckeditor5-table/theme/table.css */
.ck-content .table table th {
font-weight: bold;
background: hsla(0, 0%, 0%, 5%);
}
/* ckeditor5-table/theme/table.css */
.ck-content[dir="rtl"] .table th {
text-align: right;
}
/* ckeditor5-table/theme/table.css */
.ck-content[dir="ltr"] .table th {
text-align: left;
}
/* ckeditor5-page-break/theme/pagebreak.css */
.ck-content .page-break {
position: relative;
clear: both;
padding: 5px 0;
display: flex;
align-items: center;
justify-content: center;
}
/* ckeditor5-page-break/theme/pagebreak.css */
.ck-content .page-break::after {
content: '';
position: absolute;
border-bottom: 2px dashed hsl(0, 0%, 77%);
width: 100%;
}
/* ckeditor5-page-break/theme/pagebreak.css */
.ck-content .page-break__label {
position: relative;
z-index: 1;
padding: .3em .6em;
display: block;
text-transform: uppercase;
border: 1px solid hsl(0, 0%, 77%);
border-radius: 2px;
font-family: Helvetica, Arial, Tahoma, Verdana, Sans-Serif;
font-size: 0.75em;
font-weight: bold;
color: hsl(0, 0%, 20%);
background: hsl(0, 0%, 100%);
box-shadow: 2px 2px 1px hsla(0, 0%, 0%, 0.15);
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* ckeditor5-media-embed/theme/mediaembed.css */
.ck-content .media {
clear: both;
margin: 1em 0;
display: block;
min-width: 15em;
}
/* ckeditor5-list/theme/todolist.css */
.ck-content .todo-list {
list-style: none;
}
/* ckeditor5-list/theme/todolist.css */
.ck-content .todo-list li {
margin-bottom: 5px;
}
/* ckeditor5-list/theme/todolist.css */
.ck-content .todo-list li .todo-list {
margin-top: 5px;
}
/* ckeditor5-list/theme/todolist.css */
.ck-content .todo-list .todo-list__label > input {
-webkit-appearance: none;
display: inline-block;
position: relative;
width: var(--ck-todo-list-checkmark-size);
height: var(--ck-todo-list-checkmark-size);
vertical-align: middle;
border: 0;
left: -25px;
margin-right: -15px;
right: 0;
margin-left: 0;
}
/* ckeditor5-list/theme/todolist.css */
.ck-content .todo-list .todo-list__label > input::before {
display: block;
position: absolute;
box-sizing: border-box;
content: '';
width: 100%;
height: 100%;
border: 1px solid hsl(0, 0%, 20%);
border-radius: 2px;
transition: 250ms ease-in-out box-shadow, 250ms ease-in-out background, 250ms ease-in-out border;
}
/* ckeditor5-list/theme/todolist.css */
.ck-content .todo-list .todo-list__label > input::after {
display: block;
position: absolute;
box-sizing: content-box;
pointer-events: none;
content: '';
left: calc( var(--ck-todo-list-checkmark-size) / 3 );
top: calc( var(--ck-todo-list-checkmark-size) / 5.3 );
width: calc( var(--ck-todo-list-checkmark-size) / 5.3 );
height: calc( var(--ck-todo-list-checkmark-size) / 2.6 );
border-style: solid;
border-color: transparent;
border-width: 0 calc( var(--ck-todo-list-checkmark-size) / 8 ) calc( var(--ck-todo-list-checkmark-size) / 8 ) 0;
transform: rotate(45deg);
}
/* ckeditor5-list/theme/todolist.css */
.ck-content .todo-list .todo-list__label > input[checked]::before {
background: hsl(126, 64%, 41%);
border-color: hsl(126, 64%, 41%);
}
/* ckeditor5-list/theme/todolist.css */
.ck-content .todo-list .todo-list__label > input[checked]::after {
border-color: hsl(0, 0%, 100%);
}
/* ckeditor5-list/theme/todolist.css */
.ck-content .todo-list .todo-list__label .todo-list__label__description {
vertical-align: middle;
}
/* ckeditor5-html-embed/theme/htmlembed.css */
.ck-content .raw-html-embed {
margin: 1em auto;
min-width: 15em;
font-style: normal;
}
/* ckeditor5-horizontal-line/theme/horizontalline.css */
.ck-content hr {
margin: 15px 0;
height: 4px;
background: hsl(0, 0%, 87%);
border: 0;
}
/* ckeditor5-code-block/theme/codeblock.css */
.ck-content pre {
padding: 1em;
color: hsl(0, 0%, 20.8%);
background: hsla(0, 0%, 78%, 0.3);
border: 1px solid hsl(0, 0%, 77%);
border-radius: 2px;
text-align: left;
direction: ltr;
tab-size: 4;
white-space: pre-wrap;
font-style: normal;
min-width: 200px;
}
/* ckeditor5-code-block/theme/codeblock.css */
.ck-content pre code {
background: unset;
padding: 0;
border-radius: 0;
}
/* ckeditor5-mention/theme/mention.css */
.ck-content .mention {
background: var(--ck-color-mention-background);
color: var(--ck-color-mention-text);
}
@media print {
/* ckeditor5-page-break/theme/pagebreak.css */
.ck-content .page-break {
padding: 0;
}
/* ckeditor5-page-break/theme/pagebreak.css */
.ck-content .page-break::after {
display: none;
}
}

View File

@ -1,29 +0,0 @@
// Create as JS Backend note with attributes:
// ~targetTemplate=@task template (included in Trilium task manager)
// #customRequestHandler=task_alerts
// ~targetTemplateReminder=@reminder template (see new_reminder.js)
const {req, res} = api;
const targetTemplate = await api.currentNote.getRelationValue('targetTemplate');
const tasks = await api.getNotesWithLabel("template", targetTemplate);
let tasksData = [];
for (const task of tasks) {
tasksData.push({
attributes: await task.getAttributes(),
...task
});
}
const targetTemplateReminder = await api.currentNote.getRelationValue('targetTemplateReminder');
const reminders = await api.getNotesWithLabel("template", targetTemplateReminder);
for (const task of reminders) {
tasksData.push({
attributes: await task.getAttributes(),
...task
});
}
res.send(tasksData);