banger/internal/webui/templates/dashboard.html
Thales Maciel 2362d0ae39
Serve a local web UI from bangerd
Add a localhost-only web console so VM and image management no longer depends on the CLI for every inspection and lifecycle action.

Wire bangerd up to a configurable web listener, expose dashboard and async image-build state through the daemon, and serve CSRF-protected HTML pages with host-path picking, VM/image detail views, logs, ports, and progress polling for long-running operations.

Keep the browser path aligned with the existing sudo and host-owned artifact model: surface sudo readiness, print the web URL in daemon status, and document the new workflow. Polish the UI with resource usage cards, clearer clickable affordances, cancel paths, confirmation prompts, image-name links, and HTTP port links.

Validation: GOCACHE=/tmp/banger-gocache go test ./...
2026-03-21 16:47:47 -03:00

65 lines
1.8 KiB
HTML

{{define "dashboard_content"}}
<section class="split-grid">
<div>
<div class="section-head">
<h3>Virtual Machines</h3>
<a class="button" href="/vms/new">Create VM</a>
</div>
<table>
<thead>
<tr>
<th>Name</th>
<th>State</th>
<th>IP</th>
<th>Spec</th>
<th>Created</th>
</tr>
</thead>
<tbody>
{{range .VMs}}
<tr>
<td><a class="table-link" href="/vms/{{.ID}}">{{.Name}}</a></td>
<td><span class="state-pill {{stateClass .State}}">{{.State}}</span></td>
<td>{{if .Runtime.GuestIP}}{{.Runtime.GuestIP}}{{else}}-{{end}}</td>
<td>{{.Spec.VCPUCount}} vCPU / {{.Spec.MemoryMiB}} MiB / {{formatBytes .Spec.WorkDiskSizeBytes}}</td>
<td>{{relativeTime .CreatedAt}}</td>
</tr>
{{else}}
<tr><td colspan="5" class="muted">No VMs yet.</td></tr>
{{end}}
</tbody>
</table>
</div>
<div>
<div class="section-head">
<h3>Images</h3>
<div class="stack-inline">
<a class="button secondary" href="/images/register">Register</a>
<a class="button" href="/images/build">Build</a>
</div>
</div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Managed</th>
<th>Rootfs</th>
<th>Created</th>
</tr>
</thead>
<tbody>
{{range .Images}}
<tr>
<td><a class="table-link" href="/images/{{.ID}}">{{.Name}}</a></td>
<td>{{formatBool .Managed}}</td>
<td><code>{{.RootfsPath}}</code></td>
<td>{{relativeTime .CreatedAt}}</td>
</tr>
{{else}}
<tr><td colspan="4" class="muted">No images registered.</td></tr>
{{end}}
</tbody>
</table>
</div>
</section>
{{end}}