diff --git a/docs/User Guide/!!!meta.json b/docs/User Guide/!!!meta.json index c565494c5..3acb20f0d 100644 --- a/docs/User Guide/!!!meta.json +++ b/docs/User Guide/!!!meta.json @@ -4641,13 +4641,6 @@ "type": "text", "mime": "text/markdown", "attributes": [ - { - "type": "relation", - "name": "imageLink", - "value": "DVJl4l3T8EG2", - "isInheritable": false, - "position": 10 - }, { "type": "relation", "name": "internalLink", @@ -4662,13 +4655,6 @@ "isInheritable": false, "position": 30 }, - { - "type": "relation", - "name": "internalLink", - "value": "wX4HbRucYSDD", - "isInheritable": false, - "position": 40 - }, { "type": "relation", "name": "internalLink", @@ -4703,11 +4689,108 @@ "value": "scripts", "isInheritable": false, "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "TjLYAo3JMO8X", + "isInheritable": false, + "position": 90 } ], "format": "markdown", "dataFileName": "Scripts.md", - "attachments": [] + "attachments": [], + "dirFileName": "Scripts", + "children": [ + { + "isClone": false, + "noteId": "TjLYAo3JMO8X", + "notePath": [ + "pOsGYCXsbNQG", + "KSZ04uQ2D1St", + "6f9hih2hXXZk", + "CdNpE2pqjmI6", + "TjLYAo3JMO8X" + ], + "title": "\"New Task\" launcher button", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "xYjQUYhpbUEW", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "xYmIYSP6wE3F", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "6f9hih2hXXZk", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "zEY4DaJG4YT5", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "yIhgI5H7A2Sm", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "m1lbrzyKDaRB", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "s8alTXmpFR61", + "isInheritable": false, + "position": 70 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-task", + "isInheritable": false, + "position": 80 + } + ], + "format": "markdown", + "dataFileName": "New Task launcher button.md", + "attachments": [ + { + "attachmentId": "9C2JA6tdtRpN", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "New Task launcher button_i.png" + } + ] + } + ] }, { "isClone": false, diff --git a/docs/User Guide/User Guide/Note Types/Code/Scripts.md b/docs/User Guide/User Guide/Note Types/Code/Scripts.md index ecd15270c..1945d6245 100644 --- a/docs/User Guide/User Guide/Note Types/Code/Scripts.md +++ b/docs/User Guide/User Guide/Note Types/Code/Scripts.md @@ -10,28 +10,15 @@ To go further I must explain basic architecture of Trilium - in its essence it i So we have frontend and backend, each with their own set of responsibilities, but their common feature is that they both run JavaScript code. Add to this the fact, that we're able to create JavaScript \[\[code notes\]\] and we're onto something. -## Button use case +## Use cases -Let's take a look at our demo script (shipped with default Trilium [database](../../Advanced%20Usage/Database.md)) - Task manager. One of the things this script does is adding a button to the Trilium interface which will allow user to easily add new Task (TODO item). +* [A button launcher button](Scripts/New%20Task%20launcher%20button.md) -![](../../Attachments/button-script.png) - -First take a look at the red circle all the way on the top - this what we want to achieve - new button in UI which will create new note representing a task/todo item. - -Red point below the first one marks the note type we have created for this script - it's "JavaScript frontend". It's frontend because adding button to UI is clearly frontend responsibility. - -In the note content you can see the code which calls one of the API methods, this one is specifically meant to add new buttons. Code needs to set few button properties: - -* button title -* icon which should appear on the button -* optional shortcut under which you can trigger the button -* most importantly "action" - what must happen when button is clicked - -### Action handler +## Action handler Saving the note to the database is backend's responsibility, so we immediately pass control to the backend and ask it to create a note. Once this is done, we show the newly created note so that the user can set the task title and maybe some attributes. -### Script execution +## Script execution So we have a script which will add the button to the toolbar. But how can we execute it? One possibility is to click on "play" icon (marked by red circle). The problem with this is that this UI change is time bound by Trilium runtime so when we restart Trilium, button won't be there. @@ -41,7 +28,7 @@ The solution is marked by red circle at the bottom - this note has [label](../.. (`#run=frontendStartup` does not work for [Mobile frontend](../../Installation%20%26%20Setup/Mobile%20Frontend.md) - if you want to have scripts running there, give the script `#run=mobileStartup` label) -### More showcases +## More showcases You can see more scripting with explanation in [Advanced showcases](../../Advanced%20Usage/Advanced%20Showcases.md) diff --git a/docs/User Guide/User Guide/Note Types/Code/Scripts/New Task launcher button.md b/docs/User Guide/User Guide/Note Types/Code/Scripts/New Task launcher button.md new file mode 100644 index 000000000..ef2e11238 --- /dev/null +++ b/docs/User Guide/User Guide/Note Types/Code/Scripts/New Task launcher button.md @@ -0,0 +1,47 @@ +# "New Task" launcher button +In this example we are going to extend the functionality of the [Task Manager](../../../Advanced%20Usage/Advanced%20Showcases/Task%20Manager.md) showcase (which comes by default with Trilium) by adding a button in the [Launch Bar](../../../Basic%20Concepts%20and%20Features/UI%20Elements/Launch%20Bar.md)  (![](New%20Task%20launcher%20button_i.png)) to create a new task automatically and open it. + +## Creating the note + +1. First, create a new [Code](../../Code.md) note type with the _JS frontend_ language. +2. Define the `#run=frontendStartup` label in [Attributes](../../../Advanced%20Usage/Attributes.md). + +## Content of the script + +Copy-paste the following script: + +```javascript +api.addButtonToToolbar({ + title: "New task", + icon: "task", + shortcut: "alt+n", + action: async () => { + const taskNoteId = await api.runOnBackend(() => { + const todoRootNote = api.getNoteWithLabel("taskTodoRoot"); + const resp = api.createTextNote(todoRootNote.noteId, "New task", "") + return resp.note.noteId; + }); + + await api.waitUntilSynced(); + await api.activateNewNote(taskNoteId); + } +}); +``` + +## Testing the functionality + +Since we set the script to be run on start-up, all we need to do is to [refresh the application](../../../Troubleshooting/Refreshing%20the%20application.md). + +## Understanding how the script works + +
api.addButtonToToolbar({
+	title: "New task",
+    icon: "task",
+    shortcut: "alt+n",
+    action: async () => {
+    	// [...]
+    }
+});

This uses the Front-end API to create a icon in the Launch Bar, by specifying:

  • A title
  • A corresponding boxicons icon (without the bx- prefix).
  • Optionally, a keyboard shortcut to assign to it.
  • The action, which will be executed when the button is pressed.
const taskNoteId = await api.runOnBackend(() => {
+    // Shown below.           
+    return resp.note.noteId;
+});
  • This portion of code is actually executed on the server (backend) and not on the client (i.e. browser).
    • The reason is that the creating notes is the responsibility of the server.
  • Here we can also see that it is possible to return results from the server execution and read them in the client (taskNoteId).
const todoRootNote = api.getNoteWithLabel("taskTodoRoot");
  • Here we identify a note with the label #taskTodoRoot. This is how the Task Manager showcase knows where to place all the different tasks.
  • Normally this might return a null value if no such note could be identified, but error handling is outside the scope of this example. 
const resp = api.createTextNote(todoRootNote.noteId, "New task", "")
  • We create a new child note within the to-do root note (first argument) with the title “New task" (second argument) and no content by default (third argument).
await api.waitUntilSynced();
  • Back on the client, since we created a new note on the server, we now need to wait for the change to be reflected in the client.
await api.activateNewNote(taskNoteId);
  • Since we know the ID of the newly created note, all we have to do now is to show this note to the user.
\ No newline at end of file diff --git a/docs/User Guide/User Guide/Note Types/Code/Scripts/New Task launcher button_i.png b/docs/User Guide/User Guide/Note Types/Code/Scripts/New Task launcher button_i.png new file mode 100644 index 000000000..7a1b9c23e Binary files /dev/null and b/docs/User Guide/User Guide/Note Types/Code/Scripts/New Task launcher button_i.png differ diff --git a/src/public/app/doc_notes/en/User Guide/!!!meta.json b/src/public/app/doc_notes/en/User Guide/!!!meta.json index 7f4560e7c..88eb70db7 100644 --- a/src/public/app/doc_notes/en/User Guide/!!!meta.json +++ b/src/public/app/doc_notes/en/User Guide/!!!meta.json @@ -4641,13 +4641,6 @@ "type": "text", "mime": "text/markdown", "attributes": [ - { - "type": "relation", - "name": "imageLink", - "value": "DVJl4l3T8EG2", - "isInheritable": false, - "position": 10 - }, { "type": "relation", "name": "internalLink", @@ -4662,13 +4655,6 @@ "isInheritable": false, "position": 30 }, - { - "type": "relation", - "name": "internalLink", - "value": "wX4HbRucYSDD", - "isInheritable": false, - "position": 40 - }, { "type": "relation", "name": "internalLink", @@ -4703,11 +4689,108 @@ "value": "scripts", "isInheritable": false, "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "TjLYAo3JMO8X", + "isInheritable": false, + "position": 90 } ], "format": "html", "dataFileName": "Scripts.html", - "attachments": [] + "attachments": [], + "dirFileName": "Scripts", + "children": [ + { + "isClone": false, + "noteId": "TjLYAo3JMO8X", + "notePath": [ + "pOsGYCXsbNQG", + "KSZ04uQ2D1St", + "6f9hih2hXXZk", + "CdNpE2pqjmI6", + "TjLYAo3JMO8X" + ], + "title": "\"New Task\" launcher button", + "notePosition": 20, + "prefix": null, + "isExpanded": false, + "type": "text", + "mime": "text/html", + "attributes": [ + { + "type": "relation", + "name": "internalLink", + "value": "xYjQUYhpbUEW", + "isInheritable": false, + "position": 10 + }, + { + "type": "relation", + "name": "internalLink", + "value": "xYmIYSP6wE3F", + "isInheritable": false, + "position": 20 + }, + { + "type": "relation", + "name": "internalLink", + "value": "6f9hih2hXXZk", + "isInheritable": false, + "position": 30 + }, + { + "type": "relation", + "name": "internalLink", + "value": "zEY4DaJG4YT5", + "isInheritable": false, + "position": 40 + }, + { + "type": "relation", + "name": "internalLink", + "value": "yIhgI5H7A2Sm", + "isInheritable": false, + "position": 50 + }, + { + "type": "relation", + "name": "internalLink", + "value": "m1lbrzyKDaRB", + "isInheritable": false, + "position": 60 + }, + { + "type": "relation", + "name": "internalLink", + "value": "s8alTXmpFR61", + "isInheritable": false, + "position": 70 + }, + { + "type": "label", + "name": "iconClass", + "value": "bx bx-task", + "isInheritable": false, + "position": 80 + } + ], + "format": "html", + "dataFileName": "New Task launcher button.html", + "attachments": [ + { + "attachmentId": "9C2JA6tdtRpN", + "title": "image.png", + "role": "image", + "mime": "image/png", + "position": 10, + "dataFileName": "New Task launcher button_i.png" + } + ] + } + ] }, { "isClone": false, diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Note Types/Code/Scripts.html b/src/public/app/doc_notes/en/User Guide/User Guide/Note Types/Code/Scripts.html index fbfa1a579..8d1ebcf07 100644 --- a/src/public/app/doc_notes/en/User Guide/User Guide/Note Types/Code/Scripts.html +++ b/src/public/app/doc_notes/en/User Guide/User Guide/Note Types/Code/Scripts.html @@ -31,35 +31,17 @@ but their common feature is that they both run JavaScript code. Add to this the fact, that we're able to create JavaScript [[code notes]] and we're onto something.

-

Button use case

-

Let's take a look at our demo script (shipped with default Trilium database) - - Task manager. One of the things this script does is adding a button to - the Trilium interface which will allow user to easily add new Task (TODO - item).

-

- -

-

First take a look at the red circle all the way on the top - this what - we want to achieve - new button in UI which will create new note representing - a task/todo item.

-

Red point below the first one marks the note type we have created for - this script - it's "JavaScript frontend". It's frontend because adding - button to UI is clearly frontend responsibility.

-

In the note content you can see the code which calls one of the API methods, - this one is specifically meant to add new buttons. Code needs to set few - button properties:

+

Use cases

-

Action handler

+

Action handler

Saving the note to the database is backend's responsibility, so we immediately pass control to the backend and ask it to create a note. Once this is done, we show the newly created note so that the user can set the task title and maybe some attributes.

-

Script execution

+

Script execution

So we have a script which will add the button to the toolbar. But how can we execute it? One possibility is to click on "play" icon (marked by red circle). The problem with this is that this UI change is time bound @@ -72,7 +54,7 @@ Trilium frontend starts up.

(#run=frontendStartup does not work for Mobile frontend - if you want to have scripts running there, give the script #run=mobileStartup label)

-

More showcases

+

More showcases

You can see more scripting with explanation in Advanced showcases

Events

diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Note Types/Code/Scripts/New Task launcher button.html b/src/public/app/doc_notes/en/User Guide/User Guide/Note Types/Code/Scripts/New Task launcher button.html new file mode 100644 index 000000000..950634d05 --- /dev/null +++ b/src/public/app/doc_notes/en/User Guide/User Guide/Note Types/Code/Scripts/New Task launcher button.html @@ -0,0 +1,150 @@ + + + + + + + + "New Task" launcher button + + + +
+

"New Task" launcher button

+ +
+

In this example we are going to extend the functionality of the  + Task Manager showcase (which comes by default with Trilium) by + adding a button in the Launch Bar  + ( + ) to create a new task automatically and open it.

+

Creating the note

+
    +
  1. First, create a new Code note + type with the JS frontend language.
  2. +
  3. Define the #run=frontendStartup label in Attributes.
  4. +
+

Content of the script

+

Copy-paste the following script:

api.addButtonToToolbar({
+	title: "New task",
+    icon: "task",
+    shortcut: "alt+n",
+    action: async () => {
+    	const taskNoteId = await api.runOnBackend(() => {
+        	const todoRootNote = api.getNoteWithLabel("taskTodoRoot");
+            const resp = api.createTextNote(todoRootNote.noteId, "New task", "")           
+            return resp.note.noteId;
+        });
+        
+        await api.waitUntilSynced();
+        await api.activateNewNote(taskNoteId);
+    }
+});
+

Testing the functionality

+

Since we set the script to be run on start-up, all we need to do is to + refresh the application.

+

Understanding how the script works

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
api.addButtonToToolbar({
+	title: "New task",
+    icon: "task",
+    shortcut: "alt+n",
+    action: async () => {
+    	// [...]
+    }
+});
+
+

This uses the Front-end API to + create a icon in the Launch Bar, + by specifying:

+
    +
  • A title
  • +
  • A corresponding boxicons icon (without the bx- prefix).
  • +
  • Optionally, a keyboard shortcut to assign to it.
  • +
  • The action, which will be executed when the button is pressed.
  • +
+
const taskNoteId = await api.runOnBackend(() => {
+    // Shown below.           
+    return resp.note.noteId;
+});
+
+
    +
  • This portion of code is actually executed on the server (backend) and + not on the client (i.e. browser). +
      +
    • The reason is that the creating notes is the responsibility of the server.
    • +
    +
  • +
  • Here we can also see that it is possible to return results from the server + execution and read them in the client (taskNoteId).
  • +
+
const todoRootNote = api.getNoteWithLabel("taskTodoRoot");
+
+
    +
  • Here we identify a note with the label #taskTodoRoot. + This is how the Task Manager showcase + knows where to place all the different tasks.
  • +
  • Normally this might return a null value if no such note could + be identified, but error handling is outside the scope of this example. 
  • +
+
const resp = api.createTextNote(todoRootNote.noteId, "New task", "")
+
+
    +
  • We create a new child note within the to-do root note (first argument) + with the title “New task" (second argument) and no content by default (third + argument).
  • +
+
await api.waitUntilSynced();
+
+
    +
  • Back on the client, since we created a new note on the server, we now + need to wait for the change to be reflected in the client.
  • +
+
await api.activateNewNote(taskNoteId);
+
+
    +
  • Since we know the ID of + the newly created note, all we have to do now is to show this note to the + user.
  • +
+
+
+
+
+ + + \ No newline at end of file diff --git a/src/public/app/doc_notes/en/User Guide/User Guide/Note Types/Code/Scripts/New Task launcher button_i.png b/src/public/app/doc_notes/en/User Guide/User Guide/Note Types/Code/Scripts/New Task launcher button_i.png new file mode 100644 index 000000000..7a1b9c23e Binary files /dev/null and b/src/public/app/doc_notes/en/User Guide/User Guide/Note Types/Code/Scripts/New Task launcher button_i.png differ diff --git a/src/public/app/doc_notes/en/User Guide/navigation.html b/src/public/app/doc_notes/en/User Guide/navigation.html index a8f5846de..00a16f495 100644 --- a/src/public/app/doc_notes/en/User Guide/navigation.html +++ b/src/public/app/doc_notes/en/User Guide/navigation.html @@ -240,6 +240,11 @@
  • Code