Files
cc-switch/src/components/mcp/McpFormModal.tsx

684 lines
22 KiB
TypeScript
Raw Normal View History

import React, { useMemo, useState, useEffect } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
feat: complete stage 4 cleanup and code formatting This commit completes stage 4 of the refactoring plan, focusing on cleanup and optimization of the modernized codebase. ## Key Changes ### Code Cleanup - Remove legacy `src/lib/styles.ts` (no longer needed) - Remove old modal components (`ImportProgressModal.tsx`, `ProviderList.tsx`) - Streamline `src/lib/tauri-api.ts` from 712 lines to 17 lines (-97.6%) - Remove global `window.api` pollution - Keep only event listeners (`tauriEvents.onProviderSwitched`) - All API calls now use modular `@/lib/api/*` layer ### Type System - Clean up `src/vite-env.d.ts` (remove 156 lines of outdated types) - Remove obsolete global type declarations - All TypeScript checks pass with zero errors ### Code Formatting - Format all source files with Prettier (82 files) - Fix formatting issues in 15 files: - App.tsx and core components - MCP management components - Settings module components - Provider management components - UI components ### Documentation Updates - Update `REFACTORING_CHECKLIST.md` with stage 4 progress - Mark completed tasks in `REFACTORING_MASTER_PLAN.md` ## Impact **Code Reduction:** - Total: -1,753 lines, +384 lines (net -1,369 lines) - tauri-api.ts: 712 → 17 lines (-97.6%) - Removed styles.ts: -82 lines - Removed vite-env.d.ts declarations: -156 lines **Quality Improvements:** - ✅ Zero TypeScript errors - ✅ Zero TODO/FIXME comments - ✅ 100% Prettier compliant - ✅ Zero `window.api` references - ✅ Fully modular API layer ## Testing - [x] TypeScript compilation passes - [x] Code formatting validated - [x] No linting errors Stage 4 completion: 100% Ready for stage 5 (testing and bug fixes)
2025-10-16 12:13:51 +08:00
import {
Save,
AlertCircle,
ChevronDown,
ChevronUp,
AlertTriangle,
} from "lucide-react";
import { Button } from "@/components/ui/button";
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogFooter,
} from "@/components/ui/dialog";
feat: complete stage 4 cleanup and code formatting This commit completes stage 4 of the refactoring plan, focusing on cleanup and optimization of the modernized codebase. ## Key Changes ### Code Cleanup - Remove legacy `src/lib/styles.ts` (no longer needed) - Remove old modal components (`ImportProgressModal.tsx`, `ProviderList.tsx`) - Streamline `src/lib/tauri-api.ts` from 712 lines to 17 lines (-97.6%) - Remove global `window.api` pollution - Keep only event listeners (`tauriEvents.onProviderSwitched`) - All API calls now use modular `@/lib/api/*` layer ### Type System - Clean up `src/vite-env.d.ts` (remove 156 lines of outdated types) - Remove obsolete global type declarations - All TypeScript checks pass with zero errors ### Code Formatting - Format all source files with Prettier (82 files) - Fix formatting issues in 15 files: - App.tsx and core components - MCP management components - Settings module components - Provider management components - UI components ### Documentation Updates - Update `REFACTORING_CHECKLIST.md` with stage 4 progress - Mark completed tasks in `REFACTORING_MASTER_PLAN.md` ## Impact **Code Reduction:** - Total: -1,753 lines, +384 lines (net -1,369 lines) - tauri-api.ts: 712 → 17 lines (-97.6%) - Removed styles.ts: -82 lines - Removed vite-env.d.ts declarations: -156 lines **Quality Improvements:** - ✅ Zero TypeScript errors - ✅ Zero TODO/FIXME comments - ✅ 100% Prettier compliant - ✅ Zero `window.api` references - ✅ Fully modular API layer ## Testing - [x] TypeScript compilation passes - [x] Code formatting validated - [x] No linting errors Stage 4 completion: 100% Ready for stage 5 (testing and bug fixes)
2025-10-16 12:13:51 +08:00
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { mcpApi, type AppType } from "@/lib/api";
import { McpServer, McpServerSpec } from "@/types";
import { mcpPresets, getMcpPresetWithDescription } from "@/config/mcpPresets";
import McpWizardModal from "./McpWizardModal";
import { extractErrorMessage, translateMcpBackendError } from "@/utils/errorUtils";
import { tomlToMcpServer, extractIdFromToml, mcpServerToToml } from "@/utils/tomlUtils";
import { useMcpValidation } from "./useMcpValidation";
interface McpFormModalProps {
appType: AppType;
editingId?: string;
initialData?: McpServer;
onSave: (
id: string,
server: McpServer,
options?: { syncOtherSide?: boolean },
) => Promise<void>;
onClose: () => void;
existingIds?: string[];
}
/**
* MCP
* Claude: 使用 JSON
* Codex: 使用 TOML
*/
const McpFormModal: React.FC<McpFormModalProps> = ({
appType,
editingId,
initialData,
onSave,
onClose,
existingIds = [],
}) => {
const { t } = useTranslation();
const { formatTomlError, validateTomlConfig, validateJsonConfig } =
useMcpValidation();
const [formId, setFormId] = useState(
() => editingId || initialData?.id || "",
);
const [formName, setFormName] = useState(initialData?.name || "");
const [formDescription, setFormDescription] = useState(
initialData?.description || "",
);
const [formHomepage, setFormHomepage] = useState(initialData?.homepage || "");
const [formDocs, setFormDocs] = useState(initialData?.docs || "");
const [formTags, setFormTags] = useState(initialData?.tags?.join(", ") || "");
// 编辑模式下禁止修改 ID
const isEditing = !!editingId;
// 判断是否在编辑模式下有附加信息
const hasAdditionalInfo = !!(
initialData?.description ||
initialData?.tags?.length ||
initialData?.homepage ||
initialData?.docs
);
// 附加信息展开状态(编辑模式下有值时默认展开)
const [showMetadata, setShowMetadata] = useState(
isEditing ? hasAdditionalInfo : false,
);
// 根据 appType 决定初始格式
const [formConfig, setFormConfig] = useState(() => {
const spec = initialData?.server;
if (!spec) return "";
if (appType === "codex") {
return mcpServerToToml(spec);
}
return JSON.stringify(spec, null, 2);
});
const [configError, setConfigError] = useState("");
const [saving, setSaving] = useState(false);
const [isWizardOpen, setIsWizardOpen] = useState(false);
const [idError, setIdError] = useState("");
const [syncOtherSide, setSyncOtherSide] = useState(false);
const [otherSideHasConflict, setOtherSideHasConflict] = useState(false);
// 判断是否使用 TOML 格式
const useToml = appType === "codex";
const syncTargetLabel =
appType === "claude" ? t("apps.codex") : t("apps.claude");
const otherAppType: AppType = appType === "claude" ? "codex" : "claude";
feat: complete stage 4 cleanup and code formatting This commit completes stage 4 of the refactoring plan, focusing on cleanup and optimization of the modernized codebase. ## Key Changes ### Code Cleanup - Remove legacy `src/lib/styles.ts` (no longer needed) - Remove old modal components (`ImportProgressModal.tsx`, `ProviderList.tsx`) - Streamline `src/lib/tauri-api.ts` from 712 lines to 17 lines (-97.6%) - Remove global `window.api` pollution - Keep only event listeners (`tauriEvents.onProviderSwitched`) - All API calls now use modular `@/lib/api/*` layer ### Type System - Clean up `src/vite-env.d.ts` (remove 156 lines of outdated types) - Remove obsolete global type declarations - All TypeScript checks pass with zero errors ### Code Formatting - Format all source files with Prettier (82 files) - Fix formatting issues in 15 files: - App.tsx and core components - MCP management components - Settings module components - Provider management components - UI components ### Documentation Updates - Update `REFACTORING_CHECKLIST.md` with stage 4 progress - Mark completed tasks in `REFACTORING_MASTER_PLAN.md` ## Impact **Code Reduction:** - Total: -1,753 lines, +384 lines (net -1,369 lines) - tauri-api.ts: 712 → 17 lines (-97.6%) - Removed styles.ts: -82 lines - Removed vite-env.d.ts declarations: -156 lines **Quality Improvements:** - ✅ Zero TypeScript errors - ✅ Zero TODO/FIXME comments - ✅ 100% Prettier compliant - ✅ Zero `window.api` references - ✅ Fully modular API layer ## Testing - [x] TypeScript compilation passes - [x] Code formatting validated - [x] No linting errors Stage 4 completion: 100% Ready for stage 5 (testing and bug fixes)
2025-10-16 12:13:51 +08:00
const syncCheckboxId = useMemo(() => `sync-other-side-${appType}`, [appType]);
// 检测另一侧是否有同名 MCP
useEffect(() => {
const checkOtherSide = async () => {
const currentId = formId.trim();
if (!currentId) {
setOtherSideHasConflict(false);
return;
}
try {
feat: complete stage 4 cleanup and code formatting This commit completes stage 4 of the refactoring plan, focusing on cleanup and optimization of the modernized codebase. ## Key Changes ### Code Cleanup - Remove legacy `src/lib/styles.ts` (no longer needed) - Remove old modal components (`ImportProgressModal.tsx`, `ProviderList.tsx`) - Streamline `src/lib/tauri-api.ts` from 712 lines to 17 lines (-97.6%) - Remove global `window.api` pollution - Keep only event listeners (`tauriEvents.onProviderSwitched`) - All API calls now use modular `@/lib/api/*` layer ### Type System - Clean up `src/vite-env.d.ts` (remove 156 lines of outdated types) - Remove obsolete global type declarations - All TypeScript checks pass with zero errors ### Code Formatting - Format all source files with Prettier (82 files) - Fix formatting issues in 15 files: - App.tsx and core components - MCP management components - Settings module components - Provider management components - UI components ### Documentation Updates - Update `REFACTORING_CHECKLIST.md` with stage 4 progress - Mark completed tasks in `REFACTORING_MASTER_PLAN.md` ## Impact **Code Reduction:** - Total: -1,753 lines, +384 lines (net -1,369 lines) - tauri-api.ts: 712 → 17 lines (-97.6%) - Removed styles.ts: -82 lines - Removed vite-env.d.ts declarations: -156 lines **Quality Improvements:** - ✅ Zero TypeScript errors - ✅ Zero TODO/FIXME comments - ✅ 100% Prettier compliant - ✅ Zero `window.api` references - ✅ Fully modular API layer ## Testing - [x] TypeScript compilation passes - [x] Code formatting validated - [x] No linting errors Stage 4 completion: 100% Ready for stage 5 (testing and bug fixes)
2025-10-16 12:13:51 +08:00
const otherConfig = await mcpApi.getConfig(otherAppType);
const hasConflict = Object.keys(otherConfig.servers || {}).includes(
currentId,
);
setOtherSideHasConflict(hasConflict);
} catch (error) {
console.error("检查另一侧 MCP 配置失败:", error);
setOtherSideHasConflict(false);
}
};
checkOtherSide();
}, [formId, otherAppType]);
const wizardInitialSpec = useMemo(() => {
const fallback = initialData?.server;
if (!formConfig.trim()) {
return fallback;
}
if (useToml) {
try {
return tomlToMcpServer(formConfig);
} catch {
return fallback;
}
}
try {
const parsed = JSON.parse(formConfig);
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
return parsed as McpServerSpec;
}
return fallback;
} catch {
return fallback;
}
}, [formConfig, initialData, useToml]);
// 预设选择状态(仅新增模式显示;-1 表示自定义)
const [selectedPreset, setSelectedPreset] = useState<number | null>(
isEditing ? null : -1,
);
const handleIdChange = (value: string) => {
setFormId(value);
if (!isEditing) {
const exists = existingIds.includes(value.trim());
setIdError(exists ? t("mcp.error.idExists") : "");
}
};
const ensureUniqueId = (base: string): string => {
let candidate = base.trim();
if (!candidate) candidate = "mcp-server";
if (!existingIds.includes(candidate)) return candidate;
let i = 1;
while (existingIds.includes(`${candidate}-${i}`)) i++;
return `${candidate}-${i}`;
};
// 应用预设(写入表单但不落库)
const applyPreset = (index: number) => {
if (index < 0 || index >= mcpPresets.length) return;
const preset = mcpPresets[index];
const presetWithDesc = getMcpPresetWithDescription(preset, t);
const id = ensureUniqueId(presetWithDesc.id);
setFormId(id);
setFormName(presetWithDesc.name || presetWithDesc.id);
setFormDescription(presetWithDesc.description || "");
setFormHomepage(presetWithDesc.homepage || "");
setFormDocs(presetWithDesc.docs || "");
setFormTags(presetWithDesc.tags?.join(", ") || "");
// 根据格式转换配置
if (useToml) {
const toml = mcpServerToToml(presetWithDesc.server);
setFormConfig(toml);
setConfigError(validateTomlConfig(toml));
} else {
const json = JSON.stringify(presetWithDesc.server, null, 2);
setFormConfig(json);
setConfigError(validateJsonConfig(json));
}
setSelectedPreset(index);
};
// 切回自定义
const applyCustom = () => {
setSelectedPreset(-1);
// 恢复到空白模板
setFormId("");
setFormName("");
setFormDescription("");
setFormHomepage("");
setFormDocs("");
setFormTags("");
setFormConfig("");
setConfigError("");
};
const handleConfigChange = (value: string) => {
setFormConfig(value);
if (useToml) {
// TOML validation (use hook's complete validation)
const err = validateTomlConfig(value);
if (err) {
setConfigError(err);
return;
}
// Try to extract ID (if user hasn't filled it yet)
if (value.trim() && !formId.trim()) {
const extractedId = extractIdFromToml(value);
if (extractedId) {
setFormId(extractedId);
}
}
} else {
// JSON validation (use hook's complete validation)
const err = validateJsonConfig(value);
if (err) {
setConfigError(err);
return;
}
}
setConfigError("");
};
const handleWizardApply = (title: string, json: string) => {
setFormId(title);
if (!formName.trim()) {
setFormName(title);
}
// Wizard returns JSON, convert based on format if needed
if (useToml) {
try {
const server = JSON.parse(json) as McpServerSpec;
const toml = mcpServerToToml(server);
setFormConfig(toml);
setConfigError(validateTomlConfig(toml));
} catch (e: any) {
setConfigError(t("mcp.error.jsonInvalid"));
}
} else {
setFormConfig(json);
setConfigError(validateJsonConfig(json));
}
};
const handleSubmit = async () => {
const trimmedId = formId.trim();
if (!trimmedId) {
toast.error(t("mcp.error.idRequired"), { duration: 3000 });
return;
}
// 新增模式:阻止提交重名 ID
if (!isEditing && existingIds.includes(trimmedId)) {
setIdError(t("mcp.error.idExists"));
return;
}
// Validate configuration format
let serverSpec: McpServerSpec;
if (useToml) {
// TOML mode
const tomlError = validateTomlConfig(formConfig);
setConfigError(tomlError);
if (tomlError) {
toast.error(t("mcp.error.tomlInvalid"), { duration: 3000 });
return;
}
if (!formConfig.trim()) {
// Empty configuration
serverSpec = {
type: "stdio",
command: "",
args: [],
};
} else {
try {
serverSpec = tomlToMcpServer(formConfig);
} catch (e: any) {
const msg = e?.message || String(e);
setConfigError(formatTomlError(msg));
toast.error(t("mcp.error.tomlInvalid"), { duration: 4000 });
return;
}
}
} else {
// JSON mode
const jsonError = validateJsonConfig(formConfig);
setConfigError(jsonError);
if (jsonError) {
toast.error(t("mcp.error.jsonInvalid"), { duration: 3000 });
return;
}
if (!formConfig.trim()) {
// Empty configuration
serverSpec = {
type: "stdio",
command: "",
args: [],
};
} else {
try {
serverSpec = JSON.parse(formConfig) as McpServerSpec;
} catch (e: any) {
setConfigError(t("mcp.error.jsonInvalid"));
toast.error(t("mcp.error.jsonInvalid"), { duration: 4000 });
return;
}
}
}
// 前置必填校验
if (serverSpec?.type === "stdio" && !serverSpec?.command?.trim()) {
toast.error(t("mcp.error.commandRequired"), { duration: 3000 });
return;
}
if (serverSpec?.type === "http" && !serverSpec?.url?.trim()) {
toast.error(t("mcp.wizard.urlRequired"), { duration: 3000 });
return;
}
setSaving(true);
try {
const entry: McpServer = {
...(initialData ? { ...initialData } : {}),
id: trimmedId,
server: serverSpec,
};
if (initialData?.enabled !== undefined) {
entry.enabled = initialData.enabled;
} else if (!initialData) {
delete entry.enabled;
}
const nameTrimmed = (formName || trimmedId).trim();
entry.name = nameTrimmed || trimmedId;
const descriptionTrimmed = formDescription.trim();
if (descriptionTrimmed) {
entry.description = descriptionTrimmed;
} else {
delete entry.description;
}
const homepageTrimmed = formHomepage.trim();
if (homepageTrimmed) {
entry.homepage = homepageTrimmed;
} else {
delete entry.homepage;
}
const docsTrimmed = formDocs.trim();
if (docsTrimmed) {
entry.docs = docsTrimmed;
} else {
delete entry.docs;
}
const parsedTags = formTags
.split(",")
.map((tag) => tag.trim())
.filter((tag) => tag.length > 0);
if (parsedTags.length > 0) {
entry.tags = parsedTags;
} else {
delete entry.tags;
}
// 显式等待父组件保存流程
await onSave(trimmedId, entry, { syncOtherSide });
} catch (error: any) {
const detail = extractErrorMessage(error);
const mapped = translateMcpBackendError(detail, t);
const msg = mapped || detail || t("mcp.error.saveFailed");
toast.error(msg, { duration: mapped || detail ? 6000 : 4000 });
} finally {
setSaving(false);
}
};
const getFormTitle = () => {
if (appType === "claude") {
return isEditing ? t("mcp.editClaudeServer") : t("mcp.addClaudeServer");
} else {
return isEditing ? t("mcp.editCodexServer") : t("mcp.addCodexServer");
}
};
return (
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
<>
<Dialog open={true} onOpenChange={(open) => !open && onClose()}>
<DialogContent className="max-w-3xl max-h-[90vh] flex flex-col">
<DialogHeader>
<DialogTitle>{getFormTitle()}</DialogTitle>
</DialogHeader>
{/* Content - Scrollable */}
<div className="flex-1 overflow-y-auto -mx-6 px-6 space-y-4">
{/* 预设选择(仅新增时展示) */}
{!isEditing && (
<div>
<label className="block text-sm font-medium text-gray-900 dark:text-gray-100 mb-3">
{t("mcp.presets.title")}
</label>
<div className="flex flex-wrap gap-2">
<button
type="button"
onClick={applyCustom}
className={`inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-colors ${
selectedPreset === -1
? "bg-emerald-500 text-white dark:bg-emerald-600"
: "bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700"
}`}
>
{t("presetSelector.custom")}
</button>
{mcpPresets.map((preset, idx) => {
const descriptionKey = `mcp.presets.${preset.id}.description`;
return (
<button
key={preset.id}
type="button"
onClick={() => applyPreset(idx)}
className={`inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-colors ${
selectedPreset === idx
? "bg-emerald-500 text-white dark:bg-emerald-600"
: "bg-gray-100 dark:bg-gray-800 text-gray-500 dark:text-gray-400 hover:bg-gray-200 dark:hover:bg-gray-700"
}`}
title={t(descriptionKey)}
>
{preset.id}
</button>
);
})}
</div>
</div>
)}
{/* ID (标题) */}
<div>
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
<div className="flex items-center justify-between mb-2">
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300">
{t("mcp.form.title")} <span className="text-red-500">*</span>
</label>
{!isEditing && idError && (
<span className="text-xs text-red-500 dark:text-red-400">
{idError}
</span>
)}
</div>
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
<Input
type="text"
placeholder={t("mcp.form.titlePlaceholder")}
value={formId}
onChange={(e) => handleIdChange(e.target.value)}
disabled={isEditing}
/>
</div>
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
{/* Name */}
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
{t("mcp.form.name")}
</label>
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
<Input
type="text"
placeholder={t("mcp.form.namePlaceholder")}
value={formName}
onChange={(e) => setFormName(e.target.value)}
/>
</div>
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
{/* 可折叠的附加信息按钮 */}
<div>
<button
type="button"
onClick={() => setShowMetadata(!showMetadata)}
className="flex items-center gap-2 text-sm font-medium text-gray-700 dark:text-gray-300 hover:text-gray-900 dark:hover:text-gray-100 transition-colors"
>
{showMetadata ? (
<ChevronUp size={16} />
) : (
<ChevronDown size={16} />
)}
{t("mcp.form.additionalInfo")}
</button>
</div>
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
{/* 附加信息区域(可折叠) */}
{showMetadata && (
<>
{/* Description (描述) */}
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
{t("mcp.form.description")}
</label>
<Input
type="text"
placeholder={t("mcp.form.descriptionPlaceholder")}
value={formDescription}
onChange={(e) => setFormDescription(e.target.value)}
/>
</div>
{/* Tags */}
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
{t("mcp.form.tags")}
</label>
<Input
type="text"
placeholder={t("mcp.form.tagsPlaceholder")}
value={formTags}
onChange={(e) => setFormTags(e.target.value)}
/>
</div>
{/* Homepage */}
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
{t("mcp.form.homepage")}
</label>
<Input
type="text"
placeholder={t("mcp.form.homepagePlaceholder")}
value={formHomepage}
onChange={(e) => setFormHomepage(e.target.value)}
/>
</div>
{/* Docs */}
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
{t("mcp.form.docs")}
</label>
<Input
type="text"
placeholder={t("mcp.form.docsPlaceholder")}
value={formDocs}
onChange={(e) => setFormDocs(e.target.value)}
/>
</div>
</>
)}
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
{/* 配置输入框(根据格式显示 JSON 或 TOML */}
<div>
<div className="flex items-center justify-between mb-2">
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300">
{useToml
? t("mcp.form.tomlConfig")
: t("mcp.form.jsonConfig")}
</label>
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
{(isEditing || selectedPreset === -1) && (
<button
type="button"
onClick={() => setIsWizardOpen(true)}
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")}
</button>
)}
</div>
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
<Textarea
className="h-48 resize-none font-mono text-xs"
placeholder={
useToml
? t("mcp.form.tomlPlaceholder")
: t("mcp.form.jsonPlaceholder")
}
value={formConfig}
onChange={(e) => handleConfigChange(e.target.value)}
/>
{configError && (
<div className="flex items-center gap-2 mt-2 text-red-500 dark:text-red-400 text-sm">
<AlertCircle size={16} />
<span>{configError}</span>
</div>
)}
</div>
</div>
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
{/* Footer */}
<DialogFooter className="flex-col sm:flex-row sm:justify-between gap-3 pt-4">
{/* 双端同步选项 */}
<div className="flex items-center gap-3">
<div className="flex items-center gap-2">
<input
id={syncCheckboxId}
type="checkbox"
className="h-4 w-4 rounded border-gray-300 text-emerald-600 focus:ring-emerald-500 dark:border-gray-600 dark:bg-gray-800"
checked={syncOtherSide}
onChange={(event) => setSyncOtherSide(event.target.checked)}
/>
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
<label
htmlFor={syncCheckboxId}
className="text-sm text-gray-700 dark:text-gray-300 cursor-pointer select-none"
title={t("mcp.form.syncOtherSideHint", {
target: syncTargetLabel,
})}
>
{t("mcp.form.syncOtherSide", { target: syncTargetLabel })}
</label>
</div>
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
{syncOtherSide && otherSideHasConflict && (
<div className="flex items-center gap-1.5 text-amber-600 dark:text-amber-400">
<AlertTriangle size={14} />
<span className="text-xs font-medium">
{t("mcp.form.willOverwriteWarning", {
target: syncTargetLabel,
})}
</span>
</div>
)}
</div>
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
{/* 操作按钮 */}
<div className="flex items-center gap-3">
<Button type="button" variant="ghost" size="sm" onClick={onClose}>
{t("common.cancel")}
</Button>
<Button
type="button"
size="sm"
onClick={handleSubmit}
disabled={saving || (!isEditing && !!idError)}
variant="mcp"
>
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
<Save size={16} />
{saving
? t("common.saving")
: isEditing
? t("common.save")
: t("common.add")}
</Button>
</div>
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
</DialogFooter>
</DialogContent>
</Dialog>
{/* Wizard Modal */}
<McpWizardModal
isOpen={isWizardOpen}
onClose={() => setIsWizardOpen(false)}
onApply={handleWizardApply}
initialTitle={formId}
initialServer={wizardInitialSpec}
/>
refactor: migrate all MCP dialogs to shadcn/ui Dialog component Convert all MCP-related modal windows to use the unified shadcn/ui Dialog component for consistency with the rest of the application. Changes: - McpPanel: Replace custom modal with Dialog component - Update props from onClose to open/onOpenChange pattern - Use DialogContent, DialogHeader, DialogTitle components - Remove custom backdrop and close button (handled by Dialog) - McpFormModal: Migrate form modal to Dialog - Wrap entire form in Dialog component structure - Use DialogFooter for action buttons - Apply variant="mcp" to maintain green button styling - Remove unused X icon import - McpWizardModal: Convert wizard to Dialog - Replace custom modal structure with Dialog components - Use Button component with variant="mcp" for consistency - Remove unused isLinux and X icon imports - App.tsx: Update McpPanel usage - Remove conditional rendering wrapper - Pass open and onOpenChange props directly - dialog.tsx: Fix dialog overlay and content styling - Change overlay from bg-background/80 to bg-black/50 for consistency - Change content from bg-background to explicit bg-white dark:bg-gray-900 - Ensures opaque backgrounds matching MCP panel style Benefits: - Unified dialog behavior across the application - Consistent styling and animations - Better accessibility with Radix UI primitives - Reduced code duplication - Maintains MCP-specific green color scheme All dialogs now share the same base styling while preserving their unique content and functionality.
2025-10-16 16:20:45 +08:00
</>
);
};
export default McpFormModal;