@capillarytech/creatives-library 2.0.5 → 2.0.7
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/CapTagList/index.js +4 -1
- package/containers/Cap/index.js +2 -2
- package/containers/CreativesContainer/SlideBoxContent.js +129 -0
- package/containers/CreativesContainer/SlideBoxFooter.js +31 -0
- package/containers/CreativesContainer/SlideBoxHeader.js +62 -0
- package/containers/CreativesContainer/actions.js +15 -0
- package/containers/CreativesContainer/constants.js +9 -0
- package/containers/CreativesContainer/index.js +178 -0
- package/containers/CreativesContainer/index.scss +20 -0
- package/containers/CreativesContainer/reducer.js +23 -0
- package/containers/CreativesContainer/sagas.js +11 -0
- package/containers/CreativesContainer/selectors.js +25 -0
- package/containers/CreativesContainer/tests/actions.test.js +18 -0
- package/containers/CreativesContainer/tests/index.test.js +10 -0
- package/containers/CreativesContainer/tests/reducer.test.js +9 -0
- package/containers/CreativesContainer/tests/sagas.test.js +15 -0
- package/containers/CreativesContainer/tests/selectors.test.js +10 -0
- package/containers/Email/index.js +6 -4
- package/containers/Templates/index.js +3 -2
- package/containers/Templates/messages.js +58 -54
- package/containers/TemplatesV2/index.js +14 -20
- package/index.js +1 -1
- package/package.json +2 -2
- package/containers/TemplatesV2/reducer.js +0 -34
- package/containers/TemplatesV2/sagas.js +0 -32
|
@@ -164,14 +164,17 @@ class CapTagList extends React.Component { // eslint-disable-line react/prefer-s
|
|
|
164
164
|
{
|
|
165
165
|
value: "All",
|
|
166
166
|
label: "All",
|
|
167
|
+
key: 'all',
|
|
167
168
|
},
|
|
168
169
|
{
|
|
169
170
|
value: "Outbound",
|
|
170
171
|
label: "Outbound",
|
|
172
|
+
key: 'outbound',
|
|
171
173
|
},
|
|
172
174
|
{
|
|
173
175
|
value: "Loyalty",
|
|
174
176
|
label: "Loyalty",
|
|
177
|
+
key: 'loyalty',
|
|
175
178
|
},
|
|
176
179
|
];
|
|
177
180
|
return (
|
|
@@ -185,7 +188,7 @@ class CapTagList extends React.Component { // eslint-disable-line react/prefer-s
|
|
|
185
188
|
{this.props.moduleFilterEnabled ? <CapSelect getPopupContainer={(triggerNode) => triggerNode.parentNode} style={{width: '250px', marginBottom: '16px', minWidth: 'initial', display: 'inherit'}} onChange={this.props.onContextChange} defaultValue="All" options={options}>
|
|
186
189
|
</CapSelect> : ''}
|
|
187
190
|
<CapTree
|
|
188
|
-
styling={{
|
|
191
|
+
styling={{height: '350px', overflow: 'auto'}}
|
|
189
192
|
onSelect={this.handleOnSelect}
|
|
190
193
|
selectedKeys={this.state.tagValue}
|
|
191
194
|
expandedKeys={this.state.expandedKeys}
|
package/containers/Cap/index.js
CHANGED
|
@@ -10,11 +10,11 @@ import { createStructuredSelector } from 'reselect';
|
|
|
10
10
|
import _ from 'lodash';
|
|
11
11
|
import moment from 'moment';
|
|
12
12
|
import 'moment/locale/zh-cn';
|
|
13
|
+
import isEqual from 'lodash/isEqual';
|
|
13
14
|
import { injectIntl, intlShape } from 'react-intl';
|
|
14
15
|
import TopBar from '../../components/TopBar';
|
|
15
16
|
// import 'moment/locale/en-us';
|
|
16
17
|
import Sidebar from '../../components/Sidebar';
|
|
17
|
-
import isEqual from 'lodash/isEqual';
|
|
18
18
|
import { makeSelectAuthenticated, makeSelectUser } from './selectors';
|
|
19
19
|
import * as actions from './actions';
|
|
20
20
|
import * as locationActions from '../LanguageProvider/actions';
|
|
@@ -314,7 +314,7 @@ export class Cap extends React.Component { // eslint-disable-line react/prefer-s
|
|
|
314
314
|
logout={this.logout}
|
|
315
315
|
/> : ''}
|
|
316
316
|
<div className="main">
|
|
317
|
-
{loggedIn && type !== 'embedded' ? <div id="cap-sidebar" className={'sidebar'}>
|
|
317
|
+
{loggedIn && type !== 'embedded' && this.props.location.pathname !== 'templates' ? <div id="cap-sidebar" className={'sidebar'}>
|
|
318
318
|
<Sidebar
|
|
319
319
|
menuData={menuData}
|
|
320
320
|
productMenuData={productMenuData}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
import TemplatesV2 from '../TemplatesV2';
|
|
5
|
+
import TemplatePreview from '../../components/TemplatePreview';
|
|
6
|
+
import SmsCreate from '../Sms/Create';
|
|
7
|
+
import SmsEdit from '../Sms/Edit';
|
|
8
|
+
import Email from '../Email';
|
|
9
|
+
import * as constants from './constants';
|
|
10
|
+
const CreativesWrapper = styled.div`
|
|
11
|
+
.ant-popover,
|
|
12
|
+
.ant-notification,
|
|
13
|
+
.ant-modal-wrap {
|
|
14
|
+
z-index: 10003;
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
17
|
+
function SlideBoxContent(props) {
|
|
18
|
+
const {
|
|
19
|
+
slidBoxContent,
|
|
20
|
+
onSelectTemplate,
|
|
21
|
+
onPreviewTemplate,
|
|
22
|
+
templateData,
|
|
23
|
+
location,
|
|
24
|
+
isGetFormData,
|
|
25
|
+
getFormData,
|
|
26
|
+
messageDetails,
|
|
27
|
+
onCreateNew,
|
|
28
|
+
} = props;
|
|
29
|
+
const query = { type: 'embedded', module: 'library' };
|
|
30
|
+
const creativesLocationProps = {
|
|
31
|
+
pathname: `/sms/edit`,
|
|
32
|
+
query,
|
|
33
|
+
search: '',
|
|
34
|
+
};
|
|
35
|
+
let isCreateSms = false;
|
|
36
|
+
let isEditSms = false;
|
|
37
|
+
let isEditEmailWithId = false;
|
|
38
|
+
let isEmailEditWithContent = false;
|
|
39
|
+
if (templateData) {
|
|
40
|
+
const channel = templateData.type;
|
|
41
|
+
isEditSms = slidBoxContent === 'editTemplate' && channel === constants.SMS;
|
|
42
|
+
isCreateSms = slidBoxContent === 'createTemplate' && channel === constants.SMS;
|
|
43
|
+
isEditEmailWithId = slidBoxContent === 'editTemplate' && channel === constants.EMAIL && templateData._id;
|
|
44
|
+
isEmailEditWithContent = slidBoxContent === 'editTemplate' && channel === constants.EMAIL && !templateData._id;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<CreativesWrapper>
|
|
49
|
+
{slidBoxContent === 'templates' && (
|
|
50
|
+
<TemplatesV2
|
|
51
|
+
isFullMode={false}
|
|
52
|
+
onSelectTemplate={onSelectTemplate}
|
|
53
|
+
handlePeviewTemplate={onPreviewTemplate}
|
|
54
|
+
location={location}
|
|
55
|
+
createNew={onCreateNew}
|
|
56
|
+
/>
|
|
57
|
+
)}
|
|
58
|
+
{slidBoxContent === 'preview' && (
|
|
59
|
+
<TemplatePreview
|
|
60
|
+
content={templateData.versions.base['sms-editor']}
|
|
61
|
+
channel={templateData.type.toLowerCase()}
|
|
62
|
+
charCounterEnabled
|
|
63
|
+
/>
|
|
64
|
+
)}
|
|
65
|
+
{isEditSms && (
|
|
66
|
+
<SmsEdit
|
|
67
|
+
location={creativesLocationProps}
|
|
68
|
+
route={{ name: 'sms' }}
|
|
69
|
+
isGetFormData={isGetFormData}
|
|
70
|
+
getFormSubscriptionData={getFormData}
|
|
71
|
+
getDefaultTags={messageDetails.type}
|
|
72
|
+
subscriptionTemplateDetails={templateData}
|
|
73
|
+
/>
|
|
74
|
+
)}
|
|
75
|
+
{isCreateSms && (
|
|
76
|
+
<SmsCreate
|
|
77
|
+
location={creativesLocationProps}
|
|
78
|
+
route={{ name: 'sms' }}
|
|
79
|
+
isComponent
|
|
80
|
+
isGetFormData={isGetFormData}
|
|
81
|
+
getFormSubscriptionData={getFormData}
|
|
82
|
+
getDefaultTags={messageDetails.type}
|
|
83
|
+
/>
|
|
84
|
+
)}
|
|
85
|
+
{isEditEmailWithId && (
|
|
86
|
+
<Email
|
|
87
|
+
location={{
|
|
88
|
+
pathname: `/email`,
|
|
89
|
+
query,
|
|
90
|
+
}}
|
|
91
|
+
route={{ name: 'email' }}
|
|
92
|
+
isGetFormData={isGetFormData}
|
|
93
|
+
getFormdata={getFormData}
|
|
94
|
+
params={{ id: templateData._id }}
|
|
95
|
+
templateData={templateData}
|
|
96
|
+
getFormSubscriptionData={getFormData}
|
|
97
|
+
getDefaultTags={messageDetails.type}
|
|
98
|
+
/>
|
|
99
|
+
)}
|
|
100
|
+
{isEmailEditWithContent && (
|
|
101
|
+
<Email
|
|
102
|
+
location={{
|
|
103
|
+
pathname: `/email`,
|
|
104
|
+
query,
|
|
105
|
+
}}
|
|
106
|
+
route={{ name: 'email' }}
|
|
107
|
+
isGetFormData={isGetFormData}
|
|
108
|
+
getFormdata={getFormData}
|
|
109
|
+
params={{ id: templateData._id }}
|
|
110
|
+
templateData={templateData}
|
|
111
|
+
getFormSubscriptionData={getFormData}
|
|
112
|
+
getDefaultTags={messageDetails.type}
|
|
113
|
+
/>
|
|
114
|
+
)}
|
|
115
|
+
</CreativesWrapper>
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
SlideBoxContent.propTypes = {
|
|
119
|
+
slidBoxContent: PropTypes.node,
|
|
120
|
+
onSelectTemplate: PropTypes.func,
|
|
121
|
+
onPreviewTemplate: PropTypes.func,
|
|
122
|
+
templateData: PropTypes.object,
|
|
123
|
+
location: PropTypes.object,
|
|
124
|
+
isGetFormData: PropTypes.bool,
|
|
125
|
+
getFormData: PropTypes.func,
|
|
126
|
+
messageDetails: PropTypes.object,
|
|
127
|
+
onCreateNew: PropTypes.func,
|
|
128
|
+
};
|
|
129
|
+
export default SlideBoxContent;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FormattedMessage } from 'react-intl';
|
|
3
|
+
import { CapButton } from '@capillarytech/cap-ui-library';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
5
|
+
|
|
6
|
+
function SlideBoxHeader(props) {
|
|
7
|
+
const { slidBoxContent, onSave, messages, onEditTemplate } = props;
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<div>
|
|
11
|
+
{(slidBoxContent === 'editTemplate' ||
|
|
12
|
+
slidBoxContent === 'createTemplate') && (
|
|
13
|
+
<CapButton onClick={onSave}>
|
|
14
|
+
<FormattedMessage {...messages.creativesTemplatesSave} />
|
|
15
|
+
</CapButton>
|
|
16
|
+
)}
|
|
17
|
+
{slidBoxContent === 'preview' && (
|
|
18
|
+
<CapButton onClick={onEditTemplate} type="secondary">
|
|
19
|
+
<FormattedMessage {...messages.creativesTemplatesEdit} />
|
|
20
|
+
</CapButton>
|
|
21
|
+
)}
|
|
22
|
+
</div>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
SlideBoxHeader.propTypes = {
|
|
26
|
+
slidBoxContent: PropTypes.node,
|
|
27
|
+
onSave: PropTypes.func,
|
|
28
|
+
messages: PropTypes.object,
|
|
29
|
+
onEditTemplate: PropTypes.func,
|
|
30
|
+
};
|
|
31
|
+
export default SlideBoxHeader;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
import { FormattedMessage } from 'react-intl';
|
|
4
|
+
import { CapHeader, CapIcons } from '@capillarytech/cap-ui-library';
|
|
5
|
+
import PropTypes from 'prop-types';
|
|
6
|
+
|
|
7
|
+
const PrefixWrapper = styled.div`
|
|
8
|
+
margin-right: 16px;
|
|
9
|
+
`;
|
|
10
|
+
function SlideBoxHeader(props) {
|
|
11
|
+
const { slidBoxContent, messages, templateData, onShowTemplates } = props;
|
|
12
|
+
return (
|
|
13
|
+
<div>
|
|
14
|
+
{slidBoxContent === 'templates' && (
|
|
15
|
+
<CapHeader
|
|
16
|
+
title={<FormattedMessage {...messages.creativeTemplates} />}
|
|
17
|
+
description={
|
|
18
|
+
<FormattedMessage {...messages.creativeTemplatesDesc} />
|
|
19
|
+
}
|
|
20
|
+
inline
|
|
21
|
+
/>
|
|
22
|
+
)}
|
|
23
|
+
{slidBoxContent === 'preview' && (
|
|
24
|
+
<CapHeader
|
|
25
|
+
title={templateData.name}
|
|
26
|
+
prefix={
|
|
27
|
+
<PrefixWrapper>
|
|
28
|
+
<CapIcons.backIcon onClick={onShowTemplates} />
|
|
29
|
+
</PrefixWrapper>
|
|
30
|
+
}
|
|
31
|
+
/>
|
|
32
|
+
)}
|
|
33
|
+
{slidBoxContent === 'editTemplate' && (
|
|
34
|
+
<CapHeader
|
|
35
|
+
title={<FormattedMessage {...messages.editMessageContent} />}
|
|
36
|
+
prefix={
|
|
37
|
+
<PrefixWrapper>
|
|
38
|
+
<CapIcons.backIcon onClick={onShowTemplates} />
|
|
39
|
+
</PrefixWrapper>
|
|
40
|
+
}
|
|
41
|
+
/>
|
|
42
|
+
)}
|
|
43
|
+
{slidBoxContent === 'createTemplate' && (
|
|
44
|
+
<CapHeader
|
|
45
|
+
title={<FormattedMessage {...messages.createMessageContent} />}
|
|
46
|
+
prefix={
|
|
47
|
+
<PrefixWrapper>
|
|
48
|
+
<CapIcons.backIcon onClick={onShowTemplates} />
|
|
49
|
+
</PrefixWrapper>
|
|
50
|
+
}
|
|
51
|
+
/>
|
|
52
|
+
)}
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
SlideBoxHeader.propTypes = {
|
|
57
|
+
slidBoxContent: PropTypes.node,
|
|
58
|
+
messages: PropTypes.object,
|
|
59
|
+
templateData: PropTypes.object,
|
|
60
|
+
onShowTemplates: PropTypes.func,
|
|
61
|
+
};
|
|
62
|
+
export default SlideBoxHeader;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { PropTypes } from 'prop-types';
|
|
3
|
+
import {
|
|
4
|
+
CapSlideBox,
|
|
5
|
+
} from '@capillarytech/cap-ui-library';
|
|
6
|
+
import { injectIntl } from 'react-intl';
|
|
7
|
+
import classnames from 'classnames';
|
|
8
|
+
import {isEmpty} from 'lodash';
|
|
9
|
+
import SlideBoxContent from './SlideBoxContent';
|
|
10
|
+
import SlideBoxHeader from './SlideBoxHeader';
|
|
11
|
+
import SlideBoxFooter from './SlideBoxFooter';
|
|
12
|
+
import * as constants from './constants';
|
|
13
|
+
import './index.scss';
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
const classPrefix = 'add-creatives-section';
|
|
17
|
+
class Creatives extends React.Component {
|
|
18
|
+
constructor(props) {
|
|
19
|
+
super(props);
|
|
20
|
+
this.state = {
|
|
21
|
+
showSlideBox: true,
|
|
22
|
+
slidBoxContent: this.getSlideBocContent({mode: props.creativesMode, templateData: props.templateData}),
|
|
23
|
+
templateData: this.getTemplateData(props.templateData),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
componentWillUnmount() {
|
|
27
|
+
console.log("unmounting creatives");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
onSelectTemplate = (template) => {
|
|
32
|
+
this.setState({ slidBoxContent: 'editTemplate', templateData: template });
|
|
33
|
+
};
|
|
34
|
+
onPreviewTemplate = (template) => {
|
|
35
|
+
this.setState({ slidBoxContent: 'preview', templateData: template });
|
|
36
|
+
};
|
|
37
|
+
onEditTemplate = () => {
|
|
38
|
+
this.setState({ slidBoxContent: 'editTemplate', showSlideBox: true });
|
|
39
|
+
};
|
|
40
|
+
onCreateNew = () => {
|
|
41
|
+
this.setState({ slidBoxContent: 'createTemplate', showSlideBox: true });
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
onShowTemplates = () => {
|
|
45
|
+
this.setState({ slidBoxContent: 'templates', showSlideBox: true });
|
|
46
|
+
};
|
|
47
|
+
getSlideBocContent({mode, templateData}) {
|
|
48
|
+
let creativesMode = 'templates';
|
|
49
|
+
if (mode === 'create' && isEmpty(templateData)) {
|
|
50
|
+
creativesMode = 'templates';
|
|
51
|
+
} else if (mode === 'edit') {
|
|
52
|
+
creativesMode = 'editTemplate';
|
|
53
|
+
}
|
|
54
|
+
return creativesMode;
|
|
55
|
+
}
|
|
56
|
+
getCreativesData = (channel, template) => { //from creatives to consumers
|
|
57
|
+
const templateData = {channel };
|
|
58
|
+
if (channel === constants.SMS && template.value.base) {
|
|
59
|
+
templateData.messageBody = template.value.base['sms-editor'];
|
|
60
|
+
} else if (channel === constants.EMAIL && template.value.base) {
|
|
61
|
+
templateData.emailBody = template.value.base.html_content;
|
|
62
|
+
templateData.emailSubject = template.value.base.subject;
|
|
63
|
+
}
|
|
64
|
+
return templateData;
|
|
65
|
+
};
|
|
66
|
+
getTemplateData = (templateData) => { //from consumers to creatives
|
|
67
|
+
if (templateData) {
|
|
68
|
+
const {channel} = templateData;
|
|
69
|
+
let creativesTeplateData = {type: channel };
|
|
70
|
+
if (channel === constants.SMS) {
|
|
71
|
+
const formData = {
|
|
72
|
+
"sms-editor": templateData.messageBody,
|
|
73
|
+
};
|
|
74
|
+
creativesTeplateData = {
|
|
75
|
+
type: channel,
|
|
76
|
+
name: "Campaign message SMS content",
|
|
77
|
+
versions: {
|
|
78
|
+
base: formData,
|
|
79
|
+
history: [formData],
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
} else if (channel === constants.EMAIL) {
|
|
83
|
+
const formData = {
|
|
84
|
+
subject: templateData.emailSubject,
|
|
85
|
+
html_content: templateData.emailBody,
|
|
86
|
+
is_drag_drop: false,
|
|
87
|
+
lang_id: 411,
|
|
88
|
+
iso_code: "en",
|
|
89
|
+
language: "English",
|
|
90
|
+
};
|
|
91
|
+
creativesTeplateData = {
|
|
92
|
+
base: formData,
|
|
93
|
+
edit: true,
|
|
94
|
+
type: channel,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return creativesTeplateData;
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
getFormData = (template) => {
|
|
103
|
+
if (template.validity) {
|
|
104
|
+
this.setState(
|
|
105
|
+
{
|
|
106
|
+
isGetFormData: false,
|
|
107
|
+
},
|
|
108
|
+
() => {
|
|
109
|
+
const channel = this.state.templateData.type;
|
|
110
|
+
const creativesData = this.getCreativesData(channel, template);// convers data to consumer understandable format
|
|
111
|
+
this.props.getCreativesData(creativesData);// send data to consumer
|
|
112
|
+
},
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
toggleShowSlideBox = () => {
|
|
117
|
+
this.setState((prevState) => ({
|
|
118
|
+
...prevState,
|
|
119
|
+
templateData: undefined,
|
|
120
|
+
}), this.props.handleCloseCreatives);
|
|
121
|
+
};
|
|
122
|
+
saveMessage = () => {
|
|
123
|
+
this.setState({ isGetFormData: true });
|
|
124
|
+
};
|
|
125
|
+
render() {
|
|
126
|
+
const {slidBoxContent, isGetFormData, showSlideBox} = this.state;
|
|
127
|
+
const { templateData } = this.state;
|
|
128
|
+
return (
|
|
129
|
+
<div className={classnames(`${classPrefix}`)}>
|
|
130
|
+
<CapSlideBox
|
|
131
|
+
header={
|
|
132
|
+
<SlideBoxHeader
|
|
133
|
+
messages={this.props.messages}
|
|
134
|
+
slidBoxContent={this.state.slidBoxContent}
|
|
135
|
+
templateData={templateData}
|
|
136
|
+
onShowTemplates={this.onShowTemplates}
|
|
137
|
+
/>
|
|
138
|
+
}
|
|
139
|
+
content={
|
|
140
|
+
<SlideBoxContent
|
|
141
|
+
onSelectTemplate={this.onSelectTemplate}
|
|
142
|
+
onPreviewTemplate={this.onPreviewTemplate}
|
|
143
|
+
slidBoxContent={slidBoxContent}
|
|
144
|
+
templateData={templateData}
|
|
145
|
+
location={this.props.location}
|
|
146
|
+
messageDetails={this.props.messageDetails}
|
|
147
|
+
getFormData={this.getFormData}
|
|
148
|
+
onCreateNew={this.onCreateNew}
|
|
149
|
+
isGetFormData={isGetFormData}
|
|
150
|
+
/>
|
|
151
|
+
}
|
|
152
|
+
footer={
|
|
153
|
+
<SlideBoxFooter
|
|
154
|
+
messages={this.props.messages}
|
|
155
|
+
onSave={this.saveMessage}
|
|
156
|
+
onEditTemplate={this.onEditTemplate}
|
|
157
|
+
slidBoxContent={slidBoxContent}
|
|
158
|
+
/>
|
|
159
|
+
}
|
|
160
|
+
handleClose={this.toggleShowSlideBox}
|
|
161
|
+
show={showSlideBox}
|
|
162
|
+
size="size-l"
|
|
163
|
+
/>
|
|
164
|
+
</div>
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
Creatives.propTypes = {
|
|
170
|
+
getCreativesData: PropTypes.func,
|
|
171
|
+
messages: PropTypes.object,
|
|
172
|
+
messageDetails: PropTypes.object,
|
|
173
|
+
creativesMode: PropTypes.string,
|
|
174
|
+
location: PropTypes.object,
|
|
175
|
+
handleCloseCreatives: PropTypes.func,
|
|
176
|
+
templateData: PropTypes.object,
|
|
177
|
+
};
|
|
178
|
+
export default injectIntl(Creatives);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
@import '../../../node_modules/@capillarytech/cap-ui-library/styles/_variables.scss';
|
|
2
|
+
|
|
3
|
+
$classPrefix: add-creatives-section;
|
|
4
|
+
|
|
5
|
+
.#{$classPrefix} {
|
|
6
|
+
.#{$classPrefix}-footer {
|
|
7
|
+
position: absolute;
|
|
8
|
+
bottom: 0;
|
|
9
|
+
left: 1px;
|
|
10
|
+
padding: 0 12px;
|
|
11
|
+
display: flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
height: 48px;
|
|
14
|
+
border-top: 1px solid $CAP_G07;
|
|
15
|
+
|
|
16
|
+
&.with-creative {
|
|
17
|
+
width: 100%;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
*
|
|
3
|
+
* CreativesContainer reducer
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { fromJS } from 'immutable';
|
|
8
|
+
import {
|
|
9
|
+
DEFAULT_ACTION,
|
|
10
|
+
} from './constants';
|
|
11
|
+
|
|
12
|
+
const initialState = fromJS({});
|
|
13
|
+
|
|
14
|
+
function creativesContainerReducer(state = initialState, action) {
|
|
15
|
+
switch (action.type) {
|
|
16
|
+
case DEFAULT_ACTION:
|
|
17
|
+
return state;
|
|
18
|
+
default:
|
|
19
|
+
return state;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default creativesContainerReducer;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// import { take, call, put, select } from 'redux-saga/effects';
|
|
2
|
+
|
|
3
|
+
// Individual exports for testing
|
|
4
|
+
export function* defaultSaga() {
|
|
5
|
+
// See example in containers/HomePage/sagas.js
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// All sagas to be loaded
|
|
9
|
+
export default [
|
|
10
|
+
defaultSaga,
|
|
11
|
+
];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createSelector } from 'reselect';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Direct selector to the creativesContainer state domain
|
|
5
|
+
*/
|
|
6
|
+
const selectCreativesContainerDomain = () => (state) => state.get('creativesContainer');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Other specific selectors
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Default selector used by CreativesContainer
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const makeSelectCreativesContainer = () => createSelector(
|
|
18
|
+
selectCreativesContainerDomain(),
|
|
19
|
+
(substate) => substate.toJS()
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
export default makeSelectCreativesContainer;
|
|
23
|
+
export {
|
|
24
|
+
selectCreativesContainerDomain,
|
|
25
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
import {
|
|
3
|
+
defaultAction,
|
|
4
|
+
} from '../actions';
|
|
5
|
+
import {
|
|
6
|
+
DEFAULT_ACTION,
|
|
7
|
+
} from '../constants';
|
|
8
|
+
|
|
9
|
+
describe('CreativesContainer actions', () => {
|
|
10
|
+
describe('Default Action', () => {
|
|
11
|
+
it('has a type of DEFAULT_ACTION', () => {
|
|
12
|
+
const expected = {
|
|
13
|
+
type: DEFAULT_ACTION,
|
|
14
|
+
};
|
|
15
|
+
expect(defaultAction()).toEqual(expected);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// import React from 'react';
|
|
2
|
+
// import { shallow } from 'enzyme';
|
|
3
|
+
|
|
4
|
+
// import { CreativesContainer } from '../index';
|
|
5
|
+
|
|
6
|
+
describe('<CreativesContainer />', () => {
|
|
7
|
+
it('Expect to have unit tests specified', () => {
|
|
8
|
+
expect(true).toEqual(true);
|
|
9
|
+
});
|
|
10
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
|
|
2
|
+
import { fromJS } from 'immutable';
|
|
3
|
+
import creativesContainerReducer from '../reducer';
|
|
4
|
+
|
|
5
|
+
describe('creativesContainerReducer', () => {
|
|
6
|
+
it('returns the initial state', () => {
|
|
7
|
+
expect(creativesContainerReducer(undefined, {})).toEqual(fromJS({}));
|
|
8
|
+
});
|
|
9
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test sagas
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/* eslint-disable redux-saga/yield-effects */
|
|
6
|
+
// import { take, call, put, select } from 'redux-saga/effects';
|
|
7
|
+
// import { defaultSaga } from '../sagas';
|
|
8
|
+
|
|
9
|
+
// const generator = defaultSaga();
|
|
10
|
+
|
|
11
|
+
describe('defaultSaga Saga', () => {
|
|
12
|
+
it('Expect to have unit tests specified', () => {
|
|
13
|
+
expect(true).toEqual(true);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// import { fromJS } from 'immutable';
|
|
2
|
+
// import { makeSelectCreativesContainerDomain } from '../selectors';
|
|
3
|
+
|
|
4
|
+
// const selector = makeSelectCreativesContainerDomain();
|
|
5
|
+
|
|
6
|
+
describe('makeSelectCreativesContainerDomain', () => {
|
|
7
|
+
it('Expect to have unit tests specified', () => {
|
|
8
|
+
expect(true).toEqual(true);
|
|
9
|
+
});
|
|
10
|
+
});
|
|
@@ -2007,12 +2007,14 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
2007
2007
|
|
|
2008
2008
|
showSubject = () => {
|
|
2009
2009
|
const schema = _.cloneDeep(this.state.schema);
|
|
2010
|
-
if (
|
|
2010
|
+
if (schema.standalone) {
|
|
2011
|
+
if (this.props.location.query.type === 'embedded' && (this.props.location.query.module === "loyalty" || this.props.location.query.module === "dvs" || this.props.location.query.module === "timeline" || this.props.location.query.module === "coupon_expiry" ||
|
|
2011
2012
|
this.props.location.query.module === "library")) {
|
|
2012
|
-
|
|
2013
|
-
|
|
2013
|
+
schema.standalone.sections[0].inputFields[0].style.display = "";
|
|
2014
|
+
schema.standalone.sections[0].inputFields[0].labelStyle.display = "";
|
|
2015
|
+
}
|
|
2016
|
+
this.setState({schema});
|
|
2014
2017
|
}
|
|
2015
|
-
this.setState({schema});
|
|
2016
2018
|
}
|
|
2017
2019
|
|
|
2018
2020
|
handleOnItemClick = (isSelected, id) => {
|
|
@@ -1262,7 +1262,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1262
1262
|
onChange={(e) => this.searchTemplate(e.target.value)}
|
|
1263
1263
|
/>
|
|
1264
1264
|
{this.props.isComponent ? <div style={{display: "flex", justifyContent: "space-between", alignItems: 'center'}}>
|
|
1265
|
-
<CapButton type="secondary" onClick={() => this.props.isComponent ? this.handleBlankTemplateAction() : this.createTemplate()}>{
|
|
1265
|
+
<CapButton type="secondary" onClick={() => this.props.isComponent ? this.handleBlankTemplateAction() : this.createTemplate()}>{ this.props.intl.formatMessage(messages.createNewActionButton) }</CapButton>
|
|
1266
1266
|
</div>
|
|
1267
1267
|
:
|
|
1268
1268
|
<div className="action-container">
|
|
@@ -1557,7 +1557,7 @@ Templates.propTypes = {
|
|
|
1557
1557
|
smsEditActions: PropTypes.object,
|
|
1558
1558
|
ebillActions: PropTypes.object,
|
|
1559
1559
|
emailActions: PropTypes.object,
|
|
1560
|
-
TemplatesList: PropTypes.
|
|
1560
|
+
TemplatesList: PropTypes.array,
|
|
1561
1561
|
Templates: PropTypes.object,
|
|
1562
1562
|
route: PropTypes.object,
|
|
1563
1563
|
router: PropTypes.object,
|
|
@@ -1570,6 +1570,7 @@ Templates.propTypes = {
|
|
|
1570
1570
|
onSelectTemplate: PropTypes.func,
|
|
1571
1571
|
lineActions: PropTypes.object,
|
|
1572
1572
|
isComponent: PropTypes.bool,
|
|
1573
|
+
renderNewCardGrid: PropTypes.func,
|
|
1573
1574
|
};
|
|
1574
1575
|
|
|
1575
1576
|
const mapStateToProps = createStructuredSelector({
|
|
@@ -6,175 +6,175 @@
|
|
|
6
6
|
import { defineMessages } from 'react-intl';
|
|
7
7
|
|
|
8
8
|
export default defineMessages({
|
|
9
|
-
header: {
|
|
9
|
+
"header": {
|
|
10
10
|
id: 'app.containers.Templates.header',
|
|
11
11
|
defaultMessage: 'This is Templates container !',
|
|
12
12
|
},
|
|
13
|
-
uploadedAt: {
|
|
13
|
+
"uploadedAt": {
|
|
14
14
|
id: 'app.containers.Templates.uploadedAt',
|
|
15
15
|
defaultMessage: 'Modified',
|
|
16
16
|
},
|
|
17
|
-
uploadedBy: {
|
|
17
|
+
"uploadedBy": {
|
|
18
18
|
id: 'app.containers.Templates.uploadedBy',
|
|
19
19
|
defaultMessage: 'Uploaded By',
|
|
20
20
|
},
|
|
21
|
-
mapTemplate: {
|
|
21
|
+
"mapTemplate": {
|
|
22
22
|
id: 'app.containers.Templates.mapTemplate',
|
|
23
23
|
defaultMessage: 'Map Template',
|
|
24
24
|
},
|
|
25
|
-
somethingWentWrong: {
|
|
25
|
+
"somethingWentWrong": {
|
|
26
26
|
id: 'app.containers.Templates.somethingWentWrong',
|
|
27
27
|
defaultMessage: 'Something Went Wrong!!',
|
|
28
28
|
},
|
|
29
|
-
wechatHeader: {
|
|
29
|
+
"wechatHeader": {
|
|
30
30
|
id: 'app.containers.Templates.wechatHeader',
|
|
31
31
|
defaultMessage: 'WECHAT',
|
|
32
32
|
},
|
|
33
|
-
smsHeader: {
|
|
33
|
+
"smsHeader": {
|
|
34
34
|
id: 'app.containers.Templates.smsHeader',
|
|
35
35
|
defaultMessage: 'SMS',
|
|
36
36
|
},
|
|
37
|
-
emailHeader: {
|
|
37
|
+
"emailHeader": {
|
|
38
38
|
id: 'app.containers.Templates.emailHeader',
|
|
39
39
|
defaultMessage: 'Email',
|
|
40
40
|
},
|
|
41
|
-
mobilepushHeader: {
|
|
41
|
+
"mobilepushHeader": {
|
|
42
42
|
id: 'app.containers.Templates.mobilepushHeader',
|
|
43
43
|
defaultMessage: 'Mobile Push',
|
|
44
44
|
},
|
|
45
|
-
ebillHeader: {
|
|
45
|
+
"ebillHeader": {
|
|
46
46
|
id: 'app.containers.Templates.ebillHeader',
|
|
47
47
|
defaultMessage: 'Ebill',
|
|
48
48
|
},
|
|
49
|
-
lineHeader: {
|
|
49
|
+
"lineHeader": {
|
|
50
50
|
id: 'app.containers.Templates.lineHeader',
|
|
51
51
|
defaultMessage: 'Line',
|
|
52
52
|
},
|
|
53
|
-
selectWechatHeader: {
|
|
53
|
+
"selectWechatHeader": {
|
|
54
54
|
id: 'app.containers.Templates.selectWechatHeader',
|
|
55
55
|
defaultMessage: 'Select WECHAT Template',
|
|
56
56
|
},
|
|
57
|
-
selectSmsHeader: {
|
|
57
|
+
"selectSmsHeader": {
|
|
58
58
|
id: 'app.containers.Templates.selectSmsHeader',
|
|
59
59
|
defaultMessage: 'Select SMS Template',
|
|
60
60
|
},
|
|
61
|
-
selectAccount: {
|
|
61
|
+
"selectAccount": {
|
|
62
62
|
id: 'app.containers.Templates.selectAccount',
|
|
63
63
|
defaultMessage: "Select Account",
|
|
64
64
|
},
|
|
65
|
-
gettingAllTemplates: {
|
|
65
|
+
"gettingAllTemplates": {
|
|
66
66
|
id: 'app.containers.Templates.gettingAllTemplates',
|
|
67
67
|
defaultMessage: "Getting all templates...",
|
|
68
68
|
},
|
|
69
|
-
smsChannelTemplatesHeader: {
|
|
69
|
+
"smsChannelTemplatesHeader": {
|
|
70
70
|
id: 'app.containers.Templates.smsChannelTemplatesHeader',
|
|
71
71
|
defaultMessage: "SMS Templates",
|
|
72
72
|
},
|
|
73
|
-
wechatChannelTemplatesHeader: {
|
|
73
|
+
"wechatChannelTemplatesHeader": {
|
|
74
74
|
id: 'app.containers.Templates.wechatChannelTemplatesHeader',
|
|
75
75
|
defaultMessage: "WECHAT Templates",
|
|
76
76
|
},
|
|
77
|
-
blankTemplate: {
|
|
77
|
+
"blankTemplate": {
|
|
78
78
|
id: 'app.containers.Templates.blankTemplate',
|
|
79
79
|
defaultMessage: "Blank Template",
|
|
80
80
|
},
|
|
81
|
-
selectButton: {
|
|
81
|
+
"selectButton": {
|
|
82
82
|
id: 'app.containers.Templates.selectButton',
|
|
83
83
|
defaultMessage: "Select",
|
|
84
84
|
},
|
|
85
|
-
previewButton: {
|
|
85
|
+
"previewButton": {
|
|
86
86
|
id: 'app.containers.Templates.previewButton',
|
|
87
87
|
defaultMessage: "Preview",
|
|
88
88
|
},
|
|
89
|
-
editButton: {
|
|
89
|
+
"editButton": {
|
|
90
90
|
id: 'app.containers.Templates.editButton',
|
|
91
91
|
defaultMessage: "Edit",
|
|
92
92
|
},
|
|
93
|
-
duplicateButton: {
|
|
93
|
+
"duplicateButton": {
|
|
94
94
|
id: 'app.containers.Templates.duplicateButton',
|
|
95
95
|
defaultMessage: "Duplicate",
|
|
96
96
|
},
|
|
97
|
-
deleteButton: {
|
|
97
|
+
"deleteButton": {
|
|
98
98
|
id: 'app.containers.Templates.deleteButton',
|
|
99
99
|
defaultMessage: "Delete",
|
|
100
100
|
},
|
|
101
|
-
mostRecentOption: {
|
|
101
|
+
"mostRecentOption": {
|
|
102
102
|
id: 'app.containers.Templates.mostRecentOption',
|
|
103
103
|
defaultMessage: "Most Recent",
|
|
104
104
|
},
|
|
105
|
-
alphabeticallyOption: {
|
|
105
|
+
"alphabeticallyOption": {
|
|
106
106
|
id: 'app.containers.Templates.alphabeticallyOption',
|
|
107
107
|
defaultMessage: "Alphabetically",
|
|
108
108
|
},
|
|
109
|
-
searchText: {
|
|
109
|
+
"searchText": {
|
|
110
110
|
id: 'app.containers.Templates.searchText',
|
|
111
111
|
defaultMessage: "Search",
|
|
112
112
|
},
|
|
113
|
-
noAccountMessage: {
|
|
113
|
+
"noAccountMessage": {
|
|
114
114
|
id: 'app.containers.Templates.noAccountMessage',
|
|
115
115
|
defaultMessage: "Please select an account to proceed",
|
|
116
116
|
},
|
|
117
|
-
noTemplatesMessage: {
|
|
117
|
+
"noTemplatesMessage": {
|
|
118
118
|
id: 'app.containers.Templates.noTemplatesMessage',
|
|
119
119
|
defaultMessage: "No Templates Available",
|
|
120
120
|
},
|
|
121
|
-
createSmsActionButton: {
|
|
121
|
+
"createSmsActionButton": {
|
|
122
122
|
id: 'app.containers.Templates.createSmsActionButton',
|
|
123
123
|
defaultMessage: "Create SMS",
|
|
124
124
|
},
|
|
125
|
-
createEmailActionButton: {
|
|
125
|
+
"createEmailActionButton": {
|
|
126
126
|
id: 'app.containers.Templates.createEmailActionButton',
|
|
127
127
|
defaultMessage: "Create Email",
|
|
128
128
|
},
|
|
129
|
-
sortBy: {
|
|
129
|
+
"sortBy": {
|
|
130
130
|
id: 'app.containers.Templates.sortBy',
|
|
131
131
|
defaultMessage: "Sort by",
|
|
132
132
|
},
|
|
133
|
-
unMapButton: {
|
|
133
|
+
"unMapButton": {
|
|
134
134
|
id: 'app.containers.Templates.unMapButton',
|
|
135
135
|
defaultMessage: "Unmap",
|
|
136
136
|
},
|
|
137
|
-
templateDuplicateSuccess: {
|
|
137
|
+
"templateDuplicateSuccess": {
|
|
138
138
|
id: 'app.containers.Templates.templateDuplicateSuccess',
|
|
139
139
|
defaultMessage: "Template Duplicated Successfully",
|
|
140
140
|
},
|
|
141
|
-
templateDeleteSuccess: {
|
|
141
|
+
"templateDeleteSuccess": {
|
|
142
142
|
id: 'app.containers.Templates.templateDeleteSuccess',
|
|
143
143
|
defaultMessage: "SMS Template Deleted Successfully",
|
|
144
144
|
},
|
|
145
|
-
uploadFile: {
|
|
145
|
+
"uploadFile": {
|
|
146
146
|
id: 'app.containers.Templates.uploadFile',
|
|
147
147
|
defaultMessage: "Upload File",
|
|
148
148
|
},
|
|
149
|
-
useEditor: {
|
|
149
|
+
"useEditor": {
|
|
150
150
|
id: 'app.containers.Templates.useEditor',
|
|
151
151
|
defaultMessage: "Use Editor",
|
|
152
152
|
},
|
|
153
|
-
newTemplate: {
|
|
153
|
+
"newTemplate": {
|
|
154
154
|
id: 'app.containers.Templates.newTemplate',
|
|
155
155
|
defaultMessage: "New Template",
|
|
156
156
|
},
|
|
157
|
-
uploadingFile: {
|
|
157
|
+
"uploadingFile": {
|
|
158
158
|
id: 'app.containers.Templates.uploadingFile',
|
|
159
159
|
defaultMessage: "Uploading File",
|
|
160
160
|
},
|
|
161
|
-
zipUploadFailed: {
|
|
161
|
+
"zipUploadFailed": {
|
|
162
162
|
id: 'app.containers.Templates.zipUploadFailed',
|
|
163
163
|
defaultMessage: 'Failed to Upload zip file',
|
|
164
164
|
},
|
|
165
|
-
campaigns: {
|
|
165
|
+
"campaigns": {
|
|
166
166
|
id: 'app.containers.Templates.campaigns',
|
|
167
167
|
defaultMessage: 'Campaigns',
|
|
168
168
|
},
|
|
169
|
-
creatives: {
|
|
169
|
+
"creatives": {
|
|
170
170
|
id: 'app.containers.Templates.creatives',
|
|
171
171
|
defaultMessage: 'Creatives',
|
|
172
172
|
},
|
|
173
|
-
ebillPreview: {
|
|
173
|
+
"ebillPreview": {
|
|
174
174
|
id: 'app.containers.Templates.ebillPreview',
|
|
175
175
|
defaultMessage: 'Ebill Preview',
|
|
176
176
|
},
|
|
177
|
-
emailPreview: {
|
|
177
|
+
"emailPreview": {
|
|
178
178
|
id: 'app.containers.Templates.emailPreview',
|
|
179
179
|
defaultMessage: 'Email Preview',
|
|
180
180
|
},
|
|
@@ -186,48 +186,52 @@ export default defineMessages({
|
|
|
186
186
|
id: 'app.containers.Templates.deletionFailed',
|
|
187
187
|
defaultMessage: 'Template deletion failed',
|
|
188
188
|
},
|
|
189
|
-
preview: {
|
|
189
|
+
"preview": {
|
|
190
190
|
id: 'app.containers.Templates.preview',
|
|
191
191
|
defaultMessage: 'Preview',
|
|
192
192
|
},
|
|
193
|
-
invalidUploadFileError: {
|
|
193
|
+
"invalidUploadFileError": {
|
|
194
194
|
id: 'app.containers.Templates.invalidUploadFileError',
|
|
195
195
|
defaultMessage: 'File cannot be uploaded. Please select another file with valid file format.',
|
|
196
196
|
},
|
|
197
|
-
templateDeleteConfirm: {
|
|
197
|
+
"templateDeleteConfirm": {
|
|
198
198
|
id: 'app.containers.Templates.templateDeleteConfirm',
|
|
199
199
|
defaultMessage: 'Are you sure you want to delete this Template?',
|
|
200
200
|
},
|
|
201
|
-
cancelText: {
|
|
201
|
+
"cancelText": {
|
|
202
202
|
id: 'app.containers.Templates.cancelText',
|
|
203
203
|
defaultMessage: 'Cancel',
|
|
204
204
|
},
|
|
205
|
-
yesText: {
|
|
205
|
+
"yesText": {
|
|
206
206
|
id: 'app.containers.Templates.yesText',
|
|
207
207
|
defaultMessage: 'Yes',
|
|
208
208
|
},
|
|
209
|
-
templateSelection: {
|
|
209
|
+
"templateSelection": {
|
|
210
210
|
id: 'app.containers.Templates.templateSelection',
|
|
211
211
|
defaultMessage: 'Template Selection',
|
|
212
212
|
},
|
|
213
|
-
layoutSelection: {
|
|
213
|
+
"layoutSelection": {
|
|
214
214
|
id: 'app.containers.Templates.layoutSelection',
|
|
215
215
|
defaultMessage: 'Select Layout',
|
|
216
216
|
},
|
|
217
|
-
textTemplate: {
|
|
217
|
+
"textTemplate": {
|
|
218
218
|
id: 'app.containers.Templates.textTemplate',
|
|
219
219
|
defaultMessage: 'Text',
|
|
220
220
|
},
|
|
221
|
-
imageTemplate: {
|
|
221
|
+
"imageTemplate": {
|
|
222
222
|
id: 'app.containers.Templates.imageTemplate',
|
|
223
223
|
defaultMessage: 'Image',
|
|
224
224
|
},
|
|
225
|
-
selectDefaultButton: {
|
|
225
|
+
"selectDefaultButton": {
|
|
226
226
|
id: 'app.containers.Templates.selectDefaultButton',
|
|
227
227
|
defaultMessage: 'Select',
|
|
228
228
|
},
|
|
229
|
-
previewGenerateText: {
|
|
229
|
+
"previewGenerateText": {
|
|
230
230
|
id: 'app.containers.Templates.previewGenerateText',
|
|
231
231
|
defaultMessage: 'Preview is being generated...',
|
|
232
232
|
},
|
|
233
|
+
"createNewActionButton": {
|
|
234
|
+
id: 'app.containers.Templates.createNewActionButton',
|
|
235
|
+
defaultMessage: 'Create new',
|
|
236
|
+
},
|
|
233
237
|
});
|
|
@@ -8,7 +8,7 @@ import PropTypes from 'prop-types';
|
|
|
8
8
|
|
|
9
9
|
import React from 'react';
|
|
10
10
|
import { connect } from 'react-redux';
|
|
11
|
-
import { injectIntl } from 'react-intl';
|
|
11
|
+
import { injectIntl, intlShape } from 'react-intl';
|
|
12
12
|
import { createStructuredSelector } from 'reselect';
|
|
13
13
|
import { bindActionCreators } from 'redux';
|
|
14
14
|
import { CapTab, CapCard, CapIcons, CapButton } from '@capillarytech/cap-ui-library';
|
|
@@ -26,10 +26,10 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
26
26
|
this.state = {
|
|
27
27
|
selectedChannel: this.props.channel || 'sms',
|
|
28
28
|
panes: [
|
|
29
|
-
{content: this.getTemplatesComponent('sms'), tab: 'Sms', key: 'sms
|
|
30
|
-
{content: this.getTemplatesComponent('email'), tab: 'Email', key: 'email
|
|
31
|
-
{content: this.getTemplatesComponent('wechat'), tab: 'Wechat', key: 'wechat
|
|
32
|
-
{content: this.getTemplatesComponent('mobilepush'), tab: 'Mpush', key: '
|
|
29
|
+
{content: this.getTemplatesComponent('sms'), tab: 'Sms', key: 'sms'},
|
|
30
|
+
{content: this.getTemplatesComponent('email'), tab: 'Email', key: 'email'},
|
|
31
|
+
{content: this.getTemplatesComponent('wechat'), tab: 'Wechat', key: 'wechat'},
|
|
32
|
+
{content: this.getTemplatesComponent('mobilepush'), tab: 'Mpush', key: 'mobilepush'},
|
|
33
33
|
],
|
|
34
34
|
};
|
|
35
35
|
}
|
|
@@ -39,7 +39,7 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
39
39
|
{
|
|
40
40
|
title: template.name,
|
|
41
41
|
content: template.versions.base['sms-editor'],
|
|
42
|
-
extra: [<View onClick={() => { this.props.isFullMode
|
|
42
|
+
extra: [<View onClick={() => { if (this.props.isFullMode) { handlers.handlePreviewClick(template); } else { this.props.handlePeviewTemplate(template); } }} />],
|
|
43
43
|
hoverOption: <CapButton onClick={(e) => handlers.handleEditClick(e, template._id)}>{this.props.intl.formatMessage(this.props.isFullMode ? messages.edit : messages.select)}</CapButton>,
|
|
44
44
|
}));
|
|
45
45
|
return (<div>
|
|
@@ -54,7 +54,8 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
54
54
|
query = {type: 'embedded', module: 'library'};
|
|
55
55
|
}
|
|
56
56
|
return (<Templates
|
|
57
|
-
|
|
57
|
+
key={channel}
|
|
58
|
+
location={{pathname: `/${channel}`, search: '', query}}
|
|
58
59
|
route={{name: channel}}
|
|
59
60
|
router={this.props.router}
|
|
60
61
|
isComponent={!this.props.isFullMode}
|
|
@@ -74,25 +75,17 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
74
75
|
}
|
|
75
76
|
return pane;
|
|
76
77
|
});
|
|
77
|
-
this.setState({panes});
|
|
78
|
+
this.setState({panes, selectedChannel});
|
|
78
79
|
}
|
|
79
80
|
isLoading() {
|
|
80
81
|
return this.props.Templates.loadingTemplates;
|
|
81
82
|
}
|
|
82
83
|
render() {
|
|
83
84
|
return (
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
// templateData={this.state.previewTemplate}
|
|
89
|
-
// channel={this.state.selectedChannel}
|
|
90
|
-
// handleClose={this.togglePreview}
|
|
91
|
-
// onEditClick={this.handleEditClick}
|
|
92
|
-
// onDuplicateClick={this.duplicateTemplate}
|
|
93
|
-
// location={this.props.location}
|
|
94
|
-
// />}
|
|
95
|
-
// </CapSpin>
|
|
85
|
+
<div>
|
|
86
|
+
<CapTab panes={this.state.panes} onChange={this.channelChange} activeKey={this.state.selectedChannel} defaultActiveKey={this.state.selectedChannel}/>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
96
89
|
);
|
|
97
90
|
}
|
|
98
91
|
}
|
|
@@ -106,6 +99,7 @@ TemplatesV2.propTypes = {
|
|
|
106
99
|
Templates: PropTypes.object,
|
|
107
100
|
TemplatesList: PropTypes.arrayOf(PropTypes.object),
|
|
108
101
|
handlePeviewTemplate: PropTypes.func,
|
|
102
|
+
intl: intlShape,
|
|
109
103
|
};
|
|
110
104
|
|
|
111
105
|
TemplatesV2.defaultProps = {
|
package/index.js
CHANGED
|
@@ -63,7 +63,7 @@ export {default as TagListSaga} from './containers/TagList/sagas';
|
|
|
63
63
|
export {default as TagListReducer} from './containers/TagList/reducer';
|
|
64
64
|
export {default as TemplatePreview} from './components/TemplatePreview';
|
|
65
65
|
export {default as EmailPreview} from './components/EmailPreview';
|
|
66
|
-
|
|
66
|
+
export {default as CreativesContainer} from './containers/CreativesContainer';
|
|
67
67
|
|
|
68
68
|
export { CapContainer,
|
|
69
69
|
TemplatesContainer,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capillarytech/creatives-library",
|
|
3
3
|
"author": "meharaj",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.7",
|
|
5
5
|
"description": "Capillary creatives ui",
|
|
6
6
|
"main": "./index.js",
|
|
7
7
|
"module": "./index.es.js",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"license": "LicenseRef-LICENSE",
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@capillarytech/cap-react-ui-library": "latest",
|
|
16
|
-
"@capillarytech/cap-ui-library": "^1.0.
|
|
16
|
+
"@capillarytech/cap-ui-library": "^1.0.42",
|
|
17
17
|
"antd": "^3.13.1",
|
|
18
18
|
"axios": "^0.16.2",
|
|
19
19
|
"babel-polyfill": "6.20.0",
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
*
|
|
3
|
-
* TemplatesV2 reducer
|
|
4
|
-
*
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { fromJS } from 'immutable';
|
|
8
|
-
import * as types from './constants';
|
|
9
|
-
|
|
10
|
-
const initialState = fromJS({
|
|
11
|
-
loadingTemplates: true,
|
|
12
|
-
smsTemplates: [],
|
|
13
|
-
emailTemplates: [],
|
|
14
|
-
wechatTemplates: [],
|
|
15
|
-
mobilepushTemplates: [],
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
function templatesV2Reducer(state = initialState, action) {
|
|
19
|
-
const channelTemplates = `${action.channel}Templates`;
|
|
20
|
-
switch (action.type) {
|
|
21
|
-
case types.DEFAULT_ACTION:
|
|
22
|
-
return state;
|
|
23
|
-
case types.GET_TEMPLATES_REQUEST:
|
|
24
|
-
return state.set('loadingTemplates', true);
|
|
25
|
-
case types.GET_TEMPLATES_SUCESS:
|
|
26
|
-
return state.set('loadingTemplates', false).set(channelTemplates, action.templates);
|
|
27
|
-
case types.GET_TEMPLATES_FAILURE:
|
|
28
|
-
return state.set('loadingTemplates', false).set('error', action.error);
|
|
29
|
-
default:
|
|
30
|
-
return state;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export default templatesV2Reducer;
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { take, takeLatest, call, put, cancel } from 'redux-saga/effects';
|
|
2
|
-
import { LOCATION_CHANGE } from 'react-router-redux';
|
|
3
|
-
import * as Api from '../../services/api';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import * as types from './constants';
|
|
7
|
-
// Individual exports for testing
|
|
8
|
-
export function* defaultSaga() {
|
|
9
|
-
// See example in containers/HomePage/sagas.js
|
|
10
|
-
}
|
|
11
|
-
function* getTemplates(action) {
|
|
12
|
-
try {
|
|
13
|
-
const req = {
|
|
14
|
-
channel: action.channel,
|
|
15
|
-
queryParams: action.query,
|
|
16
|
-
};
|
|
17
|
-
const res = yield call(Api.getAllTemplates, req);
|
|
18
|
-
yield put({type: types.GET_TEMPLATES_SUCESS, templates: res.response.templates, channel: action.channel});
|
|
19
|
-
} catch (error) {
|
|
20
|
-
yield put({type: types.GET_TEMPLATES_FAILURE, error});
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
function* getTemplatesWatcher() {
|
|
24
|
-
const watcher = yield takeLatest(types.GET_TEMPLATES_REQUEST, getTemplates);
|
|
25
|
-
yield take(LOCATION_CHANGE);
|
|
26
|
-
yield cancel(watcher);
|
|
27
|
-
}
|
|
28
|
-
// All sagas to be loaded
|
|
29
|
-
export default [
|
|
30
|
-
defaultSaga,
|
|
31
|
-
getTemplatesWatcher,
|
|
32
|
-
];
|