diff --git a/front/src/applications/stdcm/components/StdcmForm/StdcmVias.tsx b/front/src/applications/stdcm/components/StdcmForm/StdcmVias.tsx index a833da92901..2094450d3e2 100644 --- a/front/src/applications/stdcm/components/StdcmForm/StdcmVias.tsx +++ b/front/src/applications/stdcm/components/StdcmForm/StdcmVias.tsx @@ -84,16 +84,6 @@ const StdcmVias = ({ disabled = false }: StdcmConfigCardProps) => { }; }, [newIntermediateOpIndex]); - const updateStopDuration = (stopTime: string, pathStep: StdcmPathStep) => { - const stopFor = stopTime ? Number(stopTime) : undefined; - dispatch( - updateStdcmPathStep({ - id: pathStep.id, - updates: { stopFor }, - }) - ); - }; - const deleteViaOnClick = (pathStepId: string) => { dispatch(deleteStdcmVia(pathStepId)); }; @@ -147,11 +137,9 @@ const StdcmVias = ({ disabled = false }: StdcmConfigCardProps) => { stopTypes={pathStep.stopType} updatePathStepStopType={(newStopType) => updateStopType(newStopType, pathStep)} /> - updateStopDuration(e, pathStep)} - /> + {pathStep.stopType !== StdcmStopTypes.PASSAGE_TIME && ( + + )} ); diff --git a/front/src/applications/stdcm/components/StdcmForm/StopDurationInput.tsx b/front/src/applications/stdcm/components/StdcmForm/StopDurationInput.tsx index 5e53591c3c0..6986cf9d93e 100644 --- a/front/src/applications/stdcm/components/StdcmForm/StopDurationInput.tsx +++ b/front/src/applications/stdcm/components/StdcmForm/StopDurationInput.tsx @@ -1,63 +1,77 @@ import { useMemo, useEffect, useState } from 'react'; import { Input } from '@osrd-project/ui-core'; -import { debounce } from 'lodash'; +import type { Status } from '@osrd-project/ui-core/dist/components/inputs/StatusMessage'; import { useTranslation } from 'react-i18next'; +import { useOsrdConfActions } from 'common/osrdContext'; +import type { StdcmConfSliceActions } from 'reducers/osrdconf/stdcmConf'; +import type { StdcmPathStep } from 'reducers/osrdconf/types'; +import { useAppDispatch } from 'store'; +import { useDebounce } from 'utils/helpers'; +import { parseNumber } from 'utils/strings'; + import { StdcmStopTypes } from '../../types'; type StopDurationInputProps = { - stopType: StdcmStopTypes; - stopDuration?: number; - updatePathStepStopTime: (stopTime: string) => void; + pathStep: Extract; }; -const StopDurationInput = ({ - stopType, - stopDuration, - updatePathStepStopTime, -}: StopDurationInputProps) => { +const StopDurationInput = ({ pathStep }: StopDurationInputProps) => { + const dispatch = useAppDispatch(); const { t } = useTranslation('stdcm'); - const [pathStepStopTime, setPathStepStopTime] = useState(''); + const { updateStdcmPathStep } = useOsrdConfActions() as StdcmConfSliceActions; - const stopWarning = stopType === StdcmStopTypes.DRIVER_SWITCH && stopDuration && stopDuration < 3; + const [stopDuration, setStopDuration] = useState( + pathStep.stopFor !== undefined ? `${pathStep.stopFor}` : '' + ); + const debouncedStopDuration = useDebounce(stopDuration, 300); - const debounceUpdatePathStepStopTime = useMemo( - () => debounce((value) => updatePathStepStopTime(value), 300), - [] + const stopWarning = useMemo( + () => + pathStep.stopType === StdcmStopTypes.DRIVER_SWITCH && + pathStep.stopFor !== undefined && + pathStep.stopFor < 3 + ? { + status: 'warning' as Status, + message: t('trainPath.warningMinStopTime'), + } + : undefined, + [pathStep.stopType, pathStep.stopFor] ); useEffect(() => { - setPathStepStopTime(stopDuration !== undefined ? `${stopDuration}` : ''); - }, [stopDuration]); + setStopDuration(pathStep.stopFor !== undefined ? `${pathStep.stopFor}` : ''); + }, [pathStep.stopFor]); + + useEffect(() => { + const parsedNumber = parseNumber(debouncedStopDuration); + const newStopDuration = parsedNumber !== undefined ? Math.round(parsedNumber) : undefined; + if (newStopDuration !== pathStep.stopFor) { + dispatch( + updateStdcmPathStep({ + id: pathStep.id, + updates: { stopFor: newStopDuration }, + }) + ); + } + }, [debouncedStopDuration]); return ( - stopType !== StdcmStopTypes.PASSAGE_TIME && ( -
- { - // TODO: Find a better way to prevent user from entering decimal values - const value = e.target.value.replace(/[\D.,]/g, ''); - setPathStepStopTime(value); - debounceUpdatePathStepStopTime(value); - }} - value={pathStepStopTime} - trailingContent="minutes" - statusWithMessage={ - stopWarning - ? { - status: 'warning', - message: t('trainPath.warningMinStopTime'), - } - : undefined - } - /> -
- ) +
+ { + setStopDuration(e.target.value); + }} + value={stopDuration} + trailingContent="minutes" + statusWithMessage={stopWarning} + /> +
); }; diff --git a/front/src/utils/strings.ts b/front/src/utils/strings.ts index 9f4ebe6a08b..4aa0d2bf86d 100644 --- a/front/src/utils/strings.ts +++ b/front/src/utils/strings.ts @@ -49,8 +49,7 @@ export function geti18nKeyForNull(str: string | null): string { /** Given a string, return a number or undefined */ export function parseNumber(str: string) { - const number = Number(str); - return !Number.isNaN(number) ? number : undefined; + return str && !Number.isNaN(Number(str)) ? Number(str) : undefined; } /**