Feature: HTMX + Jinja2 Frontend ersetzt Next.js komplett
- Kein Node.js, kein npm, kein Build-Schritt mehr - HTMX 2.0.4 + PicoCSS 2 vendored in backend/static/ - Jinja2 Templates für alle 9 Seiten (Dashboard, ZFS, Snapshots, Shares, Identities, Logs, Services, Navigator, Login) - HTMX Fragments für Live-Updates (30s Polling Dashboard) - JWT als httpOnly Cookie statt localStorage - Disk Usage zeigt TB/PB korrekt (Jinja2 serverseitig formatiert) - Update-safe: nur Python-Deps, keine npm-Abhängigkeiten Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}ZFS – ZMB Webui{% endblock %}
|
||||
{% block content %}
|
||||
<h2>ZFS Pools & Datasets</h2>
|
||||
|
||||
{% if not pools %}
|
||||
<p>Keine ZFS Pools verfügbar.</p>
|
||||
{% else %}
|
||||
|
||||
{% for pool in pools %}
|
||||
<details open>
|
||||
<summary><strong>{{ pool.name }}</strong>
|
||||
<span class="badge {% if pool.health == 'ONLINE' %}badge-green{% elif pool.health == 'DEGRADED' %}badge-yellow{% else %}badge-red{% endif %}" style="margin-left:0.5rem">{{ pool.health }}</span>
|
||||
</summary>
|
||||
|
||||
<div class="actions" style="margin:0.75rem 0">
|
||||
<button class="outline"
|
||||
hx-post="/api/pools/{{ pool.name }}/scrub"
|
||||
hx-confirm="Scrub für {{ pool.name }} starten?"
|
||||
hx-swap="none">🔍 Scrub</button>
|
||||
<button class="outline"
|
||||
hx-post="/api/pools/{{ pool.name }}/resilver"
|
||||
hx-confirm="Resilver für {{ pool.name }} starten?"
|
||||
hx-swap="none">🔄 Resilver</button>
|
||||
<button class="outline secondary"
|
||||
hx-post="/api/pools/{{ pool.name }}/clear"
|
||||
hx-confirm="Fehler für {{ pool.name }} löschen?"
|
||||
hx-swap="none">✖ Clear Errors</button>
|
||||
</div>
|
||||
|
||||
<!-- VDev Tree -->
|
||||
{% if pool.vdevs %}
|
||||
<h4>VDev Struktur</h4>
|
||||
<table>
|
||||
<thead><tr><th>Name</th><th>Typ</th><th>Status</th></tr></thead>
|
||||
<tbody>
|
||||
{% for vdev in pool.vdevs %}
|
||||
<tr>
|
||||
<td>{{ vdev.name }}</td>
|
||||
<td>{{ vdev.type }}</td>
|
||||
<td><span class="badge {% if vdev.state == 'ONLINE' %}badge-green{% elif vdev.state == 'DEGRADED' %}badge-yellow{% else %}badge-red{% endif %}">{{ vdev.state }}</span></td>
|
||||
</tr>
|
||||
{% if vdev.disks %}
|
||||
{% for disk in vdev.disks %}
|
||||
<tr style="font-size:0.85rem">
|
||||
<td> ↳ {{ disk.name }}</td>
|
||||
<td><span style="color:var(--pico-muted-color)">disk</span></td>
|
||||
<td><span class="badge {% if disk.state == 'ONLINE' %}badge-green{% elif disk.state == 'DEGRADED' %}badge-yellow{% else %}badge-red{% endif %}">{{ disk.state }}</span></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
|
||||
<!-- Datasets -->
|
||||
{% if pool.datasets %}
|
||||
<h4>Datasets</h4>
|
||||
<table>
|
||||
<thead><tr><th>Name</th><th>Typ</th><th>Belegt</th><th>Verfügbar</th><th>Kompression</th></tr></thead>
|
||||
<tbody>
|
||||
{% for ds in pool.datasets %}
|
||||
<tr>
|
||||
<td>{{ ds.name }}</td>
|
||||
<td><span class="badge">{{ ds.type }}</span></td>
|
||||
<td>{{ ds.used }}</td>
|
||||
<td>{{ ds.available }}</td>
|
||||
<td>{{ ds.compression }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
</details>
|
||||
<hr>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user