Skip to content

Preserve scroll position when switching between chat and file tabs#1125

Open
vishsanghishetty wants to merge 2 commits intoambient-code:mainfrom
vishsanghishetty:fix/1070-preserve-artifact-scroll-position
Open

Preserve scroll position when switching between chat and file tabs#1125
vishsanghishetty wants to merge 2 commits intoambient-code:mainfrom
vishsanghishetty:fix/1070-preserve-artifact-scroll-position

Conversation

@vishsanghishetty
Copy link
Copy Markdown

@vishsanghishetty vishsanghishetty commented Apr 1, 2026

Summary

Fixes #1070 — the artifact viewer now preserves scroll position when switching between chat and file/task tabs.

The root cause was that renderMainContent() conditionally mounted/unmounted the Chat, FileViewer, and TaskTranscriptViewer components on every tab switch. Each mount reset scroll position and React Query cache.

The fix renders all tab content simultaneously and toggles visibility with the CSS hidden class (display: none). Inactive FileViewers also stop polling via a new isActive prop so background tabs don't make unnecessary fetches.

What changed

  • page.tsxrenderMainContent() now renders chat, all open file tabs, and all open task tabs at once; inactive ones get className="hidden"
  • file-viewer.tsx — added isActive prop (default true) that gates refetchInterval so hidden tabs don't poll
  • file-viewer.test.tsx — 3 new tests covering the polling logic based on isActive and sessionPhase

Test plan

  • Unit tests pass (11/11 in file-viewer, full suite green)
  • TypeScript compiles clean (tsc --noEmit)
  • ESLint clean (only pre-existing warning)
  • Manual test: open a file tab, scroll down, switch to chat, switch back — scroll position is preserved

Video recording of the manual test will be attached in a comment below.
ambient-scroll

render all tab content simultaneously and toggle visibility with CSS
hidden class instead of mounting/unmounting. gates FileViewer polling
on an isActive prop so background tabs don't fetch.

closes ambient-code#1070

Signed-off-by: Vishali <vsanghis@redhat.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 1, 2026

Walkthrough

Renders chat, all open file tabs, and all open task tabs simultaneously (hidden via CSS) to preserve component state; adds an optional isActive prop to FileViewer and TaskTranscriptViewer to gate React Query polling when a tab is not active.

Changes

Cohort / File(s) Summary
Session Page Render
components/frontend/src/app/projects/[name]/sessions/[sessionName]/page.tsx
Refactored main render to mount chat, all open FileViewer tabs, and all open TaskTranscriptViewer tabs concurrently; visibility is controlled via hidden/isActive instead of conditional mounting.
FileViewer Component & Tests
components/frontend/src/app/projects/[name]/sessions/[sessionName]/components/file-viewer.tsx, components/frontend/src/app/projects/[name]/sessions/[sessionName]/components/__tests__/file-viewer.test.tsx
Added optional isActive?: boolean (default true) to FileViewer; polling (refetchInterval) now requires isActive && sessionPhase === "Running". New tests verify useWorkspaceFile receives appropriate refetchInterval.
Task Transcript Viewer
components/frontend/src/app/projects/[name]/sessions/[sessionName]/components/task-transcript-viewer.tsx
Added optional isActive?: boolean (default true) and gated task polling so periodic refetching occurs only when isActive is true and task is running; preserves manual refresh and rendering behavior.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Page as "Session Page"
participant Chat as "ChatView\n(hidden toggle)"
participant File as "FileViewer(s)\nisActive prop"
participant Task as "TaskTranscriptViewer(s)\nisActive prop"
Page->>Chat: mount (always)
Page->>File: mount all open viewers (isActive true/false)
Page->>Task: mount all open task viewers (isActive true/false)
Note right of File: when isActive && sessionPhase==="Running"\n-> enable polling (refetchInterval: 5000)
Note right of Task: when isActive && task.status==="running"\n-> enable polling (refetchInterval: 5000)
Page->>File: toggle isActive on tab switch (hide/show via CSS)
Page->>Task: toggle isActive on tab switch (hide/show via CSS)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly explains the root cause and solution: preventing component remounting by rendering all tabs and toggling visibility, while adding isActive prop to gate polling.
Linked Issues check ✅ Passed The PR directly addresses issue #1070 by preserving artifact viewer scroll position through preventing component unmounting and toggling visibility with CSS hidden class.
Out of Scope Changes check ✅ Passed All changes align with the primary objective: page.tsx renders all tabs simultaneously, file-viewer and task-transcript-viewer add isActive prop for polling control, and new tests verify polling behavior.
Title check ✅ Passed The title accurately summarizes the main change: rendering all tabs simultaneously and hiding inactive ones preserves scroll position when switching between chat and file tabs.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/frontend/src/app/projects/`[name]/sessions/[sessionName]/page.tsx:
- Around line 1691-1708: The TaskTranscriptViewer is polling running tasks even
when its tab is hidden; update the TaskTranscriptViewerProps to accept an
optional boolean isActive, pass isActive from the mapping (where
fileTabs.openTaskTabs is rendered) similarly to FileViewer, and change the
refetchInterval logic inside TaskTranscriptViewer to only poll when isActive &&
sessionPhase === "Running" && task?.status === "running" (matching FileViewer's
pattern) so inactive mounted tabs do not trigger periodic network calls.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d24e5948-00e5-4adf-8053-e92ad69dd6d5

📥 Commits

Reviewing files that changed from the base of the PR and between 65e454c and e49dfb3.

📒 Files selected for processing (3)
  • components/frontend/src/app/projects/[name]/sessions/[sessionName]/components/__tests__/file-viewer.test.tsx
  • components/frontend/src/app/projects/[name]/sessions/[sessionName]/components/file-viewer.tsx
  • components/frontend/src/app/projects/[name]/sessions/[sessionName]/page.tsx

Signed-off-by: Vishali <vsanghis@redhat.com>
@vishsanghishetty vishsanghishetty changed the title preserve scroll position when switching between chat and file tabs Preserve scroll position when switching between chat and file tabs Apr 1, 2026
@ambient-code ambient-code bot added this to the Review Queue milestone Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Artifact viewer does not preserve scroll position when switching between chat and file view

1 participant