@nyaruka/temba-components 0.91.6 → 0.92.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/demo/index.html +1 -1
  3. package/dist/temba-components.js +760 -1189
  4. package/dist/temba-components.js.map +1 -1
  5. package/out-tsc/src/chat/Chat.js +714 -0
  6. package/out-tsc/src/chat/Chat.js.map +1 -0
  7. package/out-tsc/src/completion/helpers.js +1 -29
  8. package/out-tsc/src/completion/helpers.js.map +1 -1
  9. package/out-tsc/src/compose/Compose.js +6 -2
  10. package/out-tsc/src/compose/Compose.js.map +1 -1
  11. package/out-tsc/src/contacts/ContactChat.js +518 -54
  12. package/out-tsc/src/contacts/ContactChat.js.map +1 -1
  13. package/out-tsc/src/contacts/events.js +1 -998
  14. package/out-tsc/src/contacts/events.js.map +1 -1
  15. package/out-tsc/src/lightbox/Lightbox.js +4 -0
  16. package/out-tsc/src/lightbox/Lightbox.js.map +1 -1
  17. package/out-tsc/src/list/TembaMenu.js +0 -1
  18. package/out-tsc/src/list/TembaMenu.js.map +1 -1
  19. package/out-tsc/src/markdown.js +33 -0
  20. package/out-tsc/src/markdown.js.map +1 -0
  21. package/out-tsc/src/select/Select.js +6 -1
  22. package/out-tsc/src/select/Select.js.map +1 -1
  23. package/out-tsc/src/textinput/TextInput.js +1 -1
  24. package/out-tsc/src/textinput/TextInput.js.map +1 -1
  25. package/out-tsc/src/thumbnail/Thumbnail.js +128 -81
  26. package/out-tsc/src/thumbnail/Thumbnail.js.map +1 -1
  27. package/out-tsc/src/utils/index.js +9 -11
  28. package/out-tsc/src/utils/index.js.map +1 -1
  29. package/out-tsc/src/webchat/WebChat.js +109 -358
  30. package/out-tsc/src/webchat/WebChat.js.map +1 -1
  31. package/out-tsc/src/webchat/index.js +17 -0
  32. package/out-tsc/src/webchat/index.js.map +1 -1
  33. package/out-tsc/temba-modules.js +2 -2
  34. package/out-tsc/temba-modules.js.map +1 -1
  35. package/out-tsc/temba-webchat.js +2 -0
  36. package/out-tsc/temba-webchat.js.map +1 -1
  37. package/out-tsc/test/temba-contact-chat.test.js +1 -0
  38. package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
  39. package/out-tsc/test/temba-lightbox.test.js +4 -4
  40. package/out-tsc/test/temba-lightbox.test.js.map +1 -1
  41. package/package.json +1 -1
  42. package/screenshots/truth/contacts/compose-attachments-no-text-failure.png +0 -0
  43. package/screenshots/truth/contacts/compose-attachments-no-text-success.png +0 -0
  44. package/screenshots/truth/contacts/compose-text-and-attachments-failure-attachments.png +0 -0
  45. package/screenshots/truth/contacts/compose-text-and-attachments-failure-generic.png +0 -0
  46. package/screenshots/truth/contacts/compose-text-and-attachments-failure-text-and-attachments.png +0 -0
  47. package/screenshots/truth/contacts/compose-text-and-attachments-failure-text.png +0 -0
  48. package/screenshots/truth/contacts/compose-text-and-attachments-success.png +0 -0
  49. package/screenshots/truth/contacts/compose-text-no-attachments-failure.png +0 -0
  50. package/screenshots/truth/contacts/compose-text-no-attachments-success.png +0 -0
  51. package/screenshots/truth/contacts/contact-active-default.png +0 -0
  52. package/screenshots/truth/contacts/contact-active-show-chatbox.png +0 -0
  53. package/screenshots/truth/contacts/contact-archived-hide-chatbox.png +0 -0
  54. package/screenshots/truth/contacts/contact-blocked-hide-chatbox.png +0 -0
  55. package/screenshots/truth/contacts/contact-stopped-hide-chatbox.png +0 -0
  56. package/screenshots/truth/lightbox/img-zoomed.png +0 -0
  57. package/screenshots/truth/lightbox/img.png +0 -0
  58. package/src/chat/Chat.ts +791 -0
  59. package/src/completion/helpers.ts +2 -40
  60. package/src/compose/Compose.ts +6 -2
  61. package/src/contacts/ContactChat.ts +609 -59
  62. package/src/contacts/events.ts +1 -1068
  63. package/src/lightbox/Lightbox.ts +5 -0
  64. package/src/list/TembaMenu.ts +0 -1
  65. package/src/markdown.ts +41 -0
  66. package/src/select/Select.ts +5 -1
  67. package/src/textinput/TextInput.ts +1 -1
  68. package/src/thumbnail/Thumbnail.ts +130 -81
  69. package/src/utils/index.ts +12 -13
  70. package/src/webchat/WebChat.ts +196 -413
  71. package/src/webchat/index.ts +23 -1
  72. package/static/css/temba-components.css +2 -0
  73. package/temba-modules.ts +2 -2
  74. package/temba-webchat.ts +2 -0
  75. package/test/temba-contact-chat.test.ts +1 -0
  76. package/test/temba-lightbox.test.ts +4 -4
  77. package/test-assets/contacts/history.json +1 -56
  78. package/out-tsc/src/contacts/ContactHistory.js +0 -691
  79. package/out-tsc/src/contacts/ContactHistory.js.map +0 -1
  80. package/out-tsc/test/temba-contact-history.test.js +0 -69
  81. package/out-tsc/test/temba-contact-history.test.js.map +0 -1
  82. package/src/contacts/ContactHistory.ts +0 -875
  83. package/test/temba-contact-history.test.ts +0 -107
