fix(ui): layouts responsive pour panneau agents et bandeau d'onglets sidebar
AgentsPanel : formulaire de création et items d'agent passent en colonne, les libellés/états longs (running in IdeA, profil) wrappent/tronquent au lieu de déborder. ProjectsView : les onglets de la sidebar wrappent sur plusieurs lignes pour rester tous visibles, le bouton collapse reste épinglé en haut. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -206,9 +206,9 @@ export function AgentsPanel({ projectId, projectRoot = "" }: AgentsPanelProps) {
|
||||
{/* ── Create form ── */}
|
||||
<form
|
||||
onSubmit={(e) => void handleCreate(e)}
|
||||
className="flex flex-wrap items-end gap-2 border-b border-border p-4"
|
||||
className="flex flex-col gap-3 border-b border-border p-4"
|
||||
>
|
||||
<div className="flex min-w-0 flex-1 flex-col gap-1">
|
||||
<div className="flex min-w-0 flex-col gap-1">
|
||||
<label
|
||||
htmlFor="agent-name-input"
|
||||
className="text-xs font-medium text-muted"
|
||||
@ -221,12 +221,12 @@ export function AgentsPanel({ projectId, projectRoot = "" }: AgentsPanelProps) {
|
||||
placeholder="My agent"
|
||||
value={newName}
|
||||
onChange={(e) => setNewName(e.target.value)}
|
||||
className="min-w-32"
|
||||
className="w-full"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Template selector */}
|
||||
<div className="flex min-w-0 flex-1 flex-col gap-1">
|
||||
<div className="flex min-w-0 flex-col gap-1">
|
||||
<label
|
||||
htmlFor="agent-template-select"
|
||||
className="text-xs font-medium text-muted"
|
||||
@ -256,7 +256,7 @@ export function AgentsPanel({ projectId, projectRoot = "" }: AgentsPanelProps) {
|
||||
|
||||
{/* Profile selector — hidden when a template is chosen */}
|
||||
{!hasTemplate && (
|
||||
<div className="flex min-w-0 flex-1 flex-col gap-1">
|
||||
<div className="flex min-w-0 flex-col gap-1">
|
||||
<label
|
||||
htmlFor="agent-profile-select"
|
||||
className="text-xs font-medium text-muted"
|
||||
@ -304,6 +304,7 @@ export function AgentsPanel({ projectId, projectRoot = "" }: AgentsPanelProps) {
|
||||
aria-label="create agent"
|
||||
disabled={!canCreate}
|
||||
loading={vm.busy}
|
||||
className="self-end"
|
||||
>
|
||||
Create
|
||||
</Button>
|
||||
@ -330,17 +331,17 @@ export function AgentsPanel({ projectId, projectRoot = "" }: AgentsPanelProps) {
|
||||
<li
|
||||
key={a.id}
|
||||
className={cn(
|
||||
"flex items-center justify-between gap-3 py-2 first:pt-0 last:pb-0",
|
||||
"flex flex-col gap-2 py-3 first:pt-0 last:pb-0",
|
||||
isSelected && "rounded-md bg-raised px-2",
|
||||
)}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => void vm.selectAgent(a.id)}
|
||||
className="flex min-w-0 flex-1 flex-col items-start gap-0.5 text-left"
|
||||
className="flex min-w-0 flex-col items-start gap-0.5 text-left"
|
||||
aria-pressed={isSelected}
|
||||
>
|
||||
<span className="flex items-center gap-2">
|
||||
<span className="flex min-w-0 max-w-full flex-wrap items-center gap-2">
|
||||
<span className="font-medium text-content">{a.name}</span>
|
||||
{agentDrift && (
|
||||
<span
|
||||
@ -366,13 +367,13 @@ export function AgentsPanel({ projectId, projectRoot = "" }: AgentsPanelProps) {
|
||||
</span>
|
||||
<span className="text-xs text-muted">{profileName}</span>
|
||||
{live && (
|
||||
<span className="text-xs text-primary">
|
||||
<span className="block w-full min-w-0 truncate text-xs text-primary">
|
||||
running in IdeA · {live.sessionId ?? live.nodeId}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
|
||||
<div className="flex items-center gap-1.5 shrink-0">
|
||||
<div className="flex flex-wrap items-center gap-1.5">
|
||||
{/* Profile hot-swap selector (Chantier A). Changing the
|
||||
engine abandons the conversation history → confirmation. */}
|
||||
{vm.profiles.length > 0 && (
|
||||
|
||||
@ -147,8 +147,12 @@ export function ProjectsView() {
|
||||
sidebarCollapsed && "hidden",
|
||||
)}
|
||||
>
|
||||
{/* Sidebar tab strip (no role="tablist" to avoid collision with project tabs) */}
|
||||
<div className="flex shrink-0 items-stretch border-b border-border">
|
||||
{/* Sidebar tab strip (no role="tablist" to avoid collision with project tabs).
|
||||
The tabs wrap onto multiple rows when they exceed the sidebar width
|
||||
so every label stays visible without scrolling; the collapse button
|
||||
stays pinned to the top-right. */}
|
||||
<div className="flex shrink-0 items-start border-b border-border">
|
||||
<div className="flex min-w-0 flex-1 flex-wrap items-stretch">
|
||||
{SIDEBAR_TABS.map((t) => (
|
||||
<button
|
||||
key={t.id}
|
||||
@ -156,7 +160,7 @@ export function ProjectsView() {
|
||||
aria-selected={sidebarTab === t.id}
|
||||
onClick={() => setSidebarTab(t.id)}
|
||||
className={cn(
|
||||
"flex-1 px-2 py-2 text-xs font-medium transition-colors",
|
||||
"shrink-0 whitespace-nowrap px-3 py-2 text-xs font-medium transition-colors",
|
||||
sidebarTab === t.id
|
||||
? "border-b-2 border-primary text-content"
|
||||
: "text-muted hover:text-content",
|
||||
@ -165,12 +169,13 @@ export function ProjectsView() {
|
||||
{t.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
aria-label="collapse sidebar"
|
||||
title="Collapse sidebar"
|
||||
onClick={() => setSidebarCollapsed(true)}
|
||||
className="shrink-0 px-2 text-muted hover:text-content"
|
||||
className="shrink-0 self-stretch border-l border-border px-2 text-muted hover:text-content"
|
||||
>
|
||||
«
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user