"""HTMX partial routes for dynamic updates.""" from fastapi import APIRouter, Request, Depends, Form from fastapi.responses import HTMLResponse from sqlalchemy.orm import Session from ..database import get_db from ..models.user import User, UserRole from ..models.gateway import Gateway from ..models.endpoint import Endpoint from ..models.access import UserGatewayAccess, ConnectionLog from ..models.vpn_server import VPNServer from ..models.vpn_connection_log import VPNConnectionLog from ..services.vpn_server_service import VPNServerService from ..services.vpn_sync_service import VPNSyncService from .deps import get_current_user_web router = APIRouter() @router.get("/dashboard/stats", response_class=HTMLResponse) async def dashboard_stats( request: Request, db: Session = Depends(get_db), current_user: User = Depends(get_current_user_web) ): """Dashboard statistics partial.""" gateways_total = db.query(Gateway).count() gateways_online = db.query(Gateway).filter(Gateway.is_online == True).count() endpoints_total = db.query(Endpoint).count() users_total = db.query(User).filter(User.is_active == True).count() active_connections = db.query(ConnectionLog).filter( ConnectionLog.disconnected_at.is_(None) ).count() # Count VPN clients across all active servers vpn_clients_total = 0 vpn_servers = db.query(VPNServer).filter(VPNServer.is_active == True).all() service = VPNServerService(db) for server in vpn_servers: try: clients = service.get_connected_clients(server) vpn_clients_total += len(clients) except: pass # Server might be offline return f"""
{gw.router_type} | {gw.location or 'Kein Standort'}
{status_badge} Zuletzt: {last_seen}
DetailsKeine Gateways vorhanden
' html = '| {status} {gw.name} | {gw.router_type} |
Keine Endpunkte definiert
| Name | Adresse | Protokoll | Anwendung | |
|---|---|---|---|---|
| {ep.name} | {ep.internal_ip}:{ep.port} |
{protocol_badge} | {ep.application_name or '-'} |
Keine Benutzer haben Zugriff
| Benutzer | Rolle | Gewährt am | Gewährt von | |
|---|---|---|---|---|
| {user.username if user else '-'} | {user.role.value if user else '-'} | {granted_at} | {granted_by.username if granted_by else '-'} |
Keine VPN-Verbindungen aufgezeichnet
| Profil | Server | Echte Adresse | Verbunden | Getrennt | Dauer | Traffic |
|---|---|---|---|---|---|---|
| {profile_name} | {server_name} | {real_addr} |
{connected} | {disconnected} | {duration_str} | {traffic} |
Keine VPN-Clients verbunden
' html = '''| Gateway | Profil | VPN-Server | Echte Adresse | Empfangen | Gesendet | Verbunden seit |
|---|---|---|---|---|---|---|
| {gateway_name} | {profile_name} | {server_name} | {real_addr} |
{rx_str} | {tx_str} | {connected} |
Keine aktiven Verbindungen
' html = 'Keine Verbindungen
' html = 'Keine Verbindungshistorie
' html = '| Benutzer | Gateway | Endpunkt | Verbunden | Getrennt | Dauer |
|---|---|---|---|---|---|
| {user.username if user else '-'} | {gateway.name if gateway else '-'} | {endpoint.name if endpoint else '-'} | {connected} | {disconnected} | {duration} |