@capillarytech/creatives-library 8.0.263 → 8.0.264

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 (163) 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/tests/integration/TemplateCreation/TemplateCreation.integration.test.js +35 -17
  9. package/tests/integration/TemplateCreation/api-response.js +1 -31
  10. package/tests/integration/TemplateCreation/msw-handler.js +0 -2
  11. package/utils/common.js +0 -5
  12. package/utils/commonUtils.js +5 -28
  13. package/utils/tagValidations.js +2 -1
  14. package/utils/tests/commonUtil.test.js +0 -224
  15. package/utils/transformTemplateConfig.js +10 -0
  16. package/v2Components/CapDeviceContent/index.js +56 -61
  17. package/v2Components/CapTagList/index.js +1 -6
  18. package/v2Components/CapTagListWithInput/index.js +1 -5
  19. package/v2Components/CapTagListWithInput/messages.js +1 -1
  20. package/v2Components/CapWhatsappCTA/tests/index.test.js +0 -5
  21. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +2 -2
  22. package/v2Components/ErrorInfoNote/index.js +72 -402
  23. package/v2Components/ErrorInfoNote/messages.js +6 -32
  24. package/v2Components/ErrorInfoNote/style.scss +6 -278
  25. package/v2Components/FormBuilder/index.js +8 -8
  26. package/v2Components/FormBuilder/tests/index.test.js +4 -13
  27. package/v2Components/HtmlEditor/HTMLEditor.js +99 -418
  28. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +133 -1882
  29. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +16 -27
  30. package/v2Components/HtmlEditor/_htmlEditor.scss +45 -108
  31. package/v2Components/HtmlEditor/_index.lazy.scss +1 -0
  32. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +102 -23
  33. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +140 -148
  34. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +1 -2
  35. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
  36. package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +1 -9
  37. package/v2Components/HtmlEditor/components/EditorToolbar/index.js +6 -31
  38. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +0 -22
  39. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +7 -4
  40. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +45 -35
  41. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +3 -1
  42. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
  43. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +6 -7
  44. package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +10 -7
  45. package/v2Components/HtmlEditor/components/PreviewPane/index.js +43 -22
  46. package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
  47. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +152 -0
  48. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/_validationErrorDisplay.scss +0 -18
  49. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +31 -36
  50. package/v2Components/HtmlEditor/components/ValidationPanel/_validationPanel.scss +34 -46
  51. package/v2Components/HtmlEditor/components/ValidationPanel/index.js +46 -52
  52. package/v2Components/HtmlEditor/constants.js +20 -45
  53. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +16 -373
  54. package/v2Components/HtmlEditor/hooks/__tests__/useValidation.test.js +16 -351
  55. package/v2Components/HtmlEditor/hooks/useEditorContent.js +2 -5
  56. package/v2Components/HtmlEditor/hooks/useInAppContent.js +146 -88
  57. package/v2Components/HtmlEditor/hooks/useValidation.js +56 -213
  58. package/v2Components/HtmlEditor/index.js +1 -1
  59. package/v2Components/HtmlEditor/messages.js +94 -102
  60. package/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +45 -214
  61. package/v2Components/HtmlEditor/utils/__tests__/validationAdapter.test.js +0 -134
  62. package/v2Components/HtmlEditor/utils/contentSanitizer.js +41 -40
  63. package/v2Components/HtmlEditor/utils/htmlValidator.js +72 -71
  64. package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +124 -158
  65. package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +25 -23
  66. package/v2Components/HtmlEditor/utils/validationAdapter.js +41 -66
  67. package/v2Components/MobilePushPreviewV2/index.js +7 -33
  68. package/v2Components/TemplatePreview/_templatePreview.scss +24 -55
  69. package/v2Components/TemplatePreview/index.js +32 -47
  70. package/v2Components/TemplatePreview/messages.js +0 -4
  71. package/v2Components/TestAndPreviewSlidebox/_testAndPreviewSlidebox.scss +0 -1
  72. package/v2Containers/BeeEditor/index.js +90 -172
  73. package/v2Containers/CreativesContainer/SlideBoxContent.js +51 -127
  74. package/v2Containers/CreativesContainer/SlideBoxFooter.js +13 -163
  75. package/v2Containers/CreativesContainer/SlideBoxHeader.js +1 -2
  76. package/v2Containers/CreativesContainer/constants.js +0 -1
  77. package/v2Containers/CreativesContainer/index.js +46 -240
  78. package/v2Containers/CreativesContainer/messages.js +0 -8
  79. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +2 -11
  80. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +50 -38
  81. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +0 -103
  82. package/v2Containers/Email/actions.js +0 -7
  83. package/v2Containers/Email/constants.js +1 -5
  84. package/v2Containers/Email/index.js +29 -234
  85. package/v2Containers/Email/messages.js +0 -32
  86. package/v2Containers/Email/reducer.js +1 -12
  87. package/v2Containers/Email/sagas.js +7 -61
  88. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +0 -2
  89. package/v2Containers/Email/tests/reducer.test.js +0 -46
  90. package/v2Containers/Email/tests/sagas.test.js +29 -320
  91. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +21 -211
  92. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +74 -40
  93. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +67 -2
  94. package/v2Containers/EmailWrapper/constants.js +0 -2
  95. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +77 -629
  96. package/v2Containers/EmailWrapper/index.js +23 -103
  97. package/v2Containers/EmailWrapper/messages.js +1 -65
  98. package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +214 -0
  99. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +77 -594
  100. package/v2Containers/FTP/index.js +1 -1
  101. package/v2Containers/InApp/actions.js +0 -7
  102. package/v2Containers/InApp/constants.js +4 -20
  103. package/v2Containers/InApp/index.js +360 -802
  104. package/v2Containers/InApp/index.scss +3 -4
  105. package/v2Containers/InApp/messages.js +3 -7
  106. package/v2Containers/InApp/reducer.js +3 -21
  107. package/v2Containers/InApp/sagas.js +9 -29
  108. package/v2Containers/InApp/selectors.js +5 -25
  109. package/v2Containers/InApp/tests/index.test.js +50 -154
  110. package/v2Containers/InApp/tests/reducer.test.js +0 -34
  111. package/v2Containers/InApp/tests/sagas.test.js +9 -61
  112. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +0 -3
  113. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +0 -2
  114. package/v2Containers/Line/Container/Text/index.js +1 -0
  115. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +0 -2
  116. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +0 -9
  117. package/v2Containers/MobilePushNew/index.js +1 -0
  118. package/v2Containers/Rcs/index.js +3 -0
  119. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +0 -12
  120. package/v2Containers/SmsTrai/Edit/index.js +1 -0
  121. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +0 -4
  122. package/v2Containers/TagList/index.js +19 -62
  123. package/v2Containers/Templates/_templates.scss +1 -60
  124. package/v2Containers/Templates/index.js +4 -89
  125. package/v2Containers/Templates/messages.js +0 -4
  126. package/v2Containers/TemplatesV2/TemplatesV2.style.js +2 -4
  127. package/v2Containers/Viber/index.js +1 -0
  128. package/v2Containers/WebPush/Create/index.js +1 -1
  129. package/v2Containers/WebPush/Create/utils/validation.js +2 -1
  130. package/v2Containers/Whatsapp/index.js +1 -0
  131. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +0 -34
  132. package/v2Containers/Zalo/index.js +1 -0
  133. package/v2Containers/Zalo/tests/index.test.js +1 -5
  134. package/v2Components/ErrorInfoNote/constants.js +0 -1
  135. package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +0 -870
  136. package/v2Components/HtmlEditor/components/ValidationPanel/constants.js +0 -6
  137. package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +0 -281
  138. package/v2Components/HtmlEditor/components/ValidationTabs/index.js +0 -295
  139. package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +0 -51
  140. package/v2Components/HtmlEditor/utils/validationConstants.js +0 -38
  141. package/v2Components/MobilePushPreviewV2/constants.js +0 -6
  142. package/v2Containers/BeePopupEditor/_beePopupEditor.scss +0 -14
  143. package/v2Containers/BeePopupEditor/constants.js +0 -10
  144. package/v2Containers/BeePopupEditor/index.js +0 -194
  145. package/v2Containers/BeePopupEditor/tests/index.test.js +0 -627
  146. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +0 -1246
  147. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +0 -2472
  148. package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +0 -520
  149. package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +0 -956
  150. package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +0 -376
  151. package/v2Containers/InApp/__tests__/sagas.test.js +0 -363
  152. package/v2Containers/InApp/tests/selectors.test.js +0 -612
  153. package/v2Containers/InAppWrapper/components/InAppWrapperView.js +0 -151
  154. package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +0 -267
  155. package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +0 -23
  156. package/v2Containers/InAppWrapper/constants.js +0 -16
  157. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +0 -473
  158. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +0 -198
  159. package/v2Containers/InAppWrapper/index.js +0 -148
  160. package/v2Containers/InAppWrapper/messages.js +0 -49
  161. package/v2Containers/InappAdvance/index.js +0 -1099
  162. package/v2Containers/InappAdvance/index.scss +0 -10
  163. package/v2Containers/InappAdvance/tests/index.test.js +0 -448
