@nyaruka/temba-components 0.156.1 → 0.156.3

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.
@@ -76,6 +76,7 @@ export const send_broadcast: ActionConfig = {
76
76
  required: true,
77
77
  evaluated: true,
78
78
  placeholder: 'Type your message here...',
79
+ maxLength: 640,
79
80
  maxAttachments: 10,
80
81
  accept: '',
81
82
  endpoint: '/api/v2/media.json',
@@ -180,5 +181,52 @@ export const send_broadcast: ActionConfig = {
180
181
  if (formData.text && typeof formData.text === 'string') {
181
182
  formData.text = formData.text.trim();
182
183
  }
184
+ },
185
+ localizable: ['text', 'attachments'],
186
+ toLocalizationFormData: (
187
+ action: SendBroadcast,
188
+ localization: Record<string, any>
189
+ ) => {
190
+ const formData: FormData = {
191
+ uuid: action.uuid
192
+ };
193
+
194
+ if (localization.text && Array.isArray(localization.text)) {
195
+ formData.text = localization.text[0] || '';
196
+ } else {
197
+ formData.text = '';
198
+ }
199
+
200
+ if (localization.attachments && Array.isArray(localization.attachments)) {
201
+ formData.attachments = localization.attachments;
202
+ } else {
203
+ formData.attachments = [];
204
+ }
205
+
206
+ return formData;
207
+ },
208
+ fromLocalizationFormData: (formData: FormData, action: SendBroadcast) => {
209
+ const localization: Record<string, any> = {};
210
+
211
+ if (formData.text && formData.text.trim() !== '') {
212
+ if (formData.text !== action.text) {
213
+ localization.text = [formData.text];
214
+ }
215
+ }
216
+
217
+ const attachments = (formData.attachments || []).filter(
218
+ (att: string) => att && att.trim() !== ''
219
+ );
220
+
221
+ if (attachments.length > 0) {
222
+ if (
223
+ JSON.stringify(attachments) !==
224
+ JSON.stringify(action.attachments || [])
225
+ ) {
226
+ localization.attachments = attachments;
227
+ }
228
+ }
229
+
230
+ return localization;
183
231
  }
184
232
  };
@@ -45,12 +45,13 @@ export const send_email: ActionConfig = {
45
45
  required: true,
46
46
  evaluated: true,
47
47
  placeholder: 'Enter email subject',
48
- maxLength: 255
48
+ maxLength: 1000
49
49
  },
50
50
  body: {
51
51
  type: 'textarea',
52
52
  required: true,
53
53
  evaluated: true,
54
+ maxLength: 10000,
54
55
  minHeight: 175
55
56
  }
56
57
  },
@@ -65,6 +66,46 @@ export const send_email: ActionConfig = {
65
66
  body: formData.body
66
67
  };
67
68
  },
