@capillarytech/creatives-library 8.0.242-alpha.1 → 8.0.242-alpha.11

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 (255) hide show
  1. package/assets/Android.png +0 -0
  2. package/assets/iOS.png +0 -0
  3. package/config/app.js +1 -1
  4. package/constants/unified.js +2 -2
  5. package/initialReducer.js +0 -2
  6. package/package.json +1 -1
  7. package/services/api.js +5 -10
  8. package/services/tests/api.test.js +0 -18
  9. package/translations/en.json +4 -3
  10. package/utils/common.js +6 -5
  11. package/utils/commonUtils.js +1 -14
  12. package/utils/imageUrlUpload.js +141 -0
  13. package/utils/tests/commonUtil.test.js +0 -224
  14. package/utils/transformTemplateConfig.js +10 -0
  15. package/v2Components/CapDeviceContent/index.js +56 -61
  16. package/v2Components/CapImageUpload/constants.js +2 -0
  17. package/v2Components/CapImageUpload/index.js +65 -16
  18. package/v2Components/CapImageUpload/index.scss +4 -1
  19. package/v2Components/CapImageUpload/messages.js +5 -1
  20. package/v2Components/CapImageUrlUpload/constants.js +26 -0
  21. package/v2Components/CapImageUrlUpload/index.js +365 -0
  22. package/v2Components/CapImageUrlUpload/index.scss +35 -0
  23. package/v2Components/CapImageUrlUpload/messages.js +47 -0
  24. package/v2Components/CapTagList/index.js +1 -6
  25. package/v2Components/CapTagListWithInput/index.js +1 -5
  26. package/v2Components/CapTagListWithInput/messages.js +1 -1
  27. package/v2Components/CapWhatsappCTA/tests/index.test.js +0 -5
  28. package/v2Components/ErrorInfoNote/index.js +72 -412
  29. package/v2Components/ErrorInfoNote/messages.js +0 -22
  30. package/v2Components/ErrorInfoNote/style.scss +2 -279
  31. package/v2Components/HtmlEditor/HTMLEditor.js +89 -210
  32. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +133 -1132
  33. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +12 -17
  34. package/v2Components/HtmlEditor/_htmlEditor.scss +23 -8
  35. package/v2Components/HtmlEditor/_index.lazy.scss +1 -1
  36. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +101 -13
  37. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +139 -148
  38. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +1 -2
  39. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
  40. package/v2Components/HtmlEditor/components/EditorToolbar/index.js +1 -1
  41. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +0 -1
  42. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +7 -4
  43. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +45 -35
  44. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +3 -1
  45. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
  46. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +6 -7
  47. package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +6 -3
  48. package/v2Components/HtmlEditor/components/PreviewPane/index.js +11 -10
  49. package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
  50. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +62 -87
  51. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +31 -49
  52. package/v2Components/HtmlEditor/constants.js +20 -29
  53. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +16 -373
  54. package/v2Components/HtmlEditor/hooks/useEditorContent.js +2 -5
  55. package/v2Components/HtmlEditor/hooks/useInAppContent.js +146 -88
  56. package/v2Components/HtmlEditor/index.js +1 -1
  57. package/v2Components/HtmlEditor/messages.js +85 -95
  58. package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +101 -99
  59. package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +25 -23
  60. package/v2Components/HtmlEditor/utils/validationAdapter.js +41 -34
  61. package/v2Components/MobilePushPreviewV2/index.js +7 -32
  62. package/v2Components/TemplatePreview/_templatePreview.scss +24 -44
  63. package/v2Components/TemplatePreview/index.js +32 -47
  64. package/v2Components/TemplatePreview/messages.js +0 -4
  65. package/v2Components/TestAndPreviewSlidebox/index.js +25 -31
  66. package/v2Containers/App/constants.js +5 -0
  67. package/v2Containers/BeeEditor/index.js +80 -82
  68. package/v2Containers/Cap/tests/__snapshots__/index.test.js.snap +4 -3
  69. package/v2Containers/CreativesContainer/SlideBoxContent.js +118 -148
  70. package/v2Containers/CreativesContainer/SlideBoxFooter.js +3 -9
  71. package/v2Containers/CreativesContainer/SlideBoxHeader.js +2 -2
  72. package/v2Containers/CreativesContainer/constants.js +2 -1
  73. package/v2Containers/CreativesContainer/index.js +41 -173
  74. package/v2Containers/CreativesContainer/messages.js +4 -4
  75. package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +210 -0
  76. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +354 -38
  77. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +0 -36
  78. package/v2Containers/Email/actions.js +0 -7
  79. package/v2Containers/Email/constants.js +1 -5
  80. package/v2Containers/Email/index.js +0 -13
  81. package/v2Containers/Email/messages.js +0 -32
  82. package/v2Containers/Email/reducer.js +1 -12
  83. package/v2Containers/Email/sagas.js +6 -41
  84. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +0 -2
  85. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +7 -193
  86. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +74 -40
  87. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +67 -2
  88. package/v2Containers/EmailWrapper/constants.js +0 -2
  89. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +67 -436
  90. package/v2Containers/EmailWrapper/index.js +23 -99
  91. package/v2Containers/EmailWrapper/messages.js +1 -61
  92. package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +1 -26
  93. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +77 -111
  94. package/v2Containers/InApp/actions.js +0 -7
  95. package/v2Containers/InApp/constants.js +4 -20
  96. package/v2Containers/InApp/index.js +357 -800
  97. package/v2Containers/InApp/index.scss +3 -4
  98. package/v2Containers/InApp/messages.js +3 -7
  99. package/v2Containers/InApp/reducer.js +3 -21
  100. package/v2Containers/InApp/sagas.js +9 -29
  101. package/v2Containers/InApp/selectors.js +5 -25
  102. package/v2Containers/InApp/tests/index.test.js +50 -154
  103. package/v2Containers/InApp/tests/reducer.test.js +0 -34
  104. package/v2Containers/InApp/tests/sagas.test.js +9 -61
  105. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +12 -12
  106. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +8 -8
  107. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +100 -77
  108. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +72 -63
  109. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +184 -150
  110. package/v2Containers/SmsTrai/Create/tests/__snapshots__/index.test.js.snap +16 -12
  111. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +32 -28
  112. package/v2Containers/TagList/index.js +1 -67
  113. package/v2Containers/Templates/ChannelTypeIllustration.js +13 -1
  114. package/v2Containers/Templates/_templates.scss +202 -56
  115. package/v2Containers/Templates/actions.js +2 -1
  116. package/v2Containers/Templates/constants.js +1 -0
  117. package/v2Containers/Templates/index.js +278 -128
  118. package/v2Containers/Templates/messages.js +24 -4
  119. package/v2Containers/Templates/reducer.js +2 -0
  120. package/v2Containers/Templates/tests/index.test.js +10 -0
  121. package/v2Containers/TemplatesV2/index.js +8 -1
  122. package/v2Containers/TemplatesV2/messages.js +4 -0
  123. package/v2Containers/WebPush/Create/components/BrandIconSection.js +108 -0
  124. package/v2Containers/WebPush/Create/components/ButtonForm.js +172 -0
  125. package/v2Containers/WebPush/Create/components/ButtonItem.js +101 -0
  126. package/v2Containers/WebPush/Create/components/ButtonList.js +145 -0
  127. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.js +164 -0
  128. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.test.js +463 -0
  129. package/v2Containers/WebPush/Create/components/FormActions.js +54 -0
  130. package/v2Containers/WebPush/Create/components/FormActions.test.js +163 -0
  131. package/v2Containers/WebPush/Create/components/MediaSection.js +142 -0
  132. package/v2Containers/WebPush/Create/components/MediaSection.test.js +341 -0
  133. package/v2Containers/WebPush/Create/components/MessageSection.js +103 -0
  134. package/v2Containers/WebPush/Create/components/MessageSection.test.js +268 -0
  135. package/v2Containers/WebPush/Create/components/NotificationTitleSection.js +87 -0
  136. package/v2Containers/WebPush/Create/components/NotificationTitleSection.test.js +210 -0
  137. package/v2Containers/WebPush/Create/components/TemplateNameSection.js +54 -0
  138. package/v2Containers/WebPush/Create/components/TemplateNameSection.test.js +143 -0
  139. package/v2Containers/WebPush/Create/components/__snapshots__/ButtonsLinksSection.test.js.snap +86 -0
  140. package/v2Containers/WebPush/Create/components/__snapshots__/FormActions.test.js.snap +16 -0
  141. package/v2Containers/WebPush/Create/components/__snapshots__/MediaSection.test.js.snap +41 -0
  142. package/v2Containers/WebPush/Create/components/__snapshots__/MessageSection.test.js.snap +54 -0
  143. package/v2Containers/WebPush/Create/components/__snapshots__/NotificationTitleSection.test.js.snap +37 -0
  144. package/v2Containers/WebPush/Create/components/__snapshots__/TemplateNameSection.test.js.snap +21 -0
  145. package/v2Containers/WebPush/Create/components/_buttons.scss +246 -0
  146. package/v2Containers/WebPush/Create/components/tests/ButtonForm.test.js +554 -0
  147. package/v2Containers/WebPush/Create/components/tests/ButtonItem.test.js +607 -0
  148. package/v2Containers/WebPush/Create/components/tests/ButtonList.test.js +633 -0
  149. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonForm.test.js.snap +666 -0
  150. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonItem.test.js.snap +74 -0
  151. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonList.test.js.snap +78 -0
  152. package/v2Containers/WebPush/Create/hooks/useButtonManagement.js +138 -0
  153. package/v2Containers/WebPush/Create/hooks/useButtonManagement.test.js +406 -0
  154. package/v2Containers/WebPush/Create/hooks/useCharacterCount.js +30 -0
  155. package/v2Containers/WebPush/Create/hooks/useCharacterCount.test.js +151 -0
  156. package/v2Containers/WebPush/Create/hooks/useImageUpload.js +104 -0
  157. package/v2Containers/WebPush/Create/hooks/useImageUpload.test.js +538 -0
  158. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +122 -0
  159. package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +633 -0
  160. package/v2Containers/WebPush/Create/index.js +1056 -0
  161. package/v2Containers/WebPush/Create/index.scss +134 -0
  162. package/v2Containers/WebPush/Create/messages.js +203 -0
  163. package/v2Containers/WebPush/Create/preview/DevicePreviewContent.js +228 -0
  164. package/v2Containers/WebPush/Create/preview/NotificationContainer.js +294 -0
  165. package/v2Containers/WebPush/Create/preview/PreviewContent.js +90 -0
  166. package/v2Containers/WebPush/Create/preview/PreviewControls.js +305 -0
  167. package/v2Containers/WebPush/Create/preview/PreviewDisclaimer.js +23 -0
  168. package/v2Containers/WebPush/Create/preview/WebPushPreview.js +150 -0
  169. package/v2Containers/WebPush/Create/preview/assets/Light.svg +53 -0
  170. package/v2Containers/WebPush/Create/preview/assets/Top.svg +5 -0
  171. package/v2Containers/WebPush/Create/preview/assets/android-arrow-down.svg +9 -0
  172. package/v2Containers/WebPush/Create/preview/assets/android-arrow-up.svg +9 -0
  173. package/v2Containers/WebPush/Create/preview/assets/chrome-icon.png +0 -0
  174. package/v2Containers/WebPush/Create/preview/assets/edge-icon.png +0 -0
  175. package/v2Containers/WebPush/Create/preview/assets/firefox-icon.svg +106 -0
  176. package/v2Containers/WebPush/Create/preview/assets/iOS.svg +26 -0
  177. package/v2Containers/WebPush/Create/preview/assets/macos-arrow-down-icon.svg +9 -0
  178. package/v2Containers/WebPush/Create/preview/assets/macos-triple-dot-icon.svg +9 -0
  179. package/v2Containers/WebPush/Create/preview/assets/opera-icon.svg +18 -0
  180. package/v2Containers/WebPush/Create/preview/assets/safari-icon.svg +29 -0
  181. package/v2Containers/WebPush/Create/preview/assets/windows-close-icon.svg +9 -0
  182. package/v2Containers/WebPush/Create/preview/assets/windows-triple-dot-icon.svg +9 -0
  183. package/v2Containers/WebPush/Create/preview/components/AndroidMobileChromeHeader.js +47 -0
  184. package/v2Containers/WebPush/Create/preview/components/AndroidMobileExpanded.js +141 -0
  185. package/v2Containers/WebPush/Create/preview/components/IOSHeader.js +45 -0
  186. package/v2Containers/WebPush/Create/preview/components/NotificationExpandedContent.js +68 -0
  187. package/v2Containers/WebPush/Create/preview/components/NotificationHeader.js +61 -0
  188. package/v2Containers/WebPush/Create/preview/components/WindowsChromeExpanded.js +99 -0
  189. package/v2Containers/WebPush/Create/preview/components/tests/AndroidMobileExpanded.test.js +733 -0
  190. package/v2Containers/WebPush/Create/preview/components/tests/WindowsChromeExpanded.test.js +571 -0
  191. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/AndroidMobileExpanded.test.js.snap +81 -0
  192. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/WindowsChromeExpanded.test.js.snap +81 -0
  193. package/v2Containers/WebPush/Create/preview/config/notificationMappings.js +50 -0
  194. package/v2Containers/WebPush/Create/preview/constants.js +637 -0
  195. package/v2Containers/WebPush/Create/preview/notification-container.scss +79 -0
  196. package/v2Containers/WebPush/Create/preview/preview.scss +351 -0
  197. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-chrome.scss +370 -0
  198. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-edge.scss +12 -0
  199. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-firefox.scss +12 -0
  200. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-opera.scss +12 -0
  201. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-chrome.scss +47 -0
  202. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-edge.scss +11 -0
  203. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-firefox.scss +11 -0
  204. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-opera.scss +11 -0
  205. package/v2Containers/WebPush/Create/preview/styles/_base.scss +207 -0
  206. package/v2Containers/WebPush/Create/preview/styles/_ios.scss +153 -0
  207. package/v2Containers/WebPush/Create/preview/styles/_ipados.scss +107 -0
  208. package/v2Containers/WebPush/Create/preview/styles/_macos-chrome.scss +101 -0
  209. package/v2Containers/WebPush/Create/preview/styles/_windows-chrome.scss +229 -0
  210. package/v2Containers/WebPush/Create/preview/tests/DevicePreviewContent.test.js +909 -0
  211. package/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +1081 -0
  212. package/v2Containers/WebPush/Create/preview/tests/PreviewControls.test.js +723 -0
  213. package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +943 -0
  214. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/DevicePreviewContent.test.js.snap +131 -0
  215. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/NotificationContainer.test.js.snap +112 -0
  216. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/PreviewControls.test.js.snap +144 -0
  217. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/WebPushPreview.test.js.snap +129 -0
  218. package/v2Containers/WebPush/Create/utils/payloadBuilder.js +94 -0
  219. package/v2Containers/WebPush/Create/utils/payloadBuilder.test.js +390 -0
  220. package/v2Containers/WebPush/Create/utils/previewUtils.js +89 -0
  221. package/v2Containers/WebPush/Create/utils/urlValidation.js +115 -0
  222. package/v2Containers/WebPush/Create/utils/urlValidation.test.js +449 -0
  223. package/v2Containers/WebPush/Create/utils/validation.js +75 -0
  224. package/v2Containers/WebPush/Create/utils/validation.test.js +283 -0
  225. package/v2Containers/WebPush/actions.js +60 -0
  226. package/v2Containers/WebPush/constants.js +128 -0
  227. package/v2Containers/WebPush/index.js +2 -0
  228. package/v2Containers/WebPush/reducer.js +104 -0
  229. package/v2Containers/WebPush/sagas.js +119 -0
  230. package/v2Containers/WebPush/selectors.js +65 -0
  231. package/v2Containers/WebPush/tests/reducer.test.js +863 -0
  232. package/v2Containers/WebPush/tests/sagas.test.js +566 -0
  233. package/v2Containers/WebPush/tests/selectors.test.js +843 -0
  234. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +528 -431
  235. package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +0 -254
  236. package/v2Components/HtmlEditor/components/ValidationTabs/index.js +0 -362
  237. package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +0 -51
  238. package/v2Containers/BeePopupEditor/constants.js +0 -10
  239. package/v2Containers/BeePopupEditor/index.js +0 -193
  240. package/v2Containers/BeePopupEditor/tests/index.test.js +0 -627
  241. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +0 -1045
  242. package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +0 -376
  243. package/v2Containers/InApp/__tests__/sagas.test.js +0 -363
  244. package/v2Containers/InApp/tests/selectors.test.js +0 -612
  245. package/v2Containers/InAppWrapper/components/InAppWrapperView.js +0 -162
  246. package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +0 -267
  247. package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +0 -9
  248. package/v2Containers/InAppWrapper/constants.js +0 -16
  249. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +0 -473
  250. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +0 -198
  251. package/v2Containers/InAppWrapper/index.js +0 -148
  252. package/v2Containers/InAppWrapper/messages.js +0 -49
  253. package/v2Containers/InappAdvance/index.js +0 -1099
  254. package/v2Containers/InappAdvance/index.scss +0 -10
  255. package/v2Containers/InappAdvance/tests/index.test.js +0 -448
