"use client" import React, { useState } from "react" import { FileCode, Save, X, AlertCircle, CheckCircle2 } from "lucide-react" import Editor from "@monaco-editor/react" import * as yaml from "js-yaml" import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog" import { Button } from "@/components/ui/button" import { Label } from "@/components/ui/label" import { Input } from "@/components/ui/input" import { toast } from "sonner" import { useTheme } from "next-themes" interface EngineCreateDialogProps { open: boolean onOpenChange: (open: boolean) => void onSave?: (name: string, yamlContent: string) => Promise } /** * 新建引擎弹窗 */ export function EngineCreateDialog({ open, onOpenChange, onSave, }: EngineCreateDialogProps) { const [engineName, setEngineName] = useState("") const [yamlContent, setYamlContent] = useState("") const [isSubmitting, setIsSubmitting] = useState(false) const [isEditorReady, setIsEditorReady] = useState(false) const [yamlError, setYamlError] = useState<{ message: string; line?: number; column?: number } | null>(null) const { theme } = useTheme() const editorRef = React.useRef(null) // 默认 YAML 模板 const defaultYaml = `# 请在此处编写引擎配置 YAML # 可以参考 engine_config_example.yaml 文件中的配置示例`; // 当对话框打开时,重置表单 React.useEffect(() => { if (open) { setEngineName("") setYamlContent(defaultYaml) setYamlError(null) } }, [open]) // 验证 YAML 语法 const validateYaml = (content: string) => { if (!content.trim()) { setYamlError(null) return true } try { yaml.load(content) setYamlError(null) return true } catch (error) { const yamlError = error as yaml.YAMLException setYamlError({ message: yamlError.message, line: yamlError.mark?.line ? yamlError.mark.line + 1 : undefined, column: yamlError.mark?.column ? yamlError.mark.column + 1 : undefined, }) return false } } // 处理编辑器内容变化 const handleEditorChange = (value: string | undefined) => { const newValue = value || "" setYamlContent(newValue) validateYaml(newValue) } // 处理编辑器挂载 const handleEditorDidMount = (editor: any) => { editorRef.current = editor setIsEditorReady(true) } // 处理保存 const handleSave = async () => { // 验证引擎名称 if (!engineName.trim()) { toast.error("请输入引擎名称") return } // YAML 验证 if (!yamlContent.trim()) { toast.error("配置内容不能为空") return } if (!validateYaml(yamlContent)) { toast.error("YAML 语法错误", { description: yamlError?.message, }) return } setIsSubmitting(true) try { if (onSave) { await onSave(engineName, yamlContent) } else { // TODO: 调用实际的 API 创建引擎 await new Promise(resolve => setTimeout(resolve, 1000)) } toast.success("引擎创建成功", { description: `引擎 "${engineName}" 已成功创建`, }) onOpenChange(false) } catch (error) { console.error("Failed to create engine:", error) toast.error("引擎创建失败", { description: error instanceof Error ? error.message : "未知错误", }) } finally { setIsSubmitting(false) } } // 处理关闭 const handleClose = () => { if (engineName.trim() || yamlContent !== defaultYaml) { const confirmed = window.confirm("您有未保存的更改,确定要关闭吗?") if (!confirmed) return } onOpenChange(false) } return (
新建扫描引擎 创建新的扫描引擎配置,使用 Monaco Editor 编辑 YAML 配置文件,支持语法高亮、自动补全和错误提示。
{/* 引擎名称输入 */}
setEngineName(e.target.value)} placeholder="请输入引擎名称,例如:全面扫描引擎" disabled={isSubmitting} className="max-w-md" />
{/* YAML 编辑器 */}
{/* 语法验证状态 */}
{yamlContent.trim() && ( yamlError ? (
语法错误
) : (
语法正确
) )}
{/* Monaco Editor */}

加载编辑器...

} />
{/* 错误信息显示 */} {yamlError && (

{yamlError.line && yamlError.column ? `第 ${yamlError.line} 行,第 ${yamlError.column} 列` : "YAML 语法错误"}

{yamlError.message}

)}
) }