@capillarytech/creatives-library 8.0.159 → 8.0.161

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 (312) hide show
  1. package/components/BreadCrumbs/index.js +65 -0
  2. package/components/BreadCrumbs/messages.js +13 -0
  3. package/components/CapTagList/index.js +235 -0
  4. package/components/CapTagList/messages.js +45 -0
  5. package/components/Card/_customCard.scss +40 -0
  6. package/components/Card/index.js +78 -0
  7. package/components/Card/tests/__snapshots__/index.test.js.snap +22 -0
  8. package/components/Card/tests/index.test.js +20 -0
  9. package/components/CardGrid/index.js +71 -0
  10. package/components/Ckeditor/index.js +238 -0
  11. package/components/Ckeditor/messages.js +13 -0
  12. package/components/Ckeditor/style.scss +3 -0
  13. package/components/Component/index.js +29 -0
  14. package/components/CustomPopOver/index.js +81 -0
  15. package/components/CustomPopOver/messages.js +17 -0
  16. package/components/DateFilter/index.js +349 -0
  17. package/components/DateFilter/messages.js +57 -0
  18. package/components/DateRange/index.js +114 -0
  19. package/components/DateRange/messages.js +25 -0
  20. package/components/Edmeditor/index.js +65 -0
  21. package/components/Edmeditor/messages.js +13 -0
  22. package/components/EmailPreview/_emailPreview.scss +119 -0
  23. package/components/EmailPreview/assets/images/iPad.svg +10 -0
  24. package/components/EmailPreview/assets/images/mobile.png +0 -0
  25. package/components/EmailPreview/index.js +107 -0
  26. package/components/EmailPreview/messages.js +33 -0
  27. package/components/Footer/index.js +27 -0
  28. package/components/Footer/messages.js +13 -0
  29. package/components/FormBuilder/_formBuilder.scss +83 -0
  30. package/components/FormBuilder/index.js +3279 -0
  31. package/components/FormBuilder/messages.js +61 -0
  32. package/components/Header/index.js +44 -0
  33. package/components/Header/messages.js +29 -0
  34. package/components/ImagePreview/_imagePreview.scss +63 -0
  35. package/components/ImagePreview/index.js +52 -0
  36. package/components/ImagePreview/messages.js +17 -0
  37. package/components/PageHeader/_pageHeader.scss +22 -0
  38. package/components/PageHeader/index.js +37 -0
  39. package/components/PageHeader/messages.js +13 -0
  40. package/components/Pagination/_pagination.scss +5 -0
  41. package/components/Pagination/index.js +49 -0
  42. package/components/PreviewSideBar/_previewsidebar.scss +28 -0
  43. package/components/PreviewSideBar/index.js +152 -0
  44. package/components/PreviewSideBar/messages.js +41 -0
  45. package/components/Sidebar/_sidebar.scss +115 -0
  46. package/components/Sidebar/index.js +214 -0
  47. package/components/Sidebar/messages.js +21 -0
  48. package/components/SlideBox/_slideBox.scss +63 -0
  49. package/components/SlideBox/index.js +47 -0
  50. package/components/SlideBox/tests/index.test.js +103 -0
  51. package/components/SmsEditor/index.js +55 -0
  52. package/components/SmsTest/index.js +117 -0
  53. package/components/SmsTest/messages.js +21 -0
  54. package/components/TemplatePreview/WechatRichmediaTemplatePreview/_wechatRichmediaTemplatePrev.scss +42 -0
  55. package/components/TemplatePreview/WechatRichmediaTemplatePreview/index.js +141 -0
  56. package/components/TemplatePreview/WechatRichmediaTemplatePreview/messages.js +21 -0
  57. package/components/TemplatePreview/_templatePreview.scss +642 -0
  58. package/components/TemplatePreview/assets/images/WECHAT_5x.png +0 -0
  59. package/components/TemplatePreview/assets/images/androidPushMessage.svg +45 -0
  60. package/components/TemplatePreview/assets/images/home-screen-android.svg +21 -0
  61. package/components/TemplatePreview/assets/images/home-screen-ios.svg +16 -0
  62. package/components/TemplatePreview/assets/images/iPhonePushMessage.svg +135 -0
  63. package/components/TemplatePreview/assets/images/mobile.svg +24 -0
  64. package/components/TemplatePreview/assets/images/sms-body.png +0 -0
  65. package/components/TemplatePreview/assets/images/sms-icon.png +0 -0
  66. package/components/TemplatePreview/assets/images/sms_mobile.png +0 -0
  67. package/components/TemplatePreview/assets/images/sms_mobile_android.svg +22 -0
  68. package/components/TemplatePreview/assets/images/sms_mobile_ios.svg +16 -0
  69. package/components/TemplatePreview/assets/images/user-icon.svg +19 -0
  70. package/components/TemplatePreview/assets/images/wechat-mobile.svg +78 -0
  71. package/components/TemplatePreview/assets/images/wechat_mobile_android.svg +20 -0
  72. package/components/TemplatePreview/index.js +617 -0
  73. package/components/TemplatePreview/messages.js +78 -0
  74. package/components/Toastr/index.js +60 -0
  75. package/components/Toastr/messages.js +13 -0
  76. package/components/ToastrMessage/index.js +113 -0
  77. package/components/ToastrMessage/messages.js +17 -0
  78. package/components/TopBar/_topbar.scss +46 -0
  79. package/components/TopBar/assets/images/capillary_logo.png +0 -0
  80. package/components/TopBar/assets/images/old_capillary_logo.png +0 -0
  81. package/components/TopBar/index.js +113 -0
  82. package/components/TopBar/messages.js +29 -0
  83. package/containers/App/actions.js +7 -0
  84. package/containers/App/constants.js +114 -0
  85. package/containers/App/index.js +52 -0
  86. package/containers/App/reducer.js +19 -0
  87. package/containers/App/sagas.js +31 -0
  88. package/containers/App/selectors.js +25 -0
  89. package/containers/App/test/saga.test.js +11 -0
  90. package/containers/Assets/Gallery/_gallery.scss +126 -0
  91. package/containers/Assets/Gallery/actions.js +37 -0
  92. package/containers/Assets/Gallery/constants.js +23 -0
  93. package/containers/Assets/Gallery/index.js +473 -0
  94. package/containers/Assets/Gallery/messages.js +93 -0
  95. package/containers/Assets/Gallery/reducer.js +81 -0
  96. package/containers/Assets/Gallery/sagas.js +80 -0
  97. package/containers/Assets/Gallery/selectors.js +25 -0
  98. package/containers/Assets/Gallery/tests/__snapshots__/reducer.test.js.snap +9 -0
  99. package/containers/Assets/Gallery/tests/actions.test.js +25 -0
  100. package/containers/Assets/Gallery/tests/reducer.test.js +96 -0
  101. package/containers/Assets/Gallery/tests/saga.test.js +157 -0
  102. package/containers/Cap/actions.js +66 -0
  103. package/containers/Cap/constants.js +25 -0
  104. package/containers/Cap/index.js +402 -0
  105. package/containers/Cap/messages.js +75 -0
  106. package/containers/Cap/reducer.js +113 -0
  107. package/containers/Cap/sagas.js +159 -0
  108. package/containers/Cap/selectors.js +75 -0
  109. package/containers/Cap/tests/__snapshots__/index.test.js.snap +2270 -0
  110. package/containers/Cap/tests/index.test.js +22 -0
  111. package/containers/Cap/tests/saga.test.js +284 -0
  112. package/containers/Dashboard/actions.js +15 -0
  113. package/containers/Dashboard/constants.js +7 -0
  114. package/containers/Dashboard/index.js +76 -0
  115. package/containers/Dashboard/messages.js +13 -0
  116. package/containers/Dashboard/reducer.js +21 -0
  117. package/containers/Dashboard/sagas.js +17 -0
  118. package/containers/Dashboard/selectors.js +25 -0
  119. package/containers/Dashboard/test/saga.test.js +9 -0
  120. package/containers/Ebill/_ebill.scss +5 -0
  121. package/containers/Ebill/actions.js +43 -0
  122. package/containers/Ebill/constants.js +20 -0
  123. package/containers/Ebill/index.js +1278 -0
  124. package/containers/Ebill/messages.js +77 -0
  125. package/containers/Ebill/reducer.js +72 -0
  126. package/containers/Ebill/sagas.js +74 -0
  127. package/containers/Ebill/selectors.js +25 -0
  128. package/containers/Ebill/test/saga.test.js +11 -0
  129. package/containers/Email/_email.scss +141 -0
  130. package/containers/Email/actions.js +81 -0
  131. package/containers/Email/constants.js +36 -0
  132. package/containers/Email/index.js +3325 -0
  133. package/containers/Email/messages.js +289 -0
  134. package/containers/Email/reducer.js +142 -0
  135. package/containers/Email/sagas.js +135 -0
  136. package/containers/Email/selectors.js +31 -0
  137. package/containers/Email/test/saga.test.js +671 -0
  138. package/containers/LanguageProvider/actions.js +17 -0
  139. package/containers/LanguageProvider/constants.js +8 -0
  140. package/containers/LanguageProvider/index.js +80 -0
  141. package/containers/LanguageProvider/reducer.js +30 -0
  142. package/containers/LanguageProvider/selectors.js +20 -0
  143. package/containers/LanguageProvider/tests/actions.test.js +19 -0
  144. package/containers/LanguageProvider/tests/index.test.js +78 -0
  145. package/containers/LanguageProvider/tests/reducer.test.js +20 -0
  146. package/containers/LanguageProvider/tests/selectors.test.js +15 -0
  147. package/containers/Line/Create/_lineCreate.scss +54 -0
  148. package/containers/Line/Create/actions.js +90 -0
  149. package/containers/Line/Create/constants.js +39 -0
  150. package/containers/Line/Create/index.js +836 -0
  151. package/containers/Line/Create/messages.js +189 -0
  152. package/containers/Line/Create/reducer.js +99 -0
  153. package/containers/Line/Create/sagas.js +121 -0
  154. package/containers/Line/Create/selectors.js +36 -0
  155. package/containers/Line/Create/tests/saga.test.js +202 -0
  156. package/containers/Line/Edit/_lineEdit.scss +35 -0
  157. package/containers/Line/Edit/actions.js +79 -0
  158. package/containers/Line/Edit/constants.js +27 -0
  159. package/containers/Line/Edit/index.js +1050 -0
  160. package/containers/Line/Edit/messages.js +177 -0
  161. package/containers/Line/Edit/reducer.js +83 -0
  162. package/containers/Line/Edit/sagas.js +80 -0
  163. package/containers/Line/Edit/selectors.js +29 -0
  164. package/containers/Line/Edit/test/saga.test.js +160 -0
  165. package/containers/Login/assets/images/capillary_logo.png +0 -0
  166. package/containers/Login/components/LoginForm/index.js +62 -0
  167. package/containers/Login/components/LoginForm/messages.js +33 -0
  168. package/containers/Login/index.js +130 -0
  169. package/containers/Login/messages.js +25 -0
  170. package/containers/Login/selectors.js +25 -0
  171. package/containers/MobilePush/Create/_mobilePushCreate.scss +39 -0
  172. package/containers/MobilePush/Create/actions.js +46 -0
  173. package/containers/MobilePush/Create/constants.js +23 -0
  174. package/containers/MobilePush/Create/index.js +2303 -0
  175. package/containers/MobilePush/Create/messages.js +269 -0
  176. package/containers/MobilePush/Create/reducer.js +70 -0
  177. package/containers/MobilePush/Create/sagas.js +74 -0
  178. package/containers/MobilePush/Create/selectors.js +28 -0
  179. package/containers/MobilePush/Create/test/saga.test.js +19 -0
  180. package/containers/MobilePush/Edit/_mobilePushCreate.scss +39 -0
  181. package/containers/MobilePush/Edit/actions.js +91 -0
  182. package/containers/MobilePush/Edit/constants.js +35 -0
  183. package/containers/MobilePush/Edit/index.js +2601 -0
  184. package/containers/MobilePush/Edit/messages.js +266 -0
  185. package/containers/MobilePush/Edit/reducer.js +112 -0
  186. package/containers/MobilePush/Edit/sagas.js +126 -0
  187. package/containers/MobilePush/Edit/selectors.js +29 -0
  188. package/containers/MobilePush/Edit/tests/saga.test.js +255 -0
  189. package/containers/NotFoundPage/index.js +25 -0
  190. package/containers/NotFoundPage/messages.js +13 -0
  191. package/containers/NotFoundPage/tests/index.test.js +17 -0
  192. package/containers/Sms/Create/_smsCreate.scss +42 -0
  193. package/containers/Sms/Create/actions.js +27 -0
  194. package/containers/Sms/Create/constants.js +16 -0
  195. package/containers/Sms/Create/index.js +1488 -0
  196. package/containers/Sms/Create/messages.js +109 -0
  197. package/containers/Sms/Create/reducer.js +41 -0
  198. package/containers/Sms/Create/sagas.js +40 -0
  199. package/containers/Sms/Create/selectors.js +28 -0
  200. package/containers/Sms/Create/test/saga.test.js +11 -0
  201. package/containers/Sms/Edit/actions.js +40 -0
  202. package/containers/Sms/Edit/constants.js +17 -0
  203. package/containers/Sms/Edit/index.js +1472 -0
  204. package/containers/Sms/Edit/messages.js +105 -0
  205. package/containers/Sms/Edit/reducer.js +50 -0
  206. package/containers/Sms/Edit/sagas.js +60 -0
  207. package/containers/Sms/Edit/selectors.js +32 -0
  208. package/containers/Sms/Edit/test/saga.test.js +13 -0
  209. package/containers/TagList/_tagList.scss +8 -0
  210. package/containers/TagList/actions.js +15 -0
  211. package/containers/TagList/constants.js +32 -0
  212. package/containers/TagList/index.js +236 -0
  213. package/containers/TagList/messages.js +13 -0
  214. package/containers/TagList/reducer.js +23 -0
  215. package/containers/TagList/sagas.js +11 -0
  216. package/containers/TagList/selectors.js +25 -0
  217. package/containers/Templates/_templates.scss +333 -0
  218. package/containers/Templates/actions.js +103 -0
  219. package/containers/Templates/constants.js +60 -0
  220. package/containers/Templates/index.js +1756 -0
  221. package/containers/Templates/messages.js +337 -0
  222. package/containers/Templates/reducer.js +142 -0
  223. package/containers/Templates/sagas.js +163 -0
  224. package/containers/Templates/selectors.js +28 -0
  225. package/containers/Templates/test/saga.test.js +241 -0
  226. package/containers/WeChat/MapTemplates/_mapTemplates.scss +8 -0
  227. package/containers/WeChat/MapTemplates/actions.js +52 -0
  228. package/containers/WeChat/MapTemplates/constants.js +28 -0
  229. package/containers/WeChat/MapTemplates/index.js +1610 -0
  230. package/containers/WeChat/MapTemplates/messages.js +157 -0
  231. package/containers/WeChat/MapTemplates/reducer.js +74 -0
  232. package/containers/WeChat/MapTemplates/sagas.js +84 -0
  233. package/containers/WeChat/MapTemplates/selectors.js +25 -0
  234. package/containers/WeChat/MapTemplates/test/saga.test.js +155 -0
  235. package/containers/WeChat/RichmediaTemplates/Create/_createRichmedia.scss +57 -0
  236. package/containers/WeChat/RichmediaTemplates/Create/actions.js +36 -0
  237. package/containers/WeChat/RichmediaTemplates/Create/constants.js +15 -0
  238. package/containers/WeChat/RichmediaTemplates/Create/index.js +1071 -0
  239. package/containers/WeChat/RichmediaTemplates/Create/messages.js +165 -0
  240. package/containers/WeChat/RichmediaTemplates/Create/reducer.js +60 -0
  241. package/containers/WeChat/RichmediaTemplates/Create/richmediaschema.js +497 -0
  242. package/containers/WeChat/RichmediaTemplates/Create/sagas.js +51 -0
  243. package/containers/WeChat/RichmediaTemplates/Create/selectors.js +37 -0
  244. package/containers/WeChat/RichmediaTemplates/Create/test/saga.test.js +13 -0
  245. package/containers/WeChat/RichmediaTemplates/Edit/actions.js +20 -0
  246. package/containers/WeChat/RichmediaTemplates/Edit/constants.js +10 -0
  247. package/containers/WeChat/RichmediaTemplates/Edit/index.js +136 -0
  248. package/containers/WeChat/RichmediaTemplates/Edit/messages.js +13 -0
  249. package/containers/WeChat/RichmediaTemplates/Edit/reducer.js +28 -0
  250. package/containers/WeChat/RichmediaTemplates/Edit/sagas.js +36 -0
  251. package/containers/WeChat/RichmediaTemplates/Edit/selectors.js +30 -0
  252. package/containers/WeChat/RichmediaTemplates/Edit/test/saga.test.js +12 -0
  253. package/containers/WeChat/RichmediaTemplates/View/actions.js +15 -0
  254. package/containers/WeChat/RichmediaTemplates/View/constants.js +7 -0
  255. package/containers/WeChat/RichmediaTemplates/View/index.js +47 -0
  256. package/containers/WeChat/RichmediaTemplates/View/messages.js +21 -0
  257. package/containers/WeChat/RichmediaTemplates/View/reducer.js +23 -0
  258. package/containers/WeChat/RichmediaTemplates/View/sagas.js +11 -0
  259. package/containers/WeChat/RichmediaTemplates/View/selectors.js +25 -0
  260. package/index.js +2 -4
  261. package/package.json +1 -1
  262. package/routes.js +202 -136
  263. package/services/getSchema.js +1 -1
  264. package/services/localStorageApi.js +0 -1
  265. package/tests/i18n.test.js +1 -1
  266. package/utils/asyncInjectors.js +78 -0
  267. package/utils/authWrapper.js +1 -1
  268. package/utils/callNativeEvent.js +16 -0
  269. package/utils/checkStore.js +21 -0
  270. package/utils/common.js +2 -2
  271. package/utils/customAuthWrapper.js +62 -0
  272. package/utils/customConnectedAuthWrapper.js +26 -0
  273. package/utils/tagValidations.js +1 -1
  274. package/utils/tests/authWrapper.test.js +1 -1
  275. package/utils/tests/checkStore.test.js +1 -1
  276. package/utils/tests/customAuth.test.js +1 -1
  277. package/utils/transformerUtils.js +1 -1
  278. package/v2Components/CapTagList/index.js +14 -9
  279. package/v2Components/Carousel/style.scss +1 -1
  280. package/v2Components/CustomerSearchSection/index.js +83 -79
  281. package/v2Components/EmailMobilePreview/index.js +2 -2
  282. package/v2Components/EmailPreview/_emailPreview.scss +1 -0
  283. package/v2Components/EmailPreviewV2/_emailPreviewV2.scss +1 -0
  284. package/v2Components/FormBuilder/index.js +80 -55
  285. package/v2Components/TemplatePreview/index.js +1 -2
  286. package/v2Components/TestAndPreviewSlidebox/PreviewSection.js +1 -1
  287. package/v2Components/TestAndPreviewSlidebox/SendTestMessage.js +1 -1
  288. package/v2Components/TestAndPreviewSlidebox/_testAndPreviewSlidebox.scss +2 -1
  289. package/v2Components/TestAndPreviewSlidebox/index.js +223 -22
  290. package/v2Components/TestAndPreviewSlidebox/reducer.js +15 -6
  291. package/v2Components/TestAndPreviewSlidebox/sagas.js +24 -3
  292. package/v2Components/TestAndPreviewSlidebox/tests/PreviewSection.test.js +1 -1
  293. package/v2Components/TestAndPreviewSlidebox/tests/reducer.test.js +21 -5
  294. package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +20 -5
  295. package/v2Containers/Cap/tests/saga.test.js +1 -1
  296. package/v2Containers/CreativesContainer/SlideBoxContent.js +9 -3
  297. package/v2Containers/CreativesContainer/index.js +22 -15
  298. package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +599 -1
  299. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +1941 -0
  300. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +5 -0
  301. package/v2Containers/Email/index.js +116 -32
  302. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +3 -0
  303. package/v2Containers/EmailWrapper/index.js +6 -0
  304. package/v2Containers/FTP/index.js +1 -1
  305. package/v2Containers/Line/Container/Text/index.js +1 -1
  306. package/v2Containers/Sms/Create/index.js +1 -1
  307. package/v2Containers/Sms/Edit/index.js +1 -1
  308. package/v2Containers/TagList/index.js +1 -1
  309. package/v2Containers/TagList/utils.js +1 -1
  310. package/v2Containers/Templates/index.js +1 -1
  311. package/v2Containers/Templates/sagas.js +1 -1
  312. package/constants/unified.js +0 -189
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import PropTypes from 'prop-types';
8
- import React, { useState, useEffect, useMemo } from 'react';
8
+ import React, { useState, useEffect, useMemo, useRef } from 'react';
9
9
  import { convert } from "html-to-text";
