Files
CC-Switch/src/components/providers/forms/GeminiConfigEditor.tsx
T
Jason 239c6fb2d7 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
2026-03-11 14:40:14 +08:00

83 lines
2.2 KiB
TypeScript

import React, { useState } from "react";
import { GeminiEnvSection, GeminiConfigSection } from "./GeminiConfigSections";
import { GeminiCommonConfigModal } from "./GeminiCommonConfigModal";
interface GeminiConfigEditorProps {
envValue: string;
configValue: string;
onEnvChange: (value: string) => void;
onConfigChange: (value: string) => void;
onEnvBlur?: () => void;
useCommonConfig: boolean;
onCommonConfigToggle: (checked: boolean) => void;
commonConfigSnippet: string;
onCommonConfigSnippetChange: (value: string) => boolean;
onCommonConfigErrorClear: () => void;
commonConfigError: string;
envError: string;
configError: string;
onExtract?: () => void;
isExtracting?: boolean;
}
const GeminiConfigEditor: React.FC<GeminiConfigEditorProps> = ({
envValue,
configValue,
onEnvChange,
onConfigChange,
onEnvBlur,
useCommonConfig,
onCommonConfigToggle,
commonConfigSnippet,
onCommonConfigSnippetChange,
onCommonConfigErrorClear,
commonConfigError,
envError,
configError,
onExtract,
isExtracting,
}) => {
const [isCommonConfigModalOpen, setIsCommonConfigModalOpen] = useState(false);
const handleCloseCommonConfigModal = () => {
onCommonConfigErrorClear();
setIsCommonConfigModalOpen(false);
};
return (
<div className="space-y-6">
{/* Env Section */}
<GeminiEnvSection
value={envValue}
onChange={onEnvChange}
onBlur={onEnvBlur}
error={envError}
useCommonConfig={useCommonConfig}
onCommonConfigToggle={onCommonConfigToggle}
onEditCommonConfig={() => setIsCommonConfigModalOpen(true)}
commonConfigError={commonConfigError}
/>
{/* Config JSON Section */}
<GeminiConfigSection
value={configValue}
onChange={onConfigChange}
configError={configError}
/>
{/* Common Config Modal */}
<GeminiCommonConfigModal
isOpen={isCommonConfigModalOpen}
onClose={handleCloseCommonConfigModal}
value={commonConfigSnippet}
onSave={onCommonConfigSnippetChange}
error={commonConfigError}
onExtract={onExtract}
isExtracting={isExtracting}
/>
</div>
);
};
export default GeminiConfigEditor;