108 lines
4.5 KiB
HTML
108 lines
4.5 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}Audit Log (latest 100){% endblock %}
|
|
{% block body_class %}themed-bg{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container">
|
|
<h1 class="page-title">Security · Audit Log (latest 100)</h1>
|
|
|
|
<div class="card" style="padding:20px; width:100%;">
|
|
<div class="table-wrap" style="overflow-x:auto;">
|
|
<table class="table" style="width:100%; border-collapse:separate; border-spacing:0 6px;">
|
|
<thead>
|
|
<tr>
|
|
<th style="padding:10px 14px; text-align:left;">Date / Time</th>
|
|
<th style="padding:10px 14px; text-align:left;">Entry</th>
|
|
<th style="padding:10px 14px; text-align:left;">Action & Changes</th>
|
|
<th style="padding:10px 14px; text-align:left;">User</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for r in rows %}
|
|
<tr style="background:#fff; box-shadow:0 1px 3px rgba(0,0,0,0.08);">
|
|
<td style="padding:10px 14px; vertical-align:top;">{{ r.timestamp|date:"Y-m-d H:i:s" }}</td>
|
|
<td style="padding:10px 14px; vertical-align:top;">
|
|
{% if r.action == "delete" %}
|
|
<span style="color:#dc2626; font-weight:600;">#{{ r.entry_id }}</span>
|
|
{% else %}
|
|
<a href="{% url 'view_entry' r.entry_id %}" class="pill-link" title="Open entry #{{ r.entry_id }}">#{{ r.entry_id }}</a>
|
|
{% endif %}
|
|
</td>
|
|
<td style="padding:10px 14px; vertical-align:top;">
|
|
{% if r.action == "create" %}
|
|
<span class="pill pill-green">Created</span>
|
|
{% elif r.action == "update" %}
|
|
<span class="pill pill-blue">Updated</span>
|
|
{% else %}
|
|
<span class="pill pill-red">Deleted</span>
|
|
{% endif %}
|
|
|
|
{% if r.action == "update" and r.changes %}
|
|
<ul class="diff-list">
|
|
{% for field, pair in r.changes.items %}
|
|
<li>
|
|
<strong>{{ field }}</strong>:
|
|
<span class="chip chip-old">{{ pair.0 }}</span>
|
|
<span style="margin: 0 6px;">→</span>
|
|
<span class="chip chip-new">{{ pair.1 }}</span>
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
{% elif r.action == "create" and r.changes.__created__ %}
|
|
<details>
|
|
<summary class="small">Show created fields</summary>
|
|
<ul class="diff-list">
|
|
{% for k, v in r.changes.__created__.items %}
|
|
<li><strong>{{ k }}</strong>: <code>{{ v }}</code></li>
|
|
{% endfor %}
|
|
</ul>
|
|
</details>
|
|
{% elif r.action == "delete" and r.changes.__deleted__ %}
|
|
<details open>
|
|
<summary class="small">Deleted record snapshot</summary>
|
|
<ul class="diff-list">
|
|
{% for k, v in r.changes.__deleted__.items %}
|
|
<li><strong>{{ k }}</strong>: <code>{{ v }}</code></li>
|
|
{% endfor %}
|
|
</ul>
|
|
</details>
|
|
{% endif %}
|
|
</td>
|
|
<td style="padding:10px 14px; vertical-align:top;">{{ r.username|default:"—" }}</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr><td colspan="4" class="muted" style="padding:12px 14px;">No audit entries yet.</td></tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.pill {
|
|
display:inline-block; padding:4px 12px; border-radius:999px;
|
|
color:#fff; font-size:0.85em; line-height:1;
|
|
}
|
|
.pill-green { background:#22c55e; } /* green-500 */
|
|
.pill-blue { background:#3b82f6; } /* blue-500 */
|
|
.pill-red { background:#ef4444; } /* red-500 */
|
|
|
|
.pill-link {
|
|
display:inline-block; padding:4px 10px; border-radius:999px;
|
|
background:#e5e7eb; color:#111; text-decoration:none; font-size:0.85em;
|
|
}
|
|
.pill-link:hover { text-decoration:underline; }
|
|
|
|
.diff-list { margin:8px 0 0; padding-left:18px; }
|
|
.diff-list li { margin:4px 0; }
|
|
|
|
.chip {
|
|
display:inline-block; max-width:360px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
|
|
padding:2px 8px; border-radius:8px; font-size:0.85em;
|
|
border:1px solid #e5e7eb; background:#f9fafb; color:#111827;
|
|
}
|
|
.chip-old { background:#fff1f2; border-color:#fecdd3; } /* light red */
|
|
.chip-new { background:#ecfeff; border-color:#bae6fd; } /* light blue */
|
|
</style>
|
|
{% endblock %} |