diff --git a/package-lock.json b/package-lock.json index edc3c00e0a..0beea7ad9f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@mui/lab": "5.0.0-alpha.169", "@mui/material": "^5.15.14", "@mui/x-tree-view": "^6.17.0", - "@powsybl/network-viewer": "1.1.1", + "@powsybl/network-viewer": "file:../../../~powsybl/powsybl-diagram-viewer/powsybl-network-viewer-1.2.0.tgz", "@reduxjs/toolkit": "^2.2.3", "@svgdotjs/svg.js": "^3.2.0", "@svgdotjs/svg.panzoom.js": "^2.1.2", @@ -5176,9 +5176,11 @@ } }, "node_modules/@powsybl/network-viewer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@powsybl/network-viewer/-/network-viewer-1.1.1.tgz", - "integrity": "sha512-spXy3EnRlbvPbsq4ue3ECA+Dz7z/9WEOOaXoGtPyMyZtbHlDJCpWUoVwg7iVbr33uYMAY8oDvqu+sLszZ9aNCw==", + "version": "1.2.0", + "resolved": "file:../../../~powsybl/powsybl-diagram-viewer/powsybl-network-viewer-1.2.0.tgz", + "integrity": "sha512-UbZ6jmVym8bfkYKgMBh1N9h+Y2B38J2F7r7xKqM0zDHCafSn9867sJIWselTCy5hzEzFmBunAfTjFRMcUMiulA==", + "hasInstallScript": true, + "license": "MPL-2.0", "dependencies": { "@mapbox/mapbox-gl-draw": "^1.4.3", "@svgdotjs/svg.js": "^3.2.0", diff --git a/package.json b/package.json index 6a05aceba3..cbdaa583ef 100644 --- a/package.json +++ b/package.json @@ -13,10 +13,11 @@ "@mui/lab": "5.0.0-alpha.169", "@mui/material": "^5.15.14", "@mui/x-tree-view": "^6.17.0", - "@powsybl/network-viewer": "1.1.1", + "@powsybl/network-viewer": "file:../../../~powsybl/powsybl-diagram-viewer/powsybl-network-viewer-1.2.0.tgz", "@reduxjs/toolkit": "^2.2.3", "@svgdotjs/svg.js": "^3.2.0", "@svgdotjs/svg.panzoom.js": "^2.1.2", + "@xyflow/react": "^12.3.2", "ag-grid-community": "^31.0.0", "ag-grid-react": "^31.2.0", "cheap-ruler": "^3.0.2", @@ -35,7 +36,6 @@ "react-beautiful-dnd": "^13.1.1", "react-csv-downloader": "^3.1.0", "react-dom": "^18.2.0", - "@xyflow/react": "^12.3.2", "react-grid-layout": "^1.4.4", "react-hook-form": "^7.51.2", "react-intl": "^6.6.4", diff --git a/src/components/diagrams/singleLineDiagram/single-line-diagram-content.tsx b/src/components/diagrams/singleLineDiagram/single-line-diagram-content.tsx index dd2a8b4d68..c9af6981c2 100644 --- a/src/components/diagrams/singleLineDiagram/single-line-diagram-content.tsx +++ b/src/components/diagrams/singleLineDiagram/single-line-diagram-content.tsx @@ -411,7 +411,7 @@ function SingleLineDiagramContent(props: SingleLineDiagramContentProps) { handleOpenModificationDialog={handleOpenModificationDialog} onOpenDynamicSimulationEventDialog={handleOpenDynamicSimulationEventDialog} currentNode={currentNode} - studyUuid={studyUuid as UUID} + studyUuid={studyUuid} modificationInProgress={modificationInProgress} setModificationInProgress={setModificationInProgress} /> @@ -430,11 +430,7 @@ function SingleLineDiagramContent(props: SingleLineDiagramContentProps) { equipmentMenu.equipmentId && equipmentMenu.equipmentType === equipmentType && ( { const networkMapref = useRef(null); // hold the reference to the network map (from powsybl-network-viewer) const dispatch = useDispatch(); @@ -323,7 +322,6 @@ const MapViewer = ({ currentNode={currentNode} onChangeTab={onChangeTab} showInSpreadsheet={showInSpreadsheet} - setErrorMessage={setErrorMessage} onDrawPolygonModeActive={onDrawingModeEnter} onPolygonChanged={() => {}} onDrawEvent={onDrawEvent} diff --git a/src/components/menus/base-equipment-menu.tsx b/src/components/menus/base-equipment-menu.tsx index 58d9ce8167..b4917e8cbb 100644 --- a/src/components/menus/base-equipment-menu.tsx +++ b/src/components/menus/base-equipment-menu.tsx @@ -145,7 +145,7 @@ const ItemViewInForm = ({ ); }; -// Temporary type definition for VoltageLevel Equipment, pending a more comprehensive Equipment typing in diagramViewer +// TODO: Temporary type definition for VoltageLevel Equipment, pending a more comprehensive Equipment typing in diagramViewer export type MapEquipment = Equipment & { substationId: string; substationName: string; diff --git a/src/components/network/gs-map-equipments.ts b/src/components/network/gs-map-equipments.ts index 942436232f..9210dc38da 100644 --- a/src/components/network/gs-map-equipments.ts +++ b/src/components/network/gs-map-equipments.ts @@ -6,23 +6,21 @@ */ import { UUID } from 'crypto'; -import { RefObject } from 'react'; -import { IntlShape } from 'react-intl'; import { Dispatch } from 'redux'; import { UseSnackMessageReturn } from '@gridsuite/commons-ui'; import { mapEquipmentsCreated, setMapEquipementsInitialized } from '../../redux/actions'; +import { MapEquipments } from '@powsybl/network-viewer'; +import type { AppDispatch } from '../../redux/store'; import { fetchHvdcLinesMapInfos, fetchLinesMapInfos, fetchSubstationsMapInfos, fetchTieLinesMapInfos, -} from '../../services/study/network'; -import { MapEquipments } from '@powsybl/network-viewer'; +} from '../../services/study/network-ts'; export default class GSMapEquipments extends MapEquipments { - dispatch: Dispatch; + dispatch: AppDispatch; errHandler?: UseSnackMessageReturn['snackError']; - intlRef: RefObject; initEquipments(studyUuid: UUID, currentNodeUuid: UUID) { const fetchSubstationsMapInfosPromise = fetchSubstationsMapInfos(studyUuid, currentNodeUuid, undefined, false); @@ -102,17 +100,15 @@ export default class GSMapEquipments extends MapEquipments { studyUuid: UUID, currentNodeUuid: UUID, errHandler: UseSnackMessageReturn['snackError'], - dispatch: Dispatch, - intlRef: RefObject + dispatch: Dispatch ) { super(); this.dispatch = dispatch; this.errHandler = errHandler; - this.intlRef = intlRef; this.initEquipments(studyUuid, currentNodeUuid); } - reloadImpactedSubstationsEquipments(studyUuid: UUID, currentNode: any, substationsIds: string[] | null) { + reloadImpactedSubstationsEquipments(studyUuid: UUID, currentNode: any, substationsIds: string[] | undefined) { const updatedSubstations = fetchSubstationsMapInfos(studyUuid, currentNode?.id, substationsIds, true); const updatedLines = fetchLinesMapInfos(studyUuid, currentNode?.id, substationsIds, true); const updatedTieLines = fetchTieLinesMapInfos(studyUuid, currentNode?.id, substationsIds, true); diff --git a/src/components/network/network-map-tab.tsx b/src/components/network/network-map-tab.tsx index 0229705bec..31df3c1114 100644 --- a/src/components/network/network-map-tab.tsx +++ b/src/components/network/network-map-tab.tsx @@ -5,27 +5,38 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +import type { Writable } from 'type-fest'; import { - NetworkMap, + type Coordinate, + DRAW_MODES, GeoData, - NetworkMapRef, - LineFlowMode, + type GeoDataEquipment, + type GeoDataLine, + type GeoDataSubstation, LineFlowColorMode, - DRAW_MODES, + LineFlowMode, + type MapHvdcLine, + type MapLine, + type MapSubstation, + type MapTieLine, + type MapVoltageLevel, + NetworkMap, + type NetworkMapProps, + type NetworkMapRef, } from '@powsybl/network-viewer'; -import { useCallback, useEffect, useState, useRef, useMemo, RefObject } from 'react'; +import { type FunctionComponent, type RefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import withOperatingStatusMenu, { MenuBranchProps } from '../menus/operating-status-menu'; -import BaseEquipmentMenu, { MapEquipment } from '../menus/base-equipment-menu'; +import BaseEquipmentMenu, { MapEquipment as BaseEquipment } from '../menus/base-equipment-menu'; import withEquipmentMenu from '../menus/equipment-menu'; import VoltageLevelChoice from '../voltage-level-choice'; -import NominalVoltageFilter from './nominal-voltage-filter'; +import NominalVoltageFilter, { type NominalVoltageFilterProps } from './nominal-voltage-filter'; import { useDispatch, useSelector } from 'react-redux'; import { PARAM_MAP_BASEMAP, PARAM_MAP_MANUAL_REFRESH, PARAM_USE_NAME } from '../../utils/config-params'; -import { Equipment, EquipmentType, useIntlRef, useSnackMessage } from '@gridsuite/commons-ui'; +import { Equipment, EquipmentType, useSnackMessage } from '@gridsuite/commons-ui'; import { isNodeBuilt, isNodeRenamed, isSameNode, isSameNodeAndBuilt } from '../graph/util/model-functions'; import { resetMapReloaded, setMapDataLoading } from '../../redux/actions'; import GSMapEquipments from './gs-map-equipments'; -import LinearProgress from '@mui/material/LinearProgress'; +import { Box, LinearProgress, useTheme } from '@mui/material'; import { UPDATE_TYPE_HEADER } from '../study-container'; import SubstationModificationDialog from '../dialogs/network-modifications/substation/modification/substation-modification-dialog'; import VoltageLevelModificationDialog from '../dialogs/network-modifications/voltage-level/modification/voltage-level-modification-dialog'; @@ -34,7 +45,6 @@ import LineModificationDialog from '../dialogs/network-modifications/line/modifi import { deleteEquipment } from '../../services/study/network-modifications'; import EquipmentDeletionDialog from '../dialogs/network-modifications/equipment-deletion/equipment-deletion-dialog'; import { fetchLinePositions, fetchSubstationPositions } from '../../services/study/geo-data'; - import { useMapBoxToken } from './network-map/use-mapbox-token'; import EquipmentPopover from '../tooltips/equipment-popover'; import RunningStatus from 'components/utils/running-status'; @@ -43,23 +53,12 @@ import { useGetStudyImpacts } from 'hooks/use-get-study-impacts'; import { ROOT_NODE_LABEL } from '../../constants/node.constant'; import { UUID } from 'crypto'; import { AppState, CurrentTreeNode } from 'redux/reducer'; -import { - Coordinate, - Line, - Substation, - Equipment as EquipmentGeoData, -} from '@powsybl/network-viewer/dist/components/network-map-viewer/network/geo-data'; -import { - Equipment as EquipmentMap, - Substation as SubstationMap, - Line as LineMap, - VoltageLevel as VoltageLevelMap, -} from '@powsybl/network-viewer/dist/components/network-map-viewer/network/map-equipments'; -import { Box, useTheme } from '@mui/material'; -const INITIAL_POSITION = [0, 0] as [number, number]; + +const INITIAL_POSITION = [0, 0] as const; const INITIAL_ZOOM = 9; const LABELS_ZOOM_THRESHOLD = 9; const ARROWS_ZOOM_THRESHOLD = 7; +const EMPTY_ARRAY: any[] = []; const styles = { divNominalVoltageFilter: { @@ -81,7 +80,7 @@ const styles = { const NODE_CHANGED_ERROR = 'Node has changed or is not built anymore. The Promise is rejected.'; type NetworkMapTabProps = { - networkMapRef: React.RefObject; + networkMapRef: RefObject; studyUuid: UUID; currentNode: CurrentTreeNode; visible: boolean; @@ -92,12 +91,11 @@ type NetworkMapTabProps = { lineFlowAlertThreshold: number; openVoltageLevel: (idVoltageLevel: string) => void; showInSpreadsheet: (equipment: { equipmentType: EquipmentType; equipmentId: string }) => void; - setErrorMessage: (message: string) => void; onDrawPolygonModeActive: (active: DRAW_MODES) => void; onPolygonChanged: (polygoneFeature: any) => void; onDrawEvent: (drawEvent: number) => void; isInDrawingMode: boolean; - onNominalVoltagesChange: (nominalVoltages: unknown[]) => void; + onNominalVoltagesChange: (nominalVoltages: number[]) => void; }; export const NetworkMapTab = ({ @@ -115,7 +113,6 @@ export const NetworkMapTab = ({ /* callbacks */ openVoltageLevel, showInSpreadsheet, - setErrorMessage, onDrawPolygonModeActive, onPolygonChanged, onDrawEvent, @@ -141,14 +138,13 @@ export const NetworkMapTab = ({ const dispatch = useDispatch(); - const intlRef = useIntlRef(); const [isRootNodeGeoDataLoaded, setIsRootNodeGeoDataLoaded] = useState(false); const [isInitialized, setInitialized] = useState(false); const mapBoxToken = useMapBoxToken(); const { snackError } = useSnackMessage(); - const [filteredNominalVoltages, setFilteredNominalVoltages] = useState(); + const [filteredNominalVoltages, setFilteredNominalVoltages] = useState(); const [geoData, setGeoData] = useState(); const geoDataRef = useRef(); @@ -180,7 +176,7 @@ export const NetworkMapTab = ({ type EquipmentMenuProps = { position?: [number, number] | null; - equipment?: MapEquipment; + equipment?: BaseEquipment; equipmentType?: EquipmentType; display: boolean; }; @@ -191,9 +187,9 @@ export const NetworkMapTab = ({ const [position, setPosition] = useState([-1, -1]); const currentNodeRef = useRef(null); - const [updatedLines, setUpdatedLines] = useState([]); - const [updatedTieLines, setUpdatedTieLines] = useState([]); - const [updatedHvdcLines, setUpdatedHvdcLines] = useState([]); + const [updatedLines, setUpdatedLines] = useState([]); + const [updatedTieLines, setUpdatedTieLines] = useState([]); + const [updatedHvdcLines, setUpdatedHvdcLines] = useState([]); const [equipmentToModify, setEquipmentToModify] = useState(); const [modificationDialogOpen, setModificationDialogOpen] = useState(false); const [deletionDialogOpen, setDeletionDialogOpen] = useState(false); @@ -289,7 +285,8 @@ export const NetworkMapTab = ({ studyUuid: UUID; equipmentType: EquipmentType; }; - function withEquipment(Menu: React.FC, props: MenuProps | null) { + + function withEquipment(Menu: FunctionComponent, props: MenuProps | null) { return ( equipmentMenu?.equipment && equipmentMenu.position && @@ -314,7 +311,7 @@ export const NetworkMapTab = ({ const MenuVoltageLevel = withEquipmentMenu(BaseEquipmentMenu, EquipmentType.VOLTAGE_LEVEL, 'voltage-level-menus'); - function showEquipmentMenu(equipment: MapEquipment, x: number, y: number, type: EquipmentType) { + function showEquipmentMenu(equipment: BaseEquipment, x: number, y: number, type: EquipmentType) { setEquipmentMenu({ position: [x, y], equipment: equipment, @@ -339,12 +336,9 @@ export const NetworkMapTab = ({ const handleDeleteEquipment = useCallback( (equipmentType: EquipmentType | null, equipmentId: string) => { - const equipment = mapEquipments?.hvdcLinesById?.get(equipmentId) as Equipment; if ( equipmentType === EquipmentType.HVDC_LINE && - equipment && - 'hvdcType' in equipment && - equipment.hvdcType === 'LCC' + mapEquipments?.hvdcLinesById?.get(equipmentId)?.hvdcType === 'LCC' ) { // only hvdc line with LCC requires a Dialog (to select MCS) handleOpenDeletionDialog(equipmentId, EquipmentType.HVDC_LINE); @@ -370,10 +364,10 @@ export const NetworkMapTab = ({ closeChoiceVoltageLevelMenu(); } - const voltageLevelMenuClick = (equipment: VoltageLevelMap, x: number, y: number) => { + const voltageLevelMenuClick = (equipment: MapVoltageLevel, x: number, y: number) => { // don't display the voltage level menu in drawing mode. if (!isInDrawingMode) { - showEquipmentMenu(equipment as MapEquipment, x, y, EquipmentType.VOLTAGE_LEVEL); + showEquipmentMenu(equipment as unknown as BaseEquipment, x, y, EquipmentType.VOLTAGE_LEVEL); } }; @@ -388,7 +382,7 @@ export const NetworkMapTab = ({ ); const getEquipmentsNotFoundIds = useCallback( - (foundEquipmentPositions: Map, allEquipments: EquipmentGeoData[]) => { + (foundEquipmentPositions: Map, allEquipments: GeoDataEquipment[]) => { return allEquipments .filter((s) => !foundEquipmentPositions.has(s.id) || temporaryGeoDataIdsRef?.current?.has(s.id)) .map((s) => s.id); @@ -400,14 +394,17 @@ export const NetworkMapTab = ({ return coordinate1?.lat === coordinate2?.lat && coordinate1?.lon === coordinate2?.lon; }; - const substationPositionsAreEqual = useCallback((substationPos1: Substation, substationPos2: Substation) => { - return ( - latLonEqual(substationPos1?.coordinate, substationPos2?.coordinate) && - substationPos1?.country === substationPos2?.country - ); - }, []); + const substationPositionsAreEqual = useCallback( + (substationPos1: GeoDataSubstation, substationPos2: GeoDataSubstation) => { + return ( + latLonEqual(substationPos1?.coordinate, substationPos2?.coordinate) && + substationPos1?.country === substationPos2?.country + ); + }, + [] + ); - const linePositionsAreEqual = useCallback((linePos1: Line, linePos2: Line) => { + const linePositionsAreEqual = useCallback((linePos1: GeoDataLine, linePos2: GeoDataLine) => { return ( latLonEqual(linePos1?.coordinates?.[0], linePos2?.coordinates?.[0]) && latLonEqual(linePos1?.coordinates?.[1], linePos2?.coordinates?.[1]) && @@ -433,7 +430,7 @@ export const NetworkMapTab = ({ ); const updateSubstationsTemporaryGeoData = useCallback( - (requestedPositions: string[], fetchedPositions: Substation[]) => { + (requestedPositions: string[], fetchedPositions: GeoDataSubstation[]) => { let someDataHasChanged = false; fetchedPositions.forEach((pos) => { // If the geo data is the same in the geoData and in the server response, it's not updated @@ -459,7 +456,7 @@ export const NetworkMapTab = ({ ); const updateLinesTemporaryGeoData = useCallback( - (requestedPositions: string[], fetchedPositions: Line[]) => { + (requestedPositions: string[], fetchedPositions: GeoDataLine[]) => { let someDataHasChanged = false; fetchedPositions.forEach((pos) => { // If the geo data is the same in the geoData and in the server response, it's not updated @@ -494,11 +491,12 @@ export const NetworkMapTab = ({ const loadMissingGeoData = useCallback(() => { const notFoundSubstationIds = getEquipmentsNotFoundIds( geoDataRef.current.substationPositionsById, - mapEquipments?.substations as Substation[] + //@ts-expect-error TODO: manage undefined case + mapEquipments?.substations ); const notFoundLineIds = lineFullPath - ? getEquipmentsNotFoundIds(geoDataRef.current.linePositionsById, mapEquipments?.lines as Line[]) + ? getEquipmentsNotFoundIds(geoDataRef.current.linePositionsById, mapEquipments?.lines as GeoDataEquipment[]) : []; if (notFoundSubstationIds.length > 0 || notFoundLineIds.length > 0) { @@ -581,6 +579,7 @@ export const NetworkMapTab = ({ console.info(`Loading geo data of study '${studyUuid}'...`); dispatch(setMapDataLoading(true)); + // @ts-expect-error TODO: manage rootNodeId undefined case const substationPositionsDone = fetchSubstationPositions(studyUuid, rootNodeId).then((data) => { console.info(`Received substations of study '${studyUuid}'...`); const newGeoData = new GeoData(new Map(), geoDataRef.current?.linePositionsById || new Map()); @@ -591,7 +590,8 @@ export const NetworkMapTab = ({ const linePositionsDone = !lineFullPath ? Promise.resolve() - : fetchLinePositions(studyUuid, rootNodeId).then((data) => { + : // @ts-expect-error TODO: manage rootNodeId undefined case + fetchLinePositions(studyUuid, rootNodeId).then((data) => { console.info(`Received lines of study '${studyUuid}'...`); const newGeoData = new GeoData(geoDataRef.current?.substationPositionsById || new Map(), new Map()); newGeoData.setLinePositions(data); @@ -649,11 +649,11 @@ export const NetworkMapTab = ({ if (!isNodeBuilt(currentNode) || !studyUuid) { return; } - const gSMapEquipments = new GSMapEquipments(studyUuid, currentNode?.id, snackError, dispatch, intlRef); + const gSMapEquipments = new GSMapEquipments(studyUuid, currentNode?.id, snackError, dispatch); if (gSMapEquipments) { dispatch(resetMapReloaded()); } - }, [currentNode, dispatch, intlRef, snackError, studyUuid]); + }, [currentNode, dispatch, snackError, studyUuid]); const reloadMapEquipments = useCallback( (currentNodeAtReloadCalling: CurrentTreeNode | null, substationsIds: UUID[] | undefined) => { @@ -662,7 +662,7 @@ export const NetworkMapTab = ({ } const { updatedSubstations, updatedLines, updatedTieLines, updatedHvdcLines } = mapEquipments - ? mapEquipments.reloadImpactedSubstationsEquipments(studyUuid, currentNode, substationsIds ?? null) + ? mapEquipments.reloadImpactedSubstationsEquipments(studyUuid, currentNode, substationsIds) : { updatedSubstations: Promise.resolve([]), updatedLines: Promise.resolve([]), @@ -774,9 +774,9 @@ export const NetworkMapTab = ({ return; } if (deletedEquipments?.length > 0 && mapEquipments) { - deletedEquipments.forEach((deletedEquipment) => { - mapEquipments.removeEquipment(deletedEquipment?.equipmentType, deletedEquipment?.equipmentId); - }); + deletedEquipments.forEach((deletedEquipment) => + mapEquipments.removeEquipment(deletedEquipment?.equipmentType, deletedEquipment?.equipmentId) + ); resetDeletedEquipments(); } }, [deletedEquipments, mapEquipments, resetDeletedEquipments]); @@ -858,13 +858,12 @@ export const NetworkMapTab = ({ } }, [isInitialized, lineFullPath, loadGeoData]); - let choiceVoltageLevelsSubstation: EquipmentMap | null = null; - if (choiceVoltageLevelsSubstationId) { - choiceVoltageLevelsSubstation = mapEquipments?.getSubstation(choiceVoltageLevelsSubstationId); - } + const choiceVoltageLevelsSubstation = choiceVoltageLevelsSubstationId + ? mapEquipments?.getSubstation(choiceVoltageLevelsSubstationId) + : null; const displayEquipmentMenu = ( - equipment: MapEquipment, + equipment: BaseEquipment, x: number, y: number, equipmentType: EquipmentType, @@ -905,14 +904,17 @@ export const NetworkMapTab = ({ ); } - const renderLinePopover = (elementId: string, ref: RefObject) => ( - + const renderLinePopover = useCallback>( + (elementId, ref) => ( + + ), + [loadFlowStatus, studyUuid] ); const renderMap = () => ( @@ -925,7 +927,7 @@ export const NetworkMapTab = ({ filteredNominalVoltages={filteredNominalVoltages} labelsZoomThreshold={LABELS_ZOOM_THRESHOLD} arrowsZoomThreshold={ARROWS_ZOOM_THRESHOLD} - initialPosition={INITIAL_POSITION} + initialPosition={INITIAL_POSITION as Writable} initialZoom={INITIAL_ZOOM} lineFullPath={lineFullPath} lineParallelPath={lineParallelPath} @@ -937,14 +939,26 @@ export const NetworkMapTab = ({ disabled={disabled} onSubstationClick={openVoltageLevel} onSubstationClickChooseVoltageLevel={chooseVoltageLevelForSubstation} - onSubstationMenuClick={(equipment: SubstationMap, x: number, y: number) => - displayEquipmentMenu(equipment as MapEquipment, x, y, EquipmentType.SUBSTATION, isInDrawingMode) + onSubstationMenuClick={(equipment: MapSubstation, x: number, y: number) => + displayEquipmentMenu( + equipment as unknown as BaseEquipment, + x, + y, + EquipmentType.SUBSTATION, + isInDrawingMode + ) } - onLineMenuClick={(equipment: LineMap, x: number, y: number) => - displayEquipmentMenu(equipment as MapEquipment, x, y, EquipmentType.LINE, isInDrawingMode) + onLineMenuClick={(equipment: MapLine, x: number, y: number) => + displayEquipmentMenu(equipment as unknown as BaseEquipment, x, y, EquipmentType.LINE, isInDrawingMode) } - onHvdcLineMenuClick={(equipment: EquipmentMap, x: number, y: number) => - displayEquipmentMenu(equipment as MapEquipment, x, y, EquipmentType.HVDC_LINE, isInDrawingMode) + onHvdcLineMenuClick={(equipment: MapHvdcLine, x: number, y: number) => + displayEquipmentMenu( + equipment as unknown as BaseEquipment, + x, + y, + EquipmentType.HVDC_LINE, + isInDrawingMode + ) } onVoltageLevelMenuClick={voltageLevelMenuClick} mapBoxToken={mapBoxToken} @@ -974,18 +988,30 @@ export const NetworkMapTab = ({ /> ); - function handleChange(newValues: unknown[]) { - setFilteredNominalVoltages(newValues); - onNominalVoltagesChange(newValues); - } + const handleFilteredNominalVoltagesChange = useCallback( + (newValues) => { + setFilteredNominalVoltages(newValues); + onNominalVoltagesChange(newValues); + }, + [onNominalVoltagesChange] + ); + + // Set up filteredNominalVoltages once at map initialization + // TODO: how do we must manage case where voltages change (like when changing node), as filters are already initialized? + const nominalVoltages = mapEquipments?.getNominalVoltages(); + useEffect(() => { + if (nominalVoltages !== undefined && nominalVoltages.length > 0 && filteredNominalVoltages === undefined) { + handleFilteredNominalVoltagesChange(nominalVoltages); + } + }, [filteredNominalVoltages, handleFilteredNominalVoltagesChange, nominalVoltages]); function renderNominalVoltageFilter() { return ( ); diff --git a/src/components/network/nominal-voltage-filter.tsx b/src/components/network/nominal-voltage-filter.tsx index c0a13fb7e1..6d10c54dff 100644 --- a/src/components/network/nominal-voltage-filter.tsx +++ b/src/components/network/nominal-voltage-filter.tsx @@ -5,15 +5,9 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { useEffect } from 'react'; -import List from '@mui/material/List'; -import ListItem from '@mui/material/ListItem'; -import Checkbox from '@mui/material/Checkbox'; -import ListItemText from '@mui/material/ListItemText'; -import Paper from '@mui/material/Paper'; +import { useCallback, useMemo } from 'react'; +import { Button, Checkbox, List, ListItem, ListItemButton, ListItemText, Paper } from '@mui/material'; import { FormattedMessage } from 'react-intl'; -import Button from '@mui/material/Button'; -import { ListItemButton } from '@mui/material'; const styles = { nominalVoltageZone: { @@ -43,83 +37,81 @@ const styles = { }, }; -type NominalVoltageFilterProps = { +export type NominalVoltageFilterProps = { nominalVoltages: number[]; filteredNominalVoltages: number[]; onChange: (filteredNominalVoltages: number[]) => void; }; -const NominalVoltageFilter = ({ nominalVoltages, filteredNominalVoltages, onChange }: NominalVoltageFilterProps) => { - // Set up filteredNominalVoltages - useEffect(() => { - if (nominalVoltages && !filteredNominalVoltages) { - onChange(nominalVoltages as number[]); - } - }, [nominalVoltages, filteredNominalVoltages, onChange]); +export default function NominalVoltageFilter({ + nominalVoltages, + filteredNominalVoltages, + onChange, +}: Readonly) { + const handleToggle = useCallback( + (vnoms: number[], isToggle = false) => { + let newFiltered: number[]; + if (isToggle) { + // we "inverse" the selection for vnoms values + newFiltered = [...filteredNominalVoltages]; + vnoms.forEach((vnom) => { + const currentIndex = filteredNominalVoltages.indexOf(vnom); + if (currentIndex === -1) { + newFiltered.push(vnom); //not previously present, we add it + } else { + newFiltered.splice(currentIndex, 1); // previously present, we remove it + } + }); + } else { + // it's just the new selection + newFiltered = [...vnoms]; + } + onChange(newFiltered); + }, + [filteredNominalVoltages, onChange] + ); + const handleSelectAll = useCallback(() => handleToggle(nominalVoltages), [handleToggle, nominalVoltages]); + const handleSelectNone = useCallback(() => handleToggle([]), [handleToggle]); - const handleToggle = (vnoms: number[], isToggle: boolean) => () => { - // filter on nominal voltage - let newFiltered = [...filteredNominalVoltages]; - if (isToggle) { - vnoms.forEach((vnom) => { - const currentIndex = filteredNominalVoltages.indexOf(vnom); - if (currentIndex === -1) { - newFiltered.push(vnom); - } else { - newFiltered.splice(currentIndex, 1); - } - }); - } else { - newFiltered = [...vnoms]; - } - onChange(newFiltered); - }; + const nominalVoltagesList = useMemo( + () => + nominalVoltages.map((value) => ( + + handleToggle([value], true)} + disabled={!filteredNominalVoltages} + > + + + + + )), + [filteredNominalVoltages, handleToggle, nominalVoltages] + ); - if (!(nominalVoltages?.length > 0)) { + if (nominalVoltages.length <= 0) { return false; } return ( - - - {nominalVoltages.map((value) => { - return ( - - - - - - - ); - })} + {nominalVoltagesList} ); -}; - -export default NominalVoltageFilter; +} diff --git a/src/components/study-container.jsx b/src/components/study-container.jsx index 785633da73..52bf1a096a 100644 --- a/src/components/study-container.jsx +++ b/src/components/study-container.jsx @@ -737,13 +737,7 @@ export function StudyContainer({ view, onChangeTab }) { } // we wait for the user params to be loaded because it can cause some bugs (e.g. with lineFullPath for the map) message={'LoadingRemoteData'} > - + ); diff --git a/src/components/study-pane.jsx b/src/components/study-pane.jsx index d9f2ea899c..579ac17d74 100644 --- a/src/components/study-pane.jsx +++ b/src/components/study-pane.jsx @@ -51,7 +51,7 @@ export const StudyView = { PARAMETERS: 'Parameters', }; -const StudyPane = ({ studyUuid, currentNode, setErrorMessage, ...props }) => { +const StudyPane = ({ studyUuid, currentNode, ...props }) => { const [tableEquipment, setTableEquipment] = useState({ id: null, type: null, @@ -87,7 +87,6 @@ const StudyPane = ({ studyUuid, currentNode, setErrorMessage, ...props }) => { tableEquipment={tableEquipment} onTableEquipementChanged={(newTableEquipment) => setTableEquipment(newTableEquipment)} onChangeTab={props.onChangeTab} - setErrorMessage={setErrorMessage} > {/* using a key in these TabPanelLazy because we can change the nodeUuid in this component */} diff --git a/src/hooks/use-voltage-levels-list-infos.ts b/src/hooks/use-voltage-levels-list-infos.ts index ee4d2f4362..f0c3b0528b 100644 --- a/src/hooks/use-voltage-levels-list-infos.ts +++ b/src/hooks/use-voltage-levels-list-infos.ts @@ -13,7 +13,7 @@ export default function useVoltageLevelsListInfos(studyUuid: UUID, nodeUuid: UUI const [voltageLevelsListInfos, setVoltageLevelsListInfos] = useState([]); useEffect(() => { if (studyUuid && nodeUuid) { - fetchVoltageLevelsListInfos(studyUuid, nodeUuid).then((values) => { + fetchVoltageLevelsListInfos(studyUuid, nodeUuid).then((values: any) => { setVoltageLevelsListInfos( values.sort((a: { id: string }, b: { id: string }) => a.id.localeCompare(b.id)) ); diff --git a/src/redux/actions.ts b/src/redux/actions.ts index 787d9cf1ca..7eb847a84c 100644 --- a/src/redux/actions.ts +++ b/src/redux/actions.ts @@ -36,7 +36,14 @@ import { UUID } from 'crypto'; import type { LiteralUnion, UnknownArray } from 'type-fest'; import NetworkModificationTreeModel from '../components/graph/network-modification-tree-model'; import { NodeInsertModes } from '../components/graph/nodes/node-insert-modes'; -import { LineFlowColorMode, LineFlowMode } from '@powsybl/network-viewer'; +import { + LineFlowColorMode, + LineFlowMode, + type MapHvdcLine, + type MapLine, + type MapSubstation, + type MapTieLine, +} from '@powsybl/network-viewer'; import { AppState, CurrentTreeNode, @@ -236,17 +243,17 @@ export function resetEquipmentsPostLoadflow(): ResetEquipmentsPostLoadflowAction export const MAP_EQUIPMENTS_CREATED = 'MAP_EQUIPMENTS_CREATED'; export type MapEquipmentsCreatedAction = Readonly> & { mapEquipments: GSMapEquipments; - newLines?: MutableUnknownArray; - newTieLines?: MutableUnknownArray; - newSubstations?: MutableUnknownArray; - newHvdcLines?: MutableUnknownArray; + newLines?: MapLine[]; + newTieLines?: MapTieLine[]; + newSubstations?: MapSubstation[]; + newHvdcLines?: MapHvdcLine[]; }; export function mapEquipmentsCreated( mapEquipments: GSMapEquipments, - newLines?: MutableUnknownArray, - newTieLines?: MutableUnknownArray, - newSubstations?: MutableUnknownArray, - newHvdcLines?: MutableUnknownArray + newLines?: MapLine[], + newTieLines?: MapTieLine[], + newSubstations?: MapSubstation[], + newHvdcLines?: MapHvdcLine[] ): MapEquipmentsCreatedAction { return { type: MAP_EQUIPMENTS_CREATED, @@ -776,9 +783,9 @@ export function setEventScenarioDrawerOpen(isEventScenarioDrawerOpen: boolean): export const CENTER_ON_SUBSTATION = 'CENTER_ON_SUBSTATION'; export type CenterOnSubstationAction = Readonly> & { - centerOnSubstation: { to: unknown }; + centerOnSubstation: { to: string }; }; -export function centerOnSubstation(substationId: unknown): CenterOnSubstationAction { +export function centerOnSubstation(substationId: string): CenterOnSubstationAction { return { type: CENTER_ON_SUBSTATION, centerOnSubstation: { to: substationId }, diff --git a/src/redux/reducer.ts b/src/redux/reducer.ts index 60514f3641..0b2a7e92bb 100644 --- a/src/redux/reducer.ts +++ b/src/redux/reducer.ts @@ -302,7 +302,11 @@ import { } from '../utils/store-sort-filter-fields'; import { UUID } from 'crypto'; import { Filter } from '../components/results/common/results-global-filter'; -import { LineFlowColorMode, LineFlowMode } from '@powsybl/network-viewer'; +import { + LineFlowColorMode, + LineFlowMode, + EQUIPMENT_TYPES as NetworkViewerEquipmentType, +} from '@powsybl/network-viewer'; import type { UnknownArray, ValueOf, WritableDeep } from 'type-fest'; import { Node } from '@xyflow/react'; import { SortConfigType, SortWay } from '../hooks/use-aggrid-sort'; @@ -346,7 +350,7 @@ export interface StudyUpdatedEventDataHeader { // Payloads export interface DeletedEquipment { equipmentId: string; - equipmentType: string; + equipmentType: NetworkViewerEquipmentType; } export interface NetworkImpactsInfos { @@ -468,7 +472,7 @@ export interface AppState extends CommonStoreState { notificationIdList: UUID[]; nonEvacuatedEnergyNotif: boolean; recentGlobalFilters: Filter[]; - mapEquipments: GSMapEquipments | null; + mapEquipments: GSMapEquipments | undefined; networkAreaDiagramNbVoltageLevels: number; networkAreaDiagramDepth: number; studyDisplayMode: StudyDisplayMode; @@ -492,9 +496,7 @@ export interface AppState extends CommonStoreState { isExplorerDrawerOpen: boolean; isModificationsDrawerOpen: boolean; isEventScenarioDrawerOpen: boolean; - centerOnSubstation: null | { - to: unknown; - }; + centerOnSubstation: undefined | { to: string }; isModificationsInProgress: boolean; reloadMap: boolean; isMapEquipmentsInitialized: boolean; @@ -629,7 +631,7 @@ const initialState: AppState = { allChildrenIds: null, }, tables: initialTablesState, - mapEquipments: null, + mapEquipments: undefined, geoData: null, networkModificationTreeModel: new NetworkModificationTreeModel(), computedLanguage: getLocalStorageComputedLanguage(), @@ -646,7 +648,7 @@ const initialState: AppState = { isExplorerDrawerOpen: true, isModificationsDrawerOpen: false, isEventScenarioDrawerOpen: false, - centerOnSubstation: null, + centerOnSubstation: undefined, notificationIdList: [], isModificationsInProgress: false, studyDisplayMode: StudyDisplayMode.HYBRID, @@ -836,13 +838,8 @@ export const reducer = createReducer(initialState, (builder) => { }); builder.addCase(MAP_EQUIPMENTS_CREATED, (state, action: MapEquipmentsCreatedAction) => { - let newMapEquipments; //if it's not initialised yet we take the empty one given in action - if (!state.mapEquipments) { - newMapEquipments = action.mapEquipments.newMapEquipmentForUpdate() as GSMapEquipments; - } else { - newMapEquipments = state.mapEquipments.newMapEquipmentForUpdate() as GSMapEquipments; - } + const newMapEquipments = (state.mapEquipments ?? action.mapEquipments).newMapEquipmentForUpdate(); if (action.newLines) { newMapEquipments.lines = action.newLines; newMapEquipments.completeLinesInfos([]); diff --git a/src/services/study/geo-data.js b/src/services/study/geo-data.ts similarity index 77% rename from src/services/study/geo-data.js rename to src/services/study/geo-data.ts index a960fae9e3..d0af0d9990 100644 --- a/src/services/study/geo-data.js +++ b/src/services/study/geo-data.ts @@ -5,10 +5,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +import type { UUID } from 'crypto'; +import type { GeoDataLine, GeoDataSubstation } from '@powsybl/network-viewer'; import { backendFetchJson, getQueryParamsList } from '../utils'; import { getStudyUrlWithNodeUuid } from './index'; -export function fetchSubstationPositions(studyUuid, currentNodeUuid, substationsIds) { +export function fetchSubstationPositions( + studyUuid: UUID, + currentNodeUuid: UUID, + substationsIds?: string[] +): Promise { console.info( `Fetching substation positions of study '${studyUuid}' and node '${currentNodeUuid}' with ids '${substationsIds}'...` ); @@ -22,7 +28,11 @@ export function fetchSubstationPositions(studyUuid, currentNodeUuid, substations return backendFetchJson(fetchSubstationPositionsUrl); } -export function fetchLinePositions(studyUuid, currentNodeUuid, linesIds) { +export function fetchLinePositions( + studyUuid: UUID, + currentNodeUuid: UUID, + linesIds?: string[] +): Promise { console.info( `Fetching line positions of study '${studyUuid}' and node '${currentNodeUuid}' with ids '${linesIds}'...` ); diff --git a/src/services/study/network-map.ts b/src/services/study/network-map.ts index acc7467796..85824dcf10 100644 --- a/src/services/study/network-map.ts +++ b/src/services/study/network-map.ts @@ -9,7 +9,7 @@ import { getStudyUrlWithNodeUuid } from './index'; import { backendFetchJson, backendFetchText, getQueryParamsList } from '../utils'; import { EQUIPMENT_INFOS_TYPES } from '../../components/utils/equipment-types'; import { EquipmentInfos, EquipmentType, createFilter } from '@gridsuite/commons-ui'; -import { fetchNetworkElementsInfos } from './network'; +import { fetchNetworkElementsInfos } from './network-ts'; import { createContingencyList } from 'services/explore'; import { ContingencyList, createIdentifierContingencyList } from './contingency-list'; import { UUID } from 'crypto'; @@ -237,7 +237,7 @@ export async function createMapContingencyList( } const selectedEquipmentsIds = selectedEquipments.map((element) => element.id); - const elementsIds = await fetchNetworkElementsInfos( + const elementsIds = await fetchNetworkElementsInfos( studyUuid, currentNodeUuid, selectedEquipmentsIds, diff --git a/src/services/study/network-ts.ts b/src/services/study/network-ts.ts new file mode 100644 index 0000000000..43634cf6bd --- /dev/null +++ b/src/services/study/network-ts.ts @@ -0,0 +1,124 @@ +/* + * Copyright © 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import type { UnknownArray } from 'type-fest'; +import type { UUID } from 'crypto'; +import type { MapHvdcLine, MapLine, MapSubstation, MapTieLine } from '@powsybl/network-viewer'; +import { EQUIPMENT_INFOS_TYPES, EQUIPMENT_TYPES } from '../../components/utils/equipment-types'; +import { backendFetchJson, getQueryParamsList } from '../utils'; +import { getStudyUrlWithNodeUuid } from './index'; + +/* + * NOTE: this file is temporary until network.js is fully migrated to TS + */ + +/* elements */ +export async function fetchNetworkElementsInfos( + studyUuid: UUID, + currentNodeUuid: UUID, + substationsIds: string[] | undefined, + elementType: string, //TODO found which EQUIPMENT_TYPES enum to use + infoType: string, // TODO migrate to EquipmentInfosTypes + inUpstreamBuiltParentNode?: boolean, + nominalVoltages?: UnknownArray +): Promise { + const substationsCount = substationsIds ? substationsIds.length : 0; + const nominalVoltagesStr = nominalVoltages ? `[${nominalVoltages}]` : '[]'; + + console.info( + `Fetching network '${elementType}' elements '${infoType}' infos of study '${studyUuid}' and node '${currentNodeUuid}' with ${substationsCount} substations ids and ${nominalVoltagesStr} nominal voltages.` + ); + + const nominalVoltagesParams = getQueryParamsList(nominalVoltages, 'nominalVoltages'); + + const nominalVoltagesParamsList = nominalVoltages && nominalVoltages?.length > 0 ? '&' + nominalVoltagesParams : ''; + + const urlSearchParams = new URLSearchParams(); + if (inUpstreamBuiltParentNode !== undefined) { + urlSearchParams.append('inUpstreamBuiltParentNode', String(inUpstreamBuiltParentNode)); + } + urlSearchParams.append('infoType', infoType); + urlSearchParams.append('elementType', elementType); + + const fetchElementsUrl = + getStudyUrlWithNodeUuid(studyUuid, currentNodeUuid) + + '/network/elements' + + '?' + + urlSearchParams + + nominalVoltagesParamsList; + console.debug(fetchElementsUrl); + + return await backendFetchJson(fetchElementsUrl, { + method: 'post', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(substationsIds ?? null), + }); +} + +export function fetchSubstationsMapInfos( + studyUuid: UUID, + currentNodeUuid: UUID, + substationsIds: string[] | undefined, + inUpstreamBuiltParentNode: boolean +) { + return fetchNetworkElementsInfos( + studyUuid, + currentNodeUuid, + substationsIds, + EQUIPMENT_TYPES.SUBSTATION, + EQUIPMENT_INFOS_TYPES.MAP.type, + inUpstreamBuiltParentNode + ); +} + +export function fetchLinesMapInfos( + studyUuid: UUID, + currentNodeUuid: UUID, + substationsIds: string[] | undefined, + inUpstreamBuiltParentNode: boolean +) { + return fetchNetworkElementsInfos( + studyUuid, + currentNodeUuid, + substationsIds, + EQUIPMENT_TYPES.LINE, + EQUIPMENT_INFOS_TYPES.MAP.type, + inUpstreamBuiltParentNode + ); +} + +export function fetchTieLinesMapInfos( + studyUuid: UUID, + currentNodeUuid: UUID, + substationsIds: string[] | undefined, + inUpstreamBuiltParentNode: boolean +) { + return fetchNetworkElementsInfos( + studyUuid, + currentNodeUuid, + substationsIds, + EQUIPMENT_TYPES.TIE_LINE, + EQUIPMENT_INFOS_TYPES.MAP.type, + inUpstreamBuiltParentNode + ); +} + +export function fetchHvdcLinesMapInfos( + studyUuid: UUID, + currentNodeUuid: UUID, + substationsIds: string[] | undefined, + inUpstreamBuiltParentNode: boolean +) { + return fetchNetworkElementsInfos( + studyUuid, + currentNodeUuid, + substationsIds, + EQUIPMENT_TYPES.HVDC_LINE, + EQUIPMENT_INFOS_TYPES.MAP.type, + inUpstreamBuiltParentNode + ); +} diff --git a/src/services/study/network.js b/src/services/study/network.js index ae4d1ca5ee..6232b782e9 100644 --- a/src/services/study/network.js +++ b/src/services/study/network.js @@ -7,7 +7,8 @@ import { getStudyUrlWithNodeUuid, PREFIX_STUDY_QUERIES } from './index'; import { EQUIPMENT_INFOS_TYPES, EQUIPMENT_TYPES } from '../../components/utils/equipment-types'; -import { backendFetch, backendFetchJson, backendFetchText, getQueryParamsList, getUrlWithToken } from '../utils'; +import { backendFetch, backendFetchJson, backendFetchText, getUrlWithToken } from '../utils'; +import { fetchNetworkElementsInfos } from './network-ts'; /* voltage-levels */ export function getVoltageLevelSingleLineDiagram( @@ -117,49 +118,6 @@ export function getSubstationSingleLineDiagram( ); } -/* elements */ -export function fetchNetworkElementsInfos( - studyUuid, - currentNodeUuid, - substationsIds, - elementType, - infoType, - inUpstreamBuiltParentNode, - nominalVoltages -) { - const substationsCount = substationsIds ? substationsIds.length : 0; - const nominalVoltagesStr = nominalVoltages ? `[${nominalVoltages}]` : '[]'; - - console.info( - `Fetching network '${elementType}' elements '${infoType}' infos of study '${studyUuid}' and node '${currentNodeUuid}' with ${substationsCount} substations ids and ${nominalVoltagesStr} nominal voltages.` - ); - - const nominalVoltagesParams = getQueryParamsList(nominalVoltages, 'nominalVoltages'); - - const nominalVoltagesParamsList = nominalVoltages && nominalVoltages?.length > 0 ? '&' + nominalVoltagesParams : ''; - - const urlSearchParams = new URLSearchParams(); - if (inUpstreamBuiltParentNode !== undefined) { - urlSearchParams.append('inUpstreamBuiltParentNode', inUpstreamBuiltParentNode); - } - urlSearchParams.append('infoType', infoType); - urlSearchParams.append('elementType', elementType); - - const fetchElementsUrl = - getStudyUrlWithNodeUuid(studyUuid, currentNodeUuid) + - '/network/elements' + - '?' + - urlSearchParams + - nominalVoltagesParamsList; - console.debug(fetchElementsUrl); - - return backendFetchJson(fetchElementsUrl, { - method: 'post', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(substationsIds ?? null), - }); -} - export function fetchNetworkElementInfos( studyUuid, currentNodeUuid, @@ -190,50 +148,6 @@ export function fetchNetworkElementInfos( return backendFetchJson(fetchElementsUrl); } -export function fetchSubstationsMapInfos(studyUuid, currentNodeUuid, substationsIds, inUpstreamBuiltParentNode) { - return fetchNetworkElementsInfos( - studyUuid, - currentNodeUuid, - substationsIds, - EQUIPMENT_TYPES.SUBSTATION, - EQUIPMENT_INFOS_TYPES.MAP.type, - inUpstreamBuiltParentNode - ); -} - -export function fetchLinesMapInfos(studyUuid, currentNodeUuid, substationsIds, inUpstreamBuiltParentNode) { - return fetchNetworkElementsInfos( - studyUuid, - currentNodeUuid, - substationsIds, - EQUIPMENT_TYPES.LINE, - EQUIPMENT_INFOS_TYPES.MAP.type, - inUpstreamBuiltParentNode - ); -} - -export function fetchTieLinesMapInfos(studyUuid, currentNodeUuid, substationsIds, inUpstreamBuiltParentNode) { - return fetchNetworkElementsInfos( - studyUuid, - currentNodeUuid, - substationsIds, - EQUIPMENT_TYPES.TIE_LINE, - EQUIPMENT_INFOS_TYPES.MAP.type, - inUpstreamBuiltParentNode - ); -} - -export function fetchHvdcLinesMapInfos(studyUuid, currentNodeUuid, substationsIds, inUpstreamBuiltParentNode) { - return fetchNetworkElementsInfos( - studyUuid, - currentNodeUuid, - substationsIds, - EQUIPMENT_TYPES.HVDC_LINE, - EQUIPMENT_INFOS_TYPES.MAP.type, - inUpstreamBuiltParentNode - ); -} - export function fetchSubstations(studyUuid, currentNodeUuid, substationsIds) { return fetchNetworkElementsInfos( studyUuid,