@capillarytech/creatives-library 3.10.0 → 3.11.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/assets/lineImageTemplate.png +0 -0
- package/components/TemplatePreview/WechatRichmediaTemplatePreview/index.js +7 -7
- package/components/TemplatePreview/_templatePreview.scss +287 -20
- package/components/TemplatePreview/assets/images/home-screen-android.svg +21 -0
- package/components/TemplatePreview/assets/images/home-screen-ios.svg +16 -0
- package/components/TemplatePreview/assets/images/sms_mobile_android.svg +22 -0
- package/components/TemplatePreview/assets/images/sms_mobile_ios.svg +16 -0
- package/components/TemplatePreview/assets/images/wechat_mobile_android.svg +20 -0
- package/components/TemplatePreview/index.js +203 -31
- package/components/TemplatePreview/messages.js +21 -0
- package/containers/Assets/Gallery/index.js +53 -59
- package/containers/Cap/index.js +1 -0
- package/index.js +6 -0
- package/package.json +1 -1
- package/routes.js +5 -0
- package/services/getSchema.js +4 -1
- package/translations/en.json +40 -4
- package/translations/zh.json +39 -3
- package/v2Components/FormBuilder/index.js +188 -37
- package/v2Components/FormBuilder/messages.js +16 -0
- package/v2Components/MobilePushPreviewV2/index.js +44 -36
- package/v2Components/MobilePushPreviewV2/messages.js +0 -8
- package/v2Components/TemplatePreview/WechatRichmediaTemplatePreview/_wechatRichmediaTemplatePrev.scss +64 -0
- package/v2Components/TemplatePreview/WechatRichmediaTemplatePreview/index.js +100 -18
- package/v2Components/TemplatePreview/WechatRichmediaTemplatePreview/messages.js +12 -0
- package/v2Components/TemplatePreview/_templatePreview.scss +24 -4
- package/v2Components/TemplatePreview/assets/images/home-screen-android.svg +21 -0
- package/v2Components/TemplatePreview/assets/images/home-screen-ios.svg +16 -0
- package/v2Components/TemplatePreview/assets/images/sms_mobile_android.svg +22 -0
- package/v2Components/TemplatePreview/assets/images/wechat-home-screen-android.svg +21 -0
- package/v2Components/TemplatePreview/assets/images/wechat_mobile_android.svg +20 -0
- package/v2Components/TemplatePreview/index.js +162 -23
- package/v2Components/TemplatePreview/messages.js +8 -0
- package/v2Containers/Assets/Gallery/index.js +54 -48
- package/v2Containers/CreativesContainer/SlideBoxContent.js +87 -4
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +1 -1
- package/v2Containers/CreativesContainer/index.js +58 -2
- package/v2Containers/CreativesContainer/messages.js +2 -2
- package/v2Containers/Email/_email.scss +7 -1
- package/v2Containers/Email/index.js +40 -14
- package/v2Containers/Email/messages.js +4 -0
- package/v2Containers/Email/reducer.js +1 -0
- package/v2Containers/EmailWrapper/index.js +7 -5
- package/v2Containers/Line/Create/_lineCreate.scss +40 -19
- package/v2Containers/Line/Create/actions.js +13 -9
- package/v2Containers/Line/Create/index.js +498 -237
- package/v2Containers/Line/Create/initialSchema.js +378 -0
- package/v2Containers/Line/Create/messages.js +42 -2
- package/v2Containers/Line/Create/sagas.js +10 -4
- package/v2Containers/Line/Create/selectors.js +3 -9
- package/v2Containers/Line/CreateWrapper/constants.js +2 -0
- package/v2Containers/Line/CreateWrapper/index.js +117 -0
- package/v2Containers/Line/CreateWrapper/messages.js +55 -0
- package/v2Containers/MobilePush/Create/index.js +5 -0
- package/v2Containers/MobilePush/Edit/index.js +5 -0
- package/v2Containers/MobilepushWrapper/index.js +4 -1
- package/v2Containers/Sms/Create/index.js +2 -1
- package/v2Containers/Sms/Edit/index.js +2 -0
- package/v2Containers/Templates/_templates.scss +24 -1
- package/v2Containers/Templates/actions.js +7 -0
- package/v2Containers/Templates/constants.js +2 -0
- package/v2Containers/Templates/index.js +118 -15
- package/v2Containers/Templates/messages.js +8 -0
- package/v2Containers/Templates/reducer.js +2 -0
- package/v2Containers/TemplatesV2/index.js +5 -4
- package/v2Containers/TemplatesV2/messages.js +4 -0
|
@@ -10,17 +10,114 @@ import React from 'react';
|
|
|
10
10
|
import _ from 'lodash';
|
|
11
11
|
import { injectIntl, FormattedMessage, intlShape } from 'react-intl';
|
|
12
12
|
// import styled from 'styled-components';
|
|
13
|
-
import {CapColumn, CapRow, CapHeading} from '@capillarytech/cap-ui-library';
|
|
13
|
+
import {CapColumn, CapRow, CapHeading, CapIcon, CapButton, CapImage} from '@capillarytech/cap-ui-library';
|
|
14
14
|
import './_templatePreview.scss';
|
|
15
15
|
import {updateCharCount} from '../../utils/smsCharCountV2';
|
|
16
16
|
import messages from './messages';
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
const
|
|
17
|
+
import { WECHAT } from '../../v2Containers/CreativesContainer/constants';
|
|
18
|
+
const wechatBodyNew = require('./assets/images/wechat_mobile_android.svg');
|
|
19
|
+
const smsMobileAndroid = require('./assets/images/sms_mobile_android.svg');
|
|
20
20
|
const androidPushMessagePhone = require('./assets/images/androidPushMessage.svg');
|
|
21
21
|
const iPhonePushMessagePhone = require('./assets/images/iPhonePushMessage.svg');
|
|
22
22
|
|
|
23
23
|
class TemplatePreview extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
|
24
|
+
onPreviewContentClicked = (channel) => {
|
|
25
|
+
const IOSContent = (this.props.templateDataRaw && this.props.templateDataRaw.versions.base.IOS) ||
|
|
26
|
+
((this.props.device === 'iphone' || this.props.device === 'ios') && this.props.content);
|
|
27
|
+
const ANDROIDContent = (this.props.templateDataRaw && this.props.templateDataRaw.versions.base.ANDROID) ||
|
|
28
|
+
(this.props.device === 'android' && this.props.content);
|
|
29
|
+
const mobilePushPreviewContent = [];
|
|
30
|
+
if (this.props.channel === 'MOBILEPUSH') {
|
|
31
|
+
const previewObj = {
|
|
32
|
+
channel: this.props.channel,
|
|
33
|
+
accountId: this.props.templateDataRaw && this.props.templateDataRaw.definition.accountId,
|
|
34
|
+
messageSubject: this.props.templateDataRaw && this.props.templateDataRaw.name,
|
|
35
|
+
id: 'message_content_id_1',
|
|
36
|
+
};
|
|
37
|
+
if (IOSContent) {
|
|
38
|
+
previewObj.iosContent = {
|
|
39
|
+
title: IOSContent.title || IOSContent.header,
|
|
40
|
+
message: IOSContent.message || IOSContent.bodyText,
|
|
41
|
+
deviceType: "IOS",
|
|
42
|
+
expandableDetails: IOSContent.expandableDetails ||
|
|
43
|
+
{
|
|
44
|
+
style: "BIG_PICTURE",
|
|
45
|
+
image: this.props.content.bodyImage,
|
|
46
|
+
message: this.props.content.bodyText,
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (ANDROIDContent) {
|
|
51
|
+
previewObj.androidContent = {
|
|
52
|
+
title: ANDROIDContent.title || ANDROIDContent.header,
|
|
53
|
+
message: ANDROIDContent.message || ANDROIDContent.bodyText,
|
|
54
|
+
deviceType: "ANDROID",
|
|
55
|
+
expandableDetails: ANDROIDContent.expandableDetails ||
|
|
56
|
+
{
|
|
57
|
+
style: "BIG_PICTURE",
|
|
58
|
+
image: this.props.content.bodyImage,
|
|
59
|
+
message: this.props.content.bodyText,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
mobilePushPreviewContent.push(previewObj);
|
|
64
|
+
}
|
|
65
|
+
const previewContent = this.props.channel === 'MOBILEPUSH' ? mobilePushPreviewContent : this.props.content;
|
|
66
|
+
const params = {
|
|
67
|
+
content: previewContent,
|
|
68
|
+
channel,
|
|
69
|
+
};
|
|
70
|
+
this.props.onPreviewContentClicked(params);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
onTestContentClicked = (channel) => {
|
|
74
|
+
let mobilePushPreviewContent = {};
|
|
75
|
+
const IOSContent = (this.props.templateDataRaw && this.props.templateDataRaw.versions.base.IOS) ||
|
|
76
|
+
((this.props.device === 'iphone' || this.props.device === 'ios') && this.props.content);
|
|
77
|
+
const ANDROIDContent = (this.props.templateDataRaw && this.props.templateDataRaw.versions.base.ANDROID) ||
|
|
78
|
+
(this.props.device === 'android' && this.props.content);
|
|
79
|
+
if (this.props.channel === 'MOBILEPUSH') {
|
|
80
|
+
mobilePushPreviewContent = {
|
|
81
|
+
channel: this.props.channel,
|
|
82
|
+
accountId: this.props.templateDataRaw && this.props.templateDataRaw.definition.accountId,
|
|
83
|
+
messageSubject: this.props.templateDataRaw && this.props.templateDataRaw.name,
|
|
84
|
+
id: 'message_content_id_1',
|
|
85
|
+
};
|
|
86
|
+
if (ANDROIDContent) {
|
|
87
|
+
mobilePushPreviewContent.androidContent = {
|
|
88
|
+
title: ANDROIDContent.title || ANDROIDContent.header,
|
|
89
|
+
message: ANDROIDContent.message || ANDROIDContent.bodyText,
|
|
90
|
+
deviceType: "ANDROID",
|
|
91
|
+
expandableDetails: ANDROIDContent.expandableDetails ||
|
|
92
|
+
{
|
|
93
|
+
style: "BIG_PICTURE",
|
|
94
|
+
image: this.props.content.bodyImage,
|
|
95
|
+
message: this.props.content.bodyText,
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
if (IOSContent) {
|
|
100
|
+
mobilePushPreviewContent.iosContent = {
|
|
101
|
+
title: IOSContent.title || IOSContent.header,
|
|
102
|
+
message: IOSContent.message || IOSContent.bodyText,
|
|
103
|
+
deviceType: "IOS",
|
|
104
|
+
expandableDetails: IOSContent.expandableDetails ||
|
|
105
|
+
{
|
|
106
|
+
style: "BIG_PICTURE",
|
|
107
|
+
image: this.props.content.bodyImage,
|
|
108
|
+
message: this.props.content.bodyText,
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const previewContent = this.props.channel === 'MOBILEPUSH' ? mobilePushPreviewContent : this.props.content;
|
|
114
|
+
const params = {
|
|
115
|
+
content: previewContent,
|
|
116
|
+
channel,
|
|
117
|
+
};
|
|
118
|
+
this.props.onTestContentClicked(params);
|
|
119
|
+
};
|
|
120
|
+
|
|
24
121
|
render() {
|
|
25
122
|
let content = channel && channel.toLowerCase() === 'sms' ? [this.props.content] : this.props.content;
|
|
26
123
|
const channel = this.props.channel;
|
|
@@ -50,6 +147,7 @@ class TemplatePreview extends React.Component { // eslint-disable-line react/pre
|
|
|
50
147
|
return undefined;
|
|
51
148
|
});
|
|
52
149
|
}
|
|
150
|
+
const disablePreviewAndTest = this.props.channel === 'MOBILEPUSH' ? !this.props.content.header : (this.props.channel === 'SMS' ? !this.props.content : false);
|
|
53
151
|
return (
|
|
54
152
|
<CapRow>
|
|
55
153
|
{this.props.showCount && <CapColumn span={16}>
|
|
@@ -64,16 +162,45 @@ class TemplatePreview extends React.Component { // eslint-disable-line react/pre
|
|
|
64
162
|
</CapHeading>}
|
|
65
163
|
</CapColumn>}
|
|
66
164
|
<CapColumn span={this.props.showCount ? 8 : 24}>
|
|
165
|
+
{this.props.showTestAndPreviewIcon && this.props.channel !== WECHAT && (
|
|
166
|
+
<div className="test-and-preview-container">
|
|
167
|
+
<CapButton
|
|
168
|
+
style={{
|
|
169
|
+
color: '#2466ea',
|
|
170
|
+
display: 'inline-block',
|
|
171
|
+
padding: '0 6px',
|
|
172
|
+
marginTop: '12px',
|
|
173
|
+
}}
|
|
174
|
+
type="flat"
|
|
175
|
+
onClick={() => this.onPreviewContentClicked(this.props.channel)}
|
|
176
|
+
disabled={disablePreviewAndTest}
|
|
177
|
+
>
|
|
178
|
+
<CapIcon type="eye"/><FormattedMessage {...messages.preview} />
|
|
179
|
+
</CapButton>
|
|
180
|
+
<CapButton
|
|
181
|
+
style={{
|
|
182
|
+
color: '#2466ea',
|
|
183
|
+
display: 'inline-block',
|
|
184
|
+
padding: '0 6px',
|
|
185
|
+
marginTop: '12px',
|
|
186
|
+
}}
|
|
187
|
+
type="flat"
|
|
188
|
+
onClick={() => this.onTestContentClicked(this.props.channel)}
|
|
189
|
+
disabled={disablePreviewAndTest}
|
|
190
|
+
>
|
|
191
|
+
<CapIcon type="lab"/><FormattedMessage {...messages.testMessage} />
|
|
192
|
+
</CapButton>
|
|
193
|
+
</div>
|
|
194
|
+
)}
|
|
67
195
|
<div className={`preview-container ${type === 'embedded' ? 'embedded-preview' : ''}`}>
|
|
68
196
|
{ channel && channel.toLowerCase() === 'sms' &&
|
|
69
197
|
<div>
|
|
70
|
-
<div className="shell align-center" id="sms-preview">
|
|
71
|
-
<
|
|
198
|
+
<div className="shell-v2 align-center" id="sms-preview">
|
|
199
|
+
<CapImage className="preview-image sms" src={smsMobileAndroid} alt="Preview is being generated"/>
|
|
72
200
|
<div className="msgContainer sms">
|
|
73
|
-
<img className="sms-icon" src={smsIcon} alt="Sms icon" />
|
|
74
201
|
<div className={"message-pop sms"}>
|
|
75
202
|
{content && content.length && content.map((msg, index) =>
|
|
76
|
-
<CapColumn key={`"message-pop-content-${index}`} className="message-pop-item align-left" style={{ background: '#
|
|
203
|
+
<CapColumn key={`"message-pop-content-${index}`} className="message-pop-item align-left" style={{ background: '#FFFFFF', color: '#091e42'}}>
|
|
77
204
|
{msg}
|
|
78
205
|
</CapColumn>)
|
|
79
206
|
}
|
|
@@ -96,10 +223,9 @@ class TemplatePreview extends React.Component { // eslint-disable-line react/pre
|
|
|
96
223
|
</div>
|
|
97
224
|
}
|
|
98
225
|
{channel && channel.toLowerCase() === 'wechat' ?
|
|
99
|
-
( <div className="shell align-center" id="sms-preview">
|
|
100
|
-
<
|
|
101
|
-
<div className="msgContainer">
|
|
102
|
-
{this.props.channel.toLowerCase() === 'wechat' ? <div className="sms-icon" style={{ width: '25px', height: '25px', background: '#2E89DF' }}></div> : <img className="sms-icon" src={smsIcon} alt={this.props.intl.formatMessage(messages.smsIcon)} />}
|
|
226
|
+
( <div className="shell-v2 align-center" id="sms-preview">
|
|
227
|
+
<CapImage className="preview-image" src={channel.toLowerCase() === 'wechat' ? wechatBodyNew : smsMobileAndroid} alt="Preview is being generated"/>
|
|
228
|
+
<div className="msgContainer wechat">
|
|
103
229
|
<div className="message-pop align-left" style={{ background: `${this.props.channel.toLowerCase() === 'wechat' ? '#ffffff' : '#3F51B5'}`, color: `${this.props.channel.toLowerCase() === 'wechat' ? '#333333' : '#ffffff'}`}}>{content}
|
|
104
230
|
</div>
|
|
105
231
|
</div>
|
|
@@ -107,10 +233,10 @@ class TemplatePreview extends React.Component { // eslint-disable-line react/pre
|
|
|
107
233
|
) : ''
|
|
108
234
|
}
|
|
109
235
|
{ channel && (channel.toLowerCase() === 'mobilepush') &&
|
|
110
|
-
(<div className="shell align-center" id="mobilepush-preview">
|
|
111
|
-
<
|
|
236
|
+
(<div className="shell-v2 align-center" id="mobilepush-preview">
|
|
237
|
+
<CapImage className="preview-image" src={this.props.device === "android" ? androidPushMessagePhone : iPhonePushMessagePhone} alt={this.props.intl.formatMessage(messages.previewGenerated)}/>
|
|
112
238
|
{(!!content.header || !!content.bodyText || !!content.bodyImage) &&
|
|
113
|
-
<div className={`${this.props.device}-push-message-Container`}>
|
|
239
|
+
<div className={`${this.props.device === 'ios' ? 'iphone' : this.props.device}-push-message-Container`}>
|
|
114
240
|
{this.props.device === "android" ?
|
|
115
241
|
<div className="message-pop align-left">
|
|
116
242
|
<div className="app-name">
|
|
@@ -123,7 +249,7 @@ class TemplatePreview extends React.Component { // eslint-disable-line react/pre
|
|
|
123
249
|
{content.bodyText}
|
|
124
250
|
</div>
|
|
125
251
|
{content.bodyImage && <div className="body-image">
|
|
126
|
-
<
|
|
252
|
+
<CapImage src={content.bodyImage} alt="" />
|
|
127
253
|
</div>}
|
|
128
254
|
{content.actions.filter((action) => action.label).length ?
|
|
129
255
|
<div className="actions">
|
|
@@ -138,7 +264,7 @@ class TemplatePreview extends React.Component { // eslint-disable-line react/pre
|
|
|
138
264
|
<span className="app-icon"></span>{content.appName ? content.appName : "App name"} <i className="material-icons">{this.props.intl.formatMessage(messages.close)}</i>
|
|
139
265
|
</div>
|
|
140
266
|
{content.bodyImage && <div className="body-image">
|
|
141
|
-
<
|
|
267
|
+
<CapImage src={content.bodyImage} alt=""/>
|
|
142
268
|
</div>}
|
|
143
269
|
<div className="title">
|
|
144
270
|
{content.header}
|
|
@@ -156,13 +282,22 @@ class TemplatePreview extends React.Component { // eslint-disable-line react/pre
|
|
|
156
282
|
}
|
|
157
283
|
{
|
|
158
284
|
channel && channel.toLowerCase() === 'line' ? (
|
|
159
|
-
<div className="shell align-center" id="sms-preview">
|
|
160
|
-
<
|
|
161
|
-
<div className="msgContainer">
|
|
162
|
-
<div className="sms-icon" style={{ width: '
|
|
285
|
+
<div className="shell-v2 align-center" id="sms-preview">
|
|
286
|
+
<CapImage className="preview-image" src={wechatBodyNew} alt={this.props.intl.formatMessage(messages.previewGenerated)}/>
|
|
287
|
+
<div className="msgContainer line-preview">
|
|
288
|
+
<div className="sms-icon" style={{ left: 10, borderRadius: '50%', width: '20px', height: '20px', background: '#2E89DF' }}></div>
|
|
163
289
|
<div className="message-pop align-left" style={{ background: '#ffffff', color: '#333333' }}>
|
|
164
|
-
{
|
|
165
|
-
|
|
290
|
+
{
|
|
291
|
+
content && Object.keys(content).map((item) => {
|
|
292
|
+
if (item === 'bodyText' && content[item]) {
|
|
293
|
+
return content[item];
|
|
294
|
+
}
|
|
295
|
+
if (item === 'bodyImage' && content[item]) {
|
|
296
|
+
return <CapImage src={content[item]} alt="brand-name" style={{maxWidth: '100%'}}/>;
|
|
297
|
+
}
|
|
298
|
+
return null;
|
|
299
|
+
})
|
|
300
|
+
}
|
|
166
301
|
</div>
|
|
167
302
|
</div>
|
|
168
303
|
{ (content && content.bodyText) ? <p style={{fontSize: 16, fontWeight: "bold"}}>Chars Count: {content.bodyText.length} / (1600)</p> : '' }
|
|
@@ -189,6 +324,10 @@ TemplatePreview.propTypes = {
|
|
|
189
324
|
unicodeEnabled: PropTypes.bool,
|
|
190
325
|
showCount: PropTypes.bool,
|
|
191
326
|
intl: intlShape.isRequired,
|
|
327
|
+
templateDataRaw: PropTypes.object,
|
|
328
|
+
onPreviewContentClicked: PropTypes.func,
|
|
329
|
+
onTestContentClicked: PropTypes.func,
|
|
330
|
+
showTestAndPreviewIcon: PropTypes.bool,
|
|
192
331
|
};
|
|
193
332
|
|
|
194
333
|
export default (injectIntl(TemplatePreview));
|
|
@@ -50,4 +50,12 @@ export default defineMessages({
|
|
|
50
50
|
id: 'creatives.componentsV2.TemplatePreview.smsIcon',
|
|
51
51
|
defaultMessage: 'Sms Icon',
|
|
52
52
|
},
|
|
53
|
+
preview: {
|
|
54
|
+
id: 'creatives.componentsV2.TemplatePreview.preview',
|
|
55
|
+
defaultMessage: 'Preview',
|
|
56
|
+
},
|
|
57
|
+
testMessage: {
|
|
58
|
+
id: 'creatives.componentsV2.TemplatePreview.testMessage',
|
|
59
|
+
defaultMessage: 'Test Message',
|
|
60
|
+
},
|
|
53
61
|
});
|
|
@@ -81,7 +81,7 @@ export class Gallery extends React.Component { // eslint-disable-line react/pref
|
|
|
81
81
|
const params = {
|
|
82
82
|
name: this.state.searchText,
|
|
83
83
|
};
|
|
84
|
-
this.getAllAssets({params});
|
|
84
|
+
this.getAllAssets({params, resetPage: true});
|
|
85
85
|
}
|
|
86
86
|
if (!this.props.Gallery.fetchingAllAssets && !_.isEmpty(this.props.Gallery.assetList) && this.props.Gallery.assetList[0] && this.props.Gallery.assetList[0].totalCount && this.state.totalCount === 0) {
|
|
87
87
|
this.setState({totalCount: this.props.Gallery.assetList[0].totalCount});
|
|
@@ -98,19 +98,12 @@ export class Gallery extends React.Component { // eslint-disable-line react/pref
|
|
|
98
98
|
name: this.state.searchText,
|
|
99
99
|
sortBy: 'Most Recent',
|
|
100
100
|
};
|
|
101
|
-
this.getAllAssets({params});
|
|
101
|
+
this.getAllAssets({params, resetPage: true});
|
|
102
102
|
}
|
|
103
103
|
if (!nextProps.Gallery.deletingAsset && nextProps.Gallery.assetDeleteError && !_.isEqual(nextProps.Gallery.deletingAsset, this.props.Gallery.deletingAsset)) {
|
|
104
104
|
const message = getMessageObject('error', this.props.intl.formatMessage(messages.assetDeleteFailed), true);
|
|
105
105
|
this.props.globalActions.addMessageToQueue(message);
|
|
106
106
|
}
|
|
107
|
-
if ( nextProps.Gallery.itemDeleted || !nextProps.Gallery.assetUploading) {
|
|
108
|
-
const params = {
|
|
109
|
-
name: this.state.searchText,
|
|
110
|
-
sortBy: 'Most Recent',
|
|
111
|
-
};
|
|
112
|
-
this.getAllAssets({params}, true);
|
|
113
|
-
}
|
|
114
107
|
}
|
|
115
108
|
|
|
116
109
|
componentWillUnmount() {
|
|
@@ -236,18 +229,20 @@ export class Gallery extends React.Component { // eslint-disable-line react/pref
|
|
|
236
229
|
uploadImages(e, {files}) {
|
|
237
230
|
e.preventDefault();
|
|
238
231
|
const _URL = window.URL || window.webkitURL;
|
|
239
|
-
//const file = files[0];
|
|
240
232
|
for (const file in files) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
233
|
+
if (files.hasOwnProperty(file)) {
|
|
234
|
+
const img = new Image();
|
|
235
|
+
const that = this;
|
|
236
|
+
img.src = _URL.createObjectURL(files[file]);
|
|
237
|
+
img.onload = function () {
|
|
238
|
+
const fileParams = {
|
|
239
|
+
width: this.width,
|
|
240
|
+
height: this.height,
|
|
241
|
+
isGeneratePreview: true,
|
|
242
|
+
};
|
|
243
|
+
that.props.actions.uploadAsset(files[file], 'image', fileParams);
|
|
248
244
|
};
|
|
249
|
-
|
|
250
|
-
};
|
|
245
|
+
}
|
|
251
246
|
}
|
|
252
247
|
}
|
|
253
248
|
getIllustrationProps={
|
|
@@ -316,29 +311,34 @@ export class Gallery extends React.Component { // eslint-disable-line react/pref
|
|
|
316
311
|
{
|
|
317
312
|
key: `${currentChannel}-card-${template.name}`,
|
|
318
313
|
title: <span title={template.name} >{template.name}</span>,
|
|
319
|
-
extra: [
|
|
320
|
-
<CapIcon
|
|
321
|
-
className="view-gallery"
|
|
322
|
-
style={{marginRight: '16px'}}
|
|
323
|
-
type="eye"
|
|
324
|
-
onClick={() => { this.openPreviewMode(template); }}
|
|
325
|
-
/>,
|
|
326
|
-
<CapDropdown
|
|
327
|
-
overlay={
|
|
328
|
-
<CapMenu>
|
|
329
|
-
<CapMenu.Item className="delete-gallery" onClick={() => this.deleteAsset(template)}>
|
|
330
|
-
<FormattedMessage {...messages.delete} />
|
|
331
|
-
</CapMenu.Item>
|
|
332
|
-
</CapMenu>
|
|
333
|
-
}
|
|
334
|
-
>
|
|
335
|
-
<CapIcon type="more" />
|
|
336
|
-
</CapDropdown>,
|
|
337
|
-
],
|
|
338
314
|
};
|
|
315
|
+
if (!this.props.isLineAsset) {
|
|
316
|
+
templateData.extra = [
|
|
317
|
+
<CapIcon
|
|
318
|
+
className="view-gallery"
|
|
319
|
+
style={{marginRight: '16px'}}
|
|
320
|
+
type="eye"
|
|
321
|
+
onClick={() => { this.openPreviewMode(template); }}
|
|
322
|
+
/>,
|
|
323
|
+
<CapDropdown
|
|
324
|
+
overlay={
|
|
325
|
+
<CapMenu>
|
|
326
|
+
<CapMenu.Item className="delete-gallery" onClick={() => this.deleteAsset(template)}>
|
|
327
|
+
<FormattedMessage {...messages.delete} />
|
|
328
|
+
</CapMenu.Item>
|
|
329
|
+
</CapMenu>
|
|
330
|
+
}
|
|
331
|
+
>
|
|
332
|
+
<CapIcon type="more" />
|
|
333
|
+
</CapDropdown>,
|
|
334
|
+
];
|
|
335
|
+
}
|
|
339
336
|
if (!this.props.isFullMode) {
|
|
340
337
|
templateData.hoverOption = <CapButton onClick={(e) => handlers.selectAsset(e, template._id)}><FormattedMessage {...messages.select} /></CapButton>;
|
|
341
338
|
}
|
|
339
|
+
if (this.props.isLineAsset) {
|
|
340
|
+
templateData.hoverOption = <CapButton onClick={() => this.props.onGalleryImageSelect(template)}><FormattedMessage {...messages.select} /></CapButton>;
|
|
341
|
+
}
|
|
342
342
|
const secureFilePath = _.get(template, 'metaInfo.secure_file_path');
|
|
343
343
|
templateData.url = secureFilePath || _.get(template, 'metaInfo.public_url');
|
|
344
344
|
return templateData;
|
|
@@ -347,7 +347,7 @@ export class Gallery extends React.Component { // eslint-disable-line react/pref
|
|
|
347
347
|
{filterContent}
|
|
348
348
|
<CapSpin spinning={isLoading} tip={loadingTip} style={{width: "100%"}}>
|
|
349
349
|
{!isLoading && <div>
|
|
350
|
-
{!_.isEmpty(templates) || !_.isEmpty(searchText) ? <div className=
|
|
350
|
+
{!_.isEmpty(templates) || !_.isEmpty(searchText) ? <div className={`pagination-container ${this.props.isLineAsset ? 'gallery-upload' : ''}`}>
|
|
351
351
|
<CapCustomCardList key={`${currentChannel}-card-list`} cardList={cardDataList} type={'Email'} />
|
|
352
352
|
{!_.isEmpty(searchText) && _.isEmpty(templates) && (
|
|
353
353
|
<div style={{ height: '65vh', textAlign: 'center', lineHeight: '65vh'}}>
|
|
@@ -421,21 +421,25 @@ export class Gallery extends React.Component { // eslint-disable-line react/pref
|
|
|
421
421
|
<div style={{ marginTop: '8px', width: '50%'}}>
|
|
422
422
|
<CapInput.Search
|
|
423
423
|
className="search-text"
|
|
424
|
-
style={{width: '210px'}}
|
|
424
|
+
style={{width: `${this.props.isLineAsset ? '324px' : '210px'}`}}
|
|
425
425
|
placeholder={this.props.intl.formatMessage(messages.search)}
|
|
426
426
|
value={this.state.searchText}
|
|
427
427
|
onChange={(e) => this.searchAsset(e.target.value)}
|
|
428
428
|
onClear={() => this.searchAsset('')}
|
|
429
429
|
/>
|
|
430
430
|
</div>
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
<
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
431
|
+
{
|
|
432
|
+
!this.props.isLineAsset && (
|
|
433
|
+
<div style={{ textAlign: 'right', marginTop: '16px', width: '50%'}}>
|
|
434
|
+
<form encType="multipart/form-data" id="myForm">
|
|
435
|
+
<input style={{ display: 'none'}} id="fileName" type="file" onChange={(e) => this.uploadImages(e, {files: e.target.files})} accept="image/*" multiple/>
|
|
436
|
+
<CapButton className="upload-image-gallery" type={this.props.location.query.type !== 'embedded' ? 'primary' : 'secondary'} onClick={(e) => this.openFileDialog(e)} style={{float: 'right'}}>
|
|
437
|
+
<FormattedMessage {...messages.upload} />
|
|
438
|
+
</CapButton>
|
|
439
|
+
</form>
|
|
440
|
+
</div>
|
|
441
|
+
)
|
|
442
|
+
}
|
|
439
443
|
</div>
|
|
440
444
|
) : <input style={{ display: 'none'}} id="fileName" type="file" onChange={(e) => this.uploadImages(e, {files: e.target.files})} accept="image/*" multiple/>;
|
|
441
445
|
const isLoading = this.props.Gallery.assetUploading || this.props.Gallery.fetchingAllAssets;
|
|
@@ -496,6 +500,8 @@ Gallery.propTypes = {
|
|
|
496
500
|
location: PropTypes.object,
|
|
497
501
|
intl: intlShape.isRequired,
|
|
498
502
|
isFullMode: PropTypes.bool,
|
|
503
|
+
isLineAsset: PropTypes.bool,
|
|
504
|
+
onGalleryImageSelect: PropTypes.func,
|
|
499
505
|
};
|
|
500
506
|
|
|
501
507
|
const mapStateToProps = createStructuredSelector({
|
|
@@ -11,12 +11,14 @@ import EmailWrapper from '../EmailWrapper';
|
|
|
11
11
|
import MobilepushWrapper from '../MobilepushWrapper';
|
|
12
12
|
import EmailPreviewV2 from '../../v2Components/EmailPreviewV2';
|
|
13
13
|
import MobilePushPreview from '../../v2Components/MobilePushPreviewV2';
|
|
14
|
+
import LineEdit from '../Line/Create';
|
|
14
15
|
import WechatWrapper from '../WeChat/Wrapper';
|
|
15
16
|
import Facebook from '../Facebook';
|
|
16
17
|
import { RICH_MEDIA, MAP_TEMPLATE, CREATE } from '../WeChat/Wrapper/constants';
|
|
17
18
|
import CallTask from '../CallTask';
|
|
18
19
|
import MobliPushEdit from '../MobilePush/Edit';
|
|
19
20
|
import * as constants from './constants';
|
|
21
|
+
import CreateLineWrapper from '../Line/CreateWrapper';
|
|
20
22
|
const CreativesWrapper = styled.div`
|
|
21
23
|
.ant-popover,
|
|
22
24
|
.ant-notification,
|
|
@@ -41,6 +43,7 @@ function SlideBoxContent(props) {
|
|
|
41
43
|
location,
|
|
42
44
|
isGetFormData,
|
|
43
45
|
getFormData,
|
|
46
|
+
onCreateComplete,
|
|
44
47
|
messageDetails,
|
|
45
48
|
onCreateNew,
|
|
46
49
|
currentChannel,
|
|
@@ -69,7 +72,11 @@ function SlideBoxContent(props) {
|
|
|
69
72
|
selectedWeChatAccount,
|
|
70
73
|
weChatMaptemplateStep,
|
|
71
74
|
onWeChatMaptemplateStepChange,
|
|
75
|
+
onTestContentClicked,
|
|
76
|
+
onPreviewContentClicked,
|
|
72
77
|
onFacebookSubmit,
|
|
78
|
+
saveMessage,
|
|
79
|
+
selectedAccount,
|
|
73
80
|
} = props;
|
|
74
81
|
const type = messageDetails.type.toLowerCase(); // type is context in get tags values : outbound | dvs | referral | loyalty | coupons
|
|
75
82
|
const query = { type: !isFullMode && 'embedded', module: isFullMode ? 'default' : 'library', isEditFromCampaigns: (templateData || {}).isEditFromCampaigns};
|
|
@@ -80,9 +87,11 @@ function SlideBoxContent(props) {
|
|
|
80
87
|
};
|
|
81
88
|
let channel = currentChannel;//for create mode
|
|
82
89
|
const isCreateSms = slidBoxContent === 'createTemplate' && channel === constants.SMS;
|
|
90
|
+
const isCreateLine = slidBoxContent === 'createTemplate' && channel === constants.LINE;
|
|
83
91
|
const isCreateMPush = slidBoxContent === 'createTemplate' && channel === constants.MOBILE_PUSH;
|
|
84
92
|
const isCreateCallTask = slidBoxContent === 'createTemplate' && channel === constants.CALL_TASK;
|
|
85
93
|
let isEditSms = false;
|
|
94
|
+
let isEditLine = false;
|
|
86
95
|
let isEditEmailWithId = false;
|
|
87
96
|
let isEmailEditWithContent = false;
|
|
88
97
|
let isPreview = false;
|
|
@@ -95,16 +104,42 @@ function SlideBoxContent(props) {
|
|
|
95
104
|
if (templateData && channel) {
|
|
96
105
|
channel = templateData.type;// for edit mode with template data
|
|
97
106
|
isEditSms = slidBoxContent === 'editTemplate' && channel === constants.SMS;
|
|
107
|
+
isEditLine = slidBoxContent === 'editTemplate' && channel === constants.LINE;
|
|
98
108
|
isEditCallTask = slidBoxContent === 'editTemplate' && channel === constants.CALL_TASK;
|
|
99
109
|
isEditMPush = slidBoxContent === 'editTemplate' && channel === constants.MOBILE_PUSH;
|
|
100
110
|
isEditEmailWithId = slidBoxContent === 'editTemplate' && channel === constants.EMAIL && templateData._id;
|
|
101
111
|
isEmailEditWithContent = slidBoxContent === 'editTemplate' && channel === constants.EMAIL && !templateData._id;
|
|
102
112
|
isEditFacebook = slidBoxContent === 'editTemplate' && channel === constants.FACEBOOK;
|
|
103
|
-
isPreview = slidBoxContent === 'preview' && channel === constants.SMS;
|
|
113
|
+
isPreview = slidBoxContent === 'preview' && (channel === constants.SMS || channel === constants.LINE);
|
|
104
114
|
isEmailPreview = slidBoxContent === 'preview' && channel === constants.EMAIL;
|
|
105
115
|
isMpushPreview = slidBoxContent === 'preview' && channel === constants.MOBILE_PUSH;
|
|
106
116
|
}
|
|
107
117
|
|
|
118
|
+
const getChannelPreviewContent = (templateDataObject) => {
|
|
119
|
+
switch (templateDataObject.type.toUpperCase()) {
|
|
120
|
+
case constants.SMS:
|
|
121
|
+
return get(templateDataObject, `versions.base['sms-editor']`);
|
|
122
|
+
case constants.LINE: {
|
|
123
|
+
const content = get(templateDataObject, `versions.base.content.messages[0]`, {});
|
|
124
|
+
let previewContent = {};
|
|
125
|
+
if (content.text) {
|
|
126
|
+
previewContent = {
|
|
127
|
+
bodyText: content.text,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
if (content.originalContentUrl) {
|
|
131
|
+
previewContent = {
|
|
132
|
+
...previewContent,
|
|
133
|
+
bodyImage: content.previewImageUrl,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
return previewContent;
|
|
137
|
+
}
|
|
138
|
+
default:
|
|
139
|
+
return get(templateDataObject, `versions.base.content`);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
108
143
|
return (
|
|
109
144
|
<CreativesWrapper>
|
|
110
145
|
{!isFullMode && slidBoxContent === 'templates' && (
|
|
@@ -127,10 +162,10 @@ function SlideBoxContent(props) {
|
|
|
127
162
|
)}
|
|
128
163
|
{isPreview && (
|
|
129
164
|
<TemplatePreview
|
|
130
|
-
content={
|
|
165
|
+
content={getChannelPreviewContent(templateData)}
|
|
131
166
|
unicodeEnabled={get(templateData, `versions.base['unicode-validity']`)}
|
|
132
167
|
channel={templateData.type.toLowerCase()}
|
|
133
|
-
charCounterEnabled
|
|
168
|
+
charCounterEnabled={channel === constants.SMS}
|
|
134
169
|
templateData={templateData}
|
|
135
170
|
showCount
|
|
136
171
|
forwardedTags={forwardedTags}
|
|
@@ -185,6 +220,8 @@ function SlideBoxContent(props) {
|
|
|
185
220
|
templateData={templateData}
|
|
186
221
|
forwardedTags={forwardedTags}
|
|
187
222
|
selectedOfferDetails={selectedOfferDetails}
|
|
223
|
+
onPreviewContentClicked={onPreviewContentClicked}
|
|
224
|
+
onTestContentClicked={onTestContentClicked}
|
|
188
225
|
/>
|
|
189
226
|
)}
|
|
190
227
|
{
|
|
@@ -218,6 +255,8 @@ function SlideBoxContent(props) {
|
|
|
218
255
|
isFullMode={isFullMode}
|
|
219
256
|
forwardedTags={forwardedTags}
|
|
220
257
|
selectedOfferDetails={selectedOfferDetails}
|
|
258
|
+
onPreviewContentClicked={onPreviewContentClicked}
|
|
259
|
+
onTestContentClicked={onTestContentClicked}
|
|
221
260
|
/>
|
|
222
261
|
)}
|
|
223
262
|
{isEmailCreate && (
|
|
@@ -240,6 +279,8 @@ function SlideBoxContent(props) {
|
|
|
240
279
|
onValidationFail={onValidationFail}
|
|
241
280
|
forwardedTags={forwardedTags}
|
|
242
281
|
selectedOfferDetails={selectedOfferDetails}
|
|
282
|
+
onPreviewContentClicked={onPreviewContentClicked}
|
|
283
|
+
onTestContentClicked={onTestContentClicked}
|
|
243
284
|
/>
|
|
244
285
|
)}
|
|
245
286
|
{(isEditEmailWithId || isEmailEditWithContent) && (
|
|
@@ -263,6 +304,8 @@ function SlideBoxContent(props) {
|
|
|
263
304
|
onValidationFail={onValidationFail}
|
|
264
305
|
forwardedTags={forwardedTags}
|
|
265
306
|
selectedOfferDetails={selectedOfferDetails}
|
|
307
|
+
onPreviewContentClicked={onPreviewContentClicked}
|
|
308
|
+
onTestContentClicked={onTestContentClicked}
|
|
266
309
|
/>
|
|
267
310
|
)}
|
|
268
311
|
{isEditMPush &&
|
|
@@ -283,6 +326,8 @@ function SlideBoxContent(props) {
|
|
|
283
326
|
onValidationFail={onValidationFail}
|
|
284
327
|
forwardedTags={forwardedTags}
|
|
285
328
|
selectedOfferDetails={selectedOfferDetails}
|
|
329
|
+
onPreviewContentClicked={onPreviewContentClicked}
|
|
330
|
+
onTestContentClicked={onTestContentClicked}
|
|
286
331
|
/>
|
|
287
332
|
}
|
|
288
333
|
{isCreateMPush &&
|
|
@@ -307,7 +352,9 @@ function SlideBoxContent(props) {
|
|
|
307
352
|
query={query}
|
|
308
353
|
forwardedTags={forwardedTags}
|
|
309
354
|
onValidationFail={onValidationFail}
|
|
310
|
-
selectedOfferDetails={selectedOfferDetails}
|
|
355
|
+
selectedOfferDetails={selectedOfferDetails}
|
|
356
|
+
onPreviewContentClicked={onPreviewContentClicked}
|
|
357
|
+
onTestContentClicked={onTestContentClicked}/>
|
|
311
358
|
}
|
|
312
359
|
{
|
|
313
360
|
isEditFacebook && (
|
|
@@ -319,6 +366,39 @@ function SlideBoxContent(props) {
|
|
|
319
366
|
/>
|
|
320
367
|
)
|
|
321
368
|
}
|
|
369
|
+
{
|
|
370
|
+
isEditLine && (
|
|
371
|
+
<LineEdit
|
|
372
|
+
location={creativesLocationProps}
|
|
373
|
+
params={{
|
|
374
|
+
id: templateData._id,
|
|
375
|
+
mode: templateData.modeType || (templateData.definition && templateData.definition.mode),
|
|
376
|
+
}}
|
|
377
|
+
route={{ name: (templateData.modeType || (templateData.definition && templateData.definition.mode)) === 'image' ? 'edit_image' : 'edit_text' }}
|
|
378
|
+
onCreateComplete={onCreateComplete}
|
|
379
|
+
isFullMode={isFullMode}
|
|
380
|
+
saveMessage={saveMessage}
|
|
381
|
+
getFormSubscriptionData={getFormData}
|
|
382
|
+
isGetFormData={isGetFormData}
|
|
383
|
+
templateData={templateData}
|
|
384
|
+
selectedAccount={selectedAccount}
|
|
385
|
+
/>
|
|
386
|
+
)
|
|
387
|
+
}
|
|
388
|
+
{
|
|
389
|
+
isCreateLine && (
|
|
390
|
+
<CreateLineWrapper
|
|
391
|
+
location={creativesLocationProps}
|
|
392
|
+
onCreateComplete={onCreateComplete}
|
|
393
|
+
isFullMode={isFullMode}
|
|
394
|
+
isGetFormData={isGetFormData}
|
|
395
|
+
saveMessage={saveMessage}
|
|
396
|
+
selectedAccount={selectedAccount}
|
|
397
|
+
templateData={templateData}
|
|
398
|
+
getFormSubscriptionData={getFormData}
|
|
399
|
+
/>
|
|
400
|
+
)
|
|
401
|
+
}
|
|
322
402
|
</CreativesWrapper>
|
|
323
403
|
);
|
|
324
404
|
}
|
|
@@ -359,5 +439,8 @@ SlideBoxContent.propTypes = {
|
|
|
359
439
|
onWeChatMaptemplateStepChange: PropTypes.func,
|
|
360
440
|
weChatMaptemplateStep: PropTypes.string,
|
|
361
441
|
onFacebookSubmit: PropTypes.func,
|
|
442
|
+
onCreateComplete: PropTypes.func,
|
|
443
|
+
saveMessage: PropTypes.func,
|
|
444
|
+
selectedAccount: PropTypes.object,
|
|
362
445
|
};
|
|
363
446
|
export default SlideBoxContent;
|
|
@@ -48,7 +48,7 @@ function SlideBoxHeader(props) {
|
|
|
48
48
|
)}
|
|
49
49
|
{!showTemplateNameHeader && slidBoxContent === 'editTemplate' && (
|
|
50
50
|
<CapHeader
|
|
51
|
-
title={<FormattedMessage {...messages.editMessageContent} />}
|
|
51
|
+
title={<FormattedMessage {...messages.editMessageContent} values={{channel: getChannelLabel(channel)}}/>}
|
|
52
52
|
prefix={creativesMode !== 'edit' && !isFullMode && showPrefix &&
|
|
53
53
|
<PrefixWrapper>
|
|
54
54
|
<CapIcons.backIcon onClick={onShowTemplates} />
|