From 9d1478e05cfdb7c879afa5d36e41ad1326d084f7 Mon Sep 17 00:00:00 2001 From: nncluzu Date: Wed, 1 Nov 2023 00:17:58 +0100 Subject: [PATCH] - replace actions/selectors from old reducer by the new slices one. Rebase dev - fix osrdConfContext - add mapInfraID in map store - add infraID in props TracksGeographic - add infraID in props common/Map/Layers/Routes - add infraID in props common/Map/Layers/OperationalPoints - add infraID in props common/Map/Layers/Catenaries - add infraID in props BufferStops, Detectors, LineSearchLayer, NeutralSections, Signals, SpeedLimits, Switches, SNCF_PSL - add infraID in props common/Map/Layers/GeoJSONs and add editorInfraID in editor slice - remove eslint warning - create commonState builder - change osrdConfContext to osrdContext - create mapViewer slice - fix eslint error - fix error after rebase - add test mapViewer - fix review's comments front: change type snakeCase to PascalCase and extends InfraStateType to StdcmConf and OperationalStudyConf front: create and use useOsrdConfSelector front: create and use useInfraID front: create and use useOsrdConfActions front: create and use useUpdateInfraID front: move featureInfoClick from infra reducer to osrdConf reducer front: rename/harmonize front: remove stdcmMode from store front: fix front: remove unnecessary condition front: typo --- front/src/applications/editor/Editor.tsx | 26 +- front/src/applications/editor/Home.tsx | 5 +- front/src/applications/editor/Map.tsx | 9 +- .../editor/components/EntityError.tsx | 7 +- .../editor/components/EntitySumUp.tsx | 8 +- .../InfraErrors/InfraErrorCorrectorModal.tsx | 15 +- .../InfraErrors/InfraErrorsModal.tsx | 8 +- .../editor/components/LayersModal.tsx | 29 +- front/src/applications/editor/nav.tsx | 32 +- .../editor/tools/pointEdition/components.tsx | 95 ++- .../catenary/CatenaryEditionLayers.tsx | 40 +- .../editor/tools/rangeEdition/components.tsx | 39 +- .../SpeedSectionEditionLayers.tsx | 49 +- .../editor/tools/routeEdition/components.tsx | 33 +- .../components/EditRouteMetadata.tsx | 74 +- .../routeEdition/components/EditRoutePath.tsx | 59 +- .../routeEdition/components/Endpoints.tsx | 37 +- .../routeEdition/components/WayPointInput.tsx | 26 +- .../editor/tools/selection/components.tsx | 34 +- .../editor/tools/switchEdition/components.tsx | 44 +- .../TrackSectionEndpointSelector.tsx | 29 +- .../editor/tools/switchEdition/useSwitch.ts | 22 +- .../editor/tools/trackEdition/components.tsx | 55 +- front/src/applications/editor/tools/types.ts | 9 +- front/src/applications/editor/tools/utils.ts | 29 +- .../applications/operationalStudies/consts.ts | 20 +- .../views/ManageTrainSchedule.tsx | 51 +- .../operationalStudies/views/Scenario.tsx | 52 +- front/src/applications/referenceMap/Home.tsx | 10 +- front/src/applications/referenceMap/Map.tsx | 35 +- .../stdcm/components/RunningTime.tsx | 22 +- .../src/applications/stdcm/formatStcmConf.ts | 14 +- .../applications/stdcm/views/OSRDSTDCM.tsx | 24 +- .../stdcm/views/OSRDStdcmConfig.tsx | 34 +- .../stdcm/views/StdcmRequestModal.tsx | 13 +- .../withOSRDStdcmMissingInfo.tsx | 11 +- .../common/InfraSelector/InfraSelector.tsx | 20 +- .../InfraSelectorModalBodyStandard.tsx | 24 +- .../common/Map/Buttons/ButtonMapInfras.tsx | 5 +- front/src/common/Map/Buttons/MapButtons.tsx | 24 +- front/src/common/Map/Layers/BufferStops.tsx | 7 +- front/src/common/Map/Layers/Catenaries.tsx | 18 +- front/src/common/Map/Layers/Detectors.tsx | 15 +- front/src/common/Map/Layers/GeoJSONs.tsx | 74 +- .../src/common/Map/Layers/LineSearchLayer.tsx | 8 +- .../src/common/Map/Layers/NeutralSections.tsx | 6 +- .../common/Map/Layers/OperationalPoints.tsx | 6 +- front/src/common/Map/Layers/Routes.tsx | 17 +- front/src/common/Map/Layers/Signals.tsx | 8 +- front/src/common/Map/Layers/SpeedLimits.tsx | 19 +- front/src/common/Map/Layers/Switches.tsx | 19 +- .../common/Map/Layers/TracksGeographic.tsx | 12 +- .../common/Map/Layers/extensions/SNCF/PSL.tsx | 29 +- .../Map/Layers/extensions/SNCF/PSLSigns.tsx | 20 +- front/src/common/Map/Search/MapSearchLine.tsx | 4 +- .../src/common/Map/Search/MapSearchSignal.tsx | 9 +- .../common/Map/Search/MapSearchStation.tsx | 5 +- .../Map/Settings/MapSettingsSpeedLimits.tsx | 24 +- front/src/common/Map/WarpedMap/DataLoader.tsx | 34 +- .../Map/WarpedMap/SimulationWarpedMap.tsx | 40 +- front/src/common/Pathfinding/Pathfinding.tsx | 52 +- front/src/common/Pathfinding/TypeAndPath.tsx | 24 +- .../ScenarioExplorer/ScenarioExplorer.tsx | 31 +- .../ScenarioExplorerModalScenarioMiniCard.tsx | 15 +- .../SpeedLimitByTagSelector.tsx | 25 +- front/src/common/osrdConfContext.tsx | 36 - front/src/common/osrdContext.tsx | 128 ++++ front/src/main/app.jsx | 61 +- .../components/AddOrEditProjectModal.tsx | 39 +- .../RollingStockCardButtons.tsx | 31 +- .../RollingStockModal.tsx | 18 +- .../WithRollingStockSelector.tsx | 16 +- .../components/AddOrEditScenarioModal.tsx | 20 +- .../scenario/components/ScenarioCard.tsx | 26 +- .../components/SimulationResultsMap.tsx | 84 ++- .../components/StdcmAllowances.tsx | 31 +- .../study/components/AddOrEditStudyModal.tsx | 39 +- .../modules/study/components/StudyCard.tsx | 21 +- .../ImportTrainScheduleModal.tsx | 36 +- .../components/ImportTrainSchedule/Map.tsx | 37 +- .../Allowances/Allowances.tsx | 34 +- .../ElectricalProfiles.tsx | 14 +- .../DisplayItinerary/Destination.tsx | 13 +- .../Itinerary/DisplayItinerary/Origin.tsx | 51 +- .../Itinerary/DisplayItinerary/Vias.tsx | 12 +- .../Itinerary/DisplayVias.tsx | 22 +- .../Itinerary/Itinerary.tsx | 34 +- .../Itinerary/ModalSuggeredVias.tsx | 31 +- .../ManageTrainScheduleMap/Itinerary.tsx | 10 +- .../ItineraryMarkers.tsx | 5 +- .../ManageTrainScheduleMap/RenderPopup.tsx | 45 +- .../ManageTrainScheduleMap/setPointIti.ts | 29 +- .../components/ManageTrainSchedule/Map.tsx | 95 ++- .../PowerRestrictionsSelector.tsx | 20 +- .../SubmitConfAddTrainSchedule.tsx | 67 +- .../SubmitConfUpdateTrainSchedules.tsx | 49 +- .../TrainAddingSettings.tsx | 19 +- .../ManageTrainSchedule/TrainSettings.tsx | 36 +- .../helpers/adjustConfWithTrainToModify.ts | 77 +- .../components/Timetable/Timetable.tsx | 54 +- .../TimetableManageTrainSchedule.tsx | 19 +- .../Timetable/TimetableTrainCard.tsx | 31 +- front/src/reducers/__tests__/osrdconf.spec.ts | 203 ----- .../editor/__tests__/editorReducer.spec.ts | 28 +- front/src/reducers/editor/index.ts | 53 +- front/src/reducers/editor/selectors.ts | 19 +- front/src/reducers/index.ts | 119 +-- front/src/reducers/infra/index.ts | 21 + front/src/reducers/infra/selectors.ts | 7 + front/src/reducers/main/index.ts | 2 +- front/src/reducers/map/index.ts | 26 +- front/src/reducers/map/mapReducer.spec.ts | 36 +- .../__tests__/mapViewerReducer.spec.ts | 28 + front/src/reducers/mapViewer/index.ts | 24 + front/src/reducers/mapViewer/selectors.ts | 10 + front/src/reducers/osrdconf/index.ts | 709 ------------------ .../osrdconf/operationalStudiesConf/index.ts | 23 + .../operationalStudiesConf/selectors.ts | 17 + .../simulationConfReducers.spec.ts | 23 + .../__tests__}/commonConfBuilder.ts | 24 +- .../osrdConfCommon/__tests__}/utils.ts | 235 +++--- .../osrdConfCommon}/index.ts | 72 +- .../osrdConfCommon}/selectors.ts | 25 +- front/src/reducers/osrdconf/selectors.ts | 66 -- .../stdcmConf/index.ts | 6 +- .../reducers/osrdconf/stdcmConf/selectors.ts | 22 + .../stdcmConf/stdcmConfReducers.spec.ts | 10 +- .../osrdconf2/simulationConf/index.ts | 19 - .../osrdconf2/simulationConf/selectors.ts | 8 - .../simulationConfReducers.spec.ts | 21 - .../reducers/osrdconf2/stdcmConf/selectors.ts | 14 - front/src/reducers/user/index.ts | 2 +- front/yarn.lock | 14 +- 133 files changed, 2357 insertions(+), 2612 deletions(-) delete mode 100644 front/src/common/osrdConfContext.tsx create mode 100644 front/src/common/osrdContext.tsx delete mode 100644 front/src/reducers/__tests__/osrdconf.spec.ts create mode 100644 front/src/reducers/infra/index.ts create mode 100644 front/src/reducers/infra/selectors.ts create mode 100644 front/src/reducers/mapViewer/__tests__/mapViewerReducer.spec.ts create mode 100644 front/src/reducers/mapViewer/index.ts create mode 100644 front/src/reducers/mapViewer/selectors.ts delete mode 100644 front/src/reducers/osrdconf/index.ts create mode 100644 front/src/reducers/osrdconf/operationalStudiesConf/index.ts create mode 100644 front/src/reducers/osrdconf/operationalStudiesConf/selectors.ts create mode 100644 front/src/reducers/osrdconf/operationalStudiesConf/simulationConfReducers.spec.ts rename front/src/reducers/{osrdconf2/common/tests => osrdconf/osrdConfCommon/__tests__}/commonConfBuilder.ts (95%) rename front/src/reducers/{osrdconf2/common/tests => osrdconf/osrdConfCommon/__tests__}/utils.ts (66%) rename front/src/reducers/{osrdconf2/common => osrdconf/osrdConfCommon}/index.ts (88%) rename front/src/reducers/{osrdconf2/common => osrdconf/osrdConfCommon}/selectors.ts (76%) delete mode 100644 front/src/reducers/osrdconf/selectors.ts rename front/src/reducers/{osrdconf2 => osrdconf}/stdcmConf/index.ts (83%) create mode 100644 front/src/reducers/osrdconf/stdcmConf/selectors.ts rename front/src/reducers/{osrdconf2 => osrdconf}/stdcmConf/stdcmConfReducers.spec.ts (87%) delete mode 100644 front/src/reducers/osrdconf2/simulationConf/index.ts delete mode 100644 front/src/reducers/osrdconf2/simulationConf/selectors.ts delete mode 100644 front/src/reducers/osrdconf2/simulationConf/simulationConfReducers.spec.ts delete mode 100644 front/src/reducers/osrdconf2/stdcmConf/selectors.ts diff --git a/front/src/applications/editor/Editor.tsx b/front/src/applications/editor/Editor.tsx index 22e23408686..926b57c30f7 100644 --- a/front/src/applications/editor/Editor.tsx +++ b/front/src/applications/editor/Editor.tsx @@ -1,18 +1,17 @@ -import cx from 'classnames'; -import { isNil, toInteger } from 'lodash'; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate, useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; +import { useNavigate, useParams } from 'react-router-dom'; +import cx from 'classnames'; +import { isNil, toInteger } from 'lodash'; import 'applications/editor/Editor.scss'; import 'common/Map/Map.scss'; -import { getInfraID } from 'reducers/osrdconf/selectors'; +import type { EditorSliceActions } from 'reducers/editor'; import { getIsLoading } from 'reducers/main/mainSelector'; import { LoaderState } from 'common/Loader'; -import { loadDataModel, selectLayers, updateTotalsIssue } from 'reducers/editor'; -import { updateInfraID } from 'reducers/osrdconf'; +import { loadDataModel, updateTotalsIssue } from 'reducers/editor'; import { updateViewport } from 'reducers/map'; import { useModal } from 'common/BootstrapSNCF/ModalSNCF'; import { useSwitchTypes } from 'applications/editor/tools/switchEdition/types'; @@ -30,7 +29,8 @@ import TOOL_TYPES from 'applications/editor/tools/toolTypes'; import type { CommonToolState } from 'applications/editor/tools/commonToolState'; import type { EditorState } from 'applications/editor/tools/types'; import type { MapRef } from 'react-map-gl/maplibre'; -import type { +import { useInfraID, useOsrdActions } from 'common/osrdContext'; +import { EditorContextType, ExtendedEditorContextType, FullTool, @@ -43,14 +43,16 @@ const Editor = () => { const { t } = useTranslation(); const dispatch = useDispatch(); const navigate = useNavigate(); + const { register } = useKeyboardShortcuts(); const { openModal, closeModal } = useModal(); + const { updateInfraID, selectLayers } = useOsrdActions() as EditorSliceActions; const mapRef = useRef(null); const { urlInfra } = useParams(); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const isLoading = useSelector(getIsLoading); const editorState = useSelector((state: { editor: EditorState }) => state.editor); const switchTypes = useSwitchTypes(infraID); - const { register } = useKeyboardShortcuts(); + /* eslint-disable @typescript-eslint/no-explicit-any */ const [toolAndState, setToolAndState] = useState>({ tool: TOOLS[TOOL_TYPES.SELECTION], @@ -67,7 +69,10 @@ const Editor = () => { const switchTool = useCallback( ({ toolType, toolState }: switchProps) => { const tool = TOOLS[toolType]; - const state = { ...tool.getInitialState({ infraID, switchTypes }), ...(toolState || {}) }; + const state = { + ...tool.getInitialState({ infraID, switchTypes }), + ...(toolState || {}), + }; setToolAndState({ tool, state, @@ -304,6 +309,7 @@ const Editor = () => { toolState: toolAndState.state, activeTool: toolAndState.tool, setToolState, + infraID, }} /> {isSearchToolOpened && ( diff --git a/front/src/applications/editor/Home.tsx b/front/src/applications/editor/Home.tsx index 1f846d493dc..f0f91dadc45 100644 --- a/front/src/applications/editor/Home.tsx +++ b/front/src/applications/editor/Home.tsx @@ -1,18 +1,17 @@ import React, { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; -import { useSelector } from 'react-redux'; import { Route, Routes } from 'react-router-dom'; import { GoLock } from 'react-icons/go'; import NavBarSNCF from 'common/BootstrapSNCF/NavBarSNCF'; import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import { ModalProvider } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; +import { useInfraID } from 'common/osrdContext'; import Editor from './Editor'; export default function HomeEditorUnplugged() { const { t } = useTranslation(['home/home', 'referenceMap']); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const [getInfraById, { data: infra }] = osrdEditoastApi.endpoints.getInfraById.useLazyQuery({}); /** diff --git a/front/src/applications/editor/Map.tsx b/front/src/applications/editor/Map.tsx index 05f7f223763..2fb8b249c35 100644 --- a/front/src/applications/editor/Map.tsx +++ b/front/src/applications/editor/Map.tsx @@ -25,7 +25,6 @@ import VirtualLayers from 'modules/simulationResult/components/SimulationResults import EditorContext from 'applications/editor/context'; import { CUSTOM_ATTRIBUTION } from 'common/Map/const'; import { getEntity } from 'applications/editor/data/api'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import { getMapMouseEventNearestFeature } from 'utils/mapHelper'; import { getMap, getShowOSM, getTerrain3DExaggeration } from 'reducers/map/selectors'; import { LAYER_GROUPS_ORDER, LAYERS } from 'config/layerOrder'; @@ -55,6 +54,7 @@ interface MapProps { viewport: Viewport; setViewport: (newViewport: Partial, updateRouter?: boolean) => void; mapRef: React.RefObject; + infraID: number | undefined; } interface MapState { @@ -72,6 +72,7 @@ const MapUnplugged = ({ viewport, setViewport, children, + infraID, }: PropsWithChildren) => { const dispatch = useDispatch(); const mapBlankStyle = useMapBlankStyle(); @@ -81,7 +82,6 @@ const MapUnplugged = ({ isHovering: false, }); const context = useContext(EditorContext) as EditorContextType; - const infraID = useSelector(getInfraID); const switchTypes = useSwitchTypes(infraID); const editorState = useSelector((state: { editor: EditorState }) => state.editor); const showOSM = useSelector(getShowOSM); @@ -303,7 +303,10 @@ const MapUnplugged = ({ )} - + = ({ entity, className }) => { const { t } = useTranslation(); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const { data } = osrdEditoastApi.endpoints.getInfraByIdErrors.useQuery( { // Infra can be undefined, but in this case the query is skipped diff --git a/front/src/applications/editor/components/EntitySumUp.tsx b/front/src/applications/editor/components/EntitySumUp.tsx index 63ed9000997..ec97dfdfdef 100644 --- a/front/src/applications/editor/components/EntitySumUp.tsx +++ b/front/src/applications/editor/components/EntitySumUp.tsx @@ -1,13 +1,14 @@ import React, { FC, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { flatMap, forEach, isNumber, uniq } from 'lodash'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { Dispatch } from 'redux'; import { TFunction } from 'i18next'; import cx from 'classnames'; import { LoaderFill } from 'common/Loader'; -import { +import { useInfraID } from 'common/osrdContext'; +import type { BufferStopEntity, CatenaryEntity, EditorEntity, @@ -18,7 +19,6 @@ import { TrackSectionEntity, } from 'types'; import { getSpeedSectionsNameString } from 'common/Map/Layers/SpeedLimits'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import { EditoastType } from '../tools/types'; import { NEW_ENTITY_ID } from '../data/utils'; import { getEntities, getEntity } from '../data/api'; @@ -302,7 +302,7 @@ const EntitySumUp: FC< > = ({ entity, id, objType, classes, status, error }) => { const dispatch = useDispatch(); const { t } = useTranslation(); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const [state, setState] = useState< | { type: 'idle' } | { type: 'loading' } diff --git a/front/src/applications/editor/components/InfraErrors/InfraErrorCorrectorModal.tsx b/front/src/applications/editor/components/InfraErrors/InfraErrorCorrectorModal.tsx index b89e818cba5..1f7dabbdec6 100644 --- a/front/src/applications/editor/components/InfraErrors/InfraErrorCorrectorModal.tsx +++ b/front/src/applications/editor/components/InfraErrors/InfraErrorCorrectorModal.tsx @@ -1,20 +1,21 @@ import React, { useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { useTranslation } from 'react-i18next'; -import { ConfirmModal, useModal } from 'common/BootstrapSNCF/ModalSNCF'; -import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import { OPERATION_TYPE } from 'applications/editor/tools/types'; + import Loader from 'common/Loader'; +import { useInfraID } from 'common/osrdContext'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import { ConfirmModal, useModal } from 'common/BootstrapSNCF/ModalSNCF'; + import { saveOperations } from 'reducers/editor'; -import { getInfraID } from 'reducers/osrdconf/selectors'; -import { OPERATION_TYPE } from 'applications/editor/tools/types'; const InfraErrorCorrectorModal = () => { const { t } = useTranslation(); const dispatch = useDispatch(); const { closeModal } = useModal(); - - const infraId = useSelector(getInfraID); + const infraId = useInfraID(); const [isSaving, setIsSaving] = useState(false); const { data: infraAutoFixes, isLoading } = diff --git a/front/src/applications/editor/components/InfraErrors/InfraErrorsModal.tsx b/front/src/applications/editor/components/InfraErrors/InfraErrorsModal.tsx index 1c8e581afb9..7f1269223da 100644 --- a/front/src/applications/editor/components/InfraErrors/InfraErrorsModal.tsx +++ b/front/src/applications/editor/components/InfraErrors/InfraErrorsModal.tsx @@ -1,11 +1,11 @@ import React, { FC } from 'react'; -import { useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; import { Modal } from 'common/BootstrapSNCF/ModalSNCF'; +import { useInfraID } from 'common/osrdContext'; + import InfraErrorsList from './InfraErrorsList'; -import { InfraError } from './types'; -import { getInfraID } from '../../../../reducers/osrdconf/selectors'; +import type { InfraError } from './types'; interface InfraErrorsModalProps { onErrorClick: (infraId: number, item: InfraError) => void | Promise; @@ -13,7 +13,7 @@ interface InfraErrorsModalProps { const InfraErrorsModal: FC = ({ onErrorClick }) => { const { t } = useTranslation(); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); return ( diff --git a/front/src/applications/editor/components/LayersModal.tsx b/front/src/applications/editor/components/LayersModal.tsx index 19dcc0dee12..216d60e83d3 100644 --- a/front/src/applications/editor/components/LayersModal.tsx +++ b/front/src/applications/editor/components/LayersModal.tsx @@ -3,27 +3,30 @@ import { useDispatch, useSelector } from 'react-redux'; import { groupBy, mapKeys, mapValues, sum, isString, isArray, uniq } from 'lodash'; import { useTranslation } from 'react-i18next'; import { MdSpeed } from 'react-icons/md'; +import { GiElectric } from 'react-icons/gi'; import { TbRectangleVerticalFilled } from 'react-icons/tb'; -import bufferStopIcon from 'assets/pictures/layersicons/bufferstop.svg'; +import { EDITOAST_TO_LAYER_DICT } from 'applications/editor/tools/types'; +import type { LayerType, EditoastType } from 'applications/editor/tools/types'; +import type { EditorEntity } from 'types'; + +import pslsIcon from 'assets/pictures/layersicons/layer_tivs.svg'; import switchesIcon from 'assets/pictures/layersicons/switches.svg'; import detectorsIcon from 'assets/pictures/layersicons/detectors.svg'; -import trackSectionsIcon from 'assets/pictures/layersicons/layer_adv.svg'; import signalsIcon from 'assets/pictures/layersicons/layer_signal.svg'; -import pslsIcon from 'assets/pictures/layersicons/layer_tivs.svg'; +import bufferStopIcon from 'assets/pictures/layersicons/bufferstop.svg'; +import trackSectionsIcon from 'assets/pictures/layersicons/layer_adv.svg'; -import SwitchSNCF from 'common/BootstrapSNCF/SwitchSNCF/SwitchSNCF'; +import { useInfraID } from 'common/osrdContext'; import { Modal } from 'common/BootstrapSNCF/ModalSNCF'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import SwitchSNCF from 'common/BootstrapSNCF/SwitchSNCF/SwitchSNCF'; +import MapSettingsMapStyle from 'common/Map/Settings/MapSettingsMapStyle'; import MapSettingsBackgroundSwitches from 'common/Map/Settings/MapSettingsBackgroundSwitches'; -import { GiElectric } from 'react-icons/gi'; -import { LayerType, EDITOAST_TO_LAYER_DICT, EditoastType } from 'applications/editor/tools/types'; -import { selectLayers } from 'reducers/editor'; -import { EditorEntity } from 'types'; + import { getMap } from 'reducers/map/selectors'; -import { getInfraID } from 'reducers/osrdconf/selectors'; -import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; import { updateLayersSettings } from 'reducers/map'; -import MapSettingsMapStyle from 'common/Map/Settings/MapSettingsMapStyle'; +import { editorSliceActions } from 'reducers/editor'; export const LAYERS: Array<{ layers: LayerType[]; icon: string | JSX.Element }> = [ { layers: ['track_sections'], icon: trackSectionsIcon }, @@ -56,7 +59,7 @@ const LayersModal: FC = ({ const { t } = useTranslation(); const { layersSettings } = useSelector(getMap); const [selectedLayers, setSelectedLayers] = useState>(initialLayers); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const { data: speedLimitTags } = osrdEditoastApi.endpoints.getInfraByIdSpeedLimitTags.useQuery({ id: infraID as number, @@ -138,7 +141,7 @@ const LayersModal: FC = ({ return result; }, new Set(selectedLayers)); setSelectedLayers(newSelectedLayersList); - dispatch(selectLayers(newSelectedLayersList)); + dispatch(editorSliceActions.selectLayers(newSelectedLayersList)); onChange({ newLayers: newSelectedLayersList }); }} name={`editor-layer-${layerKey}`} diff --git a/front/src/applications/editor/nav.tsx b/front/src/applications/editor/nav.tsx index 6b8563b8e2a..47ad8445a12 100644 --- a/front/src/applications/editor/nav.tsx +++ b/front/src/applications/editor/nav.tsx @@ -1,23 +1,27 @@ import React from 'react'; import { Dispatch } from 'redux'; +import { MapRef } from 'react-map-gl/maplibre'; +import { NavigateFunction } from 'react-router-dom'; import { IconType } from 'react-icons'; -import { BsExclamationOctagon, BsSliders2 } from 'react-icons/bs'; -import { FaRegCompass } from 'react-icons/fa'; import { GiRailway } from 'react-icons/gi'; +import { FaRegCompass } from 'react-icons/fa'; +import { GoSearch, GoZoomIn, GoZoomOut } from 'react-icons/go'; +import { BsExclamationOctagon, BsSliders2 } from 'react-icons/bs'; import { isNil } from 'lodash'; -import { NavigateFunction } from 'react-router-dom'; -import { MapRef } from 'react-map-gl/maplibre'; -import { Viewport } from 'reducers/map'; -import { selectLayers } from 'reducers/editor'; -import { Shortcut } from 'utils/hooks/useKeyboardShortcuts'; -import { ModalContextType } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; +import type { Shortcut } from 'utils/hooks/useKeyboardShortcuts'; + +import LayersModal from 'applications/editor/components/LayersModal'; +import { EDITOAST_TO_LAYER_DICT } from 'applications/editor/tools/types'; +import { SelectionState } from 'applications/editor/tools/selection/types'; +import type { EditorState, EditoastType } from 'applications/editor/tools/types'; +import type { EditorContextType, Tool } from 'applications/editor/tools/editorContextTypes'; + import InfraSelectorModal from 'common/InfraSelector/InfraSelectorModal'; -import { GoSearch, GoZoomIn, GoZoomOut } from 'react-icons/go'; -import { EditorState, EDITOAST_TO_LAYER_DICT, EditoastType } from './tools/types'; -import LayersModal from './components/LayersModal'; -import { SelectionState } from './tools/selection/types'; -import { EditorContextType, Tool } from './tools/editorContextTypes'; +import type { ModalContextType } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; + +import type { Viewport } from 'reducers/map'; +import { editorSliceActions } from 'reducers/editor'; const ZOOM_DEFAULT = 5; const ZOOM_DELTA = 1.5; @@ -154,7 +158,7 @@ const NavButtons: NavButton[][] = [ const newSet = new Set(editorState.editorLayers); if (newSet.has('errors')) newSet.delete('errors'); else newSet.add('errors'); - dispatch(selectLayers(newSet)); + dispatch(editorSliceActions.selectLayers(newSet)); }, }, ], diff --git a/front/src/applications/editor/tools/pointEdition/components.tsx b/front/src/applications/editor/tools/pointEdition/components.tsx index 66d4cc02684..7c6b352e884 100644 --- a/front/src/applications/editor/tools/pointEdition/components.tsx +++ b/front/src/applications/editor/tools/pointEdition/components.tsx @@ -1,20 +1,35 @@ -import { Map } from 'maplibre-gl'; -import React, { ComponentType, FC, useContext, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useContext, useEffect, useMemo, useRef, useState } from 'react'; +import type { ComponentType } from 'react'; import { useDispatch, useSelector } from 'react-redux'; +import { Map } from 'maplibre-gl'; import { Popup } from 'react-map-gl/maplibre'; import { useTranslation } from 'react-i18next'; -import { featureCollection } from '@turf/helpers'; import { isEqual } from 'lodash'; import along from '@turf/along'; -import { BiArrowFromLeft, BiArrowToRight } from 'react-icons/bi'; +import length from '@turf/length'; +import { featureCollection } from '@turf/helpers'; import { BsBoxArrowInRight } from 'react-icons/bs'; +import { BiArrowFromLeft, BiArrowToRight } from 'react-icons/bi'; -import GeoJSONs, { EditorSource, SourcesDefinitionsIndex } from 'common/Map/Layers/GeoJSONs'; -import colors from 'common/Map/Consts/colors'; -import { save } from 'reducers/editor'; -import { getInfraID } from 'reducers/osrdconf/selectors'; -import { - NULL_GEOMETRY, +import type { + ExtendedEditorContextType, + EditorContextType, +} from 'applications/editor/tools/editorContextTypes'; +import EditorContext from 'applications/editor/context'; +import TOOL_TYPES from 'applications/editor/tools/toolTypes'; +import EditorForm from 'applications/editor/components/EditorForm'; +import type { EditoastType } from 'applications/editor/tools/types'; +import EntityError from 'applications/editor/components/EntityError'; +import EntitySumUp from 'applications/editor/components/EntitySumUp'; +import { getEntities, getEntity } from 'applications/editor/data/api'; +import { getEditRouteState } from 'applications/editor/tools/routeEdition/utils'; +import type { PointEditionState } from 'applications/editor/tools/pointEdition/types'; +import { formatSignalingSystems } from 'applications/editor/tools/pointEdition/utils'; +import { CustomPosition } from 'applications/editor/tools/pointEdition/CustomPosition'; +import { NEW_ENTITY_ID, flattenEntity, cleanSymbolType } from 'applications/editor/data/utils'; +import { CustomFlagSignalCheckbox } from 'applications/editor/tools/pointEdition/CustomFlagSignalCheckbox'; + +import type { EditorEntity, TrackSectionEntity, RouteEntity, @@ -22,39 +37,33 @@ import { DetectorEntity, BufferStopEntity, } from 'types'; +import { NULL_GEOMETRY } from 'types'; + +import { save } from 'reducers/editor'; +import { getMap } from 'reducers/map/selectors'; + +import colors from 'common/Map/Consts/colors'; +import GeoJSONs, { EditorSource, SourcesDefinitionsIndex } from 'common/Map/Layers/GeoJSONs'; import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; -import EditorForm from 'applications/editor/components/EditorForm'; -import EntitySumUp from 'applications/editor/components/EntitySumUp'; -import EditorContext from 'applications/editor/context'; -import { getEntities, getEntity } from 'applications/editor/data/api'; -import { NEW_ENTITY_ID, flattenEntity, cleanSymbolType } from 'applications/editor/data/utils'; import { Spinner } from 'common/Loader'; -import { getMap } from 'reducers/map/selectors'; -import EntityError from 'applications/editor/components/EntityError'; -import { - ExtendedEditorContextType, - EditorContextType, -} from 'applications/editor/tools/editorContextTypes'; -import { getEditRouteState } from 'applications/editor/tools/routeEdition/utils'; -import TOOL_TYPES from 'applications/editor/tools/toolTypes'; -import { EditoastType } from 'applications/editor/tools/types'; -import length from '@turf/length'; -import { CustomFlagSignalCheckbox } from './CustomFlagSignalCheckbox'; -import { PointEditionState } from './types'; -import { formatSignalingSystems } from './utils'; -import { CustomPosition } from './CustomPosition'; +import { useInfraID } from 'common/osrdContext'; export const POINT_LAYER_ID = 'pointEditionTool/new-entity'; type EditorPoint = BufferStopEntity | DetectorEntity | SignalEntity; +interface RoutesListProps { + type: EditoastType; + id: string; +} + /** * Generic component to show routes starting or ending from the edited waypoint: */ -export const RoutesList: FC<{ type: EditoastType; id: string }> = ({ type, id }) => { +export const RoutesList = ({ type, id }: RoutesListProps) => { const dispatch = useDispatch(); const { t } = useTranslation(); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const [routesState, setRoutesState] = useState< | { type: 'idle' } | { type: 'loading' } @@ -186,17 +195,18 @@ export const RoutesList: FC<{ type: EditoastType; id: string }> = ({ type, id }) ); }; +interface PointEditionLeftPanelProps { + type: EditoastType; +} /** * Generic component for point edition left panel: */ -export const PointEditionLeftPanel: FC<{ type: EditoastType }> = ({ +export const PointEditionLeftPanel = ({ type, -}: { - type: EditoastType; -}) => { +}: PointEditionLeftPanelProps) => { const dispatch = useDispatch(); const { t } = useTranslation(); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const { state, setState, isFormSubmited, setIsFormSubmited } = useContext( EditorContext ) as ExtendedEditorContextType>; @@ -370,7 +380,7 @@ export const getPointEditionLeftPanel = () => ; -export const BasePointEditionLayers: FC<{ +interface BasePointEditionLayersProps { // eslint-disable-next-line react/no-unused-prop-types map: Map; mergeEntityWithNearestPoint?: ( @@ -378,7 +388,13 @@ export const BasePointEditionLayers: FC<{ nearestPoint: NonNullable['nearestPoint']> ) => EditorEntity; interactiveLayerIDRegex?: RegExp; -}> = ({ mergeEntityWithNearestPoint, interactiveLayerIDRegex }) => { +} + +export const BasePointEditionLayers = ({ + mergeEntityWithNearestPoint, + interactiveLayerIDRegex, +}: BasePointEditionLayersProps) => { + const infraID = useInfraID(); const { renderingFingerprint, state: { nearestPoint, mousePosition, entity, objType }, @@ -446,6 +462,7 @@ export const BasePointEditionLayers: FC<{ fingerprint={renderingFingerprint} layersSettings={layersSettings} issuesSettings={issuesSettings} + infraID={infraID} /> {/* Edited entity */} @@ -465,7 +482,7 @@ export const BasePointEditionLayers: FC<{ ); }; -export const SignalEditionLayers: FC<{ map: Map }> = ({ map }) => ( +export const SignalEditionLayers = ({ map }: { map: Map }) => ( { +import type { CatenaryEntity, TrackSectionEntity } from 'types'; + +import colors from 'common/Map/Consts/colors'; +import { useInfraID } from 'common/osrdContext'; +import GeoJSONs, { SourcesDefinitionsIndex } from 'common/Map/Layers/GeoJSONs'; + +import { getMap } from 'reducers/map/selectors'; + +export const CatenaryEditionLayers = () => { const dispatch = useDispatch(); const { t } = useTranslation(); const { @@ -29,7 +33,8 @@ export const CatenaryEditionLayers: FC = () => { } = useContext(EditorContext) as ExtendedEditorContextType>; const { mapStyle, layersSettings, issuesSettings, showIGNBDORTHO } = useSelector(getMap); - const infraId = useSelector(getInfraID); + + const infraID = useInfraID(); const selection = useMemo(() => { // Dragging an extremity: if (interactionState.type === 'moveRangeExtremity') @@ -91,7 +96,7 @@ export const CatenaryEditionLayers: FC = () => { })); getEntities( - infraId as number, + infraID as number, missingTrackIDs, 'TrackSection', dispatch @@ -119,7 +124,7 @@ export const CatenaryEditionLayers: FC = () => { })); getEntity( - infraId as number, + infraID as number, hoveredItem.id, 'TrackSection', dispatch @@ -189,6 +194,7 @@ export const CatenaryEditionLayers: FC = () => { layersSettings={layersSettings} issuesSettings={issuesSettings} isEmphasized={false} + infraID={infraID} /> {layersProps.map((props, i) => ( @@ -210,7 +216,7 @@ export const CatenaryEditionLayers: FC = () => { ); }; -export const CatenaryMessages: FC = () => { +export const CatenaryMessages = () => { const { t } = useTranslation(); const { state } = useContext(EditorContext) as ExtendedEditorContextType< RangeEditionState diff --git a/front/src/applications/editor/tools/rangeEdition/components.tsx b/front/src/applications/editor/tools/rangeEdition/components.tsx index 966305cc807..1ff2a0224df 100644 --- a/front/src/applications/editor/tools/rangeEdition/components.tsx +++ b/front/src/applications/editor/tools/rangeEdition/components.tsx @@ -1,40 +1,40 @@ -import { cloneDeep } from 'lodash'; -import { useSelector } from 'react-redux'; +import React, { useContext, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import React, { FC, useContext, useState } from 'react'; import { BsArrowBarRight } from 'react-icons/bs'; import { MdShowChart } from 'react-icons/md'; import { FaFlagCheckered, FaTimes } from 'react-icons/fa'; +import { cloneDeep } from 'lodash'; import EditorContext from 'applications/editor/context'; +import { NEW_ENTITY_ID } from 'applications/editor/data/utils'; import EntityError from 'applications/editor/components/EntityError'; import EntitySumUp from 'applications/editor/components/EntitySumUp'; -import { NEW_ENTITY_ID } from 'applications/editor/data/utils'; -import { +import type { RangeEditionState } from 'applications/editor/tools/rangeEdition/types'; +import { getPointAt, speedSectionIsPsl } from 'applications/editor/tools/rangeEdition/utils'; +import EditPSLSection from 'applications/editor/tools/rangeEdition/speedSection/EditPSLSection'; +import CatenaryMetadataForm from 'applications/editor/tools/rangeEdition/catenary/CatenaryMetadataForm'; +import SpeedSectionMetadataForm from 'applications/editor/tools/rangeEdition/speedSection/SpeedSectionMetadataForm'; +import type { ExtendedEditorContextType, PartialOrReducer, } from 'applications/editor/tools/editorContextTypes'; -import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; -import CheckboxRadioSNCF from 'common/BootstrapSNCF/CheckboxRadioSNCF'; -import { LoaderFill } from 'common/Loader'; -import { getInfraID } from 'reducers/osrdconf/selectors'; -import { - APPLICABLE_DIRECTIONS, + +import type { ApplicableDirection, CatenaryEntity, SpeedSectionEntity, SpeedSectionPslEntity, } from 'types'; +import { APPLICABLE_DIRECTIONS } from 'types'; -import CatenaryMetadataForm from './catenary/CatenaryMetadataForm'; -import EditPSLSection from './speedSection/EditPSLSection'; -import SpeedSectionMetadataForm from './speedSection/SpeedSectionMetadataForm'; -import { RangeEditionState } from './types'; -import { getPointAt, speedSectionIsPsl } from './utils'; +import { LoaderFill } from 'common/Loader'; +import { useInfraID } from 'common/osrdContext'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import CheckboxRadioSNCF from 'common/BootstrapSNCF/CheckboxRadioSNCF'; const DEFAULT_DISPLAYED_RANGES_COUNT = 5; -export const TrackRangesList: FC = () => { +export const TrackRangesList = () => { const { state: { entity, trackSectionsCache }, setState, @@ -210,7 +210,7 @@ export const TrackRangesList: FC = () => { ); }; -export const RangeEditionLeftPanel: FC = () => { +export const RangeEditionLeftPanel = () => { const { t } = useTranslation(); const { setState, @@ -221,8 +221,7 @@ export const RangeEditionLeftPanel: FC = () => { const isNew = entity.properties.id === NEW_ENTITY_ID; const isPSL = speedSectionIsPsl(entity as SpeedSectionEntity); - - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const { data: voltages } = osrdEditoastApi.useGetInfraByIdVoltagesQuery( { diff --git a/front/src/applications/editor/tools/rangeEdition/speedSection/SpeedSectionEditionLayers.tsx b/front/src/applications/editor/tools/rangeEdition/speedSection/SpeedSectionEditionLayers.tsx index 83cf5f155fe..5a624f17f3b 100644 --- a/front/src/applications/editor/tools/rangeEdition/speedSection/SpeedSectionEditionLayers.tsx +++ b/front/src/applications/editor/tools/rangeEdition/speedSection/SpeedSectionEditionLayers.tsx @@ -1,35 +1,39 @@ +import React, { useContext, useEffect, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; -import React, { FC, useContext, useEffect, useMemo } from 'react'; -import { getMap } from 'reducers/map/selectors'; +import { Layer, Popup, Source } from 'react-map-gl/maplibre'; +import type { Feature, FeatureCollection, LineString, Point } from 'geojson'; +import { featureCollection } from '@turf/helpers'; +import { mapValues } from 'lodash'; + import EditorContext from 'applications/editor/context'; -import { Feature, FeatureCollection, LineString, Point } from 'geojson'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import { flattenEntity } from 'applications/editor/data/utils'; -import { featureCollection } from '@turf/helpers'; -import { SpeedSectionEntity, TrackSectionEntity } from 'types'; -import colors from 'common/Map/Consts/colors'; -import GeoJSONs, { SourcesDefinitionsIndex } from 'common/Map/Layers/GeoJSONs'; +import EntitySumUp from 'applications/editor/components/EntitySumUp'; import { getEntities, getEntity } from 'applications/editor/data/api'; -import { mapValues } from 'lodash'; -import { Layer, Popup, Source } from 'react-map-gl/maplibre'; +import type { ExtendedEditorContextType } from 'applications/editor/tools/editorContextTypes'; +import type { + PslSignFeature, + RangeEditionState, + TrackState, +} from 'applications/editor/tools/rangeEdition/types'; import { generatePslSignFeatures, getTrackRangeFeatures, isOnModeMove, speedSectionIsPsl, } from 'applications/editor/tools/rangeEdition/utils'; -import { - PslSignFeature, - RangeEditionState, - TrackState, -} from 'applications/editor/tools/rangeEdition/types'; -import { ExtendedEditorContextType } from 'applications/editor/tools/editorContextTypes'; -import EntitySumUp from 'applications/editor/components/EntitySumUp'; + +import type { SpeedSectionEntity, TrackSectionEntity } from 'types'; + +import colors from 'common/Map/Consts/colors'; +import { useInfraID } from 'common/osrdContext'; +import GeoJSONs, { SourcesDefinitionsIndex } from 'common/Map/Layers/GeoJSONs'; + +import { getMap } from 'reducers/map/selectors'; const emptyFeatureCollection = featureCollection([]); -export const SpeedSectionEditionLayers: FC = () => { +export const SpeedSectionEditionLayers = () => { const dispatch = useDispatch(); const { t } = useTranslation(); const { @@ -40,7 +44,7 @@ export const SpeedSectionEditionLayers: FC = () => { } = useContext(EditorContext) as ExtendedEditorContextType>; const isPSL = speedSectionIsPsl(entity); const { mapStyle, layersSettings, issuesSettings, showIGNBDORTHO } = useSelector(getMap); - const infraId = useSelector(getInfraID); + const infraID = useInfraID(); const selection = useMemo(() => { const res: string[] = [entity.properties.id]; @@ -126,7 +130,7 @@ export const SpeedSectionEditionLayers: FC = () => { })); getEntities( - infraId as number, + infraID as number, missingTrackIDs, 'TrackSection', dispatch @@ -154,7 +158,7 @@ export const SpeedSectionEditionLayers: FC = () => { })); getEntity( - infraId as number, + infraID as number, hoveredItem.id, 'TrackSection', dispatch @@ -236,6 +240,7 @@ export const SpeedSectionEditionLayers: FC = () => { layersSettings={layersSettings} issuesSettings={issuesSettings} isEmphasized={false} + infraID={infraID} /> { ); }; -export const SpeedSectionMessages: FC = () => null; +export const SpeedSectionMessages = () => null; // export const SpeedSectionMessages: FC = () => { // const { t } = useTranslation(); diff --git a/front/src/applications/editor/tools/routeEdition/components.tsx b/front/src/applications/editor/tools/routeEdition/components.tsx index b545d326e0e..8b56e15330a 100644 --- a/front/src/applications/editor/tools/routeEdition/components.tsx +++ b/front/src/applications/editor/tools/routeEdition/components.tsx @@ -1,18 +1,30 @@ -import React, { FC, useContext } from 'react'; +import React, { useContext } from 'react'; import { useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; - import { compact } from 'lodash'; + import EditorContext from 'applications/editor/context'; +import type { ExtendedEditorContextType } from 'applications/editor/tools/editorContextTypes'; +import type { + EditRoutePathState, + RouteEditionState, +} from 'applications/editor/tools/routeEdition/types'; +import { + EditRoutePathEditionLayers, + EditRoutePathLeftPanel, +} from 'applications/editor/tools/routeEdition/components/EditRoutePath'; +import { + EditRouteMetadataLayers, + EditRouteMetadataPanel, +} from 'applications/editor/tools/routeEdition/components/EditRouteMetadata'; + import colors from 'common/Map/Consts/colors'; import GeoJSONs from 'common/Map/Layers/GeoJSONs'; +import { useInfraID } from 'common/osrdContext'; + import { getMap } from 'reducers/map/selectors'; -import { ExtendedEditorContextType } from 'applications/editor/tools/editorContextTypes'; -import { EditRoutePathState, RouteEditionState } from './types'; -import { EditRoutePathEditionLayers, EditRoutePathLeftPanel } from './components/EditRoutePath'; -import { EditRouteMetadataLayers, EditRouteMetadataPanel } from './components/EditRouteMetadata'; -export const RouteEditionLeftPanel: FC = () => { +export const RouteEditionLeftPanel = () => { const { state } = useContext(EditorContext) as ExtendedEditorContextType; return ( @@ -26,14 +38,14 @@ export const RouteEditionLeftPanel: FC = () => { ); }; -export const RouteEditionLayers: FC = () => { +export const RouteEditionLayers = () => { const { state, renderingFingerprint, editorState: { editorLayers }, } = useContext(EditorContext) as ExtendedEditorContextType; const { mapStyle, layersSettings, issuesSettings } = useSelector(getMap); - + const infraID = useInfraID(); const { routeState, optionsState } = state as EditRoutePathState; const selectedRouteIndex = optionsState.type === 'options' ? optionsState.focusedOptionIndex : undefined; @@ -60,6 +72,7 @@ export const RouteEditionLayers: FC = () => { fingerprint={renderingFingerprint} layersSettings={layersSettings} issuesSettings={issuesSettings} + infraID={infraID} /> {state.type === 'editRoutePath' ? ( @@ -70,7 +83,7 @@ export const RouteEditionLayers: FC = () => { ); }; -export const RouteMessages: FC = () => { +export const RouteMessages = () => { const { t } = useTranslation(); const { state } = useContext(EditorContext) as ExtendedEditorContextType; diff --git a/front/src/applications/editor/tools/routeEdition/components/EditRouteMetadata.tsx b/front/src/applications/editor/tools/routeEdition/components/EditRouteMetadata.tsx index 256905e0535..7793652978b 100644 --- a/front/src/applications/editor/tools/routeEdition/components/EditRouteMetadata.tsx +++ b/front/src/applications/editor/tools/routeEdition/components/EditRouteMetadata.tsx @@ -1,38 +1,48 @@ -import React, { FC, useContext, useEffect, useMemo, useState } from 'react'; +import React, { useContext, useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { Feature, LineString } from 'geojson'; -import { Layer, Popup, Source } from 'react-map-gl/maplibre'; -import { featureCollection, lineString } from '@turf/helpers'; import { useTranslation } from 'react-i18next'; -import { cloneDeep, first, isEqual, last } from 'lodash'; import { FaFlagCheckered } from 'react-icons/fa'; import { BsArrowBarRight } from 'react-icons/bs'; import { MdDelete, MdSave } from 'react-icons/md'; import { GoPlusCircle } from 'react-icons/go'; -import { EditorEntity, WayPointEntity } from 'types/editor'; -import { addFailureNotification, addSuccessNotification } from 'reducers/main'; +import { Layer, Popup, Source } from 'react-map-gl/maplibre'; +import { featureCollection, lineString } from '@turf/helpers'; +import type { Feature, LineString } from 'geojson'; +import { cloneDeep, first, isEqual, last } from 'lodash'; + +import type { EditorEntity, WayPointEntity } from 'types/editor'; +import EditorContext from 'applications/editor/context'; +import { NEW_ENTITY_ID } from 'applications/editor/data/utils'; +import { getMixedEntities } from 'applications/editor/data/api'; +import EntityError from 'applications/editor/components/EntityError'; +import type { ExtendedEditorContextType } from 'applications/editor/tools/editorContextTypes'; +import { DisplayEndpoints } from 'applications/editor/tools/routeEdition/components/Endpoints'; +import type { + EditRoutePathState, + EditRouteMetadataState, + RouteEditionState, +} from 'applications/editor/tools/routeEdition/types'; +import { + getEditRouteState, + getEmptyCreateRouteState, + getRouteGeometryByRouteId, +} from 'applications/editor/tools/routeEdition/utils'; -import { EditRoutePathState, EditRouteMetadataState, RouteEditionState } from '../types'; +import { LoaderFill } from 'common/Loader'; +import colors from 'common/Map/Consts/colors'; +import { useInfraID } from 'common/osrdContext'; +import { ConfirmModal } from 'common/BootstrapSNCF/ModalSNCF/ConfirmModal'; import { getRoutesLineLayerProps, getRoutesPointLayerProps, getRoutesTextLayerProps, -} from '../../../../../common/Map/Layers/Routes'; -import colors from '../../../../../common/Map/Consts/colors'; -import { getEditRouteState, getEmptyCreateRouteState, getRouteGeometryByRouteId } from '../utils'; -import EditorContext from '../../../context'; -import { getMixedEntities } from '../../../data/api'; -import { LoaderFill } from '../../../../../common/Loader'; -import { ConfirmModal } from '../../../../../common/BootstrapSNCF/ModalSNCF/ConfirmModal'; -import { save } from '../../../../../reducers/editor'; -import { DisplayEndpoints } from './Endpoints'; -import { getInfraID } from '../../../../../reducers/osrdconf/selectors'; -import { getMapStyle } from '../../../../../reducers/map/selectors'; -import { ExtendedEditorContextType } from '../../editorContextTypes'; -import EntityError from '../../../components/EntityError'; -import { NEW_ENTITY_ID } from '../../../data/utils'; +} from 'common/Map/Layers/Routes'; + +import { save } from 'reducers/editor'; +import { getMapStyle } from 'reducers/map/selectors'; +import { addFailureNotification, addSuccessNotification } from 'reducers/main'; -export const EditRouteMetadataPanel: FC<{ state: EditRouteMetadataState }> = ({ state }) => { +export const EditRouteMetadataPanel = ({ state }: { state: EditRouteMetadataState }) => { const dispatch = useDispatch(); const { t } = useTranslation(); const { initialRouteEntity, routeEntity } = state; @@ -40,7 +50,7 @@ export const EditRouteMetadataPanel: FC<{ state: EditRouteMetadataState }> = ({ const { setState, openModal, closeModal } = useContext( EditorContext ) as ExtendedEditorContextType; - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const [isLoading, setIsLoading] = useState(false); const isReleaseDetectorsEditionLocked = @@ -52,13 +62,11 @@ export const EditRouteMetadataPanel: FC<{ state: EditRouteMetadataState }> = ({
{t('Editor.tools.routes-edition.edit-route')}
@@ -190,10 +198,10 @@ export const EditRouteMetadataPanel: FC<{ state: EditRouteMetadataState }> = ({ ); }; -export const EditRouteMetadataLayers: FC<{ state: EditRouteMetadataState }> = ({ state }) => { +export const EditRouteMetadataLayers = ({ state }: { state: EditRouteMetadataState }) => { const dispatch = useDispatch(); const { t } = useTranslation(); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const mapStyle = useSelector(getMapStyle); const lineProps = useMemo(() => { diff --git a/front/src/applications/editor/tools/routeEdition/components/EditRoutePath.tsx b/front/src/applications/editor/tools/routeEdition/components/EditRoutePath.tsx index 93e12b18f99..2a67a20d7fa 100644 --- a/front/src/applications/editor/tools/routeEdition/components/EditRoutePath.tsx +++ b/front/src/applications/editor/tools/routeEdition/components/EditRoutePath.tsx @@ -1,45 +1,49 @@ -import React, { FC, useCallback, useContext, useMemo, useState } from 'react'; +import React, { useCallback, useContext, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; -import chroma from 'chroma-js'; -import { Layer, LineLayer, Popup, Source } from 'react-map-gl/maplibre'; +import type { LineLayer } from 'react-map-gl/maplibre'; +import { Layer, Popup, Source } from 'react-map-gl/maplibre'; +import { FiSearch } from 'react-icons/fi'; +import { FaFlagCheckered } from 'react-icons/fa'; +import { BsArrowBarRight } from 'react-icons/bs'; import { featureCollection } from '@turf/helpers'; import cx from 'classnames'; import { omit } from 'lodash'; -import { FaFlagCheckered } from 'react-icons/fa'; -import { BsArrowBarRight } from 'react-icons/bs'; -import { FiSearch } from 'react-icons/fi'; +import chroma from 'chroma-js'; + +import type { EditorEntity, OmitLayer, RouteEntity, WayPointEntity } from 'types'; -import { EditorEntity, OmitLayer, RouteEntity, WayPointEntity } from 'types'; -import { LoaderFill } from 'common/Loader'; -import { getRoutesLineLayerProps } from 'common/Map/Layers/Routes'; -import colors from 'common/Map/Consts/colors'; -import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; -import { getInfraID } from 'reducers/osrdconf/selectors'; -import { getMapStyle } from 'reducers/map/selectors'; import EditorContext from 'applications/editor/context'; import { getEntity } from 'applications/editor/data/api'; +import EntitySumUp from 'applications/editor/components/EntitySumUp'; import { nestEntity, entityToCreateOperation } from 'applications/editor/data/utils'; +import type { ExtendedEditorContextType } from 'applications/editor/tools/editorContextTypes'; +import { EditEndpoints } from 'applications/editor/tools/routeEdition/components/Endpoints'; +import type { + EditRoutePathState, + OptionsStateType, + RouteEditionState, +} from 'applications/editor/tools/routeEdition/types'; import { getCompatibleRoutesPayload, getEditRouteState, getRouteGeometries, } from 'applications/editor/tools/routeEdition/utils'; -import EntitySumUp from 'applications/editor/components/EntitySumUp'; -import { ExtendedEditorContextType } from 'applications/editor/tools/editorContextTypes'; -import { - EditRoutePathState, - OptionsStateType, - RouteEditionState, -} from 'applications/editor/tools/routeEdition/types'; -import { EditEndpoints } from './Endpoints'; -export const EditRoutePathLeftPanel: FC<{ state: EditRoutePathState }> = ({ state }) => { +import { LoaderFill } from 'common/Loader'; +import colors from 'common/Map/Consts/colors'; +import { useInfraID } from 'common/osrdContext'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import { getRoutesLineLayerProps } from 'common/Map/Layers/Routes'; + +import { getMapStyle } from 'reducers/map/selectors'; + +export const EditRoutePathLeftPanel = ({ state }: { state: EditRoutePathState }) => { const dispatch = useDispatch(); const { t } = useTranslation(); const [editorSave] = osrdEditoastApi.endpoints.postInfraById.useMutation({}); const { setState } = useContext(EditorContext) as ExtendedEditorContextType; - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const [isSaving, setIsSaving] = useState(false); const [includeReleaseDetectors, setIncludeReleaseDetectors] = useState(true); const { entryPoint, exitPoint } = state.routeState; @@ -59,7 +63,10 @@ export const EditRoutePathLeftPanel: FC<{ state: EditRoutePathState }> = ({ stat exitPoint, dispatch ); - const candidates = await postPathfinding({ id: infraID as number, body: payload }).unwrap(); + const candidates = await postPathfinding({ + id: infraID as number, + body: payload, + }).unwrap(); const candidateColors = chroma .scale(['#321BF7CC', '#37B5F0CC', '#F0901FCC', '#F7311BCC', '#D124E0CC']) @@ -248,7 +255,7 @@ export const EditRoutePathLeftPanel: FC<{ state: EditRoutePathState }> = ({ stat ); }; -export const EditRoutePathEditionLayers: FC<{ state: EditRoutePathState }> = ({ +export const EditRoutePathEditionLayers = ({ state: { hovered, extremityEditionState, @@ -256,6 +263,8 @@ export const EditRoutePathEditionLayers: FC<{ state: EditRoutePathState }> = ({ optionsState, routeState: { entryPoint, exitPoint }, }, +}: { + state: EditRoutePathState; }) => { const mapStyle = useSelector(getMapStyle); const { t } = useTranslation(); diff --git a/front/src/applications/editor/tools/routeEdition/components/Endpoints.tsx b/front/src/applications/editor/tools/routeEdition/components/Endpoints.tsx index 57543dc442a..4fdc0e97f9f 100644 --- a/front/src/applications/editor/tools/routeEdition/components/Endpoints.tsx +++ b/front/src/applications/editor/tools/routeEdition/components/Endpoints.tsx @@ -1,23 +1,27 @@ -import React, { FC, useContext } from 'react'; -import { BsArrowBarRight, BsBoxArrowInRight } from 'react-icons/bs'; +import React, { useContext } from 'react'; import { HiSwitchVertical } from 'react-icons/hi'; import { FaFlagCheckered } from 'react-icons/fa'; +import { BsArrowBarRight, BsBoxArrowInRight } from 'react-icons/bs'; import { useTranslation } from 'react-i18next'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; + +import type { BufferStopEntity, DetectorEntity, WayPoint, WayPointEntity } from 'types'; -import { getInfraID } from 'reducers/osrdconf/selectors'; -import { BufferStopEntity, DetectorEntity, WayPoint, WayPointEntity } from 'types'; import EditorContext from 'applications/editor/context'; import { getEntity } from 'applications/editor/data/api'; -import EntitySumUp from 'applications/editor/components/EntitySumUp'; import TOOL_TYPES from 'applications/editor/tools/toolTypes'; -import { RouteState } from 'applications/editor/tools/routeEdition/types'; -import WayPointInput from './WayPointInput'; +import EntitySumUp from 'applications/editor/components/EntitySumUp'; +import type { RouteState } from 'applications/editor/tools/routeEdition/types'; +import WayPointInput from 'applications/editor/tools/routeEdition/components/WayPointInput'; -export const EditEndpoints: FC<{ state: RouteState; onChange: (newState: RouteState) => void }> = ({ - state, - onChange, -}) => { +import { useInfraID } from 'common/osrdContext'; + +interface EditEndpointsProps { + state: RouteState; + onChange: (newState: RouteState) => void; +} + +export const EditEndpoints = ({ state, onChange }: EditEndpointsProps) => { const { t } = useTranslation(); const { entryPoint, exitPoint } = state; @@ -59,11 +63,11 @@ export const EditEndpoints: FC<{ state: RouteState; onChange: (newState: RouteSt ); }; -const ExtremityDisplay: FC = ({ type, id }) => { +const ExtremityDisplay = ({ type, id }: WayPoint) => { const dispatch = useDispatch(); const { t } = useTranslation(); const { switchTool } = useContext(EditorContext); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); return (
@@ -104,11 +108,8 @@ const ExtremityDisplay: FC = ({ type, id }) => { ); }; -export const DisplayEndpoints: FC<{ - state: RouteState; -}> = ({ state }) => { +export const DisplayEndpoints = ({ entryPoint, exitPoint, entryPointDirection }: RouteState) => { const { t } = useTranslation(); - const { entryPoint, exitPoint, entryPointDirection } = state; return ( <> diff --git a/front/src/applications/editor/tools/routeEdition/components/WayPointInput.tsx b/front/src/applications/editor/tools/routeEdition/components/WayPointInput.tsx index 55d32d6d07c..707e795632a 100644 --- a/front/src/applications/editor/tools/routeEdition/components/WayPointInput.tsx +++ b/front/src/applications/editor/tools/routeEdition/components/WayPointInput.tsx @@ -1,30 +1,34 @@ -import React, { FC, useCallback, useContext, useEffect, useState } from 'react'; +import React, { useCallback, useContext, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { GoTrash } from 'react-icons/go'; import { FaMapMarkedAlt, FaTimesCircle } from 'react-icons/fa'; -import { Position } from 'geojson'; +import type { Position } from 'geojson'; + +import type { EndPoint, WayPoint, WayPointEntity } from 'types'; import EditorContext from 'applications/editor/context'; -import { EditRoutePathState, EndPointKeys } from 'applications/editor/tools/routeEdition/types'; import { getEntity } from 'applications/editor/data/api'; -import EntitySumUp from 'applications/editor/components/EntitySumUp'; import Tipped from 'applications/editor/components/Tipped'; -import { getInfraID } from 'reducers/osrdconf/selectors'; -import { ExtendedEditorContextType } from 'applications/editor/tools/editorContextTypes'; -import { EndPoint, WayPoint, WayPointEntity } from 'types'; +import EntitySumUp from 'applications/editor/components/EntitySumUp'; +import { EndPointKeys } from 'applications/editor/tools/routeEdition/types'; +import type { EditRoutePathState } from 'applications/editor/tools/routeEdition/types'; +import type { ExtendedEditorContextType } from 'applications/editor/tools/editorContextTypes'; + +import { useInfraID } from 'common/osrdContext'; -const WayPointInput: FC<{ +interface WayPointInputProps { endPoint: EndPoint; wayPoint: WayPoint | null; onChange: (newWayPoint: WayPoint & { position: Position }) => void; -}> = ({ endPoint, wayPoint, onChange }) => { +} +const WayPointInput = ({ endPoint, wayPoint, onChange }: WayPointInputProps) => { const dispatch = useDispatch(); const { state, setState } = useContext( EditorContext ) as ExtendedEditorContextType; const { t } = useTranslation(); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const [entityState, setEntityState] = useState< { type: 'data'; entity: WayPointEntity } | { type: 'loading' } | { type: 'empty' } >({ type: 'empty' }); diff --git a/front/src/applications/editor/tools/selection/components.tsx b/front/src/applications/editor/tools/selection/components.tsx index 773cb43e95c..e33fd680563 100644 --- a/front/src/applications/editor/tools/selection/components.tsx +++ b/front/src/applications/editor/tools/selection/components.tsx @@ -1,4 +1,4 @@ -import React, { FC, useContext } from 'react'; +import React, { useContext } from 'react'; import { Layer, Popup, Source } from 'react-map-gl/maplibre'; import { useSelector } from 'react-redux'; import { groupBy, map } from 'lodash'; @@ -6,17 +6,24 @@ import { GoNoEntry } from 'react-icons/go'; import { RiFocus3Line } from 'react-icons/ri'; import { useTranslation } from 'react-i18next'; -import { Zone } from 'types'; -import colors from 'common/Map/Consts/colors'; -import { getMap } from 'reducers/map/selectors'; +import type { Zone } from 'types'; + import { zoneToFeature } from 'utils/mapHelper'; + +import EditorContext from 'applications/editor/context'; +import 'applications/editor/tools/selection/styles.scss'; +import EntitySumUp from 'applications/editor/components/EntitySumUp'; +import type { SelectionState } from 'applications/editor/tools/selection/types'; +import type { + EditorContextType, + ExtendedEditorContextType, +} from 'applications/editor/tools/editorContextTypes'; + +import colors from 'common/Map/Consts/colors'; import GeoJSONs from 'common/Map/Layers/GeoJSONs'; -import { SelectionState } from './types'; -import EditorContext from '../../context'; -import EntitySumUp from '../../components/EntitySumUp'; +import { useInfraID } from 'common/osrdContext'; -import './styles.scss'; -import { EditorContextType, ExtendedEditorContextType } from '../editorContextTypes'; +import { getMap } from 'reducers/map/selectors'; export const SelectionMessages = () => { const { t, state } = useContext(EditorContext) as EditorContextType; @@ -24,14 +31,14 @@ export const SelectionMessages = () => { return t(`Editor.tools.select-items.help.${state.selectionState.type}-selection`).toString(); }; -const SelectionZone: FC<{ newZone?: Zone }> = ({ newZone }) => +const SelectionZone = ({ newZone }: { newZone?: Zone }) => newZone ? ( ) : null; -export const SelectionLayers: FC = () => { +export const SelectionLayers = () => { const { state, editorState: { editorLayers }, @@ -39,6 +46,8 @@ export const SelectionLayers: FC = () => { } = useContext(EditorContext) as ExtendedEditorContextType; const { mapStyle, layersSettings, issuesSettings } = useSelector(getMap); + const infraID = useInfraID(); + let selectionZone: Zone | undefined; if (state.mousePosition) { @@ -67,6 +76,7 @@ export const SelectionLayers: FC = () => { fingerprint={renderingFingerprint} layersSettings={layersSettings} issuesSettings={issuesSettings} + infraID={infraID} /> {state.mousePosition && state.selectionState.type === 'single' && state.hovered && ( @@ -94,7 +104,7 @@ export const SelectionLayers: FC = () => { ); }; -export const SelectionLeftPanel: FC = () => { +export const SelectionLeftPanel = () => { const { t } = useTranslation(); const { state, setState } = useContext( EditorContext diff --git a/front/src/applications/editor/tools/switchEdition/components.tsx b/front/src/applications/editor/tools/switchEdition/components.tsx index 4d22f86c9dc..4f3000d24aa 100644 --- a/front/src/applications/editor/tools/switchEdition/components.tsx +++ b/front/src/applications/editor/tools/switchEdition/components.tsx @@ -1,37 +1,40 @@ -import React, { FC, useContext, useEffect, useMemo, useRef, useState } from 'react'; +import React, { useContext, useEffect, useMemo, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; import Select from 'react-select'; -import { first, last, debounce } from 'lodash'; import { Layer, Popup, Source } from 'react-map-gl/maplibre'; -import { featureCollection, point } from '@turf/helpers'; import nearestPoint from '@turf/nearest-point'; -import { Position } from 'geojson'; +import { featureCollection, point } from '@turf/helpers'; +import { first, last, debounce } from 'lodash'; +import type { Position } from 'geojson'; + +import type { SwitchEntity, TrackSectionEntity } from 'types'; -import EditorForm from 'applications/editor//components/EditorForm'; -import EntitySumUp from 'applications/editor/components/EntitySumUp'; -import EntityError from 'applications/editor/components/EntityError'; import EditorContext from 'applications/editor/context'; import { getEntity } from 'applications/editor/data/api'; import { flattenEntity } from 'applications/editor/data/utils'; -import { ExtendedEditorContextType } from 'applications/editor/tools/editorContextTypes'; +import EditorForm from 'applications/editor//components/EditorForm'; +import EntitySumUp from 'applications/editor/components/EntitySumUp'; +import EntityError from 'applications/editor/components/EntityError'; +import useSwitch from 'applications/editor/tools/switchEdition/useSwitch'; +import { SwitchEditionState } from 'applications/editor/tools/switchEdition/types'; +import type { FlatSwitchEntity } from 'applications/editor/tools/switchEdition/utils'; +import type { ExtendedEditorContextType } from 'applications/editor/tools/editorContextTypes'; +import { flatSwitchToSwitch, getNewSwitch } from 'applications/editor/tools/switchEdition/utils'; +import { CustomSchemaField } from 'applications/editor/tools/switchEdition/components/CustomSchemaField'; + import colors from 'common/Map/Consts/colors'; import GeoJSONs from 'common/Map/Layers/GeoJSONs'; +import { useInfraID } from 'common/osrdContext'; import { getSwitchesLayerProps, getSwitchesNameLayerProps } from 'common/Map/Layers/Switches'; + import { save } from 'reducers/editor'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import { getMap } from 'reducers/map/selectors'; -import { SwitchEntity, TrackSectionEntity } from 'types'; - -import { FlatSwitchEntity, flatSwitchToSwitch, getNewSwitch } from './utils'; -import { SwitchEditionState } from './types'; -import useSwitch from './useSwitch'; -import { CustomSchemaField } from './components/CustomSchemaField'; -export const SwitchEditionLeftPanel: FC = () => { +export const SwitchEditionLeftPanel = () => { const dispatch = useDispatch(); const { t } = useTranslation(); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const { state, setState, isFormSubmited, setIsFormSubmited } = useContext( EditorContext ) as ExtendedEditorContextType; @@ -146,10 +149,10 @@ export const SwitchEditionLeftPanel: FC = () => { ); }; -export const SwitchEditionLayers: FC = () => { +export const SwitchEditionLayers = () => { const dispatch = useDispatch(); const { t } = useTranslation(); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const { renderingFingerprint, state, @@ -288,6 +291,7 @@ export const SwitchEditionLayers: FC = () => { fingerprint={renderingFingerprint} layersSettings={layersSettings} issuesSettings={issuesSettings} + infraID={infraID} /> {/* Edited switch */} @@ -335,7 +339,7 @@ export const SwitchEditionLayers: FC = () => { ); }; -export const SwitchMessages: FC = () => { +export const SwitchMessages = () => { const { t } = useTranslation(); const { state: { portEditionState }, diff --git a/front/src/applications/editor/tools/switchEdition/components/TrackSectionEndpointSelector.tsx b/front/src/applications/editor/tools/switchEdition/components/TrackSectionEndpointSelector.tsx index fde2964d1d3..72cfffaf64d 100644 --- a/front/src/applications/editor/tools/switchEdition/components/TrackSectionEndpointSelector.tsx +++ b/front/src/applications/editor/tools/switchEdition/components/TrackSectionEndpointSelector.tsx @@ -1,29 +1,36 @@ -import React, { FC, useCallback, useContext, useEffect, useState } from 'react'; -import { keyBy } from 'lodash'; +import React, { useCallback, useContext, useEffect, useState } from 'react'; +import { useDispatch } from 'react-redux'; import Select from 'react-select'; -import { FieldProps } from '@rjsf/core'; import { useTranslation } from 'react-i18next'; -import { useDispatch, useSelector } from 'react-redux'; import { FaMapMarkedAlt, FaTimesCircle } from 'react-icons/fa'; +import type { FieldProps } from '@rjsf/core'; +import { keyBy } from 'lodash'; + import EditorContext from 'applications/editor/context'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import { getEntity } from 'applications/editor/data/api'; import Tipped from 'applications/editor/components/Tipped'; -import { DEFAULT_ENDPOINT, ENDPOINTS, ENDPOINTS_SET, TrackSectionEntity } from 'types'; -import { FLAT_SWITCH_PORTS_PREFIX } from '../utils'; -import { PortEndPointCandidate, SwitchEditionState } from '../types'; -import { ExtendedEditorContextType } from '../../editorContextTypes'; +import { FLAT_SWITCH_PORTS_PREFIX } from 'applications/editor/tools/switchEdition/utils'; +import type { ExtendedEditorContextType } from 'applications/editor/tools/editorContextTypes'; + +import type { TrackSectionEntity } from 'types'; +import { DEFAULT_ENDPOINT, ENDPOINTS, ENDPOINTS_SET } from 'types'; +import type { + PortEndPointCandidate, + SwitchEditionState, +} from 'applications/editor/tools/switchEdition/types'; + +import { useInfraID } from 'common/osrdContext'; const ENDPOINT_OPTIONS = ENDPOINTS.map((s) => ({ value: s, label: s })); const ENDPOINT_OPTIONS_DICT = keyBy(ENDPOINT_OPTIONS, 'value'); -const TrackSectionEndpointSelector: FC = ({ schema, formData, onChange, name }) => { +const TrackSectionEndpointSelector = ({ schema, formData, onChange, name }: FieldProps) => { const dispatch = useDispatch(); const { state, setState } = useContext( EditorContext ) as ExtendedEditorContextType; const { t } = useTranslation(); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const portId = name.replace(FLAT_SWITCH_PORTS_PREFIX, ''); const endpoint = ENDPOINTS_SET.has(formData?.endpoint) ? formData.endpoint : DEFAULT_ENDPOINT; diff --git a/front/src/applications/editor/tools/switchEdition/useSwitch.ts b/front/src/applications/editor/tools/switchEdition/useSwitch.ts index 59071291ddf..9d166427850 100644 --- a/front/src/applications/editor/tools/switchEdition/useSwitch.ts +++ b/front/src/applications/editor/tools/switchEdition/useSwitch.ts @@ -1,13 +1,19 @@ import { useContext, useMemo } from 'react'; -import { useSelector } from 'react-redux'; import { first, keyBy } from 'lodash'; -import { SwitchEntity } from 'types'; + +import type { SwitchEntity } from 'types'; + import EditorContext from 'applications/editor/context'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import { NEW_ENTITY_ID } from 'applications/editor/data/utils'; -import { SwitchEditionState, useSwitchTypes } from './types'; -import { ExtendedEditorContextType } from '../editorContextTypes'; -import { getSwitchTypeJSONSchema, switchToFlatSwitch } from './utils'; +import { useSwitchTypes } from 'applications/editor/tools/switchEdition/types'; +import type { SwitchEditionState } from 'applications/editor/tools/switchEdition/types'; +import type { ExtendedEditorContextType } from 'applications/editor/tools/editorContextTypes'; +import { + getSwitchTypeJSONSchema, + switchToFlatSwitch, +} from 'applications/editor/tools/switchEdition/utils'; + +import { useInfraID } from 'common/osrdContext'; // TODO : Rename all switch by tracknode when back renaming PR merged const useSwitch = () => { @@ -19,8 +25,8 @@ const useSwitch = () => { const baseSchema = editorState.editorSchema.find((e) => e.objType === 'Switch')?.schema; // Retrieve proper data - const infraId = useSelector(getInfraID); - const switchTypes = useSwitchTypes(infraId); + const infraID = useInfraID(); + const switchTypes = useSwitchTypes(infraID); const switchTypesDict = useMemo(() => keyBy(switchTypes, 'id'), [switchTypes]); const switchTypeOptions = useMemo( diff --git a/front/src/applications/editor/tools/trackEdition/components.tsx b/front/src/applications/editor/tools/trackEdition/components.tsx index 98ce58a48aa..39fe26eeb12 100644 --- a/front/src/applications/editor/tools/trackEdition/components.tsx +++ b/front/src/applications/editor/tools/trackEdition/components.tsx @@ -1,35 +1,38 @@ -import React, { FC, useContext, useEffect, useRef, useState } from 'react'; +import React, { useContext, useEffect, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Layer, Source } from 'react-map-gl/maplibre'; import { useTranslation } from 'react-i18next'; -import { last } from 'lodash'; -import { Position } from 'geojson'; import { BsBoxArrowInRight } from 'react-icons/bs'; +import { last } from 'lodash'; +import type { Position } from 'geojson'; + +import type { CatenaryEntity, SpeedSectionEntity, TrackSectionEntity } from 'types'; +import EditorContext from 'applications/editor/context'; +import { getEntities } from 'applications/editor/data/api'; +import TOOL_TYPES from 'applications/editor/tools/toolTypes'; +import { NEW_ENTITY_ID } from 'applications/editor/data/utils'; import EditorForm from 'applications/editor/components/EditorForm'; import EntitySumUp from 'applications/editor/components/EntitySumUp'; import EntityError from 'applications/editor/components/EntityError'; -import { getEntities } from 'applications/editor/data/api'; -import { NEW_ENTITY_ID } from 'applications/editor/data/utils'; -import EditorContext from 'applications/editor/context'; +import { injectGeometry, removeInvalidRanges } from 'applications/editor/tools/trackEdition/utils'; +import type { TrackEditionState } from 'applications/editor/tools/trackEdition/types'; +import type { ExtendedEditorContextType } from 'applications/editor/tools/editorContextTypes'; import { getEditCatenaryState, getEditSpeedSectionState, } from 'applications/editor/tools/rangeEdition/utils'; -import TOOL_TYPES from 'applications/editor/tools/toolTypes'; -import { ExtendedEditorContextType } from 'applications/editor/tools/editorContextTypes'; -import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; + import { Spinner } from 'common/Loader'; -import GeoJSONs from 'common/Map/Layers/GeoJSONs'; import colors from 'common/Map/Consts/colors'; +import GeoJSONs from 'common/Map/Layers/GeoJSONs'; +import { useInfraID } from 'common/osrdContext'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; + import { save } from 'reducers/editor'; import { getMap } from 'reducers/map/selectors'; -import { getInfraID } from 'reducers/osrdconf/selectors'; -import { CatenaryEntity, SpeedSectionEntity, TrackSectionEntity } from 'types'; import DebouncedNumberInputSNCF from 'common/BootstrapSNCF/FormSNCF/DebouncedNumberInputSNCF'; import { WidgetProps } from '@rjsf/core'; -import { TrackEditionState } from './types'; -import { injectGeometry, removeInvalidRanges } from './utils'; export const TRACK_LAYER_ID = 'trackEditionTool/new-track-path'; export const POINTS_LAYER_ID = 'trackEditionTool/new-track-points'; @@ -38,16 +41,19 @@ const TRACK_COLOR = '#666'; const TRACK_STYLE = { 'line-color': TRACK_COLOR, 'line-dasharray': [2, 1], 'line-width': 2 }; const DEFAULT_DISPLAYED_RANGES_COUNT = 3; +interface AttachedRangesItemsListProps { + id: string; + itemType: 'SpeedSection' | 'Catenary'; +} + /** * Generic component to show attached ranges items of a specific type for an edited track section: */ -export const AttachedRangesItemsList: FC<{ id: string; itemType: 'SpeedSection' | 'Catenary' }> = ({ - id, - itemType, -}) => { + +export const AttachedRangesItemsList = ({ id, itemType }: AttachedRangesItemsListProps) => { const dispatch = useDispatch(); const { t } = useTranslation(); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const [itemsState, setItemsState] = useState< | { type: 'idle' } | { type: 'loading' } @@ -185,7 +191,7 @@ export const AttachedRangesItemsList: FC<{ id: string; itemType: 'SpeedSection' ); }; -export const TrackEditionLayers: FC = () => { +export const TrackEditionLayers = () => { const { state, renderingFingerprint, @@ -193,6 +199,8 @@ export const TrackEditionLayers: FC = () => { } = useContext(EditorContext) as ExtendedEditorContextType; const { mapStyle, layersSettings, issuesSettings } = useSelector(getMap); + const infraID = useInfraID(); + const isAddingPointOnExistingSection = typeof state.nearestPoint?.properties?.sectionIndex === 'number'; const points = state.track.geometry.coordinates; @@ -240,6 +248,7 @@ export const TrackEditionLayers: FC = () => { fingerprint={renderingFingerprint} layersSettings={layersSettings} issuesSettings={issuesSettings} + infraID={infraID} /> {/* Track path */} @@ -355,10 +364,10 @@ export const CustomLengthInput: React.FC = (props) => { ); }; -export const TrackEditionLeftPanel: FC = () => { +export const TrackEditionLeftPanel: React.FC = () => { const dispatch = useDispatch(); const { t } = useTranslation(); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const { state, setState, isFormSubmited, setIsFormSubmited } = useContext( EditorContext ) as ExtendedEditorContextType; @@ -461,7 +470,7 @@ export const TrackEditionLeftPanel: FC = () => { ); }; -export const TrackEditionMessages: FC = () => { +export const TrackEditionMessages = () => { const { t, state } = useContext(EditorContext) as ExtendedEditorContextType; switch (state.editionState.type) { diff --git a/front/src/applications/editor/tools/types.ts b/front/src/applications/editor/tools/types.ts index 0522d09d9e0..869b4ae7f5e 100644 --- a/front/src/applications/editor/tools/types.ts +++ b/front/src/applications/editor/tools/types.ts @@ -1,9 +1,12 @@ import { flatMap } from 'lodash'; -import { EditorSchema } from '../../../types'; -import { InfraErrorLevel, InfraErrorType } from '../components/InfraErrors/types'; +import { EditorSchema } from 'types'; -export interface EditorState { +import { InfraErrorLevel, InfraErrorType } from 'applications/editor/components/InfraErrors/types'; + +import { InfraState } from 'reducers/infra'; + +export interface EditorState extends InfraState { editorSchema: EditorSchema; editorLayers: Set; issues: { diff --git a/front/src/applications/editor/tools/utils.ts b/front/src/applications/editor/tools/utils.ts index e955b85c918..959380233e8 100644 --- a/front/src/applications/editor/tools/utils.ts +++ b/front/src/applications/editor/tools/utils.ts @@ -1,13 +1,13 @@ -import { MapLayerMouseEvent } from 'maplibre-gl'; -import { Feature, LineString, Point } from 'geojson'; +import type { MapLayerMouseEvent } from 'maplibre-gl'; +import type { Dispatch } from 'redux'; +import turfBbox from '@turf/bbox'; import length from '@turf/length'; import lineSlice from '@turf/line-slice'; -import { NearestPoint } from '@turf/nearest-point'; -import turfBbox from '@turf/bbox'; import { featureCollection } from '@turf/helpers'; -import { Dispatch } from 'redux'; +import type { NearestPoint } from '@turf/nearest-point'; +import type { Feature, LineString, Point } from 'geojson'; -import { +import type { Bbox, BufferStopEntity, CatenaryEntity, @@ -19,12 +19,15 @@ import { SwitchEntity, TrackSectionEntity, } from 'types'; -import { selectLayers } from 'reducers/editor'; -import { TrackState } from './rangeEdition/types'; -import TOOL_TYPES from './toolTypes'; -import { EditorContextType } from './editorContextTypes'; -import { EDITOAST_TO_LAYER_DICT, EditoastType, EditorState } from './types'; -import { getEntity } from '../data/api'; + +import { getEntity } from 'applications/editor/data/api'; +import TOOL_TYPES from 'applications/editor/tools/toolTypes'; +import { EDITOAST_TO_LAYER_DICT } from 'applications/editor/tools/types'; +import type { TrackState } from 'applications/editor/tools/rangeEdition/types'; +import type { EditoastType, EditorState } from 'applications/editor/tools/types'; +import type { EditorContextType } from 'applications/editor/tools/editorContextTypes'; + +import { editorSliceActions } from 'reducers/editor'; /** * Since Turf and Editoast do not compute the lengths the same way (see #1751) @@ -106,7 +109,7 @@ export function selectEntity( }); // dispatch the new layers - if (actualLayers.size !== nextLayers.size) dispatch(selectLayers(nextLayers)); + if (actualLayers.size !== nextLayers.size) dispatch(editorSliceActions.selectLayers(nextLayers)); } /** diff --git a/front/src/applications/operationalStudies/consts.ts b/front/src/applications/operationalStudies/consts.ts index 0380885c67d..9dea013183d 100644 --- a/front/src/applications/operationalStudies/consts.ts +++ b/front/src/applications/operationalStudies/consts.ts @@ -1,6 +1,4 @@ import i18n from 'i18n'; -import { SwitchType } from 'types'; -import { ObjectFieldsTypes } from 'utils/types'; import { Position, Feature } from 'geojson'; import { AllowanceValue, @@ -13,6 +11,7 @@ import { import { LinearMetadataItem } from 'common/IntervalsDataViz/types'; import { HeightPosition } from 'reducers/osrdsimulation/types'; import { AllowanceForm } from 'modules/trainschedule/components/ManageTrainSchedule/Allowances/types'; +import { InfraState } from 'reducers/infra'; export const BLOCKTYPES = [ { @@ -88,6 +87,8 @@ interface MODES_Types { export const MODES: MODES_Types = Object.freeze({ simulation: 'SIMULATION', stdcm: 'STDCM', + editor: 'EDITOR', + mapViewer: 'MAP_VIEWER', }); export const DEFAULT_MODE = MODES.simulation; @@ -149,7 +150,7 @@ export const studyTypes = Object.keys(STUDY_TYPES) as StudyType[]; export type PowerRestrictionRange = LinearMetadataItem<{ value: string }>; -export interface OsrdConfState { +export interface OsrdConfState extends InfraState { rollingStockComfort: RollingStockComfortType; name: string; trainCount: number; @@ -161,8 +162,6 @@ export interface OsrdConfState { projectID?: number; studyID?: number; scenarioID?: number; - infraID?: number; - switchTypes?: SwitchType[]; pathfindingID?: number; timetableID?: number; rollingStockID?: number; @@ -175,7 +174,6 @@ export interface OsrdConfState { destination?: PointOnMap; vias: PointOnMap[]; suggeredVias: PathResponse['steps'] | PointOnMap[]; - trainCompo: undefined; geojson?: PathResponse; originDate?: string; originTime?: string; @@ -184,21 +182,15 @@ export interface OsrdConfState { originLinkedBounds: boolean; destinationDate?: string; destinationTime?: string; - featureInfoClick: { displayPopup: boolean; feature?: Feature; coordinates?: number[] }; gridMarginBefore?: number; gridMarginAfter?: number; trainScheduleIDsToModify: number[]; + featureInfoClick: { displayPopup: boolean; feature?: Feature; coordinates?: number[] }; } export interface OsrdStdcmConfState extends OsrdConfState { maximumRunTime: number; - standardStdcmAllowance?: StandardAllowance; // We wait for auto generated types -} - -export interface OsrdMultiConfState { - mode: ObjectFieldsTypes; - simulationConf: OsrdConfState; - stdcmConf: OsrdStdcmConfState; + standardStdcmAllowance?: StandardAllowance; } export const RUNTIME_CAP = 43200; diff --git a/front/src/applications/operationalStudies/views/ManageTrainSchedule.tsx b/front/src/applications/operationalStudies/views/ManageTrainSchedule.tsx index dcedc727cbb..fbde1437c90 100644 --- a/front/src/applications/operationalStudies/views/ManageTrainSchedule.tsx +++ b/front/src/applications/operationalStudies/views/ManageTrainSchedule.tsx @@ -2,40 +2,47 @@ import React, { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; -import TrainSettings from 'modules/trainschedule/components/ManageTrainSchedule/TrainSettings'; -import Itinerary from 'modules/trainschedule/components/ManageTrainSchedule/Itinerary/Itinerary'; -import Map from 'modules/trainschedule/components/ManageTrainSchedule/Map'; -import SpeedLimitByTagSelector from 'common/SpeedLimitByTagSelector/SpeedLimitByTagSelector'; -import PowerRestrictionsSelector from 'modules/trainschedule/components/ManageTrainSchedule/PowerRestrictionsSelector'; -import adjustConfWithTrainToModify from 'modules/trainschedule/components/ManageTrainSchedule/helpers/adjustConfWithTrainToModify'; -import ElectricalProfiles from 'modules/trainschedule/components/ManageTrainSchedule/ElectricalProfiles'; -import Allowances from 'modules/trainschedule/components/ManageTrainSchedule/Allowances/Allowances'; -import { - getPathfindingID, - getRollingStockID, - getTrainScheduleIDsToModify, -} from 'reducers/osrdconf/selectors'; -import { osrdEditoastApi, RangedValue } from 'common/api/osrdEditoastApi'; -import { RollingStockSelector } from 'modules/rollingStock/components/RollingStockSelector'; -import Tabs from 'common/Tabs'; import rollingStockPic from 'assets/pictures/components/train.svg'; import pahtFindingPic from 'assets/pictures/components/pathfinding.svg'; import allowancesPic from 'assets/pictures/components/allowances.svg'; import simulationSettings from 'assets/pictures/components/simulationSettings.svg'; -import RollingStock2Img from 'modules/rollingStock/components/RollingStock2Img'; -import { isElectric } from 'modules/rollingStock/helpers/electric'; + import { formatKmValue } from 'utils/strings'; +import { isElectric } from 'modules/rollingStock/helpers/electric'; +import RollingStock2Img from 'modules/rollingStock/components/RollingStock2Img'; +import { Itinerary, Map } from 'modules/trainschedule/components/ManageTrainSchedule'; +import { RollingStockSelector } from 'modules/rollingStock/components/RollingStockSelector'; +import TrainSettings from 'modules/trainschedule/components/ManageTrainSchedule/TrainSettings'; +import Allowances from 'modules/trainschedule/components/ManageTrainSchedule/Allowances/Allowances'; +import ElectricalProfiles from 'modules/trainschedule/components/ManageTrainSchedule/ElectricalProfiles'; +import PowerRestrictionsSelector from 'modules/trainschedule/components/ManageTrainSchedule/PowerRestrictionsSelector'; +import adjustConfWithTrainToModify from 'modules/trainschedule/components/ManageTrainSchedule/helpers/adjustConfWithTrainToModify'; + +import Tabs from 'common/Tabs'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import type { RangedValue } from 'common/api/osrdEditoastApi'; +import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; +import SpeedLimitByTagSelector from 'common/SpeedLimitByTagSelector/SpeedLimitByTagSelector'; + export default function ManageTrainSchedule() { const dispatch = useDispatch(); const { t } = useTranslation(['operationalStudies/manageTrainSchedule']); + const { + getRollingStockID, + getPathfindingID, + getTrainScheduleIDsToModify, + getUsingElectricalProfiles, + } = useOsrdConfSelectors(); const rollingStockID = useSelector(getRollingStockID); const pathFindingID = useSelector(getPathfindingID); const trainScheduleIDsToModify = useSelector(getTrainScheduleIDsToModify); + const usingElectricalProfiles = useSelector(getUsingElectricalProfiles); const [getTrainScheduleById] = osrdEditoastApi.endpoints.getTrainScheduleById.useLazyQuery({}); const [getPathfindingById] = osrdEditoastApi.endpoints.getPathfindingByPathfindingId.useLazyQuery( {} ); + const osrdActions = useOsrdConfActions(); // Details for tabs const { data: pathFinding } = osrdEditoastApi.useGetPathfindingByPathfindingIdQuery( @@ -159,7 +166,13 @@ export default function ManageTrainSchedule() { getPathfindingById({ pathfindingId: trainSchedule.path_id }) .unwrap() .then((path) => { - adjustConfWithTrainToModify(trainSchedule, path, dispatch); + adjustConfWithTrainToModify( + trainSchedule, + path, + dispatch, + usingElectricalProfiles, + osrdActions + ); }); } }); diff --git a/front/src/applications/operationalStudies/views/Scenario.tsx b/front/src/applications/operationalStudies/views/Scenario.tsx index e72cccecf78..d6ef2bd30b4 100644 --- a/front/src/applications/operationalStudies/views/Scenario.tsx +++ b/front/src/applications/operationalStudies/views/Scenario.tsx @@ -1,36 +1,40 @@ import React, { useEffect, useMemo, useState } from 'react'; -import NavBarSNCF from 'common/BootstrapSNCF/NavBarSNCF'; +import { useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; -import Timetable from 'modules/trainschedule/components/Timetable/Timetable'; -import infraLogo from 'assets/pictures/components/tracks.svg'; import { useSelector, useDispatch } from 'react-redux'; -import { MODES, MANAGE_TRAIN_SCHEDULE_TYPES } from 'applications/operationalStudies/consts'; -import { updateInfraID, updateMode, updateTimetableID } from 'reducers/osrdconf'; -import TimetableManageTrainSchedule from 'modules/trainschedule/components/Timetable/TimetableManageTrainSchedule'; -import BreadCrumbs from 'applications/operationalStudies/components/BreadCrumbs'; -import { getInfraID, getTimetableID } from 'reducers/osrdconf/selectors'; -import { useModal } from 'common/BootstrapSNCF/ModalSNCF'; import { GoPencil } from 'react-icons/go'; -import { FaEye, FaEyeSlash } from 'react-icons/fa'; import { GiElectric } from 'react-icons/gi'; -import { useParams } from 'react-router-dom'; +import { FaEye, FaEyeSlash } from 'react-icons/fa'; + +import infraLogo from 'assets/pictures/components/tracks.svg'; + +import BreadCrumbs from 'applications/operationalStudies/components/BreadCrumbs'; +import { MANAGE_TRAIN_SCHEDULE_TYPES } from 'applications/operationalStudies/consts'; +import SimulationResults from 'applications/operationalStudies/views/SimulationResults'; +import ImportTrainSchedule from 'applications/operationalStudies/views/ImportTrainSchedule'; +import ManageTrainSchedule from 'applications/operationalStudies/views/ManageTrainSchedule'; +import InfraLoadingState from 'applications/operationalStudies/components/Scenario/InfraLoadingState'; +import getSimulationResults, { + selectProjection, +} from 'applications/operationalStudies/components/Scenario/getSimulationResults'; + +import NavBarSNCF from 'common/BootstrapSNCF/NavBarSNCF'; +import { useModal } from 'common/BootstrapSNCF/ModalSNCF'; import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; -import AddAndEditScenarioModal from 'modules/scenario/components/AddOrEditScenarioModal'; +import { useInfraID, useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; + +import Timetable from 'modules/trainschedule/components/Timetable/Timetable'; import ScenarioLoaderMessage from 'modules/scenario/components/ScenarioLoaderMessage'; -import { RootState } from 'reducers'; +import AddAndEditScenarioModal from 'modules/scenario/components/AddOrEditScenarioModal'; +import TimetableManageTrainSchedule from 'modules/trainschedule/components/Timetable/TimetableManageTrainSchedule'; + +import type { RootState } from 'reducers'; import { updateSelectedProjection, updateSimulation } from 'reducers/osrdsimulation/actions'; import { getAllowancesSettings, getSelectedProjection, getSelectedTrainId, } from 'reducers/osrdsimulation/selectors'; -import ImportTrainSchedule from './ImportTrainSchedule'; -import ManageTrainSchedule from './ManageTrainSchedule'; -import SimulationResults from './SimulationResults'; -import InfraLoadingState from '../components/Scenario/InfraLoadingState'; -import getSimulationResults, { - selectProjection, -} from '../components/Scenario/getSimulationResults'; type SimulationParams = { projectId: string; @@ -57,7 +61,9 @@ export default function Scenario() { studyId: urlStudyId, scenarioId: urlScenarioId, } = useParams() as SimulationParams; - const infraId = useSelector(getInfraID); + + const { getTimetableID } = useOsrdConfSelectors(); + const infraId = useInfraID(); const timetableId = useSelector(getTimetableID); const selectedTrainId = useSelector(getSelectedTrainId); const selectedProjection = useSelector(getSelectedProjection); @@ -91,6 +97,8 @@ export default function Scenario() { if (isScenarioError && errorScenario) throw errorScenario; }, [isScenarioError, errorScenario]); + const { updateInfraID, updateTimetableID } = useOsrdConfActions(); + useEffect(() => { if (scenario) { dispatch(updateTimetableID(scenario.timetable_id)); @@ -172,8 +180,6 @@ export default function Scenario() { useEffect(() => { if (!projectId || !studyId || !scenarioId) { throw new Error('Missing projectId, studyId or scenarioId'); - } else { - dispatch(updateMode(MODES.simulation)); } }, [projectId, studyId, scenarioId]); diff --git a/front/src/applications/referenceMap/Home.tsx b/front/src/applications/referenceMap/Home.tsx index 4116d370b3b..5a0e7e7a570 100644 --- a/front/src/applications/referenceMap/Home.tsx +++ b/front/src/applications/referenceMap/Home.tsx @@ -1,18 +1,18 @@ -import React, { FC, useEffect } from 'react'; +import React, { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { Route, Routes } from 'react-router-dom'; -import { useSelector } from 'react-redux'; import { GoLock } from 'react-icons/go'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import NavBarSNCF from 'common/BootstrapSNCF/NavBarSNCF'; import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; import { ModalProvider } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; +import { useInfraID } from 'common/osrdContext'; import Map from './Map'; -const HomeReferenceMap: FC = () => { +const HomeReferenceMap = () => { const { t } = useTranslation(['home/home', 'referenceMap']); - const infraID = useSelector(getInfraID); + + const infraID = useInfraID(); const [getInfraById, { data: infra }] = osrdEditoastApi.endpoints.getInfraById.useLazyQuery({}); /** diff --git a/front/src/applications/referenceMap/Map.tsx b/front/src/applications/referenceMap/Map.tsx index 46eb7b80ad3..cbaab4668a9 100644 --- a/front/src/applications/referenceMap/Map.tsx +++ b/front/src/applications/referenceMap/Map.tsx @@ -6,11 +6,10 @@ import { useDispatch, useSelector } from 'react-redux'; import { useParams } from 'react-router-dom'; import type { MapRef } from 'react-map-gl/maplibre'; -import type { RootState } from 'reducers'; import type { Viewport } from 'reducers/map'; -import { getTerrain3DExaggeration } from 'reducers/map/selectors'; import { LAYER_GROUPS_ORDER, LAYERS } from 'config/layerOrder'; +import { getMap, getTerrain3DExaggeration } from 'reducers/map/selectors'; /* Main data & layers */ import Background from 'common/Map/Layers/Background'; @@ -44,14 +43,14 @@ import { CUSTOM_ATTRIBUTION } from 'common/Map/const'; import { useMapBlankStyle } from 'common/Map/Layers/blankStyle'; import 'common/Map/Map.scss'; +import { useInfraID } from 'common/osrdContext'; function Map() { const mapBlankStyle = useMapBlankStyle(); - const { viewport, mapSearchMarker, mapStyle, showOSM, layersSettings } = useSelector( - (state: RootState) => state.map - ); const [mapLoaded, setMapLoaded] = useState(false); + const { viewport, mapSearchMarker, mapStyle, showOSM, layersSettings } = useSelector(getMap); + const infraID = useInfraID(); const terrain3DExaggeration = useSelector(getTerrain3DExaggeration); const mapRef = useRef(null); const { urlLat, urlLon, urlZoom, urlBearing, urlPitch } = useParams(); @@ -175,50 +174,70 @@ function Map() { + - + + - + - {mapSearchMarker && } diff --git a/front/src/applications/stdcm/components/RunningTime.tsx b/front/src/applications/stdcm/components/RunningTime.tsx index 151120a6720..2e2de9d95fe 100644 --- a/front/src/applications/stdcm/components/RunningTime.tsx +++ b/front/src/applications/stdcm/components/RunningTime.tsx @@ -1,14 +1,20 @@ -import React, { ComponentType, useState } from 'react'; +import React, { useState } from 'react'; +import type { ComponentType } from 'react'; +import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; -import { updateMaximumRunTime } from 'reducers/osrdconf'; -import InputSNCF from 'common/BootstrapSNCF/InputSNCF'; -import { Dispatch } from 'redux'; -import { noop } from 'lodash'; import { RxLapTimer } from 'react-icons/rx'; -import { useTranslation } from 'react-i18next'; +import type { Dispatch } from 'redux'; +import { noop } from 'lodash'; + import { sec2time, time2sec } from 'utils/timeManipulation'; + import { RUNTIME_CAP } from 'applications/operationalStudies/consts'; -import { getMaximumRunTime } from 'reducers/osrdconf/selectors'; + +import InputSNCF from 'common/BootstrapSNCF/InputSNCF'; +import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; + +import type { StdcmConfSliceActions } from 'reducers/osrdconf/stdcmConf'; +import type { StdcmConfSelectors } from 'reducers/osrdconf/stdcmConf/selectors'; interface RunningTimeProps { dispatch?: Dispatch; @@ -23,6 +29,8 @@ export function withProps(Component: ComponentType) { function RunningTime({ dispatch = noop }: RunningTimeProps) { const { t } = useTranslation(['operationalStudies/manageTrainSchedule']); + const { getMaximumRunTime } = useOsrdConfSelectors() as StdcmConfSelectors; + const { updateMaximumRunTime } = useOsrdConfActions() as StdcmConfSliceActions; const maximumRunTime = useSelector(getMaximumRunTime); const [isRtBelowCap, setIsRtBelowCap] = useState(true); diff --git a/front/src/applications/stdcm/formatStcmConf.ts b/front/src/applications/stdcm/formatStcmConf.ts index 3db3d96da82..acf55258513 100644 --- a/front/src/applications/stdcm/formatStcmConf.ts +++ b/front/src/applications/stdcm/formatStcmConf.ts @@ -1,18 +1,22 @@ import { Dispatch } from 'redux'; import { TFunction } from 'i18next'; -import { PathfindingRequest, PostStdcmApiArg } from 'common/api/osrdEditoastApi'; +import { PathfindingRequest } from 'common/api/osrdEditoastApi'; -import { createAllowanceValue } from 'applications/stdcm/components/allowancesConsts'; -import { OsrdStdcmConfState } from 'applications/operationalStudies/consts'; import { time2sec } from 'utils/timeManipulation'; -import { setFailure } from 'reducers/main'; +import { createAllowanceValue } from 'applications/stdcm/components/allowancesConsts'; +import type { OsrdStdcmConfState } from 'applications/operationalStudies/consts'; + import { getPathfindingQuery } from 'common/Pathfinding/Pathfinding'; +import type { PostStdcmApiArg } from 'common/api/osrdEditoastApi'; + +import { setFailure } from 'reducers/main'; +import type { InfraState } from 'reducers/infra'; export default function formatStdcmConf( dispatch: Dispatch, t: TFunction, - osrdconf: OsrdStdcmConfState + osrdconf: OsrdStdcmConfState & InfraState ): PostStdcmApiArg | undefined { let error = false; if (!osrdconf.origin) { diff --git a/front/src/applications/stdcm/views/OSRDSTDCM.tsx b/front/src/applications/stdcm/views/OSRDSTDCM.tsx index f9f533475e4..56b4edc2020 100644 --- a/front/src/applications/stdcm/views/OSRDSTDCM.tsx +++ b/front/src/applications/stdcm/views/OSRDSTDCM.tsx @@ -1,27 +1,21 @@ import React, { useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { getMode } from 'reducers/osrdconf/selectors'; -import { updateSelectedTrainId, updateSelectedProjection } from 'reducers/osrdsimulation/actions'; -import { MODES } from 'applications/operationalStudies/consts'; +import { useDispatch } from 'react-redux'; + import STDCM_REQUEST_STATUS from 'applications/stdcm/consts'; -import { StdcmRequestStatus } from 'applications/stdcm/types'; -import { updateMode } from 'reducers/osrdconf'; -import OSRDStdcmConfig from './OSRDStdcmConfig'; -import StdcmRequestModal from './StdcmRequestModal'; +import type { StdcmRequestStatus } from 'applications/stdcm/types'; +import OSRDStdcmConfig from 'applications/stdcm/views/OSRDStdcmConfig'; +import StdcmRequestModal from 'applications/stdcm/views/StdcmRequestModal'; + +import { updateSelectedTrainId, updateSelectedProjection } from 'reducers/osrdsimulation/actions'; export default function OSRDSTDCM() { const dispatch = useDispatch(); - const mode = useSelector(getMode); const [currentStdcmRequestStatus, setCurrentStdcmRequestStatus] = useState( STDCM_REQUEST_STATUS.idle ); useEffect(() => { - if (mode !== MODES.stdcm) dispatch(updateMode(MODES.stdcm)); - return () => { - dispatch(updateMode(MODES.simulation)); - dispatch(updateSelectedTrainId(undefined)); - dispatch(updateSelectedProjection(undefined)); - }; + dispatch(updateSelectedTrainId(undefined)); + dispatch(updateSelectedProjection(undefined)); }, []); return ( diff --git a/front/src/applications/stdcm/views/OSRDStdcmConfig.tsx b/front/src/applications/stdcm/views/OSRDStdcmConfig.tsx index 77b0cee379f..c0f2cfab8f9 100644 --- a/front/src/applications/stdcm/views/OSRDStdcmConfig.tsx +++ b/front/src/applications/stdcm/views/OSRDStdcmConfig.tsx @@ -2,26 +2,23 @@ import React, { useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useSelector } from 'react-redux'; -import { Itinerary, Map } from 'modules/trainschedule/components/ManageTrainSchedule'; -import { StdcmRequestStatus } from 'applications/stdcm/types'; import STDCM_REQUEST_STATUS from 'applications/stdcm/consts'; +import type { StdcmRequestStatus } from 'applications/stdcm/types'; +import RunningTime from 'applications/stdcm/components/RunningTime'; +import OSRDStdcmResults from 'applications/stdcm/views/OSRDStdcmResults'; +import type { OsrdStdcmConfState } from 'applications/operationalStudies/consts'; + +import StdcmAllowances from 'modules/stdcmAllowances/components/StdcmAllowances'; +import { Itinerary, Map } from 'modules/trainschedule/components/ManageTrainSchedule'; +import { RollingStockSelector } from 'modules/rollingStock/components/RollingStockSelector'; + +import { useInfraID, useOsrdSelectors } from 'common/osrdContext'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; import ScenarioExplorer from 'common/ScenarioExplorer/ScenarioExplorer'; import SpeedLimitByTagSelector from 'common/SpeedLimitByTagSelector/SpeedLimitByTagSelector'; -import { - getConf, - getInfraID, - getProjectID, - getScenarioID, - getStudyID, - getTimetableID, -} from 'reducers/osrdconf/selectors'; + import { getSelectedTrain } from 'reducers/osrdsimulation/selectors'; -import { RollingStockSelector } from 'modules/rollingStock/components/RollingStockSelector'; -import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; -import StdcmAllowances from 'modules/stdcmAllowances/components/StdcmAllowances'; -import { OsrdStdcmConfState } from 'applications/operationalStudies/consts'; -import OSRDStdcmResults from './OSRDStdcmResults'; -import RunningTime from '../components/RunningTime'; +import type { StdcmConfSelectors } from 'reducers/osrdconf/stdcmConf/selectors'; type OSRDStdcmConfigProps = { currentStdcmRequestStatus: string; @@ -32,14 +29,17 @@ export default function OSRDConfig({ currentStdcmRequestStatus, setCurrentStdcmRequestStatus, }: OSRDStdcmConfigProps) { + const { getConf, getProjectID, getScenarioID, getStudyID, getTimetableID } = + useOsrdSelectors() as StdcmConfSelectors; const projectID = useSelector(getProjectID); const studyID = useSelector(getStudyID); const scenarioID = useSelector(getScenarioID); const timetableID = useSelector(getTimetableID); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const selectedTrain = useSelector(getSelectedTrain); const [showMap, setShowMap] = useState(true); const [isInfraLoaded, setIsInfraLoaded] = useState(false); + const osrdconf: OsrdStdcmConfState = useSelector(getConf) as OsrdStdcmConfState; const { t } = useTranslation([ diff --git a/front/src/applications/stdcm/views/StdcmRequestModal.tsx b/front/src/applications/stdcm/views/StdcmRequestModal.tsx index 6b9eb653fac..ba3ba095dc7 100644 --- a/front/src/applications/stdcm/views/StdcmRequestModal.tsx +++ b/front/src/applications/stdcm/views/StdcmRequestModal.tsx @@ -10,7 +10,6 @@ import { import { useDispatch, useSelector } from 'react-redux'; import { CHART_AXES } from 'modules/simulationResult/components/simulationResultsConsts'; -import { getConf } from 'reducers/osrdconf/selectors'; // Generic components import ModalBodySNCF from 'common/BootstrapSNCF/ModalSNCF/ModalBodySNCF'; import ModalHeaderSNCF from 'common/BootstrapSNCF/ModalSNCF/ModalHeaderSNCF'; @@ -20,15 +19,16 @@ import createTrain from 'modules/simulationResult/components/SpaceTimeChart/crea import formatStdcmConf from 'applications/stdcm/formatStcmConf'; // Static Data and Assets import { setFailure } from 'reducers/main'; -import { OsrdStdcmConfState } from 'applications/operationalStudies/consts'; import STDCM_REQUEST_STATUS from 'applications/stdcm/consts'; -import { updateItinerary } from 'reducers/osrdconf'; import { useTranslation } from 'react-i18next'; import { Spinner } from 'common/Loader'; -import { osrdEditoastApi, SimulationReport } from 'common/api/osrdEditoastApi'; -import { StdcmRequestStatus } from 'applications/stdcm/types'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import type { SimulationReport } from 'common/api/osrdEditoastApi'; +import type { StdcmRequestStatus } from 'applications/stdcm/types'; import { extractMessageFromError, extractStatusFromError } from 'utils/error'; import { Train } from 'reducers/osrdsimulation/types'; +import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; +import type { OsrdStdcmConfState } from 'applications/operationalStudies/consts'; type StdcmRequestModalProps = { setCurrentStdcmRequestStatus: (currentStdcmRequestStatus: StdcmRequestStatus) => void; @@ -41,6 +41,7 @@ export default function StdcmRequestModal(props: StdcmRequestModalProps) { 'operationalStudies/manageTrainSchedule', 'translation', ]); + const { getConf } = useOsrdConfSelectors(); const osrdconf = useSelector(getConf); const dispatch = useDispatch(); @@ -48,6 +49,8 @@ export default function StdcmRequestModal(props: StdcmRequestModalProps) { const [getTrainScheduleResults] = osrdEditoastApi.endpoints.getTrainScheduleResults.useLazyQuery(); + const { updateItinerary } = useOsrdConfActions(); + // Theses are prop-drilled from OSRDSTDCM Component, which is conductor. // Remains fit with one-level limit const { setCurrentStdcmRequestStatus, currentStdcmRequestStatus } = props; diff --git a/front/src/common/DisplayMissingInfo/withOSRDStdcmMissingInfo.tsx b/front/src/common/DisplayMissingInfo/withOSRDStdcmMissingInfo.tsx index 05777cc82cb..514aaca503c 100644 --- a/front/src/common/DisplayMissingInfo/withOSRDStdcmMissingInfo.tsx +++ b/front/src/common/DisplayMissingInfo/withOSRDStdcmMissingInfo.tsx @@ -1,13 +1,16 @@ -import React, { ComponentType, useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; +import React, { useEffect, useState } from 'react'; +import type { ComponentType } from 'react'; import { useSelector } from 'react-redux'; -import { getDestination, getOrigin, getRollingStockID } from 'reducers/osrdconf/selectors'; -import DisplayMissingInfo from './DisplayMissingInfo'; +import { useTranslation } from 'react-i18next'; + +import { useOsrdConfSelectors } from 'common/osrdContext'; +import DisplayMissingInfo from 'common/DisplayMissingInfo/DisplayMissingInfo'; const withOSRDStdcmMissingInfo = (Component: ComponentType) => (hocProps: T) => { const { t } = useTranslation('missingInfo'); + const { getDestination, getOrigin, getRollingStockID } = useOsrdConfSelectors(); const origin = useSelector(getOrigin); const destination = useSelector(getDestination); diff --git a/front/src/common/InfraSelector/InfraSelector.tsx b/front/src/common/InfraSelector/InfraSelector.tsx index b478e3d93ae..416a06e7d95 100644 --- a/front/src/common/InfraSelector/InfraSelector.tsx +++ b/front/src/common/InfraSelector/InfraSelector.tsx @@ -1,14 +1,18 @@ import React, { useState, useEffect } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { useTranslation } from 'react-i18next'; -import { setFailure } from 'reducers/main'; +import { GoLock } from 'react-icons/go'; + import icon from 'assets/pictures/components/tracks.svg'; -import InfraSelectorModal from 'common/InfraSelector/InfraSelectorModal'; + +import 'common/InfraSelector/InfraSelector.scss'; +import { useInfraID } from 'common/osrdContext'; +import type { Infra } from 'common/api/osrdEditoastApi'; import { useModal } from 'common/BootstrapSNCF/ModalSNCF'; -import { getInfraID } from 'reducers/osrdconf/selectors'; -import { GoLock } from 'react-icons/go'; -import './InfraSelector.scss'; -import { Infra, osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import InfraSelectorModal from 'common/InfraSelector/InfraSelectorModal'; + +import { setFailure } from 'reducers/main'; type InfraSelectorProps = { isModalOnly?: boolean; @@ -17,7 +21,7 @@ type InfraSelectorProps = { const InfraSelector = ({ isModalOnly = false }: InfraSelectorProps) => { const dispatch = useDispatch(); const [selectedInfra, setSelectedInfra] = useState(undefined); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const { openModal } = useModal(); const [getInfraByID] = osrdEditoastApi.endpoints.getInfraById.useLazyQuery({}); const { t } = useTranslation(['infraManagement']); diff --git a/front/src/common/InfraSelector/InfraSelectorModalBodyStandard.tsx b/front/src/common/InfraSelector/InfraSelectorModalBodyStandard.tsx index 36b64120ba1..f5d73be86a4 100644 --- a/front/src/common/InfraSelector/InfraSelectorModalBodyStandard.tsx +++ b/front/src/common/InfraSelector/InfraSelectorModalBodyStandard.tsx @@ -1,13 +1,20 @@ import React, { useContext } from 'react'; +import { useTranslation } from 'react-i18next'; +import { useDispatch } from 'react-redux'; import nextId from 'react-id-generator'; import { GoLock } from 'react-icons/go'; + +import { MODES } from 'applications/operationalStudies/consts'; + import InputSNCF from 'common/BootstrapSNCF/InputSNCF'; -import { useDispatch, useSelector } from 'react-redux'; -import { getInfraID } from 'reducers/osrdconf/selectors'; -import { updateInfraID, deleteItinerary } from 'reducers/osrdconf'; -import { useTranslation } from 'react-i18next'; +import type { Infra } from 'common/api/osrdEditoastApi'; import { ModalContext } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; -import { Infra } from 'common/api/osrdEditoastApi'; +import { + useInfraID, + useOsrdConfActions, + useOsrdContext, + useUpdateInfraID, +} from 'common/osrdContext'; type InfraSelectorModalBodyStandardProps = { filter: string; @@ -38,13 +45,16 @@ export default function InfraSelectorModalBodyStandard({ }: InfraSelectorModalBodyStandardProps) { const { t } = useTranslation(['translation', 'infraManagement']); const dispatch = useDispatch(); - const infraID = useSelector(getInfraID); + const { mode } = useOsrdContext(); + const updateInfraID = useUpdateInfraID(); + const infraID = useInfraID(); const { closeModal } = useContext(ModalContext); + const { deleteItinerary } = useOsrdConfActions(); function setInfraID(id: number) { dispatch(updateInfraID(id)); if (onInfraChange) onInfraChange(id); - dispatch(deleteItinerary()); + if (mode === (MODES.simulation || MODES.stdcm)) dispatch(deleteItinerary()); if (!onlySelectionMode) { closeModal(); } diff --git a/front/src/common/Map/Buttons/ButtonMapInfras.tsx b/front/src/common/Map/Buttons/ButtonMapInfras.tsx index 64b3dde1b93..418e5a387aa 100644 --- a/front/src/common/Map/Buttons/ButtonMapInfras.tsx +++ b/front/src/common/Map/Buttons/ButtonMapInfras.tsx @@ -2,15 +2,14 @@ import React from 'react'; import { GiRailway } from 'react-icons/gi'; import InfraSelector from 'common/InfraSelector/InfraSelector'; import { useModal } from 'common/BootstrapSNCF/ModalSNCF'; -import { getInfraID } from 'reducers/osrdconf/selectors'; -import { useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; import cx from 'classnames'; import Tipped from 'applications/editor/components/Tipped'; +import { useInfraID } from 'common/osrdContext'; const ButtonMapInfras = () => { const { openModal } = useModal(); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const { t } = useTranslation('translation'); return ( diff --git a/front/src/common/Map/Buttons/MapButtons.tsx b/front/src/common/Map/Buttons/MapButtons.tsx index 9b72310bafd..dc21e90d77c 100644 --- a/front/src/common/Map/Buttons/MapButtons.tsx +++ b/front/src/common/Map/Buttons/MapButtons.tsx @@ -17,14 +17,14 @@ import ButtonMapInfras from 'common/Map/Buttons/ButtonMapInfras'; import MapKey from 'common/Map/MapKey'; import MapSearch from 'common/Map/Search/MapSearch'; import MapSettings from 'common/Map/Settings/MapSettings'; -import { getFeatureInfoClick } from 'reducers/osrdconf/selectors'; -import { useSelector, useDispatch } from 'react-redux'; -import { updateFeatureInfoClickOSRD } from 'reducers/osrdconf'; +import { useDispatch } from 'react-redux'; + import useOutsideClick from 'utils/hooks/useOutsideClick'; type MapButtonsProps = { map?: MapRef; resetPitchBearing: () => void; + closeFeatureInfoClickPopup?: () => void; withInfraButton?: boolean; }; @@ -39,8 +39,12 @@ const DEFAULT_VIEWPORT = { }; const MAP_POPOVERS = { SEARCH: 'SEARCH', SETTINGS: 'SETTINGS', KEY: 'KEY' }; -export default function MapButtons({ map, resetPitchBearing, withInfraButton }: MapButtonsProps) { - const featureInfoClick = useSelector(getFeatureInfoClick); +export default function MapButtons({ + map, + resetPitchBearing, + closeFeatureInfoClickPopup, + withInfraButton, +}: MapButtonsProps) { const dispatch = useDispatch(); const { isOpen } = useContext(ModalContext); @@ -54,15 +58,7 @@ export default function MapButtons({ map, resetPitchBearing, withInfraButton }: // Close the pop up of the map useEffect(() => { - if (featureInfoClick.displayPopup) { - dispatch( - updateFeatureInfoClickOSRD({ - displayPopup: false, - feature: undefined, - }) - ); - } - // eslint-disable-next-line react-hooks/exhaustive-deps + if (closeFeatureInfoClickPopup) closeFeatureInfoClickPopup(); }, [openedPopover, isOpen]); // Close the Popover when opening modal diff --git a/front/src/common/Map/Layers/BufferStops.tsx b/front/src/common/Map/Layers/BufferStops.tsx index 0a70a2672cd..f6046c37990 100644 --- a/front/src/common/Map/Layers/BufferStops.tsx +++ b/front/src/common/Map/Layers/BufferStops.tsx @@ -1,7 +1,6 @@ -import React, { FC } from 'react'; +import React from 'react'; import { useSelector } from 'react-redux'; import { Source, SymbolLayer } from 'react-map-gl/maplibre'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import { Theme, OmitLayer } from 'types'; import { MAP_URL } from 'common/Map/const'; import OrderedLayer from 'common/Map/Layers/OrderedLayer'; @@ -36,10 +35,10 @@ export function getBufferStopsLayerProps(params: { sourceTable?: string }): Omit interface BufferStopsProps { colors: Theme; layerOrder: number; + infraID: number | undefined; } -const BufferStops: FC = ({ layerOrder }) => { - const infraID = useSelector(getInfraID); +const BufferStops = ({ layerOrder, infraID }: BufferStopsProps) => { const layersSettings = useSelector(getLayersSettings); return layersSettings.bufferstops ? ( diff --git a/front/src/common/Map/Layers/Catenaries.tsx b/front/src/common/Map/Layers/Catenaries.tsx index ad28c32de3b..f8ab0d16561 100644 --- a/front/src/common/Map/Layers/Catenaries.tsx +++ b/front/src/common/Map/Layers/Catenaries.tsx @@ -1,18 +1,20 @@ import React from 'react'; import { useSelector } from 'react-redux'; -import { Source, LayerProps } from 'react-map-gl/maplibre'; +import { Source } from 'react-map-gl/maplibre'; +import type { LayerProps } from 'react-map-gl/maplibre'; +import { isNil } from 'lodash'; -import { RootState } from 'reducers'; -import { Theme } from 'types'; -import { MAP_URL } from 'common/Map/const'; -import { getInfraID } from 'reducers/osrdconf/selectors'; +import type { Theme } from 'types'; +import { MAP_URL } from 'common/Map/const'; import OrderedLayer from 'common/Map/Layers/OrderedLayer'; -import { isNil } from 'lodash'; + +import type { RootState } from 'reducers'; interface CatenariesProps { colors: Theme; layerOrder: number; + infraID: number | undefined; } export function getCatenariesProps({ @@ -121,10 +123,8 @@ export function getCatenariesTextParams({ return res; } -export default function Catenaries(props: CatenariesProps) { +export default function Catenaries({ colors, layerOrder, infraID }: CatenariesProps) { const { layersSettings } = useSelector((state: RootState) => state.map); - const infraID = useSelector(getInfraID); - const { colors, layerOrder } = props; const catenariesParams: LayerProps = getCatenariesProps({ colors, sourceTable: 'catenaries' }); const catenariesTextParams: LayerProps = getCatenariesTextParams({ colors, diff --git a/front/src/common/Map/Layers/Detectors.tsx b/front/src/common/Map/Layers/Detectors.tsx index e95395e19f5..5bdcd55786c 100644 --- a/front/src/common/Map/Layers/Detectors.tsx +++ b/front/src/common/Map/Layers/Detectors.tsx @@ -1,12 +1,13 @@ -import React, { FC } from 'react'; +import React from 'react'; import { useSelector } from 'react-redux'; -import { Source, CircleLayer, SymbolLayer } from 'react-map-gl/maplibre'; +import { Source } from 'react-map-gl/maplibre'; +import type { CircleLayer, SymbolLayer } from 'react-map-gl/maplibre'; -import { Theme, OmitLayer } from 'types'; -import { MAP_URL } from 'common/Map/const'; +import type { Theme, OmitLayer } from 'types'; +import { MAP_URL } from 'common/Map/const'; import OrderedLayer from 'common/Map/Layers/OrderedLayer'; -import { getInfraID } from 'reducers/osrdconf/selectors'; + import { getLayersSettings } from 'reducers/map/selectors'; export function getDetectorsLayerProps(params: { @@ -58,10 +59,10 @@ export function getDetectorsNameLayerProps(params: { interface DetectorsProps { colors: Theme; layerOrder: number; + infraID: number | undefined; } -const Detectors: FC = ({ colors, layerOrder }) => { - const infraID = useSelector(getInfraID); +const Detectors = ({ colors, layerOrder, infraID }: DetectorsProps) => { const layersSettings = useSelector(getLayersSettings); const layerPoint = getDetectorsLayerProps({ colors, sourceTable: 'detectors' }); diff --git a/front/src/common/Map/Layers/GeoJSONs.tsx b/front/src/common/Map/Layers/GeoJSONs.tsx index 77ca7649581..8e1cc9b21ff 100644 --- a/front/src/common/Map/Layers/GeoJSONs.tsx +++ b/front/src/common/Map/Layers/GeoJSONs.tsx @@ -1,52 +1,59 @@ +import React, { useEffect, useMemo, useState } from 'react'; import { useSelector } from 'react-redux'; -import React, { FC, useEffect, useMemo, useState } from 'react'; +import { Layer, Source } from 'react-map-gl/maplibre'; +import type { AnyLayer, LayerProps } from 'react-map-gl/maplibre'; +import type { FilterSpecification } from 'maplibre-gl'; import chroma from 'chroma-js'; -import { Feature, FeatureCollection } from 'geojson'; +import type { Feature, FeatureCollection } from 'geojson'; import { isPlainObject, mapValues, omit } from 'lodash'; -import { AnyLayer, Layer, Source, LayerProps } from 'react-map-gl/maplibre'; -import { FilterSpecification } from 'maplibre-gl'; -import { LayerType } from 'applications/editor/tools/types'; -import { RootState } from 'reducers'; -import { MapState } from 'reducers/map'; -import { getInfraID } from 'reducers/osrdconf/selectors'; +import type { Theme } from 'types'; + import { LAYERS, LAYER_ENTITIES_ORDERS, LAYER_GROUPS_ORDER } from 'config/layerOrder'; -import { Theme } from 'types'; -import geoMainLayer from './geographiclayers'; + +import type { LayerType } from 'applications/editor/tools/types'; + +import geoMainLayer from 'common/Map/Layers/geographiclayers'; import { getPointLayerProps, getSignalLayerProps, getSignalMatLayerProps, -} from './geoSignalsLayers'; -import { lineNameLayer, lineNumberLayer, trackNameLayer } from './commonLayers'; -import { getBufferStopsLayerProps } from './BufferStops'; -import { getDetectorsLayerProps, getDetectorsNameLayerProps } from './Detectors'; -import { getSwitchesLayerProps, getSwitchesNameLayerProps } from './Switches'; +} from 'common/Map/Layers/geoSignalsLayers'; +import type { LayerContext } from 'common/Map/Layers/types'; +import { Platforms } from 'common/Map/Layers/Platforms'; +import OrderedLayer from 'common/Map/Layers/OrderedLayer'; +import getKPLabelLayerProps from 'common/Map/Layers/KPLabel'; +import { MAP_TRACK_SOURCE, MAP_URL } from 'common/Map/const'; +import { getBufferStopsLayerProps } from 'common/Map/Layers/BufferStops'; +import { getSwitchesLayerProps, getSwitchesNameLayerProps } from 'common/Map/Layers/Switches'; +import { lineNameLayer, lineNumberLayer, trackNameLayer } from 'common/Map/Layers/commonLayers'; +import { getDetectorsLayerProps, getDetectorsNameLayerProps } from 'common/Map/Layers/Detectors'; +import { getCatenariesProps, getCatenariesTextParams } from 'common/Map/Layers/Catenaries'; +import { + getPSLSignsLayerProps, + getPSLSignsMastLayerProps, +} from 'common/Map/Layers/extensions/SNCF/PSLSigns'; import { getLineErrorsLayerProps, getLineTextErrorsLayerProps, getPointErrorsLayerProps, getPointTextErrorsLayerProps, -} from './Errors'; -import { MAP_TRACK_SOURCE, MAP_URL } from '../const'; +} from 'common/Map/Layers/Errors'; import { getSpeedSectionsFilter, getSpeedSectionsLineLayerProps, getSpeedSectionsPointLayerProps, getSpeedSectionsTextLayerProps, -} from './SpeedLimits'; +} from 'common/Map/Layers/SpeedLimits'; import { getPSLFilter, getPSLSpeedLineBGLayerProps, getPSLSpeedLineLayerProps, getPSLSpeedValueLayerProps, -} from './extensions/SNCF/PSL'; -import { getPSLSignsLayerProps, getPSLSignsMastLayerProps } from './extensions/SNCF/PSLSigns'; -import { LayerContext } from './types'; -import { getCatenariesProps, getCatenariesTextParams } from './Catenaries'; -import getKPLabelLayerProps from './KPLabel'; -import OrderedLayer from './OrderedLayer'; -import { Platforms } from './Platforms'; +} from 'common/Map/Layers/extensions/SNCF/PSL'; + +import type { RootState } from 'reducers'; +import type { MapState } from 'reducers/map'; const POINT_ENTITIES_MIN_ZOOM = 12; @@ -387,12 +394,14 @@ export const SourcesDefinitionsIndex = SOURCES_DEFINITION.reduce( {} as Record AnyLayer[]> ); -export const EditorSource: FC<{ +interface EditorSourceProps { id?: string; data: Feature | FeatureCollection; layers: AnyLayer[]; layerOrder?: number; -}> = ({ id, data, layers, layerOrder }) => { +} + +export const EditorSource = ({ id, data, layers, layerOrder }: EditorSourceProps) => { const dataFingerPrint = data.type === 'FeatureCollection' ? data.features.map((f) => f.properties?.id).concat() @@ -410,7 +419,7 @@ export const EditorSource: FC<{ ); }; -const GeoJSONs: FC<{ +interface GeoJSONsProps { colors: Theme; layersSettings: MapState['layersSettings']; issuesSettings?: MapState['issuesSettings']; @@ -423,7 +432,10 @@ const GeoJSONs: FC<{ beforeId?: string; // When true, all layers are rendered (ie "minZoom" restrictions are ignored) renderAll?: boolean; -}> = ({ + infraID: number | undefined; +} + +const GeoJSONs = ({ colors, layersSettings, issuesSettings, @@ -435,8 +447,8 @@ const GeoJSONs: FC<{ isEmphasized = true, beforeId, renderAll, -}) => { - const infraID = useSelector(getInfraID); + infraID, +}: GeoJSONsProps) => { const selectedPrefix = `${prefix}selected/`; const hiddenColors = useMemo( () => diff --git a/front/src/common/Map/Layers/LineSearchLayer.tsx b/front/src/common/Map/Layers/LineSearchLayer.tsx index f76bde3a477..de2abfa57f8 100644 --- a/front/src/common/Map/Layers/LineSearchLayer.tsx +++ b/front/src/common/Map/Layers/LineSearchLayer.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import { getMap } from 'reducers/map/selectors'; import { MAP_TRACK_SOURCES, MAP_URL } from 'common/Map/const'; import { useSelector } from 'react-redux'; @@ -8,11 +7,10 @@ import OrderedLayer from 'common/Map/Layers/OrderedLayer'; interface TracksGeographicProps { layerOrder?: number; + infraID: number | undefined; } -function LineSearchLayer(props: TracksGeographicProps) { - const { layerOrder } = props; - const infraID = useSelector(getInfraID); +const LineSearchLayer = ({ layerOrder, infraID }: TracksGeographicProps) => { const { lineSearchCode } = useSelector(getMap); const infraVersion = infraID !== undefined ? `?infra=${infraID}` : null; @@ -38,6 +36,6 @@ function LineSearchLayer(props: TracksGeographicProps) { )} ) : null; -} +}; export default LineSearchLayer; diff --git a/front/src/common/Map/Layers/NeutralSections.tsx b/front/src/common/Map/Layers/NeutralSections.tsx index 023095a387e..306dd71a8e6 100644 --- a/front/src/common/Map/Layers/NeutralSections.tsx +++ b/front/src/common/Map/Layers/NeutralSections.tsx @@ -4,7 +4,6 @@ import { Source, LayerProps } from 'react-map-gl/maplibre'; import { RootState } from 'reducers'; import { MAP_URL } from 'common/Map/const'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import colors from 'common/Map/Consts/colors'; import { getMapStyle } from 'reducers/map/selectors'; @@ -12,13 +11,12 @@ import OrderedLayer from 'common/Map/Layers/OrderedLayer'; interface NeutralSectionsProps { layerOrder: number; + infraID: number | undefined; } -export default function NeutralSections(props: NeutralSectionsProps) { +export default function NeutralSections({ layerOrder, infraID }: NeutralSectionsProps) { const { layersSettings } = useSelector((state: RootState) => state.map); - const infraID = useSelector(getInfraID); const mapStyle = useSelector(getMapStyle); - const { layerOrder } = props; const neutralSectionsParams: LayerProps = { type: 'line', 'source-layer': 'neutral_sections', diff --git a/front/src/common/Map/Layers/OperationalPoints.tsx b/front/src/common/Map/Layers/OperationalPoints.tsx index 2faf034f1e3..77094de9bb1 100644 --- a/front/src/common/Map/Layers/OperationalPoints.tsx +++ b/front/src/common/Map/Layers/OperationalPoints.tsx @@ -8,17 +8,15 @@ import { MAP_URL } from 'common/Map/const'; import OrderedLayer from 'common/Map/Layers/OrderedLayer'; import getKPLabelLayerProps from 'common/Map/Layers/KPLabel'; -import { getInfraID } from 'reducers/osrdconf/selectors'; interface Props { colors: Theme; layerOrder: number; + infraID: number | undefined; } -export default function OperationalPoints(props: Props) { +export default function OperationalPoints({ colors, layerOrder, infraID }: Props) { const { layersSettings } = useSelector((state: RootState) => state.map); - const infraID = useSelector(getInfraID); - const { colors, layerOrder } = props; const point: LayerProps = { type: 'circle', 'source-layer': 'operational_points', diff --git a/front/src/common/Map/Layers/Routes.tsx b/front/src/common/Map/Layers/Routes.tsx index 917d8b1fd5e..e6ef18826cc 100644 --- a/front/src/common/Map/Layers/Routes.tsx +++ b/front/src/common/Map/Layers/Routes.tsx @@ -1,16 +1,19 @@ import React from 'react'; import { useSelector } from 'react-redux'; -import { CircleLayer, LineLayer, Source, SymbolLayer } from 'react-map-gl/maplibre'; +import { Source } from 'react-map-gl/maplibre'; +import type { CircleLayer, LineLayer, SymbolLayer } from 'react-map-gl/maplibre'; + +import type { Theme, OmitLayer } from 'types'; -import { RootState } from 'reducers'; -import { Theme, OmitLayer } from 'types'; import { MAP_URL } from 'common/Map/const'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import OrderedLayer from 'common/Map/Layers/OrderedLayer'; +import { getMap } from 'reducers/map/selectors'; + interface RoutesProps { colors: Theme; layerOrder: number; + infraID: number | undefined; } export function getRoutesLineLayerProps(params: { @@ -87,10 +90,8 @@ export function getRoutesTextLayerProps(params: { return res; } -export default function Routes(props: RoutesProps) { - const { colors, layerOrder } = props; - const { layersSettings } = useSelector((state: RootState) => state.map); - const infraID = useSelector(getInfraID); +export default function Routes({ colors, layerOrder, infraID }: RoutesProps) { + const { layersSettings } = useSelector(getMap); const lineProps = getRoutesLineLayerProps({ colors, sourceTable: 'routes' }); const pointProps = getRoutesPointLayerProps({ colors, sourceTable: 'routes' }); diff --git a/front/src/common/Map/Layers/Signals.tsx b/front/src/common/Map/Layers/Signals.tsx index 2c483b81e88..06cc57e1905 100644 --- a/front/src/common/Map/Layers/Signals.tsx +++ b/front/src/common/Map/Layers/Signals.tsx @@ -7,7 +7,6 @@ import { Theme } from 'types'; import { MAP_URL } from 'common/Map/const'; import OrderedLayer from 'common/Map/Layers/OrderedLayer'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import { getLayersSettings, getMapStyle } from 'reducers/map/selectors'; import { getPointLayerProps, @@ -23,13 +22,12 @@ interface PlatformProps { hovered?: { id: string; layer: string }; mapRef?: React.RefObject; layerOrder: number; + infraID: number | undefined; } -function Signals(props: PlatformProps) { +const Signals = ({ colors, sourceTable, layerOrder, infraID }: PlatformProps) => { const mapStyle = useSelector(getMapStyle); const layersSettings = useSelector(getLayersSettings); - const infraID = useSelector(getInfraID); - const { colors, sourceTable, layerOrder } = props; const prefix = mapStyle === 'blueprint' ? 'SCHB ' : ''; @@ -74,6 +72,6 @@ function Signals(props: PlatformProps) { /> ) : null; -} +}; export default Signals; diff --git a/front/src/common/Map/Layers/SpeedLimits.tsx b/front/src/common/Map/Layers/SpeedLimits.tsx index 9e5d098a303..fa4ba273e19 100644 --- a/front/src/common/Map/Layers/SpeedLimits.tsx +++ b/front/src/common/Map/Layers/SpeedLimits.tsx @@ -1,19 +1,22 @@ import React from 'react'; import { isNil } from 'lodash'; import { useSelector } from 'react-redux'; -import { Source, SymbolLayer, LineLayer } from 'react-map-gl/maplibre'; -import { ExpressionSpecification, FilterSpecification } from 'maplibre-gl'; +import { Source } from 'react-map-gl/maplibre'; +import type { SymbolLayer, LineLayer } from 'react-map-gl/maplibre'; +import type { ExpressionSpecification, FilterSpecification } from 'maplibre-gl'; + +import type { Theme, OmitLayer } from 'types'; -import { RootState } from 'reducers'; import { MAP_URL } from 'common/Map/const'; -import { Theme, OmitLayer } from 'types'; import OrderedLayer from 'common/Map/Layers/OrderedLayer'; -import { getInfraID } from 'reducers/osrdconf/selectors'; -import { MapState } from 'reducers/map'; + +import type { RootState } from 'reducers'; +import type { MapState } from 'reducers/map'; interface SpeedLimitsProps { colors: Theme; layerOrder: number; + infraID: number | undefined; } export function getSpeedSectionsTag({ speedlimittag }: MapState['layersSettings']): string { @@ -167,10 +170,8 @@ export function getSpeedSectionsTextLayerProps({ return res; } -export default function SpeedLimits(props: SpeedLimitsProps) { +export default function SpeedLimits({ colors, layerOrder, infraID }: SpeedLimitsProps) { const { layersSettings } = useSelector((state: RootState) => state.map); - const infraID = useSelector(getInfraID); - const { colors, layerOrder } = props; const filter = getSpeedSectionsFilter(layersSettings); const lineProps = { diff --git a/front/src/common/Map/Layers/Switches.tsx b/front/src/common/Map/Layers/Switches.tsx index 4029e265b05..3913da30c9e 100644 --- a/front/src/common/Map/Layers/Switches.tsx +++ b/front/src/common/Map/Layers/Switches.tsx @@ -1,13 +1,15 @@ -import React, { FC } from 'react'; +import React from 'react'; import { useSelector } from 'react-redux'; -import { Source, SymbolLayer, CircleLayer } from 'react-map-gl/maplibre'; -import { MAP_URL } from 'common/Map/const'; -import { RootState } from 'reducers'; -import { Theme, OmitLayer } from 'types'; -import { getInfraID } from 'reducers/osrdconf/selectors'; +import { Source } from 'react-map-gl/maplibre'; +import type { SymbolLayer, CircleLayer } from 'react-map-gl/maplibre'; + +import type { Theme, OmitLayer } from 'types'; +import { MAP_URL } from 'common/Map/const'; import OrderedLayer from 'common/Map/Layers/OrderedLayer'; +import type { RootState } from 'reducers'; + export function getSwitchesLayerProps(params: { colors: Theme; sourceTable?: string; @@ -59,12 +61,11 @@ export function getSwitchesNameLayerProps(params: { interface SwitchesProps { colors: Theme; layerOrder: number; + infraID: number | undefined; } -const Switches: FC = (props) => { +const Switches = ({ colors, layerOrder, infraID }: SwitchesProps) => { const { layersSettings } = useSelector((state: RootState) => state.map); - const infraID = useSelector(getInfraID); - const { colors, layerOrder } = props; const layerPoint = getSwitchesLayerProps({ colors, sourceTable: 'switches' }); const layerName = getSwitchesNameLayerProps({ colors, sourceTable: 'switches' }); diff --git a/front/src/common/Map/Layers/TracksGeographic.tsx b/front/src/common/Map/Layers/TracksGeographic.tsx index 807da4199f0..2b10aa4c979 100644 --- a/front/src/common/Map/Layers/TracksGeographic.tsx +++ b/front/src/common/Map/Layers/TracksGeographic.tsx @@ -2,24 +2,22 @@ import React from 'react'; import { useSelector } from 'react-redux'; import { Source } from 'react-map-gl/maplibre'; -import { RootState } from 'reducers'; -import { Theme } from 'types'; +import type { Theme } from 'types'; import { MAP_TRACK_SOURCES, MAP_URL } from 'common/Map/const'; import geoMainLayer from 'common/Map/Layers/geographiclayers'; import { lineNameLayer, lineNumberLayer, trackNameLayer } from 'common/Map/Layers/commonLayers'; import OrderedLayer from 'common/Map/Layers/OrderedLayer'; -import { getInfraID } from 'reducers/osrdconf/selectors'; +import { getMap } from 'reducers/map/selectors'; interface TracksGeographicProps { colors: Theme; layerOrder?: number; + infraID: number | undefined; } -function TracksGeographic(props: TracksGeographicProps) { - const { colors, layerOrder } = props; - const infraID = useSelector(getInfraID); - const { showIGNBDORTHO, showIGNSCAN25 } = useSelector((state: RootState) => state.map); +function TracksGeographic({ colors, layerOrder, infraID }: TracksGeographicProps) { + const { showIGNBDORTHO, showIGNSCAN25 } = useSelector(getMap); const infraVersion = infraID !== undefined ? `?infra=${infraID}` : null; return ( diff --git a/front/src/common/Map/Layers/extensions/SNCF/PSL.tsx b/front/src/common/Map/Layers/extensions/SNCF/PSL.tsx index c3601432a8c..c8f486953c1 100644 --- a/front/src/common/Map/Layers/extensions/SNCF/PSL.tsx +++ b/front/src/common/Map/Layers/extensions/SNCF/PSL.tsx @@ -1,24 +1,27 @@ /* eslint-disable react/jsx-pascal-case */ import React from 'react'; import { useSelector } from 'react-redux'; -import { RootState } from 'reducers'; -import { LineLayer, SymbolLayer, Source } from 'react-map-gl/maplibre'; +import { Source } from 'react-map-gl/maplibre'; +import type { LineLayer, SymbolLayer } from 'react-map-gl/maplibre'; import { isNil } from 'lodash'; -import { TFunction } from 'i18next'; +import type { TFunction } from 'i18next'; import { useTranslation } from 'react-i18next'; -import { FilterSpecification } from 'maplibre-gl'; +import type { FilterSpecification } from 'maplibre-gl'; + +import type { Theme, OmitLayer } from 'types'; import { MAP_URL } from 'common/Map/const'; import OrderedLayer from 'common/Map/Layers/OrderedLayer'; -import { getInfraID } from 'reducers/osrdconf/selectors'; -import { MapState } from 'reducers/map'; -import { getSpeedSectionsTag, getSpeedSectionsName } from '../../SpeedLimits'; -import { Theme, OmitLayer } from '../../../../../types'; -import SNCF_PSL_Signs from './PSLSigns'; +import SNCF_PSL_Signs from 'common/Map/Layers/extensions/SNCF/PSLSigns'; +import { getSpeedSectionsTag, getSpeedSectionsName } from 'common/Map/Layers/SpeedLimits'; + +import type { RootState } from 'reducers'; +import type { MapState } from 'reducers/map'; interface SNCF_PSLProps { colors: Theme; layerOrder?: number; + infraID?: number | undefined; } export function getPSLFilter(layersSettings: MapState['layersSettings']): FilterSpecification { @@ -154,11 +157,9 @@ export function getPSLSpeedLineLayerProps({ return res; } -export default function SNCF_PSL(props: SNCF_PSLProps) { +const SNCF_PSL = ({ colors, layerOrder, infraID }: SNCF_PSLProps) => { const { t } = useTranslation('map-settings'); const { layersSettings } = useSelector((state: RootState) => state.map); - const infraID = useSelector(getInfraID); - const { colors, layerOrder } = props; const speedSectionFilter = getPSLFilter(layersSettings); @@ -219,4 +220,6 @@ export default function SNCF_PSL(props: SNCF_PSLProps) { ); } return null; -} +}; + +export default SNCF_PSL; diff --git a/front/src/common/Map/Layers/extensions/SNCF/PSLSigns.tsx b/front/src/common/Map/Layers/extensions/SNCF/PSLSigns.tsx index 366b3186645..c57afe1f205 100644 --- a/front/src/common/Map/Layers/extensions/SNCF/PSLSigns.tsx +++ b/front/src/common/Map/Layers/extensions/SNCF/PSLSigns.tsx @@ -1,14 +1,18 @@ import React from 'react'; -import { MAP_URL } from 'common/Map/const'; -import { LayerProps, Source, SymbolLayer } from 'react-map-gl/maplibre'; +import { Source } from 'react-map-gl/maplibre'; +import type { LayerProps, SymbolLayer } from 'react-map-gl/maplibre'; import { useSelector } from 'react-redux'; -import { getInfraID } from 'reducers/osrdconf/selectors'; -import { Theme, OmitLayer } from 'types'; import { isNil } from 'lodash'; + +import type { Theme, OmitLayer } from 'types'; + +import { MAP_URL } from 'common/Map/const'; +import { useInfraID } from 'common/osrdContext'; +import OrderedLayer from 'common/Map/Layers/OrderedLayer'; +import type { LayerContext } from 'common/Map/Layers/types'; +import getKPLabelLayerProps from 'common/Map/Layers/KPLabel'; + import { getMap } from 'reducers/map/selectors'; -import OrderedLayer from '../../OrderedLayer'; -import { LayerContext } from '../../types'; -import getKPLabelLayerProps from '../../KPLabel'; interface SNCF_PSL_SignsProps { colors: Theme; @@ -95,7 +99,7 @@ export function getPSLSignsMastLayerProps({ } export default function SNCF_PSL_Signs(props: SNCF_PSL_SignsProps) { - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const { colors, layerOrder } = props; const { mapStyle } = useSelector(getMap); diff --git a/front/src/common/Map/Search/MapSearchLine.tsx b/front/src/common/Map/Search/MapSearchLine.tsx index ad35f1d7acd..a02df1f61d7 100644 --- a/front/src/common/Map/Search/MapSearchLine.tsx +++ b/front/src/common/Map/Search/MapSearchLine.tsx @@ -1,6 +1,5 @@ import React, { useEffect, useState } from 'react'; import { getMap } from 'reducers/map/selectors'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; import { updateLineSearchCode, updateMapSearchMarker } from 'reducers/map'; import { useDebounce } from 'utils/helpers'; @@ -15,6 +14,7 @@ import WebMercatorViewport from 'viewport-mercator-project'; import type { Viewport } from 'reducers/map'; import type { Zone, SearchResultItemTrack, SearchPayload } from 'common/api/osrdEditoastApi'; import type { BBox } from '@turf/helpers'; +import { useInfraID } from 'common/osrdContext'; type MapSearchLineProps = { updateExtViewport: (viewport: Partial) => void; @@ -22,7 +22,7 @@ type MapSearchLineProps = { }; const MapSearchLine = ({ updateExtViewport, closeMapSearchPopUp }: MapSearchLineProps) => { - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const map = useSelector(getMap); const { t } = useTranslation(['map-search']); const dispatch = useDispatch(); diff --git a/front/src/common/Map/Search/MapSearchSignal.tsx b/front/src/common/Map/Search/MapSearchSignal.tsx index 49d148f3c64..dc4c3673843 100644 --- a/front/src/common/Map/Search/MapSearchSignal.tsx +++ b/front/src/common/Map/Search/MapSearchSignal.tsx @@ -1,14 +1,14 @@ import React, { useEffect, useMemo, useRef, useState } from 'react'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import { getMap } from 'reducers/map/selectors'; -import { onResultSearchClick } from 'common/Map/utils'; -import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; + import { setFailure } from 'reducers/main'; import { sortBy } from 'lodash'; import { useDebounce } from 'utils/helpers'; import { useDispatch, useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; import InputSNCF from 'common/BootstrapSNCF/InputSNCF'; +import { onResultSearchClick } from 'common/Map/utils'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; import MultiSelectSNCF from 'common/BootstrapSNCF/MultiSelectSNCF'; import nextId from 'react-id-generator'; import SelectImproved from 'common/BootstrapSNCF/SelectImprovedSNCF'; @@ -16,6 +16,7 @@ import SignalCard from 'common/Map/Search/SignalCard'; import type { SearchResultItemSignal, SearchPayload } from 'common/api/osrdEditoastApi'; import type { Viewport } from 'reducers/map'; +import { useInfraID } from 'common/osrdContext'; type MapSearchSignalProps = { updateExtViewport: (viewport: Partial) => void; @@ -29,7 +30,7 @@ export type SortType = { const MapSearchSignal = ({ updateExtViewport, closeMapSearchPopUp }: MapSearchSignalProps) => { const map = useSelector(getMap); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const [searchState, setSearch] = useState(''); const [searchLineState, setSearchLine] = useState(''); const { t } = useTranslation(['translation', 'map-search']); diff --git a/front/src/common/Map/Search/MapSearchStation.tsx b/front/src/common/Map/Search/MapSearchStation.tsx index 3016b7bbd23..5291ed442a1 100644 --- a/front/src/common/Map/Search/MapSearchStation.tsx +++ b/front/src/common/Map/Search/MapSearchStation.tsx @@ -1,5 +1,4 @@ import React, { useState, useEffect, useCallback } from 'react'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import { getMap } from 'reducers/map/selectors'; import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; import { onResultSearchClick } from 'common/Map/utils'; @@ -9,10 +8,12 @@ import { useSelector, useDispatch } from 'react-redux'; import { useTranslation } from 'react-i18next'; import InputSNCF from 'common/BootstrapSNCF/InputSNCF'; import nextId from 'react-id-generator'; + import StationCard from 'common/StationCard'; import type { SearchQuery, SearchResultItemOperationalPoint } from 'common/api/osrdEditoastApi'; import type { Viewport } from 'reducers/map'; +import { useInfraID } from 'common/osrdContext'; type MapSearchStationProps = { updateExtViewport: (viewport: Partial) => void; @@ -27,7 +28,7 @@ const MapSearchStation = ({ updateExtViewport, closeMapSearchPopUp }: MapSearchS >(undefined); const [trigramResults, setTrigramResults] = useState([]); const [nameResults, setNameResults] = useState([]); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const [postSearch] = osrdEditoastApi.usePostSearchMutation(); const dispatch = useDispatch(); diff --git a/front/src/common/Map/Settings/MapSettingsSpeedLimits.tsx b/front/src/common/Map/Settings/MapSettingsSpeedLimits.tsx index 58fb0264ca5..c19c0f698f9 100644 --- a/front/src/common/Map/Settings/MapSettingsSpeedLimits.tsx +++ b/front/src/common/Map/Settings/MapSettingsSpeedLimits.tsx @@ -1,21 +1,27 @@ import React, { useEffect, useMemo } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { useTranslation } from 'react-i18next'; -import { MapState, updateLayersSettings } from 'reducers/map'; import { IoMdSpeedometer } from 'react-icons/io'; -import { IconType } from 'react-icons'; -import { SerializedError } from '@reduxjs/toolkit'; +import type { IconType } from 'react-icons'; +import type { SerializedError } from '@reduxjs/toolkit'; import TIVsSVGFile from 'assets/pictures/layersicons/layer_tivs.svg'; -import SwitchSNCF, { SWITCH_TYPES } from 'common/BootstrapSNCF/SwitchSNCF/SwitchSNCF'; -import SelectImprovedSNCF from 'common/BootstrapSNCF/SelectImprovedSNCF'; + import DotsLoader from 'common/DotsLoader/DotsLoader'; +import { useInfraID } from 'common/osrdContext'; import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; -import { ApiError } from 'common/api/baseGeneratedApis'; +import type { ApiError } from 'common/api/baseGeneratedApis'; +import SelectImprovedSNCF from 'common/BootstrapSNCF/SelectImprovedSNCF'; +import SwitchSNCF, { SWITCH_TYPES } from 'common/BootstrapSNCF/SwitchSNCF/SwitchSNCF'; +import { + FormatSwitch as SimpleFormatSwitch, + Icon2SVG, +} from 'common/Map/Settings/MapSettingsLayers'; + import { setFailure } from 'reducers/main'; -import { getInfraID } from 'reducers/osrdconf/selectors'; import { getMap } from 'reducers/map/selectors'; -import { FormatSwitch as SimpleFormatSwitch, Icon2SVG } from './MapSettingsLayers'; +import { updateLayersSettings } from 'reducers/map'; +import type { MapState } from 'reducers/map'; type FormatSwitchProps = { name: keyof MapState['layersSettings']; @@ -28,7 +34,7 @@ const FormatSwitch = ({ name, icon: IconComponent, color = '', disabled }: Forma const dispatch = useDispatch(); const { t } = useTranslation(['operationalStudies/manageTrainSchedule', 'map-settings']); const { layersSettings } = useSelector(getMap); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const { data: tagsList, isError: isGetSpeedLimitTagsError, diff --git a/front/src/common/Map/WarpedMap/DataLoader.tsx b/front/src/common/Map/WarpedMap/DataLoader.tsx index 920edbfc619..23d11fa15ae 100644 --- a/front/src/common/Map/WarpedMap/DataLoader.tsx +++ b/front/src/common/Map/WarpedMap/DataLoader.tsx @@ -1,23 +1,26 @@ /* eslint-disable no-console */ -import React, { FC, useEffect, useMemo, useState } from 'react'; -import { useSelector } from 'react-redux'; +import React, { useEffect, useMemo, useState } from 'react'; import { createPortal } from 'react-dom'; - -import { FeatureCollection } from 'geojson'; -import ReactMapGL, { LayerProps, MapRef, Source } from 'react-map-gl/maplibre'; -import { BBox2d } from '@turf/helpers/dist/js/lib/geojson'; +import { useSelector } from 'react-redux'; +import ReactMapGL, { Source } from 'react-map-gl/maplibre'; +import type { LayerProps, MapRef } from 'react-map-gl/maplibre'; import { featureCollection } from '@turf/helpers'; +import type { BBox2d } from '@turf/helpers/dist/js/lib/geojson'; +import type { FeatureCollection } from 'geojson'; import { map, sum, uniqBy } from 'lodash'; import mapStyleJson from 'assets/mapstyles/OSMStyle.json'; -import { LayerType } from 'applications/editor/tools/types'; -import { useMapBlankStyle } from 'common/Map/Layers/blankStyle'; -import GeoJSONs from 'common/Map/Layers/GeoJSONs'; + +import type { LayerType } from 'applications/editor/tools/types'; + +import { OSM_URL } from 'common/Map/const'; import colors from 'common/Map/Consts/colors'; import { getMap } from 'reducers/map/selectors'; -import { OSM_URL } from 'common/Map/const'; -import { simplifyFeature } from 'common/Map/WarpedMap/core/helpers'; +import GeoJSONs from 'common/Map/Layers/GeoJSONs'; +import { useInfraID } from 'common/osrdContext'; import OrderedLayer from 'common/Map/Layers/OrderedLayer'; +import { useMapBlankStyle } from 'common/Map/Layers/blankStyle'; +import { simplifyFeature } from 'common/Map/WarpedMap/core/helpers'; const TIME_LABEL = 'Loading OSRD and OSM data around warped path'; @@ -31,16 +34,20 @@ const OSM_LAYERS = new Set(['building', 'water', 'water_name', 'waterway', 'poi' * * It is designed as a component instead of a hook to simplify mounting/unmounting the temporary invisible map. */ -const DataLoader: FC<{ + +interface DataLoaderProps { bbox: BBox2d; getGeoJSONs: ( osrdData: Partial>, osmData: Record ) => void; layers: Set; -}> = ({ bbox, getGeoJSONs, layers }) => { +} + +const DataLoader = ({ bbox, getGeoJSONs, layers }: DataLoaderProps) => { const mapBlankStyle = useMapBlankStyle(); const { mapStyle, layersSettings } = useSelector(getMap); + const infraID = useInfraID(); const [mapRef, setMapRef] = useState(null); const [state, setState] = useState<'idle' | 'render' | 'loaded'>('idle'); const osmLayers = useMemo(() => { @@ -154,6 +161,7 @@ const DataLoader: FC<{ isEmphasized={false} layers={layers} renderAll + infraID={infraID} /> )} diff --git a/front/src/common/Map/WarpedMap/SimulationWarpedMap.tsx b/front/src/common/Map/WarpedMap/SimulationWarpedMap.tsx index cfe7f747ca9..212ed31b43d 100644 --- a/front/src/common/Map/WarpedMap/SimulationWarpedMap.tsx +++ b/front/src/common/Map/WarpedMap/SimulationWarpedMap.tsx @@ -1,37 +1,43 @@ /* eslint-disable no-console */ +import React, { useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import React, { FC, useEffect, useMemo, useState } from 'react'; import { clamp, first, isEmpty, isNil, keyBy, last, mapValues, omitBy, debounce } from 'lodash'; import { PiLinkBold, PiLinkBreakBold } from 'react-icons/pi'; import bbox from '@turf/bbox'; import length from '@turf/length'; import { lineString } from '@turf/helpers'; -import { BBox2d } from '@turf/helpers/dist/js/lib/geojson'; -import { Feature, FeatureCollection, LineString, Position } from 'geojson'; -import { LngLatBoundsLike } from 'maplibre-gl'; +import type { BBox2d } from '@turf/helpers/dist/js/lib/geojson'; +import type { Feature, FeatureCollection, LineString, Position } from 'geojson'; +import type { LngLatBoundsLike } from 'maplibre-gl'; + +import { clip } from 'utils/mapHelper'; +import { getAsyncMemoData, useAsyncMemo } from 'utils/useAsyncMemo'; +import type { AsyncMemoState } from 'utils/useAsyncMemo'; + +import type { LayerType } from 'applications/editor/tools/types'; + +import type { TrainPosition } from 'modules/simulationResult/components/SimulationResultsMap/types'; +import { getSimulationHoverPositions } from 'modules/simulationResult/components/SimulationResultsMap/helpers'; import { LoaderFill } from 'common/Loader'; -import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; -import { LayerType } from 'applications/editor/tools/types'; -import DataLoader from 'common/Map/WarpedMap/DataLoader'; -import getWarping, { WarpingFunction } from 'common/Map/WarpedMap/getWarping'; +import { useInfraID } from 'common/osrdContext'; import WarpedMap from 'common/Map/WarpedMap/WarpedMap'; -import { TrainPosition } from 'modules/simulationResult/components/SimulationResultsMap/types'; -import { getInfraID } from 'reducers/osrdconf/selectors'; +import getWarping from 'common/Map/WarpedMap/getWarping'; +import DataLoader from 'common/Map/WarpedMap/DataLoader'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import type { WarpingFunction } from 'common/Map/WarpedMap/getWarping'; import { getImprovedOSRDData } from 'common/Map/WarpedMap/core/helpers'; + +import type { PositionsSpeedTimes, Train } from 'reducers/osrdsimulation/types'; import { getOsrdSimulation, getSelectedProjection, getSelectedTrain, } from 'reducers/osrdsimulation/selectors'; -import type { PositionsSpeedTimes, Train } from 'reducers/osrdsimulation/types'; -import { AsyncMemoState, getAsyncMemoData, useAsyncMemo } from 'utils/useAsyncMemo'; -import { getSimulationHoverPositions } from 'modules/simulationResult/components/SimulationResultsMap/helpers'; -import { clip } from 'utils/mapHelper'; -import './SimulationWarpedMap.scss'; import { useChartSynchronizer } from 'modules/simulationResult/components/ChartHelpers/ChartSynchronizer'; +import 'common/Map/WarpedMap/SimulationWarpedMap.scss'; const TIME_LABEL = 'Warping OSRD and OSM data'; const WIDTH = 300; @@ -62,9 +68,9 @@ function transformDataStatePayload( * This component handles loading the simulation path, all the surrounding data (OSM and OSRD), transforms them, and * then mounts a WarpedMap with all that data: */ -const SimulationWarpedMap: FC<{ collapsed?: boolean }> = ({ collapsed }) => { +const SimulationWarpedMap = ({ collapsed }: { collapsed?: boolean }) => { const dispatch = useDispatch(); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const [state, setState] = useState< | { type: 'idle' } | { type: 'loading' } diff --git a/front/src/common/Pathfinding/Pathfinding.tsx b/front/src/common/Pathfinding/Pathfinding.tsx index 4672e82dd7c..a751cd07717 100644 --- a/front/src/common/Pathfinding/Pathfinding.tsx +++ b/front/src/common/Pathfinding/Pathfinding.tsx @@ -1,42 +1,25 @@ import React, { useState, useEffect, useReducer } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { Position } from 'geojson'; +import type { Position } from 'geojson'; import bbox from '@turf/bbox'; import { useTranslation } from 'react-i18next'; import { compact, isEqual, omit } from 'lodash'; import { GoAlert, GoCheckCircle, GoStop } from 'react-icons/go'; -import { setFailure } from 'reducers/main'; - -import { ArrayElement } from 'utils/types'; +import type { ArrayElement } from 'utils/types'; import { conditionalStringConcat, formatKmValue } from 'utils/strings'; -import { - PathResponse, - PathfindingRequest, - PathfindingStep, - osrdEditoastApi, -} from 'common/api/osrdEditoastApi'; -import { PointOnMap } from 'applications/operationalStudies/consts'; - -import { - replaceVias, - updateItinerary, - updatePathfindingID, - updateSuggeredVias, -} from 'reducers/osrdconf'; -import { - getInfraID, - getOrigin, - getDestination, - getVias, - getRollingStockID, - getPathfindingID, - getGeojson, -} from 'reducers/osrdconf/selectors'; +import type { PathResponse, PathfindingRequest, PathfindingStep } from 'common/api/osrdEditoastApi'; + import infraLogo from 'assets/pictures/components/tracks.svg'; +import type { PointOnMap } from 'applications/operationalStudies/consts'; import InfraLoadingState from 'applications/operationalStudies/components/Scenario/InfraLoadingState'; -import { Spinner } from '../Loader'; + +import { Spinner } from 'common/Loader'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; + +import { setFailure } from 'reducers/main'; interface PathfindingState { running: boolean; @@ -268,6 +251,15 @@ function Pathfinding({ zoomToFeature, path }: PathfindingProps) { const [pathfindingRequest, setPathfindingRequest] = useState>(); const dispatch = useDispatch(); + const { + getInfraID, + getOrigin, + getDestination, + getVias, + getRollingStockID, + getPathfindingID, + getGeojson, + } = useOsrdConfSelectors(); const infraID = useSelector(getInfraID, isEqual); const origin = useSelector(getOrigin, isEqual); const destination = useSelector(getDestination, isEqual); @@ -299,6 +291,10 @@ function Pathfinding({ zoomToFeature, path }: PathfindingProps) { } ); const [reloadInfra] = osrdEditoastApi.usePostInfraByIdLoadMutation(); + + const { replaceVias, updateItinerary, updatePathfindingID, updateSuggeredVias } = + useOsrdConfActions(); + useEffect(() => { if (reloadCount <= 5 && infra && infra.state === 'TRANSIENT_ERROR') { setTimeout(() => { diff --git a/front/src/common/Pathfinding/TypeAndPath.tsx b/front/src/common/Pathfinding/TypeAndPath.tsx index d50a1e5bd1b..06bc5c48ec8 100644 --- a/front/src/common/Pathfinding/TypeAndPath.tsx +++ b/front/src/common/Pathfinding/TypeAndPath.tsx @@ -1,21 +1,25 @@ /* eslint-disable jsx-a11y/no-autofocus */ -import { +import type { PathResponse, PostSearchApiArg, SearchResultItemOperationalPoint, - osrdEditoastApi, } from 'common/api/osrdEditoastApi'; import React, { useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; -import { getInfraID, getRollingStockID } from 'reducers/osrdconf/selectors'; -import { useDebounce } from 'utils/helpers'; -import cx from 'classnames'; import { GoAlert, GoTriangleRight } from 'react-icons/go'; +import bbox from '@turf/bbox'; +import type { Position } from 'geojson'; +import cx from 'classnames'; + +import { useDebounce } from 'utils/helpers'; + import { loadPathFinding } from 'modules/trainschedule/components/ManageTrainSchedule/helpers/adjustConfWithTrainToModify'; + +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import { useInfraID, useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; + import { setFailure } from 'reducers/main'; -import bbox from '@turf/bbox'; -import { Position } from 'geojson'; type SearchConstraintType = (string | number | string[])[]; type PathfindingProps = { @@ -54,11 +58,13 @@ export default function TypeAndPath({ zoomToFeature }: PathfindingProps) { const dispatch = useDispatch(); const [inputText, setInputText] = useState(''); const [opList, setOpList] = useState([]); - const infraId = useSelector(getInfraID); + const { getRollingStockID } = useOsrdConfSelectors(); + const infraId = useInfraID(); const rollingStockId = useSelector(getRollingStockID); const [postSearch] = osrdEditoastApi.endpoints.postSearch.useMutation(); const [postPathfinding] = osrdEditoastApi.endpoints.postPathfinding.useMutation(); const { t } = useTranslation('operationalStudies/manageTrainSchedule'); + const osrdActions = useOsrdConfActions(); const debouncedInputText = useDebounce(inputText.trimEnd(), 500); @@ -122,7 +128,7 @@ export default function TypeAndPath({ zoomToFeature }: PathfindingProps) { .unwrap() .then((itineraryCreated: PathResponse) => { zoomToFeature(bbox(itineraryCreated.geographic)); - loadPathFinding(itineraryCreated, dispatch); + loadPathFinding(itineraryCreated, dispatch, osrdActions); }) .catch((e) => { dispatch( diff --git a/front/src/common/ScenarioExplorer/ScenarioExplorer.tsx b/front/src/common/ScenarioExplorer/ScenarioExplorer.tsx index 6c935c89f16..4997df45f0e 100644 --- a/front/src/common/ScenarioExplorer/ScenarioExplorer.tsx +++ b/front/src/common/ScenarioExplorer/ScenarioExplorer.tsx @@ -1,19 +1,20 @@ import React, { useEffect, useState } from 'react'; -import { useModal } from 'common/BootstrapSNCF/ModalSNCF'; -import infraIcon from 'assets/pictures/components/tracks.svg'; -import scenarioIcon from 'assets/pictures/home/operationalStudies.svg'; -import projectIcon from 'assets/pictures/views/projects.svg'; -import studyIcon from 'assets/pictures/views/study.svg'; import { useTranslation } from 'react-i18next'; import { MdTrain } from 'react-icons/md'; import { useDispatch, useSelector } from 'react-redux'; -import { updateInfraID, updateTimetableID } from 'reducers/osrdconf'; -import { TrainScheduleSummary, osrdEditoastApi } from 'common/api/osrdEditoastApi'; + +import studyIcon from 'assets/pictures/views/study.svg'; +import projectIcon from 'assets/pictures/views/projects.svg'; +import infraIcon from 'assets/pictures/components/tracks.svg'; +import scenarioIcon from 'assets/pictures/home/operationalStudies.svg'; + import { getDocument } from 'common/api/documentApi'; -import { getTimetableID } from 'reducers/osrdconf/selectors'; -import { useOsrdConfContext } from 'common/osrdConfContext'; -import ScenarioExplorerModal from './ScenarioExplorerModal'; -import { ScenarioExplorerProps } from './ScenarioExplorerTypes'; +import { useModal } from 'common/BootstrapSNCF/ModalSNCF'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; +import type { TrainScheduleSummary } from 'common/api/osrdEditoastApi'; +import ScenarioExplorerModal from 'common/ScenarioExplorer/ScenarioExplorerModal'; +import type { ScenarioExplorerProps } from 'common/ScenarioExplorer/ScenarioExplorerTypes'; export default function ScenarioExplorer({ globalProjectId, @@ -23,11 +24,9 @@ export default function ScenarioExplorer({ const { t } = useTranslation('common/scenarioExplorer'); const dispatch = useDispatch(); const { openModal } = useModal(); + const { getTimetableID } = useOsrdConfSelectors(); const timetableID = useSelector(getTimetableID); const [imageUrl, setImageUrl] = useState(); - const { - slice: { actions: osrdConfActions }, - } = useOsrdConfContext(); const { data: projectDetails } = osrdEditoastApi.useGetProjectsByProjectIdQuery( { projectId: globalProjectId as number }, @@ -54,6 +53,8 @@ export default function ScenarioExplorer({ { skip: !timetableID } ); + const { updateInfraID, updateTimetableID } = useOsrdConfActions(); + const getProjectImage = async (imageId: number) => { try { const blobImage = await getDocument(imageId); @@ -74,8 +75,6 @@ export default function ScenarioExplorer({ if (scenarioDetails?.timetable_id) { dispatch(updateTimetableID(scenarioDetails.timetable_id)); dispatch(updateInfraID(scenarioDetails.infra_id)); - // TODO remove when completely separate simulationconf and stdcmconf - dispatch(osrdConfActions.updateInfraID(scenarioDetails.infra_id)); } }, [scenarioDetails]); diff --git a/front/src/common/ScenarioExplorer/ScenarioExplorerModalScenarioMiniCard.tsx b/front/src/common/ScenarioExplorer/ScenarioExplorerModalScenarioMiniCard.tsx index 73cbc8d01b1..61e7ddf7afb 100644 --- a/front/src/common/ScenarioExplorer/ScenarioExplorerModalScenarioMiniCard.tsx +++ b/front/src/common/ScenarioExplorer/ScenarioExplorerModalScenarioMiniCard.tsx @@ -1,15 +1,10 @@ -import cx from 'classnames'; import React, { useContext } from 'react'; import { useDispatch } from 'react-redux'; +import cx from 'classnames'; + +import { useOsrdConfActions } from 'common/osrdContext'; import { ModalContext } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; -import { - updateInfraID, - updateProjectID, - updateScenarioID, - updateStudyID, - updateTimetableID, -} from 'reducers/osrdconf'; -import { MiniCardsScenarioProps } from './ScenarioExplorerTypes'; +import { MiniCardsScenarioProps } from 'common/ScenarioExplorer/ScenarioExplorerTypes'; export default function ScenarioMiniCard({ scenario, @@ -20,6 +15,8 @@ export default function ScenarioMiniCard({ }: MiniCardsScenarioProps) { const dispatch = useDispatch(); const { closeModal } = useContext(ModalContext); + const { updateInfraID, updateProjectID, updateScenarioID, updateStudyID, updateTimetableID } = + useOsrdConfActions(); const selectScenario = () => { setSelectedID(scenario.id); dispatch(updateProjectID(projectID)); diff --git a/front/src/common/SpeedLimitByTagSelector/SpeedLimitByTagSelector.tsx b/front/src/common/SpeedLimitByTagSelector/SpeedLimitByTagSelector.tsx index 2c02b9b2e19..95c8daeb44f 100644 --- a/front/src/common/SpeedLimitByTagSelector/SpeedLimitByTagSelector.tsx +++ b/front/src/common/SpeedLimitByTagSelector/SpeedLimitByTagSelector.tsx @@ -1,17 +1,20 @@ -import React, { ComponentType, useEffect, useMemo } from 'react'; +import React, { useEffect, useMemo } from 'react'; +import type { ComponentType } from 'react'; +import type { Dispatch } from 'redux'; import { useDispatch, useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; -import { Dispatch } from 'redux'; +import type { FetchBaseQueryError } from '@reduxjs/toolkit/query/react'; import { isEmpty, noop } from 'lodash'; -import { FetchBaseQueryError } from '@reduxjs/toolkit/query/react'; -import { setFailure } from 'reducers/main'; -import { updateSpeedLimitByTag } from 'reducers/osrdconf'; -import { getInfraID, getSpeedLimitByTag } from 'reducers/osrdconf/selectors'; -import SelectImprovedSNCF from 'common/BootstrapSNCF/SelectImprovedSNCF'; -import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; import icon from 'assets/pictures/components/speedometer.svg'; -import './SpeedLimitByTagSelector.scss'; + +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import { useInfraID, useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; +import SelectImprovedSNCF from 'common/BootstrapSNCF/SelectImprovedSNCF'; + +import { setFailure } from 'reducers/main'; + +import 'common/SpeedLimitByTagSelector/SpeedLimitByTagSelector.scss'; type SpeedLimitByTagSelectorProps = { t?: (key: string) => string; @@ -25,7 +28,8 @@ function withOSRDInfraData(Component: ComponentType) { return (hocProps: T) => { const { t } = useTranslation(['operationalStudies/manageTrainSchedule']); const dispatch = useDispatch(); - const infraID = useSelector(getInfraID); + const { getSpeedLimitByTag } = useOsrdConfSelectors(); + const infraID = useInfraID(); const speedLimitByTag = useSelector(getSpeedLimitByTag); const { data: speedLimitsByTags = [], error } = osrdEditoastApi.useGetInfraByIdSpeedLimitTagsQuery( @@ -34,6 +38,7 @@ function withOSRDInfraData(Component: ComponentType) { }, { skip: !infraID } ); + const { updateSpeedLimitByTag } = useOsrdConfActions(); const dispatchUpdateSpeedLimitByTag = (newTag: string) => { dispatch(updateSpeedLimitByTag(newTag)); }; diff --git a/front/src/common/osrdConfContext.tsx b/front/src/common/osrdConfContext.tsx deleted file mode 100644 index 84e706b0c61..00000000000 --- a/front/src/common/osrdConfContext.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React, { createContext, useContext, useMemo } from 'react'; -import { simulationConfSliceType } from 'reducers/osrdconf2/simulationConf'; -import { simulationConfSelectorsType } from 'reducers/osrdconf2/simulationConf/selectors'; -import { stdcmConfSliceType } from 'reducers/osrdconf2/stdcmConf'; -import { stdcmConfSelectorsType } from 'reducers/osrdconf2/stdcmConf/selectors'; -import { ModalProvider } from './BootstrapSNCF/ModalSNCF/ModalProvider'; - -export type OsrdConfType = { - slice: simulationConfSliceType | stdcmConfSliceType; - selectors: simulationConfSelectorsType | stdcmConfSelectorsType; -} | null; - -const OsrdConfContext = createContext(null); - -export const useOsrdConfContext = () => { - const context = useContext(OsrdConfContext); - if (!context) { - throw new Error('useOsrdConfContext must be used within a OsrdConfContext.Provider'); - } - return context; -}; - -type Props = { - slice: NonNullable['slice']; - selectors: NonNullable['selectors']; -}; -export const OsrdConfContextLayout = ({ slice, selectors }: Props) => { - const value = useMemo(() => ({ slice, selectors }), [slice, selectors]); - return ( - - - - ); -}; - -export default OsrdConfContext; diff --git a/front/src/common/osrdContext.tsx b/front/src/common/osrdContext.tsx new file mode 100644 index 00000000000..a01fcf1531a --- /dev/null +++ b/front/src/common/osrdContext.tsx @@ -0,0 +1,128 @@ +import React, { createContext, useContext, useMemo } from 'react'; + +import type { ObjectFieldsTypes } from 'utils/types'; + +import { MODES } from 'applications/operationalStudies/consts'; + +import { ModalProvider } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; + +import type { OsrdSlice } from 'reducers'; +import type { EditorSelectors } from 'reducers/editor/selectors'; +import type { MapViewerSelectors } from 'reducers/mapViewer/selectors'; +import type { StdcmConfSliceActions } from 'reducers/osrdconf/stdcmConf'; +import type { StdcmConfSelectors } from 'reducers/osrdconf/stdcmConf/selectors'; +import type { OperationalStudiesConfSliceActions } from 'reducers/osrdconf/operationalStudiesConf'; +import type { OperationalStudiesConfSelectors } from 'reducers/osrdconf/operationalStudiesConf/selectors'; +import { useSelector } from 'react-redux'; + +export type OsrdSelectors = + | OperationalStudiesConfSelectors + | StdcmConfSelectors + | MapViewerSelectors + | EditorSelectors; + +export type OsrdContextType = { + slice: OsrdSlice; + selectors: OsrdSelectors; + mode: ObjectFieldsTypes; + isStdcm: boolean; + isSimulation: boolean; +} | null; + +const OsrdContext = createContext(null); + +export const useOsrdContext = () => { + const context = useContext(OsrdContext); + if (!context) { + throw new Error('useOsrdContext must be used within a OsrdContext.Provider'); + } + return context; +}; + +export const useOsrdActions = () => { + const { slice } = useOsrdContext(); + if (!slice) { + throw new Error('OsrdContext slice is not available'); + } + + if (!slice.actions) { + throw new Error('OsrdContext slice does not have actions'); + } + + return slice.actions; +}; + +export const useOsrdConfActions = () => { + const { slice } = useOsrdContext(); + + if (!slice) { + throw new Error('OsrdContext slice is not available'); + } + + if (!slice.actions) { + throw new Error('OsrdContext slice does not have actions'); + } + + return slice.actions as StdcmConfSliceActions | OperationalStudiesConfSliceActions; +}; + +export const useOsrdSelectors = () => { + const { selectors } = useOsrdContext(); + if (!selectors) { + throw new Error('OsrdContext selectors are not available'); + } + + return selectors; +}; + +export const useOsrdConfSelectors = () => { + const { selectors } = useOsrdContext(); + if (!selectors) { + throw new Error('OsrdContext selectors are not available'); + } + + return selectors as StdcmConfSelectors | OperationalStudiesConfSelectors; +}; + +export const useInfraID = () => { + const { selectors } = useOsrdContext(); + if (!selectors) { + throw new Error('OsrdContext selectors are not available'); + } + + const infraId = useSelector(selectors.getInfraID); + return infraId; +}; + +export const useUpdateInfraID = () => { + const { slice } = useOsrdContext(); + if (!slice) { + throw new Error('OsrdContext slice is not available'); + } + + if (!slice.actions) { + throw new Error('OsrdContext slice does not have actions'); + } + + return slice.actions.updateInfraID; +}; + +type OsrdContextLayoutProps = { + slice: NonNullable['slice']; + selectors: NonNullable['selectors']; + mode: ObjectFieldsTypes; +}; + +export const OsrdContextLayout = ({ slice, selectors, mode }: OsrdContextLayoutProps) => { + const isStdcm = mode === MODES.stdcm; + const isSimulation = mode === MODES.simulation; + const value = useMemo( + () => ({ slice, selectors, mode, isStdcm, isSimulation }), + [slice, selectors] + ); + return ( + + + + ); +}; diff --git a/front/src/main/app.jsx b/front/src/main/app.jsx index 2ad3c83f1e5..0287455043e 100644 --- a/front/src/main/app.jsx +++ b/front/src/main/app.jsx @@ -2,24 +2,33 @@ import React, { Suspense, useEffect } from 'react'; import { useDispatch } from 'react-redux'; import { createBrowserRouter, RouterProvider } from 'react-router-dom'; import 'i18n'; -import { updateLastInterfaceVersion } from 'reducers/main'; +import Home from 'main/home'; +import Loader from 'common/Loader'; import useAuth from 'utils/hooks/OsrdAuth'; +import ErrorBoundary from 'common/ErrorBoundary'; +import { OsrdContextLayout } from 'common/osrdContext'; +import { NotificationsState } from 'common/Notifications'; + +import HomeStdcm from 'applications/stdcm/Home'; import HomeEditor from 'applications/editor/Home'; import HomeMap from 'applications/referenceMap/Home'; -import HomeOperationalStudies from 'applications/operationalStudies/Home'; -import HomeStdcm from 'applications/stdcm/Home'; -import Loader from 'common/Loader'; -import Home from 'main/home'; -import { NotificationsState } from 'common/Notifications'; -import Project from 'applications/operationalStudies/views/Project'; +import { MODES } from 'applications/operationalStudies/consts'; import Study from 'applications/operationalStudies/views/Study'; +import Project from 'applications/operationalStudies/views/Project'; import Scenario from 'applications/operationalStudies/views/Scenario'; +import HomeOperationalStudies from 'applications/operationalStudies/Home'; import HomeRollingStockEditor from 'applications/rollingStockEditor/Home'; -import { OsrdConfContextLayout } from 'common/osrdConfContext'; -import { simulationConfSlice, simulationConfSliceActions } from 'reducers/osrdconf2/simulationConf'; -import { stdcmConfSlice, stdcmConfSliceActions } from 'reducers/osrdconf2/stdcmConf'; -import ErrorBoundary from 'common/ErrorBoundary'; + +import { editorSlice } from 'reducers/editor'; +import { mapViewerSlice } from 'reducers/mapViewer'; +import editorSelectors from 'reducers/editor/selectors'; +import { updateLastInterfaceVersion } from 'reducers/main'; +import { stdcmConfSlice } from 'reducers/osrdconf/stdcmConf'; +import mapViewerSelectors from 'reducers/mapViewer/selectors'; +import stdcmConfSelectors from 'reducers/osrdconf/stdcmConf/selectors'; +import { operationalStudiesConfSlice } from 'reducers/osrdconf/operationalStudiesConf'; +import simulationConfSelectors from 'reducers/osrdconf/operationalStudiesConf/selectors'; import('@sncf/bootstrap-sncf.metier.reseau/dist/css/bootstrap-sncf.min.css'); @@ -30,15 +39,32 @@ const router = createBrowserRouter([ }, { path: 'map/*', - element: , + element: ( + + ), + children: [{ path: '*', element: }], }, { path: 'editor/*', - element: , + element: ( + + ), + children: [ + { + path: '*', + element: , + }, + ], }, { path: 'stdcm/*', - element: , + element: ( + + ), children: [ { path: '*', @@ -53,7 +79,11 @@ const router = createBrowserRouter([ { path: 'operational-studies/', element: ( - + ), errorElement: , children: [ @@ -89,7 +119,6 @@ export default function App() { dispatch(updateLastInterfaceVersion(import.meta.env.OSRD_GIT_DESCRIBE)); }, []); const { isUserLogged } = useAuth(); - return ( }> diff --git a/front/src/modules/project/components/AddOrEditProjectModal.tsx b/front/src/modules/project/components/AddOrEditProjectModal.tsx index 5cc20030a3b..22056012bd8 100644 --- a/front/src/modules/project/components/AddOrEditProjectModal.tsx +++ b/front/src/modules/project/components/AddOrEditProjectModal.tsx @@ -1,29 +1,34 @@ import React, { useContext, useEffect, useState } from 'react'; -import ChipsSNCF from 'common/BootstrapSNCF/ChipsSNCF'; -import InputSNCF from 'common/BootstrapSNCF/InputSNCF'; -import ModalBodySNCF from 'common/BootstrapSNCF/ModalSNCF/ModalBodySNCF'; -import ModalFooterSNCF from 'common/BootstrapSNCF/ModalSNCF/ModalFooterSNCF'; -import ModalHeaderSNCF from 'common/BootstrapSNCF/ModalSNCF/ModalHeaderSNCF'; -import { ModalContext } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; -import TextareaSNCF from 'common/BootstrapSNCF/TextareaSNCF'; +import { useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; +import { useDispatch, useSelector } from 'react-redux'; +import { FaPlus } from 'react-icons/fa'; import { BiTargetLock } from 'react-icons/bi'; import { GoPencil, GoTrash } from 'react-icons/go'; -import { FaPlus } from 'react-icons/fa'; -import { MdBusinessCenter, MdDescription, MdTitle } from 'react-icons/md'; import { RiMoneyEuroCircleLine } from 'react-icons/ri'; +import { MdBusinessCenter, MdDescription, MdTitle } from 'react-icons/md'; import { ReactMarkdown } from 'react-markdown/lib/react-markdown'; -import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom'; -import { setFailure, setSuccess } from 'reducers/main'; -import { updateProjectID } from 'reducers/osrdconf'; +import { SerializedError } from '@reduxjs/toolkit'; import remarkGfm from 'remark-gfm'; + import { useDebounce } from 'utils/helpers'; -import { ProjectCreateForm, ProjectWithStudies, osrdEditoastApi } from 'common/api/osrdEditoastApi'; -import { postDocument } from 'common/api/documentApi'; + import PictureUploader from 'applications/operationalStudies/components/Project/PictureUploader'; + +import { useOsrdConfActions } from 'common/osrdContext'; +import { postDocument } from 'common/api/documentApi'; +import ChipsSNCF from 'common/BootstrapSNCF/ChipsSNCF'; +import InputSNCF from 'common/BootstrapSNCF/InputSNCF'; import type { ApiError } from 'common/api/baseGeneratedApis'; -import { SerializedError } from '@reduxjs/toolkit'; +import TextareaSNCF from 'common/BootstrapSNCF/TextareaSNCF'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import ModalBodySNCF from 'common/BootstrapSNCF/ModalSNCF/ModalBodySNCF'; +import ModalFooterSNCF from 'common/BootstrapSNCF/ModalSNCF/ModalFooterSNCF'; +import ModalHeaderSNCF from 'common/BootstrapSNCF/ModalSNCF/ModalHeaderSNCF'; +import { ModalContext } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; +import type { ProjectWithStudies, ProjectCreateForm } from 'common/api/osrdEditoastApi'; + +import { setFailure, setSuccess } from 'reducers/main'; import { getUserSafeWord } from 'reducers/user/userSelectors'; const emptyProject: ProjectCreateForm = { @@ -64,6 +69,8 @@ export default function AddOrEditProjectModal({ const [patchProject] = osrdEditoastApi.endpoints.patchProjectsByProjectId.useMutation(); const [deleteProject] = osrdEditoastApi.endpoints.deleteProjectsByProjectId.useMutation(); + const { updateProjectID } = useOsrdConfActions(); + const removeTag = (idx: number) => { if (!currentProject.tags) return; const newTags = Array.from(currentProject.tags); diff --git a/front/src/modules/rollingStock/components/RollingStockCard/RollingStockCardButtons.tsx b/front/src/modules/rollingStock/components/RollingStockCard/RollingStockCardButtons.tsx index 2d51054293e..b6f0732a143 100644 --- a/front/src/modules/rollingStock/components/RollingStockCard/RollingStockCardButtons.tsx +++ b/front/src/modules/rollingStock/components/RollingStockCard/RollingStockCardButtons.tsx @@ -2,17 +2,13 @@ import React, { useContext, useEffect, useMemo, useState } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { useTranslation } from 'react-i18next'; +import { comfort2pictogram } from 'modules/rollingStock/components/RollingStockSelector/RollingStockHelpers'; + +import type { Comfort } from 'common/api/osrdEditoastApi'; +import OptionsSNCF from 'common/BootstrapSNCF/OptionsSNCF'; +import type { Option } from 'common/BootstrapSNCF/OptionsSNCF'; +import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; import { ModalContext } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; -import OptionsSNCF, { Option } from 'common/BootstrapSNCF/OptionsSNCF'; -import { - updatePathfindingID, - updatePowerRestrictionRanges, - updateRollingStockComfort, - updateRollingStockID, -} from 'reducers/osrdconf'; -import { getRollingStockComfort } from 'reducers/osrdconf/selectors'; -import { useOsrdConfContext } from 'common/osrdConfContext'; -import { comfort2pictogram } from '../RollingStockSelector/RollingStockHelpers'; interface RollingStockCardButtonsProps { id: number; @@ -28,16 +24,21 @@ const RollingStockCardButtons = ({ const dispatch = useDispatch(); const { t } = useTranslation(['rollingstock']); const { closeModal } = useContext(ModalContext); - const { - slice: { actions: osrdConfActions }, - } = useOsrdConfContext(); + + const { getRollingStockComfort } = useOsrdConfSelectors(); const rollingStockComfort = useSelector(getRollingStockComfort); const [comfort, setComfort] = useState('STANDARD'); + const { + updatePathfindingID, + updatePowerRestrictionRanges, + updateRollingStockComfort, + updateRollingStockID, + } = useOsrdConfActions(); + const selectRollingStock = () => { setOpenedRollingStockCardId(undefined); - dispatch(updateRollingStockComfort(comfort)); - dispatch(osrdConfActions.updateRollingStockID(id)); + dispatch(updateRollingStockComfort(comfort as Comfort)); dispatch(updateRollingStockID(id)); dispatch(updatePowerRestrictionRanges([])); dispatch(updatePathfindingID(undefined)); diff --git a/front/src/modules/rollingStock/components/RollingStockSelector/RollingStockModal.tsx b/front/src/modules/rollingStock/components/RollingStockSelector/RollingStockModal.tsx index 75a0b11cfe9..06c008ed5c5 100644 --- a/front/src/modules/rollingStock/components/RollingStockSelector/RollingStockModal.tsx +++ b/front/src/modules/rollingStock/components/RollingStockSelector/RollingStockModal.tsx @@ -1,16 +1,19 @@ -import React, { useState, useEffect, useContext, useMemo, MutableRefObject } from 'react'; +import React, { useState, useEffect, useContext, useMemo } from 'react'; +import type { MutableRefObject } from 'react'; import { useSelector, useDispatch } from 'react-redux'; -import { setFailure } from 'reducers/main'; import { useTranslation } from 'react-i18next'; -import { LightRollingStockWithLiveries } from 'common/api/osrdEditoastApi'; -import { enhancedEditoastApi } from 'common/api/enhancedEditoastApi'; -import { getRollingStockID } from 'reducers/osrdconf/selectors'; +import RollingStockCard from 'modules/rollingStock/components/RollingStockCard/RollingStockCard'; +import SearchRollingStock from 'modules/rollingStock/components/RollingStockSelector/SearchRollingStock'; + import Loader from 'common/Loader'; +import { useOsrdConfSelectors } from 'common/osrdContext'; +import { enhancedEditoastApi } from 'common/api/enhancedEditoastApi'; import ModalBodySNCF from 'common/BootstrapSNCF/ModalSNCF/ModalBodySNCF'; import { ModalContext } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; -import RollingStockCard from 'modules/rollingStock/components/RollingStockCard/RollingStockCard'; -import SearchRollingStock from './SearchRollingStock'; +import type { LightRollingStockWithLiveries } from 'common/api/osrdEditoastApi'; + +import { setFailure } from 'reducers/main'; interface RollingStockModal { ref2scroll: MutableRefObject; @@ -18,6 +21,7 @@ interface RollingStockModal { function RollingStockModal({ ref2scroll }: RollingStockModal) { const dispatch = useDispatch(); + const { getRollingStockID } = useOsrdConfSelectors(); const rollingStockID = useSelector(getRollingStockID); const { t } = useTranslation(['translation', 'rollingstock']); const [isLoading, setIsLoading] = useState(true); diff --git a/front/src/modules/rollingStock/components/RollingStockSelector/WithRollingStockSelector.tsx b/front/src/modules/rollingStock/components/RollingStockSelector/WithRollingStockSelector.tsx index 189397384cd..dfa486e6084 100644 --- a/front/src/modules/rollingStock/components/RollingStockSelector/WithRollingStockSelector.tsx +++ b/front/src/modules/rollingStock/components/RollingStockSelector/WithRollingStockSelector.tsx @@ -1,10 +1,14 @@ -import React, { ComponentType, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; -import { getRollingStockID, getRollingStockComfort } from 'reducers/osrdconf/selectors'; -import { RollingStockWithLiveries, osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import React, { useEffect, useState } from 'react'; +import type { ComponentType } from 'react'; import { useTranslation } from 'react-i18next'; +import { useSelector } from 'react-redux'; + import RollingStock2Img from 'modules/rollingStock/components/RollingStock2Img'; -import RollingStockSelector from './RollingStockSelector'; +import RollingStockSelector from 'modules/rollingStock/components/RollingStockSelector/RollingStockSelector'; + +import { useOsrdConfSelectors } from 'common/osrdContext'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import type { RollingStockWithLiveries } from 'common/api/osrdEditoastApi'; const WithRollingStockSelector = (Component: ComponentType) => @@ -14,6 +18,8 @@ const WithRollingStockSelector = const [rollingStockSelected, setRollingStockSelected] = useState< RollingStockWithLiveries | undefined >(); + + const { getRollingStockID, getRollingStockComfort } = useOsrdConfSelectors(); const rollingStockId = useSelector(getRollingStockID); const rollingStockComfort: string = useSelector(getRollingStockComfort); const comfort = t('rollingstock:comfort'); diff --git a/front/src/modules/scenario/components/AddOrEditScenarioModal.tsx b/front/src/modules/scenario/components/AddOrEditScenarioModal.tsx index ae3a35228cd..efaa209d7a0 100644 --- a/front/src/modules/scenario/components/AddOrEditScenarioModal.tsx +++ b/front/src/modules/scenario/components/AddOrEditScenarioModal.tsx @@ -4,23 +4,25 @@ import { GoPencil, GoTrash } from 'react-icons/go'; import { FaPlus } from 'react-icons/fa'; import { GiElectric } from 'react-icons/gi'; import { MdDescription, MdTitle } from 'react-icons/md'; -import { useDispatch, useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import { useNavigate, useParams } from 'react-router-dom'; import { sortBy } from 'lodash'; import ChipsSNCF from 'common/BootstrapSNCF/ChipsSNCF'; import InputSNCF from 'common/BootstrapSNCF/InputSNCF'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import TextareaSNCF from 'common/BootstrapSNCF/TextareaSNCF'; +import { useInfraID, useOsrdConfActions } from 'common/osrdContext'; +import SelectImprovedSNCF from 'common/BootstrapSNCF/SelectImprovedSNCF'; import ModalBodySNCF from 'common/BootstrapSNCF/ModalSNCF/ModalBodySNCF'; +import InfraSelectorModal from 'common/InfraSelector/InfraSelectorModal'; import ModalFooterSNCF from 'common/BootstrapSNCF/ModalSNCF/ModalFooterSNCF'; import ModalHeaderSNCF from 'common/BootstrapSNCF/ModalSNCF/ModalHeaderSNCF'; import { ModalContext } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; -import SelectImprovedSNCF from 'common/BootstrapSNCF/SelectImprovedSNCF'; -import TextareaSNCF from 'common/BootstrapSNCF/TextareaSNCF'; -import InfraSelectorModal from 'common/InfraSelector/InfraSelectorModal'; -import { osrdEditoastApi, ScenarioCreateForm, ScenarioPatchForm } from 'common/api/osrdEditoastApi'; +import type { ScenarioCreateForm, ScenarioPatchForm } from 'common/api/osrdEditoastApi'; + import { setFailure, setSuccess } from 'reducers/main'; -import { updateScenarioID } from 'reducers/osrdconf'; -import { getInfraID } from 'reducers/osrdconf/selectors'; +import type { OperationalStudiesConfSliceActions } from 'reducers/osrdconf/operationalStudiesConf'; type CreateOrPatchScenarioForm = ScenarioPatchForm & { id?: number; @@ -81,7 +83,7 @@ export default function AddOrEditScenarioModal({ const [displayErrors, setDisplayErrors] = useState(false); const dispatch = useDispatch(); const navigate = useNavigate(); - const infraID = useSelector(getInfraID); + const infraID = useInfraID(); const selectedValue = useMemo(() => { if (currentScenario.electrical_profile_set_id) { @@ -95,6 +97,8 @@ export default function AddOrEditScenarioModal({ type ElectricalProfileSetType = { id: number; name: string }; + const { updateScenarioID } = useOsrdConfActions() as OperationalStudiesConfSliceActions; + const removeTag = (idx: number) => { const newTags = currentScenario.tags ? Array.from(currentScenario.tags) : []; newTags.splice(idx, 1); diff --git a/front/src/modules/scenario/components/ScenarioCard.tsx b/front/src/modules/scenario/components/ScenarioCard.tsx index 62dc392265d..110a0d43df8 100644 --- a/front/src/modules/scenario/components/ScenarioCard.tsx +++ b/front/src/modules/scenario/components/ScenarioCard.tsx @@ -1,27 +1,33 @@ import React from 'react'; +import { useDispatch } from 'react-redux'; import { useTranslation } from 'react-i18next'; +import { MdTrain } from 'react-icons/md'; +import { FcCalendar } from 'react-icons/fc'; import { useNavigate } from 'react-router-dom'; -import { RiFolderChartLine } from 'react-icons/ri'; -import infraLogo from 'assets/pictures/components/tracks.svg'; import { AiFillFolderOpen } from 'react-icons/ai'; +import { RiFolderChartLine } from 'react-icons/ri'; +import nextId from 'react-id-generator'; + import { dateTimeFormatting } from 'utils/date'; -import { useDispatch } from 'react-redux'; -import { updateScenarioID } from 'reducers/osrdconf'; + +import infraLogo from 'assets/pictures/components/tracks.svg'; + +import { useOsrdConfActions } from 'common/osrdContext'; +import type { ScenarioWithCountTrains } from 'common/api/osrdEditoastApi'; + import { updateSelectedProjection } from 'reducers/osrdsimulation/actions'; -import { FcCalendar } from 'react-icons/fc'; -import { MdTrain } from 'react-icons/md'; -import nextId from 'react-id-generator'; -import { ScenarioWithCountTrains } from 'common/api/osrdEditoastApi'; +import type { OperationalStudiesConfSliceActions } from 'reducers/osrdconf/operationalStudiesConf'; -type Props = { +type StudyCardProps = { setFilterChips: (filterChips: string) => void; scenario: ScenarioWithCountTrains; }; -export default function StudyCard({ setFilterChips, scenario }: Props) { +export default function StudyCard({ setFilterChips, scenario }: StudyCardProps) { const { t } = useTranslation('operationalStudies/study'); const navigate = useNavigate(); const dispatch = useDispatch(); + const { updateScenarioID } = useOsrdConfActions() as OperationalStudiesConfSliceActions; const handleClick = () => { dispatch(updateScenarioID(scenario.id)); diff --git a/front/src/modules/simulationResult/components/SimulationResultsMap.tsx b/front/src/modules/simulationResult/components/SimulationResultsMap.tsx index 63548e3219b..9f98a051b0c 100644 --- a/front/src/modules/simulationResult/components/SimulationResultsMap.tsx +++ b/front/src/modules/simulationResult/components/SimulationResultsMap.tsx @@ -1,44 +1,52 @@ -import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useParams } from 'react-router-dom'; -import { MapLayerMouseEvent } from 'maplibre-gl'; +import type { MapLayerMouseEvent } from 'maplibre-gl'; import WebMercatorViewport from 'viewport-mercator-project'; -import ReactMapGL, { AttributionControl, MapRef, ScaleControl } from 'react-map-gl/maplibre'; -import { Feature, LineString } from 'geojson'; -import { BBox, lineString, point } from '@turf/helpers'; +import ReactMapGL, { AttributionControl, ScaleControl } from 'react-map-gl/maplibre'; +import type { MapRef } from 'react-map-gl/maplibre'; +import type { Feature, LineString } from 'geojson'; +import { lineString, point } from '@turf/helpers'; +import type { BBox } from '@turf/helpers'; import bbox from '@turf/bbox'; import lineLength from '@turf/length'; import lineSlice from '@turf/line-slice'; import { keyBy } from 'lodash'; +import type { TrainPosition } from 'modules/simulationResult/components/SimulationResultsMap/types'; + +import type { RootState } from 'reducers'; +import type { Viewport } from 'reducers/map'; +import { updateViewport, updateMapSearchMarker } from 'reducers/map'; +import type { Train } from 'reducers/osrdsimulation/types'; import { getPresentSimulation, getSelectedTrain } from 'reducers/osrdsimulation/selectors'; -import { Train } from 'reducers/osrdsimulation/types'; -import { updateMapSearchMarker, updateViewport, Viewport } from 'reducers/map'; -import { RootState } from 'reducers'; -import { TrainPosition } from 'modules/simulationResult/components/SimulationResultsMap/types'; /* Main data & layers */ import Background from 'common/Map/Layers/Background'; import BufferStops from 'common/Map/Layers/BufferStops'; import VirtualLayers from 'modules/simulationResult/components/SimulationResultsMap/VirtualLayers'; + /* Settings & Buttons */ -import MapButtons from 'common/Map/Buttons/MapButtons'; -import Detectors from 'common/Map/Layers/Detectors'; -import Catenaries from 'common/Map/Layers/Catenaries'; -import NeutralSections from 'common/Map/Layers/NeutralSections'; -import Hillshade from 'common/Map/Layers/Hillshade'; -import OSM from 'common/Map/Layers/OSM'; -import OperationalPoints from 'common/Map/Layers/OperationalPoints'; -import PlatformsLayer from 'common/Map/Layers/Platforms'; import RenderItinerary from 'modules/simulationResult/components/SimulationResultsMap/RenderItinerary'; + +import OSM from 'common/Map/Layers/OSM'; import Routes from 'common/Map/Layers/Routes'; -import SearchMarker from 'common/Map/Layers/SearchMarker'; import Signals from 'common/Map/Layers/Signals'; -import SpeedLimits from 'common/Map/Layers/SpeedLimits'; import Switches from 'common/Map/Layers/Switches'; +import Detectors from 'common/Map/Layers/Detectors'; +import Hillshade from 'common/Map/Layers/Hillshade'; +import Catenaries from 'common/Map/Layers/Catenaries'; +import MapButtons from 'common/Map/Buttons/MapButtons'; +import SpeedLimits from 'common/Map/Layers/SpeedLimits'; +import PlatformsLayer from 'common/Map/Layers/Platforms'; +import SearchMarker from 'common/Map/Layers/SearchMarker'; +import NeutralSections from 'common/Map/Layers/NeutralSections'; +import OperationalPoints from 'common/Map/Layers/OperationalPoints'; + /* Objects & various */ -import TracksGeographic from 'common/Map/Layers/TracksGeographic'; import TracksOSM from 'common/Map/Layers/TracksOSM'; +import TracksGeographic from 'common/Map/Layers/TracksGeographic'; + /* Interactions */ import TrainHoverPosition from 'modules/simulationResult/components/SimulationResultsMap/TrainHoverPosition'; @@ -51,14 +59,16 @@ import { import { LAYER_GROUPS_ORDER, LAYERS } from 'config/layerOrder'; import 'common/Map/Map.scss'; -import SNCF_PSL from 'common/Map/Layers/extensions/SNCF/PSL'; -import IGN_BD_ORTHO from 'common/Map/Layers/IGN_BD_ORTHO'; +import Terrain from 'common/Map/Layers/Terrain'; +import { CUSTOM_ATTRIBUTION } from 'common/Map/const'; +import { useInfraID } from 'common/osrdContext'; import IGN_SCAN25 from 'common/Map/Layers/IGN_SCAN25'; import IGN_CADASTRE from 'common/Map/Layers/IGN_CADASTRE'; -import { CUSTOM_ATTRIBUTION } from 'common/Map/const'; -import { SimulationReport, osrdEditoastApi } from 'common/api/osrdEditoastApi'; -import Terrain from 'common/Map/Layers/Terrain'; +import IGN_BD_ORTHO from 'common/Map/Layers/IGN_BD_ORTHO'; +import SNCF_PSL from 'common/Map/Layers/extensions/SNCF/PSL'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; import { getTerrain3DExaggeration } from 'reducers/map/selectors'; +import type { SimulationReport } from 'common/api/osrdEditoastApi'; import { getRegimeKey, getSimulationHoverPositions } from './SimulationResultsMap/helpers'; import { useChartSynchronizer } from './ChartHelpers/ChartSynchronizer'; @@ -66,7 +76,7 @@ interface MapProps { setExtViewport: (viewport: Viewport) => void; } -const Map: FC = ({ setExtViewport }) => { +const Map = ({ setExtViewport }: MapProps) => { const mapBlankStyle = useMapBlankStyle(); const [mapLoaded, setMapLoaded] = useState(false); const { viewport, mapSearchMarker, mapStyle, showOSM } = useSelector( @@ -110,6 +120,8 @@ const Map: FC = ({ setExtViewport }) => { ); const mapRef = React.useRef(null); + const infraID = useInfraID(); + const zoomToFeature = (boundingBox: BBox) => { const [minLng, minLat, maxLng, maxLat] = boundingBox; const viewportTemp = new WebMercatorViewport({ ...viewport, width: 600, height: 400 }); @@ -295,42 +307,57 @@ const Map: FC = ({ setExtViewport }) => { - + + - = ({ setExtViewport }) => { sourceTable="signals" colors={colors[mapStyle]} layerOrder={LAYER_GROUPS_ORDER[LAYERS.SIGNALS.GROUP]} + infraID={infraID} /> {mapSearchMarker && } diff --git a/front/src/modules/stdcmAllowances/components/StdcmAllowances.tsx b/front/src/modules/stdcmAllowances/components/StdcmAllowances.tsx index f0687ddfbaa..ead1b306191 100644 --- a/front/src/modules/stdcmAllowances/components/StdcmAllowances.tsx +++ b/front/src/modules/stdcmAllowances/components/StdcmAllowances.tsx @@ -1,29 +1,28 @@ import React from 'react'; import { useDispatch, useSelector } from 'react-redux'; - import { useTranslation } from 'react-i18next'; -import InputSNCF from 'common/BootstrapSNCF/InputSNCF'; -import InputGroupSNCF, { InputGroupSNCFValue } from 'common/BootstrapSNCF/InputGroupSNCF'; - -import { - getGridMarginBefore, - getGridMarginAfter, - getStandardStdcmAllowance, -} from 'reducers/osrdconf/selectors'; -import { - updateGridMarginAfter, - updateGridMarginBefore, - updateStdcmStandardAllowance, -} from 'reducers/osrdconf'; -import { StandardAllowance } from 'applications/operationalStudies/consts'; -import { AllowanceValue } from 'common/api/osrdEditoastApi'; import { convertInputStringToNumber } from 'utils/strings'; + +import type { StandardAllowance } from 'applications/operationalStudies/consts'; import { ALLOWANCE_UNITS_KEYS } from 'applications/stdcm/components/allowancesConsts'; +import InputSNCF from 'common/BootstrapSNCF/InputSNCF'; +import InputGroupSNCF from 'common/BootstrapSNCF/InputGroupSNCF'; +import type { AllowanceValue } from 'common/api/osrdEditoastApi'; +import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; +import type { InputGroupSNCFValue } from 'common/BootstrapSNCF/InputGroupSNCF'; + +import type { StdcmConfSliceActions } from 'reducers/osrdconf/stdcmConf'; +import type { StdcmConfSelectors } from 'reducers/osrdconf/stdcmConf/selectors'; + const StdcmAllowances = () => { const { t } = useTranslation('allowances'); const dispatch = useDispatch(); + const { getGridMarginBefore, getGridMarginAfter, getStandardStdcmAllowance } = + useOsrdConfSelectors() as StdcmConfSelectors; + const { updateGridMarginAfter, updateGridMarginBefore, updateStdcmStandardAllowance } = + useOsrdConfActions() as StdcmConfSliceActions; const gridMarginBefore = useSelector(getGridMarginBefore); const gridMarginAfter = useSelector(getGridMarginAfter); const stdcmStandardAllowance = useSelector(getStandardStdcmAllowance); diff --git a/front/src/modules/study/components/AddOrEditStudyModal.tsx b/front/src/modules/study/components/AddOrEditStudyModal.tsx index e83390476db..002daf20f39 100644 --- a/front/src/modules/study/components/AddOrEditStudyModal.tsx +++ b/front/src/modules/study/components/AddOrEditStudyModal.tsx @@ -1,26 +1,34 @@ import React, { useContext, useEffect, useMemo, useState } from 'react'; +import { useDispatch } from 'react-redux'; +import { useTranslation } from 'react-i18next'; +import { useNavigate, useParams } from 'react-router-dom'; +import { FaPlus, FaTasks } from 'react-icons/fa'; +import { GoNote, GoPencil, GoTrash } from 'react-icons/go'; +import { MdBusinessCenter, MdTitle } from 'react-icons/md'; +import { RiCalendarLine, RiMoneyEuroCircleLine, RiQuestionLine } from 'react-icons/ri'; + import studyLogo from 'assets/pictures/views/studies.svg'; + +import { formatDateForInput, getEarliestDate } from 'utils/date'; + +import { STUDY_STATES, studyStates, studyTypes } from 'applications/operationalStudies/consts'; + +import { createSelectOptions } from 'modules/study/utils'; + +import { useOsrdConfActions } from 'common/osrdContext'; import ChipsSNCF from 'common/BootstrapSNCF/ChipsSNCF'; import InputSNCF from 'common/BootstrapSNCF/InputSNCF'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import TextareaSNCF from 'common/BootstrapSNCF/TextareaSNCF'; +import SelectImprovedSNCF from 'common/BootstrapSNCF/SelectImprovedSNCF'; import ModalBodySNCF from 'common/BootstrapSNCF/ModalSNCF/ModalBodySNCF'; +import { ModalContext } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; import ModalFooterSNCF from 'common/BootstrapSNCF/ModalSNCF/ModalFooterSNCF'; import ModalHeaderSNCF from 'common/BootstrapSNCF/ModalSNCF/ModalHeaderSNCF'; -import { ModalContext } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; -import SelectImprovedSNCF from 'common/BootstrapSNCF/SelectImprovedSNCF'; -import TextareaSNCF from 'common/BootstrapSNCF/TextareaSNCF'; -import { useTranslation } from 'react-i18next'; -import { FaPlus, FaTasks } from 'react-icons/fa'; -import { GoNote, GoPencil, GoTrash } from 'react-icons/go'; -import { MdBusinessCenter, MdTitle } from 'react-icons/md'; -import { RiCalendarLine, RiMoneyEuroCircleLine, RiQuestionLine } from 'react-icons/ri'; -import { useDispatch } from 'react-redux'; -import { useNavigate, useParams } from 'react-router-dom'; +import type { StudyCreateForm, StudyWithScenarios } from 'common/api/osrdEditoastApi'; + import { setFailure, setSuccess } from 'reducers/main'; -import { updateStudyID } from 'reducers/osrdconf'; -import { StudyCreateForm, StudyWithScenarios, osrdEditoastApi } from 'common/api/osrdEditoastApi'; -import { STUDY_STATES, studyStates, studyTypes } from 'applications/operationalStudies/consts'; -import { formatDateForInput, getEarliestDate } from 'utils/date'; -import { createSelectOptions } from '../utils'; +import type { OperationalStudiesConfSliceActions } from 'reducers/osrdconf/operationalStudiesConf'; interface StudyForm extends StudyCreateForm { id?: number; @@ -43,6 +51,7 @@ export default function AddOrEditStudyModal({ editionMode, study }: Props) { const [currentStudy, setCurrentStudy] = useState((study as StudyForm) || emptyStudy); const [displayErrors, setDisplayErrors] = useState(false); const { projectId } = useParams() as StudyParams; + const { updateStudyID } = useOsrdConfActions() as OperationalStudiesConfSliceActions; const dispatch = useDispatch(); const navigate = useNavigate(); diff --git a/front/src/modules/study/components/StudyCard.tsx b/front/src/modules/study/components/StudyCard.tsx index 283fc6596e2..30ebad78809 100644 --- a/front/src/modules/study/components/StudyCard.tsx +++ b/front/src/modules/study/components/StudyCard.tsx @@ -1,26 +1,33 @@ import React from 'react'; +import { useDispatch } from 'react-redux'; import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; import nextId from 'react-id-generator'; -import { AiFillFolderOpen } from 'react-icons/ai'; import { FcCalendar } from 'react-icons/fc'; +import { RiFolderChartLine } from 'react-icons/ri'; +import { AiFillFolderOpen } from 'react-icons/ai'; + import studyLogo from 'assets/pictures/views/study.svg'; + import { budgetFormat } from 'utils/numbers'; import { dateTimeFormatting } from 'utils/date'; -import { useDispatch } from 'react-redux'; -import { updateScenarioID, updateStudyID } from 'reducers/osrdconf'; -import { RiFolderChartLine } from 'react-icons/ri'; -import { StudyWithScenarios } from 'common/api/osrdEditoastApi'; -type Props = { +import type { StudyWithScenarios } from 'common/api/osrdEditoastApi'; +import { useOsrdConfActions } from 'common/osrdContext'; + +import type { OperationalStudiesConfSliceActions } from 'reducers/osrdconf/operationalStudiesConf'; + +type StudyCardProps = { setFilterChips: (filterChips: string) => void; study: StudyWithScenarios; }; -export default function StudyCard({ setFilterChips, study }: Props) { +export default function StudyCard({ setFilterChips, study }: StudyCardProps) { const { t } = useTranslation(['operationalStudies/project', 'operationalStudies/study']); const navigate = useNavigate(); const dispatch = useDispatch(); + const { updateScenarioID, updateStudyID } = + useOsrdConfActions() as OperationalStudiesConfSliceActions; const handleClick = () => { dispatch(updateStudyID(study.id)); diff --git a/front/src/modules/trainschedule/components/ImportTrainSchedule/ImportTrainScheduleModal.tsx b/front/src/modules/trainschedule/components/ImportTrainSchedule/ImportTrainScheduleModal.tsx index c606a78ea44..e4f06d0b1d7 100644 --- a/front/src/modules/trainschedule/components/ImportTrainSchedule/ImportTrainScheduleModal.tsx +++ b/front/src/modules/trainschedule/components/ImportTrainSchedule/ImportTrainScheduleModal.tsx @@ -1,33 +1,36 @@ import React, { useEffect, useMemo, useState } from 'react'; +import { useSelector } from 'react-redux'; +import { useTranslation } from 'react-i18next'; +import { compact } from 'lodash'; import cx from 'classnames'; -import ModalBodySNCF from 'common/BootstrapSNCF/ModalSNCF/ModalBodySNCF'; +import { + TrainSchedule, + TrainScheduleWithPath, + TrainScheduleWithPathRef, +} from 'applications/operationalStudies/types'; + import Map from 'modules/trainschedule/components/ImportTrainSchedule/Map'; -import { useTranslation } from 'react-i18next'; -import { useSelector } from 'react-redux'; -import { getRollingStockID } from 'reducers/osrdconf/selectors'; +import type { Point } from 'modules/trainschedule/components/ImportTrainSchedule/types'; +import { refactorUniquePaths } from 'modules/trainschedule/components/ImportTrainSchedule/ImportTrainScheduleHelpers'; import generatePathfindingPayload from 'modules/trainschedule/components/ImportTrainSchedule/generatePathfindingPayload'; import generateTrainSchedulesPayload from 'modules/trainschedule/components/ImportTrainSchedule/generateTrainSchedulesPayload'; import { initialViewport, initialStatus, } from 'modules/trainschedule/components/ImportTrainSchedule/consts'; -import { refactorUniquePaths } from 'modules/trainschedule/components/ImportTrainSchedule/ImportTrainScheduleHelpers'; -import { +import Spacer from 'common/Spacer'; +import { useOsrdSelectors } from 'common/osrdContext'; +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import ModalBodySNCF from 'common/BootstrapSNCF/ModalSNCF/ModalBodySNCF'; +import type { LightRollingStock, PathResponse, TrainScheduleBatchItem, - osrdEditoastApi, } from 'common/api/osrdEditoastApi'; -import { compact } from 'lodash'; -import Spacer from 'common/Spacer'; -import { - TrainSchedule, - TrainScheduleWithPath, - TrainScheduleWithPathRef, -} from 'applications/operationalStudies/types'; -import ImportTrainScheduleModalFooter from './ImportTrainScheduleModalFooter'; -import { Point } from './types'; + +import type { OperationalStudiesConfSelectors } from 'reducers/osrdconf/operationalStudiesConf/selectors'; +import ImportTrainScheduleModalFooter from 'modules/trainschedule/components/ImportTrainSchedule/ImportTrainScheduleModalFooter'; /* METHOD * @@ -72,6 +75,7 @@ const ImportTrainScheduleModal = ({ trains, }: ImportTrainScheduleModalProps) => { const { t } = useTranslation(['operationalStudies/importTrainSchedule']); + const { getRollingStockID } = useOsrdSelectors() as OperationalStudiesConfSelectors; const rollingStockID = useSelector(getRollingStockID); const { refetch: refetchTimetable } = diff --git a/front/src/modules/trainschedule/components/ImportTrainSchedule/Map.tsx b/front/src/modules/trainschedule/components/ImportTrainSchedule/Map.tsx index 5bd9465b06b..37cf9380114 100644 --- a/front/src/modules/trainschedule/components/ImportTrainSchedule/Map.tsx +++ b/front/src/modules/trainschedule/components/ImportTrainSchedule/Map.tsx @@ -1,30 +1,33 @@ import React, { useEffect, useRef, useState } from 'react'; -import ReactMapGL, { - AttributionControl, - ScaleControl, - MapLayerMouseEvent, -} from 'react-map-gl/maplibre'; -import { point as turfPoint } from '@turf/helpers'; import { useSelector } from 'react-redux'; +import type { MapLayerMouseEvent } from 'react-map-gl/maplibre'; +import ReactMapGL, { AttributionControl, ScaleControl } from 'react-map-gl/maplibre'; +import { point as turfPoint } from '@turf/helpers'; import turfNearestPointOnLine, { NearestPointOnLine } from '@turf/nearest-point-on-line'; +import type { LineString } from 'geojson'; /* Main data & layers */ -import Background from 'common/Map/Layers/Background'; import VirtualLayers from 'modules/simulationResult/components/SimulationResultsMap/VirtualLayers'; + +import Background from 'common/Map/Layers/Background'; import SnappedMarker from 'common/Map/Layers/SnappedMarker'; + /* Objects & various */ -import TracksGeographic from 'common/Map/Layers/TracksGeographic'; -import colors from 'common/Map/Consts/colors'; -import { useMapBlankStyle } from 'common/Map/Layers/blankStyle'; +import { getMapMouseEventNearestFeature } from 'utils/mapHelper'; + import { LAYER_GROUPS_ORDER, LAYERS } from 'config/layerOrder'; -import 'common/Map/Map.scss'; -import OperationalPoints from 'common/Map/Layers/OperationalPoints'; -import { Platforms } from 'common/Map/Layers/Platforms'; -import { getMapMouseEventNearestFeature } from 'utils/mapHelper'; +import colors from 'common/Map/Consts/colors'; import { CUSTOM_ATTRIBUTION } from 'common/Map/const'; +import { useInfraID } from 'common/osrdContext'; +import { Platforms } from 'common/Map/Layers/Platforms'; +import { useMapBlankStyle } from 'common/Map/Layers/blankStyle'; +import TracksGeographic from 'common/Map/Layers/TracksGeographic'; +import OperationalPoints from 'common/Map/Layers/OperationalPoints'; + import { getMapStyle } from 'reducers/map/selectors'; -import { LineString } from 'geojson'; + +import 'common/Map/Map.scss'; interface MapProps { viewport: { latitude: number; longitude: number }; @@ -48,6 +51,8 @@ const Map = ({ viewport, setViewport, setClickedFeatureId }: MapProps) => { const mapBlankStyle = useMapBlankStyle(); const mapStyle = useSelector(getMapStyle); + const infraID = useInfraID(); + const [lngLatHover, setLngLatHover] = useState(); const [trackSectionGeoJSON, setTrackSectionGeoJSON] = useState(); const [snappedPoint, setSnappedPoint] = useState(); @@ -126,10 +131,12 @@ const Map = ({ viewport, setViewport, setClickedFeatureId }: MapProps) => { {snappedPoint !== undefined ? : null} diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/Allowances/Allowances.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/Allowances/Allowances.tsx index 9ac25836487..15bcccdbe33 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/Allowances/Allowances.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/Allowances/Allowances.tsx @@ -3,23 +3,29 @@ import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; import { AiOutlineDash } from 'react-icons/ai'; -import { StandardAllowance, osrdEditoastApi, Allowance } from 'common/api/osrdEditoastApi'; -import { updateAllowances } from 'reducers/osrdconf'; -import { getAllowances, getPathfindingID } from 'reducers/osrdconf/selectors'; -import AllowancesStandardSettings from './AllowancesStandardSettings'; -import AllowancesActions from './AllowancesActions'; -import AllowancesList from './AllowancesList'; -import { +import { AllowancesTypes } from 'modules/trainschedule/components/ManageTrainSchedule/Allowances/types'; +import AllowancesList from 'modules/trainschedule/components/ManageTrainSchedule/Allowances/AllowancesList'; +import AllowancesActions from 'modules/trainschedule/components/ManageTrainSchedule/Allowances/AllowancesActions'; +import { initialStandardAllowance } from 'modules/trainschedule/components/ManageTrainSchedule/Allowances/consts'; +import AllowancesLinearView from 'modules/trainschedule/components/ManageTrainSchedule/Allowances/AllowancesLinearView'; +import AllowancesStandardSettings from 'modules/trainschedule/components/ManageTrainSchedule/Allowances/AllowancesStandardSettings'; +import getAllowanceValue, { + fillAllowancesWithDefaultRanges, +} from 'modules/trainschedule/components/ManageTrainSchedule/Allowances/helpers'; +import type { AllowanceValueForm, - AllowancesTypes, EngineeringAllowanceForm, OverlapAllowancesIndexesType, RangeAllowanceForm, StandardAllowanceForm, -} from './types'; -import { initialStandardAllowance } from './consts'; -import getAllowanceValue, { fillAllowancesWithDefaultRanges } from './helpers'; -import AllowancesLinearView from './AllowancesLinearView'; +} from 'modules/trainschedule/components/ManageTrainSchedule/Allowances/types'; + +import { osrdEditoastApi } from 'common/api/osrdEditoastApi'; +import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; +import type { StandardAllowance, Allowance } from 'common/api/osrdEditoastApi'; + +import type { OperationalStudiesConfSliceActions } from 'reducers/osrdconf/operationalStudiesConf'; +import type { OperationalStudiesConfSelectors } from 'reducers/osrdconf/operationalStudiesConf/selectors'; const MissingPathFindingMessage = () => { const { t } = useTranslation('operationalStudies/allowances'); @@ -38,6 +44,8 @@ const ResetButton = ({ resetFunction }: { resetFunction: () => void }) => { export default function Allowances() { const { t } = useTranslation('operationalStudies/allowances'); const dispatch = useDispatch(); + const { getAllowances, getPathfindingID } = + useOsrdConfSelectors() as OperationalStudiesConfSelectors; const pathFindingID = useSelector(getPathfindingID); const { data: pathFinding } = osrdEditoastApi.useGetPathfindingByPathfindingIdQuery( { pathfindingId: pathFindingID as number }, @@ -87,6 +95,8 @@ export default function Allowances() { [standardAllowance] ); + const { updateAllowances } = useOsrdConfActions() as OperationalStudiesConfSliceActions; + const setStandardDistribution = (distribution: StandardAllowance['distribution']) => { setStandardAllowance({ ...standardAllowance, distribution }); }; diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/ElectricalProfiles.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/ElectricalProfiles.tsx index a25d859e458..e3c3b34af9f 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/ElectricalProfiles.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/ElectricalProfiles.tsx @@ -1,16 +1,22 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; -import { toggleUsingElectricalProfiles } from 'reducers/osrdconf'; -import SwitchSNCF, { SWITCH_TYPES } from 'common/BootstrapSNCF/SwitchSNCF/SwitchSNCF'; + import electricalProfilesIcon from 'assets/pictures/components/electricalProfiles.svg'; -import { getUsingElectricalProfiles } from 'reducers/osrdconf/selectors'; +import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; +import SwitchSNCF, { SWITCH_TYPES } from 'common/BootstrapSNCF/SwitchSNCF/SwitchSNCF'; + +import type { OperationalStudiesConfSliceActions } from 'reducers/osrdconf/operationalStudiesConf'; +import type { OperationalStudiesConfSelectors } from 'reducers/osrdconf/operationalStudiesConf/selectors'; export default function ElectricalProfiles() { + const { getUsingElectricalProfiles } = useOsrdConfSelectors() as OperationalStudiesConfSelectors; + const { toggleUsingElectricalProfiles } = + useOsrdConfActions() as OperationalStudiesConfSliceActions; + const dispatch = useDispatch(); const usingElectricalProfiles = useSelector(getUsingElectricalProfiles); const { t } = useTranslation(['operationalStudies/manageTrainSchedule']); - const dispatch = useDispatch(); return (
diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayItinerary/Destination.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayItinerary/Destination.tsx index 83d96c1a102..02a793eb4ea 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayItinerary/Destination.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayItinerary/Destination.tsx @@ -1,18 +1,21 @@ import React from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { Position } from 'geojson'; import { useTranslation } from 'react-i18next'; import { IoFlag } from 'react-icons/io5'; +import type { Position } from 'geojson'; -import { getDestination } from 'reducers/osrdconf/selectors'; -import { updateDestination, updatePathfindingID } from 'reducers/osrdconf'; +import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; + +import type { StdcmConfSliceActions } from 'reducers/osrdconf/stdcmConf'; +import type { StdcmConfSelectors } from 'reducers/osrdconf/stdcmConf/selectors'; interface DestinationProps { zoomToFeaturePoint: (lngLat?: Position, id?: string) => void; } -function Destination(props: DestinationProps) { - const { zoomToFeaturePoint } = props; +function Destination({ zoomToFeaturePoint }: DestinationProps) { + const { getDestination } = useOsrdConfSelectors() as StdcmConfSelectors; + const { updateDestination, updatePathfindingID } = useOsrdConfActions() as StdcmConfSliceActions; const destination = useSelector(getDestination); const dispatch = useDispatch(); diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayItinerary/Origin.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayItinerary/Origin.tsx index 5333a46229f..bccd43b8e6c 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayItinerary/Origin.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayItinerary/Origin.tsx @@ -1,40 +1,43 @@ import React from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { Position } from 'geojson'; +import { useTranslation } from 'react-i18next'; import { RiMapPin2Fill } from 'react-icons/ri'; import { BiLink, BiUnlink } from 'react-icons/bi'; -import { useTranslation } from 'react-i18next'; +import type { Position } from 'geojson'; -import { - updateOrigin, - updateOriginDate, - updateOriginTime, - updateOriginUpperBoundDate, - updateOriginUpperBoundTime, - toggleOriginLinkedBounds, - updatePathfindingID, -} from 'reducers/osrdconf'; -import { - getMode, - getOrigin, - getOriginDate, - getOriginTime, - getOriginLinkedBounds, - getOriginUpperBoundDate, - getOriginUpperBoundTime, -} from 'reducers/osrdconf/selectors'; import { makeEnumBooleans } from 'utils/constants'; -import InputSNCF from 'common/BootstrapSNCF/InputSNCF'; import { MODES } from 'applications/operationalStudies/consts'; +import InputSNCF from 'common/BootstrapSNCF/InputSNCF'; +import { useOsrdConfActions, useOsrdContext, useOsrdConfSelectors } from 'common/osrdContext'; + interface OriginProps { zoomToFeaturePoint: (lngLat?: Position, id?: string) => void; } -function Origin(props: OriginProps) { - const { zoomToFeaturePoint } = props; - const mode = useSelector(getMode); +function Origin({ zoomToFeaturePoint }: OriginProps) { + const { + getOrigin, + getOriginDate, + getOriginTime, + getOriginLinkedBounds, + getOriginUpperBoundDate, + getOriginUpperBoundTime, + } = useOsrdConfSelectors(); + + const { mode } = useOsrdContext(); + + const { + updateOrigin, + updateOriginDate, + updateOriginTime, + updateOriginUpperBoundDate, + updateOriginUpperBoundTime, + toggleOriginLinkedBounds, + updatePathfindingID, + } = useOsrdConfActions(); + const origin = useSelector(getOrigin); const originDate = useSelector(getOriginDate); const originTime = useSelector(getOriginTime); diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayItinerary/Vias.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayItinerary/Vias.tsx index 58a45f6b8fb..48d1942a26b 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayItinerary/Vias.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayItinerary/Vias.tsx @@ -1,16 +1,20 @@ import React from 'react'; import { useSelector } from 'react-redux'; -import { Position } from 'geojson'; import { useTranslation } from 'react-i18next'; +import type { Position } from 'geojson'; + import DisplayVias from 'modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayVias'; -import { getVias } from 'reducers/osrdconf/selectors'; + +import { useOsrdSelectors } from 'common/osrdContext'; + +import type { OperationalStudiesConfSelectors } from 'reducers/osrdconf/operationalStudiesConf/selectors'; interface ViasProps { zoomToFeaturePoint: (lngLat?: Position, id?: string) => void; } -function Vias(props: ViasProps) { - const { zoomToFeaturePoint } = props; +function Vias({ zoomToFeaturePoint }: ViasProps) { + const { getVias } = useOsrdSelectors() as OperationalStudiesConfSelectors; const vias = useSelector(getVias); const { t } = useTranslation(['operationalStudies/manageTrainSchedule']); diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayVias.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayVias.tsx index 44bea1b869f..8e92a94c0f5 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayVias.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayVias.tsx @@ -1,23 +1,25 @@ import React, { useState, useEffect } from 'react'; -import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'; import { useSelector, useDispatch } from 'react-redux'; -import { deleteVias, permuteVias, updateViaStopTime } from 'reducers/osrdconf'; -import InputSNCF from 'common/BootstrapSNCF/InputSNCF'; -import { useDebounce } from 'utils/helpers'; -import { getConf, getVias } from 'reducers/osrdconf/selectors'; +import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'; +import type { Action } from '@reduxjs/toolkit'; import cx from 'classnames'; -import { AnyAction, ThunkAction } from '@reduxjs/toolkit'; import { Position } from 'geojson'; -import { RootState } from 'reducers'; import { formatUicToCi } from 'utils/strings'; +import { useDebounce } from 'utils/helpers'; + +import InputSNCF from 'common/BootstrapSNCF/InputSNCF'; +import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; + type InputStopTimeProps = { index: number; setIndexSelected: (selectedIndex?: number) => void; - dispatchAndRun: (dispatch: ThunkAction) => void; + dispatchAndRun: (action: Action) => void; }; function InputStopTime({ index, setIndexSelected, dispatchAndRun }: InputStopTimeProps) { + const { getVias } = useOsrdConfSelectors(); + const { updateViaStopTime } = useOsrdConfActions(); const vias = useSelector(getVias); const [stopTime, setStopTime] = useState(vias[index].duration || 0); const [firstStart, setFirstStart] = useState(true); @@ -53,12 +55,14 @@ type DisplayViasProps = { }; export default function DisplayVias({ zoomToFeaturePoint }: DisplayViasProps) { + const { getConf, getVias } = useOsrdConfSelectors(); const osrdconf = useSelector(getConf); const dispatch = useDispatch(); const vias = useSelector(getVias); const [indexSelected, setIndexSelected] = useState(undefined); + const { permuteVias, updateViaStopTime, deleteVias } = useOsrdConfActions(); - const dispatchAndRun = (action: ThunkAction) => { + const dispatchAndRun = (action: Action) => { dispatch(action); }; diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/Itinerary.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/Itinerary.tsx index da80b8159b1..c7c4b135f12 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/Itinerary.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/Itinerary.tsx @@ -1,34 +1,32 @@ import React, { useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; import { WebMercatorViewport } from 'viewport-mercator-project'; +import { GoArrowSwitch, GoPlus, GoRocket, GoTrash } from 'react-icons/go'; +import type { Position } from 'geojson'; -import { - clearVias, - replaceVias, - updateDestination, - updateOrigin, - updatePathfindingID, -} from 'reducers/osrdconf'; -import { updateFeatureInfoClick, updateViewport, Viewport } from 'reducers/map'; -import { Position } from 'geojson'; +import Tipped from 'applications/editor/components/Tipped'; import DisplayItinerary from 'modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayItinerary'; import ModalSuggerredVias from 'modules/trainschedule/components/ManageTrainSchedule/Itinerary/ModalSuggeredVias'; -import { getOrigin, getDestination, getVias, getGeojson } from 'reducers/osrdconf/selectors'; -import { getMap } from 'reducers/map/selectors'; import Pathfinding from 'common/Pathfinding/Pathfinding'; -import { useTranslation } from 'react-i18next'; import { useModal } from 'common/BootstrapSNCF/ModalSNCF'; -import { GoArrowSwitch, GoPlus, GoRocket, GoTrash } from 'react-icons/go'; -import Tipped from 'applications/editor/components/Tipped'; import TypeAndPath from 'common/Pathfinding/TypeAndPath'; import { PathResponse } from 'common/api/osrdEditoastApi'; +import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; + +import type { Viewport } from 'reducers/map'; +import { getMap } from 'reducers/map/selectors'; +import { updateViewport } from 'reducers/map'; type ItineraryProps = { path?: PathResponse; }; function Itinerary({ path }: ItineraryProps) { + const { getOrigin, getDestination, getVias, getGeojson } = useOsrdConfSelectors(); + const { replaceVias, updateDestination, updateOrigin, updatePathfindingID, clearVias } = + useOsrdConfActions(); const origin = useSelector(getOrigin); const destination = useSelector(getDestination); const vias = useSelector(getVias); @@ -41,7 +39,7 @@ function Itinerary({ path }: ItineraryProps) { const { t } = useTranslation('operationalStudies/manageTrainSchedule'); const { openModal } = useModal(); - const zoomToFeature = (boundingBox: Position, id = undefined) => { + const zoomToFeature = (boundingBox: Position) => { const [minLng, minLat, maxLng, maxLat] = boundingBox; const viewport = new WebMercatorViewport({ ...map.viewport, width: 600, height: 400 }); @@ -62,10 +60,9 @@ function Itinerary({ path }: ItineraryProps) { zoom: zoom < 5 ? 5 : zoom, }; setExtViewport(newViewport); - if (id) updateFeatureInfoClick(Number(id)); }; - const zoomToFeaturePoint = (lngLat?: Position, id?: string) => { + const zoomToFeaturePoint = (lngLat?: Position) => { if (lngLat) { const newViewport = { ...map.viewport, @@ -74,9 +71,6 @@ function Itinerary({ path }: ItineraryProps) { zoom: 16, }; setExtViewport(newViewport); - if (id) { - updateFeatureInfoClick(Number(id)); - } } }; diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/ModalSuggeredVias.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/ModalSuggeredVias.tsx index 6626e377eeb..7a214902ef0 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/ModalSuggeredVias.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/ModalSuggeredVias.tsx @@ -1,20 +1,24 @@ import React, { useContext } from 'react'; -import { getSuggeredVias, getVias } from 'reducers/osrdconf/selectors'; -import { replaceVias } from 'reducers/osrdconf'; import { useSelector, useDispatch } from 'react-redux'; import { useTranslation } from 'react-i18next'; -import ModalHeaderSNCF from 'common/BootstrapSNCF/ModalSNCF/ModalHeaderSNCF'; -import ModalBodySNCF from 'common/BootstrapSNCF/ModalSNCF/ModalBodySNCF'; -import ModalFooterSNCF from 'common/BootstrapSNCF/ModalSNCF/ModalFooterSNCF'; import { GoDash, GoPlus, GoTrash } from 'react-icons/go'; -import { ModalContext } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; -import { Spinner } from 'common/Loader'; + import type { ArrayElement } from 'utils/types'; + +import { Spinner } from 'common/Loader'; import type { PathResponse, PathWaypoint } from 'common/api/osrdEditoastApi'; import { formatUicToCi } from 'utils/strings'; import cx from 'classnames'; +import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; +import ModalBodySNCF from 'common/BootstrapSNCF/ModalSNCF/ModalBodySNCF'; +import { ModalContext } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider'; +import ModalHeaderSNCF from 'common/BootstrapSNCF/ModalSNCF/ModalHeaderSNCF'; +import ModalFooterSNCF from 'common/BootstrapSNCF/ModalSNCF/ModalFooterSNCF'; + +import type { OperationalStudiesConfSliceActions } from 'reducers/osrdconf/operationalStudiesConf'; +import type { OperationalStudiesConfSelectors } from 'reducers/osrdconf/operationalStudiesConf/selectors'; -type Props = { +type ModalSugerredViasProps = { removeAllVias: () => void; pathfindingInProgress?: boolean; }; @@ -23,12 +27,17 @@ function LoaderPathfindingInProgress() { return ; } -export default function ModalSugerredVias({ removeAllVias, pathfindingInProgress }: Props) { +export default function ModalSugerredVias({ + removeAllVias, + pathfindingInProgress, +}: ModalSugerredViasProps) { + const { replaceVias } = useOsrdConfActions() as OperationalStudiesConfSliceActions; + const { getSuggeredVias, getVias } = useOsrdConfSelectors() as OperationalStudiesConfSelectors; const dispatch = useDispatch(); - const suggeredVias = useSelector(getSuggeredVias) as PathWaypoint[]; const vias = useSelector(getVias); - + const suggeredVias = useSelector(getSuggeredVias) as PathWaypoint[]; const { t } = useTranslation('operationalStudies/manageTrainSchedule'); + const nbVias = suggeredVias ? suggeredVias.length - 1 : 0; const selectedViasTracks = vias.map((via) => via.id); const { closeModal } = useContext(ModalContext); diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/Itinerary.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/Itinerary.tsx index 0ab0c2b4c76..2df1733e903 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/Itinerary.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/Itinerary.tsx @@ -1,17 +1,17 @@ import React from 'react'; -import { Source } from 'react-map-gl/maplibre'; import { useSelector } from 'react-redux'; +import { GeoJSONFeature } from 'maplibre-gl'; +import { Source } from 'react-map-gl/maplibre'; +import { useOsrdConfSelectors } from 'common/osrdContext'; import OrderedLayer from 'common/Map/Layers/OrderedLayer'; -import { getGeojson, getOrigin, getDestination } from 'reducers/osrdconf/selectors'; -import { GeoJSONFeature } from 'maplibre-gl'; interface ItineraryProps { layerOrder: number; } -export default function Itinerary(props: ItineraryProps) { - const { layerOrder } = props; +export default function Itinerary({ layerOrder }: ItineraryProps) { + const { getGeojson, getOrigin, getDestination } = useOsrdConfSelectors(); const geojson = useSelector(getGeojson); const origin = useSelector(getOrigin); const destination = useSelector(getDestination); diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/ItineraryMarkers.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/ItineraryMarkers.tsx index 064d70178ab..ca77589f2b2 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/ItineraryMarkers.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/ItineraryMarkers.tsx @@ -1,14 +1,14 @@ -import { Map } from 'maplibre-gl'; import React, { useMemo } from 'react'; +import { Map } from 'maplibre-gl'; import { useSelector } from 'react-redux'; import { Marker } from 'react-map-gl/maplibre'; import originSVG from 'assets/pictures/origin.svg'; import destinationSVG from 'assets/pictures/destination.svg'; import viaSVG from 'assets/pictures/via.svg'; -import { getVias, getOrigin, getDestination } from 'reducers/osrdconf/selectors'; import { getNearestTrack } from 'utils/mapHelper'; import { PointOnMap } from 'applications/operationalStudies/consts'; import { Position } from '@turf/helpers'; +import { useOsrdConfSelectors } from 'common/osrdContext'; enum MARKER_TYPE { ORIGIN = 'origin', @@ -67,6 +67,7 @@ const getMarkerName = (marker: PointOnMap, coordinates: number[] | Position, map }; const ItineraryMarkers = ({ map }: { map: Map }) => { + const { getVias, getOrigin, getDestination } = useOsrdConfSelectors(); const vias = useSelector(getVias); const origin = useSelector(getOrigin); const destination = useSelector(getDestination); diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/RenderPopup.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/RenderPopup.tsx index bbe246cef80..8b9aacf10ce 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/RenderPopup.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/RenderPopup.tsx @@ -1,13 +1,13 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import React from 'react'; -import { Popup } from 'react-map-gl/maplibre'; import { useSelector } from 'react-redux'; - -import { getFeatureInfoClick } from 'reducers/osrdconf/selectors'; -import { RiMapPin2Fill, RiMapPin3Fill } from 'react-icons/ri'; -import setPointIti from 'modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/setPointIti'; import { useTranslation } from 'react-i18next'; +import { Popup } from 'react-map-gl/maplibre'; import { IoFlag } from 'react-icons/io5'; +import { RiMapPin2Fill, RiMapPin3Fill } from 'react-icons/ri'; + +import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; +import setPointIti from 'modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/setPointIti'; type FeatureInfoClickType = { displayPopup: boolean; @@ -16,6 +16,8 @@ type FeatureInfoClickType = { }; function RenderPopup() { + const { getFeatureInfoClick } = useOsrdConfSelectors(); + const { updateOrigin, updateDestination, addVias, updateFeatureInfoClick } = useOsrdConfActions(); const { t } = useTranslation(['operationalStudies/manageTrainSchedule']); const featureInfoClick: FeatureInfoClickType = useSelector(getFeatureInfoClick); @@ -51,7 +53,16 @@ function RenderPopup() {