From 10686e5e07b05dbb4ea06ff4704590a4eaf4d0c7 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Mon, 13 Jul 2026 21:59:15 -0500 Subject: [PATCH] delete references to required_zones when a zone is deleted cover all cases in review alerts/detections, genai, snapshots, mqtt autotracking will fail backend validation if the user tries to delete the required zone, so they will just need to reassign the zone before deleting --- web/src/components/settings/PolygonItem.tsx | 28 +++++++++++++++++-- web/src/utils/zoneEdutUtil.ts | 30 +++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/web/src/components/settings/PolygonItem.tsx b/web/src/components/settings/PolygonItem.tsx index ffd85eaec6..2ba196f0be 100644 --- a/web/src/components/settings/PolygonItem.tsx +++ b/web/src/components/settings/PolygonItem.tsx @@ -27,7 +27,7 @@ import axios from "axios"; import { toast } from "sonner"; import useSWR from "swr"; import { FrigateConfig } from "@/types/frigateConfig"; -import { reviewQueries } from "@/utils/zoneEdutUtil"; +import { removeRequiredZoneQuery, reviewQueries } from "@/utils/zoneEdutUtil"; import IconWrapper from "../ui/icon-wrapper"; import { buttonVariants } from "@/components/ui/button"; import { Trans, useTranslation } from "react-i18next"; @@ -153,6 +153,30 @@ export default function PolygonItem({ cameraConfig?.review.alerts.required_zones || [], cameraConfig?.review.detections.required_zones || [], ); + const genaiQueries = removeRequiredZoneQuery( + polygon.name, + polygon.camera, + "objects.genai", + cameraConfig?.objects.genai.required_zones || [], + ); + const snapshotQueries = removeRequiredZoneQuery( + polygon.name, + polygon.camera, + "snapshots", + cameraConfig?.snapshots.required_zones || [], + ); + const mqttQueries = removeRequiredZoneQuery( + polygon.name, + polygon.camera, + "mqtt", + cameraConfig?.mqtt.required_zones || [], + ); + const autotrackQueries = removeRequiredZoneQuery( + polygon.name, + polygon.camera, + "onvif.autotracking", + cameraConfig?.onvif.autotracking.required_zones || [], + ); // Also delete from profiles that have overrides for this zone let profileQueries = ""; if (allProfileNames && cameraConfig) { @@ -165,7 +189,7 @@ export default function PolygonItem({ } } } - url = `cameras.${polygon.camera}.zones.${polygon.name}${alertQueries}${detectionQueries}${profileQueries}`; + url = `cameras.${polygon.camera}.zones.${polygon.name}${alertQueries}${detectionQueries}${genaiQueries}${snapshotQueries}${mqttQueries}${autotrackQueries}${profileQueries}`; } await axios diff --git a/web/src/utils/zoneEdutUtil.ts b/web/src/utils/zoneEdutUtil.ts index ce5ed3d962..7107003e83 100644 --- a/web/src/utils/zoneEdutUtil.ts +++ b/web/src/utils/zoneEdutUtil.ts @@ -1,3 +1,33 @@ +// Build a config/set query fragment that removes `name` from a +// required_zones list on the given camera section (e.g. "snapshots", +// "mqtt", "objects.genai", "onvif.autotracking"), rebuilding the +// remaining entries. When removing the name empties the list, the +// required_zones key itself is deleted so the field reverts to its +// default instead of retaining the now-stale zone name. Returns an empty +// string when `name` is not present so unrelated sections are untouched. +export const removeRequiredZoneQuery = ( + name: string, + camera: string, + section: string, + zones: string[], +) => { + const remaining = new Set(zones || []); + + if (!remaining.has(name)) { + return ""; + } + + remaining.delete(name); + + const key = `cameras.${camera}.${section}.required_zones`; + + if (remaining.size === 0) { + return `&${key}`; + } + + return [...remaining].map((zone) => `&${key}=${zone}`).join(""); +}; + export const reviewQueries = ( name: string, review_alerts: boolean,