refactor: compose TopBar center slot with server-specific controls
Some checks failed
CI / cleanup-branch (push) Has been skipped
CI / build (push) Failing after 52s
CI / docker (push) Has been skipped
CI / deploy (push) Has been skipped
CI / deploy-feature (push) Has been skipped

Update to @cameleer/design-system@0.1.40 which decomposes TopBar into a
composable shell. Move status filters, time range, search trigger, and
auto-refresh toggle from the DS TopBar into LayoutShell as composed
children. Fixes cameleer/cameleer-saas#53.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-10 17:06:03 +02:00
parent f0658cbd07
commit 2863ceef12
3 changed files with 43 additions and 8 deletions

View File

@@ -6,6 +6,10 @@ import {
SidebarTree,
StatusDot,
TopBar,
SearchTrigger,
AutoRefreshToggle,
ButtonGroup,
TimeRangeDropdown,
CommandPalette,
CommandPaletteProvider,
GlobalFilterProvider,
@@ -15,7 +19,7 @@ import {
useGlobalFilters,
useStarred,
} from '@cameleer/design-system';
import type { SearchResult, SidebarTreeNode, DropdownItem } from '@cameleer/design-system';
import type { SearchResult, SidebarTreeNode, DropdownItem, ButtonGroupItem } from '@cameleer/design-system';
import sidebarLogo from '@cameleer/design-system/assets/cameleer3-logo.svg';
import { Box, Settings, FileText, ChevronRight, Square, Pause, Star, X, User } from 'lucide-react';
import { AboutMeDialog } from './AboutMeDialog';
@@ -264,6 +268,13 @@ function StarredList({ items, onNavigate, onRemove }: { items: StarredItem[]; on
/* Section state keys */
/* ------------------------------------------------------------------ */
const STATUS_ITEMS: ButtonGroupItem[] = [
{ value: 'completed', label: 'OK', color: 'var(--success)' },
{ value: 'warning', label: 'Warn', color: 'var(--warning)' },
{ value: 'failed', label: 'Error', color: 'var(--error)' },
{ value: 'running', label: 'Running', color: 'var(--running)' },
]
const SK_APPS = 'sidebar:section:apps';
const SK_ADMIN = 'sidebar:section:admin';
const SK_COLLAPSED = 'sidebar:collapsed';
@@ -276,7 +287,8 @@ function LayoutContent() {
const navigate = useNavigate();
const location = useLocation();
const queryClient = useQueryClient();
const { timeRange, autoRefresh, refreshTimeRange } = useGlobalFilters();
const globalFilters = useGlobalFilters();
const { timeRange, autoRefresh, refreshTimeRange } = globalFilters;
// --- Role checks ----------------------------------------------------
const isAdmin = useIsAdmin();
@@ -754,7 +766,30 @@ function LayoutContent() {
user={username ? { name: username } : undefined}
userMenuItems={userMenuItems}
onLogout={handleLogout}
/>
>
<SearchTrigger onClick={() => setPaletteOpen(true)} />
<ButtonGroup
items={STATUS_ITEMS}
value={globalFilters.statusFilters}
onChange={(selected) => {
const current = globalFilters.statusFilters
for (const v of selected) {
if (!current.has(v)) globalFilters.toggleStatus(v as 'completed' | 'warning' | 'failed' | 'running')
}
for (const v of current) {
if (!selected.has(v)) globalFilters.toggleStatus(v as 'completed' | 'warning' | 'failed' | 'running')
}
}}
/>
<TimeRangeDropdown
value={globalFilters.timeRange}
onChange={globalFilters.setTimeRange}
/>
<AutoRefreshToggle
active={globalFilters.autoRefresh}
onChange={globalFilters.setAutoRefresh}
/>
</TopBar>
<AboutMeDialog open={aboutMeOpen} onClose={() => setAboutMeOpen(false)} />
<CommandPalette
key={isAdminPage ? 'admin' : 'ops'}