@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
|
@@ -2281,6 +2281,7 @@ new message content.",
|
|
|
2281
2281
|
"email": [Function],
|
|
2282
2282
|
"facebookPreview": [Function],
|
|
2283
2283
|
"gallery": [Function],
|
|
2284
|
+
"inApp": [Function],
|
|
2284
2285
|
"language": [Function],
|
|
2285
2286
|
"navigationConfig": [Function],
|
|
2286
2287
|
"previewAndTest": [Function],
|
|
@@ -18313,6 +18314,7 @@ new message content.",
|
|
|
18313
18314
|
"email": [Function],
|
|
18314
18315
|
"facebookPreview": [Function],
|
|
18315
18316
|
"gallery": [Function],
|
|
18317
|
+
"inApp": [Function],
|
|
18316
18318
|
"language": [Function],
|
|
18317
18319
|
"navigationConfig": [Function],
|
|
18318
18320
|
"previewAndTest": [Function],
|
|
@@ -34345,6 +34347,7 @@ new message content.",
|
|
|
34345
34347
|
"email": [Function],
|
|
34346
34348
|
"facebookPreview": [Function],
|
|
34347
34349
|
"gallery": [Function],
|
|
34350
|
+
"inApp": [Function],
|
|
34348
34351
|
"language": [Function],
|
|
34349
34352
|
"navigationConfig": [Function],
|
|
34350
34353
|
"previewAndTest": [Function],
|
|
@@ -50899,6 +50902,7 @@ new message content.",
|
|
|
50899
50902
|
"email": [Function],
|
|
50900
50903
|
"facebookPreview": [Function],
|
|
50901
50904
|
"gallery": [Function],
|
|
50905
|
+
"inApp": [Function],
|
|
50902
50906
|
"language": [Function],
|
|
50903
50907
|
"navigationConfig": [Function],
|
|
50904
50908
|
"previewAndTest": [Function],
|
|
@@ -68001,6 +68005,7 @@ new message content.",
|
|
|
68001
68005
|
"email": [Function],
|
|
68002
68006
|
"facebookPreview": [Function],
|
|
68003
68007
|
"gallery": [Function],
|
|
68008
|
+
"inApp": [Function],
|
|
68004
68009
|
"language": [Function],
|
|
68005
68010
|
"navigationConfig": [Function],
|
|
68006
68011
|
"previewAndTest": [Function],
|
|
@@ -84033,6 +84038,7 @@ new message content.",
|
|
|
84033
84038
|
"email": [Function],
|
|
84034
84039
|
"facebookPreview": [Function],
|
|
84035
84040
|
"gallery": [Function],
|
|
84041
|
+
"inApp": [Function],
|
|
84036
84042
|
"language": [Function],
|
|
84037
84043
|
"navigationConfig": [Function],
|
|
84038
84044
|
"previewAndTest": [Function],
|
|
@@ -103374,6 +103380,7 @@ new message content.",
|
|
|
103374
103380
|
"email": [Function],
|
|
103375
103381
|
"facebookPreview": [Function],
|
|
103376
103382
|
"gallery": [Function],
|
|
103383
|
+
"inApp": [Function],
|
|
103377
103384
|
"language": [Function],
|
|
103378
103385
|
"navigationConfig": [Function],
|
|
103379
103386
|
"previewAndTest": [Function],
|
|
@@ -122715,6 +122722,7 @@ new message content.",
|
|
|
122715
122722
|
"email": [Function],
|
|
122716
122723
|
"facebookPreview": [Function],
|
|
122717
122724
|
"gallery": [Function],
|
|
122725
|
+
"inApp": [Function],
|
|
122718
122726
|
"language": [Function],
|
|
122719
122727
|
"navigationConfig": [Function],
|
|
122720
122728
|
"previewAndTest": [Function],
|
|
@@ -142731,6 +142739,7 @@ new message content.",
|
|
|
142731
142739
|
"email": [Function],
|
|
142732
142740
|
"facebookPreview": [Function],
|
|
142733
142741
|
"gallery": [Function],
|
|
142742
|
+
"inApp": [Function],
|
|
142734
142743
|
"language": [Function],
|
|
142735
142744
|
"navigationConfig": [Function],
|
|
142736
142745
|
"previewAndTest": [Function],
|
|
@@ -158763,6 +158772,7 @@ new message content.",
|
|
|
158763
158772
|
"email": [Function],
|
|
158764
158773
|
"facebookPreview": [Function],
|
|
158765
158774
|
"gallery": [Function],
|
|
158775
|
+
"inApp": [Function],
|
|
158766
158776
|
"language": [Function],
|
|
158767
158777
|
"navigationConfig": [Function],
|
|
158768
158778
|
"previewAndTest": [Function],
|
|
@@ -174795,6 +174805,7 @@ new message content.",
|
|
|
174795
174805
|
"email": [Function],
|
|
174796
174806
|
"facebookPreview": [Function],
|
|
174797
174807
|
"gallery": [Function],
|
|
174808
|
+
"inApp": [Function],
|
|
174798
174809
|
"language": [Function],
|
|
174799
174810
|
"navigationConfig": [Function],
|
|
174800
174811
|
"previewAndTest": [Function],
|
|
@@ -190827,6 +190838,7 @@ new message content.",
|
|
|
190827
190838
|
"email": [Function],
|
|
190828
190839
|
"facebookPreview": [Function],
|
|
190829
190840
|
"gallery": [Function],
|
|
190841
|
+
"inApp": [Function],
|
|
190830
190842
|
"language": [Function],
|
|
190831
190843
|
"navigationConfig": [Function],
|
|
190832
190844
|
"previewAndTest": [Function],
|
|
@@ -2281,6 +2281,7 @@ new message content.",
|
|
|
2281
2281
|
"email": [Function],
|
|
2282
2282
|
"facebookPreview": [Function],
|
|
2283
2283
|
"gallery": [Function],
|
|
2284
|
+
"inApp": [Function],
|
|
2284
2285
|
"language": [Function],
|
|
2285
2286
|
"navigationConfig": [Function],
|
|
2286
2287
|
"previewAndTest": [Function],
|
|
@@ -13480,6 +13481,7 @@ new message content.",
|
|
|
13480
13481
|
"email": [Function],
|
|
13481
13482
|
"facebookPreview": [Function],
|
|
13482
13483
|
"gallery": [Function],
|
|
13484
|
+
"inApp": [Function],
|
|
13483
13485
|
"language": [Function],
|
|
13484
13486
|
"navigationConfig": [Function],
|
|
13485
13487
|
"previewAndTest": [Function],
|
|
@@ -24425,6 +24427,7 @@ new message content.",
|
|
|
24425
24427
|
"email": [Function],
|
|
24426
24428
|
"facebookPreview": [Function],
|
|
24427
24429
|
"gallery": [Function],
|
|
24430
|
+
"inApp": [Function],
|
|
24428
24431
|
"language": [Function],
|
|
24429
24432
|
"navigationConfig": [Function],
|
|
24430
24433
|
"previewAndTest": [Function],
|
|
@@ -35370,6 +35373,7 @@ new message content.",
|
|
|
35370
35373
|
"email": [Function],
|
|
35371
35374
|
"facebookPreview": [Function],
|
|
35372
35375
|
"gallery": [Function],
|
|
35376
|
+
"inApp": [Function],
|
|
35373
35377
|
"language": [Function],
|
|
35374
35378
|
"navigationConfig": [Function],
|
|
35375
35379
|
"previewAndTest": [Function],
|
|
@@ -40,6 +40,7 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
40
40
|
tags: [],
|
|
41
41
|
tagsError: false,
|
|
42
42
|
currentContext: null, // Track current context to detect changes
|
|
43
|
+
hasTriggeredInitialApiCall: false, // Track if we've triggered API call when popover opens
|
|
43
44
|
};
|
|
44
45
|
this.renderTags = this.renderTags.bind(this);
|
|
45
46
|
this.populateTags = this.populateTags.bind(this);
|
|
@@ -51,6 +52,14 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
51
52
|
|
|
52
53
|
componentDidMount() {
|
|
53
54
|
this.generateTags(this.props);
|
|
55
|
+
// Trigger initial API call if tags are empty (similar to Email/SMS behavior)
|
|
56
|
+
const { tags, injectedTags, onContextChange } = this.props;
|
|
57
|
+
const hasNoTags = (!tags || tags.length === 0) && _.isEmpty(injectedTags);
|
|
58
|
+
if (hasNoTags && onContextChange) {
|
|
59
|
+
// Trigger API call with default 'Outbound' context to match CapTagList default
|
|
60
|
+
// This ensures tags are loaded when component mounts
|
|
61
|
+
this.getTagsforContext('Outbound');
|
|
62
|
+
}
|
|
54
63
|
}
|
|
55
64
|
|
|
56
65
|
componentWillReceiveProps(nextProps) {
|
|
@@ -59,23 +68,27 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
59
68
|
// 2. Context change is happening (detected by different tag arrays)
|
|
60
69
|
const { injectedTags: currentInjectedTags, tags: currentTags } = this.props;
|
|
61
70
|
const { injectedTags: nextInjectedTags, tags: nextTags, fetchingSchemaError } = nextProps;
|
|
62
|
-
|
|
71
|
+
|
|
63
72
|
const isInitialLoad = _.isEmpty(currentInjectedTags) && _.isEmpty(currentTags);
|
|
64
73
|
const isContextChange = !_.isEqual(nextTags, currentTags) && !_.isEmpty(currentTags);
|
|
65
|
-
|
|
74
|
+
|
|
66
75
|
if (isInitialLoad || isContextChange) {
|
|
67
76
|
this.setState({loading: true});
|
|
68
77
|
}
|
|
69
|
-
|
|
78
|
+
|
|
70
79
|
// Only reset loading for injectedTags changes if we're not currently loading due to context change
|
|
71
80
|
if (!_.isEqual(nextInjectedTags, currentInjectedTags) && !this.state.loading) {
|
|
72
81
|
this.setState({loading: false});
|
|
73
82
|
this.clearLoadingTimeout();
|
|
74
83
|
}
|
|
75
|
-
|
|
84
|
+
|
|
76
85
|
if (!_.isEqual(nextTags, currentTags)) {
|
|
77
86
|
this.setState({loading: false});
|
|
78
87
|
this.clearLoadingTimeout();
|
|
88
|
+
// Reset the flag when tags are received, so we can trigger API call again if needed
|
|
89
|
+
if (nextTags && nextTags.length > 0) {
|
|
90
|
+
this.setState({ hasTriggeredInitialApiCall: false });
|
|
91
|
+
}
|
|
79
92
|
}
|
|
80
93
|
if (fetchingSchemaError) {
|
|
81
94
|
this.setState({tagsError: fetchingSchemaError, loading: false});
|
|
@@ -86,7 +99,7 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
86
99
|
componentDidUpdate(prevProps) {
|
|
87
100
|
const { tags, injectedTags, selectedOfferDetails } = this.props;
|
|
88
101
|
const { tags: prevTags, injectedTags: prevInjectedTags, selectedOfferDetails: prevSelectedOfferDetails } = prevProps;
|
|
89
|
-
|
|
102
|
+
|
|
90
103
|
if (tags !== prevTags || injectedTags !== prevInjectedTags || selectedOfferDetails !== prevSelectedOfferDetails) {
|
|
91
104
|
this.generateTags(this.props);
|
|
92
105
|
}
|
|
@@ -111,17 +124,44 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
111
124
|
getTagsforContext = (data) => {
|
|
112
125
|
// Set loading state when context change is requested
|
|
113
126
|
this.setState({loading: true, currentContext: data});
|
|
114
|
-
|
|
127
|
+
|
|
115
128
|
// Set a timeout to prevent infinite loading (fallback safety)
|
|
116
129
|
this.clearLoadingTimeout();
|
|
117
130
|
this.loadingTimeout = setTimeout(() => {
|
|
118
131
|
this.setState({loading: false});
|
|
119
132
|
}, 5000); // Reduced timeout to 5 seconds for better UX
|
|
120
|
-
|
|
133
|
+
|
|
121
134
|
const { onContextChange } = this.props;
|
|
122
|
-
onContextChange
|
|
135
|
+
// Always call onContextChange if available - this triggers the API call
|
|
136
|
+
// The API call will fetch tags from /meta/TAG endpoint
|
|
137
|
+
if (onContextChange) {
|
|
138
|
+
onContextChange(data);
|
|
139
|
+
} else {
|
|
140
|
+
console.warn('TagList: onContextChange is not available. API call will not be triggered.');
|
|
141
|
+
}
|
|
123
142
|
}
|
|
124
143
|
|
|
144
|
+
handlePopoverVisibilityChange = (visible) => {
|
|
145
|
+
// When popover opens, trigger API call if tags are empty or if we haven't triggered it yet
|
|
146
|
+
// This ensures API call happens when user clicks "Add Label" button
|
|
147
|
+
if (visible && this.props.onContextChange) {
|
|
148
|
+
const { tags, injectedTags } = this.props;
|
|
149
|
+
// Check if tags array is empty or if state tags are empty
|
|
150
|
+
const hasNoTags = (!tags || tags.length === 0) && _.isEmpty(injectedTags);
|
|
151
|
+
const hasNoStateTags = _.isEmpty(this.state.tags);
|
|
152
|
+
const hasNotTriggeredApiCall = !this.state.hasTriggeredInitialApiCall;
|
|
153
|
+
|
|
154
|
+
// Trigger API call if tags are not loaded yet OR if we haven't triggered it yet
|
|
155
|
+
if ((hasNoTags || hasNoStateTags || hasNotTriggeredApiCall)) {
|
|
156
|
+
// Mark that we've triggered the API call
|
|
157
|
+
this.setState({ hasTriggeredInitialApiCall: true });
|
|
158
|
+
// Trigger API call with default 'Outbound' context to match CapTagList default
|
|
159
|
+
// This will call onContextChange which triggers handleOnTagsContextChange in InApp
|
|
160
|
+
this.getTagsforContext('Outbound');
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
125
165
|
generateTags = (props) => {
|
|
126
166
|
let tags = {};
|
|
127
167
|
let injectedTags = {};
|
|
@@ -149,11 +189,11 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
149
189
|
if (eventContextTags?.length) {
|
|
150
190
|
const TAG_HEADER_MSG_LABEL = this.props.intl.formatMessage(messages.entryEvent);
|
|
151
191
|
eventContextTagsObj.eventContextTags = {
|
|
152
|
-
name: TAG_HEADER_MSG_LABEL,
|
|
153
|
-
desc: TAG_HEADER_MSG_LABEL,
|
|
154
|
-
resolved: true,
|
|
192
|
+
"name": TAG_HEADER_MSG_LABEL,
|
|
193
|
+
"desc": TAG_HEADER_MSG_LABEL,
|
|
194
|
+
"resolved": true,
|
|
155
195
|
'tag-header': true,
|
|
156
|
-
subtags: {},
|
|
196
|
+
"subtags": {},
|
|
157
197
|
};
|
|
158
198
|
|
|
159
199
|
eventContextTags.forEach((tag) => {
|
|
@@ -164,11 +204,11 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
164
204
|
// Initializing the tags profile if it doesn't exist
|
|
165
205
|
if (!eventContextTagsObj?.eventContextTags?.subtags?.[profileId]) {
|
|
166
206
|
eventContextTagsObj.eventContextTags.subtags[profileId] = {
|
|
167
|
-
name: profileName,
|
|
168
|
-
desc: profileName,
|
|
169
|
-
resolved: true,
|
|
207
|
+
"name": profileName,
|
|
208
|
+
"desc": profileName,
|
|
209
|
+
"resolved": true,
|
|
170
210
|
'tag-header': true,
|
|
171
|
-
subtags: {},
|
|
211
|
+
"subtags": {},
|
|
172
212
|
};
|
|
173
213
|
}
|
|
174
214
|
// Adding the current tag to the profile group
|
|
@@ -201,7 +241,7 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
201
241
|
_.forEach(tagsList, (temp) => {
|
|
202
242
|
const tag = temp.definition;
|
|
203
243
|
const { intl } = this.props;
|
|
204
|
-
|
|
244
|
+
const { locale: userLocale } = intl || {};
|
|
205
245
|
|
|
206
246
|
// Check if the tag.value should be skipped based on feature control
|
|
207
247
|
if (_.includes(excludedTags, tag.value)) {
|
|
@@ -209,8 +249,8 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
209
249
|
}
|
|
210
250
|
if (!tag['tag-header']) {
|
|
211
251
|
mainTags[tag.value] = {
|
|
212
|
-
|
|
213
|
-
|
|
252
|
+
name: tag?.label[userLocale] ? tag?.label[userLocale] : tag?.label?.en,
|
|
253
|
+
desc: tag?.label[userLocale] ? tag?.label[userLocale] : tag?.label?.en,
|
|
214
254
|
};
|
|
215
255
|
} else if (tag['tag-header'] && mainTags[tag.value]) {
|
|
216
256
|
mainTags[tag.value].subtags = _.concat(mainTags[tag.value].subtags, tag.subtags);
|
|
@@ -366,12 +406,14 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
366
406
|
visibleTaglist={this.props.visibleTaglist}
|
|
367
407
|
hidePopover={this.props.hidePopover}
|
|
368
408
|
onContextChange={this.getTagsforContext}
|
|
409
|
+
onVisibleChange={this.handlePopoverVisibilityChange}
|
|
369
410
|
moduleFilterEnabled={this.props.moduleFilterEnabled}
|
|
370
411
|
modalProps={this.props.modalProps}
|
|
371
412
|
currentOrgDetails={this.props.currentOrgDetails}
|
|
372
413
|
channel={this.props.channel}
|
|
373
414
|
disabled={this.props.disabled}
|
|
374
415
|
fetchingSchemaError={this?.state?.tagsError}
|
|
416
|
+
popoverPlacement={this.props.popoverPlacement}
|
|
375
417
|
/>
|
|
376
418
|
</div>
|
|
377
419
|
);
|
|
@@ -402,6 +444,7 @@ TagList.propTypes = {
|
|
|
402
444
|
disabled: PropTypes.bool,
|
|
403
445
|
fetchingSchemaError: PropTypes.bool,
|
|
404
446
|
eventContextTags: PropTypes.array,
|
|
447
|
+
popoverPlacement: PropTypes.string,
|
|
405
448
|
intl: PropTypes.shape({
|
|
406
449
|
formatMessage: PropTypes.func.isRequired,
|
|
407
450
|
locale: PropTypes.string,
|
|
@@ -316,6 +316,64 @@
|
|
|
316
316
|
}
|
|
317
317
|
}
|
|
318
318
|
}
|
|
319
|
+
.INAPP {
|
|
320
|
+
margin-bottom: $CAP_SPACE_12;
|
|
321
|
+
.inapp-container {
|
|
322
|
+
margin-top: $CAP_SPACE_24;
|
|
323
|
+
}
|
|
324
|
+
// Modal Layout - centered
|
|
325
|
+
.inapp-modal-layout {
|
|
326
|
+
position: absolute;
|
|
327
|
+
display: flex;
|
|
328
|
+
width: 12rem;
|
|
329
|
+
top: 10%;
|
|
330
|
+
left: 10%;
|
|
331
|
+
bottom: 5%;
|
|
332
|
+
overflow: hidden;
|
|
333
|
+
background-color: $CAP_WHITE;
|
|
334
|
+
border-radius: $CAP_SPACE_08;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Full Screen Layout
|
|
338
|
+
.inapp-fullscreen-layout {
|
|
339
|
+
position: absolute;
|
|
340
|
+
display: flex;
|
|
341
|
+
width: 12rem;
|
|
342
|
+
left: 10%;
|
|
343
|
+
top: 1%;
|
|
344
|
+
bottom: 1%;
|
|
345
|
+
overflow: hidden;
|
|
346
|
+
background-color: $CAP_WHITE;
|
|
347
|
+
border-radius: $CAP_SPACE_08;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Top Banner Layout
|
|
351
|
+
.inapp-top-banner-layout {
|
|
352
|
+
position: absolute;
|
|
353
|
+
display: flex;
|
|
354
|
+
width: 12rem;
|
|
355
|
+
left: 10%;
|
|
356
|
+
top: 1%;
|
|
357
|
+
bottom: 20%;
|
|
358
|
+
overflow: hidden;
|
|
359
|
+
background-color: $CAP_WHITE;
|
|
360
|
+
border-radius: $CAP_SPACE_08;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Bottom Banner Layout
|
|
364
|
+
.inapp-bottom-banner-layout {
|
|
365
|
+
position: absolute;
|
|
366
|
+
display: flex;
|
|
367
|
+
justify-content: center;
|
|
368
|
+
width: 12rem;
|
|
369
|
+
left: 10%;
|
|
370
|
+
top: 50%;
|
|
371
|
+
bottom: 2%;
|
|
372
|
+
overflow: hidden;
|
|
373
|
+
background-color: $CAP_WHITE;
|
|
374
|
+
border-radius: $CAP_SPACE_08;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
319
377
|
}
|
|
320
378
|
|
|
321
379
|
.WEBPUSH {
|
|
@@ -897,7 +955,8 @@
|
|
|
897
955
|
}
|
|
898
956
|
|
|
899
957
|
.whatsapp-filters,
|
|
900
|
-
.zalo-filters
|
|
958
|
+
.zalo-filters,
|
|
959
|
+
.inapp-filters {
|
|
901
960
|
display: flex;
|
|
902
961
|
width: 100%;
|
|
903
962
|
padding-left: 8px;
|
|
@@ -128,13 +128,14 @@ import {
|
|
|
128
128
|
VIDEO,
|
|
129
129
|
GIF,
|
|
130
130
|
} from '../Whatsapp/constants';
|
|
131
|
-
import { INAPP_LAYOUT_DETAILS } from '../InApp/constants';
|
|
131
|
+
import { INAPP_LAYOUT_DETAILS, INAPP_MESSAGE_LAYOUT_TYPES, INAPP_MEDIA_TYPES, BIG_HTML, ANDROID, IOS } from '../InApp/constants';
|
|
132
132
|
import { ZALO_STATUS_OPTIONS, ZALO_STATUSES } from '../Zalo/constants';
|
|
133
133
|
import { getWhatsappContent, getWhatsappStatus, getWhatsappCategory, getWhatsappCta, getWhatsappQuickReply, getWhatsappAutoFill, getWhatsappCarouselButtonView } from '../Whatsapp/utils';
|
|
134
134
|
import { getRCSContent } from '../Rcs/utils';
|
|
135
135
|
import {RCS_STATUSES} from '../Rcs/constants';
|
|
136
136
|
import zaloMessages from '../Zalo/messages';
|
|
137
137
|
import rcsMessages from '../Rcs/messages';
|
|
138
|
+
import inAppMessages from '../InApp/messages';
|
|
138
139
|
import globalMessages from '../../v2Containers/Cap/messages';
|
|
139
140
|
import { handlePreviewInNewTab } from '../../utils/common';
|
|
140
141
|
|
|
@@ -204,6 +205,29 @@ const SMS_FILTERS = {
|
|
|
204
205
|
SERVICE_IMPLICIT: 'implicit',
|
|
205
206
|
};
|
|
206
207
|
|
|
208
|
+
const INAPP_LAYOUT_OPTIONS = [
|
|
209
|
+
{
|
|
210
|
+
key: 'popup',
|
|
211
|
+
value: INAPP_MESSAGE_LAYOUT_TYPES.MODAL,
|
|
212
|
+
label: <FormattedMessage {...inAppMessages.layoutModal} />,
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
key: 'topBanner',
|
|
216
|
+
value: INAPP_MESSAGE_LAYOUT_TYPES.TOPBANNER,
|
|
217
|
+
label: <FormattedMessage {...inAppMessages.layoutTopBanner} />,
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
key: 'bottomBanner',
|
|
221
|
+
value: INAPP_MESSAGE_LAYOUT_TYPES.BOTTOMBANNER,
|
|
222
|
+
label: <FormattedMessage {...inAppMessages.layoutBottomBanner} />,
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
key: 'fullScreen',
|
|
226
|
+
value: INAPP_MESSAGE_LAYOUT_TYPES.FULLSCREEN,
|
|
227
|
+
label: <FormattedMessage {...inAppMessages.layoutFullScreen} />,
|
|
228
|
+
},
|
|
229
|
+
];
|
|
230
|
+
|
|
207
231
|
const WHATSAPP_LOWERCASE = WHATSAPP.toLowerCase();
|
|
208
232
|
const RCS_LOWERCASE = RCS.toLowerCase();
|
|
209
233
|
const SMS_LOWERCASE = SMS.toLowerCase();
|
|
@@ -255,6 +279,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
255
279
|
selectedWhatsappStatus: '',
|
|
256
280
|
selectedWhatsappCategory: '',
|
|
257
281
|
selectedZaloStatus: '',
|
|
282
|
+
selectedInAppLayout: '',
|
|
258
283
|
hostName: '',
|
|
259
284
|
searchedZaloTemplates: [],
|
|
260
285
|
searchingZaloTemplate: false,
|
|
@@ -1759,6 +1784,19 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1759
1784
|
return templates;
|
|
1760
1785
|
}
|
|
1761
1786
|
|
|
1787
|
+
filterInAppTemplates = (templates) => {
|
|
1788
|
+
const { selectedInAppLayout } = this.state;
|
|
1789
|
+
if (!selectedInAppLayout) {
|
|
1790
|
+
return templates;
|
|
1791
|
+
}
|
|
1792
|
+
return templates.filter((template) => {
|
|
1793
|
+
const androidBodyType = get(template, 'versions.base.content.ANDROID.bodyType');
|
|
1794
|
+
const iosBodyType = get(template, 'versions.base.content.IOS.bodyType');
|
|
1795
|
+
const inappBodyType = androidBodyType || iosBodyType;
|
|
1796
|
+
return inappBodyType === selectedInAppLayout;
|
|
1797
|
+
});
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1762
1800
|
filterSMSTemplates = (templates) => {
|
|
1763
1801
|
const { smsFilter } = this.state;
|
|
1764
1802
|
if (SMS_FILTERS.ALL === smsFilter) {
|
|
@@ -1845,6 +1883,9 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1845
1883
|
case ZALO:
|
|
1846
1884
|
filteredTemplates = this.filterZaloTemplates(templates);
|
|
1847
1885
|
break;
|
|
1886
|
+
case INAPP:
|
|
1887
|
+
filteredTemplates = this.filterInAppTemplates(templates);
|
|
1888
|
+
break;
|
|
1848
1889
|
default:
|
|
1849
1890
|
break;
|
|
1850
1891
|
}
|
|
@@ -2134,9 +2175,12 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2134
2175
|
templateData.isNewMobilePush = commonUtil.hasNewMobilePushFeatureEnabled();
|
|
2135
2176
|
}
|
|
2136
2177
|
break;
|
|
2137
|
-
case INAPP:
|
|
2178
|
+
case INAPP: {
|
|
2179
|
+
// Pass the full template object to CapCustomCard so getInAppContent can extract the data
|
|
2180
|
+
// Similar to how MOBILE_PUSH passes the full template when new feature is enabled
|
|
2138
2181
|
templateData.content = template;
|
|
2139
2182
|
break;
|
|
2183
|
+
}
|
|
2140
2184
|
case WECHAT:
|
|
2141
2185
|
templateData.content = this.prepareWeChatPreviewData(template);
|
|
2142
2186
|
break;
|
|
@@ -2514,7 +2558,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2514
2558
|
return (<div>
|
|
2515
2559
|
{[WECHAT, MOBILE_PUSH, WEBPUSH, INAPP, WHATSAPP, ZALO, RCS].includes(currentChannel) && this.showAccountName()}
|
|
2516
2560
|
{filterContent}
|
|
2517
|
-
{[WHATSAPP, ZALO,RCS].includes(currentChannel) && this.selectedFilters()}
|
|
2561
|
+
{[WHATSAPP, ZALO, INAPP,RCS].includes(currentChannel) && this.selectedFilters()}
|
|
2518
2562
|
{<div>
|
|
2519
2563
|
{!isEmpty(filteredTemplates) || !isEmpty(this.state.searchText) || !isEmpty(this.props.Templates.templateError) ? (
|
|
2520
2564
|
<div className={!isEmpty(this.state.searchText) && isEmpty(cardDataList) ? '' : this.isFullMode() ? "v2-pagination-container" : "v2-pagination-container-half"}>
|
|
@@ -2729,6 +2773,9 @@ return (<div>
|
|
|
2729
2773
|
|
|
2730
2774
|
prepareWeChatMappedPreviewData(content, templateTags, tagData) {
|
|
2731
2775
|
let formattedContent = cloneDeep(content);
|
|
2776
|
+
if (!formattedContent || typeof formattedContent !== 'string') {
|
|
2777
|
+
return formattedContent || '';
|
|
2778
|
+
}
|
|
2732
2779
|
forEach(templateTags, (tag) => {
|
|
2733
2780
|
if (tagData[tag].value !== undefined) {
|
|
2734
2781
|
formattedContent = formattedContent.replace(`{{${tag}.DATA}}`, tagData[tag].value);
|
|
@@ -3981,14 +4028,19 @@ return (<div>
|
|
|
3981
4028
|
}
|
|
3982
4029
|
|
|
3983
4030
|
removeZaloFilter = () => this.setState({ selectedZaloStatus: null });
|
|
4031
|
+
removeInAppLayoutFilter = () => this.setState({ selectedInAppLayout: '' });
|
|
3984
4032
|
|
|
3985
4033
|
selectedFilters = () => {
|
|
3986
|
-
const { selectedWhatsappStatus, selectedWhatsappCategory, selectedZaloStatus } = this.state;
|
|
4034
|
+
const { selectedWhatsappStatus, selectedWhatsappCategory, selectedZaloStatus, selectedInAppLayout } = this.state;
|
|
3987
4035
|
const {
|
|
3988
4036
|
intl: {
|
|
3989
4037
|
formatMessage,
|
|
3990
4038
|
},
|
|
3991
4039
|
} = this.props;
|
|
4040
|
+
const getInAppLayoutLabel = (layoutValue) => {
|
|
4041
|
+
const layoutOption = INAPP_LAYOUT_OPTIONS.find(opt => opt.value === layoutValue);
|
|
4042
|
+
return layoutOption ? layoutOption.label : layoutValue;
|
|
4043
|
+
};
|
|
3992
4044
|
return (
|
|
3993
4045
|
<CapRow type="flex" align="middle" className="selected-whatsapp-filters">
|
|
3994
4046
|
{
|
|
@@ -4023,6 +4075,23 @@ return (<div>
|
|
|
4023
4075
|
</CapTag>
|
|
4024
4076
|
) : null
|
|
4025
4077
|
}
|
|
4078
|
+
{
|
|
4079
|
+
selectedInAppLayout ? (
|
|
4080
|
+
<CapTag closable onClose={this.removeInAppLayoutFilter}>
|
|
4081
|
+
{formatMessage(messages.layout)}: {getInAppLayoutLabel(selectedInAppLayout)}
|
|
4082
|
+
</CapTag>
|
|
4083
|
+
) : null
|
|
4084
|
+
}
|
|
4085
|
+
{
|
|
4086
|
+
selectedInAppLayout ? (
|
|
4087
|
+
<CapLink
|
|
4088
|
+
onClick={() => {
|
|
4089
|
+
this.removeInAppLayoutFilter();
|
|
4090
|
+
}}
|
|
4091
|
+
title={this.props.intl.formatMessage(messages.clearAll)}
|
|
4092
|
+
/>
|
|
4093
|
+
) : null
|
|
4094
|
+
}
|
|
4026
4095
|
</CapRow>
|
|
4027
4096
|
);
|
|
4028
4097
|
}
|
|
@@ -4033,6 +4102,7 @@ return (<div>
|
|
|
4033
4102
|
setLineFilter = (e) => this.setState({lineFilter: e.target.value});
|
|
4034
4103
|
setSMSFilter = (e) => this.setState({smsFilter: e.target.value});
|
|
4035
4104
|
setZaloStatus = (value) => this.setState({selectedZaloStatus: value?.item?.props?.value});
|
|
4105
|
+
setInAppLayout = (value) => this.setState({selectedInAppLayout: value?.item?.props?.value});
|
|
4036
4106
|
|
|
4037
4107
|
openCreativesFullMode = () => {
|
|
4038
4108
|
const channelLowerCase = this.state.channel.toLowerCase();
|
|
@@ -4285,6 +4355,21 @@ return (<div>
|
|
|
4285
4355
|
)
|
|
4286
4356
|
: () => null
|
|
4287
4357
|
}
|
|
4358
|
+
{
|
|
4359
|
+
channel.toUpperCase() === INAPP && (
|
|
4360
|
+
<div className="inapp-filters">
|
|
4361
|
+
<CapSelectFilter
|
|
4362
|
+
placement="bottomLeft"
|
|
4363
|
+
data={INAPP_LAYOUT_OPTIONS}
|
|
4364
|
+
onSelect={this.setInAppLayout}
|
|
4365
|
+
selectedValue={this.state.selectedInAppLayout}
|
|
4366
|
+
placeholder="Layout"
|
|
4367
|
+
showBadge
|
|
4368
|
+
width="120px"
|
|
4369
|
+
/>
|
|
4370
|
+
</div>
|
|
4371
|
+
)
|
|
4372
|
+
}
|
|
4288
4373
|
<div style={{display: "flex", justifyContent: "space-between", alignItems: 'center'}}>
|
|
4289
4374
|
{
|
|
4290
4375
|
this.state?.channel?.toLowerCase() === WHATSAPP_LOWERCASE && (isWhatsappCountExeeded)? (
|
|
@@ -558,6 +558,10 @@ export default defineMessages({
|
|
|
558
558
|
id: `${scope}.rcsOnlyApprovedTemplates`,
|
|
559
559
|
defaultMessage: 'Only "Approved" templates are available here, as you can use those templates to create a message.',
|
|
560
560
|
},
|
|
561
|
+
"layout": {
|
|
562
|
+
id: `${scope}.layout`,
|
|
563
|
+
defaultMessage: `Layout`,
|
|
564
|
+
},
|
|
561
565
|
"status": {
|
|
562
566
|
id: `${scope}.status`,
|
|
563
567
|
defaultMessage: 'Status',
|
|
@@ -14,8 +14,10 @@ export default css`
|
|
|
14
14
|
margin: 0 auto;
|
|
15
15
|
width: 100%;
|
|
16
16
|
padding: ${CAP_SPACE_24} 0;
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
/* Only main channel tabs content, not HTML Editor validation panel tabs */
|
|
18
|
+
> .cap-tab-v2 > .ant-tabs-content-holder > .ant-tabs-content,
|
|
19
|
+
> .cap-tab-v2 > .ant-tabs-content {
|
|
20
|
+
margin-top: ${CAP_SPACE_16};
|
|
19
21
|
}
|
|
20
22
|
` : `.cap-tab-v2 {
|
|
21
23
|
height: calc(100vh - 11.25rem);
|