From 1156984fa6bef58d2cacc906e93cb68c48b2be9c Mon Sep 17 00:00:00 2001 From: makearmy Date: Mon, 6 Oct 2025 22:05:29 -0400 Subject: [PATCH] submission form cleanup --- components/details/CO2GalvoDetail.tsx | 74 ++++++++++++++--------- components/forms/SettingsSubmit.tsx | 85 ++++++++++++++++++++------- components/lists/CO2GalvoList.tsx | 2 +- 3 files changed, 112 insertions(+), 49 deletions(-) diff --git a/components/details/CO2GalvoDetail.tsx b/components/details/CO2GalvoDetail.tsx index 918b59a9..58ece1d9 100644 --- a/components/details/CO2GalvoDetail.tsx +++ b/components/details/CO2GalvoDetail.tsx @@ -92,9 +92,13 @@ export default function CO2GalvoDetail({ id, editable }: { id: string | number; const j = t ? JSON.parse(t) : null; const idVal = j?.data?.id ?? j?.id ?? null; if (alive) setMeId(idVal ? String(idVal) : null); - } catch { /* ignore */ } + } catch { + /* ignore */ + } })(); - return () => { alive = false; }; + return () => { + alive = false; + }; }, []); useEffect(() => { @@ -170,7 +174,9 @@ export default function CO2GalvoDetail({ id, editable }: { id: string | number; if (!dead) setLoading(false); } })(); - return () => { dead = true; }; + return () => { + dead = true; + }; }, [id]); if (loading) return

Loading setting…

