mirror of
https://github.com/siderolabs/talos.git
synced 2025-10-26 14:01:39 +01:00
When the dashboard is used via the CLI through a proxy, e.g., through Omni, node names or IDs can be used in the `--nodes` flag instead of the IPs. This caused rendering inconsistencies in the dashboard, as some parts of it used the IPs and some used the names passed in the context. Fix this by collecting all node IPs on dashboard start, and map these IPs to the respective nodes passed as the `--nodes` flag. On the dashboard footer, we always display the node names as they are passed in the `--nodes` flag. As part of it, remove the node list change reactivity from the dashboard, so it will always take the passed nodes as the truth. The IP to node mapping collection at dashboard startup also solves another issue where the first API call by the dashboard triggered the interactive API authentication (e.g., the OIDC flow). Previously, because the terminal was already switched to the raw mode, it was not possible to authenticate properly. Signed-off-by: Utku Ozdemir <utku.ozdemir@siderolabs.com>
128 lines
2.7 KiB
Go
128 lines
2.7 KiB
Go
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
package components
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/gdamore/tcell/v2"
|
|
"github.com/rivo/tview"
|
|
"github.com/siderolabs/gen/maps"
|
|
)
|
|
|
|
// Footer represents the top bar with host info.
|
|
type Footer struct {
|
|
tview.TextView
|
|
|
|
selectedNode string
|
|
nodes []string
|
|
|
|
screenKeyToName map[string]string
|
|
|
|
selectedScreen string
|
|
}
|
|
|
|
// NewFooter initializes Footer.
|
|
func NewFooter(screenKeyToName map[string]string, nodes []string) *Footer {
|
|
var initialScreen string
|
|
for _, name := range screenKeyToName {
|
|
initialScreen = name
|
|
|
|
break
|
|
}
|
|
|
|
widget := &Footer{
|
|
TextView: *tview.NewTextView(),
|
|
screenKeyToName: screenKeyToName,
|
|
selectedScreen: initialScreen,
|
|
nodes: nodes,
|
|
}
|
|
|
|
widget.SetDynamicColors(true)
|
|
|
|
// set the background to be a horizontal line
|
|
widget.SetDrawFunc(func(screen tcell.Screen, x, y, width, height int) (int, int, int, int) {
|
|
for i := x; i < x+width; i++ {
|
|
for j := y; j < y+height; j++ {
|
|
screen.SetContent(
|
|
i,
|
|
j,
|
|
tview.BoxDrawingsLightHorizontal,
|
|
nil,
|
|
tcell.StyleDefault.Foreground(tcell.ColorWhite),
|
|
)
|
|
}
|
|
}
|
|
|
|
return x, y, width, height
|
|
})
|
|
|
|
widget.refresh()
|
|
|
|
return widget
|
|
}
|
|
|
|
// OnNodeSelect implements the NodeSelectListener interface.
|
|
func (widget *Footer) OnNodeSelect(node string) {
|
|
widget.selectedNode = node
|
|
|
|
widget.refresh()
|
|
}
|
|
|
|
// SelectScreen refreshes the footer with the tabs and screens data.
|
|
func (widget *Footer) SelectScreen(screen string) {
|
|
widget.selectedScreen = screen
|
|
|
|
widget.refresh()
|
|
}
|
|
|
|
func (widget *Footer) refresh() {
|
|
widget.SetText(fmt.Sprintf(
|
|
"[%s] --- %s",
|
|
widget.nodesText(),
|
|
widget.screensText(),
|
|
))
|
|
}
|
|
|
|
func (widget *Footer) nodesText() string {
|
|
nodesCopy := make([]string, 0, len(widget.nodes))
|
|
|
|
for _, node := range widget.nodes {
|
|
if node == widget.selectedNode {
|
|
name := node
|
|
if name == "" {
|
|
name = "(local)"
|
|
}
|
|
|
|
nodesCopy = append(nodesCopy, fmt.Sprintf("[red]%s[-]", name))
|
|
} else {
|
|
nodesCopy = append(nodesCopy, node)
|
|
}
|
|
}
|
|
|
|
return strings.Join(nodesCopy, " | ")
|
|
}
|
|
|
|
func (widget *Footer) screensText() string {
|
|
screenKeys := maps.Keys(widget.screenKeyToName)
|
|
sort.Strings(screenKeys)
|
|
|
|
screenTexts := make([]string, 0, len(widget.screenKeyToName))
|
|
|
|
for _, screenKey := range screenKeys {
|
|
screen := widget.screenKeyToName[screenKey]
|
|
|
|
if screen == widget.selectedScreen {
|
|
screenTexts = append(screenTexts, fmt.Sprintf("[[red]%s[-]]", screen))
|
|
} else {
|
|
screenTexts = append(screenTexts, fmt.Sprintf("[%s: %s]", screenKey, screen))
|
|
}
|
|
}
|
|
|
|
return strings.Join(screenTexts, " --- ")
|
|
}
|