Files
2026-05-07 11:09:06 -04:00

88 lines
3.5 KiB
HTML

{% extends "admin/layouts/base.html" %}
{% block title %}Audit Log{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-4">
<h4 class="fw-bold mb-0"><i class="bi bi-journal-text me-2"></i>Audit Log</h4>
<a href="{{ url_for('audit_log.export_csv', **filters) }}" class="btn btn-outline-secondary btn-sm">
<i class="bi bi-download me-1"></i>Export CSV
</a>
</div>
<div class="card shadow-sm mb-3">
<div class="card-body py-2">
<form method="GET" class="row g-2 align-items-end">
<div class="col-md-2">
<label class="form-label small mb-1">Actor</label>
<select class="form-select form-select-sm" name="actor_id">
<option value="">All</option>
{% for u in system_users %}
<option value="{{ u.id }}" {{ 'selected' if filters.actor_id == u.id }}>{{ u.name }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-2">
<label class="form-label small mb-1">Action prefix</label>
<input type="text" class="form-control form-control-sm font-monospace" name="action"
value="{{ filters.action }}" placeholder="e.g. tenant.">
</div>
<div class="col-md-2">
<label class="form-label small mb-1">Target type</label>
<input type="text" class="form-control form-control-sm font-monospace" name="target_type"
value="{{ filters.target_type }}" placeholder="tenant, plan…">
</div>
<div class="col-md-2">
<label class="form-label small mb-1">From</label>
<input type="date" class="form-control form-control-sm" name="date_from" value="{{ filters.date_from }}">
</div>
<div class="col-md-2">
<label class="form-label small mb-1">To</label>
<input type="date" class="form-control form-control-sm" name="date_to" value="{{ filters.date_to }}">
</div>
<div class="col-md-2">
<button type="submit" class="btn btn-dark btn-sm w-100">Filter</button>
</div>
</form>
</div>
</div>
<div class="card shadow-sm">
<div class="table-responsive">
<table class="table table-sm table-hover mb-0 font-monospace" style="font-size:0.82rem;">
<thead class="table-dark">
<tr><th>Time</th><th>Actor</th><th>Action</th><th>Target</th><th>IP</th></tr>
</thead>
<tbody>
{% for e in entries %}
<tr>
<td class="text-nowrap">{{ e.created_at.strftime('%Y-%m-%d %H:%M:%S') }}</td>
<td>{{ e.actor_type }}:{{ e.actor_id }}</td>
<td>{{ e.action }}</td>
<td>{{ (e.target_type ~ ':' ~ e.target_id) if e.target_type else '—' }}</td>
<td class="text-muted">{{ e.ip_address or '—' }}</td>
</tr>
{% else %}
<tr><td colspan="5" class="text-center text-muted py-4">No entries match your filter.</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% if pagination.pages > 1 %}
<nav class="mt-3">
<ul class="pagination pagination-sm">
{% if pagination.has_prev %}
<li class="page-item">
<a class="page-link" href="{{ url_for('audit_log.index', page=pagination.prev_num, **filters) }}">Previous</a>
</li>
{% endif %}
<li class="page-item disabled"><span class="page-link">Page {{ pagination.page }} of {{ pagination.pages }}</span></li>
{% if pagination.has_next %}
<li class="page-item">
<a class="page-link" href="{{ url_for('audit_log.index', page=pagination.next_num, **filters) }}">Next</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% endblock %}