Skip to content

Commit d316156

Browse files
Yohhclarani
authored andcommitted
editoast+front: display CI/CH codes in pathfinding component
editoast: pathfinding: add CI/CH codes to pathfinding response - add uic and ch to PathfindingResponse and PathWaypoint struct - get them from waypoint in Pathfinding impl - add ch to ResultStops struct, add_stops_additional_information fn and train_with_simulation_output_fixture_set fn - update openapi.yaml front: pathfinding: display CI/CH codes - create formatUicToCi in utils/strings.ts - add CI/CH codes in ModalSugerredVias, StationCard and DisplayVias - add CH code in AllowancesModalOP and DriverTrainScheduleStop - add elipsis to vias name in modal - replace suggered by suggested tests: - add ch and uic to steps in test_pathfinding.py
1 parent 044204f commit d316156

File tree

20 files changed

+133
-50
lines changed

20 files changed

+133
-50
lines changed

editoast/openapi.yaml

+13
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,9 @@ components:
12981298
type: object
12991299
PathWaypoint:
13001300
properties:
1301+
ch:
1302+
nullable: true
1303+
type: string
13011304
duration:
13021305
format: double
13031306
type: number
@@ -1318,6 +1321,10 @@ components:
13181321
$ref: '#/components/schemas/GeoJsonPoint'
13191322
suggestion:
13201323
type: boolean
1324+
uic:
1325+
format: int64
1326+
nullable: true
1327+
type: integer
13211328
required:
13221329
- id
13231330
- name
@@ -1327,6 +1334,8 @@ components:
13271334
- suggestion
13281335
- geo
13291336
- sch
1337+
- uic
1338+
- ch
13301339
type: object
13311340
PathfindingPayload:
13321341
description: |-
@@ -1749,6 +1758,9 @@ components:
17491758
type: object
17501759
ResultStops:
17511760
properties:
1761+
ch:
1762+
nullable: true
1763+
type: string
17521764
duration:
17531765
format: double
17541766
type: number
@@ -1762,6 +1774,7 @@ components:
17621774
- time
17631775
- position
17641776
- duration
1777+
- ch
17651778
type: object
17661779
RjsPowerRestrictionRange:
17671780
description: A range along the train path where a power restriction is applied.

editoast/src/fixtures.rs

+2
Original file line numberDiff line numberDiff line change
@@ -478,11 +478,13 @@ pub mod tests {
478478
time: 0.0,
479479
duration: 0.0,
480480
position: 0.0,
481+
ch: None,
481482
},
482483
ResultStops {
483484
time: 110.90135448736316,
484485
duration: 1.0,
485486
position: 2417.6350658673214,
487+
ch: None,
486488
},
487489
],
488490
head_positions: vec![ResultPosition {

editoast/src/models/pathfinding.rs

+4
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ pub struct PathWaypoint {
185185
))]
186186
#[schema(value_type = GeoJsonPoint)]
187187
pub sch: geojson::Geometry,
188+
#[schema(required)]
189+
pub uic: Option<i64>,
190+
#[schema(required)]
191+
pub ch: Option<String>,
188192
}
189193

190194
impl Pathfinding {

editoast/src/models/train_schedule.rs

+2
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ pub struct ResultStops {
239239
pub time: f64,
240240
pub position: f64,
241241
pub duration: f64,
242+
#[schema(required)]
243+
pub ch: Option<String>,
242244
}
243245

244246
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default, ToSchema)]

editoast/src/views/pathfinding/mod.rs

