Files
cameleer-server/docs/superpowers/plans/2026-04-02-admin-context-separation.md
hsiegeln 574f82b731
Some checks failed
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m7s
CI / docker (push) Successful in 37s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Has been cancelled
docs: add historical implementation plans
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 15:45:49 +02:00

286 lines
7.8 KiB
Markdown

# Admin Page Context Separation Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Hide the operational sidebar and TopBar on admin pages, replacing them with a minimal admin header bar containing only a back button and logout.
**Architecture:** Conditionally skip `<Sidebar>`, `<TopBar>`, and `<CommandPalette>` in `LayoutShell` when `isAdminPage` is true. Add a self-contained admin header bar inside `AdminLayout` with back navigation and user/logout. No design system changes needed — `AppShell` already handles `null` sidebar gracefully.
**Tech Stack:** React 19, react-router, lucide-react icons, CSS Modules, `@cameleer/design-system` CSS variables
---
## File Map
| File | Action | Responsibility |
|------|--------|----------------|
| `ui/src/components/LayoutShell.tsx` | Modify | Conditionally skip Sidebar, TopBar, CommandPalette on admin pages |
| `ui/src/pages/Admin/AdminLayout.tsx` | Modify | Add slim admin header bar with back button and user/logout |
| `ui/src/pages/Admin/AdminLayout.module.css` | Create | Styles for admin header bar |
---
### Task 1: Modify LayoutShell to Skip Sidebar/TopBar on Admin Pages
**Files:**
- Modify: `ui/src/components/LayoutShell.tsx`
- [ ] **Step 1: Update `AppShell` sidebar prop to be conditional**
In `LayoutShell.tsx`, find the `return` statement in `LayoutContent` (around line 296). Change the `<AppShell>` to conditionally pass `null` as sidebar, and conditionally render TopBar and CommandPalette:
```tsx
return (
<AppShell
sidebar={
isAdminPage ? null : <Sidebar apps={sidebarApps} onNavigate={handleSidebarNavigate} />
}
>
{!isAdminPage && (
<TopBar
breadcrumb={breadcrumb}
user={username ? { name: username } : undefined}
onLogout={handleLogout}
/>
)}
{!isAdminPage && (
<CommandPalette
open={paletteOpen}
onClose={() => setPaletteOpen(false)}
onOpen={() => setPaletteOpen(true)}
onSelect={handlePaletteSelect}
onSubmit={handlePaletteSubmit}
onQueryChange={setPaletteQuery}
data={searchData}
/>
)}
{!isAdminPage && (
<ContentTabs active={scope.tab} onChange={setTab} scope={scope} />
)}
<main style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden', minHeight: 0, padding: isAdminPage ? 0 : 0 }}>
<Outlet />
</main>
</AppShell>
);
```
Note: The existing `isAdminPage` guard on `ContentTabs` (line 317) and the padding ternary on `<main>` (line 321) should be updated. Admin padding moves into `AdminLayout` itself, so set `padding: 0` for admin in the main tag.
- [ ] **Step 2: Verify it compiles**
Run: `cd ui && npx tsc --noEmit`
Expected: No type errors.
- [ ] **Step 3: Commit**
```bash
git add ui/src/components/LayoutShell.tsx
git commit -m "feat(#112): hide sidebar, topbar, cmd palette on admin pages"
```
---
### Task 2: Create Admin Header Bar Styles
**Files:**
- Create: `ui/src/pages/Admin/AdminLayout.module.css`
- [ ] **Step 1: Create the CSS module**
```css
.header {
display: flex;
align-items: center;
height: 48px;
padding: 0 16px;
background: var(--bg-surface);
border-bottom: 1px solid var(--border-subtle);
}
.backBtn {
display: flex;
align-items: center;
gap: 6px;
background: none;
border: none;
color: var(--text-secondary);
font-size: 13px;
font-family: var(--font-body);
cursor: pointer;
padding: 6px 10px;
border-radius: var(--radius-sm);
}
.backBtn:hover {
background: var(--bg-hover);
color: var(--text-primary);
}
.title {
flex: 1;
text-align: center;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.08em;
color: var(--text-muted);
text-transform: uppercase;
}
.userSection {
display: flex;
align-items: center;
gap: 12px;
}
.username {
font-size: 13px;
color: var(--text-secondary);
font-family: var(--font-body);
}
.logoutBtn {
background: none;
border: 1px solid var(--border-subtle);
border-radius: var(--radius-sm);
padding: 4px 12px;
font-size: 12px;
color: var(--text-secondary);
cursor: pointer;
font-family: var(--font-body);
}
.logoutBtn:hover {
background: var(--bg-hover);
color: var(--text-primary);
}
.content {
padding: 20px 24px 40px;
}
```
- [ ] **Step 2: Commit**
```bash
git add ui/src/pages/Admin/AdminLayout.module.css
git commit -m "feat(#112): add admin header bar styles"
```
---
### Task 3: Add Admin Header Bar to AdminLayout
**Files:**
- Modify: `ui/src/pages/Admin/AdminLayout.tsx`
- [ ] **Step 1: Rewrite AdminLayout with the header bar**
Replace the full contents of `AdminLayout.tsx`:
```tsx
import { Outlet, useNavigate, useLocation } from 'react-router';
import { Tabs } from '@cameleer/design-system';
import { ArrowLeft, LogOut } from 'lucide-react';
import { useAuthStore } from '../../auth/auth-store';
import styles from './AdminLayout.module.css';
const ADMIN_TABS = [
{ label: 'User Management', value: '/admin/rbac' },
{ label: 'Audit Log', value: '/admin/audit' },
{ label: 'OIDC', value: '/admin/oidc' },
{ label: 'App Config', value: '/admin/appconfig' },
{ label: 'Database', value: '/admin/database' },
{ label: 'ClickHouse', value: '/admin/clickhouse' },
];
export default function AdminLayout() {
const navigate = useNavigate();
const location = useLocation();
const { username, logout } = useAuthStore();
const handleBack = () => navigate('/exchanges');
const handleLogout = () => {
logout();
navigate('/login');
};
return (
<div>
<header className={styles.header}>
<button className={styles.backBtn} onClick={handleBack}>
<ArrowLeft size={16} />
Back
</button>
<span className={styles.title}>Admin</span>
<div className={styles.userSection}>
<span className={styles.username}>{username}</span>
<button className={styles.logoutBtn} onClick={handleLogout}>
<LogOut size={14} />
</button>
</div>
</header>
<Tabs
tabs={ADMIN_TABS}
active={location.pathname}
onChange={(path) => navigate(path)}
/>
<div className={styles.content}>
<Outlet />
</div>
</div>
);
}
```
- [ ] **Step 2: Verify it compiles**
Run: `cd ui && npx tsc --noEmit`
Expected: No type errors.
- [ ] **Step 3: Commit**
```bash
git add ui/src/pages/Admin/AdminLayout.tsx
git commit -m "feat(#112): add admin header bar with back button and logout"
```
---
### Task 4: Visual Verification
- [ ] **Step 1: Start the dev server and verify**
Run: `cd ui && npm run dev`
Open `http://localhost:5173/admin/rbac` and verify:
1. No sidebar visible — content spans full viewport width
2. No TopBar (no breadcrumb, no search trigger, no status filters, no time range)
3. Admin header bar visible at top with: `[<- Back]` left, `ADMIN` center, `[username] [logout]` right
4. Admin tabs (User Management, Audit Log, etc.) below the header bar
5. Admin content renders correctly below tabs
- [ ] **Step 2: Verify operational pages are unaffected**
Navigate to `http://localhost:5173/exchanges` and verify:
1. Sidebar renders normally with app/agent/route trees
2. TopBar renders with breadcrumb, search, filters, time range
3. ContentTabs show (Exchanges, Dashboard, Runtime, Logs)
4. Command palette works (Ctrl+K / Cmd+K)
- [ ] **Step 3: Verify back button**
From any admin page, click "Back" — should navigate to `/exchanges`.
- [ ] **Step 4: Verify logout**
Click logout icon in admin header — should navigate to `/login`.
- [ ] **Step 5: Final commit if any fixes were needed**
```bash
git add -A
git commit -m "fix(#112): admin layout adjustments from visual review"
```