feat(ui): add quick-set button for model mapping fields (#2179)

* feat(ui): add quick-set button for model mapping fields

Add a "一键设置" (Quick Set) button in the model mapping section to
simplify provider configuration. When users enter a model name in any
of the five model fields, they can now click this button to populate
all fields with that same value.

This addresses the UX friction of manually filling all five model
mapping fields (主模型, 推理模型, Haiku, Sonnet, Opus) when the
provider uses the same model name across all request types.

Implementation:
- Add Wand2 icon import from lucide-react
- Insert quick-set button alongside existing fetch-models button
- Logic picks first non-empty model value and applies to all fields
- Show success toast after applying
- Disabled state when all model fields are empty
- Add i18n strings for zh, en, ja locales

Relates to user feedback about tedious model configuration workflow.

* style(ui): format ClaudeFormFields component code

Apply consistent code formatting to ClaudeFormFields.tsx following
project linting rules. Includes multi-line import statements and
improved readability for conditional expressions.
This commit is contained in:
King
2026-04-19 21:42:17 +08:00
committed by GitHub
parent 87635e7fc6
commit 8ba92b5470
4 changed files with 64 additions and 11 deletions
@@ -24,7 +24,13 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { ChevronDown, ChevronRight, Download, Loader2 } from "lucide-react";
import {
ChevronDown,
ChevronRight,
Download,
Loader2,
Wand2,
} from "lucide-react";
import EndpointSpeedTest from "./EndpointSpeedTest";
import { ApiKeySection, EndpointField, ModelInputWithFetch } from "./shared";
import { CopilotAuthSection } from "./CopilotAuthSection";
@@ -571,23 +577,64 @@ export function ClaudeFormFields({
<div className="space-y-1 pt-2 border-t">
<div className="flex items-center justify-between">
<FormLabel>{t("providerForm.modelMappingLabel")}</FormLabel>
{!isCopilotPreset && (
<div className="flex gap-2">
{/* 一键设置按钮 */}
<Button
type="button"
variant="outline"
size="sm"
onClick={handleFetchModels}
disabled={isFetchingModels}
onClick={() => {
const value =
claudeModel ||
reasoningModel ||
defaultHaikuModel ||
defaultSonnetModel ||
defaultOpusModel;
if (value) {
onModelChange("ANTHROPIC_MODEL", value);
onModelChange("ANTHROPIC_REASONING_MODEL", value);
onModelChange("ANTHROPIC_DEFAULT_HAIKU_MODEL", value);
onModelChange("ANTHROPIC_DEFAULT_SONNET_MODEL", value);
onModelChange("ANTHROPIC_DEFAULT_OPUS_MODEL", value);
toast.success(
t("providerForm.quickSetSuccess", {
defaultValue: "已将模型名称应用到所有字段",
}),
);
}
}}
disabled={
!claudeModel &&
!reasoningModel &&
!defaultHaikuModel &&
!defaultSonnetModel &&
!defaultOpusModel
}
className="h-7 gap-1"
>
{isFetchingModels ? (
<Loader2 className="h-3.5 w-3.5 animate-spin" />
) : (
<Download className="h-3.5 w-3.5" />
)}
{t("providerForm.fetchModels")}
<Wand2 className="h-3.5 w-3.5" />
{t("providerForm.quickSetModels", {
defaultValue: "一键设置",
})}
</Button>
)}
{!isCopilotPreset && (
<Button
type="button"
variant="outline"
size="sm"
onClick={handleFetchModels}
disabled={isFetchingModels}
className="h-7 gap-1"
>
{isFetchingModels ? (
<Loader2 className="h-3.5 w-3.5 animate-spin" />
) : (
<Download className="h-3.5 w-3.5" />
)}
{t("providerForm.fetchModels")}
</Button>
)}
</div>
</div>
<p className="text-xs text-muted-foreground">
{t("providerForm.modelMappingHint")}