@nyaruka/temba-components 0.135.9 → 0.136.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.
- package/CHANGELOG.md +16 -0
- package/demo/components/webchat/example.html +4 -2
- package/dist/static/svg/index.svg +1 -1
- package/dist/temba-components.js +1323 -317
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/Icons.js +2 -1
- package/out-tsc/src/Icons.js.map +1 -1
- package/out-tsc/src/flow/CanvasNode.js +11 -0
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +224 -2
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/Plumber.js +320 -1
- package/out-tsc/src/flow/Plumber.js.map +1 -1
- package/out-tsc/src/interfaces.js +1 -0
- package/out-tsc/src/interfaces.js.map +1 -1
- package/out-tsc/src/layout/FloatingWindow.js +30 -8
- package/out-tsc/src/layout/FloatingWindow.js.map +1 -1
- package/out-tsc/src/simulator/Simulator.js +1827 -0
- package/out-tsc/src/simulator/Simulator.js.map +1 -0
- package/out-tsc/src/store/AppState.js +33 -0
- package/out-tsc/src/store/AppState.js.map +1 -1
- package/out-tsc/src/utils.js +48 -0
- package/out-tsc/src/utils.js.map +1 -1
- package/out-tsc/temba-modules.js +2 -0
- package/out-tsc/temba-modules.js.map +1 -1
- package/out-tsc/test/temba-flow-editor.test.js +1 -1
- package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
- package/out-tsc/test/temba-flow-plumber-connections.test.js +3 -1
- package/out-tsc/test/temba-flow-plumber-connections.test.js.map +1 -1
- package/out-tsc/test/temba-flow-plumber.test.js +3 -1
- package/out-tsc/test/temba-flow-plumber.test.js.map +1 -1
- package/out-tsc/test/temba-simulator.test.js +642 -0
- package/out-tsc/test/temba-simulator.test.js.map +1 -0
- package/out-tsc/test/utils.test.js +1 -1
- package/out-tsc/test/utils.test.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/simulator/after-message-sent.png +0 -0
- package/screenshots/truth/simulator/after-reset.png +0 -0
- package/screenshots/truth/simulator/attachment-menu.png +0 -0
- package/screenshots/truth/simulator/context-expanded.png +0 -0
- package/screenshots/truth/simulator/context-explorer-open.png +0 -0
- package/screenshots/truth/simulator/event-info.png +0 -0
- package/screenshots/truth/simulator/image-attachment.png +0 -0
- package/screenshots/truth/simulator/open-initial.png +0 -0
- package/screenshots/truth/simulator/quick-replies.png +0 -0
- package/src/Icons.ts +2 -1
- package/src/flow/CanvasNode.ts +12 -0
- package/src/flow/Editor.ts +240 -1
- package/src/flow/Plumber.ts +371 -2
- package/src/interfaces.ts +2 -1
- package/src/layout/FloatingWindow.ts +36 -11
- package/src/simulator/Simulator.ts +2008 -0
- package/src/store/AppState.ts +53 -0
- package/src/utils.ts +53 -0
- package/static/svg/index.svg +1 -1
- package/static/svg/work/traced/route.svg +1 -0
- package/static/svg/work/used/route.svg +3 -0
- package/temba-modules.ts +2 -0
- package/test/temba-flow-editor.test.ts +1 -1
- package/test/temba-flow-plumber-connections.test.ts +4 -1
- package/test/temba-flow-plumber.test.ts +4 -1
- package/test/temba-simulator.test.ts +866 -0
- package/test/utils.test.ts +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DotEndpoint, FlowchartConnector, newInstance, ready, RectangleEndpoint, EVENT_CONNECTION_DRAG, EVENT_CONNECTION_ABORT, INTERCEPT_BEFORE_DROP, EVENT_CONNECTION, EVENT_REVERT, INTERCEPT_BEFORE_DETACH, EVENT_CONNECTION_DETACHED } from '@jsplumb/browser-ui';
|
|
2
|
+
import { getStore } from '../store/Store';
|
|
2
3
|
const CONNECTOR_DEFAULTS = {
|
|
3
4
|
type: FlowchartConnector.type,
|
|
4
5
|
options: {
|
|
@@ -56,12 +57,20 @@ export const TARGET_DEFAULTS = {
|
|
|
56
57
|
target: true
|
|
57
58
|
};
|
|
58
59
|
export class Plumber {
|
|
59
|
-
constructor(canvas) {
|
|
60
|
+
constructor(canvas, editor) {
|
|
60
61
|
this.jsPlumb = null;
|
|
61
62
|
this.pendingConnections = [];
|
|
62
63
|
this.connectionListeners = new Map();
|
|
63
64
|
this.connectionDragging = false;
|
|
64
65
|
this.connectionWait = null;
|
|
66
|
+
this.activityData = null;
|
|
67
|
+
this.hoveredActivityKey = null;
|
|
68
|
+
this.recentContactsPopup = null;
|
|
69
|
+
this.recentContactsCache = {};
|
|
70
|
+
this.pendingFetches = {};
|
|
71
|
+
this.hideContactsTimeout = null;
|
|
72
|
+
this.showContactsTimeout = null;
|
|
73
|
+
this.editor = editor;
|
|
65
74
|
ready(() => {
|
|
66
75
|
this.jsPlumb = newInstance({
|
|
67
76
|
container: canvas,
|
|
@@ -174,6 +183,316 @@ export class Plumber {
|
|
|
174
183
|
this.pendingConnections.push({ scope, fromId, toId });
|
|
175
184
|
this.processPendingConnections();
|
|
176
185
|
}
|
|
186
|
+
setActivityData(activityData) {
|
|
187
|
+
this.activityData = activityData;
|
|
188
|
+
// Clear recent contacts cache when activity data changes
|
|
189
|
+
this.clearRecentContactsCache();
|
|
190
|
+
this.updateActivityOverlays();
|
|
191
|
+
}
|
|
192
|
+
updateActivityOverlays() {
|
|
193
|
+
if (!this.jsPlumb || !this.activityData) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
// Get all connections
|
|
197
|
+
const connections = this.jsPlumb.getConnections();
|
|
198
|
+
connections.forEach((connection) => {
|
|
199
|
+
// Get the source exit element
|
|
200
|
+
const sourceElement = connection.source;
|
|
201
|
+
if (!sourceElement) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
// Get destination node
|
|
205
|
+
const targetElement = connection.target;
|
|
206
|
+
if (!targetElement) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
// Create activity key: exitUuid:destinationUuid
|
|
210
|
+
const exitUuid = sourceElement.id;
|
|
211
|
+
const destinationUuid = targetElement.id;
|
|
212
|
+
const activityKey = `${exitUuid}:${destinationUuid}`;
|
|
213
|
+
// Get activity count for this segment
|
|
214
|
+
const count = this.activityData.segments[activityKey];
|
|
215
|
+
// Remove existing activity overlays
|
|
216
|
+
connection.removeOverlay('activity-label');
|
|
217
|
+
// Add new overlay if there's activity
|
|
218
|
+
if (count && count > 0) {
|
|
219
|
+
const overlay = connection.addOverlay({
|
|
220
|
+
type: 'Label',
|
|
221
|
+
options: {
|
|
222
|
+
label: count.toLocaleString(),
|
|
223
|
+
id: 'activity-label',
|
|
224
|
+
cssClass: 'activity-overlay',
|
|
225
|
+
location: 20 // Fixed pixel distance from the start (exit point)
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
// Add hover events for recent contacts popup
|
|
229
|
+
// Use setTimeout to ensure the overlay is fully rendered
|
|
230
|
+
setTimeout(() => {
|
|
231
|
+
var _a, _b;
|
|
232
|
+
// Try multiple ways to get the overlay element
|
|
233
|
+
let overlayElement = overlay.canvas || overlay.element || ((_a = overlay.getElement) === null || _a === void 0 ? void 0 : _a.call(overlay));
|
|
234
|
+
// If still not found, query the DOM directly
|
|
235
|
+
if (!overlayElement) {
|
|
236
|
+
const overlays = connection.getOverlays();
|
|
237
|
+
if (Array.isArray(overlays)) {
|
|
238
|
+
for (const ovl of overlays) {
|
|
239
|
+
if (ovl.id === 'activity-label') {
|
|
240
|
+
overlayElement =
|
|
241
|
+
ovl.canvas || ovl.element || ((_b = ovl.getElement) === null || _b === void 0 ? void 0 : _b.call(ovl));
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// Also try querying by CSS class
|
|
248
|
+
if (!overlayElement && connection.canvas) {
|
|
249
|
+
overlayElement =
|
|
250
|
+
connection.canvas.querySelector('.activity-overlay');
|
|
251
|
+
}
|
|
252
|
+
if (overlayElement) {
|
|
253
|
+
overlayElement.style.cursor = 'pointer';
|
|
254
|
+
overlayElement.setAttribute('data-activity-key', activityKey);
|
|
255
|
+
overlayElement.addEventListener('mouseenter', () => {
|
|
256
|
+
var _a;
|
|
257
|
+
// Don't show recent contacts when simulator is active
|
|
258
|
+
const store = getStore();
|
|
259
|
+
if (store === null || store === void 0 ? void 0 : store.getState().simulatorActive) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
// Get flow UUID from the editor element
|
|
263
|
+
const editor = document.querySelector('temba-flow-editor');
|
|
264
|
+
const flowUuid = (_a = editor === null || editor === void 0 ? void 0 : editor.definition) === null || _a === void 0 ? void 0 : _a.uuid;
|
|
265
|
+
if (flowUuid) {
|
|
266
|
+
// Start fetching immediately
|
|
267
|
+
this.fetchRecentContacts(activityKey, flowUuid);
|
|
268
|
+
// But delay showing the popup by half a second
|
|
269
|
+
this.showContactsTimeout = window.setTimeout(() => {
|
|
270
|
+
this.showRecentContacts(activityKey, flowUuid);
|
|
271
|
+
}, 500);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
overlayElement.addEventListener('mouseleave', () => {
|
|
275
|
+
// Cancel the show timeout if still pending
|
|
276
|
+
if (this.showContactsTimeout) {
|
|
277
|
+
clearTimeout(this.showContactsTimeout);
|
|
278
|
+
this.showContactsTimeout = null;
|
|
279
|
+
}
|
|
280
|
+
this.hoveredActivityKey = null;
|
|
281
|
+
this.hideRecentContacts();
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}, 50);
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
// Force repaint to ensure overlays are positioned correctly
|
|
288
|
+
this.repaintEverything();
|
|
289
|
+
}
|
|
290
|
+
findOverlayElement(activityKey) {
|
|
291
|
+
// Find overlay by data attribute
|
|
292
|
+
const overlays = document.querySelectorAll('.activity-overlay');
|
|
293
|
+
for (const overlay of overlays) {
|
|
294
|
+
if (overlay.getAttribute('data-activity-key') === activityKey) {
|
|
295
|
+
return overlay;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
async fetchRecentContacts(activityKey, flowUuid) {
|
|
301
|
+
// Skip if already cached or currently fetching
|
|
302
|
+
if (this.recentContactsCache[activityKey] ||
|
|
303
|
+
this.pendingFetches[activityKey]) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
// Cancel any pending fetch for this key
|
|
307
|
+
if (this.pendingFetches[activityKey]) {
|
|
308
|
+
this.pendingFetches[activityKey].abort();
|
|
309
|
+
}
|
|
310
|
+
// Fetch recent contacts from endpoint
|
|
311
|
+
const controller = new AbortController();
|
|
312
|
+
this.pendingFetches[activityKey] = controller;
|
|
313
|
+
try {
|
|
314
|
+
// Parse exit UUID and destination UUID from activity key
|
|
315
|
+
const [exitUuid, destinationUuid] = activityKey.split(':');
|
|
316
|
+
const endpoint = `/flow/recent_contacts/${flowUuid}/${exitUuid}/${destinationUuid}/`;
|
|
317
|
+
const response = await fetch(endpoint, {
|
|
318
|
+
signal: controller.signal
|
|
319
|
+
});
|
|
320
|
+
if (!response.ok) {
|
|
321
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
322
|
+
}
|
|
323
|
+
const data = await response.json();
|
|
324
|
+
// API returns array directly, not wrapped in results
|
|
325
|
+
const recentContacts = Array.isArray(data) ? data : data.results || [];
|
|
326
|
+
// Cache the results
|
|
327
|
+
this.recentContactsCache[activityKey] = recentContacts;
|
|
328
|
+
}
|
|
329
|
+
catch (error) {
|
|
330
|
+
if (error.name !== 'AbortError') {
|
|
331
|
+
console.error('Failed to fetch recent contacts:', error);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
finally {
|
|
335
|
+
delete this.pendingFetches[activityKey];
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
async showRecentContacts(activityKey, flowUuid) {
|
|
339
|
+
// Don't show recent contacts when simulator is active
|
|
340
|
+
const store = getStore();
|
|
341
|
+
if (store === null || store === void 0 ? void 0 : store.getState().simulatorActive) {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
// Find the overlay element fresh to avoid stale references
|
|
345
|
+
const overlayElement = this.findOverlayElement(activityKey);
|
|
346
|
+
if (!overlayElement) {
|
|
347
|
+
console.warn('Could not find overlay element for activity:', activityKey);
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
// Clear any pending hide timeout
|
|
351
|
+
if (this.hideContactsTimeout) {
|
|
352
|
+
clearTimeout(this.hideContactsTimeout);
|
|
353
|
+
this.hideContactsTimeout = null;
|
|
354
|
+
}
|
|
355
|
+
this.hoveredActivityKey = activityKey;
|
|
356
|
+
// Create popup if it doesn't exist
|
|
357
|
+
if (!this.recentContactsPopup) {
|
|
358
|
+
this.recentContactsPopup = document.createElement('div');
|
|
359
|
+
this.recentContactsPopup.className = 'recent-contacts-popup';
|
|
360
|
+
// Add inline styles to ensure visibility
|
|
361
|
+
this.recentContactsPopup.style.position = 'absolute';
|
|
362
|
+
this.recentContactsPopup.style.width = '200px';
|
|
363
|
+
this.recentContactsPopup.style.background = '#f3f3f3';
|
|
364
|
+
this.recentContactsPopup.style.borderRadius = '10px';
|
|
365
|
+
this.recentContactsPopup.style.boxShadow =
|
|
366
|
+
'0 1px 3px 1px rgba(130, 130, 130, 0.2)';
|
|
367
|
+
this.recentContactsPopup.style.zIndex = '1015';
|
|
368
|
+
this.recentContactsPopup.style.display = 'none';
|
|
369
|
+
document.body.appendChild(this.recentContactsPopup);
|
|
370
|
+
}
|
|
371
|
+
// Add hover events to keep popup open (only needs to be done once)
|
|
372
|
+
if (!this.recentContactsPopup.onmouseenter) {
|
|
373
|
+
this.recentContactsPopup.onmouseenter = () => {
|
|
374
|
+
if (this.hideContactsTimeout) {
|
|
375
|
+
clearTimeout(this.hideContactsTimeout);
|
|
376
|
+
this.hideContactsTimeout = null;
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
this.recentContactsPopup.onmouseleave = () => {
|
|
380
|
+
this.hoveredActivityKey = null;
|
|
381
|
+
this.hideRecentContacts();
|
|
382
|
+
};
|
|
383
|
+
// Add click event listener for contact names
|
|
384
|
+
this.recentContactsPopup.onclick = (e) => {
|
|
385
|
+
const target = e.target;
|
|
386
|
+
if (target.classList.contains('contact-name')) {
|
|
387
|
+
this.hideRecentContacts(false);
|
|
388
|
+
const contactUuid = target.getAttribute('data-uuid');
|
|
389
|
+
if (contactUuid) {
|
|
390
|
+
// Fire custom event through editor
|
|
391
|
+
this.editor.fireCustomEvent('temba-contact-clicked', {
|
|
392
|
+
uuid: contactUuid
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
// Check cache first
|
|
399
|
+
if (this.recentContactsCache[activityKey]) {
|
|
400
|
+
this.renderRecentContactsPopup(this.recentContactsCache[activityKey]);
|
|
401
|
+
this.positionPopup(overlayElement);
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
// Show loading state if data isn't ready yet
|
|
405
|
+
this.recentContactsPopup.innerHTML =
|
|
406
|
+
'<div class="no-contacts-message">Loading...</div>';
|
|
407
|
+
this.positionPopup(overlayElement);
|
|
408
|
+
// Wait for the fetch to complete
|
|
409
|
+
await this.fetchRecentContacts(activityKey, flowUuid);
|
|
410
|
+
// Render if still hovering over this activity
|
|
411
|
+
if (this.hoveredActivityKey === activityKey) {
|
|
412
|
+
const contacts = this.recentContactsCache[activityKey] || [];
|
|
413
|
+
this.renderRecentContactsPopup(contacts);
|
|
414
|
+
this.positionPopup(overlayElement);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
positionPopup(overlayElement) {
|
|
419
|
+
if (!this.recentContactsPopup)
|
|
420
|
+
return;
|
|
421
|
+
// Position popup near the overlay
|
|
422
|
+
const rect = overlayElement.getBoundingClientRect();
|
|
423
|
+
this.recentContactsPopup.style.left = `${rect.left + window.scrollX}px`;
|
|
424
|
+
this.recentContactsPopup.style.top = `${rect.bottom + window.scrollY + 5}px`;
|
|
425
|
+
// Remove inline display style so CSS class can work
|
|
426
|
+
this.recentContactsPopup.style.display = '';
|
|
427
|
+
// Trigger animation by adding class
|
|
428
|
+
this.recentContactsPopup.classList.remove('show');
|
|
429
|
+
// Force reflow to restart animation
|
|
430
|
+
void this.recentContactsPopup.offsetWidth;
|
|
431
|
+
this.recentContactsPopup.classList.add('show');
|
|
432
|
+
}
|
|
433
|
+
renderRecentContactsPopup(recentContacts) {
|
|
434
|
+
if (!this.recentContactsPopup)
|
|
435
|
+
return;
|
|
436
|
+
const hasContacts = recentContacts.length > 0;
|
|
437
|
+
if (!hasContacts) {
|
|
438
|
+
// Simple message when no contacts
|
|
439
|
+
this.recentContactsPopup.innerHTML =
|
|
440
|
+
'<div class="no-contacts-message">No Recent Contacts</div>';
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
let html = `<div class="popup-title">Recent Contacts</div>`;
|
|
444
|
+
recentContacts.forEach((contact) => {
|
|
445
|
+
html += `<div class="contact-row">`;
|
|
446
|
+
html += `<div class="contact-name" data-uuid="${contact.contact.uuid}">${contact.contact.name}</div>`;
|
|
447
|
+
if (contact.operand) {
|
|
448
|
+
html += `<div class="contact-operand">${contact.operand}</div>`;
|
|
449
|
+
}
|
|
450
|
+
if (contact.time) {
|
|
451
|
+
const time = new Date(contact.time);
|
|
452
|
+
const now = new Date();
|
|
453
|
+
const diffMs = now.getTime() - time.getTime();
|
|
454
|
+
const diffMins = Math.floor(diffMs / 60000);
|
|
455
|
+
const diffHours = Math.floor(diffMs / 3600000);
|
|
456
|
+
const diffDays = Math.floor(diffMs / 86400000);
|
|
457
|
+
let timeStr = '';
|
|
458
|
+
if (diffMins < 1)
|
|
459
|
+
timeStr = 'just now';
|
|
460
|
+
else if (diffMins < 60)
|
|
461
|
+
timeStr = `${diffMins}m ago`;
|
|
462
|
+
else if (diffHours < 24)
|
|
463
|
+
timeStr = `${diffHours}h ago`;
|
|
464
|
+
else
|
|
465
|
+
timeStr = `${diffDays}d ago`;
|
|
466
|
+
html += `<div class="contact-time">${timeStr}</div>`;
|
|
467
|
+
}
|
|
468
|
+
html += `</div>`;
|
|
469
|
+
});
|
|
470
|
+
this.recentContactsPopup.innerHTML = html;
|
|
471
|
+
}
|
|
472
|
+
hideRecentContacts(wait = true) {
|
|
473
|
+
if (!wait) {
|
|
474
|
+
if (this.recentContactsPopup) {
|
|
475
|
+
this.recentContactsPopup.classList.remove('show');
|
|
476
|
+
this.recentContactsPopup.style.display = 'none';
|
|
477
|
+
this.hoveredActivityKey = null;
|
|
478
|
+
}
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
this.hideContactsTimeout = window.setTimeout(() => {
|
|
482
|
+
// Check if we're still hovering over an activity
|
|
483
|
+
if (!this.hoveredActivityKey && this.recentContactsPopup) {
|
|
484
|
+
this.recentContactsPopup.classList.remove('show');
|
|
485
|
+
this.recentContactsPopup.style.display = 'none';
|
|
486
|
+
this.hoveredActivityKey = null;
|
|
487
|
+
}
|
|
488
|
+
}, 200); // Small delay to allow moving between overlay and popup
|
|
489
|
+
}
|
|
490
|
+
clearRecentContactsCache() {
|
|
491
|
+
this.recentContactsCache = {};
|
|
492
|
+
// Cancel any pending fetches
|
|
493
|
+
Object.values(this.pendingFetches).forEach((controller) => controller.abort());
|
|
494
|
+
this.pendingFetches = {};
|
|
495
|
+
}
|
|
177
496
|
repaintEverything() {
|
|
178
497
|
if (this.jsPlumb) {
|
|
179
498
|
this.jsPlumb.repaintEverything();
|
|
@@ -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';\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\n constructor(canvas: HTMLElement) {\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 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 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"]}
|
|
@@ -56,5 +56,6 @@ export var CustomEventType;
|
|
|
56
56
|
CustomEventType["NodeEditRequested"] = "temba-node-edit-requested";
|
|
57
57
|
CustomEventType["NodeSaved"] = "temba-node-saved";
|
|
58
58
|
CustomEventType["NodeEditCancelled"] = "temba-node-edit-cancelled";
|
|
59
|
+
CustomEventType["FollowSimulation"] = "temba-follow-simulation";
|
|
59
60
|
})(CustomEventType || (CustomEventType = {}));
|
|
60
61
|
//# sourceMappingURL=interfaces.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../src/interfaces.ts"],"names":[],"mappings":"AAwBA,MAAM,CAAN,IAAY,SAIX;AAJD,WAAY,SAAS;IACnB,mCAAsB,CAAA;IACtB,uCAA0B,CAAA;IAC1B,qCAAwB,CAAA;AAC1B,CAAC,EAJW,SAAS,KAAT,SAAS,QAIpB;AAED,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,sDAAgC,CAAA;IAChC,gEAA0C,CAAA;IAC1C,4DAAsC,CAAA;AACxC,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B;AAED,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACtB,6BAAa,CAAA;IACb,iCAAiB,CAAA;AACnB,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB;AAkOD,MAAM,CAAN,IAAY,
|
|
1
|
+
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../src/interfaces.ts"],"names":[],"mappings":"AAwBA,MAAM,CAAN,IAAY,SAIX;AAJD,WAAY,SAAS;IACnB,mCAAsB,CAAA;IACtB,uCAA0B,CAAA;IAC1B,qCAAwB,CAAA;AAC1B,CAAC,EAJW,SAAS,KAAT,SAAS,QAIpB;AAED,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,sDAAgC,CAAA;IAChC,gEAA0C,CAAA;IAC1C,4DAAsC,CAAA;AACxC,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B;AAED,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACtB,6BAAa,CAAA;IACb,iCAAiB,CAAA;AACnB,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB;AAkOD,MAAM,CAAN,IAAY,eAyCX;AAzCD,WAAY,eAAe;IACzB,0CAAuB,CAAA;IACvB,4CAAyB,CAAA;IACzB,8CAA2B,CAAA;IAC3B,yDAAsC,CAAA;IACtC,gDAA6B,CAAA;IAC7B,gDAA6B,CAAA;IAC7B,yDAAsC,CAAA;IACtC,uDAAoC,CAAA;IACpC,6DAA0C,CAAA;IAC1C,2DAAwC,CAAA;IACxC,2DAAwC,CAAA;IACxC,yDAAsC,CAAA;IACtC,qDAAkC,CAAA;IAClC,gDAA6B,CAAA;IAC7B,kDAA+B,CAAA;IAC/B,2CAAwB,CAAA;IACxB,uDAAoC,CAAA;IACpC,wCAAqB,CAAA;IACrB,uDAAoC,CAAA;IACpC,iDAA8B,CAAA;IAC9B,+CAA4B,CAAA;IAC5B,uDAAoC,CAAA;IACpC,uDAAoC,CAAA;IACpC,4CAAyB,CAAA;IACzB,2DAAwC,CAAA;IACxC,wCAAqB,CAAA;IACrB,gDAA6B,CAAA;IAC7B,0CAAuB,CAAA;IACvB,yDAAsC,CAAA;IACtC,wCAAqB,CAAA;IACrB,gEAA6C,CAAA;IAC7C,qDAAkC,CAAA;IAClC,sEAAmD,CAAA;IACnD,oEAAiD,CAAA;IACjD,qDAAkC,CAAA;IAClC,oEAAiD,CAAA;IACjD,kEAA+C,CAAA;IAC/C,iDAA8B,CAAA;IAC9B,kEAA+C,CAAA;IAC/C,+DAA4C,CAAA;AAC9C,CAAC,EAzCW,eAAe,KAAf,eAAe,QAyC1B","sourcesContent":["export interface Workspace {\n uuid: string;\n name: string;\n country: string;\n languages: string[];\n timezone: string;\n date_style: DateStyle;\n anon: boolean;\n}\n\nexport interface Language {\n iso: string;\n name: string;\n}\n\nexport interface Attachment {\n uuid: string;\n content_type: string;\n url: string;\n filename: string;\n size: number;\n error: string;\n}\n\nexport enum DateStyle {\n DayFirst = 'day_first',\n MonthFirst = 'month_first',\n YearFirst = 'year_first'\n}\n\nexport enum ScheduledEventType {\n CampaignEvent = 'campaign_event',\n ScheduledBroadcast = 'scheduled_broadcast',\n ScheduledTrigger = 'scheduled_trigger'\n}\n\nexport enum TicketStatus {\n Open = 'open',\n Closed = 'closed'\n}\n\nexport interface ScheduledEvent {\n type: ScheduledEventType;\n scheduled: string;\n repeat_period: string;\n campaign?: ObjectReference;\n flow?: ObjectReference;\n message?: string;\n}\n\nexport interface NamedUser extends User {\n name: string;\n}\n\nexport interface User {\n id?: number;\n first_name?: string;\n last_name?: string;\n name?: string;\n email?: string;\n role?: string;\n created_on?: string;\n avatar?: string;\n}\n\nexport interface Ticket {\n uuid: string;\n subject: string;\n body?: string;\n closed_on: string;\n opened_on: string;\n status: string;\n contact: ObjectReference;\n topic: ObjectReference;\n assignee?: { email: string; name: string; avatar?: string };\n}\n\nexport interface FlowResult {\n key: string;\n name: string;\n categories: string[];\n node_uuids: string[];\n}\n\nexport interface FlowDetails {\n name: string;\n results: FlowResult[];\n modified_on: string;\n runs: {\n active: number;\n completed: number;\n expired: number;\n interrupted: number;\n };\n}\n\nexport interface Msg {\n text: string;\n status: string;\n channel: ObjectReference;\n quick_replies: string[];\n urn: string;\n direction: string;\n type: string;\n attachments: string[];\n unsendable_reason?:\n | 'no_route'\n | 'contact_blocked'\n | 'contact_stopped'\n | 'contact_archived'\n | 'org_suspended'\n | 'looping';\n}\n\nexport interface ObjectReference {\n uuid: string;\n name: string;\n}\n\nexport interface Shortcut {\n uuid: string;\n name: string;\n text: string;\n modified_on: string;\n}\n\nexport interface ContactField {\n key: string;\n label: string;\n value_type: string;\n featured: boolean;\n priority: number;\n agent_access: string;\n type: string;\n usages: { campaign_events: number; flows: number; groups: number };\n}\n\nexport interface ContactGroup {\n uuid: string;\n count: number;\n name: string;\n query?: string;\n status: string;\n}\n\nexport interface URN {\n scheme: string;\n path: string;\n}\n\nexport interface Group {\n name: string;\n uuid: string;\n is_dynamic?: boolean;\n}\n\nexport interface ContactNote {\n text: string;\n created_on: string;\n created_by: NamedUser;\n}\n\nexport interface ContactTicket {\n name: string;\n uuid: string;\n status: string;\n\n contact: {\n uuid: string;\n name: string;\n created_on: Date;\n last_seen_on: Date;\n };\n}\n\nexport interface Contact {\n name: string;\n uuid: string;\n stopped: boolean;\n blocked: boolean;\n urns: string[];\n language?: string;\n fields: { [key: string]: string };\n groups: Group[];\n notes: ContactNote[];\n modified_on: string;\n created_on: string;\n last_seen_on: string;\n status: string;\n\n ref?: string; // only returned for anon workspaces\n flow?: ObjectReference;\n last_msg?: Msg;\n direction?: string;\n ticket: {\n uuid: string;\n subject: string;\n closed_on?: string;\n last_activity_on: string;\n assignee?: User;\n topic?: ObjectReference;\n };\n}\n\nexport interface FeatureProperties {\n name: string;\n osm_id: string;\n level: number;\n children?: FeatureProperties[];\n has_children?: boolean;\n aliases?: string;\n parent_osm_id?: string;\n id?: number;\n path?: string;\n}\n\nexport interface Position {\n top: number;\n left: number;\n}\n\nexport interface FunctionExample {\n template: string;\n output: string;\n}\n\nexport interface CompletionOption {\n name?: string;\n summary: string;\n\n // functions\n signature?: string;\n detail?: string;\n examples?: FunctionExample[];\n}\n\nexport interface CompletionResult {\n anchorPosition: Position;\n query: string;\n options: CompletionOption[];\n currentFunction: CompletionOption;\n}\n\nexport interface CompletionProperty {\n key: string;\n help: string;\n type: string;\n}\n\nexport interface CompletionType {\n name: string;\n\n key_source?: string;\n property_template?: CompletionProperty;\n properties?: CompletionProperty[];\n}\n\nexport interface CompletionSchema {\n types: CompletionType[];\n root: CompletionProperty[];\n root_no_session: CompletionProperty[];\n}\n\nexport type KeyedAssets = { [assetType: string]: string[] };\n\nexport enum CustomEventType {\n Loaded = 'temba-loaded',\n Loading = 'temba-loading',\n Canceled = 'temba-canceled',\n CursorChanged = 'temba-cursor-changed',\n Refreshed = 'temba-refreshed',\n Selection = 'temba-selection',\n ButtonClicked = 'temba-button-clicked',\n DialogHidden = 'temba-dialog-hidden',\n ScrollThreshold = 'temba-scroll-threshold',\n ContentChanged = 'temba-content-changed',\n ContextChanged = 'temba-context-changed',\n FetchComplete = 'temba-fetch-complete',\n MessageSent = 'temba-message-sent',\n Submitted = 'temba-submitted',\n Redirected = 'temba-redirected',\n NoPath = 'temba-no-path',\n StoreUpdated = 'temba-store-updated',\n Ready = 'temba-ready',\n OrderChanged = 'temba-order-changed',\n DragStart = 'temba-drag-start',\n DragStop = 'temba-drag-stop',\n DragExternal = 'temba-drag-external',\n DragInternal = 'temba-drag-internal',\n Resized = 'temba-resized',\n DetailsChanged = 'temba-details-changed',\n Error = 'temba-error',\n Interrupt = 'temba-interrupt',\n Opened = 'temba-opened',\n TicketUpdated = 'temba-ticket-updated',\n Moved = 'temba-moved',\n DateRangeChanged = 'temba-date-range-changed',\n NodeDeleted = 'temba-node-deleted',\n ActionEditRequested = 'temba-action-edit-requested',\n AddActionRequested = 'temba-add-action-requested',\n ActionSaved = 'temba-action-saved',\n ActionEditCanceled = 'temba-action-edit-canceled',\n NodeEditRequested = 'temba-node-edit-requested',\n NodeSaved = 'temba-node-saved',\n NodeEditCancelled = 'temba-node-edit-cancelled',\n FollowSimulation = 'temba-follow-simulation'\n}\n"]}
|
|
@@ -18,6 +18,10 @@ export class FloatingWindow extends RapidElement {
|
|
|
18
18
|
this.dragging = false;
|
|
19
19
|
this.chromeless = false;
|
|
20
20
|
this.color = '#6B7280';
|
|
21
|
+
this.leftBoundaryMargin = 0;
|
|
22
|
+
this.rightBoundaryMargin = 0;
|
|
23
|
+
this.topBoundaryMargin = 0;
|
|
24
|
+
this.bottomBoundaryMargin = 0;
|
|
21
25
|
this.dragStartX = 0;
|
|
22
26
|
this.dragStartY = 0;
|
|
23
27
|
this.dragOffsetX = 0;
|
|
@@ -51,12 +55,12 @@ export class FloatingWindow extends RapidElement {
|
|
|
51
55
|
this.top = this.dragOffsetY + deltaY;
|
|
52
56
|
// keep window within viewport bounds with 20px padding
|
|
53
57
|
const padding = 20;
|
|
54
|
-
this.left = Math.max(padding, Math.min(this.left, window.innerWidth - this.width - padding));
|
|
58
|
+
this.left = Math.max(padding - this.leftBoundaryMargin, Math.min(this.left, window.innerWidth - this.width - padding + this.rightBoundaryMargin));
|
|
55
59
|
// get the actual rendered height of the window element
|
|
56
60
|
const windowElement = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.window');
|
|
57
61
|
const currentHeight = (windowElement === null || windowElement === void 0 ? void 0 : windowElement.offsetHeight) || this.maxHeight || window.innerHeight;
|
|
58
|
-
const maxTop = Math.max(padding, window.innerHeight - currentHeight - padding);
|
|
59
|
-
this.top = Math.max(padding, Math.min(this.top, maxTop));
|
|
62
|
+
const maxTop = Math.max(padding - this.topBoundaryMargin, window.innerHeight - currentHeight - padding + this.bottomBoundaryMargin);
|
|
63
|
+
this.top = Math.max(padding - this.topBoundaryMargin, Math.min(this.top, maxTop));
|
|
60
64
|
};
|
|
61
65
|
this.handleMouseUp = () => {
|
|
62
66
|
this.dragging = false;
|
|
@@ -75,12 +79,13 @@ export class FloatingWindow extends RapidElement {
|
|
|
75
79
|
const currentHeight = (windowElement === null || windowElement === void 0 ? void 0 : windowElement.offsetHeight) || this.maxHeight || window.innerHeight;
|
|
76
80
|
// if positioned from right, always recalculate from right edge
|
|
77
81
|
if (this.positionFromRight) {
|
|
78
|
-
this.left =
|
|
82
|
+
this.left =
|
|
83
|
+
window.innerWidth - this.width - padding + this.rightBoundaryMargin;
|
|
79
84
|
}
|
|
80
85
|
else {
|
|
81
86
|
// only adjust left if out of bounds
|
|
82
|
-
const minLeft = padding;
|
|
83
|
-
const maxLeft = window.innerWidth - this.width - padding;
|
|
87
|
+
const minLeft = padding - this.leftBoundaryMargin;
|
|
88
|
+
const maxLeft = window.innerWidth - this.width - padding + this.rightBoundaryMargin;
|
|
84
89
|
if (this.left < minLeft) {
|
|
85
90
|
this.left = minLeft;
|
|
86
91
|
}
|
|
@@ -89,8 +94,8 @@ export class FloatingWindow extends RapidElement {
|
|
|
89
94
|
}
|
|
90
95
|
}
|
|
91
96
|
// only adjust top if out of bounds
|
|
92
|
-
const minTop = padding;
|
|
93
|
-
const maxTop = Math.max(padding, window.innerHeight - currentHeight - padding);
|
|
97
|
+
const minTop = padding - this.topBoundaryMargin;
|
|
98
|
+
const maxTop = Math.max(padding - this.topBoundaryMargin, window.innerHeight - currentHeight - padding + this.bottomBoundaryMargin);
|
|
94
99
|
if (this.top < minTop) {
|
|
95
100
|
this.top = minTop;
|
|
96
101
|
}
|
|
@@ -125,6 +130,11 @@ export class FloatingWindow extends RapidElement {
|
|
|
125
130
|
background: transparent;
|
|
126
131
|
border-radius: 0;
|
|
127
132
|
box-shadow: none;
|
|
133
|
+
pointer-events: none;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.window.chromeless .body {
|
|
137
|
+
pointer-events: none;
|
|
128
138
|
}
|
|
129
139
|
|
|
130
140
|
.window.dragging {
|
|
@@ -342,4 +352,16 @@ __decorate([
|
|
|
342
352
|
__decorate([
|
|
343
353
|
property({ type: String })
|
|
344
354
|
], FloatingWindow.prototype, "color", void 0);
|
|
355
|
+
__decorate([
|
|
356
|
+
property({ type: Number })
|
|
357
|
+
], FloatingWindow.prototype, "leftBoundaryMargin", void 0);
|
|
358
|
+
__decorate([
|
|
359
|
+
property({ type: Number })
|
|
360
|
+
], FloatingWindow.prototype, "rightBoundaryMargin", void 0);
|
|
361
|
+
__decorate([
|
|
362
|
+
property({ type: Number })
|
|
363
|
+
], FloatingWindow.prototype, "topBoundaryMargin", void 0);
|
|
364
|
+
__decorate([
|
|
365
|
+
property({ type: Number })
|
|
366
|
+
], FloatingWindow.prototype, "bottomBoundaryMargin", void 0);
|
|
345
367
|
//# sourceMappingURL=FloatingWindow.js.map
|