From 05e38d1c488c191e922755dc2d4c03c990fcfa14 Mon Sep 17 00:00:00 2001 From: basseche Date: Thu, 5 Feb 2026 10:10:26 +0100 Subject: [PATCH 1/3] add check on planned active power set point Signed-off-by: basseche --- .../creation/generator-creation-dialog.tsx | 19 ++++++++++++++++++- src/translations/en.json | 1 + src/translations/fr.json | 1 + 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/components/dialogs/network-modifications/generator/creation/generator-creation-dialog.tsx b/src/components/dialogs/network-modifications/generator/creation/generator-creation-dialog.tsx index 415961f7b4..a5060a02e5 100644 --- a/src/components/dialogs/network-modifications/generator/creation/generator-creation-dialog.tsx +++ b/src/components/dialogs/network-modifications/generator/creation/generator-creation-dialog.tsx @@ -130,7 +130,24 @@ const formSchema = yup .required(), [RATED_NOMINAL_POWER]: yup.number().nullable().min(0, 'mustBeGreaterOrEqualToZero'), ...getShortCircuitFormSchema(), - [PLANNED_ACTIVE_POWER_SET_POINT]: yup.number().nullable(), + [PLANNED_ACTIVE_POWER_SET_POINT]: yup + .number() + .nullable() + .test( + 'activePowerSetPoint', + 'PlannedActivePowerSetPointMustBeBetweenMinAndMaxActivePower', + (value, context) => { + const minActivePower = context.parent[MINIMUM_ACTIVE_POWER]; + const maxActivePower = context.parent[MAXIMUM_ACTIVE_POWER]; + if (value === null || value === undefined) { + return true; + } + if (minActivePower === null || maxActivePower === null) { + return false; + } + return value >= minActivePower && value <= maxActivePower; + } + ), [MARGINAL_COST]: yup.number().nullable(), [PLANNED_OUTAGE_RATE]: yup.number().nullable().min(0, 'RealPercentage').max(1, 'RealPercentage'), [FORCED_OUTAGE_RATE]: yup.number().nullable().min(0, 'RealPercentage').max(1, 'RealPercentage'), diff --git a/src/translations/en.json b/src/translations/en.json index 979bacb615..a77db3f55c 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -749,6 +749,7 @@ "forcedOutageRate": "Forced outage rate", "MinActivePowerMustBeLessOrEqualToMaxActivePower": "Minimum active power value must be less than or equal to maximum active power value", "ActivePowerMustBeZeroOrBetweenMinAndMaxActivePower": "Active power value must be equal to 0 or between minimum and maximum active power values", + "PlannedActivePowerSetPointMustBeBetweenMinAndMaxActivePower": "Planned active power set point must be between minimum and maximum active power values", "RatedNominalPowerMustBeGreaterThanZero": "The rated nominal power value must be greater than 0", "NormalizedPercentage": "This percentage must be between 0 and 100", "RealPercentage": "This value must be between 0 and 1", diff --git a/src/translations/fr.json b/src/translations/fr.json index 1b998ad5bc..4876745c85 100644 --- a/src/translations/fr.json +++ b/src/translations/fr.json @@ -744,6 +744,7 @@ "forcedOutageRate": "Indisponibilité fortuite", "MinActivePowerMustBeLessOrEqualToMaxActivePower": "La valeur de la puissance active min doit être inférieure ou égale à la valeur de la puissance active max", "ActivePowerMustBeZeroOrBetweenMinAndMaxActivePower": "La valeur de la puissance active doit être égale à 0 ou comprise entre la valeur de la puissance active min et la valeur de la puissance active max", + "PlannedActivePowerSetPointMustBeBetweenMinAndMaxActivePower": "La valeur de la puissance imposée doit être comprise entre la valeur de la puissance active min et la valeur de la puissance active max", "RatedNominalPowerMustBeGreaterThanZero": "La valeur de la puissance nominale doit être supérieure à 0", "NormalizedPercentage": "Ce pourcentage doit être compris entre 0 et 100", "RealPercentage": "Cette valeur doit être comprise entre 0 et 1", From 2072d4341dc115e57804a00038b2f4bbec956bd7 Mon Sep 17 00:00:00 2001 From: basseche Date: Tue, 10 Feb 2026 15:33:04 +0100 Subject: [PATCH 2/3] Review Signed-off-by: basseche --- .../creation/generator-creation-dialog.tsx | 18 ++++------- .../dialogs/set-points/set-points-utils.ts | 32 ++++++++++++------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/components/dialogs/network-modifications/generator/creation/generator-creation-dialog.tsx b/src/components/dialogs/network-modifications/generator/creation/generator-creation-dialog.tsx index a5060a02e5..833ada9085 100644 --- a/src/components/dialogs/network-modifications/generator/creation/generator-creation-dialog.tsx +++ b/src/components/dialogs/network-modifications/generator/creation/generator-creation-dialog.tsx @@ -87,7 +87,11 @@ import { import { GeneratorCreationInfos } from '../../../../../services/network-modification-types'; import { DeepNullable } from '../../../../utils/ts-utils'; import { GeneratorCreationDialogSchemaForm, GeneratorFormInfos } from '../generator-dialog.type'; -import { getSetPointsEmptyFormData, getSetPointsSchema } from '../../../set-points/set-points-utils'; +import { + getSetPointsEmptyFormData, + getSetPointsSchema, + testValueWithinPowerInterval, +} from '../../../set-points/set-points-utils'; import { NetworkModificationDialogProps } from '../../../../graph/menus/network-modifications/network-modification-menu.type'; import { getShortCircuitEmptyFormData, @@ -136,17 +140,7 @@ const formSchema = yup .test( 'activePowerSetPoint', 'PlannedActivePowerSetPointMustBeBetweenMinAndMaxActivePower', - (value, context) => { - const minActivePower = context.parent[MINIMUM_ACTIVE_POWER]; - const maxActivePower = context.parent[MAXIMUM_ACTIVE_POWER]; - if (value === null || value === undefined) { - return true; - } - if (minActivePower === null || maxActivePower === null) { - return false; - } - return value >= minActivePower && value <= maxActivePower; - } + testValueWithinPowerInterval ), [MARGINAL_COST]: yup.number().nullable(), [PLANNED_OUTAGE_RATE]: yup.number().nullable().min(0, 'RealPercentage').max(1, 'RealPercentage'), diff --git a/src/components/dialogs/set-points/set-points-utils.ts b/src/components/dialogs/set-points/set-points-utils.ts index 1452b307db..ab814b1d6d 100644 --- a/src/components/dialogs/set-points/set-points-utils.ts +++ b/src/components/dialogs/set-points/set-points-utils.ts @@ -13,6 +13,7 @@ import { VOLTAGE_REGULATION, } from 'components/utils/field-constants'; import yup from 'components/utils/yup-config'; +import { TestContext } from 'yup'; export const getSetPointsEmptyFormData = (_isEquipmentModification = false) => ({ [ACTIVE_POWER_SET_POINT]: null, @@ -34,6 +35,25 @@ export const getReactivePowerSetPointSchema = (isEquipmentModification = false) }), }); +const testValueWithinPowerIntervalOrEqualToZero = (value: number | null | undefined, context: TestContext) => { + if (value === 0) { + return true; + } + return testValueWithinPowerInterval(value, context); +}; + +export const testValueWithinPowerInterval = (value: number | null | undefined, context: TestContext) => { + const minActivePower = context.parent[MINIMUM_ACTIVE_POWER]; + const maxActivePower = context.parent[MAXIMUM_ACTIVE_POWER]; + if (value === null || value === undefined) { + return true; + } + if (minActivePower === null || maxActivePower === null) { + return false; + } + return value >= minActivePower && value <= maxActivePower; +}; + export const getActivePowerSetPointSchema = (isEquipmentModification = false) => ({ [ACTIVE_POWER_SET_POINT]: yup .number() @@ -52,17 +72,7 @@ export const getActivePowerSetPointSchema = (isEquipmentModification = false) => .test( 'activePowerSetPoint', 'ActivePowerMustBeZeroOrBetweenMinAndMaxActivePower', - (value, context) => { - const minActivePower = context.parent[MINIMUM_ACTIVE_POWER]; - const maxActivePower = context.parent[MAXIMUM_ACTIVE_POWER]; - if (value === 0) { - return true; - } - if (minActivePower === null || maxActivePower === null) { - return false; - } - return value >= minActivePower && value <= maxActivePower; - } + testValueWithinPowerIntervalOrEqualToZero ); }, }), From b77e1ff2881cb777068e928e41f12c8399acf898 Mon Sep 17 00:00:00 2001 From: basseche Date: Wed, 11 Feb 2026 11:00:28 +0100 Subject: [PATCH 3/3] Review 2 Signed-off-by: basseche --- .../generator/creation/generator-creation-dialog.tsx | 1 + src/components/dialogs/set-points/set-points-utils.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/dialogs/network-modifications/generator/creation/generator-creation-dialog.tsx b/src/components/dialogs/network-modifications/generator/creation/generator-creation-dialog.tsx index 833ada9085..4846dddb74 100644 --- a/src/components/dialogs/network-modifications/generator/creation/generator-creation-dialog.tsx +++ b/src/components/dialogs/network-modifications/generator/creation/generator-creation-dialog.tsx @@ -137,6 +137,7 @@ const formSchema = yup [PLANNED_ACTIVE_POWER_SET_POINT]: yup .number() .nullable() + .default(null) .test( 'activePowerSetPoint', 'PlannedActivePowerSetPointMustBeBetweenMinAndMaxActivePower', diff --git a/src/components/dialogs/set-points/set-points-utils.ts b/src/components/dialogs/set-points/set-points-utils.ts index ab814b1d6d..6c0855ecde 100644 --- a/src/components/dialogs/set-points/set-points-utils.ts +++ b/src/components/dialogs/set-points/set-points-utils.ts @@ -35,14 +35,14 @@ export const getReactivePowerSetPointSchema = (isEquipmentModification = false) }), }); -const testValueWithinPowerIntervalOrEqualToZero = (value: number | null | undefined, context: TestContext) => { +const testValueWithinPowerIntervalOrEqualToZero = (value: number, context: TestContext) => { if (value === 0) { return true; } return testValueWithinPowerInterval(value, context); }; -export const testValueWithinPowerInterval = (value: number | null | undefined, context: TestContext) => { +export const testValueWithinPowerInterval = (value: number | null, context: TestContext) => { const minActivePower = context.parent[MINIMUM_ACTIVE_POWER]; const maxActivePower = context.parent[MAXIMUM_ACTIVE_POWER]; if (value === null || value === undefined) {