@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
|
@@ -16,7 +16,7 @@ const VALIDATION_SOURCES = {
|
|
|
16
16
|
EMAIL_SPECIFIC: 'email-specific',
|
|
17
17
|
INAPP_SPECIFIC: 'inapp-specific',
|
|
18
18
|
EMAIL_COMPATIBILITY: 'email-compatibility',
|
|
19
|
-
MOBILE_OPTIMIZATION: 'mobile-optimization'
|
|
19
|
+
MOBILE_OPTIMIZATION: 'mobile-optimization',
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
/**
|
|
@@ -30,42 +30,47 @@ export const transformValidationToErrorInfo = (validation, variant = 'email') =>
|
|
|
30
30
|
return { errorMessages: { LIQUID_ERROR_MSG: [], STANDARD_ERROR_MSG: [] } };
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
if (typeof validation.getAllIssues !== 'function') {
|
|
34
|
+
console.warn('[validationAdapter] validation.getAllIssues is not a function:', validation);
|
|
35
|
+
return { errorMessages: { LIQUID_ERROR_MSG: [], STANDARD_ERROR_MSG: [] } };
|
|
36
|
+
}
|
|
37
|
+
|
|
33
38
|
const allIssues = validation.getAllIssues();
|
|
39
|
+
// Safety check: ensure allIssues is an array
|
|
40
|
+
if (!Array.isArray(allIssues)) {
|
|
41
|
+
console.warn('[validationAdapter] validation.getAllIssues() did not return an array:', allIssues);
|
|
42
|
+
return { errorMessages: { LIQUID_ERROR_MSG: [], STANDARD_ERROR_MSG: [] } };
|
|
43
|
+
}
|
|
34
44
|
|
|
35
45
|
// Separate liquid and standard errors
|
|
36
|
-
const liquidErrors = allIssues.filter(issue =>
|
|
37
|
-
issue.
|
|
38
|
-
issue.
|
|
39
|
-
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
issue.source !== VALIDATION_SOURCES.LIQUID &&
|
|
44
|
-
!issue.rule?.includes('liquid') &&
|
|
45
|
-
!issue.message?.toLowerCase().includes('liquid')
|
|
46
|
-
);
|
|
46
|
+
const liquidErrors = allIssues.filter((issue) => issue.source === VALIDATION_SOURCES.LIQUID
|
|
47
|
+
|| issue.rule?.includes('liquid')
|
|
48
|
+
|| issue.message?.toLowerCase().includes('liquid'));
|
|
49
|
+
|
|
50
|
+
const standardErrors = allIssues.filter((issue) => issue.source !== VALIDATION_SOURCES.LIQUID
|
|
51
|
+
&& !issue.rule?.includes('liquid')
|
|
52
|
+
&& !issue.message?.toLowerCase().includes('liquid'));
|
|
47
53
|
|
|
48
54
|
// Format errors for ErrorInfoNote
|
|
49
|
-
const formatErrors = (errors) =>
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
message += `, Char ${error.column}`;
|
|
58
|
-
}
|
|
59
|
-
message += '.';
|
|
55
|
+
const formatErrors = (errors) => errors.map((error) => {
|
|
56
|
+
let {message} = error;
|
|
57
|
+
|
|
58
|
+
// Add line/column info if available
|
|
59
|
+
if (error.line) {
|
|
60
|
+
message += ` Line ${error.line}`;
|
|
61
|
+
if (error.column) {
|
|
62
|
+
message += `, Char ${error.column}`;
|
|
60
63
|
}
|
|
64
|
+
message += '.';
|
|
65
|
+
}
|
|
61
66
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
// Add rule info if available
|
|
68
|
+
if (error.rule) {
|
|
69
|
+
message += ` • ${error.rule}`;
|
|
70
|
+
}
|
|
66
71
|
|
|
67
|
-
|
|
68
|
-
|
|
72
|
+
return message;
|
|
73
|
+
});
|
|
69
74
|
|
|
70
75
|
// Handle InApp variant with platform-specific errors (if needed in future)
|
|
71
76
|
if (variant === 'inapp') {
|
|
@@ -74,8 +79,8 @@ export const transformValidationToErrorInfo = (validation, variant = 'email') =>
|
|
|
74
79
|
return {
|
|
75
80
|
errorMessages: {
|
|
76
81
|
LIQUID_ERROR_MSG: formatErrors(liquidErrors),
|
|
77
|
-
STANDARD_ERROR_MSG: formatErrors(standardErrors)
|
|
78
|
-
}
|
|
82
|
+
STANDARD_ERROR_MSG: formatErrors(standardErrors),
|
|
83
|
+
},
|
|
79
84
|
};
|
|
80
85
|
}
|
|
81
86
|
|
|
@@ -83,8 +88,8 @@ export const transformValidationToErrorInfo = (validation, variant = 'email') =>
|
|
|
83
88
|
return {
|
|
84
89
|
errorMessages: {
|
|
85
90
|
LIQUID_ERROR_MSG: formatErrors(liquidErrors),
|
|
86
|
-
STANDARD_ERROR_MSG: formatErrors(standardErrors)
|
|
87
|
-
}
|
|
91
|
+
STANDARD_ERROR_MSG: formatErrors(standardErrors),
|
|
92
|
+
},
|
|
88
93
|
};
|
|
89
94
|
};
|
|
90
95
|
|
|
@@ -98,7 +103,18 @@ export const hasValidationErrors = (validation) => {
|
|
|
98
103
|
return false;
|
|
99
104
|
}
|
|
100
105
|
|
|
106
|
+
if (typeof validation.getAllIssues !== 'function') {
|
|
107
|
+
console.warn('[validationAdapter] validation.getAllIssues is not a function:', validation);
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
|
|
101
111
|
const allIssues = validation.getAllIssues();
|
|
112
|
+
// Safety check: ensure allIssues is an array
|
|
113
|
+
if (!Array.isArray(allIssues)) {
|
|
114
|
+
console.warn('[validationAdapter] validation.getAllIssues() did not return an array:', allIssues);
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
|
|
102
118
|
return allIssues.length > 0;
|
|
103
119
|
};
|
|
104
120
|
|
|
@@ -112,19 +128,28 @@ export const getValidationSummary = (validation) => {
|
|
|
112
128
|
return { totalErrors: 0, totalWarnings: 0, hasLiquidErrors: false };
|
|
113
129
|
}
|
|
114
130
|
|
|
131
|
+
if (typeof validation.getAllIssues !== 'function') {
|
|
132
|
+
console.warn('[validationAdapter] validation.getAllIssues is not a function:', validation);
|
|
133
|
+
return { totalErrors: 0, totalWarnings: 0, hasLiquidErrors: false };
|
|
134
|
+
}
|
|
135
|
+
|
|
115
136
|
const allIssues = validation.getAllIssues();
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
);
|
|
137
|
+
// Safety check: ensure allIssues is an array
|
|
138
|
+
if (!Array.isArray(allIssues)) {
|
|
139
|
+
console.warn('[validationAdapter] validation.getAllIssues() did not return an array:', allIssues);
|
|
140
|
+
return { totalErrors: 0, totalWarnings: 0, hasLiquidErrors: false };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const errors = allIssues.filter((issue) => issue.severity === 'error');
|
|
144
|
+
const warnings = allIssues.filter((issue) => issue.severity === 'warning');
|
|
145
|
+
const liquidErrors = allIssues.filter((issue) => issue.source === VALIDATION_SOURCES.LIQUID
|
|
146
|
+
|| issue.rule?.includes('liquid')
|
|
147
|
+
|| issue.message?.toLowerCase().includes('liquid'));
|
|
123
148
|
|
|
124
149
|
return {
|
|
125
150
|
totalErrors: errors.length,
|
|
126
151
|
totalWarnings: warnings.length,
|
|
127
152
|
hasLiquidErrors: liquidErrors.length > 0,
|
|
128
|
-
totalIssues: allIssues.length
|
|
153
|
+
totalIssues: allIssues.length,
|
|
129
154
|
};
|
|
130
155
|
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation Constants
|
|
3
|
+
*
|
|
4
|
+
* Shared constants for validation issue categorization across HTML Editor components
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Issue sources for categorizing validation errors
|
|
8
|
+
export const ISSUE_SOURCES = {
|
|
9
|
+
HTMLHINT: 'htmlhint',
|
|
10
|
+
CSS_VALIDATOR: 'css-validator',
|
|
11
|
+
CUSTOM: 'custom',
|
|
12
|
+
SECURITY: 'security',
|
|
13
|
+
LIQUID: 'liquid-validator',
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// Label issue patterns - syntax errors related to tags
|
|
17
|
+
// These patterns identify tag syntax errors (open/close tags, attributes, brackets)
|
|
18
|
+
export const LABEL_ISSUE_PATTERNS = [
|
|
19
|
+
'tag must be paired',
|
|
20
|
+
'open tag match failed',
|
|
21
|
+
'closed tag match failed',
|
|
22
|
+
'missing required',
|
|
23
|
+
'tag-pair',
|
|
24
|
+
'attr-value-not-empty',
|
|
25
|
+
'attr-no-duplication',
|
|
26
|
+
'tag-self-close',
|
|
27
|
+
'spec-char-escape',
|
|
28
|
+
'tagname-lowercase',
|
|
29
|
+
'attr-lowercase',
|
|
30
|
+
'src-not-empty',
|
|
31
|
+
'alt-require',
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
// Tab keys: Errors = blocking, Warnings = non-blocking
|
|
35
|
+
export const ERROR_TAB_KEYS = {
|
|
36
|
+
ERRORS: 'errors',
|
|
37
|
+
WARNINGS: 'warnings',
|
|
38
|
+
};
|
|
@@ -16,6 +16,7 @@ import { INAPP } from '../../v2Containers/App/constants';
|
|
|
16
16
|
import { ANDROID, IOS } from '../../v2Containers/InApp/constants';
|
|
17
17
|
import { getCtaObject } from '../../v2Containers/InApp/utils';
|
|
18
18
|
import { CAROUSEL, VIDEO } from '../../v2Containers/MobilePushNew/constants';
|
|
19
|
+
import { DEVICE_TYPES, IPHONE } from './constants';
|
|
19
20
|
|
|
20
21
|
class MobilePushPreviewV2 extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
|
21
22
|
constructor(props) {
|
|
@@ -26,8 +27,17 @@ class MobilePushPreviewV2 extends React.Component { // eslint-disable-line react
|
|
|
26
27
|
this.getPreview = this.getPreview.bind(this);
|
|
27
28
|
this.setContent = this.setContent.bind(this);
|
|
28
29
|
this.goToDuplicate = this.goToDuplicate.bind(this);
|
|
29
|
-
|
|
30
|
-
const
|
|
30
|
+
// Check for INAPP channel structure (versions.base.content.ANDROID/IOS) or MOBILE_PUSH structure (versions.base.ANDROID/IOS)
|
|
31
|
+
const { channel, templateData } = props;
|
|
32
|
+
let hasAndroid;
|
|
33
|
+
let hasIos;
|
|
34
|
+
if (channel === INAPP.toUpperCase()) {
|
|
35
|
+
hasAndroid = get(templateData, 'versions.base.content.ANDROID') || get(templateData, 'androidContent');
|
|
36
|
+
hasIos = get(templateData, 'versions.base.content.IOS') || get(templateData, 'iosContent');
|
|
37
|
+
} else {
|
|
38
|
+
hasAndroid = get(templateData, 'versions.base.ANDROID') || get(templateData, 'androidContent.title');
|
|
39
|
+
hasIos = get(templateData, 'versions.base.IOS') || get(templateData, 'iosContent.title');
|
|
40
|
+
}
|
|
31
41
|
let device = "android";
|
|
32
42
|
if (hasAndroid) {
|
|
33
43
|
device = 'android';
|
|
@@ -45,6 +55,17 @@ class MobilePushPreviewV2 extends React.Component { // eslint-disable-line react
|
|
|
45
55
|
if (channel === INAPP.toUpperCase()) {
|
|
46
56
|
const androidContent = get(templateData, 'versions.base.content.ANDROID') || get(templateData, 'androidContent');
|
|
47
57
|
const iosContent = get(templateData, 'versions.base.content.IOS') || get(templateData, 'iosContent');
|
|
58
|
+
const isBeeFreeTemplate = get(androidContent, 'isBEEeditor') || get(iosContent, 'isBEEeditor');
|
|
59
|
+
if (isBeeFreeTemplate) {
|
|
60
|
+
// Normalize device to 'android' or 'ios' for comparison
|
|
61
|
+
const normalizedDevice = device === IPHONE ? DEVICE_TYPES.IOS : device?.toLowerCase();
|
|
62
|
+
const isAndroid = normalizedDevice === ANDROID.toLowerCase();
|
|
63
|
+
content = {
|
|
64
|
+
inAppPreviewContent: isAndroid ? androidContent?.beeHtml : iosContent?.beeHtml,
|
|
65
|
+
isBeeFreeTemplate: true,
|
|
66
|
+
};
|
|
67
|
+
return content;
|
|
68
|
+
}
|
|
48
69
|
const androidPreviewContent = {
|
|
49
70
|
templateTitle: androidContent?.title,
|
|
50
71
|
templateMsg: androidContent?.message,
|
|
@@ -57,9 +78,12 @@ class MobilePushPreviewV2 extends React.Component { // eslint-disable-line react
|
|
|
57
78
|
mediaPreview: { inAppImageSrcIos: iosContent?.expandableDetails?.image },
|
|
58
79
|
ctaData: getCtaObject(iosContent?.expandableDetails?.ctas),
|
|
59
80
|
};
|
|
81
|
+
// Normalize device to 'android' or 'ios' for comparison
|
|
82
|
+
const normalizedDevice = device === IPHONE ? DEVICE_TYPES.IOS : device?.toLowerCase();
|
|
83
|
+
const isAndroid = normalizedDevice === ANDROID.toLowerCase();
|
|
60
84
|
content = {
|
|
61
|
-
inAppPreviewContent:
|
|
62
|
-
templateLayoutType:
|
|
85
|
+
inAppPreviewContent: isAndroid ? androidPreviewContent : iosPreviewContent,
|
|
86
|
+
templateLayoutType: isAndroid ? androidContent?.bodyType : iosContent?.bodyType,
|
|
63
87
|
};
|
|
64
88
|
} else if (channel === MOBILE_PUSH) {
|
|
65
89
|
const androidContent = get(templateData, 'versions.base.ANDROID') || get(templateData, 'androidContent');
|
|
@@ -125,7 +149,9 @@ class MobilePushPreviewV2 extends React.Component { // eslint-disable-line react
|
|
|
125
149
|
}
|
|
126
150
|
|
|
127
151
|
getPreview(device) {
|
|
128
|
-
|
|
152
|
+
// Normalize device to 'android' or 'ios' for comparison
|
|
153
|
+
const normalizedDevice = device === IPHONE ? DEVICE_TYPES.IOS : device?.toLowerCase();
|
|
154
|
+
const deviceParam = normalizedDevice === ANDROID.toLowerCase() ? ANDROID : IOS;
|
|
129
155
|
return (
|
|
130
156
|
<TemplatePreview
|
|
131
157
|
device={this.props.channel === INAPP.toUpperCase() ? deviceParam : device}
|
|
@@ -159,8 +185,8 @@ class MobilePushPreviewV2 extends React.Component { // eslint-disable-line react
|
|
|
159
185
|
hasAndroid = get(templateData, 'versions.base.ANDROID') || get(templateData, 'androidContent.title');
|
|
160
186
|
hasIos = get(templateData, 'versions.base.IOS') || get(templateData, 'iosContent.title');
|
|
161
187
|
} else if (this.props.channel === INAPP.toUpperCase()) {
|
|
162
|
-
hasAndroid = get(templateData, 'versions.base.content.ANDROID') || get(templateData, 'androidContent
|
|
163
|
-
hasIos = get(templateData, 'versions.base.content.IOS') || get(templateData, 'iosContent
|
|
188
|
+
hasAndroid = get(templateData, 'versions.base.content.ANDROID') || get(templateData, 'androidContent');
|
|
189
|
+
hasIos = get(templateData, 'versions.base.content.IOS') || get(templateData, 'iosContent');
|
|
164
190
|
}
|
|
165
191
|
const hasBothAndroidAndIos = hasAndroid && hasIos;
|
|
166
192
|
return (
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
@import '~@capillarytech/cap-ui-library/styles/_variables.scss';
|
|
2
2
|
|
|
3
|
+
.shell-v2 {
|
|
4
|
+
&.align-center {
|
|
5
|
+
.preview-image-container {
|
|
6
|
+
position: relative;
|
|
7
|
+
display: inline-block;
|
|
8
|
+
width: 100%;
|
|
9
|
+
height: 100%;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
3
14
|
.shell-v2 {
|
|
4
15
|
position: relative;
|
|
5
16
|
-webkit-transform: translate(-50%);
|
|
@@ -16,10 +27,11 @@
|
|
|
16
27
|
&.mobilepush
|
|
17
28
|
|
|
18
29
|
.inapp-message-container-POPUP-ANDROID {
|
|
30
|
+
background-color: $CAP_WHITE;
|
|
19
31
|
position: absolute;
|
|
20
|
-
top:
|
|
32
|
+
top: 30%;
|
|
21
33
|
display: flex;
|
|
22
|
-
width:
|
|
34
|
+
width: 14.286rem;
|
|
23
35
|
left: 28%;
|
|
24
36
|
|
|
25
37
|
.inapp-title-POPUP-ANDROID {
|
|
@@ -59,10 +71,10 @@
|
|
|
59
71
|
.inapp-message-container-HEADER-ANDROID {
|
|
60
72
|
position: absolute;
|
|
61
73
|
display: flex;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
74
|
+
width: 17.571rem;
|
|
75
|
+
left: 18%;
|
|
76
|
+
top: 4.071rem;
|
|
77
|
+
background-color: $CAP_WHITE;
|
|
66
78
|
|
|
67
79
|
.inapp-title-HEADER-ANDROID {
|
|
68
80
|
left: 34%;
|
|
@@ -129,22 +141,24 @@
|
|
|
129
141
|
|
|
130
142
|
|
|
131
143
|
.inapp-message-container-FOOTER-ANDROID {
|
|
144
|
+
background-color: $CAP_WHITE;
|
|
132
145
|
position: absolute;
|
|
133
146
|
display: flex;
|
|
134
147
|
justify-content: center;
|
|
135
|
-
bottom:
|
|
136
|
-
width:
|
|
137
|
-
left:
|
|
148
|
+
bottom: 2.5%;
|
|
149
|
+
width: 16.571rem;
|
|
150
|
+
left: 21%;
|
|
151
|
+
background-color: $CAP_WHITE;
|
|
138
152
|
|
|
139
153
|
.inapp-title-FOOTER-ANDROID {
|
|
140
|
-
width:
|
|
154
|
+
width: 6.429rem;
|
|
141
155
|
height: 12px;
|
|
142
156
|
text-align: left;
|
|
143
157
|
left: 34%;
|
|
144
158
|
justify-content: center;
|
|
145
159
|
position: relative;
|
|
146
160
|
right: 33%;
|
|
147
|
-
bottom: -
|
|
161
|
+
bottom: -1.429rem;
|
|
148
162
|
font-size: 10px;
|
|
149
163
|
text-overflow: ellipsis;
|
|
150
164
|
overflow: hidden;
|
|
@@ -201,10 +215,12 @@
|
|
|
201
215
|
}
|
|
202
216
|
|
|
203
217
|
.inapp-message-container-FULLSCREEN-ANDROID {
|
|
218
|
+
background-color: $CAP_WHITE;
|
|
204
219
|
position: absolute;
|
|
205
220
|
top: 10%;
|
|
206
221
|
display: flex;
|
|
207
|
-
left:
|
|
222
|
+
left: 20%;
|
|
223
|
+
width: 16.643rem;
|
|
208
224
|
.inapp-title-FULLSCREEN-ANDROID {
|
|
209
225
|
text-overflow: ellipsis;
|
|
210
226
|
overflow: hidden;
|
|
@@ -238,10 +254,11 @@
|
|
|
238
254
|
}
|
|
239
255
|
|
|
240
256
|
.inapp-message-container-POPUP-iOS {
|
|
257
|
+
background-color: $CAP_WHITE;
|
|
241
258
|
position: absolute;
|
|
242
|
-
top:
|
|
259
|
+
top: 30%;
|
|
243
260
|
display: flex;
|
|
244
|
-
width:
|
|
261
|
+
width: 14.286rem;
|
|
245
262
|
left: 28%;
|
|
246
263
|
|
|
247
264
|
.inapp-title-POPUP-iOS {
|
|
@@ -278,18 +295,19 @@
|
|
|
278
295
|
}
|
|
279
296
|
|
|
280
297
|
.inapp-message-container-HEADER-iOS {
|
|
298
|
+
background-color: $CAP_WHITE;
|
|
281
299
|
position: absolute;
|
|
282
300
|
display: flex;
|
|
283
|
-
width:
|
|
284
|
-
left:
|
|
285
|
-
top:
|
|
301
|
+
width: 16.571rem;
|
|
302
|
+
left: 20%;
|
|
303
|
+
top: 10%;
|
|
286
304
|
|
|
287
305
|
.inapp-title-HEADER-iOS {
|
|
288
306
|
left: 34%;
|
|
289
307
|
top: 15%;
|
|
290
308
|
position: relative;
|
|
291
309
|
font-size: 10px;
|
|
292
|
-
width:
|
|
310
|
+
width: 6.429rem;
|
|
293
311
|
height: 12px;
|
|
294
312
|
text-overflow: ellipsis;
|
|
295
313
|
overflow: hidden;
|
|
@@ -300,7 +318,7 @@
|
|
|
300
318
|
|
|
301
319
|
.without-image-title-HEADER-ios {
|
|
302
320
|
left: 26%;
|
|
303
|
-
top:
|
|
321
|
+
top: 1.286rem;
|
|
304
322
|
text-align: center;
|
|
305
323
|
}
|
|
306
324
|
|
|
@@ -330,7 +348,7 @@
|
|
|
330
348
|
.without-image-content-HEADER-ios {
|
|
331
349
|
width: 92%;
|
|
332
350
|
left: 6%;
|
|
333
|
-
top:
|
|
351
|
+
top: 1.5rem;
|
|
334
352
|
}
|
|
335
353
|
|
|
336
354
|
.inapp-button-HEADER-iOS {
|
|
@@ -347,12 +365,14 @@
|
|
|
347
365
|
}
|
|
348
366
|
|
|
349
367
|
.inapp-message-container-FOOTER-iOS {
|
|
368
|
+
background-color: $CAP_WHITE;
|
|
350
369
|
position: absolute;
|
|
351
370
|
display: flex;
|
|
352
371
|
justify-content: center;
|
|
353
|
-
width:
|
|
354
|
-
left:
|
|
355
|
-
top:
|
|
372
|
+
width: 16.571rem;
|
|
373
|
+
left: 20%;
|
|
374
|
+
top: 42%;
|
|
375
|
+
bottom: 3.5%;
|
|
356
376
|
|
|
357
377
|
.inapp-title-FOOTER-iOS {
|
|
358
378
|
width: 90px;
|
|
@@ -420,10 +440,12 @@
|
|
|
420
440
|
}
|
|
421
441
|
|
|
422
442
|
.inapp-message-container-FULLSCREEN-iOS {
|
|
443
|
+
background-color: $CAP_WHITE;
|
|
423
444
|
position: absolute;
|
|
424
445
|
top: 10%;
|
|
425
446
|
display: flex;
|
|
426
|
-
left:
|
|
447
|
+
left: 20%;
|
|
448
|
+
width: 16.643rem;
|
|
427
449
|
.inapp-title-FULLSCREEN-iOS {
|
|
428
450
|
text-overflow: ellipsis;
|
|
429
451
|
overflow: hidden;
|
|
@@ -455,6 +477,15 @@
|
|
|
455
477
|
bottom: -1%;
|
|
456
478
|
}
|
|
457
479
|
}
|
|
480
|
+
|
|
481
|
+
.inapp-message-container-MODAL-ANDROID, .inapp-message-container-MODAL-iOS {
|
|
482
|
+
background-color: $CAP_WHITE;
|
|
483
|
+
position: absolute;
|
|
484
|
+
top: 30%;
|
|
485
|
+
display: flex;
|
|
486
|
+
width: 14.286rem;
|
|
487
|
+
left: 28%;
|
|
488
|
+
}
|
|
458
489
|
}
|
|
459
490
|
|
|
460
491
|
|
|
@@ -37,14 +37,8 @@ import {
|
|
|
37
37
|
import { VIBER, FACEBOOK } from '../../v2Containers/App/constants';
|
|
38
38
|
import Carousel from '../Carousel';
|
|
39
39
|
import whatsappMobileAndroid from './assets/images/whatsapp_mobile_android.svg';
|
|
40
|
-
import
|
|
41
|
-
import
|
|
42
|
-
import inAppMobileAndroidBottom from './assets/images/inapp_mobile_android_bottom.svg';
|
|
43
|
-
import inAppMobileAndroidFull from './assets/images/inapp_mobile_android_full.svg';
|
|
44
|
-
import inAppMobileIOSModal from './assets/images/inapp_mobile_ios_modal.svg';
|
|
45
|
-
import inAppMobileIOSTop from './assets/images/inapp_mobile_ios_top.svg';
|
|
46
|
-
import inAppMobileIOSBottom from './assets/images/inapp_mobile_ios_bottom.svg';
|
|
47
|
-
import inAppMobileIOSFull from './assets/images/inapp_mobile_ios_full.svg';
|
|
40
|
+
import inAppMobileDeviceAndroid from '../../assets/Android.png';
|
|
41
|
+
import inAppMobileDeviceIos from '../../assets/iOS.png';
|
|
48
42
|
import whatsappImageEmptyPreview from './assets/images/empty_image_preview.svg';
|
|
49
43
|
import whatsappVideoEmptyPreview from './assets/images/empty_video_preview.svg';
|
|
50
44
|
import videoPlay from '../../assets/videoPlay.svg';
|
|
@@ -239,7 +233,7 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
|
|
|
239
233
|
} = this.props;
|
|
240
234
|
let content = channel && channel.toLowerCase() === 'sms' ? [this.props.content] : this.props.content;
|
|
241
235
|
const { formatMessage } = intl;
|
|
242
|
-
const { rcsPreviewContent, inAppPreviewContent, viberPreviewContent } = content || {};
|
|
236
|
+
const { rcsPreviewContent, inAppPreviewContent, viberPreviewContent, isBeeFreeTemplate } = content || {};
|
|
243
237
|
const { rcsImageSrc, rcsVideoSrc, rcsTitle, rcsDesc, rcsSuggestions } = rcsPreviewContent || {};
|
|
244
238
|
const {
|
|
245
239
|
videoParams,
|
|
@@ -247,7 +241,11 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
|
|
|
247
241
|
buttonText: viberButtonText,
|
|
248
242
|
messageContent: viberMessageContent,
|
|
249
243
|
} = viberPreviewContent || {};
|
|
244
|
+
let isHTMLContent = true;
|
|
250
245
|
const {mediaPreview = {}, templateTitle = "", templateMsg = "", ctaData} = inAppPreviewContent || {};
|
|
246
|
+
if(templateTitle !== undefined && ctaData !== undefined && templateMsg !== undefined) {
|
|
247
|
+
isHTMLContent = false;
|
|
248
|
+
}
|
|
251
249
|
let smsDetails = {};
|
|
252
250
|
// let smsText = '';
|
|
253
251
|
if (this.props.content && this.props.charCounterEnabled) {
|
|
@@ -464,27 +462,9 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
|
|
|
464
462
|
|
|
465
463
|
const getPreviewImage = () => {
|
|
466
464
|
if (this.props.device === ANDROID) {
|
|
467
|
-
|
|
468
|
-
case INAPP_MESSAGE_LAYOUT_TYPES.MODAL:
|
|
469
|
-
return inAppMobileAndroidModal;
|
|
470
|
-
case INAPP_MESSAGE_LAYOUT_TYPES.TOPBANNER:
|
|
471
|
-
return inAppMobileAndroidTop;
|
|
472
|
-
case INAPP_MESSAGE_LAYOUT_TYPES.BOTTOMBANNER:
|
|
473
|
-
return inAppMobileAndroidBottom;
|
|
474
|
-
default:
|
|
475
|
-
return inAppMobileAndroidFull;
|
|
476
|
-
}
|
|
465
|
+
return inAppMobileDeviceAndroid;
|
|
477
466
|
} else {
|
|
478
|
-
|
|
479
|
-
case INAPP_MESSAGE_LAYOUT_TYPES.MODAL:
|
|
480
|
-
return inAppMobileIOSModal;
|
|
481
|
-
case INAPP_MESSAGE_LAYOUT_TYPES.TOPBANNER:
|
|
482
|
-
return inAppMobileIOSTop;
|
|
483
|
-
case INAPP_MESSAGE_LAYOUT_TYPES.BOTTOMBANNER:
|
|
484
|
-
return inAppMobileIOSBottom;
|
|
485
|
-
default:
|
|
486
|
-
return inAppMobileIOSFull;
|
|
487
|
-
}
|
|
467
|
+
return inAppMobileDeviceIos;
|
|
488
468
|
}
|
|
489
469
|
};
|
|
490
470
|
|
|
@@ -1374,7 +1354,34 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
|
|
|
1374
1354
|
</div>
|
|
1375
1355
|
)}
|
|
1376
1356
|
{channel?.toUpperCase() === INAPP && (
|
|
1377
|
-
|
|
1357
|
+
isBeeFreeTemplate ? (
|
|
1358
|
+
<div className="shell-v2 align-center">
|
|
1359
|
+
<CapRow className="preview-image-container">
|
|
1360
|
+
<CapImage
|
|
1361
|
+
className="preview-image"
|
|
1362
|
+
src={this.props.device === ANDROID ? inAppMobileDeviceAndroid : inAppMobileDeviceIos}
|
|
1363
|
+
alt={formatMessage(messages.previewGenerated)}
|
|
1364
|
+
/>
|
|
1365
|
+
<iframe
|
|
1366
|
+
srcDoc={inAppPreviewContent?.value}
|
|
1367
|
+
title={formatMessage(messages.inappPreview)}
|
|
1368
|
+
style={{
|
|
1369
|
+
position: 'absolute',
|
|
1370
|
+
top: '3rem',
|
|
1371
|
+
left: '5rem',
|
|
1372
|
+
width: '60%',
|
|
1373
|
+
height: '89%',
|
|
1374
|
+
zIndex: 1,
|
|
1375
|
+
pointerEvents: 'none',
|
|
1376
|
+
backgroundColor: 'white',
|
|
1377
|
+
borderRadius: `${CAP_SPACE_08}`,
|
|
1378
|
+
}}
|
|
1379
|
+
frameBorder="0"
|
|
1380
|
+
/>
|
|
1381
|
+
</CapRow>
|
|
1382
|
+
</div>
|
|
1383
|
+
): (
|
|
1384
|
+
<div className="shell-v2 align-center">
|
|
1378
1385
|
<CapImage
|
|
1379
1386
|
className="preview-image"
|
|
1380
1387
|
src={getPreviewImage()}
|
|
@@ -1382,9 +1389,15 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
|
|
|
1382
1389
|
/>
|
|
1383
1390
|
<div className="preview-image">
|
|
1384
1391
|
<div
|
|
1385
|
-
className={`inapp-message-container-${templateLayoutType}-${device}
|
|
1392
|
+
className={`inapp-message-container-${templateLayoutType}-${device} inapp`}
|
|
1386
1393
|
>
|
|
1387
|
-
|
|
1394
|
+
{isHTMLContent ? (
|
|
1395
|
+
<div
|
|
1396
|
+
className="inapp-html-content"
|
|
1397
|
+
dangerouslySetInnerHTML={{ __html: templateMsg }}
|
|
1398
|
+
/>
|
|
1399
|
+
) : (
|
|
1400
|
+
<div className="preview-inapp-screen">
|
|
1388
1401
|
{
|
|
1389
1402
|
<CapLabel
|
|
1390
1403
|
type="label15"
|
|
@@ -1449,9 +1462,11 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
|
|
|
1449
1462
|
</CapButton>
|
|
1450
1463
|
)}
|
|
1451
1464
|
</div>
|
|
1465
|
+
)}
|
|
1452
1466
|
</div>
|
|
1453
1467
|
</div>
|
|
1454
1468
|
</div>
|
|
1469
|
+
)
|
|
1455
1470
|
)}
|
|
1456
1471
|
</CapRow>
|
|
1457
1472
|
</CapColumn>
|
|
@@ -94,4 +94,8 @@ export default defineMessages({
|
|
|
94
94
|
id: 'creatives.componentsV2.TemplatePreview.videoNotSupported',
|
|
95
95
|
defaultMessage: 'Your browser does not support the video tag.',
|
|
96
96
|
},
|
|
97
|
+
inappPreview: {
|
|
98
|
+
id: 'creatives.componentsV2.TemplatePreview.inappPreview',
|
|
99
|
+
defaultMessage: 'Inapp Preview',
|
|
100
|
+
},
|
|
97
101
|
});
|