@@ -207,31 +207,13 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
207
207
  const isBEESupport = (this.props.location.query.isBEESupport !== "false") || false;
208
208
  const isBEEAppEnable = this.checkBeeEditorAllowedForLibrary();
209
209
  if (!_.isEmpty(this.props.Templates.BEETemplate)) {
210
- const isDragDrop = this.props.Templates.BEETemplate.versions?.base?.is_drag_drop;
211
-
212
- if (isDragDrop && isBEEAppEnable ) {
210
+ if (this.props.Templates.BEETemplate.versions.base.is_drag_drop && isBEEAppEnable ) {
213
211
  this.setState({isDragDrop: true});
214
212
  }
215
213
  if (this.props.params.id) {
216
- // Extract drag_drop_id - check multiple possible paths
217
- const activeTab = this.props.Templates.BEETemplate.versions?.base?.activeTab || 'en';
218
- const activeTabData = this.props.Templates.BEETemplate.versions?.base?.[activeTab] || {};
219
- const dragDropId = activeTabData.drag_drop_id
220
- || activeTabData.id
221
- || _.get(this.props.Templates.BEETemplate, 'versions.base.drag_drop_id')
222
- || _.get(this.props.Templates.BEETemplate, 'versions.base.id')
223
- || this.props.Templates.BEETemplate?._id;
224
- 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);
225
215
  } else if (this.props.location.query.module !== "library" || (this.props.location.query.module === "library" && !this.props.templateData)) {
226
- // Extract drag_drop_id - check multiple possible paths
227
- const activeTab = this.props.Templates.BEETemplate.versions?.base?.activeTab || 'en';
228
- const activeTabData = this.props.Templates.BEETemplate.versions?.base?.[activeTab] || {};
229
- const dragDropId = activeTabData.drag_drop_id
230
- || activeTabData.id
231
- || _.get(this.props.Templates.BEETemplate, 'versions.base.drag_drop_id')
232
- || _.get(this.props.Templates.BEETemplate, 'versions.base.id')
233
- || this.props.Templates.BEETemplate?._id;
234
- 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);
235
217
  }
