@capillarytech/creatives-library 2.0.54 → 2.0.57

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.
Files changed (53) hide show
  1. package/components/CallTaskPreview/_callTaskPreview.scss +17 -0
  2. package/components/CallTaskPreview/images/Footer.png +0 -0
  3. package/components/CallTaskPreview/images/Header.png +0 -0
  4. package/components/CallTaskPreview/index.js +37 -0
  5. package/components/CallTaskPreview/messages.js +13 -0
  6. package/components/CallTaskPreview/tests/index.test.js +15 -0
  7. package/components/CapTagList/index.js +1 -1
  8. package/components/EmailPreviewV2/index.js +3 -1
  9. package/components/FormBuilder/index.js +10 -7
  10. package/components/NewCallTask/_newCallTask.scss +9 -0
  11. package/components/NewCallTask/index.js +152 -0
  12. package/components/NewCallTask/messages.js +29 -0
  13. package/components/NewCallTask/tests/index.test.js +10 -0
  14. package/containers/CallTask/_callTask.scss +5 -0
  15. package/containers/CallTask/actions.js +15 -0
  16. package/containers/CallTask/constants.js +7 -0
  17. package/containers/CallTask/index.js +141 -0
  18. package/containers/CallTask/messages.js +21 -0
  19. package/containers/CallTask/reducer.js +23 -0
  20. package/containers/CallTask/sagas.js +11 -0
  21. package/containers/CallTask/selectors.js +25 -0
  22. package/containers/CallTask/tests/actions.test.js +18 -0
  23. package/containers/CallTask/tests/index.test.js +10 -0
  24. package/containers/CallTask/tests/reducer.test.js +9 -0
  25. package/containers/CallTask/tests/sagas.test.js +15 -0
  26. package/containers/CallTask/tests/selectors.test.js +10 -0
  27. package/containers/CreativesContainer/SlideBoxContent.js +66 -3
  28. package/containers/CreativesContainer/SlideBoxFooter.js +3 -3
  29. package/containers/CreativesContainer/constants.js +2 -0
  30. package/containers/CreativesContainer/index.js +105 -21
  31. package/containers/Email/_email.scss +0 -1
  32. package/containers/Email/index.js +2 -0
  33. package/containers/Line/Edit/_lineEdit.scss +0 -4
  34. package/containers/MobilePush/Create/_mobilePushCreate.scss +0 -4
  35. package/containers/MobilePush/Create/index.js +4 -2
  36. package/containers/MobilePush/Edit/_mobilePushCreate.scss +0 -4
  37. package/containers/MobilePush/Edit/index.js +11 -8
  38. package/containers/MobilePush/Edit/selectors.js +2 -1
  39. package/containers/MobilepushWrapper/index.js +92 -0
  40. package/containers/MobilepushWrapper/messages.js +25 -0
  41. package/containers/MobilepushWrapper/tests/index.test.js +10 -0
  42. package/containers/Sms/Create/_smsCreate.scss +0 -1
  43. package/containers/Sms/Edit/actions.js +6 -0
  44. package/containers/Sms/Edit/constants.js +1 -0
  45. package/containers/Sms/Edit/index.js +1 -0
  46. package/containers/Sms/Edit/reducer.js +2 -0
  47. package/containers/TagList/index.js +3 -3
  48. package/containers/Templates/index.js +35 -17
  49. package/containers/TemplatesV2/index.js +22 -11
  50. package/index.js +7 -0
  51. package/package.json +2 -2
  52. package/routes.js +7 -2
  53. package/styles/containers/layout/_layoutPage.scss +1 -2
@@ -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
+ }
@@ -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
  }
