mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-04-23 09:29:13 +08:00
- Redesign MCP panel to match main interface style - Add toggle switch for each MCP server to enable/disable - Use emerald theme color consistent with MCP button - Create card-based layout with one MCP per row - Add dedicated form modal for add/edit operations - Implement proper empty state with friendly prompts - Add comprehensive i18n support (zh/en) - Extend McpServer type to support enabled field - Backend already supports enabled field via serde_json::Value Components: - McpPanel: Main panel container with header and list - McpListItem: Card-based list item with toggle and actions - McpFormModal: Independent modal for add/edit forms - McpToggle: Emerald-themed toggle switch component All changes passed TypeScript type checking and production build.
85 lines
2.3 KiB
TypeScript
85 lines
2.3 KiB
TypeScript
import React from "react";
|
||
import { useTranslation } from "react-i18next";
|
||
import { Edit3, Trash2 } from "lucide-react";
|
||
import { McpServer } from "../../types";
|
||
import { cardStyles, buttonStyles, cn } from "../../lib/styles";
|
||
import McpToggle from "./McpToggle";
|
||
|
||
interface McpListItemProps {
|
||
id: string;
|
||
server: McpServer;
|
||
onToggle: (id: string, enabled: boolean) => void;
|
||
onEdit: (id: string) => void;
|
||
onDelete: (id: string) => void;
|
||
}
|
||
|
||
/**
|
||
* MCP 列表项组件
|
||
* 每个 MCP 占一行,左侧是 Toggle 开关,中间是名称和详细信息,右侧是编辑和删除按钮
|
||
*/
|
||
const McpListItem: React.FC<McpListItemProps> = ({
|
||
id,
|
||
server,
|
||
onToggle,
|
||
onEdit,
|
||
onDelete,
|
||
}) => {
|
||
const { t } = useTranslation();
|
||
|
||
// 默认启用
|
||
const enabled = server.enabled !== false;
|
||
|
||
// 构建详细信息文本
|
||
const details = [server.type, server.command, ...(server.args || [])].join(
|
||
" · ",
|
||
);
|
||
|
||
return (
|
||
<div className={cn(cardStyles.interactive, "!p-4")}>
|
||
<div className="flex items-center gap-4">
|
||
{/* 左侧:Toggle 开关 */}
|
||
<div className="flex-shrink-0">
|
||
<McpToggle
|
||
enabled={enabled}
|
||
onChange={(newEnabled) => onToggle(id, newEnabled)}
|
||
/>
|
||
</div>
|
||
|
||
{/* 中间:名称和详细信息 */}
|
||
<div className="flex-1 min-w-0">
|
||
<h3 className="font-medium text-gray-900 dark:text-gray-100 mb-1">
|
||
{id}
|
||
</h3>
|
||
<p className="text-sm text-gray-500 dark:text-gray-400 truncate">
|
||
{details}
|
||
</p>
|
||
</div>
|
||
|
||
{/* 右侧:操作按钮 */}
|
||
<div className="flex items-center gap-2 flex-shrink-0">
|
||
<button
|
||
onClick={() => onEdit(id)}
|
||
className={buttonStyles.icon}
|
||
title={t("common.edit")}
|
||
>
|
||
<Edit3 size={16} />
|
||
</button>
|
||
|
||
<button
|
||
onClick={() => onDelete(id)}
|
||
className={cn(
|
||
buttonStyles.icon,
|
||
"hover:text-red-500 hover:bg-red-100 dark:hover:text-red-400 dark:hover:bg-red-500/10",
|
||
)}
|
||
title={t("common.delete")}
|
||
>
|
||
<Trash2 size={16} />
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default McpListItem;
|