✨ UIBUILDER New Release v6.7 - New front-end router, improvements to uib-html, uib-save and more

Hi all, a sneaky mid-week release for UIBUILDER. :grinning:

The big news is the inclusion of the first release of the new front-end routing library for creating Single-Page Apps (SPAs). But there is much more as well.


Highlights

  • The new front-end routing library is available. Easy to use, robust and reasonably comprehensive. It is not dependent on uibuilder but offered with it to enable Single-Page Apps (SPA's) to be easily created with uibuilder.

  • The uib-html node now allows an HTML string wrapper. This defaults to uibuilder's default "Blank" template HTML or can be overridden using msg.template. This lets you create a fully working page from no-code and low-code configurations that can be fed direct to uib-save or used in Dashboard or with http-in/-out nodes. Or indeed with external web server tools.

New client library - uibrouter - front-end routing library

A complete, standalone library for doing front-end routing with both internal and external templates. Lightweight and simple to use. See the documentation for details.

uib-html improvements

  • The uib-html node now accepts a msg.template property which, if provided, MUST contain a valid HTML page template.

This allows you to grab an existing page using the htmlSend command, add new elements/updates and save it back to a uibuilder instance either as the default page or another page, for example, using the uib-save node. Overwriting a page is a way of ensuring that new accesses get a known page with structure and potentially data.

You can, of course, use this node to produce HTML for use outside of UIBUILDER. For example, use uib-element/uib-update, add a template and use this node to create a complete web page for use with http-in/-out, a static website or some other web service.

You probably don't need/want the template if outputting for the Node-RED Dashboard ui_template node.

uib-save improvements

  • The reload client flag now actually works.

  • The new "Use pageName" flag allows you to save to the uibuilder node's live folder using the page name returned from the front-end or manually set in msg._ui.pageName or msg.uib.pageName. This makes it easier to save an updated page via the htmlSend command (either from Node-RED or from front-end code). See the example flow to see how this works. It means that you don't need to know the folder or the pageName at all.

  • The filename can include folders (use / as separator) and missing folders will be created automatically if the "Create Folder" flag is set. Note that you cannot have any .. in the filename, this is to prevent escaping from the instance root folder and causing mayhem elsewhere. By default, new folders cannot be created (this is a safety feature), select the "Create Folder?" flag to allow creation.

  • The Editor js has been moved out of the html file and put into resources/uib-save.js. It is loaded by the html file in a link. This makes development a lot easier. The code also references resources/ti-common.js to ensure consistency.

uib-tag improvements

  • FIXED - Tag name input would only accept string. Now correctly processes other types.

Client library improvements

  • FIXED Client htmlSend, when called as a Node-RED command, was returning 2 messages. Now returns the HTML string and sends it to Node-RED directly only if the new 2nd argument is TRUE (the default so that direct calls will still work without changes).

  • FIXED eventSend when attached to a change event returns the value property that all input tags have - except when they don't! When input is used as a checkbox, it has a checked property instead. Function changed to return the checked value if it exists (true or false), the value property otherwise.

  • NEW function and command watchUrlHash - Toggle (or manually set on/off) sending URL Hash changes back to Node-RED in a standard msg.

  • NEW watched variable urlHash Set on load and updated as it changes. URL Hashes are used by front-end routing for Single-Page-Apps (SPA's). They do not reload the page.

  • New utility function truthy Takes a truthy/falsy input (e.g. text, number, boolean) and returns true or false (boolean). If input is neither truthy or falsy, can take a 2nd parameter which is the default return.

  • Function added to watch for url hash changes.

uibuilder node improvements

  • uibuilder - Reduce code complexity by moving more fs actions out into libs/fs.js.

  • Some common Node-RED Editor code and styles moved to common libraries (resources/ti-common.js & resources/ti-common.css) loaded as resources. Making the editor code smaller and more consistent.

Editor panel improvements

  • Major rework of tracking node instances. Custom events are now fired: 'uibuilder:node-added', 'uibuilder:node-changed', 'uibuilder:node-deleted'. With the node in question passed as data in the event. For added nodes, an extra property addType is added to the node object and set to either "load" (fired when the Editor is loaded which adds all nodes), "new" (when a brand new instance is added, eg from the palette), or "paste/import". The tracking code is also now only ever instanciated once when the Editor is loaded.

  • Better and more consistent removal of URL setting when pasting or importing existing uibuilder nodes.

  • The Editor js has been moved out of the html file and put into resources/uibuilder.js. It is loaded by the html file in a link. This makes development a lot easier. The code also references resources/ti-common.js to ensure consistency.

  • Improved debug information. Debug output to Editor page console is automatic if environment variable NODE_ENV is set to 'dev' or 'development' (it used to be if running on localhost). Otherwise can be turned on by manually issueing uibuilder.debug = true on the browser console on the Editor page.

Examples

  • uib-save and uib-html example flows added.

  • uib-var-web-component example flow added. Contains several examples of showing uibuilder managed variables dynamically in your HTML code. Including several no-code examples.

  • uib-tag example flow added.

Other improvements

  • NEW node Library libs/lowcode.js - The beginnings of moving the zero- to low-code element translations (e.g. uib-element, uib-update and uib-tag) to their own library. With the possibility of eventually making that library available as a stand-alone front-end library as well. Not yet in use.

  • libs/fs.js - More replacements towards removing dependency on fs-extra. More move of filing system actions out of other nodes and libraries.

  • NEW utility function getSource(propName, node, msg, RED, src, srcType) in libs/uiblib.js - this is an ASYNC function that returns a promise. It is a standardised way of getting the current value from a Node-RED Typed Input field.

  • Enhanced tooltips not applied to the Monaco/Ace edit panel.

6 Likes

Wow!
I just started with uibuilder and I am still not sure if I really have the big picture ;-).
Just updated to uibilder 6.6 today and asked myself if 6.7 should allready be in the palette or is it a release for manual update?
I am so looking forward to get my UI done with UIBUILDER :star_struck:
best regards
Antonio

Should be available, I updated it on npm then updated the flows site manually.

Been a month since the last release, so plenty of time to upgrade! :rofl:

Hmm, just tried an update on one of my systems and you are correct, it isn't showing 6.7 even though the flows site and npm both show it.

A manual update will work.

@knolleary or @Steve-Mcl - is there a problem with the catalogue? Been several hours now since the update landed and I reloaded the editor page.

Update available in palette

1 Like

Hi Julian!
I just began to follow your Getting Started manual, and made some unexpected observations.
To reproduce:

  • Pull a uibuilder node in a flow.
  • Press Deploy.
  • The editor complains that the node just dropped isn't configured correctly. Deploy anyway.
  • Open the property editor of the uibuilder node, enter a valid URL ( like uibtest), close the property pane with Done.
  • First observation: The uibuilder node still shows the red triangle - despite correctly configured now.
  • Press Deploy.
  • The editor complains that the node still isn't configured correctly. Deploy anyway.
  • Second observation: The uibuilder node still shows the red triangle - which is definitely unexpected now. Node status displays "Node Initialised" @ blue.

When dropping an uibuilder node, opening the property editor, entering a valid url, pressing Done & then Deploy, the uibuilder node doesn't show the triangle of error.

And: You've created an exciting element of the Node-RED eco system. Thank you for this contribution! :+1:

Arghhh! There's always someone! :grinning:

Well done, you've spotted a weakness! It has to do with the complexity of ensuring unique URL's that are also unique and valid folders and getting everything created as early as possible so that everything else works.

Unfortunately, Node-RED has no way (that I'm aware of) of actually preventing a deploy. Really, it would be much better if you couldn't deploy until you've entered a valid URL. Any ideas would be gratefully received.

Otherwise, I'll try to reproduce your process and see if I can improve the processing.

Looks like it's validateVersion that triggers this red triangle.

Following the sequence stated above, this.deployedVersion === undefined even after the second deploy.
this.deployedVersion yet is only set in oneditsave if ( this.changed || this.mustChange ):

oneditsave yet is invoked only after validateVersion, thus the validation fails when run the first time - returning false. When you deploy another time, the triangle gets removed - as now this.deployedVersion != undefined.

To fix this, I'd clear the triangle indicator when you assign this.deployedVersion = RED.settings.uibuilderCurrentVersion in oneditsave, given that this.urlValid == true as well.

1 Like

Ah, nice spot! That was something I put in to enable a warning message to users on a version jump that required users to make changes to any deployed uibuilder nodes. I wonder - were you doing a large version jump of uibuilder?

I'll take a look at what you've indicated, thanks again.

No. Began with a clean system...

Ah, OK. That sounds like a regression that's crept in then. Thanks, I can check that.

Hi Ralph,

You will be glad to note that I've added a fix for this in v6.8 - now, if the url is missing or invalid, the node simply isn't actually configured and an error message is logged. Once the error is cleared, then the node is configured.

This will also fix some other edge-cases such as deploying with a duplicate url.

Unfortunately, in some cases, this does cause Node-RED to throw a bit of a tantrum:

0|Node-RED  | 1 Jan 13:20:56 - [error]
0|Node-RED  | ********************************************************************
0|Node-RED  | Unexpected Node Error
0|Node-RED  | ********************************************************************
0|Node-RED  | Info:
0|Node-RED  |  Node object is not a node-red Node
0|Node-RED  | Stack:
0|Node-RED  |  TypeError: Cannot read properties of undefined (reading 'length')
0|Node-RED  |     at Node.close (D:\src\nr\node_modules\@node-red\runtime\lib\nodes\Node.js:319:41)
0|Node-RED  |     at stopNode (D:\src\nr\node_modules\@node-red\runtime\lib\flows\Flow.js:746:31)
0|Node-RED  |     at Flow.stop (D:\src\nr\node_modules\@node-red\runtime\lib\flows\Flow.js:388:35)
0|Node-RED  |     at D:\src\nr\node_modules\@node-red\runtime\lib\flows\index.js:477:43
0|Node-RED  |     at Array.forEach (<anonymous>)
0|Node-RED  |     at stop (D:\src\nr\node_modules\@node-red\runtime\lib\flows\index.js:473:19)
0|Node-RED  |     at D:\src\nr\node_modules\@node-red\runtime\lib\flows\index.js:220:20
0|Node-RED  |     at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
0|Node-RED  | Please report this issue, including the information logged above:
0|Node-RED  | https://github.com/node-red/node-red/issues/
0|Node-RED  | ********************************************************************

Thankfully, this doesn't seem to do any other harm.