dashboard: tick question TTL chip every second
The `⏳ MM:SS` chip on an asked-with-timeout question was rendered once and then frozen — the operator saw stale info (e.g. 48s sitting unchanged for the whole TTL window) (issue #335). Stamp the deadline onto the chip as `data-deadline` and run a single page-wide setInterval that refreshes every `.q-ttl[data- deadline]`'s textContent each second. No re-render of the questions section; no new state on the client. No-op when no chips are on screen. Also pulls the bucketed seconds-to-string logic into a `formatTtl` helper so the renderer and the ticker share one source of truth. Closes #335.
This commit is contained in:
parent
5887111327
commit
6f3b56ad84
1 changed files with 40 additions and 9 deletions
|
|
@ -1028,15 +1028,17 @@
|
||||||
el('span', { class: 'msg-sep' }, 'asks:'),
|
el('span', { class: 'msg-sep' }, 'asks:'),
|
||||||
);
|
);
|
||||||
if (q.deadline_at) {
|
if (q.deadline_at) {
|
||||||
const remaining = q.deadline_at - Math.floor(Date.now() / 1000);
|
// Tag the chip with its deadline so the global 1s ticker
|
||||||
let txt;
|
// (set up just below this function) can refresh the text
|
||||||
if (remaining <= 0) txt = 'expiring…';
|
// without re-rendering the whole questions section
|
||||||
else if (remaining < 60) txt = '⏳ ' + remaining + 's';
|
// (issue #335).
|
||||||
else if (remaining < 3600) txt = '⏳ ' + Math.floor(remaining / 60) + 'm '
|
const ttlEl = el('span', {
|
||||||
+ (remaining % 60) + 's';
|
class: 'q-ttl', 'data-deadline': String(q.deadline_at),
|
||||||
else txt = '⏳ ' + Math.floor(remaining / 3600) + 'h '
|
});
|
||||||
+ Math.floor((remaining % 3600) / 60) + 'm';
|
ttlEl.textContent = formatTtl(
|
||||||
head.append(' ', el('span', { class: 'q-ttl' }, txt));
|
q.deadline_at - Math.floor(Date.now() / 1000),
|
||||||
|
);
|
||||||
|
head.append(' ', ttlEl);
|
||||||
}
|
}
|
||||||
const qBody = el('div', { class: 'q-body' });
|
const qBody = el('div', { class: 'q-body' });
|
||||||
appendLinkified(qBody, q.question, q.question_refs);
|
appendLinkified(qBody, q.question, q.question_refs);
|
||||||
|
|
@ -1156,6 +1158,35 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Format a remaining-seconds count as the `⏳ …` TTL chip text on a
|
||||||
|
// question card. Bucketed at minutes / hours so a long deadline stays
|
||||||
|
// readable; "expiring…" once the deadline has passed (the host-side
|
||||||
|
// ttl-watchdog will fire shortly).
|
||||||
|
function formatTtl(remaining) {
|
||||||
|
if (remaining <= 0) return 'expiring…';
|
||||||
|
if (remaining < 60) return '⏳ ' + remaining + 's';
|
||||||
|
if (remaining < 3600) {
|
||||||
|
return '⏳ ' + Math.floor(remaining / 60) + 'm '
|
||||||
|
+ (remaining % 60) + 's';
|
||||||
|
}
|
||||||
|
return '⏳ ' + Math.floor(remaining / 3600) + 'h '
|
||||||
|
+ Math.floor((remaining % 3600) / 60) + 'm';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Single page-wide ticker that refreshes every TTL chip in place
|
||||||
|
// each second (issue #335). Renderers stamp `data-deadline` on the
|
||||||
|
// chip; this just updates `textContent`, no re-render of the
|
||||||
|
// questions section. No-op when no chips are on screen, so the
|
||||||
|
// cost is negligible.
|
||||||
|
setInterval(() => {
|
||||||
|
const now = Math.floor(Date.now() / 1000);
|
||||||
|
document.querySelectorAll('.q-ttl[data-deadline]').forEach((node) => {
|
||||||
|
const deadline = Number(node.getAttribute('data-deadline'));
|
||||||
|
if (!Number.isFinite(deadline)) return;
|
||||||
|
node.textContent = formatTtl(deadline - now);
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
// ─── operator inbox (derived from the broker message stream) ───────────
|
// ─── operator inbox (derived from the broker message stream) ───────────
|
||||||
// No longer shipped on `/api/state.operator_inbox`. The dashboard
|
// No longer shipped on `/api/state.operator_inbox`. The dashboard
|
||||||
// terminal's HiveTerminal feeds this via `onAnyEvent` — backfill from
|
// terminal's HiveTerminal feeds this via `onAnyEvent` — backfill from
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue