Skip to content

feat(studio): link trace detail to test case row click (FP-185)#341

Closed
walston wants to merge 4 commits into
mainfrom
nwalston/traces-view
Closed

feat(studio): link trace detail to test case row click (FP-185)#341
walston wants to merge 4 commits into
mainfrom
nwalston/traces-view

Conversation

@walston

@walston walston commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Closes FP-185

Screen.Recording.2026-06-15.at.14.19.38.mov

Summary

Clicking a session row in the experiment detail page now opens an inline trace detail panel to the right of the table, using the same CSS transition pattern as the filter panel. The panel shows Trace Summary and Experiment Context cards; the spans table is omitted in this narrower context.

To enable reuse, IntakeTraceDetailBody is extracted from IntakeTraceDetailRoute — separating the route-level concerns (breadcrumbs, PageHeader) from the content. A showSpans prop (default true) controls whether the spans table renders, leaving the Intake full-page view unchanged.

Test plan

  • Open an experiment detail page → click any session row → confirm the trace detail panel slides in from the right showing Trace Summary and Experiment Context
  • Click the × button → confirm the panel closes
  • Navigate to Intake → Traces → open any trace → confirm the full-page view still shows the spans table and renders correctly
  • Click a row with no trace_id (if any) → confirm nothing opens

Summary by CodeRabbit

  • New Features
    • Added an interactive side-panel trace detail view in the sessions table; selecting a row opens trace details in a right panel with a close button.
    • Trace detail pages now render via a shared detail view, with experiment context, a span-count “showing first N of M” message when truncated, and optional spans/table content.
  • Bug Fixes / UX Improvements
    • Improved trace detail loading, not-found, and error feedback; simplified page shell while keeping the missing-trace guard.
  • Tests
    • Updated route tests to assert trace content asynchronously.

@walston walston requested review from a team as code owners June 15, 2026 21:19
@github-actions github-actions Bot added the feat label Jun 15, 2026
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 2d90dc36-d98c-478e-8ab8-7bb15d48a6ea

📥 Commits

Reviewing files that changed from the base of the PR and between 71e2342 and 6ebb6f6.

📒 Files selected for processing (1)
  • web/packages/studio/src/routes/IntakeTraceDetailRoute/index.spec.tsx

📝 Walkthrough

Walkthrough

IntakeTraceDetailBody is extracted as a new exported component that owns trace fetching, loading/error/404 handling, and a showSpans prop. IntakeTraceDetailRoute delegates all content rendering to it. ExperimentSessionsDataView uses it as an inline right-side panel when a session row with a trace_id is clicked.

Changes

Inline Trace Detail Panel

Layer / File(s) Summary
Extract and build IntakeTraceDetailBody component
web/packages/studio/src/components/IntakeTraceDetailBody/index.tsx
New exported component handles useGetTrace in detailed mode, 404/loading/error states, builds trace summary panels with experiment context when present, and conditionally renders IntakeSpansTable in a two-column layout when showSpans is true.
Simplify IntakeTraceDetailRoute to page shell
web/packages/studio/src/routes/IntakeTraceDetailRoute/index.tsx
Route removes inline trace fetching and rendering, keeping only route guards and page shell markup that delegates all trace display to IntakeTraceDetailBody.
Two-pane layout in ExperimentSessionsDataView
web/packages/studio/src/components/dataViews/ExperimentSessionsDataView/index.tsx
Adds selectedTraceId state, wires onRowClick to set it from trace_id, and renders a conditional right-side animated panel with IntakeTraceDetailBody and close button.
Update tests to async trace assertions
web/packages/studio/src/routes/IntakeTraceDetailRoute/index.spec.tsx
Tests now use findByText to asynchronously await trace label and "Experiment Context" rendering.

Possibly related PRs

  • NVIDIA-NeMo/nemo-platform#260: Modifies ExperimentSessionsDataView row-click handling via StudioDataView's onRowClick API, which this PR extends to open an inline trace detail panel.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding click functionality to test case rows to open a trace detail panel inline, with the ticket reference providing context.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch nwalston/traces-view

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
web/packages/studio/src/routes/IntakeTraceDetailRoute/index.tsx (1)

59-59: ⚡ Quick win

Redundant trace fetch in both components.

IntakeTraceDetailContent fetches the trace only to compute traceBreadcrumbLabel, but IntakeTraceDetailBody immediately re-fetches it. TanStack Query dedupes these calls, but the code is confusing. Consider removing the fetch from IntakeTraceDetailContent and using traceId directly for the breadcrumb until the trace loads.

♻️ Suggested simplification
 const IntakeTraceDetailContent: FC<IntakeTraceDetailContentProps> = ({ traceId }) => {
   const workspace = useWorkspaceFromPath();
-  const { data: trace } = useGetTrace(workspace, traceId, { mode: 'detailed' });
   const { setBreadcrumbs } = useBreadcrumbs();
-  const traceBreadcrumbLabel = trace ? getTraceDisplayName(trace) : traceId;
+  const traceBreadcrumbLabel = traceId; // Body component handles full trace fetch

   useEffect(() => {
     setBreadcrumbs([

Also applies to: 110-116

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/packages/studio/src/routes/IntakeTraceDetailRoute/index.tsx` at line 59,
Remove the redundant useGetTrace call in IntakeTraceDetailContent (the one used
only for computing traceBreadcrumbLabel at line 59) and instead use the traceId
directly for the breadcrumb display until the trace data loads. Keep the
useGetTrace call in IntakeTraceDetailBody (lines 110-116) as it is the primary
consumer of the trace data. This eliminates the confusing redundant fetch while
maintaining the same functionality since TanStack Query will still dedupe any
queries, but the code intent becomes clearer.
web/packages/studio/src/components/dataViews/ExperimentSessionsDataView/index.tsx (1)

22-22: ⚖️ Poor tradeoff

Consider relocating IntakeTraceDetailBody to components directory.

Importing a component from a route file works but inverts typical dependency flow. Since IntakeTraceDetailBody is now a reusable component, it could live in @studio/components/IntakeTraceDetailBody for clearer separation of concerns.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@web/packages/studio/src/components/dataViews/ExperimentSessionsDataView/index.tsx`
at line 22, The IntakeTraceDetailBody component is currently imported from a
route file (`@studio/routes/IntakeTraceDetailRoute`), which inverts the typical
dependency flow where components should be imported from the components
directory. Move the IntakeTraceDetailBody component to a new file in the
components directory at `@studio/components/IntakeTraceDetailBody`, then update
the import statement in ExperimentSessionsDataView/index.tsx to import from the
new components location. Check for any other files that import
IntakeTraceDetailBody from the old routes location and update those imports as
well to maintain consistency.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@web/packages/studio/src/components/dataViews/ExperimentSessionsDataView/index.tsx`:
- Line 215: The Stack panel that displays trace details lacks independent
scrolling capability because it has overflow-hidden without a height constraint.
Locate the Stack component that is conditionally rendered based on the
showTraceDetail variable and add the CSS classes overflow-y-auto and
max-h-[calc(100vh-2rem)] to it. This will constrain the panel's height to the
viewport and enable vertical scrolling within the panel instead of forcing
full-page scroll when content exceeds the viewport height.

---

Nitpick comments:
In
`@web/packages/studio/src/components/dataViews/ExperimentSessionsDataView/index.tsx`:
- Line 22: The IntakeTraceDetailBody component is currently imported from a
route file (`@studio/routes/IntakeTraceDetailRoute`), which inverts the typical
dependency flow where components should be imported from the components
directory. Move the IntakeTraceDetailBody component to a new file in the
components directory at `@studio/components/IntakeTraceDetailBody`, then update
the import statement in ExperimentSessionsDataView/index.tsx to import from the
new components location. Check for any other files that import
IntakeTraceDetailBody from the old routes location and update those imports as
well to maintain consistency.

In `@web/packages/studio/src/routes/IntakeTraceDetailRoute/index.tsx`:
- Line 59: Remove the redundant useGetTrace call in IntakeTraceDetailContent
(the one used only for computing traceBreadcrumbLabel at line 59) and instead
use the traceId directly for the breadcrumb display until the trace data loads.
Keep the useGetTrace call in IntakeTraceDetailBody (lines 110-116) as it is the
primary consumer of the trace data. This eliminates the confusing redundant
fetch while maintaining the same functionality since TanStack Query will still
dedupe any queries, but the code intent becomes clearer.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3b532aaf-fc98-46af-a942-1aabd4c7d974

📥 Commits

Reviewing files that changed from the base of the PR and between a7ae032 and f5a1fff.

📒 Files selected for processing (2)
  • web/packages/studio/src/components/dataViews/ExperimentSessionsDataView/index.tsx
  • web/packages/studio/src/routes/IntakeTraceDetailRoute/index.tsx

@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 19462/25829 75.3% 60.9%
Integration Tests 11372/24601 46.2% 20.2%

walston added 3 commits June 16, 2026 10:05
Clicking a session row in the experiment detail page now opens an
inline trace detail panel to the right of the table. The panel shows
Trace Summary and Experiment Context cards; the spans table is omitted
in this context.

- Extract IntakeTraceDetailBody from IntakeTraceDetailRoute so the
  trace content can be rendered without route-level concerns
  (breadcrumbs, PageHeader). Adds optional showSpans prop (default
  true) to skip the spans table when rendering in the panel.
- Wire ExperimentSessionsDataView: row click sets selectedTraceId,
  which drives a CSS-transition inline panel (same pattern as
  FilterPanel). Close button lives at the top of the panel column.

Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…-185)

- Move IntakeTraceDetailBody and its props interface out of
  IntakeTraceDetailRoute into @studio/components/IntakeTraceDetailBody
- Remove redundant useGetTrace call from IntakeTraceDetailContent;
  use traceId directly for breadcrumb/heading until trace data loads
- Update ExperimentSessionsDataView import to new component location

Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…Body move

- Fix import/order lint error in ExperimentSessionsDataView
- Update IntakeTraceDetailRoute tests: heading now shows traceId
  directly (no longer waits for trace fetch), so findByText for
  Experiment Context needs to be async too

Signed-off-by: Nathan Walston <nwalston@nvidia.com>
@walston walston force-pushed the nwalston/traces-view branch from 1c2386d to 71e2342 Compare June 16, 2026 17:12
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
@walston

walston commented Jun 16, 2026

Copy link
Copy Markdown
Contributor Author

#353

@walston walston closed this Jun 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant