From c2952b89c1671bb51f1c6dda0c47423fb2afb609 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Sat, 3 Jan 2026 06:25:34 -0700 Subject: [PATCH] Add ability to select case in export dialog --- web/public/locales/en/components/dialog.json | 4 ++ web/src/components/overlay/ExportDialog.tsx | 63 +++++++++++++++++++- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/web/public/locales/en/components/dialog.json b/web/public/locales/en/components/dialog.json index a56c2b1da..907a61add 100644 --- a/web/public/locales/en/components/dialog.json +++ b/web/public/locales/en/components/dialog.json @@ -48,6 +48,10 @@ "name": { "placeholder": "Name the Export" }, + "case": { + "label": "Case", + "placeholder": "Select a case" + }, "select": "Select", "export": "Export", "selectOrExport": "Select or Export", diff --git a/web/src/components/overlay/ExportDialog.tsx b/web/src/components/overlay/ExportDialog.tsx index 976b20042..5d68d88db 100644 --- a/web/src/components/overlay/ExportDialog.tsx +++ b/web/src/components/overlay/ExportDialog.tsx @@ -22,7 +22,14 @@ import useSWR from "swr"; import { FrigateConfig } from "@/types/frigateConfig"; import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover"; import { TimezoneAwareCalendar } from "./ReviewActivityCalendar"; -import { SelectSeparator } from "../ui/select"; +import { + Select, + SelectContent, + SelectItem, + SelectSeparator, + SelectTrigger, + SelectValue, +} from "../ui/select"; import { isDesktop, isIOS, isMobile } from "react-device-detect"; import { Drawer, DrawerContent, DrawerTrigger } from "../ui/drawer"; import SaveExportOverlay from "./SaveExportOverlay"; @@ -31,6 +38,7 @@ import { baseUrl } from "@/api/baseUrl"; import { cn } from "@/lib/utils"; import { GenericVideoPlayer } from "../player/GenericVideoPlayer"; import { useTranslation } from "react-i18next"; +import { ExportCase } from "@/types/export"; const EXPORT_OPTIONS = [ "1", @@ -67,6 +75,9 @@ export default function ExportDialog({ }: ExportDialogProps) { const { t } = useTranslation(["components/dialog"]); const [name, setName] = useState(""); + const [selectedCaseId, setSelectedCaseId] = useState( + undefined, + ); const onStartExport = useCallback(() => { if (!range) { @@ -89,6 +100,7 @@ export default function ExportDialog({ { playback: "realtime", name, + export_case_id: selectedCaseId || undefined, }, ) .then((response) => { @@ -102,6 +114,7 @@ export default function ExportDialog({ ), }); setName(""); + setSelectedCaseId(undefined); setRange(undefined); setMode("none"); } @@ -118,10 +131,11 @@ export default function ExportDialog({ { position: "top-center" }, ); }); - }, [camera, name, range, setRange, setName, setMode, t]); + }, [camera, name, range, selectedCaseId, setRange, setName, setMode, t]); const handleCancel = useCallback(() => { setName(""); + setSelectedCaseId(undefined); setMode("none"); setRange(undefined); }, [setMode, setRange]); @@ -190,8 +204,10 @@ export default function ExportDialog({ currentTime={currentTime} range={range} name={name} + selectedCaseId={selectedCaseId} onStartExport={onStartExport} setName={setName} + setSelectedCaseId={setSelectedCaseId} setRange={setRange} setMode={setMode} onCancel={handleCancel} @@ -207,8 +223,10 @@ type ExportContentProps = { currentTime: number; range?: TimeRange; name: string; + selectedCaseId?: string; onStartExport: () => void; setName: (name: string) => void; + setSelectedCaseId: (caseId: string | undefined) => void; setRange: (range: TimeRange | undefined) => void; setMode: (mode: ExportMode) => void; onCancel: () => void; @@ -218,14 +236,17 @@ export function ExportContent({ currentTime, range, name, + selectedCaseId, onStartExport, setName, + setSelectedCaseId, setRange, setMode, onCancel, }: ExportContentProps) { const { t } = useTranslation(["components/dialog"]); const [selectedOption, setSelectedOption] = useState("1"); + const { data: cases } = useSWR("cases"); const onSelectTime = useCallback( (option: ExportOption) => { @@ -320,6 +341,44 @@ export function ExportContent({ value={name} onChange={(e) => setName(e.target.value)} /> +
+ + +
{isDesktop && }