feat(frontend): show build duration on job status and list

Display elapsed time while building and total duration from start to completion for success and failure.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-29 13:53:52 +08:00
parent 44fa5d3d82
commit f6fa4bb1ca
3 changed files with 87 additions and 1 deletions

View File

@@ -1,6 +1,7 @@
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { fetchBuilds, statusLabel, type Build } from "../api/client";
import { getBuildDuration, isBuildFinished } from "../lib/duration";
export default function BuildList() {
const [builds, setBuilds] = useState<Build[]>([]);
@@ -32,7 +33,10 @@ export default function BuildList() {
{build.appName} ({build.appNameEn})
</Link>
<div className="meta-line">
v{build.appVersion} · {build.id} · {statusLabel(build.status)}{" "}
v{build.appVersion} · {statusLabel(build.status)}
{isBuildFinished(build.status)
? ` · 耗时 ${getBuildDuration(build).text}`
: null}{" "}
· {new Date(build.createdAt).toLocaleString()}
</div>
</li>

View File

@@ -1,11 +1,17 @@
import { useEffect, useState } from "react";
import { Link, useParams } from "react-router-dom";
import { fetchBuild, statusLabel, type Build } from "../api/client";
import {
formatDateTime,
getBuildDuration,
isBuildFinished,
} from "../lib/duration";
export default function JobStatus() {
const { id } = useParams<{ id: string }>();
const [build, setBuild] = useState<Build | null>(null);
const [error, setError] = useState<string | null>(null);
const [now, setNow] = useState(() => Date.now());
useEffect(() => {
if (!id) return;
@@ -37,6 +43,14 @@ export default function JobStatus() {
};
}, [id]);
useEffect(() => {
if (!build || isBuildFinished(build.status)) return;
const timer = window.setInterval(() => setNow(Date.now()), 1000);
return () => window.clearInterval(timer);
}, [build?.status, build?.id]);
const duration = build ? getBuildDuration(build, now) : null;
if (!id) {
return <p className="error-text"> ID</p>;
}
@@ -90,6 +104,22 @@ export default function JobStatus() {
</span>
</dd>
</div>
<div>
<dt></dt>
<dd>{formatDateTime(build.createdAt)}</dd>
</div>
{duration?.finished ? (
<div>
<dt></dt>
<dd>{formatDateTime(build.updatedAt)}</dd>
</div>
) : null}
<div>
<dt>{duration?.finished ? "构建总耗时" : "已用时间"}</dt>
<dd>
<strong>{duration?.text ?? "—"}</strong>
</dd>
</div>
</dl>
{build.status === "completed" ? (