@capillarytech/creatives-library 8.0.271 → 8.0.273
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 +2 -1
- package/initialReducer.js +2 -0
- package/package.json +1 -1
- package/services/api.js +10 -0
- package/services/tests/api.test.js +34 -0
- package/tests/integration/TemplateCreation/TemplateCreation.integration.test.js +17 -35
- package/tests/integration/TemplateCreation/api-response.js +31 -1
- package/tests/integration/TemplateCreation/msw-handler.js +2 -0
- package/utils/common.js +5 -0
- package/utils/commonUtils.js +28 -5
- package/utils/imageUrlUpload.js +13 -14
- package/utils/tests/commonUtil.test.js +224 -0
- package/utils/tests/imageUrlUpload.test.js +298 -0
- package/utils/transformTemplateConfig.js +0 -10
- package/v2Components/CapDeviceContent/index.js +61 -56
- package/v2Components/CapTagList/index.js +6 -1
- package/v2Components/CapTagListWithInput/index.js +5 -1
- package/v2Components/CapTagListWithInput/messages.js +1 -1
- package/v2Components/CapWhatsappCTA/tests/index.test.js +5 -0
- package/v2Components/ErrorInfoNote/constants.js +1 -0
- package/v2Components/ErrorInfoNote/index.js +402 -72
- package/v2Components/ErrorInfoNote/messages.js +32 -6
- package/v2Components/ErrorInfoNote/style.scss +278 -6
- package/v2Components/FormBuilder/tests/index.test.js +13 -4
- package/v2Components/HtmlEditor/HTMLEditor.js +418 -99
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +870 -0
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +1882 -133
- package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +27 -16
- package/v2Components/HtmlEditor/_htmlEditor.scss +108 -45
- package/v2Components/HtmlEditor/_index.lazy.scss +0 -1
- package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +23 -102
- package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +148 -140
- package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +2 -1
- package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
- package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +9 -1
- package/v2Components/HtmlEditor/components/EditorToolbar/index.js +31 -6
- package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +22 -0
- package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +4 -7
- package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +35 -45
- package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +1 -3
- package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
- package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +7 -6
- package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +7 -10
- package/v2Components/HtmlEditor/components/PreviewPane/index.js +22 -43
- package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
- package/v2Components/HtmlEditor/components/ValidationErrorDisplay/_validationErrorDisplay.scss +18 -0
- package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +36 -31
- package/v2Components/HtmlEditor/components/ValidationPanel/_validationPanel.scss +46 -34
- package/v2Components/HtmlEditor/components/ValidationPanel/constants.js +6 -0
- package/v2Components/HtmlEditor/components/ValidationPanel/index.js +52 -46
- package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +277 -0
- package/v2Components/HtmlEditor/components/ValidationTabs/index.js +295 -0
- package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +51 -0
- package/v2Components/HtmlEditor/constants.js +45 -20
- package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +373 -16
- package/v2Components/HtmlEditor/hooks/__tests__/useValidation.test.js +351 -16
- package/v2Components/HtmlEditor/hooks/useEditorContent.js +5 -2
- package/v2Components/HtmlEditor/hooks/useInAppContent.js +88 -146
- package/v2Components/HtmlEditor/hooks/useValidation.js +213 -56
- package/v2Components/HtmlEditor/index.js +1 -1
- package/v2Components/HtmlEditor/messages.js +102 -94
- package/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +214 -45
- package/v2Components/HtmlEditor/utils/__tests__/validationAdapter.test.js +134 -0
- package/v2Components/HtmlEditor/utils/contentSanitizer.js +40 -41
- package/v2Components/HtmlEditor/utils/htmlValidator.js +71 -72
- package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +158 -124
- package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +23 -25
- package/v2Components/HtmlEditor/utils/validationAdapter.js +66 -41
- package/v2Components/HtmlEditor/utils/validationConstants.js +38 -0
- package/v2Components/MobilePushPreviewV2/constants.js +6 -0
- package/v2Components/MobilePushPreviewV2/index.js +33 -7
- package/v2Components/TemplatePreview/_templatePreview.scss +55 -24
- package/v2Components/TemplatePreview/index.js +47 -32
- package/v2Components/TemplatePreview/messages.js +4 -0
- package/v2Components/TestAndPreviewSlidebox/_testAndPreviewSlidebox.scss +1 -0
- package/v2Containers/BeeEditor/index.js +172 -90
- package/v2Containers/BeePopupEditor/_beePopupEditor.scss +14 -0
- package/v2Containers/BeePopupEditor/constants.js +10 -0
- package/v2Containers/BeePopupEditor/index.js +194 -0
- package/v2Containers/BeePopupEditor/tests/index.test.js +627 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +127 -51
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +156 -13
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +2 -1
- package/v2Containers/CreativesContainer/constants.js +1 -0
- package/v2Containers/CreativesContainer/index.js +251 -47
- package/v2Containers/CreativesContainer/messages.js +8 -0
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +11 -2
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +38 -50
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +103 -0
- package/v2Containers/Email/actions.js +7 -0
- package/v2Containers/Email/constants.js +5 -1
- package/v2Containers/Email/index.js +234 -29
- package/v2Containers/Email/messages.js +32 -0
- package/v2Containers/Email/reducer.js +12 -1
- package/v2Containers/Email/sagas.js +61 -7
- package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +2 -0
- package/v2Containers/Email/tests/reducer.test.js +46 -0
- package/v2Containers/Email/tests/sagas.test.js +320 -29
- package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +1246 -0
- package/v2Containers/EmailWrapper/components/EmailWrapperView.js +212 -21
- package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +40 -74
- package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +2614 -0
- package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +520 -0
- package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +2 -67
- package/v2Containers/EmailWrapper/constants.js +2 -0
- package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +627 -79
- package/v2Containers/EmailWrapper/index.js +103 -23
- package/v2Containers/EmailWrapper/messages.js +65 -1
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +955 -0
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +596 -82
- package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +376 -0
- package/v2Containers/InApp/__tests__/sagas.test.js +363 -0
- package/v2Containers/InApp/actions.js +7 -0
- package/v2Containers/InApp/constants.js +20 -4
- package/v2Containers/InApp/index.js +802 -360
- package/v2Containers/InApp/index.scss +4 -3
- package/v2Containers/InApp/messages.js +7 -3
- package/v2Containers/InApp/reducer.js +21 -3
- package/v2Containers/InApp/sagas.js +29 -9
- package/v2Containers/InApp/selectors.js +25 -5
- package/v2Containers/InApp/tests/index.test.js +154 -50
- package/v2Containers/InApp/tests/reducer.test.js +34 -0
- package/v2Containers/InApp/tests/sagas.test.js +61 -9
- package/v2Containers/InApp/tests/selectors.test.js +612 -0
- package/v2Containers/InAppWrapper/components/InAppWrapperView.js +151 -0
- package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +267 -0
- package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +23 -0
- package/v2Containers/InAppWrapper/constants.js +16 -0
- package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +473 -0
- package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +198 -0
- package/v2Containers/InAppWrapper/index.js +148 -0
- package/v2Containers/InAppWrapper/messages.js +49 -0
- package/v2Containers/InappAdvance/index.js +1099 -0
- package/v2Containers/InappAdvance/index.scss +10 -0
- package/v2Containers/InappAdvance/tests/index.test.js +448 -0
- package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +3 -0
- package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +2 -0
- package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +2 -0
- package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +9 -0
- package/v2Containers/MobilePush/Create/index.js +1 -1
- package/v2Containers/MobilePush/Edit/index.js +10 -6
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +12 -0
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4 -0
- package/v2Containers/TagList/index.js +62 -19
- package/v2Containers/Templates/_templates.scss +60 -1
- package/v2Containers/Templates/index.js +89 -4
- package/v2Containers/Templates/messages.js +4 -0
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +4 -2
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +34 -0
- package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +0 -152
- package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +0 -214
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
CAP_SPACE_16, CAP_SPACE_32, CAP_SPACE_56, CAP_SPACE_64,
|
|
5
|
+
} from '@capillarytech/cap-ui-library/styled/variables';
|
|
4
6
|
|
|
5
7
|
import CapSlideBox from '@capillarytech/cap-ui-library/CapSlideBox';
|
|
6
8
|
import CapHeader from '@capillarytech/cap-ui-library/CapHeader';
|
|
@@ -44,7 +46,7 @@ import {
|
|
|
44
46
|
} from '../Line/Container/constants';
|
|
45
47
|
import {EXTERNAL_URL, SITE_URL, WEBPUSH_MEDIA_TYPES} from '../WebPush/constants';
|
|
46
48
|
import { IMAGE, VIDEO } from '../Facebook/Advertisement/constant';
|
|
47
|
-
import {RCS_STATUSES} from '../Rcs/constants';
|
|
49
|
+
import { RCS_STATUSES } from '../Rcs/constants';
|
|
48
50
|
import { CREATIVE } from '../Facebook/constants';
|
|
49
51
|
import { LOYALTY } from '../App/constants';
|
|
50
52
|
import {
|
|
@@ -65,19 +67,29 @@ import {
|
|
|
65
67
|
// getTemplateDiffState
|
|
66
68
|
} from "../../utils/transformerUtils";
|
|
67
69
|
import { MANUAL_CAROUSEL } from '../MobilePushNew/constants';
|
|
70
|
+
import { BIG_HTML } from '../InApp/constants';
|
|
68
71
|
|
|
69
72
|
const classPrefix = 'add-creatives-section';
|
|
70
73
|
const CREATIVES_CONTAINER = 'creativesContainer';
|
|
71
74
|
|
|
72
75
|
const SlideBoxWrapper = styled.div`
|
|
73
76
|
.cap-slide-box-v2-container{
|
|
74
|
-
.slidebox-header, .slidebox-content-container
|
|
77
|
+
.slidebox-header, .slidebox-content-container{
|
|
75
78
|
margin-bottom: ${({ slideBoxWrapperMargin }) => `${slideBoxWrapperMargin}`};
|
|
76
79
|
padding: 0 rem;
|
|
77
80
|
&.has-footer{
|
|
78
81
|
overflow-x: hidden;
|
|
79
82
|
}
|
|
80
83
|
}
|
|
84
|
+
.slidebox-footer{
|
|
85
|
+
/* Only apply margin-bottom to footer when ErrorInfoNote is shown in footer (BEE editor) */
|
|
86
|
+
/* For HTML Editor, errors are shown in ValidationErrorDisplay (inside content area), so no footer margin needed */
|
|
87
|
+
margin-bottom: ${({ shouldApplyFooterMargin }) => (shouldApplyFooterMargin ? `${CAP_SPACE_16}` : '0')};
|
|
88
|
+
padding: 0 rem;
|
|
89
|
+
&.has-footer{
|
|
90
|
+
overflow-x: hidden;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
81
93
|
}
|
|
82
94
|
`;
|
|
83
95
|
export class Creatives extends React.Component {
|
|
@@ -96,6 +108,7 @@ export class Creatives extends React.Component {
|
|
|
96
108
|
currentChannel: this.props.channel || 'sms',
|
|
97
109
|
weChatTemplateType: '',
|
|
98
110
|
weChatMaptemplateStep: 0,
|
|
111
|
+
inAppEditorType: null,
|
|
99
112
|
isLiquidValidationError: false,
|
|
100
113
|
errorMessages: [],
|
|
101
114
|
liquidErrorMessage: {
|
|
@@ -108,6 +121,15 @@ export class Creatives extends React.Component {
|
|
|
108
121
|
isTestAndPreviewMode: false, // Add flag to track Test & Preview mode
|
|
109
122
|
// Performance optimization: Local template name for immediate UI feedback
|
|
110
123
|
localTemplateName: '',
|
|
124
|
+
// Track selected email create mode for new flow (HTML Editor vs Drag & Drop)
|
|
125
|
+
selectedEmailCreateMode: null,
|
|
126
|
+
// HTML Editor validation state (for email channel)
|
|
127
|
+
htmlEditorValidationState: {
|
|
128
|
+
isContentEmpty: true,
|
|
129
|
+
issueCounts: { errors: 0, warnings: 0, total: 0 },
|
|
130
|
+
validationComplete: false, // Flag to track if validation has completed
|
|
131
|
+
errorsAcknowledged: false, // Flag to track if user has acknowledged errors by clicking redirection icon
|
|
132
|
+
},
|
|
111
133
|
};
|
|
112
134
|
this.liquidFlow = Boolean(commonUtil.hasLiquidSupportFeature());
|
|
113
135
|
this.creativesTemplateSteps = {
|
|
@@ -137,7 +159,7 @@ export class Creatives extends React.Component {
|
|
|
137
159
|
if (!this.props?.isFullMode) {
|
|
138
160
|
this.props?.templateActions.getCdnTransformationConfig();
|
|
139
161
|
}
|
|
140
|
-
|
|
162
|
+
|
|
141
163
|
// Store loyalty tag props if loyaltyTagFetchingDependencies is provided
|
|
142
164
|
const { loyaltyTagFetchingDependencies } = this.props;
|
|
143
165
|
if (loyaltyTagFetchingDependencies) {
|
|
@@ -163,9 +185,9 @@ export class Creatives extends React.Component {
|
|
|
163
185
|
const isEmptyTemplateName = !value.trim();
|
|
164
186
|
|
|
165
187
|
// 1. IMMEDIATE: Update local state for instant UI feedback
|
|
166
|
-
this.setState({
|
|
188
|
+
this.setState({
|
|
167
189
|
isTemplateNameEmpty: isEmptyTemplateName,
|
|
168
|
-
localTemplateName: value
|
|
190
|
+
localTemplateName: value,
|
|
169
191
|
});
|
|
170
192
|
|
|
171
193
|
// 2. DEBOUNCED: Only debounce the expensive onFormDataChange call
|
|
@@ -244,8 +266,19 @@ export class Creatives extends React.Component {
|
|
|
244
266
|
onCreateNextStep = () => {
|
|
245
267
|
this.setState((prevState) => {
|
|
246
268
|
let templateStep = prevState.templateStep + 1;
|
|
247
|
-
const { emailCreateMode, currentChannel } = prevState;
|
|
248
|
-
|
|
269
|
+
const { emailCreateMode, currentChannel, selectedEmailCreateMode } = prevState;
|
|
270
|
+
|
|
271
|
+
// Check if we should skip template selection for HTML Editor
|
|
272
|
+
const supportCKEditor = commonUtil.hasSupportCKEditor();
|
|
273
|
+
const shouldSkipTemplateSelection = !supportCKEditor
|
|
274
|
+
&& selectedEmailCreateMode === 'html_editor'
|
|
275
|
+
&& currentChannel.toUpperCase() === constants.EMAIL
|
|
276
|
+
&& prevState.templateStep === 1; // Only skip if we're at modeSelection step
|
|
277
|
+
|
|
278
|
+
if (shouldSkipTemplateSelection) {
|
|
279
|
+
// Skip template selection (step 2), go directly to createTemplateContent (step 3)
|
|
280
|
+
templateStep = prevState.templateStep + 2;
|
|
281
|
+
} else if ((currentChannel.toUpperCase() === constants.EMAIL && emailCreateMode === "upload") || [constants.MOBILE_PUSH, constants.WECHAT, constants.INAPP].includes(currentChannel.toUpperCase())) {
|
|
249
282
|
templateStep = prevState.templateStep + 2;
|
|
250
283
|
}
|
|
251
284
|
return {
|
|
@@ -254,14 +287,21 @@ export class Creatives extends React.Component {
|
|
|
254
287
|
});
|
|
255
288
|
}
|
|
256
289
|
|
|
257
|
-
onEmailModeChange = (mode) => {
|
|
258
|
-
this.setState({
|
|
290
|
+
onEmailModeChange = (mode, selectedMode = null) => {
|
|
291
|
+
this.setState({
|
|
292
|
+
emailCreateMode: mode,
|
|
293
|
+
selectedEmailCreateMode: selectedMode || mode, // Store the selected mode for new flow
|
|
294
|
+
});
|
|
259
295
|
}
|
|
260
296
|
|
|
261
297
|
onInAppModeChange = (mode) => {
|
|
262
298
|
this.setState({ inAppCreateMode: mode });
|
|
263
299
|
}
|
|
264
300
|
|
|
301
|
+
onInAppEditorTypeChange = (editorType) => {
|
|
302
|
+
this.setState({ inAppEditorType: editorType });
|
|
303
|
+
}
|
|
304
|
+
|
|
265
305
|
onMobilepushModeChange = (mode) => {
|
|
266
306
|
this.setState({ mobilePushCreateMode: mode });
|
|
267
307
|
}
|
|
@@ -305,7 +345,7 @@ export class Creatives extends React.Component {
|
|
|
305
345
|
}
|
|
306
346
|
return buttonObj;
|
|
307
347
|
});
|
|
308
|
-
const {url, previewUrl} = media || {};
|
|
348
|
+
const { url, previewUrl } = media || {};
|
|
309
349
|
return {
|
|
310
350
|
bodyText: bodyTemplate,
|
|
311
351
|
varMap: cardVarMapped,
|
|
@@ -434,14 +474,35 @@ export class Creatives extends React.Component {
|
|
|
434
474
|
}
|
|
435
475
|
case constants.INAPP: {
|
|
436
476
|
const mode = get(templateData, 'androidContent.type') || get(templateData, 'iosContent.type') || '';
|
|
477
|
+
|
|
478
|
+
// Check if this is a BEE editor template (identified by special title 'bee free template')
|
|
479
|
+
const isAndroidBeeEditor = templateData?.androidContent?.type === constants.HTML
|
|
480
|
+
&& templateData?.androidContent?.title?.toLowerCase() === 'bee free template';
|
|
481
|
+
const isIosBeeEditor = templateData?.iosContent?.type === constants.HTML
|
|
482
|
+
&& templateData?.iosContent?.title?.toLowerCase() === 'bee free template';
|
|
483
|
+
|
|
437
484
|
creativesTemplateData = {
|
|
438
485
|
type: channel,
|
|
439
486
|
name: templateData.messageSubject,
|
|
440
487
|
versions: {
|
|
441
488
|
base: {
|
|
442
489
|
content: {
|
|
443
|
-
ANDROID:
|
|
444
|
-
|
|
490
|
+
ANDROID: isAndroidBeeEditor ? {
|
|
491
|
+
type: templateData?.androidContent?.type,
|
|
492
|
+
bodyType: templateData?.androidContent?.bodyType,
|
|
493
|
+
deviceType: constants.ANDROID,
|
|
494
|
+
beeHtml: { value: templateData?.androidContent?.message },
|
|
495
|
+
beeJson: templateData?.androidContent?.expandableDetails?.message,
|
|
496
|
+
isBEEeditor: true,
|
|
497
|
+
} : templateData?.androidContent,
|
|
498
|
+
IOS: isIosBeeEditor ? {
|
|
499
|
+
type: templateData?.iosContent?.type,
|
|
500
|
+
bodyType: templateData?.iosContent?.bodyType,
|
|
501
|
+
deviceType: constants.IOS,
|
|
502
|
+
beeHtml: { value: templateData?.iosContent?.message },
|
|
503
|
+
beeJson: templateData?.iosContent?.expandableDetails?.message,
|
|
504
|
+
isBEEeditor: true,
|
|
505
|
+
} : templateData?.iosContent,
|
|
445
506
|
},
|
|
446
507
|
},
|
|
447
508
|
},
|
|
@@ -676,7 +737,7 @@ export class Creatives extends React.Component {
|
|
|
676
737
|
} = templateData || {};
|
|
677
738
|
const cardContent = (rcsContent.cardContent && rcsContent.cardContent[0]) || {};
|
|
678
739
|
const Status = RCS_STATUSES.approved || '';
|
|
679
|
-
|
|
740
|
+
|
|
680
741
|
creativesTemplateData = {
|
|
681
742
|
type: channel,
|
|
682
743
|
edit: true,
|
|
@@ -828,7 +889,7 @@ export class Creatives extends React.Component {
|
|
|
828
889
|
});
|
|
829
890
|
|
|
830
891
|
getMobilePushCarouselData = (expandableDetails = []) => {
|
|
831
|
-
const newExpandableDetails = {...expandableDetails};
|
|
892
|
+
const newExpandableDetails = { ...expandableDetails };
|
|
832
893
|
newExpandableDetails.style = expandableDetails.style || MANUAL_CAROUSEL;
|
|
833
894
|
newExpandableDetails.message = expandableDetails.message || '';
|
|
834
895
|
newExpandableDetails.ctas = expandableDetails.ctas || [];
|
|
@@ -923,11 +984,24 @@ export class Creatives extends React.Component {
|
|
|
923
984
|
androidContent.custom = custom;
|
|
924
985
|
}
|
|
925
986
|
if (channel === constants.MOBILE_PUSH && androidContent?.expandableDetails?.carouselData?.length) {
|
|
926
|
-
androidContent.expandableDetails = this.getMobilePushCarouselData({...androidContent?.expandableDetails});
|
|
987
|
+
androidContent.expandableDetails = this.getMobilePushCarouselData({ ...androidContent?.expandableDetails });
|
|
988
|
+
}
|
|
989
|
+
if (androidContent?.isBEEeditor && androidContent?.beeHtml?.value) {
|
|
990
|
+
templateData.androidContent = {};
|
|
991
|
+
templateData.androidContent.type = constants.HTML;
|
|
992
|
+
templateData.androidContent.message = androidContent?.beeHtml?.value || '';
|
|
993
|
+
templateData.androidContent.title = 'bee free template';
|
|
994
|
+
templateData.androidContent.bodyType = androidContent?.bodyType;
|
|
995
|
+
templateData.androidContent.deviceType = constants.ANDROID;
|
|
996
|
+
templateData.androidContent.expandableDetails = {
|
|
997
|
+
style: BIG_HTML,
|
|
998
|
+
message: androidContent?.beeJson || '',
|
|
999
|
+
};
|
|
1000
|
+
} else if (!androidContent?.isBEEeditor) {
|
|
1001
|
+
templateData.androidContent = androidContent;
|
|
1002
|
+
templateData.androidContent.type = androidContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || constants.TEXT;
|
|
1003
|
+
templateData.androidContent.deviceType = constants.ANDROID;
|
|
927
1004
|
}
|
|
928
|
-
templateData.androidContent = androidContent;
|
|
929
|
-
templateData.androidContent.type = androidContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || constants.TEXT;
|
|
930
|
-
templateData.androidContent.deviceType = constants.ANDROID;
|
|
931
1005
|
}
|
|
932
1006
|
const iosContent = channel === constants.INAPP ? get(channelTemplate, 'versions.base.content.IOS') : get(channelTemplate, 'versions.base.IOS');
|
|
933
1007
|
if (!isEmpty(iosContent)) {
|
|
@@ -945,11 +1019,24 @@ export class Creatives extends React.Component {
|
|
|
945
1019
|
iosContent.custom = custom;
|
|
946
1020
|
}
|
|
947
1021
|
if (channel === constants.MOBILE_PUSH && iosContent?.expandableDetails?.carouselData?.length) {
|
|
948
|
-
iosContent.expandableDetails = this.getMobilePushCarouselData({...iosContent?.expandableDetails});
|
|
1022
|
+
iosContent.expandableDetails = this.getMobilePushCarouselData({ ...iosContent?.expandableDetails });
|
|
1023
|
+
}
|
|
1024
|
+
if (iosContent?.isBEEeditor && iosContent?.beeHtml?.value) {
|
|
1025
|
+
templateData.iosContent = {};
|
|
1026
|
+
templateData.iosContent.type = constants.HTML;
|
|
1027
|
+
templateData.iosContent.message = iosContent?.beeHtml?.value || '';
|
|
1028
|
+
templateData.iosContent.title = 'bee free template';
|
|
1029
|
+
templateData.iosContent.bodyType = iosContent?.bodyType;
|
|
1030
|
+
templateData.iosContent.deviceType = constants.IOS;
|
|
1031
|
+
templateData.iosContent.expandableDetails = {
|
|
1032
|
+
style: BIG_HTML,
|
|
1033
|
+
message: iosContent?.beeJson || '',
|
|
1034
|
+
};
|
|
1035
|
+
} else if (!iosContent?.isBEEeditor) {
|
|
1036
|
+
templateData.iosContent = iosContent;
|
|
1037
|
+
templateData.iosContent.type = iosContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || 'TEXT';
|
|
1038
|
+
templateData.iosContent.deviceType = constants.IOS;
|
|
949
1039
|
}
|
|
950
|
-
templateData.iosContent = iosContent;
|
|
951
|
-
templateData.iosContent.type = iosContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || 'TEXT';
|
|
952
|
-
templateData.iosContent.deviceType = constants.IOS;
|
|
953
1040
|
}
|
|
954
1041
|
templateData.messageSubject = channelTemplate?.name ? channelTemplate?.name : "messageSubject";
|
|
955
1042
|
}
|
|
@@ -1164,7 +1251,7 @@ export class Creatives extends React.Component {
|
|
|
1164
1251
|
contentType = "",
|
|
1165
1252
|
cardType = "",
|
|
1166
1253
|
cardSettings = {},
|
|
1167
|
-
} = get(versions, 'base.content.RCS.rcsContent',{});
|
|
1254
|
+
} = get(versions, 'base.content.RCS.rcsContent', {});
|
|
1168
1255
|
const rcsContent = {
|
|
1169
1256
|
contentType,
|
|
1170
1257
|
cardType,
|
|
@@ -1402,7 +1489,7 @@ export class Creatives extends React.Component {
|
|
|
1402
1489
|
processCentralCommsMetaId = (channel, creativesData) => {
|
|
1403
1490
|
// Create the payload for the centralcommnsmetaId API call
|
|
1404
1491
|
const { isLoyaltyModule = false, loyaltyMetaData = {} } = this.props;
|
|
1405
|
-
const { actionName, setMetaData = () => {} } = loyaltyMetaData;
|
|
1492
|
+
const { actionName, setMetaData = () => { } } = loyaltyMetaData;
|
|
1406
1493
|
|
|
1407
1494
|
// const isTemplateModified = getTemplateDiffState(
|
|
1408
1495
|
// channel,
|
|
@@ -1452,6 +1539,9 @@ export class Creatives extends React.Component {
|
|
|
1452
1539
|
if (prevState.currentChannel.toUpperCase() === constants.EMAIL) {
|
|
1453
1540
|
newState = { ...newState, emailCreateMode: null };
|
|
1454
1541
|
}
|
|
1542
|
+
if (prevState.currentChannel.toUpperCase() === constants.INAPP) {
|
|
1543
|
+
newState = { ...newState, inAppEditorType: null };
|
|
1544
|
+
}
|
|
1455
1545
|
return newState;
|
|
1456
1546
|
});
|
|
1457
1547
|
}
|
|
@@ -1497,7 +1587,7 @@ export class Creatives extends React.Component {
|
|
|
1497
1587
|
shouldShowFooter = () => {
|
|
1498
1588
|
const { isFullMode } = this.props;
|
|
1499
1589
|
const {
|
|
1500
|
-
slidBoxContent, currentChannel, emailCreateMode, templateNameExists, templateStep, mobilePushCreateMode, weChatTemplateType, templateData,
|
|
1590
|
+
slidBoxContent, currentChannel, emailCreateMode, templateNameExists, templateStep, mobilePushCreateMode, weChatTemplateType, templateData, inAppCreateMode,
|
|
1501
1591
|
} = this.state;
|
|
1502
1592
|
const channel = currentChannel.toUpperCase();
|
|
1503
1593
|
const currentStep = this.creativesTemplateSteps[templateStep];
|
|
@@ -1505,6 +1595,13 @@ export class Creatives extends React.Component {
|
|
|
1505
1595
|
showFooter = isFullMode && slidBoxContent === "preview";
|
|
1506
1596
|
const isMobilepush = channel === constants.MOBILE_PUSH;
|
|
1507
1597
|
|
|
1598
|
+
const supportCKEditor = commonUtil.hasSupportCKEditor();
|
|
1599
|
+
if (!supportCKEditor && channel === constants.EMAIL && currentStep === 'modeSelection' && slidBoxContent === 'createTemplate') {
|
|
1600
|
+
return true;
|
|
1601
|
+
}
|
|
1602
|
+
if (!supportCKEditor && channel === constants.EMAIL && currentStep === 'createTemplateContent' && slidBoxContent === 'createTemplate') {
|
|
1603
|
+
showFooter = true;
|
|
1604
|
+
}
|
|
1508
1605
|
|
|
1509
1606
|
if (!isFullMode) {
|
|
1510
1607
|
const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
|
|
@@ -1516,7 +1613,12 @@ export class Creatives extends React.Component {
|
|
|
1516
1613
|
}
|
|
1517
1614
|
} else if (channel === constants.EMAIL && isFullMode) {
|
|
1518
1615
|
const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
|
|
1519
|
-
|
|
1616
|
+
// CK editor flow: show footer on mode selection when a card is selected so user sees Continue (disabled until name + card)
|
|
1617
|
+
if (supportCKEditor && slidBoxContent === 'createTemplate' && currentStep === 'modeSelection') {
|
|
1618
|
+
showFooter = !!emailCreateMode;
|
|
1619
|
+
} else {
|
|
1620
|
+
showFooter = isEmailCreate && emailCreateMode && templateNameExists;
|
|
1621
|
+
}
|
|
1520
1622
|
}
|
|
1521
1623
|
if (channel === constants.EMAIL && emailCreateMode === "upload") {
|
|
1522
1624
|
showFooter = showFooter && !this.props.isUploading;
|
|
@@ -1540,6 +1642,7 @@ export class Creatives extends React.Component {
|
|
|
1540
1642
|
showFooter = true;
|
|
1541
1643
|
}
|
|
1542
1644
|
|
|
1645
|
+
|
|
1543
1646
|
if (showFooter) {
|
|
1544
1647
|
if (slidBoxContent === "createTemplate" && ((channel === constants.EMAIL && currentStep === 'createTemplateContent')
|
|
1545
1648
|
|| ([constants.SMS, constants.WECHAT].includes(channel) && currentStep === 'modeSelection'))) {
|
|
@@ -1562,7 +1665,7 @@ export class Creatives extends React.Component {
|
|
|
1562
1665
|
|
|
1563
1666
|
shouldShowDoneFooter = () => {
|
|
1564
1667
|
const {
|
|
1565
|
-
slidBoxContent, templateStep, currentChannel, templateData,
|
|
1668
|
+
slidBoxContent, templateStep, currentChannel, templateData, inAppCreateMode,
|
|
1566
1669
|
} = this.state;
|
|
1567
1670
|
const { isFullMode } = this.props;
|
|
1568
1671
|
const currentStep = this.creativesTemplateSteps[templateStep];
|
|
@@ -1570,10 +1673,17 @@ export class Creatives extends React.Component {
|
|
|
1570
1673
|
const channelName = !isFullMode && templateData ? templateData.type : currentChannel;
|
|
1571
1674
|
const channel = channelName?.toUpperCase();
|
|
1572
1675
|
|
|
1573
|
-
|
|
1676
|
+
// Check supportCKEditor flag for new HTML editor flow
|
|
1677
|
+
const supportCKEditor = commonUtil.hasSupportCKEditor();
|
|
1574
1678
|
if (channel === constants.EMAIL || channel === constants.SMS) {
|
|
1575
1679
|
const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
|
|
1576
|
-
|
|
1680
|
+
|
|
1681
|
+
// For new HTML editor flow (when supportCKEditor is false), show Done footer when in createTemplateContent step
|
|
1682
|
+
if (!supportCKEditor && channel === constants.EMAIL && slidBoxContent === 'createTemplate' && currentStep === 'createTemplateContent') {
|
|
1683
|
+
showDone = true;
|
|
1684
|
+
} else {
|
|
1685
|
+
showDone = (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate') && !isEmailCreate;
|
|
1686
|
+
}
|
|
1577
1687
|
} else if ([constants.WECHAT, constants.MOBILE_PUSH].includes(channel)) {
|
|
1578
1688
|
showDone = currentStep === "createTemplateContent" || slidBoxContent === "editTemplate";
|
|
1579
1689
|
|
|
@@ -1583,7 +1693,6 @@ export class Creatives extends React.Component {
|
|
|
1583
1693
|
}
|
|
1584
1694
|
}
|
|
1585
1695
|
|
|
1586
|
-
|
|
1587
1696
|
return showDone;
|
|
1588
1697
|
}
|
|
1589
1698
|
|
|
@@ -1603,18 +1712,18 @@ export class Creatives extends React.Component {
|
|
|
1603
1712
|
templateNameComponentInput = ({ formData, onFormDataChange, name }) => {
|
|
1604
1713
|
// Use local state for immediate UI feedback, fallback to prop value
|
|
1605
1714
|
const displayValue = this.state.localTemplateName !== '' ? this.state.localTemplateName : name;
|
|
1606
|
-
|
|
1715
|
+
|
|
1607
1716
|
return (
|
|
1608
1717
|
<CapInput
|
|
1609
1718
|
value={displayValue}
|
|
1610
1719
|
suffix={<span />}
|
|
1611
|
-
onBlur={() => {
|
|
1612
|
-
this.setState({
|
|
1720
|
+
onBlur={() => {
|
|
1721
|
+
this.setState({
|
|
1613
1722
|
isEditName: false,
|
|
1614
|
-
localTemplateName: '' // Clear local state on blur
|
|
1615
|
-
}, () => {
|
|
1616
|
-
this.showTemplateName({ formData, onFormDataChange });
|
|
1617
|
-
});
|
|
1723
|
+
localTemplateName: '', // Clear local state on blur
|
|
1724
|
+
}, () => {
|
|
1725
|
+
this.showTemplateName({ formData, onFormDataChange });
|
|
1726
|
+
});
|
|
1618
1727
|
}}
|
|
1619
1728
|
onChange={(ev) => {
|
|
1620
1729
|
const { value } = ev.currentTarget;
|
|
@@ -1626,10 +1735,18 @@ export class Creatives extends React.Component {
|
|
|
1626
1735
|
}
|
|
1627
1736
|
|
|
1628
1737
|
showTemplateName = ({ formData, onFormDataChange }) => { //gets called from email/index after template data is fetched
|
|
1629
|
-
const {
|
|
1738
|
+
const {
|
|
1739
|
+
slidBoxContent, currentChannel, isEditName, templateStep,
|
|
1740
|
+
} = this.state;
|
|
1630
1741
|
const channel = currentChannel.toUpperCase();
|
|
1631
1742
|
if ([constants.EMAIL, constants.MOBILE_PUSH, constants.INAPP].includes(channel) && (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate')) {
|
|
1632
1743
|
const name = get(formData, 'template-name');
|
|
1744
|
+
|
|
1745
|
+
const isModeSelectionStep = templateStep === 'modeSelection' || this.creativesTemplateSteps[templateStep] === 'modeSelection';
|
|
1746
|
+
const isCreateMode = slidBoxContent === 'createTemplate';
|
|
1747
|
+
if (isCreateMode && isModeSelectionStep) {
|
|
1748
|
+
return;
|
|
1749
|
+
}
|
|
1633
1750
|
if (channel === constants.EMAIL && !name && slidBoxContent === 'createTemplate') {
|
|
1634
1751
|
this.setState({ isTemplateNameEmpty: true });
|
|
1635
1752
|
}
|
|
@@ -1637,9 +1754,9 @@ export class Creatives extends React.Component {
|
|
|
1637
1754
|
if (name && !isEditName) {
|
|
1638
1755
|
this.setState({ showTemplateNameComponentEdit: false });
|
|
1639
1756
|
} else if (isEditName) {
|
|
1640
|
-
this.setState({
|
|
1757
|
+
this.setState({
|
|
1641
1758
|
showTemplateNameComponentEdit: true,
|
|
1642
|
-
localTemplateName: name || '' // Initialize local state with current value
|
|
1759
|
+
localTemplateName: name || '', // Initialize local state with current value
|
|
1643
1760
|
});
|
|
1644
1761
|
}
|
|
1645
1762
|
}
|
|
@@ -1653,15 +1770,31 @@ export class Creatives extends React.Component {
|
|
|
1653
1770
|
});
|
|
1654
1771
|
}
|
|
1655
1772
|
|
|
1773
|
+
// Callback to update HTML Editor validation state (called from EmailWrapper)
|
|
1774
|
+
updateHtmlEditorValidationState = (validationState) => {
|
|
1775
|
+
this.setState({
|
|
1776
|
+
htmlEditorValidationState: validationState,
|
|
1777
|
+
});
|
|
1778
|
+
}
|
|
1779
|
+
|
|
1656
1780
|
shouldShowContinueFooter = () => { // only for email for now, has to be modified according to channel
|
|
1657
1781
|
const {
|
|
1658
|
-
slidBoxContent, templateStep, currentChannel, emailCreateMode, mobilePushCreateMode,
|
|
1782
|
+
slidBoxContent, templateStep, currentChannel, emailCreateMode, mobilePushCreateMode, inAppEditorType, weChatTemplateType,
|
|
1659
1783
|
} = this.state;
|
|
1660
1784
|
let isShowContinueFooter = false;
|
|
1661
1785
|
const currentStep = this.creativesTemplateSteps[templateStep];
|
|
1662
1786
|
const channel = currentChannel.toUpperCase();
|
|
1787
|
+
// Check if supportCKEditor is false (new flow)
|
|
1788
|
+
const supportCKEditor = commonUtil.hasSupportCKEditor(); // Default to legacy flow
|
|
1663
1789
|
if (channel === constants.EMAIL || channel === constants.SMS) {
|
|
1664
|
-
|
|
1790
|
+
// New flow: Show Continue button when supportCKEditor is false and in modeSelection
|
|
1791
|
+
// Always show it (even if disabled) - visibility is separate from enabled state
|
|
1792
|
+
if (!supportCKEditor && currentStep === 'modeSelection' && slidBoxContent === 'createTemplate') {
|
|
1793
|
+
return true; // Return early to ensure visibility
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
// Legacy flow: Original logic (only when supportCKEditor is true)
|
|
1797
|
+
if (supportCKEditor && ((emailCreateMode === "upload" && !isEmpty(this.props.EmailLayout)) || emailCreateMode === "editor")) {
|
|
1665
1798
|
let isEmailCreate = slidBoxContent === 'createTemplate';
|
|
1666
1799
|
isEmailCreate = currentChannel.toUpperCase() === constants.EMAIL && ((emailCreateMode === "upload" && currentStep !== 'createTemplateContent') || (emailCreateMode === "editor" && currentStep !== 'createTemplateContent' && currentStep !== "templateSelection"));
|
|
1667
1800
|
isShowContinueFooter = isEmailCreate && emailCreateMode;
|
|
@@ -1670,8 +1803,6 @@ export class Creatives extends React.Component {
|
|
|
1670
1803
|
isShowContinueFooter = !isEmpty(mobilePushCreateMode) && currentStep === "modeSelection";
|
|
1671
1804
|
} else if (currentChannel.toUpperCase() === constants.WECHAT) {
|
|
1672
1805
|
isShowContinueFooter = !isEmpty(weChatTemplateType) && currentStep === "modeSelection";
|
|
1673
|
-
} else if (currentChannel.toUpperCase() === constants.INAPP) {
|
|
1674
|
-
isShowContinueFooter = !isEmpty(inAppCreateMode) && currentChannel === "modeSelection";
|
|
1675
1806
|
}
|
|
1676
1807
|
|
|
1677
1808
|
return isShowContinueFooter;
|
|
@@ -1697,6 +1828,34 @@ export class Creatives extends React.Component {
|
|
|
1697
1828
|
return true;
|
|
1698
1829
|
}
|
|
1699
1830
|
|
|
1831
|
+
// Check if Continue button should be disabled (for new flow only)
|
|
1832
|
+
isContinueButtonDisabled = () => {
|
|
1833
|
+
const {
|
|
1834
|
+
currentChannel, emailCreateMode, templateNameExists, mobilePushCreateMode, templateStep,
|
|
1835
|
+
} = this.state;
|
|
1836
|
+
const { isFullMode, EmailLayout } = this.props;
|
|
1837
|
+
if (currentChannel.toUpperCase() === constants.EMAIL) {
|
|
1838
|
+
// Upload mode: enable when a file has been uploaded (EmailLayout set by ZIP or HTML upload)
|
|
1839
|
+
// Other modes: enable when an editor type is selected (html_editor, drag_drop, editor)
|
|
1840
|
+
const isUploadComplete = emailCreateMode === 'upload' && !isEmpty(EmailLayout);
|
|
1841
|
+
const isEditorSelected = !!emailCreateMode && emailCreateMode !== 'upload';
|
|
1842
|
+
const canContinue = isUploadComplete || isEditorSelected;
|
|
1843
|
+
// In full mode: require both template name AND (upload complete or editor selected)
|
|
1844
|
+
// In library mode: require only upload complete or editor selection
|
|
1845
|
+
// Same rules for both CK editor and non-CK flows
|
|
1846
|
+
if (isFullMode) {
|
|
1847
|
+
const isTemplateNameValid = templateNameExists;
|
|
1848
|
+
return !(isTemplateNameValid && canContinue);
|
|
1849
|
+
}
|
|
1850
|
+
return !canContinue;
|
|
1851
|
+
}
|
|
1852
|
+
if (currentChannel.toUpperCase() === constants.MOBILE_PUSH) {
|
|
1853
|
+
const currentStep = this.creativesTemplateSteps[templateStep];
|
|
1854
|
+
return !(!isEmpty(mobilePushCreateMode) && currentStep === 'modeSelection');
|
|
1855
|
+
}
|
|
1856
|
+
return false;
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1700
1859
|
render() {
|
|
1701
1860
|
const {
|
|
1702
1861
|
slidBoxContent,
|
|
@@ -1705,6 +1864,7 @@ export class Creatives extends React.Component {
|
|
|
1705
1864
|
templateData,
|
|
1706
1865
|
currentChannel,
|
|
1707
1866
|
emailCreateMode,
|
|
1867
|
+
selectedEmailCreateMode,
|
|
1708
1868
|
templateStep,
|
|
1709
1869
|
isLoadingContent,
|
|
1710
1870
|
mobilePushCreateMode,
|
|
@@ -1717,6 +1877,8 @@ export class Creatives extends React.Component {
|
|
|
1717
1877
|
activeFormBuilderTab,
|
|
1718
1878
|
showTestAndPreviewSlidebox,
|
|
1719
1879
|
isTestAndPreviewMode,
|
|
1880
|
+
inAppEditorType,
|
|
1881
|
+
htmlEditorValidationState,
|
|
1720
1882
|
} = this.state;
|
|
1721
1883
|
const {
|
|
1722
1884
|
isFullMode,
|
|
@@ -1739,9 +1901,37 @@ export class Creatives extends React.Component {
|
|
|
1739
1901
|
isLoyaltyModule,
|
|
1740
1902
|
loyaltyMetaData = {},
|
|
1741
1903
|
} = this.props;
|
|
1904
|
+
// Compute Continue button label: "Continue" for EMAIL (when CK) and MOBILE_PUSH; "Next" for others
|
|
1905
|
+
const supportCKEditor = commonUtil.hasSupportCKEditor();
|
|
1906
|
+
const useContinueLabel = (currentChannel?.toUpperCase() === constants.EMAIL && supportCKEditor)
|
|
1907
|
+
|| currentChannel?.toUpperCase() === constants.MOBILE_PUSH;
|
|
1908
|
+
const continueButtonLabel = useContinueLabel ? messages.continue : messages.next;
|
|
1909
|
+
|
|
1742
1910
|
const mapTemplateCreate = slidBoxContent === "createTemplate"
|
|
1743
1911
|
&& weChatTemplateType === MAP_TEMPLATE
|
|
1744
1912
|
&& templateStep !== "modeSelection";
|
|
1913
|
+
|
|
1914
|
+
// Determine if we're in HTML Editor mode (where errors are shown in ValidationErrorDisplay, not ErrorInfoNote in footer)
|
|
1915
|
+
const isEmailChannel = currentChannel?.toUpperCase() === constants.EMAIL;
|
|
1916
|
+
const isEditMode = slidBoxContent === 'editTemplate';
|
|
1917
|
+
const isHTMLEditorModeInCreate = selectedEmailCreateMode === 'html_editor';
|
|
1918
|
+
const isHTMLEditorModeInEdit = isEditMode && htmlEditorValidationState != null;
|
|
1919
|
+
const isHTMLEditorMode = isEmailChannel && (isHTMLEditorModeInCreate || isHTMLEditorModeInEdit);
|
|
1920
|
+
const isBEEEditor = selectedEmailCreateMode === 'drag_drop'
|
|
1921
|
+
|| (emailCreateMode === 'editor' && !isHTMLEditorMode);
|
|
1922
|
+
|
|
1923
|
+
// Check for BEE editor errors (same logic as SlideBoxFooter)
|
|
1924
|
+
const hasStandardErrors = liquidErrorMessage && liquidErrorMessage.STANDARD_ERROR_MSG && liquidErrorMessage.STANDARD_ERROR_MSG.length > 0;
|
|
1925
|
+
const hasLiquidErrors = liquidErrorMessage && liquidErrorMessage.LIQUID_ERROR_MSG && liquidErrorMessage.LIQUID_ERROR_MSG.length > 0;
|
|
1926
|
+
const htmlEditorHasErrors = htmlEditorValidationState && htmlEditorValidationState.issueCounts && htmlEditorValidationState.issueCounts.total > 0;
|
|
1927
|
+
const hasBEEEditorErrors = isEmailChannel && (hasStandardErrors || hasLiquidErrors) && (!htmlEditorValidationState || !htmlEditorHasErrors);
|
|
1928
|
+
|
|
1929
|
+
// Only apply margin to footer when ErrorInfoNote is shown in footer (BEE editor)
|
|
1930
|
+
// For HTML Editor, errors are shown in ValidationErrorDisplay (inside content area), so no footer margin needed
|
|
1931
|
+
// IMPORTANT: Never show ErrorInfoNote in footer when in HTML Editor mode, even if liquidErrorMessage exists
|
|
1932
|
+
const shouldShowErrorInfoNoteInFooter = isHTMLEditorMode ? false : hasBEEEditorErrors;
|
|
1933
|
+
|
|
1934
|
+
// Calculate margin for header/content (always apply if there are errors, regardless of editor type)
|
|
1745
1935
|
const slideBoxWrapperMargin = (get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0 && get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0)
|
|
1746
1936
|
? CAP_SPACE_64
|
|
1747
1937
|
: get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0
|
|
@@ -1751,7 +1941,11 @@ export class Creatives extends React.Component {
|
|
|
1751
1941
|
: 0;
|
|
1752
1942
|
/* TODO: Instead of passing down same props separately to each component down, write common function to these props and pass it accordingly */
|
|
1753
1943
|
return (
|
|
1754
|
-
<SlideBoxWrapper
|
|
1944
|
+
<SlideBoxWrapper
|
|
1945
|
+
slideBoxWrapperMargin={slideBoxWrapperMargin}
|
|
1946
|
+
shouldApplyFooterMargin={shouldShowErrorInfoNoteInFooter}
|
|
1947
|
+
className={classnames(`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`)}
|
|
1948
|
+
>
|
|
1755
1949
|
<CapSlideBox
|
|
1756
1950
|
header={
|
|
1757
1951
|
this.shouldShowHeader() && (
|
|
@@ -1800,6 +1994,8 @@ export class Creatives extends React.Component {
|
|
|
1800
1994
|
onChannelChange={this.onChannelChange}
|
|
1801
1995
|
onEmailModeChange={this.onEmailModeChange}//used when create is clicked in email
|
|
1802
1996
|
emailCreateMode={emailCreateMode}// upload zip || use editor are values
|
|
1997
|
+
onInAppEditorTypeChange={this.onInAppEditorTypeChange}//used when create is clicked in inapp
|
|
1998
|
+
inAppEditorType={inAppEditorType}// htmlEditor || dragDropEditor are values
|
|
1803
1999
|
templateStep={this.creativesTemplateSteps[templateStep]}
|
|
1804
2000
|
onCreateNextStep={this.onCreateNextStep}
|
|
1805
2001
|
onEnterTemplateName={this.onEnterTemplateName}
|
|
@@ -1809,6 +2005,8 @@ export class Creatives extends React.Component {
|
|
|
1809
2005
|
cap={cap}
|
|
1810
2006
|
setIsLoadingContent={this.setIsLoadingContent}
|
|
1811
2007
|
onMobilepushModeChange={this.onMobilepushModeChange}
|
|
2008
|
+
inAppCreateMode={this.state.inAppCreateMode}
|
|
2009
|
+
onInAppModeChange={this.onInAppModeChange}
|
|
1812
2010
|
mobilePushCreateMode={mobilePushCreateMode}
|
|
1813
2011
|
showTemplateName={this.showTemplateName}
|
|
1814
2012
|
onValidationFail={this.onValidationFail}
|
|
@@ -1847,6 +2045,7 @@ export class Creatives extends React.Component {
|
|
|
1847
2045
|
handleTestAndPreview={this.handleTestAndPreview}
|
|
1848
2046
|
handleCloseTestAndPreview={this.handleCloseTestAndPreview}
|
|
1849
2047
|
isTestAndPreviewMode={(() => this.state.isTestAndPreviewMode)()}
|
|
2048
|
+
onHtmlEditorValidationStateChange={this.updateHtmlEditorValidationState}
|
|
1850
2049
|
/>
|
|
1851
2050
|
)}
|
|
1852
2051
|
footer={this.shouldShowFooter() ? (
|
|
@@ -1861,6 +2060,7 @@ export class Creatives extends React.Component {
|
|
|
1861
2060
|
currentChannel={currentChannel.toUpperCase()}
|
|
1862
2061
|
templateStep={this.creativesTemplateSteps[templateStep]}
|
|
1863
2062
|
emailCreateMode={emailCreateMode}
|
|
2063
|
+
selectedEmailCreateMode={selectedEmailCreateMode}
|
|
1864
2064
|
shouldShowContinueFooter={this.shouldShowContinueFooter}
|
|
1865
2065
|
shouldShowDoneFooter={this.shouldShowDoneFooter}
|
|
1866
2066
|
fetchingCmsData={fetchingCmsData}
|
|
@@ -1869,18 +2069,22 @@ export class Creatives extends React.Component {
|
|
|
1869
2069
|
errorMessages={liquidErrorMessage}
|
|
1870
2070
|
currentTab={activeFormBuilderTab}
|
|
1871
2071
|
onTestAndPreview={this.handleTestAndPreview}
|
|
2072
|
+
isContinueButtonDisabled={this.isContinueButtonDisabled()}
|
|
2073
|
+
continueButtonLabel={continueButtonLabel}
|
|
1872
2074
|
showTestAndPreviewButton={(() => {
|
|
1873
2075
|
const isEmailOrSmsOrWhatsappOrRcsOrInAppOrMobilePush = [constants.EMAIL, constants.SMS, constants.WHATSAPP, constants.RCS, constants.INAPP, constants.MOBILE_PUSH, constants.VIBER, constants.ZALO].includes(currentChannel.toUpperCase());
|
|
1874
2076
|
const showButton = isEmailOrSmsOrWhatsappOrRcsOrInAppOrMobilePush && (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate');
|
|
1875
2077
|
return showButton;
|
|
1876
2078
|
})()}
|
|
2079
|
+
htmlEditorValidationState={htmlEditorValidationState}
|
|
2080
|
+
isCreatingTemplate={slidBoxContent === 'createTemplate' && currentChannel.toUpperCase() === constants.EMAIL}
|
|
1877
2081
|
/>
|
|
1878
2082
|
) : isLiquidValidationError && (
|
|
1879
2083
|
<CapRow className="template-footer-width">
|
|
1880
2084
|
{(() => {
|
|
1881
2085
|
const errorsToShow = get(liquidErrorMessage, constants.LIQUID_ERROR_MSG, []);
|
|
1882
2086
|
const standardErrorsToShow = get(liquidErrorMessage, constants.STANDARD_ERROR_MSG, []);
|
|
1883
|
-
return <ErrorInfoNote currentTab={activeFormBuilderTab?.toUpperCase()} errorMessages={{LIQUID_ERROR_MSG: errorsToShow, STANDARD_ERROR_MSG: standardErrorsToShow}} />;
|
|
2087
|
+
return <ErrorInfoNote currentTab={activeFormBuilderTab?.toUpperCase()} errorMessages={{ LIQUID_ERROR_MSG: errorsToShow, STANDARD_ERROR_MSG: standardErrorsToShow }} />;
|
|
1884
2088
|
})()}
|
|
1885
2089
|
</CapRow>
|
|
1886
2090
|
)}
|
|
@@ -282,6 +282,10 @@ export default defineMessages({
|
|
|
282
282
|
id: `${scope}.creativesTemplatesUpdate`,
|
|
283
283
|
defaultMessage: `Update`,
|
|
284
284
|
},
|
|
285
|
+
"creativesTemplatesDone": {
|
|
286
|
+
id: `${scope}.creativesTemplatesDone`,
|
|
287
|
+
defaultMessage: `Done`,
|
|
288
|
+
},
|
|
285
289
|
"creativesTemplatesDiscard": {
|
|
286
290
|
id: `${scope}.creativesTemplatesDiscard`,
|
|
287
291
|
defaultMessage: `Discard`,
|
|
@@ -370,4 +374,8 @@ export default defineMessages({
|
|
|
370
374
|
id: `${scope}.testAndPreview`,
|
|
371
375
|
defaultMessage: `Preview and Test`,
|
|
372
376
|
},
|
|
377
|
+
"next": {
|
|
378
|
+
id: `${scope}.next`,
|
|
379
|
+
defaultMessage: `Next`,
|
|
380
|
+
},
|
|
373
381
|
});
|