@capillarytech/creatives-library 8.0.255-alpha.4 → 8.0.255

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 (278) hide show
  1. package/assets/Android.png +0 -0
  2. package/assets/iOS.png +0 -0
  3. package/constants/unified.js +2 -2
  4. package/initialReducer.js +2 -0
  5. package/package.json +1 -1
  6. package/services/api.js +10 -5
  7. package/services/tests/api.test.js +34 -0
  8. package/translations/en.json +3 -4
  9. package/utils/common.js +5 -6
  10. package/utils/commonUtils.js +28 -5
  11. package/utils/tests/commonUtil.test.js +224 -0
  12. package/utils/tests/transformerUtils.test.js +0 -297
  13. package/utils/transformTemplateConfig.js +0 -10
  14. package/utils/transformerUtils.js +0 -40
  15. package/v2Components/CapDeviceContent/index.js +61 -56
  16. package/v2Components/CapImageUpload/constants.js +0 -2
  17. package/v2Components/CapImageUpload/index.js +16 -65
  18. package/v2Components/CapImageUpload/index.scss +1 -4
  19. package/v2Components/CapImageUpload/messages.js +1 -5
  20. package/v2Components/CapTagList/index.js +6 -1
  21. package/v2Components/CapTagListWithInput/index.js +5 -1
  22. package/v2Components/CapTagListWithInput/messages.js +1 -1
  23. package/v2Components/CapWhatsappCTA/tests/index.test.js +5 -0
  24. package/v2Components/ErrorInfoNote/constants.js +1 -0
  25. package/v2Components/ErrorInfoNote/index.js +457 -72
  26. package/v2Components/ErrorInfoNote/messages.js +36 -6
  27. package/v2Components/ErrorInfoNote/style.scss +282 -6
  28. package/v2Components/FormBuilder/tests/index.test.js +13 -4
  29. package/v2Components/HtmlEditor/HTMLEditor.js +547 -94
  30. package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +874 -0
  31. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +1441 -133
  32. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +27 -16
  33. package/v2Components/HtmlEditor/_htmlEditor.scss +108 -45
  34. package/v2Components/HtmlEditor/_index.lazy.scss +0 -1
  35. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +23 -102
  36. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +148 -140
  37. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +2 -1
  38. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
  39. package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +9 -0
  40. package/v2Components/HtmlEditor/components/EditorToolbar/index.js +4 -4
  41. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +22 -0
  42. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +4 -7
  43. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +35 -45
  44. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +1 -3
  45. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
  46. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +7 -6
  47. package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +3 -6
  48. package/v2Components/HtmlEditor/components/PreviewPane/index.js +22 -43
  49. package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
  50. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/_validationErrorDisplay.scss +1 -0
  51. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +49 -31
  52. package/v2Components/HtmlEditor/components/ValidationPanel/_validationPanel.scss +50 -34
  53. package/v2Components/HtmlEditor/components/ValidationPanel/constants.js +6 -0
  54. package/v2Components/HtmlEditor/components/ValidationPanel/index.js +70 -41
  55. package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +255 -0
  56. package/v2Components/HtmlEditor/components/ValidationTabs/index.js +364 -0
  57. package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +51 -0
  58. package/v2Components/HtmlEditor/constants.js +42 -20
  59. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +373 -16
  60. package/v2Components/HtmlEditor/hooks/__tests__/useValidation.test.js +103 -0
  61. package/v2Components/HtmlEditor/hooks/useEditorContent.js +5 -2
  62. package/v2Components/HtmlEditor/hooks/useInAppContent.js +88 -146
  63. package/v2Components/HtmlEditor/hooks/useValidation.js +189 -53
  64. package/v2Components/HtmlEditor/index.js +1 -1
  65. package/v2Components/HtmlEditor/messages.js +92 -94
  66. package/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +94 -45
  67. package/v2Components/HtmlEditor/utils/__tests__/validationAdapter.test.js +134 -0
  68. package/v2Components/HtmlEditor/utils/contentSanitizer.js +40 -41
  69. package/v2Components/HtmlEditor/utils/htmlValidator.js +71 -72
  70. package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +134 -102
  71. package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +23 -25
  72. package/v2Components/HtmlEditor/utils/validationAdapter.js +66 -41
  73. package/v2Components/HtmlEditor/utils/validationConstants.js +40 -0
  74. package/v2Components/MobilePushPreviewV2/index.js +32 -7
  75. package/v2Components/TemplatePreview/_templatePreview.scss +55 -24
  76. package/v2Components/TemplatePreview/index.js +47 -32
  77. package/v2Components/TemplatePreview/messages.js +4 -0
  78. package/v2Components/TestAndPreviewSlidebox/_testAndPreviewSlidebox.scss +1 -0
  79. package/v2Containers/App/constants.js +0 -5
  80. package/v2Containers/BeeEditor/index.js +172 -90
  81. package/v2Containers/BeePopupEditor/_beePopupEditor.scss +14 -0
  82. package/v2Containers/BeePopupEditor/constants.js +10 -0
  83. package/v2Containers/BeePopupEditor/index.js +194 -0
  84. package/v2Containers/BeePopupEditor/tests/index.test.js +627 -0
  85. package/v2Containers/Cap/tests/__snapshots__/index.test.js.snap +3 -4
  86. package/v2Containers/CreativesContainer/SlideBoxContent.js +129 -107
  87. package/v2Containers/CreativesContainer/SlideBoxFooter.js +163 -13
  88. package/v2Containers/CreativesContainer/SlideBoxHeader.js +2 -2
  89. package/v2Containers/CreativesContainer/constants.js +1 -3
  90. package/v2Containers/CreativesContainer/index.js +239 -214
  91. package/v2Containers/CreativesContainer/messages.js +8 -4
  92. package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +0 -210
  93. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +11 -2
  94. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +38 -354
  95. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +106 -0
  96. package/v2Containers/Email/actions.js +7 -0
  97. package/v2Containers/Email/constants.js +5 -1
  98. package/v2Containers/Email/index.js +234 -29
  99. package/v2Containers/Email/messages.js +32 -0
  100. package/v2Containers/Email/reducer.js +12 -1
  101. package/v2Containers/Email/sagas.js +61 -7
  102. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +2 -0
  103. package/v2Containers/Email/tests/reducer.test.js +46 -0
  104. package/v2Containers/Email/tests/sagas.test.js +320 -29
  105. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +1285 -0
  106. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +211 -21
  107. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +40 -74
  108. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +1880 -0
  109. package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +520 -0
  110. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +2 -67
  111. package/v2Containers/EmailWrapper/constants.js +2 -0
  112. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +629 -77
  113. package/v2Containers/EmailWrapper/index.js +103 -23
  114. package/v2Containers/EmailWrapper/messages.js +65 -1
  115. package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +643 -0
  116. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +594 -77
  117. package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +376 -0
  118. package/v2Containers/InApp/__tests__/sagas.test.js +363 -0
  119. package/v2Containers/InApp/actions.js +7 -0
  120. package/v2Containers/InApp/constants.js +20 -4
  121. package/v2Containers/InApp/index.js +802 -359
  122. package/v2Containers/InApp/index.scss +4 -3
  123. package/v2Containers/InApp/messages.js +7 -3
  124. package/v2Containers/InApp/reducer.js +21 -3
  125. package/v2Containers/InApp/sagas.js +29 -9
  126. package/v2Containers/InApp/selectors.js +25 -5
  127. package/v2Containers/InApp/tests/index.test.js +154 -50
  128. package/v2Containers/InApp/tests/reducer.test.js +34 -0
  129. package/v2Containers/InApp/tests/sagas.test.js +61 -9
  130. package/v2Containers/InApp/tests/selectors.test.js +612 -0
  131. package/v2Containers/InAppWrapper/components/InAppWrapperView.js +151 -0
  132. package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +267 -0
  133. package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +23 -0
  134. package/v2Containers/InAppWrapper/constants.js +16 -0
  135. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +473 -0
  136. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +198 -0
  137. package/v2Containers/InAppWrapper/index.js +148 -0
  138. package/v2Containers/InAppWrapper/messages.js +49 -0
  139. package/v2Containers/InappAdvance/index.js +1099 -0
  140. package/v2Containers/InappAdvance/index.scss +10 -0
  141. package/v2Containers/InappAdvance/tests/index.test.js +448 -0
  142. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +15 -36
  143. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +8 -8
  144. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +77 -100
  145. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +63 -72
  146. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +190 -250
  147. package/v2Containers/SmsTrai/Create/tests/__snapshots__/index.test.js.snap +12 -16
  148. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +40 -48
  149. package/v2Containers/TagList/index.js +62 -19
  150. package/v2Containers/Templates/ChannelTypeIllustration.js +1 -13
  151. package/v2Containers/Templates/_templates.scss +56 -202
  152. package/v2Containers/Templates/actions.js +1 -2
  153. package/v2Containers/Templates/constants.js +0 -1
  154. package/v2Containers/Templates/index.js +123 -278
  155. package/v2Containers/Templates/messages.js +4 -24
  156. package/v2Containers/Templates/reducer.js +0 -2
  157. package/v2Containers/Templates/tests/index.test.js +0 -10
  158. package/v2Containers/TemplatesV2/index.js +7 -15
  159. package/v2Containers/TemplatesV2/messages.js +0 -4
  160. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +768 -1272
  161. package/utils/imageUrlUpload.js +0 -141
  162. package/v2Components/CapImageUrlUpload/constants.js +0 -26
  163. package/v2Components/CapImageUrlUpload/index.js +0 -365
  164. package/v2Components/CapImageUrlUpload/index.scss +0 -35
  165. package/v2Components/CapImageUrlUpload/messages.js +0 -47
  166. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +0 -152
  167. package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +0 -214
  168. package/v2Containers/WebPush/Create/components/BrandIconSection.js +0 -108
  169. package/v2Containers/WebPush/Create/components/ButtonForm.js +0 -172
  170. package/v2Containers/WebPush/Create/components/ButtonItem.js +0 -101
  171. package/v2Containers/WebPush/Create/components/ButtonList.js +0 -145
  172. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.js +0 -164
  173. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.test.js +0 -463
  174. package/v2Containers/WebPush/Create/components/FormActions.js +0 -54
  175. package/v2Containers/WebPush/Create/components/FormActions.test.js +0 -163
  176. package/v2Containers/WebPush/Create/components/MediaSection.js +0 -142
  177. package/v2Containers/WebPush/Create/components/MediaSection.test.js +0 -341
  178. package/v2Containers/WebPush/Create/components/MessageSection.js +0 -103
  179. package/v2Containers/WebPush/Create/components/MessageSection.test.js +0 -268
  180. package/v2Containers/WebPush/Create/components/NotificationTitleSection.js +0 -87
  181. package/v2Containers/WebPush/Create/components/NotificationTitleSection.test.js +0 -210
  182. package/v2Containers/WebPush/Create/components/TemplateNameSection.js +0 -54
  183. package/v2Containers/WebPush/Create/components/TemplateNameSection.test.js +0 -143
  184. package/v2Containers/WebPush/Create/components/__snapshots__/ButtonsLinksSection.test.js.snap +0 -86
  185. package/v2Containers/WebPush/Create/components/__snapshots__/FormActions.test.js.snap +0 -16
  186. package/v2Containers/WebPush/Create/components/__snapshots__/MediaSection.test.js.snap +0 -41
  187. package/v2Containers/WebPush/Create/components/__snapshots__/MessageSection.test.js.snap +0 -54
  188. package/v2Containers/WebPush/Create/components/__snapshots__/NotificationTitleSection.test.js.snap +0 -37
  189. package/v2Containers/WebPush/Create/components/__snapshots__/TemplateNameSection.test.js.snap +0 -21
  190. package/v2Containers/WebPush/Create/components/_buttons.scss +0 -246
  191. package/v2Containers/WebPush/Create/components/tests/ButtonForm.test.js +0 -554
  192. package/v2Containers/WebPush/Create/components/tests/ButtonItem.test.js +0 -607
  193. package/v2Containers/WebPush/Create/components/tests/ButtonList.test.js +0 -633
  194. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonForm.test.js.snap +0 -666
  195. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonItem.test.js.snap +0 -74
  196. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonList.test.js.snap +0 -78
  197. package/v2Containers/WebPush/Create/hooks/useButtonManagement.js +0 -138
  198. package/v2Containers/WebPush/Create/hooks/useButtonManagement.test.js +0 -406
  199. package/v2Containers/WebPush/Create/hooks/useCharacterCount.js +0 -30
  200. package/v2Containers/WebPush/Create/hooks/useCharacterCount.test.js +0 -151
  201. package/v2Containers/WebPush/Create/hooks/useImageUpload.js +0 -104
  202. package/v2Containers/WebPush/Create/hooks/useImageUpload.test.js +0 -538
  203. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +0 -122
  204. package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +0 -633
  205. package/v2Containers/WebPush/Create/index.js +0 -1148
  206. package/v2Containers/WebPush/Create/index.scss +0 -134
  207. package/v2Containers/WebPush/Create/messages.js +0 -203
  208. package/v2Containers/WebPush/Create/preview/DevicePreviewContent.js +0 -228
  209. package/v2Containers/WebPush/Create/preview/NotificationContainer.js +0 -294
  210. package/v2Containers/WebPush/Create/preview/PreviewContent.js +0 -90
  211. package/v2Containers/WebPush/Create/preview/PreviewControls.js +0 -305
  212. package/v2Containers/WebPush/Create/preview/PreviewDisclaimer.js +0 -23
  213. package/v2Containers/WebPush/Create/preview/WebPushPreview.js +0 -155
  214. package/v2Containers/WebPush/Create/preview/assets/Light.svg +0 -53
  215. package/v2Containers/WebPush/Create/preview/assets/Top.svg +0 -5
  216. package/v2Containers/WebPush/Create/preview/assets/android-arrow-down.svg +0 -9
  217. package/v2Containers/WebPush/Create/preview/assets/android-arrow-up.svg +0 -9
  218. package/v2Containers/WebPush/Create/preview/assets/chrome-icon.png +0 -0
  219. package/v2Containers/WebPush/Create/preview/assets/edge-icon.png +0 -0
  220. package/v2Containers/WebPush/Create/preview/assets/firefox-icon.svg +0 -106
  221. package/v2Containers/WebPush/Create/preview/assets/iOS.svg +0 -26
  222. package/v2Containers/WebPush/Create/preview/assets/macos-arrow-down-icon.svg +0 -9
  223. package/v2Containers/WebPush/Create/preview/assets/macos-triple-dot-icon.svg +0 -9
  224. package/v2Containers/WebPush/Create/preview/assets/opera-icon.svg +0 -18
  225. package/v2Containers/WebPush/Create/preview/assets/safari-icon.svg +0 -29
  226. package/v2Containers/WebPush/Create/preview/assets/windows-close-icon.svg +0 -9
  227. package/v2Containers/WebPush/Create/preview/assets/windows-triple-dot-icon.svg +0 -9
  228. package/v2Containers/WebPush/Create/preview/components/AndroidMobileChromeHeader.js +0 -47
  229. package/v2Containers/WebPush/Create/preview/components/AndroidMobileExpanded.js +0 -141
  230. package/v2Containers/WebPush/Create/preview/components/IOSHeader.js +0 -45
  231. package/v2Containers/WebPush/Create/preview/components/NotificationExpandedContent.js +0 -68
  232. package/v2Containers/WebPush/Create/preview/components/NotificationHeader.js +0 -61
  233. package/v2Containers/WebPush/Create/preview/components/WindowsChromeExpanded.js +0 -99
  234. package/v2Containers/WebPush/Create/preview/components/tests/AndroidMobileExpanded.test.js +0 -733
  235. package/v2Containers/WebPush/Create/preview/components/tests/WindowsChromeExpanded.test.js +0 -571
  236. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/AndroidMobileExpanded.test.js.snap +0 -81
  237. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/WindowsChromeExpanded.test.js.snap +0 -81
  238. package/v2Containers/WebPush/Create/preview/config/notificationMappings.js +0 -50
  239. package/v2Containers/WebPush/Create/preview/constants.js +0 -637
  240. package/v2Containers/WebPush/Create/preview/notification-container.scss +0 -79
  241. package/v2Containers/WebPush/Create/preview/preview.scss +0 -351
  242. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-chrome.scss +0 -370
  243. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-edge.scss +0 -12
  244. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-firefox.scss +0 -12
  245. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-opera.scss +0 -12
  246. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-chrome.scss +0 -47
  247. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-edge.scss +0 -11
  248. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-firefox.scss +0 -11
  249. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-opera.scss +0 -11
  250. package/v2Containers/WebPush/Create/preview/styles/_base.scss +0 -207
  251. package/v2Containers/WebPush/Create/preview/styles/_ios.scss +0 -153
  252. package/v2Containers/WebPush/Create/preview/styles/_ipados.scss +0 -107
  253. package/v2Containers/WebPush/Create/preview/styles/_macos-chrome.scss +0 -101
  254. package/v2Containers/WebPush/Create/preview/styles/_windows-chrome.scss +0 -229
  255. package/v2Containers/WebPush/Create/preview/tests/DevicePreviewContent.test.js +0 -909
  256. package/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +0 -1081
  257. package/v2Containers/WebPush/Create/preview/tests/PreviewControls.test.js +0 -723
  258. package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +0 -1327
  259. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/DevicePreviewContent.test.js.snap +0 -131
  260. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/NotificationContainer.test.js.snap +0 -112
  261. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/PreviewControls.test.js.snap +0 -144
  262. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/WebPushPreview.test.js.snap +0 -129
  263. package/v2Containers/WebPush/Create/utils/payloadBuilder.js +0 -96
  264. package/v2Containers/WebPush/Create/utils/payloadBuilder.test.js +0 -396
  265. package/v2Containers/WebPush/Create/utils/previewUtils.js +0 -89
  266. package/v2Containers/WebPush/Create/utils/urlValidation.js +0 -115
  267. package/v2Containers/WebPush/Create/utils/urlValidation.test.js +0 -449
  268. package/v2Containers/WebPush/Create/utils/validation.js +0 -75
  269. package/v2Containers/WebPush/Create/utils/validation.test.js +0 -283
  270. package/v2Containers/WebPush/actions.js +0 -60
  271. package/v2Containers/WebPush/constants.js +0 -132
  272. package/v2Containers/WebPush/index.js +0 -2
  273. package/v2Containers/WebPush/reducer.js +0 -104
  274. package/v2Containers/WebPush/sagas.js +0 -119
  275. package/v2Containers/WebPush/selectors.js +0 -65
  276. package/v2Containers/WebPush/tests/reducer.test.js +0 -863
  277. package/v2Containers/WebPush/tests/sagas.test.js +0 -566
  278. package/v2Containers/WebPush/tests/selectors.test.js +0 -960
