diff --git a/web/public/locales/en/common.json b/web/public/locales/en/common.json index 4a67413f3..87f32a251 100644 --- a/web/public/locales/en/common.json +++ b/web/public/locales/en/common.json @@ -96,7 +96,9 @@ "back": "Go back", "hide": "Hide {{item}}", "show": "Show {{item}}", - "ID": "ID" + "ID": "ID", + "none": "None", + "all": "All" }, "list": { "two": "{{0}} and {{1}}", diff --git a/web/src/components/overlay/CreateTriggerDialog.tsx b/web/src/components/overlay/CreateTriggerDialog.tsx index 41fa61411..11734acaf 100644 --- a/web/src/components/overlay/CreateTriggerDialog.tsx +++ b/web/src/components/overlay/CreateTriggerDialog.tsx @@ -159,7 +159,7 @@ export default function CreateTriggerDialog({ }); const onSubmit = async (values: z.infer) => { - if (trigger) { + if (trigger && existingTriggerNames.includes(trigger.name)) { onEdit({ ...values }); } else { onCreate( diff --git a/web/src/components/overlay/detail/SearchDetailDialog.tsx b/web/src/components/overlay/detail/SearchDetailDialog.tsx index fb979be48..7ff49d4d5 100644 --- a/web/src/components/overlay/detail/SearchDetailDialog.tsx +++ b/web/src/components/overlay/detail/SearchDetailDialog.tsx @@ -34,9 +34,11 @@ import ActivityIndicator from "@/components/indicators/activity-indicator"; import { FaArrowRight, FaCheckCircle, - FaChevronDown, FaChevronLeft, FaChevronRight, + FaMicrophone, + FaCheck, + FaTimes, } from "react-icons/fa"; import { TrackingDetails } from "./TrackingDetails"; import { AnnotationSettingsPane } from "./AnnotationSettingsPane"; @@ -89,6 +91,7 @@ import { CameraNameLabel } from "@/components/camera/FriendlyNameLabel"; import { DialogPortal } from "@radix-ui/react-dialog"; import { useDetailStream } from "@/context/detail-stream-context"; import { PiSlidersHorizontalBold } from "react-icons/pi"; +import { HiSparkles } from "react-icons/hi"; const SEARCH_TABS = ["snapshot", "tracking_details"] as const; export type SearchTab = (typeof SEARCH_TABS)[number]; @@ -348,7 +351,12 @@ function DialogContentComponent({ } /> ) : ( -
+
-
+
+
{snapshotElement}
-
+
-
+
(null); const handleDescriptionFocus = useCallback(() => { setInputFocused(true); @@ -1119,6 +1124,23 @@ function ObjectDetailsTab({ ); const popoverContainerRef = useRef(null); + const canRegenerate = !!( + config?.cameras[search.camera].objects.genai.enabled && search.end_time + ); + const showGenAIPlaceholder = !!( + config?.cameras[search.camera].objects.genai.enabled && + !search.end_time && + (config.cameras[search.camera].objects.genai.required_zones.length === 0 || + search.zones.some((zone) => + config.cameras[search.camera].objects.genai.required_zones.includes( + zone, + ), + )) && + (config.cameras[search.camera].objects.genai.objects.length === 0 || + config.cameras[search.camera].objects.genai.objects.includes( + search.label, + )) + ); return (
@@ -1379,75 +1401,68 @@ function ObjectDetailsTab({
)}
- {config?.cameras[search.camera].objects.genai.enabled && - !search.end_time && - (config.cameras[search.camera].objects.genai.required_zones.length === - 0 || - search.zones.some((zone) => - config.cameras[search.camera].objects.genai.required_zones.includes( - zone, - ), - )) && - (config.cameras[search.camera].objects.genai.objects.length === 0 || - config.cameras[search.camera].objects.genai.objects.includes( - search.label, - )) ? ( - <> -
- {t("details.description.label")} -
-
-
- -
-
{t("details.description.aiTips")}
-
- - ) : ( - <> -
-