; @@ -197,9 +203,16 @@ export default function CO2GalvoDetail({ id, editable }: { id: string | number; const isMine = meId && ownerId ? meId === ownerId : false; // Small field renderer (label on top, value below) - const Field = ({ label, value, suffix }: { label: string; value: React.ReactNode | string | number | null | undefined; suffix?: string }) => { - const primitive = - typeof value === "string" || typeof value === "number" || typeof value === "boolean"; + const Field = ({ + label, + value, + suffix, + }: { + label: string; + value: React.ReactNode | string | number | null | undefined; + suffix?: string; + }) => { + const primitive = typeof value === "string" || typeof value === "number" || typeof value === "boolean"; const isEmpty = value == null || value === "" || (typeof value === "number" && isNaN(value as number)); return ( @@ -240,10 +253,19 @@ export default function CO2GalvoDetail({ id, editable }: { id: string | number; }; const DITHER_LABEL = (v: string | undefined) => (v ? v.charAt(0).toUpperCase() + v.slice(1) : "—"); + const asNumOrNull = (v: any): number | null => { + if (typeof v === "number") return Number.isFinite(v) ? v : null; + if (typeof v === "string" && v.trim() !== "") { + const n = Number(v); + return Number.isFinite(n) ? n : null; + } + // treat booleans/objects as null for numeric-only display + return null; + }; + // ----- EDIT MODE ----- if (editMode && rec) { - const toId = (v: any) => - v == null ? "" : typeof v === "object" ? (v.id ?? v.submission_id ?? "") : String(v); + const toId = (v: any) => (v == null ? "" : typeof v === "object" ? (v.id ?? v.submission_id ?? "") : String(v)); const initialValues = { submission_id: rec.submission_id, @@ -307,9 +329,7 @@ export default function CO2GalvoDetail({ id, editable }: { id: string | number;
- {rec.setting_notes ? ( - {rec.setting_notes}

} /> - ) : null} + {rec.setting_notes ? {rec.setting_notes}

} /> : null}
{/* Images (side-by-side thumbnails) */} @@ -356,11 +376,7 @@ export default function CO2GalvoDetail({ id, editable }: { id: string | number; @@ -396,9 +412,9 @@ export default function CO2GalvoDetail({ id, editable }: { id: string | number; - + - + {/* Pulse removed for CO2 */}
@@ -425,31 +441,35 @@ export default function CO2GalvoDetail({ id, editable }: { id: string | number; {rec.line_settings!.map((r: any, i: number) => { const perfEnabled = !!r.perf; const wobbleEnabled = !!r.wobble; + const cutVal = asNumOrNull(r.cut); + const skipVal = asNumOrNull(r.skip); + const stepVal = asNumOrNull(r.step); + const sizeVal = asNumOrNull(r.size); + return (
{r.name || `Line ${i + 1}`}
- {/* Base fields – match form order */} + {/* Base fields – match form order (Pulse removed) */}
- - +
{/* Perforation row */}
- {perfEnabled && } - {perfEnabled && } + {perfEnabled && } + {perfEnabled && }
{/* Wobble row */}
- {wobbleEnabled && } - {wobbleEnabled && } + {wobbleEnabled && } + {wobbleEnabled && }
{/* Simple toggle */} @@ -478,9 +498,9 @@ export default function CO2GalvoDetail({ id, editable }: { id: string | number; - + - + {/* Pulse removed for CO2 */} {isHalftone && } {isHalftone && } diff --git a/components/forms/SettingsSubmit.tsx b/components/forms/SettingsSubmit.tsx index 2b163c17..9a5653ea 100644 --- a/components/forms/SettingsSubmit.tsx +++ b/components/forms/SettingsSubmit.tsx @@ -81,7 +81,9 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV if (alive) setMe(null); } })(); - return () => { alive = false; }; + return () => { + alive = false; + }; }, []); // Options loaders (Directus reads) @@ -92,7 +94,8 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV (async () => { let url = ""; - let map = (rows: any[]) => rows.map((r) => ({ id: String(r.id ?? r.submission_id), label: String(r.name ?? r.model ?? r.opacity ?? r.id) })); + let map = (rows: any[]) => + rows.map((r) => ({ id: String(r.id ?? r.submission_id), label: String(r.name ?? r.model ?? r.opacity ?? r.id) })); if (path === "material") url = `${API}/items/material?fields=id,name&limit=1000&sort=name`; else if (path === "material_coating") url = `${API}/items/material_coating?fields=id,name&limit=1000&sort=name`; @@ -129,7 +132,10 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV map = (rows) => rows .slice() - .sort((a, b) => (parseFloat(a.focal_length ?? "99999") || 99999) - (parseFloat(b.focal_length ?? "99999") || 99999)) + .sort( + (a, b) => + (parseFloat(a.focal_length ?? "99999") || 99999) - (parseFloat(b.focal_length ?? "99999") || 99999) + ) .map((r) => { const fs = r.field_size ? `${r.field_size} mm` : ""; const fl = r.focal_length ? `${r.focal_length} mm` : ""; @@ -158,7 +164,9 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV if (live) setOpts(list); })().catch(() => live && setOpts([])); - return () => { live = false; }; + return () => { + live = false; + }; }, [path, includeId]); return { opts }; @@ -172,7 +180,16 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV ]; const RASTER_TYPES = FILL_TYPES; const RASTER_DITHER: Opt[] = [ - "threshold", "ordered", "atkinson", "dither", "stucki", "jarvis", "newsprint", "halftone", "sketch", "grayscale", + "threshold", + "ordered", + "atkinson", + "dither", + "stucki", + "jarvis", + "newsprint", + "halftone", + "sketch", + "grayscale", ].map((x) => ({ id: x, label: x[0].toUpperCase() + x.slice(1) })); // react-hook-form @@ -281,9 +298,15 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV }, [ isEdit, initialValues, - mats.opts, coats.opts, colors.opts, opacs.opts, - soft.opts, srcs.opts, - conf.opts, apt.opts, exp.opts, + mats.opts, + coats.opts, + colors.opts, + opacs.opts, + soft.opts, + srcs.opts, + conf.opts, + apt.opts, + exp.opts, lens.opts, setValue, ]); @@ -291,7 +314,8 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV // Image files const [photoFile, setPhotoFile] = useState(null); const [screenFile, setScreenFile] = useState(null); - const onPick = (setter: (f: File | null) => void) => (e: React.ChangeEvent) => setter(e.target.files?.[0] ?? null); + const onPick = (setter: (f: File | null) => void) => (e: React.ChangeEvent) => + setter(e.target.files?.[0] ?? null); const onSubmit = async (values: any) => { setSubmitErr(null); @@ -354,7 +378,9 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV {/* Hide local H1 in edit mode to avoid duplicate page title */} {!isEdit &&

Submit CO₂ Galvo Setting

} {meLabel ?

Submitting as {meLabel}

: null} - {submitErr ?
{submitErr}
: null} + {submitErr ? ( +
{submitErr}
+ ) : null}
@@ -441,11 +467,11 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV {options.map((o) => ( - + ))}
@@ -616,7 +655,9 @@ function Repeater({ title, fields, onAdd, onRemove, render }: any) {
{title} - +
@@ -624,7 +665,9 @@ function Repeater({ title, fields, onAdd, onRemove, render }: any) {
{render(i)}
- +
))} diff --git a/components/lists/CO2GalvoList.tsx b/components/lists/CO2GalvoList.tsx index 85e13f45..5caec5f5 100644 --- a/components/lists/CO2GalvoList.tsx +++ b/components/lists/CO2GalvoList.tsx @@ -82,7 +82,7 @@ export default function CO2GalvoList({ const fields = [ "submission_id", "setting_title", - "owner", + // IMPORTANT: request the expanded relation only (do NOT include bare 'owner' id) "owner.id", "owner.username", "uploader",