@@ -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';
@@ -42,9 +44,8 @@ import { makeSelectFetchingCmsData } from '../Email/selectors';
42
44
  import {
43
45
  IMAGE as LINE_IMAGE, IMAGE_MAP, IMAGE_CAROUSEL, VIDEO as LINE_VIDEO, TEMPLATE, STICKER,
44
46
  } from '../Line/Container/constants';
45
- import {EXTERNAL_URL, SITE_URL, WEBPUSH_MEDIA_TYPES} from '../WebPush/constants';
46
47
  import { IMAGE, VIDEO } from '../Facebook/Advertisement/constant';
47
- import {RCS_STATUSES} from '../Rcs/constants';
48
+ import { RCS_STATUSES } from '../Rcs/constants';
48
49
  import { CREATIVE } from '../Facebook/constants';
49
50
  import { LOYALTY } from '../App/constants';
50
51
  import {
@@ -65,19 +66,29 @@ import {
65
66
  // getTemplateDiffState
66
67
  } from "../../utils/transformerUtils";
67
68
  import { MANUAL_CAROUSEL } from '../MobilePushNew/constants';
69
+ import { BIG_HTML } from '../InApp/constants';
68
70
 
69
71
  const classPrefix = 'add-creatives-section';
70
72
  const CREATIVES_CONTAINER = 'creativesContainer';
71
73
 
72
74
  const SlideBoxWrapper = styled.div`
73
75
  .cap-slide-box-v2-container{
74
- .slidebox-header, .slidebox-content-container, .slidebox-footer{
76
+ .slidebox-header, .slidebox-content-container{
75
77
  margin-bottom: ${({ slideBoxWrapperMargin }) => `${slideBoxWrapperMargin}`};
76
78
  padding: 0 rem;
77
79
  &.has-footer{
78
80
  overflow-x: hidden;
79
81
  }
80
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
+ }
81
92
  }
82
93
  `;
83
94
  export class Creatives extends React.Component {
@@ -96,6 +107,7 @@ export class Creatives extends React.Component {
96
107
  currentChannel: this.props.channel || 'sms',
97
108
  weChatTemplateType: '',
98
109
  weChatMaptemplateStep: 0,
110
+ inAppEditorType: null,
99
111
  isLiquidValidationError: false,
100
112
  errorMessages: [],
101
113
  liquidErrorMessage: {
@@ -108,6 +120,17 @@ export class Creatives extends React.Component {
108
120
  isTestAndPreviewMode: false, // Add flag to track Test & Preview mode
109
121
  // Performance optimization: Local template name for immediate UI feedback
110
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
+ },
111
134
  };
112
135
  this.liquidFlow = Boolean(commonUtil.hasLiquidSupportFeature());
113
136
  this.creativesTemplateSteps = {
@@ -137,7 +160,7 @@ export class Creatives extends React.Component {
137
160
  if (!this.props?.isFullMode) {
138
161
  this.props?.templateActions.getCdnTransformationConfig();
139
162
  }
140
-
163
+
141
164
  // Store loyalty tag props if loyaltyTagFetchingDependencies is provided
142
165
  const { loyaltyTagFetchingDependencies } = this.props;
143
166
  if (loyaltyTagFetchingDependencies) {
@@ -163,9 +186,9 @@ export class Creatives extends React.Component {
163
186
  const isEmptyTemplateName = !value.trim();
164
187
 
165
188
  // 1. IMMEDIATE: Update local state for instant UI feedback
166
- this.setState({
189
+ this.setState({
167
190
  isTemplateNameEmpty: isEmptyTemplateName,
168
- localTemplateName: value
191
+ localTemplateName: value,
169
192
  });
170
193
 
171
194
  // 2. DEBOUNCED: Only debounce the expensive onFormDataChange call
@@ -244,8 +267,19 @@ export class Creatives extends React.Component {
244
267
  onCreateNextStep = () => {
245
268
  this.setState((prevState) => {
246
269
  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())) {
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())) {
249
283
  templateStep = prevState.templateStep + 2;
250
284
  }
251
285
  return {
@@ -254,14 +288,21 @@ export class Creatives extends React.Component {
254
288
  });
255
289
  }
256
290
 
257
- onEmailModeChange = (mode) => {
258
- 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
+ });
259
296
  }
260
297
 
261
298
  onInAppModeChange = (mode) => {
262
299
  this.setState({ inAppCreateMode: mode });
263
300
  }
264
301
 
302
+ onInAppEditorTypeChange = (editorType) => {
303
+ this.setState({ inAppEditorType: editorType });
304
+ }
305
+
265
306
  onMobilepushModeChange = (mode) => {
266
307
  this.setState({ mobilePushCreateMode: mode });
267
308
  }
@@ -305,7 +346,7 @@ export class Creatives extends React.Component {
305
346
  }
306
347
  return buttonObj;
307
348
  });
308
- const {url, previewUrl} = media || {};
349
+ const { url, previewUrl } = media || {};
309
350
  return {
310
351
  bodyText: bodyTemplate,
311
352
  varMap: cardVarMapped,
@@ -434,14 +475,35 @@ export class Creatives extends React.Component {
434
475
  }
435
476
  case constants.INAPP: {
436
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
+
437
485
  creativesTemplateData = {
438
486
  type: channel,
439
487
  name: templateData.messageSubject,
440
488
  versions: {
441
489
  base: {
442
490
  content: {
443
- ANDROID: templateData?.androidContent,
444
- 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,
445
507
  },
446
508
  },
447
509
  },
@@ -676,7 +738,7 @@ export class Creatives extends React.Component {
676
738
  } = templateData || {};
677
739
  const cardContent = (rcsContent.cardContent && rcsContent.cardContent[0]) || {};
678
740
  const Status = RCS_STATUSES.approved || '';
679
-
741
+
680
742
  creativesTemplateData = {
681
743
  type: channel,
682
744
  edit: true,
@@ -709,73 +771,6 @@ export class Creatives extends React.Component {
709
771
  };
710
772
  break;
711
773
  }
712
- case constants.WEBPUSH: {
713
- // Convert from campaign format (messageContent.content.content) to creatives format
714
- const webpushContent = get(templateData, 'content', {});
715
- const accountId = get(templateData, 'accountId');
716
- const {
717
- title,
718
- message,
719
- iconImageUrl: brandIcon = "",
720
- cta,
721
- expandableDetails
722
- } = webpushContent || {};
723
-
724
- // Map cta to onClickAction
725
- let onClickAction = null;
726
- if (cta) {
727
- if (cta?.type === EXTERNAL_URL) {
728
- onClickAction = {
729
- type: URL,
730
- url: cta?.actionLink || '',
731
- };
732
- } else {
733
- onClickAction = {
734
- type: cta?.type || SITE_URL,
735
- };
736
- }
737
- }
738
-
739
- // Map expandableDetails.ctas to ctas array
740
- let ctas = [];
741
- if (expandableDetails?.ctas && expandableDetails?.ctas?.length > 0) {
742
- ctas = expandableDetails?.ctas?.map((ctaItem) => ({
743
- actionText: ctaItem?.title || ctaItem?.actionText || '',
744
- type: URL,
745
- actionLink: ctaItem?.actionLink || '',
746
- }));
747
- }
748
-
749
- // Map expandableDetails.media to image if present
750
- let image = null;
751
- if (expandableDetails?.media && expandableDetails?.media?.length > 0) {
752
- const firstMedia = expandableDetails?.media[0];
753
- if (firstMedia?.type === WEBPUSH_MEDIA_TYPES.IMAGE && firstMedia?.url) {
754
- image = firstMedia?.url;
755
- }
756
- }
757
-
758
- creativesTemplateData = {
759
- type: channel,
760
- name: templateData?.messageSubject,
761
- versions: {
762
- base: {
763
- content: {
764
- webpush: {
765
- title: title || '',
766
- message: message || '',
767
- ...(brandIcon && { brandIcon }),
768
- ...(onClickAction && { onClickAction }),
769
- ...(ctas.length > 0 && { ctas }),
770
- ...(image && { image, mediaType: IMAGE }),
771
- },
772
- },
773
- },
774
- },
775
- definition: { accountId },
776
- };
777
- break;
778
- }
779
774
  default:
780
775
  break;
781
776
  }
@@ -828,7 +823,7 @@ export class Creatives extends React.Component {
828
823
  });
829
824
 
830
825
  getMobilePushCarouselData = (expandableDetails = []) => {
831
- const newExpandableDetails = {...expandableDetails};
826
+ const newExpandableDetails = { ...expandableDetails };
832
827
  newExpandableDetails.style = expandableDetails.style || MANUAL_CAROUSEL;
833
828
  newExpandableDetails.message = expandableDetails.message || '';
834
829
  newExpandableDetails.ctas = expandableDetails.ctas || [];
@@ -923,11 +918,24 @@ export class Creatives extends React.Component {
923
918
  androidContent.custom = custom;
924
919
  }
925
920
  if (channel === constants.MOBILE_PUSH && androidContent?.expandableDetails?.carouselData?.length) {
926
- 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;
927
938
  }
928
- templateData.androidContent = androidContent;
929
- templateData.androidContent.type = androidContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || constants.TEXT;
930
- templateData.androidContent.deviceType = constants.ANDROID;
931
939
  }
932
940
  const iosContent = channel === constants.INAPP ? get(channelTemplate, 'versions.base.content.IOS') : get(channelTemplate, 'versions.base.IOS');
933
941
  if (!isEmpty(iosContent)) {
@@ -945,11 +953,24 @@ export class Creatives extends React.Component {
945
953
  iosContent.custom = custom;
946
954
  }
947
955
  if (channel === constants.MOBILE_PUSH && iosContent?.expandableDetails?.carouselData?.length) {
948
- 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;
949
973
  }
950
- templateData.iosContent = iosContent;
951
- templateData.iosContent.type = iosContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || 'TEXT';
952
- templateData.iosContent.deviceType = constants.IOS;
953
974
  }
954
975
  templateData.messageSubject = channelTemplate?.name ? channelTemplate?.name : "messageSubject";
955
976
  }
@@ -1164,7 +1185,7 @@ export class Creatives extends React.Component {
1164
1185
  contentType = "",
1165
1186
  cardType = "",
1166
1187
  cardSettings = {},
1167
- } = get(versions, 'base.content.RCS.rcsContent',{});
1188
+ } = get(versions, 'base.content.RCS.rcsContent', {});
1168
1189
  const rcsContent = {
1169
1190
  contentType,
1170
1191
  cardType,
@@ -1190,105 +1211,6 @@ export class Creatives extends React.Component {
1190
1211
  }
1191
1212
  }
1192
1213
  break;
1193
- case constants.WEBPUSH: {
1194
- if (template.value) {
1195
- const channelTemplate = template.value;
1196
- const accountId = get(channelTemplate, 'definition.accountId');
1197
- const webpushContent = get(channelTemplate, 'versions.base.content.webpush', {});
1198
- const {
1199
- title,
1200
- message,
1201
- brandIcon,
1202
- iconImageUrl: templateImageUrl ,
1203
- onClickAction,
1204
- ctas: templateCtas,
1205
- cta: templateCta,
1206
- expandableDetails: templateExpandableDetails,
1207
- image
1208
- } = webpushContent || {};
1209
-
1210
- const iconImageUrl = brandIcon || templateImageUrl || '';
1211
-
1212
- // Map onClickAction to cta
1213
- let cta = null;
1214
- if (onClickAction) {
1215
- if (onClickAction?.type === URL) {
1216
- cta = {
1217
- type: EXTERNAL_URL,
1218
- actionLink: onClickAction?.url || '',
1219
- };
1220
- } else {
1221
- cta = {
1222
- type: onClickAction?.type || SITE_URL,
1223
- actionLink: onClickAction?.url || '',
1224
- };
1225
- }
1226
- } else if (templateCta) {
1227
- // Fallback to cta if onClickAction is not present
1228
- cta = {
1229
- type: templateCta?.type || EXTERNAL_URL,
1230
- actionLink: templateCta?.actionLink || '',
1231
- };
1232
- }
1233
-
1234
- // Map ctas array to expandableDetails.ctas
1235
- let expandableDetails = null;
1236
- const hasCtas = templateCtas && templateCtas.length > 0;
1237
- const hasImage = image;
1238
-
1239
- if (hasCtas || hasImage) {
1240
- expandableDetails = {
1241
- media: [],
1242
- ctas: [],
1243
- };
1244
-
1245
- // Map image to expandableDetails.media
1246
- if (hasImage) {
1247
- expandableDetails.media = [{
1248
- url: image,
1249
- type: IMAGE,
1250
- }];
1251
- }
1252
-
1253
- // Map ctas array to expandableDetails.ctas
1254
- if (hasCtas) {
1255
- expandableDetails.ctas = templateCtas.map((ctaItem) => ({
1256
- type: ctaItem?.type === URL ? EXTERNAL_URL : ctaItem?.type,
1257
- action: ctaItem?.action || '',
1258
- title: ctaItem?.actionText || ctaItem?.title || '',
1259
- actionLink: ctaItem?.actionLink || '',
1260
- }));
1261
- }
1262
- } else if (templateExpandableDetails) {
1263
- // If expandableDetails already exists, use it
1264
- expandableDetails = {
1265
- media: templateExpandableDetails?.media || [],
1266
- ctas: templateExpandableDetails?.ctas || [],
1267
- };
1268
- }
1269
-
1270
- // Convert from creatives format to campaign format
1271
- templateData = {
1272
- channel,
1273
- messageContent: {
1274
- content: {
1275
- channel: constants.WEBPUSH,
1276
- accountId,
1277
- content: {
1278
- title: title || '',
1279
- message: message || '',
1280
- ...(iconImageUrl && { iconImageUrl }),
1281
- ...(cta && { cta }),
1282
- ...(expandableDetails && { expandableDetails }),
1283
- },
1284
- messageSubject: channelTemplate?.name ? channelTemplate.name : 'messageSubject',
1285
- offers: [],
1286
- },
1287
- },
1288
- };
1289
- }
1290
- break;
1291
- }
1292
1214
  default:
1293
1215
  break;
1294
1216
  }
@@ -1340,7 +1262,6 @@ export class Creatives extends React.Component {
1340
1262
  case constants.SMS:
1341
1263
  case constants.WECHAT:
1342
1264
  case constants.VIBER:
1343
- case constants.WEBPUSH:
1344
1265
  break;
1345
1266
  case constants.EMAIL:
1346
1267
  gtmDetails = {
@@ -1402,7 +1323,7 @@ export class Creatives extends React.Component {
1402
1323
  processCentralCommsMetaId = (channel, creativesData) => {
1403
1324
  // Create the payload for the centralcommnsmetaId API call
1404
1325
  const { isLoyaltyModule = false, loyaltyMetaData = {} } = this.props;
1405
- const { actionName, setMetaData = () => {} } = loyaltyMetaData;
1326
+ const { actionName, setMetaData = () => { } } = loyaltyMetaData;
1406
1327
 
1407
1328
  // const isTemplateModified = getTemplateDiffState(
1408
1329
  // channel,
@@ -1452,6 +1373,9 @@ export class Creatives extends React.Component {
1452
1373
  if (prevState.currentChannel.toUpperCase() === constants.EMAIL) {
1453
1374
  newState = { ...newState, emailCreateMode: null };
1454
1375
  }
1376
+ if (prevState.currentChannel.toUpperCase() === constants.INAPP) {
1377
+ newState = { ...newState, inAppEditorType: null };
1378
+ }
1455
1379
  return newState;
1456
1380
  });
1457
1381
  }
@@ -1497,7 +1421,7 @@ export class Creatives extends React.Component {
1497
1421
  shouldShowFooter = () => {
1498
1422
  const { isFullMode } = this.props;
1499
1423
  const {
1500
- slidBoxContent, currentChannel, emailCreateMode, templateNameExists, templateStep, mobilePushCreateMode, weChatTemplateType, templateData,
1424
+ slidBoxContent, currentChannel, emailCreateMode, templateNameExists, templateStep, mobilePushCreateMode, weChatTemplateType, templateData, inAppCreateMode,
1501
1425
  } = this.state;
1502
1426
  const channel = currentChannel.toUpperCase();
1503
1427
  const currentStep = this.creativesTemplateSteps[templateStep];
@@ -1505,6 +1429,13 @@ export class Creatives extends React.Component {
1505
1429
  showFooter = isFullMode && slidBoxContent === "preview";
1506
1430
  const isMobilepush = channel === constants.MOBILE_PUSH;
1507
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
+ }
1508
1439
 
1509
1440
  if (!isFullMode) {
1510
1441
  const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
@@ -1540,6 +1471,7 @@ export class Creatives extends React.Component {
1540
1471
  showFooter = true;
1541
1472
  }
1542
1473
 
1474
+
1543
1475
  if (showFooter) {
1544
1476
  if (slidBoxContent === "createTemplate" && ((channel === constants.EMAIL && currentStep === 'createTemplateContent')
1545
1477
  || ([constants.SMS, constants.WECHAT].includes(channel) && currentStep === 'modeSelection'))) {
@@ -1562,7 +1494,7 @@ export class Creatives extends React.Component {
1562
1494
 
1563
1495
  shouldShowDoneFooter = () => {
1564
1496
  const {
1565
- slidBoxContent, templateStep, currentChannel, templateData,
1497
+ slidBoxContent, templateStep, currentChannel, templateData, inAppCreateMode,
1566
1498
  } = this.state;
1567
1499
  const { isFullMode } = this.props;
1568
1500
  const currentStep = this.creativesTemplateSteps[templateStep];
@@ -1570,10 +1502,17 @@ export class Creatives extends React.Component {
1570
1502
  const channelName = !isFullMode && templateData ? templateData.type : currentChannel;
1571
1503
  const channel = channelName?.toUpperCase();
1572
1504
 
1573
-
1505
+ // Check supportCKEditor flag for new HTML editor flow
1506
+ const supportCKEditor = commonUtil.hasSupportCKEditor();
1574
1507
  if (channel === constants.EMAIL || channel === constants.SMS) {
1575
1508
  const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
1576
- 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
+ }
1577
1516
  } else if ([constants.WECHAT, constants.MOBILE_PUSH].includes(channel)) {
1578
1517
  showDone = currentStep === "createTemplateContent" || slidBoxContent === "editTemplate";
1579
1518
 
@@ -1583,7 +1522,6 @@ export class Creatives extends React.Component {
1583
1522
  }
1584
1523
  }
1585
1524
 
1586
-
1587
1525
  return showDone;
1588
1526
  }
1589
1527
 
@@ -1603,18 +1541,18 @@ export class Creatives extends React.Component {
1603
1541
  templateNameComponentInput = ({ formData, onFormDataChange, name }) => {
1604
1542
  // Use local state for immediate UI feedback, fallback to prop value
1605
1543
  const displayValue = this.state.localTemplateName !== '' ? this.state.localTemplateName : name;
1606
-
1544
+
1607
1545
  return (
1608
1546
  <CapInput
1609
1547
  value={displayValue}
1610
1548
  suffix={<span />}
1611
- onBlur={() => {
1612
- this.setState({
1549
+ onBlur={() => {
1550
+ this.setState({
1613
1551
  isEditName: false,
1614
- localTemplateName: '' // Clear local state on blur
1615
- }, () => {
1616
- this.showTemplateName({ formData, onFormDataChange });
1617
- });
1552
+ localTemplateName: '', // Clear local state on blur
1553
+ }, () => {
1554
+ this.showTemplateName({ formData, onFormDataChange });
1555
+ });
1618
1556
  }}
1619
1557
  onChange={(ev) => {
1620
1558
  const { value } = ev.currentTarget;
@@ -1626,10 +1564,18 @@ export class Creatives extends React.Component {
1626
1564
  }
1627
1565
 
1628
1566
  showTemplateName = ({ formData, onFormDataChange }) => { //gets called from email/index after template data is fetched
1629
- const { slidBoxContent, currentChannel, isEditName } = this.state;
1567
+ const {
1568
+ slidBoxContent, currentChannel, isEditName, templateStep,
1569
+ } = this.state;
1630
1570
  const channel = currentChannel.toUpperCase();
1631
1571
  if ([constants.EMAIL, constants.MOBILE_PUSH, constants.INAPP].includes(channel) && (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate')) {
1632
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
+ }
1633
1579
  if (channel === constants.EMAIL && !name && slidBoxContent === 'createTemplate') {
1634
1580
  this.setState({ isTemplateNameEmpty: true });
1635
1581
  }
@@ -1637,9 +1583,9 @@ export class Creatives extends React.Component {
1637
1583
  if (name && !isEditName) {
1638
1584
  this.setState({ showTemplateNameComponentEdit: false });
1639
1585
  } else if (isEditName) {
1640
- this.setState({
1586
+ this.setState({
1641
1587
  showTemplateNameComponentEdit: true,
1642
- localTemplateName: name || '' // Initialize local state with current value
1588
+ localTemplateName: name || '', // Initialize local state with current value
1643
1589
  });
1644
1590
  }
1645
1591
  }
@@ -1653,15 +1599,31 @@ export class Creatives extends React.Component {
1653
1599
  });
1654
1600
  }
1655
1601
 
1602
+ // Callback to update HTML Editor validation state (called from EmailWrapper)
1603
+ updateHtmlEditorValidationState = (validationState) => {
1604
+ this.setState({
1605
+ htmlEditorValidationState: validationState,
1606
+ });
1607
+ }
1608
+
1656
1609
  shouldShowContinueFooter = () => { // only for email for now, has to be modified according to channel
1657
1610
  const {
1658
- slidBoxContent, templateStep, currentChannel, emailCreateMode, mobilePushCreateMode, inAppCreateMode, weChatTemplateType,
1611
+ slidBoxContent, templateStep, currentChannel, emailCreateMode, mobilePushCreateMode, inAppEditorType, weChatTemplateType,
1659
1612
  } = this.state;
1660
1613
  let isShowContinueFooter = false;
1661
1614
  const currentStep = this.creativesTemplateSteps[templateStep];
1662
1615
  const channel = currentChannel.toUpperCase();
1616
+ // Check if supportCKEditor is false (new flow)
1617
+ const supportCKEditor = commonUtil.hasSupportCKEditor(); // Default to legacy flow
1663
1618
  if (channel === constants.EMAIL || channel === constants.SMS) {
1664
- 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")) {
1665
1627
  let isEmailCreate = slidBoxContent === 'createTemplate';
1666
1628
  isEmailCreate = currentChannel.toUpperCase() === constants.EMAIL && ((emailCreateMode === "upload" && currentStep !== 'createTemplateContent') || (emailCreateMode === "editor" && currentStep !== 'createTemplateContent' && currentStep !== "templateSelection"));
1667
1629
  isShowContinueFooter = isEmailCreate && emailCreateMode;
@@ -1670,8 +1632,6 @@ export class Creatives extends React.Component {
1670
1632
  isShowContinueFooter = !isEmpty(mobilePushCreateMode) && currentStep === "modeSelection";
1671
1633
  } else if (currentChannel.toUpperCase() === constants.WECHAT) {
1672
1634
  isShowContinueFooter = !isEmpty(weChatTemplateType) && currentStep === "modeSelection";
1673
- } else if (currentChannel.toUpperCase() === constants.INAPP) {
1674
- isShowContinueFooter = !isEmpty(inAppCreateMode) && currentChannel === "modeSelection";
1675
1635
  }
1676
1636
 
1677
1637
  return isShowContinueFooter;
@@ -1697,6 +1657,28 @@ export class Creatives extends React.Component {
1697
1657
  return true;
1698
1658
  }
1699
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
+
1700
1682
  render() {
1701
1683
  const {
1702
1684
  slidBoxContent,
@@ -1705,6 +1687,7 @@ export class Creatives extends React.Component {
1705
1687
  templateData,
1706
1688
  currentChannel,
1707
1689
  emailCreateMode,
1690
+ selectedEmailCreateMode,
1708
1691
  templateStep,
1709
1692
  isLoadingContent,
1710
1693
  mobilePushCreateMode,
@@ -1717,6 +1700,8 @@ export class Creatives extends React.Component {
1717
1700
  activeFormBuilderTab,
1718
1701
  showTestAndPreviewSlidebox,
1719
1702
  isTestAndPreviewMode,
1703
+ inAppEditorType,
1704
+ htmlEditorValidationState,
1720
1705
  } = this.state;
1721
1706
  const {
1722
1707
  isFullMode,
@@ -1739,9 +1724,35 @@ export class Creatives extends React.Component {
1739
1724
  isLoyaltyModule,
1740
1725
  loyaltyMetaData = {},
1741
1726
  } = this.props;
1727
+ // Compute Continue button label
1728
+ const supportCKEditor = commonUtil.hasSupportCKEditor();
1729
+ const continueButtonLabel = supportCKEditor ? messages.continue : messages.next;
1730
+
1742
1731
  const mapTemplateCreate = slidBoxContent === "createTemplate"
1743
1732
  && weChatTemplateType === MAP_TEMPLATE
1744
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)
1745
1756
  const slideBoxWrapperMargin = (get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0 && get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0)
1746
1757
  ? CAP_SPACE_64
1747
1758
  : get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0
@@ -1751,7 +1762,11 @@ export class Creatives extends React.Component {
1751
1762
  : 0;
1752
1763
  /* TODO: Instead of passing down same props separately to each component down, write common function to these props and pass it accordingly */
1753
1764
  return (
1754
- <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
+ >
1755
1770
  <CapSlideBox
1756
1771
  header={
1757
1772
  this.shouldShowHeader() && (
@@ -1800,6 +1815,8 @@ export class Creatives extends React.Component {
1800
1815
  onChannelChange={this.onChannelChange}
1801
1816
  onEmailModeChange={this.onEmailModeChange}//used when create is clicked in email
1802
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
1803
1820
  templateStep={this.creativesTemplateSteps[templateStep]}
1804
1821
  onCreateNextStep={this.onCreateNextStep}
1805
1822
  onEnterTemplateName={this.onEnterTemplateName}
@@ -1809,6 +1826,8 @@ export class Creatives extends React.Component {
1809
1826
  cap={cap}
1810
1827
  setIsLoadingContent={this.setIsLoadingContent}
1811
1828
  onMobilepushModeChange={this.onMobilepushModeChange}
1829
+ inAppCreateMode={this.state.inAppCreateMode}
1830
+ onInAppModeChange={this.onInAppModeChange}
1812
1831
  mobilePushCreateMode={mobilePushCreateMode}
1813
1832
  showTemplateName={this.showTemplateName}
1814
1833
  onValidationFail={this.onValidationFail}
@@ -1847,6 +1866,7 @@ export class Creatives extends React.Component {
1847
1866
  handleTestAndPreview={this.handleTestAndPreview}
1848
1867
  handleCloseTestAndPreview={this.handleCloseTestAndPreview}
1849
1868
  isTestAndPreviewMode={(() => this.state.isTestAndPreviewMode)()}
1869
+ onHtmlEditorValidationStateChange={this.updateHtmlEditorValidationState}
1850
1870
  />
1851
1871
  )}
1852
1872
  footer={this.shouldShowFooter() ? (
@@ -1861,6 +1881,7 @@ export class Creatives extends React.Component {
1861
1881
  currentChannel={currentChannel.toUpperCase()}
1862
1882
  templateStep={this.creativesTemplateSteps[templateStep]}
1863
1883
  emailCreateMode={emailCreateMode}
1884
+ selectedEmailCreateMode={selectedEmailCreateMode}
1864
1885
  shouldShowContinueFooter={this.shouldShowContinueFooter}
1865
1886
  shouldShowDoneFooter={this.shouldShowDoneFooter}
1866
1887
  fetchingCmsData={fetchingCmsData}
@@ -1869,18 +1890,22 @@ export class Creatives extends React.Component {
1869
1890
  errorMessages={liquidErrorMessage}
1870
1891
  currentTab={activeFormBuilderTab}
1871
1892
  onTestAndPreview={this.handleTestAndPreview}
1893
+ isContinueButtonDisabled={this.isContinueButtonDisabled()}
1894
+ continueButtonLabel={continueButtonLabel}
1872
1895
  showTestAndPreviewButton={(() => {
1873
1896
  const isEmailOrSmsOrWhatsappOrRcsOrInAppOrMobilePush = [constants.EMAIL, constants.SMS, constants.WHATSAPP, constants.RCS, constants.INAPP, constants.MOBILE_PUSH, constants.VIBER, constants.ZALO].includes(currentChannel.toUpperCase());
1874
1897
  const showButton = isEmailOrSmsOrWhatsappOrRcsOrInAppOrMobilePush && (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate');
1875
1898
  return showButton;
1876
1899
  })()}
1900
+ htmlEditorValidationState={htmlEditorValidationState}
1901
+ isCreatingTemplate={slidBoxContent === 'createTemplate' && currentChannel.toUpperCase() === constants.EMAIL}
1877
1902
  />
1878
1903
  ) : isLiquidValidationError && (
1879
1904
  <CapRow className="template-footer-width">
1880
1905
  {(() => {
1881
1906
  const errorsToShow = get(liquidErrorMessage, constants.LIQUID_ERROR_MSG, []);
1882
1907
  const standardErrorsToShow = get(liquidErrorMessage, constants.STANDARD_ERROR_MSG, []);
1883
- 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 }} />;
1884
1909
  })()}
1885
1910
  </CapRow>
1886
1911
  )}