Skip to content

Commit e3dff86

Browse files
committed
front: separate StdcmPathStep and PathStep types
- completely separate StdcmPathStep and PathStep types - remove all the fake uic path item location (which were equal to -1) - add a transformer in the persist config so the date are correctly deserialized from the local storage Signed-off-by: Clara Ni <clara.ni@outlook.fr>
1 parent 6de675f commit e3dff86

30 files changed

+312
-226
lines changed

front/public/locales/en/stdcm.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
"datePickerErrors": {
2222
"invalidInput": "The date must be formatted as dd/mm/yy",
2323
"invalidDate": "Select a date between {{startDate}} and {{endDate}}"
24-
}
24+
},
25+
"incompleteForm": "Incomplete form",
26+
"viaNotDefined": "Au moins une localisation n'est pas renseignée"
2527
},
2628
"indicateAnteriorPath": "Indicate anterior path",
2729
"indicatePosteriorPath": "Indicate posterior path",

front/public/locales/fr/stdcm.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
"datePickerErrors": {
2222
"invalidInput": "Saississez une date au format dd/mm/yy",
2323
"invalidDate": "Renseignez une date entre le {{startDate}} et le {{endDate}}"
24-
}
24+
},
25+
"incompleteForm": "Formulaire incomplet",
26+
"viaNotDefined": "Au moins une localisation n'est pas renseignée"
2527
},
2628
"indicateAnteriorPath": "Indiquer le sillon antérieur",
2729
"indicatePosteriorPath": "Indiquer le sillon postérieur",

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

+7-17
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { useEffect, useState } from 'react';
1+
import { useEffect, useMemo, useState } from 'react';
22

33
import { Button } from '@osrd-project/ui-core';
44
import { ArrowDown, ArrowUp } from '@osrd-project/ui-icons';
55
import cx from 'classnames';
6-
import { compact } from 'lodash';
76
import { useTranslation } from 'react-i18next';
87
import { useSelector } from 'react-redux';
98

