Skip to content

Commit ed0dd5d

Browse files
authored
add form for hvdc lcc (#2412)
Signed-off-by: Rehili Ghazwa <[email protected]>
1 parent 752d5d4 commit ed0dd5d

32 files changed

+1192
-85
lines changed

src/components/dialogs/commons/modificationDialog.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ ModificationDialog.propTypes = {
9494
onClear: PropTypes.func.isRequired,
9595
onSave: PropTypes.func.isRequired,
9696
searchCopy: PropTypes.object,
97+
subtitle: PropTypes.object,
9798
disabledSave: PropTypes.bool,
9899
onValidated: PropTypes.func,
99100
onValidationError: PropTypes.func,
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Copyright (c) 2024, 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+
8+
export interface ConnectablePositionInfos {
9+
connectionDirection: string | null;
10+
connectionName?: string | null;
11+
connectionPosition?: string | null;
12+
terminalConnected?: boolean | null;
13+
}
14+
15+
export interface Connectivity {
16+
voltageLevel: { id?: string };
17+
busOrBusbarSection: { id?: string; name?: string };
18+
connectionDirection?: string;
19+
connectionName?: string;
20+
connectionPosition?: number;
21+
terminalConnected?: boolean;
22+
}

src/components/dialogs/form-search-copy-hook.js

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,7 @@ import { useSnackMessage } from '@gridsuite/commons-ui';
1111
import { EQUIPMENT_INFOS_TYPES } from '../utils/equipment-types';
1212
import { fetchNetworkElementInfos } from '../../services/study/network';
1313

14-
export const useFormSearchCopy = ({
15-
studyUuid,
16-
currentNodeUuid,
17-
toFormValues,
18-
setFormValues,
19-
elementType,
20-
operation,
21-
}) => {
14+
export const useFormSearchCopy = ({ studyUuid, currentNodeUuid, toFormValues, setFormValues, elementType }) => {
2215
const intl = useIntl();
2316

2417
const { snackInfo, snackError } = useSnackMessage();
@@ -33,8 +26,7 @@ export const useFormSearchCopy = ({
3326
elementType,
3427
EQUIPMENT_INFOS_TYPES.FORM.type,
3528
element.id,
36-
true,
37-
operation
29+
true
3830
);
3931
return fetchElementPromise
4032
.then((response) => {

src/components/dialogs/network-modifications/common/properties/properties-form.tsx

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ import { useFormContext, useWatch } from 'react-hook-form';
1414
import GridSection from '../../../commons/grid-section';
1515

1616
type PropertiesFormProps = {
17+
id?: string;
1718
networkElementType?: string;
1819
isModification?: boolean;
1920
};
2021

21-
const PropertiesForm = ({ networkElementType, isModification = false }: PropertiesFormProps) => {
22+
const PropertiesForm = ({ id, networkElementType, isModification = false }: PropertiesFormProps) => {
23+
const additionalProperties = id ? `${id}.${ADDITIONAL_PROPERTIES}` : ADDITIONAL_PROPERTIES;
2224
const watchProps = useWatch({
23-
name: ADDITIONAL_PROPERTIES,
25+
name: additionalProperties,
2426
});
2527
const { getValues, setValue } = useFormContext();
2628
const [predefinedProperties, setPredefinedProperties] = useState({} as PredefinedProperties);
@@ -36,19 +38,19 @@ const PropertiesForm = ({ networkElementType, isModification = false }: Properti
3638

3739
const getDeletionMark = useCallback(
3840
(idx: number) => {
39-
const properties = getValues(`${ADDITIONAL_PROPERTIES}`);
41+
const properties = getValues(`${additionalProperties}`);
4042
if (properties && typeof properties[idx] !== 'undefined') {
4143
return watchProps && properties[idx][DELETION_MARK];
4244
}
4345
return false;
4446
},
45-
[getValues, watchProps]
47+
[getValues, watchProps, additionalProperties]
4648
);
4749

4850
const deleteCallback = useCallback(
4951
(idx: number) => {
5052
let markedForDeletion = false;
51-
const properties = getValues(`${ADDITIONAL_PROPERTIES}`);
53+
const properties = getValues(`${additionalProperties}`);
5254
if (properties && typeof properties[idx] !== 'undefined') {
5355
markedForDeletion = properties[idx][DELETION_MARK];
5456
} else {
@@ -58,19 +60,19 @@ const PropertiesForm = ({ networkElementType, isModification = false }: Properti
5860
let canRemoveLine = true;
5961
if (markedForDeletion) {
6062
// just unmark
61-
setValue(`${ADDITIONAL_PROPERTIES}.${idx}.${DELETION_MARK}`, false, { shouldDirty: true });
63+
setValue(`${additionalProperties}.${idx}.${DELETION_MARK}`, false, { shouldDirty: true });
6264
canRemoveLine = false;
6365
} else {
6466
// we should mark for deletion a property that actually exists in the network and not delete the property line straight away
6567
if (properties[idx][PREVIOUS_VALUE] && properties[idx][ADDED] === false) {
66-
setValue(`${ADDITIONAL_PROPERTIES}.${idx}.${DELETION_MARK}`, true, { shouldDirty: true });
68+
setValue(`${additionalProperties}.${idx}.${DELETION_MARK}`, true, { shouldDirty: true });
6769
canRemoveLine = false;
6870
}
6971
}
7072
// otherwise just delete the line
7173
return canRemoveLine;
7274
},
73-
[getValues, setValue]
75+
[getValues, setValue, additionalProperties]
7476
);
7577

7678
const modificationProperties = isModification
@@ -83,7 +85,7 @@ const PropertiesForm = ({ networkElementType, isModification = false }: Properti
8385

8486
const additionalProps = (
8587
<ExpandableInput
86-
name={ADDITIONAL_PROPERTIES}
88+
name={additionalProperties}
8789
Field={PropertyForm}
8890
fieldProps={{ predefinedProperties }}
8991
addButtonLabel={'AddProperty'}

src/components/dialogs/network-modifications/common/properties/property-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export type PredefinedProperties = {
3333
};
3434

3535
type Equipment = {
36-
properties: Record<string, string> | undefined;
36+
properties?: Record<string, string>;
3737
};
3838

3939
export const fetchPredefinedProperties = (networkElementType: string): Promise<PredefinedProperties | undefined> => {

src/components/dialogs/network-modifications/equipment-deletion/hvdc-lcc-deletion/hvdc-lcc-deletion-specific-form.jsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { Grid } from '@mui/material';
99
import { CheckboxInput } from '@gridsuite/commons-ui';
1010
import ReadOnlyInput from 'components/utils/rhf-inputs/read-only/read-only-input';
1111
import {
12-
MCS_SELECTED,
12+
SHUNT_COMPENSATOR_SELECTED,
1313
ID,
1414
DELETION_SPECIFIC_DATA,
1515
SHUNT_COMPENSATOR_SIDE_1,
@@ -39,7 +39,10 @@ const HvdcLccDeletionSpecificForm = () => {
3939
{mcsRows.map((field, index) => (
4040
<Grid container spacing={1} alignItems="center" key={field.id}>
4141
<Grid item xs={1} align={'start'}>
42-
<CheckboxInput key={field.id + 'SEL'} name={`${arrayFormName}[${index}].${MCS_SELECTED}`} />
42+
<CheckboxInput
43+
key={field.id + 'SEL'}
44+
name={`${arrayFormName}[${index}].${SHUNT_COMPENSATOR_SELECTED}`}
45+
/>
4346
</Grid>
4447
<Grid item xs={11} align={'start'}>
4548
<ReadOnlyInput key={field.id + 'ID'} name={`${arrayFormName}[${index}].${ID}`} />
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/**
2+
* Copyright (c) 2024, 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+
import { Box, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material';
8+
import Tooltip from '@mui/material/Tooltip';
9+
import IconButton from '@mui/material/IconButton';
10+
import AddCircleIcon from '@mui/icons-material/AddCircle';
11+
import { useIntl } from 'react-intl';
12+
import { useMemo, useState } from 'react';
13+
import DeleteIcon from '@mui/icons-material/Delete';
14+
import { useFieldArray } from 'react-hook-form';
15+
import {
16+
FILTERS_SHUNT_COMPENSATOR_TABLE,
17+
MAX_Q_AT_NOMINAL_V,
18+
SHUNT_COMPENSATOR_ID,
19+
SHUNT_COMPENSATOR_NAME,
20+
SHUNT_COMPENSATOR_SELECTED,
21+
} from '../../../../../utils/field-constants';
22+
import { FloatInput, SwitchInput, TextInput } from '@gridsuite/commons-ui';
23+
import { ReactivePowerAdornment } from '../../../../dialog-utils';
24+
25+
interface FiltersShuntCompensatorTableProps {
26+
id: string;
27+
}
28+
export default function FiltersShuntCompensatorTable({ id }: Readonly<FiltersShuntCompensatorTableProps>) {
29+
const intl = useIntl();
30+
const {
31+
fields: rows,
32+
append: handleAddRow,
33+
remove: handleRemoveRow,
34+
} = useFieldArray({ name: `${id}.${FILTERS_SHUNT_COMPENSATOR_TABLE}` });
35+
const [isHover, setIsHover] = useState<Record<number, boolean>>({});
36+
const handleHover = (rowIndex: number, hoverState: boolean) => {
37+
setIsHover((prev) => ({
38+
...prev,
39+
[rowIndex]: hoverState,
40+
}));
41+
};
42+
const columnsDefinition = useMemo(() => {
43+
return [
44+
{
45+
label: 'shuntCompensatorId',
46+
dataKey: SHUNT_COMPENSATOR_ID,
47+
initialValue: '',
48+
width: '30%',
49+
},
50+
{
51+
label: 'shuntCompensatorName',
52+
dataKey: SHUNT_COMPENSATOR_NAME,
53+
initialValue: '',
54+
width: '30%',
55+
},
56+
{
57+
label: 'maxQAtNominalV',
58+
dataKey: MAX_Q_AT_NOMINAL_V,
59+
initialValue: null,
60+
width: '30%',
61+
},
62+
{
63+
label: 'connected',
64+
dataKey: SHUNT_COMPENSATOR_SELECTED,
65+
initialValue: true,
66+
width: '10%',
67+
},
68+
].map((column) => ({
69+
...column,
70+
label: intl.formatMessage({ id: column.label }),
71+
}));
72+
}, [intl]);
73+
74+
const newRowData = useMemo(() => {
75+
const newRowData: { [key: string]: null | string | boolean } = {};
76+
columnsDefinition.forEach((column) => {
77+
newRowData[column.dataKey] = column.initialValue;
78+
});
79+
return newRowData;
80+
}, [columnsDefinition]);
81+
82+
return (
83+
<TableContainer>
84+
<Table stickyHeader size="small" sx={{ tableLayout: 'fixed', textAlign: 'center' }}>
85+
<TableHead>
86+
<TableRow>
87+
{columnsDefinition.map((column) => (
88+
<TableCell key={column.dataKey} sx={{ width: column.width, textAlign: 'center' }}>
89+
<Box>{column.label}</Box>
90+
</TableCell>
91+
))}
92+
<TableCell sx={{ width: '10%', textAlign: 'right' }}>
93+
<Tooltip
94+
title={intl.formatMessage({
95+
id: 'AddRows',
96+
})}
97+
>
98+
<span>
99+
<IconButton onClick={() => handleAddRow(newRowData)}>
100+
<AddCircleIcon />
101+
</IconButton>
102+
</span>
103+
</Tooltip>
104+
</TableCell>
105+
</TableRow>
106+
</TableHead>
107+
<TableBody>
108+
{rows.map((row: Record<'id', string>, index) => (
109+
<TableRow
110+
key={row.id}
111+
className={isHover[index] ? 'hover-row' : ''}
112+
onMouseEnter={() => handleHover(index, true)}
113+
onMouseLeave={() => handleHover(index, false)}
114+
>
115+
{columnsDefinition.map((column) => (
116+
<TableCell key={column.dataKey} sx={{ width: column.width, textAlign: 'center' }}>
117+
{column.dataKey === SHUNT_COMPENSATOR_ID && (
118+
<TextInput
119+
name={`${id}.${FILTERS_SHUNT_COMPENSATOR_TABLE}[${index}].${SHUNT_COMPENSATOR_ID}`}
120+
/>
121+
)}
122+
{column.dataKey === SHUNT_COMPENSATOR_NAME && (
123+
<TextInput
124+
name={`${id}.${FILTERS_SHUNT_COMPENSATOR_TABLE}[${index}].${SHUNT_COMPENSATOR_NAME}`}
125+
/>
126+
)}
127+
{column.dataKey === MAX_Q_AT_NOMINAL_V && (
128+
<FloatInput
129+
name={`${id}.${FILTERS_SHUNT_COMPENSATOR_TABLE}[${index}].${MAX_Q_AT_NOMINAL_V}`}
130+
adornment={ReactivePowerAdornment}
131+
/>
132+
)}
133+
{column.dataKey === SHUNT_COMPENSATOR_SELECTED && (
134+
<SwitchInput
135+
name={`${id}.${FILTERS_SHUNT_COMPENSATOR_TABLE}[${index}].${SHUNT_COMPENSATOR_SELECTED}`}
136+
/>
137+
)}
138+
</TableCell>
139+
))}
140+
<TableCell>
141+
{isHover[index] && (
142+
<Tooltip
143+
title={intl.formatMessage({
144+
id: 'DeleteRows',
145+
})}
146+
>
147+
<IconButton onClick={() => handleRemoveRow(index)}>
148+
<DeleteIcon />
149+
</IconButton>
150+
</Tooltip>
151+
)}
152+
</TableCell>
153+
</TableRow>
154+
))}
155+
</TableBody>
156+
</Table>
157+
</TableContainer>
158+
);
159+
}

0 commit comments

Comments
 (0)