Skip to content

Commit 775cc4e

Browse files
authored
Fix sonar issues "Do not nest functions more than 4 levels deep" (#3033)
* fix(App): add parameter to `updateParams` to fill empty params with defaultValues if given. * fix(App): create a `computeRetrieveOptionalServices` function in 'src/components/utils/optional-services.ts' and use it in App component * fix(ExportNetworkDialog): create a completeDefaultValuesForExtensionsParameters * fix(TabularDialog): create a `convertCreations` function * fix(CheckboxTreeview): create `getSelectedItems` function outside the `useImperativeHandle` scope * fix(CurvePreview): create `isCurveAlreadyAdded` and `isRowSelected` helper functions * fix(ModelFilter): create `getSelectedVariables` func outside of the `useImperativeHandle` scope * fix(getReactiveCapabilityCurveValidationSchema): create `hasAtLeastOneNegativeP` and `hasAtLeastOnePositiveP` helper functions * fix(RootNetworkChipCellRenderer): create a helper function `getUpdatedExcludedModifications` * fix(useDiagramModel): create `handleFetchSuccess` `handleFetchError` and `handleFetchFinally` to remove some code depth * fix(PlutlySeriesChart): move the `seriesToData` helper function outside the component * fix(ColumnsConfig) : Create `DraggableColumnItem` and `DroppableColumnsList` separated components. * fix Node.js built-in modules should be imported using the "node:" protocol typescript:S7772 introduced here * fix Use ".some()" instead of ".filter().length" checks or ".find()" for existence testing typescript:S7754 * fix Use "for...of" loops instead of "forEach" method calls typescript:S7728 Signed-off-by: sBouzols <[email protected]>
1 parent 9de91a6 commit 775cc4e

File tree

14 files changed

+504
-353
lines changed

14 files changed

+504
-353
lines changed

src/components/app.jsx

Lines changed: 18 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@
77

88
import { useCallback, useEffect, useState } from 'react';
99
import { useDispatch, useSelector } from 'react-redux';
10-
import {
11-
getOptionalServiceByServerName,
12-
OptionalServicesNames,
13-
OptionalServicesStatus,
14-
} from './utils/optional-services';
10+
import { retrieveOptionalServices } from './utils/optional-services';
1511
import { Navigate, Route, Routes, useLocation, useMatch, useNavigate } from 'react-router';
1612
import {
1713
AnnouncementNotification,
@@ -106,8 +102,22 @@ const App = () => {
106102
);
107103

108104
const updateParams = useCallback(
109-
(params) => {
105+
(params, defaultValues = null) => {
110106
console.debug('received UI parameters : ', params);
107+
if (defaultValues) {
108+
// Browsing defaultParametersValues entries
109+
Object.entries(defaultValues).forEach(([key, defaultValue]) => {
110+
// Checking if keys defined in defaultParametersValues file are already defined in config server
111+
// If they are not defined, values are taken from default values file
112+
if (!params.find((param) => param.name === key)) {
113+
params.push({
114+
name: key,
115+
value: defaultValue,
116+
});
117+
}
118+
});
119+
console.debug('UI parameters filled with default values when undefined : ', params);
120+
}
111121
params.forEach((param) => {
112122
switch (param.name) {
113123
case PARAM_THEME:
@@ -306,18 +316,7 @@ const App = () => {
306316

307317
const fetchAppConfigPromise = fetchConfigParameters(APP_NAME).then((params) => {
308318
fetchDefaultParametersValues().then((defaultValues) => {
309-
// Browsing defaultParametersValues entries
310-
Object.entries(defaultValues).forEach(([key, defaultValue]) => {
311-
// Checking if keys defined in defaultParametersValues file are already defined in config server
312-
// If they are not defined, values are taken from default values file
313-
if (!params.find((param) => param.name === key)) {
314-
params.push({
315-
name: key,
316-
value: defaultValue,
317-
});
318-
}
319-
});
320-
updateParams(params);
319+
updateParams(params, defaultValues);
321320
});
322321
});
323322

@@ -327,29 +326,7 @@ const App = () => {
327326

328327
const fetchOptionalServices = getOptionalServices()
329328
.then((services) => {
330-
const retrieveOptionalServices = services.map((service) => {
331-
return {
332-
...service,
333-
name: getOptionalServiceByServerName(service.name),
334-
};
335-
});
336-
// get all potentially optional services
337-
const optionalServicesNames = Object.keys(OptionalServicesNames);
338-
339-
// if one of those services was not returned by "getOptionalServices", it means it was defined as "not optional"
340-
// in that case, we consider it is UP
341-
optionalServicesNames
342-
.filter(
343-
(serviceName) =>
344-
!retrieveOptionalServices.map((service) => service.name).includes(serviceName)
345-
)
346-
.forEach((serviceName) =>
347-
retrieveOptionalServices.push({
348-
name: serviceName,
349-
status: OptionalServicesStatus.Up,
350-
})
351-
);
352-
dispatch(setOptionalServices(retrieveOptionalServices));
329+
dispatch(setOptionalServices(retrieveOptionalServices(services)));
353330
})
354331
.catch((error) => {
355332
snackError({

src/components/dialogs/export-network-dialog.tsx

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,13 @@ import DialogContent from '@mui/material/DialogContent';
2525
import DialogActions from '@mui/material/DialogActions';
2626
import Button from '@mui/material/Button';
2727
import { useCallback, useEffect, useMemo, useState } from 'react';
28-
import { CancelButton, FlatParameters, fetchDirectoryElementPath, useSnackMessage } from '@gridsuite/commons-ui';
28+
import {
29+
CancelButton,
30+
FlatParameters,
31+
Parameter,
32+
fetchDirectoryElementPath,
33+
useSnackMessage,
34+
} from '@gridsuite/commons-ui';
2935
import { ExportFormatProperties, getAvailableExportFormats } from '../../services/study';
3036
import { getExportUrl } from '../../services/study/network';
3137
import { isBlankOrEmpty } from 'components/utils/validation-functions';
@@ -57,6 +63,18 @@ interface ExportNetworkDialogProps {
5763
rootNetworkUuid: UUID;
5864
}
5965

66+
// we check if the param is for extension, if it is, we select all possible values by default.
67+
// the only way for the moment to check if the param is for extension, is by checking his type is name.
68+
// TODO to be removed when extensions param default value corrected in backend to include all possible values
69+
function getDefaultValuesForExtensionsParameter(parameters: Parameter[]): Parameter[] {
70+
return parameters.map((parameter) => {
71+
if (parameter.type === STRING_LIST && parameter.name?.endsWith('extensions')) {
72+
parameter.defaultValue = parameter.possibleValues;
73+
}
74+
return parameter;
75+
});
76+
}
77+
6078
export function ExportNetworkDialog({
6179
open,
6280
onClose,
@@ -102,16 +120,9 @@ export function ExportNetworkDialog({
102120
const availableFormats = enableDeveloperMode
103121
? formats
104122
: Object.fromEntries(Object.entries(formats).filter(([key]) => key === XIIDM_FORMAT));
105-
// we check if the param is for extension, if it is, we select all possible values by default.
106-
// the only way for the moment to check if the param is for extension, is by checking his type is name.
107-
//TODO to be removed when extensions param default value corrected in backend to include all possible values
123+
108124
Object.values(availableFormats).forEach((format) => {
109-
format.parameters = format.parameters.map((parameter) => {
110-
if (parameter.type === STRING_LIST && parameter.name?.endsWith('extensions')) {
111-
parameter.defaultValue = parameter.possibleValues;
112-
}
113-
return parameter;
114-
});
125+
format.parameters = getDefaultValuesForExtensionsParameter(format.parameters);
115126
});
116127
setFormatsWithParameters(availableFormats);
117128
});

src/components/dialogs/network-modifications/tabular/tabular-dialog.tsx

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,20 @@ import {
4848
} from './tabular-creation-utils';
4949
import { NetworkModificationDialogProps } from '../../../graph/menus/network-modifications/network-modification-menu.type';
5050

51+
function convertCreations(creations: Modification[]): Modification[] {
52+
return creations.map((creat: Modification) => {
53+
let creation: Modification = {};
54+
Object.keys(formatModification(creat)).forEach((key) => {
55+
const entry = convertCreationFieldFromBackToFront(key, creat[key]);
56+
(Array.isArray(entry) ? entry : [entry]).forEach((item) => {
57+
creation[item.key] = item.value;
58+
});
59+
});
60+
creation = addPropertiesFromBack(creation, creat?.[TABULAR_PROPERTIES]);
61+
return creation;
62+
});
63+
}
64+
5165
type TabularDialogProps = NetworkModificationDialogProps & {
5266
editData: TabularModificationEditDataType;
5367
dialogMode: TabularModificationType;
@@ -114,17 +128,7 @@ export function TabularDialog({
114128
const initTabularCreationData = useCallback(
115129
(editData: TabularModificationCreationType) => {
116130
const equipmentType = getEquipmentTypeFromCreationType(editData?.creationType);
117-
const creations = editData?.creations.map((creat: Modification) => {
118-
let creation: Modification = {};
119-
Object.keys(formatModification(creat)).forEach((key) => {
120-
const entry = convertCreationFieldFromBackToFront(key, creat[key]);
121-
(Array.isArray(entry) ? entry : [entry]).forEach((item) => {
122-
creation[item.key] = item.value;
123-
});
124-
});
125-
creation = addPropertiesFromBack(creation, creat?.[TABULAR_PROPERTIES]);
126-
return creation;
127-
});
131+
const creations = convertCreations(editData?.creations);
128132
reset({
129133
[TYPE]: equipmentType,
130134
[MODIFICATIONS_TABLE]: creations,

src/components/dialogs/parameters/dynamicsimulation/curve/common/checkbox-treeview.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -175,20 +175,21 @@ const CheckboxTreeview = forwardRef<GetSelectedItemsHandle, CheckBoxTreeViewProp
175175
[itemStates]
176176
);
177177

178+
const getSelectedItems = useCallback(() => {
179+
return items.filter(
180+
(item) => getState(item.id) === CheckState.CHECKED && !items.some((elem) => elem.parentId === item.id) // no children
181+
);
182+
}, [items, getState]);
183+
178184
// expose some api for the component by using ref
179185
useImperativeHandle(
180186
ref,
181187
() => ({
182188
api: {
183-
getSelectedItems: () =>
184-
items.filter(
185-
(item) =>
186-
getState(item.id) === CheckState.CHECKED &&
187-
!items.find((elem) => elem.parentId === item.id) // no children
188-
),
189+
getSelectedItems,
189190
},
190191
}),
191-
[items, getState]
192+
[getSelectedItems]
192193
);
193194

194195
// render functions (recursive rendering)

src/components/dialogs/parameters/dynamicsimulation/curve/dialog/curve-preview.tsx

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ export interface CurveHandler {
3838
};
3939
}
4040

41+
function isCurveAlreadyAdded(curves: Curve[], curve: Curve): boolean {
42+
return curves.some((elem) => elem.equipmentId === curve.equipmentId && elem.variableId === curve.variableId);
43+
}
44+
45+
function isRowSelected(elem: Curve, selectedRows: Curve[]): boolean {
46+
return selectedRows.some(
47+
(selectedElem) => elem.equipmentId === selectedElem.equipmentId && elem.variableId === selectedElem.variableId
48+
);
49+
}
50+
4151
const CurvePreview = forwardRef<CurveHandler>((props, ref) => {
4252
const intl = useIntl();
4353
const gridRef = useRef<AgGridReact<any>>(null);
@@ -88,50 +98,41 @@ const CurvePreview = forwardRef<CurveHandler>((props, ref) => {
8898
setSelectedRowsLength(selectedRows.length);
8999
}, []);
90100

101+
const addCurves = useCallback((curves: Curve[]) => {
102+
setRowData((prev) => {
103+
const notYetAddedCurves = curves.filter((curve) => !isCurveAlreadyAdded(prev, curve));
104+
return [...prev, ...notYetAddedCurves];
105+
});
106+
}, []);
107+
108+
const removeCurves = useCallback(() => {
109+
if (!gridRef.current) {
110+
return;
111+
}
112+
const selectedRows = gridRef.current.api.getSelectedRows();
113+
114+
// reset selected rows length
115+
setSelectedRowsLength(0);
116+
117+
setRowData((prev) => {
118+
const remainingRows = prev.filter((elem) => !isRowSelected(elem, selectedRows));
119+
return remainingRows;
120+
});
121+
}, []);
122+
91123
// expose some api for the component by using ref
92124
useImperativeHandle(
93125
ref,
94126
() => ({
95127
api: {
96-
addCurves: (curves) => {
97-
setRowData((prev) => {
98-
const notYetAddedCurves = curves.filter(
99-
(curve) =>
100-
!prev.find(
101-
(elem) =>
102-
elem.equipmentId === curve.equipmentId && elem.variableId === curve.variableId
103-
)
104-
);
105-
return [...prev, ...notYetAddedCurves];
106-
});
107-
},
108-
removeCurves: () => {
109-
if (!gridRef.current) {
110-
return;
111-
}
112-
const selectedRows = gridRef.current.api.getSelectedRows();
113-
114-
// reset selected rows length
115-
setSelectedRowsLength(0);
116-
117-
setRowData((prev) => {
118-
const remainingRows = prev.filter(
119-
(elem) =>
120-
!selectedRows.find(
121-
(selectedElem) =>
122-
elem.equipmentId === selectedElem.equipmentId &&
123-
elem.variableId === selectedElem.variableId
124-
)
125-
);
126-
return remainingRows;
127-
});
128-
},
128+
addCurves,
129+
removeCurves,
129130
getCurves: () => {
130131
return rowData;
131132
},
132133
},
133134
}),
134-
[rowData]
135+
[addCurves, removeCurves, rowData]
135136
);
136137

137138
return (

src/components/dialogs/parameters/dynamicsimulation/curve/dialog/model-filter.tsx

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -226,25 +226,26 @@ const ModelFilter = forwardRef<GetSelectedVariablesHandle, ModelFilterProps>(
226226
});
227227
}, [studyUuid]);
228228

229+
const getSelectedVariables = useCallback((): ModelVariable[] => {
230+
return (
231+
variablesRef.current?.api
232+
.getSelectedItems()
233+
.filter((item) => item.variableId) // filter to keep only variable item
234+
.filter(
235+
(item, index, arr) => arr.findIndex((elem) => elem.variableId === item.variableId) === index
236+
) ?? []
237+
); // remove duplicated by variableId
238+
}, []);
239+
229240
// expose some api for the component by using ref
230241
useImperativeHandle(
231242
ref,
232243
() => ({
233244
api: {
234-
getSelectedVariables: () => {
235-
return (
236-
variablesRef.current?.api
237-
.getSelectedItems()
238-
.filter((item) => item.variableId) // filter to keep only variable item
239-
.filter(
240-
(item, index, arr) =>
241-
arr.findIndex((elem) => elem.variableId === item.variableId) === index
242-
) ?? []
243-
); // remove duplicated by variableId
244-
},
245+
getSelectedVariables,
245246
},
246247
}),
247-
[]
248+
[getSelectedVariables]
248249
);
249250

250251
const getModelLabel = useMemo(() => {

0 commit comments

Comments
 (0)