diff --git a/package-lock.json b/package-lock.json index 4f8e9874a3..c2a8fa2b84 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", - "@gridsuite/commons-ui": "0.76.2", + "@gridsuite/commons-ui": "0.77.0", "@hookform/resolvers": "^3.3.4", "@mui/icons-material": "^5.15.14", "@mui/lab": "5.0.0-alpha.169", @@ -3202,9 +3202,9 @@ } }, "node_modules/@gridsuite/commons-ui": { - "version": "0.76.2", - "resolved": "https://registry.npmjs.org/@gridsuite/commons-ui/-/commons-ui-0.76.2.tgz", - "integrity": "sha512-ecIWTX/gvddjbKDtSZSCaTGnk3tspBtsKvxSD0x4jvzxUM+DL3y9X9eLugmW+7eI9vEtUjnTPifJiKTueu5WZg==", + "version": "0.77.0", + "resolved": "https://registry.npmjs.org/@gridsuite/commons-ui/-/commons-ui-0.77.0.tgz", + "integrity": "sha512-mUZszkwwpYR4sbOlYRYSMt8CUkywbCLVcGkhLG8S7IuHmoKO4psN2sCMr35tNgvkBM+xh0jow4bNesn3WZTYnQ==", "dependencies": { "@react-querybuilder/dnd": "^7.2.0", "@react-querybuilder/material": "^7.2.0", diff --git a/package.json b/package.json index 846bb0778c..5b955711d6 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "dependencies": { "@emotion/react": "^11.11.4", "@emotion/styled": "^11.11.5", - "@gridsuite/commons-ui": "0.76.2", + "@gridsuite/commons-ui": "0.77.0", "@hookform/resolvers": "^3.3.4", "@mui/icons-material": "^5.15.14", "@mui/lab": "5.0.0-alpha.169", diff --git a/src/components/dialogs/network-modifications/by-filter/by-assignment/assignment/assignment-constants.ts b/src/components/dialogs/network-modifications/by-filter/by-assignment/assignment/assignment-constants.ts index 6e829d76d7..55ce6efc87 100644 --- a/src/components/dialogs/network-modifications/by-filter/by-assignment/assignment/assignment-constants.ts +++ b/src/components/dialogs/network-modifications/by-filter/by-assignment/assignment/assignment-constants.ts @@ -6,10 +6,10 @@ */ import type { ReadonlyDeep } from 'type-fest'; -import { DataType, FieldOptionType, FieldType } from './assignment.type'; +import { DataType, FieldOptionType } from './assignment.type'; import { LOAD_TYPES } from '../../../../../network/constants'; -import { EquipmentType, kiloUnitToUnit, microUnitToUnit, unitToKiloUnit, unitToMicroUnit } from '@gridsuite/commons-ui'; -import { KILO_AMPERE, MICRO_SIEMENS } from '../../../../../utils/field-constants'; +import { EquipmentType, FieldType } from '@gridsuite/commons-ui'; +import { KILO_AMPERE, MEGA_VAR, MICRO_SIEMENS, SIEMENS } from '../../../../../utils/field-constants'; export const FIELD_OPTIONS = { PROPERTY: { @@ -105,18 +105,14 @@ export const FIELD_OPTIONS = { MAX_SUSCEPTANCE: { id: FieldType.MAX_SUSCEPTANCE, label: 'maxSusceptance', - unit: MICRO_SIEMENS, + unit: SIEMENS, dataType: DataType.DOUBLE, - outputConverter: (value) => microUnitToUnit(value), - inputConverter: (value) => unitToMicroUnit(value), }, MAX_Q_AT_NOMINAL_V: { id: FieldType.MAX_Q_AT_NOMINAL_V, label: 'maxQAtNominalV', - unit: MICRO_SIEMENS, + unit: MEGA_VAR, dataType: DataType.DOUBLE, - outputConverter: (value) => microUnitToUnit(value), - inputConverter: (value) => unitToMicroUnit(value), }, NOMINAL_VOLTAGE: { id: FieldType.NOMINAL_VOLTAGE, @@ -138,16 +134,12 @@ export const FIELD_OPTIONS = { label: 'LowShortCircuitCurrentLimit', unit: KILO_AMPERE, dataType: DataType.DOUBLE, - outputConverter: (value) => kiloUnitToUnit(value), - inputConverter: (value) => unitToKiloUnit(value), }, HIGH_SHORT_CIRCUIT_CURRENT_LIMIT: { id: FieldType.HIGH_SHORT_CIRCUIT_CURRENT_LIMIT, label: 'HighShortCircuitCurrentLimit', unit: KILO_AMPERE, dataType: DataType.DOUBLE, - outputConverter: (value) => kiloUnitToUnit(value), - inputConverter: (value) => unitToKiloUnit(value), }, ACTIVE_POWER: { id: FieldType.ACTIVE_POWER, @@ -174,16 +166,12 @@ export const FIELD_OPTIONS = { label: 'G', unit: MICRO_SIEMENS, dataType: DataType.DOUBLE, - outputConverter: (value) => microUnitToUnit(value), - inputConverter: (value) => unitToMicroUnit(value), }, B: { id: FieldType.B, label: 'B', unit: MICRO_SIEMENS, dataType: DataType.DOUBLE, - outputConverter: (value) => microUnitToUnit(value), - inputConverter: (value) => unitToMicroUnit(value), }, RATED_U1: { id: FieldType.RATED_U1, diff --git a/src/components/dialogs/network-modifications/by-filter/by-assignment/assignment/assignment-form.tsx b/src/components/dialogs/network-modifications/by-filter/by-assignment/assignment/assignment-form.tsx index 3a1838adbe..409bc9d566 100644 --- a/src/components/dialogs/network-modifications/by-filter/by-assignment/assignment/assignment-form.tsx +++ b/src/components/dialogs/network-modifications/by-filter/by-assignment/assignment/assignment-form.tsx @@ -20,11 +20,11 @@ import DensityLargeIcon from '@mui/icons-material/DensityLarge'; import { EDITED_FIELD, FILTERS, PROPERTY_NAME_FIELD, VALUE_FIELD } from '../../../../../utils/field-constants'; import { useFormContext, useWatch } from 'react-hook-form'; import { getIdOrValue } from '../../../../commons/utils'; -import { useIntl } from 'react-intl'; import { DataType, FieldOptionType } from './assignment.type'; import { areIdsEqual, comparatorStrIgnoreCase } from '../../../../../utils/utils'; import { PredefinedProperties } from '../../../common/properties/property-utils'; import GridItem from '../../../../commons/grid-item'; +import useFormatLabelWithUnit from '../../../../../../hooks/use-format-label-with-unit'; interface AssignmentFormProps { name: string; @@ -41,8 +41,6 @@ const AssignmentForm: FC = ({ equipmentFields, equipmentType, }) => { - const intl = useIntl(); - const { setValue } = useFormContext(); const watchEditedField = useWatch({ @@ -76,14 +74,7 @@ const AssignmentForm: FC = ({ setValue(`${name}.${index}.${VALUE_FIELD}`, dataType === DataType.BOOLEAN ? false : null); } - const formatLabelWithUnit = useMemo(() => { - return (value: string | { label: string; unit?: string }) => { - if (typeof value === 'string') { - return value; - } - return `${intl.formatMessage({ id: value.label })} ${value.unit ?? ''}`; - }; - }, [intl]); + const formatLabelWithUnit = useFormatLabelWithUnit(); const filtersField = ( { return Object.values(FIELD_OPTIONS).find((fieldOption) => fieldOption.id === fieldName); }; -export const convertOutputValue = (fieldName?: string | null, fieldValue?: FieldValue) => { - const fieldOption = getFieldOption(fieldName); - // @ts-expect-error TODO TS2339: Property outputConverter does not exist on typeof FIELD_OPTIONS[*] - return fieldOption?.outputConverter ? fieldOption.outputConverter(Number(fieldValue)) : fieldValue; -}; - -export const convertInputValue = (fieldName?: string | null, fieldValue?: FieldValue) => { - const fieldOption = getFieldOption(fieldName); - // @ts-expect-error TODO TS2339: Property inputConverter does not exist on typeof FIELD_OPTIONS[*] - return fieldOption?.inputConverter ? fieldOption.inputConverter(Number(fieldValue)) : fieldValue; -}; - // ("undefined" is accepted here in RHF, but it conflicts with MUI behaviour which does not like undefined values) export const getAssignmentInitialValue = () => ({ [FILTERS]: [], diff --git a/src/components/dialogs/network-modifications/by-filter/by-assignment/assignment/assignment.type.ts b/src/components/dialogs/network-modifications/by-filter/by-assignment/assignment/assignment.type.ts index 84ecd2651f..87234e974a 100644 --- a/src/components/dialogs/network-modifications/by-filter/by-assignment/assignment/assignment.type.ts +++ b/src/components/dialogs/network-modifications/by-filter/by-assignment/assignment/assignment.type.ts @@ -81,7 +81,6 @@ export enum FieldType { PHASE_TARGET_DEADBAND = 'PHASE_TARGET_DEADBAND', LOAD_TYPE = 'LOAD_TYPE', } - // --- types for the form model --- // export type Assignment = { diff --git a/src/components/dialogs/network-modifications/by-filter/by-assignment/modification-by-assignment-dialog.tsx b/src/components/dialogs/network-modifications/by-filter/by-assignment/modification-by-assignment-dialog.tsx index 5a553e0288..c00e5ae755 100644 --- a/src/components/dialogs/network-modifications/by-filter/by-assignment/modification-by-assignment-dialog.tsx +++ b/src/components/dialogs/network-modifications/by-filter/by-assignment/modification-by-assignment-dialog.tsx @@ -7,7 +7,13 @@ import { yupResolver } from '@hookform/resolvers/yup'; import yup from 'components/utils/yup-config'; -import { CustomFormProvider, useSnackMessage } from '@gridsuite/commons-ui'; +import { + convertInputValue, + convertOutputValue, + CustomFormProvider, + FieldType, + useSnackMessage, +} from '@gridsuite/commons-ui'; import { FC, useCallback, useEffect } from 'react'; import { FetchStatus } from '../../../../../services/utils'; import { useForm } from 'react-hook-form'; @@ -18,8 +24,6 @@ import ModificationByAssignmentForm from './modification-by-assignment-form'; import { ASSIGNMENTS, EDITED_FIELD, EQUIPMENT_TYPE_FIELD, VALUE_FIELD } from '../../../../utils/field-constants'; import { modifyByAssignment } from '../../../../../services/study/network-modifications'; import { - convertInputValue, - convertOutputValue, getAssignmentFromEditData, getAssignmentInitialValue, getAssignmentsSchema, @@ -72,7 +76,10 @@ const ModificationByAssignmentDialog: FC = ({ const assignments: Assignment[] = editData.assignmentInfosList?.map((info: Assignment) => { const assignment = getAssignmentFromEditData(info); - const valueConverted = convertInputValue(assignment[EDITED_FIELD], assignment[VALUE_FIELD]); + const fieldKey = assignment[EDITED_FIELD] as keyof typeof FieldType; + const field = FieldType[fieldKey]; + const value = assignment[VALUE_FIELD]; + const valueConverted = convertInputValue(field, value); return { ...assignment, [VALUE_FIELD]: valueConverted, @@ -93,7 +100,10 @@ const ModificationByAssignmentDialog: FC = ({ (formData: ModificationByAssignment) => { const assignmentsList = formData[ASSIGNMENTS].map((assignment) => { const dataType = getDataType(assignment[EDITED_FIELD]); - const valueConverted = convertOutputValue(assignment[EDITED_FIELD], assignment[VALUE_FIELD]); + const fieldKey = assignment[EDITED_FIELD] as keyof typeof FieldType; + const field = FieldType[fieldKey]; + const value = assignment[VALUE_FIELD]; + const valueConverted = convertOutputValue(field, value); return { ...assignment, dataType, diff --git a/src/components/dialogs/network-modifications/by-filter/by-formula/by-formula-dialog.jsx b/src/components/dialogs/network-modifications/by-filter/by-formula/by-formula-dialog.jsx index 7d5e11ae49..44209ca99d 100644 --- a/src/components/dialogs/network-modifications/by-filter/by-formula/by-formula-dialog.jsx +++ b/src/components/dialogs/network-modifications/by-filter/by-formula/by-formula-dialog.jsx @@ -7,7 +7,13 @@ import { yupResolver } from '@hookform/resolvers/yup'; import yup from 'components/utils/yup-config'; -import { CustomFormProvider, useSnackMessage } from '@gridsuite/commons-ui'; +import { + convertInputValue, + convertOutputValue, + CustomFormProvider, + FieldType, + useSnackMessage, +} from '@gridsuite/commons-ui'; import { useCallback, useEffect } from 'react'; import { FetchStatus } from '../../../../../services/utils'; import { useForm } from 'react-hook-form'; @@ -29,11 +35,11 @@ import { import { modifyByFormula } from '../../../../../services/study/network-modifications'; import { getFormulaInitialValue, getFormulaSchema } from './formula/formula-utils'; -function getFieldOrValue(input) { +function getFieldOrConvertedUnitValue(input, fieldType) { const value = input.replace(',', '.'); const isNumber = !isNaN(parseFloat(value)); return { - [VALUE]: isNumber ? value : null, + [VALUE]: isNumber ? convertOutputValue(fieldType, value) : null, [EQUIPMENT_FIELD]: isNumber ? null : input, }; } @@ -71,8 +77,16 @@ const ByFormulaDialog = ({ editData, currentNode, studyUuid, isUpdate, editDataF useEffect(() => { if (editData) { const formulas = editData.formulaInfosList?.map((formula) => { - const ref1 = formula?.fieldOrValue1?.value?.toString() ?? formula?.fieldOrValue1?.equipmentField; - const ref2 = formula?.fieldOrValue2?.value?.toString() ?? formula?.fieldOrValue2?.equipmentField; + const valueConverted1 = convertInputValue( + FieldType[formula[EDITED_FIELD]], + formula?.fieldOrValue1?.value + ); + const valueConverted2 = convertInputValue( + FieldType[formula[EDITED_FIELD]], + formula?.fieldOrValue2?.value + ); + const ref1 = valueConverted1?.toString() ?? formula?.fieldOrValue1?.equipmentField; + const ref2 = valueConverted2?.toString() ?? formula?.fieldOrValue2?.equipmentField; return { [REFERENCE_FIELD_OR_VALUE_1]: ref1, [REFERENCE_FIELD_OR_VALUE_2]: ref2, @@ -95,8 +109,14 @@ const ByFormulaDialog = ({ editData, currentNode, studyUuid, isUpdate, editDataF const onSubmit = useCallback( (data) => { const formulas = data[FORMULAS].map((formula) => { - const fieldOrValue1 = getFieldOrValue(formula[REFERENCE_FIELD_OR_VALUE_1]); - const fieldOrValue2 = getFieldOrValue(formula[REFERENCE_FIELD_OR_VALUE_2]); + const fieldOrValue1 = getFieldOrConvertedUnitValue( + formula[REFERENCE_FIELD_OR_VALUE_1], + FieldType[formula[EDITED_FIELD]] + ); + const fieldOrValue2 = getFieldOrConvertedUnitValue( + formula[REFERENCE_FIELD_OR_VALUE_2], + FieldType[formula[EDITED_FIELD]] + ); return { fieldOrValue1, fieldOrValue2, diff --git a/src/components/dialogs/network-modifications/by-filter/by-formula/formula/formula-form.tsx b/src/components/dialogs/network-modifications/by-filter/by-formula/formula/formula-form.tsx index 371f9cc0d6..032bb188dc 100644 --- a/src/components/dialogs/network-modifications/by-filter/by-formula/formula/formula-form.tsx +++ b/src/components/dialogs/network-modifications/by-filter/by-formula/formula/formula-form.tsx @@ -20,9 +20,9 @@ import { EQUIPMENTS_FIELDS } from './formula-utils'; import ReferenceAutocompleteInput from './reference-autocomplete-input'; import DragHandleIcon from '@mui/icons-material/DragHandle'; import { getIdOrValue, getLabelOrValue } from '../../../../commons/utils'; -import { useIntl } from 'react-intl'; import { Grid } from '@mui/material'; import GridItem from '../../../../commons/grid-item'; +import useFormatLabelWithUnit from '../../../../../../hooks/use-format-label-with-unit'; interface FormulaProps { name: string; @@ -40,13 +40,12 @@ const FormulaForm: FunctionComponent = ({ name, index }) => { const equipmentTypeWatch = useWatch({ name: EQUIPMENT_TYPE_FIELD, }); - - const intl = useIntl(); - - const equipmentFields: { id: string; label: string }[] = + const equipmentFields: { id: string; label: string; unit: string }[] = // @ts-expect-error TODO: missing type in context EQUIPMENTS_FIELDS?.[equipmentTypeWatch] ?? []; + const formatLabelWithUnit = useFormatLabelWithUnit(); + const filtersField = ( = ({ name, index }) => { size={'small'} inputTransform={(value: any) => equipmentFields.find((option) => option?.id === value) || value} outputTransform={(option: any) => getIdOrValue(option) ?? null} - getOptionLabel={(option: any) => intl.formatMessage({ id: getLabelOrValue(option) })} + getOptionLabel={(option: any) => formatLabelWithUnit(option)} /> ); diff --git a/src/components/dialogs/network-modifications/by-filter/by-formula/formula/formula-utils.tsx b/src/components/dialogs/network-modifications/by-filter/by-formula/formula/formula-utils.tsx index d5380dba60..d9fc753e16 100644 --- a/src/components/dialogs/network-modifications/by-filter/by-formula/formula/formula-utils.tsx +++ b/src/components/dialogs/network-modifications/by-filter/by-formula/formula/formula-utils.tsx @@ -11,10 +11,14 @@ import { EQUIPMENT_TYPE_FIELD, FILTERS, ID, + KILO_AMPERE, + MEGA_VAR, + MICRO_SIEMENS, NAME, OPERATOR, REFERENCE_FIELD_OR_VALUE_1, REFERENCE_FIELD_OR_VALUE_2, + SIEMENS, SPECIFIC_METADATA, TYPE, } from '../../../../../utils/field-constants'; @@ -24,6 +28,7 @@ import { AnyObject, TestContext, TestFunction } from 'yup'; export type EquipmentField = { id: string; label: string; + unit?: string; }; type EquipmentFieldsKeys = | EQUIPMENT_TYPES.GENERATOR @@ -69,8 +74,8 @@ export const EQUIPMENTS_FIELDS: EquipmentFields = { [EQUIPMENT_TYPES.SHUNT_COMPENSATOR]: [ { id: 'MAXIMUM_SECTION_COUNT', label: 'maximumSectionCount' }, { id: 'SECTION_COUNT', label: 'sectionCount' }, - { id: 'MAX_SUSCEPTANCE', label: 'maxSusceptance' }, - { id: 'MAX_Q_AT_NOMINAL_V', label: 'maxQAtNominalV' }, + { id: 'MAX_SUSCEPTANCE', label: 'maxSusceptance', unit: SIEMENS }, + { id: 'MAX_Q_AT_NOMINAL_V', label: 'maxQAtNominalV', unit: MEGA_VAR }, ], [EQUIPMENT_TYPES.VOLTAGE_LEVEL]: [ { id: 'NOMINAL_VOLTAGE', label: 'NominalVoltage' }, @@ -79,10 +84,12 @@ export const EQUIPMENTS_FIELDS: EquipmentFields = { { id: 'LOW_SHORT_CIRCUIT_CURRENT_LIMIT', label: 'LowShortCircuitCurrentLimit', + unit: KILO_AMPERE, }, { id: 'HIGH_SHORT_CIRCUIT_CURRENT_LIMIT', label: 'HighShortCircuitCurrentLimit', + unit: KILO_AMPERE, }, ], [EQUIPMENT_TYPES.LOAD]: [ @@ -92,8 +99,8 @@ export const EQUIPMENTS_FIELDS: EquipmentFields = { [EQUIPMENT_TYPES.TWO_WINDINGS_TRANSFORMER]: [ { id: 'R', label: 'SeriesResistanceText' }, { id: 'X', label: 'SeriesReactanceText' }, - { id: 'G', label: 'G' }, - { id: 'B', label: 'B' }, + { id: 'G', label: 'G', unit: MICRO_SIEMENS }, + { id: 'B', label: 'B', unit: MICRO_SIEMENS }, { id: 'RATED_U1', label: 'RatedU1' }, { id: 'RATED_U2', label: 'RatedU2' }, { id: 'RATED_S', label: 'RatedNominalPowerText' }, diff --git a/src/components/dialogs/network-modifications/line/characteristics-pane/line-characteristics-pane.jsx b/src/components/dialogs/network-modifications/line/characteristics-pane/line-characteristics-pane.jsx index b4a8e3faf7..96c8fb40d5 100644 --- a/src/components/dialogs/network-modifications/line/characteristics-pane/line-characteristics-pane.jsx +++ b/src/components/dialogs/network-modifications/line/characteristics-pane/line-characteristics-pane.jsx @@ -7,7 +7,7 @@ import { Grid } from '@mui/material'; import { MicroSusceptanceAdornment, OhmAdornment } from '../../../dialog-utils'; -import { FloatInput } from '@gridsuite/commons-ui'; +import { convertInputValue, FieldType, FloatInput } from '@gridsuite/commons-ui'; import { ConnectivityForm } from '../../../connectivity/connectivity-form'; import { B1, @@ -20,7 +20,6 @@ import { R, X, } from 'components/utils/field-constants'; -import { unitToMicroUnit } from 'utils/unit-converter'; import PropertiesForm from '../../common/properties/properties-form'; import useVoltageLevelsListInfos from '../../../../../hooks/use-voltage-levels-list-infos'; import GridSection from '../../../commons/grid-section'; @@ -70,7 +69,7 @@ const LineCharacteristicsPane = ({ name={`${id}.${G1}`} label="ShuntConductanceText" adornment={MicroSusceptanceAdornment} - previousValue={unitToMicroUnit(lineToModify?.g1)} + previousValue={convertInputValue(FieldType.G1, lineToModify?.g1)} clearable={clearableFields} /> ); @@ -80,7 +79,7 @@ const LineCharacteristicsPane = ({ name={`${id}.${B1}`} label="ShuntSusceptanceText" adornment={MicroSusceptanceAdornment} - previousValue={unitToMicroUnit(lineToModify?.b1)} + previousValue={convertInputValue(FieldType.B1, lineToModify?.b1)} clearable={clearableFields} /> ); @@ -90,7 +89,7 @@ const LineCharacteristicsPane = ({ name={`${id}.${G2}`} label="ShuntConductanceText" adornment={MicroSusceptanceAdornment} - previousValue={unitToMicroUnit(lineToModify?.g2)} + previousValue={convertInputValue(FieldType.G2, lineToModify?.g2)} clearable={clearableFields} /> ); @@ -100,7 +99,7 @@ const LineCharacteristicsPane = ({ name={`${id}.${B2}`} label="ShuntSusceptanceText" adornment={MicroSusceptanceAdornment} - previousValue={unitToMicroUnit(lineToModify?.b2)} + previousValue={convertInputValue(FieldType.B2, lineToModify?.b2)} clearable={clearableFields} /> ); diff --git a/src/components/dialogs/network-modifications/line/creation/line-creation-dialog.jsx b/src/components/dialogs/network-modifications/line/creation/line-creation-dialog.jsx index 14f013adb4..e0fbaa2734 100644 --- a/src/components/dialogs/network-modifications/line/creation/line-creation-dialog.jsx +++ b/src/components/dialogs/network-modifications/line/creation/line-creation-dialog.jsx @@ -5,7 +5,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { CustomFormProvider, TextInput, useSnackMessage } from '@gridsuite/commons-ui'; +import { + convertInputValue, + convertOutputValue, + CustomFormProvider, + FieldType, + TextInput, + useSnackMessage, +} from '@gridsuite/commons-ui'; import { yupResolver } from '@hookform/resolvers/yup'; import { Box, Grid } from '@mui/material'; import { @@ -41,7 +48,6 @@ import PropTypes from 'prop-types'; import { useCallback, useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import { FetchStatus } from '../../../../../services/utils'; -import { microUnitToUnit, unitToMicroUnit } from 'utils/unit-converter'; import { FORM_LOADING_DELAY, UNDEFINED_CONNECTION_DIRECTION } from 'components/network/constants'; import yup from 'components/utils/yup-config'; import ModificationDialog from '../../../commons/modificationDialog'; @@ -149,10 +155,10 @@ const LineCreationDialog = ({ ...getCharacteristicsFormData({ r: line.r, x: line.x, - g1: unitToMicroUnit(line.g1), // this form uses and displays microSiemens - b1: unitToMicroUnit(line.b1), - g2: unitToMicroUnit(line.g2), - b2: unitToMicroUnit(line.b2), + g1: convertInputValue(FieldType.G1, line.g1), // this form uses and displays microSiemens + b1: convertInputValue(FieldType.B1, line.b1), + g2: convertInputValue(FieldType.G2, line.g2), + b2: convertInputValue(FieldType.B2, line.b2), ...(displayConnectivity && getConnectivityFormData( { @@ -200,10 +206,10 @@ const LineCreationDialog = ({ ...getCharacteristicsFormData({ r: line.r, x: line.x, - g1: unitToMicroUnit(line.g1), - b1: unitToMicroUnit(line.b1), - g2: unitToMicroUnit(line.g2), - b2: unitToMicroUnit(line.b2), + g1: convertInputValue(FieldType.G1, line.g1), + b1: convertInputValue(FieldType.B1, line.b1), + g2: convertInputValue(FieldType.G2, line.g2), + b2: convertInputValue(FieldType.B2, line.b2), ...getConnectivityFormData( { busbarSectionId: line.busOrBusbarSectionId1, @@ -290,10 +296,10 @@ const LineCreationDialog = ({ lineName: sanitizeString(header[EQUIPMENT_NAME]), r: characteristics[R], x: characteristics[X], - g1: microUnitToUnit(characteristics[G1]), - b1: microUnitToUnit(characteristics[B1]), - g2: microUnitToUnit(characteristics[G2]), - b2: microUnitToUnit(characteristics[B2]), + g1: convertOutputValue(FieldType.G1, characteristics[G1]), + b1: convertOutputValue(FieldType.B1, characteristics[B1]), + g2: convertOutputValue(FieldType.G2, characteristics[G2]), + b2: convertOutputValue(FieldType.B2, characteristics[B2]), voltageLevelId1: characteristics[CONNECTIVITY_1]?.[VOLTAGE_LEVEL]?.id, busOrBusbarSectionId1: characteristics[CONNECTIVITY_1]?.[BUS_OR_BUSBAR_SECTION]?.id, voltageLevelId2: characteristics[CONNECTIVITY_2]?.[VOLTAGE_LEVEL]?.id, diff --git a/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.jsx b/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.jsx index 72debdcb5c..855b327c68 100644 --- a/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.jsx +++ b/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.jsx @@ -6,7 +6,13 @@ */ import { useCallback, useEffect, useMemo, useState } from 'react'; -import { CustomFormProvider, useSnackMessage } from '@gridsuite/commons-ui'; +import { + convertInputValue, + convertOutputValue, + CustomFormProvider, + FieldType, + useSnackMessage, +} from '@gridsuite/commons-ui'; import { yupResolver } from '@hookform/resolvers/yup'; import { ADDITIONAL_PROPERTIES, @@ -39,7 +45,6 @@ import { } from 'components/utils/field-constants'; import { useForm } from 'react-hook-form'; import { sanitizeString } from 'components/dialogs/dialog-utils'; -import { microUnitToUnit, unitToMicroUnit } from 'utils/unit-converter'; import yup from 'components/utils/yup-config'; import ModificationDialog from '../../../commons/modificationDialog'; @@ -161,10 +166,10 @@ const LineModificationDialog = ({ ...getCharacteristicsWithOutConnectivityFormData({ r: line.r?.value ?? null, x: line.x?.value ?? null, - g1: unitToMicroUnit(line.g1?.value ?? null), - b1: unitToMicroUnit(line.b1?.value ?? null), - g2: unitToMicroUnit(line.g2?.value ?? null), - b2: unitToMicroUnit(line.b2?.value ?? null), + g1: convertInputValue(FieldType.G1, line.g1?.value ?? null), + b1: convertInputValue(FieldType.B1, line.b1?.value ?? null), + g2: convertInputValue(FieldType.G2, line.g2?.value ?? null), + b2: convertInputValue(FieldType.B2, line.b2?.value ?? null), }), ...getLimitsFormData({ permanentLimit1: line.currentLimits1?.permanentLimit, @@ -228,10 +233,10 @@ const LineModificationDialog = ({ lineName: sanitizeString(line[EQUIPMENT_NAME]), r: characteristics[R], x: characteristics[X], - g1: microUnitToUnit(characteristics[G1]), - b1: microUnitToUnit(characteristics[B1]), - g2: microUnitToUnit(characteristics[G2]), - b2: microUnitToUnit(characteristics[B2]), + g1: convertOutputValue(FieldType.G1, characteristics[G1]), + b1: convertOutputValue(FieldType.B1, characteristics[B1]), + g2: convertOutputValue(FieldType.G2, characteristics[G2]), + b2: convertOutputValue(FieldType.B2, characteristics[B2]), currentLimit1: currentLimits1, currentLimit2: currentLimits2, voltageLevelId1: connectivity1[VOLTAGE_LEVEL]?.id, diff --git a/src/components/dialogs/network-modifications/tabular-modification/tabular-modification-dialog.jsx b/src/components/dialogs/network-modifications/tabular-modification/tabular-modification-dialog.jsx index 6cba2d0d11..fe2f875e11 100644 --- a/src/components/dialogs/network-modifications/tabular-modification/tabular-modification-dialog.jsx +++ b/src/components/dialogs/network-modifications/tabular-modification/tabular-modification-dialog.jsx @@ -19,8 +19,8 @@ import { createTabulareModification } from 'services/study/network-modifications import { FetchStatus } from 'services/utils'; import TabularModificationForm from './tabular-modification-form'; import { - convertValueFromBackToFront, - convertValueFromFrontToBack, + convertInputValues, + convertOutputValues, formatModification, getEquipmentTypeFromModificationType, TABULAR_MODIFICATION_TYPES, @@ -76,7 +76,7 @@ const TabularModificationDialog = ({ const modifications = editData?.modifications.map((modif) => { const modification = {}; Object.keys(formatModification(modif)).forEach((key) => { - modification[key] = convertValueFromBackToFront(key, modif[key]); + modification[key] = convertInputValues(key, modif[key]); }); return modification; }); @@ -95,7 +95,7 @@ const TabularModificationDialog = ({ type: modificationType, }; Object.keys(row).forEach((key) => { - modification[key] = convertValueFromFrontToBack(key, row[key]); + modification[key] = convertOutputValues(key, row[key]); }); return modification; }); diff --git a/src/components/dialogs/network-modifications/tabular-modification/tabular-modification-utils.ts b/src/components/dialogs/network-modifications/tabular-modification/tabular-modification-utils.ts index 8cd238357e..e669e0a20f 100644 --- a/src/components/dialogs/network-modifications/tabular-modification/tabular-modification-utils.ts +++ b/src/components/dialogs/network-modifications/tabular-modification/tabular-modification-utils.ts @@ -5,19 +5,24 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { MODIFICATION_TYPES } from '@gridsuite/commons-ui'; +import { convertInputValue, convertOutputValue, FieldType, MODIFICATION_TYPES } from '@gridsuite/commons-ui'; import { + B, + B1, + B2, CONNECTED, CONNECTED1, CONNECTED2, + COUNTRY, ENERGY_SOURCE, EQUIPMENT_ID, FORCED_OUTAGE_RATE, + G, + G1, + G2, HIGH_VOLTAGE_LIMIT, LOAD_TYPE, LOW_VOLTAGE_LIMIT, - G, - B, MARGINAL_COST, MAX_P, MAX_Q_AT_NOMINAL_V, @@ -29,27 +34,21 @@ import { PLANNED_ACTIVE_POWER_SET_POINT, PLANNED_OUTAGE_RATE, Q0, + R, RATED_S, RATED_U1, RATED_U2, SECTION_COUNT, - R, - X, SHUNT_COMPENSATOR_TYPE, - G1, - B1, - G2, - B2, STEP_UP_TRANSFORMER_REACTANCE, - COUNTRY, TARGET_P, TARGET_Q, TARGET_V, TRANSIENT_REACTANCE, VOLTAGE_REGULATION_ON, + X, } from 'components/utils/field-constants'; -import { microUnitToUnit, unitToMicroUnit } from 'utils/unit-converter'; -import { toModificationOperation } from 'components/utils/utils'; +import { toModificationOperation } from '../../../utils/utils'; export interface TabularModificationFields { [key: string]: string[]; @@ -112,38 +111,6 @@ export const formatModification = (modification: Modification) => { return rest; }; -export const convertValueFromBackToFront = (key: string, value: { value: string | number }) => { - switch (key) { - case EQUIPMENT_ID: - return value; - case G: - case B: - case G1: - case G2: - case B1: - case B2: - return unitToMicroUnit(value?.value); - default: - return value?.value; - } -}; - -export const convertValueFromFrontToBack = (key: string, value: string | number) => { - switch (key) { - case EQUIPMENT_ID: - return value; - case G: - case B: - case G1: - case G2: - case B1: - case B2: - return toModificationOperation(microUnitToUnit(value)); - default: - return toModificationOperation(value); - } -}; - export const getEquipmentTypeFromModificationType = (type: string) => { return Object.keys(TABULAR_MODIFICATION_TYPES).find((key) => TABULAR_MODIFICATION_TYPES[key] === type); }; @@ -151,3 +118,30 @@ export const getEquipmentTypeFromModificationType = (type: string) => { export const styles = { grid: { height: 500, width: '100%' }, }; + +/** + * Convert a camelCase string to SNAKE_CASE format and map it to a key in the FieldType enum. + * @param key - The camelCase string to be converted. + * @returns The corresponding value from the FieldType enum. + */ +const convertCamelToSnake = (key: string) => + FieldType[ + key + .split(/\.?(?=[A-Z])/) + .join('_') + .toUpperCase() as keyof typeof FieldType + ]; + +export const convertInputValues = (key: string, value: { value: string | number }) => { + if (key === EQUIPMENT_ID) { + return value; + } + return convertInputValue(convertCamelToSnake(key), value?.value); +}; + +export const convertOutputValues = (key: string, value: string | number) => { + if (key === EQUIPMENT_ID) { + return value; + } + return toModificationOperation(convertOutputValue(convertCamelToSnake(key), value)); +}; diff --git a/src/components/dialogs/network-modifications/two-windings-transformer/characteristics-pane/two-windings-transformer-characteristics-pane.jsx b/src/components/dialogs/network-modifications/two-windings-transformer/characteristics-pane/two-windings-transformer-characteristics-pane.jsx index a4f71c0da3..7ad2e2f2c2 100644 --- a/src/components/dialogs/network-modifications/two-windings-transformer/characteristics-pane/two-windings-transformer-characteristics-pane.jsx +++ b/src/components/dialogs/network-modifications/two-windings-transformer/characteristics-pane/two-windings-transformer-characteristics-pane.jsx @@ -8,9 +8,8 @@ import { Grid } from '@mui/material'; import { FormattedMessage } from 'react-intl'; import { MicroSusceptanceAdornment, MVAPowerAdornment, OhmAdornment, VoltageAdornment } from '../../../dialog-utils'; -import { FloatInput } from '@gridsuite/commons-ui'; +import { convertInputValue, FieldType, FloatInput } from '@gridsuite/commons-ui'; import { B, CHARACTERISTICS, G, R, RATED_S, RATED_U1, RATED_U2, X } from 'components/utils/field-constants'; -import { unitToMicroUnit } from '../../../../../utils/unit-converter'; import PropertiesForm from '../../common/properties/properties-form'; import GridSection from '../../../commons/grid-section'; import GridItem from '../../../commons/grid-item'; @@ -43,7 +42,7 @@ const TwoWindingsTransformerCharacteristicsPane = ({ id = CHARACTERISTICS, twtTo name={`${id}.${G}`} label="G" adornment={MicroSusceptanceAdornment} - previousValue={unitToMicroUnit(twtToModify?.g)} + previousValue={convertInputValue(FieldType.G, twtToModify?.g)} clearable={isModification} /> ); @@ -53,7 +52,7 @@ const TwoWindingsTransformerCharacteristicsPane = ({ id = CHARACTERISTICS, twtTo name={`${id}.${B}`} label="B" adornment={MicroSusceptanceAdornment} - previousValue={unitToMicroUnit(twtToModify?.b)} + previousValue={convertInputValue(FieldType.B, twtToModify?.b)} clearable={isModification} /> ); diff --git a/src/components/dialogs/network-modifications/two-windings-transformer/creation/two-windings-transformer-creation-dialog.jsx b/src/components/dialogs/network-modifications/two-windings-transformer/creation/two-windings-transformer-creation-dialog.jsx index e59cd0ba9d..444fb7b4de 100644 --- a/src/components/dialogs/network-modifications/two-windings-transformer/creation/two-windings-transformer-creation-dialog.jsx +++ b/src/components/dialogs/network-modifications/two-windings-transformer/creation/two-windings-transformer-creation-dialog.jsx @@ -5,7 +5,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { CustomFormProvider, useSnackMessage } from '@gridsuite/commons-ui'; +import { + convertInputValue, + convertOutputValue, + CustomFormProvider, + FieldType, + useSnackMessage, +} from '@gridsuite/commons-ui'; import { yupResolver } from '@hookform/resolvers/yup'; import { Grid } from '@mui/material'; import { @@ -55,7 +61,6 @@ import PropTypes from 'prop-types'; import { useCallback, useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; import { FetchStatus } from '../../../../../services/utils'; -import { microUnitToUnit, unitToMicroUnit } from 'utils/unit-converter'; import { sanitizeString } from '../../../dialog-utils'; import EquipmentSearchDialog from '../../../equipment-search-dialog'; import { useFormSearchCopy } from '../../../form-search-copy-hook'; @@ -218,8 +223,8 @@ const TwoWindingsTransformerCreationDialog = ({ ...getTwoWindingsTransformerFormData({ r: twt.r, x: twt.x, - g: unitToMicroUnit(twt.g), - b: unitToMicroUnit(twt.b), + g: convertInputValue(FieldType.G, twt.g), + b: convertInputValue(FieldType.B, twt.b), ratedU1: twt.ratedU1, ratedU2: twt.ratedU2, ratedS: twt.ratedS, @@ -311,8 +316,8 @@ const TwoWindingsTransformerCreationDialog = ({ ...getTwoWindingsTransformerFormData({ r: twt.r, x: twt.x, - g: unitToMicroUnit(twt.g), - b: unitToMicroUnit(twt.b), + g: convertInputValue(FieldType.G, twt.g), + b: convertInputValue(FieldType.B, twt.b), ratedU1: twt.ratedU1, ratedU2: twt.ratedU2, ratedS: twt.ratedS, @@ -503,8 +508,8 @@ const TwoWindingsTransformerCreationDialog = ({ temporaryLimits: sanitizeLimitNames(limits[CURRENT_LIMITS_2]?.[TEMPORARY_LIMITS]), }; - characteristics[G] = microUnitToUnit(characteristics[G]); - characteristics[B] = microUnitToUnit(characteristics[B]); + characteristics[G] = convertOutputValue(FieldType.G, characteristics[G]); + characteristics[B] = convertOutputValue(FieldType.B, characteristics[B]); let ratioTap = undefined; if (enableRatioTapChanger) { const ratioTapChangerFormValues = twt[RATIO_TAP_CHANGER]; diff --git a/src/components/dialogs/network-modifications/two-windings-transformer/modification/two-windings-transformer-modification-dialog.jsx b/src/components/dialogs/network-modifications/two-windings-transformer/modification/two-windings-transformer-modification-dialog.jsx index 50b554707d..450704eda5 100644 --- a/src/components/dialogs/network-modifications/two-windings-transformer/modification/two-windings-transformer-modification-dialog.jsx +++ b/src/components/dialogs/network-modifications/two-windings-transformer/modification/two-windings-transformer-modification-dialog.jsx @@ -5,7 +5,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { CustomFormProvider, useSnackMessage } from '@gridsuite/commons-ui'; +import { + convertInputValue, + convertOutputValue, + CustomFormProvider, + FieldType, + useSnackMessage, +} from '@gridsuite/commons-ui'; import { yupResolver } from '@hookform/resolvers/yup'; import { Box, Grid } from '@mui/material'; import { @@ -54,7 +60,6 @@ import { import PropTypes from 'prop-types'; import { useCallback, useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; -import { microUnitToUnit, unitToMicroUnit } from 'utils/unit-converter'; import { sanitizeString } from '../../../dialog-utils'; import { FORM_LOADING_DELAY, @@ -236,8 +241,8 @@ const TwoWindingsTransformerModificationDialog = ({ ...getCharacteristicsFormData({ r: twt.r?.value, x: twt.x?.value, - g: unitToMicroUnit(twt.g?.value), - b: unitToMicroUnit(twt.b?.value), + g: convertInputValue(FieldType.G, twt.g?.value), + b: convertInputValue(FieldType.B, twt.b?.value), ratedU1: twt.ratedU1?.value, ratedU2: twt.ratedU2?.value, ratedS: twt.ratedS?.value, @@ -490,8 +495,8 @@ const TwoWindingsTransformerModificationDialog = ({ twoWindingsTransformerName: toModificationOperation(sanitizeString(twt[EQUIPMENT_NAME])), r: toModificationOperation(characteristics[R]), x: toModificationOperation(characteristics[X]), - g: toModificationOperation(microUnitToUnit(characteristics[G])), - b: toModificationOperation(microUnitToUnit(characteristics[B])), + g: toModificationOperation(convertOutputValue(FieldType.G, characteristics[G])), + b: toModificationOperation(convertOutputValue(FieldType.B, characteristics[B])), ratedS: toModificationOperation(characteristics[RATED_S]), ratedU1: toModificationOperation(characteristics[RATED_U1]), ratedU2: toModificationOperation(characteristics[RATED_U2]), 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 82278e28b8..27d924635a 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 @@ -5,7 +5,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { CustomFormProvider, useSnackMessage } from '@gridsuite/commons-ui'; +import { + convertInputValue, + convertOutputValue, + CustomFormProvider, + FieldType, + useSnackMessage, +} from '@gridsuite/commons-ui'; import { yupResolver } from '@hookform/resolvers/yup'; import { sanitizeString } from 'components/dialogs/dialog-utils'; import EquipmentSearchDialog from 'components/dialogs/equipment-search-dialog'; @@ -41,7 +47,6 @@ import VoltageLevelCreationForm from './voltage-level-creation-form'; import { controlCouplingOmnibusBetweenSections } from '../voltage-level-creation-utils'; import { EQUIPMENT_TYPES } from 'components/utils/equipment-types'; import { useIntl } from 'react-intl'; -import { kiloUnitToUnit, unitToKiloUnit } from 'utils/unit-converter'; import { FORM_LOADING_DELAY } from 'components/network/constants'; import { useOpenShortWaitFetching } from '../../../commons/handle-modification-form'; import { createVoltageLevel } from '../../../../../services/study/network-modifications'; @@ -159,10 +164,12 @@ const VoltageLevelCreationDialog = ({ [NOMINAL_V]: voltageLevel[NOMINAL_V], [LOW_VOLTAGE_LIMIT]: voltageLevel[LOW_VOLTAGE_LIMIT], [HIGH_VOLTAGE_LIMIT]: voltageLevel[HIGH_VOLTAGE_LIMIT], - [LOW_SHORT_CIRCUIT_CURRENT_LIMIT]: unitToKiloUnit( + [LOW_SHORT_CIRCUIT_CURRENT_LIMIT]: convertInputValue( + FieldType.LOW_SHORT_CIRCUIT_CURRENT_LIMIT, fromCopy ? voltageLevel.identifiableShortCircuit?.ipMin : voltageLevel.ipMin ), - [HIGH_SHORT_CIRCUIT_CURRENT_LIMIT]: unitToKiloUnit( + [HIGH_SHORT_CIRCUIT_CURRENT_LIMIT]: convertInputValue( + FieldType.HIGH_SHORT_CIRCUIT_CURRENT_LIMIT, fromCopy ? voltageLevel.identifiableShortCircuit?.ipMax : voltageLevel.ipMax ), [BUS_BAR_COUNT]: voltageLevel[BUS_BAR_COUNT] ?? 1, @@ -215,8 +222,14 @@ const VoltageLevelCreationDialog = ({ nominalV: voltageLevel[NOMINAL_V], lowVoltageLimit: voltageLevel[LOW_VOLTAGE_LIMIT], highVoltageLimit: voltageLevel[HIGH_VOLTAGE_LIMIT], - ipMin: kiloUnitToUnit(voltageLevel[LOW_SHORT_CIRCUIT_CURRENT_LIMIT]), - ipMax: kiloUnitToUnit(voltageLevel[HIGH_SHORT_CIRCUIT_CURRENT_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) => { diff --git a/src/components/dialogs/network-modifications/voltage-level/modification/voltage-level-modification-dialog.jsx b/src/components/dialogs/network-modifications/voltage-level/modification/voltage-level-modification-dialog.jsx index cdbb0ab781..e1fc0cc3c9 100644 --- a/src/components/dialogs/network-modifications/voltage-level/modification/voltage-level-modification-dialog.jsx +++ b/src/components/dialogs/network-modifications/voltage-level/modification/voltage-level-modification-dialog.jsx @@ -21,10 +21,15 @@ import { } from 'components/utils/field-constants'; import yup from 'components/utils/yup-config'; import { yupResolver } from '@hookform/resolvers/yup'; -import { CustomFormProvider, useSnackMessage } from '@gridsuite/commons-ui'; +import { + convertInputValue, + convertOutputValue, + CustomFormProvider, + FieldType, + useSnackMessage, +} from '@gridsuite/commons-ui'; import { useOpenShortWaitFetching } from '../../../commons/handle-modification-form'; import { FORM_LOADING_DELAY } from 'components/network/constants'; -import { kiloUnitToUnit, unitToKiloUnit } from 'utils/unit-converter'; import { EQUIPMENT_INFOS_TYPES, EQUIPMENT_TYPES } from 'components/utils/equipment-types'; import { EquipmentIdSelector } from '../../../equipment-id/equipment-id-selector'; import { modifyVoltageLevel } from '../../../../../services/study/network-modifications'; @@ -105,8 +110,10 @@ const VoltageLevelModificationDialog = ({ [NOMINAL_V]: editData?.nominalV?.value ?? null, [LOW_VOLTAGE_LIMIT]: editData?.lowVoltageLimit?.value ?? null, [HIGH_VOLTAGE_LIMIT]: editData?.highVoltageLimit?.value ?? null, - [LOW_SHORT_CIRCUIT_CURRENT_LIMIT]: unitToKiloUnit(editData?.ipMin?.value) ?? null, - [HIGH_SHORT_CIRCUIT_CURRENT_LIMIT]: unitToKiloUnit(editData?.ipMax?.value) ?? null, + [LOW_SHORT_CIRCUIT_CURRENT_LIMIT]: + convertInputValue(FieldType.LOW_SHORT_CIRCUIT_CURRENT_LIMIT, editData?.ipMin?.value) ?? null, + [HIGH_SHORT_CIRCUIT_CURRENT_LIMIT]: + convertInputValue(FieldType.HIGH_SHORT_CIRCUIT_CURRENT_LIMIT, editData?.ipMax?.value) ?? null, ...getPropertiesFromModification(editData.properties), }); } @@ -128,10 +135,12 @@ const VoltageLevelModificationDialog = ({ if (voltageLevel) { //We convert values of low short circuit current limit and high short circuit current limit from A to KA if (voltageLevel.identifiableShortCircuit) { - voltageLevel.identifiableShortCircuit.ipMax = unitToKiloUnit( + voltageLevel.identifiableShortCircuit.ipMax = convertInputValue( + FieldType.HIGH_SHORT_CIRCUIT_CURRENT_LIMIT, voltageLevel.identifiableShortCircuit?.ipMax ); - voltageLevel.identifiableShortCircuit.ipMin = unitToKiloUnit( + voltageLevel.identifiableShortCircuit.ipMin = convertInputValue( + FieldType.LOW_SHORT_CIRCUIT_CURRENT_LIMIT, voltageLevel.identifiableShortCircuit?.ipMin ); } @@ -176,8 +185,14 @@ const VoltageLevelModificationDialog = ({ nominalV: voltageLevel[NOMINAL_V], lowVoltageLimit: voltageLevel[LOW_VOLTAGE_LIMIT], highVoltageLimit: voltageLevel[HIGH_VOLTAGE_LIMIT], - lowShortCircuitCurrentLimit: kiloUnitToUnit(voltageLevel[LOW_SHORT_CIRCUIT_CURRENT_LIMIT]), - highShortCircuitCurrentLimit: kiloUnitToUnit(voltageLevel[HIGH_SHORT_CIRCUIT_CURRENT_LIMIT]), + lowShortCircuitCurrentLimit: convertOutputValue( + FieldType.LOW_SHORT_CIRCUIT_CURRENT_LIMIT, + voltageLevel[LOW_SHORT_CIRCUIT_CURRENT_LIMIT] + ), + highShortCircuitCurrentLimit: convertOutputValue( + FieldType.HIGH_SHORT_CIRCUIT_CURRENT_LIMIT, + voltageLevel[HIGH_SHORT_CIRCUIT_CURRENT_LIMIT] + ), properties: toModificationProperties(voltageLevel), }).catch((error) => { snackError({ diff --git a/src/components/results/shortcircuit/shortcircuit-analysis-result-content.ts b/src/components/results/shortcircuit/shortcircuit-analysis-result-content.ts index c20c883b50..0b944cd7e9 100644 --- a/src/components/results/shortcircuit/shortcircuit-analysis-result-content.ts +++ b/src/components/results/shortcircuit/shortcircuit-analysis-result-content.ts @@ -8,7 +8,7 @@ import { ALL_BUSES, ONE_BUS } from 'utils/store-sort-filter-fields'; import { ShortCircuitAnalysisType } from './shortcircuit-analysis-result.type'; import { FilterSelectorType } from '../../custom-aggrid/custom-aggrid-header.type'; -import { kiloUnitToUnit } from '../../../utils/unit-converter'; +import { kiloUnitToUnit } from '@gridsuite/commons-ui'; export const PAGE_OPTIONS = [25, 100, 500, 1000]; @@ -57,8 +57,8 @@ export const convertFilterValues = (filterSelector: FilterSelectorType[]) => { case 'limitMax': return { ...filter, - value: kiloUnitToUnit(filter.value), - tolerance: kiloUnitToUnit(filter.tolerance), + value: kiloUnitToUnit(Number(filter.value)), + tolerance: kiloUnitToUnit(Number(filter.tolerance)), }; default: return filter; diff --git a/src/components/results/shortcircuit/shortcircuit-analysis-result-table.tsx b/src/components/results/shortcircuit/shortcircuit-analysis-result-table.tsx index b7ca08ca6d..8b2b7e6054 100644 --- a/src/components/results/shortcircuit/shortcircuit-analysis-result-table.tsx +++ b/src/components/results/shortcircuit/shortcircuit-analysis-result-table.tsx @@ -24,8 +24,7 @@ import { FilterParams, } from '../../custom-aggrid/custom-aggrid-header.type'; import { makeAgGridCustomHeaderColumn } from '../../custom-aggrid/custom-aggrid-header-utils'; -import { unitToKiloUnit } from '../../../utils/unit-converter'; -import { CustomAGGrid } from '@gridsuite/commons-ui'; +import { CustomAGGrid, unitToKiloUnit } from '@gridsuite/commons-ui'; import { convertSide } from '../loadflow/load-flow-result-utils'; import { CustomAggridComparatorFilter } from '../../custom-aggrid/custom-aggrid-filters/custom-aggrid-comparator-filter'; import { CustomAggridAutocompleteFilter } from '../../custom-aggrid/custom-aggrid-filters/custom-aggrid-autocomplete-filter'; diff --git a/src/components/spreadsheet/config/equipment/line.ts b/src/components/spreadsheet/config/equipment/line.ts index 6585d2dfdc..ea6495c290 100644 --- a/src/components/spreadsheet/config/equipment/line.ts +++ b/src/components/spreadsheet/config/equipment/line.ts @@ -19,8 +19,8 @@ import { typeAndFetchers, } from './common-config'; import { MEDIUM_COLUMN_WIDTH } from '../../utils/constants'; -import { unitToMicroUnit } from '../../../../utils/unit-converter'; import { genericColumnOfProperties } from '../common/column-properties'; +import { convertInputValue, FieldType } from '@gridsuite/commons-ui'; export const LINE_TAB_DEF = { index: 2, @@ -134,7 +134,7 @@ export const LINE_TAB_DEF = { numeric: true, ...defaultNumericFilterConfig, fractionDigits: 1, - valueGetter: (params) => unitToMicroUnit(params.data.g1), + valueGetter: (params) => convertInputValue(FieldType.G1, params.data.g1), getQuickFilterText: excludeFromGlobalFilter, }, { @@ -143,7 +143,7 @@ export const LINE_TAB_DEF = { numeric: true, ...defaultNumericFilterConfig, fractionDigits: 1, - valueGetter: (params) => unitToMicroUnit(params.data.g2), + valueGetter: (params) => convertInputValue(FieldType.G2, params.data.g2), getQuickFilterText: excludeFromGlobalFilter, }, { @@ -152,7 +152,7 @@ export const LINE_TAB_DEF = { numeric: true, ...defaultNumericFilterConfig, fractionDigits: 1, - valueGetter: (params) => unitToMicroUnit(params.data.b1), + valueGetter: (params) => convertInputValue(FieldType.B1, params.data.b1), getQuickFilterText: excludeFromGlobalFilter, }, { @@ -161,7 +161,7 @@ export const LINE_TAB_DEF = { numeric: true, ...defaultNumericFilterConfig, fractionDigits: 1, - valueGetter: (params) => unitToMicroUnit(params.data.b2), + valueGetter: (params) => convertInputValue(FieldType.B2, params.data.b2), getQuickFilterText: excludeFromGlobalFilter, }, { diff --git a/src/components/spreadsheet/config/equipment/tie-line.ts b/src/components/spreadsheet/config/equipment/tie-line.ts index 08e6cbe1f0..dc3182606e 100644 --- a/src/components/spreadsheet/config/equipment/tie-line.ts +++ b/src/components/spreadsheet/config/equipment/tie-line.ts @@ -19,8 +19,8 @@ import { typeAndFetchers, } from './common-config'; import { MEDIUM_COLUMN_WIDTH } from '../../utils/constants'; -import { unitToMicroUnit } from '../../../../utils/unit-converter'; import { genericColumnOfPropertiesReadonly } from '../common/column-properties'; +import { convertInputValue, FieldType } from '@gridsuite/commons-ui'; export const TIE_LINE_TAB_DEF = { index: 15, @@ -134,7 +134,7 @@ export const TIE_LINE_TAB_DEF = { numeric: true, ...defaultNumericFilterConfig, fractionDigits: 1, - valueGetter: (params) => unitToMicroUnit(params.data.g1), + valueGetter: (params) => convertInputValue(FieldType.G1, params.data.g1), getQuickFilterText: excludeFromGlobalFilter, }, { @@ -143,7 +143,7 @@ export const TIE_LINE_TAB_DEF = { numeric: true, ...defaultNumericFilterConfig, fractionDigits: 1, - valueGetter: (params) => unitToMicroUnit(params.data.g2), + valueGetter: (params) => convertInputValue(FieldType.G2, params.data.g2), getQuickFilterText: excludeFromGlobalFilter, }, { @@ -152,7 +152,7 @@ export const TIE_LINE_TAB_DEF = { numeric: true, ...defaultNumericFilterConfig, fractionDigits: 1, - valueGetter: (params) => unitToMicroUnit(params.data.b1), + valueGetter: (params) => convertInputValue(FieldType.B1, params.data.b1), getQuickFilterText: excludeFromGlobalFilter, }, { @@ -161,7 +161,7 @@ export const TIE_LINE_TAB_DEF = { numeric: true, ...defaultNumericFilterConfig, fractionDigits: 1, - valueGetter: (params) => unitToMicroUnit(params.data.b2), + valueGetter: (params) => convertInputValue(FieldType.B2, params.data.b2), getQuickFilterText: excludeFromGlobalFilter, }, { diff --git a/src/components/spreadsheet/config/equipment/two-windings-transformer.ts b/src/components/spreadsheet/config/equipment/two-windings-transformer.ts index 83e8ba90ae..d18c9d7701 100644 --- a/src/components/spreadsheet/config/equipment/two-windings-transformer.ts +++ b/src/components/spreadsheet/config/equipment/two-windings-transformer.ts @@ -29,7 +29,6 @@ import { import { MEDIUM_COLUMN_WIDTH } from '../../utils/constants'; import { PHASE_REGULATION_MODES, RATIO_REGULATION_MODES, REGULATION_TYPES, SIDE } from '../../../network/constants'; import { computeHighTapPosition, getTapChangerRegulationTerminalValue } from '../../../utils/utils'; -import { unitToMicroUnit } from '../../../../utils/unit-converter'; import { getComputedRegulationMode } from '../../../dialogs/network-modifications/two-windings-transformer/tap-changer-pane/ratio-tap-changer-pane/ratio-tap-changer-pane-utils'; import { genericColumnOfPropertiesEditPopup } from '../common/column-properties'; import { @@ -39,6 +38,7 @@ import { numericalCellEditorConfig, standardSelectCellEditorConfig, } from '../common/cell-editors'; +import { convertInputValue, FieldType } from '@gridsuite/commons-ui'; function getTwtRatioRegulationModeId(twt: any) { //regulationMode is set by the user (in edit mode) @@ -600,7 +600,7 @@ export const TWO_WINDINGS_TRANSFORMER_TAB_DEF = { numeric: true, ...defaultNumericFilterConfig, fractionDigits: 1, - valueGetter: (params) => unitToMicroUnit(params.data.g), + valueGetter: (params) => convertInputValue(FieldType.G, params.data.g), getQuickFilterText: excludeFromGlobalFilter, }, { @@ -609,7 +609,7 @@ export const TWO_WINDINGS_TRANSFORMER_TAB_DEF = { numeric: true, ...defaultNumericFilterConfig, fractionDigits: 1, - valueGetter: (params) => unitToMicroUnit(params.data.b), + valueGetter: (params) => convertInputValue(FieldType.B, params.data.b), getQuickFilterText: excludeFromGlobalFilter, }, { diff --git a/src/components/spreadsheet/config/equipment/voltage-level.ts b/src/components/spreadsheet/config/equipment/voltage-level.ts index 9728d292e8..a933bc4a31 100644 --- a/src/components/spreadsheet/config/equipment/voltage-level.ts +++ b/src/components/spreadsheet/config/equipment/voltage-level.ts @@ -18,9 +18,9 @@ import { excludeFromGlobalFilter, typeAndFetchers, } from './common-config'; -import { kiloUnitToUnit, unitToKiloUnit } from '../../../../utils/unit-converter'; import { genericColumnOfPropertiesEditPopup } from '../common/column-properties'; import { numericalCellEditorConfig } from '../common/cell-editors'; +import { convertInputValue, convertOutputValue, FieldType } from '@gridsuite/commons-ui'; function generateEditableNumericColumnDefinition< TId extends string, @@ -91,12 +91,21 @@ export const VOLTAGE_LEVEL_TAB_DEF = { fractionDigits: 1, ...editableColumnConfig, numeric: true, - ...numericalCellEditorConfig((params) => unitToKiloUnit(params.data?.identifiableShortCircuit?.ipMin)), - valueGetter: (params) => unitToKiloUnit(params.data?.identifiableShortCircuit?.ipMin), + ...numericalCellEditorConfig((params) => + convertInputValue( + FieldType.LOW_SHORT_CIRCUIT_CURRENT_LIMIT, + params.data?.identifiableShortCircuit?.ipMin + ) + ), + valueGetter: (params) => + convertInputValue( + FieldType.LOW_SHORT_CIRCUIT_CURRENT_LIMIT, + params.data?.identifiableShortCircuit?.ipMin + ), valueSetter: (params) => { params.data.identifiableShortCircuit = { ...params.data.identifiableShortCircuit, - ipMin: kiloUnitToUnit(params.newValue), + ipMin: convertOutputValue(FieldType.LOW_SHORT_CIRCUIT_CURRENT_LIMIT, params.newValue), }; return true; }, @@ -112,12 +121,21 @@ export const VOLTAGE_LEVEL_TAB_DEF = { fractionDigits: 1, ...editableColumnConfig, numeric: true, - ...numericalCellEditorConfig((params) => unitToKiloUnit(params.data?.identifiableShortCircuit?.ipMax)), - valueGetter: (params) => unitToKiloUnit(params.data?.identifiableShortCircuit?.ipMax), + ...numericalCellEditorConfig((params) => + convertInputValue( + FieldType.HIGH_SHORT_CIRCUIT_CURRENT_LIMIT, + params.data?.identifiableShortCircuit?.ipMax + ) + ), + valueGetter: (params) => + convertInputValue( + FieldType.HIGH_SHORT_CIRCUIT_CURRENT_LIMIT, + params.data?.identifiableShortCircuit?.ipMax + ), valueSetter: (params) => { params.data.identifiableShortCircuit = { ...params.data.identifiableShortCircuit, - ipMax: kiloUnitToUnit(params.newValue), + ipMax: convertOutputValue(FieldType.HIGH_SHORT_CIRCUIT_CURRENT_LIMIT, params.newValue), }; return true; }, diff --git a/src/components/tooltips/equipment-popover.jsx b/src/components/tooltips/equipment-popover.jsx index 65df5187c6..c040d9c242 100644 --- a/src/components/tooltips/equipment-popover.jsx +++ b/src/components/tooltips/equipment-popover.jsx @@ -16,8 +16,7 @@ import { RunningStatus } from '../utils/running-status'; import { EQUIPMENT_INFOS_TYPES, EQUIPMENT_TYPES } from 'components/utils/equipment-types'; import { fetchNetworkElementInfos } from '../../services/study/network'; import { mergeSx } from '../utils/functions'; -import { unitToMicroUnit } from 'utils/unit-converter'; -import { useDebounce } from '@gridsuite/commons-ui'; +import { convertInputValue, FieldType, useDebounce } from '@gridsuite/commons-ui'; const styles = { tableCells: { @@ -220,12 +219,12 @@ const EquipmentPopover = ({ studyUuid, anchorEl, anchorPosition, equipmentId, eq }; const renderVoltageLevelCharacteristics = (equipmentInfo, equipmentType) => { - const renderShuntSusceptanceRow = (voltageLevelId, susceptanceValue) => ( + const renderShuntSusceptanceRow = (voltageLevelId, susceptanceValue, fieldType) => ( {renderTableCell({ value: voltageLevelId, isLabel: false })} {renderTableCell({ label: 'shuntSusceptance', isLabel: true })} {renderTableCell({ - value: unitToMicroUnit(susceptanceValue)?.toFixed(2), + value: convertInputValue(fieldType, susceptanceValue)?.toFixed(2), isLabel: false, })} @@ -234,11 +233,11 @@ const EquipmentPopover = ({ studyUuid, anchorEl, anchorPosition, equipmentId, eq return ( <> {equipmentType === EQUIPMENT_TYPES.TWO_WINDINGS_TRANSFORMER ? ( - renderShuntSusceptanceRow(equipmentInfo.voltageLevelId2, equipmentInfo?.b) + renderShuntSusceptanceRow(equipmentInfo.voltageLevelId2, equipmentInfo?.b, FieldType.B) ) : ( <> - {renderShuntSusceptanceRow(equipmentInfo.voltageLevelId1, equipmentInfo.b1)} - {renderShuntSusceptanceRow(equipmentInfo.voltageLevelId2, equipmentInfo?.b2)} + {renderShuntSusceptanceRow(equipmentInfo.voltageLevelId1, equipmentInfo.b1, FieldType.B1)} + {renderShuntSusceptanceRow(equipmentInfo.voltageLevelId2, equipmentInfo?.b2, FieldType.B2)} )} diff --git a/src/components/utils/field-constants.ts b/src/components/utils/field-constants.ts index 8bf2123b68..1257e9b8e7 100644 --- a/src/components/utils/field-constants.ts +++ b/src/components/utils/field-constants.ts @@ -385,4 +385,6 @@ export const MAX_S_AUTOMATON = 'maxSAutomaton'; export const STAND_BY_AUTOMATON = 'StandbyAutomaton'; export const FILTERS_SHUNT_COMPENSATOR_TABLE = 'shuntCompensatorInfos'; export const MICRO_SIEMENS = '(µS)'; +export const SIEMENS = '(S)'; export const KILO_AMPERE = '(kA)'; +export const MEGA_VAR = '(MVar)'; diff --git a/src/hooks/use-format-label-with-unit.ts b/src/hooks/use-format-label-with-unit.ts new file mode 100644 index 0000000000..00ec3d8a2d --- /dev/null +++ b/src/hooks/use-format-label-with-unit.ts @@ -0,0 +1,21 @@ +/** + * Copyright (c) 2025, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { useMemo } from 'react'; +import { useIntl } from 'react-intl'; + +export default function useFormatLabelWithUnit() { + const intl = useIntl(); + return useMemo(() => { + return (value: string | { label: string; unit?: string }) => { + if (typeof value === 'string') { + return value; + } + return `${intl.formatMessage({ id: value.label })} ${value.unit ?? ''}`; + }; + }, [intl]); +} diff --git a/src/utils/unit-converter.ts b/src/utils/unit-converter.ts deleted file mode 100644 index bd031f68e9..0000000000 --- a/src/utils/unit-converter.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Copyright (c) 2024, RTE (http://www.rte-france.com) - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -import { isBlankOrEmpty } from '../components/utils/validation-functions'; -import { roundToDefaultPrecision } from './rounding'; - -export const unitToMicroUnit = (num: any) => (isBlankOrEmpty(num) ? undefined : roundToDefaultPrecision(num * 1e6)); -export const microUnitToUnit = (num: any) => (isBlankOrEmpty(num) ? undefined : roundToDefaultPrecision(num / 1e6)); -export const kiloUnitToUnit = (num: any) => (isBlankOrEmpty(num) ? undefined : roundToDefaultPrecision(num * 1e3)); -export const unitToKiloUnit = (num: any) => (isBlankOrEmpty(num) ? undefined : roundToDefaultPrecision(num / 1e3));