;
opId: string;
isOrigin?: boolean;
};
-const defaultDate = (date?: Date) => {
- const newDate = date ? new Date(date) : new Date();
- newDate.setHours(0, 0, 0);
- return newDate;
-};
-
-const StdcmOpSchedule = ({
- disabled,
- onArrivalChange,
- onArrivalTypeChange,
- onArrivalToleranceChange,
- opTimingData,
- opScheduleTimeType,
- opToleranceValues,
- opId,
- isOrigin = false,
-}: StdcmOpScheduleProps) => {
+const StdcmOpSchedule = ({ disabled, pathStep, opId, isOrigin = false }: StdcmOpScheduleProps) => {
const { t } = useTranslation('stdcm');
+ const dispatch = useAppDispatch();
+
+ const { updateStdcmPathStep } = useOsrdConfActions() as StdcmConfSliceActions;
const { getSearchDatetimeWindow } = useOsrdConfSelectors();
const searchDatetimeWindow = useSelector(getSearchDatetimeWindow);
- const { arrivalDate, arrivalTime, arrivalTimeHours, arrivalTimeMinutes, arrivalToleranceValues } =
- useMemo(() => {
- const isArrivalDateValid =
- opTimingData?.arrivalDate &&
- isArrivalDateInSearchTimeWindow(opTimingData.date, searchDatetimeWindow);
-
+ const { arrivalTime, arrivalTimeHours, arrivalTimeMinutes } = useMemo(() => {
+ if (!pathStep.arrival) {
return {
- arrivalDate:
- opTimingData && isArrivalDateValid
- ? opTimingData.date
- : defaultDate(searchDatetimeWindow?.begin),
- arrivalTime: opTimingData?.arrivalTime,
- arrivalTimeHours: opTimingData?.arrivalTimeHours,
- arrivalTimeMinutes: opTimingData?.arrivalTimeMinutes,
- arrivalToleranceValues: {
- minusTolerance: opToleranceValues.arrivalToleranceBefore,
- plusTolerance: opToleranceValues.arrivalToleranceAfter,
- },
+ arrivalTime: undefined,
+ arrivalTimeHours: undefined,
+ arrivalTimeMinutes: undefined,
};
- }, [opTimingData, opToleranceValues, searchDatetimeWindow]);
+ }
+ return {
+ arrivalTime: dateToHHMMSS(pathStep.arrival, { withoutSeconds: true }),
+ arrivalTimeHours: pathStep.arrival.getHours(),
+ arrivalTimeMinutes: pathStep.arrival.getMinutes(),
+ };
+ }, [pathStep.arrival]);
+
+ const tolerances = useMemo(
+ () => ({
+ minusTolerance: pathStep.tolerances?.before || 0,
+ plusTolerance: pathStep.tolerances?.after || 0,
+ }),
+ [pathStep.tolerances]
+ );
const selectableSlot = useMemo(
() =>
@@ -101,26 +73,27 @@ const StdcmOpSchedule = ({
[t, searchDatetimeWindow]
);
- useEffect(() => {
- if (
- (!isArrivalDateInSearchTimeWindow(arrivalDate, searchDatetimeWindow) ||
- !opTimingData?.arrivalDate) &&
- opScheduleTimeType === 'preciseTime'
- ) {
- onArrivalChange({
- date: defaultDate(searchDatetimeWindow?.begin),
- hours: arrivalTimeHours || 0,
- minutes: arrivalTimeMinutes || 0,
- });
- }
- }, [searchDatetimeWindow, opScheduleTimeType]);
+ const onArrivalChange = ({ date, hours, minutes }: ScheduleConstraint) => {
+ const newDate = new Date(date);
+ newDate.setHours(hours, minutes);
+ dispatch(
+ updateStdcmPathStep({
+ id: pathStep.id,
+ updates: { arrival: newDate },
+ })
+ );
+ };
+
+ const onArrivalTypeChange = (arrivalType: ArrivalTimeTypes) => {
+ dispatch(updateStdcmPathStep({ id: pathStep.id, updates: { arrivalType } }));
+ };
return (
<>
- {opScheduleTimeType === 'preciseTime' && (
+ {pathStep.arrivalType === 'preciseTime' && (
{
onArrivalChange({
date: e,
@@ -161,7 +134,11 @@ const StdcmOpSchedule = ({
hours={arrivalTimeHours}
minutes={arrivalTimeMinutes}
onTimeChange={({ hours, minutes }) => {
- onArrivalChange({ date: arrivalDate, hours, minutes });
+ onArrivalChange({
+ date: pathStep.arrival || searchDatetimeWindow!.begin,
+ hours,
+ minutes,
+ });
}}
disabled={disabled}
value={arrivalTime}
@@ -171,13 +148,15 @@ const StdcmOpSchedule = ({
{}}
onToleranceChange={({ minusTolerance, plusTolerance }) => {
- onArrivalToleranceChange({
- toleranceBefore: minusTolerance,
- toleranceAfter: plusTolerance,
- });
+ dispatch(
+ updateStdcmPathStep({
+ id: pathStep.id,
+ updates: { tolerances: { before: minusTolerance, after: plusTolerance } },
+ })
+ );
}}
disabled={disabled}
/>
diff --git a/front/src/applications/stdcm/components/StdcmForm/StdcmOrigin.tsx b/front/src/applications/stdcm/components/StdcmForm/StdcmOrigin.tsx
index bc934810e45..63b760c2bac 100644
--- a/front/src/applications/stdcm/components/StdcmForm/StdcmOrigin.tsx
+++ b/front/src/applications/stdcm/components/StdcmForm/StdcmOrigin.tsx
@@ -1,74 +1,21 @@
-import { useMemo } from 'react';
-
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
-import { getTimesInfoFromDate } from 'applications/stdcm/utils';
import OriginIcon from 'assets/pictures/mapMarkers/start.svg';
-import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext';
-import type { StdcmConfSliceActions } from 'reducers/osrdconf/stdcmConf';
+import { useOsrdConfSelectors } from 'common/osrdContext';
import type { StdcmConfSelectors } from 'reducers/osrdconf/stdcmConf/selectors';
-import { useAppDispatch } from 'store';
import StdcmCard from './StdcmCard';
import StdcmOperationalPoint from './StdcmOperationalPoint';
import StdcmOpSchedule from './StdcmOpSchedule';
-import type { ArrivalTimeTypes, ScheduleConstraint, StdcmConfigCardProps } from '../../types';
+import type { StdcmConfigCardProps } from '../../types';
const StdcmOrigin = ({ disabled = false }: StdcmConfigCardProps) => {
const { t } = useTranslation('stdcm');
- const dispatch = useAppDispatch();
const { getStdcmOrigin } = useOsrdConfSelectors() as StdcmConfSelectors;
const origin = useSelector(getStdcmOrigin);
- const { updateStdcmPathStep } = useOsrdConfActions() as StdcmConfSliceActions;
-
- const { originArrival, originToleranceValues } = useMemo(
- () => ({
- originArrival: getTimesInfoFromDate(origin.arrival),
- originToleranceValues: {
- arrivalToleranceBefore: origin.tolerances?.before || 0,
- arrivalToleranceAfter: origin.tolerances?.after || 0,
- },
- }),
- [origin]
- );
-
- const onOriginArrivalChange = ({ date, hours, minutes }: ScheduleConstraint) => {
- date.setHours(hours, minutes);
- dispatch(
- updateStdcmPathStep({
- id: origin.id,
- updates: { arrival: date },
- })
- );
- };
-
- const onOriginArrivalTypeChange = (arrivalType: ArrivalTimeTypes) => {
- dispatch(
- updateStdcmPathStep({
- id: origin.id,
- updates: { arrivalType },
- })
- );
- };
-
- const onOriginToleranceChange = ({
- toleranceBefore,
- toleranceAfter,
- }: {
- toleranceBefore: number;
- toleranceAfter: number;
- }) => {
- dispatch(
- updateStdcmPathStep({
- id: origin.id,
- updates: { tolerances: { before: toleranceBefore, after: toleranceAfter } },
- })
- );
- };
-
return (
{
pathStepId={origin.id}
disabled={disabled}
/>
-
+
);
};
diff --git a/front/src/reducers/osrdconf/stdcmConf/index.ts b/front/src/reducers/osrdconf/stdcmConf/index.ts
index be8576ee1e5..27cfa0d9674 100644
--- a/front/src/reducers/osrdconf/stdcmConf/index.ts
+++ b/front/src/reducers/osrdconf/stdcmConf/index.ts
@@ -11,6 +11,7 @@ import {
import { defaultCommonConf, buildCommonConfReducers } from 'reducers/osrdconf/osrdConfCommon';
import type { OsrdStdcmConfState, StdcmPathStep } from 'reducers/osrdconf/types';
import { addElementAtIndex } from 'utils/array';
+import { isArrivalDateInSearchTimeWindow } from 'utils/date';
import type { ArrayElement } from 'utils/types';
const DEFAULT_TOLERANCE = 1800; // 30min
@@ -127,11 +128,34 @@ export const stdcmConfSlice = createSlice({
state.timetableID = action.payload.timetableID;
state.electricalProfileSetId = action.payload.electricalProfileSetId;
state.searchDatetimeWindow = action.payload.searchDatetimeWindow;
- if (action.payload.workScheduleGroupId) {
- state.workScheduleGroupId = action.payload.workScheduleGroupId;
- }
- if (action.payload.temporarySpeedLimitGroupId) {
- state.temporarySpeedLimitGroupId = action.payload.temporarySpeedLimitGroupId;
+ state.workScheduleGroupId = action.payload.workScheduleGroupId;
+ state.temporarySpeedLimitGroupId = action.payload.temporarySpeedLimitGroupId;
+
+ // check that the arrival dates are in the search time window
+ const { searchDatetimeWindow } = action.payload;
+ if (searchDatetimeWindow) {
+ const origin = state.stdcmPathSteps.at(0)! as Extract;
+ const destination = state.stdcmPathSteps.at(-1)! as Extract<
+ StdcmPathStep,
+ { isVia: false }
+ >;
+ let newOrigin = origin;
+ let newDestination = destination;
+
+ if (
+ !origin.arrival ||
+ !isArrivalDateInSearchTimeWindow(origin.arrival, searchDatetimeWindow)
+ ) {
+ newOrigin = { ...origin, arrival: searchDatetimeWindow.begin };
+ }
+ if (
+ !destination.arrival ||
+ !isArrivalDateInSearchTimeWindow(destination.arrival, searchDatetimeWindow)
+ ) {
+ newDestination = { ...destination, arrival: searchDatetimeWindow.end };
+ }
+
+ state.stdcmPathSteps = [newOrigin, ...state.stdcmPathSteps.slice(1, -1), newDestination];
}
},
updateStdcmPathSteps(
diff --git a/front/src/reducers/osrdconf/types.ts b/front/src/reducers/osrdconf/types.ts
index 5179206b930..1999f987283 100644
--- a/front/src/reducers/osrdconf/types.ts
+++ b/front/src/reducers/osrdconf/types.ts
@@ -102,6 +102,7 @@ export type StdcmPathStep = {
| {
isVia: false;
arrivalType: ArrivalTimeTypes;
+ // TODO: make arrival non nullable (/!\ store migration)
arrival?: Date;
tolerances?: { before: number; after: number };
}