fix(desktop): resync fallback editor after config reload
Some checks are pending
CI / Detect affected areas (push) Waiting to run
CI / Python tests (push) Blocked by required conditions
CI / Python lints (push) Blocked by required conditions
CI / TypeScript (push) Blocked by required conditions
CI / Docs Site (push) Blocked by required conditions
CI / Deny unrelated histories (push) Blocked by required conditions
CI / Check contributors (push) Blocked by required conditions
CI / Check uv.lock (push) Blocked by required conditions
CI / Lint Docker scripts (push) Blocked by required conditions
CI / Build&Test Docker image (push) Blocked by required conditions
CI / Supply-chain scan (push) Blocked by required conditions
CI / OSV scan (push) Waiting to run
CI / All required checks pass (push) Blocked by required conditions
CI / CI timing report (push) Blocked by required conditions
Deploy Site / deploy-vercel (push) Waiting to run
Deploy Site / deploy-docs (push) Waiting to run

This commit is contained in:
teknium1 2026-07-12 01:12:10 -07:00 committed by Teknium
parent bf3667aeec
commit 7b5ba20547
2 changed files with 33 additions and 1 deletions

View file

@ -43,6 +43,23 @@ async function renderField(value: unknown, onChange = vi.fn()) {
return onChange
}
async function renderFieldWithRerender(value: unknown, onChange = vi.fn()) {
const { FallbackModelsField } = await import('./fallback-models-field')
const client = new QueryClient({ defaultOptions: { queries: { retry: false } } })
const view = render(
<QueryClientProvider client={client}>
<FallbackModelsField onChange={onChange} value={value} />
</QueryClientProvider>
)
return (next: unknown) =>
view.rerender(
<QueryClientProvider client={client}>
<FallbackModelsField onChange={onChange} value={next} />
</QueryClientProvider>
)
}
const CHAIN = [
{ provider: 'copilot', model: 'gpt-5-mini' },
{ provider: 'openai-codex', model: 'gpt-5.4-mini' }
@ -84,4 +101,13 @@ describe('FallbackModelsField', () => {
expect(screen.getByText(/No fallback models/)).toBeTruthy()
expect(screen.queryAllByLabelText('Remove')).toHaveLength(0)
})
it('resyncs rows when persisted config changes', async () => {
const rerender = await renderFieldWithRerender(CHAIN)
expect(screen.getAllByLabelText('Remove')).toHaveLength(2)
rerender([{ provider: 'nous', model: 'hermes-4' }])
await waitFor(() => expect(screen.getAllByLabelText('Remove')).toHaveLength(1))
})
})

View file

@ -1,5 +1,5 @@
import { useQuery } from '@tanstack/react-query'
import { useState } from 'react'
import { useEffect, useState } from 'react'
import { Button } from '@/components/ui/button'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
@ -70,6 +70,12 @@ export function FallbackModelsField({
const [rows, setRows] = useState<FallbackEntry[]>(() => normalizeEntries(value))
// Settings can reload after a profile/config change while this component
// stays mounted. Avoid displaying or saving the previous profile's chain.
useEffect(() => {
setRows(normalizeEntries(value))
}, [value])
const commit = (next: FallbackEntry[]) => {
setRows(next)
onChange(next.filter(entry => entry.provider && entry.model))