@capillarytech/creatives-library 8.0.316 → 8.0.317-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/constants/unified.js +15 -0
- package/package.json +1 -1
- package/services/api.js +6 -0
- package/services/tests/api.test.js +7 -0
- package/utils/common.js +6 -1
- package/utils/templateVarUtils.js +172 -0
- package/utils/tests/tagValidations.test.js +34 -0
- package/utils/tests/templateVarUtils.test.js +160 -0
- package/v2Components/CapTagList/index.js +25 -22
- package/v2Components/CapTagList/style.scss +48 -0
- package/v2Components/CapTagListWithInput/__tests__/CapTagListWithInput.test.js +63 -0
- package/v2Components/CapTagListWithInput/index.js +4 -0
- package/v2Components/CapWhatsappCTA/index.js +2 -0
- package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +70 -49
- package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +8 -2
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +207 -21
- package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +16 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +85 -10
- package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +30 -0
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +79 -11
- package/v2Components/CommonTestAndPreview/SendTestMessage.js +11 -5
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +20 -1
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +133 -4
- package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +12 -0
- package/v2Components/CommonTestAndPreview/constants.js +38 -0
- package/v2Components/CommonTestAndPreview/index.js +693 -155
- package/v2Components/CommonTestAndPreview/messages.js +41 -3
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +59 -0
- package/v2Components/CommonTestAndPreview/sagas.js +15 -6
- package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +352 -0
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +269 -1
- 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/SendTestMessage.test.js +25 -4
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +199 -1
- package/v2Components/CommonTestAndPreview/tests/index.test.js +132 -4
- package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +67 -0
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +2 -2
- package/v2Components/FormBuilder/index.js +14 -1
- package/v2Components/HtmlEditor/HTMLEditor.js +6 -1
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +1 -0
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +927 -2
- package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +3 -0
- package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +87 -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 +107 -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 +197 -0
- package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +261 -0
- package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +422 -0
- package/v2Components/SmsFallback/useLocalTemplateList.js +92 -0
- package/v2Components/TestAndPreviewSlidebox/index.js +8 -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/BeeEditor/index.js +3 -0
- package/v2Containers/CommunicationFlow/CommunicationFlow.js +291 -0
- package/v2Containers/CommunicationFlow/CommunicationFlow.scss +25 -0
- package/v2Containers/CommunicationFlow/Tests/CommunicationFlow.test.js +255 -0
- package/v2Containers/CommunicationFlow/constants.js +200 -0
- package/v2Containers/CommunicationFlow/index.js +102 -0
- package/v2Containers/CommunicationFlow/messages.js +346 -0
- package/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/ChannelSelectionStep.js +522 -0
- package/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/ChannelSelectionStep.scss +170 -0
- package/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/Tests/ChannelSelectionStep.test.js +796 -0
- package/v2Containers/CommunicationFlow/steps/ChannelSelectionStep/index.js +5 -0
- package/v2Containers/CommunicationFlow/steps/CommunicationStrategyStep/CommunicationStrategyStep.js +95 -0
- package/v2Containers/CommunicationFlow/steps/CommunicationStrategyStep/Tests/CommunicationStrategyStep.test.js +133 -0
- package/v2Containers/CommunicationFlow/steps/CommunicationStrategyStep/index.js +5 -0
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/DeliverySettingsSection.js +289 -0
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/DeliverySettingsSection.scss +70 -0
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/SenderDetails.js +319 -0
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/SenderDetails.scss +69 -0
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/DeliverySettingsSection.test.js +616 -0
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js +577 -0
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/deliverySettingsConfig.test.js +1111 -0
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/deliverySettingsConfig.js +696 -0
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/index.js +7 -0
- package/v2Containers/CommunicationFlow/steps/DynamicControlsStep/DynamicControlsStep.js +102 -0
- package/v2Containers/CommunicationFlow/steps/DynamicControlsStep/DynamicControlsStep.scss +36 -0
- package/v2Containers/CommunicationFlow/steps/DynamicControlsStep/Tests/DynamicControlsStep.test.js +91 -0
- package/v2Containers/CommunicationFlow/steps/DynamicControlsStep/index.js +5 -0
- package/v2Containers/CommunicationFlow/steps/MessageTypeStep/MessageTypeStep.js +86 -0
- package/v2Containers/CommunicationFlow/steps/MessageTypeStep/Tests/MessageTypeStep.test.js +100 -0
- package/v2Containers/CommunicationFlow/steps/MessageTypeStep/index.js +5 -0
- package/v2Containers/CommunicationFlow/utils/getEnabledSteps.js +30 -0
- package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +43 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +64 -5
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +10 -1
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +29 -4
- package/v2Containers/CreativesContainer/constants.js +12 -0
- package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +67 -0
- package/v2Containers/CreativesContainer/index.js +289 -93
- package/v2Containers/CreativesContainer/index.scss +51 -1
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +90 -0
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +104 -0
- package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +110 -0
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +8 -0
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +363 -0
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +20 -10
- 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/Email/index.js +1 -0
- package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +7 -1
- package/v2Containers/EmailWrapper/components/EmailWrapperView.js +3 -0
- package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +20 -2
- package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +16 -1
- package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +3 -0
- package/v2Containers/EmailWrapper/index.js +4 -0
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +1 -0
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +9 -0
- package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +19 -0
- package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +3 -0
- package/v2Containers/InAppWrapper/index.js +3 -0
- package/v2Containers/MobilePush/Create/index.js +2 -0
- package/v2Containers/MobilePush/Edit/index.js +2 -0
- package/v2Containers/MobilepushWrapper/index.js +3 -1
- package/v2Containers/Rcs/constants.js +32 -1
- package/v2Containers/Rcs/index.js +951 -873
- package/v2Containers/Rcs/index.scss +85 -6
- package/v2Containers/Rcs/messages.js +10 -1
- package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +205 -0
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +40834 -1963
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +0 -5
- package/v2Containers/Rcs/tests/index.test.js +41 -38
- package/v2Containers/Rcs/tests/mockData.js +38 -0
- package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +251 -0
- package/v2Containers/Rcs/tests/utils.test.js +379 -1
- package/v2Containers/Rcs/utils.js +358 -10
- package/v2Containers/Sms/Create/index.js +83 -36
- package/v2Containers/Sms/Edit/index.js +2 -0
- 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 +611 -128
- package/v2Containers/SmsTrai/Edit/index.scss +121 -0
- package/v2Containers/SmsTrai/Edit/messages.js +9 -4
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4327 -2374
- package/v2Containers/SmsWrapper/index.js +39 -8
- package/v2Containers/TagList/index.js +47 -2
- package/v2Containers/TagList/messages.js +4 -0
- package/v2Containers/TagList/tests/TagList.test.js +122 -20
- package/v2Containers/TagList/tests/mockdata.js +17 -0
- package/v2Containers/Templates/TemplatesActionBar.js +101 -0
- package/v2Containers/Templates/_templates.scss +61 -2
- package/v2Containers/Templates/actions.js +11 -0
- package/v2Containers/Templates/constants.js +2 -0
- package/v2Containers/Templates/index.js +90 -40
- package/v2Containers/Templates/sagas.js +57 -12
- package/v2Containers/Templates/tests/TemplatesActionBar.test.js +120 -0
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1043 -1079
- package/v2Containers/Templates/tests/sagas.test.js +193 -12
- 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/Viber/index.js +5 -0
- package/v2Containers/WebPush/Create/hooks/useTagManagement.js +0 -2
- package/v2Containers/WebPush/Create/index.js +9 -1
- package/v2Containers/Whatsapp/index.js +8 -20
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +598 -34
- package/v2Containers/Zalo/index.js +2 -0
|
@@ -10,12 +10,14 @@ import { isTraiDLTEnable } from '../../utils/common';
|
|
|
10
10
|
import SmsEdit from '../Sms/Edit';
|
|
11
11
|
import SmsTraiCreate from '../SmsTrai/Create';
|
|
12
12
|
import SmsTraiEdit from '../SmsTrai/Edit';
|
|
13
|
+
|
|
13
14
|
const SmsWrapper = (props) => {
|
|
14
15
|
const {
|
|
15
16
|
isCreateSms,
|
|
16
17
|
isEditSms,
|
|
17
18
|
setIsLoadingContent,
|
|
18
19
|
location,
|
|
20
|
+
route: routeFromProps,
|
|
19
21
|
isGetFormData,
|
|
20
22
|
getFormSubscriptionData,
|
|
21
23
|
isFullMode,
|
|
@@ -30,6 +32,7 @@ const SmsWrapper = (props) => {
|
|
|
30
32
|
smsRegister,
|
|
31
33
|
onShowTemplates,
|
|
32
34
|
eventContextTags,
|
|
35
|
+
waitEventContextTags,
|
|
33
36
|
showLiquidErrorInFooter,
|
|
34
37
|
getLiquidTags,
|
|
35
38
|
showTestAndPreviewSlidebox,
|
|
@@ -37,15 +40,33 @@ const SmsWrapper = (props) => {
|
|
|
37
40
|
handleCloseTestAndPreview,
|
|
38
41
|
isTestAndPreviewMode,
|
|
39
42
|
onValidationFail,
|
|
43
|
+
embeddedSmsFallback = false,
|
|
44
|
+
onEmbeddedSmsFooterValidity,
|
|
45
|
+
forceFullTagContext = false,
|
|
40
46
|
} = props;
|
|
41
47
|
|
|
48
|
+
/** FormBuilder / SMS Create assume `location.query`; connected-router shapes may omit it. */
|
|
49
|
+
const smsLocation = (() => {
|
|
50
|
+
const loc = location || {};
|
|
51
|
+
const q = loc.query;
|
|
52
|
+
if (q && typeof q === 'object') {
|
|
53
|
+
return { ...loc, query: { ...q } };
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
pathname: loc.pathname || '/sms/create',
|
|
57
|
+
search: loc.search || '',
|
|
58
|
+
query: { type: 'embedded', module: 'library' },
|
|
59
|
+
};
|
|
60
|
+
})();
|
|
61
|
+
|
|
42
62
|
const smsProps = {
|
|
43
63
|
onCreateComplete,
|
|
44
64
|
setIsLoadingContent,
|
|
45
|
-
location,
|
|
46
|
-
route: { name: 'sms' },
|
|
65
|
+
location: smsLocation,
|
|
66
|
+
route: routeFromProps || { name: 'sms' },
|
|
47
67
|
isGetFormData,
|
|
48
68
|
getFormSubscriptionData,
|
|
69
|
+
templateData,
|
|
49
70
|
getDefaultTags,
|
|
50
71
|
isFullMode,
|
|
51
72
|
forwardedTags,
|
|
@@ -53,6 +74,7 @@ const SmsWrapper = (props) => {
|
|
|
53
74
|
onPreviewContentClicked,
|
|
54
75
|
onTestContentClicked,
|
|
55
76
|
eventContextTags,
|
|
77
|
+
waitEventContextTags,
|
|
56
78
|
showLiquidErrorInFooter,
|
|
57
79
|
getLiquidTags,
|
|
58
80
|
showTestAndPreviewSlidebox,
|
|
@@ -60,24 +82,33 @@ const SmsWrapper = (props) => {
|
|
|
60
82
|
handleCloseTestAndPreview,
|
|
61
83
|
isTestAndPreviewMode,
|
|
62
84
|
onValidationFail,
|
|
85
|
+
forceFullTagContext,
|
|
86
|
+
embeddedSmsFallback,
|
|
87
|
+
onEmbeddedSmsFooterValidity,
|
|
88
|
+
...(embeddedSmsFallback
|
|
89
|
+
? {
|
|
90
|
+
tagListGetPopupContainer: () => document.body,
|
|
91
|
+
tagListPopoverOverlayStyle: { zIndex: 10020 },
|
|
92
|
+
tagListPopoverOverlayClassName: 'sms-fallback-taglist-popover rcs-sms-fallback-taglist-popover',
|
|
93
|
+
}
|
|
94
|
+
: {}),
|
|
63
95
|
};
|
|
64
|
-
const
|
|
96
|
+
const useTraiSmsFlow = isTraiDLTEnable(isFullMode, smsRegister);
|
|
65
97
|
return <>
|
|
66
98
|
{
|
|
67
|
-
isCreateSms && (
|
|
99
|
+
isCreateSms && (useTraiSmsFlow ?
|
|
68
100
|
<SmsTraiCreate
|
|
69
101
|
isComponent
|
|
70
102
|
{...smsProps}
|
|
71
103
|
onShowTemplates={onShowTemplates}
|
|
72
104
|
/> :
|
|
73
105
|
<SmsCreate
|
|
74
|
-
isComponent
|
|
75
|
-
|
|
76
|
-
}
|
|
106
|
+
isComponent
|
|
107
|
+
{...smsProps}
|
|
77
108
|
/>
|
|
78
109
|
)
|
|
79
110
|
}
|
|
80
|
-
{isEditSms && (
|
|
111
|
+
{isEditSms && (useTraiSmsFlow ?
|
|
81
112
|
<SmsTraiEdit
|
|
82
113
|
{...smsProps}
|
|
83
114
|
params={{id: templateData._id}}
|
|
@@ -167,7 +167,7 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
167
167
|
let injectedTags = {};
|
|
168
168
|
const eventContextTagsObj = {};
|
|
169
169
|
|
|
170
|
-
const {selectedOfferDetails, eventContextTags } = props;
|
|
170
|
+
const {selectedOfferDetails, eventContextTags, waitEventContextTags } = props;
|
|
171
171
|
if (props.injectedTags && !_.isEmpty(props.injectedTags)) {
|
|
172
172
|
const formattedInjectedTags = handleInjectedData(
|
|
173
173
|
props.injectedTags,
|
|
@@ -219,6 +219,43 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
219
219
|
};
|
|
220
220
|
});
|
|
221
221
|
}
|
|
222
|
+
// Wait event context tags should be displayed in the Add Labels when node is next to Event based wait node.
|
|
223
|
+
if (waitEventContextTags && Object.keys(waitEventContextTags)?.length) {
|
|
224
|
+
|
|
225
|
+
Object.keys(waitEventContextTags).forEach((blockId) => {
|
|
226
|
+
const WAIT_EVENT_HEADER_MSG_LABEL = `${waitEventContextTags[blockId].eventName} (${waitEventContextTags[blockId].blockName})`;
|
|
227
|
+
eventContextTagsObj[blockId] = {
|
|
228
|
+
"name": WAIT_EVENT_HEADER_MSG_LABEL,
|
|
229
|
+
"desc": WAIT_EVENT_HEADER_MSG_LABEL,
|
|
230
|
+
"resolved": true,
|
|
231
|
+
'tag-header': true,
|
|
232
|
+
"subtags": {},
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
waitEventContextTags?.[blockId]?.tags?.forEach((tag) => {
|
|
236
|
+
const {
|
|
237
|
+
tagName, label, profileId, profileName, blockName, eventName
|
|
238
|
+
} = tag || {};
|
|
239
|
+
if (!profileId || !tagName || !label || !profileName) return;
|
|
240
|
+
// Initializing the tags profile if it doesn't exist
|
|
241
|
+
if (!eventContextTagsObj?.[blockId]?.subtags?.[profileId]) {
|
|
242
|
+
eventContextTagsObj[blockId].subtags[profileId] = {
|
|
243
|
+
"name": profileName,
|
|
244
|
+
"desc": profileName,
|
|
245
|
+
"resolved": true,
|
|
246
|
+
'tag-header': true,
|
|
247
|
+
"subtags": {},
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
// Adding the current tag to the profile group
|
|
251
|
+
eventContextTagsObj[blockId].subtags[profileId].subtags[tagName] = {
|
|
252
|
+
name: label,
|
|
253
|
+
desc: label,
|
|
254
|
+
resolved: true,
|
|
255
|
+
};
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
}
|
|
222
259
|
this.setState({tags: _.merge( {}, tags, injectedTags, eventContextTagsObj )});
|
|
223
260
|
}
|
|
224
261
|
|
|
@@ -406,7 +443,7 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
406
443
|
isDisabled = true;
|
|
407
444
|
tooltipMsg = intl.formatMessage(messages.personalizationNotSupportedAnonymous);
|
|
408
445
|
}
|
|
409
|
-
|
|
446
|
+
|
|
410
447
|
return (
|
|
411
448
|
<div className={this.props.className ? this.props.className : ''}>
|
|
412
449
|
<CapTagList
|
|
@@ -427,6 +464,9 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
427
464
|
disableTooltipMsg={tooltipMsg}
|
|
428
465
|
fetchingSchemaError={this?.state?.tagsError}
|
|
429
466
|
popoverPlacement={this.props.popoverPlacement}
|
|
467
|
+
overlayStyle={this.props.popoverOverlayStyle}
|
|
468
|
+
overlayClassName={this.props.popoverOverlayClassName}
|
|
469
|
+
getPopupContainer={this.props.getPopupContainer}
|
|
430
470
|
/>
|
|
431
471
|
</div>
|
|
432
472
|
);
|
|
@@ -437,6 +477,7 @@ TagList.defaultProps = {
|
|
|
437
477
|
isNewVersionFlow: false,
|
|
438
478
|
userLocale: 'en',
|
|
439
479
|
eventContextTags: [],
|
|
480
|
+
waitEventContextTags: {},
|
|
440
481
|
};
|
|
441
482
|
|
|
442
483
|
TagList.propTypes = {
|
|
@@ -457,10 +498,14 @@ TagList.propTypes = {
|
|
|
457
498
|
disabled: PropTypes.bool,
|
|
458
499
|
fetchingSchemaError: PropTypes.bool,
|
|
459
500
|
eventContextTags: PropTypes.array,
|
|
501
|
+
waitEventContextTags: PropTypes.object,
|
|
460
502
|
popoverPlacement: PropTypes.string,
|
|
461
503
|
// message to show when Add Label button is disabled (e.g. personalization restriction)
|
|
462
504
|
disableTooltipMsg: PropTypes.string,
|
|
463
505
|
restrictPersonalization: PropTypes.bool,
|
|
506
|
+
popoverOverlayStyle: PropTypes.object,
|
|
507
|
+
popoverOverlayClassName: PropTypes.string,
|
|
508
|
+
getPopupContainer: PropTypes.func,
|
|
464
509
|
intl: PropTypes.shape({
|
|
465
510
|
formatMessage: PropTypes.func.isRequired,
|
|
466
511
|
locale: PropTypes.string,
|
|
@@ -19,4 +19,8 @@ export default defineMessages({
|
|
|
19
19
|
id: `${scope}.personalizationNotSupportedAnonymous`,
|
|
20
20
|
defaultMessage: 'Personalization tags are not supported for anonymous customers',
|
|
21
21
|
},
|
|
22
|
+
waitEvent: {
|
|
23
|
+
id: `${scope}.waitEvent`,
|
|
24
|
+
defaultMessage: 'Wait Event',
|
|
25
|
+
},
|
|
22
26
|
});
|
|
@@ -5,28 +5,34 @@ import { initialReducer } from '../../../initialReducer';
|
|
|
5
5
|
import { injectIntl } from "react-intl";
|
|
6
6
|
import { fireEvent } from "@testing-library/react";
|
|
7
7
|
import { TagList } from '../index';
|
|
8
|
-
import { TagListData, eventContextTags } from './mockdata';
|
|
8
|
+
import { TagListData, eventContextTags, waitEventContextTags } from './mockdata';
|
|
9
|
+
import { OfferTag, badgesTags, offer } from '../../../utils/tests/common.mockdata';
|
|
10
|
+
import * as commonUtils from "../../../utils/common";
|
|
9
11
|
import { Provider } from 'react-redux';
|
|
10
12
|
import { screen, render } from '../../../utils/test-utils';
|
|
11
13
|
import history from '../../../utils/history';
|
|
12
14
|
const { getByText, queryByText } = screen;
|
|
13
15
|
|
|
16
|
+
const buildProps = (props = {}) => ({
|
|
17
|
+
...TagListData,
|
|
18
|
+
onTagSelect: jest.fn(),
|
|
19
|
+
...props,
|
|
20
|
+
});
|
|
14
21
|
|
|
15
|
-
const initializeTagList = (props) => {
|
|
22
|
+
const initializeTagList = (props = {}) => {
|
|
16
23
|
const store = configureStore({}, initialReducer, history);
|
|
17
24
|
const Component = injectIntl(TagList);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
...
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
const propsObj = buildProps(props);
|
|
26
|
+
return {
|
|
27
|
+
...render(
|
|
28
|
+
<Provider store={store}>
|
|
29
|
+
<Component {...propsObj} />
|
|
30
|
+
</Provider>
|
|
31
|
+
),
|
|
32
|
+
store,
|
|
33
|
+
Component,
|
|
34
|
+
propsObj,
|
|
23
35
|
};
|
|
24
|
-
|
|
25
|
-
return render(
|
|
26
|
-
<Provider store={store}>
|
|
27
|
-
<Component {...propsObj} />
|
|
28
|
-
</Provider>
|
|
29
|
-
);
|
|
30
36
|
};
|
|
31
37
|
|
|
32
38
|
const addLabelBtnAssertion = () => {
|
|
@@ -41,19 +47,115 @@ describe("TagList test : UNIT", () => {
|
|
|
41
47
|
addLabelBtnAssertion();
|
|
42
48
|
});
|
|
43
49
|
|
|
44
|
-
it('should render event context
|
|
45
|
-
initializeTagList({eventContextTags});
|
|
50
|
+
it('should render event context tag section from generateTags', () => {
|
|
51
|
+
initializeTagList({ eventContextTags, moduleFilterEnabled: false });
|
|
46
52
|
addLabelBtnAssertion();
|
|
47
53
|
const EVENT_CONTEXT_TAG_HEADER = getByText(/Entry event/i);
|
|
48
54
|
expect(EVENT_CONTEXT_TAG_HEADER).toBeInTheDocument();
|
|
49
|
-
fireEvent.click(EVENT_CONTEXT_TAG_HEADER);
|
|
50
|
-
// Customer profile tags
|
|
51
|
-
const CUSTOMER_PROFILE = getByText(/Current Customer/i);
|
|
52
|
-
fireEvent.click(CUSTOMER_PROFILE);
|
|
53
|
-
expect(getByText(/lifetimePurchases/i)).toBeInTheDocument();
|
|
54
55
|
|
|
55
56
|
// Behavioural event profile tags should not be visible as label and profile name is not present
|
|
56
57
|
const BEHAVIOURAL_EVENT_PROFILE = queryByText(/Behavioural event/i);
|
|
57
58
|
expect(BEHAVIOURAL_EVENT_PROFILE).not.toBeInTheDocument();
|
|
58
59
|
});
|
|
60
|
+
|
|
61
|
+
it('should render wait event context section when waitEventContextTags is provided', () => {
|
|
62
|
+
initializeTagList({ waitEventContextTags, moduleFilterEnabled: false });
|
|
63
|
+
addLabelBtnAssertion();
|
|
64
|
+
const WAIT_EVENT_HEADER = getByText(/Order Placed \(Wait Block\)/i);
|
|
65
|
+
expect(WAIT_EVENT_HEADER).toBeInTheDocument();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should merge empty waitEventContextTags with entry event tags', () => {
|
|
69
|
+
initializeTagList({ eventContextTags, waitEventContextTags: {}, moduleFilterEnabled: false });
|
|
70
|
+
addLabelBtnAssertion();
|
|
71
|
+
expect(getByText(/Entry event/i)).toBeInTheDocument();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('calls parent onContextChange with Outbound when tags and injectedTags are empty on mount', () => {
|
|
75
|
+
const onContextChange = jest.fn();
|
|
76
|
+
initializeTagList({
|
|
77
|
+
tags: [],
|
|
78
|
+
injectedTags: {},
|
|
79
|
+
onContextChange,
|
|
80
|
+
onTagSelect: jest.fn(),
|
|
81
|
+
});
|
|
82
|
+
expect(onContextChange).toHaveBeenCalledWith('Outbound');
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('applies fetchingSchemaError from props via componentWillReceiveProps', () => {
|
|
86
|
+
const { rerender, Component, propsObj, store } = initializeTagList({ fetchingSchemaError: false });
|
|
87
|
+
addLabelBtnAssertion();
|
|
88
|
+
rerender(
|
|
89
|
+
<Provider store={store}>
|
|
90
|
+
<Component {...propsObj} fetchingSchemaError />
|
|
91
|
+
</Provider>
|
|
92
|
+
);
|
|
93
|
+
expect(screen.getByText(/add label/i)).toBeInTheDocument();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('disables Add label when restrictPersonalization is true', () => {
|
|
97
|
+
initializeTagList({
|
|
98
|
+
restrictPersonalization: true,
|
|
99
|
+
disabled: false,
|
|
100
|
+
moduleFilterEnabled: false,
|
|
101
|
+
});
|
|
102
|
+
const btn = screen.getByText(/add label/i).closest('button');
|
|
103
|
+
expect(btn).toBeDisabled();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('calls transformCouponTags when selectedOfferDetails and coupon tags are present', () => {
|
|
107
|
+
const spy = jest.spyOn(TagList.prototype, 'transformCouponTags');
|
|
108
|
+
initializeTagList({
|
|
109
|
+
tags: OfferTag,
|
|
110
|
+
injectedTags: {},
|
|
111
|
+
selectedOfferDetails: [{ id: 'c1', couponName: 'Promo Coupon', couponSeriesId: 'c1' }],
|
|
112
|
+
moduleFilterEnabled: false,
|
|
113
|
+
});
|
|
114
|
+
expect(spy).toHaveBeenCalled();
|
|
115
|
+
spy.mockRestore();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('calls transformBadgeTags from common when badge offer and Badge tags are present', () => {
|
|
119
|
+
const spy = jest.spyOn(commonUtils, 'transformBadgeTags');
|
|
120
|
+
initializeTagList({
|
|
121
|
+
tags: badgesTags,
|
|
122
|
+
injectedTags: {},
|
|
123
|
+
selectedOfferDetails: offer,
|
|
124
|
+
moduleFilterEnabled: false,
|
|
125
|
+
});
|
|
126
|
+
expect(spy).toHaveBeenCalled();
|
|
127
|
+
spy.mockRestore();
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it('unmounts without throwing', () => {
|
|
131
|
+
const { unmount } = initializeTagList();
|
|
132
|
+
expect(() => unmount()).not.toThrow();
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('regenerates tags when props.tags change (componentDidUpdate)', () => {
|
|
136
|
+
const { rerender, Component, store } = initializeTagList({ tags: TagListData.tags });
|
|
137
|
+
const extra = [
|
|
138
|
+
...TagListData.tags,
|
|
139
|
+
{
|
|
140
|
+
_id: 'extra-tag',
|
|
141
|
+
type: 'TAG',
|
|
142
|
+
definition: {
|
|
143
|
+
label: { en: 'Extra' },
|
|
144
|
+
value: 'extra_value',
|
|
145
|
+
subtags: [],
|
|
146
|
+
'tag-header': false,
|
|
147
|
+
supportedModules: [{ context: 'default', layout: 'sms', mandatory: false }],
|
|
148
|
+
},
|
|
149
|
+
scope: { tag: 'STANDARD', orgId: -1, verticals: [] },
|
|
150
|
+
isActive: true,
|
|
151
|
+
},
|
|
152
|
+
];
|
|
153
|
+
rerender(
|
|
154
|
+
<Provider store={store}>
|
|
155
|
+
<Component {...buildProps({ tags: extra })} />
|
|
156
|
+
</Provider>
|
|
157
|
+
);
|
|
158
|
+
addLabelBtnAssertion();
|
|
159
|
+
expect(screen.getByText(/add label/i)).toBeInTheDocument();
|
|
160
|
+
});
|
|
59
161
|
});
|
|
@@ -149,3 +149,20 @@ export const eventContextTags = [
|
|
|
149
149
|
"isDynamicFact": false
|
|
150
150
|
}
|
|
151
151
|
];
|
|
152
|
+
|
|
153
|
+
export const waitEventContextTags = {
|
|
154
|
+
block1: {
|
|
155
|
+
eventName: 'Order Placed',
|
|
156
|
+
blockName: 'Wait Block',
|
|
157
|
+
tags: [
|
|
158
|
+
{
|
|
159
|
+
tagName: 'waitEvent.orderId',
|
|
160
|
+
label: 'Order ID',
|
|
161
|
+
profileId: 'ORDER_PROFILE',
|
|
162
|
+
profileName: 'Order Profile',
|
|
163
|
+
blockName: 'Wait Block',
|
|
164
|
+
eventName: 'Order Placed',
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import CapInput from '@capillarytech/cap-ui-library/CapInput';
|
|
4
|
+
import CapButton from '@capillarytech/cap-ui-library/CapButton';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Reusable action bar for template pickers.
|
|
8
|
+
* Layout and spacing live in `_templates.scss` (`.action-container`, `.action-container__toolbar-row`).
|
|
9
|
+
* Default search field width: `.action-container__toolbar-row .search-text` (13.125rem).
|
|
10
|
+
* Pass `searchInputClassName` / `searchInputStyle` to override (defaults match Templates list: 210px per master).
|
|
11
|
+
*/
|
|
12
|
+
const TemplatesActionBar = ({
|
|
13
|
+
searchValue,
|
|
14
|
+
onSearchChange,
|
|
15
|
+
onSearch,
|
|
16
|
+
onClear,
|
|
17
|
+
searchPlaceholder,
|
|
18
|
+
searchInputClassName,
|
|
19
|
+
searchInputStyle,
|
|
20
|
+
ctaLabel,
|
|
21
|
+
onCtaClick,
|
|
22
|
+
ctaDisabled,
|
|
23
|
+
ctaClassName,
|
|
24
|
+
ctaNode,
|
|
25
|
+
children,
|
|
26
|
+
showCta = true,
|
|
27
|
+
}) => (
|
|
28
|
+
<div className="action-container">
|
|
29
|
+
<div className="action-container__toolbar-row">
|
|
30
|
+
{searchPlaceholder && (
|
|
31
|
+
<CapInput.Search
|
|
32
|
+
className={['search-text', searchInputClassName].filter(Boolean).join(' ')}
|
|
33
|
+
placeholder={searchPlaceholder}
|
|
34
|
+
value={searchValue}
|
|
35
|
+
onChange={onSearchChange}
|
|
36
|
+
/* antd `Input` (used by CapInput.Search) has no `onSearch`; only `Input.Search` does. */
|
|
37
|
+
onPressEnter={(e) => {
|
|
38
|
+
if (onSearch) {
|
|
39
|
+
const v = e?.target && 'value' in e.target ? e.target.value : searchValue;
|
|
40
|
+
onSearch(v);
|
|
41
|
+
}
|
|
42
|
+
}}
|
|
43
|
+
onSearch={onSearch}
|
|
44
|
+
onClear={onClear}
|
|
45
|
+
onScroll={(e) => e.stopPropagation()}
|
|
46
|
+
/>
|
|
47
|
+
)}
|
|
48
|
+
{children}
|
|
49
|
+
</div>
|
|
50
|
+
{showCta && (
|
|
51
|
+
<div>
|
|
52
|
+
{ctaNode || (
|
|
53
|
+
<CapButton
|
|
54
|
+
className={ctaClassName}
|
|
55
|
+
type="primary"
|
|
56
|
+
disabled={ctaDisabled}
|
|
57
|
+
onClick={onCtaClick}
|
|
58
|
+
>
|
|
59
|
+
{ctaLabel}
|
|
60
|
+
</CapButton>
|
|
61
|
+
)}
|
|
62
|
+
</div>
|
|
63
|
+
)}
|
|
64
|
+
</div>
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
TemplatesActionBar.propTypes = {
|
|
68
|
+
searchValue: PropTypes.string,
|
|
69
|
+
onSearchChange: PropTypes.func,
|
|
70
|
+
onSearch: PropTypes.func,
|
|
71
|
+
onClear: PropTypes.func,
|
|
72
|
+
searchPlaceholder: PropTypes.string,
|
|
73
|
+
searchInputClassName: PropTypes.string,
|
|
74
|
+
searchInputStyle: PropTypes.object,
|
|
75
|
+
ctaLabel: PropTypes.node,
|
|
76
|
+
onCtaClick: PropTypes.func,
|
|
77
|
+
ctaDisabled: PropTypes.bool,
|
|
78
|
+
ctaClassName: PropTypes.string,
|
|
79
|
+
ctaNode: PropTypes.node,
|
|
80
|
+
children: PropTypes.node,
|
|
81
|
+
showCta: PropTypes.bool,
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
TemplatesActionBar.defaultProps = {
|
|
85
|
+
searchValue: '',
|
|
86
|
+
onSearchChange: () => {},
|
|
87
|
+
onSearch: () => {},
|
|
88
|
+
onClear: () => {},
|
|
89
|
+
searchPlaceholder: '',
|
|
90
|
+
searchInputClassName: '',
|
|
91
|
+
searchInputStyle: { width: '210px' },
|
|
92
|
+
ctaLabel: null,
|
|
93
|
+
onCtaClick: () => {},
|
|
94
|
+
ctaDisabled: false,
|
|
95
|
+
ctaClassName: '',
|
|
96
|
+
ctaNode: null,
|
|
97
|
+
children: null,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export default TemplatesActionBar;
|
|
101
|
+
|
|
@@ -659,11 +659,27 @@
|
|
|
659
659
|
}
|
|
660
660
|
|
|
661
661
|
.action-container{
|
|
662
|
-
margin-top:
|
|
663
|
-
margin-bottom:
|
|
662
|
+
margin-top: $CAP_SPACE_08;
|
|
663
|
+
margin-bottom: $CAP_SPACE_16;
|
|
664
664
|
display: flex;
|
|
665
665
|
justify-content: space-between;
|
|
666
666
|
align-items: center;
|
|
667
|
+
|
|
668
|
+
&__toolbar-row {
|
|
669
|
+
display: flex;
|
|
670
|
+
align-items: center;
|
|
671
|
+
gap: 0.75rem;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
&__toolbar-row .search-text {
|
|
675
|
+
width: 13.125rem;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
&__create-row {
|
|
679
|
+
display: flex;
|
|
680
|
+
justify-content: space-between;
|
|
681
|
+
align-items: center;
|
|
682
|
+
}
|
|
667
683
|
}
|
|
668
684
|
|
|
669
685
|
.popover-action-container:hover{
|
|
@@ -1101,4 +1117,47 @@
|
|
|
1101
1117
|
.inapp-illustration-parent {
|
|
1102
1118
|
height: "calc(100vh - 325px)";
|
|
1103
1119
|
overflow: 'auto';
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
/* Local SMS / slidebox: viewport-based .v2-pagination-container-half height leaves empty space below and clips cards */
|
|
1123
|
+
.creatives-templates-container--local-sms.library-mode {
|
|
1124
|
+
.creatives-templates-list.library-mode > .cap-row:first-of-type > div {
|
|
1125
|
+
display: flex;
|
|
1126
|
+
flex-direction: column;
|
|
1127
|
+
flex: 1 1 auto;
|
|
1128
|
+
min-height: 0;
|
|
1129
|
+
overflow: hidden;
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
.creatives-templates-list.library-mode > .cap-row:first-of-type > div > div:first-child {
|
|
1133
|
+
display: flex;
|
|
1134
|
+
flex-direction: column;
|
|
1135
|
+
flex: 1 1 auto;
|
|
1136
|
+
min-height: 0;
|
|
1137
|
+
overflow: hidden;
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
/* Block below search/filter: grid + skeletons — must grow to use space above footer */
|
|
1141
|
+
.creatives-templates-list.library-mode > .cap-row:first-of-type > div > div:first-child > div:nth-child(2) {
|
|
1142
|
+
flex: 1 1 auto;
|
|
1143
|
+
min-height: 0;
|
|
1144
|
+
display: flex;
|
|
1145
|
+
flex-direction: column;
|
|
1146
|
+
overflow: hidden;
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
/*
|
|
1150
|
+
* Scroll needs a definite height. Pure flex + height:auto + max-height:100% often won’t bound (no % base), so no scrollbar.
|
|
1151
|
+
* Use a taller slice than global 100vh-20rem so the grid uses space under search; still overflow-y:auto for long lists.
|
|
1152
|
+
*/
|
|
1153
|
+
.v2-pagination-container,
|
|
1154
|
+
.v2-pagination-container-half {
|
|
1155
|
+
flex: 0 1 auto;
|
|
1156
|
+
min-height: 0;
|
|
1157
|
+
height: calc(100vh - 12rem);
|
|
1158
|
+
max-height: calc(100vh - 12rem);
|
|
1159
|
+
overflow-y: auto;
|
|
1160
|
+
overflow-x: hidden;
|
|
1161
|
+
-webkit-overflow-scrolling: touch;
|
|
1162
|
+
}
|
|
1104
1163
|
}
|
|
@@ -15,6 +15,17 @@ export function getAllTemplates(channel, queryParams, intlCopyOf = '') {
|
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
|
|
19
|
+
export function getLocalSmsTemplates(queryParams, intlCopyOf = '', onSuccess, onFailure) {
|
|
20
|
+
return {
|
|
21
|
+
type: types.GET_LOCAL_SMS_TEMPLATES_REQUEST,
|
|
22
|
+
queryParams,
|
|
23
|
+
intlCopyOf,
|
|
24
|
+
onSuccess,
|
|
25
|
+
onFailure,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
18
29
|
export function resetTemplate() {
|
|
19
30
|
return {
|
|
20
31
|
type: types.RESET_TEMPLATE,
|
|
@@ -10,6 +10,8 @@ export const GET_ALL_TEMPLATES_REQUEST = 'app/v2Containers/Templates/GET_ALL_TEM
|
|
|
10
10
|
export const GET_ALL_TEMPLATES_SUCCESS = 'app/v2Containers/Templates/GET_ALL_TEMPLATES_SUCCESS';
|
|
11
11
|
export const GET_ALL_TEMPLATES_FAILURE = 'app/v2Containers/Templates/GET_ALL_TEMPLATES_FAILURE';
|
|
12
12
|
|
|
13
|
+
export const GET_LOCAL_SMS_TEMPLATES_REQUEST = 'app/v2Containers/Templates/GET_LOCAL_SMS_TEMPLATES_REQUEST';
|
|
14
|
+
|
|
13
15
|
export const DELETE_TEMPLATE_REQUEST = 'app/v2Containers/Templates/DELETE_TEMPLATE_REQUEST';
|
|
14
16
|
export const DELETE_RCS_TEMPLATE_REQUEST = 'app/v2Containers/Templates/DELETE_RCS_TEMPLATE_REQUEST';
|
|
15
17
|
export const DELETE_TEMPLATE_SUCCESS = 'app/v2Containers/Templates/DELETE_TEMPLATE_SUCCESS';
|