@nyaruka/temba-components 0.67.3 → 0.68.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 +15 -0
- package/demo/index.html +5 -3
- package/dist/{314b925e.js → dd629ee4.js} +802 -122
- package/dist/index.js +802 -122
- package/dist/static/svg/index.svg +1 -1
- 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/ContactTickets.js +4 -6
- package/out-tsc/src/contacts/ContactTickets.js.map +1 -1
- package/out-tsc/src/contacts/events.js +3 -8
- package/out-tsc/src/contacts/events.js.map +1 -1
- package/out-tsc/src/imagepicker/CroppieCSS.js +254 -0
- package/out-tsc/src/imagepicker/CroppieCSS.js.map +1 -0
- package/out-tsc/src/imagepicker/ImagePicker.js +248 -0
- package/out-tsc/src/imagepicker/ImagePicker.js.map +1 -0
- package/out-tsc/src/interfaces.js.map +1 -1
- package/out-tsc/src/list/NotificationList.js +4 -0
- package/out-tsc/src/list/NotificationList.js.map +1 -1
- package/out-tsc/src/list/TembaMenu.js +1 -1
- package/out-tsc/src/list/TembaMenu.js.map +1 -1
- package/out-tsc/src/list/TicketList.js +16 -12
- package/out-tsc/src/list/TicketList.js.map +1 -1
- package/out-tsc/src/mask/Mask.js +36 -0
- package/out-tsc/src/mask/Mask.js.map +1 -0
- package/out-tsc/src/utils/index.js +24 -16
- package/out-tsc/src/utils/index.js.map +1 -1
- package/out-tsc/src/vectoricon/index.js +5 -1
- package/out-tsc/src/vectoricon/index.js.map +1 -1
- package/out-tsc/src/webchat/WebChat.js +515 -0
- package/out-tsc/src/webchat/WebChat.js.map +1 -0
- package/out-tsc/src/webchat/index.js +7 -0
- package/out-tsc/src/webchat/index.js.map +1 -0
- package/out-tsc/temba-modules.js +6 -0
- package/out-tsc/temba-modules.js.map +1 -1
- package/package.json +4 -2
- package/screenshots/truth/contacts/tickets-assignment.png +0 -0
- package/screenshots/truth/contacts/tickets.png +0 -0
- package/screenshots/truth/menu/menu-focused-with items.png +0 -0
- package/screenshots/truth/menu/menu-refresh-1.png +0 -0
- package/screenshots/truth/menu/menu-refresh-2.png +0 -0
- package/screenshots/truth/menu/menu-root.png +0 -0
- package/screenshots/truth/menu/menu-submenu.png +0 -0
- package/screenshots/truth/menu/menu-tasks-nextup.png +0 -0
- package/screenshots/truth/menu/menu-tasks.png +0 -0
- package/src/contacts/ContactTickets.ts +4 -6
- package/src/contacts/events.ts +3 -9
- package/src/imagepicker/CroppieCSS.ts +254 -0
- package/src/imagepicker/ImagePicker.ts +272 -0
- package/src/interfaces.ts +2 -1
- package/src/list/NotificationList.ts +3 -0
- package/src/list/TembaMenu.ts +1 -1
- package/src/list/TicketList.ts +16 -12
- package/src/mask/Mask.ts +32 -0
- package/src/untyped.d.ts +1 -0
- package/src/utils/index.ts +26 -18
- package/src/vectoricon/index.ts +5 -1
- package/src/webchat/WebChat.ts +559 -0
- package/src/webchat/index.ts +6 -0
- package/static/svg/index.svg +1 -1
- package/static/svg/webchat.svg +1 -0
- package/static/svg/work/traced/camera-01.svg +1 -0
- package/static/svg/work/traced/send-03.svg +1 -0
- package/static/svg/work/used/camera-01.svg +4 -0
- package/static/svg/work/used/send-03.svg +3 -0
- package/svg.js +12 -8
- package/temba-modules.ts +6 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nyaruka/temba-components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.68.0",
|
|
4
4
|
"description": "Web components to support rapidpro and related projects",
|
|
5
5
|
"author": "Nyaruka <code@nyaruka.coim>",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"test:watch": "wtr --node-resolve --watch",
|
|
27
27
|
"storybook": "concurrently --kill-others --names tsc,storybook \"npm run tsc:watch\" \"start-storybook --node-resolve --watch --open\"",
|
|
28
28
|
"storybook:build": "build-storybook",
|
|
29
|
-
"svg": "rimraf static/svg/work && node svg.js --resolution=150",
|
|
29
|
+
"svg": "rimraf static/svg/work && node svg.js --resolution=150 --output='./static/svg/index.svg' --usage='./src/vectoricon/index.ts'",
|
|
30
|
+
"svg-wc": "rimraf static/svg/work && node svg.js --resolution=150 --output='./static/svg/webchat.svg' --usage='./src/webchat/index.ts'",
|
|
30
31
|
"version": "yarn run build && auto-changelog -p && git add CHANGELOG.md",
|
|
31
32
|
"locale:extract": "lit-localize extract --config localize.config.json",
|
|
32
33
|
"locale:build": "lit-localize build --config localize.config.json"
|
|
@@ -34,6 +35,7 @@
|
|
|
34
35
|
"dependencies": {
|
|
35
36
|
"@lit/localize": "^0.11.4",
|
|
36
37
|
"color-hash": "^2.0.2",
|
|
38
|
+
"croppie": "^2.6.5",
|
|
37
39
|
"geojson": "^0.5.0",
|
|
38
40
|
"highlight.js": "^10.7.1",
|
|
39
41
|
"image-size": "^0.9.7",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -155,7 +155,6 @@ export class ContactTickets extends StoreElement {
|
|
|
155
155
|
|
|
156
156
|
.user {
|
|
157
157
|
display: flex;
|
|
158
|
-
padding: 0.4em 0.7em;
|
|
159
158
|
align-items: center;
|
|
160
159
|
border-radius: var(--curvature);
|
|
161
160
|
cursor: pointer;
|
|
@@ -166,8 +165,6 @@ export class ContactTickets extends StoreElement {
|
|
|
166
165
|
}
|
|
167
166
|
|
|
168
167
|
.user .avatar {
|
|
169
|
-
font-size: 0.5em;
|
|
170
|
-
margin-right: 1em;
|
|
171
168
|
}
|
|
172
169
|
|
|
173
170
|
.user .name {
|
|
@@ -251,7 +248,7 @@ export class ContactTickets extends StoreElement {
|
|
|
251
248
|
return null;
|
|
252
249
|
}
|
|
253
250
|
return html`<div class="user">
|
|
254
|
-
<div class="avatar">${renderAvatar({ user: user })}</div>
|
|
251
|
+
<div class="avatar">${renderAvatar({ user: user, scale: 0.6 })}</div>
|
|
255
252
|
<div class="name">${getFullName(user)}</div>
|
|
256
253
|
</div>`;
|
|
257
254
|
}
|
|
@@ -355,10 +352,11 @@ export class ContactTickets extends StoreElement {
|
|
|
355
352
|
<div slot="toggle" class="toggle">
|
|
356
353
|
${ticket.assignee
|
|
357
354
|
? html`
|
|
358
|
-
<div
|
|
355
|
+
<div>
|
|
359
356
|
${renderAvatar({
|
|
360
357
|
name: ticket.assignee.name,
|
|
361
|
-
|
|
358
|
+
user: ticket.assignee,
|
|
359
|
+
scale: 0.7,
|
|
362
360
|
})}
|
|
363
361
|
</div>
|
|
364
362
|
`
|
package/src/contacts/events.ts
CHANGED
|
@@ -697,12 +697,6 @@ export const getEventGroupType = (event: ContactEvent, ticket: string) => {
|
|
|
697
697
|
return 'verbose';
|
|
698
698
|
};
|
|
699
699
|
|
|
700
|
-
export const renderUserAvatar = (user: User) => {
|
|
701
|
-
return html`<div style="width:3.5em;font-size:0.8em">
|
|
702
|
-
${renderAvatar({ user, position: 'left' })}
|
|
703
|
-
</div>`;
|
|
704
|
-
};
|
|
705
|
-
|
|
706
700
|
export const renderAttachment = (attachment: string): TemplateResult => {
|
|
707
701
|
const idx = attachment.indexOf(':');
|
|
708
702
|
const attType = attachment.substr(0, idx);
|
|
@@ -881,7 +875,7 @@ export const renderMsgEvent = (
|
|
|
881
875
|
|
|
882
876
|
${!isInbound && event.created_by
|
|
883
877
|
? html`<div style="margin-left:0.8em;margin-top:0.3em;font-size:0.9em">
|
|
884
|
-
${
|
|
878
|
+
${renderAvatar({ user: event.created_by })}
|
|
885
879
|
</div>`
|
|
886
880
|
: null}
|
|
887
881
|
</div>`;
|
|
@@ -1016,8 +1010,8 @@ export const renderNoteCreated = (event: TicketEvent): TemplateResult => {
|
|
|
1016
1010
|
></temba-date>
|
|
1017
1011
|
</div>
|
|
1018
1012
|
</div>
|
|
1019
|
-
<div style="margin-left:0.8em;margin-top:0.3em;
|
|
1020
|
-
${
|
|
1013
|
+
<div style="margin-left:0.8em;margin-top:0.3em;">
|
|
1014
|
+
${renderAvatar({ user: event.created_by })}
|
|
1021
1015
|
</div>
|
|
1022
1016
|
</div>`;
|
|
1023
1017
|
};
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
|
|
3
|
+
export const CroppieCSS = css`
|
|
4
|
+
.croppie-container {
|
|
5
|
+
width: 100%;
|
|
6
|
+
height: 100%;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.croppie-container .cr-image {
|
|
10
|
+
z-index: -1;
|
|
11
|
+
position: absolute;
|
|
12
|
+
top: 0;
|
|
13
|
+
left: 0;
|
|
14
|
+
transform-origin: 0 0;
|
|
15
|
+
max-height: none;
|
|
16
|
+
max-width: none;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.croppie-container .cr-boundary {
|
|
20
|
+
position: relative;
|
|
21
|
+
overflow: hidden;
|
|
22
|
+
margin: 0 auto;
|
|
23
|
+
z-index: 1;
|
|
24
|
+
width: 100%;
|
|
25
|
+
height: 100%;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.croppie-container .cr-viewport,
|
|
29
|
+
.croppie-container .cr-resizer {
|
|
30
|
+
position: absolute;
|
|
31
|
+
border: 2px solid #fff;
|
|
32
|
+
margin: auto;
|
|
33
|
+
top: 0;
|
|
34
|
+
bottom: 0;
|
|
35
|
+
right: 0;
|
|
36
|
+
left: 0;
|
|
37
|
+
box-shadow: 0 0 2000px 2000px rgba(0, 0, 0, 0.5);
|
|
38
|
+
z-index: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.croppie-container .cr-resizer {
|
|
42
|
+
z-index: 2;
|
|
43
|
+
box-shadow: none;
|
|
44
|
+
pointer-events: none;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.croppie-container .cr-resizer-vertical,
|
|
48
|
+
.croppie-container .cr-resizer-horisontal {
|
|
49
|
+
position: absolute;
|
|
50
|
+
pointer-events: all;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.croppie-container .cr-resizer-vertical::after,
|
|
54
|
+
.croppie-container .cr-resizer-horisontal::after {
|
|
55
|
+
display: block;
|
|
56
|
+
position: absolute;
|
|
57
|
+
box-sizing: border-box;
|
|
58
|
+
border: 1px solid black;
|
|
59
|
+
background: #fff;
|
|
60
|
+
width: 10px;
|
|
61
|
+
height: 10px;
|
|
62
|
+
content: '';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.croppie-container .cr-resizer-vertical {
|
|
66
|
+
bottom: -5px;
|
|
67
|
+
cursor: row-resize;
|
|
68
|
+
width: 100%;
|
|
69
|
+
height: 10px;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.croppie-container .cr-resizer-vertical::after {
|
|
73
|
+
left: 50%;
|
|
74
|
+
margin-left: -5px;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.croppie-container .cr-resizer-horisontal {
|
|
78
|
+
right: -5px;
|
|
79
|
+
cursor: col-resize;
|
|
80
|
+
width: 10px;
|
|
81
|
+
height: 100%;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.croppie-container .cr-resizer-horisontal::after {
|
|
85
|
+
top: 50%;
|
|
86
|
+
margin-top: -5px;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.croppie-container .cr-original-image {
|
|
90
|
+
display: none;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.croppie-container .cr-vp-circle {
|
|
94
|
+
border-radius: 50%;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.croppie-container .cr-overlay {
|
|
98
|
+
z-index: 1;
|
|
99
|
+
position: absolute;
|
|
100
|
+
cursor: move;
|
|
101
|
+
touch-action: none;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.croppie-container .cr-slider-wrap {
|
|
105
|
+
width: 75%;
|
|
106
|
+
margin: 15px auto;
|
|
107
|
+
text-align: center;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.croppie-result {
|
|
111
|
+
position: relative;
|
|
112
|
+
overflow: hidden;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.croppie-result img {
|
|
116
|
+
position: absolute;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.croppie-container .cr-image,
|
|
120
|
+
.croppie-container .cr-overlay,
|
|
121
|
+
.croppie-container .cr-viewport {
|
|
122
|
+
-webkit-transform: translateZ(0);
|
|
123
|
+
-moz-transform: translateZ(0);
|
|
124
|
+
-ms-transform: translateZ(0);
|
|
125
|
+
transform: translateZ(0);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/*************************************/
|
|
129
|
+
/***** STYLING RANGE INPUT ***********/
|
|
130
|
+
/*************************************/
|
|
131
|
+
/*http://brennaobrien.com/blog/2014/05/style-input-type-range-in-every-browser.html */
|
|
132
|
+
/*************************************/
|
|
133
|
+
|
|
134
|
+
.cr-slider {
|
|
135
|
+
-webkit-appearance: none;
|
|
136
|
+
/*removes default webkit styles*/
|
|
137
|
+
/*border: 1px solid white; */ /*fix for FF unable to apply focus style bug */
|
|
138
|
+
width: 300px;
|
|
139
|
+
/*required for proper track sizing in FF*/
|
|
140
|
+
max-width: 100%;
|
|
141
|
+
padding-top: 8px;
|
|
142
|
+
padding-bottom: 8px;
|
|
143
|
+
background-color: transparent;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.cr-slider::-webkit-slider-runnable-track {
|
|
147
|
+
width: 100%;
|
|
148
|
+
height: 3px;
|
|
149
|
+
background: rgba(0, 0, 0, 0.5);
|
|
150
|
+
border: 0;
|
|
151
|
+
border-radius: 3px;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.cr-slider::-webkit-slider-thumb {
|
|
155
|
+
-webkit-appearance: none;
|
|
156
|
+
border: none;
|
|
157
|
+
height: 16px;
|
|
158
|
+
width: 16px;
|
|
159
|
+
border-radius: 50%;
|
|
160
|
+
background: #ddd;
|
|
161
|
+
margin-top: -6px;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.cr-slider:focus {
|
|
165
|
+
outline: none;
|
|
166
|
+
}
|
|
167
|
+
/*
|
|
168
|
+
.cr-slider:focus::-webkit-slider-runnable-track {
|
|
169
|
+
background: #ccc;
|
|
170
|
+
}
|
|
171
|
+
*/
|
|
172
|
+
|
|
173
|
+
.cr-slider::-moz-range-track {
|
|
174
|
+
width: 100%;
|
|
175
|
+
height: 3px;
|
|
176
|
+
background: rgba(0, 0, 0, 0.5);
|
|
177
|
+
border: 0;
|
|
178
|
+
border-radius: 3px;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.cr-slider::-moz-range-thumb {
|
|
182
|
+
border: none;
|
|
183
|
+
height: 16px;
|
|
184
|
+
width: 16px;
|
|
185
|
+
border-radius: 50%;
|
|
186
|
+
background: #ddd;
|
|
187
|
+
margin-top: -6px;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/*hide the outline behind the border*/
|
|
191
|
+
.cr-slider:-moz-focusring {
|
|
192
|
+
outline: 1px solid white;
|
|
193
|
+
outline-offset: -1px;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.cr-slider::-ms-track {
|
|
197
|
+
width: 100%;
|
|
198
|
+
height: 5px;
|
|
199
|
+
background: transparent;
|
|
200
|
+
/*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */
|
|
201
|
+
border-color: transparent; /*leave room for the larger thumb to overflow with a transparent border */
|
|
202
|
+
border-width: 6px 0;
|
|
203
|
+
color: transparent; /*remove default tick marks*/
|
|
204
|
+
}
|
|
205
|
+
.cr-slider::-ms-fill-lower {
|
|
206
|
+
background: rgba(0, 0, 0, 0.5);
|
|
207
|
+
border-radius: 10px;
|
|
208
|
+
}
|
|
209
|
+
.cr-slider::-ms-fill-upper {
|
|
210
|
+
background: rgba(0, 0, 0, 0.5);
|
|
211
|
+
border-radius: 10px;
|
|
212
|
+
}
|
|
213
|
+
.cr-slider::-ms-thumb {
|
|
214
|
+
border: none;
|
|
215
|
+
height: 16px;
|
|
216
|
+
width: 16px;
|
|
217
|
+
border-radius: 50%;
|
|
218
|
+
background: #ddd;
|
|
219
|
+
margin-top: 1px;
|
|
220
|
+
}
|
|
221
|
+
.cr-slider:focus::-ms-fill-lower {
|
|
222
|
+
background: rgba(0, 0, 0, 0.5);
|
|
223
|
+
}
|
|
224
|
+
.cr-slider:focus::-ms-fill-upper {
|
|
225
|
+
background: rgba(0, 0, 0, 0.5);
|
|
226
|
+
}
|
|
227
|
+
/*******************************************/
|
|
228
|
+
|
|
229
|
+
/***********************************/
|
|
230
|
+
/* Rotation Tools */
|
|
231
|
+
/***********************************/
|
|
232
|
+
.cr-rotate-controls {
|
|
233
|
+
position: absolute;
|
|
234
|
+
bottom: 5px;
|
|
235
|
+
left: 5px;
|
|
236
|
+
z-index: 1;
|
|
237
|
+
}
|
|
238
|
+
.cr-rotate-controls button {
|
|
239
|
+
border: 0;
|
|
240
|
+
background: none;
|
|
241
|
+
}
|
|
242
|
+
.cr-rotate-controls i:before {
|
|
243
|
+
display: inline-block;
|
|
244
|
+
font-style: normal;
|
|
245
|
+
font-weight: 900;
|
|
246
|
+
font-size: 22px;
|
|
247
|
+
}
|
|
248
|
+
.cr-rotate-l i:before {
|
|
249
|
+
content: '↺';
|
|
250
|
+
}
|
|
251
|
+
.cr-rotate-r i:before {
|
|
252
|
+
content: '↻';
|
|
253
|
+
}
|
|
254
|
+
`;
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-this-alias */
|
|
2
|
+
import { html, css, PropertyValueMap } from 'lit';
|
|
3
|
+
import 'croppie/croppie.js';
|
|
4
|
+
import { CroppieCSS } from './CroppieCSS';
|
|
5
|
+
import { property } from 'lit/decorators.js';
|
|
6
|
+
import { Icon } from '../vectoricon';
|
|
7
|
+
import { FormElement } from '../FormElement';
|
|
8
|
+
|
|
9
|
+
export class ImagePicker extends FormElement {
|
|
10
|
+
static styles = css`
|
|
11
|
+
${CroppieCSS}
|
|
12
|
+
|
|
13
|
+
.croppie {
|
|
14
|
+
max-width: 400px;
|
|
15
|
+
border: 0px solid #ccc;
|
|
16
|
+
border-radius: 0.5em;
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
background: #fff;
|
|
19
|
+
margin-top: -20%;
|
|
20
|
+
box-shadow: 0 0 15px 5px rgba(0, 0, 0, 0.1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.croppie .controls {
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
flex-direction: row;
|
|
27
|
+
justify-content: center;
|
|
28
|
+
position: absolute;
|
|
29
|
+
z-index: 1;
|
|
30
|
+
width: 400px;
|
|
31
|
+
margin-top: -42px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.toggle {
|
|
35
|
+
height: 110px;
|
|
36
|
+
width: 110px;
|
|
37
|
+
cursor: pointer;
|
|
38
|
+
display: flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
justify-content: center;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.circle .toggle {
|
|
44
|
+
border-radius: 50%;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.toggle.set {
|
|
48
|
+
box-shadow: rgba(0, 0, 0, 0.1) 0px 3px 7px 0px,
|
|
49
|
+
rgba(0, 0, 0, 0.2) 0px 1px 2px 0px, inset 0 0 0 5px rgba(0, 0, 0, 0.1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.toggle.set:hover {
|
|
53
|
+
box-shadow: rgba(0, 0, 0, 0.1) 0px 3px 7px 0px,
|
|
54
|
+
rgba(0, 0, 0, 0.2) 0px 1px 2px 0px, inset 0 0 0 5px rgba(0, 0, 0, 0.2);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.toggle temba-icon {
|
|
58
|
+
color: rgba(0, 0, 0, 0.2);
|
|
59
|
+
padding: 5px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
toggle:hover temba-icon {
|
|
63
|
+
color: rgba(0, 0, 0, 0.8);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.toggle.set temba-icon {
|
|
67
|
+
border-radius: 50%;
|
|
68
|
+
margin-right: -90%;
|
|
69
|
+
margin-bottom: -50%;
|
|
70
|
+
background: rgba(240, 240, 240, 1);
|
|
71
|
+
box-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px 0px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.toggle.set:hover temba-icon {
|
|
75
|
+
background: #fff;
|
|
76
|
+
color: var(--color-primary-dark);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.circle .toggle.set temba-icon {
|
|
80
|
+
margin-right: -70%;
|
|
81
|
+
margin-bottom: -70%;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.hidden {
|
|
85
|
+
display: none;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.controls temba-icon {
|
|
89
|
+
margin: 0em 0.75em;
|
|
90
|
+
background: rgba(255, 255, 255, 0.8);
|
|
91
|
+
border-radius: 50%;
|
|
92
|
+
padding: 6px;
|
|
93
|
+
transition: all 0.1s ease-in-out;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.controls {
|
|
97
|
+
pointer-events: none;
|
|
98
|
+
display: flex;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.controls temba-icon {
|
|
102
|
+
pointer-events: all;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.controls temba-icon.close {
|
|
106
|
+
color: rgba(0, 0, 0, 0.2);
|
|
107
|
+
background: rgba(255, 255, 255, 0.2);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.controls temba-icon.submit {
|
|
111
|
+
color: rgba(0, 0, 0, 0.2);
|
|
112
|
+
box-shadow: inset 0 0 0 2px rgba(0, 0, 0, 0.1);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.controls temba-icon:hover {
|
|
116
|
+
color: white;
|
|
117
|
+
cursor: pointer;
|
|
118
|
+
background: var(--color-primary-dark);
|
|
119
|
+
}
|
|
120
|
+
`;
|
|
121
|
+
|
|
122
|
+
@property({ type: String })
|
|
123
|
+
tempImage: string;
|
|
124
|
+
|
|
125
|
+
@property({ type: String })
|
|
126
|
+
url: string;
|
|
127
|
+
|
|
128
|
+
@property({ type: String })
|
|
129
|
+
shape = 'square';
|
|
130
|
+
|
|
131
|
+
@property({ type: Boolean, attribute: false })
|
|
132
|
+
showCroppie = false;
|
|
133
|
+
|
|
134
|
+
uploadReader = new FileReader();
|
|
135
|
+
croppie: any;
|
|
136
|
+
|
|
137
|
+
protected firstUpdated(
|
|
138
|
+
changed: PropertyValueMap<any> | Map<PropertyKey, unknown>
|
|
139
|
+
): void {
|
|
140
|
+
super.firstUpdated(changed);
|
|
141
|
+
const picker = this;
|
|
142
|
+
|
|
143
|
+
this.uploadReader.onload = function () {
|
|
144
|
+
picker.launchCroppie(picker.uploadReader.result as any);
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
public updated(changed: Map<string, any>): void {
|
|
149
|
+
super.updated(changed);
|
|
150
|
+
if (changed.has('url')) {
|
|
151
|
+
this.setAttribute('url', this.url);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
private closeCroppie() {
|
|
156
|
+
this.showCroppie = false;
|
|
157
|
+
const wrapper = this.shadowRoot.querySelector('.croppie .embed');
|
|
158
|
+
if (wrapper.firstChild) {
|
|
159
|
+
wrapper.removeChild(wrapper.firstChild);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private launchCroppie(url: string) {
|
|
164
|
+
const wrapper = this.shadowRoot.querySelector('.croppie .embed');
|
|
165
|
+
if (wrapper.firstChild) {
|
|
166
|
+
wrapper.removeChild(wrapper.firstChild);
|
|
167
|
+
}
|
|
168
|
+
this.showCroppie = true;
|
|
169
|
+
const croppie = document.createElement('div');
|
|
170
|
+
wrapper.appendChild(croppie);
|
|
171
|
+
|
|
172
|
+
const Croppie = (window as any).Croppie;
|
|
173
|
+
this.croppie = new Croppie(croppie, {
|
|
174
|
+
enableExif: true,
|
|
175
|
+
viewport: {
|
|
176
|
+
width: 300,
|
|
177
|
+
height: 300,
|
|
178
|
+
type: this.shape,
|
|
179
|
+
},
|
|
180
|
+
boundary: {
|
|
181
|
+
width: 400,
|
|
182
|
+
height: 400,
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
this.croppie.bind({ url });
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private saveResult() {
|
|
190
|
+
const picker = this;
|
|
191
|
+
this.croppie
|
|
192
|
+
.result({
|
|
193
|
+
type: 'blob',
|
|
194
|
+
size: 'viewport',
|
|
195
|
+
format: 'webp',
|
|
196
|
+
quality: 1,
|
|
197
|
+
circle: false,
|
|
198
|
+
})
|
|
199
|
+
.then(function (resp: any) {
|
|
200
|
+
const blob = resp;
|
|
201
|
+
picker.url = URL.createObjectURL(blob);
|
|
202
|
+
|
|
203
|
+
// const blob = dataURItoBlob(resp);
|
|
204
|
+
const fd = new FormData();
|
|
205
|
+
fd.append(picker.name, blob, 'filename.webp');
|
|
206
|
+
|
|
207
|
+
picker.value = fd;
|
|
208
|
+
picker.closeCroppie();
|
|
209
|
+
|
|
210
|
+
console.log('image changed', picker.name, picker.value, picker.url);
|
|
211
|
+
// picker.dispatchEvent(new CustomEvent('image-changed', { detail: resp }));
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
private handleToggleClicked() {
|
|
216
|
+
const fileInput = this.shadowRoot.querySelector('#file');
|
|
217
|
+
(fileInput as any).click();
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
private handleFileChanged(e: Event) {
|
|
221
|
+
const input = e.target as any;
|
|
222
|
+
if (input.files.length > 0) {
|
|
223
|
+
this.uploadReader.readAsDataURL(input.files[0]);
|
|
224
|
+
}
|
|
225
|
+
input.value = '';
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
protected render() {
|
|
229
|
+
return html`
|
|
230
|
+
<div class="wrapper ${this.shape} ${this.label ? 'label' : ''}">
|
|
231
|
+
<temba-field
|
|
232
|
+
name=${this.name}
|
|
233
|
+
label=${this.label}
|
|
234
|
+
.helpText=${this.helpText}
|
|
235
|
+
.errors=${this.errors}
|
|
236
|
+
.widgetOnly=${this.widgetOnly}
|
|
237
|
+
.helpAlways=${true}
|
|
238
|
+
?disabled=${this.disabled}
|
|
239
|
+
>
|
|
240
|
+
<input class='hidden' type="file" accept="image/*" capture="camera" id="file" name="file" @change=${
|
|
241
|
+
this.handleFileChanged
|
|
242
|
+
}/>
|
|
243
|
+
<div class='toggle ${this.url ? 'set' : ''} ${
|
|
244
|
+
this.showCroppie ? 'hidden' : ''
|
|
245
|
+
}' @click=${this.handleToggleClicked} style="background: ${
|
|
246
|
+
this.url
|
|
247
|
+
? `url('${this.url}') center / contain no-repeat`
|
|
248
|
+
: 'rgba(0, 0, 0, 0.1)'
|
|
249
|
+
}">
|
|
250
|
+
<temba-icon name=${Icon.upload_image} size="1.5"></temba-icon>
|
|
251
|
+
</div>
|
|
252
|
+
|
|
253
|
+
<temba-mask ?show=${this.showCroppie} class="${
|
|
254
|
+
this.showCroppie ? 'editing' : ''
|
|
255
|
+
}">
|
|
256
|
+
<div class='croppie'>
|
|
257
|
+
<div class='embed'></div>
|
|
258
|
+
<div class='controls'>
|
|
259
|
+
<temba-icon class="close" size="1" name=${Icon.close} @click=${
|
|
260
|
+
this.closeCroppie
|
|
261
|
+
}></temba-icon>
|
|
262
|
+
<div style="flex-grow:1"></div>
|
|
263
|
+
<temba-icon class="submit" size="1" name=${Icon.submit} @click=${
|
|
264
|
+
this.saveResult
|
|
265
|
+
}></temba-icon>
|
|
266
|
+
</div>
|
|
267
|
+
</temba-mask>
|
|
268
|
+
</temba-field>
|
|
269
|
+
</div>
|
|
270
|
+
`;
|
|
271
|
+
}
|
|
272
|
+
}
|
package/src/interfaces.ts
CHANGED
|
@@ -55,6 +55,7 @@ export interface User {
|
|
|
55
55
|
email?: string;
|
|
56
56
|
role?: string;
|
|
57
57
|
created_on?: string;
|
|
58
|
+
avatar?: string;
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
export interface Ticket {
|
|
@@ -66,7 +67,7 @@ export interface Ticket {
|
|
|
66
67
|
status: string;
|
|
67
68
|
contact: ObjectReference;
|
|
68
69
|
topic: ObjectReference;
|
|
69
|
-
assignee?: { email: string; name: string };
|
|
70
|
+
assignee?: { email: string; name: string; avatar?: string };
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
export interface FlowResult {
|
|
@@ -95,6 +95,9 @@ export class NotificationList extends TembaList {
|
|
|
95
95
|
} else if (notification.export.type === 'results') {
|
|
96
96
|
icon = Icon.results_export;
|
|
97
97
|
body = 'Exported flow results';
|
|
98
|
+
} else if (notification.export.type === 'ticket') {
|
|
99
|
+
icon = Icon.tickets_export;
|
|
100
|
+
body = 'Exported tickets';
|
|
98
101
|
}
|
|
99
102
|
} else if (notification.type === 'tickets:activity') {
|
|
100
103
|
icon = Icon.tickets;
|
package/src/list/TembaMenu.ts
CHANGED
|
@@ -993,7 +993,7 @@ export class TembaMenu extends RapidElement {
|
|
|
993
993
|
});
|
|
994
994
|
|
|
995
995
|
if (menuItem.avatar) {
|
|
996
|
-
icon = renderAvatar({ name: menuItem.avatar, tip: false });
|
|
996
|
+
icon = renderAvatar({ name: menuItem.avatar, tip: false, scale: 1.2 });
|
|
997
997
|
if (menuItem.bubble) {
|
|
998
998
|
icon = html`${icon}${menuItem.bubble
|
|
999
999
|
? html`<div
|