45 lines
2.3 KiB
TypeScript
45 lines
2.3 KiB
TypeScript
// File: frontend/app/workflow/components/WorkflowSidebar.tsx
|
|
// Description: 侧边栏组件,用于拖放节点
|
|
|
|
import React, { DragEvent } from 'react';
|
|
import { MessageSquareText, BrainCircuit, Database, LogOut, Play, CheckCircle } 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: '结束' } },
|
|
];
|
|
|
|
|
|
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>
|
|
);
|
|
};
|