Skip to content

Commit

Permalink
s
Browse files Browse the repository at this point in the history
  • Loading branch information
anisometropie committed Aug 14, 2024
1 parent c4b7678 commit 244baf6
Show file tree
Hide file tree
Showing 24 changed files with 775 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,17 @@ import {
import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext';
import { formatSuggestedOperationalPoints, upsertPathStepsInOPs } from 'modules/pathfinding/utils';
import { getSupportedElectrification, isThermal } from 'modules/rollingStock/helpers/electric';
import { updateDaySinceDeparture } from 'modules/timesStops/helpers/utils';
import { adjustConfWithTrainToModifyV2 } from 'modules/trainschedule/components/ManageTrainSchedule/helpers/adjustConfWithTrainToModify';
import type { SuggestedOP } from 'modules/trainschedule/components/ManageTrainSchedule/types';
import type {
SuggestedOP,
TimeExtraDays,
} from 'modules/trainschedule/components/ManageTrainSchedule/types';
import { setFailure } from 'reducers/main';
import type { OperationalStudiesConfSliceActions } from 'reducers/osrdconf/operationalStudiesConf';
import type { PathStep } from 'reducers/osrdconf/types';
import { useAppDispatch } from 'store';
import { addDurationToIsoDate } from 'utils/date';
import { addDurationToIsoDate, extractHHMMSS } from 'utils/date';
import { castErrorToFailure } from 'utils/error';
import { getPointCoordinates } from 'utils/geometry';
import { mmToM } from 'utils/physics';
Expand All @@ -33,8 +37,8 @@ type ItineraryForTrainUpdate = {
pathProperties: ManageTrainSchedulePathProperties;
};

const computeBasePathSteps = (trainSchedule: TrainScheduleResult) =>
trainSchedule.path.map((step) => {
const computeBasePathSteps = (trainSchedule: TrainScheduleResult) => {
const basePathSteps = trainSchedule.path.map((step) => {
const correspondingSchedule = trainSchedule.schedule?.find(
(schedule) => schedule.at === step.id
);
Expand Down Expand Up @@ -62,18 +66,26 @@ const computeBasePathSteps = (trainSchedule: TrainScheduleResult) =>
name = step.operational_point;
}

const fomattedArrival: TimeExtraDays | undefined = arrival
? { time: extractHHMMSS(addDurationToIsoDate(trainSchedule.start_time, arrival)) }
: undefined;
return {
...stepWithoutSecondaryCode,
ch: 'secondary_code' in step ? step.secondary_code : undefined,
name,
arrival: arrival
? addDurationToIsoDate(trainSchedule.start_time, arrival).substring(11, 19)
: arrival,
arrival: fomattedArrival,
stopFor: stopFor ? ISO8601Duration2sec(stopFor).toString() : stopFor,
locked,
onStopSignal,
} as PathStep;
});
// console.log(
// 'computeBasePathSteps',
// basePathSteps,
// updateDaySinceDeparture(basePathSteps, trainSchedule.start_time)
// );
return updateDaySinceDeparture(basePathSteps, trainSchedule.start_time);
};

const useSetupItineraryForTrainUpdate = (
setPathProperties: (pathProperties: ManageTrainSchedulePathProperties) => void,
Expand Down Expand Up @@ -185,6 +197,7 @@ const useSetupItineraryForTrainUpdate = (
});
}

// console.log('updatedPathSteps', trainSchedule, updatedPathSteps);
const allWaypoints = upsertPathStepsInOPs(suggestedOperationalPoints, updatedPathSteps);

return {
Expand Down
9 changes: 9 additions & 0 deletions front/src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,12 @@ export const DATA_TYPES = {
* A string with the format HH:MM:SS or HH:MM
*/
export type TimeString = string;

/**
* A string with the complete iso format
*
* @example "2024-08-08T10:12:46.209Z"
* @example "2024-08-08T10:12:46Z"
* @example "2024-08-08T10:12:46+02:00"
*/
export type IsoDateTimeString = string;
21 changes: 21 additions & 0 deletions front/src/modules/timesStops/ReadOnlyTime.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';

import type { CellProps } from 'react-datasheet-grid/dist/types';

import type { TimeExtraDays } from 'modules/trainschedule/components/ManageTrainSchedule/types';

type ReadOnlyTimeProps = CellProps<TimeExtraDays | null | undefined, string>;

const ReadOnlyTime = ({ rowData }: ReadOnlyTimeProps) => {
const { time, daySinceDeparture, dayDisplayed } = rowData || {};
if (time) {
const fullString =
daySinceDeparture !== undefined && dayDisplayed ? `${time} J+${daySinceDeparture}` : time;
return <div className="read-only-time">{fullString}</div>;
}
return null;
};

ReadOnlyTime.displayName = 'ReadOnlyTime';

export default ReadOnlyTime;
29 changes: 19 additions & 10 deletions front/src/modules/timesStops/TimeInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ import React, { useRef, useState, useEffect } from 'react';

import type { CellProps } from 'react-datasheet-grid/dist/types';

const TimeInput = ({
focus,
rowData,
active,
setRowData,
}: CellProps<string | null | undefined, string>) => {
import type { TimeExtraDays } from 'modules/trainschedule/components/ManageTrainSchedule/types';

type TimeInputProps = CellProps<TimeExtraDays | null | undefined, string>;

const TimeInput = ({ focus, rowData, active, setRowData }: TimeInputProps) => {
const ref = useRef<HTMLInputElement>(null);
const [tempTimeValue, setTempTimeValue] = useState<string | null | undefined>(rowData);
const [tempTimeValue, setTempTimeValue] = useState<TimeExtraDays | null | undefined>(rowData);

useEffect(() => {
if (active) {
Expand All @@ -26,7 +25,7 @@ const TimeInput = ({
setTempTimeValue(rowData);
}, [rowData]);

return (
const input = (
<input
className="dsg-input"
type="time"
Expand All @@ -37,9 +36,9 @@ const TimeInput = ({
pointerEvents: focus ? 'auto' : 'none',
opacity: rowData || active ? undefined : 0,
}}
value={tempTimeValue ?? ''}
value={tempTimeValue?.time ?? ''}
onChange={(e) => {
setTempTimeValue(e.target.value);
setTempTimeValue((prev) => ({ ...prev, time: e.target.value }));
}}
onBlur={() => {
// To prevent the operational point to be transformed into a via if we leave the cell empty after focusing it
Expand All @@ -49,6 +48,16 @@ const TimeInput = ({
}}
/>
);

if (tempTimeValue?.daySinceDeparture && tempTimeValue.dayDisplayed) {
return (
<div className="time-input-container">
{input}
<span className="extra-text">J+{tempTimeValue.daySinceDeparture}</span>
</div>
);
}
return input;
};

TimeInput.displayName = 'TimeInput';
Expand Down
29 changes: 19 additions & 10 deletions front/src/modules/timesStops/TimesStops.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import { isVia } from 'modules/pathfinding/utils';
import type { SuggestedOP } from 'modules/trainschedule/components/ManageTrainSchedule/types';
import type { PathStep } from 'reducers/osrdconf/types';
import { useAppDispatch } from 'store';
import { time2sec } from 'utils/timeManipulation';

import { marginRegExValidation } from './consts';
import { formatSuggestedViasToRowVias, transformRowDataOnChange } from './helpers/utils';
import {
formatSuggestedViasToRowVias,
updateRowTimesAndMargin,
updateDaySinceDeparture,
} from './helpers/utils';
import { useTimeStopsColumns } from './hooks/useTimeStopsColumns';
import { TableType } from './types';
import type { PathWaypointRow } from './types';
Expand Down Expand Up @@ -42,7 +44,7 @@ const TimesStops = ({
const { t } = useTranslation('timesStops');

const dispatch = useAppDispatch();
const { upsertViaFromSuggestedOP } = useOsrdConfActions();
const { upsertSeveralViasFromSuggestedOP } = useOsrdConfActions();

const [rows, setRows] = useState<PathWaypointRow[]>([]);

Expand All @@ -55,7 +57,7 @@ const TimesStops = ({
startTime,
tableType
);
setRows(suggestedOPs);
setRows(updateDaySinceDeparture(suggestedOPs, startTime, true, true));
}
}, [allWaypoints, pathSteps, startTime]);

Expand All @@ -74,15 +76,22 @@ const TimesStops = ({
className="time-stops-datasheet"
columns={columns}
value={rows}
onChange={(row: PathWaypointRow[], [op]) => {
onChange={(newRows: PathWaypointRow[], [op]) => {
if (!isInputTable) {
return;
}
const newRowData = transformRowDataOnChange(row[op.fromRowIndex], rows[op.fromRowIndex], op, allWaypoints.length);
if (!newRowData.isMarginValid) {
setRows(row);
let updatedRows = [...newRows];
updatedRows[op.fromRowIndex] = updateRowTimesAndMargin(
newRows[op.fromRowIndex],
rows[op.fromRowIndex],
op,
allWaypoints.length
);
updatedRows = updateDaySinceDeparture(updatedRows, startTime!);
if (!updatedRows[op.fromRowIndex].isMarginValid) {
setRows(newRows);
} else {
dispatch(upsertViaFromSuggestedOP(newRowData as SuggestedOP));
dispatch(upsertSeveralViasFromSuggestedOP(updatedRows.filter((row) => row.arrival)));
}
}}
stickyRightColumn={stickyRightColumn}
Expand Down
2 changes: 0 additions & 2 deletions front/src/modules/timesStops/TimesStopsInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ type TimesStopsInputProps = {
startTime: string;
pathSteps: PathStep[];
};

const TimesStopsinput = ({ allWaypoints, startTime, pathSteps }: TimesStopsInputProps) => {
const dispatch = useAppDispatch();
const { updatePathSteps } = useOsrdConfActions();
Expand All @@ -65,7 +64,6 @@ const TimesStopsinput = ({ allWaypoints, startTime, pathSteps }: TimesStopsInput

dispatch(updatePathSteps({ pathSteps: updatedPathSteps }));
};

return (
<TimesStops
allWaypoints={allWaypoints}
Expand Down
10 changes: 5 additions & 5 deletions front/src/modules/timesStops/TimesStopsOutput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { TrainScheduleResult } from 'common/api/osrdEditoastApi';
import { Loader } from 'common/Loaders/Loader';
import type { OperationalPointWithTimeAndSpeed } from 'modules/trainschedule/components/DriverTrainScheduleV2/types';
import type { PathStep } from 'reducers/osrdconf/types';
import { isoUtcStringToLocaleDateString } from 'utils/date';
import { convertIsoUtcToLocalTime } from 'utils/date';
import { NO_BREAK_SPACE } from 'utils/strings';

import useOutputTableData from './hooks/useOutputTableData';
Expand All @@ -31,12 +31,12 @@ const TimesStopsOutput = ({
simulatedTrain,
pathProperties,
operationalPoints,
selectedTrainSchedule,
selectedTrainSchedule, // coming straight from GET /train_schedule
pathSteps,
pathLength,
dataIsLoading,
}: TimesStopsOutputProps) => {
const startTime = isoUtcStringToLocaleDateString(selectedTrainSchedule.start_time);
const startTime = convertIsoUtcToLocalTime(selectedTrainSchedule.start_time);
const enrichedOperationalPoints = useOutputTableData(
simulatedTrain,
pathProperties,
Expand All @@ -59,8 +59,8 @@ const TimesStopsOutput = ({
tableType={TableType.Output}
cellClassName={({ rowData: rowData_ }) => {
const rowData = rowData_ as PathWaypointRow;
const arrivalScheduleNotRespected = rowData.arrival
? rowData.calculatedArrival !== rowData.arrival
const arrivalScheduleNotRespected = rowData?.arrival?.time
? rowData.calculatedArrival !== rowData.arrival.time
: false;
const negativeDiffMargins = Number(rowData.diffMargins?.split(NO_BREAK_SPACE)[0]) < 0;
return cx({
Expand Down
62 changes: 49 additions & 13 deletions front/src/modules/timesStops/helpers/__tests__/scheduleData.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,56 @@ import { describe, it, expect } from 'vitest';
import { computeScheduleData } from '../scheduleData';

describe('computeScheduleData', () => {
it('should compute simple arrival time in the correct timezone', () => {
const schedule = {
at: 'id325',
arrival: 'PT3600S',
stop_for: 'PT100S',
on_stop_signal: false,
locked: false,
};
const startTime = '2024-05-14T00:00:00Z';
describe('same day', () => {
it('should compute simple arrival time in the correct timezone', () => {
const schedule = {
at: 'id325',
arrival: 'PT3600S',
stop_for: 'PT100S',
on_stop_signal: false,
locked: false,
};
const startTime = '2024-05-14T00:00:00Z';

expect(computeScheduleData(schedule, startTime)).toEqual({
arrival: 3600,
departure: 3700,
stopFor: 100,
expect(computeScheduleData(schedule, startTime)).toEqual({
arrival: 3600,
departure: 3700,
stopFor: 100,
});
});
it('should compute simple arrival time in the correct timezone 2', () => {
const schedule = {
at: 'id325',
arrival: 'PT3600S',
stop_for: 'PT100S',
on_stop_signal: false,
locked: false,
};
const startTime = '2024-05-14T01:00:00Z';

expect(computeScheduleData(schedule, startTime)).toEqual({
arrival: 7200,
departure: 7300,
stopFor: 100,
});
});
});
describe('after midnight', () => {
it('should compute simple arrival time in the correct timezone', () => {
const schedule = {
at: 'id325',
arrival: 'PT3600S',
stop_for: 'PT100S',
on_stop_signal: false,
locked: false,
};
const startTime = '2024-05-14T23:50:00Z';

expect(computeScheduleData(schedule, startTime)).toEqual({
arrival: 3000,
departure: 3100,
stopFor: 100,
});
});
});
});
Loading

0 comments on commit 244baf6

Please sign in to comment.