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>
);
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 && (
<>
@ -158,40 +222,4 @@ export function CamerasFilterButton({
</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 FilterSwitch from "./FilterSwitch";
import { FilterList } from "@/types/filter";
import { CalendarRangeFilterButton } from "./CalendarFilterButton";
import { CamerasFilterButton } from "./CamerasFilterButton";
import {
DEFAULT_SEARCH_FILTERS,
@ -80,8 +79,6 @@ export default function SearchFilterGroup({
return [...labels].sort();
}, [config, filterList, filter]);
const { data: allSubLabels } = useSWR(["sub_labels", { split_joined: 1 }]);
const allZones = useMemo<string[]>(() => {
if (filterList?.zones) {
return filterList.zones;
@ -169,60 +166,12 @@ export default function SearchFilterGroup({
}}
/>
)}
<SearchFilterDialog />
{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}
<SearchFilterDialog
filter={filter}
filterValues={filterValues}
groups={groups}
onUpdateFilter={onUpdateFilter}
/>
)}
{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>
);
}

View File

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

View File

@ -3,9 +3,37 @@ import { FaCog } from "react-icons/fa";
import { useState } from "react";
import { PlatformAwareSheet } from "./PlatformAwareDialog";
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 trigger = (
@ -14,7 +42,20 @@ export default function SearchFilterDialog({}: SearchFilterDialogProps) {
More Filters
</Button>
);
const content = <></>;
const content = (
<>
<CamerasFilterContent
allCameras={filterValues.cameras}
currentCameras={currentCameras}
groups={groups}
setCurrentCameras={setCurrentCameras}
setOpen={setOpen}
updateCameraFilter={(newCameras) => {
onUpdateFilter({ ...filter, cameras: newCameras });
}}
/>
</>
);
return (
<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 })
}
/>
)}
*/