Add UI enhancements: charts, firmware summary, uninstalled components, source chips
- Dashboard: line charts (assets over time, components total + uninstalled)
with filled areas, shared x-axis (Mon YYYY), auto-formatted y-labels (1k/1M)
and global start date derived from earliest FirstSeenAt across components
- /ui/ingest/history: source type chips (Ingest / CSV Import / Manual / System)
- /ui/component/models: firmware version count column, column filters,
sortable headers, vendor distribution pie chart
- /ui/component/{vendor}/{model}: firmware version summary table with
per-version healthy/unknown/failed counts, failed rows highlighted
- /ui/component/uninstalled: new page + nav item; components not installed
on any server, two-level grouping by vendor then model (collapsed by default)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
65
internal/api/ui_components_uninstalled.tmpl
Normal file
65
internal/api/ui_components_uninstalled.tmpl
Normal file
@@ -0,0 +1,65 @@
|
||||
{{define "components_uninstalled"}}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
{{template "head" .}}
|
||||
<body>
|
||||
{{template "topbar" .}}
|
||||
{{template "breadcrumbs" .}}
|
||||
|
||||
<main class="container">
|
||||
<section class="card">
|
||||
<h2>Uninstalled Components</h2>
|
||||
<div class="meta" style="margin-bottom:16px;">Components not currently installed in any server. Grouped by vendor, then by model.</div>
|
||||
|
||||
{{if .VendorGroups}}
|
||||
{{range .VendorGroups}}
|
||||
<details style="margin-bottom:12px; border:1px solid #e5e7eb; border-radius:10px; overflow:hidden;">
|
||||
<summary style="list-style:none; cursor:pointer; padding:12px 16px; background:#f8fafc; display:flex; align-items:center; justify-content:space-between; gap:12px;">
|
||||
<div style="font-weight:600; font-size:14px;">{{.Vendor}}</div>
|
||||
<div class="timeline-card-badges">
|
||||
<span class="timeline-card-badge">{{.Total}} components</span>
|
||||
<span class="timeline-card-badge">{{len .ModelGroups}} models</span>
|
||||
</div>
|
||||
</summary>
|
||||
<div style="padding:12px 16px; display:flex; flex-direction:column; gap:10px;">
|
||||
{{range .ModelGroups}}
|
||||
<details style="border:1px solid #e5e7eb; border-radius:8px; overflow:hidden;">
|
||||
<summary style="list-style:none; cursor:pointer; padding:8px 12px; background:#f1f5f9; display:flex; align-items:center; justify-content:space-between; gap:12px;">
|
||||
<span style="font-weight:500; font-size:13px;">{{.Model}}</span>
|
||||
<span class="timeline-card-badge">{{len .Components}}</span>
|
||||
</summary>
|
||||
<div style="padding:8px 0;">
|
||||
<table class="table" data-disable-auto-filters="true">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Status</th>
|
||||
<th>Vendor Serial</th>
|
||||
<th>Vendor</th>
|
||||
<th>Model</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{range .Components}}
|
||||
<tr class="clickable" onclick="navigateToRow('{{.URL}}')">
|
||||
<td><span class="badge {{componentStatusClass .Status}}">{{componentStatusText .Status}}</span></td>
|
||||
<td><a href="{{.URL}}" onclick="event.stopPropagation();">{{.Component.VendorSerial}}</a></td>
|
||||
<td>{{if .Component.Vendor}}{{.Component.Vendor}}{{else}}—{{end}}</td>
|
||||
<td>{{if .Component.Model}}{{.Component.Model}}{{else}}—{{end}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</details>
|
||||
{{end}}
|
||||
</div>
|
||||
</details>
|
||||
{{end}}
|
||||
{{else}}
|
||||
<div class="meta">No uninstalled components found — all components are currently installed.</div>
|
||||
{{end}}
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user