88 lines
3.5 KiB
HTML
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 %} |