@capillarytech/creatives-library 8.0.161 → 8.0.163
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -179,7 +179,7 @@ const TestAndPreviewSlidebox = (props) => {
|
|
|
179
179
|
resolvedTitle: formData['template-subject'] || ''
|
|
180
180
|
});
|
|
181
181
|
|
|
182
|
-
//
|
|
182
|
+
// Always extract tags when content changes
|
|
183
183
|
const payloadContent = convert(htmlFile, GLOBAL_CONVERT_OPTIONS);
|
|
184
184
|
actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
|
|
185
185
|
}
|
|
@@ -202,7 +202,7 @@ const TestAndPreviewSlidebox = (props) => {
|
|
|
202
202
|
resolvedTitle: formData['template-subject'] || ''
|
|
203
203
|
});
|
|
204
204
|
|
|
205
|
-
//
|
|
205
|
+
// Always extract tags when showing
|
|
206
206
|
const payloadContent = convert(templateContent, GLOBAL_CONVERT_OPTIONS);
|
|
207
207
|
actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
|
|
208
208
|
} else {
|
|
@@ -211,6 +211,7 @@ const TestAndPreviewSlidebox = (props) => {
|
|
|
211
211
|
getCurrentContent,
|
|
212
212
|
GLOBAL_CONVERT_OPTIONS
|
|
213
213
|
);
|
|
214
|
+
// Always extract tags when showing
|
|
214
215
|
actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
|
|
215
216
|
}
|
|
216
217
|
}
|
|
@@ -228,31 +229,30 @@ const TestAndPreviewSlidebox = (props) => {
|
|
|
228
229
|
const templateContent = currentTabData?.[activeTab]?.['template-content'];
|
|
229
230
|
|
|
230
231
|
if (templateContent && templateContent.trim() !== '') {
|
|
232
|
+
// Common function to handle content update
|
|
233
|
+
const handleContentUpdate = (content) => {
|
|
234
|
+
setPreviewDataHtml({
|
|
235
|
+
resolvedBody: content,
|
|
236
|
+
resolvedTitle: formData['template-subject'] || ''
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
// Extract tags from content
|
|
240
|
+
const payloadContent = convert(content, GLOBAL_CONVERT_OPTIONS);
|
|
241
|
+
actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
|
|
242
|
+
};
|
|
243
|
+
|
|
231
244
|
if (isDragDrop) {
|
|
232
|
-
// For Bee editor, update
|
|
245
|
+
// For Bee editor, update preview
|
|
233
246
|
if (templateContent !== previousBeeContentRef.current) {
|
|
234
|
-
|
|
235
247
|
previousBeeContentRef.current = templateContent;
|
|
236
248
|
setBeeContent(templateContent);
|
|
237
|
-
|
|
238
|
-
resolvedBody: templateContent,
|
|
239
|
-
resolvedTitle: formData['template-subject'] || ''
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
// Extract tags with latest content
|
|
243
|
-
const payloadContent = convert(templateContent, GLOBAL_CONVERT_OPTIONS);
|
|
244
|
-
actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
|
|
249
|
+
handleContentUpdate(templateContent);
|
|
245
250
|
}
|
|
246
251
|
} else {
|
|
247
|
-
// For CKEditor,
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
// Extract tags with latest content
|
|
254
|
-
const payloadContent = convert(templateContent, GLOBAL_CONVERT_OPTIONS);
|
|
255
|
-
actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
|
|
252
|
+
// For CKEditor, only update if content changed
|
|
253
|
+
if (templateContent !== previewDataHtml?.resolvedBody) {
|
|
254
|
+
handleContentUpdate(templateContent);
|
|
255
|
+
}
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
258
|
}, [formData, currentTab]);
|
|
@@ -260,9 +260,19 @@ const TestAndPreviewSlidebox = (props) => {
|
|
|
260
260
|
// Cleanup effect to reset ref when slidebox closes
|
|
261
261
|
useEffect(() => {
|
|
262
262
|
if (!show) {
|
|
263
|
+
// Reset all state
|
|
263
264
|
previousBeeContentRef.current = '';
|
|
264
265
|
setBeeContent('');
|
|
265
266
|
setPreviewDataHtml('');
|
|
267
|
+
setSelectedCustomer(null);
|
|
268
|
+
setRequiredTags([]);
|
|
269
|
+
setOptionalTags([]);
|
|
270
|
+
setCustomValues({});
|
|
271
|
+
setShowJSON(false);
|
|
272
|
+
setTagsExtracted(false);
|
|
273
|
+
setPreviewDevice('desktop');
|
|
274
|
+
setSelectedTestEntities([]);
|
|
275
|
+
actions.clearPrefilledValues();
|
|
266
276
|
}
|
|
267
277
|
}, [show]);
|
|
268
278
|
|
|
@@ -274,14 +284,22 @@ const TestAndPreviewSlidebox = (props) => {
|
|
|
274
284
|
|
|
275
285
|
// Listen for extract tags API result
|
|
276
286
|
useEffect(() => {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
287
|
+
// Categorize tags into required and optional
|
|
288
|
+
const required = [];
|
|
289
|
+
const optional = [];
|
|
290
|
+
let hasPersonalizationTags = false;
|
|
281
291
|
|
|
292
|
+
if (extractedTags?.length > 0) {
|
|
282
293
|
const processTag = (tag, parentPath = '') => {
|
|
283
294
|
const currentPath = parentPath ? `${parentPath}.${tag.name}` : tag.name;
|
|
284
295
|
|
|
296
|
+
// Skip unsubscribe tag for input fields
|
|
297
|
+
if (tag.name === 'unsubscribe') {
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
hasPersonalizationTags = true;
|
|
302
|
+
|
|
285
303
|
if (tag?.metaData?.userDriven === false) {
|
|
286
304
|
required.push({
|
|
287
305
|
...tag,
|
|
@@ -301,43 +319,75 @@ const TestAndPreviewSlidebox = (props) => {
|
|
|
301
319
|
|
|
302
320
|
extractedTags.forEach((tag) => processTag(tag));
|
|
303
321
|
|
|
304
|
-
|
|
305
|
-
|
|
322
|
+
if (hasPersonalizationTags) {
|
|
323
|
+
setRequiredTags(required);
|
|
324
|
+
setOptionalTags(optional);
|
|
306
325
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
326
|
+
// Initialize custom values for required tags
|
|
327
|
+
const initialValues = {};
|
|
328
|
+
required.forEach((tag) => {
|
|
329
|
+
initialValues[tag.fullPath] = '';
|
|
330
|
+
});
|
|
331
|
+
optional.forEach((tag) => {
|
|
332
|
+
initialValues[tag.fullPath] = '';
|
|
333
|
+
});
|
|
334
|
+
setCustomValues(initialValues);
|
|
335
|
+
} else {
|
|
336
|
+
// Reset all tag-related state if no personalization tags
|
|
337
|
+
setRequiredTags([]);
|
|
338
|
+
setOptionalTags([]);
|
|
339
|
+
setCustomValues({});
|
|
340
|
+
setTagsExtracted(false);
|
|
341
|
+
}
|
|
342
|
+
} else {
|
|
343
|
+
// Reset all tag-related state if no tags
|
|
344
|
+
setRequiredTags([]);
|
|
345
|
+
setOptionalTags([]);
|
|
346
|
+
setCustomValues({});
|
|
347
|
+
setTagsExtracted(false);
|
|
316
348
|
}
|
|
317
349
|
}, [extractedTags]);
|
|
318
350
|
|
|
319
351
|
useEffect(() => {
|
|
320
|
-
if (
|
|
321
|
-
|
|
322
|
-
|
|
352
|
+
if (selectedCustomer) {
|
|
353
|
+
setTagsExtracted(true); // Auto-open custom values editor
|
|
354
|
+
|
|
355
|
+
// Get all available tags
|
|
356
|
+
const allTags = [...requiredTags, ...optionalTags];
|
|
357
|
+
|
|
358
|
+
if (allTags.length > 0) {
|
|
323
359
|
const payload = {
|
|
324
360
|
channel: EMAIL,
|
|
325
361
|
messageTitle: formData['template-subject'],
|
|
326
|
-
messageBody:
|
|
327
|
-
resolvedTags:
|
|
362
|
+
messageBody: getCurrentContent,
|
|
363
|
+
resolvedTags: {},
|
|
328
364
|
userId: selectedCustomer?.customerId,
|
|
329
365
|
};
|
|
330
366
|
actions.getPrefilledValuesRequested(payload);
|
|
331
367
|
}
|
|
332
368
|
}
|
|
333
|
-
}, [selectedCustomer
|
|
369
|
+
}, [selectedCustomer]);
|
|
334
370
|
|
|
335
371
|
useEffect(() => {
|
|
336
|
-
if (prefilledValues
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
372
|
+
if (prefilledValues) {
|
|
373
|
+
// Always replace all values with prefilled values
|
|
374
|
+
const updatedValues = {};
|
|
375
|
+
[...requiredTags, ...optionalTags].forEach((tag) => {
|
|
376
|
+
updatedValues[tag.fullPath] = prefilledValues[tag.fullPath] || '';
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
setCustomValues(updatedValues);
|
|
381
|
+
|
|
382
|
+
// Update preview with prefilled values
|
|
383
|
+
const payload = {
|
|
384
|
+
channel: EMAIL,
|
|
385
|
+
messageTitle: formData['template-subject'],
|
|
386
|
+
messageBody: getCurrentContent,
|
|
387
|
+
resolvedTags: updatedValues,
|
|
388
|
+
userId: selectedCustomer?.customerId,
|
|
389
|
+
};
|
|
390
|
+
actions.updatePreviewRequested(payload);
|
|
341
391
|
}
|
|
342
392
|
}, [JSON.stringify(prefilledValues)]);
|
|
343
393
|
|
|
@@ -371,7 +421,13 @@ const TestAndPreviewSlidebox = (props) => {
|
|
|
371
421
|
setPreviewDevice('desktop');
|
|
372
422
|
setPreviewDataHtml('');
|
|
373
423
|
setSelectedTestEntities([]);
|
|
424
|
+
setBeeContent('');
|
|
425
|
+
previousBeeContentRef.current = '';
|
|
426
|
+
|
|
427
|
+
// Clear any pending actions
|
|
374
428
|
actions.clearPrefilledValues();
|
|
429
|
+
|
|
430
|
+
// Call parent's onClose if provided
|
|
375
431
|
if (onClose) {
|
|
376
432
|
onClose();
|
|
377
433
|
}
|
|
@@ -384,24 +440,35 @@ const TestAndPreviewSlidebox = (props) => {
|
|
|
384
440
|
// Handle customer selection from CustomerSearchSection
|
|
385
441
|
const handleCustomerSelect = (customer) => {
|
|
386
442
|
setSelectedCustomer(customer);
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
443
|
+
setTagsExtracted(true); // Auto-open custom values editor
|
|
444
|
+
|
|
445
|
+
// Clear any existing values while waiting for prefilled values
|
|
446
|
+
const emptyValues = {};
|
|
447
|
+
[...requiredTags, ...optionalTags].forEach((tag) => {
|
|
448
|
+
emptyValues[tag.fullPath] = '';
|
|
393
449
|
});
|
|
450
|
+
setCustomValues(emptyValues);
|
|
394
451
|
};
|
|
395
452
|
|
|
396
453
|
const handleClearSelection = () => {
|
|
397
454
|
setSelectedCustomer(null);
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
return newValues;
|
|
455
|
+
|
|
456
|
+
// Initialize empty values for all tags
|
|
457
|
+
const emptyValues = {};
|
|
458
|
+
[...requiredTags, ...optionalTags].forEach((tag) => {
|
|
459
|
+
emptyValues[tag.fullPath] = '';
|
|
404
460
|
});
|
|
461
|
+
setCustomValues(emptyValues);
|
|
462
|
+
|
|
463
|
+
// Update preview with empty values
|
|
464
|
+
const payload = {
|
|
465
|
+
channel: EMAIL,
|
|
466
|
+
messageTitle: formData['template-subject'],
|
|
467
|
+
messageBody: getCurrentContent,
|
|
468
|
+
resolvedTags: emptyValues,
|
|
469
|
+
userId: null,
|
|
470
|
+
};
|
|
471
|
+
actions.updatePreviewRequested(payload);
|
|
405
472
|
};
|
|
406
473
|
|
|
407
474
|
// Handle custom value changes
|
|
@@ -426,63 +493,38 @@ const TestAndPreviewSlidebox = (props) => {
|
|
|
426
493
|
|
|
427
494
|
// Handle discard custom values
|
|
428
495
|
const handleDiscardCustomValues = () => {
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
496
|
+
// Initialize empty values for all tags
|
|
497
|
+
const emptyValues = {};
|
|
498
|
+
[...requiredTags, ...optionalTags].forEach((tag) => {
|
|
499
|
+
emptyValues[tag.fullPath] = '';
|
|
432
500
|
});
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
501
|
+
setCustomValues(emptyValues);
|
|
502
|
+
|
|
503
|
+
// Update preview with empty values
|
|
504
|
+
const payload = {
|
|
505
|
+
channel: EMAIL,
|
|
506
|
+
messageTitle: formData['template-subject'],
|
|
507
|
+
messageBody: getCurrentContent,
|
|
508
|
+
resolvedTags: emptyValues,
|
|
509
|
+
userId: selectedCustomer?.customerId,
|
|
510
|
+
};
|
|
511
|
+
actions.updatePreviewRequested(payload);
|
|
437
512
|
};
|
|
438
513
|
|
|
439
514
|
// Handle update preview
|
|
440
515
|
const handleUpdatePreview = async () => {
|
|
441
516
|
try {
|
|
442
|
-
//
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
const currentTabData = formData[currentTab - 1];
|
|
446
|
-
const activeTab = currentTabData?.activeTab;
|
|
447
|
-
const isDragDrop = currentTabData?.[activeTab]?.is_drag_drop;
|
|
448
|
-
|
|
449
|
-
// For BEE editor, ensure content is saved first
|
|
450
|
-
if (isDragDrop && beeInstance) {
|
|
451
|
-
// Trigger save to ensure latest content
|
|
452
|
-
beeInstance.save();
|
|
453
|
-
|
|
454
|
-
// Wait a bit for save to complete and formData to update
|
|
455
|
-
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
456
|
-
|
|
457
|
-
// Get latest content from formData
|
|
458
|
-
const updatedContent = formData[currentTab - 1]?.[activeTab]?.['template-content'];
|
|
459
|
-
const payload = {
|
|
460
|
-
channel: EMAIL,
|
|
461
|
-
messageTitle: formData['template-subject'],
|
|
462
|
-
messageBody: updatedContent || getCurrentContent,
|
|
463
|
-
resolvedTags: currentCustomValues, // Use stored values
|
|
464
|
-
userId: selectedCustomer?.customerId,
|
|
465
|
-
};
|
|
517
|
+
// Include unsubscribe tag if content contains it
|
|
518
|
+
const resolvedTags = { ...customValues };
|
|
466
519
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
const payload = {
|
|
476
|
-
channel: EMAIL,
|
|
477
|
-
messageTitle: formData['template-subject'],
|
|
478
|
-
messageBody: templateContent,
|
|
479
|
-
resolvedTags: currentCustomValues,
|
|
480
|
-
userId: selectedCustomer?.customerId,
|
|
481
|
-
};
|
|
482
|
-
|
|
483
|
-
// Use the same update preview action for both editors
|
|
484
|
-
await actions.updatePreviewRequested(payload);
|
|
485
|
-
}
|
|
520
|
+
const payload = {
|
|
521
|
+
channel: EMAIL,
|
|
522
|
+
messageTitle: formData['template-subject'],
|
|
523
|
+
messageBody: getCurrentContent,
|
|
524
|
+
resolvedTags,
|
|
525
|
+
userId: selectedCustomer?.customerId,
|
|
526
|
+
};
|
|
527
|
+
await actions.updatePreviewRequested(payload);
|
|
486
528
|
} catch (error) {
|
|
487
529
|
console.error('Error updating preview:', error);
|
|
488
530
|
CapNotification.error({
|
|
@@ -493,7 +535,34 @@ const TestAndPreviewSlidebox = (props) => {
|
|
|
493
535
|
|
|
494
536
|
// Handle extract tags button click
|
|
495
537
|
const handleExtractTags = () => {
|
|
538
|
+
// Extract tags from current content
|
|
539
|
+
const currentTabData = formData[currentTab - 1];
|
|
540
|
+
const activeTab = currentTabData?.activeTab;
|
|
541
|
+
const templateContent = currentTabData?.[activeTab]?.['template-content'];
|
|
542
|
+
|
|
543
|
+
// Check for personalization tags (excluding unsubscribe)
|
|
544
|
+
const content = templateContent || getCurrentContent;
|
|
545
|
+
const tags = content.match(/{{[^}]+}}/g) || [];
|
|
546
|
+
const hasPersonalizationTags = tags.some(tag => !tag.includes('unsubscribe'));
|
|
547
|
+
|
|
548
|
+
if (!hasPersonalizationTags && tags.length === 1 && tags[0].includes('unsubscribe')) {
|
|
549
|
+
// If only unsubscribe tag is present, show noTagsExtracted message
|
|
550
|
+
setTagsExtracted(false);
|
|
551
|
+
setRequiredTags([]);
|
|
552
|
+
setOptionalTags([]);
|
|
553
|
+
setCustomValues({});
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// Extract tags
|
|
496
558
|
setTagsExtracted(true);
|
|
559
|
+
if (templateContent) {
|
|
560
|
+
const payloadContent = convert(templateContent, GLOBAL_CONVERT_OPTIONS);
|
|
561
|
+
actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
|
|
562
|
+
} else {
|
|
563
|
+
const payloadContent = convert(getCurrentContent, GLOBAL_CONVERT_OPTIONS);
|
|
564
|
+
actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
|
|
565
|
+
}
|
|
497
566
|
};
|
|
498
567
|
|
|
499
568
|
const handleTestEntitiesChange = (value) => {
|