Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

front: drop formatDurationAsISO8601() #10230

Draft
wants to merge 6 commits into
base: dev
Choose a base branch
from
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from 'common/api/osrdEditoastApi';
import type { AppDispatch } from 'store';
import { formatToIsoDate } from 'utils/date';
import { calculateTimeDifferenceInSeconds, formatDurationAsISO8601 } from 'utils/timeManipulation';
import { Duration } from 'utils/duration';

import type MacroEditorState from './MacroEditorState';
import type { NodeIndexed } from './MacroEditorState';
Expand Down Expand Up @@ -157,7 +157,7 @@ const getTimeLockDate = (
};

const formatDateDifference = (start: Date, stop: Date) =>
formatDurationAsISO8601(calculateTimeDifferenceInSeconds(start, stop));
Duration.subtractDate(stop, start).toString();

const createTrainSchedulePayload = async ({
trainrunSections,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, it, expect } from 'vitest';

import type { PathfindingResult } from 'common/api/osrdEditoastApi';
import { Duration } from 'utils/duration';

import { updatePathStepsFromOperationalPoints } from '../useSetupItineraryForTrainUpdate';

Expand Down Expand Up @@ -154,7 +155,7 @@ describe('updatePathStepsFrom', () => {
uic: 87747006,
secondary_code: 'P2',
name: '87747006',
arrival: '15:00:00',
arrival: Duration.parse('PT60S'),
stopFor: null,
},
{
Expand All @@ -164,7 +165,7 @@ describe('updatePathStepsFrom', () => {
secondary_code: 'BV',
name: '87747337',
arrival: null,
stopFor: '0',
stopFor: Duration.zero,
},
];
const pathFindingResult = {
Expand Down Expand Up @@ -198,7 +199,7 @@ describe('updatePathStepsFrom', () => {
uic: 87747006,
secondary_code: 'P2', // should not be BV here, it has the same uic but not the same ch
name: 'Grenadille',
arrival: '15:00:00',
arrival: Duration.parse('PT60S'),
stopFor: null,
kp: '129+952',
positionOnPath: 586000,
Expand Down Expand Up @@ -234,7 +235,7 @@ describe('updatePathStepsFrom', () => {
trigram: 'GE',
secondary_code: 'P2',
name: '87747006',
arrival: '15:00:00',
arrival: Duration.parse('PT60S'),
},
{
id: 'who-0',
Expand Down Expand Up @@ -272,7 +273,7 @@ describe('updatePathStepsFrom', () => {
trigram: 'GE',
secondary_code: 'P2',
name: 'Grenadille',
arrival: '15:00:00',
arrival: Duration.parse('PT60S'),
kp: '129+952',
positionOnPath: 586000,
coordinates: [5.711846462951984, 45.19643525506182],
Expand Down Expand Up @@ -303,7 +304,7 @@ describe('updatePathStepsFrom', () => {
trigram: 'GE',
secondary_code: 'P2',
name: '87747006',
arrival: '15:00:00',
arrival: Duration.parse('PT60S'),
},
{
id: 'who-0',
Expand Down Expand Up @@ -341,7 +342,7 @@ describe('updatePathStepsFrom', () => {
secondary_code: 'P2',
trigram: 'GE',
name: '87747006',
arrival: '15:00:00',
arrival: Duration.parse('PT60S'),
kp: undefined,
positionOnPath: 586000,
coordinates: [5.711846462951984, 45.19643525506182],
Expand Down
6 changes: 0 additions & 6 deletions front/src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@ export const DATA_TYPES = {
*/
export type TimeString = string;

/**
* A ISO 8601 duration string
* @example "PT3600S"
*/
export type IsoDurationString = string;

export type RangedValue = {
begin: number;
end: number;
Expand Down
4 changes: 3 additions & 1 deletion front/src/modules/pathfinding/hooks/usePathfinding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { setFailure, setWarning } from 'reducers/main';
import type { PathStep } from 'reducers/osrdconf/types';
import { useAppDispatch } from 'store';
import { isEmptyArray } from 'utils/array';
import { Duration } from 'utils/duration';
import { castErrorToFailure } from 'utils/error';

import useInfraStatus from './useInfraStatus';
Expand Down Expand Up @@ -131,7 +132,8 @@ const usePathfinding = (

const theoreticalMargin = i === 0 ? step.theoreticalMargin || '0%' : step.theoreticalMargin;

const stopFor = i === pathStepsInput.length - 1 && !step.stopFor ? '0' : step.stopFor;
const stopFor =
i === pathStepsInput.length - 1 && !step.stopFor ? Duration.zero : step.stopFor;
const stopType = i === pathStepsInput.length - 1 && !step.stopFor ? undefined : step.stopType;

return {
Expand Down
2 changes: 1 addition & 1 deletion front/src/modules/pathfinding/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const getPathfindingQuery = ({
export const upsertPathStepsInOPs = (ops: SuggestedOP[], pathSteps: PathStep[]): SuggestedOP[] => {
let updatedOPs = [...ops];
pathSteps.forEach((step) => {
const { stopFor, arrival, receptionSignal, theoreticalMargin } = step;
const { arrival, stopFor, receptionSignal, theoreticalMargin } = step;
// We check only for pathSteps added by map click
if ('track' in step) {
const formattedStep: SuggestedOP = {
Expand Down
5 changes: 4 additions & 1 deletion front/src/modules/timesStops/TimesStopsInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import type { SuggestedOP } from 'modules/trainschedule/components/ManageTrainSc
import type { OperationalStudiesConfSliceActions } from 'reducers/osrdconf/operationalStudiesConf';
import type { PathStep } from 'reducers/osrdconf/types';
import { useAppDispatch } from 'store';
import { Duration } from 'utils/duration';
import { sec2ms } from 'utils/timeManipulation';

import {
durationSinceStartTime,
Expand Down Expand Up @@ -119,11 +121,12 @@ const TimesStopsInput = ({
(row, index) =>
!isEqual(normalizeNullablesInRow(row), normalizeNullablesInRow(rows[index]))
)
.map(({ shortSlipDistance, onStopSignal, arrival, departure, ...row }) => ({
.map(({ shortSlipDistance, onStopSignal, arrival, departure, stopFor, ...row }) => ({
...row,
arrival: durationSinceStartTime(startTime, arrival),
departure: durationSinceStartTime(startTime, departure),
receptionSignal: onStopSignalToReceptionSignal(onStopSignal, shortSlipDistance),
stopFor: stopFor ? new Duration(sec2ms(Number(stopFor))) : null,
}));
dispatch(upsertSeveralViasFromSuggestedOP(newVias));
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, it, expect } from 'vitest';

import { type TimesStopsInputRow } from 'modules/timesStops/types';
import { Duration } from 'utils/duration';

import {
updateRowTimesAndMargin,
Expand Down Expand Up @@ -820,7 +821,7 @@ describe('durationSinceStartTime', () => {

const result = durationSinceStartTime(startTime, stepTimeDays);

expect(result).toBe('PT36000S');
expect(result).toEqual(Duration.parse('PT36000S'));
});

it('should return the correct duration. daySinceDeparture 1', () => {
Expand All @@ -832,14 +833,14 @@ describe('durationSinceStartTime', () => {

const result = durationSinceStartTime(startTime, stepTimeDays);

expect(result).toBe('PT90000S');
expect(result).toEqual(Duration.parse('PT90000S'));
});
});

describe('calculateStepTimeDays', () => {
it('should return correct time and daySinceDeparture', () => {
const startTime = new Date('2023-09-01T10:00:00Z');
const isoDuration = 'PT36000S'; // 10 hours
const isoDuration = Duration.parse('PT36000S'); // 10 hours

const result = calculateStepTimeAndDays(startTime, isoDuration);

Expand All @@ -851,7 +852,7 @@ describe('calculateStepTimeDays', () => {

it('should return correct time and daySinceDeparture, daySinceDeparture 1', () => {
const startTime = new Date('2023-09-01T10:00:00Z');
const isoDuration = 'PT122400S'; // 1 day 10 hours
const isoDuration = Duration.parse('PT122400S'); // 1 day 10 hours

const result = calculateStepTimeAndDays(startTime, isoDuration);

Expand Down
35 changes: 18 additions & 17 deletions front/src/modules/timesStops/helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,21 @@ import { round, isEqual, isNil } from 'lodash';
import { keyColumn, createTextColumn } from 'react-datasheet-grid';

import type { ReceptionSignal } from 'common/api/osrdEditoastApi';
import type { IsoDurationString, TimeString } from 'common/types';
import type { TimeString } from 'common/types';
import { matchPathStepAndOp } from 'modules/pathfinding/utils';
import type { SuggestedOP } from 'modules/trainschedule/components/ManageTrainSchedule/types';
import type { PathStep } from 'reducers/osrdconf/types';
import { Duration } from 'utils/duration';
import { msToS } from 'utils/physics';
import { NO_BREAK_SPACE } from 'utils/strings';
import {
calculateTimeDifferenceInSeconds,
datetime2sec,
durationInSeconds,
formatDurationAsISO8601,
sec2time,
SECONDS_IN_A_DAY,
secToHoursString,
time2sec,
ms2sec,
} from 'utils/timeManipulation';

import { marginRegExValidation, MarginUnit } from '../consts';
Expand Down Expand Up @@ -78,15 +79,17 @@ export const formatSuggestedViasToRowVias = (

const { arrival, receptionSignal, stopFor, theoreticalMargin } = objectToUse || {};

const stopForSeconds = stopFor ? ms2sec(stopFor.ms) : undefined;

const isMarginValid = theoreticalMargin ? marginRegExValidation.test(theoreticalMargin) : true;
const durationArrivalTime = i === 0 ? 'PT0S' : arrival;
const arrivalInSeconds = durationArrivalTime ? time2sec(durationArrivalTime) : null;
const arrivalDuration = i === 0 ? Duration.zero : arrival;
const arrivalInSeconds = arrivalDuration ? msToS(arrivalDuration.ms) : null;

const formattedArrival = calculateStepTimeAndDays(startTime, durationArrivalTime);
const formattedArrival = calculateStepTimeAndDays(startTime, arrivalDuration);

const departureTime =
stopFor && arrivalInSeconds
? secToHoursString(arrivalInSeconds + Number(stopFor), { withSeconds: true })
stopForSeconds !== undefined && arrivalInSeconds
? secToHoursString(arrivalInSeconds + stopForSeconds, { withSeconds: true })
: undefined;
const formattedDeparture: TimeExtraDays | undefined = departureTime
? { time: departureTime }
Expand All @@ -101,7 +104,7 @@ export const formatSuggestedViasToRowVias = (
onStopSignal,
name: name || t('waypoint', { id: filteredOp.pathStepId }),
shortSlipDistance,
stopFor,
stopFor: stopForSeconds !== undefined ? String(stopForSeconds) : undefined,
theoreticalMargin,
isWaypoint: op.isWaypoint || pathStep !== undefined,
};
Expand Down Expand Up @@ -282,7 +285,7 @@ export function updateDaySinceDeparture(
export function durationSinceStartTime(
startTime?: Date,
stepTimeDays?: TimeExtraDays
): IsoDurationString | null {
): Duration | null {
if (!startTime || !stepTimeDays?.time || stepTimeDays?.daySinceDeparture === undefined) {
return null;
}
Expand All @@ -291,23 +294,21 @@ export function durationSinceStartTime(
stepTimeDays.daySinceDeparture,
'day'
);
return formatDurationAsISO8601(
calculateTimeDifferenceInSeconds(start.toISOString(), step.toISOString())
);
return Duration.subtractDate(step.toDate(), startTime);
}

export function calculateStepTimeAndDays(
startTime?: Date | null,
isoDuration?: IsoDurationString | null
duration?: Duration | null
): TimeExtraDays | undefined {
if (!startTime || !isoDuration) {
if (!startTime || !duration) {
return undefined;
}

const start = dayjs(startTime);
const duration = dayjs.duration(isoDuration);
const dur = dayjs.duration(duration.ms);

const waypointArrivalTime = start.add(duration);
const waypointArrivalTime = start.add(dur);
const daySinceDeparture = waypointArrivalTime.diff(start, 'day');
const time: TimeString = waypointArrivalTime.format('HH:mm:ss');

Expand Down
3 changes: 2 additions & 1 deletion front/src/modules/timesStops/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export type TimesStopsRow = {
isMarginValid?: boolean;
};

export type TimesStopsInputRow = Omit<SuggestedOP, 'arrival' | 'departure'> & TimesStopsRow;
export type TimesStopsInputRow = Omit<SuggestedOP, 'arrival' | 'departure' | 'stopFor'> &
TimesStopsRow;

export enum TableType {
Input = 'Input',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import nextId from 'react-id-generator';
import type { ImportedTrainSchedule } from 'applications/operationalStudies/types';
import type { TrainScheduleBase } from 'common/api/osrdEditoastApi';
import { formatToIsoDate } from 'utils/date';
import { calculateTimeDifferenceInSeconds, formatDurationAsISO8601 } from 'utils/timeManipulation';
import { Duration } from 'utils/duration';

export function generateTrainSchedulesPayloads(
trains: ImportedTrainSchedule[],
Expand All @@ -19,6 +19,8 @@ export function generateTrainSchedulesPayloads(
return payloads; // Skip this train
}

const departureTime = new Date(train.departureTime);

const { path, schedule } = train.steps.reduce(
(acc, step, index) => {
const stepId = nextId();
Expand All @@ -37,13 +39,10 @@ export function generateTrainSchedulesPayloads(

// Skip first step, handle time differences
if (index !== 0) {
const timeDifferenceInSeconds = calculateTimeDifferenceInSeconds(
train.departureTime,
step.arrivalTime
);
const arrivalTime = new Date(step.arrivalTime);
const schedulePoint: NonNullable<TrainScheduleBase['schedule']>[number] = {
at: stepId,
arrival: formatDurationAsISO8601(timeDifferenceInSeconds),
arrival: Duration.subtractDate(arrivalTime, departureTime).toString(),
stop_for: step.duration ? `PT${step.duration}S` : undefined,
};
acc.schedule.push(schedulePoint);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { describe, expect, it } from 'vitest';

import type { PathStep } from 'reducers/osrdconf/types';
import { Duration } from 'utils/duration';

import formatSchedule from '../formatSchedule';

Expand Down Expand Up @@ -31,16 +32,16 @@ describe('formatSchedule', () => {
kp: '117+422',
name: 'V',
positionOnPath: 13116000,
arrival: 'PT60S',
stopFor: '0',
arrival: Duration.parse('PT60S'),
stopFor: Duration.zero,
locked: false,
receptionSignal: 'OPEN',
},
];
const result = formatSchedule(pathSteps);
expect(result).toEqual([
{
arrival: 'PT60S',
arrival: 'PT1M',
at: 'id332',
locked: false,
reception_signal: 'OPEN',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import { compact, isNaN, isNil } from 'lodash';
import { compact } from 'lodash';

import type { TrainScheduleBase } from 'common/api/osrdEditoastApi';
import type { PathStep } from 'reducers/osrdconf/types';
import { formatDurationAsISO8601 } from 'utils/timeManipulation';

const formatSchedule = (pathSteps: PathStep[]): TrainScheduleBase['schedule'] => {
const schedules = pathSteps.map((step) => {
if (step?.arrival || step.stopFor) {
return {
at: step.id,
arrival: step.arrival ?? undefined,
arrival: step.arrival?.toString() ?? undefined,
locked: step.locked,
reception_signal: step.receptionSignal,
stop_for:
isNil(step.stopFor) || isNaN(Number(step.stopFor))
? undefined
: formatDurationAsISO8601(Number(step.stopFor)),
stop_for: step.stopFor ? step.stopFor.toString() : undefined,
};
}
return undefined;
Expand Down
Loading
Loading