diff --git a/front/public/locales/en/translation.json b/front/public/locales/en/translation.json index cf31a2b37c7..3f8a39c1e23 100644 --- a/front/public/locales/en/translation.json +++ b/front/public/locales/en/translation.json @@ -435,6 +435,7 @@ "select-track": "Select a line on the map" }, "label": "Switch tool", + "duplicate-errors": "The track {{track}} is already used by the port {{port}}", "no-track-picked-yet": "No line selected yet", "switch-type": "Switch type", "untitled-track": "Untitled track" diff --git a/front/public/locales/fr/translation.json b/front/public/locales/fr/translation.json index 084ad229e9a..e419b439ea1 100644 --- a/front/public/locales/fr/translation.json +++ b/front/public/locales/fr/translation.json @@ -434,6 +434,7 @@ "no-move": "Les aiguillages ne peuvent pas être déplacés, et sont automatiquement placés sur leur premier port.", "select-track": "Sélectionnez une ligne sur la carte" }, + "duplicate-errors": "Le track {{track}} est déjà utilisé par le port {{port}}", "label": "Outil \"Aiguillage\"", "no-track-picked-yet": "Aucune ligne n'a encore été sélectionnée", "switch-type": "Type d'aiguillage", diff --git a/front/src/applications/editor/tools/switchEdition/components.tsx b/front/src/applications/editor/tools/switchEdition/components.tsx index 4f3000d24aa..ca6cd83c9fe 100644 --- a/front/src/applications/editor/tools/switchEdition/components.tsx +++ b/front/src/applications/editor/tools/switchEdition/components.tsx @@ -5,7 +5,7 @@ import Select from 'react-select'; import { Layer, Popup, Source } from 'react-map-gl/maplibre'; import nearestPoint from '@turf/nearest-point'; import { featureCollection, point } from '@turf/helpers'; -import { first, last, debounce } from 'lodash'; +import { first, last, debounce, groupBy, filter } from 'lodash'; import type { Position } from 'geojson'; import type { SwitchEntity, TrackSectionEntity } from 'types'; @@ -94,6 +94,15 @@ export const SwitchEditionLeftPanel = () => { }} onSubmit={async (flatSwitch) => { const entityToSave = flatSwitchToSwitch(switchType, flatSwitch as FlatSwitchEntity); + const detectedDuplicates = filter( + groupBy(entityToSave.properties.ports, 'track'), + (v, _) => v.length > 1 + ); + + if (detectedDuplicates.length > 0) { + throw new Error(t('Editor.infra-errors.error-type.node_endpoints_not_unique.name')); + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any const res: any = await dispatch( save( diff --git a/front/src/applications/editor/tools/switchEdition/components/TrackSectionEndpointSelector.tsx b/front/src/applications/editor/tools/switchEdition/components/TrackSectionEndpointSelector.tsx index 72cfffaf64d..dc26d24003b 100644 --- a/front/src/applications/editor/tools/switchEdition/components/TrackSectionEndpointSelector.tsx +++ b/front/src/applications/editor/tools/switchEdition/components/TrackSectionEndpointSelector.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useContext, useEffect, useState } from 'react'; +import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react'; import { useDispatch } from 'react-redux'; import Select from 'react-select'; import { useTranslation } from 'react-i18next'; @@ -29,6 +29,18 @@ const TrackSectionEndpointSelector = ({ schema, formData, onChange, name }: Fiel const { state, setState } = useContext( EditorContext ) as ExtendedEditorContextType; + + const duplicateWith = useMemo(() => { + const ports = Object.entries(state.entity.properties?.ports ?? {}).map(([k, v]) => ({ + ...v, + port: k, + name: `port::${k}`, + })); + const currentPort = ports.find((p) => p.name === name); + const othersPorts = ports.filter((p) => p.name !== name); + return othersPorts.filter((p) => p.track === currentPort?.track); + }, [state.entity.properties]); + const { t } = useTranslation(); const infraID = useInfraID(); @@ -89,6 +101,14 @@ const TrackSectionEndpointSelector = ({ schema, formData, onChange, name }: Fiel
{schema.title &&
{schema.title}
} {schema.description &&

{schema.description}

} + {duplicateWith.map(({ track, port }) => ( +
+ {t('Editor.tools.switch-edition.duplicate-errors', { + track, + port, + })} +
+ ))}
{trackSection ? (