@capillarytech/creatives-library 2.0.53 → 2.0.56
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/CallTaskPreview/_callTaskPreview.scss +17 -0
- package/components/CallTaskPreview/images/Footer.png +0 -0
- package/components/CallTaskPreview/images/Header.png +0 -0
- package/components/CallTaskPreview/index.js +37 -0
- package/components/CallTaskPreview/messages.js +13 -0
- package/components/CallTaskPreview/tests/index.test.js +15 -0
- package/components/CapTagList/index.js +1 -1
- package/components/EmailPreviewV2/index.js +3 -1
- package/components/NewCallTask/_newCallTask.scss +9 -0
- package/components/NewCallTask/index.js +152 -0
- package/components/NewCallTask/messages.js +29 -0
- package/components/NewCallTask/tests/index.test.js +10 -0
- package/containers/CallTask/_callTask.scss +5 -0
- package/containers/CallTask/actions.js +15 -0
- package/containers/CallTask/constants.js +7 -0
- package/containers/CallTask/index.js +141 -0
- package/containers/CallTask/messages.js +21 -0
- package/containers/CallTask/reducer.js +23 -0
- package/containers/CallTask/sagas.js +11 -0
- package/containers/CallTask/selectors.js +25 -0
- package/containers/CallTask/tests/actions.test.js +18 -0
- package/containers/CallTask/tests/index.test.js +10 -0
- package/containers/CallTask/tests/reducer.test.js +9 -0
- package/containers/CallTask/tests/sagas.test.js +15 -0
- package/containers/CallTask/tests/selectors.test.js +10 -0
- package/containers/CreativesContainer/SlideBoxContent.js +22 -0
- package/containers/CreativesContainer/constants.js +1 -0
- package/containers/CreativesContainer/index.js +34 -6
- package/containers/Email/_email.scss +0 -1
- package/containers/Email/index.js +4 -3
- package/containers/Line/Edit/_lineEdit.scss +0 -4
- package/containers/MobilePush/Create/_mobilePushCreate.scss +0 -4
- package/containers/MobilePush/Edit/_mobilePushCreate.scss +0 -4
- package/containers/Sms/Create/_smsCreate.scss +0 -1
- package/containers/Sms/Edit/actions.js +6 -0
- package/containers/Sms/Edit/constants.js +1 -0
- package/containers/Sms/Edit/index.js +1 -0
- package/containers/Sms/Edit/reducer.js +2 -0
- package/containers/TagList/index.js +3 -3
- package/containers/TemplatesV2/index.js +21 -10
- package/index.js +7 -0
- package/package.json +2 -2
- package/routes.js +7 -2
- package/styles/containers/layout/_layoutPage.scss +1 -2
- package/containers/TemplatesV2/reducer.js +0 -34
- package/containers/TemplatesV2/sagas.js +0 -32
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
.call-task-preview {
|
|
2
|
+
.call-task-subject-container {
|
|
3
|
+
padding: 8px;
|
|
4
|
+
background: #444;
|
|
5
|
+
color: white;
|
|
6
|
+
font-size: 12px;
|
|
7
|
+
font-weight: 500;
|
|
8
|
+
}
|
|
9
|
+
.call-task-message-container {
|
|
10
|
+
overflow-y: auto;
|
|
11
|
+
height: 150px;
|
|
12
|
+
width: 100%;
|
|
13
|
+
font-size: 12px;
|
|
14
|
+
background: #eee;
|
|
15
|
+
padding: 8px;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* CallTaskPreview
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import PropTypes from 'prop-types';
|
|
9
|
+
import HeaderPng from './images/Header.png';
|
|
10
|
+
import FooterPng from './images/Footer.png';
|
|
11
|
+
|
|
12
|
+
import './_callTaskPreview.scss';
|
|
13
|
+
|
|
14
|
+
class CallTaskPreview extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
|
15
|
+
render() {
|
|
16
|
+
const { subject, messageBody } = this.props;
|
|
17
|
+
return (
|
|
18
|
+
<div className="call-task-preview">
|
|
19
|
+
<img style={{ width: '100%' }} src={HeaderPng} alt="header" />
|
|
20
|
+
<div className="call-task-subject-container">
|
|
21
|
+
{subject}
|
|
22
|
+
</div>
|
|
23
|
+
<div className="call-task-message-container">
|
|
24
|
+
{messageBody}
|
|
25
|
+
</div>
|
|
26
|
+
<img style={{ width: '100%' }} src={FooterPng} alt="footer" />
|
|
27
|
+
</div>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
CallTaskPreview.propTypes = {
|
|
33
|
+
subject: PropTypes.string,
|
|
34
|
+
messageBody: PropTypes.string,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default CallTaskPreview;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* CallTaskPreview Messages
|
|
3
|
+
*
|
|
4
|
+
* This contains all the text for the CallTaskPreview component.
|
|
5
|
+
*/
|
|
6
|
+
import { defineMessages } from 'react-intl';
|
|
7
|
+
|
|
8
|
+
export default defineMessages({
|
|
9
|
+
header: {
|
|
10
|
+
id: 'app.components.CallTaskPreview.header',
|
|
11
|
+
defaultMessage: 'This is the CallTaskPreview component !',
|
|
12
|
+
},
|
|
13
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { shallow } from "enzyme";
|
|
3
|
+
import CallTaskPreview from "../index";
|
|
4
|
+
|
|
5
|
+
describe("<CallTaskPreview />", () => {
|
|
6
|
+
it("Test if Call task component renders", () => {
|
|
7
|
+
const component = shallow(
|
|
8
|
+
<CallTaskPreview
|
|
9
|
+
subject="this is test"
|
|
10
|
+
body="this is test message body"
|
|
11
|
+
/>
|
|
12
|
+
);
|
|
13
|
+
expect(component).toMatchSnapshot();
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -81,8 +81,8 @@ class CapTagList extends React.Component { // eslint-disable-line react/prefer-s
|
|
|
81
81
|
tagValue = tagValue.replace("(N)", `${days}`);
|
|
82
82
|
const resultArray = [];
|
|
83
83
|
resultArray.push(tagValue);
|
|
84
|
-
this.props.onSelect(resultArray);
|
|
85
84
|
this.setState({showModal: false, dynamicDateValue: ''});
|
|
85
|
+
this.props.onSelect(resultArray);
|
|
86
86
|
};
|
|
87
87
|
|
|
88
88
|
handleCancel = () => {
|
|
@@ -54,7 +54,9 @@ class EmailPreviewV2 extends React.Component {
|
|
|
54
54
|
this.props.templateActions.getTemplateDetails(templateData._id); // templateContent: html data to be shown in iframe
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
|
|
57
|
+
componentWillUnmount() {
|
|
58
|
+
this.props.templateActions.resetTemplateData();
|
|
59
|
+
}
|
|
58
60
|
changePreviewDevice = (ev) => {
|
|
59
61
|
this.setState({currentDevice: ev.currentTarget.id});
|
|
60
62
|
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* NewCallTask
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import PropTypes from 'prop-types';
|
|
9
|
+
import { CapRow, CapColumn, CapInput, CapButton, CapSpin } from '@capillarytech/cap-ui-library';
|
|
10
|
+
import { injectIntl, intlShape } from 'react-intl';
|
|
11
|
+
import TagList from '../../containers/TagList';
|
|
12
|
+
import CallTaskPreview from '../CallTaskPreview';
|
|
13
|
+
import messages from './messages';
|
|
14
|
+
import './_newCallTask.scss';
|
|
15
|
+
|
|
16
|
+
class NewCallTask extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
|
17
|
+
constructor(props) {
|
|
18
|
+
super(props);
|
|
19
|
+
this.state = this.getInitialState();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
getInitialState = () => {
|
|
23
|
+
const { templateData } = this.props;
|
|
24
|
+
return {
|
|
25
|
+
subject: templateData && templateData.subject ? templateData.subject : '',
|
|
26
|
+
messageBody: templateData && templateData.messageBody ? templateData.messageBody : '',
|
|
27
|
+
description: templateData && templateData.description ? templateData.description : '',
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
onTagSelect = (data) => {
|
|
32
|
+
this.insertAtCursor(`{{${data}}}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
setInputRef = (textarea) => {
|
|
36
|
+
this.textArea = textarea;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
insertAtCursor = (myValue) => {
|
|
40
|
+
this.textArea.focus();
|
|
41
|
+
const textAreaRef = this.textArea.textAreaRef;
|
|
42
|
+
let pos = textAreaRef.selectionEnd + myValue.length;
|
|
43
|
+
//IE support
|
|
44
|
+
let newMessage = textAreaRef.value + myValue;
|
|
45
|
+
if (document.selection) {
|
|
46
|
+
this.textArea.focus();
|
|
47
|
+
const sel = document.selection.createRange();
|
|
48
|
+
sel.text = myValue;
|
|
49
|
+
} else if (textAreaRef.selectionStart || textAreaRef.selectionStart === '0') { //MOZILLA and others
|
|
50
|
+
const startPos = textAreaRef.selectionStart;
|
|
51
|
+
const endPos = textAreaRef.selectionEnd;
|
|
52
|
+
newMessage = textAreaRef.value.substring(0, startPos) + myValue + textAreaRef.value.substring(endPos, textAreaRef.value.length);
|
|
53
|
+
pos = startPos + myValue.length;
|
|
54
|
+
}
|
|
55
|
+
this.setState({
|
|
56
|
+
messageBody: newMessage,
|
|
57
|
+
}, () => {
|
|
58
|
+
textAreaRef.selectionStart = pos;
|
|
59
|
+
textAreaRef.selectionEnd = pos;
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
updateSubject = (e) => {
|
|
64
|
+
this.setState({
|
|
65
|
+
subject: e.target.value,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
updateMessageBody = (e) => {
|
|
70
|
+
this.setState({
|
|
71
|
+
messageBody: e.target.value,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
updateDescription = (e) => {
|
|
76
|
+
this.setState({
|
|
77
|
+
description: e.target.value,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
submitForm = () => {
|
|
82
|
+
this.props.onCallTaskSubmit(this.state);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
render() {
|
|
86
|
+
const { intl, isLoading, metaEntities } = this.props;
|
|
87
|
+
const { formatMessage } = intl;
|
|
88
|
+
const { subject, messageBody, description } = this.state;
|
|
89
|
+
const tags = metaEntities && metaEntities.tags ? metaEntities.tags.standard : [];
|
|
90
|
+
return (
|
|
91
|
+
<CapSpin spinning={isLoading}>
|
|
92
|
+
<CapRow gutter={16}>
|
|
93
|
+
<CapColumn span={12}>
|
|
94
|
+
<div style={{ height: 'calc(100vh - 187px)', overflowY: 'auto', paddingRight: "8px" }}>
|
|
95
|
+
<div style={{ marginBottom: '34px' }}>
|
|
96
|
+
<CapInput
|
|
97
|
+
label={formatMessage(messages.callTaskTitle)}
|
|
98
|
+
onChange={this.updateSubject}
|
|
99
|
+
value={subject}
|
|
100
|
+
isRequired
|
|
101
|
+
/>
|
|
102
|
+
</div>
|
|
103
|
+
<div style={{ position: 'relative', marginBottom: '34px' }}>
|
|
104
|
+
<TagList
|
|
105
|
+
className="new-call-task-tagList"
|
|
106
|
+
label={formatMessage(messages.personalisationTags)}
|
|
107
|
+
tags={tags}
|
|
108
|
+
onTagSelect={this.onTagSelect}
|
|
109
|
+
/>
|
|
110
|
+
<CapInput.TextArea
|
|
111
|
+
setInputRef={this.setInputRef}
|
|
112
|
+
label={formatMessage(messages.messageHeader)}
|
|
113
|
+
onChange={this.updateMessageBody}
|
|
114
|
+
value={messageBody}
|
|
115
|
+
isRequired
|
|
116
|
+
/>
|
|
117
|
+
</div>
|
|
118
|
+
<CapInput.TextArea
|
|
119
|
+
label={formatMessage(messages.description)}
|
|
120
|
+
onChange={this.updateDescription}
|
|
121
|
+
value={description}
|
|
122
|
+
isRequired
|
|
123
|
+
/>
|
|
124
|
+
</div>
|
|
125
|
+
<CapButton
|
|
126
|
+
disabled={!subject || !messageBody || !description}
|
|
127
|
+
className="new-call-task-done-button"
|
|
128
|
+
onClick={this.submitForm}>
|
|
129
|
+
{formatMessage(messages.done)}
|
|
130
|
+
</CapButton>
|
|
131
|
+
</CapColumn>
|
|
132
|
+
<CapColumn span={12}>
|
|
133
|
+
<CallTaskPreview
|
|
134
|
+
subject={subject}
|
|
135
|
+
messageBody={messageBody}
|
|
136
|
+
/>
|
|
137
|
+
</CapColumn>
|
|
138
|
+
</CapRow>
|
|
139
|
+
</CapSpin>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
NewCallTask.propTypes = {
|
|
145
|
+
intl: intlShape.isRequired,
|
|
146
|
+
onCallTaskSubmit: PropTypes.func,
|
|
147
|
+
templateData: PropTypes.object,
|
|
148
|
+
isLoading: PropTypes.bool,
|
|
149
|
+
metaEntities: PropTypes.object,
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
export default injectIntl(NewCallTask);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* NewCallTask Messages
|
|
3
|
+
*
|
|
4
|
+
* This contains all the text for the NewCallTask component.
|
|
5
|
+
*/
|
|
6
|
+
import { defineMessages } from 'react-intl';
|
|
7
|
+
|
|
8
|
+
export default defineMessages({
|
|
9
|
+
callTaskTitle: {
|
|
10
|
+
id: 'app.components.NewCallTask.callTaskTitle',
|
|
11
|
+
defaultMessage: 'Call Task title',
|
|
12
|
+
},
|
|
13
|
+
messageHeader: {
|
|
14
|
+
id: 'app.components.NewCallTask.messageHeader',
|
|
15
|
+
defaultMessage: 'Message',
|
|
16
|
+
},
|
|
17
|
+
description: {
|
|
18
|
+
id: 'app.components.NewCallTask.description',
|
|
19
|
+
defaultMessage: 'Description',
|
|
20
|
+
},
|
|
21
|
+
done: {
|
|
22
|
+
id: 'app.components.NewCallTask.done',
|
|
23
|
+
defaultMessage: 'Done',
|
|
24
|
+
},
|
|
25
|
+
personalisationTags: {
|
|
26
|
+
id: 'app.components.NewCallTask.personalisationTags',
|
|
27
|
+
defaultMessage: 'Personalisation tags',
|
|
28
|
+
},
|
|
29
|
+
});
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/*
|
|
2
|
+
*
|
|
3
|
+
* CallTask
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
import PropTypes from 'prop-types';
|
|
7
|
+
import React from 'react';
|
|
8
|
+
import { bindActionCreators } from "redux";
|
|
9
|
+
import { connect } from 'react-redux';
|
|
10
|
+
import {
|
|
11
|
+
//CapSlideBox,
|
|
12
|
+
CapButton,
|
|
13
|
+
//CapIcon,
|
|
14
|
+
//CapHeader,
|
|
15
|
+
CapLabel,
|
|
16
|
+
} from '@capillarytech/cap-ui-library';
|
|
17
|
+
import { injectIntl, intlShape } from 'react-intl';
|
|
18
|
+
import { createStructuredSelector } from 'reselect';
|
|
19
|
+
import { makeSelectMetaEntities, isLoadingMetaEntities } from '../Cap/selectors';
|
|
20
|
+
import * as globalActions from '../../containers/Cap/actions';
|
|
21
|
+
import * as actions from "./actions";
|
|
22
|
+
import makeSelectCallTask from './selectors';
|
|
23
|
+
import NewCallTask from '../../components/NewCallTask';
|
|
24
|
+
import messages from './messages';
|
|
25
|
+
import './_callTask.scss';
|
|
26
|
+
|
|
27
|
+
export class CallTask extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
|
28
|
+
constructor(props) {
|
|
29
|
+
super(props);
|
|
30
|
+
this.state = {
|
|
31
|
+
showCallTaskSlidebox: false,
|
|
32
|
+
mode: props.mode || '', // supported modes are create | edit
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
componentDidMount() {
|
|
37
|
+
const query = {
|
|
38
|
+
layout: 'SMS',
|
|
39
|
+
type: 'TAG',
|
|
40
|
+
context: 'outbound',
|
|
41
|
+
embedded: 'embedded',
|
|
42
|
+
};
|
|
43
|
+
this.props.globalActions.fetchSchemaForEntity(query);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
showNewCallTask = () => {
|
|
47
|
+
this.setState({
|
|
48
|
+
showCallTaskSlidebox: true,
|
|
49
|
+
mode: 'create',
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
closeSlideBox = () => {
|
|
54
|
+
this.setState({
|
|
55
|
+
showCallTaskSlidebox: false,
|
|
56
|
+
mode: '',
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
render() {
|
|
61
|
+
const { intl, onCallTaskSubmit, templateData, loadingMetaEntities, metaEntities, showContentInSlidebox, onCreateNew } = this.props;
|
|
62
|
+
const { formatMessage } = intl;
|
|
63
|
+
const { mode } = this.state;
|
|
64
|
+
return (
|
|
65
|
+
<div>
|
|
66
|
+
{mode ?
|
|
67
|
+
<NewCallTask
|
|
68
|
+
metaEntities={metaEntities}
|
|
69
|
+
isLoading={loadingMetaEntities}
|
|
70
|
+
mode={mode}
|
|
71
|
+
templateData={templateData}
|
|
72
|
+
onCallTaskSubmit={onCallTaskSubmit}
|
|
73
|
+
/>
|
|
74
|
+
:
|
|
75
|
+
<div>
|
|
76
|
+
<CapLabel type="label1">
|
|
77
|
+
{formatMessage(messages.callTaskInfo)}
|
|
78
|
+
</CapLabel>
|
|
79
|
+
<div className="call-task-action-button">
|
|
80
|
+
<CapButton onClick={showContentInSlidebox ? this.showNewCallTask : onCreateNew}>
|
|
81
|
+
{formatMessage(messages.addNewCallTask)}
|
|
82
|
+
</CapButton>
|
|
83
|
+
</div>
|
|
84
|
+
{/* {
|
|
85
|
+
showCallTaskSlidebox && showContentInSlidebox &&
|
|
86
|
+
<CapSlideBox
|
|
87
|
+
header={
|
|
88
|
+
<CapHeader
|
|
89
|
+
title={formatMessage(messages.newMessage)}
|
|
90
|
+
prefix={
|
|
91
|
+
<CapIcon style={{ marginRight: '16px' }} type={"back"} onClick={this.closeSlideBox} />
|
|
92
|
+
} />
|
|
93
|
+
}
|
|
94
|
+
show={showCallTaskSlidebox}
|
|
95
|
+
size="size-l"
|
|
96
|
+
handleClose={this.closeSlideBox}
|
|
97
|
+
content={
|
|
98
|
+
<NewCallTask
|
|
99
|
+
metaEntities={metaEntities}
|
|
100
|
+
isLoading={loadingMetaEntities}
|
|
101
|
+
mode={mode}
|
|
102
|
+
onCallTaskSubmit={onCallTaskSubmit}
|
|
103
|
+
/>
|
|
104
|
+
}
|
|
105
|
+
/>
|
|
106
|
+
} */}
|
|
107
|
+
</div>
|
|
108
|
+
}
|
|
109
|
+
</div>
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
CallTask.propTypes = {
|
|
115
|
+
intl: intlShape.isRequired,
|
|
116
|
+
onCallTaskSubmit: PropTypes.func,
|
|
117
|
+
mode: PropTypes.string,
|
|
118
|
+
templateData: PropTypes.object,
|
|
119
|
+
globalActions: PropTypes.object,
|
|
120
|
+
metaEntities: PropTypes.object,
|
|
121
|
+
loadingMetaEntities: PropTypes.bool,
|
|
122
|
+
showContentInSlidebox: PropTypes.bool,
|
|
123
|
+
onCreateNew: PropTypes.func,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
const mapStateToProps = createStructuredSelector({
|
|
128
|
+
CallTask: makeSelectCallTask(),
|
|
129
|
+
metaEntities: makeSelectMetaEntities(),
|
|
130
|
+
loadingMetaEntities: isLoadingMetaEntities(),
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
function mapDispatchToProps(dispatch) {
|
|
134
|
+
return {
|
|
135
|
+
globalActions: bindActionCreators(globalActions, dispatch),
|
|
136
|
+
actions: bindActionCreators(actions, dispatch),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(CallTask));
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* CallTask Messages
|
|
3
|
+
*
|
|
4
|
+
* This contains all the text for the CallTask component.
|
|
5
|
+
*/
|
|
6
|
+
import { defineMessages } from 'react-intl';
|
|
7
|
+
|
|
8
|
+
export default defineMessages({
|
|
9
|
+
addNewCallTask: {
|
|
10
|
+
id: 'app.containers.CallTask.addNewCallTask',
|
|
11
|
+
defaultMessage: 'Add New Call Task',
|
|
12
|
+
},
|
|
13
|
+
newMessage: {
|
|
14
|
+
id: 'app.containers.CallTask.newMessage',
|
|
15
|
+
defaultMessage: 'New Message',
|
|
16
|
+
},
|
|
17
|
+
callTaskInfo: {
|
|
18
|
+
id: 'app.containers.CallTask.callTaskInfo',
|
|
19
|
+
defaultMessage: 'Call Tasks are message sent to store staff. The messages are displayed on the Point of Sale (POS) machines for store staff to take action.',
|
|
20
|
+
},
|
|
21
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
*
|
|
3
|
+
* CallTask 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 callTaskReducer(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 callTaskReducer;
|
|
@@ -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 callTask state domain
|
|
5
|
+
*/
|
|
6
|
+
const selectCallTaskDomain = () => (state) => state.get('callTask');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Other specific selectors
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Default selector used by CallTask
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const makeSelectCallTask = () => createSelector(
|
|
18
|
+
selectCallTaskDomain(),
|
|
19
|
+
(substate) => substate.toJS()
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
export default makeSelectCallTask;
|
|
23
|
+
export {
|
|
24
|
+
selectCallTaskDomain,
|
|
25
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
import {
|
|
3
|
+
defaultAction,
|
|
4
|
+
} from '../actions';
|
|
5
|
+
import {
|
|
6
|
+
DEFAULT_ACTION,
|
|
7
|
+
} from '../constants';
|
|
8
|
+
|
|
9
|
+
describe('CallTask 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,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(false).toEqual(false);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// import { fromJS } from 'immutable';
|
|
2
|
+
// import { makeSelectCallTaskDomain } from '../selectors';
|
|
3
|
+
|
|
4
|
+
// const selector = makeSelectCallTaskDomain();
|
|
5
|
+
|
|
6
|
+
describe('makeSelectCallTaskDomain', () => {
|
|
7
|
+
it('Expect to have unit tests specified', () => {
|
|
8
|
+
expect(false).toEqual(false);
|
|
9
|
+
});
|
|
10
|
+
});
|
|
@@ -8,6 +8,7 @@ import SmsEdit from '../Sms/Edit';
|
|
|
8
8
|
import Email from '../Email';
|
|
9
9
|
import EmailWrapper from '../EmailWrapper';
|
|
10
10
|
import EmailPreviewV2 from '../../components/EmailPreviewV2';
|
|
11
|
+
import CallTask from '../CallTask';
|
|
11
12
|
import * as constants from './constants';
|
|
12
13
|
const CreativesWrapper = styled.div`
|
|
13
14
|
.ant-popover,
|
|
@@ -36,6 +37,7 @@ function SlideBoxContent(props) {
|
|
|
36
37
|
cap,
|
|
37
38
|
onResetStep,
|
|
38
39
|
isFullMode,
|
|
40
|
+
onCallTaskSubmit,
|
|
39
41
|
setIsLoadingContent,
|
|
40
42
|
} = props;
|
|
41
43
|
const type = messageDetails.type.toLowerCase(); // type is context in get tags values : outbound | dvs | referral | loyalty | coupons
|
|
@@ -47,15 +49,18 @@ function SlideBoxContent(props) {
|
|
|
47
49
|
};
|
|
48
50
|
let channel = currentChannel;//for create mode
|
|
49
51
|
const isCreateSms = slidBoxContent === 'createTemplate' && channel === constants.SMS;
|
|
52
|
+
const isCreateCallTask = slidBoxContent === 'createTemplate' && channel === 'CALLTASK';
|
|
50
53
|
let isEditSms = false;
|
|
51
54
|
let isEditEmailWithId = false;
|
|
52
55
|
let isEmailEditWithContent = false;
|
|
53
56
|
let isPreview = false;
|
|
54
57
|
let isEmailPreview = false;
|
|
58
|
+
let isEditCallTask = false;
|
|
55
59
|
const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL;
|
|
56
60
|
if (templateData && channel) {
|
|
57
61
|
channel = templateData.type;// for edit mode with template data
|
|
58
62
|
isEditSms = slidBoxContent === 'editTemplate' && channel === constants.SMS;
|
|
63
|
+
isEditCallTask = slidBoxContent === 'editTemplate' && channel === constants.CALL_TASK;
|
|
59
64
|
isEditEmailWithId = slidBoxContent === 'editTemplate' && channel === constants.EMAIL && templateData._id;
|
|
60
65
|
isEmailEditWithContent = slidBoxContent === 'editTemplate' && channel === constants.EMAIL && !templateData._id;
|
|
61
66
|
isPreview = slidBoxContent === 'preview' && channel !== constants.EMAIL;
|
|
@@ -73,6 +78,7 @@ function SlideBoxContent(props) {
|
|
|
73
78
|
createNew={onCreateNew}
|
|
74
79
|
channel={channel.toLowerCase()}
|
|
75
80
|
onChannelChange={onChannelChange}
|
|
81
|
+
onCallTaskSubmit={onCallTaskSubmit}
|
|
76
82
|
cap={cap}
|
|
77
83
|
/>
|
|
78
84
|
)}
|
|
@@ -103,6 +109,21 @@ function SlideBoxContent(props) {
|
|
|
103
109
|
subscriptionTemplateDetails={templateData} // used only in library mode
|
|
104
110
|
/>
|
|
105
111
|
)}
|
|
112
|
+
{
|
|
113
|
+
isEditCallTask &&
|
|
114
|
+
<CallTask
|
|
115
|
+
mode={'edit'}
|
|
116
|
+
templateData={templateData}
|
|
117
|
+
onCallTaskSubmit={onCallTaskSubmit}
|
|
118
|
+
/>
|
|
119
|
+
}
|
|
120
|
+
{
|
|
121
|
+
isCreateCallTask &&
|
|
122
|
+
<CallTask
|
|
123
|
+
mode={'create'}
|
|
124
|
+
onCallTaskSubmit={onCallTaskSubmit}
|
|
125
|
+
/>
|
|
126
|
+
}
|
|
106
127
|
{isCreateSms && (
|
|
107
128
|
<SmsCreate
|
|
108
129
|
setIsLoadingContent={setIsLoadingContent}
|
|
@@ -172,6 +193,7 @@ SlideBoxContent.propTypes = {
|
|
|
172
193
|
onEmailNextStep: PropTypes.func,
|
|
173
194
|
cap: PropTypes.object,
|
|
174
195
|
onResetStep: PropTypes.func,
|
|
196
|
+
onCallTaskSubmit: PropTypes.func,
|
|
175
197
|
isFullMode: PropTypes.bool,
|
|
176
198
|
setIsLoadingContent: PropTypes.func,
|
|
177
199
|
};
|
|
@@ -7,5 +7,6 @@
|
|
|
7
7
|
export const DEFAULT_ACTION = 'app/CreativesContainer/DEFAULT_ACTION';
|
|
8
8
|
export const EMAIL = "EMAIL";
|
|
9
9
|
export const SMS = "SMS";
|
|
10
|
+
export const CALL_TASK = "CALL_TASK";
|
|
10
11
|
export const SHOW_CONTANER_LOADER = "app/CreativesContainer/SHOW_CONTANER_LOADER";
|
|
11
12
|
export const HIDE_CONTAINER_LOADER = "app/CreativesContainer/HIDE_CONTAINER_LOADER";
|
|
@@ -66,20 +66,37 @@ class Creatives extends React.Component {
|
|
|
66
66
|
};
|
|
67
67
|
|
|
68
68
|
onShowTemplates = () => {
|
|
69
|
-
this.setState({ slidBoxContent: 'templates', showSlideBox: true });
|
|
69
|
+
this.setState({ slidBoxContent: 'templates', showSlideBox: true, isGetFormData: false });
|
|
70
70
|
};
|
|
71
71
|
onChannelChange = (channel) => {
|
|
72
72
|
this.setState({currentChannel: channel});
|
|
73
73
|
}
|
|
74
74
|
onEmailNextStep = () => {
|
|
75
|
-
this.setState((prevState) =>
|
|
76
|
-
templateStep
|
|
77
|
-
|
|
75
|
+
this.setState((prevState) => {
|
|
76
|
+
let templateStep = prevState.templateStep + 1;
|
|
77
|
+
const {emailCreateMode, currentChannel} = prevState;
|
|
78
|
+
if (currentChannel.toUpperCase() === constants.EMAIL && emailCreateMode === "upload") {
|
|
79
|
+
templateStep = prevState.templateStep + 2;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
templateStep,
|
|
84
|
+
};
|
|
85
|
+
});
|
|
78
86
|
}
|
|
79
87
|
|
|
80
88
|
onEmailModeChange = (mode) => {
|
|
81
89
|
this.setState({ emailCreateMode: mode});
|
|
82
90
|
}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
onCallTaskSubmit = (data) => {
|
|
94
|
+
this.props.getCreativesData({
|
|
95
|
+
channel: 'CALL_TASK',
|
|
96
|
+
...data,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
83
100
|
getTemplateData = (templateData) => { //from consumers to creatives
|
|
84
101
|
const {isFullMode} = this.props;
|
|
85
102
|
if (!isFullMode && templateData) { // for component mode
|
|
@@ -111,6 +128,14 @@ class Creatives extends React.Component {
|
|
|
111
128
|
edit: true,
|
|
112
129
|
type: channel,
|
|
113
130
|
};
|
|
131
|
+
} else if (channel === constants.CALL_TASK) {
|
|
132
|
+
creativesTeplateData = {
|
|
133
|
+
subject: templateData.subject,
|
|
134
|
+
messageBody: templateData.messageBody,
|
|
135
|
+
description: templateData.description,
|
|
136
|
+
edit: true,
|
|
137
|
+
type: channel,
|
|
138
|
+
};
|
|
114
139
|
}
|
|
115
140
|
return creativesTeplateData;
|
|
116
141
|
}
|
|
@@ -138,6 +163,7 @@ class Creatives extends React.Component {
|
|
|
138
163
|
}
|
|
139
164
|
return creativesMode;
|
|
140
165
|
}
|
|
166
|
+
|
|
141
167
|
getFormData = (template) => {
|
|
142
168
|
if (template.validity) {
|
|
143
169
|
this.setState(
|
|
@@ -180,7 +206,7 @@ class Creatives extends React.Component {
|
|
|
180
206
|
this.setState({ isGetFormData: true });
|
|
181
207
|
};
|
|
182
208
|
shouldShowFooter = () => {
|
|
183
|
-
const {isFullMode} = this.props;
|
|
209
|
+
const {isFullMode } = this.props;
|
|
184
210
|
const {slidBoxContent, currentChannel, emailCreateMode, templateStep} = this.state;
|
|
185
211
|
const channel = currentChannel.toUpperCase();
|
|
186
212
|
const currentStep = this.creativesTemplateSteps[templateStep];
|
|
@@ -188,7 +214,8 @@ class Creatives extends React.Component {
|
|
|
188
214
|
if (!isFullMode ) {
|
|
189
215
|
const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
|
|
190
216
|
const isCreate = (slidBoxContent === 'editTemplate' || slidBoxContent === 'createTemplate') && !isEmailCreate;
|
|
191
|
-
|
|
217
|
+
const isCallTask = channel === 'CALLTASK';
|
|
218
|
+
showFooter = (isCreate || (isEmailCreate && emailCreateMode) || slidBoxContent === 'preview') && !isCallTask;
|
|
192
219
|
} else if (channel === constants.EMAIL && isFullMode) {
|
|
193
220
|
const isEmailCreate = slidBoxContent === 'createTemplate' && channel === constants.EMAIL && currentStep !== 'createTemplateContent';
|
|
194
221
|
showFooter = isEmailCreate && emailCreateMode;
|
|
@@ -250,6 +277,7 @@ class Creatives extends React.Component {
|
|
|
250
277
|
location={this.props.location}
|
|
251
278
|
messageDetails={this.props.messageDetails}
|
|
252
279
|
getFormData={this.getFormData}
|
|
280
|
+
onCallTaskSubmit={this.onCallTaskSubmit}
|
|
253
281
|
onCreateNew={this.onCreateNew}
|
|
254
282
|
isGetFormData={isGetFormData}
|
|
255
283
|
isFullMode={isFullMode}
|
|
@@ -390,7 +390,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
390
390
|
const message = getMessageObject('error', (nextProps.Email.createTemplateErrorMessage && nextProps.Email.createTemplateErrorMessage !== '') ? nextProps.Email.createTemplateErrorMessage : this.props.intl.formatMessage(messages.somethingWentWrong), true);
|
|
391
391
|
this.props.globalActions.addMessageToQueue(message);
|
|
392
392
|
}
|
|
393
|
-
if (!nextProps.Email.fetchingCmsData && !_.isEqual(nextProps.Email.cmsData, this.props.Email.cmsData)) {
|
|
393
|
+
if (!nextProps.Email.fetchingCmsData && !_.isEqual(nextProps.Email.cmsData, this.props.Email.cmsData) && !_.isEmpty(nextProps.Email.cmsData)) {
|
|
394
394
|
const formData = _.cloneDeep(this.state.formData);
|
|
395
395
|
if (nextProps.Email.langId && nextProps.Email.langId !== 'undefined') {
|
|
396
396
|
const langId = nextProps.Email.langId;
|
|
@@ -2540,6 +2540,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
2540
2540
|
onItemClick={this.handleOnItemClick}
|
|
2541
2541
|
colNumber={2}
|
|
2542
2542
|
enablePagination
|
|
2543
|
+
isLoading={this.props.Email.fetchingAllAssets}
|
|
2543
2544
|
/>
|
|
2544
2545
|
</Pagination>
|
|
2545
2546
|
</div>
|
|
@@ -2619,7 +2620,7 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
|
|
|
2619
2620
|
/>}
|
|
2620
2621
|
<ImagePreview
|
|
2621
2622
|
header={imagePreviewHeader}
|
|
2622
|
-
content={imagePreviewContent}
|
|
2623
|
+
content={imagePreviewContent}
|
|
2623
2624
|
show={this.state.showImageSelectionBox}
|
|
2624
2625
|
handleClose={this.handleImagePreviewClose}
|
|
2625
2626
|
isLoading={this.props.Email.fetchingAllAssets}
|
|
@@ -2671,4 +2672,4 @@ function mapDispatchToProps(dispatch) {
|
|
|
2671
2672
|
};
|
|
2672
2673
|
}
|
|
2673
2674
|
|
|
2674
|
-
export default UserIsAuthenticated(connect(mapStateToProps, mapDispatchToProps)(injectIntl(Email)));
|
|
2675
|
+
export default UserIsAuthenticated(connect(mapStateToProps, mapDispatchToProps)(injectIntl(Email)));
|
|
@@ -15,3 +15,4 @@ export const EDIT_TEMPLATE_SUCCESS = 'app/containers/Sms/Edit/EDIT_TEMPLATE_SUCC
|
|
|
15
15
|
export const EDIT_TEMPLATE_FAILURE = 'app/containers/Sms/Edit/EDIT_TEMPLATE_FAILURE';
|
|
16
16
|
|
|
17
17
|
export const CLEAR_EDIT_RESPONSE_REQUEST = 'app/containers/Sms/Create/CLEAR_EDIT_RESPONSE_REQUEST';
|
|
18
|
+
export const RESET_EDIT_TEMPLATE = 'app/containers/Sms/Create/RESET_EDIT_TEMPLATE';
|
|
@@ -194,6 +194,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
|
|
|
194
194
|
if (this.props.setIsLoadingContent) {
|
|
195
195
|
this.props.setIsLoadingContent(true); // setting isLoading of CreativesContainer so that slidebox foot can be hidden till content is loaded
|
|
196
196
|
}
|
|
197
|
+
this.props.actions.resetEditTemplate();
|
|
197
198
|
window.removeEventListener("message", this.handleFrameTasks);
|
|
198
199
|
}
|
|
199
200
|
|
|
@@ -42,6 +42,8 @@ function editReducer(state = initialState, action) {
|
|
|
42
42
|
return state.set('getTemplateDetailsInProgress', false);
|
|
43
43
|
case types.CLEAR_EDIT_RESPONSE_REQUEST:
|
|
44
44
|
return state.set('editResponse', {});
|
|
45
|
+
case types.RESET_EDIT_TEMPLATE:
|
|
46
|
+
return state.set('templateDetails', {});
|
|
45
47
|
default:
|
|
46
48
|
return state;
|
|
47
49
|
}
|
|
@@ -82,9 +82,9 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
|
|
|
82
82
|
console.log('Inside ', tag.label);
|
|
83
83
|
mainTags[tag.value] = {
|
|
84
84
|
'tag-header': true,
|
|
85
|
-
name: tag.label[this.props.userLocale] ? tag.label[this.props.userLocale] : tag.label.en,
|
|
86
|
-
desc: tag.desc ? tag.desc : tag.label.en,
|
|
87
|
-
subtags: tag.subtags,
|
|
85
|
+
"name": tag.label[this.props.userLocale] ? tag.label[this.props.userLocale] : tag.label.en,
|
|
86
|
+
"desc": tag.desc ? tag.desc : tag.label.en,
|
|
87
|
+
"subtags": tag.subtags,
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
90
|
});
|
|
@@ -22,6 +22,7 @@ import { makeSelectTemplates, makeSelectTemplatesResponse } from '../Templates/s
|
|
|
22
22
|
import messages from './messages';
|
|
23
23
|
import * as actions from './actions';
|
|
24
24
|
import Templates from '../Templates';
|
|
25
|
+
import CallTask from '../CallTask';
|
|
25
26
|
import './_templatesV2.scss';
|
|
26
27
|
|
|
27
28
|
const {CapCustomCardList} = CapCustomCard;
|
|
@@ -52,6 +53,7 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
52
53
|
const deafaultPanes = [
|
|
53
54
|
{content: <div></div>, tab: 'Sms', key: 'sms'},
|
|
54
55
|
{content: <div></div>, tab: 'Email', key: 'email'},
|
|
56
|
+
// {content: <div></div>, tab: 'Call Task', key: 'calltask'},
|
|
55
57
|
// {content: this.getTemplatesComponent('wechat'), tab: 'Wechat', key: 'wechat'},
|
|
56
58
|
// {content: <div></div>, tab: 'Mpush', key: 'mobilepush'},
|
|
57
59
|
];
|
|
@@ -94,22 +96,27 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
94
96
|
|
|
95
97
|
</div>);
|
|
96
98
|
}
|
|
99
|
+
|
|
100
|
+
getCallTaskComponent = () => <CallTask onCreateNew={this.props.createNew} onCallTaskSubmit={this.props.onCallTaskSubmit}/>
|
|
101
|
+
|
|
97
102
|
getTemplatesComponent(channel) {
|
|
98
103
|
// const templates = this.props.Templates[`${channel}Templates`];
|
|
99
104
|
let query = {};
|
|
100
105
|
if (!this.props.isFullMode) {
|
|
101
106
|
query = {type: 'embedded', module: 'library'};
|
|
102
107
|
}
|
|
103
|
-
return (
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
108
|
+
return (channel === 'calltask' ?
|
|
109
|
+
this.getCallTaskComponent() :
|
|
110
|
+
<Templates
|
|
111
|
+
key={channel}
|
|
112
|
+
location={{pathname: `/${channel}`, search: '', query}}
|
|
113
|
+
route={{name: channel}}
|
|
114
|
+
router={this.props.router}
|
|
115
|
+
isFullMode={this.props.isFullMode}
|
|
116
|
+
createNew={this.props.createNew}
|
|
117
|
+
onSelectTemplate={(id) => this.props.onSelectTemplate(this.selectTemplate(id))}
|
|
118
|
+
renderNewCardGrid={this.getTemplateDataForGrid}
|
|
119
|
+
handlePeviewTemplate={this.props.handlePeviewTemplate}
|
|
113
120
|
/>);
|
|
114
121
|
}
|
|
115
122
|
|
|
@@ -121,6 +128,9 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
|
|
|
121
128
|
if (channel === "mpush") {
|
|
122
129
|
channel = "mobilepush";
|
|
123
130
|
}
|
|
131
|
+
if (channel === 'call task') {
|
|
132
|
+
channel = "calltask";
|
|
133
|
+
}
|
|
124
134
|
pane.content = this.getTemplatesComponent(channel);
|
|
125
135
|
return pane;
|
|
126
136
|
}
|
|
@@ -175,6 +185,7 @@ TemplatesV2.propTypes = {
|
|
|
175
185
|
Templates: PropTypes.object,
|
|
176
186
|
TemplatesList: PropTypes.arrayOf(PropTypes.object),
|
|
177
187
|
handlePeviewTemplate: PropTypes.func,
|
|
188
|
+
onCallTaskSubmit: PropTypes.func,
|
|
178
189
|
intl: intlShape,
|
|
179
190
|
onChannelChange: PropTypes.func,
|
|
180
191
|
};
|
package/index.js
CHANGED
|
@@ -19,6 +19,10 @@ import Email from './containers/Email/index';
|
|
|
19
19
|
import emailReducer from './containers/Email/reducer';
|
|
20
20
|
import emailSaga from './containers/Email/sagas';
|
|
21
21
|
|
|
22
|
+
import CallTask from './containers/CallTask/index';
|
|
23
|
+
import callTaskReducer from './containers/CallTask/reducer';
|
|
24
|
+
import callTaskSaga from './containers/CallTask/sagas';
|
|
25
|
+
|
|
22
26
|
import WeChat from './containers/WeChat/MapTemplates';
|
|
23
27
|
import wechatReduce from './containers/WeChat/MapTemplates/reducer';
|
|
24
28
|
import wechatSaga from './containers/WeChat/MapTemplates/sagas';
|
|
@@ -55,6 +59,7 @@ const TemplatesContainer = {Templates, templateReducer, templateSaga};
|
|
|
55
59
|
const SmsCreateContainer = {SmsCreate, smsCreateReducer, smsCreateSaga};
|
|
56
60
|
const SmsEditContainer = {SmsEdit, smsEditReducer, smsEditSaga};
|
|
57
61
|
const EmailContainer = {Email, emailReducer, emailSaga};
|
|
62
|
+
const CallTaskContainer = {CallTask, callTaskReducer, callTaskSaga};
|
|
58
63
|
const WechatContainer = {WeChat, wechatReduce, wechatSaga};
|
|
59
64
|
const MobilePushCreateContainer = {MobilepushCreate, mobilepushCreateReducer, mobilepushCreateSaga};
|
|
60
65
|
const MobilePushEditContainer = {MobilepushEdit, mobilepushEditReducer, mobilepushEditSaga};
|
|
@@ -68,6 +73,7 @@ export {default as TagListReducer} from './containers/TagList/reducer';
|
|
|
68
73
|
export {default as TemplatePreview} from './components/TemplatePreview';
|
|
69
74
|
export {default as EmailPreview} from './components/EmailPreview';
|
|
70
75
|
export {default as EmailPreviewV2} from './components/EmailPreviewV2';
|
|
76
|
+
export {default as CallTaskPreview} from './components/CallTaskPreview';
|
|
71
77
|
export {default as EmailMobilePreview} from './components/EmailMobilePreview';
|
|
72
78
|
|
|
73
79
|
CreativesContainer.CreativesContainerReducer = CreativesContainerReducer;
|
|
@@ -77,6 +83,7 @@ export { CapContainer,
|
|
|
77
83
|
SmsCreateContainer,
|
|
78
84
|
SmsEditContainer,
|
|
79
85
|
EmailContainer,
|
|
86
|
+
CallTaskContainer,
|
|
80
87
|
WechatContainer,
|
|
81
88
|
Cap,
|
|
82
89
|
Templates,
|
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.56",
|
|
5
5
|
"description": "Capillary creatives ui",
|
|
6
6
|
"main": "./index.js",
|
|
7
7
|
"module": "./index.es.js",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
},
|
|
13
13
|
"license": "LicenseRef-LICENSE",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@capillarytech/cap-ui-library": "^1.0.
|
|
15
|
+
"@capillarytech/cap-ui-library": "^1.0.96",
|
|
16
16
|
"antd": "^3.15.0",
|
|
17
17
|
"axios": "^0.16.2",
|
|
18
18
|
"babel-polyfill": "6.20.0",
|
package/routes.js
CHANGED
|
@@ -607,21 +607,26 @@ export default function createRoutes(store) {
|
|
|
607
607
|
import('containers/Sms/Edit/reducer'),
|
|
608
608
|
import('containers/Sms/Edit/sagas'),
|
|
609
609
|
import('containers/Email/reducer'),
|
|
610
|
-
import('containers/Email/sagas')
|
|
610
|
+
import('containers/Email/sagas'),
|
|
611
|
+
import('containers/CallTask/reducer'),
|
|
612
|
+
import('containers/CallTask/sagas'),
|
|
613
|
+
]);
|
|
611
614
|
|
|
612
615
|
const renderRoute = loadModule(cb);
|
|
613
616
|
|
|
614
|
-
importModules.then(([reducer, sagas, component, emailContainerSagas, creativesContainerReducer, smsCreateReducer, smsCreateSaga, smsEditReducer, smsEditSaga, emailReducer, emailSaga]) => {
|
|
617
|
+
importModules.then(([reducer, sagas, component, emailContainerSagas, creativesContainerReducer, smsCreateReducer, smsCreateSaga, smsEditReducer, smsEditSaga, emailReducer, emailSaga, callTaskReducer, callTaskSagas]) => {
|
|
615
618
|
injectReducer('templates', reducer.default);
|
|
616
619
|
injectReducer('create', smsCreateReducer.default);
|
|
617
620
|
injectReducer('creativesContainer', creativesContainerReducer.default);
|
|
618
621
|
injectReducer('edit', smsEditReducer.default);
|
|
619
622
|
injectReducer('email', emailReducer.default);
|
|
623
|
+
injectReducer('callTask', callTaskReducer.default);
|
|
620
624
|
injectSagas(sagas.default);
|
|
621
625
|
injectSagas(emailContainerSagas.default);
|
|
622
626
|
injectSagas(smsCreateSaga.default);
|
|
623
627
|
injectSagas(smsEditSaga.default);
|
|
624
628
|
injectSagas(emailSaga.default);
|
|
629
|
+
injectSagas(callTaskSagas.default);
|
|
625
630
|
renderRoute(component);
|
|
626
631
|
});
|
|
627
632
|
importModules.catch(errorLoading);
|
|
@@ -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
|
-
];
|