@capillarytech/creatives-library 8.0.129 → 8.0.130
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/containers/App/constants.js +0 -1
- package/containers/Templates/constants.js +10 -1
- package/containers/Templates/index.js +45 -45
- package/package.json +1 -1
- package/services/api.js +9 -7
- package/services/tests/haptic-api.test.js +387 -0
- package/tests/integration/TemplateCreation/TemplateCreation.integration.test.js +3 -8
- package/tests/integration/TemplateCreation/api-response.js +0 -5
- package/tests/integration/TemplateCreation/msw-handler.js +63 -42
- package/utils/common.js +0 -7
- package/utils/commonUtils.js +6 -2
- package/utils/tests/vendorDataTransformers.test.js +512 -0
- package/utils/vendorDataTransformers.js +108 -0
- package/v2Components/CapDocumentUpload/index.js +2 -2
- package/v2Components/CapImageUpload/index.js +46 -59
- package/v2Components/CapInAppCTA/index.js +0 -1
- package/v2Components/CapTagList/index.js +120 -177
- package/v2Components/CapVideoUpload/constants.js +0 -3
- package/v2Components/CapVideoUpload/index.js +110 -167
- package/v2Components/CapVideoUpload/messages.js +0 -16
- package/v2Components/Carousel/index.js +13 -15
- package/v2Components/ErrorInfoNote/style.scss +0 -1
- package/v2Components/MobilePushPreviewV2/index.js +5 -37
- package/v2Components/TemplatePreview/_templatePreview.scss +72 -114
- package/v2Components/TemplatePreview/index.js +50 -178
- package/v2Components/TemplatePreview/messages.js +0 -4
- package/v2Containers/CreativesContainer/SlideBoxContent.js +62 -127
- package/v2Containers/CreativesContainer/index.js +136 -191
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +22 -0
- package/v2Containers/InApp/constants.js +0 -1
- package/v2Containers/InApp/index.js +13 -13
- package/v2Containers/MobilePush/Create/index.js +0 -1
- package/v2Containers/MobilePush/commonMethods.js +14 -7
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +5 -5
- package/v2Containers/TagList/index.js +10 -56
- package/v2Containers/Templates/_templates.scss +1 -101
- package/v2Containers/Templates/index.js +41 -151
- package/v2Containers/Templates/messages.js +0 -8
- package/v2Containers/Templates/sagas.js +0 -2
- package/v2Containers/Whatsapp/constants.js +32 -1
- package/v2Containers/Whatsapp/index.js +104 -25
- package/v2Containers/Whatsapp/tests/haptic.test.js +405 -0
- package/utils/createPayload.js +0 -405
- package/utils/tests/createPayload.test.js +0 -785
- package/v2Components/CapMpushCTA/constants.js +0 -25
- package/v2Components/CapMpushCTA/index.js +0 -402
- package/v2Components/CapMpushCTA/index.scss +0 -95
- package/v2Components/CapMpushCTA/messages.js +0 -101
- package/v2Components/TemplatePreview/assets/images/Android _ With date and time.svg +0 -29
- package/v2Components/TemplatePreview/assets/images/android.svg +0 -9
- package/v2Components/TemplatePreview/assets/images/iOS _ With date and time.svg +0 -26
- package/v2Components/TemplatePreview/assets/images/ios.svg +0 -9
- package/v2Containers/MobilePushNew/actions.js +0 -116
- package/v2Containers/MobilePushNew/components/CtaButtons.js +0 -181
- package/v2Containers/MobilePushNew/components/MediaUploaders.js +0 -834
- package/v2Containers/MobilePushNew/components/PlatformContentFields.js +0 -345
- package/v2Containers/MobilePushNew/components/index.js +0 -5
- package/v2Containers/MobilePushNew/components/tests/CtaButtons.test.js +0 -798
- package/v2Containers/MobilePushNew/components/tests/MediaUploaders.test.js +0 -2114
- package/v2Containers/MobilePushNew/components/tests/PlatformContentFields.test.js +0 -343
- package/v2Containers/MobilePushNew/constants.js +0 -115
- package/v2Containers/MobilePushNew/hooks/tests/usePlatformSync.test.js +0 -1299
- package/v2Containers/MobilePushNew/hooks/tests/useUpload.test.js +0 -1223
- package/v2Containers/MobilePushNew/hooks/usePlatformSync.js +0 -246
- package/v2Containers/MobilePushNew/hooks/useUpload.js +0 -726
- package/v2Containers/MobilePushNew/index.js +0 -3412
- package/v2Containers/MobilePushNew/index.scss +0 -308
- package/v2Containers/MobilePushNew/messages.js +0 -242
- package/v2Containers/MobilePushNew/reducer.js +0 -160
- package/v2Containers/MobilePushNew/sagas.js +0 -198
- package/v2Containers/MobilePushNew/selectors.js +0 -55
- package/v2Containers/MobilePushNew/tests/reducer.test.js +0 -741
- package/v2Containers/MobilePushNew/tests/sagas.test.js +0 -863
- package/v2Containers/MobilePushNew/tests/selectors.test.js +0 -425
- package/v2Containers/MobilePushNew/tests/utils.test.js +0 -322
- package/v2Containers/MobilePushNew/utils.js +0 -33
|
@@ -248,13 +248,20 @@ function getLinkTypeFields({inputFieldsArgs, fieldIndex, deepLinkOptions, formDa
|
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
function getContent(obj) {
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
251
|
+
const {
|
|
252
|
+
versions : {
|
|
253
|
+
base: {
|
|
254
|
+
ANDROID: {
|
|
255
|
+
title : androidTitle,
|
|
256
|
+
message : androidMessage
|
|
257
|
+
} = {},
|
|
258
|
+
IOS: {
|
|
259
|
+
title: iosTitle,
|
|
260
|
+
message: iosMessage
|
|
261
|
+
} = {}
|
|
262
|
+
} = {}
|
|
263
|
+
} = {}
|
|
264
|
+
} = obj;
|
|
258
265
|
return `${androidTitle} ${androidMessage} ${iosTitle} ${iosMessage}`;
|
|
259
266
|
}
|
|
260
267
|
export {
|
|
@@ -95639,7 +95639,7 @@ new message content.",
|
|
|
95639
95639
|
>
|
|
95640
95640
|
<input
|
|
95641
95641
|
accept="image/*"
|
|
95642
|
-
id="
|
|
95642
|
+
id="fileName"
|
|
95643
95643
|
key="imgFile"
|
|
95644
95644
|
onChange={[Function]}
|
|
95645
95645
|
style={
|
|
@@ -116561,7 +116561,7 @@ new message content.",
|
|
|
116561
116561
|
>
|
|
116562
116562
|
<input
|
|
116563
116563
|
accept="image/*"
|
|
116564
|
-
id="
|
|
116564
|
+
id="fileName"
|
|
116565
116565
|
key="imgFile"
|
|
116566
116566
|
onChange={[Function]}
|
|
116567
116567
|
style={
|
|
@@ -137377,7 +137377,7 @@ new message content.",
|
|
|
137377
137377
|
>
|
|
137378
137378
|
<input
|
|
137379
137379
|
accept="image/*"
|
|
137380
|
-
id="
|
|
137380
|
+
id="fileName"
|
|
137381
137381
|
key="imgFile"
|
|
137382
137382
|
onChange={[Function]}
|
|
137383
137383
|
style={
|
|
@@ -158299,7 +158299,7 @@ new message content.",
|
|
|
158299
158299
|
>
|
|
158300
158300
|
<input
|
|
158301
158301
|
accept="image/*"
|
|
158302
|
-
id="
|
|
158302
|
+
id="fileName"
|
|
158303
158303
|
key="imgFile"
|
|
158304
158304
|
onChange={[Function]}
|
|
158305
158305
|
style={
|
|
@@ -199210,7 +199210,7 @@ new message content.",
|
|
|
199210
199210
|
>
|
|
199211
199211
|
<input
|
|
199212
199212
|
accept="image/*"
|
|
199213
|
-
id="
|
|
199213
|
+
id="fileName"
|
|
199214
199214
|
key="imgFile"
|
|
199215
199215
|
onChange={[Function]}
|
|
199216
199216
|
style={
|
|
@@ -39,14 +39,12 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
39
39
|
loading: false,
|
|
40
40
|
tags: [],
|
|
41
41
|
tagsError: false,
|
|
42
|
-
currentContext: null, // Track current context to detect changes
|
|
43
42
|
};
|
|
44
43
|
this.renderTags = this.renderTags.bind(this);
|
|
45
44
|
this.populateTags = this.populateTags.bind(this);
|
|
46
45
|
this.populateTagForChildren = this.populateTagForChildren.bind(this);
|
|
47
46
|
this.transformInjectedTags = this.transformInjectedTags.bind(this);
|
|
48
47
|
this.transformCouponTags = this.transformCouponTags.bind(this);
|
|
49
|
-
this.loadingTimeout = null; // Add timeout reference
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
componentDidMount() {
|
|
@@ -54,72 +52,33 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
54
52
|
}
|
|
55
53
|
|
|
56
54
|
componentWillReceiveProps(nextProps) {
|
|
57
|
-
|
|
58
|
-
// 1. Both injectedTags and tags are empty (initial load)
|
|
59
|
-
// 2. Context change is happening (detected by different tag arrays)
|
|
60
|
-
const { injectedTags: currentInjectedTags, tags: currentTags } = this.props;
|
|
61
|
-
const { injectedTags: nextInjectedTags, tags: nextTags, fetchingSchemaError } = nextProps;
|
|
62
|
-
|
|
63
|
-
const isInitialLoad = _.isEmpty(currentInjectedTags) && _.isEmpty(currentTags);
|
|
64
|
-
const isContextChange = !_.isEqual(nextTags, currentTags) && !_.isEmpty(currentTags);
|
|
65
|
-
|
|
66
|
-
if (isInitialLoad || isContextChange) {
|
|
55
|
+
if (_.isEmpty(this.props.injectedTags) && _.isEmpty(this.props.tags)) {
|
|
67
56
|
this.setState({loading: true});
|
|
68
57
|
}
|
|
69
|
-
|
|
70
|
-
// Only reset loading for injectedTags changes if we're not currently loading due to context change
|
|
71
|
-
if (!_.isEqual(nextInjectedTags, currentInjectedTags) && !this.state.loading) {
|
|
58
|
+
if (!_.isEqual(nextProps.injectedTags, this.props.injectedTags)) {
|
|
72
59
|
this.setState({loading: false});
|
|
73
|
-
this.clearLoadingTimeout();
|
|
74
60
|
}
|
|
75
|
-
|
|
76
|
-
if (!_.isEqual(nextTags, currentTags)) {
|
|
61
|
+
if (!_.isEqual(nextProps.tags, this.props.tags)) {
|
|
77
62
|
this.setState({loading: false});
|
|
78
|
-
this.clearLoadingTimeout();
|
|
79
63
|
}
|
|
80
|
-
if (fetchingSchemaError) {
|
|
81
|
-
this.setState({tagsError: fetchingSchemaError
|
|
82
|
-
this.clearLoadingTimeout();
|
|
64
|
+
if (nextProps?.fetchingSchemaError) {
|
|
65
|
+
this.setState({tagsError: nextProps?.fetchingSchemaError});
|
|
83
66
|
}
|
|
84
67
|
}
|
|
85
68
|
|
|
86
69
|
componentDidUpdate(prevProps) {
|
|
87
|
-
|
|
88
|
-
const { tags: prevTags, injectedTags: prevInjectedTags, selectedOfferDetails: prevSelectedOfferDetails } = prevProps;
|
|
89
|
-
|
|
90
|
-
if (tags !== prevTags || injectedTags !== prevInjectedTags || selectedOfferDetails !== prevSelectedOfferDetails) {
|
|
70
|
+
if (this.props.tags !== prevProps.tags || this.props.injectedTags !== prevProps.injectedTags || this.props.selectedOfferDetails !== prevProps.selectedOfferDetails) {
|
|
91
71
|
this.generateTags(this.props);
|
|
92
72
|
}
|
|
93
73
|
}
|
|
94
74
|
|
|
95
|
-
componentWillUnmount() {
|
|
96
|
-
this.clearLoadingTimeout();
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
clearLoadingTimeout = () => {
|
|
100
|
-
if (this.loadingTimeout) {
|
|
101
|
-
clearTimeout(this.loadingTimeout);
|
|
102
|
-
this.loadingTimeout = null;
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
|
|
106
75
|
onSelect = (selectedKeys) => {
|
|
107
|
-
|
|
108
|
-
onTagSelect(selectedKeys[0]);
|
|
76
|
+
this.props.onTagSelect(selectedKeys[0]);
|
|
109
77
|
};
|
|
110
78
|
|
|
111
79
|
getTagsforContext = (data) => {
|
|
112
|
-
//
|
|
113
|
-
this.
|
|
114
|
-
|
|
115
|
-
// Set a timeout to prevent infinite loading (fallback safety)
|
|
116
|
-
this.clearLoadingTimeout();
|
|
117
|
-
this.loadingTimeout = setTimeout(() => {
|
|
118
|
-
this.setState({loading: false});
|
|
119
|
-
}, 5000); // Reduced timeout to 5 seconds for better UX
|
|
120
|
-
|
|
121
|
-
const { onContextChange } = this.props;
|
|
122
|
-
onContextChange(data);
|
|
80
|
+
//this.setState({loading: true});
|
|
81
|
+
this.props.onContextChange(data);
|
|
123
82
|
}
|
|
124
83
|
|
|
125
84
|
generateTags = (props) => {
|
|
@@ -200,8 +159,7 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
200
159
|
//Form tags object with tag headers
|
|
201
160
|
_.forEach(tagsList, (temp) => {
|
|
202
161
|
const tag = temp.definition;
|
|
203
|
-
const {
|
|
204
|
-
const { locale: userLocale } = intl || {};
|
|
162
|
+
const { locale: userLocale } = this.props?.intl || {};
|
|
205
163
|
|
|
206
164
|
// Check if the tag.value should be skipped based on feature control
|
|
207
165
|
if (_.includes(excludedTags, tag.value)) {
|
|
@@ -402,10 +360,6 @@ TagList.propTypes = {
|
|
|
402
360
|
disabled: PropTypes.bool,
|
|
403
361
|
fetchingSchemaError: PropTypes.bool,
|
|
404
362
|
eventContextTags: PropTypes.array,
|
|
405
|
-
intl: PropTypes.shape({
|
|
406
|
-
formatMessage: PropTypes.func.isRequired,
|
|
407
|
-
locale: PropTypes.string,
|
|
408
|
-
}).isRequired,
|
|
409
363
|
};
|
|
410
364
|
|
|
411
365
|
const mapStateToProps = createStructuredSelector({
|
|
@@ -219,106 +219,6 @@
|
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
}
|
|
222
|
-
|
|
223
|
-
.MOBILEPUSH {
|
|
224
|
-
.ant-card-body {
|
|
225
|
-
padding: 0;
|
|
226
|
-
background-color: $CAP_WHITE;
|
|
227
|
-
border-top: 1px solid $CAP_COLOR_16;
|
|
228
|
-
.ant-card-meta {
|
|
229
|
-
background-color: $CAP_G09;
|
|
230
|
-
padding: 0;
|
|
231
|
-
.ant-card-meta-description {
|
|
232
|
-
.mobilepush-container {
|
|
233
|
-
background-color: $CAP_WHITE;
|
|
234
|
-
padding: $CAP_SPACE_12;
|
|
235
|
-
.app-header {
|
|
236
|
-
color: #5D5D5D;
|
|
237
|
-
font-weight: 600;
|
|
238
|
-
padding: 0.285rem 0.571rem 0.285rem 0.571rem;
|
|
239
|
-
display: flex;
|
|
240
|
-
align-items: center;
|
|
241
|
-
justify-content: space-between;
|
|
242
|
-
.app-header-left{
|
|
243
|
-
display: flex;
|
|
244
|
-
align-items: center;
|
|
245
|
-
div {
|
|
246
|
-
word-break: break-word;
|
|
247
|
-
}
|
|
248
|
-
.app-icon {
|
|
249
|
-
width: 0.857rem;
|
|
250
|
-
height: 0.857rem;
|
|
251
|
-
border-radius: 50%;
|
|
252
|
-
background-color: #737070;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
.mobilepush-message {
|
|
257
|
-
padding-left: 1.65rem;
|
|
258
|
-
}
|
|
259
|
-
.mobilepush-image {
|
|
260
|
-
width: 100%;
|
|
261
|
-
height: 120px;
|
|
262
|
-
margin-top: 10px;
|
|
263
|
-
}
|
|
264
|
-
.mobilepush-image-padding {
|
|
265
|
-
padding-left: 1.65rem;
|
|
266
|
-
}
|
|
267
|
-
.scroll-container {
|
|
268
|
-
overflow-x: auto;
|
|
269
|
-
display: flex;
|
|
270
|
-
padding-top: $CAP_SPACE_06;
|
|
271
|
-
padding-right: $CAP_SPACE_06;
|
|
272
|
-
white-space: nowrap;
|
|
273
|
-
scrollbar-width: none; // Hide scrollbar in Firefox
|
|
274
|
-
&::-webkit-scrollbar {
|
|
275
|
-
display: none; // Hide scrollbar in Chrome/Safari/Opera
|
|
276
|
-
}
|
|
277
|
-
overflow: hidden;
|
|
278
|
-
height: 100%;
|
|
279
|
-
width: 100%;
|
|
280
|
-
margin-left: 1.65rem;
|
|
281
|
-
.whatsapp-carousel-container {
|
|
282
|
-
padding: $CAP_SPACE_04 0px $CAP_SPACE_08;
|
|
283
|
-
border-radius: $CAP_SPACE_06;
|
|
284
|
-
background-color: $CAP_WHITE;
|
|
285
|
-
width: 80%;
|
|
286
|
-
flex-shrink: 0;
|
|
287
|
-
white-space: pre-wrap;
|
|
288
|
-
word-break: break-word;
|
|
289
|
-
overflow: auto;
|
|
290
|
-
text-align: left;
|
|
291
|
-
margin: 0;
|
|
292
|
-
.whatsapp-carousel-card {
|
|
293
|
-
margin: $CAP_SPACE_02 $CAP_SPACE_02 $CAP_SPACE_01 $CAP_SPACE_02;
|
|
294
|
-
.whatsapp-carousel-body {
|
|
295
|
-
margin-bottom: $CAP_SPACE_08;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
.actions{
|
|
301
|
-
background-color: #ffffff;
|
|
302
|
-
height: auto;
|
|
303
|
-
padding: $CAP_SPACE_08;
|
|
304
|
-
text-align: center;
|
|
305
|
-
display: flex;
|
|
306
|
-
flex-direction: column;
|
|
307
|
-
align-items: center;
|
|
308
|
-
justify-content: center;
|
|
309
|
-
gap: $CAP_SPACE_08;
|
|
310
|
-
.action{
|
|
311
|
-
font-size: $FONT_SIZE_S;
|
|
312
|
-
font-weight: 600;
|
|
313
|
-
color: #1970DA;
|
|
314
|
-
height: 1.25rem;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
222
|
}
|
|
323
223
|
|
|
324
224
|
.create-new-link{
|
|
@@ -602,7 +502,7 @@
|
|
|
602
502
|
}
|
|
603
503
|
}
|
|
604
504
|
.iphone-push-message-Container{
|
|
605
|
-
top:
|
|
505
|
+
top: 8%;
|
|
606
506
|
.message-pop{
|
|
607
507
|
border-radius: 4px;
|
|
608
508
|
word-wrap: break-word;
|
|
@@ -12,7 +12,7 @@ import styled from 'styled-components';
|
|
|
12
12
|
import {injectIntl, intlShape, FormattedMessage } from 'react-intl';
|
|
13
13
|
import { createStructuredSelector } from 'reselect';
|
|
14
14
|
import moment from "moment";
|
|
15
|
-
|
|
15
|
+
import Bugsnag from "@bugsnag/js";
|
|
16
16
|
import get from 'lodash/get';
|
|
17
17
|
import isEmpty from 'lodash/isEmpty';
|
|
18
18
|
import isEqual from 'lodash/isEqual';
|
|
@@ -53,20 +53,23 @@ import {
|
|
|
53
53
|
CapSpin
|
|
54
54
|
} from "@capillarytech/cap-ui-library";
|
|
55
55
|
import { makeSelectTemplates, makeSelectTemplatesResponse } from './selectors';
|
|
56
|
-
import { makeSelectCreate as makeSelectCreateSms
|
|
56
|
+
import { makeSelectCreate as makeSelectCreateSms} from '../Sms/Create/selectors';
|
|
57
57
|
import { makeSelectCreate as makeSelectCreateMobilePush } from '../MobilePush/Create/selectors';
|
|
58
|
-
import {
|
|
58
|
+
import { makeSelectInApp } from '../InApp/selectors';
|
|
59
59
|
import { makeSelectEbill as makeSelectCreateEbill } from '../Ebill/selectors';
|
|
60
60
|
import { makeSelectEmail as makeSelectCreateEmail } from '../Email/selectors';
|
|
61
61
|
import { makeSelectEdit } from '../Sms/Edit/selectors';
|
|
62
62
|
import { makeSelectLine } from '../Line/Container/selectors';
|
|
63
63
|
import { makeSelectViber } from '../Viber/selectors';
|
|
64
64
|
import { makeSelectZalo } from '../Zalo/selectors';
|
|
65
|
-
import {
|
|
65
|
+
import { UserIsAuthenticated } from '../../utils/authWrapper';
|
|
66
|
+
import { getObjFromQueryParams } from '../../utils/v2common';
|
|
67
|
+
import messages from './messages';
|
|
68
|
+
import {checkUnicode} from '../../utils/smsCharCountV2';
|
|
66
69
|
import * as actions from './actions';
|
|
67
70
|
import * as smsActions from '../Sms/Create/actions';
|
|
68
71
|
import * as mobilepushActions from '../MobilePush/Create/actions';
|
|
69
|
-
import * as
|
|
72
|
+
import * as inAppActions from '../InApp/actions';
|
|
70
73
|
import * as smsEditActions from '../Sms/Edit/actions';
|
|
71
74
|
import * as ebillActions from '../Ebill/actions';
|
|
72
75
|
import * as emailActions from '../Email/actions';
|
|
@@ -76,16 +79,11 @@ import * as facebookActions from '../Facebook/actions';
|
|
|
76
79
|
import * as whatsappActions from '../Whatsapp/actions';
|
|
77
80
|
import * as rcsActions from '../Rcs/actions';
|
|
78
81
|
import * as zaloActions from '../Zalo/actions';
|
|
79
|
-
import * as inAppActions from '../InApp/actions';
|
|
80
|
-
import * as globalActions from '../Cap/actions';
|
|
81
|
-
import { makeSelectAuthenticated } from '../Cap/selectors';
|
|
82
|
-
import { UserIsAuthenticated } from '../../utils/authWrapper';
|
|
83
|
-
import { getObjFromQueryParams } from '../../utils/v2common';
|
|
84
|
-
import messages from './messages';
|
|
85
|
-
import {checkUnicode} from '../../utils/smsCharCountV2';
|
|
86
82
|
import CardGrid from '../../v2Components/CardGrid';
|
|
87
83
|
import config from '../../config/app';
|
|
88
84
|
import './_templates.scss';
|
|
85
|
+
import * as globalActions from '../Cap/actions';
|
|
86
|
+
import { makeSelectAuthenticated } from '../Cap/selectors';
|
|
89
87
|
import * as commonUtil from '../../utils/common';
|
|
90
88
|
import Pagination from '../../v2Components/Pagination';
|
|
91
89
|
import EmailPreview from '../../v2Components/EmailPreview';
|
|
@@ -109,7 +107,14 @@ import {
|
|
|
109
107
|
STATUS as WHATSAPP_STATUS,
|
|
110
108
|
WHATSAPP_STATUSES,
|
|
111
109
|
HOST_GUPSHUP,
|
|
110
|
+
HOST_HAPTIC,
|
|
112
111
|
CATEGORY_OPTIONS_MAP,
|
|
112
|
+
HOST_TWILIO,
|
|
113
|
+
TWILIO_CATEGORY_OPTIONS,
|
|
114
|
+
KARIX_GUPSHUP_CATEGORY_OPTIONS,
|
|
115
|
+
ICS_CATEGORY_OPTIONS,
|
|
116
|
+
HAPTIC_CATEGORY_OPTIONS,
|
|
117
|
+
HOST_ICS,
|
|
113
118
|
IMAGE,
|
|
114
119
|
VIDEO,
|
|
115
120
|
} from '../Whatsapp/constants';
|
|
@@ -144,8 +149,6 @@ import { compose } from 'redux';
|
|
|
144
149
|
import { v2TemplateSaga } from './sagas';
|
|
145
150
|
import injectSaga from '../../utils/injectSaga';
|
|
146
151
|
import { DAEMON } from '@capillarytech/vulcan-react-sdk/utils/sagaInjectorTypes';
|
|
147
|
-
import { v2MobilePushSagas } from '../MobilePushNew/sagas';
|
|
148
|
-
const withMobilePushNewSaga = injectSaga({ key: 'mobilePushNew', saga: v2MobilePushSagas, mode: DAEMON });
|
|
149
152
|
|
|
150
153
|
const { timeTracker } = GA;
|
|
151
154
|
const {CapCustomCardList} = CapCustomCard;
|
|
@@ -234,29 +237,28 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
234
237
|
searchedZaloTemplates: [],
|
|
235
238
|
searchingZaloTemplate: false,
|
|
236
239
|
zaloPreviewItemId: {},
|
|
237
|
-
uploadInProgress: false,
|
|
238
|
-
deleteConfirmationModal: false,
|
|
239
|
-
templateToDelete: {},
|
|
240
|
-
edmDefaultTemplateSelection: false,
|
|
241
|
-
edmSelectedTemplateId: '',
|
|
242
|
-
edmEmailPreview: false,
|
|
243
|
-
emailPreviewDevice: 'desktop',
|
|
244
|
-
// Add flag to prevent duplicate API calls
|
|
245
|
-
isProcessingEditResponse: false,
|
|
246
240
|
};
|
|
247
|
-
|
|
248
|
-
this.createTemplate = this.createTemplate.bind(this);
|
|
249
|
-
this.searchTemplate = this.searchTemplate.bind(this);
|
|
250
|
-
this.handleSortBy = this.handleSortBy.bind(this);
|
|
251
|
-
this.duplicateTemplate = this.duplicateTemplate.bind(this);
|
|
252
|
-
this.deleteTemplate = this.deleteTemplate.bind(this);
|
|
241
|
+
|
|
253
242
|
this.handleOnHoverItem = this.handleOnHoverItem.bind(this);
|
|
254
243
|
this.handleOnItemClick = this.handleOnItemClick.bind(this);
|
|
255
244
|
this.handleEditClick = this.handleEditClick.bind(this);
|
|
256
245
|
this.handlePreviewClick = this.handlePreviewClick.bind(this);
|
|
246
|
+
this.createTemplate = this.createTemplate.bind(this);
|
|
247
|
+
this.duplicateTemplate = this.duplicateTemplate.bind(this);
|
|
248
|
+
this.deleteTemplate = this.deleteTemplate.bind(this);
|
|
249
|
+
this.togglePreview = this.togglePreview.bind(this);
|
|
250
|
+
this.searchTemplate = this.searchTemplate.bind(this);
|
|
251
|
+
this.handleSortBy = this.handleSortBy.bind(this);
|
|
252
|
+
this.getCurrentWindow = this.getCurrentWindow.bind(this);
|
|
257
253
|
this.handleFrameTasks = this.handleFrameTasks.bind(this);
|
|
254
|
+
this.startTemplateCreation = this.startTemplateCreation.bind(this);
|
|
255
|
+
this.startLoading = this.startLoading.bind(this);
|
|
256
|
+
this.prepareWeChatPreviewData = this.prepareWeChatPreviewData.bind(this);
|
|
257
|
+
this.prepareWeChatMappedPreviewData = this.prepareWeChatMappedPreviewData.bind(this);
|
|
258
258
|
this.onAccountSelect = this.onAccountSelect.bind(this);
|
|
259
|
-
this.
|
|
259
|
+
this.prepareMobilePushPreviewData = this.prepareMobilePushPreviewData.bind(this);
|
|
260
|
+
this.menuOnClickEvent = this.menuOnClickEvent.bind(this);
|
|
261
|
+
this.delayTimer = 0;
|
|
260
262
|
}
|
|
261
263
|
|
|
262
264
|
// This function is to map the selected source account identifier and the connectionProperties data of domainPropertiesData object to get the hostName.
|
|
@@ -265,7 +267,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
265
267
|
this.setState({ hostName: '' });
|
|
266
268
|
return '';
|
|
267
269
|
}
|
|
268
|
-
|
|
270
|
+
|
|
269
271
|
const domainHostName = domainPropertiesData?.find(({ domainProperties }) => {
|
|
270
272
|
const {
|
|
271
273
|
connectionProperties: { account_sid, wabaId, userid, sourceAccountIdentifier, oa_id } = {},
|
|
@@ -274,7 +276,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
274
276
|
// wabaId, user_id, account_sid are for Karix, Gupshup, and Twilio (Whatsapp) respectively and oa_id is for Zalo.
|
|
275
277
|
return [account_sid, wabaId, userid, oa_id, sourceAccountIdentifier].includes(selectedSourceAccountIdentifier);
|
|
276
278
|
})?.domainProperties?.hostName || '';
|
|
277
|
-
|
|
279
|
+
|
|
278
280
|
this.setState({ hostName: domainHostName });
|
|
279
281
|
return domainHostName;
|
|
280
282
|
}
|
|
@@ -396,7 +398,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
396
398
|
window.addEventListener("message", this.handleFrameTasks);
|
|
397
399
|
}
|
|
398
400
|
componentWillReceiveProps(nextProps = {}) {
|
|
399
|
-
|
|
400
401
|
const params = {
|
|
401
402
|
name: this.state.searchText,
|
|
402
403
|
sortBy: this.state.sortBy,
|
|
@@ -566,31 +567,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
566
567
|
this.props.lineActions.clearCreateResponse();
|
|
567
568
|
}
|
|
568
569
|
|
|
569
|
-
// Check for MobilePushNew edit response - prevent duplicate calls
|
|
570
|
-
if (selectedChannel === "mobilepush" && nextProps.MobilePushNew && nextProps.MobilePushNew.editResponse && nextProps.MobilePushNew.editResponse.templateId && nextProps.MobilePushNew.editResponse.templateId !== '' && !this.state.isProcessingEditResponse) {
|
|
571
|
-
// Set flag to prevent duplicate processing
|
|
572
|
-
this.setState({ isProcessingEditResponse: true });
|
|
573
|
-
|
|
574
|
-
const message = `${this.state.channel} ${this.props.intl.formatMessage(messages.templateUpdateSuccess)}`;
|
|
575
|
-
|
|
576
|
-
CapNotification.success({
|
|
577
|
-
key: 'editSuccess',
|
|
578
|
-
message
|
|
579
|
-
});
|
|
580
|
-
|
|
581
|
-
this.getAllTemplates({params, resetPage: true});
|
|
582
|
-
|
|
583
|
-
this.props.mobilePushNewActions.clearData();
|
|
584
|
-
|
|
585
|
-
this.props.mobilePushNewActions.clearEditResponse();
|
|
586
|
-
|
|
587
|
-
// Reset flag after a delay to allow for next edit
|
|
588
|
-
setTimeout(() => {
|
|
589
|
-
this.setState({ isProcessingEditResponse: false });
|
|
590
|
-
}, 1000);
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
|
|
594
570
|
|
|
595
571
|
if (nextProps.Create && this.props.Create && nextProps.Create.createTemplateError && !isEqual(nextProps.Create.createTemplateError, this.props.Create.createTemplateError)) {
|
|
596
572
|
const message = this.props.intl.formatMessage(messages.somethingWentWrong);
|
|
@@ -861,7 +837,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
861
837
|
if (this.state.previewOpen) {
|
|
862
838
|
creativesParams.mode = 'preview';
|
|
863
839
|
creativesParams = {...creativesParams, ...this.state.previewTemplate};
|
|
864
|
-
|
|
840
|
+
|
|
865
841
|
}
|
|
866
842
|
return creativesParams;
|
|
867
843
|
}
|
|
@@ -1262,82 +1238,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1262
1238
|
break;
|
|
1263
1239
|
}
|
|
1264
1240
|
case MOBILE_PUSH:
|
|
1265
|
-
if (!commonUtil.hasNewMobilePushFeatureEnabled()) {
|
|
1266
|
-
templateData.content = template;
|
|
1267
|
-
} else {
|
|
1268
|
-
const mpushData = get(template, 'versions.base', template);
|
|
1269
|
-
const androidData = get(mpushData, 'ANDROID') || get(mpushData, 'androidContent');
|
|
1270
|
-
const iosData = get(mpushData, 'IOS') || get(mpushData, 'iosContent');
|
|
1271
|
-
let mpushListingData = androidData;
|
|
1272
|
-
if (isEmpty(androidData) || !androidData?.title) {
|
|
1273
|
-
mpushListingData = iosData;
|
|
1274
|
-
};
|
|
1275
|
-
const { title, message, expandableDetails: { style = '', image, carouselData = [], ctas = [] } = {} } = mpushListingData || {};
|
|
1276
|
-
templateData.content = (
|
|
1277
|
-
<div className='mobilepush-container'>
|
|
1278
|
-
<div className="app-header">
|
|
1279
|
-
<div className="app-header-left">
|
|
1280
|
-
<span className="app-icon">{""}</span>
|
|
1281
|
-
<CapLabel type="label4">{title}</CapLabel>
|
|
1282
|
-
</div>
|
|
1283
|
-
</div>
|
|
1284
|
-
<CapLabel className="mobilepush-message" type="label1">{message}</CapLabel>
|
|
1285
|
-
{style === 'BIG_PICTURE' && (
|
|
1286
|
-
<CapImage src={image} className="mobilepush-image mobilepush-image-padding" />
|
|
1287
|
-
)}
|
|
1288
|
-
{(style === 'MANUAL_CAROUSEL' || style === 'AUTO_CAROUSEL' || style === 'FILMSTRIP_CAROUSEL') && (
|
|
1289
|
-
<div className="scroll-container">
|
|
1290
|
-
{carouselData.map((data, index) => {
|
|
1291
|
-
return (
|
|
1292
|
-
<div
|
|
1293
|
-
key={`carousel-${index + 1}`}
|
|
1294
|
-
className="whatsapp-carousel-container"
|
|
1295
|
-
role="group"
|
|
1296
|
-
>
|
|
1297
|
-
<div className="whatsapp-carousel-card">
|
|
1298
|
-
{data?.mediaType === IMAGE.toLowerCase() && (
|
|
1299
|
-
<CapImage
|
|
1300
|
-
src={data?.imageUrl ? data?.imageUrl : whatsappImageEmptyPreview}
|
|
1301
|
-
className="whatsapp-image"
|
|
1302
|
-
/>
|
|
1303
|
-
)}
|
|
1304
|
-
{data?.mediaType === VIDEO.toLowerCase() && (
|
|
1305
|
-
<div className="video-preview">
|
|
1306
|
-
<CapImage
|
|
1307
|
-
src={data?.videoPreviewImg ? data?.videoPreviewImg : whatsappVideoEmptyPreview}
|
|
1308
|
-
className="whatsapp-image"
|
|
1309
|
-
/>
|
|
1310
|
-
<div className="icon-position">
|
|
1311
|
-
<CapImage
|
|
1312
|
-
className="video-icon"
|
|
1313
|
-
src={videoPlay}
|
|
1314
|
-
/>
|
|
1315
|
-
</div>
|
|
1316
|
-
</div>
|
|
1317
|
-
)}
|
|
1318
|
-
</div>
|
|
1319
|
-
</div>
|
|
1320
|
-
)
|
|
1321
|
-
})}
|
|
1322
|
-
</div>
|
|
1323
|
-
)}
|
|
1324
|
-
{ctas.length > 0 && (
|
|
1325
|
-
<div className="actions">
|
|
1326
|
-
{ctas.map((cta) => (
|
|
1327
|
-
<span
|
|
1328
|
-
className="action"
|
|
1329
|
-
key={`action-${cta?.actionText}`}
|
|
1330
|
-
>
|
|
1331
|
-
{cta?.actionText && cta?.actionText.toUpperCase()}
|
|
1332
|
-
</span>
|
|
1333
|
-
))}
|
|
1334
|
-
</div>
|
|
1335
|
-
)}
|
|
1336
|
-
</div>
|
|
1337
|
-
);
|
|
1338
|
-
templateData.isNewMobilePush = commonUtil.hasNewMobilePushFeatureEnabled();
|
|
1339
|
-
}
|
|
1340
|
-
break;
|
|
1341
1241
|
case INAPP:
|
|
1342
1242
|
templateData.content = template;
|
|
1343
1243
|
break;
|
|
@@ -2153,18 +2053,12 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2153
2053
|
delete duplicateObj._id;
|
|
2154
2054
|
|
|
2155
2055
|
if (this.state.channel.toLowerCase() === "mobilepush") {
|
|
2156
|
-
const params = {
|
|
2157
|
-
name: this.state.searchText,
|
|
2158
|
-
sortBy: this.state.sortBy,
|
|
2159
|
-
};
|
|
2160
2056
|
duplicateObj.definition.accountId = this.props.Templates.selectedWeChatAccount.id;
|
|
2161
|
-
this.props.
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
this.props.mobilePushNewActions.clearCreateResponse();
|
|
2167
|
-
}
|
|
2057
|
+
this.props.mobilepushActions.createTemplate(duplicateObj, () => {
|
|
2058
|
+
const message = `${this.state.channel} ${this.props.intl.formatMessage(messages.templateDuplicateSuccess)}`;
|
|
2059
|
+
CapNotification.success({key: 'duplicateSuccess', message});
|
|
2060
|
+
this.getAllTemplates({params: {}}, true);
|
|
2061
|
+
this.props.mobilepushActions.clearCreateResponse();
|
|
2168
2062
|
});
|
|
2169
2063
|
} else if (this.state.channel.toLowerCase() === "inapp") {
|
|
2170
2064
|
duplicateObj.definition.accountId = this.props.Templates.selectedWeChatAccount.id;
|
|
@@ -2916,7 +2810,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2916
2810
|
break;
|
|
2917
2811
|
}
|
|
2918
2812
|
let showNoAccountHeader = isEmpty(weCrmAccounts) && !fetchingWeCrmAccounts;
|
|
2919
|
-
// Zalo and Whatsapp has dependencies on domainProperties to get the hostName. Show loader until the domainProperties are fetched.
|
|
2813
|
+
// Zalo and Whatsapp has dependencies on domainProperties to get the hostName. Show loader until the domainProperties are fetched.
|
|
2920
2814
|
const isDomainPropertiesLoading = [WHATSAPP, ZALO].includes(channel) && senderDetails?.status === "REQUEST";
|
|
2921
2815
|
if (channel === FACEBOOK && !isEmpty(campaignSettings) ) {
|
|
2922
2816
|
const fbSetting = get(campaignSettings, 'accountSettings.socialAccountSettings.facebookAccountSettings', []);
|
|
@@ -3505,7 +3399,6 @@ Templates.propTypes = {
|
|
|
3505
3399
|
actions: PropTypes.object.isRequired,
|
|
3506
3400
|
smsActions: PropTypes.object,
|
|
3507
3401
|
mobilepushActions: PropTypes.object,
|
|
3508
|
-
mobilePushNewActions: PropTypes.object,
|
|
3509
3402
|
smsEditActions: PropTypes.object,
|
|
3510
3403
|
ebillActions: PropTypes.object,
|
|
3511
3404
|
emailActions: PropTypes.object,
|
|
@@ -3538,7 +3431,6 @@ const mapStateToProps = createStructuredSelector({
|
|
|
3538
3431
|
TemplatesList: makeSelectTemplatesResponse(),
|
|
3539
3432
|
Create: makeSelectCreateSms(),
|
|
3540
3433
|
CreateMobilePush: makeSelectCreateMobilePush(),
|
|
3541
|
-
MobilePushNew: makeSelectMobilePushNew(),
|
|
3542
3434
|
CreateEbill: makeSelectCreateEbill(),
|
|
3543
3435
|
Edit: makeSelectEdit(),
|
|
3544
3436
|
EmailCreate: makeSelectCreateEmail(),
|
|
@@ -3554,7 +3446,6 @@ function mapDispatchToProps(dispatch) {
|
|
|
3554
3446
|
actions: bindActionCreators(actions, dispatch),
|
|
3555
3447
|
smsActions: bindActionCreators(smsActions, dispatch),
|
|
3556
3448
|
mobilepushActions: bindActionCreators(mobilepushActions, dispatch),
|
|
3557
|
-
mobilePushNewActions: bindActionCreators(mobilePushNewActions, dispatch),
|
|
3558
3449
|
inAppActions: bindActionCreators(inAppActions, dispatch),
|
|
3559
3450
|
smsEditActions: bindActionCreators(smsEditActions, dispatch),
|
|
3560
3451
|
ebillActions: bindActionCreators(ebillActions, dispatch),
|
|
@@ -3578,7 +3469,6 @@ const withSaga = injectSaga({ key: 'templates', saga: v2TemplateSaga, mode: DAEM
|
|
|
3578
3469
|
export default compose(
|
|
3579
3470
|
UserIsAuthenticated,
|
|
3580
3471
|
withSaga,
|
|
3581
|
-
withMobilePushNewSaga,
|
|
3582
3472
|
withReducer,
|
|
3583
3473
|
withConnect,
|
|
3584
3474
|
)(injectIntl(Templates));
|
|
@@ -538,12 +538,4 @@ export default defineMessages({
|
|
|
538
538
|
id: `${scope}.zaloOnlyApprovedTemplates`,
|
|
539
539
|
defaultMessage: 'Only enabled/approved templates are shown here',
|
|
540
540
|
},
|
|
541
|
-
"templateCreateSuccess": {
|
|
542
|
-
id: `${scope}.templateCreateSuccess`,
|
|
543
|
-
defaultMessage: 'Template created successfully',
|
|
544
|
-
},
|
|
545
|
-
"templateUpdateSuccess": {
|
|
546
|
-
id: `${scope}.templateUpdateSuccess`,
|
|
547
|
-
defaultMessage: 'Template updated successfully',
|
|
548
|
-
},
|
|
549
541
|
});
|
|
@@ -9,7 +9,6 @@ import { saveCdnConfigs, removeAllCdnLocalStorageItems } from '../../utils/cdnTr
|
|
|
9
9
|
import { COPY_OF } from '../../containers/App/constants';
|
|
10
10
|
import { ZALO_TEMPLATE_INFO_REQUEST } from '../Zalo/constants';
|
|
11
11
|
import { getTemplateInfoById } from '../Zalo/saga';
|
|
12
|
-
import { watchCreateTemplate } from '../MobilePushNew/sagas';
|
|
13
12
|
// Individual exports for testing
|
|
14
13
|
export function* getAllTemplates(channel, queryParams) {
|
|
15
14
|
try {
|
|
@@ -253,7 +252,6 @@ export function* v2TemplateSaga() {
|
|
|
253
252
|
watchFetchWeCrmAccounts(),
|
|
254
253
|
watchGetSenderDetails(),
|
|
255
254
|
watchForGetTemplateInfoById(),
|
|
256
|
-
// watchCreateTemplate(),
|
|
257
255
|
]);
|
|
258
256
|
}
|
|
259
257
|
|