diff --git a/src/components/dialogs/network-modifications/voltage-level/creation/voltage-level-creation-dialog.jsx b/src/components/dialogs/network-modifications/voltage-level/creation/voltage-level-creation-dialog.jsx
index 27d924635a..836880d836 100644
--- a/src/components/dialogs/network-modifications/voltage-level/creation/voltage-level-creation-dialog.jsx
+++ b/src/components/dialogs/network-modifications/voltage-level/creation/voltage-level-creation-dialog.jsx
@@ -10,6 +10,7 @@ import {
convertOutputValue,
CustomFormProvider,
FieldType,
+ MODIFICATION_TYPES,
useSnackMessage,
} from '@gridsuite/commons-ui';
import { yupResolver } from '@hookform/resolvers/yup';
@@ -17,9 +18,12 @@ import { sanitizeString } from 'components/dialogs/dialog-utils';
import EquipmentSearchDialog from 'components/dialogs/equipment-search-dialog';
import { useFormSearchCopy } from 'components/dialogs/form-search-copy-hook';
import {
+ ADD_SUBSTATION_CREATION,
+ ADDITIONAL_PROPERTIES,
BUS_BAR_COUNT,
BUS_BAR_SECTION_ID1,
BUS_BAR_SECTION_ID2,
+ COUNTRY,
COUPLING_OMNIBUS,
EQUIPMENT_ID,
EQUIPMENT_NAME,
@@ -31,7 +35,10 @@ import {
NAME,
NOMINAL_V,
SECTION_COUNT,
+ SUBSTATION_CREATION,
+ SUBSTATION_CREATION_ID,
SUBSTATION_ID,
+ SUBSTATION_NAME,
SWITCH_KIND,
SWITCH_KINDS,
SWITCHES_BETWEEN_SECTIONS,
@@ -84,6 +91,11 @@ const emptyFormData = {
[SWITCHES_BETWEEN_SECTIONS]: '',
[COUPLING_OMNIBUS]: [],
[SWITCH_KINDS]: [],
+ [ADD_SUBSTATION_CREATION]: false,
+ [SUBSTATION_CREATION_ID]: null,
+ [SUBSTATION_NAME]: null,
+ [COUNTRY]: null,
+ [SUBSTATION_CREATION]: emptyProperties,
...emptyProperties,
};
@@ -92,7 +104,23 @@ const formSchema = yup
.shape({
[EQUIPMENT_ID]: yup.string().required(),
[EQUIPMENT_NAME]: yup.string().nullable(),
- [SUBSTATION_ID]: yup.string().nullable().required(),
+ [SUBSTATION_ID]: yup
+ .string()
+ .nullable()
+ .when([ADD_SUBSTATION_CREATION], {
+ is: (addSubstationCreation) => addSubstationCreation === false,
+ then: (schema) => schema.required(),
+ }),
+ [SUBSTATION_CREATION_ID]: yup
+ .string()
+ .nullable()
+ .when([ADD_SUBSTATION_CREATION], {
+ is: (addSubstationCreation) => addSubstationCreation === true,
+ then: (schema) => schema.required(),
+ }),
+ [SUBSTATION_NAME]: yup.string().nullable(),
+ [COUNTRY]: yup.string().nullable(),
+ [SUBSTATION_CREATION]: creationPropertiesSchema,
[NOMINAL_V]: yup.number().nullable().required(),
[LOW_VOLTAGE_LIMIT]: yup.number().nullable(),
[HIGH_VOLTAGE_LIMIT]: yup.number().nullable(),
@@ -148,22 +176,12 @@ const VoltageLevelCreationDialog = ({
resolver: yupResolver(formSchema),
});
- const { reset } = formMethods;
+ const { reset, setValue, getValues } = formMethods;
const intl = useIntl();
-
const fromExternalDataToFormValues = useCallback(
(voltageLevel, fromCopy = true) => {
- const properties = fromCopy
- ? copyEquipmentPropertiesForCreation(voltageLevel)
- : getPropertiesFromModification(voltageLevel.properties);
- reset({
- [EQUIPMENT_ID]: (voltageLevel[EQUIPMENT_ID] ?? voltageLevel[ID]) + (fromCopy ? '(1)' : ''),
- [EQUIPMENT_NAME]: voltageLevel[EQUIPMENT_NAME] ?? voltageLevel[NAME],
- [TOPOLOGY_KIND]: voltageLevel[TOPOLOGY_KIND],
- [SUBSTATION_ID]: voltageLevel[SUBSTATION_ID],
- [NOMINAL_V]: voltageLevel[NOMINAL_V],
- [LOW_VOLTAGE_LIMIT]: voltageLevel[LOW_VOLTAGE_LIMIT],
- [HIGH_VOLTAGE_LIMIT]: voltageLevel[HIGH_VOLTAGE_LIMIT],
+ const isSubstationCreation = !fromCopy && voltageLevel.substationCreation?.equipmentId != null;
+ const shortCircuitLimits = {
[LOW_SHORT_CIRCUIT_CURRENT_LIMIT]: convertInputValue(
FieldType.LOW_SHORT_CIRCUIT_CURRENT_LIMIT,
fromCopy ? voltageLevel.identifiableShortCircuit?.ipMin : voltageLevel.ipMin
@@ -172,29 +190,67 @@ const VoltageLevelCreationDialog = ({
FieldType.HIGH_SHORT_CIRCUIT_CURRENT_LIMIT,
fromCopy ? voltageLevel.identifiableShortCircuit?.ipMax : voltageLevel.ipMax
),
- [BUS_BAR_COUNT]: voltageLevel[BUS_BAR_COUNT] ?? 1,
- [SECTION_COUNT]: voltageLevel[SECTION_COUNT] ?? 1,
- [SWITCHES_BETWEEN_SECTIONS]: voltageLevel.switchKinds
- ?.map((switchKind) => {
- return intl.formatMessage({ id: switchKind });
- })
- .join(' / '),
- [COUPLING_OMNIBUS]: voltageLevel.couplingDevices ?? [],
- [SWITCH_KINDS]:
- voltageLevel.switchKinds != null
- ? voltageLevel.switchKinds?.map((switchKind) => ({
- [SWITCH_KIND]: switchKind,
- }))
- : [],
- ...properties,
- });
+ };
+ const switchKinds =
+ voltageLevel.switchKinds?.map((switchKind) => ({
+ [SWITCH_KIND]: switchKind,
+ })) || [];
+
+ const switchesBetweenSections =
+ voltageLevel.switchKinds?.map((switchKind) => intl.formatMessage({ id: switchKind })).join(' / ') || '';
+
+ const equipmentId = (voltageLevel[EQUIPMENT_ID] ?? voltageLevel[ID]) + (fromCopy ? '(1)' : '');
+ const equipmentName = voltageLevel[EQUIPMENT_NAME] ?? voltageLevel[NAME];
+ const substationId = isSubstationCreation ? null : voltageLevel[SUBSTATION_ID] ?? null;
+
+ const properties = fromCopy
+ ? copyEquipmentPropertiesForCreation(voltageLevel)
+ : getPropertiesFromModification(voltageLevel.properties);
+ reset(
+ {
+ [EQUIPMENT_ID]: equipmentId,
+ [EQUIPMENT_NAME]: equipmentName,
+ [TOPOLOGY_KIND]: voltageLevel[TOPOLOGY_KIND],
+ [SUBSTATION_ID]: substationId,
+ [NOMINAL_V]: voltageLevel[NOMINAL_V],
+ [LOW_VOLTAGE_LIMIT]: voltageLevel[LOW_VOLTAGE_LIMIT],
+ [HIGH_VOLTAGE_LIMIT]: voltageLevel[HIGH_VOLTAGE_LIMIT],
+ [LOW_VOLTAGE_LIMIT]: voltageLevel[LOW_VOLTAGE_LIMIT],
+ [HIGH_VOLTAGE_LIMIT]: voltageLevel[HIGH_VOLTAGE_LIMIT],
+ ...shortCircuitLimits,
+ [BUS_BAR_COUNT]: voltageLevel[BUS_BAR_COUNT] ?? 1,
+ [SECTION_COUNT]: voltageLevel[SECTION_COUNT] ?? 1,
+ [SWITCHES_BETWEEN_SECTIONS]: switchesBetweenSections,
+ [COUPLING_OMNIBUS]: voltageLevel.couplingDevices ?? [],
+ [SWITCH_KINDS]: switchKinds,
+ ...properties,
+ },
+ { keepDefaultValues: true }
+ );
+ if (isSubstationCreation) {
+ const substationKeys = [
+ [SUBSTATION_CREATION_ID, voltageLevel.substationCreation?.equipmentId],
+ [SUBSTATION_NAME, voltageLevel.substationCreation?.equipmentName],
+ [COUNTRY, voltageLevel.substationCreation?.country],
+ ];
+ substationKeys.forEach(([key, value]) => {
+ setValue(key, value);
+ });
+ setValue(
+ `${SUBSTATION_CREATION}.${ADDITIONAL_PROPERTIES}`,
+ voltageLevel.substationCreation?.properties
+ );
+ setValue(ADD_SUBSTATION_CREATION, true);
+ } else {
+ setValue(ADD_SUBSTATION_CREATION, false);
+ }
if (!voltageLevel.isRetrievedBusbarSections && fromCopy) {
snackWarning({
messageId: 'BusBarSectionsCopyingNotSupported',
});
}
},
- [intl, reset, snackWarning]
+ [setValue, intl, reset, snackWarning]
);
const searchCopy = useFormSearchCopy({
@@ -213,12 +269,22 @@ const VoltageLevelCreationDialog = ({
const onSubmit = useCallback(
(voltageLevel) => {
+ const substationCreation = getValues(ADD_SUBSTATION_CREATION)
+ ? {
+ type: MODIFICATION_TYPES.SUBSTATION_CREATION.type,
+ equipmentId: voltageLevel[SUBSTATION_CREATION_ID],
+ equipmentName: voltageLevel[SUBSTATION_NAME],
+ country: voltageLevel[COUNTRY],
+ properties: toModificationProperties(voltageLevel[SUBSTATION_CREATION]),
+ }
+ : null;
onCreateVoltageLevel({
studyUuid: studyUuid,
nodeUuid: currentNodeUuid,
voltageLevelId: voltageLevel[EQUIPMENT_ID],
voltageLevelName: sanitizeString(voltageLevel[EQUIPMENT_NAME]),
- substationId: voltageLevel[SUBSTATION_ID],
+ substationId: substationCreation === null ? voltageLevel[SUBSTATION_ID] : null,
+ substationCreation: substationCreation,
nominalV: voltageLevel[NOMINAL_V],
lowVoltageLimit: voltageLevel[LOW_VOLTAGE_LIMIT],
highVoltageLimit: voltageLevel[HIGH_VOLTAGE_LIMIT],
@@ -247,7 +313,7 @@ const VoltageLevelCreationDialog = ({
});
});
},
- [onCreateVoltageLevel, studyUuid, currentNodeUuid, editData, snackError]
+ [getValues, onCreateVoltageLevel, studyUuid, currentNodeUuid, editData, snackError]
);
const clear = useCallback(() => {
diff --git a/src/components/dialogs/network-modifications/voltage-level/creation/voltage-level-creation-form.jsx b/src/components/dialogs/network-modifications/voltage-level/creation/voltage-level-creation-form.jsx
index aa221b626c..3e9ae2d619 100644
--- a/src/components/dialogs/network-modifications/voltage-level/creation/voltage-level-creation-form.jsx
+++ b/src/components/dialogs/network-modifications/voltage-level/creation/voltage-level-creation-form.jsx
@@ -6,7 +6,9 @@
*/
import {
+ ADD_SUBSTATION_CREATION,
BUS_BAR_COUNT,
+ COUNTRY,
EQUIPMENT_ID,
EQUIPMENT_NAME,
HIGH_SHORT_CIRCUIT_CURRENT_LIMIT,
@@ -15,31 +17,42 @@ import {
LOW_VOLTAGE_LIMIT,
NOMINAL_V,
SECTION_COUNT,
+ SUBSTATION_CREATION,
+ SUBSTATION_CREATION_ID,
SUBSTATION_ID,
+ SUBSTATION_NAME,
} from 'components/utils/field-constants';
-import { useEffect, useState } from 'react';
-import { VoltageAdornment, KiloAmpereAdornment } from 'components/dialogs/dialog-utils';
-import { FloatInput } from '@gridsuite/commons-ui';
-import { TextInput } from '@gridsuite/commons-ui';
-import { AutocompleteInput } from '@gridsuite/commons-ui';
-import { getObjectId } from 'components/utils/utils';
-import { Box, Grid } from '@mui/material';
-import { IntegerInput } from '@gridsuite/commons-ui';
+import { useCallback, useEffect, useState } from 'react';
+import { KiloAmpereAdornment, VoltageAdornment } from 'components/dialogs/dialog-utils';
+import { AutocompleteInput, FloatInput, IntegerInput, TextInput } from '@gridsuite/commons-ui';
+import { Box, Grid, Paper } from '@mui/material';
import { CouplingOmnibusForm } from '../coupling-omnibus/coupling-omnibus-form';
import { SwitchesBetweenSections } from '../switches-between-sections/switches-between-sections';
import { fetchEquipmentsIds } from '../../../../../services/study/network-map';
import PropertiesForm from '../../common/properties/properties-form';
-import { useWatch } from 'react-hook-form';
+import { useFormContext, useWatch } from 'react-hook-form';
import GridItem from '../../../commons/grid-item';
import GridSection from '../../../commons/grid-section';
+import IconButton from '@mui/material/IconButton';
+import { useIntl } from 'react-intl';
+import CountrySelectionInput from '../../../../utils/rhf-inputs/country-selection-input';
+import DeleteIcon from '@mui/icons-material/Delete';
+import LineSeparator from '../../../commons/line-separator';
const VoltageLevelCreationForm = ({ currentNode, studyUuid }) => {
const currentNodeUuid = currentNode?.id;
+ const intl = useIntl();
+ const { setValue } = useFormContext();
const [substations, setSubstations] = useState([]);
-
+ const [isWithSubstationCreation, setIsWithSubstationCreation] = useState(false);
const watchBusBarCount = useWatch({ name: BUS_BAR_COUNT });
const watchSectionCount = useWatch({ name: SECTION_COUNT });
+ const watchAddSubstationCreation = useWatch({ name: ADD_SUBSTATION_CREATION });
+ const [selectedNewSubstation, setSelectedNewSubstation] = useState('');
+ useEffect(() => {
+ setIsWithSubstationCreation(watchAddSubstationCreation);
+ }, [watchAddSubstationCreation]);
useEffect(() => {
if (studyUuid && currentNodeUuid) {
@@ -53,22 +66,50 @@ const VoltageLevelCreationForm = ({ currentNode, studyUuid }) => {
);
+ function getCustomPaper(children) {
+ return (
+
+
+ {children}
+
+
+ {`${intl.formatMessage({ id: 'CreateSubstation' })} : ${selectedNewSubstation}`}
+
+
+
+ );
+ }
+
+ const handleAddButton = useCallback(() => {
+ setValue(SUBSTATION_CREATION_ID, selectedNewSubstation);
+ setValue(ADD_SUBSTATION_CREATION, true);
+ setIsWithSubstationCreation(true);
+ }, [selectedNewSubstation, setValue]);
const voltageLevelNameField = ;
const substationField = (
(value === null ? '' : value)}
outputTransform={(value) => value}
size={'small'}
formProps={{ margin: 'normal' }}
+ PaperComponent={({ children }) => getCustomPaper(children)}
+ onInputChange={(_, value) => {
+ if (typeof value === 'string') {
+ setSelectedNewSubstation(value);
+ }
+ }}
+ noOptionsText={''}
/>
);
@@ -106,14 +147,57 @@ const VoltageLevelCreationForm = ({ currentNode, studyUuid }) => {
const couplingOmnibusForm = ;
+ const substationCreationIdField = ;
+ const substationCreationNameField = ;
+
+ const substationCreationCountryField = ;
+
+ const handleDeleteButton = useCallback(() => {
+ setSelectedNewSubstation('');
+ setValue(ADD_SUBSTATION_CREATION, false);
+ setIsWithSubstationCreation(false);
+ }, [setValue]);
+
return (
<>
- {voltageLevelIdField}
- {voltageLevelNameField}
- {substationField}
+ {voltageLevelIdField}
+ {voltageLevelNameField}
-
+
+ {isWithSubstationCreation ? (
+
+
+
+
+
+ {substationCreationIdField}
+
+
+ {substationCreationNameField}
+
+
+ {substationCreationCountryField}
+
+
+
+
+
+
+
+
+
+
+
+
+ ) : (
+
+
+ {substationField}
+
+
+ )}
+
{nominalVoltageField}
{lowVoltageLimitField}
diff --git a/src/components/utils/field-constants.ts b/src/components/utils/field-constants.ts
index 517d444ef5..244816de20 100644
--- a/src/components/utils/field-constants.ts
+++ b/src/components/utils/field-constants.ts
@@ -7,6 +7,10 @@
export const EQUIPMENT_ID = 'equipmentId';
export const EQUIPMENT_NAME = 'equipmentName';
+export const SUBSTATION_NAME = 'substationName';
+export const SUBSTATION_CREATION_ID = 'substationCreationId';
+export const ADD_SUBSTATION_CREATION = 'addSubstationCreationId';
+export const SUBSTATION_CREATION = 'substationCreation';
export const LOAD_TYPE = 'loadType';
export const CONNECTIVITY = 'connectivity';
export const SETPOINTS_LIMITS = 'setpointsLimits';
diff --git a/src/services/network-modification-types.ts b/src/services/network-modification-types.ts
index e44d2113c1..0c47763967 100644
--- a/src/services/network-modification-types.ts
+++ b/src/services/network-modification-types.ts
@@ -286,6 +286,7 @@ export interface VoltageLeveInfo {
}
export interface VoltageLeveCreationlInfo extends VoltageLeveInfo {
+ substationCreation?: SubstationCreationInfo | null;
ipMin: number | null;
ipMax: number | null;
}
diff --git a/src/services/study/network-modifications.ts b/src/services/study/network-modifications.ts
index 1ca88c4af2..0ab6b58ee1 100644
--- a/src/services/study/network-modifications.ts
+++ b/src/services/study/network-modifications.ts
@@ -1373,6 +1373,7 @@ export function createVoltageLevel({
voltageLevelId,
voltageLevelName,
substationId,
+ substationCreation,
nominalV,
lowVoltageLimit,
highVoltageLimit,
@@ -1400,6 +1401,7 @@ export function createVoltageLevel({
equipmentId: voltageLevelId,
equipmentName: voltageLevelName,
substationId: substationId,
+ substationCreation: substationCreation,
nominalV: nominalV,
lowVoltageLimit: lowVoltageLimit,
highVoltageLimit: highVoltageLimit,
diff --git a/src/translations/en.json b/src/translations/en.json
index 779adf7108..af6b3b3800 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -663,6 +663,7 @@
"TabularModificationError": "Error while creating tabular modification",
"TabularModificationShuntWarning": "Both maximum reactive power (and/or type) and maximum susceptance have been submitted for the same shunt compensator. Maximum susceptance will thus be ignored.",
"equipmentId": "ID",
+ "substationName": "Substation name",
"activePower": "p (MW)",
"maxActivePower": "Max P (MW)",
"maxP": "Max P (MW)",
diff --git a/src/translations/fr.json b/src/translations/fr.json
index 2f12b55bb8..6c63d5b451 100644
--- a/src/translations/fr.json
+++ b/src/translations/fr.json
@@ -663,6 +663,7 @@
"TabularModificationError": "Erreur lors de la modification tabulaire",
"TabularModificationShuntWarning": "La modification tabulaire contient des valeurs pour la puissance réactive installée (et/ou le type) et la susceptance installée d'un même MCS. La susceptance installée sera donc ignorée.",
"equipmentId": "ID",
+ "substationName": "Nom du site",
"activePower": "p (MW)",
"maxActivePower": "P max (MW)",
"maxP": "P max (MW)",