mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-07-15 00:11:15 +03:00
require all masks and zones to be on the base config
This commit is contained in:
parent
a7761225bc
commit
b116f61055
@ -539,6 +539,7 @@
|
|||||||
},
|
},
|
||||||
"restart_required": "Restart required (masks/zones changed)",
|
"restart_required": "Restart required (masks/zones changed)",
|
||||||
"disabledInConfig": "Item is disabled in the config file",
|
"disabledInConfig": "Item is disabled in the config file",
|
||||||
|
"addDisabledProfile": "Add to the base config first, then override in the profile",
|
||||||
"profileBase": "(base)",
|
"profileBase": "(base)",
|
||||||
"profileOverride": "(override)",
|
"profileOverride": "(override)",
|
||||||
"toast": {
|
"toast": {
|
||||||
|
|||||||
@ -154,7 +154,19 @@ export default function PolygonItem({
|
|||||||
cameraConfig?.review.alerts.required_zones || [],
|
cameraConfig?.review.alerts.required_zones || [],
|
||||||
cameraConfig?.review.detections.required_zones || [],
|
cameraConfig?.review.detections.required_zones || [],
|
||||||
);
|
);
|
||||||
url = `cameras.${polygon.camera}.zones.${polygon.name}${alertQueries}${detectionQueries}`;
|
// Also delete from profiles that have overrides for this zone
|
||||||
|
let profileQueries = "";
|
||||||
|
if (allProfileNames && cameraConfig) {
|
||||||
|
for (const profileName of allProfileNames) {
|
||||||
|
if (
|
||||||
|
cameraConfig.profiles?.[profileName]?.zones?.[polygon.name] !==
|
||||||
|
undefined
|
||||||
|
) {
|
||||||
|
profileQueries += `&cameras.${polygon.camera}.profiles.${profileName}.zones.${polygon.name}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
url = `cameras.${polygon.camera}.zones.${polygon.name}${alertQueries}${detectionQueries}${profileQueries}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
await axios
|
await axios
|
||||||
@ -214,11 +226,41 @@ export default function PolygonItem({
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let cameraUpdate: Record<string, unknown>;
|
||||||
|
if (editingProfile) {
|
||||||
|
cameraUpdate = { profiles: { [editingProfile]: deleteSection } };
|
||||||
|
} else {
|
||||||
|
// Base mode: also delete from profiles that have overrides for this mask
|
||||||
|
const profileDeletes: Record<string, unknown> = {};
|
||||||
|
if (allProfileNames && cameraConfig) {
|
||||||
|
for (const profileName of allProfileNames) {
|
||||||
|
const profileData = cameraConfig.profiles?.[profileName];
|
||||||
|
if (!profileData) continue;
|
||||||
|
|
||||||
|
const hasMask =
|
||||||
|
polygon.type === "motion_mask"
|
||||||
|
? profileData.motion?.mask?.[polygon.name] !== undefined
|
||||||
|
: polygon.type === "object_mask"
|
||||||
|
? profileData.objects?.mask?.[polygon.name] !== undefined ||
|
||||||
|
Object.values(profileData.objects?.filters || {}).some(
|
||||||
|
(f) => f?.mask?.[polygon.name] !== undefined,
|
||||||
|
)
|
||||||
|
: false;
|
||||||
|
|
||||||
|
if (hasMask) {
|
||||||
|
profileDeletes[profileName] = deleteSection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cameraUpdate =
|
||||||
|
Object.keys(profileDeletes).length > 0
|
||||||
|
? { ...deleteSection, profiles: profileDeletes }
|
||||||
|
: deleteSection;
|
||||||
|
}
|
||||||
|
|
||||||
const configUpdate = {
|
const configUpdate = {
|
||||||
cameras: {
|
cameras: {
|
||||||
[polygon.camera]: editingProfile
|
[polygon.camera]: cameraUpdate,
|
||||||
? { profiles: { [editingProfile]: deleteSection } }
|
|
||||||
: deleteSection,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -271,6 +313,7 @@ export default function PolygonItem({
|
|||||||
index,
|
index,
|
||||||
setLoadingPolygonIndex,
|
setLoadingPolygonIndex,
|
||||||
editingProfile,
|
editingProfile,
|
||||||
|
allProfileNames,
|
||||||
onDeleted,
|
onDeleted,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -430,10 +473,28 @@ export default function PolygonItem({
|
|||||||
<AlertDialogContent>
|
<AlertDialogContent>
|
||||||
<AlertDialogHeader>
|
<AlertDialogHeader>
|
||||||
<AlertDialogTitle>
|
<AlertDialogTitle>
|
||||||
{t("masksAndZones.form.polygonDrawing.delete.title")}
|
{polygon.polygonSource === "override"
|
||||||
|
? t(
|
||||||
|
"masksAndZones.form.polygonDrawing.revertOverride.title",
|
||||||
|
)
|
||||||
|
: t("masksAndZones.form.polygonDrawing.delete.title")}
|
||||||
</AlertDialogTitle>
|
</AlertDialogTitle>
|
||||||
</AlertDialogHeader>
|
</AlertDialogHeader>
|
||||||
<AlertDialogDescription>
|
<AlertDialogDescription>
|
||||||
|
{polygon.polygonSource === "override" ? (
|
||||||
|
<Trans
|
||||||
|
ns="views/settings"
|
||||||
|
values={{
|
||||||
|
type: t(
|
||||||
|
`masksAndZones.form.polygonDrawing.type.${polygon.type}`,
|
||||||
|
{ ns: "views/settings" },
|
||||||
|
),
|
||||||
|
name: polygon.friendly_name ?? polygon.name,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
masksAndZones.form.polygonDrawing.revertOverride.desc
|
||||||
|
</Trans>
|
||||||
|
) : (
|
||||||
<Trans
|
<Trans
|
||||||
ns="views/settings"
|
ns="views/settings"
|
||||||
values={{
|
values={{
|
||||||
@ -446,6 +507,7 @@ export default function PolygonItem({
|
|||||||
>
|
>
|
||||||
masksAndZones.form.polygonDrawing.delete.desc
|
masksAndZones.form.polygonDrawing.delete.desc
|
||||||
</Trans>
|
</Trans>
|
||||||
|
)}
|
||||||
</AlertDialogDescription>
|
</AlertDialogDescription>
|
||||||
<AlertDialogFooter>
|
<AlertDialogFooter>
|
||||||
<AlertDialogCancel>
|
<AlertDialogCancel>
|
||||||
|
|||||||
@ -816,10 +816,12 @@ export default function MasksAndZonesView({
|
|||||||
</HoverCard>
|
</HoverCard>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
|
<span className="inline-flex">
|
||||||
<Button
|
<Button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
className="size-6 rounded-md bg-secondary-foreground p-1 text-background"
|
className="size-6 rounded-md bg-secondary-foreground p-1 text-background"
|
||||||
aria-label={t("masksAndZones.zones.add")}
|
aria-label={t("masksAndZones.zones.add")}
|
||||||
|
disabled={!!currentEditingProfile}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setEditPane("zone");
|
setEditPane("zone");
|
||||||
handleNewPolygon("zone");
|
handleNewPolygon("zone");
|
||||||
@ -827,9 +829,12 @@ export default function MasksAndZonesView({
|
|||||||
>
|
>
|
||||||
<LuPlus />
|
<LuPlus />
|
||||||
</Button>
|
</Button>
|
||||||
|
</span>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
{t("masksAndZones.zones.add")}
|
{currentEditingProfile
|
||||||
|
? t("masksAndZones.addDisabledProfile")
|
||||||
|
: t("masksAndZones.zones.add")}
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
@ -891,10 +896,12 @@ export default function MasksAndZonesView({
|
|||||||
</HoverCard>
|
</HoverCard>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
|
<span className="inline-flex">
|
||||||
<Button
|
<Button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
className="size-6 rounded-md bg-secondary-foreground p-1 text-background"
|
className="size-6 rounded-md bg-secondary-foreground p-1 text-background"
|
||||||
aria-label={t("masksAndZones.motionMasks.add")}
|
aria-label={t("masksAndZones.motionMasks.add")}
|
||||||
|
disabled={!!currentEditingProfile}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setEditPane("motion_mask");
|
setEditPane("motion_mask");
|
||||||
handleNewPolygon("motion_mask");
|
handleNewPolygon("motion_mask");
|
||||||
@ -902,9 +909,12 @@ export default function MasksAndZonesView({
|
|||||||
>
|
>
|
||||||
<LuPlus />
|
<LuPlus />
|
||||||
</Button>
|
</Button>
|
||||||
|
</span>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
{t("masksAndZones.motionMasks.add")}
|
{currentEditingProfile
|
||||||
|
? t("masksAndZones.addDisabledProfile")
|
||||||
|
: t("masksAndZones.motionMasks.add")}
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
@ -968,10 +978,12 @@ export default function MasksAndZonesView({
|
|||||||
</HoverCard>
|
</HoverCard>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
|
<span className="inline-flex">
|
||||||
<Button
|
<Button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
className="size-6 rounded-md bg-secondary-foreground p-1 text-background"
|
className="size-6 rounded-md bg-secondary-foreground p-1 text-background"
|
||||||
aria-label={t("masksAndZones.objectMasks.add")}
|
aria-label={t("masksAndZones.objectMasks.add")}
|
||||||
|
disabled={!!currentEditingProfile}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setEditPane("object_mask");
|
setEditPane("object_mask");
|
||||||
handleNewPolygon("object_mask");
|
handleNewPolygon("object_mask");
|
||||||
@ -979,9 +991,12 @@ export default function MasksAndZonesView({
|
|||||||
>
|
>
|
||||||
<LuPlus />
|
<LuPlus />
|
||||||
</Button>
|
</Button>
|
||||||
|
</span>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
{t("masksAndZones.objectMasks.add")}
|
{currentEditingProfile
|
||||||
|
? t("masksAndZones.addDisabledProfile")
|
||||||
|
: t("masksAndZones.objectMasks.add")}
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user