feat(web): richer active-job rows on The Floor (source/format/tracks, stage, elapsed, error)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+76
-25
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { describeJob } from "./_ui/status";
|
||||
import { describeJob, timeAgo } from "./_ui/status";
|
||||
import { StatTiles } from "./_ui/stat-tiles";
|
||||
import { SectionHeader } from "./_ui/section-header";
|
||||
import { JobRow } from "./_ui/job-row";
|
||||
@@ -15,11 +15,31 @@ type Row = {
|
||||
status: string;
|
||||
createdAt?: string;
|
||||
rgMbid?: string | null;
|
||||
job: { state: string; currentStage: string } | null;
|
||||
job: {
|
||||
state: string;
|
||||
currentStage: string;
|
||||
attempts: number;
|
||||
error: string | null;
|
||||
claimedAt: string | null;
|
||||
updatedAt: string | null;
|
||||
candidateCount: number;
|
||||
chosen: { source: string; format: string; trackCount: number } | null;
|
||||
} | null;
|
||||
};
|
||||
|
||||
function jobOf(r: Row) {
|
||||
return r.job ?? { state: "requested", currentStage: "intake" };
|
||||
return (
|
||||
r.job ?? {
|
||||
state: "requested",
|
||||
currentStage: "intake",
|
||||
attempts: 0,
|
||||
error: null,
|
||||
claimedAt: null,
|
||||
updatedAt: null,
|
||||
candidateCount: 0,
|
||||
chosen: null,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function pressedMark(r: Row): string {
|
||||
@@ -101,28 +121,59 @@ export function Queue() {
|
||||
<p className="empty">The press is quiet. Queue a release above, or send one over from Wanted or Discover.</p>
|
||||
) : (
|
||||
<section className="floor">
|
||||
{active.map((r) => {
|
||||
const j = jobOf(r);
|
||||
const d = describeJob(j.state, j.currentStage);
|
||||
const attention = d.kind === "attention";
|
||||
return (
|
||||
<JobRow
|
||||
key={r.id}
|
||||
artist={r.artist}
|
||||
album={r.album}
|
||||
kind={d.kind}
|
||||
label={d.label}
|
||||
step={d.step}
|
||||
total={d.totalSteps}
|
||||
indeterminate={j.state === "matching" || j.state === "matched"}
|
||||
note={
|
||||
attention
|
||||
? "No source met the quality cutoff, or the pipeline stalled. Retry the request, or lower the cutoff for this release."
|
||||
: undefined
|
||||
}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{(() => {
|
||||
const now = Date.now();
|
||||
return active.map((r) => {
|
||||
const j = jobOf(r);
|
||||
const d = describeJob(j.state, j.currentStage);
|
||||
const attention = d.kind === "attention";
|
||||
|
||||
let meta: string | undefined;
|
||||
if (j.state === "downloading" || j.state === "tagging") {
|
||||
const parts: string[] = [];
|
||||
if (j.chosen) parts.push(`${j.chosen.source} · ${j.chosen.format} · ${j.chosen.trackCount} tracks`);
|
||||
const elapsed = timeAgo(j.claimedAt ?? j.updatedAt, now);
|
||||
if (elapsed) parts.push(elapsed);
|
||||
meta = parts.join(" · ") || undefined;
|
||||
} else if (j.state === "matching" || j.state === "matched") {
|
||||
meta =
|
||||
j.candidateCount > 0
|
||||
? `${j.candidateCount} sources${j.chosen ? ` · best: ${j.chosen.source} ${j.chosen.format}` : ""}`
|
||||
: "Searching sources…";
|
||||
} else if (j.state === "requested") {
|
||||
const elapsed = timeAgo(r.createdAt, now);
|
||||
meta = elapsed ? `In the queue · ${elapsed}` : "In the queue";
|
||||
} else if (j.state === "needs_attention") {
|
||||
meta = undefined;
|
||||
} else {
|
||||
meta = undefined;
|
||||
}
|
||||
|
||||
const note = attention
|
||||
? j.error?.trim() ||
|
||||
"No source met the quality cutoff, or the pipeline stalled. Retry the request, or lower the cutoff for this release."
|
||||
: undefined;
|
||||
|
||||
const stageLabel =
|
||||
attention || j.state === "matching" || j.state === "matched" ? undefined : j.currentStage;
|
||||
|
||||
return (
|
||||
<JobRow
|
||||
key={r.id}
|
||||
artist={r.artist}
|
||||
album={r.album}
|
||||
kind={d.kind}
|
||||
label={d.label}
|
||||
step={d.step}
|
||||
total={d.totalSteps}
|
||||
indeterminate={j.state === "matching" || j.state === "matched"}
|
||||
meta={meta}
|
||||
note={note}
|
||||
stageLabel={stageLabel}
|
||||
/>
|
||||
);
|
||||
});
|
||||
})()}
|
||||
</section>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user