@capillarytech/creatives-library 8.0.242-alpha.0 → 8.0.242-alpha.10

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 (216) hide show
  1. package/assets/Android.png +0 -0
  2. package/assets/iOS.png +0 -0
  3. package/constants/unified.js +2 -1
  4. package/initialReducer.js +2 -0
  5. package/package.json +1 -1
  6. package/sagas/__tests__/assetPolling.test.js +74 -3
  7. package/sagas/assetPolling.js +8 -1
  8. package/services/api.js +10 -5
  9. package/services/tests/api.test.js +18 -0
  10. package/translations/en.json +0 -1
  11. package/utils/common.js +5 -0
  12. package/utils/commonUtils.js +14 -1
  13. package/utils/tests/commonUtil.test.js +224 -0
  14. package/utils/transformTemplateConfig.js +0 -10
  15. package/utils/transformerUtils.js +0 -42
  16. package/v2Components/CapDeviceContent/index.js +61 -56
  17. package/v2Components/CapImageUpload/constants.js +0 -2
  18. package/v2Components/CapImageUpload/index.js +14 -54
  19. package/v2Components/CapImageUpload/index.scss +1 -4
  20. package/v2Components/CapImageUpload/messages.js +0 -4
  21. package/v2Components/CapTagList/index.js +6 -1
  22. package/v2Components/CapTagListWithInput/index.js +5 -1
  23. package/v2Components/CapTagListWithInput/messages.js +1 -1
  24. package/v2Components/CapWhatsappCTA/tests/index.test.js +5 -0
  25. package/v2Components/ErrorInfoNote/index.js +412 -72
  26. package/v2Components/ErrorInfoNote/messages.js +22 -0
  27. package/v2Components/ErrorInfoNote/style.scss +279 -2
  28. package/v2Components/HtmlEditor/HTMLEditor.js +220 -91
  29. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +1132 -133
  30. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +17 -12
  31. package/v2Components/HtmlEditor/_htmlEditor.scss +107 -45
  32. package/v2Components/HtmlEditor/_index.lazy.scss +1 -1
  33. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +13 -101
  34. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +148 -139
  35. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +2 -1
  36. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
  37. package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +9 -0
  38. package/v2Components/HtmlEditor/components/EditorToolbar/index.js +1 -1
  39. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +22 -0
  40. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +4 -7
  41. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +35 -45
  42. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +1 -3
  43. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
  44. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +7 -6
  45. package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +3 -6
  46. package/v2Components/HtmlEditor/components/PreviewPane/index.js +10 -11
  47. package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
  48. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +70 -72
  49. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +49 -31
  50. package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +254 -0
  51. package/v2Components/HtmlEditor/components/ValidationTabs/index.js +362 -0
  52. package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +51 -0
  53. package/v2Components/HtmlEditor/constants.js +29 -20
  54. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +373 -16
  55. package/v2Components/HtmlEditor/hooks/useEditorContent.js +5 -2
  56. package/v2Components/HtmlEditor/hooks/useInAppContent.js +88 -146
  57. package/v2Components/HtmlEditor/index.js +1 -1
  58. package/v2Components/HtmlEditor/messages.js +95 -85
  59. package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +99 -101
  60. package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +23 -25
  61. package/v2Components/HtmlEditor/utils/validationAdapter.js +34 -41
  62. package/v2Components/MobilePushPreviewV2/index.js +32 -7
  63. package/v2Components/TemplatePreview/_templatePreview.scss +44 -24
  64. package/v2Components/TemplatePreview/index.js +47 -32
  65. package/v2Components/TemplatePreview/messages.js +4 -0
  66. package/v2Components/TestAndPreviewSlidebox/index.js +31 -25
  67. package/v2Containers/App/constants.js +0 -5
  68. package/v2Containers/BeeEditor/index.js +82 -80
  69. package/v2Containers/BeePopupEditor/constants.js +10 -0
  70. package/v2Containers/BeePopupEditor/index.js +193 -0
  71. package/v2Containers/BeePopupEditor/tests/index.test.js +627 -0
  72. package/v2Containers/Cap/tests/__snapshots__/index.test.js.snap +0 -1
  73. package/v2Containers/CreativesContainer/SlideBoxContent.js +148 -120
  74. package/v2Containers/CreativesContainer/SlideBoxFooter.js +9 -3
  75. package/v2Containers/CreativesContainer/SlideBoxHeader.js +2 -2
  76. package/v2Containers/CreativesContainer/constants.js +1 -2
  77. package/v2Containers/CreativesContainer/index.js +173 -193
  78. package/v2Containers/CreativesContainer/messages.js +4 -4
  79. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +38 -50
  80. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +36 -0
  81. package/v2Containers/Email/actions.js +7 -0
  82. package/v2Containers/Email/constants.js +5 -1
  83. package/v2Containers/Email/index.js +13 -0
  84. package/v2Containers/Email/messages.js +32 -0
  85. package/v2Containers/Email/reducer.js +12 -1
  86. package/v2Containers/Email/sagas.js +41 -6
  87. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +2 -0
  88. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +1046 -0
  89. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +193 -7
  90. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +40 -74
  91. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +2 -67
  92. package/v2Containers/EmailWrapper/constants.js +2 -0
  93. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +436 -67
  94. package/v2Containers/EmailWrapper/index.js +99 -23
  95. package/v2Containers/EmailWrapper/messages.js +61 -1
  96. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +111 -77
  97. package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +376 -0
  98. package/v2Containers/InApp/__tests__/sagas.test.js +363 -0
  99. package/v2Containers/InApp/actions.js +7 -0
  100. package/v2Containers/InApp/constants.js +20 -4
  101. package/v2Containers/InApp/index.js +801 -357
  102. package/v2Containers/InApp/index.scss +4 -3
  103. package/v2Containers/InApp/messages.js +7 -3
  104. package/v2Containers/InApp/reducer.js +21 -3
  105. package/v2Containers/InApp/sagas.js +29 -9
  106. package/v2Containers/InApp/selectors.js +25 -5
  107. package/v2Containers/InApp/tests/index.test.js +154 -50
  108. package/v2Containers/InApp/tests/reducer.test.js +34 -0
  109. package/v2Containers/InApp/tests/sagas.test.js +61 -9
  110. package/v2Containers/InApp/tests/selectors.test.js +612 -0
  111. package/v2Containers/InAppWrapper/components/InAppWrapperView.js +162 -0
  112. package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +267 -0
  113. package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +9 -0
  114. package/v2Containers/InAppWrapper/constants.js +16 -0
  115. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +473 -0
  116. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +198 -0
  117. package/v2Containers/InAppWrapper/index.js +148 -0
  118. package/v2Containers/InAppWrapper/messages.js +49 -0
  119. package/v2Containers/InappAdvance/index.js +1099 -0
  120. package/v2Containers/InappAdvance/index.scss +10 -0
  121. package/v2Containers/InappAdvance/tests/index.test.js +448 -0
  122. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +3 -3
  123. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +2 -2
  124. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +2 -25
  125. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +9 -18
  126. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +12 -46
  127. package/v2Containers/SmsTrai/Create/tests/__snapshots__/index.test.js.snap +0 -4
  128. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4 -8
  129. package/v2Containers/TagList/index.js +67 -1
  130. package/v2Containers/Templates/ChannelTypeIllustration.js +1 -13
  131. package/v2Containers/Templates/_templates.scss +56 -200
  132. package/v2Containers/Templates/actions.js +1 -2
  133. package/v2Containers/Templates/constants.js +0 -1
  134. package/v2Containers/Templates/index.js +124 -277
  135. package/v2Containers/Templates/messages.js +4 -24
  136. package/v2Containers/Templates/reducer.js +0 -2
  137. package/v2Containers/Templates/tests/index.test.js +0 -10
  138. package/v2Containers/TemplatesV2/index.js +2 -3
  139. package/v2Containers/TemplatesV2/messages.js +0 -4
  140. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +35 -132
  141. package/v2Components/CapImageUrlUpload/constants.js +0 -19
  142. package/v2Components/CapImageUrlUpload/index.js +0 -455
  143. package/v2Components/CapImageUrlUpload/index.scss +0 -35
  144. package/v2Components/CapImageUrlUpload/messages.js +0 -47
  145. package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +0 -214
  146. package/v2Containers/WebPush/Create/components/ButtonForm.js +0 -175
  147. package/v2Containers/WebPush/Create/components/ButtonItem.js +0 -101
  148. package/v2Containers/WebPush/Create/components/ButtonList.js +0 -144
  149. package/v2Containers/WebPush/Create/components/_buttons.scss +0 -246
  150. package/v2Containers/WebPush/Create/components/tests/ButtonForm.test.js +0 -554
  151. package/v2Containers/WebPush/Create/components/tests/ButtonItem.test.js +0 -607
  152. package/v2Containers/WebPush/Create/components/tests/ButtonList.test.js +0 -633
  153. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonForm.test.js.snap +0 -666
  154. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonItem.test.js.snap +0 -74
  155. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonList.test.js.snap +0 -80
  156. package/v2Containers/WebPush/Create/index.js +0 -1755
  157. package/v2Containers/WebPush/Create/index.scss +0 -123
  158. package/v2Containers/WebPush/Create/messages.js +0 -199
  159. package/v2Containers/WebPush/Create/preview/DevicePreviewContent.js +0 -241
  160. package/v2Containers/WebPush/Create/preview/NotificationContainer.js +0 -290
  161. package/v2Containers/WebPush/Create/preview/PreviewContent.js +0 -81
  162. package/v2Containers/WebPush/Create/preview/PreviewControls.js +0 -240
  163. package/v2Containers/WebPush/Create/preview/PreviewDisclaimer.js +0 -23
  164. package/v2Containers/WebPush/Create/preview/WebPushPreview.js +0 -144
  165. package/v2Containers/WebPush/Create/preview/assets/Light.svg +0 -53
  166. package/v2Containers/WebPush/Create/preview/assets/Top.svg +0 -5
  167. package/v2Containers/WebPush/Create/preview/assets/chrome-icon.png +0 -0
  168. package/v2Containers/WebPush/Create/preview/assets/edge-icon.png +0 -0
  169. package/v2Containers/WebPush/Create/preview/assets/firefox-icon.svg +0 -106
  170. package/v2Containers/WebPush/Create/preview/assets/iOS.svg +0 -26
  171. package/v2Containers/WebPush/Create/preview/assets/opera-icon.svg +0 -18
  172. package/v2Containers/WebPush/Create/preview/assets/safari-icon.svg +0 -29
  173. package/v2Containers/WebPush/Create/preview/components/AndroidMobileChromeHeader.js +0 -44
  174. package/v2Containers/WebPush/Create/preview/components/AndroidMobileExpanded.js +0 -110
  175. package/v2Containers/WebPush/Create/preview/components/IOSHeader.js +0 -45
  176. package/v2Containers/WebPush/Create/preview/components/NotificationExpandedContent.js +0 -72
  177. package/v2Containers/WebPush/Create/preview/components/NotificationHeader.js +0 -55
  178. package/v2Containers/WebPush/Create/preview/components/WindowsChromeExpanded.js +0 -70
  179. package/v2Containers/WebPush/Create/preview/components/tests/AndroidMobileExpanded.test.js +0 -512
  180. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/AndroidMobileExpanded.test.js.snap +0 -77
  181. package/v2Containers/WebPush/Create/preview/config/notificationMappings.js +0 -527
  182. package/v2Containers/WebPush/Create/preview/constants.js +0 -162
  183. package/v2Containers/WebPush/Create/preview/notification-container.scss +0 -104
  184. package/v2Containers/WebPush/Create/preview/preview.scss +0 -409
  185. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-chrome.scss +0 -300
  186. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-edge.scss +0 -12
  187. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-firefox.scss +0 -12
  188. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-opera.scss +0 -12
  189. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-chrome.scss +0 -303
  190. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-edge.scss +0 -11
  191. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-firefox.scss +0 -11
  192. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-opera.scss +0 -11
  193. package/v2Containers/WebPush/Create/preview/styles/_base.scss +0 -188
  194. package/v2Containers/WebPush/Create/preview/styles/_ios.scss +0 -106
  195. package/v2Containers/WebPush/Create/preview/styles/_ipados.scss +0 -107
  196. package/v2Containers/WebPush/Create/preview/styles/_macos-chrome.scss +0 -75
  197. package/v2Containers/WebPush/Create/preview/styles/_windows-chrome.scss +0 -174
  198. package/v2Containers/WebPush/Create/preview/tests/DevicePreviewContent.test.js +0 -909
  199. package/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +0 -1077
  200. package/v2Containers/WebPush/Create/preview/tests/PreviewControls.test.js +0 -723
  201. package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +0 -943
  202. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/DevicePreviewContent.test.js.snap +0 -128
  203. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/NotificationContainer.test.js.snap +0 -121
  204. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/PreviewControls.test.js.snap +0 -144
  205. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/WebPushPreview.test.js.snap +0 -127
  206. package/v2Containers/WebPush/Create/utils/urlValidation.js +0 -116
  207. package/v2Containers/WebPush/Create/utils/urlValidation.test.js +0 -449
  208. package/v2Containers/WebPush/actions.js +0 -60
  209. package/v2Containers/WebPush/constants.js +0 -108
  210. package/v2Containers/WebPush/index.js +0 -2
  211. package/v2Containers/WebPush/reducer.js +0 -104
  212. package/v2Containers/WebPush/sagas.js +0 -119
  213. package/v2Containers/WebPush/selectors.js +0 -65
  214. package/v2Containers/WebPush/tests/reducer.test.js +0 -863
  215. package/v2Containers/WebPush/tests/sagas.test.js +0 -566
  216. package/v2Containers/WebPush/tests/selectors.test.js +0 -960
@@ -1,16 +1,19 @@
1
- import { useState, useEffect, useMemo, useCallback } from 'react';
1
+ import React, {
2
+ useState, useEffect, useMemo, useCallback, useRef,
3
+ } from 'react';
2
4
  import isEmpty from 'lodash/isEmpty';
3
- import get from 'lodash/get';
4
5
  import find from 'lodash/find';
6
+ import get from 'lodash/get';
5
7
  import { GA } from '@capillarytech/cap-ui-utils';
6
8
  import CapNotification from '@capillarytech/cap-ui-library/CapNotification';
9
+ import CapIcon from '@capillarytech/cap-ui-library/CapIcon';
7
10
  import { CHANNEL_CREATE_TRACK_MAPPING } from '../../App/constants';
8
11
  import { gtmPush } from '../../../utils/gtmTrackers';
9
12
  import { EMAIL } from '../../CreativesContainer/constants';
10
13
  import messages from '../messages';
11
- import { STEPS } from '../constants';
12
- import { EMAIL_CREATE_MODES } from '../constants';
14
+ import { STEPS, EMAIL_CREATE_MODES } from '../constants';
13
15
  import { containsBase64Images } from '../../../utils/content';
16
+ import { hasSupportCKEditor } from '../../../utils/common';
14
17
 
