Skip to content

Commit

Permalink
More updates
Browse files Browse the repository at this point in the history
  • Loading branch information
TotallyInformation committed Jan 8, 2023
1 parent 7cd73cf commit 5b9615b
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 34 deletions.
5 changes: 3 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
* v16 - Promisified setTimeout/setImmediate, RegExp match indices. npm v7 (peer deps now installed again).
* fs.rmdir no longer supports recursive (use new fs.rm)
* v17 - OpenSSL 3 (incl QUIC), Readline Promise API
* v18 - (Experimental: Fetch API, Web Streams API, Test Runner), HTTP Timeouts, findLast/findLastIndex array methods,
* Improvements to the Intl.Locale API [calendars, collations, hourCycles, numberingSystems, timeZones, textInfo, weekInfo],
* v18 - (Experimental: Fetch API, Web Streams API, Test Runner), HTTP Timeouts, findLast/findLastIndex array methods,
* Improvements to the Intl.Locale API [calendars, collations, hourCycles, numberingSystems, timeZones, textInfo, weekInfo],
* Intl.supportedValuesOf function
* v19 - (Experimental: node --watch), HTTP(S)/1.1 KeepAlive by default, Stable WebCrypto API, Intl.NumberFormat
*/
Expand Down Expand Up @@ -104,6 +104,7 @@ module.exports = {

// Try to keep code complexity in functions to a minimum
'sonarjs/cognitive-complexity': ['error', 60], // default is 15! Need to try and improve this :-)
'sonarjs/no-duplicate-string': ['warn', 5], // default is 3

// Make Standard less annoying
'brace-style': 'off', // You should only use one-true-brace style but sometimes we want to compress things a bit.
Expand Down
53 changes: 31 additions & 22 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ typora-root-url: docs/images

# Changelog

## Known Issues
## Known current limitations

Note that v6.0.0 moves the new client libraries (`uibuilder.esm.min.js` and `uibuilder.iife.min.js`) to current and the old client library (`uibuilderfe.js`) to functionally stabilised and on the road to being deprecated. The experimental `uib-list` node has some improvements but is still feature incomplete. The new `uib-brand.css` style library still needs quite a bit of additional work. The new `uib-list` node is still a little rough but should work fine for most things.
Note that v6.1.0 makes the new client libraries (`uibuilder.esm.min.js` and `uibuilder.iife.min.js`) current and the old client library (`uibuilderfe.js`) is now no longer recommended and is not being updated, it is on the road to being deprecated. The experimental `uib-list` node will now also be deprecated, the features are moved to the new `uib-element` node. The new `uib-brand.css` style library still needs quite a bit of additional work.

Dynamic content does not currently work with VueJS (and probably other frameworks that rely on pre-building components). Such frameworks _require_ both the components and the structure to be pre-defined _before_ the DOM is fully loaded. They have their own methods to provide dynamic includes, lazy loading, etc that are very different (and generally much more complex) than uibuilder's simple to use feature. **However**, dynamic content _DOES_ work with HTML components. The component definitions have to be loaded before you use them (that can be dynamic too!) and you _must_ use the ESM build of the uibuilder client library since HTML Components are ES Module only.

Expand All @@ -20,6 +20,7 @@ Check the [roadmap](./docs/roadmap.md) for future developments.
* Disable the new Open button along with other disabled things when new or url has changed.
* Add template description to display.
* Switch tooltips to using aria-label with hover CSS as in the new node.
* Improve help box for _uib switch

* `socket.js`
* Add rooms: page, User id, Tab id - will allow broadcasts to a specific page, user or individual tab and will not be purely reliant on the `_socketId` which can change.
Expand All @@ -42,6 +43,7 @@ Check the [roadmap](./docs/roadmap.md) for future developments.

### IIFE/ESM/Module client library

* [ ] Ensure _ui method update allows "selector" - Order of pref: id>selector>name>type + upd docs `client-docs/config-driven-ui.md##msg-schema-1`
* Add `uibuilder.cacheSend()` and `uibuilder.cacheClear()` functions - reinstate in uib-cache fn now we've removed extra ctrl send
* Add a `uibuilder.navigate(url)` function to allow a msg from node-red to change the page. Ensure it works with SPA routers and with anchor links.
* Add option to send log events back to node-red via the `navigator.sendBeacon()` method.
Expand Down Expand Up @@ -80,39 +82,30 @@ NOTE: Caches the INPUT, not the OUTPUT
* Chaining
* JSON msg templates for each type

### NEW node: `uib-attribs`
### NEW node: `uib-update`

Send attribute overrides to an existing HTML element (using a selector)
Might need changes to FE code? New _ui mode `attribs`?

Also
* slot changer
* Mustache-like replacer ? How? Really need? Use ID instead? Maybe create our own event handler for data-driven elements?
* ? Mustache-like if/then/else ?
* ? Mustache-like loops ?
Send updates to an existing HTML element (using a selector). Uses _ui mode `update`

### Examples

* Update all to use new libs. Remove (c).
* Update all to use new libs and updated templates
* Add example for Vue sfc loader.
* Update/add examples for each template
* Add global Notification/Toast input
* Add dynamic HTML input

### Templates - update to latest standards
* Not yet done:
* [ ] vue
* [ ] vue-simple
* [ ] svelte-basic
* Maybe add:
### Templates
* Maybe add as external templates.
* Vue v3 (build)
* Vue v3 + Quasar
* REACT (no-build)
* REACT (build)
* jQuery + jQuery UI (maybe + some add-ons?)

### uib-cache

* Output node.warn msg if recv input with no "Cache by" msg prop. (e.g. no msg.topic for default setting)
* Add cache clear button

### Doc updates

Expand All @@ -138,10 +131,10 @@ Also
> Please remember that no changes are being made to the old `uibuilderfe.js` client. Nothing listed here applies to that.
* Messages sent from the client either inherit the topic from the last inbound msg or from a default set using `uibuilder.set('topic', 'my topic string')`. The default will take preference.
* The client library has a number of new functions: `uibuilder.syntaxHighlight(json)`,
* The client library has a number of new functions: `uibuilder.syntaxHighlight(json)`, `uibuilder.logToServer(...)`, `uibuilder.beaconLog('text')`.
* The client library reports changes of visibility back to node-red via a new control msg.
* The client library creates a `tabId` which is reported back to node-red when messages are sent. Helps identify the origin. Future uibuilder versions will let you send messages to a specific tab id which does not change even if the page is reloaded (only if the tab is closed).
* Messages from the client now also include the `url` from the uibuilder node they relate to so that it is easier to process messages from multiple different uibuilder nodes.
* If you turn on the advanced option "Include msg._uib in standard msg output.", messages from the client now include client details for you to use in your own security processing or just to identify where things have come from (e.g. what page name as well as what client).

### `uibuilder` node

Expand Down Expand Up @@ -177,8 +170,12 @@ Also
* Added Docs button next to new Open button. Add book icon to docs buttons.

* `socket.js`
* Added `url` to _uib property to make downstream processing easier.
* Added visibility change control msg. Sent by FE client.
* When asked to add msg._uib to std output msgs, Standardised on the same client details as for control msgs to make downstream processing easier.
* Added visibility-change control msg. Sent by FE client. Fires when the open page changes from hidden-to-visible or visa versa.
* New functions: sendCtrlMsg, getClientDetails. Standardise/simplify client details shown on control msgs.

* `web.js`
* Added new `addBeaconRoute` function that sets up the `./_clientLog` instance endpoint. Use the new client `uibuilder.beaconLog(txtToSend, logLevel)` function to send a simple text log back to Node-RED even if socket.io isn't working.

### IIFE/ESM/Module client library

Expand All @@ -194,6 +191,14 @@ Also

* Added internal flag if VueJS is loaded. To be used for dynamic UI processing.

* Added **new function** `uibuilder.beaconLog(txtToSend, logLevel)` which allows sending a simple, short log message back to Node-RED even if socket.io is not connected. In Node-RED, outputs to the Node-RED log and sends a uibuilder control message where `msg.uibuilderCtrl` = "client beacon log".

* Added **new function** `uibuilder.logToServer()` which will take any number and type of arguments and send them all back to Node-RED in the msg.payload of a _control_ message (out of port #2) where `msg.uibuilderCtrl` = "client log message". Client details are added to the message.

### `uib-cache` node

* Added filter to remove msg.res and msg.req which come from ExpressJS and cannot be serialised so create errors.

### **NEW** `uib-element` node

This node lets you easily create new front-end UI elements from within Node-RED. It has a selection of element types ranging from simple text structures, through different types of list and full tables. It is a much more comprehensive node than the previous, experimental, `uib-list` node.
Expand Down Expand Up @@ -226,12 +231,16 @@ Element types included in this release:
* All templates have .eslintrc.js files in the root folder. You may need to install eslint extensions to match. If this file gets in the way, it can be safely deleted. It helps maintain standard coding practices and helps avoid the use of JavaScript which is too new.
* Removed the (c) from the remaining templates. There is no (c) on any of them. They all fall under MIT license. Use as you will, there are no intellectual property restraints on the template code.
* Change all to load client from `../uibuilder/uibuilder.xxx.min.js` instead of `./uibuilder.xxx.min.js` for consistency with other standard and installed library loads. Note that both locations remain valid.
* Moved all scripts to head with defer now we no longer expect IE. Much cleaner code.
* Updated:
* [x] blank
* [x] blank-iife-client
* [x] blank-old-client
* [x] blank-esm-client
* [x] iife-vue3-nobuild
* [x] vue v2 + bootstrap-vue
* [x] vue v2 + bootstrap-vue - simple
* [x] svelte-basic


### Examples
Expand Down
1 change: 1 addition & 0 deletions docs/_sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* [How & why to use the list node](list-node.md)
* [How to use the cache node](cache-node.md)
* [How to use instance API's](instance-apis.md)
* [Other How-To's](how-to/README.md)
* Developing UI's
* [The modern front-end client](uibuilder.module.md)
* [Features](client-docs/features.md)
Expand Down
42 changes: 34 additions & 8 deletions docs/client-docs/config-driven-ui.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,29 @@ created: 2022-06-11 14:15:26
lastUpdated: 2023-01-04 15:40:54
---

- [Dynamic content limitations](#dynamic-content-limitations)
- [Positioning new elements before existing ones rather than after](#positioning-new-elements-before-existing-ones-rather-than-after)
- [Updates and sub-components](#updates-and-sub-components)
- [Dynamic content details](#dynamic-content-details)
- [Initial load from JSON URL](#initial-load-from-json-url)
- [Dynamic changes via messages from Node-RED (or local set)](#dynamic-changes-via-messages-from-node-red-or-local-set)
- [Available methods](#available-methods)
- [Method: load](#method-load)
- [Caveats and limitations](#caveats-and-limitations)
- [Msg schema \& example](#msg-schema--example)
- [Example showing load in your own index.js](#example-showing-load-in-your-own-indexjs)
- [Method: add](#method-add)
- [Msg schema](#msg-schema)
- [Example msgs for nested components](#example-msgs-for-nested-components)
- [Method: remove](#method-remove)
- [Method: update](#method-update)
- [Msg schema](#msg-schema-1)
- [Method: reload - Reloads the current page](#method-reload---reloads-the-current-page)
- [Method: notify](#method-notify)
- [HTML Tags](#html-tags)
- [Schema](#schema)
- [Method: alert](#method-alert)

## Dynamic content limitations

There are currently a small number of limitations of this approach that you should be aware of.
Expand Down Expand Up @@ -379,9 +402,9 @@ The remove method will remove the listed HTML elements from the page assuming th

## Method: update

The update method will update the referenced HTML elements (whether native HTML, web components or framework components). Most of the same properties as for the `add` method are available for updates.
The update method will update the referenced HTML elements (whether native HTML, or ECMA web components). Most of the same properties as for the `add` method are available for updates.

Obviously, to update something, you must identify it. CSS selectors are used to identify the elements to update.
Obviously, to update something, you must identify it. You can identify the thing(s) to update by: The HTML ID attribute, a CSS selector, an HTML name attribute or the HTML tag (type). If multiple of those identifies are provided, the priority is in that order

Unlike the other methods, the update method will find **ALL** matching elements and update them. This means that you could, for example, change the text colour of all list entries on the page with a single update.

Expand All @@ -396,22 +419,24 @@ Unlike the other methods, the update method will find **ALL** matching elements
// List of component instances to update on the page - results in 1 or more HTML custom elements being selected and updated
"components": [
{
// Only 1 of these three properties will be used to search.
// In the order of preference id > name > type
// Only 1 of these four properties will be used to search.
// In the order of preference id > selector > name > type

// The most direct way to select a single element
"id": "...",
// The element's name can be used instead of id - note that names may not be unique
// The most comprehensive and flexible way to select 1 or many elements via a CSS selector
"selector": "...",
// The element's name can be used instead of id - note that names might not be unique and so multiple elements may be updated
"name": "...",
// A generic CSS selector can be specified here. e.g. "div" or "p#classname", etc.
// A generic CSS selector can be specified here as well. e.g. "div" or "p#classname", etc.
"type": "...",

// Optional. HTML to add to slot - if not present, the contents of msg.payload will be used.
// Optional. Text or HTML to add to slot - if not present, the contents of msg.payload will be used.
// This allows multi-components to have their own slot content.
// However, the payload is not passed on to sub-components
"slot": "HTML to <i>add</i> to <sup>slot</sup> instead of <code>msg.payload</code>",

// Optional. Markdown to add to the slot. Converted Markdown is added after the standard slot.
// Optional. Markdown to add to the slot. Converted Markdown is added after the standard slot. Requires a markdown library of course.
"slotMarkdown": "## A heading 2\n\nRendered by **marked** <sub>if loaded</sub>.\n\n```javascript\nvar x = alert('Hey Jim')\n```\n"

// Optional. Each property will be applied to the element attributes
Expand All @@ -423,6 +448,7 @@ Unlike the other methods, the update method will find **ALL** matching elements

// Optional. properties to be added to/replaced on the element. Unlike attributes, these can contain any data.
// Take care to avoid name clashes with internal properties or bad things are likely to happen!
// Most useful when working with ECMA Components though will work with custom front-end code as well.
"properties": {
// ...
},
Expand Down
30 changes: 29 additions & 1 deletion docs/client-docs/features.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,39 @@
---
title: Features of the modern, modular front-end client `uibuilder.esm.js` and `uibuilder.iife.js`
description: >
Description of the main features.
created: 2022-06-11 14:15:26
lastUpdated: 2023-01-04 15:30:54
---

- [Dynamic, data-driven HTML content](#dynamic-data-driven-html-content)
- [Exposes global uibuilder and $](#exposes-global-uibuilder-and-)
- [Includes the Socket.IO client library](#includes-the-socketio-client-library)
- [start function (now rarely needed)](#start-function-now-rarely-needed)
- [$ function](#-function)
- [onChange/cancelChange functions](#onchangecancelchange-functions)
- [onTopic/cancelTopic functions](#ontopiccanceltopic-functions)
- [Conditional logging](#conditional-logging)
- [document-level events](#document-level-events)
- [setPing function](#setping-function)
- [set function](#set-function)
- [Page auto-reload](#page-auto-reload)
- [setStore, getStore, removeStore functions](#setstore-getstore-removestore-functions)
- [send function](#send-function)
- [eventSend function](#eventsend-function)
- [Plain html/javascript example.](#plain-htmljavascript-example)
- [VueJS/bootstrap-vue example](#vuejsbootstrap-vue-example)
- [Auto-loading of the uibuilder default stylesheet](#auto-loading-of-the-uibuilder-default-stylesheet)
- [Initial connection message now shows whether the page is newly loaded or not](#initial-connection-message-now-shows-whether-the-page-is-newly-loaded-or-not)
- [Stable client identifier](#stable-client-identifier)
- [Number of connections is tracked and sent to server on (re)connect](#number-of-connections-is-tracked-and-sent-to-server-on-reconnect)
- [Example client connect control msg](#example-client-connect-control-msg)
- [Client connection/disconnection control messages](#client-connectiondisconnection-control-messages)
- [Client Connect message](#client-connect-message)
- [Client Disconnect (and error) message](#client-disconnect-and-error-message)
- [Message from server to client](#message-from-server-to-client)
- [ui function](#ui-function)

## Dynamic, data-driven HTML content

This feature allows you to dynamically create a UI or part of a UI using just configuration information either send in messages from Node-RED or loaded from a JSON file (or a combination of both).
Expand Down
9 changes: 9 additions & 0 deletions docs/how-to/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: Hints and Tips for using uibuilder
description: >
A collection of FAQ's, how-to's, hints and tips.
created: 2023-01-04 20:27:33
lastUpdated: 2023-01-04 20:27:38
---

* [Loading external files](how-to/load-external-files.md) - including HTML, styles, scripts, and web components.
19 changes: 19 additions & 0 deletions docs/how-to/load-external-files.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
title: How to load external files using uibuilder
description: >
Include external HTML, styles, JavaScript and ECMA web components from external files.
created: 2023-01-04 20:27:33
lastUpdated: 2023-01-04 20:27:38
---

This can be done from Node-RED by sending a msg to the front-end with the appropriate msg._ui data.

It can also be done from front-end code by simulating a msg from Node-RED using the same data.

In addition, external loads can be included in an initial UI load using the `load` method from Node-RED or the `loadui` function in the front-end - `uibuilder.loadui('something.json')`.

## References

* [Method: Load](../client-docs/config-driven-ui.md#method-load)
* [Simulating a msg from Node-RED](../client-docs/features.md)

Loading

0 comments on commit 5b9615b

Please sign in to comment.