@@ -12,14 +12,14 @@
12
12
  * Note: Uses injectIntl with forwardRef to provide direct access to CodeEditorPane via ref
13
13
  */
14
14
 
15
- import React, {
16
- useRef, useCallback, useMemo, useState, useEffect,
17
- } from 'react';
15
+ import React, { useRef, useCallback, useMemo, useState } from 'react';
18
16
  import PropTypes from 'prop-types';
17
+ import { Layout } from 'antd'; // Fallback - no Cap UI equivalent
19
18
  import { injectIntl, intlShape } from 'react-intl';
20
19
 
21
20
  // Cap UI Components (First Preference)
22
21
  import CapRow from '@capillarytech/cap-ui-library/CapRow';
22
+ import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
23
23
  import CapSpin from '@capillarytech/cap-ui-library/CapSpin';
24
24
  import CapNotification from '@capillarytech/cap-ui-library/CapNotification';
25
25
  import CapModal from '@capillarytech/cap-ui-library/CapModal';
@@ -40,9 +40,7 @@ import { useLayoutState } from './hooks/useLayoutState';
40
40
  import { useValidation } from './hooks/useValidation';
41
41
 
42
42
  // Constants
43
- import {
44
- HTML_EDITOR_VARIANTS, DEVICE_TYPES, DEFAULT_HTML_CONTENT, TAG, EMBEDDED, DEFAULT, FULL, ALL, SMS, EMAIL,
45
- } from './constants';
43
+ import { HTML_EDITOR_VARIANTS, DEVICE_TYPES, DEFAULT_HTML_CONTENT } from './constants';
46
44
 
