diff --git a/front/src/applications/stdcm/components/StdcmForm/StdcmInputVia.tsx b/front/src/applications/stdcm/components/StdcmForm/StdcmInputVia.tsx
deleted file mode 100644
index 244dd723622..00000000000
--- a/front/src/applications/stdcm/components/StdcmForm/StdcmInputVia.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import { useMemo, useEffect, useState } from 'react';
-
-import { Input } from '@osrd-project/ui-core';
-import { debounce } from 'lodash';
-import { useTranslation } from 'react-i18next';
-
-import { StdcmStopTypes } from '../../types';
-
-type StdcmInputViaProps = {
- stopType: StdcmStopTypes;
- stopDuration?: number;
- updatePathStepStopTime: (stopTime: string) => void;
-};
-
-const StdcmInputVia = ({ stopType, stopDuration, updatePathStepStopTime }: StdcmInputViaProps) => {
- const { t } = useTranslation('stdcm');
-
- const [pathStepStopTime, setPathStepStopTime] = useState('');
-
- const stopWarning = stopType === StdcmStopTypes.DRIVER_SWITCH && stopDuration && stopDuration < 3;
-
- const debounceUpdatePathStepStopTime = useMemo(
- () => debounce((value) => updatePathStepStopTime(value), 300),
- []
- );
-
- useEffect(() => {
- setPathStepStopTime(stopDuration !== undefined ? `${stopDuration}` : '');
- }, [stopDuration]);
-
- 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
- }
- />
-
- )
- );
-};
-
-export default StdcmInputVia;
diff --git a/front/src/applications/stdcm/components/StdcmForm/StdcmVias.tsx b/front/src/applications/stdcm/components/StdcmForm/StdcmVias.tsx
index e2cba5798b8..2094450d3e2 100644
--- a/front/src/applications/stdcm/components/StdcmForm/StdcmVias.tsx
+++ b/front/src/applications/stdcm/components/StdcmForm/StdcmVias.tsx
@@ -13,9 +13,9 @@ import { useAppDispatch } from 'store';
import StdcmCard from './StdcmCard';
import StdcmDefaultCard from './StdcmDefaultCard';
-import StdcmInputVia from './StdcmInputVia';
import StdcmOperationalPoint from './StdcmOperationalPoint';
import StdcmStopType from './StdcmStopType';
+import StopDurationInput from './StopDurationInput';
import { StdcmStopTypes } from '../../types';
import type { StdcmConfigCardProps } from '../../types';
@@ -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
new file mode 100644
index 00000000000..6986cf9d93e
--- /dev/null
+++ b/front/src/applications/stdcm/components/StdcmForm/StopDurationInput.tsx
@@ -0,0 +1,78 @@
+import { useMemo, useEffect, useState } from 'react';
+
+import { Input } from '@osrd-project/ui-core';
+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 = {
+ pathStep: Extract;
+};
+
+const StopDurationInput = ({ pathStep }: StopDurationInputProps) => {
+ const dispatch = useAppDispatch();
+ const { t } = useTranslation('stdcm');
+
+ const { updateStdcmPathStep } = useOsrdConfActions() as StdcmConfSliceActions;
+
+ const [stopDuration, setStopDuration] = useState(
+ pathStep.stopFor !== undefined ? `${pathStep.stopFor}` : ''
+ );
+ const debouncedStopDuration = useDebounce(stopDuration, 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(() => {
+ 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 (
+
+ {
+ setStopDuration(e.target.value);
+ }}
+ value={stopDuration}
+ trailingContent="minutes"
+ statusWithMessage={stopWarning}
+ />
+
+ );
+};
+
+export default StopDurationInput;
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;
}
/**