@capillarytech/creatives-library 7.2.0 → 7.3.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/components/TopBar/assets/images/capillary_logo.png +0 -0
- package/components/TopBar/assets/images/old_capillary_logo.png +0 -0
- package/config/app.js +2 -0
- package/containers/Templates/index.js +2 -2
- package/favicon.ico +0 -0
- package/index.js +7 -0
- package/old_favicon.ico +0 -0
- package/package.json +1 -1
- package/reducers.js +2 -1
- package/services/api.js +6 -0
- package/utils/common.js +178 -0
- package/v2Components/TemplatePreview/assets/images/mobile.svg +24 -0
- package/v2Containers/App/constants.js +5 -1
- package/v2Containers/CreativesContainer/SlideBoxContent.js +17 -1
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +5 -1
- package/v2Containers/CreativesContainer/constants.js +2 -0
- package/v2Containers/CreativesContainer/index.js +8 -0
- package/v2Containers/Email/index.js +1 -0
- package/v2Containers/FTP/_FTP.scss +14 -3
- package/v2Containers/FTP/index.js +82 -18
- package/v2Containers/FTP/messages.js +8 -0
- package/v2Containers/FTP/temp.js +11838 -0
- package/v2Containers/Templates/index.js +1 -1
- package/v2Containers/TemplatesV2/index.js +13 -0
- package/v2Containers/TemplatesV2/messages.js +4 -0
- package/v2Containers/Viber/index.js +1 -1
|
@@ -20,6 +20,10 @@ export const TRACK_CREATE_WECHAT = 'createWeChat';
|
|
|
20
20
|
export const TRACK_CREATE_IMAGE = 'createImage';
|
|
21
21
|
export const TRACK_CREATE_LINE = 'createLine';
|
|
22
22
|
|
|
23
|
+
export const CREATE = 'create';
|
|
24
|
+
export const EDIT = 'edit';
|
|
25
|
+
export const PREVIEW = 'preview';
|
|
26
|
+
|
|
23
27
|
export const VIBER = 'viber';
|
|
24
28
|
export const TRACK_EDIT_SMS = 'editSms';
|
|
25
29
|
export const TRACK_EDIT_EMAIL = 'editEmail';
|
|
@@ -47,5 +51,5 @@ export const CHANNEL_EDIT_TRACK_MAPPING = {
|
|
|
47
51
|
};
|
|
48
52
|
export const GTM_TRACKING_ID = 'UA-110024621-2';
|
|
49
53
|
export const BEE_PLUGIN = 'BEE_PLUGIN';
|
|
50
|
-
|
|
54
|
+
export const NO_COMMUNICATION = 'NO_COMMUNICATION';
|
|
51
55
|
export const CREATIVES_UI_VIEW = 'CREATIVES_UI_VIEW';
|
|
@@ -19,6 +19,7 @@ import CallTask from '../CallTask';
|
|
|
19
19
|
import MobliPushEdit from '../MobilePush/Edit';
|
|
20
20
|
import * as constants from './constants';
|
|
21
21
|
import LineContainer from '../Line/Container';
|
|
22
|
+
import FTP from '../FTP';
|
|
22
23
|
import Viber from '../Viber';
|
|
23
24
|
const CreativesWrapper = styled.div`
|
|
24
25
|
.ant-popover,
|
|
@@ -134,6 +135,7 @@ function SlideBoxContent(props) {
|
|
|
134
135
|
selectedAccount,
|
|
135
136
|
onShowTemplates,
|
|
136
137
|
handleClose,
|
|
138
|
+
onFTPSubmit,
|
|
137
139
|
} = props;
|
|
138
140
|
const type = (messageDetails.type || '').toLowerCase(); // type is context in get tags values : outbound | dvs | referral | loyalty | coupons
|
|
139
141
|
const query = { type: !isFullMode && 'embedded', module: isFullMode ? 'default' : 'library', isEditFromCampaigns: (templateData || {}).isEditFromCampaigns};
|
|
@@ -173,6 +175,7 @@ function SlideBoxContent(props) {
|
|
|
173
175
|
let isEditCallTask = false;
|
|
174
176
|
let isEditMPush = false;
|
|
175
177
|
let isEditFacebook = false;
|
|
178
|
+
let isEditFTP = false;
|
|
176
179
|
const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL;
|
|
177
180
|
if (templateData && channel) {
|
|
178
181
|
channel = templateData.type;// for edit mode with template data
|
|
@@ -185,6 +188,7 @@ function SlideBoxContent(props) {
|
|
|
185
188
|
isPreview = slidBoxContent === 'preview' && (channel === constants.SMS || channel === constants.LINE || channel === constants.VIBER);
|
|
186
189
|
isEmailPreview = slidBoxContent === 'preview' && channel === constants.EMAIL;
|
|
187
190
|
isMpushPreview = slidBoxContent === 'preview' && channel === constants.MOBILE_PUSH;
|
|
191
|
+
isEditFTP = slidBoxContent === 'editTemplate' && [constants.NO_COMMUNICATION, constants.FTP].includes(channel);
|
|
188
192
|
}
|
|
189
193
|
|
|
190
194
|
const getChannelPreviewContent = (templateDataObject) => {
|
|
@@ -263,7 +267,6 @@ function SlideBoxContent(props) {
|
|
|
263
267
|
return get(templateDataObject, `versions.base.content`);
|
|
264
268
|
}
|
|
265
269
|
};
|
|
266
|
-
|
|
267
270
|
return (
|
|
268
271
|
<CreativesWrapper>
|
|
269
272
|
{!isFullMode && slidBoxContent === 'templates' && (
|
|
@@ -286,6 +289,10 @@ function SlideBoxContent(props) {
|
|
|
286
289
|
onCreateComplete={onCreateComplete}
|
|
287
290
|
getFormSubscriptionData={getFormData}
|
|
288
291
|
handleClose={handleClose}
|
|
292
|
+
onFTPSubmit={onFTPSubmit}
|
|
293
|
+
slidBoxContent={slidBoxContent}
|
|
294
|
+
FTPMode="create"
|
|
295
|
+
selectedOfferDetails={selectedOfferDetails}
|
|
289
296
|
/>
|
|
290
297
|
)}
|
|
291
298
|
{isPreview && (
|
|
@@ -354,6 +361,14 @@ function SlideBoxContent(props) {
|
|
|
354
361
|
onTestContentClicked={onTestContentClicked}
|
|
355
362
|
/>
|
|
356
363
|
)}
|
|
364
|
+
{isEditFTP && (
|
|
365
|
+
<FTP
|
|
366
|
+
mode="edit"
|
|
367
|
+
onFTPSubmit={onFTPSubmit}
|
|
368
|
+
messageDetails={messageDetails}
|
|
369
|
+
selectedOfferDetails={selectedOfferDetails}
|
|
370
|
+
/>
|
|
371
|
+
)}
|
|
357
372
|
{
|
|
358
373
|
isEditCallTask &&
|
|
359
374
|
<CallTask
|
|
@@ -608,5 +623,6 @@ SlideBoxContent.propTypes = {
|
|
|
608
623
|
onCreateComplete: PropTypes.func,
|
|
609
624
|
saveMessage: PropTypes.func,
|
|
610
625
|
selectedAccount: PropTypes.object,
|
|
626
|
+
onFTPSubmit: PropTypes.func,
|
|
611
627
|
};
|
|
612
628
|
export default SlideBoxContent;
|
|
@@ -6,6 +6,8 @@ import moment from 'moment';
|
|
|
6
6
|
import PropTypes from 'prop-types';
|
|
7
7
|
import messages from './messages';
|
|
8
8
|
import { MAP_TEMPLATE } from '../WeChat/Wrapper/constants';
|
|
9
|
+
import { NO_COMMUNICATION } from '../App/constants';
|
|
10
|
+
import { FTP } from '../FTP';
|
|
9
11
|
const PrefixWrapper = styled.div`
|
|
10
12
|
margin-right: 16px;
|
|
11
13
|
`;
|
|
@@ -15,6 +17,8 @@ function getChannelLabel(channel = '') {
|
|
|
15
17
|
email: 'Email',
|
|
16
18
|
mobilepush: 'Push notification',
|
|
17
19
|
wechat: 'Wechat',
|
|
20
|
+
no_communication: 'NO_COMMUNICATION',
|
|
21
|
+
ftp: 'FTP',
|
|
18
22
|
};
|
|
19
23
|
return labels[channel.toLowerCase()];
|
|
20
24
|
}
|
|
@@ -27,7 +31,7 @@ function SlideBoxHeader(props) {
|
|
|
27
31
|
{slidBoxContent === 'templates' && !showTemplateNameHeader && (
|
|
28
32
|
<CapHeader
|
|
29
33
|
title={<FormattedMessage {...messages.creativeTemplates} />}
|
|
30
|
-
description={
|
|
34
|
+
description={![NO_COMMUNICATION, FTP].includes(channel) &&
|
|
31
35
|
<FormattedMessage {...messages.creativeTemplatesDesc} />
|
|
32
36
|
}
|
|
33
37
|
/>
|
|
@@ -13,6 +13,8 @@ export const CALL_TASK = "CALL_TASK";
|
|
|
13
13
|
export const MOBILE_PUSH = "MOBILEPUSH";
|
|
14
14
|
export const WECHAT = "WECHAT";
|
|
15
15
|
export const FACEBOOK = "FACEBOOK";
|
|
16
|
+
export const FTP = "FTP";
|
|
17
|
+
export const NO_COMMUNICATION = "NO_COMMUNICATION";
|
|
16
18
|
export const VIBER = "VIBER";
|
|
17
19
|
|
|
18
20
|
export const SHOW_CONTANER_LOADER = "app/CreativesContainer/SHOW_CONTANER_LOADER";
|
|
@@ -142,6 +142,13 @@ class Creatives extends React.Component {
|
|
|
142
142
|
const {channel} = templateData;
|
|
143
143
|
let creativesTemplateData = {type: channel };
|
|
144
144
|
switch (channel) {
|
|
145
|
+
case constants.NO_COMMUNICATION: {
|
|
146
|
+
creativesTemplateData = {
|
|
147
|
+
type: channel,
|
|
148
|
+
...templateData,
|
|
149
|
+
};
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
145
152
|
case constants.SMS: {
|
|
146
153
|
const formData = {
|
|
147
154
|
"sms-editor": templateData.messageBody,
|
|
@@ -641,6 +648,7 @@ class Creatives extends React.Component {
|
|
|
641
648
|
selectedAccount={this.props.selectedAccount}
|
|
642
649
|
onShowTemplates={this.onShowTemplates}
|
|
643
650
|
handleClose={this.handleCloseSlideBox}
|
|
651
|
+
onFTPSubmit={getCreativesData}
|
|
644
652
|
editor={editor}
|
|
645
653
|
/>
|
|
646
654
|
}
|
|
@@ -2358,6 +2358,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
2358
2358
|
const response = {
|
|
2359
2359
|
action: "getFormData",
|
|
2360
2360
|
postAction: this.state.getFormDataValue || 'next',
|
|
2361
|
+
id : _.get(this.props, 'Email.templateDetails._id', ''),
|
|
2361
2362
|
value: this.transformFormData(passedData),
|
|
2362
2363
|
validity: this.state.isFormValid,
|
|
2363
2364
|
type: 'EMAIL',
|
|
@@ -61,7 +61,8 @@
|
|
|
61
61
|
}
|
|
62
62
|
.scrollable-section{
|
|
63
63
|
height: calc(100vh - 220px);
|
|
64
|
-
|
|
64
|
+
overflow-y: auto;
|
|
65
|
+
margin-bottom: $CAP_SPACE_08;
|
|
65
66
|
}
|
|
66
67
|
.FTP-tagList {
|
|
67
68
|
position: absolute;
|
|
@@ -82,8 +83,13 @@
|
|
|
82
83
|
}
|
|
83
84
|
.ftp-preview-message-content{
|
|
84
85
|
max-width: 450px;
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
margin-top: 4px;
|
|
87
|
+
color: $FONT_COLOR_02;
|
|
88
|
+
.ant-input[disabled]{
|
|
89
|
+
background-color: $CAP_WHITE;
|
|
90
|
+
color: $FONT_COLOR_01;
|
|
91
|
+
cursor: default;
|
|
92
|
+
}
|
|
87
93
|
}
|
|
88
94
|
.ftp-preview-data-title{
|
|
89
95
|
margin-top: $CAP_SPACE_40;
|
|
@@ -100,4 +106,9 @@
|
|
|
100
106
|
.manage-ftp-setting-div{
|
|
101
107
|
display: flex;
|
|
102
108
|
align-items: baseline;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.configure-ftp-setting-div{
|
|
112
|
+
text-align: center;
|
|
113
|
+
align-items: baseline;
|
|
103
114
|
}
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
CapTreeSelect,
|
|
20
20
|
CapDivider,
|
|
21
21
|
} from '@capillarytech/cap-ui-library';
|
|
22
|
-
import { find, cloneDeep, findIndex, isEmpty, isEqual, filter } from 'lodash';
|
|
22
|
+
import { find, cloneDeep, findIndex, isEmpty, isEqual, filter, flattenDeep } from 'lodash';
|
|
23
23
|
import * as actions from './actions';
|
|
24
24
|
import { makeSelectFTP, makeSelectMetaEntities } from './selectors';
|
|
25
25
|
import withCreatives from '../../hoc/withCreatives';
|
|
@@ -140,24 +140,35 @@ export class FTP extends React.Component {
|
|
|
140
140
|
>
|
|
141
141
|
{formatMessage(messages.ftpServer)}
|
|
142
142
|
</CapHeading>
|
|
143
|
-
<CapHeading type="h6" className="manage-ftp-setting-div">
|
|
143
|
+
{serverOptions.length && <CapHeading type="h6" className="manage-ftp-setting-div">
|
|
144
144
|
{formatMessage(messages.ftpServerDesc)}
|
|
145
145
|
<CapLink
|
|
146
146
|
title={formatMessage(messages.manageFTPSettings)}
|
|
147
147
|
className="select-server"
|
|
148
148
|
onClick={this.handleManageFTPSettings}
|
|
149
149
|
/>
|
|
150
|
-
</CapHeading>
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
150
|
+
</CapHeading>}
|
|
151
|
+
{serverOptions.length ? (
|
|
152
|
+
<CapRadioCard
|
|
153
|
+
className="select-account"
|
|
154
|
+
onChange={this.onChangeFTPServer}
|
|
155
|
+
panes={serverOptions}
|
|
156
|
+
cardHeight="48px"
|
|
157
|
+
cardWidth="276px"
|
|
158
|
+
size="small"
|
|
159
|
+
defaultValue={selectedServer}
|
|
160
|
+
selected={selectedServer}
|
|
161
|
+
/>
|
|
162
|
+
) : (
|
|
163
|
+
<CapHeading type="h6" className="configure-ftp-setting-div">
|
|
164
|
+
{formatMessage(messages.selectFtpServerDesc)}
|
|
165
|
+
<CapLink
|
|
166
|
+
title={formatMessage(messages.manageFTPSettings)}
|
|
167
|
+
className="select-server"
|
|
168
|
+
onClick={this.handleManageFTPSettings}
|
|
169
|
+
/>
|
|
170
|
+
</CapHeading>
|
|
171
|
+
)}
|
|
161
172
|
</CapSpin>
|
|
162
173
|
);
|
|
163
174
|
};
|
|
@@ -176,11 +187,61 @@ export class FTP extends React.Component {
|
|
|
176
187
|
}));
|
|
177
188
|
};
|
|
178
189
|
|
|
190
|
+
getFlatTags = (tags) => {
|
|
191
|
+
const flatTags = [];
|
|
192
|
+
tags.forEach(tag => {
|
|
193
|
+
if ((tag.children || []).length) {
|
|
194
|
+
const innerTags = this.getFlatTags(tag.children);
|
|
195
|
+
flatTags.push(innerTags);
|
|
196
|
+
} else {
|
|
197
|
+
flatTags.push(tag.value);
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
return flattenDeep(flatTags);
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
validateTags(content, tagsParam) {
|
|
205
|
+
const tags = tagsParam;
|
|
206
|
+
const response = {};
|
|
207
|
+
response.valid = true;
|
|
208
|
+
response.unsupportedTags = [];
|
|
209
|
+
const flatTags = this.getFlatTags(tags);
|
|
210
|
+
if (flatTags && flatTags.length) {
|
|
211
|
+
const regex = /{{[(A-Z\w+(\s\w+)*$\(\)@!#$%^&*~.,/\\]+}}/g;
|
|
212
|
+
const matchedTags = [...content.matchAll(regex)];
|
|
213
|
+
matchedTags.forEach((tag) => {
|
|
214
|
+
let ifSupported = !!flatTags.find((t) => t === tag[0]);
|
|
215
|
+
if (!ifSupported) {
|
|
216
|
+
const tagValue = tag[0].substring(this.indexOfEnd(tag[0], '{{'), tag[0].indexOf('}}'));
|
|
217
|
+
response.unsupportedTags.push(tagValue);
|
|
218
|
+
response.valid = false;
|
|
219
|
+
}
|
|
220
|
+
if (response.unsupportedTags.length === 0) {
|
|
221
|
+
response.valid = true;
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
return response;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
indexOfEnd(targetString, string) {
|
|
229
|
+
const io = targetString.indexOf(string);
|
|
230
|
+
return io == -1 ? -1 : io + string.length;
|
|
231
|
+
}
|
|
232
|
+
|
|
179
233
|
getMessageContent = () => {
|
|
180
|
-
const { messageContent } = this.state;
|
|
234
|
+
const { messageContent, tagsTree = []} = this.state;
|
|
181
235
|
const { formatMessage } = this.props.intl;
|
|
182
236
|
const { metaEntities, selectedOfferDetails } = this.props;
|
|
183
237
|
const tagsRaw = metaEntities && metaEntities.tags ? metaEntities.tags.standard : [];
|
|
238
|
+
const validateTagResponse = this.validateTags(messageContent, tagsTree);
|
|
239
|
+
let unsupportedTags = null;
|
|
240
|
+
let errorMessageText = '';
|
|
241
|
+
if (!validateTagResponse.valid) {
|
|
242
|
+
unsupportedTags = validateTagResponse.unsupportedTags.join(', ').toString();
|
|
243
|
+
errorMessageText = formatMessage(messages.unsupportedTagsValidationError, {unsupportedTags})
|
|
244
|
+
}
|
|
184
245
|
return (
|
|
185
246
|
<CapRow>
|
|
186
247
|
<CapColumn span={11}>
|
|
@@ -197,6 +258,7 @@ export class FTP extends React.Component {
|
|
|
197
258
|
label={formatMessage(messages.messageHeader)}
|
|
198
259
|
onChange={this.updateMessageBody}
|
|
199
260
|
value={messageContent}
|
|
261
|
+
errorMessage={errorMessageText}
|
|
200
262
|
/>
|
|
201
263
|
</div>
|
|
202
264
|
</CapColumn>
|
|
@@ -341,9 +403,11 @@ export class FTP extends React.Component {
|
|
|
341
403
|
<CapHeading className="ftp-preview-message-title" type="h3">
|
|
342
404
|
<FormattedMessage {...messages.messageContent}/>
|
|
343
405
|
</CapHeading>
|
|
344
|
-
<
|
|
345
|
-
{messageBody}
|
|
346
|
-
|
|
406
|
+
<CapInput.TextArea
|
|
407
|
+
value={messageBody}
|
|
408
|
+
disabled
|
|
409
|
+
className="ftp-preview-message-content"
|
|
410
|
+
/>
|
|
347
411
|
<CapHeading className="ftp-preview-data-title" type="h3">
|
|
348
412
|
<FormattedMessage {...messages.dataPreview}/>
|
|
349
413
|
</CapHeading>
|
|
@@ -353,7 +417,7 @@ export class FTP extends React.Component {
|
|
|
353
417
|
};
|
|
354
418
|
|
|
355
419
|
showAccountSelection = () => {
|
|
356
|
-
this.setState({ viewMode: UIView.serverSelection, selectedServer: null
|
|
420
|
+
this.setState({ viewMode: UIView.serverSelection, selectedServer: null});
|
|
357
421
|
};
|
|
358
422
|
|
|
359
423
|
selectCsvColumn = (option, label, index) => {
|
|
@@ -5,6 +5,10 @@ export default defineMessages({
|
|
|
5
5
|
id: 'creatives.containersV2.FTP.ftpServerDesc',
|
|
6
6
|
defaultMessage: 'Select the FTP server to send the message data. To add another FTP location, ',
|
|
7
7
|
},
|
|
8
|
+
selectFtpServerDesc: {
|
|
9
|
+
id: 'creatives.containersV2.FTP.selectFtpServerDesc',
|
|
10
|
+
defaultMessage: 'FTP not configured for this org. Please add FTP server ',
|
|
11
|
+
},
|
|
8
12
|
ftpServer: {
|
|
9
13
|
id: 'creatives.containersV2.FTP.ftpServer',
|
|
10
14
|
defaultMessage: 'FTP Server',
|
|
@@ -17,6 +21,10 @@ export default defineMessages({
|
|
|
17
21
|
id: 'creatives.containersV2.FTP.addColumn',
|
|
18
22
|
defaultMessage: 'Add column',
|
|
19
23
|
},
|
|
24
|
+
unsupportedTagsValidationError: {
|
|
25
|
+
id: 'creatives.containersV2.FTP.unsupportedTagsValidationError',
|
|
26
|
+
defaultMessage: 'Unsupported tags: {unsupportedTags}. Please remove them from this message.',
|
|
27
|
+
},
|
|
20
28
|
selectTag: {
|
|
21
29
|
id: 'creatives.containersV2.FTP.selectTag',
|
|
22
30
|
defaultMessage: 'Select tag',
|