per-step screenshot + html snapshots, matches-only list, full German UI, CSV export
* apply: Recorder.step_snap(page, name) captures both a JPEG screenshot and the page HTML for every major moment; every provider now calls step_snap at each logical step so failure reports contain the exact DOM and rendered state at every stage of the flow * ZIP report: each snapshot becomes snapshots/NN_<label>.jpg + snapshots/NN_<label>.html for AI-assisted debugging * web: Wohnungsliste zeigt nur noch Flats, die die eigenen Filter treffen; Match-Chip entfernt (Liste ist jetzt implizit matchend) * UI komplett auf Deutsch: Protokoll statt Logs, Administrator statt admin, Trockenmodus statt dry-run, Automatik pausiert statt circuit open, Alarm statt Alert, Abmelden statt Logout * Wohnungen-Header: Zeile 1 Info (Alarm + Filter), Zeile 2 Schalter mit echten Radio-Paaren (An/Aus) für Automatisch bewerben und Trockenmodus; hx-confirm auf den kritischen Radios; per-form CSS für sichtbaren Check-State * Protokoll: von/bis-Datumsfilter (Berliner Zeit) + CSV-Download (/logs/export.csv) mit UTC + lokaler Zeit Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
04b591fa9e
commit
7444f90d6a
16 changed files with 360 additions and 202 deletions
|
|
@ -1,9 +1,36 @@
|
|||
{% extends "_layout.html" %}
|
||||
{% block content %}
|
||||
<section class="card p-4">
|
||||
<form method="get" action="/logs" class="flex flex-wrap items-end gap-3">
|
||||
<div>
|
||||
<label class="block text-xs uppercase tracking-wide text-slate-500 mb-1">von</label>
|
||||
<input class="input" type="date" name="from" value="{{ from_str }}">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs uppercase tracking-wide text-slate-500 mb-1">bis</label>
|
||||
<input class="input" type="date" name="to" value="{{ to_str }}">
|
||||
</div>
|
||||
<button class="btn btn-primary text-sm" type="submit">Anwenden</button>
|
||||
<a class="btn btn-ghost text-sm" href="/logs">zurücksetzen</a>
|
||||
<a class="btn btn-ghost text-sm"
|
||||
href="/logs/export.csv?from={{ from_str }}&to={{ to_str }}">
|
||||
CSV herunterladen
|
||||
</a>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<div class="px-4 py-3 border-b border-soft flex items-center justify-between">
|
||||
<h2 class="font-semibold">System-Log</h2>
|
||||
<span class="text-xs text-slate-500">{{ events|length }} Einträge (max 300, letzte 14 Tage)</span>
|
||||
<h2 class="font-semibold">System-Protokoll</h2>
|
||||
<span class="text-xs text-slate-500">
|
||||
{{ events|length }} Einträge
|
||||
{% if from_str or to_str %}
|
||||
· Zeitraum:
|
||||
{{ from_str or "alles davor" }} — {{ to_str or "heute" }}
|
||||
{% else %}
|
||||
· ohne Filter (Anzeige bis 500; Aufbewahrung 14 Tage)
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="divide-y divide-soft">
|
||||
{% for e in events %}
|
||||
|
|
@ -15,12 +42,12 @@
|
|||
<span class="chip chip-info">{{ e.source }}</span>
|
||||
{% endif %}
|
||||
<span class="text-slate-700">{{ e.action }}</span>
|
||||
{% if e.user %}<span class="text-slate-500">user={{ e.user }}</span>{% endif %}
|
||||
{% if e.user %}<span class="text-slate-500">Benutzer: {{ e.user }}</span>{% endif %}
|
||||
{% if e.details %}<span class="text-slate-500">— {{ e.details }}</span>{% endif %}
|
||||
{% if e.ip %}<span class="text-slate-400">[{{ e.ip }}]</span>{% endif %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="px-4 py-8 text-center text-slate-500">Keine Einträge.</div>
|
||||
<div class="px-4 py-8 text-center text-slate-500">Keine Einträge im gewählten Zeitraum.</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue