Add cameras page to more filters

This commit is contained in:
Nicolas Mowen 2024-10-15 15:55:05 -06:00
parent e11f4b8940
commit 9bce6efddc
4 changed files with 171 additions and 99 deletions

View File

@ -69,6 +69,70 @@ export function CamerasFilterButton({
</Button> </Button>
); );
const content = ( const content = (
<CamerasFilterContent
allCameras={allCameras}
groups={groups}
currentCameras={currentCameras}
setCurrentCameras={setCurrentCameras}
setOpen={setOpen}
updateCameraFilter={updateCameraFilter}
/>
);
if (isMobile) {
return (
<Drawer
open={open}
onOpenChange={(open) => {
if (!open) {
setCurrentCameras(selectedCameras);
}
setOpen(open);
}}
>
<DrawerTrigger asChild>{trigger}</DrawerTrigger>
<DrawerContent className="max-h-[75dvh] overflow-hidden">
{content}
</DrawerContent>
</Drawer>
);
}
return (
<DropdownMenu
modal={false}
open={open}
onOpenChange={(open) => {
if (!open) {
setCurrentCameras(selectedCameras);
}
setOpen(open);
}}
>
<DropdownMenuTrigger asChild>{trigger}</DropdownMenuTrigger>
<DropdownMenuContent>{content}</DropdownMenuContent>
</DropdownMenu>
);
}
type CamerasFilterContentProps = {
allCameras: string[];
currentCameras: string[] | undefined;
groups: [string, CameraGroupConfig][];
setCurrentCameras: (cameras: string[] | undefined) => void;
setOpen: (open: boolean) => void;
updateCameraFilter: (cameras: string[] | undefined) => void;
};
export function CamerasFilterContent({
allCameras,
currentCameras,
groups,
setCurrentCameras,
setOpen,
updateCameraFilter,
}: CamerasFilterContentProps) {
return (
<> <>
{isMobile && ( {isMobile && (
<> <>
@ -158,40 +222,4 @@ export function CamerasFilterButton({
</div> </div>
</> </>
); );
if (isMobile) {
return (
<Drawer
open={open}
onOpenChange={(open) => {
if (!open) {
setCurrentCameras(selectedCameras);
}
setOpen(open);
}}
>
<DrawerTrigger asChild>{trigger}</DrawerTrigger>
<DrawerContent className="max-h-[75dvh] overflow-hidden">
{content}
</DrawerContent>
</Drawer>
);
}
return (
<DropdownMenu
modal={false}
open={open}
onOpenChange={(open) => {
if (!open) {
setCurrentCameras(selectedCameras);
}
setOpen(open);
}}
>
<DropdownMenuTrigger asChild>{trigger}</DropdownMenuTrigger>
<DropdownMenuContent>{content}</DropdownMenuContent>
</DropdownMenu>
);
} }

View File

@ -10,7 +10,6 @@ import { Switch } from "../ui/switch";
import { Label } from "../ui/label"; import { Label } from "../ui/label";
import FilterSwitch from "./FilterSwitch"; import FilterSwitch from "./FilterSwitch";
import { FilterList } from "@/types/filter"; import { FilterList } from "@/types/filter";
import { CalendarRangeFilterButton } from "./CalendarFilterButton";
import { CamerasFilterButton } from "./CamerasFilterButton"; import { CamerasFilterButton } from "./CamerasFilterButton";
import { import {
DEFAULT_SEARCH_FILTERS, DEFAULT_SEARCH_FILTERS,
@ -80,8 +79,6 @@ export default function SearchFilterGroup({
return [...labels].sort(); return [...labels].sort();
}, [config, filterList, filter]); }, [config, filterList, filter]);
const { data: allSubLabels } = useSWR(["sub_labels", { split_joined: 1 }]);
const allZones = useMemo<string[]>(() => { const allZones = useMemo<string[]>(() => {
if (filterList?.zones) { if (filterList?.zones) {
return filterList.zones; return filterList.zones;
@ -169,60 +166,12 @@ export default function SearchFilterGroup({
}} }}
/> />
)} )}
<SearchFilterDialog /> <SearchFilterDialog
{filters.includes("date") && ( filter={filter}
<CalendarRangeFilterButton filterValues={filterValues}
range={ groups={groups}
filter?.after == undefined || filter?.before == undefined onUpdateFilter={onUpdateFilter}
? undefined />
: {
from: new Date(filter.after * 1000),
to: new Date(filter.before * 1000),
}
}
defaultText={isMobile ? "Dates" : "All Dates"}
updateSelectedRange={onUpdateSelectedRange}
/>
)}
{filters.includes("time") && (
<TimeRangeFilterButton
config={config}
timeRange={filter?.time_range}
updateTimeRange={(time_range) =>
onUpdateFilter({ ...filter, time_range })
}
/>
)}
{filters.includes("zone") && allZones.length > 0 && (
<ZoneFilterButton
allZones={filterValues.zones}
selectedZones={filter?.zones}
updateZoneFilter={(newZones) =>
onUpdateFilter({ ...filter, zones: newZones })
}
/>
)}
{filters.includes("sub") && (
<SubFilterButton
allSubLabels={allSubLabels}
selectedSubLabels={filter?.sub_labels}
updateSubLabelFilter={(newSubLabels) =>
onUpdateFilter({ ...filter, sub_labels: newSubLabels })
}
/>
)}
{config?.semantic_search?.enabled &&
filters.includes("source") &&
!filter?.search_type?.includes("similarity") && (
<SearchTypeButton
selectedSearchSources={
filter?.search_type ?? ["thumbnail", "description"]
}
updateSearchSourceFilter={(newSearchSource) =>
onUpdateFilter({ ...filter, search_type: newSearchSource })
}
/>
)}
</div> </div>
); );
} }

View File

@ -65,9 +65,7 @@ export function PlatformAwareSheet({
if (isMobile) { if (isMobile) {
return ( return (
<MobilePage open={open} onOpenChange={onOpenChange}> <MobilePage open={open} onOpenChange={onOpenChange}>
<Button asChild onClick={() => onOpenChange(!open)}> <Button asChild>{trigger}</Button>
{trigger}
</Button>
<MobilePageContent className="max-h-[75dvh] overflow-hidden px-4"> <MobilePageContent className="max-h-[75dvh] overflow-hidden px-4">
{content} {content}
</MobilePageContent> </MobilePageContent>

View File

@ -3,9 +3,37 @@ import { FaCog } from "react-icons/fa";
import { useState } from "react"; import { useState } from "react";
import { PlatformAwareSheet } from "./PlatformAwareDialog"; import { PlatformAwareSheet } from "./PlatformAwareDialog";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { CamerasFilterContent } from "@/components/filter/CamerasFilterButton";
import useSWR from "swr";
import { SearchFilter, SearchSource } from "@/types/search";
import { CameraGroupConfig } from "@/types/frigateConfig";
type SearchFilterDialogProps = {
filter?: SearchFilter;
filterValues: {
cameras: string[];
labels: string[];
zones: string[];
search_type: SearchSource[];
};
groups: [string, CameraGroupConfig][];
onUpdateFilter: (filter: SearchFilter) => void;
};
export default function SearchFilterDialog({
filter,
filterValues,
groups,
onUpdateFilter,
}: SearchFilterDialogProps) {
// data
const { data: allSubLabels } = useSWR(["sub_labels", { split_joined: 1 }]);
const [currentCameras, setCurrentCameras] = useState<string[] | undefined>(
filter?.cameras,
);
// state
type SearchFilterDialogProps = {};
export default function SearchFilterDialog({}: SearchFilterDialogProps) {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const trigger = ( const trigger = (
@ -14,7 +42,20 @@ export default function SearchFilterDialog({}: SearchFilterDialogProps) {
More Filters More Filters
</Button> </Button>
); );
const content = <></>; const content = (
<>
<CamerasFilterContent
allCameras={filterValues.cameras}
currentCameras={currentCameras}
groups={groups}
setCurrentCameras={setCurrentCameras}
setOpen={setOpen}
updateCameraFilter={(newCameras) => {
onUpdateFilter({ ...filter, cameras: newCameras });
}}
/>
</>
);
return ( return (
<PlatformAwareSheet <PlatformAwareSheet
@ -26,3 +67,59 @@ export default function SearchFilterDialog({}: SearchFilterDialogProps) {
/> />
); );
} }
/**
* {filters.includes("date") && (
<CalendarRangeFilterButton
range={
filter?.after == undefined || filter?.before == undefined
? undefined
: {
from: new Date(filter.after * 1000),
to: new Date(filter.before * 1000),
}
}
defaultText={isMobile ? "Dates" : "All Dates"}
updateSelectedRange={onUpdateSelectedRange}
/>
)}
{filters.includes("time") && (
<TimeRangeFilterButton
config={config}
timeRange={filter?.time_range}
updateTimeRange={(time_range) =>
onUpdateFilter({ ...filter, time_range })
}
/>
)}
{filters.includes("zone") && allZones.length > 0 && (
<ZoneFilterButton
allZones={filterValues.zones}
selectedZones={filter?.zones}
updateZoneFilter={(newZones) =>
onUpdateFilter({ ...filter, zones: newZones })
}
/>
)}
{filters.includes("sub") && (
<SubFilterButton
allSubLabels={allSubLabels}
selectedSubLabels={filter?.sub_labels}
updateSubLabelFilter={(newSubLabels) =>
onUpdateFilter({ ...filter, sub_labels: newSubLabels })
}
/>
)}
{config?.semantic_search?.enabled &&
filters.includes("source") &&
!filter?.search_type?.includes("similarity") && (
<SearchTypeButton
selectedSearchSources={
filter?.search_type ?? ["thumbnail", "description"]
}
updateSearchSourceFilter={(newSearchSource) =>
onUpdateFilter({ ...filter, search_type: newSearchSource })
}
/>
)}
*/