@capillarytech/creatives-library 8.0.263 → 8.0.265
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.
- package/assets/Android.png +0 -0
- package/assets/iOS.png +0 -0
- package/constants/unified.js +1 -3
- package/initialReducer.js +0 -2
- package/package.json +1 -1
- package/services/api.js +0 -15
- package/services/tests/api.test.js +0 -34
- package/tests/integration/TemplateCreation/TemplateCreation.integration.test.js +35 -17
- package/tests/integration/TemplateCreation/api-response.js +1 -31
- package/tests/integration/TemplateCreation/msw-handler.js +0 -2
- package/utils/common.js +0 -11
- package/utils/commonUtils.js +5 -28
- package/utils/tests/commonUtil.test.js +0 -224
- package/utils/tests/transformerUtils.test.js +0 -297
- package/utils/transformTemplateConfig.js +10 -0
- package/utils/transformerUtils.js +0 -40
- package/v2Components/CapDeviceContent/index.js +56 -61
- package/v2Components/CapImageUpload/constants.js +0 -2
- package/v2Components/CapImageUpload/index.js +16 -65
- package/v2Components/CapImageUpload/index.scss +1 -4
- package/v2Components/CapImageUpload/messages.js +1 -5
- package/v2Components/CapTagList/index.js +1 -6
- package/v2Components/CapTagListWithInput/index.js +1 -5
- package/v2Components/CapTagListWithInput/messages.js +1 -1
- package/v2Components/CapWhatsappCTA/tests/index.test.js +0 -5
- package/v2Components/ErrorInfoNote/index.js +72 -402
- package/v2Components/ErrorInfoNote/messages.js +6 -32
- package/v2Components/ErrorInfoNote/style.scss +6 -278
- package/v2Components/FormBuilder/tests/index.test.js +4 -13
- package/v2Components/HtmlEditor/HTMLEditor.js +99 -418
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +133 -1882
- package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +16 -27
- package/v2Components/HtmlEditor/_htmlEditor.scss +45 -108
- package/v2Components/HtmlEditor/_index.lazy.scss +1 -0
- package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +102 -23
- package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +140 -148
- package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +1 -2
- package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
- package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +1 -9
- package/v2Components/HtmlEditor/components/EditorToolbar/index.js +6 -31
- package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +0 -22
- package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +7 -4
- package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +45 -35
- package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +3 -1
- package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
- package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +6 -7
- package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +10 -7
- package/v2Components/HtmlEditor/components/PreviewPane/index.js +43 -22
- package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
- package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +152 -0
- package/v2Components/HtmlEditor/components/ValidationErrorDisplay/_validationErrorDisplay.scss +0 -18
- package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +31 -36
- package/v2Components/HtmlEditor/components/ValidationPanel/_validationPanel.scss +34 -46
- package/v2Components/HtmlEditor/components/ValidationPanel/index.js +46 -52
- package/v2Components/HtmlEditor/constants.js +20 -45
- package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +16 -373
- package/v2Components/HtmlEditor/hooks/__tests__/useValidation.test.js +16 -351
- package/v2Components/HtmlEditor/hooks/useEditorContent.js +2 -5
- package/v2Components/HtmlEditor/hooks/useInAppContent.js +146 -88
- package/v2Components/HtmlEditor/hooks/useValidation.js +56 -213
- package/v2Components/HtmlEditor/index.js +1 -1
- package/v2Components/HtmlEditor/messages.js +94 -102
- package/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +45 -214
- package/v2Components/HtmlEditor/utils/__tests__/validationAdapter.test.js +0 -134
- package/v2Components/HtmlEditor/utils/contentSanitizer.js +41 -40
- package/v2Components/HtmlEditor/utils/htmlValidator.js +72 -71
- package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +124 -158
- package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +25 -23
- package/v2Components/HtmlEditor/utils/validationAdapter.js +41 -66
- package/v2Components/MobilePushPreviewV2/index.js +7 -33
- package/v2Components/TemplatePreview/_templatePreview.scss +24 -55
- package/v2Components/TemplatePreview/index.js +32 -47
- package/v2Components/TemplatePreview/messages.js +0 -4
- package/v2Components/TestAndPreviewSlidebox/_testAndPreviewSlidebox.scss +0 -1
- package/v2Containers/App/constants.js +0 -5
- package/v2Containers/BeeEditor/index.js +90 -172
- package/v2Containers/CreativesContainer/SlideBoxContent.js +53 -184
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +13 -163
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +1 -3
- package/v2Containers/CreativesContainer/constants.js +0 -4
- package/v2Containers/CreativesContainer/index.js +46 -408
- package/v2Containers/CreativesContainer/messages.js +0 -12
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +0 -210
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +2 -11
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +50 -342
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +0 -103
- package/v2Containers/Email/actions.js +0 -7
- package/v2Containers/Email/constants.js +1 -5
- package/v2Containers/Email/index.js +36 -237
- package/v2Containers/Email/messages.js +0 -32
- package/v2Containers/Email/reducer.js +1 -12
- package/v2Containers/Email/sagas.js +7 -61
- package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +0 -2
- package/v2Containers/Email/tests/reducer.test.js +0 -46
- package/v2Containers/Email/tests/sagas.test.js +29 -320
- package/v2Containers/EmailWrapper/components/EmailWrapperView.js +21 -211
- package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +74 -40
- package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +67 -2
- package/v2Containers/EmailWrapper/constants.js +0 -2
- package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +77 -629
- package/v2Containers/EmailWrapper/index.js +23 -103
- package/v2Containers/EmailWrapper/messages.js +1 -65
- package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +214 -0
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +77 -594
- package/v2Containers/InApp/actions.js +0 -7
- package/v2Containers/InApp/constants.js +4 -20
- package/v2Containers/InApp/index.js +359 -802
- package/v2Containers/InApp/index.scss +3 -4
- package/v2Containers/InApp/messages.js +3 -7
- package/v2Containers/InApp/reducer.js +3 -21
- package/v2Containers/InApp/sagas.js +9 -29
- package/v2Containers/InApp/selectors.js +5 -25
- package/v2Containers/InApp/tests/index.test.js +50 -154
- package/v2Containers/InApp/tests/reducer.test.js +0 -34
- package/v2Containers/InApp/tests/sagas.test.js +9 -61
- package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +0 -3
- package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +0 -2
- package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +0 -2
- package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +0 -9
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +0 -12
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +0 -4
- package/v2Containers/TagList/index.js +19 -62
- package/v2Containers/Templates/ChannelTypeIllustration.js +1 -13
- package/v2Containers/Templates/_templates.scss +1 -265
- package/v2Containers/Templates/actions.js +1 -2
- package/v2Containers/Templates/constants.js +0 -1
- package/v2Containers/Templates/index.js +38 -363
- package/v2Containers/Templates/messages.js +0 -28
- package/v2Containers/Templates/reducer.js +0 -2
- package/v2Containers/Templates/tests/index.test.js +0 -10
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +2 -4
- package/v2Containers/TemplatesV2/index.js +7 -15
- package/v2Containers/TemplatesV2/messages.js +0 -4
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +0 -34
- package/utils/imageUrlUpload.js +0 -141
- package/v2Components/CapImageUrlUpload/constants.js +0 -26
- package/v2Components/CapImageUrlUpload/index.js +0 -365
- package/v2Components/CapImageUrlUpload/index.scss +0 -35
- package/v2Components/CapImageUrlUpload/messages.js +0 -47
- package/v2Components/ErrorInfoNote/constants.js +0 -1
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +0 -870
- package/v2Components/HtmlEditor/components/ValidationPanel/constants.js +0 -6
- package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +0 -281
- package/v2Components/HtmlEditor/components/ValidationTabs/index.js +0 -295
- package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +0 -51
- package/v2Components/HtmlEditor/utils/validationConstants.js +0 -38
- package/v2Components/MobilePushPreviewV2/constants.js +0 -6
- package/v2Containers/BeePopupEditor/_beePopupEditor.scss +0 -14
- package/v2Containers/BeePopupEditor/constants.js +0 -10
- package/v2Containers/BeePopupEditor/index.js +0 -194
- package/v2Containers/BeePopupEditor/tests/index.test.js +0 -627
- package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +0 -1246
- package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +0 -2472
- package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +0 -520
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +0 -956
- package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +0 -376
- package/v2Containers/InApp/__tests__/sagas.test.js +0 -363
- package/v2Containers/InApp/tests/selectors.test.js +0 -612
- package/v2Containers/InAppWrapper/components/InAppWrapperView.js +0 -151
- package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +0 -267
- package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +0 -23
- package/v2Containers/InAppWrapper/constants.js +0 -16
- package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +0 -473
- package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +0 -198
- package/v2Containers/InAppWrapper/index.js +0 -148
- package/v2Containers/InAppWrapper/messages.js +0 -49
- package/v2Containers/InappAdvance/index.js +0 -1099
- package/v2Containers/InappAdvance/index.scss +0 -10
- package/v2Containers/InappAdvance/tests/index.test.js +0 -448
- package/v2Containers/WebPush/Create/components/BrandIconSection.js +0 -108
- package/v2Containers/WebPush/Create/components/ButtonForm.js +0 -172
- package/v2Containers/WebPush/Create/components/ButtonItem.js +0 -101
- package/v2Containers/WebPush/Create/components/ButtonList.js +0 -145
- package/v2Containers/WebPush/Create/components/ButtonsLinksSection.js +0 -164
- package/v2Containers/WebPush/Create/components/ButtonsLinksSection.test.js +0 -463
- package/v2Containers/WebPush/Create/components/FormActions.js +0 -54
- package/v2Containers/WebPush/Create/components/FormActions.test.js +0 -163
- package/v2Containers/WebPush/Create/components/MediaSection.js +0 -142
- package/v2Containers/WebPush/Create/components/MediaSection.test.js +0 -341
- package/v2Containers/WebPush/Create/components/MessageSection.js +0 -103
- package/v2Containers/WebPush/Create/components/MessageSection.test.js +0 -268
- package/v2Containers/WebPush/Create/components/NotificationTitleSection.js +0 -87
- package/v2Containers/WebPush/Create/components/NotificationTitleSection.test.js +0 -210
- package/v2Containers/WebPush/Create/components/TemplateNameSection.js +0 -54
- package/v2Containers/WebPush/Create/components/TemplateNameSection.test.js +0 -143
- package/v2Containers/WebPush/Create/components/__snapshots__/ButtonsLinksSection.test.js.snap +0 -86
- package/v2Containers/WebPush/Create/components/__snapshots__/FormActions.test.js.snap +0 -16
- package/v2Containers/WebPush/Create/components/__snapshots__/MediaSection.test.js.snap +0 -41
- package/v2Containers/WebPush/Create/components/__snapshots__/MessageSection.test.js.snap +0 -54
- package/v2Containers/WebPush/Create/components/__snapshots__/NotificationTitleSection.test.js.snap +0 -37
- package/v2Containers/WebPush/Create/components/__snapshots__/TemplateNameSection.test.js.snap +0 -21
- package/v2Containers/WebPush/Create/components/_buttons.scss +0 -246
- package/v2Containers/WebPush/Create/components/tests/ButtonForm.test.js +0 -554
- package/v2Containers/WebPush/Create/components/tests/ButtonItem.test.js +0 -607
- package/v2Containers/WebPush/Create/components/tests/ButtonList.test.js +0 -633
- package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonForm.test.js.snap +0 -666
- package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonItem.test.js.snap +0 -74
- package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonList.test.js.snap +0 -78
- package/v2Containers/WebPush/Create/hooks/useButtonManagement.js +0 -138
- package/v2Containers/WebPush/Create/hooks/useButtonManagement.test.js +0 -406
- package/v2Containers/WebPush/Create/hooks/useCharacterCount.js +0 -30
- package/v2Containers/WebPush/Create/hooks/useCharacterCount.test.js +0 -151
- package/v2Containers/WebPush/Create/hooks/useImageUpload.js +0 -104
- package/v2Containers/WebPush/Create/hooks/useImageUpload.test.js +0 -538
- package/v2Containers/WebPush/Create/hooks/useTagManagement.js +0 -122
- package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +0 -633
- package/v2Containers/WebPush/Create/index.js +0 -1148
- package/v2Containers/WebPush/Create/index.scss +0 -134
- package/v2Containers/WebPush/Create/messages.js +0 -211
- package/v2Containers/WebPush/Create/preview/DevicePreviewContent.js +0 -228
- package/v2Containers/WebPush/Create/preview/NotificationContainer.js +0 -294
- package/v2Containers/WebPush/Create/preview/PreviewContent.js +0 -90
- package/v2Containers/WebPush/Create/preview/PreviewControls.js +0 -305
- package/v2Containers/WebPush/Create/preview/PreviewDisclaimer.js +0 -25
- package/v2Containers/WebPush/Create/preview/WebPushPreview.js +0 -155
- package/v2Containers/WebPush/Create/preview/assets/Light.svg +0 -53
- package/v2Containers/WebPush/Create/preview/assets/Top.svg +0 -5
- package/v2Containers/WebPush/Create/preview/assets/android-arrow-down.svg +0 -9
- package/v2Containers/WebPush/Create/preview/assets/android-arrow-up.svg +0 -9
- package/v2Containers/WebPush/Create/preview/assets/chrome-icon.png +0 -0
- package/v2Containers/WebPush/Create/preview/assets/edge-icon.png +0 -0
- package/v2Containers/WebPush/Create/preview/assets/firefox-icon.svg +0 -106
- package/v2Containers/WebPush/Create/preview/assets/iOS.svg +0 -26
- package/v2Containers/WebPush/Create/preview/assets/macos-arrow-down-icon.svg +0 -9
- package/v2Containers/WebPush/Create/preview/assets/macos-triple-dot-icon.svg +0 -9
- package/v2Containers/WebPush/Create/preview/assets/opera-icon.svg +0 -18
- package/v2Containers/WebPush/Create/preview/assets/safari-icon.svg +0 -29
- package/v2Containers/WebPush/Create/preview/assets/windows-close-icon.svg +0 -9
- package/v2Containers/WebPush/Create/preview/assets/windows-triple-dot-icon.svg +0 -9
- package/v2Containers/WebPush/Create/preview/components/AndroidMobileChromeHeader.js +0 -51
- package/v2Containers/WebPush/Create/preview/components/AndroidMobileExpanded.js +0 -145
- package/v2Containers/WebPush/Create/preview/components/IOSHeader.js +0 -45
- package/v2Containers/WebPush/Create/preview/components/NotificationExpandedContent.js +0 -68
- package/v2Containers/WebPush/Create/preview/components/NotificationHeader.js +0 -61
- package/v2Containers/WebPush/Create/preview/components/WindowsChromeExpanded.js +0 -99
- package/v2Containers/WebPush/Create/preview/components/tests/AndroidMobileExpanded.test.js +0 -733
- package/v2Containers/WebPush/Create/preview/components/tests/WindowsChromeExpanded.test.js +0 -571
- package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/AndroidMobileExpanded.test.js.snap +0 -85
- package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/WindowsChromeExpanded.test.js.snap +0 -81
- package/v2Containers/WebPush/Create/preview/config/notificationMappings.js +0 -50
- package/v2Containers/WebPush/Create/preview/constants.js +0 -637
- package/v2Containers/WebPush/Create/preview/notification-container.scss +0 -79
- package/v2Containers/WebPush/Create/preview/preview.scss +0 -358
- package/v2Containers/WebPush/Create/preview/styles/_android-mobile-chrome.scss +0 -370
- package/v2Containers/WebPush/Create/preview/styles/_android-mobile-edge.scss +0 -12
- package/v2Containers/WebPush/Create/preview/styles/_android-mobile-firefox.scss +0 -12
- package/v2Containers/WebPush/Create/preview/styles/_android-mobile-opera.scss +0 -12
- package/v2Containers/WebPush/Create/preview/styles/_android-tablet-chrome.scss +0 -47
- package/v2Containers/WebPush/Create/preview/styles/_android-tablet-edge.scss +0 -11
- package/v2Containers/WebPush/Create/preview/styles/_android-tablet-firefox.scss +0 -11
- package/v2Containers/WebPush/Create/preview/styles/_android-tablet-opera.scss +0 -11
- package/v2Containers/WebPush/Create/preview/styles/_base.scss +0 -207
- package/v2Containers/WebPush/Create/preview/styles/_ios.scss +0 -153
- package/v2Containers/WebPush/Create/preview/styles/_ipados.scss +0 -107
- package/v2Containers/WebPush/Create/preview/styles/_macos-chrome.scss +0 -101
- package/v2Containers/WebPush/Create/preview/styles/_windows-chrome.scss +0 -229
- package/v2Containers/WebPush/Create/preview/tests/DevicePreviewContent.test.js +0 -909
- package/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +0 -1081
- package/v2Containers/WebPush/Create/preview/tests/PreviewControls.test.js +0 -723
- package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +0 -1327
- package/v2Containers/WebPush/Create/preview/tests/__snapshots__/DevicePreviewContent.test.js.snap +0 -131
- package/v2Containers/WebPush/Create/preview/tests/__snapshots__/NotificationContainer.test.js.snap +0 -112
- package/v2Containers/WebPush/Create/preview/tests/__snapshots__/PreviewControls.test.js.snap +0 -144
- package/v2Containers/WebPush/Create/preview/tests/__snapshots__/WebPushPreview.test.js.snap +0 -129
- package/v2Containers/WebPush/Create/utils/payloadBuilder.js +0 -96
- package/v2Containers/WebPush/Create/utils/payloadBuilder.test.js +0 -396
- package/v2Containers/WebPush/Create/utils/previewUtils.js +0 -89
- package/v2Containers/WebPush/Create/utils/urlValidation.js +0 -115
- package/v2Containers/WebPush/Create/utils/urlValidation.test.js +0 -449
- package/v2Containers/WebPush/Create/utils/validation.js +0 -75
- package/v2Containers/WebPush/Create/utils/validation.test.js +0 -283
- package/v2Containers/WebPush/actions.js +0 -60
- package/v2Containers/WebPush/constants.js +0 -132
- package/v2Containers/WebPush/index.js +0 -2
- package/v2Containers/WebPush/reducer.js +0 -104
- package/v2Containers/WebPush/sagas.js +0 -119
- package/v2Containers/WebPush/selectors.js +0 -65
- package/v2Containers/WebPush/tests/reducer.test.js +0 -863
- package/v2Containers/WebPush/tests/sagas.test.js +0 -566
- package/v2Containers/WebPush/tests/selectors.test.js +0 -960
|
@@ -1,20 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
useState, useEffect, useMemo, useCallback, useRef,
|
|
3
|
-
} from 'react';
|
|
1
|
+
import { useState, useEffect, useMemo, useCallback } from 'react';
|
|
4
2
|
import isEmpty from 'lodash/isEmpty';
|
|
5
|
-
import find from 'lodash/find';
|
|
6
3
|
import get from 'lodash/get';
|
|
4
|
+
import find from 'lodash/find';
|
|
7
5
|
import { GA } from '@capillarytech/cap-ui-utils';
|
|
8
6
|
import CapNotification from '@capillarytech/cap-ui-library/CapNotification';
|
|
9
|
-
import
|
|
10
|
-
import { CHANNEL_CREATE_TRACK_MAPPING, BEE_PLUGIN } from '../../App/constants';
|
|
7
|
+
import { CHANNEL_CREATE_TRACK_MAPPING } from '../../App/constants';
|
|
11
8
|
import { gtmPush } from '../../../utils/gtmTrackers';
|
|
12
9
|
import { EMAIL } from '../../CreativesContainer/constants';
|
|
13
10
|
import messages from '../messages';
|
|
14
|
-
import { STEPS
|
|
11
|
+
import { STEPS } from '../constants';
|
|
12
|
+
import { EMAIL_CREATE_MODES } from '../constants';
|
|
15
13
|
import { containsBase64Images } from '../../../utils/content';
|
|
16
|
-
import { hasSupportCKEditor } from '../../../utils/common';
|
|
17
|
-
|
|
18
14
|
|
|
19
15
|
/**
|
|
20
16
|
* Custom hook to handle EmailWrapper component business logic
|
|
@@ -60,35 +56,27 @@ const useEmailWrapper = ({
|
|
|
60
56
|
handleTestAndPreview,
|
|
61
57
|
handleCloseTestAndPreview,
|
|
62
58
|
isTestAndPreviewMode,
|
|
63
|
-
// Props for BEE enabled check
|
|
64
|
-
location,
|
|
65
|
-
emailActions,
|
|
66
|
-
Email,
|
|
67
|
-
templateData,
|
|
68
|
-
params,
|
|
69
59
|
}) => {
|
|
70
60
|
// State management
|
|
71
61
|
const [templateName, setTemplateName] = useState('');
|
|
72
62
|
const [isTemplateNameEmpty, setIsTemplateNameEmpty] = useState(true);
|
|
73
63
|
const [selectedCreateMode, setSelectedCreateMode] = useState('');
|
|
74
64
|
const [modeContent, setModeContent] = useState({});
|
|
75
|
-
const [isBeeEditorEnabled, setIsBeeEditorEnabled] = useState(null); // null = not checked yet, true/false = checked
|
|
76
|
-
const beeStatusCheckRef = useRef(false); // Track if we've made the API call for current step
|
|
77
|
-
const defaultTemplatesFetchedRef = useRef(false);
|
|
78
|
-
const beeTemplateSetRef = useRef(false); // Track if we've set BEETemplate for current template
|
|
79
65
|
const [routeParams] = useState({
|
|
80
66
|
pathname: `/email/create`,
|
|
81
67
|
query: { module: 'library', type: 'embedded' },
|
|
82
68
|
});
|
|
83
69
|
|
|
84
70
|
// Cleanup effect
|
|
85
|
-
useEffect(() =>
|
|
86
|
-
|
|
87
|
-
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
return () => {
|
|
73
|
+
onResetStep();
|
|
74
|
+
templatesActions.resetTemplateData();
|
|
75
|
+
};
|
|
88
76
|
}, [onResetStep, templatesActions]);
|
|
89
77
|
|
|
90
78
|
// Event handlers
|
|
91
|
-
const onTemplateNameChange = useCallback(({
|
|
79
|
+
const onTemplateNameChange = useCallback(({target: {value}}) => {
|
|
92
80
|
const isEmptyTemplateName = !value?.trim();
|
|
93
81
|
setTemplateName(value);
|
|
94
82
|
setIsTemplateNameEmpty(isEmptyTemplateName);
|
|
@@ -100,237 +88,9 @@ const useEmailWrapper = ({
|
|
|
100
88
|
}
|
|
101
89
|
}, [onEnterTemplateName, onRemoveTemplateName]);
|
|
102
90
|
|
|
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
|
-
// IMPORTANT: Always use API response when available, regardless of mode
|
|
108
|
-
// This ensures consistent behavior across full mode and library mode
|
|
109
|
-
// The API response represents whether BEE is enabled for the organization
|
|
110
|
-
if (isBeeEditorEnabled !== null) {
|
|
111
|
-
return isBeeEditorEnabled;
|
|
112
|
-
}
|
|
113
|
-
// If we haven't checked yet, return false (disabled) until API responds
|
|
114
|
-
// Note: In full mode, BEE might still be allowed for UI purposes (editor selection),
|
|
115
|
-
// but for API calls (isBEEAppEnable), we should use the actual org setting
|
|
116
|
-
return false;
|
|
117
|
-
}, [isBeeEditorEnabled]);
|
|
118
|
-
|
|
119
|
-
// Helper function to convert numeric templateStep to string step
|
|
120
|
-
const getStepFromTemplateStep = useCallback((templateStepValue) => {
|
|
121
|
-
// templateStep is numeric: 1 = modeSelection, 2 = templateSelection, 3 = createTemplateContent
|
|
122
|
-
if (typeof templateStepValue === 'number') {
|
|
123
|
-
switch (templateStepValue) {
|
|
124
|
-
case 1:
|
|
125
|
-
return STEPS.MODE_SELECTION;
|
|
126
|
-
case 2:
|
|
127
|
-
return STEPS.TEMPLATE_SELECTION;
|
|
128
|
-
case 3:
|
|
129
|
-
return STEPS.CREATE_TEMPLATE_CONTENT;
|
|
130
|
-
default:
|
|
131
|
-
return STEPS.MODE_SELECTION;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
// If it's already a string, return as-is
|
|
135
|
-
return templateStepValue || STEPS.MODE_SELECTION;
|
|
136
|
-
}, []);
|
|
137
|
-
|
|
138
|
-
// Convert step to string format if it's numeric
|
|
139
|
-
const currentStep = useMemo(() => getStepFromTemplateStep(step), [step, getStepFromTemplateStep]);
|
|
140
|
-
|
|
141
|
-
// Effect to check BEE enabled status via new API when entering MODE_SELECTION step or edit mode
|
|
142
|
-
useEffect(() => {
|
|
143
|
-
const supportCKEditor = hasSupportCKEditor();
|
|
144
|
-
// Only check BEE enabled status for new flow (when supportCKEditor is false)
|
|
145
|
-
// Reset the ref when step changes to MODE_SELECTION to allow API call
|
|
146
|
-
if (currentStep === STEPS.MODE_SELECTION) {
|
|
147
|
-
beeStatusCheckRef.current = false;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Check if we're in edit mode (need to check BEE status for editor selection)
|
|
151
|
-
const hasParamsId = params?.id || location?.query?.id || location?.params?.id || location?.pathname?.includes('/edit/');
|
|
152
|
-
console.log('***hasParamsId', hasParamsId, location, params);
|
|
153
|
-
const isEditMode = hasParamsId;
|
|
154
|
-
|
|
155
|
-
// Only check BEE enabled status for new flow (when supportCKEditor is false)
|
|
156
|
-
// Call API in MODE_SELECTION step OR in edit mode (if not already called)
|
|
157
|
-
// Check all conditions
|
|
158
|
-
const shouldMakeCall = !supportCKEditor
|
|
159
|
-
&& (currentStep === STEPS.MODE_SELECTION || isEditMode)
|
|
160
|
-
&& !beeStatusCheckRef.current
|
|
161
|
-
&& emailActions;
|
|
162
|
-
|
|
163
|
-
if (shouldMakeCall) {
|
|
164
|
-
// Mark that we've made the API call
|
|
165
|
-
beeStatusCheckRef.current = true;
|
|
166
|
-
|
|
167
|
-
// Make API call to check BEE enabled status using new endpoint
|
|
168
|
-
emailActions.getCmsAccounts('BEE_PLUGIN');
|
|
169
|
-
}
|
|
170
|
-
}, [currentStep, emailActions, params?.id, location?.query?.id, location?.params?.id, location?.pathname]);
|
|
171
|
-
|
|
172
|
-
// Effect to update isBeeEditorEnabled based on new API response
|
|
173
|
-
// This effect watches for isBeeEnabled from the new API response
|
|
174
|
-
useEffect(() => {
|
|
175
|
-
// Process API response regardless of step (needed for edit mode editor selection)
|
|
176
|
-
// Also check if we've made the API call (beeStatusCheckRef.current === true)
|
|
177
|
-
if (beeStatusCheckRef.current) {
|
|
178
|
-
// Use isBeeEnabled from the new API response
|
|
179
|
-
if (Email?.isBeeEnabled !== undefined && Email?.isBeeEnabled !== null) {
|
|
180
|
-
setIsBeeEditorEnabled(Email.isBeeEnabled);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
// If API call fails, treat as disabled
|
|
184
|
-
if (Email?.fetchingCmsAccountsError && beeStatusCheckRef.current) {
|
|
185
|
-
setIsBeeEditorEnabled(false);
|
|
186
|
-
}
|
|
187
|
-
}, [Email?.isBeeEnabled, Email?.fetchingCmsAccountsError]);
|
|
188
|
-
|
|
189
|
-
// Effect to fetch template details when in edit mode
|
|
190
|
-
// This ensures template data is loaded so editor type can be determined correctly
|
|
191
|
-
useEffect(() => {
|
|
192
|
-
const supportCKEditor = hasSupportCKEditor();
|
|
193
|
-
if (supportCKEditor) {
|
|
194
|
-
// Legacy flow: Email component handles getTemplateDetails
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// New flow: Fetch template details if we're in edit mode and don't have template data yet
|
|
199
|
-
const hasParamsId = params?.id || location?.query?.id || location?.params?.id || location?.pathname?.includes('/edit/');
|
|
200
|
-
const hasTemplateDetails = Email?.templateDetails && !isEmpty(Email.templateDetails);
|
|
201
|
-
const hasTemplateDataProp = templateData && !isEmpty(templateData);
|
|
202
|
-
const isTemplateLoading = Email?.getTemplateDetailsInProgress;
|
|
203
|
-
|
|
204
|
-
// Only fetch if we have an ID, don't have template data yet, and not already loading
|
|
205
|
-
if (hasParamsId && !hasTemplateDetails && !hasTemplateDataProp && !isTemplateLoading && emailActions?.getTemplateDetails) {
|
|
206
|
-
const templateId = params?.id || location?.query?.id || location?.params?.id;
|
|
207
|
-
if (templateId) {
|
|
208
|
-
emailActions.getTemplateDetails(templateId, 'email');
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}, [params?.id, location?.query?.id, location?.params?.id, location?.pathname, Email?.templateDetails, Email?.getTemplateDetailsInProgress, templateData, emailActions]);
|
|
212
|
-
|
|
213
|
-
// Effect to set BEETemplate when template details are loaded for BEE templates
|
|
214
|
-
// This ensures Email component can properly initialize BEE editor
|
|
215
|
-
useEffect(() => {
|
|
216
|
-
const supportCKEditor = hasSupportCKEditor();
|
|
217
|
-
if (supportCKEditor) {
|
|
218
|
-
// Legacy flow: Email component handles this
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// New flow: When template details are loaded and it's a BEE template, set it in Templates.BEETemplate
|
|
223
|
-
// This allows Email component to properly initialize and call getCmsSetting
|
|
224
|
-
const hasTemplateDetails = Email?.templateDetails && !isEmpty(Email.templateDetails);
|
|
225
|
-
// Note: We check Email?.BEETemplate as a proxy, but the actual BEETemplate is in Templates reducer
|
|
226
|
-
// The Email component will detect it via this.props.Templates.BEETemplate
|
|
227
|
-
const hasBEETemplate = Email?.BEETemplate && !isEmpty(Email.BEETemplate);
|
|
228
|
-
|
|
229
|
-
if (hasTemplateDetails && !hasBEETemplate && templatesActions?.setBEETemplate && !beeTemplateSetRef.current) {
|
|
230
|
-
// Check if it's a BEE template
|
|
231
|
-
const editTemplateData = Email.templateDetails;
|
|
232
|
-
const getIsDragDrop = (data) => {
|
|
233
|
-
if (!data) return false;
|
|
234
|
-
const baseDragDrop = get(data, 'versions.base.is_drag_drop', false);
|
|
235
|
-
if (baseDragDrop === true || baseDragDrop === 1) return true;
|
|
236
|
-
const activeTab = get(data, 'versions.base.activeTab', 'en');
|
|
237
|
-
const activeTabDragDrop = get(data, `versions.base.${activeTab}.is_drag_drop`, false);
|
|
238
|
-
if (activeTabDragDrop === true || activeTabDragDrop === 1) return true;
|
|
239
|
-
const baseLevelDragDrop = get(data, 'base.is_drag_drop', false);
|
|
240
|
-
if (baseLevelDragDrop === true || baseLevelDragDrop === 1) return true;
|
|
241
|
-
const rootDragDrop = get(data, 'is_drag_drop', false);
|
|
242
|
-
if (rootDragDrop === true || rootDragDrop === 1) return true;
|
|
243
|
-
return false;
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
const isDragDrop = getIsDragDrop(editTemplateData);
|
|
247
|
-
|
|
248
|
-
// If it's a BEE template, set it in Templates.BEETemplate
|
|
249
|
-
if (isDragDrop) {
|
|
250
|
-
beeTemplateSetRef.current = true;
|
|
251
|
-
templatesActions.setBEETemplate(editTemplateData);
|
|
252
|
-
|
|
253
|
-
// Also call getCmsSetting directly as a fallback if Email component doesn't detect it
|
|
254
|
-
// Extract drag_drop_id - check multiple possible paths
|
|
255
|
-
const activeTab = get(editTemplateData, 'versions.base.activeTab', 'en');
|
|
256
|
-
const activeTabData = get(editTemplateData, `versions.base.${activeTab}`, {});
|
|
257
|
-
const dragDropId = activeTabData.drag_drop_id
|
|
258
|
-
|| activeTabData.id
|
|
259
|
-
|| get(editTemplateData, 'versions.base.drag_drop_id')
|
|
260
|
-
|| get(editTemplateData, 'versions.base.id')
|
|
261
|
-
|| editTemplateData._id;
|
|
262
|
-
|
|
263
|
-
const isBEESupport = (location?.query?.isBEESupport !== "false") || false;
|
|
264
|
-
// IMPORTANT: isBEEAppEnable should be consistent across full mode and library mode
|
|
265
|
-
// It represents whether BEE is enabled for the organization, not the mode
|
|
266
|
-
// This ensures the same template behaves the same way in both modes
|
|
267
|
-
const isBEEAppEnable = checkBeeEditorEnabled();
|
|
268
|
-
// Check if we're in edit mode - check multiple sources for id
|
|
269
|
-
const hasParamsId = params?.id
|
|
270
|
-
|| location?.query?.id
|
|
271
|
-
|| location?.params?.id
|
|
272
|
-
|| (location?.pathname && location.pathname.includes('/edit/'));
|
|
273
|
-
const cmsMode = hasParamsId ? 'open' : 'create';
|
|
274
|
-
// Extract langId from active tab
|
|
275
|
-
const activeTabForLang = get(editTemplateData, 'versions.base.activeTab', 'en');
|
|
276
|
-
|
|
277
|
-
// Call getCmsSetting if emailActions is available
|
|
278
|
-
// Note: This is a fallback - the Email component should also call it in componentWillReceiveProps
|
|
279
|
-
if (emailActions?.getCmsSetting) {
|
|
280
|
-
emailActions.getCmsSetting(BEE_PLUGIN, dragDropId, cmsMode, activeTabForLang, isBEESupport, isBEEAppEnable);
|
|
281
|
-
} else {
|
|
282
|
-
console.warn('[useEmailWrapper] emailActions.getCmsSetting not available');
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Reset ref when template changes (template details cleared)
|
|
288
|
-
if (!hasTemplateDetails && beeTemplateSetRef.current) {
|
|
289
|
-
beeTemplateSetRef.current = false;
|
|
290
|
-
}
|
|
291
|
-
}, [Email?.templateDetails, Email?.BEETemplate, Email?.getTemplateDetailsInProgress, Email?.fetchingCmsSettings, templatesActions, emailActions, params?.id, location?.query, checkBeeEditorEnabled, isFullMode]);
|
|
292
|
-
|
|
293
91
|
const onChange = useCallback((e) => {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
if (value === EMAIL_CREATE_MODES.DRAG_DROP && !checkBeeEditorEnabled()) {
|
|
297
|
-
return; // Ignore selection if BEE editor is disabled
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
// CRITICAL: When DRAG_DROP is selected, set selectedCreateMode to DRAG_DROP
|
|
301
|
-
// This ensures emailProps will have editor: 'BEE' and selectedEditorMode: null
|
|
302
|
-
if (value === EMAIL_CREATE_MODES.DRAG_DROP) {
|
|
303
|
-
setSelectedCreateMode(EMAIL_CREATE_MODES.DRAG_DROP);
|
|
304
|
-
} else {
|
|
305
|
-
setSelectedCreateMode(value);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
const supportCKEditor = hasSupportCKEditor();
|
|
309
|
-
|
|
310
|
-
// Map new modes to existing modes for backwards compatibility
|
|
311
|
-
let mappedValue = value;
|
|
312
|
-
|
|
313
|
-
if (!supportCKEditor) {
|
|
314
|
-
// New flow: Handle HTML Editor, Drag & Drop, and Upload Zip
|
|
315
|
-
// Don't auto-navigate - wait for Next button click
|
|
316
|
-
if (value === EMAIL_CREATE_MODES.HTML_EDITOR) {
|
|
317
|
-
// HTML Editor: Map to EDITOR but skip template selection
|
|
318
|
-
mappedValue = EMAIL_CREATE_MODES.EDITOR;
|
|
319
|
-
setModeContent({ skipTemplateSelection: true });
|
|
320
|
-
} else if (value === EMAIL_CREATE_MODES.DRAG_DROP) {
|
|
321
|
-
// Drag & Drop: Map to EDITOR and show template selection
|
|
322
|
-
mappedValue = EMAIL_CREATE_MODES.EDITOR;
|
|
323
|
-
} else if (value === EMAIL_CREATE_MODES.UPLOAD) {
|
|
324
|
-
// Upload Zip: Keep as UPLOAD
|
|
325
|
-
mappedValue = EMAIL_CREATE_MODES.UPLOAD;
|
|
326
|
-
}
|
|
327
|
-
} else if (value === EMAIL_CREATE_MODES.EDITOR && showNextStep) {
|
|
328
|
-
// Legacy flow: Auto-navigate immediately (existing behavior)
|
|
329
|
-
showNextStep();
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
onEmailModeChange(mappedValue, value); // Pass both mapped value and original selected mode
|
|
333
|
-
}, [onEmailModeChange, showNextStep, checkBeeEditorEnabled]);
|
|
92
|
+
onEmailModeChange(e.target.value);
|
|
93
|
+
}, [onEmailModeChange]);
|
|
334
94
|
|
|
335
95
|
const handleZipUploadError = useCallback(() => {
|
|
336
96
|
const message = {
|
|
@@ -408,10 +168,10 @@ const useEmailWrapper = ({
|
|
|
408
168
|
handleZipUploadError();
|
|
409
169
|
return;
|
|
410
170
|
}
|
|
411
|
-
|
|
171
|
+
|
|
412
172
|
// Check for base64 images in HTML content
|
|
413
|
-
containsBase64Images({content:
|
|
414
|
-
|
|
173
|
+
containsBase64Images({content:text, CapNotification});
|
|
174
|
+
|
|
415
175
|
setModeContent({ file });
|
|
416
176
|
templatesActions.handleHtmlUpload(text);
|
|
417
177
|
};
|
|
@@ -434,12 +194,8 @@ const useEmailWrapper = ({
|
|
|
434
194
|
const data = find(CmsTemplates, { _id: id });
|
|
435
195
|
templatesActions.setEdmTemplate(data);
|
|
436
196
|
templatesActions.setBEETemplate(data);
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
if (!selectedCreateMode) {
|
|
440
|
-
setSelectedCreateMode(EMAIL_CREATE_MODES.EDITOR);
|
|
441
|
-
}
|
|
442
|
-
}, [CmsTemplates, templatesActions, selectedCreateMode]);
|
|
197
|
+
setSelectedCreateMode(EMAIL_CREATE_MODES.EDITOR);
|
|
198
|
+
}, [CmsTemplates, templatesActions]);
|
|
443
199
|
|
|
444
200
|
const useFileUpload = useCallback(({ file }) => {
|
|
445
201
|
setModeContent({});
|
|
@@ -453,73 +209,41 @@ const useEmailWrapper = ({
|
|
|
453
209
|
|
|
454
210
|
// Main logic effect - MOVED AFTER function declarations
|
|
455
211
|
useEffect(() => {
|
|
456
|
-
|
|
212
|
+
// Skip if user has already made a selection
|
|
213
|
+
if (selectedCreateMode) return;
|
|
457
214
|
|
|
458
215
|
// Handle different steps
|
|
459
|
-
switch (
|
|
216
|
+
switch (step) {
|
|
460
217
|
case STEPS.MODE_SELECTION:
|
|
461
218
|
if (emailCreateMode === EMAIL_CREATE_MODES.UPLOAD && !EmailLayout) {
|
|
462
219
|
// Commented out: document.getElementById('upload-email-template').click();
|
|
463
220
|
}
|
|
464
221
|
break;
|
|
465
222
|
|
|
466
|
-
case STEPS.TEMPLATE_SELECTION:
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
// NOT needed for HTML_EDITOR (goes directly to editor)
|
|
223
|
+
case STEPS.TEMPLATE_SELECTION:
|
|
224
|
+
const needsTemplates = emailCreateMode === EMAIL_CREATE_MODES.EDITOR
|
|
225
|
+
&& !CmsTemplates
|
|
226
|
+
&& !getCmsTemplatesInProgress;
|
|
471
227
|
|
|
472
|
-
|
|
473
|
-
if (supportCKEditor) {
|
|
474
|
-
// Legacy flow: only for EDITOR mode
|
|
475
|
-
needsTemplates = emailCreateMode === EMAIL_CREATE_MODES.EDITOR
|
|
476
|
-
&& !CmsTemplates
|
|
477
|
-
&& !getCmsTemplatesInProgress;
|
|
478
|
-
} else {
|
|
479
|
-
// New flow: for DRAG_DROP only (not HTML_EDITOR)
|
|
480
|
-
needsTemplates = selectedCreateMode === EMAIL_CREATE_MODES.DRAG_DROP
|
|
481
|
-
&& !CmsTemplates
|
|
482
|
-
&& !getCmsTemplatesInProgress;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
if (needsTemplates && !defaultTemplatesFetchedRef.current) {
|
|
228
|
+
if (needsTemplates) {
|
|
486
229
|
templatesActions.getDefaultBeeTemplates();
|
|
487
|
-
defaultTemplatesFetchedRef.current = true;
|
|
488
230
|
}
|
|
489
231
|
break;
|
|
490
|
-
}
|
|
491
232
|
|
|
492
|
-
case STEPS.CREATE_TEMPLATE_CONTENT:
|
|
233
|
+
case STEPS.CREATE_TEMPLATE_CONTENT:
|
|
493
234
|
if (emailCreateMode === EMAIL_CREATE_MODES.UPLOAD && !isEmpty(EmailLayout)) {
|
|
494
235
|
setSelectedCreateMode(EMAIL_CREATE_MODES.UPLOAD);
|
|
495
|
-
} else if (emailCreateMode === EMAIL_CREATE_MODES.EDITOR
|
|
496
|
-
|
|
497
|
-
|| selectedCreateMode === EMAIL_CREATE_MODES.EDITOR
|
|
498
|
-
|| selectedCreateMode === EMAIL_CREATE_MODES.DRAG_DROP) {
|
|
499
|
-
if (!supportCKEditor && selectedCreateMode === EMAIL_CREATE_MODES.HTML_EDITOR) {
|
|
500
|
-
// HTML Editor mode: Skip template selection, go directly to editor
|
|
501
|
-
setSelectedCreateMode(EMAIL_CREATE_MODES.HTML_EDITOR);
|
|
502
|
-
} else if (isEmpty(SelectedEdmDefaultTemplate) && modeContent.id) {
|
|
503
|
-
// Legacy EDITOR or DRAG_DROP: Need template selection
|
|
504
|
-
handleEdmDefaultTemplateSelection(modeContent.id);
|
|
505
|
-
} else if (!supportCKEditor && selectedCreateMode === EMAIL_CREATE_MODES.DRAG_DROP) {
|
|
506
|
-
// CRITICAL: Template already selected for DRAG_DROP - ensure selectedCreateMode is DRAG_DROP
|
|
507
|
-
// This ensures emailProps will have editor: 'BEE' and selectedEditorMode: null
|
|
508
|
-
setSelectedCreateMode(EMAIL_CREATE_MODES.DRAG_DROP);
|
|
509
|
-
} else {
|
|
510
|
-
// Template already selected for legacy EDITOR
|
|
511
|
-
setSelectedCreateMode(EMAIL_CREATE_MODES.EDITOR);
|
|
512
|
-
}
|
|
236
|
+
} else if (emailCreateMode === EMAIL_CREATE_MODES.EDITOR && isEmpty(SelectedEdmDefaultTemplate)) {
|
|
237
|
+
handleEdmDefaultTemplateSelection(modeContent.id);
|
|
513
238
|
}
|
|
514
239
|
break;
|
|
515
|
-
}
|
|
516
240
|
|
|
517
241
|
default:
|
|
518
242
|
// No operation for other steps
|
|
519
243
|
break;
|
|
520
244
|
}
|
|
521
245
|
}, [
|
|
522
|
-
|
|
246
|
+
step,
|
|
523
247
|
selectedCreateMode,
|
|
524
248
|
emailCreateMode,
|
|
525
249
|
EmailLayout,
|
|
@@ -528,224 +252,58 @@ const useEmailWrapper = ({
|
|
|
528
252
|
modeContent.id,
|
|
529
253
|
SelectedEdmDefaultTemplate,
|
|
530
254
|
templatesActions,
|
|
531
|
-
handleEdmDefaultTemplateSelection
|
|
255
|
+
handleEdmDefaultTemplateSelection
|
|
532
256
|
]);
|
|
533
257
|
|
|
534
|
-
// CRITICAL: Reset selectedCreateMode when templateData is cleared (new template creation)
|
|
535
|
-
// This ensures that when user creates a new template after editing, selectedCreateMode is reset
|
|
536
|
-
useEffect(() => {
|
|
537
|
-
// If templateData is cleared/null and we're not in edit mode, reset selectedCreateMode
|
|
538
|
-
const hasParamsId = params?.id
|
|
539
|
-
|| location?.query?.id
|
|
540
|
-
|| location?.params?.id
|
|
541
|
-
|| location?.pathname?.includes('/edit/');
|
|
542
|
-
const hasTemplateData = templateData && !isEmpty(templateData);
|
|
543
|
-
const isEditMode = hasParamsId || hasTemplateData;
|
|
544
|
-
|
|
545
|
-
// If we're creating a new template (no templateData and no params.id), reset selectedCreateMode
|
|
546
|
-
// BUT only if we're in MODE_SELECTION step (navigating back to start)
|
|
547
|
-
// DO NOT reset in CREATE_TEMPLATE_CONTENT - that's where we need selectedCreateMode to render the editor!
|
|
548
|
-
// Also DO NOT reset if emailCreateMode is set - it means user has made a selection
|
|
549
|
-
if (!isEditMode && !hasTemplateData && selectedCreateMode && currentStep === STEPS.MODE_SELECTION && !emailCreateMode) {
|
|
550
|
-
// Reset only when returning to MODE_SELECTION step
|
|
551
|
-
// This preserves user selection while in content creation
|
|
552
|
-
setSelectedCreateMode('');
|
|
553
|
-
}
|
|
554
|
-
}, [templateData, params?.id, location?.query?.id, location?.params?.id, location?.pathname, selectedCreateMode, templateName, currentStep, emailCreateMode]);
|
|
555
|
-
|
|
556
258
|
// Derived state
|
|
557
|
-
const
|
|
558
|
-
|
|
559
|
-
// Prepare props for Email component - MOVED BEFORE isShowEmailCreate to avoid circular dependency
|
|
560
|
-
const emailProps = useMemo(() => {
|
|
561
|
-
// Determine editor type and mode based on selectedCreateMode
|
|
562
|
-
let editorType = editor;
|
|
563
|
-
let selectedEditorMode = null;
|
|
564
|
-
|
|
565
|
-
if (!supportCKEditorFlag) {
|
|
566
|
-
// CRITICAL: Check selectedCreateMode FIRST to prioritize user's explicit selection
|
|
567
|
-
// This ensures DRAG_DROP selection takes precedence over edit mode detection
|
|
568
|
-
// even if templateDetails persists from a previous template
|
|
569
|
-
if (selectedCreateMode === EMAIL_CREATE_MODES.DRAG_DROP) {
|
|
570
|
-
// CRITICAL: DRAG_DROP mode always uses BEE editor
|
|
571
|
-
// This takes precedence over edit mode detection
|
|
572
|
-
editorType = 'BEE';
|
|
573
|
-
selectedEditorMode = null; // BEE uses existing flow (null indicates BEE editor)
|
|
574
|
-
} else if (selectedCreateMode === EMAIL_CREATE_MODES.HTML_EDITOR) {
|
|
575
|
-
// HTML_EDITOR mode: Always use HTML editor
|
|
576
|
-
editorType = 'HTML';
|
|
577
|
-
selectedEditorMode = EMAIL_CREATE_MODES.HTML_EDITOR;
|
|
578
|
-
} else {
|
|
579
|
-
// Check if we're editing an existing template
|
|
580
|
-
// CRITICAL: Only treat as edit mode if we have params.id (actual edit URL) or templateData prop
|
|
581
|
-
// Don't use templateDetails existence alone, as it might persist from previous template
|
|
582
|
-
const hasParamsId = params?.id || location?.query?.id || location?.params?.id || location?.pathname?.includes('/edit/');
|
|
583
|
-
const hasTemplateDetails = Email?.templateDetails && !isEmpty(Email.templateDetails);
|
|
584
|
-
const hasBEETemplate = Email?.BEETemplate && !isEmpty(Email.BEETemplate);
|
|
585
|
-
const hasTemplateDataProp = templateData && !isEmpty(templateData);
|
|
586
|
-
// CRITICAL: Consider it edit mode if we have params.id OR templateData prop (library mode)
|
|
587
|
-
// This allows editor type determination even when template data is still loading
|
|
588
|
-
const isEditMode = hasParamsId || hasTemplateDataProp;
|
|
259
|
+
const isShowEmailCreate = !isEmpty(selectedCreateMode) && (!isEmpty(EmailLayout) || SelectedEdmDefaultTemplate);
|
|
589
260
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
// Check if BEE is enabled for org (equivalent to checkBeeEditorAllowedForLibrary)
|
|
635
|
-
// For editor selection:
|
|
636
|
-
// - In full mode: BEE is always enabled
|
|
637
|
-
// - In library mode: Check API response, but if API hasn't responded yet and template is BEE, allow BEE (optimistic)
|
|
638
|
-
// - Also check if editor prop is explicitly "BEE"
|
|
639
|
-
const beeEnabledFromAPI = checkBeeEditorEnabled();
|
|
640
|
-
const isAPIResponsePending = isBeeEditorEnabled === null;
|
|
641
|
-
console.log('***isAPIResponsePending', isAPIResponsePending, 'isDragDrop', isDragDrop, 'isFullMode', isFullMode, 'editor', editor, 'beeEnabledFromAPI', beeEnabledFromAPI, 'isAPIResponsePending && isDragDrop && !isFullMode', isAPIResponsePending && isDragDrop && !isFullMode);
|
|
642
|
-
const isBeeEnabled = isFullMode
|
|
643
|
-
|| (editor === "BEE" && !isFullMode)
|
|
644
|
-
|| beeEnabledFromAPI
|
|
645
|
-
|| (isAPIResponsePending && isDragDrop && !isFullMode); // Optimistic: if template is BEE and API pending, allow BEE
|
|
646
|
-
|
|
647
|
-
// If template was created in BEE AND BEE is enabled → open in BEE editor
|
|
648
|
-
// Otherwise → open in HTML editor (fallback)
|
|
649
|
-
// IMPORTANT: When supportCKEditor is false, default to HTML editor unless explicitly BEE
|
|
650
|
-
if (isDragDrop && isBeeEnabled) {
|
|
651
|
-
editorType = 'BEE';
|
|
652
|
-
selectedEditorMode = null; // BEE uses existing flow
|
|
653
|
-
} else {
|
|
654
|
-
// Fallback to HTML editor if BEE not enabled or template not created in BEE
|
|
655
|
-
// This ensures HTML editor is used when supportCKEditor is false
|
|
656
|
-
editorType = 'HTML';
|
|
657
|
-
selectedEditorMode = EMAIL_CREATE_MODES.HTML_EDITOR;
|
|
658
|
-
}
|
|
659
|
-
} else if (selectedCreateMode === EMAIL_CREATE_MODES.EDITOR) {
|
|
660
|
-
// EDITOR mode: Check if selected template is a BEE template
|
|
661
|
-
// When a default template is selected, it's stored in Templates.BEETemplate
|
|
662
|
-
const beeTemplate = Email?.BEETemplate || SelectedEdmDefaultTemplate;
|
|
663
|
-
const isBEETemplate = beeTemplate && (
|
|
664
|
-
get(beeTemplate, 'versions.base.is_drag_drop') === true
|
|
665
|
-
|| get(beeTemplate, 'base.is_drag_drop') === true
|
|
666
|
-
|| beeTemplate.is_drag_drop === true
|
|
667
|
-
);
|
|
668
|
-
|
|
669
|
-
if (isBEETemplate && checkBeeEditorEnabled()) {
|
|
670
|
-
// Template is BEE and BEE is enabled → use BEE editor
|
|
671
|
-
editorType = 'BEE';
|
|
672
|
-
selectedEditorMode = null; // BEE uses existing flow
|
|
673
|
-
} else {
|
|
674
|
-
// Template is not BEE or BEE is disabled → use HTML editor
|
|
675
|
-
editorType = 'HTML';
|
|
676
|
-
selectedEditorMode = EMAIL_CREATE_MODES.HTML_EDITOR;
|
|
677
|
-
}
|
|
678
|
-
} else {
|
|
679
|
-
// Default: When supportCKEditor is false and no mode selected, use HTML editor
|
|
680
|
-
editorType = 'HTML';
|
|
681
|
-
selectedEditorMode = EMAIL_CREATE_MODES.HTML_EDITOR;
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
// UPLOAD mode uses existing editor prop
|
|
685
|
-
}
|
|
686
|
-
// Legacy flow (supportCKEditor is true): Use existing editor prop as-is - no changes
|
|
687
|
-
|
|
688
|
-
// Determine template name for edit mode
|
|
689
|
-
let finalTemplateName = templateName;
|
|
690
|
-
if (Email?.templateDetails?.name) {
|
|
691
|
-
finalTemplateName = Email.templateDetails.name;
|
|
692
|
-
} else if (templateData?.name) {
|
|
693
|
-
finalTemplateName = templateData.name;
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
// Determine params - include id for edit mode
|
|
697
|
-
const emailParams = {};
|
|
698
|
-
if (params?.id) {
|
|
699
|
-
emailParams.id = params.id;
|
|
700
|
-
} else if (location?.query?.id) {
|
|
701
|
-
emailParams.id = location.query.id;
|
|
702
|
-
} else if (location?.params?.id) {
|
|
703
|
-
emailParams.id = location.params.id;
|
|
704
|
-
} else if (location?.pathname?.includes('/edit/')) {
|
|
705
|
-
// Extract id from pathname if it's in the format /edit/:id
|
|
706
|
-
const match = location.pathname.match(/\/edit\/([^/]+)/);
|
|
707
|
-
if (match) {
|
|
708
|
-
emailParams.id = match[1];
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
return {
|
|
713
|
-
setIsLoadingContent,
|
|
714
|
-
key: "email-create-template",
|
|
715
|
-
location: routeParams,
|
|
716
|
-
route: { name: 'email' },
|
|
717
|
-
params: emailParams,
|
|
718
|
-
isGetFormData,
|
|
719
|
-
getFormdata,
|
|
720
|
-
getFormSubscriptionData: getFormdata,
|
|
721
|
-
getDefaultTags: type,
|
|
722
|
-
isFullMode,
|
|
723
|
-
defaultData: { 'template-name': finalTemplateName },
|
|
724
|
-
cap,
|
|
725
|
-
showTemplateName,
|
|
726
|
-
showLiquidErrorInFooter,
|
|
727
|
-
onValidationFail,
|
|
728
|
-
forwardedTags,
|
|
729
|
-
selectedOfferDetails,
|
|
730
|
-
onPreviewContentClicked,
|
|
731
|
-
onTestContentClicked,
|
|
732
|
-
editor: editorType,
|
|
733
|
-
selectedEditorMode, // Pass selected mode to Email component (only for HTML_EDITOR)
|
|
734
|
-
moduleType,
|
|
735
|
-
eventContextTags,
|
|
736
|
-
isLoyaltyModule,
|
|
737
|
-
showTestAndPreviewSlidebox,
|
|
738
|
-
handleTestAndPreview,
|
|
739
|
-
handleCloseTestAndPreview,
|
|
740
|
-
isTestAndPreviewMode,
|
|
741
|
-
};
|
|
742
|
-
}, [
|
|
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
|
+
}), [
|
|
743
305
|
setIsLoadingContent,
|
|
744
306
|
routeParams,
|
|
745
|
-
Email?.BEETemplate,
|
|
746
|
-
Email?.templateDetails, // Include templateDetails so editor type recalculates when template loads
|
|
747
|
-
SelectedEdmDefaultTemplate,
|
|
748
|
-
checkBeeEditorEnabled,
|
|
749
307
|
isGetFormData,
|
|
750
308
|
getFormdata,
|
|
751
309
|
type,
|
|
@@ -767,118 +325,8 @@ const useEmailWrapper = ({
|
|
|
767
325
|
handleTestAndPreview,
|
|
768
326
|
handleCloseTestAndPreview,
|
|
769
327
|
isTestAndPreviewMode,
|
|
770
|
-
selectedCreateMode,
|
|
771
|
-
supportCKEditorFlag,
|
|
772
|
-
checkBeeEditorEnabled,
|
|
773
|
-
isBeeEditorEnabled, // Include to recalculate when API response arrives
|
|
774
|
-
Email,
|
|
775
|
-
location,
|
|
776
|
-
params,
|
|
777
|
-
editor,
|
|
778
|
-
isFullMode,
|
|
779
|
-
templateData,
|
|
780
|
-
templateName,
|
|
781
328
|
]);
|
|
782
329
|
|
|
783
|
-
const isShowEmailCreate = useMemo(() => {
|
|
784
|
-
// Check if we're in edit mode (templateDetails or BEETemplate exists, or params.id exists)
|
|
785
|
-
const hasTemplateDetails = Email?.templateDetails && !isEmpty(Email.templateDetails);
|
|
786
|
-
const hasBEETemplate = Email?.BEETemplate && !isEmpty(Email.BEETemplate);
|
|
787
|
-
const hasParamsId = params?.id || location?.query?.id || location?.params?.id || location?.pathname?.includes('/edit/');
|
|
788
|
-
const isEditMode = hasTemplateDetails || hasBEETemplate || hasParamsId;
|
|
789
|
-
|
|
790
|
-
// In edit mode (when supportCKEditor is false), always show editor
|
|
791
|
-
if (!supportCKEditorFlag && isEditMode) {
|
|
792
|
-
// Check if it's explicitly BEE editor
|
|
793
|
-
const isExplicitlyBEE = emailCreateMode === EMAIL_CREATE_MODES.DRAG_DROP
|
|
794
|
-
|| (emailProps?.editor === 'BEE' && emailProps?.selectedEditorMode === null);
|
|
795
|
-
// Show editor for both BEE and HTML in edit mode
|
|
796
|
-
return true;
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
if (!selectedCreateMode) return false;
|
|
800
|
-
|
|
801
|
-
// For HTML Editor (new flow): Always show editor directly without template selection
|
|
802
|
-
// This takes precedence over step check to ensure HTML Editor is shown even if step is temporarily TEMPLATE_SELECTION
|
|
803
|
-
if (!supportCKEditorFlag && selectedCreateMode === EMAIL_CREATE_MODES.HTML_EDITOR) {
|
|
804
|
-
return true;
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
// CRITICAL: For DRAG_DROP mode, show template selection first (CmsTemplatesComponent)
|
|
808
|
-
// Only show editor (Email component with BEE) after template is selected
|
|
809
|
-
if (emailCreateMode === EMAIL_CREATE_MODES.DRAG_DROP || selectedCreateMode === EMAIL_CREATE_MODES.DRAG_DROP) {
|
|
810
|
-
// If we're in TEMPLATE_SELECTION step, show template selection (not email editor)
|
|
811
|
-
if (currentStep === STEPS.TEMPLATE_SELECTION) {
|
|
812
|
-
return false;
|
|
813
|
-
}
|
|
814
|
-
// After template selection, show editor when template is selected
|
|
815
|
-
return !isEmpty(SelectedEdmDefaultTemplate);
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
// If we're in TEMPLATE_SELECTION step, show template selection (not email editor)
|
|
819
|
-
// This applies to legacy Editor modes
|
|
820
|
-
if (currentStep === STEPS.TEMPLATE_SELECTION) {
|
|
821
|
-
return false;
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
// For Upload: Show editor when EmailLayout exists
|
|
825
|
-
if (emailCreateMode === EMAIL_CREATE_MODES.UPLOAD) {
|
|
826
|
-
return !isEmpty(EmailLayout);
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
// For Editor: Show editor when template is selected
|
|
830
|
-
return !isEmpty(SelectedEdmDefaultTemplate);
|
|
831
|
-
}, [currentStep, selectedCreateMode, supportCKEditorFlag, emailCreateMode, EmailLayout, SelectedEdmDefaultTemplate, Email?.templateDetails, Email?.BEETemplate, params?.id, location?.query?.id, location?.params?.id, location?.pathname, emailProps?.editor, emailProps?.selectedEditorMode]);
|
|
832
|
-
|
|
833
|
-
// Memoize static data
|
|
834
|
-
const modes = useMemo(() => {
|
|
835
|
-
const supportCKEditor = hasSupportCKEditor();
|
|
836
|
-
const isBeeEditorEnabledValue = checkBeeEditorEnabled();
|
|
837
|
-
|
|
838
|
-
if (supportCKEditor) {
|
|
839
|
-
// Legacy flow: Show only 2 options (Upload Zip, Use Editor)
|
|
840
|
-
return [
|
|
841
|
-
{
|
|
842
|
-
title: formatMessage(messages.zipUpload),
|
|
843
|
-
content: formatMessage(messages.zipUploadDesc),
|
|
844
|
-
value: EMAIL_CREATE_MODES.UPLOAD,
|
|
845
|
-
},
|
|
846
|
-
{
|
|
847
|
-
title: formatMessage(messages.useEditor),
|
|
848
|
-
content: formatMessage(messages.useEditorDesc),
|
|
849
|
-
value: EMAIL_CREATE_MODES.EDITOR,
|
|
850
|
-
},
|
|
851
|
-
];
|
|
852
|
-
}
|
|
853
|
-
|
|
854
|
-
// New flow: Show 3 options (HTML Editor, Drag & Drop, Upload Zip)
|
|
855
|
-
return [
|
|
856
|
-
{
|
|
857
|
-
title: formatMessage(messages.htmlEditorTitle),
|
|
858
|
-
content: formatMessage(messages.htmlEditorDesc),
|
|
859
|
-
value: EMAIL_CREATE_MODES.HTML_EDITOR,
|
|
860
|
-
icon: <CapIcon type="code" />,
|
|
861
|
-
},
|
|
862
|
-
{
|
|
863
|
-
title: formatMessage(messages.dragDropEditorTitle),
|
|
864
|
-
content: formatMessage(messages.dragDropEditorDesc),
|
|
865
|
-
value: EMAIL_CREATE_MODES.DRAG_DROP,
|
|
866
|
-
icon: <CapIcon type="draggable" svgProps={{ fill: 'currentColor' }} />,
|
|
867
|
-
disabled: !isBeeEditorEnabledValue,
|
|
868
|
-
tooltipProps: !isBeeEditorEnabledValue ? {
|
|
869
|
-
title: formatMessage(messages.beeEditorDisabledTooltip),
|
|
870
|
-
placement: 'top',
|
|
871
|
-
} : undefined,
|
|
872
|
-
},
|
|
873
|
-
{
|
|
874
|
-
title: formatMessage(messages.uploadZipTitle),
|
|
875
|
-
content: formatMessage(messages.uploadZipDesc),
|
|
876
|
-
value: EMAIL_CREATE_MODES.UPLOAD,
|
|
877
|
-
icon: <CapIcon type="file" />,
|
|
878
|
-
},
|
|
879
|
-
];
|
|
880
|
-
}, [formatMessage, checkBeeEditorEnabled]);
|
|
881
|
-
|
|
882
330
|
// Prepare props for CmsTemplatesComponent
|
|
883
331
|
const cmsTemplatesProps = useMemo(() => ({
|
|
884
332
|
cmsTemplates: CmsTemplates,
|
|
@@ -910,4 +358,4 @@ const useEmailWrapper = ({
|
|
|
910
358
|
};
|
|
911
359
|
};
|
|
912
360
|
|
|
913
|
-
export default useEmailWrapper;
|
|
361
|
+
export default useEmailWrapper;
|