settings forms to prevent it from revert user changed

This commit is contained in:
Carter 2026-07-17 14:58:31 -06:00
parent 80750bd3e9
commit ddd0b5062b
3 changed files with 38 additions and 67 deletions

View file

@ -213,15 +213,13 @@ export default function ComponentSettings(props: Props) {
)
);
setFormComponent(initComponent);
setExcludedNodes(initComponent.settings.excludedNodes)
setExcludedNodes(cloneDeep(initComponent.settings.excludedNodes));
}, [props.component, componentTypeOptions]);
useEffect(() => {
if (isDialogOpen && prevIsDialogOpen) return;
if (props.component !== prevComponent || isDialogOpen !== prevIsDialogOpen) {
if (!isDialogOpen || prevIsDialogOpen) return;
init();
}
}, [props.component, prevComponent, init, isDialogOpen, prevIsDialogOpen]);
}, [init, isDialogOpen, prevIsDialogOpen]);
const close = () => {
closeDialogCallback();

View file

@ -31,6 +31,7 @@ import LinearMutationBuilder from "common/LinearMutationBuilder";
import { makeStyles } from "@mui/styles";
import { useNavigate } from "react-router-dom";
import CancelSubmit from "common/CancelSubmit";
import { cloneDeep } from "lodash";
interface TabPanelProps {
children?: React.ReactNode;
@ -94,7 +95,6 @@ export default function DeviceSettings(props: Props) {
const { success, error } = useSnackbar();
const deviceAPI = useDeviceAPI();
const { device, isDialogOpen, closeDialogCallback, canEdit, refreshCallback, components } = props;
const prevDevice = usePrevious(device);
const prevIsDialogOpen = usePrevious(isDialogOpen);
const [deviceForm, setDeviceForm] = useState<Device>(deviceFromForm(Device.clone(device)));
const [isRemoveDeviceDialogOpen, setIsRemoveDeviceDialogOpen] = useState<boolean>(false);
@ -103,7 +103,9 @@ export default function DeviceSettings(props: Props) {
const [compExtTwo, setCompExtTwo] = useState("");
const [compExtThree, setCompExtThree] = useState("");
const [currentTab, setCurrentTab] = useState(0);
const [linearMutations, setLinearMutations] = useState<pond.LinearMutation[]>([]);
const [linearMutations, setLinearMutations] = useState<pond.LinearMutation[]>(
cloneDeep(device.settings.mutations)
);
const [componentsByDevice, setComponentsByDevice] = useState<Map<string, Component[]>>(
new Map<string, Component[]>()
);
@ -111,28 +113,22 @@ export default function DeviceSettings(props: Props) {
const [existingMutation, setExistingMutation] = useState<pond.LinearMutation>();
useEffect(() => {
if (isDialogOpen && prevIsDialogOpen) return;
if (prevDevice !== device || isDialogOpen !== prevIsDialogOpen) {
setDeviceForm(deviceFromForm(Device.clone(props.device)));
if (device.settings.extensionComponents[0]) {
setCompExtOne(device.settings.extensionComponents[0]);
}
if (device.settings.extensionComponents[1]) {
setCompExtTwo(device.settings.extensionComponents[1]);
}
if (device.settings.extensionComponents[2]) {
setCompExtThree(device.settings.extensionComponents[2]);
}
if (device.settings.mutations) {
setLinearMutations(device.settings.mutations);
}
if (!isDialogOpen || prevIsDialogOpen) return;
const settingsForm = deviceFromForm(Device.clone(device));
setDeviceForm(settingsForm);
setSleeps(settingsForm.settings.sleepDurationS > 0);
setCompExtOne(settingsForm.settings.extensionComponents[0] ?? "");
setCompExtTwo(settingsForm.settings.extensionComponents[1] ?? "");
setCompExtThree(settingsForm.settings.extensionComponents[2] ?? "");
setLinearMutations(cloneDeep(settingsForm.settings.mutations));
if (components) {
let cbd = new Map<string, Component[]>();
cbd.set(device.id().toString(), components);
cbd.set(settingsForm.id().toString(), components);
setComponentsByDevice(cbd);
}
}
}, [device, prevDevice, props.device, components, isDialogOpen, prevIsDialogOpen]);
}, [device, components, isDialogOpen, prevIsDialogOpen]);
const close = () => {
closeDialogCallback();
@ -147,7 +143,7 @@ export default function DeviceSettings(props: Props) {
const minCheckPeriodS = (): number => {
let defaultPeriod = 60;
switch (device.settings.platform) {
switch (deviceForm.settings.platform) {
case pond.DevicePlatform.DEVICE_PLATFORM_ELECTRON:
return user.hasFeature("admin") ? defaultPeriod : 300;
default:
@ -319,7 +315,7 @@ export default function DeviceSettings(props: Props) {
id="name"
name="name"
label="Name"
defaultValue={deviceForm.settings.name}
value={deviceForm.settings.name}
onChange={changeName}
margin="normal"
variant="outlined"
@ -332,7 +328,7 @@ export default function DeviceSettings(props: Props) {
id="description"
name="description"
label="Description"
defaultValue={deviceForm.settings.description}
value={deviceForm.settings.description}
onChange={changeDescription}
multiline
rows={2}
@ -550,8 +546,8 @@ export default function DeviceSettings(props: Props) {
const mutationsContent = () => {
let mutations: JSX.Element[] = [];
if (device.settings.mutations) {
device.settings.mutations.forEach((mut, i) => {
if (linearMutations) {
linearMutations.forEach((mut, i) => {
mutations.push(
<ListItem key={"mutation" + i}>
<Grid
@ -568,9 +564,7 @@ export default function DeviceSettings(props: Props) {
variant="contained"
style={{ backgroundColor: "red" }}
onClick={() => {
let lm = linearMutations;
lm.splice(i, 1);
setLinearMutations([...lm]);
setLinearMutations(linearMutations.filter((_, index) => index !== i));
}}>
Remove
</Button>
@ -696,9 +690,7 @@ export default function DeviceSettings(props: Props) {
setNewMutationDialog(false);
}}
onSubmit={newMutation => {
let lm = linearMutations;
lm.push(newMutation);
setLinearMutations(lm);
setLinearMutations([...linearMutations, newMutation]);
}}
/>
</React.Fragment>

View file

@ -32,7 +32,6 @@ import moment from "moment-timezone";
import {
componentIDToString,
emptyComponentId,
getComponentIDString,
sameComponentID,
stringToComponentId
} from "pbHelpers/Component";
@ -130,9 +129,6 @@ export default function InteractionSettings(props: Props) {
} = props;
const theme = useTheme();
const { success, error } = useSnackbar();
const prevInitialInteraction = usePrevious(initialInteraction);
const prevComponents = usePrevious(components);
const prevInitialComponent = usePrevious(initialComponent);
const prevIsDialogOpen = usePrevious(isDialogOpen);
const classes = useStyles();
const [{ user, as }] = useGlobalState();
@ -167,7 +163,7 @@ export default function InteractionSettings(props: Props) {
const setDefaultState = useCallback(() => {
let interaction = getDefaultInteraction();
if (initialInteraction && mode === "update") {
interaction = initialInteraction;
interaction = Interaction.clone(initialInteraction);
if (interaction.settings.subtype === 0 || interaction.settings.subtype === 1) {
setSubtypeDropdown(interaction.settings.subtype);
} else {
@ -223,7 +219,7 @@ export default function InteractionSettings(props: Props) {
setDutyCycle(interactionResult.dutyCycle.toString());
setMappedComponents(mappedComponents);
setInteraction(interaction);
}, [components, initialComponent, initialConditions, initialInteraction, mode, /*sensor*/]);
}, [components, initialComponent, initialConditions, initialInteraction, mode, sensor, user]);
const availableSources = () => {
return components.filter(component => isSource(component.settings.type));
@ -233,27 +229,12 @@ export default function InteractionSettings(props: Props) {
if (user && user.settings.timezone) {
setTimezone(user.settings.timezone);
}
if (isDialogOpen && prevIsDialogOpen) return;
if (
prevInitialInteraction !== initialInteraction ||
(prevComponents && prevComponents.length !== components.length) ||
getComponentIDString(prevInitialComponent) !== getComponentIDString(initialComponent) ||
isDialogOpen !== prevIsDialogOpen
) {
}, [user]);
useEffect(() => {
if (!isDialogOpen || prevIsDialogOpen) return;
setDefaultState();
}
}, [
components.length,
initialComponent,
initialInteraction,
prevComponents,
prevInitialComponent,
prevInitialInteraction,
setDefaultState,
user,
isDialogOpen,
prevIsDialogOpen
]);
}, [isDialogOpen, prevIsDialogOpen, setDefaultState]);
const getAvailableSinks = () => {
let type = or(interaction.settings.result, pond.InteractionResult.create()).type;