Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions front/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion front/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"@ag-media/react-pdf-table": "^2.0.3",
"@nivo/core": "^0.99.0",
"@nivo/line": "^0.99.0",
"@osrd-project/netzgrafik-frontend": "0.0.0-snapshot.5eafed2a3fd1e8818d84679046e2c2274a948bc1",
"@osrd-project/netzgrafik-frontend": "0.0.0-snapshot.09bd436ff2dd9d6422a08dc05f9a551c7382e642",
"@osrd-project/ui-charts": "0.0.1-dev",
"@osrd-project/ui-core": "0.0.1-dev",
"@osrd-project/ui-icons": "0.0.1-dev",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const handleLabelOperation = async ({
await handleUpdateTimetableItem({
netzgrafikDto,
trainrun,
tags: ['labelIds'],
trainScheduleSetId,
infraId,
state,
Expand Down Expand Up @@ -104,9 +105,8 @@ export const handleOperation = async ({
break;
case 'trainrun': {
await handleTrainrunOperation({
type,
netzgrafikDto,
trainrunId: event.trainrun.id,
trainrunEvent: event,
trainScheduleSetId,
infraId,
state,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ import { isPacedTrainId } from 'utils/trainId';
import { checkChangeGroups } from '../../ManageTimetableItem/helpers/buildPacedTrainException';
import type {
NetzgrafikDto,
NGEEvent,
TrainrunSectionDto,
NodeDto,
TimeLockDto,
TrainrunDto,
NGETrainrunEvent,
TrainrunUpdateTag,
} from '../../NGE/types';
import {
DEFAULT_TRAIN_SCHEDULE_PAYLOAD,
Expand Down Expand Up @@ -388,12 +389,25 @@ export const createPacedAttributesFromTrainrun = (
const handleCreateTimetableItem = async (
netzgrafikDto: NetzgrafikDto,
trainrun: TrainrunDto,
duplicatedTrainrunId: number | undefined,
trainScheduleSetId: number,
infraId: number,
state: MacroEditorState,
dispatch: AppDispatch,
addUpsertedTimetableItems: (timetableItems: TimetableItem[]) => void
) => {
const duplicatedTimetableItemIds = duplicatedTrainrunId
? state.timetableItemIdByNgeId.get(duplicatedTrainrunId)
: undefined;
const duplicatedForwardTimetableItem = duplicatedTimetableItemIds?.[0]
? await fetchTimetableItem(duplicatedTimetableItemIds[0], dispatch)
: { id: undefined, train_name: undefined };
const duplicatedReturnTimetableItem = duplicatedTimetableItemIds?.[1]
? await fetchTimetableItem(duplicatedTimetableItemIds[1], dispatch)
: { id: undefined, train_name: undefined };
const { id: _id, train_name: _name, ...duplicatedForwardBase } = duplicatedForwardTimetableItem;
const { id: __id, train_name: __name, ...duplicatedReturnBase } = duplicatedReturnTimetableItem;
Comment on lines +408 to +409
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete id
delete train_name


const trainrunSections = getContinuousTrainrunSectionsByTrainrunId(netzgrafikDto, trainrun.id);
const labels = getTrainrunLabels(netzgrafikDto, trainrun);

Expand Down Expand Up @@ -431,11 +445,14 @@ const handleCreateTimetableItem = async (
train_name: trainrun.name,
labels,
category,
...duplicatedForwardBase,
...pathAndSchedule,
};

const returnTrip =
trainrun.direction === 'round_trip' ? { ...forwardTrip, ...returnPathAndSchedule } : undefined;
trainrun.direction === 'round_trip'
? { ...forwardTrip, ...duplicatedReturnBase, ...returnPathAndSchedule }
: undefined;

const timetableItemsToCreate = returnTrip ? [forwardTrip, returnTrip] : [forwardTrip];

Expand Down Expand Up @@ -494,6 +511,8 @@ const handleDeleteTimetableItem = async (
export const handleUpdateTimetableItem = async ({
netzgrafikDto,
trainrun,
tags,
oneWayDirection,
trainScheduleSetId,
infraId,
state,
Expand All @@ -503,6 +522,8 @@ export const handleUpdateTimetableItem = async ({
}: {
netzgrafikDto: NetzgrafikDto;
trainrun: TrainrunDto;
tags: TrainrunUpdateTag[];
oneWayDirection?: 'forward' | 'backward';
infraId: number;
trainScheduleSetId: number;
state: MacroEditorState;
Expand All @@ -511,17 +532,24 @@ export const handleUpdateTimetableItem = async ({
addDeletedTimetableItemIds: (timetableItemIds: TimetableItemId[]) => void;
}) => {
const timetableItemIds = state.timetableItemIdByNgeId.get(trainrun.id)!;
const oldForwardTimetableItem = await fetchTimetableItem(timetableItemIds[0], dispatch);
let oldForwardId = timetableItemIds[0];
if (oneWayDirection === 'backward') {
// Case 1: Switching from round trip to the return trip (now forward)
if (timetableItemIds[1]) oldForwardId = timetableItemIds[1];
// Case 2: Inverting the direction of a one way train (we sadly don't store the old return)
else tags.push('nodes', 'times');
}
const oldForwardTimetableItem = await fetchTimetableItem(oldForwardId, dispatch);
const trainrunSections = getContinuousTrainrunSectionsByTrainrunId(netzgrafikDto, trainrun.id);
const labels = getTrainrunLabels(netzgrafikDto, trainrun);
const forwardPathAndSchedule = generatePathAndSchedule(
const { path: forwardPath, ...forwardSchedule } = generatePathAndSchedule(
trainrunSections,
netzgrafikDto.nodes,
new Date(oldForwardTimetableItem.start_time),
TRAINRUN_DIRECTIONS.FORWARD,
state
);
await populateSecondaryCodesInPath(forwardPathAndSchedule.path, infraId, dispatch);
await populateSecondaryCodesInPath(forwardPath, infraId, dispatch);

const { id: _id, ...timetableItemBase } = oldForwardTimetableItem;

Expand All @@ -534,13 +562,13 @@ export const handleUpdateTimetableItem = async ({

const newForwardTrainBase: Omit<TrainScheduleResponse, 'id'> = {
...timetableItemBase,
train_name: trainrun.name,
labels,
// Reset margins because they contain references to path items
margins: undefined,
paced,
category,
...forwardPathAndSchedule,
...(tags.includes('name') && { train_name: trainrun.name }),
...(tags.includes('labelIds') && { labels }),
// Reset margins if the path changed because they contain references to path items
...(tags.includes('nodes') && { path: forwardPath, margins: undefined, ...forwardSchedule }),
...(tags.includes('times') && { ...forwardSchedule }),
...(tags.includes('frequencyId') && { paced }),
...(tags.includes('categoryId') && { category }),
};

if (paced && oldForwardTimetableItem.paced) {
Expand All @@ -562,25 +590,25 @@ export const handleUpdateTimetableItem = async ({

if (trainrun.direction === 'one_way') {
if (timetableItemIds[1]) {
// NGE always selects the forward trip by default when going from round trip to one way trip,
// thus the trip that needs to be deleted is always the return trip
await storeRoundTrip(dispatch, newForwardTimetableItem.id);
await deleteTimetableItemById(timetableItemIds[1], dispatch, addDeletedTimetableItemIds);
const oldReturnId =
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idToDelete

oneWayDirection !== 'backward' ? timetableItemIds[1] : timetableItemIds[0];
await deleteTimetableItemById(oldReturnId, dispatch, addDeletedTimetableItemIds);
}

state.timetableItemIdByNgeId.set(trainrun.id, [newForwardTimetableItem.id, null]);
return;
}

const returnPathAndSchedule = generatePathAndSchedule(
const { path: returnPath, ...returnSchedule } = generatePathAndSchedule(
trainrunSections,
netzgrafikDto.nodes,
new Date(oldForwardTimetableItem.start_time),
TRAINRUN_DIRECTIONS.BACKWARD,
state
);

await populateSecondaryCodesInPath(returnPathAndSchedule.path, infraId, dispatch);
await populateSecondaryCodesInPath(returnPath, infraId, dispatch);

let newReturnTimetableItem: TimetableItem;
const returnPaced: TrainSchedule['paced'] = paced ? { ...paced, exceptions: [] } : null;
Expand All @@ -591,13 +619,16 @@ export const handleUpdateTimetableItem = async ({
const { id: _return_id, ...oldReturnTrainBase } = oldReturnTimetableItem;
const newReturnTrainBase: Omit<TrainScheduleResponse, 'id'> = {
...oldReturnTrainBase,
train_name: trainrun.name,
labels,
// Reset margins because they contain references to path items
margins: undefined,
paced: returnPaced,
category,
...returnPathAndSchedule,
...(tags.includes('name') && { train_name: trainrun.name }),
...(tags.includes('labelIds') && { labels }),
// Reset margins if the path changed because they contain references to path items
...(tags.includes('nodes') && { path: returnPath, margins: undefined, ...returnSchedule }),
...(tags.includes('times') && {
schedule: returnSchedule.schedule,
start_time: returnSchedule.start_time,
}),
...(tags.includes('frequencyId') && { paced: returnPaced }),
...(tags.includes('categoryId') && { category }),
};

if (returnPaced && oldReturnTimetableItem.paced) {
Expand Down Expand Up @@ -625,7 +656,8 @@ export const handleUpdateTimetableItem = async ({

const returnPacedTrain: TrainSchedule = {
...pacedTrainWithoutTrainScheduleSetId,
...returnPathAndSchedule,
...returnSchedule,
path: returnPath,
paced: returnPaced,
};

Expand All @@ -646,32 +678,31 @@ export const handleUpdateTimetableItem = async ({
};

export const handleTrainrunOperation = async ({
type,
netzgrafikDto,
trainrunId,
trainrunEvent,
trainScheduleSetId,
infraId,
state,
dispatch,
addUpsertedTimetableItems,
addDeletedTimetableItemIds,
}: {
type: NGEEvent['type'];
netzgrafikDto: NetzgrafikDto;
trainrunId: number;
trainrunEvent: NGETrainrunEvent;
trainScheduleSetId: number;
infraId: number;
state: MacroEditorState;
dispatch: AppDispatch;
addUpsertedTimetableItems: (timetableItems: TimetableItem[]) => void;
addDeletedTimetableItemIds: (timetableItemIds: TimetableItemId[]) => void;
}) => {
const trainrun = netzgrafikDto.trainruns.find((tr) => tr.id === trainrunId);
switch (type) {
const trainrun = trainrunEvent.trainrun;
switch (trainrunEvent.type) {
case 'create': {
await handleCreateTimetableItem(
netzgrafikDto,
trainrun!,
trainrun,
trainrunEvent.duplicatedTrainrunId,
trainScheduleSetId,
infraId,
state,
Expand All @@ -683,7 +714,9 @@ export const handleTrainrunOperation = async ({
case 'update': {
await handleUpdateTimetableItem({
netzgrafikDto,
trainrun: trainrun!,
trainrun,
tags: trainrunEvent.tags,
oneWayDirection: trainrunEvent.oneWayDirection,
trainScheduleSetId,
infraId,
dispatch,
Expand All @@ -694,7 +727,7 @@ export const handleTrainrunOperation = async ({
break;
}
case 'delete': {
await handleDeleteTimetableItem(trainrunId, state, dispatch, addDeletedTimetableItemIds);
await handleDeleteTimetableItem(trainrun.id, state, dispatch, addDeletedTimetableItemIds);
break;
}
default:
Expand Down Expand Up @@ -738,6 +771,7 @@ export const updateTrainrunsByNode = async ({
await handleUpdateTimetableItem({
netzgrafikDto,
trainrun,
tags: ['nodes'],
trainScheduleSetId,
infraId,
dispatch,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,17 +220,46 @@ export type NetzgrafikDto = {
};
};

export type NGEEvent = {
type: 'create' | 'delete' | 'update';
} & (
export type TrainrunUpdateTag =
| 'nodes'
| 'times'
| 'numberOfStops'
| 'name'
| 'categoryId'
| 'frequencyId'
| 'timeCategoryId'
| 'labelIds'
| 'direction';

export type NGETrainrunEvent =
| {
type: 'create';
objectType: 'trainrun';
trainrun: TrainrunDto;
duplicatedTrainrunId?: number;
}
| {
type: 'update';
objectType: 'trainrun';
trainrun: TrainrunDto;
tags: TrainrunUpdateTag[];
oneWayDirection?: 'forward' | 'backward';
}
| { objectType: 'node'; node: NodeDto }
| { objectType: 'label'; label: LabelDto }
| { objectType: 'note'; note: FreeFloatingTextDto }
);
| {
type: 'delete';
objectType: 'trainrun';
trainrun: TrainrunDto;
};

export type NGEEvent =
| NGETrainrunEvent
| ({
type: 'create' | 'delete' | 'update';
} & (
| { objectType: 'node'; node: NodeDto }
| { objectType: 'label'; label: LabelDto }
| { objectType: 'note'; note: FreeFloatingTextDto }
));

export type LabelDto = {
id: number | string;
Expand Down
Loading