[APM] Fixing time comparison types (#101423)

* fixing time comparison types

* fixing ts issues

* addressing PR comments

* addressing PR comments

* addressing PR comments

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Cauê Marcondes 2021-06-16 14:32:22 -04:00 committed by GitHub
parent 8eea491412
commit adc95c1023
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 407 additions and 242 deletions

View file

@ -15,7 +15,7 @@ import {
expectTextsInDocument,
expectTextsNotInDocument,
} from '../../../utils/testHelpers';
import { TimeComparison } from './';
import { getComparisonTypes, getSelectOptions, TimeComparison } from './';
import * as urlHelpers from '../../shared/Links/url_helpers';
import moment from 'moment';
import { TimeRangeComparisonType } from './get_time_range_comparison';
@ -37,188 +37,248 @@ describe('TimeComparison', () => {
moment.tz.setDefault('Europe/Amsterdam');
});
afterAll(() => moment.tz.setDefault(''));
const spy = jest.spyOn(urlHelpers, 'replace');
beforeEach(() => {
jest.resetAllMocks();
describe('getComparisonTypes', () => {
it('shows week and day before when 15 minutes is selected', () => {
expect(
getComparisonTypes({
start: '2021-06-04T16:17:02.335Z',
end: '2021-06-04T16:32:02.335Z',
})
).toEqual([
TimeRangeComparisonType.DayBefore.valueOf(),
TimeRangeComparisonType.WeekBefore.valueOf(),
]);
});
it('shows week and day before when Today is selected', () => {
expect(
getComparisonTypes({
start: '2021-06-04T04:00:00.000Z',
end: '2021-06-05T03:59:59.999Z',
})
).toEqual([
TimeRangeComparisonType.DayBefore.valueOf(),
TimeRangeComparisonType.WeekBefore.valueOf(),
]);
});
it('shows week and day before when 24 hours is selected', () => {
expect(
getComparisonTypes({
start: '2021-06-03T16:31:35.748Z',
end: '2021-06-04T16:31:35.748Z',
})
).toEqual([
TimeRangeComparisonType.DayBefore.valueOf(),
TimeRangeComparisonType.WeekBefore.valueOf(),
]);
});
it('shows week before when 25 hours is selected', () => {
expect(
getComparisonTypes({
start: '2021-06-02T12:32:00.000Z',
end: '2021-06-03T13:32:09.079Z',
})
).toEqual([TimeRangeComparisonType.WeekBefore.valueOf()]);
});
it('shows week before when 7 days is selected', () => {
expect(
getComparisonTypes({
start: '2021-05-28T16:32:17.520Z',
end: '2021-06-04T16:32:17.520Z',
})
).toEqual([TimeRangeComparisonType.WeekBefore.valueOf()]);
});
it('shows period before when 8 days is selected', () => {
expect(
getComparisonTypes({
start: '2021-05-27T16:32:46.747Z',
end: '2021-06-04T16:32:46.747Z',
})
).toEqual([TimeRangeComparisonType.PeriodBefore.valueOf()]);
});
});
describe('Time range is between 0 - 24 hours', () => {
it('sets default values', () => {
const Wrapper = getWrapper({
start: '2021-01-28T14:45:00.000Z',
end: '2021-01-28T15:00:00.000Z',
rangeTo: 'now',
describe('getSelectOptions', () => {
it('returns formatted text based on comparison type', () => {
expect(
getSelectOptions({
comparisonTypes: [
TimeRangeComparisonType.DayBefore,
TimeRangeComparisonType.WeekBefore,
TimeRangeComparisonType.PeriodBefore,
],
start: '2021-05-27T16:32:46.747Z',
end: '2021-06-04T16:32:46.747Z',
})
).toEqual([
{
value: TimeRangeComparisonType.DayBefore.valueOf(),
text: 'Day before',
},
{
value: TimeRangeComparisonType.WeekBefore.valueOf(),
text: 'Week before',
},
{
value: TimeRangeComparisonType.PeriodBefore.valueOf(),
text: '19/05 18:32 - 27/05 18:32',
},
]);
});
it('formats period before as DD/MM/YY HH:mm when range years are different', () => {
expect(
getSelectOptions({
comparisonTypes: [TimeRangeComparisonType.PeriodBefore],
start: '2020-05-27T16:32:46.747Z',
end: '2021-06-04T16:32:46.747Z',
})
).toEqual([
{
value: TimeRangeComparisonType.PeriodBefore.valueOf(),
text: '20/05/19 18:32 - 27/05/20 18:32',
},
]);
});
});
describe('TimeComparison component', () => {
const spy = jest.spyOn(urlHelpers, 'replace');
beforeEach(() => {
jest.resetAllMocks();
});
describe('Time range is between 0 - 24 hours', () => {
it('sets default values', () => {
const Wrapper = getWrapper({
exactStart: '2021-06-04T16:17:02.335Z',
exactEnd: '2021-06-04T16:32:02.335Z',
});
render(<TimeComparison />, { wrapper: Wrapper });
expect(spy).toHaveBeenCalledWith(expect.anything(), {
query: {
comparisonEnabled: 'true',
comparisonType: TimeRangeComparisonType.DayBefore,
},
});
});
render(<TimeComparison />, {
wrapper: Wrapper,
});
expect(spy).toHaveBeenCalledWith(expect.anything(), {
query: {
comparisonEnabled: 'true',
it('selects day before and enables comparison', () => {
const Wrapper = getWrapper({
exactStart: '2021-06-04T16:17:02.335Z',
exactEnd: '2021-06-04T16:32:02.335Z',
comparisonEnabled: true,
comparisonType: TimeRangeComparisonType.DayBefore,
},
});
const component = render(<TimeComparison />, { wrapper: Wrapper });
expectTextsInDocument(component, ['Day before', 'Week before']);
expect(
(component.getByTestId('comparisonSelect') as HTMLSelectElement)
.selectedIndex
).toEqual(0);
});
});
it('selects day before and enables comparison', () => {
const Wrapper = getWrapper({
start: '2021-01-28T14:45:00.000Z',
end: '2021-01-28T15:00:00.000Z',
comparisonEnabled: true,
comparisonType: TimeRangeComparisonType.DayBefore,
rangeTo: 'now',
it('enables day before option when date difference is equal to 24 hours', () => {
const Wrapper = getWrapper({
exactStart: '2021-06-03T16:31:35.748Z',
exactEnd: '2021-06-04T16:31:35.748Z',
comparisonEnabled: true,
comparisonType: TimeRangeComparisonType.DayBefore,
});
const component = render(<TimeComparison />, { wrapper: Wrapper });
expectTextsInDocument(component, ['Day before', 'Week before']);
expect(
(component.getByTestId('comparisonSelect') as HTMLSelectElement)
.selectedIndex
).toEqual(0);
});
const component = render(<TimeComparison />, {
wrapper: Wrapper,
});
expectTextsInDocument(component, ['Day before', 'Week before']);
expect(
(component.getByTestId('comparisonSelect') as HTMLSelectElement)
.selectedIndex
).toEqual(0);
});
it('enables yesterday option when date difference is equal to 24 hours', () => {
const Wrapper = getWrapper({
start: '2021-01-28T10:00:00.000Z',
end: '2021-01-29T10:00:00.000Z',
comparisonEnabled: true,
comparisonType: TimeRangeComparisonType.DayBefore,
rangeTo: 'now',
});
const component = render(<TimeComparison />, {
wrapper: Wrapper,
});
expectTextsInDocument(component, ['Day before', 'Week before']);
expect(
(component.getByTestId('comparisonSelect') as HTMLSelectElement)
.selectedIndex
).toEqual(0);
});
it('selects previous period when rangeTo is different than now', () => {
const Wrapper = getWrapper({
start: '2021-01-28T10:00:00.000Z',
end: '2021-01-29T10:00:00.000Z',
comparisonEnabled: true,
comparisonType: TimeRangeComparisonType.PeriodBefore,
rangeTo: 'now-15m',
});
const component = render(<TimeComparison />, {
wrapper: Wrapper,
});
expectTextsInDocument(component, ['27/01 11:00 - 28/01 11:00']);
expect(
(component.getByTestId('comparisonSelect') as HTMLSelectElement)
.selectedIndex
).toEqual(0);
});
});
describe('Time range is between 24 hours - 1 week', () => {
it("doesn't show yesterday option when date difference is greater than 24 hours", () => {
const Wrapper = getWrapper({
start: '2021-01-28T10:00:00.000Z',
end: '2021-01-29T11:00:00.000Z',
comparisonEnabled: true,
comparisonType: TimeRangeComparisonType.WeekBefore,
rangeTo: 'now',
});
const component = render(<TimeComparison />, {
wrapper: Wrapper,
});
expectTextsNotInDocument(component, ['Day before']);
expectTextsInDocument(component, ['Week before']);
});
it('sets default values', () => {
const Wrapper = getWrapper({
start: '2021-01-26T15:00:00.000Z',
end: '2021-01-28T15:00:00.000Z',
rangeTo: 'now',
});
render(<TimeComparison />, {
wrapper: Wrapper,
});
expect(spy).toHaveBeenCalledWith(expect.anything(), {
query: {
comparisonEnabled: 'true',
describe('Time range is between 24 hours - 1 week', () => {
it("doesn't show day before option when date difference is greater than 24 hours", () => {
const Wrapper = getWrapper({
exactStart: '2021-06-02T12:32:00.000Z',
exactEnd: '2021-06-03T13:32:09.079Z',
comparisonEnabled: true,
comparisonType: TimeRangeComparisonType.WeekBefore,
},
});
const component = render(<TimeComparison />, {
wrapper: Wrapper,
});
expectTextsNotInDocument(component, ['Day before']);
expectTextsInDocument(component, ['Week before']);
});
});
it('selects week and enables comparison', () => {
const Wrapper = getWrapper({
start: '2021-01-26T15:00:00.000Z',
end: '2021-01-28T15:00:00.000Z',
comparisonEnabled: true,
comparisonType: TimeRangeComparisonType.WeekBefore,
rangeTo: 'now',
it('sets default values', () => {
const Wrapper = getWrapper({
exactStart: '2021-06-02T12:32:00.000Z',
exactEnd: '2021-06-03T13:32:09.079Z',
});
render(<TimeComparison />, {
wrapper: Wrapper,
});
expect(spy).toHaveBeenCalledWith(expect.anything(), {
query: {
comparisonEnabled: 'true',
comparisonType: TimeRangeComparisonType.WeekBefore,
},
});
});
const component = render(<TimeComparison />, {
wrapper: Wrapper,
it('selects week before and enables comparison', () => {
const Wrapper = getWrapper({
exactStart: '2021-06-02T12:32:00.000Z',
exactEnd: '2021-06-03T13:32:09.079Z',
comparisonEnabled: true,
comparisonType: TimeRangeComparisonType.WeekBefore,
});
const component = render(<TimeComparison />, {
wrapper: Wrapper,
});
expectTextsNotInDocument(component, ['Day before']);
expectTextsInDocument(component, ['Week before']);
expect(
(component.getByTestId('comparisonSelect') as HTMLSelectElement)
.selectedIndex
).toEqual(0);
});
expectTextsNotInDocument(component, ['Day before']);
expectTextsInDocument(component, ['Week before']);
expect(
(component.getByTestId('comparisonSelect') as HTMLSelectElement)
.selectedIndex
).toEqual(0);
});
it('selects previous period when rangeTo is different than now', () => {
const Wrapper = getWrapper({
start: '2021-01-26T15:00:00.000Z',
end: '2021-01-28T15:00:00.000Z',
comparisonEnabled: true,
comparisonType: TimeRangeComparisonType.PeriodBefore,
rangeTo: '2021-01-28T15:00:00.000Z',
describe('Time range is greater than 7 days', () => {
it('Shows absolute times without year when within the same year', () => {
const Wrapper = getWrapper({
exactStart: '2021-05-27T16:32:46.747Z',
exactEnd: '2021-06-04T16:32:46.747Z',
comparisonEnabled: true,
comparisonType: TimeRangeComparisonType.PeriodBefore,
});
const component = render(<TimeComparison />, {
wrapper: Wrapper,
});
expect(spy).not.toHaveBeenCalled();
expectTextsInDocument(component, ['19/05 18:32 - 27/05 18:32']);
expect(
(component.getByTestId('comparisonSelect') as HTMLSelectElement)
.selectedIndex
).toEqual(0);
});
const component = render(<TimeComparison />, {
wrapper: Wrapper,
});
expectTextsInDocument(component, ['24/01 16:00 - 26/01 16:00']);
expect(
(component.getByTestId('comparisonSelect') as HTMLSelectElement)
.selectedIndex
).toEqual(0);
});
});
describe('Time range is greater than 7 days', () => {
it('Shows absolute times without year when within the same year', () => {
const Wrapper = getWrapper({
start: '2021-01-20T15:00:00.000Z',
end: '2021-01-28T15:00:00.000Z',
comparisonEnabled: true,
comparisonType: TimeRangeComparisonType.PeriodBefore,
rangeTo: 'now',
it('Shows absolute times with year when on different year', () => {
const Wrapper = getWrapper({
exactStart: '2020-05-27T16:32:46.747Z',
exactEnd: '2021-06-04T16:32:46.747Z',
comparisonEnabled: true,
comparisonType: TimeRangeComparisonType.PeriodBefore,
});
const component = render(<TimeComparison />, {
wrapper: Wrapper,
});
expect(spy).not.toHaveBeenCalled();
expectTextsInDocument(component, ['20/05/19 18:32 - 27/05/20 18:32']);
expect(
(component.getByTestId('comparisonSelect') as HTMLSelectElement)
.selectedIndex
).toEqual(0);
});
const component = render(<TimeComparison />, {
wrapper: Wrapper,
});
expect(spy).not.toHaveBeenCalled();
expectTextsInDocument(component, ['12/01 16:00 - 20/01 16:00']);
expect(
(component.getByTestId('comparisonSelect') as HTMLSelectElement)
.selectedIndex
).toEqual(0);
});
it('Shows absolute times with year when on different year', () => {
const Wrapper = getWrapper({
start: '2020-12-20T15:00:00.000Z',
end: '2021-01-28T15:00:00.000Z',
comparisonEnabled: true,
comparisonType: TimeRangeComparisonType.PeriodBefore,
rangeTo: 'now',
});
const component = render(<TimeComparison />, {
wrapper: Wrapper,
});
expect(spy).not.toHaveBeenCalled();
expectTextsInDocument(component, ['11/11/20 16:00 - 20/12/20 16:00']);
expect(
(component.getByTestId('comparisonSelect') as HTMLSelectElement)
.selectedIndex
).toEqual(0);
});
});
});

View file

@ -59,80 +59,92 @@ function formatDate({
return `${momentStart.format(dateFormat)} - ${momentEnd.format(dateFormat)}`;
}
function getSelectOptions({
export function getComparisonTypes({
start,
end,
rangeTo,
comparisonEnabled,
}: {
start?: string;
end?: string;
rangeTo?: string;
comparisonEnabled?: boolean;
}) {
const momentStart = moment(start);
const momentEnd = moment(end);
const dayBeforeOption = {
value: TimeRangeComparisonType.DayBefore,
text: i18n.translate('xpack.apm.timeComparison.select.dayBefore', {
defaultMessage: 'Day before',
}),
};
const dateDiff = getDateDifference({
start: momentStart,
end: momentEnd,
unitOfTime: 'days',
precise: true,
});
const weekBeforeOption = {
value: TimeRangeComparisonType.WeekBefore,
text: i18n.translate('xpack.apm.timeComparison.select.weekBefore', {
defaultMessage: 'Week before',
}),
};
const dateDiff = Number(
getDateDifference({
start: momentStart,
end: momentEnd,
unitOfTime: 'days',
precise: true,
}).toFixed(2)
);
const isRangeToNow = rangeTo === 'now';
if (isRangeToNow) {
// Less than or equals to one day
if (dateDiff <= 1) {
return [dayBeforeOption, weekBeforeOption];
}
// Less than or equals to one week
if (dateDiff <= 7) {
return [weekBeforeOption];
}
// Less than or equals to one day
if (dateDiff <= 1) {
return [
TimeRangeComparisonType.DayBefore,
TimeRangeComparisonType.WeekBefore,
];
}
const { comparisonStart, comparisonEnd } = getTimeRangeComparison({
comparisonType: TimeRangeComparisonType.PeriodBefore,
start,
end,
comparisonEnabled,
});
const dateFormat = getDateFormat({
previousPeriodStart: comparisonStart,
currentPeriodEnd: end,
});
const prevPeriodOption = {
value: TimeRangeComparisonType.PeriodBefore,
text: formatDate({
dateFormat,
previousPeriodStart: comparisonStart,
previousPeriodEnd: comparisonEnd,
}),
};
// Less than or equals to one week
if (dateDiff <= 7) {
return [TimeRangeComparisonType.WeekBefore];
}
// }
// above one week or when rangeTo is not "now"
return [prevPeriodOption];
return [TimeRangeComparisonType.PeriodBefore];
}
export function getSelectOptions({
comparisonTypes,
start,
end,
}: {
comparisonTypes: TimeRangeComparisonType[];
start?: string;
end?: string;
}) {
return comparisonTypes.map((value) => {
switch (value) {
case TimeRangeComparisonType.DayBefore: {
return {
value,
text: i18n.translate('xpack.apm.timeComparison.select.dayBefore', {
defaultMessage: 'Day before',
}),
};
}
case TimeRangeComparisonType.WeekBefore: {
return {
value,
text: i18n.translate('xpack.apm.timeComparison.select.weekBefore', {
defaultMessage: 'Week before',
}),
};
}
case TimeRangeComparisonType.PeriodBefore: {
const { comparisonStart, comparisonEnd } = getTimeRangeComparison({
comparisonType: TimeRangeComparisonType.PeriodBefore,
start,
end,
comparisonEnabled: true,
});
const dateFormat = getDateFormat({
previousPeriodStart: comparisonStart,
currentPeriodEnd: end,
});
return {
value,
text: formatDate({
dateFormat,
previousPeriodStart: comparisonStart,
previousPeriodEnd: comparisonEnd,
}),
};
}
}
});
}
export function TimeComparison() {
@ -140,14 +152,12 @@ export function TimeComparison() {
const history = useHistory();
const { isMedium, isLarge } = useBreakPoints();
const {
urlParams: { start, end, comparisonEnabled, comparisonType, rangeTo },
urlParams: { comparisonEnabled, comparisonType, exactStart, exactEnd },
} = useUrlParams();
const selectOptions = getSelectOptions({
start,
end,
rangeTo,
comparisonEnabled,
const comparisonTypes = getComparisonTypes({
start: exactStart,
end: exactEnd,
});
// Sets default values
@ -155,14 +165,18 @@ export function TimeComparison() {
urlHelpers.replace(history, {
query: {
comparisonEnabled: comparisonEnabled === false ? 'false' : 'true',
comparisonType: comparisonType
? comparisonType
: selectOptions[0].value,
comparisonType: comparisonType ? comparisonType : comparisonTypes[0],
},
});
return null;
}
const selectOptions = getSelectOptions({
comparisonTypes,
start: exactStart,
end: exactEnd,
});
const isSelectedComparisonTypeAvailable = selectOptions.some(
({ value }) => value === comparisonType
);

View file

@ -10,6 +10,9 @@ import moment from 'moment-timezone';
import * as helpers from './helpers';
describe('url_params_context helpers', () => {
beforeEach(() => {
jest.restoreAllMocks();
});
describe('getDateRange', () => {
describe('with non-rounded dates', () => {
describe('one minute', () => {
@ -23,6 +26,8 @@ describe('url_params_context helpers', () => {
).toEqual({
start: '2021-01-28T05:47:00.000Z',
end: '2021-01-28T05:48:55.304Z',
exactStart: '2021-01-28T05:47:52.134Z',
exactEnd: '2021-01-28T05:48:55.304Z',
});
});
});
@ -37,6 +42,8 @@ describe('url_params_context helpers', () => {
).toEqual({
start: '2021-01-27T05:46:00.000Z',
end: '2021-01-28T05:46:13.367Z',
exactStart: '2021-01-27T05:46:07.377Z',
exactEnd: '2021-01-28T05:46:13.367Z',
});
});
});
@ -52,6 +59,8 @@ describe('url_params_context helpers', () => {
).toEqual({
start: '2020-01-28T05:52:00.000Z',
end: '2021-01-28T05:52:39.741Z',
exactStart: '2020-01-28T05:52:36.290Z',
exactEnd: '2021-01-28T05:52:39.741Z',
});
});
});
@ -66,6 +75,8 @@ describe('url_params_context helpers', () => {
rangeTo: 'now',
start: '1970-01-01T00:00:00.000Z',
end: '1971-01-01T00:00:00.000Z',
exactStart: '1970-01-01T00:00:00.000Z',
exactEnd: '1971-01-01T00:00:00.000Z',
},
rangeFrom: 'now-1m',
rangeTo: 'now',
@ -73,6 +84,8 @@ describe('url_params_context helpers', () => {
).toEqual({
start: '1970-01-01T00:00:00.000Z',
end: '1971-01-01T00:00:00.000Z',
exactStart: '1970-01-01T00:00:00.000Z',
exactEnd: '1971-01-01T00:00:00.000Z',
});
});
});
@ -94,24 +107,37 @@ describe('url_params_context helpers', () => {
).toEqual({
start: '1972-01-01T00:00:00.000Z',
end: '1973-01-01T00:00:00.000Z',
exactStart: undefined,
exactEnd: undefined,
});
});
});
describe('when the start or end are invalid', () => {
it('returns the previous state', () => {
const endDate = moment('2021-06-04T18:03:24.211Z');
jest
.spyOn(datemath, 'parse')
.mockReturnValueOnce(undefined)
.mockReturnValueOnce(endDate)
.mockReturnValueOnce(undefined)
.mockReturnValueOnce(endDate);
expect(
helpers.getDateRange({
state: {
start: '1972-01-01T00:00:00.000Z',
end: '1973-01-01T00:00:00.000Z',
exactStart: '1972-01-01T00:00:00.000Z',
exactEnd: '1973-01-01T00:00:00.000Z',
},
rangeFrom: 'nope',
rangeTo: 'now',
})
).toEqual({
start: '1972-01-01T00:00:00.000Z',
exactStart: '1972-01-01T00:00:00.000Z',
end: '1973-01-01T00:00:00.000Z',
exactEnd: '1973-01-01T00:00:00.000Z',
});
});
});
@ -134,8 +160,38 @@ describe('url_params_context helpers', () => {
).toEqual({
start: '1970-01-01T00:00:00.000Z',
end: '1970-01-01T00:00:00.000Z',
exactStart: '1970-01-01T00:00:00.000Z',
exactEnd: '1970-01-01T00:00:00.000Z',
});
});
});
});
describe('getExactDate', () => {
it('returns date when it is not not relative', () => {
expect(helpers.getExactDate('2021-01-28T05:47:52.134Z')).toEqual(
new Date('2021-01-28T05:47:52.134Z')
);
});
['s', 'm', 'h', 'd', 'w'].map((roundingOption) =>
it(`removes /${roundingOption} rounding option from relative time`, () => {
const spy = jest.spyOn(datemath, 'parse');
helpers.getExactDate(`now/${roundingOption}`);
expect(spy).toHaveBeenCalledWith('now', {});
})
);
it('removes rounding option but keeps subtracting time', () => {
const spy = jest.spyOn(datemath, 'parse');
helpers.getExactDate('now-24h/h');
expect(spy).toHaveBeenCalledWith('now-24h', {});
});
it('removes rounding option but keeps adding time', () => {
const spy = jest.spyOn(datemath, 'parse');
helpers.getExactDate('now+15m/h');
expect(spy).toHaveBeenCalledWith('now+15m', {});
});
});
});

View file

@ -19,6 +19,16 @@ function getParsedDate(rawDate?: string, options = {}) {
}
}
export function getExactDate(rawDate: string) {
const isRelativeDate = rawDate.startsWith('now');
if (isRelativeDate) {
// remove rounding from relative dates "Today" (now/d) and "This week" (now/w)
const rawDateWithouRounding = rawDate.replace(/\/([smhdw])$/, '');
return getParsedDate(rawDateWithouRounding);
}
return getParsedDate(rawDate);
}
export function getDateRange({
state,
rangeFrom,
@ -30,16 +40,28 @@ export function getDateRange({
}) {
// If the previous state had the same range, just return that instead of calculating a new range.
if (state.rangeFrom === rangeFrom && state.rangeTo === rangeTo) {
return { start: state.start, end: state.end };
return {
start: state.start,
end: state.end,
exactStart: state.exactStart,
exactEnd: state.exactEnd,
};
}
const start = getParsedDate(rangeFrom);
const end = getParsedDate(rangeTo, { roundUp: true });
const exactStart = rangeFrom ? getExactDate(rangeFrom) : undefined;
const exactEnd = rangeTo ? getExactDate(rangeTo) : undefined;
// `getParsedDate` will return undefined for invalid or empty dates. We return
// the previous state if either date is undefined.
if (!start || !end) {
return { start: state.start, end: state.end };
return {
start: state.start,
end: state.end,
exactStart: state.exactStart,
exactEnd: state.exactEnd,
};
}
// rounds down start to minute
@ -48,6 +70,8 @@ export function getDateRange({
return {
start: roundedStart.toISOString(),
end: end.toISOString(),
exactStart: exactStart?.toISOString(),
exactEnd: exactEnd?.toISOString(),
};
}

View file

@ -24,7 +24,7 @@ import { IUrlParams } from './types';
type TimeUrlParams = Pick<
IUrlParams,
'start' | 'end' | 'rangeFrom' | 'rangeTo'
'start' | 'end' | 'rangeFrom' | 'rangeTo' | 'exactStart' | 'exactEnd'
>;
export function resolveUrlParams(location: Location, state: TimeUrlParams) {

View file

@ -17,6 +17,8 @@ export type IUrlParams = {
environment?: string;
rangeFrom?: string;
rangeTo?: string;
exactStart?: string;
exactEnd?: string;
refreshInterval?: number;
refreshPaused?: boolean;
sortDirection?: string;

View file

@ -54,7 +54,14 @@ const UrlParamsProvider: React.ComponentClass<{}> = withRouter(
({ location, children }) => {
const refUrlParams = useRef(resolveUrlParams(location, {}));
const { start, end, rangeFrom, rangeTo } = refUrlParams.current;
const {
start,
end,
rangeFrom,
rangeTo,
exactStart,
exactEnd,
} = refUrlParams.current;
// Counter to force an update in useFetcher when the refresh button is clicked.
const [rangeId, setRangeId] = useState(0);
@ -66,8 +73,10 @@ const UrlParamsProvider: React.ComponentClass<{}> = withRouter(
end,
rangeFrom,
rangeTo,
exactStart,
exactEnd,
}),
[location, start, end, rangeFrom, rangeTo]
[location, start, end, rangeFrom, rangeTo, exactStart, exactEnd]
);
refUrlParams.current = urlParams;