feat(viewer): compact status and severity table icons

This commit is contained in:
2026-04-22 21:19:12 +03:00
parent 2fb01d30a6
commit 34ebaa524d
9 changed files with 322 additions and 241 deletions

View File

@@ -49,6 +49,7 @@ var hiddenTableFields = map[string]struct{}{
const vendorDeviceIDField = "ven:dev"
var commonPreferredColumns = []string{
"severity_icon",
"status",
"slot",
"location",
@@ -333,6 +334,9 @@ func collectColumns(section string, rows []map[string]any) []string {
}
seen[key] = struct{}{}
}
if hasSeverity(row) {
seen["severity_icon"] = struct{}{}
}
if hasVendorDeviceID(row) {
seen[vendorDeviceIDField] = struct{}{}
}
@@ -494,6 +498,9 @@ func formatStringValue(value string) string {
}
func formatRowValue(column string, row map[string]any) string {
if column == "severity_icon" {
return strings.TrimSpace(formatValue(row["severity"]))
}
if column == vendorDeviceIDField {
return formatVendorDeviceID(row)
}
@@ -589,6 +596,10 @@ func hasVendorDeviceID(value map[string]any) bool {
return formatVendorDeviceID(value) != ""
}
func hasSeverity(value map[string]any) bool {
return strings.TrimSpace(formatValue(value["severity"])) != ""
}
func isHiddenTableField(section string, key string) bool {
if isHiddenField(key) {
return true

View File

@@ -47,6 +47,18 @@ func TestRenderHTMLIncludesKnownSectionsAndFields(t *testing.T) {
t.Fatalf("expected rendered html to contain %q", needle)
}
}
for _, needle := range []string{
`<th class="status-column" aria-label="status"></th>`,
`<td class="status-column">`,
`<span class="status-badge status-ok" role="img" aria-label="OK" title="OK"></span>`,
} {
if !strings.Contains(text, needle) {
t.Fatalf("expected rendered html to contain %q", needle)
}
}
if strings.Contains(text, "<th>status</th>") {
t.Fatalf("expected status table headers to be rendered without visible text")
}
if strings.Contains(text, "2026-03-15T12:00:00Z") {
t.Fatalf("expected RFC3339 timestamp to be rendered in human-readable form")
@@ -266,6 +278,12 @@ func TestRenderHTMLGroupsPCIeDevicesByClass(t *testing.T) {
if strings.Contains(text, "<th>device_class</th>") {
t.Fatalf("expected device_class column to be hidden from PCIe tables")
}
if !strings.Contains(text, `<th class="status-column" aria-label="status"></th>`) {
t.Fatalf("expected grouped PCIe tables to render compact status header cells")
}
if !strings.Contains(text, `<span class="status-badge status-warning" role="img" aria-label="Warning" title="Warning"></span>`) {
t.Fatalf("expected grouped PCIe tables to render icon-only status cells with accessible labels")
}
if strings.Index(text, "<h3>Display controller</h3>") > strings.Index(text, "<h3>Network controller</h3>") {
t.Fatalf("expected PCIe class groups to be sorted by device_class")
}
@@ -307,10 +325,17 @@ func TestRenderHTMLAddsSeverityFilterForEventLogs(t *testing.T) {
`<option value="info">Info</option>`,
`data-severity="critical"`,
`data-severity="info"`,
`<th class="status-column" aria-label="severity"></th>`,
`<span class="status-badge severity-info" role="img" aria-label="Info" title="Info"></span>`,
`<span class="status-badge severity-critical" role="img" aria-label="Critical" title="Critical"></span>`,
`<th>severity</th>`,
"/static/view.js",
} {
if !strings.Contains(text, needle) {
t.Fatalf("expected rendered html to contain %q", needle)
}
}
if strings.Contains(text, "<th>severity_icon</th>") {
t.Fatalf("expected synthetic severity icon column header to remain visually empty")
}
}