Skip to content

Commit 5320a9b

Browse files
authored
fix(cloud-agent): improve workspace tab interaction affordances (#3462)
* fix(cloud-agent): improve workspace tab interaction affordances * fix(cloud-agent): remove chat tab attention dot
1 parent b95216e commit 5320a9b

2 files changed

Lines changed: 25 additions & 24 deletions

File tree

apps/web/src/components/cloud-agent-next/CloudAgentWorkspaceTabs.tsx

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { Button } from '@/components/ui/button';
44
import { cn } from '@/lib/utils';
5-
import { MessageSquare, Plus, Terminal, X } from 'lucide-react';
5+
import { MessageSquare, Terminal, X } from 'lucide-react';
66
import { CHAT_TAB_ID, terminalTabId } from './terminal-tabs';
77
import type { TerminalWorkspaceTab, WorkspaceTabId } from './terminal-tabs';
88

@@ -11,18 +11,16 @@ type TerminalStatusSummary = {
1111
statusText: string;
1212
};
1313

14-
function statusDotClass(status: TerminalStatusSummary['status'] | 'chat-active'): string {
14+
function statusDotClass(status: TerminalStatusSummary['status']): string {
1515
if (status === 'connected') return 'bg-emerald-500';
1616
if (status === 'error' || status === 'exited') return 'bg-destructive';
17-
if (status === 'chat-active') return 'bg-primary';
1817
return 'bg-amber-500';
1918
}
2019

2120
export function CloudAgentWorkspaceTabs({
2221
activeTabId,
2322
terminals,
2423
terminalStatuses,
25-
chatNeedsAttention,
2624
canCreateTerminal,
2725
onSelectTab,
2826
onCreateTerminal,
@@ -32,13 +30,14 @@ export function CloudAgentWorkspaceTabs({
3230
activeTabId: WorkspaceTabId;
3331
terminals: TerminalWorkspaceTab[];
3432
terminalStatuses: Record<string, TerminalStatusSummary | undefined>;
35-
chatNeedsAttention: boolean;
3633
canCreateTerminal: boolean;
3734
onSelectTab: (tabId: WorkspaceTabId) => void;
3835
onCreateTerminal: () => void;
3936
onCloseTerminal: (terminalId: string) => void;
4037
className?: string;
4138
}) {
39+
const chatActive = activeTabId === CHAT_TAB_ID;
40+
4241
return (
4342
<div
4443
role="tablist"
@@ -48,17 +47,18 @@ export function CloudAgentWorkspaceTabs({
4847
<Button
4948
type="button"
5049
size="sm"
51-
variant={activeTabId === CHAT_TAB_ID ? 'secondary' : 'ghost'}
52-
className="h-8 shrink-0 gap-2"
50+
variant={chatActive ? 'secondary' : 'ghost'}
51+
className={cn(
52+
'h-8 shrink-0 gap-2',
53+
chatActive ? 'cursor-default hover:bg-secondary' : 'cursor-pointer'
54+
)}
5355
role="tab"
54-
aria-selected={activeTabId === CHAT_TAB_ID}
55-
onClick={() => onSelectTab(CHAT_TAB_ID)}
56+
aria-selected={chatActive}
57+
aria-disabled={chatActive || undefined}
58+
onClick={chatActive ? undefined : () => onSelectTab(CHAT_TAB_ID)}
5659
>
5760
<MessageSquare className="h-4 w-4" />
5861
<span>Chat</span>
59-
{chatNeedsAttention && (
60-
<span className={cn('h-2 w-2 rounded-full', statusDotClass('chat-active'))} />
61-
)}
6262
</Button>
6363

6464
{terminals.map(tab => {
@@ -78,8 +78,12 @@ export function CloudAgentWorkspaceTabs({
7878
type="button"
7979
role="tab"
8080
aria-selected={active}
81-
className="flex h-full min-w-0 items-center gap-2 rounded-l-md px-2 text-sm font-medium"
82-
onClick={() => onSelectTab(tabId)}
81+
aria-disabled={active || undefined}
82+
className={cn(
83+
'flex h-full min-w-0 items-center gap-2 rounded-l-md px-2 text-sm font-medium focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring',
84+
active ? 'cursor-default' : 'cursor-pointer'
85+
)}
86+
onClick={active ? undefined : () => onSelectTab(tabId)}
8387
>
8488
<Terminal className="h-4 w-4 shrink-0" />
8589
<span className="max-w-32 truncate">{tab.title}</span>
@@ -88,7 +92,7 @@ export function CloudAgentWorkspaceTabs({
8892
<button
8993
type="button"
9094
aria-label={`Close ${tab.title}`}
91-
className="hover:bg-muted flex h-full w-7 shrink-0 items-center justify-center rounded-r-md"
95+
className="hover:bg-muted flex h-full w-7 shrink-0 cursor-pointer items-center justify-center rounded-r-md focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
9296
onClick={() => onCloseTerminal(tab.id)}
9397
>
9498
<X className="h-3.5 w-3.5" />
@@ -100,13 +104,15 @@ export function CloudAgentWorkspaceTabs({
100104
{canCreateTerminal && (
101105
<Button
102106
type="button"
103-
size="icon"
107+
size="sm"
104108
variant="ghost"
105-
className="h-8 w-8 shrink-0"
106-
aria-label="New terminal"
109+
className="text-muted-foreground hover:text-foreground h-8 shrink-0 gap-2 px-2"
107110
onClick={onCreateTerminal}
108111
>
109-
<Plus className="h-4 w-4" />
112+
<span aria-hidden="true" className="font-jetbrains text-xs">
113+
{'>_'}
114+
</span>
115+
<span>New terminal</span>
110116
</Button>
111117
)}
112118
</div>

apps/web/src/components/cloud-agent-next/CloudChatPage.tsx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,6 @@ export default function CloudChatPage({ organizationId }: CloudChatPageProps) {
443443
[]
444444
);
445445

446-
const chatNeedsAttention = Boolean(activeQuestion || activePermission || statusIndicator);
447-
448446
const terminalPaneMap = workspaceTabs.terminals.map(tab => {
449447
const active = terminalTabId(tab.id) === workspaceTabs.activeTabId;
450448
return (
@@ -661,9 +659,6 @@ export default function CloudChatPage({ organizationId }: CloudChatPageProps) {
661659
activeTabId={workspaceTabs.activeTabId}
662660
terminals={workspaceTabs.terminals}
663661
terminalStatuses={terminalStatuses}
664-
chatNeedsAttention={
665-
chatNeedsAttention && workspaceTabs.activeTabId !== CHAT_TAB_ID
666-
}
667662
canCreateTerminal={canOpenTerminal}
668663
onSelectTab={handleSelectWorkspaceTab}
669664
onCreateTerminal={handleCreateTerminalTab}

0 commit comments

Comments
 (0)