diff --git a/front/src/modules/pathfinding/hooks/usePathfinding.ts b/front/src/modules/pathfinding/hooks/usePathfinding.ts index fee63419ff0..8473adc591a 100644 --- a/front/src/modules/pathfinding/hooks/usePathfinding.ts +++ b/front/src/modules/pathfinding/hooks/usePathfinding.ts @@ -28,6 +28,7 @@ import type { PathStep } from 'reducers/osrdconf/types'; import { useAppDispatch } from 'store'; import { isEmptyArray } from 'utils/array'; import { castErrorToFailure } from 'utils/error'; +import { usePrevious } from 'utils/hooks/state'; import useInfraStatus from './useInfraStatus'; @@ -150,17 +151,28 @@ export const usePathfinding = ( ) => { const { t } = useTranslation(['operationalStudies/manageTrainSchedule']); const dispatch = useAppDispatch(); - const { getInfraID, getOrigin, getDestination, getVias, getPathSteps, getPowerRestriction } = - useOsrdConfSelectors(); + const { + getInfraID, + getOrigin, + getDestination, + getVias, + getPathSteps, + getPowerRestriction, + getPathStepsCompletedWithPFResult, + } = useOsrdConfSelectors(); const infraId = useSelector(getInfraID, isEqual); const origin = useSelector(getOrigin, isEqual); const destination = useSelector(getDestination, isEqual); const vias = useSelector(getVias(), isEqual); const pathSteps = useSelector(getPathSteps); + const pathStepsCompletedWithPF = useSelector(getPathStepsCompletedWithPFResult); const powerRestrictions = useSelector(getPowerRestriction); const { infra, reloadCount, setIsInfraError } = useInfraStatus(); const { rollingStock } = useStoreDataForRollingStockSelector(); + const previousOrigin = usePrevious(origin); + const previousDestination = usePrevious(destination); + const initializerArgs = { origin, destination, @@ -196,6 +208,11 @@ export const usePathfinding = ( }; useEffect(() => { + // ignore update made automatically to vias from pathfinding result + // we want only the changes asked manually by user + if (pathStepsCompletedWithPF) { + return; + } if (isPathfindingInitialized) { pathfindingDispatch({ type: 'VIAS_CHANGED', @@ -209,6 +226,12 @@ export const usePathfinding = ( }, [vias]); useEffect(() => { + if ( + (previousOrigin !== origin || previousDestination !== destination) && + pathStepsCompletedWithPF + ) { + return; + } if (isPathfindingInitialized) { pathfindingDispatch({ type: 'PATHFINDING_PARAM_CHANGED', @@ -339,7 +362,11 @@ export const usePathfinding = ( ); } dispatch( - updatePathSteps({ pathSteps: updatedPathSteps, resetPowerRestrictions: true }) + updatePathSteps({ + pathSteps: updatedPathSteps, + resetPowerRestrictions: true, + completedWithPFResult: true, + }) ); const allWaypoints = upsertPathStepsInOPs( diff --git a/front/src/reducers/osrdconf/osrdConfCommon/index.ts b/front/src/reducers/osrdconf/osrdConfCommon/index.ts index 5b4c533160c..3d31b2ea466 100644 --- a/front/src/reducers/osrdconf/osrdConfCommon/index.ts +++ b/front/src/reducers/osrdconf/osrdConfCommon/index.ts @@ -46,6 +46,7 @@ export const defaultCommonConf: OsrdConfState = { featureInfoClick: { displayPopup: false }, // Corresponds to origin and destination not defined pathSteps: [null, null], + pathStepsCompletedWithPFResult: false, rollingStockComfort: 'STANDARD' as const, startTime: new Date().toISOString(), }; @@ -75,7 +76,11 @@ interface CommonConfReducers extends InfraStateReducers ['updateFeatureInfoClick']: CaseReducer>; ['updatePathSteps']: CaseReducer< S, - PayloadAction<{ pathSteps: S['pathSteps']; resetPowerRestrictions?: boolean }> + PayloadAction<{ + pathSteps: S['pathSteps']; + resetPowerRestrictions?: boolean; + completedWithPFResult?: boolean; + }> >; ['deleteItinerary']: CaseReducer; ['clearVias']: CaseReducer; @@ -165,6 +170,7 @@ export function buildCommonConfReducers(): CommonConfRe } return pathStep; }); + state.pathStepsCompletedWithPFResult = false; }, updateGridMarginBefore(state: Draft, action: PayloadAction) { state.gridMarginBefore = action.payload; @@ -178,23 +184,31 @@ export function buildCommonConfReducers(): CommonConfRe }, updatePathSteps( state: Draft, - action: PayloadAction<{ pathSteps: S['pathSteps']; resetPowerRestrictions?: boolean }> + action: PayloadAction<{ + pathSteps: S['pathSteps']; + resetPowerRestrictions?: boolean; + completedWithPFResult?: boolean; + }> ) { state.pathSteps = action.payload.pathSteps; + state.pathStepsCompletedWithPFResult = action.payload.completedWithPFResult || false; if (action.payload.resetPowerRestrictions) { state.powerRestriction = []; } }, deleteItinerary(state: Draft) { state.pathSteps = [null, null]; + state.pathStepsCompletedWithPFResult = false; }, clearVias(state: Draft) { state.pathSteps = [state.pathSteps[0], state.pathSteps[state.pathSteps.length - 1]]; + state.pathStepsCompletedWithPFResult = false; }, // Use this action in the via list, not the suggested op list deleteVia(state: Draft, action: PayloadAction) { // Index takes count of the origin in the array state.pathSteps = removeElementAtIndex(state.pathSteps, action.payload + 1); + state.pathStepsCompletedWithPFResult = false; }, // Use this action only to via added by click on map addVia( @@ -209,10 +223,12 @@ export function buildCommonConfReducers(): CommonConfRe action.payload.newVia, action.payload.pathProperties ); + state.pathStepsCompletedWithPFResult = false; }, moveVia: { reducer: (state: Draft, action: PayloadAction) => { state.pathSteps = action.payload; + state.pathStepsCompletedWithPFResult = false; }, prepare: (vias: S['pathSteps'], from: number, to: number) => { const newVias = Array.from(vias); @@ -227,11 +243,13 @@ export function buildCommonConfReducers(): CommonConfRe // from the suggested via modal upsertViaFromSuggestedOP(state: Draft, action: PayloadAction) { upsertPathStep(state.pathSteps, action.payload); + state.pathStepsCompletedWithPFResult = false; }, upsertSeveralViasFromSuggestedOP(state: Draft, action: PayloadAction) { action.payload.forEach((suggestedOp) => { upsertPathStep(state.pathSteps, suggestedOp); }); + state.pathStepsCompletedWithPFResult = false; }, updateRollingStockComfort(state: Draft, action: PayloadAction) { state.rollingStockComfort = action.payload; diff --git a/front/src/reducers/osrdconf/osrdConfCommon/selectors.ts b/front/src/reducers/osrdconf/osrdConfCommon/selectors.ts index e10df286d1c..9b41831806b 100644 --- a/front/src/reducers/osrdconf/osrdConfCommon/selectors.ts +++ b/front/src/reducers/osrdconf/osrdConfCommon/selectors.ts @@ -49,6 +49,7 @@ const buildCommonConfSelectors = ( getPowerRestriction: makeOsrdConfSelector('powerRestriction'), getFeatureInfoClick: makeOsrdConfSelector('featureInfoClick'), getPathSteps, + getPathStepsCompletedWithPFResult: makeOsrdConfSelector('pathStepsCompletedWithPFResult'), getOrigin: (state: RootState) => { const pathSteps = getPathSteps(state); return pathSteps[0]; diff --git a/front/src/reducers/osrdconf/types.ts b/front/src/reducers/osrdconf/types.ts index d26fb8c1db7..7eecd54e539 100644 --- a/front/src/reducers/osrdconf/types.ts +++ b/front/src/reducers/osrdconf/types.ts @@ -39,6 +39,7 @@ export interface OsrdConfState extends InfraState { gridMarginAfter?: number; featureInfoClick: { displayPopup: boolean; feature?: Feature; coordinates?: number[] }; pathSteps: (PathStep | null)[]; + pathStepsCompletedWithPFResult: boolean; rollingStockComfort: Comfort; // Format ISO 8601 startTime: string;