🐛 Fix tab reset issue when versions update via realtime#3599
Conversation
- Track previous version count using useRef to detect new additions - Only trigger onChangeSelectedVersion callback when new versions are added - Preserve user's tab selection during version updates - Maintain ERD tab switch only for explicit user actions and new versions This prevents the active tab from being reset to ERD when existing versions are updated through realtime subscriptions, improving UX consistency.
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
2 Skipped Deployments
|
WalkthroughThe hook useRealtimeVersionsWithSchema adds a ref to track previous versions length and adjusts its effect: it updates selected version as before, but now conditionally calls onChangeSelectedVersion only when the versions list grows and a non-null target version exists, then updates the ref. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant RealtimeFeed as Realtime Versions Feed
participant Hook as useRealtimeVersionsWithSchema
participant UI as SessionDetail UI
Note over Hook: prevVersionsLengthRef holds previous versions length
RealtimeFeed-->>Hook: versions updated
Hook->>Hook: compute targetVersion
Hook->>UI: setSelectedVersion(targetVersion)
alt versions length increased AND targetVersion != null
Hook-->>UI: onChangeSelectedVersion(targetVersion)
else
Note over Hook: Skip calling onChangeSelectedVersion
end
Hook->>Hook: prevVersionsLengthRef = current versions length
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate 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. Comment |
|
Updates to Preview Branch (fix/preserve-tab-selection-on-version-update) ↗︎
Tasks are run on every commit but only new migration files are pushed.
View logs for this Workflow Run ↗︎. |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
frontend/apps/app/components/SessionDetailPage/hooks/useRealtimeVersionsWithSchema/useRealtimeVersionsWithSchema.ts (1)
123-139: Handle DELETE events to avoid spurious errors and stale state.The realtime handler parses payload.new for all events. For DELETE, payload.new is null; this logs an error and leaves deleted versions in state.
Apply this diff to ignore or remove deleted versions:
(payload) => { try { - const parsed = v.safeParse( - buildingSchemaVersionsSchema, - payload.new, - ) - if (!parsed.success) { - handleError(new Error('Invalid building schema version format')) - return - } - - const updatedVersion = parsed.output - handleAddOrUpdateVersion(updatedVersion) + // DELETE events have `old`, INSERT/UPDATE have `new` + if (payload.eventType === 'DELETE') { + const deleted = payload.old as { id?: string } | null + if (deleted?.id) { + setVersions((prev) => prev.filter((v) => v.id !== deleted.id)) + } + return + } + + const parsed = v.safeParse( + buildingSchemaVersionsSchema, + payload.new, + ) + if (!parsed.success) { + handleError(new Error('Invalid building schema version format')) + return + } + + const updatedVersion = parsed.output + handleAddOrUpdateVersion(updatedVersion) } catch (error) { handleError(error) } },
🧹 Nitpick comments (1)
frontend/apps/app/components/SessionDetailPage/hooks/useRealtimeVersionsWithSchema/useRealtimeVersionsWithSchema.ts (1)
34-34: Consider tracking more than just length to prevent unnecessary resets.Length alone can’t distinguish “content update” vs. “reorder” of the same items. Optional: add a ref for the previous latest version ID to make decisions more robust and to avoid redundant state sets.
Example:
-const prevVersionsLengthRef = useRef(initialVersions.length) +const prevVersionsLengthRef = useRef(initialVersions.length) +const prevLatestIdRef = useRef<string | null>(initialVersions[0]?.id ?? null)Then update prevLatestIdRef.current alongside prevVersionsLengthRef.current when versions change.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
frontend/apps/app/components/SessionDetailPage/hooks/useRealtimeVersionsWithSchema/useRealtimeVersionsWithSchema.ts(3 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Name utility files in camelCase (e.g., mergeSchema.ts)
Files:
frontend/apps/app/components/SessionDetailPage/hooks/useRealtimeVersionsWithSchema/useRealtimeVersionsWithSchema.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript/TSX across the codebase
**/*.{ts,tsx}: Prefer early returns for readability
Use named exports only (no default exports)
Prefer const arrow functions over function declarations for simple utilities (e.g., const toggle = () => {})
Files:
frontend/apps/app/components/SessionDetailPage/hooks/useRealtimeVersionsWithSchema/useRealtimeVersionsWithSchema.ts
frontend/apps/**
📄 CodeRabbit inference engine (AGENTS.md)
Next.js apps live under frontend/apps; target app-specific scripts and configs there
Files:
frontend/apps/app/components/SessionDetailPage/hooks/useRealtimeVersionsWithSchema/useRealtimeVersionsWithSchema.ts
frontend/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Follow existing import patterns and tsconfig path aliases
Files:
frontend/apps/app/components/SessionDetailPage/hooks/useRealtimeVersionsWithSchema/useRealtimeVersionsWithSchema.ts
frontend/apps/**/app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
frontend/apps/**/app/**/*.{ts,tsx}: Use Server Components for server-side data fetching
Do client-side data fetching only when necessary
Align data fetching responsibilities with component roles
Use Server Actions for all data mutations (create/update/delete)
Files:
frontend/apps/app/components/SessionDetailPage/hooks/useRealtimeVersionsWithSchema/useRealtimeVersionsWithSchema.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: frontend-ci
- GitHub Check: frontend-lint
- GitHub Check: Supabase Preview
- GitHub Check: security-review
🔇 Additional comments (1)
frontend/apps/app/components/SessionDetailPage/hooks/useRealtimeVersionsWithSchema/useRealtimeVersionsWithSchema.ts (1)
5-5: Importing useRef looks correct.No issues with adding useRef to support the new length-tracking behavior.
Issue
Why is this change needed?
When versions are updated through realtime subscriptions in the SessionDetailPage, the active tab unexpectedly resets to the ERD tab, disrupting the user's workflow. This caused two specific issues:
This occurred because the
onChangeSelectedVersioncallback was being triggered for any version update, not just when new versions are added.The fix ensures that the ERD tab is only automatically activated when:
This preserves the user's tab selection during routine version updates while maintaining the expected behavior for new version additions, and ensures all tabs (including SQL) remain clickable and functional.
2025-09-25.18.23.43.mov
demo.mov