Skip to content
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

notification ui node enhancements #932

Merged
merged 17 commits into from
Aug 20, 2024

Conversation

bartbutenaers
Copy link
Contributor

Description

This PR adds some enhancements to the Notification ui node. Some of these enhancements were a bit too much related, so I decided to combine them in a single PR.

1. Help panel

There was no help panel yet for this node, so I added one:

image

2. Output msg fix

As described in issue 928 the output messages were not being send anymore. Don't know since which version, or which change caused it. Just fixed it...

3. Close via msg

As described in issue 733 it should be able to close the notification dialog using an input message.

I used some kind of toggle mechanism: when you inject a msg and the dialog is closed, then it will be opened. And the other way around:

toggle_notification

So I don't look at the content of the payload. Don't know if that is ok? I have not mentioned it yet in the documentation for this reason.

4. Confirmation button

Beside the already existing dismiss button, there is now also a confirmation button. As described in issues 606 and (partially) 193.

  • By default the new confirmation button is inactive, to behave like older instances of this node:

    image

    In that case only the existing dismiss button is being displayed, similar to in the previous version:

    image

    When clicked, a message is send:

    image

    As discussed this is a breaking change because previously a payload "clicked" was being used, which would not be very useful in a context of two buttons...

  • When activated, it becomes possible to specify the label of the second button:

    image

    In this case the two buttons will be displayed:

    image

    When the new confirmation button is clicked, a message is send:

    image

  • When only the new confirmation button is acivated:

    image

    Then only the new button is being displayed:

    image

  • And when custom labels are specified for both buttons:

    image

    Then both labels will be displayed:

    image

Related Issue(s)

Issue 928
Issue 733
Issue 606
Issue 193 (partially)

Checklist

  • [ X ] I have read the contribution guidelines
  • Suitable unit/system level tests have been added and they pass
  • Documentation has been updated
    • Upgrade instructions
    • Configuration details
    • Concepts
  • Changes flowforge.yml?
    • Issue/PR raised on FlowFuse/helm to update ConfigMap Template
    • Issue/PR raised on FlowFuse/CloudProject to update values for Staging/Production

Labels

  • Includes a DB migration? -> add the area:migration label

@colinl
Copy link
Contributor

colinl commented May 31, 2024

I thought that the OK/Cancel feature was going to be handled by a new ui-dialog rather than being added to the notification node.
See #193.

@colinl
Copy link
Contributor

colinl commented May 31, 2024

OK, I have just seen the latest posts on #193 where it was decided to do it the way D1 did it.

ui/src/widgets/ui-notification/UINotification.vue Outdated Show resolved Hide resolved
ui/src/widgets/ui-notification/UINotification.vue Outdated Show resolved Hide resolved
ui/src/widgets/ui-notification/UINotification.vue Outdated Show resolved Hide resolved
Co-authored-by: Joe Pavitt <[email protected]>
@joepavitt
Copy link
Collaborator

For the close via msg - currently, that would close for any payload received? I think we need to be a little more strict in it's requirements. To be consistent with other approaches, we could use a msg.ui_update option, but that's generally reserved for dynamic/persistent changes. Here I think a msg.show = false would be appropriate?

@bartbutenaers
Copy link
Contributor Author

@joepavitt,
You can implement this in a million different ways. For me msg.show = false is fine. I don't really have an opinion about this one. Just let me know.

@joepavitt
Copy link
Collaborator

Actually, let's go msg.clear_notification = true - feels more instructive

@colinl
Copy link
Contributor

colinl commented Jun 12, 2024

Should msg.reset be a candidate, as that is used elsewhere for clearing things?

@joepavitt
Copy link
Collaborator

as that is used elsewhere for clearing things?

is it?

@colinl
Copy link
Contributor

colinl commented Jun 12, 2024

Delay and Trigger nodes for example.

@bartbutenaers
Copy link
Contributor Author

Yes but inside the dashboard it is more common usage to clear stuff e.g. using an empty string in the payload (see dropdown, radiobuttons, ...)

@colinl
Copy link
Contributor

colinl commented Jun 12, 2024

True.

@bartbutenaers
Copy link
Contributor Author

@joepavitt,
I have updated the code to close the window if msg.clear_notification = true is injected.

However when I inject, msg.clear_notification = false I expect nothing to happen. Instead the title of the notification disappears:

