@nyaruka/temba-components 0.142.2 → 0.142.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/temba-components.js +266 -192
  3. package/dist/temba-components.js.map +1 -1
  4. package/out-tsc/src/flow/CanvasMenu.js +8 -3
  5. package/out-tsc/src/flow/CanvasMenu.js.map +1 -1
  6. package/out-tsc/src/flow/CanvasNode.js +158 -9
  7. package/out-tsc/src/flow/CanvasNode.js.map +1 -1
  8. package/out-tsc/src/flow/Editor.js +473 -17
  9. package/out-tsc/src/flow/Editor.js.map +1 -1
  10. package/out-tsc/src/flow/NodeEditor.js +8 -8
  11. package/out-tsc/src/flow/NodeEditor.js.map +1 -1
  12. package/out-tsc/src/flow/Plumber.js +89 -27
  13. package/out-tsc/src/flow/Plumber.js.map +1 -1
  14. package/out-tsc/src/flow/StickyNote.js +63 -3
  15. package/out-tsc/src/flow/StickyNote.js.map +1 -1
  16. package/out-tsc/src/flow/actions/send_msg.js +11 -8
  17. package/out-tsc/src/flow/actions/send_msg.js.map +1 -1
  18. package/out-tsc/src/flow/nodes/split_by_subflow.js +3 -1
  19. package/out-tsc/src/flow/nodes/split_by_subflow.js.map +1 -1
  20. package/out-tsc/src/flow/utils.js +1 -3
  21. package/out-tsc/src/flow/utils.js.map +1 -1
  22. package/out-tsc/src/list/SortableList.js +104 -43
  23. package/out-tsc/src/list/SortableList.js.map +1 -1
  24. package/out-tsc/src/simulator/Simulator.js +5 -1
  25. package/out-tsc/src/simulator/Simulator.js.map +1 -1
  26. package/package.json +1 -1
  27. package/screenshots/truth/actions/send_msg/render/long-quick-replies.png +0 -0
  28. package/screenshots/truth/actions/send_msg/render/text-with-many-quick-replies.png +0 -0
  29. package/screenshots/truth/actions/send_msg/render/text-with-quick-replies.png +0 -0
  30. package/src/flow/CanvasMenu.ts +12 -4
  31. package/src/flow/CanvasNode.ts +185 -9
  32. package/src/flow/Editor.ts +552 -19
  33. package/src/flow/NodeEditor.ts +12 -12
  34. package/src/flow/Plumber.ts +101 -36
  35. package/src/flow/StickyNote.ts +76 -4
  36. package/src/flow/actions/send_msg.ts +11 -8
  37. package/src/flow/nodes/split_by_subflow.ts +3 -1
  38. package/src/flow/utils.ts +1 -3
  39. package/src/list/SortableList.ts +117 -47
  40. package/src/simulator/Simulator.ts +5 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Plumber.js","sourceRoot":"","sources":["../../../src/flow/Plumber.ts"],"names":[],"mappings":"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","sourcesContent":["import { isRightClick } from './utils';\n\nexport type TargetFace = 'top' | 'left' | 'right';\n\n// Shared arrow/drag constants used by both Plumber and Editor\nexport const ARROW_LENGTH = 13;\nexport const ARROW_HALF_WIDTH = 6.5;\nexport const CURSOR_GAP = 1;\nexport const EXIT_STUB = 30;\n\ninterface ConnectionEndpoints {\n sourceX: number;\n sourceY: number;\n targetX: number;\n targetY: number;\n targetFace: TargetFace;\n jogYOffset: number;\n}\n\ninterface ConnectionInfo {\n scope: string; // nodeId\n fromId: string; // exitId\n toId: string; // target nodeId\n svgEl: SVGSVGElement;\n pathEl: SVGPathElement;\n arrowEl: SVGPolygonElement;\n}\n\ninterface DragState {\n sourceId: string;\n scope: string;\n originalTargetId: string | null;\n svgEl: SVGSVGElement;\n pathEl: SVGPathElement;\n arrowEl: SVGPolygonElement;\n onMove: (e: MouseEvent) => void;\n onUp: (e: MouseEvent) => void;\n}\n\n/**\n * Calculate a flowchart-style SVG path between two points.\n * Routes with right-angle segments, stubs at each end, and rounded corners.\n * Supports entering the target from top, left, or right faces.\n */\nexport function calculateFlowchartPath(\n sourceX: number,\n sourceY: number,\n targetX: number,\n targetY: number,\n stubStart = 20,\n stubEnd = 10,\n cornerRadius = 5,\n targetFace: TargetFace = 'top',\n jogYOffset = 0\n): string {\n const r = cornerRadius;\n\n if (targetFace === 'top') {\n // Target is below (or we treat it as such): exit down, horizontal jog, enter from top\n const exitY = sourceY + stubStart;\n const entryY = targetY - stubEnd;\n\n let d = `M ${sourceX} ${sourceY}`;\n\n if (sourceX === targetX) {\n // Straight vertical — no turns needed\n d += ` L ${targetX} ${entryY}`;\n } else {\n // L-shape: exit curves horizontal, then straight down to target.\n // jogY is the horizontal level — must be above entryY so the\n // final approach into the node is always downward (no backtracking).\n const dirX = targetX > sourceX ? 1 : -1;\n const baseJogY = Math.max(sourceY + r, Math.min(exitY, entryY - r));\n const jogY = Math.max(\n sourceY + r,\n Math.min(baseJogY + jogYOffset, entryY - r - 3)\n );\n\n // Corner 1: vertical→horizontal at jogY\n const r1 = Math.min(r, jogY - sourceY);\n if (r1 >= 1) {\n d += ` L ${sourceX} ${jogY - r1}`;\n d += ` Q ${sourceX} ${jogY}, ${sourceX + dirX * r1} ${jogY}`;\n } else {\n d += ` L ${sourceX} ${jogY}`;\n }\n\n // Corner 2: horizontal→vertical at targetX — leave minSeg of\n // straight line after the curve before reaching entryY\n const minSeg = 3;\n const r2 = Math.min(r, Math.max(0, entryY - jogY - minSeg));\n if (r2 >= 1) {\n d += ` L ${targetX - dirX * r2} ${jogY}`;\n d += ` Q ${targetX} ${jogY}, ${targetX} ${jogY + r2}`;\n } else {\n d += ` L ${targetX} ${jogY}`;\n }\n d += ` L ${targetX} ${entryY}`;\n }\n\n d += ` L ${targetX} ${targetY}`;\n return d;\n }\n\n if (targetFace === 'left' || targetFace === 'right') {\n // Route: exit down from source, horizontal jog, vertical to target Y, stub into side\n // When target is above source, skip the exit stub so the path turns horizontal\n // as quickly as possible (only the corner radius creates downward travel)\n const goingUp = targetY < sourceY;\n const exitY = sourceY + (goingUp ? 0 : stubStart);\n const sideDir = targetFace === 'left' ? -1 : 1;\n // Entry point is OUTSIDE the node boundary (stub behind arrowhead)\n const entryX = targetX + sideDir * stubEnd;\n\n const dirX = entryX > sourceX ? 1 : -1;\n\n // Minimum straight segment after each curve\n const minSeg = 3;\n\n // When the horizontal approach would double-back over the stub\n // (dirX matches sideDir), keep midY at the natural exit level so\n // the path jogs horizontally ABOVE the target and descends into\n // the stub — never dipping past the target and curving back up.\n // For non-backtrack, midY goes to targetY for a direct entry.\n const midY =\n dirX === sideDir ? exitY + r * 2 : Math.max(exitY + r * 2, targetY);\n\n let d = `M ${sourceX} ${sourceY} L ${sourceX} ${exitY}`;\n\n // Corner 1: vertical→horizontal at (sourceX, midY)\n if (midY - exitY > r) {\n d += ` L ${sourceX} ${midY - r}`;\n d += ` Q ${sourceX} ${midY}, ${sourceX + dirX * r} ${midY}`;\n }\n\n const vertGap = Math.abs(midY - targetY);\n\n if (vertGap < 1) {\n // midY ≈ targetY — horizontal to entryX, then stub into face\n d += ` L ${entryX} ${targetY}`;\n d += ` L ${targetX} ${targetY}`;\n } else {\n // Corners 2 and 3 — turnR is limited so that at least minSeg of\n // straight line remains between the two corners and after corner 3\n const turnDir = targetY < midY ? -1 : 1;\n const turnR = Math.min(\n r,\n Math.max(0, Math.floor((vertGap - minSeg) / 2)),\n Math.max(0, stubEnd - minSeg)\n );\n\n if (turnR >= 1) {\n // Corner 2: horizontal→vertical at (entryX, midY)\n d += ` L ${entryX - dirX * turnR} ${midY}`;\n d += ` Q ${entryX} ${midY}, ${entryX} ${midY + turnDir * turnR}`;\n // Vertical toward targetY\n d += ` L ${entryX} ${targetY - turnDir * turnR}`;\n // Corner 3: vertical→horizontal into side face\n d += ` Q ${entryX} ${targetY}, ${entryX - sideDir * turnR} ${targetY}`;\n } else {\n d += ` L ${entryX} ${midY}`;\n d += ` L ${entryX} ${targetY}`;\n }\n // Horizontal stub into target face\n d += ` L ${targetX} ${targetY}`;\n }\n\n return d;\n }\n\n return `M ${sourceX} ${sourceY} L ${targetX} ${targetY}`;\n}\n\nexport class Plumber {\n private connections: Map<string, ConnectionInfo> = new Map();\n private sources: Map<string, () => void> = new Map(); // exitId → cleanup fn\n private canvas: HTMLElement;\n private pendingConnections: {\n scope: string;\n fromId: string;\n toId: string;\n }[] = [];\n private connectionWait: number | null = null;\n private connectionListeners: Map<string, ((info: any) => void)[]> = new Map();\n private dragState: DragState | null = null;\n private editor: any;\n private retryCount = 0;\n private maxRetries = 3;\n\n // Activity overlay state\n private activityData: { segments: { [key: string]: number } } | null = null;\n private overlays: Map<string, HTMLElement> = new Map();\n private hoveredActivityKey: string | null = null;\n private recentContactsPopup: HTMLElement | null = null;\n private recentContactsCache: { [key: string]: any[] } = {};\n private pendingFetches: { [key: string]: AbortController } = {};\n private hideContactsTimeout: number | null = null;\n private showContactsTimeout: number | null = null;\n\n public connectionDragging = false;\n public zoom = 1.0;\n\n constructor(canvas: HTMLElement, editor: any) {\n this.canvas = canvas;\n this.editor = editor;\n }\n\n // --- Event system ---\n\n private notifyListeners(eventName: string, info: any) {\n const listeners = this.connectionListeners.get(eventName) || [];\n listeners.forEach((listener) => listener(info));\n }\n\n public on(eventName: string, callback: (info: any) => void) {\n if (!this.connectionListeners.has(eventName)) {\n this.connectionListeners.set(eventName, []);\n }\n this.connectionListeners.get(eventName).push(callback);\n }\n\n public off(eventName: string, callback: (info: any) => void) {\n if (!this.connectionListeners.has(eventName)) return;\n const listeners = this.connectionListeners.get(eventName);\n const index = listeners.indexOf(callback);\n if (index !== -1) {\n listeners.splice(index, 1);\n }\n }\n\n // --- Source/Target registration ---\n\n public makeSource(exitId: string) {\n const element = document.getElementById(exitId);\n if (!element) return;\n\n // Clean up any existing listener for this exit\n if (this.sources.has(exitId)) {\n this.sources.get(exitId)();\n }\n\n let pendingDrag: {\n startX: number;\n startY: number;\n onMove: (e: MouseEvent) => void;\n onUp: (e: MouseEvent) => void;\n } | null = null;\n\n const DRAG_THRESHOLD = 5;\n\n const onMouseDown = (e: MouseEvent) => {\n if (isRightClick(e)) return;\n\n // Don't start drag from exit if it already has a connection —\n // existing connections are picked up from the arrowhead instead\n if (this.connections.has(exitId)) return;\n\n const startX = e.clientX;\n const startY = e.clientY;\n\n const nodeEl = element.closest('temba-flow-node');\n const scope = nodeEl?.getAttribute('uuid') || '';\n const originalTargetId: string | null = null;\n\n const onMove = (me: MouseEvent) => {\n const dx = me.clientX - startX;\n const dy = me.clientY - startY;\n if (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD) {\n // Exceeded threshold — start actual drag\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n pendingDrag = null;\n this.startDrag(exitId, scope, originalTargetId, me);\n }\n };\n\n const onUp = () => {\n // Mouse released without dragging — let click handler fire\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n pendingDrag = null;\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n pendingDrag = { startX, startY, onMove, onUp };\n };\n\n element.addEventListener('mousedown', onMouseDown);\n this.sources.set(exitId, () => {\n element.removeEventListener('mousedown', onMouseDown);\n if (pendingDrag) {\n document.removeEventListener('mousemove', pendingDrag.onMove);\n document.removeEventListener('mouseup', pendingDrag.onUp);\n pendingDrag = null;\n }\n });\n }\n\n public makeTarget(_nodeId: string) {\n // No-op: target detection happens via DOM hover during drag\n }\n\n // --- Connection creation ---\n\n public connectIds(scope: string, fromId: string, toId: string) {\n this.pendingConnections.push({ scope, fromId, toId });\n this.processPendingConnections();\n }\n\n public processPendingConnections() {\n if (this.connectionWait) {\n cancelAnimationFrame(this.connectionWait);\n this.connectionWait = null;\n }\n\n this.connectionWait = requestAnimationFrame(() => {\n const failed: { scope: string; fromId: string; toId: string }[] = [];\n const createdTargets = new Set<string>();\n\n this.pendingConnections.forEach((conn) => {\n const { scope, fromId, toId } = conn;\n // Remove existing connection from this exit if any\n this.removeConnectionSVG(fromId);\n if (!this.createConnectionSVG(fromId, scope, toId)) {\n failed.push(conn);\n } else {\n createdTargets.add(toId);\n }\n });\n this.pendingConnections = [];\n\n // Repaint all connections that share a target or source with newly\n // created ones so anchor distribution and jogY offsets are correct\n if (createdTargets.size > 0) {\n const createdScopes = new Set<string>();\n this.connections.forEach((conn) => {\n if (createdTargets.has(conn.toId)) {\n createdScopes.add(conn.scope);\n }\n });\n this.connections.forEach((conn, exitId) => {\n if (createdTargets.has(conn.toId) || createdScopes.has(conn.scope)) {\n this.updateConnectionSVG(exitId);\n }\n });\n }\n\n // Retry failed connections (elements may not be laid out yet)\n if (failed.length > 0 && this.retryCount < this.maxRetries) {\n this.retryCount++;\n this.pendingConnections = failed;\n this.processPendingConnections();\n } else {\n this.retryCount = 0;\n }\n });\n }\n\n // --- Anchor point distribution ---\n\n /** Convert a viewport-to-canvas rect difference to canvas coordinates */\n private toCanvas(viewportDiff: number): number {\n return viewportDiff / this.zoom;\n }\n\n private determineTargetFace(\n sourceX: number,\n sourceY: number,\n targetCenterX: number,\n targetTop: number\n ): TargetFace {\n const verticalGap = targetTop - sourceY;\n\n // Top face requires enough vertical room for the exit stub, entry stub,\n // arrow, and curved corners. Below this threshold the path components\n // overlap and the connection backtracks, so use a side face instead.\n if (verticalGap > 30) {\n return 'top';\n }\n\n // Source is level with, below, or too close to target — connect to a side face\n if (sourceX < targetCenterX) {\n return 'left';\n }\n return 'right';\n }\n\n private getConnectionEndpoints(\n fromId: string,\n toId: string,\n scope?: string\n ): ConnectionEndpoints | null {\n const fromEl = document.getElementById(fromId);\n const toEl = document.getElementById(toId);\n if (!fromEl || !toEl) return null;\n\n const canvasRect = this.canvas.getBoundingClientRect();\n const fromRect = fromEl.getBoundingClientRect();\n const toRect = toEl.getBoundingClientRect();\n\n if (fromRect.width === 0 || toRect.width === 0) return null;\n\n // All coordinates are converted to canvas space by dividing by zoom\n const sourceX = this.toCanvas(\n fromRect.left + fromRect.width / 2 - canvasRect.left\n );\n const sourceY = this.toCanvas(fromRect.bottom - canvasRect.top);\n\n // Pre-compute target canvas-space values for determineTargetFace\n const toCenterX = this.toCanvas(\n toRect.left + toRect.width / 2 - canvasRect.left\n );\n const toTopCanvas = this.toCanvas(toRect.top - canvasRect.top);\n\n const targetFace = this.determineTargetFace(\n sourceX,\n sourceY,\n toCenterX,\n toTopCanvas\n );\n\n // Find all connections targeting the same node, grouped by face\n // Track source position for spatial sorting\n const faceConnections: Map<\n TargetFace,\n { fromId: string; sortPos: number }[]\n > = new Map();\n this.connections.forEach((conn) => {\n if (conn.toId === toId) {\n const connFromEl = document.getElementById(conn.fromId);\n if (connFromEl) {\n const connFromRect = connFromEl.getBoundingClientRect();\n const connSourceX = this.toCanvas(\n connFromRect.left + connFromRect.width / 2 - canvasRect.left\n );\n const connSourceY = this.toCanvas(\n connFromRect.bottom - canvasRect.top\n );\n const face = this.determineTargetFace(\n connSourceX,\n connSourceY,\n toCenterX,\n toTopCanvas\n );\n if (!faceConnections.has(face)) {\n faceConnections.set(face, []);\n }\n // Sort position: X for top face, Y for side faces\n const sortPos = face === 'top' ? connSourceX : connSourceY;\n faceConnections.get(face).push({ fromId: conn.fromId, sortPos });\n }\n }\n });\n\n // Add current connection to its face group if not already tracked\n if (!faceConnections.has(targetFace)) {\n faceConnections.set(targetFace, []);\n }\n const faceGroup = faceConnections.get(targetFace);\n if (!faceGroup.find((e) => e.fromId === fromId)) {\n const sortPos = targetFace === 'top' ? sourceX : sourceY;\n faceGroup.push({ fromId, sortPos });\n }\n\n // Sort by spatial position so connections don't cross\n faceGroup.sort((a, b) => a.sortPos - b.sortPos);\n const index = faceGroup.findIndex((e) => e.fromId === fromId);\n const count = faceGroup.length;\n\n // Calculate anchor point on the chosen face (all in canvas space)\n const targetLeft = this.toCanvas(toRect.left - canvasRect.left);\n const targetTop = toTopCanvas;\n const targetW = this.toCanvas(toRect.width);\n const targetH = this.toCanvas(toRect.height);\n\n let targetX: number;\n let targetY: number;\n\n if (targetFace === 'top') {\n // Distribute across top face (middle 60% of width)\n const margin = targetW * 0.2;\n const span = targetW * 0.6;\n targetX =\n count === 1\n ? targetLeft + targetW / 2\n : targetLeft + margin + (span * (index + 0.5)) / count;\n targetY = targetTop;\n } else if (targetFace === 'left') {\n targetX = targetLeft;\n // Distribute along left face (middle 60% of height)\n const margin = targetH * 0.2;\n const span = targetH * 0.6;\n targetY =\n count === 1\n ? targetTop + targetH / 2\n : targetTop + margin + (span * (index + 0.5)) / count;\n } else {\n // right\n targetX = targetLeft + targetW;\n const margin = targetH * 0.2;\n const span = targetH * 0.6;\n targetY =\n count === 1\n ? targetTop + targetH / 2\n : targetTop + margin + (span * (index + 0.5)) / count;\n }\n\n // Compute jogYOffset: stagger horizontal segments for sibling exits\n // from the same source node so paths don't overlap\n let jogYOffset = 0;\n if (targetFace === 'top' && scope) {\n const SIBLING_SPACING = 8;\n const MAX_SPREAD = 50;\n\n const siblings: { fromId: string; targetX: number }[] = [];\n this.connections.forEach((conn) => {\n if (conn.scope === scope && conn.toId !== toId) {\n const connFromEl = document.getElementById(conn.fromId);\n const connToEl = document.getElementById(conn.toId);\n if (connFromEl && connToEl) {\n const connFromRect = connFromEl.getBoundingClientRect();\n const connToRect = connToEl.getBoundingClientRect();\n const connSourceX = this.toCanvas(\n connFromRect.left + connFromRect.width / 2 - canvasRect.left\n );\n const connSourceY = this.toCanvas(\n connFromRect.bottom - canvasRect.top\n );\n const connToCenterX = this.toCanvas(\n connToRect.left + connToRect.width / 2 - canvasRect.left\n );\n const connToTop = this.toCanvas(connToRect.top - canvasRect.top);\n const connFace = this.determineTargetFace(\n connSourceX,\n connSourceY,\n connToCenterX,\n connToTop\n );\n if (connFace === 'top') {\n const connTargetLeft = this.toCanvas(\n connToRect.left - canvasRect.left\n );\n const connTargetW = this.toCanvas(connToRect.width);\n siblings.push({\n fromId: conn.fromId,\n targetX: connTargetLeft + connTargetW / 2\n });\n }\n }\n }\n });\n\n if (siblings.length > 0) {\n siblings.push({ fromId, targetX });\n siblings.sort((a, b) => a.targetX - b.targetX);\n const idx = siblings.findIndex((s) => s.fromId === fromId);\n const sibCount = siblings.length;\n const rawSpread = (sibCount - 1) * SIBLING_SPACING;\n const spacing =\n rawSpread > MAX_SPREAD\n ? MAX_SPREAD / (sibCount - 1)\n : SIBLING_SPACING;\n jogYOffset = (idx - (sibCount - 1) / 2) * spacing;\n }\n }\n\n return { sourceX, sourceY, targetX, targetY, targetFace, jogYOffset };\n }\n\n // --- SVG creation and management ---\n\n private createSVGElement(): {\n svgEl: SVGSVGElement;\n pathEl: SVGPathElement;\n arrowEl: SVGPolygonElement;\n } {\n const svgEl = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svgEl.classList.add('plumb-connector');\n svgEl.style.position = 'absolute';\n svgEl.style.left = '0';\n svgEl.style.top = '0';\n svgEl.style.width = '100%';\n svgEl.style.height = '100%';\n svgEl.style.pointerEvents = 'none';\n svgEl.style.overflow = 'visible';\n\n const pathEl = document.createElementNS(\n 'http://www.w3.org/2000/svg',\n 'path'\n );\n pathEl.setAttribute('fill', 'none');\n pathEl.setAttribute('stroke', 'var(--color-connectors)');\n pathEl.setAttribute('stroke-width', '3');\n pathEl.style.pointerEvents = 'stroke';\n\n const arrowEl = document.createElementNS(\n 'http://www.w3.org/2000/svg',\n 'polygon'\n );\n arrowEl.setAttribute('fill', 'var(--color-connectors)');\n arrowEl.classList.add('plumb-arrow');\n arrowEl.style.pointerEvents = 'fill';\n arrowEl.style.cursor = 'pointer';\n\n svgEl.appendChild(pathEl);\n svgEl.appendChild(arrowEl);\n\n // Hover support\n const addHover = () => svgEl.classList.add('hover');\n const removeHover = () => svgEl.classList.remove('hover');\n pathEl.addEventListener('mouseenter', addHover);\n pathEl.addEventListener('mouseleave', removeHover);\n arrowEl.addEventListener('mouseenter', addHover);\n arrowEl.addEventListener('mouseleave', removeHover);\n\n return { svgEl, pathEl, arrowEl };\n }\n\n private updateSVGPath(\n pathEl: SVGPathElement,\n arrowEl: SVGPolygonElement,\n sourceX: number,\n sourceY: number,\n targetX: number,\n targetY: number,\n targetFace: TargetFace = 'top',\n jogYOffset = 0\n ) {\n const aw = ARROW_HALF_WIDTH;\n const al = ARROW_LENGTH;\n const stubBehindArrow = 8;\n\n // Path ends at arrow BASE (not tip) so the line never pokes through the front.\n // The arrow polygon covers from base to the node edge (tip).\n let pathTargetX = targetX;\n let pathTargetY = targetY;\n if (targetFace === 'top') {\n pathTargetY = targetY - al;\n } else if (targetFace === 'left') {\n pathTargetX = targetX - al;\n } else if (targetFace === 'right') {\n pathTargetX = targetX + al;\n }\n\n const effectiveStub = stubBehindArrow;\n const d = calculateFlowchartPath(\n sourceX,\n sourceY,\n pathTargetX,\n pathTargetY,\n EXIT_STUB,\n effectiveStub,\n 5,\n targetFace,\n jogYOffset\n );\n pathEl.setAttribute('d', d);\n\n // Arrow tip at node edge, base extends outward\n if (targetFace === 'top') {\n arrowEl.setAttribute(\n 'points',\n `${targetX},${targetY} ${targetX - aw},${targetY - al} ${\n targetX + aw\n },${targetY - al}`\n );\n } else if (targetFace === 'left') {\n arrowEl.setAttribute(\n 'points',\n `${targetX},${targetY} ${targetX - al},${targetY - aw} ${\n targetX - al\n },${targetY + aw}`\n );\n } else {\n arrowEl.setAttribute(\n 'points',\n `${targetX},${targetY} ${targetX + al},${targetY - aw} ${\n targetX + al\n },${targetY + aw}`\n );\n }\n }\n\n private createConnectionSVG(\n exitId: string,\n scope: string,\n toId: string\n ): boolean {\n const endpoints = this.getConnectionEndpoints(exitId, toId, scope);\n if (!endpoints) return false;\n\n const { svgEl, pathEl, arrowEl } = this.createSVGElement();\n this.updateSVGPath(\n pathEl,\n arrowEl,\n endpoints.sourceX,\n endpoints.sourceY,\n endpoints.targetX,\n endpoints.targetY,\n endpoints.targetFace,\n endpoints.jogYOffset\n );\n this.canvas.appendChild(svgEl);\n\n this.connections.set(exitId, {\n scope,\n fromId: exitId,\n toId,\n svgEl,\n pathEl,\n arrowEl\n });\n\n // Make arrowhead draggable for picking up existing connections\n const DRAG_THRESHOLD = 5;\n const onArrowMouseDown = (e: MouseEvent) => {\n if (isRightClick(e)) return;\n e.stopPropagation();\n\n const startX = e.clientX;\n const startY = e.clientY;\n\n const onMove = (me: MouseEvent) => {\n const dx = me.clientX - startX;\n const dy = me.clientY - startY;\n if (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD) {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n this.startDrag(exitId, scope, toId, me);\n }\n };\n\n const onUp = () => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n };\n arrowEl.addEventListener('mousedown', onArrowMouseDown);\n\n // Mark the exit element as connected\n const exitEl = document.getElementById(exitId);\n if (exitEl) {\n exitEl.classList.add('connected');\n }\n\n // Create activity overlay if activity data exists for this segment\n if (this.activityData) {\n const activityKey = `${exitId}:${toId}`;\n const count = this.activityData.segments[activityKey];\n if (count && count > 0) {\n const overlayEl = this.createOverlayElement(count, activityKey);\n this.canvas.appendChild(overlayEl);\n this.overlays.set(exitId, overlayEl);\n this.updateOverlayPosition(exitId);\n }\n }\n\n return true;\n }\n\n private updateConnectionSVG(exitId: string) {\n const conn = this.connections.get(exitId);\n if (!conn) return;\n\n const endpoints = this.getConnectionEndpoints(\n conn.fromId,\n conn.toId,\n conn.scope\n );\n if (!endpoints) return;\n\n this.updateSVGPath(\n conn.pathEl,\n conn.arrowEl,\n endpoints.sourceX,\n endpoints.sourceY,\n endpoints.targetX,\n endpoints.targetY,\n endpoints.targetFace,\n endpoints.jogYOffset\n );\n this.updateOverlayPosition(exitId);\n }\n\n private removeConnectionSVG(exitId: string) {\n const conn = this.connections.get(exitId);\n if (!conn) return;\n\n const overlay = this.overlays.get(exitId);\n if (overlay) {\n overlay.remove();\n this.overlays.delete(exitId);\n }\n\n conn.svgEl.remove();\n this.connections.delete(exitId);\n }\n\n // --- Repaint ---\n\n public repaintEverything() {\n this.connections.forEach((_conn, exitId) => {\n this.updateConnectionSVG(exitId);\n });\n }\n\n public revalidate(ids: string[]) {\n // Find all connections directly involving the given IDs\n const directExits: string[] = [];\n const affectedTargets = new Set<string>();\n\n this.connections.forEach((conn, exitId) => {\n if (\n ids.includes(conn.fromId) ||\n ids.includes(conn.toId) ||\n ids.includes(conn.scope)\n ) {\n directExits.push(exitId);\n affectedTargets.add(conn.toId);\n }\n });\n\n // Also repaint sibling connections that share a target\n // (so anchor distribution stays correct during drag)\n const allExitsToRepaint = new Set(directExits);\n this.connections.forEach((conn, exitId) => {\n if (affectedTargets.has(conn.toId)) {\n allExitsToRepaint.add(exitId);\n }\n });\n\n allExitsToRepaint.forEach((exitId) => {\n this.updateConnectionSVG(exitId);\n });\n }\n\n // --- Connection removal ---\n\n public forgetNode(nodeId: string) {\n // Remove all connections where this node is source or target\n const toRemove: string[] = [];\n this.connections.forEach((conn, exitId) => {\n if (conn.scope === nodeId || conn.toId === nodeId) {\n toRemove.push(exitId);\n }\n });\n toRemove.forEach((exitId) => this.removeConnectionSVG(exitId));\n\n // Remove source listeners for exits of this node\n const exitEls = document.getElementById(nodeId)?.querySelectorAll('.exit');\n if (exitEls) {\n exitEls.forEach((el) => {\n const id = el.id;\n if (this.sources.has(id)) {\n this.sources.get(id)();\n this.sources.delete(id);\n }\n });\n }\n }\n\n public removeNodeConnections(nodeId: string, exitIds?: string[]) {\n // Only remove outbound connections from this node's exits.\n // Inbound connections are managed by their source nodes and\n // will repaint correctly on the next revalidate.\n const exits =\n exitIds ||\n Array.from(\n document.getElementById(nodeId)?.querySelectorAll('.exit') || []\n ).map((el) => el.id);\n\n exits.forEach((exitId) => this.removeConnectionSVG(exitId));\n }\n\n public removeExitConnection(exitId: string): boolean {\n if (!this.connections.has(exitId)) return false;\n this.removeConnectionSVG(exitId);\n return true;\n }\n\n public removeAllEndpoints(nodeId: string) {\n // Remove source listeners for this node's exits\n const exitEls = document.getElementById(nodeId)?.querySelectorAll('.exit');\n if (exitEls) {\n exitEls.forEach((el) => {\n const id = el.id;\n if (this.sources.has(id)) {\n this.sources.get(id)();\n this.sources.delete(id);\n }\n });\n }\n }\n\n // --- Connection state ---\n\n public setConnectionRemovingState(\n exitId: string,\n isRemoving: boolean\n ): boolean {\n const conn = this.connections.get(exitId);\n if (!conn) return false;\n\n if (isRemoving) {\n conn.svgEl.classList.add('removing');\n } else {\n conn.svgEl.classList.remove('removing');\n }\n return true;\n }\n\n // --- Activity overlays ---\n\n public setActivityData(\n activityData: { segments: { [key: string]: number } } | null\n ) {\n this.activityData = activityData;\n this.clearRecentContactsCache();\n this.updateActivityOverlays();\n }\n\n private updateActivityOverlays() {\n if (!this.activityData) {\n this.overlays.forEach((el) => el.remove());\n this.overlays.clear();\n return;\n }\n\n const activeExitIds = new Set<string>();\n\n this.connections.forEach((conn, exitId) => {\n const activityKey = `${conn.fromId}:${conn.toId}`;\n const count = this.activityData.segments[activityKey];\n\n if (count && count > 0) {\n activeExitIds.add(exitId);\n let overlayEl = this.overlays.get(exitId);\n\n if (!overlayEl) {\n overlayEl = this.createOverlayElement(count, activityKey);\n this.canvas.appendChild(overlayEl);\n this.overlays.set(exitId, overlayEl);\n } else {\n overlayEl.textContent = count.toLocaleString();\n overlayEl.setAttribute('data-activity-key', activityKey);\n }\n\n this.updateOverlayPosition(exitId);\n }\n });\n\n // Remove overlays for connections that no longer have activity\n this.overlays.forEach((el, exitId) => {\n if (!activeExitIds.has(exitId)) {\n el.remove();\n this.overlays.delete(exitId);\n }\n });\n }\n\n private createOverlayElement(\n count: number,\n activityKey: string\n ): HTMLElement {\n const el = document.createElement('div');\n el.className = 'activity-overlay';\n el.textContent = count.toLocaleString();\n el.setAttribute('data-activity-key', activityKey);\n\n el.addEventListener('mouseenter', () => {\n const flowUuid = this.getFlowUuid();\n if (flowUuid) {\n this.fetchRecentContacts(activityKey, flowUuid);\n this.showContactsTimeout = window.setTimeout(() => {\n this.showRecentContacts(activityKey, flowUuid);\n }, 500);\n }\n });\n\n el.addEventListener('mouseleave', () => {\n if (this.showContactsTimeout) {\n clearTimeout(this.showContactsTimeout);\n this.showContactsTimeout = null;\n }\n this.hoveredActivityKey = null;\n this.hideRecentContacts();\n });\n\n return el;\n }\n\n private updateOverlayPosition(exitId: string) {\n const overlayEl = this.overlays.get(exitId);\n const conn = this.connections.get(exitId);\n if (!overlayEl || !conn) return;\n\n const endpoints = this.getConnectionEndpoints(\n conn.fromId,\n conn.toId,\n conn.scope\n );\n if (!endpoints) return;\n\n overlayEl.style.position = 'absolute';\n overlayEl.style.left = `${endpoints.sourceX}px`;\n overlayEl.style.top = `${endpoints.sourceY + EXIT_STUB / 2}px`;\n overlayEl.style.transform = 'translate(-50%, -50%)';\n }\n\n private getFlowUuid(): string | null {\n return this.editor?.definition?.uuid || null;\n }\n\n // --- Recent contacts ---\n\n private async fetchRecentContacts(activityKey: string, flowUuid: string) {\n if (\n this.recentContactsCache[activityKey] ||\n this.pendingFetches[activityKey]\n ) {\n return;\n }\n\n const controller = new AbortController();\n this.pendingFetches[activityKey] = controller;\n\n try {\n const [exitUuid, destinationUuid] = activityKey.split(':');\n const endpoint = `/flow/recent_contacts/${flowUuid}/${exitUuid}/${destinationUuid}/`;\n const response = await fetch(endpoint, { signal: controller.signal });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const data = await response.json();\n this.recentContactsCache[activityKey] = Array.isArray(data)\n ? data\n : data.results || [];\n } catch (error) {\n if ((error as Error).name !== 'AbortError') {\n console.error('Failed to fetch recent contacts:', error);\n }\n } finally {\n delete this.pendingFetches[activityKey];\n }\n }\n\n private async showRecentContacts(activityKey: string, flowUuid: string) {\n const overlayElement = this.findOverlayForActivityKey(activityKey);\n if (!overlayElement) return;\n\n if (this.hideContactsTimeout) {\n clearTimeout(this.hideContactsTimeout);\n this.hideContactsTimeout = null;\n }\n\n this.hoveredActivityKey = activityKey;\n\n if (!this.recentContactsPopup) {\n this.recentContactsPopup = document.createElement('div');\n this.recentContactsPopup.className = 'recent-contacts-popup';\n this.recentContactsPopup.style.position = 'absolute';\n this.recentContactsPopup.style.zIndex = '1015';\n this.recentContactsPopup.style.display = 'none';\n document.body.appendChild(this.recentContactsPopup);\n\n this.recentContactsPopup.onmouseenter = () => {\n if (this.hideContactsTimeout) {\n clearTimeout(this.hideContactsTimeout);\n this.hideContactsTimeout = null;\n }\n };\n this.recentContactsPopup.onmouseleave = () => {\n this.hoveredActivityKey = null;\n this.hideRecentContacts();\n };\n\n this.recentContactsPopup.onclick = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n if (target.classList.contains('contact-name')) {\n this.hideRecentContacts(false);\n const contactUuid = target.getAttribute('data-uuid');\n if (contactUuid) {\n this.editor.fireCustomEvent('temba-contact-clicked', {\n uuid: contactUuid,\n metaKey: e.metaKey,\n ctrlKey: e.ctrlKey\n });\n }\n }\n };\n }\n\n if (this.recentContactsCache[activityKey]) {\n this.renderRecentContactsPopup(this.recentContactsCache[activityKey]);\n this.positionPopup(overlayElement);\n } else {\n this.recentContactsPopup.innerHTML =\n '<div class=\"no-contacts-message\">Loading...</div>';\n this.positionPopup(overlayElement);\n await this.fetchRecentContacts(activityKey, flowUuid);\n if (this.hoveredActivityKey === activityKey) {\n this.renderRecentContactsPopup(\n this.recentContactsCache[activityKey] || []\n );\n this.positionPopup(overlayElement);\n }\n }\n }\n\n private findOverlayForActivityKey(activityKey: string): HTMLElement | null {\n for (const [, el] of this.overlays) {\n if (el.getAttribute('data-activity-key') === activityKey) {\n return el;\n }\n }\n return null;\n }\n\n private positionPopup(overlayElement: HTMLElement) {\n if (!this.recentContactsPopup) return;\n const rect = overlayElement.getBoundingClientRect();\n this.recentContactsPopup.style.left = `${rect.left + window.scrollX}px`;\n this.recentContactsPopup.style.top = `${\n rect.bottom + window.scrollY + 5\n }px`;\n this.recentContactsPopup.style.display = '';\n this.recentContactsPopup.classList.remove('show');\n void this.recentContactsPopup.offsetWidth;\n this.recentContactsPopup.classList.add('show');\n }\n\n private renderRecentContactsPopup(recentContacts: any[]) {\n if (!this.recentContactsPopup) return;\n\n if (recentContacts.length === 0) {\n this.recentContactsPopup.innerHTML =\n '<div class=\"no-contacts-message\">No Recent Contacts</div>';\n return;\n }\n\n let html = '<div class=\"popup-title\">Recent Contacts</div>';\n recentContacts.forEach((contact: any) => {\n html += '<div class=\"contact-row\">';\n html += `<div class=\"contact-name\" data-uuid=\"${contact.contact.uuid}\">${contact.contact.name}</div>`;\n if (contact.operand) {\n html += `<div class=\"contact-operand\">${contact.operand}</div>`;\n }\n if (contact.time) {\n const time = new Date(contact.time);\n const diffMs = Date.now() - time.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n let timeStr = '';\n if (diffMins < 1) timeStr = 'just now';\n else if (diffMins < 60) timeStr = `${diffMins}m ago`;\n else if (diffHours < 24) timeStr = `${diffHours}h ago`;\n else timeStr = `${diffDays}d ago`;\n html += `<div class=\"contact-time\">${timeStr}</div>`;\n }\n html += '</div>';\n });\n this.recentContactsPopup.innerHTML = html;\n }\n\n private hideRecentContacts(wait = true) {\n if (!wait) {\n if (this.recentContactsPopup) {\n this.recentContactsPopup.classList.remove('show');\n this.recentContactsPopup.style.display = 'none';\n this.hoveredActivityKey = null;\n }\n return;\n }\n\n this.hideContactsTimeout = window.setTimeout(() => {\n if (!this.hoveredActivityKey && this.recentContactsPopup) {\n this.recentContactsPopup.classList.remove('show');\n this.recentContactsPopup.style.display = 'none';\n this.hoveredActivityKey = null;\n }\n }, 200);\n }\n\n public clearRecentContactsCache() {\n this.recentContactsCache = {};\n Object.values(this.pendingFetches).forEach((controller) =>\n controller.abort()\n );\n this.pendingFetches = {};\n }\n\n // --- Drag-and-drop ---\n\n private startDrag(\n exitId: string,\n scope: string,\n originalTargetId: string | null,\n e: MouseEvent\n ) {\n // Remove existing connection SVG for this exit (the connection is being dragged away)\n this.removeConnectionSVG(exitId);\n\n const { svgEl, pathEl, arrowEl } = this.createSVGElement();\n svgEl.classList.add('dragging');\n // Ensure the drag SVG never intercepts mouse events (e.g. hover detection on nodes)\n pathEl.style.pointerEvents = 'none';\n arrowEl.style.pointerEvents = 'none';\n this.canvas.appendChild(svgEl);\n\n // Calculate source point\n const exitEl = document.getElementById(exitId);\n if (!exitEl) {\n svgEl.remove();\n return;\n }\n\n const canvasRect = this.canvas.getBoundingClientRect();\n const exitRect = exitEl.getBoundingClientRect();\n const sourceX = this.toCanvas(\n exitRect.left + exitRect.width / 2 - canvasRect.left\n );\n const sourceY = this.toCanvas(exitRect.bottom - canvasRect.top);\n\n const aw = ARROW_HALF_WIDTH;\n const al = ARROW_LENGTH;\n const stubBehindArrow = 8;\n\n // Update the drag path and arrow based on cursor position.\n // Arrow trails just before the cursor (between source and cursor).\n const cursorGap = CURSOR_GAP;\n const updateDragPath = (cx: number, cy: number) => {\n const goingUp = cy < sourceY;\n\n let routeFace: TargetFace = 'top';\n if (goingUp) {\n routeFace = cx < sourceX ? 'left' : 'right';\n }\n\n // Position the arrow so its top edge sits just before the cursor.\n // \"Top\" = smallest Y on screen, which is the base for a downward\n // arrow and the tip for an upward arrow.\n let arrowBaseY: number;\n if (goingUp) {\n // Arrow points up: tip just below cursor, base below that\n arrowBaseY = cy + cursorGap + al;\n } else {\n // Arrow points down: base just above cursor, tip below\n arrowBaseY = cy - cursorGap;\n }\n\n const d = calculateFlowchartPath(\n sourceX,\n sourceY,\n cx,\n arrowBaseY,\n EXIT_STUB,\n goingUp ? 0 : stubBehindArrow,\n 5,\n routeFace\n );\n pathEl.setAttribute('d', d);\n\n if (goingUp) {\n const tipY = cy + cursorGap;\n arrowEl.setAttribute(\n 'points',\n `${cx},${tipY} ${cx - aw},${arrowBaseY} ${cx + aw},${arrowBaseY}`\n );\n } else {\n const tipY = arrowBaseY + al;\n arrowEl.setAttribute(\n 'points',\n `${cx},${tipY} ${cx - aw},${arrowBaseY} ${cx + aw},${arrowBaseY}`\n );\n }\n };\n\n // Initial path to cursor (convert viewport to canvas coordinates)\n const cursorX = this.toCanvas(e.clientX - canvasRect.left);\n const cursorY = this.toCanvas(e.clientY - canvasRect.top);\n updateDragPath(cursorX, cursorY);\n\n this.connectionDragging = true;\n\n const onMove = (me: MouseEvent) => {\n // Re-read canvasRect each move since scroll may have changed\n const rect = this.canvas.getBoundingClientRect();\n const cx = this.toCanvas(me.clientX - rect.left);\n const cy = this.toCanvas(me.clientY - rect.top);\n updateDragPath(cx, cy);\n };\n\n const onUp = (_me: MouseEvent) => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n\n // Remove the drag SVG\n svgEl.remove();\n this.connectionDragging = false;\n this.dragState = null;\n\n // Fire abort event so Editor can handle connection logic\n this.notifyListeners('connection:abort', {\n source: exitEl,\n sourceId: exitId,\n target: { id: originalTargetId },\n data: { nodeId: scope }\n });\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n\n this.dragState = {\n sourceId: exitId,\n scope,\n originalTargetId,\n svgEl,\n pathEl,\n arrowEl,\n onMove,\n onUp\n };\n\n // Fire drag event so Editor knows a drag has started\n this.notifyListeners('connection:drag', {\n sourceId: exitId,\n sourceX,\n sourceY,\n data: { nodeId: scope },\n target: { id: originalTargetId }\n });\n }\n\n // --- Reset ---\n\n public reset() {\n if (this.connectionWait) {\n cancelAnimationFrame(this.connectionWait);\n this.connectionWait = null;\n }\n this.pendingConnections = [];\n\n // Remove all connection SVGs\n this.connections.forEach((conn) => conn.svgEl.remove());\n this.connections.clear();\n\n // Remove all activity overlays\n this.overlays.forEach((el) => el.remove());\n this.overlays.clear();\n\n // Clean up recent contacts popup\n this.hideRecentContacts(false);\n if (this.recentContactsPopup) {\n this.recentContactsPopup.remove();\n this.recentContactsPopup = null;\n }\n this.recentContactsCache = {};\n Object.values(this.pendingFetches).forEach((c) => c.abort());\n this.pendingFetches = {};\n\n // Remove all source listeners\n this.sources.forEach((cleanup) => cleanup());\n this.sources.clear();\n\n // Clean up any active drag\n if (this.dragState) {\n document.removeEventListener('mousemove', this.dragState.onMove);\n document.removeEventListener('mouseup', this.dragState.onUp);\n this.dragState.svgEl.remove();\n this.dragState = null;\n this.connectionDragging = false;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"Plumber.js","sourceRoot":"","sources":["../../../src/flow/Plumber.ts"],"names":[],"mappings":"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","sourcesContent":["import { isRightClick } from './utils';\n\nexport type TargetFace = 'top' | 'left' | 'right';\n\n/** Extract clientX/clientY from a MouseEvent or the first touch of a TouchEvent. */\nfunction getClientCoords(e: MouseEvent | TouchEvent): {\n clientX: number;\n clientY: number;\n} {\n if ('touches' in e) {\n const touch = e.touches[0] || (e as TouchEvent).changedTouches[0];\n return { clientX: touch.clientX, clientY: touch.clientY };\n }\n return {\n clientX: (e as MouseEvent).clientX,\n clientY: (e as MouseEvent).clientY\n };\n}\n\n// Shared arrow/drag constants used by both Plumber and Editor\nexport const ARROW_LENGTH = 13;\nexport const ARROW_HALF_WIDTH = 6.5;\nexport const CURSOR_GAP = 1;\nexport const EXIT_STUB = 30;\n\ninterface ConnectionEndpoints {\n sourceX: number;\n sourceY: number;\n targetX: number;\n targetY: number;\n targetFace: TargetFace;\n jogYOffset: number;\n}\n\ninterface ConnectionInfo {\n scope: string; // nodeId\n fromId: string; // exitId\n toId: string; // target nodeId\n svgEl: SVGSVGElement;\n pathEl: SVGPathElement;\n arrowEl: SVGPolygonElement;\n}\n\ninterface DragState {\n sourceId: string;\n scope: string;\n originalTargetId: string | null;\n svgEl: SVGSVGElement;\n pathEl: SVGPathElement;\n arrowEl: SVGPolygonElement;\n onMove: (e: MouseEvent | TouchEvent) => void;\n onUp: (e: MouseEvent | TouchEvent) => void;\n}\n\n/**\n * Calculate a flowchart-style SVG path between two points.\n * Routes with right-angle segments, stubs at each end, and rounded corners.\n * Supports entering the target from top, left, or right faces.\n */\nexport function calculateFlowchartPath(\n sourceX: number,\n sourceY: number,\n targetX: number,\n targetY: number,\n stubStart = 20,\n stubEnd = 10,\n cornerRadius = 5,\n targetFace: TargetFace = 'top',\n jogYOffset = 0\n): string {\n const r = cornerRadius;\n\n if (targetFace === 'top') {\n // Target is below (or we treat it as such): exit down, horizontal jog, enter from top\n const exitY = sourceY + stubStart;\n const entryY = targetY - stubEnd;\n\n let d = `M ${sourceX} ${sourceY}`;\n\n if (sourceX === targetX) {\n // Straight vertical — no turns needed\n d += ` L ${targetX} ${entryY}`;\n } else {\n // L-shape: exit curves horizontal, then straight down to target.\n // jogY is the horizontal level — must be above entryY so the\n // final approach into the node is always downward (no backtracking).\n const dirX = targetX > sourceX ? 1 : -1;\n const baseJogY = Math.max(sourceY + r, Math.min(exitY, entryY - r));\n const jogY = Math.max(\n sourceY + r,\n Math.min(baseJogY + jogYOffset, entryY - r - 3)\n );\n\n // Corner 1: vertical→horizontal at jogY\n const r1 = Math.min(r, jogY - sourceY);\n if (r1 >= 1) {\n d += ` L ${sourceX} ${jogY - r1}`;\n d += ` Q ${sourceX} ${jogY}, ${sourceX + dirX * r1} ${jogY}`;\n } else {\n d += ` L ${sourceX} ${jogY}`;\n }\n\n // Corner 2: horizontal→vertical at targetX — leave minSeg of\n // straight line after the curve before reaching entryY\n const minSeg = 3;\n const r2 = Math.min(r, Math.max(0, entryY - jogY - minSeg));\n if (r2 >= 1) {\n d += ` L ${targetX - dirX * r2} ${jogY}`;\n d += ` Q ${targetX} ${jogY}, ${targetX} ${jogY + r2}`;\n } else {\n d += ` L ${targetX} ${jogY}`;\n }\n d += ` L ${targetX} ${entryY}`;\n }\n\n d += ` L ${targetX} ${targetY}`;\n return d;\n }\n\n if (targetFace === 'left' || targetFace === 'right') {\n // Route: exit down from source, horizontal jog, vertical to target Y, stub into side\n // When target is above source, skip the exit stub so the path turns horizontal\n // as quickly as possible (only the corner radius creates downward travel)\n const goingUp = targetY < sourceY;\n const exitY = sourceY + (goingUp ? 0 : stubStart);\n const sideDir = targetFace === 'left' ? -1 : 1;\n // Entry point is OUTSIDE the node boundary (stub behind arrowhead)\n const entryX = targetX + sideDir * stubEnd;\n\n const dirX = entryX > sourceX ? 1 : -1;\n\n // Minimum straight segment after each curve\n const minSeg = 3;\n\n // When the horizontal approach would double-back over the stub\n // (dirX matches sideDir), keep midY at the natural exit level so\n // the path jogs horizontally ABOVE the target and descends into\n // the stub — never dipping past the target and curving back up.\n // For non-backtrack, midY goes to targetY for a direct entry.\n const midY =\n dirX === sideDir ? exitY + r * 2 : Math.max(exitY + r * 2, targetY);\n\n let d = `M ${sourceX} ${sourceY} L ${sourceX} ${exitY}`;\n\n // Corner 1: vertical→horizontal at (sourceX, midY)\n if (midY - exitY > r) {\n d += ` L ${sourceX} ${midY - r}`;\n d += ` Q ${sourceX} ${midY}, ${sourceX + dirX * r} ${midY}`;\n }\n\n const vertGap = Math.abs(midY - targetY);\n\n if (vertGap < 1) {\n // midY ≈ targetY — horizontal to entryX, then stub into face\n d += ` L ${entryX} ${targetY}`;\n d += ` L ${targetX} ${targetY}`;\n } else {\n // Corners 2 and 3 — turnR is limited so that at least minSeg of\n // straight line remains between the two corners and after corner 3\n const turnDir = targetY < midY ? -1 : 1;\n const turnR = Math.min(\n r,\n Math.max(0, Math.floor((vertGap - minSeg) / 2)),\n Math.max(0, stubEnd - minSeg)\n );\n\n if (turnR >= 1) {\n // Corner 2: horizontal→vertical at (entryX, midY)\n d += ` L ${entryX - dirX * turnR} ${midY}`;\n d += ` Q ${entryX} ${midY}, ${entryX} ${midY + turnDir * turnR}`;\n // Vertical toward targetY\n d += ` L ${entryX} ${targetY - turnDir * turnR}`;\n // Corner 3: vertical→horizontal into side face\n d += ` Q ${entryX} ${targetY}, ${entryX - sideDir * turnR} ${targetY}`;\n } else {\n d += ` L ${entryX} ${midY}`;\n d += ` L ${entryX} ${targetY}`;\n }\n // Horizontal stub into target face\n d += ` L ${targetX} ${targetY}`;\n }\n\n return d;\n }\n\n return `M ${sourceX} ${sourceY} L ${targetX} ${targetY}`;\n}\n\nexport class Plumber {\n private connections: Map<string, ConnectionInfo> = new Map();\n private sources: Map<string, () => void> = new Map(); // exitId → cleanup fn\n private canvas: HTMLElement;\n private pendingConnections: {\n scope: string;\n fromId: string;\n toId: string;\n }[] = [];\n private connectionWait: number | null = null;\n private connectionListeners: Map<string, ((info: any) => void)[]> = new Map();\n private dragState: DragState | null = null;\n private editor: any;\n private retryCount = 0;\n private maxRetries = 3;\n\n // Activity overlay state\n private activityData: { segments: { [key: string]: number } } | null = null;\n private overlays: Map<string, HTMLElement> = new Map();\n private hoveredActivityKey: string | null = null;\n private recentContactsPopup: HTMLElement | null = null;\n private recentContactsCache: { [key: string]: any[] } = {};\n private pendingFetches: { [key: string]: AbortController } = {};\n private hideContactsTimeout: number | null = null;\n private showContactsTimeout: number | null = null;\n\n public connectionDragging = false;\n public zoom = 1.0;\n\n constructor(canvas: HTMLElement, editor: any) {\n this.canvas = canvas;\n this.editor = editor;\n }\n\n // --- Event system ---\n\n private notifyListeners(eventName: string, info: any) {\n const listeners = this.connectionListeners.get(eventName) || [];\n listeners.forEach((listener) => listener(info));\n }\n\n public on(eventName: string, callback: (info: any) => void) {\n if (!this.connectionListeners.has(eventName)) {\n this.connectionListeners.set(eventName, []);\n }\n this.connectionListeners.get(eventName).push(callback);\n }\n\n public off(eventName: string, callback: (info: any) => void) {\n if (!this.connectionListeners.has(eventName)) return;\n const listeners = this.connectionListeners.get(eventName);\n const index = listeners.indexOf(callback);\n if (index !== -1) {\n listeners.splice(index, 1);\n }\n }\n\n // --- Source/Target registration ---\n\n public makeSource(exitId: string) {\n const element = document.getElementById(exitId);\n if (!element) return;\n\n // Clean up any existing listener for this exit\n if (this.sources.has(exitId)) {\n this.sources.get(exitId)();\n }\n\n let pendingDrag: {\n startX: number;\n startY: number;\n onMove: (e: MouseEvent | TouchEvent) => void;\n onUp: (e: MouseEvent | TouchEvent) => void;\n isTouch: boolean;\n } | null = null;\n\n const DRAG_THRESHOLD = 5;\n\n const beginPendingDrag = (e: MouseEvent | TouchEvent) => {\n if ('button' in e && isRightClick(e)) return;\n\n // Don't start drag from exit if it already has a connection —\n // existing connections are picked up from the arrowhead instead\n if (this.connections.has(exitId)) return;\n\n const isTouch = 'touches' in e;\n if (isTouch) e.preventDefault();\n\n const { clientX: startX, clientY: startY } = getClientCoords(e);\n\n const nodeEl = element.closest('temba-flow-node');\n const scope = nodeEl?.getAttribute('uuid') || '';\n const originalTargetId: string | null = null;\n\n const onMove = (me: MouseEvent | TouchEvent) => {\n const { clientX, clientY } = getClientCoords(me);\n const dx = clientX - startX;\n const dy = clientY - startY;\n if (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD) {\n // Exceeded threshold — start actual drag\n removePendingListeners();\n this.startDrag(exitId, scope, originalTargetId, me);\n }\n };\n\n const onUp = () => {\n // Released without dragging — let click handler fire\n removePendingListeners();\n };\n\n const removePendingListeners = () => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n document.removeEventListener('touchmove', onMove);\n document.removeEventListener('touchend', onUp);\n document.removeEventListener('touchcancel', onUp);\n pendingDrag = null;\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n document.addEventListener('touchmove', onMove, { passive: false });\n document.addEventListener('touchend', onUp);\n document.addEventListener('touchcancel', onUp);\n pendingDrag = { startX, startY, onMove, onUp, isTouch };\n };\n\n element.addEventListener('mousedown', beginPendingDrag);\n element.addEventListener('touchstart', beginPendingDrag, {\n passive: false\n });\n this.sources.set(exitId, () => {\n element.removeEventListener('mousedown', beginPendingDrag);\n element.removeEventListener('touchstart', beginPendingDrag);\n if (pendingDrag) {\n document.removeEventListener('mousemove', pendingDrag.onMove);\n document.removeEventListener('mouseup', pendingDrag.onUp);\n document.removeEventListener('touchmove', pendingDrag.onMove);\n document.removeEventListener('touchend', pendingDrag.onUp);\n document.removeEventListener('touchcancel', pendingDrag.onUp);\n pendingDrag = null;\n }\n });\n }\n\n public makeTarget(_nodeId: string) {\n // No-op: target detection happens via DOM hover during drag\n }\n\n // --- Connection creation ---\n\n public connectIds(scope: string, fromId: string, toId: string) {\n this.pendingConnections.push({ scope, fromId, toId });\n this.processPendingConnections();\n }\n\n public processPendingConnections() {\n if (this.connectionWait) {\n cancelAnimationFrame(this.connectionWait);\n this.connectionWait = null;\n }\n\n this.connectionWait = requestAnimationFrame(() => {\n const failed: { scope: string; fromId: string; toId: string }[] = [];\n const createdTargets = new Set<string>();\n\n this.pendingConnections.forEach((conn) => {\n const { scope, fromId, toId } = conn;\n // Remove existing connection from this exit if any\n this.removeConnectionSVG(fromId);\n if (!this.createConnectionSVG(fromId, scope, toId)) {\n failed.push(conn);\n } else {\n createdTargets.add(toId);\n }\n });\n this.pendingConnections = [];\n\n // Repaint all connections that share a target or source with newly\n // created ones so anchor distribution and jogY offsets are correct\n if (createdTargets.size > 0) {\n const createdScopes = new Set<string>();\n this.connections.forEach((conn) => {\n if (createdTargets.has(conn.toId)) {\n createdScopes.add(conn.scope);\n }\n });\n this.connections.forEach((conn, exitId) => {\n if (createdTargets.has(conn.toId) || createdScopes.has(conn.scope)) {\n this.updateConnectionSVG(exitId);\n }\n });\n }\n\n // Retry failed connections (elements may not be laid out yet)\n if (failed.length > 0 && this.retryCount < this.maxRetries) {\n this.retryCount++;\n this.pendingConnections = failed;\n this.processPendingConnections();\n } else {\n this.retryCount = 0;\n }\n });\n }\n\n // --- Anchor point distribution ---\n\n /** Convert a viewport-to-canvas rect difference to canvas coordinates */\n private toCanvas(viewportDiff: number): number {\n return viewportDiff / this.zoom;\n }\n\n private determineTargetFace(\n sourceX: number,\n sourceY: number,\n targetCenterX: number,\n targetTop: number\n ): TargetFace {\n const verticalGap = targetTop - sourceY;\n\n // Top face requires enough vertical room for the exit stub, entry stub,\n // arrow, and curved corners. Below this threshold the path components\n // overlap and the connection backtracks, so use a side face instead.\n if (verticalGap > 30) {\n return 'top';\n }\n\n // Source is level with, below, or too close to target — connect to a side face\n if (sourceX < targetCenterX) {\n return 'left';\n }\n return 'right';\n }\n\n private getConnectionEndpoints(\n fromId: string,\n toId: string,\n scope?: string\n ): ConnectionEndpoints | null {\n const fromEl = document.getElementById(fromId);\n const toEl = document.getElementById(toId);\n if (!fromEl || !toEl) return null;\n\n const canvasRect = this.canvas.getBoundingClientRect();\n const fromRect = fromEl.getBoundingClientRect();\n const toRect = toEl.getBoundingClientRect();\n\n if (fromRect.width === 0 || toRect.width === 0) return null;\n\n // All coordinates are converted to canvas space by dividing by zoom\n const sourceX = this.toCanvas(\n fromRect.left + fromRect.width / 2 - canvasRect.left\n );\n const sourceY = this.toCanvas(fromRect.bottom - canvasRect.top);\n\n // Pre-compute target canvas-space values for determineTargetFace\n const toCenterX = this.toCanvas(\n toRect.left + toRect.width / 2 - canvasRect.left\n );\n const toTopCanvas = this.toCanvas(toRect.top - canvasRect.top);\n\n const targetFace = this.determineTargetFace(\n sourceX,\n sourceY,\n toCenterX,\n toTopCanvas\n );\n\n // Find all connections targeting the same node, grouped by face\n // Track source position for spatial sorting\n const faceConnections: Map<\n TargetFace,\n { fromId: string; sortPos: number }[]\n > = new Map();\n this.connections.forEach((conn) => {\n if (conn.toId === toId) {\n const connFromEl = document.getElementById(conn.fromId);\n if (connFromEl) {\n const connFromRect = connFromEl.getBoundingClientRect();\n const connSourceX = this.toCanvas(\n connFromRect.left + connFromRect.width / 2 - canvasRect.left\n );\n const connSourceY = this.toCanvas(\n connFromRect.bottom - canvasRect.top\n );\n const face = this.determineTargetFace(\n connSourceX,\n connSourceY,\n toCenterX,\n toTopCanvas\n );\n if (!faceConnections.has(face)) {\n faceConnections.set(face, []);\n }\n // Sort position: X for top face, Y for side faces\n const sortPos = face === 'top' ? connSourceX : connSourceY;\n faceConnections.get(face).push({ fromId: conn.fromId, sortPos });\n }\n }\n });\n\n // Add current connection to its face group if not already tracked\n if (!faceConnections.has(targetFace)) {\n faceConnections.set(targetFace, []);\n }\n const faceGroup = faceConnections.get(targetFace);\n if (!faceGroup.find((e) => e.fromId === fromId)) {\n const sortPos = targetFace === 'top' ? sourceX : sourceY;\n faceGroup.push({ fromId, sortPos });\n }\n\n // Sort by spatial position so connections don't cross\n faceGroup.sort((a, b) => a.sortPos - b.sortPos);\n const index = faceGroup.findIndex((e) => e.fromId === fromId);\n const count = faceGroup.length;\n\n // Calculate anchor point on the chosen face (all in canvas space)\n const targetLeft = this.toCanvas(toRect.left - canvasRect.left);\n const targetTop = toTopCanvas;\n const targetW = this.toCanvas(toRect.width);\n const targetH = this.toCanvas(toRect.height);\n\n let targetX: number;\n let targetY: number;\n\n if (targetFace === 'top') {\n // Distribute across top face (middle 60% of width)\n const margin = targetW * 0.2;\n const span = targetW * 0.6;\n targetX =\n count === 1\n ? targetLeft + targetW / 2\n : targetLeft + margin + (span * (index + 0.5)) / count;\n targetY = targetTop;\n } else if (targetFace === 'left') {\n targetX = targetLeft;\n // Distribute along left face (middle 60% of height)\n const margin = targetH * 0.2;\n const span = targetH * 0.6;\n targetY =\n count === 1\n ? targetTop + targetH / 2\n : targetTop + margin + (span * (index + 0.5)) / count;\n } else {\n // right\n targetX = targetLeft + targetW;\n const margin = targetH * 0.2;\n const span = targetH * 0.6;\n targetY =\n count === 1\n ? targetTop + targetH / 2\n : targetTop + margin + (span * (index + 0.5)) / count;\n }\n\n // Compute jogYOffset: stagger horizontal segments for sibling exits\n // from the same source node so paths don't overlap\n let jogYOffset = 0;\n if (targetFace === 'top' && scope) {\n const SIBLING_SPACING = 8;\n const MAX_SPREAD = 50;\n\n const siblings: { fromId: string; targetX: number }[] = [];\n this.connections.forEach((conn) => {\n if (conn.scope === scope && conn.toId !== toId) {\n const connFromEl = document.getElementById(conn.fromId);\n const connToEl = document.getElementById(conn.toId);\n if (connFromEl && connToEl) {\n const connFromRect = connFromEl.getBoundingClientRect();\n const connToRect = connToEl.getBoundingClientRect();\n const connSourceX = this.toCanvas(\n connFromRect.left + connFromRect.width / 2 - canvasRect.left\n );\n const connSourceY = this.toCanvas(\n connFromRect.bottom - canvasRect.top\n );\n const connToCenterX = this.toCanvas(\n connToRect.left + connToRect.width / 2 - canvasRect.left\n );\n const connToTop = this.toCanvas(connToRect.top - canvasRect.top);\n const connFace = this.determineTargetFace(\n connSourceX,\n connSourceY,\n connToCenterX,\n connToTop\n );\n if (connFace === 'top') {\n const connTargetLeft = this.toCanvas(\n connToRect.left - canvasRect.left\n );\n const connTargetW = this.toCanvas(connToRect.width);\n siblings.push({\n fromId: conn.fromId,\n targetX: connTargetLeft + connTargetW / 2\n });\n }\n }\n }\n });\n\n if (siblings.length > 0) {\n siblings.push({ fromId, targetX });\n siblings.sort((a, b) => a.targetX - b.targetX);\n const idx = siblings.findIndex((s) => s.fromId === fromId);\n const sibCount = siblings.length;\n const rawSpread = (sibCount - 1) * SIBLING_SPACING;\n const spacing =\n rawSpread > MAX_SPREAD\n ? MAX_SPREAD / (sibCount - 1)\n : SIBLING_SPACING;\n jogYOffset = (idx - (sibCount - 1) / 2) * spacing;\n }\n }\n\n return { sourceX, sourceY, targetX, targetY, targetFace, jogYOffset };\n }\n\n // --- SVG creation and management ---\n\n private createSVGElement(): {\n svgEl: SVGSVGElement;\n pathEl: SVGPathElement;\n arrowEl: SVGPolygonElement;\n } {\n const svgEl = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svgEl.classList.add('plumb-connector');\n svgEl.style.position = 'absolute';\n svgEl.style.left = '0';\n svgEl.style.top = '0';\n svgEl.style.width = '100%';\n svgEl.style.height = '100%';\n svgEl.style.pointerEvents = 'none';\n svgEl.style.overflow = 'visible';\n\n const pathEl = document.createElementNS(\n 'http://www.w3.org/2000/svg',\n 'path'\n );\n pathEl.setAttribute('fill', 'none');\n pathEl.setAttribute('stroke', 'var(--color-connectors)');\n pathEl.setAttribute('stroke-width', '3');\n pathEl.style.pointerEvents = 'stroke';\n\n const arrowEl = document.createElementNS(\n 'http://www.w3.org/2000/svg',\n 'polygon'\n );\n arrowEl.setAttribute('fill', 'var(--color-connectors)');\n arrowEl.classList.add('plumb-arrow');\n arrowEl.style.pointerEvents = 'fill';\n arrowEl.style.cursor = 'pointer';\n\n svgEl.appendChild(pathEl);\n svgEl.appendChild(arrowEl);\n\n // Hover support\n const addHover = () => svgEl.classList.add('hover');\n const removeHover = () => svgEl.classList.remove('hover');\n pathEl.addEventListener('mouseenter', addHover);\n pathEl.addEventListener('mouseleave', removeHover);\n arrowEl.addEventListener('mouseenter', addHover);\n arrowEl.addEventListener('mouseleave', removeHover);\n\n return { svgEl, pathEl, arrowEl };\n }\n\n private updateSVGPath(\n pathEl: SVGPathElement,\n arrowEl: SVGPolygonElement,\n sourceX: number,\n sourceY: number,\n targetX: number,\n targetY: number,\n targetFace: TargetFace = 'top',\n jogYOffset = 0\n ) {\n const aw = ARROW_HALF_WIDTH;\n const al = ARROW_LENGTH;\n const stubBehindArrow = 8;\n\n // Path ends at arrow BASE (not tip) so the line never pokes through the front.\n // The arrow polygon covers from base to the node edge (tip).\n let pathTargetX = targetX;\n let pathTargetY = targetY;\n if (targetFace === 'top') {\n pathTargetY = targetY - al;\n } else if (targetFace === 'left') {\n pathTargetX = targetX - al;\n } else if (targetFace === 'right') {\n pathTargetX = targetX + al;\n }\n\n const effectiveStub = stubBehindArrow;\n const d = calculateFlowchartPath(\n sourceX,\n sourceY,\n pathTargetX,\n pathTargetY,\n EXIT_STUB,\n effectiveStub,\n 5,\n targetFace,\n jogYOffset\n );\n pathEl.setAttribute('d', d);\n\n // Arrow tip at node edge, base extends outward\n if (targetFace === 'top') {\n arrowEl.setAttribute(\n 'points',\n `${targetX},${targetY} ${targetX - aw},${targetY - al} ${\n targetX + aw\n },${targetY - al}`\n );\n } else if (targetFace === 'left') {\n arrowEl.setAttribute(\n 'points',\n `${targetX},${targetY} ${targetX - al},${targetY - aw} ${\n targetX - al\n },${targetY + aw}`\n );\n } else {\n arrowEl.setAttribute(\n 'points',\n `${targetX},${targetY} ${targetX + al},${targetY - aw} ${\n targetX + al\n },${targetY + aw}`\n );\n }\n }\n\n private createConnectionSVG(\n exitId: string,\n scope: string,\n toId: string\n ): boolean {\n const endpoints = this.getConnectionEndpoints(exitId, toId, scope);\n if (!endpoints) return false;\n\n const { svgEl, pathEl, arrowEl } = this.createSVGElement();\n this.updateSVGPath(\n pathEl,\n arrowEl,\n endpoints.sourceX,\n endpoints.sourceY,\n endpoints.targetX,\n endpoints.targetY,\n endpoints.targetFace,\n endpoints.jogYOffset\n );\n this.canvas.appendChild(svgEl);\n\n this.connections.set(exitId, {\n scope,\n fromId: exitId,\n toId,\n svgEl,\n pathEl,\n arrowEl\n });\n\n // Make arrowhead draggable for picking up existing connections\n const DRAG_THRESHOLD = 5;\n const onArrowDown = (e: MouseEvent | TouchEvent) => {\n if ('button' in e && isRightClick(e)) return;\n e.stopPropagation();\n if ('touches' in e) e.preventDefault();\n\n const { clientX: startX, clientY: startY } = getClientCoords(e);\n\n const onMove = (me: MouseEvent | TouchEvent) => {\n const { clientX, clientY } = getClientCoords(me);\n const dx = clientX - startX;\n const dy = clientY - startY;\n if (Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD) {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n document.removeEventListener('touchmove', onMove);\n document.removeEventListener('touchend', onUp);\n document.removeEventListener('touchcancel', onUp);\n this.startDrag(exitId, scope, toId, me);\n }\n };\n\n const onUp = () => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n document.removeEventListener('touchmove', onMove);\n document.removeEventListener('touchend', onUp);\n document.removeEventListener('touchcancel', onUp);\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n document.addEventListener('touchmove', onMove, { passive: false });\n document.addEventListener('touchend', onUp);\n document.addEventListener('touchcancel', onUp);\n };\n arrowEl.addEventListener('mousedown', onArrowDown);\n arrowEl.addEventListener('touchstart', onArrowDown, { passive: false });\n pathEl.addEventListener('mousedown', onArrowDown);\n pathEl.addEventListener('touchstart', onArrowDown, { passive: false });\n\n // Mark the exit element as connected\n const exitEl = document.getElementById(exitId);\n if (exitEl) {\n exitEl.classList.add('connected');\n }\n\n // Create activity overlay if activity data exists for this segment\n if (this.activityData) {\n const activityKey = `${exitId}:${toId}`;\n const count = this.activityData.segments[activityKey];\n if (count && count > 0) {\n const overlayEl = this.createOverlayElement(count, activityKey);\n this.canvas.appendChild(overlayEl);\n this.overlays.set(exitId, overlayEl);\n this.updateOverlayPosition(exitId);\n }\n }\n\n return true;\n }\n\n private updateConnectionSVG(exitId: string) {\n const conn = this.connections.get(exitId);\n if (!conn) return;\n\n const endpoints = this.getConnectionEndpoints(\n conn.fromId,\n conn.toId,\n conn.scope\n );\n if (!endpoints) return;\n\n this.updateSVGPath(\n conn.pathEl,\n conn.arrowEl,\n endpoints.sourceX,\n endpoints.sourceY,\n endpoints.targetX,\n endpoints.targetY,\n endpoints.targetFace,\n endpoints.jogYOffset\n );\n this.updateOverlayPosition(exitId);\n }\n\n private removeConnectionSVG(exitId: string) {\n const conn = this.connections.get(exitId);\n if (!conn) return;\n\n const overlay = this.overlays.get(exitId);\n if (overlay) {\n overlay.remove();\n this.overlays.delete(exitId);\n }\n\n conn.svgEl.remove();\n this.connections.delete(exitId);\n }\n\n // --- Repaint ---\n\n public repaintEverything() {\n this.connections.forEach((_conn, exitId) => {\n this.updateConnectionSVG(exitId);\n });\n }\n\n public revalidate(ids: string[]) {\n // Find all connections directly involving the given IDs\n const directExits: string[] = [];\n const affectedTargets = new Set<string>();\n\n this.connections.forEach((conn, exitId) => {\n if (\n ids.includes(conn.fromId) ||\n ids.includes(conn.toId) ||\n ids.includes(conn.scope)\n ) {\n directExits.push(exitId);\n affectedTargets.add(conn.toId);\n }\n });\n\n // Also repaint sibling connections that share a target\n // (so anchor distribution stays correct during drag)\n const allExitsToRepaint = new Set(directExits);\n this.connections.forEach((conn, exitId) => {\n if (affectedTargets.has(conn.toId)) {\n allExitsToRepaint.add(exitId);\n }\n });\n\n allExitsToRepaint.forEach((exitId) => {\n this.updateConnectionSVG(exitId);\n });\n }\n\n // --- Connection removal ---\n\n public forgetNode(nodeId: string) {\n // Remove all connections where this node is source or target\n const toRemove: string[] = [];\n this.connections.forEach((conn, exitId) => {\n if (conn.scope === nodeId || conn.toId === nodeId) {\n toRemove.push(exitId);\n }\n });\n toRemove.forEach((exitId) => this.removeConnectionSVG(exitId));\n\n // Remove source listeners for exits of this node\n const exitEls = document.getElementById(nodeId)?.querySelectorAll('.exit');\n if (exitEls) {\n exitEls.forEach((el) => {\n const id = el.id;\n if (this.sources.has(id)) {\n this.sources.get(id)();\n this.sources.delete(id);\n }\n });\n }\n }\n\n public removeNodeConnections(nodeId: string, exitIds?: string[]) {\n // Only remove outbound connections from this node's exits.\n // Inbound connections are managed by their source nodes and\n // will repaint correctly on the next revalidate.\n const exits =\n exitIds ||\n Array.from(\n document.getElementById(nodeId)?.querySelectorAll('.exit') || []\n ).map((el) => el.id);\n\n exits.forEach((exitId) => this.removeConnectionSVG(exitId));\n }\n\n public removeExitConnection(exitId: string): boolean {\n if (!this.connections.has(exitId)) return false;\n this.removeConnectionSVG(exitId);\n return true;\n }\n\n public removeAllEndpoints(nodeId: string) {\n // Remove source listeners for this node's exits\n const exitEls = document.getElementById(nodeId)?.querySelectorAll('.exit');\n if (exitEls) {\n exitEls.forEach((el) => {\n const id = el.id;\n if (this.sources.has(id)) {\n this.sources.get(id)();\n this.sources.delete(id);\n }\n });\n }\n }\n\n // --- Connection state ---\n\n public setConnectionRemovingState(\n exitId: string,\n isRemoving: boolean\n ): boolean {\n const conn = this.connections.get(exitId);\n if (!conn) return false;\n\n if (isRemoving) {\n conn.svgEl.classList.add('removing');\n } else {\n conn.svgEl.classList.remove('removing');\n }\n return true;\n }\n\n // --- Activity overlays ---\n\n public setActivityData(\n activityData: { segments: { [key: string]: number } } | null\n ) {\n this.activityData = activityData;\n this.clearRecentContactsCache();\n this.updateActivityOverlays();\n }\n\n private updateActivityOverlays() {\n if (!this.activityData) {\n this.overlays.forEach((el) => el.remove());\n this.overlays.clear();\n return;\n }\n\n const activeExitIds = new Set<string>();\n\n this.connections.forEach((conn, exitId) => {\n const activityKey = `${conn.fromId}:${conn.toId}`;\n const count = this.activityData.segments[activityKey];\n\n if (count && count > 0) {\n activeExitIds.add(exitId);\n let overlayEl = this.overlays.get(exitId);\n\n if (!overlayEl) {\n overlayEl = this.createOverlayElement(count, activityKey);\n this.canvas.appendChild(overlayEl);\n this.overlays.set(exitId, overlayEl);\n } else {\n overlayEl.textContent = count.toLocaleString();\n overlayEl.setAttribute('data-activity-key', activityKey);\n }\n\n this.updateOverlayPosition(exitId);\n }\n });\n\n // Remove overlays for connections that no longer have activity\n this.overlays.forEach((el, exitId) => {\n if (!activeExitIds.has(exitId)) {\n el.remove();\n this.overlays.delete(exitId);\n }\n });\n }\n\n private createOverlayElement(\n count: number,\n activityKey: string\n ): HTMLElement {\n const el = document.createElement('div');\n el.className = 'activity-overlay';\n el.textContent = count.toLocaleString();\n el.setAttribute('data-activity-key', activityKey);\n\n el.addEventListener('mouseenter', () => {\n const flowUuid = this.getFlowUuid();\n if (flowUuid) {\n this.fetchRecentContacts(activityKey, flowUuid);\n this.showContactsTimeout = window.setTimeout(() => {\n this.showRecentContacts(activityKey, flowUuid);\n }, 500);\n }\n });\n\n el.addEventListener('mouseleave', () => {\n if (this.showContactsTimeout) {\n clearTimeout(this.showContactsTimeout);\n this.showContactsTimeout = null;\n }\n this.hoveredActivityKey = null;\n this.hideRecentContacts();\n });\n\n return el;\n }\n\n private updateOverlayPosition(exitId: string) {\n const overlayEl = this.overlays.get(exitId);\n const conn = this.connections.get(exitId);\n if (!overlayEl || !conn) return;\n\n const endpoints = this.getConnectionEndpoints(\n conn.fromId,\n conn.toId,\n conn.scope\n );\n if (!endpoints) return;\n\n overlayEl.style.position = 'absolute';\n overlayEl.style.left = `${endpoints.sourceX}px`;\n overlayEl.style.top = `${endpoints.sourceY + EXIT_STUB / 2}px`;\n overlayEl.style.transform = 'translate(-50%, -50%)';\n }\n\n private getFlowUuid(): string | null {\n return this.editor?.definition?.uuid || null;\n }\n\n // --- Recent contacts ---\n\n private async fetchRecentContacts(activityKey: string, flowUuid: string) {\n if (\n this.recentContactsCache[activityKey] ||\n this.pendingFetches[activityKey]\n ) {\n return;\n }\n\n const controller = new AbortController();\n this.pendingFetches[activityKey] = controller;\n\n try {\n const [exitUuid, destinationUuid] = activityKey.split(':');\n const endpoint = `/flow/recent_contacts/${flowUuid}/${exitUuid}/${destinationUuid}/`;\n const response = await fetch(endpoint, { signal: controller.signal });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const data = await response.json();\n this.recentContactsCache[activityKey] = Array.isArray(data)\n ? data\n : data.results || [];\n } catch (error) {\n if ((error as Error).name !== 'AbortError') {\n console.error('Failed to fetch recent contacts:', error);\n }\n } finally {\n delete this.pendingFetches[activityKey];\n }\n }\n\n private async showRecentContacts(activityKey: string, flowUuid: string) {\n const overlayElement = this.findOverlayForActivityKey(activityKey);\n if (!overlayElement) return;\n\n if (this.hideContactsTimeout) {\n clearTimeout(this.hideContactsTimeout);\n this.hideContactsTimeout = null;\n }\n\n this.hoveredActivityKey = activityKey;\n\n if (!this.recentContactsPopup) {\n this.recentContactsPopup = document.createElement('div');\n this.recentContactsPopup.className = 'recent-contacts-popup';\n this.recentContactsPopup.style.position = 'absolute';\n this.recentContactsPopup.style.zIndex = '1015';\n this.recentContactsPopup.style.display = 'none';\n document.body.appendChild(this.recentContactsPopup);\n\n this.recentContactsPopup.onmouseenter = () => {\n if (this.hideContactsTimeout) {\n clearTimeout(this.hideContactsTimeout);\n this.hideContactsTimeout = null;\n }\n };\n this.recentContactsPopup.onmouseleave = () => {\n this.hoveredActivityKey = null;\n this.hideRecentContacts();\n };\n\n this.recentContactsPopup.onclick = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n if (target.classList.contains('contact-name')) {\n this.hideRecentContacts(false);\n const contactUuid = target.getAttribute('data-uuid');\n if (contactUuid) {\n this.editor.fireCustomEvent('temba-contact-clicked', {\n uuid: contactUuid,\n metaKey: e.metaKey,\n ctrlKey: e.ctrlKey\n });\n }\n }\n };\n }\n\n if (this.recentContactsCache[activityKey]) {\n this.renderRecentContactsPopup(this.recentContactsCache[activityKey]);\n this.positionPopup(overlayElement);\n } else {\n this.recentContactsPopup.innerHTML =\n '<div class=\"no-contacts-message\">Loading...</div>';\n this.positionPopup(overlayElement);\n await this.fetchRecentContacts(activityKey, flowUuid);\n if (this.hoveredActivityKey === activityKey) {\n this.renderRecentContactsPopup(\n this.recentContactsCache[activityKey] || []\n );\n this.positionPopup(overlayElement);\n }\n }\n }\n\n private findOverlayForActivityKey(activityKey: string): HTMLElement | null {\n for (const [, el] of this.overlays) {\n if (el.getAttribute('data-activity-key') === activityKey) {\n return el;\n }\n }\n return null;\n }\n\n private positionPopup(overlayElement: HTMLElement) {\n if (!this.recentContactsPopup) return;\n const rect = overlayElement.getBoundingClientRect();\n this.recentContactsPopup.style.left = `${rect.left + window.scrollX}px`;\n this.recentContactsPopup.style.top = `${\n rect.bottom + window.scrollY + 5\n }px`;\n this.recentContactsPopup.style.display = '';\n this.recentContactsPopup.classList.remove('show');\n void this.recentContactsPopup.offsetWidth;\n this.recentContactsPopup.classList.add('show');\n }\n\n private renderRecentContactsPopup(recentContacts: any[]) {\n if (!this.recentContactsPopup) return;\n\n if (recentContacts.length === 0) {\n this.recentContactsPopup.innerHTML =\n '<div class=\"no-contacts-message\">No Recent Contacts</div>';\n return;\n }\n\n let html = '<div class=\"popup-title\">Recent Contacts</div>';\n recentContacts.forEach((contact: any) => {\n html += '<div class=\"contact-row\">';\n html += `<div class=\"contact-name\" data-uuid=\"${contact.contact.uuid}\">${contact.contact.name}</div>`;\n if (contact.operand) {\n html += `<div class=\"contact-operand\">${contact.operand}</div>`;\n }\n if (contact.time) {\n const time = new Date(contact.time);\n const diffMs = Date.now() - time.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n let timeStr = '';\n if (diffMins < 1) timeStr = 'just now';\n else if (diffMins < 60) timeStr = `${diffMins}m ago`;\n else if (diffHours < 24) timeStr = `${diffHours}h ago`;\n else timeStr = `${diffDays}d ago`;\n html += `<div class=\"contact-time\">${timeStr}</div>`;\n }\n html += '</div>';\n });\n this.recentContactsPopup.innerHTML = html;\n }\n\n private hideRecentContacts(wait = true) {\n if (!wait) {\n if (this.recentContactsPopup) {\n this.recentContactsPopup.classList.remove('show');\n this.recentContactsPopup.style.display = 'none';\n this.hoveredActivityKey = null;\n }\n return;\n }\n\n this.hideContactsTimeout = window.setTimeout(() => {\n if (!this.hoveredActivityKey && this.recentContactsPopup) {\n this.recentContactsPopup.classList.remove('show');\n this.recentContactsPopup.style.display = 'none';\n this.hoveredActivityKey = null;\n }\n }, 200);\n }\n\n public clearRecentContactsCache() {\n this.recentContactsCache = {};\n Object.values(this.pendingFetches).forEach((controller) =>\n controller.abort()\n );\n this.pendingFetches = {};\n }\n\n // --- Drag-and-drop ---\n\n private startDrag(\n exitId: string,\n scope: string,\n originalTargetId: string | null,\n e: MouseEvent | TouchEvent\n ) {\n // Hide (don't remove) the existing connection SVG while dragging.\n // On iOS Safari, removing the element that received the original\n // touchstart can trigger touchcancel, prematurely ending the drag.\n // We defer removal until the drag ends.\n const oldConn = this.connections.get(exitId);\n if (oldConn) {\n oldConn.svgEl.style.display = 'none';\n const overlay = this.overlays.get(exitId);\n if (overlay) overlay.style.display = 'none';\n }\n\n const { svgEl, pathEl, arrowEl } = this.createSVGElement();\n svgEl.classList.add('dragging');\n // Ensure the drag SVG never intercepts mouse events (e.g. hover detection on nodes)\n pathEl.style.pointerEvents = 'none';\n arrowEl.style.pointerEvents = 'none';\n this.canvas.appendChild(svgEl);\n\n // Calculate source point\n const exitEl = document.getElementById(exitId);\n if (!exitEl) {\n svgEl.remove();\n return;\n }\n\n const canvasRect = this.canvas.getBoundingClientRect();\n const exitRect = exitEl.getBoundingClientRect();\n const sourceX = this.toCanvas(\n exitRect.left + exitRect.width / 2 - canvasRect.left\n );\n const sourceY = this.toCanvas(exitRect.bottom - canvasRect.top);\n\n const aw = ARROW_HALF_WIDTH;\n const al = ARROW_LENGTH;\n const stubBehindArrow = 8;\n\n // Update the drag path and arrow based on cursor position.\n // Arrow trails just before the cursor (between source and cursor).\n const cursorGap = CURSOR_GAP;\n const updateDragPath = (cx: number, cy: number) => {\n const goingUp = cy < sourceY;\n\n let routeFace: TargetFace = 'top';\n if (goingUp) {\n routeFace = cx < sourceX ? 'left' : 'right';\n }\n\n // Position the arrow so its top edge sits just before the cursor.\n // \"Top\" = smallest Y on screen, which is the base for a downward\n // arrow and the tip for an upward arrow.\n let arrowBaseY: number;\n if (goingUp) {\n // Arrow points up: tip just below cursor, base below that\n arrowBaseY = cy + cursorGap + al;\n } else {\n // Arrow points down: base just above cursor, tip below\n arrowBaseY = cy - cursorGap;\n }\n\n const d = calculateFlowchartPath(\n sourceX,\n sourceY,\n cx,\n arrowBaseY,\n EXIT_STUB,\n goingUp ? 0 : stubBehindArrow,\n 5,\n routeFace\n );\n pathEl.setAttribute('d', d);\n\n if (goingUp) {\n const tipY = cy + cursorGap;\n arrowEl.setAttribute(\n 'points',\n `${cx},${tipY} ${cx - aw},${arrowBaseY} ${cx + aw},${arrowBaseY}`\n );\n } else {\n const tipY = arrowBaseY + al;\n arrowEl.setAttribute(\n 'points',\n `${cx},${tipY} ${cx - aw},${arrowBaseY} ${cx + aw},${arrowBaseY}`\n );\n }\n };\n\n // Initial path to cursor (convert viewport to canvas coordinates)\n const { clientX: initX, clientY: initY } = getClientCoords(e);\n const cursorX = this.toCanvas(initX - canvasRect.left);\n const cursorY = this.toCanvas(initY - canvasRect.top);\n updateDragPath(cursorX, cursorY);\n\n this.connectionDragging = true;\n\n const onMove = (me: MouseEvent | TouchEvent) => {\n if ('touches' in me) me.preventDefault();\n // Re-read canvasRect each move since scroll may have changed\n const rect = this.canvas.getBoundingClientRect();\n const { clientX, clientY } = getClientCoords(me);\n const cx = this.toCanvas(clientX - rect.left);\n const cy = this.toCanvas(clientY - rect.top);\n updateDragPath(cx, cy);\n };\n\n const onUp = (_me: MouseEvent | TouchEvent) => {\n document.removeEventListener('mousemove', onMove);\n document.removeEventListener('mouseup', onUp);\n document.removeEventListener('touchmove', onMove);\n document.removeEventListener('touchend', onUp);\n document.removeEventListener('touchcancel', onUp);\n\n // Remove the drag SVG and the hidden old connection SVG\n svgEl.remove();\n this.removeConnectionSVG(exitId);\n this.connectionDragging = false;\n this.dragState = null;\n\n // Fire abort event so Editor can handle connection logic\n this.notifyListeners('connection:abort', {\n source: exitEl,\n sourceId: exitId,\n target: { id: originalTargetId },\n data: { nodeId: scope }\n });\n };\n\n document.addEventListener('mousemove', onMove);\n document.addEventListener('mouseup', onUp);\n document.addEventListener('touchmove', onMove, { passive: false });\n document.addEventListener('touchend', onUp);\n document.addEventListener('touchcancel', onUp);\n\n this.dragState = {\n sourceId: exitId,\n scope,\n originalTargetId,\n svgEl,\n pathEl,\n arrowEl,\n onMove,\n onUp\n };\n\n // Fire drag event so Editor knows a drag has started\n this.notifyListeners('connection:drag', {\n sourceId: exitId,\n sourceX,\n sourceY,\n data: { nodeId: scope },\n target: { id: originalTargetId }\n });\n }\n\n // --- Reset ---\n\n public reset() {\n if (this.connectionWait) {\n cancelAnimationFrame(this.connectionWait);\n this.connectionWait = null;\n }\n this.pendingConnections = [];\n\n // Remove all connection SVGs\n this.connections.forEach((conn) => conn.svgEl.remove());\n this.connections.clear();\n\n // Remove all activity overlays\n this.overlays.forEach((el) => el.remove());\n this.overlays.clear();\n\n // Clean up recent contacts popup\n this.hideRecentContacts(false);\n if (this.recentContactsPopup) {\n this.recentContactsPopup.remove();\n this.recentContactsPopup = null;\n }\n this.recentContactsCache = {};\n Object.values(this.pendingFetches).forEach((c) => c.abort());\n this.pendingFetches = {};\n\n // Remove all source listeners\n this.sources.forEach((cleanup) => cleanup());\n this.sources.clear();\n\n // Clean up any active drag\n if (this.dragState) {\n document.removeEventListener('mousemove', this.dragState.onMove);\n document.removeEventListener('mouseup', this.dragState.onUp);\n this.dragState.svgEl.remove();\n this.dragState = null;\n this.connectionDragging = false;\n }\n }\n}\n"]}
