diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/transaction_details_tabs.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/transaction_details_tabs.tsx index cfcd0470a7f2d..8cdfd44c7581a 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/transaction_details_tabs.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/transaction_details_tabs.tsx @@ -5,8 +5,9 @@ * 2.0. */ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; +import { omit } from 'lodash'; import { useHistory } from 'react-router-dom'; import { XYBrushArea } from '@elastic/charts'; @@ -16,6 +17,7 @@ import { useUrlParams } from '../../../context/url_params_context/use_url_params import { useApmParams } from '../../../hooks/use_apm_params'; import { useTransactionTraceSamplesFetcher } from '../../../hooks/use_transaction_trace_samples_fetcher'; +import { maybe } from '../../../../common/utils/maybe'; import { HeightRetainer } from '../../shared/HeightRetainer'; import { fromQuery, push, toQuery } from '../../shared/Links/url_helpers'; @@ -62,22 +64,46 @@ export function TransactionDetailsTabs() { } }; - const { sampleRangeFrom, sampleRangeTo } = urlParams; + const { sampleRangeFrom, sampleRangeTo, transactionId, traceId } = urlParams; const { traceSamples } = traceSamplesData; const clearChartSelection = () => { - const firstSample = traceSamples[0]; - + // enforces a reset of the current sample to be highlighted in the chart + // and selected in waterfall section below, otherwise we end up with + // stale data for the selected sample push(history, { query: { sampleRangeFrom: '', sampleRangeTo: '', - transactionId: firstSample?.transactionId, - traceId: firstSample?.traceId, + traceId: '', + transactionId: '', }, }); }; + useEffect(() => { + const selectedSample = traceSamples.find( + (sample) => + sample.transactionId === transactionId && sample.traceId === traceId + ); + + if (!selectedSample) { + // selected sample was not found. select a new one: + const preferredSample = maybe(traceSamples[0]); + + history.replace({ + ...history.location, + search: fromQuery({ + ...omit(toQuery(history.location.search), [ + 'traceId', + 'transactionId', + ]), + ...preferredSample, + }), + }); + } + }, [history, traceSamples, transactionId, traceId]); + return ( <> diff --git a/x-pack/plugins/apm/public/hooks/use_transaction_trace_samples_fetcher.ts b/x-pack/plugins/apm/public/hooks/use_transaction_trace_samples_fetcher.ts index d27c7bdfeb566..673c1086033b5 100644 --- a/x-pack/plugins/apm/public/hooks/use_transaction_trace_samples_fetcher.ts +++ b/x-pack/plugins/apm/public/hooks/use_transaction_trace_samples_fetcher.ts @@ -5,11 +5,7 @@ * 2.0. */ -import { omit } from 'lodash'; -import { useHistory } from 'react-router-dom'; import { useFetcher } from './use_fetcher'; -import { toQuery, fromQuery } from '../components/shared/Links/url_helpers'; -import { maybe } from '../../common/utils/maybe'; import { useUrlParams } from '../context/url_params_context/use_url_params'; import { useApmServiceContext } from '../context/apm_service/use_apm_service_context'; @@ -45,7 +41,6 @@ export function useTransactionTraceSamplesFetcher({ }, } = useUrlParams(); - const history = useHistory(); const { data = INITIAL_DATA, status, error } = useFetcher( async (callApmApi) => { if (serviceName && start && end && transactionType && transactionName) { @@ -77,27 +72,6 @@ export function useTransactionTraceSamplesFetcher({ const { traceSamples } = response; - const selectedSample = traceSamples.find( - (sample) => - sample.transactionId === transactionId && sample.traceId === traceId - ); - - if (!selectedSample) { - // selected sample was not found. select a new one: - const preferredSample = maybe(traceSamples[0]); - - history.replace({ - ...history.location, - search: fromQuery({ - ...omit(toQuery(history.location.search), [ - 'traceId', - 'transactionId', - ]), - ...preferredSample, - }), - }); - } - return { noHits: false, traceSamples,