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