Files
patrick 5ecd143535 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>
2026-06-05 18:45:46 +02:00

80 lines
2.6 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}ZFS ZMB Webui{% endblock %}
{% block content %}
<h2>ZFS Pools &amp; 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">&#128269; Scrub</button>
<button class="outline"
hx-post="/api/pools/{{ pool.name }}/resilver"
hx-confirm="Resilver für {{ pool.name }} starten?"
hx-swap="none">&#128260; 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">&#10006; 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>&nbsp;&nbsp;&nbsp;&#8627; {{ 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 %}