Skip to content

Commit 90dff68

Browse files
committed
front: allowances: fix allowances components
1 parent 3864195 commit 90dff68

File tree

17 files changed

+858
-315
lines changed

17 files changed

+858
-315
lines changed

front/src/applications/operationalStudies/consts.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { SwitchType } from 'types';
33
import { ObjectFieldsTypes } from 'utils/types';
44
import { Position, Feature } from 'geojson';
55
import {
6-
Allowance,
76
AllowanceValue,
87
Comfort,
98
ElectrificationRange,
@@ -15,6 +14,7 @@ import {
1514
} from 'common/api/osrdEditoastApi';
1615
import { LinearMetadataItem } from 'common/IntervalsDataViz/types';
1716
import { HeightPosition } from 'reducers/osrdsimulation/types';
17+
import { AllowanceForm } from 'modules/trainschedule/components/ManageTrainSchedule/Allowances/types';
1818

1919
export const BLOCKTYPES = [
2020
{
@@ -161,7 +161,7 @@ export interface OsrdConfState {
161161
trainCount: number;
162162
trainStep: number;
163163
trainDelta: number;
164-
allowances: Allowance[];
164+
allowances: AllowanceForm[];
165165
usingElectricalProfiles: boolean;
166166
labels: string[];
167167
projectID?: number;

front/src/common/BootstrapSNCF/InputGroupSNCF.tsx

+5-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type Props = {
3030
max?: number;
3131
step?: number | string;
3232
textRight?: boolean;
33+
disabled?: boolean;
3334
disableUnitSelector?: boolean;
3435
};
3536

@@ -52,6 +53,7 @@ export default function InputGroupSNCF({
5253
max,
5354
step,
5455
textRight = false,
56+
disabled = false,
5557
disableUnitSelector = false,
5658
}: Props) {
5759
const [isDropdownShown, setIsDropdownShown] = useState(false);
@@ -88,11 +90,12 @@ export default function InputGroupSNCF({
8890
title={placeholder}
8991
placeholder={placeholder}
9092
onChange={(e) => handleType({ type: selected.id, value: e.target.value })}
91-
value={value}
93+
value={value !== undefined && !disabled ? value : ''}
9294
min={min}
9395
max={max}
9496
data-testid="input-group-first-field"
9597
step={step}
98+
disabled={disabled}
9699
/>
97100
<span className="form-control-state" />
98101
{selected.unit && (
@@ -122,7 +125,7 @@ export default function InputGroupSNCF({
122125
aria-haspopup="true"
123126
aria-expanded="false"
124127
aria-controls={id}
125-
disabled={disableUnitSelector}
128+
disabled={disabled || disableUnitSelector}
126129
>
127130
<span className={cx(condensed && 'small')}>{selected.label}</span>
128131
<i

front/src/common/BootstrapSNCF/InputSNCF.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ const InputSNCF = ({
103103
type="button"
104104
className={`${newFormSize} btn btn-primary btn-only-icon active`}
105105
onClick={appendOptions.onClick}
106+
disabled={disabled}
106107
>
107108
{appendOptions.label}
108109
<span className="sr-only">{appendOptions.name}</span>
@@ -149,7 +150,7 @@ const InputSNCF = ({
149150
className={`form-control ${backgroundColor} ${formSize} ${readOnlyFlag} ${clearOption} ${condensedInput} ${textAlignmentClass}`}
150151
id={id}
151152
name={name}
152-
value={value}
153+
value={disabled ? '' : value}
153154
placeholder={placeholder}
154155
ref={(input) => (focus ? input && input.focus() : null)}
155156
min={min}

front/src/modules/trainschedule/components/ManageTrainSchedule/Allowances/Allowances.tsx

+84-96
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
import React, { useEffect, useMemo, useState } from 'react';
22
import { useTranslation } from 'react-i18next';
33
import { useDispatch, useSelector } from 'react-redux';
4-
import { getAllowances, getPathfindingID } from 'reducers/osrdconf/selectors';
5-
import { StandardAllowance, osrdEditoastApi, Allowance } from 'common/api/osrdEditoastApi';
64
import { AiOutlineDash } from 'react-icons/ai';
5+
6+
import { StandardAllowance, osrdEditoastApi, Allowance } from 'common/api/osrdEditoastApi';
77
import { updateAllowances } from 'reducers/osrdconf';
8-
import cx from 'classnames';
8+
import { getAllowances, getPathfindingID } from 'reducers/osrdconf/selectors';
99
import AllowancesStandardSettings from './AllowancesStandardSettings';
1010
import AllowancesActions from './AllowancesActions';
1111
import AllowancesList from './AllowancesList';
1212
import {
1313
AllowanceValueForm,
1414
AllowancesTypes,
1515
EngineeringAllowanceForm,
16-
ManageAllowancesType,
1716
OverlapAllowancesIndexesType,
17+
RangeAllowanceForm,
1818
StandardAllowanceForm,
1919
} from './types';
20-
import AllowancesLinearView from './AllowancesLinearView';
2120
import { initialStandardAllowance } from './consts';
22-
import getAllowanceValue from './helpers';
21+
import getAllowanceValue, { fillAllowancesWithDefaultRanges } from './helpers';
22+
import AllowancesLinearView from './AllowancesLinearView';
2323

2424
const MissingPathFindingMessage = () => {
2525
const { t } = useTranslation('operationalStudies/allowances');
@@ -43,16 +43,26 @@ export default function Allowances() {
4343
{ id: pathFindingID as number },
4444
{ skip: !pathFindingID }
4545
);
46-
const pathLength = pathFinding?.length ? Math.round(pathFinding.length) : 0;
46+
47+
const pathLength = pathFinding?.length ? pathFinding.length : 0;
4748
const allowances = useSelector(getAllowances);
48-
const [collapsedStandardAllowanceRanges, setCollapsedStandardAllowanceRanges] = useState(true);
49-
const [standardAllowance, setStandardAllowance] = useState(
50-
(allowances &&
51-
(allowances.find(
49+
const [standardAllowance, setStandardAllowance] = useState(() => {
50+
if (allowances) {
51+
const tmpStandardAllowance = allowances.find(
5252
(allowance) => allowance.allowance_type === 'standard'
53-
) as StandardAllowanceForm)) ||
54-
initialStandardAllowance
55-
);
53+
) as StandardAllowanceForm;
54+
if (tmpStandardAllowance)
55+
return {
56+
...tmpStandardAllowance,
57+
ranges: fillAllowancesWithDefaultRanges(
58+
tmpStandardAllowance.ranges,
59+
tmpStandardAllowance.default_value,
60+
pathLength
61+
),
62+
};
63+
}
64+
return initialStandardAllowance;
65+
});
5666
const [engineeringAllowances, setEngineeringAllowances] = useState(
5767
(allowances &&
5868
(allowances.filter(
@@ -69,6 +79,9 @@ export default function Allowances() {
6979
const [overlapAllowancesIndexes, setOverlapAllowancesIndexes] =
7080
useState<OverlapAllowancesIndexesType>([false, false]);
7181

82+
const [engineeringOverlapAllowancesIndexes, setEngineeringOverlapAllowancesIndexes] =
83+
useState<OverlapAllowancesIndexesType>([false, false]);
84+
7285
const standardAllowanceValue = useMemo(
7386
() => getAllowanceValue(standardAllowance.default_value),
7487
[standardAllowance]
@@ -78,10 +91,6 @@ export default function Allowances() {
7891
setStandardAllowance({ ...standardAllowance, distribution });
7992
};
8093

81-
const setStandardValueAndUnit = (valueAndUnit: AllowanceValueForm) => {
82-
setStandardAllowance({ ...standardAllowance, default_value: valueAndUnit });
83-
};
84-
8594
const toggleStandardAllowanceSelectedIndex = (AllowanceIndex?: number) => {
8695
setStandardAllowanceSelectedIndex(
8796
AllowanceIndex !== standardAllowanceSelectedIndex ? AllowanceIndex : undefined
@@ -96,46 +105,38 @@ export default function Allowances() {
96105
const resetFunction = (type: AllowancesTypes) => {
97106
if (type === AllowancesTypes.standard) {
98107
setStandardAllowance(initialStandardAllowance);
108+
setStandardAllowanceSelectedIndex(undefined);
99109
}
100110
if (type === AllowancesTypes.standard) {
101111
setEngineeringAllowances([]);
112+
setEngineeringAllowanceSelectedIndex(undefined);
102113
}
103114
};
104115

105-
// This function manage "add" and "delete" allowance, "update" is "delete" followed by "add"
106-
const manageAllowance = ({
107-
type,
108-
newAllowance,
109-
allowanceIndexToDelete,
110-
}: ManageAllowancesType) => {
111-
if (type === AllowancesTypes.standard) {
112-
const newRanges =
113-
allowanceIndexToDelete !== undefined
114-
? standardAllowance.ranges.filter((_, idx) => allowanceIndexToDelete !== idx)
115-
: [...standardAllowance.ranges];
116-
setStandardAllowance({
117-
...standardAllowance,
118-
ranges: (newAllowance ? [...newRanges, newAllowance] : newRanges).sort(
119-
(a, b) => a.begin_position - b.begin_position
120-
),
121-
});
122-
setStandardAllowanceSelectedIndex(undefined);
123-
}
124-
if (type === AllowancesTypes.engineering) {
125-
const newEngineeringAllowances =
126-
allowanceIndexToDelete !== undefined
127-
? engineeringAllowances.filter((_, index) => index !== allowanceIndexToDelete)
128-
: [...engineeringAllowances];
129-
setEngineeringAllowances(
130-
(newAllowance
131-
? ([...newEngineeringAllowances, newAllowance] as EngineeringAllowanceForm[])
132-
: newEngineeringAllowances
133-
).sort((a, b) => a.begin_position - b.begin_position)
134-
);
135-
setEngineeringAllowanceSelectedIndex(undefined);
136-
}
116+
const updateStandardAllowanceDefaultValue = (newDefaultValue: AllowanceValueForm) => {
117+
setStandardAllowance({ ...standardAllowance, default_value: newDefaultValue });
137118
};
138119

120+
const updateStandardAllowances = (newStandardAllowanceRanges: RangeAllowanceForm[]) => {
121+
setStandardAllowance({
122+
...standardAllowance,
123+
ranges: newStandardAllowanceRanges,
124+
});
125+
setStandardAllowanceSelectedIndex(undefined);
126+
};
127+
128+
const updateEngineeringAllowances = (newStandardAllowanceRanges: EngineeringAllowanceForm[]) => {
129+
setEngineeringAllowances(newStandardAllowanceRanges);
130+
setEngineeringAllowanceSelectedIndex(undefined);
131+
};
132+
133+
useEffect(() => {
134+
const newRanges = standardAllowance.ranges.map((allowance) =>
135+
allowance.isDefault ? { ...allowance, value: standardAllowance.default_value } : allowance
136+
);
137+
setStandardAllowance({ ...standardAllowance, ranges: newRanges });
138+
}, [standardAllowance.default_value]);
139+
139140
// dispatch only the valid allowances in the store
140141
useEffect(() => {
141142
const standardAllowanceDefaultValue = getAllowanceValue(standardAllowance.default_value);
@@ -161,55 +162,40 @@ export default function Allowances() {
161162
distribution={standardAllowance.distribution}
162163
valueAndUnit={standardAllowance.default_value}
163164
setDistribution={setStandardDistribution}
164-
setValueAndUnit={setStandardValueAndUnit}
165+
updateStandardAllowanceDefaultValue={updateStandardAllowanceDefaultValue}
165166
/>
166167
{standardAllowanceValue !== undefined && standardAllowanceValue > 0 && (
167168
<>
168-
<button
169-
className="subtitle mb-1 mt-2"
170-
type="button"
171-
onClick={() =>
172-
setCollapsedStandardAllowanceRanges(!collapsedStandardAllowanceRanges)
173-
}
174-
>
169+
<div className="subtitle mb-2 mt-2">
175170
<AiOutlineDash />
176171
<span className="ml-1">{t('standardAllowanceIntervals')}</span>
177-
<span className={cx('ml-auto', standardAllowance.ranges.length > 0 && 'd-none')}>
178-
{collapsedStandardAllowanceRanges ? (
179-
<i className="icons-arrow-down" />
180-
) : (
181-
<i className="icons-arrow-up" />
182-
)}
183-
</span>
184-
</button>
185-
{(!collapsedStandardAllowanceRanges || standardAllowance.ranges.length > 0) && (
186-
<>
187-
<AllowancesActions
188-
allowances={standardAllowance.ranges}
189-
pathLength={pathLength}
190-
manageAllowance={manageAllowance}
191-
type={AllowancesTypes.standard}
192-
allowanceSelectedIndex={standardAllowanceSelectedIndex}
193-
setAllowanceSelectedIndex={setStandardAllowanceSelectedIndex}
194-
setOverlapAllowancesIndexes={setOverlapAllowancesIndexes}
195-
pathFindingSteps={pathFinding?.steps}
196-
/>
197-
<AllowancesLinearView
198-
allowances={standardAllowance.ranges}
199-
pathLength={pathLength}
200-
allowanceSelectedIndex={standardAllowanceSelectedIndex}
201-
setAllowanceSelectedIndex={toggleStandardAllowanceSelectedIndex}
202-
globalDistribution={standardAllowance.distribution}
203-
/>
204-
<AllowancesList
205-
allowances={standardAllowance.ranges}
206-
type={AllowancesTypes.standard}
207-
allowanceSelectedIndex={standardAllowanceSelectedIndex}
208-
setAllowanceSelectedIndex={toggleStandardAllowanceSelectedIndex}
209-
overlapAllowancesIndexes={overlapAllowancesIndexes}
210-
/>
211-
</>
212-
)}
172+
</div>
173+
<AllowancesActions
174+
allowances={standardAllowance.ranges}
175+
pathLength={pathLength}
176+
type={AllowancesTypes.standard}
177+
allowanceSelectedIndex={standardAllowanceSelectedIndex}
178+
setAllowanceSelectedIndex={setStandardAllowanceSelectedIndex}
179+
setOverlapAllowancesIndexes={setOverlapAllowancesIndexes}
180+
pathFindingSteps={pathFinding?.steps}
181+
updateAllowances={updateStandardAllowances}
182+
defaultAllowance={standardAllowance.default_value}
183+
overlapAllowancesIndexes={overlapAllowancesIndexes}
184+
/>
185+
<AllowancesLinearView
186+
allowances={standardAllowance.ranges}
187+
defaultAllowance={standardAllowance.default_value}
188+
pathLength={pathLength}
189+
allowanceSelectedIndex={standardAllowanceSelectedIndex}
190+
setAllowanceSelectedIndex={toggleStandardAllowanceSelectedIndex}
191+
globalDistribution={standardAllowance.distribution}
192+
/>
193+
<AllowancesList
194+
allowances={standardAllowance.ranges}
195+
allowanceSelectedIndex={standardAllowanceSelectedIndex}
196+
setAllowanceSelectedIndex={toggleStandardAllowanceSelectedIndex}
197+
overlapAllowancesIndexes={overlapAllowancesIndexes}
198+
/>
213199
</>
214200
)}
215201
</div>
@@ -232,11 +218,13 @@ export default function Allowances() {
232218
<AllowancesActions
233219
allowances={engineeringAllowances}
234220
pathLength={pathLength}
235-
manageAllowance={manageAllowance}
221+
updateAllowances={updateEngineeringAllowances}
236222
type={AllowancesTypes.engineering}
237223
allowanceSelectedIndex={EngineeringAllowanceSelectedIndex}
238224
setAllowanceSelectedIndex={setEngineeringAllowanceSelectedIndex}
239225
pathFindingSteps={pathFinding?.steps}
226+
overlapAllowancesIndexes={engineeringOverlapAllowancesIndexes}
227+
setOverlapAllowancesIndexes={setEngineeringOverlapAllowancesIndexes}
240228
/>
241229
{/*
242230
* Temporary desactivated until new version with overlap
@@ -250,9 +238,9 @@ export default function Allowances() {
250238
*/}
251239
<AllowancesList
252240
allowances={engineeringAllowances}
253-
type={AllowancesTypes.engineering}
254241
allowanceSelectedIndex={EngineeringAllowanceSelectedIndex}
255242
setAllowanceSelectedIndex={toggleEngineeringAllowanceSelectedIndex}
243+
overlapAllowancesIndexes={engineeringOverlapAllowancesIndexes}
256244
/>
257245
</div>
258246
</>

0 commit comments

Comments
 (0)