@capillarytech/creatives-library 8.0.254 → 8.0.255-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/assets/Android.png +0 -0
  2. package/assets/iOS.png +0 -0
  3. package/constants/unified.js +2 -1
  4. package/initialReducer.js +2 -0
  5. package/package.json +1 -1
  6. package/services/api.js +10 -0
  7. package/services/tests/api.test.js +34 -0
  8. package/utils/common.js +5 -0
  9. package/utils/commonUtils.js +28 -5
  10. package/utils/tests/commonUtil.test.js +224 -0
  11. package/utils/transformTemplateConfig.js +0 -10
  12. package/v2Components/CapDeviceContent/index.js +61 -56
  13. package/v2Components/CapTagList/index.js +6 -1
  14. package/v2Components/CapTagListWithInput/index.js +5 -1
  15. package/v2Components/CapTagListWithInput/messages.js +1 -1
  16. package/v2Components/CapWhatsappCTA/tests/index.test.js +5 -0
  17. package/v2Components/ErrorInfoNote/constants.js +1 -0
  18. package/v2Components/ErrorInfoNote/index.js +457 -72
  19. package/v2Components/ErrorInfoNote/messages.js +36 -6
  20. package/v2Components/ErrorInfoNote/style.scss +282 -6
  21. package/v2Components/FormBuilder/tests/index.test.js +13 -4
  22. package/v2Components/HtmlEditor/HTMLEditor.js +547 -94
  23. package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +874 -0
  24. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +1358 -133
  25. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +27 -16
  26. package/v2Components/HtmlEditor/_htmlEditor.scss +108 -45
  27. package/v2Components/HtmlEditor/_index.lazy.scss +0 -1
  28. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +22 -101
  29. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +149 -140
  30. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +2 -1
  31. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
  32. package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +9 -0
  33. package/v2Components/HtmlEditor/components/EditorToolbar/index.js +1 -1
  34. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +22 -0
  35. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +4 -7
  36. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +35 -45
  37. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +1 -3
  38. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
  39. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +7 -6
  40. package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +3 -6
  41. package/v2Components/HtmlEditor/components/PreviewPane/index.js +24 -34
  42. package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
  43. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +49 -31
  44. package/v2Components/HtmlEditor/components/ValidationPanel/_validationPanel.scss +50 -34
  45. package/v2Components/HtmlEditor/components/ValidationPanel/constants.js +6 -0
  46. package/v2Components/HtmlEditor/components/ValidationPanel/index.js +70 -41
  47. package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +254 -0
  48. package/v2Components/HtmlEditor/components/ValidationTabs/index.js +364 -0
  49. package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +51 -0
  50. package/v2Components/HtmlEditor/constants.js +42 -20
  51. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +373 -16
  52. package/v2Components/HtmlEditor/hooks/__tests__/useValidation.apiErrors.test.js +794 -0
  53. package/v2Components/HtmlEditor/hooks/useEditorContent.js +5 -2
  54. package/v2Components/HtmlEditor/hooks/useInAppContent.js +88 -146
  55. package/v2Components/HtmlEditor/hooks/useValidation.js +189 -53
  56. package/v2Components/HtmlEditor/index.js +1 -1
  57. package/v2Components/HtmlEditor/messages.js +95 -85
  58. package/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +94 -45
  59. package/v2Components/HtmlEditor/utils/__tests__/validationAdapter.test.js +134 -0
  60. package/v2Components/HtmlEditor/utils/contentSanitizer.js +40 -41
  61. package/v2Components/HtmlEditor/utils/htmlValidator.js +71 -72
  62. package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +134 -102
  63. package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +23 -25
  64. package/v2Components/HtmlEditor/utils/validationAdapter.js +66 -41
  65. package/v2Components/HtmlEditor/utils/validationConstants.js +40 -0
  66. package/v2Components/MobilePushPreviewV2/index.js +32 -7
  67. package/v2Components/TemplatePreview/_templatePreview.scss +55 -24
  68. package/v2Components/TemplatePreview/index.js +47 -32
  69. package/v2Components/TemplatePreview/messages.js +4 -0
  70. package/v2Components/TestAndPreviewSlidebox/_testAndPreviewSlidebox.scss +1 -0
  71. package/v2Containers/BeeEditor/index.js +172 -90
  72. package/v2Containers/BeePopupEditor/_beePopupEditor.scss +14 -0
  73. package/v2Containers/BeePopupEditor/constants.js +10 -0
  74. package/v2Containers/BeePopupEditor/index.js +194 -0
  75. package/v2Containers/BeePopupEditor/tests/index.test.js +627 -0
  76. package/v2Containers/CreativesContainer/SlideBoxContent.js +128 -51
  77. package/v2Containers/CreativesContainer/SlideBoxFooter.js +163 -13
  78. package/v2Containers/CreativesContainer/SlideBoxHeader.js +2 -1
  79. package/v2Containers/CreativesContainer/constants.js +1 -0
  80. package/v2Containers/CreativesContainer/index.js +239 -46
  81. package/v2Containers/CreativesContainer/messages.js +8 -0
  82. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +11 -2
  83. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +38 -50
  84. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +106 -0
  85. package/v2Containers/Email/actions.js +7 -0
  86. package/v2Containers/Email/constants.js +5 -1
  87. package/v2Containers/Email/index.js +234 -29
  88. package/v2Containers/Email/messages.js +32 -0
  89. package/v2Containers/Email/reducer.js +12 -1
  90. package/v2Containers/Email/sagas.js +61 -7
  91. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +2 -0
  92. package/v2Containers/Email/tests/reducer.test.js +46 -0
  93. package/v2Containers/Email/tests/sagas.test.js +320 -29
  94. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +1285 -0
  95. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +207 -19
  96. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +40 -74
  97. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +1870 -0
  98. package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +520 -0
  99. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +2 -67
  100. package/v2Containers/EmailWrapper/constants.js +2 -0
  101. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +629 -77
  102. package/v2Containers/EmailWrapper/index.js +103 -23
  103. package/v2Containers/EmailWrapper/messages.js +61 -1
  104. package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +643 -0
  105. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +594 -77
  106. package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +376 -0
  107. package/v2Containers/InApp/__tests__/sagas.test.js +363 -0
  108. package/v2Containers/InApp/actions.js +7 -0
  109. package/v2Containers/InApp/constants.js +20 -4
  110. package/v2Containers/InApp/index.js +802 -359
  111. package/v2Containers/InApp/index.scss +4 -3
  112. package/v2Containers/InApp/messages.js +7 -3
  113. package/v2Containers/InApp/reducer.js +21 -3
  114. package/v2Containers/InApp/sagas.js +29 -9
  115. package/v2Containers/InApp/selectors.js +25 -5
  116. package/v2Containers/InApp/tests/index.test.js +154 -50
  117. package/v2Containers/InApp/tests/reducer.test.js +34 -0
  118. package/v2Containers/InApp/tests/sagas.test.js +61 -9
  119. package/v2Containers/InApp/tests/selectors.test.js +612 -0
  120. package/v2Containers/InAppWrapper/components/InAppWrapperView.js +151 -0
  121. package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +267 -0
  122. package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +23 -0
  123. package/v2Containers/InAppWrapper/constants.js +16 -0
  124. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +473 -0
  125. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +198 -0
  126. package/v2Containers/InAppWrapper/index.js +148 -0
  127. package/v2Containers/InAppWrapper/messages.js +49 -0
  128. package/v2Containers/InappAdvance/index.js +1099 -0
  129. package/v2Containers/InappAdvance/index.scss +10 -0
  130. package/v2Containers/InappAdvance/tests/index.test.js +448 -0
  131. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +3 -0
  132. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +2 -0
  133. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +2 -0
  134. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +9 -0
  135. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +12 -0
  136. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4 -0
  137. package/v2Containers/TagList/index.js +62 -19
  138. package/v2Containers/Templates/_templates.scss +60 -1
  139. package/v2Containers/Templates/index.js +89 -4
  140. package/v2Containers/Templates/messages.js +4 -0
  141. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +34 -0
  142. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +0 -152
  143. package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +0 -214
