@nyaruka/temba-components 0.68.0 → 0.71.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 +12 -0
- package/dist/{dd629ee4.js → 2b9b9834.js} +274 -212
- package/dist/index.js +274 -212
- package/dist/sw.js +1 -1
- package/dist/sw.js.map +1 -1
- package/dist/templates/components-body.html +1 -1
- package/dist/templates/components-head.html +1 -1
- package/out-tsc/src/contacts/ContactHistory.js +20 -13
- package/out-tsc/src/contacts/ContactHistory.js.map +1 -1
- package/out-tsc/src/contacts/ContactTickets.js +27 -23
- package/out-tsc/src/contacts/ContactTickets.js.map +1 -1
- package/out-tsc/src/contacts/events.js +7 -8
- package/out-tsc/src/contacts/events.js.map +1 -1
- package/out-tsc/src/imagepicker/ImagePicker.js +3 -6
- package/out-tsc/src/imagepicker/ImagePicker.js.map +1 -1
- package/out-tsc/src/list/TicketList.js +4 -5
- package/out-tsc/src/list/TicketList.js.map +1 -1
- package/out-tsc/src/store/Store.js +3 -0
- package/out-tsc/src/store/Store.js.map +1 -1
- package/out-tsc/src/store/StoreElement.js +11 -30
- package/out-tsc/src/store/StoreElement.js.map +1 -1
- package/out-tsc/src/store/StoreMonitorElement.js +50 -0
- package/out-tsc/src/store/StoreMonitorElement.js.map +1 -0
- package/out-tsc/src/user/TembaUser.js +107 -0
- package/out-tsc/src/user/TembaUser.js.map +1 -0
- package/out-tsc/src/utils/index.js +1 -1
- package/out-tsc/src/utils/index.js.map +1 -1
- package/out-tsc/temba-modules.js +2 -0
- package/out-tsc/temba-modules.js.map +1 -1
- package/out-tsc/test/temba-contact-tickets.test.js +1 -1
- package/out-tsc/test/temba-contact-tickets.test.js.map +1 -1
- package/package.json +1 -1
- package/rollup.config.js +3 -0
- package/screenshots/truth/contacts/tickets-assignment.png +0 -0
- package/screenshots/truth/contacts/tickets.png +0 -0
- package/src/contacts/ContactHistory.ts +28 -14
- package/src/contacts/ContactTickets.ts +28 -34
- package/src/contacts/events.ts +8 -19
- package/src/imagepicker/ImagePicker.ts +3 -7
- package/src/list/TicketList.ts +4 -5
- package/src/store/Store.ts +4 -0
- package/src/store/StoreElement.ts +13 -38
- package/src/store/StoreMonitorElement.ts +61 -0
- package/src/user/TembaUser.ts +111 -0
- package/src/utils/index.ts +1 -2
- package/temba-modules.ts +2 -0
- package/templates/index.html +7 -4
- package/test/temba-contact-tickets.test.ts +1 -3
|
@@ -2,15 +2,12 @@ import { css, html, PropertyValueMap, TemplateResult } from 'lit';
|
|
|
2
2
|
import { property } from 'lit/decorators.js';
|
|
3
3
|
import { CustomEventType, Ticket, TicketStatus, User } from '../interfaces';
|
|
4
4
|
import { StoreElement } from '../store/StoreElement';
|
|
5
|
-
import {
|
|
6
|
-
getClasses,
|
|
7
|
-
getFullName,
|
|
8
|
-
postJSON,
|
|
9
|
-
renderAvatar,
|
|
10
|
-
stopEvent,
|
|
11
|
-
} from '../utils';
|
|
5
|
+
import { getClasses, postJSON, stopEvent } from '../utils';
|
|
12
6
|
import { Icon } from '../vectoricon';
|
|
13
7
|
|
|
8
|
+
const dropdownUserScale = 0.7;
|
|
9
|
+
const inlineUserScale = 0.8;
|
|
10
|
+
|
|
14
11
|
export class ContactTickets extends StoreElement {
|
|
15
12
|
@property({ type: String })
|
|
16
13
|
agent: string;
|
|
@@ -129,6 +126,10 @@ export class ContactTickets extends StoreElement {
|
|
|
129
126
|
border-bottom: 1px solid #f3f3f3;
|
|
130
127
|
}
|
|
131
128
|
|
|
129
|
+
.option-group temba-user {
|
|
130
|
+
flex-grow: 1;
|
|
131
|
+
}
|
|
132
|
+
|
|
132
133
|
.assigned .user {
|
|
133
134
|
flex-grow: 1;
|
|
134
135
|
}
|
|
@@ -164,9 +165,6 @@ export class ContactTickets extends StoreElement {
|
|
|
164
165
|
background: var(--color-selection);
|
|
165
166
|
}
|
|
166
167
|
|
|
167
|
-
.user .avatar {
|
|
168
|
-
}
|
|
169
|
-
|
|
170
168
|
.user .name {
|
|
171
169
|
display: -webkit-box;
|
|
172
170
|
-webkit-line-clamp: 1;
|
|
@@ -243,16 +241,6 @@ export class ContactTickets extends StoreElement {
|
|
|
243
241
|
}
|
|
244
242
|
}
|
|
245
243
|
|
|
246
|
-
private renderUser(user: User) {
|
|
247
|
-
if (!user) {
|
|
248
|
-
return null;
|
|
249
|
-
}
|
|
250
|
-
return html`<div class="user">
|
|
251
|
-
<div class="avatar">${renderAvatar({ user: user, scale: 0.6 })}</div>
|
|
252
|
-
<div class="name">${getFullName(user)}</div>
|
|
253
|
-
</div>`;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
244
|
private handleClose(uuid: string) {
|
|
257
245
|
postJSON(`/api/v2/ticket_actions.json`, {
|
|
258
246
|
tickets: [uuid],
|
|
@@ -285,6 +273,7 @@ export class ContactTickets extends StoreElement {
|
|
|
285
273
|
if (ticket.assignee && ticket.assignee.email === email) {
|
|
286
274
|
return;
|
|
287
275
|
}
|
|
276
|
+
this.blur();
|
|
288
277
|
|
|
289
278
|
postJSON(`/api/v2/ticket_actions.json`, {
|
|
290
279
|
tickets: [uuid],
|
|
@@ -352,13 +341,10 @@ export class ContactTickets extends StoreElement {
|
|
|
352
341
|
<div slot="toggle" class="toggle">
|
|
353
342
|
${ticket.assignee
|
|
354
343
|
? html`
|
|
355
|
-
<
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
scale: 0.7,
|
|
360
|
-
})}
|
|
361
|
-
</div>
|
|
344
|
+
<temba-user
|
|
345
|
+
email=${ticket.assignee.email}
|
|
346
|
+
scale="${inlineUserScale}"
|
|
347
|
+
></temba-user>
|
|
362
348
|
`
|
|
363
349
|
: html`
|
|
364
350
|
<temba-button
|
|
@@ -384,11 +370,11 @@ export class ContactTickets extends StoreElement {
|
|
|
384
370
|
? 'current-user'
|
|
385
371
|
: ''}"
|
|
386
372
|
>
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
373
|
+
<temba-user
|
|
374
|
+
email=${ticket.assignee.email}
|
|
375
|
+
name
|
|
376
|
+
scale="${dropdownUserScale}"
|
|
377
|
+
></temba-user>
|
|
392
378
|
<temba-button
|
|
393
379
|
name="Unassign"
|
|
394
380
|
primary
|
|
@@ -418,7 +404,11 @@ export class ContactTickets extends StoreElement {
|
|
|
418
404
|
);
|
|
419
405
|
}}
|
|
420
406
|
>
|
|
421
|
-
|
|
407
|
+
<temba-user
|
|
408
|
+
email=${agent.email}
|
|
409
|
+
name
|
|
410
|
+
scale="${dropdownUserScale}"
|
|
411
|
+
></temba-user>
|
|
422
412
|
</div>
|
|
423
413
|
`
|
|
424
414
|
: null}
|
|
@@ -444,7 +434,11 @@ export class ContactTickets extends StoreElement {
|
|
|
444
434
|
);
|
|
445
435
|
}}
|
|
446
436
|
>
|
|
447
|
-
|
|
437
|
+
<temba-user
|
|
438
|
+
email=${user.email}
|
|
439
|
+
scale="${dropdownUserScale}"
|
|
440
|
+
name
|
|
441
|
+
></temba-user>
|
|
448
442
|
</div>`;
|
|
449
443
|
})}
|
|
450
444
|
</div>
|
package/src/contacts/events.ts
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import { css,
|
|
1
|
+
import { css, html, TemplateResult } from 'lit';
|
|
2
2
|
import { Msg, ObjectReference, User } from '../interfaces';
|
|
3
|
-
import {
|
|
4
|
-
getClasses,
|
|
5
|
-
NamedObject,
|
|
6
|
-
oxford,
|
|
7
|
-
oxfordFn,
|
|
8
|
-
oxfordNamed,
|
|
9
|
-
renderAvatar,
|
|
10
|
-
} from '../utils';
|
|
3
|
+
import { getClasses, oxford, oxfordFn, oxfordNamed } from '../utils';
|
|
11
4
|
import { Icon } from '../vectoricon';
|
|
12
5
|
import { getDisplayName } from './helpers';
|
|
13
6
|
|
|
@@ -758,10 +751,7 @@ export const renderAttachment = (attachment: string): TemplateResult => {
|
|
|
758
751
|
return html`<div style="">${inner}</div>`;
|
|
759
752
|
};
|
|
760
753
|
|
|
761
|
-
export const renderMsgEvent = (
|
|
762
|
-
event: MsgEvent,
|
|
763
|
-
agent: string
|
|
764
|
-
): TemplateResult => {
|
|
754
|
+
export const renderMsgEvent = (event: MsgEvent): TemplateResult => {
|
|
765
755
|
const isInbound = event.type === Events.MESSAGE_RECEIVED;
|
|
766
756
|
const isError = event.status === 'E';
|
|
767
757
|
const isFailure = event.status === 'F';
|
|
@@ -874,9 +864,10 @@ export const renderMsgEvent = (
|
|
|
874
864
|
</div>
|
|
875
865
|
|
|
876
866
|
${!isInbound && event.created_by
|
|
877
|
-
? html`<
|
|
878
|
-
|
|
879
|
-
|
|
867
|
+
? html`<temba-user
|
|
868
|
+
style="margin-left:0.5em"
|
|
869
|
+
email=${event.created_by.email}
|
|
870
|
+
></temba-user>`
|
|
880
871
|
: null}
|
|
881
872
|
</div>`;
|
|
882
873
|
};
|
|
@@ -1010,9 +1001,7 @@ export const renderNoteCreated = (event: TicketEvent): TemplateResult => {
|
|
|
1010
1001
|
></temba-date>
|
|
1011
1002
|
</div>
|
|
1012
1003
|
</div>
|
|
1013
|
-
<
|
|
1014
|
-
${renderAvatar({ user: event.created_by })}
|
|
1015
|
-
</div>
|
|
1004
|
+
<temba-user email=${event.created_by.email}></temba-user>
|
|
1016
1005
|
</div>`;
|
|
1017
1006
|
};
|
|
1018
1007
|
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-this-alias */
|
|
2
2
|
import { html, css, PropertyValueMap } from 'lit';
|
|
3
|
-
import 'croppie/croppie.js';
|
|
4
3
|
import { CroppieCSS } from './CroppieCSS';
|
|
5
4
|
import { property } from 'lit/decorators.js';
|
|
6
5
|
import { Icon } from '../vectoricon';
|
|
@@ -166,11 +165,11 @@ export class ImagePicker extends FormElement {
|
|
|
166
165
|
wrapper.removeChild(wrapper.firstChild);
|
|
167
166
|
}
|
|
168
167
|
this.showCroppie = true;
|
|
169
|
-
const
|
|
170
|
-
wrapper.appendChild(
|
|
168
|
+
const ele = document.createElement('div');
|
|
169
|
+
wrapper.appendChild(ele);
|
|
171
170
|
|
|
172
171
|
const Croppie = (window as any).Croppie;
|
|
173
|
-
this.croppie = new Croppie(
|
|
172
|
+
this.croppie = new Croppie(ele, {
|
|
174
173
|
enableExif: true,
|
|
175
174
|
viewport: {
|
|
176
175
|
width: 300,
|
|
@@ -206,9 +205,6 @@ export class ImagePicker extends FormElement {
|
|
|
206
205
|
|
|
207
206
|
picker.value = fd;
|
|
208
207
|
picker.closeCroppie();
|
|
209
|
-
|
|
210
|
-
console.log('image changed', picker.name, picker.value, picker.url);
|
|
211
|
-
// picker.dispatchEvent(new CustomEvent('image-changed', { detail: resp }));
|
|
212
208
|
});
|
|
213
209
|
}
|
|
214
210
|
|
package/src/list/TicketList.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { property } from 'lit/decorators.js';
|
|
|
3
3
|
import { TembaList } from './TembaList';
|
|
4
4
|
import { Contact } from '../interfaces';
|
|
5
5
|
import { Icon } from '../vectoricon';
|
|
6
|
-
import { renderAvatar } from '../utils';
|
|
7
6
|
|
|
8
7
|
export class TicketList extends TembaList {
|
|
9
8
|
@property({ type: String })
|
|
@@ -76,10 +75,10 @@ export class TicketList extends TembaList {
|
|
|
76
75
|
>
|
|
77
76
|
<div>
|
|
78
77
|
${!contact.ticket.closed_on && contact.ticket.assignee
|
|
79
|
-
? html
|
|
80
|
-
|
|
81
|
-
scale
|
|
82
|
-
|
|
78
|
+
? html`<temba-user
|
|
79
|
+
email=${contact.ticket.assignee.email}
|
|
80
|
+
scale="0.8"
|
|
81
|
+
></temba-user>`
|
|
83
82
|
: null}
|
|
84
83
|
</div>
|
|
85
84
|
</div>
|
package/src/store/Store.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PropertyValueMap } from 'lit';
|
|
2
2
|
import { property } from 'lit/decorators.js';
|
|
3
3
|
import { CustomEventType } from '../interfaces';
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
import { Store } from './Store';
|
|
6
|
+
import { StoreMonitorElement } from './StoreMonitorElement';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* StoreElement is a listener for a given endpoint that re-renders
|
|
9
10
|
* when the underlying store element changes
|
|
10
11
|
*/
|
|
11
|
-
export class StoreElement extends
|
|
12
|
+
export class StoreElement extends StoreMonitorElement {
|
|
12
13
|
@property({ type: String })
|
|
13
14
|
url: string;
|
|
14
15
|
|
|
@@ -31,17 +32,15 @@ export class StoreElement extends RapidElement {
|
|
|
31
32
|
});
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
});
|
|
35
|
+
protected storeUpdated(event: CustomEvent) {
|
|
36
|
+
if (event.detail.url === this.url) {
|
|
37
|
+
const previous = this.data;
|
|
38
|
+
this.data = event.detail.data;
|
|
39
|
+
this.fireCustomEvent(CustomEventType.Refreshed, {
|
|
40
|
+
data: event.detail.data,
|
|
41
|
+
previous,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
45
44
|
}
|
|
46
45
|
|
|
47
46
|
protected updated(
|
|
@@ -59,30 +58,6 @@ export class StoreElement extends RapidElement {
|
|
|
59
58
|
|
|
60
59
|
connectedCallback(): void {
|
|
61
60
|
super.connectedCallback();
|
|
62
|
-
this.store = document.querySelector('temba-store') as Store;
|
|
63
|
-
this.handleStoreUpdated = this.handleStoreUpdated.bind(this);
|
|
64
61
|
this.prepareData = this.prepareData.bind(this);
|
|
65
|
-
if (this.store) {
|
|
66
|
-
this.store.addEventListener(
|
|
67
|
-
CustomEventType.StoreUpdated,
|
|
68
|
-
this.handleStoreUpdated
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
disconnectedCallback(): void {
|
|
74
|
-
super.disconnectedCallback();
|
|
75
|
-
if (this.store) {
|
|
76
|
-
this.store.removeEventListener(
|
|
77
|
-
CustomEventType.StoreUpdated,
|
|
78
|
-
this.handleStoreUpdated
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
public render(): TemplateResult {
|
|
84
|
-
if (!this.store.ready && this.showLoading) {
|
|
85
|
-
return html`<temba-loading></temba-loading>`;
|
|
86
|
-
}
|
|
87
62
|
}
|
|
88
63
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { html, PropertyValueMap, TemplateResult } from 'lit';
|
|
2
|
+
import { property } from 'lit/decorators.js';
|
|
3
|
+
import { CustomEventType } from '../interfaces';
|
|
4
|
+
import { RapidElement } from '../RapidElement';
|
|
5
|
+
import { Store } from './Store';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* StoreMonitorElement notifies when the store is updated and with what url
|
|
9
|
+
*/
|
|
10
|
+
export class StoreMonitorElement extends RapidElement {
|
|
11
|
+
@property({ type: String })
|
|
12
|
+
url: string;
|
|
13
|
+
|
|
14
|
+
@property({ type: Boolean })
|
|
15
|
+
showLoading = false;
|
|
16
|
+
|
|
17
|
+
store: Store;
|
|
18
|
+
|
|
19
|
+
private handleStoreUpdated(event: CustomEvent) {
|
|
20
|
+
this.store.initialHttpComplete.then(() => {
|
|
21
|
+
this.storeUpdated(event);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
|
|
26
|
+
protected storeUpdated(event: CustomEvent) {}
|
|
27
|
+
|
|
28
|
+
protected updated(
|
|
29
|
+
properties: PropertyValueMap<any> | Map<PropertyKey, unknown>
|
|
30
|
+
): void {
|
|
31
|
+
super.updated(properties);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
connectedCallback(): void {
|
|
35
|
+
super.connectedCallback();
|
|
36
|
+
this.store = document.querySelector('temba-store') as Store;
|
|
37
|
+
this.handleStoreUpdated = this.handleStoreUpdated.bind(this);
|
|
38
|
+
if (this.store) {
|
|
39
|
+
this.store.addEventListener(
|
|
40
|
+
CustomEventType.StoreUpdated,
|
|
41
|
+
this.handleStoreUpdated
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
disconnectedCallback(): void {
|
|
47
|
+
super.disconnectedCallback();
|
|
48
|
+
if (this.store) {
|
|
49
|
+
this.store.removeEventListener(
|
|
50
|
+
CustomEventType.StoreUpdated,
|
|
51
|
+
this.handleStoreUpdated
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public render(): TemplateResult {
|
|
57
|
+
if (!this.store.ready && this.showLoading) {
|
|
58
|
+
return html`<temba-loading></temba-loading>`;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { PropertyValueMap, TemplateResult, css, html } from 'lit';
|
|
2
|
+
import { property } from 'lit/decorators.js';
|
|
3
|
+
import { User } from '../interfaces';
|
|
4
|
+
import { StoreMonitorElement } from '../store/StoreMonitorElement';
|
|
5
|
+
import { colorHash, extractInitials } from '../utils';
|
|
6
|
+
|
|
7
|
+
export class TembaUser extends StoreMonitorElement {
|
|
8
|
+
public static styles = css`
|
|
9
|
+
:host {
|
|
10
|
+
display: flex;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.wrapper {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: row;
|
|
16
|
+
align-items: center;
|
|
17
|
+
flex-grow: 1;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.name {
|
|
21
|
+
flex-grow: 1;
|
|
22
|
+
display: -webkit-box;
|
|
23
|
+
-webkit-line-clamp: 1;
|
|
24
|
+
-webkit-box-orient: vertical;
|
|
25
|
+
overflow: hidden;
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
@property({ type: String })
|
|
30
|
+
email: string;
|
|
31
|
+
|
|
32
|
+
@property({ type: Number })
|
|
33
|
+
scale: number;
|
|
34
|
+
|
|
35
|
+
@property({ type: Boolean })
|
|
36
|
+
name: string;
|
|
37
|
+
|
|
38
|
+
@property({ type: Object, attribute: false })
|
|
39
|
+
user: User;
|
|
40
|
+
|
|
41
|
+
@property({ type: String, attribute: false })
|
|
42
|
+
background: string;
|
|
43
|
+
|
|
44
|
+
@property({ type: String, attribute: false })
|
|
45
|
+
initials: string;
|
|
46
|
+
|
|
47
|
+
@property({ type: String, attribute: false })
|
|
48
|
+
fullName: string;
|
|
49
|
+
|
|
50
|
+
public updated(
|
|
51
|
+
changed: PropertyValueMap<any> | Map<PropertyKey, unknown>
|
|
52
|
+
): void {
|
|
53
|
+
super.updated(changed);
|
|
54
|
+
if (changed.has('email')) {
|
|
55
|
+
this.user = this.store.getUser(this.email);
|
|
56
|
+
if (this.user) {
|
|
57
|
+
this.fullName = [this.user.first_name, this.user.last_name].join(' ');
|
|
58
|
+
if (this.user.avatar) {
|
|
59
|
+
this.background = `url('${this.user.avatar}') center / contain no-repeat`;
|
|
60
|
+
this.initials = '';
|
|
61
|
+
} else {
|
|
62
|
+
this.background = colorHash.hex(this.fullName);
|
|
63
|
+
this.initials = extractInitials(this.fullName);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public render(): TemplateResult {
|
|
70
|
+
if (!this.user) {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return html` <div class="wrapper">
|
|
75
|
+
<div
|
|
76
|
+
class="avatar-circle"
|
|
77
|
+
style="
|
|
78
|
+
transform:scale(${this.scale || 1});
|
|
79
|
+
display: flex;
|
|
80
|
+
height: 30px;
|
|
81
|
+
width: 30px;
|
|
82
|
+
flex-direction: row;
|
|
83
|
+
align-items: center;
|
|
84
|
+
color: #fff;
|
|
85
|
+
border-radius: 100%;
|
|
86
|
+
font-weight: 400;
|
|
87
|
+
overflow: hidden;
|
|
88
|
+
font-size: 12px;
|
|
89
|
+
box-shadow: inset 0 0 0 3px rgba(0, 0, 0, 0.1);
|
|
90
|
+
background:${this.background}"
|
|
91
|
+
>
|
|
92
|
+
${this.initials
|
|
93
|
+
? html` <div
|
|
94
|
+
style="border: 0px solid red; display:flex; flex-direction: column; align-items:center;flex-grow:1"
|
|
95
|
+
>
|
|
96
|
+
<div style="border:0px solid blue;">${this.initials}</div>
|
|
97
|
+
</div>`
|
|
98
|
+
: null}
|
|
99
|
+
</div>
|
|
100
|
+
${this.name
|
|
101
|
+
? html`<div
|
|
102
|
+
class="name"
|
|
103
|
+
style="margin: 0px ${this.scale - 0.5}em;font-size:${this.scale +
|
|
104
|
+
0.2}em"
|
|
105
|
+
>
|
|
106
|
+
${this.fullName}
|
|
107
|
+
</div>`
|
|
108
|
+
: null}
|
|
109
|
+
</div>`;
|
|
110
|
+
}
|
|
111
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -4,11 +4,10 @@ import { Button } from '../button/Button';
|
|
|
4
4
|
import { Dialog } from '../dialog/Dialog';
|
|
5
5
|
import { Attachment, ContactField, Ticket, User } from '../interfaces';
|
|
6
6
|
import ColorHash from 'color-hash';
|
|
7
|
-
import { userInfo } from 'os';
|
|
8
7
|
|
|
9
8
|
export const DEFAULT_MEDIA_ENDPOINT = '/api/v2/media.json';
|
|
10
9
|
|
|
11
|
-
const colorHash = new ColorHash();
|
|
10
|
+
export const colorHash = new ColorHash();
|
|
12
11
|
|
|
13
12
|
export type Asset = KeyedAsset & Ticket & ContactField;
|
|
14
13
|
|
package/temba-modules.ts
CHANGED
|
@@ -53,6 +53,7 @@ import { NotificationList } from './src/list/NotificationList';
|
|
|
53
53
|
import { WebChat } from './src/webchat/WebChat';
|
|
54
54
|
import { ImagePicker } from './src/imagepicker/ImagePicker';
|
|
55
55
|
import { Mask } from './src/mask/Mask';
|
|
56
|
+
import { TembaUser } from './src/user/TembaUser';
|
|
56
57
|
|
|
57
58
|
export function addCustomElement(name: string, comp: any) {
|
|
58
59
|
if (!window.customElements.get(name)) {
|
|
@@ -116,3 +117,4 @@ addCustomElement('temba-thumbnail', Thumbnail);
|
|
|
116
117
|
addCustomElement('temba-webchat', WebChat);
|
|
117
118
|
addCustomElement('temba-image-picker', ImagePicker);
|
|
118
119
|
addCustomElement('temba-mask', Mask);
|
|
120
|
+
addCustomElement('temba-user', TembaUser);
|
package/templates/index.html
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
2
|
<html lang="en">
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
|
|
4
|
+
<head></head>
|
|
5
|
+
|
|
6
|
+
<body>
|
|
7
|
+
<script type="module" src="../out-tsc/temba-components.js"></script>
|
|
8
|
+
</body>
|
|
9
|
+
|
|
7
10
|
</html>
|
|
@@ -48,9 +48,7 @@ describe('temba-contact-tickets', () => {
|
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
// click on the avatar element
|
|
51
|
-
(
|
|
52
|
-
tickets.shadowRoot.querySelector('.avatar-circle') as HTMLDivElement
|
|
53
|
-
).click();
|
|
51
|
+
(tickets.shadowRoot.querySelector('temba-user') as HTMLDivElement).click();
|
|
54
52
|
assert.instanceOf(tickets, ContactTickets);
|
|
55
53
|
await assertScreenshot('contacts/tickets-assignment', getClip(tickets));
|
|
56
54
|
});
|