diff --git a/public/app/features/explore/Explore.tsx b/public/app/features/explore/Explore.tsx index 8e595a4b67c..a793f1f537f 100644 --- a/public/app/features/explore/Explore.tsx +++ b/public/app/features/explore/Explore.tsx @@ -307,6 +307,7 @@ export class Explore extends React.PureComponent { splitOpenFn={splitOpen} scrollElement={this.scrollElement} topOfExploreViewRef={this.topOfExploreViewRef} + queryResponse={queryResponse} /> ) ); diff --git a/public/app/features/explore/TraceView/TraceView.test.tsx b/public/app/features/explore/TraceView/TraceView.test.tsx index be916efcbb0..3ebd18bbad6 100644 --- a/public/app/features/explore/TraceView/TraceView.test.tsx +++ b/public/app/features/explore/TraceView/TraceView.test.tsx @@ -4,16 +4,22 @@ import { TraceView } from './TraceView'; import { setDataSourceSrv } from '@grafana/runtime'; import { ExploreId } from 'app/types'; import { TraceData, TraceSpanData } from '@jaegertracing/jaeger-ui-components/src/types/trace'; -import { MutableDataFrame } from '@grafana/data'; +import { getDefaultTimeRange, LoadingState, MutableDataFrame } from '@grafana/data'; import { configureStore } from '../../../store/configureStore'; import { Provider } from 'react-redux'; import userEvent from '@testing-library/user-event'; function renderTraceView(frames = [frameOld]) { const store = configureStore(); + const mockPanelData = { + state: LoadingState.Done, + series: [], + timeRange: getDefaultTimeRange(), + }; + const { container, baseElement } = render( - {}} /> + {}} queryResponse={mockPanelData} /> ); return { @@ -146,9 +152,20 @@ describe('TraceView', () => { it('resets detail view for new trace with the identical spanID', () => { const store = configureStore(); + const mockPanelData = { + state: LoadingState.Done, + series: [], + timeRange: getDefaultTimeRange(), + }; + const { rerender } = render( - {}} /> + {}} + queryResponse={mockPanelData} + /> ); const span = screen.getAllByText('', { selector: 'div[data-test-id="span-view"]' })[2]; @@ -158,7 +175,12 @@ describe('TraceView', () => { rerender( - {}} /> + {}} + queryResponse={mockPanelData} + /> ); expect(screen.queryByText(/Process/)).not.toBeInTheDocument(); diff --git a/public/app/features/explore/TraceView/TraceView.tsx b/public/app/features/explore/TraceView/TraceView.tsx index 24a31dd3fdc..697a36b2578 100644 --- a/public/app/features/explore/TraceView/TraceView.tsx +++ b/public/app/features/explore/TraceView/TraceView.tsx @@ -5,7 +5,9 @@ import { DataSourceApi, Field, LinkModel, + LoadingState, mapInternalLinkToExplore, + PanelData, SplitOpen, TraceSpanRow, } from '@grafana/data'; @@ -24,7 +26,7 @@ import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; import { getTimeZone } from 'app/features/profile/state/selectors'; import { StoreState } from 'app/types'; import { ExploreId } from 'app/types/explore'; -import React, { RefObject, useCallback, useMemo, useState } from 'react'; +import React, { RefObject, useCallback, useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { changePanelState } from '../state/explorePane'; import { createSpanLinkFactory } from './createSpanLink'; @@ -44,6 +46,7 @@ type Props = { exploreId: ExploreId; scrollElement?: Element; topOfExploreViewRef?: RefObject; + queryResponse: PanelData; }; export function TraceView(props: Props) { @@ -106,6 +109,12 @@ export function TraceView(props: Props) { [childrenHiddenIDs, detailStates, hoverIndentGuideIds, spanNameColumnWidth, traceProp?.traceID] ); + useEffect(() => { + if (props.queryResponse.state === LoadingState.Done) { + props.topOfExploreViewRef?.current?.scrollIntoView(); + } + }, [props.queryResponse, props.topOfExploreViewRef]); + const traceToLogsOptions = (getDatasourceSrv().getInstanceSettings(datasource?.name)?.jsonData as TraceToLogsData) ?.tracesToLogs; const createSpanLink = useMemo( diff --git a/public/app/features/explore/TraceView/TraceViewContainer.tsx b/public/app/features/explore/TraceView/TraceViewContainer.tsx index 1f0123aa708..787be09db35 100644 --- a/public/app/features/explore/TraceView/TraceViewContainer.tsx +++ b/public/app/features/explore/TraceView/TraceViewContainer.tsx @@ -1,6 +1,6 @@ import React, { RefObject } from 'react'; import { Collapse } from '@grafana/ui'; -import { DataFrame, SplitOpen } from '@grafana/data'; +import { DataFrame, PanelData, SplitOpen } from '@grafana/data'; import { TraceView } from './TraceView'; import { ExploreId } from 'app/types/explore'; @@ -10,9 +10,10 @@ interface Props { exploreId: ExploreId; scrollElement?: Element; topOfExploreViewRef?: RefObject; + queryResponse: PanelData; } export function TraceViewContainer(props: Props) { - const { dataFrames, splitOpenFn, exploreId, scrollElement, topOfExploreViewRef } = props; + const { dataFrames, splitOpenFn, exploreId, scrollElement, topOfExploreViewRef, queryResponse } = props; return ( @@ -22,6 +23,7 @@ export function TraceViewContainer(props: Props) { splitOpenFn={splitOpenFn} scrollElement={scrollElement} topOfExploreViewRef={topOfExploreViewRef} + queryResponse={queryResponse} /> );