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: highlight unindentify prs in itinerary component #9270

Draft
wants to merge 1 commit 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
@@ -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';
Expand All @@ -8,16 +9,23 @@ 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);

const dispatch = useDispatch();
const { t } = useTranslation(['operationalStudies/manageTrainSchedule']);

const isInvalid =
invalidPathItems &&
destination &&
'trigram' in destination &&
invalidPathItems.includes(destination.trigram);

if (!destination)
return (
<>
Expand All @@ -29,7 +37,10 @@ const Destination = ({ zoomToFeaturePoint }: DestinationProps) => {
);

return (
<div className="place" data-testid="itinerary-destination">
<div
className={cx('place', { 'invalid-path-item': isInvalid })}
data-testid="itinerary-destination"
>
<div className="pl-1 hover w-100 d-flex align-items-center">
<span className="text-warning mr-2">
<IoFlag />
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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,
Expand Down Expand Up @@ -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 = (
<div
onClick={() => {
Expand Down Expand Up @@ -89,7 +94,10 @@ const Origin = ({ zoomToFeaturePoint }: OriginProps) => {
);

return (
<div className="mb-2 place" data-testid="itinerary-origin">
<div
className={cx('mb-2 place', { 'invalid-path-item': isInvalid })}
data-testid="itinerary-origin"
>
<div className="pl-1 hover w-100 d-flex align-items-center">
<span className="text-success mr-2">
<RiMapPin2Fill />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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),
})}
>
<div className="ring" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 = {
Expand Down Expand Up @@ -165,20 +168,24 @@ const Itinerary = ({
)}
<div className="osrd-config-item-container pathfinding-details" data-testid="itinerary">
<div data-testid="display-itinerary">
<Origin zoomToFeaturePoint={zoomToFeaturePoint} />
<Origin zoomToFeaturePoint={zoomToFeaturePoint} invalidPathItems={invalidPathItems} />
<div className="vias-list mb-2" data-testid="itinerary-vias">
{pathSteps.length > 2 ? (
<Vias
zoomToFeaturePoint={zoomToFeaturePoint}
shouldManageStopDuration={shouldManageStopDuration}
invalidPathItems={invalidPathItems}
/>
) : (
<small data-testid="no-waypoint-chosen-text" className="ml-4">
{t('noPlaceChosen')}
</small>
)}
</div>
<Destination zoomToFeaturePoint={zoomToFeaturePoint} />
<Destination
zoomToFeaturePoint={zoomToFeaturePoint}
invalidPathItems={invalidPathItems}
/>
</div>
</div>
</div>
Expand Down
45 changes: 42 additions & 3 deletions front/src/modules/pathfinding/hooks/usePathfinding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,11 +177,34 @@ export const usePathfinding = (

const { updatePathSteps } = useOsrdConfActions();

const [invalidItems, setInvalidItems] = useState<string[]>([]);

const generatePathfindingParams = (): PostInfraByInfraIdPathfindingBlocksApiArg | null => {
setPathProperties?.(undefined);
return getPathfindingQuery({ infraId, rollingStock, origin, destination, pathSteps });
console.log('pathSteps:', pathSteps);
console.log('invalidItems:', invalidItems);

const filteredPathSteps = pathSteps.filter(
(step) =>
step !== null &&
step.coordinates !== null &&
!('trigram' in step && invalidItems.includes(step.trigram))
);
console.log('Après filtrage - filteredPathSteps:', filteredPathSteps);
return getPathfindingQuery({
infraId,
rollingStock,
origin,
destination,
pathSteps: filteredPathSteps,
});
};

// const generatePathfindingParams = (): PostInfraByInfraIdPathfindingBlocksApiArg | null => {
// setPathProperties?.(undefined);
// return getPathfindingQuery({ infraId, rollingStock, origin, destination, pathSteps });
// };

useEffect(() => {
if (isPathfindingInitialized) {
pathfindingDispatch({
Expand Down Expand Up @@ -225,8 +248,23 @@ 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 (
pathfindingDispatch({
type: 'PATHFINDING_ERROR',
message: `Invalid path item: ${invalidPathItems.join(', ')}`,
});
if (invalidPathItems.length > 0) {
setInvalidItems([...invalidPathItems]);
startPathFinding();
}
} else if (
pathfindingResult.status === 'success' ||
pathfindingResult.status === 'incompatible_constraints'
) {
Expand Down Expand Up @@ -346,7 +384,7 @@ export const usePathfinding = (
if (infra && infra.state === 'CACHED' && pathfindingState.mustBeLaunched) {
startPathFinding();
}
}, [pathfindingState.mustBeLaunched, infra]);
}, [pathfindingState.mustBeLaunched, infra, invalidItems]);

useEffect(() => setIsPathfindingInitialized(true), []);

Expand All @@ -358,5 +396,6 @@ export const usePathfinding = (
infra,
reloadCount,
},
invalidItems,
};
};
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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',
Expand Down Expand Up @@ -57,25 +58,42 @@ const formatPointWithNoName = (
</>
);

const extractMarkerInformation = (pathSteps: (PathStep | null)[], showStdcmAssets: boolean) =>
pathSteps.reduce((acc, cur, index) => {
const extractMarkerInformation = (
pathSteps: (PathStep | null)[],
showStdcmAssets: boolean,
invalidItems: string[] = []
) => {
console.log('Extracting marker information');
console.log('pathSteps:', pathSteps);
console.log('invalidItems:', invalidItems);

const filteredPathSteps = pathSteps.filter(
(step) =>
step && step.coordinates && (!('trigram' in step) || !invalidItems.includes(step.trigram))
);

return filteredPathSteps.reduce((acc, cur, index) => {
console.log(`Processing PathStep at index ${index}:`, cur);
if (cur && 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) {
} else if (index > 0 && index < filteredPathSteps.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) {
} else if (index === filteredPathSteps.length - 1) {
console.log('Adding DESTINATION marker');
acc.push({
coordinates: cur.coordinates,
type: MARKER_TYPE.DESTINATION,
Expand All @@ -86,16 +104,34 @@ const extractMarkerInformation = (pathSteps: (PathStep | null)[], showStdcmAsset
}
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, showStdcmAssets, invalidItems]
);

useEffect(() => {
console.log('Invalid Items:', invalidItems);
console.log('pathSteps:', pathSteps);
console.log('markersInformation:', markersInformation);
}, [invalidItems, pathSteps]);

const getMarkerDisplayInformation = useCallback(
(markerInfo: MarkerInformation) => {
const {
Expand Down Expand Up @@ -138,8 +174,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 = (
<div className={`map-pathfinding-marker ${markerInfo.type}-name`}>
Expand Down Expand Up @@ -173,9 +214,8 @@ const ItineraryMarkers = ({ map, simulationPathSteps, showStdcmAssets }: Itinera
</Marker>
);
}),
[markersInformation]
[simulationPathSteps, pathSteps, showStdcmAssets, invalidItems]
);

return Markers;
};

Expand Down
6 changes: 6 additions & 0 deletions front/src/styles/scss/common/components/_pathfinding.scss
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@
}
}
}
.via,
.place {
&.invalid-path-item {
color: #e05206;
}
}

.pathfinding-state-main-container {
.content {
Expand Down
Loading