-
Notifications
You must be signed in to change notification settings - Fork 2
Installable Widget Node
Currently, Node-RED Dashboard do not allow installing user created widget nodes. Instead, it supports TEMPLATE node which allows embedding HTML code in its setting panel. However, making new widget node installable is desirable because it enriches Node-RED Dashboard ecosystem as of current Node-RED nodes.
- Basic node code (HTML and JavaScript) structure follows those of template node (but can be arbitrary),
- Support code generation from existing TEMPLATE node using nodegen tool (optional).
-
Widget node is basically same as ordinary Node-RED node. Different point is that it requires accessing
ui.jsmodule of Node-RED Dashboard for accessing UI interfaces (e.g.ui.add). Becauseus.jsis stored undernode-red-dashboardmodule, we need some means for accessing it.Proposal:
-
Add interface (e.g.
getDashboardPath) for getting module install path ofnode-red-dashboard.- Can access other data stored under
node-red-dashboardsuch as icons. - As pointed on the last teleconference, this interface is too specialized for Node-RED Dashboard.
- Can access other data stored under
-
Add interface (e.g. getModulePath) for getting module installation path (or other information if there are good usage) of any module.
- This proposal is generarization of #1.
-
Add interface for accessing
ui.jsinterface from node API (i.e.REDvariable) passed on node initialization.- Similar to #1, this proposal is too specialized for Node-RED Dashboard.
-
other better way for accessing
ui.js?
Currently, we prefer #2 because this one is more general compared to other proposal.
-
-
Accessing interfaces of
us.jsmust be delayed afternode-red-dashboardis loaded.Proposal:
- Delay
requireofui.jsuntil widget node deployment.
- Delay
- HTML code
- Same as normal node described at (https://nodered.org/docs/creating-nodes/node-html).
- JavaScript code
- load
us.jsmodule using method of proposal#2, - call
us.addfunction with parameters similar to TEMPLATE node.
- load
-
HTML code
<script type="text/x-red" data-template-name="ui_hello"> ... help text ... </script> <script type="text/javascript"> function mk_conf(NAME) { ... create node definition ... }; RED.nodes.registerType('ui_hello', mk_conf('hello')); </script>
-
JavaScript code
module.exports = function(RED) { var TEMPLATE_SCOPE = "local"; // HTML code for widget var TEMPLATE = '// name: hello\n<div style=\"background-color:#84180F; color:#FFFFFF; border-radius:15px; font-size:20px;\" align=\"center\">\n Hello Node-RED\n</div>\n'; var STORE_OUT_MSGS = true; var FWD_IN_MSGS = true; var ui = undefined; function TemplateNode(config) { if(ui === undefined) { // load ui.js module var base = RED.nodes.getModulePath("node-red-dashboard"); ui = require(base+'/ui')(RED); } RED.nodes.createNode(this, config); var node = this; var group = RED.nodes.getNode(config.group); if (!group && TEMPLATE_SCOPE !== 'global') { return; } var tab = null; if (TEMPLATE_SCOPE !== 'global') { tab = RED.nodes.getNode(group.config.tab); if (!tab) { return; } if (!config.width) { config.width = group.config.width; } } var hei = Number(config.height || 0); // initialize UI widget var done = ui.add({ forwardInputMessages: FWD_IN_MSGS, storeFrontEndInputAsState: STORE_OUT_MSGS, emitOnlyNewValues: false, node: node, tab: tab, group: group, control: { type: 'template', order: config.order, width: config.width || 6, height: hei, format: TEMPLATE, templateScope: TEMPLATE_SCOPE }, ... }); node.on("close", done); } RED.nodes.registerType('ui_hello', TemplateNode); };
Comment from DCJ:
The problem that I haven't worked out is that it isn't just about ui.add.
Quite a few widgets have extra code in src/components/ui-component/templates/ui-component-ctrl.js
Could this also be abstracted back up to ui.add in some way ? and thus allow nodes to add their own functions there instead ? (I've not scrutinised it enough to know yet). As many of these are to do with initialising the widgets internal functions would this conflict with proposal 2) re the timing of loading and create a sequencing issue ? (or would it help tidy it up ?)
In some ways option ii) is too broad - it could allow any extra node to try to build on top of any other node - I think while we possibly do want to do this - I think we want to restrict which nodes extend what, or have some way to stop nodes being extended unless they explicitly declare they can be.
Finally I go back to the overall "bigger picture" thought... Is dashboard the right thing to extend ? - seeing as it is based on Angular 1 - and we don't want to move to typescript / Angular4,5,etc