ui on new contrat page

This commit is contained in:
Marshal
2026-06-28 23:39:35 +00:00
parent 47c91cad03
commit 947dcbed3d
6 changed files with 647 additions and 134 deletions

View File

@@ -47,6 +47,16 @@ const buildInitialValues = (
values[field.name] = field.noneOption ? FLEET_SELECT_NONE : "";
return;
}
// For selects, snap the record value onto a real option even if its casing
// drifted (e.g. an API/seed value of "Available" vs the "AVAILABLE" option).
// Otherwise the Select renders blank and a required field fails on submit.
if (field.type === "select" && field.options?.length) {
const match = field.options.find(
(o) => String(o.value).toLowerCase() === String(raw).toLowerCase(),
);
values[field.name] = match ? match.value : raw;
return;
}
values[field.name] = raw;
});
return values;
@@ -127,6 +137,15 @@ const FleetFormDialog = ({
return Object.keys(next).length === 0;
};
// Field types keyed by name, so the submit payload can coerce each value to the
// type the API expects (number columns come back from the API as strings like
// "24.00", which the DTO's @IsNumber rejects on an otherwise-unchanged save).
const fieldTypeByName = useMemo(() => {
const map: Record<string, FleetFormFieldDef["type"]> = {};
fields.forEach((f) => (map[f.name] = f.type));
return map;
}, [fields]);
const handleSubmit = () => {
if (!validate()) return;
const payload = Object.fromEntries(
@@ -134,6 +153,10 @@ const FleetFormDialog = ({
.map(([key, value]) => {
if (value === FLEET_SELECT_NONE || value === "")
return [key, undefined];
if (fieldTypeByName[key] === "number") {
const num = Number(value);
return [key, Number.isNaN(num) ? undefined : num];
}
return [key, value];
})
.filter(([, value]) => value !== undefined),

View File

@@ -20,14 +20,11 @@ export const formatFleetCell = (
format?: FleetColumnFormat,
accessorKey?: string,
): ReactNode => {
console.log('formatFleetCell:', { value, format, accessorKey, type: typeof value });
if (format === "statusBadge") {
const status = value == null || value === "" ? "—" : String(value);
const getStatusColor = (st: string): string => {
const s = st.toUpperCase();
console.log('Status for color mapping:', s);
if (s === "ACTIVE") return "green";
if (s === "ACTIVE" || s === "AVAILABLE") return "green";
if (s === "INACTIVE") return "gray";
if (s === "SUSPENDED" || s === "OUT_OF_SERVICE") return "red";
if (s === "MAINTENANCE" || s === "ON_LEAVE") return "orange";
@@ -35,7 +32,6 @@ export const formatFleetCell = (
return "gray";
};
const color = getStatusColor(status);
console.log('Assigned color:', color, 'for status:', status);
return (
<Badge variant="light" color={color} size="sm" radius="md">
{status}
@@ -50,7 +46,5 @@ export const formatFleetCell = (
}
}
const result = formatRuleEngineCell(value, format as ColumnFormat | undefined);
console.log('formatRuleEngineCell result for', accessorKey, ':', result);
return result;
return formatRuleEngineCell(value, format as ColumnFormat | undefined);
};