diff --git a/package-lock.json b/package-lock.json index 5e1021c5b1..7138316b65 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", - "@gridsuite/commons-ui": "0.284.0", + "@gridsuite/commons-ui": "0.285.0", "@hello-pangea/dnd": "^18.0.1", "@hookform/resolvers": "^4.1.3", "@mui/icons-material": "^7.3.11", @@ -2944,9 +2944,9 @@ } }, "node_modules/@gridsuite/commons-ui": { - "version": "0.284.0", - "resolved": "https://registry.npmjs.org/@gridsuite/commons-ui/-/commons-ui-0.284.0.tgz", - "integrity": "sha512-EQLUSpkUi4M87mgk2wEBQXOWDf0Tf+cplguibRuyrkcpwNXlIx2Xn2QJLmB2eb8jFgEn3vrI8ddpXvosaxoGEA==", + "version": "0.285.0", + "resolved": "https://registry.npmjs.org/@gridsuite/commons-ui/-/commons-ui-0.285.0.tgz", + "integrity": "sha512-Sv8DsqHE66caz6aAoD0poeioBMhVsc2SIPzJU/g8p5bIlymGFnfY7bznt00vxDGchiIWWDyW6L6fLkbLqdMnUg==", "license": "MPL-2.0", "dependencies": { "@ag-grid-community/locale": "^35.3.1", diff --git a/package.json b/package.json index 9425048fe7..62427d6b17 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", - "@gridsuite/commons-ui": "0.284.0", + "@gridsuite/commons-ui": "0.285.0", "@hello-pangea/dnd": "^18.0.1", "@hookform/resolvers": "^4.1.3", "@mui/icons-material": "^7.3.11", diff --git a/src/components/dialogs/network-modifications/hvdc-line/lcc/common/lcc-hvdc-line.tsx b/src/components/dialogs/network-modifications/hvdc-line/lcc/common/lcc-hvdc-line.tsx index 5e1d5bbc0d..253ee55f5d 100644 --- a/src/components/dialogs/network-modifications/hvdc-line/lcc/common/lcc-hvdc-line.tsx +++ b/src/components/dialogs/network-modifications/hvdc-line/lcc/common/lcc-hvdc-line.tsx @@ -13,9 +13,10 @@ import { PropertiesForm, SelectInput, VoltageAdornment, + VSC_CONVERTER_MODE, + VscConverterMode, } from '@gridsuite/commons-ui'; import { ACTIVE_POWER_SETPOINT, CONVERTERS_MODE, MAX_P, NOMINAL_V, R } from '../../../../../utils/field-constants'; -import { VSC_CONVERTER_MODE, VscConverterMode } from 'components/network/constants'; import { Grid } from '@mui/material'; import { GridItem } from '../../../../commons/grid-item'; import { LccFormInfos } from './lcc-type'; diff --git a/src/components/dialogs/network-modifications/hvdc-line/vsc/converter-station/converter-station-pane.tsx b/src/components/dialogs/network-modifications/hvdc-line/vsc/converter-station/converter-station-pane.tsx deleted file mode 100644 index b8c890bed6..0000000000 --- a/src/components/dialogs/network-modifications/hvdc-line/vsc/converter-station/converter-station-pane.tsx +++ /dev/null @@ -1,220 +0,0 @@ -/** - * Copyright (c) 2023, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import { FunctionComponent, useCallback, useEffect } from 'react'; -import { - CheckboxNullableInput, - ConnectivityForm, - FieldConstants, - FloatInput, - GridSection, - PercentageAdornment, - ReactiveLimitsForm, - ReactivePowerAdornment, - SwitchInput, - TextInput, - VoltageAdornment, -} from '@gridsuite/commons-ui'; -import { - CONNECTIVITY, - CONVERTER_STATION_ID, - CONVERTER_STATION_NAME, - LOSS_FACTOR, - REACTIVE_POWER, - VOLTAGE, - VOLTAGE_REGULATION_ON, -} from '../../../../../utils/field-constants'; -import type { UUID } from 'node:crypto'; -import { Grid, TextField } from '@mui/material'; -import { useFormContext, useWatch } from 'react-hook-form'; -import { UpdateReactiveCapabilityCurveTable } from './converter-station-utils'; -import { useIntl } from 'react-intl'; -import useVoltageLevelsListInfos from '../../../../../../hooks/use-voltage-levels-list-infos'; -import { GridItem } from '../../../../commons/grid-item'; -import { ConverterStationElementModificationInfos } from './converter-station-type'; -import { CurrentTreeNode } from '../../../../../graph/tree-node.type'; -import PositionDiagramPane from '../../../../../grid-layout/cards/diagrams/singleLineDiagram/positionDiagram/position-diagram-pane'; -import { fetchBusesOrBusbarSectionsForVoltageLevel } from '../../../../../../services/study/network'; - -interface VscConverterStationPaneProps { - id: string; - stationLabel: string; - currentNode: CurrentTreeNode; - studyUuid: UUID; - currentRootNetworkUuid: UUID; - isModification?: boolean; - previousValues?: ConverterStationElementModificationInfos | null; - updatePreviousReactiveCapabilityCurveTableConverterStation?: UpdateReactiveCapabilityCurveTable; -} - -const ConverterStationPane: FunctionComponent = ({ - id, - stationLabel, - currentNode, - studyUuid, - currentRootNetworkUuid, - isModification = false, - previousValues, - updatePreviousReactiveCapabilityCurveTableConverterStation, -}) => { - const intl = useIntl(); - - const { trigger } = useFormContext(); - - const fetchBusesOrBusbarSections = useCallback( - (voltageLevelId: string) => - fetchBusesOrBusbarSectionsForVoltageLevel( - studyUuid, - currentNode.id, - currentRootNetworkUuid, - voltageLevelId - ), - [studyUuid, currentNode.id, currentRootNetworkUuid] - ); - - const voltageRegulationOnWatch = useWatch({ - name: `${id}.${VOLTAGE_REGULATION_ON}`, - }); - - useEffect(() => { - if (!voltageRegulationOnWatch) { - trigger(`${id}.${VOLTAGE_REGULATION_ON}`); - } - }); - - const voltageLevelOptions = useVoltageLevelsListInfos(studyUuid, currentNode?.id, currentRootNetworkUuid); - - const generatorIdField = isModification ? ( - - ) : ( - - ); - - const generatorNameField = ( - - ); - - const connectivityForm = ( - - ); - - const lossFactorField = ( - - ); - - const reactivePowerField = ( - - ); - - const previousVoltageRegulatorOn = () => { - return intl.formatMessage({ - id: previousValues?.voltageRegulatorOn ? 'On' : 'Off', - }); - }; - const voltageRegulation = isModification ? ( - - ) : ( - - ); - - const voltageField = ( - - ); - - return ( - - - - {generatorIdField} - {generatorNameField} - - - {!isModification && ( - <> - - - {connectivityForm} - - - )} - - - - {lossFactorField} - - - - - - - - {reactivePowerField} - - - {voltageRegulation} - {voltageField} - - - ); -}; - -export default ConverterStationPane; diff --git a/src/components/dialogs/network-modifications/hvdc-line/vsc/converter-station/converter-station-type.ts b/src/components/dialogs/network-modifications/hvdc-line/vsc/converter-station/converter-station-type.ts deleted file mode 100644 index a300941931..0000000000 --- a/src/components/dialogs/network-modifications/hvdc-line/vsc/converter-station/converter-station-type.ts +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright (c) 2025, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import { - BUS_OR_BUSBAR_SECTION, - CONNECTED, - CONNECTION_DIRECTION, - CONNECTION_NAME, - CONNECTION_POSITION, - CONNECTIVITY, - CONVERTER_STATION_ID, - CONVERTER_STATION_NAME, - ID, - LOSS_FACTOR, - REACTIVE_POWER, - VOLTAGE, - VOLTAGE_LEVEL, - VOLTAGE_REGULATION_ON, -} from '../../../../../utils/field-constants'; -import { - ConnectablePositionInfos, - FieldConstants, - MeasurementInfo, - MinMaxReactiveLimitsFormInfos, - ReactiveCapabilityCurvePoints, -} from '@gridsuite/commons-ui'; - -export interface VscConverterStationFormInfos { - id: string; - name: string | null; - lossFactor: number; - voltageSetpoint: number | null; - reactivePowerSetpoint: number | null; - voltageRegulatorOn: boolean; - voltageLevelId: string; - busOrBusbarSectionId: string; - nominalV: number; - terminalConnected: boolean; - p: number | null; - q: number | null; - reactiveCapabilityCurvePoints: ReactiveCapabilityCurvePoints[]; - minMaxReactiveLimits: MinMaxReactiveLimitsFormInfos | null; - connectablePosition: ConnectablePositionInfos; - reactivePower?: number; - voltageRegulationOn?: boolean; - voltage?: number; - measurementP: MeasurementInfo | undefined; - measurementQ: MeasurementInfo | undefined; -} - -// the backend return a converterStationElementInfo.reactiveCapabilityCurvePoints -// but the form define rename is to reactiveCapabilityCurveTable -// may be we should refactor the forms in Battery , generator and converter station to use the same name -export type ConverterStationElementModificationInfos = Omit< - VscConverterStationFormInfos, - 'reactiveCapabilityCurvePoints' -> & { reactiveCapabilityCurveTable: ReactiveCapabilityCurvePoints[] }; - -export type VscConverterStation = { - [CONVERTER_STATION_ID]: string | null; - [CONVERTER_STATION_NAME]?: string; - [LOSS_FACTOR]: number | null; - [VOLTAGE_REGULATION_ON]?: boolean; - [REACTIVE_POWER]: number | null; - [VOLTAGE]: number | null; - [CONNECTIVITY]?: { - [VOLTAGE_LEVEL]: { [ID]?: string }; - [BUS_OR_BUSBAR_SECTION]: { [ID]?: string }; - [CONNECTION_DIRECTION]?: string; - [CONNECTION_NAME]?: string; - [CONNECTION_POSITION]?: number; - [CONNECTED]?: boolean; - }; - [FieldConstants.REACTIVE_LIMITS]?: { - [FieldConstants.MINIMUM_REACTIVE_POWER]?: number; - [FieldConstants.MAXIMUM_REACTIVE_POWER]?: number; - [FieldConstants.REACTIVE_CAPABILITY_CURVE_CHOICE]: string; - [FieldConstants.REACTIVE_CAPABILITY_CURVE_TABLE]?: ReactiveCapabilityCurvePoints[]; - }; - [FieldConstants.STATE_ESTIMATION]?: { - [FieldConstants.MEASUREMENT_P]?: MeasurementInfo; - [FieldConstants.MEASUREMENT_Q]?: MeasurementInfo; - }; -}; diff --git a/src/components/dialogs/network-modifications/hvdc-line/vsc/converter-station/converter-station-utils.tsx b/src/components/dialogs/network-modifications/hvdc-line/vsc/converter-station/converter-station-utils.tsx deleted file mode 100644 index 398d78be05..0000000000 --- a/src/components/dialogs/network-modifications/hvdc-line/vsc/converter-station/converter-station-utils.tsx +++ /dev/null @@ -1,297 +0,0 @@ -/** - * Copyright (c) 2023, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import { - AttributeModification, - FieldConstants, - getConnectivityFormData, - getConnectivityWithPositionEmptyFormData, - getConnectivityWithPositionValidationSchema, - getInjectionActiveReactivePowerEditDataProperties, - getInjectionActiveReactivePowerEmptyFormDataProperties, - getInjectionActiveReactivePowerValidationSchemaProperties, - getReactiveLimitsEmptyFormData, - getReactiveLimitsFormData, - getReactiveLimitsSchema, - MODIFICATION_TYPES, - MUST_BE_GREATER_OR_EQUAL_TO_ZERO, - NORMALIZED_PERCENTAGE, - ReactiveCapabilityCurvePoints, - sanitizeString, - toModificationOperation, - UNDEFINED_CONNECTION_DIRECTION, -} from '@gridsuite/commons-ui'; -import * as yup from 'yup'; -import { - BUS_OR_BUSBAR_SECTION, - CONNECTED, - CONNECTION_DIRECTION, - CONNECTION_NAME, - CONNECTION_POSITION, - CONNECTIVITY, - CONVERTER_STATION_ID, - CONVERTER_STATION_NAME, - ID, - LOSS_FACTOR, - MEASUREMENT_P, - MEASUREMENT_Q, - REACTIVE_POWER, - STATE_ESTIMATION, - VOLTAGE, - VOLTAGE_LEVEL, - VOLTAGE_REGULATION_ON, -} from '../../../../../utils/field-constants'; -import { VscConverterStationFormInfos, ConverterStationElementModificationInfos } from './converter-station-type'; -import { ConverterStationCreationInfos } from '../../../../../../services/network-modification-types'; - -export type UpdateReactiveCapabilityCurveTable = (action: string, index: number) => void; - -export type UpdateReactiveCapabilityCurveTableConverterStation = ( - action: string, - index: number, - converterStationName: 'converterStation1' | 'converterStation2' -) => void; - -export interface ConverterStationModificationInterfaceEditData { - equipmentId: string; - equipmentName: AttributeModification | null; - lossFactor: AttributeModification | null; - reactivePowerSetpoint?: AttributeModification; - voltageRegulationOn: AttributeModification; - voltageSetpoint?: AttributeModification | null; - voltageLevelId: AttributeModification | null; - busOrBusbarSectionId: AttributeModification | null; - connectionDirection: AttributeModification | null; - connectionName?: AttributeModification | null; - connectionPosition?: AttributeModification | null; - terminalConnected?: AttributeModification | null; - reactiveCapabilityCurvePoints: ReactiveCapabilityCurvePoints[]; - reactiveCapabilityCurve: AttributeModification | null; - minQ: AttributeModification | null; - maxQ: AttributeModification | null; -} - -export function getVscConverterStationSchema() { - return yup.object().shape({ - [CONVERTER_STATION_ID]: yup.string().nullable().required(), - [CONVERTER_STATION_NAME]: yup.string().nullable(), - [LOSS_FACTOR]: yup.number().nullable().required().min(0, NORMALIZED_PERCENTAGE).max(100, NORMALIZED_PERCENTAGE), - [VOLTAGE_REGULATION_ON]: yup.boolean(), - [REACTIVE_POWER]: yup - .number() - .nullable() - .default(null) - .when([VOLTAGE_REGULATION_ON], { - is: false, - then: (schema) => schema.required(), - }), - [VOLTAGE]: yup - .number() - .nullable() - .default(null) - .min(0, MUST_BE_GREATER_OR_EQUAL_TO_ZERO) - .when([VOLTAGE_REGULATION_ON], { - is: true, - then: (schema) => schema.required(), - }), - ...getConnectivityWithPositionValidationSchema(), - ...getReactiveLimitsSchema(false, true), - }); -} - -export function getVscConverterStationModificationSchema(id: string) { - return { - [id]: yup.object().shape({ - [CONVERTER_STATION_ID]: yup.string(), - [CONVERTER_STATION_NAME]: yup.string().nullable(), - [LOSS_FACTOR]: yup.number().nullable().min(0, NORMALIZED_PERCENTAGE).max(100, NORMALIZED_PERCENTAGE), - [VOLTAGE_REGULATION_ON]: yup.boolean().nullable(), - [REACTIVE_POWER]: yup.number().nullable(), - [VOLTAGE]: yup.number().nullable().min(0, MUST_BE_GREATER_OR_EQUAL_TO_ZERO), - [STATE_ESTIMATION]: getInjectionActiveReactivePowerValidationSchemaProperties(), - ...getReactiveLimitsSchema(true), - }), - }; -} - -export function getVscConverterStationEmptyFormData(isModification = false) { - return { - [CONVERTER_STATION_ID]: isModification ? '' : null, - [CONVERTER_STATION_NAME]: isModification ? '' : null, - [LOSS_FACTOR]: null, - [REACTIVE_POWER]: null, - [VOLTAGE_REGULATION_ON]: isModification ? null : false, - [VOLTAGE]: null, - [STATE_ESTIMATION]: getInjectionActiveReactivePowerEmptyFormDataProperties(), - ...getConnectivityWithPositionEmptyFormData(), - ...getReactiveLimitsEmptyFormData(), - }; -} - -export function getConverterStationCreationData(converterStation: any) { - const reactiveLimits = converterStation[FieldConstants.REACTIVE_LIMITS]; - const isReactiveCapabilityCurveOn = reactiveLimits[FieldConstants.REACTIVE_CAPABILITY_CURVE_CHOICE] === 'CURVE'; - return { - type: MODIFICATION_TYPES.CONVERTER_STATION_CREATION.type, - equipmentId: converterStation[CONVERTER_STATION_ID], - equipmentName: converterStation[CONVERTER_STATION_NAME], - lossFactor: converterStation[LOSS_FACTOR], - reactivePowerSetpoint: converterStation[REACTIVE_POWER], - voltageRegulationOn: converterStation[VOLTAGE_REGULATION_ON], - voltageSetpoint: converterStation[VOLTAGE], - voltageLevelId: converterStation[CONNECTIVITY]?.[VOLTAGE_LEVEL]?.[ID], - busOrBusbarSectionId: converterStation[CONNECTIVITY]?.[BUS_OR_BUSBAR_SECTION]?.[ID], - connectionName: sanitizeString(converterStation[CONNECTIVITY]?.[CONNECTION_NAME]), - connectionDirection: converterStation[CONNECTIVITY]?.[CONNECTION_DIRECTION] ?? UNDEFINED_CONNECTION_DIRECTION, - connectionPosition: converterStation[CONNECTIVITY]?.[CONNECTION_POSITION], - terminalConnected: converterStation[CONNECTIVITY]?.[CONNECTED], - reactiveCapabilityCurve: isReactiveCapabilityCurveOn, - minQ: isReactiveCapabilityCurveOn ? null : reactiveLimits[FieldConstants.MINIMUM_REACTIVE_POWER], - maxQ: isReactiveCapabilityCurveOn ? null : reactiveLimits[FieldConstants.MAXIMUM_REACTIVE_POWER], - reactiveCapabilityCurvePoints: isReactiveCapabilityCurveOn - ? reactiveLimits[FieldConstants.REACTIVE_CAPABILITY_CURVE_TABLE] - : null, - }; -} - -export function getConverterStationModificationData( - converterStation: any, - converterStationToModify: ConverterStationElementModificationInfos | undefined -) { - const reactiveLimits = converterStation[FieldConstants.REACTIVE_LIMITS]; - const isReactiveCapabilityCurveOn = reactiveLimits[FieldConstants.REACTIVE_CAPABILITY_CURVE_CHOICE] === 'CURVE'; - - return { - type: MODIFICATION_TYPES.CONVERTER_STATION_MODIFICATION.type, - equipmentId: converterStationToModify?.id ?? converterStation[CONVERTER_STATION_ID], - equipmentName: toModificationOperation(converterStation[CONVERTER_STATION_NAME]), - lossFactor: toModificationOperation(converterStation[LOSS_FACTOR]), - reactivePowerSetpoint: toModificationOperation(converterStation[REACTIVE_POWER]), - voltageRegulationOn: toModificationOperation(converterStation[VOLTAGE_REGULATION_ON]), - voltageSetpoint: toModificationOperation(converterStation[VOLTAGE]), - voltageLevelId: toModificationOperation(converterStation[CONNECTIVITY]?.[VOLTAGE_LEVEL]?.[ID]), - busOrBusbarSectionId: toModificationOperation(converterStation[CONNECTIVITY]?.[BUS_OR_BUSBAR_SECTION]?.[ID]), - reactiveCapabilityCurve: toModificationOperation(isReactiveCapabilityCurveOn), - pMeasurementValue: toModificationOperation(converterStation[STATE_ESTIMATION]?.[MEASUREMENT_P]?.value), - pMeasurementValidity: toModificationOperation(converterStation[STATE_ESTIMATION]?.[MEASUREMENT_P]?.validity), - qMeasurementValue: toModificationOperation(converterStation[STATE_ESTIMATION]?.[MEASUREMENT_Q]?.value), - qMeasurementValidity: toModificationOperation(converterStation[STATE_ESTIMATION]?.[MEASUREMENT_Q]?.validity), - minQ: toModificationOperation( - isReactiveCapabilityCurveOn ? null : reactiveLimits[FieldConstants.MINIMUM_REACTIVE_POWER] - ), - maxQ: toModificationOperation( - isReactiveCapabilityCurveOn ? null : reactiveLimits[FieldConstants.MAXIMUM_REACTIVE_POWER] - ), - reactiveCapabilityCurvePoints: isReactiveCapabilityCurveOn - ? reactiveLimits[FieldConstants.REACTIVE_CAPABILITY_CURVE_TABLE] - : null, - }; -} - -export function getConverterStationFormEditData(id: string, converterStation: ConverterStationCreationInfos) { - return { - [id]: { - [CONVERTER_STATION_ID]: converterStation?.equipmentId, - [CONVERTER_STATION_NAME]: converterStation?.equipmentName ?? '', - [LOSS_FACTOR]: converterStation?.lossFactor, - [REACTIVE_POWER]: converterStation?.reactivePowerSetpoint, - [VOLTAGE_REGULATION_ON]: converterStation?.voltageRegulationOn, - [VOLTAGE]: converterStation?.voltageSetpoint, - ...getConnectivityFormData({ - voltageLevelId: converterStation?.voltageLevelId, - busbarSectionId: converterStation?.busOrBusbarSectionId, - connectionDirection: converterStation?.connectionDirection, - connectionName: converterStation?.connectionName, - connectionPosition: converterStation?.connectionPosition, - terminalConnected: converterStation?.terminalConnected, - }), - ...getConverterStationReactiveLimits(converterStation), - }, - }; -} - -export function getConverterStationModificationFormEditData( - id: string, - converterStation: ConverterStationModificationInterfaceEditData -) { - return { - [id]: { - [CONVERTER_STATION_ID]: converterStation?.equipmentId, - [CONVERTER_STATION_NAME]: converterStation?.equipmentName?.value ?? '', - [LOSS_FACTOR]: converterStation?.lossFactor?.value ?? null, - [REACTIVE_POWER]: converterStation?.reactivePowerSetpoint?.value ?? null, - [VOLTAGE_REGULATION_ON]: converterStation?.voltageRegulationOn?.value ?? null, - [VOLTAGE]: converterStation?.voltageSetpoint?.value ?? null, - [STATE_ESTIMATION]: getInjectionActiveReactivePowerEditDataProperties(converterStation), - ...getConnectivityFormData({ - voltageLevelId: converterStation?.voltageLevelId?.value ?? null, - busbarSectionId: converterStation?.busOrBusbarSectionId?.value ?? null, - connectionDirection: converterStation?.connectionDirection?.value ?? null, - connectionName: converterStation?.connectionName?.value ?? null, - connectionPosition: converterStation?.connectionPosition?.value ?? null, - terminalConnected: converterStation?.terminalConnected?.value ?? null, - }), - ...getConverterStationModificationReactiveLimits(converterStation), - }, - }; -} - -function getConverterStationReactiveLimits(converterStation: ConverterStationCreationInfos) { - return converterStation.reactiveCapabilityCurve - ? getReactiveLimitsFormData({ - reactiveCapabilityCurveChoice: 'CURVE', - minimumReactivePower: null, - maximumReactivePower: null, - reactiveCapabilityCurvePoints: converterStation.reactiveCapabilityCurvePoints, - }) - : getReactiveLimitsFormData({ - reactiveCapabilityCurveChoice: 'MINMAX', - minimumReactivePower: converterStation.minQ, - maximumReactivePower: converterStation.maxQ, - reactiveCapabilityCurvePoints: converterStation?.reactiveCapabilityCurvePoints ?? null, - }); -} - -function getConverterStationModificationReactiveLimits( - converterStationEditData: ConverterStationModificationInterfaceEditData -) { - return { - ...getReactiveLimitsFormData({ - reactiveCapabilityCurveChoice: converterStationEditData?.reactiveCapabilityCurve?.value - ? 'CURVE' - : 'MINMAX', - maximumReactivePower: converterStationEditData?.maxQ?.value ?? null, - minimumReactivePower: converterStationEditData?.minQ?.value ?? null, - reactiveCapabilityCurvePoints: converterStationEditData?.reactiveCapabilityCurvePoints ?? null, - }), - }; -} - -export function getConverterStationFromSearchCopy(converterStation?: VscConverterStationFormInfos) { - return { - [CONVERTER_STATION_ID]: converterStation?.id + '(1)', - [CONVERTER_STATION_NAME]: converterStation?.name ?? '', - [LOSS_FACTOR]: converterStation?.lossFactor, - [REACTIVE_POWER]: converterStation?.reactivePowerSetpoint, - [VOLTAGE_REGULATION_ON]: converterStation?.voltageRegulatorOn, - [VOLTAGE]: converterStation?.voltageSetpoint, - ...getConnectivityFormData({ - voltageLevelId: converterStation?.voltageLevelId, - busbarSectionId: converterStation?.busOrBusbarSectionId, - connectionDirection: converterStation?.connectablePosition?.connectionDirection, - connectionName: converterStation?.connectablePosition?.connectionName, - connectionPosition: null, - terminalConnected: true, - }), - ...getReactiveLimitsFormData({ - reactiveCapabilityCurveChoice: converterStation?.minMaxReactiveLimits ? 'MINMAX' : 'CURVE', - minimumReactivePower: converterStation?.minMaxReactiveLimits?.minQ, - maximumReactivePower: converterStation?.minMaxReactiveLimits?.maxQ, - reactiveCapabilityCurvePoints: converterStation?.reactiveCapabilityCurvePoints ?? null, - }), - }; -} diff --git a/src/components/dialogs/network-modifications/hvdc-line/vsc/creation/vsc-creation-dialog.tsx b/src/components/dialogs/network-modifications/hvdc-line/vsc/creation/vsc-creation-dialog.tsx index 61117a66b4..51862f36d9 100644 --- a/src/components/dialogs/network-modifications/hvdc-line/vsc/creation/vsc-creation-dialog.tsx +++ b/src/components/dialogs/network-modifications/hvdc-line/vsc/creation/vsc-creation-dialog.tsx @@ -5,95 +5,45 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { useCallback, useEffect, useState } from 'react'; +import { useCallback, useEffect } from 'react'; import { copyEquipmentPropertiesForCreation, - creationPropertiesSchema, CustomFormProvider, - emptyProperties, ExtendedEquipmentType, - getPropertiesFromModification, - MODIFICATION_TYPES, snackWithFallback, - TextInput, - toModificationProperties, useSnackMessage, DeepNullable, - filledTextField, - sanitizeString, - FieldConstants, + VscHvdcLineForm, + VscHdvLineCreationDto, + vscHvdcLineCreationEmptyFormData, + vscHvdcLineCreationFormSchema, + VscHvdcLineCreationFormData, + vscHvdcLineCreationFormToDto, + vscHvdcLineCreationDtoToForm, + VscHvdcLineInfo, + getVscHvdcLineCharacteristicsFromCopy, + converterStationCreationFromCopy, + useTabs, + VscHvdcLineDialogTab, + HVDC_LINE_TAB_FIELDS, } from '@gridsuite/commons-ui'; -import { FieldErrors, useForm } from 'react-hook-form'; +import { useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; -import { - ACTIVE_POWER_SETPOINT, - ANGLE_DROOP_ACTIVE_POWER_CONTROL, - CONVERTER_STATION_1, - CONVERTER_STATION_2, - CONVERTERS_MODE, - EQUIPMENT_ID, - EQUIPMENT_NAME, - HVDC_LINE_TAB, - MAX_P, - NOMINAL_V, - OPERATOR_ACTIVE_POWER_LIMIT_SIDE1, - OPERATOR_ACTIVE_POWER_LIMIT_SIDE2, - P0, - R, -} from '../../../../../utils/field-constants'; -import { Box, Grid } from '@mui/material'; -import VscTabs from '../vsc-tabs'; -import * as yup from 'yup'; import { FORM_LOADING_DELAY } from '../../../../../network/constants'; import { ModificationDialog } from '../../../../commons/modificationDialog'; import { useOpenShortWaitFetching } from '../../../../commons/handle-modification-form'; import { FetchStatus } from '../../../../../../services/utils'; -import VscCreationForm from './vsc-creation-form'; -import { createVsc } from '../../../../../../services/study/network-modifications'; +import { createVscHvdcLine } from '../../../../../../services/study/network-modifications'; import { useFormSearchCopy } from '../../../../commons/use-form-search-copy'; import EquipmentSearchDialog from '../../../../equipment-search-dialog'; -import { GridItem } from '../../../../commons/grid-item'; -import { VSC_TABS } from '../vsc-utils'; import { isNodeBuilt } from 'components/graph/util/model-functions'; import { NetworkModificationDialogProps } from '../../../../../graph/menus/network-modifications/network-modification-menu.type'; -import { VscCreationInfos } from '../../../../../../services/network-modification-types'; -import { VscCreationDialogSchemaForm, VscFormInfos } from '../vsc-dialog.type'; -import { - getVscHvdcLinePaneEmptyFormData, - getVscHvdcLinePaneSchema, - getVscHvdcLineTabFormData, - getVscHvdcLineTabFormEditData, -} from '../hvdc-line-pane/vsc-hvdc-line-pane-utils'; -import { - getConverterStationCreationData, - getConverterStationFormEditData, - getConverterStationFromSearchCopy, - getVscConverterStationEmptyFormData, - getVscConverterStationSchema, -} from '../converter-station/converter-station-utils'; - -const formSchema = yup - .object() - .shape({ - [EQUIPMENT_ID]: yup.string().required(), - [EQUIPMENT_NAME]: yup.string().nullable(), - [HVDC_LINE_TAB]: getVscHvdcLinePaneSchema(), - [CONVERTER_STATION_1]: getVscConverterStationSchema(), - [CONVERTER_STATION_2]: getVscConverterStationSchema(), - }) - .concat(creationPropertiesSchema) - .required(); -const emptyFormData = { - [EQUIPMENT_ID]: '', - [EQUIPMENT_NAME]: '', - [HVDC_LINE_TAB]: getVscHvdcLinePaneEmptyFormData(false), - [CONVERTER_STATION_1]: getVscConverterStationEmptyFormData(false), - [CONVERTER_STATION_2]: getVscConverterStationEmptyFormData(false), - ...emptyProperties, -}; +import PositionDiagramPane from '../../../../../grid-layout/cards/diagrams/singleLineDiagram/positionDiagram/position-diagram-pane'; +import useVoltageLevelsListInfos from '../../../../../../hooks/use-voltage-levels-list-infos'; +import { fetchBusesOrBusbarSectionsForVoltageLevel } from '../../../../../../services/study/network'; -export type VscCreationDialogProps = NetworkModificationDialogProps & { - editData: VscCreationInfos; +type VscCreationDialogProps = NetworkModificationDialogProps & { + editData?: VscHdvLineCreationDto; }; export default function VscCreationDialog({ @@ -107,22 +57,29 @@ export default function VscCreationDialog({ }: Readonly) { const currentNodeUuid = currentNode.id; const { snackError } = useSnackMessage(); - const [tabIndex, setTabIndex] = useState(VSC_TABS.HVDC_LINE_TAB); - const [tabIndexesWithError, setTabIndexesWithError] = useState([]); + const voltageLevelOptions = useVoltageLevelsListInfos(studyUuid, currentNode?.id, currentRootNetworkUuid); + + const formMethods = useForm>({ + defaultValues: vscHvdcLineCreationEmptyFormData, + resolver: yupResolver>(vscHvdcLineCreationFormSchema), + }); + const { reset } = formMethods; - const formMethods = useForm>({ - defaultValues: emptyFormData, - resolver: yupResolver>(formSchema), + const { errors } = formMethods.formState; + const useTabsReturn = useTabs({ + defaultTab: VscHvdcLineDialogTab.HVDC_LINE_TAB, + errors, + tabFields: HVDC_LINE_TAB_FIELDS, }); - const fromSearchCopyToFormValues = (hvdcLine: VscFormInfos) => { + const fromSearchCopyToFormValues = (hvdcLine: VscHvdcLineInfo) => { reset( { - [EQUIPMENT_ID]: hvdcLine.id + '(1)', - [EQUIPMENT_NAME]: hvdcLine.name ?? '', - [HVDC_LINE_TAB]: getVscHvdcLineTabFormData(hvdcLine), - [CONVERTER_STATION_1]: getConverterStationFromSearchCopy(hvdcLine.converterStation1), - [CONVERTER_STATION_2]: getConverterStationFromSearchCopy(hvdcLine.converterStation2), + equipmentID: hvdcLine.id + '(1)', + equipmentName: hvdcLine.name ?? '', + hvdcLine: getVscHvdcLineCharacteristicsFromCopy(hvdcLine), + converterStation1: converterStationCreationFromCopy(hvdcLine.converterStation1), + converterStation2: converterStationCreationFromCopy(hvdcLine.converterStation2), ...copyEquipmentPropertiesForCreation(hvdcLine), }, { keepDefaultValues: true } @@ -137,116 +94,50 @@ export default function VscCreationDialog({ const searchCopy = useFormSearchCopy(fromSearchCopyToFormValues, ExtendedEquipmentType.HVDC_LINE_VSC); - const generatorIdField = ( - - ); - - const generatorNameField = ; - - const headersAndTabs = ( - - - {generatorIdField} - {generatorNameField} - - - - ); - - const { reset } = formMethods; - useEffect(() => { if (editData) { - reset({ - [EQUIPMENT_ID]: editData.equipmentId, - [EQUIPMENT_NAME]: editData?.equipmentName ?? '', - ...getVscHvdcLineTabFormEditData(HVDC_LINE_TAB, editData), - ...getConverterStationFormEditData(CONVERTER_STATION_1, editData.converterStation1), - ...getConverterStationFormEditData(CONVERTER_STATION_2, editData.converterStation2), - ...getPropertiesFromModification(editData.properties), - }); + reset(vscHvdcLineCreationDtoToForm(editData)); } - }, [editData, reset]); + }, [reset, editData]); const clear = useCallback(() => { - reset(emptyFormData); + reset(vscHvdcLineCreationEmptyFormData); }, [reset]); - const onValidationError = (errors: FieldErrors) => { - let tabsInError = []; - if (errors?.[HVDC_LINE_TAB] !== undefined) { - tabsInError.push(VSC_TABS.HVDC_LINE_TAB); - } - if (errors?.[CONVERTER_STATION_1] !== undefined) { - tabsInError.push(VSC_TABS.CONVERTER_STATION_1); - } - - if (errors?.[CONVERTER_STATION_2] !== undefined) { - tabsInError.push(VSC_TABS.CONVERTER_STATION_2); - } - - if (tabsInError.length > 0) { - setTabIndex(tabsInError[0]); - } - - setTabIndexesWithError(tabsInError); - }; - const onSubmit = useCallback( - (hvdcLine: VscCreationDialogSchemaForm) => { - const hvdcLineTab = hvdcLine[HVDC_LINE_TAB]; - const vscCreationInfos = { - type: MODIFICATION_TYPES.VSC_CREATION.type, - equipmentId: hvdcLine[EQUIPMENT_ID], - equipmentName: sanitizeString(hvdcLine[EQUIPMENT_NAME]) ?? null, - nominalV: hvdcLineTab[NOMINAL_V], - r: hvdcLineTab[R], - maxP: hvdcLineTab[MAX_P], - operatorActivePowerLimitFromSide1ToSide2: hvdcLineTab[OPERATOR_ACTIVE_POWER_LIMIT_SIDE1] ?? null, - operatorActivePowerLimitFromSide2ToSide1: hvdcLineTab[OPERATOR_ACTIVE_POWER_LIMIT_SIDE2] ?? null, - convertersMode: hvdcLineTab[CONVERTERS_MODE], - activePowerSetpoint: hvdcLineTab[ACTIVE_POWER_SETPOINT], - angleDroopActivePowerControl: hvdcLineTab[ANGLE_DROOP_ACTIVE_POWER_CONTROL] ?? null, - p0: hvdcLineTab[P0] ?? null, - droop: hvdcLineTab[FieldConstants.DROOP] ?? null, - converterStation1: getConverterStationCreationData(hvdcLine[CONVERTER_STATION_1]), - converterStation2: getConverterStationCreationData(hvdcLine[CONVERTER_STATION_2]), - properties: toModificationProperties(hvdcLine), - } satisfies VscCreationInfos; - createVsc({ - vscCreationInfos: vscCreationInfos, - studyUuid: studyUuid, - nodeUuid: currentNodeUuid, - modificationUuid: editData?.uuid, - isUpdate: !!editData, - }).catch((error) => { - snackWithFallback(snackError, error, { headerId: 'VscCreationError' }); + (lineForm: VscHvdcLineCreationFormData) => { + const dto = vscHvdcLineCreationFormToDto(lineForm); + createVscHvdcLine(studyUuid, currentNodeUuid, editData?.uuid, dto).catch((error: Error) => { + snackWithFallback(snackError, error, { headerId: 'HvdcCreationError' }); }); }, - [studyUuid, currentNodeUuid, editData, snackError] + [editData?.uuid, studyUuid, currentNodeUuid, snackError] + ); + + const fetchBusesOrBusbarSections = useCallback( + (voltageLevelId: string) => + fetchBusesOrBusbarSectionsForVoltageLevel( + studyUuid, + currentNodeUuid, + currentRootNetworkUuid, + voltageLevelId + ), + [studyUuid, currentNodeUuid, currentRootNetworkUuid] ); return ( - + - ) { - return ( - <> - - - - - ); -} diff --git a/src/components/dialogs/network-modifications/hvdc-line/vsc/hvdc-line-pane/vsc-hvdc-line-pane-utils.tsx b/src/components/dialogs/network-modifications/hvdc-line/vsc/hvdc-line-pane/vsc-hvdc-line-pane-utils.tsx deleted file mode 100644 index 0f306bfbc2..0000000000 --- a/src/components/dialogs/network-modifications/hvdc-line/vsc/hvdc-line-pane/vsc-hvdc-line-pane-utils.tsx +++ /dev/null @@ -1,139 +0,0 @@ -/** - * Copyright (c) 2023, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import * as yup from 'yup'; -import { - ACTIVE_POWER_SETPOINT, - ANGLE_DROOP_ACTIVE_POWER_CONTROL, - CONVERTERS_MODE, - NOMINAL_V, - R, - MAX_P, - OPERATOR_ACTIVE_POWER_LIMIT_SIDE1, - OPERATOR_ACTIVE_POWER_LIMIT_SIDE2, - P0, -} from '../../../../../utils/field-constants'; -import { VscFormInfos } from '../vsc-dialog.type'; -import { VscCreationInfos } from '../../../../../../services/network-modification-types'; -import { FieldConstants, MUST_BE_GREATER_OR_EQUAL_TO_ZERO } from '@gridsuite/commons-ui'; - -export function getVscHvdcLinePaneSchema() { - return yup.object().shape( - { - [NOMINAL_V]: yup.number().nullable().min(0, MUST_BE_GREATER_OR_EQUAL_TO_ZERO).required(), - [R]: yup.number().nullable().min(0, MUST_BE_GREATER_OR_EQUAL_TO_ZERO).required(), - [MAX_P]: yup.number().nullable().required(), - [OPERATOR_ACTIVE_POWER_LIMIT_SIDE1]: yup.number().nullable(), - [OPERATOR_ACTIVE_POWER_LIMIT_SIDE2]: yup.number().nullable(), - [CONVERTERS_MODE]: yup.string().required(), - [ANGLE_DROOP_ACTIVE_POWER_CONTROL]: yup.boolean(), - [ACTIVE_POWER_SETPOINT]: yup.number().nullable().required(), - [P0]: yup - .number() - .nullable() - .default(null) - .when([ANGLE_DROOP_ACTIVE_POWER_CONTROL, FieldConstants.DROOP], { - is: (angleDroopActivePowerControl: boolean, droop: number) => - angleDroopActivePowerControl || (droop !== null && droop !== undefined), - then: (schema) => schema.required(), - }), - [FieldConstants.DROOP]: yup - .number() - .nullable() - .default(null) - .when([ANGLE_DROOP_ACTIVE_POWER_CONTROL, P0], { - is: (angleDroopActivePowerControl: boolean, p0: number) => - angleDroopActivePowerControl || (p0 !== null && p0 !== undefined), - then: (schema) => schema.required(), - }), - }, - [[P0, FieldConstants.DROOP]] - ); -} - -export function getVscHvdcLineModificationPaneSchema(id: string) { - return { - [id]: yup.object().shape( - { - [NOMINAL_V]: yup.number().nullable().min(0, MUST_BE_GREATER_OR_EQUAL_TO_ZERO), - [R]: yup.number().nullable().min(0, MUST_BE_GREATER_OR_EQUAL_TO_ZERO), - [MAX_P]: yup.number().nullable(), - [OPERATOR_ACTIVE_POWER_LIMIT_SIDE1]: yup.number().nullable(), - [OPERATOR_ACTIVE_POWER_LIMIT_SIDE2]: yup.number().nullable(), - [CONVERTERS_MODE]: yup.string().nullable(), - [ANGLE_DROOP_ACTIVE_POWER_CONTROL]: yup.boolean().nullable(), - [ACTIVE_POWER_SETPOINT]: yup.number().nullable().nullable(), - [P0]: yup.number().nullable(), - [FieldConstants.DROOP]: yup.number().nullable(), - }, - [[P0, FieldConstants.DROOP]] - ), - }; -} -export function getVscHvdcLinePaneEmptyFormData(isModification: boolean) { - return { - [NOMINAL_V]: null, - [R]: null, - [MAX_P]: null, - [OPERATOR_ACTIVE_POWER_LIMIT_SIDE1]: null, - [OPERATOR_ACTIVE_POWER_LIMIT_SIDE2]: null, - [CONVERTERS_MODE]: null, - [ACTIVE_POWER_SETPOINT]: null, - [ANGLE_DROOP_ACTIVE_POWER_CONTROL]: isModification ? null : false, - [P0]: null, - [FieldConstants.DROOP]: null, - }; -} - -export function getVscHvdcLineTabFormData(hvdcLine: VscFormInfos) { - return { - [NOMINAL_V]: hvdcLine?.nominalV, - [R]: hvdcLine?.r, - [MAX_P]: hvdcLine?.maxP, - [OPERATOR_ACTIVE_POWER_LIMIT_SIDE1]: hvdcLine?.hvdcOperatorActivePowerRange?.oprFromCS1toCS2, - [OPERATOR_ACTIVE_POWER_LIMIT_SIDE2]: hvdcLine?.hvdcOperatorActivePowerRange?.oprFromCS1toCS2, - [CONVERTERS_MODE]: hvdcLine?.convertersMode, - [ACTIVE_POWER_SETPOINT]: hvdcLine?.activePowerSetpoint, - [ANGLE_DROOP_ACTIVE_POWER_CONTROL]: hvdcLine?.hvdcAngleDroopActivePowerControl?.isEnabled, - [P0]: hvdcLine?.hvdcAngleDroopActivePowerControl?.p0, - [FieldConstants.DROOP]: hvdcLine?.hvdcAngleDroopActivePowerControl?.droop, - }; -} - -export function getVscHvdcLineTabFormEditData(id: string, hvdcLine: VscCreationInfos) { - return { - [id]: { - [NOMINAL_V]: hvdcLine.nominalV, - [R]: hvdcLine.r, - [MAX_P]: hvdcLine.maxP, - [OPERATOR_ACTIVE_POWER_LIMIT_SIDE1]: hvdcLine?.operatorActivePowerLimitFromSide2ToSide1, - [OPERATOR_ACTIVE_POWER_LIMIT_SIDE2]: hvdcLine?.operatorActivePowerLimitFromSide1ToSide2, - [CONVERTERS_MODE]: hvdcLine.convertersMode, - [ACTIVE_POWER_SETPOINT]: hvdcLine.activePowerSetpoint, - [ANGLE_DROOP_ACTIVE_POWER_CONTROL]: hvdcLine?.angleDroopActivePowerControl, - [P0]: hvdcLine?.p0, - [FieldConstants.DROOP]: hvdcLine?.droop, - }, - }; -} - -export function getVscHvdcLineModificationTabFormData(id: string, hvdcLine: any) { - return { - [id]: { - [NOMINAL_V]: hvdcLine?.nominalV?.value ?? null, - [R]: hvdcLine?.r?.value ?? null, - [MAX_P]: hvdcLine?.maxP?.value ?? null, - [OPERATOR_ACTIVE_POWER_LIMIT_SIDE1]: hvdcLine?.operatorActivePowerLimitFromSide1ToSide2?.value ?? null, - [OPERATOR_ACTIVE_POWER_LIMIT_SIDE2]: hvdcLine?.operatorActivePowerLimitFromSide2ToSide1?.value ?? null, - [CONVERTERS_MODE]: hvdcLine?.convertersMode?.value ?? null, - [ACTIVE_POWER_SETPOINT]: hvdcLine?.activePowerSetpoint?.value ?? null, - [ANGLE_DROOP_ACTIVE_POWER_CONTROL]: hvdcLine?.angleDroopActivePowerControl?.value ?? null, - [P0]: hvdcLine?.p0?.value ?? null, - [FieldConstants.DROOP]: hvdcLine?.droop?.value ?? null, - }, - }; -} diff --git a/src/components/dialogs/network-modifications/hvdc-line/vsc/hvdc-line-pane/vsc-hvdc-line-pane.tsx b/src/components/dialogs/network-modifications/hvdc-line/vsc/hvdc-line-pane/vsc-hvdc-line-pane.tsx deleted file mode 100644 index d9a329ea9a..0000000000 --- a/src/components/dialogs/network-modifications/hvdc-line/vsc/hvdc-line-pane/vsc-hvdc-line-pane.tsx +++ /dev/null @@ -1,216 +0,0 @@ -/** - * Copyright (c) 2023, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import { - ActivePowerAdornment, - CheckboxNullableInput, - FieldConstants, - FloatInput, - GridSection, - OhmAdornment, - PropertiesForm, - SelectInput, - SwitchInput, - VoltageAdornment, -} from '@gridsuite/commons-ui'; -import { - ACTIVE_POWER_SETPOINT, - ANGLE_DROOP_ACTIVE_POWER_CONTROL, - CONVERTERS_MODE, - MAX_P, - NOMINAL_V, - OPERATOR_ACTIVE_POWER_LIMIT_SIDE1, - OPERATOR_ACTIVE_POWER_LIMIT_SIDE2, - P0, - R, -} from '../../../../../utils/field-constants'; -import { VSC_CONVERTER_MODE } from 'components/network/constants'; -import { FunctionComponent, useEffect } from 'react'; -import { Grid } from '@mui/material'; -import { useFormContext, useWatch } from 'react-hook-form'; -import { VscModificationInfo } from 'services/network-modification-types'; -import { useIntl } from 'react-intl'; -import { GridItem } from '../../../../commons/grid-item'; - -interface VscHvdcLinePaneProps { - id: string; - isEquipementModification?: boolean; - previousValues?: VscModificationInfo | null; -} - -const VscHvdcLinePane: FunctionComponent = ({ - id, - isEquipementModification = false, - previousValues, -}) => { - const intl = useIntl(); - const { trigger } = useFormContext(); - - const angleDroopWatch = useWatch({ - name: `${id}.${ANGLE_DROOP_ACTIVE_POWER_CONTROL}`, - }); - - useEffect(() => { - if (!angleDroopWatch) { - trigger(`${id}.${P0}`); - trigger(`${id}.${FieldConstants.DROOP}`); - } - }, [angleDroopWatch, trigger, id]); - - const dcNominalVoltageField = ( - - ); - - const dcResistanceField = ( - - ); - - const maximumActivePowerField = ( - - ); - - const operatorActivePowerLimitSide1Field = ( - - ); - - const operatorActivePowerLimitSide2Field = ( - - ); - - const previousConverterMode = () => { - if (previousValues?.convertersMode === VSC_CONVERTER_MODE.SIDE_1_INVERTER_SIDE_2_RECTIFIER.id) { - return intl.formatMessage({ - id: VSC_CONVERTER_MODE.SIDE_1_INVERTER_SIDE_2_RECTIFIER.label, - }); - } else if (previousValues?.convertersMode === VSC_CONVERTER_MODE.SIDE_1_RECTIFIER_SIDE_2_INVERTER.id) { - return intl.formatMessage({ - id: VSC_CONVERTER_MODE.SIDE_1_RECTIFIER_SIDE_2_INVERTER.label, - }); - } - }; - - const converterModeField = ( - - ); - - const activePowerField = ( - - ); - - const previousAngleDropPowerControl = () => { - if (previousValues?.hvdcAngleDroopActivePowerControl?.isEnabled === true) { - return intl.formatMessage({ id: 'On' }); - } - - return intl.formatMessage({ id: 'Off' }); - }; - - function getAngleDroopActivePowerControlField() { - if (isEquipementModification) { - return ( - - ); - } else { - return ( - - ); - } - } - - const AngleDroopActivePowerControl = getAngleDroopActivePowerControlField(); - - const p0Field = ( - - ); - - const droopField = ( - - ); - - return ( - <> - - - {dcNominalVoltageField} - {dcResistanceField} - {maximumActivePowerField} - - - - - {operatorActivePowerLimitSide1Field} - {operatorActivePowerLimitSide2Field} - - - - - {converterModeField} - {activePowerField} - {AngleDroopActivePowerControl} - {droopField} - {p0Field} - - - - - ); -}; - -export default VscHvdcLinePane; diff --git a/src/components/dialogs/network-modifications/hvdc-line/vsc/modification/vsc-modification-dialog.tsx b/src/components/dialogs/network-modifications/hvdc-line/vsc/modification/vsc-modification-dialog.tsx index 676ad2fe3e..3f8ff4e361 100644 --- a/src/components/dialogs/network-modifications/hvdc-line/vsc/modification/vsc-modification-dialog.tsx +++ b/src/components/dialogs/network-modifications/hvdc-line/vsc/modification/vsc-modification-dialog.tsx @@ -10,144 +10,101 @@ import { ModificationDialog } from '../../../../commons/modificationDialog'; import { EquipmentIdSelector } from '../../../../equipment-id/equipment-id-selector'; import { EQUIPMENT_INFOS_TYPES } from 'components/utils/equipment-types'; import { yupResolver } from '@hookform/resolvers/yup'; -import * as yup from 'yup'; -import { - ACTIVE_POWER_SETPOINT, - ANGLE_DROOP_ACTIVE_POWER_CONTROL, - CONVERTER_STATION_1, - CONVERTER_STATION_2, - CONVERTERS_MODE, - EQUIPMENT_ID, - EQUIPMENT_NAME, - HVDC_LINE_TAB, - MAX_P, - NOMINAL_V, - OPERATOR_ACTIVE_POWER_LIMIT_SIDE1, - OPERATOR_ACTIVE_POWER_LIMIT_SIDE2, - P0, - R, -} from '../../../../../utils/field-constants'; import { FetchStatus } from '../../../../../../services/utils'; -import { - getVscHvdcLineModificationPaneSchema, - getVscHvdcLineModificationTabFormData, - getVscHvdcLinePaneEmptyFormData, -} from '../hvdc-line-pane/vsc-hvdc-line-pane-utils'; -import { - getConverterStationModificationData, - getConverterStationModificationFormEditData, - getVscConverterStationEmptyFormData, - getVscConverterStationModificationSchema, -} from '../converter-station/converter-station-utils'; -import { VscModificationForm } from './vsc-modification-from'; import { useOpenShortWaitFetching } from 'components/dialogs/commons/handle-modification-form'; import { FORM_LOADING_DELAY } from 'components/network/constants'; -import { modifyVsc } from 'services/study/network-modifications'; -import { fetchNetworkElementInfos } from '../../../../../../services/study/network'; -import { VscModificationInfo } from 'services/network-modification-types'; +import { modifyVscHvdcLine } from 'services/study/network-modifications'; +import { + fetchBusesOrBusbarSectionsForVoltageLevel, + fetchNetworkElementInfos, +} from '../../../../../../services/study/network'; + import { CustomFormProvider, - emptyProperties, + DeepNullable, ExtendedEquipmentType, FieldConstants, getConcatenatedProperties, - getPropertiesFromModification, - modificationPropertiesSchema, + HVDC_LINE_TAB_FIELDS, ReactiveCapabilityCurvePoints, REMOVE, - sanitizeString, - setCurrentReactiveCapabilityCurveTable, - setSelectedReactiveLimits, snackWithFallback, - toModificationProperties, useSnackMessage, + useTabs, + VscHdvLineModificationDto, + VscHvdcLineDialogTab, + VscHvdcLineForm, + VscHvdcLineInfo, + vscHvdcLineModificationDtoToForm, + vscHvdcLineModificationEmptyFormData, + VscHvdcLineModificationFormData, + vscHvdcLineModificationFormSchema, + vscHvdcLineModificationFormToDto, } from '@gridsuite/commons-ui'; import { isNodeBuilt } from '../../../../../graph/util/model-functions'; import { useFormWithDirtyTracking } from 'components/dialogs/commons/use-form-with-dirty-tracking'; -import { VSC_TABS } from '../vsc-utils'; +import { EquipmentModificationDialogProps } from '../../../../../graph/menus/network-modifications/network-modification-menu.type'; +import PositionDiagramPane from '../../../../../grid-layout/cards/diagrams/singleLineDiagram/positionDiagram/position-diagram-pane'; +import useVoltageLevelsListInfos from '../../../../../../hooks/use-voltage-levels-list-infos'; -const formSchema = yup - .object() - .shape({ - [EQUIPMENT_ID]: yup.string().nullable(), - [EQUIPMENT_NAME]: yup.string().nullable(), - ...getVscHvdcLineModificationPaneSchema(HVDC_LINE_TAB), - ...getVscConverterStationModificationSchema(CONVERTER_STATION_1), - ...getVscConverterStationModificationSchema(CONVERTER_STATION_2), - }) - .concat(modificationPropertiesSchema) - .required(); -const emptyFormData = { - [EQUIPMENT_ID]: '', - [EQUIPMENT_NAME]: '', - [HVDC_LINE_TAB]: getVscHvdcLinePaneEmptyFormData(true), - [CONVERTER_STATION_1]: getVscConverterStationEmptyFormData(true), - [CONVERTER_STATION_2]: getVscConverterStationEmptyFormData(true), - ...emptyProperties, +type VscModificationDialogProps = EquipmentModificationDialogProps & { + editData?: VscHdvLineModificationDto; }; -const VscModificationDialog: React.FC = ({ +export default function VscModificationDialog({ editData, - defaultIdValue, // Used to pre-select an equipmentId when calling this dialog from the network map or spreadsheet + defaultIdValue, currentNode, studyUuid, currentRootNetworkUuid, isUpdate, editDataFetchStatus, ...dialogProps -}) => { - const [tabIndex, setTabIndex] = useState(VSC_TABS.HVDC_LINE_TAB); - +}: Readonly) { + const currentNodeUuid = currentNode.id; const [equipmentId, setEquipmentId] = useState(defaultIdValue ?? null); - const [vscToModify, setVscToModify] = useState(null); + const [vscToModify, setVscToModify] = useState(null); const [dataFetchStatus, setDataFetchStatus] = useState(FetchStatus.IDLE); - const formMethods = useFormWithDirtyTracking({ - defaultValues: emptyFormData, - resolver: yupResolver(formSchema), - }); const { snackError } = useSnackMessage(); - const { reset, getValues, setValue, handleSubmit } = formMethods; + const voltageLevelOptions = useVoltageLevelsListInfos(studyUuid, currentNode?.id, currentRootNetworkUuid); + + const formMethods = useFormWithDirtyTracking>({ + defaultValues: vscHvdcLineModificationEmptyFormData, + resolver: yupResolver>(vscHvdcLineModificationFormSchema), + }); + const { reset, getValues, setValue } = formMethods; + + const { errors } = formMethods.formState; + const useTabsReturn = useTabs({ + defaultTab: VscHvdcLineDialogTab.HVDC_LINE_TAB, + errors, + tabFields: HVDC_LINE_TAB_FIELDS, + }); const open = useOpenShortWaitFetching({ isDataFetched: !isUpdate || editDataFetchStatus === FetchStatus.SUCCEED || editDataFetchStatus === FetchStatus.FAILED, delay: FORM_LOADING_DELAY, }); - const fromEditDataToFormValues = useCallback( - (editData: any) => { - if (editData?.equipmentId) { - setEquipmentId(editData.equipmentId); - } - reset({ - [EQUIPMENT_NAME]: editData?.equipmentName?.value ?? '', - ...getVscHvdcLineModificationTabFormData(HVDC_LINE_TAB, editData), - ...getConverterStationModificationFormEditData(CONVERTER_STATION_1, editData.converterStation1), - ...getConverterStationModificationFormEditData(CONVERTER_STATION_2, editData.converterStation2), - ...getPropertiesFromModification(editData.properties), - }); - }, - [reset] - ); useEffect(() => { if (editData) { - fromEditDataToFormValues(editData); + if (editData?.equipmentId) { + setEquipmentId(editData.equipmentId); + } + reset(vscHvdcLineModificationDtoToForm(editData)); } - }, [fromEditDataToFormValues, editData]); + }, [reset, editData]); - //this method empties the form, and let us pass custom data that we want to set - const setValuesAndEmptyOthers = useCallback( - (customData = {}, keepDefaultValues = false) => { - reset({ ...emptyFormData, ...customData }, { keepDefaultValues: keepDefaultValues }); - }, - [reset] - ); + const clear = useCallback(() => { + reset(vscHvdcLineModificationEmptyFormData); + }, [reset]); const onEquipmentIdChange = useCallback( (equipmentId: string | null) => { if (!equipmentId) { - setValuesAndEmptyOthers(); setVscToModify(null); + reset(vscHvdcLineModificationEmptyFormData, { keepDefaultValues: true }); } else { setDataFetchStatus(FetchStatus.RUNNING); fetchNetworkElementInfos( @@ -167,33 +124,39 @@ const VscModificationDialog: React.FC = ({ const previousReactiveCapabilityCurveTable1 = value.converterStation1?.reactiveCapabilityCurvePoints; if (previousReactiveCapabilityCurveTable1) { - setCurrentReactiveCapabilityCurveTable( - previousReactiveCapabilityCurveTable1, - `${CONVERTER_STATION_1}.${FieldConstants.REACTIVE_LIMITS}.${FieldConstants.REACTIVE_CAPABILITY_CURVE_TABLE}`, - setValue + setValue( + `${FieldConstants.CONVERTER_STATION_1}.${FieldConstants.REACTIVE_LIMITS}.${FieldConstants.REACTIVE_CAPABILITY_CURVE_TABLE}` as any, + previousReactiveCapabilityCurveTable1 ); } const previousReactiveCapabilityCurveTable2 = value.converterStation2?.reactiveCapabilityCurvePoints; if (previousReactiveCapabilityCurveTable2) { - setCurrentReactiveCapabilityCurveTable( - previousReactiveCapabilityCurveTable2, - `${CONVERTER_STATION_2}.${FieldConstants.REACTIVE_LIMITS}.${FieldConstants.REACTIVE_CAPABILITY_CURVE_TABLE}`, - setValue + setValue( + `${FieldConstants.CONVERTER_STATION_2}.${FieldConstants.REACTIVE_LIMITS}.${FieldConstants.REACTIVE_CAPABILITY_CURVE_TABLE}` as any, + previousReactiveCapabilityCurveTable2 ); } - setSelectedReactiveLimits( - `${CONVERTER_STATION_1}.${FieldConstants.REACTIVE_LIMITS}.${FieldConstants.REACTIVE_CAPABILITY_CURVE_CHOICE}`, - value.converterStation1?.minMaxReactiveLimits, - setValue + + setValue( + `${FieldConstants.CONVERTER_STATION_1}.${FieldConstants.REACTIVE_LIMITS}.${FieldConstants.REACTIVE_CAPABILITY_CURVE_CHOICE}` as any, + value.converterStation1?.minMaxReactiveLimits ? 'MINMAX' : 'CURVE' + ); + setValue( + `${FieldConstants.CONVERTER_STATION_2}.${FieldConstants.REACTIVE_LIMITS}.${FieldConstants.REACTIVE_CAPABILITY_CURVE_CHOICE}` as any, + value.converterStation2?.minMaxReactiveLimits ? 'MINMAX' : 'CURVE' ); - setSelectedReactiveLimits( - `${CONVERTER_STATION_2}.${FieldConstants.REACTIVE_LIMITS}.${FieldConstants.REACTIVE_CAPABILITY_CURVE_CHOICE}`, - value.converterStation2?.minMaxReactiveLimits, - setValue + setValue( + `${FieldConstants.CONVERTER_STATION_1}.${FieldConstants.CONVERTER_STATION_ID}` as any, + value.converterStation1?.id ); + setValue( + `${FieldConstants.CONVERTER_STATION_2}.${FieldConstants.CONVERTER_STATION_ID}` as any, + value.converterStation2?.id + ); + setVscToModify({ ...value, converterStation1: { @@ -208,6 +171,7 @@ const VscModificationDialog: React.FC = ({ reset( (formValues) => ({ ...formValues, + [FieldConstants.EQUIPMENT_ID]: equipmentId, [FieldConstants.ADDITIONAL_PROPERTIES]: getConcatenatedProperties(value, getValues), }), { @@ -219,22 +183,16 @@ const VscModificationDialog: React.FC = ({ }) .catch(() => { setDataFetchStatus(FetchStatus.FAILED); + reset((formValues) => ({ ...formValues, [FieldConstants.EQUIPMENT_ID]: equipmentId }), { + keepDirty: true, + }); if (editData?.equipmentId !== equipmentId) { setVscToModify(null); } }); } }, - [ - setValuesAndEmptyOthers, - currentRootNetworkUuid, - studyUuid, - currentNode, - setValue, - reset, - getValues, - editData?.equipmentId, - ] + [currentRootNetworkUuid, studyUuid, currentNode, setValue, reset, getValues, editData?.equipmentId] ); useEffect(() => { @@ -243,47 +201,21 @@ const VscModificationDialog: React.FC = ({ } }, [equipmentId, onEquipmentIdChange]); - const onSubmit = (hvdcLine: any) => { - const hvdcLineTab = hvdcLine[HVDC_LINE_TAB]; - const converterStation1 = getConverterStationModificationData( - hvdcLine[CONVERTER_STATION_1], - vscToModify?.converterStation1 - ); - const converterStation2 = getConverterStationModificationData( - hvdcLine[CONVERTER_STATION_2], - vscToModify?.converterStation2 - ); - - modifyVsc({ - studyUuid: studyUuid, - nodeUuid: currentNode.id, - id: equipmentId, - name: sanitizeString(hvdcLine[EQUIPMENT_NAME]), - nominalV: hvdcLineTab[NOMINAL_V], - r: hvdcLineTab[R], - maxP: hvdcLineTab[MAX_P], - operatorActivePowerLimitSide1: hvdcLineTab[OPERATOR_ACTIVE_POWER_LIMIT_SIDE1], - operatorActivePowerLimitSide2: hvdcLineTab[OPERATOR_ACTIVE_POWER_LIMIT_SIDE2], - convertersMode: hvdcLineTab[CONVERTERS_MODE], - activePowerSetpoint: hvdcLineTab[ACTIVE_POWER_SETPOINT], - angleDroopActivePowerControl: hvdcLineTab[ANGLE_DROOP_ACTIVE_POWER_CONTROL], - p0: hvdcLineTab[P0], - droop: hvdcLineTab[FieldConstants.DROOP], - converterStation1: converterStation1, - converterStation2: converterStation2, - properties: toModificationProperties(hvdcLine), - isUpdate: !!editData, - modificationUuid: editData?.uuid ?? null, - }).catch((error) => { - snackWithFallback(snackError, error, { headerId: 'VscModificationError' }); - }); - }; + const onSubmit = useCallback( + (lineForm: VscHvdcLineModificationFormData) => { + const dto = vscHvdcLineModificationFormToDto(lineForm); + modifyVscHvdcLine(studyUuid, currentNodeUuid, editData?.uuid, dto).catch((error: Error) => { + snackWithFallback(snackError, error, { headerId: 'HvdcModificationError' }); + }); + }, + [editData?.uuid, studyUuid, currentNodeUuid, snackError] + ); const updateConverterStationCapabilityCurveTable = ( newRccValues: ReactiveCapabilityCurvePoints[] | undefined, action: string, index: number, - previousValue: VscModificationInfo | null + previousValue: VscHvdcLineInfo | null ): any => { if (!newRccValues) { return previousValue; @@ -304,17 +236,28 @@ const VscModificationDialog: React.FC = ({ const updatePreviousReactiveCapabilityCurveTableConverterStation = ( action: string, index: number, - converterStationName: 'converterStation1' | 'converterStation2' + converterStationName: FieldConstants.CONVERTER_STATION_1 | FieldConstants.CONVERTER_STATION_2 ) => { - setVscToModify((previousValue: VscModificationInfo | null) => { - const newRccValues = previousValue?.[converterStationName]?.reactiveCapabilityCurveTable; + setVscToModify((previousValue: VscHvdcLineInfo | null) => { + const newRccValues = previousValue?.[converterStationName]?.reactiveCapabilityCurvePoints; return updateConverterStationCapabilityCurveTable(newRccValues, action, index, previousValue); }); }; + const fetchBusesOrBusbarSections = useCallback( + (voltageLevelId: string) => + fetchBusesOrBusbarSectionsForVoltageLevel( + studyUuid, + currentNodeUuid, + currentRootNetworkUuid, + voltageLevelId + ), + [studyUuid, currentNodeUuid, currentRootNetworkUuid] + ); + return ( = ({ > = ({ /> )} {equipmentId !== null && ( - + useTabsReturn={useTabsReturn} + hvdcLineToModify={vscToModify} + isModification + /> )} ); -}; - -export default VscModificationDialog; +} diff --git a/src/components/dialogs/network-modifications/hvdc-line/vsc/modification/vsc-modification-from.tsx b/src/components/dialogs/network-modifications/hvdc-line/vsc/modification/vsc-modification-from.tsx deleted file mode 100644 index caebe2d529..0000000000 --- a/src/components/dialogs/network-modifications/hvdc-line/vsc/modification/vsc-modification-from.tsx +++ /dev/null @@ -1,148 +0,0 @@ -/** - * Copyright (c) 2024, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import { - CONVERTER_STATION_1, - CONVERTER_STATION_2, - EQUIPMENT_NAME, - HVDC_LINE_TAB, -} from '../../../../../utils/field-constants'; -import { FunctionComponent } from 'react'; -import VscHvdcLinePane from '../hvdc-line-pane/vsc-hvdc-line-pane'; -import ConverterStationPane from '../converter-station/converter-station-pane'; -import type { UUID } from 'node:crypto'; -import { VscModificationInfo } from 'services/network-modification-types'; -import { GridSection, PowerMeasurementsForm, TextInput } from '@gridsuite/commons-ui'; -import { Box, Grid, TextField } from '@mui/material'; -import VscTabs from '../vsc-tabs'; -import { UpdateReactiveCapabilityCurveTableConverterStation } from '../converter-station/converter-station-utils'; -import { GridItem } from '../../../../commons/grid-item'; -import { VSC_TABS } from '../vsc-utils'; -import { CurrentTreeNode } from '../../../../../graph/tree-node.type'; - -interface VscModificationFormProps { - tabIndex: number; - studyUuid: UUID; - currentNode: CurrentTreeNode; - currentRootNetworkUuid: UUID; - equipmentId: string; - vscToModify: VscModificationInfo | null; - setTabIndex: React.Dispatch>; - tabIndexesWithError: number[]; - updatePreviousReactiveCapabilityCurveTableConverterStation: UpdateReactiveCapabilityCurveTableConverterStation; -} - -export const VscModificationForm: FunctionComponent = ({ - tabIndex, - setTabIndex, - studyUuid, - currentNode, - currentRootNetworkUuid, - equipmentId, - vscToModify, - tabIndexesWithError, - updatePreviousReactiveCapabilityCurveTableConverterStation, -}) => { - const vscIdField = ( - - ); - - const vscNameField = ( - - ); - - const headersAndTabs = ( - - - {vscIdField} - {vscNameField} - - - - ); - - return ( - <> - {headersAndTabs} - - - - - - ); -}; diff --git a/src/components/dialogs/network-modifications/hvdc-line/vsc/vsc-dialog.type.ts b/src/components/dialogs/network-modifications/hvdc-line/vsc/vsc-dialog.type.ts deleted file mode 100644 index 40021677da..0000000000 --- a/src/components/dialogs/network-modifications/hvdc-line/vsc/vsc-dialog.type.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Copyright (c) 2026, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -import { - ACTIVE_POWER_SETPOINT, - ANGLE_DROOP_ACTIVE_POWER_CONTROL, - CONVERTER_STATION_1, - CONVERTER_STATION_2, - CONVERTERS_MODE, - EQUIPMENT_ID, - EQUIPMENT_NAME, - HVDC_LINE_TAB, - MAX_P, - NOMINAL_V, - OPERATOR_ACTIVE_POWER_LIMIT_SIDE1, - OPERATOR_ACTIVE_POWER_LIMIT_SIDE2, - P0, - R, -} from '../../../../utils/field-constants'; -import { VscConverterStation, VscConverterStationFormInfos } from './converter-station/converter-station-type'; -import { FieldConstants, Property } from '@gridsuite/commons-ui'; - -export type VscDialogSchemaBaseForm = { - [EQUIPMENT_NAME]?: string; - [HVDC_LINE_TAB]: { - [NOMINAL_V]: number | null; - [R]: number | null; - [MAX_P]: number | null; - [OPERATOR_ACTIVE_POWER_LIMIT_SIDE1]?: number; - [OPERATOR_ACTIVE_POWER_LIMIT_SIDE2]?: number; - [CONVERTERS_MODE]: string; - [ANGLE_DROOP_ACTIVE_POWER_CONTROL]?: boolean; - [ACTIVE_POWER_SETPOINT]: number | null; - [P0]: number | null; - [FieldConstants.DROOP]: number | null; - }; - [CONVERTER_STATION_1]: VscConverterStation; - [CONVERTER_STATION_2]: VscConverterStation; - // Properties - [FieldConstants.ADDITIONAL_PROPERTIES]?: Property[]; -}; - -export type VscCreationDialogSchemaForm = { [EQUIPMENT_ID]: string } & VscDialogSchemaBaseForm; - -export interface VscFormInfos { - id: string; - name: string; - nominalV?: number; - r?: number; - activePowerSetpoint?: number; - maxP?: number; - convertersMode?: string; - operatingStatus?: string; - converterStation1?: VscConverterStationFormInfos; - converterStation2?: VscConverterStationFormInfos; - hvdcAngleDroopActivePowerControl?: HvdcAngleDroopActivePowerControlInfos; - hvdcOperatorActivePowerRange?: HvdcOperatorActivePowerRangeInfos; - properties?: Record; -} - -export interface HvdcAngleDroopActivePowerControlInfos { - droop?: number; - isEnabled?: boolean; - p0?: number; -} -export interface HvdcOperatorActivePowerRangeInfos { - oprFromCS1toCS2?: number; - oprFromCS2toCS1?: number; -} diff --git a/src/components/dialogs/network-modifications/hvdc-line/vsc/vsc-tabs.tsx b/src/components/dialogs/network-modifications/hvdc-line/vsc/vsc-tabs.tsx deleted file mode 100644 index 7c9af1ad5a..0000000000 --- a/src/components/dialogs/network-modifications/hvdc-line/vsc/vsc-tabs.tsx +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (c) 2023, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import { Grid, Tab, Tabs } from '@mui/material'; -import { FormattedMessage } from 'react-intl'; -import { getTabIndicatorStyle, getTabStyle } from '../../../../utils/tab-utils'; -import { VSC_TABS } from './vsc-utils'; -import { Dispatch, SetStateAction } from 'react'; - -interface VscTabsProps { - tabIndex: number; - tabIndexesWithError: number[]; - setTabIndex: Dispatch>; - isModification: boolean; -} - -export default function VscTabs({ - tabIndex, - tabIndexesWithError, - setTabIndex, - isModification, -}: Readonly) { - return ( - <> - - setTabIndex(newValue)} - slotProps={{ - indicator: { - sx: getTabIndicatorStyle(tabIndexesWithError, tabIndex), - }, - }} - > - } - sx={getTabStyle(tabIndexesWithError, VSC_TABS.HVDC_LINE_TAB)} - /> - } - sx={getTabStyle(tabIndexesWithError, VSC_TABS.CONVERTER_STATION_1)} - /> - } - sx={getTabStyle(tabIndexesWithError, VSC_TABS.CONVERTER_STATION_2)} - /> - {isModification && ( - } - sx={getTabStyle(tabIndexesWithError, VSC_TABS.STATE_ESTIMATION)} - /> - )} - - - - ); -} diff --git a/src/components/dialogs/network-modifications/hvdc-line/vsc/vsc-utils.ts b/src/components/dialogs/network-modifications/hvdc-line/vsc/vsc-utils.ts deleted file mode 100644 index e214094b7a..0000000000 --- a/src/components/dialogs/network-modifications/hvdc-line/vsc/vsc-utils.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Copyright (c) 2025, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -export const VSC_TABS = { - HVDC_LINE_TAB: 0, - CONVERTER_STATION_1: 1, - CONVERTER_STATION_2: 2, - STATE_ESTIMATION: 3, -}; diff --git a/src/components/dialogs/network-modifications/voltage-level/modification/voltage-level-modification-dialog.tsx b/src/components/dialogs/network-modifications/voltage-level/modification/voltage-level-modification-dialog.tsx index 5a8a6da2e2..0963e1681e 100644 --- a/src/components/dialogs/network-modifications/voltage-level/modification/voltage-level-modification-dialog.tsx +++ b/src/components/dialogs/network-modifications/voltage-level/modification/voltage-level-modification-dialog.tsx @@ -56,7 +56,7 @@ interface VoltageLevelModificationDialogProps { currentRootNetworkUuid: UUID; studyUuid: UUID; isUpdate: boolean; - editDataFetchStatus: FetchStatusType; + editDataFetchStatus?: FetchStatusType; [key: string]: any; } diff --git a/src/components/network/constants.ts b/src/components/network/constants.ts index 83df845b65..e30779a5bc 100644 --- a/src/components/network/constants.ts +++ b/src/components/network/constants.ts @@ -65,32 +65,6 @@ export const VARIATION_TYPES = { TARGET_P: { id: 'TARGET_P', label: 'TargetPText' }, } as const; -export const SWITCH_TYPE = { - BREAKER: { id: 'BREAKER', label: 'Breaker' }, - DISCONNECTOR: { id: 'DISCONNECTOR', label: 'Disconnector' }, -} as const; - -export enum VscConverterMode { - SIDE_1_RECTIFIER_SIDE_2_INVERTER = 'SIDE_1_RECTIFIER_SIDE_2_INVERTER', - SIDE_1_INVERTER_SIDE_2_RECTIFIER = 'SIDE_1_INVERTER_SIDE_2_RECTIFIER', -} - -export interface VscConverterModeValue { - id: string; - label: string; -} - -export const VSC_CONVERTER_MODE: Record = { - [VscConverterMode.SIDE_1_RECTIFIER_SIDE_2_INVERTER]: { - id: 'SIDE_1_RECTIFIER_SIDE_2_INVERTER', - label: 'side1RectifierSide2Inverter', - }, - [VscConverterMode.SIDE_1_INVERTER_SIDE_2_RECTIFIER]: { - id: 'SIDE_1_INVERTER_SIDE_2_RECTIFIER', - label: 'side1InverterSide2Rectifier', - }, -}; - export const REGULATING_TERMINAL_TYPES = [ 'LINE', 'TWO_WINDINGS_TRANSFORMER', diff --git a/src/services/network-modification-types.ts b/src/services/network-modification-types.ts index f1780d7d5f..543ab33041 100644 --- a/src/services/network-modification-types.ts +++ b/src/services/network-modification-types.ts @@ -7,7 +7,6 @@ import type { UUID } from 'node:crypto'; import { Filter } from '../components/dialogs/network-modifications/by-filter/commons/by-filter.type'; -import { ConverterStationElementModificationInfos } from '../components/dialogs/network-modifications/hvdc-line/vsc/converter-station/converter-station-type'; import { AssignmentDataType, AssignmentFieldValue, @@ -24,37 +23,6 @@ export interface WithModificationId { uuid: UUID; } -export interface HvdcAngleDroopActivePowerControlInfo { - isEnabled: boolean; - droop: number; - p0: number; -} - -export interface HvdcOperatorActivePowerRange { - oprFromCS1toCS2: number; - oprFromCS2toCS1: number; -} - -export interface VscModificationInfo { - id: string; - name: string; - nominalV: number; - r: number; - maxP: number; - hvdcOperatorActivePowerRange: HvdcOperatorActivePowerRange; - convertersMode: string; - activePowerSetpoint: number; - hvdcAngleDroopActivePowerControl: HvdcAngleDroopActivePowerControlInfo; - converterStation1: ConverterStationElementModificationInfos; - converterStation2: ConverterStationElementModificationInfos; - voltageLevelId: string; - busOrBusbarSectionId: string; - connectionDirection: string | null; - connectionName?: string | null; - connectionPosition?: string | null; - terminalConnected?: boolean | null; -} - export type VoltageLevelCreationInfo = VoltageLevelCreationDto & { studyUuid: UUID; nodeUuid: UUID; @@ -134,22 +102,6 @@ export interface LCCCreationConverterStation { shuntCompensatorsOnSide: LccShuntCompensatorInfos[]; } -export interface VSCModificationConverterStation { - voltageSetpoint: AttributeModification | null; - lossFactor: AttributeModification | null; - reactiveCapabilityCurve: AttributeModification | null; - busOrBusbarSectionId: AttributeModification | null; - type: string; - minQ: AttributeModification | null; - equipmentId: string; - reactiveCapabilityCurvePoints: ReactiveCapabilityCurvePoints[] | null; - voltageLevelId: AttributeModification | null; - reactivePowerSetpoint: AttributeModification | null; - equipmentName: AttributeModification | null; - voltageRegulationOn: AttributeModification | null; - maxQ: AttributeModification | null; -} - export interface Assignment { dataType?: AssignmentDataType; value?: AssignmentFieldValue; @@ -289,28 +241,6 @@ export interface LccModificationInfos { properties?: Property[] | null; } -export interface VSCModificationInfo { - studyUuid: string; - nodeUuid: UUID; - id: string | null; - name?: string | null; - nominalV: number; - r: number; - maxP: number; - operatorActivePowerLimitSide1: any; - operatorActivePowerLimitSide2: any; - convertersMode: string; - activePowerSetpoint: number; - angleDroopActivePowerControl: boolean; - p0: number | null; - droop: number | null; - converterStation1: VSCModificationConverterStation; - converterStation2: VSCModificationConverterStation; - properties?: Property[] | null; - isUpdate: boolean; - modificationUuid: UUID; -} - type GenerationDispatchInfos = { lossCoefficient: number | null; defaultOutageRate: number | null; diff --git a/src/services/study/network-modifications.ts b/src/services/study/network-modifications.ts index aa25721ca2..006009b63e 100644 --- a/src/services/study/network-modifications.ts +++ b/src/services/study/network-modifications.ts @@ -16,7 +16,6 @@ import { MODIFICATION_TYPES, ModificationType, safeEncodeURIComponent, - toModificationOperation, SubstationCreationDto, SubstationModificationDto, NetworkModificationMetadata, @@ -39,6 +38,8 @@ import { CouplingDeviceCreationDto, CreateVoltageLevelTopologyDto, VoltageLevelSectionCreationDto, + VscHdvLineCreationDto, + VscHdvLineModificationDto, MoveVoltageLevelFeederBaysDto, TopologyVoltageLevelModificationDto, TabularModificationRow, @@ -60,8 +61,6 @@ import { Variations, VariationType, VoltageLevelCreationInfo, - VscCreationInfos, - VSCModificationInfo, } from '../network-modification-types'; function getNetworkModificationUrl(studyUuid: string | null | undefined, nodeUuid: string | undefined) { @@ -1338,91 +1337,49 @@ export function modifyLcc({ }); } -export function createVsc({ - vscCreationInfos, - studyUuid, - nodeUuid, - modificationUuid, - isUpdate, -}: { - vscCreationInfos: VscCreationInfos; - studyUuid: UUID; - nodeUuid: UUID; - modificationUuid?: string | null; - isUpdate: boolean; -}) { +export function createVscHvdcLine( + studyUuid: UUID, + nodeUuid: UUID, + modificationUuid: UUID | undefined, + dto: VscHdvLineCreationDto +) { let createVscUrl = getNetworkModificationUrl(studyUuid, nodeUuid); if (modificationUuid) { createVscUrl += '/' + encodeURIComponent(modificationUuid); - console.info('Updating vsc creation'); + console.info('Updating vsc hvdc line creation'); } else { - console.info('Creating vsc creation'); + console.info('Creating vsc hvdc line creation'); } return backendFetchText(createVscUrl, { - method: isUpdate ? 'PUT' : 'POST', + method: modificationUuid ? 'PUT' : 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, - body: JSON.stringify(vscCreationInfos), + body: JSON.stringify(dto), }); } -export function modifyVsc({ - studyUuid, - nodeUuid, - id, - name, - nominalV, - r, - maxP, - operatorActivePowerLimitSide1, - operatorActivePowerLimitSide2, - convertersMode, - activePowerSetpoint, - angleDroopActivePowerControl, - p0, - droop, - converterStation1, - converterStation2, - properties, - modificationUuid, -}: VSCModificationInfo) { - let modificationUrl = getNetworkModificationUrl(studyUuid, nodeUuid); - +export function modifyVscHvdcLine( + studyUuid: UUID, + nodeUuid: UUID, + modificationUuid: UUID | undefined, + dto: VscHdvLineModificationDto +) { + let updateVscUrl = getNetworkModificationUrl(studyUuid, nodeUuid); if (modificationUuid) { - modificationUrl += '/' + encodeURIComponent(modificationUuid); - console.info('Updating Vsc modification'); + updateVscUrl += '/' + encodeURIComponent(modificationUuid); + console.info('Updating vsc hvdc line modification'); } else { - console.info('Creating Vsc modification'); + console.info('Creating vsc hvdc line modification'); } - - const vscModification = { - type: MODIFICATION_TYPES.VSC_MODIFICATION.type, - equipmentId: id, - equipmentName: toModificationOperation(name), - nominalV: toModificationOperation(nominalV), - r: toModificationOperation(r), - maxP: toModificationOperation(maxP), - operatorActivePowerLimitFromSide1ToSide2: toModificationOperation(operatorActivePowerLimitSide1), - operatorActivePowerLimitFromSide2ToSide1: toModificationOperation(operatorActivePowerLimitSide2), - convertersMode: toModificationOperation(convertersMode), - activePowerSetpoint: toModificationOperation(activePowerSetpoint), - angleDroopActivePowerControl: toModificationOperation(angleDroopActivePowerControl), - p0: toModificationOperation(p0), - droop: toModificationOperation(droop), - converterStation1: converterStation1, - converterStation2: converterStation2, - properties: properties, - }; //add missing informations - - return backendFetchText(modificationUrl, { + return backendFetchText(updateVscUrl, { method: modificationUuid ? 'PUT' : 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, - body: JSON.stringify(vscModification), + body: JSON.stringify(dto), }); } diff --git a/src/translations/messages-en.ts b/src/translations/messages-en.ts index b3a5491482..15796e4874 100644 --- a/src/translations/messages-en.ts +++ b/src/translations/messages-en.ts @@ -577,7 +577,6 @@ const messages_en = { 'withoutunit.directTransX': 'Transient reactance', 'withoutunit.stepUpTransformerX': 'Transformer reactance', 'withoutunit.plannedActivePowerSetPoint': 'Planning P', - CreateVsc: 'Create HVDC (VSC)', CreateLcc: 'Create HVDC (LCC)', Filters: 'Filters', Side: 'Side', @@ -593,10 +592,7 @@ const messages_en = { shuntCompensatorType: 'Type', Information: 'Information', FillAllFields: 'Please fill all fields', - ModifySubstation: 'Modify substation', - ModifyVsc: 'Modify HVDC (VSC)', ModifyLcc: 'Modify HVDC (LCC)', - SubstationModificationError: 'Error while modifying substation', CreateVoltageLevel: 'Create a voltage level', Substation: 'Substation', @@ -974,11 +970,6 @@ const messages_en = { converterModeLabel: 'Converters mode', lossFactorLabel: 'Loss Factor', powerFactorLabel: 'Power Factor', - angleDroopActivePowerControlLabel: 'Angle droop active power control', - p0Label: 'P0', - droopLabel: 'k', - side1RectifierSide2Inverter: 'Flow (Side1->Side2)', - side1InverterSide2Rectifier: 'Flow (Side2->Side1)', 'withoutunit.g': 'Magnetizing conductance', 'withoutunit.b': 'Magnetizing susceptance', diff --git a/src/translations/messages-fr.ts b/src/translations/messages-fr.ts index 9d4b0e53dd..33361b560d 100644 --- a/src/translations/messages-fr.ts +++ b/src/translations/messages-fr.ts @@ -583,7 +583,6 @@ const messages_fr = { 'withoutunit.directTransX': 'Réactance transitoire', 'withoutunit.stepUpTransformerX': 'Réactance du transformateur', 'withoutunit.plannedActivePowerSetPoint': 'P imposée', - CreateVsc: "Création d'une HVDC (VSC)", CreateLcc: "Création d'une HVDC (LCC)", Filters: 'Filtres', Side: 'Côté', @@ -596,10 +595,7 @@ const messages_fr = { shuntCompensatorType: 'Type', Information: 'Information', FillAllFields: 'Veuillez remplir tous les champs', - ModifySubstation: 'Modifier un site', - ModifyVsc: 'Modifier une HVDC (VSC)', ModifyLcc: 'Modifier une HVDC (LCC)', - SubstationModificationError: "Erreur lors de la modification d'un site", CreateVoltageLevel: 'Créer un poste', Substation: 'Site', @@ -985,11 +981,6 @@ const messages_fr = { converterModeLabel: 'Mode de fonctionnement des stations', lossFactorLabel: 'Coefficient de pertes', powerFactorLabel: 'Coefficient Q/P', - angleDroopActivePowerControlLabel: 'Emulation AC', - p0Label: 'P0', - droopLabel: 'Gain', - side1RectifierSide2Inverter: 'Flux (1->2)', - side1InverterSide2Rectifier: 'Flux (2->1)', shuntCompensatorId: 'ID du MCS', shuntCompensatorName: 'Nom du MCS', connectedToHvdc: 'Connecté à HVDC',