From 09b4aaa4795313af40acd11f1d2e6dbc4ee9faf0 Mon Sep 17 00:00:00 2001 From: Mikhail Chusavitin Date: Mon, 16 Mar 2026 15:06:18 +0300 Subject: [PATCH] Move firmware mismatch indicators to server card --- internal/api/asset_component_actions_api.go | 23 ++++++++++++--------- internal/api/ui_assets.tmpl | 16 ++++++++++---- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/internal/api/asset_component_actions_api.go b/internal/api/asset_component_actions_api.go index a3eb643..ebac9ea 100644 --- a/internal/api/asset_component_actions_api.go +++ b/internal/api/asset_component_actions_api.go @@ -13,16 +13,17 @@ import ( ) type currentAssetComponentItem struct { - ComponentID string `json:"component_id"` - Status string `json:"status"` - Type string `json:"type,omitempty"` - Slot string `json:"slot,omitempty"` - VendorSerial string `json:"vendor_serial"` - Vendor *string `json:"vendor,omitempty"` - Model *string `json:"model,omitempty"` - Firmware *string `json:"firmware,omitempty"` - InstalledAt *time.Time `json:"installed_at,omitempty"` - CurrentAssetID string `json:"current_asset_id"` + ComponentID string `json:"component_id"` + Status string `json:"status"` + Type string `json:"type,omitempty"` + Slot string `json:"slot,omitempty"` + VendorSerial string `json:"vendor_serial"` + Vendor *string `json:"vendor,omitempty"` + Model *string `json:"model,omitempty"` + Firmware *string `json:"firmware,omitempty"` + FirmwareMismatch bool `json:"firmware_mismatch,omitempty"` + InstalledAt *time.Time `json:"installed_at,omitempty"` + CurrentAssetID string `json:"current_asset_id"` } type currentAssetComponentsFilters struct { @@ -191,6 +192,7 @@ func (h assetComponentHandlers) buildCurrentAssetComponentsPayload(r *http.Reque firmwareByID, _ := h.deps.Installations.ListLatestFirmwareByComponentIDs(r.Context(), ids) metaByID, _ := h.deps.Installations.ListCurrentComponentMetaByIDs(r.Context(), ids) instByID, _ := h.deps.Installations.ListCurrentInstallationsByComponentIDs(r.Context(), ids) + firmwareMismatchByID := detectFirmwareMismatchByComponent(components, firmwareByID) items := make([]currentAssetComponentItem, 0, len(components)) var statuses, types, slots, serials, vendors, models, firmwares []string for _, c := range components { @@ -227,6 +229,7 @@ func (h assetComponentHandlers) buildCurrentAssetComponentsPayload(r *http.Reque v := strings.TrimSpace(fw) item.Firmware = &v } + item.FirmwareMismatch = firmwareMismatchByID[c.ID] items = append(items, item) statuses = append(statuses, item.Status) types = append(types, item.Type) diff --git a/internal/api/ui_assets.tmpl b/internal/api/ui_assets.tmpl index 7d1817d..e0a7f2c 100644 --- a/internal/api/ui_assets.tmpl +++ b/internal/api/ui_assets.tmpl @@ -18,6 +18,9 @@
+ {{if .HasFirmwareMismatch}} +
Firmware mismatch Identical devices on this server have different firmware versions.
+ {{end}}
@@ -98,9 +101,6 @@
- {{if .HasFirmwareMismatch}} -
Firmware mismatch Identical devices on this server have different firmware versions.
- {{end}}
Loading current components…
@@ -734,6 +734,14 @@ if (s === 'unknown') return { badgeClass: 'status-yellow', border: '#f8ddb2', bg: '#fffaf1', label: 'Unknown present' }; return { badgeClass: 'status-green', border: '#bde6cd', bg: '#f5fbf7', label: 'Healthy only' }; } + function firmwareCell(row) { + const firmware = esc(text(row.firmware)); + if (!row.firmware_mismatch) return firmware; + return ` + ${firmware} + ! + `; + } function renderPanel() { if (!panel) return; @@ -793,7 +801,7 @@ ${esc(text(row.vendor_serial))} ${esc(text(row.vendor))} ${esc(text(row.model))} - ${esc(text(row.firmware))} + ${firmwareCell(row)} `; }).join('')}