Common problem: Different dashboard for different users?

Hello! I note that they are a lot of people searching for this but I have not the answer:

I try to configure different dashboards for different users, in order to limit the interaction with some devices or to avoid visibility of some devices for some peoples.

What could be the best solution?

Thanks!
Diego

Multiple Users

This Dashboard does NOT support multiple individual users. It is a view of the status of the underlying Node-RED flow, which itself is single user. If the state of the flow changes then all clients will get notified of that change.

Messages coming from the dashboard do have a msg.socketid , and updates like change of tab, notifications, and audio alerts will be directed only to that session. Delete the msg.sessionid to send to all sessions.

If you need a true multiuser dashboard (eg with logins) then you need to build your own. The node-red-contrib-uibuilder is a great place to start as you can bring whatever ui tooling framework you like to the party.

As Dave says, node-red-contrib-uibuilder gives you a lot more flexibility than Dashboard at the cost of you needing to do rather more coding.

I'm currently working on a security model for uibuilder which will make adding security to it a lot easier. There is another recent thread in this forum if you are interested in following along and maybe testing and contributing ideas.

Unfortunately getting security right isn't easy, especially when using websockets for the majority of the data transfer as both Dashboard and uibuilder do. So it is taking some time to get it right.

I'll throw in my 2 cents worth:

Granted NR doesn't support multi users.

Say you have 3 users.

Build a dashboard for all 3.

In the settings (somewhere) there is an option to not show the other dashboard drop down menu.
Set it so it doesn't show the drop down.

Each "dashboard" would have a different url - it used to be easier I remember where it would be "IP address":1880/ui/<number>
and that would point you to a particular dashboard.

That would work.
In the browser you would have to hide the URL part so the person couldn't enter another address.

Possible?

Actually, NR does. Dashboard doesn't. It is a complex piece of engineering, very clever and nice for beginners. Not so nice when you reach the cliff-edge.

That's why I created uibuilder. Yes, you currently trade all those pre-built cards for the flexibility and if I had the time, I'd have already created a framework that would let you do something similar with uibuilder without losing the flexibility - I already have the ideas just not the time to build it right now (not sure about the skills, time will tell! :grinning:). We are slowly getting there though and even Dashboard took a couple of years to reach maturity.

It is a useful idea to make the UI simpler for users but of course doesn't provide any security. Since Dashboard is a single-page app, all the components are always loaded I think.

@TotallyInformation
Ok.

Thanks.

It was just a passing thought/suggestion/idea.

All good.

what i have done today, is to start 3 sessions of node-red within the same host using PM2. The first NR session handle everyting include admin dashbaord. The other 2 NR handle only dashboard.
those 3 NR share/get the same data from mongoDB in which getting updated from 1st NR session.
i also use NGINX to route from address/ui1, address/ui2, address/ui3 to address:1880/ui, address:1881/ui, address:1882/ui

the limitation is, it's still 1 user for 1 NR stance. Actually, you can have many users for 1 NR instance but they are all having the same screen.
/tee

1 Like

There is usually a way with Node-RED :grinning:

I use something like this so that several users can see one information or another.
You can open several dashboards with the same Tab but different information

[{"id":"1c28f0b4.d543ff","type":"ui_template","z":"3923e77f.c8fa98","group":"51e32ed.b394cd","name":"","order":2,"width":"6","height":"7","format":"<!--div data-ng-init=\"send({payload:action()})\"></div-->\n\n<div > mi mensaje</div>   \n<div ng-bind-html=\"msg.Date\"></div>\n<div ng-bind-html=\"msg.payload\"></div>\n<div ng-bind-html=\"msg.parameter\"></div>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":580,"y":880,"wires":[[]]},{"id":"ff72f324.94dff","type":"ui_template","z":"3923e77f.c8fa98","group":"51e32ed.b394cd","name":"datepicker","order":1,"width":"0","height":"0","format":"\n\n<div id=\"PickerDate\" align=\"center\">\n\n    <span id=\"TabulationSpace\"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong></span>\n    \n    <span id=\"SelectDate\"><strong>Seleccionar fecha:&nbsp;</strong></span>\n    \n    <input type=\"date\" id=\"fecha\" onchange=\"DatePicker()\">\n    \n    <span id=\"TabulationSpace\"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</strong></span>\n    \n    <md-button ng-click=\"send(action())\" id=\"actualizarTablero\" >\n        Actualizar Tablero \n    </md-button>\n</div>\n\n<script>\n\n    \n    n = new Date();\n    y = n.getFullYear();\n    m = n.getMonth() + 1;\n    d = n.getDate();\n    \n    document.querySelector('input[type=\"date\"]').value =  y+ \"-\" + m + \"-\" +d ;\n\n\n    \n    var date=document.querySelector('input[type=\"date\"]').value;\n    \n    function DatePicker(){\n        var date = document.querySelector('input[type=\"date\"]').value;\n        obj.Date = date;\n    }\n    var obj = {\"Date\":date};\n    DatePicker();\n \n    this.scope.action = function() { return obj; }\n</script>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":130,"y":880,"wires":[["1c28f0b4.d543ff","ef0455d8.bb0038"]]},{"id":"ef0455d8.bb0038","type":"debug","z":"3923e77f.c8fa98","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":450,"y":920,"wires":[]},{"id":"51e32ed.b394cd","type":"ui_group","z":"","name":"Default","tab":"5dff7e29.bb9b2","disp":true,"width":"23","collapse":false},{"id":"5dff7e29.bb9b2","type":"ui_tab","z":"","name":"hometest","icon":"dashboard","disabled":false,"hidden":false}]

Based on this, I could do from panels to insert parameters

(I admit new tips)