Files
cc-switch/src/components/mcp/McpListItem.tsx
Jason 511980e3ea fix(mcp): remove SSE support; keep stdio default when type is omitted
- Backend: reject "sse" in validators; accept missing type as stdio; require url only for http (mcp.rs, claude_mcp.rs)
- Frontend: McpServer.type narrowed to "stdio" | "http" (optional) (src/types.ts)
- UI: avoid undefined in list item details (McpListItem)
- Claude-only sync after delete to update ~/.claude.json (commands.rs)

Notes:
- Ran typecheck and cargo check: both pass
- Clippy shows advisory warnings unrelated to this change
- Prettier check warns on a few files; limited scope changes kept minimal
2025-10-09 22:02:56 +08:00

85 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 || [])]
.filter(Boolean) as string[])
.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;