From c1226b7fd8445ee9feb945cc2da76f65e2269a14 Mon Sep 17 00:00:00 2001 From: Mathieu Date: Thu, 3 Oct 2024 17:28:29 +0200 Subject: [PATCH] front: highlight unindentify prs in itinerary component Signed-off-by: Mathieu --- .../DisplayItinerary/Destination.tsx | 15 ++- .../Itinerary/DisplayItinerary/Origin.tsx | 12 +- .../Itinerary/DisplayItinerary/Vias.tsx | 5 +- .../components/Itinerary/Itinerary.tsx | 11 +- .../pathfinding/hooks/usePathfinding.ts | 19 +++- .../ItineraryMarkers.tsx | 103 +++++++++++++----- .../scss/common/components/_pathfinding.scss | 6 + 7 files changed, 133 insertions(+), 38 deletions(-) diff --git a/front/src/modules/pathfinding/components/Itinerary/DisplayItinerary/Destination.tsx b/front/src/modules/pathfinding/components/Itinerary/DisplayItinerary/Destination.tsx index c7f4e0d1cbc..2a031d608c1 100644 --- a/front/src/modules/pathfinding/components/Itinerary/DisplayItinerary/Destination.tsx +++ b/front/src/modules/pathfinding/components/Itinerary/DisplayItinerary/Destination.tsx @@ -1,4 +1,5 @@ import { XCircle } from '@osrd-project/ui-icons'; +import cx from 'classnames'; import type { Position } from 'geojson'; import { useTranslation } from 'react-i18next'; import { IoFlag } from 'react-icons/io5'; @@ -8,9 +9,10 @@ import { useOsrdConfActions, useOsrdConfSelectors } from 'common/osrdContext'; type DestinationProps = { zoomToFeaturePoint: (lngLat?: Position, id?: string) => void; + invalidPathItems?: string[]; }; -const Destination = ({ zoomToFeaturePoint }: DestinationProps) => { +const Destination = ({ zoomToFeaturePoint, invalidPathItems }: DestinationProps) => { const { getDestination } = useOsrdConfSelectors(); const { updateDestination } = useOsrdConfActions(); const destination = useSelector(getDestination); @@ -18,6 +20,12 @@ const Destination = ({ zoomToFeaturePoint }: DestinationProps) => { const dispatch = useDispatch(); const { t } = useTranslation(['operationalStudies/manageTrainSchedule']); + const isInvalid = + invalidPathItems && + destination && + 'trigram' in destination && + invalidPathItems.includes(destination.trigram); + if (!destination) return ( <> @@ -29,7 +37,10 @@ const Destination = ({ zoomToFeaturePoint }: DestinationProps) => { ); return ( -
+
diff --git a/front/src/modules/pathfinding/components/Itinerary/DisplayItinerary/Origin.tsx b/front/src/modules/pathfinding/components/Itinerary/DisplayItinerary/Origin.tsx index 6bcac4c5fbd..5653728811c 100644 --- a/front/src/modules/pathfinding/components/Itinerary/DisplayItinerary/Origin.tsx +++ b/front/src/modules/pathfinding/components/Itinerary/DisplayItinerary/Origin.tsx @@ -1,4 +1,5 @@ import { XCircle } from '@osrd-project/ui-icons'; +import cx from 'classnames'; import type { Position } from 'geojson'; import { useTranslation } from 'react-i18next'; import { BiLink, BiUnlink } from 'react-icons/bi'; @@ -12,9 +13,10 @@ import { makeEnumBooleans } from 'utils/constants'; type OriginProps = { zoomToFeaturePoint: (lngLat?: Position, id?: string) => void; + invalidPathItems?: string[]; }; -const Origin = ({ zoomToFeaturePoint }: OriginProps) => { +const Origin = ({ zoomToFeaturePoint, invalidPathItems }: OriginProps) => { const { getOrigin, getOriginDate, @@ -45,6 +47,9 @@ const Origin = ({ zoomToFeaturePoint }: OriginProps) => { const { t } = useTranslation(['operationalStudies/manageTrainSchedule']); const { isStdcm } = makeEnumBooleans(MODES, mode); + const isInvalid = + invalidPathItems && origin && 'trigram' in origin && invalidPathItems.includes(origin.trigram); + const originPointName = (
{ @@ -89,7 +94,10 @@ const Origin = ({ zoomToFeaturePoint }: OriginProps) => { ); return ( -
+
diff --git a/front/src/modules/pathfinding/components/Itinerary/DisplayItinerary/Vias.tsx b/front/src/modules/pathfinding/components/Itinerary/DisplayItinerary/Vias.tsx index ce138ded7e1..1de70de3ac1 100644 --- a/front/src/modules/pathfinding/components/Itinerary/DisplayItinerary/Vias.tsx +++ b/front/src/modules/pathfinding/components/Itinerary/DisplayItinerary/Vias.tsx @@ -16,9 +16,10 @@ import ViaStopDurationSelector from './ViaStopDurationSelector'; type ViasProps = { shouldManageStopDuration?: boolean; zoomToFeaturePoint: (lngLat?: Position, id?: string) => void; + invalidPathItems?: string[]; }; -const Vias = ({ zoomToFeaturePoint, shouldManageStopDuration }: ViasProps) => { +const Vias = ({ zoomToFeaturePoint, shouldManageStopDuration, invalidPathItems }: ViasProps) => { const { t } = useTranslation('operationalStudies/manageTrainSchedule'); const { getVias } = useOsrdConfSelectors(); const dispatch = useAppDispatch(); @@ -51,6 +52,8 @@ const Vias = ({ zoomToFeaturePoint, shouldManageStopDuration }: ViasProps) => { {...providedDraggable.dragHandleProps} className={cx('place via', { 'is-a-stop': via.arrival || via.stopFor, + 'invalid-path-item': + 'trigram' in via && invalidPathItems?.includes(via.trigram), })} >
diff --git a/front/src/modules/pathfinding/components/Itinerary/Itinerary.tsx b/front/src/modules/pathfinding/components/Itinerary/Itinerary.tsx index ce134f0b200..c3d086fe92f 100644 --- a/front/src/modules/pathfinding/components/Itinerary/Itinerary.tsx +++ b/front/src/modules/pathfinding/components/Itinerary/Itinerary.tsx @@ -24,6 +24,7 @@ import Destination from './DisplayItinerary/Destination'; import Origin from './DisplayItinerary/Origin'; import Vias from './DisplayItinerary/Vias'; import ModalSuggestedVias from './ModalSuggestedVias'; +import { usePathfinding } from 'modules/pathfinding/hooks/usePathfinding'; type ItineraryProps = { pathProperties?: ManageTrainSchedulePathProperties; @@ -49,6 +50,8 @@ const Itinerary = ({ const { t } = useTranslation('operationalStudies/manageTrainSchedule'); const { openModal } = useModal(); + const { invalidItems: invalidPathItems } = usePathfinding(setPathProperties, pathProperties); + const zoomToFeaturePoint = (lngLat?: Position) => { if (lngLat) { const newViewport = { @@ -165,12 +168,13 @@ const Itinerary = ({ )}
- +
{pathSteps.length > 2 ? ( ) : ( @@ -178,7 +182,10 @@ const Itinerary = ({ )}
- +
diff --git a/front/src/modules/pathfinding/hooks/usePathfinding.ts b/front/src/modules/pathfinding/hooks/usePathfinding.ts index 6444535a55d..464ab501dd3 100644 --- a/front/src/modules/pathfinding/hooks/usePathfinding.ts +++ b/front/src/modules/pathfinding/hooks/usePathfinding.ts @@ -177,6 +177,8 @@ export const usePathfinding = ( const { updatePathSteps } = useOsrdConfActions(); + const [invalidItems, setInvalidItems] = useState([]); + const generatePathfindingParams = (): PostInfraByInfraIdPathfindingBlocksApiArg | null => { setPathProperties?.(undefined); return getPathfindingQuery({ infraId, rollingStock, origin, destination, pathSteps }); @@ -225,8 +227,22 @@ export const usePathfinding = ( try { const pathfindingResult = await postPathfindingBlocks(pathfindingInput).unwrap(); + if (pathfindingResult.status === 'invalid_path_items') { + console.log('pathfindingResult:', pathfindingResult.status); + const invalidPathItems = pathfindingResult.items + .map((item) => { + return 'trigram' in item.path_item ? item.path_item.trigram : null; + }) + .filter((trigram): trigram is string => trigram !== null); + if (invalidPathItems.length > 0) { + setInvalidItems([...invalidPathItems]); + } - if ( + pathfindingDispatch({ + type: 'PATHFINDING_ERROR', + message: `Invalid path item: ${invalidPathItems.join(', ')}`, + }); + } else if ( pathfindingResult.status === 'success' || pathfindingResult.status === 'incompatible_constraints' ) { @@ -358,5 +374,6 @@ export const usePathfinding = ( infra, reloadCount, }, + invalidItems, }; }; diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/ItineraryMarkers.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/ItineraryMarkers.tsx index d79090410e7..346ef174a8c 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/ItineraryMarkers.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/ItineraryMarkers.tsx @@ -1,4 +1,4 @@ -import { useCallback, useMemo } from 'react'; +import { useCallback, useEffect, useMemo } from 'react'; import type { Position } from '@turf/helpers'; import cx from 'classnames'; @@ -15,6 +15,7 @@ import viaSVG from 'assets/pictures/via.svg'; import { useOsrdConfSelectors } from 'common/osrdContext'; import type { PathStep } from 'reducers/osrdconf/types'; import { getNearestTrack } from 'utils/mapHelper'; +import { usePathfinding } from 'modules/pathfinding/hooks/usePathfinding'; enum MARKER_TYPE { ORIGIN = 'origin', @@ -57,45 +58,82 @@ const formatPointWithNoName = ( ); -const extractMarkerInformation = (pathSteps: (PathStep | null)[], showStdcmAssets: boolean) => - pathSteps.reduce((acc, cur, index) => { - if (cur && cur.coordinates) { - if (index === 0) { - acc.push({ - coordinates: cur.coordinates, - type: MARKER_TYPE.ORIGIN, - marker: cur, - imageSource: showStdcmAssets ? stdcmOrigin : originSVG, - }); - } else if (index > 0 && index < pathSteps.length - 1) { - acc.push({ - coordinates: cur.coordinates, - type: MARKER_TYPE.VIA, - marker: cur, - imageSource: showStdcmAssets ? stdcmVia : viaSVG, - index, - }); - } else if (index === pathSteps.length - 1) { - acc.push({ - coordinates: cur.coordinates, - type: MARKER_TYPE.DESTINATION, - marker: cur, - imageSource: showStdcmAssets ? stdcmDestination : destinationSVG, - }); +const extractMarkerInformation = ( + pathSteps: (PathStep | null)[], + showStdcmAssets: boolean, + invalidItems: string[] = [] +) => { + console.log('pathSteps2:', pathSteps); + return pathSteps.reduce((acc, cur, index) => { + // if (cur && cur.coordinates && ('trigram' in cur ? !invalidItems.includes(cur.trigram) : true)) { + if (cur) { + console.log(`Processing PathStep at index ${index} with coordinates: `, cur.coordinates); + const isInvalid = 'trigram' in cur ? invalidItems.includes(cur.trigram) : false; + console.log(`Is Invalid: ${isInvalid}`, cur); + + if (!isInvalid && cur.coordinates) { + if (index === 0) { + console.log('Adding ORIGIN marker'); + acc.push({ + coordinates: cur.coordinates, + type: MARKER_TYPE.ORIGIN, + marker: cur, + imageSource: showStdcmAssets ? stdcmOrigin : originSVG, + }); + } else if (index > 0 && index < pathSteps.length - 1) { + console.log('Adding VIA marker'); + acc.push({ + coordinates: cur.coordinates, + type: MARKER_TYPE.VIA, + marker: cur, + imageSource: showStdcmAssets ? stdcmVia : viaSVG, + index, + }); + } else if (index === pathSteps.length - 1) { + console.log('Adding DESTINATION marker'); + acc.push({ + coordinates: cur.coordinates, + type: MARKER_TYPE.DESTINATION, + marker: cur, + imageSource: showStdcmAssets ? stdcmDestination : destinationSVG, + }); + } + } else { + console.log('PathStep is invalid and will not be added:', cur); } + } else { + console.log('PathStep has no coordinates or is null:', cur); } return acc; }, [] as MarkerInformation[]); +}; const ItineraryMarkers = ({ map, simulationPathSteps, showStdcmAssets }: ItineraryMarkersProps) => { const { getPathSteps } = useOsrdConfSelectors(); const pathSteps = useSelector(getPathSteps); + useEffect(() => { + console.log('Retrieved pathSteps:', pathSteps); + pathSteps.forEach((step, index) => { + if (step) { + console.log(`PathStep at index ${index} - ID: ${step.id}, Coordinates:`, step.coordinates); + } + }); + }, [pathSteps]); + + const { invalidItems } = usePathfinding(); + const markersInformation = useMemo( - () => extractMarkerInformation(simulationPathSteps || pathSteps, showStdcmAssets), - [simulationPathSteps, pathSteps] + () => extractMarkerInformation(simulationPathSteps || pathSteps, showStdcmAssets, invalidItems), + [simulationPathSteps, pathSteps, invalidItems] ); + useEffect(() => { + console.log('Invalid Items:', invalidItems); + console.log('pathSteps:', pathSteps); + console.log('markersInformation:', markersInformation); + }, [invalidItems, pathSteps]); + const getMarkerDisplayInformation = useCallback( (markerInfo: MarkerInformation) => { const { @@ -138,8 +176,13 @@ const ItineraryMarkers = ({ map, simulationPathSteps, showStdcmAssets }: Itinera const Markers = useMemo( () => markersInformation.map((markerInfo) => { + console.log('SimulationPathSteps:', simulationPathSteps); + console.log('PathSteps passed to extractMarkerInformation:', pathSteps); const isDestination = markerInfo.type === MARKER_TYPE.DESTINATION; const isVia = markerInfo.type === MARKER_TYPE.VIA; + console.log('Markers to display:', markersInformation.length); + console.log('Markers Information2:', markersInformation); + console.log('Invalid Items2:', invalidItems); const markerName = (
@@ -173,9 +216,9 @@ const ItineraryMarkers = ({ map, simulationPathSteps, showStdcmAssets }: Itinera ); }), - [markersInformation] + [simulationPathSteps, pathSteps, showStdcmAssets, invalidItems] ); - + console.log('markeres:', Markers); return Markers; }; diff --git a/front/src/styles/scss/common/components/_pathfinding.scss b/front/src/styles/scss/common/components/_pathfinding.scss index bff21e8f6c1..7a298f705c1 100644 --- a/front/src/styles/scss/common/components/_pathfinding.scss +++ b/front/src/styles/scss/common/components/_pathfinding.scss @@ -91,6 +91,12 @@ } } } +.via, +.place { + &.invalid-path-item { + color: #e05206; + } +} .pathfinding-state-main-container { .content {