@capillarytech/creatives-library 6.10.5 → 6.10.6

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 (59) hide show
  1. package/package.json +1 -1
  2. package/reducers.js +2 -0
  3. package/routes.js +4 -0
  4. package/services/api.js +6 -0
  5. package/translations/en.json +17 -0
  6. package/translations/zh.json +17 -0
  7. package/v2Components/FormBuilder/index.js +2 -3
  8. package/v2Components/TemplatePreview/WechatRichmediaTemplatePreview/_wechatRichmediaTemplatePrev.scss +151 -151
  9. package/v2Components/TemplatePreview/WechatRichmediaTemplatePreview/messages.js +33 -33
  10. package/v2Components/TemplatePreview/WechatRichmediaTemplatePreview/tests/index.test.js +10 -10
  11. package/v2Components/TemplatePreview/assets/images/androidPushMessage.svg +44 -44
  12. package/v2Components/TemplatePreview/assets/images/home-screen-android.svg +21 -21
  13. package/v2Components/TemplatePreview/assets/images/home-screen-ios.svg +16 -16
  14. package/v2Components/TemplatePreview/assets/images/iPhonePushMessage.svg +134 -134
  15. package/v2Components/TemplatePreview/assets/images/mobile.svg +23 -23
  16. package/v2Components/TemplatePreview/assets/images/sms_mobile_android.svg +22 -22
  17. package/v2Components/TemplatePreview/assets/images/user-icon.svg +18 -18
  18. package/v2Components/TemplatePreview/assets/images/wechat-home-screen-android.svg +21 -21
  19. package/v2Components/TemplatePreview/assets/images/wechat-mobile.svg +77 -77
  20. package/v2Components/TemplatePreview/assets/images/wechat_mobile_android.svg +20 -20
  21. package/v2Components/TemplatePreview/tests/index.test.js +10 -10
  22. package/v2Containers/BeeEditor/actions.js +12 -0
  23. package/v2Containers/BeeEditor/constants.js +5 -0
  24. package/v2Containers/BeeEditor/index.js +329 -0
  25. package/v2Containers/BeeEditor/index.scss +6 -0
  26. package/v2Containers/BeeEditor/messages.js +67 -0
  27. package/v2Containers/BeeEditor/reducer.js +25 -0
  28. package/v2Containers/BeeEditor/sagas.js +33 -0
  29. package/v2Containers/BeeEditor/selectors.js +17 -0
  30. package/v2Containers/BeeEditor/tests/index.test.js +10 -0
  31. package/v2Containers/CreativesContainer/actions.js +27 -27
  32. package/v2Containers/CreativesContainer/constants.js +17 -17
  33. package/v2Containers/CreativesContainer/index.js +3 -3
  34. package/v2Containers/CreativesContainer/index.scss +44 -44
  35. package/v2Containers/CreativesContainer/messages.js +305 -305
  36. package/v2Containers/CreativesContainer/reducer.js +29 -29
  37. package/v2Containers/CreativesContainer/sagas.js +11 -11
  38. package/v2Containers/CreativesContainer/selectors.js +30 -30
  39. package/v2Containers/CreativesContainer/tests/actions.test.js +18 -18
  40. package/v2Containers/CreativesContainer/tests/index.test.js +10 -10
  41. package/v2Containers/CreativesContainer/tests/reducer.test.js +9 -9
  42. package/v2Containers/CreativesContainer/tests/sagas.test.js +15 -15
  43. package/v2Containers/CreativesContainer/tests/selectors.test.js +10 -10
  44. package/v2Containers/Email/index.js +1 -1
  45. package/v2Containers/Templates/tests/actions.test.js +18 -18
  46. package/v2Containers/Templates/tests/index.test.js +10 -10
  47. package/v2Containers/Templates/tests/reducer.test.js +9 -9
  48. package/v2Containers/Templates/tests/sagas.test.js +15 -15
  49. package/v2Containers/Templates/tests/selectors.test.js +10 -10
  50. package/v2Containers/TemplatesV2/TemplatesV2.style.js +29 -29
  51. package/v2Containers/TemplatesV2/actions.js +16 -16
  52. package/v2Containers/TemplatesV2/constants.js +10 -10
  53. package/v2Containers/TemplatesV2/messages.js +61 -61
  54. package/v2Containers/TemplatesV2/selectors.js +25 -25
  55. package/v2Containers/TemplatesV2/tests/actions.test.js +18 -18
  56. package/v2Containers/TemplatesV2/tests/index.test.js +10 -10
  57. package/v2Containers/TemplatesV2/tests/reducer.test.js +9 -9
  58. package/v2Containers/TemplatesV2/tests/sagas.test.js +15 -15
  59. package/v2Containers/TemplatesV2/tests/selectors.test.js +10 -10
