@@ -4,15 +4,26 @@ import { Checkbox } from '@osrd-project/ui-core';
4
4
import { ChevronDown , ChevronRight , Clock , Flame , Manchette } from '@osrd-project/ui-icons' ;
5
5
import cx from 'classnames' ;
6
6
import dayjs from 'dayjs' ;
7
+ import { omit } from 'lodash' ;
7
8
import { useTranslation } from 'react-i18next' ;
8
9
9
- import { osrdEditoastApi } from 'common/api/osrdEditoastApi' ;
10
+ import { osrdEditoastApi , type PacedTrainBase } from 'common/api/osrdEditoastApi' ;
10
11
import { setFailure , setSuccess } from 'reducers/main' ;
11
- import type { PacedTrainId , TimetableItemId , TrainId } from 'reducers/osrdconf/types' ;
12
+ import type {
13
+ PacedTrainId ,
14
+ PacedTrainResultWithPacedTrainId ,
15
+ TimetableItemId ,
16
+ TimetableItemWithTimetableId ,
17
+ TrainId ,
18
+ } from 'reducers/osrdconf/types' ;
12
19
import { useAppDispatch } from 'store' ;
20
+ import { addDurationToDate , Duration } from 'utils/duration' ;
13
21
import { castErrorToFailure } from 'utils/error' ;
14
22
import { ms2min } from 'utils/timeManipulation' ;
15
- import { formatPacedTrainIdToEditoastTrainId } from 'utils/trainId' ;
23
+ import {
24
+ formatEditoastTrainIdToPacedTrainId ,
25
+ formatPacedTrainIdToEditoastTrainId ,
26
+ } from 'utils/trainId' ;
16
27
17
28
import TimetableItemActions from '../TimetableItemActions' ;
18
29
import useOccurrences from './hooks/useOccurrences' ;
@@ -28,6 +39,7 @@ type PacedTrainItemProps = {
28
39
isProjectionPathUsed : boolean ;
29
40
selectedTimeTableItemId : TrainId | undefined ;
30
41
selectPacedTrainToEdit : ( pacedTrain : PacedTrainWithDetails ) => void ;
42
+ upsertTimetableItems : ( timetableItems : TimetableItemWithTimetableId [ ] ) => void ;
31
43
removePaceTrains : ( pacedTrainIdsToRemove : TimetableItemId [ ] ) => void ;
32
44
// dtoImport: () => void;
33
45
} ;
@@ -41,6 +53,7 @@ const PacedTrainItem = ({
41
53
isProjectionPathUsed,
42
54
selectPacedTrainToEdit,
43
55
selectedTimeTableItemId,
56
+ upsertTimetableItems,
44
57
removePaceTrains,
45
58
// dtoImport,
46
59
} : PacedTrainItemProps ) => {
@@ -50,11 +63,12 @@ const PacedTrainItem = ({
50
63
const [ isOccurrencesListOpen , setIsOccurrencesListOpen ] = useState ( false ) ;
51
64
const { occurrences, occurrencesCount } = useOccurrences ( pacedTrain ) ;
52
65
66
+ const [ postPacedTrain ] = osrdEditoastApi . endpoints . postTimetableByIdPacedTrains . useMutation ( ) ;
67
+ const [ getPacedTrainById ] = osrdEditoastApi . endpoints . getPacedTrainById . useLazyQuery ( ) ;
53
68
const [ deletePacedTrains ] = osrdEditoastApi . endpoints . deletePacedTrain . useMutation ( ) ;
54
69
55
70
const toggleOccurrencesList = ( ) => setIsOccurrencesListOpen ( ( open ) => ! open ) ;
56
71
const selectPathProjection = async ( ) => { } ;
57
- const duplicatePacedTrain = async ( ) => { } ;
58
72
59
73
const deletePacedTrain = async ( ) => {
60
74
// if (isSelected) {
@@ -63,7 +77,6 @@ const PacedTrainItem = ({
63
77
// dispatch(updateSelectedTrainId(undefined));
64
78
// }
65
79
66
- // TODO Paced train : Adapt this to handle paced trains in issue https://github.com/OpenRailAssociation/osrd/issues/10615
67
80
deletePacedTrains ( {
68
81
body : { ids : [ formatPacedTrainIdToEditoastTrainId ( pacedTrain . id ) ] } ,
69
82
} )
@@ -73,7 +86,7 @@ const PacedTrainItem = ({
73
86
// dtoImport();
74
87
dispatch (
75
88
setSuccess ( {
76
- title : t ( 'timetable.pacedTrainDeleted' , { name : pacedTrain . trainName } ) ,
89
+ title : t ( 'timetable.pacedTrainDeleted' , { name : pacedTrain . name } ) ,
77
90
text : '' ,
78
91
} )
79
92
) ;
@@ -86,6 +99,55 @@ const PacedTrainItem = ({
86
99
} ) ;
87
100
} ;
88
101
102
+ const duplicatePacedTrain = async ( ) => {
103
+ // Static for now, will be dynamic when UI will be ready
104
+ const pacedTrainName = `${ pacedTrain . name } (${ t ( 'timetable.copy' ) } )` ;
105
+ const pacedTrainDelta = 5 ;
106
+
107
+ const editoastTrainId = formatPacedTrainIdToEditoastTrainId ( pacedTrain . id ) ;
108
+ const pacedTrainDetail = await getPacedTrainById ( {
109
+ id : editoastTrainId ,
110
+ } )
111
+ . unwrap ( )
112
+ . catch ( ( e ) => {
113
+ dispatch ( setFailure ( castErrorToFailure ( e ) ) ) ;
114
+ } ) ;
115
+
116
+ if ( pacedTrainDetail ) {
117
+ const startTime = new Date ( pacedTrainDetail . start_time ) ;
118
+ const newStartTimeString = addDurationToDate (
119
+ startTime ,
120
+ new Duration ( { minutes : pacedTrainDelta } )
121
+ ) ;
122
+ const newPacedTrain : PacedTrainBase = {
123
+ ...omit ( pacedTrainDetail , [ 'id' , 'timetable_id' ] ) ,
124
+ start_time : newStartTimeString . toISOString ( ) ,
125
+ train_name : pacedTrainName ,
126
+ } ;
127
+
128
+ try {
129
+ const [ pacedTrainResult ] = await postPacedTrain ( {
130
+ id : pacedTrainDetail . timetable_id ,
131
+ body : [ newPacedTrain ] ,
132
+ } ) . unwrap ( ) ;
133
+ const formattedTrainScheduleResult : PacedTrainResultWithPacedTrainId = {
134
+ ...pacedTrainResult ,
135
+ id : formatEditoastTrainIdToPacedTrainId ( pacedTrainResult . id ) ,
136
+ } ;
137
+ upsertTimetableItems ( [ formattedTrainScheduleResult ] ) ;
138
+ // dtoImport();
139
+ dispatch (
140
+ setSuccess ( {
141
+ title : t ( 'timetable.pacedTrainAdded' ) ,
142
+ text : `${ pacedTrainName } ` ,
143
+ } )
144
+ ) ;
145
+ } catch ( e ) {
146
+ dispatch ( setFailure ( castErrorToFailure ( e ) ) ) ;
147
+ }
148
+ }
149
+ } ;
150
+
89
151
return (
90
152
< div
91
153
data-testid = "scenario-timetable-train"
@@ -113,7 +175,7 @@ const PacedTrainItem = ({
113
175
</ div >
114
176
115
177
< div
116
- title = { pacedTrain . trainName }
178
+ title = { pacedTrain . name }
117
179
className = "paced-train-main-info"
118
180
onClick = { toggleOccurrencesList }
119
181
role = "button"
@@ -131,7 +193,7 @@ const PacedTrainItem = ({
131
193
< ChevronRight className = "toggle-icon center-icon" />
132
194
) }
133
195
< div className = "train-info" >
134
- < span className = "train-name" > { pacedTrain . trainName } </ span >
196
+ < span className = "train-name" > { pacedTrain . name } </ span >
135
197
</ div >
136
198
</ div >
137
199
0 commit comments