|
5 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
6 | 6 | */ |
7 | 7 |
|
8 | | -import { useCallback, useMemo } from 'react'; |
9 | | -import { Button, Checkbox, List, ListItem, ListItemButton, ListItemText, Paper } from '@mui/material'; |
| 8 | +import { useCallback, useEffect, useMemo, useState } from 'react'; |
| 9 | +import { Button, Checkbox, List, ListItem, ListItemButton, ListItemText, Paper, Tooltip } from '@mui/material'; |
10 | 10 | import { FormattedMessage } from 'react-intl'; |
11 | 11 | import { type MuiStyles } from '@gridsuite/commons-ui'; |
| 12 | +import { BASE_VOLTAGES, MAX_VOLTAGE, VoltageLevelInterval } from './constants'; |
| 13 | +import { getNominalVoltageIntervalName } from './utils/nominal-voltage-filter-utils'; |
12 | 14 |
|
13 | 15 | const styles = { |
14 | 16 | nominalVoltageZone: { |
@@ -44,56 +46,101 @@ export type NominalVoltageFilterProps = { |
44 | 46 | onChange: (filteredNominalVoltages: number[]) => void; |
45 | 47 | }; |
46 | 48 |
|
| 49 | +type VoltageLevelValuesInterval = VoltageLevelInterval & { |
| 50 | + vlListValues: number[]; |
| 51 | + isChecked: boolean; |
| 52 | +}; |
| 53 | + |
47 | 54 | export default function NominalVoltageFilter({ |
48 | 55 | nominalVoltages, |
49 | 56 | filteredNominalVoltages, |
50 | 57 | onChange, |
51 | 58 | }: Readonly<NominalVoltageFilterProps>) { |
| 59 | + const [voltageLevelIntervals, setVoltageLevelIntervals] = useState<VoltageLevelValuesInterval[]>( |
| 60 | + BASE_VOLTAGES.map((interval) => ({ ...interval, vlListValues: [], isChecked: true })) |
| 61 | + ); |
| 62 | + useEffect(() => { |
| 63 | + const newIntervals = BASE_VOLTAGES.map((interval) => { |
| 64 | + const vlListValues = nominalVoltages.filter( |
| 65 | + (vnom) => getNominalVoltageIntervalName(vnom) === interval.name |
| 66 | + ); |
| 67 | + return { ...interval, vlListValues, isChecked: true }; |
| 68 | + }); |
| 69 | + setVoltageLevelIntervals(newIntervals); |
| 70 | + }, [nominalVoltages]); |
| 71 | + |
52 | 72 | const handleToggle = useCallback( |
53 | | - (vnoms: number[], isToggle = false) => { |
| 73 | + (interval: VoltageLevelValuesInterval) => { |
54 | 74 | let newFiltered: number[]; |
55 | | - if (isToggle) { |
56 | | - // we "inverse" the selection for vnoms values |
57 | | - newFiltered = [...filteredNominalVoltages]; |
58 | | - vnoms.forEach((vnom) => { |
59 | | - const currentIndex = filteredNominalVoltages.indexOf(vnom); |
60 | | - if (currentIndex === -1) { |
61 | | - newFiltered.push(vnom); //not previously present, we add it |
62 | | - } else { |
63 | | - newFiltered.splice(currentIndex, 1); // previously present, we remove it |
64 | | - } |
65 | | - }); |
66 | | - } else { |
67 | | - // it's just the new selection |
68 | | - newFiltered = [...vnoms]; |
| 75 | + |
| 76 | + // we "inverse" the selection for vlListValues |
| 77 | + newFiltered = [...filteredNominalVoltages]; |
| 78 | + for (const vnom of interval.vlListValues) { |
| 79 | + const currentIndex = newFiltered.indexOf(vnom); |
| 80 | + if (currentIndex === -1) { |
| 81 | + newFiltered.push(vnom); // not previously present, we add it |
| 82 | + } else { |
| 83 | + newFiltered.splice(currentIndex, 1); // previously present, we remove it |
| 84 | + } |
69 | 85 | } |
70 | | - onChange(newFiltered); |
| 86 | + setVoltageLevelIntervals((prev) => |
| 87 | + prev.map((i) => (i.name === interval.name ? { ...i, isChecked: !i.isChecked } : i)) |
| 88 | + ); |
| 89 | + |
| 90 | + onChange(newFiltered); // update filteredNominalVoltages |
71 | 91 | }, |
72 | 92 | [filteredNominalVoltages, onChange] |
73 | 93 | ); |
74 | | - const handleSelectAll = useCallback(() => handleToggle(nominalVoltages), [handleToggle, nominalVoltages]); |
75 | | - const handleSelectNone = useCallback(() => handleToggle([]), [handleToggle]); |
| 94 | + const handleToggleCheckAll = useCallback( |
| 95 | + (check: boolean) => { |
| 96 | + // if check is true, we check all; otherwise we uncheck all |
| 97 | + setVoltageLevelIntervals((prev) => prev.map((interval) => ({ ...interval, isChecked: check }))); |
| 98 | + onChange(check ? [...nominalVoltages] : []); // update filteredNominalVoltages |
| 99 | + }, |
| 100 | + [nominalVoltages, onChange] |
| 101 | + ); |
| 102 | + const handleSelectAll = useCallback(() => handleToggleCheckAll(true), [handleToggleCheckAll]); |
| 103 | + const handleSelectNone = useCallback(() => handleToggleCheckAll(false), [handleToggleCheckAll]); |
76 | 104 |
|
77 | 105 | const nominalVoltagesList = useMemo( |
78 | 106 | () => |
79 | | - nominalVoltages.map((value) => ( |
80 | | - <ListItem sx={styles.nominalVoltageItem} key={value}> |
81 | | - <ListItemButton |
82 | | - role={undefined} |
83 | | - dense |
84 | | - onClick={() => handleToggle([value], true)} |
85 | | - disabled={!filteredNominalVoltages} |
86 | | - > |
87 | | - <Checkbox |
88 | | - color="default" |
89 | | - sx={styles.nominalVoltageCheck} |
90 | | - checked={!filteredNominalVoltages || filteredNominalVoltages.indexOf(value) !== -1} |
91 | | - /> |
92 | | - <ListItemText sx={styles.nominalVoltageText} disableTypography primary={`${value} kV`} /> |
93 | | - </ListItemButton> |
94 | | - </ListItem> |
95 | | - )), |
96 | | - [filteredNominalVoltages, handleToggle, nominalVoltages] |
| 107 | + voltageLevelIntervals |
| 108 | + .filter((interval) => interval.vlListValues.length > 0) |
| 109 | + .map((interval) => ( |
| 110 | + <ListItem sx={styles.nominalVoltageItem} key={interval.name}> |
| 111 | + <Tooltip |
| 112 | + title={ |
| 113 | + <FormattedMessage |
| 114 | + id={'voltageLevelInterval'} |
| 115 | + values={{ |
| 116 | + lowBound: interval.minValue, |
| 117 | + highBound: interval.maxValue === Infinity ? MAX_VOLTAGE : interval.maxValue, |
| 118 | + }} |
| 119 | + /> |
| 120 | + } |
| 121 | + > |
| 122 | + <ListItemButton |
| 123 | + role={undefined} |
| 124 | + dense |
| 125 | + onClick={() => handleToggle(interval)} |
| 126 | + disabled={!filteredNominalVoltages} |
| 127 | + > |
| 128 | + <Checkbox |
| 129 | + color="default" |
| 130 | + sx={styles.nominalVoltageCheck} |
| 131 | + checked={interval.isChecked} |
| 132 | + /> |
| 133 | + |
| 134 | + <ListItemText |
| 135 | + sx={styles.nominalVoltageText} |
| 136 | + disableTypography |
| 137 | + primary={`${interval.vlValue} kV`} |
| 138 | + ></ListItemText> |
| 139 | + </ListItemButton> |
| 140 | + </Tooltip> |
| 141 | + </ListItem> |
| 142 | + )), |
| 143 | + [filteredNominalVoltages, handleToggle, voltageLevelIntervals] |
97 | 144 | ); |
98 | 145 |
|
99 | 146 | if (nominalVoltages.length <= 0) { |
|
0 commit comments