From e5adbaac626974526bd8164a98998dbcd3edddec Mon Sep 17 00:00:00 2001 From: Benjamin Kaiser Date: Mon, 6 Nov 2023 13:41:00 +1000 Subject: [PATCH] Add frontend note prompt API --- docs/frontend_api/FrontendScriptApi.html | 178 +++++++++++------- src/public/app/services/dialog.js | 8 +- .../app/services/frontend_script_api.js | 5 + src/public/app/widgets/dialogs/add_link.js | 36 +++- 4 files changed, 148 insertions(+), 79 deletions(-) diff --git a/docs/frontend_api/FrontendScriptApi.html b/docs/frontend_api/FrontendScriptApi.html index 85072e613..3c1334cfe 100644 --- a/docs/frontend_api/FrontendScriptApi.html +++ b/docs/frontend_api/FrontendScriptApi.html @@ -49,8 +49,7 @@
-

This is the main frontend API interface for scripts. All the properties and methods are published in the "api" object -available in the JS frontend notes. You can use e.g. api.showMessage(api.startNote.title);

+

This is the main frontend API interface for scripts. All the properties and methods are published in the "api" object available in the JS frontend notes. You can use e.g. api.showMessage(api.startNote.title);

@@ -462,7 +461,7 @@ available in the JS frontend notes. You can use e.g. api.showMessage(api.s
Source:
@@ -558,8 +557,7 @@ available in the JS frontend notes. You can use e.g. api.showMessage(api.s
- day.js library for date manipulation. -See https://day.js.org for documentation + day.js library for date manipulation. See https://day.js.org for documentation
@@ -632,6 +630,68 @@ See https://day.js.org for documentation +

getNoteAutocomplete

+ + + + +
+ Show prompt for selecting a note to the user. +
+ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Source:
+
+ + + + + + + +
+ + + + + + + +

originEntity :object|null

@@ -1275,8 +1335,7 @@ See https://day.js.org for documentation - id of the button, used to identify the old instances of this button to be replaced - ID is optional because of BC, but not specifying it is deprecated. ID can be alphanumeric only. + id of the button, used to identify the old instances of this button to be replaced ID is optional because of BC, but not specifying it is deprecated. ID can be alphanumeric only. @@ -1378,8 +1437,7 @@ See https://day.js.org for documentation -
Deprecated:
  • you can now create/modify launchers in the top-left Menu -> Configure Launchbar - for special needs there's also backend API's createOrUpdateLauncher()
+
Deprecated:
  • you can now create/modify launchers in the top-left Menu -> Configure Launchbar for special needs there's also backend API's createOrUpdateLauncher()
@@ -1530,7 +1588,7 @@ See https://day.js.org for documentation
Source:
@@ -1696,8 +1754,7 @@ See https://day.js.org for documentation - specify namespace of the handler for the cases where call for bind may be repeated. - If a handler with this ID exists, it's replaced by the new handler. + specify namespace of the handler for the cases where call for bind may be repeated. If a handler with this ID exists, it's replaced by the new handler. @@ -1738,7 +1795,7 @@ See https://day.js.org for documentation
Source:
@@ -2157,7 +2214,7 @@ See https://day.js.org for documentation
Source:
@@ -2469,7 +2526,7 @@ See https://day.js.org for documentation
Source:
@@ -2624,7 +2681,7 @@ See https://day.js.org for documentation
Source:
@@ -2730,7 +2787,7 @@ See https://day.js.org for documentation
Source:
@@ -2840,7 +2897,7 @@ See https://day.js.org for documentation
Source:
@@ -2946,7 +3003,7 @@ See https://day.js.org for documentation
Source:
@@ -3052,7 +3109,7 @@ See https://day.js.org for documentation
Source:
@@ -3162,7 +3219,7 @@ See https://day.js.org for documentation
Source:
@@ -3268,7 +3325,7 @@ See https://day.js.org for documentation
Source:
@@ -3334,8 +3391,7 @@ See https://day.js.org for documentation
- Get access to the widget handling note detail. Methods like `getWidgetType()` and `getTypeWidget()` to get to the -implementation of actual widget type. + Get access to the widget handling note detail. Methods like `getWidgetType()` and `getTypeWidget()` to get to the implementation of actual widget type.
@@ -3379,7 +3435,7 @@ implementation of actual widget type.
Source:
@@ -3534,7 +3590,7 @@ implementation of actual widget type.
Source:
@@ -3689,7 +3745,7 @@ implementation of actual widget type.
Source:
@@ -3751,8 +3807,7 @@ implementation of actual widget type.
- Instance name identifies particular Trilium instance. It can be useful for scripts -if some action needs to happen on only one specific instance. + Instance name identifies particular Trilium instance. It can be useful for scripts if some action needs to happen on only one specific instance.
@@ -3898,7 +3953,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -4057,7 +4112,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -4119,8 +4174,7 @@ if some action needs to happen on only one specific instance.
- Returns note by given noteId. If note is missing from the cache, it's loaded. -* + Returns note by given noteId. If note is missing from the cache, it's loaded. *
@@ -4315,7 +4369,7 @@ if some action needs to happen on only one specific instance.
Source:
@@ -4381,10 +4435,7 @@ if some action needs to happen on only one specific instance.
- Returns list of notes. If note is missing from the cache, it's loaded. - -This is often used to bulk-fill the cache with notes which would have to be picked one by one -otherwise (by e.g. createLink()) + Returns list of notes. If note is missing from the cache, it's loaded. This is often used to bulk-fill the cache with notes which would have to be picked one by one otherwise (by e.g. createLink())
@@ -4626,7 +4677,7 @@ otherwise (by e.g. createLink())
Source:
@@ -4781,7 +4832,7 @@ otherwise (by e.g. createLink())
Source:
@@ -4936,7 +4987,7 @@ otherwise (by e.g. createLink())
Source:
@@ -5086,7 +5137,7 @@ otherwise (by e.g. createLink())
Source:
@@ -5771,7 +5822,7 @@ otherwise (by e.g. createLink())
Source:
@@ -5945,7 +5996,7 @@ otherwise (by e.g. createLink())
Source:
@@ -6100,7 +6151,7 @@ otherwise (by e.g. createLink())
Source:
@@ -6254,7 +6305,7 @@ otherwise (by e.g. createLink())
Source:
@@ -6453,13 +6504,7 @@ otherwise (by e.g. createLink())
- Executes given anonymous function on the backend. -Internally this serializes the anonymous function into string and sends it to backend via AJAX. -This function is meant for advanced needs where an async function is necessary. -In this case, the automatic request-scoped transaction management is not applied, -and you need to manually define transaction via api.transactional(). - -If you have a synchronous function, please use api.runOnBackend(). + Executes given anonymous function on the backend. Internally this serializes the anonymous function into string and sends it to backend via AJAX. This function is meant for advanced needs where an async function is necessary. In this case, the automatic request-scoped transaction management is not applied, and you need to manually define transaction via api.transactional(). If you have a synchronous function, please use api.runOnBackend().
@@ -6644,10 +6689,7 @@ If you have a synchronous function, please use api.runOnBackend().
- Executes given anonymous function on the backend. -Internally this serializes the anonymous function into string and sends it to backend via AJAX. -Please make sure that the supplied function is synchronous. Only sync functions will work correctly -with transaction management. If you really know what you're doing, you can call api.runAsyncOnBackendWithManualTransactionHandling() + Executes given anonymous function on the backend. Internally this serializes the anonymous function into string and sends it to backend via AJAX. Please make sure that the supplied function is synchronous. Only sync functions will work correctly with transaction management. If you really know what you're doing, you can call api.runAsyncOnBackendWithManualTransactionHandling()
@@ -6832,8 +6874,7 @@ with transaction management. If you really know what you're doing, you can call
- This is a powerful search method - you can search by attributes and their values, e.g.: -"#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search + This is a powerful search method - you can search by attributes and their values, e.g.: "#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
@@ -6988,8 +7029,7 @@ with transaction management. If you really know what you're doing, you can call
- This is a powerful search method - you can search by attributes and their values, e.g.: -"#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search + This is a powerful search method - you can search by attributes and their values, e.g.: "#dateModified =* MONTH AND #log". See full documentation for all options at: https://github.com/zadam/trilium/wiki/Search
@@ -7237,7 +7277,7 @@ with transaction management. If you really know what you're doing, you can call
Source:
@@ -7388,7 +7428,7 @@ with transaction management. If you really know what you're doing, you can call
Source:
@@ -8408,7 +8448,7 @@ with transaction management. If you really know what you're doing, you can call
Source:
@@ -8568,7 +8608,7 @@ with transaction management. If you really know what you're doing, you can call
Source:
@@ -8612,11 +8652,7 @@ with transaction management. If you really know what you're doing, you can call
- Trilium runs in a backend and frontend process, when something is changed on the backend from a script, -frontend will get asynchronously synchronized. - -This method returns a promise which resolves once all the backend -> frontend synchronization is finished. -Typical use case is when a new note has been created, we should wait until it is synced into frontend and only then activate it. + Trilium runs in a backend and frontend process, when something is changed on the backend from a script, frontend will get asynchronously synchronized. This method returns a promise which resolves once all the backend -> frontend synchronization is finished. Typical use case is when a new note has been created, we should wait until it is synced into frontend and only then activate it.
@@ -8660,7 +8696,7 @@ Typical use case is when a new note has been created, we should wait until it is
Source:
diff --git a/src/public/app/services/dialog.js b/src/public/app/services/dialog.js index 325a65146..4241fa138 100644 --- a/src/public/app/services/dialog.js +++ b/src/public/app/services/dialog.js @@ -23,9 +23,15 @@ async function prompt(props) { appContext.triggerCommand("showPromptDialog", {...props, callback: res})); } +async function promptNoteAutocomplete(props) { + return new Promise(res => + appContext.triggerCommand("showAddLinkDialog", {...props, callback: res})); +} + export default { info, confirm, confirmDeleteNoteBoxWithNote, - prompt + prompt, + promptNoteAutocomplete }; diff --git a/src/public/app/services/frontend_script_api.js b/src/public/app/services/frontend_script_api.js index 989a49879..fcabf445a 100644 --- a/src/public/app/services/frontend_script_api.js +++ b/src/public/app/services/frontend_script_api.js @@ -372,6 +372,11 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, $contain */ this.showPromptDialog = dialogService.prompt; + /** + * Show prompt for selecting a note to the user. + */ + this.getNoteAutocomplete = dialogService.promptNoteAutocomplete; + /** * Trigger command. This is a very low-level API which should be avoided if possible. * diff --git a/src/public/app/widgets/dialogs/add_link.js b/src/public/app/widgets/dialogs/add_link.js index 117bc052f..199030099 100644 --- a/src/public/app/widgets/dialogs/add_link.js +++ b/src/public/app/widgets/dialogs/add_link.js @@ -44,7 +44,7 @@ const TPL = `
@@ -77,30 +77,52 @@ export default class AddLinkDialog extends BasicWidget { const linkTitle = this.getLinkType() === 'reference-link' ? null : this.$linkTitle.val(); - this.textTypeWidget.addLink(this.$autoComplete.getSelectedNotePath(), linkTitle); + if (this.textTypeWidget) { + this.textTypeWidget.addLink(this.$autoComplete.getSelectedNotePath(), linkTitle); + } + if (this.resolve) { + this.resolve({ + isExternal: false, + link: this.$autoComplete.getSelectedNotePath(), + title: linkTitle + }); + } } else if (this.$autoComplete.getSelectedExternalLink()) { this.$widget.modal('hide'); - this.textTypeWidget.addLink(this.$autoComplete.getSelectedExternalLink(), this.$linkTitle.val()); + if (this.textTypeWidget) { + this.textTypeWidget.addLink(this.$autoComplete.getSelectedExternalLink(), this.$linkTitle.val()); + } + if (this.resolve) { + this.resolve({ + isExternal: false, + link: this.$autoComplete.getSelectedExternalLink(), + title: this.$linkTitle.val() + }); + } } else { logError("No link to add."); + if (this.resolve) { + this.resolve(false); + } } return false; }); } - async showAddLinkDialogEvent({textTypeWidget, text = ''}) { + async showAddLinkDialogEvent({textTypeWidget, text = '', callback}) { this.textTypeWidget = textTypeWidget; + this.resolve = callback; - this.$addLinkTitleSettings.toggle(!this.textTypeWidget.hasSelection()); + this.$addLinkTitleSettings.toggle(this.textTypeWidget ? !this.textTypeWidget.hasSelection() : false); this.$addLinkTitleSettings.find('input[type=radio]').on('change', e => this.updateTitleSettingsVisibility(e)); // with selection hyperlink is implied - if (this.textTypeWidget.hasSelection()) { + if (this.textTypeWidget && this.textTypeWidget.hasSelection()) { this.$addLinkTitleSettings.find("input[value='hyper-link']").prop("checked", true); } else { @@ -121,7 +143,7 @@ export default class AddLinkDialog extends BasicWidget { }; noteAutocompleteService.initNoteAutocomplete(this.$autoComplete, { - allowExternalLinks: true, + allowExternalLinks: false, allowCreatingNotes: true });