refactor(viewer): consolidate rendering and harden uploads
This commit is contained in:
+64
-150
@@ -44,16 +44,6 @@ var sectionTitles = map[string]string{
|
||||
|
||||
var preferredMetaKeys = []string{"target_host", "collected_at", "source_type", "protocol", "filename"}
|
||||
|
||||
var hiddenFields = map[string]struct{}{
|
||||
"status_at_collection": {},
|
||||
}
|
||||
|
||||
var hiddenTableFields = map[string]struct{}{
|
||||
"status_checked_at": {},
|
||||
}
|
||||
|
||||
const vendorDeviceIDField = "ven:dev"
|
||||
|
||||
var commonPreferredColumns = []string{
|
||||
"severity_icon",
|
||||
"status",
|
||||
@@ -69,7 +59,8 @@ var commonPreferredColumns = []string{
|
||||
"product_name",
|
||||
"part_number",
|
||||
"serial_number",
|
||||
vendorDeviceIDField,
|
||||
"vendor_id",
|
||||
"device_id",
|
||||
"firmware",
|
||||
"version",
|
||||
"bdf",
|
||||
@@ -136,9 +127,6 @@ func buildMeta(root map[string]any) []fieldRow {
|
||||
rows := make([]fieldRow, 0)
|
||||
used := make(map[string]struct{})
|
||||
for _, key := range preferredMetaKeys {
|
||||
if isHiddenField(key) {
|
||||
continue
|
||||
}
|
||||
if value, ok := root[key]; ok {
|
||||
rows = append(rows, fieldRow{Key: key, Value: formatValue(value)})
|
||||
used[key] = struct{}{}
|
||||
@@ -147,10 +135,9 @@ func buildMeta(root map[string]any) []fieldRow {
|
||||
extraKeys := make([]string, 0)
|
||||
for key := range root {
|
||||
if key == "hardware" {
|
||||
continue
|
||||
}
|
||||
if isHiddenField(key) {
|
||||
continue
|
||||
if _, handledAsSections := root[key].(map[string]any); handledAsSections {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if _, ok := used[key]; ok {
|
||||
continue
|
||||
@@ -208,6 +195,14 @@ func buildSection(key string, value any) []sectionView {
|
||||
Rows: buildFieldRows(typed),
|
||||
}}
|
||||
case []any:
|
||||
if !allObjectItems(typed) {
|
||||
return []sectionView{{
|
||||
ID: key,
|
||||
Title: titleFor(key),
|
||||
Kind: "object",
|
||||
Rows: buildArrayRows(typed),
|
||||
}}
|
||||
}
|
||||
if key == "pcie_devices" {
|
||||
return []sectionView{buildPCIeSection(typed)}
|
||||
}
|
||||
@@ -225,24 +220,57 @@ func buildSection(key string, value any) []sectionView {
|
||||
}
|
||||
|
||||
func buildSensorSections(sensors map[string]any) []sectionView {
|
||||
out := make([]sectionView, 0)
|
||||
orderedKeys := make([]string, 0, len(sensors))
|
||||
used := make(map[string]struct{}, len(sensors))
|
||||
for _, key := range []string{"fans", "power", "temperatures", "other"} {
|
||||
value, ok := sensors[key]
|
||||
if !ok {
|
||||
continue
|
||||
if _, ok := sensors[key]; ok {
|
||||
orderedKeys = append(orderedKeys, key)
|
||||
used[key] = struct{}{}
|
||||
}
|
||||
items, ok := value.([]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
var extraKeys []string
|
||||
for key := range sensors {
|
||||
if _, ok := used[key]; !ok {
|
||||
extraKeys = append(extraKeys, key)
|
||||
}
|
||||
}
|
||||
sort.Strings(extraKeys)
|
||||
orderedKeys = append(orderedKeys, extraKeys...)
|
||||
|
||||
out := make([]sectionView, 0, len(orderedKeys))
|
||||
for _, key := range orderedKeys {
|
||||
var sections []sectionView
|
||||
if key == "sensors" {
|
||||
sections = []sectionView{{ID: key, Title: titleFor(key), Kind: "object", Rows: []fieldRow{{Key: key, Value: formatValue(sensors[key])}}}}
|
||||
} else {
|
||||
sections = buildSection(key, sensors[key])
|
||||
}
|
||||
for _, section := range sections {
|
||||
section.ID = "sensors-" + section.ID
|
||||
section.Title = "Sensors / " + section.Title
|
||||
out = append(out, section)
|
||||
}
|
||||
section := buildTableSection(key, items)
|
||||
section.ID = "sensors-" + key
|
||||
section.Title = "Sensors / " + titleFor(key)
|
||||
out = append(out, section)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func allObjectItems(items []any) bool {
|
||||
for _, item := range items {
|
||||
if _, ok := item.(map[string]any); !ok {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func buildArrayRows(items []any) []fieldRow {
|
||||
rows := make([]fieldRow, 0, len(items))
|
||||
for index, item := range items {
|
||||
rows = append(rows, fieldRow{Key: fmt.Sprintf("[%d]", index), Value: formatValue(item)})
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
func buildTableSection(key string, items []any) sectionView {
|
||||
rows := make([]map[string]any, 0, len(items))
|
||||
for _, item := range items {
|
||||
@@ -258,23 +286,13 @@ func buildTableSection(key string, items []any) sectionView {
|
||||
for _, column := range columns {
|
||||
cells[column] = formatRowValue(column, row)
|
||||
}
|
||||
status := strings.TrimSpace(cells["status"])
|
||||
tableRows = append(tableRows, tableRow{
|
||||
Status: status,
|
||||
Severity: normalizeSeverity(cells["severity"]),
|
||||
Cells: cells,
|
||||
RawCells: row,
|
||||
})
|
||||
}
|
||||
|
||||
return sectionView{
|
||||
ID: key,
|
||||
Title: titleFor(key),
|
||||
Kind: "table",
|
||||
Columns: columns,
|
||||
Items: tableRows,
|
||||
SeverityOptions: collectSeverityOptions(columns, rows),
|
||||
}
|
||||
return sectionView{ID: key, Title: titleFor(key), Kind: "table", Columns: columns, Items: tableRows}
|
||||
}
|
||||
|
||||
func buildPCIeSection(items []any) sectionView {
|
||||
@@ -311,18 +329,11 @@ func buildPCIeSection(items []any) sectionView {
|
||||
cells[column] = formatRowValue(column, row)
|
||||
}
|
||||
items = append(items, tableRow{
|
||||
Status: strings.TrimSpace(cells["status"]),
|
||||
Severity: normalizeSeverity(cells["severity"]),
|
||||
Cells: cells,
|
||||
RawCells: row,
|
||||
})
|
||||
}
|
||||
groups = append(groups, tableGroupView{
|
||||
Title: className,
|
||||
Columns: columns,
|
||||
Items: items,
|
||||
SeverityOptions: collectSeverityOptions(columns, rows),
|
||||
})
|
||||
groups = append(groups, tableGroupView{Title: className, Columns: columns, Items: items})
|
||||
}
|
||||
|
||||
return sectionView{
|
||||
@@ -337,7 +348,7 @@ func collectColumns(section string, rows []map[string]any) []string {
|
||||
seen := make(map[string]struct{})
|
||||
for _, row := range rows {
|
||||
for key := range row {
|
||||
if isHiddenTableField(section, key) {
|
||||
if section == "pcie_devices" && key == "device_class" {
|
||||
continue
|
||||
}
|
||||
seen[key] = struct{}{}
|
||||
@@ -345,9 +356,6 @@ func collectColumns(section string, rows []map[string]any) []string {
|
||||
if hasSeverity(row) {
|
||||
seen["severity_icon"] = struct{}{}
|
||||
}
|
||||
if hasVendorDeviceID(row) {
|
||||
seen[vendorDeviceIDField] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
columns := make([]string, 0, len(seen))
|
||||
@@ -366,72 +374,14 @@ func collectColumns(section string, rows []map[string]any) []string {
|
||||
return append(columns, extra...)
|
||||
}
|
||||
|
||||
func collectSeverityOptions(columns []string, rows []map[string]any) []severityOption {
|
||||
if !containsColumn(columns, "severity") {
|
||||
return nil
|
||||
}
|
||||
|
||||
seen := make(map[string]string)
|
||||
for _, row := range rows {
|
||||
label := strings.TrimSpace(formatRowValue("severity", row))
|
||||
value := normalizeSeverity(label)
|
||||
if value == "" {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[value]; ok {
|
||||
continue
|
||||
}
|
||||
seen[value] = canonicalSeverityLabel(label, value)
|
||||
}
|
||||
if len(seen) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
knownOrder := []string{"critical", "warning", "info"}
|
||||
options := make([]severityOption, 0, len(seen))
|
||||
for _, value := range knownOrder {
|
||||
label, ok := seen[value]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
options = append(options, severityOption{Value: value, Label: label})
|
||||
delete(seen, value)
|
||||
}
|
||||
|
||||
extraValues := make([]string, 0, len(seen))
|
||||
for value := range seen {
|
||||
extraValues = append(extraValues, value)
|
||||
}
|
||||
sort.Strings(extraValues)
|
||||
for _, value := range extraValues {
|
||||
options = append(options, severityOption{Value: value, Label: seen[value]})
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
||||
func containsColumn(columns []string, target string) bool {
|
||||
for _, column := range columns {
|
||||
if column == target {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func buildFieldRows(object map[string]any) []fieldRow {
|
||||
keys := make([]string, 0, len(object))
|
||||
for key := range object {
|
||||
if isHiddenField(key) {
|
||||
continue
|
||||
}
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
rows := make([]fieldRow, 0, len(keys))
|
||||
if combinedVendorDeviceID := formatVendorDeviceID(object); combinedVendorDeviceID != "" {
|
||||
rows = append(rows, fieldRow{Key: vendorDeviceIDField, Value: combinedVendorDeviceID})
|
||||
}
|
||||
for _, key := range keys {
|
||||
rows = append(rows, fieldRow{Key: key, Value: formatValue(object[key])})
|
||||
}
|
||||
@@ -468,9 +418,6 @@ func formatValue(value any) string {
|
||||
func formatObjectValue(value map[string]any) string {
|
||||
keys := make([]string, 0, len(value))
|
||||
for key := range value {
|
||||
if isHiddenField(key) {
|
||||
continue
|
||||
}
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
@@ -509,9 +456,6 @@ 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)
|
||||
}
|
||||
return formatValue(row[column])
|
||||
}
|
||||
|
||||
@@ -544,15 +488,6 @@ func canonicalSeverityLabel(raw, normalized string) string {
|
||||
}
|
||||
}
|
||||
|
||||
func formatVendorDeviceID(value map[string]any) string {
|
||||
vendorID := strings.TrimSpace(formatValue(value["vendor_id"]))
|
||||
deviceID := strings.TrimSpace(formatValue(value["device_id"]))
|
||||
if vendorID == "" || deviceID == "" {
|
||||
return ""
|
||||
}
|
||||
return vendorID + ":" + deviceID
|
||||
}
|
||||
|
||||
func formatDate(value string) (string, bool) {
|
||||
layouts := []struct {
|
||||
layout string
|
||||
@@ -592,33 +527,10 @@ func titleFor(key string) string {
|
||||
return strings.ReplaceAll(strings.Title(strings.ReplaceAll(key, "_", " ")), "Pcie", "PCIe")
|
||||
}
|
||||
|
||||
func isHiddenField(key string) bool {
|
||||
if key == "vendor_id" || key == "device_id" {
|
||||
return true
|
||||
}
|
||||
_, ok := hiddenFields[key]
|
||||
return ok
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
if section == "pcie_devices" && key == "device_class" {
|
||||
return true
|
||||
}
|
||||
_, ok := hiddenTableFields[key]
|
||||
return ok
|
||||
}
|
||||
|
||||
func sortPCIeRows(rows []map[string]any) {
|
||||
sort.SliceStable(rows, func(i, j int) bool {
|
||||
left := []string{
|
||||
@@ -627,7 +539,8 @@ func sortPCIeRows(rows []map[string]any) {
|
||||
formatRowValue("vendor", rows[i]),
|
||||
formatRowValue("model", rows[i]),
|
||||
formatRowValue("serial_number", rows[i]),
|
||||
formatRowValue(vendorDeviceIDField, rows[i]),
|
||||
formatRowValue("vendor_id", rows[i]),
|
||||
formatRowValue("device_id", rows[i]),
|
||||
formatRowValue("bdf", rows[i]),
|
||||
}
|
||||
right := []string{
|
||||
@@ -636,7 +549,8 @@ func sortPCIeRows(rows []map[string]any) {
|
||||
formatRowValue("vendor", rows[j]),
|
||||
formatRowValue("model", rows[j]),
|
||||
formatRowValue("serial_number", rows[j]),
|
||||
formatRowValue(vendorDeviceIDField, rows[j]),
|
||||
formatRowValue("vendor_id", rows[j]),
|
||||
formatRowValue("device_id", rows[j]),
|
||||
formatRowValue("bdf", rows[j]),
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user