Skip to content

Commit b897a90

Browse files
committed
feat(flow-chat): keep background commands accessible when idle
- Allow the background command panel to open without active commands. - Render a localized empty state and hide unavailable bulk actions. - Add coverage for the idle background command panel.
1 parent 765e11e commit b897a90

6 files changed

Lines changed: 45 additions & 12 deletions

File tree

src/web-ui/src/flow_chat/components/modern/FlowChatHeader.scss

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,17 @@
269269
scrollbar-gutter: stable;
270270
}
271271

272+
&__background-command-empty-state {
273+
min-height: 48px;
274+
display: flex;
275+
align-items: center;
276+
justify-content: center;
277+
padding: $size-gap-3;
278+
color: var(--bf-appearance-token-color-text-secondary);
279+
font-size: var(--bf-appearance-token-flowchat-font-size-xs);
280+
text-align: center;
281+
}
282+
272283
&__background-command-list-item-button {
273284
display: flex;
274285
flex-direction: column;

src/web-ui/src/flow_chat/components/modern/FlowChatHeader.test.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,24 @@ describe('FlowChatHeader', () => {
157157
expect(treeContainer?.nextElementSibling).toBe(commandContainer);
158158
});
159159

160+
it('opens the background command panel when no commands exist', () => {
161+
act(() => {
162+
root.render(<FlowChatHeader {...createProps()} />);
163+
});
164+
165+
const commandButton = container.querySelector<HTMLButtonElement>(
166+
'[data-testid="flowchat-header-background-commands"]',
167+
);
168+
expect(commandButton?.disabled).toBe(false);
169+
170+
act(() => {
171+
commandButton?.click();
172+
});
173+
174+
const panel = container.querySelector('.flowchat-header__background-command-panel');
175+
expect(panel?.textContent).toContain('flowChatHeader.backgroundCommandEmpty');
176+
});
177+
160178
it('renders background command menus in a portal outside the scrollable panel', () => {
161179
const onStopBackgroundCommand = vi.fn();
162180
const onStopAllBackgroundCommands = vi.fn();

src/web-ui/src/flow_chat/components/modern/FlowChatHeader.tsx

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,11 @@ export const FlowChatHeader: React.FC<FlowChatHeaderProps> = ({
220220
}, [searchOpenRequest]);
221221

222222
useEffect(() => {
223-
if (!hasBackgroundCommands) {
224-
setIsBackgroundCommandPanelOpen(false);
225-
setIsBackgroundCommandSectionMenuOpen(false);
226-
setOpenBackgroundCommandMenuId(null);
227-
setBackgroundCommandMenuPosition(null);
228-
}
223+
if (hasBackgroundCommands) return;
224+
225+
setIsBackgroundCommandSectionMenuOpen(false);
226+
setOpenBackgroundCommandMenuId(null);
227+
setBackgroundCommandMenuPosition(null);
229228
}, [hasBackgroundCommands]);
230229

231230
useEffect(() => {
@@ -299,7 +298,6 @@ export const FlowChatHeader: React.FC<FlowChatHeaderProps> = ({
299298
);
300299

301300
const handleToggleBackgroundCommandPanel = () => {
302-
if (!hasBackgroundCommands) return;
303301
setIsBackgroundCommandSectionMenuOpen(false);
304302
setOpenBackgroundCommandMenuId(null);
305303
setIsBackgroundCommandPanelOpen(prev => !prev);
@@ -535,7 +533,6 @@ export const FlowChatHeader: React.FC<FlowChatHeaderProps> = ({
535533
size="xs"
536534
onClick={handleToggleBackgroundCommandPanel}
537535
tooltip={backgroundCommandLabel}
538-
disabled={!hasBackgroundCommands}
539536
aria-label={backgroundCommandLabel}
540537
aria-expanded={isBackgroundCommandPanelOpen}
541538
aria-haspopup="dialog"
@@ -552,7 +549,7 @@ export const FlowChatHeader: React.FC<FlowChatHeaderProps> = ({
552549
</span>
553550
</IconButton>
554551

555-
{isBackgroundCommandPanelOpen && hasBackgroundCommands && (
552+
{isBackgroundCommandPanelOpen && (
556553
<div
557554
className="flowchat-header__background-command-panel"
558555
data-bf-component="flow-chat-header"
@@ -563,7 +560,7 @@ export const FlowChatHeader: React.FC<FlowChatHeaderProps> = ({
563560
<div className="flowchat-header__background-command-panel-header">
564561
<span>{backgroundCommandLabel}</span>
565562
<div className="flowchat-header__background-command-panel-header-actions">
566-
{onStopAllBackgroundCommands ? (
563+
{hasBackgroundCommands && onStopAllBackgroundCommands ? (
567564
<IconButton
568565
className="flowchat-header__background-command-menu-button"
569566
variant="ghost"
@@ -612,7 +609,7 @@ export const FlowChatHeader: React.FC<FlowChatHeaderProps> = ({
612609
data-bf-component="flow-chat-header"
613610
data-bf-part="activitySection"
614611
>
615-
{displayBackgroundCommands.map((command) => (
612+
{hasBackgroundCommands ? displayBackgroundCommands.map((command) => (
616613
<div
617614
key={command.execSessionKey}
618615
className="flowchat-header__background-command-list-item"
@@ -637,7 +634,11 @@ export const FlowChatHeader: React.FC<FlowChatHeaderProps> = ({
637634
</button>
638635
{renderBackgroundCommandActions(command)}
639636
</div>
640-
))}
637+
)) : (
638+
<div className="flowchat-header__background-command-empty-state">
639+
{t('flowChatHeader.backgroundCommandEmpty')}
640+
</div>
641+
)}
641642
</div>
642643
</div>
643644
)}

src/web-ui/src/locales/en-US/flow-chat.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,7 @@
12571257
"idle": "Idle"
12581258
},
12591259
"backgroundCommands": "Background commands ({{count}})",
1260+
"backgroundCommandEmpty": "No background commands",
12601261
"backgroundCommandUntitled": "Background command",
12611262
"backgroundCommandSession": "Session #{{id}}",
12621263
"backgroundCommandStatusRunning": "Active",

src/web-ui/src/locales/zh-CN/flow-chat.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,7 @@
12571257
"idle": "空闲"
12581258
},
12591259
"backgroundCommands": "后台命令({{count}})",
1260+
"backgroundCommandEmpty": "暂无后台命令",
12601261
"backgroundCommandUntitled": "后台命令",
12611262
"backgroundCommandSession": "会话 #{{id}}",
12621263
"backgroundCommandStatusRunning": "进行中",

src/web-ui/src/locales/zh-TW/flow-chat.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,7 @@
12571257
"idle": "閒置"
12581258
},
12591259
"backgroundCommands": "背景命令({{count}})",
1260+
"backgroundCommandEmpty": "目前沒有背景命令",
12601261
"backgroundCommandUntitled": "背景命令",
12611262
"backgroundCommandSession": "會話 #{{id}}",
12621263
"backgroundCommandStatusRunning": "進行中",

0 commit comments

Comments
 (0)