@capillarytech/creatives-library 8.0.249 → 8.0.250-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 (136) 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 +18 -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/index.js +452 -72
  18. package/v2Components/ErrorInfoNote/messages.js +22 -0
  19. package/v2Components/ErrorInfoNote/style.scss +280 -4
  20. package/v2Components/FormBuilder/tests/index.test.js +13 -4
  21. package/v2Components/HtmlEditor/HTMLEditor.js +640 -94
  22. package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +874 -0
  23. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +1167 -133
  24. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +27 -16
  25. package/v2Components/HtmlEditor/_htmlEditor.scss +108 -45
  26. package/v2Components/HtmlEditor/_index.lazy.scss +1 -1
  27. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +13 -101
  28. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +148 -139
  29. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +2 -1
  30. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
  31. package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +9 -0
  32. package/v2Components/HtmlEditor/components/EditorToolbar/index.js +1 -1
  33. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +22 -0
  34. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +4 -7
  35. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +35 -45
  36. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +1 -3
  37. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
  38. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +7 -6
  39. package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +3 -6
  40. package/v2Components/HtmlEditor/components/PreviewPane/index.js +11 -13
  41. package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
  42. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +49 -31
  43. package/v2Components/HtmlEditor/components/ValidationPanel/index.js +68 -39
  44. package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +254 -0
  45. package/v2Components/HtmlEditor/components/ValidationTabs/index.js +391 -0
  46. package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +51 -0
  47. package/v2Components/HtmlEditor/constants.js +42 -20
  48. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +373 -16
  49. package/v2Components/HtmlEditor/hooks/__tests__/useValidation.apiErrors.test.js +795 -0
  50. package/v2Components/HtmlEditor/hooks/useEditorContent.js +5 -2
  51. package/v2Components/HtmlEditor/hooks/useInAppContent.js +88 -146
  52. package/v2Components/HtmlEditor/hooks/useValidation.js +189 -53
  53. package/v2Components/HtmlEditor/index.js +1 -1
  54. package/v2Components/HtmlEditor/messages.js +95 -85
  55. package/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +94 -45
  56. package/v2Components/HtmlEditor/utils/contentSanitizer.js +40 -41
  57. package/v2Components/HtmlEditor/utils/htmlValidator.js +71 -72
  58. package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +134 -102
  59. package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +23 -25
  60. package/v2Components/HtmlEditor/utils/validationAdapter.js +66 -41
  61. package/v2Components/MobilePushPreviewV2/index.js +32 -7
  62. package/v2Components/TemplatePreview/_templatePreview.scss +44 -24
  63. package/v2Components/TemplatePreview/index.js +47 -32
  64. package/v2Components/TemplatePreview/messages.js +4 -0
  65. package/v2Components/TestAndPreviewSlidebox/_testAndPreviewSlidebox.scss +1 -0
  66. package/v2Containers/BeeEditor/index.js +172 -90
  67. package/v2Containers/BeePopupEditor/constants.js +10 -0
  68. package/v2Containers/BeePopupEditor/index.js +193 -0
  69. package/v2Containers/BeePopupEditor/tests/index.test.js +627 -0
  70. package/v2Containers/CreativesContainer/SlideBoxContent.js +127 -51
  71. package/v2Containers/CreativesContainer/SlideBoxFooter.js +163 -13
  72. package/v2Containers/CreativesContainer/SlideBoxHeader.js +2 -1
  73. package/v2Containers/CreativesContainer/constants.js +1 -0
  74. package/v2Containers/CreativesContainer/index.js +239 -46
  75. package/v2Containers/CreativesContainer/messages.js +8 -0
  76. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +11 -2
  77. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +38 -50
  78. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +106 -0
  79. package/v2Containers/Email/actions.js +7 -0
  80. package/v2Containers/Email/constants.js +5 -1
  81. package/v2Containers/Email/index.js +222 -27
  82. package/v2Containers/Email/messages.js +32 -0
  83. package/v2Containers/Email/reducer.js +12 -1
  84. package/v2Containers/Email/sagas.js +61 -7
  85. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +2 -0
  86. package/v2Containers/Email/tests/sagas.test.js +320 -29
  87. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +1321 -0
  88. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +210 -15
  89. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +40 -74
  90. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +1749 -0
  91. package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +520 -0
  92. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +2 -67
  93. package/v2Containers/EmailWrapper/constants.js +2 -0
  94. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +629 -77
  95. package/v2Containers/EmailWrapper/index.js +103 -23
  96. package/v2Containers/EmailWrapper/messages.js +61 -1
  97. package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +643 -0
  98. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +594 -77
  99. package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +376 -0
  100. package/v2Containers/InApp/__tests__/sagas.test.js +363 -0
  101. package/v2Containers/InApp/actions.js +7 -0
  102. package/v2Containers/InApp/constants.js +20 -4
  103. package/v2Containers/InApp/index.js +802 -359
  104. package/v2Containers/InApp/index.scss +4 -3
  105. package/v2Containers/InApp/messages.js +7 -3
  106. package/v2Containers/InApp/reducer.js +21 -3
  107. package/v2Containers/InApp/sagas.js +29 -9
  108. package/v2Containers/InApp/selectors.js +25 -5
  109. package/v2Containers/InApp/tests/index.test.js +154 -50
  110. package/v2Containers/InApp/tests/reducer.test.js +34 -0
  111. package/v2Containers/InApp/tests/sagas.test.js +61 -9
  112. package/v2Containers/InApp/tests/selectors.test.js +612 -0
  113. package/v2Containers/InAppWrapper/components/InAppWrapperView.js +162 -0
  114. package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +267 -0
  115. package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +9 -0
  116. package/v2Containers/InAppWrapper/constants.js +16 -0
  117. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +473 -0
  118. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +198 -0
  119. package/v2Containers/InAppWrapper/index.js +148 -0
  120. package/v2Containers/InAppWrapper/messages.js +49 -0
  121. package/v2Containers/InappAdvance/index.js +1099 -0
  122. package/v2Containers/InappAdvance/index.scss +10 -0
  123. package/v2Containers/InappAdvance/tests/index.test.js +448 -0
  124. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +3 -0
  125. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +2 -0
  126. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +2 -0
  127. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +9 -0
  128. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +12 -0
  129. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4 -0
  130. package/v2Containers/TagList/index.js +62 -19
  131. package/v2Containers/Templates/_templates.scss +60 -1
  132. package/v2Containers/Templates/index.js +89 -4
  133. package/v2Containers/Templates/messages.js +4 -0
  134. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +34 -0
  135. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +0 -152
  136. 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';
