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:
+10
-14
@@ -15,11 +15,12 @@ from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect, status
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import JSONResponse, FileResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.templating import Jinja2Templates
|
||||
|
||||
# Add backend to path for imports
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
|
||||
from routers import auth, pools, datasets, snapshots, navigator, identities, shares, system
|
||||
from routers import auth, pools, datasets, snapshots, navigator, identities, shares, system, pages
|
||||
from services.zfs_runner import zfs_runner
|
||||
|
||||
# Configure logging
|
||||
@@ -114,7 +115,11 @@ async def websocket_endpoint(websocket: WebSocket):
|
||||
ws_clients.discard(websocket)
|
||||
|
||||
|
||||
# Include routers (must be before static files mounting)
|
||||
# Static assets (HTMX, PicoCSS — vendored)
|
||||
_static_dir = os.path.join(os.path.dirname(__file__), "static")
|
||||
app.mount("/static", StaticFiles(directory=_static_dir), name="static")
|
||||
|
||||
# Include API routers first
|
||||
app.include_router(auth.router)
|
||||
app.include_router(pools.router)
|
||||
app.include_router(datasets.router)
|
||||
@@ -124,6 +129,9 @@ app.include_router(identities.router)
|
||||
app.include_router(shares.router)
|
||||
app.include_router(system.router)
|
||||
|
||||
# HTML pages router last (catches /, /login, /zfs, /fragments/*)
|
||||
app.include_router(pages.router)
|
||||
|
||||
|
||||
|
||||
# Health check endpoint (no auth required)
|
||||
@@ -156,18 +164,6 @@ async def status_check():
|
||||
}
|
||||
|
||||
|
||||
# Root endpoint - API info only
|
||||
@app.get("/")
|
||||
async def root(request: Request):
|
||||
"""API info"""
|
||||
return {
|
||||
"name": "ZMB Webui API",
|
||||
"version": "1.0.0",
|
||||
"docs": "/docs",
|
||||
"frontend": str(request.base_url)
|
||||
}
|
||||
|
||||
|
||||
# Error handler
|
||||
@app.exception_handler(Exception)
|
||||
async def general_exception_handler(request: Request, exc: Exception):
|
||||
|
||||
Reference in New Issue
Block a user