{% 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). #}
0 selected
{% 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. #}
idjobdata
{# 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 }}