FlowFuse / FlowFuse/node-red-dashboard

FR: Expose echarts (and perhaps other libs) to users for ui-template

Open
#1,967 5 comments 1 reaction 0 assignees View on GitHub
needs-triage size:XS type:feature
Dominant language
HTML
Stars
355
Forks
82
Avg merge
4d 23h
Merged PRs (30d)
24

Description

### Description

I propose we make `echarts` lib available to user for use in `ui-template`s. This removes the need for users to import echarts themselves (via CDN or other mechanism) and perform the whole `setTimeout` rigamarole!

I propose we add a window property `window.dashboard` (TBD) that can be populated with the things we wish to make accessible to users.

e.g.: in `ui/src/main.mjs` we add:
```js
// Make echarts, mermaid, highlight.js & marked available globally for third-party NR widgets
import * as echarts from 'echarts'
import hljs from 'highlight.js'
import { marked } from 'marked'
import mermaid from 'mermaid'
window.dashboard = {
echarts,
hljs,
marked,
mermaid
}
```

For usage in a ui-template, you would simply access it via the prop name:
```js
this.myChart = window.dashboard.echarts.init(this.$refs.charttpw, "dark");
```


Alternatively, they could be lazy loaded (though it makes no difference to the bundle size as they need to be bundled for use in existing DB2 nodes anyhow)! But - if we ever did made the heavier components lazy load throughout the dashboard, this would be a way to have them available to the user still:

```js
window.dashboard = {
echarts: null,
mermaid: null,
marked: null,
hljs: null,
/**
* Dynamically loads a library and attaches it to window.dashboard
* @param {'echarts'|'mermaid'|'marked'|'hljs'} name - The name of the library to load
* @returns {Promise} The loaded library
*/
async loadLibrary (name) {
switch (name) {
case 'echarts':
if (!window.echarts) {
window.echarts = (await import('echarts')).default
}
return window.echarts
case 'hljs':
if (!window.hljs) {
window.hljs = (await import('highlight.js')).default
}
return window.hljs
case 'mermaid':
if (!window.mermaid) {
window.mermaid = (await import('mermaid')).default
}
return window.mermaid
case 'marked':
if (!window.marked) {
window.marked = (await import('marked')).marked
}
return window.marked
default:
throw new Error('Unknown library: ' + name)
}
}
}
```

For usage in a ui-template, you would load the lib then use it e.g.
```js
window.dashboard.loadLibrary("echarts").then(echarts => {
// Use echarts here
});
```
or
```js
await window.dashboard.loadLibrary("echarts")
// Use window.dashboard.echarts
```


---


As a bonus, we could add some ui-template _Quick Set_ templates that should how to use them.

Image

### Have you provided an initial effort estimate for this issue?

I have provided an initial effort estimate

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.