(
+ timezone
+ ? [
+ "recordings/summary",
+ {
+ timezone: timezone,
+ cameras: reviewCamerasParam,
+ },
+ ]
+ : null,
+ );
// preview videos
const previewTimes = useMemo(() => {
diff --git a/web/src/pages/Settings.tsx b/web/src/pages/Settings.tsx
index 6f445f0c47..e2666f57e3 100644
--- a/web/src/pages/Settings.tsx
+++ b/web/src/pages/Settings.tsx
@@ -706,12 +706,7 @@ export default function Settings() {
}
return Object.values(config.cameras)
- .filter(
- (conf) =>
- conf.ui.dashboard &&
- conf.enabled_in_config &&
- !isReplayCamera(conf.name),
- )
+ .filter((conf) => conf.enabled_in_config && !isReplayCamera(conf.name))
.sort((aConf, bConf) => aConf.ui.order - bConf.ui.order);
}, [config]);
diff --git a/web/src/views/events/EventView.tsx b/web/src/views/events/EventView.tsx
index dd89e78780..50236b284a 100644
--- a/web/src/views/events/EventView.tsx
+++ b/web/src/views/events/EventView.tsx
@@ -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,
},
]);
diff --git a/web/src/views/system/GeneralMetrics.tsx b/web/src/views/system/GeneralMetrics.tsx
index 4cba965298..1a7767ffb5 100644
--- a/web/src/views/system/GeneralMetrics.tsx
+++ b/web/src/views/system/GeneralMetrics.tsx
@@ -540,6 +540,36 @@ export default function GeneralMetrics({
return Object.keys(series).length > 0 ? Object.values(series) : undefined;
}, [statsHistory]);
+ // Number of cards the hardware grid renders. Which ones appear depends on
+ // the vendor, so the column count follows the count rather than assuming a
+ // fixed set is present.
+ const hardwareCardCount = useMemo(() => {
+ if (!statsHistory[0]?.gpu_usages) {
+ return 0;
+ }
+
+ const hasNpu = statsHistory[0].npu_usages != undefined;
+
+ return (
+ 1 + // gpu usage always renders alongside gpu_usages
+ (gpuMemSeries ? 1 : 0) +
+ (gpuEncSeries?.length ? 1 : 0) +
+ (gpuComputeSeries?.length ? 1 : 0) +
+ (gpuDecSeries?.length ? 1 : 0) +
+ (gpuTempSeries?.length ? 1 : 0) +
+ (hasNpu ? 1 : 0) +
+ (hasNpu && npuTempSeries?.length ? 1 : 0)
+ );
+ }, [
+ statsHistory,
+ gpuMemSeries,
+ gpuEncSeries,
+ gpuComputeSeries,
+ gpuDecSeries,
+ gpuTempSeries,
+ npuTempSeries,
+ ]);
+
// other processes stats
const hardwareType = useMemo(() => {
@@ -763,12 +793,9 @@ export default function GeneralMetrics({
= 3 && "lg:grid-cols-3",
+ hardwareCardCount >= 4 && "xl:grid-cols-4",
+ hardwareCardCount >= 5 && "3xl:grid-cols-5",
)}
>
{statsHistory[0]?.gpu_usages && (