Add score filter to Explore view (#14397)

* backend score filtering and sorting

* score filter frontend

* use input for score filtering

* use correct score on search thumbnail

* add popover to explain top_score

* revert sublabel score calc

* update filters logic

* fix rounding on score

* wait until default view is loaded

* don't turn button to selected style for similarity searches

* clarify language

* fix alert dialog buttons to use correct destructive variant

* use root level top_score for very old events

* better arrangement of thumbnail footer items on smaller screens
This commit is contained in:
Josh Hawkins
2024-10-17 06:30:52 -05:00
committed by GitHub
parent edaccd86d6
commit 8173cd7776
16 changed files with 353 additions and 136 deletions

View File

@@ -45,6 +45,9 @@ class EventsSearchQueryParams(BaseModel):
before: Optional[float] = None
time_range: Optional[str] = DEFAULT_TIME_RANGE
timezone: Optional[str] = "utc"
min_score: Optional[float] = None
max_score: Optional[float] = None
sort: Optional[str] = None
class EventsSummaryQueryParams(BaseModel):

View File

@@ -348,6 +348,7 @@ def events_search(request: Request, params: EventsSearchQueryParams = Depends())
search_type = params.search_type
include_thumbnails = params.include_thumbnails
limit = params.limit
sort = params.sort
# Filters
cameras = params.cameras
@@ -355,6 +356,8 @@ def events_search(request: Request, params: EventsSearchQueryParams = Depends())
zones = params.zones
after = params.after
before = params.before
min_score = params.min_score
max_score = params.max_score
time_range = params.time_range
# for similarity search
@@ -430,6 +433,14 @@ def events_search(request: Request, params: EventsSearchQueryParams = Depends())
if before:
event_filters.append((Event.start_time < before))
if min_score is not None and max_score is not None:
event_filters.append((Event.data["score"].between(min_score, max_score)))
else:
if min_score is not None:
event_filters.append((Event.data["score"] >= min_score))
if max_score is not None:
event_filters.append((Event.data["score"] <= max_score))
if time_range != DEFAULT_TIME_RANGE:
tz_name = params.timezone
hour_modifier, minute_modifier, _ = get_tz_modifiers(tz_name)
@@ -554,11 +565,19 @@ def events_search(request: Request, params: EventsSearchQueryParams = Depends())
processed_events.append(processed_event)
# Sort by search distance if search_results are available, otherwise by start_time
# Sort by search distance if search_results are available, otherwise by start_time as default
if search_results:
processed_events.sort(key=lambda x: x.get("search_distance", float("inf")))
else:
processed_events.sort(key=lambda x: x["start_time"], reverse=True)
if sort == "score_asc":
processed_events.sort(key=lambda x: x["score"])
elif sort == "score_desc":
processed_events.sort(key=lambda x: x["score"], reverse=True)
elif sort == "date_asc":
processed_events.sort(key=lambda x: x["start_time"])
else:
# "date_desc" default
processed_events.sort(key=lambda x: x["start_time"], reverse=True)
# Limit the number of events returned
processed_events = processed_events[:limit]