mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-14 15:15:22 +03:00
Handle single lists
This commit is contained in:
parent
09824c19a4
commit
c59aae718d
@ -417,7 +417,9 @@ function ZoneFilterButton({
|
|||||||
<div
|
<div
|
||||||
className={`hidden md:block ${selectedZones?.length ? "text-selected-foreground" : "text-primary"}`}
|
className={`hidden md:block ${selectedZones?.length ? "text-selected-foreground" : "text-primary"}`}
|
||||||
>
|
>
|
||||||
{selectedZones?.length ? `${selectedZones.length} Zones` : "All Zones"}
|
{selectedZones?.length
|
||||||
|
? `${selectedZones.length} Zone${selectedZones.length > 1 ? "s" : ""}`
|
||||||
|
: "All Zones"}
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
@ -558,6 +560,7 @@ export function ZoneFilterContent({
|
|||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setCurrentZones?.(undefined);
|
setCurrentZones?.(undefined);
|
||||||
|
updateZoneFilter?.(undefined);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Reset
|
Reset
|
||||||
@ -731,7 +734,7 @@ export function SubFilterContent({
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setCurrentSubLabels(undefined);
|
updateSubLabelFilter(undefined);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Reset
|
Reset
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { FilterType } from "@/types/filter";
|
import { FilterType } from "@/types/filter";
|
||||||
import { useMemo, useState } from "react";
|
import { useCallback, useMemo, useState } from "react";
|
||||||
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
type useApiFilterReturn<F extends FilterType> = [
|
type useApiFilterReturn<F extends FilterType> = [
|
||||||
filter: F | undefined,
|
filter: F | undefined,
|
||||||
@ -41,3 +42,90 @@ export default function useApiFilter<
|
|||||||
|
|
||||||
return [filter, setFilter, searchParams];
|
return [filter, setFilter, searchParams];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useApiFilterArgs<
|
||||||
|
F extends FilterType,
|
||||||
|
>(): useApiFilterReturn<F> {
|
||||||
|
const location = useLocation();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const setFilter = useCallback(
|
||||||
|
(filter: F) => {
|
||||||
|
let search = "";
|
||||||
|
|
||||||
|
Object.entries(filter).forEach(([key, value]) => {
|
||||||
|
let char = "";
|
||||||
|
if (search.length == 0) {
|
||||||
|
char = "?";
|
||||||
|
} else {
|
||||||
|
char = "&";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
if (value.length == 0) {
|
||||||
|
// empty array means all so ignore
|
||||||
|
} else {
|
||||||
|
search += `${char}${key}=${value.join(",")}`;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (value != undefined) {
|
||||||
|
search += `${char}${key}=${value}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
navigate(`${location.pathname}${search}`, { ...location.state });
|
||||||
|
},
|
||||||
|
[location, navigate],
|
||||||
|
);
|
||||||
|
|
||||||
|
const filter = useMemo<F>(() => {
|
||||||
|
const search = location?.search?.substring(1);
|
||||||
|
|
||||||
|
if (search == undefined || search.length == 0) {
|
||||||
|
return {} as F;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filter: { [key: string]: unknown } = {};
|
||||||
|
|
||||||
|
search.split("&").forEach((full) => {
|
||||||
|
const [key, value] = full.split("=");
|
||||||
|
|
||||||
|
if (isNaN(parseFloat(value))) {
|
||||||
|
filter[key] = value.includes(",") ? value.split(",") : [value];
|
||||||
|
} else {
|
||||||
|
if (value != undefined) {
|
||||||
|
filter[key] = `${value}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return filter as F;
|
||||||
|
}, [location?.search]);
|
||||||
|
|
||||||
|
const searchParams = useMemo(() => {
|
||||||
|
if (filter == undefined || Object.keys(filter).length == 0) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const search: { [key: string]: string } = {};
|
||||||
|
|
||||||
|
Object.entries(filter).forEach(([key, value]) => {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
if (value.length == 0) {
|
||||||
|
// empty array means all so ignore
|
||||||
|
} else {
|
||||||
|
search[key] = value.join(",");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (value != undefined) {
|
||||||
|
search[key] = `${value}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return search;
|
||||||
|
}, [filter]);
|
||||||
|
|
||||||
|
return [filter, setFilter, searchParams];
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import useApiFilter from "@/hooks/use-api-filter";
|
import { useApiFilterArgs } from "@/hooks/use-api-filter";
|
||||||
import { useCameraPreviews } from "@/hooks/use-camera-previews";
|
import { useCameraPreviews } from "@/hooks/use-camera-previews";
|
||||||
import { useOverlayState } from "@/hooks/use-overlay-state";
|
import { useOverlayState } from "@/hooks/use-overlay-state";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
@ -27,7 +27,7 @@ export default function Search() {
|
|||||||
// search filter
|
// search filter
|
||||||
|
|
||||||
const [searchFilter, setSearchFilter, searchSearchParams] =
|
const [searchFilter, setSearchFilter, searchSearchParams] =
|
||||||
useApiFilter<SearchFilter>();
|
useApiFilterArgs<SearchFilter>();
|
||||||
|
|
||||||
const onUpdateFilter = useCallback(
|
const onUpdateFilter = useCallback(
|
||||||
(newFilter: SearchFilter) => {
|
(newFilter: SearchFilter) => {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user