10
10
  import { createStructuredSelector } from 'reselect';
11
11
  import { connect } from 'react-redux';
@@ -75,6 +75,7 @@ const TestAndPreviewSlidebox = (props) => {
75
75
  prefilledValues,
76
76
  isSendingTestMessage,
77
77
  beeInstance,
78
+ currentTab = 1, // Add currentTab prop with default value
78
79
  } = props;
79
80
 
80
81
  // State management
@@ -85,30 +86,185 @@ const TestAndPreviewSlidebox = (props) => {
85
86
  const [showJSON, setShowJSON] = useState(false);
86
87
  const [tagsExtracted, setTagsExtracted] = useState(false);
87
88
  const [previewDevice, setPreviewDevice] = useState('desktop');
88
- const [previewDataHtml, setPreviewDataHtml] = useState(previewData || '');
89
+ const [previewDataHtml, setPreviewDataHtml] = useState(() => {
90
+ // Initialize with current content if available
91
+ const currentTabData = formData[currentTab - 1];
92
+ const activeTab = currentTabData?.activeTab;
93
+ const templateContent = currentTabData?.[activeTab]?.['template-content'];
94
+
95
+ if (templateContent) {
96
+ return {
97
+ resolvedBody: templateContent,
98
+ resolvedTitle: formData['template-subject'] || ''
99
+ };
100
+ }
101
+ return previewData || '';
102
+ });
89
103
  const [selectedTestEntities, setSelectedTestEntities] = useState([]);
104
+ const [beeContent, setBeeContent] = useState(''); // Track BEE editor content separately
105
+ const previousBeeContentRef = useRef(''); // Track previous BEE content to prevent unnecessary updates
90
106
 
91
107
  const isUpdatePreviewDisabled = useMemo(() => (
92
108
  requiredTags.some((tag) => !customValues[tag.fullPath])
93
109
  ), [requiredTags, customValues]);
94
110
 
111
+ // Get the current content based on editor type
112
+ const getCurrentContent = useMemo(() => {
113
+ const currentTabData = formData[currentTab - 1];
114
+ const activeTab = currentTabData?.activeTab;
115
+ const isDragDrop = currentTabData?.[activeTab]?.is_drag_drop;
116
+
117
+ if (isDragDrop && beeContent) {
118
+ return beeContent; // Use BEE content if available
119
+ }
120
+
121
+ // For CKEditor in edit mode, get content from formData
122
+ if (!isDragDrop && currentTabData?.[activeTab]?.['template-content']) {
123
+ return currentTabData[activeTab]['template-content'];
124
+ }
125
+
126
+ return content; // Fall back to content prop
127
+ }, [formData, currentTab, beeContent, content, beeInstance]);
128
+
95
129
  useEffect(() => {
96
- if (show && beeInstance) {
97
- beeInstance.save();
130
+ // Only save BEE content if we're actually using BEE editor
131
+ const currentTabData = formData[currentTab - 1];
132
+ const activeTab = currentTabData?.activeTab;
133
+ const isDragDrop = currentTabData?.[activeTab]?.is_drag_drop;
134
+
135
+ if (show && beeInstance && isDragDrop) {
136
+ // Check if we already have content in formData
137
+ const existingContent = currentTabData?.[activeTab]?.[`template-content`];
138
+ if (existingContent && existingContent.trim() !== '') {
139
+ // We already have content, update local state only if it's different
140
+ if (existingContent !== previousBeeContentRef.current) {
141
+ previousBeeContentRef.current = existingContent;
142
+ setBeeContent(existingContent);
143
+ setPreviewDataHtml({
144
+ resolvedBody: existingContent,
145
+ resolvedTitle: formData['template-subject'] || ''
146
+ });
147
+ }
148
+ } else {
149
+ // No content yet, trigger save
150
+ beeInstance.save();
151
+ }
98
152
  }
99
- }, [show, beeInstance]);
153
+ }, [show, beeInstance, currentTab]);
100
154
 
