You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
5.6 KiB
HTML
143 lines
5.6 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Audit Log</title>
|
|
<style>
|
|
:root { color-scheme: dark; }
|
|
body { margin:0; font-family:system-ui, Arial; background:#0e0f12; color:#e8e8ea; }
|
|
header { padding:16px 20px; border-bottom:1px solid #23242a; display:flex; align-items:center; gap:12px; }
|
|
h1 { margin:0; font-size:20px; }
|
|
.filters { display:flex; gap:10px; flex-wrap:wrap; margin-left:auto; }
|
|
.filters input, .filters select {
|
|
background:#14151a; color:#e8e8ea; border:1px solid #2a2c33; border-radius:8px; padding:8px 10px; font-size:14px;
|
|
}
|
|
.filters button {
|
|
background:#2b6efe; color:white; border:none; border-radius:8px; padding:8px 12px; cursor:pointer;
|
|
}
|
|
.filters a { color:#9aa0a6; text-decoration:none; padding-left:6px; }
|
|
|
|
.wrap { padding:16px 20px; }
|
|
table { width:100%; border-collapse:separate; border-spacing:0 10px; }
|
|
thead th { font-weight:600; font-size:12px; color:#a9acb3; text-align:left; padding:0 12px 6px; }
|
|
tbody tr { background:#14151a; border:1px solid #23242a; }
|
|
tbody td { padding:12px; vertical-align:top; }
|
|
.badge { display:inline-block; padding:2px 8px; border-radius:999px; font-size:12px; font-weight:600; }
|
|
.ad { background:#153e25; color:#67d48a; border:1px solid #1f6b3b; }
|
|
.ed { background:#332a16; color:#f0c56a; border:1px solid #6d5a24; }
|
|
.del{ background:#3a1e22; color:#f08a94; border:1px solid #6d2b33; }
|
|
|
|
.meta { color:#a9acb3; font-size:12px; }
|
|
.json { background:#0c0d10; border:1px solid #23242a; border-radius:8px; padding:10px; font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size:12px; white-space:pre-wrap; max-height:260px; overflow:auto; }
|
|
details { margin-top:8px; }
|
|
details > summary { cursor:pointer; color:#bfc3cb; }
|
|
.pill { display:inline-block; background:#1b1d23; border:1px solid #2a2c33; border-radius:999px; padding:2px 8px; font-size:12px; margin-right:6px; color:#cfd2d8; }
|
|
.rowhead { display:flex; align-items:center; gap:10px; }
|
|
.pagination { display:flex; gap:8px; align-items:center; margin-top:10px; }
|
|
.pagination a, .pagination span {
|
|
background:#14151a; border:1px solid #23242a; color:#e8e8ea; padding:6px 10px; border-radius:8px; text-decoration:none; font-size:14px;
|
|
}
|
|
.pagination .current { background:#1b1d23; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<header>
|
|
<h1>Audit Log</h1>
|
|
<form class="filters" method="get">
|
|
<input type="number" name="entry_id" placeholder="Entry ID" value="{{ f_entry_id or '' }}">
|
|
<select name="action">
|
|
<option value="">Any action</option>
|
|
{% for a in actions %}
|
|
<option value="{{a}}" {% if f_action==a %}selected{% endif %}>{{a}}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<input type="text" name="actor" placeholder="Actor" value="{{ f_actor or '' }}">
|
|
<select name="device">
|
|
<option value="">Any device</option>
|
|
{% for d in devices %}
|
|
<option value="{{d}}" {% if f_device==d %}selected{% endif %}>{{d}}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<input type="text" name="q" placeholder="Search old/new/UA" value="{{ f_q or '' }}">
|
|
<input type="number" name="per_page" min="10" max="200" value="{{ per_page }}">
|
|
<button type="submit">Filter</button>
|
|
<a href="{{ url_for('audit_html') }}">Clear</a>
|
|
</form>
|
|
</header>
|
|
|
|
<div class="wrap">
|
|
<div class="meta">{{ total }} events • page {{ page }} / {{ pages }}</div>
|
|
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th style="width:180px">Time (UTC)</th>
|
|
<th style="width:100px">Action</th>
|
|
<th style="width:90px">Entry</th>
|
|
<th>Who / Where</th>
|
|
<th>Old → New</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for r in rows %}
|
|
<tr>
|
|
<td>{{ r.ts }}</td>
|
|
<td>
|
|
{% if r.action=='add' %}
|
|
<span class="badge ad">add</span>
|
|
{% elif r.action=='edit' %}
|
|
<span class="badge ed">edit</span>
|
|
{% else %}
|
|
<span class="badge del">delete</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if r.entry_id %}
|
|
<span class="pill">#{{ r.entry_id }}</span>
|
|
<a class="pill" href="{{ url_for('audit_html', entry_id=r.entry_id) }}">history</a>
|
|
{% else %}
|
|
<span class="pill">—</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
<div class="rowhead">
|
|
<span class="pill">{{ r.actor or 'anon' }}</span>
|
|
<span class="pill">{{ r.device or 'Unknown' }}</span>
|
|
<span class="pill">{{ r.ip or '' }}</span>
|
|
</div>
|
|
<div class="meta" title="{{ r.user_agent }}">{{ r.user_agent[:80] }}{% if r.user_agent and r.user_agent|length>80 %}…{% endif %}</div>
|
|
</td>
|
|
<td>
|
|
<details>
|
|
<summary>Old</summary>
|
|
<pre class="json">{{ r.old_pretty }}</pre>
|
|
</details>
|
|
<details>
|
|
<summary>New</summary>
|
|
<pre class="json">{{ r.new_pretty }}</pre>
|
|
</details>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
|
|
<div class="pagination">
|
|
{% if page > 1 %}
|
|
<a href="{{ url_for('audit_html', entry_id=f_entry_id, action=f_action, actor=f_actor, device=f_device, q=f_q, per_page=per_page, page=page-1) }}">← Prev</a>
|
|
{% else %}
|
|
<span>← Prev</span>
|
|
{% endif %}
|
|
<span class="current">Page {{ page }}</span>
|
|
{% if page < pages %}
|
|
<a href="{{ url_for('audit_html', entry_id=f_entry_id, action=f_action, actor=f_actor, device=f_device, q=f_q, per_page=per_page, page=page+1) }}">Next →</a>
|
|
{% else %}
|
|
<span>Next →</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
|
|
</body>
|
|
</html>
|