@capillarytech/creatives-library 8.0.252 → 8.0.254

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/assets/Android.png +0 -0
  2. package/assets/iOS.png +0 -0
  3. package/constants/unified.js +1 -2
  4. package/initialReducer.js +0 -2
  5. package/package.json +1 -1
  6. package/services/api.js +0 -10
  7. package/services/tests/api.test.js +0 -34
  8. package/utils/common.js +0 -5
  9. package/utils/commonUtils.js +5 -28
  10. package/utils/tests/commonUtil.test.js +0 -224
  11. package/utils/transformTemplateConfig.js +10 -0
  12. package/v2Components/CapDeviceContent/index.js +56 -61
  13. package/v2Components/CapTagList/index.js +1 -6
  14. package/v2Components/CapTagListWithInput/index.js +1 -5
  15. package/v2Components/CapTagListWithInput/messages.js +1 -1
  16. package/v2Components/CapWhatsappCTA/tests/index.test.js +0 -5
  17. package/v2Components/ErrorInfoNote/index.js +72 -455
  18. package/v2Components/ErrorInfoNote/messages.js +6 -36
  19. package/v2Components/ErrorInfoNote/style.scss +4 -280
  20. package/v2Components/FormBuilder/tests/index.test.js +4 -13
  21. package/v2Components/HtmlEditor/HTMLEditor.js +94 -547
  22. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +133 -1358
  23. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +16 -27
  24. package/v2Components/HtmlEditor/_htmlEditor.scss +45 -108
  25. package/v2Components/HtmlEditor/_index.lazy.scss +1 -1
  26. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +101 -22
  27. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +140 -146
  28. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +1 -2
  29. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
  30. package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +0 -9
  31. package/v2Components/HtmlEditor/components/EditorToolbar/index.js +1 -1
  32. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +0 -22
  33. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +7 -4
  34. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +45 -35
  35. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +3 -1
  36. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
  37. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +6 -7
  38. package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +6 -3
  39. package/v2Components/HtmlEditor/components/PreviewPane/index.js +34 -24
  40. package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
  41. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +152 -0
  42. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +31 -49
  43. package/v2Components/HtmlEditor/components/ValidationPanel/_validationPanel.scss +34 -50
  44. package/v2Components/HtmlEditor/components/ValidationPanel/index.js +41 -70
  45. package/v2Components/HtmlEditor/constants.js +20 -42
  46. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +16 -373
  47. package/v2Components/HtmlEditor/hooks/useEditorContent.js +2 -5
  48. package/v2Components/HtmlEditor/hooks/useInAppContent.js +146 -88
  49. package/v2Components/HtmlEditor/hooks/useValidation.js +53 -189
  50. package/v2Components/HtmlEditor/index.js +1 -1
  51. package/v2Components/HtmlEditor/messages.js +85 -95
  52. package/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +45 -94
  53. package/v2Components/HtmlEditor/utils/__tests__/validationAdapter.test.js +0 -134
  54. package/v2Components/HtmlEditor/utils/contentSanitizer.js +41 -40
  55. package/v2Components/HtmlEditor/utils/htmlValidator.js +72 -71
  56. package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +102 -134
  57. package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +25 -23
  58. package/v2Components/HtmlEditor/utils/validationAdapter.js +41 -66
  59. package/v2Components/MobilePushPreviewV2/index.js +7 -32
  60. package/v2Components/TemplatePreview/_templatePreview.scss +24 -55
  61. package/v2Components/TemplatePreview/index.js +32 -47
  62. package/v2Components/TemplatePreview/messages.js +0 -4
  63. package/v2Components/TestAndPreviewSlidebox/_testAndPreviewSlidebox.scss +0 -1
  64. package/v2Containers/BeeEditor/index.js +90 -172
  65. package/v2Containers/CreativesContainer/SlideBoxContent.js +51 -128
  66. package/v2Containers/CreativesContainer/SlideBoxFooter.js +13 -163
  67. package/v2Containers/CreativesContainer/SlideBoxHeader.js +1 -2
  68. package/v2Containers/CreativesContainer/constants.js +0 -1
  69. package/v2Containers/CreativesContainer/index.js +46 -239
  70. package/v2Containers/CreativesContainer/messages.js +0 -8
  71. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +2 -11
  72. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +50 -38
  73. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +0 -106
  74. package/v2Containers/Email/actions.js +0 -7
  75. package/v2Containers/Email/constants.js +1 -5
  76. package/v2Containers/Email/index.js +32 -241
  77. package/v2Containers/Email/messages.js +0 -32
  78. package/v2Containers/Email/reducer.js +1 -12
  79. package/v2Containers/Email/sagas.js +7 -61
  80. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +0 -2
  81. package/v2Containers/Email/tests/reducer.test.js +0 -46
  82. package/v2Containers/Email/tests/sagas.test.js +29 -320
  83. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +19 -207
  84. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +74 -40
  85. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +67 -2
  86. package/v2Containers/EmailWrapper/constants.js +0 -2
  87. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +77 -629
  88. package/v2Containers/EmailWrapper/index.js +23 -103
  89. package/v2Containers/EmailWrapper/messages.js +1 -61
  90. package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +214 -0
  91. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +77 -594
  92. package/v2Containers/InApp/actions.js +0 -7
  93. package/v2Containers/InApp/constants.js +4 -20
  94. package/v2Containers/InApp/index.js +359 -802
  95. package/v2Containers/InApp/index.scss +3 -4
  96. package/v2Containers/InApp/messages.js +3 -7
  97. package/v2Containers/InApp/reducer.js +3 -21
  98. package/v2Containers/InApp/sagas.js +9 -29
  99. package/v2Containers/InApp/selectors.js +5 -25
  100. package/v2Containers/InApp/tests/index.test.js +50 -154
  101. package/v2Containers/InApp/tests/reducer.test.js +0 -34
  102. package/v2Containers/InApp/tests/sagas.test.js +9 -61
  103. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +0 -3
  104. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +0 -2
  105. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +0 -2
  106. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +0 -9
  107. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +0 -12
  108. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +0 -4
  109. package/v2Containers/TagList/index.js +19 -62
  110. package/v2Containers/Templates/_templates.scss +1 -60
  111. package/v2Containers/Templates/index.js +4 -89
  112. package/v2Containers/Templates/messages.js +0 -4
  113. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +0 -34
  114. package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +0 -874
  115. package/v2Components/HtmlEditor/components/ValidationPanel/constants.js +0 -6
  116. package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +0 -254
  117. package/v2Components/HtmlEditor/components/ValidationTabs/index.js +0 -364
  118. package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +0 -51
  119. package/v2Components/HtmlEditor/hooks/__tests__/useValidation.apiErrors.test.js +0 -795
  120. package/v2Components/HtmlEditor/utils/validationConstants.js +0 -40
  121. package/v2Containers/BeePopupEditor/_beePopupEditor.scss +0 -14
  122. package/v2Containers/BeePopupEditor/constants.js +0 -10
  123. package/v2Containers/BeePopupEditor/index.js +0 -194
  124. package/v2Containers/BeePopupEditor/tests/index.test.js +0 -627
  125. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +0 -1285
  126. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +0 -1870
  127. package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +0 -520
  128. package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +0 -643
  129. package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +0 -376
  130. package/v2Containers/InApp/__tests__/sagas.test.js +0 -363
  131. package/v2Containers/InApp/tests/selectors.test.js +0 -612
  132. package/v2Containers/InAppWrapper/components/InAppWrapperView.js +0 -151
  133. package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +0 -267
  134. package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +0 -23
  135. package/v2Containers/InAppWrapper/constants.js +0 -16
  136. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +0 -473
  137. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +0 -198
  138. package/v2Containers/InAppWrapper/index.js +0 -148
  139. package/v2Containers/InAppWrapper/messages.js +0 -49
  140. package/v2Containers/InappAdvance/index.js +0 -1099
  141. package/v2Containers/InappAdvance/index.scss +0 -10
  142. package/v2Containers/InappAdvance/tests/index.test.js +0 -448
