Running Reports

live more →
{{ running_count }}
Running
{{ done_count }}
Done
{{ failed_count }}
Failed
{% if runs %} {% for run in runs %} {% set progress = run.progress %} {% set is_multi = progress and progress.total > 1 %} {% set pct = (progress.completed / progress.total * 100) | round(1) if is_multi else 0 %} {% set is_err = run.status != 'running' and run.result == 'error' %} {% set is_cancelled = run.status != 'running' and run.result == 'cancelled' %} {% set is_success = run.status != 'running' and run.result == 'success' %} {% set is_finished_unknown = run.status != 'running' and run.result != 'success' and run.result != 'error' and run.result != 'cancelled' %} {% set report_url = run.report_url %} {# A workflow run renders as ONE first-class row: named by the workflow, a segment sparkline (done / pulsing-now / pending) in place of the bar, and a click that opens the run (/run/{id}) — NOT the last report. The is_wf branch is evaluated FIRST so a successful workflow links to /run/{id}, not report_url. A COMPOUND row links to the SAME canvas (/run/{id}): the fan-in canvas is reopened and its deliverable node opens the combined report (spec §9). So the LINK uses is_canvas (workflow OR compound); the NAME still uses is_wf (a compound row shows recipes[0] = the compound/bundle name, not a workflow_name) — only the link target changes. ALL terminal states (success / cancelled / error / unknown) for a canvas row reopen the canvas (/run/{id}) — including ERROR (fix ④): the canvas now renders the terminal error state + the deliverable's error message, and a persistent "Run log" link in the canvas toolbar keeps the raw log one click away. Only ad-hoc (non-canvas) report errors still route straight to /run/{id}/log. #} {% set is_wf = run.kind == 'workflow' %} {% set is_canvas = run.kind in ('workflow', 'compound') %} {% set wf_total = (progress.total if progress else (run.recipes | length)) or (run.recipes | length) %} {% set wf_completed = (progress.completed if progress else 0) %} {% set wf_tint = 'success' if is_success else ('error' if is_err else ('cancelled' if is_cancelled else 'neutral')) %}
{% if is_wf %}{{ run.workflow_name or 'Workflow' }}{% else %}{{ run.recipes[0] }}{% if run.recipes | length > 1 %} +{{ run.recipes | length - 1 }}{% endif %}{% endif %} · {{ run.scope }} {% if is_err %} ✕ failed {% elif is_cancelled %} — cancelled {% elif is_success %} ✓ done {% elif is_finished_unknown %} {# Defensive: completed run with null/unexpected result — show neutral state #} — finished {% else %} {% if run.elapsed >= 60 %}{{ (run.elapsed // 60) }}m{% else %}{{ run.elapsed }}s{% endif %} {# B2 #21: per-row Stop — wired to POST /api/run/{id}/cancel by the delegated handler in command-center.js (stops row-navigation propagation on canvas rows). The poller settles the row to "cancelled" on its next tick. #} {% endif %}
{% if is_wf %} {# ── Workflow segment sparkline (one .seg per step) ────────────── Running: done (< completed) / now (== completed, pulsing) / pending. Finished: all done, result-tinted (+ a one-time shimmer added by the poller on the in-place transition). The template owns this markup; the poller only toggles .seg classes + the label (no rebuild → no drift). #}
{% for i in range(wf_total) %}{% endfor %}
{% if run.status == 'running' %}step {{ wf_completed }} of {{ wf_total }}{% else %}{{ wf_total }} steps{% endif %}
{% elif run.status == 'running' %} {% if is_multi %} {# Determinate bar: multiple recipes, show progress width #}
recipe {{ progress.completed }}/{{ progress.total }}
{% else %} {# Indeterminate bar: single recipe or no progress yet — use sweep animation #}
running…
{% endif %} {% elif is_err %}
{% elif is_success %}
{% else %} {# cancelled or null result — neutral muted bar #}
{% endif %}
{% endfor %} {% else %}
No reports running Launch one from the report cards below.
{% endif %}