fix(ui): unify Session navigation and restore uniform tab borders

This commit is contained in:
Codex
2026-09-13 16:22:20 +02:00
parent 45db3a239b
commit 2953f6b608
17 changed files with 174 additions and 59 deletions
+12 -8
View File
@@ -61,7 +61,7 @@ interface AppShellProps {
const SESSION_SCOPES: readonly SessionScope[] = ["mine", "all"];
function sessionScopeTabClass(selected: boolean): string {
const base = "relative -mb-px flex h-8 w-full cursor-pointer items-center justify-center rounded-t-md border border-b-0 px-2 text-xs font-semibold tracking-[0.005em] outline-none focus-visible:z-10 focus-visible:ring-3 focus-visible:ring-[oklch(var(--nav-active-border)/0.28)]";
const base = "relative flex min-h-[38px] w-full cursor-pointer items-center justify-center rounded-md border px-[11px] py-[3px] text-xs font-semibold tracking-[0.005em] outline-none focus-visible:z-10 focus-visible:ring-3 focus-visible:ring-[oklch(var(--nav-active-border)/0.28)]";
return selected
? `${base} border-[oklch(var(--nav-active-border))] bg-[oklch(var(--nav-active))] text-[oklch(var(--nav-active-foreground))] hover:bg-[oklch(var(--nav-active-hover))]`
: `${base} border-border bg-card text-muted-foreground hover:border-muted-foreground/45 hover:bg-muted/55 hover:text-foreground`;
@@ -638,6 +638,8 @@ export function AppShell({ canLogout }: AppShellProps) {
deliveredToastCountRef.current = sessionToasts.length;
}, [sessionToasts]);
const sessionViewOpen = Boolean(activeSessionId) || creatingSession;
const canReturnToCurrentSession = creatingSession || (Boolean(activeSessionId) && !finalized && !activeSession?.archived);
const sessionActionUnavailable = !canReturnToCurrentSession && (preprocessingBlocksNewSession || !workingContext.ready || administrationBusy);
const working = sessionViewOpen && !pendingWidget && agentActive;
// The workflow bar runs only while the harness works, not while a finalized
// session sits idle or a gate awaits the reviewer (pendingWidget).
@@ -965,19 +967,21 @@ export function AppShell({ canLogout }: AppShellProps) {
</div>
<div className="thot-session-navigation__primary-controls">
{activeSurface !== "core" && <Button variant="outline" size="sm" className="w-full" onClick={() => navigate({ surface: "core" })}>{t("Return to session")}</Button>}
<Button
variant={currentNavigation === "core" ? "navigationActive" : "outline"}
size="sm"
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 || !workingContext.ready || administrationBusy
data-navigation-state={sessionActionUnavailable
? "unavailable"
: currentNavigation === "core" ? "current" : "available"}
disabled={preprocessingBlocksNewSession || !workingContext.ready || administrationBusy}
title={preprocessingBlocksNewSession ? preprocessingQuery.data?.detail : undefined}
onClick={startNewSession}
>{t("New session")}</Button>
disabled={sessionActionUnavailable}
title={sessionActionUnavailable && preprocessingBlocksNewSession ? preprocessingQuery.data?.detail : undefined}
onClick={() => {
if (canReturnToCurrentSession) navigate({ surface: "core" });
else startNewSession();
}}
>{t("Session")}</Button>
{isAdmin && (
<Accordion.Root
value={adminNavigationValue}
@@ -1075,7 +1079,7 @@ export function AppShell({ canLogout }: AppShellProps) {
role="tablist"
aria-label={t("Session scope")}
aria-orientation="horizontal"
className="grid grid-cols-2 border-b border-border"
className="grid grid-cols-2 gap-1"
>
<button
ref={(node) => { sessionScopeTabRefs.current.mine = node; }}