/** * WorkflowCard Component * Draggable and resizable workflow card on the canvas */ import React, { useCallback } from 'react'; import { ProjectCanvasItem } from '../types'; // import styles from (TODO: SCSS module - Phase 5) import { WorkflowCardHeader } from './WorkflowCardHeader'; import { WorkflowCardPreview } from './WorkflowCardPreview'; import { WorkflowCardFooter } from './WorkflowCardFooter'; import { WorkflowCardActions } from './WorkflowCardActions'; import { useDragResize } from './useDragResize'; import { testId } from '../../../../hooks/useAccessible'; interface WorkflowCardProps { item: ProjectCanvasItem; workflow: any; isSelected: boolean; onSelect: (id: string, multiSelect: boolean) => void; onUpdatePosition: (id: string, x: number, y: number) => void; onUpdateSize: (id: string, width: number, height: number) => void; onDelete: (id: string) => void; onOpen: (workflowId: string) => void; zoom: number; snapToGrid: (pos: { x: number; y: number }) => { x: number; y: number }; } export const WorkflowCard: React.FC = ({ item, workflow, isSelected, onSelect, onUpdatePosition, onUpdateSize, onDelete, onOpen, zoom, snapToGrid }) => { const { cardRef, isDragging, handleDragStart, handleResizeStart } = useDragResize({ item, zoom, snapToGrid, onUpdatePosition, onUpdateSize }); const handleSelect = useCallback( (e: React.MouseEvent) => { e.stopPropagation(); const multiSelect = e.ctrlKey || e.metaKey || e.shiftKey; onSelect(item.id, multiSelect); }, [item.id, onSelect] ); const nodeCount = workflow?.nodes?.length || 0; const connectionCount = workflow?.connections?.length || 0; return (
{/* SR-only description of workflow info */}
{nodeCount} nodes, {connectionCount} connections. {isSelected ? 'Currently selected.' : ''} {isDragging ? 'Currently dragging.' : ''} Use arrow keys to move, drag to reposition, or resize handles to resize.
); }; export default React.memo(WorkflowCard, (prevProps, nextProps) => { return ( prevProps.item.id === nextProps.item.id && prevProps.item.position.x === nextProps.item.position.x && prevProps.item.position.y === nextProps.item.position.y && prevProps.item.size.width === nextProps.item.size.width && prevProps.item.size.height === nextProps.item.size.height && prevProps.isSelected === nextProps.isSelected && prevProps.item.zIndex === nextProps.item.zIndex ); });