Files
wrapped/app/templates/admin_audit.html
T
inecs 8c8dbd2348 Улучшить unwrap, UI и админку; обновить документацию.
- Неверный пароль не сжигает wrap сразу: Argon2-гейт до consume и лимит попыток (по умолчанию 3) в настройках
- Подсветка синтаксиса, автоопределение языка, спиннеры, размеры файлов, пагинация audit
- make push (git, Ctrl-D) и актуальный README
2026-07-18 10:17:05 +03:00

124 lines
5.1 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "admin_base.html" %}
{% block admin_content %}
<section class="audit-page">
<form class="audit-filters" id="audit-filter-form" method="get" action="/admin/audit">
<input type="hidden" name="page" value="1" />
<label class="audit-field">
<span data-i18n="admin.audit.eventType">Event type</span>
<select name="event_type" id="audit-event-type">
<option value="" {% if not event_type %}selected{% endif %} data-i18n="admin.audit.allEvents">All events</option>
{% for t in event_types %}
<option value="{{ t }}" {% if event_type == t %}selected{% endif %}>{{ t }}</option>
{% endfor %}
</select>
</label>
<label class="audit-field audit-field-grow">
<span data-i18n="admin.audit.wrapId">Wrap ID</span>
<input name="wrap_id" value="{{ wrap_id }}" class="mono" placeholder="…" autocomplete="off" />
</label>
<label class="audit-field">
<span data-i18n="admin.audit.perPage">Per page</span>
<select name="per_page" id="audit-per-page">
{% for n in per_page_options %}
<option value="{{ n }}" {% if per_page == n %}selected{% endif %}>{{ n }}</option>
{% endfor %}
</select>
</label>
<button class="btn primary audit-filter-btn" type="submit" data-i18n="admin.audit.filter">Filter</button>
</form>
<div class="audit-meta">
{% if total %}
<span class="audit-count">{{ from_idx }}{{ to_idx }}</span>
<span data-i18n="admin.audit.of">of</span>
<span class="audit-count">{{ total }}</span>
{% else %}
<span class="audit-count">0</span>
{% endif %}
<span data-i18n="admin.audit.events">events</span>
</div>
<div class="audit-table-wrap">
<table class="audit-table">
<thead>
<tr>
<th data-i18n="admin.audit.col.time">Time</th>
<th data-i18n="admin.audit.col.event">Event</th>
<th data-i18n="admin.audit.col.ok">OK</th>
<th data-i18n="admin.audit.col.wrap">Wrap</th>
<th>IP</th>
<th>UA</th>
<th data-i18n="admin.audit.col.details">Details</th>
</tr>
</thead>
<tbody>
{% for e in events %}
<tr class="{% if not e.success %}audit-row-fail{% endif %}">
<td class="mono audit-time" data-ts="{{ e.created_at.isoformat() if e.created_at else '' }}">{{ e.created_at }}</td>
<td><span class="audit-event-pill">{{ e.event_type }}</span></td>
<td>
{% if e.success %}
<span class="audit-status ok"><i class="fa-solid fa-check" aria-hidden="true"></i> <span data-i18n="admin.audit.yes">yes</span></span>
{% else %}
<span class="audit-status fail"><i class="fa-solid fa-xmark" aria-hidden="true"></i> <span data-i18n="admin.audit.no">no</span></span>
{% endif %}
</td>
<td class="mono">{{ e.wrap_id or "—" }}</td>
<td class="mono">{{ e.ip or "—" }}</td>
<td class="ua" title="{{ e.user_agent or '' }}">{{ e.user_agent or "—" }}</td>
<td class="audit-details"><code>{{ e.details }}</code></td>
</tr>
{% else %}
<tr>
<td colspan="7" class="audit-empty" data-i18n="admin.audit.empty">No events</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% if show_pagination %}
<nav class="pagination" aria-label="Pagination">
{% if has_prev %}
<a class="btn pagination-nav" href="/admin/audit?page={{ page - 1 }}&amp;per_page={{ per_page }}&amp;event_type={{ event_type|urlencode }}&amp;wrap_id={{ wrap_id|urlencode }}">
<i class="fa-solid fa-chevron-left" aria-hidden="true"></i>
<span data-i18n="admin.audit.prev">Prev</span>
</a>
{% else %}
<span class="btn pagination-nav" aria-disabled="true">
<i class="fa-solid fa-chevron-left" aria-hidden="true"></i>
<span data-i18n="admin.audit.prev">Prev</span>
</span>
{% endif %}
<div class="pagination-pages">
{% for p in page_window %}
{% if p is none %}
<span class="pagination-ellipsis" aria-hidden="true"></span>
{% elif p == page %}
<span class="pagination-page is-current" aria-current="page">{{ p }}</span>
{% else %}
<a class="pagination-page" href="/admin/audit?page={{ p }}&amp;per_page={{ per_page }}&amp;event_type={{ event_type|urlencode }}&amp;wrap_id={{ wrap_id|urlencode }}">{{ p }}</a>
{% endif %}
{% endfor %}
</div>
{% if has_next %}
<a class="btn pagination-nav" href="/admin/audit?page={{ page + 1 }}&amp;per_page={{ per_page }}&amp;event_type={{ event_type|urlencode }}&amp;wrap_id={{ wrap_id|urlencode }}">
<span data-i18n="admin.audit.next">Next</span>
<i class="fa-solid fa-chevron-right" aria-hidden="true"></i>
</a>
{% else %}
<span class="btn pagination-nav" aria-disabled="true">
<span data-i18n="admin.audit.next">Next</span>
<i class="fa-solid fa-chevron-right" aria-hidden="true"></i>
</span>
{% endif %}
</nav>
{% endif %}
</section>
{% endblock %}
{% block admin_scripts %}
<script src="/static/js/admin-audit.js"></script>
{% endblock %}