@nyaruka/temba-components 0.132.0 → 0.134.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 +31 -1
- package/demo/components/flow/example.html +1 -0
- package/demo/components/webchat/example.html +1 -1
- package/demo/static/css/tailwind.css +30019 -0
- package/dist/locales/es.js +5 -5
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/fr.js +5 -5
- package/dist/locales/fr.js.map +1 -1
- package/dist/locales/locale-codes.js +2 -11
- package/dist/locales/locale-codes.js.map +1 -1
- package/dist/locales/pt.js +5 -5
- package/dist/locales/pt.js.map +1 -1
- package/dist/temba-components.js +555 -476
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/display/Chat.js +248 -95
- package/out-tsc/src/display/Chat.js.map +1 -1
- package/out-tsc/src/display/FloatingTab.js +4 -4
- package/out-tsc/src/display/FloatingTab.js.map +1 -1
- package/out-tsc/src/display/TembaUser.js +3 -3
- package/out-tsc/src/display/TembaUser.js.map +1 -1
- package/out-tsc/src/events.js.map +1 -1
- package/out-tsc/src/flow/CanvasNode.js +132 -58
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +183 -58
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/utils.js +141 -0
- package/out-tsc/src/flow/utils.js.map +1 -1
- package/out-tsc/src/interfaces.js.map +1 -1
- package/out-tsc/src/layout/FloatingWindow.js +1 -2
- package/out-tsc/src/layout/FloatingWindow.js.map +1 -1
- package/out-tsc/src/list/ContentMenu.js +1 -0
- package/out-tsc/src/list/ContentMenu.js.map +1 -1
- package/out-tsc/src/list/SortableList.js +3 -2
- package/out-tsc/src/list/SortableList.js.map +1 -1
- package/out-tsc/src/live/ContactChat.js +184 -205
- package/out-tsc/src/live/ContactChat.js.map +1 -1
- package/out-tsc/src/locales/es.js +5 -5
- package/out-tsc/src/locales/es.js.map +1 -1
- package/out-tsc/src/locales/fr.js +5 -5
- package/out-tsc/src/locales/fr.js.map +1 -1
- package/out-tsc/src/locales/locale-codes.js +2 -11
- package/out-tsc/src/locales/locale-codes.js.map +1 -1
- package/out-tsc/src/locales/pt.js +5 -5
- package/out-tsc/src/locales/pt.js.map +1 -1
- package/out-tsc/src/store/AppState.js +34 -0
- package/out-tsc/src/store/AppState.js.map +1 -1
- package/out-tsc/src/store/Store.js +5 -5
- package/out-tsc/src/store/Store.js.map +1 -1
- package/out-tsc/src/utils.js +3 -3
- package/out-tsc/src/utils.js.map +1 -1
- package/out-tsc/src/webchat/WebChat.js +22 -9
- package/out-tsc/src/webchat/WebChat.js.map +1 -1
- package/out-tsc/test/ActionHelper.js +6 -5
- package/out-tsc/test/ActionHelper.js.map +1 -1
- package/out-tsc/test/actions/send_broadcast.test.js +9 -4
- package/out-tsc/test/actions/send_broadcast.test.js.map +1 -1
- package/out-tsc/test/temba-contact-chat.test.js +1 -1
- package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
- package/out-tsc/test/temba-floating-window.test.js +0 -2
- package/out-tsc/test/temba-floating-window.test.js.map +1 -1
- package/out-tsc/test/temba-flow-collision.test.js +673 -0
- package/out-tsc/test/temba-flow-collision.test.js.map +1 -0
- package/out-tsc/test/temba-flow-editor-node.test.js +195 -0
- package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
- package/out-tsc/test/temba-utils-uuid.test.js +45 -1
- package/out-tsc/test/temba-utils-uuid.test.js.map +1 -1
- package/out-tsc/test/utils.test.js +2 -2
- package/out-tsc/test/utils.test.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/actions/add_contact_groups/render/descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/long-group-names.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/many-groups.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/multiple-groups.png +0 -0
- package/screenshots/truth/actions/add_contact_groups/render/single-group.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/expression-facebook.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/expression-phone.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/facebook-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/instagram-handle.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/line-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/phone-number.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/telegram-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/viber-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/wechat-id.png +0 -0
- package/screenshots/truth/actions/add_contact_urn/render/whatsapp.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/cleanup-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/long-descriptive-group-names.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/many-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/multiple-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/remove-from-all-groups.png +0 -0
- package/screenshots/truth/actions/remove_contact_groups/render/single-group.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/contacts-only.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/groups-and-contacts.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/groups-only.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/many-groups.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/multiline-text.png +0 -0
- package/screenshots/truth/actions/send_broadcast/render/with-attachments.png +0 -0
- package/screenshots/truth/actions/send_email/render/complex-business-email.png +0 -0
- package/screenshots/truth/actions/send_email/render/empty-body.png +0 -0
- package/screenshots/truth/actions/send_email/render/empty-subject.png +0 -0
- package/screenshots/truth/actions/send_email/render/long-subject.png +0 -0
- package/screenshots/truth/actions/send_email/render/multiline-body.png +0 -0
- package/screenshots/truth/actions/send_email/render/multiple-recipients.png +0 -0
- package/screenshots/truth/actions/send_email/render/simple-email.png +0 -0
- package/screenshots/truth/actions/send_email/render/with-expressions.png +0 -0
- package/screenshots/truth/actions/send_msg/render/long-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/multiline-text-with-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/simple-text.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-with-linebreaks.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-with-many-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-with-quick-replies.png +0 -0
- package/screenshots/truth/actions/send_msg/render/text-without-quick-replies.png +0 -0
- package/screenshots/truth/actions/start_session/render/contact-query.png +0 -0
- package/screenshots/truth/actions/start_session/render/contacts-only.png +0 -0
- package/screenshots/truth/actions/start_session/render/create-contact.png +0 -0
- package/screenshots/truth/actions/start_session/render/groups-and-contacts.png +0 -0
- package/screenshots/truth/actions/start_session/render/groups-only.png +0 -0
- package/screenshots/truth/actions/start_session/render/many-recipients.png +0 -0
- package/screenshots/truth/contacts/chat-failure.png +0 -0
- package/screenshots/truth/contacts/chat-for-archived-contact.png +0 -0
- package/screenshots/truth/contacts/chat-for-blocked-contact.png +0 -0
- package/screenshots/truth/contacts/chat-for-stopped-contact.png +0 -0
- package/screenshots/truth/contacts/chat-sends-attachments-only.png +0 -0
- package/screenshots/truth/contacts/chat-sends-text-and-attachments.png +0 -0
- package/screenshots/truth/contacts/chat-sends-text-only.png +0 -0
- package/screenshots/truth/floating-tab/default.png +0 -0
- package/screenshots/truth/floating-tab/gray.png +0 -0
- package/screenshots/truth/floating-tab/green.png +0 -0
- package/screenshots/truth/floating-tab/hover.png +0 -0
- package/screenshots/truth/floating-tab/purple.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/information-extraction.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/sentiment-analysis.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/summarization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm/render/translation-task.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/basic-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/custom-input-and-result-name.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/feedback-categorization.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/many-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_llm_categorize/render/minimal-categories.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/ab-test-multiple-variants.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/sampling-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/three-way-split.png +0 -0
- package/screenshots/truth/nodes/split_by_random/render/two-bucket-split.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/basic-digits-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/phone-number-collection.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/single-digit-with-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/render/verification-code.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/basic-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/custom-result-name.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/no-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/render/short-timeout.png +0 -0
- package/src/display/Chat.ts +331 -135
- package/src/display/FloatingTab.ts +4 -4
- package/src/display/TembaUser.ts +3 -2
- package/src/events.ts +12 -12
- package/src/flow/CanvasNode.ts +140 -57
- package/src/flow/Editor.ts +240 -58
- package/src/flow/utils.ts +207 -1
- package/src/interfaces.ts +7 -0
- package/src/layout/FloatingWindow.ts +1 -3
- package/src/list/ContentMenu.ts +1 -0
- package/src/list/SortableList.ts +3 -2
- package/src/live/ContactChat.ts +195 -221
- package/src/locales/es.ts +13 -18
- package/src/locales/fr.ts +13 -18
- package/src/locales/locale-codes.ts +2 -11
- package/src/locales/pt.ts +13 -18
- package/src/store/AppState.ts +43 -0
- package/src/store/Store.ts +5 -5
- package/src/utils.ts +3 -3
- package/src/webchat/WebChat.ts +24 -10
- package/test/ActionHelper.ts +13 -5
- package/test/actions/send_broadcast.test.ts +4 -2
- package/test/temba-contact-chat.test.ts +1 -1
- package/test/temba-floating-window.test.ts +0 -2
- package/test/temba-flow-collision.test.ts +833 -0
- package/test/temba-flow-editor-node.test.ts +224 -0
- package/test/temba-utils-uuid.test.ts +61 -1
- package/test/utils.test.ts +7 -2
- package/test-assets/contacts/history.json +22 -9
- package/web-test-runner.config.mjs +3 -3
|
@@ -57,6 +57,7 @@ export class CanvasNode extends RapidElement {
|
|
|
57
57
|
|
|
58
58
|
.action .cn-title:hover .remove-button,
|
|
59
59
|
.router:hover .remove-button {
|
|
60
|
+
visibility: visible;
|
|
60
61
|
opacity: 0.7;
|
|
61
62
|
}
|
|
62
63
|
|
|
@@ -73,7 +74,7 @@ export class CanvasNode extends RapidElement {
|
|
|
73
74
|
.remove-button {
|
|
74
75
|
background: transparent;
|
|
75
76
|
color: white;
|
|
76
|
-
|
|
77
|
+
visibility: hidden;
|
|
77
78
|
cursor: pointer;
|
|
78
79
|
font-size: 1em;
|
|
79
80
|
font-weight: 600;
|
|
@@ -81,16 +82,22 @@ export class CanvasNode extends RapidElement {
|
|
|
81
82
|
z-index: 10;
|
|
82
83
|
transition: all 100ms ease-in-out;
|
|
83
84
|
align-self: center;
|
|
84
|
-
|
|
85
|
+
margin-right:0.15em;
|
|
85
86
|
border: 0px solid red;
|
|
86
87
|
width: 1em;
|
|
87
88
|
pointer-events: auto; /* Ensure remove button can receive events */
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
.remove-button:hover {
|
|
92
|
+
visibility: visible;
|
|
91
93
|
opacity: 1;
|
|
92
94
|
}
|
|
93
95
|
|
|
96
|
+
.translating-hidden {
|
|
97
|
+
visibility: hidden !important;
|
|
98
|
+
pointer-events: none !important;
|
|
99
|
+
}
|
|
100
|
+
|
|
94
101
|
.action.sortable {
|
|
95
102
|
display: flex;
|
|
96
103
|
align-items: stretch;
|
|
@@ -102,6 +109,7 @@ export class CanvasNode extends RapidElement {
|
|
|
102
109
|
flex-direction: column;
|
|
103
110
|
min-width: 0; /* Allow flex item to shrink below its content size */
|
|
104
111
|
overflow: hidden;
|
|
112
|
+
background: #fff;
|
|
105
113
|
}
|
|
106
114
|
|
|
107
115
|
.action .body {
|
|
@@ -132,7 +140,7 @@ export class CanvasNode extends RapidElement {
|
|
|
132
140
|
}
|
|
133
141
|
|
|
134
142
|
.action .drag-handle {
|
|
135
|
-
|
|
143
|
+
visibility: hidden;
|
|
136
144
|
transition: all 200ms ease-in-out;
|
|
137
145
|
cursor: move;
|
|
138
146
|
background: rgba(0, 0, 0, 0.02);
|
|
@@ -147,6 +155,7 @@ export class CanvasNode extends RapidElement {
|
|
|
147
155
|
}
|
|
148
156
|
|
|
149
157
|
.action:hover .drag-handle {
|
|
158
|
+
visibility: visible;
|
|
150
159
|
opacity: 0.7;
|
|
151
160
|
|
|
152
161
|
|
|
@@ -157,6 +166,7 @@ export class CanvasNode extends RapidElement {
|
|
|
157
166
|
}
|
|
158
167
|
|
|
159
168
|
.action .drag-handle:hover {
|
|
169
|
+
visibility: visible;
|
|
160
170
|
opacity: 1;
|
|
161
171
|
|
|
162
172
|
}
|
|
@@ -360,6 +370,18 @@ export class CanvasNode extends RapidElement {
|
|
|
360
370
|
opacity: 1 !important;
|
|
361
371
|
transform: scale(1.1);
|
|
362
372
|
}
|
|
373
|
+
|
|
374
|
+
.empty-node-placeholder {
|
|
375
|
+
height: 60px;
|
|
376
|
+
background: #f3f4f6;
|
|
377
|
+
border: 2px dashed #d1d5db;
|
|
378
|
+
border-radius: var(--curvature);
|
|
379
|
+
display: flex;
|
|
380
|
+
align-items: center;
|
|
381
|
+
justify-content: center;
|
|
382
|
+
color: #9ca3af;
|
|
383
|
+
font-size: 0.9em;
|
|
384
|
+
}
|
|
363
385
|
}`;
|
|
364
386
|
}
|
|
365
387
|
constructor() {
|
|
@@ -382,6 +404,9 @@ export class CanvasNode extends RapidElement {
|
|
|
382
404
|
this.draggedActionHeight = 0;
|
|
383
405
|
// Track external action drag (action being dragged from another node)
|
|
384
406
|
this.externalDragInfo = null;
|
|
407
|
+
// Track if we're showing a placeholder for our own last action being dragged out
|
|
408
|
+
this.showLastActionPlaceholder = false;
|
|
409
|
+
this.lastActionPlaceholderHeight = 60;
|
|
385
410
|
this.handleActionOrderChanged = this.handleActionOrderChanged.bind(this);
|
|
386
411
|
this.handleActionDragStart = this.handleActionDragStart.bind(this);
|
|
387
412
|
this.handleActionDragExternal = this.handleActionDragExternal.bind(this);
|
|
@@ -407,6 +432,14 @@ export class CanvasNode extends RapidElement {
|
|
|
407
432
|
updated(changes) {
|
|
408
433
|
var _b;
|
|
409
434
|
super.updated(changes);
|
|
435
|
+
if (!!changes.get('ui') && changes.has('ui')) {
|
|
436
|
+
// run revalidation every 50ms until 350ms to catch animation updates
|
|
437
|
+
for (let delay = 25; delay <= 350; delay += 25) {
|
|
438
|
+
setTimeout(() => {
|
|
439
|
+
this.plumber.revalidate([this.node.uuid]);
|
|
440
|
+
}, delay);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
410
443
|
if (changes.has('node')) {
|
|
411
444
|
// Only proceed if plumber is available (for tests that don't set it up)
|
|
412
445
|
if (this.plumber) {
|
|
@@ -594,6 +627,8 @@ export class CanvasNode extends RapidElement {
|
|
|
594
627
|
this.actionRemovalTimeouts.delete(nodeId);
|
|
595
628
|
}
|
|
596
629
|
// Fire the node deleted event
|
|
630
|
+
// The Editor will handle cleanup (Plumber connections) and call store.removeNodes()
|
|
631
|
+
// The store's removeNodes method handles rerouting of connections
|
|
597
632
|
this.fireCustomEvent(CustomEventType.NodeDeleted, {
|
|
598
633
|
uuid: this.node.uuid
|
|
599
634
|
});
|
|
@@ -601,6 +636,11 @@ export class CanvasNode extends RapidElement {
|
|
|
601
636
|
handleActionOrderChanged(event) {
|
|
602
637
|
var _b;
|
|
603
638
|
const [fromIdx, toIdx] = event.detail.swap;
|
|
639
|
+
// If we have an external drag in progress, ignore internal order changes
|
|
640
|
+
// as they'll be handled by the external drop handler
|
|
641
|
+
if (this.externalDragInfo) {
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
604
644
|
// swap our actions
|
|
605
645
|
const newActions = [...this.node.actions];
|
|
606
646
|
const movedAction = newActions.splice(fromIdx, 1)[0];
|
|
@@ -623,6 +663,12 @@ export class CanvasNode extends RapidElement {
|
|
|
623
663
|
// Fallback to a reasonable default
|
|
624
664
|
this.draggedActionHeight = 60;
|
|
625
665
|
}
|
|
666
|
+
// If this is the last action, show placeholder
|
|
667
|
+
if (this.node.actions.length === 1) {
|
|
668
|
+
this.showLastActionPlaceholder = true;
|
|
669
|
+
this.lastActionPlaceholderHeight = this.draggedActionHeight;
|
|
670
|
+
this.requestUpdate();
|
|
671
|
+
}
|
|
626
672
|
}
|
|
627
673
|
handleActionDragExternal(event) {
|
|
628
674
|
// stop propagation of the original event from SortableList
|
|
@@ -636,6 +682,8 @@ export class CanvasNode extends RapidElement {
|
|
|
636
682
|
}
|
|
637
683
|
const actionIndex = parseInt(splitId[1], 10);
|
|
638
684
|
const action = this.node.actions[actionIndex];
|
|
685
|
+
// Check if this is the last action
|
|
686
|
+
const isLastAction = this.node.actions.length === 1;
|
|
639
687
|
// fire event to editor to show canvas drop preview, including the captured height
|
|
640
688
|
this.fireCustomEvent(CustomEventType.DragExternal, {
|
|
641
689
|
action,
|
|
@@ -643,7 +691,8 @@ export class CanvasNode extends RapidElement {
|
|
|
643
691
|
actionIndex,
|
|
644
692
|
mouseX: event.detail.mouseX,
|
|
645
693
|
mouseY: event.detail.mouseY,
|
|
646
|
-
actionHeight: this.draggedActionHeight
|
|
694
|
+
actionHeight: this.draggedActionHeight,
|
|
695
|
+
isLastAction
|
|
647
696
|
});
|
|
648
697
|
}
|
|
649
698
|
handleActionDragInternal(_event) {
|
|
@@ -654,6 +703,8 @@ export class CanvasNode extends RapidElement {
|
|
|
654
703
|
}
|
|
655
704
|
handleActionDragStop(event) {
|
|
656
705
|
const isExternal = event.detail.isExternal;
|
|
706
|
+
// Clear last action placeholder when drag stops
|
|
707
|
+
this.showLastActionPlaceholder = false;
|
|
657
708
|
if (isExternal) {
|
|
658
709
|
// stop propagation of the original event from SortableList
|
|
659
710
|
event.stopPropagation();
|
|
@@ -666,16 +717,21 @@ export class CanvasNode extends RapidElement {
|
|
|
666
717
|
}
|
|
667
718
|
const actionIndex = parseInt(split[1], 10);
|
|
668
719
|
const action = this.node.actions[actionIndex];
|
|
669
|
-
//
|
|
720
|
+
// Check if this is the last action in the node
|
|
721
|
+
const isLastAction = this.node.actions.length === 1;
|
|
722
|
+
// Always fire the DragStop event so the Editor can handle drops on other nodes
|
|
723
|
+
// The Editor will decide whether to create a new node or drop on existing node
|
|
670
724
|
this.fireCustomEvent(CustomEventType.DragStop, {
|
|
671
725
|
action,
|
|
672
726
|
nodeUuid: this.node.uuid,
|
|
673
727
|
actionIndex,
|
|
674
728
|
isExternal: true,
|
|
729
|
+
isLastAction,
|
|
675
730
|
mouseX: event.detail.mouseX,
|
|
676
731
|
mouseY: event.detail.mouseY
|
|
677
732
|
});
|
|
678
733
|
}
|
|
734
|
+
this.requestUpdate();
|
|
679
735
|
}
|
|
680
736
|
handleActionMouseDown(event, action) {
|
|
681
737
|
// Don't handle clicks on the remove button, drag handle, or when action is in removing state
|
|
@@ -931,7 +987,6 @@ export class CanvasNode extends RapidElement {
|
|
|
931
987
|
const dropIndex = (_e = (_c = (_b = this.externalDragInfo) === null || _b === void 0 ? void 0 : _b.dropIndex) !== null && _c !== void 0 ? _c : (_d = this.node.actions) === null || _d === void 0 ? void 0 : _d.length) !== null && _e !== void 0 ? _e : 0;
|
|
932
988
|
// Clear external drag state
|
|
933
989
|
this.externalDragInfo = null;
|
|
934
|
-
// Remove the action from the source node
|
|
935
990
|
const store = getStore();
|
|
936
991
|
if (!store)
|
|
937
992
|
return;
|
|
@@ -939,51 +994,64 @@ export class CanvasNode extends RapidElement {
|
|
|
939
994
|
if (!flowDefinition)
|
|
940
995
|
return;
|
|
941
996
|
const sourceNode = flowDefinition.nodes.find((n) => n.uuid === sourceNodeUuid);
|
|
942
|
-
if (sourceNode)
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
this.fireCustomEvent(CustomEventType.NodeDeleted, {
|
|
947
|
-
uuid: sourceNodeUuid
|
|
948
|
-
});
|
|
949
|
-
}
|
|
950
|
-
else {
|
|
951
|
-
// Update source node
|
|
952
|
-
const updatedSourceNode = {
|
|
953
|
-
...sourceNode,
|
|
954
|
-
actions: updatedSourceActions
|
|
955
|
-
};
|
|
956
|
-
(_f = getStore()) === null || _f === void 0 ? void 0 : _f.getState().updateNode(sourceNodeUuid, updatedSourceNode);
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
// Add the action to this node at the calculated position
|
|
997
|
+
if (!sourceNode)
|
|
998
|
+
return;
|
|
999
|
+
// IMPORTANT: Add the action to this node FIRST, before removing from source
|
|
1000
|
+
// This ensures we don't lose the action if the source node gets deleted
|
|
960
1001
|
const newActions = [...this.node.actions];
|
|
961
1002
|
newActions.splice(dropIndex, 0, action);
|
|
962
1003
|
const updatedNode = { ...this.node, actions: newActions };
|
|
963
|
-
(
|
|
1004
|
+
(_f = getStore()) === null || _f === void 0 ? void 0 : _f.getState().updateNode(this.node.uuid, updatedNode);
|
|
1005
|
+
// Now remove the action from the source node
|
|
1006
|
+
const updatedSourceActions = sourceNode.actions.filter((_a, idx) => idx !== actionIndex);
|
|
1007
|
+
// If source node has no actions left, remove it
|
|
1008
|
+
if (updatedSourceActions.length === 0) {
|
|
1009
|
+
// Fire event to Editor so it can clean up jsPlumb connections properly
|
|
1010
|
+
this.fireCustomEvent(CustomEventType.NodeDeleted, {
|
|
1011
|
+
uuid: sourceNodeUuid
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
else {
|
|
1015
|
+
// Update source node
|
|
1016
|
+
const updatedSourceNode = {
|
|
1017
|
+
...sourceNode,
|
|
1018
|
+
actions: updatedSourceActions
|
|
1019
|
+
};
|
|
1020
|
+
(_g = getStore()) === null || _g === void 0 ? void 0 : _g.getState().updateNode(sourceNodeUuid, updatedSourceNode);
|
|
1021
|
+
}
|
|
964
1022
|
// Request update
|
|
965
1023
|
this.requestUpdate();
|
|
966
1024
|
}
|
|
967
1025
|
renderTitle(config, action, index, isRemoving = false) {
|
|
968
|
-
var _b, _c, _d;
|
|
1026
|
+
var _b, _c, _d, _e;
|
|
969
1027
|
const color = config.group
|
|
970
1028
|
? (_b = ACTION_GROUP_METADATA[config.group]) === null || _b === void 0 ? void 0 : _b.color
|
|
971
1029
|
: '#aaaaaa';
|
|
972
1030
|
return html `<div class="cn-title" style="background:${color}">
|
|
973
|
-
${
|
|
974
|
-
? html `<temba-icon
|
|
975
|
-
|
|
1031
|
+
${((_c = this.ui) === null || _c === void 0 ? void 0 : _c.type) === 'execute_actions'
|
|
1032
|
+
? html `<temba-icon
|
|
1033
|
+
class="drag-handle ${this.isTranslating
|
|
1034
|
+
? 'translating-hidden'
|
|
1035
|
+
: ''}"
|
|
1036
|
+
name="sort"
|
|
1037
|
+
></temba-icon>`
|
|
1038
|
+
: ((_e = (_d = this.node) === null || _d === void 0 ? void 0 : _d.actions) === null || _e === void 0 ? void 0 : _e.length) > 1
|
|
1039
|
+
? html `<temba-icon
|
|
1040
|
+
class="drag-handle ${this.isTranslating
|
|
1041
|
+
? 'translating-hidden'
|
|
1042
|
+
: ''}"
|
|
1043
|
+
name="sort"
|
|
1044
|
+
></temba-icon>`
|
|
1045
|
+
: html `<div class="title-spacer"></div>`}
|
|
976
1046
|
|
|
977
1047
|
<div class="name">${isRemoving ? 'Remove?' : config.name}</div>
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
</div>`
|
|
986
|
-
: html `<div class="title-spacer"></div>`}
|
|
1048
|
+
<div
|
|
1049
|
+
class="remove-button ${this.isTranslating ? 'translating-hidden' : ''}"
|
|
1050
|
+
@click=${(e) => this.handleActionRemoveClick(e, action, index)}
|
|
1051
|
+
title="Remove action"
|
|
1052
|
+
>
|
|
1053
|
+
✕
|
|
1054
|
+
</div>
|
|
987
1055
|
</div>`;
|
|
988
1056
|
}
|
|
989
1057
|
renderNodeTitle(config, node, ui, isRemoving = false) {
|
|
@@ -1005,15 +1073,13 @@ export class CanvasNode extends RapidElement {
|
|
|
1005
1073
|
? config.renderTitle(node, ui)
|
|
1006
1074
|
: html `${config.name}`}
|
|
1007
1075
|
</div>
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
</div>`
|
|
1016
|
-
: html `<div class="title-spacer"></div>`}
|
|
1076
|
+
<div
|
|
1077
|
+
class="remove-button ${this.isTranslating ? 'translating-hidden' : ''}"
|
|
1078
|
+
@click=${(e) => this.handleNodeRemoveClick(e)}
|
|
1079
|
+
title="Remove node"
|
|
1080
|
+
>
|
|
1081
|
+
✕
|
|
1082
|
+
</div>
|
|
1017
1083
|
</div>`;
|
|
1018
1084
|
}
|
|
1019
1085
|
renderDropPlaceholder() {
|
|
@@ -1251,18 +1317,26 @@ export class CanvasNode extends RapidElement {
|
|
|
1251
1317
|
: this.node.actions.length > 0
|
|
1252
1318
|
? this.ui.type === 'execute_actions'
|
|
1253
1319
|
? html `<temba-sortable-list
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1320
|
+
dragHandle="drag-handle"
|
|
1321
|
+
externalDrag
|
|
1322
|
+
@temba-order-changed="${this.handleActionOrderChanged}"
|
|
1323
|
+
@temba-drag-start="${this.handleActionDragStart}"
|
|
1324
|
+
@temba-drag-external="${this.handleActionDragExternal}"
|
|
1325
|
+
@temba-drag-internal="${this.handleActionDragInternal}"
|
|
1326
|
+
@temba-drag-stop="${this.handleActionDragStop}"
|
|
1327
|
+
>
|
|
1328
|
+
${this.renderActionsWithPlaceholder()}
|
|
1329
|
+
</temba-sortable-list>
|
|
1330
|
+
${this.showLastActionPlaceholder
|
|
1331
|
+
? html `<div
|
|
1332
|
+
class="empty-node-placeholder"
|
|
1333
|
+
style="height: ${this.lastActionPlaceholderHeight}px;"
|
|
1334
|
+
></div>`
|
|
1335
|
+
: ''}`
|
|
1264
1336
|
: html `${this.node.actions.map((action, index) => this.renderAction(this.node, action, index))}`
|
|
1265
|
-
: ''
|
|
1337
|
+
: this.ui.type === 'execute_actions'
|
|
1338
|
+
? html `<div class="empty-node-placeholder"></div>`
|
|
1339
|
+
: ''}
|
|
1266
1340
|
${this.node.router
|
|
1267
1341
|
? html `<div class="router-section">
|
|
1268
1342
|
${this.renderRouter(this.node.router, this.ui)}
|