From a2205d676ddf860300c4956730027ee8b96a742c Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Tue, 16 Sep 2025 18:22:12 +0200 Subject: [PATCH 1/9] type and clean limits modification Signed-off-by: Mathieu DEHARBE --- .../dialogs/limits/limits-pane-utils.ts | 224 +++++++----------- .../modification/line-modification-dialog.tsx | 30 ++- .../modification/line-modification-type.ts | 52 +++- ...ndings-transformer-modification-dialog.jsx | 16 +- src/components/utils/field-constants.ts | 1 + src/components/utils/utils.ts | 23 +- 6 files changed, 174 insertions(+), 172 deletions(-) diff --git a/src/components/dialogs/limits/limits-pane-utils.ts b/src/components/dialogs/limits/limits-pane-utils.ts index 31b30b35bf..35f5fb69e9 100644 --- a/src/components/dialogs/limits/limits-pane-utils.ts +++ b/src/components/dialogs/limits/limits-pane-utils.ts @@ -9,8 +9,12 @@ import { sanitizeString } from '../dialog-utils'; import { APPLICABIlITY, CURRENT_LIMITS, + DELETION_MARK, ID, + LIMIT_SETS_MODIFICATION_TYPE, LIMITS, + MODIFICATION_TYPE, + NAME, OPERATIONAL_LIMITS_GROUPS, PERMANENT_LIMIT, SELECTED_LIMITS_GROUP_1, @@ -20,12 +24,14 @@ import { TEMPORARY_LIMIT_NAME, TEMPORARY_LIMIT_VALUE, TEMPORARY_LIMITS, - NAME, - LIMIT_SETS_MODIFICATION_TYPE, } from 'components/utils/field-constants'; -import { areArrayElementsUnique, formatTemporaryLimits, toModificationOperation } from 'components/utils/utils'; +import { + areArrayElementsUnique, + formatTemporaryLimits, + formatToTemporaryLimitsDialogForm, + toModificationOperation, +} from 'components/utils/utils'; import yup from 'components/utils/yup-config'; -import { isNodeBuilt } from '../../graph/util/model-functions'; import { AttributeModification, CurrentLimits, @@ -33,10 +39,13 @@ import { OperationType, TemporaryLimit, } from '../../../services/network-modification-types'; -import { CurrentTreeNode } from '../../graph/tree-node.type'; import { BranchInfos } from '../../../services/study/network-map.type'; import { areOperationalLimitsGroupUnique, OperationalLimitsId } from './limits-utils'; -import { LineModificationEditData } from '../network-modifications/line/modification/line-modification-type'; +import { + LineModificationDialogForm, + OperationalLimitsGroupDialogForm, + TemporaryLimitDialogForm, +} from '../network-modifications/line/modification/line-modification-type'; const limitsGroupValidationSchema = (isModification: boolean) => ({ [ID]: yup.string().nonNullable().required(), @@ -154,7 +163,9 @@ export const getAllLimitsFormData = ( /** * sanitizes limit names and filters out the empty temporary limits lines */ -export const sanitizeLimitsGroups = (limitsGroups: OperationalLimitsGroup[]): OperationalLimitsGroup[] => +export const sanitizeLimitsGroups = ( + limitsGroups: OperationalLimitsGroupDialogForm[] +): OperationalLimitsGroupDialogForm[] => limitsGroups.map(({ currentLimits, ...baseData }) => ({ ...baseData, id: baseData.name, @@ -179,69 +190,56 @@ export const sanitizeLimitsGroups = (limitsGroups: OperationalLimitsGroup[]): Op }, })); -export const sanitizeLimitNames = (temporaryLimitList: TemporaryLimit[]): TemporaryLimit[] => +export const sanitizeLimitNames = (temporaryLimitList: TemporaryLimitDialogForm[]): TemporaryLimitDialogForm[] => temporaryLimitList - ?.filter((limit: TemporaryLimit) => limit?.name?.trim()) + ?.filter((limit: TemporaryLimitDialogForm) => limit?.name?.trim()) .map(({ name, ...temporaryLimit }) => ({ ...temporaryLimit, name: sanitizeString(name) ?? '', })) || []; -const findTemporaryLimit = (temporaryLimits: TemporaryLimit[], limit: TemporaryLimit) => - temporaryLimits?.find((l) => l.name === limit.name && l.acceptableDuration === limit.acceptableDuration); +const findTemporaryLimitForm = (temporaryLimits: TemporaryLimitDialogForm[], limit: TemporaryLimit) => + temporaryLimits?.find( + (l: TemporaryLimitDialogForm) => l.name === limit.name && l.acceptableDuration === limit.acceptableDuration + ); export const updateTemporaryLimits = ( - modifiedTemporaryLimits: TemporaryLimit[], // from the form (ie network modification values) + limitsDialogForm: TemporaryLimitDialogForm[], temporaryLimitsToModify: TemporaryLimit[] // from map server ) => { - let updatedTemporaryLimits = modifiedTemporaryLimits ?? []; + let updatedTemporaryLimits = limitsDialogForm ?? []; //add temporary limits from from map server that are not in the form values temporaryLimitsToModify?.forEach((limit: TemporaryLimit) => { - if (findTemporaryLimit(updatedTemporaryLimits, limit) === undefined) { - updatedTemporaryLimits?.push({ - ...limit, - }); + if (findTemporaryLimitForm(updatedTemporaryLimits, limit) === undefined) { + updatedTemporaryLimits?.push(temporaryLimitToTemporaryLimitDialogForm(limit)); } }); //remove deleted temporary limits from current and previous modifications - updatedTemporaryLimits = updatedTemporaryLimits?.filter( - (limit: TemporaryLimit) => - limit.modificationType !== TEMPORARY_LIMIT_MODIFICATION_TYPE.DELETE && - !( - (limit.modificationType === null || - limit.modificationType === TEMPORARY_LIMIT_MODIFICATION_TYPE.MODIFY) && - findTemporaryLimit(temporaryLimitsToModify, limit) === undefined - ) - ); + updatedTemporaryLimits = updatedTemporaryLimits?.filter((limit: TemporaryLimitDialogForm) => !limit[DELETION_MARK]); - //update temporary limits values - updatedTemporaryLimits?.forEach((limit: TemporaryLimit) => { - if (limit.modificationType === null) { - limit.value = findTemporaryLimit(temporaryLimitsToModify, limit)?.value ?? null; - } - }); return updatedTemporaryLimits; }; /** - * extract data loaded from the map server and merge it with local data in order to fill the operaitonal liits groups modification interface + * extract data loaded from the map server and merge it with local data + * in order to fill the operational limits groups modification interface */ -export const updateOpLimitsGroups = ( - formBranchModification: LineModificationEditData, +export const combineFormAndMapServerLimitsGroups = ( + formBranchModification: LineModificationDialogForm, mapServerBranch: BranchInfos -): OperationalLimitsGroup[] => { - let updatedOpLG: OperationalLimitsGroup[] = formBranchModification.limits.operationalLimitsGroups ?? []; +): OperationalLimitsGroupDialogForm[] => { + let updatedOpLG: OperationalLimitsGroupDialogForm[] = formBranchModification.limits.operationalLimitsGroups ?? []; // updates limit values : - updatedOpLG.forEach((opLG: OperationalLimitsGroup) => { + updatedOpLG.forEach((opLG: OperationalLimitsGroupDialogForm) => { const equivalentFromMapServer = mapServerBranch.currentLimits?.find( (currentLimit: CurrentLimits) => currentLimit.id === opLG.name && currentLimit.applicability === opLG.applicability ); if (equivalentFromMapServer !== undefined) { opLG.currentLimits.temporaryLimits = updateTemporaryLimits( - formatTemporaryLimits(opLG.currentLimits.temporaryLimits), + opLG.currentLimits.temporaryLimits, formatTemporaryLimits(equivalentFromMapServer.temporaryLimits) ); } @@ -250,7 +248,7 @@ export const updateOpLimitsGroups = ( // adds all the operational limits groups from mapServerBranch THAT ARE NOT DELETED by the netmod mapServerBranch.currentLimits.forEach((currentLimit: CurrentLimits) => { const equivalentFromNetMod = updatedOpLG.find( - (opLG: OperationalLimitsGroup) => + (opLG: OperationalLimitsGroupDialogForm) => currentLimit.id === opLG.name && currentLimit.applicability === opLG.applicability ); if (equivalentFromNetMod === undefined) { @@ -262,88 +260,29 @@ export const updateOpLimitsGroups = ( id: currentLimit.id, applicability: currentLimit.applicability, permanentLimit: null, - temporaryLimits: formatTemporaryLimits(currentLimit.temporaryLimits), + temporaryLimits: formatToTemporaryLimitsDialogForm(currentLimit.temporaryLimits), }, }); } }); - //remove deleted operational limits groups - updatedOpLG = updatedOpLG?.filter( - (opLG: OperationalLimitsGroup) => opLG.modificationType !== TEMPORARY_LIMIT_MODIFICATION_TYPE.DELETE - ); - return updatedOpLG; }; export const addModificationTypeToTemporaryLimits = ( - temporaryLimits: TemporaryLimit[], - temporaryLimitsToModify: TemporaryLimit[], - networkTemporaryLimits: TemporaryLimit[], - currentNode: CurrentTreeNode + formTemporaryLimits: TemporaryLimitDialogForm[] ): TemporaryLimit[] => { - const formattedTemporaryLimitsToModify = formatTemporaryLimits(temporaryLimitsToModify); - const formattedNetworkTemporaryLimits = formatTemporaryLimits(networkTemporaryLimits); - const updatedTemporaryLimits: TemporaryLimit[] = temporaryLimits.map((limit) => { - const limitWithSameName = findTemporaryLimit(formattedTemporaryLimitsToModify, limit); - if (limitWithSameName) { - const currentLimitWithSameName: TemporaryLimit | undefined = findTemporaryLimit( - formattedNetworkTemporaryLimits, - limitWithSameName - ); - if ( - (currentLimitWithSameName?.modificationType === TEMPORARY_LIMIT_MODIFICATION_TYPE.MODIFY && - isNodeBuilt(currentNode)) || - currentLimitWithSameName?.modificationType === TEMPORARY_LIMIT_MODIFICATION_TYPE.ADD - ) { - return { - ...limit, - modificationType: currentLimitWithSameName.modificationType, - }; - } else { - return limitWithSameName.value === limit.value - ? { - ...limit, - modificationType: null, - } - : { - ...limit, - modificationType: TEMPORARY_LIMIT_MODIFICATION_TYPE.MODIFY, - }; - } - } else { - return { - ...limit, - modificationType: TEMPORARY_LIMIT_MODIFICATION_TYPE.ADD, - }; - } - }); - //add deleted limits - formattedTemporaryLimitsToModify?.forEach((limit) => { - if (!findTemporaryLimit(temporaryLimits, limit)) { - updatedTemporaryLimits.push({ - ...limit, - modificationType: TEMPORARY_LIMIT_MODIFICATION_TYPE.DELETE, - }); - } - }); - //add previously deleted limits - formattedNetworkTemporaryLimits?.forEach((limit) => { - if ( - !findTemporaryLimit(updatedTemporaryLimits, limit) && - limit.modificationType === TEMPORARY_LIMIT_MODIFICATION_TYPE.DELETE - ) { - updatedTemporaryLimits.push({ - ...limit, - modificationType: TEMPORARY_LIMIT_MODIFICATION_TYPE.DELETE, - }); - } + return formTemporaryLimits.map((limit: TemporaryLimitDialogForm) => { + return { + ...limit, + modificationType: TEMPORARY_LIMIT_MODIFICATION_TYPE.MODIFY_OR_ADD, + // TODO : add deleted limits if they are tagged + }; }); - return updatedTemporaryLimits; }; export function addOperationTypeToSelectedOpLG( - selectedOpLG: string, + selectedOpLG: string | null, noSelectionString: string ): AttributeModification | null { return selectedOpLG === noSelectionString @@ -357,53 +296,54 @@ export function addOperationTypeToSelectedOpLG( /** * converts the limits groups into a modification limits group * ie mostly add the ADD, MODIFY, MODIFY_OR_ADD, DELETE and REPLACE tags to the data using a delta between the form and the network values - * note : for now only ADD and MODIFY_OR_ADD are handled, the others have been disabled for various reasons + * note : for now only MODIFY_OR_ADD are handled, the others have been disabled for various reasons * - * @param limitsGroups current data from the form - * @param networkLine data of the line modified by the network modification - * @param editData data from the existing network modification, if the user is editing a netmod already stored in database - * @param currentNode + * @param limitsGroupsForm current data from the form */ export const addModificationTypeToOpLimitsGroups = ( - limitsGroups: OperationalLimitsGroup[], - networkLine: BranchInfos | null, - editData: LineModificationEditData | null | undefined, - currentNode: CurrentTreeNode -) => { - let modificationLimitsGroups: OperationalLimitsGroup[] = sanitizeLimitsGroups(limitsGroups); + limitsGroupsForm: OperationalLimitsGroupDialogForm[] +): OperationalLimitsGroup[] => { + let modificationLimitsGroupsForm: OperationalLimitsGroupDialogForm[] = sanitizeLimitsGroups(limitsGroupsForm); - modificationLimitsGroups = modificationLimitsGroups.map((formLimitsGroup: OperationalLimitsGroup) => { + return modificationLimitsGroupsForm.map((limitsGroupForm: OperationalLimitsGroupDialogForm) => { const modificationType: string = LIMIT_SETS_MODIFICATION_TYPE.MODIFY_OR_ADD; - const networkCurrentLimits = networkLine?.currentLimits.find( - (lineOpLimitGroup: CurrentLimits) => - lineOpLimitGroup.id === formLimitsGroup.name && - lineOpLimitGroup.applicability === formLimitsGroup.applicability - ); const temporaryLimits: TemporaryLimit[] = addModificationTypeToTemporaryLimits( - sanitizeLimitNames(formLimitsGroup.currentLimits?.[TEMPORARY_LIMITS]), - networkCurrentLimits?.temporaryLimits ?? [], - editData?.operationalLimitsGroups?.find( - (editDataOpLimitGroup: OperationalLimitsGroup) => - editDataOpLimitGroup.id === formLimitsGroup.name && - editDataOpLimitGroup.applicability === formLimitsGroup.applicability - )?.currentLimits?.temporaryLimits ?? [], - currentNode + sanitizeLimitNames(limitsGroupForm[CURRENT_LIMITS]?.[TEMPORARY_LIMITS]) ); - let currentLimits = formLimitsGroup.currentLimits; - if (formLimitsGroup.currentLimits?.[PERMANENT_LIMIT] || temporaryLimits.length > 0) { - currentLimits.permanentLimit = formLimitsGroup.currentLimits?.[PERMANENT_LIMIT]; - currentLimits.temporaryLimits = temporaryLimits; - } + const currentLimits: CurrentLimits = { + id: limitsGroupForm[CURRENT_LIMITS][ID], + applicability: limitsGroupForm[CURRENT_LIMITS]?.[APPLICABIlITY], + permanentLimit: limitsGroupForm[CURRENT_LIMITS]?.[PERMANENT_LIMIT] ?? null, + temporaryLimits: temporaryLimits ?? [], + }; return { - id: formLimitsGroup.id, - name: formLimitsGroup.name, - applicability: formLimitsGroup.applicability, + id: limitsGroupForm.id, + name: limitsGroupForm.name, + applicability: limitsGroupForm.applicability, currentLimits: currentLimits, modificationType: modificationType, }; }); +}; - return modificationLimitsGroups; +export const temporaryLimitToTemporaryLimitDialogForm = (temporaryLimit: TemporaryLimit): TemporaryLimitDialogForm => { + return { + [TEMPORARY_LIMIT_NAME]: temporaryLimit.name, + [TEMPORARY_LIMIT_DURATION]: temporaryLimit.acceptableDuration, + [TEMPORARY_LIMIT_VALUE]: temporaryLimit.value, + [DELETION_MARK]: false, + }; +}; + +export const temporaryLimitDialogFormToTemporaryLimit = (temporaryLimit: TemporaryLimitDialogForm): TemporaryLimit => { + return { + [TEMPORARY_LIMIT_NAME]: temporaryLimit.name, + [TEMPORARY_LIMIT_DURATION]: temporaryLimit.acceptableDuration, + [TEMPORARY_LIMIT_VALUE]: temporaryLimit.value, + [MODIFICATION_TYPE]: temporaryLimit[DELETION_MARK] + ? TEMPORARY_LIMIT_MODIFICATION_TYPE.DELETE + : TEMPORARY_LIMIT_MODIFICATION_TYPE.MODIFY_OR_ADD, + }; }; diff --git a/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx b/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx index bb0e973644..2de9c4bf7b 100644 --- a/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx +++ b/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx @@ -59,7 +59,7 @@ import { addModificationTypeToOpLimitsGroups, getAllLimitsFormData, formatOpLimitGroups, - updateOpLimitsGroups, + combineFormAndMapServerLimitsGroups, addOperationTypeToSelectedOpLG, } from '../../../limits/limits-pane-utils'; import { @@ -101,11 +101,11 @@ import { UUID } from 'crypto'; import { CurrentTreeNode } from '../../../../graph/tree-node.type'; import { BranchInfos } from '../../../../../services/study/network-map.type'; import { useIntl } from 'react-intl'; -import { LineModificationEditData } from './line-modification-type'; +import { LimitsDialogForm, LineModificationDialogForm } from './line-modification-type'; export interface LineModificationDialogProps { // contains data when we try to edit an existing hypothesis from the current node's list - editData: LineModificationEditData | null | undefined; + editData: LineModificationDialogForm | null | undefined; // Used to pre-select an equipmentId when calling this dialog from the SLD or network map defaultIdValue: string; studyUuid: UUID; @@ -183,7 +183,7 @@ const LineModificationDialog = ({ const { reset, setValue, getValues } = formMethods; const fromEditDataToFormValues = useCallback( - (lineModification: LineModificationEditData) => { + (lineModification: LineModificationDialogForm) => { if (lineModification?.equipmentId) { setSelectedId(lineModification.equipmentId); } @@ -220,12 +220,12 @@ const LineModificationDialog = ({ }, [fromEditDataToFormValues, editData]); const onSubmit = useCallback( - (line: LineModificationEditData) => { + (line: LineModificationDialogForm) => { const connectivity1 = line[CONNECTIVITY]?.[CONNECTIVITY_1]; const connectivity2 = line[CONNECTIVITY]?.[CONNECTIVITY_2]; const characteristics = line[CHARACTERISTICS]; const stateEstimationData = line[STATE_ESTIMATION]; - const limits = line[LIMITS]; + const limits: LimitsDialogForm = line[LIMITS]; modifyLine({ studyUuid: studyUuid, @@ -239,12 +239,7 @@ const LineModificationDialog = ({ b1: convertOutputValue(FieldType.B1, characteristics[B1]), g2: convertOutputValue(FieldType.G2, characteristics[G2]), b2: convertOutputValue(FieldType.B2, characteristics[B2]), - operationalLimitsGroups: addModificationTypeToOpLimitsGroups( - limits[OPERATIONAL_LIMITS_GROUPS], - lineToModify, - editData, - currentNode - ), + operationalLimitsGroups: addModificationTypeToOpLimitsGroups(limits[OPERATIONAL_LIMITS_GROUPS]), selectedLimitsGroup1: addOperationTypeToSelectedOpLG( limits[SELECTED_LIMITS_GROUP_1], intl.formatMessage({ @@ -285,7 +280,7 @@ const LineModificationDialog = ({ }); }); }, - [studyUuid, currentNodeUuid, editData, selectedId, lineToModify, currentNode, intl, snackError] + [studyUuid, currentNodeUuid, editData, selectedId, intl, snackError] ); const clear = useCallback(() => { @@ -308,11 +303,14 @@ const LineModificationDialog = ({ .then((line: BranchInfos) => { if (line) { setLineToModify(line); - reset((formValues: LineModificationEditData) => ({ + reset((formValues: LineModificationDialogForm) => ({ ...formValues, ...{ [LIMITS]: { - [OPERATIONAL_LIMITS_GROUPS]: updateOpLimitsGroups(formValues, line), + [OPERATIONAL_LIMITS_GROUPS]: combineFormAndMapServerLimitsGroups( + formValues, + line + ), }, }, [ADDITIONAL_PROPERTIES]: getConcatenatedProperties(line, getValues), @@ -341,7 +339,7 @@ const LineModificationDialog = ({ } }, [selectedId, onEquipmentIdChange]); - const onValidationError = (errors: FieldErrors) => { + const onValidationError = (errors: FieldErrors) => { let tabsInError: number[] = []; if (errors?.[LIMITS] !== undefined) { tabsInError.push(LineModificationDialogTab.LIMITS_TAB); diff --git a/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts b/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts index 0bdaafc9d5..0a6d2aed7f 100644 --- a/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts +++ b/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts @@ -6,10 +6,29 @@ */ import { UUID } from 'crypto'; -import { AttributeModification, OperationalLimitsGroup } from '../../../../../services/network-modification-types'; +import { + AttributeModification, + CurrentLimits, + OperationalLimitsGroup, +} from '../../../../../services/network-modification-types'; import { Property } from '../../common/properties/property-utils'; +import { + APPLICABIlITY, + CURRENT_LIMITS, + DELETION_MARK, + ID, + NAME, + OPERATIONAL_LIMITS_GROUPS, + PERMANENT_LIMIT, + SELECTED_LIMITS_GROUP_1, + SELECTED_LIMITS_GROUP_2, + TEMPORARY_LIMIT_DURATION, + TEMPORARY_LIMIT_NAME, + TEMPORARY_LIMIT_VALUE, + TEMPORARY_LIMITS, +} from '../../../../utils/field-constants'; -export interface LineModificationEditData { +export interface LineModificationDialogForm { uuid?: string; equipmentId?: string; equipmentName?: { value: string }; @@ -52,5 +71,32 @@ export interface LineModificationEditData { AdditionalProperties: any; characteristics: any; stateEstimation: any; - limits: any; + limits: LimitsDialogForm; +} + +export interface LimitsDialogForm { + [SELECTED_LIMITS_GROUP_1]: string | null; + [SELECTED_LIMITS_GROUP_2]: string | null; + [OPERATIONAL_LIMITS_GROUPS]: OperationalLimitsGroupDialogForm[]; +} + +export interface OperationalLimitsGroupDialogForm { + [ID]: string; + [NAME]: string; + [APPLICABIlITY]?: string; + [CURRENT_LIMITS]: CurrentLimitsDialogForm; +} + +export interface CurrentLimitsDialogForm { + [ID]: string; // TODO : needed here or only in OperationalLimitsGroupDialogForm ?? + [APPLICABIlITY]?: string; // TODO : needed here or only in OperationalLimitsGroupDialogForm ?? + [PERMANENT_LIMIT]: number | null; + [TEMPORARY_LIMITS]: TemporaryLimitDialogForm[]; +} + +export interface TemporaryLimitDialogForm { + [TEMPORARY_LIMIT_NAME]: string; + [TEMPORARY_LIMIT_DURATION]: number | null; + [TEMPORARY_LIMIT_VALUE]: number | null; + [DELETION_MARK]: boolean; } 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 26f96e88a1..7b41105357 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 @@ -95,7 +95,7 @@ import { getAllLimitsFormData, getLimitsEmptyFormData, getLimitsValidationSchema, - updateOpLimitsGroups, + combineFormAndMapServerLimitsGroups, } from '../../../limits/limits-pane-utils'; import { useOpenShortWaitFetching } from 'components/dialogs/commons/handle-modification-form'; import TwoWindingsTransformerModificationDialogHeader from './two-windings-transformer-modification-dialog-header'; @@ -483,12 +483,7 @@ const TwoWindingsTransformerModificationDialog = ({ ratedS: toModificationOperation(characteristics[RATED_S]), ratedU1: toModificationOperation(characteristics[RATED_U1]), ratedU2: toModificationOperation(characteristics[RATED_U2]), - operationalLimitsGroups: addModificationTypeToOpLimitsGroups( - limits[OPERATIONAL_LIMITS_GROUPS], - twtToModify, - editData, - currentNode - ), + operationalLimitsGroups: addModificationTypeToOpLimitsGroups(limits[OPERATIONAL_LIMITS_GROUPS]), selectedLimitsGroup1: addOperationTypeToSelectedOpLG( limits[SELECTED_LIMITS_GROUP_1], intl.formatMessage({ @@ -538,8 +533,6 @@ const TwoWindingsTransformerModificationDialog = ({ currentNodeUuid, editData, selectedId, - twtToModify, - currentNode, intl, computeRatioTapForSubmit, computePhaseTapForSubmit, @@ -659,7 +652,10 @@ const TwoWindingsTransformerModificationDialog = ({ ...formValues, ...{ [LIMITS]: { - [OPERATIONAL_LIMITS_GROUPS]: updateOpLimitsGroups(formValues, twt), + [OPERATIONAL_LIMITS_GROUPS]: combineFormAndMapServerLimitsGroups( + formValues, + twt + ), }, }, ...getRatioTapChangerFormData({ diff --git a/src/components/utils/field-constants.ts b/src/components/utils/field-constants.ts index b335eb6428..0ff1576bf9 100644 --- a/src/components/utils/field-constants.ts +++ b/src/components/utils/field-constants.ts @@ -204,6 +204,7 @@ export const TEMPORARY_LIMIT_DURATION = 'acceptableDuration'; export const TEMPORARY_LIMIT_VALUE = 'value'; export const TEMPORARY_LIMIT_MODIFICATION_TYPE = { MODIFY: 'MODIFY', + MODIFY_OR_ADD: 'MODIFY_OR_ADD', // if the limit exists it is modified, if not it is created ADD: 'ADD', DELETE: 'DELETE', REPLACE: 'REPLACE', diff --git a/src/components/utils/utils.ts b/src/components/utils/utils.ts index 363be30020..a15ac285a8 100644 --- a/src/components/utils/utils.ts +++ b/src/components/utils/utils.ts @@ -16,7 +16,18 @@ import { } from 'services/network-modification-types'; import { VoltageLevel } from './equipment-types'; import { Option } from '@gridsuite/commons-ui'; -import { APPLICABIlITY, CURRENT_LIMITS, ID, NAME, SELECTED } from './field-constants'; +import { + APPLICABIlITY, + CURRENT_LIMITS, + DELETION_MARK, + ID, + NAME, + SELECTED, + TEMPORARY_LIMIT_DURATION, + TEMPORARY_LIMIT_NAME, + TEMPORARY_LIMIT_VALUE, +} from './field-constants'; +import { TemporaryLimitDialogForm } from '../dialogs/network-modifications/line/modification/line-modification-type'; export const UNDEFINED_ACCEPTABLE_DURATION = Math.pow(2, 31) - 1; @@ -128,6 +139,16 @@ export const formatTemporaryLimits = (temporaryLimits: TemporaryLimit[]): Tempor }; }); +export const formatToTemporaryLimitsDialogForm = (temporaryLimits: TemporaryLimit[]): TemporaryLimitDialogForm[] => + temporaryLimits?.map((limit: TemporaryLimit) => { + return { + [TEMPORARY_LIMIT_NAME]: limit?.[TEMPORARY_LIMIT_NAME] ?? '', + [TEMPORARY_LIMIT_VALUE]: limit?.[TEMPORARY_LIMIT_VALUE] ?? null, + [TEMPORARY_LIMIT_DURATION]: limit?.[TEMPORARY_LIMIT_DURATION] ?? null, + [DELETION_MARK]: false, + }; + }); + export const formatCompleteCurrentLimit = (completeLimitsGroups: CurrentLimits[]) => { const formattedCompleteLimitsGroups: OperationalLimitsGroup[] = []; if (completeLimitsGroups) { From 90da6259f9a0b1a46249f3a3326f00e6866b9d8e Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Thu, 18 Sep 2025 10:42:01 +0200 Subject: [PATCH 2/9] use DELETION_MARK Signed-off-by: Mathieu DEHARBE --- .../dialogs/limits/limits-pane-utils.ts | 5 +++-- .../dialogs/limits/temporary-limits-table.tsx | 17 ++++++++++++----- .../modification/line-modification-dialog.tsx | 2 +- .../line/modification/line-modification-type.ts | 6 +----- src/components/utils/utils.ts | 11 +++++++---- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/components/dialogs/limits/limits-pane-utils.ts b/src/components/dialogs/limits/limits-pane-utils.ts index 35f5fb69e9..8c17a95c09 100644 --- a/src/components/dialogs/limits/limits-pane-utils.ts +++ b/src/components/dialogs/limits/limits-pane-utils.ts @@ -275,8 +275,9 @@ export const addModificationTypeToTemporaryLimits = ( return formTemporaryLimits.map((limit: TemporaryLimitDialogForm) => { return { ...limit, - modificationType: TEMPORARY_LIMIT_MODIFICATION_TYPE.MODIFY_OR_ADD, - // TODO : add deleted limits if they are tagged + modificationType: limit[DELETION_MARK] + ? TEMPORARY_LIMIT_MODIFICATION_TYPE.DELETE + : TEMPORARY_LIMIT_MODIFICATION_TYPE.MODIFY_OR_ADD, }; }); }; diff --git a/src/components/dialogs/limits/temporary-limits-table.tsx b/src/components/dialogs/limits/temporary-limits-table.tsx index 3c37805658..88ea701341 100644 --- a/src/components/dialogs/limits/temporary-limits-table.tsx +++ b/src/components/dialogs/limits/temporary-limits-table.tsx @@ -6,7 +6,7 @@ */ import { useState } from 'react'; -import { useFieldArray } from 'react-hook-form'; +import { useFieldArray, useFormContext } from 'react-hook-form'; import { Box, Grid, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material'; import { ColumnNumeric, @@ -20,7 +20,7 @@ import { import IconButton from '@mui/material/IconButton'; import AddCircleIcon from '@mui/icons-material/AddCircle'; import DeleteIcon from '@mui/icons-material/Delete'; -import { SELECTED } from '../../utils/field-constants'; +import { DELETION_MARK, SELECTED } from '../../utils/field-constants'; import { TemporaryLimit } from '../../../services/network-modification-types'; const styles = { @@ -91,8 +91,9 @@ function TemporaryLimitsTable({ isValueModified, disableAddingRows = false, }: Readonly) { - const { fields, append, remove } = useFieldArray({ name: arrayFormName }); + const { fields, append } = useFieldArray({ name: arrayFormName }); const [hoveredRowIndex, setHoveredRowIndex] = useState(-1); + const { setValue, getValues } = useFormContext(); function renderTableCell(rowId: string, rowIndex: number, column: ColumnText | ColumnNumeric) { const name = `${arrayFormName}[${rowIndex}].${column.dataKey}`; @@ -147,7 +148,10 @@ function TemporaryLimitsTable({ setHoveredRowIndex(index)} onMouseLeave={() => setHoveredRowIndex(-1)}> {columnsDefinition.map((column) => renderTableCell(rowId, index, column))} - remove(index)}> + setValue(`${arrayFormName}[${index}].${DELETION_MARK}`, true)} + > @@ -157,7 +161,10 @@ function TemporaryLimitsTable({ function renderTableBody() { return ( - {fields.map((value: Record<'id', string>, index: number) => renderTableRow(value.id, index))} + {fields.map( + (value: Record<'id', string>, index: number) => + !getValues(`${arrayFormName}[${index}].${DELETION_MARK}`) && renderTableRow(value.id, index) + )} ); } diff --git a/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx b/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx index 2de9c4bf7b..a0b45eb563 100644 --- a/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx +++ b/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx @@ -203,7 +203,7 @@ const LineModificationDialog = ({ b2: convertInputValue(FieldType.B2, lineModification.b2?.value ?? null), }), ...getAllLimitsFormData( - formatOpLimitGroups(lineModification.operationalLimitsGroups), + formatOpLimitGroups(lineModification.operationalLimitsGroups), // TODO : aller typer tout ça plus proprement => doit donner un type form au fnal lineModification.selectedOperationalLimitsGroup1?.value ?? null, lineModification.selectedOperationalLimitsGroup2?.value ?? null ), diff --git a/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts b/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts index 0a6d2aed7f..7fe16870c6 100644 --- a/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts +++ b/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts @@ -6,11 +6,7 @@ */ import { UUID } from 'crypto'; -import { - AttributeModification, - CurrentLimits, - OperationalLimitsGroup, -} from '../../../../../services/network-modification-types'; +import { AttributeModification, OperationalLimitsGroup } from '../../../../../services/network-modification-types'; import { Property } from '../../common/properties/property-utils'; import { APPLICABIlITY, diff --git a/src/components/utils/utils.ts b/src/components/utils/utils.ts index a15ac285a8..5081a6219f 100644 --- a/src/components/utils/utils.ts +++ b/src/components/utils/utils.ts @@ -21,9 +21,11 @@ import { CURRENT_LIMITS, DELETION_MARK, ID, + MODIFICATION_TYPE, NAME, SELECTED, TEMPORARY_LIMIT_DURATION, + TEMPORARY_LIMIT_MODIFICATION_TYPE, TEMPORARY_LIMIT_NAME, TEMPORARY_LIMIT_VALUE, } from './field-constants'; @@ -132,10 +134,11 @@ export function toModificationUnsetOperation( export const formatTemporaryLimits = (temporaryLimits: TemporaryLimit[]): TemporaryLimit[] => temporaryLimits?.map((limit: TemporaryLimit) => { return { - name: limit?.name ?? '', - value: limit?.value ?? null, - acceptableDuration: limit?.acceptableDuration ?? null, - modificationType: limit?.modificationType ?? null, + [TEMPORARY_LIMIT_NAME]: limit?.[TEMPORARY_LIMIT_NAME] ?? '', + [TEMPORARY_LIMIT_VALUE]: limit?.[TEMPORARY_LIMIT_VALUE] ?? null, + [TEMPORARY_LIMIT_DURATION]: limit?.[TEMPORARY_LIMIT_DURATION] ?? null, + [MODIFICATION_TYPE]: limit?.[MODIFICATION_TYPE] ?? null, + [DELETION_MARK]: limit?.modificationType === TEMPORARY_LIMIT_MODIFICATION_TYPE.DELETE, }; }); From 241e5bd154c9fc5037b352e574d862b828b0f615 Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Fri, 19 Sep 2025 10:09:34 +0200 Subject: [PATCH 3/9] dirty DELETION_MARK Signed-off-by: Mathieu DEHARBE --- src/components/dialogs/limits/limits-pane-utils.ts | 1 - src/components/dialogs/limits/temporary-limits-table.tsx | 2 +- .../line/modification/line-modification-dialog.tsx | 9 +++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/dialogs/limits/limits-pane-utils.ts b/src/components/dialogs/limits/limits-pane-utils.ts index ed2e7637c9..0e217c1c5b 100644 --- a/src/components/dialogs/limits/limits-pane-utils.ts +++ b/src/components/dialogs/limits/limits-pane-utils.ts @@ -35,7 +35,6 @@ import yup from 'components/utils/yup-config'; import { AttributeModification, CurrentLimits, - LineModificationInfos, OperationalLimitsGroup, OperationType, TemporaryLimit, diff --git a/src/components/dialogs/limits/temporary-limits-table.tsx b/src/components/dialogs/limits/temporary-limits-table.tsx index e97f1b8290..07b46d81af 100644 --- a/src/components/dialogs/limits/temporary-limits-table.tsx +++ b/src/components/dialogs/limits/temporary-limits-table.tsx @@ -151,7 +151,7 @@ function TemporaryLimitsTable({ setValue(`${arrayFormName}[${index}].${DELETION_MARK}`, true)} + onClick={() => setValue(`${arrayFormName}[${index}].${DELETION_MARK}`, true, { shouldDirty: true })} > diff --git a/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx b/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx index e50630aae2..ec4241214c 100644 --- a/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx +++ b/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx @@ -103,6 +103,7 @@ import { BranchInfos } from '../../../../../services/study/network-map.type'; import { useIntl } from 'react-intl'; import { LimitsDialogForm, LineModificationFormInfos } from './line-modification-type'; import { LineModificationInfos } from '../../../../../services/network-modification-types'; +import { toModificationOperation } from '../../../../utils/utils'; export interface LineModificationDialogProps { // contains data when we try to edit an existing hypothesis from the current node's list @@ -310,10 +311,10 @@ const LineModificationDialog = ({ ...{ [LIMITS]: { [OPERATIONAL_LIMITS_GROUPS]: combineFormAndMapServerLimitsGroups( - formValues, - line - ), - }, + formValues, + line + ), + }, }, [ADDITIONAL_PROPERTIES]: getConcatenatedProperties(line, getValues), }), From 8efe39e05e18d4d2572d9457f1a98327e8117ebc Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Fri, 19 Sep 2025 10:30:48 +0200 Subject: [PATCH 4/9] rename form data to FormInfos Signed-off-by: Mathieu DEHARBE --- .../dialogs/limits/limits-pane-utils.ts | 42 +++++++++---------- .../modification/line-modification-dialog.tsx | 4 +- .../modification/line-modification-type.ts | 18 ++++---- ...ndings-transformer-modification-dialog.jsx | 4 +- src/components/utils/utils.ts | 4 +- 5 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/components/dialogs/limits/limits-pane-utils.ts b/src/components/dialogs/limits/limits-pane-utils.ts index 0e217c1c5b..7d2bfeb9d1 100644 --- a/src/components/dialogs/limits/limits-pane-utils.ts +++ b/src/components/dialogs/limits/limits-pane-utils.ts @@ -43,8 +43,8 @@ import { BranchInfos } from '../../../services/study/network-map.type'; import { areOperationalLimitsGroupUnique, OperationalLimitsId } from './limits-utils'; import { LineModificationFormInfos, - OperationalLimitsGroupDialogForm, - TemporaryLimitDialogForm, + OperationalLimitsGroupFormInfos, + TemporaryLimitFormInfos, } from '../network-modifications/line/modification/line-modification-type'; const limitsGroupValidationSchema = (isModification: boolean) => ({ @@ -164,8 +164,8 @@ export const getAllLimitsFormData = ( * sanitizes limit names and filters out the empty temporary limits lines */ export const sanitizeLimitsGroups = ( - limitsGroups: OperationalLimitsGroupDialogForm[] -): OperationalLimitsGroupDialogForm[] => + limitsGroups: OperationalLimitsGroupFormInfos[] +): OperationalLimitsGroupFormInfos[] => limitsGroups.map(({ currentLimits, ...baseData }) => ({ ...baseData, id: baseData.name, @@ -190,21 +190,21 @@ export const sanitizeLimitsGroups = ( }, })); -export const sanitizeLimitNames = (temporaryLimitList: TemporaryLimitDialogForm[]): TemporaryLimitDialogForm[] => +export const sanitizeLimitNames = (temporaryLimitList: TemporaryLimitFormInfos[]): TemporaryLimitFormInfos[] => temporaryLimitList - ?.filter((limit: TemporaryLimitDialogForm) => limit?.name?.trim()) + ?.filter((limit: TemporaryLimitFormInfos) => limit?.name?.trim()) .map(({ name, ...temporaryLimit }) => ({ ...temporaryLimit, name: sanitizeString(name) ?? '', })) || []; -const findTemporaryLimitForm = (temporaryLimits: TemporaryLimitDialogForm[], limit: TemporaryLimit) => +const findTemporaryLimitForm = (temporaryLimits: TemporaryLimitFormInfos[], limit: TemporaryLimit) => temporaryLimits?.find( - (l: TemporaryLimitDialogForm) => l.name === limit.name && l.acceptableDuration === limit.acceptableDuration + (l: TemporaryLimitFormInfos) => l.name === limit.name && l.acceptableDuration === limit.acceptableDuration ); export const updateTemporaryLimits = ( - limitsDialogForm: TemporaryLimitDialogForm[], + limitsDialogForm: TemporaryLimitFormInfos[], temporaryLimitsToModify: TemporaryLimit[] // from map server ) => { let updatedTemporaryLimits = limitsDialogForm ?? []; @@ -216,7 +216,7 @@ export const updateTemporaryLimits = ( }); //remove deleted temporary limits from current and previous modifications - updatedTemporaryLimits = updatedTemporaryLimits?.filter((limit: TemporaryLimitDialogForm) => !limit[DELETION_MARK]); + updatedTemporaryLimits = updatedTemporaryLimits?.filter((limit: TemporaryLimitFormInfos) => !limit[DELETION_MARK]); return updatedTemporaryLimits; }; @@ -228,11 +228,11 @@ export const updateTemporaryLimits = ( export const combineFormAndMapServerLimitsGroups = ( formBranchModification: LineModificationFormInfos, mapServerBranch: BranchInfos -): OperationalLimitsGroupDialogForm[] => { - let updatedOpLG: OperationalLimitsGroupDialogForm[] = formBranchModification.limits.operationalLimitsGroups ?? []; +): OperationalLimitsGroupFormInfos[] => { + let updatedOpLG: OperationalLimitsGroupFormInfos[] = formBranchModification.limits.operationalLimitsGroups ?? []; // updates limit values : - updatedOpLG.forEach((opLG: OperationalLimitsGroupDialogForm) => { + updatedOpLG.forEach((opLG: OperationalLimitsGroupFormInfos) => { const equivalentFromMapServer = mapServerBranch.currentLimits?.find( (currentLimit: CurrentLimits) => currentLimit.id === opLG.name && currentLimit.applicability === opLG.applicability @@ -248,7 +248,7 @@ export const combineFormAndMapServerLimitsGroups = ( // adds all the operational limits groups from mapServerBranch THAT ARE NOT DELETED by the netmod mapServerBranch.currentLimits?.forEach((currentLimit: CurrentLimits) => { const equivalentFromNetMod = updatedOpLG.find( - (opLG: OperationalLimitsGroupDialogForm) => + (opLG: OperationalLimitsGroupFormInfos) => currentLimit.id === opLG.name && currentLimit.applicability === opLG.applicability ); if (equivalentFromNetMod === undefined) { @@ -270,9 +270,9 @@ export const combineFormAndMapServerLimitsGroups = ( }; export const addModificationTypeToTemporaryLimits = ( - formTemporaryLimits: TemporaryLimitDialogForm[] + formTemporaryLimits: TemporaryLimitFormInfos[] ): TemporaryLimit[] => { - return formTemporaryLimits.map((limit: TemporaryLimitDialogForm) => { + return formTemporaryLimits.map((limit: TemporaryLimitFormInfos) => { return { ...limit, modificationType: limit[DELETION_MARK] @@ -302,11 +302,11 @@ export function addOperationTypeToSelectedOpLG( * @param limitsGroupsForm current data from the form */ export const addModificationTypeToOpLimitsGroups = ( - limitsGroupsForm: OperationalLimitsGroupDialogForm[] + limitsGroupsForm: OperationalLimitsGroupFormInfos[] ): OperationalLimitsGroup[] => { - let modificationLimitsGroupsForm: OperationalLimitsGroupDialogForm[] = sanitizeLimitsGroups(limitsGroupsForm); + let modificationLimitsGroupsForm: OperationalLimitsGroupFormInfos[] = sanitizeLimitsGroups(limitsGroupsForm); - return modificationLimitsGroupsForm.map((limitsGroupForm: OperationalLimitsGroupDialogForm) => { + return modificationLimitsGroupsForm.map((limitsGroupForm: OperationalLimitsGroupFormInfos) => { const modificationType: string = LIMIT_SETS_MODIFICATION_TYPE.MODIFY_OR_ADD; const temporaryLimits: TemporaryLimit[] = addModificationTypeToTemporaryLimits( @@ -329,7 +329,7 @@ export const addModificationTypeToOpLimitsGroups = ( }); }; -export const temporaryLimitToTemporaryLimitDialogForm = (temporaryLimit: TemporaryLimit): TemporaryLimitDialogForm => { +export const temporaryLimitToTemporaryLimitDialogForm = (temporaryLimit: TemporaryLimit): TemporaryLimitFormInfos => { return { [TEMPORARY_LIMIT_NAME]: temporaryLimit.name, [TEMPORARY_LIMIT_DURATION]: temporaryLimit.acceptableDuration, @@ -338,7 +338,7 @@ export const temporaryLimitToTemporaryLimitDialogForm = (temporaryLimit: Tempora }; }; -export const temporaryLimitDialogFormToTemporaryLimit = (temporaryLimit: TemporaryLimitDialogForm): TemporaryLimit => { +export const temporaryLimitDialogFormToTemporaryLimit = (temporaryLimit: TemporaryLimitFormInfos): TemporaryLimit => { return { [TEMPORARY_LIMIT_NAME]: temporaryLimit.name, [TEMPORARY_LIMIT_DURATION]: temporaryLimit.acceptableDuration, diff --git a/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx b/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx index ec4241214c..1ac9b45a3c 100644 --- a/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx +++ b/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx @@ -101,7 +101,7 @@ import { UUID } from 'crypto'; import { CurrentTreeNode } from '../../../../graph/tree-node.type'; import { BranchInfos } from '../../../../../services/study/network-map.type'; import { useIntl } from 'react-intl'; -import { LimitsDialogForm, LineModificationFormInfos } from './line-modification-type'; +import { LimitsDialogFormInfos, LineModificationFormInfos } from './line-modification-type'; import { LineModificationInfos } from '../../../../../services/network-modification-types'; import { toModificationOperation } from '../../../../utils/utils'; @@ -227,7 +227,7 @@ const LineModificationDialog = ({ const connectivity2 = line[CONNECTIVITY]?.[CONNECTIVITY_2]; const characteristics = line[CHARACTERISTICS]; const stateEstimationData = line[STATE_ESTIMATION]; - const limits: LimitsDialogForm = line[LIMITS]; + const limits: LimitsDialogFormInfos = line[LIMITS]; modifyLine({ studyUuid: studyUuid, diff --git a/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts b/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts index 7c10a319c4..d3eda5e904 100644 --- a/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts +++ b/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts @@ -66,30 +66,32 @@ export interface LineModificationFormInfos { AdditionalProperties: any; characteristics: any; stateEstimation: any; - limits: LimitsDialogForm; + limits: LimitsDialogFormInfos; } -export interface LimitsDialogForm { +export interface LimitsDialogFormInfos { [SELECTED_LIMITS_GROUP_1]: string | null; [SELECTED_LIMITS_GROUP_2]: string | null; - [OPERATIONAL_LIMITS_GROUPS]: OperationalLimitsGroupDialogForm[]; + [OPERATIONAL_LIMITS_GROUPS]: OperationalLimitsGroupFormInfos[]; } -export interface OperationalLimitsGroupDialogForm { +export interface OperationalLimitsGroupFormInfos { + // here 'id' is a concatenation of NAME and APPLICABIlITY because 2 limits sets on side1 and 2 may have the same name + // "ID" from the map server is stored as NAME in the form because of this [ID]: string; [NAME]: string; [APPLICABIlITY]?: string; - [CURRENT_LIMITS]: CurrentLimitsDialogForm; + [CURRENT_LIMITS]: CurrentLimitsFormInfos; } -export interface CurrentLimitsDialogForm { +export interface CurrentLimitsFormInfos { [ID]: string; // TODO : needed here or only in OperationalLimitsGroupDialogForm ?? [APPLICABIlITY]?: string; // TODO : needed here or only in OperationalLimitsGroupDialogForm ?? [PERMANENT_LIMIT]: number | null; - [TEMPORARY_LIMITS]: TemporaryLimitDialogForm[]; + [TEMPORARY_LIMITS]: TemporaryLimitFormInfos[]; } -export interface TemporaryLimitDialogForm { +export interface TemporaryLimitFormInfos { [TEMPORARY_LIMIT_NAME]: string; [TEMPORARY_LIMIT_DURATION]: number | null; [TEMPORARY_LIMIT_VALUE]: number | null; 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 2a9e9817da..0fb2e315a4 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 @@ -654,8 +654,8 @@ const TwoWindingsTransformerModificationDialog = ({ ...{ [LIMITS]: { [OPERATIONAL_LIMITS_GROUPS]: combineFormAndMapServerLimitsGroups( - formValues, - twt + formValues, + twt ), }, }, diff --git a/src/components/utils/utils.ts b/src/components/utils/utils.ts index 5081a6219f..1aa6d70b28 100644 --- a/src/components/utils/utils.ts +++ b/src/components/utils/utils.ts @@ -29,7 +29,7 @@ import { TEMPORARY_LIMIT_NAME, TEMPORARY_LIMIT_VALUE, } from './field-constants'; -import { TemporaryLimitDialogForm } from '../dialogs/network-modifications/line/modification/line-modification-type'; +import { TemporaryLimitFormInfos } from '../dialogs/network-modifications/line/modification/line-modification-type'; export const UNDEFINED_ACCEPTABLE_DURATION = Math.pow(2, 31) - 1; @@ -142,7 +142,7 @@ export const formatTemporaryLimits = (temporaryLimits: TemporaryLimit[]): Tempor }; }); -export const formatToTemporaryLimitsDialogForm = (temporaryLimits: TemporaryLimit[]): TemporaryLimitDialogForm[] => +export const formatToTemporaryLimitsDialogForm = (temporaryLimits: TemporaryLimit[]): TemporaryLimitFormInfos[] => temporaryLimits?.map((limit: TemporaryLimit) => { return { [TEMPORARY_LIMIT_NAME]: limit?.[TEMPORARY_LIMIT_NAME] ?? '', From 1b5768f684eba649f5498a492534d9b1f1f3fb49 Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Fri, 19 Sep 2025 11:23:26 +0200 Subject: [PATCH 5/9] handle TODOs Signed-off-by: Mathieu DEHARBE --- .../dialogs/limits/limits-pane-utils.ts | 37 ++++++------------- .../modification/line-modification-dialog.tsx | 4 +- .../modification/line-modification-type.ts | 5 +-- ...ndings-transformer-modification-dialog.jsx | 4 +- src/components/utils/utils.ts | 4 +- 5 files changed, 20 insertions(+), 34 deletions(-) diff --git a/src/components/dialogs/limits/limits-pane-utils.ts b/src/components/dialogs/limits/limits-pane-utils.ts index 7d2bfeb9d1..956206595d 100644 --- a/src/components/dialogs/limits/limits-pane-utils.ts +++ b/src/components/dialogs/limits/limits-pane-utils.ts @@ -13,7 +13,6 @@ import { ID, LIMIT_SETS_MODIFICATION_TYPE, LIMITS, - MODIFICATION_TYPE, NAME, OPERATIONAL_LIMITS_GROUPS, PERMANENT_LIMIT, @@ -28,7 +27,7 @@ import { import { areArrayElementsUnique, formatTemporaryLimits, - formatToTemporaryLimitsDialogForm, + formatToTemporaryLimitsFormInfos, toModificationOperation, } from 'components/utils/utils'; import yup from 'components/utils/yup-config'; @@ -125,7 +124,9 @@ export const getLimitsEmptyFormData = (id = LIMITS) => { return limitsEmptyFormData(id); }; -export const formatOpLimitGroups = (limitGroups: OperationalLimitsGroup[]): OperationalLimitsGroup[] => { +export const formatOpLimitGroupsToFormInfos = ( + limitGroups: OperationalLimitsGroup[] +): OperationalLimitsGroupFormInfos[] => { if (!limitGroups) { return []; } @@ -134,19 +135,18 @@ export const formatOpLimitGroups = (limitGroups: OperationalLimitsGroup[]): Oper id: opLimitGroup.id + opLimitGroup.applicability, name: opLimitGroup.id, applicability: opLimitGroup.applicability, - modificationType: opLimitGroup.modificationType, currentLimits: { id: opLimitGroup.currentLimits.id, applicability: opLimitGroup.applicability, permanentLimit: opLimitGroup.currentLimits.permanentLimit, - temporaryLimits: formatTemporaryLimits(opLimitGroup.currentLimits.temporaryLimits), + temporaryLimits: formatToTemporaryLimitsFormInfos(opLimitGroup.currentLimits.temporaryLimits), }, }; }); }; export const getAllLimitsFormData = ( - operationalLimitsGroups: OperationalLimitsGroup[] = [], + operationalLimitsGroups: OperationalLimitsGroupFormInfos[] = [], selectedOperationalLimitsGroup1: string | null = null, selectedOperationalLimitsGroup2: string | null = null, id = LIMITS @@ -208,10 +208,10 @@ export const updateTemporaryLimits = ( temporaryLimitsToModify: TemporaryLimit[] // from map server ) => { let updatedTemporaryLimits = limitsDialogForm ?? []; - //add temporary limits from from map server that are not in the form values + //add temporary limits from map server that are not in the form values temporaryLimitsToModify?.forEach((limit: TemporaryLimit) => { if (findTemporaryLimitForm(updatedTemporaryLimits, limit) === undefined) { - updatedTemporaryLimits?.push(temporaryLimitToTemporaryLimitDialogForm(limit)); + updatedTemporaryLimits?.push(temporaryLimitToTemporaryLimitFormInfos(limit)); } }); @@ -235,7 +235,7 @@ export const combineFormAndMapServerLimitsGroups = ( updatedOpLG.forEach((opLG: OperationalLimitsGroupFormInfos) => { const equivalentFromMapServer = mapServerBranch.currentLimits?.find( (currentLimit: CurrentLimits) => - currentLimit.id === opLG.name && currentLimit.applicability === opLG.applicability + currentLimit.id === opLG.name && currentLimit.applicability === opLG[CURRENT_LIMITS][APPLICABIlITY] ); if (equivalentFromMapServer !== undefined) { opLG.currentLimits.temporaryLimits = updateTemporaryLimits( @@ -249,18 +249,17 @@ export const combineFormAndMapServerLimitsGroups = ( mapServerBranch.currentLimits?.forEach((currentLimit: CurrentLimits) => { const equivalentFromNetMod = updatedOpLG.find( (opLG: OperationalLimitsGroupFormInfos) => - currentLimit.id === opLG.name && currentLimit.applicability === opLG.applicability + currentLimit.id === opLG.name && currentLimit.applicability === opLG[CURRENT_LIMITS][APPLICABIlITY] ); if (equivalentFromNetMod === undefined) { updatedOpLG.push({ id: currentLimit.id + currentLimit.applicability, name: currentLimit.id, - applicability: currentLimit.applicability, currentLimits: { id: currentLimit.id, applicability: currentLimit.applicability, permanentLimit: null, - temporaryLimits: formatToTemporaryLimitsDialogForm(currentLimit.temporaryLimits), + temporaryLimits: formatToTemporaryLimitsFormInfos(currentLimit.temporaryLimits), }, }); } @@ -322,14 +321,13 @@ export const addModificationTypeToOpLimitsGroups = ( return { id: limitsGroupForm.id, name: limitsGroupForm.name, - applicability: limitsGroupForm.applicability, currentLimits: currentLimits, modificationType: modificationType, }; }); }; -export const temporaryLimitToTemporaryLimitDialogForm = (temporaryLimit: TemporaryLimit): TemporaryLimitFormInfos => { +export const temporaryLimitToTemporaryLimitFormInfos = (temporaryLimit: TemporaryLimit): TemporaryLimitFormInfos => { return { [TEMPORARY_LIMIT_NAME]: temporaryLimit.name, [TEMPORARY_LIMIT_DURATION]: temporaryLimit.acceptableDuration, @@ -337,14 +335,3 @@ export const temporaryLimitToTemporaryLimitDialogForm = (temporaryLimit: Tempora [DELETION_MARK]: false, }; }; - -export const temporaryLimitDialogFormToTemporaryLimit = (temporaryLimit: TemporaryLimitFormInfos): TemporaryLimit => { - return { - [TEMPORARY_LIMIT_NAME]: temporaryLimit.name, - [TEMPORARY_LIMIT_DURATION]: temporaryLimit.acceptableDuration, - [TEMPORARY_LIMIT_VALUE]: temporaryLimit.value, - [MODIFICATION_TYPE]: temporaryLimit[DELETION_MARK] - ? TEMPORARY_LIMIT_MODIFICATION_TYPE.DELETE - : TEMPORARY_LIMIT_MODIFICATION_TYPE.MODIFY_OR_ADD, - }; -}; diff --git a/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx b/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx index 1ac9b45a3c..876ff8a45d 100644 --- a/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx +++ b/src/components/dialogs/network-modifications/line/modification/line-modification-dialog.tsx @@ -58,7 +58,7 @@ import { getLimitsValidationSchema, addModificationTypeToOpLimitsGroups, getAllLimitsFormData, - formatOpLimitGroups, + formatOpLimitGroupsToFormInfos, combineFormAndMapServerLimitsGroups, addOperationTypeToSelectedOpLG, } from '../../../limits/limits-pane-utils'; @@ -205,7 +205,7 @@ const LineModificationDialog = ({ b2: convertInputValue(FieldType.B2, lineModification.b2?.value ?? null), }), ...getAllLimitsFormData( - formatOpLimitGroups(lineModification.operationalLimitsGroups), // TODO : aller typer tout ça plus proprement => doit donner un type form au fnal + formatOpLimitGroupsToFormInfos(lineModification.operationalLimitsGroups), lineModification.selectedOperationalLimitsGroup1?.value ?? null, lineModification.selectedOperationalLimitsGroup2?.value ?? null ), diff --git a/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts b/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts index d3eda5e904..49e56dab43 100644 --- a/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts +++ b/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts @@ -80,13 +80,12 @@ export interface OperationalLimitsGroupFormInfos { // "ID" from the map server is stored as NAME in the form because of this [ID]: string; [NAME]: string; - [APPLICABIlITY]?: string; [CURRENT_LIMITS]: CurrentLimitsFormInfos; } export interface CurrentLimitsFormInfos { - [ID]: string; // TODO : needed here or only in OperationalLimitsGroupDialogForm ?? - [APPLICABIlITY]?: string; // TODO : needed here or only in OperationalLimitsGroupDialogForm ?? + [ID]: string; + [APPLICABIlITY]?: string; [PERMANENT_LIMIT]: number | null; [TEMPORARY_LIMITS]: TemporaryLimitFormInfos[]; } 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 0fb2e315a4..5a19b64513 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 @@ -91,7 +91,7 @@ import { import { addModificationTypeToOpLimitsGroups, addOperationTypeToSelectedOpLG, - formatOpLimitGroups, + formatOpLimitGroupsToFormInfos, getAllLimitsFormData, getLimitsEmptyFormData, getLimitsValidationSchema, @@ -247,7 +247,7 @@ const TwoWindingsTransformerModificationDialog = ({ }), ...getStateEstimationEditData(STATE_ESTIMATION, twtModification), ...getAllLimitsFormData( - formatOpLimitGroups(twtModification.operationalLimitsGroups), + formatOpLimitGroupsToFormInfos(twtModification.operationalLimitsGroups), twtModification.selectedOperationalLimitsGroup1?.value ?? null, twtModification.selectedOperationalLimitsGroup2?.value ?? null ), diff --git a/src/components/utils/utils.ts b/src/components/utils/utils.ts index 1aa6d70b28..11844d39e9 100644 --- a/src/components/utils/utils.ts +++ b/src/components/utils/utils.ts @@ -142,13 +142,13 @@ export const formatTemporaryLimits = (temporaryLimits: TemporaryLimit[]): Tempor }; }); -export const formatToTemporaryLimitsDialogForm = (temporaryLimits: TemporaryLimit[]): TemporaryLimitFormInfos[] => +export const formatToTemporaryLimitsFormInfos = (temporaryLimits: TemporaryLimit[]): TemporaryLimitFormInfos[] => temporaryLimits?.map((limit: TemporaryLimit) => { return { [TEMPORARY_LIMIT_NAME]: limit?.[TEMPORARY_LIMIT_NAME] ?? '', [TEMPORARY_LIMIT_VALUE]: limit?.[TEMPORARY_LIMIT_VALUE] ?? null, [TEMPORARY_LIMIT_DURATION]: limit?.[TEMPORARY_LIMIT_DURATION] ?? null, - [DELETION_MARK]: false, + [DELETION_MARK]: limit?.modificationType === TEMPORARY_LIMIT_MODIFICATION_TYPE.DELETE, }; }); From c970d22dad38c9e4a90e9b14000e4d6567044d49 Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Fri, 19 Sep 2025 14:15:23 +0200 Subject: [PATCH 6/9] deletionMarkFormName Signed-off-by: Mathieu DEHARBE --- .../dialogs/limits/temporary-limits-table.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/components/dialogs/limits/temporary-limits-table.tsx b/src/components/dialogs/limits/temporary-limits-table.tsx index 07b46d81af..d730835701 100644 --- a/src/components/dialogs/limits/temporary-limits-table.tsx +++ b/src/components/dialogs/limits/temporary-limits-table.tsx @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { useState } from 'react'; +import { useCallback, useState } from 'react'; import { useFieldArray, useFormContext } from 'react-hook-form'; import { Box, Grid, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material'; import { @@ -145,13 +145,18 @@ function TemporaryLimitsTable({ ); } + const deletionMarkFormName = useCallback( + (index: number) => `${arrayFormName}[${index}].${DELETION_MARK}`, + [arrayFormName] + ); + const renderTableRow = (rowId: string, index: number) => ( setHoveredRowIndex(index)} onMouseLeave={() => setHoveredRowIndex(-1)}> {columnsDefinition.map((column) => renderTableCell(rowId, index, column))} setValue(`${arrayFormName}[${index}].${DELETION_MARK}`, true, { shouldDirty: true })} + onClick={() => setValue(deletionMarkFormName(index), true, { shouldDirty: true })} > @@ -164,7 +169,7 @@ function TemporaryLimitsTable({ {fields.map( (value: Record<'id', string>, index: number) => - !getValues(`${arrayFormName}[${index}].${DELETION_MARK}`) && renderTableRow(value.id, index) + !getValues(deletionMarkFormName(index)) && renderTableRow(value.id, index) )} ); From 6b8df158dc3ec11263eac1e78e6bde568e528c4c Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Fri, 19 Sep 2025 15:15:37 +0200 Subject: [PATCH 7/9] type strongly OperationalLimitsGroupFormInfos and remove applicability from CurrentLimitsFormInfos Signed-off-by: Mathieu DEHARBE --- .../limits/limits-groups-contextual-menu.tsx | 6 +++--- src/components/dialogs/limits/limits-pane-utils.ts | 14 +++++++------- src/components/dialogs/limits/limits-pane.tsx | 12 +++++++----- .../limits/operational-limits-groups-tabs.tsx | 5 +++-- .../limits/selected-operational-limit-group.tsx | 8 ++++---- .../line/modification/line-modification-type.ts | 2 +- src/components/utils/utils.ts | 1 - 7 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/components/dialogs/limits/limits-groups-contextual-menu.tsx b/src/components/dialogs/limits/limits-groups-contextual-menu.tsx index b9edc7cc1c..d5598c4fe3 100644 --- a/src/components/dialogs/limits/limits-groups-contextual-menu.tsx +++ b/src/components/dialogs/limits/limits-groups-contextual-menu.tsx @@ -18,9 +18,9 @@ import ListItemIcon from '@mui/material/ListItemIcon'; import { ContentCopy, Delete, Edit } from '@mui/icons-material'; import ListItemText from '@mui/material/ListItemText'; import { useIntl } from 'react-intl'; -import { OperationalLimitsGroup } from '../../../services/network-modification-types'; import { PopoverProps } from '@mui/material/Popover'; import { APPLICABILITY } from '../../network/constants'; +import { OperationalLimitsGroupFormInfos } from '../network-modifications/line/modification/line-modification-type'; export interface LimitsGroupsContextualMenuProps { parentFormName: string; @@ -81,11 +81,11 @@ export function LimitsGroupsContextualMenu({ const handleDuplicateTab = () => { let newName: string = ''; if (indexSelectedLimitSet !== null) { - const duplicatedLimits1: OperationalLimitsGroup = getValues( + const duplicatedLimits1: OperationalLimitsGroupFormInfos = getValues( `${operationalLimitsGroupsFormName}[${indexSelectedLimitSet}]` ); newName = duplicatedLimits1.name + '_COPY'; - const newLimitsGroup1: OperationalLimitsGroup = { + const newLimitsGroup1: OperationalLimitsGroupFormInfos = { ...duplicatedLimits1, [ID]: newName, }; diff --git a/src/components/dialogs/limits/limits-pane-utils.ts b/src/components/dialogs/limits/limits-pane-utils.ts index 956206595d..3064e5230f 100644 --- a/src/components/dialogs/limits/limits-pane-utils.ts +++ b/src/components/dialogs/limits/limits-pane-utils.ts @@ -137,7 +137,6 @@ export const formatOpLimitGroupsToFormInfos = ( applicability: opLimitGroup.applicability, currentLimits: { id: opLimitGroup.currentLimits.id, - applicability: opLimitGroup.applicability, permanentLimit: opLimitGroup.currentLimits.permanentLimit, temporaryLimits: formatToTemporaryLimitsFormInfos(opLimitGroup.currentLimits.temporaryLimits), }, @@ -204,10 +203,10 @@ const findTemporaryLimitForm = (temporaryLimits: TemporaryLimitFormInfos[], limi ); export const updateTemporaryLimits = ( - limitsDialogForm: TemporaryLimitFormInfos[], + temporaryLimitsFormInfos: TemporaryLimitFormInfos[], temporaryLimitsToModify: TemporaryLimit[] // from map server ) => { - let updatedTemporaryLimits = limitsDialogForm ?? []; + let updatedTemporaryLimits = temporaryLimitsFormInfos ?? []; //add temporary limits from map server that are not in the form values temporaryLimitsToModify?.forEach((limit: TemporaryLimit) => { if (findTemporaryLimitForm(updatedTemporaryLimits, limit) === undefined) { @@ -235,7 +234,7 @@ export const combineFormAndMapServerLimitsGroups = ( updatedOpLG.forEach((opLG: OperationalLimitsGroupFormInfos) => { const equivalentFromMapServer = mapServerBranch.currentLimits?.find( (currentLimit: CurrentLimits) => - currentLimit.id === opLG.name && currentLimit.applicability === opLG[CURRENT_LIMITS][APPLICABIlITY] + currentLimit.id === opLG.name && currentLimit.applicability === opLG[APPLICABIlITY] ); if (equivalentFromMapServer !== undefined) { opLG.currentLimits.temporaryLimits = updateTemporaryLimits( @@ -249,15 +248,15 @@ export const combineFormAndMapServerLimitsGroups = ( mapServerBranch.currentLimits?.forEach((currentLimit: CurrentLimits) => { const equivalentFromNetMod = updatedOpLG.find( (opLG: OperationalLimitsGroupFormInfos) => - currentLimit.id === opLG.name && currentLimit.applicability === opLG[CURRENT_LIMITS][APPLICABIlITY] + currentLimit.id === opLG.name && currentLimit.applicability === opLG[APPLICABIlITY] ); if (equivalentFromNetMod === undefined) { updatedOpLG.push({ id: currentLimit.id + currentLimit.applicability, name: currentLimit.id, + applicability: currentLimit.applicability, currentLimits: { id: currentLimit.id, - applicability: currentLimit.applicability, permanentLimit: null, temporaryLimits: formatToTemporaryLimitsFormInfos(currentLimit.temporaryLimits), }, @@ -313,7 +312,7 @@ export const addModificationTypeToOpLimitsGroups = ( ); const currentLimits: CurrentLimits = { id: limitsGroupForm[CURRENT_LIMITS][ID], - applicability: limitsGroupForm[CURRENT_LIMITS]?.[APPLICABIlITY], + applicability: limitsGroupForm?.[APPLICABIlITY], permanentLimit: limitsGroupForm[CURRENT_LIMITS]?.[PERMANENT_LIMIT] ?? null, temporaryLimits: temporaryLimits ?? [], }; @@ -321,6 +320,7 @@ export const addModificationTypeToOpLimitsGroups = ( return { id: limitsGroupForm.id, name: limitsGroupForm.name, + applicability: limitsGroupForm.applicability, currentLimits: currentLimits, modificationType: modificationType, }; diff --git a/src/components/dialogs/limits/limits-pane.tsx b/src/components/dialogs/limits/limits-pane.tsx index 727a629460..4187a20a36 100644 --- a/src/components/dialogs/limits/limits-pane.tsx +++ b/src/components/dialogs/limits/limits-pane.tsx @@ -17,7 +17,7 @@ import { LimitsSidePane } from './limits-side-pane'; import { SelectedOperationalLimitGroup } from './selected-operational-limit-group.js'; import { useCallback, useRef, useState } from 'react'; import { useWatch } from 'react-hook-form'; -import { CurrentLimits, OperationalLimitsGroup } from '../../../services/network-modification-types'; +import { CurrentLimits } from '../../../services/network-modification-types'; import { OperationalLimitsGroupsTabs } from './operational-limits-groups-tabs'; import { tabStyles } from 'components/utils/tab-utils'; import IconButton from '@mui/material/IconButton'; @@ -26,6 +26,7 @@ import GridSection from '../commons/grid-section'; import { styles } from '../dialog-utils'; import AddIcon from '@mui/icons-material/ControlPoint'; import { APPLICABILITY } from '../../network/constants'; +import { OperationalLimitsGroupFormInfos } from '../network-modifications/line/modification/line-modification-type'; export interface LimitsPaneProps { id?: string; @@ -44,7 +45,7 @@ export function LimitsPane({ const myRef: any = useRef(null); - const limitsGroups: OperationalLimitsGroup[] = useWatch({ + const limitsGroups: OperationalLimitsGroupFormInfos[] = useWatch({ name: `${id}.${OPERATIONAL_LIMITS_GROUPS}`, }); @@ -72,10 +73,11 @@ export function LimitsPane({ } // checks if limit sets with that name already exist - const sameNameInLs: OperationalLimitsGroup[] = limitsGroups + const sameNameInLs: OperationalLimitsGroupFormInfos[] = limitsGroups .filter((_ls, index: number) => index !== indexSelectedLimitSet) .filter( - (limitsGroup: OperationalLimitsGroup) => limitsGroup.name.trim() === editedLimitGroupName.trim() + (limitsGroup: OperationalLimitsGroupFormInfos) => + limitsGroup.name.trim() === editedLimitGroupName.trim() ); // only 2 limit sets with the same name are allowed and only if there have SIDE1 and SIDE2 applicability @@ -151,7 +153,7 @@ export function LimitsPane({ {indexSelectedLimitSet !== null && limitsGroups.map( - (operationalLimitsGroup: OperationalLimitsGroup, index: number) => + (operationalLimitsGroup: OperationalLimitsGroupFormInfos, index: number) => index === indexSelectedLimitSet && ( >; checkLimitSetUnicity: (editedLimitGroupName: string, newSelectedApplicability: string) => string; @@ -285,7 +286,7 @@ export const OperationalLimitsGroupsTabs = forwardRef - {limitsGroups.map((opLg: OperationalLimitsGroup, index: number) => ( + {limitsGroups.map((opLg: OperationalLimitsGroupFormInfos, index: number) => ( setHoveredRowIndex(index)} onMouseLeave={() => setHoveredRowIndex(-1)} diff --git a/src/components/dialogs/limits/selected-operational-limit-group.tsx b/src/components/dialogs/limits/selected-operational-limit-group.tsx index 58c68f2412..e59e9fcc29 100644 --- a/src/components/dialogs/limits/selected-operational-limit-group.tsx +++ b/src/components/dialogs/limits/selected-operational-limit-group.tsx @@ -8,9 +8,9 @@ import { useMemo } from 'react'; import { useWatch } from 'react-hook-form'; import { Box } from '@mui/material'; import { AutocompleteInput } from '@gridsuite/commons-ui'; -import { OperationalLimitsGroup } from '../../../services/network-modification-types'; import { APPLICABILITY } from '../../network/constants'; import { useIntl } from 'react-intl'; +import { OperationalLimitsGroupFormInfos } from '../network-modifications/line/modification/line-modification-type'; export interface SelectedOperationalLimitGroupProps { selectedFormName: string; @@ -29,7 +29,7 @@ export const SelectedOperationalLimitGroup = ({ previousValue, isABranchModif, }: Readonly) => { - const optionsValues: OperationalLimitsGroup[] = useWatch({ + const optionsValues: OperationalLimitsGroupFormInfos[] = useWatch({ name: optionsFormName, }); const intl = useIntl(); @@ -38,12 +38,12 @@ export const SelectedOperationalLimitGroup = ({ const finalOptions: string[] = optionsValues ? optionsValues .filter( - (optionObj: OperationalLimitsGroup) => + (optionObj: OperationalLimitsGroupFormInfos) => optionObj.applicability && (optionObj.applicability === filteredApplicability || optionObj.applicability === APPLICABILITY.EQUIPMENT.id) ) - .map((filteredoptionObj: OperationalLimitsGroup) => filteredoptionObj.name) + .map((filteredoptionObj: OperationalLimitsGroupFormInfos) => filteredoptionObj.name) .filter((id: string) => id != null) : []; if (isABranchModif) { diff --git a/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts b/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts index 49e56dab43..758436c397 100644 --- a/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts +++ b/src/components/dialogs/network-modifications/line/modification/line-modification-type.ts @@ -79,13 +79,13 @@ export interface OperationalLimitsGroupFormInfos { // here 'id' is a concatenation of NAME and APPLICABIlITY because 2 limits sets on side1 and 2 may have the same name // "ID" from the map server is stored as NAME in the form because of this [ID]: string; + [APPLICABIlITY]?: string; [NAME]: string; [CURRENT_LIMITS]: CurrentLimitsFormInfos; } export interface CurrentLimitsFormInfos { [ID]: string; - [APPLICABIlITY]?: string; [PERMANENT_LIMIT]: number | null; [TEMPORARY_LIMITS]: TemporaryLimitFormInfos[]; } diff --git a/src/components/utils/utils.ts b/src/components/utils/utils.ts index 11844d39e9..40944f57b9 100644 --- a/src/components/utils/utils.ts +++ b/src/components/utils/utils.ts @@ -138,7 +138,6 @@ export const formatTemporaryLimits = (temporaryLimits: TemporaryLimit[]): Tempor [TEMPORARY_LIMIT_VALUE]: limit?.[TEMPORARY_LIMIT_VALUE] ?? null, [TEMPORARY_LIMIT_DURATION]: limit?.[TEMPORARY_LIMIT_DURATION] ?? null, [MODIFICATION_TYPE]: limit?.[MODIFICATION_TYPE] ?? null, - [DELETION_MARK]: limit?.modificationType === TEMPORARY_LIMIT_MODIFICATION_TYPE.DELETE, }; }); From c826b842548db77ee3cb18a1fdfdb0b621125633 Mon Sep 17 00:00:00 2001 From: Mathieu Deharbe <148252167+Mathieu-Deharbe@users.noreply.github.com> Date: Tue, 23 Sep 2025 17:39:19 +0200 Subject: [PATCH 8/9] are to is Co-authored-by: Florent MILLOT <75525996+flomillot@users.noreply.github.com> --- src/components/dialogs/limits/limits-pane-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/dialogs/limits/limits-pane-utils.ts b/src/components/dialogs/limits/limits-pane-utils.ts index 3064e5230f..d7198715d8 100644 --- a/src/components/dialogs/limits/limits-pane-utils.ts +++ b/src/components/dialogs/limits/limits-pane-utils.ts @@ -295,7 +295,7 @@ export function addOperationTypeToSelectedOpLG( /** * converts the limits groups into a modification limits group * ie mostly add the ADD, MODIFY, MODIFY_OR_ADD, DELETE and REPLACE tags to the data using a delta between the form and the network values - * note : for now only MODIFY_OR_ADD are handled, the others have been disabled for various reasons + * note : for now only MODIFY_OR_ADD is handled, the others have been disabled for various reasons * * @param limitsGroupsForm current data from the form */ From ead6cca1628b94bc77e72e50aa9a668cf07b0347 Mon Sep 17 00:00:00 2001 From: Mathieu DEHARBE Date: Tue, 23 Sep 2025 18:00:39 +0200 Subject: [PATCH 9/9] remove useless variable Signed-off-by: Mathieu DEHARBE --- src/components/dialogs/limits/limits-pane-utils.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/components/dialogs/limits/limits-pane-utils.ts b/src/components/dialogs/limits/limits-pane-utils.ts index 3064e5230f..54738f7dc6 100644 --- a/src/components/dialogs/limits/limits-pane-utils.ts +++ b/src/components/dialogs/limits/limits-pane-utils.ts @@ -305,8 +305,6 @@ export const addModificationTypeToOpLimitsGroups = ( let modificationLimitsGroupsForm: OperationalLimitsGroupFormInfos[] = sanitizeLimitsGroups(limitsGroupsForm); return modificationLimitsGroupsForm.map((limitsGroupForm: OperationalLimitsGroupFormInfos) => { - const modificationType: string = LIMIT_SETS_MODIFICATION_TYPE.MODIFY_OR_ADD; - const temporaryLimits: TemporaryLimit[] = addModificationTypeToTemporaryLimits( sanitizeLimitNames(limitsGroupForm[CURRENT_LIMITS]?.[TEMPORARY_LIMITS]) ); @@ -322,7 +320,7 @@ export const addModificationTypeToOpLimitsGroups = ( name: limitsGroupForm.name, applicability: limitsGroupForm.applicability, currentLimits: currentLimits, - modificationType: modificationType, + modificationType: LIMIT_SETS_MODIFICATION_TYPE.MODIFY_OR_ADD, }; }); };