hide cameras with ui.review disabled from the Motion tab and the review summaries

The Motion tab built its own camera list that never checked ui.review, so a hidden camera still got a preview tile, and its motion and overlap queries fell back to every allowed camera. The review and recordings summaries had the same gap: they are aggregate day counts that can't be filtered client side, so a hidden camera kept contributing to the severity tab counts and calendar indicators while its items were absent from the list. Filter the motion camera list on ui.review and query all four endpoints with the visible camera list instead of letting the backend default to all, and skip the summary queries until the config resolves so the counts don't briefly render as zero.
This commit is contained in:
Josh Hawkins
2026-07-30 07:56:45 -05:00
parent 4c11de87b0
commit c160a0dfeb
2 changed files with 37 additions and 18 deletions
+27 -16
View File
@@ -84,6 +84,11 @@ export default function Events() {
.map((conf) => conf.name);
}, [allowedCameras, config?.cameras]);
const reviewCamerasParam = useMemo(
() => reviewCameras.join(","),
[reviewCameras],
);
const selectedMotionSearchCamera = useMemo(() => {
if (!motionSearchCamera) {
return null;
@@ -450,15 +455,17 @@ export default function Events() {
// review summary
const { data: reviewSummary, mutate: updateSummary } = useSWR<ReviewSummary>(
[
"review/summary",
{
timezone: timezone,
cameras: reviewSearchParams["cameras"] ?? null,
labels: reviewSearchParams["labels"] ?? null,
zones: reviewSearchParams["zones"] ?? null,
},
],
timezone
? [
"review/summary",
{
timezone: timezone,
cameras: reviewSearchParams["cameras"] ?? reviewCamerasParam,
labels: reviewSearchParams["labels"] ?? null,
zones: reviewSearchParams["zones"] ?? null,
},
]
: null,
{
revalidateOnFocus: true,
refreshInterval: 30000,
@@ -473,13 +480,17 @@ export default function Events() {
// recordings summary
const { data: recordingsSummary } = useSWR<RecordingsSummary>([
"recordings/summary",
{
timezone: timezone,
cameras: reviewSearchParams["cameras"] ?? null,
},
]);
const { data: recordingsSummary } = useSWR<RecordingsSummary>(
timezone
? [
"recordings/summary",
{
timezone: timezone,
cameras: reviewSearchParams["cameras"] ?? reviewCamerasParam,
},
]
: null,
);
// preview videos
const previewTimes = useMemo(() => {
+10 -2
View File
@@ -1024,6 +1024,9 @@ function MotionReview({
if (!allowedCameras.includes(cam.name)) {
return false;
}
if (cam.ui?.review === false) {
return false;
}
if (selectedCams && !selectedCams.includes(cam.name)) {
return false;
}
@@ -1033,6 +1036,11 @@ function MotionReview({
return cameras.sort((a, b) => a.ui.order - b.ui.order);
}, [config, filter, allowedCameras]);
const reviewCamerasParam = useMemo(
() => reviewCameras.map((cam) => cam.name).join(","),
[reviewCameras],
);
const videoPlayersRef = useRef<{ [camera: string]: PreviewController }>({});
// motion data
@@ -1052,7 +1060,7 @@ function MotionReview({
before: alignedBefore,
after: alignedAfter,
scale: segmentDuration / 2,
cameras: filter?.cameras?.join(",") ?? null,
cameras: reviewCamerasParam,
},
]);
@@ -1061,7 +1069,7 @@ function MotionReview({
{
before: alignedBefore,
after: alignedAfter,
cameras: filter?.cameras?.join(",") ?? null,
cameras: reviewCamerasParam,
},
]);