Files
CC-Switch/src/components/providers/ProviderEmptyState.tsx
T
Jason c12364a940 feat(claude-desktop): rework Claude Code import flow
- Derive route keys from the upstream model name (pass-through style)
  instead of fixed Claude aliases, and translate the legacy [1M] suffix
  into the supports1m field at the import boundary. Three Claude aliases
  mapped to the same upstream now collapse to a single route (e.g.
  MiniMax-M2 across SONNET/OPUS/HAIKU env produces one
  claude-MiniMax-M2 -> MiniMax-M2 row), with [1M] OR-aggregated.
- Add an import-time safety net that rebuilds claude-desktop-official
  when missing, so users who deleted it can recover via the normal
  import button without losing customizations on other providers.
- Hide API key and endpoint URL inputs in the official provider edit
  form to mirror Claude Code's behavior and prevent user confusion.
- Reword the empty-state import button label for clarity.
2026-05-12 21:31:30 +08:00

55 lines
1.8 KiB
TypeScript

import { Download, Users } from "lucide-react";
import { useTranslation } from "react-i18next";
import { Button } from "@/components/ui/button";
import type { AppId } from "@/lib/api/types";
interface ProviderEmptyStateProps {
appId: AppId;
onCreate?: () => void;
onImport?: () => void;
}
export function ProviderEmptyState({
appId,
onCreate,
onImport,
}: ProviderEmptyStateProps) {
const { t } = useTranslation();
const showSnippetHint =
appId === "claude" || appId === "codex" || appId === "gemini";
return (
<div className="flex flex-col items-center justify-center rounded-lg border border-dashed border-border p-10 text-center">
<div className="mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-muted">
<Users className="h-7 w-7 text-muted-foreground" />
</div>
<h3 className="text-lg font-semibold">{t("provider.noProviders")}</h3>
<p className="mt-2 max-w-lg text-sm text-muted-foreground">
{t("provider.noProvidersDescription")}
</p>
{showSnippetHint && (
<p className="mt-1 max-w-lg text-sm text-muted-foreground">
{t("provider.noProvidersDescriptionSnippet")}
</p>
)}
<div className="mt-6 flex flex-col gap-2">
{onImport && (
<Button onClick={onImport}>
<Download className="mr-2 h-4 w-4" />
{appId === "claude-desktop"
? t("provider.importFromClaude", {
defaultValue: "将 Claude Code 中已有的供应商导入",
})
: t("provider.importCurrent")}
</Button>
)}
{onCreate && (
<Button variant={onImport ? "outline" : "default"} onClick={onCreate}>
{t("provider.addProvider")}
</Button>
)}
</div>
</div>
);
}