@nyaruka/temba-components 0.108.6 → 0.109.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.
Files changed (120) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/static/svg/index.svg +1 -1
  3. package/dist/temba-components.js +602 -455
  4. package/dist/temba-components.js.map +1 -1
  5. package/out-tsc/src/charcount/CharCount.js +4 -5
  6. package/out-tsc/src/charcount/CharCount.js.map +1 -1
  7. package/out-tsc/src/completion/Completion.js +27 -16
  8. package/out-tsc/src/completion/Completion.js.map +1 -1
  9. package/out-tsc/src/compose/Compose.js +259 -95
  10. package/out-tsc/src/compose/Compose.js.map +1 -1
  11. package/out-tsc/src/contacts/ContactChat.js +18 -16
  12. package/out-tsc/src/contacts/ContactChat.js.map +1 -1
  13. package/out-tsc/src/contacts/ContactTickets.js +1 -1
  14. package/out-tsc/src/contacts/ContactTickets.js.map +1 -1
  15. package/out-tsc/src/interfaces.js.map +1 -1
  16. package/out-tsc/src/list/ShortcutList.js +125 -0
  17. package/out-tsc/src/list/ShortcutList.js.map +1 -0
  18. package/out-tsc/src/list/TembaList.js +8 -5
  19. package/out-tsc/src/list/TembaList.js.map +1 -1
  20. package/out-tsc/src/options/Options.js +46 -35
  21. package/out-tsc/src/options/Options.js.map +1 -1
  22. package/out-tsc/src/select/Select.js +1 -1
  23. package/out-tsc/src/select/Select.js.map +1 -1
  24. package/out-tsc/src/store/Store.js +18 -3
  25. package/out-tsc/src/store/Store.js.map +1 -1
  26. package/out-tsc/src/tabpane/Tab.js +2 -0
  27. package/out-tsc/src/tabpane/Tab.js.map +1 -1
  28. package/out-tsc/src/tabpane/TabPane.js +27 -5
  29. package/out-tsc/src/tabpane/TabPane.js.map +1 -1
  30. package/out-tsc/src/textinput/TextInput.js +7 -2
  31. package/out-tsc/src/textinput/TextInput.js.map +1 -1
  32. package/out-tsc/src/utils/index.js.map +1 -1
  33. package/out-tsc/src/vectoricon/index.js +4 -3
  34. package/out-tsc/src/vectoricon/index.js.map +1 -1
  35. package/out-tsc/temba-modules.js +2 -0
  36. package/out-tsc/temba-modules.js.map +1 -1
  37. package/out-tsc/test/temba-compose.test.js +26 -18
  38. package/out-tsc/test/temba-compose.test.js.map +1 -1
  39. package/out-tsc/test/temba-contact-chat.test.js +27 -18
  40. package/out-tsc/test/temba-contact-chat.test.js.map +1 -1
  41. package/package.json +1 -1
  42. package/screenshots/truth/compose/attachments-and-send-button.png +0 -0
  43. package/screenshots/truth/compose/attachments-no-send-button.png +0 -0
  44. package/screenshots/truth/compose/attachments-with-all-files-and-click-send.png +0 -0
  45. package/screenshots/truth/compose/attachments-with-all-files.png +0 -0
  46. package/screenshots/truth/compose/attachments-with-failure-files.png +0 -0
  47. package/screenshots/truth/compose/attachments-with-success-files-and-click-send.png +0 -0
  48. package/screenshots/truth/compose/attachments-with-success-files.png +0 -0
  49. package/screenshots/truth/compose/chatbox-attachments-counter-and-send-button.png +0 -0
  50. package/screenshots/truth/compose/chatbox-attachments-counter-no-send-button.png +0 -0
  51. package/screenshots/truth/compose/chatbox-attachments-no-counter-and-send-button.png +0 -0
  52. package/screenshots/truth/compose/chatbox-attachments-no-counter-no-send-button.png +0 -0
  53. package/screenshots/truth/compose/chatbox-counter-and-send-button.png +0 -0
  54. package/screenshots/truth/compose/chatbox-counter-no-send-button.png +0 -0
  55. package/screenshots/truth/compose/chatbox-no-counter-and-send-button.png +0 -0
  56. package/screenshots/truth/compose/chatbox-no-counter-no-send-button.png +0 -0
  57. package/screenshots/truth/compose/chatbox-no-text-attachments-with-all-files-and-click-send.png +0 -0
  58. package/screenshots/truth/compose/chatbox-no-text-attachments-with-all-files.png +0 -0
  59. package/screenshots/truth/compose/chatbox-no-text-attachments-with-failure-files.png +0 -0
  60. package/screenshots/truth/compose/chatbox-no-text-attachments-with-success-files-and-click-send.png +0 -0
  61. package/screenshots/truth/compose/chatbox-no-text-attachments-with-success-files.png +0 -0
  62. package/screenshots/truth/compose/chatbox-with-text-and-click-send.png +0 -0
  63. package/screenshots/truth/compose/chatbox-with-text-and-hit-enter.png +0 -0
  64. package/screenshots/truth/compose/chatbox-with-text-and-spaces.png +0 -0
  65. package/screenshots/truth/compose/chatbox-with-text-and-url.png +0 -0
  66. package/screenshots/truth/compose/chatbox-with-text-attachments-no-files-and-click-send.png +0 -0
  67. package/screenshots/truth/compose/chatbox-with-text-attachments-no-files-and-hit-enter.png +0 -0
  68. package/screenshots/truth/compose/chatbox-with-text-attachments-no-files.png +0 -0
  69. package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files-and-click-send.png +0 -0
  70. package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files-and-hit-enter.png +0 -0
  71. package/screenshots/truth/compose/chatbox-with-text-attachments-with-all-files.png +0 -0
  72. package/screenshots/truth/compose/chatbox-with-text-attachments-with-failure-files.png +0 -0
  73. package/screenshots/truth/compose/chatbox-with-text-attachments-with-success-files-and-click-send.png +0 -0
  74. package/screenshots/truth/compose/chatbox-with-text-attachments-with-success-files-and-hit-enter.png +0 -0
  75. package/screenshots/truth/compose/chatbox-with-text-attachments-with-success-files.png +0 -0
  76. package/screenshots/truth/compose/chatbox-with-text-no-spaces.png +0 -0
  77. package/screenshots/truth/compose/chatbox-with-text.png +0 -0
  78. package/screenshots/truth/contacts/compose-attachments-no-text-failure.png +0 -0
  79. package/screenshots/truth/contacts/compose-attachments-no-text-success.png +0 -0
  80. package/screenshots/truth/contacts/compose-text-and-attachments-failure-attachments.png +0 -0
  81. package/screenshots/truth/contacts/compose-text-and-attachments-failure-generic.png +0 -0
  82. package/screenshots/truth/contacts/compose-text-and-attachments-failure-text-and-attachments.png +0 -0
  83. package/screenshots/truth/contacts/compose-text-and-attachments-failure-text.png +0 -0
  84. package/screenshots/truth/contacts/compose-text-and-attachments-success.png +0 -0
  85. package/screenshots/truth/contacts/compose-text-no-attachments-failure.png +0 -0
  86. package/screenshots/truth/contacts/compose-text-no-attachments-success.png +0 -0
  87. package/screenshots/truth/contacts/contact-active-default.png +0 -0
  88. package/screenshots/truth/contacts/contact-active-show-chatbox.png +0 -0
  89. package/screenshots/truth/counter/summary.png +0 -0
  90. package/screenshots/truth/counter/text.png +0 -0
  91. package/screenshots/truth/counter/unicode-variables.png +0 -0
  92. package/screenshots/truth/counter/unicode.png +0 -0
  93. package/screenshots/truth/counter/variable.png +0 -0
  94. package/src/charcount/CharCount.ts +4 -5
  95. package/src/completion/Completion.ts +33 -19
  96. package/src/compose/Compose.ts +289 -96
  97. package/src/contacts/ContactChat.ts +18 -16
  98. package/src/contacts/ContactTickets.ts +1 -1
  99. package/src/interfaces.ts +7 -0
  100. package/src/list/ShortcutList.ts +137 -0
  101. package/src/list/TembaList.ts +9 -6
  102. package/src/options/Options.ts +53 -44
  103. package/src/select/Select.ts +1 -1
  104. package/src/store/Store.ts +23 -4
  105. package/src/tabpane/Tab.ts +2 -0
  106. package/src/tabpane/TabPane.ts +28 -5
  107. package/src/textinput/TextInput.ts +9 -3
  108. package/src/utils/index.ts +8 -2
  109. package/src/vectoricon/index.ts +4 -3
  110. package/static/svg/index.svg +1 -1
  111. package/static/svg/work/traced/user-plus-01.svg +1 -0
  112. package/static/svg/work/traced/zap-fast.svg +1 -0
  113. package/static/svg/work/used/user-plus-01.svg +3 -0
  114. package/static/svg/work/used/zap-fast.svg +3 -0
  115. package/temba-modules.ts +2 -0
  116. package/test/temba-compose.test.ts +28 -35
  117. package/test/temba-contact-chat.test.ts +28 -37
  118. package/test-assets/store/shortcuts.json +14 -0
  119. package/static/svg/work/traced/message-dots-circle.svg +0 -1
  120. package/static/svg/work/used/message-dots-circle.svg +0 -3
