@capillarytech/creatives-library 7.17.35 → 7.17.37-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/Templates/actions.js +0 -5
- package/index.js +6 -0
- package/package.json +1 -1
- package/routes.js +5 -0
- package/services/api.js +6 -1
- package/v2Components/WhatsappStatusContainer/_whatsappStatusContainer.scss +2 -1
- package/v2Containers/App/constants.js +1 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +13 -0
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +9 -6
- package/v2Containers/CreativesContainer/constants.js +1 -0
- package/v2Containers/CreativesContainer/index.scss +3 -0
- package/v2Containers/CreativesContainer/messages.js +8 -0
- package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +6 -1
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +58 -0
- package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +18114 -88
- package/v2Containers/Templates/_templates.scss +20 -2
- package/v2Containers/Templates/actions.js +4 -3
- package/v2Containers/Templates/constants.js +2 -1
- package/v2Containers/Templates/index.js +326 -120
- package/v2Containers/Templates/messages.js +32 -8
- package/v2Containers/Templates/reducer.js +3 -1
- package/v2Containers/Templates/sagas.js +2 -2
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +623 -43
- package/v2Containers/Templates/tests/actions.test.js +18 -0
- package/v2Containers/Templates/tests/index.test.js +52 -1
- package/v2Containers/Templates/tests/mockData.js +41 -1
- package/v2Containers/Templates/tests/reducer.test.js +50 -0
- package/v2Containers/Templates/tests/sagas.test.js +40 -2
- package/v2Containers/Templates/tests/selector.test.js +17 -0
- package/v2Containers/TemplatesV2/index.js +2 -2
- package/v2Containers/TemplatesV2/messages.js +4 -0
- package/v2Containers/Zalo/actions.js +17 -0
- package/v2Containers/Zalo/constants.js +56 -0
- package/v2Containers/Zalo/index.js +390 -0
- package/v2Containers/Zalo/index.scss +76 -0
- package/v2Containers/Zalo/messages.js +74 -0
- package/v2Containers/Zalo/reducer.js +57 -0
- package/v2Containers/Zalo/saga.js +35 -0
- package/v2Containers/Zalo/selectors.js +14 -0
- package/v2Containers/Zalo/tests/actions.test.js +20 -0
- package/v2Containers/Zalo/tests/index.test.js +127 -0
- package/v2Containers/Zalo/tests/mockData.js +11470 -0
- package/v2Containers/Zalo/tests/reducer.test.js +85 -0
- package/v2Containers/Zalo/tests/saga.test.js +115 -0
- package/v2Containers/Zalo/tests/selectors.test.js +52 -0
- package/v2Containers/mockdata.js +817 -680
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
/* eslint-disable react/prop-types */
|
|
2
|
+
import React, { useState, useEffect } from "react";
|
|
3
|
+
import { injectIntl } from "react-intl";
|
|
4
|
+
import { createStructuredSelector } from "reselect";
|
|
5
|
+
import { bindActionCreators } from "redux";
|
|
6
|
+
import { get } from "lodash";
|
|
7
|
+
import styled from 'styled-components';
|
|
8
|
+
import {
|
|
9
|
+
CapSpin,
|
|
10
|
+
CapRow,
|
|
11
|
+
CapColumn,
|
|
12
|
+
CapLabel,
|
|
13
|
+
CapAlert,
|
|
14
|
+
CapInput,
|
|
15
|
+
CapHeading,
|
|
16
|
+
CapHeader,
|
|
17
|
+
CapIcon,
|
|
18
|
+
} from "@capillarytech/cap-ui-library";
|
|
19
|
+
import {
|
|
20
|
+
CAP_SPACE_16,
|
|
21
|
+
CAP_SPACE_24,
|
|
22
|
+
CAP_SPACE_32,
|
|
23
|
+
CAP_WHITE,
|
|
24
|
+
} from '@capillarytech/cap-ui-library/styled/variables';
|
|
25
|
+
import messages from "./messages";
|
|
26
|
+
import withCreatives from "../../hoc/withCreatives";
|
|
27
|
+
import {
|
|
28
|
+
SUCCESS_ALERT,
|
|
29
|
+
REQUEST,
|
|
30
|
+
EMBEDDED,
|
|
31
|
+
DEFAULT,
|
|
32
|
+
TAG,
|
|
33
|
+
FULL,
|
|
34
|
+
ALL,
|
|
35
|
+
LIBRARY,
|
|
36
|
+
ERROR_ALERT,
|
|
37
|
+
WARNING_ALERT,
|
|
38
|
+
ZALO_STATUSES,
|
|
39
|
+
} from "./constants";
|
|
40
|
+
import "./index.scss";
|
|
41
|
+
import { makeSelectZalo } from "./selectors";
|
|
42
|
+
import * as zaloActions from "./actions";
|
|
43
|
+
import * as templateActions from "../Templates/actions";
|
|
44
|
+
import { makeSelectTemplates } from "../Templates/selectors";
|
|
45
|
+
import TagList from "../TagList";
|
|
46
|
+
import globalMessages from "../Cap/messages";
|
|
47
|
+
import { makeSelectMetaEntities, setInjectedTags } from "../Cap/selectors";
|
|
48
|
+
import * as globalActions from "../Cap/actions";
|
|
49
|
+
import { validateTags } from "../../utils/tagValidations";
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
export const Zalo = ({
|
|
53
|
+
intl,
|
|
54
|
+
actions,
|
|
55
|
+
zaloTemplateInfoData,
|
|
56
|
+
templateData,
|
|
57
|
+
location,
|
|
58
|
+
metaEntities,
|
|
59
|
+
getDefaultTags,
|
|
60
|
+
supportedTags,
|
|
61
|
+
injectedTags,
|
|
62
|
+
selectedOfferDetails,
|
|
63
|
+
template,
|
|
64
|
+
}) => {
|
|
65
|
+
const { formatMessage } = intl;
|
|
66
|
+
const [zaloTemplateListParams, setZaloTemplateListParams] = useState([]);
|
|
67
|
+
const [templatePreviewUrl, setTemplatePreviewUrl] = useState("");
|
|
68
|
+
const [tags, updateTags] = useState([]);
|
|
69
|
+
const [textAreaId, updateTextAreaId] = useState("");
|
|
70
|
+
const [templateStatus, setZaloTemplateStatus] = useState(ZALO_STATUSES.ENABLE);
|
|
71
|
+
|
|
72
|
+
const ZaloFooter = styled.div`
|
|
73
|
+
background-color: ${CAP_WHITE};
|
|
74
|
+
position: fixed;
|
|
75
|
+
bottom: 0;
|
|
76
|
+
width: 100%;
|
|
77
|
+
margin-left: -32px;
|
|
78
|
+
padding: ${CAP_SPACE_32} ${CAP_SPACE_24};
|
|
79
|
+
z-index: 1;
|
|
80
|
+
|
|
81
|
+
.ant-btn {
|
|
82
|
+
margin-right: ${CAP_SPACE_16};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
`;
|
|
86
|
+
|
|
87
|
+
const { zaloTemplateInfoStatus, zaloTemplateInfoValue } =
|
|
88
|
+
zaloTemplateInfoData;
|
|
89
|
+
|
|
90
|
+
// here listParams and previewUrl data will be setting in respective states. We got that data by destructring
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
if (zaloTemplateInfoValue) {
|
|
93
|
+
const {
|
|
94
|
+
versions: {
|
|
95
|
+
base: {
|
|
96
|
+
content: {
|
|
97
|
+
zalo: { listParams = [], previewUrl = "", status = "" } = {},
|
|
98
|
+
} = {},
|
|
99
|
+
} = {},
|
|
100
|
+
} = {},
|
|
101
|
+
} = zaloTemplateInfoValue;
|
|
102
|
+
setZaloTemplateListParams(listParams);
|
|
103
|
+
setTemplatePreviewUrl(previewUrl);
|
|
104
|
+
setZaloTemplateStatus(status);
|
|
105
|
+
updateTextAreaId(listParams[0]?.name);
|
|
106
|
+
}
|
|
107
|
+
}, [zaloTemplateInfoValue]);
|
|
108
|
+
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
const {
|
|
111
|
+
weCrmAccounts: [
|
|
112
|
+
{
|
|
113
|
+
name,
|
|
114
|
+
sourceAccountIdentifier,
|
|
115
|
+
configs: { token },
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
} = template;
|
|
119
|
+
const { _id: id } = templateData;
|
|
120
|
+
actions.getTemplateInfoById({
|
|
121
|
+
username: name,
|
|
122
|
+
oa_id: sourceAccountIdentifier,
|
|
123
|
+
token,
|
|
124
|
+
id,
|
|
125
|
+
});
|
|
126
|
+
}, []);
|
|
127
|
+
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
let tag = get(metaEntities, `tags.standard`, []);
|
|
130
|
+
const { type, module } = location?.query || {};
|
|
131
|
+
if (type === EMBEDDED && module === LIBRARY && !getDefaultTags) {
|
|
132
|
+
tag = supportedTags;
|
|
133
|
+
}
|
|
134
|
+
updateTags(tag);
|
|
135
|
+
}, [metaEntities]);
|
|
136
|
+
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
//fetching tags
|
|
139
|
+
const { type, module } = location?.query || {};
|
|
140
|
+
const isEmbedded = type === EMBEDDED;
|
|
141
|
+
const query = {
|
|
142
|
+
layout: "SMS",
|
|
143
|
+
type: TAG,
|
|
144
|
+
context: isEmbedded ? module : DEFAULT,
|
|
145
|
+
embedded: isEmbedded ? type : FULL,
|
|
146
|
+
};
|
|
147
|
+
if (getDefaultTags) {
|
|
148
|
+
query.context = getDefaultTags;
|
|
149
|
+
}
|
|
150
|
+
actions.fetchSchemaForEntity(query);
|
|
151
|
+
}, []);
|
|
152
|
+
|
|
153
|
+
const handleOnTagsContextChange = (data) => {
|
|
154
|
+
const { type } = location?.query || {};
|
|
155
|
+
const isEmbedded = type === EMBEDDED;
|
|
156
|
+
const query = {
|
|
157
|
+
layout: "SMS",
|
|
158
|
+
type: TAG,
|
|
159
|
+
context:
|
|
160
|
+
(data || "").toLowerCase() === ALL
|
|
161
|
+
? DEFAULT
|
|
162
|
+
: (data || "").toLowerCase(),
|
|
163
|
+
embedded: isEmbedded ? type : FULL,
|
|
164
|
+
};
|
|
165
|
+
actions.fetchSchemaForEntity(query);
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const onTagSelect = (data) => {
|
|
169
|
+
if (data && textAreaId) {
|
|
170
|
+
const updatedZaloTemplateInfo = zaloTemplateListParams.map((item) => {
|
|
171
|
+
if (item?.name === textAreaId) {
|
|
172
|
+
const text = `${item?.value ? item?.value : ""}{{${data}}}`;
|
|
173
|
+
return {
|
|
174
|
+
...item,
|
|
175
|
+
value: text,
|
|
176
|
+
error:
|
|
177
|
+
text.length <= item?.minLength || text.length > item?.maxLength
|
|
178
|
+
? formatMessage(messages.maxMinLengthMessage, {
|
|
179
|
+
minLength: item?.minLength,
|
|
180
|
+
maxLength: item?.maxLength,
|
|
181
|
+
})
|
|
182
|
+
: "",
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
return item;
|
|
186
|
+
});
|
|
187
|
+
setZaloTemplateListParams(updatedZaloTemplateInfo);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const tagValidationErrorMessage = (message) => {
|
|
192
|
+
const tagValidationResponse =
|
|
193
|
+
validateTags({
|
|
194
|
+
content: message,
|
|
195
|
+
tagsParam: tags,
|
|
196
|
+
injectedTagsParams: injectedTags,
|
|
197
|
+
location,
|
|
198
|
+
tagModule: getDefaultTags,
|
|
199
|
+
}) || {};
|
|
200
|
+
const { unsupportedTags = [], isBraceError } = tagValidationResponse;
|
|
201
|
+
let tagError = "";
|
|
202
|
+
if (unsupportedTags.length > 0) {
|
|
203
|
+
tagError = formatMessage(globalMessages.unsupportedTagsValidationError, {
|
|
204
|
+
unsupportedTags,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
if (isBraceError) {
|
|
208
|
+
tagError = formatMessage(globalMessages.unbalanacedCurlyBraces);
|
|
209
|
+
}
|
|
210
|
+
return tagError;
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
// this function is used for handle form data change in this also handle error validtion on change of value
|
|
214
|
+
const handleFormDataChange = (e, field) => {
|
|
215
|
+
const {
|
|
216
|
+
target: { value },
|
|
217
|
+
} = e;
|
|
218
|
+
const updatedZaloTemplateInfo = zaloTemplateListParams?.map((item) => {
|
|
219
|
+
if (item?.name === field?.name) {
|
|
220
|
+
const error = handleErrorValidation(value, field);
|
|
221
|
+
return {
|
|
222
|
+
...item,
|
|
223
|
+
value,
|
|
224
|
+
error,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
return item;
|
|
228
|
+
});
|
|
229
|
+
setZaloTemplateListParams(updatedZaloTemplateInfo);
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
//this function is used for checking errror validation in this it validate tags error and length error
|
|
233
|
+
const handleErrorValidation = (e, field) => {
|
|
234
|
+
const { minLength, maxLength } = field;
|
|
235
|
+
let error = tagValidationErrorMessage(e);
|
|
236
|
+
|
|
237
|
+
if (e.length <= minLength || e.length > maxLength) {
|
|
238
|
+
error = formatMessage(messages.maxMinLengthMessage, {
|
|
239
|
+
minLength,
|
|
240
|
+
maxLength,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return error;
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const renderTextBoxesForListParams = (listParam) => {
|
|
248
|
+
const { name, error, value } = listParam;
|
|
249
|
+
return (
|
|
250
|
+
<CapInput
|
|
251
|
+
id={`zalo-${name}`}
|
|
252
|
+
onChange={(e) => handleFormDataChange(e, listParam)}
|
|
253
|
+
errorMessage={error}
|
|
254
|
+
placeholder={formatMessage(messages.addVariableWithMessage)}
|
|
255
|
+
defaultValue={value || ""}
|
|
256
|
+
value={value || ""}
|
|
257
|
+
size="default"
|
|
258
|
+
onFocus={() => setTextAreaId(name)}
|
|
259
|
+
/>
|
|
260
|
+
);
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const setTextAreaId = (fieldName) => {
|
|
264
|
+
updateTextAreaId(fieldName);
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
const handlePreview = () => {
|
|
268
|
+
window.open(templatePreviewUrl, "_blank");
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
const getTemplateStatusType = () => {
|
|
272
|
+
switch (templateStatus) {
|
|
273
|
+
case ZALO_STATUSES.ENABLE:
|
|
274
|
+
return SUCCESS_ALERT;
|
|
275
|
+
case ZALO_STATUSES.REJECT:
|
|
276
|
+
return ERROR_ALERT;
|
|
277
|
+
default:
|
|
278
|
+
return WARNING_ALERT;
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
return (
|
|
283
|
+
<CapSpin spinning={zaloTemplateInfoStatus === REQUEST}>
|
|
284
|
+
<CapRow type="flex" className="cap-zalo-creatives">
|
|
285
|
+
<CapColumn span={14}>
|
|
286
|
+
<CapAlert
|
|
287
|
+
message={
|
|
288
|
+
<CapLabel type="label2">
|
|
289
|
+
{formatMessage(messages.approvedStatusMsg, {
|
|
290
|
+
status: formatMessage(messages?.[templateStatus]),
|
|
291
|
+
})}
|
|
292
|
+
</CapLabel>
|
|
293
|
+
}
|
|
294
|
+
type={getTemplateStatusType()}
|
|
295
|
+
/>
|
|
296
|
+
<CapRow>
|
|
297
|
+
<CapRow className="whatsapp-render-heading">
|
|
298
|
+
<CapHeader
|
|
299
|
+
className="zalo-variable-heading"
|
|
300
|
+
title={
|
|
301
|
+
<CapHeading type="h4">
|
|
302
|
+
{formatMessage(messages.variables)}
|
|
303
|
+
</CapHeading>
|
|
304
|
+
}
|
|
305
|
+
suffix={
|
|
306
|
+
<TagList
|
|
307
|
+
label={formatMessage(globalMessages.addLabels)}
|
|
308
|
+
onTagSelect={onTagSelect}
|
|
309
|
+
location={location}
|
|
310
|
+
tags={tags || []}
|
|
311
|
+
onContextChange={handleOnTagsContextChange}
|
|
312
|
+
injectedTags={injectedTags || {}}
|
|
313
|
+
selectedOfferDetails={selectedOfferDetails}
|
|
314
|
+
/>
|
|
315
|
+
}
|
|
316
|
+
/>
|
|
317
|
+
</CapRow>
|
|
318
|
+
<CapRow className="zalo-variable-list">
|
|
319
|
+
{zaloTemplateListParams?.map((listParam) => {
|
|
320
|
+
const { name = "", maxLength, value = "" } = listParam;
|
|
321
|
+
return (
|
|
322
|
+
<>
|
|
323
|
+
{renderTextBoxesForListParams(listParam)}
|
|
324
|
+
<CapRow className="variable-field-container">
|
|
325
|
+
<CapLabel className="variable-field-name">
|
|
326
|
+
{formatMessage(messages.variableType, {
|
|
327
|
+
fieldName: name,
|
|
328
|
+
})}
|
|
329
|
+
</CapLabel>
|
|
330
|
+
<CapLabel className="variable-field-length">
|
|
331
|
+
{formatMessage(messages.charactersCount, {
|
|
332
|
+
variableLength: value?.length,
|
|
333
|
+
fixedLength: maxLength,
|
|
334
|
+
})}
|
|
335
|
+
</CapLabel>
|
|
336
|
+
</CapRow>
|
|
337
|
+
</>
|
|
338
|
+
);
|
|
339
|
+
})}
|
|
340
|
+
</CapRow>
|
|
341
|
+
</CapRow>
|
|
342
|
+
</CapColumn>
|
|
343
|
+
<CapColumn type="flex" span={10} className="zalo-preview-container">
|
|
344
|
+
<CapRow>
|
|
345
|
+
<CapLabel className="preview-head">
|
|
346
|
+
{formatMessage(messages.previewHead)}
|
|
347
|
+
</CapLabel>
|
|
348
|
+
</CapRow>
|
|
349
|
+
<CapRow>
|
|
350
|
+
<CapLabel className="preview-text">
|
|
351
|
+
{formatMessage(messages.previewText)}
|
|
352
|
+
</CapLabel>
|
|
353
|
+
</CapRow>
|
|
354
|
+
<CapRow>
|
|
355
|
+
<CapLabel
|
|
356
|
+
data-testid="preview-link-button"
|
|
357
|
+
onClick={handlePreview}
|
|
358
|
+
className="preview-link"
|
|
359
|
+
>
|
|
360
|
+
{formatMessage(messages.openPreview)}{" "}
|
|
361
|
+
<CapIcon type="open-in-new-light"></CapIcon>
|
|
362
|
+
</CapLabel>
|
|
363
|
+
</CapRow>
|
|
364
|
+
</CapColumn>
|
|
365
|
+
</CapRow>
|
|
366
|
+
<ZaloFooter></ZaloFooter>
|
|
367
|
+
</CapSpin>
|
|
368
|
+
);
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
const mapStateToProps = createStructuredSelector({
|
|
372
|
+
zaloTemplateInfoData: makeSelectZalo(),
|
|
373
|
+
template: makeSelectTemplates(),
|
|
374
|
+
metaEntities: makeSelectMetaEntities(),
|
|
375
|
+
injectedTags: setInjectedTags(),
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
const mapDispatchToProps = (dispatch) => ({
|
|
379
|
+
actions: bindActionCreators(
|
|
380
|
+
{ ...zaloActions, ...templateActions, ...globalActions },
|
|
381
|
+
dispatch
|
|
382
|
+
),
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
export default withCreatives({
|
|
386
|
+
WrappedComponent: injectIntl(Zalo),
|
|
387
|
+
mapStateToProps,
|
|
388
|
+
mapDispatchToProps,
|
|
389
|
+
userAuth: true,
|
|
390
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
@import '~@capillarytech/cap-ui-library/styles/_variables.scss';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
.cap-zalo-creatives {
|
|
5
|
+
.zalo-variable-heading {
|
|
6
|
+
margin-top: $CAP_SPACE_24;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.zalo-variable-list {
|
|
10
|
+
margin: 0px 0px 200px;
|
|
11
|
+
|
|
12
|
+
input {
|
|
13
|
+
height: $CAP_SPACE_40;
|
|
14
|
+
margin-top: $CAP_SPACE_16;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.ant-calendar-picker {
|
|
18
|
+
width: 100%;
|
|
19
|
+
|
|
20
|
+
.ant-calendar-picker-icon {
|
|
21
|
+
top: 50%;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.ant-input-suffix {
|
|
26
|
+
top: 62%;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.variable-field-container {
|
|
31
|
+
display: flex;
|
|
32
|
+
margin-top: $CAP_SPACE_08;
|
|
33
|
+
|
|
34
|
+
div {
|
|
35
|
+
font-weight: 400;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.variable-field-length {
|
|
39
|
+
position: absolute;
|
|
40
|
+
right: 0;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.zalo-preview-container {
|
|
45
|
+
text-align: center;
|
|
46
|
+
position: fixed;
|
|
47
|
+
right: 0;
|
|
48
|
+
padding-left: 194px;
|
|
49
|
+
padding-right: 116px;
|
|
50
|
+
|
|
51
|
+
.preview-head {
|
|
52
|
+
font-weight: 500;
|
|
53
|
+
font-size: $FONT_SIZE_M;
|
|
54
|
+
color: $FONT_COLOR_01;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.preview-text {
|
|
58
|
+
font-weight: 400;
|
|
59
|
+
font-size: $FONT_SIZE_S;
|
|
60
|
+
padding-top: $CAP_SPACE_08;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.preview-link {
|
|
64
|
+
font-weight: 500;
|
|
65
|
+
font-size: $FONT_SIZE_M;
|
|
66
|
+
color: $FONT_COLOR_05;
|
|
67
|
+
margin-top: $CAP_SPACE_19;
|
|
68
|
+
cursor: pointer;
|
|
69
|
+
|
|
70
|
+
svg {
|
|
71
|
+
height: $CAP_SPACE_16;
|
|
72
|
+
width: $CAP_SPACE_16;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { defineMessages } from "react-intl";
|
|
2
|
+
const prefix = `creatives.containersV2.zalo`;
|
|
3
|
+
|
|
4
|
+
export default defineMessages({
|
|
5
|
+
approvedStatusMsg: {
|
|
6
|
+
id: `${prefix}.approvedStatusMsg`,
|
|
7
|
+
defaultMessage: "This template has been {status}",
|
|
8
|
+
},
|
|
9
|
+
variables: {
|
|
10
|
+
id: `${prefix}.variables`,
|
|
11
|
+
defaultMessage: "Variables",
|
|
12
|
+
},
|
|
13
|
+
addVariableWithMessage: {
|
|
14
|
+
id: `${prefix}.addVariableWithMessage`,
|
|
15
|
+
defaultMessage: "Add labels or text or combination of both",
|
|
16
|
+
},
|
|
17
|
+
variableType: {
|
|
18
|
+
id: `${prefix}.variableType`,
|
|
19
|
+
defaultMessage: "Variable type: <{fieldName}>",
|
|
20
|
+
},
|
|
21
|
+
charactersCount: {
|
|
22
|
+
id: `${prefix}.charactersCount`,
|
|
23
|
+
defaultMessage: "Characters count {variableLength}/{fixedLength}",
|
|
24
|
+
},
|
|
25
|
+
maxMinLengthMessage: {
|
|
26
|
+
id: `${prefix}.maxLengthMessage`,
|
|
27
|
+
defaultMessage:
|
|
28
|
+
"Character count for this variable should be in between {minLength} to {maxLength}",
|
|
29
|
+
},
|
|
30
|
+
previewHead: {
|
|
31
|
+
id: `${prefix}.previewText`,
|
|
32
|
+
defaultMessage: "Preview",
|
|
33
|
+
},
|
|
34
|
+
previewText: {
|
|
35
|
+
id: `${prefix}.previewText`,
|
|
36
|
+
defaultMessage: `Preview of the template is generated on the Zalo platform. Click on ‘Open preview’ to view it in a new tab`,
|
|
37
|
+
},
|
|
38
|
+
openPreview: {
|
|
39
|
+
id: `${prefix}.openPreview`,
|
|
40
|
+
defaultMessage: "Open Preview",
|
|
41
|
+
},
|
|
42
|
+
ENABLE_STATUS: {
|
|
43
|
+
id: `${prefix}.ENABLE_STATUS`,
|
|
44
|
+
defaultMessage: 'Enable',
|
|
45
|
+
},
|
|
46
|
+
REJECT_STATUS: {
|
|
47
|
+
id: `${prefix}.REJECT_STATUS`,
|
|
48
|
+
defaultMessage: 'Reject',
|
|
49
|
+
},
|
|
50
|
+
DISABLE_STATUS: {
|
|
51
|
+
id: `${prefix}.DISABLE_STATUS`,
|
|
52
|
+
defaultMessage: 'Disable',
|
|
53
|
+
},
|
|
54
|
+
PENDING_REVIEW_STATUS: {
|
|
55
|
+
id: `${prefix}.PENDING_REVIEW_STATUS`,
|
|
56
|
+
defaultMessage: 'Review Pending',
|
|
57
|
+
},
|
|
58
|
+
ENABLE: {
|
|
59
|
+
id: `${prefix}.ENABLE`,
|
|
60
|
+
defaultMessage: 'enabled',
|
|
61
|
+
},
|
|
62
|
+
REJECT: {
|
|
63
|
+
id: `${prefix}.REJECT`,
|
|
64
|
+
defaultMessage: 'rejected',
|
|
65
|
+
},
|
|
66
|
+
DISABLE: {
|
|
67
|
+
id: `${prefix}.DISABLE`,
|
|
68
|
+
defaultMessage: 'disabled',
|
|
69
|
+
},
|
|
70
|
+
PENDING_REVIEW: {
|
|
71
|
+
id: `${prefix}.PENDING_REVIEW`,
|
|
72
|
+
defaultMessage: 'pending review',
|
|
73
|
+
},
|
|
74
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { fromJS } from "immutable";
|
|
2
|
+
import {
|
|
3
|
+
ZALO_TEMPLATE_INFO_ERROR,
|
|
4
|
+
ZALO_TEMPLATE_INFO_SUCCESS,
|
|
5
|
+
ZALO_TEMPLATE_INFO_REQUEST,
|
|
6
|
+
ZALO_TEMPLATE_PREVIEW_RESET,
|
|
7
|
+
ZALO_TEMPLATE_PREVIEW_INFO,
|
|
8
|
+
SUCCESS,
|
|
9
|
+
REQUEST,
|
|
10
|
+
ERROR,
|
|
11
|
+
} from "./constants";
|
|
12
|
+
|
|
13
|
+
const initialState = fromJS({
|
|
14
|
+
zaloTemplateInfoStatus: "",
|
|
15
|
+
zaloTemplateInfoValue: "",
|
|
16
|
+
zaloTemplateInfoError: "",
|
|
17
|
+
zaloTemplatePreviewData: "",
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const zaloReducer = (state = initialState, action) => {
|
|
21
|
+
switch (action.type) {
|
|
22
|
+
case ZALO_TEMPLATE_INFO_REQUEST:
|
|
23
|
+
return state
|
|
24
|
+
.set("zaloTemplateInfoStatus", REQUEST)
|
|
25
|
+
.set("zaloTemplateInfoValue", "")
|
|
26
|
+
.set("zaloTemplateInfoError", null);
|
|
27
|
+
|
|
28
|
+
case ZALO_TEMPLATE_INFO_SUCCESS:
|
|
29
|
+
return state
|
|
30
|
+
.set("zaloTemplateInfoStatus", SUCCESS)
|
|
31
|
+
.set("zaloTemplateInfoValue", action.result)
|
|
32
|
+
.set("zaloTemplateInfoError", null);
|
|
33
|
+
|
|
34
|
+
case ZALO_TEMPLATE_INFO_ERROR:
|
|
35
|
+
return state
|
|
36
|
+
.set("zaloTemplateInfoStatus", ERROR)
|
|
37
|
+
.set("zaloTemplateInfoValue", "")
|
|
38
|
+
.set("zaloTemplateInfoError", action.error);
|
|
39
|
+
|
|
40
|
+
case ZALO_TEMPLATE_PREVIEW_INFO:
|
|
41
|
+
return state
|
|
42
|
+
.set("zaloTemplateInfoStatus", SUCCESS)
|
|
43
|
+
.set("zaloTemplatePreviewData", action.result)
|
|
44
|
+
.set("zaloTemplateInfoError", null);
|
|
45
|
+
|
|
46
|
+
case ZALO_TEMPLATE_PREVIEW_RESET:
|
|
47
|
+
return state
|
|
48
|
+
.set("zaloTemplateInfoStatus", REQUEST)
|
|
49
|
+
.set("zaloTemplatePreviewData", "")
|
|
50
|
+
.set("zaloTemplateInfoError", null);
|
|
51
|
+
|
|
52
|
+
default:
|
|
53
|
+
return state;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export default zaloReducer;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { call, put, takeLatest } from "redux-saga/effects";
|
|
2
|
+
import * as Api from "../../services/api";
|
|
3
|
+
import {
|
|
4
|
+
ZALO_TEMPLATE_INFO_REQUEST,
|
|
5
|
+
ZALO_TEMPLATE_INFO_SUCCESS,
|
|
6
|
+
ZALO_TEMPLATE_INFO_ERROR,
|
|
7
|
+
ZALO_TEMPLATE_PREVIEW_INFO,
|
|
8
|
+
} from "./constants";
|
|
9
|
+
|
|
10
|
+
export function* getTemplateInfoById({ payload }) {
|
|
11
|
+
try {
|
|
12
|
+
const res = yield call(Api.getTemplateInfoById, payload);
|
|
13
|
+
if (res?.success) {
|
|
14
|
+
yield put({
|
|
15
|
+
type: payload?.preview
|
|
16
|
+
? ZALO_TEMPLATE_PREVIEW_INFO
|
|
17
|
+
: ZALO_TEMPLATE_INFO_SUCCESS,
|
|
18
|
+
result: res?.response || {},
|
|
19
|
+
});
|
|
20
|
+
} else {
|
|
21
|
+
yield put({
|
|
22
|
+
type: ZALO_TEMPLATE_INFO_ERROR,
|
|
23
|
+
error: res?.error || res?.message,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
} catch (error) {
|
|
27
|
+
yield put({ type: ZALO_TEMPLATE_INFO_ERROR, error });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function* watchForGetTemplateInfoById() {
|
|
32
|
+
yield takeLatest(ZALO_TEMPLATE_INFO_REQUEST, getTemplateInfoById);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export default [watchForGetTemplateInfoById];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createSelector } from "reselect";
|
|
2
|
+
import { fromJS } from "immutable";
|
|
3
|
+
|
|
4
|
+
const selectZaloDomain = (state = fromJS({})) => state.get("zalo");
|
|
5
|
+
|
|
6
|
+
const makeSelectZalo = () =>
|
|
7
|
+
createSelector(selectZaloDomain, (substate = fromJS({})) => ({
|
|
8
|
+
zaloTemplateInfoStatus: substate.get("zaloTemplateInfoStatus"),
|
|
9
|
+
zaloTemplateInfoValue: substate.get("zaloTemplateInfoValue"),
|
|
10
|
+
zaloTemplateInfoError: substate.get("zaloTemplateInfoError"),
|
|
11
|
+
zaloTemplatePreviewData: substate.get("zaloTemplatePreviewData"),
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
export { makeSelectZalo, selectZaloDomain };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as types from "../constants";
|
|
2
|
+
import * as actions from "../actions";
|
|
3
|
+
|
|
4
|
+
describe("Test zalo actions", () => {
|
|
5
|
+
it("has a type of ZALO_TEMPLATE_INFO_REQUEST action", () => {
|
|
6
|
+
const payload = {};
|
|
7
|
+
const expected = {
|
|
8
|
+
type: types.ZALO_TEMPLATE_INFO_REQUEST,
|
|
9
|
+
payload,
|
|
10
|
+
};
|
|
11
|
+
expect(actions.getTemplateInfoById(payload)).toEqual(expected);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("has a type of ZALO_TEMPLATE_PREVIEW_RESET action", () => {
|
|
15
|
+
const expected = {
|
|
16
|
+
type: types.ZALO_TEMPLATE_PREVIEW_RESET,
|
|
17
|
+
};
|
|
18
|
+
expect(actions.resetTemplateInfoData()).toEqual(expected);
|
|
19
|
+
});
|
|
20
|
+
});
|