@nyaruka/temba-components 0.136.1 → 0.138.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/demo/components/webchat/example.html +2 -2
- package/dist/temba-components.js +692 -622
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/display/Chat.js +123 -44
- package/out-tsc/src/display/Chat.js.map +1 -1
- package/out-tsc/src/display/FloatingTab.js +2 -2
- package/out-tsc/src/display/FloatingTab.js.map +1 -1
- package/out-tsc/src/events/eventRenderers.js +442 -0
- package/out-tsc/src/events/eventRenderers.js.map +1 -0
- package/out-tsc/src/flow/CanvasNode.js +45 -24
- package/out-tsc/src/flow/CanvasNode.js.map +1 -1
- package/out-tsc/src/flow/Editor.js +308 -18
- package/out-tsc/src/flow/Editor.js.map +1 -1
- package/out-tsc/src/flow/NodeEditor.js +0 -1
- package/out-tsc/src/flow/NodeEditor.js.map +1 -1
- package/out-tsc/src/flow/Plumber.js +110 -64
- package/out-tsc/src/flow/Plumber.js.map +1 -1
- package/out-tsc/src/list/ShortcutList.js +1 -1
- package/out-tsc/src/list/ShortcutList.js.map +1 -1
- package/out-tsc/src/live/ContactChat.js +12 -321
- package/out-tsc/src/live/ContactChat.js.map +1 -1
- package/out-tsc/src/simulator/Simulator.js +439 -575
- package/out-tsc/src/simulator/Simulator.js.map +1 -1
- package/out-tsc/src/store/AppState.js +12 -2
- package/out-tsc/src/store/AppState.js.map +1 -1
- package/out-tsc/test/temba-flow-editor-node.test.js +2 -1
- package/out-tsc/test/temba-flow-editor-node.test.js.map +1 -1
- package/out-tsc/test/temba-flow-editor-revisions.test.js +106 -0
- package/out-tsc/test/temba-flow-editor-revisions.test.js.map +1 -0
- package/out-tsc/test/temba-flow-editor.test.js +14 -10
- package/out-tsc/test/temba-flow-editor.test.js.map +1 -1
- package/out-tsc/test/temba-flow-plumber-connections.test.js +7 -1
- package/out-tsc/test/temba-flow-plumber-connections.test.js.map +1 -1
- package/out-tsc/test/temba-flow-plumber.test.js +6 -0
- package/out-tsc/test/temba-flow-plumber.test.js.map +1 -1
- package/out-tsc/test/temba-simulator.test.js +51 -32
- package/out-tsc/test/temba-simulator.test.js.map +1 -1
- package/package.json +1 -1
- 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/nodes/split_by_llm_categorize/editor/feedback-categorization.png +0 -0
- 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/display/Chat.ts +123 -44
- package/src/display/FloatingTab.ts +2 -2
- package/src/events/eventRenderers.ts +527 -0
- package/src/flow/CanvasNode.ts +54 -29
- package/src/flow/Editor.ts +360 -19
- package/src/flow/NodeEditor.ts +0 -1
- package/src/flow/Plumber.ts +123 -69
- package/src/list/ShortcutList.ts +1 -1
- package/src/live/ContactChat.ts +17 -376
- package/src/simulator/Simulator.ts +498 -617
- package/src/store/AppState.ts +13 -2
- package/test/temba-flow-editor-node.test.ts +2 -1
- package/test/temba-flow-editor-revisions.test.ts +134 -0
- package/test/temba-flow-editor.test.ts +16 -10
- package/test/temba-flow-plumber-connections.test.ts +7 -1
- package/test/temba-flow-plumber.test.ts +6 -0
- package/test/temba-simulator.test.ts +64 -34
package/src/display/Chat.ts
CHANGED
|
@@ -219,7 +219,13 @@ export class Chat extends RapidElement {
|
|
|
219
219
|
display: flex;
|
|
220
220
|
flex-direction: row;
|
|
221
221
|
align-items: flex-start;
|
|
222
|
-
margin-bottom:
|
|
222
|
+
margin-bottom: 8px;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.row.is-event {
|
|
226
|
+
margin-bottom: 2px;
|
|
227
|
+
margin-left: 0px !important;
|
|
228
|
+
margin-right: 4px !important;
|
|
223
229
|
}
|
|
224
230
|
|
|
225
231
|
.input-panel {
|
|
@@ -263,10 +269,9 @@ export class Chat extends RapidElement {
|
|
|
263
269
|
}
|
|
264
270
|
|
|
265
271
|
.bubble {
|
|
266
|
-
padding:
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
border-radius: var(--curvature);
|
|
272
|
+
padding: 10px 14px;
|
|
273
|
+
background: var(--color-chat-in, #e5e5ea);
|
|
274
|
+
border-radius: 18px;
|
|
270
275
|
border: var(--chat-border-in, none);
|
|
271
276
|
}
|
|
272
277
|
|
|
@@ -278,7 +283,7 @@ export class Chat extends RapidElement {
|
|
|
278
283
|
}
|
|
279
284
|
|
|
280
285
|
.outgoing .latest .bubble {
|
|
281
|
-
border-bottom-left-radius:
|
|
286
|
+
border-bottom-left-radius: 4px;
|
|
282
287
|
}
|
|
283
288
|
|
|
284
289
|
.incoming .bubble-wrap {
|
|
@@ -286,13 +291,13 @@ export class Chat extends RapidElement {
|
|
|
286
291
|
}
|
|
287
292
|
|
|
288
293
|
.incoming .bubble {
|
|
289
|
-
background: var(--color-chat-out, #
|
|
294
|
+
background: var(--color-chat-out, #007aff);
|
|
290
295
|
border: var(--chat-border-out, none);
|
|
291
296
|
color: white;
|
|
292
297
|
}
|
|
293
298
|
|
|
294
299
|
.incoming .latest .bubble {
|
|
295
|
-
border-bottom-right-radius:
|
|
300
|
+
border-bottom-right-radius: 4px;
|
|
296
301
|
}
|
|
297
302
|
|
|
298
303
|
.incoming .bubble .name {
|
|
@@ -308,16 +313,26 @@ export class Chat extends RapidElement {
|
|
|
308
313
|
color: rgba(0, 0, 0, 0.5);
|
|
309
314
|
}
|
|
310
315
|
|
|
316
|
+
.warning .bubble {
|
|
317
|
+
background: #fef3c7;
|
|
318
|
+
color: rgba(125, 87, 18, 0.8);
|
|
319
|
+
border: none;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.warning .bubble .name {
|
|
323
|
+
color: rgba(125, 87, 18, 0.6);
|
|
324
|
+
}
|
|
325
|
+
|
|
311
326
|
.failed .bubble,
|
|
312
327
|
.error .bubble {
|
|
313
|
-
border:
|
|
314
|
-
background: #
|
|
315
|
-
color: #
|
|
328
|
+
border: none;
|
|
329
|
+
background: #fee3e3;
|
|
330
|
+
color: #c01829;
|
|
316
331
|
}
|
|
317
332
|
|
|
318
333
|
.error .bubble .name,
|
|
319
334
|
.failed .bubble .name {
|
|
320
|
-
color:
|
|
335
|
+
color: rgba(192, 24, 41, 0.6);
|
|
321
336
|
}
|
|
322
337
|
|
|
323
338
|
.deleted .bubble {
|
|
@@ -332,15 +347,48 @@ export class Chat extends RapidElement {
|
|
|
332
347
|
|
|
333
348
|
.message-text {
|
|
334
349
|
white-space: pre-wrap;
|
|
335
|
-
margin-bottom: 0
|
|
336
|
-
line-height: 1.
|
|
350
|
+
margin-bottom: 0;
|
|
351
|
+
line-height: 1.2;
|
|
337
352
|
word-break: break-word;
|
|
353
|
+
font-size: 13px;
|
|
338
354
|
}
|
|
339
355
|
|
|
340
356
|
.message-deleted {
|
|
341
357
|
font-style: italic;
|
|
342
|
-
margin-bottom: 0
|
|
343
|
-
line-height: 1.
|
|
358
|
+
margin-bottom: 0;
|
|
359
|
+
line-height: 1.2;
|
|
360
|
+
font-size: 13px;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
.quick-replies {
|
|
364
|
+
display: flex;
|
|
365
|
+
flex-wrap: wrap;
|
|
366
|
+
justify-content: center;
|
|
367
|
+
gap: 6px;
|
|
368
|
+
padding: 8px 0;
|
|
369
|
+
margin: 0 auto;
|
|
370
|
+
max-width: 90%;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.quick-reply-btn {
|
|
374
|
+
padding: 4px 8px;
|
|
375
|
+
border-radius: 18px;
|
|
376
|
+
border: 1px solid var(--color-chat-out, #007aff);
|
|
377
|
+
background: white;
|
|
378
|
+
color: var(--color-chat-out, #007aff);
|
|
379
|
+
font-size: 11px;
|
|
380
|
+
cursor: pointer;
|
|
381
|
+
transition: all 0.2s ease;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
.quick-reply-btn:hover:not(:disabled) {
|
|
385
|
+
background: var(--color-chat-out, #007aff);
|
|
386
|
+
color: white;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.quick-reply-btn:disabled {
|
|
390
|
+
opacity: 0.5;
|
|
391
|
+
cursor: not-allowed;
|
|
344
392
|
}
|
|
345
393
|
|
|
346
394
|
.chat {
|
|
@@ -381,12 +429,21 @@ export class Chat extends RapidElement {
|
|
|
381
429
|
overflow-x: hidden;
|
|
382
430
|
-webkit-overflow-scrolling: touch;
|
|
383
431
|
overflow-scrolling: touch;
|
|
384
|
-
padding:
|
|
385
|
-
|
|
432
|
+
padding: var(--chat-top-padding, 1em) 1em
|
|
433
|
+
var(--chat-bottom-padding, 2.5em) 1em;
|
|
386
434
|
display: flex;
|
|
387
435
|
flex-direction: column-reverse;
|
|
388
436
|
}
|
|
389
437
|
|
|
438
|
+
:host(.phone-screen) .scroll {
|
|
439
|
+
scrollbar-width: none;
|
|
440
|
+
-ms-overflow-style: none;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
:host(.phone-screen) .scroll::-webkit-scrollbar {
|
|
444
|
+
display: none;
|
|
445
|
+
}
|
|
446
|
+
|
|
390
447
|
.messages:before {
|
|
391
448
|
content: '';
|
|
392
449
|
background: radial-gradient(
|
|
@@ -520,6 +577,9 @@ export class Chat extends RapidElement {
|
|
|
520
577
|
display: flex;
|
|
521
578
|
flex-direction: column;
|
|
522
579
|
align-items: center;
|
|
580
|
+
text-align: center;
|
|
581
|
+
font-size: 11px;
|
|
582
|
+
color: #8e8e93;
|
|
523
583
|
}
|
|
524
584
|
|
|
525
585
|
.event p {
|
|
@@ -650,6 +710,9 @@ export class Chat extends RapidElement {
|
|
|
650
710
|
@property({ type: Boolean })
|
|
651
711
|
agent = false;
|
|
652
712
|
|
|
713
|
+
@property({ type: Boolean })
|
|
714
|
+
avatars = false;
|
|
715
|
+
|
|
653
716
|
@property({ type: Boolean, attribute: false })
|
|
654
717
|
endOfHistory = false;
|
|
655
718
|
|
|
@@ -665,6 +728,9 @@ export class Chat extends RapidElement {
|
|
|
665
728
|
@property({ type: Boolean })
|
|
666
729
|
hasFooter = false;
|
|
667
730
|
|
|
731
|
+
@property({ type: Boolean })
|
|
732
|
+
showTimestamps = true;
|
|
733
|
+
|
|
668
734
|
private msgMap = new Map<string, ContactEvent>();
|
|
669
735
|
private metadataCache = new Map<string, ContactEvent>();
|
|
670
736
|
|
|
@@ -890,7 +956,7 @@ export class Chat extends RapidElement {
|
|
|
890
956
|
}
|
|
891
957
|
}
|
|
892
958
|
|
|
893
|
-
|
|
959
|
+
public scrollToBottom() {
|
|
894
960
|
const scroll = this.shadowRoot.querySelector('.scroll');
|
|
895
961
|
if (scroll) {
|
|
896
962
|
scroll.scrollTop = 0;
|
|
@@ -934,10 +1000,11 @@ export class Chat extends RapidElement {
|
|
|
934
1000
|
const name = currentMsg._user?.name;
|
|
935
1001
|
|
|
936
1002
|
const showAvatar =
|
|
937
|
-
|
|
1003
|
+
this.avatars &&
|
|
1004
|
+
(((currentMsg.type === 'msg_received' ||
|
|
938
1005
|
currentMsg.type === 'msg_created') &&
|
|
939
1006
|
this.agent) ||
|
|
940
|
-
|
|
1007
|
+
!incoming);
|
|
941
1008
|
|
|
942
1009
|
const isSystem = !currentMsg._user?.uuid;
|
|
943
1010
|
|
|
@@ -1000,8 +1067,10 @@ export class Chat extends RapidElement {
|
|
|
1000
1067
|
(statusClass === 'failed' || statusClass === 'errored'));
|
|
1001
1068
|
const unsendableClass = hasError ? 'error' : '';
|
|
1002
1069
|
const deletedClass = msgEvent._deleted ? 'deleted' : '';
|
|
1070
|
+
const latestClass = index === msgIds.length - 1 ? 'latest' : '';
|
|
1071
|
+
const eventClass = msg._rendered ? 'is-event' : '';
|
|
1003
1072
|
return html`<div
|
|
1004
|
-
class="row message ${statusClass} ${unsendableClass} ${deletedClass}"
|
|
1073
|
+
class="row message ${statusClass} ${unsendableClass} ${deletedClass} ${latestClass} ${eventClass}"
|
|
1005
1074
|
>
|
|
1006
1075
|
${this.renderMessage(msg, index == 0 ? name : null)}
|
|
1007
1076
|
</div>`;
|
|
@@ -1035,6 +1104,12 @@ export class Chat extends RapidElement {
|
|
|
1035
1104
|
}
|
|
1036
1105
|
|
|
1037
1106
|
const message = event as MsgEvent;
|
|
1107
|
+
|
|
1108
|
+
// safety check: if msg doesn't exist, return nothing
|
|
1109
|
+
if (!message.msg) {
|
|
1110
|
+
return html``;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1038
1113
|
const unsendableReason = message.msg?.unsendable_reason;
|
|
1039
1114
|
const statusReason = message._status?.reason;
|
|
1040
1115
|
const errorMessage = unsendableReason
|
|
@@ -1069,28 +1144,32 @@ export class Chat extends RapidElement {
|
|
|
1069
1144
|
|
|
1070
1145
|
return html`
|
|
1071
1146
|
<div class="bubble-wrap">
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1147
|
+
${this.showTimestamps
|
|
1148
|
+
? html`<div class="popup" style="white-space: nowrap;">
|
|
1149
|
+
${errorMessage
|
|
1150
|
+
? html`<div
|
|
1151
|
+
style="color: var(--color-error); margin-right: 1em;"
|
|
1152
|
+
>
|
|
1153
|
+
${errorMessage}
|
|
1154
|
+
</div>`
|
|
1155
|
+
: null}
|
|
1156
|
+
<temba-date
|
|
1157
|
+
value="${message.created_on.toISOString()}"
|
|
1158
|
+
display="relative"
|
|
1159
|
+
></temba-date>
|
|
1160
|
+
${logsURL
|
|
1161
|
+
? html`<a
|
|
1162
|
+
style="margin-left: 1em; color: var(--color-primary-dark);"
|
|
1163
|
+
href="${logsURL}"
|
|
1164
|
+
target="_blank"
|
|
1165
|
+
rel="noopener noreferrer"
|
|
1166
|
+
><temba-icon name="log"></temba-icon
|
|
1167
|
+
></a>`
|
|
1168
|
+
: null}
|
|
1169
|
+
|
|
1170
|
+
<div class="arrow">▼</div>
|
|
1171
|
+
</div>`
|
|
1172
|
+
: null}
|
|
1094
1173
|
${isDeleted
|
|
1095
1174
|
? html`<div class="bubble">
|
|
1096
1175
|
${name ? html`<div class="name">${name}</div>` : null}
|
|
@@ -102,10 +102,10 @@ export class FloatingTab extends RapidElement {
|
|
|
102
102
|
// auto-calculate position based on index
|
|
103
103
|
const index = FloatingTab.allTabs.indexOf(this);
|
|
104
104
|
if (index === -1) {
|
|
105
|
-
this.top =
|
|
105
|
+
this.top = 150; // default fallback
|
|
106
106
|
} else {
|
|
107
107
|
// start at 100px and stack with 10px gap between tabs
|
|
108
|
-
this.top =
|
|
108
|
+
this.top = 150 + index * (FloatingTab.TAB_HEIGHT + 0);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
|