mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-07 08:26:51 +00:00
fix: prevent false dirty state from headers in OpenAICompatible
Add deep equality check before calling setApiConfigurationField for openAiHeaders in OpenAICompatible.tsx. This prevents the Settings dialog from incorrectly showing an unsaved changes prompt when the headers have not actually changed. The fix follows the same pattern already used in ApiOptions.tsx, using JSON.stringify for deep equality comparison. Fixes #8230
This commit is contained in:
parent
503f40241d
commit
3d3b8c411e
2 changed files with 64 additions and 4 deletions
|
|
@ -84,17 +84,20 @@ export const OpenAICompatible = ({
|
|||
setCustomHeaders((prev) => prev.filter((_, i) => i !== index))
|
||||
}, [])
|
||||
|
||||
// Helper to convert array of tuples to object
|
||||
|
||||
// Add effect to update the parent component's state when local headers change
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
const currentConfigHeaders = apiConfiguration?.openAiHeaders || {}
|
||||
const headerObject = convertHeadersToObject(customHeaders)
|
||||
setApiConfigurationField("openAiHeaders", headerObject)
|
||||
|
||||
// Only update if the processed object is different from the current config.
|
||||
if (JSON.stringify(currentConfigHeaders) !== JSON.stringify(headerObject)) {
|
||||
setApiConfigurationField("openAiHeaders", headerObject)
|
||||
}
|
||||
}, 300)
|
||||
|
||||
return () => clearTimeout(timer)
|
||||
}, [customHeaders, setApiConfigurationField])
|
||||
}, [customHeaders, apiConfiguration?.openAiHeaders, setApiConfigurationField])
|
||||
|
||||
const handleInputChange = useCallback(
|
||||
<K extends keyof ProviderSettings, E>(
|
||||
|
|
|
|||
|
|
@ -313,3 +313,60 @@ describe("OpenAICompatible Component - includeMaxTokens checkbox", () => {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("OpenAICompatible Component - Headers dirty state fix", () => {
|
||||
const mockSetApiConfigurationField = vi.fn()
|
||||
const mockOrganizationAllowList = {
|
||||
allowAll: true,
|
||||
providers: {},
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
vi.useFakeTimers()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers()
|
||||
})
|
||||
|
||||
it("should not call setApiConfigurationField when headers have not changed", async () => {
|
||||
const apiConfiguration: Partial<ProviderSettings> = {
|
||||
openAiHeaders: { "X-Test": "value" },
|
||||
}
|
||||
|
||||
render(
|
||||
<OpenAICompatible
|
||||
apiConfiguration={apiConfiguration as ProviderSettings}
|
||||
setApiConfigurationField={mockSetApiConfigurationField}
|
||||
organizationAllowList={mockOrganizationAllowList}
|
||||
/>,
|
||||
)
|
||||
|
||||
// Wait for the debounced update
|
||||
vi.advanceTimersByTime(350)
|
||||
|
||||
// setApiConfigurationField should NOT be called because the headers haven't changed
|
||||
expect(mockSetApiConfigurationField).not.toHaveBeenCalledWith("openAiHeaders", expect.anything())
|
||||
})
|
||||
|
||||
it("should not trigger dirty state on initial mount with empty headers", async () => {
|
||||
const apiConfiguration: Partial<ProviderSettings> = {
|
||||
openAiHeaders: {},
|
||||
}
|
||||
|
||||
render(
|
||||
<OpenAICompatible
|
||||
apiConfiguration={apiConfiguration as ProviderSettings}
|
||||
setApiConfigurationField={mockSetApiConfigurationField}
|
||||
organizationAllowList={mockOrganizationAllowList}
|
||||
/>,
|
||||
)
|
||||
|
||||
// Wait for the debounced update
|
||||
vi.advanceTimersByTime(350)
|
||||
|
||||
// setApiConfigurationField should NOT be called because the headers haven't changed
|
||||
expect(mockSetApiConfigurationField).not.toHaveBeenCalledWith("openAiHeaders", expect.anything())
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue