@nyaruka/temba-components 0.136.1 → 0.138.0

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 (73) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/demo/components/webchat/example.html +2 -2
  3. package/dist/temba-components.js +692 -622
  4. package/dist/temba-components.js.map +1 -1
  5. package/out-tsc/src/display/Chat.js +123 -44
  6. package/out-tsc/src/display/Chat.js.map +1 -1
  7. package/out-tsc/src/display/FloatingTab.js +2 -2
  8. package/out-tsc/src/display/FloatingTab.js.map +1 -1
  9. package/out-tsc/src/events/eventRenderers.js +442 -0
  10. package/out-tsc/src/events/eventRenderers.js.map +1 -0
  11. package/out-tsc/src/flow/CanvasNode.js +45 -24
  12. package/out-tsc/src/flow/CanvasNode.js.map +1 -1
  13. package/out-tsc/src/flow/Editor.js +308 -18
  14. package/out-tsc/src/flow/Editor.js.map +1 -1
  15. package/out-tsc/src/flow/NodeEditor.js +0 -1
  16. package/out-tsc/src/flow/NodeEditor.js.map +1 -1
  17. package/out-tsc/src/flow/Plumber.js +110 -64
  18. package/out-tsc/src/flow/Plumber.js.map +1 -1
  19. package/out-tsc/src/list/ShortcutList.js +1 -1
  20. package/out-tsc/src/list/ShortcutList.js.map +1 -1
  21. package/out-tsc/src/live/ContactChat.js +12 -321
  22. package/out-tsc/src/live/ContactChat.js.map +1 -1
  23. package/out-tsc/src/simulator/Simulator.js +439 -575
  24. package/out-tsc/src/simulator/Simulator.js.map +1 -1
  25. package/out-tsc/src/store/AppState.js +12 -2
  26. package/out-tsc/src/store/AppState.js.map +1 -1
  27. package/out-tsc/test/temba-flow-editor-node.test.js +2 -1
  28. package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
  29. package/out-tsc/test/temba-flow-editor-revisions.test.js +106 -0
  30. package/out-tsc/test/temba-flow-editor-revisions.test.js.map +1 -0
  31. package/out-tsc/test/temba-flow-editor.test.js +14 -10
  32. package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
  33. package/out-tsc/test/temba-flow-plumber-connections.test.js +7 -1
  34. package/out-tsc/test/temba-flow-plumber-connections.test.js.map +1 -1
  35. package/out-tsc/test/temba-flow-plumber.test.js +6 -0
  36. package/out-tsc/test/temba-flow-plumber.test.js.map +1 -1
  37. package/out-tsc/test/temba-simulator.test.js +51 -32
  38. package/out-tsc/test/temba-simulator.test.js.map +1 -1
  39. package/package.json +1 -1
  40. package/screenshots/truth/contacts/chat-failure.png +0 -0
  41. package/screenshots/truth/contacts/chat-for-archived-contact.png +0 -0
  42. package/screenshots/truth/contacts/chat-for-blocked-contact.png +0 -0
  43. package/screenshots/truth/contacts/chat-for-stopped-contact.png +0 -0
  44. package/screenshots/truth/contacts/chat-sends-attachments-only.png +0 -0
  45. package/screenshots/truth/contacts/chat-sends-text-and-attachments.png +0 -0
  46. package/screenshots/truth/contacts/chat-sends-text-only.png +0 -0
  47. package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
  48. package/screenshots/truth/simulator/after-message-sent.png +0 -0
  49. package/screenshots/truth/simulator/after-reset.png +0 -0
  50. package/screenshots/truth/simulator/attachment-menu.png +0 -0
  51. package/screenshots/truth/simulator/context-expanded.png +0 -0
  52. package/screenshots/truth/simulator/context-explorer-open.png +0 -0
  53. package/screenshots/truth/simulator/event-info.png +0 -0
  54. package/screenshots/truth/simulator/image-attachment.png +0 -0
  55. package/screenshots/truth/simulator/open-initial.png +0 -0
  56. package/screenshots/truth/simulator/quick-replies.png +0 -0
  57. package/src/display/Chat.ts +123 -44
  58. package/src/display/FloatingTab.ts +2 -2
  59. package/src/events/eventRenderers.ts +527 -0
  60. package/src/flow/CanvasNode.ts +54 -29
  61. package/src/flow/Editor.ts +360 -19
  62. package/src/flow/NodeEditor.ts +0 -1
  63. package/src/flow/Plumber.ts +123 -69
  64. package/src/list/ShortcutList.ts +1 -1
  65. package/src/live/ContactChat.ts +17 -376
  66. package/src/simulator/Simulator.ts +498 -617
  67. package/src/store/AppState.ts +13 -2
  68. package/test/temba-flow-editor-node.test.ts +2 -1
  69. package/test/temba-flow-editor-revisions.test.ts +134 -0
  70. package/test/temba-flow-editor.test.ts +16 -10
  71. package/test/temba-flow-plumber-connections.test.ts +7 -1
  72. package/test/temba-flow-plumber.test.ts +6 -0
  73. package/test/temba-simulator.test.ts +64 -34
@@ -57,6 +57,43 @@ export const TARGET_DEFAULTS = {
57
57
  target: true
58
58
  };
