diff --git a/web/src/components/overlay/detail/SearchDetailDialog.tsx b/web/src/components/overlay/detail/SearchDetailDialog.tsx index 7f69f2ca2..ed472c742 100644 --- a/web/src/components/overlay/detail/SearchDetailDialog.tsx +++ b/web/src/components/overlay/detail/SearchDetailDialog.tsx @@ -333,13 +333,18 @@ function ObjectDetailsTab({ } }, [search]); - const identifierScore = useMemo(() => { + const recognizedLicensePlateScore = useMemo(() => { if (!search) { return undefined; } - if (search.data.identifier && search.data?.identifier_score) { - return Math.round((search.data?.identifier_score ?? 0) * 100); + if ( + search.data.recognized_license_plate && + search.data?.recognized_license_plate_score + ) { + return Math.round( + (search.data?.recognized_license_plate_score ?? 0) * 100, + ); } else { return undefined; } @@ -550,13 +555,16 @@ function ObjectDetailsTab({ - {search?.data.identifier && ( + {search?.data.recognized_license_plate && (
-
Identifier
+
+ Recognized License Plate +
- {search.data.identifier}{" "} - {identifierScore && ` (${identifierScore}%)`} + {search.data.recognized_license_plate}{" "} + {recognizedLicensePlateScore && + ` (${recognizedLicensePlateScore}%)`}
diff --git a/web/src/components/overlay/dialog/SearchFilterDialog.tsx b/web/src/components/overlay/dialog/SearchFilterDialog.tsx index 59b30f82f..2768f8859 100644 --- a/web/src/components/overlay/dialog/SearchFilterDialog.tsx +++ b/web/src/components/overlay/dialog/SearchFilterDialog.tsx @@ -86,7 +86,7 @@ export default function SearchFilterDialog({ (currentFilter.max_speed ?? 150) < 150 || (currentFilter.zones?.length ?? 0) > 0 || (currentFilter.sub_labels?.length ?? 0) > 0 || - (currentFilter.identifier?.length ?? 0) > 0), + (currentFilter.recognized_license_plate?.length ?? 0) > 0), [currentFilter], ); @@ -128,10 +128,13 @@ export default function SearchFilterDialog({ setCurrentFilter({ ...currentFilter, sub_labels: newSubLabels }) } /> - - setCurrentFilter({ ...currentFilter, identifier: identifiers }) + + setCurrentFilter({ + ...currentFilter, + recognized_license_plate: plate, + }) } /> @@ -847,97 +850,109 @@ export function SnapshotClipFilterContent({ ); } -type IdentifierFilterContentProps = { - identifiers: string[] | undefined; - setIdentifiers: (identifiers: string[] | undefined) => void; +type RecognizedLicensePlatesFilterContentProps = { + recognizedLicensePlates: string[] | undefined; + setRecognizedLicensePlates: ( + recognizedLicensePlates: string[] | undefined, + ) => void; }; -export function IdentifierFilterContent({ - identifiers, - setIdentifiers, -}: IdentifierFilterContentProps) { - const { data: allIdentifiers, error } = useSWR("identifiers", { - revalidateOnFocus: false, - }); - - const [selectedIdentifiers, setSelectedIdentifiers] = useState( - identifiers || [], +export function RecognizedLicensePlatesFilterContent({ + recognizedLicensePlates, + setRecognizedLicensePlates, +}: RecognizedLicensePlatesFilterContentProps) { + const { data: allRecognizedLicensePlates, error } = useSWR( + "recognized_license_plates", + { + revalidateOnFocus: false, + }, ); + + const [selectedRecognizedLicensePlates, setSelectedRecognizedLicensePlates] = + useState(recognizedLicensePlates || []); const [inputValue, setInputValue] = useState(""); useEffect(() => { - if (identifiers) { - setSelectedIdentifiers(identifiers); + if (recognizedLicensePlates) { + setSelectedRecognizedLicensePlates(recognizedLicensePlates); } else { - setSelectedIdentifiers([]); + setSelectedRecognizedLicensePlates([]); } - }, [identifiers]); + }, [recognizedLicensePlates]); - const handleSelect = (identifier: string) => { - const newSelected = selectedIdentifiers.includes(identifier) - ? selectedIdentifiers.filter((id) => id !== identifier) // Deselect - : [...selectedIdentifiers, identifier]; // Select + const handleSelect = (recognizedLicensePlate: string) => { + const newSelected = selectedRecognizedLicensePlates.includes( + recognizedLicensePlate, + ) + ? selectedRecognizedLicensePlates.filter( + (id) => id !== recognizedLicensePlate, + ) // Deselect + : [...selectedRecognizedLicensePlates, recognizedLicensePlate]; // Select - setSelectedIdentifiers(newSelected); + setSelectedRecognizedLicensePlates(newSelected); if (newSelected.length === 0) { - setIdentifiers(undefined); // Clear filter if no identifiers selected + setRecognizedLicensePlates(undefined); // Clear filter if no plates selected } else { - setIdentifiers(newSelected); + setRecognizedLicensePlates(newSelected); } }; - if (!allIdentifiers || allIdentifiers.length === 0) { + if (!allRecognizedLicensePlates || allRecognizedLicensePlates.length === 0) { return null; } - const filteredIdentifiers = - allIdentifiers?.filter((id) => + const filteredRecognizedLicensePlates = + allRecognizedLicensePlates?.filter((id) => id.toLowerCase().includes(inputValue.toLowerCase()), ) || []; return (
-
Identifiers
+
Recognized License Plates
{error ? ( -

Failed to load identifiers

- ) : !allIdentifiers ? ( -

Loading identifiers...

+

+ Failed to load recognized license plates. +

+ ) : !allRecognizedLicensePlates ? ( +

+ Loading recognized license plates... +

) : ( <> - {filteredIdentifiers.length === 0 && inputValue && ( - No identifiers found. + {filteredRecognizedLicensePlates.length === 0 && inputValue && ( + No license plates found. )} - {filteredIdentifiers.map((identifier) => ( + {filteredRecognizedLicensePlates.map((plate) => ( handleSelect(identifier)} + key={plate} + value={plate} + onSelect={() => handleSelect(plate)} className="cursor-pointer" > - {identifier} + {plate} ))} - {selectedIdentifiers.length > 0 && ( + {selectedRecognizedLicensePlates.length > 0 && (
- {selectedIdentifiers.map((id) => ( + {selectedRecognizedLicensePlates.map((id) => ( )}

- Select one or more identifiers from the list. + Select one or more plates from the list.

); diff --git a/web/src/pages/Explore.tsx b/web/src/pages/Explore.tsx index cf24ff70d..31fe81d04 100644 --- a/web/src/pages/Explore.tsx +++ b/web/src/pages/Explore.tsx @@ -105,7 +105,8 @@ export default function Explore() { cameras: searchSearchParams["cameras"], labels: searchSearchParams["labels"], sub_labels: searchSearchParams["sub_labels"], - identifier: searchSearchParams["identifier"], + recognized_license_plate: + searchSearchParams["recognized_license_plate"], zones: searchSearchParams["zones"], before: searchSearchParams["before"], after: searchSearchParams["after"], @@ -141,7 +142,8 @@ export default function Explore() { cameras: searchSearchParams["cameras"], labels: searchSearchParams["labels"], sub_labels: searchSearchParams["sub_labels"], - identifier: searchSearchParams["identifier"], + recognized_license_plate: + searchSearchParams["recognized_license_plate"], zones: searchSearchParams["zones"], before: searchSearchParams["before"], after: searchSearchParams["after"], diff --git a/web/src/types/search.ts b/web/src/types/search.ts index 90bcd54d7..5dca11973 100644 --- a/web/src/types/search.ts +++ b/web/src/types/search.ts @@ -58,8 +58,8 @@ export type SearchResult = { average_estimated_speed: number; velocity_angle: number; path_data: [number[], number][]; - identifier?: string; - identifier_score?: number; + recognized_license_plate?: string; + recognized_license_plate_score?: number; }; }; @@ -68,7 +68,7 @@ export type SearchFilter = { cameras?: string[]; labels?: string[]; sub_labels?: string[]; - identifier?: string[]; + recognized_license_plate?: string[]; zones?: string[]; before?: number; after?: number; @@ -92,7 +92,7 @@ export type SearchQueryParams = { cameras?: string[]; labels?: string[]; sub_labels?: string[]; - identifier?: string[]; + recognized_license_plate?: string[]; zones?: string[]; before?: string; after?: string; diff --git a/web/src/views/search/SearchView.tsx b/web/src/views/search/SearchView.tsx index 7f1b1e4a1..3d7cbfcfe 100644 --- a/web/src/views/search/SearchView.tsx +++ b/web/src/views/search/SearchView.tsx @@ -121,7 +121,9 @@ export default function SearchView({ }, [config, searchFilter]); const { data: allSubLabels } = useSWR("sub_labels"); - const { data: allIdentifiers } = useSWR("identifiers"); + const { data: allRecognizedLicensePlates } = useSWR( + "recognized_license_plate", + ); const allZones = useMemo(() => { if (!config) { @@ -161,13 +163,20 @@ export default function SearchView({ max_score: ["100"], min_speed: ["1"], max_speed: ["150"], - identifier: allIdentifiers, + recognized_license_plate: allRecognizedLicensePlates, has_clip: ["yes", "no"], has_snapshot: ["yes", "no"], ...(config?.plus?.enabled && searchFilter?.has_snapshot && { is_submitted: ["yes", "no"] }), }), - [config, allLabels, allZones, allSubLabels, allIdentifiers, searchFilter], + [ + config, + allLabels, + allZones, + allSubLabels, + allRecognizedLicensePlates, + searchFilter, + ], ); // remove duplicate event ids