refactor(mcp): improve UI consistency and i18n

- Add MCP-specific green button style (buttonStyles.mcp)
- Unify MCP panel and form buttons with emerald theme
- Adjust MCP entry button width to match AppSwitcher (px-3)
- Reduce JSON editor height from h-64 to h-48
- Update translations: "Add/Edit Server" → "Add/Edit MCP"
- Change form label to "MCP Title (Unique)" for clarity
- Move config wizard button to right side of JSON label
- Fix McpListItem enabled state check (explicit true check)
This commit is contained in:
Jason
2025-10-10 11:58:40 +08:00
parent 7493f3f9dd
commit 7f1131dfae
7 changed files with 24 additions and 20 deletions

View File

@@ -23,7 +23,7 @@ function App() {
const [currentProviderId, setCurrentProviderId] = useState<string>(""); const [currentProviderId, setCurrentProviderId] = useState<string>("");
const [isAddModalOpen, setIsAddModalOpen] = useState(false); const [isAddModalOpen, setIsAddModalOpen] = useState(false);
const [editingProviderId, setEditingProviderId] = useState<string | null>( const [editingProviderId, setEditingProviderId] = useState<string | null>(
null, null
); );
const [notification, setNotification] = useState<{ const [notification, setNotification] = useState<{
message: string; message: string;
@@ -44,7 +44,7 @@ function App() {
const showNotification = ( const showNotification = (
message: string, message: string,
type: "success" | "error", type: "success" | "error",
duration = 3000, duration = 3000
) => { ) => {
// 清除之前的定时器 // 清除之前的定时器
if (timeoutRef.current) { if (timeoutRef.current) {
@@ -196,7 +196,7 @@ function App() {
? t("notifications.removedFromClaudePlugin") ? t("notifications.removedFromClaudePlugin")
: t("notifications.appliedToClaudePlugin"), : t("notifications.appliedToClaudePlugin"),
"success", "success",
2000, 2000
); );
} }
} catch (error: any) { } catch (error: any) {
@@ -219,7 +219,7 @@ function App() {
showNotification( showNotification(
t("notifications.switchSuccess", { appName }), t("notifications.switchSuccess", { appName }),
"success", "success",
2000, 2000
); );
// 更新托盘菜单 // 更新托盘菜单
await window.api.updateTrayMenu(); await window.api.updateTrayMenu();
@@ -310,7 +310,7 @@ function App() {
<button <button
onClick={() => setIsMcpOpen(true)} onClick={() => setIsMcpOpen(true)}
className="inline-flex items-center gap-2 px-6 py-2 text-sm font-medium rounded-md transition-colors bg-emerald-500 text-white hover:bg-emerald-600 dark:bg-emerald-600 dark:hover:bg-emerald-700" className="inline-flex items-center gap-2 px-7 py-2 text-sm font-medium rounded-lg transition-colors bg-emerald-500 text-white hover:bg-emerald-600 dark:bg-emerald-600 dark:hover:bg-emerald-700"
> >
MCP MCP
</button> </button>

View File

@@ -244,13 +244,13 @@ const McpFormModal: React.FC<McpFormModalProps> = ({
<button <button
type="button" type="button"
onClick={() => setIsWizardOpen(true)} onClick={() => setIsWizardOpen(true)}
className="text-xs text-blue-500 dark:text-blue-400 hover:text-blue-600 dark:hover:text-blue-300 transition-colors" className="text-sm text-blue-500 dark:text-blue-400 hover:text-blue-600 dark:hover:text-blue-300 transition-colors"
> >
{t("mcp.form.useWizard")} {t("mcp.form.useWizard")}
</button> </button>
</div> </div>
<textarea <textarea
className={`${inputStyles.text} h-64 resize-none font-mono text-xs`} className={`${inputStyles.text} h-48 resize-none font-mono text-xs`}
placeholder={t("mcp.form.jsonPlaceholder")} placeholder={t("mcp.form.jsonPlaceholder")}
value={formJson} value={formJson}
onChange={(e) => handleJsonChange(e.target.value)} onChange={(e) => handleJsonChange(e.target.value)}
@@ -272,7 +272,7 @@ const McpFormModal: React.FC<McpFormModalProps> = ({
<button <button
onClick={handleSubmit} onClick={handleSubmit}
disabled={saving || (!isEditing && !!idError)} disabled={saving || (!isEditing && !!idError)}
className={buttonStyles.primary} className={`inline-flex items-center gap-2 ${buttonStyles.mcp}`}
> >
<Save size={16} /> <Save size={16} />
{saving {saving

View File

@@ -26,8 +26,8 @@ const McpListItem: React.FC<McpListItemProps> = ({
}) => { }) => {
const { t } = useTranslation(); const { t } = useTranslation();
// 默认启用 // 仅当显式为 true 时视为启用;避免 undefined 被误判为启用
const enabled = server.enabled !== false; const enabled = server.enabled === true;
// 只显示 description没有则留空 // 只显示 description没有则留空
const description = (server as any).description || ""; const description = (server as any).description || "";

View File

@@ -8,7 +8,7 @@ import { ConfirmDialog } from "../ConfirmDialog";
import { extractErrorMessage } from "../../utils/errorUtils"; import { extractErrorMessage } from "../../utils/errorUtils";
import { mcpPresets } from "../../config/mcpPresets"; import { mcpPresets } from "../../config/mcpPresets";
import McpToggle from "./McpToggle"; import McpToggle from "./McpToggle";
import { cardStyles, cn } from "../../lib/styles"; import { buttonStyles, cardStyles, cn } from "../../lib/styles";
interface McpPanelProps { interface McpPanelProps {
onClose: () => void; onClose: () => void;
@@ -178,7 +178,7 @@ const McpPanel: React.FC<McpPanelProps> = ({ onClose, onNotify }) => {
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<button <button
onClick={handleAdd} onClick={handleAdd}
className="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-md bg-emerald-500 text-white hover:bg-emerald-600 dark:bg-emerald-600 dark:hover:bg-emerald-700 transition-colors" className={`inline-flex items-center gap-2 ${buttonStyles.mcp}`}
> >
<Plus size={16} /> <Plus size={16} />
{t("mcp.add")} {t("mcp.add")}

View File

@@ -258,21 +258,21 @@
"empty": "No MCP servers", "empty": "No MCP servers",
"emptyDescription": "Click the button in the top right to add your first MCP server", "emptyDescription": "Click the button in the top right to add your first MCP server",
"add": "Add MCP", "add": "Add MCP",
"addServer": "Add Server", "addServer": "Add MCP",
"editServer": "Edit Server", "editServer": "Edit MCP",
"configPath": "Config Path", "configPath": "Config Path",
"serverCount": "{{count}} MCP server(s) configured", "serverCount": "{{count}} MCP server(s) configured",
"template": { "template": {
"fetch": "Quick Template: mcp-fetch" "fetch": "Quick Template: mcp-fetch"
}, },
"form": { "form": {
"title": "Server Title", "title": "MCP Title (Unique)",
"titlePlaceholder": "my-mcp-server", "titlePlaceholder": "my-mcp-server",
"description": "Description", "description": "Description",
"descriptionPlaceholder": "Optional description", "descriptionPlaceholder": "Optional description",
"jsonConfig": "JSON Configuration", "jsonConfig": "JSON Configuration",
"jsonPlaceholder": "{\n \"type\": \"stdio\",\n \"command\": \"uvx\",\n \"args\": [\"mcp-server-fetch\"]\n}", "jsonPlaceholder": "{\n \"type\": \"stdio\",\n \"command\": \"uvx\",\n \"args\": [\"mcp-server-fetch\"]\n}",
"useWizard": "or use configuration wizard" "useWizard": "Config Wizard"
}, },
"wizard": { "wizard": {
"title": "MCP Configuration Wizard", "title": "MCP Configuration Wizard",

View File

@@ -258,21 +258,21 @@
"empty": "暂无 MCP 服务器", "empty": "暂无 MCP 服务器",
"emptyDescription": "点击右上角按钮添加第一个 MCP 服务器", "emptyDescription": "点击右上角按钮添加第一个 MCP 服务器",
"add": "添加 MCP", "add": "添加 MCP",
"addServer": "新增服务器", "addServer": "新增 MCP",
"editServer": "编辑服务器", "editServer": "编辑 MCP",
"configPath": "配置路径", "configPath": "配置路径",
"serverCount": "已配置 {{count}} 个 MCP 服务器", "serverCount": "已配置 {{count}} 个 MCP 服务器",
"template": { "template": {
"fetch": "快速模板mcp-fetch" "fetch": "快速模板mcp-fetch"
}, },
"form": { "form": {
"title": "服务器标题", "title": "MCP 标题(唯一)",
"titlePlaceholder": "my-mcp-server", "titlePlaceholder": "my-mcp-server",
"description": "描述", "description": "描述",
"descriptionPlaceholder": "可选的描述信息", "descriptionPlaceholder": "可选的描述信息",
"jsonConfig": "JSON 配置", "jsonConfig": "JSON 配置",
"jsonPlaceholder": "{\n \"type\": \"stdio\",\n \"command\": \"uvx\",\n \"args\": [\"mcp-server-fetch\"]\n}", "jsonPlaceholder": "{\n \"type\": \"stdio\",\n \"command\": \"uvx\",\n \"args\": [\"mcp-server-fetch\"]\n}",
"useWizard": "或者使用配置向导" "useWizard": "配置向导"
}, },
"wizard": { "wizard": {
"title": "MCP 配置向导", "title": "MCP 配置向导",

View File

@@ -16,6 +16,10 @@ export const buttonStyles = {
danger: danger:
"px-4 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 dark:bg-red-600 dark:hover:bg-red-700 transition-colors text-sm font-medium", "px-4 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 dark:bg-red-600 dark:hover:bg-red-700 transition-colors text-sm font-medium",
// MCP 专属按钮:绿底白字
mcp:
"px-4 py-2 bg-emerald-500 text-white rounded-lg hover:bg-emerald-600 dark:bg-emerald-600 dark:hover:bg-emerald-700 transition-colors text-sm font-medium",
// 幽灵按钮:无背景,仅悬浮反馈 // 幽灵按钮:无背景,仅悬浮反馈
ghost: ghost:
"px-4 py-2 text-gray-500 hover:text-gray-900 hover:bg-gray-100 dark:text-gray-400 dark:hover:text-gray-100 dark:hover:bg-gray-800 rounded-lg transition-colors text-sm font-medium", "px-4 py-2 text-gray-500 hover:text-gray-900 hover:bg-gray-100 dark:text-gray-400 dark:hover:text-gray-100 dark:hover:bg-gray-800 rounded-lg transition-colors text-sm font-medium",