// ======================================== // Node Palette Component // ======================================== // Draggable node palette for creating new nodes import { DragEvent, useState } from 'react'; import { useIntl } from 'react-intl'; import { Terminal, FileText, GitBranch, GitMerge, ChevronDown, ChevronRight, GripVertical } from 'lucide-react'; import { cn } from '@/lib/utils'; import { Button } from '@/components/ui/Button'; import { useFlowStore } from '@/stores'; import type { FlowNodeType } from '@/types/flow'; import { NODE_TYPE_CONFIGS } from '@/types/flow'; // Icon mapping for node types const nodeIcons: Record> = { 'slash-command': Terminal, 'file-operation': FileText, conditional: GitBranch, parallel: GitMerge, }; // Color mapping for node types const nodeColors: Record = { 'slash-command': 'bg-blue-500 hover:bg-blue-600', 'file-operation': 'bg-green-500 hover:bg-green-600', conditional: 'bg-amber-500 hover:bg-amber-600', parallel: 'bg-purple-500 hover:bg-purple-600', }; const nodeBorderColors: Record = { 'slash-command': 'border-blue-500', 'file-operation': 'border-green-500', conditional: 'border-amber-500', parallel: 'border-purple-500', }; interface NodePaletteProps { className?: string; } interface NodeTypeCardProps { type: FlowNodeType; } function NodeTypeCard({ type }: NodeTypeCardProps) { const config = NODE_TYPE_CONFIGS[type]; const Icon = nodeIcons[type]; // Handle drag start const onDragStart = (event: DragEvent) => { event.dataTransfer.setData('application/reactflow-node-type', type); event.dataTransfer.effectAllowed = 'move'; }; return (
{config.label}
{config.description}
); } export function NodePalette({ className }: NodePaletteProps) { const { formatMessage } = useIntl(); const [isExpanded, setIsExpanded] = useState(true); const isPaletteOpen = useFlowStore((state) => state.isPaletteOpen); const setIsPaletteOpen = useFlowStore((state) => state.setIsPaletteOpen); if (!isPaletteOpen) { return (
); } return (
{/* Header */}

{formatMessage({ id: 'orchestrator.palette.title' })}

{/* Instructions */}
{formatMessage({ id: 'orchestrator.palette.instructions' })}
{/* Node Type Categories */}
{/* Execution Nodes */}
{isExpanded && (
{(Object.keys(NODE_TYPE_CONFIGS) as FlowNodeType[]).map((type) => ( ))}
)}
{/* Footer */}
{formatMessage({ id: 'orchestrator.palette.tipLabel' })} {formatMessage({ id: 'orchestrator.palette.tip' })}
); } export default NodePalette;