diff --git a/src/components/dialogs/network-modifications/voltage-level/coupling-omnibus/coupling-omnibus-creation.tsx b/src/components/dialogs/network-modifications/voltage-level/coupling-omnibus/coupling-omnibus-creation.tsx deleted file mode 100644 index 7c37d4f286..0000000000 --- a/src/components/dialogs/network-modifications/voltage-level/coupling-omnibus/coupling-omnibus-creation.tsx +++ /dev/null @@ -1,66 +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 { AutocompleteInput, Option } from '@gridsuite/commons-ui'; -import { BUS_BAR_SECTION_ID1, BUS_BAR_SECTION_ID2, COUPLING_OMNIBUS } from 'components/utils/field-constants'; -import GridItem from '../../../commons/grid-item'; -import { useEffect } from 'react'; -import { useFormContext } from 'react-hook-form'; - -interface CouplingOmnibusCreationProps { - index: number; - sectionOptions: Option[]; -} - -// TODO should use "name" props instead of `${COUPLING_OMNIBUS}.(...)` -export const CouplingOmnibusCreation = ({ index, sectionOptions }: CouplingOmnibusCreationProps) => { - const { getValues, trigger, subscribe } = useFormContext(); - // Watch BUS_BAR_SECTION_ID1 changed - useEffect(() => { - const unsubscribe = subscribe({ - name: [`${COUPLING_OMNIBUS}.${index}.${BUS_BAR_SECTION_ID1}`], - formState: { - values: true, - }, - callback: () => { - // force trigger validation on BUS_BAR_SECTION_ID2 if it has a value - if (getValues(`${COUPLING_OMNIBUS}.${index}.${BUS_BAR_SECTION_ID2}`)) { - trigger(`${COUPLING_OMNIBUS}.${index}.${BUS_BAR_SECTION_ID2}`); - } - }, - }); - return () => unsubscribe(); - }, [subscribe, trigger, getValues, index]); - - const busBarSectionId1Field = ( - - ); - const busBarSectionId2Field = ( - - ); - - return ( - <> - {busBarSectionId1Field} - {busBarSectionId2Field} - - ); -}; diff --git a/src/components/dialogs/network-modifications/voltage-level/coupling-omnibus/coupling-omnibus-form.tsx b/src/components/dialogs/network-modifications/voltage-level/coupling-omnibus/coupling-omnibus-form.tsx deleted file mode 100644 index d22023d6a0..0000000000 --- a/src/components/dialogs/network-modifications/voltage-level/coupling-omnibus/coupling-omnibus-form.tsx +++ /dev/null @@ -1,57 +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 { - BUS_BAR_COUNT, - BUS_BAR_SECTION_ID1, - BUS_BAR_SECTION_ID2, - COUPLING_OMNIBUS, - EQUIPMENT_ID, - SECTION_COUNT, -} from 'components/utils/field-constants'; -import { CouplingOmnibusCreation } from './coupling-omnibus-creation'; -import { useEffect, useMemo } from 'react'; -import { useFormContext, useWatch } from 'react-hook-form'; -import { buildNewBusbarSections } from 'components/utils/utils'; -import { ExpandableInput } from '@gridsuite/commons-ui'; - -export const CouplingOmnibusForm = () => { - const { setValue } = useFormContext(); - - const couplingOmnibusCreation = { - [BUS_BAR_SECTION_ID1]: null, - [BUS_BAR_SECTION_ID2]: null, - }; - - const watchVoltageLevelID = useWatch({ name: EQUIPMENT_ID }); - const watchBusBarCount = useWatch({ name: BUS_BAR_COUNT }); - const watchSectionCount = useWatch({ name: SECTION_COUNT }); - - const sectionOptions = useMemo(() => { - if (watchVoltageLevelID && watchBusBarCount && watchSectionCount) { - return buildNewBusbarSections(watchVoltageLevelID, watchSectionCount, watchBusBarCount).map((section) => { - return typeof section === 'string' ? section : section.id; - }); - } - return []; - }, [watchVoltageLevelID, watchBusBarCount, watchSectionCount]); - - useEffect(() => { - // the cleanup function is triggered every time sectionOptions changes and when unmounting - return () => setValue(COUPLING_OMNIBUS, []); - }, [sectionOptions, setValue]); - - return ( - - ); -}; diff --git a/src/components/dialogs/network-modifications/voltage-level/creation/voltage-level-creation-dialog.tsx b/src/components/dialogs/network-modifications/voltage-level/creation/voltage-level-creation-dialog.tsx index 1884cbc5f4..6d885f7919 100644 --- a/src/components/dialogs/network-modifications/voltage-level/creation/voltage-level-creation-dialog.tsx +++ b/src/components/dialogs/network-modifications/voltage-level/creation/voltage-level-creation-dialog.tsx @@ -6,61 +6,31 @@ */ import { - convertInputValue, - convertOutputValue, - copyEquipmentPropertiesForCreation, - creationPropertiesSchema, CustomFormProvider, - emptyProperties, + DeepNullable, EquipmentType, - FieldType, - getPropertiesFromModification, - MODIFICATION_TYPES, - Properties, - Property, + FieldConstants, snackWithFallback, - toModificationProperties, useSnackMessage, - DeepNullable, - sanitizeString, - FieldConstants, + VoltageLevelCreationDto, + VoltageLevelCreationFormData, + VoltageLevelFormInfos, + voltageLevelCreationDtoToForm, + voltageLevelInfosToForm, + voltageLevelCreationEmptyFormData, + voltageLevelCreationFormSchema, + voltageLevelCreationFormToDto, } from '@gridsuite/commons-ui'; import { yupResolver } from '@hookform/resolvers/yup'; import EquipmentSearchDialog from 'components/dialogs/equipment-search-dialog'; import { useFormSearchCopy } from 'components/dialogs/commons/use-form-search-copy'; -import { - ADD_SUBSTATION_CREATION, - BUS_BAR_COUNT, - BUS_BAR_SECTION_ID1, - BUS_BAR_SECTION_ID2, - COUPLING_OMNIBUS, - EQUIPMENT_ID, - HIGH_SHORT_CIRCUIT_CURRENT_LIMIT, - HIGH_VOLTAGE_LIMIT, - ID, - IS_ATTACHMENT_POINT_CREATION, - LOW_SHORT_CIRCUIT_CURRENT_LIMIT, - LOW_VOLTAGE_LIMIT, - NAME, - NOMINAL_V, - SECTION_COUNT, - SUBSTATION_CREATION, - SUBSTATION_CREATION_ID, - SUBSTATION_ID, - SUBSTATION_NAME, - SWITCH_KIND, - SWITCH_KINDS, - SWITCHES_BETWEEN_SECTIONS, - TOPOLOGY_KIND, -} from 'components/utils/field-constants'; -import yup from 'components/utils/yup-config'; import { FC, useCallback, useEffect, useMemo } from 'react'; import { useForm } from 'react-hook-form'; import { ModificationDialog } from 'components/dialogs/commons/modificationDialog'; -import VoltageLevelCreationForm from './voltage-level-creation-form'; -import { EQUIPMENT_TYPES } from 'components/utils/equipment-types'; import { useIntl } from 'react-intl'; +import StudyVoltageLevelCreationForm from './voltage-level-creation-form'; +import { EQUIPMENT_TYPES } from 'components/utils/equipment-types'; import { FORM_LOADING_DELAY } from 'components/network/constants'; import { useOpenShortWaitFetching } from '../../../commons/handle-modification-form'; import { createVoltageLevel } from '../../../../../services/study/network-modifications'; @@ -68,41 +38,18 @@ import { FetchStatus } from '../../../../../services/utils'; import { UUID } from 'node:crypto'; import { AttachedSubstationCreationInfo, + CouplingDeviceInfos, SwitchKind, VoltageLevelCreationInfo, } from '../../../../../services/network-modification-types'; import { CurrentTreeNode } from '../../../../graph/tree-node.type'; -import { CreateCouplingDeviceDialogSchemaForm } from '../../coupling-device/coupling-device-dialog.type'; -export type SwitchKindFormData = { [SWITCH_KIND]: string }; - -interface VoltageLevelCreationFormData { - [FieldConstants.ADDITIONAL_PROPERTIES]?: Property[]; - [ADD_SUBSTATION_CREATION]: boolean; - [BUS_BAR_COUNT]: number; - [FieldConstants.COUNTRY]: string | null; - [COUPLING_OMNIBUS]: CreateCouplingDeviceDialogSchemaForm[]; - [EQUIPMENT_ID]: string; - [FieldConstants.EQUIPMENT_NAME]: string; - [HIGH_SHORT_CIRCUIT_CURRENT_LIMIT]: number | null; - [HIGH_VOLTAGE_LIMIT]: number | null; - [IS_ATTACHMENT_POINT_CREATION]: boolean; - [LOW_SHORT_CIRCUIT_CURRENT_LIMIT]: number | null; - [LOW_VOLTAGE_LIMIT]: number | null; - [NOMINAL_V]: number | null; - [SECTION_COUNT]: number; - [SUBSTATION_CREATION]: Properties; - [SUBSTATION_CREATION_ID]: string | null; - [SUBSTATION_ID]: string | null; - [SUBSTATION_NAME]: string | null; - [SWITCHES_BETWEEN_SECTIONS]: string; - [SWITCH_KINDS]: SwitchKindFormData[]; - [TOPOLOGY_KIND]: string | null; +interface StudyVoltageLevelCreationDto extends VoltageLevelCreationDto { uuid?: UUID; } interface VoltageLevelCreationDialogProps { - editData?: VoltageLevelCreationFormData; + editData?: StudyVoltageLevelCreationDto; currentNode: CurrentTreeNode; studyUuid: string; currentRootNetworkUuid: UUID; @@ -116,7 +63,7 @@ interface VoltageLevelCreationDialogProps { } /** - * Dialog to create a load in the network + * Dialog to create a voltage level in the network * @param currentNode The node we are currently working on * @param studyUuid the study we are currently working on * @param editData the data to edit @@ -126,142 +73,6 @@ interface VoltageLevelCreationDialogProps { * @param editDataFetchStatus indicates the status of fetching EditData */ -const emptyFormData: VoltageLevelCreationFormData = { - [EQUIPMENT_ID]: '', - [FieldConstants.EQUIPMENT_NAME]: '', - [SUBSTATION_ID]: null, - [NOMINAL_V]: null, - [LOW_VOLTAGE_LIMIT]: null, - [HIGH_VOLTAGE_LIMIT]: null, - [LOW_SHORT_CIRCUIT_CURRENT_LIMIT]: null, - [HIGH_SHORT_CIRCUIT_CURRENT_LIMIT]: null, - [BUS_BAR_COUNT]: 1, - [SECTION_COUNT]: 1, - [SWITCHES_BETWEEN_SECTIONS]: '', - [COUPLING_OMNIBUS]: [], - [SWITCH_KINDS]: [], - [ADD_SUBSTATION_CREATION]: false, - [SUBSTATION_CREATION_ID]: null, - [SUBSTATION_NAME]: null, - [FieldConstants.COUNTRY]: null, - [IS_ATTACHMENT_POINT_CREATION]: false, - [TOPOLOGY_KIND]: null, - [SUBSTATION_CREATION]: emptyProperties, -}; - -const formSchema = yup - .object() - .shape({ - [EQUIPMENT_ID]: yup - .string() - .required() - .when([ADD_SUBSTATION_CREATION], { - is: (addSubstationCreation: boolean) => !addSubstationCreation, - then: (schema) => - schema.notOneOf([yup.ref(SUBSTATION_ID), null], 'CreateSubstationInVoltageLevelIdenticalId'), - }) - .when([ADD_SUBSTATION_CREATION], { - is: (addSubstationCreation: boolean) => addSubstationCreation, - then: (schema) => - schema.notOneOf( - [yup.ref(SUBSTATION_CREATION_ID), null], - 'CreateSubstationInVoltageLevelIdenticalId' - ), - }), - [FieldConstants.EQUIPMENT_NAME]: yup.string().nullable(), - [ADD_SUBSTATION_CREATION]: yup.boolean().required(), - [SUBSTATION_ID]: yup - .string() - .nullable() - .when([ADD_SUBSTATION_CREATION], { - is: (addSubstationCreation: boolean) => !addSubstationCreation, - then: (schema) => - schema - .required() - .notOneOf([yup.ref(EQUIPMENT_ID), null], 'CreateSubstationInVoltageLevelIdenticalId'), - }), - [SUBSTATION_CREATION_ID]: yup - .string() - .nullable() - .when([ADD_SUBSTATION_CREATION], { - is: (addSubstationCreation: boolean) => addSubstationCreation, - then: (schema) => - schema - .required() - .notOneOf([yup.ref(EQUIPMENT_ID), null], 'CreateSubstationInVoltageLevelIdenticalId'), - }), - [SUBSTATION_NAME]: yup.string().nullable(), - [FieldConstants.COUNTRY]: yup.string().nullable(), - [SUBSTATION_CREATION]: creationPropertiesSchema, - [NOMINAL_V]: yup - .number() - .nullable() - .when([IS_ATTACHMENT_POINT_CREATION], { - is: (isAttachmentPointCreation: boolean) => !isAttachmentPointCreation, - then: (schema) => schema.min(0, 'mustBeGreaterOrEqualToZero').required(), - }), - [LOW_VOLTAGE_LIMIT]: yup - .number() - .nullable() - .min(0, 'mustBeGreaterOrEqualToZero') - .max(yup.ref(HIGH_VOLTAGE_LIMIT), 'voltageLevelNominalVoltageMaxValueError'), - [HIGH_VOLTAGE_LIMIT]: yup.number().nullable().min(0, 'mustBeGreaterOrEqualToZero'), - [LOW_SHORT_CIRCUIT_CURRENT_LIMIT]: yup - .number() - .nullable() - .min(0, 'ShortCircuitCurrentLimitMustBeGreaterOrEqualToZero') - .max(yup.ref(HIGH_SHORT_CIRCUIT_CURRENT_LIMIT), 'ShortCircuitCurrentLimitMinMaxError'), - [HIGH_SHORT_CIRCUIT_CURRENT_LIMIT]: yup - .number() - .nullable() - .min(0, 'ShortCircuitCurrentLimitMustBeGreaterOrEqualToZero') - .when([LOW_SHORT_CIRCUIT_CURRENT_LIMIT], { - is: (lowShortCircuitCurrentLimit: number | null) => lowShortCircuitCurrentLimit != null, - then: (schema) => schema.required(), - }), - [BUS_BAR_COUNT]: yup - .number() - .nullable() - .when([IS_ATTACHMENT_POINT_CREATION], { - is: (isAttachmentPointCreation: boolean) => !isAttachmentPointCreation, - then: (schema) => schema.min(1, 'BusBarCountMustBeGreaterThanOrEqualToOne').required(), - }), - [SECTION_COUNT]: yup - .number() - .nullable() - .when([IS_ATTACHMENT_POINT_CREATION], { - is: (isAttachmentPointCreation: boolean) => !isAttachmentPointCreation, - then: (schema) => schema.min(1, 'SectionCountMustBeGreaterThanOrEqualToOne').required(), - }), - [SWITCHES_BETWEEN_SECTIONS]: yup - .string() - .nullable() - .when([SECTION_COUNT], { - is: (sectionCount: number) => sectionCount > 1, - then: (schema) => schema.required(), - }), - [SWITCH_KINDS]: yup.array().of( - yup.object().shape({ - [SWITCH_KIND]: yup.string().required(), - }) - ), - [IS_ATTACHMENT_POINT_CREATION]: yup.boolean().required(), - [TOPOLOGY_KIND]: yup.string().nullable(), - [COUPLING_OMNIBUS]: yup.array().of( - yup.object().shape({ - [BUS_BAR_SECTION_ID1]: yup.string().nullable().required(), - [BUS_BAR_SECTION_ID2]: yup - .string() - .nullable() - .required() - .notOneOf([yup.ref(BUS_BAR_SECTION_ID1), null], 'CreateCouplingDeviceIdenticalBusBar'), - }) - ), - }) - .concat(creationPropertiesSchema); - -type VoltageLevelFormInfos = yup.InferType; - const VoltageLevelCreationDialog: FC = ({ editData, currentNode, @@ -275,140 +86,103 @@ const VoltageLevelCreationDialog: FC = ({ ...dialogProps }) => { const currentNodeUuid = currentNode.id; + const intl = useIntl(); const { snackError, snackWarning } = useSnackMessage(); - const defaultValues = useMemo((): VoltageLevelCreationFormData => { + const defaultValues = useMemo(() => { if (isAttachmentPointModification) { - return { ...emptyFormData, [ADD_SUBSTATION_CREATION]: true, [IS_ATTACHMENT_POINT_CREATION]: true }; - } else { - return emptyFormData; + return { + ...voltageLevelCreationEmptyFormData, + [FieldConstants.ADD_SUBSTATION_CREATION]: true, + [FieldConstants.HIDE_NOMINAL_VOLTAGE]: true, + [FieldConstants.HIDE_BUS_BAR_SECTION]: true, + }; } + return voltageLevelCreationEmptyFormData; }, [isAttachmentPointModification]); - const formMethods = useForm>({ + const formMethods = useForm>({ defaultValues: defaultValues, - resolver: yupResolver>(formSchema), + resolver: yupResolver>(voltageLevelCreationFormSchema), }); - const { reset, setValue, getValues, trigger, subscribe } = formMethods; + const { reset, getValues, trigger, subscribe } = formMethods; - const intl = useIntl(); - const fromExternalDataToFormValues = useCallback( - (voltageLevel: Record, fromCopy = true) => { - const isSubstationCreation = - (!fromCopy && voltageLevel.substationCreation?.equipmentId != null) || isAttachmentPointModification; - const shortCircuitLimits = { - [LOW_SHORT_CIRCUIT_CURRENT_LIMIT]: convertInputValue( - FieldType.LOW_SHORT_CIRCUIT_CURRENT_LIMIT, - fromCopy ? voltageLevel.identifiableShortCircuit?.ipMin : voltageLevel.ipMin - ), - [HIGH_SHORT_CIRCUIT_CURRENT_LIMIT]: convertInputValue( - FieldType.HIGH_SHORT_CIRCUIT_CURRENT_LIMIT, - fromCopy ? voltageLevel.identifiableShortCircuit?.ipMax : voltageLevel.ipMax - ), - }; - const switchKinds: SwitchKindFormData[] = - voltageLevel.switchKinds?.map((switchKind: string) => ({ - [SWITCH_KIND]: switchKind, - })) || []; - const switchesBetweenSections = - voltageLevel.switchKinds - ?.map((switchKind: string) => intl.formatMessage({ id: switchKind })) - .join(' / ') || ''; + const applyAttachmentPointOverrides = useCallback( + (formData: Record) => { + if (isAttachmentPointModification) { + formData[FieldConstants.HIDE_NOMINAL_VOLTAGE] = true; + formData[FieldConstants.HIDE_BUS_BAR_SECTION] = true; + if (!formData[FieldConstants.ADD_SUBSTATION_CREATION]) { + formData[FieldConstants.ADD_SUBSTATION_CREATION] = true; + } + } + }, + [isAttachmentPointModification] + ); - const equipmentId = (voltageLevel[EQUIPMENT_ID] ?? voltageLevel[ID]) + (fromCopy ? '(1)' : ''); - const equipmentName = voltageLevel[FieldConstants.EQUIPMENT_NAME] ?? voltageLevel[NAME]; - const substationId = isSubstationCreation ? null : (voltageLevel[SUBSTATION_ID] ?? null); + const fromSearchCopyToFormValues = useCallback( + (voltageLevel: VoltageLevelFormInfos) => { + const formData = voltageLevelInfosToForm(voltageLevel, intl); + formData[FieldConstants.EQUIPMENT_ID] += '(1)'; + applyAttachmentPointOverrides(formData); + reset(formData, { keepDefaultValues: true }); - const properties = fromCopy - ? copyEquipmentPropertiesForCreation(voltageLevel) - : getPropertiesFromModification(voltageLevel.properties); - reset( - { - [EQUIPMENT_ID]: equipmentId, - [FieldConstants.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], - ...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, - [IS_ATTACHMENT_POINT_CREATION]: isAttachmentPointModification, - ...properties, - }, - { keepDefaultValues: true } - ); - if (isSubstationCreation) { - const substationKeys = [ - [SUBSTATION_CREATION_ID, voltageLevel.substationCreation?.equipmentId], - [SUBSTATION_NAME, voltageLevel.substationCreation?.equipmentName], - [FieldConstants.COUNTRY, voltageLevel.substationCreation?.country], - ]; - substationKeys.forEach(([key, value]) => { - setValue(key, value); - }); - setValue( - `${SUBSTATION_CREATION}.${FieldConstants.ADDITIONAL_PROPERTIES}`, - voltageLevel.substationCreation?.properties - ); - setValue(ADD_SUBSTATION_CREATION, true); - } else { - setValue(ADD_SUBSTATION_CREATION, false); - } - if (!voltageLevel.isSymmetrical && fromCopy) { + if (!voltageLevel.isSymmetrical) { snackWarning({ messageId: 'BusBarSectionsCopyingNotSupported', }); } }, - [isAttachmentPointModification, reset, intl, setValue, snackWarning] + [applyAttachmentPointOverrides, intl, reset, snackWarning] + ); + + const fromEditDataToFormValues = useCallback( + (editDto: VoltageLevelCreationDto) => { + const formData = voltageLevelCreationDtoToForm(editDto, intl, true); + applyAttachmentPointOverrides(formData); + reset(formData, { keepDefaultValues: true }); + }, + [applyAttachmentPointOverrides, intl, reset] ); // Supervisor watches to trigger validation for interdependent constraints useEffect(() => { - // Watch HIGH_VOLTAGE_LIMIT changed const unsubscribeHighVoltageLimit = subscribe({ - name: [`${HIGH_VOLTAGE_LIMIT}`], + name: [FieldConstants.HIGH_VOLTAGE_LIMIT], formState: { values: true, }, callback: ({ isSubmitted }: { isSubmitted?: boolean }) => { if (isSubmitted) { - trigger(`${LOW_VOLTAGE_LIMIT}`).then(); + trigger(FieldConstants.LOW_VOLTAGE_LIMIT).then(); } }, }); - // Watch EQUIPMENT_ID changed const unsubscribeEquipmentId = subscribe({ - name: [EQUIPMENT_ID], + name: [FieldConstants.EQUIPMENT_ID], formState: { values: true, }, callback: () => { - if (getValues(SUBSTATION_ID)) { - trigger(SUBSTATION_ID); + if (getValues(FieldConstants.SUBSTATION_ID)) { + trigger(FieldConstants.SUBSTATION_ID); } - if (getValues(SUBSTATION_CREATION_ID)) { - trigger(SUBSTATION_CREATION_ID); + if (getValues(FieldConstants.SUBSTATION_CREATION_ID)) { + trigger(FieldConstants.SUBSTATION_CREATION_ID); } }, }); - // Watch SUBSTATION_ID or SUBSTATION_CREATION_ID changed const unsubscribeSubstationIds = subscribe({ - name: [SUBSTATION_ID, SUBSTATION_CREATION_ID], + name: [FieldConstants.SUBSTATION_ID, FieldConstants.SUBSTATION_CREATION_ID], formState: { values: true, }, callback: () => { - if (getValues(EQUIPMENT_ID)) { - trigger(EQUIPMENT_ID); + if (getValues(FieldConstants.EQUIPMENT_ID)) { + trigger(FieldConstants.EQUIPMENT_ID); } }, }); @@ -420,62 +194,46 @@ const VoltageLevelCreationDialog: FC = ({ }; }, [subscribe, trigger, getValues]); - const searchCopy = useFormSearchCopy(fromExternalDataToFormValues, EQUIPMENT_TYPES.VOLTAGE_LEVEL); + const searchCopy = useFormSearchCopy(fromSearchCopyToFormValues, EQUIPMENT_TYPES.VOLTAGE_LEVEL); useEffect(() => { if (editData) { - fromExternalDataToFormValues(editData, false); + fromEditDataToFormValues(editData); } - }, [fromExternalDataToFormValues, editData]); + }, [fromEditDataToFormValues, editData]); const onSubmit = useCallback( (voltageLevel: VoltageLevelCreationFormData) => { - const substationCreation: AttachedSubstationCreationInfo | null = getValues(ADD_SUBSTATION_CREATION) - ? { - type: MODIFICATION_TYPES.SUBSTATION_CREATION.type, - equipmentId: voltageLevel[SUBSTATION_CREATION_ID], - equipmentName: voltageLevel[SUBSTATION_NAME], - country: voltageLevel[FieldConstants.COUNTRY], - properties: toModificationProperties(voltageLevel[SUBSTATION_CREATION]), - } - : null; + const dto = voltageLevelCreationFormToDto(voltageLevel); onCreateVoltageLevel({ studyUuid: studyUuid as UUID, nodeUuid: currentNodeUuid, - equipmentId: voltageLevel[EQUIPMENT_ID], - equipmentName: sanitizeString(voltageLevel[FieldConstants.EQUIPMENT_NAME]) ?? undefined, - substationId: substationCreation === null ? voltageLevel[SUBSTATION_ID] : null, - substationCreation: substationCreation, - nominalV: voltageLevel[NOMINAL_V], - lowVoltageLimit: voltageLevel[LOW_VOLTAGE_LIMIT], - highVoltageLimit: voltageLevel[HIGH_VOLTAGE_LIMIT], - ipMin: convertOutputValue( - FieldType.LOW_SHORT_CIRCUIT_CURRENT_LIMIT, - voltageLevel[LOW_SHORT_CIRCUIT_CURRENT_LIMIT] - ), - ipMax: convertOutputValue( - FieldType.HIGH_SHORT_CIRCUIT_CURRENT_LIMIT, - voltageLevel[HIGH_SHORT_CIRCUIT_CURRENT_LIMIT] - ), - busbarCount: voltageLevel[BUS_BAR_COUNT], - sectionCount: voltageLevel[SECTION_COUNT], - switchKinds: voltageLevel[SWITCH_KINDS].map((e) => { - return e.switchKind as SwitchKind; - }), - couplingDevices: voltageLevel[COUPLING_OMNIBUS], + equipmentId: dto.equipmentId, + equipmentName: dto.equipmentName ?? undefined, + substationId: dto.substationId, + substationCreation: dto.substationCreation as AttachedSubstationCreationInfo | null, + nominalV: dto.nominalV, + lowVoltageLimit: dto.lowVoltageLimit, + highVoltageLimit: dto.highVoltageLimit, + ipMin: dto.ipMin, + ipMax: dto.ipMax, + busbarCount: dto.busbarCount, + sectionCount: dto.sectionCount, + switchKinds: dto.switchKinds as SwitchKind[], + couplingDevices: dto.couplingDevices as CouplingDeviceInfos[], isUpdate: !!editData, modificationUuid: editData?.uuid, - properties: toModificationProperties(voltageLevel), + properties: dto.properties, }).catch((error: Error) => { snackWithFallback(snackError, error, { headerId: 'VoltageLevelCreationError' }); }); }, - [getValues, onCreateVoltageLevel, studyUuid, currentNodeUuid, editData, snackError] + [onCreateVoltageLevel, studyUuid, currentNodeUuid, editData, snackError] ); const clear = useCallback(() => { - reset(emptyFormData); - }, [reset]); + reset(defaultValues); + }, [reset, defaultValues]); const open = useOpenShortWaitFetching({ isDataFetched: @@ -484,7 +242,7 @@ const VoltageLevelCreationDialog: FC = ({ }); return ( - + = ({ isDataFetching={isUpdate && editDataFetchStatus === FetchStatus.RUNNING} {...dialogProps} > - { +}: StudyVoltageLevelCreationFormProps) => { const intl = useIntl(); const { setValue, getValues } = useFormContext(); const [substations, setSubstations] = useState([]); - const watchBusBarCount = useWatch({ name: BUS_BAR_COUNT }); - const watchSectionCount = useWatch({ name: SECTION_COUNT }); - const watchAddSubstationCreation = useWatch({ name: ADD_SUBSTATION_CREATION }); - const watchIsAttachmentPointCreation = useWatch({ name: IS_ATTACHMENT_POINT_CREATION }); - - useEffect(() => { - // in new substation mode, set the default country - if (watchAddSubstationCreation && !getValues(FieldConstants.COUNTRY)) { - fetchDefaultCountry().then((country) => { - if (country) { - setValue(FieldConstants.COUNTRY, country); - } - }); - } - }, [setValue, getValues, watchAddSubstationCreation]); + const watchHideNominalVoltage = useWatch({ name: FieldConstants.HIDE_NOMINAL_VOLTAGE }); + const watchHideBusBarSection = useWatch({ name: FieldConstants.HIDE_BUS_BAR_SECTION }); + const showDeleteSubstationButton = !(watchHideNominalVoltage && watchHideBusBarSection); useEffect(() => { if (studyUuid && currentNodeUuid && currentRootNetworkUuid) { @@ -94,9 +53,10 @@ const VoltageLevelCreationForm = ({ } }, [studyUuid, currentNodeUuid, currentRootNetworkUuid]); - const voltageLevelIdField = ( - - ); + const handleAddButton = useCallback(() => { + setValue(FieldConstants.SUBSTATION_CREATION_ID, getValues(FieldConstants.SUBSTATION_ID)); + setValue(FieldConstants.ADD_SUBSTATION_CREATION, true); + }, [setValue, getValues]); function getCustomPaper(children: React.ReactNode) { return ( @@ -109,165 +69,23 @@ const VoltageLevelCreationForm = ({ sx={{ justifyContent: 'flex-start', fontSize: 'medium', marginLeft: '2%', width: '100%' }} onMouseDown={handleAddButton} > - {`${intl.formatMessage({ id: 'CreateSubstation' })} : ${getValues(SUBSTATION_ID)}`} + {`${intl.formatMessage({ id: 'CreateSubstation' })} : ${getValues(FieldConstants.SUBSTATION_ID)}`} ); } - const handleAddButton = useCallback(() => { - setValue(SUBSTATION_CREATION_ID, getValues(SUBSTATION_ID)); - setValue(ADD_SUBSTATION_CREATION, true); - }, [setValue, getValues]); - const voltageLevelNameField = ( - - ); - - const substationField = ( - getCustomPaper(children)} - noOptionsText={''} - allowNewValue - /> - ); - - const nominalVoltageField = ; - - const lowVoltageLimitField = ( - - ); - - const highVoltageLimitField = ( - - ); - - const lowShortCircuitCurrentLimitField = ( - - ); - - const highShortCircuitCurrentLimitField = ( - - ); - - const busBarCountField = ; - - const sectionCountField = ; - - const displayOmnibus = watchBusBarCount > 1 || watchSectionCount > 1; - - const couplingOmnibusForm = ; - - const substationCreationIdField = ; - const substationCreationNameField = ; - - const substationCreationCountryField = ( - - ); - - const handleDeleteButton = useCallback(() => { - setValue(ADD_SUBSTATION_CREATION, false); - // clear the fields of the new substation - setValue(SUBSTATION_CREATION_ID, null); - setValue(SUBSTATION_NAME, null); - setValue(FieldConstants.COUNTRY, null); - }, [setValue]); - return ( - <> - - {voltageLevelIdField} - {voltageLevelNameField} - - - {watchAddSubstationCreation ? ( - - - - - - {substationCreationIdField} - - - {substationCreationNameField} - - - {substationCreationCountryField} - - {!watchIsAttachmentPointCreation && ( - - - - - - - - )} - - - - - - - ) : ( - - - {substationField} - - - )} - - - {!watchIsAttachmentPointCreation && {nominalVoltageField}} - {lowVoltageLimitField} - {highVoltageLimitField} - - - - {lowShortCircuitCurrentLimitField} - {highShortCircuitCurrentLimitField} - - - {!watchIsAttachmentPointCreation && ( - <> - - - {busBarCountField} - {sectionCountField} - - - {displayOmnibus && ( - <> - - - {couplingOmnibusForm} - - - )} - - )} - - + getCustomPaper(children), + noOptionsText: '', + }} + showDeleteSubstationButton={showDeleteSubstationButton} + /> ); }; -export default VoltageLevelCreationForm; +export default StudyVoltageLevelCreationForm; diff --git a/src/components/dialogs/network-modifications/voltage-level/switches-between-sections/create-switches-between-sections/create-switches-dialog-submit-button.tsx b/src/components/dialogs/network-modifications/voltage-level/switches-between-sections/create-switches-between-sections/create-switches-dialog-submit-button.tsx deleted file mode 100644 index 9e06b3b45e..0000000000 --- a/src/components/dialogs/network-modifications/voltage-level/switches-between-sections/create-switches-between-sections/create-switches-dialog-submit-button.tsx +++ /dev/null @@ -1,27 +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 { Button } from '@mui/material'; -import { FieldValues, SubmitHandler, useFormContext } from 'react-hook-form'; -import { FormattedMessage } from 'react-intl'; -import { CreateSwitchesFormData } from '../switches-between-sections'; - -interface CreateSwitchesDialogSubmitButtonProps { - handleSave: (data: CreateSwitchesFormData) => void | Promise; -} - -const CreateSwitchesDialogSubmitButton = ({ handleSave }: CreateSwitchesDialogSubmitButtonProps) => { - const { handleSubmit } = useFormContext(); - - return ( - - ); -}; - -export default CreateSwitchesDialogSubmitButton; diff --git a/src/components/dialogs/network-modifications/voltage-level/switches-between-sections/create-switches-between-sections/create-switches-dialog-utils.ts b/src/components/dialogs/network-modifications/voltage-level/switches-between-sections/create-switches-between-sections/create-switches-dialog-utils.ts deleted file mode 100644 index 90e2dc43ae..0000000000 --- a/src/components/dialogs/network-modifications/voltage-level/switches-between-sections/create-switches-between-sections/create-switches-dialog-utils.ts +++ /dev/null @@ -1,28 +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 { SWITCH_KINDS, SWITCH_KIND } from 'components/utils/field-constants'; -import yup from 'components/utils/yup-config'; - -export const getCreateSwitchesValidationSchema = (id = SWITCH_KINDS) => { - return { - [id]: yup.array().nullable().of(getSwitchTypeSchema()), - }; -}; - -const createSwitchesEmptyFormData = () => ({ - [SWITCH_KIND]: '', -}); - -export const getSwitchTypeSchema = () => - yup.object().shape({ - [SWITCH_KIND]: yup.string().nullable().required(), - }); - -export const getCreateSwitchesEmptyFormData = (sectionCount: number, id = SWITCH_KINDS) => ({ - [id]: new Array(sectionCount - 1).fill(createSwitchesEmptyFormData()), -}); diff --git a/src/components/dialogs/network-modifications/voltage-level/switches-between-sections/create-switches-between-sections/create-switches-dialog.tsx b/src/components/dialogs/network-modifications/voltage-level/switches-between-sections/create-switches-between-sections/create-switches-dialog.tsx deleted file mode 100644 index bb23a892af..0000000000 --- a/src/components/dialogs/network-modifications/voltage-level/switches-between-sections/create-switches-between-sections/create-switches-dialog.tsx +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Copyright (c) 2022, 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 { Dialog, DialogActions } from '@mui/material'; -import { useForm } from 'react-hook-form'; -import { yupResolver } from '@hookform/resolvers/yup'; -import CreateSwitchesDialogSubmitButton from './create-switches-dialog-submit-button'; -import CreateSwitchesForm from './create-switches-form'; -import { getCreateSwitchesEmptyFormData, getCreateSwitchesValidationSchema } from './create-switches-dialog-utils'; -import { SWITCH_KINDS } from 'components/utils/field-constants'; -import yup from 'components/utils/yup-config'; -import React, { useEffect } from 'react'; -import { CancelButton, CustomFormProvider } from '@gridsuite/commons-ui'; -import { CreateSwitchesFormData, SwitchKindData } from '../switches-between-sections'; - -const formSchema = yup.object().shape({ - ...getCreateSwitchesValidationSchema(), -}) as yup.ObjectSchema; - -interface CreateSwitchesDialogProps { - sectionCount: number; - handleCreateSwitchesDialog: (data: CreateSwitchesFormData) => void; - setOpenCreateSwitchesDialog: React.Dispatch>; - openCreateSwitchesDialog: boolean; - switchKinds: SwitchKindData[]; -} - -export const CreateSwitchesDialog = ({ - sectionCount, - handleCreateSwitchesDialog, - setOpenCreateSwitchesDialog, - openCreateSwitchesDialog, - switchKinds, -}: CreateSwitchesDialogProps) => { - const emptyFormData = getCreateSwitchesEmptyFormData(sectionCount); - const formMethods = useForm({ - defaultValues: emptyFormData, - resolver: yupResolver(formSchema), - }); - - const { reset } = formMethods; - - useEffect(() => { - if (switchKinds?.length > 0) { - reset({ - [SWITCH_KINDS]: switchKinds, - }); - } - }, [switchKinds, reset]); - - const handleCloseDialog = () => { - reset(emptyFormData); - setOpenCreateSwitchesDialog(false); - }; - - const handleSave = (data: CreateSwitchesFormData) => { - handleCreateSwitchesDialog(data); - handleCloseDialog(); - }; - - return ( - - - - - - - - - - ); -}; diff --git a/src/components/dialogs/network-modifications/voltage-level/switches-between-sections/create-switches-between-sections/create-switches-form.tsx b/src/components/dialogs/network-modifications/voltage-level/switches-between-sections/create-switches-between-sections/create-switches-form.tsx deleted file mode 100644 index d8823335e5..0000000000 --- a/src/components/dialogs/network-modifications/voltage-level/switches-between-sections/create-switches-between-sections/create-switches-form.tsx +++ /dev/null @@ -1,57 +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 { DialogContent, DialogTitle, Grid } from '@mui/material'; -import { SWITCH_TYPE } from 'components/network/constants'; -import EnumInput from 'components/utils/rhf-inputs/enum-input'; -import { SWITCH_KIND } from 'components/utils/field-constants'; -import { useFieldArray } from 'react-hook-form'; -import { FormattedMessage } from 'react-intl'; - -interface CreateSwitchesFormProps { - id: string; -} - -const CreateSwitchesForm = ({ id }: CreateSwitchesFormProps) => { - const { fields: rows } = useFieldArray({ name: `${id}` }); - return ( - <> - - - - - - {rows.map((value, index) => { - return ( - - - - ); - })} - - - - ); -}; - -export default CreateSwitchesForm; diff --git a/src/components/dialogs/network-modifications/voltage-level/switches-between-sections/switches-between-sections.tsx b/src/components/dialogs/network-modifications/voltage-level/switches-between-sections/switches-between-sections.tsx deleted file mode 100644 index a72ff2514b..0000000000 --- a/src/components/dialogs/network-modifications/voltage-level/switches-between-sections/switches-between-sections.tsx +++ /dev/null @@ -1,121 +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 { IconButton } from '@mui/material'; -import { TextInput } from '@gridsuite/commons-ui'; -import { SECTION_COUNT, SWITCHES_BETWEEN_SECTIONS, SWITCH_KINDS, SWITCH_KIND } from 'components/utils/field-constants'; -import { ReactElement, useCallback, useEffect, useRef, useState } from 'react'; -import { useFormContext, useWatch } from 'react-hook-form'; -import { useIntl } from 'react-intl'; -import { CreateSwitchesDialog } from './create-switches-between-sections/create-switches-dialog'; -import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'; -import GridItem from '../../../commons/grid-item'; - -export interface SwitchKindData { - [SWITCH_KIND]: string; -} - -export interface CreateSwitchesFormData { - [SWITCH_KINDS]: SwitchKindData[]; -} - -export const SwitchesBetweenSections = (): ReactElement => { - const { getValues, setValue } = useFormContext(); - const [openCreateSwitchesDialog, setOpenCreateSwitchesDialog] = useState(false); - - const watchSectionCount: number = useWatch({ name: SECTION_COUNT }); - const watchSwitchesBetweenSections: string = useWatch({ - name: SWITCHES_BETWEEN_SECTIONS, - }); - - const addIconAdornment = useCallback((clickCallback: () => void): ReactElement => { - return ( - - - - ); - }, []); - - const handleClickOpenSwitchesPane = useCallback(() => { - if (watchSectionCount > 1) { - setOpenCreateSwitchesDialog(true); - } - }, [watchSectionCount]); - - const intl = useIntl(); - const setSwitchesKinds = useCallback( - (data: CreateSwitchesFormData) => { - const map = data[SWITCH_KINDS].map((switchData) => { - return intl.formatMessage({ id: switchData[SWITCH_KIND] }); - }); - setValue(SWITCHES_BETWEEN_SECTIONS, map.join(' / '), { - shouldValidate: true, - shouldDirty: true, - }); - setValue(SWITCH_KINDS, data[SWITCH_KINDS]); - }, - [intl, setValue] - ); - - const handleCreateSwitchesDialog = useCallback( - (data: CreateSwitchesFormData) => { - setSwitchesKinds(data); - }, - [setSwitchesKinds] - ); - - const sectionCountRef = useRef(watchSectionCount); - const switchesBetweenSectionsRef = useRef(watchSwitchesBetweenSections); - - useEffect(() => { - // If the user changes the section count, we reset the switches between sections - if ( - sectionCountRef.current !== watchSectionCount && - switchesBetweenSectionsRef.current === watchSwitchesBetweenSections - ) { - const initialKindDisconnector: SwitchKindData = { switchKind: 'DISCONNECTOR' }; - let list = []; - if (watchSectionCount >= 1) { - list = new Array(watchSectionCount - 1).fill(initialKindDisconnector); - } - const data: CreateSwitchesFormData = { switchKinds: list }; - setSwitchesKinds(data); - } - sectionCountRef.current = watchSectionCount; - switchesBetweenSectionsRef.current = watchSwitchesBetweenSections; - }, [watchSectionCount, watchSwitchesBetweenSections, setSwitchesKinds]); - - const switchesBetweenSectionsField = ( - - ); - - if (Number.isNaN(watchSectionCount) || watchSectionCount <= 1) { - return <>; - } else { - return ( - <> - {switchesBetweenSectionsField} - {openCreateSwitchesDialog && ( - - )} - - ); - } -}; diff --git a/src/components/dialogs/network-modifications/voltage-level/topology-creation/create-voltage-level-topology-form.tsx b/src/components/dialogs/network-modifications/voltage-level/topology-creation/create-voltage-level-topology-form.tsx index b023e018a7..7ec6f714a2 100644 --- a/src/components/dialogs/network-modifications/voltage-level/topology-creation/create-voltage-level-topology-form.tsx +++ b/src/components/dialogs/network-modifications/voltage-level/topology-creation/create-voltage-level-topology-form.tsx @@ -17,7 +17,7 @@ import { FormattedMessage, useIntl } from 'react-intl'; import type { UUID } from 'node:crypto'; import { isNodeBuilt } from '../../../../graph/util/model-functions'; import { CurrentTreeNode } from '../../../../graph/tree-node.type'; -import { SwitchesBetweenSections } from '../switches-between-sections/switches-between-sections'; +import { SwitchesBetweenSections } from '@gridsuite/commons-ui'; export interface CreateVoltageLevelTopologyFormProps { voltageLevelId: string; diff --git a/src/components/dialogs/network-modifications/voltage-level/voltage-level-creation-utils.js b/src/components/dialogs/network-modifications/voltage-level/voltage-level-creation-utils.js deleted file mode 100644 index 727710e2d3..0000000000 --- a/src/components/dialogs/network-modifications/voltage-level/voltage-level-creation-utils.js +++ /dev/null @@ -1,46 +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 { COUPLING_OMNIBUS, BUS_BAR_SECTION_ID1, BUS_BAR_SECTION_ID2 } from 'components/utils/field-constants'; -import yup from 'components/utils/yup-config'; - -const buildValidationError = (errors, field) => { - return errors.length === 0 - ? true - : { - name: 'ValidationError', - path: `${field}`, - errors: [], - inner: errors, - }; -}; - -/* - * Get BusBarSection indexes linked to itself - */ -const findBusBarSectionIndexesItSelf = (values) => { - const indexes = []; - values?.forEach((value, index) => { - if (value[BUS_BAR_SECTION_ID1] === value[BUS_BAR_SECTION_ID2]) { - indexes.push(index); - } - }); - return indexes; -}; - -export const controlCouplingOmnibusBetweenSections = (values, message) => { - const errors = []; - const indexes = findBusBarSectionIndexesItSelf(values); - if (indexes?.length > 0) { - indexes.forEach((index) => { - errors.push(new yup.ValidationError(message, null, `${COUPLING_OMNIBUS}[${index}].${BUS_BAR_SECTION_ID1}`)); - errors.push(new yup.ValidationError(message, null, `${COUPLING_OMNIBUS}[${index}].${BUS_BAR_SECTION_ID2}`)); - }); - } - - return buildValidationError(errors, COUPLING_OMNIBUS); -};