+15-7
Original file line numberDiff line numberDiff line change
@@ -375,12 +375,18 @@ impl Pathfinding {
375375
} else {
376376
steps_duration.next().unwrap()
377377
};
378-
let op_name = waypoint
379-
.id
380-
.as_ref()
381-
.map(|op_id| op_map.get(op_id).expect("unexpected OP id"))
382-
.and_then(|op| op.extensions.identifier.as_ref())
383-
.map(|ident| ident.name.as_ref().to_owned());
378+
let op_info = waypoint.id.as_ref().map(|op_id| {
379+
let op = op_map.get(op_id).expect("unexpected OP id");
380+
let name = op
381+
.extensions
382+
.identifier
383+
.as_ref()
384+
.map(|ident| ident.name.as_ref().to_owned());
385+
let uic = op.extensions.identifier.as_ref().map(|ident| ident.uic);
386+
let ch = op.extensions.sncf.as_ref().map(|sncf| sncf.ch.to_owned());
387+
(name, uic, ch)
388+
});
389+
let (name, uic, ch) = op_info.unwrap_or_default();
384390
let track = track_map
385391
.get(&waypoint.location.track_section.0)
386392
.expect("unexpected track id");
@@ -397,13 +403,15 @@ impl Pathfinding {
397403
let sch = geos::geojson::Geometry::try_from(sch).unwrap();
398404
PathWaypoint {
399405
id: waypoint.id.clone(),
400-
name: op_name,
406+
name,
401407
location: waypoint.location.clone(),
402408
duration,
403409
path_offset: waypoint.path_offset,
404410
suggestion: waypoint.suggestion,
405411
geo,
406412
sch,
413+
uic,
414+
ch,
407415
}
408416
})
409417
.collect();

editoast/src/views/train_schedule/simulation_report.rs

+2
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@ async fn add_stops_additional_information(
273273
time: s.time,
274274
position: s.position,
275275
duration: s.duration,
276+
ch: pw.ch.clone(),
276277
},
277278
id: pw.id.clone(),
278279
name: pw.name.clone(),
@@ -286,6 +287,7 @@ async fn add_stops_additional_information(
286287
time: s.time,
287288
position: s.position,
288289
duration: s.duration,
290+
ch: pw.ch.clone(),
289291
},
290292
..Default::default()
291293
},

front/src/applications/operationalStudies/consts.ts

