From 0622fa4d62a2e0cd2d515e4710e5e2f889b9cffc Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Wed, 28 Jan 2026 14:25:00 +0100 Subject: [PATCH 1/3] add in calculation cluster parameters dor shortcircuit Signed-off-by: Etienne LESOT --- .../elementSearchInput/ElementSearchInput.tsx | 9 +- src/components/inputs/SelectClearable.tsx | 6 +- .../agGridTable/CustomAgGridTable.tsx | 2 +- .../autocompleteInputs/AutocompleteInput.tsx | 11 +- .../selectInputs/SelectInput.tsx | 9 +- .../AutocompleteWithFavorites.tsx | 9 +- .../parameters/short-circuit/constants.ts | 8 + .../short-circuit/short-circuit-fields.tsx | 72 +------ .../short-circuit-parameters-content.tsx | 59 ++++++ .../short-circuit-parameters-form.tsx | 57 ++++-- .../short-circuit-parameters-utils.ts | 46 ++++- .../short-circuit-specific-fields.tsx | 186 ++++++++++++++++++ .../use-short-circuit-parameters-form.ts | 17 +- src/translations/en/parameters.ts | 4 + src/translations/fr/parameters.ts | 4 + 15 files changed, 387 insertions(+), 112 deletions(-) create mode 100644 src/components/parameters/short-circuit/short-circuit-parameters-content.tsx create mode 100644 src/components/parameters/short-circuit/short-circuit-specific-fields.tsx diff --git a/src/components/elementSearch/elementSearchInput/ElementSearchInput.tsx b/src/components/elementSearch/elementSearchInput/ElementSearchInput.tsx index c3880675c..5760d5dae 100644 --- a/src/components/elementSearch/elementSearchInput/ElementSearchInput.tsx +++ b/src/components/elementSearch/elementSearchInput/ElementSearchInput.tsx @@ -13,11 +13,10 @@ export type RenderElementProps = HTMLAttributes & { inputValue: string; }; -export interface ElementSearchInputProps - extends Pick< - AutocompleteProps, - 'sx' | 'size' | 'loadingText' | 'loading' | 'disableClearable' | 'getOptionDisabled' | 'PaperComponent' - > { +export interface ElementSearchInputProps extends Pick< + AutocompleteProps, + 'sx' | 'size' | 'loadingText' | 'loading' | 'disableClearable' | 'getOptionDisabled' | 'PaperComponent' +> { searchTerm: string; onSearchTermChange: (searchTerm: string) => void; onSelectionChange: (selection: T) => void; diff --git a/src/components/inputs/SelectClearable.tsx b/src/components/inputs/SelectClearable.tsx index e55308859..7a7128223 100644 --- a/src/components/inputs/SelectClearable.tsx +++ b/src/components/inputs/SelectClearable.tsx @@ -11,8 +11,10 @@ import { FieldLabel } from './reactHookForm/utils/FieldLabel'; type SelectOption = { id: string; label?: string }; -export interface SelectClearableProps - extends Omit, 'value' | 'onChange' | 'renderInput'> { +export interface SelectClearableProps extends Omit< + AutocompleteProps, + 'value' | 'onChange' | 'renderInput' +> { value: string | null; onChange: (value: string | null) => void; label?: string; diff --git a/src/components/inputs/reactHookForm/agGridTable/CustomAgGridTable.tsx b/src/components/inputs/reactHookForm/agGridTable/CustomAgGridTable.tsx index 8c0da0071..f7b03a2e9 100644 --- a/src/components/inputs/reactHookForm/agGridTable/CustomAgGridTable.tsx +++ b/src/components/inputs/reactHookForm/agGridTable/CustomAgGridTable.tsx @@ -119,7 +119,7 @@ export function CustomAgGridTable({ const isLastSelected = Boolean( rowData?.length && - gridApi?.api.getRowNode(rowData[rowData.length - 1][FieldConstants.AG_GRID_ROW_UUID])?.isSelected() + gridApi?.api.getRowNode(rowData[rowData.length - 1][FieldConstants.AG_GRID_ROW_UUID])?.isSelected() ); const noRowSelected = selectedRows.length === 0; diff --git a/src/components/inputs/reactHookForm/autocompleteInputs/AutocompleteInput.tsx b/src/components/inputs/reactHookForm/autocompleteInputs/AutocompleteInput.tsx index b31003640..9f03fa77d 100644 --- a/src/components/inputs/reactHookForm/autocompleteInputs/AutocompleteInput.tsx +++ b/src/components/inputs/reactHookForm/autocompleteInputs/AutocompleteInput.tsx @@ -12,12 +12,11 @@ import { genHelperError, identity, isFieldRequired, FieldLabel, HelperPreviousVa import { useCustomFormContext } from '../provider'; import { Option } from '../../../../utils'; -export interface AutocompleteInputProps - extends Omit< - AutocompleteProps, - // we already defined them in our custom Autocomplete - 'value' | 'onChange' | 'renderInput' - > { +export interface AutocompleteInputProps extends Omit< + AutocompleteProps, + // we already defined them in our custom Autocomplete + 'value' | 'onChange' | 'renderInput' +> { name: string; options: Option[]; label?: string; diff --git a/src/components/inputs/reactHookForm/selectInputs/SelectInput.tsx b/src/components/inputs/reactHookForm/selectInputs/SelectInput.tsx index 2385caa01..6250f48e8 100644 --- a/src/components/inputs/reactHookForm/selectInputs/SelectInput.tsx +++ b/src/components/inputs/reactHookForm/selectInputs/SelectInput.tsx @@ -9,11 +9,10 @@ import { useIntl } from 'react-intl'; import { AutocompleteInput, AutocompleteInputProps } from '../autocompleteInputs'; import { Option } from '../../../../utils'; -export interface SelectInputProps - extends Omit< - AutocompleteInputProps, - 'outputTransform' | 'inputTransform' | 'readOnly' | 'getOptionLabel' // already defined in SelectInput - > { +export interface SelectInputProps extends Omit< + AutocompleteInputProps, + 'outputTransform' | 'inputTransform' | 'readOnly' | 'getOptionLabel' // already defined in SelectInput +> { options: Option[]; onCheckNewValue?: (value: Option | null) => boolean; // if return false, do not apply the new value } diff --git a/src/components/inputs/reactQueryBuilder/AutocompleteWithFavorites.tsx b/src/components/inputs/reactQueryBuilder/AutocompleteWithFavorites.tsx index 199a2e8e2..9a2f0fb10 100644 --- a/src/components/inputs/reactQueryBuilder/AutocompleteWithFavorites.tsx +++ b/src/components/inputs/reactQueryBuilder/AutocompleteWithFavorites.tsx @@ -16,11 +16,10 @@ const styles = { }), } as const satisfies MuiStyles; -interface AutocompleteWithFavoritesProps - extends Omit< - AutocompleteProps, - 'multiple' | 'renderInput' | 'renderGroup' | 'groupBy' - > { +interface AutocompleteWithFavoritesProps extends Omit< + AutocompleteProps, + 'multiple' | 'renderInput' | 'renderGroup' | 'groupBy' +> { favorites: Value[]; valid: boolean; } diff --git a/src/components/parameters/short-circuit/constants.ts b/src/components/parameters/short-circuit/constants.ts index acf455af6..1e7fee2ce 100644 --- a/src/components/parameters/short-circuit/constants.ts +++ b/src/components/parameters/short-circuit/constants.ts @@ -29,6 +29,9 @@ export const SHORT_CIRCUIT_VOLTAGE_RANGES = 'voltageRanges'; // specific parameters export const SHORT_CIRCUIT_ONLY_STARTED_GENERATORS_IN_CALCULATION_CLUSTER = 'onlyStartedGeneratorsInCalculationCluster'; +export const SHORT_CIRCUIT_ONLY_STARTED_GENERATORS_OUTSIDE_CALCULATION_CLUSTER = + 'onlyStartedGeneratorsOutsideCalculationCluster'; +export const SHORT_CIRCUIT_IN_CALCULATION_CLUSTER_FILTERS = 'inCalculationClusterFilters'; export const SHORT_CIRCUIT_MODEL_POWER_ELECTRONICS = 'modelPowerElectronics'; export const SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS = 'powerElectronicsMaterials'; @@ -70,3 +73,8 @@ export const onlyStartedGeneratorsOptions = { label: 'ShortCircuitStartedLabel', }, }; + +export enum ShortCircuitTabValues { + 'General' = 0, + 'StudyArea' = 1, +} diff --git a/src/components/parameters/short-circuit/short-circuit-fields.tsx b/src/components/parameters/short-circuit/short-circuit-fields.tsx index cb13a5ab4..f81e98586 100644 --- a/src/components/parameters/short-circuit/short-circuit-fields.tsx +++ b/src/components/parameters/short-circuit/short-circuit-fields.tsx @@ -9,18 +9,14 @@ import { useEffect, useMemo, useState } from 'react'; import { Grid } from '@mui/material'; import { green, red } from '@mui/material/colors'; import { Lens } from '@mui/icons-material'; -import { useFormContext, useWatch } from 'react-hook-form'; -import { FormattedMessage } from 'react-intl'; +import { useWatch } from 'react-hook-form'; import { InitialVoltage, intlInitialVoltageProfileMode, intlPredefinedParametersOptions, - onlyStartedGeneratorsOptions, PredefinedParameters, SHORT_CIRCUIT_INITIAL_VOLTAGE_PROFILE_MODE, SHORT_CIRCUIT_ONLY_STARTED_GENERATORS_IN_CALCULATION_CLUSTER, - SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS, - SHORT_CIRCUIT_MODEL_POWER_ELECTRONICS, SHORT_CIRCUIT_PREDEFINED_PARAMS, SHORT_CIRCUIT_WITH_FEEDER_RESULT, SHORT_CIRCUIT_WITH_LOADS, @@ -34,8 +30,6 @@ import GridSection from '../../grid/grid-section'; import { CheckboxInput, FieldLabel, MuiSelectInput, RadioInput, SwitchInput } from '../../inputs'; import type { SxStyle } from '../../../utils/styles'; import { COMMON_PARAMETERS, SPECIFIC_PARAMETERS } from '../common'; -import { ShortCircuitIccMaterialTable } from './short-circuit-icc-material-table'; -import { COLUMNS_DEFINITIONS_ICC_MATERIALS } from './short-circuit-icc-material-table-columns-definition'; export interface ShortCircuitFieldsProps { resetAll: (predefinedParams: PredefinedParameters) => void; @@ -47,13 +41,7 @@ export enum Status { ERROR = 'ERROR', } -const columnsDef = COLUMNS_DEFINITIONS_ICC_MATERIALS.map((col) => ({ - ...col, - label: , - tooltip: , -})); - -export function ShortCircuitFields({ resetAll, isDeveloperMode = true }: Readonly) { +export function ShortCircuitFields({ resetAll }: Readonly) { const [status, setStatus] = useState(Status.SUCCESS); const watchInitialVoltageProfileMode = useWatch({ name: `${COMMON_PARAMETERS}.${SHORT_CIRCUIT_INITIAL_VOLTAGE_PROFILE_MODE}`, @@ -73,14 +61,7 @@ export function ShortCircuitFields({ resetAll, isDeveloperMode = true }: Readonl const watchNeutralPosition = useWatch({ name: `${COMMON_PARAMETERS}.${SHORT_CIRCUIT_WITH_NEUTRAL_POSITION}`, }); - const watchSpecificParameters = useWatch({ - name: `${SPECIFIC_PARAMETERS}`, - }); - const isThereSpecificParameters = useMemo( - () => Object.keys(watchSpecificParameters).length > 0 && watchSpecificParameters.constructor === Object, - [watchSpecificParameters] - ); // Courcirc specific parameters const watchOnlyStartedGeneratorsInCalculationCluster = useWatch({ name: `${SPECIFIC_PARAMETERS}.${SHORT_CIRCUIT_ONLY_STARTED_GENERATORS_IN_CALCULATION_CLUSTER}`, @@ -139,8 +120,6 @@ export function ShortCircuitFields({ resetAll, isDeveloperMode = true }: Readonl resetAll(newPredefinedParameters); }; - const { setValue } = useFormContext(); - // fields definition const feederResult = ( @@ -187,32 +166,6 @@ export function ShortCircuitFields({ resetAll, isDeveloperMode = true }: Readonl /> ); - // Forced to specificly manage this onlyStartedGeneratorsInCalculationCluster parameter because it's a boolean type, but we want to use a radio button here. - const onlyStartedGeneratorsInCalculationCluster = ( - { - setValue( - `${SPECIFIC_PARAMETERS}.${SHORT_CIRCUIT_ONLY_STARTED_GENERATORS_IN_CALCULATION_CLUSTER}`, - value === 'true', - { - shouldDirty: true, - } - ); - }, - }} - /> - ); - - const modelPowerElectronics = ( - - ); - useEffect(() => { // To show the right status, we need to check the predefinedParams and initial voltage profile mode values. // Show success only if ICC_MAX_WITH_NOMINAL_VOLTAGE_MAP is associated with NOMINAL, or ICC_MAX_WITH_CEI909 with CEI909, or ICC_MIN_WITH_NOMINAL_VOLTAGE_MAP with NOMINAL @@ -270,27 +223,6 @@ export function ShortCircuitFields({ resetAll, isDeveloperMode = true }: Readonl {initialVoltageProfileModeField} - {isThereSpecificParameters && ( - <> - - - {onlyStartedGeneratorsInCalculationCluster} - - {isDeveloperMode && ( - <> - - - {modelPowerElectronics} - - - - )} - - )} ); } diff --git a/src/components/parameters/short-circuit/short-circuit-parameters-content.tsx b/src/components/parameters/short-circuit/short-circuit-parameters-content.tsx new file mode 100644 index 000000000..387036674 --- /dev/null +++ b/src/components/parameters/short-circuit/short-circuit-parameters-content.tsx @@ -0,0 +1,59 @@ +/** + * 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 { Box, Grid } from '@mui/material'; +import { ShortCircuitParametersTabValues } from './short-circuit-parameters-utils'; +import { parametersStyles } from '../parameters-style'; +import { TabPanel } from '../common/parameters'; +import type { MuiStyles } from '../../../utils/styles'; +import { PredefinedParameters } from './constants'; +import { ShortCircuitFields } from './short-circuit-fields'; +import { ShortCircuitSpecificFields } from './short-circuit-specific-fields'; + +type ShortCircuitParametersContentProps = { + isDeveloperMode: boolean; + resetAll: (predefinedParams: PredefinedParameters) => void; + selectedTab: ShortCircuitParametersTabValues; +}; + +const styles = { + container: { + ...parametersStyles.scrollableGrid, + maxHeight: '100%', + }, + maxWidth: { + width: '100%', + }, + wrapper: { + flexGrow: 1, + overflow: 'auto', + paddingLeft: 1, + }, +} as const satisfies MuiStyles; + +function ShortCircuitParametersContent({ + isDeveloperMode, + resetAll, + selectedTab, +}: Readonly) { + return ( + + + + + + + + + + + + + ); +} + +export default ShortCircuitParametersContent; diff --git a/src/components/parameters/short-circuit/short-circuit-parameters-form.tsx b/src/components/parameters/short-circuit/short-circuit-parameters-form.tsx index 387dd40be..e8985f73f 100644 --- a/src/components/parameters/short-circuit/short-circuit-parameters-form.tsx +++ b/src/components/parameters/short-circuit/short-circuit-parameters-form.tsx @@ -5,12 +5,24 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -import { Box, Grid, LinearProgress } from '@mui/material'; +import { Box, Grid, LinearProgress, Tab, Tabs } from '@mui/material'; import { ReactNode } from 'react'; +import { FormattedMessage } from 'react-intl'; import { CustomFormProvider } from '../../inputs'; -import { parametersStyles } from '../parameters-style'; -import { ShortCircuitFields } from './short-circuit-fields'; +import { getTabStyle, parametersStyles } from '../parameters-style'; import { UseShortCircuitParametersFormReturn } from './use-short-circuit-parameters-form'; +import { MuiStyles } from '../../../utils'; +import ShortCircuitParametersContent from './short-circuit-parameters-content'; +import { ShortCircuitParametersTabValues } from './short-circuit-parameters-utils'; + +const styles = { + shortCircuitParameters: { + height: '100%', + display: 'flex', + position: 'relative', + flexDirection: 'column', + }, +} as const satisfies MuiStyles; interface ShortCircuitParametersFormProps { shortCircuitMethods: UseShortCircuitParametersFormReturn; @@ -25,25 +37,38 @@ export function ShortCircuitParametersForm({ renderActions, isDeveloperMode, }: Readonly) { - const { formMethods, formSchema, paramsLoaded, resetAll } = shortCircuitMethods; - + const { formMethods, formSchema, paramsLoaded, resetAll, selectedTab, handleTabChange, tabIndexesWithError } = + shortCircuitMethods; return ( - + {renderTitleFields?.()} {paramsLoaded ? ( - - - + <> + + + } + value={ShortCircuitParametersTabValues.GENERAL} + sx={getTabStyle(tabIndexesWithError, ShortCircuitParametersTabValues.GENERAL)} + /> + } + value={ShortCircuitParametersTabValues.STUDY_AREA} + sx={getTabStyle(tabIndexesWithError, ShortCircuitParametersTabValues.STUDY_AREA)} + /> + + + + + + ) : ( )} diff --git a/src/components/parameters/short-circuit/short-circuit-parameters-utils.ts b/src/components/parameters/short-circuit/short-circuit-parameters-utils.ts index ca5d1bd5c..becfb6068 100644 --- a/src/components/parameters/short-circuit/short-circuit-parameters-utils.ts +++ b/src/components/parameters/short-circuit/short-circuit-parameters-utils.ts @@ -5,8 +5,10 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +import { UUID } from 'node:crypto'; import { InitialVoltage, + SHORT_CIRCUIT_IN_CALCULATION_CLUSTER_FILTERS, SHORT_CIRCUIT_INITIAL_VOLTAGE_PROFILE_MODE, SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS, SHORT_CIRCUIT_WITH_FEEDER_RESULT, @@ -17,7 +19,7 @@ import { } from './constants'; import yup from '../../../utils/yupConfig'; import { COMMON_PARAMETERS, SPECIFIC_PARAMETERS } from '../common'; -import { type SpecificParameterInfos, type SpecificParametersValues } from '../../../utils'; +import { EquipmentType, type SpecificParameterInfos, type SpecificParametersValues } from '../../../utils'; import type { PowerElectronicsMaterial } from './short-circuit-parameters.type'; import { @@ -27,6 +29,30 @@ import { getSpecificParametersFormSchema, } from '../common/utils'; +export enum ShortCircuitParametersTabValues { + GENERAL = 'General', + STUDY_AREA = 'StudyArea', +} + +export enum ShortCircuitParametersFieldConstants { + SUB_EQUIPMENT_TYPES_BY_FILTER = 'subEquipmentTypesByFilter', + FILTER_ID = 'filterId', + SUB_EQUIPMENT_TYPES = 'subEquipmentTypes', +} + +export interface FilterSubEquipments { + [ShortCircuitParametersFieldConstants.FILTER_ID]: string; + [ShortCircuitParametersFieldConstants.SUB_EQUIPMENT_TYPES]: string[]; +} + +export interface FilterElement { + id: UUID; + name: string; + specificMetadata: { + equipmentType: string; + }; +} + export const getCommonShortCircuitParametersFormSchema = () => { return yup.object().shape({ [COMMON_PARAMETERS]: yup.object().shape({ @@ -79,6 +105,17 @@ export const getSpecificShortCircuitParametersFormSchema = ( ...(powerElectronicsMaterialsSchema ? { [SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS]: powerElectronicsMaterialsSchema } : {}), + ...{ + [SHORT_CIRCUIT_IN_CALCULATION_CLUSTER_FILTERS]: yup.array().of( + yup.object().shape({ + [ShortCircuitParametersFieldConstants.FILTER_ID]: yup.string().required(), + [ShortCircuitParametersFieldConstants.SUB_EQUIPMENT_TYPES]: yup + .array() + .required() + .of(yup.string().required()), + }) + ), + }, }; const overrideSchema = yup.object().shape({ @@ -185,3 +222,10 @@ export const formatShortCircuitSpecificParameters = ( } return formatted; }; + +export function isSubstationOrVoltageLevelFilter(filter: FilterElement) { + return ( + filter.specificMetadata.equipmentType === EquipmentType.SUBSTATION || + filter.specificMetadata.equipmentType === EquipmentType.VOLTAGE_LEVEL + ); +} diff --git a/src/components/parameters/short-circuit/short-circuit-specific-fields.tsx b/src/components/parameters/short-circuit/short-circuit-specific-fields.tsx new file mode 100644 index 000000000..7dfc8913d --- /dev/null +++ b/src/components/parameters/short-circuit/short-circuit-specific-fields.tsx @@ -0,0 +1,186 @@ +import { Grid } from '@mui/material'; + +import { useCallback, useMemo } from 'react'; +import { useFormContext, useWatch } from 'react-hook-form'; +import { FormattedMessage } from 'react-intl'; +import { ShortCircuitIccMaterialTable } from './short-circuit-icc-material-table'; +import { SPECIFIC_PARAMETERS } from '../common'; +import { CheckboxInput, DirectoryItemsInput, OverflowableChipWithHelperText, RadioInput } from '../../inputs'; +import { COLUMNS_DEFINITIONS_ICC_MATERIALS } from './short-circuit-icc-material-table-columns-definition'; +import { ArrayAction, ElementType, EquipmentType } from '../../../utils'; +import GridSection from '../../grid/grid-section'; +import GridItem from '../../grid/grid-item'; +import { + onlyStartedGeneratorsOptions, + SHORT_CIRCUIT_IN_CALCULATION_CLUSTER_FILTERS, + SHORT_CIRCUIT_MODEL_POWER_ELECTRONICS, + SHORT_CIRCUIT_ONLY_STARTED_GENERATORS_IN_CALCULATION_CLUSTER, + SHORT_CIRCUIT_ONLY_STARTED_GENERATORS_OUTSIDE_CALCULATION_CLUSTER, + SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS, +} from './constants'; +import { + FilterElement, + FilterSubEquipments, + isSubstationOrVoltageLevelFilter, + ShortCircuitParametersFieldConstants, +} from './short-circuit-parameters-utils'; + +const equipmentTypes: string[] = [ + EquipmentType.SUBSTATION, + EquipmentType.VOLTAGE_LEVEL, + EquipmentType.LINE, + EquipmentType.TWO_WINDINGS_TRANSFORMER, + EquipmentType.THREE_WINDINGS_TRANSFORMER, + EquipmentType.GENERATOR, + EquipmentType.BATTERY, + EquipmentType.LOAD, + EquipmentType.SHUNT_COMPENSATOR, + EquipmentType.STATIC_VAR_COMPENSATOR, + EquipmentType.HVDC_LINE, + EquipmentType.DANGLING_LINE, +]; + +export interface ShortCircuitSpecificFieldsProps { + isDeveloperMode: boolean; +} + +const columnsDef = COLUMNS_DEFINITIONS_ICC_MATERIALS.map((col) => ({ + ...col, + label: , + tooltip: , +})); + +export function ShortCircuitSpecificFields({ isDeveloperMode = true }: Readonly) { + const { setValue, getValues } = useFormContext(); + + // Forced to specificly manage this onlyStartedGenerators parameter because it's a boolean type, but we want to use a radio button here. + const inClusterOnlyStartedGenerators = ( + { + setValue( + `${SPECIFIC_PARAMETERS}.${SHORT_CIRCUIT_ONLY_STARTED_GENERATORS_IN_CALCULATION_CLUSTER}`, + value === 'true', + { + shouldDirty: true, + } + ); + }, + }} + /> + ); + + const outClusterOnlyStartedGenerators = ( + { + setValue( + `${SPECIFIC_PARAMETERS}.${SHORT_CIRCUIT_ONLY_STARTED_GENERATORS_OUTSIDE_CALCULATION_CLUSTER}`, + value === 'true', + { + shouldDirty: true, + } + ); + }, + }} + /> + ); + + const modelPowerElectronics = ( + + ); + + const watchSpecificParameters = useWatch({ + name: `${SPECIFIC_PARAMETERS}`, + }); + + const isThereSpecificParameters = useMemo( + () => Object.keys(watchSpecificParameters).length > 0 && watchSpecificParameters.constructor === Object, + [watchSpecificParameters] + ); + + const handleFilterOnChange = useCallback( + (_currentFilters: any, action?: ArrayAction, filter?: FilterElement) => { + if (!action || !filter) { + console.error('Action or filter is missing in handleFilterOnChange'); + return; + } + if (isSubstationOrVoltageLevelFilter(filter)) { + const currentSubEquipmentsByFilters = getValues( + ShortCircuitParametersFieldConstants.SUB_EQUIPMENT_TYPES_BY_FILTER + ); + if (action === ArrayAction.ADD) { + const newFilterSubEquipments = { + [ShortCircuitParametersFieldConstants.FILTER_ID]: filter.id, + [ShortCircuitParametersFieldConstants.SUB_EQUIPMENT_TYPES]: [], + }; + setValue(ShortCircuitParametersFieldConstants.SUB_EQUIPMENT_TYPES_BY_FILTER, [ + ...currentSubEquipmentsByFilters, + newFilterSubEquipments, + ]); + } else if (action === ArrayAction.REMOVE) { + setValue( + ShortCircuitParametersFieldConstants.SUB_EQUIPMENT_TYPES_BY_FILTER, + currentSubEquipmentsByFilters.filter( + (value: FilterSubEquipments) => + value[ShortCircuitParametersFieldConstants.FILTER_ID] !== filter.id + ) + ); + } + } + }, + [setValue, getValues] + ); + + return ( + <> + {isThereSpecificParameters && ( + <> + + + + + + + + {inClusterOnlyStartedGenerators} + + + + {outClusterOnlyStartedGenerators} + + {isDeveloperMode && ( + <> + + + {modelPowerElectronics} + + + + )} + + )} + + ); +} diff --git a/src/components/parameters/short-circuit/use-short-circuit-parameters-form.ts b/src/components/parameters/short-circuit/use-short-circuit-parameters-form.ts index 45d0b767d..d4ea462c0 100644 --- a/src/components/parameters/short-circuit/use-short-circuit-parameters-form.ts +++ b/src/components/parameters/short-circuit/use-short-circuit-parameters-form.ts @@ -7,7 +7,7 @@ import { FieldErrors, useForm, UseFormReturn } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; -import { useCallback, useEffect, useMemo, useState } from 'react'; +import { useCallback, SyntheticEvent, useEffect, useMemo, useState } from 'react'; import { ObjectSchema } from 'yup'; import type { UUID } from 'node:crypto'; import yup from '../../../utils/yupConfig'; @@ -37,12 +37,16 @@ import { getDefaultShortCircuitSpecificParamsValues, getShortCircuitSpecificParametersValues, getSpecificShortCircuitParametersFormSchema, + ShortCircuitParametersTabValues, } from './short-circuit-parameters-utils'; import { snackWithFallback } from '../../../utils/error'; export interface UseShortCircuitParametersFormReturn { formMethods: UseFormReturn; formSchema: ObjectSchema; + selectedTab: ShortCircuitParametersTabValues; + handleTabChange: (event: SyntheticEvent, newValue: ShortCircuitParametersTabValues) => void; + tabIndexesWithError: ShortCircuitParametersTabValues[]; resetAll: (predefinedParameter: PredefinedParameters) => void; specificParametersDescriptionForProvider: SpecificParameterInfos[]; toShortCircuitFormValues: (_params: ShortCircuitParametersInfos) => any; @@ -70,9 +74,17 @@ export const useShortCircuitParametersForm = ({ description, }: UseShortCircuitParametersFormProps): UseShortCircuitParametersFormReturn => { const [, provider, , , , params, , updateParameters, , specificParamsDescriptions] = parametersBackend; + const [selectedTab, setSelectedTab] = useState( + ShortCircuitParametersTabValues.GENERAL + ); + const [tabIndexesWithError] = useState([]); const [paramsLoaded, setParamsLoaded] = useState(false); const { snackError } = useSnackMessage(); + const handleTabChange = useCallback((event: SyntheticEvent, newValue: ShortCircuitParametersTabValues) => { + setSelectedTab(newValue); + }, []); + const specificParametersDescriptionForProvider = useMemo(() => { return provider && specificParamsDescriptions?.[provider] ? specificParamsDescriptions[provider] : []; }, [provider, specificParamsDescriptions]); @@ -251,6 +263,9 @@ export const useShortCircuitParametersForm = ({ return { formMethods, formSchema, + selectedTab, + handleTabChange, + tabIndexesWithError, specificParametersDescriptionForProvider, toShortCircuitFormValues, formatNewParams, diff --git a/src/translations/en/parameters.ts b/src/translations/en/parameters.ts index 0a9b41654..c83e8bcb5 100644 --- a/src/translations/en/parameters.ts +++ b/src/translations/en/parameters.ts @@ -55,6 +55,7 @@ export const parametersEn = { General: 'General', LimitReductions: 'Limit reductions', + StudyArea: 'Study area', IST: 'PATL', LimitVoltageInterval: 'Between TATL{lowBound} and TATL{highBound}', LimitVoltageAfterIST: 'Between PATL and TATL{highBound}', @@ -119,6 +120,9 @@ export const parametersEn = { ShortCircuitCharacteristics: 'Features considered', ShortCircuitVoltageProfileMode: 'Initial voltage profile', ShortCircuitStartedGeneratorsMode: 'Generators started', + ShortCircuitInClusterFilter: 'In cluster filters', + ShortCircuitInCluster: 'In cluster', + ShortCircuitOutCluster: 'Out cluster', ShortCircuitPowerElectronicsSection: 'Modeling of power electronics connected equipment', ShortCircuitModelPowerElectronics: 'Consider following Icc characteristics', ShortCircuitIccMaterialActivate: 'Activate', diff --git a/src/translations/fr/parameters.ts b/src/translations/fr/parameters.ts index 5abde27e5..96156bea2 100644 --- a/src/translations/fr/parameters.ts +++ b/src/translations/fr/parameters.ts @@ -57,6 +57,7 @@ export const parametersFr = { General: 'Général', LimitReductions: 'Abattements', + StudyArea: "Zone d'étude", IST: 'IST', LimitVoltageInterval: 'Entre IT{lowBound} et IT{highBound}', LimitVoltageAfterIST: 'Entre IST et IT{highBound}', @@ -123,6 +124,9 @@ export const parametersFr = { ShortCircuitCharacteristics: 'Caractéristiques prises en compte', ShortCircuitVoltageProfileMode: 'Plan de tension initial', ShortCircuitStartedGeneratorsMode: 'Démarrage des groupes', + ShortCircuitInClusterFilter: 'Regroupements de la zone intérieure', + ShortCircuitInCluster: 'Zone intérieure', + ShortCircuitOutCluster: 'Zone extérieure', ShortCircuitPowerElectronicsSection: "Modélisation des équipements raccordés par de l'électronique de puissance", ShortCircuitModelPowerElectronics: "Prise en compte des caractéristiques d'Icc suivantes", ShortCircuitIccMaterialActivate: 'Actif', From 04162d763d76dd554251c17e1e1f304d4b129869 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Mon, 2 Feb 2026 16:14:44 +0100 Subject: [PATCH 2/3] fix position Signed-off-by: Etienne LESOT --- .../short-circuit-specific-fields.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/components/parameters/short-circuit/short-circuit-specific-fields.tsx b/src/components/parameters/short-circuit/short-circuit-specific-fields.tsx index 7dfc8913d..41fadc9a1 100644 --- a/src/components/parameters/short-circuit/short-circuit-specific-fields.tsx +++ b/src/components/parameters/short-circuit/short-circuit-specific-fields.tsx @@ -40,6 +40,16 @@ const equipmentTypes: string[] = [ EquipmentType.DANGLING_LINE, ]; +const styles = { + h4: { + marginBottom: 1, + }, + h5: { + marginBottom: 1, + marginTop: 1, + }, +}; + export interface ShortCircuitSpecificFieldsProps { isDeveloperMode: boolean; } @@ -157,12 +167,12 @@ export function ShortCircuitSpecificFields({ isDeveloperMode = true }: Readonly< fullHeight /> - - + + {inClusterOnlyStartedGenerators} - + {outClusterOnlyStartedGenerators} From 62f93c015ccc6bea4237f826dc0726f187752c48 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Tue, 3 Feb 2026 09:00:09 +0100 Subject: [PATCH 3/3] try to fix Signed-off-by: Etienne LESOT --- src/components/parameters/common/utils.ts | 7 ++- .../short-circuit-parameters-utils.ts | 21 +------ .../short-circuit-specific-fields.tsx | 56 +------------------ .../use-short-circuit-parameters-form.ts | 2 + 4 files changed, 12 insertions(+), 74 deletions(-) diff --git a/src/components/parameters/common/utils.ts b/src/components/parameters/common/utils.ts index 682c3fe72..ee06c61e5 100644 --- a/src/components/parameters/common/utils.ts +++ b/src/components/parameters/common/utils.ts @@ -13,6 +13,7 @@ import { } from '../../../utils'; import { SPECIFIC_PARAMETERS } from './constant'; import yup from '../../../utils/yupConfig'; +import { SHORT_CIRCUIT_IN_CALCULATION_CLUSTER_FILTERS } from '../short-circuit'; export const getSpecificParametersFormSchema = (specificParameters: SpecificParameterInfos[] | undefined) => { const shape: { [key: string]: yup.AnySchema } = {}; @@ -97,7 +98,11 @@ export const getAllSpecificParametersValues = ( ): SpecificParametersValues => { return Object.keys(formData[SPECIFIC_PARAMETERS]).reduce((acc: SpecificParametersValues, key: string) => { if (_specificParametersValues[key].toString() !== formData[SPECIFIC_PARAMETERS][key].toString()) { - acc[key] = formData[SPECIFIC_PARAMETERS][key].toString(); + if (key == SHORT_CIRCUIT_IN_CALCULATION_CLUSTER_FILTERS) { + acc[key] = formData[SPECIFIC_PARAMETERS][key]; + } else { + acc[key] = formData[SPECIFIC_PARAMETERS][key].toString(); + } } return acc; }, {}); diff --git a/src/components/parameters/short-circuit/short-circuit-parameters-utils.ts b/src/components/parameters/short-circuit/short-circuit-parameters-utils.ts index becfb6068..00d88621a 100644 --- a/src/components/parameters/short-circuit/short-circuit-parameters-utils.ts +++ b/src/components/parameters/short-circuit/short-circuit-parameters-utils.ts @@ -35,14 +35,7 @@ export enum ShortCircuitParametersTabValues { } export enum ShortCircuitParametersFieldConstants { - SUB_EQUIPMENT_TYPES_BY_FILTER = 'subEquipmentTypesByFilter', - FILTER_ID = 'filterId', - SUB_EQUIPMENT_TYPES = 'subEquipmentTypes', -} - -export interface FilterSubEquipments { - [ShortCircuitParametersFieldConstants.FILTER_ID]: string; - [ShortCircuitParametersFieldConstants.SUB_EQUIPMENT_TYPES]: string[]; + FILTER_ID = 'id', } export interface FilterElement { @@ -109,10 +102,6 @@ export const getSpecificShortCircuitParametersFormSchema = ( [SHORT_CIRCUIT_IN_CALCULATION_CLUSTER_FILTERS]: yup.array().of( yup.object().shape({ [ShortCircuitParametersFieldConstants.FILTER_ID]: yup.string().required(), - [ShortCircuitParametersFieldConstants.SUB_EQUIPMENT_TYPES]: yup - .array() - .required() - .of(yup.string().required()), }) ), }, @@ -155,6 +144,7 @@ export const getDefaultShortCircuitSpecificParamsValues = ( active: false, })); } + defaultValues[SHORT_CIRCUIT_IN_CALCULATION_CLUSTER_FILTERS] = []; return defaultValues; }; @@ -222,10 +212,3 @@ export const formatShortCircuitSpecificParameters = ( } return formatted; }; - -export function isSubstationOrVoltageLevelFilter(filter: FilterElement) { - return ( - filter.specificMetadata.equipmentType === EquipmentType.SUBSTATION || - filter.specificMetadata.equipmentType === EquipmentType.VOLTAGE_LEVEL - ); -} diff --git a/src/components/parameters/short-circuit/short-circuit-specific-fields.tsx b/src/components/parameters/short-circuit/short-circuit-specific-fields.tsx index 41fadc9a1..cc8a7d349 100644 --- a/src/components/parameters/short-circuit/short-circuit-specific-fields.tsx +++ b/src/components/parameters/short-circuit/short-circuit-specific-fields.tsx @@ -18,27 +18,9 @@ import { SHORT_CIRCUIT_ONLY_STARTED_GENERATORS_OUTSIDE_CALCULATION_CLUSTER, SHORT_CIRCUIT_POWER_ELECTRONICS_MATERIALS, } from './constants'; -import { - FilterElement, - FilterSubEquipments, - isSubstationOrVoltageLevelFilter, - ShortCircuitParametersFieldConstants, -} from './short-circuit-parameters-utils'; +import { FilterElement } from './short-circuit-parameters-utils'; -const equipmentTypes: string[] = [ - EquipmentType.SUBSTATION, - EquipmentType.VOLTAGE_LEVEL, - EquipmentType.LINE, - EquipmentType.TWO_WINDINGS_TRANSFORMER, - EquipmentType.THREE_WINDINGS_TRANSFORMER, - EquipmentType.GENERATOR, - EquipmentType.BATTERY, - EquipmentType.LOAD, - EquipmentType.SHUNT_COMPENSATOR, - EquipmentType.STATIC_VAR_COMPENSATOR, - EquipmentType.HVDC_LINE, - EquipmentType.DANGLING_LINE, -]; +const equipmentTypes: string[] = [EquipmentType.VOLTAGE_LEVEL]; const styles = { h4: { @@ -116,39 +98,6 @@ export function ShortCircuitSpecificFields({ isDeveloperMode = true }: Readonly< [watchSpecificParameters] ); - const handleFilterOnChange = useCallback( - (_currentFilters: any, action?: ArrayAction, filter?: FilterElement) => { - if (!action || !filter) { - console.error('Action or filter is missing in handleFilterOnChange'); - return; - } - if (isSubstationOrVoltageLevelFilter(filter)) { - const currentSubEquipmentsByFilters = getValues( - ShortCircuitParametersFieldConstants.SUB_EQUIPMENT_TYPES_BY_FILTER - ); - if (action === ArrayAction.ADD) { - const newFilterSubEquipments = { - [ShortCircuitParametersFieldConstants.FILTER_ID]: filter.id, - [ShortCircuitParametersFieldConstants.SUB_EQUIPMENT_TYPES]: [], - }; - setValue(ShortCircuitParametersFieldConstants.SUB_EQUIPMENT_TYPES_BY_FILTER, [ - ...currentSubEquipmentsByFilters, - newFilterSubEquipments, - ]); - } else if (action === ArrayAction.REMOVE) { - setValue( - ShortCircuitParametersFieldConstants.SUB_EQUIPMENT_TYPES_BY_FILTER, - currentSubEquipmentsByFilters.filter( - (value: FilterSubEquipments) => - value[ShortCircuitParametersFieldConstants.FILTER_ID] !== filter.id - ) - ); - } - } - }, - [setValue, getValues] - ); - return ( <> {isThereSpecificParameters && ( @@ -163,7 +112,6 @@ export function ShortCircuitSpecificFields({ isDeveloperMode = true }: Readonly< equipmentTypes={equipmentTypes} ChipComponent={OverflowableChipWithHelperText} chipProps={{ variant: 'outlined' }} - onChange={handleFilterOnChange} fullHeight /> diff --git a/src/components/parameters/short-circuit/use-short-circuit-parameters-form.ts b/src/components/parameters/short-circuit/use-short-circuit-parameters-form.ts index d4ea462c0..a6bd19f07 100644 --- a/src/components/parameters/short-circuit/use-short-circuit-parameters-form.ts +++ b/src/components/parameters/short-circuit/use-short-circuit-parameters-form.ts @@ -15,6 +15,7 @@ import { DESCRIPTION, NAME } from '../../inputs'; import { InitialVoltage, PredefinedParameters, + SHORT_CIRCUIT_IN_CALCULATION_CLUSTER_FILTERS, SHORT_CIRCUIT_INITIAL_VOLTAGE_PROFILE_MODE, SHORT_CIRCUIT_ONLY_STARTED_GENERATORS_IN_CALCULATION_CLUSTER, SHORT_CIRCUIT_PREDEFINED_PARAMS, @@ -152,6 +153,7 @@ export const useShortCircuitParametersForm = ({ predefinedParameter === PredefinedParameters.ICC_MIN_WITH_NOMINAL_VOLTAGE_MAP, dirty ); + setValue(`${SPECIFIC_PARAMETERS}.${SHORT_CIRCUIT_IN_CALCULATION_CLUSTER_FILTERS}`, []); }, [params?.commonParameters, setValue] );