mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	loading of custom widgets
This commit is contained in:
		| @@ -248,6 +248,21 @@ class Note extends Entity { | ||||
|         return (await this.getAttributes(name)).filter(attr => attr.type === RELATION); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param {string} [name] - relation name to filter | ||||
|      * @returns {Promise<Note[]>} | ||||
|      */ | ||||
|     async getRelationTargets(name) { | ||||
|         const relations = await this.getRelations(name); | ||||
|         const targets = []; | ||||
|  | ||||
|         for (const relation of relations) { | ||||
|             targets.push(await relation.getTargetNote()); | ||||
|         } | ||||
|  | ||||
|         return targets; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param {string} [name] - relation name to filter | ||||
|      * @returns {Promise<Attribute[]>} all note's relation definitions including inherited ones | ||||
|   | ||||
| @@ -196,12 +196,27 @@ class NoteShort { | ||||
|  | ||||
|     /** | ||||
|      * @param {string} name | ||||
|      * @returns {Promise<Note>|null} target note of the relation or null (if target is empty or note was not found) | ||||
|      * @returns {Promise<NoteShort>|null} target note of the relation or null (if target is empty or note was not found) | ||||
|      */ | ||||
|     async getRelationTarget(name) { | ||||
|         const relation = await this.getRelation(name); | ||||
|         const targets = await this.getRelationTargets(name); | ||||
|  | ||||
|         return relation ? await repository.getNote(relation.value) : null; | ||||
|         return targets.length > 0 ? targets[0] : null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param {string} [name] - relation name to filter | ||||
|      * @returns {Promise<NoteShort[]>} | ||||
|      */ | ||||
|     async getRelationTargets(name) { | ||||
|         const relations = await this.getRelations(name); | ||||
|         const targets = []; | ||||
|  | ||||
|         for (const relation of relations) { | ||||
|             targets.push(await this.treeCache.getNote(relation.value)); | ||||
|         } | ||||
|  | ||||
|         return targets; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
| @@ -5,7 +5,7 @@ import infoService from "./info.js"; | ||||
| async function getAndExecuteBundle(noteId, originEntity = null) { | ||||
|     const bundle = await server.get('script/bundle/' + noteId); | ||||
|  | ||||
|     await executeBundle(bundle, originEntity); | ||||
|     return await executeBundle(bundle, originEntity); | ||||
| } | ||||
|  | ||||
| async function executeBundle(bundle, originEntity, tabContext) { | ||||
|   | ||||
| @@ -7,8 +7,9 @@ import treeCache from './tree_cache.js'; | ||||
| import noteDetailService from './note_detail.js'; | ||||
| import noteTypeService from './note_type.js'; | ||||
| import noteTooltipService from './note_tooltip.js'; | ||||
| import protectedSessionService from'./protected_session.js'; | ||||
| import dateNotesService from'./date_notes.js'; | ||||
| import protectedSessionService from './protected_session.js'; | ||||
| import dateNotesService from './date_notes.js'; | ||||
| import StandardWidget from '../widgets/standard_widget.js'; | ||||
|  | ||||
| /** | ||||
|  * This is the main frontend API interface for scripts. It's published in the local "api" object. | ||||
| @@ -32,6 +33,9 @@ function FrontendScriptApi(startNote, currentNote, originEntity = null, tabConte | ||||
|     /** @property {TabContext|null} - experimental! */ | ||||
|     this.tabContext = tabContext; | ||||
|  | ||||
|     /** @property {StandardWidget} */ | ||||
|     this.StandardWidget = StandardWidget; | ||||
|  | ||||
|     /** | ||||
|      * Activates note in the tree and in the note detail. | ||||
|      * | ||||
|   | ||||
| @@ -2,6 +2,8 @@ import NoteInfoWidget from "../widgets/note_info.js"; | ||||
| import LinkMapWidget from "../widgets/link_map.js"; | ||||
| import NoteRevisionsWidget from "../widgets/note_revisions.js"; | ||||
| import AttributesWidget from "../widgets/attributes.js"; | ||||
| import bundleService from "./bundle.js"; | ||||
| import messagingService from "./messaging.js"; | ||||
|  | ||||
| class Sidebar { | ||||
|     /** | ||||
| @@ -9,6 +11,7 @@ class Sidebar { | ||||
|      * @param {object} state | ||||
|      */ | ||||
|     constructor(ctx, state = {}) { | ||||
|         /** @property {TabContext} */ | ||||
|         this.ctx = ctx; | ||||
|         this.state = state; | ||||
|         this.widgets = []; | ||||
| @@ -51,15 +54,27 @@ class Sidebar { | ||||
|  | ||||
|         const widgetClasses = [AttributesWidget, LinkMapWidget, NoteRevisionsWidget, NoteInfoWidget]; | ||||
|  | ||||
|         const widgetRelations = await this.ctx.note.getRelations('widget'); | ||||
|  | ||||
|         for (const widgetRelation of widgetRelations) { | ||||
|             const widgetClass = await bundleService.getAndExecuteBundle(widgetRelation.value, this.ctx.note); | ||||
|  | ||||
|             widgetClasses.push(widgetClass); | ||||
|         } | ||||
|  | ||||
|         for (const widgetClass of widgetClasses) { | ||||
|             const state = (this.state.widgets || []).find(s => s.name === widgetClass.name); | ||||
|  | ||||
|             const widget = new widgetClass(this.ctx, state); | ||||
|             this.widgets.push(widget); | ||||
|             try { | ||||
|                 const widget = new widgetClass(this.ctx, state); | ||||
|                 await widget.renderBody(); | ||||
|  | ||||
|             widget.renderBody(); // let it run in parallel | ||||
|  | ||||
|             this.$widgetContainer.append(widget.getWidgetElement()); | ||||
|                 this.widgets.push(widget); | ||||
|                 this.$widgetContainer.append(widget.getWidgetElement()); | ||||
|             } | ||||
|             catch (e) { | ||||
|                 messagingService.logError(`Error while loading widget ${widgetClass.name}: ${e.message}`); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -106,6 +106,7 @@ class TabContext { | ||||
|     setNote(note, notePath) { | ||||
|         this.noteId = note.noteId; | ||||
|         this.notePath = notePath; | ||||
|         /** @property {NoteFull} */ | ||||
|         this.note = note; | ||||
|         this.tabRow.updateTab(this.$tab[0], {title: note.title}); | ||||
|  | ||||
| @@ -136,7 +137,7 @@ class TabContext { | ||||
|         this.showPaths(); | ||||
|  | ||||
|         if (this.sidebar) { | ||||
|             this.sidebar.noteLoaded(); | ||||
|             this.sidebar.noteLoaded(); // load async | ||||
|         } | ||||
|  | ||||
|         console.debug(`Switched tab ${this.tabId} to ${this.noteId}`); | ||||
|   | ||||
| @@ -161,6 +161,7 @@ ${await note.getContent()}; | ||||
| } catch (e) { throw new Error("Load of script note \\"${note.title}\\" (${note.noteId}) failed with: " + e.message); } | ||||
| if (!module.exports) module.exports = {}; | ||||
| for (const exportKey in exports) module.exports[exportKey] = exports[exportKey]; | ||||
| return module.exports; | ||||
| }).call({}, {}, apiContext.modules['${note.noteId}'], apiContext.require(${JSON.stringify(moduleNoteIds)}), apiContext.apis['${note.noteId}']` + (modules.length > 0 ? ', ' : '') + | ||||
|             modules.map(mod => `apiContext.modules['${mod.noteId}'].exports`).join(', ') + `)); | ||||
| `; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user