diff --git a/x-pack/plugins/apm/public/components/shared/time_comparison/index.test.tsx b/x-pack/plugins/apm/public/components/shared/time_comparison/index.test.tsx
index a4f44290fe777..dd87c23908cbc 100644
--- a/x-pack/plugins/apm/public/components/shared/time_comparison/index.test.tsx
+++ b/x-pack/plugins/apm/public/components/shared/time_comparison/index.test.tsx
@@ -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('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',
- });
- render(, {
- wrapper: Wrapper,
- });
- expect(spy).toHaveBeenCalledWith(expect.anything(), {
- query: {
- comparisonEnabled: 'true',
- comparisonType: TimeRangeComparisonType.DayBefore,
- },
- });
+
+ 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('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',
- });
- const component = render(, {
- wrapper: Wrapper,
- });
- expectTextsInDocument(component, ['Day before', 'Week before']);
+
+ it('shows week and day before when Today is selected', () => {
expect(
- (component.getByTestId('comparisonSelect') as HTMLSelectElement)
- .selectedIndex
- ).toEqual(0);
+ getComparisonTypes({
+ start: '2021-06-04T04:00:00.000Z',
+ end: '2021-06-05T03:59:59.999Z',
+ })
+ ).toEqual([
+ TimeRangeComparisonType.DayBefore.valueOf(),
+ TimeRangeComparisonType.WeekBefore.valueOf(),
+ ]);
});
- 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(, {
- wrapper: Wrapper,
- });
- expectTextsInDocument(component, ['Day before', 'Week before']);
+ 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(
- (component.getByTestId('comparisonSelect') as HTMLSelectElement)
- .selectedIndex
- ).toEqual(0);
+ getComparisonTypes({
+ start: '2021-06-02T12:32:00.000Z',
+ end: '2021-06-03T13:32:09.079Z',
+ })
+ ).toEqual([TimeRangeComparisonType.WeekBefore.valueOf()]);
});
- 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(, {
- wrapper: Wrapper,
- });
- expectTextsInDocument(component, ['27/01 11:00 - 28/01 11:00']);
+ 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(
- (component.getByTestId('comparisonSelect') as HTMLSelectElement)
- .selectedIndex
- ).toEqual(0);
+ getComparisonTypes({
+ start: '2021-05-27T16:32:46.747Z',
+ end: '2021-06-04T16:32:46.747Z',
+ })
+ ).toEqual([TimeRangeComparisonType.PeriodBefore.valueOf()]);
});
});
- 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(, {
- 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(, {
- wrapper: Wrapper,
- });
- expect(spy).toHaveBeenCalledWith(expect.anything(), {
- query: {
- comparisonEnabled: 'true',
- comparisonType: TimeRangeComparisonType.WeekBefore,
+ 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('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',
- });
- const component = render(, {
- wrapper: Wrapper,
- });
- expectTextsNotInDocument(component, ['Day before']);
- expectTextsInDocument(component, ['Week before']);
+
+ it('formats period before as DD/MM/YY HH:mm when range years are different', () => {
expect(
- (component.getByTestId('comparisonSelect') as HTMLSelectElement)
- .selectedIndex
- ).toEqual(0);
+ 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',
+ },
+ ]);
});
+ });
- 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('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(, { wrapper: Wrapper });
+ expect(spy).toHaveBeenCalledWith(expect.anything(), {
+ query: {
+ comparisonEnabled: 'true',
+ comparisonType: TimeRangeComparisonType.DayBefore,
+ },
+ });
});
- const component = render(, {
- wrapper: Wrapper,
+ 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(, { wrapper: Wrapper });
+ expectTextsInDocument(component, ['Day before', 'Week before']);
+ expect(
+ (component.getByTestId('comparisonSelect') as HTMLSelectElement)
+ .selectedIndex
+ ).toEqual(0);
+ });
+
+ 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(, { wrapper: Wrapper });
+ expectTextsInDocument(component, ['Day before', 'Week before']);
+ expect(
+ (component.getByTestId('comparisonSelect') as HTMLSelectElement)
+ .selectedIndex
+ ).toEqual(0);
});
- 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',
+ 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(, {
+ wrapper: Wrapper,
+ });
+ expectTextsNotInDocument(component, ['Day before']);
+ expectTextsInDocument(component, ['Week before']);
});
- const component = render(, {
- wrapper: Wrapper,
+ it('sets default values', () => {
+ const Wrapper = getWrapper({
+ exactStart: '2021-06-02T12:32:00.000Z',
+ exactEnd: '2021-06-03T13:32:09.079Z',
+ });
+ render(, {
+ wrapper: Wrapper,
+ });
+ expect(spy).toHaveBeenCalledWith(expect.anything(), {
+ query: {
+ comparisonEnabled: 'true',
+ comparisonType: TimeRangeComparisonType.WeekBefore,
+ },
+ });
+ });
+ 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(, {
+ wrapper: Wrapper,
+ });
+ expectTextsNotInDocument(component, ['Day before']);
+ expectTextsInDocument(component, ['Week before']);
+ expect(
+ (component.getByTestId('comparisonSelect') as HTMLSelectElement)
+ .selectedIndex
+ ).toEqual(0);
});
- 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',
+ 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(, {
+ 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(, {
- wrapper: Wrapper,
+
+ 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(, {
+ 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);
});
- 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);
});
});
});
diff --git a/x-pack/plugins/apm/public/components/shared/time_comparison/index.tsx b/x-pack/plugins/apm/public/components/shared/time_comparison/index.tsx
index 98fbd4f399d98..cbe7b81486a64 100644
--- a/x-pack/plugins/apm/public/components/shared/time_comparison/index.tsx
+++ b/x-pack/plugins/apm/public/components/shared/time_comparison/index.tsx
@@ -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 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';
+ const dateDiff = getDateDifference({
+ start: momentStart,
+ end: momentEnd,
+ unitOfTime: 'days',
+ precise: true,
+ });
- if (isRangeToNow) {
- // Less than or equals to one day
- if (dateDiff <= 1) {
- return [dayBeforeOption, weekBeforeOption];
- }
+ // Less than or equals to one day
+ if (dateDiff <= 1) {
+ return [
+ TimeRangeComparisonType.DayBefore,
+ TimeRangeComparisonType.WeekBefore,
+ ];
+ }
- // Less than or equals to one week
- if (dateDiff <= 7) {
- return [weekBeforeOption];
- }
+ // Less than or equals to one week
+ if (dateDiff <= 7) {
+ return [TimeRangeComparisonType.WeekBefore];
}
+ // }
- const { comparisonStart, comparisonEnd } = getTimeRangeComparison({
- comparisonType: TimeRangeComparisonType.PeriodBefore,
- start,
- end,
- comparisonEnabled,
- });
+ // above one week or when rangeTo is not "now"
+ return [TimeRangeComparisonType.PeriodBefore];
+}
- const dateFormat = getDateFormat({
- previousPeriodStart: comparisonStart,
- currentPeriodEnd: end,
- });
+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 prevPeriodOption = {
- value: TimeRangeComparisonType.PeriodBefore,
- text: formatDate({
- dateFormat,
- previousPeriodStart: comparisonStart,
- previousPeriodEnd: comparisonEnd,
- }),
- };
+ const dateFormat = getDateFormat({
+ previousPeriodStart: comparisonStart,
+ currentPeriodEnd: end,
+ });
- // above one week or when rangeTo is not "now"
- return [prevPeriodOption];
+ 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
);
diff --git a/x-pack/plugins/apm/public/context/url_params_context/helpers.test.ts b/x-pack/plugins/apm/public/context/url_params_context/helpers.test.ts
index 4de68a5bc2036..784b10b3f3ee1 100644
--- a/x-pack/plugins/apm/public/context/url_params_context/helpers.test.ts
+++ b/x-pack/plugins/apm/public/context/url_params_context/helpers.test.ts
@@ -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', {});
+ });
+ });
});
diff --git a/x-pack/plugins/apm/public/context/url_params_context/helpers.ts b/x-pack/plugins/apm/public/context/url_params_context/helpers.ts
index eae9eba8b3dda..902456bf4ebc0 100644
--- a/x-pack/plugins/apm/public/context/url_params_context/helpers.ts
+++ b/x-pack/plugins/apm/public/context/url_params_context/helpers.ts
@@ -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(),
};
}
diff --git a/x-pack/plugins/apm/public/context/url_params_context/resolve_url_params.ts b/x-pack/plugins/apm/public/context/url_params_context/resolve_url_params.ts
index b6e7330be30cb..134f65bbf0f40 100644
--- a/x-pack/plugins/apm/public/context/url_params_context/resolve_url_params.ts
+++ b/x-pack/plugins/apm/public/context/url_params_context/resolve_url_params.ts
@@ -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) {
diff --git a/x-pack/plugins/apm/public/context/url_params_context/types.ts b/x-pack/plugins/apm/public/context/url_params_context/types.ts
index 4332019d1a1c9..5e9e4bd257b87 100644
--- a/x-pack/plugins/apm/public/context/url_params_context/types.ts
+++ b/x-pack/plugins/apm/public/context/url_params_context/types.ts
@@ -17,6 +17,8 @@ export type IUrlParams = {
environment?: string;
rangeFrom?: string;
rangeTo?: string;
+ exactStart?: string;
+ exactEnd?: string;
refreshInterval?: number;
refreshPaused?: boolean;
sortDirection?: string;
diff --git a/x-pack/plugins/apm/public/context/url_params_context/url_params_context.tsx b/x-pack/plugins/apm/public/context/url_params_context/url_params_context.tsx
index 1da57ac10a20c..f3969745b6ea7 100644
--- a/x-pack/plugins/apm/public/context/url_params_context/url_params_context.tsx
+++ b/x-pack/plugins/apm/public/context/url_params_context/url_params_context.tsx
@@ -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;