236
218
  }
237
219
  this.setState({ content: (this.props.Templates.selectedEmailLayout ? this.props.Templates.selectedEmailLayout : ''), formData});
@@ -254,52 +236,11 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
254
236
  if (this.props.location.query.type === 'embedded') {
255
237
  this.showNext();
256
238
  }
257
-
258
- // Check if BEETemplate was set after componentWillMount but before componentDidMount
259
- // This can happen if BEETemplate is set asynchronously
260
- if (!_.isEmpty(this.props.Templates.BEETemplate) && !this.state.isDragDrop) {
261
- const isBEESupport = (this.props.location.query.isBEESupport !== "false") || false;
262
- const isBEEAppEnable = this.checkBeeEditorAllowedForLibrary();
263
- const beeTemplate = this.props.Templates.BEETemplate;
264
- const activeTab = beeTemplate.versions?.base?.activeTab || 'en';
265
- const activeTabData = beeTemplate.versions?.base?.[activeTab] || {};
266
- const isDragDrop = activeTabData.is_drag_drop
267
- || beeTemplate.versions?.base?.is_drag_drop
268
- || beeTemplate.base?.is_drag_drop
269
- || beeTemplate.is_drag_drop;
270
-
271
- if (isDragDrop && isBEEAppEnable) {
272
- this.setState({isDragDrop: true});
273
-
274
- const dragDropId = activeTabData.drag_drop_id
275
- || activeTabData.id
276
- || _.get(beeTemplate, 'versions.base.drag_drop_id')
277
- || _.get(beeTemplate, 'versions.base.id')
278
- || beeTemplate._id;
279
-
280
- if (this.props.params.id) {
281
- const activeTabForLang = beeTemplate.versions?.base?.activeTab || 'en';
282
- this.props.actions.getCmsSetting(BEE_PLUGIN, dragDropId, 'open', activeTabForLang, isBEESupport, isBEEAppEnable);
283
- } else {
284
- this.props.actions.getCmsSetting(BEE_PLUGIN, dragDropId, 'create', undefined, isBEESupport, isBEEAppEnable);
285
- }
286
- }
287
- }
288
239
  }
