Miscellaneous fixes (#23009)
CI / AMD64 Build (push) Has been cancelled
CI / ARM Build (push) Has been cancelled
CI / Jetson Jetpack 6 (push) Has been cancelled
CI / AMD64 Extra Build (push) Has been cancelled
CI / ARM Extra Build (push) Has been cancelled
CI / Assemble and push default build (push) Has been cancelled
CI / Synaptics Build (push) Has been cancelled

* Reduce max frames per second to 1

* Use pydantic but don't fail if some constraints are not met.

* Adjust limits

* Adjust limits

* Cleanup

* add unsaved changes icon/popover to individual settings section

* allow changing camera friendly_name from camera management pane

---------

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>
This commit is contained in:
Nicolas Mowen
2026-04-26 17:09:35 -05:00
committed by GitHub
co-authored by Josh Hawkins
parent 0ea8924727
commit 4171efcd79
9 changed files with 267 additions and 87 deletions
@@ -65,10 +65,14 @@ import {
globalCameraDefaultSections,
buildOverrides,
buildConfigDataForPath,
flattenOverrides,
getBaseCameraSectionValue,
sanitizeSectionData as sharedSanitizeSectionData,
requiresRestartForOverrides as sharedRequiresRestartForOverrides,
} from "@/utils/configUtil";
import SaveAllPreviewPopover, {
type SaveAllPreviewItem,
} from "@/components/overlay/detail/SaveAllPreviewPopover";
import RestartDialog from "@/components/overlay/dialog/RestartDialog";
import { useRestart } from "@/api/ws";
import type {
@@ -913,6 +917,34 @@ export function ConfigSection({
);
}, [sectionConfig?.renderers, sectionPath, cameraName, setPendingData]);
// Build a flat list of pending field changes for this section only.
// Mirrors the global Save All preview but scoped to the current section so
// users can inspect what will be saved without leaving the section.
const sectionPreviewItems = useMemo<SaveAllPreviewItem[]>(() => {
if (!hasChanges) return [];
if (!effectiveOverrides || typeof effectiveOverrides !== "object") {
return [];
}
const flattened = flattenOverrides(effectiveOverrides as JsonValue);
return flattened.map(({ path, value }) => ({
scope: effectiveLevel,
cameraName,
profileName: profileName
? (profileFriendlyName ?? profileName)
: undefined,
fieldPath: path ? `${sectionPath}.${path}` : sectionPath,
value,
}));
}, [
hasChanges,
effectiveOverrides,
effectiveLevel,
cameraName,
profileName,
profileFriendlyName,
sectionPath,
]);
if (!modifiedSchema) {
return null;
}
@@ -1018,6 +1050,12 @@ export function ConfigSection({
defaultValue: "You have unsaved changes",
})}
</span>
<SaveAllPreviewPopover
items={sectionPreviewItems}
className="h-7 w-7"
align="start"
side="top"
/>
</div>
)}
<div className="flex w-full flex-col gap-2 sm:flex-row sm:items-center md:w-auto">