feat: add About Me dialog showing user info, roles, and groups
All checks were successful
CI / cleanup-branch (push) Has been skipped
CI / build (push) Successful in 1m48s
CI / docker (push) Successful in 1m45s
CI / deploy-feature (push) Has been skipped
CI / deploy (push) Successful in 37s

- Add GET /api/v1/auth/me endpoint returning current user's UserDetail
- Add AboutMeDialog component with role badges and group memberships
- Add userMenuItems prop to TopBar via design-system update
- Wire "About Me" menu item into user dropdown above Logout

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-08 12:12:29 +02:00
parent a8b977a2db
commit 448a63adc9
7 changed files with 213 additions and 7 deletions

View File

@@ -15,9 +15,10 @@ import {
useGlobalFilters,
useStarred,
} from '@cameleer/design-system';
import type { SearchResult, SidebarTreeNode } from '@cameleer/design-system';
import type { SearchResult, SidebarTreeNode, DropdownItem } from '@cameleer/design-system';
import sidebarLogo from '@cameleer/design-system/assets/cameleer3-logo.svg';
import { Box, Settings, FileText, ChevronRight, Square, Pause, Star, X } from 'lucide-react';
import { Box, Settings, FileText, ChevronRight, Square, Pause, Star, X, User } from 'lucide-react';
import { AboutMeDialog } from './AboutMeDialog';
import css from './LayoutShell.module.css';
import { useQueryClient } from '@tanstack/react-query';
import { useRouteCatalog } from '../api/queries/catalog';
@@ -437,6 +438,12 @@ function LayoutContent() {
const effectiveSelectedPath = sidebarRevealPath ?? location.pathname;
// --- About Me dialog -----------------------------------------------
const [aboutMeOpen, setAboutMeOpen] = useState(false);
const userMenuItems: DropdownItem[] = useMemo(() => [
{ label: 'About Me', icon: createElement(User, { size: 14 }), onClick: () => setAboutMeOpen(true) },
], []);
// --- Exchange full-text search via command palette -----------------
const [paletteQuery, setPaletteQuery] = useState('');
const debouncedQuery = useDebouncedValue(paletteQuery, 300);
@@ -724,8 +731,10 @@ function LayoutContent() {
/>
}
user={username ? { name: username } : undefined}
userMenuItems={userMenuItems}
onLogout={handleLogout}
/>
<AboutMeDialog open={aboutMeOpen} onClose={() => setAboutMeOpen(false)} />
<CommandPalette
key={isAdminPage ? 'admin' : 'ops'}
open={paletteOpen}