@gridsuite/commons-ui 0.241.1 → 0.242.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/README.md +4 -0
  2. package/dist/components/composite/grid/grid-item.d.ts +2 -1
  3. package/dist/components/composite/grid/grid-item.js +9 -2
  4. package/dist/components/ui/inputs/checkbox-autocomplete/checkbox-autocomplete.d.ts +1 -2
  5. package/dist/features/index.js +87 -3
  6. package/dist/features/network-modification-table/index.js +2 -1
  7. package/dist/features/network-modification-table/use-modifications-drag-and-drop.js +2 -1
  8. package/dist/features/network-modification-table/utils.d.ts +1 -0
  9. package/dist/features/network-modification-table/utils.js +5 -1
  10. package/dist/features/network-modifications/battery/creation/BatteryCreationForm.js +3 -0
  11. package/dist/features/network-modifications/battery/creation/batteryCreation.utils.js +3 -0
  12. package/dist/features/network-modifications/battery/modification/BatteryDialogHeader.js +3 -0
  13. package/dist/features/network-modifications/battery/modification/BatteryDialogTabsContent.js +3 -0
  14. package/dist/features/network-modifications/battery/modification/batteryModification.utils.js +3 -0
  15. package/dist/features/network-modifications/common/connectivity/connectivityForm.utils.d.ts +71 -2
  16. package/dist/features/network-modifications/common/connectivity/connectivityForm.utils.js +26 -8
  17. package/dist/features/network-modifications/common/connectivity/index.js +3 -1
  18. package/dist/features/network-modifications/common/currentLimits/LimitsPane.d.ts +7 -0
  19. package/dist/features/network-modifications/common/currentLimits/LimitsPane.js +243 -0
  20. package/dist/features/network-modifications/common/currentLimits/LimitsTagChip.d.ts +9 -0
  21. package/dist/features/network-modifications/common/currentLimits/LimitsTagChip.js +29 -0
  22. package/dist/features/network-modifications/common/currentLimits/SelectedOperationalLimitGroup.d.ts +9 -0
  23. package/dist/features/network-modifications/common/currentLimits/SelectedOperationalLimitGroup.js +100 -0
  24. package/dist/features/network-modifications/common/currentLimits/index.d.ts +12 -0
  25. package/dist/features/network-modifications/common/currentLimits/index.js +47 -0
  26. package/dist/features/network-modifications/common/currentLimits/limits.types.d.ts +52 -0
  27. package/dist/features/network-modifications/common/currentLimits/limits.types.js +17 -0
  28. package/dist/features/network-modifications/common/currentLimits/limitsEditor/LimitsEditor.d.ts +10 -0
  29. package/dist/features/network-modifications/common/currentLimits/limitsEditor/LimitsEditor.js +285 -0
  30. package/dist/features/network-modifications/common/currentLimits/limitsEditor/LimitsPropertiesSideStack.d.ts +5 -0
  31. package/dist/features/network-modifications/common/currentLimits/limitsEditor/LimitsPropertiesSideStack.js +184 -0
  32. package/dist/features/network-modifications/common/currentLimits/limitsEditor/TemporaryLimitsTable.d.ts +14 -0
  33. package/dist/features/network-modifications/common/currentLimits/limitsEditor/TemporaryLimitsTable.js +166 -0
  34. package/dist/features/network-modifications/common/currentLimits/limitsEditor/index.d.ts +10 -0
  35. package/dist/features/network-modifications/common/currentLimits/limitsEditor/index.js +10 -0
  36. package/dist/features/network-modifications/common/currentLimits/limitsEditor/limitsChart.d.ts +11 -0
  37. package/dist/features/network-modifications/common/currentLimits/limitsEditor/limitsChart.js +177 -0
  38. package/dist/features/network-modifications/common/currentLimits/limitsPane.utils.d.ts +213 -0
  39. package/dist/features/network-modifications/common/currentLimits/limitsPane.utils.js +337 -0
  40. package/dist/features/network-modifications/common/currentLimits/operationalLimitsGroups/LimitsGroupsContextualMenu.d.ts +25 -0
  41. package/dist/features/network-modifications/common/currentLimits/operationalLimitsGroups/LimitsGroupsContextualMenu.js +92 -0
  42. package/dist/features/network-modifications/common/currentLimits/operationalLimitsGroups/LimitsPropertiesStack.d.ts +10 -0
  43. package/dist/features/network-modifications/common/currentLimits/operationalLimitsGroups/LimitsPropertiesStack.js +25 -0
  44. package/dist/features/network-modifications/common/currentLimits/operationalLimitsGroups/OperationalLimitsGroupTabLabel.d.ts +10 -0
  45. package/dist/features/network-modifications/common/currentLimits/operationalLimitsGroups/OperationalLimitsGroupTabLabel.js +73 -0
  46. package/dist/features/network-modifications/common/currentLimits/operationalLimitsGroups/OperationalLimitsGroups.d.ts +16 -0
  47. package/dist/features/network-modifications/common/currentLimits/operationalLimitsGroups/OperationalLimitsGroups.js +121 -0
  48. package/dist/features/network-modifications/common/currentLimits/operationalLimitsGroups/index.d.ts +11 -0
  49. package/dist/features/network-modifications/common/currentLimits/operationalLimitsGroups/index.js +12 -0
  50. package/dist/features/network-modifications/common/currentLimits/operationalLimitsGroups/operationalLimitsGroups.types.d.ts +71 -0
  51. package/dist/features/network-modifications/common/currentLimits/operationalLimitsGroups/operationalLimitsGroups.types.js +15 -0
  52. package/dist/features/network-modifications/common/currentLimits/operationalLimitsGroups/operationalLimitsGroupsStyles.d.ts +46 -0
  53. package/dist/features/network-modifications/common/currentLimits/operationalLimitsGroups/operationalLimitsGroupsStyles.js +45 -0
  54. package/dist/features/network-modifications/common/index.d.ts +1 -0
  55. package/dist/features/network-modifications/common/index.js +50 -2
  56. package/dist/features/network-modifications/common/measurements/branchActiveReactivePowerForm.utils.d.ts +11 -0
  57. package/dist/features/network-modifications/common/measurements/branchActiveReactivePowerForm.utils.js +6 -4
  58. package/dist/features/network-modifications/common/measurements/index.js +2 -1
  59. package/dist/features/network-modifications/common/reactiveLimits/reactiveCapabilityCurve/ReactiveCapabilityCurveTableForm.js +1 -1
  60. package/dist/features/network-modifications/common/voltageRegulation/VoltageRegulationForm.js +3 -7
  61. package/dist/features/network-modifications/equipmentDeletion/EquipmentDeletionForm.js +3 -0
  62. package/dist/features/network-modifications/generator/creation/GeneratorCreationForm.js +9 -6
  63. package/dist/features/network-modifications/generator/creation/generatorCreation.utils.js +3 -0
  64. package/dist/features/network-modifications/generator/modification/GeneratorDialogHeader.js +3 -0
  65. package/dist/features/network-modifications/generator/modification/GeneratorDialogTabsContent.js +9 -6
  66. package/dist/features/network-modifications/generator/modification/generatorModification.utils.js +3 -0
  67. package/dist/features/network-modifications/index.d.ts +1 -0
  68. package/dist/features/network-modifications/index.js +85 -2
  69. package/dist/features/network-modifications/line/catalog/index.d.ts +8 -0
  70. package/dist/features/network-modifications/line/catalog/index.js +14 -0
  71. package/dist/features/network-modifications/line/catalog/lineCatalog.type.d.ts +66 -0
  72. package/dist/features/network-modifications/line/catalog/lineCatalog.type.js +7 -0
  73. package/dist/features/network-modifications/line/catalog/segment.utils.d.ts +90 -0
  74. package/dist/features/network-modifications/line/catalog/segment.utils.js +100 -0
  75. package/dist/features/network-modifications/line/characteristics/LineCharacteristicsPane.d.ts +8 -0
  76. package/dist/features/network-modifications/line/characteristics/LineCharacteristicsPane.js +152 -0
  77. package/dist/features/network-modifications/line/characteristics/index.d.ts +9 -0
  78. package/dist/features/network-modifications/line/characteristics/index.js +9 -0
  79. package/dist/features/network-modifications/line/characteristics/lineCharacteristicsPane.types.d.ts +14 -0
  80. package/dist/features/network-modifications/line/characteristics/lineCharacteristicsPane.types.js +1 -0
  81. package/dist/features/network-modifications/line/characteristics/lineCharacteristicsPane.utils.d.ts +52 -0
  82. package/dist/features/network-modifications/line/characteristics/lineCharacteristicsPane.utils.js +53 -0
  83. package/dist/features/network-modifications/line/common/LineDialogHeader.d.ts +6 -0
  84. package/dist/features/network-modifications/line/common/LineDialogHeader.js +103 -0
  85. package/dist/features/network-modifications/line/common/LineDialogTabs.d.ts +9 -0
  86. package/dist/features/network-modifications/line/common/LineDialogTabs.js +61 -0
  87. package/dist/features/network-modifications/line/common/LineDialogTabsContent.d.ts +8 -0
  88. package/dist/features/network-modifications/line/common/LineDialogTabsContent.js +96 -0
  89. package/dist/features/network-modifications/line/common/LineForm.d.ts +6 -0
  90. package/dist/features/network-modifications/line/common/LineForm.js +50 -0
  91. package/dist/features/network-modifications/line/common/index.d.ts +12 -0
  92. package/dist/features/network-modifications/line/common/index.js +13 -0
  93. package/dist/features/network-modifications/line/common/line.types.d.ts +47 -0
  94. package/dist/features/network-modifications/line/common/line.types.js +1 -0
  95. package/dist/features/network-modifications/line/common/line.utils.d.ts +13 -0
  96. package/dist/features/network-modifications/line/common/line.utils.js +34 -0
  97. package/dist/features/network-modifications/line/creation/index.d.ts +8 -0
  98. package/dist/features/network-modifications/line/creation/index.js +7 -0
  99. package/dist/features/network-modifications/line/creation/lineCreation.types.d.ts +39 -0
  100. package/dist/features/network-modifications/line/creation/lineCreation.types.js +1 -0
  101. package/dist/features/network-modifications/line/creation/lineCreation.utils.d.ts +151 -0
  102. package/dist/features/network-modifications/line/creation/lineCreation.utils.js +172 -0
  103. package/dist/features/network-modifications/line/index.d.ts +10 -0
  104. package/dist/features/network-modifications/line/index.js +37 -0
  105. package/dist/features/network-modifications/load/common/LoadDialogHeader.js +3 -0
  106. package/dist/features/network-modifications/load/modification/loadModification.utils.js +3 -0
  107. package/dist/features/network-modifications/shunt-compensator/common/CharacteristicsForm.js +7 -6
  108. package/dist/features/network-modifications/shunt-compensator/creation/ShuntCompensatorCreationForm.js +3 -0
  109. package/dist/features/network-modifications/shunt-compensator/creation/shuntCompensatorCreation.utils.js +3 -0
  110. package/dist/features/network-modifications/shunt-compensator/modification/ShuntCompensatorModificationForm.js +3 -0
  111. package/dist/features/network-modifications/shunt-compensator/modification/shuntCompensatorModification.utils.js +3 -0
  112. package/dist/features/network-modifications/substation/creation/SubstationCreationForm.js +3 -0
  113. package/dist/features/network-modifications/substation/modification/SubstationModificationForm.js +3 -0
  114. package/dist/features/network-modifications/voltageLevel/creation/VoltageLevelCreationForm.js +3 -0
  115. package/dist/features/network-modifications/voltageLevel/creation/index.js +3 -0
  116. package/dist/features/network-modifications/voltageLevel/creation/tabs/substationTab/SubstationCreationSection.js +3 -0
  117. package/dist/features/network-modifications/voltageLevel/creation/voltageLevelCreation.utils.js +3 -0
  118. package/dist/features/network-modifications/voltageLevel/index.js +3 -0
  119. package/dist/features/network-modifications/voltageLevel/modification/VoltageLevelModificationForm.js +4 -1
  120. package/dist/features/parameters/common/contingency-table/contingency-table.js +22 -10
  121. package/dist/features/parameters/common/contingency-table/types.d.ts +7 -8
  122. package/dist/features/parameters/common/contingency-table/utils.d.ts +13 -0
  123. package/dist/features/parameters/common/contingency-table/utils.js +31 -0
  124. package/dist/features/parameters/loadflow/load-flow-general-parameters.js +5 -1
  125. package/dist/features/parameters/security-analysis/security-analysis-parameters-form.js +19 -31
  126. package/dist/hooks/useModificationLabelComputer.js +1 -0
  127. package/dist/index.js +87 -3
  128. package/dist/translations/en/networkModificationsEn.d.ts +28 -0
  129. package/dist/translations/en/networkModificationsEn.js +28 -0
  130. package/dist/translations/en/parameters.d.ts +3 -1
  131. package/dist/translations/en/parameters.js +3 -1
  132. package/dist/translations/fr/networkModificationsFr.d.ts +28 -0
  133. package/dist/translations/fr/networkModificationsFr.js +28 -0
  134. package/dist/translations/fr/parameters.d.ts +3 -1
  135. package/dist/translations/fr/parameters.js +3 -1
  136. package/dist/utils/constants/fieldConstants.d.ts +47 -1
  137. package/dist/utils/constants/fieldConstants.js +46 -0
  138. package/dist/utils/types/modificationType.d.ts +4 -0
  139. package/dist/utils/types/modificationType.js +5 -0
  140. package/package.json +11 -4
