fix(chat): open chat name settings from naming failures (#34533)

* fix(chat): link naming failures to chat name settings

* fix(chat): hide naming settings link when controls are unavailable
This commit is contained in:
Jinjing
2026-10-27 14:27:53 -07:00
committed by GitHub
parent 9fd9cd7362
commit 54411a9a96
4 changed files with 73 additions and 5 deletions
@@ -0,0 +1,21 @@
import { defineFixture } from '../../component-fixtures/component-fixture'
import { NativeChatNamingErrorBlock } from './NativeChatNamingFailure'
export const failed = defineFixture({
width: 288,
render: () => (
<div className="w-64 rounded-md border border-border bg-popover p-3 text-xs text-popover-foreground">
<NativeChatNamingErrorBlock
naming={{
message: 'The selected model is not supported.',
canRegenerate: true,
regenerating: false,
regenerate: () => {},
dialogOpen: false,
setDialogOpen: () => {},
readFullOutput: async () => null
}}
/>
</div>
)
})
@@ -10,9 +10,20 @@ import { useNativeChatNamingFailure } from './use-native-chat-naming-failure'
const client = vi.hoisted(() => ({
supported: false,
web: false,
emit: (_event: AgentSessionStatusEvent) => {},
regenerate: vi.fn<() => Promise<boolean>>()
}))
const settings = vi.hoisted(() => ({
openSettingsPage: vi.fn(),
openSettingsTarget: vi.fn()
}))
vi.mock('@/store', () => ({
useAppStore: { getState: () => settings }
}))
vi.mock('@/lib/web-client-location', () => ({
isWebClientLocation: () => client.web
}))
vi.mock('@/runtime/structured-agent-session-client', () => ({
subscribeStructuredAgentSessionStatus: async (_target: unknown, emit: typeof client.emit) => {
client.emit = emit
@@ -60,6 +71,7 @@ async function hoverChatTab(): Promise<void> {
describe('chat tab naming failure', () => {
beforeEach(() => {
vi.useFakeTimers()
vi.clearAllMocks()
client.regenerate.mockResolvedValue(true)
})
afterEach(() => {
@@ -68,13 +80,30 @@ describe('chat tab naming failure', () => {
vi.useRealTimers()
})
it.each([true, false])(
'shows the error, with Regenerate name when the host has it: %s',
async (supported) => {
it.each([
{ supported: true, web: false },
{ supported: false, web: false },
{ supported: true, web: true },
{ supported: false, web: true }
])(
'shows recovery actions for host regeneration support=$supported, web=$web',
async ({ supported, web }) => {
client.supported = supported
client.web = web
await hoverChatTab()
expect(screen.getAllByText("Couldn't name this chat").length).toBeGreaterThan(0)
expect(screen.getAllByRole('button', { name: 'view error' }).length).toBeGreaterThan(0)
const settingsButtons = screen.queryAllByRole('button', { name: 'Settings' })
expect(settingsButtons.length > 0).toBe(!web)
if (!web) {
fireEvent.click(settingsButtons[0])
expect(settings.openSettingsPage).toHaveBeenCalledOnce()
expect(settings.openSettingsTarget).toHaveBeenCalledExactlyOnceWith({
pane: 'chat',
repoId: null,
sectionId: 'chat-names'
})
}
const regenerate = screen.queryAllByRole('button', { name: 'Regenerate name' })
expect(regenerate.length > 0).toBe(supported)
if (supported) {
@@ -1,5 +1,7 @@
import { AlertCircle, RefreshCw } from 'lucide-react'
import { AlertCircle, RefreshCw, Settings } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { useAppStore } from '@/store'
import { isWebClientLocation } from '@/lib/web-client-location'
import { NameGenerationFailedDialog } from '../sidebar/AutoRenameFailedDialog'
import { translate } from '@/i18n/i18n'
import type { NativeChatNamingFailureControls } from './use-native-chat-naming-failure'
@@ -27,7 +29,7 @@ export function NativeChatNamingErrorBlock({
'The chat-name agent stopped with an error, so the chat keeps its first message as its name.'
)}
</p>
<div className="flex items-center gap-1.5 pt-1 pl-4.5">
<div className="flex flex-wrap items-center gap-1.5 pt-1 pl-4.5">
<Button
type="button"
variant="destructive-chip"
@@ -49,6 +51,21 @@ export function NativeChatNamingErrorBlock({
{regenerateLabel(naming)}
</Button>
) : null}
{isWebClientLocation() ? null : (
<Button
type="button"
variant="ghost"
size="chip"
onClick={() => {
const store = useAppStore.getState()
store.openSettingsPage()
store.openSettingsTarget({ pane: 'chat', repoId: null, sectionId: 'chat-names' })
}}
>
<Settings aria-hidden />
{translate('tabHoverCard.namingFailure.settings', 'Settings')}
</Button>
)}
</div>
</div>
)
+1
View File
@@ -21457,6 +21457,7 @@
"title": "Couldn't name this chat",
"description": "The chat-name agent stopped with an error, so the chat keeps its first message as its name.",
"viewError": "view error",
"settings": "Settings",
"dialogTitle": "Chat auto-name failed",
"dialogDescriptionStart": "Orca couldn't generate a name for",
"dialogDescriptionEnd": "from its first message."