@@ -1,6 +1,8 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { CAP_SPACE_32, CAP_SPACE_56, CAP_SPACE_64 } from '@capillarytech/cap-ui-library/styled/variables';
3
+ import {
4
+ CAP_SPACE_16, CAP_SPACE_32, CAP_SPACE_56, CAP_SPACE_64,
5
+ } from '@capillarytech/cap-ui-library/styled/variables';
4
6
 
5
7
  import CapSlideBox from '@capillarytech/cap-ui-library/CapSlideBox';
6
8
  import CapHeader from '@capillarytech/cap-ui-library/CapHeader';
@@ -43,7 +45,7 @@ import {
43
45
  IMAGE as LINE_IMAGE, IMAGE_MAP, IMAGE_CAROUSEL, VIDEO as LINE_VIDEO, TEMPLATE, STICKER,
44
46
  } from '../Line/Container/constants';
45
47
  import { IMAGE, VIDEO } from '../Facebook/Advertisement/constant';
46
- import {RCS_STATUSES} from '../Rcs/constants';
48
+ import { RCS_STATUSES } from '../Rcs/constants';
47
49
  import { CREATIVE } from '../Facebook/constants';
48
50
  import { LOYALTY } from '../App/constants';
49
51
  import {
@@ -64,19 +66,29 @@ import {
64
66
  // getTemplateDiffState
65
67
  } from "../../utils/transformerUtils";
66
68
  import { MANUAL_CAROUSEL } from '../MobilePushNew/constants';
69
+ import { BIG_HTML } from '../InApp/constants';
67
70
 
68
71
  const classPrefix = 'add-creatives-section';
69
72
  const CREATIVES_CONTAINER = 'creativesContainer';
70
73
 
71
74
  const SlideBoxWrapper = styled.div`
72
75
  .cap-slide-box-v2-container{
73
- .slidebox-header, .slidebox-content-container, .slidebox-footer{
76
+ .slidebox-header, .slidebox-content-container{
74
77
  margin-bottom: ${({ slideBoxWrapperMargin }) => `${slideBoxWrapperMargin}`};
75
78
  padding: 0 rem;
76
79
  &.has-footer{
77
80
  overflow-x: hidden;
78
81
  }
79
82
  }
83
+ .slidebox-footer{
84
+ /* Only apply margin-bottom to footer when ErrorInfoNote is shown in footer (BEE editor) */
85
+ /* For HTML Editor, errors are shown in ValidationErrorDisplay (inside content area), so no footer margin needed */
86
+ margin-bottom: ${({ shouldApplyFooterMargin }) => (shouldApplyFooterMargin ? `${CAP_SPACE_16}` : '0')};
87
+ padding: 0 rem;
88
+ &.has-footer{
89
+ overflow-x: hidden;
90
+ }
91
+ }
80
92
  }
81
93
  `;
82
94
  export class Creatives extends React.Component {
@@ -95,6 +107,7 @@ export class Creatives extends React.Component {
95
107
  currentChannel: this.props.channel || 'sms',
96
108
  weChatTemplateType: '',
97
109
  weChatMaptemplateStep: 0,
110
+ inAppEditorType: null,
98
111
  isLiquidValidationError: false,
99
112
  errorMessages: [],
100
113
  liquidErrorMessage: {
@@ -107,6 +120,17 @@ export class Creatives extends React.Component {
107
120
  isTestAndPreviewMode: false, // Add flag to track Test & Preview mode
108
121
  // Performance optimization: Local template name for immediate UI feedback
109
122
  localTemplateName: '',
123
+ // Track selected email create mode for new flow (HTML Editor vs Drag & Drop)
124
+ selectedEmailCreateMode: null,
125
+ // HTML Editor validation state (for email channel)
126
+ htmlEditorValidationState: {
127
+ isContentEmpty: true,
128
+ issueCounts: {
129
+ html: 0, label: 0, liquid: 0, total: 0,
130
+ },
131
+ validationComplete: false, // Flag to track if validation has completed
132
+ errorsAcknowledged: false, // Flag to track if user has acknowledged errors by clicking redirection icon
133
+ },
110
134
  };
111
135
  this.liquidFlow = Boolean(commonUtil.hasLiquidSupportFeature());
112
136
  this.creativesTemplateSteps = {
@@ -136,7 +160,7 @@ export class Creatives extends React.Component {
136
160
  if (!this.props?.isFullMode) {
137
161
  this.props?.templateActions.getCdnTransformationConfig();
138
162
  }
139
-
163
+
140
164
  // Store loyalty tag props if loyaltyTagFetchingDependencies is provided
141
165
  const { loyaltyTagFetchingDependencies } = this.props;
142
166
  if (loyaltyTagFetchingDependencies) {
@@ -162,9 +186,9 @@ export class Creatives extends React.Component {
162
186
  const isEmptyTemplateName = !value.trim();
163
187
 
164
188
  // 1. IMMEDIATE: Update local state for instant UI feedback
165
- this.setState({
189
+ this.setState({
166
190
  isTemplateNameEmpty: isEmptyTemplateName,
167
- localTemplateName: value
191
+ localTemplateName: value,
168
192
  });
169
193
 
170
194
  // 2. DEBOUNCED: Only debounce the expensive onFormDataChange call
@@ -243,8 +267,19 @@ export class Creatives extends React.Component {
243
267
  onCreateNextStep = () => {
244
268
  this.setState((prevState) => {
245
269
  let templateStep = prevState.templateStep + 1;
246
- const { emailCreateMode, currentChannel } = prevState;
247
- if ((currentChannel.toUpperCase() === constants.EMAIL && emailCreateMode === "upload") || [constants.MOBILE_PUSH, constants.WECHAT, constants.INAPP].includes(currentChannel.toUpperCase())) {
270
+ const { emailCreateMode, currentChannel, selectedEmailCreateMode } = prevState;
271
+
272
+ // Check if we should skip template selection for HTML Editor
273
+ const supportCKEditor = commonUtil.hasSupportCKEditor();
274
+ const shouldSkipTemplateSelection = !supportCKEditor
275
+ && selectedEmailCreateMode === 'html_editor'
276
+ && currentChannel.toUpperCase() === constants.EMAIL
277
+ && prevState.templateStep === 1; // Only skip if we're at modeSelection step
278
+
279
+ if (shouldSkipTemplateSelection) {
280
+ // Skip template selection (step 2), go directly to createTemplateContent (step 3)
281
+ templateStep = prevState.templateStep + 2;
282
+ } else if ((currentChannel.toUpperCase() === constants.EMAIL && emailCreateMode === "upload") || [constants.MOBILE_PUSH, constants.WECHAT, constants.INAPP].includes(currentChannel.toUpperCase())) {
248
283
  templateStep = prevState.templateStep + 2;
249
284
  }
250
285
  return {
@@ -253,14 +288,21 @@ export class Creatives extends React.Component {
253
288
  });
254
289
  }
255
290
 
256
- onEmailModeChange = (mode) => {
257
- this.setState({ emailCreateMode: mode });
291
+ onEmailModeChange = (mode, selectedMode = null) => {
292
+ this.setState({
293
+ emailCreateMode: mode,
294
+ selectedEmailCreateMode: selectedMode || mode, // Store the selected mode for new flow
295
+ });
258
296
  }
259
297
 
260
298
  onInAppModeChange = (mode) => {
261
299
  this.setState({ inAppCreateMode: mode });
262
300
  }
263
301
 
302
+ onInAppEditorTypeChange = (editorType) => {
303
+ this.setState({ inAppEditorType: editorType });
304
+ }
305
+
264
306
  onMobilepushModeChange = (mode) => {
265
307
  this.setState({ mobilePushCreateMode: mode });
266
308
  }
@@ -304,7 +346,7 @@ export class Creatives extends React.Component {
304
346
  }
305
347
  return buttonObj;
306
348
  });
307
- const {url, previewUrl} = media || {};
349
+ const { url, previewUrl } = media || {};
308
350
  return {
309
351
  bodyText: bodyTemplate,
310
352
  varMap: cardVarMapped,
@@ -433,14 +475,35 @@ export class Creatives extends React.Component {
433
475
  }
434
476
  case constants.INAPP: {
435
477
  const mode = get(templateData, 'androidContent.type') || get(templateData, 'iosContent.type') || '';
478
+
479
+ // Check if this is a BEE editor template (identified by special title 'bee free template')
480
+ const isAndroidBeeEditor = templateData?.androidContent?.type === constants.HTML
481
+ && templateData?.androidContent?.title?.toLowerCase() === 'bee free template';
482
+ const isIosBeeEditor = templateData?.iosContent?.type === constants.HTML
483
+ && templateData?.iosContent?.title?.toLowerCase() === 'bee free template';
484
+
436
485
  creativesTemplateData = {
437
486
  type: channel,
438
487
  name: templateData.messageSubject,
439
488
  versions: {
440
489
  base: {
441
490
  content: {
442
- ANDROID: templateData?.androidContent,
443
- IOS: templateData?.iosContent,
491
+ ANDROID: isAndroidBeeEditor ? {
492
+ type: templateData?.androidContent?.type,
493
+ bodyType: templateData?.androidContent?.bodyType,
494
+ deviceType: constants.ANDROID,
495
+ beeHtml: { value: templateData?.androidContent?.message },
496
+ beeJson: templateData?.androidContent?.expandableDetails?.message,
497
+ isBEEeditor: true,
498
+ } : templateData?.androidContent,
499
+ IOS: isIosBeeEditor ? {
500
+ type: templateData?.iosContent?.type,
501
+ bodyType: templateData?.iosContent?.bodyType,
502
+ deviceType: constants.IOS,
503
+ beeHtml: { value: templateData?.iosContent?.message },
504
+ beeJson: templateData?.iosContent?.expandableDetails?.message,
505
+ isBEEeditor: true,
506
+ } : templateData?.iosContent,
444
507
  },
445
508
  },
446
509
  },
@@ -675,7 +738,7 @@ export class Creatives extends React.Component {
675
738
  } = templateData || {};
676
739
  const cardContent = (rcsContent.cardContent && rcsContent.cardContent[0]) || {};
677
740
  const Status = RCS_STATUSES.approved || '';
678
-
741
+
679
742
  creativesTemplateData = {
680
743
  type: channel,
681
744
  edit: true,
@@ -760,7 +823,7 @@ export class Creatives extends React.Component {
760
823
  });
761
824
 
762
825
  getMobilePushCarouselData = (expandableDetails = []) => {
763
- const newExpandableDetails = {...expandableDetails};
826
+ const newExpandableDetails = { ...expandableDetails };
764
827
  newExpandableDetails.style = expandableDetails.style || MANUAL_CAROUSEL;
765
828
  newExpandableDetails.message = expandableDetails.message || '';
766
829
  newExpandableDetails.ctas = expandableDetails.ctas || [];
@@ -855,11 +918,24 @@ export class Creatives extends React.Component {
855
918
  androidContent.custom = custom;
856
919
  }
857
920
  if (channel === constants.MOBILE_PUSH && androidContent?.expandableDetails?.carouselData?.length) {
858
- androidContent.expandableDetails = this.getMobilePushCarouselData({...androidContent?.expandableDetails});
921
+ androidContent.expandableDetails = this.getMobilePushCarouselData({ ...androidContent?.expandableDetails });
922
+ }
923
+ if (androidContent?.isBEEeditor && androidContent?.beeHtml?.value) {
924
+ templateData.androidContent = {};
925
+ templateData.androidContent.type = constants.HTML;
926
+ templateData.androidContent.message = androidContent?.beeHtml?.value || '';
927
+ templateData.androidContent.title = 'bee free template';
928
+ templateData.androidContent.bodyType = androidContent?.bodyType;
929
+ templateData.androidContent.deviceType = constants.ANDROID;
930
+ templateData.androidContent.expandableDetails = {
931
+ style: BIG_HTML,
932
+ message: androidContent?.beeJson || '',
933
+ };
934
+ } else if (!androidContent?.isBEEeditor) {
935
+ templateData.androidContent = androidContent;
936
+ templateData.androidContent.type = androidContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || constants.TEXT;
937
+ templateData.androidContent.deviceType = constants.ANDROID;
859
938
  }
860
- templateData.androidContent = androidContent;
861
- templateData.androidContent.type = androidContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || constants.TEXT;
862
- templateData.androidContent.deviceType = constants.ANDROID;
863
939
  }
864
940
  const iosContent = channel === constants.INAPP ? get(channelTemplate, 'versions.base.content.IOS') : get(channelTemplate, 'versions.base.IOS');
865
941
  if (!isEmpty(iosContent)) {
@@ -877,11 +953,24 @@ export class Creatives extends React.Component {
877
953
  iosContent.custom = custom;
878
954
  }
879
955
  if (channel === constants.MOBILE_PUSH && iosContent?.expandableDetails?.carouselData?.length) {
880
- iosContent.expandableDetails = this.getMobilePushCarouselData({...iosContent?.expandableDetails});
956
+ iosContent.expandableDetails = this.getMobilePushCarouselData({ ...iosContent?.expandableDetails });
957
+ }
958
+ if (iosContent?.isBEEeditor && iosContent?.beeHtml?.value) {
959
+ templateData.iosContent = {};
960
+ templateData.iosContent.type = constants.HTML;
961
+ templateData.iosContent.message = iosContent?.beeHtml?.value || '';
962
+ templateData.iosContent.title = 'bee free template';
963
+ templateData.iosContent.bodyType = iosContent?.bodyType;
964
+ templateData.iosContent.deviceType = constants.IOS;
965
+ templateData.iosContent.expandableDetails = {
966
+ style: BIG_HTML,
967
+ message: iosContent?.beeJson || '',
968
+ };
969
+ } else if (!iosContent?.isBEEeditor) {
970
+ templateData.iosContent = iosContent;
971
+ templateData.iosContent.type = iosContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || 'TEXT';
972
+ templateData.iosContent.deviceType = constants.IOS;
881
973
  }
882
- templateData.iosContent = iosContent;
883
- templateData.iosContent.type = iosContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || 'TEXT';
884
- templateData.iosContent.deviceType = constants.IOS;
885
974
  }
886
975
  templateData.messageSubject = channelTemplate?.name ? channelTemplate?.name : "messageSubject";
887
976
  }
@@ -1096,7 +1185,7 @@ export class Creatives extends React.Component {
1096
1185
  contentType = "",
1097
1186
  cardType = "",
1098
1187
  cardSettings = {},
1099
- } = get(versions, 'base.content.RCS.rcsContent',{});
1188
+ } = get(versions, 'base.content.RCS.rcsContent', {});
1100
1189
  const rcsContent = {
1101
1190
  contentType,
1102
1191
  cardType,
@@ -1234,7 +1323,7 @@ export class Creatives extends React.Component {
1234
1323
  processCentralCommsMetaId = (channel, creativesData) => {
1235
1324
  // Create the payload for the centralcommnsmetaId API call
1236
1325
  const { isLoyaltyModule = false, loyaltyMetaData = {} } = this.props;
1237
- const { actionName, setMetaData = () => {} } = loyaltyMetaData;
1326
+ const { actionName, setMetaData = () => { } } = loyaltyMetaData;
1238
1327
 
1239
1328
  // const isTemplateModified = getTemplateDiffState(
1240
1329
  // channel,
@@ -1284,6 +1373,9 @@ export class Creatives extends React.Component {
1284
1373
  if (prevState.currentChannel.toUpperCase() === constants.EMAIL) {
1285
1374
  newState = { ...newState, emailCreateMode: null };
1286
1375
  }
1376
+ if (prevState.currentChannel.toUpperCase() === constants.INAPP) {
1377
+ newState = { ...newState, inAppEditorType: null };
1378
+ }
1287
1379
  return newState;
1288
1380
  });
1289
1381
  }
@@ -1329,7 +1421,7 @@ export class Creatives extends React.Component {
1329
1421
  shouldShowFooter = () => {
1330
1422
  const { isFullMode } = this.props;
1331
1423
  const {
1332
- slidBoxContent, currentChannel, emailCreateMode, templateNameExists, templateStep, mobilePushCreateMode, weChatTemplateType, templateData,
1424
+ slidBoxContent, currentChannel, emailCreateMode, templateNameExists, templateStep, mobilePushCreateMode, weChatTemplateType, templateData, inAppCreateMode,
1333
1425
  } = this.state;
1334
1426
  const channel = currentChannel.toUpperCase();
1335
1427
  const currentStep = this.creativesTemplateSteps[templateStep];
@@ -1337,6 +1429,13 @@ export class Creatives extends React.Component {
1337
1429
  showFooter = isFullMode && slidBoxContent === "preview";
1338
1430
  const isMobilepush = channel === constants.MOBILE_PUSH;
1339
1431
 
1432
+ const supportCKEditor = commonUtil.hasSupportCKEditor();
1433
+ if (!supportCKEditor && channel === constants.EMAIL && currentStep === 'modeSelection' && slidBoxContent === 'createTemplate') {
1434
+ return true;
1435
+ }
1436
+ if (!supportCKEditor && channel === constants.EMAIL && currentStep === 'createTemplateContent' && slidBoxContent === 'createTemplate') {
1437
+ showFooter = true;
1438
+ }
1340
1439
 
1341
1440
  if (!isFullMode) {
1342
1441
  const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
@@ -1372,6 +1471,7 @@ export class Creatives extends React.Component {
1372
1471
  showFooter = true;
1373
1472
  }
1374
1473
 
1474
+
1375
1475
  if (showFooter) {
1376
1476
  if (slidBoxContent === "createTemplate" && ((channel === constants.EMAIL && currentStep === 'createTemplateContent')
1377
1477
  || ([constants.SMS, constants.WECHAT].includes(channel) && currentStep === 'modeSelection'))) {
@@ -1394,7 +1494,7 @@ export class Creatives extends React.Component {
1394
1494
 
1395
1495
  shouldShowDoneFooter = () => {
1396
1496
  const {
1397
- slidBoxContent, templateStep, currentChannel, templateData,
1497
+ slidBoxContent, templateStep, currentChannel, templateData, inAppCreateMode,
1398
1498
  } = this.state;
1399
1499
  const { isFullMode } = this.props;
1400
1500
  const currentStep = this.creativesTemplateSteps[templateStep];
@@ -1402,10 +1502,17 @@ export class Creatives extends React.Component {
1402
1502
  const channelName = !isFullMode && templateData ? templateData.type : currentChannel;
1403
1503
  const channel = channelName?.toUpperCase();
1404
1504
 
1405
-
1505
+ // Check supportCKEditor flag for new HTML editor flow
1506
+ const supportCKEditor = commonUtil.hasSupportCKEditor();
1406
1507
  if (channel === constants.EMAIL || channel === constants.SMS) {
1407
1508
  const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
1408
- showDone = (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate') && !isEmailCreate;
1509
+
1510
+ // For new HTML editor flow (when supportCKEditor is false), show Done footer when in createTemplateContent step
1511
+ if (!supportCKEditor && channel === constants.EMAIL && slidBoxContent === 'createTemplate' && currentStep === 'createTemplateContent') {
1512
+ showDone = true;
1513
+ } else {
1514
+ showDone = (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate') && !isEmailCreate;
1515
+ }
1409
1516
  } else if ([constants.WECHAT, constants.MOBILE_PUSH].includes(channel)) {
1410
1517
  showDone = currentStep === "createTemplateContent" || slidBoxContent === "editTemplate";
1411
1518
 
@@ -1415,7 +1522,6 @@ export class Creatives extends React.Component {
1415
1522
  }
1416
1523
  }
1417
1524
 
1418
-
1419
1525
  return showDone;
1420
1526
  }
1421
1527
 
@@ -1435,18 +1541,18 @@ export class Creatives extends React.Component {
1435
1541
  templateNameComponentInput = ({ formData, onFormDataChange, name }) => {
1436
1542
  // Use local state for immediate UI feedback, fallback to prop value
1437
1543
  const displayValue = this.state.localTemplateName !== '' ? this.state.localTemplateName : name;
1438
-
1544
+
1439
1545
  return (
1440
1546
  <CapInput
1441
1547
  value={displayValue}
1442
1548
  suffix={<span />}
1443
- onBlur={() => {
1444
- this.setState({
1549
+ onBlur={() => {
1550
+ this.setState({
1445
1551
  isEditName: false,
1446
- localTemplateName: '' // Clear local state on blur
1447
- }, () => {
1448
- this.showTemplateName({ formData, onFormDataChange });
1449
- });
1552
+ localTemplateName: '', // Clear local state on blur
1553
+ }, () => {
1554
+ this.showTemplateName({ formData, onFormDataChange });
1555
+ });
1450
1556
  }}
1451
1557
  onChange={(ev) => {
1452
1558
  const { value } = ev.currentTarget;
@@ -1458,10 +1564,18 @@ export class Creatives extends React.Component {
1458
1564
  }
1459
1565
 
1460
1566
  showTemplateName = ({ formData, onFormDataChange }) => { //gets called from email/index after template data is fetched
1461
- const { slidBoxContent, currentChannel, isEditName } = this.state;
1567
+ const {
1568
+ slidBoxContent, currentChannel, isEditName, templateStep,
1569
+ } = this.state;
1462
1570
  const channel = currentChannel.toUpperCase();
1463
1571
  if ([constants.EMAIL, constants.MOBILE_PUSH, constants.INAPP].includes(channel) && (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate')) {
1464
1572
  const name = get(formData, 'template-name');
1573
+
1574
+ const isModeSelectionStep = templateStep === 'modeSelection' || this.creativesTemplateSteps[templateStep] === 'modeSelection';
1575
+ const isCreateMode = slidBoxContent === 'createTemplate';
1576
+ if (isCreateMode && isModeSelectionStep) {
1577
+ return;
1578
+ }
1465
1579
  if (channel === constants.EMAIL && !name && slidBoxContent === 'createTemplate') {
1466
1580
  this.setState({ isTemplateNameEmpty: true });
1467
1581
  }
@@ -1469,9 +1583,9 @@ export class Creatives extends React.Component {
1469
1583
  if (name && !isEditName) {
1470
1584
  this.setState({ showTemplateNameComponentEdit: false });
1471
1585
  } else if (isEditName) {
1472
- this.setState({
1586
+ this.setState({
1473
1587
  showTemplateNameComponentEdit: true,
1474
- localTemplateName: name || '' // Initialize local state with current value
1588
+ localTemplateName: name || '', // Initialize local state with current value
1475
1589
  });
1476
1590
  }
1477
1591
  }
@@ -1485,15 +1599,31 @@ export class Creatives extends React.Component {
1485
1599
  });
1486
1600
  }
1487
1601
 
1602
+ // Callback to update HTML Editor validation state (called from EmailWrapper)
1603
+ updateHtmlEditorValidationState = (validationState) => {
1604
+ this.setState({
1605
+ htmlEditorValidationState: validationState,
1606
+ });
1607
+ }
1608
+
1488
1609
  shouldShowContinueFooter = () => { // only for email for now, has to be modified according to channel
1489
1610
  const {
1490
- slidBoxContent, templateStep, currentChannel, emailCreateMode, mobilePushCreateMode, inAppCreateMode, weChatTemplateType,
1611
+ slidBoxContent, templateStep, currentChannel, emailCreateMode, mobilePushCreateMode, inAppEditorType, weChatTemplateType,
1491
1612
  } = this.state;
1492
1613
  let isShowContinueFooter = false;
1493
1614
  const currentStep = this.creativesTemplateSteps[templateStep];
1494
1615
  const channel = currentChannel.toUpperCase();
1616
+ // Check if supportCKEditor is false (new flow)
1617
+ const supportCKEditor = commonUtil.hasSupportCKEditor(); // Default to legacy flow
1495
1618
  if (channel === constants.EMAIL || channel === constants.SMS) {
1496
- if ((emailCreateMode === "upload" && !isEmpty(this.props.EmailLayout)) || emailCreateMode === "editor") {
1619
+ // New flow: Show Continue button when supportCKEditor is false and in modeSelection
1620
+ // Always show it (even if disabled) - visibility is separate from enabled state
1621
+ if (!supportCKEditor && currentStep === 'modeSelection' && slidBoxContent === 'createTemplate') {
1622
+ return true; // Return early to ensure visibility
1623
+ }
1624
+
1625
+ // Legacy flow: Original logic (only when supportCKEditor is true)
1626
+ if (supportCKEditor && ((emailCreateMode === "upload" && !isEmpty(this.props.EmailLayout)) || emailCreateMode === "editor")) {
1497
1627
  let isEmailCreate = slidBoxContent === 'createTemplate';
1498
1628
  isEmailCreate = currentChannel.toUpperCase() === constants.EMAIL && ((emailCreateMode === "upload" && currentStep !== 'createTemplateContent') || (emailCreateMode === "editor" && currentStep !== 'createTemplateContent' && currentStep !== "templateSelection"));
1499
1629
  isShowContinueFooter = isEmailCreate && emailCreateMode;
@@ -1502,8 +1632,6 @@ export class Creatives extends React.Component {
1502
1632
  isShowContinueFooter = !isEmpty(mobilePushCreateMode) && currentStep === "modeSelection";
1503
1633
  } else if (currentChannel.toUpperCase() === constants.WECHAT) {
1504
1634
  isShowContinueFooter = !isEmpty(weChatTemplateType) && currentStep === "modeSelection";
1505
- } else if (currentChannel.toUpperCase() === constants.INAPP) {
1506
- isShowContinueFooter = !isEmpty(inAppCreateMode) && currentChannel === "modeSelection";
1507
1635
  }
1508
1636
 
1509
1637
  return isShowContinueFooter;
@@ -1529,6 +1657,28 @@ export class Creatives extends React.Component {
1529
1657
  return true;
1530
1658
  }
1531
1659
 
1660
+ // Check if Continue button should be disabled (for new flow only)
1661
+ isContinueButtonDisabled = () => {
1662
+ const { currentChannel, emailCreateMode, templateNameExists } = this.state;
1663
+ const { isFullMode } = this.props;
1664
+ const supportCKEditor = commonUtil.hasSupportCKEditor();
1665
+ if (supportCKEditor) {
1666
+ return false;
1667
+ }
1668
+ if (currentChannel.toUpperCase() === constants.EMAIL) {
1669
+ const isEditorSelected = !!emailCreateMode && emailCreateMode !== 'upload';
1670
+ // In full mode: require both template name AND editor selection
1671
+ // In library mode: require only editor selection (template name not needed)
1672
+ if (isFullMode) {
1673
+ const isTemplateNameValid = templateNameExists;
1674
+ return !(isTemplateNameValid && isEditorSelected);
1675
+ }
1676
+ // Library mode: only editor selection is required
1677
+ return !isEditorSelected;
1678
+ }
1679
+ return true;
1680
+ }
1681
+
1532
1682
  render() {
1533
1683
  const {
1534
1684
  slidBoxContent,
@@ -1537,6 +1687,7 @@ export class Creatives extends React.Component {
1537
1687
  templateData,
1538
1688
  currentChannel,
1539
1689
  emailCreateMode,
1690
+ selectedEmailCreateMode,
1540
1691
  templateStep,
1541
1692
  isLoadingContent,
1542
1693
  mobilePushCreateMode,
@@ -1549,6 +1700,8 @@ export class Creatives extends React.Component {
1549
1700
  activeFormBuilderTab,
1550
1701
  showTestAndPreviewSlidebox,
1551
1702
  isTestAndPreviewMode,
1703
+ inAppEditorType,
1704
+ htmlEditorValidationState,
1552
1705
  } = this.state;
1553
1706
  const {
1554
1707
  isFullMode,
@@ -1571,9 +1724,35 @@ export class Creatives extends React.Component {
1571
1724
  isLoyaltyModule,
1572
1725
  loyaltyMetaData = {},
1573
1726
  } = this.props;
1727
+ // Compute Continue button label
1728
+ const supportCKEditor = commonUtil.hasSupportCKEditor();
1729
+ const continueButtonLabel = supportCKEditor ? messages.continue : messages.next;
1730
+
1574
1731
  const mapTemplateCreate = slidBoxContent === "createTemplate"
1575
1732
  && weChatTemplateType === MAP_TEMPLATE
1576
1733
  && templateStep !== "modeSelection";
1734
+
1735
+ // Determine if we're in HTML Editor mode (where errors are shown in ValidationErrorDisplay, not ErrorInfoNote in footer)
1736
+ const isEmailChannel = currentChannel?.toUpperCase() === constants.EMAIL;
1737
+ const isEditMode = slidBoxContent === 'editTemplate';
1738
+ const isHTMLEditorModeInCreate = selectedEmailCreateMode === 'html_editor';
1739
+ const isHTMLEditorModeInEdit = isEditMode && htmlEditorValidationState != null;
1740
+ const isHTMLEditorMode = isEmailChannel && (isHTMLEditorModeInCreate || isHTMLEditorModeInEdit);
1741
+ const isBEEEditor = selectedEmailCreateMode === 'drag_drop'
1742
+ || (emailCreateMode === 'editor' && !isHTMLEditorMode);
1743
+
1744
+ // Check for BEE editor errors (same logic as SlideBoxFooter)
1745
+ const hasStandardErrors = liquidErrorMessage && liquidErrorMessage.STANDARD_ERROR_MSG && liquidErrorMessage.STANDARD_ERROR_MSG.length > 0;
1746
+ const hasLiquidErrors = liquidErrorMessage && liquidErrorMessage.LIQUID_ERROR_MSG && liquidErrorMessage.LIQUID_ERROR_MSG.length > 0;
1747
+ const htmlEditorHasErrors = htmlEditorValidationState && htmlEditorValidationState.issueCounts && htmlEditorValidationState.issueCounts.total > 0;
1748
+ const hasBEEEditorErrors = isEmailChannel && (hasStandardErrors || hasLiquidErrors) && (!htmlEditorValidationState || !htmlEditorHasErrors);
1749
+
1750
+ // Only apply margin to footer when ErrorInfoNote is shown in footer (BEE editor)
1751
+ // For HTML Editor, errors are shown in ValidationErrorDisplay (inside content area), so no footer margin needed
1752
+ // IMPORTANT: Never show ErrorInfoNote in footer when in HTML Editor mode, even if liquidErrorMessage exists
1753
+ const shouldShowErrorInfoNoteInFooter = isHTMLEditorMode ? false : hasBEEEditorErrors;
1754
+
1755
+ // Calculate margin for header/content (always apply if there are errors, regardless of editor type)
1577
1756
  const slideBoxWrapperMargin = (get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0 && get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0)
1578
1757
  ? CAP_SPACE_64
1579
1758
  : get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0
@@ -1583,7 +1762,11 @@ export class Creatives extends React.Component {
1583
1762
  : 0;
1584
1763
  /* TODO: Instead of passing down same props separately to each component down, write common function to these props and pass it accordingly */
1585
1764
  return (
1586
- <SlideBoxWrapper slideBoxWrapperMargin={slideBoxWrapperMargin} className={classnames(`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`)}>
1765
+ <SlideBoxWrapper
1766
+ slideBoxWrapperMargin={slideBoxWrapperMargin}
1767
+ shouldApplyFooterMargin={shouldShowErrorInfoNoteInFooter}
1768
+ className={classnames(`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`)}
1769
+ >
1587
1770
  <CapSlideBox
1588
1771
  header={
1589
1772
  this.shouldShowHeader() && (
@@ -1632,6 +1815,8 @@ export class Creatives extends React.Component {
1632
1815
  onChannelChange={this.onChannelChange}
1633
1816
  onEmailModeChange={this.onEmailModeChange}//used when create is clicked in email
1634
1817
  emailCreateMode={emailCreateMode}// upload zip || use editor are values
1818
+ onInAppEditorTypeChange={this.onInAppEditorTypeChange}//used when create is clicked in inapp
1819
+ inAppEditorType={inAppEditorType}// htmlEditor || dragDropEditor are values
1635
1820
  templateStep={this.creativesTemplateSteps[templateStep]}
1636
1821
  onCreateNextStep={this.onCreateNextStep}
1637
1822
  onEnterTemplateName={this.onEnterTemplateName}
@@ -1641,6 +1826,8 @@ export class Creatives extends React.Component {
1641
1826
  cap={cap}
1642
1827
  setIsLoadingContent={this.setIsLoadingContent}
1643
1828
  onMobilepushModeChange={this.onMobilepushModeChange}
1829
+ inAppCreateMode={this.state.inAppCreateMode}
1830
+ onInAppModeChange={this.onInAppModeChange}
1644
1831
  mobilePushCreateMode={mobilePushCreateMode}
1645
1832
  showTemplateName={this.showTemplateName}
1646
1833
  onValidationFail={this.onValidationFail}
@@ -1679,6 +1866,7 @@ export class Creatives extends React.Component {
1679
1866
  handleTestAndPreview={this.handleTestAndPreview}
1680
1867
  handleCloseTestAndPreview={this.handleCloseTestAndPreview}
1681
1868
  isTestAndPreviewMode={(() => this.state.isTestAndPreviewMode)()}
1869
+ onHtmlEditorValidationStateChange={this.updateHtmlEditorValidationState}
1682
1870
  />
1683
1871
  )}
1684
1872
  footer={this.shouldShowFooter() ? (
@@ -1693,6 +1881,7 @@ export class Creatives extends React.Component {
1693
1881
  currentChannel={currentChannel.toUpperCase()}
1694
1882
  templateStep={this.creativesTemplateSteps[templateStep]}
1695
1883
  emailCreateMode={emailCreateMode}
1884
+ selectedEmailCreateMode={selectedEmailCreateMode}
1696
1885
  shouldShowContinueFooter={this.shouldShowContinueFooter}
1697
1886
  shouldShowDoneFooter={this.shouldShowDoneFooter}
1698
1887
  fetchingCmsData={fetchingCmsData}
@@ -1701,18 +1890,22 @@ export class Creatives extends React.Component {
1701
1890
  errorMessages={liquidErrorMessage}
1702
1891
  currentTab={activeFormBuilderTab}
1703
1892
  onTestAndPreview={this.handleTestAndPreview}
1893
+ isContinueButtonDisabled={this.isContinueButtonDisabled()}
1894
+ continueButtonLabel={continueButtonLabel}
1704
1895
  showTestAndPreviewButton={(() => {
1705
1896
  const isEmailOrSmsOrWhatsappOrRcsOrInAppOrMobilePush = [constants.EMAIL, constants.SMS, constants.WHATSAPP, constants.RCS, constants.INAPP, constants.MOBILE_PUSH, constants.VIBER, constants.ZALO].includes(currentChannel.toUpperCase());
1706
1897
  const showButton = isEmailOrSmsOrWhatsappOrRcsOrInAppOrMobilePush && (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate');
1707
1898
  return showButton;
1708
1899
  })()}
1900
+ htmlEditorValidationState={htmlEditorValidationState}
1901
+ isCreatingTemplate={slidBoxContent === 'createTemplate' && currentChannel.toUpperCase() === constants.EMAIL}
1709
1902
  />
1710
1903
  ) : isLiquidValidationError && (
1711
1904
  <CapRow className="template-footer-width">
1712
1905
  {(() => {
1713
1906
  const errorsToShow = get(liquidErrorMessage, constants.LIQUID_ERROR_MSG, []);
1714
1907
  const standardErrorsToShow = get(liquidErrorMessage, constants.STANDARD_ERROR_MSG, []);
1715
- return <ErrorInfoNote currentTab={activeFormBuilderTab?.toUpperCase()} errorMessages={{LIQUID_ERROR_MSG: errorsToShow, STANDARD_ERROR_MSG: standardErrorsToShow}} />;
1908
+ return <ErrorInfoNote currentTab={activeFormBuilderTab?.toUpperCase()} errorMessages={{ LIQUID_ERROR_MSG: errorsToShow, STANDARD_ERROR_MSG: standardErrorsToShow }} />;
1716
1909
  })()}
1717
1910
  </CapRow>
1718
1911
  )}
@@ -282,6 +282,10 @@ export default defineMessages({
282
282
  id: `${scope}.creativesTemplatesUpdate`,
283
283
  defaultMessage: `Update`,
284
284
  },
285
+ "creativesTemplatesDone": {
286
+ id: `${scope}.creativesTemplatesDone`,
287
+ defaultMessage: `Done`,
288
+ },
285
289
  "creativesTemplatesDiscard": {
286
290
  id: `${scope}.creativesTemplatesDiscard`,
287
291
  defaultMessage: `Discard`,
@@ -366,4 +370,8 @@ export default defineMessages({
366
370
  id: `${scope}.testAndPreview`,
367
371
  defaultMessage: `Preview and Test`,
368
372
  },
373
+ "next": {
374
+ id: `${scope}.next`,
375
+ defaultMessage: `Next`,
376
+ },
369
377
  });
@@ -43,7 +43,12 @@ describe("test for empty email empty template name", () => {
43
43
  slidBoxContent: "editTemplate",
44
44
  currentChannel: "EMAIL",
45
45
  templateStep: "modeSelection",
46
- isTemplateNameEmpty: true
46
+ isTemplateNameEmpty: true,
47
+ htmlEditorValidationState: {
48
+ isContentEmpty: false,
49
+ issueCounts: { html: 0, label: 0, liquid: 0, total: 0 },
50
+ },
51
+ isCreatingTemplate: false,
47
52
  }
48
53
  renderComponent(props);
49
54
  const errorMessage = await screen.findByText(/template name cannot be empty/i);
@@ -52,7 +57,11 @@ describe("test for empty email empty template name", () => {
52
57
  expect(updateBtn).toBeDisabled();
53
58
  renderComponent({
54
59
  ...props,
55
- isTemplateNameEmpty: false
60
+ isTemplateNameEmpty: false,
61
+ htmlEditorValidationState: {
62
+ isContentEmpty: false,
63
+ issueCounts: { html: 0, label: 0, liquid: 0, total: 0 },
64
+ },
56
65
  })
57
66
  const updateBtns = screen.getAllByRole('button',{name:/update/i});
58
67
  expect(updateBtns[1]).toBeEnabled();