diff --git a/web/src/components/config-form/sections/BaseSection.tsx b/web/src/components/config-form/sections/BaseSection.tsx
index 6c32ffae6a..cd14047693 100644
--- a/web/src/components/config-form/sections/BaseSection.tsx
+++ b/web/src/components/config-form/sections/BaseSection.tsx
@@ -175,6 +175,9 @@ export interface BaseSectionProps {
isSavingAll?: boolean;
/** Callback when this section's saving state changes */
onSavingChange?: (isSaving: boolean) => void;
+ /** When true, render the form fields only; suppress the internal save/undo bar.
+ * The parent owns the save action and reads pending data via `onPendingDataChange`. */
+ embedded?: boolean;
}
export interface CreateSectionOptions {
@@ -211,6 +214,7 @@ export function ConfigSection({
onDeleteProfileSection,
isSavingAll = false,
onSavingChange,
+ embedded = false,
}: ConfigSectionProps) {
// For replay level, treat as camera-level config access
const effectiveLevel = level === "replay" ? "camera" : level;
@@ -1048,121 +1052,123 @@ export function ConfigSection({
}}
/>
-
+ {!embedded && (
- {hasChanges && (
-
-
- {t("unsavedChanges", {
- ns: "views/settings",
- defaultValue: "You have unsaved changes",
- })}
-
-
-
- )}
-
- {((effectiveLevel === "camera" && isOverridden) ||
- effectiveLevel === "global") &&
- !hasChanges &&
- !skipSave &&
- !profileName && (
-
- )}
- {profileName &&
- profileOverridesSection &&
- !hasChanges &&
- !skipSave &&
- onDeleteProfileSection && (
-
- )}
+
{hasChanges && (
+
+
+ {t("unsavedChanges", {
+ ns: "views/settings",
+ defaultValue: "You have unsaved changes",
+ })}
+
+
+
+ )}
+
+ {((effectiveLevel === "camera" && isOverridden) ||
+ effectiveLevel === "global") &&
+ !hasChanges &&
+ !skipSave &&
+ !profileName && (
+
+ )}
+ {profileName &&
+ profileOverridesSection &&
+ !hasChanges &&
+ !skipSave &&
+ onDeleteProfileSection && (
+
+ )}
+ {hasChanges && (
+
+ )}
- )}
-
+
-
+ )}