Skip to content

Commit

Permalink
front: adapt power restriction v2 inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
RomainValls committed Jun 26, 2024
1 parent de1e59c commit 2cf5596
Show file tree
Hide file tree
Showing 10 changed files with 248 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
"powerRestrictionExplanationText": "By default, the simulation will use the nominal power.",
"powerRestrictionEmptyExplanationText": "The selected rolling stock does not have any power restrictions. You can edit it in the rolling stock editor.",
"removeVia": "Remove this waypoint",
"resetPowerRestrictions": "Reset power restrictions",
"restartPathfinding": "Restart search",
"rollingstock": "Rolling stock",
"saving": "Saving... please wait",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
"powerRestrictionEmptyExplanationText": "Le matériel roulant sélectionné ne possède pas de restrictions de puissance. Vous pouvez en créer dans l'éditeur de matériel roulant.",
"removeVia": "Retirer ce via",
"restartPathfinding": "Relancer la recherche",
"resetPowerRestrictions": "Réinitialiser les restrictions de puissance",
"rollingstock": "Matériel",
"saving": "Enregistrement en cours... veuillez patienter",
"simulation": "Simulation",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useMemo, useState } from 'react';
import React, { useEffect, useMemo, useState } from 'react';

import { compact } from 'lodash';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';

Expand All @@ -16,6 +17,7 @@ import { useOsrdConfSelectors } from 'common/osrdContext';
import { useStoreDataForSpeedLimitByTagSelector } from 'common/SpeedLimitByTagSelector/useStoreDataForSpeedLimitByTagSelector';
import Tabs from 'common/Tabs';
import ItineraryV2 from 'modules/pathfinding/components/Itinerary/ItineraryV2';
import { upsertViasInOPs } from 'modules/pathfinding/utils';
import PowerRestrictionsSelectorV2 from 'modules/powerRestriction/components/PowerRestrictionsSelectorV2';
import RollingStock2Img from 'modules/rollingStock/components/RollingStock2Img';
import { RollingStockSelector } from 'modules/rollingStock/components/RollingStockSelector';
Expand Down Expand Up @@ -56,6 +58,19 @@ const ManageTrainScheduleV2 = () => {
value: string;
};

useEffect(() => {
if (pathProperties) {
const allVias = upsertViasInOPs(
pathProperties.suggestedOperationalPoints,
compact(pathSteps)
);
setPathProperties({
...pathProperties,
allVias,
});
}
}, [pathSteps]);