@@ -8,7 +8,6 @@ export class Compose extends FormElement {
8
8
  static get styles() {
9
9
  return css `
10
10
  :host {
11
- --textarea-min-height: var(--textarea-min-height, 4em);
12
11
  overflow: hidden;
13
12
  border-top-right-radius: var(--curvature);
14
13
  border-top-left-radius: var(--curvature);
@@ -27,13 +26,15 @@ export class Compose extends FormElement {
27
26
  flex-direction: column;
28
27
  justify-content: space-between;
29
28
  position: relative;
30
-
31
- border-radius: var(--curvature-widget);
29
+ overflow: hidden;
30
+ border-radius: var(--compose-curvature, var(--curvature-widget));
32
31
  background: var(--color-widget-bg);
33
32
  border: var(--compose-border, 1px solid var(--color-widget-border));
34
33
  transition: all ease-in-out var(--transition-speed);
35
34
  box-shadow: var(--compose-shadow, var(--widget-box-shadow));
36
35
  caret-color: var(--input-caret);
36
+ --color-widget-bg-focused: transparent;
37
+ --color-widget-bg: transparent;
37
38
  }
38
39
 
39
40
  .chatbox {
@@ -44,7 +45,10 @@ export class Compose extends FormElement {
44
45
  );
45
46
 
46
47
  --widget-box-shadow: none;
47
- padding: var(--compose-padding, 0px);
48
+ display: block;
49
+ flex-grow: 1;
50
+ --widget-box-shadow-focused: none;
51
+ --temba-textinput-padding: 1em 1em;
48
52
  }
49
53
 
50
54
  .actions {
@@ -53,9 +57,6 @@ export class Compose extends FormElement {
53
57
  align-items: center;
54
58
  padding: 0em;
55
59
  background: #f9f9f9;
56
- border-bottom-left-radius: var(--curvature);
57
- border-bottom-right-radius: var(--curvature);
58
- border-top: solid 1px var(--color-widget-border);
59
60
  }
60
61
 
61
62
  .actions-right {
@@ -81,6 +82,7 @@ export class Compose extends FormElement {
81
82
  .send-error {
82
83
  color: rgba(250, 0, 0, 0.75);
83
84
  font-size: var(--help-text-size);
85
+ padding: 0.5em;
84
86
  }
85
87
 
86
88
  .language {
@@ -93,12 +95,19 @@ export class Compose extends FormElement {
93
95
  display: flex;
94
96
  }
95
97
 
98
+ .gutter {
99
+ align-items: center;
100
+ display: flex;
101
+ margin: 0.5em;
102
+ }
103
+
96
104
  #send-button {
97
105
  margin: 0.3em;
98
106
  }
99
107
 
100
108
  temba-tabs {
101
109
  --focused-tab-color: #f4f4f4;
110
+ min-height: var(--compose-min-height, 13.5em);
102
111
  }
103
112
 
104
113
  .quick-replies {
@@ -106,14 +115,47 @@ export class Compose extends FormElement {
106
115
  }
107
116
 
108
117
  .optins {
109
- padding: 1em;
118
+ margin: 0.8em;
119
+ }
120
+
121
+ .templates {
122
+ margin: 0.8em;
110
123
  }
111
124
 
112
125
  .attachments {
126
+ min-height: 5em;
127
+ padding: 0.2em;
128
+ align-items: center;
129
+ display: flex;
130
+ background: #f9f9f9;
131
+ border-radius: var(--curvature);
132
+ margin: 0.6em;
133
+ margin-bottom: 0em;
134
+ }
135
+
136
+ .pane-bottom {
137
+ border: 0px solid red;
138
+ --color-placeholder: rgba(0, 0, 0, 0.2);
139
+ flex-grow: 99;
113
140
  }
114
141
 
115
- temba-template-editor {
116
- padding: 1em;
142
+ .shortcut-wrapper {
143
+ max-height: var(--shortcuts-height, 12em);
144
+ display: flex;
145
+ flex-direction: row;
146
+ align-items: stretch;
147
+ --options-block-shadow: none;
148
+ --curvature-widget: 0px;
149
+ --color-options-bg: #fff;
150
+ border-bottom: 1px solid var(--color-widget-border);
151
+ }
152
+
153
+ temba-shortcuts {
154
+ flex-grow: 1;
155
+ }
156
+
157
+ .quick-replies {
158
+ background: #f9f9f9;
117
159
  }
118
160
  `;
119
161
  }
@@ -138,6 +180,7 @@ export class Compose extends FormElement {
138
180
  this.buttonError = '';
139
181
  this.langValues = {};
140
182
  this.currentLanguage = 'und';
183
+ this.hasPendingText = false;
141
184
  }
142
185
  isBaseLanguage() {
143
186
  return (this.currentLanguage == 'und' ||
@@ -146,6 +189,11 @@ export class Compose extends FormElement {
146
189
  handleTabChanged() {
147
190
  const tabs = this.shadowRoot.querySelector('temba-tabs');
148
191
  this.currentTab = tabs.getCurrentTab();
192
+ if (this.currentTab && this.currentTab.name === 'Shortcuts') {
193
+ const shortcuts = this.shadowRoot.querySelector('temba-shortcuts');
194
+ shortcuts.filter = '';
195
+ }
196
+ this.setFocusOnChatbox();
149
197
  }
150
198
  firstUpdated(changes) {
151
199
  var _a, _b;
@@ -229,13 +277,14 @@ export class Compose extends FormElement {
229
277
  if (completion) {
230
278
  window.setTimeout(() => {
231
279
  completion.focus();
232
- // this.resetTabs();
233
280
  }, 0);
234
281
  }
235
282
  }
236
283
  }
237
284
  reset() {
238
- this.shadowRoot.querySelector('.chatbox').value = '';
285
+ const completion = this.shadowRoot.querySelector('.chatbox');
286
+ completion.textInputElement.value = '';
287
+ completion.value = '';
239
288
  this.initialText = '';
240
289
  this.currentText = '';
241
290
  this.currentQuickReplies = [];
@@ -252,7 +301,21 @@ export class Compose extends FormElement {
252
301
  }
253
302
  handleChatboxChange(evt) {
254
303
  const chatbox = evt.target;
255
- this.currentText = chatbox.value;
304
+ const inputElement = chatbox.getTextInput().inputElement;
305
+ this.currentText = inputElement.value;
306
+ this.hasPendingText = inputElement.value.length > 0;
307
+ // is the last character a / and is it at the beginning of the line
308
+ const cursor = inputElement.selectionStart;
309
+ const text = inputElement.value;
310
+ const lineStart = text.lastIndexOf('\n', cursor - 1) + 1;
311
+ const line = text.substring(lineStart, cursor);
312
+ if (line.startsWith('/')) {
313
+ // switch to the shortcuts tab
314
+ const tabs = this.shadowRoot.querySelector('temba-tabs');
315
+ tabs.focusTab('Shortcuts');
316
+ const shortcuts = this.shadowRoot.querySelector('temba-shortcuts');
317
+ shortcuts.filter = line.substring(1);
318
+ }
256
319
  }
257
320
  toggleButton() {
258
321
  if (this.button) {
@@ -277,18 +340,62 @@ export class Compose extends FormElement {
277
340
  evt.stopPropagation();
278
341
  this.handleSend();
279
342
  }
280
- handleSendEnter(evt) {
281
- if (this.button) {
343
+ getCurrentLine() {
344
+ const chatbox = this.shadowRoot.querySelector('.chatbox');
345
+ const cursor = chatbox.getTextInput().inputElement.selectionStart - 1;
346
+ const text = chatbox.value;
347
+ const start = text.substring(0, cursor).lastIndexOf('\n') + 1;
348
+ let end = chatbox.value.indexOf('\n', start);
349
+ if (end === -1) {
350
+ end = chatbox.value.length;
351
+ }
352
+ return { text: chatbox.value.substring(start, end), index: start };
353
+ }
354
+ handleKeyDown(evt) {
355
+ const tabs = this.shadowRoot.querySelector('temba-tabs');
356
+ const num = parseInt(evt.key);
357
+ if (!Number.isNaN(num) &&
358
+ num > 0 &&
359
+ evt.ctrlKey &&
360
+ evt.metaKey &&
361
+ num <= tabs.tabs.length) {
362
+ tabs.index = num - 1;
363
+ }
364
+ // if they type / as the first character in a line, switch to the shortcut
365
+ if (evt.key === '/' && this.currentTab.name !== 'Shortcuts') {
366
+ const line = this.getCurrentLine();
367
+ const text = line.text.trim();
368
+ if (text.trim().length === 1) {
369
+ evt.preventDefault();
370
+ tabs.index = tabs.tabs.findIndex((tab) => tab.name === 'Shortcuts');
371
+ }
372
+ }
373
+ else if (evt.key === 'Backspace') {
374
+ const line = this.getCurrentLine();
375
+ const text = line.text;
376
+ if (text === '/') {
377
+ tabs.index = tabs.tabs.findIndex((tab) => tab.name === 'Reply');
378
+ }
379
+ }
380
+ if (this.currentTab.name === 'Shortcuts') {
282
381
  if (evt.key === 'Enter' && !evt.shiftKey) {
283
- if (this.completion) {
284
- const chat = evt.target;
285
- if (!chat.hasVisibleOptions()) {
382
+ return;
383
+ }
384
+ }
385
+ if (this.button) {
386
+ if (evt.key === 'Enter') {
387
+ if (!evt.shiftKey) {
388
+ evt.preventDefault();
389
+ if (this.completion) {
390
+ const chat = evt.target;
391
+ if (!chat.hasVisibleOptions()) {
392
+ this.handleSend();
393
+ }
394
+ }
395
+ else {
286
396
  this.handleSend();
287
397
  }
288
398
  }
289
- else {
290
- this.handleSend();
291
- }
292
399
  }
293
400
  }
294
401
  }
@@ -304,7 +411,7 @@ export class Compose extends FormElement {
304
411
  this.currentLanguage = select.values[0].iso;
305
412
  }
306
413
  resetTabs() {
307
- this.shadowRoot.querySelector('temba-tabs').index = -1;
414
+ this.shadowRoot.querySelector('temba-tabs').index = 0;
308
415
  }
309
416
  render() {
310
417
  return html `
@@ -330,42 +437,11 @@ export class Compose extends FormElement {
330
437
  </temba-select>`
331
438
  : null}
332
439
  <div class="container">
333
- ${this.chatbox ? html `${this.getChatbox()}` : null}
334
440
  <div class="items actions">${this.getActions()}</div>
335
441
  </div>
336
442
  </temba-field>
337
443
  `;
338
444
  }
339
- getChatbox() {
340
- if (this.completion) {
341
- return html `<temba-completion
342
- class="chatbox"
343
- .value=${this.initialText}
344
- gsm
345
- textarea
346
- ?autogrow=${this.autogrow}
347
- maxlength=${this.maxLength}
348
- @change=${this.handleChatboxChange}
349
- @keydown=${this.handleSendEnter}
350
- placeholder="Write something here"
351
- >
352
- </temba-completion>`;
353
- }
354
- else {
355
- return html `<temba-textinput
356
- class="chatbox"
357
- gsm
358
- textarea
359
- ?autogrow=${this.autogrow}
360
- maxlength=${this.maxLength}
361
- .value=${this.initialText}
362
- @change=${this.handleChatboxChange}
363
- @keydown=${this.handleSendEnter}
364
- placeholder="Write something here"
365
- >
366
- </temba-textinput>`;
367
- }
368
- }
369
445
  handleTemplateChanged(evt) {
370
446
  var _a;
371
447
  this.currentTemplate = evt.detail.template;
@@ -375,6 +451,37 @@ export class Compose extends FormElement {
375
451
  handleTemplateVariablesChanged(evt) {
376
452
  this.variables = [...evt.detail.variables];
377
453
  }
454
+ getTextInput() {
455
+ return this.shadowRoot.querySelector('.chatbox').getTextInput();
456
+ }
457
+ handleShortcutSelection(event) {
458
+ this.activeShortcut = event.detail.selected;
459
+ const line = this.getCurrentLine();
460
+ const chatbox = this.getTextInput();
461
+ const originalText = chatbox.value;
462
+ if (line.text.startsWith('/')) {
463
+ const newText = originalText.substring(0, line.index) +
464
+ this.activeShortcut.text +
465
+ originalText.substring(line.index + line.text.length);
466
+ chatbox.updateValue(newText);
467
+ // set our cursor to the end of the shortcut
468
+ const cursor = line.index + this.activeShortcut.text.length;
469
+ chatbox.inputElement.setSelectionRange(cursor, cursor);
470
+ }
471
+ else {
472
+ // add the text where the cursor is
473
+ const cursor = chatbox.inputElement.selectionStart;
474
+ const newText = originalText.substring(0, cursor) +
475
+ this.activeShortcut.text +
476
+ originalText.substring(cursor);
477
+ chatbox.updateValue(newText);
478
+ // set the cursor to the end of the shortcut text
479
+ const newCursor = cursor + this.activeShortcut.text.length;
480
+ chatbox.inputElement.setSelectionRange(newCursor, newCursor);
481
+ }
482
+ const tabs = this.shadowRoot.querySelector('temba-tabs');
483
+ tabs.index = tabs.tabs.findIndex((tab) => tab.name === 'Reply');
484
+ }
378
485
  getActions() {
379
486
  const showOptins = this.optIns && this.isBaseLanguage();
380
487
  const showTemplates = this.templates && this.isBaseLanguage();
@@ -382,17 +489,22 @@ export class Compose extends FormElement {
382
489
  <temba-tabs
383
490
  embedded
384
491
  focusedname
385
- bottom
386
- unselect
492
+ index="0"
387
493
  @temba-context-changed=${this.handleTabChanged}
388
494
  refresh="${(this.currentAttachments || []).length}|${this.index}|${this
389
495
  .currentQuickReplies.length}|${showOptins}|${this
390
496
  .currentOptin}|${showTemplates}|${this.currentTemplate}"
391
497
  >
498
+ <temba-tab
499
+ name="Reply"
500
+ icon="message"
501
+ selectionBackground="#fff"
502
+ ></temba-tab>
392
503
  ${this.attachments
393
504
  ? html `<temba-tab
394
505
  name="Attachments"
395
506
  icon="attachment"
507
+ selectionBackground="#fff"
396
508
  .count=${(this.currentAttachments || []).length}
397
509
  >
398
510
  <div class="items attachments">
@@ -409,9 +521,11 @@ export class Compose extends FormElement {
409
521
  ? html `<temba-tab
410
522
  name="Quick Replies"
411
523
  icon="quick_replies"
524
+ selectionBackground="#fff"
412
525
  .count=${this.currentQuickReplies.length}
413
526
  >
414
527
  <temba-select
528
+ class="quick-replies"
415
529
  @change=${this.handleQuickReplyChange}
416
530
  .values=${this.currentQuickReplies}
417
531
  class="quick-replies"
@@ -423,48 +537,90 @@ export class Compose extends FormElement {
423
537
  ></temba-select>
424
538
  </temba-tab>`
425
539
  : null}
426
- <temba-tab
427
- name="Opt-in"
428
- icon="channel_fba"
429
- ?hidden=${!showOptins}
430
- ?checked=${this.currentOptin.length > 0}
431
- >
432
- <temba-select
433
- @change=${this.handleOptInChange}
434
- .values=${this.currentOptin}
435
- endpoint="${this.optinEndpoint}"
436
- class="optins"
437
- searchable
438
- clearable
439
- placeholder="Select an opt-in to use for Facebook (optional)"
440
- ></temba-select>
441
- </temba-tab>
540
+ ${showOptins
541
+ ? html `<temba-tab
542
+ name="Opt-in"
543
+ icon="channel_fba"
544
+ selectionBackground="#fff"
545
+ ?hidden=${!showOptins}
546
+ ?checked=${this.currentOptin.length > 0}
547
+ >
548
+ <temba-select
549
+ @change=${this.handleOptInChange}
550
+ .values=${this.currentOptin}
551
+ endpoint="${this.optinEndpoint}"
552
+ class="optins"
553
+ searchable
554
+ clearable
555
+ placeholder="Select an opt-in to use for Facebook (optional)"
556
+ ></temba-select>
557
+ </temba-tab>`
558
+ : null}
559
+ ${showTemplates
560
+ ? html `<temba-tab
561
+ name="Template"
562
+ icon="channel_wa"
563
+ selectionBackground="#fff"
564
+ ?alert=${this.errors &&
565
+ this.errors.find((error) => error.includes('template'))}
566
+ ?hidden=${!showTemplates}
567
+ ?checked=${this.currentTemplate}
568
+ >
569
+ <temba-template-editor
570
+ class="templates"
571
+ @temba-context-changed=${this.handleTemplateChanged}
572
+ @temba-content-changed=${this.handleTemplateVariablesChanged}
573
+ template=${this.template}
574
+ variables=${JSON.stringify(this.variables)}
575
+ url=${this.templateEndpoint}
576
+ lang=${this.currentLanguage}
577
+ >
578
+ </temba-template-editor>
579
+ </temba-tab>`
580
+ : null}
442
581
 
443
- <temba-tab
444
- name="Template"
445
- icon="channel_wa"
446
- ?alert=${this.errors &&
447
- this.errors.find((error) => error.includes('template'))}
448
- ?hidden=${!showTemplates}
449
- ?checked=${this.currentTemplate}
450
- >
451
- <temba-template-editor
452
- @temba-context-changed=${this.handleTemplateChanged}
453
- @temba-content-changed=${this.handleTemplateVariablesChanged}
454
- template=${this.template}
455
- variables=${JSON.stringify(this.variables)}
456
- url=${this.templateEndpoint}
457
- lang=${this.currentLanguage}
458
- >
459
- </temba-template-editor>
582
+ <!--temba-tab
583
+ name="Note"
584
+ icon="notes"
585
+ activityColor="#ffbd00"
586
+ selectionBackground="#fff9c2"
587
+ borderColor="#ebdf6f"
588
+ ></temba-tab-->
589
+
590
+ <temba-tab name="Shortcuts" icon="shortcut" selectionBackground="#fff">
591
+ <div class="shortcut-wrapper">
592
+ <temba-shortcuts
593
+ @temba-selection=${this.handleShortcutSelection}
594
+ ></temba-shortcuts>
595
+ </div>
460
596
  </temba-tab>
461
597
 
462
598
  <div slot="tab-right" class="top-right">
599
+ ${this.counter ? this.getCounter() : null}
600
+ </div>
601
+
602
+ <div
603
+ slot="pane-bottom"
604
+ class="pane-bottom ${this.hasPendingText ? 'pending' : ''}"
605
+ >
606
+ ${this.chatbox
607
+ ? html `<temba-completion
608
+ class="chatbox"
609
+ .value=${this.initialText}
610
+ gsm
611
+ textarea
612
+ ?disableCompletion=${!this.completion}
613
+ ?autogrow=${this.autogrow}
614
+ maxlength=${this.maxLength}
615
+ @change=${this.handleChatboxChange}
616
+ @keydown=${this.handleKeyDown}
617
+ placeholder="Write something here"
618
+ >
619
+ </temba-completion>`
620
+ : null}
463
621
  ${this.buttonError
464
622
  ? html `<div class="send-error">${this.buttonError}</div>`
465
623
  : null}
466
- ${this.counter ? this.getCounter() : null}
467
- ${this.button ? this.getButton() : null}
468
624
  </div>
469
625
  </temba-tabs>
470
626
  `;
@@ -475,12 +631,14 @@ export class Compose extends FormElement {
475
631
  ></temba-charcount>`;
476
632
  }
477
633
  getButton() {
478
- return html ` <temba-button
479
- id="send-button"
480
- name=${this.buttonName}
634
+ return html `<temba-icon
635
+ tabindex="1"
636
+ class="send-icon"
637
+ name="send"
638
+ size="1"
639
+ clickable
481
640
  @click=${this.handleSendClick}
482
- ?disabled=${this.buttonDisabled}
483
- ></temba-button>`;
641
+ ></temba-icon>`;
484
642
  }
485
643
  }
486
644
  __decorate([
@@ -588,4 +746,10 @@ __decorate([
588
746
  __decorate([
589
747
  property({ type: Object })
590
748
  ], Compose.prototype, "currentTab", void 0);
749
+ __decorate([
750
+ property({ type: Boolean })
751
+ ], Compose.prototype, "hasPendingText", void 0);
752
+ __decorate([
753
+ property({ type: Object })
754
+ ], Compose.prototype, "activeShortcut", void 0);
591
755
  //# sourceMappingURL=Compose.js.map