feat(dashboard): live ticker for approval request-age chips + precise stale threshold
Approval cards render their age label ("requested N ago") at
render time from a cold /api/state or an approval_added /
approval_resolved SSE event. An approval sitting pending for
an hour would show a stale "0s ago" unless one of those events
fired in the meantime.
Fix: stamp data-requested-at=<unix> on each .approval-ts span.
A 1s setInterval ticker reads all live chips, recomputes the
relative time via fmtAgo, and toggles .stale (amber highlight)
at exactly the 1-hour threshold — no longer dependent on
the next full re-render cycle to apply the amber colour.
This commit is contained in:
parent
717177dbad
commit
4731b64f3e
1 changed files with 17 additions and 0 deletions
|
|
@ -1994,6 +1994,22 @@ window.marked = marked;
|
||||||
});
|
});
|
||||||
}, 30_000);
|
}, 30_000);
|
||||||
|
|
||||||
|
// Live ticker for approval request-age chips. Approval cards only
|
||||||
|
// re-render on `approval_added`/`approval_resolved` SSE events, so
|
||||||
|
// a request pending for an hour could still show "0s ago" without
|
||||||
|
// this ticker. Also flips `.stale` (amber highlight) at exactly 1h
|
||||||
|
// rather than only at the next re-render.
|
||||||
|
setInterval(() => {
|
||||||
|
const now = Math.floor(Date.now() / 1000);
|
||||||
|
document.querySelectorAll('.approval-ts[data-requested-at]').forEach((node) => {
|
||||||
|
const requestedAt = Number(node.getAttribute('data-requested-at'));
|
||||||
|
if (!Number.isFinite(requestedAt)) return;
|
||||||
|
const ageSec = Math.max(0, now - requestedAt);
|
||||||
|
node.textContent = 'requested ' + fmtAgo(requestedAt);
|
||||||
|
node.classList.toggle('stale', ageSec >= 3600);
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
const APPROVAL_TAB_KEY = 'hyperhive:approvals:tab';
|
const APPROVAL_TAB_KEY = 'hyperhive:approvals:tab';
|
||||||
// Derived approval state — cold-loaded from /api/state, then mutated
|
// Derived approval state — cold-loaded from /api/state, then mutated
|
||||||
// live by `approval_added` / `approval_resolved` dashboard events.
|
// live by `approval_added` / `approval_resolved` dashboard events.
|
||||||
|
|
@ -2248,6 +2264,7 @@ window.marked = marked;
|
||||||
head.append(el('span', {
|
head.append(el('span', {
|
||||||
class: 'approval-ts' + (ageSec >= 3600 ? ' stale' : ''),
|
class: 'approval-ts' + (ageSec >= 3600 ? ' stale' : ''),
|
||||||
title: 'requested ' + new Date(a.requested_at * 1000).toLocaleString(),
|
title: 'requested ' + new Date(a.requested_at * 1000).toLocaleString(),
|
||||||
|
'data-requested-at': String(a.requested_at),
|
||||||
}, 'requested ' + fmtAgo(a.requested_at)));
|
}, 'requested ' + fmtAgo(a.requested_at)));
|
||||||
}
|
}
|
||||||
li.append(head);
|
li.append(head);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue