|
|
{% extends "admin/base.html" %} |
|
|
|
|
|
{% block title %}Tâches Planifiées{% endblock %} |
|
|
{% block page_title %}Tâches Planifiées{% endblock %} |
|
|
|
|
|
{% block content %} |
|
|
<div class="space-y-6"> |
|
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4"> |
|
|
<div class="bg-gray-800 rounded-lg p-4 border border-gray-700"> |
|
|
<div class="flex items-center"> |
|
|
<div class="p-3 rounded-full bg-blue-500/20 text-blue-400"> |
|
|
<i class="fas fa-tasks text-xl"></i> |
|
|
</div> |
|
|
<div class="ml-4"> |
|
|
<p class="text-sm text-gray-400">Total Tâches</p> |
|
|
<p class="text-2xl font-bold text-white">{{ stats.total }}</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="bg-gray-800 rounded-lg p-4 border border-gray-700"> |
|
|
<div class="flex items-center"> |
|
|
<div class="p-3 rounded-full bg-green-500/20 text-green-400"> |
|
|
<i class="fas fa-play text-xl"></i> |
|
|
</div> |
|
|
<div class="ml-4"> |
|
|
<p class="text-sm text-gray-400">Actives</p> |
|
|
<p class="text-2xl font-bold text-white">{{ stats.active }}</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="bg-gray-800 rounded-lg p-4 border border-gray-700"> |
|
|
<div class="flex items-center"> |
|
|
<div class="p-3 rounded-full bg-yellow-500/20 text-yellow-400"> |
|
|
<i class="fas fa-clock text-xl"></i> |
|
|
</div> |
|
|
<div class="ml-4"> |
|
|
<p class="text-sm text-gray-400">En Attente</p> |
|
|
<p class="text-2xl font-bold text-white">{{ stats.pending }}</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="bg-gray-800 rounded-lg p-4 border border-gray-700"> |
|
|
<div class="flex items-center"> |
|
|
<div class="p-3 rounded-full bg-red-500/20 text-red-400"> |
|
|
<i class="fas fa-exclamation-triangle text-xl"></i> |
|
|
</div> |
|
|
<div class="ml-4"> |
|
|
<p class="text-sm text-gray-400">Échecs</p> |
|
|
<p class="text-2xl font-bold text-white">{{ stats.failed }}</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="bg-gray-800 rounded-lg border border-gray-700"> |
|
|
<div class="p-6 border-b border-gray-700 flex justify-between items-center"> |
|
|
<h3 class="text-lg font-semibold text-white">Liste des Tâches</h3> |
|
|
<a href="{{ url_for('admin_tasks.view_logs') }}" class="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg text-sm"> |
|
|
<i class="fas fa-history mr-2"></i>Voir les Logs |
|
|
</a> |
|
|
</div> |
|
|
<div class="overflow-x-auto"> |
|
|
<table class="w-full text-left"> |
|
|
<thead class="bg-gray-700/50"> |
|
|
<tr> |
|
|
<th class="px-6 py-3 text-sm font-medium text-gray-300">Nom</th> |
|
|
<th class="px-6 py-3 text-sm font-medium text-gray-300">Planning</th> |
|
|
<th class="px-6 py-3 text-sm font-medium text-gray-300">Statut</th> |
|
|
<th class="px-6 py-3 text-sm font-medium text-gray-300">Dernier Run</th> |
|
|
<th class="px-6 py-3 text-sm font-medium text-gray-300">Prochain Run</th> |
|
|
<th class="px-6 py-3 text-sm font-medium text-gray-300">Actions</th> |
|
|
</tr> |
|
|
</thead> |
|
|
<tbody class="divide-y divide-gray-700"> |
|
|
{% for task in tasks %} |
|
|
<tr class="hover:bg-gray-700/30 {% if task.should_run() %}bg-yellow-500/10{% endif %}"> |
|
|
<td class="px-6 py-4"> |
|
|
<div class="flex items-center"> |
|
|
<div> |
|
|
<p class="text-sm font-medium text-white">{{ task.name }}</p> |
|
|
<p class="text-xs text-gray-400">{{ task.description }}</p> |
|
|
{% if task.should_run() %} |
|
|
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-yellow-500/20 text-yellow-400 mt-1"> |
|
|
À exécuter! |
|
|
</span> |
|
|
{% endif %} |
|
|
</div> |
|
|
</div> |
|
|
</td> |
|
|
<td class="px-6 py-4 text-sm text-gray-300"> |
|
|
{% if task.schedule_type == 'daily' %} |
|
|
Quotidien à {{ task.schedule_time.strftime('%H:%M') }} |
|
|
{% elif task.schedule_type == 'hourly' %} |
|
|
Toutes les heures |
|
|
{% else %} |
|
|
Tous les {{ task.interval_minutes }} min |
|
|
{% endif %} |
|
|
</td> |
|
|
<td class="px-6 py-4"> |
|
|
{% if task.last_status == 'success' %} |
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-500/20 text-green-400"> |
|
|
<i class="fas fa-check mr-1"></i> Succès |
|
|
</span> |
|
|
{% elif task.last_status == 'failed' %} |
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-500/20 text-red-400"> |
|
|
<i class="fas fa-times mr-1"></i> Échec |
|
|
</span> |
|
|
{% elif task.last_status == 'running' %} |
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-500/20 text-blue-400"> |
|
|
<i class="fas fa-spinner fa-spin mr-1"></i> En cours |
|
|
</span> |
|
|
{% else %} |
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-500/20 text-gray-400"> |
|
|
En attente |
|
|
</span> |
|
|
{% endif %} |
|
|
</td> |
|
|
<td class="px-6 py-4 text-sm text-gray-300"> |
|
|
{% if task.last_run_at %} |
|
|
{{ task.last_run_at.strftime('%d/%m/%Y %H:%M') }} |
|
|
<br><span class="text-xs text-gray-500">{{ task.run_count }} runs</span> |
|
|
{% else %} |
|
|
<span class="text-gray-500">Jamais</span> |
|
|
{% endif %} |
|
|
</td> |
|
|
<td class="px-6 py-4 text-sm text-gray-300"> |
|
|
{% if task.next_run_at %} |
|
|
{{ task.next_run_at.strftime('%d/%m/%Y %H:%M') }} |
|
|
{% else %} |
|
|
<span class="text-gray-500">Non calculé</span> |
|
|
{% endif %} |
|
|
</td> |
|
|
<td class="px-6 py-4"> |
|
|
<div class="flex space-x-2"> |
|
|
<form method="POST" action="{{ url_for('admin_tasks.run_task_now', task_id=task.id) }}" class="inline"> |
|
|
<button type="submit" class="px-3 py-1 bg-blue-600 hover:bg-blue-700 text-white rounded text-sm" title="Exécuter maintenant"> |
|
|
<i class="fas fa-play"></i> |
|
|
</button> |
|
|
</form> |
|
|
<form method="POST" action="{{ url_for('admin_tasks.toggle_task', task_id=task.id) }}" class="inline"> |
|
|
<button type="submit" class="px-3 py-1 {% if task.is_active %}bg-gray-600 hover:bg-gray-700{% else %}bg-green-600 hover:bg-green-700{% endif %} text-white rounded text-sm" title="{{ 'Désactiver' if task.is_active else 'Activer' }}"> |
|
|
<i class="fas {% if task.is_active %}fa-pause{% else %}fa-play{% endif %}"></i> |
|
|
</button> |
|
|
</form> |
|
|
</div> |
|
|
</td> |
|
|
</tr> |
|
|
{% if task.last_error %} |
|
|
<tr class="bg-red-500/5"> |
|
|
<td colspan="6" class="px-6 py-2"> |
|
|
<p class="text-xs text-red-400"> |
|
|
<i class="fas fa-exclamation-circle mr-1"></i> |
|
|
<strong>Erreur:</strong> {{ task.last_error[:200] }}{% if task.last_error|length > 200 %}...{% endif %} |
|
|
</p> |
|
|
</td> |
|
|
</tr> |
|
|
{% endif %} |
|
|
{% endfor %} |
|
|
</tbody> |
|
|
</table> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="bg-blue-900/30 border border-blue-700 rounded-lg p-4"> |
|
|
<div class="flex items-start"> |
|
|
<i class="fas fa-info-circle text-blue-400 mt-0.5 mr-3"></i> |
|
|
<div> |
|
|
<h4 class="text-sm font-medium text-blue-300">À propos du Scheduler</h4> |
|
|
<p class="text-sm text-blue-200 mt-1"> |
|
|
Ce système remplace les cron jobs traditionnels. Les tâches sont stockées en base de données |
|
|
et peuvent être exécutées manuellement ou automatiquement. Si le serveur redémarre, |
|
|
les tâches manquées seront automatiquement rattrapées. |
|
|
</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
{% endblock %} |
|
|
|
|
|
{% block scripts %} |
|
|
<script> |
|
|
|
|
|
setInterval(function() { |
|
|
window.location.reload(); |
|
|
}, 30000); |
|
|
</script> |
|
|
{% endblock %} |
|
|
|