MeshDD-Bot/static/nina.html
ppfeiffer 2feff2c2c7 feat: NINA Wiederholungsintervall, AGS-Tabelle, Badge-Fix (v0.8.1)
- resend_interval: zweiter Intervall fuer erneutes Senden aktiver
  Warnmeldungen ins Mesh (nur bei send_to_mesh=true). Standard 3600s.
  NinaBot._resend_loop() laeuft als eigener asyncio-Task; _active-Dict
  haelt aktive Warnungen vor (Cancel entfernt Eintraege).
- AGS-Code-Verwaltung als Tabelle mit Trash-Button je Zeile statt
  Badges mit X-Button.
- Severity-Badges: explizite text-white/text-dark, kein bg-opacity-85
  mehr - lesbar in beiden Themes.
- colspan-Fix: leere Alerts-Zeile auf 5 Spalten korrigiert.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-19 12:44:29 +01:00

212 lines
12 KiB
HTML
Raw 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.

<!DOCTYPE html>
<html lang="de" data-bs-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MeshDD-Bot NINA</title>
<link href="https://cdn.jsdelivr.net/npm/@tabler/core@1.4.0/dist/css/tabler.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet">
<link rel="stylesheet" href="/static/css/style.css">
</head>
<body class="antialiased">
<!-- Top Navbar -->
<nav class="top-navbar d-flex align-items-center px-3">
<button class="btn btn-link text-body p-0 me-2 d-lg-none" id="sidebarToggle">
<i class="bi bi-list fs-5"></i>
</button>
<span class="fw-bold me-auto">
<i class="bi bi-broadcast-pin text-info me-1"></i>MeshDD-Bot
<small class="text-body-secondary fw-normal" id="versionLabel"></small>
</span>
<div class="d-flex align-items-center gap-2">
<span id="userMenu" class="d-none">
<small class="text-body-secondary me-1"><i class="bi bi-person-fill me-1"></i><span id="userName"></span></small>
<a href="/auth/logout" class="btn btn-sm btn-outline-secondary py-0 px-1" title="Abmelden">
<i class="bi bi-box-arrow-right" style="font-size:.75rem"></i>
</a>
</span>
<a href="/login" id="loginBtn" class="btn btn-sm btn-outline-info py-0 px-1 d-none">
<i class="bi bi-person" style="font-size:.75rem"></i> Login
</a>
<button class="btn btn-sm btn-outline-secondary py-0 px-1" id="themeToggle" title="Theme wechseln">
<i class="bi bi-sun-fill" id="themeIcon" style="font-size:.75rem"></i>
</button>
</div>
</nav>
<aside class="sidebar" id="sidebar"></aside>
<div class="sidebar-backdrop" id="sidebarBackdrop"></div>
<!-- Content -->
<main class="content-wrapper">
<div class="d-flex justify-content-between align-items-center mb-2">
<h6 class="mb-0"><i class="bi bi-shield-exclamation me-1 text-warning"></i>NINA Warnmeldungen</h6>
<div class="d-flex gap-2 align-items-center">
<span class="badge bg-secondary" id="statusBadge">Lade...</span>
</div>
</div>
<div class="row g-3">
<!-- Settings Card -->
<div class="col-12 col-xl-5">
<div class="card card-outline card-warning h-100">
<div class="card-header">
<h6 class="card-title mb-0"><i class="bi bi-gear me-1"></i>Einstellungen</h6>
</div>
<div class="card-body">
<form id="ninaForm">
<!-- Enable + send toggles -->
<div class="mb-3">
<div class="form-check form-switch mb-2">
<input class="form-check-input" type="checkbox" id="ninaEnabled" role="switch">
<label class="form-check-label fw-semibold" for="ninaEnabled">Aktiviert</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="ninaSendToMesh" role="switch">
<label class="form-check-label" for="ninaSendToMesh">
Ins Mesh senden
<small class="text-body-secondary ms-1">(aus = nur Weboberfläche)</small>
</label>
</div>
</div>
<div class="row g-3 mb-3">
<div class="col-5">
<label for="pollInterval" class="form-label">Abfrage&shy;intervall (Sek.)</label>
<input type="number" class="form-control form-control-sm" id="pollInterval"
min="60" max="3600" step="60" value="300">
<div class="form-text">Neue Warnmeldungen</div>
</div>
<div class="col-5">
<label for="resendInterval" class="form-label">Wieder&shy;holungsintervall (Sek.)</label>
<input type="number" class="form-control form-control-sm" id="resendInterval"
min="60" step="60" value="3600">
<div class="form-text">Aktive Warnungen</div>
</div>
<div class="col-2">
<label for="ninaChannel" class="form-label">Kanal</label>
<input type="number" class="form-control form-control-sm" id="ninaChannel"
min="0" max="7" value="0">
</div>
</div>
<div class="mb-3">
<label for="minSeverity" class="form-label">Mindest-Schweregrad</label>
<select class="form-select form-select-sm" id="minSeverity">
<option value="Minor">Gering (Minor)</option>
<option value="Moderate">Mäßig (Moderate)</option>
<option value="Severe" selected>Schwerwiegend (Severe)</option>
<option value="Extreme">Extrem (Extreme)</option>
</select>
</div>
<!-- AGS Codes -->
<div class="mb-3">
<label class="form-label">AGS-Codes (Amtliche Gemeindeschlüssel)</label>
<div class="table-responsive mb-2" style="max-height:160px;overflow-y:auto">
<table class="table table-sm table-hover table-striped mb-0 align-middle">
<thead class="table-dark">
<tr>
<th>AGS-Code</th>
<th style="width:42px"></th>
</tr>
</thead>
<tbody id="agsList"></tbody>
</table>
</div>
<div class="input-group input-group-sm">
<input type="text" class="form-control" id="agsInput"
placeholder="z.B. 091620000000 (München)" maxlength="12">
<button class="btn btn-outline-secondary" type="button" id="btnAddAgs">
<i class="bi bi-plus-lg"></i> Hinzufügen
</button>
</div>
<div class="form-text">
8- oder 12-stelliger AGS-Code des Landkreises/der kreisfreien Stadt.
<a href="https://www.destatis.de/DE/Themen/Laender-Regionen/Regionales/Gemeindeverzeichnis/_inhalt.html"
target="_blank" rel="noopener" class="text-info">AGS-Verzeichnis</a>
</div>
</div>
<!-- Sources -->
<div class="mb-3">
<label class="form-label">Quellen</label>
<div class="row g-2">
<div class="col-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="srcKatwarn" checked>
<label class="form-check-label" for="srcKatwarn">Katwarn</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="srcBiwapp" checked>
<label class="form-check-label" for="srcBiwapp">BIWAPP</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="srcMowas" checked>
<label class="form-check-label" for="srcMowas">MoWaS</label>
</div>
</div>
<div class="col-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="srcDwd" checked>
<label class="form-check-label" for="srcDwd">DWD (Wetter)</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="srcLhp" checked>
<label class="form-check-label" for="srcLhp">LHP (Hochwasser)</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="srcPolice">
<label class="form-check-label" for="srcPolice">Polizei</label>
</div>
</div>
</div>
</div>
<div class="d-flex gap-2">
<button type="button" class="btn btn-warning btn-sm" id="btnSaveNina">
<i class="bi bi-floppy me-1"></i>Speichern
</button>
<span id="saveStatus" class="d-none align-self-center small"></span>
</div>
</form>
</div>
</div>
</div>
<!-- Alerts Card -->
<div class="col-12 col-xl-7">
<div class="card card-outline card-danger h-100">
<div class="card-header d-flex justify-content-between align-items-center">
<h6 class="card-title mb-0"><i class="bi bi-bell-fill me-1 text-danger"></i>Letzte Warnmeldungen</h6>
<small class="text-body-secondary">Live via WebSocket</small>
</div>
<div class="card-body p-0 table-responsive">
<table class="table table-hover table-sm table-striped mb-0 align-middle">
<thead class="table-dark">
<tr>
<th style="width:90px">Schweregrad</th>
<th>Meldung</th>
<th style="width:110px">Typ</th>
<th style="width:60px" class="text-center">Mesh</th>
<th style="width:130px">Zeitstempel</th>
</tr>
</thead>
<tbody id="alertsTable">
<tr><td colspan="5" class="text-center text-body-secondary py-3">Keine Meldungen NINA aktivieren und AGS-Codes konfigurieren.</td></tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</main>
<footer id="pageFooter" class="page-footer"></footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="/static/js/app.js"></script>
<script src="/static/js/nina.js"></script>
</body>
</html>