diff --git a/src/components/dialogs/commons/criteria-based/criteria-based-form.js b/src/components/dialogs/commons/criteria-based/criteria-based-form.js index 5a2fdacc0..731d7a770 100644 --- a/src/components/dialogs/commons/criteria-based/criteria-based-form.js +++ b/src/components/dialogs/commons/criteria-based/criteria-based-form.js @@ -42,6 +42,7 @@ const CriteriaBasedForm = ({ equipments, defaultValues }) => { shouldOpenPopup={openConfirmationPopup} resetOnConfirmation={handleResetOnConfirmation} message={'changeTypeMessage'} + validateButtonLabel={'button.changeType'} /> ); diff --git a/src/components/dialogs/delete-dialog.js b/src/components/dialogs/delete-dialog.js index 9770e2d1f..58c1c2331 100644 --- a/src/components/dialogs/delete-dialog.js +++ b/src/components/dialogs/delete-dialog.js @@ -82,7 +82,6 @@ const DeleteDialog = ({ itemName: ( ), diff --git a/src/components/dialogs/filter/expert/expert-filter-constants.ts b/src/components/dialogs/filter/expert/expert-filter-constants.ts index 5f13d2ee7..f7c0da1b6 100644 --- a/src/components/dialogs/filter/expert/expert-filter-constants.ts +++ b/src/components/dialogs/filter/expert/expert-filter-constants.ts @@ -38,6 +38,10 @@ export const EXPERT_FILTER_EQUIPMENTS = { id: 'SHUNT_COMPENSATOR', label: 'ShuntCompensators', }, + LINE: { + id: 'LINE', + label: 'Lines', + }, }; export const ENERGY_SOURCE_OPTIONS = [ @@ -292,6 +296,90 @@ export const FIELDS_OPTIONS = { dataType: DataType.NUMBER, inputType: 'number', }, + CONNECTED_1: { + name: FieldType.CONNECTED_1, + label: 'terminal1Connected', + dataType: DataType.BOOLEAN, + valueEditorType: 'switch', + }, + CONNECTED_2: { + name: FieldType.CONNECTED_2, + label: 'terminal2Connected', + dataType: DataType.BOOLEAN, + valueEditorType: 'switch', + }, + VOLTAGE_LEVEL_ID_1: { + name: FieldType.VOLTAGE_LEVEL_ID_1, + label: 'voltageLevelId1', + dataType: DataType.STRING, + }, + VOLTAGE_LEVEL_ID_2: { + name: FieldType.VOLTAGE_LEVEL_ID_2, + label: 'voltageLevelId2', + dataType: DataType.STRING, + }, + NOMINAL_VOLTAGE_1: { + name: FieldType.NOMINAL_VOLTAGE_1, + label: 'nominalVoltage1Or', + dataType: DataType.NUMBER, + inputType: 'number', + }, + NOMINAL_VOLTAGE_2: { + name: FieldType.NOMINAL_VOLTAGE_2, + label: 'nominalVoltage2Ex', + dataType: DataType.NUMBER, + inputType: 'number', + }, + COUNTRY_1: { + name: FieldType.COUNTRY_1, + label: 'country1', + dataType: DataType.ENUM, + valueEditorType: 'select', + defaultValue: 'AF', + }, + COUNTRY_2: { + name: FieldType.COUNTRY_2, + label: 'country2', + dataType: DataType.ENUM, + valueEditorType: 'select', + defaultValue: 'AF', + }, + SERIE_RESISTANCE: { + name: FieldType.SERIE_RESISTANCE, + label: 'seriesResistance', + dataType: DataType.NUMBER, + inputType: 'number', + }, + SERIE_REACTANCE: { + name: FieldType.SERIE_REACTANCE, + label: 'seriesReactance', + dataType: DataType.NUMBER, + inputType: 'number', + }, + SHUNT_CONDUCTANCE_1: { + name: FieldType.SHUNT_CONDUCTANCE_1, + label: 'shuntConductance1', + dataType: DataType.NUMBER, + inputType: 'number', + }, + SHUNT_CONDUCTANCE_2: { + name: FieldType.SHUNT_CONDUCTANCE_2, + label: 'shuntConductance2', + dataType: DataType.NUMBER, + inputType: 'number', + }, + SHUNT_SUSCEPTANCE_1: { + name: FieldType.SHUNT_SUSCEPTANCE_1, + label: 'shuntSusceptance1', + dataType: DataType.NUMBER, + inputType: 'number', + }, + SHUNT_SUSCEPTANCE_2: { + name: FieldType.SHUNT_SUSCEPTANCE_2, + label: 'shuntSusceptance2', + dataType: DataType.NUMBER, + inputType: 'number', + }, }; export const fields: Record = { @@ -323,6 +411,7 @@ export const fields: Record = { FIELDS_OPTIONS.COUNTRY, FIELDS_OPTIONS.P0, FIELDS_OPTIONS.Q0, + FIELDS_OPTIONS.CONNECTED, ], SHUNT_COMPENSATOR: [ FIELDS_OPTIONS.ID, @@ -364,4 +453,22 @@ export const fields: Record = { FIELDS_OPTIONS.NAME, FIELDS_OPTIONS.COUNTRY, ], + LINE: [ + FIELDS_OPTIONS.ID, + FIELDS_OPTIONS.NAME, + FIELDS_OPTIONS.CONNECTED_1, + FIELDS_OPTIONS.CONNECTED_2, + FIELDS_OPTIONS.VOLTAGE_LEVEL_ID_1, + FIELDS_OPTIONS.VOLTAGE_LEVEL_ID_2, + FIELDS_OPTIONS.NOMINAL_VOLTAGE_1, + FIELDS_OPTIONS.NOMINAL_VOLTAGE_2, + FIELDS_OPTIONS.COUNTRY_1, + FIELDS_OPTIONS.COUNTRY_2, + FIELDS_OPTIONS.SERIE_RESISTANCE, + FIELDS_OPTIONS.SERIE_REACTANCE, + FIELDS_OPTIONS.SHUNT_CONDUCTANCE_1, + FIELDS_OPTIONS.SHUNT_CONDUCTANCE_2, + FIELDS_OPTIONS.SHUNT_SUSCEPTANCE_1, + FIELDS_OPTIONS.SHUNT_SUSCEPTANCE_2, + ], }; diff --git a/src/components/dialogs/filter/expert/expert-filter-form.tsx b/src/components/dialogs/filter/expert/expert-filter-form.tsx index 0b4b0cf8b..a99c1fa97 100644 --- a/src/components/dialogs/filter/expert/expert-filter-form.tsx +++ b/src/components/dialogs/filter/expert/expert-filter-form.tsx @@ -138,6 +138,7 @@ function ExpertFilterForm() { shouldOpenPopup={openConfirmationPopup} resetOnConfirmation={handleResetOnConfirmation} message={'changeTypeMessage'} + validateButtonLabel={'button.changeType'} /> {watchEquipmentType && diff --git a/src/components/dialogs/filter/expert/expert-filter-utils.ts b/src/components/dialogs/filter/expert/expert-filter-utils.ts index 383184ca0..b483f7857 100644 --- a/src/components/dialogs/filter/expert/expert-filter-utils.ts +++ b/src/components/dialogs/filter/expert/expert-filter-utils.ts @@ -32,10 +32,18 @@ import { RuleGroupTypeExport, RuleTypeExport, } from './expert-filter.type'; +import { microUnitToUnit, unitToMicroUnit } from 'utils/conversion-utils'; type CustomRuleType = RuleType & { dataType: DataType }; type CustomRuleGroupType = RuleGroupType & { dataType: DataType }; +const microUnits = [ + FieldType.SHUNT_CONDUCTANCE_1, + FieldType.SHUNT_CONDUCTANCE_2, + FieldType.SHUNT_SUSCEPTANCE_1, + FieldType.SHUNT_SUSCEPTANCE_2, +]; + const getDataType = (fieldName: string) => { const field = Object.values(FIELDS_OPTIONS).find( (field) => field.name === fieldName @@ -93,6 +101,17 @@ export const getOperators = (fieldName: string, intl: IntlShape) => { return defaultOperators; }; +function changeValueUnit(value: any, field: FieldType) { + if (microUnits.includes(field)) { + if (!Array.isArray(value)) { + return microUnitToUnit(value); + } else { + return value.map((a: number) => microUnitToUnit(a)); + } + } + return value; +} + export function exportExpertRules( query: CustomRuleGroupType ): RuleGroupTypeExport { @@ -105,9 +124,11 @@ export function exportExpertRules( )?.customName as OperatorType, value: !isValueAnArray && rule.operator !== OperatorType.EXISTS - ? rule.value + ? changeValueUnit(rule.value, rule.field as FieldType) : undefined, - values: isValueAnArray ? rule.value : undefined, + values: isValueAnArray + ? changeValueUnit(rule.value, rule.field as FieldType) + : undefined, dataType: getDataType(rule.field) as DataType, }; } @@ -141,12 +162,19 @@ export function importExpertRules( if (rule.dataType === DataType.NUMBER) { return rule.values .map((value) => parseFloat(value as string)) + .map((numberValue) => { + return microUnits.includes(rule.field) + ? unitToMicroUnit(numberValue)! + : numberValue; + }) .sort((a, b) => a - b); } else { return rule.values.sort(); } } else { - return rule.value; + return microUnits.includes(rule.field) + ? unitToMicroUnit(parseFloat(rule.value as string)) + : rule.value; } } diff --git a/src/components/dialogs/filter/expert/expert-filter.type.ts b/src/components/dialogs/filter/expert/expert-filter.type.ts index 932727386..4eb4d4502 100644 --- a/src/components/dialogs/filter/expert/expert-filter.type.ts +++ b/src/components/dialogs/filter/expert/expert-filter.type.ts @@ -56,6 +56,20 @@ export enum FieldType { SWITCHED_ON_Q_AT_NOMINAL_V = 'SWITCHED_ON_Q_AT_NOMINAL_V', MAX_SUSCEPTANCE = 'MAX_SUSCEPTANCE', SWITCHED_ON_SUSCEPTANCE = 'SWITCHED_ON_SUSCEPTANCE', + CONNECTED_1 = 'CONNECTED_1', + CONNECTED_2 = 'CONNECTED_2', + VOLTAGE_LEVEL_ID_1 = 'VOLTAGE_LEVEL_ID_1', + VOLTAGE_LEVEL_ID_2 = 'VOLTAGE_LEVEL_ID_2', + NOMINAL_VOLTAGE_1 = 'NOMINAL_VOLTAGE_1', + NOMINAL_VOLTAGE_2 = 'NOMINAL_VOLTAGE_2', + COUNTRY_1 = 'COUNTRY_1', + COUNTRY_2 = 'COUNTRY_2', + SERIE_RESISTANCE = 'SERIE_RESISTANCE', + SERIE_REACTANCE = 'SERIE_REACTANCE', + SHUNT_CONDUCTANCE_1 = 'SHUNT_CONDUCTANCE_1', + SHUNT_CONDUCTANCE_2 = 'SHUNT_CONDUCTANCE_2', + SHUNT_SUSCEPTANCE_1 = 'SHUNT_SUSCEPTANCE_1', + SHUNT_SUSCEPTANCE_2 = 'SHUNT_SUSCEPTANCE_2', } export enum DataType { diff --git a/src/components/dialogs/filter/explicit-naming/explicit-naming-filter-form.tsx b/src/components/dialogs/filter/explicit-naming/explicit-naming-filter-form.tsx index 4eb18a3cb..92cab306a 100644 --- a/src/components/dialogs/filter/explicit-naming/explicit-naming-filter-form.tsx +++ b/src/components/dialogs/filter/explicit-naming/explicit-naming-filter-form.tsx @@ -185,6 +185,7 @@ function ExplicitNamingFilterForm() { shouldOpenPopup={openConfirmationPopup} resetOnConfirmation={handleResetOnConfirmation} message={'changeTypeMessage'} + validateButtonLabel={'button.changeType'} /> {watchEquipmentType && ( diff --git a/src/components/dialogs/replace-with-script-dialog.js b/src/components/dialogs/replace-with-script-dialog.js index 251c3dbd4..04d7ae6a4 100644 --- a/src/components/dialogs/replace-with-script-dialog.js +++ b/src/components/dialogs/replace-with-script-dialog.js @@ -51,7 +51,7 @@ const ReplaceWithScriptDialog = ({ id, open, onClose, onClick, title }) => { diff --git a/src/components/utils/popup-confirmation-dialog.js b/src/components/utils/popup-confirmation-dialog.js index b97ca56de..238321972 100644 --- a/src/components/utils/popup-confirmation-dialog.js +++ b/src/components/utils/popup-confirmation-dialog.js @@ -17,6 +17,7 @@ import { CancelButton } from '@gridsuite/commons-ui'; const PopupConfirmationDialog = ({ message, + validateButtonLabel, openConfirmationPopup, setOpenConfirmationPopup, handlePopupConfirmation, @@ -37,11 +38,15 @@ const PopupConfirmationDialog = ({ setOpenConfirmationPopup(false)} /> ); }; +PopupConfirmationDialog.defaultProps = { + validateButtonLabel: undefined, +}; + export default PopupConfirmationDialog; diff --git a/src/components/utils/rhf-inputs/select-inputs/input-with-popup-confirmation.js b/src/components/utils/rhf-inputs/select-inputs/input-with-popup-confirmation.js index 7dd3b20ab..904d88bcb 100644 --- a/src/components/utils/rhf-inputs/select-inputs/input-with-popup-confirmation.js +++ b/src/components/utils/rhf-inputs/select-inputs/input-with-popup-confirmation.js @@ -8,6 +8,7 @@ const InputWithPopupConfirmation = ({ shouldOpenPopup, // condition to open popup confirmation resetOnConfirmation, // function to reset values in your form on confirmation, message, + validateButtonLabel, ...props }) => { const [newValue, setNewValue] = useState(null); @@ -47,9 +48,14 @@ const InputWithPopupConfirmation = ({ openConfirmationPopup={openPopup} setOpenConfirmationPopup={setOpenPopup} handlePopupConfirmation={handlePopupConfirmation} + validateButtonLabel={validateButtonLabel} /> ); }; +InputWithPopupConfirmation.defaultProps = { + validateButtonLabel: undefined, +}; + export default InputWithPopupConfirmation; diff --git a/src/components/utils/rqb-inputs/combinator-selector.tsx b/src/components/utils/rqb-inputs/combinator-selector.tsx index 742a819d9..999a361c6 100644 --- a/src/components/utils/rqb-inputs/combinator-selector.tsx +++ b/src/components/utils/rqb-inputs/combinator-selector.tsx @@ -23,6 +23,7 @@ const CombinatorSelector = (props: CombinatorSelectorProps) => { <> { // No value needed for this operator return null; } - if (props.field === FieldType.COUNTRY) { + if ( + [FieldType.COUNTRY, FieldType.COUNTRY_1, FieldType.COUNTRY_2].includes( + props.field as FieldType + ) + ) { return ; } if ( diff --git a/src/translations/en.json b/src/translations/en.json index 58801b614..0fa372bad 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1,4 +1,7 @@ { + "button.replace": "Replace", + "button.changeType": "Change", + "button.changeOperator": "Change", "close": "Close", "parameters": "Parameters", "paramsChangingError": "An error occured when changing the parameters", @@ -63,11 +66,11 @@ "confirmDirectoryDialog": "Confirm", "insertNewDirectoryDialogTitle": "Create folder", "insertNewRootDirectoryDialogTitle": "Create root folder", - "deleteDirectoryDialogMessage": "Are you sure you want to delete the {itemName} folder and the items it contains ?", - "deleteMultipleDirectoriesDialogMessage": "Are you sure you want to delete those {itemsCount} folders and the items they contains ?", - "deleteItemDialogMessage": "Are you sure you want to delete {itemName} ?", - "deleteMultipleItemsDialogMessage": "Are you sure you want to delete those {itemsCount} items ?", - "deleteItemDialogTitle": "Delete {itemName}", + "deleteDirectoryDialogMessage": "The {itemName} folder and the items it contains will be deleted.", + "deleteMultipleDirectoriesDialogMessage": "{itemsCount} folders and the items they contain will be deleted.", + "deleteItemDialogMessage": "{itemName} will be deleted.", + "deleteMultipleItemsDialogMessage": "{itemsCount} items will be deleted.", + "deleteItemDialogTitle": "Delete\u00a0{itemName}", "deleteMultipleItemsDialogTitle": "Delete {itemsCount} items", "renameDirectoryDialogTitle": "Rename the folder", "accessRights": "Access rights", @@ -110,7 +113,7 @@ "equipmentID": "Equipment ID", "equipments": "Equipments", "nominalVoltage": "Nominal voltage", - "alertBeforeReplaceWithScript": "Do you really want to replace this list with a Groovy script ?{br}{br}This action cannot be reversed", + "alertBeforeReplaceWithScript": "This list will be replaced by a Groovy script.{br}This action is irreversible.", "replaceList": "Replace list", "copyToScriptList": "Copy to script", "copyToScript": "Copy to script", @@ -153,6 +156,20 @@ "nominalVoltage1": "Nominal Voltage 1", "nominalVoltage2": "Nominal Voltage 2", "nominalVoltage3": "Nominal Voltage 3", + "nominalVoltage1Or": "Nominal Voltage 1", + "nominalVoltage2Ex": "Nominal Voltage 2", + "voltageLevelId1": "Voltage level ID 1", + "voltageLevelId2": "Voltage level ID 2", + "terminal1Connected": "Connected 1", + "terminal2Connected": "Connected 2", + "country1": "Country 1", + "country2": "Country 2", + "seriesResistance": "Series resistance (Ω)", + "seriesReactance": "Series reactance (Ω)", + "shuntConductance1": "Shunt conductance 1 (μS)", + "shuntSusceptance1": "Shunt susceptance 1 (μS)", + "shuntConductance2": "Shunt conductance 2 (μS)", + "shuntSusceptance2": "Shunt susceptance 2 (μS)", "cannotRetrieveContingencyList": "Could not retrieve contingency list: ", "cannotRetrieveFilter": "Could not retrieve filter: ", "FreePropsCrit": "By properties filtering", @@ -186,8 +203,8 @@ "serverConnectionFailed": "Failed to connect to server. Please retry later.", "invalidFormatOrName": "Imported file name or format invalid", "parameterLoadingProblem": "problem of loading parameters", - "changeOperatorMessage": "Do you want to change the operator? The new operator will be applied to all the rules already created in the group.", - "changeTypeMessage": "Do you want to change the type? Previous configuration will be erased", + "changeOperatorMessage": "The operator will be changed and will be applied to all the rules already created in the group.", + "changeTypeMessage": "The type will be changed and previous configuration will be erased.", "keepCSVDataMessage": "Do you want to replace or add the new data to the current list ?", "add": "Add", "replace": "Replace", diff --git a/src/translations/fr.json b/src/translations/fr.json index c83ad4f28..d4bb2d736 100644 --- a/src/translations/fr.json +++ b/src/translations/fr.json @@ -1,4 +1,7 @@ { + "button.replace": "Remplacer", + "button.changeType": "Modifier", + "button.changeOperator": "Modifier", "close": "Fermer", "parameters": "Paramètres", "paramsChangingError": "Une erreur est survenue lors de la modification des paramètres", @@ -63,11 +66,11 @@ "renameFolder": "Renommer", "insertNewDirectoryDialogTitle": "Créer un dossier", "insertNewRootDirectoryDialogTitle": "Créer un dossier racine", - "deleteDirectoryDialogMessage": "Êtes-vous sûr(e) de vouloir supprimer le dossier {itemName} ainsi que les éléments qu'il contient ?", - "deleteMultipleDirectoriesDialogMessage": "Êtes-vous sûr(e) de vouloir supprimer ces dossiers ainsi que les éléments qu'ils contiennent ?", - "deleteItemDialogMessage": "Êtes-vous sûr(e) de vouloir supprimer {itemName} ?", - "deleteMultipleItemsDialogMessage": "Êtes-vous sûr(e) de vouloir supprimer ces {itemsCount} éléments ?", - "deleteItemDialogTitle": "Supprimer {itemName}", + "deleteDirectoryDialogMessage": "Le dossier {itemName} ainsi que les éléments qu'il contient va être supprimé.", + "deleteMultipleDirectoriesDialogMessage": "{itemsCount} dossiers ainsi que les éléments qu'ils contiennent vont être supprimés.", + "deleteItemDialogMessage": "{itemName} va être supprimé.", + "deleteMultipleItemsDialogMessage": "{itemsCount} éléments vont être supprimés.", + "deleteItemDialogTitle": "Supprimer\u00a0{itemName}", "deleteMultipleItemsDialogTitle": "Supprimer {itemsCount} éléments", "renameDirectoryDialogTitle": "Renommer le dossier", "accessRights": "Droits d'accès", @@ -110,7 +113,7 @@ "equipmentID": "ID d'ouvrage", "equipments": "Ouvrages", "nominalVoltage": "Tension nominale", - "alertBeforeReplaceWithScript": "Voulez-vous vraiment remplacer cette liste par un script Groovy ?{br}{br}Cette action est irréversible", + "alertBeforeReplaceWithScript": "Cette liste sera remplacée par un script Groovy.{br}Cette action est irréversible.", "replaceList": "Remplacer la liste", "copyToScriptList": "Copier vers script", "copyToScript": "Copier dans un script", @@ -153,6 +156,20 @@ "nominalVoltage1": "Tension nominale 1", "nominalVoltage2": "Tension nominale 2", "nominalVoltage3": "Tension nominale 3", + "nominalVoltage1Or": "Tension nominale Or", + "nominalVoltage2Ex": "Tension nominale Ex", + "voltageLevelId1": "ID Poste Or", + "voltageLevelId2": "ID Poste Ex", + "terminal1Connected": "Connecté Or", + "terminal2Connected": "Connecté Ex", + "country1": "Pays Or", + "country2": "Pays Ex", + "seriesResistance": "Résistance série (Ω)", + "seriesReactance": "Réactance série (Ω)", + "shuntConductance1": "Conductance parallèle Or (μS)", + "shuntSusceptance1": "Susceptance parallèle Or (μS)", + "shuntConductance2": "Conductance parallèle Ex (μS)", + "shuntSusceptance2": "Susceptance parallèle Ex (μS)", "cannotRetrieveContingencyList": "Erreur d'accès à la liste d'aléas : ", "cannotRetrieveFilter": "Erreur d'accès au filtre : ", "FreePropsCrit": "Filtrage par propriétés", @@ -186,8 +203,8 @@ "serverConnectionFailed": "Échec de connexion avec le serveur. Veuillez réessayer ultérieurement", "invalidFormatOrName": "Format ou nom du fichier importé non valide", "parameterLoadingProblem": "Problème de chargement des paramètres", - "changeOperatorMessage": "Voulez-vous changer l'opérateur ? Le nouvel opérateur s'appliquera sur toutes les règles déjà créées dans le groupe.", - "changeTypeMessage": "Voulez-vous changer le type ? La précédente configuration sera perdue", + "changeOperatorMessage": "L'opérateur sera modifié et s'appliquera sur toutes les règles déjà créées dans le groupe.", + "changeTypeMessage": "Le type sera modifié et la précédente configuration sera perdue.", "keepCSVDataMessage": "Voulez-vous remplacer la liste existante ou y ajouter les nouvelles données ?", "add": "Ajouter", "replace": "Remplacer", diff --git a/src/utils/conversion-utils.ts b/src/utils/conversion-utils.ts new file mode 100644 index 000000000..cb23fb97c --- /dev/null +++ b/src/utils/conversion-utils.ts @@ -0,0 +1,30 @@ +/** + * 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/. + */ + +export const GRIDSUITE_DEFAULT_PRECISION: number = 13; + +export const roundToPrecision = (num: number, precision: number) => + Number(num.toPrecision(precision)); + +export const roundToDefaultPrecision = (num: number) => + roundToPrecision(num, GRIDSUITE_DEFAULT_PRECISION); + +export function isBlankOrEmpty(value: unknown) { + if (value === undefined || value === null) { + return true; + } + if (typeof value === 'string') { + return /^\s*$/.test(value); + } + return false; +} + +export const unitToMicroUnit = (num: number) => + isBlankOrEmpty(num) ? undefined : roundToDefaultPrecision(num * 1e6); + +export const microUnitToUnit = (num: number) => + isBlankOrEmpty(num) ? undefined : roundToDefaultPrecision(num / 1e6);