Skip to content

Commit 8cc275a

Browse files
committed
front: enhance pathfinding loading state management
1 parent 9ddc06c commit 8cc275a

File tree

4 files changed

+49
-54
lines changed

4 files changed

+49
-54
lines changed

front/src/applications/stdcm/components/StdcmForm/StdcmConfig.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import StdcmConsist from './StdcmConsist';
2424
import StdcmDestination from './StdcmDestination';
2525
import StdcmLinkedTrainSearch from './StdcmLinkedTrainSearch';
2626
import StdcmOrigin from './StdcmOrigin';
27-
import useStaticPathfinding from '../../hooks/useStaticPathfinding';
27+
import useStdcmPathfinding from '../../hooks/useStdcmPathfinding';
2828
import type { StdcmConfigErrors } from '../../types';
2929
import StdcmSimulationParams from '../StdcmSimulationParams';
3030
import StdcmVias from './StdcmVias';
@@ -82,8 +82,8 @@ const StdcmConfig = ({
8282
const totalMass = useSelector(getTotalMass);
8383
const totalLength = useSelector(getTotalLength);
8484
const maxSpeed = useSelector(getMaxSpeed);
85+
const { isPathfindingLoading, pathfinding } = useStdcmPathfinding(infra);
8586

86-
const pathfinding = useStaticPathfinding(infra);
8787
const formRef = useRef<HTMLDivElement>(null);
8888

8989
const [formErrors, setFormErrors] = useState<StdcmConfigErrors>();
@@ -250,6 +250,7 @@ const StdcmConfig = ({
250250
id="stdcm-map-config"
251251
hideAttribution
252252
hideItinerary
253+
isPathfindingLoading={isPathfindingLoading}
253254
preventPointSelection
254255
pathGeometry={pathfinding?.geometry}
255256
showStdcmAssets

front/src/applications/stdcm/hooks/useStaticPathfinding.ts front/src/applications/stdcm/hooks/useStdcmPathfinding.ts

+25-40
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,7 @@ import { useEffect, useMemo, useState } from 'react';
33
import { compact, isEqual } from 'lodash';
44
import { useSelector } from 'react-redux';
55

6-
import {
7-
osrdEditoastApi,
8-
type InfraWithState,
9-
type PathfindingResult,
10-
} from 'common/api/osrdEditoastApi';
6+
import { osrdEditoastApi, type InfraWithState } from 'common/api/osrdEditoastApi';
117
import { useOsrdConfSelectors } from 'common/osrdContext';
128
import usePathProperties from 'modules/pathfinding/hooks/usePathProperties';
139
import { getPathfindingQuery } from 'modules/pathfinding/utils';
@@ -24,17 +20,12 @@ function pathStepsToLocations(
2420
return compact(pathSteps.map((s) => s.location));
2521
}
2622

27-
const useStaticPathfinding = (infra?: InfraWithState) => {
23+
const useStdcmPathfinding = (infra?: InfraWithState) => {
2824
const { getStdcmPathSteps } = useOsrdConfSelectors() as StdcmConfSelectors;
2925
const pathSteps = useSelector(getStdcmPathSteps);
3026
const [pathStepsLocations, setPathStepsLocations] = useState(pathStepsToLocations(pathSteps));
3127
const { rollingStock } = useStoreDataForRollingStockSelector();
3228

33-
const [pathfinding, setPathfinding] = useState<PathfindingResult>();
34-
35-
const [postPathfindingBlocks] =
36-
osrdEditoastApi.endpoints.postInfraByInfraIdPathfindingBlocks.useLazyQuery();
37-
3829
// When pathSteps changed
3930
// => update the pathStepsLocations (if needed by doing a deep comparison).
4031
useEffect(() => {
@@ -45,46 +36,40 @@ const useStaticPathfinding = (infra?: InfraWithState) => {
4536
});
4637
}, [pathSteps]);
4738

39+
const pathfindingPayload = useMemo(() => {
40+
if (infra?.state !== 'CACHED' || pathStepsLocations.length < 2) {
41+
return null;
42+
}
43+
return getPathfindingQuery({
44+
infraId: infra.id,
45+
rollingStock,
46+
pathSteps: pathStepsLocations,
47+
});
48+
}, [pathStepsLocations, rollingStock, infra]);
49+
50+
const { data: pathfinding, isFetching } =
51+
osrdEditoastApi.endpoints.postInfraByInfraIdPathfindingBlocks.useQuery(pathfindingPayload!, {
52+
skip: !pathfindingPayload,
53+
});
54+
4855
const pathProperties = usePathProperties(
4956
infra?.id,
5057
pathfinding?.status === 'success' ? pathfinding : undefined,
5158
['geometry']
5259
);
5360

54-
useEffect(() => {
55-
const launchPathfinding = async () => {
56-
setPathfinding(undefined);
57-
if (infra?.state !== 'CACHED' || !rollingStock || pathStepsLocations.length < 2) {
58-
return;
59-
}
60-
61-
const payload = getPathfindingQuery({
62-
infraId: infra.id,
63-
rollingStock,
64-
pathSteps: pathStepsLocations,
65-
});
66-
67-
if (payload === null) {
68-
return;
69-
}
70-
71-
const pathfindingResult = await postPathfindingBlocks(payload).unwrap();
72-
73-
setPathfinding(pathfindingResult);
74-
};
75-
76-
launchPathfinding();
77-
}, [pathStepsLocations, rollingStock, infra]);
78-
79-
const result = useMemo(
61+
const pathfindingResult = useMemo(
8062
() =>
8163
pathfinding
82-
? { status: pathfinding.status, geometry: pathProperties?.geometry ?? undefined }
64+
? {
65+
status: pathfinding.status,
66+
geometry: pathProperties?.geometry ?? undefined,
67+
}
8368
: null,
8469
[pathfinding, pathProperties]
8570
);
8671

87-
return result;
72+
return { isPathfindingLoading: isFetching, pathfinding: pathfindingResult };
8873
};
8974

90-
export default useStaticPathfinding;
75+
export default useStdcmPathfinding;

front/src/modules/trainschedule/components/ManageTrainSchedule/Map.tsx

+2-7
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ const Map = ({
8080
const terrain3DExaggeration = useSelector(getTerrain3DExaggeration);
8181
const { viewport, mapSearchMarker, mapStyle, showOSM, layersSettings } = useSelector(getMap);
8282
const mapRef = useRef<MapRef | null>(null);
83-
const mapContainer = useMemo(() => mapRef.current?.getContainer(), [mapRef.current]);
8483

8584
const pathGeometry = useMemo(
8685
() => geometry || pathProperties?.geometry,
@@ -210,14 +209,10 @@ const Map = ({
210209
type: 'LineString',
211210
};
212211
if (points.coordinates.length > 2) {
213-
const newViewport = computeBBoxViewport(bbox(points), viewport, {
214-
width: mapContainer?.clientWidth,
215-
height: mapContainer?.clientHeight,
216-
padding: 60,
217-
});
212+
const newViewport = computeBBoxViewport(bbox(points), viewport);
218213
dispatch(updateViewport(newViewport));
219214
}
220-
}, [pathGeometry, simulationPathSteps, mapContainer]);
215+
}, [pathGeometry, simulationPathSteps]);
221216

222217
return (
223218
<>

front/src/modules/trainschedule/components/ManageTrainSchedule/NewMap.tsx

+19-5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { useParams } from 'react-router-dom';
1111
import captureMap from 'applications/operationalStudies/helpers/captureMap';
1212
import type { ManageTrainSchedulePathProperties } from 'applications/operationalStudies/types';
1313
import type { PathProperties } from 'common/api/osrdEditoastApi';
14+
import { LoaderFill } from 'common/Loaders';
1415
import MapButtons from 'common/Map/Buttons/MapButtons';
1516
import { CUSTOM_ATTRIBUTION } from 'common/Map/const';
1617
import colors from 'common/Map/Consts/colors';
@@ -53,6 +54,7 @@ type MapProps = {
5354
setMapCanvas?: (mapCanvas: string) => void;
5455
hideAttribution?: boolean;
5556
hideItinerary?: boolean;
57+
isPathfindingLoading?: boolean;
5658
preventPointSelection?: boolean;
5759
id: string;
5860
simulationPathSteps: MarkerInformation[];
@@ -73,6 +75,7 @@ const NewMap = ({
7375
setMapCanvas,
7476
hideAttribution = false,
7577
hideItinerary = false,
78+
isPathfindingLoading = false,
7679
preventPointSelection = false,
7780
id,
7881
simulationPathSteps,
@@ -99,6 +102,14 @@ const NewMap = ({
99102
[pathProperties, geometry]
100103
);
101104

105+
const mapRef = useRef<MapRef | null>(null);
106+
const mapContainer = useMemo(() => mapRef.current?.getContainer(), [mapRef.current]);
107+
108+
const mapViewport = useMemo(
109+
() => (pathGeometry ? computeBBoxViewport(bbox(pathGeometry), viewport) : viewport),
110+
[pathGeometry, viewport]
111+
);
112+
102113
const [mapIsLoaded, setMapIsLoaded] = useState(false);
103114

104115
const [snappedPoint, setSnappedPoint] = useState<Feature<Point> | undefined>();
@@ -116,8 +127,6 @@ const NewMap = ({
116127
[]
117128
);
118129

119-
const mapRef = useRef<MapRef | null>(null);
120-
121130
const scaleControlStyle = {
122131
left: 20,
123132
bottom: 20,
@@ -228,14 +237,19 @@ const NewMap = ({
228237
coordinates: compact(simulationPathSteps.map((step) => step.coordinates)),
229238
type: 'LineString',
230239
};
231-
if (points.coordinates.length > 2) {
232-
const newViewport = computeBBoxViewport(bbox(points), viewport);
240+
if (points.coordinates.length > 2 && !isPathfindingLoading) {
241+
const newViewport = computeBBoxViewport(bbox(points), mapViewport, {
242+
width: mapContainer?.clientWidth,
243+
height: mapContainer?.clientHeight,
244+
padding: 60,
245+
});
233246
updateViewportChange(newViewport);
234247
}
235-
}, [pathGeometry, simulationPathSteps]);
248+
}, [pathGeometry, simulationPathSteps, mapContainer, isPathfindingLoading]);
236249

237250
return (
238251
<>
252+
{isPathfindingLoading && <LoaderFill />}
239253
<MapButtons
240254
zoomIn={zoomIn}
241255
zoomOut={zoomOut}

0 commit comments

Comments
 (0)