@nyaruka/temba-components 0.94.5 → 0.96.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.
@@ -21,7 +21,6 @@ export class TemplateEditor extends FormElement {
21
21
  }
22
22
 
23
23
  .content {
24
- margin-bottom: 1em;
25
24
  }
26
25
 
27
26
  .picker {
@@ -43,6 +42,7 @@ export class TemplateEditor extends FormElement {
43
42
 
44
43
  .error-message {
45
44
  padding-left: 0.5em;
45
+ padding-bottom: 1em;
46
46
  }
47
47
 
48
48
  .variable {
@@ -121,40 +121,43 @@ export class TemplateEditor extends FormElement {
121
121
  }
122
122
  firstUpdated(changes) {
123
123
  super.firstUpdated(changes);
124
+ if (changes.has('variables') && this.variables) {
125
+ this.currentVariables = this.variables.slice();
126
+ }
124
127
  }
125
- updated(changedProperties) {
126
- super.updated(changedProperties);
128
+ updated(changes) {
129
+ super.updated(changes);
130
+ if (changes.has('template')) {
131
+ this.currentVariables = this.variables;
132
+ }
127
133
  }
128
134
  handleTemplateChanged(event) {
129
135
  const prev = this.selectedTemplate;
130
136
  this.selectedTemplate = event.target.values[0];
137
+ if (prev) {
138
+ this.currentVariables = [];
139
+ }
131
140
  const [lang, loc] = this.lang.split('-');
132
141
  if (this.selectedTemplate) {
133
- this.selectedTemplate.translations.forEach((translation) => {
134
- if (translation.locale === this.lang ||
135
- (!loc && translation.locale.split('-')[0] === lang)) {
136
- this.translation = translation;
137
- // initialize our variables array
138
- const newVariables = new Array((translation.variables || []).length).fill('');
139
- if (!prev) {
140
- // copy our previous variables into newVariables
141
- if (this.variables) {
142
- this.variables.forEach((variable, index) => {
143
- newVariables[index] = variable;
144
- });
145
- }
146
- }
147
- this.variables = newVariables;
148
- }
142
+ this.translation = this.selectedTemplate.translations.find((translation) => {
143
+ return (translation.locale === this.lang ||
144
+ (!loc && translation.locale.split('-')[0] === lang));
149
145
  });
146
+ if (this.translation) {
147
+ this.variables = new Array((this.translation.variables || []).length).fill('');
148
+ }
149
+ else {
150
+ this.variables = [];
151
+ }
150
152
  }
151
153
  else {
152
154
  this.translation = null;
155
+ this.variables = [];
153
156
  }
154
157
  this.fireCustomEvent(CustomEventType.ContextChanged, {
155
158
  template: this.selectedTemplate,
156
159
  translation: this.translation,
157
- variables: this.variables
160
+ variables: this.currentVariables
158
161
  });
159
162
  }
160
163
  handleAttachmentLoading(event) {
@@ -167,30 +170,31 @@ export class TemplateEditor extends FormElement {
167
170
  const media = event.target;
168
171
  const index = parseInt(media.getAttribute('index'));
169
172
  if (media.attachments.length === 0) {
170
- this.variables[index] = '';
173
+ this.currentVariables[index] = '';
171
174
  }
172
175
  else {
173
176
  const attachment = media.attachments[0];
174
177
  if (attachment.url && attachment.content_type) {
175
- this.variables[index] = `${attachment.content_type}:${attachment.url}`;
178
+ this.currentVariables[index] = `${attachment.content_type}:${attachment.url}`;
176
179
  }
177
180
  else {
178
- this.variables[index] = ``;
181
+ this.currentVariables[index] = ``;
179
182
  }
180
183
  }
181
184
  this.fireContentChange();
185
+ this.requestUpdate('currentVariables');
182
186
  }
183
187
  handleVariableChanged(event) {
184
188
  const target = event.target;
185
189
  const variableIndex = parseInt(target.getAttribute('index'));
186
- this.variables[variableIndex] = target.value;
190
+ this.currentVariables[variableIndex] = target.value;
187
191
  this.fireContentChange();
188
192
  }
189
193
  fireContentChange() {
190
194
  this.fireCustomEvent(CustomEventType.ContentChanged, {
191
195
  template: this.selectedTemplate,
192
196
  translation: this.translation,
193
- variables: this.variables
197
+ variables: this.currentVariables
194
198
  });
195
199
  }
196
200
  renderVariables(component) {
@@ -208,11 +212,12 @@ export class TemplateEditor extends FormElement {
208
212
  return html `<span class="text">${part}</span>`;
209
213
  }
210
214
  const variableIndex = component.variables[part];
215
+ const currVariables = this.currentVariables || [];
211
216
  return html `<temba-completion
212
217
  class="variable"
213
218
  type="text"
214
- value=${variableIndex < this.variables.length
215
- ? this.variables[variableIndex]
219
+ value=${variableIndex < currVariables.length
220
+ ? currVariables[variableIndex]
216
221
  : null}
217
222
  @keyup=${this.handleVariableChanged}
218
223
  name="${component.name}"
@@ -229,8 +234,8 @@ export class TemplateEditor extends FormElement {
229
234
  variableSpec.type === 'audio' ||
230
235
  variableSpec.type === 'video') {
231
236
  let attachments = [];
232
- if (this.variables[variableIndex]) {
233
- const parts = this.variables[variableIndex].split(':');
237
+ if (this.currentVariables[variableIndex]) {
238
+ const parts = this.currentVariables[variableIndex].split(':');
234
239
  const content_type = parts[0];
235
240
  const url = parts.slice(1).join(':');
236
241
  attachments = [{ url, content_type }];
@@ -242,8 +247,9 @@ export class TemplateEditor extends FormElement {
242
247
  display: flex;
243
248
  align-items: center;
244
249
  border-radius: var(--curvature);
250
+ margin-bottom: 0.5em;
245
251
  ${attachments.length === 0 && !loading
246
- ? `background-color:rgba(255,0,0,.07);`
252
+ ? `background-color:rgba(0,0,0,.04);`
247
253
  : ``}
248
254
  "
249
255
  >
@@ -309,7 +315,7 @@ export class TemplateEditor extends FormElement {
309
315
  if (this.translation) {
310
316
  content = this.renderComponents(this.translation.components);
311
317
  }
312
- else {
318
+ else if (this.selectedTemplate) {
313
319
  content = html `<div class="error-message">
314
320
  No approved translation was found for current language.
315
321
  </div>`;
@@ -330,8 +336,7 @@ export class TemplateEditor extends FormElement {
330
336
  @change=${this.handleTemplateChanged}
331
337
  >
332
338
  </temba-select>
333
-
334
- ${this.template ? html ` <div class="template">${content}</div>` : null}
339
+ ${content ? html ` <div class="template">${content}</div>` : null}
335
340
  </div>
336
341
  `;
337
342
  }
@@ -355,6 +360,9 @@ __decorate([
355
360
  __decorate([
356
361
  property({ type: Array })
357
362
  ], TemplateEditor.prototype, "variables", void 0);
363
+ __decorate([
364
+ property({ type: Array })
365
+ ], TemplateEditor.prototype, "currentVariables", void 0);
358
366
  __decorate([
359
367
  property({ type: Object, attribute: false })
360
368
  ], TemplateEditor.prototype, "translation", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateEditor.js","sourceRoot":"","sources":["../../../src/templates/TemplateEditor.ts"],"names":[],"mappings":"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","sourcesContent":["import { property } from 'lit/decorators.js';\nimport { FormElement } from '../FormElement';\nimport { TemplateResult, html, css, PropertyValueMap, LitElement } from 'lit';\nimport { CustomEventType } from '../interfaces';\nimport { MediaPicker } from '../mediapicker/MediaPicker';\nimport { getClasses } from '../utils';\n\ninterface Component {\n name: string;\n type: string;\n content: string;\n variables: { [key: string]: number };\n}\n\ninterface Translation {\n locale: string;\n status: string;\n channel: { uuid: string; name: string };\n components: Component[];\n variables: { type: string }[];\n}\n\ninterface Template {\n created_on: string;\n modified_on: string;\n name: string;\n translations: Translation[];\n uuid: string;\n}\n\nexport class TemplateEditor extends FormElement {\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true\n };\n\n static get styles() {\n return css`\n .component {\n background: #fff;\n border: 1px solid var(--color-widget-border);\n border-radius: var(--curvature);\n padding: 1em;\n margin-top: 1em;\n }\n\n .content {\n margin-bottom: 1em;\n }\n\n .picker {\n margin-bottom: 0.5em;\n display: block;\n }\n .param {\n display: flex;\n margin-bottom: 0.5em;\n align-items: center;\n }\n label {\n margin-right: 0.5em;\n }\n\n .content span {\n margin-right: 0.25em;\n }\n\n .error-message {\n padding-left: 0.5em;\n }\n\n .variable {\n display: inline-block;\n margin: 0.25em 0em;\n margin-right: 0.25em;\n }\n\n .button-wrapper {\n background: #f9f9f9;\n border-radius: var(--curvature);\n padding: 0.5em;\n display: flex;\n flex-direction: column;\n }\n\n .button-header {\n font-weight: normal;\n margin-left: 0.25em;\n margin-bottom: -0.5em;\n font-size: 0.9em;\n color: #777;\n }\n\n .buttons {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n margin-bottom: 1em;\n }\n\n .button {\n background: #fff;\n padding: 0.3em 1em;\n border: 1px solid #e6e6e6;\n border-radius: var(--curvature);\n min-height: 23px;\n display: flex;\n flex-direction: row;\n align-items: center;\n margin-right: 0.5em;\n margin-top: 0.5em;\n align-items: center;\n }\n\n .button .content {\n margin-bottom: 0;\n }\n\n .button .display {\n margin-right: 0.5em;\n background: #f9f9f9;\n padding: 0.25em 1em;\n border-radius: var(--curvature);\n }\n\n temba-textinput,\n temba-completion {\n --temba-textinput-padding: 5px 5px;\n --temba-textinput-font-size: 0.9em;\n line-height: initial;\n }\n\n .template {\n background: #fff;\n border-radius: var(--curvature);\n border: 1px solid var(--color-widget-border);\n padding: 1em;\n line-height: 2.2em;\n max-height: 50vh;\n overflow-y: auto;\n overflow-x: hidden;\n padding-bottom: 0;\n }\n `;\n }\n\n @property({ type: String })\n url: string;\n\n // initial template uuid\n @property({ type: String })\n template: string;\n\n @property({ type: Object })\n selectedTemplate: Template;\n\n @property({ type: String })\n lang = 'eng-US';\n\n @property({ type: Array })\n variables: string[];\n\n @property({ type: Object, attribute: false })\n translation: Translation;\n\n @property({ type: Boolean })\n translating: boolean;\n\n pickersLoading: { [key: number]: boolean } = {};\n\n public firstUpdated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(changes);\n }\n\n public updated(changedProperties: Map<string, any>): void {\n super.updated(changedProperties);\n }\n\n private handleTemplateChanged(event: CustomEvent) {\n const prev = this.selectedTemplate;\n this.selectedTemplate = (event.target as any).values[0] as Template;\n const [lang, loc] = this.lang.split('-');\n if (this.selectedTemplate) {\n this.selectedTemplate.translations.forEach((translation) => {\n if (\n translation.locale === this.lang ||\n (!loc && translation.locale.split('-')[0] === lang)\n ) {\n this.translation = translation;\n // initialize our variables array\n const newVariables = new Array(\n (translation.variables || []).length\n ).fill('');\n\n if (!prev) {\n // copy our previous variables into newVariables\n if (this.variables) {\n this.variables.forEach((variable, index) => {\n newVariables[index] = variable;\n });\n }\n }\n this.variables = newVariables;\n }\n });\n } else {\n this.translation = null;\n }\n\n this.fireCustomEvent(CustomEventType.ContextChanged, {\n template: this.selectedTemplate,\n translation: this.translation,\n variables: this.variables\n });\n }\n\n private handleAttachmentLoading(event: CustomEvent) {\n const media = event.target as MediaPicker;\n const index = parseInt(media.getAttribute('index'));\n this.pickersLoading[index] = event.detail.loading;\n this.requestUpdate();\n }\n\n private handleAttachmentsChanged(event: CustomEvent) {\n const media = event.target as MediaPicker;\n const index = parseInt(media.getAttribute('index'));\n\n if (media.attachments.length === 0) {\n this.variables[index] = '';\n } else {\n const attachment = media.attachments[0];\n if (attachment.url && attachment.content_type) {\n this.variables[index] = `${attachment.content_type}:${attachment.url}`;\n } else {\n this.variables[index] = ``;\n }\n }\n this.fireContentChange();\n }\n\n private handleVariableChanged(event: CustomEvent) {\n const target = event.target as HTMLInputElement;\n const variableIndex = parseInt(target.getAttribute('index'));\n this.variables[variableIndex] = target.value;\n this.fireContentChange();\n }\n\n private fireContentChange() {\n this.fireCustomEvent(CustomEventType.ContentChanged, {\n template: this.selectedTemplate,\n translation: this.translation,\n variables: this.variables\n });\n }\n\n private renderVariables(component: Component) {\n // create a regex match based on the variable names\n const variableRegex = new RegExp(\n `{{(${Object.keys(component.variables || []).join('|')})}}`,\n 'g'\n );\n\n let variables = null;\n\n let parts = [];\n if (component.content && component.content.trim().length > 0) {\n parts = component.content?.split(variableRegex) || [];\n }\n\n if (parts.length > 0) {\n variables = parts.map((part, index) => {\n if (index % 2 === 0) {\n return html`<span class=\"text\">${part}</span>`;\n }\n const variableIndex = component.variables[part];\n return html`<temba-completion\n class=\"variable\"\n type=\"text\"\n value=${variableIndex < this.variables.length\n ? this.variables[variableIndex]\n : null}\n @keyup=${this.handleVariableChanged}\n name=\"${component.name}\"\n index=\"${variableIndex}\"\n placeholder=\"{{${part}}}\"\n ></temba-completion>`;\n });\n } else {\n variables = Object.values(component.variables).map((variableIndex) => {\n const variableSpec = this.translation.variables[variableIndex];\n if (\n variableSpec.type === 'image' ||\n variableSpec.type === 'document' ||\n variableSpec.type === 'audio' ||\n variableSpec.type === 'video'\n ) {\n let attachments = [];\n if (this.variables[variableIndex]) {\n const parts = this.variables[variableIndex].split(':');\n const content_type = parts[0];\n const url = parts.slice(1).join(':');\n attachments = [{ url, content_type }];\n }\n\n const loading = this.pickersLoading[variableIndex];\n\n return html`<div\n class=${getClasses({ loading })}\n style=\"\n display: flex; \n align-items: center; \n border-radius: var(--curvature);\n ${attachments.length === 0 && !loading\n ? `background-color:rgba(255,0,0,.07);`\n : ``}\n \"\n >\n <temba-media-picker\n accept=\"${variableSpec.type === 'document'\n ? 'application/pdf'\n : variableSpec.type + '/*'}\"\n max=\"1\"\n index=${variableIndex}\n icon=\"attachment_${variableSpec.type}\"\n attachments=${JSON.stringify(attachments)}\n @temba-loading=${this.handleAttachmentLoading.bind(this)}\n @change=${this.handleAttachmentsChanged.bind(this)}\n ></temba-media-picker>\n <div>\n ${attachments.length == 0 && !loading\n ? html`Attach ${variableSpec.type} to continue`\n : ''}\n </div>\n </div>`;\n }\n });\n }\n\n return html`<div class=\"content\">${variables}</div> `;\n }\n\n public renderComponents(components: Component[]): TemplateResult {\n const nonButtons = components\n .filter((comp) => !comp.type.startsWith('button/'))\n .map(\n (component) =>\n html`<div class=\"${component['name']}\">\n ${this.renderVariables(component)}\n </div>`\n );\n const buttonComponents = components.filter((comp) =>\n comp.type.startsWith('button/')\n );\n const buttons =\n buttonComponents.length > 0 ? this.renderButtons(buttonComponents) : null;\n return html`<div class=\"main\">${nonButtons}</div>\n <div class=\"buttons\">\n ${buttons}\n <div></div>\n </div>`;\n }\n\n public renderButtons(components): TemplateResult {\n const buttons = components.map((component) => {\n if (component.display) {\n return html`\n <div class=\"button\">\n <div class=\"display\">${component.display}</div>\n ${this.renderVariables(component)}\n </div>\n `;\n } else {\n return html`\n <div class=\"button\">${this.renderVariables(component)}</div>\n `;\n }\n });\n return html`<div class=\"button-wrapper\">\n <div class=\"button-header\">Template Buttons</div>\n <div class=\"buttons\">${buttons}</div>\n </div>`;\n }\n\n public render(): TemplateResult {\n let content = null;\n if (this.translation) {\n content = this.renderComponents(this.translation.components);\n } else {\n content = html`<div class=\"error-message\">\n No approved translation was found for current language.\n </div>`;\n }\n\n return html`\n <div>\n <temba-select\n searchable\n ?clearable=${!this.translating}\n ?disabled=${this.translating}\n valuekey=\"uuid\"\n class=\"picker\"\n value=\"${this.template}\"\n endpoint=\"${this.url}\"\n shouldExclude=${(template) => template.status !== 'approved'}\n placeholder=\"Select a template\"\n @temba-content-changed=${this.swallowEvent}\n @change=${this.handleTemplateChanged}\n >\n </temba-select>\n\n ${this.template ? html` <div class=\"template\">${content}</div>` : null}\n </div>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"TemplateEditor.js","sourceRoot":"","sources":["../../../src/templates/TemplateEditor.ts"],"names":[],"mappings":"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","sourcesContent":["import { property } from 'lit/decorators.js';\nimport { FormElement } from '../FormElement';\nimport { TemplateResult, html, css, PropertyValueMap, LitElement } from 'lit';\nimport { CustomEventType } from '../interfaces';\nimport { MediaPicker } from '../mediapicker/MediaPicker';\nimport { getClasses } from '../utils';\n\ninterface Component {\n name: string;\n type: string;\n content: string;\n variables: { [key: string]: number };\n}\n\ninterface Translation {\n locale: string;\n status: string;\n channel: { uuid: string; name: string };\n components: Component[];\n variables: { type: string }[];\n}\n\ninterface Template {\n created_on: string;\n modified_on: string;\n name: string;\n translations: Translation[];\n uuid: string;\n}\n\nexport class TemplateEditor extends FormElement {\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true\n };\n\n static get styles() {\n return css`\n .component {\n background: #fff;\n border: 1px solid var(--color-widget-border);\n border-radius: var(--curvature);\n padding: 1em;\n margin-top: 1em;\n }\n\n .content {\n }\n\n .picker {\n margin-bottom: 0.5em;\n display: block;\n }\n .param {\n display: flex;\n margin-bottom: 0.5em;\n align-items: center;\n }\n label {\n margin-right: 0.5em;\n }\n\n .content span {\n margin-right: 0.25em;\n }\n\n .error-message {\n padding-left: 0.5em;\n padding-bottom: 1em;\n }\n\n .variable {\n display: inline-block;\n margin: 0.25em 0em;\n margin-right: 0.25em;\n }\n\n .button-wrapper {\n background: #f9f9f9;\n border-radius: var(--curvature);\n padding: 0.5em;\n display: flex;\n flex-direction: column;\n }\n\n .button-header {\n font-weight: normal;\n margin-left: 0.25em;\n margin-bottom: -0.5em;\n font-size: 0.9em;\n color: #777;\n }\n\n .buttons {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n margin-bottom: 1em;\n }\n\n .button {\n background: #fff;\n padding: 0.3em 1em;\n border: 1px solid #e6e6e6;\n border-radius: var(--curvature);\n min-height: 23px;\n display: flex;\n flex-direction: row;\n align-items: center;\n margin-right: 0.5em;\n margin-top: 0.5em;\n align-items: center;\n }\n\n .button .content {\n margin-bottom: 0;\n }\n\n .button .display {\n margin-right: 0.5em;\n background: #f9f9f9;\n padding: 0.25em 1em;\n border-radius: var(--curvature);\n }\n\n temba-textinput,\n temba-completion {\n --temba-textinput-padding: 5px 5px;\n --temba-textinput-font-size: 0.9em;\n line-height: initial;\n }\n\n .template {\n background: #fff;\n border-radius: var(--curvature);\n border: 1px solid var(--color-widget-border);\n padding: 1em;\n line-height: 2.2em;\n max-height: 50vh;\n overflow-y: auto;\n overflow-x: hidden;\n padding-bottom: 0;\n }\n `;\n }\n\n @property({ type: String })\n url: string;\n\n // initial template uuid\n @property({ type: String })\n template: string;\n\n @property({ type: Object })\n selectedTemplate: Template;\n\n @property({ type: String })\n lang = 'eng-US';\n\n // initial variables, not reflected back\n @property({ type: Array })\n variables: string[];\n\n @property({ type: Array })\n currentVariables: string[];\n\n @property({ type: Object, attribute: false })\n translation: Translation;\n\n @property({ type: Boolean })\n translating: boolean;\n\n pickersLoading: { [key: number]: boolean } = {};\n\n public firstUpdated(\n changes: PropertyValueMap<any> | Map<PropertyKey, unknown>\n ): void {\n super.firstUpdated(changes);\n if (changes.has('variables') && this.variables) {\n this.currentVariables = this.variables.slice();\n }\n }\n\n public updated(changes: Map<string, any>): void {\n super.updated(changes);\n\n if (changes.has('template')) {\n this.currentVariables = this.variables;\n }\n }\n\n private handleTemplateChanged(event: CustomEvent) {\n const prev = this.selectedTemplate;\n this.selectedTemplate = (event.target as any).values[0] as Template;\n\n if (prev) {\n this.currentVariables = [];\n }\n\n const [lang, loc] = this.lang.split('-');\n if (this.selectedTemplate) {\n this.translation = this.selectedTemplate.translations.find(\n (translation) => {\n return (\n translation.locale === this.lang ||\n (!loc && translation.locale.split('-')[0] === lang)\n );\n }\n );\n\n if (this.translation) {\n this.variables = new Array(\n (this.translation.variables || []).length\n ).fill('');\n } else {\n this.variables = [];\n }\n } else {\n this.translation = null;\n this.variables = [];\n }\n\n this.fireCustomEvent(CustomEventType.ContextChanged, {\n template: this.selectedTemplate,\n translation: this.translation,\n variables: this.currentVariables\n });\n }\n\n private handleAttachmentLoading(event: CustomEvent) {\n const media = event.target as MediaPicker;\n const index = parseInt(media.getAttribute('index'));\n this.pickersLoading[index] = event.detail.loading;\n this.requestUpdate();\n }\n\n private handleAttachmentsChanged(event: CustomEvent) {\n const media = event.target as MediaPicker;\n const index = parseInt(media.getAttribute('index'));\n\n if (media.attachments.length === 0) {\n this.currentVariables[index] = '';\n } else {\n const attachment = media.attachments[0];\n if (attachment.url && attachment.content_type) {\n this.currentVariables[\n index\n ] = `${attachment.content_type}:${attachment.url}`;\n } else {\n this.currentVariables[index] = ``;\n }\n }\n this.fireContentChange();\n this.requestUpdate('currentVariables');\n }\n\n private handleVariableChanged(event: CustomEvent) {\n const target = event.target as HTMLInputElement;\n const variableIndex = parseInt(target.getAttribute('index'));\n this.currentVariables[variableIndex] = target.value;\n this.fireContentChange();\n }\n\n private fireContentChange() {\n this.fireCustomEvent(CustomEventType.ContentChanged, {\n template: this.selectedTemplate,\n translation: this.translation,\n variables: this.currentVariables\n });\n }\n\n private renderVariables(component: Component) {\n // create a regex match based on the variable names\n const variableRegex = new RegExp(\n `{{(${Object.keys(component.variables || []).join('|')})}}`,\n 'g'\n );\n\n let variables = null;\n\n let parts = [];\n if (component.content && component.content.trim().length > 0) {\n parts = component.content?.split(variableRegex) || [];\n }\n\n if (parts.length > 0) {\n variables = parts.map((part, index) => {\n if (index % 2 === 0) {\n return html`<span class=\"text\">${part}</span>`;\n }\n const variableIndex = component.variables[part];\n const currVariables = this.currentVariables || [];\n return html`<temba-completion\n class=\"variable\"\n type=\"text\"\n value=${variableIndex < currVariables.length\n ? currVariables[variableIndex]\n : null}\n @keyup=${this.handleVariableChanged}\n name=\"${component.name}\"\n index=\"${variableIndex}\"\n placeholder=\"{{${part}}}\"\n ></temba-completion>`;\n });\n } else {\n variables = Object.values(component.variables).map((variableIndex) => {\n const variableSpec = this.translation.variables[variableIndex];\n if (\n variableSpec.type === 'image' ||\n variableSpec.type === 'document' ||\n variableSpec.type === 'audio' ||\n variableSpec.type === 'video'\n ) {\n let attachments = [];\n if (this.currentVariables[variableIndex]) {\n const parts = this.currentVariables[variableIndex].split(':');\n const content_type = parts[0];\n const url = parts.slice(1).join(':');\n attachments = [{ url, content_type }];\n }\n\n const loading = this.pickersLoading[variableIndex];\n\n return html`<div\n class=${getClasses({ loading })}\n style=\"\n display: flex; \n align-items: center; \n border-radius: var(--curvature);\n margin-bottom: 0.5em;\n ${attachments.length === 0 && !loading\n ? `background-color:rgba(0,0,0,.04);`\n : ``}\n \"\n >\n <temba-media-picker\n accept=\"${variableSpec.type === 'document'\n ? 'application/pdf'\n : variableSpec.type + '/*'}\"\n max=\"1\"\n index=${variableIndex}\n icon=\"attachment_${variableSpec.type}\"\n attachments=${JSON.stringify(attachments)}\n @temba-loading=${this.handleAttachmentLoading.bind(this)}\n @change=${this.handleAttachmentsChanged.bind(this)}\n ></temba-media-picker>\n <div>\n ${attachments.length == 0 && !loading\n ? html`Attach ${variableSpec.type} to continue`\n : ''}\n </div>\n </div>`;\n }\n });\n }\n\n return html`<div class=\"content\">${variables}</div> `;\n }\n\n public renderComponents(components: Component[]): TemplateResult {\n const nonButtons = components\n .filter((comp) => !comp.type.startsWith('button/'))\n .map(\n (component) =>\n html`<div class=\"${component['name']}\">\n ${this.renderVariables(component)}\n </div>`\n );\n const buttonComponents = components.filter((comp) =>\n comp.type.startsWith('button/')\n );\n const buttons =\n buttonComponents.length > 0 ? this.renderButtons(buttonComponents) : null;\n return html`<div class=\"main\">${nonButtons}</div>\n <div class=\"buttons\">\n ${buttons}\n <div></div>\n </div>`;\n }\n\n public renderButtons(components): TemplateResult {\n const buttons = components.map((component) => {\n if (component.display) {\n return html`\n <div class=\"button\">\n <div class=\"display\">${component.display}</div>\n ${this.renderVariables(component)}\n </div>\n `;\n } else {\n return html`\n <div class=\"button\">${this.renderVariables(component)}</div>\n `;\n }\n });\n return html`<div class=\"button-wrapper\">\n <div class=\"button-header\">Template Buttons</div>\n <div class=\"buttons\">${buttons}</div>\n </div>`;\n }\n\n public render(): TemplateResult {\n let content = null;\n if (this.translation) {\n content = this.renderComponents(this.translation.components);\n } else if (this.selectedTemplate) {\n content = html`<div class=\"error-message\">\n No approved translation was found for current language.\n </div>`;\n }\n\n return html`\n <div>\n <temba-select\n searchable\n ?clearable=${!this.translating}\n ?disabled=${this.translating}\n valuekey=\"uuid\"\n class=\"picker\"\n value=\"${this.template}\"\n endpoint=\"${this.url}\"\n shouldExclude=${(template) => template.status !== 'approved'}\n placeholder=\"Select a template\"\n @temba-content-changed=${this.swallowEvent}\n @change=${this.handleTemplateChanged}\n >\n </temba-select>\n ${content ? html` <div class=\"template\">${content}</div>` : null}\n </div>\n `;\n }\n}\n"]}
@@ -18,7 +18,9 @@ const getInitialValue = (text, attachments, quick_replies) => {
18
18
  text: text ? text : '',
19
19
  attachments: attachments ? attachments : [],
20
20
  quick_replies: quick_replies ? quick_replies : [],
21
- optin: null
21
+ optin: null,
22
+ template: null,
23
+ variables: []
22
24
  }
23
25
  };
24
26
  return composeValue;
@@ -1 +1 @@
1
- {"version":3,"file":"temba-compose.test.js","sourceRoot":"","sources":["../../test/temba-compose.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert, expect } from '@open-wc/testing';\nimport { Compose } from '../src/compose/Compose';\nimport { assertScreenshot, getClip, getComponent } from './utils.test';\nimport { Button } from '../src/button/Button';\nimport { Completion } from '../src/completion/Completion';\nimport { DEFAULT_MEDIA_ENDPOINT } from '../src/utils';\nimport { Attachment } from '../src/interfaces';\n\nconst TAG = 'temba-compose';\nconst getCompose = async (attrs: any = {}, width = 500, height = 500) => {\n const compose = (await getComponent(\n TAG,\n attrs,\n '',\n width,\n height,\n 'display:flex;flex-direction:column;flex-grow:1;'\n )) as Compose;\n return compose;\n};\n\nexport const updateComponent = async (\n compose: Compose,\n text?: string,\n attachments?: Attachment[]\n): Promise<void> => {\n compose.initialText = text ? text : '';\n compose.currentAttachments = attachments ? attachments : [];\n await compose.updateComplete;\n};\n\nconst getInitialValue = (\n text?: string,\n attachments?: Attachment[],\n quick_replies?: []\n): any => {\n const composeValue = {\n und: {\n text: text ? text : '',\n attachments: attachments ? attachments : [],\n quick_replies: quick_replies ? quick_replies : [],\n optin: null\n }\n };\n return composeValue;\n};\nconst getComposeValue = (value: any): string => {\n return JSON.stringify(value);\n};\n\nexport const getValidText = () => {\n return 'sà-wàd-dee!';\n};\n// for a server limit of 640 chars, return a string that is 640+ chars\nexport const getInvalidText = () => {\n return \"p}h<r0P<?SCIbV1+pwW1Hj8g^J&=Sm2f)K=5LjFFUZ№5@ybpoLZ7DJ(27qdWxQMaO)I1nB4(D%d3c(H)QXOF6F?4>&d{lhd5?0`Lio!yAGMO№*AxN5{z5s.IO*dy?tm}vXJ#Lf-HlD;xmNp}0<P42=w#ll9)B-e9>Q#'{~Vp<dl:xC9`T^lhh@TosCZ^:(H<Ji<E(~PojvYk^rPB+poYy^Ne~Su1:9?IgH'4S5Q9v0g№FEIUc~!{S7;746j'Sd@Nfu3=x?CsuR;YLP4j+AOzDARZG?0(Ji(NMg=r%n0Fq?R1?E%Yf`bcoVZAJ^bl0J'^@;lH>T.HmxYxwS;1?(bfrh?pRdd73:iMxrfx5luQ(}<dCD1b3g'G0CtkB№;8KkbL=>krG{RO%Va4wwr%P>jE*+n(E11}Ju9#<.f^)<MTH09^b{RQv7~H`#@Hda6{MV&H@xdyEKq#M@nZng8WTU66!F@*!)w*EpQ+65XKuQCaESgq=PHmtqi@l;F?PHvl^g@Z:+}}Xyr`IC2=3?20^I'qSU*tkyinM^JF.ZI>}~XzRQJn№v3o-w?Vy&gC:c.l(&9{`M#-'N}{T#7lw8(4:iY621'>C^.&hVZn:R!G}Ek){D#'KkiJWawq#7~GLBN*?V!ncw)d%&(tXj\";\n};\n\n// valid = attachments that are uploaded sent to the server when the user clicks send\nexport const getValidAttachments = (numFiles = 2): Attachment[] => {\n const attachments = [];\n let index = 1;\n while (index <= numFiles) {\n const s = 's' + index;\n const attachment = {\n uuid: s,\n content_type: 'image/png',\n type: 'image/png',\n filename: 'name_' + s,\n url: 'url_' + s,\n size: 1024,\n error: null\n } as Attachment;\n attachments.push(attachment);\n index++;\n }\n return attachments;\n};\n// invalid = attachments that are not uploaded and are not sent to the server when the user clicks send\nexport const getInvalidAttachments = (): Attachment[] => {\n const f1 = 'f1';\n const fail1 = {\n uuid: f1,\n content_type: 'image/png',\n type: 'image/png',\n filename: 'name_' + f1,\n url: 'url_' + f1,\n size: 26624,\n error: 'Limit for file uploads is 25.0 MB'\n } as Attachment;\n const f2 = 'f2';\n const fail2 = {\n uuid: f2,\n content_type: 'application/octet-stream',\n type: 'application/octet-stream',\n filename: 'name_' + f2,\n url: 'url_' + f2,\n size: 1024,\n error: 'Unsupported file type'\n } as Attachment;\n\n return [fail1, fail2];\n};\n\n// for a test width of 500, return a string that is 60+ chars with spaces\n// to test that line breaks / word wrapping works as expected\nconst getValidText_Long_WithSpaces = () => {\n return 'bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb ';\n};\nconst getValidText_Long_WithNoSpaces = () => {\n return 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';\n};\nconst getValidText_Long_WithUrl = () => {\n return 'http://www.yourmomyourmomyourmomyourmomyourmomyourmomyourmomyourmomyourmomyourmomyourmom.com';\n};\n\ndescribe('temba-compose chatbox', () => {\n it('can be created', async () => {\n const compose: Compose = await getCompose();\n assert.instanceOf(compose, Compose);\n expect(compose.endpoint).equals(DEFAULT_MEDIA_ENDPOINT);\n });\n\n it('cannot be created with a different endpoint', async () => {\n const compose: Compose = await getCompose({\n endpoint: '/schmsgmedia/schmupload/'\n });\n assert.instanceOf(compose, Compose);\n expect(compose.endpoint).equals(DEFAULT_MEDIA_ENDPOINT);\n });\n\n it('chatbox no counter no send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true\n });\n await assertScreenshot(\n 'compose/chatbox-no-counter-no-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox no counter and send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n button: true\n });\n await assertScreenshot(\n 'compose/chatbox-no-counter-and-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox counter no send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true\n });\n await assertScreenshot(\n 'compose/chatbox-counter-no-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox counter and send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await assertScreenshot(\n 'compose/chatbox-counter-and-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox counter and send button deserialize and serialize', async () => {\n const initialValue = getInitialValue();\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal('');\n expect(compose.currentAttachments).to.deep.equal([]);\n // serialize\n expect(compose.value).to.equal('{}');\n });\n\n it('chatbox with text', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText());\n await assertScreenshot('compose/chatbox-with-text', getClip(compose));\n });\n\n it('chatbox with text deserialize and serialize', async () => {\n const initialValue = getInitialValue(getValidText());\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal(getValidText());\n expect(compose.currentAttachments).to.deep.equal([]);\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n\n it('chatbox with text and spaces', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText_Long_WithSpaces());\n await assertScreenshot(\n 'compose/chatbox-with-text-and-spaces',\n getClip(compose)\n );\n });\n\n it('chatbox with text and no spaces', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText_Long_WithNoSpaces());\n await assertScreenshot(\n 'compose/chatbox-with-text-no-spaces',\n getClip(compose)\n );\n });\n\n it('chatbox with text and url', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText_Long_WithUrl());\n await assertScreenshot(\n 'compose/chatbox-with-text-and-url',\n getClip(compose)\n );\n });\n\n it('chatbox with text and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText());\n const send = compose.shadowRoot.querySelector(\n 'temba-button#send-button'\n ) as Button;\n send.click();\n await assertScreenshot(\n 'compose/chatbox-with-text-and-click-send',\n getClip(compose)\n );\n });\n\n it('chatbox with text and hit enter', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText());\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n await assertScreenshot(\n 'compose/chatbox-with-text-and-hit-enter',\n getClip(compose)\n );\n });\n});\n\ndescribe('temba-compose attachments', () => {\n it('attachments no send button', async () => {\n const compose: Compose = await getCompose({\n attachments: true\n });\n await assertScreenshot(\n 'compose/attachments-no-send-button',\n getClip(compose)\n );\n });\n\n it('attachments and send button', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n button: true\n });\n await assertScreenshot(\n 'compose/attachments-and-send-button',\n getClip(compose)\n );\n });\n\n it('attachments and send button deserialize and serialize', async () => {\n const initialValue = getInitialValue();\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n attachments: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal('');\n expect(compose.currentAttachments).to.deep.equal([]);\n // serialize\n expect(compose.value).to.equal('{}');\n });\n\n it('attachments with success uploaded files', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n await assertScreenshot(\n 'compose/attachments-with-success-files',\n getClip(compose)\n );\n });\n\n it('attachments with success uploaded files deserialize and serialize', async () => {\n const initialValue = getInitialValue(null, getValidAttachments());\n const composeValue = getComposeValue(initialValue);\n const compose: Compose = await getCompose({\n attachments: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal('');\n expect(compose.currentAttachments).to.deep.equal(getValidAttachments());\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n\n it('attachments with failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, null);\n await assertScreenshot(\n 'compose/attachments-with-failure-files',\n getClip(compose)\n );\n });\n\n it('attachments with success and failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n await assertScreenshot(\n 'compose/attachments-with-all-files',\n getClip(compose)\n );\n });\n\n it('attachments with success uploaded files and click send', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n const send = compose.shadowRoot.querySelector(\n 'temba-button#send-button'\n ) as Button;\n send.click();\n await assertScreenshot(\n 'compose/attachments-with-success-files-and-click-send',\n getClip(compose)\n );\n });\n\n it('attachments with success and failure uploaded files and click send', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n const send = compose.shadowRoot.querySelector(\n 'temba-button#send-button'\n ) as Button;\n send.click();\n await assertScreenshot(\n 'compose/attachments-with-all-files-and-click-send',\n getClip(compose)\n );\n });\n});\n\ndescribe('temba-compose chatbox and attachments', () => {\n it('chatbox and attachments no counter no send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true\n });\n await assertScreenshot(\n 'compose/chatbox-attachments-no-counter-no-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox and attachments no counter and send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await assertScreenshot(\n 'compose/chatbox-attachments-no-counter-and-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox and attachments counter no send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true\n });\n await assertScreenshot(\n 'compose/chatbox-attachments-counter-no-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox and attachments counter and send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true\n });\n await assertScreenshot(\n 'compose/chatbox-attachments-counter-and-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox and attachments counter and send button deserialize and serialize', async () => {\n const initialValue = getInitialValue();\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal('');\n expect(compose.currentAttachments).to.deep.equal([]);\n // serialize\n expect(compose.value).to.equal('{}');\n });\n});\n\ndescribe('temba-compose chatbox with text and attachments no files', () => {\n it('chatbox with text, attachments no files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true\n });\n updateComponent(compose, getValidText());\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-no-files',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments no files deserialize and serialize', async () => {\n const initialValue = getInitialValue(getValidText());\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal(getValidText());\n expect(compose.currentAttachments).to.deep.equal([]);\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n\n it('chatbox with text, attachments no files, and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true\n });\n updateComponent(compose, getValidText());\n const send = compose.shadowRoot.querySelector(\n 'temba-button#send-button'\n ) as Button;\n send.click();\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-no-files-and-click-send',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments no files, and hit enter', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText());\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as HTMLElement;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-no-files-and-hit-enter',\n getClip(compose)\n );\n });\n});\n\ndescribe('temba-compose chatbox no text and attachments with files', () => {\n it('chatbox no text, attachments with success uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n await assertScreenshot(\n 'compose/chatbox-no-text-attachments-with-success-files',\n getClip(compose)\n );\n });\n\n it('chatbox no text, attachments with success uploaded files deserialize and serialize', async () => {\n const initialValue = getInitialValue(null, getValidAttachments());\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal('');\n expect(compose.currentAttachments).to.deep.equal(getValidAttachments());\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n\n it('chatbox no text, attachments with failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, null);\n await assertScreenshot(\n 'compose/chatbox-no-text-attachments-with-failure-files',\n getClip(compose)\n );\n });\n\n it('chatbox no text, attachments with success and failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n await assertScreenshot(\n 'compose/chatbox-no-text-attachments-with-all-files',\n getClip(compose)\n );\n });\n\n it('chatbox no text, attachments with success uploaded files, and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n const send = compose.shadowRoot.querySelector(\n 'temba-button#send-button'\n ) as Button;\n send.click();\n await assertScreenshot(\n 'compose/chatbox-no-text-attachments-with-success-files-and-click-send',\n getClip(compose)\n );\n });\n\n it('chatbox no text, attachments with success and failure uploaded files, and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n const send = compose.shadowRoot.querySelector(\n 'temba-button#send-button'\n ) as Button;\n send.click();\n await assertScreenshot(\n 'compose/chatbox-no-text-attachments-with-all-files-and-click-send',\n getClip(compose)\n );\n });\n});\n\ndescribe('temba-compose chatbox with text and attachments with files', () => {\n it('chatbox with text, attachments with success uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-success-files',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success uploaded files deserialize and serialize', async () => {\n const initialValue = getInitialValue(getValidText(), getValidAttachments());\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true,\n value: composeValue\n });\n\n // deserialize\n expect(compose.currentText).to.equal(getValidText());\n\n expect(compose.currentAttachments).to.deep.equal(getValidAttachments());\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n\n it('chatbox with text, attachments with failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), null);\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-failure-files',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success and failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-all-files',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success uploaded files, and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n const send = compose.shadowRoot.querySelector(\n 'temba-button#send-button'\n ) as Button;\n send.click();\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-success-files-and-click-send',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success and failure uploaded files, and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n const send = compose.shadowRoot.querySelector(\n 'temba-button#send-button'\n ) as Button;\n send.click();\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-all-files-and-click-send',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success uploaded files, and hit enter', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as HTMLElement;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-success-files-and-hit-enter',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success and failure uploaded files, and hit enter', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n const chatbox = compose.shadowRoot.querySelector(\n '.chatbox'\n ) as HTMLInputElement;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n const newClip = getClip(compose);\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-all-files-and-hit-enter',\n newClip\n );\n });\n});\n"]}
1
+ {"version":3,"file":"temba-compose.test.js","sourceRoot":"","sources":["../../test/temba-compose.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert, expect } from '@open-wc/testing';\nimport { Compose } from '../src/compose/Compose';\nimport { assertScreenshot, getClip, getComponent } from './utils.test';\nimport { Button } from '../src/button/Button';\nimport { Completion } from '../src/completion/Completion';\nimport { DEFAULT_MEDIA_ENDPOINT } from '../src/utils';\nimport { Attachment } from '../src/interfaces';\n\nconst TAG = 'temba-compose';\nconst getCompose = async (attrs: any = {}, width = 500, height = 500) => {\n const compose = (await getComponent(\n TAG,\n attrs,\n '',\n width,\n height,\n 'display:flex;flex-direction:column;flex-grow:1;'\n )) as Compose;\n return compose;\n};\n\nexport const updateComponent = async (\n compose: Compose,\n text?: string,\n attachments?: Attachment[]\n): Promise<void> => {\n compose.initialText = text ? text : '';\n compose.currentAttachments = attachments ? attachments : [];\n await compose.updateComplete;\n};\n\nconst getInitialValue = (\n text?: string,\n attachments?: Attachment[],\n quick_replies?: []\n): any => {\n const composeValue = {\n und: {\n text: text ? text : '',\n attachments: attachments ? attachments : [],\n quick_replies: quick_replies ? quick_replies : [],\n optin: null,\n template: null,\n variables: []\n }\n };\n return composeValue;\n};\nconst getComposeValue = (value: any): string => {\n return JSON.stringify(value);\n};\n\nexport const getValidText = () => {\n return 'sà-wàd-dee!';\n};\n// for a server limit of 640 chars, return a string that is 640+ chars\nexport const getInvalidText = () => {\n return \"p}h<r0P<?SCIbV1+pwW1Hj8g^J&=Sm2f)K=5LjFFUZ№5@ybpoLZ7DJ(27qdWxQMaO)I1nB4(D%d3c(H)QXOF6F?4>&d{lhd5?0`Lio!yAGMO№*AxN5{z5s.IO*dy?tm}vXJ#Lf-HlD;xmNp}0<P42=w#ll9)B-e9>Q#'{~Vp<dl:xC9`T^lhh@TosCZ^:(H<Ji<E(~PojvYk^rPB+poYy^Ne~Su1:9?IgH'4S5Q9v0g№FEIUc~!{S7;746j'Sd@Nfu3=x?CsuR;YLP4j+AOzDARZG?0(Ji(NMg=r%n0Fq?R1?E%Yf`bcoVZAJ^bl0J'^@;lH>T.HmxYxwS;1?(bfrh?pRdd73:iMxrfx5luQ(}<dCD1b3g'G0CtkB№;8KkbL=>krG{RO%Va4wwr%P>jE*+n(E11}Ju9#<.f^)<MTH09^b{RQv7~H`#@Hda6{MV&H@xdyEKq#M@nZng8WTU66!F@*!)w*EpQ+65XKuQCaESgq=PHmtqi@l;F?PHvl^g@Z:+}}Xyr`IC2=3?20^I'qSU*tkyinM^JF.ZI>}~XzRQJn№v3o-w?Vy&gC:c.l(&9{`M#-'N}{T#7lw8(4:iY621'>C^.&hVZn:R!G}Ek){D#'KkiJWawq#7~GLBN*?V!ncw)d%&(tXj\";\n};\n\n// valid = attachments that are uploaded sent to the server when the user clicks send\nexport const getValidAttachments = (numFiles = 2): Attachment[] => {\n const attachments = [];\n let index = 1;\n while (index <= numFiles) {\n const s = 's' + index;\n const attachment = {\n uuid: s,\n content_type: 'image/png',\n type: 'image/png',\n filename: 'name_' + s,\n url: 'url_' + s,\n size: 1024,\n error: null\n } as Attachment;\n attachments.push(attachment);\n index++;\n }\n return attachments;\n};\n// invalid = attachments that are not uploaded and are not sent to the server when the user clicks send\nexport const getInvalidAttachments = (): Attachment[] => {\n const f1 = 'f1';\n const fail1 = {\n uuid: f1,\n content_type: 'image/png',\n type: 'image/png',\n filename: 'name_' + f1,\n url: 'url_' + f1,\n size: 26624,\n error: 'Limit for file uploads is 25.0 MB'\n } as Attachment;\n const f2 = 'f2';\n const fail2 = {\n uuid: f2,\n content_type: 'application/octet-stream',\n type: 'application/octet-stream',\n filename: 'name_' + f2,\n url: 'url_' + f2,\n size: 1024,\n error: 'Unsupported file type'\n } as Attachment;\n\n return [fail1, fail2];\n};\n\n// for a test width of 500, return a string that is 60+ chars with spaces\n// to test that line breaks / word wrapping works as expected\nconst getValidText_Long_WithSpaces = () => {\n return 'bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb bbbbbbbbbb ';\n};\nconst getValidText_Long_WithNoSpaces = () => {\n return 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';\n};\nconst getValidText_Long_WithUrl = () => {\n return 'http://www.yourmomyourmomyourmomyourmomyourmomyourmomyourmomyourmomyourmomyourmomyourmom.com';\n};\n\ndescribe('temba-compose chatbox', () => {\n it('can be created', async () => {\n const compose: Compose = await getCompose();\n assert.instanceOf(compose, Compose);\n expect(compose.endpoint).equals(DEFAULT_MEDIA_ENDPOINT);\n });\n\n it('cannot be created with a different endpoint', async () => {\n const compose: Compose = await getCompose({\n endpoint: '/schmsgmedia/schmupload/'\n });\n assert.instanceOf(compose, Compose);\n expect(compose.endpoint).equals(DEFAULT_MEDIA_ENDPOINT);\n });\n\n it('chatbox no counter no send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true\n });\n await assertScreenshot(\n 'compose/chatbox-no-counter-no-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox no counter and send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n button: true\n });\n await assertScreenshot(\n 'compose/chatbox-no-counter-and-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox counter no send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true\n });\n await assertScreenshot(\n 'compose/chatbox-counter-no-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox counter and send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await assertScreenshot(\n 'compose/chatbox-counter-and-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox counter and send button deserialize and serialize', async () => {\n const initialValue = getInitialValue();\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal('');\n expect(compose.currentAttachments).to.deep.equal([]);\n // serialize\n expect(compose.value).to.equal('{}');\n });\n\n it('chatbox with text', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText());\n await assertScreenshot('compose/chatbox-with-text', getClip(compose));\n });\n\n it('chatbox with text deserialize and serialize', async () => {\n const initialValue = getInitialValue(getValidText());\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal(getValidText());\n expect(compose.currentAttachments).to.deep.equal([]);\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n\n it('chatbox with text and spaces', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText_Long_WithSpaces());\n await assertScreenshot(\n 'compose/chatbox-with-text-and-spaces',\n getClip(compose)\n );\n });\n\n it('chatbox with text and no spaces', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText_Long_WithNoSpaces());\n await assertScreenshot(\n 'compose/chatbox-with-text-no-spaces',\n getClip(compose)\n );\n });\n\n it('chatbox with text and url', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText_Long_WithUrl());\n await assertScreenshot(\n 'compose/chatbox-with-text-and-url',\n getClip(compose)\n );\n });\n\n it('chatbox with text and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText());\n const send = compose.shadowRoot.querySelector(\n 'temba-button#send-button'\n ) as Button;\n send.click();\n await assertScreenshot(\n 'compose/chatbox-with-text-and-click-send',\n getClip(compose)\n );\n });\n\n it('chatbox with text and hit enter', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText());\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as Completion;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n await assertScreenshot(\n 'compose/chatbox-with-text-and-hit-enter',\n getClip(compose)\n );\n });\n});\n\ndescribe('temba-compose attachments', () => {\n it('attachments no send button', async () => {\n const compose: Compose = await getCompose({\n attachments: true\n });\n await assertScreenshot(\n 'compose/attachments-no-send-button',\n getClip(compose)\n );\n });\n\n it('attachments and send button', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n button: true\n });\n await assertScreenshot(\n 'compose/attachments-and-send-button',\n getClip(compose)\n );\n });\n\n it('attachments and send button deserialize and serialize', async () => {\n const initialValue = getInitialValue();\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n attachments: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal('');\n expect(compose.currentAttachments).to.deep.equal([]);\n // serialize\n expect(compose.value).to.equal('{}');\n });\n\n it('attachments with success uploaded files', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n await assertScreenshot(\n 'compose/attachments-with-success-files',\n getClip(compose)\n );\n });\n\n it('attachments with success uploaded files deserialize and serialize', async () => {\n const initialValue = getInitialValue(null, getValidAttachments());\n const composeValue = getComposeValue(initialValue);\n const compose: Compose = await getCompose({\n attachments: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal('');\n expect(compose.currentAttachments).to.deep.equal(getValidAttachments());\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n\n it('attachments with failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, null);\n await assertScreenshot(\n 'compose/attachments-with-failure-files',\n getClip(compose)\n );\n });\n\n it('attachments with success and failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n await assertScreenshot(\n 'compose/attachments-with-all-files',\n getClip(compose)\n );\n });\n\n it('attachments with success uploaded files and click send', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n const send = compose.shadowRoot.querySelector(\n 'temba-button#send-button'\n ) as Button;\n send.click();\n await assertScreenshot(\n 'compose/attachments-with-success-files-and-click-send',\n getClip(compose)\n );\n });\n\n it('attachments with success and failure uploaded files and click send', async () => {\n const compose: Compose = await getCompose({\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n const send = compose.shadowRoot.querySelector(\n 'temba-button#send-button'\n ) as Button;\n send.click();\n await assertScreenshot(\n 'compose/attachments-with-all-files-and-click-send',\n getClip(compose)\n );\n });\n});\n\ndescribe('temba-compose chatbox and attachments', () => {\n it('chatbox and attachments no counter no send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true\n });\n await assertScreenshot(\n 'compose/chatbox-attachments-no-counter-no-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox and attachments no counter and send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await assertScreenshot(\n 'compose/chatbox-attachments-no-counter-and-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox and attachments counter no send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true\n });\n await assertScreenshot(\n 'compose/chatbox-attachments-counter-no-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox and attachments counter and send button', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true\n });\n await assertScreenshot(\n 'compose/chatbox-attachments-counter-and-send-button',\n getClip(compose)\n );\n });\n\n it('chatbox and attachments counter and send button deserialize and serialize', async () => {\n const initialValue = getInitialValue();\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal('');\n expect(compose.currentAttachments).to.deep.equal([]);\n // serialize\n expect(compose.value).to.equal('{}');\n });\n});\n\ndescribe('temba-compose chatbox with text and attachments no files', () => {\n it('chatbox with text, attachments no files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true\n });\n updateComponent(compose, getValidText());\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-no-files',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments no files deserialize and serialize', async () => {\n const initialValue = getInitialValue(getValidText());\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal(getValidText());\n expect(compose.currentAttachments).to.deep.equal([]);\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n\n it('chatbox with text, attachments no files, and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true\n });\n updateComponent(compose, getValidText());\n const send = compose.shadowRoot.querySelector(\n 'temba-button#send-button'\n ) as Button;\n send.click();\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-no-files-and-click-send',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments no files, and hit enter', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n counter: true,\n button: true\n });\n await updateComponent(compose, getValidText());\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as HTMLElement;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-no-files-and-hit-enter',\n getClip(compose)\n );\n });\n});\n\ndescribe('temba-compose chatbox no text and attachments with files', () => {\n it('chatbox no text, attachments with success uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n await assertScreenshot(\n 'compose/chatbox-no-text-attachments-with-success-files',\n getClip(compose)\n );\n });\n\n it('chatbox no text, attachments with success uploaded files deserialize and serialize', async () => {\n const initialValue = getInitialValue(null, getValidAttachments());\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true,\n value: composeValue\n });\n // deserialize\n expect(compose.currentText).to.equal('');\n expect(compose.currentAttachments).to.deep.equal(getValidAttachments());\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n\n it('chatbox no text, attachments with failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, null);\n await assertScreenshot(\n 'compose/chatbox-no-text-attachments-with-failure-files',\n getClip(compose)\n );\n });\n\n it('chatbox no text, attachments with success and failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n await assertScreenshot(\n 'compose/chatbox-no-text-attachments-with-all-files',\n getClip(compose)\n );\n });\n\n it('chatbox no text, attachments with success uploaded files, and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n const send = compose.shadowRoot.querySelector(\n 'temba-button#send-button'\n ) as Button;\n send.click();\n await assertScreenshot(\n 'compose/chatbox-no-text-attachments-with-success-files-and-click-send',\n getClip(compose)\n );\n });\n\n it('chatbox no text, attachments with success and failure uploaded files, and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, null, getValidAttachments());\n const send = compose.shadowRoot.querySelector(\n 'temba-button#send-button'\n ) as Button;\n send.click();\n await assertScreenshot(\n 'compose/chatbox-no-text-attachments-with-all-files-and-click-send',\n getClip(compose)\n );\n });\n});\n\ndescribe('temba-compose chatbox with text and attachments with files', () => {\n it('chatbox with text, attachments with success uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-success-files',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success uploaded files deserialize and serialize', async () => {\n const initialValue = getInitialValue(getValidText(), getValidAttachments());\n const composeValue = getComposeValue(initialValue);\n\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true,\n value: composeValue\n });\n\n // deserialize\n expect(compose.currentText).to.equal(getValidText());\n\n expect(compose.currentAttachments).to.deep.equal(getValidAttachments());\n // serialize\n expect(compose.value).to.equal(composeValue);\n });\n\n it('chatbox with text, attachments with failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), null);\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-failure-files',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success and failure uploaded files', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-all-files',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success uploaded files, and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n const send = compose.shadowRoot.querySelector(\n 'temba-button#send-button'\n ) as Button;\n send.click();\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-success-files-and-click-send',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success and failure uploaded files, and click send', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n const send = compose.shadowRoot.querySelector(\n 'temba-button#send-button'\n ) as Button;\n send.click();\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-all-files-and-click-send',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success uploaded files, and hit enter', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n const chatbox = compose.shadowRoot.querySelector('.chatbox') as HTMLElement;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-success-files-and-hit-enter',\n getClip(compose)\n );\n });\n\n it('chatbox with text, attachments with success and failure uploaded files, and hit enter', async () => {\n const compose: Compose = await getCompose({\n chatbox: true,\n attachments: true,\n button: true\n });\n await updateComponent(compose, getValidText(), getValidAttachments());\n const chatbox = compose.shadowRoot.querySelector(\n '.chatbox'\n ) as HTMLInputElement;\n chatbox.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }));\n const newClip = getClip(compose);\n await assertScreenshot(\n 'compose/chatbox-with-text-attachments-with-all-files-and-hit-enter',\n newClip\n );\n });\n});\n"]}
@@ -13,7 +13,6 @@ describe('TemplateEditor', () => {
13
13
  <temba-template-editor
14
14
  url="/static/api/templates.json"
15
15
  template="2b1cdee4-71b4-4c9a-805c-9bce6a2e7277"
16
- lang="eng"
17
16
  >
18
17
  </temba-template-editor>
19
18
  `);
@@ -46,6 +45,10 @@ describe('TemplateEditor', () => {
46
45
  >
47
46
  </temba-template-editor>
48
47
  `);
48
+ const clip = getClip(templateEditor);
49
+ clip.height = 200;
50
+ clip.bottom = clip.top + clip.height;
51
+ await assertScreenshot('templates/unapproved', clip);
49
52
  const errorMessage = templateEditor.shadowRoot.querySelector('.error-message').innerText;
50
53
  expect(errorMessage).to.equal('No approved translation was found for current language.');
51
54
  });
@@ -1 +1 @@
1
- {"version":3,"file":"temba-template-editor.test.js","sourceRoot":"","sources":["../../test/temba-template-editor.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAGzD,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEzD,MAAM,oBAAoB,GAAG,KAAK,EAAE,GAAmB,EAAE,EAAE;IACzD,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACjD,UAAU,CAAC,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAClD,MAAM,cAAc,GAAG,MAAM,OAAO,CAAiB,GAAG,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IAE1E,MAAM,cAAc,CAAC,cAAc,CAAC;IACpC,OAAO,cAAc,CAAC;AACxB,CAAC,CAAC;AAEF,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,cAAc,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAA;;;;;;;KAOrD,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QAClB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QACrC,MAAM,gBAAgB,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,cAAc,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAA;;;;;;;KAOrD,CAAC,CAAC;QAEH,cAAc,CAAC,IAAI,GAAG,KAAK,CAAC;QAE5B,MAAM,IAAI,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QAClB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QAErC,MAAM,gBAAgB,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,cAAc,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAA;;;;;;;KAOrD,CAAC,CAAC;QAEH,MAAM,YAAY,GAChB,cAAc,CAAC,UAAU,CAAC,aAAa,CACrC,gBAAgB,CAEnB,CAAC,SAAS,CAAC;QACZ,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,KAAK,CAC3B,yDAAyD,CAC1D,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { html, fixture, expect } from '@open-wc/testing';\nimport { TemplateEditor } from '../src/templates/TemplateEditor';\nimport { TemplateResult } from 'lit';\nimport { assertScreenshot, getClip } from './utils.test';\n\nconst createTemplateEditor = async (def: TemplateResult) => {\n const parentNode = document.createElement('div');\n parentNode.setAttribute('style', 'width: 520px;');\n const templateEditor = await fixture<TemplateEditor>(def, { parentNode });\n\n await templateEditor.updateComplete;\n return templateEditor;\n};\n\ndescribe('TemplateEditor', () => {\n it('renders template content', async () => {\n const templateEditor = await createTemplateEditor(html`\n <temba-template-editor\n url=\"/static/api/templates.json\"\n template=\"2b1cdee4-71b4-4c9a-805c-9bce6a2e7277\"\n lang=\"eng\"\n >\n </temba-template-editor>\n `);\n const clip = getClip(templateEditor);\n clip.height = 500;\n clip.bottom = clip.top + clip.height;\n await assertScreenshot('templates/default', clip);\n });\n\n it('updates template content when language changes', async () => {\n const templateEditor = await createTemplateEditor(html`\n <temba-template-editor\n url=\"/static/api/templates.json\"\n template=\"2b1cdee4-71b4-4c9a-805c-9bce6a2e7277\"\n lang=\"eng\"\n >\n </temba-template-editor>\n `);\n\n templateEditor.lang = 'fra';\n\n const clip = getClip(templateEditor);\n clip.height = 500;\n clip.bottom = clip.top + clip.height;\n\n await assertScreenshot('templates/french', clip);\n });\n\n it('renders an error message no language is found', async () => {\n const templateEditor = await createTemplateEditor(html`\n <temba-template-editor\n url=\"/static/api/templates.json\"\n template=\"2b1cdee4-71b4-4c9a-805c-9bce6a2e7277\"\n lang=\"spa\"\n >\n </temba-template-editor>\n `);\n\n const errorMessage = (\n templateEditor.shadowRoot.querySelector(\n '.error-message'\n ) as HTMLDivElement\n ).innerText;\n expect(errorMessage).to.equal(\n 'No approved translation was found for current language.'\n );\n });\n});\n"]}
1
+ {"version":3,"file":"temba-template-editor.test.js","sourceRoot":"","sources":["../../test/temba-template-editor.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAGzD,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEzD,MAAM,oBAAoB,GAAG,KAAK,EAAE,GAAmB,EAAE,EAAE;IACzD,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACjD,UAAU,CAAC,YAAY,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAClD,MAAM,cAAc,GAAG,MAAM,OAAO,CAAiB,GAAG,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;IAE1E,MAAM,cAAc,CAAC,cAAc,CAAC;IACpC,OAAO,cAAc,CAAC;AACxB,CAAC,CAAC;AAEF,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,cAAc,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAA;;;;;;KAMrD,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QAClB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QACrC,MAAM,gBAAgB,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,cAAc,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAA;;;;;;;KAOrD,CAAC,CAAC;QAEH,cAAc,CAAC,IAAI,GAAG,KAAK,CAAC;QAE5B,MAAM,IAAI,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QAClB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QAErC,MAAM,gBAAgB,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,cAAc,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAA;;;;;;;KAOrD,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QAClB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC;QAErC,MAAM,gBAAgB,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;QAErD,MAAM,YAAY,GAChB,cAAc,CAAC,UAAU,CAAC,aAAa,CACrC,gBAAgB,CAEnB,CAAC,SAAS,CAAC;QACZ,MAAM,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,KAAK,CAC3B,yDAAyD,CAC1D,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { html, fixture, expect } from '@open-wc/testing';\nimport { TemplateEditor } from '../src/templates/TemplateEditor';\nimport { TemplateResult } from 'lit';\nimport { assertScreenshot, getClip } from './utils.test';\n\nconst createTemplateEditor = async (def: TemplateResult) => {\n const parentNode = document.createElement('div');\n parentNode.setAttribute('style', 'width: 520px;');\n const templateEditor = await fixture<TemplateEditor>(def, { parentNode });\n\n await templateEditor.updateComplete;\n return templateEditor;\n};\n\ndescribe('TemplateEditor', () => {\n it('renders template content', async () => {\n const templateEditor = await createTemplateEditor(html`\n <temba-template-editor\n url=\"/static/api/templates.json\"\n template=\"2b1cdee4-71b4-4c9a-805c-9bce6a2e7277\"\n >\n </temba-template-editor>\n `);\n const clip = getClip(templateEditor);\n clip.height = 500;\n clip.bottom = clip.top + clip.height;\n await assertScreenshot('templates/default', clip);\n });\n\n it('updates template content when language changes', async () => {\n const templateEditor = await createTemplateEditor(html`\n <temba-template-editor\n url=\"/static/api/templates.json\"\n template=\"2b1cdee4-71b4-4c9a-805c-9bce6a2e7277\"\n lang=\"eng\"\n >\n </temba-template-editor>\n `);\n\n templateEditor.lang = 'fra';\n\n const clip = getClip(templateEditor);\n clip.height = 500;\n clip.bottom = clip.top + clip.height;\n\n await assertScreenshot('templates/french', clip);\n });\n\n it('renders an error message no language is found', async () => {\n const templateEditor = await createTemplateEditor(html`\n <temba-template-editor\n url=\"/static/api/templates.json\"\n template=\"2b1cdee4-71b4-4c9a-805c-9bce6a2e7277\"\n lang=\"spa\"\n >\n </temba-template-editor>\n `);\n\n const clip = getClip(templateEditor);\n clip.height = 200;\n clip.bottom = clip.top + clip.height;\n\n await assertScreenshot('templates/unapproved', clip);\n\n const errorMessage = (\n templateEditor.shadowRoot.querySelector(\n '.error-message'\n ) as HTMLDivElement\n ).innerText;\n expect(errorMessage).to.equal(\n 'No approved translation was found for current language.'\n );\n });\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nyaruka/temba-components",
3
- "version": "0.94.5",
3
+ "version": "0.96.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",