Move firmware mismatch indicators to server card

This commit is contained in:
Mikhail Chusavitin
2026-03-16 15:06:18 +03:00
parent 373b02111a
commit 09b4aaa479
2 changed files with 25 additions and 14 deletions

View File

@@ -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)

View File

@@ -18,6 +18,9 @@
</div>
<div class="meta" id="asset-recompute-message" style="margin-bottom: 8px;"></div>
<div class="meta" id="asset-edit-message" style="margin-bottom: 12px;"></div>
{{if .HasFirmwareMismatch}}
<div class="meta" style="margin-bottom: 12px;"><span class="badge status-yellow">Firmware mismatch</span> Identical devices on this server have different firmware versions.</div>
{{end}}
<div style="display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); gap:16px; align-items:start;">
<div class="meta-grid">
<div>
@@ -98,9 +101,6 @@
<button class="button" id="current-components-remove" type="button" disabled>Remove</button>
</div>
</div>
{{if .HasFirmwareMismatch}}
<div class="meta"><span class="badge status-yellow">Firmware mismatch</span> Identical devices on this server have different firmware versions.</div>
{{end}}
<div class="meta" id="current-components-message" style="margin-bottom: 10px;"></div>
<div id="current-components-panel" data-asset-id="{{.Asset.ID}}">
<div class="meta">Loading current components…</div>
@@ -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 `<span style="display:inline-flex; align-items:center; gap:6px;">
<span>${firmware}</span>
<span class="badge status-yellow" title="Firmware version differs from an identical component on this server" aria-label="Firmware mismatch">!</span>
</span>`;
}
function renderPanel() {
if (!panel) return;
@@ -793,7 +801,7 @@
<td>${esc(text(row.vendor_serial))}</td>
<td>${esc(text(row.vendor))}</td>
<td>${esc(text(row.model))}</td>
<td>${esc(text(row.firmware))}</td>
<td>${firmwareCell(row)}</td>
</tr>`;
}).join('')}
</tbody>