Add structured job progress tracking
This commit is contained in:
@@ -25,6 +25,16 @@ import "./styles.css";
|
||||
|
||||
const API_BASE = import.meta.env.VITE_API_BASE ?? "http://localhost:8010";
|
||||
|
||||
type JobProgress = {
|
||||
percent: number | null;
|
||||
label: string;
|
||||
stage: string;
|
||||
current: number | null;
|
||||
total: number | null;
|
||||
unit: string | null;
|
||||
source: string;
|
||||
};
|
||||
|
||||
type Job = {
|
||||
id: string;
|
||||
type: string;
|
||||
@@ -35,6 +45,7 @@ type Job = {
|
||||
finished_at?: string;
|
||||
log_tail?: string;
|
||||
params: Record<string, unknown>;
|
||||
progress?: JobProgress;
|
||||
};
|
||||
|
||||
type Catalog = {
|
||||
@@ -273,6 +284,21 @@ function StatusPill({ status }: { status: string }) {
|
||||
return <span className={`pill pill-${status}`}>{status}</span>;
|
||||
}
|
||||
|
||||
function JobProgressBar({ progress }: { progress?: JobProgress }) {
|
||||
const percent = typeof progress?.percent === "number" ? Math.max(0, Math.min(100, progress.percent)) : 0;
|
||||
return (
|
||||
<div className="progressBox" data-stage={progress?.stage ?? "unknown"}>
|
||||
<div className="progressTrack" aria-label={progress?.label ?? "job progress"}>
|
||||
<span style={{ width: `${percent}%` }} />
|
||||
</div>
|
||||
<div className="progressMeta">
|
||||
<span>{progress?.label ?? "等待日志"}</span>
|
||||
<strong>{typeof progress?.percent === "number" ? `${progress.percent.toFixed(progress.percent % 1 ? 1 : 0)}%` : "..."}</strong>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function App() {
|
||||
const { catalog, gpus, jobs, results, curves, datasets, datasetValidations, coverage, acceptance, deepAcceptance, error, refresh } = useData();
|
||||
const [taskType, setTaskType] = useState("mock.echo");
|
||||
@@ -553,9 +579,12 @@ function App() {
|
||||
<div className="jobList">
|
||||
{jobs.slice(0, 12).map((job) => (
|
||||
<button key={job.id} className="jobRow" onClick={() => inspectJob(job)}>
|
||||
<span>{job.type}</span>
|
||||
<StatusPill status={job.status} />
|
||||
<div className="jobRowTop">
|
||||
<span>{job.type}</span>
|
||||
<StatusPill status={job.status} />
|
||||
</div>
|
||||
<small>{job.description || job.id.slice(0, 8)}</small>
|
||||
<JobProgressBar progress={job.progress} />
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -836,6 +865,7 @@ function App() {
|
||||
<Square size={18} />
|
||||
</button>
|
||||
</div>
|
||||
{selectedJob && <JobProgressBar progress={selectedJob.progress} />}
|
||||
<pre>{log || "No log selected."}</pre>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user