{% from "macros.html" import icon, bar_color, job_row, empty_state, pglink with context %} {% if state in ['failed', 'completed', 'delayed', 'wait'] and jobs %}
{# Bulk-action bar - shown by JS only when ≥1 row is selected (persists across pages). #}
{% if state == 'failed' %} {% endif %}
{% endif %} {# data-view sits ON the grid itself (bulk-select page identity) - no extra wrapper: idiomorph relocates id-keyed rows across intermediate divs. #}
{% if state in ['failed', 'completed', 'delayed', 'wait'] and jobs %} {# Header cells mirror the row cells one-per-track; the subgrid aligns them. #}
id job data {# right-aligned like the numeric values they head #} when ×
{% endif %} {% for j in jobs %}{{ job_row(name, j, state, page) }} {% else %}
{{ empty_state('inbox', 'No ' ~ state ~ ' jobs' ~ (' - all clear' if state == 'failed' else '')) }}
{% endfor %}
{# Live-refresh the list (table + total count + pagination) on any job event, for every state. Paused while a row is open by jobs-live.js (progressive: if that JS fails to load, the refresh still fires - just without the pause). Morph + stable row ids keep it flicker-free; throttle + drop rate-cap it. #} {# id keyed by view: idiomorph matches by id, so a morph can never recycle this node (and its init-time htmx closures) across different queue/state views #} {% if pages > 1 %}
{{ total|comma }} {{ state }} · page {{ page }} of {{ pages }}
{% endif %}