{% from "macros.html" import icon, bar_color, job_row, jobs_head, empty_state, pglink, state_label with context %} {# every state except active is bulk-actionable (a worker holds active jobs) #} {% set bulk = state != 'active' %} {% if bulk and jobs %}
{# Bulk-action bar - shown by JS only when ≥1 row is selected (persists across pages). #}
{% if state == 'failed' %} {% endif %}
{% endif %} {% if state == 'active' and q.counts['waiting-children'] %} {# Parked flows fold into active, which isn't bulk-selectable, so their bulk cancel lives here: every waiting-children parent plus its whole subtree. #}
{% endif %} {# data-view sits ON the grid itself (bulk-select page identity) - no extra wrapper: idiomorph relocates id-keyed rows across intermediate divs. #}
{% if jobs %}{{ jobs_head(bulk) }}{% endif %} {% for j in jobs %}{{ job_row(name, j, state, page, bulk) }} {% else %}
{%- if state == 'wait' -%}{{ empty_state('inbox', 'No waiting jobs') }} {%- else -%}{{ empty_state('inbox', 'No ' ~ state ~ ' jobs') }} {%- endif -%}
{% 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_label(state) }} · page {{ page }} of {{ pages }}
{% endif %}