fix: use createPortal for DetailPanel instead of context+useEffect
The previous approach used useEffect+context to hoist DetailPanel content to the AppShell level, but the dependency-free useEffect caused a re-render loop that broke sidebar navigation. Replace with createPortal: pages render DetailPanel inline in their JSX but portal it to a target div (#detail-panel-portal) at the AppShell level. No state lifting, no re-render loops. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,6 @@ import { useRouteCatalog } from '../api/queries/catalog';
|
||||
import { useAgents } from '../api/queries/agents';
|
||||
import { useAuthStore } from '../auth/auth-store';
|
||||
import { useMemo, useCallback } from 'react';
|
||||
import { DetailPanelProvider, useDetailPanelSlot } from './DetailPanelContext';
|
||||
|
||||
function healthToColor(health: string): string {
|
||||
switch (health) {
|
||||
@@ -69,7 +68,6 @@ function LayoutContent() {
|
||||
const { data: agents } = useAgents();
|
||||
const { username, logout } = useAuthStore();
|
||||
const { open: paletteOpen, setOpen: setPaletteOpen } = useCommandPalette();
|
||||
const { detail } = useDetailPanelSlot();
|
||||
|
||||
const sidebarApps: SidebarApp[] = useMemo(() => {
|
||||
if (!catalog) return [];
|
||||
@@ -124,7 +122,6 @@ function LayoutContent() {
|
||||
apps={sidebarApps}
|
||||
/>
|
||||
}
|
||||
detail={detail}
|
||||
>
|
||||
<TopBar
|
||||
breadcrumb={breadcrumb}
|
||||
@@ -140,6 +137,8 @@ function LayoutContent() {
|
||||
<main style={{ flex: 1, overflow: 'auto', padding: '1.5rem' }}>
|
||||
<Outlet />
|
||||
</main>
|
||||
{/* Portal target for DetailPanel — pages use createPortal to render here */}
|
||||
<div id="detail-panel-portal" />
|
||||
</AppShell>
|
||||
);
|
||||
}
|
||||
@@ -149,9 +148,7 @@ export function LayoutShell() {
|
||||
<ToastProvider>
|
||||
<CommandPaletteProvider>
|
||||
<GlobalFilterProvider>
|
||||
<DetailPanelProvider>
|
||||
<LayoutContent />
|
||||
</DetailPanelProvider>
|
||||
<LayoutContent />
|
||||
</GlobalFilterProvider>
|
||||
</CommandPaletteProvider>
|
||||
</ToastProvider>
|
||||
|
||||
Reference in New Issue
Block a user