@@ -62,7 +62,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
62
62
  isEdit: false,
63
63
  schema: {},
64
64
  loading: false,
65
- isFormValid: true,
66
65
  injectedTags: {},
67
66
  checkValidation: false,
68
67
  saveEdmDataMode: 'save',
@@ -208,31 +207,13 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
208
207
  const isBEESupport = (this.props.location.query.isBEESupport !== "false") || false;
209
208
  const isBEEAppEnable = this.checkBeeEditorAllowedForLibrary();
210
209
  if (!_.isEmpty(this.props.Templates.BEETemplate)) {
211
- const isDragDrop = this.props.Templates.BEETemplate.versions?.base?.is_drag_drop;
212
-
213
- if (isDragDrop && isBEEAppEnable ) {
210
+ if (this.props.Templates.BEETemplate.versions.base.is_drag_drop && isBEEAppEnable ) {
214
211
  this.setState({isDragDrop: true});
215
212
  }
216
213
  if (this.props.params.id) {
217
- // Extract drag_drop_id - check multiple possible paths
218
- const activeTab = this.props.Templates.BEETemplate.versions?.base?.activeTab || 'en';
219
- const activeTabData = this.props.Templates.BEETemplate.versions?.base?.[activeTab] || {};
220
- const dragDropId = activeTabData.drag_drop_id
221
- || activeTabData.id
222
- || _.get(this.props.Templates.BEETemplate, 'versions.base.drag_drop_id')
223
- || _.get(this.props.Templates.BEETemplate, 'versions.base.id')
224
- || this.props.Templates.BEETemplate?._id;
225
- this.props.actions.getCmsSetting(BEE_PLUGIN, dragDropId, 'open', undefined, isBEESupport, isBEEAppEnable);
214
+ this.props.actions.getCmsSetting(BEE_PLUGIN, _.get(this.props.Templates.BEETemplate, 'versions.base.drag_drop_id', this.props.Templates.BEETemplate?._id), 'open', undefined, isBEESupport, isBEEAppEnable);
226
215
  } else if (this.props.location.query.module !== "library" || (this.props.location.query.module === "library" && !this.props.templateData)) {
227
- // Extract drag_drop_id - check multiple possible paths
228
- const activeTab = this.props.Templates.BEETemplate.versions?.base?.activeTab || 'en';
229
- const activeTabData = this.props.Templates.BEETemplate.versions?.base?.[activeTab] || {};
230
- const dragDropId = activeTabData.drag_drop_id
231
- || activeTabData.id
232
- || _.get(this.props.Templates.BEETemplate, 'versions.base.drag_drop_id')
233
- || _.get(this.props.Templates.BEETemplate, 'versions.base.id')
234
- || this.props.Templates.BEETemplate?._id;
235
- this.props.actions.getCmsSetting(BEE_PLUGIN, dragDropId, 'create', undefined, isBEESupport, isBEEAppEnable);
216
+ this.props.actions.getCmsSetting(BEE_PLUGIN, _.get(this.props.Templates.BEETemplate, 'versions.base.drag_drop_id', this.props.Templates.BEETemplate?._id), 'create', undefined, isBEESupport, isBEEAppEnable);
236
217
  }
237
218
  }
238
219
  this.setState({ content: (this.props.Templates.selectedEmailLayout ? this.props.Templates.selectedEmailLayout : ''), formData});
@@ -255,52 +236,11 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
255
236
  if (this.props.location.query.type === 'embedded') {
256
237
  this.showNext();
257
238
  }
258
-
259
- // Check if BEETemplate was set after componentWillMount but before componentDidMount
260
- // This can happen if BEETemplate is set asynchronously
261
- if (!_.isEmpty(this.props.Templates.BEETemplate) && !this.state.isDragDrop) {
262
- const isBEESupport = (this.props.location.query.isBEESupport !== "false") || false;
263
- const isBEEAppEnable = this.checkBeeEditorAllowedForLibrary();
264
- const beeTemplate = this.props.Templates.BEETemplate;
265
- const activeTab = beeTemplate.versions?.base?.activeTab || 'en';
266
- const activeTabData = beeTemplate.versions?.base?.[activeTab] || {};
267
- const isDragDrop = activeTabData.is_drag_drop
268
- || beeTemplate.versions?.base?.is_drag_drop
269
- || beeTemplate.base?.is_drag_drop
270
- || beeTemplate.is_drag_drop;
271
-
272
- if (isDragDrop && isBEEAppEnable) {
273
- this.setState({isDragDrop: true});
274
-
275
- const dragDropId = activeTabData.drag_drop_id
276
- || activeTabData.id
277
- || _.get(beeTemplate, 'versions.base.drag_drop_id')
278
- || _.get(beeTemplate, 'versions.base.id')
279
- || beeTemplate._id;
280
-
281
- if (this.props.params.id) {
282
- const activeTabForLang = beeTemplate.versions?.base?.activeTab || 'en';
283
- this.props.actions.getCmsSetting(BEE_PLUGIN, dragDropId, 'open', activeTabForLang, isBEESupport, isBEEAppEnable);
284
- } else {
285
- this.props.actions.getCmsSetting(BEE_PLUGIN, dragDropId, 'create', undefined, isBEESupport, isBEEAppEnable);
286
- }
287
- }
288
- }
289
239
  }
