Compare commits

...
2 Commits
14 changed files with 165 additions and 130 deletions
@@ -64,7 +64,6 @@ export default function Step2StateArea({
const selectedCameraNames = cameraAreas.map((ca) => ca.camera);
return Object.entries(config.cameras)
.sort()
.filter(
([name, cam]) =>
cam.enabled &&
@@ -72,6 +71,7 @@ export default function Step2StateArea({
!isReplayCamera(name) &&
!selectedCameraNames.includes(name),
)
.sort(([, a], [, b]) => a.ui.order - b.ui.order)
.map(([name]) => ({
name,
displayName: resolveCameraName(config, name),
@@ -29,9 +29,13 @@ export default function ExportFilterGroup({
const filterValues = useMemo(
() => ({
cameras: allowedCameras,
cameras: [...allowedCameras].sort(
(a, b) =>
(config?.cameras[a]?.ui?.order ?? 0) -
(config?.cameras[b]?.ui?.order ?? 0),
),
}),
[allowedCameras],
[config, allowedCameras],
);
const groups = useMemo(() => {
@@ -127,12 +127,16 @@ export default function SearchFilterGroup({
const filterValues = useMemo(
() => ({
cameras: allowedCameras,
cameras: [...allowedCameras].sort(
(a, b) =>
(config?.cameras[a]?.ui?.order ?? 0) -
(config?.cameras[b]?.ui?.order ?? 0),
),
labels: Object.values(allLabels || {}),
zones: Object.values(allZones || {}),
search_type: ["thumbnail", "description"] as SearchSource[],
}),
[allLabels, allZones, allowedCameras],
[config, allLabels, allZones, allowedCameras],
);
const availableSortTypes = useMemo(() => {
@@ -53,8 +53,12 @@ export default function CreateRoleDialog({
const { t } = useTranslation(["views/settings"]);
const [isLoading, setIsLoading] = useState<boolean>(false);
const cameras = Object.keys(config.cameras || {}).filter(
(name) => !isReplayCamera(name),
const cameras = Object.keys(config.cameras || {})
.filter((name) => !isReplayCamera(name))
.sort(
(a, b) =>
(config.cameras[a]?.ui?.order ?? 0) -
(config.cameras[b]?.ui?.order ?? 0),
);
const existingRoles = Object.keys(config.auth?.roles || {});
@@ -47,8 +47,12 @@ export default function EditRoleCamerasDialog({
const { t } = useTranslation(["views/settings"]);
const [isLoading, setIsLoading] = useState<boolean>(false);
const cameras = Object.keys(config.cameras || {}).filter(
(name) => !isReplayCamera(name),
const cameras = Object.keys(config.cameras || {})
.filter((name) => !isReplayCamera(name))
.sort(
(a, b) =>
(config.cameras[a]?.ui?.order ?? 0) -
(config.cameras[b]?.ui?.order ?? 0),
);
const formSchema = z.object({
@@ -39,7 +39,9 @@ export default function ObjectPathPlotter() {
const cameraNames = useMemo(() => {
if (!config) return [];
return Object.keys(config.cameras).filter((name) => !isReplayCamera(name));
return Object.keys(config.cameras)
.filter((name) => !isReplayCamera(name))
.sort((a, b) => config.cameras[a].ui.order - config.cameras[b].ui.order);
}, [config]);
useEffect(() => {
@@ -96,7 +96,7 @@ export default function CloneCameraDialog({
if (!config) return [];
return Object.keys(config.cameras)
.filter((c) => !isReplayCamera(c))
.sort();
.sort((a, b) => config.cameras[a].ui.order - config.cameras[b].ui.order);
}, [config]);
const formSchema = useMemo(() => {
@@ -176,7 +176,7 @@ export default function CloneCameraDialog({
if (!config) return [];
return Object.keys(config.cameras)
.filter((c) => c !== sourceCamera && !isReplayCamera(c))
.sort();
.sort((a, b) => config.cameras[a].ui.order - config.cameras[b].ui.order);
}, [config, sourceCamera]);
const srcCfg = config?.cameras?.[sourceCamera];
+1 -1
View File
@@ -169,7 +169,7 @@ export default function WsMessageFeed({
const cam = config.cameras[name];
return !isReplayCamera(name) && cam.enabled_in_config;
})
.sort();
.sort((a, b) => config.cameras[a].ui.order - config.cameras[b].ui.order);
}, [config]);
const filteredMessages = useMemo(() => {
+7 -5
View File
@@ -75,11 +75,13 @@ export default function Events() {
return [] as string[];
}
return Object.keys(config.cameras).filter(
(cam) =>
allowedCameras.includes(cam) &&
config.cameras[cam]?.ui?.review !== false,
);
return Object.values(config.cameras)
.filter(
(conf) =>
allowedCameras.includes(conf.name) && conf.ui?.review !== false,
)
.sort((aConf, bConf) => aConf.ui.order - bConf.ui.order)
.map((conf) => conf.name);
}, [allowedCameras, config?.cameras]);
const selectedMotionSearchCamera = useMemo(() => {
+3 -3
View File
@@ -30,9 +30,9 @@ export default function MotionSearch() {
const cameras = useMemo(() => {
if (!config?.cameras) return [];
return Object.keys(config.cameras).filter((cam) =>
allowedCameras.includes(cam),
);
return Object.keys(config.cameras)
.filter((cam) => allowedCameras.includes(cam))
.sort((a, b) => config.cameras[a].ui.order - config.cameras[b].ui.order);
}, [config?.cameras, allowedCameras]);
// Selected camera state
@@ -208,7 +208,12 @@ export default function CameraManagementView({
!config.cameras[camera].enabled_in_config &&
!isReplayCamera(camera),
)
.sort();
.sort((a, b) => {
const orderA = config.cameras[a].ui?.order ?? 0;
const orderB = config.cameras[b].ui?.order ?? 0;
if (orderA !== orderB) return orderA - orderB;
return a.localeCompare(b);
});
}
return [];
}, [config]);
@@ -217,7 +222,12 @@ export default function CameraManagementView({
if (config) {
return Object.keys(config.cameras)
.filter((camera) => !isReplayCamera(camera))
.sort();
.sort((a, b) => {
const orderA = config.cameras[a].ui?.order ?? 0;
const orderB = config.cameras[b].ui?.order ?? 0;
if (orderA !== orderB) return orderA - orderB;
return a.localeCompare(b);
});
}
return [];
}, [config]);
@@ -140,6 +140,7 @@ export default function FrigatePlusSettingsView(_props: SettingsPageProps) {
<tbody>
{Object.entries(config.cameras)
.filter(([name]) => !isReplayCamera(name))
.sort(([, a], [, b]) => a.ui.order - b.ui.order)
.map(([name, camera]) => (
<tr
key={name}
+6 -2
View File
@@ -148,7 +148,7 @@ export default function ProfilesView({
const data: Record<string, Record<string, string[]>> = {};
const cameras = Object.keys(config.cameras)
.filter((name) => !isReplayCamera(name))
.sort();
.sort((a, b) => config.cameras[a].ui.order - config.cameras[b].ui.order);
for (const profile of allProfileNames) {
data[profile] = {};
@@ -474,7 +474,11 @@ export default function ProfilesView({
const color = getProfileColor(profile, allProfileNames);
const isActive = activeProfile === profile;
const cameraData = profileOverviewData[profile] ?? {};
const cameras = Object.keys(cameraData).sort();
const cameras = Object.keys(cameraData).sort(
(a, b) =>
(config?.cameras[a]?.ui?.order ?? 0) -
(config?.cameras[b]?.ui?.order ?? 0),
);
const isExpanded = expandedProfiles.has(profile);
return (
+13 -13
View File
@@ -316,7 +316,9 @@ export default function CameraMetrics({
</div>
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
{config &&
Object.values(config.cameras).map((camera) => {
Object.values(config.cameras)
.sort((a, b) => a.ui.order - b.ui.order)
.map((camera) => {
if (camera.enabled && !isReplayCamera(camera.name)) {
return (
<Fragment key={camera.name}>
@@ -339,24 +341,22 @@ export default function CameraMetrics({
] && (
<ConnectionQualityIndicator
quality={
statsHistory[statsHistory.length - 1]?.cameras[
camera.name
]?.connection_quality
statsHistory[statsHistory.length - 1]
?.cameras[camera.name]?.connection_quality
}
expectedFps={
statsHistory[statsHistory.length - 1]?.cameras[
camera.name
]?.expected_fps || 0
statsHistory[statsHistory.length - 1]
?.cameras[camera.name]?.expected_fps || 0
}
reconnects={
statsHistory[statsHistory.length - 1]?.cameras[
camera.name
]?.reconnects_last_hour || 0
statsHistory[statsHistory.length - 1]
?.cameras[camera.name]
?.reconnects_last_hour || 0
}
stalls={
statsHistory[statsHistory.length - 1]?.cameras[
camera.name
]?.stalls_last_hour || 0
statsHistory[statsHistory.length - 1]
?.cameras[camera.name]?.stalls_last_hour ||
0
}
/>
)}