Refactor Search Page (#13645)

* Always enable search page

* Always show eents when searching

* No default search background

* Center and show all filters when semantic search is not enabled

* Limit number of default items shown

* Adjust search options

* Add support for sub label filtering

* Separate out filters and clean up detail pane

* Tablet cleanup

* Fix current hour search preview

* Handle single lists

* Cleanup api search
This commit is contained in:
Nicolas Mowen
2024-09-10 10:23:20 -06:00
committed by GitHub
parent ceb7aa8b36
commit c8521554c8
11 changed files with 770 additions and 270 deletions

View File

@@ -1,5 +1,26 @@
import { FilterType } from "@/types/filter";
import { useMemo, useState } from "react";
import { useCallback, useMemo, useState } from "react";
import { useSearchParams } from "react-router-dom";
function getStringifiedArgs(filter: FilterType) {
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;
}
type useApiFilterReturn<F extends FilterType> = [
filter: F | undefined,
@@ -20,23 +41,48 @@ export default function useApiFilter<
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;
return getStringifiedArgs(filter);
}, [filter]);
return [filter, setFilter, searchParams];
}
export function useApiFilterArgs<
F extends FilterType,
>(): useApiFilterReturn<F> {
const [rawParams, setRawParams] = useSearchParams();
const setFilter = useCallback(
(newFilter: F) => setRawParams(getStringifiedArgs(newFilter)),
[setRawParams],
);
const filter = useMemo<F>(() => {
if (rawParams.size == 0) {
return {} as F;
}
const filter: { [key: string]: unknown } = {};
rawParams.forEach((value, key) => {
if (isNaN(parseFloat(value))) {
filter[key] = value.includes(",") ? value.split(",") : [value];
} else {
if (value != undefined) {
filter[key] = `${value}`;
}
}
});
return filter as F;
}, [rawParams]);
const searchParams = useMemo(() => {
if (filter == undefined || Object.keys(filter).length == 0) {
return {};
}
return getStringifiedArgs(filter);
}, [filter]);
return [filter, setFilter, searchParams];

View File

@@ -19,7 +19,9 @@ export const ID_PLAYGROUND = 6;
export default function useNavigation(
variant: "primary" | "secondary" = "primary",
) {
const { data: config } = useSWR<FrigateConfig>("config");
const { data: config } = useSWR<FrigateConfig>("config", {
revalidateOnFocus: false,
});
return useMemo(
() =>
@@ -44,7 +46,6 @@ export default function useNavigation(
icon: IoSearch,
title: "Search",
url: "/search",
enabled: config?.semantic_search?.enabled,
},
{
id: ID_EXPORT,
@@ -70,6 +71,6 @@ export default function useNavigation(
enabled: ENV !== "production",
},
] as NavData[],
[config?.plus.enabled, config?.semantic_search.enabled, variant],
[config?.plus.enabled, variant],
);
}