# Dashboard 2.0 is now Generally Available

**URL:** <https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913>\
**Category:** Dashboard\
**Tags:** dashboard-2\
**Created:** [25 January 2024 16:59 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913 "2024-01-25T16:59:41Z")\
**Posts on this page:** 20\
**Page:** 5

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [2 February 2024 20:11 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/81 "2024-02-02T20:11:08Z")

</div>

Well I just don't want to be remembered as the man who turned every bit and byte to gauges... 🤣

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [2 February 2024 23:41 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/82 "2024-02-02T23:41:42Z")

</div>

> [@hotNipi](#):
>
> Well I just don't want to be remembered as the man who turned every bit and byte to gauges

Oops, might be a bit late for that! 🤣

But then they are absolutely on-topic for everyone using Node-RED for IoT and more. Can't beat a good gauge.  
 ![OutOfGasGIF](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/d/6/d6b384e65aabaffc0f8764fde2e45347fd23cb0d.gif)

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [3 February 2024 21:02 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/83 "2024-02-03T21:02:51Z")

</div>

7 posts were split to a new topic: [Dashboard 2 - Multi-state switch](https://discourse.nodered.org/t/dashboard-2-multi-state-switch/85168)

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [8 February 2024 10:20 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/84 "2024-02-08T10:20:40Z")

</div>

> [@TheSaltydog](#):
>
> Any news for a Gauge widget?

My phone beeped and the news is that Gauge is not far away anymore.

> <https://github.com/FlowFuse/node-red-dashboard/pull/530>
>
> \## Description
> 
> \- Add new, purpose built UI Gauge widget
> \- Uses d3js for rend…ering & animation
> 
> \### Segments
> 
> Allows for more customisation over the colours/banding that was available in Dashboard 1.0:
> 
> \<img width="685" alt="Screenshot 2024-01-26 at 19 10 58" src="https://github.com/FlowFuse/node-red-dashboard/assets/99246719/42603dd2-75aa-44e4-8e67-8867313e270d"\>
> 
> \### Example (First Draft)
> 
> https://github.com/FlowFuse/node-red-dashboard/assets/99246719/ee6772b0-f93f-40fd-abdf-c9f68b983b69
> 
> \## Still to do
> 
> Still lots to do on this, main priority items:
> 
> \- \[x\] Labels, Titles & Value displayed
> \- \[x\] Value formatting
> \- \[x\] Config Options: for sizing/thickness
> \- \[x\] Config Option: b/g color of arc
> \- \[x\] Config Option: Show/Hide the "segments" bar
> \- \[x\] Config Option: \`arc.cornerRadius()\`
> \- \[x\] Support Different "Angles" - Rather than free flowing 0-360 option, may make this a dropdown of 90, 180, 270, 360
> \- \[\] Different Gauge "types"
> - This always felt a little forced in Dashboard 1.0 with compass, levels, etc, so may avoid this, and do separate widget types.
> 
> \## Related Issue(s)
> 
> Closes #12 
> 
> \## Checklist
> 
> 
> 
> - \[x\] I have read the \[contribution guidelines\](https://github.com/FlowFuse/flowfuse/blob/main/CONTRIBUTING.md)
> - \[\] Suitable unit/system level tests have been added and they pass
> - \[\] Documentation has been updated

Still, I did some cleanup and improvements for my creations,  
🔔 It is now 3 of them merged all in one template. Configure look and feel.  
🔔 It can be adjusted too look nice on light or dark background  
🔔 Gauges do resize. 1x1 for round gauge is a bit too small. 2x1 container is optimal.  
🔔 Configuration is easy and every bit is commented - read carefully.

Feel free to use, adjust or change and make it look and feel it as you wish.

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/8/c8b8b8e352f0eee0e3b2e8d5271d62c20fb4e58a.png)

TEMPLATE:

```auto
<template>
    <template v-if="type === 'round'">
        <div ref="hng" class="round-led-level" :style="`--size:${size}; --shadow:${shadow}; --ledsize:${ledSize};`">
            <header>
                <div class="round-led-level-text">
                    <span class="round-led-level-label">{{label}}</span>
                </div>
            </header>
            <div>
                <div class="round-led-level-stripe">
                    <div v-for="(color, index) in colors" :key="index" class="round-led-level-led"
                        :ref="'dot-' + index"></div>
                </div>
                <div class="round-led-level-centered-text">
                    <span class="round-led-level-value">{{formattedValue}}</span>
                    <span class="round-led-level-unit">{{unit}}</span>
                </div>
                <div class="round-led-level-limits">
                    <span>{{min}}</span>
                    <span>{{max}}</span>
                </div>
            </div>
            <div>
    </template>
    <template v-if="type === 'linear'">
        <div ref="hng" class="led-level" :style="`--shadow:${shadow};`">
            <div class="led-level-text">
                <span class="led-level-label">{{label}}</span>
                <span class="led-level-value">{{formattedValue}}<span class="led-level-unit">{{unit}}</span></span>
            </div>
            <div class="led-level-stripe">
                <div v-for="(color, index) in colors" :key="index" class="led-level-led" :ref="'dot-' + index"></div>
            </div>
            <div class="led-level-limits">
                <span>{{min}}</span>
                <span>{{max}}</span>
            </div>
            <div>
    </template>
    <template v-if="type === 'artless'">
        <div ref="hng" :class="icon ? 'ag-wrapper-2' : 'ag-wrapper-1'" :style="`--line-color:${colors[0]};`">
            <div v-if="icon" class="ag-icon">
                <v-icon aria-hidden="false">{{icon}}</v-icon>
            </div>
            <div class="ag-content">
                <div class="ag-text">
                    <span class="ag-label">{{label}}</span>
                    <span class="ag-value">{{formattedValue}}<span class="ag-unit">{{unit}}</span></span>
                </div>
                <div class="ag-track" ref="agLine">
                    <div class="ag-track-background"></div>
                    <div class="ag-track-foreground" :style="{'width': percentage +'%'}"></div>
                </div>
                <div class="ag-limits">
                    <span class="ag-min">{{min}}</span>
                    <span class="ag-max">{{max}}</span>
                </div>
            </div>
        </div>
    </template>
</template>

<script>
    export default {
    data(){
        return {
            //Define me here
            type:"round", // Gauge type. "artless", "linear" or "round"                                          
            label:"Round Gauge", // The label
            icon:"mdi-account", // (type: artless) (optional) the icon
            min:0, // Smallest expected value
            max:100, // Highest expected value
            unit:"cm³",// The unit of the measurement
            dim:0.3, //(type: round, linear) How dim is led when not glowing
            shadow:0.5, //(type: round, linear) Led shadow intensity (too much makes graphics muddy)
            filterFunction:"brightness", // (type: round, linear) "brightness" for dark themes, "opacity" for light themes  
            animate:true, // Animating led's is not most performant thing in the world.                          
            
            // Define colors

            // For type "round" and "linear" the count of colors equals count of led's.
            // For type "artless" first color from colors array is used.  
            // For type "round" the led size depends on how many colors is defined. About 20 is optimal.
            // Color can be defined as:
            // HEX - "#FF00FF" 
            // RGB - rgb(0,65,88)
            // named color - "red"
            // or depend on some defined CSS variable      
            colors:[                   
                    "rgb(var(--v-theme-success))",
                    "rgb(var(--v-theme-success))",
                    "rgb(var(--v-theme-success))",
                    "rgb(var(--v-theme-success))",
                    "rgb(var(--v-theme-success))",
                    "rgb(var(--v-theme-success))",
                    "rgb(var(--v-theme-success))",
                    "rgb(var(--v-theme-success))",
                    "rgb(var(--v-theme-success))",
                    "rgb(var(--v-theme-success))",
                    "rgb(var(--v-theme-success))",
                    "rgb(var(--v-theme-success))",
                    "rgb(var(--v-theme-success))",
                    "rgb(var(--v-theme-warning))",
                    "rgb(var(--v-theme-warning))",
                    "rgb(var(--v-theme-warning))",
                    "rgb(var(--v-theme-error))",
                    "rgb(var(--v-theme-error))",
                   ],            
            
            //no need to change those
            value:0,
            previousValue:0,
            size:100,           
            inited:false
        }
    },

   
    methods: {        
        getElement: function(name,base){        
            if(base){
                return this.$refs[name]
            }
            return this.$refs[name][0]
        },
        validate(data){
            let ret
            if(typeof data !== "number"){
                ret = parseFloat(data)
                if(isNaN(ret)){
                    console.log("BAD DATA! gauge type:",this.type, "id:",this.id,"data:",data)
                    return null
                }   
            }
            else{
                ret = data
            }
            
            return ret
        },

        full: function(){
            return Math.floor(this.colors.length*this.percentage/100)
        },
        half: function (){
            let p = this.colors.length*this.percentage/100;
            p -= this.full()
            p *= .5
            p += this.dim;
            return p;
        },
        filter: function(amount){
            let f
            switch(amount){
                case "full":{
                    f = this.filterFunction == "brightness" ? "brightness(1.1)" : "opacity(1)";
                    break
                }
                case "half":{
                    f = this.filterFunction == "brightness" ? "brightness(" +this.half()+")" : "opacity(" +this.half()+")";
                    break
                }
                default:{
                    f = this.filterFunction == "brightness" ? "brightness(" +this.dim+")" : "opacity(" +this.dim+")";
                    break
                }
            }
            return f
        },

        lit: function(){
            if(this.inited == false){
                return
            }
            const down = this.previousValue > this.value

            let time = .01
            this.colors.forEach((e,i) => {
                let dot = this.getElement("dot-"+i);
                if(!dot){
                    console.log("lit() no dots found")
                    return
                }                
                if(i<this.full()){
                    dot.style.filter=this.filter("full");
                    dot.style.outlineColor="#ffffff40" ;
                }
                else if(i==this.full()){
                    dot.style.filter= this.filter("half");
                    dot.style.outlineColor="#ffffff40" ;
                }
                else{
                    dot.style.filter= this.filter("dim");
                    dot.style.outlineColor="#00000040" ;
                }
                if(down){
                    time = (this.colors.length - i) * .12                    
                }
                dot.style.transition = this.animate ? "filter "+time+"s" : "unset";
            })
            this.previousValue = this.value
        },
        onResize:function(){            
            let g = this.getElement("hng",true)
            if(!g){
                return
            }
            this.$nextTick(() => {
                this.size = g.clientWidth;
                this.updateLayout()
            })
           g.style.setProperty('--size',this.size);          
        },
        updateLayout:function(){
            let angle;
            const step = 270 / this.colors.length;
            const radius = (this.size - (this.size*0.1))/2
            const s = this.ledSize / -2;        
            this.colors.forEach((c,i) => {
                    let dot = this.getElement("dot-"+i);
                    if(!dot){
                        console.log("round init() no dots found")
                        return
                    }
                    dot.style.backgroundColor = c               
                    dot.style.transition = "filter 0.1s";
                    dot.style.setProperty('--dot',i);
                    angle = ((i+1)*step) * Math.PI / 180;
                    dot.style.left = s + radius * Math.cos(angle) + 'px';
                    dot.style.top = s + radius * Math.sin(angle) + 'px';
                    dot.style.transform = 'translate('+s+'px, '+s+'px)'; 
                    dot.style.rotate = (angle - 0.08)+"rad"               
                }
            )
        }
    },
    watch: {
        msg: function(){    
            if(this.msg.payload != undefined){  
                const v = this.validate(this.msg.payload)
                if(!v){
                    return
                }         
                this.value = v
                if(this.type != "artless"){
                    this.lit()
                } 
            }
        }
    },
    computed: {
        formattedValue: function () {
            return this.value.toFixed(2)
        },
        percentage: function(){
            return Math.floor(((this.value - this.min) / (this.max - this.min)) * 100);
        },                
        ledSize:function(){
            const s = 4.71239 * ((this.size - (this.size*0.3))/2)            
            return s / this.colors.length
        }
    },
    mounted(){
        if(this.type == "round"){
            let g = this.getElement("hng",true)
            if(!g){
                return
            }            
            this.resizeObserver = new ResizeObserver((entries) => {
                this.onResize()
            });
            this.resizeObserver.observe(g);           
            
            setTimeout(()=>{
                this.onResize()
            },20)
        }
        else if(this.type == "linear"){
            this.colors.forEach((c,i) => {
                    let dot = this.getElement("dot-"+i);
                    if(!dot){
                        console.log("linear init() no dots found")
                        return
                    }
                    dot.style.backgroundColor = c               
                    dot.style.transition = "filter 0.1s";
                }
            )
        }
        else{
            const line = this.getElement("agLine",true);
            line.style.setProperty('--line-color',this.colors[0])
            if(this.animate == true){                
                if(!line){
                    console.log("artless init() no line found")
                    return
                }
                line.style.transition = "width 0.5s";
            }
        }        
       
        this.inited = true;
    },
    unmounted () {
        if(this.resizeObserver){
            this.resizeObserver.disconnect();
            this.resizeObserver = null;            
        }
    },
}
</script>

```

CSS:

```auto
.led-level{
    display: grid;
    grid-template-rows: 1.3em 1fr .7em;
    gap: 2px;
}
.led-level-stripe{
    display: flex;
    gap:2px;
}    
.led-level-led {
    --s:var(--shadow,0.2);
    --shadowColor:rgba(0,0,0,var(--s));
    background: #ffffff;
    width: 100%;
    height: 100%;
    border-radius: 4px;
    box-shadow: inset 0px 0px 10px 0px var(--shadowColor), 0px 0px 3px 0px var(--shadowColor);
    filter: brightness(0.4);
}
.led-level-text{
    font-size: 1.25em;
    line-height: 1em;
    align-self: end;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    user-select: none;
}
.led-level-value{       
    font-weight:bold;
}
.led-level-unit{
    font-size:.75em;
    font-weight:normal;
    padding-inline-start: 0.15em;
}
.led-level-limits{
    display: flex;
    justify-content: space-between;
    font-size: .75em;
    line-height: .75em;
    align-content: flex-end;
    flex-wrap: wrap;
     user-select: none;
}
.round-led-level{
    display: grid;
    grid-template-rows: 1em 1fr;
    width:100%;
    height: 100%;
    aspect-ratio: 1/1;
    position: relative;
    margin: auto;
}
.round-led-level>div{
    position: relative;;
}
.round-led-level-stripe{
    display: block;
    position: absolute;
    left: 50%;
    top: 56%;
    rotate: 135deg;  
}    
.round-led-level-led {
    --s:var(--shadow,0.2);
    --shadowColor:rgba(0,0,0,var(--s));
    background: #ffffff;
    position: absolute;
    width: calc(var(--ledsize) * 1px);
    aspect-ratio: 1/1;
    border-radius: 4px;
    box-shadow: inset 0px 0px calc(var(--ledsize) / 3 * 1px) 0px var(--shadowColor), 0px 0px calc(var(--ledsize) / 7 * 1px) 0px var(--shadowColor);
    filter: brightness(0.4);
    transform-origin: center center;
}
.round-led-level-text{    
    font-size: clamp(0.5em,calc(var(--size) * .1 * 1px),1.25em);
    line-height: 1rem;
    text-align: center;
    user-select: none;
    white-space: nowrap;
}
.round-led-level-centered-text{
    position: absolute;
    inset: 0;
    font-size: 1rem;
    line-height: 1;
    display: grid;
    text-align: center;
    grid-template-rows: 1.5fr 1fr;
    gap: 0.1em;
    user-select: none;   
    align-items: center;
}
.round-led-level-value{       
    font-weight:bold;
    font-size: calc(var(--size) * .15 * 1px);
    align-self: end;
}
.round-led-level-unit{
    font-size:calc(var(--size) * .1 * 1px);
    font-weight:normal;
    align-self: start;
    padding-inline-start: 0.15em;
}
.round-led-level-limits{
    position: absolute;
    inset:0; 
    display: flex;
    justify-content: space-between;
    font-size: calc(var(--size) * .06 * 1px);
    line-height: calc(var(--size) * .06 * 1px);
    align-content: flex-end;
    flex-wrap: wrap;
    padding-inline:1em;
    user-select: none;
}
.ag-wrapper-2 {
    display: grid;
    grid-template-columns: 3em 1fr;
    gap:1em;
}
.ag-wrapper-1 {
    display: grid;
    grid-template-columns: 1fr;   
}
.ag-icon{
    font-size: 2em;
    display: flex;
    flex-direction: column;
    justify-content: center;        
}
.ag-content{
    display: grid;
    grid-template-rows: 1fr 7px 0.75em;
    gap: 2px;
}
.ag-text{
    font-size: 1.25em;
    line-height: 1em;
    align-self: end;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    user-select: none;
}
.ag-value{       
    font-weight:bold;
}
.ag-unit{
    font-size:.75em;
    font-weight:normal;
    padding-inline-start: 0.15em;
}
.ag-limits{
    display: flex;
    justify-content: space-between;
    font-size: .75em;
    line-height: .75em;
    align-content: center;
    flex-wrap: wrap;
    user-select: none;
}

.ag-track{
    position:relative;
    display:flex;
    align-items: center;
    width: 100%;
    border-radius: 6px;
}

.ag-track-background{
    position:absolute;
    background: var(--line-color,rgb(var(--v-theme-primary)));
    opacity: 0.45;
    width: 100%;
    height: 50%;
    border-radius:inherit;
}
.ag-track-foreground{
    position:absolute;
    background-color: var(--line-color,rgb(var(--v-theme-primary)));
    width: 50%;
    height: 100%;
    max-width: 100%;
    border-radius:inherit;
    transition:inherit;
}

```

---

<div class="post-metadata">

**Author:** ![joepavitt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/joepavitt/32/59722_2.png) [@joepavitt](https://discourse.nodered.org/u/joepavitt)\
**Post date:** [8 February 2024 10:33 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/85 "2024-02-08T10:33:15Z")

</div>

Yep - new UI Gauge _should_ go out today. It doesn't have the linear/compass options yet, and I don't have the segmented style so beautifully demonstrated by @hotNipi - but you can see a preview of it here: [New Widget: UI Gauge by joepavitt · Pull Request #530 · FlowFuse/node-red-dashboard · GitHub](https://github.com/FlowFuse/node-red-dashboard/pull/530#issuecomment-1932336771) and a breakdown of the examples (in the docs that are already live) here: [Gauge ui-gauge | Node-RED Dashboard 2.0](https://dashboard.flowfuse.com/nodes/widgets/ui-gauge.html)

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [8 February 2024 20:52 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/86 "2024-02-08T20:52:46Z")

</div>

5 posts were merged into an existing topic: [UI Gauge is Available](https://discourse.nodered.org/t/ui-gauge-is-available/85318/5)

---

<div class="post-metadata">

**Author:** ![diegodamaceno](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/diegodamaceno/32/85742_2.png) [@diegodamaceno](https://discourse.nodered.org/u/diegodamaceno)\
**Post date:** [9 February 2024 15:02 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/87 "2024-02-09T15:02:45Z")

</div>

Having this css for the page, can you help me make the title bar also transparent? @joepavitt @hotNipi

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/7/2/7218b77a7721ebaab4845175da2120189dffcaa6.jpeg)

```auto

/* cuida do fundo */
.v-main {
    background-image: url('/fundo.jpg');
    background-size: cover;
}

/* cuida do grupo */
.nrdb-ui-group .v-card {    
    background-color: #00000040 !important; /* cuida da cor do fundo dos grupos do menu */
    border-radius: 10px !important; /* cuida da curva dos cantos do cartão de grupo */
    border: 1px solid #000000;
    color: #ffffff;
    
}

/* cuida do estilo de fonte a pagina */
body {
    font-family: monospace;
}

/* cuida do menu */
.v-navigation-drawer {
    background-color: #00000040;   
}

/* cuida da cor do titulo do grupo */
.v-card-title {
    color: #ffffff;
}

/* cuida da cor do titulo do menu */
.v-list-item-title {
    color: #ffffff;
}

```

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [9 February 2024 15:23 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/88 "2024-02-09T15:23:19Z")

</div>

```auto
.v-app-bar.v-toolbar {
    background: transparent;
}

```

---

<div class="post-metadata">

**Author:** ![diegodamaceno](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/diegodamaceno/32/85742_2.png) [@diegodamaceno](https://discourse.nodered.org/u/diegodamaceno)\
**Post date:** [9 February 2024 16:03 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/89 "2024-02-09T16:03:10Z")

</div>

The journey continues and I really appreciate everyone's help... I'm already able to bring my look to d2.... now we have the icon in the top left corner that I need to understand which v- is to be able to help the color.. = ]

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/4/e/4e9a123921d7283acc3672323160e8a35c2d5ecc.jpeg)

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [9 February 2024 16:09 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/90 "2024-02-09T16:09:05Z")

</div>

> [@diegodamaceno](#):
>
> I need to understand which v- is to be able to help the color.

Use the browsers dev tools to find the path each and every item you wish to adjust.

[![](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/5/0/50ff13c4674eeb457cd32f04dead6985b8044431.jpeg "DevTools tip: Copy CSS selectors") ](https://www.youtube.com/watch?v=9URg-Xd8xYs)

---

<div class="post-metadata">

**Author:** ![joepavitt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/joepavitt/32/59722_2.png) [@joepavitt](https://discourse.nodered.org/u/joepavitt)\
**Post date:** [9 February 2024 16:28 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/91 "2024-02-09T16:28:01Z")

</div>

As per @Steve-Mcl's note, if you're in Chrome for example, right click it \> "Inspect Element", and it'll show the CSS classes applied to that element which you can use for a selector.

---

<div class="post-metadata">

**Author:** ![diegodamaceno](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/diegodamaceno/32/85742_2.png) [@diegodamaceno](https://discourse.nodered.org/u/diegodamaceno)\
**Post date:** [11 February 2024 11:32 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/92 "2024-02-11T11:32:25Z")

</div>

Thank you to everyone who is helping me, everything went well and I'm already moving forward with the project.

---

<div class="post-metadata">

**Author:** ![diegodamaceno](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/diegodamaceno/32/85742_2.png) [@diegodamaceno](https://discourse.nodered.org/u/diegodamaceno)\
**Post date:** [20 February 2024 16:21 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/93 "2024-02-20T16:21:16Z")

</div>

@hotNipi

I'm counting on the help of insurance to get out of this:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/9/8/981db47259e0d5ad68fdda2ceaead9025ebde335.png)

```auto
<template>
    <div class="card_alexa">
        <div class="play_stop">
            <v-btn class="button_play" ref="button" stacked @click="play">
                <v-icon class="icon_cinema" ref="icon">mdi-play</v-icon>
            </v-btn>
            <v-btn class="button_stop" stacked @click="stop">
                <v-icon class="icon_cinema">mdi-stop</v-icon>
            </v-btn>
        </div>                        
        <v-slider class="slider_alexa"></v-slider>
        <v-text-field class="text_alexa"></v-text-field>          
    </div>
</template>

<style>
    .card_alexa {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        height: 250px;
        width: 250px;
        background-color: #4F4F4F;
        border: 1px solid #000000;
        border-radius: 18px;
    }
    .play_stop {
        display: flex;
        flex-direction: row;
        justify-content: center;
    }
    .button_play, .button_stop {
        background-color: transparent;
    }
    .slider_alexa {
        width: 80%;
    }
    .text_alexa {
        display: flex;
        justify-content: center; /* Alinha horizontalmente ao centro */
        align-items: center; /* Alinha verticalmente ao centro */
        width: 80%; /* Defina a largura desejada */
        height: auto; /* Permita que a altura se ajuste conforme o conteúdo */
        margin: auto; /* Adiciona margem automática para centralizar horizontalmente */
    }

</style>

```

For this or similar.

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/2/b2d8a86128d4607904663ad0474870e52adee2a2.png)

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [20 February 2024 16:35 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/94 "2024-02-20T16:35:19Z")

</div>

I'm holding my dog's nose in my hands. She's waking up after surgery. We have here a lot of things to care about for next couple of day's. So it must wait.

---

<div class="post-metadata">

**Author:** ![joepavitt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/joepavitt/32/59722_2.png) [@joepavitt](https://discourse.nodered.org/u/joepavitt)\
**Post date:** [20 February 2024 16:50 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/95 "2024-02-20T16:50:10Z")

</div>

Worth pointing out that using the Vuetify components (e.g. `v-btn`) is optional, you can still use the raw HTML elements too and apply (entirely) your own CSS, without needing to override Vuetify's class assignments.

---

<div class="post-metadata">

**Author:** ![diegodamaceno](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/diegodamaceno/32/85742_2.png) [@diegodamaceno](https://discourse.nodered.org/u/diegodamaceno)\
**Post date:** [21 February 2024 20:28 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/96 "2024-02-21T20:28:59Z")

</div>

New element that measures ping to simply show whether the connection is good or bad. Below is the code and function I use.

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/f/5/f59d86ebd7d1d0fae73432851ce7a2dcca581d15.png)

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/e/3e1e2c0a5ccbdbea5cd519d6c86e9ccbac4564d8.png)

```auto
<template>
    <div class="card_ping">
        <div class="title_ping">{{title}}</div>
        <v-icon class="icon_ping" ref="icon">{{icon}}</v-icon>   
        <div class="title_ping">{{ping}}</div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                icon: "mdi-wifi-strength-outline",                
                title: "--",
                ping: "--"
            };
        },
        methods: {
            online_alto: function () {
                this.icon = "mdi-wifi-arrow-up";
                this.$refs.icon.$el.style.color = '#32CD32';
                this.$refs.icon.$el.style.textShadow = '0px 0px 10px #32CD32';
                this.title = "Online";               
            },
            online_baixo: function () {
                this.icon = "mdi-wifi-arrow-down";
                this.$refs.icon.$el.style.color = '#FF8C00';
                this.$refs.icon.$el.style.textShadow = '0px 0px 10px #FF8C00';
                this.title = "Online";
            },
            offline: function () {
                this.icon = "mdi-wifi-remove";
                this.$refs.icon.$el.style.color = '#A9A9A9';
                this.$refs.icon.$el.style.textShadow = '0px 0px 0px'; 
                this.title = "Offline";               
            }
        },
        watch: {
            msg: function(){
                if(this.msg.payload != undefined){
                    console.log('got message :',this.msg)                 
                    if (this.msg.payload > 0) {
                        if (this.msg.payload < 8) {
                            this.online_alto();
                            this.ping = this.msg.payload;
                        } else {
                            this.online_baixo();
                            this.ping = this.msg.payload;
                        }                               
                                            
                    } else if (this.msg.payload === false) {
                        this.desligar();
                        this.ping = "--";                                        
                    }
                }
            }
        }
    }
