mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-28 08:44:41 +08:00
refactor(presets): render presets in array order and prioritize partners
Remove the category-based grouping logic from ProviderPresetSelector, letting the array position in each preset config file be the single source of truth for display order. Move partner presets (PatewayAI, 火山Agentplan, BytePlus, DouBaoSeed) right after Shengsuanyun across all 6 config files so they appear earlier in the UI.
This commit is contained in:
@@ -395,25 +395,6 @@ export function ClaudeDesktopProviderForm({
|
||||
[],
|
||||
);
|
||||
|
||||
const groupedPresets = useMemo(
|
||||
() =>
|
||||
presetEntries.reduce<Record<string, PresetEntry[]>>((acc, entry) => {
|
||||
const cat = entry.preset.category ?? "others";
|
||||
if (!acc[cat]) acc[cat] = [];
|
||||
acc[cat].push(entry);
|
||||
return acc;
|
||||
}, {}),
|
||||
[presetEntries],
|
||||
);
|
||||
|
||||
const categoryKeys = useMemo(
|
||||
() =>
|
||||
Object.keys(groupedPresets).filter(
|
||||
(key) => key !== "custom" && groupedPresets[key]?.length,
|
||||
),
|
||||
[groupedPresets],
|
||||
);
|
||||
|
||||
const presetCategoryLabels: Record<string, string> = useMemo(
|
||||
() => ({
|
||||
official: t("providerForm.categoryOfficial", { defaultValue: "官方" }),
|
||||
@@ -777,8 +758,7 @@ export function ClaudeDesktopProviderForm({
|
||||
{!initialData && (
|
||||
<ProviderPresetSelector
|
||||
selectedPresetId={selectedPresetId}
|
||||
groupedPresets={groupedPresets}
|
||||
categoryKeys={categoryKeys}
|
||||
presetEntries={presetEntries}
|
||||
presetCategoryLabels={presetCategoryLabels}
|
||||
onPresetChange={handlePresetChange}
|
||||
category={activePreset?.category}
|
||||
|
||||
@@ -1251,23 +1251,6 @@ function ProviderFormFull({
|
||||
await onSubmit(payload);
|
||||
};
|
||||
|
||||
const groupedPresets = useMemo(() => {
|
||||
return presetEntries.reduce<Record<string, PresetEntry[]>>((acc, entry) => {
|
||||
const category = entry.preset.category ?? "others";
|
||||
if (!acc[category]) {
|
||||
acc[category] = [];
|
||||
}
|
||||
acc[category].push(entry);
|
||||
return acc;
|
||||
}, {});
|
||||
}, [presetEntries]);
|
||||
|
||||
const categoryKeys = useMemo(() => {
|
||||
return Object.keys(groupedPresets).filter(
|
||||
(key) => key !== "custom" && groupedPresets[key]?.length,
|
||||
);
|
||||
}, [groupedPresets]);
|
||||
|
||||
const shouldShowSpeedTest =
|
||||
category !== "official" && category !== "cloud_provider";
|
||||
|
||||
@@ -1553,8 +1536,7 @@ function ProviderFormFull({
|
||||
{!initialData && (
|
||||
<ProviderPresetSelector
|
||||
selectedPresetId={selectedPresetId}
|
||||
groupedPresets={groupedPresets}
|
||||
categoryKeys={categoryKeys}
|
||||
presetEntries={presetEntries}
|
||||
presetCategoryLabels={presetCategoryLabels}
|
||||
onPresetChange={handlePresetChange}
|
||||
onUniversalPresetSelect={onUniversalPresetSelect}
|
||||
|
||||
@@ -6,6 +6,9 @@ import type { ProviderPreset } from "@/config/claudeProviderPresets";
|
||||
import type { CodexProviderPreset } from "@/config/codexProviderPresets";
|
||||
import type { GeminiProviderPreset } from "@/config/geminiProviderPresets";
|
||||
import type { ClaudeDesktopProviderPreset } from "@/config/claudeDesktopProviderPresets";
|
||||
import type { OpenCodeProviderPreset } from "@/config/opencodeProviderPresets";
|
||||
import type { OpenClawProviderPreset } from "@/config/openclawProviderPresets";
|
||||
import type { HermesProviderPreset } from "@/config/hermesProviderPresets";
|
||||
import type { ProviderCategory } from "@/types";
|
||||
import {
|
||||
universalProviderPresets,
|
||||
@@ -17,7 +20,10 @@ type AnyPreset =
|
||||
| ProviderPreset
|
||||
| CodexProviderPreset
|
||||
| GeminiProviderPreset
|
||||
| ClaudeDesktopProviderPreset;
|
||||
| ClaudeDesktopProviderPreset
|
||||
| OpenCodeProviderPreset
|
||||
| OpenClawProviderPreset
|
||||
| HermesProviderPreset;
|
||||
|
||||
type PresetEntry = {
|
||||
id: string;
|
||||
@@ -26,8 +32,7 @@ type PresetEntry = {
|
||||
|
||||
interface ProviderPresetSelectorProps {
|
||||
selectedPresetId: string | null;
|
||||
groupedPresets: Record<string, PresetEntry[]>;
|
||||
categoryKeys: string[];
|
||||
presetEntries: PresetEntry[];
|
||||
presetCategoryLabels: Record<string, string>;
|
||||
onPresetChange: (value: string) => void;
|
||||
onUniversalPresetSelect?: (preset: UniversalProviderPreset) => void;
|
||||
@@ -37,8 +42,7 @@ interface ProviderPresetSelectorProps {
|
||||
|
||||
export function ProviderPresetSelector({
|
||||
selectedPresetId,
|
||||
groupedPresets,
|
||||
categoryKeys,
|
||||
presetEntries,
|
||||
presetCategoryLabels,
|
||||
onPresetChange,
|
||||
onUniversalPresetSelect,
|
||||
@@ -140,35 +144,33 @@ export function ProviderPresetSelector({
|
||||
{t("providerPreset.custom")}
|
||||
</button>
|
||||
|
||||
{categoryKeys.map((category) => {
|
||||
const entries = groupedPresets[category];
|
||||
if (!entries || entries.length === 0) return null;
|
||||
return entries.map((entry) => {
|
||||
const isSelected = selectedPresetId === entry.id;
|
||||
const isPartner = entry.preset.isPartner;
|
||||
return (
|
||||
<button
|
||||
key={entry.id}
|
||||
type="button"
|
||||
onClick={() => onPresetChange(entry.id)}
|
||||
className={`${getPresetButtonClass(isSelected, entry.preset)} relative`}
|
||||
style={getPresetButtonStyle(isSelected, entry.preset)}
|
||||
title={
|
||||
presetCategoryLabels[category] ?? t("providerPreset.other")
|
||||
}
|
||||
>
|
||||
{renderPresetIcon(entry.preset)}
|
||||
{entry.preset.nameKey
|
||||
? t(entry.preset.nameKey)
|
||||
: entry.preset.name}
|
||||
{isPartner && (
|
||||
<span className="absolute -top-1 -right-1 flex items-center gap-0.5 rounded-full bg-gradient-to-r from-amber-500 to-yellow-500 px-1.5 py-0.5 text-[10px] font-bold text-white shadow-md">
|
||||
<Star className="h-2.5 w-2.5 fill-current" />
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
});
|
||||
{presetEntries.map((entry) => {
|
||||
const isSelected = selectedPresetId === entry.id;
|
||||
const isPartner = entry.preset.isPartner;
|
||||
const presetCategory = entry.preset.category ?? "others";
|
||||
return (
|
||||
<button
|
||||
key={entry.id}
|
||||
type="button"
|
||||
onClick={() => onPresetChange(entry.id)}
|
||||
className={`${getPresetButtonClass(isSelected, entry.preset)} relative`}
|
||||
style={getPresetButtonStyle(isSelected, entry.preset)}
|
||||
title={
|
||||
presetCategoryLabels[presetCategory] ??
|
||||
t("providerPreset.other")
|
||||
}
|
||||
>
|
||||
{renderPresetIcon(entry.preset)}
|
||||
{entry.preset.nameKey
|
||||
? t(entry.preset.nameKey)
|
||||
: entry.preset.name}
|
||||
{isPartner && (
|
||||
<span className="absolute -top-1 -right-1 flex items-center gap-0.5 rounded-full bg-gradient-to-r from-amber-500 to-yellow-500 px-1.5 py-0.5 text-[10px] font-bold text-white shadow-md">
|
||||
<Star className="h-2.5 w-2.5 fill-current" />
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user