diff --git a/app/components/forms/SettingsSubmit.tsx b/app/components/forms/SettingsSubmit.tsx index db58f741..468b82f2 100644 --- a/app/components/forms/SettingsSubmit.tsx +++ b/app/components/forms/SettingsSubmit.tsx @@ -86,34 +86,48 @@ function useOptions(path: string) { })); }; } else if (rawPath === "lens") { - // Switch collections by target: CO2 Gantry uses laser_focus_lens, others use laser_scan_lens + // CO2 gantry uses focus lenses; all others use scan lenses if (target === "co2-gantry") { - url = `${API}/items/laser_focus_lens?fields=id,name&limit=1000&sort=name`; + url = `${API}/items/laser_focus_lens?fields=id,name&limit=1000`; normalize = (rows) => rows.map((r) => ({ id: String(r.id), label: String(r.name ?? r.id) })); } else { - // SCAN LENSES (fiber, uv, co2-galvo): no `name` field in this collection - url = `${API}/items/laser_scan_lens?fields=id,field_size,focal_length&limit=1000&sort=focal_length`; - normalize = (rows) => - rows.map((r) => { - const fs = r.field_size != null ? `${r.field_size}` : ""; - const fl = r.focal_length != null ? `${r.focal_length}` : ""; - const composed = [fs && `${fs} mm`, fl && `${fl} mm`].filter(Boolean).join(" — "); - return { id: String(r.id), label: composed || String(r.id) }; - }); + url = `${API}/items/laser_scan_lens?fields=id,field_size,focal_length&limit=1000`; + normalize = (rows) => { + const toNum = (v: any) => { + const m = String(v ?? "").match(/-?\d+(\.\d+)?/); + return m ? parseFloat(m[0]) : Number.POSITIVE_INFINITY; + }; + const sorted = [...rows].sort((a, b) => toNum(a.focal_length) - toNum(b.focal_length)); + return sorted.map((r) => { + const fs = r.field_size != null ? `${r.field_size}` : ""; + const fl = r.focal_length != null ? `${r.focal_length}` : ""; + const composed = [fs && `${fs} mm`, fl && `${fl} mm`].filter(Boolean).join(" — "); + return { id: String(r.id), label: composed || String(r.id) }; + }); + }; } + } } else if (rawPath === "repeater-choices") { - // reads from fields meta: target=, group=, field= + // target=, group=, field= const group = params.get("group") || ""; const field = params.get("field") || ""; + const fieldsUrl = `${API}/fields/${encodeURIComponent(target)}?fields=collection,field,meta`; const metaRes = await fetch(fieldsUrl, { cache: "no-store", credentials: "include" }); if (!metaRes.ok) throw new Error(`Directus ${metaRes.status} fetching ${fieldsUrl}`); const metaJson = await metaRes.json(); const rows = metaJson?.data ?? []; - const fullField = `${group}.${field}`; - const def = rows.find((r: any) => r?.field === fullField); - const choices: any[] = def?.meta?.options?.choices || []; + + // find the repeater parent (e.g. "fill_settings" or "raster_settings") + const parent = rows.find((r: any) => r?.field === group); + const children = parent?.meta?.options?.fields || []; // Directus stores repeater children here + + // find the child definition (e.g. "type", "dither") + const child = children.find((f: any) => f?.field === field); + + // pull choices off the child's interface meta + const choices: any[] = child?.meta?.options?.choices || []; const mapped: Opt[] = choices.map((c: any) => ({ id: String(c.value ?? c.key ?? c.id), label: String(c.text ?? c.label ?? c.name ?? c.value), @@ -126,11 +140,6 @@ function useOptions(path: string) { setLoading(false); } return; - } else { - // unknown path → empty - setOpts([]); - setLoading(false); - return; } const res = await fetch(url, { cache: "no-store", credentials: "include" });