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,44 @@
|
||||
{% macro fmt_bytes(b) %}
|
||||
{%- if b == 0 %}0 B
|
||||
{%- elif b < 1048576 %}{{ "%.1f"|format(b/1024) }} KB
|
||||
{%- elif b < 1073741824 %}{{ "%.1f"|format(b/1048576) }} MB
|
||||
{%- elif b < 1099511627776 %}{{ "%.1f"|format(b/1073741824) }} GB
|
||||
{%- else %}{{ "%.1f"|format(b/1099511627776) }} TB
|
||||
{%- endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% if not pools %}
|
||||
<p>Keine ZFS Pools verfügbar.</p>
|
||||
{% else %}
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:1rem">
|
||||
{% for pool in pools %}
|
||||
{% set pct = (pool.allocated / pool.size * 100)|int if pool.size else 0 %}
|
||||
<article style="margin:0;padding:1rem">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center">
|
||||
<strong>{{ pool.name }}</strong>
|
||||
<span class="badge {% if pool.health == 'ONLINE' %}badge-green{% elif pool.health == 'DEGRADED' %}badge-yellow{% else %}badge-red{% endif %}">{{ pool.health }}</span>
|
||||
</div>
|
||||
<div class="progress-bar-wrap" style="margin:0.5rem 0">
|
||||
<div class="progress-bar {% if pct > 85 %}bar-red{% elif pct > 70 %}bar-yellow{% else %}bar-blue{% endif %}" style="width:{{ pct }}%"></div>
|
||||
</div>
|
||||
<small style="color:var(--pico-muted-color)">
|
||||
{{ fmt_bytes(pool.allocated) }} / {{ fmt_bytes(pool.size) }} ({{ pct }}%)
|
||||
</small>
|
||||
{% if pool.status and pool.status != 'ONLINE' %}
|
||||
<p style="margin:0.5rem 0 0;font-size:0.8rem;color:#fca5a5">{{ pool.status }}</p>
|
||||
{% endif %}
|
||||
<div class="actions" style="margin-top:0.75rem">
|
||||
<button class="outline secondary"
|
||||
hx-post="/api/pools/{{ pool.name }}/scrub"
|
||||
hx-confirm="Scrub für {{ pool.name }} starten?"
|
||||
hx-target="closest article"
|
||||
hx-swap="none">Scrub</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</button>
|
||||
</div>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
Reference in New Issue
Block a user