From 53882766d93d4f6c4fd2aacab02cffe6b65eb714 Mon Sep 17 00:00:00 2001 From: Florent MILLOT Date: Wed, 17 Sep 2025 12:37:11 +0200 Subject: [PATCH 1/5] Add callback to populate unset regulation attributes with previous values Signed-off-by: Florent MILLOT --- .../ratio-tap-changer-pane-utils.js | 12 +++++- .../ratio-tap-changer-pane.jsx | 38 +++++++++++++++++-- .../rhf-inputs/boolean-nullable-input.tsx | 15 +++++--- 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane-utils.js b/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane-utils.js index df68dd2301..cf9f4b11b1 100644 --- a/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane-utils.js +++ b/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane-utils.js @@ -285,19 +285,27 @@ export const getInitialTwtRatioRegulationModeId = (twt) => { return computedRegulationMode?.id || null; }; +export const getComputedRegulationModeId = (twt) => { + return getComputedRegulationMode(twt)?.id || null; +}; + export const getComputedPreviousRatioRegulationType = (previousValues) => { const previousRegulationType = getComputedRegulationType(previousValues); return previousRegulationType?.id || null; }; -export const getComputedTapSideId = (twt) => { +export const getComputedTapSide = (twt) => { const ratioTapChangerValues = twt?.ratioTapChanger; if (!ratioTapChangerValues || !twt) { return null; } if (ratioTapChangerValues?.regulatingTerminalConnectableId === twt?.id) { - return ratioTapChangerValues?.regulatingTerminalVlId === twt?.voltageLevelId1 ? SIDE.SIDE1.id : SIDE.SIDE2.id; + return ratioTapChangerValues?.regulatingTerminalVlId === twt?.voltageLevelId1 ? SIDE.SIDE1 : SIDE.SIDE2; } else { return null; } }; + +export const getComputedTapSideId = (twt) => { + return getComputedTapSide(twt)?.id || null; +}; diff --git a/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx b/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx index f0505f9c83..34a520a247 100644 --- a/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx +++ b/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx @@ -16,7 +16,7 @@ import { TARGET_DEADBAND, TARGET_V, } from 'components/utils/field-constants'; -import { useEffect, useMemo } from 'react'; +import { useCallback, useEffect, useMemo } from 'react'; import { useFormContext, useWatch } from 'react-hook-form'; import { useIntl } from 'react-intl'; import { VoltageAdornment } from '../../../../dialog-utils'; @@ -24,7 +24,12 @@ import { FloatInput, SelectInput, SwitchInput } from '@gridsuite/commons-ui'; import RatioTapChangerPaneSteps from './ratio-tap-changer-pane-steps'; import { RATIO_REGULATION_MODES } from 'components/network/constants'; import CheckboxNullableInput from 'components/utils/rhf-inputs/boolean-nullable-input'; -import { getComputedPreviousRatioRegulationType } from './ratio-tap-changer-pane-utils'; +import { + getComputedPreviousRatioRegulationType, + getComputedRegulationModeId, + getComputedRegulationTypeId, + getComputedTapSideId, +} from './ratio-tap-changer-pane-utils'; import GridItem from '../../../../commons/grid-item'; import GridSection from '../../../../commons/grid-section'; import RegulatedTerminalSection from '../regulated-terminal-section'; @@ -39,7 +44,7 @@ const RatioTapChangerPane = ({ editData, isModification = false, }) => { - const { trigger } = useFormContext(); + const { trigger, setValue, getValues } = useFormContext(); const intl = useIntl(); const previousRegulation = () => { @@ -90,6 +95,32 @@ const RatioTapChangerPane = ({ return regulationTypeWatch || getComputedPreviousRatioRegulationType(previousValues); }, [previousValues, regulationTypeWatch]); + // we want to fill the empty fields with the previous values when 'on load' is enabled + const fillRatioTapChangerRegulationAttributesWithPreviousValues = useCallback( + (newValue) => { + if (newValue === true) { + const curRatioTapChanger = getValues(id); + + if (curRatioTapChanger[REGULATION_MODE] === null) { + setValue(`${id}.${REGULATION_MODE}`, getComputedRegulationModeId(previousValues)); + } + if (curRatioTapChanger[REGULATION_TYPE] === null) { + setValue(`${id}.${REGULATION_TYPE}`, getComputedRegulationTypeId(previousValues)); + } + if (curRatioTapChanger[REGULATION_SIDE] === null) { + setValue(`${id}.${REGULATION_SIDE}`, getComputedTapSideId(previousValues)); + } + if (curRatioTapChanger[TARGET_V] === null) { + setValue(`${id}.${TARGET_V}`, previousValues?.ratioTapChanger?.targetV); + } + if (curRatioTapChanger[TARGET_DEADBAND] === null) { + setValue(`${id}.${TARGET_DEADBAND}`, previousValues?.ratioTapChanger?.targetDeadband); + } + } + }, + [id, previousValues, regulationType, setValue, getValues, intl] + ); + // we want to update the validation of these fields when they become optionals to remove the red alert useEffect(() => { if (regulationModeWatch === RATIO_REGULATION_MODES.FIXED_RATIO.id) { @@ -107,6 +138,7 @@ const RatioTapChangerPane = ({ disabled: !ratioTapChangerEnabledWatcher, }} previousValue={previousRegulation()} + onChange={fillRatioTapChangerRegulationAttributesWithPreviousValues} /> ) : ( void; style?: { color: string }; } @@ -29,24 +30,28 @@ const CheckboxNullableInput = ({ formProps, previousValue, nullDisabled, + onChange, style, }: Readonly) => { const { - field: { onChange, value }, + field: { onChange: rhfOnChange, value }, } = useController({ name }); const intl = useIntl(); const { isNodeBuilt, isUpdate } = useCustomFormContext(); const handleChangeValue = useCallback(() => { + let newValue; if (value) { - onChange(null); + newValue = null; } else if (value === null) { - onChange(false); + newValue = false; } else { - onChange(true); + newValue = true; } - }, [onChange, value]); + rhfOnChange(newValue); + onChange?.(newValue); + }, [rhfOnChange, onChange, value]); // Get the current label based on value const currentLabel = typeof label === 'function' ? label(value) : label; From 8d7553231fe5648947b8810da2526245345a3dfa Mon Sep 17 00:00:00 2001 From: Florent MILLOT Date: Wed, 17 Sep 2025 13:00:08 +0200 Subject: [PATCH 2/5] Refactor callback parameter and dependencies in ratio tap changer pane also remove bad dependencies Signed-off-by: Florent MILLOT --- .../ratio-tap-changer-pane/ratio-tap-changer-pane.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx b/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx index 34a520a247..913c51fdba 100644 --- a/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx +++ b/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx @@ -97,8 +97,8 @@ const RatioTapChangerPane = ({ // we want to fill the empty fields with the previous values when 'on load' is enabled const fillRatioTapChangerRegulationAttributesWithPreviousValues = useCallback( - (newValue) => { - if (newValue === true) { + (newOnLoad) => { + if (newOnLoad === true) { const curRatioTapChanger = getValues(id); if (curRatioTapChanger[REGULATION_MODE] === null) { @@ -118,7 +118,7 @@ const RatioTapChangerPane = ({ } } }, - [id, previousValues, regulationType, setValue, getValues, intl] + [id, previousValues, setValue, getValues] ); // we want to update the validation of these fields when they become optionals to remove the red alert From 4a01e3e791bf9a88e04351a6477a88a07e3b858c Mon Sep 17 00:00:00 2001 From: Florent MILLOT Date: Fri, 19 Sep 2025 18:24:58 +0200 Subject: [PATCH 3/5] Extend callback to populate unset voltage level and equipment attributes with previous values Signed-off-by: Florent MILLOT --- .../ratio-tap-changer-pane.jsx | 37 +++++++++++++++++-- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx b/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx index 913c51fdba..053c6ec480 100644 --- a/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx +++ b/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx @@ -8,6 +8,7 @@ import { Grid } from '@mui/material'; import { ENABLED, + EQUIPMENT, LOAD_TAP_CHANGING_CAPABILITIES, RATIO_TAP_CHANGER, REGULATION_MODE, @@ -15,6 +16,7 @@ import { REGULATION_TYPE, TARGET_DEADBAND, TARGET_V, + VOLTAGE_LEVEL, } from 'components/utils/field-constants'; import { useCallback, useEffect, useMemo } from 'react'; import { useFormContext, useWatch } from 'react-hook-form'; @@ -104,17 +106,44 @@ const RatioTapChangerPane = ({ if (curRatioTapChanger[REGULATION_MODE] === null) { setValue(`${id}.${REGULATION_MODE}`, getComputedRegulationModeId(previousValues)); } + if (curRatioTapChanger[TARGET_V] === null) { + setValue(`${id}.${TARGET_V}`, previousValues?.ratioTapChanger?.targetV); + } + if (curRatioTapChanger[TARGET_DEADBAND] === null) { + setValue(`${id}.${TARGET_DEADBAND}`, previousValues?.ratioTapChanger?.targetDeadband); + } if (curRatioTapChanger[REGULATION_TYPE] === null) { setValue(`${id}.${REGULATION_TYPE}`, getComputedRegulationTypeId(previousValues)); } if (curRatioTapChanger[REGULATION_SIDE] === null) { setValue(`${id}.${REGULATION_SIDE}`, getComputedTapSideId(previousValues)); } - if (curRatioTapChanger[TARGET_V] === null) { - setValue(`${id}.${TARGET_V}`, previousValues?.ratioTapChanger?.targetV); + if (curRatioTapChanger[VOLTAGE_LEVEL] === null) { + const prevVl = voltageLevelOptions.find( + (vl) => vl.id === previousValues?.ratioTapChanger?.regulatingTerminalVlId + ); + if (prevVl) { + const newVlValue = { + id: prevVl.id, + label: prevVl.name ?? '', + }; + setValue(`${id}.${VOLTAGE_LEVEL}`, newVlValue); + } else { + // not supposed to happen, but if it does, we want to log it and keep the form as it is + console.error('Voltage level not found:', prevVl); + } } - if (curRatioTapChanger[TARGET_DEADBAND] === null) { - setValue(`${id}.${TARGET_DEADBAND}`, previousValues?.ratioTapChanger?.targetDeadband); + if (curRatioTapChanger[EQUIPMENT] === null) { + const prevEquipmentId = previousValues?.ratioTapChanger?.regulatingTerminalConnectableId; + if (prevEquipmentId) { + const prevEquipmentType = previousValues?.ratioTapChanger?.regulatingTerminalConnectableType; + const newEquipment = { + id: prevEquipmentId, + label: prevEquipmentType, + type: prevEquipmentType, + }; + setValue(`${id}.${EQUIPMENT}`, newEquipment); + } } } }, From 2048db0d6715fd3a8a6eea7cd932eb1e029b88f7 Mon Sep 17 00:00:00 2001 From: Florent MILLOT Date: Mon, 22 Sep 2025 17:54:07 +0200 Subject: [PATCH 4/5] Update dependency array in ratio-tap-changer-pane effect to include voltageLevelOptions Signed-off-by: Florent MILLOT --- .../ratio-tap-changer-pane/ratio-tap-changer-pane.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx b/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx index 053c6ec480..889ca75876 100644 --- a/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx +++ b/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx @@ -147,7 +147,7 @@ const RatioTapChangerPane = ({ } } }, - [id, previousValues, setValue, getValues] + [id, voltageLevelOptions, previousValues, setValue, getValues] ); // we want to update the validation of these fields when they become optionals to remove the red alert From 8748337d4b405acc24e085c371e7e1b3da7e9421 Mon Sep 17 00:00:00 2001 From: Florent MILLOT Date: Tue, 23 Sep 2025 11:24:48 +0200 Subject: [PATCH 5/5] Refactor logic for setting ratio tap changer regulation attributes by splitting into smaller, reusable functions. Signed-off-by: Florent MILLOT --- .../ratio-tap-changer-pane.jsx | 70 ++++++++++++------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx b/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx index 889ca75876..1639257b5b 100644 --- a/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx +++ b/src/components/dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane.jsx @@ -97,6 +97,41 @@ const RatioTapChangerPane = ({ return regulationTypeWatch || getComputedPreviousRatioRegulationType(previousValues); }, [previousValues, regulationTypeWatch]); + const findAndSetVoltageLevelFromPrevious = useCallback( + (previousValues, voltageLevelOptions) => { + const prevVl = voltageLevelOptions.find( + (vl) => vl.id === previousValues?.ratioTapChanger?.regulatingTerminalVlId + ); + if (prevVl) { + const newVlValue = { + id: prevVl.id, + label: prevVl.name ?? '', + }; + setValue(`${id}.${VOLTAGE_LEVEL}`, newVlValue); + } else { + // not supposed to happen, but if it does, we want to log it and keep the form as it is + console.error('Voltage level not found:', prevVl); + } + }, + [setValue, id] + ); + + const setEquipmentFromPrevious = useCallback( + (previousValues) => { + const prevEquipmentId = previousValues?.ratioTapChanger?.regulatingTerminalConnectableId; + if (prevEquipmentId) { + const prevEquipmentType = previousValues?.ratioTapChanger?.regulatingTerminalConnectableType; + const newEquipment = { + id: prevEquipmentId, + label: prevEquipmentType, + type: prevEquipmentType, + }; + setValue(`${id}.${EQUIPMENT}`, newEquipment); + } + }, + [setValue, id] + ); + // we want to fill the empty fields with the previous values when 'on load' is enabled const fillRatioTapChangerRegulationAttributesWithPreviousValues = useCallback( (newOnLoad) => { @@ -119,35 +154,22 @@ const RatioTapChangerPane = ({ setValue(`${id}.${REGULATION_SIDE}`, getComputedTapSideId(previousValues)); } if (curRatioTapChanger[VOLTAGE_LEVEL] === null) { - const prevVl = voltageLevelOptions.find( - (vl) => vl.id === previousValues?.ratioTapChanger?.regulatingTerminalVlId - ); - if (prevVl) { - const newVlValue = { - id: prevVl.id, - label: prevVl.name ?? '', - }; - setValue(`${id}.${VOLTAGE_LEVEL}`, newVlValue); - } else { - // not supposed to happen, but if it does, we want to log it and keep the form as it is - console.error('Voltage level not found:', prevVl); - } + findAndSetVoltageLevelFromPrevious(previousValues, voltageLevelOptions); } if (curRatioTapChanger[EQUIPMENT] === null) { - const prevEquipmentId = previousValues?.ratioTapChanger?.regulatingTerminalConnectableId; - if (prevEquipmentId) { - const prevEquipmentType = previousValues?.ratioTapChanger?.regulatingTerminalConnectableType; - const newEquipment = { - id: prevEquipmentId, - label: prevEquipmentType, - type: prevEquipmentType, - }; - setValue(`${id}.${EQUIPMENT}`, newEquipment); - } + setEquipmentFromPrevious(previousValues); } } }, - [id, voltageLevelOptions, previousValues, setValue, getValues] + [ + id, + voltageLevelOptions, + previousValues, + setValue, + getValues, + findAndSetVoltageLevelFromPrevious, + setEquipmentFromPrevious, + ] ); // we want to update the validation of these fields when they become optionals to remove the red alert