// Pure logic behind the image-fetch surfaces (SD-0002 §5.5): the run-detail // progress/outcome labels + the history "Images" cell + terminal-status test // that drives polling. Mirrors exportMenu.ts: pure helpers unit-tested here, // the JSX verified by the E2E suite (SLICE-2/3 pattern). import type { ImageCounts } from "../../productsApi"; export function imageProgressLabel(p: { done: number; total: number }): string { return `Fetching images: ${p.done.toLocaleString()} of ${p.total.toLocaleString()}`; } export function imageOutcomeSummary(c: ImageCounts): string { return `${c.fetched.toLocaleString()} fetched · ${c.rejected.toLocaleString()} rejected · ${c.failed.toLocaleString()} failed`; } export function historyImageCell(c: ImageCounts | undefined): string { if (!c || c.fetched + c.rejected + c.failed === 0) return "—"; const bad = c.rejected + c.failed; return bad === 0 ? `${c.fetched.toLocaleString()} ✓` : `${c.fetched.toLocaleString()} ✓ · ${bad.toLocaleString()} ✗`; } export function isRunTerminal(status: string): boolean { return status === "complete" || status === "complete_with_problems"; } export function outcomeLabel(outcome: string): string { if (outcome === "rejected_low_res") return "Rejected — below the resolution bar"; if (outcome === "rejected_not_image") return "Rejected — not a supported image"; if (outcome === "failed") return "Failed — unreachable"; return outcome; }