cherry-ai/frontend/app/workflow/components/WorkflowSidebar.tsx
2025-05-02 17:31:33 +08:00

47 lines
2.6 KiB
TypeScript

// File: frontend/app/workflow/components/WorkflowSidebar.tsx
// Description: 侧边栏组件,用于拖放节点
import React, { DragEvent } from 'react';
import { MessageSquareText, BrainCircuit, Database, LogOut, Play, CheckCircle, MessageCircleQuestion, MessageCircleReply } from 'lucide-react';
// 定义可拖拽的节点类型 (从 page.tsx 移动过来)
const nodeTypesForPalette = [
{ type: 'startNode', label: '开始流程', icon: Play, defaultData: { label: '开始' } },
{ type: 'inputNode', label: '文本输入', icon: MessageSquareText, defaultData: { text: '用户输入...' } },
{ type: 'llmNode', label: 'LLM 调用', icon: BrainCircuit, defaultData: { model: 'gpt-3.5-turbo', temperature: 0.7, systemPrompt: '你是一个乐于助人的 AI 助手。' } },
{ type: 'ragNode', label: 'RAG 查询', icon: Database, defaultData: { query: '...', knowledgeBase: 'default' } },
{ type: 'outputNode', label: '结束流程', icon: CheckCircle, defaultData: { label: '结束' } },
{ type: 'chatInputNode', label: 'Chat Input', icon: MessageCircleQuestion, defaultData: { text: '' } }, // 添加 ChatInput
{ type: 'chatOutputNode', label: 'Chat Output', icon: MessageCircleReply, defaultData: { displayText: '' } }, // 添加 ChatOutput
];
export const WorkflowSidebar = () => {
const onDragStart = (event: DragEvent, nodeType: string, defaultData: any) => {
const nodeInfo = JSON.stringify({ nodeType, defaultData });
event.dataTransfer.setData('application/reactflow', nodeInfo);
event.dataTransfer.effectAllowed = 'move';
console.log(`Drag Start: ${nodeType}`);
};
return (
<aside className="w-64 bg-white dark:bg-gray-800 p-4 border-r dark:border-gray-700 shadow-md overflow-y-auto flex-shrink-0"> {/* 添加 flex-shrink-0 */}
<h3 className="text-lg font-semibold mb-4 text-gray-800 dark:text-gray-200"></h3>
<p className="text-xs text-gray-500 dark:text-gray-400 mb-4"></p>
<div className="space-y-2">
{nodeTypesForPalette.map((nodeInfo) => (
<div
key={nodeInfo.type}
className="p-3 border dark:border-gray-600 rounded-lg cursor-grab flex items-center gap-2 bg-gray-50 dark:bg-gray-700 hover:bg-gray-100 dark:hover:bg-gray-600 transition-colors"
onDragStart={(event) => onDragStart(event, nodeInfo.type, nodeInfo.defaultData)}
draggable
>
<nodeInfo.icon size={18} className="text-gray-600 dark:text-gray-300 flex-shrink-0" />
<span className="text-sm text-gray-700 dark:text-gray-200">{nodeInfo.label}</span>
</div>
))}
</div>
</aside>
);
};