134 lines
5.2 KiB
HTML
134 lines
5.2 KiB
HTML
{% extends "base.html" %}
|
||
|
||
{% block title %}Логи{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="flex flex-wrap items-end justify-between gap-4">
|
||
<div>
|
||
<h1 class="text-2xl font-semibold">Логи</h1>
|
||
<p class="mt-1 text-sm text-slate-600">События из ClickHouse · найдено: {{ total }}</p>
|
||
</div>
|
||
</div>
|
||
|
||
<form method="get" action="/logs" class="mt-4 flex flex-wrap items-end gap-3 rounded-lg border border-slate-200 bg-white p-4">
|
||
<div>
|
||
<label for="event_type" class="text-xs text-slate-500">Тип</label>
|
||
<select
|
||
id="event_type"
|
||
name="event_type"
|
||
class="mt-1 block rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-sky-500 focus:outline-none"
|
||
>
|
||
<option value="">Все типы</option>
|
||
{% for type in event_types %}
|
||
<option value="{{ type }}" {% if type == event_type %}selected{% endif %}>{{ type }}</option>
|
||
{% endfor %}
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label for="user" class="text-xs text-slate-500">Пользователь</label>
|
||
<input
|
||
id="user"
|
||
name="user"
|
||
type="text"
|
||
value="{{ user }}"
|
||
placeholder="ID или @username"
|
||
class="mt-1 block w-48 rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-sky-500 focus:outline-none"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label for="date_from" class="text-xs text-slate-500">С</label>
|
||
<input
|
||
id="date_from"
|
||
name="date_from"
|
||
type="date"
|
||
value="{{ date_from }}"
|
||
class="mt-1 block rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-sky-500 focus:outline-none"
|
||
/>
|
||
</div>
|
||
<div>
|
||
<label for="date_to" class="text-xs text-slate-500">По</label>
|
||
<input
|
||
id="date_to"
|
||
name="date_to"
|
||
type="date"
|
||
value="{{ date_to }}"
|
||
class="mt-1 block rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-sky-500 focus:outline-none"
|
||
/>
|
||
</div>
|
||
<button type="submit" class="rounded-lg bg-sky-600 px-4 py-2 text-sm font-medium text-white hover:bg-sky-700">
|
||
Показать
|
||
</button>
|
||
<a href="/logs" class="text-sm text-slate-600 hover:underline">Сбросить</a>
|
||
</form>
|
||
|
||
{% if error %}
|
||
<div class="mt-4 rounded-lg border border-amber-200 bg-amber-50 p-3 text-sm text-amber-800">{{ error }}</div>
|
||
{% endif %}
|
||
|
||
<div class="mt-6 overflow-x-auto rounded-lg border border-slate-200 bg-white">
|
||
<table class="min-w-full divide-y divide-slate-200 text-sm">
|
||
<thead class="bg-slate-50 text-left text-slate-600">
|
||
<tr>
|
||
<th class="px-4 py-3 font-medium">Время</th>
|
||
<th class="px-4 py-3 font-medium">Событие</th>
|
||
<th class="px-4 py-3 font-medium">Пользователь</th>
|
||
<th class="hidden px-4 py-3 font-medium lg:table-cell">Чат</th>
|
||
<th class="hidden px-4 py-3 font-medium xl:table-cell">Версия</th>
|
||
<th class="px-4 py-3 font-medium">Payload</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody class="divide-y divide-slate-100">
|
||
{% for event in events %}
|
||
<tr class="align-top hover:bg-slate-50">
|
||
<td class="whitespace-nowrap px-4 py-3 text-slate-600">{{ event.time_local }}</td>
|
||
<td class="px-4 py-3">
|
||
<span class="rounded bg-slate-100 px-2 py-0.5 font-mono text-xs">{{ event.event_type }}</span>
|
||
{% if event.prod %}<span class="ml-1 rounded bg-indigo-100 px-2 py-0.5 text-xs text-indigo-800">prod</span>{% endif %}
|
||
</td>
|
||
<td class="px-4 py-3">
|
||
{% if event.user_id %}
|
||
{% if event.username %}<div>@{{ event.username }}</div>{% endif %}
|
||
<a href="/users/{{ event.user_id }}" class="font-mono text-xs text-sky-700 hover:underline">{{ event.user_id }}</a>
|
||
{% else %}
|
||
<span class="text-slate-400">—</span>
|
||
{% endif %}
|
||
</td>
|
||
<td class="hidden px-4 py-3 font-mono text-xs text-slate-500 lg:table-cell">{{ event.chat_id or "—" }}</td>
|
||
<td class="hidden px-4 py-3 text-xs text-slate-500 xl:table-cell">{{ event.bot_version }}</td>
|
||
<td class="px-4 py-3">
|
||
{% if event.payload_pretty %}
|
||
<details>
|
||
<summary class="cursor-pointer text-xs text-slate-500">JSON</summary>
|
||
<pre class="mt-1 max-h-64 max-w-xl overflow-auto rounded bg-slate-50 p-2 text-xs">{{ event.payload_pretty }}</pre>
|
||
</details>
|
||
{% else %}
|
||
<span class="text-slate-400">—</span>
|
||
{% endif %}
|
||
</td>
|
||
</tr>
|
||
{% else %}
|
||
<tr>
|
||
<td colspan="6" class="px-4 py-6 text-center text-slate-500">
|
||
{% if error %}Данные не загрузились.{% else %}За выбранный период событий нет.{% endif %}
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
{% if pages > 1 %}
|
||
<div class="mt-4 flex items-center justify-between text-sm text-slate-600">
|
||
<div>Страница {{ page }} из {{ pages }}</div>
|
||
<div class="flex gap-3">
|
||
{% if page > 1 %}
|
||
<a href="/logs?{{ query_base }}&page={{ page - 1 }}" class="hover:underline">← Назад</a>
|
||
{% endif %}
|
||
{% if page < pages %}
|
||
<a href="/logs?{{ query_base }}&page={{ page + 1 }}" class="hover:underline">Вперёд →</a>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
{% endblock %}
|