build error fix
This commit is contained in:
parent
ef7e7cbb24
commit
e03911fd51
1 changed files with 137 additions and 21 deletions
|
|
@ -55,7 +55,7 @@ function shortId(s?: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────
|
||||||
/** Normalizers for edit-mode prefill (IDs + enums) */
|
// Normalizers for edit-mode prefill (IDs + enums)
|
||||||
// ─────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────
|
||||||
function idToString(v: any): string {
|
function idToString(v: any): string {
|
||||||
if (v == null || v === "") return "";
|
if (v == null || v === "") return "";
|
||||||
|
|
@ -139,6 +139,101 @@ function normalizeForReset(iv: EditInitialValues) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────────────────────────
|
||||||
|
// Directus field whitelists + mapper (prevents drift)
|
||||||
|
// ─────────────────────────────────────────────────────────────
|
||||||
|
const DIRECTUS_FIELDS: Record<Target, readonly string[]> = {
|
||||||
|
settings_co2gal: [
|
||||||
|
"setting_title",
|
||||||
|
"setting_notes",
|
||||||
|
"photo",
|
||||||
|
"screen",
|
||||||
|
"mat",
|
||||||
|
"mat_coat",
|
||||||
|
"mat_color",
|
||||||
|
"mat_opacity",
|
||||||
|
"mat_thickness",
|
||||||
|
"source",
|
||||||
|
"lens",
|
||||||
|
"focus",
|
||||||
|
"laser_soft",
|
||||||
|
"repeat_all",
|
||||||
|
"fill_settings",
|
||||||
|
"line_settings",
|
||||||
|
"raster_settings",
|
||||||
|
],
|
||||||
|
settings_co2gan: [
|
||||||
|
"setting_title",
|
||||||
|
"setting_notes",
|
||||||
|
"photo",
|
||||||
|
"screen",
|
||||||
|
"mat",
|
||||||
|
"mat_coat",
|
||||||
|
"mat_color",
|
||||||
|
"mat_opacity",
|
||||||
|
"mat_thickness",
|
||||||
|
"source",
|
||||||
|
"lens",
|
||||||
|
"focus",
|
||||||
|
"laser_soft",
|
||||||
|
"repeat_all",
|
||||||
|
"fill_settings",
|
||||||
|
"line_settings",
|
||||||
|
"raster_settings",
|
||||||
|
],
|
||||||
|
settings_fiber: [
|
||||||
|
"setting_title",
|
||||||
|
"setting_notes",
|
||||||
|
"photo",
|
||||||
|
"screen",
|
||||||
|
"mat",
|
||||||
|
"mat_coat",
|
||||||
|
"mat_color",
|
||||||
|
"mat_opacity",
|
||||||
|
"mat_thickness",
|
||||||
|
"source",
|
||||||
|
"lens",
|
||||||
|
"focus",
|
||||||
|
"laser_soft",
|
||||||
|
"repeat_all",
|
||||||
|
"fill_settings",
|
||||||
|
"line_settings",
|
||||||
|
"raster_settings",
|
||||||
|
],
|
||||||
|
settings_uv: [
|
||||||
|
"setting_title",
|
||||||
|
"setting_notes",
|
||||||
|
"photo",
|
||||||
|
"screen",
|
||||||
|
"mat",
|
||||||
|
"mat_coat",
|
||||||
|
"mat_color",
|
||||||
|
"mat_opacity",
|
||||||
|
"mat_thickness",
|
||||||
|
"source",
|
||||||
|
"lens",
|
||||||
|
"focus",
|
||||||
|
"laser_soft",
|
||||||
|
"repeat_all",
|
||||||
|
"fill_settings",
|
||||||
|
"line_settings",
|
||||||
|
"raster_settings",
|
||||||
|
],
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
function toDirectusData(target: Target, full: any) {
|
||||||
|
const allow = new Set(DIRECTUS_FIELDS[target]);
|
||||||
|
const out: any = {};
|
||||||
|
for (const k of Object.keys(full)) {
|
||||||
|
if (!allow.has(k)) continue;
|
||||||
|
const v = full[k];
|
||||||
|
// Avoid sending empty strings to Directus (common cause of "required" confusion)
|
||||||
|
if (v === "") continue;
|
||||||
|
out[k] = v;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
// ─────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────
|
||||||
// Props (Create vs Edit) + type guard
|
// Props (Create vs Edit) + type guard
|
||||||
// ─────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────
|
||||||
|
|
@ -488,7 +583,7 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
control,
|
control,
|
||||||
reset,
|
reset,
|
||||||
setValue, // used for prefill select syncing
|
setValue,
|
||||||
getValues,
|
getValues,
|
||||||
formState: { isSubmitting },
|
formState: { isSubmitting },
|
||||||
} = useForm<any>({
|
} = useForm<any>({
|
||||||
|
|
@ -541,7 +636,7 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
|
||||||
}
|
}
|
||||||
}, [isEdit, edit?.initialValues, reset]);
|
}, [isEdit, edit?.initialValues, reset]);
|
||||||
|
|
||||||
// After reset, force RHF values once
|
// After reset, force RHF values once (covers early case)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isEdit || !current) return;
|
if (!isEdit || !current) return;
|
||||||
|
|
||||||
|
|
@ -597,6 +692,9 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
|
||||||
}
|
}
|
||||||
const bool = (v: any) => !!v;
|
const bool = (v: any) => !!v;
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────────────────────────
|
||||||
|
// SUBMIT: Build clean Directus payload + include route metadata
|
||||||
|
// ─────────────────────────────────────────────────────────────
|
||||||
async function onSubmit(values: any) {
|
async function onSubmit(values: any) {
|
||||||
setSubmitErr(null);
|
setSubmitErr(null);
|
||||||
|
|
||||||
|
|
@ -611,9 +709,10 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
|
||||||
// map UI target -> backend slug as helper
|
// map UI target -> backend slug as helper
|
||||||
const target_slug = typeForOptions;
|
const target_slug = typeForOptions;
|
||||||
|
|
||||||
const payload: any = {
|
// full UI payload (same shape the form uses)
|
||||||
target, // keep original selector value (e.g. "settings_co2gal")
|
const fullPayload: any = {
|
||||||
target_slug, // slug for server convenience (e.g. "co2-galvo")
|
target,
|
||||||
|
target_slug,
|
||||||
setting_title: values.setting_title,
|
setting_title: values.setting_title,
|
||||||
setting_notes: values.setting_notes || "",
|
setting_notes: values.setting_notes || "",
|
||||||
mat: values.mat || null,
|
mat: values.mat || null,
|
||||||
|
|
@ -676,33 +775,53 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Ensure EDIT gets routed as a PATCH via the API
|
// ✅ Exact Directus data object (whitelisted fields only, empty strings removed)
|
||||||
|
const directusData = toDirectusData(target, fullPayload);
|
||||||
|
|
||||||
|
// Early guard for the common required field
|
||||||
|
if (!directusData.setting_title) {
|
||||||
|
setSubmitErr("Title is required.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edit meta travels outside `data`
|
||||||
|
const meta: any = {};
|
||||||
if (isEdit && edit?.submissionId != null) {
|
if (isEdit && edit?.submissionId != null) {
|
||||||
payload.mode = "edit";
|
meta.mode = "edit";
|
||||||
payload.submission_id = edit.submissionId;
|
meta.submission_id = edit.submissionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let res: Response;
|
let res: Response;
|
||||||
|
|
||||||
if (photoFile || screenFile) {
|
if (photoFile || screenFile) {
|
||||||
|
// multipart: pack everything your route needs under one JSON field
|
||||||
const form = new FormData();
|
const form = new FormData();
|
||||||
// Directus multipart expects JSON in "data"
|
form.set(
|
||||||
form.set("data", JSON.stringify(payload));
|
"data",
|
||||||
// Also include top-level fields for our API route compatibility
|
JSON.stringify({
|
||||||
form.set("target", payload.target);
|
target,
|
||||||
form.set("target_slug", payload.target_slug);
|
target_slug,
|
||||||
|
...meta,
|
||||||
|
data: directusData,
|
||||||
|
})
|
||||||
|
);
|
||||||
if (photoFile) form.set("photo", photoFile, photoFile.name || "photo");
|
if (photoFile) form.set("photo", photoFile, photoFile.name || "photo");
|
||||||
if (screenFile) form.set("screen", screenFile, screenFile.name || "screen");
|
if (screenFile) form.set("screen", screenFile, screenFile.name || "screen");
|
||||||
|
|
||||||
res = await fetch("/api/submit/settings", { method: "POST", body: form, credentials: "include" });
|
res = await fetch("/api/submit/settings", { method: "POST", body: form, credentials: "include" });
|
||||||
} else {
|
} else {
|
||||||
|
// JSON parity with multipart
|
||||||
res = await fetch("/api/submit/settings", {
|
res = await fetch("/api/submit/settings", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
// Directus JSON expects { data: { ... } }
|
body: JSON.stringify({
|
||||||
// Also include top-level fields for our API route compatibility
|
target,
|
||||||
body: JSON.stringify({ data: payload, target: payload.target, target_slug: payload.target_slug }),
|
target_slug,
|
||||||
credentials: "include",
|
...meta,
|
||||||
|
data: directusData,
|
||||||
|
}),
|
||||||
|
credentials: "include",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -714,7 +833,6 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
|
||||||
|
|
||||||
// Success
|
// Success
|
||||||
if (!isEdit) {
|
if (!isEdit) {
|
||||||
// reset only on create
|
|
||||||
reset();
|
reset();
|
||||||
setPhotoFile(null);
|
setPhotoFile(null);
|
||||||
setScreenFile(null);
|
setScreenFile(null);
|
||||||
|
|
@ -723,9 +841,7 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = (data as any)?.id ? String((data as any).id) : String(edit?.submissionId ?? "");
|
const id = (data as any)?.id ? String((data as any).id) : String(edit?.submissionId ?? "");
|
||||||
// back to success (create) or view (edit)
|
|
||||||
if (isEdit) {
|
if (isEdit) {
|
||||||
// remove ?edit=1
|
|
||||||
const q = new URLSearchParams(sp.toString());
|
const q = new URLSearchParams(sp.toString());
|
||||||
q.delete("edit");
|
q.delete("edit");
|
||||||
router.replace(`/portal/laser-settings?${q.toString()}`);
|
router.replace(`/portal/laser-settings?${q.toString()}`);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue