diff --git a/docs/WEB-UI.md b/docs/WEB-UI.md index 30ad2fe..dc324fc 100644 --- a/docs/WEB-UI.md +++ b/docs/WEB-UI.md @@ -362,10 +362,14 @@ card's own `.table-wrap` rather than the page, same as the other wide tables **Started is click-to-toggle.** It renders relative ("2h ago") by default; clicking swaps to the absolute local timestamp, and clicking again swaps back. Both strings are pre-rendered server-side into the button's -`data-relative`/`data-absolute` attributes, so the swap (`app.js`, delegated -on `document.body`) is instant and needs no request — and keeps working -after the card's own 5s poll replaces the row, since the listener isn't on -the button itself. +`data-relative`/`data-absolute` attributes, so the swap (`app.js`) is +instant and needs no request. The card's own 5s poll re-renders the whole +table from the server, always starting back at relative — so which format +was showing is remembered client-side, keyed by the button's stable `id` +(`started-{run_id}-{attempt}`, or `started-vm-{vmx}` for an unmatched VM +row), and re-applied to the fresh button after every poll rather than +frozen onto the old node (which would also freeze its relative-time text, +badge, duration — everything else in that row). 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 diff --git a/src/ci_orchestrator/web/static/app.js b/src/ci_orchestrator/web/static/app.js index 92bc825..7212718 100644 --- a/src/ci_orchestrator/web/static/app.js +++ b/src/ci_orchestrator/web/static/app.js @@ -197,27 +197,56 @@ }).observe(stack, { childList: true }); } - document.body.addEventListener("htmx:afterSwap", function (evt) { - var target = evt.detail && evt.detail.target; - if (target && target.id === "action-slot") { - processSlot(target); - } - }); - // Executions "Started" cell: click swaps between the relative and // absolute time already rendered into the button's own data attributes -- // no request. Delegated on body (not the button itself) so it keeps // working after the Executions card's own 5s htmx poll replaces the row. + // + // The poll re-renders the whole card from the server every 5s, always + // starting back at "relative" -- so the choice is remembered here, keyed + // by the button's own id (stable across polls: run id/attempt or vmx), + // and re-applied to the fresh button restoreTimeToggles() finds after each + // swap, rather than freezing the node itself (which would also freeze its + // relative-time text, badge, duration -- everything else in the row). + var timeToggleState = {}; + + function applyTimeToggle(btn, showing) { + var shown = showing === "relative" ? "absolute" : "relative"; + btn.textContent = btn.dataset[showing]; + btn.title = btn.dataset[shown]; + btn.dataset.showing = showing; + } + + function restoreTimeToggles(root) { + var buttons = root.querySelectorAll ? root.querySelectorAll(".time-toggle[id]") : []; + Array.prototype.forEach.call(buttons, function (btn) { + var saved = timeToggleState[btn.id]; + if (saved && saved !== btn.dataset.showing) { + applyTimeToggle(btn, saved); + } + }); + } + document.body.addEventListener("click", function (evt) { var btn = evt.target.closest(".time-toggle"); if (!btn) { return; } var next = btn.dataset.showing === "relative" ? "absolute" : "relative"; - var shown = next === "relative" ? "absolute" : "relative"; - btn.textContent = btn.dataset[next]; - btn.title = btn.dataset[shown]; - btn.dataset.showing = next; + applyTimeToggle(btn, next); + if (btn.id) { + timeToggleState[btn.id] = next; + } + }); + + document.body.addEventListener("htmx:afterSwap", function (evt) { + var target = evt.detail && evt.detail.target; + if (target && target.id === "action-slot") { + processSlot(target); + } + if (target) { + restoreTimeToggles(target); + } }); document.addEventListener("DOMContentLoaded", function () { diff --git a/src/ci_orchestrator/web/templates/partials/executions.html b/src/ci_orchestrator/web/templates/partials/executions.html index 08e83ff..740319f 100644 --- a/src/ci_orchestrator/web/templates/partials/executions.html +++ b/src/ci_orchestrator/web/templates/partials/executions.html @@ -89,7 +89,7 @@