@nyaruka/temba-components 0.138.6 → 0.140.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/.github/workflows/cla.yml +1 -1
- package/.github/workflows/copilot-setup-steps.yml +6 -1
- package/CHANGELOG.md +26 -0
- package/demo/data/flows/sample-flow.json +24 -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 +1112 -882
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/display/Chat.js +10 -7
- package/out-tsc/src/display/Chat.js.map +1 -1
- package/out-tsc/src/display/Dropdown.js +3 -1
- package/out-tsc/src/display/Dropdown.js.map +1 -1
- package/out-tsc/src/display/FloatingTab.js +25 -32
- package/out-tsc/src/display/FloatingTab.js.map +1 -1
- package/out-tsc/src/display/Thumbnail.js +163 -5
- package/out-tsc/src/display/Thumbnail.js.map +1 -1
- package/out-tsc/src/flow/CanvasMenu.js +5 -3
- package/out-tsc/src/flow/CanvasMenu.js.map +1 -1
- package/out-tsc/src/flow/CanvasNode.js +70 -29
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +290 -239
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/NodeEditor.js +118 -10
- package/out-tsc/src/flow/NodeEditor.js.map +1 -1
- package/out-tsc/src/flow/Plumber.js +757 -403
- package/out-tsc/src/flow/Plumber.js.map +1 -1
- package/out-tsc/src/flow/StickyNote.js +13 -4
- package/out-tsc/src/flow/StickyNote.js.map +1 -1
- package/out-tsc/src/flow/actions/audio-player.js +112 -0
- package/out-tsc/src/flow/actions/audio-player.js.map +1 -0
- package/out-tsc/src/flow/actions/enter_flow.js +43 -0
- package/out-tsc/src/flow/actions/enter_flow.js.map +1 -0
- package/out-tsc/src/flow/actions/play_audio.js +57 -4
- package/out-tsc/src/flow/actions/play_audio.js.map +1 -1
- package/out-tsc/src/flow/actions/say_msg.js +86 -3
- package/out-tsc/src/flow/actions/say_msg.js.map +1 -1
- package/out-tsc/src/flow/config.js +11 -3
- package/out-tsc/src/flow/config.js.map +1 -1
- package/out-tsc/src/flow/nodes/shared-rules.js +1 -1
- package/out-tsc/src/flow/nodes/shared-rules.js.map +1 -1
- package/out-tsc/src/flow/nodes/terminal.js +7 -0
- package/out-tsc/src/flow/nodes/terminal.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_audio.js +77 -0
- package/out-tsc/src/flow/nodes/wait_for_audio.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_dial.js +151 -0
- package/out-tsc/src/flow/nodes/wait_for_dial.js.map +1 -0
- package/out-tsc/src/flow/nodes/wait_for_digits.js +61 -1
- package/out-tsc/src/flow/nodes/wait_for_digits.js.map +1 -1
- package/out-tsc/src/flow/nodes/wait_for_menu.js +173 -2
- package/out-tsc/src/flow/nodes/wait_for_menu.js.map +1 -1
- package/out-tsc/src/flow/operators.js +21 -5
- package/out-tsc/src/flow/operators.js.map +1 -1
- package/out-tsc/src/flow/types.js.map +1 -1
- package/out-tsc/src/flow/utils.js +213 -65
- package/out-tsc/src/flow/utils.js.map +1 -1
- package/out-tsc/src/form/ArrayEditor.js +4 -2
- package/out-tsc/src/form/ArrayEditor.js.map +1 -1
- package/out-tsc/src/form/FieldRenderer.js +49 -0
- package/out-tsc/src/form/FieldRenderer.js.map +1 -1
- package/out-tsc/src/interfaces.js +2 -0
- package/out-tsc/src/interfaces.js.map +1 -1
- package/out-tsc/src/layout/Dialog.js +52 -7
- package/out-tsc/src/layout/Dialog.js.map +1 -1
- package/out-tsc/src/list/TicketList.js +4 -1
- package/out-tsc/src/list/TicketList.js.map +1 -1
- package/out-tsc/src/live/TembaChart.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/simulator/Simulator.js +10 -3
- package/out-tsc/src/simulator/Simulator.js.map +1 -1
- package/out-tsc/src/store/AppState.js +89 -3
- package/out-tsc/src/store/AppState.js.map +1 -1
- package/out-tsc/test/actions/play_audio.test.js +118 -0
- package/out-tsc/test/actions/play_audio.test.js.map +1 -0
- package/out-tsc/test/actions/say_msg.test.js +158 -0
- package/out-tsc/test/actions/say_msg.test.js.map +1 -0
- package/out-tsc/test/nodes/wait_for_audio.test.js +156 -0
- package/out-tsc/test/nodes/wait_for_audio.test.js.map +1 -0
- package/out-tsc/test/nodes/wait_for_dial.test.js +336 -0
- package/out-tsc/test/nodes/wait_for_dial.test.js.map +1 -0
- package/out-tsc/test/nodes/wait_for_digits.test.js +198 -84
- package/out-tsc/test/nodes/wait_for_digits.test.js.map +1 -1
- package/out-tsc/test/nodes/wait_for_menu.test.js +340 -0
- package/out-tsc/test/nodes/wait_for_menu.test.js.map +1 -0
- package/out-tsc/test/temba-floating-tab.test.js +4 -6
- package/out-tsc/test/temba-floating-tab.test.js.map +1 -1
- package/out-tsc/test/temba-flow-collision.test.js +473 -220
- package/out-tsc/test/temba-flow-collision.test.js.map +1 -1
- package/out-tsc/test/temba-flow-editor.test.js +0 -2
- package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
- package/out-tsc/test/temba-flow-plumber-connections.test.js +83 -84
- package/out-tsc/test/temba-flow-plumber-connections.test.js.map +1 -1
- package/out-tsc/test/temba-flow-plumber.test.js +102 -93
- package/out-tsc/test/temba-flow-plumber.test.js.map +1 -1
- package/out-tsc/test/temba-node-type-selector.test.js +6 -6
- package/out-tsc/test/temba-node-type-selector.test.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/actions/play_audio/editor/expression-url.png +0 -0
- package/screenshots/truth/actions/play_audio/editor/static-url.png +0 -0
- package/screenshots/truth/actions/play_audio/render/expression-url.png +0 -0
- package/screenshots/truth/actions/play_audio/render/static-url.png +0 -0
- package/screenshots/truth/actions/say_msg/editor/multiline-text.png +0 -0
- package/screenshots/truth/actions/say_msg/editor/simple-text.png +0 -0
- package/screenshots/truth/actions/say_msg/editor/text-with-audio-url.png +0 -0
- package/screenshots/truth/actions/say_msg/render/multiline-text.png +0 -0
- package/screenshots/truth/actions/say_msg/render/simple-text.png +0 -0
- package/screenshots/truth/actions/say_msg/render/text-with-audio-url.png +0 -0
- package/screenshots/truth/editor/router.png +0 -0
- package/screenshots/truth/editor/wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_audio/editor/basic-audio-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_audio/render/basic-audio-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_dial/editor/basic-dial.png +0 -0
- package/screenshots/truth/nodes/wait_for_dial/editor/dial-with-limits.png +0 -0
- package/screenshots/truth/nodes/wait_for_dial/render/basic-dial.png +0 -0
- package/screenshots/truth/nodes/wait_for_dial/render/dial-with-limits.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/basic-digits-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/digits-with-rules.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/digits-with-rules.png +0 -0
- package/screenshots/truth/nodes/wait_for_menu/editor/menu-with-digits.png +0 -0
- package/screenshots/truth/nodes/wait_for_menu/render/menu-with-digits.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/basic-wait.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/custom-result-name.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/no-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_response/editor/short-timeout.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 +13 -7
- package/src/display/Dropdown.ts +3 -1
- package/src/display/FloatingTab.ts +24 -33
- package/src/display/Thumbnail.ts +162 -2
- package/src/flow/CanvasMenu.ts +8 -3
- package/src/flow/CanvasNode.ts +75 -30
- package/src/flow/Editor.ts +336 -288
- package/src/flow/NodeEditor.ts +137 -9
- package/src/flow/Plumber.ts +1011 -457
- package/src/flow/StickyNote.ts +14 -4
- package/src/flow/actions/audio-player.ts +127 -0
- package/src/flow/actions/enter_flow.ts +44 -0
- package/src/flow/actions/play_audio.ts +64 -5
- package/src/flow/actions/say_msg.ts +94 -4
- package/src/flow/config.ts +11 -3
- package/src/flow/nodes/shared-rules.ts +1 -1
- package/src/flow/nodes/terminal.ts +9 -0
- package/src/flow/nodes/wait_for_audio.ts +88 -0
- package/src/flow/nodes/wait_for_dial.ts +176 -0
- package/src/flow/nodes/wait_for_digits.ts +86 -2
- package/src/flow/nodes/wait_for_menu.ts +209 -3
- package/src/flow/operators.ts +23 -5
- package/src/flow/types.ts +23 -1
- package/src/flow/utils.ts +238 -81
- package/src/form/ArrayEditor.ts +4 -2
- package/src/form/FieldRenderer.ts +64 -1
- package/src/interfaces.ts +3 -1
- package/src/layout/Dialog.ts +53 -7
- package/src/list/TicketList.ts +4 -1
- package/src/live/TembaChart.ts +1 -1
- 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/simulator/Simulator.ts +13 -3
- package/src/store/AppState.ts +105 -1
- package/src/store/flow-definition.d.ts +2 -0
- package/test/actions/play_audio.test.ts +155 -0
- package/test/actions/say_msg.test.ts +196 -0
- package/test/nodes/wait_for_audio.test.ts +182 -0
- package/test/nodes/wait_for_dial.test.ts +382 -0
- package/test/nodes/wait_for_digits.test.ts +233 -109
- package/test/nodes/wait_for_menu.test.ts +383 -0
- package/test/temba-floating-tab.test.ts +4 -6
- package/test/temba-flow-collision.test.ts +495 -293
- package/test/temba-flow-editor.test.ts +0 -2
- package/test/temba-flow-plumber-connections.test.ts +97 -97
- package/test/temba-flow-plumber.test.ts +116 -103
- package/test/temba-node-type-selector.test.ts +6 -6
- package/screenshots/truth/nodes/wait_for_digits/editor/phone-number-collection.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/single-digit-with-timeout.png +0 -0
- package/screenshots/truth/nodes/wait_for_digits/editor/verification-code.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/src/flow/CanvasNode.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { getClasses } from '../utils';
|
|
|
9
9
|
import { Plumber } from './Plumber';
|
|
10
10
|
import { getStore } from '../store/Store';
|
|
11
11
|
import { CustomEventType } from '../interfaces';
|
|
12
|
-
import { AppState, fromStore, zustand } from '../store/AppState';
|
|
12
|
+
import { AppState, FlowIssue, fromStore, zustand } from '../store/AppState';
|
|
13
13
|
|
|
14
14
|
const DRAG_THRESHOLD = 5;
|
|
15
15
|
|
|
@@ -49,6 +49,12 @@ export class CanvasNode extends RapidElement {
|
|
|
49
49
|
@fromStore(zustand, (state: AppState) => state.getCurrentActivity())
|
|
50
50
|
private activity!: any;
|
|
51
51
|
|
|
52
|
+
@fromStore(zustand, (state: AppState) => state.issuesByNode)
|
|
53
|
+
private issuesByNode!: Map<string, FlowIssue[]>;
|
|
54
|
+
|
|
55
|
+
@fromStore(zustand, (state: AppState) => state.issuesByAction)
|
|
56
|
+
private issuesByAction!: Map<string, FlowIssue[]>;
|
|
57
|
+
|
|
52
58
|
// Track exits that are in "removing" state
|
|
53
59
|
private exitRemovalTimeouts: Map<string, number> = new Map();
|
|
54
60
|
|
|
@@ -185,6 +191,12 @@ export class CanvasNode extends RapidElement {
|
|
|
185
191
|
pointer-events: none !important;
|
|
186
192
|
}
|
|
187
193
|
|
|
194
|
+
/* Issue indicators - hatched red title bar */
|
|
195
|
+
.action-content.has-issues .cn-title,
|
|
196
|
+
.node.has-issues > .router .cn-title {
|
|
197
|
+
background: repeating-linear-gradient(120deg, tomato, tomato 6px, #ff7056 0, #ff7056 18px) !important;
|
|
198
|
+
}
|
|
199
|
+
|
|
188
200
|
.action.sortable {
|
|
189
201
|
display: flex;
|
|
190
202
|
align-items: stretch;
|
|
@@ -360,11 +372,7 @@ export class CanvasNode extends RapidElement {
|
|
|
360
372
|
position: relative;
|
|
361
373
|
box-shadow: 0 2px 2px rgba(0, 0, 0, .1);
|
|
362
374
|
cursor: pointer;
|
|
363
|
-
pointer-events:
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
.exit.jtk-connected {
|
|
367
|
-
background: var(--color-connectors, #e6e6e6);
|
|
375
|
+
pointer-events: all;
|
|
368
376
|
}
|
|
369
377
|
|
|
370
378
|
.exit.connected {
|
|
@@ -376,11 +384,14 @@ export class CanvasNode extends RapidElement {
|
|
|
376
384
|
background-color: var(--color-connectors, #e6e6e6);
|
|
377
385
|
}
|
|
378
386
|
|
|
379
|
-
.exit.
|
|
380
|
-
background-color: #fff;
|
|
387
|
+
.exit.read-only, .exit.read-only:hover {
|
|
381
388
|
pointer-events: none !important;
|
|
382
389
|
cursor: default;
|
|
383
390
|
}
|
|
391
|
+
|
|
392
|
+
.exit.connected.read-only, .exit.connected.read-only:hover {
|
|
393
|
+
background-color: #fff;
|
|
394
|
+
}
|
|
384
395
|
|
|
385
396
|
.exit.removing, .exit.removing:hover {
|
|
386
397
|
background-color: var(--color-error);
|
|
@@ -549,14 +560,17 @@ export class CanvasNode extends RapidElement {
|
|
|
549
560
|
// make our initial connections
|
|
550
561
|
// We use setTimeout to allow for DOM updates to complete before querying for exits
|
|
551
562
|
this.connectionTimeout = window.setTimeout(() => {
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
this.plumber.
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
563
|
+
// Terminal nodes have no visible exits
|
|
564
|
+
if (this.ui?.type !== 'terminal') {
|
|
565
|
+
for (const exit of this.node.exits) {
|
|
566
|
+
this.plumber.makeSource(exit.uuid);
|
|
567
|
+
if (exit.destination_uuid) {
|
|
568
|
+
this.plumber.connectIds(
|
|
569
|
+
this.node.uuid,
|
|
570
|
+
exit.uuid,
|
|
571
|
+
exit.destination_uuid
|
|
572
|
+
);
|
|
573
|
+
}
|
|
560
574
|
}
|
|
561
575
|
}
|
|
562
576
|
// Note: revalidation is handled by plumber's processPendingConnections which calls repaintEverything
|
|
@@ -950,6 +964,11 @@ export class CanvasNode extends RapidElement {
|
|
|
950
964
|
this.requestUpdate();
|
|
951
965
|
}
|
|
952
966
|
|
|
967
|
+
private getTopCenter(el: Element): { x: number; y: number } {
|
|
968
|
+
const rect = el.getBoundingClientRect();
|
|
969
|
+
return { x: rect.left + rect.width / 2, y: rect.top };
|
|
970
|
+
}
|
|
971
|
+
|
|
953
972
|
private handleActionMouseDown(event: MouseEvent, action: Action): void {
|
|
954
973
|
// Don't handle clicks on the remove button, drag handle, or when action is in removing state
|
|
955
974
|
const target = event.target as HTMLElement;
|
|
@@ -1003,10 +1022,18 @@ export class CanvasNode extends RapidElement {
|
|
|
1003
1022
|
// Only fire the action edit event if we haven't dragged beyond the threshold
|
|
1004
1023
|
// AND either there's no Editor parent (test case) or the Editor didn't drag the node
|
|
1005
1024
|
if (distance <= DRAG_THRESHOLD && (!editor || !editorWasDragging)) {
|
|
1025
|
+
// Use top-center of the action element as the dialog origin
|
|
1026
|
+
const actionEl = event.currentTarget as Element;
|
|
1027
|
+
const origin = actionEl
|
|
1028
|
+
? this.getTopCenter(actionEl)
|
|
1029
|
+
: { x: event.clientX, y: event.clientY };
|
|
1030
|
+
|
|
1006
1031
|
// Fire event to request action editing
|
|
1007
1032
|
this.fireCustomEvent(CustomEventType.ActionEditRequested, {
|
|
1008
1033
|
action,
|
|
1009
|
-
nodeUuid: this.node.uuid
|
|
1034
|
+
nodeUuid: this.node.uuid,
|
|
1035
|
+
originX: origin.x,
|
|
1036
|
+
originY: origin.y
|
|
1010
1037
|
});
|
|
1011
1038
|
}
|
|
1012
1039
|
}
|
|
@@ -1126,17 +1153,24 @@ export class CanvasNode extends RapidElement {
|
|
|
1126
1153
|
// Using literal 5 instead of DRAG_THRESHOLD since it's not imported
|
|
1127
1154
|
// Fire event to request node editing if the node has a router
|
|
1128
1155
|
if (this.node.router) {
|
|
1156
|
+
// Use top-center of the node as the dialog origin
|
|
1157
|
+
const origin = this.getTopCenter(this);
|
|
1158
|
+
|
|
1129
1159
|
// If router node has exactly one action, open the action editor directly
|
|
1130
1160
|
if (this.node.actions && this.node.actions.length === 1) {
|
|
1131
1161
|
this.fireCustomEvent(CustomEventType.ActionEditRequested, {
|
|
1132
1162
|
action: this.node.actions[0],
|
|
1133
|
-
nodeUuid: this.node.uuid
|
|
1163
|
+
nodeUuid: this.node.uuid,
|
|
1164
|
+
originX: origin.x,
|
|
1165
|
+
originY: origin.y
|
|
1134
1166
|
});
|
|
1135
1167
|
} else {
|
|
1136
1168
|
// Otherwise open the node editor as before
|
|
1137
1169
|
this.fireCustomEvent(CustomEventType.NodeEditRequested, {
|
|
1138
1170
|
node: this.node,
|
|
1139
|
-
nodeUI: this.ui
|
|
1171
|
+
nodeUI: this.ui,
|
|
1172
|
+
originX: origin.x,
|
|
1173
|
+
originY: origin.y
|
|
1140
1174
|
});
|
|
1141
1175
|
}
|
|
1142
1176
|
}
|
|
@@ -1311,13 +1345,11 @@ export class CanvasNode extends RapidElement {
|
|
|
1311
1345
|
const color = config.group
|
|
1312
1346
|
? ACTION_GROUP_METADATA[config.group]?.color
|
|
1313
1347
|
: '#aaaaaa';
|
|
1348
|
+
const isTerminal = this.ui?.type === 'terminal';
|
|
1314
1349
|
return html`<div class="cn-title" style="background:${color}">
|
|
1315
|
-
${
|
|
1316
|
-
? html`<
|
|
1317
|
-
|
|
1318
|
-
name="sort"
|
|
1319
|
-
></temba-icon>`
|
|
1320
|
-
: this.node?.actions?.length > 1
|
|
1350
|
+
${isTerminal
|
|
1351
|
+
? html`<div class="title-spacer"></div>`
|
|
1352
|
+
: this.ui?.type === 'execute_actions' || this.node?.actions?.length > 1
|
|
1321
1353
|
? html`<temba-icon
|
|
1322
1354
|
class="drag-handle ${this.isReadOnly() ? 'read-only-hidden' : ''}"
|
|
1323
1355
|
name="sort"
|
|
@@ -1326,7 +1358,9 @@ export class CanvasNode extends RapidElement {
|
|
|
1326
1358
|
|
|
1327
1359
|
<div class="name">${isRemoving ? 'Remove?' : config.name}</div>
|
|
1328
1360
|
<div
|
|
1329
|
-
class="remove-button ${this.isReadOnly()
|
|
1361
|
+
class="remove-button ${isTerminal || this.isReadOnly()
|
|
1362
|
+
? 'read-only-hidden'
|
|
1363
|
+
: ''}"
|
|
1330
1364
|
@click=${(e: MouseEvent) =>
|
|
1331
1365
|
this.handleActionRemoveClick(e, action, index)}
|
|
1332
1366
|
title="Remove action"
|
|
@@ -1439,6 +1473,7 @@ export class CanvasNode extends RapidElement {
|
|
|
1439
1473
|
const displayAction = this.getLocalizedAction(action);
|
|
1440
1474
|
|
|
1441
1475
|
if (config) {
|
|
1476
|
+
const hasIssues = this.issuesByAction?.has(action.uuid);
|
|
1442
1477
|
const classes = [
|
|
1443
1478
|
'action',
|
|
1444
1479
|
'sortable',
|
|
@@ -1453,7 +1488,7 @@ export class CanvasNode extends RapidElement {
|
|
|
1453
1488
|
|
|
1454
1489
|
return html`<div class="${classes}" id="action-${index}">
|
|
1455
1490
|
<div
|
|
1456
|
-
class="action-content"
|
|
1491
|
+
class="action-content ${hasIssues ? 'has-issues' : ''}"
|
|
1457
1492
|
@mousedown=${(e: MouseEvent) =>
|
|
1458
1493
|
!isDisabled && this.handleActionMouseDown(e, action)}
|
|
1459
1494
|
@mouseup=${(e: MouseEvent) =>
|
|
@@ -1629,13 +1664,19 @@ export class CanvasNode extends RapidElement {
|
|
|
1629
1664
|
const activeCount =
|
|
1630
1665
|
(this.activity?.nodes && this.activity.nodes[this.node.uuid]) || 0;
|
|
1631
1666
|
|
|
1667
|
+
// Check for node-level issues or action-level issues on any action in this node
|
|
1668
|
+
const nodeHasIssues =
|
|
1669
|
+
this.issuesByNode?.has(this.node.uuid) ||
|
|
1670
|
+
this.node.actions?.some((a) => this.issuesByAction?.has(a.uuid));
|
|
1671
|
+
|
|
1632
1672
|
return html`
|
|
1633
1673
|
<div
|
|
1634
1674
|
id="${this.node.uuid}"
|
|
1635
1675
|
class=${getClasses({
|
|
1636
1676
|
node: true,
|
|
1637
1677
|
'execute-actions': this.ui.type === 'execute_actions',
|
|
1638
|
-
'non-localizable': isNodeDisabled
|
|
1678
|
+
'non-localizable': isNodeDisabled,
|
|
1679
|
+
'has-issues': nodeHasIssues
|
|
1639
1680
|
})}
|
|
1640
1681
|
style="left:${this.ui.position.left}px;top:${this.ui.position.top}px"
|
|
1641
1682
|
>
|
|
@@ -1644,7 +1685,9 @@ export class CanvasNode extends RapidElement {
|
|
|
1644
1685
|
${activeCount.toLocaleString()}
|
|
1645
1686
|
</div>`
|
|
1646
1687
|
: ''}
|
|
1647
|
-
${nodeConfig &&
|
|
1688
|
+
${nodeConfig &&
|
|
1689
|
+
nodeConfig.type !== 'execute_actions' &&
|
|
1690
|
+
nodeConfig.type !== 'terminal'
|
|
1648
1691
|
? html`<div class="router" style="position: relative;">
|
|
1649
1692
|
<div
|
|
1650
1693
|
@mousedown=${(e: MouseEvent) => this.handleNodeMouseDown(e)}
|
|
@@ -1662,7 +1705,7 @@ export class CanvasNode extends RapidElement {
|
|
|
1662
1705
|
: null}
|
|
1663
1706
|
</div>
|
|
1664
1707
|
</div>`
|
|
1665
|
-
: this.node.actions
|
|
1708
|
+
: this.node.actions?.length > 0
|
|
1666
1709
|
? this.ui.type === 'execute_actions'
|
|
1667
1710
|
? html`<temba-sortable-list
|
|
1668
1711
|
dragHandle="drag-handle"
|
|
@@ -1692,6 +1735,8 @@ export class CanvasNode extends RapidElement {
|
|
|
1692
1735
|
${this.renderRouter(this.node.router, this.ui)}
|
|
1693
1736
|
${this.renderCategories(this.node)}
|
|
1694
1737
|
</div>`
|
|
1738
|
+
: this.ui.type === 'terminal'
|
|
1739
|
+
? ''
|
|
1695
1740
|
: html`<div class="action-exits">
|
|
1696
1741
|
${repeat(
|
|
1697
1742
|
this.node.exits,
|