290
240
 
291
241
 
292
- checkBeeEditorAllowedForLibrary = (props = null) => {
293
- // Allow passing props for use in componentWillReceiveProps (to use nextProps)
294
- const componentProps = props || this.props;
295
- const { isFullMode = false, editor, Email } = componentProps || {};
296
- // IMPORTANT: For isBEEAppEnable API parameter, use API response if available
297
- // This ensures consistent behavior across full mode and library mode
298
- // The API response (Email.isBeeEnabled) represents the actual org setting
299
- if (Email?.isBeeEnabled !== undefined && Email?.isBeeEnabled !== null) {
300
- return Email.isBeeEnabled;
301
- }
302
- // Fallback to mode-based logic for UI purposes (editor selection, etc.)
303
- // But for API calls, this should ideally use the API response
242
+ checkBeeEditorAllowedForLibrary = () => {
243
+ const { isFullMode = false, editor } = this.props || {};
304
244
  if ((editor === "BEE" && !isFullMode) || isFullMode) {
305
245
  return true;
306
246
  }
@@ -401,61 +341,9 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
401
341
  // this.props.globalActions.fetchSchemaForEntity(query);
402
342
  // }
403
343
 
404
- // Check if BEETemplate was just set (for new flow when template details load)
405
- // This handles the case where BEETemplate is set after componentWillMount
406
- const wasBEETemplateEmpty = _.isEmpty(this.props.Templates.BEETemplate);
407
- const isBEETemplateNowSet = !_.isEmpty(nextProps.Templates.BEETemplate);
408
- const isBEEAppEnable = this.checkBeeEditorAllowedForLibrary(nextProps);
409
- const isBEESupport = (nextProps.location.query.isBEESupport !== "false") || false;
410
-
411
- if (wasBEETemplateEmpty && isBEETemplateNowSet && isBEEAppEnable) {
412
- const beeTemplate = nextProps.Templates.BEETemplate;
413
- const isDragDrop = beeTemplate.versions?.base?.is_drag_drop
414
- || beeTemplate.versions?.base?.[beeTemplate.versions?.base?.activeTab || 'en']?.is_drag_drop
415
- || beeTemplate.base?.is_drag_drop
416
- || beeTemplate.is_drag_drop;
417
-
418
- // Check if we're in edit mode - check multiple sources for id
419
- const hasParamsId = nextProps.params?.id
420
- || nextProps.location?.query?.id
421
- || nextProps.location?.params?.id
422
- || (nextProps.location?.pathname && nextProps.location.pathname.includes('/edit/'));
423
-
424
- if (isDragDrop) {
425
- this.setState({isDragDrop: true});
426
-
427
- // Extract drag_drop_id - check multiple possible paths
428
- // Priority: versions.base[activeTab].drag_drop_id > versions.base[activeTab].id > versions.base.drag_drop_id > _id
429
- const activeTab = beeTemplate.versions?.base?.activeTab || 'en';
430
- const activeTabData = beeTemplate.versions?.base?.[activeTab] || {};
431
- let dragDropId = activeTabData.drag_drop_id
432
- || activeTabData.id
433
- || beeTemplate.versions?.base?.drag_drop_id
434
- || beeTemplate.versions?.base?.id
435
- || beeTemplate.base?.drag_drop_id
436
- || beeTemplate.base?.id
437
- || beeTemplate._id;
438
-
439
- // Call getCmsSetting for BEE template - use 'open' mode if in edit mode
440
- // Extract langId from active tab
441
- const activeTabForLang = beeTemplate.versions?.base?.activeTab || 'en';
442
- if (hasParamsId) {
443
- this.props.actions.getCmsSetting(BEE_PLUGIN, dragDropId, 'open', activeTabForLang, isBEESupport, isBEEAppEnable);
444
- } else if (nextProps.location.query.module !== "library" || (nextProps.location.query.module === "library" && !nextProps.templateData)) {
445
- this.props.actions.getCmsSetting(BEE_PLUGIN, dragDropId, 'create', undefined, isBEESupport, isBEEAppEnable);
446
- }
447
- }
448
- }
449
-
450
344
  if (this.state.isEdit && !this.state.editDataSet && !_.isEmpty(nextProps.Email.templateDetails) && !_.isEmpty(this.state.schema)) {
451
345
  this.setState({editDataSet: true}, () => {
452
346
  this.setEditData(nextProps.Email.templateDetails);
453
- // Update template name in parent if available
454
- if (this.props.isFullMode && this.props.showTemplateName && nextProps.Email.templateDetails.name) {
455
- const formData = this.state.formData;
456
- formData['template-name'] = nextProps.Email.templateDetails.name;
457
- this.props.showTemplateName({formData, onFormDataChange: this.onFormDataChange});
458
- }
459
347
  });
460
348
  }
461
349
  if (this.state.isEdit && nextProps.location.query.module === "library" && !_.isEmpty(nextProps.templateData) && !this.props.params.id && !nextProps.isGetFormData && _.isEmpty(_.get(this, `state.formData['template-subject']`))) {
@@ -494,7 +382,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
494
382
  const formData = _.cloneDeep(this.state.formData);
495
383
 
496
384
  const schema = _.cloneDeep(this.state.schema);
497
- const langIndex = formData[this.state.currentTab - 1]?.selectedLanguages?.indexOf(langId);
385
+ const langIndex = formData[this.state.currentTab - 1].selectedLanguages.indexOf(langId);
498
386
 
499
387
  const temp = (schema.containers || {})[this.state.currentTab - 1];
500
388
 
@@ -502,91 +390,32 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
502
390
  if (nextProps.Email.CmsSettings.isDragDrop && this.checkBeeEditorAllowedForLibrary()) {
503
391
  const beeJson = `BEEeditor${currentTab > 1 ? currentTab : ''}json`;
504
392
  const beeToken = `BEEeditor${currentTab > 1 ? currentTab : ''}token`;
505
- let beeJsonValue = '';
393
+ let beeJsonValue = _.get(nextProps, 'Templates.BEETemplate.versions.base.json-content', '');
506
394
  const selectedId = _.get(this.props, 'Email.templateDetails._id', '') || _.get(this.props, 'Templates.BEETemplate.versions.base.drag_drop_id', '');
507
-
508
- // Get beeJsonValue from template data - check multiple sources
509
- // First check if it's already in formData (from setEditData)
510
- beeJsonValue = _.get(this.state, `formData[${currentTab - 1}][${langId}].json-content`, '');
511
-
512
- // Also check formData.base
513
- if (!beeJsonValue) {
514
- beeJsonValue = _.get(this.state, `formData.base[${langId}].json-content`, '');
515
- }
516
-
517
- // Always check templateDetails and BEETemplate regardless of mode
518
- if (!beeJsonValue) {
519
- // Check Email.templateDetails first
520
- const templateDetails = nextProps.Email.templateDetails;
521
- if (templateDetails && templateDetails.versions && templateDetails.versions.base) {
522
- const baseVersion = templateDetails.versions.base;
523
- // Try language-specific path first (e.g., base.en.json-content)
524
- if (baseVersion[langId] && baseVersion[langId]['json-content']) {
525
- beeJsonValue = baseVersion[langId]['json-content'];
526
- } else if (baseVersion['json-content']) {
527
- // Fallback to base-level json-content
528
- beeJsonValue = baseVersion['json-content'];
529
- }
530
- }
531
-
532
- // If still not found, check BEETemplate
533
- if (!beeJsonValue) {
534
- const beeTemplate = nextProps.Templates.BEETemplate;
535
- if (beeTemplate && beeTemplate.versions && beeTemplate.versions.base) {
536
- const beeBase = beeTemplate.versions.base;
537
- if (beeBase[langId] && beeBase[langId]['json-content']) {
538
- beeJsonValue = beeBase[langId]['json-content'];
539
- } else if (beeBase['json-content']) {
540
- beeJsonValue = beeBase['json-content'];
541
- }
542
- }
543
- }
544
- }
545
- // Ensure we have a valid beeJsonValue - if it's a string, try to parse it to verify it's valid JSON
546
- let finalBeeJsonValue = beeJsonValue;
547
- if (beeJsonValue && typeof beeJsonValue === 'string') {
548
- try {
549
- // Try to parse to verify it's valid JSON
550
- JSON.parse(beeJsonValue);
551
- } catch (e) {
552
- console.warn('[Email] componentWillReceiveProps - beeJsonValue is not valid JSON, using as-is:', e);
395
+ if (this.state.isEdit) {
396
+ if (this.props.location.query.module === "library") {
397
+ beeJsonValue = _.get(this.state, `formData[${currentTab - 1}][${langId}].json-content`, '');
398
+ } else {
399
+ beeJsonValue = _.get(nextProps, `Email.templateDetails.versions.base[${langId}].json-content`, '');
553
400
  }
554
401
  }
555
-
556
- // Preserve existing formData values, especially template-subject
557
- const existingFormData = formData[`${currentTab - 1}`][langId] || {};
558
402
  formData[`${currentTab - 1}`][langId] = {
559
- ...existingFormData,
403
+ ...formData[`${currentTab - 1}`][langId],
560
404
  is_drag_drop: true,
561
- [beeJson]: finalBeeJsonValue,
405
+ [beeJson]: beeJsonValue,
562
406
  [beeToken]: nextProps.Email.CmsSettings.tokenData,
563
407
  id: selectedId,
564
- // Also store json-content for reference
565
- 'json-content': finalBeeJsonValue,
566
408
  };
567
-
568
- // Ensure template-subject is preserved at the top level
569
- if (formData['template-subject'] === undefined || formData['template-subject'] === '') {
570
- const subjectFromEditData = _.get(nextProps, 'Email.templateDetails.versions.base.subject', '');
571
- if (subjectFromEditData) {
572
- formData['template-subject'] = subjectFromEditData;
573
- }
574
- }
575
-
576
- if (langIndex !== undefined && langIndex !== -1 && temp && temp.panes) {
577
- _.forEach(temp.panes, (pane, index) => {
578
- const tempPane = pane;
409
+ _.forEach(temp.panes, (pane, index) => {
410
+ const tempPane = pane;
411
+ //
412
+ if (parseInt(index, 10) === parseInt(langIndex, 10)) {
579
413
  //
580
- if (parseInt(index, 10) === parseInt(langIndex, 10)) {
581
- //
582
- if (tempPane.sections && tempPane.sections[0] && tempPane.sections[0].inputFields && tempPane.sections[0].inputFields[0] && tempPane.sections[0].inputFields[0].cols) {
583
- tempPane.sections[0].inputFields[0].cols[1].colStyle = {display: ""};
584
- tempPane.sections[0].inputFields[0].cols[0].colStyle = {display: "none"};
585
- }
586
- }
587
- });
588
- }
589
- this.setState({schema, isSchemaChanged: true, loadingStatus: this.state.loadingStatus + 1, formData});
414
+ tempPane.sections[0].inputFields[0].cols[1].colStyle = {display: ""};
415
+ tempPane.sections[0].inputFields[0].cols[0].colStyle = {display: "none"};
416
+ }
417
+ });
418
+ this.setState({schema, isSchemaChanged: true, loadingStatus: this.state.loadingStatus + 1});
590
419
  } else {
591
420
  _.forEach(temp.panes, (pane, index) => {
592
421
  const tempPane = pane;
@@ -883,18 +712,8 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
883
712
  const msgString = JSON.stringify(msg);
884
713
  const langId = formData[this.state.currentTab - 1].activeTab;
885
714
  const langIndex = formData[this.state.currentTab - 1].selectedLanguages.indexOf(langId);
886
- const elementToSelect = document.getElementById(`edmeditor${(langIndex + 1) > 1 ? (langIndex + 1) : ''}`);
887
- if (elementToSelect) {
888
- try {
889
- const win = elementToSelect.contentWindow;
890
- if (win) {
891
- win.postMessage(msgString, '*');
892
- }
893
- } catch (error) {
894
- // Handle cross-origin frame access errors
895
- console.warn('Failed to access iframe contentWindow (cross-origin restriction):', error);
896
- }
897
- }
715
+ const win = document.getElementById(`edmeditor${(langIndex + 1) > 1 ? (langIndex + 1) : ''}`).contentWindow;
716
+ win.postMessage(msgString, '*');
898
717
  } else if (data === "unsubscribe" && this.state.editorInstanse) {
899
718
  const anchor = `<a href='{{${data}}}'>${data}</a>`;
900
719
  this.state.editorInstanse.insertHtml(`${anchor}`);
@@ -1069,19 +888,12 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1069
888
  return '';
1070
889
  }
1071
890
 
1072
- setFormValidity = (isFormValid) => {
1073
- this.setState({isFormValid});
1074
- }
891
+ setFormValidity = () => {}
1075
892
 
1076
893
  setEditData(editData) {
1077
894
  const isBEESupport = (this.props.location.query.isBEESupport !== "false") || false;
1078
895
  const formData = _.cloneDeep(this.state.formData);
1079
896
 
1080
- // Set template name from editData if available
1081
- if (editData.name) {
1082
- formData['template-name'] = editData.name;
1083
- }
1084
-
1085
897
  const schema = (this.props.location.query.type === 'embedded') ? this.removeStandAlone(this.state.schema) : _.cloneDeep(this.state.schema);
1086
898
  const containers = _.cloneDeep(schema.containers.slice());
1087
899
  let tabKey = "";
@@ -1090,8 +902,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1090
902
  const type = this.props.location.query.type;
1091
903
 
1092
904
  formData['template-name'] = editData.name;
1093
- const subject = _.get(editData, 'versions.base.subject', '');
1094
- formData['template-subject'] = subject;
905
+ formData['template-subject'] = _.get(editData, 'versions.base.subject');
1095
906
  formData.base = editData.versions.base;
1096
907
 
1097
908
  _.forEach(editData.versions.history, (data1, index) => {
@@ -1172,13 +983,8 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1172
983
 
1173
984
 
1174
985
  this.setState({ formData, schema, tabKey, currentTab, tabCount: editData.versions.history.length, loadingStatus: this.state.loadingStatus + 1 }, () => {
1175
- if (this.props.isFullMode && this.props.showTemplateName) {
1176
- // Ensure template name is set before showing it
1177
- const updatedFormData = _.cloneDeep(formData);
1178
- if (editData.name && !updatedFormData['template-name']) {
1179
- updatedFormData['template-name'] = editData.name;
1180
- }
1181
- this.props.showTemplateName({formData: updatedFormData, onFormDataChange: this.onFormDataChange});
986
+ if (this.props.isFullMode) {
987
+ this.props.showTemplateName({formData, onFormDataChange: this.onFormDataChange});
1182
988
  }
1183
989
  const isBEEAppEnable = this.checkBeeEditorAllowedForLibrary();
1184
990
  _.forEach((editData.versions.base.selectedLanguages), (language) => {
@@ -1309,7 +1115,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1309
1115
  isEdit: false,
1310
1116
  schema: {},
1311
1117
  loading: false,
1312
- isFormValid: true,
1313
1118
  injectedTags: {},
1314
1119
  checkValidation: false,
1315
1120
  tabKey: '',
@@ -2651,14 +2456,14 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2651
2456
  }
2652
2457
 
2653
2458
  saveFormData = (passedData) => {
2654
- //saveFormData gets called only when validation result is true
2655
2459
  if (this.state.gettingFormData && !this.props.isFullMode) {
2656
2460
  const response = {
2657
2461
  action: "getFormData",
2658
2462
  postAction: this.state.getFormDataValue || 'next',
2659
2463
  id: _.get(this.props, 'Email.templateDetails._id', ''),
2660
2464
  value: this.transformFormData(passedData),
2661
- validity: this.state.isFormValid,
2465
+ //saveFormData gets called only when validation result is true
2466
+ validity: true,
2662
2467
  type: 'EMAIL',
2663
2468
  };
2664
2469
 
@@ -2854,7 +2659,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2854
2659
  getTemplateDetailsInProgress,
2855
2660
  assetUploading,
2856
2661
  createTemplateInProgress,
2857
- fetchingCmsSettings,
2858
2662
  } = this.props.Email;
2859
2663
  let isLoading =
2860
2664
  isLoadingMetaEntities ||
@@ -2863,7 +2667,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2863
2667
  ) || (
2864
2668
  assetUploading !== undefined && assetUploading
2865
2669
  ) || (
2866
- Email && (fetchingCmsData || getTemplateDetailsInProgress || fetchingCmsSettings)
2670
+ Email && (fetchingCmsData || getTemplateDetailsInProgress)
2867
2671
  );
2868
2672
 
2869
2673
  if (!isLoading) {
@@ -3185,19 +2989,6 @@ function mapDispatchToProps(dispatch) {
3185
2989
  const withReducer = injectReducer({ key: 'email', reducer: v2EmailReducer });
3186
2990
  const withEmailSaga = injectSaga({ key: 'email', saga: v2EmailSagas });
3187
2991
 
3188
- // Base Email component without saga registration (for use from EmailWrapper)
3189
- // EmailWrapper already registers the saga, so we don't need to register it here
3190
- export const EmailWithoutSaga = withCreatives({
3191
- WrappedComponent: Email,
3192
- mapStateToProps,
3193
- mapDispatchToProps,
3194
- userAuth: true,
3195
- sagas: [], // No saga - EmailWrapper registers it
3196
- reducers: [withReducer],
3197
- });
3198
-
3199
- // Email component with saga registration (for direct use from SlideBoxContent in Edit mode)
3200
- // When Email is used directly (not as child of EmailWrapper), it needs to register the saga
3201
2992
  export default withCreatives({
3202
2993
  WrappedComponent: Email,
3203
2994
  mapStateToProps,
@@ -302,36 +302,4 @@ export default defineMessages({
302
302
  id: 'creatives.containersV2.Email.base64ImageError',
303
303
  defaultMessage: 'Base64 images are not allowed. Please upload your image to a gallery and use it, or add the image URL instead.',
304
304
  },
305
- "editorTypeTitle": {
306
- id: 'creatives.containersV2.Email.editorTypeTitle',
307
- defaultMessage: 'Editor type',
308
- },
309
- "htmlEditorTitle": {
310
- id: 'creatives.containersV2.Email.htmlEditorTitle',
311
- defaultMessage: 'HTML editor',
312
- },
313
- "htmlEditorDescription": {
314
- id: 'creatives.containersV2.Email.htmlEditorDescription',
315
- defaultMessage: 'Use a basic HTML editor to write and format your content. Suitable if you are familiar with HTML.',
316
- },
317
- "dragDropEditorTitle": {
318
- id: 'creatives.containersV2.Email.dragDropEditorTitle',
319
- defaultMessage: 'Drag & drop editor',
320
- },
321
- "dragDropEditorDescription": {
322
- id: 'creatives.containersV2.Email.dragDropEditorDescription',
323
- defaultMessage: 'Create your content visually by dragging blocks — no coding needed. Great for quick, easy designs.',
324
- },
325
- "uploadZipTitle": {
326
- id: 'creatives.containersV2.Email.uploadZipTitle',
327
- defaultMessage: 'Upload zip file',
328
- },
329
- "uploadZipDescription": {
330
- id: 'creatives.containersV2.Email.uploadZipDescription',
331
- defaultMessage: 'Upload a ZIP containing your custom HTML, images, and assets. Ideal if your content is already built.',
332
- },
333
- "nextButton": {
334
- id: 'creatives.containersV2.Email.nextButton',
335
- defaultMessage: 'Next',
336
- },
337
305
  });
@@ -11,7 +11,6 @@ import * as types from './constants';
11
11
  const initialState = fromJS({
12
12
  createTemplateInProgress: false,
13
13
  createResponse: {},
14
- isBeeEnabled: false,
15
14
  });
16
15
 
17
16
  function emailReducer(state = initialState, action) {
@@ -108,15 +107,6 @@ function emailReducer(state = initialState, action) {
108
107
  return state
109
108
  .set('fetchingCmsData', false)
110
109
  .set('fetchingCmsDataFailed', true);
111
- case types.GET_CMS_ACCOUNTS_REQUEST:
112
- return state
113
- .set('isBeeEnabled', false); // default to false
114
- case types.GET_CMS_ACCOUNTS_SUCCESS:
115
- return state
116
- .set('isBeeEnabled', action.isBeeEnabled);
117
- case types.GET_CMS_ACCOUNTS_FAILURE:
118
- return state
119
- .set('isBeeEnabled', false);
120
110
  case types.CLEAR_EMAIL_CRUD_RESPONSE_REQUEST:
121
111
  return state
122
112
  .set('createResponse', fromJS({}));
@@ -149,8 +139,7 @@ function emailReducer(state = initialState, action) {
149
139
  .set('CmsSettings', fromJS({}))
150
140
  .set('fetchingCmsData', false)
151
141
  .set('duplicateResponse', fromJS({}))
152
- .set('cmsData', '')
153
- .set('isBeeEnabled', false);
142
+ .set('cmsData', '');
154
143
  case types.TRANSFORM_EMAIL_TEMPLATE_REQUEST:
155
144
  return state.set("createTemplateInProgress", true);
156
145
  default:
@@ -1,7 +1,6 @@
1
1
  import {
2
2
  call, put, takeLatest, takeEvery, all,
3
3
  } from 'redux-saga/effects';
4
- import CapNotification from '@capillarytech/cap-ui-library/CapNotification';
5
4
  import * as Api from '../../services/api';
6
5
  import * as types from './constants';
7
6
  import { transformEmailTemplates, storeS3FileSizeDetails } from '../../utils/cdnTransformation';
@@ -10,47 +9,15 @@ export function* createTemplate(template) {
10
9
  let errorMsg;
11
10
  try {
12
11
  const result = yield call(Api.createEmailTemplate, template);
13
- // Check if the API call failed (non-2xx status codes or explicit failure)
14
- const statusCode = result.status?.code || result.status;
15
- const isError = !result.success || statusCode >= 400;
16
-
17
- if (isError) {
18
- // Extract error message from various possible locations in the response
19
- errorMsg = result.message
20
- || result.errorMessage
21
- || result.error?.message
22
- || (result.response && result.response.message)
23
- || (result.status && result.status.message)
24
- || (result.data && result.data.message)
25
- || `API Error: ${statusCode || 'Unknown error'}`;
26
- // Show error notification directly from saga
27
- CapNotification.error({
28
- key: 'createTemplateError',
29
- message: errorMsg,
30
- });
12
+ if (!result.success || result.status.code === 500) {
13
+ errorMsg = result.message;
31
14
  yield put({ type: types.CREATE_TEMPLATE_FAILURE, errorMsg });
32
- // Call callback with error so component can handle it (if needed)
33
- if (template.onCreateTemplateComplete) {
34
- try {
35
- // Call the callback directly (it's a regular function, not a generator)
36
- template.onCreateTemplateComplete({ error: true, message: errorMsg, statusCode });
37
- } catch (callbackError) {
38
- console.error('[Email Saga] Error executing callback:', callbackError);
39
- }
40
- }
41
15
  } else {
42
- yield put({
43
- type: types.CREATE_TEMPLATE_SUCCESS, data: result.response, statusCode: result.status ? result.status.code : '', errorMsg,
44
- });
16
+ yield put({ type: types.CREATE_TEMPLATE_SUCCESS, data: result.response, statusCode: result.status ? result.status.code : '', errorMsg });
45
17
  yield template.onCreateTemplateComplete(result.response);
46
18
  }
47
19
  } catch (error) {
48
- errorMsg = error.message || error.toString() || 'An unexpected error occurred';
49
20
  yield put({ type: types.CREATE_TEMPLATE_FAILURE, error, errorMsg });
50
- // Call callback with error so component can handle it
51
- if (template.onCreateTemplateComplete) {
52
- yield template.onCreateTemplateComplete({ error: true, message: errorMsg });
53
- }
54
21
  }
55
22
  }
56
23
 
@@ -59,14 +26,14 @@ export function* transformEmailTemplate({template, callback}) {
59
26
  const result = yield call(transformEmailTemplates, template);
60
27
  yield callback(result);
61
28
  } catch (error) {
62
- yield callback(template);
29
+ yield callback(template);
63
30
  }
64
31
  }
65
32
 
66
33
  export function* duplicateTemplate(payload) {
67
34
  let errorMsg;
68
35
  let result;
69
- const { id, channel, callback } = payload;
36
+ let { id, channel, callback } = payload;
70
37
  try {
71
38
  result = yield call(Api.duplicateTemplate, {id, channel} );
72
39
  if (result.status.code === 500) {
@@ -75,9 +42,7 @@ export function* duplicateTemplate(payload) {
75
42
  if (callback) {
76
43
  callback(result?.response);
77
44
  }
78
- yield put({
79
- type: types.DUPLICATE_TEMPLATE_SUCCESS, data: result?.response, statusCode: result?.status?.code, errorMsg,
80
- });
45
+ yield put({ type: types.DUPLICATE_TEMPLATE_SUCCESS, data: result?.response, statusCode: result?.status?.code, errorMsg });
81
46
  } catch (error) {
82
47
  yield put({ type: types.DUPLICATE_TEMPLATE_FAILURE, error, errorMsg });
83
48
  }
@@ -102,9 +67,7 @@ export function* getAllAssets(assetType, queryParams) {
102
67
  }
103
68
  }
104
69
 
105
- export function* getCmsSetting({
106
- cmsType, projectId, cmsMode, langId, isEdmSupport, isBEEAppEnable,
107
- }) {
70
+ export function* getCmsSetting({cmsType, projectId, cmsMode, langId, isEdmSupport, isBEEAppEnable}) {
108
71
  try {
109
72
  const result = yield call(Api.getCmsTemplateSettingsV2, cmsType, projectId, cmsMode, langId, isEdmSupport, isBEEAppEnable);
110
73
 
@@ -124,17 +87,6 @@ export function* getCmsData({cmsType, projectId, langId}) {
124
87
  }
125
88
  }
126
89
 
127
- export function* getCmsAccounts({cmsType}) {
128
- try {
129
- const result = yield call(Api.getCmsAccounts, cmsType);
130
- const { cmsAccounts } = result.data?.response || {};
131
- const isBeeEnabled = cmsAccounts?.type === cmsType;
132
- yield put({ type: types.GET_CMS_ACCOUNTS_SUCCESS, isBeeEnabled });
133
- } catch (error) {
134
- yield put({ type: types.GET_CMS_ACCOUNTS_FAILURE, error });
135
- }
136
- }
137
-
138
90
  export function* uploadAsset(file, assetType, fileParams) {
139
91
  try {
140
92
  const result = yield call(Api.uploadFile, file, assetType, fileParams);
@@ -171,10 +123,6 @@ function* watchGetCmsData() {
171
123
  yield takeEvery(types.GET_CMS_EDITOR_DATA_REQUEST, getCmsData);
172
124
  }
173
125
 
174
- function* watchGetCmsAccounts() {
175
- yield takeEvery(types.GET_CMS_ACCOUNTS_REQUEST, getCmsAccounts);
176
- }
177
-
178
126
  function* watchUploadAsset() {
179
127
  yield takeLatest(types.UPLOAD_ASSET_REQUEST, uploadAsset);
180
128
  }
@@ -191,7 +139,6 @@ export default [
191
139
  watchGetAllAssets,
192
140
  watchGetCmsSetting,
193
141
  watchGetCmsData,
194
- watchGetCmsAccounts,
195
142
  watchUploadAsset,
196
143
  watchDuplicateTemplate,
197
144
  ];
@@ -204,7 +151,6 @@ export function* v2EmailSagas() {
204
151
  watchGetAllAssets(),
205
152
  watchGetCmsSetting(),
206
153
  watchGetCmsData(),
207
- watchGetCmsAccounts(),
208
154
  watchUploadAsset(),
209
155
  ]);
210
156
  }
@@ -4,7 +4,6 @@ exports[` 1`] = `
4
4
  Immutable.Map {
5
5
  "createTemplateInProgress": false,
6
6
  "createResponse": Immutable.Map {},
7
- "isBeeEnabled": false,
8
7
  }
9
8
  `;
10
9
 
@@ -12,6 +11,5 @@ exports[` 2`] = `
12
11
  Immutable.Map {
13
12
  "createTemplateInProgress": true,
14
13
  "createResponse": Immutable.Map {},
15
- "isBeeEnabled": false,
16
14
  }
17
15
  `;