bifroest/app/templates/audit.html
2026-10-27 08:34:17 +01:00

47 lines
3.3 KiB
HTML

{% extends "base.html" %}
{% block title %}Audit-Log{% endblock %}
{% block content %}
<div class="stack stack-sm">
<h1>Audit-Log{% if workspace %}: {{ workspace.name }}{% endif %}</h1>
<p class="text-muted">Sicherheits- und fachlich relevante Ereignisse, neueste zuerst. Ohne Geheimnisse und ohne vollständige Inhalte.{% if workspace %} Ereignisse dieses Workspace; was der Plattform-Admin global ändert, steht im globalen Log.{% endif %}</p>
</div>
<section class="card"><div class="card-body stack">
<form method="get" action="{{ base }}" class="cluster aiw-filters">
<label class="text-sm">Aktion
<input name="action" list="audit-actions" value="{{ filters.action }}" placeholder="z. B. approval.">
<datalist id="audit-actions">{% for a in actions %}<option value="{{ a }}">{% endfor %}</datalist>
</label>
<label class="text-sm">Nutzer
<select name="user"><option value="">alle</option>{% for u in all_users %}<option value="{{ u.id }}" {% if filters.user_id == u.id %}selected{% endif %}>{{ u.display_name }}</option>{% endfor %}</select>
</label>
{% if not workspace %}
<label class="text-sm">Workspace
<select name="workspace"><option value="">alle</option>{% for w in all_workspaces %}<option value="{{ w.id }}" {% if filters.workspace_id == w.id %}selected{% endif %}>{{ w.name }}</option>{% endfor %}</select>
</label>
{% endif %}
<label class="text-sm">von <input type="date" name="start" value="{{ filters.start or '' }}"></label>
<label class="text-sm">bis <input type="date" name="end" value="{{ filters.end or '' }}"></label>
<button class="btn btn-secondary btn-sm" type="submit">Filtern</button>
{% if filters.query %}<a class="btn btn-ghost btn-sm" href="{{ base }}">Zurücksetzen</a>{% endif %}
<a class="btn btn-ghost btn-sm" href="{{ base }}.csv{% if filters.query %}?{{ filters.query|urlencode }}{% endif %}">CSV exportieren</a>
</form>
<p class="text-sm text-muted">{{ count|number }} Ereignis{{ 'se' if count != 1 }}{% if filters.query %} mit diesen Filtern{% endif %}.</p>
{% if events %}
<div class="table-wrap"><table>
<thead><tr><th>Zeit</th><th>Aktion</th><th>Nutzer</th>{% if not workspace %}<th>Workspace</th>{% endif %}<th>Details</th></tr></thead>
<tbody>
{% for e in events %}
<tr>
<td class="text-sm aiw-nowrap">{{ e.time.strftime('%d.%m.%Y %H:%M:%S') }}</td>
<td><code>{{ e.action }}</code>{% if e.target_kind %}<p class="text-xs text-muted">{{ e.target_kind }} {{ e.target_id }}</p>{% endif %}</td>
<td class="text-sm">{{ users.get(e.user_id, '') if e.user_id else 'System' }}</td>
{% if not workspace %}<td class="text-sm">{{ workspace_names.get(e.workspace_id, '(gelöscht)') if e.workspace_id else '' }}</td>{% endif %}
<td class="text-xs aiw-break">{% for k, v in e.data.items() %}<span class="aiw-kv"><span class="text-muted">{{ k }}</span> {{ v if v is string or v is number or v is boolean or v is none else v|tojson }}</span>{% endfor %}</td>
</tr>
{% endfor %}
</tbody>
</table></div>
{% if next_before %}<a class="btn btn-ghost btn-sm" href="{{ base }}?{{ (filters.query | combine_before(next_before)) | urlencode }}">Ältere Ereignisse</a>{% endif %}
{% else %}<p class="text-muted">Keine Ereignisse.</p>{% endif %}
</div></section>
{% endblock %}