package tui import ( "fmt" "time" ) func (m Model) viewNodesTab() string { if len(m.nodes) == 0 { return "\n No probe nodes connected." } cols := []colDef{ {"NAME", "NAME", 12, 24, true}, {"REGION", "REGION", 8, 14, false}, {"SEEN", "LAST SEEN", 8, 20, false}, {"VER", "VERSION", 8, 12, false}, {"STATUS", "STATUS", 8, 10, false}, } headers, widths := m.computeTableLayout(cols, 0) nameW := widths[0] return m.renderTable( headers, len(m.nodes), func(start, end int) [][]string { var rows [][]string for i := start; i < end; i++ { node := m.nodes[i] name := limitStr(node.Name, nameW-2) if name == "" { name = node.ID } region := node.Region if region == "" { region = subtleStyle.Render("—") } lastSeen := fmtNodeLastSeen(node.LastSeen) version := node.Version if version == "" { version = subtleStyle.Render("—") } status := fmtNodeStatus(node.LastSeen) rows = append(rows, []string{name, region, lastSeen, version, status}) } return rows }, widths, nil, ) } func fmtNodeStatus(lastSeen time.Time) string { if lastSeen.IsZero() { return subtleStyle.Render("UNKNOWN") } ago := time.Since(lastSeen) if ago < 60*time.Second { return specialStyle.Render("ONLINE") } if ago < 5*time.Minute { return warnStyle.Render("STALE") } return dangerStyle.Render("OFFLINE") } func fmtNodeLastSeen(t time.Time) string { if t.IsZero() { return subtleStyle.Render("never") } ago := time.Since(t) if ago < time.Minute { return fmt.Sprintf("%ds ago", int(ago.Seconds())) } if ago < time.Hour { return fmt.Sprintf("%dm ago", int(ago.Minutes())) } return fmt.Sprintf("%dh ago", int(ago.Hours())) }