</script>

<style>
    .card_ping {
        display: flex;
        flex-direction: column;        
        margin: auto;
        height: 75px !important; 
        width: 75px !important; 
        background-color: #4F4F4F !important;         
        border: 1px solid #000000; 
        font-size: 14px; 
        border-radius: 18px; 
    }
    .title_ping { 
        margin: auto;        
        font-size: 80%;
    }
    .icon_ping {    
        margin: auto;      
        font-size: 35px;
    }
</style>

```

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/a/3a945d3113311c74d80a15809bfd552cd2bb1af3.png)

```auto
if (msg.payload > 0) {
    node.send([{payload: msg.payload}, null])
} else if (msg.payload === false) {
    node.send([null, {payload: msg.payload}])
}

```

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [1 March 2024 16:05 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/97 "2024-03-01T16:05:05Z")

</div>

A post was split to a new topic: [Problem using ui-control](https://discourse.nodered.org/t/problem-using-ui-control/86063)

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [6 March 2024 09:31 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/98 "2024-03-06T09:31:13Z")

</div>

2 posts were split to a new topic: [Dashboard 2 Migration](https://discourse.nodered.org/t/dashboard-2-migration/86182)

---

<div class="post-metadata">

**Author:** ![SveinHa](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/sveinha/32/71169_2.png) [@SveinHa](https://discourse.nodered.org/u/SveinHa)\
**Post date:** [14 March 2024 09:39 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/99 "2024-03-14T09:39:50Z")

</div>

I use quite a bit of text nodes with text formatting like this:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/7/2/726e4f8ce45f55938f9ac6684294efde39027c60.png)

The result looks like this:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/6/c6b1355b657d788766824e07db84e34a924138e7.png)

Is this something that I may expect to be able to do in Dashboard 2.0? Haven't found anything useable so far...

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [14 March 2024 10:52 UTC](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913/100 "2024-03-14T10:52:44Z")

</div>

> [@SveinHa](#):
>
> I use quite a bit of text nodes with text formatting like this:
> 
> ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/7/2/726e4f8ce45f55938f9ac6684294efde39027c60.png)

Dashboard 2 does not (currently) support label formatting. There is an open issue already.

PS: FWIW, [font is depreciated](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/font) (and will one day stop working!)

  

> [@SveinHa](#):
>
> Haven't found anything useable so far...

You can apply CSS styles throughout your dashboard using a template node.

Alternatively, you can use template nodes and `v-cards` to achieve this or any format you desire.

[Previous page](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913.md?page=4)

[Next page](https://discourse.nodered.org/t/dashboard-2-0-is-now-generally-available/84913.md?page=6)