9+
import { extractMarkersInfo } from 'applications/stdcm/utils';
1010
import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext';
1111
import useInfraStatus from 'modules/pathfinding/hooks/useInfraStatus';
1212
import { Map } from 'modules/trainschedule/components/ManageTrainSchedule';
@@ -77,15 +77,11 @@ const StdcmConfig = ({
7777

7878
const disabled = isPending || retainedSimulationIndex > -1;
7979

80+
const markerInfos = useMemo(() => extractMarkersInfo(pathSteps), [pathSteps]);
81+
8082
const startSimulation = () => {
8183
const isPathfindingFailed = !!pathfinding && pathfinding.status !== 'success';
82-
const formErrorsStatus = checkStdcmConfigErrors(
83-
isPathfindingFailed,
84-
origin,
85-
destination,
86-
compact(pathSteps),
87-
t
88-
);
84+
const formErrorsStatus = checkStdcmConfigErrors(isPathfindingFailed, origin, destination, t);
8985
if (pathfinding?.status === 'success' && !formErrorsStatus) {
9086
launchStdcmRequest();
9187
} else {
@@ -108,13 +104,7 @@ const StdcmConfig = ({
108104

109105
useEffect(() => {
110106
const isPathfindingFailed = !!pathfinding && pathfinding.status !== 'success';
111-
const formErrorsStatus = checkStdcmConfigErrors(
112-
isPathfindingFailed,
113-
origin,
114-
destination,
115-
[],
116-
t
117-
);
107+
const formErrorsStatus = checkStdcmConfigErrors(isPathfindingFailed, origin, destination, t);
118108
setFormErrors(formErrorsStatus);
119109
}, [origin, destination, pathfinding]);
120110

@@ -195,7 +185,7 @@ const StdcmConfig = ({
195185
preventPointSelection
196186
pathGeometry={pathfinding?.geometry}
197187
showStdcmAssets
198-
simulationPathSteps={pathSteps}
188+
simulationPathSteps={markerInfos}
199189
/>
200190
</div>
201191
</div>

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

+11-8
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import { useMemo } from 'react';
33
import { useTranslation } from 'react-i18next';
44
import { useSelector } from 'react-redux';
55

6+
import { getTimesInfoFromDate } from 'applications/stdcm/utils';
67
import DestinationIcon from 'assets/pictures/mapMarkers/destination.svg';
78
import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext';
89
import type { StdcmConfSliceActions } from 'reducers/osrdconf/stdcmConf';
910
import type { StdcmConfSelectors } from 'reducers/osrdconf/stdcmConf/selectors';
1011
import { useAppDispatch } from 'store';
11-
import { extractDateAndTimefromISO, generateISODateFromDateTime } from 'utils/date';
1212

1313
import StdcmCard from './StdcmCard';
1414
import StdcmOperationalPoint from './StdcmOperationalPoint';
@@ -28,9 +28,7 @@ const StdcmDestination = ({ disabled = false }: StdcmConfigCardProps) => {
2828

2929
const { destinationArrival, destinationToleranceValues } = useMemo(
3030
() => ({
31-
destinationArrival: destination.arrival
32-
? extractDateAndTimefromISO(destination.arrival)
33-
: undefined,
31+
destinationArrival: getTimesInfoFromDate(destination.arrival),
3432
destinationToleranceValues: {
3533
arrivalToleranceBefore:
3634
destination.tolerances?.before !== undefined
@@ -45,11 +43,12 @@ const StdcmDestination = ({ disabled = false }: StdcmConfigCardProps) => {
4543
[destination]
4644
);
4745

48-
const onArrivalChange = (schedule: ScheduleConstraint) => {
46+
const onArrivalChange = ({ date, hours, minutes }: ScheduleConstraint) => {
47+
date.setHours(hours, minutes);
4948
dispatch(
5049
updateStdcmPathStep({
5150
id: destination.id,
52-
updates: { arrival: generateISODateFromDateTime(schedule) },
51+
updates: { arrival: date },
5352
})
5453
);
5554
};
@@ -80,8 +79,12 @@ const StdcmDestination = ({ disabled = false }: StdcmConfigCardProps) => {
8079
disabled={disabled}
8180
className="extremity"
8281
>
83-
{'uic' in destination && (
84-
<StdcmOperationalPoint point={destination} opPointId={destination.id} disabled={disabled} />
82+
{(!destination.location || 'uic' in destination.location) && (
83+
<StdcmOperationalPoint
84+
location={destination.location}
85+
pathStepId={destination.id}
86+
disabled={disabled}
87+
/>
8588
)}
8689
<StdcmOpSchedule
8790
onArrivalChange={onArrivalChange}

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

+5-20
Original file line numberDiff line numberDiff line change
@@ -4,44 +4,29 @@ import { Input } from '@osrd-project/ui-core';
44
import { debounce } from 'lodash';
55
import { useTranslation } from 'react-i18next';
66

7-
import type { PathStep } from 'reducers/osrdconf/types';
8-
import { ISO8601Duration2sec, secToMin } from 'utils/timeManipulation';
9-
107
import { StdcmStopTypes } from '../../types';
118

129
type StdcmInputViaProps = {
1310
stopType: StdcmStopTypes;
14-
stopDuration: PathStep['stopFor'];
11+
stopDuration?: number;
1512
updatePathStepStopTime: (stopTime: string) => void;
1613
};
1714

1815
const StdcmInputVia = ({ stopType, stopDuration, updatePathStepStopTime }: StdcmInputViaProps) => {
1916
const { t } = useTranslation('stdcm');
2017

21-
const computedStopTime = useMemo(() => {
22-
const duration = stopDuration ? `${secToMin(ISO8601Duration2sec(stopDuration))}` : '';
23-
switch (stopType) {
24-
case StdcmStopTypes.PASSAGE_TIME:
25-
return '0';
26-
case StdcmStopTypes.DRIVER_SWITCH:
27-
return duration || '3';
28-
default:
29-
return duration || '0';
30-
}
31-
}, [stopDuration, stopType]);
32-
33-
const [pathStepStopTime, setPathStepStopTime] = useState(computedStopTime);
18+
const [pathStepStopTime, setPathStepStopTime] = useState('');
3419

35-
const stopWarning = stopType === StdcmStopTypes.DRIVER_SWITCH && Number(computedStopTime) < 3;
20+
const stopWarning = stopType === StdcmStopTypes.DRIVER_SWITCH && stopDuration && stopDuration < 3;
3621

3722
const debounceUpdatePathStepStopTime = useMemo(
3823
() => debounce((value) => updatePathStepStopTime(value), 300),
3924
[]
4025
);
4126

4227
useEffect(() => {
43-
setPathStepStopTime(computedStopTime);
44-
}, [computedStopTime]);
28+
setPathStepStopTime(stopDuration ? `${stopDuration}` : '');
29+
}, [stopDuration]);
4530

4631
return (
4732
stopType !== StdcmStopTypes.PASSAGE_TIME && (

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

+24-20
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ import { type SearchResultItemOperationalPoint } from 'common/api/osrdEditoastAp
77
import useSearchOperationalPoint from 'common/Map/Search/useSearchOperationalPoint';
88
import { useOsrdConfActions } from 'common/osrdContext';
99
import type { StdcmConfSliceActions } from 'reducers/osrdconf/stdcmConf';
10-
import type { StdcmPathStep } from 'reducers/osrdconf/types';
10+
import type { UicPathItemLocation } from 'reducers/osrdconf/types';
1111
import { useAppDispatch } from 'store';
1212
import { normalized } from 'utils/strings';
1313
import { createFixedSelectOptions } from 'utils/uiCoreHelpers';
1414

1515
type StdcmOperationalPointProps = {
16-
point: StdcmPathStep;
17-
opPointId: string;
16+
location?: UicPathItemLocation;
17+
pathStepId: string;
1818
disabled?: boolean;
1919
};
2020

@@ -24,12 +24,15 @@ function formatChCode(chCode: string) {
2424
return chCode === '' ? 'BV' : chCode;
2525
}
2626

27-
const StdcmOperationalPoint = ({ point, opPointId, disabled }: StdcmOperationalPointProps) => {
27+
const StdcmOperationalPoint = ({ location, pathStepId, disabled }: StdcmOperationalPointProps) => {
2828
const { t } = useTranslation('stdcm');
2929
const dispatch = useAppDispatch();
3030

3131
const { searchTerm, chCodeFilter, sortedSearchResults, setSearchTerm, setChCodeFilter } =
32-
useSearchOperationalPoint({ initialSearchTerm: point.name, initialChCodeFilter: point.ch });
32+
useSearchOperationalPoint({
33+
initialSearchTerm: location?.name,
34+
initialChCodeFilter: location?.secondary_code || undefined,
35+
});
3336

3437
const { updateStdcmPathStep } = useOsrdConfActions() as StdcmConfSliceActions;
3538

@@ -71,20 +74,21 @@ const StdcmOperationalPoint = ({ point, opPointId, disabled }: StdcmOperationalP
7174
},
7275
[] as { label: string; id: string }[]
7376
),
74-
[point, sortedSearchResults]
77+
[location, sortedSearchResults]
7578
);
7679

7780
const dispatchNewPoint = (p?: SearchResultItemOperationalPoint) => {
78-
if (p && p.ch === point.ch && 'uic' in point && p.uic === point.uic) return;
79-
const newPoint = p
81+
if (p && p.ch === location?.secondary_code && 'uic' in location && p.uic === location.uic)
82+
return;
83+
const newLocation = p
8084
? {
8185
name: p.name,
82-
ch: p.ch,
86+
secondary_code: p.ch,
8387
uic: p.uic,
84-
coordinates: p.geographic.coordinates,
88+
coordinates: p.geographic.coordinates as [number, number],
8589
}
86-
: { name: undefined, ch: undefined, uic: -1, coordinates: undefined };
87-
dispatch(updateStdcmPathStep({ id: point.id, updates: newPoint }));
90+
: undefined;
91+
dispatch(updateStdcmPathStep({ id: pathStepId, updates: { location: newLocation } }));
8892
};
8993

9094
const updateSelectedPoint = (
@@ -110,8 +114,8 @@ const StdcmOperationalPoint = ({ point, opPointId, disabled }: StdcmOperationalP
110114

111115
const onSelectChCodeFilter = (selectedChCode?: { id: string }) => {
112116
setChCodeFilter(selectedChCode?.id);
113-
if (point && 'uic' in point)
114-
updateSelectedPoint(sortedSearchResults, point.uic, selectedChCode?.id);
117+
if (location && 'uic' in location)
118+
updateSelectedPoint(sortedSearchResults, location.uic, selectedChCode?.id);
115119
};
116120

117121
const onInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
@@ -122,20 +126,20 @@ const StdcmOperationalPoint = ({ point, opPointId, disabled }: StdcmOperationalP
122126
};
123127

124128
useEffect(() => {
125-
if (point) {
126-
setSearchTerm(point.name || '');
127-
setChCodeFilter(point.ch || '');
129+
if (location) {
130+
setSearchTerm(location.name || '');
131+
setChCodeFilter(location.secondary_code || '');
128132
} else {
129133
setSearchTerm('');
130134
setChCodeFilter(undefined);
131135
}
132-
}, [point]);
136+
}, [location]);
133137

134138
return (
135139
<div className="location-line">
136140
<div className="col-9 ci-input">
137141
<ComboBox
138-
id={`${opPointId}-ci`}
142+
id={`${pathStepId}-ci`}
139143
label={t('trainPath.ci')}
140144
value={searchTerm}
141145
onChange={onInputChange}
@@ -150,7 +154,7 @@ const StdcmOperationalPoint = ({ point, opPointId, disabled }: StdcmOperationalP
150154
<div className="col-3 p-0">
151155
<Select
152156
label={t('trainPath.ch')}
153-
id={`${opPointId}-ch`}
157+
id={`${pathStepId}-ch`}
154158
value={chCodeFilter ? { label: formatChCode(chCodeFilter), id: chCodeFilter } : undefined}
155159
onChange={(e) => onSelectChCodeFilter(e)}
156160
{...createFixedSelectOptions(sortedChOptions)}

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

+11-6
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ import { useMemo } from 'react';
33
import { useTranslation } from 'react-i18next';
44
import { useSelector } from 'react-redux';
55

6+
import { getTimesInfoFromDate } from 'applications/stdcm/utils';
67
import OriginIcon from 'assets/pictures/mapMarkers/start.svg';
78
import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext';
89
import type { StdcmConfSliceActions } from 'reducers/osrdconf/stdcmConf';
910
import type { StdcmConfSelectors } from 'reducers/osrdconf/stdcmConf/selectors';
1011
import { useAppDispatch } from 'store';
11-
import { extractDateAndTimefromISO, generateISODateFromDateTime } from 'utils/date';
1212

1313
import StdcmCard from './StdcmCard';
1414
import StdcmOperationalPoint from './StdcmOperationalPoint';
@@ -27,7 +27,7 @@ const StdcmOrigin = ({ disabled = false }: StdcmConfigCardProps) => {
2727

2828
const { originArrival, originToleranceValues } = useMemo(
2929
() => ({
30-
originArrival: origin.arrival ? extractDateAndTimefromISO(origin.arrival) : undefined,
30+
originArrival: getTimesInfoFromDate(origin.arrival),
3131
originToleranceValues: {
3232
arrivalToleranceBefore:
3333
origin.tolerances?.before !== undefined ? origin.tolerances.before : DEFAULT_TOLERANCE,
@@ -38,11 +38,12 @@ const StdcmOrigin = ({ disabled = false }: StdcmConfigCardProps) => {
3838
[origin]
3939
);
4040

41-
const onOriginArrivalChange = (schedule: ScheduleConstraint) => {
41+
const onOriginArrivalChange = ({ date, hours, minutes }: ScheduleConstraint) => {
42+
date.setHours(hours, minutes);
4243
dispatch(
4344
updateStdcmPathStep({
4445
id: origin.id,
45-
updates: { arrival: generateISODateFromDateTime(schedule) },
46+
updates: { arrival: date },
4647
})
4748
);
4849
};
@@ -79,8 +80,12 @@ const StdcmOrigin = ({ disabled = false }: StdcmConfigCardProps) => {
7980
disabled={disabled}
8081
hasTip
8182
>
82-
{'uic' in origin && (
83-
<StdcmOperationalPoint point={origin} opPointId={origin.id} disabled={disabled} />
83+
{(!origin.location || 'uic' in origin.location) && (
84+
<StdcmOperationalPoint
85+
location={origin.location}
86+
pathStepId={origin.id}
87+
disabled={disabled}
88+
/>
8489
)}
8590
<StdcmOpSchedule
8691
onArrivalChange={onOriginArrivalChange}

0 commit comments

Comments
 (0)