{% extends "controlpanel/base.html" %} {% load lucide %} {% block panel_title %}Jobs{% endblock panel_title %} {% block breadcrumb %} jobs | {{ jobs|length }} scheduled {% endblock breadcrumb %} {% block panel %}
{% lucide "info" size=16 class="inline -mt-0.5 mr-1" %} These run on Celery Beat's own schedule (see rosterchief/settings.py) — this page is monitoring only, there is no "run now" here. A run that never appears at its scheduled time is the signal something's wrong with worker/beat, not with this page.
{% for job in jobs %}
{{ job.label }}
{{ job.name }}
{% if job.latest %} {% if job.latest.status == "success" %} ok {% elif job.latest.status == "failure" %} error {% else %} running {% endif %} {% else %} never run {% endif %}
{# flex-1 here so the paragraph absorbs whatever space a shorter description leaves, keeping the schedule pill pinned to the bottom of the content block across every card in the row instead of drifting with description length. #}

{{ job.description }}

{% lucide "clock" size=12 %} {{ job.schedule }}
{% if job.latest %}
last run {{ job.latest.started_at|date:"j M Y, H:i" }} {% if job.latest.duration %}· {{ job.latest.duration.total_seconds|floatformat:1 }}s{% endif %}
{% if job.latest.status == "success" and job.latest.detail %}
{{ job.latest.detail }}
{% elif job.latest.status == "failure" and job.latest.error %}
{{ job.latest.error }}
{% endif %} {% endif %}
{% if job.runs|length > 1 %}
Recent runs
{% for run in job.runs|slice:":5" %}
{{ run.started_at|date:"d/m H:i" }} {% if run.status == "success" %} ok {% elif run.status == "failure" %} error {% else %} running {% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endblock panel %}