Add ability to select case in export dialog

This commit is contained in:
Nicolas Mowen 2026-01-03 06:25:34 -07:00
parent a10ea1f28e
commit c2952b89c1
2 changed files with 65 additions and 2 deletions

View File

@ -48,6 +48,10 @@
"name": {
"placeholder": "Name the Export"
},
"case": {
"label": "Case",
"placeholder": "Select a case"
},
"select": "Select",
"export": "Export",
"selectOrExport": "Select or Export",

View File

@ -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<string | undefined>(
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<ExportOption>("1");
const { data: cases } = useSWR<ExportCase[]>("cases");
const onSelectTime = useCallback(
(option: ExportOption) => {
@ -320,6 +341,44 @@ export function ExportContent({
value={name}
onChange={(e) => setName(e.target.value)}
/>
<div className="my-4">
<Label className="text-sm text-secondary-foreground">
{t("export.case.label", { defaultValue: "Case (optional)" })}
</Label>
<Select
value={selectedCaseId || "none"}
onValueChange={(value) =>
setSelectedCaseId(value === "none" ? undefined : value)
}
>
<SelectTrigger className="mt-2">
<SelectValue
placeholder={t("export.case.placeholder", {
defaultValue: "Select a case (optional)",
})}
/>
</SelectTrigger>
<SelectContent>
<SelectItem
value="none"
className="cursor-pointer hover:bg-accent hover:text-accent-foreground"
>
{t("label.none", { ns: "common" })}
</SelectItem>
{cases
?.sort((a, b) => a.name.localeCompare(b.name))
.map((caseItem) => (
<SelectItem
key={caseItem.id}
value={caseItem.id}
className="cursor-pointer hover:bg-accent hover:text-accent-foreground"
>
{caseItem.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{isDesktop && <SelectSeparator className="my-4 bg-secondary" />}
<DialogFooter
className={isDesktop ? "" : "mt-3 flex flex-col-reverse gap-4"}