69
+ localizable: ['subject', 'body'],
70
+ toLocalizationFormData: (
71
+ action: SendEmail,
72
+ localization: Record<string, any>
73
+ ) => {
74
+ const formData: FormData = {
75
+ uuid: action.uuid
76
+ };
77
+
78
+ if (localization.subject && Array.isArray(localization.subject)) {
79
+ formData.subject = localization.subject[0] || '';
80
+ } else {
81
+ formData.subject = '';
82
+ }
83
+
84
+ if (localization.body && Array.isArray(localization.body)) {
85
+ formData.body = localization.body[0] || '';
86
+ } else {
87
+ formData.body = '';
88
+ }
89
+
90
+ return formData;
91
+ },
92
+ fromLocalizationFormData: (formData: FormData, action: SendEmail) => {
93
+ const localization: Record<string, any> = {};
94
+
95
+ if (formData.subject && formData.subject.trim() !== '') {
96
+ if (formData.subject !== action.subject) {
97
+ localization.subject = [formData.subject];
98
+ }
99
+ }
100
+
101
+ if (formData.body && formData.body.trim() !== '') {
102
+ if (formData.body !== action.body) {
103
+ localization.body = [formData.body];
104
+ }
105
+ }
106
+
107
+ return localization;
108
+ },
68
109
  validate: (formData: FormData): ValidationResult => {
69
110
  const errors: { [key: string]: string } = {};
70
111
 
@@ -65,6 +65,7 @@ export const send_msg: ActionConfig = {
65
65
  required: true,
66
66
  evaluated: true,
67
67
  placeholder: 'Type your message here...',
68
+ maxLength: 10000,
68
69
  maxAttachments: 10,
69
70
  accept: '',
70
71
  endpoint: '/api/v2/media.json',
@@ -57,6 +57,7 @@ export const set_run_result: ActionConfig = {
57
57
  label: 'Category',
58
58
  helpText: 'Optional category for this result',
59
59
  required: false,
60
+ maxLength: 36,
60
61
  placeholder: 'Enter category...'
61
62
  }
62
63
  },
@@ -189,6 +189,7 @@ export const createRulesItemConfig = () => ({
189
189
  type: 'text' as const,
190
190
  placeholder: 'Category',
191
191
  required: true,
192
+ maxLength: 36,
192
193
  maxWidth: '120px',
193
194
  flavor: 'xsmall' as const
194
195
  }
@@ -18,6 +18,7 @@ import { getOperatorConfig } from '../operators';
18
18
  export const resultNameField: TextFieldConfig = {
19
19
  type: 'text',
20
20
  required: false,
21
+ maxLength: 64,
21
22
  placeholder: '(optional)',
22
23
  helpText: 'The name to use to reference this result in the flow'
23
24
  };
@@ -16,6 +16,7 @@ export const wait_for_audio: NodeConfig = {
16
16
  type: 'text',
17
17
  label: 'Result Name',
18
18
  required: false,
19
+ maxLength: 64,
19
20
  placeholder: '(optional)',
20
21
  helpText: 'The name to use to reference this result in the flow'
21
22
  }
@@ -34,6 +34,9 @@ const TEST_LOCATIONS = [
34
34
  'geo:-1.9536,30.0606' // Kigali
35
35
  ];
36
36
 
37
+ const truncateUrl = (url: string, maxLen = 50): string =>
38
+ url && url.length > maxLen ? url.slice(0, maxLen) + '…' : url;
39
+
37
40
  interface Contact {
38
41
  uuid: string;
39
42
  name?: string;
@@ -1472,18 +1475,20 @@ export class Simulator extends RapidElement {
1472
1475
  const renderedEvent =
1473
1476
  event.type === Events.WEBHOOK_CALLED && this.hasWebhookDetails(event)
1474
1477
  ? html`<div class="webhook-event">
1475
- <div class="webhook-event-text">${rendered}</div>
1476
- <button
1477
- type="button"
1478
- data-webhook-details="true"
1479
- class="webhook-event-log-link"
1480
- title="View webhook call details"
1481
- aria-label="View webhook call details"
1482
- @click=${(clickEvent: MouseEvent) =>
1483
- this.handleWebhookDetailsClick(event, clickEvent)}
1484
- >
1485
- <temba-icon name="log" size="0.8"></temba-icon>
1486
- </button>
1478
+ <div class="webhook-event-text">
1479
+ Called
1480
+ <a
1481
+ href="#"
1482
+ class="webhook-event-url"
1483
+ data-webhook-details="true"
1484
+ title="View webhook call details"
1485
+ @click=${(clickEvent: MouseEvent) => {
1486
+ clickEvent.preventDefault();
1487
+ this.handleWebhookDetailsClick(event, clickEvent);
1488
+ }}
1489
+ >${truncateUrl((event as any).url)}</a
1490
+ >
1491
+ </div>
1487
1492
  </div>`
1488
1493
  : rendered;
1489
1494
 
@@ -282,6 +282,8 @@ const wireScreenshots = async (page, context, wait, replaceScreenshots) => {
282
282
 
283
283
  await page.exposeFunction('click', async (element) => {
284
284
  if (page.isClosed()) return;
285
+ // reset mouse state to avoid "already pressed" errors
286
+ await page.mouse.up().catch(() => {});
285
287
  const frame = await page.frames().find((f) => {
286
288
  return true;
287
289
  });