mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
Fixes unsaved changes prompt on unchanged settings (#8230).
This commit is contained in:
parent
cfb6041648
commit
cc47997ca7
3 changed files with 28 additions and 5 deletions
|
|
@ -171,7 +171,8 @@ const ApiOptions = ({
|
|||
|
||||
// Only update if the processed object is different from the current config.
|
||||
if (JSON.stringify(currentConfigHeaders) !== JSON.stringify(newHeadersObject)) {
|
||||
setApiConfigurationField("openAiHeaders", newHeadersObject)
|
||||
// Pass false to indicate this is automatic sync, not a user action
|
||||
setApiConfigurationField("openAiHeaders", newHeadersObject, false)
|
||||
}
|
||||
},
|
||||
300,
|
||||
|
|
|
|||
|
|
@ -256,9 +256,23 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
|
|||
|
||||
const previousValue = prevState.apiConfiguration?.[field]
|
||||
|
||||
// Helper to check if two values are semantically equal
|
||||
const areValuesEqual = (a: any, b: any): boolean => {
|
||||
// Same reference
|
||||
if (a === b) return true
|
||||
// Both null/undefined
|
||||
if (a == null && b == null) return true
|
||||
// Different types
|
||||
if (typeof a !== typeof b) return false
|
||||
// For objects/arrays, do deep comparison via JSON (good enough for settings)
|
||||
if (typeof a === "object" && typeof b === "object") {
|
||||
return JSON.stringify(a) === JSON.stringify(b)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Only skip change detection for automatic initialization (not user actions)
|
||||
// This prevents the dirty state when the component initializes and auto-syncs values
|
||||
// Treat undefined, null, and empty string as uninitialized states
|
||||
const isInitialSync =
|
||||
!isUserAction &&
|
||||
(previousValue === undefined || previousValue === "" || previousValue === null) &&
|
||||
|
|
@ -266,7 +280,10 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
|
|||
value !== "" &&
|
||||
value !== null
|
||||
|
||||
if (!isInitialSync) {
|
||||
// Also skip if it's an automatic sync with semantically equal values
|
||||
const isAutomaticNoOpSync = !isUserAction && areValuesEqual(previousValue, value)
|
||||
|
||||
if (!isInitialSync && !isAutomaticNoOpSync) {
|
||||
setChangeDetected(true)
|
||||
}
|
||||
return { ...prevState, apiConfiguration: { ...prevState.apiConfiguration, [field]: value } }
|
||||
|
|
|
|||
|
|
@ -24,7 +24,11 @@ import { ThinkingBudget } from "../ThinkingBudget"
|
|||
|
||||
type OpenAICompatibleProps = {
|
||||
apiConfiguration: ProviderSettings
|
||||
setApiConfigurationField: (field: keyof ProviderSettings, value: ProviderSettings[keyof ProviderSettings]) => void
|
||||
setApiConfigurationField: <K extends keyof ProviderSettings>(
|
||||
field: K,
|
||||
value: ProviderSettings[K],
|
||||
isUserAction?: boolean,
|
||||
) => void
|
||||
organizationAllowList: OrganizationAllowList
|
||||
modelValidationError?: string
|
||||
simplifySettings?: boolean
|
||||
|
|
@ -88,7 +92,8 @@ export const OpenAICompatible = ({
|
|||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
const headerObject = convertHeadersToObject(customHeaders)
|
||||
setApiConfigurationField("openAiHeaders", headerObject)
|
||||
// Pass false to indicate this is automatic sync, not a user action
|
||||
setApiConfigurationField("openAiHeaders", headerObject, false)
|
||||
}, 300)
|
||||
|
||||
return () => clearTimeout(timer)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue