From 8f4b171d1b15b5e1238e6ac68f3c2eac73c9fcc2 Mon Sep 17 00:00:00 2001 From: navidgh67 Date: Wed, 14 Oct 2026 22:25:37 -0400 Subject: [PATCH] Show run values as stored and add a metadata download The run page rounded every numeric input and output to two decimals, so a stored Time per Step of 0.191 s showed as 0.19. Recorded values now show exactly as stored; etcher step averages stay rounded with the full value on hover. A "Download metadata" button saves the run record as JSON. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01Ve21T1az57p9vrmYj8vdNe --- web/app/data/catalog/[id]/page.tsx | 42 +++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/web/app/data/catalog/[id]/page.tsx b/web/app/data/catalog/[id]/page.tsx index 669cd25..74deae4 100644 --- a/web/app/data/catalog/[id]/page.tsx +++ b/web/app/data/catalog/[id]/page.tsx @@ -25,6 +25,7 @@ import { Activity, AlertTriangle, BookOpen, + Download, } from "lucide-react"; const FEATURE_DISPLAY: Record = { @@ -58,6 +59,26 @@ function formatNumber(value: number | null | undefined, digits = 2): string { return value.toFixed(digits); } +/** A stored input or output value exactly as recorded, without rounding. */ +function formatStoredValue(value: unknown): string { + if (value === null || value === undefined) return "—"; + if (typeof value === "number") return Number.isNaN(value) ? "—" : String(value); + return String(value); +} + +/** Save the run's stored metadata (everything the page loaded) as JSON. */ +function downloadRunMetadata(run: V2Run) { + const blob = new Blob([JSON.stringify(run, null, 2)], { type: "application/json" }); + const url = URL.createObjectURL(blob); + const link = document.createElement("a"); + link.href = url; + link.download = `run-${run.run_id}-metadata.json`; + document.body.appendChild(link); + link.click(); + link.remove(); + URL.revokeObjectURL(url); +} + function formatTimestamp(value: string | null | undefined): string { if (!value) return "—"; const sourceText = value.trim(); @@ -206,7 +227,15 @@ export default function RunDetailPage({ params }: { params: Promise<{ id: string -
+
+ {badges.map((b) => ( {key}

- {typeof value === "number" - ? formatNumber(value, 2) - : value === null || value === undefined - ? "—" - : String(value)} + {formatStoredValue(value)} {!supplemented.has(key) && outputUnits.get(key) && ( {outputUnits.get(key)} @@ -401,7 +426,10 @@ export default function RunDetailPage({ params }: { params: Promise<{ id: string {fromSummary ? [meta.description, "from the canonical summary"].filter(Boolean).join(" · ") : meta.description} - {typeof value === "number" ? formatNumber(value, 2) : value === null || value === undefined ? "—" : String(value)} + + {/* Etcher inputs are computed step averages, so they stay rounded; recorded set-points show exactly as stored. */} + {isEtcher && typeof value === "number" ? formatNumber(value, 2) : formatStoredValue(value)} + {unit} );