-
Notifications
You must be signed in to change notification settings - Fork 52
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamic Options - Implement new helper functions & update widget-load behaviour #1123
Conversation
Update: done |
How are validations being done on ui_update operations, to make sure invalid data are not allowed? |
Needs to be done on a node-by-node basis. Right now, not much validation. Also PR opened for UI Example updates: FlowFuse/node-red-dashboard-2-ui-example#17 will get it reviewed once these core PRs are merged |
8e5c47b
to
df105d4
Compare
One question regarding the use of the dynamic properties, is it sensible that the user may want to return a specific property to its default value, (for example button color, that was defined in the config window as |
If the value is set to return this.state && property in this.state && state !== null ? state : config Note, if Each node can also have bespoke handelrs there too, e.g. |
I was testing that scenario, and it doesn't work. For example:
Not a big issue from my part, but may be something to consider if it is necessary to have a way to revert to initial configuration. |
I'll handle this in a follow up @arturv2000 as I don't want to block this PR for that feature |
Will follow up with outstanding nodes in #833 once this is merged |
ui-dropdown
demo flow
|
UI Dropdown:
|
Is the problem here that a message containing only ui_update settings is stored as the last message? I think that such messages should not be stored, as the ui_update data are stored in the state store. |
The use of |
Now reliving what you mean re: multiple. That's likely an issue in current Don't think that's a problem been introduced here |
Yeah. I thought the point of making helper functions was to cement this common behaviour at the core. As such I raised it as an issue. forgive me if I am missing something here. |
This could work, but not in scope of this issue/PR |
It's not listed as a supported or new feature, so no, this has lot been added, but can be in a follow up PR/issue |
Are any of these changes breaking or will users experience differing behaviour when this is merged Joe? If yes, then I would personally recommend we get the behaviour nailed down in this PR before we release it into the wild. |
ui-number-group
demo flow
|
There should be 0 difference to UX as a result of this PR |
Ok, well in which case my semi-thorough testing should probably be halted until I can establish a baseline from Before I halt, I will post findings for UI-Button (rather than let my findings go to waste) ui-button
demo flow
What I will state is, there is a common theme across many of the issues related to override/null/refresh issues |
Most of these issues exists in Main, regarding the |
Regarding the before was this: const updates = msg.ui_update
if (typeof updates?.label !== 'undefined') {
this.dynamic.label = updates.label
}
if (typeof updates?.options !== 'undefined') {
this.dynamic.options = updates.options
} And now is: const updates = msg.ui_update
this.updateDynamicProperty('label', updates.label)
this.updateDynamicProperty('options', updates.options) But when we inject a message via Node-Red, the Replacing with: onDynamicProperty (msg) {
const updates = msg.ui_update
if (!updates) {
return
}
this.updateDynamicProperty('label', updates?.label)
this.updateDynamicProperty('options', updates?.options)
}, Solves the main issue (Not the null not returning to original configuration) The same behaviour may be happening in other widgets. The fact that is not selected upon a refresh, is because the last message is replayed (maybe this term is not technical correct), and if the last message was only to set the |
So, I'm fairly sure this is all good to go now. @Steve-Mcl the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the newly introduced issues are indeed resolved.
Code review all good.
NOTE: This is approved in the knowledge that there are a few issues related to mostly to setting then reseting dynamic props but they are existing and are to be addressed separately.
In case they are not all spelled out in the issue, the ones I seen are:
-
dropdown
- Applying dynamic label then resetting it with a
null
followed by a refresh causes the label to disappear - Applying dynamic options then resetting them with a
null
followed by a refresh causes the options to disappear
- Applying dynamic label then resetting it with a
-
form
- Applying dynamic label then resetting it with a
null
followed by a refresh causes the label to disappear - Applying dynamic options then resetting them with a
null
followed by a refresh causes the options to disappear - After Applying dynamic options, the first 2 fields appear to be bound (typing in one field will update the other)
- Applying dynamic label then resetting it with a
-
button
- Applying dynamic icon then resetting it with a
null
followed by a refresh causes the button to disappear - Applying dynamic label then resetting it with a
null
followed by a refresh causes the buttons label to disappear
- Applying dynamic icon then resetting it with a
-
button group
- Applying dynamic label then resetting it with a
null
followed by a refresh causes the label to disappear - Applying dynamic options then resetting them with a
null
followed by a refresh causes the options to disappear
- Applying dynamic label then resetting it with a
NOTE: This ↑ was not exhaustive - only a selection of the dynamic ops and widgets were tested for the purposes of this review.
Thanks Steve |
So just to make sure, there is no backwards compatibility impact:
|
correct
Yes, correct |
Excellent, thank you. |
Not that I can think of - any reason you'd need to know for this though, in your |
I'm trying to think ahead. Dash-2.0 is continuously evolving with new functionality, and it would be good to enable a node to know the dash-2.0 version it is running on (and determine which framework functionality is available). Equivalent to checking the NodeJS version to determine if a new JavaScript feature is available. Specifically in my case, it's chicken & egg. I can easily check if a message is null or undefined once I receive the load notification, but will never get this notification in the first place if datastore was empty... :-) so knowing the version will enable me to retain the current workaround (forcing a dummy datastore entry) for users who upgrade the node but are still on an older dashboard version. |
Description
Okay, this is a fairly big shift, so will do my best to articulate the changes, and the why.
widget-load
changesstate
value in thewidget-load
event. This is because any changes, and dynamic properties, set on a node when not in view on the Dashboard would be updated server-side, but not client-side. So, when a user navigates (via the side navigation) to the relevant page, the state loaded is still the original configuration provided by Node-RED's latest deploy.state
straight into our VueX store under thewidget.state
field. This means that we don't need to define this on every widget, which we would need to. Note though, that we still need to have the server-side definitions over what can go intostate
, and the client-side widgets need to reference this still viacomputed
variables (explained next)msg
orstate
saved in the server-side stores. Previously, it would only fire if something was present indatastore
(i.e. last receivedmsg
)Move to a centralised store model
dynamic
design pattern that we had implemented in order to track the dynamic overrides.widget
state stored in vuex directly usingcomputed
variables. This ensures we have a single source of truth, and not many copies of the truth distributed out to each widget/node.New global helper functions
updateDynamicProperty(property, value)
: Updates a property with the provided value, and checks against undefined typessetDynamicProperties(config)
: Will set the provided properties in the vuex store for a given widget this is run on. This will automatically update the widget's state, and any references using this property.getProperty(property)
: Automatically gets the correct value for the requested property. Will first look in the dynamic properties, and if not found, will default to the static configuration (i.e. what's defined in Node-RED) that arrived via theui-config
event.widgetState
store mutation changeswidgetState
mutation on theui
vuex store has changed to permit separation of the proeprties being set and theid
of the widget.Progress
We need to sweep over all of the existing widgets that were already using the design pattern to ensure consistency:
We can then continue #833 with the new pattern introduced here
Related Issue(s)
Closes #793
Closes #1022
Closes #1117
Closes #1122
Need to double check once closed on whether it helps #871