submission form cleanup

This commit is contained in:
makearmy 2025-10-06 21:02:47 -04:00
parent 01d16881d1
commit 1f5a44ea9f

View file

@ -55,7 +55,7 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
const [me, setMe] = useState<Me>(null);
const [submitErr, setSubmitErr] = useState<string | null>(null);
// Robust current-user fetch (unchanged)
// Robust current-user fetch
useEffect(() => {
let alive = true;
(async () => {
@ -84,7 +84,7 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
return () => { alive = false; };
}, []);
// Options loaders (unchanged)
// Options loaders (Directus reads)
function useOptions(path: string, includeId?: string | null) {
const [opts, setOpts] = useState<Opt[]>([]);
useEffect(() => {
@ -164,7 +164,7 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
return { opts };
}
// Enumerations (unchanged)
// Enumerations
const FILL_TYPES: Opt[] = [
{ id: "uni", label: "UniDirectional" },
{ id: "bi", label: "BiDirectional" },
@ -175,14 +175,14 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
"threshold", "ordered", "atkinson", "dither", "stucki", "jarvis", "newsprint", "halftone", "sketch", "grayscale",
].map((x) => ({ id: x, label: x[0].toUpperCase() + x.slice(1) }));
// react-hook-form (unchanged)
// react-hook-form
const {
register,
handleSubmit,
control,
reset,
setValue,
getValues,
getValues, // ⬅ added
setValue, // ⬅ added
formState: { isSubmitting },
} = useForm<any>({
defaultValues: {
@ -197,6 +197,7 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
// Rig & Optics
laser_soft: "",
source: "",
// keep these blank so Select shows "—"
lens_conf: "",
lens_apt: "",
lens_exp: "",
@ -210,12 +211,12 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
},
});
// Repeaters (unchanged)
// Repeaters
const fills = useFieldArray({ control, name: "fill_settings" });
const lines = useFieldArray({ control, name: "line_settings" });
const rasters = useFieldArray({ control, name: "raster_settings" });
// Prefill (unchanged)
// Prefill (edit)
useEffect(() => {
if (!isEdit || !initialValues) return;
reset({
@ -243,7 +244,43 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
});
}, [isEdit, initialValues, reset]);
// Options (unchanged)
// Re-apply select values when options hydrate (fixes stubborn placeholder issue)
useEffect(() => {
if (!isEdit || !initialValues) return;
const ensure = (name: string, currentId: string | null | undefined, opts: Opt[]) => {
if (!currentId) return;
const cur = getValues(name as any);
const curStr = cur == null ? "" : String(cur);
if (!curStr || !opts.some((o) => String(o.id) === curStr)) {
setValue(name as any, String(currentId), { shouldDirty: false, shouldValidate: false });
}
};
ensure("mat", initialValues.mat, mats.opts);
ensure("mat_coat", initialValues.mat_coat, coats.opts);
ensure("mat_color", initialValues.mat_color, colors.opts);
ensure("mat_opacity", initialValues.mat_opacity, opacs.opts);
ensure("laser_soft", initialValues.laser_soft, soft.opts);
ensure("source", initialValues.source, srcs.opts);
ensure("lens_conf", initialValues.lens_conf, conf.opts);
ensure("lens_apt", initialValues.lens_apt, apt.opts);
ensure("lens_exp", initialValues.lens_exp, exp.opts);
ensure("lens", initialValues.lens, lens.opts);
}, [
isEdit,
initialValues,
mats.opts, coats.opts, colors.opts, opacs.opts,
soft.opts, srcs.opts,
conf.opts, apt.opts, exp.opts,
lens.opts,
getValues, setValue,
]);
// Option lists (include current IDs to guarantee a visible option)
const mats = useOptions("material", initialValues?.mat ?? null);
const coats = useOptions("material_coating", initialValues?.mat_coat ?? null);
const colors = useOptions("material_color", initialValues?.mat_color ?? null);
@ -255,34 +292,7 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
const apt = useOptions("laser_scan_lens_apt", initialValues?.lens_apt ?? null);
const exp = useOptions("laser_scan_lens_exp", initialValues?.lens_exp ?? null);
// Re-apply select values when options hydrate (unchanged fix)
useEffect(() => {
const pairs: Array<[keyof any, string | null | undefined, Opt[]]> = [
["mat", initialValues?.mat, mats.opts],
["mat_coat", initialValues?.mat_coat, coats.opts],
["mat_color", initialValues?.mat_color, colors.opts],
["mat_opacity", initialValues?.mat_opacity, opacs.opts],
["laser_soft", initialValues?.laser_soft, soft.opts],
["source", initialValues?.source, srcs.opts],
["lens_conf", initialValues?.lens_conf, conf.opts],
["lens_apt", initialValues?.lens_apt, apt.opts],
["lens_exp", initialValues?.lens_exp, exp.opts],
["lens", initialValues?.lens, lens.opts],
];
pairs.forEach(([name, id, opts]) => {
if (!id || !opts.length) return;
const current = getValues(String(name));
if (!current) {
setValue(String(name), String(id), { shouldDirty: false, shouldValidate: false });
}
});
}, [
mats.opts, coats.opts, colors.opts, opacs.opts, soft.opts,
srcs.opts, conf.opts, apt.opts, exp.opts, lens.opts,
initialValues, getValues, setValue
]);
// Files (unchanged)
// Image files
const [photoFile, setPhotoFile] = useState<File | null>(null);
const [screenFile, setScreenFile] = useState<File | null>(null);
const onPick = (setter: (f: File | null) => void) => (e: React.ChangeEvent<HTMLInputElement>) => setter(e.target.files?.[0] ?? null);
@ -309,10 +319,11 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
lens: values.lens || null,
focus: values.focus === "" ? null : globalThis.Number(values.focus),
repeat_all: values.repeat_all === "" ? null : globalThis.Number(values.repeat_all),
// Repeaters
// Repeaters (raw pass-through; api will normalize nums/bools)
fill_settings: values.fill_settings || [],
line_settings: values.line_settings || [],
raster_settings: values.raster_settings || [],
// If editing with existing asset IDs, the API will accept them
...(initialValues?.photo ? { photo: initialValues.photo } : {}),
...(initialValues?.screen ? { screen: initialValues.screen } : {}),
};
@ -344,17 +355,8 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
return (
<div className="space-y-5">
<header className="space-y-1">
{/* Hide duplicate header in edit mode; keep visible in create mode */}
{!isEdit && (
<h1 className="text-xl font-semibold">
Submit CO Galvo Setting
</h1>
)}
{isEdit && (
<h2 className="text-lg font-semibold">
Edit CO Galvo Setting
</h2>
)}
{/* Hide local H1 in edit mode to avoid duplicate page title */}
{!isEdit && <h1 className="text-xl font-semibold">Submit CO Galvo Setting</h1>}
{meLabel ? <p className="text-sm text-muted-foreground">Submitting as {meLabel}</p> : null}
{submitErr ? <div className="border border-red-500 bg-red-50 text-red-700 rounded px-3 py-2 text-sm">{submitErr}</div> : null}
</header>
@ -402,7 +404,7 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
</div>
</section>
{/* Rig & Optics */}
{/* Rig & Optics (order per spec) */}
<section className="space-y-3">
<h2 className="text-lg font-semibold">Rig & Optics</h2>
@ -413,8 +415,8 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
<div className="grid md:grid-cols-3 gap-3">
<Select label="Lens Configuration" {...{ name: "lens_conf", register, options: conf.opts, required: true }} />
<Select label="Scan Head Aperture (mm)" {...{ name: "lens_apt", register, options: apt.opts, required: true }} />
<Select label="Beam Expander (X Magnification)" {...{ name: "lens_exp", register, options: exp.opts, required: true }} />
<Select label="Scan Head Aperture" {...{ name: "lens_apt", register, options: apt.opts, required: true }} />
<Select label="Beam Expander" {...{ name: "lens_exp", register, options: exp.opts, required: true }} />
</div>
<div className="grid md:grid-cols-3 gap-3">
@ -435,7 +437,7 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
onAdd={() => fills.append({ type: "" })}
onRemove={(i) => fills.remove(i)}
render={(i) => {
const auto = !!useWatch({ control, name: `fill_settings.${i}.auto` });
const autoRotate = !!useWatch({ control, name: `fill_settings.${i}.auto` });
return (
<div className="grid md:grid-cols-4 gap-2">
<Text label="Name" name={`fill_settings.${i}.name`} register={register} />
@ -448,16 +450,17 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
<Number label="Pass" name={`fill_settings.${i}.pass`} register={register} step="1" />
<Number label="Angle (°)" name={`fill_settings.${i}.angle`} register={register} step="1" />
{/* Booleans each on their own lines */}
<div className="col-span-full"><Check label="Auto Rotate" name={`fill_settings.${i}.auto`} register={register} /></div>
{auto && (
<div className="col-span-full">
{/* Move Auto first, then its increment in a half-width cell */}
<Check label="Auto Rotate" name={`fill_settings.${i}.auto`} register={register} />
{autoRotate && (
<div className="md:col-span-2">
<Number label="Auto Rotate Increment (°)" name={`fill_settings.${i}.increment`} register={register} step="0.001" />
</div>
)}
<div className="col-span-full"><Check label="Crosshatch" name={`fill_settings.${i}.cross`} register={register} /></div>
<div className="col-span-full"><Check label="Flood Fill" name={`fill_settings.${i}.flood`} register={register} /></div>
<div className="col-span-full"><Check label="Air Assist" name={`fill_settings.${i}.air`} register={register} /></div>
<Check label="Crosshatch" name={`fill_settings.${i}.cross`} register={register} />
<Check label="Flood Fill" name={`fill_settings.${i}.flood`} register={register} />
<Check label="Air Assist" name={`fill_settings.${i}.air`} register={register} />
</div>
);
}}
@ -480,12 +483,10 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
<Number label="Power (%)" name={`line_settings.${i}.power`} register={register} step="0.1" />
<Number label="Speed (mm/s)" name={`line_settings.${i}.speed`} register={register} step="0.1" />
{/* Pass BEFORE Perforation Mode (requested swap) */}
{/* Pass before perf per your last request */}
<Number label="Pass" name={`line_settings.${i}.pass`} register={register} step="1" />
<div className="col-span-full">
<Check label="Perforation Mode" name={`line_settings.${i}.perf`} register={register} />
</div>
{perf && (
<>
<Number label="Cut (mm)" name={`line_settings.${i}.cut`} register={register} step="0.001" />
@ -493,9 +494,7 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
</>
)}
<div className="col-span-full">
<Check label="Wobble" name={`line_settings.${i}.wobble`} register={register} />
</div>
{wobble && (
<>
<Number label="Step (mm)" name={`line_settings.${i}.step`} register={register} step="0.001" />
@ -503,7 +502,7 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
</>
)}
<div className="col-span-full"><Check label="Air Assist" name={`line_settings.${i}.air`} register={register} /></div>
<Check label="Air Assist" name={`line_settings.${i}.air`} register={register} />
</div>
);
}}
@ -536,11 +535,9 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
<Number label="Interval (mm)" name={`raster_settings.${i}.interval`} register={register} step="0.001" />
<Number label="Dot Width Adjustment (mm)" name={`raster_settings.${i}.dot`} register={register} step="0.1" />
<Number label="Pass" name={`raster_settings.${i}.pass`} register={register} step="1" />
{/* Booleans on their own lines */}
<div className="col-span-full"><Check label="Crosshatch" name={`raster_settings.${i}.cross`} register={register} /></div>
<div className="col-span-full"><Check label="Inverted" name={`raster_settings.${i}.inversion`} register={register} /></div>
<div className="col-span-full"><Check label="Air Assist" name={`raster_settings.${i}.air`} register={register} /></div>
<Check label="Crosshatch" name={`raster_settings.${i}.cross`} register={register} />
<Check label="Inverted" name={`raster_settings.${i}.inversion`} register={register} />
<Check label="Air Assist" name={`raster_settings.${i}.air`} register={register} />
</div>
);
}}
@ -555,7 +552,7 @@ export default function SettingsSubmit({ mode = "create", submissionId, initialV
);
}
/* Small UI (unchanged) */
/* Small UI */
function Select({
label,
name,