rename vars and add validation

This commit is contained in:
Josh Hawkins 2024-12-08 12:27:12 -06:00
parent 2fac0dd1ad
commit 1ced240956
2 changed files with 120 additions and 108 deletions

View File

@ -82,7 +82,7 @@ export default function ZoneEditPane({
} }
}, [polygon, config]); }, [polygon, config]);
const [topWidth, bottomWidth, leftDepth, rightDepth] = useMemo(() => { const [lineA, lineB, lineC, lineD] = useMemo(() => {
const distances = const distances =
polygon?.camera && polygon?.camera &&
polygon?.name && polygon?.name &&
@ -93,94 +93,107 @@ export default function ZoneEditPane({
: [0, 0, 0, 0]; : [0, 0, 0, 0];
}, [polygon, config]); }, [polygon, config]);
const formSchema = z.object({ const formSchema = z
name: z .object({
.string() name: z
.min(2, { .string()
message: "Zone name must be at least 2 characters.", .min(2, {
}) message: "Zone name must be at least 2 characters.",
.transform((val: string) => val.trim().replace(/\s+/g, "_")) })
.refine( .transform((val: string) => val.trim().replace(/\s+/g, "_"))
(value: string) => { .refine(
return !cameras.map((cam) => cam.name).includes(value); (value: string) => {
}, return !cameras.map((cam) => cam.name).includes(value);
{ },
message: "Zone name must not be the name of a camera.", {
}, message: "Zone name must not be the name of a camera.",
) },
.refine( )
(value: string) => { .refine(
const otherPolygonNames = (value: string) => {
polygons const otherPolygonNames =
?.filter((_, index) => index !== activePolygonIndex) polygons
.map((polygon) => polygon.name) || []; ?.filter((_, index) => index !== activePolygonIndex)
.map((polygon) => polygon.name) || [];
return !otherPolygonNames.includes(value); return !otherPolygonNames.includes(value);
}, },
{ {
message: "Zone name already exists on this camera.", message: "Zone name already exists on this camera.",
}, },
) )
.refine( .refine(
(value: string) => { (value: string) => {
return !value.includes("."); return !value.includes(".");
}, },
{ {
message: "Zone name must not contain a period.", message: "Zone name must not contain a period.",
}, },
) )
.refine((value: string) => /^[a-zA-Z0-9_-]+$/.test(value), { .refine((value: string) => /^[a-zA-Z0-9_-]+$/.test(value), {
message: "Zone name has an illegal character.", message: "Zone name has an illegal character.",
}),
inertia: z.coerce
.number()
.min(1, {
message: "Inertia must be above 0.",
})
.or(z.literal("")),
loitering_time: z.coerce
.number()
.min(0, {
message: "Loitering time must be greater than or equal to 0.",
})
.optional()
.or(z.literal("")),
isFinished: z.boolean().refine(() => polygon?.isFinished === true, {
message: "The polygon drawing must be finished before saving.",
}), }),
inertia: z.coerce objects: z.array(z.string()).optional(),
.number() review_alerts: z.boolean().default(false).optional(),
.min(1, { review_detections: z.boolean().default(false).optional(),
message: "Inertia must be above 0.", speedEstimation: z.boolean().default(false),
}) lineA: z.coerce
.or(z.literal("")), .number()
loitering_time: z.coerce .min(0.1, {
.number() message: "Distance must be greater than or equal to 0.1",
.min(0, { })
message: "Loitering time must be greater than or equal to 0.", .optional()
}) .or(z.literal("")),
.optional() lineB: z.coerce
.or(z.literal("")), .number()
isFinished: z.boolean().refine(() => polygon?.isFinished === true, { .min(0.1, {
message: "The polygon drawing must be finished before saving.", message: "Distance must be greater than or equal to 0.1",
}), })
objects: z.array(z.string()).optional(), .optional()
review_alerts: z.boolean().default(false).optional(), .or(z.literal("")),
review_detections: z.boolean().default(false).optional(), lineC: z.coerce
speedEstimation: z.boolean().default(false), .number()
topWidth: z.coerce .min(0.1, {
.number() message: "Distance must be greater than or equal to 0.1",
.min(0.1, { })
message: "Distance must be greater than or equal to 0.1", .optional()
}) .or(z.literal("")),
.optional() lineD: z.coerce
.or(z.literal("")), .number()
bottomWidth: z.coerce .min(0.1, {
.number() message: "Distance must be greater than or equal to 0.1",
.min(0.1, { })
message: "Distance must be greater than or equal to 0.1", .optional()
}) .or(z.literal("")),
.optional() })
.or(z.literal("")), .refine(
leftDepth: z.coerce (data) => {
.number() if (data.speedEstimation) {
.min(0.1, { return !!data.lineA && !!data.lineB && !!data.lineC && !!data.lineD;
message: "Distance must be greater than or equal to 0.1", }
}) return true;
.optional() },
.or(z.literal("")), {
rightDepth: z.coerce message: "All distance fields must be filled to use speed estimation.",
.number() path: ["speedEstimation"],
.min(0.1, { },
message: "Distance must be greater than or equal to 0.1", );
})
.optional()
.or(z.literal("")),
});
const form = useForm<z.infer<typeof formSchema>>({ const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema), resolver: zodResolver(formSchema),
@ -197,11 +210,11 @@ export default function ZoneEditPane({
config?.cameras[polygon.camera]?.zones[polygon.name]?.loitering_time, config?.cameras[polygon.camera]?.zones[polygon.name]?.loitering_time,
isFinished: polygon?.isFinished ?? false, isFinished: polygon?.isFinished ?? false,
objects: polygon?.objects ?? [], objects: polygon?.objects ?? [],
speedEstimation: !!(topWidth || bottomWidth || leftDepth || rightDepth), speedEstimation: !!(lineA || lineB || lineC || lineD),
topWidth, lineA,
bottomWidth, lineB,
leftDepth, lineC,
rightDepth, lineD,
}, },
}); });
@ -213,10 +226,10 @@ export default function ZoneEditPane({
loitering_time, loitering_time,
objects: form_objects, objects: form_objects,
speedEstimation, speedEstimation,
topWidth, lineA,
bottomWidth, lineB,
leftDepth, lineC,
rightDepth, lineD,
}: ZoneFormValuesType, // values submitted via the form }: ZoneFormValuesType, // values submitted via the form
objects: string[], objects: string[],
) => { ) => {
@ -314,9 +327,7 @@ export default function ZoneEditPane({
} }
let distancesQuery = ""; let distancesQuery = "";
const distances = [topWidth, bottomWidth, leftDepth, rightDepth].join( const distances = [lineA, lineB, lineC, lineD].join(",");
",",
);
if (speedEstimation) { if (speedEstimation) {
distancesQuery = `&cameras.${polygon?.camera}.zones.${zoneName}.distances=${distances}`; distancesQuery = `&cameras.${polygon?.camera}.zones.${zoneName}.distances=${distances}`;
} else { } else {
@ -543,7 +554,7 @@ export default function ZoneEditPane({
polygons[activePolygonIndex].points.length !== 4 polygons[activePolygonIndex].points.length !== 4
) { ) {
toast.error( toast.error(
"Zones with speed estimation must have exactly 4 points", "Zones with speed estimation must have exactly 4 points.",
); );
return; return;
} }
@ -557,6 +568,7 @@ export default function ZoneEditPane({
Enable speed estimation for objects in this zone. The zone Enable speed estimation for objects in this zone. The zone
must have exactly 4 points. must have exactly 4 points.
</FormDescription> </FormDescription>
<FormMessage />
</FormItem> </FormItem>
)} )}
/> />
@ -568,7 +580,7 @@ export default function ZoneEditPane({
<> <>
<FormField <FormField
control={form.control} control={form.control}
name="topWidth" name="lineA"
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>Line A distance</FormLabel> <FormLabel>Line A distance</FormLabel>
@ -584,7 +596,7 @@ export default function ZoneEditPane({
/> />
<FormField <FormField
control={form.control} control={form.control}
name="bottomWidth" name="lineB"
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>Line B distance</FormLabel> <FormLabel>Line B distance</FormLabel>
@ -600,7 +612,7 @@ export default function ZoneEditPane({
/> />
<FormField <FormField
control={form.control} control={form.control}
name="leftDepth" name="lineC"
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>Line C distance</FormLabel> <FormLabel>Line C distance</FormLabel>
@ -616,7 +628,7 @@ export default function ZoneEditPane({
/> />
<FormField <FormField
control={form.control} control={form.control}
name="rightDepth" name="lineD"
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<FormLabel>Line D distance</FormLabel> <FormLabel>Line D distance</FormLabel>

View File

@ -20,10 +20,10 @@ export type ZoneFormValuesType = {
isFinished: boolean; isFinished: boolean;
objects: string[]; objects: string[];
speedEstimation: boolean; speedEstimation: boolean;
topWidth: number; lineA: number;
bottomWidth: number; lineB: number;
leftDepth: number; lineC: number;
rightDepth: number; lineD: number;
}; };
export type ObjectMaskFormValuesType = { export type ObjectMaskFormValuesType = {