From 5f185318798bd514402a061324aa6f3f6f57125a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 25 Feb 2026 21:58:23 +0000 Subject: [PATCH 1/2] fix: mark session replay event sub-panel as nested to fix tab and close bugs Bug 1: Clicking an event in the session replay event list opened the sub-panel on the Session Replay tab (instead of the default tab) because both panels shared the same 'sidePanelTab' URL query parameter. Setting isNestedPanel=true makes the sub-panel use local state for its tab, defaulting to the appropriate tab for the source kind. Bug 2: Switching tabs in the sub-panel (e.g., to Overview) modified the shared sidePanelTab query param, causing the parent panel to switch away from Session Replay. This unmounted SessionSubpanel, leaving the subDrawerOpen state stuck at true, which disabled both ESC and overlay-click closing. With isNestedPanel=true, the sub-panel no longer affects the parent's tab state. Also adds a cleanup effect to reset setDrawerOpen(false) on unmount as a safety measure. Co-authored-by: Mike Shi --- packages/app/src/SessionSubpanel.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/app/src/SessionSubpanel.tsx b/packages/app/src/SessionSubpanel.tsx index b89e5fd541..cd624c8e20 100644 --- a/packages/app/src/SessionSubpanel.tsx +++ b/packages/app/src/SessionSubpanel.tsx @@ -266,6 +266,12 @@ export default function SessionSubpanel({ const [rowId, setRowId] = useState(undefined); const [aliasWith, setAliasWith] = useState([]); + useEffect(() => { + return () => { + setDrawerOpen(false); + }; + }, [setDrawerOpen]); + const [tsQuery, setTsQuery] = useQueryState( 'ts', parseAsInteger.withOptions({ history: 'replace' }), @@ -465,6 +471,7 @@ export default function SessionSubpanel({ source={traceSource} rowId={rowId} aliasWith={aliasWith} + isNestedPanel={true} onClose={() => { setDrawerOpen(false); setRowId(undefined); From ce404c5f35faac1640b9ca7f50e3a60fff26410a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 26 Feb 2026 00:54:52 +0000 Subject: [PATCH 2/2] fix: add withOverlay prop to allow overlay on nested session replay sub-panel The isNestedPanel flag bundles two behaviors: (1) using local tab state and (2) disabling the overlay. For the session replay sub-panel, we need local tab state (to avoid conflicts with the parent's sidePanelTab query param) but ALSO need the overlay for proper close behavior. Without the overlay: - Users can't click outside the sub-panel to close it - Mantine's modal stacking doesn't properly track the sub-panel, causing ESC to close all drawers instead of just the topmost one The new withOverlay prop overrides the default (!isNestedPanel) behavior, allowing isNestedPanel=true with withOverlay=true. Co-authored-by: Mike Shi --- packages/app/src/SessionSubpanel.tsx | 1 + packages/app/src/components/DBRowSidePanel.tsx | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/app/src/SessionSubpanel.tsx b/packages/app/src/SessionSubpanel.tsx index cd624c8e20..2d109cf2bb 100644 --- a/packages/app/src/SessionSubpanel.tsx +++ b/packages/app/src/SessionSubpanel.tsx @@ -472,6 +472,7 @@ export default function SessionSubpanel({ rowId={rowId} aliasWith={aliasWith} isNestedPanel={true} + withOverlay={true} onClose={() => { setDrawerOpen(false); setRowId(undefined); diff --git a/packages/app/src/components/DBRowSidePanel.tsx b/packages/app/src/components/DBRowSidePanel.tsx index c0a3140179..f5a3436a2c 100644 --- a/packages/app/src/components/DBRowSidePanel.tsx +++ b/packages/app/src/components/DBRowSidePanel.tsx @@ -88,6 +88,7 @@ type DBRowSidePanelProps = { aliasWith?: WithClause[]; onClose: () => void; isNestedPanel?: boolean; + withOverlay?: boolean; breadcrumbPath?: BreadcrumbPath; onBreadcrumbClick?: BreadcrumbNavigationCallback; }; @@ -527,6 +528,7 @@ export default function DBRowSidePanelErrorBoundary({ aliasWith, source, isNestedPanel, + withOverlay, breadcrumbPath = [], onBreadcrumbClick, }: DBRowSidePanelProps) { @@ -566,7 +568,7 @@ export default function DBRowSidePanelErrorBoundary({ { if (!subDrawerOpen) { _onClose();