From 1aa4cd24f397e48f49096898bb26e9f9d45cda70 Mon Sep 17 00:00:00 2001 From: dbraquart <107846716+dbraquart@users.noreply.github.com> Date: Thu, 19 Dec 2024 15:06:35 +0100 Subject: [PATCH] Use spreadsheet-config-server to store network visualization parameters per study (#2449) Signed-off-by: David BRAQUART --- src/components/app.jsx | 86 +++------- src/components/diagrams/diagram-pane.tsx | 61 ++++--- .../network-area-diagram-content.tsx | 7 +- .../position-diagram-pane.tsx | 29 ++-- .../network-visualizations-form.tsx | 4 +- .../network-visualizations-parameters.tsx | 111 +++++------- .../network-visualizations-utils.ts | 84 +--------- .../network-visualizations.types.tsx | 37 ++++ src/components/map-viewer.jsx | 32 +--- src/components/network/network-map-tab.tsx | 17 +- src/redux/actions.ts | 158 ++---------------- src/redux/reducer.ts | 106 +++--------- src/services/study/study-config.ts | 32 ++++ src/translations/en.json | 2 + src/translations/fr.json | 2 + 15 files changed, 250 insertions(+), 518 deletions(-) create mode 100644 src/components/dialogs/parameters/network-visualizations/network-visualizations.types.tsx create mode 100644 src/services/study/study-config.ts diff --git a/src/components/app.jsx b/src/components/app.jsx index 3a4b72bb76..32622c7c0b 100644 --- a/src/components/app.jsx +++ b/src/components/app.jsx @@ -27,23 +27,11 @@ import { FormattedMessage } from 'react-intl'; import { APP_NAME, COMMON_APP_NAME, - PARAM_CENTER_LABEL, - PARAM_COMPONENT_LIBRARY, PARAM_DEVELOPER_MODE, - PARAM_DIAGONAL_LABEL, PARAM_FAVORITE_CONTINGENCY_LISTS, PARAM_FLUX_CONVENTION, - PARAM_INIT_NAD_WITH_GEO_DATA, PARAM_LANGUAGE, PARAM_LIMIT_REDUCTION, - PARAM_LINE_FLOW_ALERT_THRESHOLD, - PARAM_LINE_FLOW_COLOR_MODE, - PARAM_LINE_FLOW_MODE, - PARAM_LINE_FULL_PATH, - PARAM_LINE_PARALLEL_PATH, - PARAM_MAP_BASEMAP, - PARAM_MAP_MANUAL_REFRESH, - PARAM_SUBSTATION_LAYOUT, PARAM_THEME, PARAM_USE_NAME, } from '../utils/config-params'; @@ -64,30 +52,20 @@ import { changeLockedColumns, changeReorderedColumns, limitReductionModified, - selectCenterLabelState, - selectComponentLibrary, selectComputedLanguage, - selectDiagonalLabelState, selectEnableDeveloperMode, selectFavoriteContingencyLists, selectFluxConvention, - selectInitNadWithGeoData, selectLanguage, selectLimitReduction, - selectLineFlowAlertThreshold, - selectLineFlowColorMode, - selectLineFlowMode, - selectLineFullPathState, - selectLineParallelPathState, - selectMapBaseMap, - selectMapManualRefresh, - selectSubstationLayout, selectTheme, selectUseName, setOptionalServices, setParamsLoaded, + setUpdateNetworkVisualizationParameters, } from '../redux/actions'; import { NOTIFICATIONS_URL_KEYS } from './utils/notificationsProvider-utils'; +import { getNetworkVisualizationParameters } from '../services/study/study-config.ts'; const noUserManager = { instance: null, error: null }; @@ -97,6 +75,7 @@ const App = () => { const { snackError } = useSnackMessage(); const user = useSelector((state) => state.user); + const studyUuid = useSelector((state) => state.studyUuid); const tablesNamesIndexes = useSelector((state) => state.tables.namesIndexes); const tablesDefinitionIndexes = useSelector((state) => state.tables.definitionIndexes); @@ -114,6 +93,14 @@ const App = () => { const [tabIndex, setTabIndex] = useState(0); + const updateNetworkVisualizationsParams = useCallback( + (params) => { + console.debug('received network visualizations parameters : ', params); + dispatch(setUpdateNetworkVisualizationParameters(params)); + }, + [dispatch] + ); + const updateParams = useCallback( (params) => { console.debug('received UI parameters : ', params); @@ -133,51 +120,15 @@ const App = () => { dispatch(selectLanguage(param.value)); dispatch(selectComputedLanguage(getComputedLanguage(param.value))); break; - case PARAM_CENTER_LABEL: - dispatch(selectCenterLabelState(param.value === 'true')); - break; - case PARAM_DIAGONAL_LABEL: - dispatch(selectDiagonalLabelState(param.value === 'true')); - break; case PARAM_LIMIT_REDUCTION: dispatch(selectLimitReduction(param.value)); break; - case PARAM_LINE_FLOW_ALERT_THRESHOLD: - dispatch(selectLineFlowAlertThreshold(param.value)); - break; - case PARAM_LINE_FLOW_COLOR_MODE: - dispatch(selectLineFlowColorMode(param.value)); - break; - case PARAM_LINE_FLOW_MODE: - dispatch(selectLineFlowMode(param.value)); - break; case PARAM_FLUX_CONVENTION: dispatch(selectFluxConvention(param.value)); break; case PARAM_DEVELOPER_MODE: dispatch(selectEnableDeveloperMode(param.value === 'true')); break; - case PARAM_INIT_NAD_WITH_GEO_DATA: - dispatch(selectInitNadWithGeoData(param.value === 'true')); - break; - case PARAM_LINE_FULL_PATH: - dispatch(selectLineFullPathState(param.value === 'true')); - break; - case PARAM_LINE_PARALLEL_PATH: - dispatch(selectLineParallelPathState(param.value === 'true')); - break; - case PARAM_SUBSTATION_LAYOUT: - dispatch(selectSubstationLayout(param.value)); - break; - case PARAM_COMPONENT_LIBRARY: - dispatch(selectComponentLibrary(param.value)); - break; - case PARAM_MAP_MANUAL_REFRESH: - dispatch(selectMapManualRefresh(param.value === 'true')); - break; - case PARAM_MAP_BASEMAP: - dispatch(selectMapBaseMap(param.value)); - break; case PARAM_USE_NAME: dispatch(selectUseName(param.value === 'true')); break; @@ -343,7 +294,11 @@ const App = () => { }, [initialMatchSilentRenewCallbackUrl, dispatch, initialMatchSigninCallbackUrl]); useEffect(() => { - if (user !== null) { + if (user !== null && studyUuid !== null) { + const fetchNetworkVisualizationParametersPromise = getNetworkVisualizationParameters(studyUuid).then( + (params) => updateNetworkVisualizationsParams(params) + ); + const fetchCommonConfigPromise = fetchConfigParameters(COMMON_APP_NAME).then((params) => updateParams(params) ); @@ -409,7 +364,12 @@ const App = () => { // This might not be necessary but allows to gradually migrate parts // of the code that don't subscribe to exactly the parameters they need. // Code that depends on this could be rewritten to depend on what it acually needs. - Promise.all([fetchCommonConfigPromise, fetchAppConfigPromise, fetchOptionalServices]) + Promise.all([ + fetchNetworkVisualizationParametersPromise, + fetchCommonConfigPromise, + fetchAppConfigPromise, + fetchOptionalServices, + ]) .then(() => { dispatch(setParamsLoaded()); }) @@ -420,7 +380,7 @@ const App = () => { }) ); } - }, [user, dispatch, updateParams, snackError]); + }, [user, studyUuid, dispatch, updateParams, snackError, updateNetworkVisualizationsParams]); const onChangeTab = useCallback((newTabIndex) => { setTabIndex(newTabIndex); diff --git a/src/components/diagrams/diagram-pane.tsx b/src/components/diagrams/diagram-pane.tsx index f1a65a5a89..35de26337a 100644 --- a/src/components/diagrams/diagram-pane.tsx +++ b/src/components/diagrams/diagram-pane.tsx @@ -7,15 +7,7 @@ import { Fragment, useCallback, useEffect, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { - PARAM_CENTER_LABEL, - PARAM_COMPONENT_LIBRARY, - PARAM_DIAGONAL_LABEL, - PARAM_INIT_NAD_WITH_GEO_DATA, - PARAM_LANGUAGE, - PARAM_SUBSTATION_LAYOUT, - PARAM_USE_NAME, -} from '../../utils/config-params'; +import { PARAM_LANGUAGE, PARAM_USE_NAME } from '../../utils/config-params'; import { Box, Chip, Stack, Theme } from '@mui/material'; import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward'; import TimelineIcon from '@mui/icons-material/Timeline'; @@ -60,11 +52,8 @@ const useDisplayView = (studyUuid: UUID, currentNode: CurrentTreeNode) => { const { snackError } = useSnackMessage(); const paramUseName = useSelector((state: AppState) => state[PARAM_USE_NAME]); const { getNameOrId } = useNameOrId(); - const centerName = useSelector((state: AppState) => state[PARAM_CENTER_LABEL]); - const diagonalName = useSelector((state: AppState) => state[PARAM_DIAGONAL_LABEL]); - const substationLayout = useSelector((state: AppState) => state[PARAM_SUBSTATION_LAYOUT]); - const componentLibrary = useSelector((state: AppState) => state[PARAM_COMPONENT_LIBRARY]); const language = useSelector((state: AppState) => state[PARAM_LANGUAGE]); + const networkVisuParams = useSelector((state: AppState) => state.networkVisualizationsParameters); const checkAndGetVoltageLevelSingleLineDiagramUrl = useCallback( (voltageLevelId: UUID) => @@ -74,14 +63,22 @@ const useDisplayView = (studyUuid: UUID, currentNode: CurrentTreeNode) => { currentNode?.id, voltageLevelId, paramUseName, - centerName, - diagonalName, - componentLibrary, + networkVisuParams.singleLineDiagramParameters.centerLabel, + networkVisuParams.singleLineDiagramParameters.diagonalLabel, + networkVisuParams.singleLineDiagramParameters.componentLibrary, SLD_DISPLAY_MODE.STATE_VARIABLE, language ) : null, - [currentNode, studyUuid, paramUseName, centerName, diagonalName, componentLibrary, language] + [ + currentNode, + studyUuid, + paramUseName, + networkVisuParams.singleLineDiagramParameters.centerLabel, + networkVisuParams.singleLineDiagramParameters.diagonalLabel, + networkVisuParams.singleLineDiagramParameters.componentLibrary, + language, + ] ); const checkAndGetSubstationSingleLineDiagramUrl = useCallback( @@ -92,22 +89,36 @@ const useDisplayView = (studyUuid: UUID, currentNode: CurrentTreeNode) => { currentNode?.id, voltageLevelId, paramUseName, - centerName, - diagonalName, - substationLayout, - componentLibrary, + networkVisuParams.singleLineDiagramParameters.centerLabel, + networkVisuParams.singleLineDiagramParameters.diagonalLabel, + networkVisuParams.singleLineDiagramParameters.substationLayout, + networkVisuParams.singleLineDiagramParameters.componentLibrary, language ) : null, - [centerName, componentLibrary, diagonalName, studyUuid, substationLayout, paramUseName, currentNode, language] + [ + networkVisuParams.singleLineDiagramParameters.centerLabel, + networkVisuParams.singleLineDiagramParameters.componentLibrary, + networkVisuParams.singleLineDiagramParameters.diagonalLabel, + studyUuid, + networkVisuParams.singleLineDiagramParameters.substationLayout, + paramUseName, + currentNode, + language, + ] ); - const initNadWithGeoData = useSelector((state: AppState) => state[PARAM_INIT_NAD_WITH_GEO_DATA]); const checkAndGetNetworkAreaDiagramUrl = useCallback( (voltageLevelsIds: UUID[], depth: number) => isNodeBuilt(currentNode) - ? getNetworkAreaDiagramUrl(studyUuid, currentNode?.id, voltageLevelsIds, depth, initNadWithGeoData) + ? getNetworkAreaDiagramUrl( + studyUuid, + currentNode?.id, + voltageLevelsIds, + depth, + networkVisuParams.networkAreaDiagramParameters.initNadWithGeoData + ) : null, - [studyUuid, currentNode, initNadWithGeoData] + [studyUuid, currentNode, networkVisuParams.networkAreaDiagramParameters.initNadWithGeoData] ); // this callback returns a promise diff --git a/src/components/diagrams/networkAreaDiagram/network-area-diagram-content.tsx b/src/components/diagrams/networkAreaDiagram/network-area-diagram-content.tsx index 9efbd206c1..58d5327f22 100644 --- a/src/components/diagrams/networkAreaDiagram/network-area-diagram-content.tsx +++ b/src/components/diagrams/networkAreaDiagram/network-area-diagram-content.tsx @@ -29,7 +29,6 @@ import { mergeSx } from '../../utils/functions'; import ComputingType from '../../computing-status/computing-type'; import { AppState } from 'redux/reducer'; import { storeNetworkAreaDiagramNodeMovement } from '../../../redux/actions'; -import { PARAM_INIT_NAD_WITH_GEO_DATA } from '../../../utils/config-params'; import { getNadIdentifier } from '../diagram-utils'; import EquipmentPopover from 'components/tooltips/equipment-popover'; import { UUID } from 'crypto'; @@ -156,7 +155,7 @@ function NetworkAreaDiagramContent(props: NetworkAreaDiagramContentProps) { const loadFlowStatus = useSelector((state: AppState) => state.computingStatus[ComputingType.LOAD_FLOW]); const nadNodeMovements = useSelector((state: AppState) => state.nadNodeMovements); const diagramStates = useSelector((state: AppState) => state.diagramStates); - const initNadWithGeoData = useSelector((state: AppState) => state[PARAM_INIT_NAD_WITH_GEO_DATA]); + const networkVisuParams = useSelector((state: AppState) => state.networkVisualizationsParameters); const [shouldDisplayTooltip, setShouldDisplayTooltip] = useState(false); const [anchorPosition, setAnchorPosition] = useState({ top: 0, left: 0 }); const [hoveredEquipmentId, setHoveredEquipmentId] = useState(''); @@ -164,8 +163,8 @@ function NetworkAreaDiagramContent(props: NetworkAreaDiagramContentProps) { const studyUuid = useSelector((state: AppState) => state.studyUuid); const nadIdentifier = useMemo(() => { - return getNadIdentifier(diagramStates, initNadWithGeoData); - }, [diagramStates, initNadWithGeoData]); + return getNadIdentifier(diagramStates, networkVisuParams.networkAreaDiagramParameters.initNadWithGeoData); + }, [diagramStates, networkVisuParams.networkAreaDiagramParameters.initNadWithGeoData]); const onMoveNodeCallback = useCallback( (equipmentId: string, nodeId: string, x: number, y: number, xOrig: number, yOrig: number) => { diff --git a/src/components/diagrams/singleLineDiagram/position-diagram-pane.tsx b/src/components/diagrams/singleLineDiagram/position-diagram-pane.tsx index f5202d284e..b6158c245a 100644 --- a/src/components/diagrams/singleLineDiagram/position-diagram-pane.tsx +++ b/src/components/diagrams/singleLineDiagram/position-diagram-pane.tsx @@ -8,13 +8,7 @@ import Dialog from '@mui/material/Dialog'; import { useCallback, useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; -import { - PARAM_CENTER_LABEL, - PARAM_COMPONENT_LIBRARY, - PARAM_DIAGONAL_LABEL, - PARAM_LANGUAGE, - PARAM_USE_NAME, -} from '../../../utils/config-params'; +import { PARAM_LANGUAGE, PARAM_USE_NAME } from '../../../utils/config-params'; import PositionDiagram from './position-diagram'; import { SLD_DISPLAY_MODE } from '../../network/constants'; import { DiagramType } from '../diagram-common'; @@ -39,10 +33,8 @@ const PositionDiagramPane: FC = ({ studyUuid, }) => { const useName = useSelector((state: AppState) => state[PARAM_USE_NAME]); - const centerName = useSelector((state: AppState) => state[PARAM_CENTER_LABEL]); - const diagonalName = useSelector((state: AppState) => state[PARAM_DIAGONAL_LABEL]); - const componentLibrary = useSelector((state: AppState) => state[PARAM_COMPONENT_LIBRARY]); const language = useSelector((state: AppState) => state[PARAM_LANGUAGE]); + const networkVisuParams = useSelector((state: AppState) => state.networkVisualizationsParameters); const [svgUrl, setSvgUrl] = useState(null); const handleClose = () => { @@ -57,13 +49,22 @@ const PositionDiagramPane: FC = ({ currentNodeUuid, voltageLevelId?.id, useName, - centerName, - diagonalName, - componentLibrary, + networkVisuParams.singleLineDiagramParameters.centerLabel, + networkVisuParams.singleLineDiagramParameters.diagonalLabel, + networkVisuParams.singleLineDiagramParameters.componentLibrary, SLD_DISPLAY_MODE.FEEDER_POSITION, language ), - [studyUuid, currentNodeUuid, voltageLevelId?.id, useName, centerName, diagonalName, componentLibrary, language] + [ + studyUuid, + currentNodeUuid, + voltageLevelId?.id, + useName, + networkVisuParams.singleLineDiagramParameters.centerLabel, + networkVisuParams.singleLineDiagramParameters.diagonalLabel, + networkVisuParams.singleLineDiagramParameters.componentLibrary, + language, + ] ); useEffect(() => { diff --git a/src/components/dialogs/parameters/network-visualizations/network-visualizations-form.tsx b/src/components/dialogs/parameters/network-visualizations/network-visualizations-form.tsx index a034b7cc9e..21f670b286 100644 --- a/src/components/dialogs/parameters/network-visualizations/network-visualizations-form.tsx +++ b/src/components/dialogs/parameters/network-visualizations/network-visualizations-form.tsx @@ -49,7 +49,7 @@ export const networkVisualizationParametersSchema = yup.object().shape({ [PARAM_LINE_PARALLEL_PATH]: yup.boolean(), [PARAM_LINE_FLOW_MODE]: yup.string(), [PARAM_LINE_FLOW_COLOR_MODE]: yup.string(), - [PARAM_LINE_FLOW_ALERT_THRESHOLD]: yup.number().positive(), + [PARAM_LINE_FLOW_ALERT_THRESHOLD]: yup.number().positive().max(100), [PARAM_MAP_MANUAL_REFRESH]: yup.boolean(), [PARAM_MAP_BASEMAP]: yup.string(), }), @@ -57,7 +57,7 @@ export const networkVisualizationParametersSchema = yup.object().shape({ [PARAM_DIAGONAL_LABEL]: yup.boolean(), [PARAM_CENTER_LABEL]: yup.boolean(), [PARAM_SUBSTATION_LAYOUT]: yup.string(), - [PARAM_COMPONENT_LIBRARY]: yup.string().nullable(), + [PARAM_COMPONENT_LIBRARY]: yup.string(), }), [TabValue.NETWORK_AREA_DIAGRAM]: yup.object().shape({ [PARAM_INIT_NAD_WITH_GEO_DATA]: yup.boolean(), diff --git a/src/components/dialogs/parameters/network-visualizations/network-visualizations-parameters.tsx b/src/components/dialogs/parameters/network-visualizations/network-visualizations-parameters.tsx index 9e65f14392..e0c6dafbad 100644 --- a/src/components/dialogs/parameters/network-visualizations/network-visualizations-parameters.tsx +++ b/src/components/dialogs/parameters/network-visualizations/network-visualizations-parameters.tsx @@ -4,30 +4,32 @@ * 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 { FunctionComponent, SyntheticEvent, useCallback, useEffect, useMemo, useState } from 'react'; +import { FunctionComponent, SyntheticEvent, useCallback, useEffect, useState } from 'react'; import { Grid, Tab, Tabs } from '@mui/material'; import { FormattedMessage } from 'react-intl'; import { styles, TabPanel } from '../parameters'; import { SingleLineDiagramParameters, useGetAvailableComponentLibraries } from './single-line-diagram-parameters'; import { NetworkAreaDiagramParameters } from './network-area-diagram-parameters'; import { MapParameters } from './map-parameters'; -import { useSelector } from 'react-redux'; -import { AppState } from '../../../../redux/reducer'; +import { useDispatch, useSelector } from 'react-redux'; +import { AppState, NotificationType } from '../../../../redux/reducer'; import { useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; import { initialNetworkVisualizationParametersForm, - NetworkVisualizationParametersForm, networkVisualizationParametersSchema, } from './network-visualizations-form'; import { CustomFormProvider, SubmitButton, useSnackMessage } from '@gridsuite/commons-ui'; -import { - formatParametersToSend, - fromNetworkVisualizationsParamsDataToFormValues, - TabValue, -} from './network-visualizations-utils'; +import { TabValue } from './network-visualizations-utils'; import { mergeSx } from '../../../utils/functions'; -import { updateConfigParameters } from '../../../../services/config'; +import { NetworkVisualizationParameters } from './network-visualizations.types'; +import { + getNetworkVisualizationParameters, + setNetworkVisualizationParameters, +} from '../../../../services/study/study-config'; +import { UUID } from 'crypto'; +import { UPDATE_TYPE_HEADER } from '../common/computation-parameters-util'; +import { setUpdateNetworkVisualizationParameters } from '../../../../redux/actions'; interface NetworkVisualizationsParametersProps { setHaveDirtyFields: (haveDirtyFields: boolean) => void; @@ -39,54 +41,11 @@ export const NetworkVisualizationsParameters: FunctionComponent state.user); const componentLibraries = useGetAvailableComponentLibraries(user); const [tabValue, setTabValue] = useState(TabValue.MAP); - const [dirtyFields, setDirtyFields] = useState>({}); - //Map parameters - const lineFullPath = useSelector((state: AppState) => state.lineFullPath); - const lineParallelPath = useSelector((state: AppState) => state.lineParallelPath); - const lineFlowMode = useSelector((state: AppState) => state.lineFlowMode); - const lineFlowColorMode = useSelector((state: AppState) => state.lineFlowColorMode); - const lineFlowAlertThreshold = useSelector((state: AppState) => state.lineFlowAlertThreshold); - const mapManualRefresh = useSelector((state: AppState) => state.mapManualRefresh); - const mapBaseMap = useSelector((state: AppState) => state.mapBaseMap); - //Single line diagram parameters - const diagonalLabel = useSelector((state: AppState) => state.diagonalLabel); - const centerLabel = useSelector((state: AppState) => state.centerLabel); - const substationLayout = useSelector((state: AppState) => state.substationLayout); - const componentLibrary = useSelector((state: AppState) => state.componentLibrary); - //Network area diagram parameters - const initNadWithGeoData = useSelector((state: AppState) => state.initNadWithGeoData); - - const parameters = useMemo(() => { - return { - lineFullPath, - lineParallelPath, - lineFlowMode, - lineFlowColorMode, - lineFlowAlertThreshold, - mapManualRefresh, - mapBaseMap, - diagonalLabel, - centerLabel, - substationLayout, - componentLibrary, - initNadWithGeoData, - }; - }, [ - lineFullPath, - lineParallelPath, - lineFlowMode, - lineFlowColorMode, - lineFlowAlertThreshold, - mapManualRefresh, - mapBaseMap, - diagonalLabel, - centerLabel, - substationLayout, - componentLibrary, - initNadWithGeoData, - ]); - + const studyUuid = useSelector((state: AppState) => state.studyUuid); + const networkVisualizationsParameters = useSelector((state: AppState) => state.networkVisualizationsParameters); + const studyUpdated = useSelector((state: AppState) => state.studyUpdated); const { snackError } = useSnackMessage(); + const dispatch = useDispatch(); const handleTabChange = useCallback((_: SyntheticEvent, newValue: TabValue) => { setTabValue(newValue); @@ -104,27 +63,41 @@ export const NetworkVisualizationsParameters: FunctionComponent { - if (parameters) { - reset(fromNetworkVisualizationsParamsDataToFormValues(parameters)); + if (networkVisualizationsParameters) { + reset(networkVisualizationsParameters); } - }, [reset, parameters]); + }, [reset, networkVisualizationsParameters]); + + useEffect(() => { + if ( + studyUpdated.eventData.headers && + studyUpdated.eventData.headers[UPDATE_TYPE_HEADER] === + NotificationType.NETWORK_VISUALIZATION_PARAMETERS_UPDATED + ) { + getNetworkVisualizationParameters(studyUuid as UUID) + .then((params: NetworkVisualizationParameters) => { + dispatch(setUpdateNetworkVisualizationParameters(params)); + }) + .catch((error) => { + snackError({ + messageTxt: error.message, + headerId: 'getNetworkVisualizationsParametersError', + }); + }); + } + }, [dispatch, reset, snackError, studyUpdated, studyUuid]); const onSubmit = useCallback( - (newParams: NetworkVisualizationParametersForm) => { - // We need to send only the fields that have been changed in order to get the proper notification. - updateConfigParameters(formatParametersToSend(newParams, dirtyFields)).catch((error) => { + (newParams: NetworkVisualizationParameters) => { + setNetworkVisualizationParameters(studyUuid as UUID, newParams).catch((error) => { snackError({ messageTxt: error.message, - headerId: 'updateVoltageInitParametersError', + headerId: 'updateNetworkVisualizationsParametersError', }); }); }, - [dirtyFields, snackError] + [studyUuid, snackError] ); - // to keep track of the changed fields because formState.dirtyFields is always empty inside onSubmit. - useEffect(() => { - setDirtyFields(formState.dirtyFields); - }, [formState, setDirtyFields]); return ( diff --git a/src/components/dialogs/parameters/network-visualizations/network-visualizations-utils.ts b/src/components/dialogs/parameters/network-visualizations/network-visualizations-utils.ts index abc468f1f4..da7fcc1740 100644 --- a/src/components/dialogs/parameters/network-visualizations/network-visualizations-utils.ts +++ b/src/components/dialogs/parameters/network-visualizations/network-visualizations-utils.ts @@ -5,30 +5,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import { LineFlowColorMode, LineFlowMode } from '@powsybl/network-viewer'; -import { - MAP_BASEMAP_CARTO, - MAP_BASEMAP_CARTO_NOLABEL, - MAP_BASEMAP_MAPBOX, - PARAM_CENTER_LABEL, - PARAM_COMPONENT_LIBRARY, - PARAM_DIAGONAL_LABEL, - PARAM_INIT_NAD_WITH_GEO_DATA, - PARAM_LINE_FLOW_ALERT_THRESHOLD, - PARAM_LINE_FLOW_COLOR_MODE, - PARAM_LINE_FLOW_MODE, - PARAM_LINE_FULL_PATH, - PARAM_LINE_PARALLEL_PATH, - PARAM_MAP_BASEMAP, - PARAM_MAP_MANUAL_REFRESH, - PARAM_SUBSTATION_LAYOUT, -} from '../../../../utils/config-params'; +import { MAP_BASEMAP_CARTO, MAP_BASEMAP_CARTO_NOLABEL, MAP_BASEMAP_MAPBOX } from '../../../../utils/config-params'; import { SubstationLayout } from '../../../diagrams/diagram-common'; -import { NetworkVisualizationParametersForm } from './network-visualizations-form'; export enum TabValue { - MAP = 'Map', - SINGLE_LINE_DIAGRAM = 'SingleLineDiagram', - NETWORK_AREA_DIAGRAM = 'NetworkAreaDiagram', + MAP = 'mapParameters', + SINGLE_LINE_DIAGRAM = 'singleLineDiagramParameters', + NETWORK_AREA_DIAGRAM = 'networkAreaDiagramParameters', } export const MAP_MANUAL_REFRESH = 'MapManualRefresh'; export const ALERT_THRESHOLD_LABEL = 'AlertThresholdLabel'; @@ -42,24 +25,6 @@ export const SUBSTATION_LAYOUT = 'SubstationLayout'; export const COMPONENT_LIBRARY = 'ComponentLibrary'; export const INIT_NAD_WITH_GEO_DATA = 'initNadWithGeoData'; -export interface NetworkVisualizationsParams { - lineFullPath: boolean; - lineParallelPath: boolean; - lineFlowMode: LineFlowMode; - lineFlowColorMode: LineFlowColorMode; - lineFlowAlertThreshold: number; - mapManualRefresh: boolean; - mapBaseMap: string; - diagonalLabel: boolean; - centerLabel: boolean; - substationLayout: string; - componentLibrary: unknown; - initNadWithGeoData: boolean; -} -export interface NestedObject { - [key: string]: NestedObject | string | number | boolean; -} - export const INTL_LINE_FLOW_MODE_OPTIONS = [ { id: LineFlowMode.STATIC_ARROWS, @@ -100,29 +65,6 @@ export const INTL_MAP_BASE_MAP_OPTIONS = [ }, ]; -export const fromNetworkVisualizationsParamsDataToFormValues = (parameters: NetworkVisualizationsParams) => { - return { - [TabValue.MAP]: { - [PARAM_LINE_FULL_PATH]: parameters.lineFullPath, - [PARAM_LINE_PARALLEL_PATH]: parameters.lineParallelPath, - [PARAM_LINE_FLOW_MODE]: parameters.lineFlowMode, - [PARAM_LINE_FLOW_COLOR_MODE]: parameters.lineFlowColorMode, - [PARAM_LINE_FLOW_ALERT_THRESHOLD]: parameters.lineFlowAlertThreshold, - [PARAM_MAP_MANUAL_REFRESH]: parameters.mapManualRefresh, - [PARAM_MAP_BASEMAP]: parameters.mapBaseMap, - }, - [TabValue.SINGLE_LINE_DIAGRAM]: { - [PARAM_DIAGONAL_LABEL]: parameters.diagonalLabel, - [PARAM_CENTER_LABEL]: parameters.centerLabel, - [PARAM_SUBSTATION_LAYOUT]: parameters.substationLayout, - [PARAM_COMPONENT_LIBRARY]: parameters.componentLibrary, - }, - [TabValue.NETWORK_AREA_DIAGRAM]: { - [PARAM_INIT_NAD_WITH_GEO_DATA]: parameters.initNadWithGeoData, - }, - }; -}; - export const INTL_SUBSTATION_LAYOUT_OPTIONS = [ { id: SubstationLayout.HORIZONTAL, @@ -133,21 +75,3 @@ export const INTL_SUBSTATION_LAYOUT_OPTIONS = [ label: 'VerticalSubstationLayout', }, ]; - -export const formatParametersToSend = ( - parameters: NetworkVisualizationParametersForm, - changedParameters: Partial -) => { - const getFlattenedObject = (nestedObject: NestedObject): Record => - Object.values(nestedObject) - .flatMap((obj) => Object.entries(obj)) - .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}); - - const flattenedParameters = getFlattenedObject(parameters as NestedObject); - const flattenedChangedParameters = getFlattenedObject(changedParameters as NestedObject); - - return Object.keys(flattenedChangedParameters).reduce((acc, field) => { - (acc as any)[field] = flattenedParameters[field]; - return acc; - }, {}); -}; diff --git a/src/components/dialogs/parameters/network-visualizations/network-visualizations.types.tsx b/src/components/dialogs/parameters/network-visualizations/network-visualizations.types.tsx new file mode 100644 index 0000000000..a35cf98be2 --- /dev/null +++ b/src/components/dialogs/parameters/network-visualizations/network-visualizations.types.tsx @@ -0,0 +1,37 @@ +/* + * 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 { UUID } from 'crypto'; +import { MAP_BASEMAP_CARTO, MAP_BASEMAP_CARTO_NOLABEL, MAP_BASEMAP_MAPBOX } from '../../../../utils/config-params'; + +type MapParameters = { + lineFullPath: boolean; + lineParallelPath: boolean; + lineFlowMode: string; + lineFlowColorMode: string; + lineFlowAlertThreshold: number; + mapManualRefresh: boolean; + mapBaseMap: typeof MAP_BASEMAP_MAPBOX | typeof MAP_BASEMAP_CARTO | typeof MAP_BASEMAP_CARTO_NOLABEL; +}; + +type SingleLineDiagramParameters = { + diagonalLabel: boolean; + centerLabel: boolean; + substationLayout: string; + componentLibrary: string; +}; + +type NetworkAreaDiagramParameters = { + initNadWithGeoData: boolean; +}; + +export type NetworkVisualizationParameters = { + id: UUID; + mapParameters: MapParameters; + singleLineDiagramParameters: SingleLineDiagramParameters; + networkAreaDiagramParameters: NetworkAreaDiagramParameters; +}; diff --git a/src/components/map-viewer.jsx b/src/components/map-viewer.jsx index c54b65fc93..4844d5fd1c 100644 --- a/src/components/map-viewer.jsx +++ b/src/components/map-viewer.jsx @@ -7,13 +7,6 @@ import { useState, useCallback, useRef, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { - PARAM_LINE_FLOW_ALERT_THRESHOLD, - PARAM_LINE_FLOW_COLOR_MODE, - PARAM_LINE_FLOW_MODE, - PARAM_LINE_FULL_PATH, - PARAM_LINE_PARALLEL_PATH, -} from '../utils/config-params'; import { setStudyDisplayMode } from '../redux/actions'; import { DRAW_EVENT, DRAW_MODES } from '@powsybl/network-viewer'; import { DiagramType } from './diagrams/diagram-common'; @@ -147,23 +140,14 @@ const MapViewer = ({ const networkMapref = useRef(null); // hold the reference to the network map (from powsybl-network-viewer) const dispatch = useDispatch(); const [drawingMode, setDrawingMode] = useState(DRAW_MODES.SIMPLE_SELECT); - const lineFullPath = useSelector((state) => state[PARAM_LINE_FULL_PATH]); - const lineParallelPath = useSelector((state) => state[PARAM_LINE_PARALLEL_PATH]); const [shouldOpenSelectionCreationPanel, setShouldOpenSelectionCreationPanel] = useState(false); + const [nominalVoltages, setNominalVoltages] = useState(); + const [isInDrawingMode, setIsInDrawingMode] = useState(false); - const lineFlowMode = useSelector((state) => state[PARAM_LINE_FLOW_MODE]); - - const lineFlowColorMode = useSelector((state) => state[PARAM_LINE_FLOW_COLOR_MODE]); - - const lineFlowAlertThreshold = useSelector((state) => Number(state[PARAM_LINE_FLOW_ALERT_THRESHOLD])); - + const networkVisuParams = useSelector((state) => state.networkVisualizationsParameters); const studyDisplayMode = useSelector((state) => state.studyDisplayMode); - const previousStudyDisplayMode = useRef(undefined); - const [nominalVoltages, setNominalVoltages] = useState(); - const [isInDrawingMode, setIsInDrawingMode] = useState(false); - const openVoltageLevel = useCallback( (vlId) => { // don't open the sld if the drawing mode is activated @@ -314,11 +298,11 @@ const MapViewer = ({ networkMapRef={networkMapref} studyUuid={studyUuid} visible={view === StudyView.MAP && studyDisplayMode !== StudyDisplayMode.TREE} - lineFullPath={lineFullPath} - lineParallelPath={lineParallelPath} - lineFlowMode={lineFlowMode} - lineFlowColorMode={lineFlowColorMode} - lineFlowAlertThreshold={lineFlowAlertThreshold} + lineFullPath={networkVisuParams.mapParameters.lineFullPath} + lineParallelPath={networkVisuParams.mapParameters.lineParallelPath} + lineFlowMode={networkVisuParams.mapParameters.lineFlowMode} + lineFlowColorMode={networkVisuParams.mapParameters.lineFlowColorMode} + lineFlowAlertThreshold={networkVisuParams.mapParameters.lineFlowAlertThreshold} openVoltageLevel={openVoltageLevel} currentNode={currentNode} onChangeTab={onChangeTab} diff --git a/src/components/network/network-map-tab.tsx b/src/components/network/network-map-tab.tsx index 0229705bec..308d584870 100644 --- a/src/components/network/network-map-tab.tsx +++ b/src/components/network/network-map-tab.tsx @@ -20,7 +20,7 @@ import withEquipmentMenu from '../menus/equipment-menu'; import VoltageLevelChoice from '../voltage-level-choice'; import NominalVoltageFilter 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 { PARAM_USE_NAME } from '../../utils/config-params'; import { Equipment, EquipmentType, useIntlRef, useSnackMessage } from '@gridsuite/commons-ui'; import { isNodeBuilt, isNodeRenamed, isSameNode, isSameNodeAndBuilt } from '../graph/util/model-functions'; import { resetMapReloaded, setMapDataLoading } from '../../redux/actions'; @@ -126,11 +126,11 @@ export const NetworkMapTab = ({ const studyUpdatedForce = useSelector((state: AppState) => state.studyUpdated); const mapDataLoading = useSelector((state: AppState) => state.mapDataLoading); const studyDisplayMode = useSelector((state: AppState) => state.studyDisplayMode); - const basemap = useSelector((state: AppState) => state[PARAM_MAP_BASEMAP]); const useName = useSelector((state: AppState) => state[PARAM_USE_NAME]); const loadFlowStatus = useSelector((state: AppState) => state.computingStatus[ComputingType.LOAD_FLOW]); const treeModel = useSelector((state: AppState) => state.networkModificationTreeModel); const centerOnSubstation = useSelector((state: AppState) => state.centerOnSubstation); + const networkVisuParams = useSelector((state: AppState) => state.networkVisualizationsParameters); const theme = useTheme(); @@ -170,13 +170,10 @@ export const NetworkMapTab = ({ const disabled = !isNodeBuilt(currentNode); const isCurrentNodeBuiltRef = useRef(isNodeBuilt(currentNode)); - const mapManualRefresh = useSelector((state: AppState) => state[PARAM_MAP_MANUAL_REFRESH]); - const refIsMapManualRefreshEnabled = useRef(); - refIsMapManualRefreshEnabled.current = mapManualRefresh; - const reloadMapNeeded = useSelector((state: AppState) => state.reloadMap); - const isMapEquipmentsInitialized = useSelector((state: AppState) => state.isMapEquipmentsInitialized); + const refIsMapManualRefreshEnabled = useRef(); + refIsMapManualRefreshEnabled.current = networkVisuParams.mapParameters.mapManualRefresh; type EquipmentMenuProps = { position?: [number, number] | null; @@ -949,7 +946,9 @@ export const NetworkMapTab = ({ onVoltageLevelMenuClick={voltageLevelMenuClick} mapBoxToken={mapBoxToken} centerOnSubstation={centerOnSubstation} - isManualRefreshBackdropDisplayed={mapManualRefresh && reloadMapNeeded && isNodeBuilt(currentNode)} + isManualRefreshBackdropDisplayed={ + networkVisuParams.mapParameters.mapManualRefresh && reloadMapNeeded && isNodeBuilt(currentNode) + } // only 2 things need this to ensure the map keeps the correct size: // - changing study display mode because it changes the map container size // programmatically @@ -958,7 +957,7 @@ export const NetworkMapTab = ({ onManualRefreshClick={updateMapEquipmentsAndGeoData} triggerMapResizeOnChange={[studyDisplayMode, visible]} renderPopover={renderLinePopover} - mapLibrary={basemap} + mapLibrary={networkVisuParams.mapParameters.mapBaseMap} mapTheme={theme?.palette.mode} areFlowsValid={loadFlowStatus === RunningStatus.SUCCEED} onDrawPolygonModeActive={(active: DRAW_MODES) => { diff --git a/src/redux/actions.ts b/src/redux/actions.ts index 0fa6bbdf38..0222063a7c 100644 --- a/src/redux/actions.ts +++ b/src/redux/actions.ts @@ -6,26 +6,11 @@ */ import { - MAP_BASEMAP_CARTO, - MAP_BASEMAP_CARTO_NOLABEL, - MAP_BASEMAP_MAPBOX, - PARAM_CENTER_LABEL, - PARAM_COMPONENT_LIBRARY, PARAM_DEVELOPER_MODE, - PARAM_DIAGONAL_LABEL, PARAM_FAVORITE_CONTINGENCY_LISTS, PARAM_FLUX_CONVENTION, - PARAM_INIT_NAD_WITH_GEO_DATA, PARAM_LANGUAGE, PARAM_LIMIT_REDUCTION, - PARAM_LINE_FLOW_ALERT_THRESHOLD, - PARAM_LINE_FLOW_COLOR_MODE, - PARAM_LINE_FLOW_MODE, - PARAM_LINE_FULL_PATH, - PARAM_LINE_PARALLEL_PATH, - PARAM_MAP_BASEMAP, - PARAM_MAP_MANUAL_REFRESH, - PARAM_SUBSTATION_LAYOUT, PARAM_THEME, PARAM_USE_NAME, PARAMS_LOADED, @@ -36,7 +21,6 @@ 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 { AppState, CurrentTreeNode, @@ -51,7 +35,7 @@ import { ComputingType } from '../components/computing-status/computing-type'; import { RunningStatus } from '../components/utils/running-status'; import { IOptionalService } from '../components/utils/optional-services'; import { FluxConventions } from '../components/dialogs/parameters/network-parameters'; -import { DiagramType, SubstationLayout } from '../components/diagrams/diagram-common'; +import { DiagramType } from '../components/diagrams/diagram-common'; import { Filter } from '../components/results/common/results-global-filter'; import { DYNAMIC_SIMULATION_RESULT_STORE_FIELD, @@ -70,6 +54,7 @@ import { ColumnWithFormula } from 'types/custom-columns.types'; import { NetworkModificationNodeData, RootNodeData } from '../components/graph/tree-node.type'; import GSMapEquipments from 'components/network/gs-map-equipments'; import { SpreadsheetEquipmentType, SpreadsheetTabDefinition } from '../components/spreadsheet/config/spreadsheet.type'; +import { NetworkVisualizationParameters } from '../components/dialogs/parameters/network-visualizations/network-visualizations.types'; type MutableUnknownArray = unknown[]; @@ -101,25 +86,14 @@ export type AppActions = | CloseStudyAction | RemoveSelectedCaseAction | UseNameAction - | CenterLabelAction - | DiagonalLabelAction - | LineFullPathAction - | LineParallelPathAction - | LineFlowModeAction | FluxConventionAction | EnableDeveloperModeAction - | LineFlowColorModeAction - | LineFlowAlertThresholdAction | LimitReductionAction | LimitReductionModifiedAction | StudyUpdatedAction | MapDataLoadingAction - | MapManualRefreshAction - | MapBasemapAction | ResetMapReloadedAction | MapEquipmentsInitializedAction - | SubstationLayoutAction - | ComponentLibraryAction | SetFullscreenDiagramAction | ChangeDisplayedColumnsNamesAction | ChangeLockedColumnsNamesAction @@ -161,6 +135,7 @@ export type AppActions = | LogsFilterAction | UpdateCustomColumnsDefinitionsAction | RemoveCustomColumnsDefinitionsAction + | UpdateNetworkVisualizationParametersAction | StateEstimationResultFilterAction; export const LOAD_EQUIPMENTS = 'LOAD_EQUIPMENTS'; @@ -447,49 +422,21 @@ export function selectUseName(useName: boolean): UseNameAction { return { type: USE_NAME, [PARAM_USE_NAME]: useName }; } -export const CENTER_LABEL = 'CENTER_LABEL'; -export type CenterLabelAction = Readonly> & { - [PARAM_CENTER_LABEL]: boolean; -}; -export function selectCenterLabelState(centerLabel: boolean): CenterLabelAction { - return { type: CENTER_LABEL, [PARAM_CENTER_LABEL]: centerLabel }; -} - -export const DIAGONAL_LABEL = 'DIAGONAL_LABEL'; -export type DiagonalLabelAction = Readonly> & { - [PARAM_DIAGONAL_LABEL]: boolean; -}; -export function selectDiagonalLabelState(diagonalLabel: boolean): DiagonalLabelAction { - return { type: DIAGONAL_LABEL, [PARAM_DIAGONAL_LABEL]: diagonalLabel }; -} - -export const LINE_FULL_PATH = 'LINE_FULL_PATH'; -export type LineFullPathAction = Readonly> & { - [PARAM_LINE_FULL_PATH]: boolean; -}; -export function selectLineFullPathState(lineFullPath: boolean): LineFullPathAction { - return { type: LINE_FULL_PATH, [PARAM_LINE_FULL_PATH]: lineFullPath }; -} - -export const LINE_PARALLEL_PATH = 'LINE_PARALLEL_PATH'; -export type LineParallelPathAction = Readonly> & { - [PARAM_LINE_PARALLEL_PATH]: boolean; +export const UPDATE_NETWORK_VISUALIZATION_PARAMETERS = 'UPDATE_NETWORK_VISUALIZATION_PARAMETERS'; +export type UpdateNetworkVisualizationParametersAction = Readonly< + Action +> & { + parameters: NetworkVisualizationParameters; }; -export function selectLineParallelPathState(lineParallelPath: boolean): LineParallelPathAction { +export function setUpdateNetworkVisualizationParameters( + parameters: NetworkVisualizationParameters +): UpdateNetworkVisualizationParametersAction { return { - type: LINE_PARALLEL_PATH, - [PARAM_LINE_PARALLEL_PATH]: lineParallelPath, + type: UPDATE_NETWORK_VISUALIZATION_PARAMETERS, + parameters: parameters, }; } -export const LINE_FLOW_MODE = 'LINE_FLOW_MODE'; -export type LineFlowModeAction = Readonly> & { - [PARAM_LINE_FLOW_MODE]: LineFlowMode; -}; -export function selectLineFlowMode(lineFlowMode: LineFlowMode): LineFlowModeAction { - return { type: LINE_FLOW_MODE, [PARAM_LINE_FLOW_MODE]: lineFlowMode }; -} - export const FLUX_CONVENTION = 'FLUX_CONVENTION'; export type FluxConventionAction = Readonly> & { [PARAM_FLUX_CONVENTION]: FluxConventions; @@ -509,39 +456,6 @@ export function selectEnableDeveloperMode(enableDeveloperMode: boolean): EnableD }; } -export const INIT_NAD_WITH_GEO_DATA = 'INIT_NAD_GEO_WITH_DATA'; -export type InitNadWithGeoDataAction = Readonly> & { - [PARAM_INIT_NAD_WITH_GEO_DATA]: boolean; -}; -export function selectInitNadWithGeoData(initNadWithGeoData: boolean): InitNadWithGeoDataAction { - return { - type: INIT_NAD_WITH_GEO_DATA, - [PARAM_INIT_NAD_WITH_GEO_DATA]: initNadWithGeoData, - }; -} - -export const LINE_FLOW_COLOR_MODE = 'LINE_FLOW_COLOR_MODE'; -export type LineFlowColorModeAction = Readonly> & { - [PARAM_LINE_FLOW_COLOR_MODE]: LineFlowColorMode; -}; -export function selectLineFlowColorMode(lineFlowColorMode: LineFlowColorMode): LineFlowColorModeAction { - return { - type: LINE_FLOW_COLOR_MODE, - [PARAM_LINE_FLOW_COLOR_MODE]: lineFlowColorMode, - }; -} - -export const LINE_FLOW_ALERT_THRESHOLD = 'LINE_FLOW_ALERT_THRESHOLD'; -export type LineFlowAlertThresholdAction = Readonly> & { - [PARAM_LINE_FLOW_ALERT_THRESHOLD]: number; -}; -export function selectLineFlowAlertThreshold(lineFlowAlertThreshold: number): LineFlowAlertThresholdAction { - return { - type: LINE_FLOW_ALERT_THRESHOLD, - [PARAM_LINE_FLOW_ALERT_THRESHOLD]: lineFlowAlertThreshold, - }; -} - export const LIMIT_REDUCTION = 'LIMIT_REDUCTION'; export type LimitReductionAction = Readonly> & { [PARAM_LIMIT_REDUCTION]: number; @@ -588,30 +502,6 @@ export function setMapDataLoading(mapDataLoading: boolean): MapDataLoadingAction }; } -export const MAP_MANUAL_REFRESH = 'MAP_MANUAL_REFRESH'; -export type MapManualRefreshAction = Readonly> & { - [PARAM_MAP_MANUAL_REFRESH]: boolean; -}; -export function selectMapManualRefresh(mapManualRefresh: boolean): MapManualRefreshAction { - return { - type: MAP_MANUAL_REFRESH, - [PARAM_MAP_MANUAL_REFRESH]: mapManualRefresh, - }; -} - -export const MAP_BASEMAP = 'MAP_BASEMAP'; -export type MapBasemapAction = Readonly> & { - [PARAM_MAP_BASEMAP]: typeof MAP_BASEMAP_MAPBOX | typeof MAP_BASEMAP_CARTO | typeof MAP_BASEMAP_CARTO_NOLABEL; -}; -export function selectMapBaseMap( - mapBaseMap: typeof MAP_BASEMAP_MAPBOX | typeof MAP_BASEMAP_CARTO | typeof MAP_BASEMAP_CARTO_NOLABEL -): MapBasemapAction { - return { - type: MAP_BASEMAP, - [PARAM_MAP_BASEMAP]: mapBaseMap, - }; -} - export const RESET_MAP_RELOADED = 'RESET_MAP_RELOADED'; export type ResetMapReloadedAction = Readonly>; export function resetMapReloaded(): ResetMapReloadedAction { @@ -631,28 +521,6 @@ export function setMapEquipementsInitialized(newValue: boolean): MapEquipmentsIn }; } -export const SUBSTATION_LAYOUT = 'SUBSTATION_LAYOUT'; -export type SubstationLayoutAction = Readonly> & { - [PARAM_SUBSTATION_LAYOUT]: SubstationLayout; -}; -export function selectSubstationLayout(substationLayout: SubstationLayout): SubstationLayoutAction { - return { - type: SUBSTATION_LAYOUT, - [PARAM_SUBSTATION_LAYOUT]: substationLayout, - }; -} - -export const COMPONENT_LIBRARY = 'COMPONENT_LIBRARY'; -export type ComponentLibraryAction = Readonly> & { - [PARAM_COMPONENT_LIBRARY]: unknown; -}; -export function selectComponentLibrary(componentLibrary: unknown): ComponentLibraryAction { - return { - type: COMPONENT_LIBRARY, - [PARAM_COMPONENT_LIBRARY]: componentLibrary, - }; -} - export const SET_FULLSCREEN_DIAGRAM = 'SET_FULLSCREEN_DIAGRAM'; export type SetFullscreenDiagramAction = Readonly> & ( diff --git a/src/redux/reducer.ts b/src/redux/reducer.ts index 812ef2927f..ecae780516 100644 --- a/src/redux/reducer.ts +++ b/src/redux/reducer.ts @@ -38,9 +38,7 @@ import { AddSortForNewSpreadsheetAction, AddToRecentGlobalFiltersAction, AppActions, - CENTER_LABEL, CENTER_ON_SUBSTATION, - CenterLabelAction, CenterOnSubstationAction, CHANGE_DISPLAYED_COLUMNS_NAMES, CHANGE_LOCKED_COLUMNS_NAMES, @@ -54,8 +52,6 @@ import { CloseDiagramAction, CloseDiagramsAction, CloseStudyAction, - COMPONENT_LIBRARY, - ComponentLibraryAction, CURRENT_TREE_NODE, CurrentTreeNodeAction, UPDATE_CUSTOM_COLUMNS_DEFINITION, @@ -66,8 +62,6 @@ import { DecrementNetworkAreaDiagramDepthAction, DELETE_EQUIPMENTS, DeleteEquipmentsAction, - DIAGONAL_LABEL, - DiagonalLabelAction, DYNAMIC_SIMULATION_RESULT_FILTER, DynamicSimulationResultFilterAction, ENABLE_DEVELOPER_MODE, @@ -78,22 +72,10 @@ import { FluxConventionAction, INCREMENT_NETWORK_AREA_DIAGRAM_DEPTH, IncrementNetworkAreaDiagramDepthAction, - INIT_NAD_WITH_GEO_DATA, - InitNadWithGeoDataAction, LIMIT_REDUCTION, LIMIT_REDUCTION_MODIFIED, LimitReductionAction, LimitReductionModifiedAction, - LINE_FLOW_ALERT_THRESHOLD, - LINE_FLOW_COLOR_MODE, - LINE_FLOW_MODE, - LINE_FULL_PATH, - LINE_PARALLEL_PATH, - LineFlowAlertThresholdAction, - LineFlowColorModeAction, - LineFlowModeAction, - LineFullPathAction, - LineParallelPathAction, LOAD_EQUIPMENTS, LOAD_NETWORK_MODIFICATION_TREE_SUCCESS, LoadEquipmentsAction, @@ -102,16 +84,12 @@ import { LoadNetworkModificationTreeSuccessAction, LOGS_FILTER, LogsFilterAction, - MAP_BASEMAP, MAP_DATA_LOADING, MAP_EQUIPMENTS_CREATED, MAP_EQUIPMENTS_INITIALIZED, - MAP_MANUAL_REFRESH, - MapBasemapAction, MapDataLoadingAction, MapEquipmentsCreatedAction, MapEquipmentsInitializedAction, - MapManualRefreshAction, MINIMIZE_DIAGRAM, MinimizeDiagramAction, NETWORK_AREA_DIAGRAM_NB_VOLTAGE_LEVELS, @@ -194,8 +172,6 @@ import { StoreNetworkAreaDiagramNodeMovementAction, STUDY_UPDATED, StudyUpdatedAction, - SUBSTATION_LAYOUT, - SubstationLayoutAction, TABLE_SORT, TableSortAction, TOGGLE_PIN_DIAGRAM, @@ -208,6 +184,8 @@ import { UseNameAction, STATEESTIMATION_RESULT_FILTER, StateEstimationResultFilterAction, + UPDATE_NETWORK_VISUALIZATION_PARAMETERS, + UpdateNetworkVisualizationParametersAction, } from './actions'; import { getLocalStorageComputedLanguage, @@ -313,10 +291,12 @@ import { COMPUTING_AND_NETWORK_MODIFICATION_TYPE } from '../utils/report/report. import { BUILD_STATUS } from '../components/network/constants'; import GSMapEquipments from 'components/network/gs-map-equipments'; import { SpreadsheetEquipmentType, SpreadsheetTabDefinition } from '../components/spreadsheet/config/spreadsheet.type'; +import { NetworkVisualizationParameters } from '../components/dialogs/parameters/network-visualizations/network-visualizations.types'; export enum NotificationType { STUDY = 'study', COMPUTATION_PARAMETERS_UPDATED = 'computationParametersUpdated', + NETWORK_VISUALIZATION_PARAMETERS_UPDATED = 'networkVisualizationParametersUpdated', } export enum StudyIndexationStatus { @@ -502,6 +482,7 @@ export interface AppState extends CommonStoreState { reloadMap: boolean; isMapEquipmentsInitialized: boolean; spreadsheetNetwork: SpreadsheetNetworkState; + networkVisualizationsParameters: NetworkVisualizationParameters; [PARAM_THEME]: GsTheme; [PARAM_LANGUAGE]: GsLang; @@ -832,7 +813,7 @@ export const reducer = createReducer(initialState, (builder) => { } }); - builder.addCase(CLOSE_STUDY, (state, action: CloseStudyAction) => { + builder.addCase(CLOSE_STUDY, (state, _action: CloseStudyAction) => { state.studyUuid = null; state.geoData = null; state.networkModificationTreeModel = null; @@ -1062,6 +1043,13 @@ export const reducer = createReducer(initialState, (builder) => { state[PARAMS_LOADED] = action[PARAMS_LOADED]; }); + builder.addCase( + UPDATE_NETWORK_VISUALIZATION_PARAMETERS, + (state, action: UpdateNetworkVisualizationParametersAction) => { + state.networkVisualizationsParameters = action.parameters; + } + ); + builder.addCase(USE_NAME, (state, action: UseNameAction) => { state[PARAM_USE_NAME] = action[PARAM_USE_NAME]; }); @@ -1070,26 +1058,6 @@ export const reducer = createReducer(initialState, (builder) => { state.user = action.user; }); - builder.addCase(CENTER_LABEL, (state, action: CenterLabelAction) => { - state[PARAM_CENTER_LABEL] = action[PARAM_CENTER_LABEL]; - }); - - builder.addCase(DIAGONAL_LABEL, (state, action: DiagonalLabelAction) => { - state[PARAM_DIAGONAL_LABEL] = action[PARAM_DIAGONAL_LABEL]; - }); - - builder.addCase(LINE_FULL_PATH, (state, action: LineFullPathAction) => { - state[PARAM_LINE_FULL_PATH] = action[PARAM_LINE_FULL_PATH]; - }); - - builder.addCase(LINE_PARALLEL_PATH, (state, action: LineParallelPathAction) => { - state[PARAM_LINE_PARALLEL_PATH] = action[PARAM_LINE_PARALLEL_PATH]; - }); - - builder.addCase(LINE_FLOW_MODE, (state, action: LineFlowModeAction) => { - state[PARAM_LINE_FLOW_MODE] = action[PARAM_LINE_FLOW_MODE]; - }); - builder.addCase(FLUX_CONVENTION, (state, action: FluxConventionAction) => { state[PARAM_FLUX_CONVENTION] = action[PARAM_FLUX_CONVENTION]; }); @@ -1098,14 +1066,6 @@ export const reducer = createReducer(initialState, (builder) => { state[PARAM_DEVELOPER_MODE] = action[PARAM_DEVELOPER_MODE]; }); - builder.addCase(INIT_NAD_WITH_GEO_DATA, (state, action: InitNadWithGeoDataAction) => { - state[PARAM_INIT_NAD_WITH_GEO_DATA] = action[PARAM_INIT_NAD_WITH_GEO_DATA]; - }); - - builder.addCase(LINE_FLOW_COLOR_MODE, (state, action: LineFlowColorModeAction) => { - state[PARAM_LINE_FLOW_COLOR_MODE] = action[PARAM_LINE_FLOW_COLOR_MODE]; - }); - builder.addCase(LIMIT_REDUCTION, (state, action: LimitReductionAction) => { state[PARAM_LIMIT_REDUCTION] = action[PARAM_LIMIT_REDUCTION]; }); @@ -1114,10 +1074,6 @@ export const reducer = createReducer(initialState, (builder) => { state.limitReductionModified = action.limitReductionModified; }); - builder.addCase(LINE_FLOW_ALERT_THRESHOLD, (state, action: LineFlowAlertThresholdAction) => { - state[PARAM_LINE_FLOW_ALERT_THRESHOLD] = action[PARAM_LINE_FLOW_ALERT_THRESHOLD]; - }); - builder.addCase(UNAUTHORIZED_USER_INFO, (state, action: UnauthorizedUserAction) => { state.authenticationRouterError = action.authenticationRouterError; }); @@ -1130,7 +1086,7 @@ export const reducer = createReducer(initialState, (builder) => { state.authenticationRouterError = action.authenticationRouterError; }); - builder.addCase(RESET_AUTHENTICATION_ROUTER_ERROR, (state, action: AuthenticationRouterErrorAction) => { + builder.addCase(RESET_AUTHENTICATION_ROUTER_ERROR, (state, _action: AuthenticationRouterErrorAction) => { state.authenticationRouterError = null; }); @@ -1138,15 +1094,7 @@ export const reducer = createReducer(initialState, (builder) => { state.showAuthenticationRouterLogin = action.showAuthenticationRouterLogin; }); - builder.addCase(MAP_MANUAL_REFRESH, (state, action: MapManualRefreshAction) => { - state[PARAM_MAP_MANUAL_REFRESH] = action[PARAM_MAP_MANUAL_REFRESH]; - }); - - builder.addCase(MAP_BASEMAP, (state, action: MapBasemapAction) => { - state[PARAM_MAP_BASEMAP] = action[PARAM_MAP_BASEMAP]; - }); - - builder.addCase(RESET_MAP_RELOADED, (state, action: ResetMapReloadedAction) => { + builder.addCase(RESET_MAP_RELOADED, (state, _action: ResetMapReloadedAction) => { state.reloadMap = false; }); @@ -1154,14 +1102,6 @@ export const reducer = createReducer(initialState, (builder) => { state.isMapEquipmentsInitialized = action.newValue; }); - builder.addCase(SUBSTATION_LAYOUT, (state, action: SubstationLayoutAction) => { - state[PARAM_SUBSTATION_LAYOUT] = action[PARAM_SUBSTATION_LAYOUT]; - }); - - builder.addCase(COMPONENT_LIBRARY, (state, action: ComponentLibraryAction) => { - state[PARAM_COMPONENT_LIBRARY] = action[PARAM_COMPONENT_LIBRARY]; - }); - builder.addCase(SET_FULLSCREEN_DIAGRAM, (state, action: SetFullscreenDiagramAction) => { state.fullScreenDiagram = action.diagramId ? { @@ -1503,7 +1443,7 @@ export const reducer = createReducer(initialState, (builder) => { state.diagramStates = state.diagramStates.filter((diagram) => !idsToClose.has(diagram.id)); }); - builder.addCase(STOP_DIAGRAM_BLINK, (state, action: StopDiagramBlinkAction) => { + builder.addCase(STOP_DIAGRAM_BLINK, (state, _action: StopDiagramBlinkAction) => { state.diagramStates.forEach((diagram) => { if (diagram.needsToBlink) { diagram.needsToBlink = undefined; @@ -1511,15 +1451,15 @@ export const reducer = createReducer(initialState, (builder) => { }); }); - builder.addCase(RESET_NETWORK_AREA_DIAGRAM_DEPTH, (state, action: ResetNetworkAreaDiagramDepthAction) => { + builder.addCase(RESET_NETWORK_AREA_DIAGRAM_DEPTH, (state, _action: ResetNetworkAreaDiagramDepthAction) => { state.networkAreaDiagramDepth = 0; }); - builder.addCase(INCREMENT_NETWORK_AREA_DIAGRAM_DEPTH, (state, action: IncrementNetworkAreaDiagramDepthAction) => { + builder.addCase(INCREMENT_NETWORK_AREA_DIAGRAM_DEPTH, (state, _action: IncrementNetworkAreaDiagramDepthAction) => { state.networkAreaDiagramDepth = state.networkAreaDiagramDepth + 1; }); - builder.addCase(DECREMENT_NETWORK_AREA_DIAGRAM_DEPTH, (state, action: DecrementNetworkAreaDiagramDepthAction) => { + builder.addCase(DECREMENT_NETWORK_AREA_DIAGRAM_DEPTH, (state, _action: DecrementNetworkAreaDiagramDepthAction) => { if (state.networkAreaDiagramDepth > 0) { state.networkAreaDiagramDepth = state.networkAreaDiagramDepth - 1; } @@ -1582,7 +1522,7 @@ export const reducer = createReducer(initialState, (builder) => { // if the equipments are not loaded into the store yet, we don't have to update them if (currentEquipment != null) { - //since substations data contains voltage level ones, they have to be treated separatly + //since substations data contains voltage level ones, they have to be treated separately if (equipmentType === EQUIPMENT_TYPES.SUBSTATION) { const [updatedSubstations, updatedVoltageLevels] = updateSubstationsAndVoltageLevels( state.spreadsheetNetwork[EQUIPMENT_TYPES.SUBSTATION] as Substation[], @@ -1626,7 +1566,7 @@ export const reducer = createReducer(initialState, (builder) => { }); }); - builder.addCase(RESET_EQUIPMENTS, (state, action: ResetEquipmentsAction) => { + builder.addCase(RESET_EQUIPMENTS, (state, _action: ResetEquipmentsAction) => { state.spreadsheetNetwork = { ...initialSpreadsheetNetworkState, }; @@ -1637,7 +1577,7 @@ export const reducer = createReducer(initialState, (builder) => { }); }); - builder.addCase(RESET_EQUIPMENTS_POST_LOADFLOW, (state, action: ResetEquipmentsPostLoadflowAction) => { + builder.addCase(RESET_EQUIPMENTS_POST_LOADFLOW, (state, _action: ResetEquipmentsPostLoadflowAction) => { state.spreadsheetNetwork = { ...initialSpreadsheetNetworkState, [EQUIPMENT_TYPES.SUBSTATION]: state.spreadsheetNetwork[EQUIPMENT_TYPES.SUBSTATION], @@ -1731,7 +1671,7 @@ export const reducer = createReducer(initialState, (builder) => { state[LOGS_STORE_FIELD][action.filterTab] = action[LOGS_STORE_FIELD]; }); - builder.addCase(RESET_LOGS_FILTER, (state, action: ResetLogsFilterAction) => { + builder.addCase(RESET_LOGS_FILTER, (state, _action: ResetLogsFilterAction) => { state[LOGS_STORE_FIELD] = { ...initialLogsFilterState, }; diff --git a/src/services/study/study-config.ts b/src/services/study/study-config.ts new file mode 100644 index 0000000000..616cf896a3 --- /dev/null +++ b/src/services/study/study-config.ts @@ -0,0 +1,32 @@ +/** + * Copyright (c) 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 { getStudyUrl } from './index'; +import { backendFetch, backendFetchJson } from '../utils'; +import { UUID } from 'crypto'; +import { NetworkVisualizationParameters } from '../../components/dialogs/parameters/network-visualizations/network-visualizations.types'; + +export function getNetworkVisualizationParameters(studyUuid: UUID) { + console.info('get network visualization parameters'); + const url = getStudyUrl(studyUuid) + '/network-visualizations/parameters'; + console.debug(url); + return backendFetchJson(url); +} + +export function setNetworkVisualizationParameters(studyUuid: UUID, newParams: NetworkVisualizationParameters) { + console.info('set network visualization parameters'); + const url = getStudyUrl(studyUuid) + '/network-visualizations/parameters'; + console.debug(url); + return backendFetch(url, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify(newParams), + }); +} diff --git a/src/translations/en.json b/src/translations/en.json index 7beaf5ba9d..529fc0fead 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -79,6 +79,8 @@ "CBNone": "None", "Map": "Map", "NetworkVisualizations": "Network visualizations", + "getNetworkVisualizationsParametersError": "An error occurred while reading the network visualizations parameters", + "updateNetworkVisualizationsParametersError": "An error occurred while updating the network visualizations parameters", "lineFullPath": "Line full path", "lineParallelPath": "Spread overlapping lines", "LineFlowMode": "Line flow mode", diff --git a/src/translations/fr.json b/src/translations/fr.json index f1020e2994..2d1b01fafe 100644 --- a/src/translations/fr.json +++ b/src/translations/fr.json @@ -80,6 +80,8 @@ "CBNone": "Aucun", "Map": "Carte", "NetworkVisualizations": "Images réseau", + "getNetworkVisualizationsParametersError": "Une erreur est survenue lors de la récupération des paramètres des images réseau", + "updateNetworkVisualizationsParametersError": "Une erreur est survenue lors de la mise a jour des paramètres des images réseau", "lineFullPath": "Afficher le chemin complet des lignes", "lineParallelPath": "Écarter les lignes superposées", "LineFlowMode": "Mode de représentation des flux sur les lignes",