Problem using ui-control

@joepavitt

I'm having trouble using UI control! I send the object to it with the page I want to display and nothing works. I confess that I find the use of pages and groups in dashboard 2.0 quite confusing. Create a page and place an element in it without a group and the page is not displayed on the left side like others with a group. The nodes ui control asks me to indicate a page for it to be pinned. I confess that I don't understand its use well. In 1.0 this manipulation was very simple, but it is very confusing. I'm also having problems with the constant need to update the page manually, something that 1.0 does naturally.

image

Please do not post question on other topics, as this makes it hard for other to search for solutions.

I have moved this question to its own topic.

Hi @diegodamaceno - there seem to be a few points being made in this post:

  1. ui-control not working
  2. The confusion of pages and groups
  3. If a template is page-scoped, it does not show in the side navigation "Dashboard 2.0" menu
  4. The need to update the UI each time (I'm guessing you mean refresh here?)
  5. The screenshot you've included which is not linked to any of the previous 4 points

I will tackle the points separetely below:

1. ui-control not working

The ui-control needs to be bound to a UI/Dashboard. Eventually, we would like to support multiple Dashboards/UIs in a single Node-RED instance, and this plan is what drives the need for the "UI" choice each time.

As long as you've bound it to your "UI" in the ui-control configuration, the ui-control should work. If it is not, please let me know what msg.payload you are sending to it.

If you're looking to force a navigation, then you will just need to include the page name as a string in the msg.payload

2. The confusion of pages and groups

The use of groups and pages was explicitly taken from the original Node-RED Dashboard. There is no difference in their implementation, so I'm not sure what you think has changed?

The only additional layer we have introduced is the "UI", which is a layer below "Pages", i.e. your UI contains all of your pages.

3. Page Scoped Templates

This is likely a bug

4. Refresh Required

I'm not aware of this being a requirement, it certainly shouldn't be. What are you trying to update/refresh whereby this is a requirement?

5. Screenshot

Please raise an issue on GitHub for this, that is a bug within the Node-RED sidebar.

I would first like to apologize for the way I put together the post to explain the problems I have. I will explain it better in this post.

I'm building my user control just like I did in 1.0. Create a page with a simple login.

<template>
    <div class="card_login" ref="card">
        <div class="title_login">Login</div>
        <v-otp-input class="input_login" length="6" v-model="senha" @keyup.enter="sendOTP"></v-otp-input>
        <v-btn class="button_login" @click="sendOTP">Autorizar</v-btn>
    </div>
</template>

<script>
    export default {
        data() {
            return {              
                senha:'',
            };
        },
        methods: {            
            sendOTP() {
                setTimeout(() => {                    
                    this.$refs.card.$el.style.backgroundColor = '#FF8C00';
                }, 1000);

                setTimeout(() => {
                    this.send({ payload: this.senha });
                    this.senha = '';
                }, 2000);
            },
        }        
    }
</script>

<style>
    .card_login {
        display: flex;
        flex-direction: column;
        margin: auto;
        height: 150px;
        width: 250px;
        background-color: #4F4F4F;
        border: 1px solid #000000;
        border-radius: 18px;
    }

    .input_login {
        display: flex;
        margin: auto;
        font-size: 14px;
        height: 5%;
        width: 90%;
    }

    .button_login {
        display: flex;
        margin: auto;
        height: 5% !important;
        width: 50% !important;
        background-color: #4F4F4F !important;
        border: 1px solid #000000;
        border-radius: 10px;
        color: #000000;
    }

    .title_login {
        display: flex;
        margin: auto;
        font-size: 14px;
        color: #000000;
    }
</style>

image

<template>
    <v-btn class="buton_logoff" ref="botao" stacked @click="start">
      <div class="title_logoff">Logoff</div>
      <v-icon class="icon_logoff" ref="icon" style="font-size: 40px;">{{ icone }}</v-icon>
    </v-btn>
</template>

<script>
  export default {
    data() {
      return {
        icone: 'mdi-power-on'
       };
    },
    methods: {
      start: function () {        
        this.icone = 'mdi-power-on';
        this.$refs.icon.$el.style.color = '#BD9608';
        this.$refs.icon.$el.style.textShadow = '0px 0px 10px #BD9608';

        setTimeout(() => {
          this.icone = 'mdi-power-cycle';
          this.$refs.icon.$el.style.color = '#A9A9A9';
          this.$refs.icon.$el.style.textShadow = '0px 0px 0px';          
        }, 1000);

        setTimeout(() => {
          this.icone = 'mdi-power-off';
          this.$refs.icon.$el.style.color = '#A9A9A9';
          this.$refs.icon.$el.style.textShadow = '0px 0px 0px';
        }, 2000);

        setTimeout(() => {
          this.send({ payload: 'ON' });
        }, 3000);

      },
    }
  };
</script>

<style>
  .buton_logoff {
    display: flex; 
    flex-direction: column; 
    margin: auto; 
    height: 75px; 
    width: 75px; 
    background-color: #FF8C00; 
    color: #000000; 
    border: 1px solid #000000; 
    font-size: 14px; 
    border-radius: 18px;
  }
  .title_logoff {
    font-size: 75%;
  }
</style>

if (msg.payload === "780705") {

    node.send([{ payload: { "page": "Neway Automações" }}])

    setTimeout(function () {
        node.send([{payload:{pages:{ hide: ["Neway Automações", "Login"]}}}])
    }, 10);

} else {
    null
}




After the last update, some bugs were resolved, so I still only have the problem of disabling groups that are not disappearing from the panel when they are marked as hide.

I am not sure, exactly, what the problem is so I hope this is not 'teaching granny to suck eggs'

Using just the function above does hide the relevant pages. The problem is, if you are ON page 'Neway Automações' although it has been hidden in the menu, you are still on the page.

Try node.send([{ payload: { "page": "Another Page" }}])

If you are trying to hide groups then you need 'groups' not 'pages'

Is it intentional that you have wrapped your msg in an array?

node.send([{ payload: { "page": "Neway Automações" }}])

Would send: msg = [{ payload: { "page": "Neway Automações" }}]

ui-control is looking for a msg.payload, which your msg doesn't have.

In fact, Sending an array of objects sends them to multiple outputs, so element 0 goes to o/p 1, element 1 to o/p 2 etc. An array of just one object sends it to o/p 1. So sending an array is pointless, but harmless, in this case.

That may depend on dashboards implementation of send (been a while since I looked at the implementation)

I thought this was in a function node.

:man_facepalming: My bad!

Everything I showed is functional, but it doesn't work when configured for groups. I will leave a function that I already use successfully in 1.0 that in the same way or in the same way does not work in 2.0.

node.send([{payload:{"tab":"Painel Neway Automações"}}])

setTimeout(function () {
    
    msg.payload = {
        "tabs": {
            "show": [                
                "Painel_Neway_Automações",
                "Rastreio"
            ]
        }
    };

    node.send(msg); 
}, 25);

setTimeout(function () {

    msg.payload = {
        "group": {
            "show": [
                "Painel_Neway_Automações_Luzes",
                "Painel_Neway_Automações_Energia",
                "Painel_Neway_Automações_Controle_TV",
                "Painel_Neway_Automações_Funcionalidades",
                "Painel_Neway_Automações_Refrigeração",
                "Painel_Neway_Automações_Movimentação",
                "Painel_Neway_Automações_Ativação_Individual",
                "Painel_Neway_Automações_Controle_Alexa",
                "Painel_Neway_Automações_Servidor",
                "Painel_Neway_Automações_ChatGPT",
                "Painel_Neway_Automações_Relógio",
                "Painel_Neway_Automações_IR",
                "Painel_Neway_Automações_Fitas_Led",
                "Painel_Neway_Automações_Entretenimento",
                "Painel_Neway_Automações_Usuário"
            ]
        }
    };

    node.send(msg);
}, 50); 
 
setTimeout(function () {

    msg.payload = {
        "group": {
            "show": [
                "Rastreio_Localização",
                "Rastreio_Usuário"                
            ]
        }
    };

    node.send(msg);
}, 75); 

The syntax or groups is slightly different, see docs

Note that a group is specified by "<page name>:"<group name>", not just "group_name".

I also have an open PR that's just been reviewed that will improve the error reporting here.

So with the default below, how would I go about accessing the "Neway Automações" page and hiding the "Fitas" group?

if (msg.payload === "780705") {

    node.send([{ payload: { "page": "Neway Automações" }}])

    setTimeout(function () {
        node.send([{payload:{pages:{ hide: ["Neway Automações", "Login"]}}}])
    }, 10);

} else {
    null
}

As per the documentation, to hide a group you'd need to do:

msg.payload = {
    groups: {
        hide: ["Neway Automações:Fitas"]
    }
}

Now yes, perfect.

if (msg.payload === 780705) {

    node.send({payload:{ "page": "Neway Automações" }})

    setTimeout(function () {
        node.send({payload:{pages:{ hide: ["Neway Automações"]}}})
    }, 25);

    setTimeout(function () {
        node.send({payload: {groups: {hide: ["Neway Automações:Fitas"]}}})
    }, 50);
    
}

HI all,

I also had to experiment quite a bit with getting UI-Control to do what I wanted. What worked for me:

Put the code below in a (not-ui, bet generic NodeRED) Template node:

> { 
>     "pages": {
>         "enable": ["PageName"]
>         },
>     "groups": {
>         "enable": ["PageName:GroupName"] 
>     }
> }

Then set the Template node to output as Parsed JSON and send this to UI-Control.

Sending as Plain text would generate errors (array errors, page can not be found, etc), as would using ' instead of ". Setting the page name in the groups array is a requirement. Omitting the " surrounding pages and groups will also result in an error.

Documentation does not cover using Template node, which imho would be the most low-code option.

The UI-Control node appears to be picky and unforgiving with regard to its required input. Only got it working after several hours of experimenting (over several days..). Very frustrating and as said the docs don't help much.
Hope someone will benefit from this. And yes, the UI-Control node needs some work (imho).

What are you using to trigger the injection? The more "Node-RED" way of doing this is with a Change node - and set msg.payload accordingly.

The docs are very clear that an object is required. I would argue it was reasonable for it to fail when sending "plain text" i.e. a string, or using ' as neither are valid JSON payloads.

The documentation of the ui-control node details how to use the ui-control node. I don't think it is reasonable for me to have to detail every variation of other Node-RED nodes that could format an object. That’s general Node-RED learning, that whilst its valuable, doesn't belong in Node-RED Dashboard documentation.

I am open to documentation improvements, but I will stand on a hill and say that I support everything that the documentation details, i.e. if you follow the specifications detailed in the documentation, it will work.

1 Like

Please do open issues detailing the expected areas of improvement and link to them here. I stand by though that ui-control does everything it specifies in the documentation reliably.

@joepavitt

Now trying this approach without success. Using a function node to do a simple password validation and thus implementing the panel and groups that such a password can show.

if (msg.payload === "780705") {
    node.send({ payload: { "page": "Neway Automações" } });

    setTimeout(function () {
        node.send({
            payload: {
                groups: {
                    show: [
                        "Neway Automações:Fitas",
                        "Neway Automações:Luzes",
                        "Neway Automações:Movimentos",
                        "Neway Automações:Servidor",
                        "Neway Automações:Entretenimento",
                        "Neway Automações:Funcionalidades",
                        "Neway Automações:Ativação Individual",
                        "Neway Automações:Alexa"
                    ]
                }
            }
        });
    }, 25);

    setTimeout(function () {
        node.send({ payload: { pages: { hide: ["Neway Automações"] } } });
    }, 50);

    setTimeout(function () {
        node.send({ payload: { pages: { show: ["Login"] } } });
    }, 75);
}

All parts run, but the part that shows all groups does not work.

setTimeout(function () {
        node.send({
            payload: {
                groups: {
                    show: [
                        "Neway Automações:Fitas",
                        "Neway Automações:Luzes",
                        "Neway Automações:Movimentos",
                        "Neway Automações:Servidor",
                        "Neway Automações:Entretenimento",
                        "Neway Automações:Funcionalidades",
                        "Neway Automações:Ativação Individual",
                        "Neway Automações:Alexa"
                    ]
                }
            }
        });
    }, 25);

Which version of @flowfuse/node-red-dashboard are you running? Do you see any errors in the Node-RED debug panel, the the developer tools console in the browser, or in the console logs for Node-RED itself?