fix(#112): add missing Routes section, fix admin double padding
Review feedback: buildRouteTreeNodes was defined but never rendered. Added Routes section between Agents and Admin. Removed duplicate padding on admin pages (AdminLayout handles its own padding). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,7 @@ import { useScope } from '../hooks/useScope';
|
||||
import {
|
||||
buildAppTreeNodes,
|
||||
buildAgentTreeNodes,
|
||||
buildRouteTreeNodes,
|
||||
buildAdminTreeNodes,
|
||||
readCollapsed,
|
||||
writeCollapsed,
|
||||
@@ -145,6 +146,7 @@ function makeChevron() {
|
||||
|
||||
const SK_APPS = 'sidebar:section:apps';
|
||||
const SK_AGENTS = 'sidebar:section:agents';
|
||||
const SK_ROUTES = 'sidebar:section:routes';
|
||||
const SK_ADMIN = 'sidebar:section:admin';
|
||||
const SK_COLLAPSED = 'sidebar:collapsed';
|
||||
|
||||
@@ -181,10 +183,11 @@ function LayoutContent() {
|
||||
// --- Section open states ------------------------------------------
|
||||
const [appsOpen, setAppsOpen] = useState(() => readCollapsed(SK_APPS, true));
|
||||
const [agentsOpen, setAgentsOpen] = useState(() => readCollapsed(SK_AGENTS, false));
|
||||
const [routesOpen, setRoutesOpen] = useState(() => readCollapsed(SK_ROUTES, false));
|
||||
const [adminOpen, setAdminOpen] = useState(() => readCollapsed(SK_ADMIN, false));
|
||||
|
||||
// Ref to remember operational section states when switching to admin
|
||||
const opsStateRef = useRef({ apps: appsOpen, agents: agentsOpen });
|
||||
const opsStateRef = useRef({ apps: appsOpen, agents: agentsOpen, routes: routesOpen });
|
||||
|
||||
const isAdminPage = location.pathname.startsWith('/admin');
|
||||
|
||||
@@ -193,9 +196,10 @@ function LayoutContent() {
|
||||
useEffect(() => {
|
||||
if (isAdminPage && !prevAdminRef.current) {
|
||||
// Entering admin — save operational states and collapse them
|
||||
opsStateRef.current = { apps: appsOpen, agents: agentsOpen };
|
||||
opsStateRef.current = { apps: appsOpen, agents: agentsOpen, routes: routesOpen };
|
||||
setAppsOpen(false);
|
||||
setAgentsOpen(false);
|
||||
setRoutesOpen(false);
|
||||
setAdminOpen(true);
|
||||
writeCollapsed(SK_APPS, false);
|
||||
writeCollapsed(SK_AGENTS, false);
|
||||
@@ -204,9 +208,11 @@ function LayoutContent() {
|
||||
// Leaving admin — restore operational states
|
||||
setAppsOpen(opsStateRef.current.apps);
|
||||
setAgentsOpen(opsStateRef.current.agents);
|
||||
setRoutesOpen(opsStateRef.current.routes);
|
||||
setAdminOpen(false);
|
||||
writeCollapsed(SK_APPS, opsStateRef.current.apps);
|
||||
writeCollapsed(SK_AGENTS, opsStateRef.current.agents);
|
||||
writeCollapsed(SK_ROUTES, opsStateRef.current.routes);
|
||||
writeCollapsed(SK_ADMIN, false);
|
||||
}
|
||||
prevAdminRef.current = isAdminPage;
|
||||
@@ -235,6 +241,17 @@ function LayoutContent() {
|
||||
});
|
||||
}, [isAdminPage, navigate]);
|
||||
|
||||
const toggleRoutes = useCallback(() => {
|
||||
if (isAdminPage) {
|
||||
navigate('/exchanges');
|
||||
return;
|
||||
}
|
||||
setRoutesOpen((prev) => {
|
||||
writeCollapsed(SK_ROUTES, !prev);
|
||||
return !prev;
|
||||
});
|
||||
}, [isAdminPage, navigate]);
|
||||
|
||||
const toggleAdmin = useCallback(() => {
|
||||
setAdminOpen((prev) => {
|
||||
writeCollapsed(SK_ADMIN, !prev);
|
||||
@@ -282,6 +299,11 @@ function LayoutContent() {
|
||||
[sidebarApps],
|
||||
);
|
||||
|
||||
const routeTreeNodes: SidebarTreeNode[] = useMemo(
|
||||
() => buildRouteTreeNodes(sidebarApps, makeStatusDot, makeChevron),
|
||||
[sidebarApps],
|
||||
);
|
||||
|
||||
const adminTreeNodes: SidebarTreeNode[] = useMemo(
|
||||
() => buildAdminTreeNodes(),
|
||||
[],
|
||||
@@ -511,6 +533,24 @@ function LayoutContent() {
|
||||
/>
|
||||
</Sidebar.Section>
|
||||
|
||||
<Sidebar.Section
|
||||
icon={createElement(GitBranch, { size: 16 })}
|
||||
label="Routes"
|
||||
open={routesOpen}
|
||||
onToggle={toggleRoutes}
|
||||
>
|
||||
<SidebarTree
|
||||
nodes={routeTreeNodes}
|
||||
selectedPath={sidebarRevealPath ?? location.pathname}
|
||||
isStarred={isStarred}
|
||||
onToggleStar={toggleStar}
|
||||
filterQuery={filterQuery}
|
||||
persistKey="routes"
|
||||
autoRevealPath={sidebarRevealPath}
|
||||
onNavigate={handleSidebarNavigate}
|
||||
/>
|
||||
</Sidebar.Section>
|
||||
|
||||
{/* When NOT on admin pages, show Admin section at bottom */}
|
||||
{!isAdminPage && (
|
||||
<Sidebar.Section
|
||||
@@ -564,7 +604,7 @@ function LayoutContent() {
|
||||
<ContentTabs active={scope.tab} onChange={setTab} scope={scope} />
|
||||
)}
|
||||
|
||||
<main style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden', minHeight: 0, padding: isAdminPage ? '1.5rem' : 0 }}>
|
||||
<main style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden', minHeight: 0 }}>
|
||||
<Outlet />
|
||||
</main>
|
||||
</AppShell>
|
||||
|
||||
Reference in New Issue
Block a user