diff --git a/src/component/ComponentSettings.tsx b/src/component/ComponentSettings.tsx index d66a3c1..ce56e56 100644 --- a/src/component/ComponentSettings.tsx +++ b/src/component/ComponentSettings.tsx @@ -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) { - init(); - } - }, [props.component, prevComponent, init, isDialogOpen, prevIsDialogOpen]); + if (!isDialogOpen || prevIsDialogOpen) return; + init(); + }, [init, isDialogOpen, prevIsDialogOpen]); const close = () => { closeDialogCallback(); diff --git a/src/device/DeviceSettings.tsx b/src/device/DeviceSettings.tsx index 26ca591..32831f5 100644 --- a/src/device/DeviceSettings.tsx +++ b/src/device/DeviceSettings.tsx @@ -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(deviceFromForm(Device.clone(device))); const [isRemoveDeviceDialogOpen, setIsRemoveDeviceDialogOpen] = useState(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([]); + const [linearMutations, setLinearMutations] = useState( + cloneDeep(device.settings.mutations) + ); const [componentsByDevice, setComponentsByDevice] = useState>( new Map() ); @@ -111,28 +113,22 @@ export default function DeviceSettings(props: Props) { const [existingMutation, setExistingMutation] = useState(); 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 (components) { - let cbd = new Map(); - cbd.set(device.id().toString(), components); - setComponentsByDevice(cbd); - } + 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(); + 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( { - let lm = linearMutations; - lm.splice(i, 1); - setLinearMutations([...lm]); + setLinearMutations(linearMutations.filter((_, index) => index !== i)); }}> Remove @@ -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]); }} /> diff --git a/src/interactions/InteractionSettings.tsx b/src/interactions/InteractionSettings.tsx index c98742f..f1f3d8c 100644 --- a/src/interactions/InteractionSettings.tsx +++ b/src/interactions/InteractionSettings.tsx @@ -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 - ) { - setDefaultState(); - } - }, [ - components.length, - initialComponent, - initialInteraction, - prevComponents, - prevInitialComponent, - prevInitialInteraction, - setDefaultState, - user, - isDialogOpen, - prevIsDialogOpen - ]); + }, [user]); + + useEffect(() => { + if (!isDialogOpen || prevIsDialogOpen) return; + setDefaultState(); + }, [isDialogOpen, prevIsDialogOpen, setDefaultState]); const getAvailableSinks = () => { let type = or(interaction.settings.result, pond.InteractionResult.create()).type;