@capillarytech/creatives-library 7.17.79 → 7.17.81-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/containers/App/constants.js +0 -1
- package/package.json +1 -1
- package/utils/common.js +9 -0
- package/utils/tests/common.test.js +14 -1
- package/v2Components/EmailMobilePreview/index.js +4 -2
- package/v2Components/EmailPreviewV2/index.js +4 -3
- package/v2Components/EmailPreviewV2/tests/__snapshots__/index.test.js.snap +0 -3
- package/v2Containers/InApp/constants.js +0 -0
- package/v2Containers/InApp/index.js +499 -0
- package/v2Containers/InApp/index.scss +0 -0
- package/v2Containers/InApp/messages.js +0 -0
package/package.json
CHANGED
package/utils/common.js
CHANGED
|
@@ -51,6 +51,15 @@ export function removeLinksFromHtmlContent(content) {
|
|
|
51
51
|
return copyContent;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
export function iframePreviewAdjustWidth(content) {
|
|
55
|
+
const doc = document.createElement('html');
|
|
56
|
+
doc.innerHTML = content;
|
|
57
|
+
let copyContent = doc.cloneNode(true).outerHTML;
|
|
58
|
+
copyContent = copyContent.replace(/<img /g, '<img width="310" ');
|
|
59
|
+
doc.remove();
|
|
60
|
+
return copyContent;
|
|
61
|
+
}
|
|
62
|
+
|
|
54
63
|
export const hasStore2DoorFeature = Auth.hasFeatureAccess.bind(
|
|
55
64
|
null,
|
|
56
65
|
STORE2DOOR_PLUS_ENABLED,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { FormattedMessage } from 'react-intl';
|
|
3
3
|
import "@testing-library/jest-dom";
|
|
4
|
-
import { filterTags, getTreeStructuredTags, handleInjectedData, intlKeyGenerator, bytes2Size, getUserNameById } from "../common";
|
|
4
|
+
import { filterTags, getTreeStructuredTags, handleInjectedData, intlKeyGenerator, bytes2Size, getUserNameById, iframePreviewAdjustWidth } from "../common";
|
|
5
5
|
import * as mockdata from "./common.mockdata";
|
|
6
6
|
|
|
7
7
|
describe("getTreeStructuredTags test", () => {
|
|
@@ -208,3 +208,16 @@ describe('bytes2Size', () => {
|
|
|
208
208
|
expect(bytes2Size(1024, -3)).toBe('1 KB');
|
|
209
209
|
});
|
|
210
210
|
});
|
|
211
|
+
|
|
212
|
+
describe('iframeAdjustWidth', () => {
|
|
213
|
+
it("should Add the width in iframe image", () => {
|
|
214
|
+
const data = [
|
|
215
|
+
<head>
|
|
216
|
+
<meta httpEquiv="Content-Type" content="text/html; charset=utf-8">
|
|
217
|
+
<meta name="viewport" content="width=device-width">
|
|
218
|
+
</meta></meta></head>,
|
|
219
|
+
|
|
220
|
+
];
|
|
221
|
+
expect(iframePreviewAdjustWidth(data)).toBe("<html><head></head><body>[object Object]</body></html>");
|
|
222
|
+
});
|
|
223
|
+
});
|
|
@@ -18,7 +18,7 @@ import EmailPreviewV2 from '../EmailPreviewV2';
|
|
|
18
18
|
import messages from '../EmailPreviewV2/messages';
|
|
19
19
|
import './index.scss';
|
|
20
20
|
import mobileBody from '../../assets/DeviceForEmail.png';
|
|
21
|
-
import { removeLinksFromHtmlContent } from './../../utils/common';
|
|
21
|
+
import { iframePreviewAdjustWidth, removeLinksFromHtmlContent } from './../../utils/common';
|
|
22
22
|
import {selectTemplateContent} from '../../containers/Templates/selectors';
|
|
23
23
|
import * as templateActions from '../../containers/Templates/actions';
|
|
24
24
|
|
|
@@ -68,6 +68,8 @@ class EmailMobilePreview extends React.Component {
|
|
|
68
68
|
templateSubject,
|
|
69
69
|
} = this.props;
|
|
70
70
|
const copyContent = templateContent && removeLinksFromHtmlContent(templateContent);
|
|
71
|
+
const updateCopyContent = templateContent && iframePreviewAdjustWidth(copyContent);
|
|
72
|
+
|
|
71
73
|
const { showAllDevices } = this.state;
|
|
72
74
|
|
|
73
75
|
const emailSubjectLabel = templateSubject && (
|
|
@@ -98,7 +100,7 @@ class EmailMobilePreview extends React.Component {
|
|
|
98
100
|
<img src={mobileBody} alt="capillary" width="386" />
|
|
99
101
|
<div className={`${messageContainerName} ${emailSubjectLabel ? 'with-subject' : ''}`}>
|
|
100
102
|
{emailSubjectLabel}
|
|
101
|
-
<iframe srcDoc={
|
|
103
|
+
<iframe srcDoc={updateCopyContent} {...deviceAspectRatio.mobile} >
|
|
102
104
|
<p><FormattedMessage {...messages.noIframeSupport}/></p>
|
|
103
105
|
</iframe>
|
|
104
106
|
</div>
|
|
@@ -19,7 +19,7 @@ import messages from './messages';
|
|
|
19
19
|
import './_emailPreviewV2.scss';
|
|
20
20
|
import tabletBody from '../../assets/iPad.svg';
|
|
21
21
|
import mobileBody from '../../assets/DeviceForEmail.png';
|
|
22
|
-
import { removeLinksFromHtmlContent } from './../../utils/common';
|
|
22
|
+
import { iframePreviewAdjustWidth, removeLinksFromHtmlContent } from './../../utils/common';
|
|
23
23
|
|
|
24
24
|
import {selectTemplateContent} from '../../v2Containers/Templates/selectors';
|
|
25
25
|
import * as templateActions from '../../v2Containers/Templates/actions';
|
|
@@ -72,7 +72,8 @@ export class EmailPreviewV2 extends React.Component {
|
|
|
72
72
|
let messageContainerName = '';
|
|
73
73
|
const {currentDevice} = this.state;
|
|
74
74
|
const { templateContent, templateData = {}, templateSubject } = this.props;
|
|
75
|
-
const copyContent = removeLinksFromHtmlContent(templateContent);
|
|
75
|
+
const copyContent = templateContent && removeLinksFromHtmlContent(templateContent);
|
|
76
|
+
const updateCopyContent = templateContent && iframePreviewAdjustWidth(copyContent);
|
|
76
77
|
let subjectClassName = 'email-subject-desktop';
|
|
77
78
|
if (currentDevice === devices.tablet) {
|
|
78
79
|
messageContainerName = 'tablet-message-container';
|
|
@@ -88,7 +89,7 @@ export class EmailPreviewV2 extends React.Component {
|
|
|
88
89
|
);
|
|
89
90
|
const iframeDiv = (<div className={`${messageContainerName}`}>
|
|
90
91
|
{emailSubjectLabel}
|
|
91
|
-
<iframe srcDoc={
|
|
92
|
+
<iframe srcDoc={updateCopyContent} {...deviceAspectRatio[currentDevice](emailSubject)} >
|
|
92
93
|
<p><FormattedMessage {...messages.browserDoesntSupportIframe} /></p>
|
|
93
94
|
</iframe>
|
|
94
95
|
</div>);
|
|
@@ -31,7 +31,6 @@ exports[`<EmailPreviewV2 /> <EmailPreviewV2 /> without the templateData 1`] = `
|
|
|
31
31
|
>
|
|
32
32
|
<iframe
|
|
33
33
|
height="500"
|
|
34
|
-
srcDoc="<html><head></head><body>undefined</body></html>"
|
|
35
34
|
width="1024"
|
|
36
35
|
>
|
|
37
36
|
<p>
|
|
@@ -67,7 +66,6 @@ exports[`<EmailPreviewV2 /> <EmailPreviewV2 /> without the templateData 1`] = `
|
|
|
67
66
|
>
|
|
68
67
|
<iframe
|
|
69
68
|
height="500"
|
|
70
|
-
srcDoc="<html><head></head><body>undefined</body></html>"
|
|
71
69
|
width="1024"
|
|
72
70
|
>
|
|
73
71
|
<p>
|
|
@@ -104,7 +102,6 @@ exports[`<EmailPreviewV2 /> <EmailPreviewV2 /> without the templateData 1`] = `
|
|
|
104
102
|
>
|
|
105
103
|
<iframe
|
|
106
104
|
height="500"
|
|
107
|
-
srcDoc="<html><head></head><body>undefined</body></html>"
|
|
108
105
|
width="1024"
|
|
109
106
|
>
|
|
110
107
|
<p>
|
|
File without changes
|
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
/* eslint-disable camelcase */
|
|
2
|
+
/* eslint-disable react/jsx-indent */
|
|
3
|
+
import React, { useState, useEffect } from 'react';
|
|
4
|
+
import { bindActionCreators } from 'redux';
|
|
5
|
+
import { createStructuredSelector } from 'reselect';
|
|
6
|
+
import { injectIntl, FormattedMessage } from 'react-intl';
|
|
7
|
+
import { get, isEmpty } from 'lodash';
|
|
8
|
+
import styled from 'styled-components';
|
|
9
|
+
import CapSpin from '@capillarytech/cap-ui-library/CapSpin';
|
|
10
|
+
import CapRow from '@capillarytech/cap-ui-library/CapRow';
|
|
11
|
+
import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
|
|
12
|
+
import CapLabel from '@capillarytech/cap-ui-library/CapLabel';
|
|
13
|
+
import CapAlert from '@capillarytech/cap-ui-library/CapAlert';
|
|
14
|
+
import CapInput from '@capillarytech/cap-ui-library/CapInput';
|
|
15
|
+
import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
|
|
16
|
+
import CapHeader from '@capillarytech/cap-ui-library/CapHeader';
|
|
17
|
+
import CapNotification from '@capillarytech/cap-ui-library/CapNotification';
|
|
18
|
+
import CapTooltip from '@capillarytech/cap-ui-library/CapTooltip';
|
|
19
|
+
import CapButton from '@capillarytech/cap-ui-library/CapButton';
|
|
20
|
+
import {
|
|
21
|
+
CAP_SPACE_16,
|
|
22
|
+
CAP_SPACE_24,
|
|
23
|
+
CAP_SPACE_32,
|
|
24
|
+
CAP_WHITE,
|
|
25
|
+
} from '@capillarytech/cap-ui-library/styled/variables';
|
|
26
|
+
import { makeSelectZalo, makeSelectAccount } from './selectors';
|
|
27
|
+
import { makeSelectMetaEntities, setInjectedTags } from '../Cap/selectors';
|
|
28
|
+
import * as zaloActions from './actions';
|
|
29
|
+
import './index.scss';
|
|
30
|
+
import {
|
|
31
|
+
SUCCESS_ALERT,
|
|
32
|
+
REQUEST,
|
|
33
|
+
EMBEDDED,
|
|
34
|
+
DEFAULT,
|
|
35
|
+
TAG,
|
|
36
|
+
FULL,
|
|
37
|
+
ALL,
|
|
38
|
+
OUTBOUND,
|
|
39
|
+
LIBRARY,
|
|
40
|
+
ERROR_ALERT,
|
|
41
|
+
WARNING_ALERT,
|
|
42
|
+
ZALO_STATUSES,
|
|
43
|
+
} from './constants';
|
|
44
|
+
import { SMS, ZALO } from '../CreativesContainer/constants';
|
|
45
|
+
import messages from './messages';
|
|
46
|
+
import globalMessages from '../Cap/messages';
|
|
47
|
+
import withCreatives from '../../hoc/withCreatives';
|
|
48
|
+
import TagList from '../TagList';
|
|
49
|
+
import { validateTags } from '../../utils/tagValidations';
|
|
50
|
+
import TemplatePreview from '../../v2Components/TemplatePreview';
|
|
51
|
+
|
|
52
|
+
export const InApp = (props) => {
|
|
53
|
+
const {
|
|
54
|
+
intl,
|
|
55
|
+
actions,
|
|
56
|
+
isFullMode,
|
|
57
|
+
templateData = {},
|
|
58
|
+
editData = {},
|
|
59
|
+
accountData: { selectedZaloAccount = {} } = {},
|
|
60
|
+
globalActions,
|
|
61
|
+
location,
|
|
62
|
+
getDefaultTags,
|
|
63
|
+
supportedTags,
|
|
64
|
+
metaEntities,
|
|
65
|
+
injectedTags,
|
|
66
|
+
getFormData,
|
|
67
|
+
selectedOfferDetails,
|
|
68
|
+
} = props || {};
|
|
69
|
+
const { formatMessage } = intl;
|
|
70
|
+
const [oa_id, setOaId] = useState('');
|
|
71
|
+
const [token, setToken] = useState('');
|
|
72
|
+
const [username, setUsername] = useState('');
|
|
73
|
+
const [templateName, setTemplateName] = useState('');
|
|
74
|
+
const [templateId, setTemplateId] = useState('');
|
|
75
|
+
const [templateListParams, setTemplateListParams] = useState([]);
|
|
76
|
+
const [templatePreviewUrl, setTemplatePreviewUrl] = useState('');
|
|
77
|
+
const [templateStatus, setZaloTemplateStatus] = useState(
|
|
78
|
+
ZALO_STATUSES.ENABLE,
|
|
79
|
+
);
|
|
80
|
+
const [tags, updateTags] = useState([]);
|
|
81
|
+
const [textAreaId, updateTextAreaId] = useState('');
|
|
82
|
+
const { zaloTemplateInfoValue = {}, zaloTemplateInfoStatus = REQUEST } =
|
|
83
|
+
editData;
|
|
84
|
+
const {
|
|
85
|
+
_id = '',
|
|
86
|
+
accountId = '',
|
|
87
|
+
zaloAccountId = '',
|
|
88
|
+
accountName = '',
|
|
89
|
+
templateConfigs: { id = '', varMapped = {} } = {},
|
|
90
|
+
token: zaloToken = '',
|
|
91
|
+
} = templateData;
|
|
92
|
+
const zaloTempId = _id || id;
|
|
93
|
+
const ZaloFooter = styled.div`
|
|
94
|
+
background-color: ${CAP_WHITE};
|
|
95
|
+
position: fixed;
|
|
96
|
+
bottom: 0;
|
|
97
|
+
width: 100%;
|
|
98
|
+
margin-left: -32px;
|
|
99
|
+
padding: ${CAP_SPACE_32} ${CAP_SPACE_24};
|
|
100
|
+
z-index: 1;
|
|
101
|
+
|
|
102
|
+
.ant-btn {
|
|
103
|
+
margin-right: ${CAP_SPACE_16};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
`;
|
|
107
|
+
//gets account details
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
if (!isEmpty(selectedZaloAccount) || !isEmpty(templateData)) {
|
|
110
|
+
const {
|
|
111
|
+
sourceAccountIdentifier = '',
|
|
112
|
+
configs: { token: accessToken = '' } = {},
|
|
113
|
+
name = '',
|
|
114
|
+
} = selectedZaloAccount;
|
|
115
|
+
const oaId = getDefaultTags === OUTBOUND ? zaloAccountId : accountId;
|
|
116
|
+
setOaId(sourceAccountIdentifier || oaId);
|
|
117
|
+
setToken(accessToken || zaloToken);
|
|
118
|
+
setUsername(name || accountName);
|
|
119
|
+
}
|
|
120
|
+
}, [selectedZaloAccount, templateData]);
|
|
121
|
+
|
|
122
|
+
//gets template details
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
if (zaloTempId && oa_id && token && username) {
|
|
125
|
+
actions.getTemplateInfoById({
|
|
126
|
+
username,
|
|
127
|
+
oa_id,
|
|
128
|
+
token,
|
|
129
|
+
id: zaloTempId,
|
|
130
|
+
actionCallback,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
//cleanup code
|
|
134
|
+
return () => {
|
|
135
|
+
actions.resetTemplateInfoData();
|
|
136
|
+
};
|
|
137
|
+
}, [zaloTempId, oa_id, token, username]);
|
|
138
|
+
|
|
139
|
+
const handleSetValues = (paramsData = []) =>
|
|
140
|
+
paramsData.map((paramData) => {
|
|
141
|
+
for (const key in varMapped) {
|
|
142
|
+
if (paramData?.name === key) {
|
|
143
|
+
paramData.value = varMapped[key];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return paramData;
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
const setDataForEdit = (setValues) => {
|
|
150
|
+
const {
|
|
151
|
+
name = '',
|
|
152
|
+
_id: zaloId = '',
|
|
153
|
+
versions: {
|
|
154
|
+
base: {
|
|
155
|
+
content: {
|
|
156
|
+
zalo: {
|
|
157
|
+
listParams: paramsData = [],
|
|
158
|
+
previewUrl = '',
|
|
159
|
+
status = '',
|
|
160
|
+
} = {},
|
|
161
|
+
} = {},
|
|
162
|
+
} = {},
|
|
163
|
+
} = {},
|
|
164
|
+
} = zaloTemplateInfoValue;
|
|
165
|
+
setTemplateName(name);
|
|
166
|
+
setTemplateId(zaloId);
|
|
167
|
+
setTemplateListParams(setValues ? handleSetValues(paramsData) : paramsData);
|
|
168
|
+
setTemplatePreviewUrl(previewUrl);
|
|
169
|
+
setZaloTemplateStatus(status);
|
|
170
|
+
updateTextAreaId(paramsData[0]?.name);
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
useEffect(() => {
|
|
174
|
+
setDataForEdit(false);
|
|
175
|
+
}, [zaloTemplateInfoValue]);
|
|
176
|
+
|
|
177
|
+
useEffect(() => {
|
|
178
|
+
if (!isEmpty(varMapped)) {
|
|
179
|
+
setDataForEdit(true);
|
|
180
|
+
}
|
|
181
|
+
}, [varMapped, zaloTemplateInfoValue]);
|
|
182
|
+
|
|
183
|
+
useEffect(() => {
|
|
184
|
+
let tag = get(metaEntities, `tags.standard`, []);
|
|
185
|
+
const { type, module } = location?.query || {};
|
|
186
|
+
if (type === EMBEDDED && module === LIBRARY && !getDefaultTags) {
|
|
187
|
+
tag = supportedTags;
|
|
188
|
+
}
|
|
189
|
+
updateTags(tag);
|
|
190
|
+
}, [metaEntities]);
|
|
191
|
+
|
|
192
|
+
useEffect(() => {
|
|
193
|
+
//fetching tags
|
|
194
|
+
const { type, module } = location?.query || {};
|
|
195
|
+
const isEmbedded = type === EMBEDDED;
|
|
196
|
+
const query = {
|
|
197
|
+
layout: SMS,
|
|
198
|
+
type: TAG,
|
|
199
|
+
context: isEmbedded ? module : DEFAULT,
|
|
200
|
+
embedded: isEmbedded ? type : FULL,
|
|
201
|
+
};
|
|
202
|
+
if (getDefaultTags) {
|
|
203
|
+
query.context = getDefaultTags;
|
|
204
|
+
}
|
|
205
|
+
globalActions.fetchSchemaForEntity(query);
|
|
206
|
+
}, []);
|
|
207
|
+
|
|
208
|
+
const handleOnTagsContextChange = (data) => {
|
|
209
|
+
const { type } = location?.query || {};
|
|
210
|
+
const isEmbedded = type === EMBEDDED;
|
|
211
|
+
const query = {
|
|
212
|
+
layout: SMS,
|
|
213
|
+
type: TAG,
|
|
214
|
+
context:
|
|
215
|
+
(data || '').toLowerCase() === ALL
|
|
216
|
+
? DEFAULT
|
|
217
|
+
: (data || '').toLowerCase(),
|
|
218
|
+
embedded: isEmbedded ? type : FULL,
|
|
219
|
+
};
|
|
220
|
+
globalActions.fetchSchemaForEntity(query);
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
const onTagSelect = (data) => {
|
|
224
|
+
if (data && textAreaId) {
|
|
225
|
+
const updatedZaloTemplateInfo = templateListParams?.map((listParams) => {
|
|
226
|
+
const { name = '', value = '', minLength, maxLength } = listParams;
|
|
227
|
+
if (name === textAreaId) {
|
|
228
|
+
const text = `${value}{{${data}}}`;
|
|
229
|
+
const isLengthError =
|
|
230
|
+
text.length <= minLength || text.length > maxLength;
|
|
231
|
+
return {
|
|
232
|
+
...listParams,
|
|
233
|
+
value: text,
|
|
234
|
+
error: isLengthError
|
|
235
|
+
? formatMessage(messages.maxMinLengthMessage, {
|
|
236
|
+
minLength,
|
|
237
|
+
maxLength,
|
|
238
|
+
})
|
|
239
|
+
: '',
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
return listParams;
|
|
243
|
+
});
|
|
244
|
+
setTemplateListParams(updatedZaloTemplateInfo);
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
const tagValidationErrorMessage = (message) => {
|
|
249
|
+
const tagValidationResponse =
|
|
250
|
+
validateTags({
|
|
251
|
+
content: message,
|
|
252
|
+
tagsParam: tags,
|
|
253
|
+
injectedTagsParams: injectedTags,
|
|
254
|
+
location,
|
|
255
|
+
tagModule: getDefaultTags,
|
|
256
|
+
}) || {};
|
|
257
|
+
const { unsupportedTags = [], isBraceError } = tagValidationResponse;
|
|
258
|
+
let tagError = '';
|
|
259
|
+
if (unsupportedTags.length > 0) {
|
|
260
|
+
tagError = formatMessage(globalMessages.unsupportedTagsValidationError, {
|
|
261
|
+
unsupportedTags,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
if (isBraceError) {
|
|
265
|
+
tagError = formatMessage(globalMessages.unbalanacedCurlyBraces);
|
|
266
|
+
}
|
|
267
|
+
return tagError;
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
//this function is used for checking errror validation in this it validate tags error and length error
|
|
271
|
+
const handleErrorValidation = (e, field) => {
|
|
272
|
+
const { minLength, maxLength } = field;
|
|
273
|
+
let error = e ? tagValidationErrorMessage(e) : '';
|
|
274
|
+
if (!e || e.length <= minLength || e.length > maxLength) {
|
|
275
|
+
error = formatMessage(messages.maxMinLengthMessage, {
|
|
276
|
+
minLength,
|
|
277
|
+
maxLength,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
return error;
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
// this function is used for handle form data change in this also handle error validtion on change of value
|
|
284
|
+
const handleFormDataChange = (e, field) => {
|
|
285
|
+
const {
|
|
286
|
+
target: { value },
|
|
287
|
+
} = e;
|
|
288
|
+
const updatedZaloTemplateInfo = templateListParams?.map((listParams) => {
|
|
289
|
+
if (listParams?.name === field?.name) {
|
|
290
|
+
const error = handleErrorValidation(value, field);
|
|
291
|
+
return {
|
|
292
|
+
...listParams,
|
|
293
|
+
value,
|
|
294
|
+
error,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
return listParams;
|
|
298
|
+
});
|
|
299
|
+
setTemplateListParams(updatedZaloTemplateInfo);
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
const renderTextBoxesForListParams = (listParam) => {
|
|
303
|
+
const { name, error, value } = listParam;
|
|
304
|
+
return (
|
|
305
|
+
<CapInput
|
|
306
|
+
id={`zalo-${name}`}
|
|
307
|
+
onChange={(e) => handleFormDataChange(e, listParam)}
|
|
308
|
+
errorMessage={error}
|
|
309
|
+
placeholder={formatMessage(messages.addVariableWithMessage)}
|
|
310
|
+
defaultValue={value || ''}
|
|
311
|
+
value={value || ''}
|
|
312
|
+
size="default"
|
|
313
|
+
onFocus={() => setTextAreaId(name)}
|
|
314
|
+
disabled={isFullMode}
|
|
315
|
+
/>
|
|
316
|
+
);
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
const setTextAreaId = (fieldName) => {
|
|
320
|
+
updateTextAreaId(fieldName);
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
const getTemplateStatusType = () => {
|
|
324
|
+
switch (templateStatus) {
|
|
325
|
+
case ZALO_STATUSES.ENABLE:
|
|
326
|
+
return SUCCESS_ALERT;
|
|
327
|
+
case ZALO_STATUSES.REJECT:
|
|
328
|
+
return ERROR_ALERT;
|
|
329
|
+
default:
|
|
330
|
+
return WARNING_ALERT;
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
const actionCallback = () => {
|
|
335
|
+
CapNotification.error({
|
|
336
|
+
message: formatMessage(messages.zaloFailureNotificationTemplate),
|
|
337
|
+
});
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
const isEditDoneDisabled = () => {
|
|
341
|
+
let disableCheck = false;
|
|
342
|
+
templateListParams.forEach((listParams) => {
|
|
343
|
+
const { error, value } = listParams;
|
|
344
|
+
const errorMessage = !error
|
|
345
|
+
? handleErrorValidation(value, listParams)
|
|
346
|
+
: error;
|
|
347
|
+
if (errorMessage) {
|
|
348
|
+
disableCheck = true;
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
return disableCheck;
|
|
352
|
+
};
|
|
353
|
+
const createPayload = () => {
|
|
354
|
+
const varMap = {};
|
|
355
|
+
templateListParams.forEach((listParam) => {
|
|
356
|
+
const { name, value } = listParam;
|
|
357
|
+
varMap[name] = value;
|
|
358
|
+
});
|
|
359
|
+
const payload = {
|
|
360
|
+
channel: ZALO,
|
|
361
|
+
accountId: oa_id,
|
|
362
|
+
...(getDefaultTags === OUTBOUND && {
|
|
363
|
+
zaloAccountId: oa_id,
|
|
364
|
+
}),
|
|
365
|
+
accountName: username,
|
|
366
|
+
templateConfigs: {
|
|
367
|
+
id: templateId?.toString(),
|
|
368
|
+
name: templateName,
|
|
369
|
+
template: templatePreviewUrl,
|
|
370
|
+
varMapped: varMap,
|
|
371
|
+
},
|
|
372
|
+
token,
|
|
373
|
+
};
|
|
374
|
+
return payload;
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
const saveToMessage = () => {
|
|
378
|
+
getFormData({
|
|
379
|
+
value: createPayload(),
|
|
380
|
+
_id: templateId,
|
|
381
|
+
validity: true,
|
|
382
|
+
type: ZALO,
|
|
383
|
+
});
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
const renderContent = () =>
|
|
387
|
+
templateListParams?.map((listParam) => {
|
|
388
|
+
const { name = '', value = '', maxLength } = listParam;
|
|
389
|
+
return (
|
|
390
|
+
<>
|
|
391
|
+
{renderTextBoxesForListParams(listParam)}
|
|
392
|
+
<CapRow className="variable-field-container">
|
|
393
|
+
<CapLabel className="variable-field-name">
|
|
394
|
+
{formatMessage(messages.variableType, {
|
|
395
|
+
name,
|
|
396
|
+
})}
|
|
397
|
+
</CapLabel>
|
|
398
|
+
<CapLabel className="variable-field-length">
|
|
399
|
+
{formatMessage(messages.charactersCount, {
|
|
400
|
+
variableLength: value.length,
|
|
401
|
+
maxLength,
|
|
402
|
+
})}
|
|
403
|
+
</CapLabel>
|
|
404
|
+
</CapRow>
|
|
405
|
+
</>
|
|
406
|
+
);
|
|
407
|
+
});
|
|
408
|
+
|
|
409
|
+
return (
|
|
410
|
+
<CapSpin spinning={zaloTemplateInfoStatus === REQUEST}>
|
|
411
|
+
<CapRow type="flex" className="cap-zalo-creatives">
|
|
412
|
+
<CapColumn span={14}>
|
|
413
|
+
{templateStatus && (
|
|
414
|
+
<CapAlert
|
|
415
|
+
message={
|
|
416
|
+
<CapLabel type="label2">
|
|
417
|
+
{formatMessage(messages.approvedStatusMsg, {
|
|
418
|
+
status: formatMessage(messages?.[templateStatus]),
|
|
419
|
+
})}
|
|
420
|
+
</CapLabel>
|
|
421
|
+
}
|
|
422
|
+
type={getTemplateStatusType()}
|
|
423
|
+
/>
|
|
424
|
+
)}
|
|
425
|
+
<CapRow>
|
|
426
|
+
<CapRow className="whatsapp-render-heading">
|
|
427
|
+
<CapHeader
|
|
428
|
+
className="zalo-variable-heading"
|
|
429
|
+
title={
|
|
430
|
+
<CapHeading type="h4">
|
|
431
|
+
{formatMessage(messages.variables)}
|
|
432
|
+
</CapHeading>
|
|
433
|
+
}
|
|
434
|
+
suffix={
|
|
435
|
+
<TagList
|
|
436
|
+
label={formatMessage(globalMessages.addLabels)}
|
|
437
|
+
onTagSelect={onTagSelect}
|
|
438
|
+
location={location}
|
|
439
|
+
tags={tags || []}
|
|
440
|
+
onContextChange={handleOnTagsContextChange}
|
|
441
|
+
injectedTags={injectedTags || {}}
|
|
442
|
+
selectedOfferDetails={selectedOfferDetails}
|
|
443
|
+
disabled={isFullMode}
|
|
444
|
+
/>
|
|
445
|
+
}
|
|
446
|
+
/>
|
|
447
|
+
</CapRow>
|
|
448
|
+
<CapRow className="zalo-variable-list">{renderContent()}</CapRow>
|
|
449
|
+
</CapRow>
|
|
450
|
+
</CapColumn>
|
|
451
|
+
<CapColumn span={10}>
|
|
452
|
+
<TemplatePreview
|
|
453
|
+
channel={ZALO}
|
|
454
|
+
templateData={{ templatePreviewUrl, fullMode: isFullMode }}
|
|
455
|
+
/>
|
|
456
|
+
</CapColumn>
|
|
457
|
+
</CapRow>
|
|
458
|
+
{!isFullMode && (
|
|
459
|
+
<ZaloFooter>
|
|
460
|
+
<CapTooltip
|
|
461
|
+
title={
|
|
462
|
+
isEditDoneDisabled()
|
|
463
|
+
? formatMessage(messages.btnDisabledTooltip)
|
|
464
|
+
: ''
|
|
465
|
+
}
|
|
466
|
+
placement={'right'}
|
|
467
|
+
>
|
|
468
|
+
<div className="button-disabled-tooltip-wrapper">
|
|
469
|
+
<CapButton
|
|
470
|
+
onClick={saveToMessage}
|
|
471
|
+
disabled={isEditDoneDisabled()}
|
|
472
|
+
>
|
|
473
|
+
<FormattedMessage {...globalMessages.done} />
|
|
474
|
+
</CapButton>
|
|
475
|
+
</div>
|
|
476
|
+
</CapTooltip>
|
|
477
|
+
</ZaloFooter>
|
|
478
|
+
)}
|
|
479
|
+
</CapSpin>
|
|
480
|
+
);
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
const mapStateToProps = createStructuredSelector({
|
|
484
|
+
editData: makeSelectZalo(),
|
|
485
|
+
accountData: makeSelectAccount(),
|
|
486
|
+
metaEntities: makeSelectMetaEntities(),
|
|
487
|
+
injectedTags: setInjectedTags(),
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
const mapDispatchToProps = (dispatch) => ({
|
|
491
|
+
actions: bindActionCreators(zaloActions, dispatch),
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
export default withCreatives({
|
|
495
|
+
WrappedComponent: injectIntl(InApp),
|
|
496
|
+
mapStateToProps,
|
|
497
|
+
mapDispatchToProps,
|
|
498
|
+
userAuth: true,
|
|
499
|
+
});
|
|
File without changes
|
|
File without changes
|