@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.
- package/CHANGELOG.md +9 -0
- package/demo/index.html +1 -1
- package/dist/temba-components.js +760 -1189
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/chat/Chat.js +714 -0
- package/out-tsc/src/chat/Chat.js.map +1 -0
- package/out-tsc/src/completion/helpers.js +1 -29
- package/out-tsc/src/completion/helpers.js.map +1 -1
- package/out-tsc/src/compose/Compose.js +6 -2
- package/out-tsc/src/compose/Compose.js.map +1 -1
- package/out-tsc/src/contacts/ContactChat.js +518 -54
- package/out-tsc/src/contacts/ContactChat.js.map +1 -1
- package/out-tsc/src/contacts/events.js +1 -998
- package/out-tsc/src/contacts/events.js.map +1 -1
- package/out-tsc/src/lightbox/Lightbox.js +4 -0
- package/out-tsc/src/lightbox/Lightbox.js.map +1 -1
- package/out-tsc/src/list/TembaMenu.js +0 -1
- package/out-tsc/src/list/TembaMenu.js.map +1 -1
- package/out-tsc/src/markdown.js +33 -0
- package/out-tsc/src/markdown.js.map +1 -0
- package/out-tsc/src/select/Select.js +6 -1
- package/out-tsc/src/select/Select.js.map +1 -1
- package/out-tsc/src/textinput/TextInput.js +1 -1
- package/out-tsc/src/textinput/TextInput.js.map +1 -1
- package/out-tsc/src/thumbnail/Thumbnail.js +128 -81
- package/out-tsc/src/thumbnail/Thumbnail.js.map +1 -1
- package/out-tsc/src/utils/index.js +9 -11
- package/out-tsc/src/utils/index.js.map +1 -1
- package/out-tsc/src/webchat/WebChat.js +109 -358
- package/out-tsc/src/webchat/WebChat.js.map +1 -1
- package/out-tsc/src/webchat/index.js +17 -0
- package/out-tsc/src/webchat/index.js.map +1 -1
- package/out-tsc/temba-modules.js +2 -2
- package/out-tsc/temba-modules.js.map +1 -1
- package/out-tsc/temba-webchat.js +2 -0
- package/out-tsc/temba-webchat.js.map +1 -1
- package/out-tsc/test/temba-contact-chat.test.js +1 -0
- package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
- package/out-tsc/test/temba-lightbox.test.js +4 -4
- package/out-tsc/test/temba-lightbox.test.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/contacts/compose-attachments-no-text-failure.png +0 -0
- package/screenshots/truth/contacts/compose-attachments-no-text-success.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-failure-attachments.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-failure-generic.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-failure-text-and-attachments.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-failure-text.png +0 -0
- package/screenshots/truth/contacts/compose-text-and-attachments-success.png +0 -0
- package/screenshots/truth/contacts/compose-text-no-attachments-failure.png +0 -0
- package/screenshots/truth/contacts/compose-text-no-attachments-success.png +0 -0
- package/screenshots/truth/contacts/contact-active-default.png +0 -0
- package/screenshots/truth/contacts/contact-active-show-chatbox.png +0 -0
- package/screenshots/truth/contacts/contact-archived-hide-chatbox.png +0 -0
- package/screenshots/truth/contacts/contact-blocked-hide-chatbox.png +0 -0
- package/screenshots/truth/contacts/contact-stopped-hide-chatbox.png +0 -0
- package/screenshots/truth/lightbox/img-zoomed.png +0 -0
- package/screenshots/truth/lightbox/img.png +0 -0
- package/src/chat/Chat.ts +791 -0
- package/src/completion/helpers.ts +2 -40
- package/src/compose/Compose.ts +6 -2
- package/src/contacts/ContactChat.ts +609 -59
- package/src/contacts/events.ts +1 -1068
- package/src/lightbox/Lightbox.ts +5 -0
- package/src/list/TembaMenu.ts +0 -1
- package/src/markdown.ts +41 -0
- package/src/select/Select.ts +5 -1
- package/src/textinput/TextInput.ts +1 -1
- package/src/thumbnail/Thumbnail.ts +130 -81
- package/src/utils/index.ts +12 -13
- package/src/webchat/WebChat.ts +196 -413
- package/src/webchat/index.ts +23 -1
- package/static/css/temba-components.css +2 -0
- package/temba-modules.ts +2 -2
- package/temba-webchat.ts +2 -0
- package/test/temba-contact-chat.test.ts +1 -0
- package/test/temba-lightbox.test.ts +4 -4
- package/test-assets/contacts/history.json +1 -56
- package/out-tsc/src/contacts/ContactHistory.js +0 -691
- package/out-tsc/src/contacts/ContactHistory.js.map +0 -1
- package/out-tsc/test/temba-contact-history.test.js +0 -69
- package/out-tsc/test/temba-contact-history.test.js.map +0 -1
- package/src/contacts/ContactHistory.ts +0 -875
- package/test/temba-contact-history.test.ts +0 -107
package/src/contacts/events.ts
CHANGED
|
@@ -1,485 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { html, TemplateResult } from 'lit';
|
|
2
2
|
import { Msg, ObjectReference, User } from '../interfaces';
|
|
3
|
-
import { getClasses, oxford, oxfordFn, oxfordNamed } from '../utils';
|
|
4
3
|
import { Icon } from '../vectoricon';
|
|
5
|
-
import { getDisplayName } from './helpers';
|
|
6
|
-
|
|
7
|
-
export const getEventStyles = () => {
|
|
8
|
-
return css`
|
|
9
|
-
.grouping {
|
|
10
|
-
margin-top: 1em;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
.grouping.verbose {
|
|
14
|
-
background: #f9f9f9;
|
|
15
|
-
color: var(--color-dark);
|
|
16
|
-
--color-link-primary: rgba(38, 166, 230, 1);
|
|
17
|
-
pointer-events: none;
|
|
18
|
-
background: #fefefe;
|
|
19
|
-
box-shadow: -8px 0px 8px 1px rgba(0, 0, 0, 0.05) inset;
|
|
20
|
-
margin-right: -16px;
|
|
21
|
-
padding-right: 16px;
|
|
22
|
-
margin-bottom: 1.3em;
|
|
23
|
-
max-width: 100%;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
.grouping .items {
|
|
27
|
-
display: block;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.grouping.verbose .items {
|
|
31
|
-
opacity: 0;
|
|
32
|
-
max-height: 0;
|
|
33
|
-
display: flex;
|
|
34
|
-
flex-direction: column;
|
|
35
|
-
user-select: auto;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.grouping.flows .items {
|
|
39
|
-
padding: 0;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
.grouping.messages .items {
|
|
43
|
-
display: flex;
|
|
44
|
-
flex-direction: column;
|
|
45
|
-
margin: 0em 0.75em;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.grouping.verbose.expanded .items {
|
|
49
|
-
transition: max-height var(--transition-speed) ease-in-out,
|
|
50
|
-
opacity var(--transition-speed) ease-in-out;
|
|
51
|
-
opacity: 1;
|
|
52
|
-
max-height: 1000px;
|
|
53
|
-
padding: 1em 1em;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
.grouping.verbose.expanded {
|
|
57
|
-
border-top: 1px solid #f3f3f3;
|
|
58
|
-
border-bottom: 1px solid #f3f3f3;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
.grouping.verbose.expanded,
|
|
62
|
-
.grouping.verbose .event-count {
|
|
63
|
-
pointer-events: auto;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.grouping.verbose temba-icon {
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
.grouping.verbose > .event,
|
|
70
|
-
.grouping.verbose > pre {
|
|
71
|
-
max-height: 0px;
|
|
72
|
-
padding-top: 0;
|
|
73
|
-
padding-bottom: 0;
|
|
74
|
-
margin-top: 0;
|
|
75
|
-
margin-bottom: 0;
|
|
76
|
-
opacity: 0;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
.grouping.verbose .attn {
|
|
80
|
-
color: #666;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
.event-count {
|
|
84
|
-
position: relative;
|
|
85
|
-
font-size: 0.8em;
|
|
86
|
-
text-align: center;
|
|
87
|
-
margin: 0 auto;
|
|
88
|
-
display: table;
|
|
89
|
-
padding: 3px 10px;
|
|
90
|
-
font-weight: 400;
|
|
91
|
-
color: #999;
|
|
92
|
-
cursor: pointer;
|
|
93
|
-
width: 100%;
|
|
94
|
-
opacity: 1;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.event-count temba-icon {
|
|
98
|
-
display: inline-block;
|
|
99
|
-
position: absolute;
|
|
100
|
-
right: 5px;
|
|
101
|
-
top: 5px;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
.event-count:hover {
|
|
105
|
-
color: var(--color-link-primary-hover);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
.expanded .event-count {
|
|
109
|
-
padding: 0;
|
|
110
|
-
pointer-events: none;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.grouping.flows {
|
|
114
|
-
margin-left: 1em;
|
|
115
|
-
margin-right: 1em;
|
|
116
|
-
margin-bottom: 1.5em;
|
|
117
|
-
|
|
118
|
-
border: 1px solid #f2f2f2;
|
|
119
|
-
border-radius: var(--curvature);
|
|
120
|
-
padding: 0.5em 1em;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
.grouping.flows .event {
|
|
124
|
-
margin: 0;
|
|
125
|
-
padding: 0;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
.grouping.tickets {
|
|
129
|
-
margin-bottom: 2em;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
pre {
|
|
133
|
-
white-space: pre-wrap;
|
|
134
|
-
word-wrap: break-word;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
.grouping.verbose.expanded .event,
|
|
138
|
-
.grouping.verbose.expanded pre {
|
|
139
|
-
max-height: 500px;
|
|
140
|
-
opacity: 1;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
.grouping-close-button {
|
|
144
|
-
position: relative;
|
|
145
|
-
display: inline-block;
|
|
146
|
-
opacity: 0;
|
|
147
|
-
float: right;
|
|
148
|
-
--icon-color: #666;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
.grouping.verbose.expanded:hover .grouping-close-button {
|
|
152
|
-
opacity: 1;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
.grouping.messages,
|
|
156
|
-
.grouping.tickets {
|
|
157
|
-
display: flex;
|
|
158
|
-
flex-direction: column;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
.event {
|
|
162
|
-
margin: 0.25em 0.5em;
|
|
163
|
-
border-radius: var(--curvature);
|
|
164
|
-
flex-grow: 1;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
.msg {
|
|
168
|
-
border-radius: calc(var(--curvature) * 2.5);
|
|
169
|
-
border: 2px solid rgba(100, 100, 100, 0.1);
|
|
170
|
-
max-width: 300px;
|
|
171
|
-
word-break: break-word;
|
|
172
|
-
overflow: hidden;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
.msg.attachments-1.no-message {
|
|
176
|
-
border: 2px solid transparent;
|
|
177
|
-
background-color: transparent !important;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
.msg .text {
|
|
181
|
-
padding: var(--event-padding);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
.event.msg_received .msg {
|
|
185
|
-
background: rgba(200, 200, 200, 0.1);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
.event.msg_created,
|
|
189
|
-
.event.broadcast_created,
|
|
190
|
-
.event.ivr_created,
|
|
191
|
-
.event.ticket_note_added {
|
|
192
|
-
align-self: flex-end;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
.event.msg_created .msg,
|
|
196
|
-
.event.broadcast_created .msg,
|
|
197
|
-
.event.ivr_created .msg {
|
|
198
|
-
background: var(--color-primary-dark);
|
|
199
|
-
color: white;
|
|
200
|
-
font-weight: 400;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
.msg.automated {
|
|
204
|
-
background: var(--color-automated) !important;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
.queued {
|
|
208
|
-
opacity: 0.3;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
.optin_requested {
|
|
212
|
-
--icon-color: var(--color-primary-dark);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
.webhook_called {
|
|
216
|
-
--icon-color: #e68628;
|
|
217
|
-
word-break: break-all;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
.webhook_called .failed {
|
|
221
|
-
--icon-color: var(--color-error);
|
|
222
|
-
color: var(--color-error);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
.input_labels_added,
|
|
226
|
-
.contact_name_changed,
|
|
227
|
-
.contact_field_changed,
|
|
228
|
-
.contact_urns_changed,
|
|
229
|
-
.contact_language_changed,
|
|
230
|
-
.run_result_changed {
|
|
231
|
-
--icon-color: rgba(1, 193, 175, 1);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
.email_sent {
|
|
235
|
-
--icon-color: #8e5ea7;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
.contact_groups_changed .added {
|
|
239
|
-
--icon-color: #309c42;
|
|
240
|
-
}
|
|
241
|
-
.contact_groups_changed .removed {
|
|
242
|
-
--icon-color: var(--color-error);
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
.event.error .description,
|
|
246
|
-
.event.failure .description {
|
|
247
|
-
color: var(--color-error);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
.description.error {
|
|
251
|
-
color: var(--color-error);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
.info {
|
|
255
|
-
border: 1px solid rgba(100, 100, 100, 0.2);
|
|
256
|
-
background: rgba(10, 10, 10, 0.02);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
.ticket_note_added {
|
|
260
|
-
max-width: 300px;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
.note-summary {
|
|
264
|
-
display: flex;
|
|
265
|
-
flex-direction: row;
|
|
266
|
-
font-size: 85%;
|
|
267
|
-
margin-top: -0.5em;
|
|
268
|
-
color: rgba(0, 0, 0, 0.6);
|
|
269
|
-
padding: 8px 3px;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
.ticket_note_added .description {
|
|
273
|
-
border: 2px solid rgba(100, 100, 100, 0.1);
|
|
274
|
-
background: rgb(255, 249, 194);
|
|
275
|
-
padding: var(--event-padding);
|
|
276
|
-
font-weight: 400;
|
|
277
|
-
color: rgba(0, 0, 0, 0.6);
|
|
278
|
-
border-radius: calc(var(--curvature) * 2.5);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
.channel_event {
|
|
282
|
-
--icon-color: rgb(200, 200, 200);
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
.airtime_transferred,
|
|
286
|
-
.flow_exited,
|
|
287
|
-
.flow_entered,
|
|
288
|
-
.ticket_opened,
|
|
289
|
-
.ticket_reopened,
|
|
290
|
-
.ticket_closed,
|
|
291
|
-
.call_started,
|
|
292
|
-
.campaign_fired {
|
|
293
|
-
--icon-color: rgba(223, 65, 159, 1);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
.active-ticket.ticket_opened {
|
|
297
|
-
padding: 0em 1em;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
.ticket_closed .inactive .subtext {
|
|
301
|
-
display: none;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
.attn {
|
|
305
|
-
color: var(--color-text);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
.flow_exited,
|
|
309
|
-
.flow_entered {
|
|
310
|
-
align-self: center;
|
|
311
|
-
max-width: 80%;
|
|
312
|
-
display: flex;
|
|
313
|
-
flex-direction: row;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
.flow_exited temba-icon,
|
|
317
|
-
.flow_entered temba-icon {
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
.event {
|
|
321
|
-
display: flex;
|
|
322
|
-
align-items: center;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
.event .description {
|
|
326
|
-
flex-grow: 1;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
.msg-summary {
|
|
330
|
-
display: flex;
|
|
331
|
-
font-size: 85%;
|
|
332
|
-
color: rgba(0, 0, 0, 0.6);
|
|
333
|
-
padding: 6px 3px;
|
|
334
|
-
margin-bottom: 0.5em;
|
|
335
|
-
margin-top: -0.5em;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
.msg-summary temba-icon.log {
|
|
339
|
-
--icon-color: rgba(0, 0, 0, 0.2);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
.msg-summary temba-icon.log:hover {
|
|
343
|
-
--icon-color: var(--color-link-primary-hover);
|
|
344
|
-
cursor: pointer;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
.msg-summary temba-icon.error {
|
|
348
|
-
--icon-color: rgba(var(--error-rgb), 0.75);
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
.msg-summary temba-icon.error:hover {
|
|
352
|
-
--icon-color: var(--color-error);
|
|
353
|
-
cursor: pointer;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
.msg-summary temba-icon.broadcast {
|
|
357
|
-
--icon-color: rgba(90, 90, 90, 0.5);
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
.msg-summary * {
|
|
361
|
-
display: flex;
|
|
362
|
-
margin-right: 1px;
|
|
363
|
-
margin-left: 1px;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
.unsupported {
|
|
367
|
-
border: 1px solid #f2f2f2;
|
|
368
|
-
color: #999;
|
|
369
|
-
padding: 0.5em 1em;
|
|
370
|
-
border-radius: var(--curvature);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
.optin {
|
|
374
|
-
align-items: center;
|
|
375
|
-
padding: 0 0.2em;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
.time {
|
|
379
|
-
padding: 0.3em 1px;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
.subtext .time {
|
|
383
|
-
padding: 0em;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
.status {
|
|
387
|
-
padding: 0.3em 3px;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
.separator {
|
|
391
|
-
padding: 0.3em 0px;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
.recipients {
|
|
395
|
-
padding: 0.3em 3px;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
.verbose temba-icon,
|
|
399
|
-
.flows temba-icon,
|
|
400
|
-
.tickets temba-icon {
|
|
401
|
-
margin-right: 0.75em;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
.attn {
|
|
405
|
-
display: inline-block;
|
|
406
|
-
font-weight: 500;
|
|
407
|
-
margin: 0px 2px;
|
|
408
|
-
word-break: break-all;
|
|
409
|
-
white-space: break-spaces;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
.subtext {
|
|
413
|
-
font-size: 80%;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
.body-pre {
|
|
417
|
-
white-space: pre-wrap;
|
|
418
|
-
word-wrap: break-word;
|
|
419
|
-
font-size: 90%;
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
a,
|
|
423
|
-
.linked {
|
|
424
|
-
color: var(--color-link-primary);
|
|
425
|
-
cursor: pointer;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
a:hover,
|
|
429
|
-
.linked:hover {
|
|
430
|
-
text-decoration: underline;
|
|
431
|
-
color: var(--color-link-primary-hover);
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
temba-icon.error {
|
|
435
|
-
--icon-color: var(--color-error);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
.delivery-error {
|
|
439
|
-
--icon-color: var(--color-error);
|
|
440
|
-
margin-right: 0.25em;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
.flow {
|
|
444
|
-
--icon-color: #ddd;
|
|
445
|
-
background: #fff;
|
|
446
|
-
width: 18px;
|
|
447
|
-
height: 18px;
|
|
448
|
-
padding-top: 4px;
|
|
449
|
-
padding-left: 9px;
|
|
450
|
-
border: 0px solid #f3f3f3;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
.assigned {
|
|
454
|
-
color: #777;
|
|
455
|
-
max-width: 300px;
|
|
456
|
-
margin-left: auto;
|
|
457
|
-
margin-right: auto;
|
|
458
|
-
display: flex;
|
|
459
|
-
flex-direction: column;
|
|
460
|
-
align-items: center;
|
|
461
|
-
margin-bottom: 10px;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
.assigned .attn {
|
|
465
|
-
color: #777;
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
.attachments {
|
|
469
|
-
display: flex;
|
|
470
|
-
flex-wrap: wrap;
|
|
471
|
-
margin: -0.2em;
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
.attachment {
|
|
475
|
-
flex: 1 0 45%;
|
|
476
|
-
border-top: 0.05em solid transparent;
|
|
477
|
-
border-left: 0.05em solid transparent;
|
|
478
|
-
margin-top: 0.05em;
|
|
479
|
-
margin-left: 0.05em;
|
|
480
|
-
}
|
|
481
|
-
`;
|
|
482
|
-
};
|
|
483
4
|
|
|
484
5
|
export interface EventGroup {
|
|
485
6
|
type: string;
|
|
@@ -487,37 +8,6 @@ export interface EventGroup {
|
|
|
487
8
|
open: boolean;
|
|
488
9
|
}
|
|
489
10
|
|
|
490
|
-
export enum Events {
|
|
491
|
-
MESSAGE_CREATED = 'msg_created',
|
|
492
|
-
MESSAGE_RECEIVED = 'msg_received',
|
|
493
|
-
BROADCAST_CREATED = 'broadcast_created',
|
|
494
|
-
IVR_CREATED = 'ivr_created',
|
|
495
|
-
FLOW_ENTERED = 'flow_entered',
|
|
496
|
-
FLOW_EXITED = 'flow_exited',
|
|
497
|
-
RUN_RESULT_CHANGED = 'run_result_changed',
|
|
498
|
-
CONTACT_FIELD_CHANGED = 'contact_field_changed',
|
|
499
|
-
CONTACT_GROUPS_CHANGED = 'contact_groups_changed',
|
|
500
|
-
CONTACT_NAME_CHANGED = 'contact_name_changed',
|
|
501
|
-
CONTACT_URNS_CHANGED = 'contact_urns_changed',
|
|
502
|
-
CAMPAIGN_FIRED = 'campaign_fired',
|
|
503
|
-
CHANNEL_EVENT = 'channel_event',
|
|
504
|
-
CONTACT_LANGUAGE_CHANGED = 'contact_language_changed',
|
|
505
|
-
WEBHOOK_CALLED = 'webhook_called',
|
|
506
|
-
AIRTIME_TRANSFERRED = 'airtime_transferred',
|
|
507
|
-
CALL_STARTED = 'call_started',
|
|
508
|
-
EMAIL_SENT = 'email_sent',
|
|
509
|
-
INPUT_LABELS_ADDED = 'input_labels_added',
|
|
510
|
-
NOTE_CREATED = 'note_created',
|
|
511
|
-
TICKET_ASSIGNED = 'ticket_assigned',
|
|
512
|
-
TICKET_NOTE_ADDED = 'ticket_note_added',
|
|
513
|
-
TICKET_CLOSED = 'ticket_closed',
|
|
514
|
-
TICKET_OPENED = 'ticket_opened',
|
|
515
|
-
TICKET_REOPENED = 'ticket_reopened',
|
|
516
|
-
OPTIN_REQUESTED = 'optin_requested',
|
|
517
|
-
ERROR = 'error',
|
|
518
|
-
FAILURE = 'failure'
|
|
519
|
-
}
|
|
520
|
-
|
|
521
11
|
export interface ContactEvent {
|
|
522
12
|
type: string;
|
|
523
13
|
created_on: string;
|
|
@@ -657,39 +147,6 @@ export interface ContactHistoryPage {
|
|
|
657
147
|
events: ContactEvent[];
|
|
658
148
|
}
|
|
659
149
|
|
|
660
|
-
export const getEventGroupType = (event: ContactEvent, ticket: string) => {
|
|
661
|
-
if (!event) {
|
|
662
|
-
return 'messages';
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
switch (event.type) {
|
|
666
|
-
case Events.TICKET_ASSIGNED:
|
|
667
|
-
case Events.TICKET_OPENED:
|
|
668
|
-
case Events.TICKET_CLOSED:
|
|
669
|
-
case Events.TICKET_REOPENED:
|
|
670
|
-
if (!ticket) {
|
|
671
|
-
return 'verbose';
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
if ((event as TicketEvent).ticket.uuid === ticket) {
|
|
675
|
-
return 'tickets';
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
break;
|
|
679
|
-
case Events.FLOW_ENTERED:
|
|
680
|
-
case Events.FLOW_EXITED:
|
|
681
|
-
return 'flows';
|
|
682
|
-
case Events.BROADCAST_CREATED:
|
|
683
|
-
case Events.MESSAGE_CREATED:
|
|
684
|
-
case Events.MESSAGE_RECEIVED:
|
|
685
|
-
case Events.IVR_CREATED:
|
|
686
|
-
case Events.TICKET_NOTE_ADDED:
|
|
687
|
-
case Events.NOTE_CREATED:
|
|
688
|
-
return 'messages';
|
|
689
|
-
}
|
|
690
|
-
return 'verbose';
|
|
691
|
-
};
|
|
692
|
-
|
|
693
150
|
export const renderAttachment = (attachment: string): TemplateResult => {
|
|
694
151
|
const idx = attachment.indexOf(':');
|
|
695
152
|
const attType = attachment.substr(0, idx);
|
|
@@ -750,527 +207,3 @@ export const renderAttachment = (attachment: string): TemplateResult => {
|
|
|
750
207
|
|
|
751
208
|
return html`<div style="">${inner}</div>`;
|
|
752
209
|
};
|
|
753
|
-
|
|
754
|
-
export const renderMsgEvent = (event: MsgEvent): TemplateResult => {
|
|
755
|
-
const isInbound = event.type === Events.MESSAGE_RECEIVED;
|
|
756
|
-
const isError = event.status === 'E';
|
|
757
|
-
const isFailure = event.status === 'F';
|
|
758
|
-
|
|
759
|
-
// summary items which appear under the message bubble
|
|
760
|
-
const summary: TemplateResult[] = [];
|
|
761
|
-
|
|
762
|
-
if (event.logs_url) {
|
|
763
|
-
summary.push(html` <div class="icon-link">
|
|
764
|
-
<temba-icon
|
|
765
|
-
onclick="goto(event)"
|
|
766
|
-
href="${event.logs_url}"
|
|
767
|
-
name="${Icon.log}"
|
|
768
|
-
class="log ${isError || isFailure ? 'error' : ''}"
|
|
769
|
-
></temba-icon>
|
|
770
|
-
</div>`);
|
|
771
|
-
} else if (isError) {
|
|
772
|
-
summary.push(
|
|
773
|
-
html`<temba-icon
|
|
774
|
-
title="Message delivery error"
|
|
775
|
-
name="${Icon.error}"
|
|
776
|
-
class="delivery-error"
|
|
777
|
-
></temba-icon>`
|
|
778
|
-
);
|
|
779
|
-
} else if (isFailure) {
|
|
780
|
-
summary.push(
|
|
781
|
-
html`<temba-icon
|
|
782
|
-
title="Message delivery failure: ${event.failed_reason_display}"
|
|
783
|
-
name="${Icon.error}"
|
|
784
|
-
class="delivery-error"
|
|
785
|
-
></temba-icon>`
|
|
786
|
-
);
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
if (event.type == 'broadcast_created') {
|
|
790
|
-
summary.push(html`<temba-icon
|
|
791
|
-
size="1"
|
|
792
|
-
class="broadcast"
|
|
793
|
-
name="${Icon.broadcast}"
|
|
794
|
-
></temba-icon>`);
|
|
795
|
-
|
|
796
|
-
if (event.recipient_count > 1) {
|
|
797
|
-
summary.push(
|
|
798
|
-
html`<div class="recipients">${event.recipient_count} contacts</div>`
|
|
799
|
-
);
|
|
800
|
-
}
|
|
801
|
-
summary.push(html`<div class="separator">•</div>`);
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
if (event.optin) {
|
|
805
|
-
summary.push(
|
|
806
|
-
html`<div class="optin">${event.optin.name}</div>
|
|
807
|
-
<div class="separator">•</div>`
|
|
808
|
-
);
|
|
809
|
-
}
|
|
810
|
-
|
|
811
|
-
if (event.status === 'Q') {
|
|
812
|
-
summary.push(html`<div>Queued</div>`);
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
summary.push(
|
|
816
|
-
html`<temba-date
|
|
817
|
-
class="time"
|
|
818
|
-
value="${event.created_on}"
|
|
819
|
-
display="duration"
|
|
820
|
-
></temba-date>`
|
|
821
|
-
);
|
|
822
|
-
|
|
823
|
-
return html`<div
|
|
824
|
-
style="display:flex;align-items:flex-start"
|
|
825
|
-
class=${getClasses({ queued: event.status === 'Q' })}
|
|
826
|
-
>
|
|
827
|
-
<div style="display:flex;flex-direction:column">
|
|
828
|
-
<div
|
|
829
|
-
class="${event.msg.text ? '' : 'no-message'} attachments-${(
|
|
830
|
-
event.msg.attachments || []
|
|
831
|
-
).length} ${getClasses({
|
|
832
|
-
msg: true,
|
|
833
|
-
automated: !isInbound && !event.created_by
|
|
834
|
-
})}"
|
|
835
|
-
>
|
|
836
|
-
${event.msg.text
|
|
837
|
-
? html` <div class="text">${event.msg.text}</div> `
|
|
838
|
-
: null}
|
|
839
|
-
${event.msg.attachments
|
|
840
|
-
? html`<div class="attachments">
|
|
841
|
-
${event.msg.attachments.map(
|
|
842
|
-
(attachment) =>
|
|
843
|
-
html` <div class="attachment">
|
|
844
|
-
${renderAttachment(attachment)}
|
|
845
|
-
</div>`
|
|
846
|
-
)}
|
|
847
|
-
</div> `
|
|
848
|
-
: null}
|
|
849
|
-
</div>
|
|
850
|
-
|
|
851
|
-
${!event.msg.text && !event.msg.attachments && !event.optin
|
|
852
|
-
? html`<div class="unsupported">Unsupported Message</div>`
|
|
853
|
-
: null}
|
|
854
|
-
|
|
855
|
-
<div
|
|
856
|
-
class="msg-summary"
|
|
857
|
-
style="align-items:center;flex-direction:row${isInbound
|
|
858
|
-
? '-reverse'
|
|
859
|
-
: ''}"
|
|
860
|
-
>
|
|
861
|
-
<div style="flex-grow:1"></div>
|
|
862
|
-
${summary}
|
|
863
|
-
</div>
|
|
864
|
-
</div>
|
|
865
|
-
|
|
866
|
-
${!isInbound && event.created_by
|
|
867
|
-
? html`<temba-user
|
|
868
|
-
style="margin-left:0.5em"
|
|
869
|
-
email=${event.created_by.email}
|
|
870
|
-
></temba-user>`
|
|
871
|
-
: null}
|
|
872
|
-
</div>`;
|
|
873
|
-
};
|
|
874
|
-
|
|
875
|
-
export const renderFlowEvent = (event: FlowEvent): TemplateResult => {
|
|
876
|
-
let verb = 'Interrupted';
|
|
877
|
-
let icon = Icon.flow_interrupted;
|
|
878
|
-
|
|
879
|
-
if (event.status !== 'I') {
|
|
880
|
-
if (event.type === Events.FLOW_ENTERED) {
|
|
881
|
-
verb = 'Started';
|
|
882
|
-
icon = Icon.flow;
|
|
883
|
-
} else {
|
|
884
|
-
verb = 'Completed';
|
|
885
|
-
icon = Icon.flow;
|
|
886
|
-
}
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
return html`
|
|
890
|
-
<temba-icon name="${icon}"></temba-icon>
|
|
891
|
-
<div class="description">
|
|
892
|
-
${verb}
|
|
893
|
-
<span
|
|
894
|
-
class="linked"
|
|
895
|
-
href="/flow/editor/${event.flow.uuid}/"
|
|
896
|
-
onclick="goto(event)"
|
|
897
|
-
>
|
|
898
|
-
${event.flow.name}
|
|
899
|
-
</span>
|
|
900
|
-
</div>
|
|
901
|
-
`;
|
|
902
|
-
};
|
|
903
|
-
|
|
904
|
-
export const renderResultEvent = (event: UpdateResultEvent): TemplateResult => {
|
|
905
|
-
if (event.name.startsWith('_')) {
|
|
906
|
-
return null;
|
|
907
|
-
}
|
|
908
|
-
return html`
|
|
909
|
-
<temba-icon name="${Icon.updated}"></temba-icon>
|
|
910
|
-
<div class="description">
|
|
911
|
-
Updated
|
|
912
|
-
<div class="attn">${event.name}</div>
|
|
913
|
-
to
|
|
914
|
-
<div class="attn">${event.value}</div>
|
|
915
|
-
${event.category
|
|
916
|
-
? html`with category
|
|
917
|
-
<div class="attn">${event.category}</div>`
|
|
918
|
-
: null}
|
|
919
|
-
</div>
|
|
920
|
-
`;
|
|
921
|
-
};
|
|
922
|
-
|
|
923
|
-
export const renderUpdateEvent = (event: UpdateFieldEvent): TemplateResult => {
|
|
924
|
-
return html`
|
|
925
|
-
<temba-icon name="${Icon.contact_updated}"></temba-icon>
|
|
926
|
-
<div class="description">
|
|
927
|
-
${event.value
|
|
928
|
-
? html`Updated
|
|
929
|
-
<div class="attn">${event.field.name}</div>
|
|
930
|
-
to
|
|
931
|
-
<div class="attn">${event.value.text}</div>`
|
|
932
|
-
: html`Cleared
|
|
933
|
-
<div class="attn">${event.field.name}</div>`}
|
|
934
|
-
</div>
|
|
935
|
-
`;
|
|
936
|
-
};
|
|
937
|
-
|
|
938
|
-
export const renderNameChanged = (event: NameChangedEvent): TemplateResult => {
|
|
939
|
-
return html`
|
|
940
|
-
<temba-icon name="${Icon.contact_updated}"></temba-icon>
|
|
941
|
-
<div class="description">
|
|
942
|
-
Updated
|
|
943
|
-
<div class="attn">Name</div>
|
|
944
|
-
to
|
|
945
|
-
<div class="attn">${event.name}</div>
|
|
946
|
-
</div>
|
|
947
|
-
`;
|
|
948
|
-
};
|
|
949
|
-
|
|
950
|
-
export const renderContactURNsChanged = (
|
|
951
|
-
event: URNsChangedEvent
|
|
952
|
-
): TemplateResult => {
|
|
953
|
-
return html`
|
|
954
|
-
<temba-icon name="${Icon.contact_updated}"></temba-icon>
|
|
955
|
-
<div class="description">
|
|
956
|
-
Updated
|
|
957
|
-
<div class="attn">URNs</div>
|
|
958
|
-
to
|
|
959
|
-
${oxfordFn(
|
|
960
|
-
event.urns,
|
|
961
|
-
(urn: string) =>
|
|
962
|
-
html`<div class="attn">${urn.split(':')[1].split('?')[0]}</div>`
|
|
963
|
-
)}
|
|
964
|
-
</div>
|
|
965
|
-
</div>
|
|
966
|
-
`;
|
|
967
|
-
};
|
|
968
|
-
|
|
969
|
-
export const renderEmailSent = (event: EmailSentEvent): TemplateResult => {
|
|
970
|
-
return html`
|
|
971
|
-
<temba-icon name="${Icon.email}"></temba-icon>
|
|
972
|
-
<div class="description">
|
|
973
|
-
Email sent to
|
|
974
|
-
<div class="attn">${oxford(event.to, 'and')}</div>
|
|
975
|
-
with subject
|
|
976
|
-
<div class="attn">${event.subject}</div>
|
|
977
|
-
</div>
|
|
978
|
-
`;
|
|
979
|
-
};
|
|
980
|
-
|
|
981
|
-
export const renderLabelsAdded = (event: LabelsAddedEvent): TemplateResult => {
|
|
982
|
-
return html`
|
|
983
|
-
<temba-icon name="${Icon.label}"></temba-icon>
|
|
984
|
-
<div class="description">
|
|
985
|
-
Message labeled with
|
|
986
|
-
<div class="attn">${oxfordNamed(event.labels, 'and')}</div>
|
|
987
|
-
</div>
|
|
988
|
-
`;
|
|
989
|
-
};
|
|
990
|
-
|
|
991
|
-
export const renderNoteCreated = (event: TicketEvent): TemplateResult => {
|
|
992
|
-
return html` <div style="display:flex;align-items:flex-start">
|
|
993
|
-
<div style="display:flex;flex-direction:column">
|
|
994
|
-
<div class="description">${event.note}</div>
|
|
995
|
-
<div class="note-summary">
|
|
996
|
-
<div style="flex-grow:1"></div>
|
|
997
|
-
<temba-date
|
|
998
|
-
class="time"
|
|
999
|
-
value="${event.created_on}"
|
|
1000
|
-
display="duration"
|
|
1001
|
-
></temba-date>
|
|
1002
|
-
</div>
|
|
1003
|
-
</div>
|
|
1004
|
-
<temba-user email=${event.created_by.email}></temba-user>
|
|
1005
|
-
</div>`;
|
|
1006
|
-
};
|
|
1007
|
-
|
|
1008
|
-
export const renderTicketAction = (
|
|
1009
|
-
event: TicketEvent,
|
|
1010
|
-
action: string,
|
|
1011
|
-
grouped: boolean
|
|
1012
|
-
): TemplateResult => {
|
|
1013
|
-
if (grouped) {
|
|
1014
|
-
return html`<div class="" style="display: flex">
|
|
1015
|
-
<temba-icon name="${Icon.inbox}"></temba-icon>
|
|
1016
|
-
<div class="description">
|
|
1017
|
-
${getDisplayName(event.created_by)} ${action} a
|
|
1018
|
-
<span
|
|
1019
|
-
onclick="goto(event)"
|
|
1020
|
-
class="linked"
|
|
1021
|
-
href="/ticket/all/open/${event.ticket.uuid}/"
|
|
1022
|
-
>
|
|
1023
|
-
ticket
|
|
1024
|
-
</span>
|
|
1025
|
-
</div>
|
|
1026
|
-
</div>`;
|
|
1027
|
-
}
|
|
1028
|
-
|
|
1029
|
-
return html`
|
|
1030
|
-
<div class="assigned active">
|
|
1031
|
-
<div style="text-align:center">
|
|
1032
|
-
${event.created_by
|
|
1033
|
-
? html` ${getDisplayName(event.created_by)} ${action} this ticket `
|
|
1034
|
-
: html` This ticket was ${action} `}
|
|
1035
|
-
</div>
|
|
1036
|
-
<div class="subtext" style="justify-content:center">
|
|
1037
|
-
<temba-date
|
|
1038
|
-
class="time"
|
|
1039
|
-
value="${event.created_on}"
|
|
1040
|
-
display="duration"
|
|
1041
|
-
></temba-date>
|
|
1042
|
-
</div>
|
|
1043
|
-
</div>
|
|
1044
|
-
`;
|
|
1045
|
-
};
|
|
1046
|
-
|
|
1047
|
-
export const renderTicketAssigned = (event: TicketEvent): TemplateResult => {
|
|
1048
|
-
return html`
|
|
1049
|
-
<div class="assigned active">
|
|
1050
|
-
<div style="text-align:center">
|
|
1051
|
-
${event.assignee
|
|
1052
|
-
? event.assignee.id === event.created_by.id
|
|
1053
|
-
? html`${getDisplayName(event.created_by)} took this ticket`
|
|
1054
|
-
: html`${getDisplayName(event.created_by)} assigned this ticket to
|
|
1055
|
-
<div class="attn">${getDisplayName(event.assignee)}</div>`
|
|
1056
|
-
: html`${getDisplayName(event.created_by)} unassigned this ticket`}
|
|
1057
|
-
</div>
|
|
1058
|
-
<div class="subtext" style="justify-content:center">
|
|
1059
|
-
<temba-date
|
|
1060
|
-
class="time"
|
|
1061
|
-
value="${event.created_on}"
|
|
1062
|
-
display="duration"
|
|
1063
|
-
></temba-date>
|
|
1064
|
-
</div>
|
|
1065
|
-
</div>
|
|
1066
|
-
`;
|
|
1067
|
-
};
|
|
1068
|
-
|
|
1069
|
-
export const renderTicketOpened = (
|
|
1070
|
-
event: TicketEvent,
|
|
1071
|
-
handleClose: (uuid: string) => void,
|
|
1072
|
-
grouped: boolean
|
|
1073
|
-
): TemplateResult => {
|
|
1074
|
-
if (grouped) {
|
|
1075
|
-
return html`<div class="" style="display: flex">
|
|
1076
|
-
<temba-icon name="${Icon.inbox}"></temba-icon>
|
|
1077
|
-
<div class="description">
|
|
1078
|
-
${event.ticket.topic.name}
|
|
1079
|
-
<span
|
|
1080
|
-
class="linked"
|
|
1081
|
-
onclick="goto(event)"
|
|
1082
|
-
href="/ticket/all/open/${event.ticket.uuid}"
|
|
1083
|
-
>ticket</span
|
|
1084
|
-
>
|
|
1085
|
-
was opened
|
|
1086
|
-
</div>
|
|
1087
|
-
</div>`;
|
|
1088
|
-
} else {
|
|
1089
|
-
return html`
|
|
1090
|
-
<div>
|
|
1091
|
-
<div style="text-align:center">
|
|
1092
|
-
${getDisplayName(event.created_by)} opened this ticket
|
|
1093
|
-
</div>
|
|
1094
|
-
<div class="subtext" style="justify-content:center">
|
|
1095
|
-
<temba-date
|
|
1096
|
-
class="time"
|
|
1097
|
-
value="${event.created_on}"
|
|
1098
|
-
display="duration"
|
|
1099
|
-
></temba-date>
|
|
1100
|
-
</div>
|
|
1101
|
-
</div>
|
|
1102
|
-
`;
|
|
1103
|
-
}
|
|
1104
|
-
};
|
|
1105
|
-
|
|
1106
|
-
export const renderErrorMessage = (
|
|
1107
|
-
event: ErrorMessageEvent
|
|
1108
|
-
): TemplateResult => {
|
|
1109
|
-
return html`
|
|
1110
|
-
<temba-icon
|
|
1111
|
-
name="${Icon.error}"
|
|
1112
|
-
style="--icon-color:var(--color-error)"
|
|
1113
|
-
></temba-icon>
|
|
1114
|
-
<div class="description">
|
|
1115
|
-
${event.text}
|
|
1116
|
-
${event.type === Events.FAILURE
|
|
1117
|
-
? html`<div>Run ended prematurely, check the flow design.</div>`
|
|
1118
|
-
: null}
|
|
1119
|
-
</div>
|
|
1120
|
-
`;
|
|
1121
|
-
};
|
|
1122
|
-
|
|
1123
|
-
export const renderWebhookEvent = (event: WebhookEvent): TemplateResult => {
|
|
1124
|
-
return html`
|
|
1125
|
-
<div
|
|
1126
|
-
class="${event.status === 'success' ? '' : 'failed'}"
|
|
1127
|
-
style="display: flex"
|
|
1128
|
-
>
|
|
1129
|
-
<temba-icon name="${Icon.webhook}"></temba-icon>
|
|
1130
|
-
<div class="description">
|
|
1131
|
-
${event.status === 'success'
|
|
1132
|
-
? html`Successfully called ${event.url}`
|
|
1133
|
-
: html`Failed to call ${event.url}`}
|
|
1134
|
-
</div>
|
|
1135
|
-
</div>
|
|
1136
|
-
`;
|
|
1137
|
-
};
|
|
1138
|
-
|
|
1139
|
-
export const renderAirtimeTransferredEvent = (
|
|
1140
|
-
event: AirtimeTransferredEvent
|
|
1141
|
-
): TemplateResult => {
|
|
1142
|
-
if (parseFloat(event.actual_amount) === 0) {
|
|
1143
|
-
return html`<temba-icon
|
|
1144
|
-
name="${Icon.error}"
|
|
1145
|
-
style="--icon-color: var(--color-error)"
|
|
1146
|
-
></temba-icon>
|
|
1147
|
-
<div class="description error">Airtime transfer failed</div>`;
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
return html`<temba-icon name="${Icon.airtime}"></temba-icon>
|
|
1151
|
-
<div class="description">
|
|
1152
|
-
Transferred
|
|
1153
|
-
<div class="attn">${event.actual_amount} ${event.currency}</div>
|
|
1154
|
-
of airtime
|
|
1155
|
-
</div>`;
|
|
1156
|
-
};
|
|
1157
|
-
|
|
1158
|
-
export const renderCallStartedEvent = (): TemplateResult => {
|
|
1159
|
-
return html`<temba-icon name="${Icon.call}"></temba-icon>
|
|
1160
|
-
<div class="description">Call Started</div>`;
|
|
1161
|
-
};
|
|
1162
|
-
|
|
1163
|
-
export const renderContactLanguageChangedEvent = (
|
|
1164
|
-
event: ContactLanguageChangedEvent
|
|
1165
|
-
): TemplateResult => {
|
|
1166
|
-
return html`<temba-icon name="${Icon.contact_updated}"></temba-icon>
|
|
1167
|
-
<div class="description">
|
|
1168
|
-
Language updated to <span class="attn">${event.language}</span>
|
|
1169
|
-
</div>`;
|
|
1170
|
-
};
|
|
1171
|
-
|
|
1172
|
-
export const renderOptinRequested = (
|
|
1173
|
-
event: OptinRequestedEvent
|
|
1174
|
-
): TemplateResult => {
|
|
1175
|
-
return html`<temba-icon name="${Icon.optin_requested}"></temba-icon>
|
|
1176
|
-
<div class="description">
|
|
1177
|
-
Requested opt-in for <span class="attn">${event.optin.name}</span>
|
|
1178
|
-
</div>`;
|
|
1179
|
-
};
|
|
1180
|
-
|
|
1181
|
-
export const renderChannelEvent = (event: ChannelEvent): TemplateResult => {
|
|
1182
|
-
let eventMessage: string | TemplateResult = '';
|
|
1183
|
-
let icon = Icon.call;
|
|
1184
|
-
|
|
1185
|
-
if (event.event.type === 'mt_miss') {
|
|
1186
|
-
eventMessage = 'Missed outgoing call';
|
|
1187
|
-
icon = Icon.call_missed;
|
|
1188
|
-
} else if (event.event.type === 'mo_miss') {
|
|
1189
|
-
eventMessage = 'Missed incoming call';
|
|
1190
|
-
icon = Icon.call_missed;
|
|
1191
|
-
} else if (event.event.type === 'new_conversation') {
|
|
1192
|
-
eventMessage = 'Started Conversation';
|
|
1193
|
-
icon = Icon.event;
|
|
1194
|
-
} else if (event.channel_event_type === 'welcome_message') {
|
|
1195
|
-
eventMessage = 'Welcome Message Sent';
|
|
1196
|
-
icon = Icon.event;
|
|
1197
|
-
} else if (event.event.type === 'referral') {
|
|
1198
|
-
eventMessage = 'Referred';
|
|
1199
|
-
icon = Icon.event;
|
|
1200
|
-
} else if (event.event.type === 'follow') {
|
|
1201
|
-
eventMessage = 'Followed';
|
|
1202
|
-
icon = Icon.event;
|
|
1203
|
-
} else if (event.event.type === 'stop_contact') {
|
|
1204
|
-
eventMessage = 'Stopped';
|
|
1205
|
-
icon = Icon.contact_stopped;
|
|
1206
|
-
} else if (event.event.type === 'mt_call') {
|
|
1207
|
-
eventMessage = 'Outgoing Phone Call';
|
|
1208
|
-
} else if (event.event.type == 'mo_call') {
|
|
1209
|
-
eventMessage = 'Incoming Phone call';
|
|
1210
|
-
} else if (event.event.type == 'optin') {
|
|
1211
|
-
eventMessage = html`Opted in to
|
|
1212
|
-
<span class="attn">${event.event.optin?.name}</span>`;
|
|
1213
|
-
icon = Icon.optin;
|
|
1214
|
-
} else if (event.event.type == 'optout') {
|
|
1215
|
-
eventMessage = html`Opted out of
|
|
1216
|
-
<span class="attn">${event.event.optin?.name}</span>`;
|
|
1217
|
-
icon = Icon.optout;
|
|
1218
|
-
}
|
|
1219
|
-
|
|
1220
|
-
return html`<temba-icon name="${icon}"></temba-icon>
|
|
1221
|
-
<div class="description">${eventMessage}</div>`;
|
|
1222
|
-
};
|
|
1223
|
-
|
|
1224
|
-
export const renderCampaignFiredEvent = (
|
|
1225
|
-
event: CampaignFiredEvent
|
|
1226
|
-
): TemplateResult => {
|
|
1227
|
-
return html`<temba-icon name="${Icon.campaign}"></temba-icon>
|
|
1228
|
-
<div class="description">
|
|
1229
|
-
Campaign
|
|
1230
|
-
<span
|
|
1231
|
-
class="linked"
|
|
1232
|
-
onclick="goto(event, this)"
|
|
1233
|
-
href="/campaign/read/${event.campaign.uuid}/"
|
|
1234
|
-
>${event.campaign.name}</span
|
|
1235
|
-
>
|
|
1236
|
-
${event.fired_result === 'S' ? 'skipped' : 'triggered'}
|
|
1237
|
-
<span
|
|
1238
|
-
class="linked"
|
|
1239
|
-
onclick="goto(event, this)"
|
|
1240
|
-
href="/campaignevent/read/${event.campaign.uuid}/${event.campaign_event
|
|
1241
|
-
.id}/"
|
|
1242
|
-
>
|
|
1243
|
-
${event.campaign_event.offset_display}
|
|
1244
|
-
${event.campaign_event.relative_to.name}</span
|
|
1245
|
-
>
|
|
1246
|
-
</div>`;
|
|
1247
|
-
};
|
|
1248
|
-
|
|
1249
|
-
export const renderContactGroupsEvent = (
|
|
1250
|
-
event: ContactGroupsEvent
|
|
1251
|
-
): TemplateResult => {
|
|
1252
|
-
const groups = event.groups_added || event.groups_removed;
|
|
1253
|
-
const added = !!event.groups_added;
|
|
1254
|
-
return html`
|
|
1255
|
-
<temba-icon
|
|
1256
|
-
name="${Icon.users}"
|
|
1257
|
-
class="${getClasses({ added: added, removed: !added })}"
|
|
1258
|
-
></temba-icon>
|
|
1259
|
-
<div class="description">
|
|
1260
|
-
${added ? 'Added to' : 'Removed from'}
|
|
1261
|
-
${oxfordFn(
|
|
1262
|
-
groups,
|
|
1263
|
-
(group: ObjectReference) =>
|
|
1264
|
-
html`<span
|
|
1265
|
-
class="linked"
|
|
1266
|
-
onclick="goto(event)"
|
|
1267
|
-
href="/contact/filter/${group.uuid}"
|
|
1268
|
-
>${group.name}</span
|
|
1269
|
-
>`
|
|
1270
|
-
)}
|
|
1271
|
-
${event.type === Events.FAILURE
|
|
1272
|
-
? html`<div>Run ended prematurely, check the flow design.</div>`
|
|
1273
|
-
: null}
|
|
1274
|
-
</div>
|
|
1275
|
-
`;
|
|
1276
|
-
};
|