@@ -556,7 +556,8 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
556
556
  _.forEach(this.state.formData, (tab, index) => {
557
557
  let isCurrentTabValid = true;
558
558
  let skipValidation = false;
559
- if (type.toLowerCase() === 'embedded' && ((isOnlyAndroid && parseInt(index) === 1) || (isOnlyIos && parseInt(index) === 0))) {
559
+ if (type.toLowerCase() === 'embedded' && ((isOnlyAndroid && parseInt(index) === 1) || (isOnlyIos && parseInt(index) === 0)) && isOnlyAndroid !== isOnlyIos) {
560
+ // skip validation of the tab which is not open in embedded mode
560
561
  skipValidation = true;
561
562
  }
562
563
  if (!isNaN(index) && tab && !skipValidation) {
@@ -2161,7 +2162,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2161
2162
  case "input":
2162
2163
  if (styling === 'semantic') {
2163
2164
  ifError = this.state.checkValidation && (isVersionEnable ? this.state.errorData[`${this.state.currentTab - 1}`][val.id] : this.state.errorData[val.id]);
2164
-
2165
+ const value = isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id];
2165
2166
  columns.push(
2166
2167
  <CapColumn key={val.id} span={val.width}>
2167
2168
  <CapInput
@@ -2173,7 +2174,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2173
2174
  placeholder={val.placeholder}
2174
2175
  onChange={(e) => this.updateFormData(e.target.value, val)}
2175
2176
  defaultValue={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2176
- value={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2177
+ value={value || ""}
2177
2178
  disabled={val.disabled}
2178
2179
  />
2179
2180
  </CapColumn>
@@ -2193,6 +2194,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2193
2194
  break;
2194
2195
  case "textarea":
2195
2196
  ifError = this.state.checkValidation && (isVersionEnable ? this.state.errorData[`${this.state.currentTab - 1}`][val.id] : this.state.errorData[val.id]);
2197
+ const value = isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id];
2196
2198
  if (styling === 'semantic') {
2197
2199
  columns.push(
2198
2200
  <CapColumn key="input" span={val.width}>
@@ -2204,7 +2206,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2204
2206
  onChange={(e) => this.updateFormData(e.target.value, val)}
2205
2207
  style={val.style ? val.style : {}}
2206
2208
  defaultValue={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2207
- value={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2209
+ value={value || ""}
2208
2210
  rows={20}
2209
2211
  disabled={val.disabled}
2210
2212
  cols={20}
@@ -2518,7 +2520,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2518
2520
  switch (type) {
2519
2521
  case "input":
2520
2522
  ifError = this.state.checkValidation && (isVersionEnable ? this.state.errorData[`${this.state.currentTab - 1}`][val.id] : this.state.errorData[val.id]);
2521
-
2523
+ const value = isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id];
2522
2524
  if (styling === 'semantic') {
2523
2525
  columns.push(
2524
2526
  <CapColumn key={val.id} span={val.width}>
@@ -2530,7 +2532,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2530
2532
  style={val.style ? val.style : {}}
2531
2533
  placeholder={val.placeholder}
2532
2534
  onChange={(e) => this.updateFormData(e.target.value, val)}
2533
- value={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2535
+ value={value || ""}
2534
2536
  defaultValue={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2535
2537
  disabled={val.disabled}
2536
2538
  />
@@ -2551,6 +2553,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2551
2553
  break;
2552
2554
  case "textarea":
2553
2555
  ifError = this.state.checkValidation && (isVersionEnable ? this.state.errorData[`${this.state.currentTab - 1}`][val.id] : this.state.errorData[val.id]);
2556
+ const textValue = isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id];
2554
2557
  if (styling === 'semantic') {
2555
2558
  columns.push(
2556
2559
  <CapColumn key="input" span={val.width} offset={val.offset}>
@@ -2564,7 +2567,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
2564
2567
  onChange={(e) => this.updateFormData(e.target.value, val)}
2565
2568
  style={val.style ? val.style : {}}
2566
2569
  defaultValue={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2567
- value={isVersionEnable ? this.state.formData[`${this.state.currentTab - 1}`][val.id] : this.state.formData[val.id]}
2570
+ value={textValue || ""}
2568
2571
  rows={10}
2569
2572
  cols={2}
2570
2573
  />
@@ -0,0 +1,9 @@
1
+ .new-call-task-done-button {
2
+ margin-top: 24px;
3
+ }
4
+
5
+ .new-call-task-tagList {
6
+ position: absolute;
7
+ right: 0;
8
+ top: -10px;
9
+ }
@@ -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,10 @@
1
+ // import React from 'react';
2
+ // import { shallow } from 'enzyme';
3
+
4
+ // import NewCallTask from '../index';
5
+
6
+ describe('<NewCallTask />', () => {
7
+ it('Expect to have unit tests specified', () => {
8
+ expect(false).toEqual(false);
9
+ });
10
+ });
@@ -0,0 +1,5 @@
1
+ .call-task-action-button {
2
+ display: flex;
3
+ justify-content: center;
4
+ margin-top: 40px;
5
+ }
@@ -0,0 +1,15 @@
1
+ /*
2
+ *
3
+ * CallTask actions
4
+ *
5
+ */
6
+
7
+ import {
8
+ DEFAULT_ACTION,
9
+ } from './constants';
10
+
11
+ export function defaultAction() {
12
+ return {
13
+ type: DEFAULT_ACTION,
14
+ };
15
+ }
@@ -0,0 +1,7 @@
1
+ /*
2
+ *
3
+ * CallTask constants
4
+ *
5
+ */
6
+
7
+ export const DEFAULT_ACTION = 'app/CallTask/DEFAULT_ACTION';
@@ -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
+ });