@nyaruka/temba-components 0.78.2 → 0.80.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/.devcontainer/Dockerfile +1 -1
- package/CHANGELOG.md +13 -15
- package/dist/static/svg/index.svg +1 -1
- package/dist/temba-components.js +8225 -0
- package/dist/temba-components.js.map +1 -0
- package/out-tsc/src/FormElement.js.map +1 -1
- package/out-tsc/src/RapidElement.js.map +1 -1
- package/out-tsc/src/RefreshElement.js.map +1 -1
- package/out-tsc/src/aliaseditor/AliasEditor.js.map +1 -1
- package/out-tsc/src/button/Button.js.map +1 -1
- package/out-tsc/src/charcount/CharCount.js.map +1 -1
- package/out-tsc/src/charcount/helpers.js.map +1 -1
- package/out-tsc/src/checkbox/Checkbox.js.map +1 -1
- package/out-tsc/src/colorpicker/ColorPicker.js.map +1 -1
- package/out-tsc/src/completion/Completion.js.map +1 -1
- package/out-tsc/src/completion/ExcellentParser.js.map +1 -1
- package/out-tsc/src/completion/helpers.js.map +1 -1
- package/out-tsc/src/compose/Compose.js.map +1 -1
- package/out-tsc/src/contacts/ContactBadges.js.map +1 -1
- package/out-tsc/src/contacts/ContactChat.js.map +1 -1
- package/out-tsc/src/contacts/ContactDetails.js.map +1 -1
- package/out-tsc/src/contacts/ContactFieldEditor.js.map +1 -1
- package/out-tsc/src/contacts/ContactFields.js.map +1 -1
- package/out-tsc/src/contacts/ContactHistory.js.map +1 -1
- package/out-tsc/src/contacts/ContactNameFetch.js.map +1 -1
- package/out-tsc/src/contacts/ContactPending.js.map +1 -1
- package/out-tsc/src/contacts/ContactStoreElement.js.map +1 -1
- package/out-tsc/src/contacts/ContactTickets.js.map +1 -1
- package/out-tsc/src/contacts/events.js.map +1 -1
- package/out-tsc/src/contacts/helpers.js.map +1 -1
- package/out-tsc/src/contactsearch/ContactSearch.js.map +1 -1
- package/out-tsc/src/date/TembaDate.js.map +1 -1
- package/out-tsc/src/datepicker/DatePicker.js.map +1 -1
- package/out-tsc/src/dialog/Dialog.js.map +1 -1
- package/out-tsc/src/dialog/Modax.js.map +1 -1
- package/out-tsc/src/dropdown/Dropdown.js.map +1 -1
- package/out-tsc/src/fields/FieldManager.js.map +1 -1
- package/out-tsc/src/flow/FlowStoreElement.js.map +1 -1
- package/out-tsc/src/formfield/FormField.js.map +1 -1
- package/out-tsc/src/imagepicker/ImagePicker.js.map +1 -1
- package/out-tsc/src/label/Label.js.map +1 -1
- package/out-tsc/src/leafletmap/LeafletMap.js.map +1 -1
- package/out-tsc/src/lightbox/Lightbox.js.map +1 -1
- package/out-tsc/src/list/ContentMenu.js.map +1 -1
- package/out-tsc/src/list/NotificationList.js.map +1 -1
- package/out-tsc/src/list/RunList.js.map +1 -1
- package/out-tsc/src/list/SortableList.js.map +1 -1
- package/out-tsc/src/list/TembaList.js.map +1 -1
- package/out-tsc/src/list/TembaMenu.js.map +1 -1
- package/out-tsc/src/list/TicketList.js.map +1 -1
- package/out-tsc/src/mask/Mask.js.map +1 -1
- package/out-tsc/src/omnibox/Omnibox.js.map +1 -1
- package/out-tsc/src/options/Options.js.map +1 -1
- package/out-tsc/src/options/helpers.js.map +1 -1
- package/out-tsc/src/remote/Remote.js.map +1 -1
- package/out-tsc/src/resizer/Resizer.js.map +1 -1
- package/out-tsc/src/select/Select.js +3 -3
- package/out-tsc/src/select/Select.js.map +1 -1
- package/out-tsc/src/shadowless/Shadowless.js.map +1 -1
- package/out-tsc/src/slider/TembaSlider.js.map +1 -1
- package/out-tsc/src/sms/gsmsplitter.js.map +1 -1
- package/out-tsc/src/sms/gsmvalidator.js.map +1 -1
- package/out-tsc/src/sms/index.js.map +1 -1
- package/out-tsc/src/sms/unicodesplitter.js.map +1 -1
- package/out-tsc/src/store/Store.js +2 -2
- package/out-tsc/src/store/Store.js.map +1 -1
- package/out-tsc/src/store/StoreElement.js.map +1 -1
- package/out-tsc/src/store/StoreMonitorElement.js.map +1 -1
- package/out-tsc/src/tabpane/TabPane.js.map +1 -1
- package/out-tsc/src/templates/TemplateEditor.js.map +1 -1
- package/out-tsc/src/textinput/TextInput.js.map +1 -1
- package/out-tsc/src/textinput/helpers.js.map +1 -1
- package/out-tsc/src/thumbnail/Thumbnail.js.map +1 -1
- package/out-tsc/src/tip/Tip.js.map +1 -1
- package/out-tsc/src/user/TembaUser.js.map +1 -1
- package/out-tsc/src/utils/index.js.map +1 -1
- package/out-tsc/src/vectoricon/VectorIcon.js.map +1 -1
- package/out-tsc/src/vectoricon/index.js +1 -1
- package/out-tsc/src/vectoricon/index.js.map +1 -1
- package/out-tsc/src/webchat/WebChat.js +109 -40
- package/out-tsc/src/webchat/WebChat.js.map +1 -1
- package/out-tsc/temba-components.js +1 -0
- package/out-tsc/temba-components.js.map +1 -1
- package/out-tsc/temba-modules.js.map +1 -1
- package/out-tsc/temba-webchat.js +10 -0
- package/out-tsc/temba-webchat.js.map +1 -0
- package/out-tsc/test/temba-compose.test.js.map +1 -1
- package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
- package/out-tsc/test/temba-contact-history.test.js.map +1 -1
- package/out-tsc/test/temba-content-menu.test.js.map +1 -1
- package/out-tsc/test/temba-list.test.js.map +1 -1
- package/out-tsc/test/temba-modax.test.js.map +1 -1
- package/out-tsc/test/temba-select.test.js.map +1 -1
- package/out-tsc/test/temba-sortable-list.test.js +2 -2
- package/out-tsc/test/temba-sortable-list.test.js.map +1 -1
- package/out-tsc/test/utils.test.js.map +1 -1
- package/package.json +28 -21
- package/rollup.components.mjs +45 -0
- package/rollup.webchat.mjs +11 -0
- package/src/select/Select.ts +3 -3
- package/src/store/Store.ts +2 -2
- package/src/untyped.d.ts +5 -0
- package/src/vectoricon/VectorIcon.ts +0 -1
- package/src/vectoricon/index.ts +1 -1
- package/src/webchat/WebChat.ts +110 -40
- package/static/svg/index.svg +1 -1
- package/static/svg/work/traced/agent.svg +1 -1
- package/static/svg/work/traced/channel-facebook.svg +1 -1
- package/static/svg/work/traced/channel-rocketchat.svg +1 -1
- package/static/svg/work/traced/channel-thinq.svg +1 -1
- package/static/svg/work/traced/channel-vonage.svg +1 -1
- package/static/svg/work/traced/zendesk.svg +1 -1
- package/temba-components.ts +1 -0
- package/temba-webchat.ts +11 -0
- package/test/temba-sortable-list.test.ts +2 -2
- package/dist/49b5238f.js +0 -7999
- package/dist/index.js +0 -7999
- package/dist/sw.js +0 -2
- package/dist/sw.js.map +0 -1
- package/dist/templates/components-body.html +0 -1
- package/dist/templates/components-head.html +0 -1
- package/dist/workbox-919adfb7.js +0 -2
- package/dist/workbox-919adfb7.js.map +0 -1
- package/rollup.config.js +0 -83
package/src/untyped.d.ts
CHANGED
package/src/vectoricon/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// for cache busting we dynamically generate a fingerprint, use yarn svg to update
|
|
2
|
-
export const SVG_FINGERPRINT = '
|
|
2
|
+
export const SVG_FINGERPRINT = 'e5bcaf1a10896e9b870da4b40474d67b';
|
|
3
3
|
|
|
4
4
|
// only icons below are included in the sprite sheet
|
|
5
5
|
export enum Icon {
|
package/src/webchat/WebChat.ts
CHANGED
|
@@ -10,6 +10,12 @@ interface Message {
|
|
|
10
10
|
timestamp: number;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
enum ChatStatus {
|
|
14
|
+
DISCONNECTED = 'disconnected',
|
|
15
|
+
CONNECTING = 'connecting',
|
|
16
|
+
CONNECTED = 'connected',
|
|
17
|
+
}
|
|
18
|
+
|
|
13
19
|
// how long of a window to show time between batches
|
|
14
20
|
const BATCH_TIME_WINDOW = 30 * 60 * 1000;
|
|
15
21
|
|
|
@@ -38,6 +44,7 @@ export class WebChat extends LitElement {
|
|
|
38
44
|
align-self: center;
|
|
39
45
|
--curvature: 0.6em;
|
|
40
46
|
--color-primary: hsla(208, 70%, 55%, 1);
|
|
47
|
+
font-family: 'Roboto', 'Helvetica Neue', sans-serif;
|
|
41
48
|
}
|
|
42
49
|
|
|
43
50
|
.block {
|
|
@@ -231,8 +238,8 @@ export class WebChat extends LitElement {
|
|
|
231
238
|
}
|
|
232
239
|
|
|
233
240
|
.input.inactive {
|
|
234
|
-
//pointer-events: none;
|
|
235
|
-
//opacity: 0.3;
|
|
241
|
+
// pointer-events: none;
|
|
242
|
+
// opacity: 0.3;
|
|
236
243
|
}
|
|
237
244
|
|
|
238
245
|
.active {
|
|
@@ -250,6 +257,33 @@ export class WebChat extends LitElement {
|
|
|
250
257
|
pointer-events: initial;
|
|
251
258
|
transform: rotate(0deg);
|
|
252
259
|
}
|
|
260
|
+
|
|
261
|
+
.notice {
|
|
262
|
+
padding: 1em;
|
|
263
|
+
background: #f8f8f8;
|
|
264
|
+
color: #666;
|
|
265
|
+
text-align: center;
|
|
266
|
+
cursor: pointer;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.connecting .notice {
|
|
270
|
+
display: flex;
|
|
271
|
+
justify-content: center;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.connecting .notice temba-icon {
|
|
275
|
+
margin-left: 0.5em;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.reconnect {
|
|
279
|
+
color: var(--color-primary);
|
|
280
|
+
text-decoration: underline;
|
|
281
|
+
font-size: 0.9em;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
.input:disabled {
|
|
285
|
+
background: transparent !important;
|
|
286
|
+
}
|
|
253
287
|
`;
|
|
254
288
|
}
|
|
255
289
|
|
|
@@ -263,8 +297,8 @@ export class WebChat extends LitElement {
|
|
|
263
297
|
messages: Message[][] = [];
|
|
264
298
|
|
|
265
299
|
// is our socket connection established
|
|
266
|
-
@property({ type:
|
|
267
|
-
|
|
300
|
+
@property({ type: String })
|
|
301
|
+
status: ChatStatus = ChatStatus.DISCONNECTED;
|
|
268
302
|
|
|
269
303
|
// is the chat widget open
|
|
270
304
|
@property({ type: Boolean })
|
|
@@ -279,37 +313,45 @@ export class WebChat extends LitElement {
|
|
|
279
313
|
@property({ type: Boolean, attribute: false })
|
|
280
314
|
hideBottomScroll = true;
|
|
281
315
|
|
|
316
|
+
@property({ type: String })
|
|
317
|
+
host: string;
|
|
318
|
+
|
|
282
319
|
private sock: WebSocket;
|
|
283
320
|
|
|
284
321
|
public constructor() {
|
|
285
322
|
super();
|
|
286
323
|
}
|
|
287
324
|
|
|
325
|
+
private handleReconnect() {
|
|
326
|
+
this.openSocket();
|
|
327
|
+
}
|
|
328
|
+
|
|
288
329
|
private openSocket(): void {
|
|
289
|
-
|
|
330
|
+
if (this.status !== ChatStatus.DISCONNECTED) {
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
this.status = ChatStatus.CONNECTING;
|
|
290
335
|
const webChat = this;
|
|
291
|
-
let url = `ws://localhost:8070/start
|
|
336
|
+
let url = `ws://localhost:8070/start/${this.channel}/`;
|
|
292
337
|
if (this.urn) {
|
|
293
|
-
url = `${url}
|
|
338
|
+
url = `${url}?chat_id=${this.urn}`;
|
|
294
339
|
}
|
|
295
340
|
this.sock = new WebSocket(url);
|
|
296
341
|
this.sock.onclose = function (event) {
|
|
297
|
-
|
|
298
|
-
webChat.active = false;
|
|
342
|
+
webChat.status = ChatStatus.DISCONNECTED;
|
|
299
343
|
};
|
|
300
344
|
this.sock.onmessage = function (event) {
|
|
301
|
-
|
|
345
|
+
webChat.status = ChatStatus.CONNECTED;
|
|
302
346
|
const msg = JSON.parse(event.data) as Message;
|
|
303
347
|
if (msg.type === 'chat_started') {
|
|
304
348
|
if (webChat.urn !== msg.identifier) {
|
|
305
349
|
webChat.messages = [];
|
|
306
350
|
}
|
|
307
351
|
webChat.urn = msg.identifier;
|
|
308
|
-
webChat.active = true;
|
|
309
352
|
webChat.requestUpdate('messages');
|
|
310
353
|
} else if (msg.type === 'chat_resumed') {
|
|
311
354
|
webChat.urn = msg.identifier;
|
|
312
|
-
webChat.active = true;
|
|
313
355
|
} else if (msg.type === 'msg_out') {
|
|
314
356
|
msg['timestamp'] = new Date().getTime();
|
|
315
357
|
webChat.addMessage(msg);
|
|
@@ -319,7 +361,6 @@ export class WebChat extends LitElement {
|
|
|
319
361
|
}
|
|
320
362
|
|
|
321
363
|
private restoreFromLocal(): void {
|
|
322
|
-
console.log('Restoring from localStorage..');
|
|
323
364
|
const data = JSON.parse(localStorage.getItem('temba-chat') || '{}');
|
|
324
365
|
const urn = 'urn' in data ? data['urn'] : null;
|
|
325
366
|
if (urn && !this.urn) {
|
|
@@ -345,7 +386,9 @@ export class WebChat extends LitElement {
|
|
|
345
386
|
|
|
346
387
|
private focusInput() {
|
|
347
388
|
const input = this.shadowRoot.querySelector('.input') as any;
|
|
348
|
-
input
|
|
389
|
+
if (input) {
|
|
390
|
+
input.focus();
|
|
391
|
+
}
|
|
349
392
|
}
|
|
350
393
|
|
|
351
394
|
public updated(
|
|
@@ -359,13 +402,18 @@ export class WebChat extends LitElement {
|
|
|
359
402
|
this.hideBottomScroll = true;
|
|
360
403
|
this.hideTopScroll = !hasScroll;
|
|
361
404
|
this.scrollToBottom();
|
|
362
|
-
this.focusInput();
|
|
363
405
|
|
|
364
|
-
if (
|
|
406
|
+
if (this.status === ChatStatus.DISCONNECTED) {
|
|
365
407
|
this.openSocket();
|
|
366
408
|
}
|
|
367
409
|
}
|
|
368
410
|
|
|
411
|
+
if (changed.has('status')) {
|
|
412
|
+
if (this.status === ChatStatus.CONNECTED) {
|
|
413
|
+
this.focusInput();
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
369
417
|
if (changed.has('channel')) {
|
|
370
418
|
this.restoreFromLocal();
|
|
371
419
|
}
|
|
@@ -404,7 +452,7 @@ export class WebChat extends LitElement {
|
|
|
404
452
|
}
|
|
405
453
|
|
|
406
454
|
private sendPendingMessage() {
|
|
407
|
-
if (this.
|
|
455
|
+
if (this.status === ChatStatus.CONNECTED) {
|
|
408
456
|
const input = this.shadowRoot.querySelector('.input') as any;
|
|
409
457
|
const text = input.value;
|
|
410
458
|
input.value = '';
|
|
@@ -512,10 +560,11 @@ export class WebChat extends LitElement {
|
|
|
512
560
|
public render(): TemplateResult {
|
|
513
561
|
return html`
|
|
514
562
|
<div
|
|
515
|
-
class="chat ${this.
|
|
516
|
-
|
|
517
|
-
? 'scroll-at-bottom'
|
|
518
|
-
|
|
563
|
+
class="chat ${this.status} ${this.hideTopScroll
|
|
564
|
+
? 'scroll-at-top'
|
|
565
|
+
: ''} ${this.hideBottomScroll ? 'scroll-at-bottom' : ''} ${this.open
|
|
566
|
+
? 'open'
|
|
567
|
+
: ''}"
|
|
519
568
|
>
|
|
520
569
|
<div class="messages">
|
|
521
570
|
<div class="scroll" @scroll=${this.handleScroll}>
|
|
@@ -527,25 +576,46 @@ export class WebChat extends LitElement {
|
|
|
527
576
|
: null}
|
|
528
577
|
</div>
|
|
529
578
|
</div>
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
579
|
+
|
|
580
|
+
${this.status === ChatStatus.DISCONNECTED
|
|
581
|
+
? html`<div class="notice">
|
|
582
|
+
<div>This chat is not currently connected.</div>
|
|
583
|
+
<div class="reconnect" @click=${this.handleReconnect}>
|
|
584
|
+
Click here to reconnect
|
|
585
|
+
<div></div>
|
|
586
|
+
</div>
|
|
587
|
+
</div>`
|
|
588
|
+
: null}
|
|
589
|
+
${this.status === ChatStatus.CONNECTING
|
|
590
|
+
? html`<div class="notice">
|
|
591
|
+
<div>Connecting</div>
|
|
592
|
+
<temba-icon name="progress_spinner" spin></temba-icon>
|
|
593
|
+
</div>`
|
|
594
|
+
: null}
|
|
595
|
+
${this.status === ChatStatus.CONNECTED
|
|
596
|
+
? html` <div
|
|
597
|
+
class="row input-panel ${this.hasPendingText ? 'pending' : ''}"
|
|
598
|
+
@click=${this.handleClickInputPanel}
|
|
599
|
+
>
|
|
600
|
+
<input
|
|
601
|
+
class="input ${this.status === ChatStatus.CONNECTED
|
|
602
|
+
? 'active'
|
|
603
|
+
: 'inactive'}"
|
|
604
|
+
type="text"
|
|
605
|
+
placeholder="Message.."
|
|
606
|
+
?disabled=${this.status !== ChatStatus.CONNECTED}
|
|
607
|
+
@keydown=${this.handleKeyUp}
|
|
608
|
+
/>
|
|
609
|
+
<temba-icon
|
|
610
|
+
tabindex="1"
|
|
611
|
+
class="send-icon"
|
|
612
|
+
name="send"
|
|
613
|
+
size="1"
|
|
614
|
+
clickable
|
|
615
|
+
@click=${this.sendPendingMessage}
|
|
616
|
+
></temba-icon>
|
|
617
|
+
</div>`
|
|
618
|
+
: null}
|
|
549
619
|
</div>
|
|
550
620
|
|
|
551
621
|
<div @click=${this.toggleChat}>
|