const pathElectrificationRanges = (): IntervalItem[] => {
if (!pathProperties || !pathProperties.electrifications) return [];

Expand Down
11 changes: 7 additions & 4 deletions front/src/common/IntervalsEditor/IntervalsEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ type IntervalsEditorProps = {
/** Total length of the path */
totalLength: number;
disableDrag?: boolean;
onResizeFromInput?: (intervalIndex: number, newEnd: number, context: 'begin' | 'end') => void;
} & (
| {
intervalType: INTERVAL_TYPES.NUMBER;
Expand Down Expand Up @@ -99,6 +100,7 @@ const IntervalsEditor = (props: IntervalsEditorProps) => {
mergeTool: true,
},
disableDrag = false,
onResizeFromInput,
} = props;

// Which segment areas are visible
Expand All @@ -113,13 +115,13 @@ const IntervalsEditor = (props: IntervalsEditorProps) => {
// Data to display
const [resizingData, setResizingData] = useState<IntervalItem[]>(data);

useEffect(() => {
setResizingData(data);
}, [data]);

// Which segment is selected
const [selected, setSelected] = useState<number | null>(null);

useEffect(() => {
setResizingData(data);
}, [data, selected]);

// For mouse click / doubleClick
const [clickTimeout, setClickTimeout] = useState<number | null>(null);
const [clickPrevent, setClickPrevent] = useState<boolean>(false);
Expand Down Expand Up @@ -333,6 +335,7 @@ const IntervalsEditor = (props: IntervalsEditorProps) => {
interval={data[selected]}
selectedIntervalIndex={selected}
setData={setData}
onInputChange={onResizeFromInput}
setSelectedIntervalIndex={setSelected}
totalLength={totalLength}
defaultValue={defaultValue}
Expand Down
12 changes: 9 additions & 3 deletions front/src/common/IntervalsEditor/IntervalsEditorCommonForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ type IntervalsEditorFormProps = {
data: IntervalItem[];
interval: IntervalItem;
selectedIntervalIndex: number;
setData: (newData: IntervalItem[]) => void;
setData: (newData: IntervalItem[], selectedIntervalIndex?: number) => void;
onInputChange?: (intervalIndex: number, newBegin: number, context: 'begin' | 'end') => void;
setSelectedIntervalIndex: (selectedIntervalIndex: number) => void;
totalLength: number;
defaultValue: string | number;
Expand All @@ -26,11 +27,12 @@ const IntervalsEditorCommonForm = ({
setSelectedIntervalIndex,
totalLength,
defaultValue,
onInputChange,
}: IntervalsEditorFormProps) => {
const { t } = useTranslation('common/common');

const [begin, setBegin] = useState<number>(Math.round(interval.begin));
const [end, setEnd] = useState(Math.round(interval.end));
const [end, setEnd] = useState<number>(Math.round(interval.end));

useEffect(() => {
setBegin(Math.round(interval.begin));
Expand All @@ -53,7 +55,11 @@ const IntervalsEditorCommonForm = ({
fieldName: 'value',
defaultValue,
});
setData(fixedResults);
if (onInputChange) {
onInputChange(selectedIntervalIndex, newPosition, context);
} else {
setData(fixedResults, selectedIntervalIndex);
}

// update the selected interval if needed
// corner case: if we create a new empty first segment
Expand Down
8 changes: 5 additions & 3 deletions front/src/common/IntervalsEditor/IntervalsEditorTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import React from 'react';

import { useTranslation } from 'react-i18next';

import { formatMValue } from 'utils/strings';

import type { IntervalItem } from './types';

interface IntervalsEditorTooltip {
Expand All @@ -13,15 +15,15 @@ const IntervalsEditorTooltip = ({ item, point }: IntervalsEditorTooltip) => {
const { t } = useTranslation('common/common');
return (
<div className="linear-metadata-tooltip">
<div className="header">{point && <span>{Math.round(point)}</span>}</div>
<div className="header">{point && <span>{Math.round(formatMValue(point))}</span>}</div>
<div className="content">
<div>
<span className="mr-3">{t('begin')}</span>
{Math.round(item.begin)}
{Math.round(formatMValue(item.begin))}
</div>
<div>
<span className="mr-3">{t('end')}</span>
{Math.round(item.end)}
{Math.round(formatMValue(item.end))}
</div>
<div>
<span className="mr-3">{t('value')}</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ const PowerRestrictionsSelectorV2 = ({
resetPowerRestrictionRangesV2,
cutPowerRestrictionRangesV2,
deletePowerRestrictionRangesV2,
resizePowerRestrictionRangeV2,
} = useOsrdConfActions();
const powerRestrictionRanges = useSelector(getPowerRestrictionV2);
const pathSteps = compact(useSelector(getPathSteps));

// pathSteps + points de coupure d'électricité
// const [updatedPathSteps, setUpdatedPathSteps] = useState<PathStep[]>([]);
const [cutPositions, setCutPositions] = useState<number[]>([]);
const [intervalsEditorData, setIntervalsEditorData] = useState<IntervalItem[]>([]);

Expand Down Expand Up @@ -198,6 +198,53 @@ const PowerRestrictionsSelectorV2 = ({
dispatch(deletePowerRestrictionRangesV2({ from: fromPathStep, to: toPathStep }));
}
};

const resizeSegmentByInput = (
selectedSegmentIndex: number,
newEnd: number,
context: 'begin' | 'end'
) => {
const firstIndex = context === 'end' ? selectedSegmentIndex : selectedSegmentIndex - 1;

let firstRestriction: PowerRestrictionV2 | undefined;
let secondRestriction: PowerRestrictionV2 | undefined;
if (firstIndex >= 0) {
const firstRangeData = intervalsEditorData[firstIndex];
if (firstRangeData.value !== NO_POWER_RESTRICTION) {
const fromPathStep = pathSteps.find((step) => step.positionOnPath === firstRangeData.begin);
const toPathStep = pathSteps.find((step) => step.positionOnPath === firstRangeData.end);
if (fromPathStep && toPathStep) {
firstRestriction = powerRestrictionRanges.find(
(restriction) =>
restriction.from === fromPathStep.id && restriction.to === toPathStep.id
);
}
}
}

const secondRangeData = intervalsEditorData[firstIndex + 1];
if (secondRangeData.value !== NO_POWER_RESTRICTION) {
const fromPathStep = pathSteps.find((step) => step.positionOnPath === secondRangeData.begin);
const toPathStep = pathSteps.find((step) => step.positionOnPath === secondRangeData.end);
if (fromPathStep && toPathStep) {
secondRestriction = powerRestrictionRanges.find(
(restriction) => restriction.from === fromPathStep.id && restriction.to === toPathStep.id
);
}
}

let newEndPathStep = pathSteps.find((pathStep) => pathStep.positionOnPath === newEnd);
if (!newEndPathStep) {
newEndPathStep = createPathStep(newEnd, cumulativeSums, pathProperties, pathSteps);
}

if (firstRestriction && newEndPathStep) {
dispatch(
resizePowerRestrictionRangeV2({ firstRestriction, secondRestriction, newEndPathStep })
);
}
};

const formatElectricalRanges = (
ranges: PowerRestrictionV2[]
): { begin: number; end: number; value: string }[] => {
Expand Down Expand Up @@ -324,9 +371,14 @@ const PowerRestrictionsSelectorV2 = ({
deleteTool: true,
}}
disableDrag
onResizeFromInput={resizeSegmentByInput}
/>
<button type="button" onClick={() => dispatch(resetPowerRestrictionRangesV2())}>
RESET
<button
className="btn-link text-reset"
type="button"
onClick={() => dispatch(resetPowerRestrictionRangesV2())}
>
{t('resetPowerRestrictions')}
</button>
</>
) : (
Expand Down
Loading

0 comments on commit 2cf5596

Please sign in to comment.