fix: prevent common config modal infinite reopen loop and add draft editing

The auto-open useEffect in CodexConfigEditor and GeminiConfigEditor
created an inescapable loop: commonConfigError triggered modal open,
closing the modal didn't clear the error, so the effect immediately
reopened it — locking the entire UI.

- Remove auto-open useEffect from both Codex and Gemini config editors
- Convert common config modals to draft editing (edit locally, validate
  before save) instead of persisting on every keystroke
- Add TOML/JSON pre-validation via parseCommonConfigSnippet before any
  merge operation to prevent invalid content from being persisted
- Expose clearCommonConfigError so editors can clear stale errors on
  modal close
This commit is contained in:
Jason
2026-03-11 14:40:14 +08:00
parent 4ac7e28b10
commit 239c6fb2d7
9 changed files with 596 additions and 204 deletions
@@ -447,6 +447,7 @@ export function ProviderForm({
handleCommonConfigSnippetChange: handleCodexCommonConfigSnippetChange,
isExtracting: isCodexExtracting,
handleExtract: handleCodexExtract,
clearCommonConfigError: clearCodexCommonConfigError,
} = useCodexCommonConfig({
codexConfig,
onConfigChange: handleCodexConfigChange,
@@ -530,6 +531,7 @@ export function ProviderForm({
handleCommonConfigSnippetChange: handleGeminiCommonConfigSnippetChange,
isExtracting: isGeminiExtracting,
handleExtract: handleGeminiExtract,
clearCommonConfigError: clearGeminiCommonConfigError,
} = useGeminiCommonConfig({
envValue: geminiEnv,
onEnvChange: handleGeminiEnvChange,
@@ -1467,6 +1469,7 @@ export function ProviderForm({
onCommonConfigToggle={handleCodexCommonConfigToggle}
commonConfigSnippet={codexCommonConfigSnippet}
onCommonConfigSnippetChange={handleCodexCommonConfigSnippetChange}
onCommonConfigErrorClear={clearCodexCommonConfigError}
commonConfigError={codexCommonConfigError}
authError={codexAuthError}
configError={codexConfigError}
@@ -1488,6 +1491,7 @@ export function ProviderForm({
onCommonConfigSnippetChange={
handleGeminiCommonConfigSnippetChange
}
onCommonConfigErrorClear={clearGeminiCommonConfigError}
commonConfigError={geminiCommonConfigError}
envError={envError}
configError={geminiConfigError}