- Live-Log-Bug behoben: _latest_log_file() sortierte nach Datei-ctime statt
nach Dateiname — auf manchen Dateisystemen (u.a. unter WSL2 auf einem
gemounteten Windows-Laufwerk) unzuverlässig und lieferte nicht immer das
tatsächlich neueste Logfile. Sortiert jetzt wie der Rest des Codes über
den chronologisch sortierbaren Dateinamen (rpi-YYYYMMDDHHMMSS.log).
- Navbar umstrukturiert in aufklappbare Gruppen mit Unterpunkten:
- "Geräte": Clients (bisherige Devices-Seite), Switche, Zugangsdaten
- "Einstellungen": Benutzer, Gruppen, Systemeinstellungen (Prüfintervall),
Im-/Export
- "Logs": Live, Änderungen (vormals Live-Log/Änderungslog)
Sichtbarkeit gilt jetzt auch pro Unterpunkt: eine Gruppe erscheint nur,
wenn mindestens ein Unterpunkt für den Benutzer sichtbar ist, und zeigt
dann auch nur die sichtbaren Unterpunkte.
- Im-/Export als eigene Unterseite mit Export/Import nebeneinander
(.settings-grid).
- Neue Seite "Mein Konto" (/account, erreichbar über ein Zahnrad-Symbol
neben dem eigenen Namen in der Sidebar) ersetzt das bisherige Profil-Modal:
Profil/Passwort/Profilbild als volle Seite, dazu für Admins die
Navbar-Reihenfolge (aus den Systemeinstellungen hierher verschoben).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
75 lines
3.0 KiB
HTML
75 lines
3.0 KiB
HTML
{% extends "base.html" %}
|
|
{% set active_page = "logs" %}
|
|
{% block page_title %}Änderungen{% endblock %}
|
|
{% block page_sub %}<div class="topbar-sub">{{ entries|length }} Einträge (letzte 500)</div>{% endblock %}
|
|
|
|
{% block content %}
|
|
|
|
{% set action_labels = {
|
|
"settings.update": "Einstellung geändert",
|
|
"device.create": "Gerät angelegt",
|
|
"device.edit": "Gerät bearbeitet",
|
|
"device.delete": "Gerät gelöscht",
|
|
"device.activate": "Gerät aktiviert",
|
|
"device.deactivate": "Gerät deaktiviert",
|
|
"switch.create": "Switch angelegt",
|
|
"switch.edit": "Switch bearbeitet",
|
|
"switch.delete": "Switch gelöscht",
|
|
"credential.create": "Zugangsdaten angelegt",
|
|
"credential.edit": "Zugangsdaten bearbeitet",
|
|
"credential.delete": "Zugangsdaten gelöscht",
|
|
"user.create": "Benutzer angelegt",
|
|
"user.edit": "Benutzer bearbeitet",
|
|
"user.delete": "Benutzer gelöscht",
|
|
"user.assign_group": "Gruppe zugewiesen",
|
|
"group.create": "Gruppe angelegt",
|
|
"group.edit": "Gruppe bearbeitet",
|
|
"group.delete": "Gruppe gelöscht",
|
|
"group.assign_admins": "Admin-Zuweisung geändert",
|
|
"profile.update": "Profil aktualisiert",
|
|
"profile.password": "Passwort geändert",
|
|
} %}
|
|
{% set action_icons = {
|
|
"delete": '<path d="M3 6h18M8 6V4a2 2 0 012-2h4a2 2 0 012 2v2m3 0l-1 14a2 2 0 01-2 2H7a2 2 0 01-2-2L4 6"/>',
|
|
"create": '<path d="M12 5v14M5 12h14"/>',
|
|
"edit": '<path d="M12 20h9"/><path d="M16.5 3.5a2.1 2.1 0 013 3L7 19l-4 1 1-4z"/>',
|
|
"activate": '<path d="M20 6L9 17l-5-5"/>',
|
|
"deactivate": '<circle cx="12" cy="12" r="9"/><path d="M15 9l-6 6M9 9l6 6"/>',
|
|
} %}
|
|
|
|
<div class="table-wrap">
|
|
<div style="overflow-x:auto;">
|
|
<table class="data-table">
|
|
<thead><tr><th style="width:1%;"></th><th>Zeitpunkt</th><th>Benutzer</th><th>Aktion</th><th>Ziel</th><th>Details</th></tr></thead>
|
|
<tbody>
|
|
{% for e in entries %}
|
|
{% set kind = e['action'].split('.')[-1] %}
|
|
<tr>
|
|
<td>
|
|
{% if avatars.get(e['username']) %}
|
|
<img class="avatar-sm" src="{{ url_for('static', filename='uploads/avatars/' + avatars[e['username']]) }}" alt="">
|
|
{% else %}
|
|
<span class="avatar-sm avatar-placeholder">{{ e['username'][:1]|upper }}</span>
|
|
{% endif %}
|
|
</td>
|
|
<td class="text-dim mono" style="font-size:12.5px;">{{ e['ts'] }}</td>
|
|
<td class="cell-name">{{ e['username'] }}</td>
|
|
<td>
|
|
<span class="pill action-pill">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">{{ (action_icons.get(kind) or action_icons['edit'])|safe }}</svg>
|
|
{{ action_labels.get(e['action'], e['action']) }}
|
|
</span>
|
|
</td>
|
|
<td>{{ e['target'] or '—' }}</td>
|
|
<td class="text-dim">{{ e['details'] or '—' }}</td>
|
|
</tr>
|
|
{% else %}
|
|
<tr class="empty-row"><td colspan="6">Noch keine Änderungen protokolliert.</td></tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
{% endblock %}
|