@@ -10,6 +10,10 @@ export class StickyNote extends RapidElement {
10
10
  this.dragging = false;
11
11
  this.selected = false;
12
12
  this.colorPickerExpanded = false;
13
+ // On touch devices, contenteditable starts false to prevent Apple Pencil
14
+ // Scribble from hijacking touches. It is set to true on explicit tap.
15
+ this.isTouchDevice = navigator.maxTouchPoints > 0;
16
+ this.editingField = null;
13
17
  }
14
18
  static get styles() {
15
19
  return css `
@@ -267,6 +271,7 @@ export class StickyNote extends RapidElement {
267
271
  }
268
272
  }
269
273
  handleTitleBlur(event) {
274
+ this.handleContentBlurForTouch(event);
270
275
  const target = event.target;
271
276
  const newTitle = target.textContent || '';
272
277
  if (this.data && newTitle !== this.data.title) {
@@ -280,6 +285,7 @@ export class StickyNote extends RapidElement {
280
285
  this.requestUpdate();
281
286
  }
282
287
  handleBodyBlur(event) {
288
+ this.handleContentBlurForTouch(event);
283
289
  const target = event.target;
284
290
  const newBody = target.innerText || '';
285
291
  if (this.data && newBody !== this.data.body) {
@@ -292,6 +298,41 @@ export class StickyNote extends RapidElement {
292
298
  }
293
299
  this.requestUpdate();
294
300
  }
301
+ /* c8 ignore start -- touch-only handlers untestable in headless Chromium */
302
+ handleDragHandleTouchStart(event) {
303
+ // Prevent Apple Pencil Scribble from activating on the adjacent
304
+ // contenteditable fields when touching/dragging the handle.
305
+ event.preventDefault();
306
+ }
307
+ /**
308
+ * On touch devices, contenteditable is off by default. A tap on the
309
+ * title or body enables it and focuses the element for editing.
310
+ */
311
+ handleContentTap(event) {
312
+ if (!this.isTouchDevice)
313
+ return;
314
+ const target = event.target;
315
+ if (!target.classList.contains('sticky-title') &&
316
+ !target.classList.contains('sticky-body'))
317
+ return;
318
+ // Enable editing and focus
319
+ target.setAttribute('contenteditable', 'true');
320
+ this.editingField = target;
321
+ target.focus();
322
+ event.stopPropagation();
323
+ }
324
+ /**
325
+ * When a contenteditable field loses focus on a touch device,
326
+ * disable contenteditable again to prevent Scribble.
327
+ */
328
+ handleContentBlurForTouch(event) {
329
+ const target = event.target;
330
+ if (this.isTouchDevice && this.editingField === target) {
331
+ target.setAttribute('contenteditable', 'false');
332
+ this.editingField = null;
333
+ }
334
+ }
335
+ /* c8 ignore stop */
295
336
  handleContentMouseDown(event) {
296
337
  // If this sticky note is selected, don't stop propagation
297
338
  // so that group dragging can work
@@ -325,8 +366,15 @@ export class StickyNote extends RapidElement {
325
366
  handleColorPickerMouseLeave() {
326
367
  this.colorPickerExpanded = false;
327
368
  }
369
+ /* c8 ignore next 5 -- touch-only */
370
+ handleColorPickerTap(event) {
371
+ event.stopPropagation();
372
+ event.preventDefault();
373
+ this.colorPickerExpanded = !this.colorPickerExpanded;
374
+ }
328
375
  handleColorOptionClick(event, color) {
329
376
  event.stopPropagation();
377
+ event.preventDefault();
330
378
  if (this.data && color !== this.data.color) {
331
379
  getStore()
332
380
  .getState()
@@ -352,23 +400,29 @@ export class StickyNote extends RapidElement {
352
400
  data-uuid="${this.uuid}"
353
401
  >
354
402
  <div class="sticky-title-container">
355
- <temba-icon name="drag" class="drag-handle"></temba-icon>
403
+ <temba-icon
404
+ name="drag"
405
+ class="drag-handle"
406
+ @touchstart=${this.handleDragHandleTouchStart}
407
+ ></temba-icon>
356
408
  <div
357
409
  class="sticky-title"
358
- contenteditable="${!this.isTranslating}"
410
+ contenteditable="${!this.isTranslating && !this.isTouchDevice}"
359
411
  @blur="${this.handleTitleBlur}"
360
412
  @keydown="${this.handleTitleKeyDown}"
361
413
  @mousedown="${this.handleContentMouseDown}"
414
+ @touchend="${this.handleContentTap}"
362
415
  .textContent="${this.data.title}"
363
416
  ></div>
364
417
  </div>
365
418
  <div class="sticky-body-container">
366
419
  <div
367
420
  class="sticky-body"
368
- contenteditable="${!this.isTranslating}"
421
+ contenteditable="${!this.isTranslating && !this.isTouchDevice}"
369
422
  @blur="${this.handleBodyBlur}"
370
423
  @keydown="${this.handleBodyKeyDown}"
371
424
  @mousedown="${this.handleContentMouseDown}"
425
+ @touchend="${this.handleContentTap}"
372
426
  .textContent="${this.data.body}"
373
427
  ></div>
374
428
  ${!this.isTranslating
@@ -380,6 +434,7 @@ export class StickyNote extends RapidElement {
380
434
  class="color-picker"
381
435
  @mouseenter="${this.handleColorPickerMouseEnter}"
382
436
  @mouseleave="${this.handleColorPickerMouseLeave}"
437
+ @touchend="${this.handleColorPickerTap}"
383
438
  >
384
439
  <div
385
440
  class="color-options ${this.colorPickerExpanded
@@ -389,22 +444,27 @@ export class StickyNote extends RapidElement {
389
444
  <div
390
445
  class="color-option yellow"
391
446
  @click="${(e) => this.handleColorOptionClick(e, 'yellow')}"
447
+ @touchend="${(e) => this.handleColorOptionClick(e, 'yellow')}"
392
448
  ></div>
393
449
  <div
394
450
  class="color-option blue"
395
451
  @click="${(e) => this.handleColorOptionClick(e, 'blue')}"
452
+ @touchend="${(e) => this.handleColorOptionClick(e, 'blue')}"
396
453
  ></div>
397
454
  <div
398
455
  class="color-option pink"
399
456
  @click="${(e) => this.handleColorOptionClick(e, 'pink')}"
457
+ @touchend="${(e) => this.handleColorOptionClick(e, 'pink')}"
400
458
  ></div>
401
459
  <div
402
460
  class="color-option green"
403
461
  @click="${(e) => this.handleColorOptionClick(e, 'green')}"
462
+ @touchend="${(e) => this.handleColorOptionClick(e, 'green')}"
404
463
  ></div>
405
464
  <div
406
465
  class="color-option gray"
407
466
  @click="${(e) => this.handleColorOptionClick(e, 'gray')}"
467
+ @touchend="${(e) => this.handleColorOptionClick(e, 'gray')}"
408
468
  ></div>
409
469
  </div>
410
470
  </div>