feat(web): row-count selector on the Executions card

Adds a "Show" selector (10 / 25 / 50 / 100) to the card header and drops the
default row count from 15 to 10. The chosen value rides on the card's own
polling URL (`/executions?limit=N`), so it survives the 5s htmx refresh with no
client-side state; a config default outside those four is rendered as an extra
option instead of disappearing. The query is parsed permissively — a stale or
hand-edited polling URL clamps or falls back to the config default rather than
422-ing a card that would otherwise render.

Ordering is now explicit rather than inherited from whatever Gitea returns:
newest first, a not-yet-started (queued) run above everything, ties broken on
Gitea's run id so matrix runs sharing a timestamp keep a stable order.
This commit is contained in:
2026-07-25 15:36:21 +02:00
parent 30fd3120a6
commit 7d1f4e2784
9 changed files with 280 additions and 22 deletions
+11 -3
View File
@@ -290,9 +290,17 @@ never answer "did the last build pass?".
Runs come from Gitea's Actions API: `/api/v1/admin/actions/runs` (every repo
on the instance, admin token) with `/api/v1/user/actions/runs` as the
non-admin fallback. `[web].executions_limit` (default 15) caps how many.
Results are cached for 10s, so the card's 5s refresh costs Gitea at most one
call per 10s window; the VM columns are re-read on every refresh.
non-admin fallback. Results are cached for 10s, so the card's 5s refresh costs
Gitea at most one call per 10s window; the VM columns are re-read on every
refresh.
Rows are ordered **newest first** (a queued run, which has no start time yet,
sorts above everything; ties break on Gitea's run id). The **Show** selector in
the card's header picks how many to list — 10 / 25 / 50 / 100, default from
`[web].executions_limit` (10). The choice rides on the card's own polling URL
(`/executions?limit=N`), so it survives every 5s refresh with no client-side
state; a value set in the config outside those four is offered as an extra
option rather than dropped.
**Where the API token comes from.** Normally nowhere extra: the dashboard
reuses the access token from your own OIDC login, so what the card shows is