Skip to content

Commit

Permalink
front: create component for times and stop train schedule v2
Browse files Browse the repository at this point in the history
- add column name, ch, duration

- add data for add data test for mock api endpoint

- add columns reception on closed signal an theoretical margin

- regex validation margin

- add allVias property to ManageTrainSchedulePathProperties

- modif insertViasInOPs to upsertViasInOPs

- StdcmView: change inserViasInOPs to upserViasInOPs
- update TimeColumnComponent

- create function formatMargin and formatSchedule

- format arrival for schedule

- remove departure in TimesStops
- add toast error if the margin is invalid

- add remove error toast
- add remove vias button

- fix review comments

- fix bug when deleted the itinerary

- fix review comments
  • Loading branch information
Uriel-Sautron authored and clarani committed May 30, 2024
1 parent ad36fe5 commit 4ae7056
Show file tree
Hide file tree
Showing 29 changed files with 461 additions and 69 deletions.
9 changes: 9 additions & 0 deletions front/public/locales/en/timesStops.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "Name",
"stopTime": "Stopping Time (s)",
"arrivalTime": "Arrival Time",
"receptionOnClosedSignal": "Reception on Closed Signal",
"theoreticalMargin": "Theoretical Margin",
"theoreticalMarginPlaceholder": "% or min/100km",
"waypoint": "Waypoint {{id}}"
}
9 changes: 9 additions & 0 deletions front/public/locales/fr/timesStops.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "Nom",
"stopTime": "Temps d'arrêt (s)",
"arrivalTime": "Heure d'arrivée",
"receptionOnClosedSignal": "Réception sur signal fermé",
"theoreticalMargin": "Marge théorique",
"theoreticalMarginPlaceholder": "% ou min/100km",
"waypoint": "Via {{id}}"
}
12 changes: 5 additions & 7 deletions front/src/applications/operationalStudies/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
type PostV2InfraByInfraIdPathfindingBlocksApiArg,
} from 'common/api/osrdEditoastApi';
import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext';
import { formatSuggestedOperationalPoints, insertViasInOPs } from 'modules/pathfinding/utils';
import { formatSuggestedOperationalPoints, upsertViasInOPs } from 'modules/pathfinding/utils';
import { getSupportedElectrification, isThermal } from 'modules/rollingStock/helpers/electric';
import { adjustConfWithTrainToModifyV2 } from 'modules/trainschedule/components/ManageTrainSchedule/helpers/adjustConfWithTrainToModify';
import type { SuggestedOP } from 'modules/trainschedule/components/ManageTrainSchedule/types';
Expand Down Expand Up @@ -99,16 +99,14 @@ export const useSetupItineraryForTrainUpdate = (
geometry,
pathfindingResult.length
);
// TODO TS2 : update operational_points property with vias added on map included in trainSchedule.path
const updatedSuggestedOPs = insertViasInOPs(
suggestedOperationalPoints,
formatedPathSteps
);

const allVias = upsertViasInOPs(suggestedOperationalPoints, formatedPathSteps);

setPathProperties({
electrifications,
geometry,
suggestedOperationalPoints: updatedSuggestedOPs,
suggestedOperationalPoints,
allVias,
length: pathfindingResult.length,
});