59
59
  export class Plumber {
60
+ initializeJSPlumb(canvas) {
61
+ this.jsPlumb = newInstance({
62
+ container: canvas,
63
+ connectionsDetachable: true,
64
+ endpointStyle: {
65
+ fill: 'green'
66
+ },
67
+ connector: CONNECTOR_DEFAULTS,
68
+ connectionOverlays: OVERLAYS_DEFAULTS
69
+ });
70
+ // Bind to connection events
71
+ this.jsPlumb.bind(EVENT_CONNECTION, (info) => {
72
+ this.connectionDragging = false;
73
+ this.notifyListeners(EVENT_CONNECTION, info);
74
+ });
75
+ // Bind to connection drag events
76
+ this.jsPlumb.bind(EVENT_CONNECTION_DRAG, (info) => {
77
+ this.connectionDragging = true;
78
+ this.notifyListeners(EVENT_CONNECTION_DRAG, info);
79
+ });
80
+ this.jsPlumb.bind(EVENT_CONNECTION_ABORT, (info) => {
81
+ this.connectionDragging = false;
82
+ this.notifyListeners(EVENT_CONNECTION_ABORT, info);
83
+ });
84
+ this.jsPlumb.bind(EVENT_CONNECTION_DETACHED, (info) => {
85
+ this.connectionDragging = false;
86
+ this.notifyListeners(EVENT_CONNECTION_DETACHED, info);
87
+ });
88
+ this.jsPlumb.bind(EVENT_REVERT, (info) => {
89
+ this.notifyListeners(EVENT_REVERT, info);
90
+ });
91
+ this.jsPlumb.bind(INTERCEPT_BEFORE_DROP, () => {
92
+ // we always deny automatic connections
93
+ return false;
94
+ });
95
+ this.jsPlumb.bind(INTERCEPT_BEFORE_DETACH, () => { });
96
+ }
60
97
  constructor(canvas, editor) {
61
98
  this.jsPlumb = null;
62
99
  this.pendingConnections = [];
@@ -72,41 +109,7 @@ export class Plumber {
72
109
  this.showContactsTimeout = null;
73
110
  this.editor = editor;
74
111
  ready(() => {
75
- this.jsPlumb = newInstance({
76
- container: canvas,
77
- connectionsDetachable: true,
78
- endpointStyle: {
79
- fill: 'green'
80
- },
81
- connector: CONNECTOR_DEFAULTS,
82
- connectionOverlays: OVERLAYS_DEFAULTS
83
- });
84
- // Bind to connection events
85
- this.jsPlumb.bind(EVENT_CONNECTION, (info) => {
86
- this.connectionDragging = false;
87
- this.notifyListeners(EVENT_CONNECTION, info);
88
- });
89
- // Bind to connection drag events
90
- this.jsPlumb.bind(EVENT_CONNECTION_DRAG, (info) => {
91
- this.connectionDragging = true;
92
- this.notifyListeners(EVENT_CONNECTION_DRAG, info);
93
- });
94
- this.jsPlumb.bind(EVENT_CONNECTION_ABORT, (info) => {
95
- this.connectionDragging = false;
96
- this.notifyListeners(EVENT_CONNECTION_ABORT, info);
97
- });
98
- this.jsPlumb.bind(EVENT_CONNECTION_DETACHED, (info) => {
99
- this.connectionDragging = false;
100
- this.notifyListeners(EVENT_CONNECTION_DETACHED, info);
101
- });
102
- this.jsPlumb.bind(EVENT_REVERT, (info) => {
103
- this.notifyListeners(EVENT_REVERT, info);
104
- });
105
- this.jsPlumb.bind(INTERCEPT_BEFORE_DROP, () => {
106
- // we always deny automatic connections
107
- return false;
108
- });
109
- this.jsPlumb.bind(INTERCEPT_BEFORE_DETACH, () => { });
112
+ this.initializeJSPlumb(canvas);
110
113
  });
111
114
  }
112
115
  notifyListeners(eventName, info) {
@@ -130,11 +133,15 @@ export class Plumber {
130
133
  }
131
134
  makeTarget(uuid) {
132
135
  const element = document.getElementById(uuid);
133
- this.jsPlumb.addEndpoint(element, TARGET_DEFAULTS);
136
+ if (!element)
137
+ return;
138
+ return this.jsPlumb.addEndpoint(element, TARGET_DEFAULTS);
134
139
  }
135
140
  makeSource(uuid) {
136
141
  const element = document.getElementById(uuid);
137
- this.jsPlumb.addEndpoint(element, SOURCE_DEFAULTS);
142
+ if (!element)
143
+ return;
144
+ return this.jsPlumb.addEndpoint(element, SOURCE_DEFAULTS);
138
145
  }
139
146
  // we'll process our pending connections, but we want to debounce this
140
147
  processPendingConnections() {
@@ -147,25 +154,30 @@ export class Plumber {
147
154
  this.connectionWait = setTimeout(() => {
148
155
  this.jsPlumb.batch(() => {
149
156
  this.pendingConnections.forEach((connection) => {
157
+ var _a;
150
158
  const { scope, fromId, toId } = connection;
151
- const fromElement = document.getElementById(fromId);
152
- const toElement = document.getElementById(toId);
153
- // delete any existing endpoints
154
- this.jsPlumb.selectEndpoints({ source: fromId }).deleteAll();
155
- const source = this.jsPlumb.addEndpoint(fromElement, {
156
- ...SOURCE_DEFAULTS,
157
- endpoint: {
158
- ...SOURCE_DEFAULTS.endpoint,
159
- options: {
160
- ...SOURCE_DEFAULTS.endpoint.options,
161
- cssClass: 'plumb-source connected'
162
- }
163
- }
164
- });
165
- const target = this.jsPlumb.addEndpoint(toElement, TARGET_DEFAULTS);
159
+ // sources and targets must exist
160
+ const source = document.getElementById(fromId);
161
+ // const target = document.getElementById(toId);
162
+ this.revalidate([fromId, toId]);
163
+ // we need to find the source endpoint
164
+ const sourceEndpoint = (_a = this.jsPlumb
165
+ .getEndpoints(source)) === null || _a === void 0 ? void 0 : _a.find((endpoint) => endpoint.elementId === fromId ? true : false);
166
+ // update endpoint have connect css class
167
+ if (sourceEndpoint) {
168
+ sourceEndpoint.addClass('connected');
169
+ }
170
+ // each connection needs its own target endpoint
171
+ const targetEndpoint = this.makeTarget(toId);
172
+ if (!sourceEndpoint || !targetEndpoint) {
173
+ console.warn(`Plumber: Cannot connect ${fromId} to ${toId}. Element(s) missing.`);
174
+ return;
175
+ }
176
+ // delete connections
177
+ this.jsPlumb.select({ source, targetEndpoint }).deleteAll();
166
178
  this.jsPlumb.connect({
167
- source,
168
- target,
179
+ source: source,
180
+ target: targetEndpoint,
169
181
  connector: {
170
182
  ...CONNECTOR_DEFAULTS,
171
183
  options: { ...CONNECTOR_DEFAULTS.options, gap: [0, 5] }
@@ -177,7 +189,14 @@ export class Plumber {
177
189
  });
178
190
  this.pendingConnections = [];
179
191
  });
180
- }, 50);
192
+ // Force a repaint to ensure connections are positioned correctly
193
+ // especially after bulk updates or view switching
194
+ window.requestAnimationFrame(() => {
195
+ if (this.jsPlumb) {
196
+ this.jsPlumb.repaintEverything();
197
+ }
198
+ });
199
+ }, 0);
181
200
  }
182
201
  connectIds(scope, fromId, toId) {
183
202
  this.pendingConnections.push({ scope, fromId, toId });
@@ -510,17 +529,39 @@ export class Plumber {
510
529
  });
511
530
  });
512
531
  }
513
- removeNodeConnections(nodeId) {
532
+ reset() {
533
+ if (this.connectionWait) {
534
+ clearTimeout(this.connectionWait);
535
+ this.connectionWait = null;
536
+ }
537
+ this.pendingConnections = [];
538
+ this.jsPlumb.select().deleteAll();
539
+ this.jsPlumb._managedElements = {};
540
+ }
541
+ forgetNode(nodeId) {
542
+ if (!this.jsPlumb)
543
+ return;
544
+ const element = document.getElementById(nodeId);
545
+ if (!element)
546
+ return;
547
+ this.jsPlumb.deleteConnectionsForElement(element);
548
+ this.jsPlumb.removeAllEndpoints(element);
549
+ this.jsPlumb.unmanage(element);
550
+ }
551
+ removeNodeConnections(nodeId, exitIds) {
514
552
  var _a;
515
553
  if (!this.jsPlumb)
516
554
  return;
517
555
  const inbound = this.jsPlumb.select({ target: nodeId });
518
- const exitIds = Array.from(((_a = document.getElementById(nodeId)) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.exit')) || []).map((exit) => {
519
- return exit.id;
520
- }) || [];
556
+ // Use provided exitIds or try to find them in DOM (fallback)
557
+ const exits = exitIds ||
558
+ Array.from(((_a = document.getElementById(nodeId)) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.exit')) || []).map((exit) => {
559
+ return exit.id;
560
+ }) ||
561
+ [];
521
562
  inbound.deleteAll();
522
- this.jsPlumb.select({ source: exitIds }).deleteAll();
523
- this.jsPlumb.selectEndpoints({ source: exitIds }).deleteAll();
563
+ this.jsPlumb.select({ source: exits }).deleteAll();
564
+ this.jsPlumb.selectEndpoints({ source: exits }).deleteAll();
524
565
  }
525
566
  removeExitConnection(exitId) {
526
567
  if (!this.jsPlumb)
@@ -534,11 +575,16 @@ export class Plumber {
534
575
  connections.forEach((connection) => {
535
576
  this.jsPlumb.deleteConnection(connection);
536
577
  });
537
- // Re-create the source endpoint (now without connection)
538
- this.jsPlumb.removeAllEndpoints(exitElement);
539
- this.makeSource(exitId);
540
578
  return connections.length > 0;
541
579
  }
580
+ removeAllEndpoints(nodeId) {
581
+ if (!this.jsPlumb)
582
+ return;
583
+ const element = document.getElementById(nodeId);
584
+ if (!element)
585
+ return;
586
+ this.jsPlumb.removeAllEndpoints(element, true);
587
+ }
542
588
  /**
543
589
  * Set the removing state for an exit's connection
544
590
  * @param exitId The ID of the exit whose connections should be marked as removing
@@ -1 +1 @@
1
- {"version":3,"file":"Plumber.js","sourceRoot":"","sources":["../../../src/flow/Plumber.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DotEndpoint,\n FlowchartConnector,\n newInstance,\n ready,\n RectangleEndpoint,\n EVENT_CONNECTION_DRAG,\n EVENT_CONNECTION_ABORT,\n INTERCEPT_BEFORE_DROP,\n EVENT_CONNECTION,\n EVENT_REVERT,\n INTERCEPT_BEFORE_DETACH,\n EVENT_CONNECTION_DETACHED\n} from '@jsplumb/browser-ui';\nimport { getStore } from '../store/Store';\n\nconst CONNECTOR_DEFAULTS = {\n type: FlowchartConnector.type,\n options: {\n stub: [20, 10],\n midpoint: 0.5,\n alwaysRespectStubs: true,\n cornerRadius: 5,\n cssClass: 'plumb-connector'\n }\n};\n\nconst OVERLAYS_DEFAULTS = [\n {\n type: 'PlainArrow',\n options: {\n width: 13,\n length: 13,\n location: 0.999,\n cssClass: 'plumb-arrow'\n }\n }\n];\n\nexport const SOURCE_DEFAULTS = {\n endpoint: {\n type: DotEndpoint.type,\n options: {\n radius: 12,\n cssClass: 'plumb-source',\n hoverClass: 'plumb-source-hover'\n }\n },\n anchors: ['Bottom', 'Continuous'],\n maxConnections: 1,\n source: true,\n dragAllowedWhenFull: false\n};\n\nexport const TARGET_DEFAULTS = {\n endpoint: {\n type: RectangleEndpoint.type,\n options: {\n width: 23,\n height: 23,\n cssClass: 'plumb-target',\n hoverClass: 'plumb-target-hover'\n }\n },\n anchor: {\n type: 'Continuous',\n options: {\n faces: ['top', 'left', 'right'],\n cssClass: 'continuos plumb-target-anchor'\n }\n },\n deleteOnEmpty: true,\n maxConnections: 1,\n target: true\n};\n\nexport class Plumber {\n private jsPlumb = null;\n private pendingConnections = [];\n private connectionListeners = new Map();\n public connectionDragging = false;\n private connectionWait = null;\n private activityData: { segments: { [key: string]: number } } | null = null;\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 private editor: any;\n\n constructor(canvas: HTMLElement, editor: any) {\n this.editor = editor;\n ready(() => {\n this.jsPlumb = newInstance({\n container: canvas,\n connectionsDetachable: true,\n endpointStyle: {\n fill: 'green'\n },\n connector: CONNECTOR_DEFAULTS,\n connectionOverlays: OVERLAYS_DEFAULTS\n });\n\n // Bind to connection events\n this.jsPlumb.bind(EVENT_CONNECTION, (info) => {\n this.connectionDragging = false;\n this.notifyListeners(EVENT_CONNECTION, info);\n });\n\n // Bind to connection drag events\n this.jsPlumb.bind(EVENT_CONNECTION_DRAG, (info) => {\n this.connectionDragging = true;\n this.notifyListeners(EVENT_CONNECTION_DRAG, info);\n });\n\n this.jsPlumb.bind(EVENT_CONNECTION_ABORT, (info) => {\n this.connectionDragging = false;\n this.notifyListeners(EVENT_CONNECTION_ABORT, info);\n });\n\n this.jsPlumb.bind(EVENT_CONNECTION_DETACHED, (info) => {\n this.connectionDragging = false;\n this.notifyListeners(EVENT_CONNECTION_DETACHED, info);\n });\n\n this.jsPlumb.bind(EVENT_REVERT, (info) => {\n this.notifyListeners(EVENT_REVERT, info);\n });\n\n this.jsPlumb.bind(INTERCEPT_BEFORE_DROP, () => {\n // we always deny automatic connections\n return false;\n });\n this.jsPlumb.bind(INTERCEPT_BEFORE_DETACH, () => {});\n });\n }\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 public makeTarget(uuid: string) {\n const element = document.getElementById(uuid);\n this.jsPlumb.addEndpoint(element, TARGET_DEFAULTS);\n }\n\n public makeSource(uuid: string) {\n const element = document.getElementById(uuid);\n this.jsPlumb.addEndpoint(element, SOURCE_DEFAULTS);\n }\n\n // we'll process our pending connections, but we want to debounce this\n public processPendingConnections() {\n // if we have a pending connection wait, clear it\n if (this.connectionWait) {\n clearTimeout(this.connectionWait);\n this.connectionWait = null;\n }\n\n // debounce the connection processing\n this.connectionWait = setTimeout(() => {\n this.jsPlumb.batch(() => {\n this.pendingConnections.forEach((connection) => {\n const { scope, fromId, toId } = connection;\n const fromElement = document.getElementById(fromId);\n const toElement = document.getElementById(toId);\n\n // delete any existing endpoints\n this.jsPlumb.selectEndpoints({ source: fromId }).deleteAll();\n\n const source = this.jsPlumb.addEndpoint(fromElement, {\n ...SOURCE_DEFAULTS,\n endpoint: {\n ...SOURCE_DEFAULTS.endpoint,\n options: {\n ...SOURCE_DEFAULTS.endpoint.options,\n cssClass: 'plumb-source connected'\n }\n }\n });\n\n const target = this.jsPlumb.addEndpoint(toElement, TARGET_DEFAULTS);\n this.jsPlumb.connect({\n source,\n target,\n connector: {\n ...CONNECTOR_DEFAULTS,\n options: { ...CONNECTOR_DEFAULTS.options, gap: [0, 5] }\n },\n data: {\n nodeId: scope\n }\n });\n });\n this.pendingConnections = [];\n });\n }, 50);\n }\n\n public connectIds(scope: string, fromId: string, toId: string) {\n this.pendingConnections.push({ scope, fromId, toId });\n this.processPendingConnections();\n }\n\n public setActivityData(\n activityData: { segments: { [key: string]: number } } | null\n ) {\n this.activityData = activityData;\n // Clear recent contacts cache when activity data changes\n this.clearRecentContactsCache();\n this.updateActivityOverlays();\n }\n\n private updateActivityOverlays() {\n if (!this.jsPlumb || !this.activityData) {\n return;\n }\n\n // Get all connections\n const connections = this.jsPlumb.getConnections();\n\n connections.forEach((connection: any) => {\n // Get the source exit element\n const sourceElement = connection.source;\n if (!sourceElement) {\n return;\n }\n\n // Get destination node\n const targetElement = connection.target;\n if (!targetElement) {\n return;\n }\n\n // Create activity key: exitUuid:destinationUuid\n const exitUuid = sourceElement.id;\n const destinationUuid = targetElement.id;\n const activityKey = `${exitUuid}:${destinationUuid}`;\n\n // Get activity count for this segment\n const count = this.activityData.segments[activityKey];\n\n // Remove existing activity overlays\n connection.removeOverlay('activity-label');\n\n // Add new overlay if there's activity\n if (count && count > 0) {\n const overlay = connection.addOverlay({\n type: 'Label',\n options: {\n label: count.toLocaleString(),\n id: 'activity-label',\n cssClass: 'activity-overlay',\n location: 20 // Fixed pixel distance from the start (exit point)\n }\n });\n\n // Add hover events for recent contacts popup\n // Use setTimeout to ensure the overlay is fully rendered\n setTimeout(() => {\n // Try multiple ways to get the overlay element\n let overlayElement =\n overlay.canvas || overlay.element || overlay.getElement?.();\n\n // If still not found, query the DOM directly\n if (!overlayElement) {\n const overlays = connection.getOverlays();\n if (Array.isArray(overlays)) {\n for (const ovl of overlays) {\n if (ovl.id === 'activity-label') {\n overlayElement =\n ovl.canvas || ovl.element || ovl.getElement?.();\n break;\n }\n }\n }\n }\n\n // Also try querying by CSS class\n if (!overlayElement && connection.canvas) {\n overlayElement =\n connection.canvas.querySelector('.activity-overlay');\n }\n\n if (overlayElement) {\n overlayElement.style.cursor = 'pointer';\n overlayElement.setAttribute('data-activity-key', activityKey);\n overlayElement.addEventListener('mouseenter', () => {\n // Don't show recent contacts when simulator is active\n const store = getStore();\n if (store?.getState().simulatorActive) {\n return;\n }\n\n // Get flow UUID from the editor element\n const editor = document.querySelector('temba-flow-editor') as any;\n const flowUuid = editor?.definition?.uuid;\n if (flowUuid) {\n // Start fetching immediately\n this.fetchRecentContacts(activityKey, flowUuid);\n\n // But delay showing the popup by half a second\n this.showContactsTimeout = window.setTimeout(() => {\n this.showRecentContacts(activityKey, flowUuid);\n }, 500);\n }\n });\n overlayElement.addEventListener('mouseleave', () => {\n // Cancel the show timeout if still pending\n if (this.showContactsTimeout) {\n clearTimeout(this.showContactsTimeout);\n this.showContactsTimeout = null;\n }\n this.hoveredActivityKey = null;\n this.hideRecentContacts();\n });\n }\n }, 50);\n }\n });\n\n // Force repaint to ensure overlays are positioned correctly\n this.repaintEverything();\n }\n\n private findOverlayElement(activityKey: string): HTMLElement | null {\n // Find overlay by data attribute\n const overlays = document.querySelectorAll('.activity-overlay');\n for (const overlay of overlays) {\n if (overlay.getAttribute('data-activity-key') === activityKey) {\n return overlay as HTMLElement;\n }\n }\n return null;\n }\n\n private async fetchRecentContacts(activityKey: string, flowUuid: string) {\n // Skip if already cached or currently fetching\n if (\n this.recentContactsCache[activityKey] ||\n this.pendingFetches[activityKey]\n ) {\n return;\n }\n\n // Cancel any pending fetch for this key\n if (this.pendingFetches[activityKey]) {\n this.pendingFetches[activityKey].abort();\n }\n\n // Fetch recent contacts from endpoint\n const controller = new AbortController();\n this.pendingFetches[activityKey] = controller;\n\n try {\n // Parse exit UUID and destination UUID from activity key\n const [exitUuid, destinationUuid] = activityKey.split(':');\n\n const endpoint = `/flow/recent_contacts/${flowUuid}/${exitUuid}/${destinationUuid}/`;\n\n const response = await fetch(endpoint, {\n signal: controller.signal\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const data = await response.json();\n // API returns array directly, not wrapped in results\n const recentContacts = Array.isArray(data) ? data : data.results || [];\n\n // Cache the results\n this.recentContactsCache[activityKey] = recentContacts;\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 // Don't show recent contacts when simulator is active\n const store = getStore();\n if (store?.getState().simulatorActive) {\n return;\n }\n\n // Find the overlay element fresh to avoid stale references\n const overlayElement = this.findOverlayElement(activityKey);\n if (!overlayElement) {\n console.warn('Could not find overlay element for activity:', activityKey);\n return;\n }\n // Clear any pending hide timeout\n if (this.hideContactsTimeout) {\n clearTimeout(this.hideContactsTimeout);\n this.hideContactsTimeout = null;\n }\n\n this.hoveredActivityKey = activityKey;\n\n // Create popup if it doesn't exist\n if (!this.recentContactsPopup) {\n this.recentContactsPopup = document.createElement('div');\n this.recentContactsPopup.className = 'recent-contacts-popup';\n // Add inline styles to ensure visibility\n this.recentContactsPopup.style.position = 'absolute';\n this.recentContactsPopup.style.width = '200px';\n this.recentContactsPopup.style.background = '#f3f3f3';\n this.recentContactsPopup.style.borderRadius = '10px';\n this.recentContactsPopup.style.boxShadow =\n '0 1px 3px 1px rgba(130, 130, 130, 0.2)';\n this.recentContactsPopup.style.zIndex = '1015';\n this.recentContactsPopup.style.display = 'none';\n document.body.appendChild(this.recentContactsPopup);\n }\n\n // Add hover events to keep popup open (only needs to be done once)\n if (!this.recentContactsPopup.onmouseenter) {\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 // Add click event listener for contact names\n this.recentContactsPopup.onclick = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n\n if (target.classList.contains('contact-name')) {\n this.hideRecentContacts(false);\n const contactUuid = target.getAttribute('data-uuid');\n if (contactUuid) {\n // Fire custom event through editor\n this.editor.fireCustomEvent('temba-contact-clicked', {\n uuid: contactUuid\n });\n }\n }\n };\n }\n\n // Check cache first\n if (this.recentContactsCache[activityKey]) {\n this.renderRecentContactsPopup(this.recentContactsCache[activityKey]);\n this.positionPopup(overlayElement);\n } else {\n // Show loading state if data isn't ready yet\n this.recentContactsPopup.innerHTML =\n '<div class=\"no-contacts-message\">Loading...</div>';\n this.positionPopup(overlayElement);\n\n // Wait for the fetch to complete\n await this.fetchRecentContacts(activityKey, flowUuid);\n\n // Render if still hovering over this activity\n if (this.hoveredActivityKey === activityKey) {\n const contacts = this.recentContactsCache[activityKey] || [];\n this.renderRecentContactsPopup(contacts);\n this.positionPopup(overlayElement);\n }\n }\n }\n\n private positionPopup(overlayElement: HTMLElement) {\n if (!this.recentContactsPopup) return;\n\n // Position popup near the overlay\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\n // Remove inline display style so CSS class can work\n this.recentContactsPopup.style.display = '';\n\n // Trigger animation by adding class\n this.recentContactsPopup.classList.remove('show');\n // Force reflow to restart animation\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 const hasContacts = recentContacts.length > 0;\n\n if (!hasContacts) {\n // Simple message when no contacts\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\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 now = new Date();\n const diffMs = now.getTime() - time.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\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\n html += `<div class=\"contact-time\">${timeStr}</div>`;\n }\n html += `</div>`;\n });\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 // Check if we're still hovering over an activity\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); // Small delay to allow moving between overlay and popup\n }\n\n public clearRecentContactsCache() {\n this.recentContactsCache = {};\n // Cancel any pending fetches\n Object.values(this.pendingFetches).forEach((controller) =>\n controller.abort()\n );\n this.pendingFetches = {};\n }\n\n public repaintEverything() {\n if (this.jsPlumb) {\n this.jsPlumb.repaintEverything();\n }\n }\n\n public revalidate(ids: string[]) {\n if (!this.jsPlumb) return;\n this.jsPlumb.batch(() => {\n ids.forEach((id) => {\n const element = document.getElementById(id);\n if (element) {\n this.jsPlumb.revalidate(element);\n }\n });\n });\n }\n\n public removeNodeConnections(nodeId: string) {\n if (!this.jsPlumb) return;\n\n const inbound = this.jsPlumb.select({ target: nodeId });\n const exitIds =\n Array.from(\n document.getElementById(nodeId)?.querySelectorAll('.exit') || []\n ).map((exit) => {\n return exit.id;\n }) || [];\n\n inbound.deleteAll();\n this.jsPlumb.select({ source: exitIds }).deleteAll();\n this.jsPlumb.selectEndpoints({ source: exitIds }).deleteAll();\n }\n\n public removeExitConnection(exitId: string) {\n if (!this.jsPlumb) return;\n\n const exitElement = document.getElementById(exitId);\n if (!exitElement) return;\n\n // Get all connections from this exit\n const connections = this.jsPlumb.getConnections({ source: exitElement });\n\n // Remove the connections\n connections.forEach((connection) => {\n this.jsPlumb.deleteConnection(connection);\n });\n\n // Re-create the source endpoint (now without connection)\n this.jsPlumb.removeAllEndpoints(exitElement);\n this.makeSource(exitId);\n\n return connections.length > 0;\n }\n\n /**\n * Set the removing state for an exit's connection\n * @param exitId The ID of the exit whose connections should be marked as removing\n * @returns true if connections were found and updated, false otherwise\n */\n public setConnectionRemovingState(\n exitId: string,\n isRemoving: boolean\n ): boolean {\n if (!this.jsPlumb) return false;\n\n const exitElement = document.getElementById(exitId);\n if (!exitElement) return false;\n\n // Get all connections from this exit\n const connections = this.jsPlumb.getConnections({ source: exitElement });\n\n if (connections.length === 0) return false;\n\n // Update the connections' CSS classes\n connections.forEach((connection) => {\n if (isRemoving) {\n connection.addClass('removing');\n } else {\n connection.removeClass('removing');\n }\n });\n\n return true;\n }\n}\n"]}
1
+ {"version":3,"file":"Plumber.js","sourceRoot":"","sources":["../../../src/flow/Plumber.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n DotEndpoint,\n FlowchartConnector,\n newInstance,\n ready,\n RectangleEndpoint,\n EVENT_CONNECTION_DRAG,\n EVENT_CONNECTION_ABORT,\n INTERCEPT_BEFORE_DROP,\n EVENT_CONNECTION,\n EVENT_REVERT,\n INTERCEPT_BEFORE_DETACH,\n EVENT_CONNECTION_DETACHED\n} from '@jsplumb/browser-ui';\nimport { getStore } from '../store/Store';\n\nconst CONNECTOR_DEFAULTS = {\n type: FlowchartConnector.type,\n options: {\n stub: [20, 10],\n midpoint: 0.5,\n alwaysRespectStubs: true,\n cornerRadius: 5,\n cssClass: 'plumb-connector'\n }\n};\n\nconst OVERLAYS_DEFAULTS = [\n {\n type: 'PlainArrow',\n options: {\n width: 13,\n length: 13,\n location: 0.999,\n cssClass: 'plumb-arrow'\n }\n }\n];\n\nexport const SOURCE_DEFAULTS = {\n endpoint: {\n type: DotEndpoint.type,\n options: {\n radius: 12,\n cssClass: 'plumb-source',\n hoverClass: 'plumb-source-hover'\n }\n },\n anchors: ['Bottom', 'Continuous'],\n maxConnections: 1,\n source: true,\n dragAllowedWhenFull: false\n};\n\nexport const TARGET_DEFAULTS = {\n endpoint: {\n type: RectangleEndpoint.type,\n options: {\n width: 23,\n height: 23,\n cssClass: 'plumb-target',\n hoverClass: 'plumb-target-hover'\n }\n },\n anchor: {\n type: 'Continuous',\n options: {\n faces: ['top', 'left', 'right'],\n cssClass: 'continuos plumb-target-anchor'\n }\n },\n deleteOnEmpty: true,\n maxConnections: 1,\n target: true\n};\n\nexport class Plumber {\n private jsPlumb = null;\n private pendingConnections = [];\n private connectionListeners = new Map();\n public connectionDragging = false;\n private connectionWait = null;\n private activityData: { segments: { [key: string]: number } } | null = null;\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 private editor: any;\n\n initializeJSPlumb(canvas: HTMLElement) {\n this.jsPlumb = newInstance({\n container: canvas,\n connectionsDetachable: true,\n endpointStyle: {\n fill: 'green'\n },\n connector: CONNECTOR_DEFAULTS,\n connectionOverlays: OVERLAYS_DEFAULTS\n });\n\n // Bind to connection events\n this.jsPlumb.bind(EVENT_CONNECTION, (info) => {\n this.connectionDragging = false;\n this.notifyListeners(EVENT_CONNECTION, info);\n });\n\n // Bind to connection drag events\n this.jsPlumb.bind(EVENT_CONNECTION_DRAG, (info) => {\n this.connectionDragging = true;\n this.notifyListeners(EVENT_CONNECTION_DRAG, info);\n });\n\n this.jsPlumb.bind(EVENT_CONNECTION_ABORT, (info) => {\n this.connectionDragging = false;\n this.notifyListeners(EVENT_CONNECTION_ABORT, info);\n });\n\n this.jsPlumb.bind(EVENT_CONNECTION_DETACHED, (info) => {\n this.connectionDragging = false;\n this.notifyListeners(EVENT_CONNECTION_DETACHED, info);\n });\n\n this.jsPlumb.bind(EVENT_REVERT, (info) => {\n this.notifyListeners(EVENT_REVERT, info);\n });\n\n this.jsPlumb.bind(INTERCEPT_BEFORE_DROP, () => {\n // we always deny automatic connections\n return false;\n });\n this.jsPlumb.bind(INTERCEPT_BEFORE_DETACH, () => {});\n }\n\n constructor(canvas: HTMLElement, editor: any) {\n this.editor = editor;\n ready(() => {\n this.initializeJSPlumb(canvas);\n });\n }\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 public makeTarget(uuid: string) {\n const element = document.getElementById(uuid);\n if (!element) return;\n return this.jsPlumb.addEndpoint(element, TARGET_DEFAULTS);\n }\n\n public makeSource(uuid: string) {\n const element = document.getElementById(uuid);\n if (!element) return;\n return this.jsPlumb.addEndpoint(element, SOURCE_DEFAULTS);\n }\n\n // we'll process our pending connections, but we want to debounce this\n public processPendingConnections() {\n // if we have a pending connection wait, clear it\n if (this.connectionWait) {\n clearTimeout(this.connectionWait);\n this.connectionWait = null;\n }\n\n // debounce the connection processing\n this.connectionWait = setTimeout(() => {\n this.jsPlumb.batch(() => {\n this.pendingConnections.forEach((connection) => {\n const { scope, fromId, toId } = connection;\n\n // sources and targets must exist\n const source = document.getElementById(fromId);\n // const target = document.getElementById(toId);\n\n this.revalidate([fromId, toId]);\n\n // we need to find the source endpoint\n const sourceEndpoint = this.jsPlumb\n .getEndpoints(source)\n ?.find((endpoint) =>\n endpoint.elementId === fromId ? true : false\n );\n\n // update endpoint have connect css class\n if (sourceEndpoint) {\n sourceEndpoint.addClass('connected');\n }\n\n // each connection needs its own target endpoint\n const targetEndpoint = this.makeTarget(toId);\n\n if (!sourceEndpoint || !targetEndpoint) {\n console.warn(\n `Plumber: Cannot connect ${fromId} to ${toId}. Element(s) missing.`\n );\n return;\n }\n\n // delete connections\n this.jsPlumb.select({ source, targetEndpoint }).deleteAll();\n this.jsPlumb.connect({\n source: source,\n target: targetEndpoint,\n connector: {\n ...CONNECTOR_DEFAULTS,\n options: { ...CONNECTOR_DEFAULTS.options, gap: [0, 5] }\n },\n data: {\n nodeId: scope\n }\n });\n });\n this.pendingConnections = [];\n });\n\n // Force a repaint to ensure connections are positioned correctly\n // especially after bulk updates or view switching\n window.requestAnimationFrame(() => {\n if (this.jsPlumb) {\n this.jsPlumb.repaintEverything();\n }\n });\n }, 0);\n }\n\n public connectIds(scope: string, fromId: string, toId: string) {\n this.pendingConnections.push({ scope, fromId, toId });\n this.processPendingConnections();\n }\n\n public setActivityData(\n activityData: { segments: { [key: string]: number } } | null\n ) {\n this.activityData = activityData;\n // Clear recent contacts cache when activity data changes\n this.clearRecentContactsCache();\n this.updateActivityOverlays();\n }\n\n private updateActivityOverlays() {\n if (!this.jsPlumb || !this.activityData) {\n return;\n }\n\n // Get all connections\n const connections = this.jsPlumb.getConnections();\n\n connections.forEach((connection: any) => {\n // Get the source exit element\n const sourceElement = connection.source;\n if (!sourceElement) {\n return;\n }\n\n // Get destination node\n const targetElement = connection.target;\n if (!targetElement) {\n return;\n }\n\n // Create activity key: exitUuid:destinationUuid\n const exitUuid = sourceElement.id;\n const destinationUuid = targetElement.id;\n const activityKey = `${exitUuid}:${destinationUuid}`;\n\n // Get activity count for this segment\n const count = this.activityData.segments[activityKey];\n\n // Remove existing activity overlays\n connection.removeOverlay('activity-label');\n\n // Add new overlay if there's activity\n if (count && count > 0) {\n const overlay = connection.addOverlay({\n type: 'Label',\n options: {\n label: count.toLocaleString(),\n id: 'activity-label',\n cssClass: 'activity-overlay',\n location: 20 // Fixed pixel distance from the start (exit point)\n }\n });\n\n // Add hover events for recent contacts popup\n // Use setTimeout to ensure the overlay is fully rendered\n setTimeout(() => {\n // Try multiple ways to get the overlay element\n let overlayElement =\n overlay.canvas || overlay.element || overlay.getElement?.();\n\n // If still not found, query the DOM directly\n if (!overlayElement) {\n const overlays = connection.getOverlays();\n if (Array.isArray(overlays)) {\n for (const ovl of overlays) {\n if (ovl.id === 'activity-label') {\n overlayElement =\n ovl.canvas || ovl.element || ovl.getElement?.();\n break;\n }\n }\n }\n }\n\n // Also try querying by CSS class\n if (!overlayElement && connection.canvas) {\n overlayElement =\n connection.canvas.querySelector('.activity-overlay');\n }\n\n if (overlayElement) {\n overlayElement.style.cursor = 'pointer';\n overlayElement.setAttribute('data-activity-key', activityKey);\n overlayElement.addEventListener('mouseenter', () => {\n // Don't show recent contacts when simulator is active\n const store = getStore();\n if (store?.getState().simulatorActive) {\n return;\n }\n\n // Get flow UUID from the editor element\n const editor = document.querySelector('temba-flow-editor') as any;\n const flowUuid = editor?.definition?.uuid;\n if (flowUuid) {\n // Start fetching immediately\n this.fetchRecentContacts(activityKey, flowUuid);\n\n // But delay showing the popup by half a second\n this.showContactsTimeout = window.setTimeout(() => {\n this.showRecentContacts(activityKey, flowUuid);\n }, 500);\n }\n });\n overlayElement.addEventListener('mouseleave', () => {\n // Cancel the show timeout if still pending\n if (this.showContactsTimeout) {\n clearTimeout(this.showContactsTimeout);\n this.showContactsTimeout = null;\n }\n this.hoveredActivityKey = null;\n this.hideRecentContacts();\n });\n }\n }, 50);\n }\n });\n\n // Force repaint to ensure overlays are positioned correctly\n this.repaintEverything();\n }\n\n private findOverlayElement(activityKey: string): HTMLElement | null {\n // Find overlay by data attribute\n const overlays = document.querySelectorAll('.activity-overlay');\n for (const overlay of overlays) {\n if (overlay.getAttribute('data-activity-key') === activityKey) {\n return overlay as HTMLElement;\n }\n }\n return null;\n }\n\n private async fetchRecentContacts(activityKey: string, flowUuid: string) {\n // Skip if already cached or currently fetching\n if (\n this.recentContactsCache[activityKey] ||\n this.pendingFetches[activityKey]\n ) {\n return;\n }\n\n // Cancel any pending fetch for this key\n if (this.pendingFetches[activityKey]) {\n this.pendingFetches[activityKey].abort();\n }\n\n // Fetch recent contacts from endpoint\n const controller = new AbortController();\n this.pendingFetches[activityKey] = controller;\n\n try {\n // Parse exit UUID and destination UUID from activity key\n const [exitUuid, destinationUuid] = activityKey.split(':');\n\n const endpoint = `/flow/recent_contacts/${flowUuid}/${exitUuid}/${destinationUuid}/`;\n\n const response = await fetch(endpoint, {\n signal: controller.signal\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const data = await response.json();\n // API returns array directly, not wrapped in results\n const recentContacts = Array.isArray(data) ? data : data.results || [];\n\n // Cache the results\n this.recentContactsCache[activityKey] = recentContacts;\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 // Don't show recent contacts when simulator is active\n const store = getStore();\n if (store?.getState().simulatorActive) {\n return;\n }\n\n // Find the overlay element fresh to avoid stale references\n const overlayElement = this.findOverlayElement(activityKey);\n if (!overlayElement) {\n console.warn('Could not find overlay element for activity:', activityKey);\n return;\n }\n // Clear any pending hide timeout\n if (this.hideContactsTimeout) {\n clearTimeout(this.hideContactsTimeout);\n this.hideContactsTimeout = null;\n }\n\n this.hoveredActivityKey = activityKey;\n\n // Create popup if it doesn't exist\n if (!this.recentContactsPopup) {\n this.recentContactsPopup = document.createElement('div');\n this.recentContactsPopup.className = 'recent-contacts-popup';\n // Add inline styles to ensure visibility\n this.recentContactsPopup.style.position = 'absolute';\n this.recentContactsPopup.style.width = '200px';\n this.recentContactsPopup.style.background = '#f3f3f3';\n this.recentContactsPopup.style.borderRadius = '10px';\n this.recentContactsPopup.style.boxShadow =\n '0 1px 3px 1px rgba(130, 130, 130, 0.2)';\n this.recentContactsPopup.style.zIndex = '1015';\n this.recentContactsPopup.style.display = 'none';\n document.body.appendChild(this.recentContactsPopup);\n }\n\n // Add hover events to keep popup open (only needs to be done once)\n if (!this.recentContactsPopup.onmouseenter) {\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 // Add click event listener for contact names\n this.recentContactsPopup.onclick = (e: MouseEvent) => {\n const target = e.target as HTMLElement;\n\n if (target.classList.contains('contact-name')) {\n this.hideRecentContacts(false);\n const contactUuid = target.getAttribute('data-uuid');\n if (contactUuid) {\n // Fire custom event through editor\n this.editor.fireCustomEvent('temba-contact-clicked', {\n uuid: contactUuid\n });\n }\n }\n };\n }\n\n // Check cache first\n if (this.recentContactsCache[activityKey]) {\n this.renderRecentContactsPopup(this.recentContactsCache[activityKey]);\n this.positionPopup(overlayElement);\n } else {\n // Show loading state if data isn't ready yet\n this.recentContactsPopup.innerHTML =\n '<div class=\"no-contacts-message\">Loading...</div>';\n this.positionPopup(overlayElement);\n\n // Wait for the fetch to complete\n await this.fetchRecentContacts(activityKey, flowUuid);\n\n // Render if still hovering over this activity\n if (this.hoveredActivityKey === activityKey) {\n const contacts = this.recentContactsCache[activityKey] || [];\n this.renderRecentContactsPopup(contacts);\n this.positionPopup(overlayElement);\n }\n }\n }\n\n private positionPopup(overlayElement: HTMLElement) {\n if (!this.recentContactsPopup) return;\n\n // Position popup near the overlay\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\n // Remove inline display style so CSS class can work\n this.recentContactsPopup.style.display = '';\n\n // Trigger animation by adding class\n this.recentContactsPopup.classList.remove('show');\n // Force reflow to restart animation\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 const hasContacts = recentContacts.length > 0;\n\n if (!hasContacts) {\n // Simple message when no contacts\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\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 now = new Date();\n const diffMs = now.getTime() - time.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\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\n html += `<div class=\"contact-time\">${timeStr}</div>`;\n }\n html += `</div>`;\n });\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 // Check if we're still hovering over an activity\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); // Small delay to allow moving between overlay and popup\n }\n\n public clearRecentContactsCache() {\n this.recentContactsCache = {};\n // Cancel any pending fetches\n Object.values(this.pendingFetches).forEach((controller) =>\n controller.abort()\n );\n this.pendingFetches = {};\n }\n\n public repaintEverything() {\n if (this.jsPlumb) {\n this.jsPlumb.repaintEverything();\n }\n }\n\n public revalidate(ids: string[]) {\n if (!this.jsPlumb) return;\n this.jsPlumb.batch(() => {\n ids.forEach((id) => {\n const element = document.getElementById(id);\n if (element) {\n this.jsPlumb.revalidate(element);\n }\n });\n });\n }\n\n public reset() {\n if (this.connectionWait) {\n clearTimeout(this.connectionWait);\n this.connectionWait = null;\n }\n this.pendingConnections = [];\n this.jsPlumb.select().deleteAll();\n this.jsPlumb._managedElements = {};\n }\n\n public forgetNode(nodeId: string) {\n if (!this.jsPlumb) return;\n const element = document.getElementById(nodeId);\n if (!element) return;\n\n this.jsPlumb.deleteConnectionsForElement(element);\n this.jsPlumb.removeAllEndpoints(element);\n this.jsPlumb.unmanage(element);\n }\n\n public removeNodeConnections(nodeId: string, exitIds?: string[]) {\n if (!this.jsPlumb) return;\n\n const inbound = this.jsPlumb.select({ target: nodeId });\n\n // Use provided exitIds or try to find them in DOM (fallback)\n const exits =\n exitIds ||\n Array.from(\n document.getElementById(nodeId)?.querySelectorAll('.exit') || []\n ).map((exit) => {\n return exit.id;\n }) ||\n [];\n\n inbound.deleteAll();\n this.jsPlumb.select({ source: exits }).deleteAll();\n this.jsPlumb.selectEndpoints({ source: exits }).deleteAll();\n }\n\n public removeExitConnection(exitId: string) {\n if (!this.jsPlumb) return;\n\n const exitElement = document.getElementById(exitId);\n if (!exitElement) return;\n\n // Get all connections from this exit\n const connections = this.jsPlumb.getConnections({ source: exitElement });\n\n // Remove the connections\n connections.forEach((connection) => {\n this.jsPlumb.deleteConnection(connection);\n });\n\n return connections.length > 0;\n }\n\n public removeAllEndpoints(nodeId: string) {\n if (!this.jsPlumb) return;\n const element = document.getElementById(nodeId);\n if (!element) return;\n this.jsPlumb.removeAllEndpoints(element, true);\n }\n\n /**\n * Set the removing state for an exit's connection\n * @param exitId The ID of the exit whose connections should be marked as removing\n * @returns true if connections were found and updated, false otherwise\n */\n public setConnectionRemovingState(\n exitId: string,\n isRemoving: boolean\n ): boolean {\n if (!this.jsPlumb) return false;\n\n const exitElement = document.getElementById(exitId);\n if (!exitElement) return false;\n\n // Get all connections from this exit\n const connections = this.jsPlumb.getConnections({ source: exitElement });\n\n if (connections.length === 0) return false;\n\n // Update the connections' CSS classes\n connections.forEach((connection) => {\n if (isRemoving) {\n connection.addClass('removing');\n } else {\n connection.removeClass('removing');\n }\n });\n\n return true;\n }\n}\n"]}
@@ -59,7 +59,7 @@ export class ShortcutList extends StoreMonitorElement {
59
59
  style="
60
60
  overflow: hidden;
61
61
  text-overflow: ellipsis;
62
- width:100px;
62
+ width:175px;
63
63
  padding-right: 10px;
64
64
  white-space: nowrap;"
65
65
  >
@@ -1 +1 @@
1
- {"version":3,"file":"ShortcutList.js","sourceRoot":"","sources":["../../../src/list/ShortcutList.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAoC,MAAM,KAAK,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGnE,MAAM,OAAO,YAAa,SAAQ,mBAAmB;IACnD,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;KAsBT,CAAC;IACJ,CAAC;IAWD;QACE,KAAK,EAAE,CAAC;QANV,sBAAiB,GAAG,EAAE,CAAC;QAGvB,gBAAW,GAAG,CAAC,CAAC;IAIhB,CAAC;IAES,YAAY,CACpB,OAA0D;QAE1D,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAEM,YAAY;QACjB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;IACrD,CAAC;IAEM,OAAO,CACZ,OAA0D;QAE1D,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAEvB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;YACrD,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,KAAK;qBAChC,YAAY,EAAE;qBACd,MAAM,CAAC,CAAC,QAAkB,EAAE,EAAE,CAC7B,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAChE,CAAC;YACN,CAAC;YACD,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAEM,cAAc,CAAC,QAAkB;QACtC,OAAO,IAAI,CAAA;;;;;;;;;UASL,QAAQ,CAAC,IAAI;;;;;;;;;;;;;;;;;UAiBb,QAAQ,CAAC,IAAI;;WAEZ,CAAC;IACV,CAAC;IAEM,WAAW;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,eAAe,CAAY,CAAC;QAC1E,OAAO,OAAO,CAAC,YAAY,EAAE,CAAC;IAChC,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAA;QACP,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YACnC,CAAC,CAAC,IAAI,CAAA;cACA,IAAI,CAAC,MAAM;gBACX,CAAC,CAAC,IAAI,CAAA,uCAAuC,IAAI,CAAC,MAAM,UAAU;gBAClE,CAAC,CAAC,IAAI,CAAA;+BACW;iBACd;YACT,CAAC,CAAC,IAAI;;;yBAGW,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YAClD,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,MAAM;;;;wBAIM,IAAI,CAAC,cAAc;uBACpB,IAAI,CAAC,WAAW;mBACpB,IAAI,CAAC,iBAAiB;;KAEpC,CAAC;IACJ,CAAC;CACF;AAtGC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4CACZ;AAGf;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;uDACH;AAGvB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;iDACX","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { Shortcut } from '../interfaces';\nimport { StoreMonitorElement } from '../store/StoreMonitorElement';\nimport { Options } from '../display/Options';\n\nexport class ShortcutList extends StoreMonitorElement {\n static get styles() {\n return css`\n temba-options {\n display: block;\n width: 100%;\n flex-grow: 1;\n }\n\n .options-empty {\n height: 0;\n overflow: hidden;\n }\n\n .no-match {\n margin: 5px 10px;\n padding: 10px;\n }\n\n .filter {\n background: #f3f3f3;\n padding: 0.1em 0.3em;\n border-radius: var(--curvature);\n }\n `;\n }\n\n @property({ type: String })\n filter: string;\n\n @property({ type: Array })\n filteredShortcuts = [];\n\n @property({ type: Number })\n cursorIndex = 0;\n\n constructor() {\n super();\n }\n\n protected firstUpdated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(changes);\n }\n\n public storeUpdated(): void {\n this.filteredShortcuts = this.store.getShortcuts();\n }\n\n public updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n\n if (changes.has('filter')) {\n if (!this.filter) {\n this.filteredShortcuts = this.store.getShortcuts();\n } else {\n this.filteredShortcuts = this.store\n .getShortcuts()\n .filter((shortcut: Shortcut) =>\n shortcut.name.toLowerCase().includes(this.filter.toLowerCase())\n );\n }\n this.cursorIndex = 0;\n }\n }\n\n public renderShortcut(shortcut: Shortcut): TemplateResult {\n return html`<div style=\"display:flex;align-items: center;min-width:0\">\n <div\n style=\"\n overflow: hidden;\n text-overflow: ellipsis;\n width:100px; \n padding-right: 10px;\n white-space: nowrap;\"\n >\n ${shortcut.name}\n </div>\n <div\n style=\" \n font-size: 0.9em;\n color: rgba(0, 0, 0, 0.4);\n flex:1;\n overflow: hidden;\n text-overflow: ellipsis;\n\n display: -webkit-box;\n line-height: 16px;\n max-height: 16px;\n -webkit-line-clamp: 1;\n -webkit-box-orient: vertical;\n \"\n >\n ${shortcut.text}\n </div>\n </div>`;\n }\n\n public getShortcut() {\n const options = this.shadowRoot.querySelector('temba-options') as Options;\n return options.getSelection();\n }\n\n public render(): TemplateResult {\n return html`\n ${this.filteredShortcuts.length === 0\n ? html`<div class=\"no-match\">\n ${this.filter\n ? html`No matches for <span class=\"filter\">${this.filter}</span>.`\n : html`No shortcuts yet, create some to quickly include them in\n your messages.`}\n </div>`\n : null}\n\n <temba-options\n class=\"options-${this.filteredShortcuts.length === 0\n ? 'empty'\n : 'full'}\"\n block\n cursorHover\n visible\n .renderOption=${this.renderShortcut}\n .cursorIndex=${this.cursorIndex}\n .options=${this.filteredShortcuts}\n ></temba-options>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"ShortcutList.js","sourceRoot":"","sources":["../../../src/list/ShortcutList.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAoC,MAAM,KAAK,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGnE,MAAM,OAAO,YAAa,SAAQ,mBAAmB;IACnD,MAAM,KAAK,MAAM;QACf,OAAO,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;KAsBT,CAAC;IACJ,CAAC;IAWD;QACE,KAAK,EAAE,CAAC;QANV,sBAAiB,GAAG,EAAE,CAAC;QAGvB,gBAAW,GAAG,CAAC,CAAC;IAIhB,CAAC;IAES,YAAY,CACpB,OAA0D;QAE1D,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAEM,YAAY;QACjB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;IACrD,CAAC;IAEM,OAAO,CACZ,OAA0D;QAE1D,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAEvB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;YACrD,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,KAAK;qBAChC,YAAY,EAAE;qBACd,MAAM,CAAC,CAAC,QAAkB,EAAE,EAAE,CAC7B,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAChE,CAAC;YACN,CAAC;YACD,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAEM,cAAc,CAAC,QAAkB;QACtC,OAAO,IAAI,CAAA;;;;;;;;;UASL,QAAQ,CAAC,IAAI;;;;;;;;;;;;;;;;;UAiBb,QAAQ,CAAC,IAAI;;WAEZ,CAAC;IACV,CAAC;IAEM,WAAW;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,eAAe,CAAY,CAAC;QAC1E,OAAO,OAAO,CAAC,YAAY,EAAE,CAAC;IAChC,CAAC;IAEM,MAAM;QACX,OAAO,IAAI,CAAA;QACP,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YACnC,CAAC,CAAC,IAAI,CAAA;cACA,IAAI,CAAC,MAAM;gBACX,CAAC,CAAC,IAAI,CAAA,uCAAuC,IAAI,CAAC,MAAM,UAAU;gBAClE,CAAC,CAAC,IAAI,CAAA;+BACW;iBACd;YACT,CAAC,CAAC,IAAI;;;yBAGW,IAAI,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC;YAClD,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,MAAM;;;;wBAIM,IAAI,CAAC,cAAc;uBACpB,IAAI,CAAC,WAAW;mBACpB,IAAI,CAAC,iBAAiB;;KAEpC,CAAC;IACJ,CAAC;CACF;AAtGC;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;4CACZ;AAGf;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;uDACH;AAGvB;IADC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;iDACX","sourcesContent":["import { css, html, PropertyValueMap, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { Shortcut } from '../interfaces';\nimport { StoreMonitorElement } from '../store/StoreMonitorElement';\nimport { Options } from '../display/Options';\n\nexport class ShortcutList extends StoreMonitorElement {\n static get styles() {\n return css`\n temba-options {\n display: block;\n width: 100%;\n flex-grow: 1;\n }\n\n .options-empty {\n height: 0;\n overflow: hidden;\n }\n\n .no-match {\n margin: 5px 10px;\n padding: 10px;\n }\n\n .filter {\n background: #f3f3f3;\n padding: 0.1em 0.3em;\n border-radius: var(--curvature);\n }\n `;\n }\n\n @property({ type: String })\n filter: string;\n\n @property({ type: Array })\n filteredShortcuts = [];\n\n @property({ type: Number })\n cursorIndex = 0;\n\n constructor() {\n super();\n }\n\n protected firstUpdated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(changes);\n }\n\n public storeUpdated(): void {\n this.filteredShortcuts = this.store.getShortcuts();\n }\n\n public updated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.updated(changes);\n\n if (changes.has('filter')) {\n if (!this.filter) {\n this.filteredShortcuts = this.store.getShortcuts();\n } else {\n this.filteredShortcuts = this.store\n .getShortcuts()\n .filter((shortcut: Shortcut) =>\n shortcut.name.toLowerCase().includes(this.filter.toLowerCase())\n );\n }\n this.cursorIndex = 0;\n }\n }\n\n public renderShortcut(shortcut: Shortcut): TemplateResult {\n return html`<div style=\"display:flex;align-items: center;min-width:0\">\n <div\n style=\"\n overflow: hidden;\n text-overflow: ellipsis;\n width:175px; \n padding-right: 10px;\n white-space: nowrap;\"\n >\n ${shortcut.name}\n </div>\n <div\n style=\" \n font-size: 0.9em;\n color: rgba(0, 0, 0, 0.4);\n flex:1;\n overflow: hidden;\n text-overflow: ellipsis;\n\n display: -webkit-box;\n line-height: 16px;\n max-height: 16px;\n -webkit-line-clamp: 1;\n -webkit-box-orient: vertical;\n \"\n >\n ${shortcut.text}\n </div>\n </div>`;\n }\n\n public getShortcut() {\n const options = this.shadowRoot.querySelector('temba-options') as Options;\n return options.getSelection();\n }\n\n public render(): TemplateResult {\n return html`\n ${this.filteredShortcuts.length === 0\n ? html`<div class=\"no-match\">\n ${this.filter\n ? html`No matches for <span class=\"filter\">${this.filter}</span>.`\n : html`No shortcuts yet, create some to quickly include them in\n your messages.`}\n </div>`\n : null}\n\n <temba-options\n class=\"options-${this.filteredShortcuts.length === 0\n ? 'empty'\n : 'full'}\"\n block\n cursorHover\n visible\n .renderOption=${this.renderShortcut}\n .cursorIndex=${this.cursorIndex}\n .options=${this.filteredShortcuts}\n ></temba-options>\n `;\n }\n}\n"]}