91 lines
3.3 KiB
HTML
91 lines
3.3 KiB
HTML
{% extends "base.html" %}
|
||
{% block title %}Синхронизация — Support Admin{% endblock %}
|
||
{% block content %}
|
||
<h1>🔄 Синхронизация с Intradesk</h1>
|
||
|
||
{# ── Кнопки запуска ── #}
|
||
<div class="card">
|
||
<h2>Запустить синхронизацию</h2>
|
||
<p style="color:#666;font-size:.85rem;margin-bottom:16px">
|
||
Данные загружаются из Intradesk API и сохраняются локально.
|
||
Синхронизация выполняется синхронно — страница обновится по завершении.
|
||
</p>
|
||
<div style="display:flex;gap:12px;flex-wrap:wrap">
|
||
{% for key, label in sync_labels.items() %}
|
||
<form method="post" action="/admin/sync/run">
|
||
<input type="hidden" name="sync_type" value="{{ key }}">
|
||
<button type="submit"
|
||
class="btn {% if key == 'all' %}btn-primary{% else %}btn-secondary{% endif %}"
|
||
style="{% if key == 'all' %}font-weight:700{% endif %}">
|
||
{% if key == 'all' %}🚀{% elif key == 'clients' %}🏢{% elif key == 'users' %}👤{% else %}📋{% endif %}
|
||
{{ label }}
|
||
</button>
|
||
</form>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
|
||
{# ── Последняя успешная синхронизация ── #}
|
||
<div class="card">
|
||
<h2>Последняя успешная синхронизация</h2>
|
||
<table>
|
||
<thead>
|
||
<tr><th>Тип</th><th>Дата</th><th>Записей</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for key, label in sync_labels.items() if key != 'all' %}
|
||
<tr>
|
||
<td>{{ label }}</td>
|
||
{% set rec = last[key] %}
|
||
{% if rec %}
|
||
<td>{{ rec.finished_at or rec.started_at }}</td>
|
||
<td>{{ rec.records_synced }}</td>
|
||
{% else %}
|
||
<td colspan="2" style="color:#999">Не выполнялась</td>
|
||
{% endif %}
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
{# ── История запусков ── #}
|
||
<div class="card">
|
||
<h2>История запусков (последние 20)</h2>
|
||
{% if logs %}
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>#</th><th>Тип</th><th>Начало</th><th>Конец</th>
|
||
<th>Статус</th><th>Записей</th><th>Ошибка</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for log in logs %}
|
||
<tr>
|
||
<td>{{ log.id }}</td>
|
||
<td>{{ sync_labels.get(log.sync_type, log.sync_type) }}</td>
|
||
<td style="white-space:nowrap;font-size:.8rem">{{ log.started_at }}</td>
|
||
<td style="white-space:nowrap;font-size:.8rem">{{ log.finished_at or '—' }}</td>
|
||
<td>
|
||
{% if log.status == 'success' %}
|
||
<span class="badge badge-closed">✓ Успешно</span>
|
||
{% elif log.status == 'error' %}
|
||
<span class="badge badge-open">✗ Ошибка</span>
|
||
{% else %}
|
||
<span class="badge badge-pending">⟳ Выполняется</span>
|
||
{% endif %}
|
||
</td>
|
||
<td>{{ log.records_synced }}</td>
|
||
<td style="color:#d93025;font-size:.8rem;max-width:300px;word-break:break-all">
|
||
{{ log.error_message or '' }}
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
{% else %}
|
||
<p style="color:#999">Синхронизаций ещё не было.</p>
|
||
{% endif %}
|
||
</div>
|
||
{% endblock %}
|