Expand Down
3 changes: 2 additions & 1 deletion front/src/applications/operationalStudies/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ export type TrainScheduleImportConfig = {
export type ManageTrainSchedulePathProperties = {
electrifications: NonNullable<PathProperties['electrifications']>;
geometry: NonNullable<PathProperties['geometry']>;
/** Operational points along the path and vias added by clicking on map */
suggestedOperationalPoints: SuggestedOP[];
/** Operational points along the path and vias added by clicking on map */
allVias: SuggestedOP[];
length: number;
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';

import { compact } from 'lodash';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';

Expand All @@ -13,19 +14,22 @@ import SpeedLimitByTagSelector from 'common/SpeedLimitByTagSelector/SpeedLimitBy
import { useStoreDataForSpeedLimitByTagSelector } from 'common/SpeedLimitByTagSelector/useStoreDataForSpeedLimitByTagSelector';
import Tabs from 'common/Tabs';
import ItineraryV2 from 'modules/pathfinding/components/Itinerary/ItineraryV2';
import { upsertViasInOPs } from 'modules/pathfinding/utils';
import RollingStock2Img from 'modules/rollingStock/components/RollingStock2Img';
import { RollingStockSelector } from 'modules/rollingStock/components/RollingStockSelector';
import { useStoreDataForRollingStockSelector } from 'modules/rollingStock/components/RollingStockSelector/useStoreDataForRollingStockSelector';
import TimesStops from 'modules/timesStops/TimesStops';
import { Map } from 'modules/trainschedule/components/ManageTrainSchedule';
import ElectricalProfiles from 'modules/trainschedule/components/ManageTrainSchedule/ElectricalProfiles';
import TrainSettings from 'modules/trainschedule/components/ManageTrainSchedule/TrainSettings';
import { formatKmValue } from 'utils/strings';

const ManageTrainScheduleV2 = () => {
const { t } = useTranslation(['operationalStudies/manageTrainSchedule']);
const { getOriginV2, getDestinationV2 } = useOsrdConfSelectors();
const { getOriginV2, getDestinationV2, getPathSteps } = useOsrdConfSelectors();
const origin = useSelector(getOriginV2);
const destination = useSelector(getDestinationV2);
const pathSteps = useSelector(getPathSteps);

const [pathProperties, setPathProperties] = useState<ManageTrainSchedulePathProperties>();

Expand All @@ -35,6 +39,19 @@ const ManageTrainScheduleV2 = () => {
const { rollingStockId, rollingStockComfort, rollingStock } =
useStoreDataForRollingStockSelector();

useEffect(() => {
if (pathProperties) {
const allVias = upsertViasInOPs(
pathProperties.suggestedOperationalPoints,
compact(pathSteps)
);
setPathProperties({
...pathProperties,
allVias,
});
}
}, [pathSteps]);

// TODO TS2 : test this hook in simulation results issue
// useSetupItineraryForTrainUpdate(setPathProperties);

Expand Down Expand Up @@ -105,7 +122,7 @@ const ManageTrainScheduleV2 = () => {
</div>
),
label: t('tabs.timesStops'),
content: null,
content: pathProperties && <TimesStops pathProperties={pathProperties} pathSteps={pathSteps} />,
};

const tabSimulationSettings = {
Expand Down
4 changes: 2 additions & 2 deletions front/src/applications/stdcm/utils/formatStdcmConfV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export const checkStdcmConf = (
id,
arrival,
locked,
stop_for,
stopFor,
positionOnPath,
coordinates,
name,
Expand All @@ -138,7 +138,7 @@ export const checkStdcmConf = (
...path
} = step;
return {
duration: stop_for ? sec2ms(ISO8601Duration2sec(stop_for)) : 0,
duration: stopFor ? sec2ms(ISO8601Duration2sec(stopFor)) : 0,
location: { ...path, secondary_code: ch },
};
}),
Expand Down
5 changes: 3 additions & 2 deletions front/src/applications/stdcm/views/StdcmView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type {
PostV2InfraByInfraIdPathPropertiesApiArg,
} from 'common/api/osrdEditoastApi';
import { useInfraID, useOsrdConfSelectors } from 'common/osrdContext';
import { formatSuggestedOperationalPoints, insertViasInOPs } from 'modules/pathfinding/utils';
import { formatSuggestedOperationalPoints, upsertViasInOPs } from 'modules/pathfinding/utils';
import type { SuggestedOP } from 'modules/trainschedule/components/ManageTrainSchedule/types';
import { updateSelectedTrainId, updateSelectedProjection } from 'reducers/osrdsimulation/actions';
import { useAppDispatch } from 'store';
Expand Down Expand Up @@ -61,7 +61,7 @@ const StdcmView = () => {
path.length
);

const updatedSuggestedOPs = insertViasInOPs(
const updatedSuggestedOPs = upsertViasInOPs(
suggestedOperationalPoints,
pathStepsWihPosition
);
Expand All @@ -70,6 +70,7 @@ const StdcmView = () => {
electrifications,
geometry,
suggestedOperationalPoints: updatedSuggestedOPs,
allVias: updatedSuggestedOPs,
length: path.length,
});
}
Expand Down
1 change: 1 addition & 0 deletions front/src/modules/modules.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
@use './scenario/styles/scenario.scss';
@use './study/styles/study.scss';
@use './trainschedule/styles/trainSchedule.scss';
@use './timesStops/styles/timesStops.scss';
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const ViaStopDurationSelector = ({
const dispatch = useAppDispatch();
const { updateViaStopTimeV2 } = useOsrdConfActions();

const currentStopTime = via.stop_for ? ISO8601Duration2sec(via.stop_for) : 0;
const currentStopTime = via.stopFor ? ISO8601Duration2sec(via.stopFor) : 0;

const [stopTime, setStopTime] = useState(currentStopTime);
const debouncedStopTime = useDebounce(stopTime, 2000);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const ViasV2 = ({ zoomToFeaturePoint, shouldManageStopDuration }: DisplayViasV2P
{...providedDraggable.draggableProps}
{...providedDraggable.dragHandleProps}
className={cx('place via', {
'is-a-stop': via.arrival || via.stop_for,
'is-a-stop': via.arrival || via.stopFor,
})}
>
<div className="ring" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const ItineraryV2 = ({
};

const resetPathfinding = () => {
setPathProperties(undefined);
dispatch(updatePathSteps([null, null]));
};

Expand Down Expand Up @@ -111,9 +112,7 @@ const ItineraryV2 = ({
className="col my-1 text-white btn bg-info btn-sm"
type="button"
onClick={() =>
openModal(
<ModalSuggestedVias suggestedOps={pathProperties.suggestedOperationalPoints} />
)
openModal(<ModalSuggestedVias suggestedVias={pathProperties.allVias} />)
}
>
<span className="mr-1">{t('addVias')}</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ import { useAppDispatch } from 'store';
import { formatUicToCi } from 'utils/strings';

type ModalSuggestedViasProps = {
suggestedOps: SuggestedOP[];
suggestedVias: SuggestedOP[];
};

const ModalSuggestedVias = ({ suggestedOps }: ModalSuggestedViasProps) => {
const ModalSuggestedVias = ({ suggestedVias }: ModalSuggestedViasProps) => {
const { updatePathSteps, upsertViaFromSuggestedOP, clearViasV2 } = useOsrdConfActions();
const { getViasV2, getDestinationV2, getPathSteps } = useOsrdConfSelectors();
const dispatch = useAppDispatch();
Expand Down Expand Up @@ -97,11 +97,11 @@ const ModalSuggestedVias = ({ suggestedOps }: ModalSuggestedViasProps) => {
</ModalHeaderSNCF>
<ModalBodySNCF>
<div className="suggested-vias">
{suggestedOps.map((op, idx) => {
if (!isOriginOrDestination(op)) {
{suggestedVias.map((via, idx) => {
if (!isOriginOrDestination(via)) {
// If name is undefined, we know the op/via has been added by clicking on map
if (isVia(vias, op)) idxTrueVia += 1;
return formatOP(op, idx, idxTrueVia);
if (isVia(vias, via)) idxTrueVia += 1;
return formatOP(via, idx, idxTrueVia);
}
return null;
})}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect, useReducer } from 'react';
import React, { useState, useEffect, useReducer, useMemo } from 'react';

import { Alert, CheckCircle, Stop } from '@osrd-project/ui-icons';
import cx from 'classnames';
Expand All @@ -23,7 +23,7 @@ import type { PathfindingActionV2, PathfindingState } from 'modules/pathfinding/
import {
formatSuggestedOperationalPoints,
getPathfindingQuery,
insertViasInOPs,
upsertViasInOPs,
} from 'modules/pathfinding/utils';
import { useStoreDataForRollingStockSelector } from 'modules/rollingStock/components/RollingStockSelector/useStoreDataForRollingStockSelector';
import type { SuggestedOP } from 'modules/trainschedule/components/ManageTrainSchedule/types';
Expand Down Expand Up @@ -192,6 +192,8 @@ const Pathfinding = ({ pathProperties, setPathProperties }: PathfindingProps) =>
pollingInterval: !isInfraLoaded ? 1000 : undefined,
}
);
const pathfindingAlReadyInitialized = useMemo(() => infra?.state === 'CACHED', []);

const [reloadInfra] = osrdEditoastApi.endpoints.postInfraByInfraIdLoad.useMutation();

const {
Expand Down Expand Up @@ -225,14 +227,16 @@ const Pathfinding = ({ pathProperties, setPathProperties }: PathfindingProps) =>
case 'CACHED': {
setIsInfraLoaded(true);
if (isInfraError) setIsInfraError(false);
pathfindingDispatch({
type: 'INFRA_CHANGED',
params: {
origin,
destination,
rollingStock,
},
});
if (!pathfindingAlReadyInitialized) {
pathfindingDispatch({
type: 'INFRA_CHANGED',
params: {
origin,
destination,
rollingStock,
},
});
}
break;
}
default:
Expand Down Expand Up @@ -308,15 +312,13 @@ const Pathfinding = ({ pathProperties, setPathProperties }: PathfindingProps) =>
pathfindingResult.length
);

const updatedSuggestedOPs = insertViasInOPs(
suggestedOperationalPoints,
pathStepsWihPosition
);
const allVias = upsertViasInOPs(suggestedOperationalPoints, pathStepsWihPosition);

setPathProperties({
electrifications,
geometry,
suggestedOperationalPoints: updatedSuggestedOPs,
suggestedOperationalPoints,
allVias,
length: pathfindingResult.length,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ const TypeAndPathV2 = ({ setPathProperties }: PathfindingProps) => {
electrifications,
geometry,
suggestedOperationalPoints,
allVias: suggestedOperationalPoints,
length: pathfindingResult.length,
});
}
Expand Down
19 changes: 17 additions & 2 deletions front/src/modules/pathfinding/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const formatSuggestedOperationalPoints = (
name: op.extensions?.identifier?.name,
uic: op.extensions?.identifier?.uic,
ch: op.extensions?.sncf?.ch,
kp: op.part.extensions?.sncf?.kp,
chLongLabel: op.extensions?.sncf?.ch_long_label,
chShortLabel: op.extensions?.sncf?.ch_short_label,
ci: op.extensions?.sncf?.ci,
Expand Down Expand Up @@ -84,7 +85,7 @@ export const getPathfindingQuery = ({
return null;
};

export const insertViasInOPs = (ops: SuggestedOP[], pathSteps: PathStep[]): SuggestedOP[] => {
export const upsertViasInOPs = (ops: SuggestedOP[], pathSteps: PathStep[]): SuggestedOP[] => {
let updatedOPs = [...ops];
const vias = pathSteps.slice(1, -1);
if (vias.length > 0) {
Expand All @@ -105,6 +106,19 @@ export const insertViasInOPs = (ops: SuggestedOP[], pathSteps: PathStep[]): Sugg
(op) => step.positionOnPath && op.positionOnPath >= step.positionOnPath
);
updatedOPs = addElementAtIndex(updatedOPs, index, formattedStep);
} else if ('uic' in step) {
updatedOPs = updatedOPs.map((op) => {
if (op.uic === step.uic && op.ch === step.ch && op.kp === step.kp) {
return {
...op,
stopFor: step.stopFor,
arrival: step.arrival,
onStopSignal: step.onStopSignal,
theoreticalMargin: step.theoreticalMargin,
};
}
return op;
});
}
});
}
Expand All @@ -120,5 +134,6 @@ export const insertViasInOPs = (ops: SuggestedOP[], pathSteps: PathStep[]): Sugg
export const isVia = (vias: PathStep[], op: SuggestedOP) =>
vias.some(
(via) =>
('uic' in via && 'ch' in via && via.uic === op.uic && via.ch === op.ch) || via.id === op.opId
('uic' in via && 'ch' in via && via.uic === op.uic && via.ch === op.ch && via.kp === op.kp) ||
via.id === op.opId
);
Loading

0 comments on commit 4ae7056

Please sign in to comment.