refactor: create modular hooks and integrate API key input

- Create custom hooks for state management:
  - useProviderCategory: manages provider category state
  - useApiKeyState: manages API key input with auto-sync to config
  - useBaseUrlState: manages base URL for Claude and Codex
  - useModelState: manages model selection state

- Integrate API key input into simplified ProviderForm:
  - Add ApiKeyInput component for Claude mode
  - Auto-populate API key into settings config
  - Disable for official providers

- Fix EndpointSpeedTest type errors:
  - Fix import paths to use @ alias
  - Add temporary type definitions
  - Format all TODO comments properly
  - Remove incorrect type assertions
  - Comment out unimplemented window.api checks

All TypeScript type checks now pass.
This commit is contained in:
Jason
2025-10-16 17:40:25 +08:00
parent 2c1346a23d
commit 98c35c7c62
13 changed files with 2322 additions and 2 deletions

View File

@@ -23,6 +23,8 @@ import {
type CodexProviderPreset,
} from "@/config/codexProviderPresets";
import { applyTemplateValues } from "@/utils/providerConfigUtils";
import ApiKeyInput from "@/components/ProviderForm/ApiKeyInput";
import { useProviderCategory, useApiKeyState } from "./hooks";
const CLAUDE_DEFAULT_CONFIG = JSON.stringify({ env: {}, config: {} }, null, 2);
const CODEX_DEFAULT_CONFIG = JSON.stringify({ auth: {}, config: "" }, null, 2);
@@ -53,6 +55,8 @@ export function ProviderForm({
}: ProviderFormProps) {
const { t } = useTranslation();
const { theme } = useTheme();
const isEditMode = Boolean(initialData);
const [selectedPresetId, setSelectedPresetId] = useState<string | null>(
initialData ? null : "custom",
);
@@ -61,6 +65,13 @@ export function ProviderForm({
category?: ProviderCategory;
} | null>(null);
// 使用 category hook
const { category } = useProviderCategory({
appType,
selectedPresetId,
isEditMode,
});
useEffect(() => {
setSelectedPresetId(initialData ? null : "custom");
setActivePreset(null);
@@ -85,6 +96,13 @@ export function ProviderForm({
mode: "onSubmit",
});
// 使用 API Key hook
const { apiKey, handleApiKeyChange, showApiKey: shouldShowApiKey } = useApiKeyState({
initialConfig: form.watch("settingsConfig"),
onConfigChange: (config) => form.setValue("settingsConfig", config),
selectedPresetId,
});
useEffect(() => {
form.reset(defaultValues);
}, [defaultValues, form]);
@@ -303,6 +321,23 @@ export function ProviderForm({
)}
/>
{/* API Key 输入框(仅 Claude 且非编辑模式显示) */}
{appType === "claude" && shouldShowApiKey(form.watch("settingsConfig"), isEditMode) && (
<div>
<ApiKeyInput
value={apiKey}
onChange={handleApiKeyChange}
required={category !== "official"}
placeholder={
category === "official"
? t("providerForm.officialNoApiKey", { defaultValue: "官方供应商无需 API Key" })
: t("providerForm.apiKeyAutoFill", { defaultValue: "输入 API Key将自动填充到配置" })
}
disabled={category === "official"}
/>
</div>
)}
<FormField
control={form.control}
name="settingsConfig"