@@ -1,20 +1,20 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="220" height="472" viewBox="0 0 220 472">
2
- <g fill="none" fill-rule="evenodd">
3
- <rect width="220" height="472" fill="#101211" rx="26"/>
4
- <rect width="202" height="404" x="9" y="36" fill="#F4F5F7" rx="9"/>
5
- <rect width="182" height="136" x="19" y="112" fill="#F4F5F7" rx="17.5"/>
6
- <path fill="#F4F5F7" d="M18 36h184c4.97 0 9 4.03 9 9v6H9v-6c0-4.97 4.03-9 9-9z"/>
7
- <path fill="#F4F5F7" d="M9 51H211V82H9z" transform="matrix(1 0 0 -1 0 133)"/>
8
- <rect width="52" height="5" x="84" y="14" fill="#2E2E2E" rx="2.5"/>
9
- <rect width="52" height="5" x="84" y="455" fill="#2E2E2E" rx="2.5"/>
10
- <circle cx="45.5" cy="19.5" r="5.5" fill="#2E2E2E"/>
11
- <circle cx="65.5" cy="19.5" r="3.5" fill="#2E2E2E"/>
12
- <text fill="#000" font-family="Roboto-Regular, Roboto" font-size="12" letter-spacing=".175">
13
- <tspan x="49.5" y="71">Muji India</tspan>
14
- </text>
15
- <circle cx="199" cy="63" r="1" fill="#000"/>
16
- <circle cx="199" cy="70" r="1" fill="#000"/>
17
- <circle cx="199" cy="66.5" r="1" fill="#000"/>
18
- <path fill="#000" d="M28 66c0 .279-.226.505-.505.505h-5.556l2.42 2.42c.198.197.198.518 0 .716-.198.198-.52.198-.718 0l-2.934-2.934c-.39-.39-.39-1.024 0-1.414l2.934-2.934c.198-.198.52-.198.718 0 .198.198.198.519 0 .717l-2.42 2.419h5.556c.279 0 .505.226.505.505z"/>
19
- </g>
20
- </svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="220" height="472" viewBox="0 0 220 472">
2
+ <g fill="none" fill-rule="evenodd">
3
+ <rect width="220" height="472" fill="#101211" rx="26"/>
4
+ <rect width="202" height="404" x="9" y="36" fill="#F4F5F7" rx="9"/>
5
+ <rect width="182" height="136" x="19" y="112" fill="#F4F5F7" rx="17.5"/>
6
+ <path fill="#F4F5F7" d="M18 36h184c4.97 0 9 4.03 9 9v6H9v-6c0-4.97 4.03-9 9-9z"/>
7
+ <path fill="#F4F5F7" d="M9 51H211V82H9z" transform="matrix(1 0 0 -1 0 133)"/>
8
+ <rect width="52" height="5" x="84" y="14" fill="#2E2E2E" rx="2.5"/>
9
+ <rect width="52" height="5" x="84" y="455" fill="#2E2E2E" rx="2.5"/>
10
+ <circle cx="45.5" cy="19.5" r="5.5" fill="#2E2E2E"/>
11
+ <circle cx="65.5" cy="19.5" r="3.5" fill="#2E2E2E"/>
12
+ <text fill="#000" font-family="Roboto-Regular, Roboto" font-size="12" letter-spacing=".175">
13
+ <tspan x="49.5" y="71">Muji India</tspan>
14
+ </text>
15
+ <circle cx="199" cy="63" r="1" fill="#000"/>
16
+ <circle cx="199" cy="70" r="1" fill="#000"/>
17
+ <circle cx="199" cy="66.5" r="1" fill="#000"/>
18
+ <path fill="#000" d="M28 66c0 .279-.226.505-.505.505h-5.556l2.42 2.42c.198.197.198.518 0 .716-.198.198-.52.198-.718 0l-2.934-2.934c-.39-.39-.39-1.024 0-1.414l2.934-2.934c.198-.198.52-.198.718 0 .198.198.198.519 0 .717l-2.42 2.419h5.556c.279 0 .505.226.505.505z"/>
19
+ </g>
20
+ </svg>
@@ -1,10 +1,10 @@
1
- // import React from 'react';
2
- // import { shallow } from 'enzyme';
3
-
4
- // import TemplatePreview from '../index';
5
-
6
- describe('<TemplatePreview />', () => {
7
- it('Expect to have unit tests specified', () => {
8
- expect(true).toEqual(false);
9
- });
10
- });
1
+ // import React from 'react';
2
+ // import { shallow } from 'enzyme';
3
+
4
+ // import TemplatePreview from '../index';
5
+
6
+ describe('<TemplatePreview />', () => {
7
+ it('Expect to have unit tests specified', () => {
8
+ expect(true).toEqual(false);
9
+ });
10
+ });
@@ -0,0 +1,12 @@
1
+ import {
2
+ CREATE_CUSTOM_ROW_REQUEST,
3
+ } from './constants';
4
+
5
+ export function createCustomRow(data, callback) {
6
+ return {
7
+ type: CREATE_CUSTOM_ROW_REQUEST,
8
+ data,
9
+ callback,
10
+ };
11
+ }
12
+
@@ -0,0 +1,5 @@
1
+ const prefix = 'APP/V2CONTAINER/BEEEDITOR';
2
+ export const CREATE_CUSTOM_ROW_REQUEST = `${prefix}/CREATE_CUSTOM_ROW_REQUEST`;
3
+ export const CREATE_CUSTOM_ROW_SUCCESS = `${prefix}/CREATE_CUSTOM_ROW_SUCCESS`;
4
+ export const CREATE_CUSTOM_ROW_FAILURE = `${prefix}/CREATE_CUSTOM_ROW_FAILURE`;
5
+
@@ -0,0 +1,329 @@
1
+ /**
2
+ *
3
+ * Beeeditor
4
+ *
5
+ */
6
+ import React, { useEffect, useState, useRef, useCallback } from 'react';
7
+ import PropTypes from 'prop-types';
8
+ import { injectIntl, intlShape, FormattedMessage } from 'react-intl';
9
+ import { connect } from 'react-redux';
10
+ import TagList from '../TagList';
11
+ import { bindActionCreators } from 'redux';
12
+ import { createStructuredSelector } from 'reselect';
13
+ import makeSelectBEE from './selectors';
14
+ import { UserIsAuthenticated } from '../../utils/authWrapper';
15
+ import config from '../../config/app';
16
+ import { loadItem } from 'services/localStorageApi';
17
+ import './index.scss';
18
+ import {
19
+ CapModal,
20
+ CapButton,
21
+ CapInput,
22
+ CapSelect,
23
+ CapSpin,
24
+ CapNotification,
25
+ }
26
+ from '@capillarytech/cap-ui-library';
27
+ import messages from './messages';
28
+ import * as beeActions from './actions';
29
+ function BeeEditor(props) {
30
+ const {
31
+ uid,
32
+ beeJson,
33
+ tokenData,
34
+ id,
35
+ location = {},
36
+ moduleFilterEnabled,
37
+ label,
38
+ className,
39
+ userLocale,
40
+ selectedOfferDetails,
41
+ tags,
42
+ injectedTags,
43
+ saveBeeInstance,
44
+ saveBeeData,
45
+ intl,
46
+ onContextChange,
47
+ actions,
48
+ BEESelect,
49
+ } = props;
50
+ const { saveRowRequest } = BEESelect;
51
+ const {formatMessage} = intl;
52
+ const UNSUBSCRIBE = 'unsubscribe';
53
+ let beePluginInstance = null;
54
+ const categoryOptions = [{key: 'cta', value: 'cta', label: formatMessage(messages.cta)},
55
+ {key: 'footer', value: 'footer', label: formatMessage(messages.footer)},
56
+ {key: 'header', value: 'header', label: formatMessage(messages.header)},
57
+ {key: 'sp', value: 'sp', label: formatMessage(messages.socialPlatform)},
58
+ {key: 'others', value: 'others', label: formatMessage(messages.others)},
59
+ ];
60
+ const [visibleTaglist, setVisibleTaglist] = useState(false);
61
+ const [showRowMetaModal, setRowMetaModal] = useState(false);
62
+ const [selectedTag, setSelectedTag] = useState({});
63
+ const [rowMetaInfo, setRowMetaInfo] = useState({});
64
+ const [rowName, setRowName] = useState('');
65
+ const [rowCategory, setRowCategory] = useState('');
66
+ let API_ENDPOINT = config.development.api_endpoint;
67
+ if (process.env.NODE_ENV === 'production') {
68
+ API_ENDPOINT = `${window.location.origin}${config.production.api_endpoint}`;
69
+ }
70
+ const savedCallback = useRef();
71
+ const filteredTags = (tags || []).filter((obj) => obj.definition.value !== UNSUBSCRIBE);
72
+ let intervalTimer;
73
+
74
+ const DEFAULT_LOCALE = 'en';
75
+ const MAPPED_LOCALE = {
76
+ 'en': 'en',
77
+ 'zh-cn': 'zh',
78
+ 'zh': 'zh',
79
+ };
80
+ const user = localStorage.getItem('user');
81
+ let locale = 'en';
82
+ if (user && JSON.parse(user).lang) {
83
+ locale = JSON.parse(user).lang;
84
+ }
85
+ const defaultFormattedUrl = locale !== DEFAULT_LOCALE && ['zh-cn', 'zh'].includes(locale)
86
+ ? `${API_ENDPOINT}/common/getBEECustomLangunage?langid=${MAPPED_LOCALE[locale]}`
87
+ : "";
88
+ useEffect(() => {
89
+ savedCallback.current = Object.keys(selectedTag).length > 0 ? selectedTag : rowMetaInfo;
90
+ }, [selectedTag, rowMetaInfo]);
91
+
92
+ const getExternalContentURLs = () => {
93
+ const externalContentURLs = categoryOptions.map((obj) => ({name: obj.label, value: `${API_ENDPOINT}/common/getCustomRows?category=${obj.value}&orgid=${loadItem('orgID')}`}));
94
+ return externalContentURLs;
95
+ };
96
+ useEffect(() => {
97
+ const beeConfig = {
98
+ uid,
99
+ container: 'bee-plugin-container',
100
+ translationsUrl: defaultFormattedUrl,
101
+ rowsConfiguration: {
102
+ emptyRows: true,
103
+ defaultRows: true,
104
+ externalContentURLs: getExternalContentURLs(),
105
+ },
106
+ contentDialog: {
107
+ specialLinks: {
108
+ label: UNSUBSCRIBE,
109
+ handler(resolve) {
110
+ resolve({
111
+ type: 'custom',
112
+ label: UNSUBSCRIBE,
113
+ link: `{{${UNSUBSCRIBE}}}`,
114
+ });
115
+ },
116
+ },
117
+ mergeTags: {
118
+ label: formatMessage(messages.addLabel),
119
+ handler: async (resolve, reject) => {
120
+ // this will open tag modal
121
+ await setVisibleTaglist(true);
122
+ // until tag modal will not open promise will not execute
123
+ // once tag modal is opened it will start 2 sec interval to wait use has selected any tag or cancel the tag selection
124
+ const promise = new Promise((resolveP) => {
125
+ intervalTimer = setInterval(() => {
126
+ // this will execute, if user cancel the tag selection
127
+ if ((savedCallback.current || {}).close === true) {
128
+ reject();
129
+ clearInterval(intervalTimer);
130
+ return;
131
+ }
132
+ // this block is checking use has selected any tag or not
133
+ if (Object.keys(savedCallback.current || {}).length > 0) {
134
+ resolveP(savedCallback.current);
135
+ setSelectedTag({});
136
+ clearInterval(intervalTimer);
137
+ }
138
+ }, 2000);
139
+ });
140
+ // once prmise will resolve , pass the resolve data to handler to show tags in bee edior
141
+ const result = await promise;
142
+ resolve(result);
143
+ },
144
+ },
145
+ saveRow: {
146
+ handler: async (resolve, reject) => {
147
+ await setRowMetaModal(true);
148
+ const promise = new Promise((resolveP) => {
149
+ intervalTimer = setInterval(() => {
150
+ if ((savedCallback.current || {}).close === true) {
151
+ reject();
152
+ clearInterval(intervalTimer);
153
+ setRowMetaInfo({});
154
+ setRowName('');
155
+ setRowCategory('');
156
+ return;
157
+ }
158
+ if (Object.keys(savedCallback.current || {}).length > 0) {
159
+ resolveP(savedCallback.current);
160
+ }
161
+ }, 2000);
162
+ });
163
+ const result = await promise;
164
+ resolve(result); // "done!"
165
+ setRowMetaInfo({});
166
+ setRowName('');
167
+ setRowCategory('');
168
+ clearInterval(intervalTimer);
169
+ },
170
+ },
171
+ },
172
+ onSave: (jsonFile, htmlFile) => {
173
+ saveBeeData(jsonFile, htmlFile);
174
+ },
175
+ onSaveRow: (rowJSON) => {
176
+ actions.createCustomRow(JSON.parse(rowJSON), callbackSaveRow);
177
+ },
178
+ };
179
+ window.BeePlugin.create(tokenData, beeConfig, (instance) => {
180
+ beePluginInstance = instance;
181
+ const parseJson = JSON.parse(beeJson);
182
+ beePluginInstance.start(parseJson);
183
+ saveBeeInstance(beePluginInstance);
184
+ });
185
+ return () => clearInterval(intervalTimer);
186
+ }, []);
187
+ const callbackSaveRow = (status, errorMsg) => {
188
+ if (status === 'success') {
189
+ CapNotification.success({message: formatMessage(messages.rowCreationSuccessMgs), key: 'create-custom-row-success'});
190
+ } else {
191
+ CapNotification.error({message: errorMsg || formatMessage(messages.rowCreationFailureMgs), key: 'create-custom-row-failure'});
192
+ }
193
+ };
194
+
195
+ const onTagSelect = (result) => {
196
+ const msg = {
197
+ name: result,
198
+ value: `{{${result}}}`,
199
+ };
200
+ setSelectedTag(msg);
201
+ setVisibleTaglist(false);
202
+ };
203
+
204
+ const onCancelTagList = () => {
205
+ setVisibleTaglist(false);
206
+ setSelectedTag({close: true});
207
+ };
208
+
209
+ const onCustomRowCancel = () => {
210
+ setRowMetaModal(false);
211
+ setRowCategory('');
212
+ setRowName('');
213
+ setRowMetaInfo({close: true});
214
+ };
215
+
216
+ const onCustomRowSave = () => {
217
+ const rowInfo = {};
218
+ if (rowCategory !== '') {
219
+ rowInfo.category = rowCategory;
220
+ }
221
+ setRowMetaInfo({
222
+ name: rowName,
223
+ ...rowInfo,
224
+ });
225
+ setRowMetaModal(false);
226
+ setRowCategory('');
227
+ setRowName('');
228
+ };
229
+
230
+ const isDisableSave = () => rowName === '' || rowCategory === '';
231
+
232
+ const onRowChange = useCallback((e) => {
233
+ setRowName(e.target.value);
234
+ });
235
+ const onChangeCategoy = (e) => {
236
+ setRowCategory(e);
237
+ };
238
+ const contentSection = <>
239
+ <CapInput
240
+ label={<FormattedMessage {...messages.rowName} />}
241
+ placeholder={formatMessage(messages.rowPlaceHolder)}
242
+ onChange={onRowChange}
243
+ value={rowName}
244
+ maxLength={50}
245
+ style={{ width: 324, paddingBottom: 21 }}
246
+ />
247
+ <CapSelect
248
+ label="Category"
249
+ style={{ width: 324, paddingBottom: 24}}
250
+ options={categoryOptions}
251
+ value={rowCategory || undefined}
252
+ placeholder={<FormattedMessage {...messages.selectCategoyPlaceholder} />}
253
+ onChange={onChangeCategoy}
254
+ />
255
+
256
+ </>;
257
+ return (
258
+ <CapSpin spinning={saveRowRequest || false}>
259
+ <div id="bee-plugin-container" style={{ height: '500px'}}>
260
+ </div>
261
+ <TagList
262
+ moduleFilterEnabled={moduleFilterEnabled}
263
+ label={label}
264
+ onTagSelect={onTagSelect}
265
+ location={location}
266
+ tags={filteredTags}
267
+ injectedTags={injectedTags}
268
+ className={className}
269
+ id={id}
270
+ userLocale={userLocale}
271
+ selectedOfferDetails={selectedOfferDetails}
272
+ visibleTaglist={visibleTaglist}
273
+ hidePopover
274
+ modalProps={{
275
+ onCancel: onCancelTagList,
276
+ style: { left: 135, top: 250 },
277
+ className: "bee-editor-tag-list",
278
+ }}
279
+ onContextChange={onContextChange}
280
+ />
281
+ <CapModal
282
+ className="custom-row-modal"
283
+ visible={showRowMetaModal}
284
+ onCancel={onCustomRowCancel}
285
+ title={formatMessage(messages.customRows)}
286
+ style={{width: 372, height: 296, left: 135, top: 300}}
287
+ footer={[
288
+ <CapButton key="submit" type="primary" id="delete-version" onClick={onCustomRowSave} disabled={isDisableSave()}>
289
+ {formatMessage(messages.done)}
290
+ </CapButton>,
291
+ ]}
292
+ >
293
+ {contentSection}
294
+ </CapModal>
295
+ </CapSpin>
296
+ );
297
+ }
298
+
299
+ BeeEditor.propTypes = {
300
+ beeJson: PropTypes.object.isRequired,
301
+ tokenData: PropTypes.object.isRequired,
302
+ uid: PropTypes.string.isRequired,
303
+ intl: intlShape.isRequired,
304
+ actions: PropTypes.object.isRequired,
305
+ BEESelect: PropTypes.object,
306
+ id: PropTypes.string,
307
+ location: PropTypes.object,
308
+ moduleFilterEnabled: PropTypes.bool,
309
+ label: PropTypes.string,
310
+ className: PropTypes.string,
311
+ tags: PropTypes.array,
312
+ saveBeeData: PropTypes.func,
313
+ saveBeeInstance: PropTypes.func,
314
+ injectedTags: PropTypes.object,
315
+ onContextChange: PropTypes.func,
316
+ userLocale: PropTypes.string,
317
+ };
318
+
319
+ const mapStateToProps = () => createStructuredSelector({
320
+ BEESelect: makeSelectBEE(),
321
+ });
322
+
323
+ function mapDispatchToProps(dispatch) {
324
+ return {
325
+ actions: bindActionCreators(beeActions, dispatch),
326
+ };
327
+ }
328
+
329
+ export default UserIsAuthenticated(connect(mapStateToProps, mapDispatchToProps)(injectIntl(BeeEditor)));
@@ -0,0 +1,6 @@
1
+ .custom-row-modal {
2
+ .ant-modal-footer {
3
+ text-align: left;
4
+ padding-left: 24px;
5
+ }
6
+ }
@@ -0,0 +1,67 @@
1
+ /*
2
+ * BeeEditor Messages
3
+ *
4
+ * This contains all the text for the BeeEditor component.
5
+ */
6
+ import { defineMessages } from 'react-intl';
7
+
8
+ const prefix = 'creatives.containersV2.BeeEditor';
9
+
10
+ export default defineMessages({
11
+ done: {
12
+ id: `${prefix}.done`,
13
+ defaultMessage: 'Done',
14
+ },
15
+ rowPlaceHolder: {
16
+ id: `${prefix}.rowPlaceHolder`,
17
+ defaultMessage: 'Enter Row name',
18
+ },
19
+ rowName: {
20
+ id: `${prefix}.rowName`,
21
+ defaultMessage: 'Row name',
22
+ },
23
+ select: {
24
+ id: `${prefix}.select`,
25
+ defaultMessage: 'Select',
26
+ },
27
+ customRows: {
28
+ id: `${prefix}.customRows`,
29
+ defaultMessage: 'Create new row',
30
+ },
31
+ selectCategoyPlaceholder: {
32
+ id: `${prefix}.selectCategoyPlaceholder`,
33
+ defaultMessage: 'Select category',
34
+ },
35
+ addLabel: {
36
+ id: `${prefix}.addLabel`,
37
+ defaultMessage: 'Add label',
38
+ },
39
+ cta: {
40
+ id: `${prefix}.cta`,
41
+ defaultMessage: 'CTA',
42
+ },
43
+ header: {
44
+ id: `${prefix}.header`,
45
+ defaultMessage: 'Header',
46
+ },
47
+ footer: {
48
+ id: `${prefix}.footer`,
49
+ defaultMessage: 'Footer',
50
+ },
51
+ others: {
52
+ id: `${prefix}.others`,
53
+ defaultMessage: 'Others',
54
+ },
55
+ socialPlatform: {
56
+ id: `${prefix}.socialPlatform`,
57
+ defaultMessage: 'Social platform',
58
+ },
59
+ rowCreationSuccessMgs: {
60
+ id: `${prefix}.rowCreationSuccessMgs`,
61
+ defaultMessage: 'Row created successfully',
62
+ },
63
+ rowCreationFailureMgs: {
64
+ id: `${prefix}.rowCreationFailureMgs`,
65
+ defaultMessage: 'Error in row creation',
66
+ },
67
+ });
@@ -0,0 +1,25 @@
1
+ import { fromJS } from 'immutable';
2
+ import {
3
+ CREATE_CUSTOM_ROW_REQUEST,
4
+ CREATE_CUSTOM_ROW_SUCCESS,
5
+ CREATE_CUSTOM_ROW_FAILURE,
6
+ } from './constants';
7
+
8
+ const initialState = fromJS({
9
+ saveRowRequest: false,
10
+ });
11
+
12
+ function beeEditorReducer(state = initialState, action) {
13
+ switch (action.type) {
14
+ case CREATE_CUSTOM_ROW_REQUEST:
15
+ return state.set('saveRowRequest', true);
16
+ case CREATE_CUSTOM_ROW_SUCCESS:
17
+ return state.set('saveRowRequest', false);
18
+ case CREATE_CUSTOM_ROW_FAILURE:
19
+ return state.set('saveRowRequest', false);
20
+ default:
21
+ return state;
22
+ }
23
+ }
24
+
25
+ export default beeEditorReducer;
@@ -0,0 +1,33 @@
1
+ import { take, cancel, call, put, takeLatest } from 'redux-saga/effects';
2
+ import { LOCATION_CHANGE } from 'react-router-redux';
3
+ import * as Api from '../../services/api';
4
+ import * as types from './constants';
5
+
6
+ export function* createCustomRow({data, callback}) {
7
+ let errorMsg;
8
+ try {
9
+ const result = yield call(Api.createCustomRow, data);
10
+ const code = result.status ? result.status.code : '';
11
+ if (!result.success || code === 500) {
12
+ errorMsg = result.message;
13
+ yield put({ type: types.CREATE_CUSTOM_ROW_FAILURE, errorMsg });
14
+ callback('failed', code !== 500 ? errorMsg : '');
15
+ } else {
16
+ yield put({ type: types.CREATE_CUSTOM_ROW_SUCCESS, data: result.response, statusCode: code, errorMsg });
17
+ callback('success');
18
+ }
19
+ } catch (error) {
20
+ yield put({ type: types.CREATE_CUSTOM_ROW_FAILURE, error, errorMsg });
21
+ }
22
+ }
23
+
24
+ function* watchCreateCustomRow() {
25
+ const watcher = yield takeLatest(types.CREATE_CUSTOM_ROW_REQUEST, createCustomRow);
26
+ yield take(LOCATION_CHANGE);
27
+ yield cancel(watcher);
28
+ }
29
+
30
+ // All sagas to be loaded
31
+ export default [
32
+ watchCreateCustomRow,
33
+ ];
@@ -0,0 +1,17 @@
1
+ import { createSelector } from 'reselect';
2
+ import { fromJS } from 'immutable';
3
+ /**
4
+ * Direct selector to the email state domain
5
+ */
6
+ const selectBEEDomain = () => (state) => state.get('beeEditor');
7
+
8
+ /**
9
+ * Default selector used by beeEditor
10
+ */
11
+
12
+ const makeSelectBEE = () => createSelector(
13
+ selectBEEDomain(),
14
+ (substate = fromJS({})) => substate.toJS()
15
+ );
16
+
17
+ export default makeSelectBEE;
@@ -0,0 +1,10 @@
1
+ // import React from 'react';
2
+ // import { shallow } from 'enzyme';
3
+
4
+ // import Beeeditor from '../index';
5
+
6
+ describe('<Beeeditor />', () => {
7
+ it('Expect to have unit tests specified', () => {
8
+ expect(true).toEqual(false);
9
+ });
10
+ });
@@ -1,27 +1,27 @@
1
- /*
2
- *
3
- * CreativesContainer actions
4
- *
5
- */
6
-
7
- import {
8
- DEFAULT_ACTION,
9
- HIDE_CONTAINER_LOADER,
10
- SHOW_CONTANER_LOADER,
11
- } from './constants';
12
-
13
- export function defaultAction() {
14
- return {
15
- type: DEFAULT_ACTION,
16
- };
17
- }
18
- export function showCreativesContainerLoader() {
19
- return {
20
- type: SHOW_CONTANER_LOADER,
21
- };
22
- }
23
- export function hideCreativesContanerLoader() {
24
- return {
25
- type: HIDE_CONTAINER_LOADER,
26
- };
27
- }
1
+ /*
2
+ *
3
+ * CreativesContainer actions
4
+ *
5
+ */
6
+
7
+ import {
8
+ DEFAULT_ACTION,
9
+ HIDE_CONTAINER_LOADER,
10
+ SHOW_CONTANER_LOADER,
11
+ } from './constants';
12
+
13
+ export function defaultAction() {
14
+ return {
15
+ type: DEFAULT_ACTION,
16
+ };
17
+ }
18
+ export function showCreativesContainerLoader() {
19
+ return {
20
+ type: SHOW_CONTANER_LOADER,
21
+ };
22
+ }
23
+ export function hideCreativesContanerLoader() {
24
+ return {
25
+ type: HIDE_CONTAINER_LOADER,
26
+ };
27
+ }
@@ -1,17 +1,17 @@
1
- /*
2
- *
3
- * CreativesContainer constants
4
- *
5
- */
6
-
7
- export const DEFAULT_ACTION = 'app/CreativesContainer/DEFAULT_ACTION';
8
- export const EMAIL = "EMAIL";
9
- export const SMS = "SMS";
10
- export const EBILL = "EBILL";
11
- export const LINE = "LINE";
12
- export const CALL_TASK = "CALL_TASK";
13
- export const MOBILE_PUSH = "MOBILEPUSH";
14
- export const WECHAT = "WECHAT";
15
- export const FACEBOOK = "FACEBOOK";
16
- export const SHOW_CONTANER_LOADER = "app/CreativesContainer/SHOW_CONTANER_LOADER";
17
- export const HIDE_CONTAINER_LOADER = "app/CreativesContainer/HIDE_CONTAINER_LOADER";
1
+ /*
2
+ *
3
+ * CreativesContainer constants
4
+ *
5
+ */
6
+
7
+ export const DEFAULT_ACTION = 'app/CreativesContainer/DEFAULT_ACTION';
8
+ export const EMAIL = "EMAIL";
9
+ export const SMS = "SMS";
10
+ export const EBILL = "EBILL";
11
+ export const LINE = "LINE";
12
+ export const CALL_TASK = "CALL_TASK";
13
+ export const MOBILE_PUSH = "MOBILEPUSH";
14
+ export const WECHAT = "WECHAT";
15
+ export const FACEBOOK = "FACEBOOK";
16
+ export const SHOW_CONTANER_LOADER = "app/CreativesContainer/SHOW_CONTANER_LOADER";
17
+ export const HIDE_CONTAINER_LOADER = "app/CreativesContainer/HIDE_CONTAINER_LOADER";