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

7.8 KiB

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:

  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
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

.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
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:

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
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
git add -A
git commit -m "fix(#112): admin layout adjustments from visual review"