>
);
diff --git a/web/src/components/filter/CameraGroupSelector.tsx b/web/src/components/filter/CameraGroupSelector.tsx
index d63fcd9bf..28568514e 100644
--- a/web/src/components/filter/CameraGroupSelector.tsx
+++ b/web/src/components/filter/CameraGroupSelector.tsx
@@ -3,7 +3,7 @@ import { isDesktop, isMobile } from "react-device-detect";
import useSWR from "swr";
import { MdHome } from "react-icons/md";
import { usePersistedOverlayState } from "@/hooks/use-overlay-state";
-import { Button } from "../ui/button";
+import { Button, buttonVariants } from "../ui/button";
import { useCallback, useMemo, useState } from "react";
import { Tooltip, TooltipContent, TooltipTrigger } from "../ui/tooltip";
import { LuPencil, LuPlus } from "react-icons/lu";
@@ -518,7 +518,10 @@ export function CameraGroupRow({
Cancel
-
+
Delete
diff --git a/web/src/components/filter/ReviewActionGroup.tsx b/web/src/components/filter/ReviewActionGroup.tsx
index c637b1e35..f2d67efd7 100644
--- a/web/src/components/filter/ReviewActionGroup.tsx
+++ b/web/src/components/filter/ReviewActionGroup.tsx
@@ -1,7 +1,7 @@
import { FaCircleCheck } from "react-icons/fa6";
import { useCallback, useState } from "react";
import axios from "axios";
-import { Button } from "../ui/button";
+import { Button, buttonVariants } from "../ui/button";
import { isDesktop } from "react-device-detect";
import { FaCompactDisc } from "react-icons/fa";
import { HiTrash } from "react-icons/hi";
@@ -79,7 +79,10 @@ export default function ReviewActionGroup({
Cancel
-
+
Delete
diff --git a/web/src/components/input/DeleteSearchDialog.tsx b/web/src/components/input/DeleteSearchDialog.tsx
index 0aaabdde5..735f52b26 100644
--- a/web/src/components/input/DeleteSearchDialog.tsx
+++ b/web/src/components/input/DeleteSearchDialog.tsx
@@ -8,6 +8,7 @@ import {
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
+import { buttonVariants } from "../ui/button";
type DeleteSearchDialogProps = {
isOpen: boolean;
@@ -35,7 +36,7 @@ export function DeleteSearchDialog({
Cancel
Delete
diff --git a/web/src/components/input/InputWithTags.tsx b/web/src/components/input/InputWithTags.tsx
index 9ca1e4093..45dfd6c32 100644
--- a/web/src/components/input/InputWithTags.tsx
+++ b/web/src/components/input/InputWithTags.tsx
@@ -201,10 +201,13 @@ export default function InputWithTags({
allSuggestions[type as FilterType]?.includes(value) ||
type == "before" ||
type == "after" ||
- type == "time_range"
+ type == "time_range" ||
+ type == "min_score" ||
+ type == "max_score"
) {
const newFilters = { ...filters };
let timestamp = 0;
+ let score = 0;
switch (type) {
case "before":
@@ -244,6 +247,40 @@ export default function InputWithTags({
newFilters[type] = timestamp / 1000;
}
break;
+ case "min_score":
+ case "max_score":
+ score = parseInt(value);
+ if (score >= 0) {
+ // Check for conflicts between min_score and max_score
+ if (
+ type === "min_score" &&
+ filters.max_score !== undefined &&
+ score > filters.max_score * 100
+ ) {
+ toast.error(
+ "The 'min_score' must be less than or equal to the 'max_score'.",
+ {
+ position: "top-center",
+ },
+ );
+ return;
+ }
+ if (
+ type === "max_score" &&
+ filters.min_score !== undefined &&
+ score < filters.min_score * 100
+ ) {
+ toast.error(
+ "The 'max_score' must be greater than or equal to the 'min_score'.",
+ {
+ position: "top-center",
+ },
+ );
+ return;
+ }
+ newFilters[type] = score / 100;
+ }
+ break;
case "time_range":
newFilters[type] = value;
break;
@@ -302,6 +339,8 @@ export default function InputWithTags({
} - ${
config?.ui.time_format === "24hour" ? endTime : convertTo12Hour(endTime)
}`;
+ } else if (filterType === "min_score" || filterType === "max_score") {
+ return Math.round(Number(filterValues) * 100).toString() + "%";
} else {
return filterValues as string;
}
@@ -320,7 +359,11 @@ export default function InputWithTags({
isValidTimeRange(
trimmedValue.replace("-", ","),
config?.ui.time_format,
- ))
+ )) ||
+ ((filterType === "min_score" || filterType === "max_score") &&
+ !isNaN(Number(trimmedValue)) &&
+ Number(trimmedValue) >= 50 &&
+ Number(trimmedValue) <= 100)
) {
createFilter(
filterType,
diff --git a/web/src/components/overlay/detail/SearchDetailDialog.tsx b/web/src/components/overlay/detail/SearchDetailDialog.tsx
index 37813645b..fe150bd56 100644
--- a/web/src/components/overlay/detail/SearchDetailDialog.tsx
+++ b/web/src/components/overlay/detail/SearchDetailDialog.tsx
@@ -62,6 +62,12 @@ import { Card, CardContent } from "@/components/ui/card";
import useImageLoaded from "@/hooks/use-image-loaded";
import ImageLoadingIndicator from "@/components/indicators/ImageLoadingIndicator";
import { GenericVideoPlayer } from "@/components/player/GenericVideoPlayer";
+import {
+ Popover,
+ PopoverContent,
+ PopoverTrigger,
+} from "@/components/ui/popover";
+import { LuInfo } from "react-icons/lu";
const SEARCH_TABS = [
"details",
@@ -279,7 +285,7 @@ function ObjectDetailsTab({
return 0;
}
- const value = search.score ?? search.data.top_score;
+ const value = search.data.top_score;
return Math.round(value * 100);
}, [search]);
@@ -369,7 +375,24 @@ function ObjectDetailsTab({
-
Score
+
+
+ Top Score
+
+
+
+
+ Info
+
+
+
+ The top score is the highest median score for the tracked
+ object, so this may differ from the score shown on the
+ search result thumbnail.
+
+
+
+ );
+}
+
type SearchTypeContentProps = {
searchSources: SearchSource[] | undefined;
setSearchSources: (sources: SearchSource[] | undefined) => void;
diff --git a/web/src/components/settings/PolygonItem.tsx b/web/src/components/settings/PolygonItem.tsx
index 68aa89978..bc1db92c3 100644
--- a/web/src/components/settings/PolygonItem.tsx
+++ b/web/src/components/settings/PolygonItem.tsx
@@ -35,6 +35,7 @@ import { FrigateConfig } from "@/types/frigateConfig";
import { reviewQueries } from "@/utils/zoneEdutUtil";
import IconWrapper from "../ui/icon-wrapper";
import { StatusBarMessagesContext } from "@/context/statusbar-provider";
+import { buttonVariants } from "../ui/button";
type PolygonItemProps = {
polygon: Polygon;
@@ -257,7 +258,10 @@ export default function PolygonItem({
Cancel
-
+
Delete
diff --git a/web/src/components/settings/SearchSettings.tsx b/web/src/components/settings/SearchSettings.tsx
index d1c0856ef..b3a1e89d3 100644
--- a/web/src/components/settings/SearchSettings.tsx
+++ b/web/src/components/settings/SearchSettings.tsx
@@ -1,6 +1,6 @@
import { Button } from "../ui/button";
import { useState } from "react";
-import { isDesktop } from "react-device-detect";
+import { isDesktop, isMobileOnly } from "react-device-detect";
import { cn } from "@/lib/utils";
import PlatformAwareDialog from "../overlay/dialog/PlatformAwareDialog";
import { FaCog } from "react-icons/fa";
@@ -40,7 +40,7 @@ export default function SearchSettings({
-
Default Search View
+
Default View
When no filters are selected, display a summary of the most recent
tracked objects per label, or display an unfiltered grid.
@@ -68,26 +68,32 @@ export default function SearchSettings({
-
-
-
-
Grid Columns
-
- Select the number of columns in the results grid.
+ {!isMobileOnly && (
+ <>
+
+
+
+
Grid Columns
+
+ Select the number of columns in the grid view.
+