feat(viewer): compact status and severity table icons
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user