@capillarytech/creatives-library 8.0.254 → 8.0.255-alpha.0
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/utils/common.js +5 -0
- package/utils/commonUtils.js +28 -5
- package/utils/tests/commonUtil.test.js +224 -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 +457 -72
- package/v2Components/ErrorInfoNote/messages.js +36 -6
- package/v2Components/ErrorInfoNote/style.scss +282 -6
- package/v2Components/FormBuilder/tests/index.test.js +13 -4
- package/v2Components/HtmlEditor/HTMLEditor.js +547 -94
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +874 -0
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +1358 -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 +22 -101
- package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +149 -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 -0
- package/v2Components/HtmlEditor/components/EditorToolbar/index.js +1 -1
- 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 +3 -6
- package/v2Components/HtmlEditor/components/PreviewPane/index.js +24 -34
- package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
- package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +49 -31
- package/v2Components/HtmlEditor/components/ValidationPanel/_validationPanel.scss +50 -34
- package/v2Components/HtmlEditor/components/ValidationPanel/constants.js +6 -0
- package/v2Components/HtmlEditor/components/ValidationPanel/index.js +70 -41
- package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +254 -0
- package/v2Components/HtmlEditor/components/ValidationTabs/index.js +364 -0
- package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +51 -0
- package/v2Components/HtmlEditor/constants.js +42 -20
- package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +373 -16
- package/v2Components/HtmlEditor/hooks/__tests__/useValidation.apiErrors.test.js +794 -0
- package/v2Components/HtmlEditor/hooks/useEditorContent.js +5 -2
- package/v2Components/HtmlEditor/hooks/useInAppContent.js +88 -146
- package/v2Components/HtmlEditor/hooks/useValidation.js +189 -53
- package/v2Components/HtmlEditor/index.js +1 -1
- package/v2Components/HtmlEditor/messages.js +95 -85
- package/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +94 -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 +134 -102
- package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +23 -25
- package/v2Components/HtmlEditor/utils/validationAdapter.js +66 -41
- package/v2Components/HtmlEditor/utils/validationConstants.js +40 -0
- package/v2Components/MobilePushPreviewV2/index.js +32 -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 +128 -51
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +163 -13
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +2 -1
- package/v2Containers/CreativesContainer/constants.js +1 -0
- package/v2Containers/CreativesContainer/index.js +239 -46
- 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 +106 -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 +1285 -0
- package/v2Containers/EmailWrapper/components/EmailWrapperView.js +207 -19
- package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +40 -74
- package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +1870 -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 +629 -77
- package/v2Containers/EmailWrapper/index.js +103 -23
- package/v2Containers/EmailWrapper/messages.js +61 -1
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +643 -0
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +594 -77
- 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 -359
- 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/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/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';
|
|
@@ -43,7 +45,7 @@ import {
|
|
|
43
45
|
IMAGE as LINE_IMAGE, IMAGE_MAP, IMAGE_CAROUSEL, VIDEO as LINE_VIDEO, TEMPLATE, STICKER,
|
|
44
46
|
} from '../Line/Container/constants';
|
|
45
47
|
import { IMAGE, VIDEO } from '../Facebook/Advertisement/constant';
|
|
46
|
-
import {RCS_STATUSES} from '../Rcs/constants';
|
|
48
|
+
import { RCS_STATUSES } from '../Rcs/constants';
|
|
47
49
|
import { CREATIVE } from '../Facebook/constants';
|
|
48
50
|
import { LOYALTY } from '../App/constants';
|
|
49
51
|
import {
|
|
@@ -64,19 +66,29 @@ import {
|
|
|
64
66
|
// getTemplateDiffState
|
|
65
67
|
} from "../../utils/transformerUtils";
|
|
66
68
|
import { MANUAL_CAROUSEL } from '../MobilePushNew/constants';
|
|
69
|
+
import { BIG_HTML } from '../InApp/constants';
|
|
67
70
|
|
|
68
71
|
const classPrefix = 'add-creatives-section';
|
|
69
72
|
const CREATIVES_CONTAINER = 'creativesContainer';
|
|
70
73
|
|
|
71
74
|
const SlideBoxWrapper = styled.div`
|
|
72
75
|
.cap-slide-box-v2-container{
|
|
73
|
-
.slidebox-header, .slidebox-content-container
|
|
76
|
+
.slidebox-header, .slidebox-content-container{
|
|
74
77
|
margin-bottom: ${({ slideBoxWrapperMargin }) => `${slideBoxWrapperMargin}`};
|
|
75
78
|
padding: 0 rem;
|
|
76
79
|
&.has-footer{
|
|
77
80
|
overflow-x: hidden;
|
|
78
81
|
}
|
|
79
82
|
}
|
|
83
|
+
.slidebox-footer{
|
|
84
|
+
/* Only apply margin-bottom to footer when ErrorInfoNote is shown in footer (BEE editor) */
|
|
85
|
+
/* For HTML Editor, errors are shown in ValidationErrorDisplay (inside content area), so no footer margin needed */
|
|
86
|
+
margin-bottom: ${({ shouldApplyFooterMargin }) => (shouldApplyFooterMargin ? `${CAP_SPACE_16}` : '0')};
|
|
87
|
+
padding: 0 rem;
|
|
88
|
+
&.has-footer{
|
|
89
|
+
overflow-x: hidden;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
80
92
|
}
|
|
81
93
|
`;
|
|
82
94
|
export class Creatives extends React.Component {
|
|
@@ -95,6 +107,7 @@ export class Creatives extends React.Component {
|
|
|
95
107
|
currentChannel: this.props.channel || 'sms',
|
|
96
108
|
weChatTemplateType: '',
|
|
97
109
|
weChatMaptemplateStep: 0,
|
|
110
|
+
inAppEditorType: null,
|
|
98
111
|
isLiquidValidationError: false,
|
|
99
112
|
errorMessages: [],
|
|
100
113
|
liquidErrorMessage: {
|
|
@@ -107,6 +120,17 @@ export class Creatives extends React.Component {
|
|
|
107
120
|
isTestAndPreviewMode: false, // Add flag to track Test & Preview mode
|
|
108
121
|
// Performance optimization: Local template name for immediate UI feedback
|
|
109
122
|
localTemplateName: '',
|
|
123
|
+
// Track selected email create mode for new flow (HTML Editor vs Drag & Drop)
|
|
124
|
+
selectedEmailCreateMode: null,
|
|
125
|
+
// HTML Editor validation state (for email channel)
|
|
126
|
+
htmlEditorValidationState: {
|
|
127
|
+
isContentEmpty: true,
|
|
128
|
+
issueCounts: {
|
|
129
|
+
html: 0, label: 0, liquid: 0, total: 0,
|
|
130
|
+
},
|
|
131
|
+
validationComplete: false, // Flag to track if validation has completed
|
|
132
|
+
errorsAcknowledged: false, // Flag to track if user has acknowledged errors by clicking redirection icon
|
|
133
|
+
},
|
|
110
134
|
};
|
|
111
135
|
this.liquidFlow = Boolean(commonUtil.hasLiquidSupportFeature());
|
|
112
136
|
this.creativesTemplateSteps = {
|
|
@@ -136,7 +160,7 @@ export class Creatives extends React.Component {
|
|
|
136
160
|
if (!this.props?.isFullMode) {
|
|
137
161
|
this.props?.templateActions.getCdnTransformationConfig();
|
|
138
162
|
}
|
|
139
|
-
|
|
163
|
+
|
|
140
164
|
// Store loyalty tag props if loyaltyTagFetchingDependencies is provided
|
|
141
165
|
const { loyaltyTagFetchingDependencies } = this.props;
|
|
142
166
|
if (loyaltyTagFetchingDependencies) {
|
|
@@ -162,9 +186,9 @@ export class Creatives extends React.Component {
|
|
|
162
186
|
const isEmptyTemplateName = !value.trim();
|
|
163
187
|
|
|
164
188
|
// 1. IMMEDIATE: Update local state for instant UI feedback
|
|
165
|
-
this.setState({
|
|
189
|
+
this.setState({
|
|
166
190
|
isTemplateNameEmpty: isEmptyTemplateName,
|
|
167
|
-
localTemplateName: value
|
|
191
|
+
localTemplateName: value,
|
|
168
192
|
});
|
|
169
193
|
|
|
170
194
|
// 2. DEBOUNCED: Only debounce the expensive onFormDataChange call
|
|
@@ -243,8 +267,19 @@ export class Creatives extends React.Component {
|
|
|
243
267
|
onCreateNextStep = () => {
|
|
244
268
|
this.setState((prevState) => {
|
|
245
269
|
let templateStep = prevState.templateStep + 1;
|
|
246
|
-
const { emailCreateMode, currentChannel } = prevState;
|
|
247
|
-
|
|
270
|
+
const { emailCreateMode, currentChannel, selectedEmailCreateMode } = prevState;
|
|
271
|
+
|
|
272
|
+
// Check if we should skip template selection for HTML Editor
|
|
273
|
+
const supportCKEditor = commonUtil.hasSupportCKEditor();
|
|
274
|
+
const shouldSkipTemplateSelection = !supportCKEditor
|
|
275
|
+
&& selectedEmailCreateMode === 'html_editor'
|
|
276
|
+
&& currentChannel.toUpperCase() === constants.EMAIL
|
|
277
|
+
&& prevState.templateStep === 1; // Only skip if we're at modeSelection step
|
|
278
|
+
|
|
279
|
+
if (shouldSkipTemplateSelection) {
|
|
280
|
+
// Skip template selection (step 2), go directly to createTemplateContent (step 3)
|
|
281
|
+
templateStep = prevState.templateStep + 2;
|
|
282
|
+
} else if ((currentChannel.toUpperCase() === constants.EMAIL && emailCreateMode === "upload") || [constants.MOBILE_PUSH, constants.WECHAT, constants.INAPP].includes(currentChannel.toUpperCase())) {
|
|
248
283
|
templateStep = prevState.templateStep + 2;
|
|
249
284
|
}
|
|
250
285
|
return {
|
|
@@ -253,14 +288,21 @@ export class Creatives extends React.Component {
|
|
|
253
288
|
});
|
|
254
289
|
}
|
|
255
290
|
|
|
256
|
-
onEmailModeChange = (mode) => {
|
|
257
|
-
this.setState({
|
|
291
|
+
onEmailModeChange = (mode, selectedMode = null) => {
|
|
292
|
+
this.setState({
|
|
293
|
+
emailCreateMode: mode,
|
|
294
|
+
selectedEmailCreateMode: selectedMode || mode, // Store the selected mode for new flow
|
|
295
|
+
});
|
|
258
296
|
}
|
|
259
297
|
|
|
260
298
|
onInAppModeChange = (mode) => {
|
|
261
299
|
this.setState({ inAppCreateMode: mode });
|
|
262
300
|
}
|
|
263
301
|
|
|
302
|
+
onInAppEditorTypeChange = (editorType) => {
|
|
303
|
+
this.setState({ inAppEditorType: editorType });
|
|
304
|
+
}
|
|
305
|
+
|
|
264
306
|
onMobilepushModeChange = (mode) => {
|
|
265
307
|
this.setState({ mobilePushCreateMode: mode });
|
|
266
308
|
}
|
|
@@ -304,7 +346,7 @@ export class Creatives extends React.Component {
|
|
|
304
346
|
}
|
|
305
347
|
return buttonObj;
|
|
306
348
|
});
|
|
307
|
-
const {url, previewUrl} = media || {};
|
|
349
|
+
const { url, previewUrl } = media || {};
|
|
308
350
|
return {
|
|
309
351
|
bodyText: bodyTemplate,
|
|
310
352
|
varMap: cardVarMapped,
|
|
@@ -433,14 +475,35 @@ export class Creatives extends React.Component {
|
|
|
433
475
|
}
|
|
434
476
|
case constants.INAPP: {
|
|
435
477
|
const mode = get(templateData, 'androidContent.type') || get(templateData, 'iosContent.type') || '';
|
|
478
|
+
|
|
479
|
+
// Check if this is a BEE editor template (identified by special title 'bee free template')
|
|
480
|
+
const isAndroidBeeEditor = templateData?.androidContent?.type === constants.HTML
|
|
481
|
+
&& templateData?.androidContent?.title?.toLowerCase() === 'bee free template';
|
|
482
|
+
const isIosBeeEditor = templateData?.iosContent?.type === constants.HTML
|
|
483
|
+
&& templateData?.iosContent?.title?.toLowerCase() === 'bee free template';
|
|
484
|
+
|
|
436
485
|
creativesTemplateData = {
|
|
437
486
|
type: channel,
|
|
438
487
|
name: templateData.messageSubject,
|
|
439
488
|
versions: {
|
|
440
489
|
base: {
|
|
441
490
|
content: {
|
|
442
|
-
ANDROID:
|
|
443
|
-
|
|
491
|
+
ANDROID: isAndroidBeeEditor ? {
|
|
492
|
+
type: templateData?.androidContent?.type,
|
|
493
|
+
bodyType: templateData?.androidContent?.bodyType,
|
|
494
|
+
deviceType: constants.ANDROID,
|
|
495
|
+
beeHtml: { value: templateData?.androidContent?.message },
|
|
496
|
+
beeJson: templateData?.androidContent?.expandableDetails?.message,
|
|
497
|
+
isBEEeditor: true,
|
|
498
|
+
} : templateData?.androidContent,
|
|
499
|
+
IOS: isIosBeeEditor ? {
|
|
500
|
+
type: templateData?.iosContent?.type,
|
|
501
|
+
bodyType: templateData?.iosContent?.bodyType,
|
|
502
|
+
deviceType: constants.IOS,
|
|
503
|
+
beeHtml: { value: templateData?.iosContent?.message },
|
|
504
|
+
beeJson: templateData?.iosContent?.expandableDetails?.message,
|
|
505
|
+
isBEEeditor: true,
|
|
506
|
+
} : templateData?.iosContent,
|
|
444
507
|
},
|
|
445
508
|
},
|
|
446
509
|
},
|
|
@@ -675,7 +738,7 @@ export class Creatives extends React.Component {
|
|
|
675
738
|
} = templateData || {};
|
|
676
739
|
const cardContent = (rcsContent.cardContent && rcsContent.cardContent[0]) || {};
|
|
677
740
|
const Status = RCS_STATUSES.approved || '';
|
|
678
|
-
|
|
741
|
+
|
|
679
742
|
creativesTemplateData = {
|
|
680
743
|
type: channel,
|
|
681
744
|
edit: true,
|
|
@@ -760,7 +823,7 @@ export class Creatives extends React.Component {
|
|
|
760
823
|
});
|
|
761
824
|
|
|
762
825
|
getMobilePushCarouselData = (expandableDetails = []) => {
|
|
763
|
-
const newExpandableDetails = {...expandableDetails};
|
|
826
|
+
const newExpandableDetails = { ...expandableDetails };
|
|
764
827
|
newExpandableDetails.style = expandableDetails.style || MANUAL_CAROUSEL;
|
|
765
828
|
newExpandableDetails.message = expandableDetails.message || '';
|
|
766
829
|
newExpandableDetails.ctas = expandableDetails.ctas || [];
|
|
@@ -855,11 +918,24 @@ export class Creatives extends React.Component {
|
|
|
855
918
|
androidContent.custom = custom;
|
|
856
919
|
}
|
|
857
920
|
if (channel === constants.MOBILE_PUSH && androidContent?.expandableDetails?.carouselData?.length) {
|
|
858
|
-
androidContent.expandableDetails = this.getMobilePushCarouselData({...androidContent?.expandableDetails});
|
|
921
|
+
androidContent.expandableDetails = this.getMobilePushCarouselData({ ...androidContent?.expandableDetails });
|
|
922
|
+
}
|
|
923
|
+
if (androidContent?.isBEEeditor && androidContent?.beeHtml?.value) {
|
|
924
|
+
templateData.androidContent = {};
|
|
925
|
+
templateData.androidContent.type = constants.HTML;
|
|
926
|
+
templateData.androidContent.message = androidContent?.beeHtml?.value || '';
|
|
927
|
+
templateData.androidContent.title = 'bee free template';
|
|
928
|
+
templateData.androidContent.bodyType = androidContent?.bodyType;
|
|
929
|
+
templateData.androidContent.deviceType = constants.ANDROID;
|
|
930
|
+
templateData.androidContent.expandableDetails = {
|
|
931
|
+
style: BIG_HTML,
|
|
932
|
+
message: androidContent?.beeJson || '',
|
|
933
|
+
};
|
|
934
|
+
} else if (!androidContent?.isBEEeditor) {
|
|
935
|
+
templateData.androidContent = androidContent;
|
|
936
|
+
templateData.androidContent.type = androidContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || constants.TEXT;
|
|
937
|
+
templateData.androidContent.deviceType = constants.ANDROID;
|
|
859
938
|
}
|
|
860
|
-
templateData.androidContent = androidContent;
|
|
861
|
-
templateData.androidContent.type = androidContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || constants.TEXT;
|
|
862
|
-
templateData.androidContent.deviceType = constants.ANDROID;
|
|
863
939
|
}
|
|
864
940
|
const iosContent = channel === constants.INAPP ? get(channelTemplate, 'versions.base.content.IOS') : get(channelTemplate, 'versions.base.IOS');
|
|
865
941
|
if (!isEmpty(iosContent)) {
|
|
@@ -877,11 +953,24 @@ export class Creatives extends React.Component {
|
|
|
877
953
|
iosContent.custom = custom;
|
|
878
954
|
}
|
|
879
955
|
if (channel === constants.MOBILE_PUSH && iosContent?.expandableDetails?.carouselData?.length) {
|
|
880
|
-
iosContent.expandableDetails = this.getMobilePushCarouselData({...iosContent?.expandableDetails});
|
|
956
|
+
iosContent.expandableDetails = this.getMobilePushCarouselData({ ...iosContent?.expandableDetails });
|
|
957
|
+
}
|
|
958
|
+
if (iosContent?.isBEEeditor && iosContent?.beeHtml?.value) {
|
|
959
|
+
templateData.iosContent = {};
|
|
960
|
+
templateData.iosContent.type = constants.HTML;
|
|
961
|
+
templateData.iosContent.message = iosContent?.beeHtml?.value || '';
|
|
962
|
+
templateData.iosContent.title = 'bee free template';
|
|
963
|
+
templateData.iosContent.bodyType = iosContent?.bodyType;
|
|
964
|
+
templateData.iosContent.deviceType = constants.IOS;
|
|
965
|
+
templateData.iosContent.expandableDetails = {
|
|
966
|
+
style: BIG_HTML,
|
|
967
|
+
message: iosContent?.beeJson || '',
|
|
968
|
+
};
|
|
969
|
+
} else if (!iosContent?.isBEEeditor) {
|
|
970
|
+
templateData.iosContent = iosContent;
|
|
971
|
+
templateData.iosContent.type = iosContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || 'TEXT';
|
|
972
|
+
templateData.iosContent.deviceType = constants.IOS;
|
|
881
973
|
}
|
|
882
|
-
templateData.iosContent = iosContent;
|
|
883
|
-
templateData.iosContent.type = iosContent?.type || get(channelTemplate, 'definition.mode', '')?.toUpperCase() || 'TEXT';
|
|
884
|
-
templateData.iosContent.deviceType = constants.IOS;
|
|
885
974
|
}
|
|
886
975
|
templateData.messageSubject = channelTemplate?.name ? channelTemplate?.name : "messageSubject";
|
|
887
976
|
}
|
|
@@ -1096,7 +1185,7 @@ export class Creatives extends React.Component {
|
|
|
1096
1185
|
contentType = "",
|
|
1097
1186
|
cardType = "",
|
|
1098
1187
|
cardSettings = {},
|
|
1099
|
-
} = get(versions, 'base.content.RCS.rcsContent',{});
|
|
1188
|
+
} = get(versions, 'base.content.RCS.rcsContent', {});
|
|
1100
1189
|
const rcsContent = {
|
|
1101
1190
|
contentType,
|
|
1102
1191
|
cardType,
|
|
@@ -1234,7 +1323,7 @@ export class Creatives extends React.Component {
|
|
|
1234
1323
|
processCentralCommsMetaId = (channel, creativesData) => {
|
|
1235
1324
|
// Create the payload for the centralcommnsmetaId API call
|
|
1236
1325
|
const { isLoyaltyModule = false, loyaltyMetaData = {} } = this.props;
|
|
1237
|
-
const { actionName, setMetaData = () => {} } = loyaltyMetaData;
|
|
1326
|
+
const { actionName, setMetaData = () => { } } = loyaltyMetaData;
|
|
1238
1327
|
|
|
1239
1328
|
// const isTemplateModified = getTemplateDiffState(
|
|
1240
1329
|
// channel,
|
|
@@ -1284,6 +1373,9 @@ export class Creatives extends React.Component {
|
|
|
1284
1373
|
if (prevState.currentChannel.toUpperCase() === constants.EMAIL) {
|
|
1285
1374
|
newState = { ...newState, emailCreateMode: null };
|
|
1286
1375
|
}
|
|
1376
|
+
if (prevState.currentChannel.toUpperCase() === constants.INAPP) {
|
|
1377
|
+
newState = { ...newState, inAppEditorType: null };
|
|
1378
|
+
}
|
|
1287
1379
|
return newState;
|
|
1288
1380
|
});
|
|
1289
1381
|
}
|
|
@@ -1329,7 +1421,7 @@ export class Creatives extends React.Component {
|
|
|
1329
1421
|
shouldShowFooter = () => {
|
|
1330
1422
|
const { isFullMode } = this.props;
|
|
1331
1423
|
const {
|
|
1332
|
-
slidBoxContent, currentChannel, emailCreateMode, templateNameExists, templateStep, mobilePushCreateMode, weChatTemplateType, templateData,
|
|
1424
|
+
slidBoxContent, currentChannel, emailCreateMode, templateNameExists, templateStep, mobilePushCreateMode, weChatTemplateType, templateData, inAppCreateMode,
|
|
1333
1425
|
} = this.state;
|
|
1334
1426
|
const channel = currentChannel.toUpperCase();
|
|
1335
1427
|
const currentStep = this.creativesTemplateSteps[templateStep];
|
|
@@ -1337,6 +1429,13 @@ export class Creatives extends React.Component {
|
|
|
1337
1429
|
showFooter = isFullMode && slidBoxContent === "preview";
|
|
1338
1430
|
const isMobilepush = channel === constants.MOBILE_PUSH;
|
|
1339
1431
|
|
|
1432
|
+
const supportCKEditor = commonUtil.hasSupportCKEditor();
|
|
1433
|
+
if (!supportCKEditor && channel === constants.EMAIL && currentStep === 'modeSelection' && slidBoxContent === 'createTemplate') {
|
|
1434
|
+
return true;
|
|
1435
|
+
}
|
|
1436
|
+
if (!supportCKEditor && channel === constants.EMAIL && currentStep === 'createTemplateContent' && slidBoxContent === 'createTemplate') {
|
|
1437
|
+
showFooter = true;
|
|
1438
|
+
}
|
|
1340
1439
|
|
|
1341
1440
|
if (!isFullMode) {
|
|
1342
1441
|
const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
|
|
@@ -1372,6 +1471,7 @@ export class Creatives extends React.Component {
|
|
|
1372
1471
|
showFooter = true;
|
|
1373
1472
|
}
|
|
1374
1473
|
|
|
1474
|
+
|
|
1375
1475
|
if (showFooter) {
|
|
1376
1476
|
if (slidBoxContent === "createTemplate" && ((channel === constants.EMAIL && currentStep === 'createTemplateContent')
|
|
1377
1477
|
|| ([constants.SMS, constants.WECHAT].includes(channel) && currentStep === 'modeSelection'))) {
|
|
@@ -1394,7 +1494,7 @@ export class Creatives extends React.Component {
|
|
|
1394
1494
|
|
|
1395
1495
|
shouldShowDoneFooter = () => {
|
|
1396
1496
|
const {
|
|
1397
|
-
slidBoxContent, templateStep, currentChannel, templateData,
|
|
1497
|
+
slidBoxContent, templateStep, currentChannel, templateData, inAppCreateMode,
|
|
1398
1498
|
} = this.state;
|
|
1399
1499
|
const { isFullMode } = this.props;
|
|
1400
1500
|
const currentStep = this.creativesTemplateSteps[templateStep];
|
|
@@ -1402,10 +1502,17 @@ export class Creatives extends React.Component {
|
|
|
1402
1502
|
const channelName = !isFullMode && templateData ? templateData.type : currentChannel;
|
|
1403
1503
|
const channel = channelName?.toUpperCase();
|
|
1404
1504
|
|
|
1405
|
-
|
|
1505
|
+
// Check supportCKEditor flag for new HTML editor flow
|
|
1506
|
+
const supportCKEditor = commonUtil.hasSupportCKEditor();
|
|
1406
1507
|
if (channel === constants.EMAIL || channel === constants.SMS) {
|
|
1407
1508
|
const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
|
|
1408
|
-
|
|
1509
|
+
|
|
1510
|
+
// For new HTML editor flow (when supportCKEditor is false), show Done footer when in createTemplateContent step
|
|
1511
|
+
if (!supportCKEditor && channel === constants.EMAIL && slidBoxContent === 'createTemplate' && currentStep === 'createTemplateContent') {
|
|
1512
|
+
showDone = true;
|
|
1513
|
+
} else {
|
|
1514
|
+
showDone = (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate') && !isEmailCreate;
|
|
1515
|
+
}
|
|
1409
1516
|
} else if ([constants.WECHAT, constants.MOBILE_PUSH].includes(channel)) {
|
|
1410
1517
|
showDone = currentStep === "createTemplateContent" || slidBoxContent === "editTemplate";
|
|
1411
1518
|
|
|
@@ -1415,7 +1522,6 @@ export class Creatives extends React.Component {
|
|
|
1415
1522
|
}
|
|
1416
1523
|
}
|
|
1417
1524
|
|
|
1418
|
-
|
|
1419
1525
|
return showDone;
|
|
1420
1526
|
}
|
|
1421
1527
|
|
|
@@ -1435,18 +1541,18 @@ export class Creatives extends React.Component {
|
|
|
1435
1541
|
templateNameComponentInput = ({ formData, onFormDataChange, name }) => {
|
|
1436
1542
|
// Use local state for immediate UI feedback, fallback to prop value
|
|
1437
1543
|
const displayValue = this.state.localTemplateName !== '' ? this.state.localTemplateName : name;
|
|
1438
|
-
|
|
1544
|
+
|
|
1439
1545
|
return (
|
|
1440
1546
|
<CapInput
|
|
1441
1547
|
value={displayValue}
|
|
1442
1548
|
suffix={<span />}
|
|
1443
|
-
onBlur={() => {
|
|
1444
|
-
this.setState({
|
|
1549
|
+
onBlur={() => {
|
|
1550
|
+
this.setState({
|
|
1445
1551
|
isEditName: false,
|
|
1446
|
-
localTemplateName: '' // Clear local state on blur
|
|
1447
|
-
}, () => {
|
|
1448
|
-
this.showTemplateName({ formData, onFormDataChange });
|
|
1449
|
-
});
|
|
1552
|
+
localTemplateName: '', // Clear local state on blur
|
|
1553
|
+
}, () => {
|
|
1554
|
+
this.showTemplateName({ formData, onFormDataChange });
|
|
1555
|
+
});
|
|
1450
1556
|
}}
|
|
1451
1557
|
onChange={(ev) => {
|
|
1452
1558
|
const { value } = ev.currentTarget;
|
|
@@ -1458,10 +1564,18 @@ export class Creatives extends React.Component {
|
|
|
1458
1564
|
}
|
|
1459
1565
|
|
|
1460
1566
|
showTemplateName = ({ formData, onFormDataChange }) => { //gets called from email/index after template data is fetched
|
|
1461
|
-
const {
|
|
1567
|
+
const {
|
|
1568
|
+
slidBoxContent, currentChannel, isEditName, templateStep,
|
|
1569
|
+
} = this.state;
|
|
1462
1570
|
const channel = currentChannel.toUpperCase();
|
|
1463
1571
|
if ([constants.EMAIL, constants.MOBILE_PUSH, constants.INAPP].includes(channel) && (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate')) {
|
|
1464
1572
|
const name = get(formData, 'template-name');
|
|
1573
|
+
|
|
1574
|
+
const isModeSelectionStep = templateStep === 'modeSelection' || this.creativesTemplateSteps[templateStep] === 'modeSelection';
|
|
1575
|
+
const isCreateMode = slidBoxContent === 'createTemplate';
|
|
1576
|
+
if (isCreateMode && isModeSelectionStep) {
|
|
1577
|
+
return;
|
|
1578
|
+
}
|
|
1465
1579
|
if (channel === constants.EMAIL && !name && slidBoxContent === 'createTemplate') {
|
|
1466
1580
|
this.setState({ isTemplateNameEmpty: true });
|
|
1467
1581
|
}
|
|
@@ -1469,9 +1583,9 @@ export class Creatives extends React.Component {
|
|
|
1469
1583
|
if (name && !isEditName) {
|
|
1470
1584
|
this.setState({ showTemplateNameComponentEdit: false });
|
|
1471
1585
|
} else if (isEditName) {
|
|
1472
|
-
this.setState({
|
|
1586
|
+
this.setState({
|
|
1473
1587
|
showTemplateNameComponentEdit: true,
|
|
1474
|
-
localTemplateName: name || '' // Initialize local state with current value
|
|
1588
|
+
localTemplateName: name || '', // Initialize local state with current value
|
|
1475
1589
|
});
|
|
1476
1590
|
}
|
|
1477
1591
|
}
|
|
@@ -1485,15 +1599,31 @@ export class Creatives extends React.Component {
|
|
|
1485
1599
|
});
|
|
1486
1600
|
}
|
|
1487
1601
|
|
|
1602
|
+
// Callback to update HTML Editor validation state (called from EmailWrapper)
|
|
1603
|
+
updateHtmlEditorValidationState = (validationState) => {
|
|
1604
|
+
this.setState({
|
|
1605
|
+
htmlEditorValidationState: validationState,
|
|
1606
|
+
});
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1488
1609
|
shouldShowContinueFooter = () => { // only for email for now, has to be modified according to channel
|
|
1489
1610
|
const {
|
|
1490
|
-
slidBoxContent, templateStep, currentChannel, emailCreateMode, mobilePushCreateMode,
|
|
1611
|
+
slidBoxContent, templateStep, currentChannel, emailCreateMode, mobilePushCreateMode, inAppEditorType, weChatTemplateType,
|
|
1491
1612
|
} = this.state;
|
|
1492
1613
|
let isShowContinueFooter = false;
|
|
1493
1614
|
const currentStep = this.creativesTemplateSteps[templateStep];
|
|
1494
1615
|
const channel = currentChannel.toUpperCase();
|
|
1616
|
+
// Check if supportCKEditor is false (new flow)
|
|
1617
|
+
const supportCKEditor = commonUtil.hasSupportCKEditor(); // Default to legacy flow
|
|
1495
1618
|
if (channel === constants.EMAIL || channel === constants.SMS) {
|
|
1496
|
-
|
|
1619
|
+
// New flow: Show Continue button when supportCKEditor is false and in modeSelection
|
|
1620
|
+
// Always show it (even if disabled) - visibility is separate from enabled state
|
|
1621
|
+
if (!supportCKEditor && currentStep === 'modeSelection' && slidBoxContent === 'createTemplate') {
|
|
1622
|
+
return true; // Return early to ensure visibility
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
// Legacy flow: Original logic (only when supportCKEditor is true)
|
|
1626
|
+
if (supportCKEditor && ((emailCreateMode === "upload" && !isEmpty(this.props.EmailLayout)) || emailCreateMode === "editor")) {
|
|
1497
1627
|
let isEmailCreate = slidBoxContent === 'createTemplate';
|
|
1498
1628
|
isEmailCreate = currentChannel.toUpperCase() === constants.EMAIL && ((emailCreateMode === "upload" && currentStep !== 'createTemplateContent') || (emailCreateMode === "editor" && currentStep !== 'createTemplateContent' && currentStep !== "templateSelection"));
|
|
1499
1629
|
isShowContinueFooter = isEmailCreate && emailCreateMode;
|
|
@@ -1502,8 +1632,6 @@ export class Creatives extends React.Component {
|
|
|
1502
1632
|
isShowContinueFooter = !isEmpty(mobilePushCreateMode) && currentStep === "modeSelection";
|
|
1503
1633
|
} else if (currentChannel.toUpperCase() === constants.WECHAT) {
|
|
1504
1634
|
isShowContinueFooter = !isEmpty(weChatTemplateType) && currentStep === "modeSelection";
|
|
1505
|
-
} else if (currentChannel.toUpperCase() === constants.INAPP) {
|
|
1506
|
-
isShowContinueFooter = !isEmpty(inAppCreateMode) && currentChannel === "modeSelection";
|
|
1507
1635
|
}
|
|
1508
1636
|
|
|
1509
1637
|
return isShowContinueFooter;
|
|
@@ -1529,6 +1657,28 @@ export class Creatives extends React.Component {
|
|
|
1529
1657
|
return true;
|
|
1530
1658
|
}
|
|
1531
1659
|
|
|
1660
|
+
// Check if Continue button should be disabled (for new flow only)
|
|
1661
|
+
isContinueButtonDisabled = () => {
|
|
1662
|
+
const { currentChannel, emailCreateMode, templateNameExists } = this.state;
|
|
1663
|
+
const { isFullMode } = this.props;
|
|
1664
|
+
const supportCKEditor = commonUtil.hasSupportCKEditor();
|
|
1665
|
+
if (supportCKEditor) {
|
|
1666
|
+
return false;
|
|
1667
|
+
}
|
|
1668
|
+
if (currentChannel.toUpperCase() === constants.EMAIL) {
|
|
1669
|
+
const isEditorSelected = !!emailCreateMode && emailCreateMode !== 'upload';
|
|
1670
|
+
// In full mode: require both template name AND editor selection
|
|
1671
|
+
// In library mode: require only editor selection (template name not needed)
|
|
1672
|
+
if (isFullMode) {
|
|
1673
|
+
const isTemplateNameValid = templateNameExists;
|
|
1674
|
+
return !(isTemplateNameValid && isEditorSelected);
|
|
1675
|
+
}
|
|
1676
|
+
// Library mode: only editor selection is required
|
|
1677
|
+
return !isEditorSelected;
|
|
1678
|
+
}
|
|
1679
|
+
return true;
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1532
1682
|
render() {
|
|
1533
1683
|
const {
|
|
1534
1684
|
slidBoxContent,
|
|
@@ -1537,6 +1687,7 @@ export class Creatives extends React.Component {
|
|
|
1537
1687
|
templateData,
|
|
1538
1688
|
currentChannel,
|
|
1539
1689
|
emailCreateMode,
|
|
1690
|
+
selectedEmailCreateMode,
|
|
1540
1691
|
templateStep,
|
|
1541
1692
|
isLoadingContent,
|
|
1542
1693
|
mobilePushCreateMode,
|
|
@@ -1549,6 +1700,8 @@ export class Creatives extends React.Component {
|
|
|
1549
1700
|
activeFormBuilderTab,
|
|
1550
1701
|
showTestAndPreviewSlidebox,
|
|
1551
1702
|
isTestAndPreviewMode,
|
|
1703
|
+
inAppEditorType,
|
|
1704
|
+
htmlEditorValidationState,
|
|
1552
1705
|
} = this.state;
|
|
1553
1706
|
const {
|
|
1554
1707
|
isFullMode,
|
|
@@ -1571,9 +1724,35 @@ export class Creatives extends React.Component {
|
|
|
1571
1724
|
isLoyaltyModule,
|
|
1572
1725
|
loyaltyMetaData = {},
|
|
1573
1726
|
} = this.props;
|
|
1727
|
+
// Compute Continue button label
|
|
1728
|
+
const supportCKEditor = commonUtil.hasSupportCKEditor();
|
|
1729
|
+
const continueButtonLabel = supportCKEditor ? messages.continue : messages.next;
|
|
1730
|
+
|
|
1574
1731
|
const mapTemplateCreate = slidBoxContent === "createTemplate"
|
|
1575
1732
|
&& weChatTemplateType === MAP_TEMPLATE
|
|
1576
1733
|
&& templateStep !== "modeSelection";
|
|
1734
|
+
|
|
1735
|
+
// Determine if we're in HTML Editor mode (where errors are shown in ValidationErrorDisplay, not ErrorInfoNote in footer)
|
|
1736
|
+
const isEmailChannel = currentChannel?.toUpperCase() === constants.EMAIL;
|
|
1737
|
+
const isEditMode = slidBoxContent === 'editTemplate';
|
|
1738
|
+
const isHTMLEditorModeInCreate = selectedEmailCreateMode === 'html_editor';
|
|
1739
|
+
const isHTMLEditorModeInEdit = isEditMode && htmlEditorValidationState != null;
|
|
1740
|
+
const isHTMLEditorMode = isEmailChannel && (isHTMLEditorModeInCreate || isHTMLEditorModeInEdit);
|
|
1741
|
+
const isBEEEditor = selectedEmailCreateMode === 'drag_drop'
|
|
1742
|
+
|| (emailCreateMode === 'editor' && !isHTMLEditorMode);
|
|
1743
|
+
|
|
1744
|
+
// Check for BEE editor errors (same logic as SlideBoxFooter)
|
|
1745
|
+
const hasStandardErrors = liquidErrorMessage && liquidErrorMessage.STANDARD_ERROR_MSG && liquidErrorMessage.STANDARD_ERROR_MSG.length > 0;
|
|
1746
|
+
const hasLiquidErrors = liquidErrorMessage && liquidErrorMessage.LIQUID_ERROR_MSG && liquidErrorMessage.LIQUID_ERROR_MSG.length > 0;
|
|
1747
|
+
const htmlEditorHasErrors = htmlEditorValidationState && htmlEditorValidationState.issueCounts && htmlEditorValidationState.issueCounts.total > 0;
|
|
1748
|
+
const hasBEEEditorErrors = isEmailChannel && (hasStandardErrors || hasLiquidErrors) && (!htmlEditorValidationState || !htmlEditorHasErrors);
|
|
1749
|
+
|
|
1750
|
+
// Only apply margin to footer when ErrorInfoNote is shown in footer (BEE editor)
|
|
1751
|
+
// For HTML Editor, errors are shown in ValidationErrorDisplay (inside content area), so no footer margin needed
|
|
1752
|
+
// IMPORTANT: Never show ErrorInfoNote in footer when in HTML Editor mode, even if liquidErrorMessage exists
|
|
1753
|
+
const shouldShowErrorInfoNoteInFooter = isHTMLEditorMode ? false : hasBEEEditorErrors;
|
|
1754
|
+
|
|
1755
|
+
// Calculate margin for header/content (always apply if there are errors, regardless of editor type)
|
|
1577
1756
|
const slideBoxWrapperMargin = (get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0 && get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0)
|
|
1578
1757
|
? CAP_SPACE_64
|
|
1579
1758
|
: get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0
|
|
@@ -1583,7 +1762,11 @@ export class Creatives extends React.Component {
|
|
|
1583
1762
|
: 0;
|
|
1584
1763
|
/* TODO: Instead of passing down same props separately to each component down, write common function to these props and pass it accordingly */
|
|
1585
1764
|
return (
|
|
1586
|
-
<SlideBoxWrapper
|
|
1765
|
+
<SlideBoxWrapper
|
|
1766
|
+
slideBoxWrapperMargin={slideBoxWrapperMargin}
|
|
1767
|
+
shouldApplyFooterMargin={shouldShowErrorInfoNoteInFooter}
|
|
1768
|
+
className={classnames(`${classPrefix} ${isFullMode ? 'creatives-full-mode' : 'creatives-library-mode'} ${mapTemplateCreate ? 'map-template-create' : ''}`)}
|
|
1769
|
+
>
|
|
1587
1770
|
<CapSlideBox
|
|
1588
1771
|
header={
|
|
1589
1772
|
this.shouldShowHeader() && (
|
|
@@ -1632,6 +1815,8 @@ export class Creatives extends React.Component {
|
|
|
1632
1815
|
onChannelChange={this.onChannelChange}
|
|
1633
1816
|
onEmailModeChange={this.onEmailModeChange}//used when create is clicked in email
|
|
1634
1817
|
emailCreateMode={emailCreateMode}// upload zip || use editor are values
|
|
1818
|
+
onInAppEditorTypeChange={this.onInAppEditorTypeChange}//used when create is clicked in inapp
|
|
1819
|
+
inAppEditorType={inAppEditorType}// htmlEditor || dragDropEditor are values
|
|
1635
1820
|
templateStep={this.creativesTemplateSteps[templateStep]}
|
|
1636
1821
|
onCreateNextStep={this.onCreateNextStep}
|
|
1637
1822
|
onEnterTemplateName={this.onEnterTemplateName}
|
|
@@ -1641,6 +1826,8 @@ export class Creatives extends React.Component {
|
|
|
1641
1826
|
cap={cap}
|
|
1642
1827
|
setIsLoadingContent={this.setIsLoadingContent}
|
|
1643
1828
|
onMobilepushModeChange={this.onMobilepushModeChange}
|
|
1829
|
+
inAppCreateMode={this.state.inAppCreateMode}
|
|
1830
|
+
onInAppModeChange={this.onInAppModeChange}
|
|
1644
1831
|
mobilePushCreateMode={mobilePushCreateMode}
|
|
1645
1832
|
showTemplateName={this.showTemplateName}
|
|
1646
1833
|
onValidationFail={this.onValidationFail}
|
|
@@ -1679,6 +1866,7 @@ export class Creatives extends React.Component {
|
|
|
1679
1866
|
handleTestAndPreview={this.handleTestAndPreview}
|
|
1680
1867
|
handleCloseTestAndPreview={this.handleCloseTestAndPreview}
|
|
1681
1868
|
isTestAndPreviewMode={(() => this.state.isTestAndPreviewMode)()}
|
|
1869
|
+
onHtmlEditorValidationStateChange={this.updateHtmlEditorValidationState}
|
|
1682
1870
|
/>
|
|
1683
1871
|
)}
|
|
1684
1872
|
footer={this.shouldShowFooter() ? (
|
|
@@ -1693,6 +1881,7 @@ export class Creatives extends React.Component {
|
|
|
1693
1881
|
currentChannel={currentChannel.toUpperCase()}
|
|
1694
1882
|
templateStep={this.creativesTemplateSteps[templateStep]}
|
|
1695
1883
|
emailCreateMode={emailCreateMode}
|
|
1884
|
+
selectedEmailCreateMode={selectedEmailCreateMode}
|
|
1696
1885
|
shouldShowContinueFooter={this.shouldShowContinueFooter}
|
|
1697
1886
|
shouldShowDoneFooter={this.shouldShowDoneFooter}
|
|
1698
1887
|
fetchingCmsData={fetchingCmsData}
|
|
@@ -1701,18 +1890,22 @@ export class Creatives extends React.Component {
|
|
|
1701
1890
|
errorMessages={liquidErrorMessage}
|
|
1702
1891
|
currentTab={activeFormBuilderTab}
|
|
1703
1892
|
onTestAndPreview={this.handleTestAndPreview}
|
|
1893
|
+
isContinueButtonDisabled={this.isContinueButtonDisabled()}
|
|
1894
|
+
continueButtonLabel={continueButtonLabel}
|
|
1704
1895
|
showTestAndPreviewButton={(() => {
|
|
1705
1896
|
const isEmailOrSmsOrWhatsappOrRcsOrInAppOrMobilePush = [constants.EMAIL, constants.SMS, constants.WHATSAPP, constants.RCS, constants.INAPP, constants.MOBILE_PUSH, constants.VIBER, constants.ZALO].includes(currentChannel.toUpperCase());
|
|
1706
1897
|
const showButton = isEmailOrSmsOrWhatsappOrRcsOrInAppOrMobilePush && (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate');
|
|
1707
1898
|
return showButton;
|
|
1708
1899
|
})()}
|
|
1900
|
+
htmlEditorValidationState={htmlEditorValidationState}
|
|
1901
|
+
isCreatingTemplate={slidBoxContent === 'createTemplate' && currentChannel.toUpperCase() === constants.EMAIL}
|
|
1709
1902
|
/>
|
|
1710
1903
|
) : isLiquidValidationError && (
|
|
1711
1904
|
<CapRow className="template-footer-width">
|
|
1712
1905
|
{(() => {
|
|
1713
1906
|
const errorsToShow = get(liquidErrorMessage, constants.LIQUID_ERROR_MSG, []);
|
|
1714
1907
|
const standardErrorsToShow = get(liquidErrorMessage, constants.STANDARD_ERROR_MSG, []);
|
|
1715
|
-
return <ErrorInfoNote currentTab={activeFormBuilderTab?.toUpperCase()} errorMessages={{LIQUID_ERROR_MSG: errorsToShow, STANDARD_ERROR_MSG: standardErrorsToShow}} />;
|
|
1908
|
+
return <ErrorInfoNote currentTab={activeFormBuilderTab?.toUpperCase()} errorMessages={{ LIQUID_ERROR_MSG: errorsToShow, STANDARD_ERROR_MSG: standardErrorsToShow }} />;
|
|
1716
1909
|
})()}
|
|
1717
1910
|
</CapRow>
|
|
1718
1911
|
)}
|
|
@@ -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`,
|
|
@@ -366,4 +370,8 @@ export default defineMessages({
|
|
|
366
370
|
id: `${scope}.testAndPreview`,
|
|
367
371
|
defaultMessage: `Preview and Test`,
|
|
368
372
|
},
|
|
373
|
+
"next": {
|
|
374
|
+
id: `${scope}.next`,
|
|
375
|
+
defaultMessage: `Next`,
|
|
376
|
+
},
|
|
369
377
|
});
|
|
@@ -43,7 +43,12 @@ describe("test for empty email empty template name", () => {
|
|
|
43
43
|
slidBoxContent: "editTemplate",
|
|
44
44
|
currentChannel: "EMAIL",
|
|
45
45
|
templateStep: "modeSelection",
|
|
46
|
-
isTemplateNameEmpty: true
|
|
46
|
+
isTemplateNameEmpty: true,
|
|
47
|
+
htmlEditorValidationState: {
|
|
48
|
+
isContentEmpty: false,
|
|
49
|
+
issueCounts: { html: 0, label: 0, liquid: 0, total: 0 },
|
|
50
|
+
},
|
|
51
|
+
isCreatingTemplate: false,
|
|
47
52
|
}
|
|
48
53
|
renderComponent(props);
|
|
49
54
|
const errorMessage = await screen.findByText(/template name cannot be empty/i);
|
|
@@ -52,7 +57,11 @@ describe("test for empty email empty template name", () => {
|
|
|
52
57
|
expect(updateBtn).toBeDisabled();
|
|
53
58
|
renderComponent({
|
|
54
59
|
...props,
|
|
55
|
-
isTemplateNameEmpty: false
|
|
60
|
+
isTemplateNameEmpty: false,
|
|
61
|
+
htmlEditorValidationState: {
|
|
62
|
+
isContentEmpty: false,
|
|
63
|
+
issueCounts: { html: 0, label: 0, liquid: 0, total: 0 },
|
|
64
|
+
},
|
|
56
65
|
})
|
|
57
66
|
const updateBtns = screen.getAllByRole('button',{name:/update/i});
|
|
58
67
|
expect(updateBtns[1]).toBeEnabled();
|