101
155
  useEffect(() => {
102
156
  if (show) {
157
+ // For BEE editor, ensure content is saved and synced first
158
+ const currentTabData = formData[currentTab - 1];
159
+ const activeTab = currentTabData?.activeTab;
160
+ const isDragDrop = currentTabData?.[activeTab]?.is_drag_drop;
161
+
162
+ if (beeInstance && isDragDrop) {
163
+ // Store original save handler
164
+ const originalOnSave = beeInstance.onSave;
165
+
166
+ // Create temporary save handler
167
+ const tempSaveHandler = (jsonFile, htmlFile) => {
168
+ // Call original handler first to ensure editor state is saved
169
+ if (originalOnSave) {
170
+ originalOnSave(jsonFile, htmlFile);
171
+ }
172
+
173
+ if (htmlFile) {
174
+ // Update our states
175
+ previousBeeContentRef.current = htmlFile;
176
+ setBeeContent(htmlFile);
177
+ setPreviewDataHtml({
178
+ resolvedBody: htmlFile,
179
+ resolvedTitle: formData['template-subject'] || ''
180
+ });
181
+
182
+ // Extract tags with latest content
183
+ const payloadContent = convert(htmlFile, GLOBAL_CONVERT_OPTIONS);
184
+ actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
185
+ }
186
+
187
+ // Restore original handler
188
+ beeInstance.onSave = originalOnSave;
189
+ };
190
+
191
+ // Set temporary handler and trigger save
192
+ beeInstance.onSave = tempSaveHandler;
193
+ beeInstance.save();
194
+ } else {
195
+ // For CKEditor, get content from formData
196
+ const templateContent = currentTabData?.[activeTab]?.['template-content'];
197
+
198
+ if (templateContent) {
199
+ // Update preview with initial content
200
+ setPreviewDataHtml({
201
+ resolvedBody: templateContent,
202
+ resolvedTitle: formData['template-subject'] || ''
203
+ });
204
+
205
+ // Extract tags with initial content
206
+ const payloadContent = convert(templateContent, GLOBAL_CONVERT_OPTIONS);
207
+ actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
208
+ } else {
209
+ // Fallback to content prop if no template content
210
+ const payloadContent = convert(
211
+ getCurrentContent,
212
+ GLOBAL_CONVERT_OPTIONS
213
+ );
214
+ actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
215
+ }
216
+ }
217
+
103
218
  actions.fetchTestCustomersRequested();
104
219
  actions.fetchTestGroupsRequested();
105
- const payloadContent = convert(
106
- content,
107
- GLOBAL_CONVERT_OPTIONS
108
- );
109
- actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
110
220
  }
111
- }, [show, content, formData]);
221
+ }, [show, beeInstance, currentTab]);
222
+
223
+ // Effect to handle content updates for both editors
224
+ useEffect(() => {
225
+ const currentTabData = formData[currentTab - 1];
226
+ const activeTab = currentTabData?.activeTab;
227
+ const isDragDrop = currentTabData?.[activeTab]?.is_drag_drop;
228
+ const templateContent = currentTabData?.[activeTab]?.['template-content'];
229
+
230
+ if (templateContent && templateContent.trim() !== '') {
231
+ if (isDragDrop) {
232
+ // For Bee editor, update both preview and extract tags
233
+ if (templateContent !== previousBeeContentRef.current) {
234
+
235
+ previousBeeContentRef.current = templateContent;
236
+ setBeeContent(templateContent);
237
+ setPreviewDataHtml({
238
+ resolvedBody: templateContent,
239
+ resolvedTitle: formData['template-subject'] || ''
240
+ });
241
+
242
+ // Extract tags with latest content
243
+ const payloadContent = convert(templateContent, GLOBAL_CONVERT_OPTIONS);
244
+ actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
245
+ }
246
+ } else {
247
+ // For CKEditor, always update preview and extract tags with latest content
248
+ setPreviewDataHtml({
249
+ resolvedBody: templateContent,
250
+ resolvedTitle: formData['template-subject'] || ''
251
+ });
252
+
253
+ // Extract tags with latest content
254
+ const payloadContent = convert(templateContent, GLOBAL_CONVERT_OPTIONS);
255
+ actions.extractTagsRequested(formData['template-subject'] || '', payloadContent);
256
+ }
257
+ }
258
+ }, [formData, currentTab]);
259
+
260
+ // Cleanup effect to reset ref when slidebox closes
261
+ useEffect(() => {
262
+ if (!show) {
263
+ previousBeeContentRef.current = '';
264
+ setBeeContent('');
265
+ setPreviewDataHtml('');
266
+ }
267
+ }, [show]);
112
268
 
