fix(frontend): isolate administration rail from portal CSS

This commit is contained in:
Codex
2026-09-07 11:05:38 +02:00
parent 28db30bd78
commit 651a5c7902
5 changed files with 148 additions and 22 deletions
+12 -11
View File
@@ -855,7 +855,7 @@ export function AppShell({ canLogout }: AppShellProps) {
{/* Right session rail */}
{(activeSurface === "database-management" || !showActivity) && (
<aside aria-label="Session navigation" className="flex w-64 shrink-0 flex-col bg-sidebar">
<div className="relative px-4 pb-3 pt-5 text-center">
<div className="thot-session-navigation__header relative text-center">
<h1 className="font-heading text-xl font-semibold leading-none tracking-tight text-foreground">
Thoth<span className="text-primary">II</span>
</h1>
@@ -878,11 +878,11 @@ export function AppShell({ canLogout }: AppShellProps) {
)}
</div>
<div className="flex flex-col gap-2 px-4 pb-3">
<div className="thot-session-navigation__primary-controls">
<Button
variant={currentNavigation === "core" ? "navigationActive" : "outline"}
size="sm"
className="w-full"
className="w-full min-w-0 max-w-full gap-[0.25rem] px-[0.75rem]"
aria-current={currentNavigation === "core" ? "page" : undefined}
data-navigation-state={preprocessingBlocksNewSession
? "unavailable"
@@ -897,15 +897,16 @@ export function AppShell({ canLogout }: AppShellProps) {
<Accordion.Root
value={adminNavigationValue}
onValueChange={setAdminNavigationValue}
className="rounded-lg border border-border/80 bg-card/45 p-1.5"
data-testid="administration-boundary"
className="min-w-0 max-w-full rounded-lg border border-border/80 bg-card/45 p-1.5"
>
<Accordion.Item value="administration">
<Accordion.Header className="m-0">
<Accordion.Item value="administration" className="min-w-0 max-w-full">
<Accordion.Header className="m-0 min-w-0 max-w-full">
<Accordion.Trigger
className={buttonVariants({
variant: !adminNavigationOpen && managementNavigationCurrent ? "navigationActive" : "outline",
size: "sm",
className: "w-full justify-between px-2.5",
className: "w-full min-w-0 max-w-full justify-between px-2.5",
})}
data-navigation-state={!adminNavigationOpen && managementNavigationCurrent ? "current" : "available"}
>
@@ -917,11 +918,11 @@ export function AppShell({ canLogout }: AppShellProps) {
/>
</Accordion.Trigger>
</Accordion.Header>
<Accordion.Panel className="grid gap-1.5 px-0.5 pt-1.5">
<Accordion.Panel className="grid min-w-0 max-w-full gap-1.5 px-0.5 pt-1.5">
<Button
variant={currentNavigation === "database" ? "navigationActive" : "outline"}
size="sm"
className="w-full"
className="w-full min-w-0 max-w-full gap-[0.25rem] px-[0.75rem]"
aria-current={currentNavigation === "database" ? "page" : undefined}
data-navigation-state={currentNavigation === "database" ? "current" : canManageDatabase ? "available" : "unavailable"}
disabled={!canManageDatabase}
@@ -937,7 +938,7 @@ export function AppShell({ canLogout }: AppShellProps) {
<Button
variant={currentNavigation === "workspace" ? "navigationActive" : "outline"}
size="sm"
className="w-full"
className="w-full min-w-0 max-w-full gap-[0.25rem] px-[0.75rem]"
aria-current={currentNavigation === "workspace" ? "page" : undefined}
aria-expanded={activeManagementPanel === "workspace"}
data-navigation-state={currentNavigation === "workspace" ? "current" : "available"}
@@ -952,7 +953,7 @@ export function AppShell({ canLogout }: AppShellProps) {
<Button
variant={currentNavigation === "pi" ? "navigationActive" : "outline"}
size="sm"
className="w-full"
className="w-full min-w-0 max-w-full gap-[0.25rem] px-[0.75rem]"
aria-current={currentNavigation === "pi" ? "page" : undefined}
aria-expanded={activeManagementPanel === "pi"}
data-navigation-state={currentNavigation === "pi" ? "current" : canManagePi ? "available" : "unavailable"}
@@ -57,8 +57,8 @@ function StatusIcon({ state }: { state?: WorkspacePreprocessingState }) {
function PhaseProgress({ progress }: { progress: PreprocessingProgress }) {
const step = Math.max(1, Math.min(progress.step, progress.totalSteps));
return (
<div className="col-span-2 mt-1 grid gap-1">
<div className="flex items-center justify-between gap-2 text-[9px] leading-none">
<div className="col-span-2 mt-1 grid min-w-0 max-w-full gap-1">
<div className="flex min-w-0 max-w-full items-center justify-between gap-[0.5rem] text-[9px] leading-none">
<span className="min-w-0 truncate font-medium text-foreground">
{PROGRESS_LABELS[progress.stage]}
</span>
@@ -240,7 +240,7 @@ export function WorkspacePreprocessingControl({
<section
aria-label="Workspace preprocessing"
aria-busy={state === "running" || loading || clearMutation.isPending}
className="mt-0.5 border-t border-border/90 px-0.5 pt-2"
className="mt-0.5 min-w-0 max-w-full border-t border-border/90 px-0.5 pt-2"
>
<p className="mb-2 px-0.5 font-mono text-[9px] font-semibold uppercase tracking-[0.08em] text-primary">
Preprocessing
@@ -272,11 +272,11 @@ export function WorkspacePreprocessingControl({
<span><strong className="block text-foreground">Keep</strong><small className="text-muted-foreground">Memory and solved questions</small></span>
</div>
</div>
<div className="grid grid-cols-[0.78fr_1.22fr] gap-1.5">
<Button type="button" variant="outline" size="xs" className="h-7 text-[9px]" disabled={clearMutation.isPending} onClick={() => setConfirmingClear(false)}>
<div className="grid min-w-0 max-w-full grid-cols-[minmax(0,0.78fr)_minmax(0,1.22fr)] gap-1.5">
<Button type="button" variant="outline" size="xs" className="h-7 min-w-0 max-w-full px-[0.625rem] text-[9px]" disabled={clearMutation.isPending} onClick={() => setConfirmingClear(false)}>
Cancel
</Button>
<Button type="button" variant="destructive" size="xs" className="h-7 text-[9px]" disabled={clearMutation.isPending} onClick={() => clearMutation.mutate()}>
<Button type="button" variant="destructive" size="xs" className="h-7 min-w-0 max-w-full px-[0.625rem] text-[9px]" disabled={clearMutation.isPending} onClick={() => clearMutation.mutate()}>
{clearMutation.isPending ? <LoaderCircle aria-hidden="true" className="animate-spin motion-reduce:animate-none" /> : <Trash2 aria-hidden="true" />}
{clearMutation.isPending ? "Clearing" : "Clear derived data"}
</Button>
@@ -284,7 +284,7 @@ export function WorkspacePreprocessingControl({
</div>
) : (
<>
<div className="grid grid-cols-[1.25rem_minmax(0,1fr)] items-center gap-1.5">
<div className="grid min-w-0 max-w-full grid-cols-[1.25rem_minmax(0,1fr)] items-center gap-1.5">
<span className={`grid size-5 place-items-center rounded-full bg-muted ${stateClasses(state)}`}>
<StatusIcon state={state} />
</span>
@@ -293,12 +293,12 @@ export function WorkspacePreprocessingControl({
{state !== "running" && <span className="text-[9px] leading-tight text-muted-foreground" title={detail}>{detail}</span>}
</div>
{progress && <PhaseProgress progress={progress} />}
<div className="col-span-2 mt-0.5 grid grid-cols-[0.78fr_1.22fr] gap-1.5">
<div className="col-span-2 mt-0.5 grid min-w-0 max-w-full grid-cols-[minmax(0,0.78fr)_minmax(0,1.22fr)] gap-1.5">
<Button
type="button"
variant="outline"
size="xs"
className="h-7 px-2 text-[10px] hover:border-destructive/35 hover:bg-destructive/5 hover:text-destructive"
className="h-7 min-w-0 max-w-full px-[0.5rem] text-[10px] hover:border-destructive/35 hover:bg-destructive/5 hover:text-destructive"
disabled={!clearable}
title={!canManage ? "Database management permission is required" : undefined}
onClick={() => setConfirmingClear(true)}
@@ -309,7 +309,7 @@ export function WorkspacePreprocessingControl({
type="button"
variant="outline"
size="xs"
className="h-7 px-2 text-[10px]"
className="h-7 min-w-0 max-w-full px-[0.5rem] text-[10px]"
disabled={!actionable}
title={!canManage ? "Database management permission is required" : undefined}
onClick={() => mutation.mutate()}