@capillarytech/creatives-library 8.0.358 → 8.0.359-alpha.1
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/constants/unified.js +29 -0
- package/package.json +1 -1
- package/services/tests/api.test.js +35 -20
- package/utils/commonUtils.js +19 -1
- package/utils/rcsPayloadUtils.js +92 -0
- package/utils/templateVarUtils.js +201 -0
- package/utils/tests/rcsPayloadUtils.test.js +226 -0
- package/utils/tests/templateVarUtils.test.js +204 -0
- package/v2Components/CapActionButton/constants.js +7 -0
- package/v2Components/CapActionButton/index.js +166 -108
- package/v2Components/CapActionButton/index.scss +157 -6
- package/v2Components/CapActionButton/messages.js +19 -3
- package/v2Components/CapActionButton/tests/index.test.js +41 -17
- package/v2Components/CapImageUpload/index.js +2 -2
- package/v2Components/CapTagList/index.js +10 -0
- package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +72 -49
- package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +8 -2
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +214 -21
- package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +16 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +83 -9
- package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +30 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +79 -11
- package/v2Components/CommonTestAndPreview/SendTestMessage.js +10 -5
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +157 -15
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +346 -76
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +150 -4
- package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +11 -0
- package/v2Components/CommonTestAndPreview/constants.js +38 -2
- package/v2Components/CommonTestAndPreview/index.js +810 -222
- package/v2Components/CommonTestAndPreview/messages.js +45 -3
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +59 -0
- package/v2Components/CommonTestAndPreview/sagas.js +25 -6
- package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +308 -284
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +231 -65
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +118 -5
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +341 -0
- package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +8 -1
- package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +34 -13
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +281 -283
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +199 -1
- package/v2Components/CommonTestAndPreview/tests/index.test.js +133 -4
- package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +67 -0
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +31 -24
- package/v2Components/FormBuilder/index.js +5 -4
- package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +91 -0
- package/v2Components/SmsFallback/constants.js +73 -0
- package/v2Components/SmsFallback/index.js +956 -0
- package/v2Components/SmsFallback/index.scss +265 -0
- package/v2Components/SmsFallback/messages.js +78 -0
- package/v2Components/SmsFallback/smsFallbackUtils.js +119 -0
- package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +50 -0
- package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +147 -0
- package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +304 -0
- package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +223 -0
- package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +309 -0
- package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +422 -0
- package/v2Components/SmsFallback/useLocalTemplateList.js +92 -0
- package/v2Components/TemplatePreview/_templatePreview.scss +37 -22
- package/v2Components/TemplatePreview/constants.js +2 -0
- package/v2Components/TemplatePreview/index.js +143 -31
- package/v2Components/TemplatePreview/tests/index.test.js +142 -0
- package/v2Components/TestAndPreviewSlidebox/index.js +13 -1
- package/v2Components/TestAndPreviewSlidebox/sagas.js +11 -4
- package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +3 -1
- package/v2Components/VarSegmentMessageEditor/constants.js +2 -0
- package/v2Components/VarSegmentMessageEditor/index.js +125 -0
- package/v2Components/VarSegmentMessageEditor/index.scss +46 -0
- package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +17 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +36 -4
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +14 -5
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +36 -5
- package/v2Containers/CreativesContainer/constants.js +9 -0
- package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +79 -0
- package/v2Containers/CreativesContainer/index.js +322 -103
- package/v2Containers/CreativesContainer/index.scss +83 -1
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +90 -0
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +79 -34
- package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +79 -16
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +8 -0
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +357 -98
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +20 -15
- package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +258 -0
- package/v2Containers/CreativesContainer/tests/index.test.js +71 -9
- package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +125 -0
- package/v2Containers/MobilePush/Create/test/saga.test.js +2 -2
- package/v2Containers/Rcs/constants.js +120 -11
- package/v2Containers/Rcs/index.js +2577 -812
- package/v2Containers/Rcs/index.scss +281 -8
- package/v2Containers/Rcs/messages.js +34 -3
- package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +225 -0
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +98036 -70145
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +0 -5
- package/v2Containers/Rcs/tests/index.test.js +152 -121
- package/v2Containers/Rcs/tests/mockData.js +38 -0
- package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +318 -0
- package/v2Containers/Rcs/tests/utils.test.js +646 -30
- package/v2Containers/Rcs/utils.js +478 -11
- package/v2Containers/Sms/Create/index.js +106 -40
- package/v2Containers/Sms/smsFormDataHelpers.js +67 -0
- package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +253 -0
- package/v2Containers/SmsTrai/Create/index.js +9 -4
- package/v2Containers/SmsTrai/Edit/constants.js +2 -0
- package/v2Containers/SmsTrai/Edit/index.js +640 -130
- package/v2Containers/SmsTrai/Edit/index.scss +121 -0
- package/v2Containers/SmsTrai/Edit/messages.js +14 -4
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4328 -2375
- package/v2Containers/SmsWrapper/index.js +37 -8
- package/v2Containers/TagList/index.js +6 -0
- package/v2Containers/Templates/TemplatesActionBar.js +101 -0
- package/v2Containers/Templates/_templates.scss +166 -9
- package/v2Containers/Templates/actions.js +11 -0
- package/v2Containers/Templates/constants.js +2 -0
- package/v2Containers/Templates/index.js +121 -53
- package/v2Containers/Templates/sagas.js +56 -12
- package/v2Containers/Templates/tests/TemplatesActionBar.test.js +120 -0
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1062 -1017
- package/v2Containers/Templates/tests/sagas.test.js +199 -16
- package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +180 -0
- package/v2Containers/Templates/utils/smsTemplatesListApi.js +79 -0
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +72 -1
- package/v2Containers/TemplatesV2/index.js +86 -23
- package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +131 -0
- package/v2Containers/WeChat/MapTemplates/test/saga.test.js +9 -9
- package/v2Containers/Whatsapp/index.js +3 -20
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +578 -34
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
@import '~@capillarytech/cap-ui-library/styles/_variables';
|
|
2
|
+
|
|
3
|
+
/* Same look as RCS edit message block: background, spacing, text color */
|
|
4
|
+
.rcs_text_area_wrapper {
|
|
5
|
+
.rcs-edit-template-message-input {
|
|
6
|
+
background-color: $CAP_G10;
|
|
7
|
+
padding: $CAP_SPACE_12 $CAP_SPACE_16 $CAP_SPACE_16;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.rcs-edit-template-message-split {
|
|
11
|
+
margin: 0 0 $CAP_SPACE_04 0;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
text-overflow: ellipsis;
|
|
14
|
+
color: $FONT_COLOR_04;
|
|
15
|
+
font-weight: 500;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/* Variable chips: match RCS edit (white field, light border, 4px radius) */
|
|
19
|
+
.rcs-edit-template-message-input .ant-input,
|
|
20
|
+
.rcs-edit-template-message-input textarea.ant-input {
|
|
21
|
+
margin: 0 0 0.125rem 0;
|
|
22
|
+
border-radius: 0.25rem;
|
|
23
|
+
border: 0.0625rem solid $CAP_G07;
|
|
24
|
+
background-color: $CAP_WHITE;
|
|
25
|
+
overflow: hidden;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* Small gap between tag border and the next line (static text) */
|
|
29
|
+
.rcs-edit-template-message-input :not(:first-child) {
|
|
30
|
+
margin-top: $CAP_SPACE_08;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.rcs-edit-template-message-input > *:last-child {
|
|
34
|
+
margin-bottom: 0;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.var-segment-message-editor__var-slot {
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: column;
|
|
40
|
+
width: 100%;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.var-segment-message-editor__read-only-value {
|
|
45
|
+
margin: 0;
|
|
46
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { CAP_SPACE_16 } from '@capillarytech/cap-ui-library/styled/variables';
|
|
3
|
+
|
|
4
|
+
const CreativesSlideBoxWrapper = ({ slideBoxWrapperMargin, shouldApplyFooterMargin, children, className, ...rest }) => (
|
|
5
|
+
<div
|
|
6
|
+
className={`creatives-slide-box-wrapper${className ? ` ${className}` : ''}`}
|
|
7
|
+
style={{
|
|
8
|
+
'--slidebox-wrapper-margin': slideBoxWrapperMargin,
|
|
9
|
+
'--slidebox-footer-margin': shouldApplyFooterMargin ? `${CAP_SPACE_16}` : '0',
|
|
10
|
+
}}
|
|
11
|
+
{...rest}
|
|
12
|
+
>
|
|
13
|
+
{children}
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
export default CreativesSlideBoxWrapper;
|
|
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
|
|
|
3
3
|
import styled from 'styled-components';
|
|
4
4
|
import get from 'lodash/get';
|
|
5
5
|
import isEmpty from 'lodash/isEmpty';
|
|
6
|
+
import pick from 'lodash/pick';
|
|
6
7
|
import cloneDeep from 'lodash/cloneDeep';
|
|
7
8
|
import TemplatesV2 from '../TemplatesV2';
|
|
8
9
|
import TemplatePreview from '../../v2Components/TemplatePreview';
|
|
@@ -25,6 +26,7 @@ import Viber from '../Viber';
|
|
|
25
26
|
import Whatsapp from '../Whatsapp';
|
|
26
27
|
import InApp from '../InApp';
|
|
27
28
|
import Rcs from '../Rcs';
|
|
29
|
+
import { isRcsTextOnlyCardMediaType, resolveRcsCardPreviewStrings } from '../Rcs/utils';
|
|
28
30
|
import { getWhatsappContent } from '../Whatsapp/utils';
|
|
29
31
|
import * as commonUtil from '../../utils/common';
|
|
30
32
|
import Zalo from '../Zalo';
|
|
@@ -180,6 +182,8 @@ export function SlideBoxContent(props) {
|
|
|
180
182
|
isTestAndPreviewMode,
|
|
181
183
|
onHtmlEditorValidationStateChange,
|
|
182
184
|
} = props;
|
|
185
|
+
const localTemplatesConfig = props.localTemplatesConfig || pick(props, constants.LOCAL_TEMPLATE_CONFIG_KEYS);
|
|
186
|
+
const useLocalTemplates = !!get(localTemplatesConfig, 'useLocalTemplates');
|
|
183
187
|
const type = (messageDetails.type || '').toLowerCase(); // type is context in get tags values : outbound | dvs | referral | loyalty | coupons
|
|
184
188
|
const query = { type: !isFullMode && 'embedded', module: isFullMode ? 'default' : 'library', isEditFromCampaigns: (templateData || {}).isEditFromCampaigns};
|
|
185
189
|
const creativesLocationProps = {
|
|
@@ -399,12 +403,37 @@ export function SlideBoxContent(props) {
|
|
|
399
403
|
}
|
|
400
404
|
case constants.RCS: {
|
|
401
405
|
const template = cloneDeep(templateDataObject);
|
|
402
|
-
const
|
|
406
|
+
const cardPath = 'versions.base.content.RCS.rcsContent.cardContent[0]';
|
|
407
|
+
const card = get(template, cardPath, {}) || {};
|
|
408
|
+
const {
|
|
409
|
+
description = '',
|
|
410
|
+
media: { mediaUrl = '' } = {},
|
|
411
|
+
title = '',
|
|
412
|
+
mediaType: cardMediaType,
|
|
413
|
+
suggestions = [],
|
|
414
|
+
cardVarMapped: nestedCardVarMapped,
|
|
415
|
+
} = card;
|
|
416
|
+
const rootMirror = templateDataObject?.rcsCardVarMapped;
|
|
417
|
+
const nestedRecord =
|
|
418
|
+
nestedCardVarMapped != null && typeof nestedCardVarMapped === 'object'
|
|
419
|
+
? nestedCardVarMapped
|
|
420
|
+
: {};
|
|
421
|
+
const rootRecord =
|
|
422
|
+
rootMirror != null && typeof rootMirror === 'object' ? rootMirror : {};
|
|
423
|
+
const mergedCardVarMapped = { ...rootRecord, ...nestedRecord };
|
|
424
|
+
const textOnlyCard = isRcsTextOnlyCardMediaType(cardMediaType);
|
|
425
|
+
const { rcsTitle, rcsDesc } = resolveRcsCardPreviewStrings(
|
|
426
|
+
title,
|
|
427
|
+
description,
|
|
428
|
+
mergedCardVarMapped,
|
|
429
|
+
!isFullMode,
|
|
430
|
+
textOnlyCard,
|
|
431
|
+
);
|
|
403
432
|
return {
|
|
404
433
|
rcsPreviewContent: {
|
|
405
434
|
rcsImageSrc: mediaUrl,
|
|
406
|
-
rcsTitle
|
|
407
|
-
rcsDesc
|
|
435
|
+
rcsTitle,
|
|
436
|
+
rcsDesc,
|
|
408
437
|
...(suggestions.length > 0 && {
|
|
409
438
|
buttonText: suggestions[0]?.text,
|
|
410
439
|
}),
|
|
@@ -430,7 +459,7 @@ export function SlideBoxContent(props) {
|
|
|
430
459
|
|
|
431
460
|
return (
|
|
432
461
|
<CreativesWrapper>
|
|
433
|
-
{
|
|
462
|
+
{slidBoxContent === 'templates' && (!isFullMode || useLocalTemplates) && (
|
|
434
463
|
<TemplatesV2
|
|
435
464
|
isFullMode={isFullMode}
|
|
436
465
|
onSelectTemplate={onSelectTemplate}
|
|
@@ -463,6 +492,7 @@ export function SlideBoxContent(props) {
|
|
|
463
492
|
waitEventContextTags={waitEventContextTags}
|
|
464
493
|
loyaltyMetaData={loyaltyMetaData}
|
|
465
494
|
isLoyaltyModule={isLoyaltyModule}
|
|
495
|
+
localTemplatesConfig={localTemplatesConfig}
|
|
466
496
|
/>
|
|
467
497
|
)}
|
|
468
498
|
{isPreview && (
|
|
@@ -633,6 +663,7 @@ export function SlideBoxContent(props) {
|
|
|
633
663
|
route={{ name: 'sms' }}
|
|
634
664
|
isCreateSms={isCreateSms}
|
|
635
665
|
isComponent
|
|
666
|
+
templateData={templateData}
|
|
636
667
|
isGetFormData={isGetFormData}
|
|
637
668
|
getFormSubscriptionData={getFormData}
|
|
638
669
|
getLiquidTags={getLiquidTags}
|
|
@@ -1239,6 +1270,7 @@ export function SlideBoxContent(props) {
|
|
|
1239
1270
|
)}
|
|
1240
1271
|
{isCreateRcs && (<Rcs
|
|
1241
1272
|
{...rcsCommonProps}
|
|
1273
|
+
templateData={templateData}
|
|
1242
1274
|
showLiquidErrorInFooter={showLiquidErrorInFooter}
|
|
1243
1275
|
showTestAndPreviewSlidebox={showTestAndPreviewSlidebox}
|
|
1244
1276
|
handleTestAndPreview={handleTestAndPreview}
|
|
@@ -49,6 +49,8 @@ function SlideBoxFooter(props) {
|
|
|
49
49
|
isAnonymousType = false,
|
|
50
50
|
templateData = {},
|
|
51
51
|
hasPersonalizationTokenError: hasPersonalizationTokenErrorProp = false,
|
|
52
|
+
/** When set (e.g. SMS library create), overrides `creativesTemplatesSave` (“Done”) for the primary button */
|
|
53
|
+
primarySaveButtonMessage,
|
|
52
54
|
} = props;
|
|
53
55
|
// Calculate if buttons should be disabled
|
|
54
56
|
// Only apply validation state checks for EMAIL channel in HTML Editor mode (not BEE/DragDrop)
|
|
@@ -165,6 +167,12 @@ function SlideBoxFooter(props) {
|
|
|
165
167
|
// Use prop from parent (FormBuilder flow) when available; else fall back to templateData check
|
|
166
168
|
const hasPersonalizationTokenError = hasPersonalizationTokenErrorProp === true || (restrictPersonalization && hasPersonalizationTokens());
|
|
167
169
|
|
|
170
|
+
function getSaveButtonLabel() {
|
|
171
|
+
if (primarySaveButtonMessage) return <FormattedMessage {...primarySaveButtonMessage} />;
|
|
172
|
+
if (isFullMode) return getFullModeSaveBtn(slidBoxContent, isCreatingTemplate);
|
|
173
|
+
return <FormattedMessage {...messages.creativesTemplatesSave} />;
|
|
174
|
+
}
|
|
175
|
+
|
|
168
176
|
return (
|
|
169
177
|
<div className="template-footer-width">
|
|
170
178
|
{shouldShowErrorInfoNote && (
|
|
@@ -187,11 +195,7 @@ function SlideBoxFooter(props) {
|
|
|
187
195
|
onClick={onSave}
|
|
188
196
|
disabled={isTemplateNameEmpty || fetchingCmsData || shouldDisableButtons || hasPersonalizationTokenError}
|
|
189
197
|
>
|
|
190
|
-
{
|
|
191
|
-
getFullModeSaveBtn(slidBoxContent, isCreatingTemplate)
|
|
192
|
-
) : (
|
|
193
|
-
<FormattedMessage {...messages.creativesTemplatesSave} />
|
|
194
|
-
)}
|
|
198
|
+
{getSaveButtonLabel()}
|
|
195
199
|
</CapButton>
|
|
196
200
|
{showTestAndPreviewButton && (
|
|
197
201
|
<CapButton
|
|
@@ -264,6 +268,10 @@ SlideBoxFooter.propTypes = {
|
|
|
264
268
|
templateData: PropTypes.object,
|
|
265
269
|
formData: PropTypes.array,
|
|
266
270
|
hasPersonalizationTokenError: PropTypes.bool,
|
|
271
|
+
primarySaveButtonMessage: PropTypes.shape({
|
|
272
|
+
id: PropTypes.string,
|
|
273
|
+
defaultMessage: PropTypes.string,
|
|
274
|
+
}),
|
|
267
275
|
};
|
|
268
276
|
|
|
269
277
|
SlideBoxFooter.defaultProps = {
|
|
@@ -291,5 +299,6 @@ SlideBoxFooter.defaultProps = {
|
|
|
291
299
|
selectedEmailCreateMode: '',
|
|
292
300
|
formData: [],
|
|
293
301
|
hasPersonalizationTokenError: false,
|
|
302
|
+
primarySaveButtonMessage: undefined,
|
|
294
303
|
};
|
|
295
304
|
export default SlideBoxFooter;
|
|
@@ -16,6 +16,7 @@ import { isTraiDLTEnable } from '../../utils/common';
|
|
|
16
16
|
import { formatString } from '../../utils/Formatter';
|
|
17
17
|
import {
|
|
18
18
|
CAP_SPACE_12,
|
|
19
|
+
CAP_SPACE_16,
|
|
19
20
|
} from '@capillarytech/cap-ui-library/styled/variables';
|
|
20
21
|
import { WHATSAPP_HELP_DOC_LINK, JOURNEY } from './constants';
|
|
21
22
|
|
|
@@ -24,7 +25,7 @@ const StyledLabel = styled(CapLabelInline)`
|
|
|
24
25
|
margin-right: ${CAP_SPACE_12};
|
|
25
26
|
`;
|
|
26
27
|
const PrefixWrapper = styled.div`
|
|
27
|
-
margin-right:
|
|
28
|
+
margin-right: ${CAP_SPACE_16};
|
|
28
29
|
`;
|
|
29
30
|
const renderData = (type, value, channel) => (
|
|
30
31
|
<StyledLabel className={channel?.toLowerCase() === ZALO ? 'zalo-template-name-spacing' : ''} type={type}>
|
|
@@ -33,7 +34,25 @@ const renderData = (type, value, channel) => (
|
|
|
33
34
|
);
|
|
34
35
|
|
|
35
36
|
export function SlideBoxHeader(props) {
|
|
36
|
-
const {
|
|
37
|
+
const {
|
|
38
|
+
slidBoxContent,
|
|
39
|
+
templateData,
|
|
40
|
+
onShowTemplates,
|
|
41
|
+
creativesMode,
|
|
42
|
+
isFullMode,
|
|
43
|
+
showPrefix,
|
|
44
|
+
shouldShowTemplateName,
|
|
45
|
+
channel,
|
|
46
|
+
templateNameRenderProp,
|
|
47
|
+
weChatTemplateType,
|
|
48
|
+
onWeChatMaptemplateStepChange,
|
|
49
|
+
weChatMaptemplateStep,
|
|
50
|
+
templateStep,
|
|
51
|
+
smsRegister,
|
|
52
|
+
handleClose,
|
|
53
|
+
moduleType,
|
|
54
|
+
useLocalTemplates = false,
|
|
55
|
+
} = props;
|
|
37
56
|
const showTemplateNameHeader = isFullMode && shouldShowTemplateName;
|
|
38
57
|
const mapTemplateCreate = !showTemplateNameHeader && slidBoxContent === 'createTemplate' && weChatTemplateType === MAP_TEMPLATE && templateStep !== 'modeSelection';
|
|
39
58
|
const isTraiDlt = isTraiDLTEnable(isFullMode, smsRegister);
|
|
@@ -54,7 +73,7 @@ export function SlideBoxHeader(props) {
|
|
|
54
73
|
} = templateData || {};
|
|
55
74
|
const templateName = whatsappTemplateName || templateData?.name;
|
|
56
75
|
const showRcsTemplateName = channel.toLowerCase() === RCS && slidBoxContent === 'editTemplate' && !isFullMode && templateName;
|
|
57
|
-
const showTemplateName = isWhatsappEdit ||
|
|
76
|
+
const showTemplateName = isWhatsappEdit || isZaloEdit;
|
|
58
77
|
const whatsappCategory = whatsappTemplateCategory || get(templateData, `versions.base.content.whatsapp.category`, '');
|
|
59
78
|
const whatsappLanguageCode = whatsappTemplateLanguageCode || get(templateData, `versions.base.content.whatsapp.languages[0].language`, '');
|
|
60
79
|
|
|
@@ -81,6 +100,9 @@ export function SlideBoxHeader(props) {
|
|
|
81
100
|
window.open(WHATSAPP_HELP_DOC_LINK, '_blank');
|
|
82
101
|
};
|
|
83
102
|
|
|
103
|
+
const showCreativesTemplatesBackButton =
|
|
104
|
+
!isFullMode && (moduleType === JOURNEY || useLocalTemplates);
|
|
105
|
+
|
|
84
106
|
return (
|
|
85
107
|
<div key="creatives-container-slidebox-header-content">
|
|
86
108
|
{slidBoxContent === 'templates' && !showTemplateNameHeader && (
|
|
@@ -89,7 +111,7 @@ export function SlideBoxHeader(props) {
|
|
|
89
111
|
description={![NO_COMMUNICATION, FTP].includes(channel) &&
|
|
90
112
|
<FormattedMessage {...messages.creativeTemplatesDesc} />
|
|
91
113
|
}
|
|
92
|
-
prefix={
|
|
114
|
+
prefix={showCreativesTemplatesBackButton &&
|
|
93
115
|
<PrefixWrapper>
|
|
94
116
|
<CapIcons.backIcon onClick={handleClose} />
|
|
95
117
|
</PrefixWrapper>
|
|
@@ -123,6 +145,12 @@ export function SlideBoxHeader(props) {
|
|
|
123
145
|
<StyledLabel className='whatsapp-rcs-slidebox-template-name' type="label2">{templateName}</StyledLabel>
|
|
124
146
|
</>
|
|
125
147
|
) : ""}
|
|
148
|
+
{showRcsTemplateName && (
|
|
149
|
+
<>
|
|
150
|
+
{renderData("label1", <FormattedMessage {...globalMessages.creativeNameLabel} />, channel)}
|
|
151
|
+
<StyledLabel className='whatsapp-rcs-slidebox-template-name' type="label2">{templateName}</StyledLabel>
|
|
152
|
+
</>
|
|
153
|
+
)}
|
|
126
154
|
{isWhatsappEdit && (
|
|
127
155
|
<>
|
|
128
156
|
{renderData("label3", <FormattedMessage {...whatsppMsg.labelSeperator} />)}
|
|
@@ -135,7 +163,7 @@ export function SlideBoxHeader(props) {
|
|
|
135
163
|
}
|
|
136
164
|
</>
|
|
137
165
|
}
|
|
138
|
-
prefix={
|
|
166
|
+
prefix={!isFullMode && showPrefix &&
|
|
139
167
|
<PrefixWrapper>
|
|
140
168
|
<CapIcons.backIcon onClick={onShowTemplates} />
|
|
141
169
|
</PrefixWrapper>
|
|
@@ -191,5 +219,8 @@ SlideBoxHeader.propTypes = {
|
|
|
191
219
|
shouldShowTemplateName: PropTypes.bool,
|
|
192
220
|
templateNameRenderProp: PropTypes.func,
|
|
193
221
|
smsRegister: PropTypes.any,
|
|
222
|
+
handleClose: PropTypes.func,
|
|
223
|
+
moduleType: PropTypes.string,
|
|
224
|
+
useLocalTemplates: PropTypes.bool,
|
|
194
225
|
};
|
|
195
226
|
export default SlideBoxHeader;
|
|
@@ -67,3 +67,12 @@ export const ALLOWED_CHANNELS_FOR_ANONYMOUS = ['mobilepush', 'webpush'];
|
|
|
67
67
|
export const ALL_CHANNELS_NEW = [
|
|
68
68
|
'sms', 'email', 'whatsapp', 'facebook', 'line', 'viber', 'rcs', 'zalo', 'inapp', 'call_task', 'ftp',
|
|
69
69
|
];
|
|
70
|
+
|
|
71
|
+
export const LOCAL_TEMPLATE_CONFIG_KEYS = ['useLocalTemplates', 'localTemplates', 'localTemplatesLoading', 'localTemplatesFilterContent', 'localTemplatesUseSkeleton', 'localTemplatesOnPageChange'];
|
|
72
|
+
|
|
73
|
+
/** Keys passed from parents into `Templates` when using local SMS template list (extends `LOCAL_TEMPLATE_CONFIG_KEYS`). */
|
|
74
|
+
export const LOCAL_TEMPLATE_CONFIG_KEYS_FOR_PICK = [
|
|
75
|
+
...LOCAL_TEMPLATE_CONFIG_KEYS,
|
|
76
|
+
'localTemplatesLoadingTip',
|
|
77
|
+
'localTemplatesFooterContent',
|
|
78
|
+
];
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared logic for CreativesContainer slidebox + embedded flows (e.g. RCS SMS fallback)
|
|
3
|
+
* that mirror the same footer liquid errors and layout margins.
|
|
4
|
+
*/
|
|
5
|
+
import get from 'lodash/get';
|
|
6
|
+
import {
|
|
7
|
+
CAP_SPACE_32,
|
|
8
|
+
CAP_SPACE_56,
|
|
9
|
+
CAP_SPACE_64,
|
|
10
|
+
} from '@capillarytech/cap-ui-library/styled/variables';
|
|
11
|
+
import * as constants from './constants';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Returns true if value is "deep empty": no errors present.
|
|
15
|
+
* Same rules as CreativesContainer (used for liquid / standard error payloads).
|
|
16
|
+
*/
|
|
17
|
+
export function isDeepEmpty(value) {
|
|
18
|
+
if (value == null) return true;
|
|
19
|
+
if (typeof value === 'string') return value.length === 0;
|
|
20
|
+
if (Array.isArray(value)) return value.every(isDeepEmpty);
|
|
21
|
+
if (typeof value === 'object') {
|
|
22
|
+
return Object.values(value).every(isDeepEmpty);
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Header/content margin below slidebox chrome when ErrorInfoNote stacks errors — same formula as CreativesContainer#render.
|
|
29
|
+
*/
|
|
30
|
+
export function getSlideBoxWrapperMarginFromLiquidErrors(liquidErrorMessage) {
|
|
31
|
+
return (get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0
|
|
32
|
+
&& get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0)
|
|
33
|
+
? CAP_SPACE_64
|
|
34
|
+
: get(liquidErrorMessage, 'LIQUID_ERROR_MSG.length', 0) > 0
|
|
35
|
+
? CAP_SPACE_56
|
|
36
|
+
: get(liquidErrorMessage, 'STANDARD_ERROR_MSG.length', 0) > 0
|
|
37
|
+
? CAP_SPACE_32
|
|
38
|
+
: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Maps FormBuilder `showLiquidErrorInFooter` args to slidebox footer state.
|
|
43
|
+
* Returns `null` when CreativesContainer intentionally skips updating (Mobile Push OLD empty clear).
|
|
44
|
+
*/
|
|
45
|
+
export function computeLiquidFooterUpdateFromFormBuilder(
|
|
46
|
+
errorMessagesFromFormBuilder,
|
|
47
|
+
existingLiquidErrorMessageOrCurrentFormBuilderTab,
|
|
48
|
+
currentFormBuilderTabOrOptions,
|
|
49
|
+
maybeOptions,
|
|
50
|
+
) {
|
|
51
|
+
// Backward compatible signature handling:
|
|
52
|
+
// old: (errors, currentFormBuilderTab, options)
|
|
53
|
+
// new: (errors, existingLiquidErrorMessage, currentFormBuilderTab, options)
|
|
54
|
+
const hasExistingErrorMessageObject = existingLiquidErrorMessageOrCurrentFormBuilderTab
|
|
55
|
+
&& typeof existingLiquidErrorMessageOrCurrentFormBuilderTab === 'object'
|
|
56
|
+
&& !Array.isArray(existingLiquidErrorMessageOrCurrentFormBuilderTab);
|
|
57
|
+
const currentFormBuilderTab = hasExistingErrorMessageObject
|
|
58
|
+
? currentFormBuilderTabOrOptions
|
|
59
|
+
: existingLiquidErrorMessageOrCurrentFormBuilderTab;
|
|
60
|
+
const options = hasExistingErrorMessageObject ? maybeOptions : currentFormBuilderTabOrOptions;
|
|
61
|
+
const { previousIsLiquidValidationError, currentChannelUpper } = options || {};
|
|
62
|
+
const liquidMsgs = get(errorMessagesFromFormBuilder, constants.LIQUID_ERROR_MSG, []);
|
|
63
|
+
const standardMsgs = get(errorMessagesFromFormBuilder, constants.STANDARD_ERROR_MSG, []);
|
|
64
|
+
const hasLiquid = !isDeepEmpty(liquidMsgs);
|
|
65
|
+
const hasStandard = !isDeepEmpty(standardMsgs);
|
|
66
|
+
const isLiquidValidationError = hasLiquid || hasStandard;
|
|
67
|
+
const isMobilePush = currentChannelUpper === constants.MOBILE_PUSH;
|
|
68
|
+
if (!hasLiquid && !hasStandard && previousIsLiquidValidationError && isMobilePush) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
isLiquidValidationError,
|
|
73
|
+
liquidErrorMessage: errorMessagesFromFormBuilder,
|
|
74
|
+
activeFormBuilderTab:
|
|
75
|
+
currentFormBuilderTab === 1
|
|
76
|
+
? constants.ANDROID
|
|
77
|
+
: (currentFormBuilderTab === 2 ? constants.IOS : null),
|
|
78
|
+
};
|
|
79
|
+
}
|