289
240
 
290
241
 
291
- checkBeeEditorAllowedForLibrary = (props = null) => {
292
- // Allow passing props for use in componentWillReceiveProps (to use nextProps)
293
- const componentProps = props || this.props;
294
- const { isFullMode = false, editor, Email } = componentProps || {};
295
- // IMPORTANT: For isBEEAppEnable API parameter, use API response if available
296
- // This ensures consistent behavior across full mode and library mode
297
- // The API response (Email.isBeeEnabled) represents the actual org setting
298
- if (Email?.isBeeEnabled !== undefined && Email?.isBeeEnabled !== null) {
299
- return Email.isBeeEnabled;
300
- }
301
- // Fallback to mode-based logic for UI purposes (editor selection, etc.)
302
- // But for API calls, this should ideally use the API response
242
+ checkBeeEditorAllowedForLibrary = () => {
243
+ const { isFullMode = false, editor } = this.props || {};
303
244
  if ((editor === "BEE" && !isFullMode) || isFullMode) {
304
245
  return true;
305
246
  }
@@ -400,61 +341,9 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
400
341
  // this.props.globalActions.fetchSchemaForEntity(query);
401
342
  // }
402
343
 
403
- // Check if BEETemplate was just set (for new flow when template details load)
404
- // This handles the case where BEETemplate is set after componentWillMount
405
- const wasBEETemplateEmpty = _.isEmpty(this.props.Templates.BEETemplate);
406
- const isBEETemplateNowSet = !_.isEmpty(nextProps.Templates.BEETemplate);
407
- const isBEEAppEnable = this.checkBeeEditorAllowedForLibrary(nextProps);
408
- const isBEESupport = (nextProps.location.query.isBEESupport !== "false") || false;
409
-
410
- if (wasBEETemplateEmpty && isBEETemplateNowSet && isBEEAppEnable) {
411
- const beeTemplate = nextProps.Templates.BEETemplate;
412
- const isDragDrop = beeTemplate.versions?.base?.is_drag_drop
413
- || beeTemplate.versions?.base?.[beeTemplate.versions?.base?.activeTab || 'en']?.is_drag_drop
414
- || beeTemplate.base?.is_drag_drop
415
- || beeTemplate.is_drag_drop;
416
-
417
- // Check if we're in edit mode - check multiple sources for id
418
- const hasParamsId = nextProps.params?.id
419
- || nextProps.location?.query?.id
420
- || nextProps.location?.params?.id
421
- || (nextProps.location?.pathname && nextProps.location.pathname.includes('/edit/'));
422
-
423
- if (isDragDrop) {
424
- this.setState({isDragDrop: true});
425
-
426
- // Extract drag_drop_id - check multiple possible paths
427
- // Priority: versions.base[activeTab].drag_drop_id > versions.base[activeTab].id > versions.base.drag_drop_id > _id
428
- const activeTab = beeTemplate.versions?.base?.activeTab || 'en';
429
- const activeTabData = beeTemplate.versions?.base?.[activeTab] || {};
430
- let dragDropId = activeTabData.drag_drop_id
431
- || activeTabData.id
432
- || beeTemplate.versions?.base?.drag_drop_id
433
- || beeTemplate.versions?.base?.id
434
- || beeTemplate.base?.drag_drop_id
435
- || beeTemplate.base?.id
436
- || beeTemplate._id;
437
-
438
- // Call getCmsSetting for BEE template - use 'open' mode if in edit mode
439
- // Extract langId from active tab
440
- const activeTabForLang = beeTemplate.versions?.base?.activeTab || 'en';
441
- if (hasParamsId) {
442
- this.props.actions.getCmsSetting(BEE_PLUGIN, dragDropId, 'open', activeTabForLang, isBEESupport, isBEEAppEnable);
443
- } else if (nextProps.location.query.module !== "library" || (nextProps.location.query.module === "library" && !nextProps.templateData)) {
444
- this.props.actions.getCmsSetting(BEE_PLUGIN, dragDropId, 'create', undefined, isBEESupport, isBEEAppEnable);
445
- }
446
- }
447
- }
448
-
449
344
  if (this.state.isEdit && !this.state.editDataSet && !_.isEmpty(nextProps.Email.templateDetails) && !_.isEmpty(this.state.schema)) {
450
345
  this.setState({editDataSet: true}, () => {
451
346
  this.setEditData(nextProps.Email.templateDetails);
452
- // Update template name in parent if available
453
- if (this.props.isFullMode && this.props.showTemplateName && nextProps.Email.templateDetails.name) {
454
- const formData = this.state.formData;
455
- formData['template-name'] = nextProps.Email.templateDetails.name;
456
- this.props.showTemplateName({formData, onFormDataChange: this.onFormDataChange});
457
- }
458
347
  });
459
348
  }
460
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']`))) {
@@ -493,7 +382,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
493
382
  const formData = _.cloneDeep(this.state.formData);
494
383
 
495
384
  const schema = _.cloneDeep(this.state.schema);
496
- const langIndex = formData[this.state.currentTab - 1]?.selectedLanguages?.indexOf(langId);
385
+ const langIndex = formData[this.state.currentTab - 1].selectedLanguages.indexOf(langId);
497
386
 
498
387
  const temp = (schema.containers || {})[this.state.currentTab - 1];
499
388
 
@@ -501,91 +390,32 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
501
390
  if (nextProps.Email.CmsSettings.isDragDrop && this.checkBeeEditorAllowedForLibrary()) {
502
391
  const beeJson = `BEEeditor${currentTab > 1 ? currentTab : ''}json`;
503
392
  const beeToken = `BEEeditor${currentTab > 1 ? currentTab : ''}token`;
504
- let beeJsonValue = '';
393
+ let beeJsonValue = _.get(nextProps, 'Templates.BEETemplate.versions.base.json-content', '');
505
394
  const selectedId = _.get(this.props, 'Email.templateDetails._id', '') || _.get(this.props, 'Templates.BEETemplate.versions.base.drag_drop_id', '');
506
-
507
- // Get beeJsonValue from template data - check multiple sources
508
- // First check if it's already in formData (from setEditData)
509
- beeJsonValue = _.get(this.state, `formData[${currentTab - 1}][${langId}].json-content`, '');
510
-
511
- // Also check formData.base
512
- if (!beeJsonValue) {
513
- beeJsonValue = _.get(this.state, `formData.base[${langId}].json-content`, '');
514
- }
515
-
516
- // Always check templateDetails and BEETemplate regardless of mode
517
- if (!beeJsonValue) {
518
- // Check Email.templateDetails first
519
- const templateDetails = nextProps.Email.templateDetails;
520
- if (templateDetails && templateDetails.versions && templateDetails.versions.base) {
521
- const baseVersion = templateDetails.versions.base;
522
- // Try language-specific path first (e.g., base.en.json-content)
523
- if (baseVersion[langId] && baseVersion[langId]['json-content']) {
524
- beeJsonValue = baseVersion[langId]['json-content'];
525
- } else if (baseVersion['json-content']) {
526
- // Fallback to base-level json-content
527
- beeJsonValue = baseVersion['json-content'];
528
- }
529
- }
530
-
531
- // If still not found, check BEETemplate
532
- if (!beeJsonValue) {
533
- const beeTemplate = nextProps.Templates.BEETemplate;
534
- if (beeTemplate && beeTemplate.versions && beeTemplate.versions.base) {
535
- const beeBase = beeTemplate.versions.base;
536
- if (beeBase[langId] && beeBase[langId]['json-content']) {
537
- beeJsonValue = beeBase[langId]['json-content'];
538
- } else if (beeBase['json-content']) {
539
- beeJsonValue = beeBase['json-content'];
540
- }
541
- }
542
- }
543
- }
544
- // Ensure we have a valid beeJsonValue - if it's a string, try to parse it to verify it's valid JSON
545
- let finalBeeJsonValue = beeJsonValue;
546
- if (beeJsonValue && typeof beeJsonValue === 'string') {
547
- try {
548
- // Try to parse to verify it's valid JSON
549
- JSON.parse(beeJsonValue);
550
- } catch (e) {
551
- 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`, '');
552
400
  }
553
401
  }
554
-
555
- // Preserve existing formData values, especially template-subject
556
- const existingFormData = formData[`${currentTab - 1}`][langId] || {};
557
402
  formData[`${currentTab - 1}`][langId] = {
558
- ...existingFormData,
403
+ ...formData[`${currentTab - 1}`][langId],
559
404
  is_drag_drop: true,
560
- [beeJson]: finalBeeJsonValue,
405
+ [beeJson]: beeJsonValue,
561
406
  [beeToken]: nextProps.Email.CmsSettings.tokenData,
562
407
  id: selectedId,
563
- // Also store json-content for reference
564
- 'json-content': finalBeeJsonValue,
565
408
  };
566
-
567
- // Ensure template-subject is preserved at the top level
568
- if (formData['template-subject'] === undefined || formData['template-subject'] === '') {
569
- const subjectFromEditData = _.get(nextProps, 'Email.templateDetails.versions.base.subject', '');
570
- if (subjectFromEditData) {
571
- formData['template-subject'] = subjectFromEditData;
572
- }
573
- }
574
-
575
- if (langIndex !== undefined && langIndex !== -1 && temp && temp.panes) {
576
- _.forEach(temp.panes, (pane, index) => {
577
- const tempPane = pane;
409
+ _.forEach(temp.panes, (pane, index) => {
410
+ const tempPane = pane;
411
+ //
412
+ if (parseInt(index, 10) === parseInt(langIndex, 10)) {
578
413
  //
579
- if (parseInt(index, 10) === parseInt(langIndex, 10)) {
580
- //
581
- if (tempPane.sections && tempPane.sections[0] && tempPane.sections[0].inputFields && tempPane.sections[0].inputFields[0] && tempPane.sections[0].inputFields[0].cols) {
582
- tempPane.sections[0].inputFields[0].cols[1].colStyle = {display: ""};
583
- tempPane.sections[0].inputFields[0].cols[0].colStyle = {display: "none"};
584
- }
585
- }
586
- });
587
- }
588
- 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});
589
419
  } else {
590
420
  _.forEach(temp.panes, (pane, index) => {
591
421
  const tempPane = pane;
@@ -882,18 +712,8 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
882
712
  const msgString = JSON.stringify(msg);
883
713
  const langId = formData[this.state.currentTab - 1].activeTab;
884
714
  const langIndex = formData[this.state.currentTab - 1].selectedLanguages.indexOf(langId);
885
- const elementToSelect = document.getElementById(`edmeditor${(langIndex + 1) > 1 ? (langIndex + 1) : ''}`);
886
- if (elementToSelect) {
887
- try {
888
- const win = elementToSelect.contentWindow;
889
- if (win) {
890
- win.postMessage(msgString, '*');
891
- }
892
- } catch (error) {
893
- // Handle cross-origin frame access errors
894
- console.warn('Failed to access iframe contentWindow (cross-origin restriction):', error);
895
- }
896
- }
715
+ const win = document.getElementById(`edmeditor${(langIndex + 1) > 1 ? (langIndex + 1) : ''}`).contentWindow;
716
+ win.postMessage(msgString, '*');
897
717
  } else if (data === "unsubscribe" && this.state.editorInstanse) {
898
718
  const anchor = `<a href='{{${data}}}'>${data}</a>`;
899
719
  this.state.editorInstanse.insertHtml(`${anchor}`);
@@ -1074,11 +894,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1074
894
  const isBEESupport = (this.props.location.query.isBEESupport !== "false") || false;
1075
895
  const formData = _.cloneDeep(this.state.formData);
1076
896
 
1077
- // Set template name from editData if available
1078
- if (editData.name) {
1079
- formData['template-name'] = editData.name;
1080
- }
1081
-
1082
897
  const schema = (this.props.location.query.type === 'embedded') ? this.removeStandAlone(this.state.schema) : _.cloneDeep(this.state.schema);
1083
898
  const containers = _.cloneDeep(schema.containers.slice());
1084
899
  let tabKey = "";
@@ -1087,8 +902,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1087
902
  const type = this.props.location.query.type;
1088
903
 
1089
904
  formData['template-name'] = editData.name;
1090
- const subject = _.get(editData, 'versions.base.subject', '');
1091
- formData['template-subject'] = subject;
905
+ formData['template-subject'] = _.get(editData, 'versions.base.subject');
1092
906
  formData.base = editData.versions.base;
1093
907
 
1094
908
  _.forEach(editData.versions.history, (data1, index) => {
@@ -1169,13 +983,8 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
1169
983
 
1170
984
 
1171
985
  this.setState({ formData, schema, tabKey, currentTab, tabCount: editData.versions.history.length, loadingStatus: this.state.loadingStatus + 1 }, () => {
1172
- if (this.props.isFullMode && this.props.showTemplateName) {
1173
- // Ensure template name is set before showing it
1174
- const updatedFormData = _.cloneDeep(formData);
1175
- if (editData.name && !updatedFormData['template-name']) {
1176
- updatedFormData['template-name'] = editData.name;
1177
- }
1178
- this.props.showTemplateName({formData: updatedFormData, onFormDataChange: this.onFormDataChange});
986
+ if (this.props.isFullMode) {
987
+ this.props.showTemplateName({formData, onFormDataChange: this.onFormDataChange});
1179
988
  }
1180
989
  const isBEEAppEnable = this.checkBeeEditorAllowedForLibrary();
1181
990
  _.forEach((editData.versions.base.selectedLanguages), (language) => {
@@ -2850,7 +2659,6 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2850
2659
  getTemplateDetailsInProgress,
2851
2660
  assetUploading,
2852
2661
  createTemplateInProgress,
2853
- fetchingCmsSettings,
2854
2662
  } = this.props.Email;
2855
2663
  let isLoading =
2856
2664
  isLoadingMetaEntities ||
@@ -2859,7 +2667,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
2859
2667
  ) || (
2860
2668
  assetUploading !== undefined && assetUploading
2861
2669
  ) || (
2862
- Email && (fetchingCmsData || getTemplateDetailsInProgress || fetchingCmsSettings)
2670
+ Email && (fetchingCmsData || getTemplateDetailsInProgress)
2863
2671
  );
2864
2672
 
2865
2673
  if (!isLoading) {
@@ -3181,19 +2989,6 @@ function mapDispatchToProps(dispatch) {
3181
2989
  const withReducer = injectReducer({ key: 'email', reducer: v2EmailReducer });
3182
2990
  const withEmailSaga = injectSaga({ key: 'email', saga: v2EmailSagas });
3183
2991
 
3184
- // Base Email component without saga registration (for use from EmailWrapper)
3185
- // EmailWrapper already registers the saga, so we don't need to register it here
3186
- export const EmailWithoutSaga = withCreatives({
3187
- WrappedComponent: Email,
3188
- mapStateToProps,
3189
- mapDispatchToProps,
3190
- userAuth: true,
3191
- sagas: [], // No saga - EmailWrapper registers it
3192
- reducers: [withReducer],
3193
- });
3194
-
3195
- // Email component with saga registration (for direct use from SlideBoxContent in Edit mode)
3196
- // When Email is used directly (not as child of EmailWrapper), it needs to register the saga
3197
2992
  export default withCreatives({
3198
2993
  WrappedComponent: Email,
3199
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
  `;
@@ -15,50 +15,4 @@ describe('emailReducer', () => {
15
15
  };
16
16
  expect(emailReducer(undefined, action)).toMatchSnapshot();
17
17
  });
18
-
19
- it.concurrent('it handles GET_CMS_ACCOUNTS_REQUEST action (line 111-113)', () => {
20
- const initialState = fromJS({
21
- isBeeEnabled: true, // Start with true to verify it gets set to false
22
- });
23
- const action = {
24
- type: types.GET_CMS_ACCOUNTS_REQUEST,
25
- };
26
- const result = emailReducer(initialState, action);
27
- expect(result.get('isBeeEnabled')).toBe(false);
28
- });
29
-
30
- it.concurrent('it handles GET_CMS_ACCOUNTS_SUCCESS action (line 114-116)', () => {
31
- const initialState = fromJS({
32
- isBeeEnabled: false,
33
- });
34
- const action = {
35
- type: types.GET_CMS_ACCOUNTS_SUCCESS,
36
- isBeeEnabled: true,
37
- };
38
- const result = emailReducer(initialState, action);
39
- expect(result.get('isBeeEnabled')).toBe(true);
40
- });
41
-
42
- it.concurrent('it handles GET_CMS_ACCOUNTS_SUCCESS action with false (line 114-116)', () => {
43
- const initialState = fromJS({
44
- isBeeEnabled: true,
45
- });
46
- const action = {
47
- type: types.GET_CMS_ACCOUNTS_SUCCESS,
48
- isBeeEnabled: false,
49
- };
50
- const result = emailReducer(initialState, action);
51
- expect(result.get('isBeeEnabled')).toBe(false);
52
- });
53
-
54
- it.concurrent('it handles GET_CMS_ACCOUNTS_FAILURE action (line 117-119)', () => {
55
- const initialState = fromJS({
56
- isBeeEnabled: true, // Start with true to verify it gets set to false
57
- });
58
- const action = {
59
- type: types.GET_CMS_ACCOUNTS_FAILURE,
60
- };
61
- const result = emailReducer(initialState, action);
62
- expect(result.get('isBeeEnabled')).toBe(false);
63
- });
64
18
  });