From e5a25f92d98babb3b170de1ea041a7444c36072a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Fri, 5 Feb 2021 09:16:34 +0100 Subject: [PATCH] [APM] Enabling yesterday option when 24 hours is selected (#90017) (#90295) * enabling yesterday option when 24 hours is selected * addressing PR comments * addressing PR comments * enabling select box --- .../common/utils/formatters/datetime.test.ts | 29 +++++-- .../apm/common/utils/formatters/datetime.ts | 26 +++--- .../shared/time_comparison/index.test.tsx | 83 ++++++++++++++++++- .../shared/time_comparison/index.tsx | 53 ++++++++---- 4 files changed, 154 insertions(+), 37 deletions(-) diff --git a/x-pack/plugins/apm/common/utils/formatters/datetime.test.ts b/x-pack/plugins/apm/common/utils/formatters/datetime.test.ts index 6aee1e2b9842de..9efb7184f39275 100644 --- a/x-pack/plugins/apm/common/utils/formatters/datetime.test.ts +++ b/x-pack/plugins/apm/common/utils/formatters/datetime.test.ts @@ -170,37 +170,52 @@ describe('date time formatters', () => { it('milliseconds', () => { const start = moment('2019-10-29 08:00:00.001'); const end = moment('2019-10-29 08:00:00.005'); - expect(getDateDifference(start, end, 'milliseconds')).toEqual(4); + expect( + getDateDifference({ start, end, unitOfTime: 'milliseconds' }) + ).toEqual(4); }); it('seconds', () => { const start = moment('2019-10-29 08:00:00'); const end = moment('2019-10-29 08:00:10'); - expect(getDateDifference(start, end, 'seconds')).toEqual(10); + expect(getDateDifference({ start, end, unitOfTime: 'seconds' })).toEqual( + 10 + ); }); it('minutes', () => { const start = moment('2019-10-29 08:00:00'); const end = moment('2019-10-29 08:15:00'); - expect(getDateDifference(start, end, 'minutes')).toEqual(15); + expect(getDateDifference({ start, end, unitOfTime: 'minutes' })).toEqual( + 15 + ); }); it('hours', () => { const start = moment('2019-10-29 08:00:00'); const end = moment('2019-10-29 10:00:00'); - expect(getDateDifference(start, end, 'hours')).toEqual(2); + expect(getDateDifference({ start, end, unitOfTime: 'hours' })).toEqual(2); }); it('days', () => { const start = moment('2019-10-29 08:00:00'); const end = moment('2019-10-30 10:00:00'); - expect(getDateDifference(start, end, 'days')).toEqual(1); + expect(getDateDifference({ start, end, unitOfTime: 'days' })).toEqual(1); }); it('months', () => { const start = moment('2019-10-29 08:00:00'); const end = moment('2019-12-29 08:00:00'); - expect(getDateDifference(start, end, 'months')).toEqual(2); + expect(getDateDifference({ start, end, unitOfTime: 'months' })).toEqual( + 2 + ); }); it('years', () => { const start = moment('2019-10-29 08:00:00'); const end = moment('2020-10-29 08:00:00'); - expect(getDateDifference(start, end, 'years')).toEqual(1); + expect(getDateDifference({ start, end, unitOfTime: 'years' })).toEqual(1); + }); + it('precise days', () => { + const start = moment('2019-10-29 08:00:00'); + const end = moment('2019-10-30 10:00:00'); + expect( + getDateDifference({ start, end, unitOfTime: 'days', precise: true }) + ).toEqual(1.0833333333333333); }); }); }); diff --git a/x-pack/plugins/apm/common/utils/formatters/datetime.ts b/x-pack/plugins/apm/common/utils/formatters/datetime.ts index 624a0b8a664bcd..88f70753f47c82 100644 --- a/x-pack/plugins/apm/common/utils/formatters/datetime.ts +++ b/x-pack/plugins/apm/common/utils/formatters/datetime.ts @@ -58,37 +58,43 @@ function getDateFormat(dateUnit: DateUnit) { } } -export const getDateDifference = ( - start: moment.Moment, - end: moment.Moment, - unitOfTime: DateUnit | TimeUnit -) => end.diff(start, unitOfTime); +export const getDateDifference = ({ + start, + end, + unitOfTime, + precise, +}: { + start: moment.Moment; + end: moment.Moment; + unitOfTime: DateUnit | TimeUnit; + precise?: boolean; +}) => end.diff(start, unitOfTime, precise); function getFormatsAccordingToDateDifference( start: moment.Moment, end: moment.Moment ) { - if (getDateDifference(start, end, 'years') >= 5) { + if (getDateDifference({ start, end, unitOfTime: 'years' }) >= 5) { return { dateFormat: getDateFormat('years') }; } - if (getDateDifference(start, end, 'months') >= 5) { + if (getDateDifference({ start, end, unitOfTime: 'months' }) >= 5) { return { dateFormat: getDateFormat('months') }; } const dateFormatWithDays = getDateFormat('days'); - if (getDateDifference(start, end, 'days') > 1) { + if (getDateDifference({ start, end, unitOfTime: 'days' }) > 1) { return { dateFormat: dateFormatWithDays }; } - if (getDateDifference(start, end, 'minutes') >= 1) { + if (getDateDifference({ start, end, unitOfTime: 'minutes' }) >= 1) { return { dateFormat: dateFormatWithDays, timeFormat: getTimeFormat('minutes'), }; } - if (getDateDifference(start, end, 'seconds') >= 10) { + if (getDateDifference({ start, end, unitOfTime: 'seconds' }) >= 10) { return { dateFormat: dateFormatWithDays, timeFormat: getTimeFormat('seconds'), 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 52d971a5511440..4ace78f74ee79e 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 @@ -17,6 +17,7 @@ import { } from '../../../utils/testHelpers'; import { TimeComparison } from './'; import * as urlHelpers from '../../shared/Links/url_helpers'; +import moment from 'moment'; function getWrapper(params?: IUrlParams) { return ({ children }: { children?: ReactNode }) => { @@ -31,6 +32,10 @@ function getWrapper(params?: IUrlParams) { } describe('TimeComparison', () => { + beforeAll(() => { + moment.tz.setDefault('Europe/Amsterdam'); + }); + afterAll(() => moment.tz.setDefault('')); const spy = jest.spyOn(urlHelpers, 'replace'); beforeEach(() => { jest.resetAllMocks(); @@ -40,6 +45,7 @@ describe('TimeComparison', () => { const Wrapper = getWrapper({ start: '2021-01-28T14:45:00.000Z', end: '2021-01-28T15:00:00.000Z', + rangeTo: 'now', }); render(, { wrapper: Wrapper, @@ -57,6 +63,7 @@ describe('TimeComparison', () => { end: '2021-01-28T15:00:00.000Z', comparisonEnabled: true, comparisonType: 'yesterday', + rangeTo: 'now', }); const component = render(, { wrapper: Wrapper, @@ -67,13 +74,64 @@ describe('TimeComparison', () => { .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: 'yesterday', + rangeTo: 'now', + }); + const component = render(, { + wrapper: Wrapper, + }); + expectTextsInDocument(component, ['Yesterday', 'A week ago']); + 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: 'previousPeriod', + rangeTo: 'now-15m', + }); + const component = render(, { + wrapper: Wrapper, + }); + expectTextsInDocument(component, ['28/01 11:00 - 29/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: 'week', + rangeTo: 'now', + }); + const component = render(, { + wrapper: Wrapper, + }); + expectTextsNotInDocument(component, ['Yesterday']); + expectTextsInDocument(component, ['A week ago']); + }); 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, @@ -91,6 +149,7 @@ describe('TimeComparison', () => { end: '2021-01-28T15:00:00.000Z', comparisonEnabled: true, comparisonType: 'week', + rangeTo: 'now', }); const component = render(, { wrapper: Wrapper, @@ -102,6 +161,24 @@ describe('TimeComparison', () => { .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: 'previousPeriod', + rangeTo: '2021-01-28T15:00:00.000Z', + }); + const component = render(, { + wrapper: Wrapper, + }); + expectTextsInDocument(component, ['26/01 16:00 - 28/01 16:00']); + expect( + (component.getByTestId('comparisonSelect') as HTMLSelectElement) + .selectedIndex + ).toEqual(0); + }); }); describe('Time range is greater than 7 days', () => { @@ -111,12 +188,13 @@ describe('TimeComparison', () => { end: '2021-01-28T15:00:00.000Z', comparisonEnabled: true, comparisonType: 'previousPeriod', + rangeTo: 'now', }); const component = render(, { wrapper: Wrapper, }); expect(spy).not.toHaveBeenCalled(); - expectTextsInDocument(component, ['20/01 - 28/01']); + expectTextsInDocument(component, ['20/01 16:00 - 28/01 16:00']); expect( (component.getByTestId('comparisonSelect') as HTMLSelectElement) .selectedIndex @@ -129,12 +207,13 @@ describe('TimeComparison', () => { end: '2021-01-28T15:00:00.000Z', comparisonEnabled: true, comparisonType: 'previousPeriod', + rangeTo: 'now', }); const component = render(, { wrapper: Wrapper, }); expect(spy).not.toHaveBeenCalled(); - expectTextsInDocument(component, ['20/12/20 - 28/01/21']); + expectTextsInDocument(component, ['20/12/20 16:00 - 28/01/21 16:00']); expect( (component.getByTestId('comparisonSelect') as HTMLSelectElement) .selectedIndex 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 bb50ca1a45e8ca..02064ea786fb09 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 @@ -33,14 +33,21 @@ function formatPreviousPeriodDates({ momentEnd: moment.Moment; }) { const isDifferentYears = momentStart.get('year') !== momentEnd.get('year'); - const dateFormat = isDifferentYears ? 'DD/MM/YY' : 'DD/MM'; + const dateFormat = isDifferentYears ? 'DD/MM/YY HH:mm' : 'DD/MM HH:mm'; return `${momentStart.format(dateFormat)} - ${momentEnd.format(dateFormat)}`; } -function getSelectOptions({ start, end }: { start?: string; end?: string }) { +function getSelectOptions({ + start, + end, + rangeTo, +}: { + start?: string; + end?: string; + rangeTo?: string; +}) { const momentStart = moment(start); const momentEnd = moment(end); - const dateDiff = getDateDifference(momentStart, momentEnd, 'days'); const yesterdayOption = { value: 'yesterday', @@ -56,22 +63,32 @@ function getSelectOptions({ start, end }: { start?: string; end?: string }) { }), }; + const dateDiff = getDateDifference({ + start: momentStart, + end: momentEnd, + unitOfTime: 'days', + precise: true, + }); + const isRangeToNow = rangeTo === 'now'; + + if (isRangeToNow) { + // Less than or equals to one day + if (dateDiff <= 1) { + return [yesterdayOption, aWeekAgoOption]; + } + + // Less than or equals to one week + if (dateDiff <= 7) { + return [aWeekAgoOption]; + } + } + const prevPeriodOption = { value: 'previousPeriod', text: formatPreviousPeriodDates({ momentStart, momentEnd }), }; - // Less than one day - if (dateDiff < 1) { - return [yesterdayOption, aWeekAgoOption]; - } - - // Less than one week - if (dateDiff <= 7) { - return [aWeekAgoOption]; - } - - // above one week + // above one week or when rangeTo is not "now" return [prevPeriodOption]; } @@ -79,10 +96,10 @@ export function TimeComparison() { const history = useHistory(); const { isMedium, isLarge } = useBreakPoints(); const { - urlParams: { start, end, comparisonEnabled, comparisonType }, + urlParams: { start, end, comparisonEnabled, comparisonType, rangeTo }, } = useUrlParams(); - const selectOptions = getSelectOptions({ start, end }); + const selectOptions = getSelectOptions({ start, end, rangeTo }); // Sets default values if (comparisonEnabled === undefined || comparisonType === undefined) { @@ -113,7 +130,7 @@ export function TimeComparison() { 0} + checked={comparisonEnabled} onChange={() => { urlHelpers.push(history, { query: {