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