15
18
  /**
16
19
  * Custom hook to handle EmailWrapper component business logic
@@ -56,12 +59,21 @@ const useEmailWrapper = ({
56
59
  handleTestAndPreview,
57
60
  handleCloseTestAndPreview,
58
61
  isTestAndPreviewMode,
62
+ // Props for BEE enabled check
63
+ location,
64
+ emailActions,
65
+ Email,
66
+ templateData,
67
+ params,
59
68
  }) => {
60
69
  // State management
61
70
  const [templateName, setTemplateName] = useState('');
62
71
  const [isTemplateNameEmpty, setIsTemplateNameEmpty] = useState(true);
63
72
  const [selectedCreateMode, setSelectedCreateMode] = useState('');
64
73
  const [modeContent, setModeContent] = useState({});
74
+ const [isBeeEditorEnabled, setIsBeeEditorEnabled] = useState(null); // null = not checked yet, true/false = checked
75
+ const beeStatusCheckRef = useRef(false); // Track if we've made the API call for current step
76
+ const defaultTemplatesFetchedRef = useRef(false);
65
77
  const [routeParams] = useState({
66
78
  pathname: `/email/create`,
67
79
  query: { module: 'library', type: 'embedded' },
@@ -76,7 +88,7 @@ const useEmailWrapper = ({
76
88
  }, [onResetStep, templatesActions]);
77
89
 
78
90
  // Event handlers
79
- const onTemplateNameChange = useCallback(({target: {value}}) => {
91
+ const onTemplateNameChange = useCallback(({ target: { value } }) => {
80
92
  const isEmptyTemplateName = !value?.trim();
81
93
  setTemplateName(value);
82
94
  setIsTemplateNameEmpty(isEmptyTemplateName);
@@ -88,9 +100,123 @@ const useEmailWrapper = ({
88
100
  }
89
101
  }, [onEnterTemplateName, onRemoveTemplateName]);
90
102
 
103
+ // Check BEE enabled status from API response
104
+ // BEE is enabled if isDragDrop is true in the API response
105
+ // This should work for both full mode and library mode
106
+ const checkBeeEditorEnabled = useCallback(() => {
107
+ // If we have checked the API and got a response, use that
108
+ if (isBeeEditorEnabled !== null) {
109
+ return isBeeEditorEnabled;
110
+ }
111
+ // If we haven't checked yet, return false (disabled) until API responds
112
+ return false;
113
+ }, [isBeeEditorEnabled]);
114
+
115
+ // Helper function to convert numeric templateStep to string step
116
+ const getStepFromTemplateStep = useCallback((templateStepValue) => {
117
+ // templateStep is numeric: 1 = modeSelection, 2 = templateSelection, 3 = createTemplateContent
118
+ if (typeof templateStepValue === 'number') {
119
+ switch (templateStepValue) {
120
+ case 1:
121
+ return STEPS.MODE_SELECTION;
122
+ case 2:
123
+ return STEPS.TEMPLATE_SELECTION;
124
+ case 3:
125
+ return STEPS.CREATE_TEMPLATE_CONTENT;
126
+ default:
127
+ return STEPS.MODE_SELECTION;
128
+ }
129
+ }
130
+ // If it's already a string, return as-is
131
+ return templateStepValue || STEPS.MODE_SELECTION;
132
+ }, []);
133
+
134
+ // Convert step to string format if it's numeric
135
+ const currentStep = useMemo(() => getStepFromTemplateStep(step), [step, getStepFromTemplateStep]);
136
+
137
+ // Effect to check BEE enabled status via new API when entering MODE_SELECTION step
138
+ useEffect(() => {
139
+ const supportCKEditor = hasSupportCKEditor();
140
+ // Only check BEE enabled status for new flow (when supportCKEditor is false)
141
+ // Reset the ref when step changes to MODE_SELECTION to allow API call
142
+ if (currentStep === STEPS.MODE_SELECTION) {
143
+ beeStatusCheckRef.current = false;
144
+ }
145
+
146
+ // Only check BEE enabled status for new flow (when supportCKEditor is false)
147
+ // Check all conditions
148
+ const shouldMakeCall = !supportCKEditor
149
+ && currentStep === STEPS.MODE_SELECTION
150
+ && !beeStatusCheckRef.current
151
+ && emailActions;
152
+
153
+ if (shouldMakeCall) {
154
+ // Mark that we've made the API call
155
+ beeStatusCheckRef.current = true;
156
+
157
+ // Make API call to check BEE enabled status using new endpoint
158
+ emailActions.getCmsAccounts('BEE_PLUGIN');
159
+ }
160
+ }, [currentStep, emailActions]);
161
+
162
+ // Effect to update isBeeEditorEnabled based on new API response
163
+ // This effect watches for isBeeEnabled from the new API response
164
+ useEffect(() => {
165
+ // Only process if we're in MODE_SELECTION step (when we're checking BEE status)
166
+ // Also check if we've made the API call (beeStatusCheckRef.current === true)
167
+ if (currentStep === STEPS.MODE_SELECTION && beeStatusCheckRef.current) {
168
+ // Use isBeeEnabled from the new API response
169
+ if (Email?.isBeeEnabled !== undefined) {
170
+ setIsBeeEditorEnabled(Email.isBeeEnabled);
171
+ }
172
+ }
173
+ // If API call fails, treat as disabled
174
+ if (Email?.fetchingCmsAccountsError && beeStatusCheckRef.current) {
175
+ setIsBeeEditorEnabled(false);
176
+ }
177
+ }, [Email?.isBeeEnabled, Email?.fetchingCmsAccountsError, currentStep]);
178
+
91
179
  const onChange = useCallback((e) => {
92
- onEmailModeChange(e.target.value);
93
- }, [onEmailModeChange]);
180
+ const { target: { value } } = e;
181
+ // Prevent selection if Drag & Drop is selected but BEE editor is not enabled
182
+ if (value === EMAIL_CREATE_MODES.DRAG_DROP && !checkBeeEditorEnabled()) {
183
+ return; // Ignore selection if BEE editor is disabled
184
+ }
185
+
186
+ // CRITICAL: When DRAG_DROP is selected, set selectedCreateMode to DRAG_DROP
187
+ // This ensures emailProps will have editor: 'BEE' and selectedEditorMode: null
188
+ if (value === EMAIL_CREATE_MODES.DRAG_DROP) {
189
+ setSelectedCreateMode(EMAIL_CREATE_MODES.DRAG_DROP);
190
+ } else {
191
+ setSelectedCreateMode(value);
192
+ }
193
+
194
+ const supportCKEditor = hasSupportCKEditor();
195
+
196
+ // Map new modes to existing modes for backwards compatibility
197
+ let mappedValue = value;
198
+
199
+ if (!supportCKEditor) {
200
+ // New flow: Handle HTML Editor, Drag & Drop, and Upload Zip
201
+ // Don't auto-navigate - wait for Next button click
202
+ if (value === EMAIL_CREATE_MODES.HTML_EDITOR) {
203
+ // HTML Editor: Map to EDITOR but skip template selection
204
+ mappedValue = EMAIL_CREATE_MODES.EDITOR;
205
+ setModeContent({ skipTemplateSelection: true });
206
+ } else if (value === EMAIL_CREATE_MODES.DRAG_DROP) {
207
+ // Drag & Drop: Map to EDITOR and show template selection
208
+ mappedValue = EMAIL_CREATE_MODES.EDITOR;
209
+ } else if (value === EMAIL_CREATE_MODES.UPLOAD) {
210
+ // Upload Zip: Keep as UPLOAD
211
+ mappedValue = EMAIL_CREATE_MODES.UPLOAD;
212
+ }
213
+ } else if (value === EMAIL_CREATE_MODES.EDITOR && showNextStep) {
214
+ // Legacy flow: Auto-navigate immediately (existing behavior)
215
+ showNextStep();
216
+ }
217
+
218
+ onEmailModeChange(mappedValue, value); // Pass both mapped value and original selected mode
219
+ }, [onEmailModeChange, showNextStep, checkBeeEditorEnabled]);
94
220
 
95
221
  const handleZipUploadError = useCallback(() => {
96
222
  const message = {
@@ -194,8 +320,12 @@ const useEmailWrapper = ({
194
320
  const data = find(CmsTemplates, { _id: id });
195
321
  templatesActions.setEdmTemplate(data);
196
322
  templatesActions.setBEETemplate(data);
197
- setSelectedCreateMode(EMAIL_CREATE_MODES.EDITOR);
198
- }, [CmsTemplates, templatesActions]);
323
+ // Don't override selectedCreateMode - preserve DRAG_DROP or EDITOR mode
324
+ // Only set if not already set
325
+ if (!selectedCreateMode) {
326
+ setSelectedCreateMode(EMAIL_CREATE_MODES.EDITOR);
327
+ }
328
+ }, [CmsTemplates, templatesActions, selectedCreateMode]);
199
329
 
200
330
  const useFileUpload = useCallback(({ file }) => {
201
331
  setModeContent({});
@@ -209,41 +339,73 @@ const useEmailWrapper = ({
209
339
 
210
340
  // Main logic effect - MOVED AFTER function declarations
211
341
  useEffect(() => {
212
- // Skip if user has already made a selection
213
- if (selectedCreateMode) return;
342
+ const supportCKEditor = hasSupportCKEditor();
214
343
 
215
344
  // Handle different steps
216
- switch (step) {
345
+ switch (currentStep) {
217
346
  case STEPS.MODE_SELECTION:
218
347
  if (emailCreateMode === EMAIL_CREATE_MODES.UPLOAD && !EmailLayout) {
219
348
  // Commented out: document.getElementById('upload-email-template').click();
220
349
  }
221
350
  break;
222
351
 
223
- case STEPS.TEMPLATE_SELECTION:
224
- const needsTemplates = emailCreateMode === EMAIL_CREATE_MODES.EDITOR
225
- && !CmsTemplates
226
- && !getCmsTemplatesInProgress;
352
+ case STEPS.TEMPLATE_SELECTION: {
353
+ // Template selection is needed for:
354
+ // 1. Legacy EDITOR mode (when supportCKEditor is true)
355
+ // 2. New DRAG_DROP mode (when supportCKEditor is false)
356
+ // NOT needed for HTML_EDITOR (goes directly to editor)
357
+
358
+ let needsTemplates = false;
359
+ if (supportCKEditor) {
360
+ // Legacy flow: only for EDITOR mode
361
+ needsTemplates = emailCreateMode === EMAIL_CREATE_MODES.EDITOR
362
+ && !CmsTemplates
363
+ && !getCmsTemplatesInProgress;
364
+ } else {
365
+ // New flow: for DRAG_DROP only (not HTML_EDITOR)
366
+ needsTemplates = selectedCreateMode === EMAIL_CREATE_MODES.DRAG_DROP
367
+ && !CmsTemplates
368
+ && !getCmsTemplatesInProgress;
369
+ }
227
370
 
228
- if (needsTemplates) {
371
+ if (needsTemplates && !defaultTemplatesFetchedRef.current) {
229
372
  templatesActions.getDefaultBeeTemplates();
373
+ defaultTemplatesFetchedRef.current = true;
230
374
  }
231
375
  break;
376
+ }
232
377
 
233
- case STEPS.CREATE_TEMPLATE_CONTENT:
378
+ case STEPS.CREATE_TEMPLATE_CONTENT: {
234
379
  if (emailCreateMode === EMAIL_CREATE_MODES.UPLOAD && !isEmpty(EmailLayout)) {
235
380
  setSelectedCreateMode(EMAIL_CREATE_MODES.UPLOAD);
236
- } else if (emailCreateMode === EMAIL_CREATE_MODES.EDITOR && isEmpty(SelectedEdmDefaultTemplate)) {
237
- handleEdmDefaultTemplateSelection(modeContent.id);
381
+ } else if (emailCreateMode === EMAIL_CREATE_MODES.EDITOR
382
+ || emailCreateMode === EMAIL_CREATE_MODES.DRAG_DROP
383
+ || selectedCreateMode === EMAIL_CREATE_MODES.EDITOR
384
+ || selectedCreateMode === EMAIL_CREATE_MODES.DRAG_DROP) {
385
+ if (!supportCKEditor && selectedCreateMode === EMAIL_CREATE_MODES.HTML_EDITOR) {
386
+ // HTML Editor mode: Skip template selection, go directly to editor
387
+ setSelectedCreateMode(EMAIL_CREATE_MODES.HTML_EDITOR);
388
+ } else if (isEmpty(SelectedEdmDefaultTemplate) && modeContent.id) {
389
+ // Legacy EDITOR or DRAG_DROP: Need template selection
390
+ handleEdmDefaultTemplateSelection(modeContent.id);
391
+ } else if (!supportCKEditor && selectedCreateMode === EMAIL_CREATE_MODES.DRAG_DROP) {
392
+ // CRITICAL: Template already selected for DRAG_DROP - ensure selectedCreateMode is DRAG_DROP
393
+ // This ensures emailProps will have editor: 'BEE' and selectedEditorMode: null
394
+ setSelectedCreateMode(EMAIL_CREATE_MODES.DRAG_DROP);
395
+ } else {
396
+ // Template already selected for legacy EDITOR
397
+ setSelectedCreateMode(EMAIL_CREATE_MODES.EDITOR);
398
+ }
238
399
  }
239
400
  break;
401
+ }
240
402
 
241
403
  default:
242
404
  // No operation for other steps
243
405
  break;
244
406
  }
245
407
  }, [
246
- step,
408
+ currentStep,
247
409
  selectedCreateMode,
248
410
  emailCreateMode,
249
411
  EmailLayout,
@@ -252,58 +414,155 @@ const useEmailWrapper = ({
252
414
  modeContent.id,
253
415
  SelectedEdmDefaultTemplate,
254
416
  templatesActions,
255
- handleEdmDefaultTemplateSelection
417
+ handleEdmDefaultTemplateSelection,
256
418
  ]);
257
419
 
420
+ // CRITICAL: Reset selectedCreateMode when templateData is cleared (new template creation)
421
+ // This ensures that when user creates a new template after editing, selectedCreateMode is reset
422
+ useEffect(() => {
423
+ // If templateData is cleared/null and we're not in edit mode, reset selectedCreateMode
424
+ const hasParamsId = params?.id
425
+ || location?.query?.id
426
+ || location?.params?.id
427
+ || location?.pathname?.includes('/edit/');
428
+ const hasTemplateData = templateData && !isEmpty(templateData);
429
+ const isEditMode = hasParamsId || hasTemplateData;
430
+
431
+ // If we're creating a new template (no templateData and no params.id), reset selectedCreateMode
432
+ // BUT only if we're in MODE_SELECTION step (navigating back to start)
433
+ // DO NOT reset in CREATE_TEMPLATE_CONTENT - that's where we need selectedCreateMode to render the editor!
434
+ // Also DO NOT reset if emailCreateMode is set - it means user has made a selection
435
+ if (!isEditMode && !hasTemplateData && selectedCreateMode && currentStep === STEPS.MODE_SELECTION && !emailCreateMode) {
436
+ // Reset only when returning to MODE_SELECTION step
437
+ // This preserves user selection while in content creation
438
+ setSelectedCreateMode('');
439
+ }
440
+ }, [templateData, params?.id, location?.query?.id, location?.params?.id, location?.pathname, selectedCreateMode, templateName, currentStep, emailCreateMode]);
441
+
258
442
  // Derived state
259
- const isShowEmailCreate = !isEmpty(selectedCreateMode) && (!isEmpty(EmailLayout) || SelectedEdmDefaultTemplate);
443
+ const supportCKEditorFlag = hasSupportCKEditor();
260
444
 
261
- // Memoize static data
262
- const modes = useMemo(() => [
263
- {
264
- title: formatMessage(messages.zipUpload),
265
- content: formatMessage(messages.zipUploadDesc),
266
- value: EMAIL_CREATE_MODES.UPLOAD,
267
- },
268
- {
269
- title: formatMessage(messages.useEditor),
270
- content: formatMessage(messages.useEditorDesc),
271
- value: EMAIL_CREATE_MODES.EDITOR,
272
- },
273
- ], [formatMessage]);
274
-
275
- // Prepare props for Email component
276
- const emailProps = useMemo(() => ({
277
- setIsLoadingContent,
278
- key: "email-create-template",
279
- location: routeParams,
280
- route: { name: 'email' },
281
- params: {},
282
- isGetFormData,
283
- getFormdata,
284
- getFormSubscriptionData: getFormdata,
285
- getDefaultTags: type,
286
- isFullMode,
287
- defaultData: { 'template-name': templateName },
288
- cap,
289
- showTemplateName,
290
- showLiquidErrorInFooter,
291
- onValidationFail,
292
- forwardedTags,
293
- selectedOfferDetails,
294
- onPreviewContentClicked,
295
- onTestContentClicked,
296
- editor,
297
- moduleType,
298
- eventContextTags,
299
- isLoyaltyModule,
300
- showTestAndPreviewSlidebox,
301
- handleTestAndPreview,
302
- handleCloseTestAndPreview,
303
- isTestAndPreviewMode,
304
- }), [
445
+ // Prepare props for Email component - MOVED BEFORE isShowEmailCreate to avoid circular dependency
446
+ const emailProps = useMemo(() => {
447
+ // Determine editor type and mode based on selectedCreateMode
448
+ let editorType = editor;
449
+ let selectedEditorMode = null;
450
+
451
+ if (!supportCKEditorFlag) {
452
+ // CRITICAL: Check selectedCreateMode FIRST to prioritize user's explicit selection
453
+ // This ensures DRAG_DROP selection takes precedence over edit mode detection
454
+ // even if templateDetails persists from a previous template
455
+ if (selectedCreateMode === EMAIL_CREATE_MODES.DRAG_DROP) {
456
+ // CRITICAL: DRAG_DROP mode always uses BEE editor
457
+ // This takes precedence over edit mode detection
458
+ editorType = 'BEE';
459
+ selectedEditorMode = null; // BEE uses existing flow (null indicates BEE editor)
460
+ } else if (selectedCreateMode === EMAIL_CREATE_MODES.HTML_EDITOR) {
461
+ // HTML_EDITOR mode: Always use HTML editor
462
+ editorType = 'HTML';
463
+ selectedEditorMode = EMAIL_CREATE_MODES.HTML_EDITOR;
464
+ } else {
465
+ // Check if we're editing an existing template
466
+ // CRITICAL: Only treat as edit mode if we have params.id (actual edit URL)
467
+ // Don't use templateDetails existence alone, as it might persist from previous template
468
+ const hasParamsId = params?.id || location?.query?.id || location?.params?.id || location?.pathname?.includes('/edit/');
469
+ const hasTemplateDetails = Email?.templateDetails && !isEmpty(Email.templateDetails);
470
+ const hasBEETemplate = Email?.BEETemplate && !isEmpty(Email.BEETemplate);
471
+ // CRITICAL: Only consider it edit mode if we have params.id (actual edit URL)
472
+ // This prevents false edit mode detection when templateDetails persists in Redux from previous template
473
+ const isEditMode = hasParamsId && (hasTemplateDetails || hasBEETemplate);
474
+
475
+ if (isEditMode) {
476
+ // Edit mode: Determine editor based on template data
477
+ // Check if template was created in BEE editor
478
+ const editTemplateData = Email?.templateDetails || Email?.BEETemplate || templateData;
479
+ const isDragDrop = get(editTemplateData, 'versions.base.is_drag_drop', false)
480
+ || get(editTemplateData, 'base.is_drag_drop', false)
481
+ || get(editTemplateData, 'is_drag_drop', false)
482
+ || get(editTemplateData, 'versions.base[0].is_drag_drop', false);
483
+
484
+ // Check if BEE is enabled for org (equivalent to checkBeeEditorAllowedForLibrary)
485
+ // For library mode: BEE is enabled if editor prop is "BEE"
486
+ // For full mode: BEE is always enabled
487
+ const isBeeEnabled = isFullMode || (editor === "BEE" && !isFullMode) || checkBeeEditorEnabled();
488
+
489
+ // If template was created in BEE AND BEE is enabled → open in BEE editor
490
+ // Otherwise → open in HTML editor (fallback)
491
+ // IMPORTANT: When supportCKEditor is false, default to HTML editor unless explicitly BEE
492
+ if (isDragDrop && isBeeEnabled) {
493
+ editorType = 'BEE';
494
+ selectedEditorMode = null; // BEE uses existing flow
495
+ } else {
496
+ // Fallback to HTML editor if BEE not enabled or template not created in BEE
497
+ // This ensures HTML editor is used when supportCKEditor is false
498
+ editorType = 'HTML';
499
+ selectedEditorMode = EMAIL_CREATE_MODES.HTML_EDITOR;
500
+ }
501
+ } else if (selectedCreateMode === EMAIL_CREATE_MODES.EDITOR) {
502
+ // EDITOR mode: Check if selected template is a BEE template
503
+ // When a default template is selected, it's stored in Templates.BEETemplate
504
+ const beeTemplate = Email?.BEETemplate || SelectedEdmDefaultTemplate;
505
+ const isBEETemplate = beeTemplate && (
506
+ get(beeTemplate, 'versions.base.is_drag_drop') === true
507
+ || get(beeTemplate, 'base.is_drag_drop') === true
508
+ || beeTemplate.is_drag_drop === true
509
+ );
510
+
511
+ if (isBEETemplate && checkBeeEditorEnabled()) {
512
+ // Template is BEE and BEE is enabled → use BEE editor
513
+ editorType = 'BEE';
514
+ selectedEditorMode = null; // BEE uses existing flow
515
+ } else {
516
+ // Template is not BEE or BEE is disabled → use HTML editor
517
+ editorType = 'HTML';
518
+ selectedEditorMode = EMAIL_CREATE_MODES.HTML_EDITOR;
519
+ }
520
+ } else {
521
+ // Default: When supportCKEditor is false and no mode selected, use HTML editor
522
+ editorType = 'HTML';
523
+ selectedEditorMode = EMAIL_CREATE_MODES.HTML_EDITOR;
524
+ }
525
+ }
526
+ // UPLOAD mode uses existing editor prop
527
+ }
528
+ // Legacy flow (supportCKEditor is true): Use existing editor prop as-is - no changes
529
+
530
+ return {
531
+ setIsLoadingContent,
532
+ key: "email-create-template",
533
+ location: routeParams,
534
+ route: { name: 'email' },
535
+ params: {},
536
+ isGetFormData,
537
+ getFormdata,
538
+ getFormSubscriptionData: getFormdata,
539
+ getDefaultTags: type,
540
+ isFullMode,
541
+ defaultData: { 'template-name': templateName },
542
+ cap,
543
+ showTemplateName,
544
+ showLiquidErrorInFooter,
545
+ onValidationFail,
546
+ forwardedTags,
547
+ selectedOfferDetails,
548
+ onPreviewContentClicked,
549
+ onTestContentClicked,
550
+ editor: editorType,
551
+ selectedEditorMode, // Pass selected mode to Email component (only for HTML_EDITOR)
552
+ moduleType,
553
+ eventContextTags,
554
+ isLoyaltyModule,
555
+ showTestAndPreviewSlidebox,
556
+ handleTestAndPreview,
557
+ handleCloseTestAndPreview,
558
+ isTestAndPreviewMode,
559
+ };
560
+ }, [
305
561
  setIsLoadingContent,
306
562
  routeParams,
563
+ Email?.BEETemplate,
564
+ SelectedEdmDefaultTemplate,
565
+ checkBeeEditorEnabled,
307
566
  isGetFormData,
308
567
  getFormdata,
309
568
  type,
@@ -325,8 +584,118 @@ const useEmailWrapper = ({
325
584
  handleTestAndPreview,
326
585
  handleCloseTestAndPreview,
327
586
  isTestAndPreviewMode,
587
+ selectedCreateMode,
588
+ supportCKEditorFlag,
589
+ checkBeeEditorEnabled,
590
+ Email,
591
+ location,
592
+ params,
593
+ editor,
594
+ isFullMode,
595
+ templateData,
328
596
  ]);
329
597
 
598
+ const isShowEmailCreate = useMemo(() => {
599
+ // Check if we're in edit mode (templateDetails or BEETemplate exists, or params.id exists)
600
+ const hasTemplateDetails = Email?.templateDetails && !isEmpty(Email.templateDetails);
601
+ const hasBEETemplate = Email?.BEETemplate && !isEmpty(Email.BEETemplate);
602
+ const hasParamsId = params?.id || location?.query?.id || location?.params?.id || location?.pathname?.includes('/edit/');
603
+ const isEditMode = hasTemplateDetails || hasBEETemplate || hasParamsId;
604
+
605
+ // In edit mode with HTML editor (when supportCKEditor is false), always show editor
606
+ if (!supportCKEditorFlag && isEditMode) {
607
+ // Check if it's explicitly BEE editor
608
+ const isExplicitlyBEE = emailCreateMode === EMAIL_CREATE_MODES.DRAG_DROP
609
+ || (emailProps?.editor === 'BEE' && emailProps?.selectedEditorMode === null);
610
+ // If not BEE, show HTML editor
611
+ if (!isExplicitlyBEE) {
612
+ return true;
613
+ }
614
+ }
615
+
616
+ if (!selectedCreateMode) return false;
617
+
618
+ // For HTML Editor (new flow): Always show editor directly without template selection
619
+ // This takes precedence over step check to ensure HTML Editor is shown even if step is temporarily TEMPLATE_SELECTION
620
+ if (!supportCKEditorFlag && selectedCreateMode === EMAIL_CREATE_MODES.HTML_EDITOR) {
621
+ return true;
622
+ }
623
+
624
+ // CRITICAL: For DRAG_DROP mode, show template selection first (CmsTemplatesComponent)
625
+ // Only show editor (Email component with BEE) after template is selected
626
+ if (emailCreateMode === EMAIL_CREATE_MODES.DRAG_DROP || selectedCreateMode === EMAIL_CREATE_MODES.DRAG_DROP) {
627
+ // If we're in TEMPLATE_SELECTION step, show template selection (not email editor)
628
+ if (currentStep === STEPS.TEMPLATE_SELECTION) {
629
+ return false;
630
+ }
631
+ // After template selection, show editor when template is selected
632
+ return !isEmpty(SelectedEdmDefaultTemplate);
633
+ }
634
+
635
+ // If we're in TEMPLATE_SELECTION step, show template selection (not email editor)
636
+ // This applies to legacy Editor modes
637
+ if (currentStep === STEPS.TEMPLATE_SELECTION) {
638
+ return false;
639
+ }
640
+
641
+ // For Upload: Show editor when EmailLayout exists
642
+ if (emailCreateMode === EMAIL_CREATE_MODES.UPLOAD) {
643
+ return !isEmpty(EmailLayout);
644
+ }
645
+
646
+ // For Editor: Show editor when template is selected
647
+ return !isEmpty(SelectedEdmDefaultTemplate);
648
+ }, [currentStep, selectedCreateMode, supportCKEditorFlag, emailCreateMode, EmailLayout, SelectedEdmDefaultTemplate, Email?.templateDetails, Email?.BEETemplate, params?.id, location?.query?.id, location?.params?.id, location?.pathname, emailProps?.editor, emailProps?.selectedEditorMode]);
649
+
650
+ // Memoize static data
651
+ const modes = useMemo(() => {
652
+ const supportCKEditor = hasSupportCKEditor();
653
+ const isBeeEditorEnabledValue = checkBeeEditorEnabled();
654
+
655
+ if (supportCKEditor) {
656
+ // Legacy flow: Show only 2 options (Upload Zip, Use Editor)
657
+ return [
658
+ {
659
+ title: formatMessage(messages.zipUpload),
660
+ content: formatMessage(messages.zipUploadDesc),
661
+ value: EMAIL_CREATE_MODES.UPLOAD,
662
+ },
663
+ {
664
+ title: formatMessage(messages.useEditor),
665
+ content: formatMessage(messages.useEditorDesc),
666
+ value: EMAIL_CREATE_MODES.EDITOR,
667
+ },
668
+ ];
669
+ }
670
+
671
+ // New flow: Show 3 options (HTML Editor, Drag & Drop, Upload Zip)
672
+ return [
673
+ {
674
+ title: formatMessage(messages.htmlEditorTitle),
675
+ content: formatMessage(messages.htmlEditorDesc),
676
+ value: EMAIL_CREATE_MODES.HTML_EDITOR,
677
+ icon: <CapIcon type="code" />,
678
+ },
679
+ {
680
+ title: formatMessage(messages.dragDropEditorTitle),
681
+ content: formatMessage(messages.dragDropEditorDesc),
682
+ value: EMAIL_CREATE_MODES.DRAG_DROP,
683
+ icon: <CapIcon type="draggable" svgProps={{ fill: 'currentColor' }} />,
684
+ disabled: !isBeeEditorEnabledValue,
685
+ tooltipProps: !isBeeEditorEnabledValue ? {
686
+ title: formatMessage(messages.beeEditorDisabledTooltip),
687
+ placement: 'top',
688
+ } : undefined,
689
+ },
690
+ {
691
+ title: formatMessage(messages.uploadZipTitle),
692
+ content: formatMessage(messages.uploadZipDesc),
693
+ value: EMAIL_CREATE_MODES.UPLOAD,
694
+ icon: <CapIcon type="file" />,
695
+ },
696
+ ];
697
+ }, [formatMessage, checkBeeEditorEnabled]);
698
+
330
699
  // Prepare props for CmsTemplatesComponent
331
700
  const cmsTemplatesProps = useMemo(() => ({
332
701
  cmsTemplates: CmsTemplates,