113
269
  useEffect(() => {
114
270
  if (previewData) {
@@ -281,15 +437,58 @@ const TestAndPreviewSlidebox = (props) => {
281
437
  };
282
438
 
283
439
  // Handle update preview
284
- const handleUpdatePreview = () => {
285
- const payload = {
286
- channel: EMAIL,
287
- messageTitle: formData['template-subject'],
288
- messageBody: content,
289
- resolvedTags: customValues,
290
- userId: selectedCustomer?.customerId,
291
- };
292
- actions.updatePreviewRequested(payload);
440
+ const handleUpdatePreview = async () => {
441
+ try {
442
+ // Store current values to prevent loss during update
443
+ const currentCustomValues = { ...customValues };
444
+
445
+ const currentTabData = formData[currentTab - 1];
446
+ const activeTab = currentTabData?.activeTab;
447
+ const isDragDrop = currentTabData?.[activeTab]?.is_drag_drop;
448
+
449
+ // For BEE editor, ensure content is saved first
450
+ if (isDragDrop && beeInstance) {
451
+ // Trigger save to ensure latest content
452
+ beeInstance.save();
453
+
454
+ // Wait a bit for save to complete and formData to update
455
+ await new Promise((resolve) => setTimeout(resolve, 500));
456
+
457
+ // Get latest content from formData
458
+ const updatedContent = formData[currentTab - 1]?.[activeTab]?.['template-content'];
459
+ const payload = {
460
+ channel: EMAIL,
461
+ messageTitle: formData['template-subject'],
462
+ messageBody: updatedContent || getCurrentContent,
463
+ resolvedTags: currentCustomValues, // Use stored values
464
+ userId: selectedCustomer?.customerId,
465
+ };
466
+
467
+ await actions.updatePreviewRequested(payload);
468
+ return;
469
+ }
470
+
471
+ // For CKEditor, get latest content directly from formData
472
+ const templateContent = currentTabData?.[activeTab]?.['template-content'];
473
+ if (templateContent) {
474
+ // Create payload for CKEditor preview update
475
+ const payload = {
476
+ channel: EMAIL,
477
+ messageTitle: formData['template-subject'],
478
+ messageBody: templateContent,
479
+ resolvedTags: currentCustomValues,
480
+ userId: selectedCustomer?.customerId,
481
+ };
482
+
483
+ // Use the same update preview action for both editors
484
+ await actions.updatePreviewRequested(payload);
485
+ }
486
+ } catch (error) {
487
+ console.error('Error updating preview:', error);
488
+ CapNotification.error({
489
+ message: formatMessage(messages.previewUpdateError),
490
+ });
491
+ }
293
492
  };
294
493
 
295
494
  // Handle extract tags button click
@@ -316,7 +515,7 @@ const TestAndPreviewSlidebox = (props) => {
316
515
  ...INITIAL_PAYLOAD,
317
516
  emailMessageContent: {
318
517
  channel: EMAIL,
319
- messageBody: previewData?.resolvedBody || content,
518
+ messageBody: previewData?.resolvedBody || getCurrentContent,
320
519
  messageSubject: previewData?.resolvedTitle || formData['template-subject'],
321
520
  },
322
521
  }, messageMetaConfigId, (response) => {
@@ -408,7 +607,7 @@ const TestAndPreviewSlidebox = (props) => {
408
607
  formData={formData}
409
608
  isUpdatingPreview={isUpdatingPreview}
410
609
  previewDataHtml={previewDataHtml}
411
- content={content}
610
+ content={getCurrentContent}
412
611
  formatMessage={formatMessage}
413
612
  PreviewChrome={PreviewChrome}
414
613
  />
@@ -548,6 +747,7 @@ TestAndPreviewSlidebox.propTypes = {
548
747
  prefilledValues: PropTypes.object,
549
748
  isSendingTestMessage: PropTypes.bool.isRequired,
550
749
  beeInstance: PropTypes.object.isRequired,
750
+ currentTab: PropTypes.number,
551
751
  };
552
752
 
553
753
  TestAndPreviewSlidebox.defaultProps = {
@@ -555,6 +755,7 @@ TestAndPreviewSlidebox.defaultProps = {
555
755
  currentChannel: EMAIL,
556
756
  messageMetaConfigId: null,
557
757
  prefilledValues: {},
758
+ currentTab: 1,
558
759
  };
559
760
 
560
761
  // Redux connection
@@ -132,18 +132,27 @@ const previewAndTestReducer = (state = initialState, action) => {
132
132
 
133
133
  // Update Preview
134
134
  case UPDATE_PREVIEW_REQUEST:
135
- return state.set('isUpdatingPreview', true)
136
- .set('updatePreviewError', null);
135
+ return state
136
+ .set('isUpdatingPreview', true)
137
+ .set('updatePreviewError', null)
138
+ // Preserve custom values during update
139
+ .set('lastCustomValues', state.get('customValues'));
137
140
 
138
141
  case UPDATE_PREVIEW_SUCCESS:
139
- return state.set('previewData', action.payload.previewData)
142
+ return state
143
+ .set('previewData', action.payload.previewData)
140
144
  .set('isUpdatingPreview', false)
141
- .set('updatePreviewError', null);
145
+ .set('updatePreviewError', null)
146
+ // Restore custom values after successful update
147
+ .set('customValues', state.get('lastCustomValues') || state.get('customValues'));
142
148
 
143
149
  case UPDATE_PREVIEW_FAILURE:
144
- return state.set('previewData', null)
150
+ return state
151
+ .set('previewData', null)
145
152
  .set('isUpdatingPreview', false)
146
- .set('updatePreviewError', action.payload.error);
153
+ .set('updatePreviewError', action.payload.error)
154
+ // Restore custom values after failure
155
+ .set('customValues', fromJS(action.payload.customValues));
147
156
 
148
157
  // Send Test Email
149
158
  case SEND_TEST_MESSAGE_REQUESTED:
@@ -76,14 +76,35 @@ export function* extractTagsSaga(action) {
76
76
  // Update Preview Saga
77
77
  export function* updatePreviewSaga(action) {
78
78
  try {
79
+ // Store custom values before making the API call
80
+ const customValues = action.payload.resolvedTags;
81
+
79
82
  const response = yield call(Api.updateEmailPreview, action.payload);
80
83
  if (response?.data) {
81
- yield put({ type: UPDATE_PREVIEW_SUCCESS, payload: { previewData: response.data } });
84
+ yield put({
85
+ type: UPDATE_PREVIEW_SUCCESS,
86
+ payload: {
87
+ previewData: response.data,
88
+ customValues, // Pass custom values to be preserved
89
+ },
90
+ });
82
91
  } else {
83
- yield put({ type: UPDATE_PREVIEW_FAILURE, payload: { error: response.error || 'Failed to update preview' } });
92
+ yield put({
93
+ type: UPDATE_PREVIEW_FAILURE,
94
+ payload: {
95
+ error: response.error || 'Failed to update preview',
96
+ customValues, // Pass custom values even on failure
97
+ },
98
+ });
84
99
  }
85
100
  } catch (error) {
86
- yield put({ type: UPDATE_PREVIEW_FAILURE, payload: { error: error.message || 'Network error occurred' } });
101
+ yield put({
102
+ type: UPDATE_PREVIEW_FAILURE,
103
+ payload: {
104
+ error: error.message || 'Network error occurred',
105
+ customValues: action.payload.resolvedTags, // Pass custom values on error
106
+ },
107
+ });
87
108
  }
88
109
  }
89
110
 
@@ -91,7 +91,7 @@ describe('PreviewSection', () => {
91
91
  </TestWrapper>
92
92
  );
93
93
 
94
- expect(container.querySelector('.preview-section')).toBeTruthy();
94
+ expect(container.querySelector('.test-and-preview-section')).toBeTruthy();
95
95
  expect(container.querySelector('.panel-section')).toBeTruthy();
96
96
  });
97
97
  });
@@ -105,27 +105,43 @@ describe("previewAndTestReducer", () => {
105
105
  const state = fromJS({
106
106
  isUpdatingPreview: false,
107
107
  updatePreviewError: null,
108
+ customValues: { test: "value" },
108
109
  });
109
110
  const action = { type: UPDATE_PREVIEW_REQUEST };
110
- const expectedResult = state.set("isUpdatingPreview", true).set("updatePreviewError", null);
111
+ const expectedResult = state
112
+ .set("isUpdatingPreview", true)
113
+ .set("updatePreviewError", null)
114
+ .set("lastCustomValues", state.get("customValues"));
111
115
  expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
112
116
  });
113
117
  it("should handle UPDATE_PREVIEW_SUCCESS action", () => {
118
+ const customValues = fromJS({ test: "value" });
114
119
  const state = fromJS({
115
120
  isUpdatingPreview: false,
116
121
  updatePreviewError: null,
122
+ lastCustomValues: customValues,
117
123
  });
118
- const action = { type: UPDATE_PREVIEW_SUCCESS, payload: { previewData: "test" } };
119
- const expectedResult = state.set("isUpdatingPreview", false).set("updatePreviewError", null).set("previewData", "test");
124
+ const action = { type: UPDATE_PREVIEW_SUCCESS, payload: { previewData: "test", customValues: customValues.toJS() } };
125
+ const expectedResult = state
126
+ .set("isUpdatingPreview", false)
127
+ .set("updatePreviewError", null)
128
+ .set("previewData", "test")
129
+ .set("customValues", customValues);
120
130
  expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
121
131
  });
122
132
  it("should handle UPDATE_PREVIEW_FAILURE action", () => {
133
+ const customValues = fromJS({ test: "value" });
123
134
  const state = fromJS({
124
135
  isUpdatingPreview: false,
125
136
  updatePreviewError: null,
137
+ lastCustomValues: customValues,
126
138
  });
127
- const action = { type: UPDATE_PREVIEW_FAILURE, payload: { error: "Update preview failed" } };
128
- const expectedResult = state.set("isUpdatingPreview", false).set("updatePreviewError", "Update preview failed").set("previewData", null);
139
+ const action = { type: UPDATE_PREVIEW_FAILURE, payload: { error: "Update preview failed", customValues: customValues.toJS() } };
140
+ const expectedResult = state
141
+ .set("isUpdatingPreview", false)
142
+ .set("updatePreviewError", "Update preview failed")
143
+ .set("previewData", null)
144
+ .set("customValues", fromJS(action.payload.customValues));
129
145
  expect(previewAndTestReducer(state, action)).toEqual(expectedResult);
130
146
  });
131
147
 
@@ -138,18 +138,21 @@ describe('TestAndPreviewSlidebox Sagas', () => {
138
138
  const mockResponse = {
139
139
  data: 'Test Preview Data',
140
140
  };
141
+ const customValues = { test: 'value' };
141
142
  return expectSaga(sagas.updatePreviewSaga, {
142
143
  payload: {
143
144
  previewData: 'Test Preview Data',
145
+ resolvedTags: customValues,
144
146
  },
145
147
  })
146
148
  .provide([
147
- [call(Api.updateEmailPreview, { previewData: 'Test Preview Data' }), mockResponse],
149
+ [call(Api.updateEmailPreview, { previewData: 'Test Preview Data', resolvedTags: customValues }), mockResponse],
148
150
  ])
149
151
  .put({
150
152
  type: types.UPDATE_PREVIEW_SUCCESS,
151
153
  payload: {
152
154
  previewData: mockResponse.data,
155
+ customValues,
153
156
  },
154
157
  })
155
158
  .run();
@@ -159,18 +162,21 @@ describe('TestAndPreviewSlidebox Sagas', () => {
159
162
  previewData: 'Test Preview Data',
160
163
  error: 'Failed to load preview',
161
164
  };
165
+ const customValues = { test: 'value' };
162
166
  return expectSaga(sagas.updatePreviewSaga, {
163
167
  payload: {
164
168
  previewData: 'Test Preview Data',
169
+ resolvedTags: customValues,
165
170
  },
166
171
  })
167
172
  .provide([
168
- [call(Api.updateEmailPreview, { previewData: 'Test Preview Data' }), mockResponse],
173
+ [call(Api.updateEmailPreview, { previewData: 'Test Preview Data', resolvedTags: customValues }), mockResponse],
169
174
  ])
170
175
  .put({
171
176
  type: types.UPDATE_PREVIEW_FAILURE,
172
177
  payload: {
173
178
  error: 'Failed to load preview',
179
+ customValues,
174
180
  },
175
181
  })
176
182
  .run();
@@ -179,54 +185,63 @@ describe('TestAndPreviewSlidebox Sagas', () => {
179
185
  const mockResponse = {
180
186
  previewData: 'Test Preview Data',
181
187
  };
188
+ const customValues = { test: 'value' };
182
189
  return expectSaga(sagas.updatePreviewSaga, {
183
190
  payload: {
184
191
  previewData: 'Test Preview Data',
192
+ resolvedTags: customValues,
185
193
  },
186
194
  })
187
195
  .provide([
188
- [call(Api.updateEmailPreview, { previewData: 'Test Preview Data' }), mockResponse],
196
+ [call(Api.updateEmailPreview, { previewData: 'Test Preview Data', resolvedTags: customValues }), mockResponse],
189
197
  ])
190
198
  .put({
191
199
  type: types.UPDATE_PREVIEW_FAILURE,
192
200
  payload: {
193
201
  error: 'Failed to update preview',
202
+ customValues,
194
203
  },
195
204
  })
196
205
  .run();
197
206
  });
198
207
  it('should handle error in updatePreviewSaga', () => {
199
208
  const error = new Error('Preview update failed');
209
+ const customValues = { test: 'value' };
200
210
  return expectSaga(sagas.updatePreviewSaga, {
201
211
  payload: {
202
212
  previewData: 'Test Preview Data',
213
+ resolvedTags: customValues,
203
214
  },
204
215
  })
205
216
  .provide([
206
- [call(Api.updateEmailPreview, { previewData: 'Test Preview Data' }), throwError(error)],
217
+ [call(Api.updateEmailPreview, { previewData: 'Test Preview Data', resolvedTags: customValues }), throwError(error)],
207
218
  ])
208
219
  .put({
209
220
  type: types.UPDATE_PREVIEW_FAILURE,
210
221
  payload: {
211
222
  error: error.message,
223
+ customValues,
212
224
  },
213
225
  })
214
226
  .run();
215
227
  });
216
228
  it('should handle error in updatePreviewSaga', () => {
217
229
  const error = 'Preview update failed';
230
+ const customValues = { test: 'value' };
218
231
  return expectSaga(sagas.updatePreviewSaga, {
219
232
  payload: {
220
233
  previewData: 'Test Preview Data',
234
+ resolvedTags: customValues,
221
235
  },
222
236
  })
223
237
  .provide([
224
- [call(Api.updateEmailPreview, { previewData: 'Test Preview Data' }), throwError(error)],
238
+ [call(Api.updateEmailPreview, { previewData: 'Test Preview Data', resolvedTags: customValues }), throwError(error)],
225
239
  ])
226
240
  .put({
227
241
  type: types.UPDATE_PREVIEW_FAILURE,
228
242
  payload: {
229
243
  error: 'Network error occurred',
244
+ customValues,
230
245
  },
231
246
  })
232
247
  .run();
@@ -36,7 +36,7 @@ import {
36
36
  CREATE_CENTRAL_COMMS_META_ID_REQUEST,
37
37
  } from '../constants';
38
38
  import { callback, error, error2, videoConfigData } from '../../mockdata';
39
- import { LOGOUT_FAILURE, LOGOUT_SUCCESS } from '../../../constants/unified';
39
+ import { LOGOUT_FAILURE, LOGOUT_REQUEST, LOGOUT_SUCCESS } from '../../../containers/Cap/constants';
40
40
 
41
41
 
42
42
 
@@ -163,6 +163,7 @@ export function SlideBoxContent(props) {
163
163
  showTestAndPreviewSlidebox,
164
164
  handleTestAndPreview,
165
165
  handleCloseTestAndPreview,
166
+ isTestAndPreviewMode,
166
167
  } = props;
167
168
  const type = (messageDetails.type || '').toLowerCase(); // type is context in get tags values : outbound | dvs | referral | loyalty | coupons
168
169
  const query = { type: !isFullMode && 'embedded', module: isFullMode ? 'default' : 'library', isEditFromCampaigns: (templateData || {}).isEditFromCampaigns};
@@ -594,7 +595,7 @@ export function SlideBoxContent(props) {
594
595
  />
595
596
  )}
596
597
 
597
- {isEmailCreate && (
598
+ {isEmailCreate && (
598
599
  <EmailWrapper
599
600
  key="creatives-email-wrapper"
600
601
  date={new Date().getMilliseconds()}
@@ -626,7 +627,8 @@ export function SlideBoxContent(props) {
626
627
  isLoyaltyModule={isLoyaltyModule}
627
628
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
628
629
  handleTestAndPreview={handleTestAndPreview}
629
- handleCloseTestAndPreview={handleCloseTestAndPreview}
630
+ handleCloseTestAndPreview={handleCloseTestAndPreview}
631
+ isTestAndPreviewMode={isTestAndPreviewMode}
630
632
  />
631
633
  )}
632
634
  {(isEditEmailWithId || isEmailEditWithContent) && (
@@ -660,6 +662,9 @@ export function SlideBoxContent(props) {
660
662
  showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
661
663
  handleTestAndPreview={handleTestAndPreview}
662
664
  handleCloseTestAndPreview={handleCloseTestAndPreview}
665
+ isTestAndPreviewMode={(() => {
666
+ return isTestAndPreviewMode;
667
+ })()}
663
668
  />
664
669
  )}
665
670
  {isEditMPush && (
@@ -1055,6 +1060,7 @@ SlideBoxContent.propTypes = {
1055
1060
  hostName: PropTypes.string,
1056
1061
  showTestAndPreviewSlidebox: PropTypes.bool,
1057
1062
  handleTestAndPreview: PropTypes.func,
1058
- handleCloseTestAndPreview: PropTypes.func
1063
+ handleCloseTestAndPreview: PropTypes.func,
1064
+ isTestAndPreviewMode: PropTypes.bool
1059
1065
  };
1060
1066
  export default SlideBoxContent;