diff --git a/web/src/components/filter/SearchFilterGroup.tsx b/web/src/components/filter/SearchFilterGroup.tsx index 6850b9df3..5fe301f19 100644 --- a/web/src/components/filter/SearchFilterGroup.tsx +++ b/web/src/components/filter/SearchFilterGroup.tsx @@ -1,5 +1,4 @@ import { Button } from "../ui/button"; -import { Popover, PopoverContent, PopoverTrigger } from "../ui/popover"; import useSWR from "swr"; import { FrigateConfig } from "@/types/frigateConfig"; import { useCallback, useEffect, useMemo, useState } from "react"; @@ -16,18 +15,11 @@ import { SearchFilter, SearchFilters, SearchSource, - DEFAULT_TIME_RANGE_AFTER, - DEFAULT_TIME_RANGE_BEFORE, } from "@/types/search"; import { DateRange } from "react-day-picker"; import { cn } from "@/lib/utils"; -import SubFilterIcon from "../icons/SubFilterIcon"; -import { FaLocationDot } from "react-icons/fa6"; import { MdLabel } from "react-icons/md"; -import SearchSourceIcon from "../icons/SearchSourceIcon"; import PlatformAwareDialog from "../overlay/dialog/PlatformAwareDialog"; -import { FaArrowRight, FaClock } from "react-icons/fa"; -import { useFormattedHour } from "@/hooks/use-date-utils"; import SearchFilterDialog from "../overlay/dialog/SearchFilterDialog"; import { CalendarRangeFilterButton } from "./CalendarFilterButton"; @@ -185,7 +177,6 @@ export default function SearchFilterGroup({ config={config} filter={filter} filterValues={filterValues} - groups={groups} onUpdateFilter={onUpdateFilter} /> @@ -364,404 +355,3 @@ export function GeneralFilterContent({ ); } - -type ZoneFilterButtonProps = { - allZones: string[]; - selectedZones?: string[]; - updateZoneFilter: (zones: string[] | undefined) => void; -}; -function ZoneFilterButton({ - allZones, - selectedZones, - updateZoneFilter, -}: ZoneFilterButtonProps) { - const [open, setOpen] = useState(false); - - const [currentZones, setCurrentZones] = useState( - selectedZones, - ); - - const buttonText = useMemo(() => { - if (isMobile) { - return "Zones"; - } - - if (!selectedZones || selectedZones.length == 0) { - return "All Zones"; - } - - if (selectedZones.length == 1) { - return selectedZones[0]; - } - - return `${selectedZones.length} Zones`; - }, [selectedZones]); - - // ui - - useEffect(() => { - setCurrentZones(selectedZones); - // only refresh when state changes - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [selectedZones]); - - const trigger = ( - - ); - const content = ( - setOpen(false)} - /> - ); - - return ( - { - if (!open) { - setCurrentZones(selectedZones); - } - - setOpen(open); - }} - /> - ); -} - -type SubFilterButtonProps = { - allSubLabels: string[]; - selectedSubLabels: string[] | undefined; - updateSubLabelFilter: (labels: string[] | undefined) => void; -}; -function SubFilterButton({ - allSubLabels, - selectedSubLabels, - updateSubLabelFilter, -}: SubFilterButtonProps) { - const [open, setOpen] = useState(false); - const [currentSubLabels, setCurrentSubLabels] = useState< - string[] | undefined - >(selectedSubLabels); - - const buttonText = useMemo(() => { - if (isMobile) { - return "Sub Labels"; - } - - if (!selectedSubLabels || selectedSubLabels.length == 0) { - return "All Sub Labels"; - } - - if (selectedSubLabels.length == 1) { - return selectedSubLabels[0]; - } - - return `${selectedSubLabels.length} Sub Labels`; - }, [selectedSubLabels]); - - const trigger = ( - - ); - const content = ( - setOpen(false)} - /> - ); - - return ( - { - if (!open) { - setCurrentSubLabels(selectedSubLabels); - } - - setOpen(open); - }} - /> - ); -} - -type SubFilterContentProps = { - allSubLabels: string[]; - selectedSubLabels: string[] | undefined; - currentSubLabels: string[] | undefined; - updateSubLabelFilter: (labels: string[] | undefined) => void; - setCurrentSubLabels: (labels: string[] | undefined) => void; - onClose: () => void; -}; -export function SubFilterContent({ - allSubLabels, - selectedSubLabels, - currentSubLabels, - updateSubLabelFilter, - setCurrentSubLabels, - onClose, -}: SubFilterContentProps) { - return ( - <> -
-
- - { - if (isChecked) { - setCurrentSubLabels(undefined); - } - }} - /> -
-
- {allSubLabels.map((item) => ( - { - if (isChecked) { - const updatedLabels = currentSubLabels - ? [...currentSubLabels] - : []; - - updatedLabels.push(item); - setCurrentSubLabels(updatedLabels); - } else { - const updatedLabels = currentSubLabels - ? [...currentSubLabels] - : []; - - // can not deselect the last item - if (updatedLabels.length > 1) { - updatedLabels.splice(updatedLabels.indexOf(item), 1); - setCurrentSubLabels(updatedLabels); - } - } - }} - /> - ))} -
-
- {isDesktop && } -
- - -
- - ); -} - -type SearchTypeButtonProps = { - selectedSearchSources: SearchSource[] | undefined; - updateSearchSourceFilter: (sources: SearchSource[] | undefined) => void; -}; -function SearchTypeButton({ - selectedSearchSources, - updateSearchSourceFilter, -}: SearchTypeButtonProps) { - const [open, setOpen] = useState(false); - - const buttonText = useMemo(() => { - if (isMobile) { - return "Sources"; - } - - if ( - !selectedSearchSources || - selectedSearchSources.length == 0 || - selectedSearchSources.length == 2 - ) { - return "All Search Sources"; - } - - if (selectedSearchSources.length == 1) { - return selectedSearchSources[0]; - } - - return `${selectedSearchSources.length} Search Sources`; - }, [selectedSearchSources]); - - const trigger = ( - - ); - const content = ( - setOpen(false)} - /> - ); - - return ( - - ); -} - -type SearchTypeContentProps = { - selectedSearchSources: SearchSource[] | undefined; - updateSearchSourceFilter: (sources: SearchSource[] | undefined) => void; - onClose: () => void; -}; -export function SearchTypeContent({ - selectedSearchSources, - updateSearchSourceFilter, - onClose, -}: SearchTypeContentProps) { - const [currentSearchSources, setCurrentSearchSources] = useState< - SearchSource[] | undefined - >(selectedSearchSources); - - return ( - <> -
-
- { - const updatedSources = currentSearchSources - ? [...currentSearchSources] - : []; - - if (isChecked) { - updatedSources.push("thumbnail"); - setCurrentSearchSources(updatedSources); - } else { - if (updatedSources.length > 1) { - const index = updatedSources.indexOf("thumbnail"); - if (index !== -1) updatedSources.splice(index, 1); - setCurrentSearchSources(updatedSources); - } - } - }} - /> - { - const updatedSources = currentSearchSources - ? [...currentSearchSources] - : []; - - if (isChecked) { - updatedSources.push("description"); - setCurrentSearchSources(updatedSources); - } else { - if (updatedSources.length > 1) { - const index = updatedSources.indexOf("description"); - if (index !== -1) updatedSources.splice(index, 1); - setCurrentSearchSources(updatedSources); - } - } - }} - /> -
- {isDesktop && } -
- - -
-
- - ); -} diff --git a/web/src/components/overlay/dialog/SearchFilterDialog.tsx b/web/src/components/overlay/dialog/SearchFilterDialog.tsx index 7359505f8..c955efb97 100644 --- a/web/src/components/overlay/dialog/SearchFilterDialog.tsx +++ b/web/src/components/overlay/dialog/SearchFilterDialog.tsx @@ -10,7 +10,7 @@ import { SearchFilter, SearchSource, } from "@/types/search"; -import { CameraGroupConfig, FrigateConfig } from "@/types/frigateConfig"; +import { FrigateConfig } from "@/types/frigateConfig"; import { Popover, PopoverContent, @@ -33,14 +33,12 @@ type SearchFilterDialogProps = { zones: string[]; search_type: SearchSource[]; }; - groups: [string, CameraGroupConfig][]; onUpdateFilter: (filter: SearchFilter) => void; }; export default function SearchFilterDialog({ config, filter, filterValues, - groups, onUpdateFilter, }: SearchFilterDialogProps) { // data @@ -50,6 +48,8 @@ export default function SearchFilterDialog({ // state + console.log(`the filter is ${JSON.stringify(currentFilter)}`); + const [open, setOpen] = useState(false); const trigger = ( @@ -64,14 +64,29 @@ export default function SearchFilterDialog({ config={config} timeRange={currentFilter.time_range} updateTimeRange={(newRange) => - setCurrentFilter({ time_range: newRange, ...currentFilter }) + setCurrentFilter({ ...currentFilter, time_range: newRange }) } /> - setCurrentFilter({ zones: newZones, ...currentFilter }) + setCurrentFilter({ ...currentFilter, zones: newZones }) + } + /> + + setCurrentFilter({ ...currentFilter, sub_labels: newSubLabels }) + } + /> + + onUpdateFilter({ ...currentFilter, search_type: newSearchSource }) } /> {isDesktop && } @@ -105,7 +120,13 @@ export default function SearchFilterDialog({ content={content} contentClassName="w-auto lg:w-[300px]" open={open} - onOpenChange={setOpen} + onOpenChange={(open) => { + if (!open) { + setCurrentFilter(filter ?? {}); + } + + setOpen(open); + }} /> ); } @@ -256,9 +277,10 @@ export function ZoneFilterContent({ return ( <>
+ {isDesktop && } + Zones {allZones && ( <> - {isDesktop && }