mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-07-05 11:31:13 +03:00
Sync state back to snapshot when child form un-modifies and remount on undo
This commit is contained in:
parent
7f550e5d07
commit
8fd9726220
@ -120,6 +120,7 @@ export default function DetectorsAndModelSettingsView({
|
|||||||
const [snapshot, setSnapshot] = useState<PageState | null>(null);
|
const [snapshot, setSnapshot] = useState<PageState | null>(null);
|
||||||
const [state, setState] = useState<PageState | null>(null);
|
const [state, setState] = useState<PageState | null>(null);
|
||||||
const [isSaving, setIsSaving] = useState(false);
|
const [isSaving, setIsSaving] = useState(false);
|
||||||
|
const [resetKey, setResetKey] = useState(0);
|
||||||
const [restartDialogOpen, setRestartDialogOpen] = useState(false);
|
const [restartDialogOpen, setRestartDialogOpen] = useState(false);
|
||||||
const { send: sendRestart } = useRestart();
|
const { send: sendRestart } = useRestart();
|
||||||
const [childPending, setChildPending] = useState<
|
const [childPending, setChildPending] = useState<
|
||||||
@ -225,21 +226,28 @@ export default function DetectorsAndModelSettingsView({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const detectorsPending = childPending["detectors"];
|
const detectorsPending = childPending["detectors"];
|
||||||
if (detectorsPending) {
|
setState((prev) => {
|
||||||
setState((prev) =>
|
if (!prev || !snapshot) return prev;
|
||||||
prev ? { ...prev, detectors: detectorsPending } : prev,
|
// When the embedded form un-modifies (data returns to baseline) it clears
|
||||||
);
|
// its entry from childPending — fall back to snapshot so state.detectors
|
||||||
}
|
// doesn't keep a stale value the user has visually reverted.
|
||||||
|
return {
|
||||||
|
...prev,
|
||||||
|
detectors: detectorsPending ?? snapshot.detectors,
|
||||||
|
};
|
||||||
|
});
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [childPending["detectors"]]);
|
}, [childPending["detectors"]]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const modelPending = childPending["model"];
|
const modelPending = childPending["model"];
|
||||||
if (modelPending) {
|
setState((prev) => {
|
||||||
setState((prev) =>
|
if (!prev || !snapshot) return prev;
|
||||||
prev ? { ...prev, customModel: modelPending } : prev,
|
return {
|
||||||
);
|
...prev,
|
||||||
}
|
customModel: modelPending ?? snapshot.customModel,
|
||||||
|
};
|
||||||
|
});
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [childPending["model"]]);
|
}, [childPending["model"]]);
|
||||||
|
|
||||||
@ -308,6 +316,7 @@ export default function DetectorsAndModelSettingsView({
|
|||||||
// Re-derive snapshot from the freshly saved state so isDirty resets.
|
// Re-derive snapshot from the freshly saved state so isDirty resets.
|
||||||
setSnapshot({ ...state });
|
setSnapshot({ ...state });
|
||||||
setChildPending({});
|
setChildPending({});
|
||||||
|
setResetKey((k) => k + 1);
|
||||||
|
|
||||||
if (detectorChanged) {
|
if (detectorChanged) {
|
||||||
toast.success(t("detectorsAndModel.toast.saveSuccessRestart"), {
|
toast.success(t("detectorsAndModel.toast.saveSuccessRestart"), {
|
||||||
@ -344,6 +353,10 @@ export default function DetectorsAndModelSettingsView({
|
|||||||
if (snapshot) {
|
if (snapshot) {
|
||||||
setState(snapshot);
|
setState(snapshot);
|
||||||
setChildPending({});
|
setChildPending({});
|
||||||
|
// Force the embedded forms to re-mount so their internal dirty/baseline
|
||||||
|
// state is rebuilt from the current config — clearing childPending alone
|
||||||
|
// doesn't reset BaseSection's internal tracking.
|
||||||
|
setResetKey((k) => k + 1);
|
||||||
}
|
}
|
||||||
}, [snapshot]);
|
}, [snapshot]);
|
||||||
|
|
||||||
@ -393,6 +406,7 @@ export default function DetectorsAndModelSettingsView({
|
|||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<SettingsGroupCard title={t("detectorsAndModel.cardTitles.detector")}>
|
<SettingsGroupCard title={t("detectorsAndModel.cardTitles.detector")}>
|
||||||
<ConfigSectionTemplate
|
<ConfigSectionTemplate
|
||||||
|
key={`detectors-${resetKey}`}
|
||||||
sectionKey="detectors"
|
sectionKey="detectors"
|
||||||
level="global"
|
level="global"
|
||||||
showOverrideIndicator={false}
|
showOverrideIndicator={false}
|
||||||
@ -591,6 +605,7 @@ export default function DetectorsAndModelSettingsView({
|
|||||||
|
|
||||||
<TabsContent value="custom">
|
<TabsContent value="custom">
|
||||||
<ConfigSectionTemplate
|
<ConfigSectionTemplate
|
||||||
|
key={`model-${resetKey}`}
|
||||||
sectionKey="model"
|
sectionKey="model"
|
||||||
level="global"
|
level="global"
|
||||||
showOverrideIndicator={false}
|
showOverrideIndicator={false}
|
||||||
@ -604,6 +619,7 @@ export default function DetectorsAndModelSettingsView({
|
|||||||
</Tabs>
|
</Tabs>
|
||||||
) : (
|
) : (
|
||||||
<ConfigSectionTemplate
|
<ConfigSectionTemplate
|
||||||
|
key={`model-${resetKey}`}
|
||||||
sectionKey="model"
|
sectionKey="model"
|
||||||
level="global"
|
level="global"
|
||||||
showOverrideIndicator={false}
|
showOverrideIndicator={false}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user