Render live durations immediately instead of leaving them to the ticker
The 10s table poll rebuilt the rows with an empty duration cell for running/pending builds (durationSeconds is null until a build finishes), which the once-per-second ticker then filled back in — a visible flicker. Rows and current-build cards now compute the elapsed time at render time. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
9e7982ce34
commit
2cb6b1598a
@@ -56,6 +56,24 @@ function statusCssClass(status) {
|
|||||||
return "status status-" + (KNOWN_STATUSES.has(status) ? status : "unknown");
|
return "status status-" + (KNOWN_STATUSES.has(status) ? status : "unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Seconds elapsed since `startedAtIso`, or null when it is missing/invalid. */
|
||||||
|
function elapsedSeconds(startedAtIso) {
|
||||||
|
const startedAt = new Date(startedAtIso || "").getTime();
|
||||||
|
return Number.isNaN(startedAt) ? null : (Date.now() - startedAt) / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The duration to display for a build: the recorded duration once finished, the
|
||||||
|
* live elapsed time while running or pending — so re-rendered rows never show an
|
||||||
|
* empty cell that the once-per-second ticker fills back in (visible flicker).
|
||||||
|
*/
|
||||||
|
function displayDurationSeconds(build) {
|
||||||
|
if (build.durationSeconds != null) {
|
||||||
|
return build.durationSeconds;
|
||||||
|
}
|
||||||
|
return build.status === "running" || build.status === "pending" ? elapsedSeconds(build.startedAt) : null;
|
||||||
|
}
|
||||||
|
|
||||||
// ---- shared infrastructure -------------------------------------------------
|
// ---- shared infrastructure -------------------------------------------------
|
||||||
|
|
||||||
const FETCH_TIMEOUT_MS = 8000;
|
const FETCH_TIMEOUT_MS = 8000;
|
||||||
@@ -216,7 +234,7 @@ function renderBuildRow(build, allowRestart) {
|
|||||||
startedCell.dataset.label = "Started";
|
startedCell.dataset.label = "Started";
|
||||||
row.appendChild(startedCell);
|
row.appendChild(startedCell);
|
||||||
|
|
||||||
const durationCell = elem("td", "duration-cell", formatDuration(build.durationSeconds));
|
const durationCell = elem("td", "duration-cell", formatDuration(displayDurationSeconds(build)));
|
||||||
durationCell.dataset.label = "Duration";
|
durationCell.dataset.label = "Duration";
|
||||||
row.appendChild(durationCell);
|
row.appendChild(durationCell);
|
||||||
|
|
||||||
@@ -309,7 +327,7 @@ function renderBuildCard(build) {
|
|||||||
);
|
);
|
||||||
header.appendChild(commitCode);
|
header.appendChild(commitCode);
|
||||||
header.appendChild(elem("span", "muted", "started " + formatTimestamp(build.startedAt)));
|
header.appendChild(elem("span", "muted", "started " + formatTimestamp(build.startedAt)));
|
||||||
header.appendChild(elem("span", "duration-cell running-duration"));
|
header.appendChild(elem("span", "duration-cell running-duration", formatDuration(displayDurationSeconds(build))));
|
||||||
const cardActions = elem("span", "build-card-actions");
|
const cardActions = elem("span", "build-card-actions");
|
||||||
cardActions.appendChild(
|
cardActions.appendChild(
|
||||||
actionButton("× Cancel", "Cancel build", "cancel-button", {
|
actionButton("× Cancel", "Cancel build", "cancel-button", {
|
||||||
|
|||||||
Reference in New Issue
Block a user