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:
10
src/App.tsx
10
src/App.tsx
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 || "";
|
||||||
|
|||||||
@@ -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")}
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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 配置向导",
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
Reference in New Issue
Block a user