Compare commits

..

4 Commits

Author SHA1 Message Date
Gaurav Tewari
681e96df82 fix: ux issue (empty menu items + refetch on scroll) 2026-10-20 18:42:42 +05:30
Gaurav Tewari
ef36279e1c chore: minor ux improvements 2026-10-20 13:41:30 +05:30
Gaurav Tewari
c64af15ac6 feat(trace-details): add AI thread view 2026-10-19 11:56:16 +05:30
Gaurav Tewari
f45d683ec2 feat(trace-details): trace details & thread tab 2026-10-19 11:56:16 +05:30
3 changed files with 10 additions and 17 deletions

View File

@@ -68,13 +68,10 @@ function TraceDetailsHeader({
const isOverview = tab === TraceDetailsTab.Overview;
// Overview-only panels must not linger over another tab.
// The filter query lives in Filters' local state, which unmounts with the
// Overview tab; drop its result too so both start empty on return.
useEffect(() => {
setIsPreviewFieldsOpen(false);
setIsAnalyticsOpen(false);
onFilteredSpansChange([], false);
}, [tab, onFilteredSpansChange]);
}, [tab]);
const previewFields = useTraceStore((s) => s.previewFields);
const setPreviewFields = useTraceStore((s) => s.setPreviewFields);

View File

@@ -383,16 +383,6 @@ describe('TraceDetailsHeader – tabs', () => {
expect(screen.getByText(metadataText)).toBeInTheDocument();
});
it('clears the filter result when switching to the Thread tab', async () => {
const user = userEvent.setup({ delay: null });
renderHeader();
baseProps.onFilteredSpansChange.mockClear();
await user.click(screen.getByTestId('trace-details-tab-thread'));
expect(baseProps.onFilteredSpansChange).toHaveBeenCalledWith([], false);
});
it('closes the Analytics panel when switching to the Thread tab', async () => {
const user = userEvent.setup({ delay: null });
renderHeader();

View File

@@ -1,4 +1,4 @@
import { useCallback, useRef, useState } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import { TraceDetailsTab } from './constants';
import { useTraceDetailsTab } from './hooks/useTraceDetailsTab';
@@ -13,8 +13,6 @@ function TraceDetailsV3(): JSX.Element {
const [filteredSpanIds, setFilteredSpanIds] = useState<string[]>([]);
const [isFilterActive, setIsFilterActive] = useState(false);
const [hasTraceData, setHasTraceData] = useState(false);
// Tracks which traceId the load event already fired for, so navigating
// between traces (the route component stays mounted) re-fires it once each.
const dataLoadedFiredForRef = useRef<string>('');
const handleFilteredSpansChange = useCallback(
@@ -25,6 +23,14 @@ function TraceDetailsV3(): JSX.Element {
[],
);
// The filter query lives in Filters' local state, which unmounts with the
// Overview tab; drop its result too so both start empty on return.
useEffect(() => {
if (!isOverview) {
handleFilteredSpansChange([], false);
}
}, [isOverview, handleFilteredSpansChange]);
return (
<TraceDetailsWrapper>
<TraceDetailsHeader