feat: implement template variables input functionality

- Create useTemplateValues hook to manage template variable state
- Support dynamic placeholder replacement in provider configs
- Add template parameter input UI in provider form
- Validate required template values before submission
- Auto-update config when template values change
This commit is contained in:
Jason
2025-10-16 20:25:39 +08:00
parent e4f85f4f65
commit 74afca7b58
3 changed files with 356 additions and 0 deletions

View File

@@ -37,6 +37,7 @@ import {
useApiKeyLink,
useCustomEndpoints,
useKimiModelSelector,
useTemplateValues,
} from "./hooks";
const CLAUDE_DEFAULT_CONFIG = JSON.stringify({ env: {}, config: {} }, null, 2);
@@ -228,7 +229,36 @@ export function ProviderForm({
: "",
});
// 使用模板变量 hook (仅 Claude 模式)
const {
templateValues,
templateValueEntries,
selectedPreset: templatePreset,
handleTemplateValueChange,
validateTemplateValues,
} = useTemplateValues({
selectedPresetId: appType === "claude" ? selectedPresetId : null,
presetEntries: appType === "claude" ? presetEntries : [],
settingsConfig: form.watch("settingsConfig"),
onConfigChange: (config) => form.setValue("settingsConfig", config),
});
const handleSubmit = (values: ProviderFormData) => {
// 验证模板变量(仅 Claude 模式)
if (appType === "claude" && templateValueEntries.length > 0) {
const validation = validateTemplateValues();
if (!validation.isValid && validation.missingField) {
form.setError("settingsConfig", {
type: "manual",
message: t("providerForm.fillParameter", {
label: validation.missingField.label,
defaultValue: `请填写 ${validation.missingField.label}`,
}),
});
return;
}
}
let settingsConfig: string;
// Codex: 组合 auth 和 config
@@ -510,6 +540,43 @@ export function ProviderForm({
</div>
)}
{/* 模板变量输入(仅 Claude 且有模板变量时显示) */}
{appType === "claude" && templateValueEntries.length > 0 && (
<div className="space-y-3">
<FormLabel>
{t("providerForm.parameterConfig", {
name: templatePreset?.name || "",
defaultValue: `${templatePreset?.name || ""} 参数配置`,
})}
</FormLabel>
<div className="space-y-4">
{templateValueEntries.map(([key, config]) => (
<div key={key} className="space-y-2">
<FormLabel htmlFor={`template-${key}`}>
{config.label}
</FormLabel>
<Input
id={`template-${key}`}
type="text"
required
value={
templateValues[key]?.editorValue ??
config.editorValue ??
config.defaultValue ??
""
}
onChange={(e) =>
handleTemplateValueChange(key, e.target.value)
}
placeholder={config.placeholder || config.label}
autoComplete="off"
/>
</div>
))}
</div>
</div>
)}
{/* Base URL 输入框(仅 Claude 第三方/自定义显示) */}
{appType === "claude" && shouldShowSpeedTest && (
<div className="space-y-2">