FLOW COMPOSER PHASE 1 2 COMPLETE
Documentation for Plans
๐ Flow Composer - Phase 1 & 2 Complete!
Date: October 13, 2025
Status: โ
PHASES 1-2 COMPLETE
๐ What's Been Implemented
โ Phase 1: Real Port Extraction
File: libs/singularity-lib/src/lib/services/flow-composition.service.ts
Intelligent Port Detection
- Analyzes flow blocks to extract real input/output ports
- Trigger blocks โ Input ports (flow entry points)
- Output blocks โ Output ports (flow exit points)
- Default ports created if no trigger/output blocks found
- Port names extracted from underlying block data
Key Methods
extractInputPorts(flow): FlowPort[] // Finds all trigger blocks
extractOutputPorts(flow): FlowPort[] // Finds all output blocks
Result
- Flows now show REAL ports based on their actual blocks
- No more mock "INPUTS" placeholder!
- Port names, data types, and descriptions extracted from flow structure
โ Phase 2: Flow Node Dragging
Files:
libs/singularity-lib/src/lib/components/flow-composer/flow-composer.component.tslibs/singularity-lib/src/lib/components/flow-composer/components/flow-node/flow-node.component.tslibs/singularity-lib/src/lib/components/flow-composer/flow-composer.component.html
Drag Functionality
- Click and drag flow nodes around the canvas
- Smooth 60fps dragging with transform updates
- Grid snapping when enabled
- Visual feedback - opacity, scale, shadow during drag
- Undo/Redo support - drag positions saved to history
Technical Implementation
// Drag state tracking
isDraggingNode = signal(false)
draggedNodeId = signal<string | null>(null)
dragOffset = signal<{ x: number; y: number }>({ x: 0, y: 0 })
// Mouse event handlers
onFlowNodeMouseDown(event, node) // Start drag
onFlowNodeDrag(event) // Continue drag
onFlowNodeDragEnd() // End drag
Visual Polish
.flow-node.dragging {
opacity: 0.8;
cursor: grabbing;
z-index: 1000;
transform: scale(1.05);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}
๐งช How to Test
Test 1: Port Extraction
- Open Flow Composer (
/singularity/flow-composer) - Drag a flow onto the canvas
- โ
Verify: Flow node shows:
- Real port names (not "INPUTS")
- Input ports from trigger blocks
- Output ports from output blocks
- Port data types displayed
Test 2: Flow Node Dragging
- Open Flow Composer
- Drag a flow onto canvas
- Click and hold on the flow node
- Drag the node around the canvas
- โ
Verify:
- Node follows mouse smoothly
- Node opacity changes to 0.8
- Node scales to 1.05x
- Shadow increases
- Cursor changes to "grabbing"
- Release mouse
- โ
Verify:
- Node stays in new position
- Node returns to normal appearance
- Position persists after save
Test 3: Grid Snapping
- Enable grid in canvas controls
- Drag a node
- โ Verify: Node snaps to grid points (20px intervals)
Test 4: Multiple Nodes
- Drag 3+ flows onto canvas
- Drag each node to different positions
- โ Verify: All nodes can be dragged independently
Test 5: Undo/Redo
- Drag a node
- Press Ctrl+Z to undo
- โ Verify: Node returns to previous position
- Press Ctrl+Y to redo
- โ Verify: Node returns to dragged position
๐ Current Capabilities
| Feature | Status | Notes |
|---|---|---|
| Load flows from storage | โ Working | Fixed storage-system integration |
| Drag flows FROM library | โ Working | Original functionality |
| Drag flows ONTO canvas | โ Working | Original functionality |
| Extract real ports | โ NEW | Trigger & output blocks detected |
| Drag nodes ON canvas | โ NEW | Smooth, grid-snapped dragging |
| Visual drag feedback | โ NEW | Opacity, scale, shadow |
| Undo/Redo dragging | โ NEW | Position history tracking |
| Connect flows | โ Next | Phase 3 |
| SVG connections | โ Next | Phase 3 |
| Validate connections | โ Next | Phase 3 |
๐ฏ What's Next: Phase 3
Connection System Implementation
Will enable:
- Click output port โ input port to create connections
- Visual SVG connection lines
- Connection validation (type checking, cycle detection)
- Connection hover/selection states
- Connection deletion
Estimated Time: 3-4 hours
๐ง Technical Details
Drag Implementation Pattern
// 1. Start drag on mousedown
onFlowNodeMouseDown(event, node) {
// Calculate mouse offset from node position
// Set isDraggingNode = true
// Store draggedNodeId
}
// 2. Update position on mousemove
onFlowNodeDrag(event) {
// Calculate new canvas position
// Apply grid snapping if enabled
// Update node position in flowNodes()
}
// 3. End drag on mouseup
onFlowNodeDragEnd() {
// Save to history for undo/redo
// Reset drag state
}
Canvas Coordinate System
// Screen โ Canvas coordinates
const canvasX = (screenX - rect.left - offset.x) / zoom;
const canvasY = (screenY - rect.top - offset.y) / zoom;
// Grid snapping (20px)
const snappedX = Math.round(canvasX / 20) * 20;
const snappedY = Math.round(canvasY / 20) * 20;
๐ Files Modified
Services
libs/singularity-lib/src/lib/services/flow-composition.service.ts- Enhanced
extractInputPorts() - Enhanced
extractOutputPorts()
- Enhanced
Components
libs/singularity-lib/src/lib/components/flow-composer/flow-composer.component.ts- Added drag state signals
- Added
onFlowNodeMouseDown() - Added
onFlowNodeDrag() - Added
onFlowNodeDragEnd() - Updated
onCanvasMouseMove()to handle node dragging - Updated
onCanvasMouseUp()to end dragging
libs/singularity-lib/src/lib/components/flow-composer/flow-composer.component.html- Added
(mousemove)and(mouseup)to canvas - Added
[dragging]binding to flow nodes - Added
(nodeMouseDown)binding to flow nodes
- Added
libs/singularity-lib/src/lib/components/flow-composer/components/flow-node/flow-node.component.ts- Added
dragginginput - Added
nodeMouseDownoutput - Added
onNodeMouseDown()method - Added
.draggingCSS styles
- Added
๐ Issues Fixed
Port extraction was using mock data
- โ Now extracts real ports from flow blocks
Nodes couldn't be moved after placement
- โ Full drag support with smooth animations
No visual feedback during interactions
- โ Opacity, scale, cursor changes implemented
๐ Architecture Lessons
Signal-Based Reactivity
All drag state managed through Angular signals:
- Automatic UI updates
- No manual change detection
- Clean, declarative code
Event Delegation
- Mouse events handled at canvas level
- Events bubbled up from child components
- Prevents port click conflicts with node dragging
Coordinate Math
- Proper screen-to-canvas coordinate transformation
- Accounts for zoom and pan offsets
- Grid snapping with configurable intervals
Status: โ READY TO TEST
Test the new functionality and we'll move on to Phase 3: Connection System! ๐