+2
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ export interface PointOnMap {
113113
track?: string;
114114
position?: number;
115115
path_offset?: number;
116+
uic?: number | null;
117+
ch?: string | null;
116118
location?: {
117119
track_section?: string;
118120
offset?: number;

front/src/common/StationCard.tsx

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from 'react';
2+
import { formatUicToCi } from 'utils/strings';
23

34
export interface ImportStation {
45
trigram?: string;
@@ -33,17 +34,15 @@ export default function StationCard({ station, onClick, fixedHeight = false }: P
3334
>
3435
<div className="station-card-head">
3536
<span className="station-card-code">{trigram}</span>
36-
<span className="station-card-name">{name}</span>
37-
{yardname && !yardNamesToExclude.includes(yardname) && (
38-
<span className="station-card-ch">{yardname}</span>
39-
)}
37+
<span className="station-card-name">{name}&nbsp;</span>
38+
{yardname && !yardNamesToExclude.includes(yardname) && <small>{yardname}</small>}
39+
{uic && <span className="station-card-uic ml-3">{formatUicToCi(uic)}</span>}
4040
</div>
4141
<div className="station-card-localization">
4242
<span className="station-card-city">{town}</span>
4343
<span className="station-card-department">{department}</span>
4444
{department && region && <div className="station-card-separator">/</div>}
4545
<span className="station-card-region">{region}</span>
46-
<span className="station-card-uic">{uic}</span>
4746
</div>
4847
{linename && (
4948
<div className="station-card-footer">

front/src/common/api/osrdEditoastApi.ts

+3
Original file line numberDiff line numberDiff line change
@@ -1643,6 +1643,7 @@ export type GeoJsonPoint = {
16431643
type: 'Point';
16441644
};
16451645
export type PathWaypoint = {
1646+
ch: string | null;
16461647
duration: number;
16471648
geo: GeoJsonPoint;
16481649
id: string | null;
@@ -1651,6 +1652,7 @@ export type PathWaypoint = {
16511652
path_offset: number;
16521653
sch: GeoJsonPoint;
16531654
suggestion: boolean;
1655+
uic: number | null;
16541656
};
16551657
export type PathResponse = {
16561658
created: string;
@@ -2201,6 +2203,7 @@ export type ResultSpeed = {
22012203
time: number;
22022204
};
22032205
export type ResultStops = {
2206+
ch: string | null;
22042207
duration: number;
22052208
position: number;
22062209
time: number;

front/src/modules/trainschedule/components/DriverTrainSchedule/DriverTrainScheduleStop.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,10 @@ export default function DriverTrainScheduleStop({ stop, idx, train }: Props) {
5252
<td className="d-flex justify-content-center">
5353
<div>{Number.isInteger(pk) ? `${pk}.0` : pk}</div>
5454
</td>
55-
<td>{stop.name || 'Unknown'}</td>
55+
<td>
56+
{stop.name || 'Unknown'}&nbsp;
57+
<small>{stop.ch}</small>
58+
</td>
5659
<td className="stoptime-container">
5760
<div className="box">
5861
<div className="box-row">

front/src/modules/trainschedule/components/ImportTrainSchedule/generateTrainSchedulesPayload.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { PathWaypoint, TrainScheduleBatchItem } from 'common/api/osrdEditoastApi
33
import { time2sec } from 'utils/timeManipulation';
44

55
// Hope for indexes are the same !
6-
// Synchronisation is done with indexes between pathfinding not suggered positions, and required steps from importation
6+
// Synchronisation is done with indexes between pathfinding not suggested positions, and required steps from importation
77
function mixPathPositionsAndTimes(requiredSteps: Step[], pathFindingWaypoints: PathWaypoint[]) {
88
const startTime = new Date(requiredSteps[0].departureTime);
99
const pathFindingStepsFiltered = pathFindingWaypoints.filter((waypoint) => !waypoint.suggestion);

front/src/modules/trainschedule/components/ManageTrainSchedule/Allowances/AllowancesModalOP.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,10 @@ export default function AllowancesModalOP({
2727
key={waypoint.path_offset}
2828
>
2929
<div className="col-6">{waypoint.path_offset}</div>
30-
<div className="col-6">{waypoint.name}</div>
30+
<div className="col-6">
31+
{waypoint.name}&nbsp;
32+
{waypoint.ch === '00' || !waypoint.ch ? 'BV' : `${waypoint.ch}`}
33+
</div>
3134
</button>
3235
))}
3336
</div>

front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/DisplayVias.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import cx from 'classnames';
99
import { AnyAction, ThunkAction } from '@reduxjs/toolkit';
1010
import { Position } from 'geojson';
1111
import { RootState } from 'reducers';
12+
import { formatUicToCi } from 'utils/strings';
1213

1314
type InputStopTimeProps = {
1415
index: number;
@@ -99,6 +100,10 @@ export default function DisplayVias({ zoomToFeaturePoint }: DisplayViasProps) {
99100
`KM ${place.position && Math.round(place.position) / 1000}`
100101
}`}
101102
</small>
103+
<small className="">{place.ch}</small>
104+
{place.uic && (
105+
<small className="text-muted ml-3">{formatUicToCi(place.uic)}</small>
106+
)}
102107
</div>
103108
{index !== indexSelected && (
104109
<div className="default-durations-button mr-1">

front/src/modules/trainschedule/components/ManageTrainSchedule/Itinerary/ModalSuggeredVias.tsx

+31-24
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { ModalContext } from 'common/BootstrapSNCF/ModalSNCF/ModalProvider';
1111
import { Spinner } from 'common/Loader';
1212
import type { ArrayElement } from 'utils/types';
1313
import type { PathResponse, PathWaypoint } from 'common/api/osrdEditoastApi';
14+
import { formatUicToCi } from 'utils/strings';
15+
import cx from 'classnames';
1416

1517
type Props = {
1618
removeAllVias: () => void;
@@ -65,32 +67,37 @@ export default function ModalSugerredVias({ removeAllVias, pathfindingInProgress
6567

6668
const formatVia = (via: ArrayElement<PathResponse['steps']>, idx: number, idxTrueVia: number) => (
6769
<div
68-
key={`suggered-via-modal-${via.id}-${idx}`}
69-
className={`d-flex align-items-center p-1 ${via.suggestion && 'suggerred-via-clickable'}`}
70+
key={`suggested-via-modal-${via.id}-${idx}`}
71+
className={cx('d-flex align-items-center p-1', via.suggestion && 'suggested-via-clickable')}
72+
title={via.name!}
7073
>
7174
{!via.suggestion && <small className="pr-2">{idxTrueVia}</small>}
7275
<i className={`${via.suggestion ? 'text-muted' : 'text-info'} icons-itinerary-bullet mr-2`} />
73-
{via.name || ''}
74-
<small className="ml-2">
75-
{via.path_offset && `KM ${Math.round(via.path_offset) / 1000}`}
76-
</small>
77-
{via.suggestion && via.id && !selectedViasTracks.includes(via.id) ? (
78-
<button
79-
className="btn btn-sm btn-only-icon ml-auto"
80-
type="button"
81-
onClick={() => convertPathfindingVias(suggeredVias, idx - 1)}
82-
>
83-
<GoPlus />
84-
</button>
85-
) : (
86-
<button
87-
className="btn btn-sm btn-only-icon ml-auto bg-dark"
88-
type="button"
89-
onClick={() => removeViaFromPath(via)}
90-
>
91-
<GoDash color="white" />
92-
</button>
93-
)}
76+
<span className="suggested-via-name">{via.name || ''}</span>&nbsp;
77+
<span>{via.ch}</span>
78+
{via.uic && <small className="text-muted ml-3">{formatUicToCi(via.uic)}</small>}
79+
<div className="ml-auto">
80+
{via.path_offset && (
81+
<small className="mr-2">{`KM ${Math.round(via.path_offset) / 1000}`}</small>
82+
)}
83+
{via.suggestion && via.id && !selectedViasTracks.includes(via.id) ? (
84+
<button
85+
className="btn btn-sm btn-only-icon"
86+
type="button"
87+
onClick={() => convertPathfindingVias(suggeredVias, idx - 1)}
88+
>
89+
<GoPlus />
90+
</button>
91+
) : (
92+
<button
93+
className="btn btn-sm btn-only-icon bg-dark"
94+
type="button"
95+
onClick={() => removeViaFromPath(via)}
96+
>
97+
<GoDash color="white" />
98+
</button>
99+
)}
100+
</div>
94101
</div>
95102
);
96103

@@ -104,7 +111,7 @@ export default function ModalSugerredVias({ removeAllVias, pathfindingInProgress
104111
</button>
105112
</ModalHeaderSNCF>
106113
<ModalBodySNCF>
107-
<div className="suggered-vias">
114+
<div className="suggested-vias">
108115
{pathfindingInProgress && <LoaderPathfindingInProgress />}
109116
{suggeredVias &&
110117
suggeredVias.map((via, idx) => {

front/src/modules/trainschedule/styles/ManageTrainSchedule/_itinerary.scss

+15-6
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
}
3535

3636
.manage-vias-modal {
37-
.suggered-vias {
37+
.suggested-vias {
3838
max-height: 30vh;
3939
overflow-y: auto;
4040
.loaderPathfindingInProgress {
@@ -48,11 +48,20 @@
4848
border-radius: 0 0 4px 4px;
4949
background-color: rgba(242, 242, 242, 0.75);
5050
}
51-
.suggerred-via-clickable {
52-
cursor: pointer;
53-
border-radius: 4px;
54-
&:hover {
55-
background-color: var(--coolgray1);
51+
.suggested-via {
52+
&-clickable {
53+
cursor: pointer;
54+
border-radius: 4px;
55+
&:hover {
56+
background-color: var(--coolgray1);
57+
}
58+
}
59+
60+
&-name {
61+
max-width: 47%;
62+
white-space: nowrap;
63+
overflow: hidden;
64+
text-overflow: ellipsis;
5665
}
5766
}
5867
}

front/src/reducers/osrdconf2/common/tests/commonConfBuilder.ts

+2
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ export default function commonConfBuilder() {
107107
type: 'Point',
108108
},
109109
suggestion: true,
110+
ch: null,
111+
uic: null,
110112
},
111113
],
112114
}),

front/src/reducers/osrdsimulation/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export interface Stop {
8080
track_number: number | null;
8181
line_name: string | null;
8282
track_name: string | null;
83+
ch?: string | null;
8384
}
8485

8586
export interface RouteAspect<Time = number, Color = number> {

0 commit comments

Comments
 (0)