{% endif %}
{# ── Stat Cards (incl. budget banner) — live-update ── #}
{# Two refresh sources, no polling: #}
{# • dashboard-refresh (from:body) — fired by sync/batch-scoring/scan #}
{# completion in THIS tab (see _BATCH_HX_TRIGGER in batch_scoring). #}
{# • sse:* — pushed by the /events stream when a background scheduler job #}
{# mutates the underlying data (see job_finder/web/live_events.py). #}
{# Covers every datum on the cards: counts (jobs), today's cost (costs), #}
{# in-review (pipeline), pending-review (detections). #}
{% include "dashboard/_stats_cards.html" %}
Quick Actions
{# Dynamic actions — auto-refresh on dashboard-refresh. 5s delay gives #}
{# the backend time to finalize session state (status='done', counts). #}
{# class="contents" makes the wrapper layout-transparent so its children #}
{# participate in the parent flex row. #}
{% include "dashboard/_quick_actions.html" %}
{# Static action — does not need to refresh on dashboard-refresh. #}
{# ── Parser Health widget — live-update ── #}
{# Re-fetches on dashboard-refresh (this tab's sync/scoring runs) and on #}
{# sse:jobs-changed so a source newly flagged DEGRADED surfaces without a #}
{# full page reload. Inline render on full page load avoids a layout shift. #}
{% include "dashboard/_degraded_sources.html" %}
{# ── Heal Activity panel (autoheal Phase D / D5) ── #}
{# Server-rendered on full page load only: heal events are post-ingestion / #}
{# daily-sweep cadence, so a live refetch hook would be noise. #}
{% include "dashboard/_heal_activity.html" %}
{# The container refetches on sse:detections-changed so detections surfaced #}
{# by the background pipeline-detection job appear live. It deliberately #}
{# does NOT listen to dashboard-refresh: user confirm/dismiss has its own #}
{# card-level swap + "confirmed!" animation (see blueprints/detections.py), #}
{# and a competing innerHTML refetch would blow that animation away. The #}
{# fragment also OOB-refreshes the header badge below. #}
{% include "dashboard/_pipeline_review_header.html" %}
{% include "dashboard/_review_queue.html" %}
{# ── History block (pipeline summary + activity tables) — live-update ── #}
{# Re-fetches on dashboard-refresh (this tab's sync/scoring/scan runs) and #}
{# on the SSE events whose data these tables surface — no polling. Partial #}
{# is shared with the full-page render above and dashboard.history_fragment. #}