47
45
  // Styles
48
46
  import './_htmlEditor.scss';
@@ -63,20 +61,6 @@ const HTMLEditor = ({
63
61
  showFullscreenButton = true,
64
62
  autoSave = true,
65
63
  autoSaveInterval = 30000, // 30 seconds
66
- // Tag-related props - tags are fetched and managed by parent component (EmailHTMLEditor, INAPP, etc.)
67
- tags = [],
68
- injectedTags = {},
69
- location,
70
- eventContextTags = [],
71
- selectedOfferDetails = [],
72
- channel,
73
- userLocale = 'en',
74
- moduleFilterEnabled = true,
75
- onTagContextChange, // Parent component handles tag fetching
76
- onTagSelect = null,
77
- onContextChange = null,
78
- globalActions = null,
79
- isLiquidEnabled = false, // Controls Liquid tab visibility in ValidationTabs
80
64
  ...props
81
65
  }) => {
82
66
  // Separate refs for main and modal editors to avoid conflicts
@@ -85,7 +69,9 @@ const HTMLEditor = ({
85
69
  const [isFullscreenModalOpen, setIsFullscreenModalOpen] = useState(false);
86
70
 
87
71
  // Get the currently active editor ref based on fullscreen state
88
- const getActiveEditorRef = useCallback(() => isFullscreenModalOpen ? modalEditorRef : mainEditorRef, [isFullscreenModalOpen]);
72
+ const getActiveEditorRef = useCallback(() => {
73
+ return isFullscreenModalOpen ? modalEditorRef : mainEditorRef;
74
+ }, [isFullscreenModalOpen]);
89
75
 
90
76
  // Initialize custom hooks for state management - always call both hooks to follow Rules of Hooks
91
77
  const isEmailVariant = variant === HTML_EDITOR_VARIANTS.EMAIL;
@@ -94,7 +80,7 @@ const HTMLEditor = ({
94
80
  autoSave: isEmailVariant ? autoSave : false,
95
81
  autoSaveInterval,
96
82
  onSave: isEmailVariant ? onSave : null,
97
- onChange: isEmailVariant ? onContentChange : null,
83
+ onChange: isEmailVariant ? onContentChange : null
98
84
  };
99
85
 
100
86
  const emailContent = useEditorContent(
@@ -111,7 +97,7 @@ const HTMLEditor = ({
111
97
  // Convert string content to device-specific format
112
98
  inAppInitialContent = {
113
99
  [DEVICE_TYPES.ANDROID]: initialContent,
114
- [DEVICE_TYPES.IOS]: initialContent,
100
+ [DEVICE_TYPES.IOS]: initialContent
115
101
  };
116
102
  } else {
117
103
  // Use provided device-specific content
@@ -123,7 +109,7 @@ const HTMLEditor = ({
123
109
  autoSave: isInAppVariant ? autoSave : false,
124
110
  autoSaveInterval,
125
111
  onSave: isInAppVariant ? onSave : null,
126
- onChange: isInAppVariant ? onContentChange : null,
112
+ onChange: isInAppVariant ? onContentChange : null
127
113
  };
128
114
 
129
115
  const inAppContent = useInAppContent(inAppInitialContent, inAppOptions);
@@ -131,64 +117,6 @@ const HTMLEditor = ({
131
117
  // Use appropriate content hook based on variant
132
118
  const content = variant === HTML_EDITOR_VARIANTS.EMAIL ? emailContent : inAppContent;
133
119
 
134
- // Update content when initialContent prop changes (for edit mode)
135
- // This ensures the editor updates when template data loads
136
- useEffect(() => {
137
- if (isEmailVariant && emailContent && initialContent !== undefined && initialContent !== null) {
138
- // Only update if content is different to avoid unnecessary updates
139
- if (emailContent.content !== initialContent) {
140
- emailContent.updateContent(initialContent, true); // immediate update
141
- }
142
- } else if (isInAppVariant && inAppContent && initialContent !== undefined && initialContent !== null) {
143
- // Handle InApp variant updates
144
- const contentToUpdate = typeof initialContent === 'string'
145
- ? { [DEVICE_TYPES.ANDROID]: initialContent, [DEVICE_TYPES.IOS]: initialContent }
146
- : initialContent;
147
- if (inAppContent.updateContent) {
148
- const currentContent = inAppContent.getDeviceContent?.(inAppContent.activeDevice);
149
- const newContent = contentToUpdate[inAppContent.activeDevice] || contentToUpdate[DEVICE_TYPES.ANDROID] || '';
150
- if (currentContent !== newContent) {
151
- inAppContent.updateContent(newContent, true);
152
- }
153
- }
154
- }
155
- }, [initialContent, isEmailVariant, isInAppVariant]);
156
- // Handle context change for tag API calls
157
- // If variant is INAPP, use SMS layout; otherwise use the channel (EMAIL)
158
- const handleContextChange = useCallback((contextData) => {
159
- // If onContextChange is provided, use it instead of making our own API call
160
- // This prevents duplicate API calls when parent component handles tag fetching
161
- if (onContextChange) {
162
- onContextChange(contextData);
163
- return;
164
- }
165
-
166
- // Only make API call if onContextChange is not provided and globalActions is available
167
- if (!globalActions || !location) {
168
- return;
169
- }
170
-
171
- const { type } = location.query || {};
172
- const tempData = (contextData || '').toLowerCase();
173
- const isEmbedded = type === EMBEDDED;
174
- const embedded = isEmbedded ? type : FULL;
175
- const context = tempData === ALL ? DEFAULT : tempData;
176
-
177
- // Determine layout: INAPP variant uses SMS, EMAIL variant uses EMAIL
178
- const layout = variant === HTML_EDITOR_VARIANTS.INAPP ? SMS : EMAIL;
179
-
180
- const query = {
181
- layout,
182
- type: TAG,
183
- context,
184
- embedded,
185
- };
186
-
187
- // Call the API via Redux action - this will trigger the saga which calls Api.fetchSchemaForEntity
188
- // The API endpoint will be: /meta/TAG?query={...}
189
- globalActions.fetchSchemaForEntity(query);
190
- }, [variant, globalActions, location, onContextChange]);
191
-
192
120
  // Destructure content properties for cleaner access throughout component
193
121
  const {
194
122
  activeDevice,
@@ -196,14 +124,14 @@ const HTMLEditor = ({
196
124
  switchDevice,
197
125
  toggleContentSync,
198
126
  getDeviceContent,
199
- markAsSaved,
127
+ markAsSaved
200
128
  } = content || {};
201
129
 
202
130
  const layout = useLayoutState({
203
131
  splitSizes: [50, 50],
204
132
  viewMode: 'desktop',
205
133
  mobileWidth: 375,
206
- isFullscreen: false,
134
+ isFullscreen: false
207
135
  });
208
136
 
209
137
  // Get current content for validation based on variant
@@ -230,7 +158,7 @@ const HTMLEditor = ({
230
158
  'sanitizer.productionValidHtml': messages.sanitizer.productionValidHtml,
231
159
  'sanitizer.productionSanitized': messages.sanitizer.productionSanitized,
232
160
  'sanitizer.productionInlineCss': messages.sanitizer.productionInlineCss,
233
- 'sanitizer.productionLargeContent': messages.sanitizer.productionLargeContent,
161
+ 'sanitizer.productionLargeContent': messages.sanitizer.productionLargeContent
234
162
  };
235
163
 
236
164
  const messageObj = messageMap[messageKey];
@@ -251,7 +179,7 @@ const HTMLEditor = ({
251
179
  'validator.largeImageDetected': messages.validator.largeImageDetected,
252
180
  'validator.unclosedCssRule': messages.validator.unclosedCssRule,
253
181
  'validator.emptyCssRule': messages.validator.emptyCssRule,
254
- 'validator.cssValidationFailed': messages.validator.cssValidationFailed,
182
+ 'validator.cssValidationFailed': messages.validator.cssValidationFailed
255
183
  };
256
184
 
257
185
  const messageObj = messageMap[messageKey];
@@ -262,69 +190,57 @@ const HTMLEditor = ({
262
190
  enableRealTime: true,
263
191
  debounceMs: 500,
264
192
  enableSanitization: true,
265
- securityLevel: 'standard',
193
+ securityLevel: 'standard'
266
194
  }, formatSanitizerMessage, formatValidatorMessage);
267
195
 
268
196
  // Handle label insertion at cursor position
269
- // Note: This is called for notification purposes only when tag is inserted via CodeEditorPane
270
- // The actual insertion happens in CodeEditorPane.handleTagSelect
271
197
  const handleLabelInsert = useCallback((label, position) => {
272
- // If position is explicitly null, it means the editor wasn't ready when tag was selected
273
- // In this case, CodeEditorPane couldn't insert the tag, so we should try here
274
- if (position === null) {
275
- // With injectIntl({ forwardRef: true }), ref points directly to CodeEditorPane
276
- const activeEditorRef = getActiveEditorRef();
277
- const editor = activeEditorRef.current;
278
-
279
- if (!editor) {
280
- CapNotification.warning({
281
- message: intl.formatMessage(messages.labelInsertError),
282
- description: intl.formatMessage(messages.editorNotReady),
283
- duration: 3,
284
- });
285
- return;
286
- }
198
+ // With injectIntl({ forwardRef: true }), ref points directly to CodeEditorPane
199
+ const activeEditorRef = getActiveEditorRef();
200
+ const editor = activeEditorRef.current;
287
201
 
288
- // Check if the required methods exist
289
- if (typeof editor?.insertText !== 'function') {
290
- CapNotification.error({
291
- message: intl.formatMessage(messages.labelInsertError),
292
- description: intl.formatMessage(messages.editorMethodNotAvailable),
293
- duration: 4,
294
- });
295
- return;
296
- }
202
+ if (!editor) {
203
+ CapNotification.warning({
204
+ message: intl.formatMessage(messages.labelInsertError),
205
+ description: intl.formatMessage(messages.editorNotReady),
206
+ duration: 3
207
+ });
208
+ return;
209
+ }
297
210
 
298
- try {
299
- // Get current cursor position
300
- const cursor = typeof editor?.getCursor === 'function' ? editor.getCursor() : 0;
301
-
302
- // Insert label at cursor position
303
- editor.insertText(label, cursor);
304
-
305
- // Focus the editor if focus method is available
306
- editor?.focus?.();
307
-
308
- // Show success notification
309
- CapNotification.success({
310
- message: intl.formatMessage(messages.labelInserted),
311
- description: intl.formatMessage(messages.labelInsertedDescription, { label }),
312
- duration: 2,
313
- });
314
- } catch (error) {
315
- CapNotification.error({
316
- message: intl.formatMessage(messages.labelInsertError),
317
- description: error.message,
318
- duration: 4,
319
- });
320
- }
321
- } else {
322
- // Tag was already inserted by CodeEditorPane (position is a valid number)
323
- // Just show success notification - no need to access editor
211
+ // Check if the required methods exist
212
+ if (typeof editor?.insertText !== 'function') {
213
+ CapNotification.error({
214
+ message: intl.formatMessage(messages.labelInsertError),
215
+ description: intl.formatMessage(messages.editorMethodNotAvailable),
216
+ duration: 4
217
+ });
218
+ return;
219
+ }
220
+
221
+ try {
222
+ // Get current cursor position or use provided position
223
+ const cursor = position !== undefined
224
+ ? position
225
+ : (typeof editor?.getCursor === 'function' ? editor.getCursor() : 0);
226
+
227
+ // Insert label at cursor position
228
+ editor.insertText(label, cursor);
229
+
230
+ // Focus the editor if focus method is available
231
+ editor?.focus?.();
232
+
233
+ // Show success notification
324
234
  CapNotification.success({
325
235
  message: intl.formatMessage(messages.labelInserted),
326
236
  description: intl.formatMessage(messages.labelInsertedDescription, { label }),
327
- duration: 2,
237
+ duration: 2
238
+ });
239
+ } catch (error) {
240
+ CapNotification.error({
241
+ message: intl.formatMessage(messages.labelInsertError),
242
+ description: error.message,
243
+ duration: 4
328
244
  });
329
245
  }
330
246
  }, [intl, getActiveEditorRef]);
@@ -343,13 +259,13 @@ const HTMLEditor = ({
343
259
 
344
260
  CapNotification.success({
345
261
  message: intl.formatMessage(messages.contentSaved),
346
- duration: 2,
262
+ duration: 2
347
263
  });
348
264
  } catch (error) {
349
265
  CapNotification.error({
350
266
  message: intl.formatMessage(messages.saveError),
351
267
  description: error.message,
352
- duration: 4,
268
+ duration: 4
353
269
  });
354
270
  }
355
271
  }, [content, onSave, intl, markAsSaved]);
@@ -391,7 +307,6 @@ const HTMLEditor = ({
391
307
  content,
392
308
  layout,
393
309
  validation,
394
- isLiquidEnabled,
395
310
  editorRef: getActiveEditorRef(),
396
311
  handleLabelInsert,
397
312
  handleSave,
@@ -404,14 +319,13 @@ const HTMLEditor = ({
404
319
  switchDevice,
405
320
  toggleContentSync,
406
321
  getDeviceContent,
407
- layoutType,
408
- }),
322
+ layoutType
323
+ })
409
324
  }), [
410
325
  variant,
411
326
  content,
412
327
  layout,
413
328
  validation,
414
- isLiquidEnabled,
415
329
  getActiveEditorRef,
416
330
  handleLabelInsert,
417
331
  handleSave,
@@ -422,7 +336,7 @@ const HTMLEditor = ({
422
336
  switchDevice,
423
337
  toggleContentSync,
424
338
  getDeviceContent,
425
- layoutType,
339
+ layoutType
426
340
  ]);
427
341
 
428
342
  // Loading state
@@ -473,23 +387,19 @@ const HTMLEditor = ({
473
387
  ref={mainEditorRef}
474
388
  readOnly={readOnly}
475
389
  onLabelInsert={handleLabelInsert}
476
- onErrorClick={handleValidationErrorClick}
477
- tags={tags}
478
- injectedTags={injectedTags}
479
- location={location}
480
- eventContextTags={eventContextTags}
481
- selectedOfferDetails={selectedOfferDetails}
482
- channel={channel}
483
- userLocale={userLocale}
484
- moduleFilterEnabled={moduleFilterEnabled}
485
- onTagContextChange={onTagContextChange}
486
- onTagSelect={onTagSelect}
487
- onContextChange={handleContextChange}
488
390
  />
489
391
 
490
392
  {/* Preview Pane */}
491
393
  <PreviewPane />
492
394
  </SplitContainer>
395
+
396
+ {/* Validation Display - Full Width Below Split Container */}
397
+ <ValidationErrorDisplay
398
+ validation={validation}
399
+ onErrorClick={handleValidationErrorClick}
400
+ variant={variant}
401
+ className="html-editor-validation"
402
+ />
493
403
  </CapRow>
494
404
 
495
405
  {/* Fullscreen Modal */}
@@ -501,17 +411,17 @@ const HTMLEditor = ({
501
411
  maskClosable={false}
502
412
  centered
503
413
  closable={false}
504
- width="90vw"
414
+ width={"90vw"}
505
415
  className="html-editor-fullscreen-modal"
506
416
  >
507
417
  <CapRow className="html-editor-fullscreen">
508
418
  {/* Editor Toolbar - Conditional based on variant */}
509
419
  {variant === HTML_EDITOR_VARIANTS.EMAIL ? (
510
420
  <EditorToolbar
511
- showFullscreenButton // Show fullscreen button in modal to allow closing
421
+ showFullscreenButton={true} // Show fullscreen button in modal to allow closing
512
422
  onLabelInsert={handleLabelInsert}
513
423
  onSave={handleSave}
514
- isFullscreenMode
424
+ isFullscreenMode={true}
515
425
  onToggleFullscreen={handleCloseFullscreen} // Close modal when clicked in fullscreen mode
516
426
  />
517
427
  ) : (
@@ -524,10 +434,10 @@ const HTMLEditor = ({
524
434
  onKeepContentSameChange={toggleContentSync}
525
435
  />
526
436
  <EditorToolbar
527
- showFullscreenButton // Show fullscreen button in modal to allow closing
437
+ showFullscreenButton={true} // Show fullscreen button in modal to allow closing
528
438
  onLabelInsert={handleLabelInsert}
529
439
  onSave={handleSave}
530
- isFullscreenMode
440
+ isFullscreenMode={true}
531
441
  onToggleFullscreen={handleCloseFullscreen} // Close modal when clicked in fullscreen mode
532
442
  variant={variant}
533
443
  showTitle={false} // Hide title in InApp variant
@@ -542,23 +452,21 @@ const HTMLEditor = ({
542
452
  <CodeEditorPane
543
453
  ref={modalEditorRef}
544
454
  readOnly={readOnly}
545
- isFullscreenMode
455
+ isFullscreenMode={true}
546
456
  onLabelInsert={handleLabelInsert}
547
- onErrorClick={handleValidationErrorClick}
548
- tags={tags}
549
- injectedTags={injectedTags}
550
- location={location}
551
- eventContextTags={eventContextTags}
552
- selectedOfferDetails={selectedOfferDetails}
553
- channel={channel}
554
- userLocale={userLocale}
555
- moduleFilterEnabled={moduleFilterEnabled}
556
- onTagContextChange={onTagContextChange}
557
457
  />
558
458
 
559
- {/* Preview Pane */}
560
- <PreviewPane isFullscreenMode isModalContext />
561
- </SplitContainer>
459
+ {/* Preview Pane */}
460
+ <PreviewPane isFullscreenMode={true} isModalContext={true} />
461
+ </SplitContainer>
462
+
463
+ {/* Validation Display in Modal */}
464
+ <ValidationErrorDisplay
465
+ validation={validation}
466
+ onErrorClick={handleValidationErrorClick}
467
+ variant={variant}
468
+ className="html-editor-validation"
469
+ />
562
470
  </CapRow>
563
471
  </CapRow>
564
472
  </CapModal>
@@ -573,7 +481,7 @@ HTMLEditor.propTypes = {
573
481
  layoutType: PropTypes.string, // Layout type for InApp variant
574
482
  initialContent: PropTypes.oneOfType([
575
483
  PropTypes.string,
576
- PropTypes.objectOf(PropTypes.string), // Per-device content for INAPP variant
484
+ PropTypes.objectOf(PropTypes.string) // Per-device content for INAPP variant
577
485
  ]),
578
486
  onSave: PropTypes.func,
579
487
  onContentChange: PropTypes.func,
@@ -581,26 +489,11 @@ HTMLEditor.propTypes = {
581
489
  readOnly: PropTypes.bool,
582
490
  showFullscreenButton: PropTypes.bool,
583
491
  autoSave: PropTypes.bool,
584
- autoSaveInterval: PropTypes.number,
585
- // Tag-related props - tags are fetched and managed by parent component
586
- tags: PropTypes.array,
587
- injectedTags: PropTypes.object,
588
- location: PropTypes.object,
589
- eventContextTags: PropTypes.array,
590
- selectedOfferDetails: PropTypes.array,
591
- channel: PropTypes.string,
592
- userLocale: PropTypes.string,
593
- moduleFilterEnabled: PropTypes.bool,
594
- onTagContextChange: PropTypes.func, // Required - parent must handle tag fetching
595
- onTagSelect: PropTypes.func,
596
- onContextChange: PropTypes.func, // Deprecated: use globalActions instead
597
- globalActions: PropTypes.object,
598
- isLiquidEnabled: PropTypes.bool, // Controls Liquid tab visibility in validation
492
+ autoSaveInterval: PropTypes.number
599
493
  };
600
494
 
601
495
  HTMLEditor.defaultProps = {
602
496
  variant: HTML_EDITOR_VARIANTS.EMAIL, // Default to email variant
603
- layoutType: null,
604
497
  initialContent: null, // Will use default from useEditorContent hook
605
498
  onSave: null,
606
499
  onContentChange: null,
@@ -608,21 +501,7 @@ HTMLEditor.defaultProps = {
608
501
  readOnly: false,
609
502
  showFullscreenButton: true,
610
503
  autoSave: true,
611
- autoSaveInterval: 30000,
612
- // Tag-related defaults - tags are fetched and managed by parent component
613
- tags: [],
614
- injectedTags: {},
615
- location: null,
616
- eventContextTags: [],
617
- selectedOfferDetails: [],
618
- channel: null,
619
- userLocale: 'en',
620
- moduleFilterEnabled: true,
621
- onTagContextChange: null, // Parent component should provide this
622
- onTagSelect: null,
623
- onContextChange: null,
624
- globalActions: null, // Redux actions for API calls
625
- isLiquidEnabled: false,
504
+ autoSaveInterval: 30000
626
505
  };
627
506
 
628
507
  // Export with forwardRef to allow direct access to CodeEditorPane via ref