@nyaruka/temba-components 0.43.8 → 0.45.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/dist/{005a8061.js → 0887303b.js} +75 -55
- package/dist/index.js +75 -55
- 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/compose/Compose.js +143 -83
- package/out-tsc/src/compose/Compose.js.map +1 -1
- package/out-tsc/src/contacts/ContactChat.js +6 -12
- package/out-tsc/src/contacts/ContactChat.js.map +1 -1
- package/out-tsc/src/contacts/ContactFields.js +1 -1
- package/out-tsc/src/contacts/ContactFields.js.map +1 -1
- package/out-tsc/src/contacts/ContactNameFetch.js +2 -1
- package/out-tsc/src/contacts/ContactNameFetch.js.map +1 -1
- package/out-tsc/src/list/TembaMenu.js +1 -6
- package/out-tsc/src/list/TembaMenu.js.map +1 -1
- package/out-tsc/src/store/Store.js +32 -1
- package/out-tsc/src/store/Store.js.map +1 -1
- package/out-tsc/src/store/StoreElement.js +19 -5
- package/out-tsc/src/store/StoreElement.js.map +1 -1
- package/out-tsc/test/temba-compose.test.js +154 -5
- package/out-tsc/test/temba-compose.test.js.map +1 -1
- package/out-tsc/test/temba-store.test.js +1 -1
- package/out-tsc/test/temba-store.test.js.map +1 -1
- package/out-tsc/test/utils.test.js +2 -2
- package/out-tsc/test/utils.test.js.map +1 -1
- package/package.json +1 -1
- package/src/compose/Compose.ts +159 -94
- package/src/contacts/ContactChat.ts +8 -11
- package/src/contacts/ContactFields.ts +1 -1
- package/src/contacts/ContactNameFetch.ts +2 -1
- package/src/list/TembaMenu.ts +1 -6
- package/src/store/Store.ts +34 -2
- package/src/store/StoreElement.ts +16 -6
- package/test/temba-compose.test.ts +172 -5
- package/test/temba-store.test.ts +1 -1
- package/test/utils.test.ts +2 -2
package/dist/sw.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
if(!self.define){let e,t={};const o=(o,n)=>(o=new URL(o+".js",n).href,t[o]||new Promise((t=>{if("document"in self){const e=document.createElement("script");e.src=o,e.onload=t,document.head.appendChild(e)}else e=o,importScripts(o),t()})).then((()=>{let e=t[o];if(!e)throw new Error(`Module ${o} didn’t register its module`);return e})));self.define=(n,s)=>{const i=e||("document"in self?document.currentScript.src:"")||location.href;if(t[i])return;let r={};const
|
|
1
|
+
if(!self.define){let e,t={};const o=(o,n)=>(o=new URL(o+".js",n).href,t[o]||new Promise((t=>{if("document"in self){const e=document.createElement("script");e.src=o,e.onload=t,document.head.appendChild(e)}else e=o,importScripts(o),t()})).then((()=>{let e=t[o];if(!e)throw new Error(`Module ${o} didn’t register its module`);return e})));self.define=(n,s)=>{const i=e||("document"in self?document.currentScript.src:"")||location.href;if(t[i])return;let r={};const d=e=>o(e,i),c={module:{uri:i},exports:r,require:d};t[i]=Promise.all(n.map((e=>c[e]||d(e)))).then((e=>(s(...e),r)))}}define(["./workbox-919adfb7"],(function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"0887303b.js",revision:"aa6fe6cbaf0dacd010621c8bfd64ca9e"},{url:"templates/components-body.html",revision:"678c6b29cd041da444710acde57da314"},{url:"templates/components-head.html",revision:"db75e958fa34dd9576cb09d8603e4fa4"}],{}),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"))),e.registerRoute("polyfills/*.js",new e.CacheFirst,"GET")}));
|
|
2
2
|
//# sourceMappingURL=sw.js.map
|
package/dist/sw.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sw.js","sources":["../../../../../tmp/
|
|
1
|
+
{"version":3,"file":"sw.js","sources":["../../../../../tmp/3ebe9d1455ee1e01a0fcd6424d05ba2c/sw.js"],"sourcesContent":["import {registerRoute as workbox_routing_registerRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-routing/registerRoute.mjs';\nimport {CacheFirst as workbox_strategies_CacheFirst} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-strategies/CacheFirst.mjs';\nimport {clientsClaim as workbox_core_clientsClaim} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/home/runner/work/temba-components/temba-components/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"0887303b.js\",\n \"revision\": \"aa6fe6cbaf0dacd010621c8bfd64ca9e\"\n },\n {\n \"url\": \"templates/components-body.html\",\n \"revision\": \"678c6b29cd041da444710acde57da314\"\n },\n {\n \"url\": \"templates/components-head.html\",\n \"revision\": \"db75e958fa34dd9576cb09d8603e4fa4\"\n }\n], {});\n\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"/index.html\")));\n\n\nworkbox_routing_registerRoute(\"polyfills/*.js\", new workbox_strategies_CacheFirst(), 'GET');\n\n\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","url","revision","workbox","registerRoute","workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","workbox_strategies_CacheFirst"],"mappings":"0nBAwBAA,KAAKC,cAELC,EAAAA,eAQAC,EAAAA,iBAAoC,CAClC,CACEC,IAAO,cACPC,SAAY,oCAEd,CACED,IAAO,iCACPC,SAAY,oCAEd,CACED,IAAO,iCACPC,SAAY,qCAEb,CAAE,GAEwBC,EAAAC,cAAC,IAAIC,EAAAA,gBAAgCC,EAAAA,wBAA2C,iBAGhFH,EAAAC,cAAC,iBAAkB,IAAIG,aAAiC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<script type="module" src="{{STATIC_URL}}@nyaruka/temba-components/dist/
|
|
1
|
+
<script type="module" src="{{STATIC_URL}}@nyaruka/temba-components/dist/0887303b.js"></script><script>window.TEMBA_COMPONENTS_VERSION="0.45.0"</script>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<link rel="modulepreload" href="{{STATIC_URL}}@nyaruka/temba-components/dist/
|
|
1
|
+
<link rel="modulepreload" href="{{STATIC_URL}}@nyaruka/temba-components/dist/0887303b.js" crossorigin="anonymous">
|
|
@@ -126,7 +126,7 @@ export class Compose extends FormElement {
|
|
|
126
126
|
padding: 0.2em;
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
#upload-
|
|
129
|
+
#upload-input {
|
|
130
130
|
display: none;
|
|
131
131
|
}
|
|
132
132
|
.upload-label {
|
|
@@ -161,25 +161,53 @@ export class Compose extends FormElement {
|
|
|
161
161
|
}
|
|
162
162
|
constructor() {
|
|
163
163
|
super();
|
|
164
|
-
this.
|
|
164
|
+
this.currentText = '';
|
|
165
165
|
this.accept = ''; //e.g. ".xls,.xlsx"
|
|
166
166
|
this.endpoint = upload_endpoint;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
this.errorValues = [];
|
|
167
|
+
this.currentAttachments = [];
|
|
168
|
+
this.failedAttachments = [];
|
|
170
169
|
this.buttonName = 'Send';
|
|
171
170
|
this.buttonDisabled = true;
|
|
172
171
|
this.buttonError = '';
|
|
172
|
+
this.value = '';
|
|
173
|
+
}
|
|
174
|
+
deserializeComposeValue() {
|
|
175
|
+
if (this.value) {
|
|
176
|
+
const parsed_value = JSON.parse(this.value);
|
|
177
|
+
if (this.chatbox) {
|
|
178
|
+
this.currentText = parsed_value.text;
|
|
179
|
+
}
|
|
180
|
+
if (this.attachments) {
|
|
181
|
+
this.currentAttachments = parsed_value.attachments;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
serializeComposeValue() {
|
|
186
|
+
const composeValue = {
|
|
187
|
+
text: this.currentText,
|
|
188
|
+
attachments: this.currentAttachments,
|
|
189
|
+
};
|
|
190
|
+
// update this.value...
|
|
191
|
+
this.value = JSON.stringify(composeValue);
|
|
192
|
+
// and then also update this.values...
|
|
193
|
+
// so that the hidden input is updated via FormElement.updateInputs()
|
|
194
|
+
this.values = [composeValue];
|
|
195
|
+
}
|
|
196
|
+
firstUpdated(changes) {
|
|
197
|
+
super.firstUpdated(changes);
|
|
198
|
+
this.deserializeComposeValue();
|
|
199
|
+
this.setFocusOnChatbox();
|
|
173
200
|
}
|
|
174
201
|
updated(changes) {
|
|
175
202
|
super.updated(changes);
|
|
176
|
-
if (changes.has('
|
|
177
|
-
this.buttonError = '';
|
|
203
|
+
if (changes.has('currentText') || changes.has('currentAttachments')) {
|
|
178
204
|
this.toggleButton();
|
|
205
|
+
this.setFocusOnChatbox();
|
|
206
|
+
this.serializeComposeValue();
|
|
207
|
+
}
|
|
208
|
+
if (changes.has('buttonError')) {
|
|
209
|
+
this.setFocusOnChatbox();
|
|
179
210
|
}
|
|
180
|
-
}
|
|
181
|
-
firstUpdated() {
|
|
182
|
-
this.setFocusOnChatbox();
|
|
183
211
|
}
|
|
184
212
|
setFocusOnChatbox() {
|
|
185
213
|
if (this.chatbox) {
|
|
@@ -193,16 +221,14 @@ export class Compose extends FormElement {
|
|
|
193
221
|
}
|
|
194
222
|
}
|
|
195
223
|
reset() {
|
|
196
|
-
this.
|
|
197
|
-
this.
|
|
198
|
-
this.
|
|
224
|
+
this.currentText = '';
|
|
225
|
+
this.currentAttachments = [];
|
|
226
|
+
this.failedAttachments = [];
|
|
199
227
|
this.buttonError = '';
|
|
200
228
|
}
|
|
201
229
|
handleChatboxChange(evt) {
|
|
202
230
|
const completion = evt.target;
|
|
203
|
-
|
|
204
|
-
this.currentChat = textInput.value;
|
|
205
|
-
this.preventDefaults(evt);
|
|
231
|
+
this.currentText = completion.value;
|
|
206
232
|
}
|
|
207
233
|
handleDragEnter(evt) {
|
|
208
234
|
this.highlight(evt);
|
|
@@ -233,20 +259,20 @@ export class Compose extends FormElement {
|
|
|
233
259
|
this.pendingDrop = false;
|
|
234
260
|
this.preventDefaults(evt);
|
|
235
261
|
}
|
|
236
|
-
|
|
262
|
+
handleUploadFileIconClicked() {
|
|
237
263
|
this.dispatchEvent(new Event('change'));
|
|
238
264
|
}
|
|
239
|
-
|
|
265
|
+
handleUploadFileInputChanged(evt) {
|
|
240
266
|
const target = evt.target;
|
|
241
267
|
const files = target.files;
|
|
242
268
|
this.uploadFiles(files);
|
|
243
269
|
}
|
|
244
270
|
uploadFiles(files) {
|
|
245
271
|
let filesToUpload = [];
|
|
246
|
-
if (this.
|
|
272
|
+
if (this.currentAttachments && this.currentAttachments.length > 0) {
|
|
247
273
|
//remove duplicate files that have already been uploaded
|
|
248
274
|
filesToUpload = [...files].filter(file => {
|
|
249
|
-
const index = this.
|
|
275
|
+
const index = this.currentAttachments.findIndex(value => value.filename === file.name && value.size === file.size);
|
|
250
276
|
if (index === -1) {
|
|
251
277
|
return file;
|
|
252
278
|
}
|
|
@@ -268,27 +294,36 @@ export class Compose extends FormElement {
|
|
|
268
294
|
.then((response) => {
|
|
269
295
|
const attachment = response.json;
|
|
270
296
|
if (attachment) {
|
|
271
|
-
this.
|
|
272
|
-
this.fireCustomEvent(CustomEventType.AttachmentAdded, attachment);
|
|
297
|
+
this.addCurrentAttachment(attachment);
|
|
273
298
|
}
|
|
274
299
|
})
|
|
275
300
|
.catch((error) => {
|
|
276
|
-
let
|
|
301
|
+
let uploadError = '';
|
|
277
302
|
if (error.status === 400) {
|
|
278
|
-
|
|
303
|
+
uploadError = error.json.file[0];
|
|
279
304
|
}
|
|
280
305
|
else {
|
|
281
|
-
|
|
306
|
+
uploadError = 'Server failure';
|
|
282
307
|
}
|
|
283
|
-
console.error(
|
|
284
|
-
this.
|
|
308
|
+
console.error(uploadError);
|
|
309
|
+
this.addFailedAttachment(file, uploadError);
|
|
285
310
|
})
|
|
286
311
|
.finally(() => {
|
|
287
312
|
this.uploading = false;
|
|
288
313
|
});
|
|
289
314
|
}
|
|
290
|
-
|
|
291
|
-
|
|
315
|
+
addCurrentAttachment(attachmentToAdd) {
|
|
316
|
+
this.currentAttachments.push(attachmentToAdd);
|
|
317
|
+
this.requestUpdate('currentAttachments');
|
|
318
|
+
this.fireCustomEvent(CustomEventType.AttachmentAdded, attachmentToAdd);
|
|
319
|
+
}
|
|
320
|
+
removeCurrentAttachment(attachmentToRemove) {
|
|
321
|
+
this.currentAttachments = this.currentAttachments.filter(currentAttachment => currentAttachment !== attachmentToRemove);
|
|
322
|
+
this.requestUpdate('currentAttachments');
|
|
323
|
+
this.fireCustomEvent(CustomEventType.AttachmentRemoved, attachmentToRemove);
|
|
324
|
+
}
|
|
325
|
+
addFailedAttachment(file, error) {
|
|
326
|
+
const failedAttachment = {
|
|
292
327
|
uuid: Math.random().toString(36).slice(2, 6),
|
|
293
328
|
content_type: file.type,
|
|
294
329
|
filename: file.name,
|
|
@@ -296,30 +331,30 @@ export class Compose extends FormElement {
|
|
|
296
331
|
size: file.size,
|
|
297
332
|
error: error,
|
|
298
333
|
};
|
|
299
|
-
this.
|
|
300
|
-
this.requestUpdate('
|
|
334
|
+
this.failedAttachments.push(failedAttachment);
|
|
335
|
+
this.requestUpdate('failedAttachments');
|
|
301
336
|
}
|
|
302
|
-
|
|
303
|
-
this.
|
|
304
|
-
this.requestUpdate('
|
|
337
|
+
removeFailedAttachment(attachmentToRemove) {
|
|
338
|
+
this.failedAttachments = this.failedAttachments.filter((failedAttachment) => failedAttachment !== attachmentToRemove);
|
|
339
|
+
this.requestUpdate('failedAttachments');
|
|
340
|
+
this.fireCustomEvent(CustomEventType.AttachmentRemoved, attachmentToRemove);
|
|
305
341
|
}
|
|
306
|
-
|
|
342
|
+
handleRemoveFileClicked(evt) {
|
|
307
343
|
const target = evt.target;
|
|
308
|
-
const
|
|
309
|
-
if (
|
|
310
|
-
this.
|
|
311
|
-
this.fireCustomEvent(CustomEventType.AttachmentRemoved, attachment);
|
|
344
|
+
const currentAttachmentToRemove = this.currentAttachments.find(({ uuid }) => uuid === target.id);
|
|
345
|
+
if (currentAttachmentToRemove) {
|
|
346
|
+
this.removeCurrentAttachment(currentAttachmentToRemove);
|
|
312
347
|
}
|
|
313
|
-
const
|
|
314
|
-
if (
|
|
315
|
-
this.
|
|
316
|
-
this.fireCustomEvent(CustomEventType.AttachmentRemoved, attachment);
|
|
348
|
+
const failedAttachmentToRemove = this.failedAttachments.find(({ uuid }) => uuid === target.id);
|
|
349
|
+
if (failedAttachmentToRemove) {
|
|
350
|
+
this.removeFailedAttachment(failedAttachmentToRemove);
|
|
317
351
|
}
|
|
318
352
|
}
|
|
319
353
|
toggleButton() {
|
|
320
354
|
if (this.button) {
|
|
321
|
-
|
|
322
|
-
const
|
|
355
|
+
this.buttonError = '';
|
|
356
|
+
const chatboxEmpty = this.currentText.trim().length === 0;
|
|
357
|
+
const attachmentsEmpty = this.currentAttachments.length === 0;
|
|
323
358
|
if (this.chatbox && this.attachments) {
|
|
324
359
|
this.buttonDisabled = chatboxEmpty && attachmentsEmpty;
|
|
325
360
|
}
|
|
@@ -334,7 +369,8 @@ export class Compose extends FormElement {
|
|
|
334
369
|
}
|
|
335
370
|
}
|
|
336
371
|
}
|
|
337
|
-
handleSendClick() {
|
|
372
|
+
handleSendClick(evt) {
|
|
373
|
+
evt.stopPropagation();
|
|
338
374
|
this.handleSend();
|
|
339
375
|
}
|
|
340
376
|
handleSendEnter(evt) {
|
|
@@ -351,34 +387,41 @@ export class Compose extends FormElement {
|
|
|
351
387
|
this.buttonDisabled = true;
|
|
352
388
|
const name = this.buttonName;
|
|
353
389
|
this.fireCustomEvent(CustomEventType.ButtonClicked, { name });
|
|
354
|
-
//after send, return focus to chatbox
|
|
355
|
-
this.setFocusOnChatbox();
|
|
356
390
|
}
|
|
357
391
|
}
|
|
358
392
|
render() {
|
|
359
393
|
return html `
|
|
360
|
-
<
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
@drop="${this.handleDrop}"
|
|
394
|
+
<temba-field
|
|
395
|
+
name=${this.name}
|
|
396
|
+
.errors=${this.errors}
|
|
397
|
+
.widgetOnly=${this.widgetOnly}
|
|
398
|
+
value=${this.value}
|
|
366
399
|
>
|
|
367
|
-
<div
|
|
400
|
+
<div
|
|
401
|
+
class=${getClasses({ container: true, highlight: this.pendingDrop })}
|
|
402
|
+
@dragenter="${this.handleDragEnter}"
|
|
403
|
+
@dragover="${this.handleDragOver}"
|
|
404
|
+
@dragleave="${this.handleDragLeave}"
|
|
405
|
+
@drop="${this.handleDrop}"
|
|
406
|
+
>
|
|
407
|
+
<div class="drop-mask"><div>Upload Attachment</div></div>
|
|
368
408
|
|
|
369
|
-
|
|
409
|
+
${this.chatbox
|
|
370
410
|
? html `<div class="items chatbox">${this.getChatbox()}</div>`
|
|
371
411
|
: null}
|
|
372
|
-
|
|
373
|
-
? html `<div class="items attachments"
|
|
412
|
+
${this.attachments
|
|
413
|
+
? html `<div class="items attachments">
|
|
414
|
+
${this.getAttachments()}
|
|
415
|
+
</div>`
|
|
374
416
|
: null}
|
|
375
|
-
|
|
376
|
-
|
|
417
|
+
<div class="items actions">${this.getActions()}</div>
|
|
418
|
+
</div>
|
|
419
|
+
</temba-field>
|
|
377
420
|
`;
|
|
378
421
|
}
|
|
379
422
|
getChatbox() {
|
|
380
423
|
return html ` <temba-completion
|
|
381
|
-
value=${this.
|
|
424
|
+
value=${this.currentText}
|
|
382
425
|
gsm
|
|
383
426
|
textarea
|
|
384
427
|
autogrow
|
|
@@ -390,45 +433,45 @@ export class Compose extends FormElement {
|
|
|
390
433
|
}
|
|
391
434
|
getAttachments() {
|
|
392
435
|
return html `
|
|
393
|
-
${(this.
|
|
394
|
-
(this.
|
|
436
|
+
${(this.currentAttachments && this.currentAttachments.length > 0) ||
|
|
437
|
+
(this.failedAttachments && this.failedAttachments.length > 0)
|
|
395
438
|
? html ` <div class="attachments-list">
|
|
396
|
-
${this.
|
|
439
|
+
${this.currentAttachments.map(validAttachment => {
|
|
397
440
|
return html ` <div class="attachment-item">
|
|
398
441
|
<div
|
|
399
442
|
class="remove-item"
|
|
400
|
-
@click="${this.
|
|
443
|
+
@click="${this.handleRemoveFileClicked}"
|
|
401
444
|
>
|
|
402
445
|
<temba-icon
|
|
403
|
-
id="${
|
|
446
|
+
id="${validAttachment.uuid}"
|
|
404
447
|
name="${Icon.delete_small}"
|
|
405
448
|
></temba-icon>
|
|
406
449
|
</div>
|
|
407
450
|
<div class="attachment-name">
|
|
408
451
|
<span
|
|
409
|
-
title="${
|
|
410
|
-
>${truncate(
|
|
411
|
-
(${formatFileSize(
|
|
412
|
-
${formatFileType(
|
|
452
|
+
title="${validAttachment.filename} (${formatFileSize(validAttachment.size, 2)}) ${validAttachment.content_type}"
|
|
453
|
+
>${truncate(validAttachment.filename, 25)}
|
|
454
|
+
(${formatFileSize(validAttachment.size, 0)})
|
|
455
|
+
${formatFileType(validAttachment.content_type)}</span
|
|
413
456
|
>
|
|
414
457
|
</div>
|
|
415
458
|
</div>`;
|
|
416
459
|
})}
|
|
417
|
-
${this.
|
|
460
|
+
${this.failedAttachments.map(invalidAttachment => {
|
|
418
461
|
return html ` <div class="attachment-item error">
|
|
419
462
|
<div
|
|
420
463
|
class="remove-item error"
|
|
421
|
-
@click="${this.
|
|
464
|
+
@click="${this.handleRemoveFileClicked}"
|
|
422
465
|
>
|
|
423
466
|
<temba-icon
|
|
424
|
-
id="${
|
|
467
|
+
id="${invalidAttachment.uuid}"
|
|
425
468
|
name="${Icon.delete_small}"
|
|
426
469
|
></temba-icon>
|
|
427
470
|
</div>
|
|
428
471
|
<div class="attachment-name">
|
|
429
472
|
<span
|
|
430
|
-
title="${
|
|
431
|
-
>${truncate(
|
|
473
|
+
title="${invalidAttachment.filename} (${formatFileSize(0, 0)}) - Attachment failed - ${invalidAttachment.error}"
|
|
474
|
+
>${truncate(invalidAttachment.filename, 25)}
|
|
432
475
|
(${formatFileSize(0, 0)}) - Attachment failed</span
|
|
433
476
|
>
|
|
434
477
|
</div>
|
|
@@ -460,23 +503,28 @@ export class Compose extends FormElement {
|
|
|
460
503
|
else {
|
|
461
504
|
return html ` <input
|
|
462
505
|
type="file"
|
|
463
|
-
id="upload-
|
|
506
|
+
id="upload-input"
|
|
464
507
|
multiple
|
|
465
508
|
accept="${this.accept}"
|
|
466
|
-
@change="${this.
|
|
509
|
+
@change="${this.handleUploadFileInputChanged}"
|
|
467
510
|
/>
|
|
468
|
-
<label
|
|
511
|
+
<label
|
|
512
|
+
id="upload-label"
|
|
513
|
+
class="actions-left upload-label"
|
|
514
|
+
for="upload-input"
|
|
515
|
+
>
|
|
469
516
|
<temba-icon
|
|
517
|
+
id="upload-icon"
|
|
470
518
|
class="upload-icon"
|
|
471
519
|
name="${Icon.attachment}"
|
|
472
|
-
@click="${this.
|
|
520
|
+
@click="${this.handleUploadFileIconClicked}"
|
|
473
521
|
clickable
|
|
474
522
|
></temba-icon>
|
|
475
523
|
</label>`;
|
|
476
524
|
}
|
|
477
525
|
}
|
|
478
526
|
getCounter() {
|
|
479
|
-
return html `<temba-charcount text="${this.
|
|
527
|
+
return html `<temba-charcount text="${this.currentText}"></temba-charcount>`;
|
|
480
528
|
}
|
|
481
529
|
getButton() {
|
|
482
530
|
return html ` <temba-button
|
|
@@ -503,8 +551,8 @@ __decorate([
|
|
|
503
551
|
property({ type: Boolean })
|
|
504
552
|
], Compose.prototype, "button", void 0);
|
|
505
553
|
__decorate([
|
|
506
|
-
property({ type: String
|
|
507
|
-
], Compose.prototype, "
|
|
554
|
+
property({ type: String })
|
|
555
|
+
], Compose.prototype, "currentText", void 0);
|
|
508
556
|
__decorate([
|
|
509
557
|
property({ type: String })
|
|
510
558
|
], Compose.prototype, "accept", void 0);
|
|
@@ -514,9 +562,12 @@ __decorate([
|
|
|
514
562
|
__decorate([
|
|
515
563
|
property({ type: Boolean, attribute: false })
|
|
516
564
|
], Compose.prototype, "uploading", void 0);
|
|
565
|
+
__decorate([
|
|
566
|
+
property({ type: Array })
|
|
567
|
+
], Compose.prototype, "currentAttachments", void 0);
|
|
517
568
|
__decorate([
|
|
518
569
|
property({ type: Array, attribute: false })
|
|
519
|
-
], Compose.prototype, "
|
|
570
|
+
], Compose.prototype, "failedAttachments", void 0);
|
|
520
571
|
__decorate([
|
|
521
572
|
property({ type: String })
|
|
522
573
|
], Compose.prototype, "buttonName", void 0);
|
|
@@ -526,4 +577,13 @@ __decorate([
|
|
|
526
577
|
__decorate([
|
|
527
578
|
property({ type: String, attribute: false })
|
|
528
579
|
], Compose.prototype, "buttonError", void 0);
|
|
580
|
+
__decorate([
|
|
581
|
+
property({ type: Boolean, attribute: 'widget_only' })
|
|
582
|
+
], Compose.prototype, "widgetOnly", void 0);
|
|
583
|
+
__decorate([
|
|
584
|
+
property({ type: Array })
|
|
585
|
+
], Compose.prototype, "errors", void 0);
|
|
586
|
+
__decorate([
|
|
587
|
+
property({ type: String })
|
|
588
|
+
], Compose.prototype, "value", void 0);
|
|
529
589
|
//# sourceMappingURL=Compose.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Compose.js","sourceRoot":"","sources":["../../../src/compose/Compose.ts"],"names":[],"mappings":"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","sourcesContent":["import { TemplateResult, html, css } from 'lit';\nimport { FormElement } from '../FormElement';\nimport { property } from 'lit/decorators.js';\nimport { Icon } from '../vectoricon';\nimport { CustomEventType } from '../interfaces';\nimport {\n formatFileSize,\n formatFileType,\n getClasses,\n postFormData,\n truncate,\n WebResponse,\n} from '../utils';\nimport { Completion } from '../completion/Completion';\nimport { VectorIcon } from '../vectoricon/VectorIcon';\nimport { Button } from '../button/Button';\n\nexport interface Attachment {\n uuid: string;\n content_type: string;\n url: string;\n filename: string;\n size: number;\n error: string;\n}\n\nexport const upload_endpoint = '/api/v2/media.json';\n\nexport class Compose extends FormElement {\n static get styles() {\n return css`\n .container {\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n position: relative;\n\n border-radius: var(--curvature-widget);\n background: var(--color-widget-bg);\n border: 1px solid var(--color-widget-border);\n transition: all ease-in-out var(--transition-speed);\n box-shadow: var(--widget-box-shadow);\n caret-color: var(--input-caret);\n padding: var(--temba-textinput-padding);\n }\n .container:focus-within {\n border-color: var(--color-focus);\n background: var(--color-widget-bg-focused);\n box-shadow: var(--widget-box-shadow-focused);\n }\n\n .drop-mask {\n opacity: 0;\n pointer-events: none;\n position: absolute;\n z-index: 1;\n height: 100%;\n width: 100%;\n bottom: 0;\n right: 0;\n background: rgba(210, 243, 184, 0.8);\n border-radius: var(--curvature-widget);\n margin: -0.5em;\n padding: 0.5em;\n transition: opacity ease-in-out var(--transition-speed);\n display: flex;\n align-items: center;\n text-align: center;\n }\n\n .highlight .drop-mask {\n opacity: 1;\n }\n\n .drop-mask > div {\n margin: auto;\n border-radius: var(--curvature-widget);\n font-weight: 400;\n color: rgba(0, 0, 0, 0.5);\n }\n\n .items {\n }\n\n temba-completion {\n margin-left: 0.3em;\n margin-top: 0.3em;\n --color-widget-border: none;\n --curvature-widget: none;\n --widget-box-shadow: none;\n --widget-box-shadow-focused: none;\n --temba-textinput-padding: 0;\n }\n\n .attachments {\n display: flex;\n flex-direction: column;\n }\n .attachments-list {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n }\n .attachment-item {\n background: rgba(100, 100, 100, 0.1);\n border-radius: 2px;\n margin: 0.3em;\n display: flex;\n color: var(--color-widget-text);\n }\n .attachment-item.error {\n background: rgba(250, 0, 0, 0.1);\n color: rgba(250, 0, 0, 0.75);\n }\n .remove-item {\n cursor: pointer !important;\n padding: 3px 6px;\n border-right: 1px solid rgba(100, 100, 100, 0.2);\n margin-top: 1px;\n background: rgba(100, 100, 100, 0.05);\n }\n\n .remove-item:hover {\n background: rgba(100, 100, 100, 0.1);\n }\n\n .remove-item.error:hover {\n background: rgba(250, 0, 0, 0.1);\n }\n\n .remove-item.error {\n background: rgba(250, 0, 0, 0.05);\n color: rgba(250, 0, 0, 0.75);\n }\n .attachment-name {\n align-self: center;\n font-size: 12px;\n padding: 2px 8px;\n }\n\n .actions {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-left: 0.25em;\n padding: 0.2em;\n }\n\n #upload-files {\n display: none;\n }\n .upload-label {\n display: flex;\n align-items: center;\n }\n .upload-icon {\n color: rgb(102, 102, 102);\n }\n .actions-right {\n display: flex;\n align-items: center;\n }\n temba-charcount {\n margin-right: 5px;\n overflow: hidden;\n --temba-charcount-counts-margin-top: 0px;\n --temba-charcount-summary-margin-top: 0px;\n --temba-charcount-summary-position: fixed;\n --temba-charcount-summary-right: 105px;\n --temba-charcount-summary-bottom: 105px;\n }\n temba-button {\n --button-y: 1px;\n --button-x: 12px;\n }\n .send-error {\n color: rgba(250, 0, 0, 0.75);\n font-size: var(--help-text-size);\n }\n `;\n }\n\n @property({ type: Boolean })\n chatbox: boolean;\n\n @property({ type: Boolean })\n attachments: boolean;\n\n @property({ type: Boolean })\n counter: boolean;\n\n @property({ type: Boolean })\n pendingDrop: boolean;\n\n @property({ type: Boolean })\n button: boolean;\n\n @property({ type: String, attribute: false })\n currentChat = '';\n\n @property({ type: String })\n accept = ''; //e.g. \".xls,.xlsx\"\n\n @property({ type: String, attribute: false })\n endpoint = upload_endpoint;\n\n @property({ type: Boolean, attribute: false })\n uploading: boolean;\n\n // values = valid and uploaded attachments\n // errorValues = invalid and not-uploaded attachments\n @property({ type: Array, attribute: false })\n errorValues: Attachment[] = [];\n\n @property({ type: String })\n buttonName = 'Send';\n\n @property({ type: Boolean, attribute: false })\n buttonDisabled = true;\n\n @property({ type: String, attribute: false })\n buttonError = '';\n\n public constructor() {\n super();\n }\n\n public updated(changes: Map<string, any>): void {\n super.updated(changes);\n\n if (changes.has('currentChat') || changes.has('values')) {\n this.buttonError = '';\n this.toggleButton();\n }\n }\n\n firstUpdated(): void {\n this.setFocusOnChatbox();\n }\n\n setFocusOnChatbox(): void {\n if (this.chatbox) {\n const completion = this.shadowRoot.querySelector(\n 'temba-completion'\n ) as Completion;\n if (completion) {\n //simulate a click inside the completion to set focus\n window.setTimeout(() => {\n completion.click();\n }, 0);\n }\n }\n }\n\n public reset(): void {\n this.currentChat = '';\n this.values = [];\n this.errorValues = [];\n this.buttonError = '';\n }\n\n private handleChatboxChange(evt: Event) {\n const completion = evt.target as Completion;\n const textInput = completion.textInputElement;\n this.currentChat = textInput.value;\n this.preventDefaults(evt);\n }\n\n private handleDragEnter(evt: DragEvent): void {\n this.highlight(evt);\n }\n\n private handleDragOver(evt: DragEvent): void {\n this.highlight(evt);\n }\n\n private handleDragLeave(evt: DragEvent): void {\n this.unhighlight(evt);\n }\n\n private handleDrop(evt: DragEvent): void {\n this.unhighlight(evt);\n\n const dt = evt.dataTransfer;\n if (dt) {\n const files = dt.files;\n this.uploadFiles(files);\n }\n }\n\n private preventDefaults(evt: Event): void {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n private highlight(evt: DragEvent): void {\n this.pendingDrop = true;\n this.preventDefaults(evt);\n }\n\n private unhighlight(evt: DragEvent): void {\n this.pendingDrop = false;\n this.preventDefaults(evt);\n }\n\n private handleAddAttachments(): void {\n this.dispatchEvent(new Event('change'));\n }\n\n private handleUploadFileChanged(evt: Event): void {\n const target = evt.target as HTMLInputElement;\n const files = target.files;\n this.uploadFiles(files);\n }\n\n public uploadFiles(files: FileList): void {\n let filesToUpload = [];\n if (this.values && this.values.length > 0) {\n //remove duplicate files that have already been uploaded\n filesToUpload = [...files].filter(file => {\n const index = this.values.findIndex(\n value => value.name === file.name && value.size === file.size\n );\n if (index === -1) {\n return file;\n }\n });\n } else {\n filesToUpload = [...files];\n }\n filesToUpload.map(fileToUpload => {\n this.uploadFile(fileToUpload);\n });\n }\n\n private uploadFile(file: File): void {\n this.uploading = true;\n\n const url = this.endpoint;\n const payload = new FormData();\n payload.append('file', file);\n postFormData(url, payload)\n .then((response: WebResponse) => {\n const attachment = response.json as Attachment;\n if (attachment) {\n this.addValue(attachment);\n this.fireCustomEvent(CustomEventType.AttachmentAdded, attachment);\n }\n })\n .catch((error: WebResponse) => {\n let fileError = '';\n if (error.status === 400) {\n fileError = error.json.file[0];\n } else {\n fileError = 'Server failure';\n }\n console.error(fileError);\n this.addErrorValue(file, fileError);\n })\n .finally(() => {\n this.uploading = false;\n });\n }\n\n private addErrorValue(file: File, error: string) {\n const errorValue = {\n uuid: Math.random().toString(36).slice(2, 6),\n content_type: file.type,\n filename: file.name,\n url: file.name,\n size: file.size,\n error: error,\n } as Attachment;\n this.errorValues.push(errorValue);\n this.requestUpdate('errorValues');\n }\n public removeErrorValue(valueToRemove: any) {\n this.errorValues = this.errorValues.filter(\n (value: any) => value !== valueToRemove\n );\n this.requestUpdate('errorValues');\n }\n\n private handleRemoveAttachment(evt: Event): void {\n const target = evt.target as HTMLDivElement;\n\n const attachment = this.values.find(({ uuid }) => uuid === target.id);\n if (attachment) {\n this.removeValue(attachment);\n this.fireCustomEvent(CustomEventType.AttachmentRemoved, attachment);\n }\n const errorAttachment = this.errorValues.find(\n ({ uuid }) => uuid === target.id\n );\n if (errorAttachment) {\n this.removeErrorValue(errorAttachment);\n this.fireCustomEvent(CustomEventType.AttachmentRemoved, attachment);\n }\n }\n\n public toggleButton() {\n if (this.button) {\n const chatboxEmpty = this.currentChat.trim().length === 0;\n const attachmentsEmpty = this.values.length === 0;\n if (this.chatbox && this.attachments) {\n this.buttonDisabled = chatboxEmpty && attachmentsEmpty;\n } else if (this.chatbox) {\n this.buttonDisabled = chatboxEmpty;\n } else if (this.attachments) {\n this.buttonDisabled = attachmentsEmpty;\n } else {\n this.buttonDisabled = true;\n }\n }\n }\n\n private handleSendClick() {\n this.handleSend();\n }\n\n private handleSendEnter(evt: KeyboardEvent) {\n if (evt.key === 'Enter' && !evt.shiftKey) {\n const chat = evt.target as Completion;\n if (!chat.hasVisibleOptions()) {\n this.handleSend();\n }\n this.preventDefaults(evt);\n }\n }\n\n private handleSend() {\n if (!this.buttonDisabled) {\n this.buttonDisabled = true;\n const name = this.buttonName;\n this.fireCustomEvent(CustomEventType.ButtonClicked, { name });\n\n //after send, return focus to chatbox\n this.setFocusOnChatbox();\n }\n }\n\n public render(): TemplateResult {\n return html`\n <div\n class=${getClasses({ container: true, highlight: this.pendingDrop })}\n @dragenter=\"${this.handleDragEnter}\"\n @dragover=\"${this.handleDragOver}\"\n @dragleave=\"${this.handleDragLeave}\"\n @drop=\"${this.handleDrop}\"\n >\n <div class=\"drop-mask\"><div>Upload Attachment</div></div>\n\n ${this.chatbox\n ? html`<div class=\"items chatbox\">${this.getChatbox()}</div>`\n : null}\n ${this.attachments\n ? html`<div class=\"items attachments\">${this.getAttachments()}</div>`\n : null}\n <div class=\"items actions\">${this.getActions()}</div>\n </div>\n `;\n }\n\n private getChatbox(): TemplateResult {\n return html` <temba-completion\n value=${this.currentChat}\n gsm\n textarea\n autogrow\n @change=${this.handleChatboxChange}\n @keydown=${this.handleSendEnter}\n placeholder=\"Write something here\"\n >\n </temba-completion>`;\n }\n\n private getAttachments(): TemplateResult {\n return html`\n ${(this.values && this.values.length > 0) ||\n (this.errorValues && this.errorValues.length > 0)\n ? html` <div class=\"attachments-list\">\n ${this.values.map(attachment => {\n return html` <div class=\"attachment-item\">\n <div\n class=\"remove-item\"\n @click=\"${this.handleRemoveAttachment}\"\n >\n <temba-icon\n id=\"${attachment.uuid}\"\n name=\"${Icon.delete_small}\"\n ></temba-icon>\n </div>\n <div class=\"attachment-name\">\n <span\n title=\"${attachment.filename} (${formatFileSize(\n attachment.size,\n 2\n )}) ${attachment.content_type}\"\n >${truncate(attachment.filename, 25)}\n (${formatFileSize(attachment.size, 0)})\n ${formatFileType(attachment.content_type)}</span\n >\n </div>\n </div>`;\n })}\n ${this.errorValues.map(errorAttachment => {\n return html` <div class=\"attachment-item error\">\n <div\n class=\"remove-item error\"\n @click=\"${this.handleRemoveAttachment}\"\n >\n <temba-icon\n id=\"${errorAttachment.uuid}\"\n name=\"${Icon.delete_small}\"\n ></temba-icon>\n </div>\n <div class=\"attachment-name\">\n <span\n title=\"${errorAttachment.filename} (${formatFileSize(\n 0,\n 0\n )}) - Attachment failed - ${errorAttachment.error}\"\n >${truncate(errorAttachment.filename, 25)}\n (${formatFileSize(0, 0)}) - Attachment failed</span\n >\n </div>\n </div>`;\n })}\n </div>`\n : null}\n `;\n }\n\n private getActions(): TemplateResult {\n return html`\n <div class=\"actions-left\">\n ${this.attachments ? this.getUploader() : null}\n </div>\n <div class=\"actions-center\"></div>\n <div class=\"actions-right\">\n ${this.buttonError\n ? html`<div class=\"send-error\">${this.buttonError}</div>`\n : null}\n ${this.counter ? this.getCounter() : null}\n ${this.button ? this.getButton() : null}\n </div>\n `;\n }\n\n private getUploader(): TemplateResult {\n if (this.uploading) {\n return html`<temba-loading units=\"3\" size=\"12\"></temba-loading>`;\n } else {\n return html` <input\n type=\"file\"\n id=\"upload-files\"\n multiple\n accept=\"${this.accept}\"\n @change=\"${this.handleUploadFileChanged}\"\n />\n <label class=\"actions-left upload-label\" for=\"upload-files\">\n <temba-icon\n class=\"upload-icon\"\n name=\"${Icon.attachment}\"\n @click=\"${this.handleAddAttachments}\"\n clickable\n ></temba-icon>\n </label>`;\n }\n }\n\n private getCounter(): TemplateResult {\n return html`<temba-charcount text=\"${this.currentChat}\"></temba-charcount>`;\n }\n\n private getButton(): TemplateResult {\n return html` <temba-button\n id=\"send-button\"\n name=${this.buttonName}\n @click=${this.handleSendClick}\n ?disabled=${this.buttonDisabled}\n ></temba-button>`;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Compose.js","sourceRoot":"","sources":["../../../src/compose/Compose.ts"],"names":[],"mappings":"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","sourcesContent":["import { TemplateResult, html, css } from 'lit';\nimport { FormElement } from '../FormElement';\nimport { property } from 'lit/decorators.js';\nimport { Icon } from '../vectoricon';\nimport { CustomEventType } from '../interfaces';\nimport {\n formatFileSize,\n formatFileType,\n getClasses,\n postFormData,\n truncate,\n WebResponse,\n} from '../utils';\nimport { Completion } from '../completion/Completion';\n\nexport interface Attachment {\n uuid: string;\n content_type: string;\n url: string;\n filename: string;\n size: number;\n error: string;\n}\n\nexport const upload_endpoint = '/api/v2/media.json';\n\nexport class Compose extends FormElement {\n static get styles() {\n return css`\n .container {\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n position: relative;\n\n border-radius: var(--curvature-widget);\n background: var(--color-widget-bg);\n border: 1px solid var(--color-widget-border);\n transition: all ease-in-out var(--transition-speed);\n box-shadow: var(--widget-box-shadow);\n caret-color: var(--input-caret);\n padding: var(--temba-textinput-padding);\n }\n .container:focus-within {\n border-color: var(--color-focus);\n background: var(--color-widget-bg-focused);\n box-shadow: var(--widget-box-shadow-focused);\n }\n\n .drop-mask {\n opacity: 0;\n pointer-events: none;\n position: absolute;\n z-index: 1;\n height: 100%;\n width: 100%;\n bottom: 0;\n right: 0;\n background: rgba(210, 243, 184, 0.8);\n border-radius: var(--curvature-widget);\n margin: -0.5em;\n padding: 0.5em;\n transition: opacity ease-in-out var(--transition-speed);\n display: flex;\n align-items: center;\n text-align: center;\n }\n\n .highlight .drop-mask {\n opacity: 1;\n }\n\n .drop-mask > div {\n margin: auto;\n border-radius: var(--curvature-widget);\n font-weight: 400;\n color: rgba(0, 0, 0, 0.5);\n }\n\n .items {\n }\n\n temba-completion {\n margin-left: 0.3em;\n margin-top: 0.3em;\n --color-widget-border: none;\n --curvature-widget: none;\n --widget-box-shadow: none;\n --widget-box-shadow-focused: none;\n --temba-textinput-padding: 0;\n }\n\n .attachments {\n display: flex;\n flex-direction: column;\n }\n .attachments-list {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n }\n .attachment-item {\n background: rgba(100, 100, 100, 0.1);\n border-radius: 2px;\n margin: 0.3em;\n display: flex;\n color: var(--color-widget-text);\n }\n .attachment-item.error {\n background: rgba(250, 0, 0, 0.1);\n color: rgba(250, 0, 0, 0.75);\n }\n .remove-item {\n cursor: pointer !important;\n padding: 3px 6px;\n border-right: 1px solid rgba(100, 100, 100, 0.2);\n margin-top: 1px;\n background: rgba(100, 100, 100, 0.05);\n }\n\n .remove-item:hover {\n background: rgba(100, 100, 100, 0.1);\n }\n\n .remove-item.error:hover {\n background: rgba(250, 0, 0, 0.1);\n }\n\n .remove-item.error {\n background: rgba(250, 0, 0, 0.05);\n color: rgba(250, 0, 0, 0.75);\n }\n .attachment-name {\n align-self: center;\n font-size: 12px;\n padding: 2px 8px;\n }\n\n .actions {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-left: 0.25em;\n padding: 0.2em;\n }\n\n #upload-input {\n display: none;\n }\n .upload-label {\n display: flex;\n align-items: center;\n }\n .upload-icon {\n color: rgb(102, 102, 102);\n }\n .actions-right {\n display: flex;\n align-items: center;\n }\n temba-charcount {\n margin-right: 5px;\n overflow: hidden;\n --temba-charcount-counts-margin-top: 0px;\n --temba-charcount-summary-margin-top: 0px;\n --temba-charcount-summary-position: fixed;\n --temba-charcount-summary-right: 105px;\n --temba-charcount-summary-bottom: 105px;\n }\n temba-button {\n --button-y: 1px;\n --button-x: 12px;\n }\n .send-error {\n color: rgba(250, 0, 0, 0.75);\n font-size: var(--help-text-size);\n }\n `;\n }\n\n @property({ type: Boolean })\n chatbox: boolean;\n\n @property({ type: Boolean })\n attachments: boolean;\n\n @property({ type: Boolean })\n counter: boolean;\n\n @property({ type: Boolean })\n pendingDrop: boolean;\n\n @property({ type: Boolean })\n button: boolean;\n\n @property({ type: String })\n currentText = '';\n\n @property({ type: String })\n accept = ''; //e.g. \".xls,.xlsx\"\n\n @property({ type: String, attribute: false })\n endpoint = upload_endpoint;\n\n @property({ type: Boolean, attribute: false })\n uploading: boolean;\n\n @property({ type: Array })\n currentAttachments: Attachment[] = [];\n\n @property({ type: Array, attribute: false })\n failedAttachments: Attachment[] = [];\n\n @property({ type: String })\n buttonName = 'Send';\n\n @property({ type: Boolean, attribute: false })\n buttonDisabled = true;\n\n @property({ type: String, attribute: false })\n buttonError = '';\n\n @property({ type: Boolean, attribute: 'widget_only' })\n widgetOnly: boolean;\n\n @property({ type: Array })\n errors: string[];\n\n @property({ type: String })\n value = '';\n\n public constructor() {\n super();\n }\n\n private deserializeComposeValue(): void {\n if (this.value) {\n const parsed_value = JSON.parse(this.value);\n if (this.chatbox) {\n this.currentText = parsed_value.text;\n }\n if (this.attachments) {\n this.currentAttachments = parsed_value.attachments;\n }\n }\n }\n\n private serializeComposeValue(): void {\n const composeValue = {\n text: this.currentText,\n attachments: this.currentAttachments,\n };\n // update this.value...\n this.value = JSON.stringify(composeValue);\n // and then also update this.values...\n // so that the hidden input is updated via FormElement.updateInputs()\n this.values = [composeValue];\n }\n\n public firstUpdated(changes: Map<string, any>): void {\n super.firstUpdated(changes);\n\n this.deserializeComposeValue();\n this.setFocusOnChatbox();\n }\n\n public updated(changes: Map<string, any>): void {\n super.updated(changes);\n\n if (changes.has('currentText') || changes.has('currentAttachments')) {\n this.toggleButton();\n this.setFocusOnChatbox();\n this.serializeComposeValue();\n }\n\n if (changes.has('buttonError')) {\n this.setFocusOnChatbox();\n }\n }\n\n private setFocusOnChatbox(): void {\n if (this.chatbox) {\n const completion = this.shadowRoot.querySelector(\n 'temba-completion'\n ) as Completion;\n if (completion) {\n //simulate a click inside the completion to set focus\n window.setTimeout(() => {\n completion.click();\n }, 0);\n }\n }\n }\n\n public reset(): void {\n this.currentText = '';\n this.currentAttachments = [];\n this.failedAttachments = [];\n this.buttonError = '';\n }\n\n private handleChatboxChange(evt: Event) {\n const completion = evt.target as Completion;\n this.currentText = completion.value;\n }\n\n private handleDragEnter(evt: DragEvent): void {\n this.highlight(evt);\n }\n\n private handleDragOver(evt: DragEvent): void {\n this.highlight(evt);\n }\n\n private handleDragLeave(evt: DragEvent): void {\n this.unhighlight(evt);\n }\n\n private handleDrop(evt: DragEvent): void {\n this.unhighlight(evt);\n\n const dt = evt.dataTransfer;\n if (dt) {\n const files = dt.files;\n this.uploadFiles(files);\n }\n }\n\n private preventDefaults(evt: Event): void {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n private highlight(evt: DragEvent): void {\n this.pendingDrop = true;\n this.preventDefaults(evt);\n }\n\n private unhighlight(evt: DragEvent): void {\n this.pendingDrop = false;\n this.preventDefaults(evt);\n }\n\n private handleUploadFileIconClicked(): void {\n this.dispatchEvent(new Event('change'));\n }\n\n private handleUploadFileInputChanged(evt: Event): void {\n const target = evt.target as HTMLInputElement;\n const files = target.files;\n this.uploadFiles(files);\n }\n\n public uploadFiles(files: FileList): void {\n let filesToUpload = [];\n if (this.currentAttachments && this.currentAttachments.length > 0) {\n //remove duplicate files that have already been uploaded\n filesToUpload = [...files].filter(file => {\n const index = this.currentAttachments.findIndex(\n value => value.filename === file.name && value.size === file.size\n );\n if (index === -1) {\n return file;\n }\n });\n } else {\n filesToUpload = [...files];\n }\n filesToUpload.map(fileToUpload => {\n this.uploadFile(fileToUpload);\n });\n }\n\n private uploadFile(file: File): void {\n this.uploading = true;\n\n const url = this.endpoint;\n const payload = new FormData();\n payload.append('file', file);\n postFormData(url, payload)\n .then((response: WebResponse) => {\n const attachment = response.json as Attachment;\n if (attachment) {\n this.addCurrentAttachment(attachment);\n }\n })\n .catch((error: WebResponse) => {\n let uploadError = '';\n if (error.status === 400) {\n uploadError = error.json.file[0];\n } else {\n uploadError = 'Server failure';\n }\n console.error(uploadError);\n this.addFailedAttachment(file, uploadError);\n })\n .finally(() => {\n this.uploading = false;\n });\n }\n\n private addCurrentAttachment(attachmentToAdd: any) {\n this.currentAttachments.push(attachmentToAdd);\n this.requestUpdate('currentAttachments');\n this.fireCustomEvent(CustomEventType.AttachmentAdded, attachmentToAdd);\n }\n private removeCurrentAttachment(attachmentToRemove: any) {\n this.currentAttachments = this.currentAttachments.filter(\n currentAttachment => currentAttachment !== attachmentToRemove\n );\n this.requestUpdate('currentAttachments');\n this.fireCustomEvent(CustomEventType.AttachmentRemoved, attachmentToRemove);\n }\n\n private addFailedAttachment(file: File, error: string) {\n const failedAttachment = {\n uuid: Math.random().toString(36).slice(2, 6),\n content_type: file.type,\n filename: file.name,\n url: file.name,\n size: file.size,\n error: error,\n } as Attachment;\n this.failedAttachments.push(failedAttachment);\n this.requestUpdate('failedAttachments');\n }\n private removeFailedAttachment(attachmentToRemove: any) {\n this.failedAttachments = this.failedAttachments.filter(\n (failedAttachment: any) => failedAttachment !== attachmentToRemove\n );\n this.requestUpdate('failedAttachments');\n this.fireCustomEvent(CustomEventType.AttachmentRemoved, attachmentToRemove);\n }\n\n private handleRemoveFileClicked(evt: Event): void {\n const target = evt.target as HTMLDivElement;\n\n const currentAttachmentToRemove = this.currentAttachments.find(\n ({ uuid }) => uuid === target.id\n );\n if (currentAttachmentToRemove) {\n this.removeCurrentAttachment(currentAttachmentToRemove);\n }\n\n const failedAttachmentToRemove = this.failedAttachments.find(\n ({ uuid }) => uuid === target.id\n );\n if (failedAttachmentToRemove) {\n this.removeFailedAttachment(failedAttachmentToRemove);\n }\n }\n\n public toggleButton() {\n if (this.button) {\n this.buttonError = '';\n const chatboxEmpty = this.currentText.trim().length === 0;\n const attachmentsEmpty = this.currentAttachments.length === 0;\n if (this.chatbox && this.attachments) {\n this.buttonDisabled = chatboxEmpty && attachmentsEmpty;\n } else if (this.chatbox) {\n this.buttonDisabled = chatboxEmpty;\n } else if (this.attachments) {\n this.buttonDisabled = attachmentsEmpty;\n } else {\n this.buttonDisabled = true;\n }\n }\n }\n\n private handleSendClick(evt: Event) {\n evt.stopPropagation();\n this.handleSend();\n }\n\n private handleSendEnter(evt: KeyboardEvent) {\n if (evt.key === 'Enter' && !evt.shiftKey) {\n const chat = evt.target as Completion;\n if (!chat.hasVisibleOptions()) {\n this.handleSend();\n }\n this.preventDefaults(evt);\n }\n }\n\n private handleSend() {\n if (!this.buttonDisabled) {\n this.buttonDisabled = true;\n const name = this.buttonName;\n this.fireCustomEvent(CustomEventType.ButtonClicked, { name });\n }\n }\n\n public render(): TemplateResult {\n return html`\n <temba-field\n name=${this.name}\n .errors=${this.errors}\n .widgetOnly=${this.widgetOnly}\n value=${this.value}\n >\n <div\n class=${getClasses({ container: true, highlight: this.pendingDrop })}\n @dragenter=\"${this.handleDragEnter}\"\n @dragover=\"${this.handleDragOver}\"\n @dragleave=\"${this.handleDragLeave}\"\n @drop=\"${this.handleDrop}\"\n >\n <div class=\"drop-mask\"><div>Upload Attachment</div></div>\n\n ${this.chatbox\n ? html`<div class=\"items chatbox\">${this.getChatbox()}</div>`\n : null}\n ${this.attachments\n ? html`<div class=\"items attachments\">\n ${this.getAttachments()}\n </div>`\n : null}\n <div class=\"items actions\">${this.getActions()}</div>\n </div>\n </temba-field>\n `;\n }\n\n private getChatbox(): TemplateResult {\n return html` <temba-completion\n value=${this.currentText}\n gsm\n textarea\n autogrow\n @change=${this.handleChatboxChange}\n @keydown=${this.handleSendEnter}\n placeholder=\"Write something here\"\n >\n </temba-completion>`;\n }\n\n private getAttachments(): TemplateResult {\n return html`\n ${(this.currentAttachments && this.currentAttachments.length > 0) ||\n (this.failedAttachments && this.failedAttachments.length > 0)\n ? html` <div class=\"attachments-list\">\n ${this.currentAttachments.map(validAttachment => {\n return html` <div class=\"attachment-item\">\n <div\n class=\"remove-item\"\n @click=\"${this.handleRemoveFileClicked}\"\n >\n <temba-icon\n id=\"${validAttachment.uuid}\"\n name=\"${Icon.delete_small}\"\n ></temba-icon>\n </div>\n <div class=\"attachment-name\">\n <span\n title=\"${validAttachment.filename} (${formatFileSize(\n validAttachment.size,\n 2\n )}) ${validAttachment.content_type}\"\n >${truncate(validAttachment.filename, 25)}\n (${formatFileSize(validAttachment.size, 0)})\n ${formatFileType(validAttachment.content_type)}</span\n >\n </div>\n </div>`;\n })}\n ${this.failedAttachments.map(invalidAttachment => {\n return html` <div class=\"attachment-item error\">\n <div\n class=\"remove-item error\"\n @click=\"${this.handleRemoveFileClicked}\"\n >\n <temba-icon\n id=\"${invalidAttachment.uuid}\"\n name=\"${Icon.delete_small}\"\n ></temba-icon>\n </div>\n <div class=\"attachment-name\">\n <span\n title=\"${invalidAttachment.filename} (${formatFileSize(\n 0,\n 0\n )}) - Attachment failed - ${invalidAttachment.error}\"\n >${truncate(invalidAttachment.filename, 25)}\n (${formatFileSize(0, 0)}) - Attachment failed</span\n >\n </div>\n </div>`;\n })}\n </div>`\n : null}\n `;\n }\n\n private getActions(): TemplateResult {\n return html`\n <div class=\"actions-left\">\n ${this.attachments ? this.getUploader() : null}\n </div>\n <div class=\"actions-center\"></div>\n <div class=\"actions-right\">\n ${this.buttonError\n ? html`<div class=\"send-error\">${this.buttonError}</div>`\n : null}\n ${this.counter ? this.getCounter() : null}\n ${this.button ? this.getButton() : null}\n </div>\n `;\n }\n\n private getUploader(): TemplateResult {\n if (this.uploading) {\n return html`<temba-loading units=\"3\" size=\"12\"></temba-loading>`;\n } else {\n return html` <input\n type=\"file\"\n id=\"upload-input\"\n multiple\n accept=\"${this.accept}\"\n @change=\"${this.handleUploadFileInputChanged}\"\n />\n <label\n id=\"upload-label\"\n class=\"actions-left upload-label\"\n for=\"upload-input\"\n >\n <temba-icon\n id=\"upload-icon\"\n class=\"upload-icon\"\n name=\"${Icon.attachment}\"\n @click=\"${this.handleUploadFileIconClicked}\"\n clickable\n ></temba-icon>\n </label>`;\n }\n }\n\n private getCounter(): TemplateResult {\n return html`<temba-charcount text=\"${this.currentText}\"></temba-charcount>`;\n }\n\n private getButton(): TemplateResult {\n return html` <temba-button\n id=\"send-button\"\n name=${this.buttonName}\n @click=${this.handleSendClick}\n ?disabled=${this.buttonDisabled}\n ></temba-button>`;\n }\n}\n"]}
|
|
@@ -158,7 +158,6 @@ export class ContactChat extends ContactStoreElement {
|
|
|
158
158
|
constructor() {
|
|
159
159
|
super();
|
|
160
160
|
this.contactsEndpoint = '/api/v2/contacts.json';
|
|
161
|
-
this.currentChat = '';
|
|
162
161
|
this.currentNote = '';
|
|
163
162
|
this.showDetails = true;
|
|
164
163
|
this.toolbar = false;
|
|
@@ -229,16 +228,14 @@ export class ContactChat extends ContactStoreElement {
|
|
|
229
228
|
};
|
|
230
229
|
const compose = evt.currentTarget;
|
|
231
230
|
if (compose) {
|
|
232
|
-
const text = compose.
|
|
233
|
-
if (text.length > 0) {
|
|
231
|
+
const text = compose.currentText;
|
|
232
|
+
if (text && text.length > 0) {
|
|
234
233
|
payload['text'] = text;
|
|
235
234
|
}
|
|
236
|
-
const attachments = compose.
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
if (attachments.length > 0) {
|
|
241
|
-
payload['attachments'] = attachments;
|
|
235
|
+
const attachments = compose.currentAttachments;
|
|
236
|
+
if (attachments && attachments.length > 0) {
|
|
237
|
+
const attachment_uuids = attachments.map(attachment => attachment.uuid);
|
|
238
|
+
payload['attachments'] = attachment_uuids;
|
|
242
239
|
}
|
|
243
240
|
}
|
|
244
241
|
if (this.currentTicket) {
|
|
@@ -451,9 +448,6 @@ __decorate([
|
|
|
451
448
|
__decorate([
|
|
452
449
|
property({ type: String })
|
|
453
450
|
], ContactChat.prototype, "contactsEndpoint", void 0);
|
|
454
|
-
__decorate([
|
|
455
|
-
property({ type: String })
|
|
456
|
-
], ContactChat.prototype, "currentChat", void 0);
|
|
457
451
|
__decorate([
|
|
458
452
|
property({ type: String })
|
|
459
453
|
], ContactChat.prototype, "currentNote", void 0);
|