@@ -1,543 +1,5 @@
1
- import { css, html } from 'lit';
2
- import { getClasses, oxford, oxfordFn, oxfordNamed } from '../utils';
1
+ import { html } from 'lit';
3
2
  import { Icon } from '../vectoricon';
4
- import { getDisplayName } from './helpers';
5
- export const getEventStyles = () => {
6
- return css `
7
- .grouping {
8
- margin-top: 1em;
9
- }
10
-
11
- .grouping.verbose {
12
- background: #f9f9f9;
13
- color: var(--color-dark);
14
- --color-link-primary: rgba(38, 166, 230, 1);
15
- pointer-events: none;
16
- background: #fefefe;
17
- box-shadow: -8px 0px 8px 1px rgba(0, 0, 0, 0.05) inset;
18
- margin-right: -16px;
19
- padding-right: 16px;
20
- margin-bottom: 1.3em;
21
- max-width: 100%;
22
- }
23
-
24
- .grouping .items {
25
- display: block;
26
- }
27
-
28
- .grouping.verbose .items {
29
- opacity: 0;
30
- max-height: 0;
31
- display: flex;
32
- flex-direction: column;
33
- user-select: auto;
34
- }
35
-
36
- .grouping.flows .items {
37
- padding: 0;
38
- }
39
-
40
- .grouping.messages .items {
41
- display: flex;
42
- flex-direction: column;
43
- margin: 0em 0.75em;
44
- }
45
-
46
- .grouping.verbose.expanded .items {
47
- transition: max-height var(--transition-speed) ease-in-out,
48
- opacity var(--transition-speed) ease-in-out;
49
- opacity: 1;
50
- max-height: 1000px;
51
- padding: 1em 1em;
52
- }
53
-
54
- .grouping.verbose.expanded {
55
- border-top: 1px solid #f3f3f3;
56
- border-bottom: 1px solid #f3f3f3;
57
- }
58
-
59
- .grouping.verbose.expanded,
60
- .grouping.verbose .event-count {
61
- pointer-events: auto;
62
- }
63
-
64
- .grouping.verbose temba-icon {
65
- }
66
-
67
- .grouping.verbose > .event,
68
- .grouping.verbose > pre {
69
- max-height: 0px;
70
- padding-top: 0;
71
- padding-bottom: 0;
72
- margin-top: 0;
73
- margin-bottom: 0;
74
- opacity: 0;
75
- }
76
-
77
- .grouping.verbose .attn {
78
- color: #666;
79
- }
80
-
81
- .event-count {
82
- position: relative;
83
- font-size: 0.8em;
84
- text-align: center;
85
- margin: 0 auto;
86
- display: table;
87
- padding: 3px 10px;
88
- font-weight: 400;
89
- color: #999;
90
- cursor: pointer;
91
- width: 100%;
92
- opacity: 1;
93
- }
94
-
95
- .event-count temba-icon {
96
- display: inline-block;
97
- position: absolute;
98
- right: 5px;
99
- top: 5px;
100
- }
101
-
102
- .event-count:hover {
103
- color: var(--color-link-primary-hover);
104
- }
105
-
106
- .expanded .event-count {
107
- padding: 0;
108
- pointer-events: none;
109
- }
110
-
111
- .grouping.flows {
112
- margin-left: 1em;
113
- margin-right: 1em;
114
- margin-bottom: 1.5em;
115
-
116
- border: 1px solid #f2f2f2;
117
- border-radius: var(--curvature);
118
- padding: 0.5em 1em;
119
- }
120
-
121
- .grouping.flows .event {
122
- margin: 0;
123
- padding: 0;
124
- }
125
-
126
- .grouping.tickets {
127
- margin-bottom: 2em;
128
- }
129
-
130
- pre {
131
- white-space: pre-wrap;
132
- word-wrap: break-word;
133
- }
134
-
135
- .grouping.verbose.expanded .event,
136
- .grouping.verbose.expanded pre {
137
- max-height: 500px;
138
- opacity: 1;
139
- }
140
-
141
- .grouping-close-button {
142
- position: relative;
143
- display: inline-block;
144
- opacity: 0;
145
- float: right;
146
- --icon-color: #666;
147
- }
148
-
149
- .grouping.verbose.expanded:hover .grouping-close-button {
150
- opacity: 1;
151
- }
152
-
153
- .grouping.messages,
154
- .grouping.tickets {
155
- display: flex;
156
- flex-direction: column;
157
- }
158
-
159
- .event {
160
- margin: 0.25em 0.5em;
161
- border-radius: var(--curvature);
162
- flex-grow: 1;
163
- }
164
-
165
- .msg {
166
- border-radius: calc(var(--curvature) * 2.5);
167
- border: 2px solid rgba(100, 100, 100, 0.1);
168
- max-width: 300px;
169
- word-break: break-word;
170
- overflow: hidden;
171
- }
172
-
173
- .msg.attachments-1.no-message {
174
- border: 2px solid transparent;
175
- background-color: transparent !important;
176
- }
177
-
178
- .msg .text {
179
- padding: var(--event-padding);
180
- }
181
-
182
- .event.msg_received .msg {
183
- background: rgba(200, 200, 200, 0.1);
184
- }
185
-
186
- .event.msg_created,
187
- .event.broadcast_created,
188
- .event.ivr_created,
189
- .event.ticket_note_added {
190
- align-self: flex-end;
191
- }
192
-
193
- .event.msg_created .msg,
194
- .event.broadcast_created .msg,
195
- .event.ivr_created .msg {
196
- background: var(--color-primary-dark);
197
- color: white;
198
- font-weight: 400;
199
- }
200
-
201
- .msg.automated {
202
- background: var(--color-automated) !important;
203
- }
204
-
205
- .queued {
206
- opacity: 0.3;
207
- }
208
-
209
- .optin_requested {
210
- --icon-color: var(--color-primary-dark);
211
- }
212
-
213
- .webhook_called {
214
- --icon-color: #e68628;
215
- word-break: break-all;
216
- }
217
-
218
- .webhook_called .failed {
219
- --icon-color: var(--color-error);
220
- color: var(--color-error);
221
- }
222
-
223
- .input_labels_added,
224
- .contact_name_changed,
225
- .contact_field_changed,
226
- .contact_urns_changed,
227
- .contact_language_changed,
228
- .run_result_changed {
229
- --icon-color: rgba(1, 193, 175, 1);
230
- }
231
-
232
- .email_sent {
233
- --icon-color: #8e5ea7;
234
- }
235
-
236
- .contact_groups_changed .added {
237
- --icon-color: #309c42;
238
- }
239
- .contact_groups_changed .removed {
240
- --icon-color: var(--color-error);
241
- }
242
-
243
- .event.error .description,
244
- .event.failure .description {
245
- color: var(--color-error);
246
- }
247
-
248
- .description.error {
249
- color: var(--color-error);
250
- }
251
-
252
- .info {
253
- border: 1px solid rgba(100, 100, 100, 0.2);
254
- background: rgba(10, 10, 10, 0.02);
255
- }
256
-
257
- .ticket_note_added {
258
- max-width: 300px;
259
- }
260
-
261
- .note-summary {
262
- display: flex;
263
- flex-direction: row;
264
- font-size: 85%;
265
- margin-top: -0.5em;
266
- color: rgba(0, 0, 0, 0.6);
267
- padding: 8px 3px;
268
- }
269
-
270
- .ticket_note_added .description {
271
- border: 2px solid rgba(100, 100, 100, 0.1);
272
- background: rgb(255, 249, 194);
273
- padding: var(--event-padding);
274
- font-weight: 400;
275
- color: rgba(0, 0, 0, 0.6);
276
- border-radius: calc(var(--curvature) * 2.5);
277
- }
278
-
279
- .channel_event {
280
- --icon-color: rgb(200, 200, 200);
281
- }
282
-
283
- .airtime_transferred,
284
- .flow_exited,
285
- .flow_entered,
286
- .ticket_opened,
287
- .ticket_reopened,
288
- .ticket_closed,
289
- .call_started,
290
- .campaign_fired {
291
- --icon-color: rgba(223, 65, 159, 1);
292
- }
293
-
294
- .active-ticket.ticket_opened {
295
- padding: 0em 1em;
296
- }
297
-
298
- .ticket_closed .inactive .subtext {
299
- display: none;
300
- }
301
-
302
- .attn {
303
- color: var(--color-text);
304
- }
305
-
306
- .flow_exited,
307
- .flow_entered {
308
- align-self: center;
309
- max-width: 80%;
310
- display: flex;
311
- flex-direction: row;
312
- }
313
-
314
- .flow_exited temba-icon,
315
- .flow_entered temba-icon {
316
- }
317
-
318
- .event {
319
- display: flex;
320
- align-items: center;
321
- }
322
-
323
- .event .description {
324
- flex-grow: 1;
325
- }
326
-
327
- .msg-summary {
328
- display: flex;
329
- font-size: 85%;
330
- color: rgba(0, 0, 0, 0.6);
331
- padding: 6px 3px;
332
- margin-bottom: 0.5em;
333
- margin-top: -0.5em;
334
- }
335
-
336
- .msg-summary temba-icon.log {
337
- --icon-color: rgba(0, 0, 0, 0.2);
338
- }
339
-
340
- .msg-summary temba-icon.log:hover {
341
- --icon-color: var(--color-link-primary-hover);
342
- cursor: pointer;
343
- }
344
-
345
- .msg-summary temba-icon.error {
346
- --icon-color: rgba(var(--error-rgb), 0.75);
347
- }
348
-
349
- .msg-summary temba-icon.error:hover {
350
- --icon-color: var(--color-error);
351
- cursor: pointer;
352
- }
353
-
354
- .msg-summary temba-icon.broadcast {
355
- --icon-color: rgba(90, 90, 90, 0.5);
356
- }
357
-
358
- .msg-summary * {
359
- display: flex;
360
- margin-right: 1px;
361
- margin-left: 1px;
362
- }
363
-
364
- .unsupported {
365
- border: 1px solid #f2f2f2;
366
- color: #999;
367
- padding: 0.5em 1em;
368
- border-radius: var(--curvature);
369
- }
370
-
371
- .optin {
372
- align-items: center;
373
- padding: 0 0.2em;
374
- }
375
-
376
- .time {
377
- padding: 0.3em 1px;
378
- }
379
-
380
- .subtext .time {
381
- padding: 0em;
382
- }
383
-
384
- .status {
385
- padding: 0.3em 3px;
386
- }
387
-
388
- .separator {
389
- padding: 0.3em 0px;
390
- }
391
-
392
- .recipients {
393
- padding: 0.3em 3px;
394
- }
395
-
396
- .verbose temba-icon,
397
- .flows temba-icon,
398
- .tickets temba-icon {
399
- margin-right: 0.75em;
400
- }
401
-
402
- .attn {
403
- display: inline-block;
404
- font-weight: 500;
405
- margin: 0px 2px;
406
- word-break: break-all;
407
- white-space: break-spaces;
408
- }
409
-
410
- .subtext {
411
- font-size: 80%;
412
- }
413
-
414
- .body-pre {
415
- white-space: pre-wrap;
416
- word-wrap: break-word;
417
- font-size: 90%;
418
- }
419
-
420
- a,
421
- .linked {
422
- color: var(--color-link-primary);
423
- cursor: pointer;
424
- }
425
-
426
- a:hover,
427
- .linked:hover {
428
- text-decoration: underline;
429
- color: var(--color-link-primary-hover);
430
- }
431
-
432
- temba-icon.error {
433
- --icon-color: var(--color-error);
434
- }
435
-
436
- .delivery-error {
437
- --icon-color: var(--color-error);
438
- margin-right: 0.25em;
439
- }
440
-
441
- .flow {
442
- --icon-color: #ddd;
443
- background: #fff;
444
- width: 18px;
445
- height: 18px;
446
- padding-top: 4px;
447
- padding-left: 9px;
448
- border: 0px solid #f3f3f3;
449
- }
450
-
451
- .assigned {
452
- color: #777;
453
- max-width: 300px;
454
- margin-left: auto;
455
- margin-right: auto;
456
- display: flex;
457
- flex-direction: column;
458
- align-items: center;
459
- margin-bottom: 10px;
460
- }
461
-
462
- .assigned .attn {
463
- color: #777;
464
- }
465
-
466
- .attachments {
467
- display: flex;
468
- flex-wrap: wrap;
469
- margin: -0.2em;
470
- }
471
-
472
- .attachment {
473
- flex: 1 0 45%;
474
- border-top: 0.05em solid transparent;
475
- border-left: 0.05em solid transparent;
476
- margin-top: 0.05em;
477
- margin-left: 0.05em;
478
- }
479
- `;
480
- };
481
- export var Events;
482
- (function (Events) {
483
- Events["MESSAGE_CREATED"] = "msg_created";
484
- Events["MESSAGE_RECEIVED"] = "msg_received";
485
- Events["BROADCAST_CREATED"] = "broadcast_created";
486
- Events["IVR_CREATED"] = "ivr_created";
487
- Events["FLOW_ENTERED"] = "flow_entered";
488
- Events["FLOW_EXITED"] = "flow_exited";
489
- Events["RUN_RESULT_CHANGED"] = "run_result_changed";
490
- Events["CONTACT_FIELD_CHANGED"] = "contact_field_changed";
491
- Events["CONTACT_GROUPS_CHANGED"] = "contact_groups_changed";
492
- Events["CONTACT_NAME_CHANGED"] = "contact_name_changed";
493
- Events["CONTACT_URNS_CHANGED"] = "contact_urns_changed";
494
- Events["CAMPAIGN_FIRED"] = "campaign_fired";
495
- Events["CHANNEL_EVENT"] = "channel_event";
496
- Events["CONTACT_LANGUAGE_CHANGED"] = "contact_language_changed";
497
- Events["WEBHOOK_CALLED"] = "webhook_called";
498
- Events["AIRTIME_TRANSFERRED"] = "airtime_transferred";
499
- Events["CALL_STARTED"] = "call_started";
500
- Events["EMAIL_SENT"] = "email_sent";
501
- Events["INPUT_LABELS_ADDED"] = "input_labels_added";
502
- Events["NOTE_CREATED"] = "note_created";
503
- Events["TICKET_ASSIGNED"] = "ticket_assigned";
504
- Events["TICKET_NOTE_ADDED"] = "ticket_note_added";
505
- Events["TICKET_CLOSED"] = "ticket_closed";
506
- Events["TICKET_OPENED"] = "ticket_opened";
507
- Events["TICKET_REOPENED"] = "ticket_reopened";
508
- Events["OPTIN_REQUESTED"] = "optin_requested";
509
- Events["ERROR"] = "error";
510
- Events["FAILURE"] = "failure";
511
- })(Events || (Events = {}));
512
- export const getEventGroupType = (event, ticket) => {
513
- if (!event) {
514
- return 'messages';
515
- }
516
- switch (event.type) {
517
- case Events.TICKET_ASSIGNED:
518
- case Events.TICKET_OPENED:
519
- case Events.TICKET_CLOSED:
520
- case Events.TICKET_REOPENED:
521
- if (!ticket) {
522
- return 'verbose';
523
- }
524
- if (event.ticket.uuid === ticket) {
525
- return 'tickets';
526
- }
527
- break;
528
- case Events.FLOW_ENTERED:
529
- case Events.FLOW_EXITED:
530
- return 'flows';
531
- case Events.BROADCAST_CREATED:
532
- case Events.MESSAGE_CREATED:
533
- case Events.MESSAGE_RECEIVED:
534
- case Events.IVR_CREATED:
535
- case Events.TICKET_NOTE_ADDED:
536
- case Events.NOTE_CREATED:
537
- return 'messages';
538
- }
539
- return 'verbose';
540
- };
541
3
  export const renderAttachment = (attachment) => {
542
4
  const idx = attachment.indexOf(':');
543
5
  const attType = attachment.substr(0, idx);
@@ -600,463 +62,4 @@ export const renderAttachment = (attachment) => {
600
62
  }
601
63
  return html `<div style="">${inner}</div>`;
602
64
  };
