@nyaruka/temba-components 0.113.0 → 0.114.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 +21 -2
- package/demo/index.html +1 -1
- package/dist/temba-components.js +793 -966
- package/dist/temba-components.js.map +1 -1
- package/out-tsc/src/aliaseditor/AliasEditor.js.map +1 -1
- package/out-tsc/src/button/Button.js +6 -2
- package/out-tsc/src/button/Button.js.map +1 -1
- package/out-tsc/src/chat/Chat.js +29 -7
- package/out-tsc/src/chat/Chat.js.map +1 -1
- package/out-tsc/src/compose/Compose.js +10 -5
- package/out-tsc/src/compose/Compose.js.map +1 -1
- package/out-tsc/src/contacts/ContactChat.js +240 -114
- package/out-tsc/src/contacts/ContactChat.js.map +1 -1
- package/out-tsc/src/contacts/ContactFieldEditor.js.map +1 -1
- package/out-tsc/src/contacts/events.js.map +1 -1
- package/out-tsc/src/contacts/helpers.js +5 -1
- package/out-tsc/src/contacts/helpers.js.map +1 -1
- package/out-tsc/src/contactsearch/ContactSearch.js +1 -1
- package/out-tsc/src/contactsearch/ContactSearch.js.map +1 -1
- package/out-tsc/src/dropdown/Dropdown.js +121 -108
- package/out-tsc/src/dropdown/Dropdown.js.map +1 -1
- package/out-tsc/src/interfaces.js +2 -0
- package/out-tsc/src/interfaces.js.map +1 -1
- package/out-tsc/src/list/ContentMenu.js +11 -8
- package/out-tsc/src/list/ContentMenu.js.map +1 -1
- package/out-tsc/src/list/RunList.js.map +1 -1
- package/out-tsc/src/list/TembaList.js +21 -14
- package/out-tsc/src/list/TembaList.js.map +1 -1
- package/out-tsc/src/list/TembaMenu.js +11 -12
- package/out-tsc/src/list/TembaMenu.js.map +1 -1
- package/out-tsc/src/list/TicketList.js +10 -0
- package/out-tsc/src/list/TicketList.js.map +1 -1
- package/out-tsc/src/omnibox/Omnibox.js +33 -90
- package/out-tsc/src/omnibox/Omnibox.js.map +1 -1
- package/out-tsc/src/options/Options.js +49 -47
- package/out-tsc/src/options/Options.js.map +1 -1
- package/out-tsc/src/select/PopupSelect.js +57 -0
- package/out-tsc/src/select/PopupSelect.js.map +1 -0
- package/out-tsc/src/select/Select.js +194 -144
- package/out-tsc/src/select/Select.js.map +1 -1
- package/out-tsc/src/select/UserSelect.js +67 -0
- package/out-tsc/src/select/UserSelect.js.map +1 -0
- package/out-tsc/src/store/Store.js +65 -14
- package/out-tsc/src/store/Store.js.map +1 -1
- package/out-tsc/src/tabpane/TabPane.js +72 -115
- package/out-tsc/src/tabpane/TabPane.js.map +1 -1
- package/out-tsc/src/textinput/TextInput.js +1 -0
- package/out-tsc/src/textinput/TextInput.js.map +1 -1
- package/out-tsc/src/user/TembaUser.js +24 -37
- package/out-tsc/src/user/TembaUser.js.map +1 -1
- package/out-tsc/src/utils/index.js +13 -6
- package/out-tsc/src/utils/index.js.map +1 -1
- package/out-tsc/temba-modules.js +4 -2
- package/out-tsc/temba-modules.js.map +1 -1
- package/out-tsc/test/temba-omnibox.test.js +43 -4
- package/out-tsc/test/temba-omnibox.test.js.map +1 -1
- package/out-tsc/test/temba-select.test.js +121 -65
- package/out-tsc/test/temba-select.test.js.map +1 -1
- package/out-tsc/test/utils.test.js +4 -0
- package/out-tsc/test/utils.test.js.map +1 -1
- package/package.json +1 -1
- package/screenshots/truth/compose/attachments-tab.png +0 -0
- package/screenshots/truth/compose/attachments-with-files-focused.png +0 -0
- package/screenshots/truth/compose/attachments-with-files.png +0 -0
- package/screenshots/truth/compose/intial-text.png +0 -0
- package/screenshots/truth/compose/no-counter.png +0 -0
- package/screenshots/truth/compose/wraps-text-and-spaces.png +0 -0
- package/screenshots/truth/compose/wraps-text-and-url.png +0 -0
- package/screenshots/truth/compose/wraps-text-no-spaces.png +0 -0
- package/screenshots/truth/contacts/chat-failure.png +0 -0
- package/screenshots/truth/contacts/chat-for-active-contact.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/content-menu/item-no-buttons.png +0 -0
- package/screenshots/truth/content-menu/items-and-buttons.png +0 -0
- package/screenshots/truth/omnibox/selected.png +0 -0
- package/screenshots/truth/select/enabled-multi-selection.png +0 -0
- package/screenshots/truth/select/endpoint-initial-value-updated.png +0 -0
- package/screenshots/truth/select/endpoint-initial-value.png +0 -0
- package/screenshots/truth/select/expressions.png +0 -0
- package/screenshots/truth/select/functions.png +0 -0
- package/screenshots/truth/select/initial-value.png +0 -0
- package/screenshots/truth/select/multi-with-endpoint.png +0 -0
- package/screenshots/truth/select/multiple-initial-values.png +0 -0
- package/screenshots/truth/select/selected-multi-test.png +0 -0
- package/screenshots/truth/select/static-initial-value.png +0 -0
- package/screenshots/truth/select/static-initial-via-selected.png +0 -0
- package/screenshots/truth/select/value-initial.png +0 -0
- package/src/aliaseditor/AliasEditor.ts +1 -1
- package/src/button/Button.ts +6 -2
- package/src/chat/Chat.ts +28 -6
- package/src/compose/Compose.ts +11 -6
- package/src/contacts/ContactChat.ts +260 -118
- package/src/contacts/ContactFieldEditor.ts +1 -1
- package/src/contacts/events.ts +1 -0
- package/src/contacts/helpers.ts +8 -1
- package/src/contactsearch/ContactSearch.ts +3 -3
- package/src/dropdown/Dropdown.ts +142 -103
- package/src/interfaces.ts +4 -1
- package/src/list/ContentMenu.ts +11 -9
- package/src/list/RunList.ts +3 -1
- package/src/list/TembaList.ts +24 -14
- package/src/list/TembaMenu.ts +14 -15
- package/src/list/TicketList.ts +11 -0
- package/src/omnibox/Omnibox.ts +34 -95
- package/src/options/Options.ts +57 -60
- package/src/select/PopupSelect.ts +53 -0
- package/src/select/Select.ts +182 -112
- package/src/select/UserSelect.ts +71 -0
- package/src/store/Store.ts +70 -21
- package/src/tabpane/TabPane.ts +79 -113
- package/src/textinput/TextInput.ts +1 -0
- package/src/user/TembaUser.ts +30 -41
- package/src/utils/index.ts +12 -8
- package/temba-modules.ts +4 -2
- package/test/temba-omnibox.test.ts +56 -4
- package/test/temba-select.test.ts +170 -56
- package/test/utils.test.ts +5 -0
- package/test-assets/select/omnibox.json +55 -0
- package/web-test-runner.config.mjs +16 -4
- package/out-tsc/src/contacts/ContactTickets.js +0 -462
- package/out-tsc/src/contacts/ContactTickets.js.map +0 -1
- package/out-tsc/test/temba-contact-tickets.test.js +0 -36
- package/out-tsc/test/temba-contact-tickets.test.js.map +0 -1
- package/src/contacts/ContactTickets.ts +0 -490
- package/test/temba-contact-tickets.test.ts +0 -52
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { css, html, PropertyValueMap, TemplateResult } from 'lit';
|
|
3
3
|
import { property } from 'lit/decorators.js';
|
|
4
4
|
import { Contact, CustomEventType, Ticket } from '../interfaces';
|
|
5
|
-
import { oxford, oxfordFn, postJSON } from '../utils';
|
|
5
|
+
import { fetchResults, oxford, oxfordFn, postJSON } from '../utils';
|
|
6
6
|
import { ContactStoreElement } from './ContactStoreElement';
|
|
7
7
|
import { Compose, ComposeValue } from '../compose/Compose';
|
|
8
8
|
import { fetchContactHistory, getDisplayName } from './helpers';
|
|
@@ -30,6 +30,8 @@ import {
|
|
|
30
30
|
import { Chat, ChatEvent, MessageType } from '../chat/Chat';
|
|
31
31
|
import { getUserDisplay } from '../webchat';
|
|
32
32
|
import { DEFAULT_AVATAR } from '../webchat/assets';
|
|
33
|
+
import { UserSelect } from '../select/UserSelect';
|
|
34
|
+
import { Select } from '../select/Select';
|
|
33
35
|
|
|
34
36
|
export enum Events {
|
|
35
37
|
MESSAGE_CREATED = 'msg_created',
|
|
@@ -253,6 +255,8 @@ export class ContactChat extends ContactStoreElement {
|
|
|
253
255
|
--compose-padding: 3px;
|
|
254
256
|
--compose-curvature: none;
|
|
255
257
|
border-top: 1px inset rgba(0, 0, 0, 0.05);
|
|
258
|
+
|
|
259
|
+
|
|
256
260
|
}
|
|
257
261
|
|
|
258
262
|
.chat-wrapper {
|
|
@@ -260,7 +264,7 @@ export class ContactChat extends ContactStoreElement {
|
|
|
260
264
|
flex-grow: 1;
|
|
261
265
|
flex-direction: column;
|
|
262
266
|
min-height: 0;
|
|
263
|
-
background:
|
|
267
|
+
background: #f9f9f9;
|
|
264
268
|
}
|
|
265
269
|
|
|
266
270
|
temba-contact-history {
|
|
@@ -300,9 +304,8 @@ export class ContactChat extends ContactStoreElement {
|
|
|
300
304
|
color: var(--color-link-primary-hover);
|
|
301
305
|
}
|
|
302
306
|
|
|
303
|
-
temba-button
|
|
304
|
-
|
|
305
|
-
--button-x: 12px;
|
|
307
|
+
temba-button {
|
|
308
|
+
margin: 0.1em 0.25em;
|
|
306
309
|
}
|
|
307
310
|
|
|
308
311
|
temba-completion {
|
|
@@ -319,6 +322,10 @@ export class ContactChat extends ContactStoreElement {
|
|
|
319
322
|
temba-compose {
|
|
320
323
|
border-top-right-radius: 0;
|
|
321
324
|
border-top-left-radius: 0;
|
|
325
|
+
--temba-tabs-options-padding: 0.5em 0.5em 0 0.5em;
|
|
326
|
+
--temba-tabs-border-left: none;
|
|
327
|
+
--temba-tabs-border-right: none;
|
|
328
|
+
--temba-tabs-border-bottom: none;
|
|
322
329
|
}
|
|
323
330
|
|
|
324
331
|
.error-gutter {
|
|
@@ -337,37 +344,42 @@ export class ContactChat extends ContactStoreElement {
|
|
|
337
344
|
|
|
338
345
|
temba-chat {
|
|
339
346
|
border-bottom: 1px solid #ddd;
|
|
347
|
+
background: linear-gradient(0deg, #fff, #fff);
|
|
348
|
+
--chat-border-in: 1px solid #eee;
|
|
349
|
+
--color-chat-out: var(--color-message)
|
|
350
|
+
);
|
|
340
351
|
}
|
|
341
352
|
|
|
342
|
-
.
|
|
353
|
+
.action-bar {
|
|
343
354
|
}
|
|
344
355
|
|
|
345
356
|
.in-flow {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
display: flex;
|
|
349
|
-
|
|
350
|
-
background: var(--color-primary-dark);
|
|
351
|
-
background: #777;
|
|
352
|
-
color: #fff;
|
|
357
|
+
border-radius: 0.8em;
|
|
353
358
|
align-items: center;
|
|
354
|
-
|
|
359
|
+
background: #666;
|
|
360
|
+
padding: 0.5em 1em;
|
|
361
|
+
margin: 1em;
|
|
362
|
+
margin-right: 2em;
|
|
363
|
+
display: inline-flex;
|
|
364
|
+
opacity: 0.9;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.in-flow:hover {
|
|
368
|
+
opacity: 1;
|
|
355
369
|
}
|
|
356
370
|
|
|
357
371
|
.in-flow .flow-name {
|
|
358
|
-
padding: 0.5em 1em;
|
|
359
372
|
display: flex;
|
|
360
|
-
|
|
373
|
+
color: #fff;
|
|
361
374
|
}
|
|
362
375
|
|
|
363
|
-
.in-flow a
|
|
364
|
-
.in-flow .interrupt {
|
|
376
|
+
.in-flow a {
|
|
365
377
|
font-weight: bold;
|
|
366
378
|
color: #fff;
|
|
367
379
|
}
|
|
368
380
|
|
|
369
|
-
.in-flow .interrupt {
|
|
370
|
-
|
|
381
|
+
.in-flow .interrupt-button {
|
|
382
|
+
margin-left: 1em;
|
|
371
383
|
}
|
|
372
384
|
|
|
373
385
|
.in-flow .interrupt {
|
|
@@ -390,26 +402,46 @@ export class ContactChat extends ContactStoreElement {
|
|
|
390
402
|
margin-right: 0.5em;
|
|
391
403
|
}
|
|
392
404
|
|
|
405
|
+
.in-ticket-wrapper {
|
|
406
|
+
}
|
|
407
|
+
|
|
393
408
|
.in-ticket {
|
|
394
|
-
--color-widget-border: transparent;
|
|
395
|
-
--color-widget-bg: transparent;
|
|
396
|
-
--widget-box-shadow: none;
|
|
397
|
-
--temba-select-selected-padding: 0.2em 0.8em;
|
|
398
|
-
--temba-select-min-height: 0;
|
|
399
|
-
--select-wrapper-bg: transparent;
|
|
400
|
-
--select-wrapper-shadow: none;
|
|
401
409
|
box-shadow: none;
|
|
402
|
-
padding: 0.5em;
|
|
410
|
+
padding: 0.5em 0.5em;
|
|
403
411
|
text-align: center;
|
|
404
|
-
|
|
412
|
+
align-items: center;
|
|
413
|
+
border-bottom: 1px solid #ddd;
|
|
405
414
|
display: flex;
|
|
406
415
|
box-shadow: none;
|
|
416
|
+
margin: 0em;
|
|
417
|
+
background: rgba(0, 0, 0, 0.03);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
temba-user {
|
|
421
|
+
border: 1px solid #ddd;
|
|
422
|
+
padding: 0.2em 0.5em;
|
|
423
|
+
border-radius: var(--curvature);
|
|
424
|
+
min-width: 10em;
|
|
425
|
+
background: #fff;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
temba-user:hover {
|
|
429
|
+
border: 1px solid #ddd;
|
|
430
|
+
background: #f9f9f9;
|
|
407
431
|
}
|
|
408
432
|
|
|
409
433
|
.assign-button {
|
|
410
434
|
--button-mask: #ebebeb;
|
|
411
435
|
color: #333;
|
|
412
|
-
margin
|
|
436
|
+
margin: 0.25em;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
temba-user-select {
|
|
440
|
+
width: 250px;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
temba-button {
|
|
444
|
+
--button-border: 1px solid #ddd;
|
|
413
445
|
}
|
|
414
446
|
`;
|
|
415
447
|
}
|
|
@@ -495,6 +527,17 @@ export class ContactChat extends ContactStoreElement {
|
|
|
495
527
|
this.reset();
|
|
496
528
|
this.fetchPreviousMessages();
|
|
497
529
|
}
|
|
530
|
+
|
|
531
|
+
if (changedProperties.has('currentTicket')) {
|
|
532
|
+
const users = this.shadowRoot.querySelector(
|
|
533
|
+
'temba-user-select'
|
|
534
|
+
) as UserSelect;
|
|
535
|
+
if (users) {
|
|
536
|
+
users.setValues(
|
|
537
|
+
this.currentTicket?.assignee ? [this.currentTicket?.assignee] : []
|
|
538
|
+
);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
498
541
|
}
|
|
499
542
|
|
|
500
543
|
private reset() {
|
|
@@ -738,14 +781,15 @@ export class ContactChat extends ContactStoreElement {
|
|
|
738
781
|
|
|
739
782
|
private getUserForEvent(event: MsgEvent | TicketEvent) {
|
|
740
783
|
let user = null;
|
|
741
|
-
if (event.
|
|
784
|
+
if (event.type === 'msg_received') {
|
|
742
785
|
user = {
|
|
743
|
-
|
|
744
|
-
name: `${event.created_by.first_name} ${event.created_by.last_name}`.trim()
|
|
786
|
+
name: this.currentContact.name
|
|
745
787
|
};
|
|
746
|
-
} else if (event.
|
|
788
|
+
} else if (event.created_by) {
|
|
747
789
|
user = {
|
|
748
|
-
|
|
790
|
+
email: event.created_by.email,
|
|
791
|
+
name: `${event.created_by.first_name} ${event.created_by.last_name}`.trim(),
|
|
792
|
+
avatar: event.created_by.avatar
|
|
749
793
|
};
|
|
750
794
|
}
|
|
751
795
|
return user;
|
|
@@ -908,15 +952,6 @@ export class ContactChat extends ContactStoreElement {
|
|
|
908
952
|
this.chat.fetching = false;
|
|
909
953
|
}
|
|
910
954
|
|
|
911
|
-
private getTembaContactHistory(): TemplateResult {
|
|
912
|
-
return html`<temba-chat
|
|
913
|
-
@temba-scroll-threshold=${this.fetchPreviousMessages}
|
|
914
|
-
@temba-fetch-complete=${this.fetchComplete}
|
|
915
|
-
avatar=${this.avatar}
|
|
916
|
-
agent
|
|
917
|
-
></temba-chat>`;
|
|
918
|
-
}
|
|
919
|
-
|
|
920
955
|
private getTembaCompose(): TemplateResult {
|
|
921
956
|
if (this.currentTicket) {
|
|
922
957
|
if (this.currentContact && this.currentContact.status !== 'active') {
|
|
@@ -949,6 +984,7 @@ export class ContactChat extends ContactStoreElement {
|
|
|
949
984
|
counter
|
|
950
985
|
autogrow
|
|
951
986
|
shortcuts
|
|
987
|
+
?embeddedTabs=${!this.currentTicket}
|
|
952
988
|
@temba-submitted=${this.handleSend.bind(this)}
|
|
953
989
|
>
|
|
954
990
|
</temba-compose>
|
|
@@ -964,83 +1000,189 @@ export class ContactChat extends ContactStoreElement {
|
|
|
964
1000
|
</div>`;
|
|
965
1001
|
}
|
|
966
1002
|
|
|
1003
|
+
private handleAssignmentChanged(evt: CustomEvent) {
|
|
1004
|
+
const users = evt.currentTarget as UserSelect;
|
|
1005
|
+
const assignee = users.values[0];
|
|
1006
|
+
this.assignTicket(assignee ? assignee.email : null);
|
|
1007
|
+
users.blur();
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
private handleTopicChanged(evt: CustomEvent) {
|
|
1011
|
+
const select = evt.target as Select<any>;
|
|
1012
|
+
const topic = select.values[0];
|
|
1013
|
+
|
|
1014
|
+
if (this.currentTicket.topic.uuid !== topic.uuid) {
|
|
1015
|
+
postJSON(`/api/v2/ticket_actions.json`, {
|
|
1016
|
+
tickets: [this.currentTicket.uuid],
|
|
1017
|
+
action: 'change_topic',
|
|
1018
|
+
topic: topic.uuid
|
|
1019
|
+
})
|
|
1020
|
+
.then(() => {
|
|
1021
|
+
this.refreshTicket();
|
|
1022
|
+
})
|
|
1023
|
+
.catch((response: any) => {
|
|
1024
|
+
console.error(response);
|
|
1025
|
+
});
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
public assignTicket(email: string) {
|
|
1030
|
+
// if its already assigned to use, it's a noop
|
|
1031
|
+
if (
|
|
1032
|
+
(this.currentTicket.assignee &&
|
|
1033
|
+
this.currentTicket.assignee.email === email) ||
|
|
1034
|
+
(this.currentTicket.assignee === null && email === null)
|
|
1035
|
+
) {
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
postJSON(`/api/v2/ticket_actions.json`, {
|
|
1040
|
+
tickets: [this.currentTicket.uuid],
|
|
1041
|
+
action: 'assign',
|
|
1042
|
+
assignee: email
|
|
1043
|
+
})
|
|
1044
|
+
.then(() => {
|
|
1045
|
+
this.refreshTicket();
|
|
1046
|
+
})
|
|
1047
|
+
.catch((response: any) => {
|
|
1048
|
+
console.error(response);
|
|
1049
|
+
});
|
|
1050
|
+
return true;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
public refreshTicket() {
|
|
1054
|
+
if (this.currentTicket) {
|
|
1055
|
+
fetchResults(`/api/v2/tickets.json?uuid=${this.currentTicket.uuid}`).then(
|
|
1056
|
+
(values) => {
|
|
1057
|
+
if (values.length > 0) {
|
|
1058
|
+
this.fireCustomEvent(CustomEventType.TicketUpdated, {
|
|
1059
|
+
ticket: values[0],
|
|
1060
|
+
previous: this.currentTicket
|
|
1061
|
+
});
|
|
1062
|
+
this.currentTicket = values[0];
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
);
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
private handleReopen() {
|
|
1070
|
+
const uuid = this.currentTicket.uuid;
|
|
1071
|
+
postJSON(`/api/v2/ticket_actions.json`, {
|
|
1072
|
+
tickets: [uuid],
|
|
1073
|
+
action: 'reopen'
|
|
1074
|
+
})
|
|
1075
|
+
.then(() => {
|
|
1076
|
+
this.refreshTicket();
|
|
1077
|
+
})
|
|
1078
|
+
.catch((response: any) => {
|
|
1079
|
+
console.error(response);
|
|
1080
|
+
});
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
private handleClose() {
|
|
1084
|
+
const uuid = this.currentTicket.uuid;
|
|
1085
|
+
postJSON(`/api/v2/ticket_actions.json`, {
|
|
1086
|
+
tickets: [uuid],
|
|
1087
|
+
action: 'close'
|
|
1088
|
+
})
|
|
1089
|
+
.then(() => {
|
|
1090
|
+
this.refreshTicket();
|
|
1091
|
+
})
|
|
1092
|
+
.catch((response: any) => {
|
|
1093
|
+
console.error(response);
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
|
|
967
1097
|
public render(): TemplateResult {
|
|
968
1098
|
const inFlow = this.currentContact && this.currentContact.flow;
|
|
969
1099
|
|
|
970
|
-
|
|
971
|
-
const
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1100
|
+
const inTicket = this.currentTicket;
|
|
1101
|
+
const ticketClosed = this.currentTicket && this.currentTicket.closed_on;
|
|
1102
|
+
|
|
1103
|
+
return html`<div class="chat-wrapper">
|
|
1104
|
+
${this.currentContact
|
|
1105
|
+
? html`<temba-chat
|
|
1106
|
+
@temba-scroll-threshold=${this.fetchPreviousMessages}
|
|
1107
|
+
@temba-fetch-complete=${this.fetchComplete}
|
|
1108
|
+
avatar=${this.avatar}
|
|
1109
|
+
agent
|
|
1110
|
+
>
|
|
1111
|
+
${inFlow
|
|
1112
|
+
? html`
|
|
1113
|
+
<div slot="footer" style="text-align:center;">
|
|
1114
|
+
<div class="in-flow">
|
|
1115
|
+
<div class="flow-name">
|
|
1116
|
+
<temba-icon name="flow" size="1.2"></temba-icon>
|
|
1117
|
+
<div>
|
|
1118
|
+
Currently in
|
|
1119
|
+
<a
|
|
1120
|
+
href="/flow/editor/${this.currentContact.flow
|
|
1121
|
+
.uuid}/"
|
|
1122
|
+
>${this.currentContact.flow.name}</a
|
|
1123
|
+
>
|
|
1124
|
+
</div>
|
|
1125
|
+
</div>
|
|
1126
|
+
${this.showInterrupt
|
|
1127
|
+
? html`<temba-button
|
|
1128
|
+
class="interrupt-button"
|
|
1129
|
+
destructive
|
|
1130
|
+
small
|
|
1131
|
+
@click=${this.handleInterrupt}
|
|
1132
|
+
name="Interrupt"
|
|
1133
|
+
>
|
|
1134
|
+
</temba-button>`
|
|
1135
|
+
: null}
|
|
1136
|
+
</div>
|
|
1137
|
+
</div>
|
|
1138
|
+
`
|
|
1139
|
+
: null}
|
|
1140
|
+
<div slot="footer"></div>
|
|
1141
|
+
</temba-chat>
|
|
1142
|
+
${inTicket
|
|
1143
|
+
? html`<div class="in-ticket-wrapper">
|
|
1144
|
+
<div class="in-ticket">
|
|
1145
|
+
<temba-user-select
|
|
1146
|
+
placeholder="Assign to.."
|
|
1147
|
+
searchable
|
|
1148
|
+
searchOnFocus
|
|
1149
|
+
clearable
|
|
1150
|
+
.values=${this.currentTicket.assignee
|
|
1151
|
+
? [this.currentTicket.assignee]
|
|
1152
|
+
: []}
|
|
1153
|
+
@change=${this.handleAssignmentChanged}
|
|
1154
|
+
?disabled=${ticketClosed}
|
|
1155
|
+
></temba-user-select>
|
|
1156
|
+
|
|
1157
|
+
<temba-select
|
|
1158
|
+
style="margin:0 0.5em; flex-grow:1"
|
|
1159
|
+
endpoint="/api/v2/topics.json"
|
|
1160
|
+
searchable
|
|
1161
|
+
valuekey="uuid"
|
|
1162
|
+
.values=${[this.currentTicket.topic]}
|
|
1163
|
+
@change=${this.handleTopicChanged}
|
|
1164
|
+
?disabled=${ticketClosed}
|
|
1165
|
+
></temba-select>
|
|
1166
|
+
|
|
1167
|
+
${this.currentTicket.closed_on
|
|
1168
|
+
? html`
|
|
1169
|
+
<temba-button
|
|
1170
|
+
name="Reopen"
|
|
1171
|
+
@click=${this.handleReopen}
|
|
1172
|
+
></temba-button>
|
|
1173
|
+
`
|
|
1174
|
+
: html`
|
|
1175
|
+
<temba-button
|
|
1176
|
+
name="Close"
|
|
1177
|
+
destructive
|
|
1178
|
+
@click=${this.handleClose}
|
|
1179
|
+
></temba-button>
|
|
1180
|
+
`}
|
|
991
1181
|
</div>
|
|
992
|
-
</div>
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
: null}
|
|
998
|
-
</div>
|
|
999
|
-
`
|
|
1000
|
-
: ''}
|
|
1001
|
-
${inTicket
|
|
1002
|
-
? html`<div class="in-ticket-wrapper">
|
|
1003
|
-
<div class="in-ticket">
|
|
1004
|
-
${this.currentTicket.assignee
|
|
1005
|
-
? html`<temba-user
|
|
1006
|
-
email=${this.currentTicket.assignee.email}
|
|
1007
|
-
scale="0.8"
|
|
1008
|
-
style="margin-right:0.25em;margin-bottom:-0.5em;margin-top:-0.5em;margin-right:0.5em;"
|
|
1009
|
-
></temba-user>`
|
|
1010
|
-
: html`<temba-button
|
|
1011
|
-
name="Assign"
|
|
1012
|
-
class="assign-button"
|
|
1013
|
-
light
|
|
1014
|
-
></temba-button>`}
|
|
1015
|
-
<temba-select
|
|
1016
|
-
searchable
|
|
1017
|
-
endpoint="/api/v2/topics.json"
|
|
1018
|
-
valueKey="uuid"
|
|
1019
|
-
.prepareOptions=${(options) => {
|
|
1020
|
-
options.forEach((option) => {
|
|
1021
|
-
option.icon = 'topic';
|
|
1022
|
-
});
|
|
1023
|
-
return options;
|
|
1024
|
-
}}
|
|
1025
|
-
values=${JSON.stringify([
|
|
1026
|
-
{ ...this.currentTicket.topic, icon: 'topic' }
|
|
1027
|
-
])}
|
|
1028
|
-
style="min-width:200px; max-width:300px;margin-right:0.5em;"
|
|
1029
|
-
>
|
|
1030
|
-
</temba-select>
|
|
1031
|
-
<div style="min-width:20px"></div>
|
|
1032
|
-
|
|
1033
|
-
${this.currentTicket.closed_on
|
|
1034
|
-
? html`reopen`
|
|
1035
|
-
: html`<div style="text-align:right;flex-grow:1">
|
|
1036
|
-
<temba-button name="Close"></temba-button>
|
|
1037
|
-
</div>`}
|
|
1038
|
-
</div>
|
|
1039
|
-
</div>`
|
|
1040
|
-
: ''}
|
|
1041
|
-
${tembaCompose}
|
|
1042
|
-
</div>
|
|
1043
|
-
`;
|
|
1044
|
-
return html`${contactHistoryAndChatbox}`;
|
|
1182
|
+
</div> `
|
|
1183
|
+
: null}
|
|
1184
|
+
${this.getTembaCompose()}`
|
|
1185
|
+
: null}
|
|
1186
|
+
</div>`;
|
|
1045
1187
|
}
|
|
1046
1188
|
}
|
|
@@ -359,7 +359,7 @@ export class ContactFieldEditor extends RapidElement {
|
|
|
359
359
|
}
|
|
360
360
|
|
|
361
361
|
public handleSelectChange(evt: CustomEvent) {
|
|
362
|
-
const select = evt.currentTarget as Select
|
|
362
|
+
const select = evt.currentTarget as Select<any>;
|
|
363
363
|
let value = '';
|
|
364
364
|
|
|
365
365
|
evt.preventDefault();
|
package/src/contacts/events.ts
CHANGED
package/src/contacts/helpers.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Contact, NamedUser, User } from '../interfaces';
|
|
2
|
+
import { Store } from '../store/Store';
|
|
2
3
|
import { fetchResults, getUrl, postUrl, WebResponse } from '../utils';
|
|
3
4
|
import { ContactHistoryPage } from './events';
|
|
4
5
|
|
|
@@ -59,6 +60,8 @@ export const fetchContactHistory = (
|
|
|
59
60
|
url += `&ticket=${ticket}`;
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
const store = document.querySelector('temba-store') as Store;
|
|
64
|
+
|
|
62
65
|
getUrl(url, controller)
|
|
63
66
|
.then((response: WebResponse) => {
|
|
64
67
|
// on success, remove our abort controller
|
|
@@ -67,7 +70,11 @@ export const fetchContactHistory = (
|
|
|
67
70
|
return response.controller === controller;
|
|
68
71
|
}
|
|
69
72
|
);
|
|
70
|
-
|
|
73
|
+
|
|
74
|
+
const page = response.json as ContactHistoryPage;
|
|
75
|
+
store.resolveUsers(page.events, ['created_by']).then(() => {
|
|
76
|
+
resolve(page);
|
|
77
|
+
});
|
|
71
78
|
})
|
|
72
79
|
.catch(() => {
|
|
73
80
|
// canceled
|
|
@@ -423,7 +423,7 @@ export class ContactSearch extends FormElement {
|
|
|
423
423
|
}
|
|
424
424
|
|
|
425
425
|
private handleActivityLevelChanged(evt: any) {
|
|
426
|
-
const select = evt.target as Select
|
|
426
|
+
const select = evt.target as Select<any>;
|
|
427
427
|
const option = select.values[0];
|
|
428
428
|
if (option) {
|
|
429
429
|
if (this.exclusions['not_seen_since_days']) {
|
|
@@ -455,7 +455,7 @@ export class ContactSearch extends FormElement {
|
|
|
455
455
|
if (checkbox.name === 'not_seen_since_days' && value) {
|
|
456
456
|
const select = checkbox.parentElement.querySelector(
|
|
457
457
|
'temba-select'
|
|
458
|
-
) as Select
|
|
458
|
+
) as Select<any>;
|
|
459
459
|
if (select.values[0]) {
|
|
460
460
|
value = parseInt(select.values[0].value);
|
|
461
461
|
} else {
|
|
@@ -563,7 +563,7 @@ export class ContactSearch extends FormElement {
|
|
|
563
563
|
.errors=${this.errors}
|
|
564
564
|
id="recipients"
|
|
565
565
|
name="recipients"
|
|
566
|
-
.
|
|
566
|
+
.values=${this.recipients}
|
|
567
567
|
endpoint="/contact/omnibox/?"
|
|
568
568
|
@change=${this.handleRecipientsChanged}
|
|
569
569
|
>
|