@@ -0,0 +1,337 @@
1
+ import { object, array, boolean, string, number } from "yup";
2
+ import { OPERATIONAL_LIMITS_GROUPS_MODIFICATION_TYPE } from "./operationalLimitsGroups/operationalLimitsGroups.types.js";
3
+ import { FieldConstants } from "../../../../utils/constants/fieldConstants.js";
4
+ import { toModificationOperation } from "../../../../utils/conversionUtils.js";
5
+ import "../../../../utils/types/equipmentType.js";
6
+ import { OperationType } from "../../../../utils/types/network-modification-types.js";
7
+ import { areArrayElementsUnique } from "../../../../utils/functions.js";
8
+ import "react/jsx-runtime";
9
+ import "@mui/icons-material";
10
+ import { sanitizeString } from "../../../../utils/ts-utils.js";
11
+ import { APPLICABILITY, TEMPORARY_LIMIT_MODIFICATION_TYPE } from "./limits.types.js";
12
+ import "react";
13
+ import "react-hook-form";
14
+ import { creationPropertiesSchema } from "../properties/propertyUtils.js";
15
+ import "@mui/material";
16
+ import "react-intl";
17
+ import "../../../../components/ui/overflowableText/OverflowableText.js";
18
+ import "localized-countries";
19
+ import "localized-countries/data/fr";
20
+ import "localized-countries/data/en";
21
+ import "notistack";
22
+ import "../../../../components/ui/reactHookForm/provider/CustomFormProvider.js";
23
+ import "../../../../components/ui/treeViewFinder/TreeViewFinder.js";
24
+ import "../../../../components/ui/reactHookForm/numbers/RangeInput.js";
25
+ import "@material-symbols/svg-400/outlined/left_panel_open.svg?react";
26
+ import "@material-symbols/svg-400/outlined/arrows_output.svg?react";
27
+ import "@material-symbols/svg-400/outlined/arrows_input.svg?react";
28
+ import "@material-symbols/svg-400/outlined/left_panel_close.svg?react";
29
+ import "@material-symbols/svg-400/outlined/add_notes.svg?react";
30
+ import "../../../../components/ui/dialogs/descriptionModificationDialog/DescriptionModificationDialog.js";
31
+ import "../../../../components/ui/reactHookForm/expandableInput/ExpandableInput.js";
32
+ import "../../../../components/ui/reactHookForm/directory-item-input/directory-item-utils.js";
33
+ import "@hello-pangea/dnd";
34
+ import "../../../../components/ui/dialogs/elementSaveDialog/ElementSaveDialog.js";
35
+ import "../../../../components/ui/snackbarProvider/SnackbarProvider.js";
36
+ import "mui-nested-menu";
37
+ import "react-resizable-panels";
38
+ import "react-papaparse";
39
+ function hasDuplicateOperationalLimitsGroups(context) {
40
+ const limitsGroup = context.parent;
41
+ const operationalLimitsGroups = context.from?.[1]?.value?.[FieldConstants.OPERATIONAL_LIMITS_GROUPS] ?? [];
42
+ const operationalLimitsGroupsWithPath = operationalLimitsGroups.map(
43
+ (item, index) => {
44
+ return {
45
+ ...item,
46
+ rhfPath: `${FieldConstants.LIMITS}.${FieldConstants.OPERATIONAL_LIMITS_GROUPS}[${index}]`
47
+ };
48
+ }
49
+ );
50
+ const limitsGroupName = sanitizeString(limitsGroup[FieldConstants.NAME]);
51
+ const filtered = operationalLimitsGroupsWithPath.filter(
52
+ (item) => sanitizeString(item[FieldConstants.NAME]) === limitsGroupName
53
+ );
54
+ if (filtered.length <= 1) {
55
+ return true;
56
+ }
57
+ const applicabilityEquipment = filtered.filter(
58
+ (item) => item[FieldConstants.APPLICABILITY_FIELD] === APPLICABILITY.EQUIPMENT.id
59
+ ).length;
60
+ const applicabilitySide1 = filtered.filter(
61
+ (item) => item[FieldConstants.APPLICABILITY_FIELD] === APPLICABILITY.SIDE1.id
62
+ ).length;
63
+ const isDuplicate = filtered.length > 2 || applicabilityEquipment > 0 || applicabilitySide1 === 0 || applicabilitySide1 > 1;
64
+ return !isDuplicate;
65
+ }
66
+ function hasDuplicate(field, context) {
67
+ return hasDuplicateOperationalLimitsGroups(context);
68
+ }
69
+ const temporaryLimitsValidationSchema = () => {
70
+ return object().shape(
71
+ {
72
+ [FieldConstants.TEMPORARY_LIMIT_DURATION]: number().nullable().min(0, "mustBeGreaterOrEqualToZero").when([FieldConstants.TEMPORARY_LIMIT_VALUE, FieldConstants.TEMPORARY_LIMIT_NAME], {
73
+ is: (value, name) => value != null || !!name,
74
+ then: (schema) => schema.required()
75
+ }),
76
+ [FieldConstants.TEMPORARY_LIMIT_VALUE]: number().nullable().positive(),
77
+ [FieldConstants.TEMPORARY_LIMIT_NAME]: string().nullable().trim().when([FieldConstants.TEMPORARY_LIMIT_VALUE, FieldConstants.TEMPORARY_LIMIT_DURATION], {
78
+ is: (value, duration) => value != null || duration != null,
79
+ then: (schema) => schema.required()
80
+ })
81
+ },
82
+ [[FieldConstants.TEMPORARY_LIMIT_DURATION, FieldConstants.TEMPORARY_LIMIT_NAME]]
83
+ );
84
+ };
85
+ const currentLimitsValidationSchema = () => ({
86
+ [FieldConstants.PERMANENT_LIMIT]: number().positive("permanentCurrentLimitMustBeGreaterThanZero").required(),
87
+ [FieldConstants.TEMPORARY_LIMITS]: array().of(temporaryLimitsValidationSchema()).test("distinctNames", "TemporaryLimitNameUnicityError", (limitsArray) => {
88
+ const namesArray = !limitsArray ? [] : limitsArray.filter((l) => !!l[FieldConstants.TEMPORARY_LIMIT_NAME]).map((l) => sanitizeString(l[FieldConstants.TEMPORARY_LIMIT_NAME]));
89
+ return areArrayElementsUnique(namesArray);
90
+ }).test("distinctDurations", "TemporaryLimitDurationUnicityError", (limitsArray) => {
91
+ const durationsArray = !limitsArray ? [] : limitsArray.map((l) => l[FieldConstants.TEMPORARY_LIMIT_DURATION]).filter((d) => d);
92
+ return areArrayElementsUnique(durationsArray);
93
+ })
94
+ });
95
+ const limitsPropertyValidationSchema = () => {
96
+ return object().shape({
97
+ [FieldConstants.NAME]: string().required(),
98
+ [FieldConstants.VALUE]: string().required()
99
+ });
100
+ };
101
+ const limitsGroupValidationSchema = object().shape({
102
+ [FieldConstants.ID]: string().nonNullable().required(),
103
+ [FieldConstants.NAME]: string().nonNullable().required(),
104
+ [FieldConstants.APPLICABILITY_FIELD]: string().nonNullable().required(),
105
+ [FieldConstants.OLG_IS_DUPLICATE]: boolean().nullable().test("testDistinct", "LimitSetApplicabilityError", hasDuplicate),
106
+ [FieldConstants.CURRENT_LIMITS]: object().shape(currentLimitsValidationSchema()),
107
+ [FieldConstants.LIMITS_PROPERTIES]: array().of(limitsPropertyValidationSchema())
108
+ }).concat(creationPropertiesSchema).required();
109
+ const getLimitsValidationSchemaProps = (isEquipmentModification = false) => object().shape({
110
+ [FieldConstants.OPERATIONAL_LIMITS_GROUPS]: isEquipmentModification ? array(limitsGroupValidationSchema).when([FieldConstants.ENABLE_OLG_MODIFICATION], {
111
+ is: true,
112
+ then: (schema) => schema.required(),
113
+ otherwise: (schema) => schema.strip()
114
+ }) : array(limitsGroupValidationSchema).required(),
115
+ [FieldConstants.SELECTED_OPERATIONAL_LIMITS_GROUP_ID1]: string().nullable(),
116
+ [FieldConstants.SELECTED_OPERATIONAL_LIMITS_GROUP_ID2]: string().nullable(),
117
+ [FieldConstants.ENABLE_OLG_MODIFICATION]: boolean()
118
+ });
119
+ const limitsValidationSchemaCreation = (id, isModification) => {
120
+ return { [id]: getLimitsValidationSchemaProps(isModification) };
121
+ };
122
+ const getLimitsValidationSchema = (id = FieldConstants.LIMITS, isModification = false) => {
123
+ return limitsValidationSchemaCreation(id, isModification);
124
+ };
125
+ const getLimitsEmptyFormDataProps = (isModification = true) => {
126
+ return {
127
+ [FieldConstants.OPERATIONAL_LIMITS_GROUPS]: [],
128
+ [FieldConstants.SELECTED_OPERATIONAL_LIMITS_GROUP_ID1]: null,
129
+ [FieldConstants.SELECTED_OPERATIONAL_LIMITS_GROUP_ID2]: null,
130
+ [FieldConstants.ENABLE_OLG_MODIFICATION]: !isModification
131
+ };
132
+ };
133
+ const getLimitsEmptyFormData = (isModification = true, id = FieldConstants.LIMITS) => {
134
+ return { [id]: getLimitsEmptyFormDataProps(isModification) };
135
+ };
136
+ const formatTemporaryLimitsModificationToFormSchema = (temporaryLimits) => temporaryLimits?.map((limit) => {
137
+ return {
138
+ [FieldConstants.TEMPORARY_LIMIT_NAME]: limit?.[FieldConstants.TEMPORARY_LIMIT_NAME]?.value ?? "",
139
+ [FieldConstants.TEMPORARY_LIMIT_VALUE]: limit?.[FieldConstants.TEMPORARY_LIMIT_VALUE]?.value ?? null,
140
+ [FieldConstants.TEMPORARY_LIMIT_DURATION]: limit?.[FieldConstants.TEMPORARY_LIMIT_DURATION]?.value ?? null
141
+ };
142
+ });
143
+ const formatOpLimitGroupsToFormInfos = (limitGroups) => {
144
+ if (!limitGroups) {
145
+ return [];
146
+ }
147
+ return limitGroups.filter(
148
+ (opLimitGroup) => opLimitGroup.modificationType !== OPERATIONAL_LIMITS_GROUPS_MODIFICATION_TYPE.DELETE
149
+ ).map((opLimitGroup) => {
150
+ return {
151
+ id: opLimitGroup.id + opLimitGroup.applicability,
152
+ name: opLimitGroup.id,
153
+ applicability: opLimitGroup.applicability,
154
+ limitsProperties: opLimitGroup.limitsProperties,
155
+ currentLimits: {
156
+ permanentLimit: opLimitGroup?.currentLimits?.permanentLimit,
157
+ temporaryLimits: formatTemporaryLimitsModificationToFormSchema(
158
+ opLimitGroup?.currentLimits?.temporaryLimits
159
+ )
160
+ }
161
+ };
162
+ });
163
+ };
164
+ const getAllLimitsFormDataProperties = (operationalLimitsGroups = [], selectedOperationalLimitsGroupId1 = null, selectedOperationalLimitsGroupId2 = null, enableOLGModification = true) => {
165
+ return {
166
+ [FieldConstants.OPERATIONAL_LIMITS_GROUPS]: operationalLimitsGroups,
167
+ [FieldConstants.SELECTED_OPERATIONAL_LIMITS_GROUP_ID1]: selectedOperationalLimitsGroupId1,
168
+ [FieldConstants.SELECTED_OPERATIONAL_LIMITS_GROUP_ID2]: selectedOperationalLimitsGroupId2,
169
+ [FieldConstants.ENABLE_OLG_MODIFICATION]: !!enableOLGModification
170
+ };
171
+ };
172
+ const getAllLimitsFormData = (operationalLimitsGroups = [], selectedOperationalLimitsGroupId1 = null, selectedOperationalLimitsGroupId2 = null, enableOLGModification = true, id = FieldConstants.LIMITS) => {
173
+ return {
174
+ [id]: getAllLimitsFormDataProperties(
175
+ operationalLimitsGroups,
176
+ selectedOperationalLimitsGroupId1,
177
+ selectedOperationalLimitsGroupId2,
178
+ enableOLGModification
179
+ )
180
+ };
181
+ };
182
+ const sanitizeLimitsGroups = (limitsGroups = []) => (limitsGroups || []).map(({ currentLimits, [FieldConstants.OLG_IS_DUPLICATE]: isDuplicate, ...baseData }) => ({
183
+ ...baseData,
184
+ [FieldConstants.OLG_IS_DUPLICATE]: isDuplicate ?? void 0,
185
+ id: baseData.name,
186
+ currentLimits: !currentLimits ? {
187
+ id: "",
188
+ permanentLimit: 0,
189
+ temporaryLimits: []
190
+ } : {
191
+ permanentLimit: currentLimits.permanentLimit,
192
+ temporaryLimits: !currentLimits.temporaryLimits ? [] : currentLimits.temporaryLimits.filter((limit) => limit?.name?.trim()).map(({ name, ...temporaryLimit }) => ({
193
+ ...temporaryLimit,
194
+ name: sanitizeString(name) ?? ""
195
+ }))
196
+ }
197
+ }));
198
+ const sanitizeLimitNames = (temporaryLimitList) => temporaryLimitList?.filter((limit) => limit?.name?.trim()).map(({ name, ...temporaryLimit }) => ({
199
+ ...temporaryLimit,
200
+ name: sanitizeString(name) ?? ""
201
+ })) || [];
202
+ const formatMapInfosToTemporaryLimitsFormSchema = (temporaryLimits) => temporaryLimits?.map((limit) => {
203
+ return {
204
+ [FieldConstants.TEMPORARY_LIMIT_NAME]: limit?.[FieldConstants.TEMPORARY_LIMIT_NAME] ?? "",
205
+ [FieldConstants.TEMPORARY_LIMIT_VALUE]: limit?.[FieldConstants.TEMPORARY_LIMIT_VALUE] ?? null,
206
+ [FieldConstants.TEMPORARY_LIMIT_DURATION]: limit?.[FieldConstants.TEMPORARY_LIMIT_DURATION] ?? null
207
+ };
208
+ });
209
+ const mapServerLimitsGroupsToFormInfos = (currentLimits) => {
210
+ return currentLimits?.map((currentLimit) => {
211
+ return {
212
+ id: currentLimit.id + currentLimit.applicability,
213
+ name: currentLimit.id,
214
+ applicability: currentLimit.applicability,
215
+ limitsProperties: currentLimit.limitsProperties,
216
+ currentLimits: {
217
+ id: currentLimit.id,
218
+ permanentLimit: currentLimit.permanentLimit,
219
+ temporaryLimits: formatMapInfosToTemporaryLimitsFormSchema(currentLimit.temporaryLimits)
220
+ }
221
+ };
222
+ });
223
+ };
224
+ const convertToOperationalLimitsGroupFormSchema = (currentLimits) => {
225
+ const updatedOpLG = [];
226
+ currentLimits.forEach((currentLimit) => {
227
+ const equivalentFromNetMod = updatedOpLG.find(
228
+ (opLG) => currentLimit.id === opLG.name && currentLimit.applicability === opLG[FieldConstants.APPLICABILITY_FIELD]
229
+ );
230
+ if (equivalentFromNetMod === void 0) {
231
+ updatedOpLG.push({
232
+ id: currentLimit.id + currentLimit.applicability,
233
+ name: currentLimit.id,
234
+ applicability: currentLimit.applicability,
235
+ limitsProperties: currentLimit.limitsProperties,
236
+ currentLimits: {
237
+ permanentLimit: currentLimit.permanentLimit ?? 0,
238
+ temporaryLimits: formatMapInfosToTemporaryLimitsFormSchema(currentLimit.temporaryLimits)
239
+ }
240
+ });
241
+ }
242
+ });
243
+ return updatedOpLG;
244
+ };
245
+ const addModificationTypeToTemporaryLimits = (formTemporaryLimits) => {
246
+ return formTemporaryLimits.map((limit) => {
247
+ return {
248
+ name: toModificationOperation(limit?.name),
249
+ acceptableDuration: toModificationOperation(limit?.acceptableDuration),
250
+ value: toModificationOperation(limit?.value),
251
+ modificationType: TEMPORARY_LIMIT_MODIFICATION_TYPE.MODIFY_OR_ADD
252
+ };
253
+ });
254
+ };
255
+ function addOperationTypeToSelectedOpLG(selectedOpLG, noSelectionString) {
256
+ return selectedOpLG === noSelectionString ? {
257
+ value: selectedOpLG,
258
+ op: OperationType.UNSET
259
+ } : toModificationOperation(selectedOpLG);
260
+ }
261
+ const addModificationTypeToOpLimitsGroups = (limitsGroupsForm) => {
262
+ const modificationLimitsGroupsForm = sanitizeLimitsGroups(limitsGroupsForm);
263
+ return modificationLimitsGroupsForm.map((limitsGroupForm) => {
264
+ const temporaryLimits = addModificationTypeToTemporaryLimits(
265
+ sanitizeLimitNames(limitsGroupForm[FieldConstants.CURRENT_LIMITS]?.[FieldConstants.TEMPORARY_LIMITS])
266
+ );
267
+ const currentLimits = {
268
+ permanentLimit: limitsGroupForm[FieldConstants.CURRENT_LIMITS]?.[FieldConstants.PERMANENT_LIMIT] ?? null,
269
+ temporaryLimits: temporaryLimits ?? []
270
+ };
271
+ return {
272
+ id: limitsGroupForm.id,
273
+ name: limitsGroupForm.name,
274
+ applicability: limitsGroupForm.applicability,
275
+ limitsProperties: limitsGroupForm.limitsProperties,
276
+ currentLimits,
277
+ modificationType: OPERATIONAL_LIMITS_GROUPS_MODIFICATION_TYPE.MODIFY_OR_ADD,
278
+ temporaryLimitsModificationType: TEMPORARY_LIMIT_MODIFICATION_TYPE.REPLACE
279
+ };
280
+ });
281
+ };
282
+ function generateEmptyTemporaryLimitArray() {
283
+ return [
284
+ {
285
+ [FieldConstants.TEMPORARY_LIMIT_NAME]: "",
286
+ [FieldConstants.TEMPORARY_LIMIT_DURATION]: null,
287
+ [FieldConstants.TEMPORARY_LIMIT_VALUE]: null
288
+ }
289
+ ];
290
+ }
291
+ function generateEmptyOperationalLimitsGroup(name) {
292
+ return {
293
+ [FieldConstants.ID]: crypto.randomUUID(),
294
+ [FieldConstants.NAME]: name,
295
+ [FieldConstants.APPLICABILITY_FIELD]: APPLICABILITY.EQUIPMENT.id,
296
+ [FieldConstants.LIMITS_PROPERTIES]: [],
297
+ [FieldConstants.CURRENT_LIMITS]: {
298
+ [FieldConstants.TEMPORARY_LIMITS]: generateEmptyTemporaryLimitArray(),
299
+ [FieldConstants.PERMANENT_LIMIT]: null
300
+ }
301
+ };
302
+ }
303
+ function generateUniqueId(baseName, names) {
304
+ let finalId = baseName;
305
+ let found = false;
306
+ let increment = 1;
307
+ let suffix = "";
308
+ do {
309
+ found = names.includes(baseName + suffix, 0);
310
+ if (found) {
311
+ increment += 1;
312
+ suffix = `(${increment})`;
313
+ finalId = baseName + suffix;
314
+ }
315
+ } while (found);
316
+ return finalId;
317
+ }
318
+ export {
319
+ addModificationTypeToOpLimitsGroups,
320
+ addModificationTypeToTemporaryLimits,
321
+ addOperationTypeToSelectedOpLG,
322
+ convertToOperationalLimitsGroupFormSchema,
323
+ formatMapInfosToTemporaryLimitsFormSchema,
324
+ formatOpLimitGroupsToFormInfos,
325
+ formatTemporaryLimitsModificationToFormSchema,
326
+ generateEmptyOperationalLimitsGroup,
327
+ generateUniqueId,
328
+ getAllLimitsFormData,
329
+ getAllLimitsFormDataProperties,
330
+ getLimitsEmptyFormData,
331
+ getLimitsEmptyFormDataProps,
332
+ getLimitsValidationSchema,
333
+ getLimitsValidationSchemaProps,
334
+ mapServerLimitsGroupsToFormInfos,
335
+ sanitizeLimitNames,
336
+ sanitizeLimitsGroups
337
+ };
@@ -0,0 +1,25 @@
1
+ import { FieldValues, UseFieldArrayAppend, UseFieldArrayRemove } from 'react-hook-form';
2
+ import { Dispatch, SetStateAction } from 'react';
3
+ import { OperationalLimitsGroupFormSchema } from './operationalLimitsGroups.types';
4
+ import { CurrentLimitsData } from '../limits.types';
5
+ export interface ContextMenuCoordinates {
6
+ x: null | number;
7
+ y: null | number;
8
+ tabIndex: null | number;
9
+ }
10
+ export interface LimitsGroupsContextualMenuProps {
11
+ parentFormName: string;
12
+ indexSelectedLimitSet: number | null;
13
+ setIndexSelectedLimitSet: Dispatch<SetStateAction<number | null>>;
14
+ handleCloseMenu: () => void;
15
+ contextMenuCoordinates: ContextMenuCoordinates;
16
+ selectedLimitsGroups1: string;
17
+ selectedLimitsGroups2: string;
18
+ currentLimitsToModify: CurrentLimitsData[];
19
+ operationalLimitsGroups: FieldValues;
20
+ appendToLimitsGroups: UseFieldArrayAppend<{
21
+ [p: string]: OperationalLimitsGroupFormSchema[];
22
+ }, string>;
23
+ removeLimitsGroups: UseFieldArrayRemove;
24
+ }
25
+ export declare function LimitsGroupsContextualMenu({ parentFormName, indexSelectedLimitSet, setIndexSelectedLimitSet, handleCloseMenu, contextMenuCoordinates, selectedLimitsGroups1, selectedLimitsGroups2, operationalLimitsGroups, appendToLimitsGroups, removeLimitsGroups, }: Readonly<LimitsGroupsContextualMenuProps>): import("react").JSX.Element;
@@ -0,0 +1,92 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useFormContext } from "react-hook-form";
3
+ import { Menu, MenuItem, ListItemIcon, ListItemText } from "@mui/material";
4
+ import { Delete, ContentCopy } from "@mui/icons-material";
5
+ import { useIntl } from "react-intl";
6
+ import { useCallback } from "react";
7
+ import { APPLICABILITY } from "../limits.types.js";
8
+ import { FieldConstants } from "../../../../../utils/constants/fieldConstants.js";
9
+ import "../../../../../utils/conversionUtils.js";
10
+ import "../../../../../utils/types/equipmentType.js";
11
+ function LimitsGroupsContextualMenu({
12
+ parentFormName,
13
+ indexSelectedLimitSet,
14
+ setIndexSelectedLimitSet,
15
+ handleCloseMenu,
16
+ contextMenuCoordinates,
17
+ selectedLimitsGroups1,
18
+ selectedLimitsGroups2,
19
+ operationalLimitsGroups,
20
+ appendToLimitsGroups,
21
+ removeLimitsGroups
22
+ }) {
23
+ const intl = useIntl();
24
+ const { setValue } = useFormContext();
25
+ const handleDeleteTab = useCallback(() => {
26
+ if (indexSelectedLimitSet !== null) {
27
+ const tabName = operationalLimitsGroups[indexSelectedLimitSet]?.name;
28
+ const applicability = operationalLimitsGroups[indexSelectedLimitSet]?.applicability ?? "";
29
+ if (selectedLimitsGroups1 === tabName && (applicability === APPLICABILITY.SIDE1.id || applicability === APPLICABILITY.EQUIPMENT.id)) {
30
+ setValue(`${parentFormName}.${FieldConstants.SELECTED_OPERATIONAL_LIMITS_GROUP_ID1}`, null);
31
+ }
32
+ if (selectedLimitsGroups2 === tabName && (applicability === APPLICABILITY.SIDE2.id || applicability === APPLICABILITY.EQUIPMENT.id)) {
33
+ setValue(`${parentFormName}.${FieldConstants.SELECTED_OPERATIONAL_LIMITS_GROUP_ID2}`, null);
34
+ }
35
+ removeLimitsGroups(indexSelectedLimitSet);
36
+ setIndexSelectedLimitSet(null);
37
+ }
38
+ handleCloseMenu();
39
+ }, [
40
+ handleCloseMenu,
41
+ indexSelectedLimitSet,
42
+ operationalLimitsGroups,
43
+ parentFormName,
44
+ removeLimitsGroups,
45
+ selectedLimitsGroups1,
46
+ selectedLimitsGroups2,
47
+ setIndexSelectedLimitSet,
48
+ setValue
49
+ ]);
50
+ const handleDuplicateTab = useCallback(() => {
51
+ let newName = "";
52
+ if (indexSelectedLimitSet !== null) {
53
+ const duplicatedLimits1 = operationalLimitsGroups[indexSelectedLimitSet];
54
+ newName = `${duplicatedLimits1.name}_COPY`;
55
+ const newLimitsGroup1 = {
56
+ ...duplicatedLimits1,
57
+ [FieldConstants.ID]: newName
58
+ };
59
+ appendToLimitsGroups(newLimitsGroup1);
60
+ handleCloseMenu();
61
+ setIndexSelectedLimitSet(operationalLimitsGroups.length);
62
+ }
63
+ }, [
64
+ indexSelectedLimitSet,
65
+ operationalLimitsGroups,
66
+ appendToLimitsGroups,
67
+ setIndexSelectedLimitSet,
68
+ handleCloseMenu
69
+ ]);
70
+ return /* @__PURE__ */ jsxs(
71
+ Menu,
72
+ {
73
+ open: contextMenuCoordinates.tabIndex != null,
74
+ onClose: handleCloseMenu,
75
+ anchorReference: "anchorPosition",
76
+ anchorPosition: contextMenuCoordinates.y !== null && contextMenuCoordinates.x !== null ? { top: contextMenuCoordinates.y, left: contextMenuCoordinates.x } : void 0,
77
+ children: [
78
+ /* @__PURE__ */ jsxs(MenuItem, { onClick: handleDeleteTab, children: [
79
+ /* @__PURE__ */ jsx(ListItemIcon, { children: /* @__PURE__ */ jsx(Delete, { fontSize: "small" }) }),
80
+ /* @__PURE__ */ jsx(ListItemText, { children: intl.formatMessage({ id: "DeleteFromMenu" }) })
81
+ ] }),
82
+ /* @__PURE__ */ jsxs(MenuItem, { onClick: handleDuplicateTab, children: [
83
+ /* @__PURE__ */ jsx(ListItemIcon, { children: /* @__PURE__ */ jsx(ContentCopy, { fontSize: "small" }) }),
84
+ /* @__PURE__ */ jsx(ListItemText, { children: intl.formatMessage({ id: "Duplicate" }) })
85
+ ] })
86
+ ]
87
+ }
88
+ );
89
+ }
90
+ export {
91
+ LimitsGroupsContextualMenu
92
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Copyright (c) 2025, RTE (http://www.rte-france.com)
3
+ * This Source Code Form is subject to the terms of the Mozilla Public
4
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
5
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
+ */
7
+ export interface LimitsPropertiesStackProps {
8
+ name: string;
9
+ }
10
+ export declare function LimitsPropertiesStack({ name }: Readonly<LimitsPropertiesStackProps>): import("react").JSX.Element;
@@ -0,0 +1,25 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { Stack, Avatar } from "@mui/material";
3
+ import { useWatch } from "react-hook-form";
4
+ import { LimitsTagChip } from "../LimitsTagChip.js";
5
+ const MAX_PROPERTIES_TO_RENDER = 2;
6
+ function getLimitsPropertiesToRender(limitsProperties) {
7
+ return limitsProperties.length < MAX_PROPERTIES_TO_RENDER ? limitsProperties : limitsProperties?.slice(0, 2);
8
+ }
9
+ function LimitsPropertiesStack({ name }) {
10
+ const limitsProperties = useWatch({ name });
11
+ const propertiesToRender = getLimitsPropertiesToRender(limitsProperties ?? []);
12
+ return /* @__PURE__ */ jsxs(Stack, { direction: "row", sx: { alignItems: "center" }, children: [
13
+ propertiesToRender.map((property) => /* @__PURE__ */ jsx(LimitsTagChip, { limitsProperty: property }, `${property.name}`)),
14
+ limitsProperties && propertiesToRender.length !== limitsProperties.length ? /* @__PURE__ */ jsx(
15
+ Avatar,
16
+ {
17
+ sx: { width: 30, height: 30 },
18
+ children: `+${limitsProperties.length - propertiesToRender.length}`
19
+ }
20
+ ) : ""
21
+ ] });
22
+ }
23
+ export {
24
+ LimitsPropertiesStack
25
+ };
@@ -0,0 +1,10 @@
1
+ import { OperationalLimitsGroupFormSchema } from './operationalLimitsGroups.types';
2
+ interface OperationalLimitsGroupTabLabelProps {
3
+ operationalLimitsGroup: OperationalLimitsGroupFormSchema;
4
+ showIconButton: boolean;
5
+ limitsPropertiesName: string;
6
+ handleOpenMenu: (event: React.MouseEvent<HTMLElement>, index: number) => void;
7
+ index: number;
8
+ }
9
+ export declare function OperationalLimitsGroupTabLabel({ operationalLimitsGroup, showIconButton, limitsPropertiesName, handleOpenMenu, index, }: Readonly<OperationalLimitsGroupTabLabelProps>): import("react").JSX.Element;
10
+ export {};
@@ -0,0 +1,73 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { Box, Stack, Tooltip, Typography, FormHelperText, IconButton } from "@mui/material";
3
+ import { FormattedMessage } from "react-intl";
4
+ import { red, grey } from "@mui/material/colors";
5
+ import { useFormState } from "react-hook-form";
6
+ import { ErrorOutlineOutlined, MoreVert } from "@mui/icons-material";
7
+ import { LimitsPropertiesStack } from "./LimitsPropertiesStack.js";
8
+ import { APPLICABILITY } from "../limits.types.js";
9
+ import { FieldConstants } from "../../../../../utils/constants/fieldConstants.js";
10
+ import "../../../../../utils/conversionUtils.js";
11
+ import "../../../../../utils/types/equipmentType.js";
12
+ function OperationalLimitsGroupTabLabel({
13
+ operationalLimitsGroup,
14
+ showIconButton,
15
+ limitsPropertiesName,
16
+ handleOpenMenu,
17
+ index
18
+ }) {
19
+ const { errors } = useFormState({
20
+ name: `${FieldConstants.LIMITS}.${FieldConstants.OPERATIONAL_LIMITS_GROUPS}`
21
+ });
22
+ const temporaryLimitsErrors = errors?.limits?.operationalLimitsGroups?.[index]?.currentLimits?.temporaryLimits;
23
+ const hasTemporaryLimitError = Array.isArray(temporaryLimitsErrors) && temporaryLimitsErrors.some((tl) => tl?.name?.message || tl?.acceptableDuration?.message);
24
+ const hasError = errors?.limits?.operationalLimitsGroups?.[index]?.name?.message || errors?.limits?.operationalLimitsGroups?.[index]?.currentLimits?.permanentLimit?.message || errors?.limits?.operationalLimitsGroups?.[index]?.[FieldConstants.OLG_IS_DUPLICATE]?.message || hasTemporaryLimitError;
25
+ return /* @__PURE__ */ jsxs(
26
+ Box,
27
+ {
28
+ sx: {
29
+ display: "inline-flex",
30
+ alignItems: "center",
31
+ boxSizing: "inherit",
32
+ justifyContent: "space-between",
33
+ paddingRight: 1,
34
+ paddingLeft: 1
35
+ },
36
+ children: [
37
+ /* @__PURE__ */ jsxs(Stack, { direction: "row", spacing: 1, sx: { alignItems: "center" }, children: [
38
+ /* @__PURE__ */ jsxs(Stack, { spacing: 0, children: [
39
+ /* @__PURE__ */ jsx(Tooltip, { title: operationalLimitsGroup.name, children: /* @__PURE__ */ jsxs(Stack, { direction: "row", spacing: 1, sx: { alignItems: "stretch" }, children: [
40
+ /* @__PURE__ */ jsx(
41
+ Typography,
42
+ {
43
+ variant: "body1",
44
+ color: hasError ? red[500] : void 0,
45
+ sx: {
46
+ maxWidth: "10ch",
47
+ textOverflow: "ellipsis"
48
+ },
49
+ noWrap: true,
50
+ children: operationalLimitsGroup.name
51
+ }
52
+ ),
53
+ hasError && /* @__PURE__ */ jsx(FormHelperText, { error: true, children: /* @__PURE__ */ jsx(ErrorOutlineOutlined, {}) })
54
+ ] }) }),
55
+ operationalLimitsGroup?.applicability ? /* @__PURE__ */ jsx(Typography, { noWrap: true, align: "left", color: grey[500], children: /* @__PURE__ */ jsx(
56
+ FormattedMessage,
57
+ {
58
+ id: Object.values(APPLICABILITY).find(
59
+ (item) => item.id === operationalLimitsGroup.applicability
60
+ )?.label
61
+ }
62
+ ) }) : ""
63
+ ] }),
64
+ /* @__PURE__ */ jsx(LimitsPropertiesStack, { name: limitsPropertiesName })
65
+ ] }),
66
+ showIconButton && /* @__PURE__ */ jsx(IconButton, { component: "span", size: "small", onClick: (e) => handleOpenMenu(e, index), children: /* @__PURE__ */ jsx(MoreVert, { fontSize: "small" }) })
67
+ ]
68
+ }
69
+ );
70
+ }
71
+ export {
72
+ OperationalLimitsGroupTabLabel
73
+ };
@@ -0,0 +1,16 @@
1
+ import { default as React } from 'react';
2
+ import { UseFieldArrayAppend } from 'react-hook-form';
3
+ import { OperationalLimitsGroupFormSchema } from './operationalLimitsGroups.types';
4
+ import { CurrentLimitsData } from '../limits.types';
5
+ export interface OperationalLimitsGroupsProps {
6
+ parentFormName: string;
7
+ indexSelectedLimitSet: number | null;
8
+ setIndexSelectedLimitSet: React.Dispatch<React.SetStateAction<number | null>>;
9
+ currentLimitsToModify: CurrentLimitsData[];
10
+ editable: boolean;
11
+ appendToLimitsGroups: UseFieldArrayAppend<{
12
+ [p: string]: OperationalLimitsGroupFormSchema[];
13
+ }, string>;
14
+ removeLimitsGroups: () => void;
15
+ }
16
+ export declare function OperationalLimitsGroups({ parentFormName, setIndexSelectedLimitSet, indexSelectedLimitSet, editable, appendToLimitsGroups, removeLimitsGroups, currentLimitsToModify, }: Readonly<OperationalLimitsGroupsProps>): React.JSX.Element;