154 lines
7.2 KiB
HTML
154 lines
7.2 KiB
HTML
{% extends "base.html" %}
|
||
|
||
{% block title %}Задачи - TGLoader Admin{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||
<h1><i class="bi bi-list-task me-2"></i>Управление задачами</h1>
|
||
</div>
|
||
|
||
<!-- Фильтры -->
|
||
<div class="card mb-4">
|
||
<div class="card-body">
|
||
<form method="GET" action="/admin/tasks" class="row g-3">
|
||
<div class="col-md-4">
|
||
<label class="form-label">Статус</label>
|
||
<select class="form-select" name="status_filter">
|
||
<option value="">Все</option>
|
||
<option value="pending" {% if status_filter == 'pending' %}selected{% endif %}>Ожидание</option>
|
||
<option value="processing" {% if status_filter == 'processing' %}selected{% endif %}>В процессе</option>
|
||
<option value="completed" {% if status_filter == 'completed' %}selected{% endif %}>Завершено</option>
|
||
<option value="failed" {% if status_filter == 'failed' %}selected{% endif %}>Ошибка</option>
|
||
<option value="cancelled" {% if status_filter == 'cancelled' %}selected{% endif %}>Отменено</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label">User ID</label>
|
||
<input type="number" class="form-control" name="user_id"
|
||
placeholder="Фильтр по User ID"
|
||
value="{{ user_id_filter or '' }}">
|
||
</div>
|
||
<div class="col-md-4">
|
||
<label class="form-label"> </label>
|
||
<button type="submit" class="btn btn-primary w-100">
|
||
<i class="bi bi-funnel me-2"></i>Применить фильтры
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Таблица задач -->
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<h5 class="mb-0">Список задач</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
{% if tasks %}
|
||
<div class="table-responsive">
|
||
<table class="table table-hover">
|
||
<thead>
|
||
<tr>
|
||
<th>ID</th>
|
||
<th>Пользователь</th>
|
||
<th>Тип</th>
|
||
<th>URL</th>
|
||
<th>Статус</th>
|
||
<th>Прогресс</th>
|
||
<th>Создано</th>
|
||
<th>Обновлено</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for task in tasks %}
|
||
<tr>
|
||
<td><code>{{ task.id }}</code></td>
|
||
<td>
|
||
{% if task.user %}
|
||
<strong>{{ task.user.username or task.user.user_id }}</strong>
|
||
<br><small class="text-muted">ID: {{ task.user_id }}</small>
|
||
{% else %}
|
||
{{ task.user_id }}
|
||
{% endif %}
|
||
</td>
|
||
<td><span class="badge bg-info">{{ task.task_type }}</span></td>
|
||
<td>
|
||
{% if task.url %}
|
||
<a href="{{ task.url }}" target="_blank" class="text-decoration-none">
|
||
{{ task.url[:60] + '...' if task.url|length > 60 else task.url }}
|
||
<i class="bi bi-box-arrow-up-right ms-1"></i>
|
||
</a>
|
||
{% else %}
|
||
<span class="text-muted">-</span>
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
{% if task.status == 'completed' %}
|
||
<span class="badge bg-success">Завершено</span>
|
||
{% elif task.status == 'processing' %}
|
||
<span class="badge bg-warning">В процессе</span>
|
||
{% elif task.status == 'pending' %}
|
||
<span class="badge bg-info">Ожидание</span>
|
||
{% elif task.status == 'failed' %}
|
||
<span class="badge bg-danger">Ошибка</span>
|
||
{% elif task.status == 'cancelled' %}
|
||
<span class="badge bg-secondary">Отменено</span>
|
||
{% else %}
|
||
<span class="badge bg-secondary">{{ task.status }}</span>
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
<div class="d-flex align-items-center">
|
||
<div class="progress me-2" style="height: 20px; width: 100px;">
|
||
<div class="progress-bar
|
||
{% if task.status == 'completed' %}bg-success
|
||
{% elif task.status == 'failed' %}bg-danger
|
||
{% elif task.status == 'processing' %}bg-warning
|
||
{% else %}bg-info{% endif %}"
|
||
role="progressbar"
|
||
style="width: {{ task.progress }}%"
|
||
aria-valuenow="{{ task.progress }}"
|
||
aria-valuemin="0"
|
||
aria-valuemax="100">
|
||
{{ task.progress }}%
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</td>
|
||
<td><small>{{ task.created_at.strftime('%Y-%m-%d %H:%M') if task.created_at else '-' }}</small></td>
|
||
<td><small>{{ task.updated_at.strftime('%Y-%m-%d %H:%M') if task.updated_at else '-' }}</small></td>
|
||
</tr>
|
||
{% if task.error_message %}
|
||
<tr>
|
||
<td colspan="8">
|
||
<div class="alert alert-danger mb-0 py-2">
|
||
<small><strong>Ошибка:</strong> {{ task.error_message }}</small>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
{% endif %}
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
{% else %}
|
||
<p class="text-muted text-center">Задачи не найдены</p>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
{% block extra_js %}
|
||
<script>
|
||
// Автообновление каждые 5 секунд для активных задач
|
||
setInterval(() => {
|
||
const hasActiveTasks = Array.from(document.querySelectorAll('.badge')).some(
|
||
badge => badge.textContent.includes('В процессе') || badge.textContent.includes('Ожидание')
|
||
);
|
||
if (hasActiveTasks) {
|
||
location.reload();
|
||
}
|
||
}, 5000);
|
||
</script>
|
||
{% endblock %}
|
||
{% endblock %}
|