@@ -44,7 +46,7 @@ import {
44
46
  } from '../Line/Container/constants';
45
47
  import {EXTERNAL_URL, SITE_URL, WEBPUSH_MEDIA_TYPES} from '../WebPush/constants';
46
48
  import { IMAGE, VIDEO } from '../Facebook/Advertisement/constant';
47
- import {RCS_STATUSES} from '../Rcs/constants';
49
+ import { RCS_STATUSES } from '../Rcs/constants';
48
50
  import { CREATIVE } from '../Facebook/constants';
49
51
  import { LOYALTY } from '../App/constants';
50
52
  import {
@@ -65,19 +67,29 @@ import {
65
67
  // getTemplateDiffState
66
68
  } from "../../utils/transformerUtils";
67
69
  import { MANUAL_CAROUSEL } from '../MobilePushNew/constants';
70
+ import { BIG_HTML } from '../InApp/constants';
68
71
 
69
72
  const classPrefix = 'add-creatives-section';
70
73
  const CREATIVES_CONTAINER = 'creativesContainer';
71
74
 
72
75
  const SlideBoxWrapper = styled.div`
73
76
  .cap-slide-box-v2-container{
74
- .slidebox-header, .slidebox-content-container, .slidebox-footer{
77
+ .slidebox-header, .slidebox-content-container{
75
78
  margin-bottom: ${({ slideBoxWrapperMargin }) => `${slideBoxWrapperMargin}`};
76
79
  padding: 0 rem;
77
80
  &.has-footer{
78
81
  overflow-x: hidden;
79
82
  }
80
83
  }
84
+ .slidebox-footer{
85
+ /* Only apply margin-bottom to footer when ErrorInfoNote is shown in footer (BEE editor) */
86
+ /* For HTML Editor, errors are shown in ValidationErrorDisplay (inside content area), so no footer margin needed */
87
+ margin-bottom: ${({ shouldApplyFooterMargin }) => (shouldApplyFooterMargin ? `${CAP_SPACE_16}` : '0')};
88
+ padding: 0 rem;
89
+ &.has-footer{
90
+ overflow-x: hidden;
91
+ }
92
+ }
81
93
  }
82
94
  `;
83
95
  export class Creatives extends React.Component {
@@ -96,6 +108,7 @@ export class Creatives extends React.Component {
96
108
  currentChannel: this.props.channel || 'sms',
97
109
  weChatTemplateType: '',
98
110
  weChatMaptemplateStep: 0,
111
+ inAppEditorType: null,
99
112
  isLiquidValidationError: false,
100
113
  errorMessages: [],
101
114
  liquidErrorMessage: {
@@ -108,6 +121,17 @@ export class Creatives extends React.Component {
108
121
  isTestAndPreviewMode: false, // Add flag to track Test & Preview mode
109
122
  // Performance optimization: Local template name for immediate UI feedback
110
123
  localTemplateName: '',
124
+ // Track selected email create mode for new flow (HTML Editor vs Drag & Drop)
125
+ selectedEmailCreateMode: null,
126
+ // HTML Editor validation state (for email channel)
127
+ htmlEditorValidationState: {
128
+ isContentEmpty: true,
129
+ issueCounts: {
130
+ html: 0, label: 0, liquid: 0, total: 0,
131
+ },
132
+ validationComplete: false, // Flag to track if validation has completed
133
+ errorsAcknowledged: false, // Flag to track if user has acknowledged errors by clicking redirection icon
134
+ },
111
135
  };
112
136
  this.liquidFlow = Boolean(commonUtil.hasLiquidSupportFeature());
113
137
  this.creativesTemplateSteps = {
@@ -137,7 +161,7 @@ export class Creatives extends React.Component {
137
161
  if (!this.props?.isFullMode) {
138
162
  this.props?.templateActions.getCdnTransformationConfig();
139
163
  }
140
-
164
+
141
165
  // Store loyalty tag props if loyaltyTagFetchingDependencies is provided
142
166
  const { loyaltyTagFetchingDependencies } = this.props;
143
167
  if (loyaltyTagFetchingDependencies) {
@@ -163,9 +187,9 @@ export class Creatives extends React.Component {
163
187
  const isEmptyTemplateName = !value.trim();
164
188
 
165
189
  // 1. IMMEDIATE: Update local state for instant UI feedback
166
- this.setState({
190
+ this.setState({
167
191
  isTemplateNameEmpty: isEmptyTemplateName,
168
- localTemplateName: value
192
+ localTemplateName: value,
169
193
  });
170
194
 
171
195
  // 2. DEBOUNCED: Only debounce the expensive onFormDataChange call
@@ -244,8 +268,19 @@ export class Creatives extends React.Component {
244
268
  onCreateNextStep = () => {
245
269
  this.setState((prevState) => {
246
270
  let templateStep = prevState.templateStep + 1;
247
- const { emailCreateMode, currentChannel } = prevState;
248
- if ((currentChannel.toUpperCase() === constants.EMAIL && emailCreateMode === "upload") || [constants.MOBILE_PUSH, constants.WECHAT, constants.INAPP].includes(currentChannel.toUpperCase())) {
271
+ const { emailCreateMode, currentChannel, selectedEmailCreateMode } = prevState;
272
+
273
+ // Check if we should skip template selection for HTML Editor
274
+ const supportCKEditor = commonUtil.hasSupportCKEditor();
275
+ const shouldSkipTemplateSelection = !supportCKEditor
276
+ && selectedEmailCreateMode === 'html_editor'
277
+ && currentChannel.toUpperCase() === constants.EMAIL
278
+ && prevState.templateStep === 1; // Only skip if we're at modeSelection step
279
+
280
+ if (shouldSkipTemplateSelection) {
281
+ // Skip template selection (step 2), go directly to createTemplateContent (step 3)
282
+ templateStep = prevState.templateStep + 2;
283
+ } else if ((currentChannel.toUpperCase() === constants.EMAIL && emailCreateMode === "upload") || [constants.MOBILE_PUSH, constants.WECHAT, constants.INAPP].includes(currentChannel.toUpperCase())) {
249
284
  templateStep = prevState.templateStep + 2;
250
285
  }
251
286
  return {
@@ -254,14 +289,21 @@ export class Creatives extends React.Component {
254
289
  });
255
290
  }
256
291
 
257
- onEmailModeChange = (mode) => {
258
- this.setState({ emailCreateMode: mode });
292
+ onEmailModeChange = (mode, selectedMode = null) => {
293
+ this.setState({
294
+ emailCreateMode: mode,
295
+ selectedEmailCreateMode: selectedMode || mode, // Store the selected mode for new flow
296
+ });
259
297
  }
260
298
 
261
299
  onInAppModeChange = (mode) => {
262
300
  this.setState({ inAppCreateMode: mode });
263
301
  }
264
302
 
303
+ onInAppEditorTypeChange = (editorType) => {
304
+ this.setState({ inAppEditorType: editorType });
305
+ }
306
+
265
307
  onMobilepushModeChange = (mode) => {
266
308
  this.setState({ mobilePushCreateMode: mode });
267
309
  }
@@ -305,7 +347,7 @@ export class Creatives extends React.Component {
305
347
  }
306
348
  return buttonObj;
307
349
  });
308
- const {url, previewUrl} = media || {};
350
+ const { url, previewUrl } = media || {};
309
351
  return {
310
352
  bodyText: bodyTemplate,
311
353
  varMap: cardVarMapped,
@@ -434,14 +476,35 @@ export class Creatives extends React.Component {
434
476
  }
435
477
  case constants.INAPP: {
436
478
  const mode = get(templateData, 'androidContent.type') || get(templateData, 'iosContent.type') || '';
479
+
480
+ // Check if this is a BEE editor template (identified by special title 'bee free template')
481
+ const isAndroidBeeEditor = templateData?.androidContent?.type === constants.HTML
482
+ && templateData?.androidContent?.title?.toLowerCase() === 'bee free template';
483
+ const isIosBeeEditor = templateData?.iosContent?.type === constants.HTML
484
+ && templateData?.iosContent?.title?.toLowerCase() === 'bee free template';
485
+
437
486
  creativesTemplateData = {
438
487
  type: channel,
439
488
  name: templateData.messageSubject,
440
489
  versions: {
441
490
  base: {
442
491
  content: {
443
- ANDROID: templateData?.androidContent,
444
- IOS: templateData?.iosContent,
492
+ ANDROID: isAndroidBeeEditor ? {
493
+ type: templateData?.androidContent?.type,
494
+ bodyType: templateData?.androidContent?.bodyType,
495
+ deviceType: constants.ANDROID,
496
+ beeHtml: { value: templateData?.androidContent?.message },
497
+ beeJson: templateData?.androidContent?.expandableDetails?.message,
498
+ isBEEeditor: true,
499
+ } : templateData?.androidContent,
500
+ IOS: isIosBeeEditor ? {
501
+ type: templateData?.iosContent?.type,
502
+ bodyType: templateData?.iosContent?.bodyType,
503
+ deviceType: constants.IOS,
504
+ beeHtml: { value: templateData?.iosContent?.message },
505
+ beeJson: templateData?.iosContent?.expandableDetails?.message,
506
+ isBEEeditor: true,
507
+ } : templateData?.iosContent,
445
508
  },
446
509
  },
447
510
  },
@@ -676,7 +739,7 @@ export class Creatives extends React.Component {
676
739
  } = templateData || {};
677
740
  const cardContent = (rcsContent.cardContent && rcsContent.cardContent[0]) || {};
678
741
  const Status = RCS_STATUSES.approved || '';
679
-
742
+
680
743
  creativesTemplateData = {
681
744
  type: channel,
682
745
  edit: true,
@@ -828,7 +891,7 @@ export class Creatives extends React.Component {
828
891
  });
829
892
 
830
893
  getMobilePushCarouselData = (expandableDetails = []) => {
831
- const newExpandableDetails = {...expandableDetails};
894
+ const newExpandableDetails = { ...expandableDetails };
832
895
  newExpandableDetails.style = expandableDetails.style || MANUAL_CAROUSEL;
833
896
  newExpandableDetails.message = expandableDetails.message || '';
834
897
  newExpandableDetails.ctas = expandableDetails.ctas || [];
@@ -923,11 +986,24 @@ export class Creatives extends React.Component {
923
986
  androidContent.custom = custom;
924
987
  }
925
988
  if (channel === constants.MOBILE_PUSH && androidContent?.expandableDetails?.carouselData?.length) {
926
- androidContent.expandableDetails = this.getMobilePushCarouselData({...androidContent?.expandableDetails});
989
+ androidContent.expandableDetails = this.getMobilePushCarouselData({ ...androidContent?.expandableDetails });
990
+ }
991
+ if (androidContent?.isBEEeditor && androidContent?.beeHtml?.value) {
992
+ templateData.androidContent = {};
993
+ templateData.androidContent.type = constants.HTML;
994
+ templateData.androidContent.message = androidContent?.beeHtml?.value || '';
995
+ templateData.androidContent.title = 'bee free template';
996
+ templateData.androidContent.bodyType = androidContent?.bodyType;
997
+ templateData.androidContent.deviceType = constants.ANDROID;
998
+ templateData.androidContent.expandableDetails = {
999
+ style: BIG_HTML,
1000
+ message: androidContent?.beeJson || '',
1001
+ };
1002
+ } else if (!androidContent?.isBEEeditor) {
1003
+ templateData.androidContent = androidContent;
1004
+ templateData.androidContent.type = androidContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || constants.TEXT;
1005
+ templateData.androidContent.deviceType = constants.ANDROID;
927
1006
  }
928
- templateData.androidContent = androidContent;
929
- templateData.androidContent.type = androidContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || constants.TEXT;
930
- templateData.androidContent.deviceType = constants.ANDROID;
931
1007
  }
932
1008
  const iosContent = channel === constants.INAPP ? get(channelTemplate, 'versions.base.content.IOS') : get(channelTemplate, 'versions.base.IOS');
933
1009
  if (!isEmpty(iosContent)) {
@@ -945,11 +1021,24 @@ export class Creatives extends React.Component {
945
1021
  iosContent.custom = custom;
946
1022
  }
947
1023
  if (channel === constants.MOBILE_PUSH && iosContent?.expandableDetails?.carouselData?.length) {
948
- iosContent.expandableDetails = this.getMobilePushCarouselData({...iosContent?.expandableDetails});
1024
+ iosContent.expandableDetails = this.getMobilePushCarouselData({ ...iosContent?.expandableDetails });
1025
+ }
1026
+ if (iosContent?.isBEEeditor && iosContent?.beeHtml?.value) {
1027
+ templateData.iosContent = {};
1028
+ templateData.iosContent.type = constants.HTML;
1029
+ templateData.iosContent.message = iosContent?.beeHtml?.value || '';
1030
+ templateData.iosContent.title = 'bee free template';
1031
+ templateData.iosContent.bodyType = iosContent?.bodyType;
1032
+ templateData.iosContent.deviceType = constants.IOS;
1033
+ templateData.iosContent.expandableDetails = {
1034
+ style: BIG_HTML,
1035
+ message: iosContent?.beeJson || '',
1036
+ };
1037
+ } else if (!iosContent?.isBEEeditor) {
1038
+ templateData.iosContent = iosContent;
1039
+ templateData.iosContent.type = iosContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || 'TEXT';
1040
+ templateData.iosContent.deviceType = constants.IOS;
949
1041
  }
950
- templateData.iosContent = iosContent;
951
- templateData.iosContent.type = iosContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || 'TEXT';
952
- templateData.iosContent.deviceType = constants.IOS;
953
1042
  }
954
1043
  templateData.messageSubject = channelTemplate?.name ? channelTemplate?.name : "messageSubject";
955
1044
  }
@@ -1164,7 +1253,7 @@ export class Creatives extends React.Component {
1164
1253
  contentType = "",
1165
1254
  cardType = "",
1166
1255
  cardSettings = {},
1167
- } = get(versions, 'base.content.RCS.rcsContent',{});
1256
+ } = get(versions, 'base.content.RCS.rcsContent', {});
1168
1257
  const rcsContent = {
1169
1258
  contentType,
1170
1259
  cardType,
@@ -1402,7 +1491,7 @@ export class Creatives extends React.Component {
1402
1491
  processCentralCommsMetaId = (channel, creativesData) => {
1403
1492
  // Create the payload for the centralcommnsmetaId API call
1404
1493
  const { isLoyaltyModule = false, loyaltyMetaData = {} } = this.props;
1405
- const { actionName, setMetaData = () => {} } = loyaltyMetaData;
1494
+ const { actionName, setMetaData = () => { } } = loyaltyMetaData;
1406
1495
 
1407
1496
  // const isTemplateModified = getTemplateDiffState(
1408
1497
  // channel,
@@ -1452,6 +1541,9 @@ export class Creatives extends React.Component {
1452
1541
  if (prevState.currentChannel.toUpperCase() === constants.EMAIL) {
1453
1542
  newState = { ...newState, emailCreateMode: null };
1454
1543
  }
1544
+ if (prevState.currentChannel.toUpperCase() === constants.INAPP) {
1545
+ newState = { ...newState, inAppEditorType: null };
1546
+ }
1455
1547
  return newState;
1456
1548
  });
1457
1549
  }
@@ -1497,7 +1589,7 @@ export class Creatives extends React.Component {
1497
1589
  shouldShowFooter = () => {
1498
1590
  const { isFullMode } = this.props;
1499
1591
  const {
1500
- slidBoxContent, currentChannel, emailCreateMode, templateNameExists, templateStep, mobilePushCreateMode, weChatTemplateType, templateData,
1592
+ slidBoxContent, currentChannel, emailCreateMode, templateNameExists, templateStep, mobilePushCreateMode, weChatTemplateType, templateData, inAppCreateMode,
1501
1593
  } = this.state;
1502
1594
  const channel = currentChannel.toUpperCase();
1503
1595
  const currentStep = this.creativesTemplateSteps[templateStep];
@@ -1505,6 +1597,13 @@ export class Creatives extends React.Component {
1505
1597
  showFooter = isFullMode && slidBoxContent === "preview";
1506
1598
  const isMobilepush = channel === constants.MOBILE_PUSH;
1507
1599
 
1600
+ const supportCKEditor = commonUtil.hasSupportCKEditor();
1601
+ if (!supportCKEditor && channel === constants.EMAIL && currentStep === 'modeSelection' && slidBoxContent === 'createTemplate') {
1602
+ return true;
1603
+ }
1604
+ if (!supportCKEditor && channel === constants.EMAIL && currentStep === 'createTemplateContent' && slidBoxContent === 'createTemplate') {
1605
+ showFooter = true;
1606
+ }
1508
1607
 
1509
1608
  if (!isFullMode) {
1510
1609
  const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
@@ -1540,6 +1639,7 @@ export class Creatives extends React.Component {
1540
1639
  showFooter = true;
1541
1640
  }
1542
1641
 
1642
+
1543
1643
  if (showFooter) {
1544
1644
  if (slidBoxContent === "createTemplate" && ((channel === constants.EMAIL && currentStep === 'createTemplateContent')
1545
1645
  || ([constants.SMS, constants.WECHAT].includes(channel) && currentStep === 'modeSelection'))) {
@@ -1562,7 +1662,7 @@ export class Creatives extends React.Component {
1562
1662
 
1563
1663
  shouldShowDoneFooter = () => {
1564
1664
  const {
1565
- slidBoxContent, templateStep, currentChannel, templateData,
1665
+ slidBoxContent, templateStep, currentChannel, templateData, inAppCreateMode,
1566
1666
  } = this.state;
1567
1667
  const { isFullMode } = this.props;
1568
1668
  const currentStep = this.creativesTemplateSteps[templateStep];
@@ -1570,10 +1670,17 @@ export class Creatives extends React.Component {
1570
1670
  const channelName = !isFullMode && templateData ? templateData.type : currentChannel;
1571
1671
  const channel = channelName?.toUpperCase();
1572
1672
 
1573
-
1673
+ // Check supportCKEditor flag for new HTML editor flow
1674
+ const supportCKEditor = commonUtil.hasSupportCKEditor();
1574
1675
  if (channel === constants.EMAIL || channel === constants.SMS) {
1575
1676
  const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
1576
- showDone = (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate') && !isEmailCreate;
1677
+
1678
+ // For new HTML editor flow (when supportCKEditor is false), show Done footer when in createTemplateContent step
1679
+ if (!supportCKEditor && channel === constants.EMAIL && slidBoxContent === 'createTemplate' && currentStep === 'createTemplateContent') {
1680
+ showDone = true;
1681
+ } else {
1682
+ showDone = (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate') && !isEmailCreate;
1683
+ }
1577
1684
  } else if ([constants.WECHAT, constants.MOBILE_PUSH].includes(channel)) {
1578
1685
  showDone = currentStep === "createTemplateContent" || slidBoxContent === "editTemplate";
1579
1686
 
@@ -1583,7 +1690,6 @@ export class Creatives extends React.Component {
1583
1690
  }
1584
1691
  }
1585
1692
 
1586
-
1587
1693
  return showDone;
1588
1694
  }
1589
1695
 
@@ -1603,18 +1709,18 @@ export class Creatives extends React.Component {
1603
1709
  templateNameComponentInput = ({ formData, onFormDataChange, name }) => {
1604
1710
  // Use local state for immediate UI feedback, fallback to prop value
1605
1711
  const displayValue = this.state.localTemplateName !== '' ? this.state.localTemplateName : name;
1606
-
1712
+
1607
1713
  return (
1608
1714
  <CapInput
1609
1715
  value={displayValue}
1610
1716
  suffix={<span />}
1611
- onBlur={() => {
1612
- this.setState({
1717
+ onBlur={() => {
1718
+ this.setState({
1613
1719
  isEditName: false,
1614
- localTemplateName: '' // Clear local state on blur
1615
- }, () => {
1616
- this.showTemplateName({ formData, onFormDataChange });
1617
- });
1720
+ localTemplateName: '', // Clear local state on blur
1721
+ }, () => {
1722
+ this.showTemplateName({ formData, onFormDataChange });
1723
+ });
1618
1724
  }}
1619
1725
  onChange={(ev) => {
1620
1726
  const { value } = ev.currentTarget;
@@ -1626,10 +1732,18 @@ export class Creatives extends React.Component {
1626
1732
  }
1627
1733
 
1628
1734
  showTemplateName = ({ formData, onFormDataChange }) => { //gets called from email/index after template data is fetched
1629
- const { slidBoxContent, currentChannel, isEditName } = this.state;
1735
+ const {
1736
+ slidBoxContent, currentChannel, isEditName, templateStep,
1737
+ } = this.state;
1630
1738
  const channel = currentChannel.toUpperCase();
1631
1739
  if ([constants.EMAIL, constants.MOBILE_PUSH, constants.INAPP].includes(channel) && (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate')) {
1632
1740
  const name = get(formData, 'template-name');
1741
+
1742
+ const isModeSelectionStep = templateStep === 'modeSelection' || this.creativesTemplateSteps[templateStep] === 'modeSelection';
1743
+ const isCreateMode = slidBoxContent === 'createTemplate';
1744
+ if (isCreateMode && isModeSelectionStep) {
1745
+ return;
1746
+ }
1633
1747
  if (channel === constants.EMAIL && !name && slidBoxContent === 'createTemplate') {
1634
1748
  this.setState({ isTemplateNameEmpty: true });
1635
1749
  }
@@ -1637,9 +1751,9 @@ export class Creatives extends React.Component {
1637
1751
  if (name && !isEditName) {
1638
1752
  this.setState({ showTemplateNameComponentEdit: false });
1639
1753
  } else if (isEditName) {
1640
- this.setState({
1754
+ this.setState({
1641
1755
  showTemplateNameComponentEdit: true,
1642
- localTemplateName: name || '' // Initialize local state with current value
1756
+ localTemplateName: name || '', // Initialize local state with current value
1643
1757
  });
1644
1758
  }
1645
1759
  }
@@ -1653,15 +1767,31 @@ export class Creatives extends React.Component {
1653
1767
  });
1654
1768
  }
1655
1769
 
1770
+ // Callback to update HTML Editor validation state (called from EmailWrapper)
1771
+ updateHtmlEditorValidationState = (validationState) => {
1772
+ this.setState({
1773
+ htmlEditorValidationState: validationState,
1774
+ });
1775
+ }
1776
+
1656
1777
  shouldShowContinueFooter = () => { // only for email for now, has to be modified according to channel
1657
1778
  const {
1658
- slidBoxContent, templateStep, currentChannel, emailCreateMode, mobilePushCreateMode, inAppCreateMode, weChatTemplateType,
1779
+ slidBoxContent, templateStep, currentChannel, emailCreateMode, mobilePushCreateMode, inAppEditorType, weChatTemplateType,
1659
1780
  } = this.state;
1660
1781
  let isShowContinueFooter = false;
1661
1782
  const currentStep = this.creativesTemplateSteps[templateStep];
1662
1783
  const channel = currentChannel.toUpperCase();
1784
+ // Check if supportCKEditor is false (new flow)
1785
+ const supportCKEditor = commonUtil.hasSupportCKEditor(); // Default to legacy flow
1663
1786
  if (channel === constants.EMAIL || channel === constants.SMS) {
1664
- if ((emailCreateMode === "upload" && !isEmpty(this.props.EmailLayout)) || emailCreateMode === "editor") {
1787
+ // New flow: Show Continue button when supportCKEditor is false and in modeSelection
1788
+ // Always show it (even if disabled) - visibility is separate from enabled state
1789
+ if (!supportCKEditor && currentStep === 'modeSelection' && slidBoxContent === 'createTemplate') {
1790
+ return true; // Return early to ensure visibility
1791
+ }
1792
+
1793
+ // Legacy flow: Original logic (only when supportCKEditor is true)
1794
+ if (supportCKEditor && ((emailCreateMode === "upload" && !isEmpty(this.props.EmailLayout)) || emailCreateMode === "editor")) {
1665
1795
  let isEmailCreate = slidBoxContent === 'createTemplate';
1666
1796
  isEmailCreate = currentChannel.toUpperCase() === constants.EMAIL && ((emailCreateMode === "upload" && currentStep !== 'createTemplateContent') || (emailCreateMode === "editor" && currentStep !== 'createTemplateContent' && currentStep !== "templateSelection"));
1667
1797
  isShowContinueFooter = isEmailCreate && emailCreateMode;
@@ -1670,8 +1800,6 @@ export class Creatives extends React.Component {
1670
1800
  isShowContinueFooter = !isEmpty(mobilePushCreateMode) && currentStep === "modeSelection";
1671
1801
  } else if (currentChannel.toUpperCase() === constants.WECHAT) {
1672
1802
  isShowContinueFooter = !isEmpty(weChatTemplateType) && currentStep === "modeSelection";
1673
- } else if (currentChannel.toUpperCase() === constants.INAPP) {
1674
- isShowContinueFooter = !isEmpty(inAppCreateMode) && currentChannel === "modeSelection";
1675
1803
  }
1676
1804
 
1677
1805
  return isShowContinueFooter;
@@ -1697,6 +1825,28 @@ export class Creatives extends React.Component {
1697
1825
  return true;
1698
1826
  }
1699
1827
 
1828
+ // Check if Continue button should be disabled (for new flow only)
1829
+ isContinueButtonDisabled = () => {
1830
+ const { currentChannel, emailCreateMode, templateNameExists } = this.state;
1831
+ const { isFullMode } = this.props;
1832
+ const supportCKEditor = commonUtil.hasSupportCKEditor();
1833
+ if (supportCKEditor) {
1834
+ return false;
1835
+ }
1836
+ if (currentChannel.toUpperCase() === constants.EMAIL) {
1837
+ const isEditorSelected = !!emailCreateMode && emailCreateMode !== 'upload';
1838
+ // In full mode: require both template name AND editor selection
1839
+ // In library mode: require only editor selection (template name not needed)
1840
+ if (isFullMode) {
1841
+ const isTemplateNameValid = templateNameExists;
1842
+ return !(isTemplateNameValid && isEditorSelected);
1843
+ }
1844
+ // Library mode: only editor selection is required
1845
+ return !isEditorSelected;
1846
+ }
1847
+ return true;
1848
+ }
1849
+
1700
1850
  render() {
1701
1851
  const {
1702
1852
  slidBoxContent,
@@ -1705,6 +1855,7 @@ export class Creatives extends React.Component {
1705
1855
  templateData,
1706
1856
  currentChannel,
1707
1857
  emailCreateMode,
1858
+ selectedEmailCreateMode,
1708
1859
  templateStep,
1709
1860
  isLoadingContent,
1710
1861
  mobilePushCreateMode,
@@ -1717,6 +1868,8 @@ export class Creatives extends React.Component {
1717
1868
  activeFormBuilderTab,
1718
1869
  showTestAndPreviewSlidebox,
1719
1870
  isTestAndPreviewMode,
1871
+ inAppEditorType,
1872
+ htmlEditorValidationState,
1720
1873
  } = this.state;
1721
1874
  const {
1722
1875
  isFullMode,
@@ -1739,9 +1892,35 @@ export class Creatives extends React.Component {
1739
1892
  isLoyaltyModule,
1740
1893
  loyaltyMetaData = {},
1741
1894
  } = this.props;
1895
+ // Compute Continue button label
1896
+ const supportCKEditor = commonUtil.hasSupportCKEditor();
1897
+ const continueButtonLabel = supportCKEditor ? messages.continue : messages.next;
1898
+
1742
1899
  const mapTemplateCreate = slidBoxContent === "createTemplate"
1743
1900
  && weChatTemplateType === MAP_TEMPLATE
1744
1901
  && templateStep !== "modeSelection";
1902
+
1903
+ // Determine if we're in HTML Editor mode (where errors are shown in ValidationErrorDisplay, not ErrorInfoNote in footer)
1904
+ const isEmailChannel = currentChannel?.toUpperCase() === constants.EMAIL;
1905
+ const isEditMode = slidBoxContent === 'editTemplate';
1906
+ const isHTMLEditorModeInCreate = selectedEmailCreateMode === 'html_editor';
1907
+ const isHTMLEditorModeInEdit = isEditMode && htmlEditorValidationState != null;
1908
+ const isHTMLEditorMode = isEmailChannel && (isHTMLEditorModeInCreate || isHTMLEditorModeInEdit);
1909
+ const isBEEEditor = selectedEmailCreateMode === 'drag_drop'
1910
+ || (emailCreateMode === 'editor' && !isHTMLEditorMode);
1911
+
1912
+ // Check for BEE editor errors (same logic as SlideBoxFooter)
1913
+ const hasStandardErrors = liquidErrorMessage && liquidErrorMessage.STANDARD_ERROR_MSG && liquidErrorMessage.STANDARD_ERROR_MSG.length > 0;
1914
+ const hasLiquidErrors = liquidErrorMessage && liquidErrorMessage.LIQUID_ERROR_MSG && liquidErrorMessage.LIQUID_ERROR_MSG.length > 0;
1915
+ const htmlEditorHasErrors = htmlEditorValidationState && htmlEditorValidationState.issueCounts && htmlEditorValidationState.issueCounts.total > 0;
1916
+ const hasBEEEditorErrors = isEmailChannel && (hasStandardErrors || hasLiquidErrors) && (!htmlEditorValidationState || !htmlEditorHasErrors);
1917
+
1918
+ // Only apply margin to footer when ErrorInfoNote is shown in footer (BEE editor)
1919
+ // For HTML Editor, errors are shown in ValidationErrorDisplay (inside content area), so no footer margin needed
1920
+ // IMPORTANT: Never show ErrorInfoNote in footer when in HTML Editor mode, even if liquidErrorMessage exists
1921
+ const shouldShowErrorInfoNoteInFooter = isHTMLEditorMode ? false : hasBEEEditorErrors;
1922
+
1923
+ // Calculate margin for header/content (always apply if there are errors, regardless of editor type)
1745
1924
  const slideBoxWrapperMargin = (get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0 && get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0)
1746
1925
  ? CAP_SPACE_64
1747
1926
  : get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0
@@ -1751,7 +1930,11 @@ export class Creatives extends React.Component {
1751
1930
  : 0;
1752
1931
  /* TODO: Instead of passing down same props separately to each component down, write common function to these props and pass it accordingly */
1753
1932
  return (
1754
- <SlideBoxWrapper slideBoxWrapperMargin={slideBoxWrapperMargin} className={classnames(`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`)}>
1933
+ <SlideBoxWrapper
1934
+ slideBoxWrapperMargin={slideBoxWrapperMargin}
1935
+ shouldApplyFooterMargin={shouldShowErrorInfoNoteInFooter}
1936
+ className={classnames(`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`)}
1937
+ >
1755
1938
  <CapSlideBox
1756
1939
  header={
1757
1940
  this.shouldShowHeader() && (
@@ -1800,6 +1983,8 @@ export class Creatives extends React.Component {
1800
1983
  onChannelChange={this.onChannelChange}
1801
1984
  onEmailModeChange={this.onEmailModeChange}//used when create is clicked in email
1802
1985
  emailCreateMode={emailCreateMode}// upload zip || use editor are values
1986
+ onInAppEditorTypeChange={this.onInAppEditorTypeChange}//used when create is clicked in inapp
1987
+ inAppEditorType={inAppEditorType}// htmlEditor || dragDropEditor are values
1803
1988
  templateStep={this.creativesTemplateSteps[templateStep]}
1804
1989
  onCreateNextStep={this.onCreateNextStep}
1805
1990
  onEnterTemplateName={this.onEnterTemplateName}
@@ -1809,6 +1994,8 @@ export class Creatives extends React.Component {
1809
1994
  cap={cap}
1810
1995
  setIsLoadingContent={this.setIsLoadingContent}
1811
1996
  onMobilepushModeChange={this.onMobilepushModeChange}
1997
+ inAppCreateMode={this.state.inAppCreateMode}
1998
+ onInAppModeChange={this.onInAppModeChange}
1812
1999
  mobilePushCreateMode={mobilePushCreateMode}
1813
2000
  showTemplateName={this.showTemplateName}
1814
2001
  onValidationFail={this.onValidationFail}
@@ -1847,6 +2034,7 @@ export class Creatives extends React.Component {
1847
2034
  handleTestAndPreview={this.handleTestAndPreview}
1848
2035
  handleCloseTestAndPreview={this.handleCloseTestAndPreview}
1849
2036
  isTestAndPreviewMode={(() => this.state.isTestAndPreviewMode)()}
2037
+ onHtmlEditorValidationStateChange={this.updateHtmlEditorValidationState}
1850
2038
  />
1851
2039
  )}
1852
2040
  footer={this.shouldShowFooter() ? (
@@ -1861,6 +2049,7 @@ export class Creatives extends React.Component {
1861
2049
  currentChannel={currentChannel.toUpperCase()}
1862
2050
  templateStep={this.creativesTemplateSteps[templateStep]}
1863
2051
  emailCreateMode={emailCreateMode}
2052
+ selectedEmailCreateMode={selectedEmailCreateMode}
1864
2053
  shouldShowContinueFooter={this.shouldShowContinueFooter}
1865
2054
  shouldShowDoneFooter={this.shouldShowDoneFooter}
1866
2055
  fetchingCmsData={fetchingCmsData}
@@ -1869,18 +2058,22 @@ export class Creatives extends React.Component {
1869
2058
  errorMessages={liquidErrorMessage}
1870
2059
  currentTab={activeFormBuilderTab}
1871
2060
  onTestAndPreview={this.handleTestAndPreview}
2061
+ isContinueButtonDisabled={this.isContinueButtonDisabled()}
2062
+ continueButtonLabel={continueButtonLabel}
1872
2063
  showTestAndPreviewButton={(() => {
1873
2064
  const isEmailOrSmsOrWhatsappOrRcsOrInAppOrMobilePush = [constants.EMAIL, constants.SMS, constants.WHATSAPP, constants.RCS, constants.INAPP, constants.MOBILE_PUSH, constants.VIBER, constants.ZALO].includes(currentChannel.toUpperCase());
1874
2065
  const showButton = isEmailOrSmsOrWhatsappOrRcsOrInAppOrMobilePush && (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate');
1875
2066
  return showButton;
1876
2067
  })()}
2068
+ htmlEditorValidationState={htmlEditorValidationState}
2069
+ isCreatingTemplate={slidBoxContent === 'createTemplate' && currentChannel.toUpperCase() === constants.EMAIL}
1877
2070
  />
1878
2071
  ) : isLiquidValidationError && (
1879
2072
  <CapRow className="template-footer-width">
1880
2073
  {(() => {
1881
2074
  const errorsToShow = get(liquidErrorMessage, constants.LIQUID_ERROR_MSG, []);
1882
2075
  const standardErrorsToShow = get(liquidErrorMessage, constants.STANDARD_ERROR_MSG, []);
1883
- return <ErrorInfoNote currentTab={activeFormBuilderTab?.toUpperCase()} errorMessages={{LIQUID_ERROR_MSG: errorsToShow, STANDARD_ERROR_MSG: standardErrorsToShow}} />;
2076
+ return <ErrorInfoNote currentTab={activeFormBuilderTab?.toUpperCase()} errorMessages={{ LIQUID_ERROR_MSG: errorsToShow, STANDARD_ERROR_MSG: standardErrorsToShow }} />;
1884
2077
  })()}
1885
2078
  </CapRow>
1886
2079
  )}
@@ -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`,
@@ -370,4 +374,8 @@ export default defineMessages({
370
374
  id: `${scope}.testAndPreview`,
371
375
  defaultMessage: `Preview and Test`,
372
376
  },
377
+ "next": {
378
+ id: `${scope}.next`,
379
+ defaultMessage: `Next`,
380
+ },
373
381
  });
@@ -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();