603
- export const renderMsgEvent = (event) => {
604
- const isInbound = event.type === Events.MESSAGE_RECEIVED;
605
- const isError = event.status === 'E';
606
- const isFailure = event.status === 'F';
607
- // summary items which appear under the message bubble
608
- const summary = [];
609
- if (event.logs_url) {
610
- summary.push(html ` <div class="icon-link">
611
- <temba-icon
612
- onclick="goto(event)"
613
- href="${event.logs_url}"
614
- name="${Icon.log}"
615
- class="log ${isError || isFailure ? 'error' : ''}"
616
- ></temba-icon>
617
- </div>`);
618
- }
619
- else if (isError) {
620
- summary.push(html `<temba-icon
621
- title="Message delivery error"
622
- name="${Icon.error}"
623
- class="delivery-error"
624
- ></temba-icon>`);
625
- }
626
- else if (isFailure) {
627
- summary.push(html `<temba-icon
628
- title="Message delivery failure: ${event.failed_reason_display}"
629
- name="${Icon.error}"
630
- class="delivery-error"
631
- ></temba-icon>`);
632
- }
633
- if (event.type == 'broadcast_created') {
634
- summary.push(html `<temba-icon
635
- size="1"
636
- class="broadcast"
637
- name="${Icon.broadcast}"
638
- ></temba-icon>`);
639
- if (event.recipient_count > 1) {
640
- summary.push(html `<div class="recipients">${event.recipient_count} contacts</div>`);
641
- }
642
- summary.push(html `<div class="separator">•</div>`);
643
- }
644
- if (event.optin) {
645
- summary.push(html `<div class="optin">${event.optin.name}</div>
646
- <div class="separator">•</div>`);
647
- }
648
- if (event.status === 'Q') {
649
- summary.push(html `<div>Queued</div>`);
650
- }
651
- summary.push(html `<temba-date
652
- class="time"
653
- value="${event.created_on}"
654
- display="duration"
655
- ></temba-date>`);
656
- return html `<div
657
- style="display:flex;align-items:flex-start"
658
- class=${getClasses({ queued: event.status === 'Q' })}
659
- >
660
- <div style="display:flex;flex-direction:column">
661
- <div
662
- class="${event.msg.text ? '' : 'no-message'} attachments-${(event.msg.attachments || []).length} ${getClasses({
663
- msg: true,
664
- automated: !isInbound && !event.created_by
665
- })}"
666
- >
667
- ${event.msg.text
668
- ? html ` <div class="text">${event.msg.text}</div> `
669
- : null}
670
- ${event.msg.attachments
671
- ? html `<div class="attachments">
672
- ${event.msg.attachments.map((attachment) => html ` <div class="attachment">
673
- ${renderAttachment(attachment)}
674
- </div>`)}
675
- </div> `
676
- : null}
677
- </div>
678
-
679
- ${!event.msg.text && !event.msg.attachments && !event.optin
680
- ? html `<div class="unsupported">Unsupported Message</div>`
681
- : null}
682
-
683
- <div
684
- class="msg-summary"
685
- style="align-items:center;flex-direction:row${isInbound
686
- ? '-reverse'
687
- : ''}"
688
- >
689
- <div style="flex-grow:1"></div>
690
- ${summary}
691
- </div>
692
- </div>
693
-
694
- ${!isInbound && event.created_by
695
- ? html `<temba-user
696
- style="margin-left:0.5em"
697
- email=${event.created_by.email}
698
- ></temba-user>`
699
- : null}
700
- </div>`;
701
- };
702
- export const renderFlowEvent = (event) => {
703
- let verb = 'Interrupted';
704
- let icon = Icon.flow_interrupted;
705
- if (event.status !== 'I') {
706
- if (event.type === Events.FLOW_ENTERED) {
707
- verb = 'Started';
708
- icon = Icon.flow;
709
- }
710
- else {
711
- verb = 'Completed';
712
- icon = Icon.flow;
713
- }
714
- }
715
- return html `
716
- <temba-icon name="${icon}"></temba-icon>
717
- <div class="description">
718
- ${verb}
719
- <span
720
- class="linked"
721
- href="/flow/editor/${event.flow.uuid}/"
722
- onclick="goto(event)"
723
- >
724
- ${event.flow.name}
725
- </span>
726
- </div>
727
- `;
728
- };
729
- export const renderResultEvent = (event) => {
730
- if (event.name.startsWith('_')) {
731
- return null;
732
- }
733
- return html `
734
- <temba-icon name="${Icon.updated}"></temba-icon>
735
- <div class="description">
736
- Updated
737
- <div class="attn">${event.name}</div>
738
- to
739
- <div class="attn">${event.value}</div>
740
- ${event.category
741
- ? html `with category
742
- <div class="attn">${event.category}</div>`
743
- : null}
744
- </div>
745
- `;
746
- };
747
- export const renderUpdateEvent = (event) => {
748
- return html `
749
- <temba-icon name="${Icon.contact_updated}"></temba-icon>
750
- <div class="description">
751
- ${event.value
752
- ? html `Updated
753
- <div class="attn">${event.field.name}</div>
754
- to
755
- <div class="attn">${event.value.text}</div>`
756
- : html `Cleared
757
- <div class="attn">${event.field.name}</div>`}
758
- </div>
759
- `;
760
- };
761
- export const renderNameChanged = (event) => {
762
- return html `
763
- <temba-icon name="${Icon.contact_updated}"></temba-icon>
764
- <div class="description">
765
- Updated
766
- <div class="attn">Name</div>
767
- to
768
- <div class="attn">${event.name}</div>
769
- </div>
770
- `;
771
- };
772
- export const renderContactURNsChanged = (event) => {
773
- return html `
774
- <temba-icon name="${Icon.contact_updated}"></temba-icon>
775
- <div class="description">
776
- Updated
777
- <div class="attn">URNs</div>
778
- to
779
- ${oxfordFn(event.urns, (urn) => html `<div class="attn">${urn.split(':')[1].split('?')[0]}</div>`)}
780
- </div>
781
- </div>
782
- `;
783
- };
784
- export const renderEmailSent = (event) => {
785
- return html `
786
- <temba-icon name="${Icon.email}"></temba-icon>
787
- <div class="description">
788
- Email sent to
789
- <div class="attn">${oxford(event.to, 'and')}</div>
790
- with subject
791
- <div class="attn">${event.subject}</div>
792
- </div>
793
- `;
794
- };
795
- export const renderLabelsAdded = (event) => {
796
- return html `
797
- <temba-icon name="${Icon.label}"></temba-icon>
798
- <div class="description">
799
- Message labeled with
800
- <div class="attn">${oxfordNamed(event.labels, 'and')}</div>
801
- </div>
802
- `;
803
- };
804
- export const renderNoteCreated = (event) => {
805
- return html ` <div style="display:flex;align-items:flex-start">
806
- <div style="display:flex;flex-direction:column">
807
- <div class="description">${event.note}</div>
808
- <div class="note-summary">
809
- <div style="flex-grow:1"></div>
810
- <temba-date
811
- class="time"
812
- value="${event.created_on}"
813
- display="duration"
814
- ></temba-date>
815
- </div>
816
- </div>
817
- <temba-user email=${event.created_by.email}></temba-user>
818
- </div>`;
819
- };
820
- export const renderTicketAction = (event, action, grouped) => {
821
- if (grouped) {
822
- return html `<div class="" style="display: flex">
823
- <temba-icon name="${Icon.inbox}"></temba-icon>
824
- <div class="description">
825
- ${getDisplayName(event.created_by)} ${action} a
826
- <span
827
- onclick="goto(event)"
828
- class="linked"
829
- href="/ticket/all/open/${event.ticket.uuid}/"
830
- >
831
- ticket
832
- </span>
833
- </div>
834
- </div>`;
835
- }
836
- return html `
837
- <div class="assigned active">
838
- <div style="text-align:center">
839
- ${event.created_by
840
- ? html ` ${getDisplayName(event.created_by)} ${action} this ticket `
841
- : html ` This ticket was ${action} `}
842
- </div>
843
- <div class="subtext" style="justify-content:center">
844
- <temba-date
845
- class="time"
846
- value="${event.created_on}"
847
- display="duration"
848
- ></temba-date>
849
- </div>
850
- </div>
851
- `;
852
- };
853
- export const renderTicketAssigned = (event) => {
854
- return html `
855
- <div class="assigned active">
856
- <div style="text-align:center">
857
- ${event.assignee
858
- ? event.assignee.id === event.created_by.id
859
- ? html `${getDisplayName(event.created_by)} took this ticket`
860
- : html `${getDisplayName(event.created_by)} assigned this ticket to
861
- <div class="attn">${getDisplayName(event.assignee)}</div>`
862
- : html `${getDisplayName(event.created_by)} unassigned this ticket`}
863
- </div>
864
- <div class="subtext" style="justify-content:center">
865
- <temba-date
866
- class="time"
867
- value="${event.created_on}"
868
- display="duration"
869
- ></temba-date>
870
- </div>
871
- </div>
872
- `;
873
- };
874
- export const renderTicketOpened = (event, handleClose, grouped) => {
875
- if (grouped) {
876
- return html `<div class="" style="display: flex">
877
- <temba-icon name="${Icon.inbox}"></temba-icon>
878
- <div class="description">
879
- ${event.ticket.topic.name}
880
- <span
881
- class="linked"
882
- onclick="goto(event)"
883
- href="/ticket/all/open/${event.ticket.uuid}"
884
- >ticket</span
885
- >
886
- was opened
887
- </div>
888
- </div>`;
889
- }
890
- else {
891
- return html `
892
- <div>
893
- <div style="text-align:center">
894
- ${getDisplayName(event.created_by)} opened this ticket
895
- </div>
896
- <div class="subtext" style="justify-content:center">
897
- <temba-date
898
- class="time"
899
- value="${event.created_on}"
900
- display="duration"
901
- ></temba-date>
902
- </div>
903
- </div>
904
- `;
905
- }
906
- };
907
- export const renderErrorMessage = (event) => {
908
- return html `
909
- <temba-icon
910
- name="${Icon.error}"
911
- style="--icon-color:var(--color-error)"
912
- ></temba-icon>
913
- <div class="description">
914
- ${event.text}
915
- ${event.type === Events.FAILURE
916
- ? html `<div>Run ended prematurely, check the flow design.</div>`
917
- : null}
918
- </div>
919
- `;
920
- };
921
- export const renderWebhookEvent = (event) => {
922
- return html `
923
- <div
924
- class="${event.status === 'success' ? '' : 'failed'}"
925
- style="display: flex"
926
- >
927
- <temba-icon name="${Icon.webhook}"></temba-icon>
928
- <div class="description">
929
- ${event.status === 'success'
930
- ? html `Successfully called ${event.url}`
931
- : html `Failed to call ${event.url}`}
932
- </div>
933
- </div>
934
- `;
935
- };
936
- export const renderAirtimeTransferredEvent = (event) => {
937
- if (parseFloat(event.actual_amount) === 0) {
938
- return html `<temba-icon
939
- name="${Icon.error}"
940
- style="--icon-color: var(--color-error)"
941
- ></temba-icon>
942
- <div class="description error">Airtime transfer failed</div>`;
943
- }
944
- return html `<temba-icon name="${Icon.airtime}"></temba-icon>
945
- <div class="description">
946
- Transferred
947
- <div class="attn">${event.actual_amount} ${event.currency}</div>
948
- of airtime
949
- </div>`;
950
- };
951
- export const renderCallStartedEvent = () => {
952
- return html `<temba-icon name="${Icon.call}"></temba-icon>
953
- <div class="description">Call Started</div>`;
954
- };
955
- export const renderContactLanguageChangedEvent = (event) => {
956
- return html `<temba-icon name="${Icon.contact_updated}"></temba-icon>
957
- <div class="description">
958
- Language updated to <span class="attn">${event.language}</span>
959
- </div>`;
960
- };
961
- export const renderOptinRequested = (event) => {
962
- return html `<temba-icon name="${Icon.optin_requested}"></temba-icon>
963
- <div class="description">
964
- Requested opt-in for <span class="attn">${event.optin.name}</span>
965
- </div>`;
966
- };
967
- export const renderChannelEvent = (event) => {
968
- var _a, _b;
969
- let eventMessage = '';
970
- let icon = Icon.call;
971
- if (event.event.type === 'mt_miss') {
972
- eventMessage = 'Missed outgoing call';
973
- icon = Icon.call_missed;
974
- }
975
- else if (event.event.type === 'mo_miss') {
976
- eventMessage = 'Missed incoming call';
977
- icon = Icon.call_missed;
978
- }
979
- else if (event.event.type === 'new_conversation') {
980
- eventMessage = 'Started Conversation';
981
- icon = Icon.event;
982
- }
983
- else if (event.channel_event_type === 'welcome_message') {
984
- eventMessage = 'Welcome Message Sent';
985
- icon = Icon.event;
986
- }
987
- else if (event.event.type === 'referral') {
988
- eventMessage = 'Referred';
989
- icon = Icon.event;
990
- }
991
- else if (event.event.type === 'follow') {
992
- eventMessage = 'Followed';
993
- icon = Icon.event;
994
- }
995
- else if (event.event.type === 'stop_contact') {
996
- eventMessage = 'Stopped';
997
- icon = Icon.contact_stopped;
998
- }
999
- else if (event.event.type === 'mt_call') {
1000
- eventMessage = 'Outgoing Phone Call';
1001
- }
1002
- else if (event.event.type == 'mo_call') {
1003
- eventMessage = 'Incoming Phone call';
1004
- }
1005
- else if (event.event.type == 'optin') {
1006
- eventMessage = html `Opted in to
1007
- <span class="attn">${(_a = event.event.optin) === null || _a === void 0 ? void 0 : _a.name}</span>`;
1008
- icon = Icon.optin;
1009
- }
1010
- else if (event.event.type == 'optout') {
1011
- eventMessage = html `Opted out of
1012
- <span class="attn">${(_b = event.event.optin) === null || _b === void 0 ? void 0 : _b.name}</span>`;
1013
- icon = Icon.optout;
1014
- }
1015
- return html `<temba-icon name="${icon}"></temba-icon>
1016
- <div class="description">${eventMessage}</div>`;
1017
- };
1018
- export const renderCampaignFiredEvent = (event) => {
1019
- return html `<temba-icon name="${Icon.campaign}"></temba-icon>
1020
- <div class="description">
1021
- Campaign
1022
- <span
1023
- class="linked"
1024
- onclick="goto(event, this)"
1025
- href="/campaign/read/${event.campaign.uuid}/"
1026
- >${event.campaign.name}</span
1027
- >
1028
- ${event.fired_result === 'S' ? 'skipped' : 'triggered'}
1029
- <span
1030
- class="linked"
1031
- onclick="goto(event, this)"
1032
- href="/campaignevent/read/${event.campaign.uuid}/${event.campaign_event
1033
- .id}/"
1034
- >
1035
- ${event.campaign_event.offset_display}
1036
- ${event.campaign_event.relative_to.name}</span
1037
- >
1038
- </div>`;
1039
- };
1040
- export const renderContactGroupsEvent = (event) => {
1041
- const groups = event.groups_added || event.groups_removed;
1042
- const added = !!event.groups_added;
1043
- return html `
1044
- <temba-icon
1045
- name="${Icon.users}"
1046
- class="${getClasses({ added: added, removed: !added })}"
1047
- ></temba-icon>
1048
- <div class="description">
1049
- ${added ? 'Added to' : 'Removed from'}
1050
- ${oxfordFn(groups, (group) => html `<span
1051
- class="linked"
1052
- onclick="goto(event)"
1053
- href="/contact/filter/${group.uuid}"
1054
- >${group.name}</span
1055
- >`)}
1056
- ${event.type === Events.FAILURE
1057
- ? html `<div>Run ended prematurely, check the flow design.</div>`
1058
- : null}
1059
- </div>
1060
- `;
1061
- };
1062
65
  //# sourceMappingURL=events.js.map