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:
@@ -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>
|
||||
|
||||
@@ -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" ? (
|
||||
|
||||
Reference in New Issue
Block a user