notification_header_disappears

Below the root cause is explained, but I don't know how to solve it. A bit too much Vue specific for me...

image

  1. When the message arrives in the frontend, it is stored
  2. Since the msg.clear_notification = false I ignore the message.
  3. The value changes because of the stored message. But since my msg has no payload, the value will be undefined.
  4. The changed value will let the title disappear.

Perhaps I should only store the message in the else section, i.e. only store the message if it is going to be used to show a new dialog?

@colinl
Copy link
Contributor

colinl commented Jun 12, 2024

I think there isn't much point saving the clear is there? If the page is refreshed while a notification is open it is not re-shown anyway. Plus if it had been cleared then it wouldn't be there anyway.

@bartbutenaers
Copy link
Contributor Author

@colinl,
You are right. Will change it tonight.
After a long heavy day at work, the dashboard code isn't always clear to me.
As I said before, storing (and more worse replaying) of messages has been a source of troubles in the ui nodes over many years.
It makes no sense at all to do it that way, and it continues to trigger unexpected weird side behaviour...

@joepavitt
Copy link
Collaborator

I'm happy to cover this @bartbutenaers

Colin is right, we just want a conditional to check a payload is present, before storing the data and overriding msg in the client

@bartbutenaers
Copy link
Contributor Author

Thanks @joepavitt !!!

@colinl
To explain my last feedback above a bit more.

My issue from last night is another nice example of this discussion. I inject a message which does not contain any information about the notification title, and hence the title is gone. Because my message becomes the last stored message, and the widget expects to find ALL his information in that last message. But the last message only contains only a little part of all the required state information of course. And now you as a node developer need to start thing about which message should be stored and which one not. Only to make sure that the required information is available in the last stored message. Which imho is not a pretty solution anymore...

I would expect that:

  1. The first message would update all kind of properties in the server side state (e.g. content, title, ...).
  2. That state delta is forwarded to the required clients, which update their Vue template and show the notification.
  3. My last message only updates the show property to false in the server side state.
  4. That state delta is forwarded to the required clients, which update their Vue template and hide their notification.

Sorry guys to repeat this theory over and over again. But I still wake up screaming in the middle of the night, being haunted by hundreds of replayed messages with faulty content ;-)

@joepavitt
Copy link
Collaborator

As an example if you've defined colour: blue on the node's config.

You send a message which defined msg.color = red with a msg.payload, and then after that, sent just a msg.payload, what colour should it be?

I'd say blue?

In the pattern you've proposed though, I understand you'd ask for red to have been stored if we merge msg objects?

@bartbutenaers
Copy link
Contributor Author

In the pattern you've proposed though, I understand you'd ask

@joepavitt,
I have added my feedback to my original discussion about server side state: see here, to keep everything nicely together. I have added an example that hopefully makes it a bit more clear.

@Steve-Mcl
Copy link
Contributor

Steve-Mcl commented Jun 14, 2024

should the command not be packed into ui_control as per other nodes control methods for symetry?

Additionally, shouldnt we emulate the options for both close and confirm e.g. msg.ui_control.close_notification AND/OR msg.ui_control.confirm_notification ?

In fact, since it would be under ui_control it could simply be msg.ui_control.close AND/OR msg.ui_control.confirm ?

@joepavitt
Copy link
Collaborator

@Steve-Mcl I had initially ruled that out because it wasn't persisting any changes, and note we changed it to msg.ui_update. That terminology change is important here.

ui_control reads better in this case, and we could introduce that alongside ui_update, to differentiate between one-off calls/commands vs. overriding of a property?

@joepavitt
Copy link
Collaborator

ui_control reads better in this case, and we could introduce that alongside ui_update, to differentiate between one-off calls/commands vs. overriding of a property?

What are your thoughts @bartbutenaers @colinl ?

@bartbutenaers
Copy link
Contributor Author

@joepavitt
I made some progress for the dynamic properties:

notification_dynamic_properties

