From 4b016c2702854080273dcf4655aa8539927d33a1 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 8 Aug 2025 22:32:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0ComfyUI=20V2=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=B5=81=E6=A8=A1=E6=9D=BF=E5=8F=82=E6=95=B0=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=8A=98=E5=8F=A0=E8=A1=A8=E5=8D=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根据ComfyUI SDK规范,为参数配置添加了折叠表单功能,提供简洁的信息展示和详细的配置表单: 🎯 核心功能: - ✅ 折叠/展开控制:每个参数都有独立的折叠状态管理 - ✅ 简洁信息展示:参数名称、类型、默认值、描述的概览 - ✅ 详细配置表单:展开后显示完整的参数配置选项 - ✅ 类型图标标识:不同参数类型使用不同颜色和图标 🎨 用户界面优化: - 参数卡片式设计,支持折叠/展开 - 类型标签和必填标识的视觉提示 - 悬停效果和交互反馈 - 简洁的信息概览和详细配置分离 🛠 技术实现: - 使用Set管理展开状态,支持多个参数同时展开 - 类型图标映射系统,每种类型有专属图标和颜色 - 智能值格式化显示,根据类型优化显示效果 - 事件冒泡控制,确保删除按钮不触发展开/折叠 📱 交互体验: - 点击参数卡片头部切换展开/折叠状态 - 展开状态下显示完整的参数配置表单 - 折叠状态下显示关键信息概览 - 删除按钮独立操作,不影响折叠状态 这个实现大大提升了参数配置的用户体验, 让用户能够快速浏览参数概览,按需展开详细配置。 --- .../comfyui/WorkflowTemplateCreator.tsx | 156 ++++++++++++++++-- 1 file changed, 140 insertions(+), 16 deletions(-) diff --git a/apps/desktop/src/components/comfyui/WorkflowTemplateCreator.tsx b/apps/desktop/src/components/comfyui/WorkflowTemplateCreator.tsx index 8e65e53..d77f878 100644 --- a/apps/desktop/src/components/comfyui/WorkflowTemplateCreator.tsx +++ b/apps/desktop/src/components/comfyui/WorkflowTemplateCreator.tsx @@ -14,6 +14,16 @@ import { AlertCircle, Plus, Trash2, + ChevronDown, + ChevronRight, + Type, + Hash, + ToggleLeft, + Image, + Music, + Video, + List, + Braces, } from 'lucide-react'; // 定义符合ComfyUI SDK的模板数据结构 @@ -101,6 +111,7 @@ export const WorkflowTemplateCreator: React.FC = ( const [isSaving, setIsSaving] = useState(false); const [workflowJsonText, setWorkflowJsonText] = useState('{}'); const [newParameterName, setNewParameterName] = useState(''); + const [expandedParameters, setExpandedParameters] = useState>(new Set()); // 重置表单数据 useEffect(() => { @@ -190,6 +201,19 @@ export const WorkflowTemplateCreator: React.FC = ( setNewParameterName(''); }; + // 切换参数展开/折叠状态 + const toggleParameterExpanded = (paramName: string) => { + setExpandedParameters(prev => { + const newSet = new Set(prev); + if (newSet.has(paramName)) { + newSet.delete(paramName); + } else { + newSet.add(paramName); + } + return newSet; + }); + }; + // 根据参数类型获取默认配置 const getDefaultConfigForType = (type: string): Partial => { switch (type) { @@ -274,6 +298,51 @@ export const WorkflowTemplateCreator: React.FC = ( return Object.keys(newErrors).length === 0; }; + // 获取参数类型的显示信息 + const getParameterTypeInfo = (type: string) => { + const typeMap = { + string: { label: '字符串', icon: Type, color: 'text-blue-600', bgColor: 'bg-blue-50' }, + integer: { label: '整数', icon: Hash, color: 'text-green-600', bgColor: 'bg-green-50' }, + float: { label: '浮点数', icon: Hash, color: 'text-green-600', bgColor: 'bg-green-50' }, + number: { label: '数字', icon: Hash, color: 'text-green-600', bgColor: 'bg-green-50' }, + boolean: { label: '布尔值', icon: ToggleLeft, color: 'text-purple-600', bgColor: 'bg-purple-50' }, + image: { label: '图片', icon: Image, color: 'text-pink-600', bgColor: 'bg-pink-50' }, + audio: { label: '音频', icon: Music, color: 'text-orange-600', bgColor: 'bg-orange-50' }, + video: { label: '视频', icon: Video, color: 'text-red-600', bgColor: 'bg-red-50' }, + array: { label: '数组', icon: List, color: 'text-indigo-600', bgColor: 'bg-indigo-50' }, + object: { label: '对象', icon: Braces, color: 'text-gray-600', bgColor: 'bg-gray-50' }, + }; + return typeMap[type as keyof typeof typeMap] || typeMap.string; + }; + + // 格式化参数值显示 + const formatParameterValue = (schema: ParameterSchema) => { + if (schema.default === undefined || schema.default === null || schema.default === '') { + return '未设置'; + } + + if (schema.param_type === 'boolean') { + return schema.default ? 'True' : 'False'; + } + + if (schema.param_type === 'integer' || schema.param_type === 'float' || schema.param_type === 'number') { + let value = String(schema.default); + if (schema.min !== undefined || schema.max !== undefined) { + const range = []; + if (schema.min !== undefined) range.push(`最小: ${schema.min}`); + if (schema.max !== undefined) range.push(`最大: ${schema.max}`); + if (range.length > 0) value += ` (${range.join(', ')})`; + } + return value; + } + + if (schema.param_type === 'image' || schema.param_type === 'audio' || schema.param_type === 'video') { + return schema.default || '未设置文件'; + } + + return String(schema.default); + }; + // 处理保存 const handleSave = async () => { if (!validateForm()) { @@ -608,21 +677,73 @@ export const WorkflowTemplateCreator: React.FC = (

添加参数来让模板更加灵活可配置

) : ( -
- {Object.entries(templateData.parameters).map(([paramName, schema]) => ( -
-
-

{paramName}

- -
+
+ {Object.entries(templateData.parameters).map(([paramName, schema]) => { + const typeInfo = getParameterTypeInfo(schema.param_type); + const isExpanded = expandedParameters.has(paramName); + const Icon = typeInfo.icon; -
+ return ( +
+ {/* 折叠头部 - 简洁信息展示 */} +
toggleParameterExpanded(paramName)} + > +
+
+
+ {isExpanded ? ( + + ) : ( + + )} +
+ +
+
+ +
+
+

{paramName}

+ + {typeInfo.label} + + {schema.required && ( + + 必填 + + )} +
+ +
+ 默认值: {formatParameterValue(schema)} + {schema.description && ( + 描述: {schema.description} + )} +
+
+
+ +
+ +
+
+
+ + {/* 展开的详细配置表单 */} + {isExpanded && ( +
+
+ )} +
)}
-
- ))} + ) + })}
)}