Reset time range if either value changes (#88186)

Previously we had `getStart` and `getEnd` methods used in `useUrlParams` that would give a new value if the respective `rangeFrom`/`rangeTo` had change.

This had the effect of sometimes making the end time sooner than the start time, causing errors on the page.

`getStart` and `getEnd` have been replaced with a `getDateRange` method that checks if *either* value has changed and recaluates the start/end, but leaves them the same if both values have not changed.

Fixes #85238.
This commit is contained in:
Nathan L Smith 2021-01-13 13:07:00 -06:00 committed by GitHub
parent 0e118c2099
commit e07c541036
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 14 deletions

View file

@ -0,0 +1,77 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import datemath from '@elastic/datemath';
import moment from 'moment-timezone';
import * as helpers from './helpers';
describe('url_params_context helpers', () => {
describe('getParsedDate', () => {
describe('given undefined', () => {
it('returns undefined', () => {
expect(helpers.getParsedDate(undefined)).toBeUndefined();
});
});
describe('given a parsable date', () => {
it('returns the parsed date', () => {
expect(helpers.getParsedDate('1970-01-01T00:00:00.000Z')).toEqual(
'1970-01-01T00:00:00.000Z'
);
});
});
describe('given a non-parsable date', () => {
it('returns null', () => {
expect(helpers.getParsedDate('nope')).toEqual(null);
});
});
});
describe('getDateRange', () => {
describe('when rangeFrom and rangeTo are not changed', () => {
it('returns the previous state', () => {
expect(
helpers.getDateRange({
state: {
rangeFrom: 'now-1m',
rangeTo: 'now',
start: '1970-01-01T00:00:00.000Z',
end: '1971-01-01T00:00:00.000Z',
},
rangeFrom: 'now-1m',
rangeTo: 'now',
})
).toEqual({
start: '1970-01-01T00:00:00.000Z',
end: '1971-01-01T00:00:00.000Z',
});
});
});
describe('when rangeFrom or rangeTo have changed', () => {
it('returns new state', () => {
jest.spyOn(datemath, 'parse').mockReturnValue(moment(0).utc());
expect(
helpers.getDateRange({
state: {
rangeFrom: 'now-1m',
rangeTo: 'now',
start: '1972-01-01T00:00:00.000Z',
end: '1973-01-01T00:00:00.000Z',
},
rangeFrom: 'now-2m',
rangeTo: 'now',
})
).toEqual({
start: '1970-01-01T00:00:00.000Z',
end: '1970-01-01T00:00:00.000Z',
});
});
});
});
});

View file

@ -17,18 +17,23 @@ export function getParsedDate(rawDate?: string, opts = {}) {
}
}
export function getStart(prevState: IUrlParams, rangeFrom?: string) {
if (prevState.rangeFrom !== rangeFrom) {
return getParsedDate(rangeFrom);
export function getDateRange({
state,
rangeFrom,
rangeTo,
}: {
state: IUrlParams;
rangeFrom?: string;
rangeTo?: string;
}) {
if (state.rangeFrom === rangeFrom && state.rangeTo === rangeTo) {
return { start: state.start, end: state.end };
}
return prevState.start;
}
export function getEnd(prevState: IUrlParams, rangeTo?: string) {
if (prevState.rangeTo !== rangeTo) {
return getParsedDate(rangeTo, { roundUp: true });
}
return prevState.end;
return {
start: getParsedDate(rangeFrom),
end: getParsedDate(rangeTo, { roundUp: true }),
};
}
export function toNumber(value?: string) {

View file

@ -11,8 +11,7 @@ import { pickKeys } from '../../../common/utils/pick_keys';
import { localUIFilterNames } from '../../../server/lib/ui_filters/local_ui_filters/config';
import { toQuery } from '../../components/shared/Links/url_helpers';
import {
getEnd,
getStart,
getDateRange,
removeUndefinedProps,
toBoolean,
toNumber,
@ -56,8 +55,7 @@ export function resolveUrlParams(location: Location, state: TimeUrlParams) {
return removeUndefinedProps({
// date params
start: getStart(state, rangeFrom),
end: getEnd(state, rangeTo),
...getDateRange({ state, rangeFrom, rangeTo }),
rangeFrom,
rangeTo,
refreshPaused: refreshPaused ? toBoolean(refreshPaused) : undefined,