From af251d2ea2ee955966d1d9ecc0afb0dd012d343d Mon Sep 17 00:00:00 2001 From: gbamparop Date: Tue, 8 Mar 2022 17:57:05 +0000 Subject: [PATCH] Update comparison date handling --- .../backend_detail_dependencies_table.tsx | 24 +- .../index.tsx | 23 +- .../app/error_group_overview/index.tsx | 10 +- .../app/service_inventory/index.tsx | 14 +- .../service_map/popover/backend_contents.tsx | 11 +- .../service_map/popover/service_contents.tsx | 11 +- .../index.tsx | 24 +- .../service_overview_errors_table/index.tsx | 9 +- ...ice_overview_instances_chart_and_table.tsx | 31 +- .../index.tsx | 10 +- .../service_overview_throughput_chart.tsx | 21 +- .../app/transaction_details/index.tsx | 2 - .../maybe_view_trace_link.tsx | 6 +- .../waterfall/flyout_top_level_properties.tsx | 6 +- .../app/transaction_overview/index.tsx | 2 - .../routing/service_detail/index.tsx | 2 + .../failed_transaction_rate_chart/index.tsx | 20 +- .../shared/charts/latency_chart/index.tsx | 12 +- .../charts/transaction_charts/index.tsx | 4 - .../index.tsx | 19 +- .../shared/time_comparison/comparison.test.ts | 434 ++++++++++++++++++ .../time_comparison/get_comparison_options.ts | 126 +++++ .../time_comparison/get_comparison_types.ts | 45 -- .../get_time_range_comparison.ts | 19 +- .../shared/time_comparison/index.test.tsx | 355 +++++--------- .../shared/time_comparison/index.tsx | 115 +---- .../shared/transactions_table/index.tsx | 18 +- .../url_params_context/helpers.test.ts | 90 +--- .../context/url_params_context/helpers.ts | 33 +- .../url_params_context/resolve_url_params.ts | 5 +- .../context/url_params_context/types.ts | 1 - .../url_params_context/url_params_context.tsx | 5 +- .../apm/public/hooks/use_comparison.ts | 4 +- .../use_error_group_distribution_fetcher.tsx | 11 +- .../apm/public/hooks/use_time_range.ts | 8 +- .../use_transaction_latency_chart_fetcher.ts | 16 +- 36 files changed, 816 insertions(+), 730 deletions(-) create mode 100644 x-pack/plugins/apm/public/components/shared/time_comparison/comparison.test.ts create mode 100644 x-pack/plugins/apm/public/components/shared/time_comparison/get_comparison_options.ts delete mode 100644 x-pack/plugins/apm/public/components/shared/time_comparison/get_comparison_types.ts diff --git a/x-pack/plugins/apm/public/components/app/backend_detail_overview/backend_detail_dependencies_table.tsx b/x-pack/plugins/apm/public/components/app/backend_detail_overview/backend_detail_dependencies_table.tsx index a72c50ec71c9455..7dc41ea4858ed62 100644 --- a/x-pack/plugins/apm/public/components/app/backend_detail_overview/backend_detail_dependencies_table.tsx +++ b/x-pack/plugins/apm/public/components/app/backend_detail_overview/backend_detail_dependencies_table.tsx @@ -9,30 +9,28 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import { getNodeName, NodeType } from '../../../../common/connections'; import { useApmParams } from '../../../hooks/use_apm_params'; -import { useLegacyUrlParams } from '../../../context/url_params_context/use_url_params'; +import { useComparison } from '../../../hooks/use_comparison'; import { useFetcher } from '../../../hooks/use_fetcher'; -import { getTimeRangeComparison } from '../../shared/time_comparison/get_time_range_comparison'; import { DependenciesTable } from '../../shared/dependencies_table'; import { ServiceLink } from '../../shared/service_link'; import { useTimeRange } from '../../../hooks/use_time_range'; export function BackendDetailDependenciesTable() { const { - urlParams: { comparisonEnabled, comparisonType }, - } = useLegacyUrlParams(); - - const { - query: { backendName, rangeFrom, rangeTo, kuery, environment }, + query: { + backendName, + rangeFrom, + rangeTo, + kuery, + environment, + comparisonEnabled, + comparisonType, + }, } = useApmParams('/backends/overview'); const { start, end } = useTimeRange({ rangeFrom, rangeTo }); - const { offset } = getTimeRangeComparison({ - start, - end, - comparisonEnabled, - comparisonType, - }); + const { offset } = useComparison(); const { data, status } = useFetcher( (callApmApi) => { diff --git a/x-pack/plugins/apm/public/components/app/backend_inventory/backend_inventory_dependencies_table/index.tsx b/x-pack/plugins/apm/public/components/app/backend_inventory/backend_inventory_dependencies_table/index.tsx index 71970e00f6d2630..33de388483df9ab 100644 --- a/x-pack/plugins/apm/public/components/app/backend_inventory/backend_inventory_dependencies_table/index.tsx +++ b/x-pack/plugins/apm/public/components/app/backend_inventory/backend_inventory_dependencies_table/index.tsx @@ -10,33 +10,30 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import { useUiTracker } from '../../../../../../observability/public'; import { getNodeName, NodeType } from '../../../../../common/connections'; -import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params'; import { useApmParams } from '../../../../hooks/use_apm_params'; +import { useComparison } from '../../../../hooks/use_comparison'; import { useFetcher } from '../../../../hooks/use_fetcher'; import { useTimeRange } from '../../../../hooks/use_time_range'; import { BackendLink } from '../../../shared/backend_link'; import { DependenciesTable } from '../../../shared/dependencies_table'; -import { getTimeRangeComparison } from '../../../shared/time_comparison/get_time_range_comparison'; export function BackendInventoryDependenciesTable() { const { - urlParams: { comparisonEnabled, comparisonType }, - } = useLegacyUrlParams(); - - const { - query: { rangeFrom, rangeTo, environment, kuery }, + query: { + rangeFrom, + rangeTo, + environment, + kuery, + comparisonEnabled, + comparisonType, + }, } = useApmParams('/backends'); const { start, end } = useTimeRange({ rangeFrom, rangeTo }); const trackEvent = useUiTracker(); - const { offset } = getTimeRangeComparison({ - start, - end, - comparisonEnabled, - comparisonType, - }); + const { offset } = useComparison(); const { data, status } = useFetcher( (callApmApi) => { diff --git a/x-pack/plugins/apm/public/components/app/error_group_overview/index.tsx b/x-pack/plugins/apm/public/components/app/error_group_overview/index.tsx index 46b963d13e51065..60b32691128e96a 100644 --- a/x-pack/plugins/apm/public/components/app/error_group_overview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/error_group_overview/index.tsx @@ -20,10 +20,10 @@ import { ChartPointerEventContextProvider } from '../../../context/chart_pointer import { useApmParams } from '../../../hooks/use_apm_params'; import { useErrorGroupDistributionFetcher } from '../../../hooks/use_error_group_distribution_fetcher'; import { useFetcher } from '../../../hooks/use_fetcher'; +import { useComparison } from '../../../hooks/use_comparison'; import { useTimeRange } from '../../../hooks/use_time_range'; import { APIReturnType } from '../../../services/rest/create_call_apm_api'; import { FailedTransactionRateChart } from '../../shared/charts/failed_transaction_rate_chart'; -import { getTimeRangeComparison } from '../../shared/time_comparison/get_time_range_comparison'; import { ErrorDistribution } from '../error_group_details/distribution'; import { ErrorGroupList } from './error_group_list'; @@ -56,18 +56,12 @@ export function ErrorGroupOverview() { sortDirection, rangeFrom, rangeTo, - comparisonType, comparisonEnabled, }, } = useApmParams('/services/{serviceName}/errors'); const { start, end } = useTimeRange({ rangeFrom, rangeTo }); - const { comparisonStart, comparisonEnd } = getTimeRangeComparison({ - start, - end, - comparisonType, - comparisonEnabled, - }); + const { comparisonStart, comparisonEnd } = useComparison(); const { errorDistributionData, status } = useErrorGroupDistributionFetcher({ serviceName, diff --git a/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx index 1e736409a96041c..59c5f27cb43f2bd 100644 --- a/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx @@ -10,13 +10,12 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; import uuid from 'uuid'; import { useAnomalyDetectionJobsContext } from '../../../context/anomaly_detection_jobs/use_anomaly_detection_jobs_context'; -import { useLegacyUrlParams } from '../../../context/url_params_context/use_url_params'; import { useLocalStorage } from '../../../hooks/use_local_storage'; +import { useComparison } from '../../../hooks/use_comparison'; import { useAnyOfApmParams } from '../../../hooks/use_apm_params'; import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher'; import { useTimeRange } from '../../../hooks/use_time_range'; import { SearchBar } from '../../shared/search_bar'; -import { getTimeRangeComparison } from '../../shared/time_comparison/get_time_range_comparison'; import { ServiceList } from './service_list'; import { MLCallout, shouldDisplayMlCallout } from '../../shared/ml_callout'; @@ -30,22 +29,13 @@ const initialData = { }; function useServicesFetcher() { - const { - urlParams: { comparisonEnabled, comparisonType }, - } = useLegacyUrlParams(); - const { query: { rangeFrom, rangeTo, environment, kuery }, } = useAnyOfApmParams('/services/{serviceName}', '/services'); const { start, end } = useTimeRange({ rangeFrom, rangeTo }); - const { offset } = getTimeRangeComparison({ - start, - end, - comparisonEnabled, - comparisonType, - }); + const { offset } = useComparison(); const { data = initialData, status: mainStatisticsStatus } = useFetcher( (callApmApi) => { diff --git a/x-pack/plugins/apm/public/components/app/service_map/popover/backend_contents.tsx b/x-pack/plugins/apm/public/components/app/service_map/popover/backend_contents.tsx index facc3a9dbc58210..d10732d98426ffe 100644 --- a/x-pack/plugins/apm/public/components/app/service_map/popover/backend_contents.tsx +++ b/x-pack/plugins/apm/public/components/app/service_map/popover/backend_contents.tsx @@ -14,10 +14,10 @@ import { useUiTracker } from '../../../../../../observability/public'; import { ContentsProps } from '.'; import { useAnyOfApmParams } from '../../../../hooks/use_apm_params'; import { useApmRouter } from '../../../../hooks/use_apm_router'; +import { useComparison } from '../../../../hooks/use_comparison'; import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher'; import { ApmRoutes } from '../../../routing/apm_route_config'; import { StatsList } from './stats_list'; -import { getTimeRangeComparison } from '../../../shared/time_comparison/get_time_range_comparison'; import { APIReturnType } from '../../../../services/rest/create_call_apm_api'; type BackendReturn = APIReturnType<'GET /internal/apm/service-map/backend'>; @@ -38,14 +38,7 @@ export function BackendContents({ '/services/{serviceName}/service-map' ); - const { comparisonEnabled, comparisonType } = query; - - const { offset } = getTimeRangeComparison({ - start, - end, - comparisonEnabled, - comparisonType, - }); + const { offset } = useComparison(); const apmRouter = useApmRouter(); diff --git a/x-pack/plugins/apm/public/components/app/service_map/popover/service_contents.tsx b/x-pack/plugins/apm/public/components/app/service_map/popover/service_contents.tsx index 9f28fbb24ff254f..4f554487baffc92 100644 --- a/x-pack/plugins/apm/public/components/app/service_map/popover/service_contents.tsx +++ b/x-pack/plugins/apm/public/components/app/service_map/popover/service_contents.tsx @@ -22,7 +22,7 @@ import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher'; import { AnomalyDetection } from './anomaly_detection'; import { StatsList } from './stats_list'; import { useTimeRange } from '../../../../hooks/use_time_range'; -import { getTimeRangeComparison } from '../../../shared/time_comparison/get_time_range_comparison'; +import { useComparison } from '../../../../hooks/use_comparison'; import { APIReturnType } from '../../../../services/rest/create_call_apm_api'; type ServiceNodeReturn = @@ -51,16 +51,11 @@ export function ServiceContents({ throw new Error('Expected rangeFrom and rangeTo to be set'); } - const { rangeFrom, rangeTo, comparisonEnabled, comparisonType } = query; + const { rangeFrom, rangeTo, comparisonEnabled } = query; const { start, end } = useTimeRange({ rangeFrom, rangeTo }); - const { offset } = getTimeRangeComparison({ - start, - end, - comparisonEnabled, - comparisonType, - }); + const { offset } = useComparison(); const serviceName = nodeData.id!; diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_dependencies_table/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_dependencies_table/index.tsx index d9c1a0220d1510a..29801da262fc721 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_dependencies_table/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_dependencies_table/index.tsx @@ -11,14 +11,13 @@ import React, { ReactNode } from 'react'; import { useUiTracker } from '../../../../../../observability/public'; import { getNodeName, NodeType } from '../../../../../common/connections'; import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context'; -import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params'; import { useApmParams } from '../../../../hooks/use_apm_params'; import { useFetcher } from '../../../../hooks/use_fetcher'; import { useTimeRange } from '../../../../hooks/use_time_range'; import { BackendLink } from '../../../shared/backend_link'; import { DependenciesTable } from '../../../shared/dependencies_table'; import { ServiceLink } from '../../../shared/service_link'; -import { getTimeRangeComparison } from '../../../shared/time_comparison/get_time_range_comparison'; +import { useComparison } from '../../../../hooks/use_comparison'; interface ServiceOverviewDependenciesTableProps { fixedHeight?: boolean; @@ -34,21 +33,20 @@ export function ServiceOverviewDependenciesTable({ hidePerPageOptions = false, }: ServiceOverviewDependenciesTableProps) { const { - urlParams: { comparisonEnabled, comparisonType, latencyAggregationType }, - } = useLegacyUrlParams(); - - const { - query: { environment, kuery, rangeFrom, rangeTo }, + query: { + environment, + kuery, + rangeFrom, + rangeTo, + comparisonEnabled, + comparisonType, + latencyAggregationType, + }, } = useApmParams('/services/{serviceName}/*'); const { start, end } = useTimeRange({ rangeFrom, rangeTo }); - const { offset } = getTimeRangeComparison({ - start, - end, - comparisonEnabled, - comparisonType, - }); + const { offset } = useComparison(); const { serviceName, transactionType } = useApmServiceContext(); diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx index 8eb5158f304c5bf..d39c32aa25e9d18 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx @@ -16,9 +16,9 @@ import { orderBy } from 'lodash'; import React, { useState } from 'react'; import uuid from 'uuid'; import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher'; +import { useComparison } from '../../../../hooks/use_comparison'; import { APIReturnType } from '../../../../services/rest/create_call_apm_api'; import { ErrorOverviewLink } from '../../../shared/links/apm/error_overview_link'; -import { getTimeRangeComparison } from '../../../shared/time_comparison/get_time_range_comparison'; import { OverviewTableContainer } from '../../../shared/overview_table_container'; import { getColumns } from './get_columns'; import { useApmParams } from '../../../../hooks/use_apm_params'; @@ -81,12 +81,7 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) { const { start, end } = useTimeRange({ rangeFrom, rangeTo }); - const { comparisonStart, comparisonEnd } = getTimeRangeComparison({ - start, - end, - comparisonType, - comparisonEnabled, - }); + const { comparisonStart, comparisonEnd } = useComparison(); const { pageIndex, sort } = tableOptions; const { direction, field } = sort; diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_chart_and_table.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_chart_and_table.tsx index 5e0aa95340e81bd..338c6ce8a4fc4ee 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_chart_and_table.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_chart_and_table.tsx @@ -10,17 +10,17 @@ import { orderBy } from 'lodash'; import React, { useState } from 'react'; import uuid from 'uuid'; import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context'; -import { useLegacyUrlParams } from '../../../context/url_params_context/use_url_params'; import { useApmParams } from '../../../hooks/use_apm_params'; +import { useComparison } from '../../../hooks/use_comparison'; import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher'; import { useTimeRange } from '../../../hooks/use_time_range'; import { APIReturnType } from '../../../services/rest/create_call_apm_api'; import { InstancesLatencyDistributionChart } from '../../shared/charts/instances_latency_distribution_chart'; -import { getTimeRangeComparison } from '../../shared/time_comparison/get_time_range_comparison'; import { ServiceOverviewInstancesTable, TableOptions, } from './service_overview_instances_table'; +import { LatencyAggregationType } from '../../../../common/latency_aggregation_types'; interface ServiceOverviewInstancesChartAndTableProps { chartHeight: number; @@ -73,21 +73,20 @@ export function ServiceOverviewInstancesChartAndTable({ const { direction, field } = sort; const { - query: { environment, kuery, rangeFrom, rangeTo }, + query: { + environment, + kuery, + rangeFrom, + rangeTo, + comparisonEnabled, + comparisonType, + latencyAggregationType, + }, } = useApmParams('/services/{serviceName}/overview'); - const { - urlParams: { latencyAggregationType, comparisonType, comparisonEnabled }, - } = useLegacyUrlParams(); - const { start, end } = useTimeRange({ rangeFrom, rangeTo }); - const { comparisonStart, comparisonEnd } = getTimeRangeComparison({ - start, - end, - comparisonType, - comparisonEnabled, - }); + const { comparisonStart, comparisonEnd } = useComparison(); const { data: mainStatsData = INITIAL_STATE_MAIN_STATS, @@ -108,7 +107,8 @@ export function ServiceOverviewInstancesChartAndTable({ query: { environment, kuery, - latencyAggregationType, + latencyAggregationType: + latencyAggregationType as LatencyAggregationType, start, end, transactionType, @@ -190,7 +190,8 @@ export function ServiceOverviewInstancesChartAndTable({ query: { environment, kuery, - latencyAggregationType, + latencyAggregationType: + latencyAggregationType as LatencyAggregationType, start, end, numBuckets: 20, diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/index.tsx index c41ad329ea86391..03f036e44b4c135 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_instances_table/index.tsx @@ -14,7 +14,6 @@ import { import { i18n } from '@kbn/i18n'; import React, { ReactNode, useEffect, useState } from 'react'; import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context'; -import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params'; import { FETCH_STATUS } from '../../../../hooks/use_fetcher'; import { APIReturnType } from '../../../../services/rest/create_call_apm_api'; import { @@ -27,6 +26,7 @@ import { getColumns } from './get_columns'; import { InstanceDetails } from './intance_details'; import { useApmParams } from '../../../../hooks/use_apm_params'; import { useBreakpoints } from '../../../../hooks/use_breakpoints'; +import { LatencyAggregationType } from '../../../../../common/latency_aggregation_types'; type ServiceInstanceMainStatistics = APIReturnType<'GET /internal/apm/services/{serviceName}/service_overview_instances/main_statistics'>; @@ -71,13 +71,9 @@ export function ServiceOverviewInstancesTable({ const { agentName } = useApmServiceContext(); const { - query: { kuery }, + query: { kuery, latencyAggregationType, comparisonEnabled }, } = useApmParams('/services/{serviceName}'); - const { - urlParams: { latencyAggregationType, comparisonEnabled }, - } = useLegacyUrlParams(); - const [itemIdToOpenActionMenuRowMap, setItemIdToOpenActionMenuRowMap] = useState>({}); @@ -127,7 +123,7 @@ export function ServiceOverviewInstancesTable({ agentName, serviceName, kuery, - latencyAggregationType, + latencyAggregationType: latencyAggregationType as LatencyAggregationType, detailedStatsData, comparisonEnabled, toggleRowDetails, diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_throughput_chart.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_throughput_chart.tsx index dbbb925fe634be0..cae35f6137be220 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_throughput_chart.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_throughput_chart.tsx @@ -18,16 +18,12 @@ import { ApmMlDetectorType } from '../../../../common/anomaly_detection/apm_ml_d import { asExactTransactionRate } from '../../../../common/utils/formatters'; import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context'; import { useEnvironmentsContext } from '../../../context/environments_context/use_environments_context'; -import { useLegacyUrlParams } from '../../../context/url_params_context/use_url_params'; import { useApmParams } from '../../../hooks/use_apm_params'; import { useFetcher } from '../../../hooks/use_fetcher'; +import { useComparison } from '../../../hooks/use_comparison'; import { usePreferredServiceAnomalyTimeseries } from '../../../hooks/use_preferred_service_anomaly_timeseries'; import { useTimeRange } from '../../../hooks/use_time_range'; import { TimeseriesChart } from '../../shared/charts/timeseries_chart'; -import { - getComparisonChartTheme, - getTimeRangeComparison, -} from '../../shared/time_comparison/get_time_range_comparison'; import { ChartType, getTimeSeriesColor, @@ -48,11 +44,7 @@ export function ServiceOverviewThroughputChart({ transactionName?: string; }) { const { - urlParams: { comparisonEnabled, comparisonType }, - } = useLegacyUrlParams(); - - const { - query: { rangeFrom, rangeTo }, + query: { rangeFrom, rangeTo, comparisonEnabled }, } = useApmParams('/services/{serviceName}'); const { environment } = useEnvironmentsContext(); @@ -65,13 +57,8 @@ export function ServiceOverviewThroughputChart({ const { transactionType, serviceName } = useApmServiceContext(); - const comparisonChartTheme = getComparisonChartTheme(); - const { comparisonStart, comparisonEnd } = getTimeRangeComparison({ - start, - end, - comparisonType, - comparisonEnabled, - }); + const { comparisonStart, comparisonEnd, comparisonChartTheme } = + useComparison(); const { data = INITIAL_STATE, status } = useFetcher( (callApmApi) => { diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/index.tsx index 327664925d5b160..3f535ae164c511f 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/index.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/index.tsx @@ -30,7 +30,6 @@ export function TransactionDetails() { rangeTo, transactionType: transactionTypeFromUrl, comparisonEnabled, - comparisonType, } = query; const { start, end } = useTimeRange({ rangeFrom, rangeTo }); const apmRouter = useApmRouter(); @@ -74,7 +73,6 @@ export function TransactionDetails() { transactionName={transactionName} isServerlessContext={isServerless} comparisonEnabled={comparisonEnabled} - comparisonType={comparisonType} /> diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/maybe_view_trace_link.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/maybe_view_trace_link.tsx index dfc89f78e4b3b77..855f5c037fdd161 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/maybe_view_trace_link.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/maybe_view_trace_link.tsx @@ -9,11 +9,11 @@ import { EuiButton, EuiFlexItem, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; import { getNextEnvironmentUrlParam } from '../../../../../common/environment_filter_values'; -import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params'; import { Transaction as ITransaction } from '../../../../../typings/es_schemas/ui/transaction'; import { TransactionDetailLink } from '../../../shared/links/apm/transaction_detail_link'; import { IWaterfall } from './waterfall_container/waterfall/waterfall_helpers/waterfall_helpers'; import { Environment } from '../../../../../common/environment_rt'; +import { useApmParams } from '../../../../hooks/use_apm_params'; export function MaybeViewTraceLink({ transaction, @@ -25,8 +25,8 @@ export function MaybeViewTraceLink({ environment: Environment; }) { const { - urlParams: { latencyAggregationType, comparisonEnabled, comparisonType }, - } = useLegacyUrlParams(); + query: { latencyAggregationType, comparisonEnabled, comparisonType }, + } = useApmParams('/services/{serviceName}/transactions/view'); const viewFullTraceButtonLabel = i18n.translate( 'xpack.apm.transactionDetails.viewFullTraceButtonLabel', diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/flyout_top_level_properties.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/flyout_top_level_properties.tsx index 20e278000266a9c..ead54b3e9d6d911 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/flyout_top_level_properties.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/waterfall_container/waterfall/flyout_top_level_properties.tsx @@ -13,7 +13,6 @@ import { } from '../../../../../../../common/elasticsearch_fieldnames'; import { getNextEnvironmentUrlParam } from '../../../../../../../common/environment_filter_values'; import { Transaction } from '../../../../../../../typings/es_schemas/ui/transaction'; -import { useLegacyUrlParams } from '../../../../../../context/url_params_context/use_url_params'; import { useApmParams } from '../../../../../../hooks/use_apm_params'; import { TransactionDetailLink } from '../../../../../shared/links/apm/transaction_detail_link'; import { ServiceLink } from '../../../../../shared/service_link'; @@ -24,11 +23,10 @@ interface Props { } export function FlyoutTopLevelProperties({ transaction }: Props) { - const { - urlParams: { latencyAggregationType, comparisonEnabled, comparisonType }, - } = useLegacyUrlParams(); const { query } = useApmParams('/services/{serviceName}/transactions/view'); + const { latencyAggregationType, comparisonEnabled, comparisonType } = query; + if (!transaction) { return null; } diff --git a/x-pack/plugins/apm/public/components/app/transaction_overview/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_overview/index.tsx index 68315fc3b2b021e..c97f395975c7bd3 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_overview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_overview/index.tsx @@ -26,7 +26,6 @@ export function TransactionOverview() { rangeTo, transactionType: transactionTypeFromUrl, comparisonEnabled, - comparisonType, }, } = useApmParams('/services/{serviceName}/transactions'); @@ -69,7 +68,6 @@ export function TransactionOverview() { end={end} isServerlessContext={isServerless} comparisonEnabled={comparisonEnabled} - comparisonType={comparisonType} /> diff --git a/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx b/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx index 6514c8288be0ec4..8f3320586bf51fe 100644 --- a/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx @@ -28,6 +28,7 @@ import { ServiceProfiling } from '../../app/service_profiling'; import { ServiceDependencies } from '../../app/service_dependencies'; import { ServiceLogs } from '../../app/service_logs'; import { InfraOverview } from '../../app/infra_overview'; +import { LatencyAggregationType } from '../../../../common/latency_aggregation_types'; function page({ title, @@ -92,6 +93,7 @@ export const serviceDetail = { query: { kuery: '', environment: ENVIRONMENT_ALL.value, + latencyAggregationType: LatencyAggregationType.avg, }, }, children: { diff --git a/x-pack/plugins/apm/public/components/shared/charts/failed_transaction_rate_chart/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/failed_transaction_rate_chart/index.tsx index 2efbae85d91c26b..53b8bae57c146e1 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/failed_transaction_rate_chart/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/failed_transaction_rate_chart/index.tsx @@ -16,12 +16,9 @@ import { useFetcher } from '../../../../hooks/use_fetcher'; import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params'; import { TimeseriesChart } from '../timeseries_chart'; import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context'; -import { - getComparisonChartTheme, - getTimeRangeComparison, -} from '../../time_comparison/get_time_range_comparison'; import { useApmParams } from '../../../../hooks/use_apm_params'; import { useTimeRange } from '../../../../hooks/use_time_range'; +import { useComparison } from '../../../../hooks/use_comparison'; import { useEnvironmentsContext } from '../../../../context/environments_context/use_environments_context'; import { ApmMlDetectorType } from '../../../../../common/anomaly_detection/apm_ml_detectors'; import { usePreferredServiceAnomalyTimeseries } from '../../../../hooks/use_preferred_service_anomaly_timeseries'; @@ -57,11 +54,11 @@ export function FailedTransactionRateChart({ kuery, }: Props) { const { - urlParams: { transactionName, comparisonEnabled, comparisonType }, + urlParams: { transactionName }, } = useLegacyUrlParams(); const { - query: { rangeFrom, rangeTo }, + query: { rangeFrom, rangeTo, comparisonEnabled }, } = useApmParams('/services/{serviceName}'); const { start, end } = useTimeRange({ rangeFrom, rangeTo }); @@ -74,13 +71,8 @@ export function FailedTransactionRateChart({ const { serviceName, transactionType, alerts } = useApmServiceContext(); - const comparisonChartThem = getComparisonChartTheme(); - const { comparisonStart, comparisonEnd } = getTimeRangeComparison({ - start, - end, - comparisonType, - comparisonEnabled, - }); + const { comparisonChartTheme, comparisonStart, comparisonEnd } = + useComparison(); const { data = INITIAL_STATE, status } = useFetcher( (callApmApi) => { @@ -165,7 +157,7 @@ export function FailedTransactionRateChart({ timeseries={timeseries} yLabelFormat={yLabelFormat} yDomain={{ min: 0, max: 1 }} - customTheme={comparisonChartThem} + customTheme={comparisonChartTheme} anomalyTimeseries={preferredAnomalyTimeseries} alerts={alerts.filter( (alert) => diff --git a/x-pack/plugins/apm/public/components/shared/charts/latency_chart/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/latency_chart/index.tsx index 6991a7aa7e200c4..880879119be9866 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/latency_chart/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/latency_chart/index.tsx @@ -15,7 +15,6 @@ import { useApmServiceContext } from '../../../../context/apm_service/use_apm_se import { LatencyAggregationType } from '../../../../../common/latency_aggregation_types'; import { getDurationFormatter } from '../../../../../common/utils/formatters'; import { useLicenseContext } from '../../../../context/license/use_license_context'; -import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params'; import { useTransactionLatencyChartsFetcher } from '../../../../hooks/use_transaction_latency_chart_fetcher'; import { TimeseriesChart } from '../../../shared/charts/timeseries_chart'; import { @@ -28,6 +27,7 @@ import { getComparisonChartTheme } from '../../time_comparison/get_time_range_co import { useEnvironmentsContext } from '../../../../context/environments_context/use_environments_context'; import { ApmMlDetectorType } from '../../../../../common/anomaly_detection/apm_ml_detectors'; import { usePreferredServiceAnomalyTimeseries } from '../../../../hooks/use_preferred_service_anomaly_timeseries'; +import { useAnyOfApmParams } from '../../../../hooks/use_apm_params'; interface Props { height?: number; @@ -48,10 +48,16 @@ export function LatencyChart({ height, kuery }: Props) { const history = useHistory(); const comparisonChartTheme = getComparisonChartTheme(); - const { urlParams } = useLegacyUrlParams(); - const { latencyAggregationType, comparisonEnabled } = urlParams; const license = useLicenseContext(); + const { + query: { comparisonEnabled, latencyAggregationType }, + } = useAnyOfApmParams( + '/services/{serviceName}/overview', + '/services/{serviceName}/transactions', + '/services/{serviceName}/transactions/view' + ); + const { environment } = useEnvironmentsContext(); const { latencyChartsData, latencyChartsStatus } = diff --git a/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/index.tsx index a2bfad0175a5f98..fe4e95de4571c14 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/transaction_charts/index.tsx @@ -14,7 +14,6 @@ import { LatencyChart } from '../latency_chart'; import { TransactionBreakdownChart } from '../transaction_breakdown_chart'; import { TransactionColdstartRateChart } from '../transaction_coldstart_rate_chart'; import { FailedTransactionRateChart } from '../failed_transaction_rate_chart'; -import { TimeRangeComparisonType } from '../../../../../common/runtime_types/comparison_type_rt'; export function TransactionCharts({ kuery, @@ -24,7 +23,6 @@ export function TransactionCharts({ transactionName, isServerlessContext, comparisonEnabled, - comparisonType, }: { kuery: string; environment: string; @@ -33,7 +31,6 @@ export function TransactionCharts({ transactionName?: string; isServerlessContext?: boolean; comparisonEnabled?: boolean; - comparisonType?: TimeRangeComparisonType; }) { return ( <> @@ -71,7 +68,6 @@ export function TransactionCharts({ transactionName={transactionName} environment={environment} comparisonEnabled={comparisonEnabled} - comparisonType={comparisonType} /> ) : ( diff --git a/x-pack/plugins/apm/public/components/shared/charts/transaction_coldstart_rate_chart/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/transaction_coldstart_rate_chart/index.tsx index 2b99562b67172ff..557d645083302a2 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/transaction_coldstart_rate_chart/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/transaction_coldstart_rate_chart/index.tsx @@ -20,13 +20,9 @@ import { useFetcher } from '../../../../hooks/use_fetcher'; import { useTheme } from '../../../../hooks/use_theme'; import { TimeseriesChart } from '../timeseries_chart'; import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context'; -import { - getComparisonChartTheme, - getTimeRangeComparison, -} from '../../time_comparison/get_time_range_comparison'; import { useApmParams } from '../../../../hooks/use_apm_params'; import { useTimeRange } from '../../../../hooks/use_time_range'; -import { TimeRangeComparisonType } from '../../../../../common/runtime_types/comparison_type_rt'; +import { useComparison } from '../../../../hooks/use_comparison'; function yLabelFormat(y?: number | null) { return asPercent(y || 0, 1); @@ -39,7 +35,6 @@ interface Props { environment: string; transactionName?: string; comparisonEnabled?: boolean; - comparisonType?: TimeRangeComparisonType; } type ColdstartRate = @@ -63,7 +58,6 @@ export function TransactionColdstartRateChart({ kuery, transactionName, comparisonEnabled, - comparisonType, }: Props) { const theme = useTheme(); @@ -74,13 +68,8 @@ export function TransactionColdstartRateChart({ const { start, end } = useTimeRange({ rangeFrom, rangeTo }); const { serviceName, transactionType } = useApmServiceContext(); - const comparisonChartThem = getComparisonChartTheme(); - const { comparisonStart, comparisonEnd } = getTimeRangeComparison({ - start, - end, - comparisonType, - comparisonEnabled, - }); + const { comparisonChartTheme, comparisonStart, comparisonEnd } = + useComparison(); const endpoint = transactionName ? ('GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate_by_transaction_name' as const) @@ -177,7 +166,7 @@ export function TransactionColdstartRateChart({ timeseries={timeseries} yLabelFormat={yLabelFormat} yDomain={{ min: 0, max: 1 }} - customTheme={comparisonChartThem} + customTheme={comparisonChartTheme} /> ); diff --git a/x-pack/plugins/apm/public/components/shared/time_comparison/comparison.test.ts b/x-pack/plugins/apm/public/components/shared/time_comparison/comparison.test.ts new file mode 100644 index 000000000000000..72aeb544abac001 --- /dev/null +++ b/x-pack/plugins/apm/public/components/shared/time_comparison/comparison.test.ts @@ -0,0 +1,434 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { TimeRangeComparisonEnum } from '../../../../common/runtime_types/comparison_type_rt'; +import { getTimeRangeComparison } from './get_time_range_comparison'; +import { getDateRange } from '../../../context/url_params_context/helpers'; +import { getComparisonOptions } from './get_comparison_options'; + +function getExpectedTimesAndComparisons({ + rangeFrom, + rangeTo, +}: { + rangeFrom: string; + rangeTo: string; +}) { + const { start, end } = getDateRange({ rangeFrom, rangeTo }); + const comparisonOptions = getComparisonOptions({ start, end }); + + const comparisons = comparisonOptions.map(({ value, text }) => { + const { comparisonStart, comparisonEnd } = getTimeRangeComparison({ + comparisonEnabled: true, + comparisonType: value, + start, + end, + }); + + return { + value, + text, + comparisonStart, + comparisonEnd, + }; + }); + + return { + start, + end, + comparisons, + }; +} + +describe('Comparison test suite', () => { + let dateNowSpy: jest.SpyInstance; + + beforeAll(() => { + const mockDateNow = '2022-01-14T18:30:15.500Z'; + dateNowSpy = jest + .spyOn(Date, 'now') + .mockReturnValue(new Date(mockDateNow).getTime()); + }); + + afterAll(() => { + dateNowSpy.mockRestore(); + }); + + describe('When the time difference is less than 25 hours', () => { + let expectation: ReturnType; + + beforeAll(() => { + expectation = getExpectedTimesAndComparisons({ + rangeFrom: '2022-01-15T18:00:00.000Z', + rangeTo: '2022-01-16T18:30:00.000Z', + }); + }); + + it('should return the correct start and end date', () => { + expect(expectation.start).toBe('2022-01-15T18:00:00.000Z'); + expect(expectation.end).toBe('2022-01-16T18:30:00.000Z'); + }); + + it('should return comparison by day and week', () => { + expect(expectation.comparisons).toEqual([ + { + value: TimeRangeComparisonEnum.DayBefore, + text: 'Day before', + comparisonStart: '2022-01-14T18:00:00.000Z', + comparisonEnd: '2022-01-15T18:30:00.000Z', + }, + { + value: TimeRangeComparisonEnum.WeekBefore, + text: 'Week before', + comparisonStart: '2022-01-08T18:00:00.000Z', + comparisonEnd: '2022-01-09T18:30:00.000Z', + }, + ]); + }); + }); + + describe('When the time difference is more than 25 hours', () => { + let expectation: ReturnType; + + beforeAll(() => { + expectation = getExpectedTimesAndComparisons({ + rangeFrom: '2022-01-15T18:00:00.000Z', + rangeTo: '2022-01-16T19:00:00.000Z', + }); + }); + + it('should return the correct start and end date', () => { + expect(expectation.start).toBe('2022-01-15T18:00:00.000Z'); + expect(expectation.end).toBe('2022-01-16T19:00:00.000Z'); + }); + + it('should only return comparison by week', () => { + expect(expectation.comparisons).toEqual([ + { + value: TimeRangeComparisonEnum.WeekBefore, + text: 'Week before', + comparisonStart: '2022-01-08T18:00:00.000Z', + comparisonEnd: '2022-01-09T19:00:00.000Z', + }, + ]); + }); + }); + + describe('When the time difference is more than 25 hours and less than 8 days', () => { + let expectation: ReturnType; + + beforeAll(() => { + expectation = getExpectedTimesAndComparisons({ + rangeFrom: '2022-01-15T18:00:00.000Z', + rangeTo: '2022-01-22T21:00:00.000Z', + }); + }); + + it('should return the correct start and end date', () => { + expect(expectation.start).toBe('2022-01-15T18:00:00.000Z'); + expect(expectation.end).toBe('2022-01-22T21:00:00.000Z'); + }); + + it('should only return comparison by week', () => { + expect(expectation.comparisons).toEqual([ + { + value: TimeRangeComparisonEnum.WeekBefore, + text: 'Week before', + comparisonStart: '2022-01-08T18:00:00.000Z', + comparisonEnd: '2022-01-15T21:00:00.000Z', + }, + ]); + }); + }); + + describe('When the time difference is 8 days', () => { + let expectation: ReturnType; + + beforeAll(() => { + expectation = getExpectedTimesAndComparisons({ + rangeFrom: '2022-01-15T18:00:00.000Z', + rangeTo: '2022-01-23T18:00:00.000Z', + }); + }); + + it('should return the correct start and end date', () => { + expect(expectation.start).toBe('2022-01-15T18:00:00.000Z'); + expect(expectation.end).toBe('2022-01-23T18:00:00.000Z'); + }); + + it('should only return comparison by period and format text as DD/MM HH:mm when range years are the same', () => { + expect(expectation.comparisons).toEqual([ + { + value: TimeRangeComparisonEnum.PeriodBefore, + text: '07/01 18:00 - 15/01 18:00', + comparisonStart: '2022-01-07T18:00:00.000Z', + comparisonEnd: '2022-01-15T18:00:00.000Z', + }, + ]); + }); + }); + + describe('When the time difference is more than 8 days', () => { + let expectation: ReturnType; + + beforeAll(() => { + expectation = getExpectedTimesAndComparisons({ + rangeFrom: '2022-01-15T18:00:00.000Z||/d', + rangeTo: '2022-01-23T18:00:00.000Z', + }); + }); + + it('should return the correct start and end date', () => { + expect(expectation.start).toBe('2022-01-15T00:00:00.000Z'); + expect(expectation.end).toBe('2022-01-23T18:00:00.000Z'); + }); + + it('should only return comparison by period and format text as DD/MM HH:mm when range years are the same', () => { + expect(expectation.comparisons).toEqual([ + { + value: TimeRangeComparisonEnum.PeriodBefore, + text: '06/01 06:00 - 15/01 00:00', + comparisonStart: '2022-01-06T06:00:00.000Z', + comparisonEnd: '2022-01-15T00:00:00.000Z', + }, + ]); + }); + }); + + describe('When "Today" is selected', () => { + let expectation: ReturnType; + + beforeAll(() => { + expectation = getExpectedTimesAndComparisons({ + rangeFrom: 'now/d', + rangeTo: 'now/d', + }); + }); + + it('should return the correct start and end date', () => { + expect(expectation.start).toBe('2022-01-14T00:00:00.000Z'); + expect(expectation.end).toBe('2022-01-14T23:59:59.999Z'); + }); + + it('should return comparison by day and week', () => { + expect(expectation.comparisons).toEqual([ + { + value: TimeRangeComparisonEnum.DayBefore, + text: 'Day before', + comparisonStart: '2022-01-13T00:00:00.000Z', + comparisonEnd: '2022-01-13T23:59:59.999Z', + }, + { + value: TimeRangeComparisonEnum.WeekBefore, + text: 'Week before', + comparisonStart: '2022-01-07T00:00:00.000Z', + comparisonEnd: '2022-01-07T23:59:59.999Z', + }, + ]); + }); + }); + + describe('When "This week" is selected', () => { + let expectation: ReturnType; + + beforeAll(() => { + expectation = getExpectedTimesAndComparisons({ + rangeFrom: 'now/w', + rangeTo: 'now/w', + }); + }); + + it('should return the correct start and end date', () => { + expect(expectation.start).toBe('2022-01-09T00:00:00.000Z'); + expect(expectation.end).toBe('2022-01-15T23:59:59.999Z'); + }); + + it('should only return comparison by week', () => { + expect(expectation.comparisons).toEqual([ + { + value: TimeRangeComparisonEnum.WeekBefore, + text: 'Week before', + comparisonStart: '2022-01-02T00:00:00.000Z', + comparisonEnd: '2022-01-08T23:59:59.999Z', + }, + ]); + }); + }); + + describe('When "Last 24 hours" is selected with no rounding', () => { + let expectation: ReturnType; + + beforeAll(() => { + expectation = getExpectedTimesAndComparisons({ + rangeFrom: 'now-24h', + rangeTo: 'now', + }); + }); + + it('should return the correct start and end date', () => { + expect(expectation.start).toBe('2022-01-13T18:30:15.500Z'); + expect(expectation.end).toBe('2022-01-14T18:30:15.500Z'); + }); + + it('should return comparison by day and week', () => { + expect(expectation.comparisons).toEqual([ + { + value: TimeRangeComparisonEnum.DayBefore, + text: 'Day before', + comparisonStart: '2022-01-12T18:30:15.500Z', + comparisonEnd: '2022-01-13T18:30:15.500Z', + }, + { + value: TimeRangeComparisonEnum.WeekBefore, + text: 'Week before', + comparisonStart: '2022-01-06T18:30:15.500Z', + comparisonEnd: '2022-01-07T18:30:15.500Z', + }, + ]); + }); + }); + + describe('When "Last 24 hours" is selected with rounding', () => { + let expectation: ReturnType; + + beforeAll(() => { + expectation = getExpectedTimesAndComparisons({ + rangeFrom: 'now-24h/h', + rangeTo: 'now', + }); + }); + + it('should return the correct start and end date', () => { + expect(expectation.start).toBe('2022-01-13T18:00:00.000Z'); + expect(expectation.end).toBe('2022-01-14T18:30:15.500Z'); + }); + + it('should return comparison by day and week', () => { + expect(expectation.comparisons).toEqual([ + { + value: TimeRangeComparisonEnum.DayBefore, + text: 'Day before', + comparisonStart: '2022-01-12T18:00:00.000Z', + comparisonEnd: '2022-01-13T18:30:15.500Z', + }, + { + value: TimeRangeComparisonEnum.WeekBefore, + text: 'Week before', + comparisonStart: '2022-01-06T18:00:00.000Z', + comparisonEnd: '2022-01-07T18:30:15.500Z', + }, + ]); + }); + }); + + describe('When "Last 7 days" is selected with no rounding', () => { + let expectation: ReturnType; + + beforeAll(() => { + expectation = getExpectedTimesAndComparisons({ + rangeFrom: 'now-7d', + rangeTo: 'now', + }); + }); + + it('should return the correct start and end date', () => { + expect(expectation.start).toBe('2022-01-07T18:30:15.500Z'); + expect(expectation.end).toBe('2022-01-14T18:30:15.500Z'); + }); + + it('should only return comparison by week', () => { + expect(expectation.comparisons).toEqual([ + { + value: TimeRangeComparisonEnum.WeekBefore, + text: 'Week before', + comparisonStart: '2021-12-31T18:30:15.500Z', + comparisonEnd: '2022-01-07T18:30:15.500Z', + }, + ]); + }); + }); + + describe('When "Last 7 days" is selected with rounding', () => { + let expectation: ReturnType; + + beforeAll(() => { + expectation = getExpectedTimesAndComparisons({ + rangeFrom: 'now-7d/d', + rangeTo: 'now', + }); + }); + + it('should return the correct start and end date', () => { + expect(expectation.start).toBe('2022-01-07T00:00:00.000Z'); + expect(expectation.end).toBe('2022-01-14T18:30:15.500Z'); + }); + + it('should only return comparison by week', () => { + expect(expectation.comparisons).toEqual([ + { + value: TimeRangeComparisonEnum.WeekBefore, + text: 'Week before', + comparisonStart: '2021-12-31T00:00:00.000Z', + comparisonEnd: '2022-01-07T18:30:15.500Z', + }, + ]); + }); + }); + + describe('When "Last 30 days" is selected with no rounding', () => { + let expectation: ReturnType; + + beforeAll(() => { + expectation = getExpectedTimesAndComparisons({ + rangeFrom: 'now-30d', + rangeTo: 'now', + }); + }); + + it('should return the correct start and end date', () => { + expect(expectation.start).toBe('2021-12-15T18:30:15.500Z'); + expect(expectation.end).toBe('2022-01-14T18:30:15.500Z'); + }); + + it('should only return comparison by period and format text as DD/MM/YY HH:mm when range years are different', () => { + expect(expectation.comparisons).toEqual([ + { + value: TimeRangeComparisonEnum.PeriodBefore, + text: '15/11/21 18:30 - 15/12/21 18:30', + comparisonStart: '2021-11-15T18:30:15.500Z', + comparisonEnd: '2021-12-15T18:30:15.500Z', + }, + ]); + }); + }); + + describe('When "Last 30 days" is selected with rounding', () => { + let expectation: ReturnType; + + beforeAll(() => { + expectation = getExpectedTimesAndComparisons({ + rangeFrom: 'now-30d/d', + rangeTo: 'now', + }); + }); + + it('should return the correct start and end date', () => { + expect(expectation.start).toBe('2021-12-15T00:00:00.000Z'); + expect(expectation.end).toBe('2022-01-14T18:30:15.500Z'); + }); + + it('should only return comparison by period and format text as DD/MM/YY HH:mm when range years are different', () => { + expect(expectation.comparisons).toEqual([ + { + value: TimeRangeComparisonEnum.PeriodBefore, + text: '14/11/21 05:29 - 15/12/21 00:00', + comparisonStart: '2021-11-14T05:29:44.500Z', + comparisonEnd: '2021-12-15T00:00:00.000Z', + }, + ]); + }); + }); +}); diff --git a/x-pack/plugins/apm/public/components/shared/time_comparison/get_comparison_options.ts b/x-pack/plugins/apm/public/components/shared/time_comparison/get_comparison_options.ts new file mode 100644 index 000000000000000..9400f668a18f0f3 --- /dev/null +++ b/x-pack/plugins/apm/public/components/shared/time_comparison/get_comparison_options.ts @@ -0,0 +1,126 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import moment from 'moment'; +import { i18n } from '@kbn/i18n'; +import { TimeRangeComparisonEnum } from '../../../../common/runtime_types/comparison_type_rt'; +import { getTimeRangeComparison } from './get_time_range_comparison'; + +const eightDaysInHours = moment.duration(8, 'd').asHours(); + +function getDateFormat({ + previousPeriodStart, + currentPeriodEnd, +}: { + previousPeriodStart?: string; + currentPeriodEnd?: string; +}) { + const momentPreviousPeriodStart = moment(previousPeriodStart); + const momentCurrentPeriodEnd = moment(currentPeriodEnd); + const isDifferentYears = + momentPreviousPeriodStart.get('year') !== + momentCurrentPeriodEnd.get('year'); + return isDifferentYears ? 'DD/MM/YY HH:mm' : 'DD/MM HH:mm'; +} + +function formatDate({ + dateFormat, + previousPeriodStart, + previousPeriodEnd, +}: { + dateFormat: string; + previousPeriodStart?: string; + previousPeriodEnd?: string; +}) { + const momentStart = moment(previousPeriodStart); + const momentEnd = moment(previousPeriodEnd); + return `${momentStart.format(dateFormat)} - ${momentEnd.format(dateFormat)}`; +} + +function getSelectOptions({ + comparisonTypes, + start, + end, +}: { + comparisonTypes: TimeRangeComparisonEnum[]; + start?: string; + end?: string; +}) { + return comparisonTypes.map((value) => { + switch (value) { + case TimeRangeComparisonEnum.DayBefore: { + return { + value, + text: i18n.translate('xpack.apm.timeComparison.select.dayBefore', { + defaultMessage: 'Day before', + }), + }; + } + case TimeRangeComparisonEnum.WeekBefore: { + return { + value, + text: i18n.translate('xpack.apm.timeComparison.select.weekBefore', { + defaultMessage: 'Week before', + }), + }; + } + case TimeRangeComparisonEnum.PeriodBefore: { + const { comparisonStart, comparisonEnd } = getTimeRangeComparison({ + comparisonType: TimeRangeComparisonEnum.PeriodBefore, + start, + end, + comparisonEnabled: true, + }); + + const dateFormat = getDateFormat({ + previousPeriodStart: comparisonStart, + currentPeriodEnd: end, + }); + + return { + value, + text: formatDate({ + dateFormat, + previousPeriodStart: comparisonStart, + previousPeriodEnd: comparisonEnd, + }), + }; + } + } + }); +} + +export function getComparisonOptions({ + start, + end, +}: { + start?: string; + end?: string; +}) { + const momentStart = moment(start); + const momentEnd = moment(end); + const hourDiff = momentEnd.diff(momentStart, 'h', true); + + let comparisonTypes: TimeRangeComparisonEnum[]; + + if (hourDiff < 25) { + // Less than 25 hours. This is because relative times may be rounded when + // asking for a day, which can result in a duration > 24h. (e.g. rangeFrom: 'now-24h/h, rangeTo: 'now') + comparisonTypes = [ + TimeRangeComparisonEnum.DayBefore, + TimeRangeComparisonEnum.WeekBefore, + ]; + } else if (hourDiff < eightDaysInHours) { + // Less than 8 days. This is because relative times may be rounded when + // asking for a week, which can result in a duration > 7d. (e.g. rangeFrom: 'now-7d/d, rangeTo: 'now') + comparisonTypes = [TimeRangeComparisonEnum.WeekBefore]; + } else { + comparisonTypes = [TimeRangeComparisonEnum.PeriodBefore]; + } + + return getSelectOptions({ comparisonTypes, start, end }); +} diff --git a/x-pack/plugins/apm/public/components/shared/time_comparison/get_comparison_types.ts b/x-pack/plugins/apm/public/components/shared/time_comparison/get_comparison_types.ts deleted file mode 100644 index 97754cd91fd3e54..000000000000000 --- a/x-pack/plugins/apm/public/components/shared/time_comparison/get_comparison_types.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import moment from 'moment'; -import { TimeRangeComparisonEnum } from '../../../../common/runtime_types/comparison_type_rt'; -import { getDateDifference } from '../../../../common/utils/formatters'; - -export function getComparisonTypes({ - start, - end, -}: { - start?: string; - end?: string; -}) { - const momentStart = moment(start).startOf('second'); - const momentEnd = moment(end).startOf('second'); - - const dateDiff = getDateDifference({ - start: momentStart, - end: momentEnd, - precise: true, - unitOfTime: 'days', - }); - - // Less than or equals to one day - if (dateDiff <= 1) { - return [ - TimeRangeComparisonEnum.DayBefore, - TimeRangeComparisonEnum.WeekBefore, - ]; - } - - // Less than or equals to one week - if (dateDiff <= 7) { - return [TimeRangeComparisonEnum.WeekBefore]; - } - // } - - // above one week or when rangeTo is not "now" - return [TimeRangeComparisonEnum.PeriodBefore]; -} diff --git a/x-pack/plugins/apm/public/components/shared/time_comparison/get_time_range_comparison.ts b/x-pack/plugins/apm/public/components/shared/time_comparison/get_time_range_comparison.ts index 92611d88aa0cc39..6a1f7b1978ca0c0 100644 --- a/x-pack/plugins/apm/public/components/shared/time_comparison/get_time_range_comparison.ts +++ b/x-pack/plugins/apm/public/components/shared/time_comparison/get_time_range_comparison.ts @@ -11,7 +11,6 @@ import { TimeRangeComparisonType, TimeRangeComparisonEnum, } from '../../../../common/runtime_types/comparison_type_rt'; -import { getDateDifference } from '../../../../common/utils/formatters'; export function getComparisonChartTheme(): PartialTheme { return { @@ -48,13 +47,9 @@ export function getTimeRangeComparison({ if (!comparisonEnabled || !comparisonType || !start || !end) { return {}; } - const startMoment = moment(start); const endMoment = moment(end); - const startEpoch = startMoment.valueOf(); - const endEpoch = endMoment.valueOf(); - let diff: number; let offset: string; @@ -63,29 +58,21 @@ export function getTimeRangeComparison({ diff = oneDayInMilliseconds; offset = '1d'; break; - case TimeRangeComparisonEnum.WeekBefore: diff = oneWeekInMilliseconds; offset = '1w'; break; - case TimeRangeComparisonEnum.PeriodBefore: - diff = getDateDifference({ - start: startMoment, - end: endMoment, - unitOfTime: 'milliseconds', - precise: true, - }); + diff = endMoment.diff(startMoment); offset = `${diff}ms`; break; - default: throw new Error('Unknown comparisonType'); } return { - comparisonStart: new Date(startEpoch - diff).toISOString(), - comparisonEnd: new Date(endEpoch - diff).toISOString(), + comparisonStart: startMoment.subtract(diff, 'ms').toISOString(), + comparisonEnd: endMoment.subtract(diff, 'ms').toISOString(), offset, }; } 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 d811fbb5d03578f..83d2962316aa208 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 @@ -13,10 +13,9 @@ import { expectTextsInDocument, expectTextsNotInDocument, } from '../../../utils/test_helpers'; -import { getSelectOptions, TimeComparison } from './'; +import { TimeComparison } from './'; import * as urlHelpers from '../../shared/links/url_helpers'; import moment from 'moment'; -import { getComparisonTypes } from './get_comparison_types'; import { MockApmPluginContextWrapper } from '../../../context/apm_plugin/mock_apm_plugin_context'; import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values'; import { @@ -26,14 +25,14 @@ import { import { MockUrlParamsContextProvider } from '../../../context/url_params_context/mock_url_params_context_provider'; function getWrapper({ - exactStart, - exactEnd, + rangeFrom, + rangeTo, comparisonType, comparisonEnabled, environment = ENVIRONMENT_ALL.value, }: { - exactStart: string; - exactEnd: string; + rangeFrom: string; + rangeTo: string; comparisonType?: TimeRangeComparisonType; comparisonEnabled?: boolean; environment?: string; @@ -42,7 +41,7 @@ function getWrapper({ return ( { +describe('TimeComparison component', () => { beforeAll(() => { moment.tz.setDefault('Europe/Amsterdam'); }); afterAll(() => moment.tz.setDefault('')); - 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([ - TimeRangeComparisonEnum.DayBefore.valueOf(), - TimeRangeComparisonEnum.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([ - TimeRangeComparisonEnum.DayBefore.valueOf(), - TimeRangeComparisonEnum.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([ - TimeRangeComparisonEnum.DayBefore.valueOf(), - TimeRangeComparisonEnum.WeekBefore.valueOf(), - ]); - }); + const spy = jest.spyOn(urlHelpers, 'replace'); + beforeEach(() => { + jest.resetAllMocks(); + }); - it('shows week and day before when 24 hours is selected but milliseconds are different', () => { - expect( - getComparisonTypes({ - start: '2021-10-15T00:52:59.554Z', - end: '2021-10-14T00:52:59.553Z', - }) - ).toEqual([ - TimeRangeComparisonEnum.DayBefore.valueOf(), - TimeRangeComparisonEnum.WeekBefore.valueOf(), - ]); + describe('Time range is between 0 - 25 hours', () => { + it('sets default values', () => { + const Wrapper = getWrapper({ + rangeFrom: '2021-06-04T16:17:02.335Z', + rangeTo: '2021-06-04T16:32:02.335Z', + }); + render(, { wrapper: Wrapper }); + expect(spy).toHaveBeenCalledWith(expect.anything(), { + query: { + comparisonEnabled: 'true', + comparisonType: TimeRangeComparisonEnum.DayBefore, + }, + }); }); - it('shows week before when 25 hours is selected', () => { + it('selects day before and enables comparison', () => { + const Wrapper = getWrapper({ + rangeFrom: '2021-06-04T16:17:02.335Z', + rangeTo: '2021-06-04T16:32:02.335Z', + comparisonEnabled: true, + comparisonType: TimeRangeComparisonEnum.DayBefore, + }); + const component = render(, { wrapper: Wrapper }); + expectTextsInDocument(component, ['Day before', 'Week before']); expect( - getComparisonTypes({ - start: '2021-06-02T12:32:00.000Z', - end: '2021-06-03T13:32:09.079Z', - }) - ).toEqual([TimeRangeComparisonEnum.WeekBefore.valueOf()]); + (component.getByTestId('comparisonSelect') as HTMLSelectElement) + .selectedIndex + ).toEqual(0); }); - 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([TimeRangeComparisonEnum.WeekBefore.valueOf()]); - }); - it('shows period before when 8 days is selected', () => { + it('enables day before option when date difference is equal to 24 hours', () => { + const Wrapper = getWrapper({ + rangeFrom: '2021-06-03T16:31:35.748Z', + rangeTo: '2021-06-04T16:31:35.748Z', + comparisonEnabled: true, + comparisonType: TimeRangeComparisonEnum.DayBefore, + }); + const component = render(, { wrapper: Wrapper }); + expectTextsInDocument(component, ['Day before', 'Week before']); expect( - getComparisonTypes({ - start: '2021-05-27T16:32:46.747Z', - end: '2021-06-04T16:32:46.747Z', - }) - ).toEqual([TimeRangeComparisonEnum.PeriodBefore.valueOf()]); + (component.getByTestId('comparisonSelect') as HTMLSelectElement) + .selectedIndex + ).toEqual(0); }); }); - describe('getSelectOptions', () => { - it('returns formatted text based on comparison type', () => { - expect( - getSelectOptions({ - comparisonTypes: [ - TimeRangeComparisonEnum.DayBefore, - TimeRangeComparisonEnum.WeekBefore, - TimeRangeComparisonEnum.PeriodBefore, - ], - start: '2021-05-27T16:32:46.747Z', - end: '2021-06-04T16:32:46.747Z', - }) - ).toEqual([ - { - value: TimeRangeComparisonEnum.DayBefore.valueOf(), - text: 'Day before', - }, - { - value: TimeRangeComparisonEnum.WeekBefore.valueOf(), - text: 'Week before', - }, - { - value: TimeRangeComparisonEnum.PeriodBefore.valueOf(), - text: '19/05 18:32 - 27/05 18:32', - }, - ]); + describe('Time range is between 25 hours - 8 days', () => { + it("doesn't show day before option when date difference is greater than 25 hours", () => { + const Wrapper = getWrapper({ + rangeFrom: '2021-06-02T12:32:00.000Z', + rangeTo: '2021-06-03T13:32:09.079Z', + comparisonEnabled: true, + comparisonType: TimeRangeComparisonEnum.WeekBefore, + }); + 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( - getSelectOptions({ - comparisonTypes: [TimeRangeComparisonEnum.PeriodBefore], - start: '2020-05-27T16:32:46.747Z', - end: '2021-06-04T16:32:46.747Z', - }) - ).toEqual([ - { - value: TimeRangeComparisonEnum.PeriodBefore.valueOf(), - text: '20/05/19 18:32 - 27/05/20 18:32', + it('sets default values', () => { + const Wrapper = getWrapper({ + rangeFrom: '2021-06-02T12:32:00.000Z', + rangeTo: '2021-06-03T13:32:09.079Z', + }); + render(, { + wrapper: Wrapper, + }); + expect(spy).toHaveBeenCalledWith(expect.anything(), { + query: { + comparisonEnabled: 'true', + comparisonType: TimeRangeComparisonEnum.WeekBefore, }, - ]); + }); }); - }); - 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: TimeRangeComparisonEnum.DayBefore, - }, - }); + it('selects week before and enables comparison', () => { + const Wrapper = getWrapper({ + rangeFrom: '2021-06-02T12:32:00.000Z', + rangeTo: '2021-06-03T13:32:09.079Z', + comparisonEnabled: true, + comparisonType: TimeRangeComparisonEnum.WeekBefore, }); - 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: TimeRangeComparisonEnum.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: TimeRangeComparisonEnum.DayBefore, - }); - const component = render(, { wrapper: Wrapper }); - expectTextsInDocument(component, ['Day before', 'Week before']); - expect( - (component.getByTestId('comparisonSelect') as HTMLSelectElement) - .selectedIndex - ).toEqual(0); + const component = render(, { + wrapper: Wrapper, }); + expectTextsNotInDocument(component, ['Day before']); + expectTextsInDocument(component, ['Week before']); + expect( + (component.getByTestId('comparisonSelect') as HTMLSelectElement) + .selectedIndex + ).toEqual(0); }); + }); - 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: TimeRangeComparisonEnum.WeekBefore, - }); - const component = render(, { - wrapper: Wrapper, - }); - expectTextsNotInDocument(component, ['Day before']); - expectTextsInDocument(component, ['Week before']); + describe('Time range is greater than 8 days', () => { + it('Shows absolute times without year when within the same year', () => { + const Wrapper = getWrapper({ + rangeFrom: '2021-05-27T16:32:46.747Z', + rangeTo: '2021-06-04T16:32:46.747Z', + comparisonEnabled: true, + comparisonType: TimeRangeComparisonEnum.PeriodBefore, }); - 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: TimeRangeComparisonEnum.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: TimeRangeComparisonEnum.WeekBefore, - }); - const component = render(, { - wrapper: Wrapper, - }); - expectTextsNotInDocument(component, ['Day before']); - expectTextsInDocument(component, ['Week before']); - expect( - (component.getByTestId('comparisonSelect') as HTMLSelectElement) - .selectedIndex - ).toEqual(0); + 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); }); - 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: TimeRangeComparisonEnum.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); + it('Shows absolute times with year when on different year', () => { + const Wrapper = getWrapper({ + rangeFrom: '2020-05-27T16:32:46.747Z', + rangeTo: '2021-06-04T16:32:46.747Z', + comparisonEnabled: true, + comparisonType: TimeRangeComparisonEnum.PeriodBefore, }); - - 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: TimeRangeComparisonEnum.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); + 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); }); }); }); 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 e48e37e6c4e61ab..cb0bc870354c499 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 @@ -7,12 +7,10 @@ import { EuiCheckbox, EuiSelect } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import moment from 'moment'; import React from 'react'; import { useHistory } from 'react-router-dom'; import { euiStyled } from '../../../../../../../src/plugins/kibana_react/common'; import { useUiTracker } from '../../../../../observability/public'; -import { TimeRangeComparisonEnum } from '../../../../common/runtime_types/comparison_type_rt'; import { useLegacyUrlParams } from '../../../context/url_params_context/use_url_params'; import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context'; import { useAnyOfApmParams } from '../../../hooks/use_apm_params'; @@ -20,8 +18,7 @@ import { useBreakpoints } from '../../../hooks/use_breakpoints'; import { useTimeRange } from '../../../hooks/use_time_range'; import * as urlHelpers from '../../shared/links/url_helpers'; import { getComparisonEnabled } from './get_comparison_enabled'; -import { getComparisonTypes } from './get_comparison_types'; -import { getTimeRangeComparison } from './get_time_range_comparison'; +import { getComparisonOptions } from './get_comparison_options'; const PrependContainer = euiStyled.div` display: flex; @@ -32,88 +29,6 @@ const PrependContainer = euiStyled.div` padding: 0 ${({ theme }) => theme.eui.paddingSizes.m}; `; -function getDateFormat({ - previousPeriodStart, - currentPeriodEnd, -}: { - previousPeriodStart?: string; - currentPeriodEnd?: string; -}) { - const momentPreviousPeriodStart = moment(previousPeriodStart); - const momentCurrentPeriodEnd = moment(currentPeriodEnd); - const isDifferentYears = - momentPreviousPeriodStart.get('year') !== - momentCurrentPeriodEnd.get('year'); - return isDifferentYears ? 'DD/MM/YY HH:mm' : 'DD/MM HH:mm'; -} - -function formatDate({ - dateFormat, - previousPeriodStart, - previousPeriodEnd, -}: { - dateFormat: string; - previousPeriodStart?: string; - previousPeriodEnd?: string; -}) { - const momentStart = moment(previousPeriodStart); - const momentEnd = moment(previousPeriodEnd); - return `${momentStart.format(dateFormat)} - ${momentEnd.format(dateFormat)}`; -} - -export function getSelectOptions({ - comparisonTypes, - start, - end, -}: { - comparisonTypes: TimeRangeComparisonEnum[]; - start?: string; - end?: string; -}) { - return comparisonTypes.map((value) => { - switch (value) { - case TimeRangeComparisonEnum.DayBefore: { - return { - value, - text: i18n.translate('xpack.apm.timeComparison.select.dayBefore', { - defaultMessage: 'Day before', - }), - }; - } - case TimeRangeComparisonEnum.WeekBefore: { - return { - value, - text: i18n.translate('xpack.apm.timeComparison.select.weekBefore', { - defaultMessage: 'Week before', - }), - }; - } - case TimeRangeComparisonEnum.PeriodBefore: { - const { comparisonStart, comparisonEnd } = getTimeRangeComparison({ - comparisonType: TimeRangeComparisonEnum.PeriodBefore, - start, - end, - comparisonEnabled: true, - }); - - const dateFormat = getDateFormat({ - previousPeriodStart: comparisonStart, - currentPeriodEnd: end, - }); - - return { - value, - text: formatDate({ - dateFormat, - previousPeriodStart: comparisonStart, - previousPeriodEnd: comparisonEnd, - }), - }; - } - } - }); -} - export function TimeComparison() { const { core } = useApmPluginContext(); const trackApmEvent = useUiTracker({ app: 'apm' }); @@ -123,19 +38,13 @@ export function TimeComparison() { query: { rangeFrom, rangeTo }, } = useAnyOfApmParams('/services', '/backends/*', '/services/{serviceName}'); - const { exactStart, end } = useTimeRange({ - rangeFrom, - rangeTo, - }); + const { start, end } = useTimeRange({ rangeFrom, rangeTo }); const { urlParams: { comparisonEnabled, comparisonType }, } = useLegacyUrlParams(); - const comparisonTypes = getComparisonTypes({ - start: exactStart, - end, - }); + const comparisonOptions = getComparisonOptions({ start, end }); // Sets default values if (comparisonEnabled === undefined || comparisonType === undefined) { @@ -148,26 +57,22 @@ export function TimeComparison() { }) === false ? 'false' : 'true', - comparisonType: comparisonType ? comparisonType : comparisonTypes[0], + comparisonType: comparisonType + ? comparisonType + : comparisonOptions[0].value, }, }); return null; } - const selectOptions = getSelectOptions({ - comparisonTypes, - start: exactStart, - end, - }); - - const isSelectedComparisonTypeAvailable = selectOptions.some( + const isSelectedComparisonTypeAvailable = comparisonOptions.some( ({ value }) => value === comparisonType ); // Replaces type when current one is no longer available in the select options - if (selectOptions.length !== 0 && !isSelectedComparisonTypeAvailable) { + if (comparisonOptions.length !== 0 && !isSelectedComparisonTypeAvailable) { urlHelpers.replace(history, { - query: { comparisonType: selectOptions[0].value }, + query: { comparisonType: comparisonOptions[0].value }, }); return null; } @@ -177,7 +82,7 @@ export function TimeComparison() { fullWidth={isSmall} data-test-subj="comparisonSelect" disabled={!comparisonEnabled} - options={selectOptions} + options={comparisonOptions} value={comparisonType} prepend={ diff --git a/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx b/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx index 4c1063173d92929..bf6e2b70d390e25 100644 --- a/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/transactions_table/index.tsx @@ -15,7 +15,6 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { EuiCode } from '@elastic/eui'; import { APIReturnType } from '../../../services/rest/create_call_apm_api'; import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context'; -import { useLegacyUrlParams } from '../../../context/url_params_context/use_url_params'; import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher'; import { TransactionOverviewLink } from '../links/apm/transaction_overview_link'; import { getTimeRangeComparison } from '../time_comparison/get_time_range_comparison'; @@ -24,6 +23,8 @@ import { getColumns } from './get_columns'; import { ElasticDocsLink } from '../links/elastic_docs_link'; import { useBreakpoints } from '../../../hooks/use_breakpoints'; import { ManagedTable } from '../managed_table'; +import { useAnyOfApmParams } from '../../../hooks/use_apm_params'; +import { LatencyAggregationType } from '../../../../common/latency_aggregation_types'; type ApiResponse = APIReturnType<'GET /internal/apm/services/{serviceName}/transactions/groups/main_statistics'>; @@ -97,8 +98,11 @@ export function TransactionsTable({ const { transactionType, serviceName } = useApmServiceContext(); const { - urlParams: { latencyAggregationType, comparisonType, comparisonEnabled }, - } = useLegacyUrlParams(); + query: { comparisonEnabled, comparisonType, latencyAggregationType }, + } = useAnyOfApmParams( + '/services/{serviceName}/transactions', + '/services/{serviceName}/overview' + ); const { comparisonStart, comparisonEnd } = getTimeRangeComparison({ start, @@ -123,7 +127,8 @@ export function TransactionsTable({ start, end, transactionType, - latencyAggregationType, + latencyAggregationType: + latencyAggregationType as LatencyAggregationType, }, }, } @@ -198,7 +203,8 @@ export function TransactionsTable({ end, numBuckets: 20, transactionType, - latencyAggregationType, + latencyAggregationType: + latencyAggregationType as LatencyAggregationType, transactionNames: JSON.stringify( transactionGroups.map(({ name }) => name).sort() ), @@ -218,7 +224,7 @@ export function TransactionsTable({ const columns = getColumns({ serviceName, - latencyAggregationType, + latencyAggregationType: latencyAggregationType as LatencyAggregationType, transactionGroupDetailedStatistics, comparisonEnabled, shouldShowSparkPlots, 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 3dc077c407545fb..9ab0948fd75aacd 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 @@ -14,55 +14,6 @@ describe('url_params_context helpers', () => { jest.restoreAllMocks(); }); describe('getDateRange', () => { - describe('with non-rounded dates', () => { - describe('one minute', () => { - it('rounds the start value to minute', () => { - expect( - helpers.getDateRange({ - state: {}, - rangeFrom: '2021-01-28T05:47:52.134Z', - rangeTo: '2021-01-28T05:48:55.304Z', - }) - ).toEqual({ - start: '2021-01-28T05:47:00.000Z', - end: '2021-01-28T05:48:55.304Z', - exactStart: '2021-01-28T05:47:52.134Z', - }); - }); - }); - describe('one day', () => { - it('rounds the start value to minute', () => { - expect( - helpers.getDateRange({ - state: {}, - rangeFrom: '2021-01-27T05:46:07.377Z', - rangeTo: '2021-01-28T05:46:13.367Z', - }) - ).toEqual({ - start: '2021-01-27T05:46:00.000Z', - end: '2021-01-28T05:46:13.367Z', - exactStart: '2021-01-27T05:46:07.377Z', - }); - }); - }); - - describe('one year', () => { - it('rounds the start value to minute', () => { - expect( - helpers.getDateRange({ - state: {}, - rangeFrom: '2020-01-28T05:52:36.290Z', - rangeTo: '2021-01-28T05:52:39.741Z', - }) - ).toEqual({ - start: '2020-01-28T05:52:00.000Z', - end: '2021-01-28T05:52:39.741Z', - exactStart: '2020-01-28T05:52:36.290Z', - }); - }); - }); - }); - describe('when rangeFrom and rangeTo are not changed', () => { it('returns the previous state', () => { expect( @@ -72,7 +23,6 @@ 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', }, rangeFrom: 'now-1m', rangeTo: 'now', @@ -80,7 +30,6 @@ 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', }); }); }); @@ -102,7 +51,6 @@ describe('url_params_context helpers', () => { ).toEqual({ start: '1972-01-01T00:00:00.000Z', end: '1973-01-01T00:00:00.000Z', - exactStart: undefined, }); }); }); @@ -113,22 +61,19 @@ describe('url_params_context helpers', () => { 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', }, 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', }); }); @@ -136,7 +81,7 @@ describe('url_params_context helpers', () => { describe('when rangeFrom or rangeTo have changed', () => { it('returns new state', () => { - jest.spyOn(datemath, 'parse').mockReturnValue(moment(0).utc()); + jest.spyOn(Date, 'now').mockReturnValue(moment(0).unix()); expect( helpers.getDateRange({ @@ -150,39 +95,10 @@ describe('url_params_context helpers', () => { rangeTo: 'now', }) ).toEqual({ - start: '1970-01-01T00:00:00.000Z', + start: '1969-12-31T23:58:00.000Z', end: '1970-01-01T00:00:00.000Z', - exactStart: '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(`doesn't remove /${roundingOption} rounding option when time is not added or subtracted`, () => { - const spy = jest.spyOn(datemath, 'parse'); - helpers.getExactDate(`now/${roundingOption}`); - expect(spy).toHaveBeenCalledWith(`now/${roundingOption}`, {}); - }) - ); - - 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 14fe77b12390a36..6856c0e7d250671 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 @@ -6,8 +6,7 @@ */ import datemath from '@elastic/datemath'; -import { compact, pickBy } from 'lodash'; -import moment from 'moment'; +import { pickBy } from 'lodash'; import { UrlParams } from './types'; function getParsedDate(rawDate?: string, options = {}) { @@ -19,26 +18,12 @@ function getParsedDate(rawDate?: string, options = {}) { } } -export function getExactDate(rawDate: string) { - const isRelativeDate = - rawDate.startsWith('now-') || 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, rangeTo, }: { - state?: Pick< - UrlParams, - 'rangeFrom' | 'rangeTo' | 'start' | 'end' | 'exactStart' - >; + state?: Pick; rangeFrom?: string; rangeTo?: string; }) { @@ -47,31 +32,23 @@ export function getDateRange({ return { start: state.start, end: state.end, - exactStart: state.exactStart, }; } const start = getParsedDate(rangeFrom); const end = getParsedDate(rangeTo, { roundUp: true }); - const exactStart = rangeFrom ? getExactDate(rangeFrom) : 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, - exactStart: state.exactStart, }; } - // rounds down start to minute - const roundedStart = moment(start).startOf('minute'); - return { - start: roundedStart.toISOString(), + start: start.toISOString(), end: end.toISOString(), - exactStart: exactStart?.toISOString(), }; } @@ -92,10 +69,6 @@ export function toBoolean(value?: string) { return value === 'true'; } -export function getPathAsArray(pathname: string = '') { - return compact(pathname.split('/')); -} - export function removeUndefinedProps(obj: T): Partial { return pickBy(obj, (value) => value !== undefined); } 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 fd049ccb23fd99c..5bb3a46c3aea469 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 @@ -19,10 +19,7 @@ import { } from './helpers'; import { UrlParams } from './types'; -type TimeUrlParams = Pick< - UrlParams, - 'start' | 'end' | 'rangeFrom' | 'rangeTo' | 'exactStart' ->; +type TimeUrlParams = Pick; export function resolveUrlParams(location: Location, state: TimeUrlParams) { const query = toQuery(location.search); 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 a67684950c3da32..6c0f10f78e7c8eb 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 @@ -16,7 +16,6 @@ export interface UrlParams { environment?: string; rangeFrom?: string; rangeTo?: string; - exactStart?: 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 ce0da99c4aa14db..80a99d1a4274b91 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 @@ -34,7 +34,7 @@ const UrlParamsProvider: React.ComponentClass<{}> = withRouter( ({ location, children }) => { const refUrlParams = useRef(resolveUrlParams(location, {})); - const { start, end, rangeFrom, rangeTo, exactStart } = refUrlParams.current; + const { start, end, rangeFrom, rangeTo } = refUrlParams.current; // Counter to force an update in useFetcher when the refresh button is clicked. const [rangeId, setRangeId] = useState(0); @@ -46,9 +46,8 @@ const UrlParamsProvider: React.ComponentClass<{}> = withRouter( end, rangeFrom, rangeTo, - exactStart, }), - [location, start, end, rangeFrom, rangeTo, exactStart] + [location, start, end, rangeFrom, rangeTo] ); refUrlParams.current = urlParams; diff --git a/x-pack/plugins/apm/public/hooks/use_comparison.ts b/x-pack/plugins/apm/public/hooks/use_comparison.ts index 93d0e31969c50ff..d9cb88f483e86f2 100644 --- a/x-pack/plugins/apm/public/hooks/use_comparison.ts +++ b/x-pack/plugins/apm/public/hooks/use_comparison.ts @@ -30,7 +30,7 @@ export function useComparison() { urlParams: { comparisonType, comparisonEnabled }, } = useLegacyUrlParams(); - const { offset } = getTimeRangeComparison({ + const { comparisonStart, comparisonEnd, offset } = getTimeRangeComparison({ start, end, comparisonType, @@ -38,6 +38,8 @@ export function useComparison() { }); return { + comparisonStart, + comparisonEnd, offset, comparisonChartTheme, }; diff --git a/x-pack/plugins/apm/public/hooks/use_error_group_distribution_fetcher.tsx b/x-pack/plugins/apm/public/hooks/use_error_group_distribution_fetcher.tsx index d843067b48e9189..ce5d327d5cebfe2 100644 --- a/x-pack/plugins/apm/public/hooks/use_error_group_distribution_fetcher.tsx +++ b/x-pack/plugins/apm/public/hooks/use_error_group_distribution_fetcher.tsx @@ -4,10 +4,10 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { getTimeRangeComparison } from '../components/shared/time_comparison/get_time_range_comparison'; import { useApmParams } from './use_apm_params'; import { useFetcher } from './use_fetcher'; import { useTimeRange } from './use_time_range'; +import { useComparison } from './use_comparison'; export function useErrorGroupDistributionFetcher({ serviceName, @@ -21,16 +21,11 @@ export function useErrorGroupDistributionFetcher({ environment: string; }) { const { - query: { rangeFrom, rangeTo, comparisonEnabled, comparisonType }, + query: { rangeFrom, rangeTo }, } = useApmParams('/services/{serviceName}/errors'); const { start, end } = useTimeRange({ rangeFrom, rangeTo }); - const { comparisonStart, comparisonEnd } = getTimeRangeComparison({ - start, - end, - comparisonType, - comparisonEnabled, - }); + const { comparisonStart, comparisonEnd } = useComparison(); const { data, status } = useFetcher( (callApmApi) => { diff --git a/x-pack/plugins/apm/public/hooks/use_time_range.ts b/x-pack/plugins/apm/public/hooks/use_time_range.ts index 4161cb9f0c67abf..26333062dfa3cb7 100644 --- a/x-pack/plugins/apm/public/hooks/use_time_range.ts +++ b/x-pack/plugins/apm/public/hooks/use_time_range.ts @@ -12,13 +12,12 @@ import { getDateRange } from '../context/url_params_context/helpers'; interface TimeRange { start: string; end: string; - exactStart: string; refreshTimeRange: () => void; timeRangeId: number; } type PartialTimeRange = Pick & - Pick, 'start' | 'end' | 'exactStart'>; + Pick, 'start' | 'end'>; export function useTimeRange(range: { rangeFrom?: string; @@ -42,7 +41,7 @@ export function useTimeRange({ }): TimeRange | PartialTimeRange { const { incrementTimeRangeId, timeRangeId } = useTimeRangeId(); - const { start, end, exactStart } = useMemo(() => { + const { start, end } = useMemo(() => { return getDateRange({ state: {}, rangeFrom, @@ -51,14 +50,13 @@ export function useTimeRange({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [rangeFrom, rangeTo, timeRangeId]); - if ((!start || !end || !exactStart) && !optional) { + if ((!start || !end) && !optional) { throw new Error('start and/or end were unexpectedly not set'); } return { start, end, - exactStart, refreshTimeRange: incrementTimeRangeId, timeRangeId, }; diff --git a/x-pack/plugins/apm/public/hooks/use_transaction_latency_chart_fetcher.ts b/x-pack/plugins/apm/public/hooks/use_transaction_latency_chart_fetcher.ts index 33bb9095665d857..b8d3ed1d8fef9e1 100644 --- a/x-pack/plugins/apm/public/hooks/use_transaction_latency_chart_fetcher.ts +++ b/x-pack/plugins/apm/public/hooks/use_transaction_latency_chart_fetcher.ts @@ -10,9 +10,9 @@ import { useFetcher } from './use_fetcher'; import { useLegacyUrlParams } from '../context/url_params_context/use_url_params'; import { useApmServiceContext } from '../context/apm_service/use_apm_service_context'; import { getLatencyChartSelector } from '../selectors/latency_chart_selectors'; -import { getTimeRangeComparison } from '../components/shared/time_comparison/get_time_range_comparison'; import { useTimeRange } from './use_time_range'; import { useApmParams } from './use_apm_params'; +import { useComparison } from './use_comparison'; export function useTransactionLatencyChartsFetcher({ kuery, @@ -23,12 +23,7 @@ export function useTransactionLatencyChartsFetcher({ }) { const { transactionType, serviceName } = useApmServiceContext(); const { - urlParams: { - transactionName, - latencyAggregationType, - comparisonType, - comparisonEnabled, - }, + urlParams: { transactionName, latencyAggregationType }, } = useLegacyUrlParams(); const { @@ -37,12 +32,7 @@ export function useTransactionLatencyChartsFetcher({ const { start, end } = useTimeRange({ rangeFrom, rangeTo }); - const { comparisonStart, comparisonEnd } = getTimeRangeComparison({ - start, - end, - comparisonType, - comparisonEnabled, - }); + const { comparisonStart, comparisonEnd } = useComparison(); const { data, error, status } = useFetcher( (callApmApi) => {