Topbar auf globalen Prüf-Timer reduziert, Aktionen+Beschreibung über Tabellen, sortierbare Listen
- Topbar zeigt rechts jetzt ausschließlich den "Nächste Prüfung"-Countdown, konsistent auf jeder Seite (auch anonymes Dashboard) statt nur auf dem Dashboard. Neuer Context-Processor inject_check_timer()/get_last_run_at() liefert last_run/interval global, ohne dass jede Route das selbst berechnen muss. - "+ Neu ..."-Buttons (Devices, Switches, Zugangsdaten, Benutzer, Gruppen) aus der Topbar entfernt und stattdessen in einen .section-head direkt über der jeweiligen Tabelle verschoben, zusammen mit einer kurzen Beschreibung der Seite (bisher nur bei Zugangsdaten/Gruppen vorhanden, jetzt auch bei Geräte/Switche/Benutzer). - Live-Log: eigene lokale Timer-Pill entfernt (redundant zum globalen Timer), "Aktualisieren"-Button in denselben section-head verschoben. Dashboard: Suchfeld aus der Topbar in den Seiteninhalt verschoben, lokale Timer-Anzeige entfernt (übernimmt die globale Topbar-Pill), Reload-bei- Intervallende-Logik bleibt als separater, unsichtbarer Scheduler erhalten. - Neue generische Tabellen-Sortierung (app.js: initSortableTables): Klick auf eine Spaltenüberschrift mit data-sort-key sortiert die Zeilen anhand von data-sort-<key>-Attributen. Unterstützt auch Akkordeon-Tabellen mit mehreren <tbody> (Gruppen: Haupt- + Detail-Zeile bleiben als Einheit zusammen, die virtuelle "Admin"-Zeile bleibt über data-sort-pinned immer oben). Angewendet auf Geräte, Switche, Zugangsdaten, Benutzer, Gruppen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -651,6 +651,40 @@ def _format_ts(ts_str: str) -> str:
|
||||
return ts_str
|
||||
|
||||
|
||||
def get_last_run_at():
|
||||
"""Zeitpunkt des letzten Prüf-Durchlaufs (jüngste Zeile im aktuellsten
|
||||
Logfile) — Basis für den globalen 'Nächste Prüfung'-Countdown in der
|
||||
Topbar, unabhängig von einer bestimmten Geräteliste."""
|
||||
latest_log = _latest_log_file()
|
||||
if not latest_log:
|
||||
return None
|
||||
latest_ts_str = None
|
||||
with open(latest_log, "r") as f:
|
||||
for line in f:
|
||||
m = _LOG_LINE_RE.match(line.strip())
|
||||
if m and (latest_ts_str is None or m.group(1) > latest_ts_str):
|
||||
latest_ts_str = m.group(1)
|
||||
if not latest_ts_str:
|
||||
return None
|
||||
try:
|
||||
return datetime.strptime(latest_ts_str, "%Y-%m-%d %H:%M:%S")
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
@app.context_processor
|
||||
def inject_check_timer():
|
||||
"""Stellt den 'Nächste Prüfung'-Countdown global für die Topbar bereit
|
||||
(auf jeder Seite sichtbar, siehe base.html) — unabhängig davon, ob die
|
||||
jeweilige Route selbst etwas mit Geräten/Logs zu tun hat."""
|
||||
interval = int(get_setting("interval", 5))
|
||||
last_run_at = get_last_run_at()
|
||||
return {
|
||||
"global_check_interval": interval,
|
||||
"global_last_run_epoch_ms": int(last_run_at.timestamp() * 1000) if last_run_at else None,
|
||||
}
|
||||
|
||||
|
||||
def get_device_status(devices):
|
||||
"""
|
||||
Ermittelt aus dem aktuellsten Logfile in einem Durchlauf je Gerät:
|
||||
|
||||
Reference in New Issue
Block a user