[{"id":"beaecd4993da0288","type":"ui-switch","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"","label":"switch","group":"182c087288129e9e","order":1,"width":0,"height":0,"passthru":false,"decouple":false,"topic":"topic","topicType":"msg","style":"","className":"","onvalue":"Machine Started","onvalueType":"str","onicon":"","oncolor":"","offvalue":"Machine Stopped","offvalueType":"str","officon":"","offcolor":"","x":130,"y":160,"wires":[["584b6aaa89870656"]]},{"id":"b669d2649ba2f496","type":"debug","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Notification output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":690,"y":160,"wires":[]},{"id":"584b6aaa89870656","type":"ui-notification","z":"4aad778b57d4f47b","g":"6394e962049dadeb","ui":"be29745a6e568f30","position":"center center","colorDefault":false,"color":"#f41515","displayTime":"0","showCountdown":true,"outputs":1,"allowDismiss":true,"dismissText":"Skip","allowConfirm":false,"confirmText":"","raw":false,"className":"","name":"","x":470,"y":160,"wires":[["b669d2649ba2f496"]]},{"id":"6c971642351df5e3","type":"inject","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Close notification","props":[{"p":"ui_update.close","v":"true","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":160,"y":100,"wires":[["584b6aaa89870656"]]},{"id":"deb020c3693a2513","type":"inject","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Position top center","props":[{"p":"ui_update","v":"{\"position\":\"top center\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":210,"y":220,"wires":[["584b6aaa89870656"]]},{"id":"12dacd88f6be4e7d","type":"inject","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Color orange","props":[{"p":"ui_update","v":"{\"color\":\"orange\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":230,"y":320,"wires":[["584b6aaa89870656"]]},{"id":"5be412e2e8fc9d34","type":"inject","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Show confirm button","props":[{"p":"ui_update","v":"{\"allowConfirm\":true,\"confirmText\":\"Let's go\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":210,"y":420,"wires":[["584b6aaa89870656"]]},{"id":"cdfb2e3bd87b1815","type":"inject","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Hide dismiss button","props":[{"p":"ui_update","v":"{\"allowDismiss\":false}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":210,"y":560,"wires":[["584b6aaa89870656"]]},{"id":"1af3465cd2962de9","type":"inject","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Dynamic title 1","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Dynamic title 1","payloadType":"str","x":220,"y":620,"wires":[["584b6aaa89870656"]]},{"id":"8f99e507001af622","type":"inject","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Hide countdown bar","props":[{"p":"ui_update","v":"{\"showCountdown\": false}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":210,"y":760,"wires":[["584b6aaa89870656"]]},{"id":"1f42a55f41791c8a","type":"inject","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Progress color light green","props":[{"p":"ui_update","v":"{\"progressColor\": \"lightGreen\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":550,"y":820,"wires":[["584b6aaa89870656"]]},{"id":"51f13a9f6ba4549d","type":"inject","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Accept raw html","props":[{"p":"ui_update","v":"{\"raw\": true}","vt":"json"},{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"<b style=\"color:red;\">Red text</b>","payloadType":"str","x":220,"y":820,"wires":[["584b6aaa89870656"]]},{"id":"85616f21ca71b9fa","type":"inject","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Show dismiss button","props":[{"p":"ui_update","v":"{\"allowDismiss\":true,\"dismissText\":\"Cancel\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":210,"y":520,"wires":[["584b6aaa89870656"]]},{"id":"c30c6cbbb799895b","type":"inject","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Show countdown bar","props":[{"p":"ui_update","v":"{\"showCountdown\": true}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":200,"y":720,"wires":[["584b6aaa89870656"]]},{"id":"593ad4d37c38b413","type":"inject","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Position center center","props":[{"p":"ui_update","v":"{\"position\":\"center center\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":200,"y":260,"wires":[["584b6aaa89870656"]]},{"id":"81502b8c45d8df7a","type":"inject","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Color light green","props":[{"p":"ui_update","v":"{\"color\":\"lightgreen\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":220,"y":360,"wires":[["584b6aaa89870656"]]},{"id":"3ac83bac84929c3a","type":"inject","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Hide confirm button","props":[{"p":"ui_update","v":"{\"allowConfirm\":false}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":210,"y":460,"wires":[["584b6aaa89870656"]]},{"id":"93ed9dedd53112e7","type":"inject","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Dynamic title 2","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Dynamic title 2","payloadType":"str","x":220,"y":660,"wires":[["584b6aaa89870656"]]},{"id":"2e30133557f53167","type":"inject","z":"4aad778b57d4f47b","g":"6394e962049dadeb","name":"Don't accept raw html","props":[{"p":"ui_update","v":"{\"raw\": false}","vt":"json"},{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"<b style=\"color:red;\">Red text</b>","payloadType":"str","x":200,"y":860,"wires":[["584b6aaa89870656"]]},{"id":"182c087288129e9e","type":"ui-group","name":"Historiek","page":"b262ac19caee413d","width":"11","height":"1","order":1,"showTitle":true,"className":"","visible":"true","disabled":"false"},{"id":"be29745a6e568f30","type":"ui-base","name":"UI Name","path":"/dashboard","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control","ui-chart","ui-text-input","ui-dropdown"],"showPathInSidebar":false,"titleBarStyle":"default"},{"id":"b262ac19caee413d","type":"ui-page","name":"Sensors historiek","ui":"be29745a6e568f30","path":"/sensors","icon":"thermometer","layout":"grid","theme":"a965ccfef139317a","order":10,"className":"","visible":"true","disabled":"false"},{"id":"a965ccfef139317a","type":"ui-theme","name":"Default","colors":{"surface":"#404040","primary":"#109fbc","bgPage":"#e8e8e8","groupBg":"#d6d6d6","groupOutline":"#6fbc10"},"sizes":{"pagePadding":"12px","groupGap":"12px","groupBorderRadius":"4px","widgetGap":"12px"}}]

The new helper functions really simplify developing things like this!! Great job!!

However the part that goes via the data store is still not clear to me. I currently only store the input message in the data store, if it contains a payload, because the payload contains the text that needs to be displayed. I have used the payload to send the text content, because I assume that that is the 'value' for this widget? Because that is the value that will be different between most notifications. Not sure if that is correct?

Because I also need to show/hide the notification. Should that be a boolean dynamic property msg.ui_update.show, because I cannot send a boolean in my payload (because I already use the payload for my notification text)?

Hope that my question is a bit clear? I don't want the message to be displayed every time I inject a message to change some or another dynamic property...

@joepavitt
Copy link
Collaborator

I currently only store the input message in the data store, if it contains a payload, because the payload contains the text that needs to be displayed.

I think this is sensible given our current API

Should that be a boolean dynamic property msg.ui_update.show, because I cannot send a boolean in my payload (because I already use the payload for my notification text)?

I'd be sending that via msg.show. For me, msg.ui_update.<property> should be used to override Node-RED configuration, and are values that would persist. In this case, msg.show is a "control" type event, not an override of a configuration/property.

@bartbutenaers
Copy link
Contributor Author

To explain my doubt a bit. I had understood the new way of working like this: all dynamic properties are stored in the state store. And the "value" of the widget is stored in the payload, so it will end up in the data store. But what is considerd as 'the value' of e.g. a notification widget? It could be the text that you display. But it could also be the fact whether you show or hide the notification. Would be nice to hear your thoughts about this...

@bartbutenaers
Copy link
Contributor Author

Hi guys,
I "think" everything is ok now. It looks to me that the failed E2E tests are not related to this PR.

All the properties can now be overridden dynamically.
And the msg.show non-persistent field is being used to hide/show the notification dialog.

Here is my latest example flow:

[{"id":"beaecd4993da0288","type":"ui-switch","z":"4aad778b57d4f47b","name":"","label":"switch","group":"182c087288129e9e","order":1,"width":0,"height":0,"passthru":false,"decouple":false,"topic":"topic","topicType":"msg","style":"","className":"","onvalue":"Machine Started","onvalueType":"str","onicon":"","oncolor":"","offvalue":"Machine Stopped","offvalueType":"str","officon":"","offcolor":"","x":150,"y":100,"wires":[["59cd96e254b1e44d"]]},{"id":"b669d2649ba2f496","type":"debug","z":"4aad778b57d4f47b","name":"Notification output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":830,"y":100,"wires":[]},{"id":"584b6aaa89870656","type":"ui-notification","z":"4aad778b57d4f47b","ui":"be29745a6e568f30","position":"center center","colorDefault":false,"color":"#f41515","displayTime":"0","showCountdown":true,"outputs":1,"allowDismiss":true,"dismissText":"Skip","raw":false,"className":"","name":"","x":610,"y":100,"wires":[["b669d2649ba2f496"]]},{"id":"6c971642351df5e3","type":"inject","z":"4aad778b57d4f47b","name":"Show notification (all clients)","props":[{"p":"show","v":"true","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":340,"y":160,"wires":[["584b6aaa89870656"]]},{"id":"deb020c3693a2513","type":"inject","z":"4aad778b57d4f47b","name":"Position top center","props":[{"p":"ui_update","v":"{\"position\":\"top center\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":370,"y":260,"wires":[["584b6aaa89870656"]]},{"id":"12dacd88f6be4e7d","type":"inject","z":"4aad778b57d4f47b","name":"Color orange","props":[{"p":"ui_update","v":"{\"color\":\"orange\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":390,"y":360,"wires":[["584b6aaa89870656"]]},{"id":"5be412e2e8fc9d34","type":"inject","z":"4aad778b57d4f47b","name":"Show confirm button","props":[{"p":"ui_update","v":"{\"allowConfirm\":true,\"confirmText\":\"Let's go\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":370,"y":460,"wires":[["584b6aaa89870656"]]},{"id":"cdfb2e3bd87b1815","type":"inject","z":"4aad778b57d4f47b","name":"Hide dismiss button","props":[{"p":"ui_update","v":"{\"allowDismiss\":false}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":370,"y":600,"wires":[["584b6aaa89870656"]]},{"id":"1af3465cd2962de9","type":"inject","z":"4aad778b57d4f47b","name":"Dynamic title 1","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Dynamic title 1","payloadType":"str","x":380,"y":660,"wires":[["584b6aaa89870656"]]},{"id":"8f99e507001af622","type":"inject","z":"4aad778b57d4f47b","name":"Hide countdown bar","props":[{"p":"ui_update","v":"{\"showCountdown\": false}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":370,"y":800,"wires":[["584b6aaa89870656"]]},{"id":"51f13a9f6ba4549d","type":"inject","z":"4aad778b57d4f47b","name":"Accept raw html","props":[{"p":"ui_update","v":"{\"raw\": true}","vt":"json"},{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"<b style=\"color:red;\">Red text</b>","payloadType":"str","x":380,"y":860,"wires":[["584b6aaa89870656"]]},{"id":"85616f21ca71b9fa","type":"inject","z":"4aad778b57d4f47b","name":"Show dismiss button","props":[{"p":"ui_update","v":"{\"allowDismiss\":true,\"dismissText\":\"Cancel\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":370,"y":560,"wires":[["584b6aaa89870656"]]},{"id":"c30c6cbbb799895b","type":"inject","z":"4aad778b57d4f47b","name":"Show countdown bar","props":[{"p":"ui_update","v":"{\"showCountdown\": true}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":360,"y":760,"wires":[["584b6aaa89870656"]]},{"id":"593ad4d37c38b413","type":"inject","z":"4aad778b57d4f47b","name":"Position center center","props":[{"p":"ui_update","v":"{\"position\":\"center center\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":360,"y":300,"wires":[["584b6aaa89870656"]]},{"id":"81502b8c45d8df7a","type":"inject","z":"4aad778b57d4f47b","name":"Color light green","props":[{"p":"ui_update","v":"{\"color\":\"lightgreen\"}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":380,"y":400,"wires":[["584b6aaa89870656"]]},{"id":"3ac83bac84929c3a","type":"inject","z":"4aad778b57d4f47b","name":"Hide confirm button","props":[{"p":"ui_update","v":"{\"allowConfirm\":false}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":370,"y":500,"wires":[["584b6aaa89870656"]]},{"id":"93ed9dedd53112e7","type":"inject","z":"4aad778b57d4f47b","name":"Dynamic title 2","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"Dynamic title 2","payloadType":"str","x":380,"y":700,"wires":[["584b6aaa89870656"]]},{"id":"2e30133557f53167","type":"inject","z":"4aad778b57d4f47b","name":"Don't accept raw html","props":[{"p":"ui_update","v":"{\"raw\": false}","vt":"json"},{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"<b style=\"color:red;\">Red text</b>","payloadType":"str","x":360,"y":900,"wires":[["584b6aaa89870656"]]},{"id":"59cd96e254b1e44d","type":"change","z":"4aad778b57d4f47b","name":"show notification (1 client)","rules":[{"t":"set","p":"show","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":100,"wires":[["584b6aaa89870656"]]},{"id":"f0fdaa8e1cd83af7","type":"inject","z":"4aad778b57d4f47b","name":"Close notification (all clients)","props":[{"p":"show","v":"false","vt":"bool"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":340,"y":200,"wires":[["584b6aaa89870656"]]},{"id":"6330f32fe804b0c6","type":"inject","z":"4aad778b57d4f47b","name":"Display time endless","props":[{"p":"ui_update","v":"{\"displayTime\": 0}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":370,"y":960,"wires":[["584b6aaa89870656"]]},{"id":"71a8a17786c3e85a","type":"inject","z":"4aad778b57d4f47b","name":"Display time 5 secs","props":[{"p":"ui_update","v":"{\"displayTime\": 5}","vt":"json"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":370,"y":1000,"wires":[["584b6aaa89870656"]]},{"id":"182c087288129e9e","type":"ui-group","name":"Historiek","page":"b262ac19caee413d","width":"11","height":"1","order":1,"showTitle":true,"className":"","visible":"true","disabled":"false"},{"id":"be29745a6e568f30","type":"ui-base","name":"UI Name","path":"/dashboard","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control","ui-chart","ui-text-input","ui-dropdown"],"showPathInSidebar":false,"titleBarStyle":"default"},{"id":"b262ac19caee413d","type":"ui-page","name":"Sensors historiek","ui":"be29745a6e568f30","path":"/sensors","icon":"thermometer","layout":"grid","theme":"a965ccfef139317a","order":10,"className":"","visible":"true","disabled":"false"},{"id":"a965ccfef139317a","type":"ui-theme","name":"Default","colors":{"surface":"#404040","primary":"#109fbc","bgPage":"#e8e8e8","groupBg":"#d6d6d6","groupOutline":"#6fbc10"},"sizes":{"pagePadding":"12px","groupGap":"12px","groupBorderRadius":"4px","widgetGap":"12px"}}]

Although the info panel might need to be updated Currently all the properties are described under Properties but also under Dynamic properties because all properties can be overridden. Not sure if that is correct? On the other hand the Properties section contain the descriptions like in the config screen, while the Dynamic properties section contains the msg property names. So that is useful information, but every property description text is twice available in the info panel...

@bartbutenaers
Copy link
Contributor Author

BTW using the msg.show to show/hide the notification dialog is a breaking change.
Although I am wondering if this widget is currently being used a lot, since it contains quite a number of issues.

@joepavitt
Copy link
Collaborator

BTW using the msg.show to show/hide the notification dialog is a breaking change.

Why so? Are you no longer showing the notification on a new msg.payload anymore?

I'd interpreted the msg.show feature as an override to force open/close, even if a new msg.payload wasn't sent.

If a msg with a msg.payload is injected, then I would still expect it to show

@bartbutenaers
Copy link
Contributor Author

Ok then indeed no breaking change.
Had interpreted you incorrectly, that the msg.show was the (only) way to go.
But makes sense indeed...
Will update the code tonight.
Enjoy your (small) break!!

@bartbutenaers
Copy link
Contributor Author

The logic has been adapted, to show the notification when there is an msg.payload or when msg.show is true. When that is not the case, the notification will be hidden when msg.show is false.

@bartbutenaers
Copy link
Contributor Author

I had forgotton to add documentation for the msg.show field.
Don't think there are "known" issues, so I consider this pull request ready for review...

@Steve-Mcl
Copy link
Contributor

I had forgotton to add documentation for the msg.show field. Don't think there are "known" issues, so I consider this pull request ready for review...

If this is ready for final review Bart, can you refresh the review request please?

image
(hit the spinner button)

Copy link
Contributor

@gayanSandamal gayanSandamal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bartbutenaers Thanks for improving the ui notification widget. Improvements are really helpful.

I found that there's a minor issue with the fill colour of the notification progress and added my comment

ui/src/widgets/ui-notification/UINotification.vue Outdated Show resolved Hide resolved
@gayanSandamal gayanSandamal self-requested a review August 20, 2024 10:12
Copy link
Contributor

@gayanSandamal gayanSandamal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me

@gayanSandamal gayanSandamal removed the request for review from joepavitt August 20, 2024 10:13
@joepavitt joepavitt self-requested a review August 20, 2024 12:13
Copy link
Collaborator

@joepavitt joepavitt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gayanSandamal's approval is good enough for me here - let's get this in

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants