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 && ( + + )} - )} - +
-
+ )}