Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

front: fix stdcm origin time panel behaviour #5761

Merged
merged 1 commit into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions front/src/applications/stdcm/views/OSRDStdcmConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ export default function OSRDConfig({
!osrdconf.origin ||
!osrdconf.destination ||
!(osrdconf.originTime || osrdconf.destinationTime) ||
(osrdconf.originTime &&
osrdconf.originUpperBoundTime &&
osrdconf.originTime > osrdconf.originUpperBoundTime) ||
!osrdconf.rollingStockID,
[infra, osrdconf]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ function Origin(props: OriginProps) {
className="form-control form-control-sm mx-1"
onChange={(e) => dispatch(updateOriginDate(e.target.value))}
value={originDate}
disabled
/>
<InputSNCF
type="time"
Expand All @@ -136,6 +135,10 @@ function Origin(props: OriginProps) {
sm
noMargin
readonly={isByDestination}
isInvalid={
(originTime && originUpperBoundTime && originTime > originUpperBoundTime) ||
false
}
/>
</div>
<div className="d-flex my-1">
Expand All @@ -144,7 +147,6 @@ function Origin(props: OriginProps) {
className="form-control form-control-sm mx-1"
onChange={(e) => dispatch(updateOriginUpperBoundDate(e.target.value))}
value={originUpperBoundDate}
disabled
/>
<InputSNCF
type="time"
Expand All @@ -156,6 +158,10 @@ function Origin(props: OriginProps) {
sm
noMargin
readonly={isByDestination}
isInvalid={
(originTime && originUpperBoundTime && originTime > originUpperBoundTime) ||
false
}
/>
</div>
</div>
Expand Down
36 changes: 0 additions & 36 deletions front/src/reducers/__tests__/osrdconf.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,24 +97,6 @@ describe('osrdconfReducer', () => {
expect(state.osrdconf.simulationConf.originTime).toBe('08:00:00');
expect(state.osrdconf.simulationConf.originUpperBoundTime).toBe('10:00:00');
});
test('lower bound should not go above upper bound when unlinked', () => {
const store = createStore({
osrdconf: {
simulationConf: {
originLinkedBounds: false,
originTime: '10:00:00',
originUpperBoundTime: '12:00:00',
},
},
});

const action = updateOriginTime('13:00:00');
store.dispatch(action);

const state = store.getState();
expect(state.osrdconf.simulationConf.originTime).toBe('12:00:00');
expect(state.osrdconf.simulationConf.originUpperBoundTime).toBe('12:00:00');
});
});
describe('updateOriginUpperBoundTime', () => {
it('should update only itself if not linked', () => {
Expand Down Expand Up @@ -187,24 +169,6 @@ describe('osrdconfReducer', () => {
expect(state.osrdconf.simulationConf.originTime).toBe('18:00:00');
expect(state.osrdconf.simulationConf.originUpperBoundTime).toBe('20:00:00');
});
test('upper bound should not go below lower bonud when unlinked', () => {
const store = createStore({
osrdconf: {
simulationConf: {
originLinkedBounds: false,
originTime: '14:00:00',
originUpperBoundTime: '18:00:00',
},
},
});

const action = updateOriginUpperBoundTime('12:00:00');
store.dispatch(action);

const state = store.getState();
expect(state.osrdconf.simulationConf.originTime).toBe('14:00:00');
expect(state.osrdconf.simulationConf.originUpperBoundTime).toBe('14:00:00');
});
});
describe('toggleOriginLinkedBounds', () => {
it('should set to false if true', () => {
Expand Down
128 changes: 128 additions & 0 deletions front/src/reducers/osrdconf/__tests__/helpers.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { computeLinkedOriginTimes } from '../helpers';

describe('computeLinkedOriginTimes', () => {
describe('should throw error', () => {
it('should throw error if no new time is provided', () => {
expect(() =>
computeLinkedOriginTimes(
'2023-11-22',
'08:00:00',
'2023-11-22',
'10:00:00',
undefined,
undefined
)
).toThrow(new Error('One of newOriginTime or newOriginUpperBoundTime must be provided'));
});

it('should throw error if 2 new times are provided', () => {
expect(() =>
computeLinkedOriginTimes(
'2023-11-22',
'08:00:00',
'2023-11-22',
'10:00:00',
'14:00:00',
'16:00:00'
)
).toThrow(new Error('Both newOriginTime and newOriginUpperBoundTime are provided'));
});
});

describe('should manage new origin time', () => {
it('should not update originUpperBoundDate', () => {
const result = computeLinkedOriginTimes(
'2023-11-22',
'08:00:00',
'2023-11-22',
'10:00:00',
'14:00:00'
);
expect(result).toEqual({
newOriginTime: '14:00:00',
newOriginUpperBoundTime: '16:00:00',
newOriginUpperBoundDate: null,
});
});

it('should set originUpperBoundDate to the day after originDate', () => {
const result = computeLinkedOriginTimes(
'2023-11-22',
'08:00:00',
'2023-11-22',
'10:00:00',
'23:00:00'
);
expect(result).toEqual({
newOriginTime: '23:00:00',
newOriginUpperBoundTime: '01:00:00',
newOriginUpperBoundDate: '2023-11-23',
});
});

it('should set originUpperBoundDate equal to originDate', () => {
const result = computeLinkedOriginTimes(
'2023-11-22',
'23:00:00',
'2023-11-23',
'01:00:00',
'09:00:00'
);
expect(result).toEqual({
newOriginTime: '09:00:00',
newOriginUpperBoundTime: '11:00:00',
newOriginUpperBoundDate: '2023-11-22',
});
});
});

describe('should manage new origin upper bound time', () => {
it('should not update originUpperBoundDate', () => {
const result = computeLinkedOriginTimes(
'2023-11-22',
'08:00:00',
'2023-11-22',
'10:00:00',
undefined,
'14:00:00'
);
expect(result).toEqual({
newOriginTime: '12:00:00',
newOriginUpperBoundTime: '14:00:00',
newOriginUpperBoundDate: null,
});
});

it('should set originUpperBoundDate to the day after originDate', () => {
const result = computeLinkedOriginTimes(
'2023-11-22',
'08:00:00',
'2023-11-22',
'10:00:00',
undefined,
'01:00:00'
);
expect(result).toEqual({
newOriginTime: '23:00:00',
newOriginUpperBoundTime: '01:00:00',
newOriginUpperBoundDate: '2023-11-23',
});
});

it('should set originUpperBoundDate equal to originDate', () => {
const result = computeLinkedOriginTimes(
'2023-11-22',
'23:00:00',
'2023-11-23',
'01:00:00',
undefined,
'23:30:00'
);
expect(result).toEqual({
newOriginTime: '21:30:00',
newOriginUpperBoundTime: '23:30:00',
newOriginUpperBoundDate: '2023-11-22',
});
});
});
});
72 changes: 72 additions & 0 deletions front/src/reducers/osrdconf/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { formatIsoDate } from 'utils/date';
import { sec2time, time2sec } from 'utils/timeManipulation';

/** 2 hours in ms */
const ORIGIN_TIME_BOUND_DEFAULT_DIFFERENCE = 7200;

const computeNewOriginUpperBoundDate = (
newOriginTime: string,
newOriginUpperBoundTime: string,
originDate: string | undefined,
originUpperBoundDate: string | undefined
) => {
if (newOriginUpperBoundTime < newOriginTime) {
const newOriginDate = originDate ? new Date(originDate) : new Date();
newOriginDate.setDate(newOriginDate.getDate() + 1);
return formatIsoDate(newOriginDate);
}
if (originDate !== originUpperBoundDate) {
return originDate;
}
return null;
};

/**
* Given current origin dates and times and a new origin time or new origin upper bound time,
* compute the new origin times and the new origin upper bound date while keeping the same time difference.
*
* See tests for more examples.
*/
// eslint-disable-next-line import/prefer-default-export
export const computeLinkedOriginTimes = (
originDate: string | undefined,
originTime: string | undefined,
originUpperBoundDate: string | undefined,
originUpperBoundTime: string | undefined,
newOriginTime: string | undefined,
newOriginUpperBoundTime: string | undefined = undefined
) => {
let computedOriginTime: string | undefined;
let computedOriginUpperBoundTime: string | undefined;

if (newOriginTime && newOriginUpperBoundTime)
throw new Error('Both newOriginTime and newOriginUpperBoundTime are provided');

const difference =
originTime && originUpperBoundTime
? time2sec(originUpperBoundTime) - time2sec(originTime)
: ORIGIN_TIME_BOUND_DEFAULT_DIFFERENCE;

if (newOriginTime) {
const newOriginTimeSeconds = time2sec(newOriginTime);
computedOriginTime = newOriginTime;
computedOriginUpperBoundTime = sec2time(newOriginTimeSeconds + difference);
} else if (newOriginUpperBoundTime) {
const newOriginUpperBoundTimeSeconds = time2sec(newOriginUpperBoundTime);
computedOriginTime = sec2time(newOriginUpperBoundTimeSeconds - difference);
computedOriginUpperBoundTime = newOriginUpperBoundTime;
} else {
throw new Error('One of newOriginTime or newOriginUpperBoundTime must be provided');
}

return {
newOriginTime: computedOriginTime,
newOriginUpperBoundTime: computedOriginUpperBoundTime,
newOriginUpperBoundDate: computeNewOriginUpperBoundDate(
computedOriginTime,
computedOriginUpperBoundTime,
originDate,
originUpperBoundDate
),
};
};
Loading
Loading