@capillarytech/creatives-library 2.0.43 → 2.0.45

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 (87) hide show
  1. package/components/CmsTemplatesComponent/index.js +1 -0
  2. package/components/FormBuilder/_formBuilder.scss +2 -14
  3. package/components/FormBuilder/index.js +106 -93
  4. package/components/Header/index.js +41 -0
  5. package/components/Header/messages.js +13 -0
  6. package/components/Header/tests/index.test.js +10 -0
  7. package/components/PreviewSideBar/index.js +7 -3
  8. package/components/TemplatePreview/index.js +6 -7
  9. package/config/app.js +2 -2
  10. package/containers/Cap/index.js +1 -1
  11. package/containers/Cap/selectors.js +11 -1
  12. package/containers/CreativesContainer/SlideBoxContent.js +5 -1
  13. package/containers/CreativesContainer/SlideBoxFooter.js +5 -9
  14. package/containers/CreativesContainer/index.js +56 -12
  15. package/containers/Email/actions.js +2 -3
  16. package/containers/Email/index.js +32 -26
  17. package/containers/Email/sagas.js +1 -0
  18. package/containers/EmailWrapper/index.js +43 -13
  19. package/containers/EmailWrapper/messages.js +8 -0
  20. package/containers/MobilePush/Create/index.js +1 -1
  21. package/containers/Sms/Create/actions.js +4 -4
  22. package/containers/Sms/Create/index.js +28 -17
  23. package/containers/Sms/Create/sagas.js +1 -2
  24. package/containers/Sms/Edit/actions.js +4 -5
  25. package/containers/Sms/Edit/index.js +31 -5
  26. package/containers/Sms/Edit/sagas.js +1 -3
  27. package/containers/Templates/actions.js +3 -1
  28. package/containers/Templates/index.js +219 -84
  29. package/containers/Templates/messages.js +8 -0
  30. package/containers/Templates/sagas.js +16 -4
  31. package/containers/Templates/selectors.js +2 -0
  32. package/containers/TemplatesV2/index.js +11 -7
  33. package/containers/WeChat/MapTemplates/_mapTemplates.scss +8 -0
  34. package/containers/WeChat/MapTemplates/actions.js +52 -0
  35. package/containers/WeChat/MapTemplates/constants.js +28 -0
  36. package/containers/WeChat/MapTemplates/index.js +1401 -0
  37. package/containers/WeChat/MapTemplates/messages.js +73 -0
  38. package/containers/WeChat/MapTemplates/reducer.js +74 -0
  39. package/containers/WeChat/MapTemplates/sagas.js +86 -0
  40. package/containers/WeChat/MapTemplates/selectors.js +25 -0
  41. package/containers/WeChat/MapTemplates/tests/actions.test.js +18 -0
  42. package/containers/WeChat/MapTemplates/tests/index.test.js +10 -0
  43. package/containers/WeChat/MapTemplates/tests/reducer.test.js +9 -0
  44. package/containers/WeChat/MapTemplates/tests/sagas.test.js +15 -0
  45. package/containers/WeChat/MapTemplates/tests/selectors.test.js +10 -0
  46. package/containers/WeChat/RichmediaTemplates/Create/_createRichmedia.scss +13 -0
  47. package/containers/WeChat/RichmediaTemplates/Create/actions.js +35 -0
  48. package/containers/WeChat/RichmediaTemplates/Create/constants.js +14 -0
  49. package/containers/WeChat/RichmediaTemplates/Create/index.js +679 -0
  50. package/containers/WeChat/RichmediaTemplates/Create/messages.js +13 -0
  51. package/containers/WeChat/RichmediaTemplates/Create/reducer.js +49 -0
  52. package/containers/WeChat/RichmediaTemplates/Create/sagas.js +44 -0
  53. package/containers/WeChat/RichmediaTemplates/Create/selectors.js +32 -0
  54. package/containers/WeChat/RichmediaTemplates/Create/tests/actions.test.js +18 -0
  55. package/containers/WeChat/RichmediaTemplates/Create/tests/index.test.js +10 -0
  56. package/containers/WeChat/RichmediaTemplates/Create/tests/reducer.test.js +9 -0
  57. package/containers/WeChat/RichmediaTemplates/Create/tests/sagas.test.js +15 -0
  58. package/containers/WeChat/RichmediaTemplates/Create/tests/selectors.test.js +10 -0
  59. package/containers/WeChat/RichmediaTemplates/Create/testschema.js +379 -0
  60. package/containers/WeChat/RichmediaTemplates/Edit/actions.js +20 -0
  61. package/containers/WeChat/RichmediaTemplates/Edit/constants.js +10 -0
  62. package/containers/WeChat/RichmediaTemplates/Edit/index.js +98 -0
  63. package/containers/WeChat/RichmediaTemplates/Edit/messages.js +13 -0
  64. package/containers/WeChat/RichmediaTemplates/Edit/reducer.js +28 -0
  65. package/containers/WeChat/RichmediaTemplates/Edit/sagas.js +32 -0
  66. package/containers/WeChat/RichmediaTemplates/Edit/selectors.js +25 -0
  67. package/containers/WeChat/RichmediaTemplates/Edit/tests/actions.test.js +18 -0
  68. package/containers/WeChat/RichmediaTemplates/Edit/tests/index.test.js +10 -0
  69. package/containers/WeChat/RichmediaTemplates/Edit/tests/reducer.test.js +9 -0
  70. package/containers/WeChat/RichmediaTemplates/Edit/tests/sagas.test.js +15 -0
  71. package/containers/WeChat/RichmediaTemplates/Edit/tests/selectors.test.js +10 -0
  72. package/containers/WeChat/RichmediaTemplates/View/actions.js +15 -0
  73. package/containers/WeChat/RichmediaTemplates/View/constants.js +7 -0
  74. package/containers/WeChat/RichmediaTemplates/View/index.js +45 -0
  75. package/containers/WeChat/RichmediaTemplates/View/messages.js +13 -0
  76. package/containers/WeChat/RichmediaTemplates/View/reducer.js +23 -0
  77. package/containers/WeChat/RichmediaTemplates/View/sagas.js +11 -0
  78. package/containers/WeChat/RichmediaTemplates/View/selectors.js +25 -0
  79. package/containers/WeChat/RichmediaTemplates/View/tests/actions.test.js +18 -0
  80. package/containers/WeChat/RichmediaTemplates/View/tests/index.test.js +10 -0
  81. package/containers/WeChat/RichmediaTemplates/View/tests/reducer.test.js +9 -0
  82. package/containers/WeChat/RichmediaTemplates/View/tests/sagas.test.js +15 -0
  83. package/containers/WeChat/RichmediaTemplates/View/tests/selectors.test.js +10 -0
  84. package/index.js +3 -3
  85. package/package.json +2 -3
  86. package/routes.js +53 -13
  87. package/services/api.js +6 -1
@@ -0,0 +1,679 @@
1
+ /*
2
+ *
3
+ * Create
4
+ *
5
+ */
6
+
7
+ import React, { PropTypes } from 'react';
8
+ import { connect } from 'react-redux';
9
+ import Helmet from 'react-helmet';
10
+ import { bindActionCreators } from 'redux';
11
+ import { createStructuredSelector } from 'reselect';
12
+ import _ from 'lodash';
13
+ import { Menu, Dropdown } from 'antd';
14
+ import { CapRow, CapColumn, CapButton, CapCard, CapSpinner } from '@capillarytech/cap-ui-library';
15
+ import makeSelectCreate, {makeSelectTemplates, getAssetDetails} from './selectors';
16
+ import * as actions from './actions';
17
+ import testschema from './testschema';
18
+ import './_createRichmedia.scss';
19
+ import * as globalActions from '../../../../containers/Cap/actions';
20
+ import {getMessageObject} from '../../../../utils/messageUtils';
21
+ import FormBuilder from '../../../../components/FormBuilder';
22
+ import Header from '../../../../components/Header';
23
+ const MenuItem = Menu.Item;
24
+ export class Create extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
25
+ constructor(props) {
26
+ super(props);
27
+ let templateData = {};
28
+ let isEdit = false;
29
+ let totalContentBlocks = 0;
30
+ let mediaId = "";
31
+ let templateId = "";
32
+ let templateName = "";
33
+ let isIframe = false;
34
+ if (props.location.query.type === "embedded" && props.location.query.module === "outbound") {
35
+ isIframe = true;
36
+ }
37
+ if (props.mode === 'EDIT') {
38
+ templateData = props.templateData;
39
+ isEdit = true;
40
+ totalContentBlocks = props.totalContentBlocks;
41
+ mediaId = props.mediaId;
42
+ templateId = props.templateId;
43
+ templateName = props.templateName;
44
+ }
45
+ this.state = {
46
+ richmediaSchema: testschema,
47
+ map: {
48
+ "image-value": {
49
+ onUpload: this.uploadImage,
50
+ },
51
+ "title-value": {
52
+ onChange: this.onFormDataChange,
53
+ },
54
+ "author-value": {
55
+ onChange: this.onFormDataChange,
56
+ },
57
+ "cover-abstract-value": {
58
+ onChange: this.onFormDataChange,
59
+ },
60
+ "source-link-value": {
61
+ onChange: this.onFormDataChange,
62
+ },
63
+ "content-value": {
64
+ onChange: this.onFormDataChange,
65
+ },
66
+ "show-cover-pic-value": {
67
+ onChange: this.onFormDataChange,
68
+ },
69
+ "post-comments-value": {
70
+ onChange: this.onFormDataChange,
71
+ },
72
+ },
73
+ isEdit,
74
+ isFormValid: true,
75
+ templateData,
76
+ currentContentId: 0,
77
+ totalContentBlocks,
78
+ templateName,
79
+ templateId,
80
+ mediaId,
81
+ isIframe,
82
+ hovered: false,
83
+ loading: false,
84
+ showModal: false,
85
+ modalContent: {
86
+ title: "Alert",
87
+ body: "Do you really want to go back? All your temporary changes will be lost!",
88
+ type: 'confirm',
89
+ id: 'template-back-confirm-modal',
90
+ },
91
+ };
92
+ this.onFormDataChange = this.onFormDataChange.bind(this);
93
+ this.cancelHandler = this.cancelHandler.bind(this);
94
+ this.templateNameHandler = this.templateNameHandler.bind(this);
95
+ this.saveHandler = this.saveHandler.bind(this);
96
+ this.previewHandler = this.previewHandler.bind(this);
97
+ this.setFormValidity = this.setFormValidity.bind(this);
98
+ this.injectEvents = this.injectEvents.bind(this);
99
+ this.injectSections = this.injectSections.bind(this);
100
+ this.injectContainer = this.injectContainer.bind(this);
101
+ this.injectColLabelSection = this.injectColLabelSection.bind(this);
102
+ this.injectMultiColSection = this.injectMultiColSection.bind(this);
103
+ this.getMappedEvent = this.getMappedEvent.bind(this);
104
+ this.updateTotalContentBlocks = this.updateTotalContentBlocks.bind(this);
105
+ this.insertTemplateData = this.insertTemplateData.bind(this);
106
+ this.uploadImage = this.uploadImage.bind(this);
107
+ this.returnCardLayout = this.returnCardLayout.bind(this);
108
+ this.menuOnClickEvent = this.menuOnClickEvent.bind(this);
109
+ this.showErrorMessage = this.showErrorMessage.bind(this);
110
+ this.returnCurrentFormData = this.returnCurrentFormData.bind(this);
111
+ this.returnCurrentSchema = this.returnCurrentSchema.bind(this);
112
+ this.handleFrameTasks = this.handleFrameTasks.bind(this);
113
+ this.getCurrentWindow = this.getCurrentWindow.bind(this);
114
+ // this.startLoading = this.startLoading.bind(this);
115
+ this.moveToTemplates = this.moveToTemplates.bind(this);
116
+ this.showNext = this.showNext.bind(this);
117
+ }
118
+ componentDidMount = () => {
119
+ if (!this.state.isEdit) {
120
+ this.updateTotalContentBlocks();
121
+ }
122
+ if (this.state.isIframe) {
123
+ window.addEventListener("message", this.handleFrameTasks);
124
+ this.showNext();
125
+ }
126
+ }
127
+ componentWillReceiveProps = (nextProps) => {
128
+ if (nextProps.Create.saveTemplateRes && !_.isEmpty(nextProps.Create.saveTemplateRes) && nextProps.Create.saveTemplateSuccess && !_.isEmpty(nextProps.Create.saveTemplateSuccess)) {
129
+ const type = nextProps.location.query.type;
130
+ this.props.router.push({
131
+ pathname: `/wechat`,
132
+ query: type === 'embedded' ? {type: 'embedded'} : {},
133
+ });
134
+ }
135
+ }
136
+ componentWillUnmount() {
137
+ if (this.state.isIframe) {
138
+ window.removeEventListener("message", this.handleFrameTasks);
139
+ }
140
+ }
141
+ onHover = (data) => {
142
+ this.setState({hovered: data});
143
+ }
144
+ onHoverRemove = (data) => {
145
+ this.setState({hovered: data});
146
+ }
147
+ onFormDataChange = (currentFormData) => {
148
+ const isLimitExceeded = this.checkFormFieldsCount(currentFormData);
149
+ if (!isLimitExceeded) {
150
+ const templateData = _.cloneDeep(this.state.templateData);
151
+ templateData[this.state.currentContentId].formData = _.cloneDeep(currentFormData);
152
+ this.setState({templateData});
153
+ }
154
+ }
155
+ getMappedEvent = (id, event) => {
156
+ const map = this.state.map;
157
+ // if (!map[id] || !map[id][event]) {
158
+ // }
159
+ return map[id][event];
160
+ }
161
+ setFormValidity = (isFormValid) => {
162
+ this.setState({isFormValid});
163
+ }
164
+ getCurrentWindow(e) {
165
+ const response = {
166
+ action: e.action,
167
+ value: 'edit',
168
+ direction: e.value,
169
+ };
170
+ parent.postMessage(JSON.stringify(response), '*');
171
+ }
172
+ getFormData(e) {
173
+ console.log("getformdata wechat richmedia: ", this.state.templateData, this.props, this.state);
174
+ const message = {
175
+ mediaList: this.props.templateData.templateDetails.versions.base.mediaList,
176
+ media_id: this.props.templateData.templateDetails.versions.base.mediaId,
177
+ definition: {
178
+ msgtype: "IMAGE",
179
+ msgcontent: "RICH_MEDIA_WECHAT",
180
+ },
181
+ };
182
+ const data = {
183
+ data: message,
184
+ accountId: this.props.Templates && this.props.Templates.selectedWeChatAccount && this.props.Templates.selectedWeChatAccount.id,
185
+ template_id: this.props.templateId,
186
+ Title: this.props.templateName,
187
+ OriginalId: this.props.Templates.selectedWeChatAccount.sourceAccountIdentifier,
188
+ TopColor: "#000000",
189
+ touser: "{{wechat_open_id}}",
190
+ creative_template_id: this.props.templateId,
191
+ };
192
+ const response = {
193
+ action: "getFormData",
194
+ value: data,
195
+ validity: this.state.isFormValid,
196
+ };
197
+ console.log("getformdata2 wechat richmedia: ", data);
198
+ e.source.postMessage(JSON.stringify(response), e.origin);
199
+ }
200
+ showErrorMessage = (errorMessage) => {
201
+ const message = getMessageObject('error', errorMessage, true);
202
+ this.props.globalActions.addMessageToQueue(message);
203
+ }
204
+ checkFormFieldsCount = (currentFormData) => {
205
+ let isLimitExceeded = false;
206
+ if (_.isEmpty(currentFormData)) {
207
+ isLimitExceeded = true;
208
+ return isLimitExceeded;
209
+ }
210
+ if (currentFormData['title-value'].length > 64) {
211
+ this.showErrorMessage("Title exceeds character count limit");
212
+ isLimitExceeded = true;
213
+ }
214
+ if (currentFormData['author-value'].length > 8) {
215
+ this.showErrorMessage("Author exceeds character count limit");
216
+ isLimitExceeded = true;
217
+ }
218
+ if (currentFormData['cover-abstract-value'].length > 120) {
219
+ this.showErrorMessage("Cover abstract exceeds character count limit");
220
+ isLimitExceeded = true;
221
+ }
222
+ return isLimitExceeded;
223
+ }
224
+ // startLoading(ifEdit) {
225
+ // if (ifEdit) {
226
+ // this.setState({loading: true});
227
+ // }
228
+ // }
229
+ moveToTemplates() {
230
+ const modalContent = {
231
+ title: "Alert",
232
+ body: "Do you really want to go back? All your temporary changes will be lost!",
233
+ type: 'confirm',
234
+ id: 'template-back-confirm-modal',
235
+ show: true,
236
+ };
237
+ this.setState({modalContent, showModal: true});
238
+ }
239
+ handleCancelModal = () => {
240
+ this.setState({showModal: false});
241
+ }
242
+ showNext() {
243
+ const response = {
244
+ action: "showNext",
245
+ value: true,
246
+ };
247
+ parent.postMessage(JSON.stringify(response), '*');
248
+ }
249
+ handleFrameTasks = (e) => {
250
+ const type = e.data;
251
+ if (typeof type === 'object') {
252
+ const action = type.action;
253
+ switch (action) {
254
+ case "startLoading":
255
+ this.startLoading(type.edit);
256
+ break;
257
+ case "getCurrentWindow":
258
+ this.getCurrentWindow(type);
259
+ break;
260
+ default:
261
+ break;
262
+ }
263
+ } else {
264
+ switch (type) {
265
+ case "getFormData":
266
+ this.getFormData(e);
267
+ break;
268
+ case "moveToTemplates":
269
+ this.moveToTemplates();
270
+ break;
271
+ default:
272
+ break;
273
+ }
274
+ }
275
+ }
276
+ injectEvents = (schema) => {
277
+ const temp = schema;
278
+ if (temp.standalone) {
279
+ temp.standalone.sections = this.injectSections(temp.standalone.sections);
280
+ }
281
+ if (temp.containers) {
282
+ _.forEach(temp.containers, (container) => {
283
+ let tempContainer = container;
284
+ tempContainer = this.injectContainer(tempContainer);
285
+ return tempContainer;
286
+ });
287
+ }
288
+ return schema;
289
+ }
290
+ injectContainer = (container) => {
291
+ const temp = container;
292
+ if (temp.type === 'tabs') {
293
+ temp.injectedEvents = {};
294
+ _.forEach(temp.supportedEvents, (event) => {
295
+ temp.injectedEvents[event] = this.getMappedEvent(temp.id, event);
296
+ });
297
+ _.forEach(temp.panes, (pane) => {
298
+ const tempPane = pane;
299
+ tempPane.sectionsHeaders = this.injectSections(tempPane.sectionsHeaders);
300
+ tempPane.sections = this.injectSections(tempPane.sections);
301
+ });
302
+ }
303
+ return temp;
304
+ }
305
+ injectSections = (sections) => {
306
+ _.forEach(sections, (section) => {
307
+ let temp = section;
308
+ if (temp.type === 'col-label') {
309
+ temp = this.injectColLabelSection(temp);
310
+ } else if (section.type === 'multicols') {
311
+ temp = this.injectMultiColSection(temp);
312
+ } else if (section.type === 'parent') {
313
+ temp = this.injectSections(temp.childSections);
314
+ }
315
+ });
316
+ return sections;
317
+ }
318
+ injectColLabelSection = (section) => {
319
+ _.forEach(section.inputFields, (inputField) => {
320
+ const temp = inputField;
321
+ temp.injectedEvents = {};
322
+ _.forEach(inputField.supportedEvents, (event) => {
323
+ temp.injectedEvents[event] = this.getMappedEvent(inputField.id, event);
324
+ });
325
+ return true;
326
+ });
327
+ _.forEach(section.actionFields, (actionField) => {
328
+ const temp = actionField;
329
+ temp.injectedEvents = {};
330
+ _.forEach(actionField.supportedEvents, (event) => {
331
+ temp.injectedEvents[event] = this.getMappedEvent(actionField.id, event);
332
+ });
333
+ return true;
334
+ });
335
+ return section;
336
+ }
337
+ injectMultiColSection = (section) => {
338
+ _.forEach(section.inputFields, (inputField) => {
339
+ _.forEach(inputField.cols, (col) => {
340
+ const temp = col;
341
+ temp.injectedEvents = {};
342
+ _.forEach(col.supportedEvents, (event) => {
343
+ temp.injectedEvents[event] = this.getMappedEvent(col.id, event);
344
+ });
345
+ return true;
346
+ });
347
+ });
348
+ _.forEach(section.actionFields, (actionField) => {
349
+ _.forEach(actionField.cols, (col) => {
350
+ const temp = col;
351
+ temp.injectedEvents = {};
352
+ _.forEach(col.supportedEvents, (event) => {
353
+ temp.injectedEvents[event] = this.getMappedEvent(col.id, event);
354
+ });
355
+ return true;
356
+ });
357
+ });
358
+ return section;
359
+ }
360
+ templateNameHandler = (ev) => {
361
+ const { value } = ev.target;
362
+ this.setState({templateName: value});
363
+ }
364
+ cancelHandler = () => {
365
+ const type = this.props.location.query.type;
366
+ this.props.router.push({
367
+ pathname: `/wechat`,
368
+ query: type === 'embedded' ? {type: 'embedded'} : {},
369
+ });
370
+ }
371
+ previewHandler = () => {
372
+ }
373
+ saveHandler = () => {
374
+ let isFormValid = this.validateFormFields();
375
+ if (_.isEmpty(this.state.templateName)) {
376
+ this.showErrorMessage("Cannot leave template name empty");
377
+ isFormValid = false;
378
+ }
379
+ if (isFormValid) {
380
+ const templateData = _.cloneDeep(this.state.templateData);
381
+ const mediaList = [];
382
+ _.forEach(templateData, (contentData) => {
383
+ const filteredContent = {
384
+ title: contentData.formData['title-value'],
385
+ author: contentData.formData['author-value'] ? contentData.formData['author-value'] : '',
386
+ digest: contentData.formData['cover-abstract-value'] ? contentData.formData['cover-abstract-value'] : '',
387
+ content: contentData.formData['content-value'],
388
+ content_source_url: contentData.formData['source-link-value'],
389
+ show_cover_pic: contentData.formData['show-cover-pic-value'] === true ? 1 : 0,
390
+ post_comments_scope: contentData.formData['post-comments-value'] ? contentData.formData['post-comments-value'] : 'No one',
391
+ thumb_media_id: contentData.mediaId,
392
+ image_url: contentData.imageUrl,
393
+ };
394
+ mediaList.push(filteredContent);
395
+ });
396
+ const saveObj = {};
397
+ saveObj.name = this.state.templateName.trim();
398
+ saveObj.appId = this.props.Templates.selectedWeChatAccount.configs.wechat_app_id;
399
+ saveObj.appSecret = this.props.Templates.selectedWeChatAccount.configs.wechat_app_secret;
400
+ saveObj.versions = {
401
+ base: {
402
+ OriginalId: this.props.Templates.selectedWeChatAccount.sourceAccountIdentifier,
403
+ mediaList,
404
+ },
405
+ history: [],
406
+ };
407
+ saveObj.definition = {
408
+ msgtype: "IMAGE",
409
+ msgcontent: "RICH_MEDIA_WECHAT",
410
+ };
411
+ if (this.state.isEdit) {
412
+ saveObj._id = this.props.templateId;
413
+ saveObj.mediaId = this.props.mediaId;
414
+ saveObj.type = "WECHAT";
415
+ }
416
+ this.props.actions.saveTemplate(saveObj);
417
+ }
418
+ }
419
+ uploadImage = (data) => {
420
+ if (data.fileParams.error) {
421
+ // const message = getMessageObject('error', this.props.intl.formatMessage(messages["File size cannot be more than 5mb"]), true);
422
+ // this.props.globalActions.addMessageToQueue(message);
423
+ } else {
424
+ const wechatParams = {
425
+ appId: this.props.Templates.selectedWeChatAccount.configs.wechat_app_id,
426
+ appSecret: this.props.Templates.selectedWeChatAccount.configs.wechat_app_secret,
427
+ source: 'wechat',
428
+ };
429
+ this.props.actions.uploadAsset(data.file, data.type, data.fileParams, null, wechatParams, this.state.currentContentId);
430
+ }
431
+ }
432
+ updateTotalContentBlocks = () => {
433
+ if (this.state.totalContentBlocks < 8) {
434
+ this.setState({
435
+ totalContentBlocks: this.state.totalContentBlocks + 1,
436
+ }, () => {
437
+ this.insertTemplateData();
438
+ });
439
+ } else {
440
+ this.showErrorMessage("You have reached the maximum template size");
441
+ }
442
+ }
443
+ insertTemplateData = () => {
444
+ const templateData = _.cloneDeep(this.state.templateData);
445
+ templateData[this.state.totalContentBlocks - 1] = {
446
+ formData: {},
447
+ imageUrl: "",
448
+ mediaId: "",
449
+ };
450
+ this.setState({templateData});
451
+ }
452
+ updateImageData = () => {
453
+ const templateData = _.cloneDeep(this.state.templateData);
454
+ if (this.props.ImageData && !_.isEmpty(this.props.ImageData[this.state.currentContentId]) && this.props.ImageData[this.state.currentContentId].metaInfo && this.props.ImageData[this.state.currentContentId].metaInfo.secure_file_path && this.props.ImageData[this.state.currentContentId].metaInfo.mediaId && templateData[this.state.currentContentId].imageUrl !== this.props.ImageData[this.state.currentContentId].metaInfo.secure_file_path) {
455
+ templateData[this.state.currentContentId].imageUrl = this.props.ImageData[this.state.currentContentId].metaInfo.secure_file_path;
456
+ templateData[this.state.currentContentId].mediaId = this.props.ImageData[this.state.currentContentId].metaInfo.mediaId;
457
+ this.setState({templateData});
458
+ }
459
+ }
460
+ updateTemplateData = (e, id) => {
461
+ //e.stopPropagation();
462
+ this.setState({currentContentId: id});
463
+ }
464
+ returnCardLayout = () => {
465
+ const templateData = _.cloneDeep(this.state.templateData);
466
+ const returnObj = [];
467
+ _.forEach(templateData, (contentData, contentId) => {
468
+ const id = parseInt(contentId, 10);
469
+ const imageUrl = contentData.imageUrl;
470
+ if (id === 0) {
471
+ returnObj[id] = (
472
+ <CapCard
473
+ id={id}
474
+ style={{ width: 244, height: 221 }}
475
+ bodyStyle={{ padding: 0 }}
476
+ onClick={(e) => this.updateTemplateData(e, id)}
477
+ // onMouseEnter={() => this.onHover(true, contentId)}
478
+ // onMouseLeave={() => this.onHoverRemove(false, contentId)}
479
+ // className={this.state.hovered ? 'hovered' : ''}
480
+ >
481
+ <div>
482
+ <div className="custom-image">
483
+ <img alt="default" width="242px" height="139px" src={imageUrl} />
484
+ </div>
485
+ <div className="custom-card">
486
+ <p>{contentData && contentData.formData ? contentData.formData['cover-abstract-value'] : ""}</p>
487
+ </div>
488
+ </div>
489
+ </CapCard>
490
+ );
491
+ } else {
492
+ returnObj[id] = (
493
+ <div id={id} onClick={(e) => this.updateTemplateData(e, id)}>
494
+ <CapRow style={{ width: 244, height: 53 }}>
495
+ <CapColumn span={18}>
496
+ {contentData && contentData.formData ? contentData.formData['title-value'] : ""}
497
+ </CapColumn>
498
+ <CapColumn span={6}>
499
+ <img alt="default" width="50px" height="47px" src={imageUrl} />
500
+ </CapColumn>
501
+ </CapRow>
502
+ </div>
503
+ );
504
+ }
505
+ });
506
+ return (
507
+ <div>{returnObj}</div>
508
+ );
509
+ }
510
+ validateFormFields = () => {
511
+ let isValid = true;
512
+ const currentContent = this.state.templateData[this.state.currentContentId];
513
+ if (_.isEmpty(currentContent.formData)) {
514
+ this.showErrorMessage("Cannot leave form empty");
515
+ isValid = false;
516
+ }
517
+ if (_.isEmpty(currentContent.formData['title-value'])) {
518
+ this.showErrorMessage("Cannot leave title field empty");
519
+ isValid = false;
520
+ }
521
+ if (_.isEmpty(currentContent.formData['source-link-value'])) {
522
+ this.showErrorMessage("Cannot leave source link field empty");
523
+ isValid = false;
524
+ }
525
+ if (_.isEmpty(currentContent.formData['content-value'])) {
526
+ this.showErrorMessage("Cannot leave content field empty");
527
+ isValid = false;
528
+ }
529
+ if (_.isEmpty(currentContent.imageUrl) || _.isEmpty(currentContent.mediaId)) {
530
+ this.showErrorMessage("Please upload an image");
531
+ isValid = false;
532
+ }
533
+ return isValid;
534
+ }
535
+ menuOnClickEvent(ev) {
536
+ const isFormValid = this.validateFormFields();
537
+ if (!isFormValid) {
538
+ return false;
539
+ }
540
+ switch (ev.key) {
541
+ case "new_richmedia_content":
542
+ this.setState({
543
+ currentContentId: this.state.currentContentId + 1,
544
+ }, () => {
545
+ this.updateTotalContentBlocks();
546
+ });
547
+ break;
548
+ case "old_richmedia_content":
549
+ this.setState({
550
+ currentContentId: this.state.currentContentId + 1,
551
+ }, () => {
552
+ this.updateTotalContentBlocks();
553
+ });
554
+ break;
555
+ default:
556
+ this.setState({
557
+ currentContentId: this.state.currentContentId + 1,
558
+ }, () => {
559
+ this.updateTotalContentBlocks();
560
+ });
561
+ }
562
+ return true;
563
+ }
564
+ returnContentMenu = () => {
565
+ let actionButton = '';
566
+ const createPushMenu = (
567
+ <Menu onClick={this.menuOnClickEvent}>
568
+ {/* <MenuItem key="old_richmedia_content">
569
+ Add existing Richmedia content
570
+ </MenuItem> */}
571
+ <MenuItem key="new_richmedia_content">
572
+ Add Richmedia content
573
+ </MenuItem>
574
+ </Menu>
575
+ );
576
+ actionButton = (<Dropdown overlay={createPushMenu} trigger={['click']}>
577
+ <CapButton style={{width: '244', height: '53', marginTop: '16'}} type="secondary">
578
+ <div style={{display: 'inline-flex'}}>
579
+ <p>
580
+ <i style={{ color: '#2e89df'}} className="material-icons">+</i>
581
+ </p>
582
+ </div>
583
+ </CapButton>
584
+ </Dropdown>);
585
+ return actionButton;
586
+ }
587
+ returnCurrentSchema = () => {
588
+ let schema = {};
589
+ if (this.state.isIframe) {
590
+ const disabledFormSchema = _.cloneDeep(this.state.richmediaSchema);
591
+ disabledFormSchema.standalone.sections[0].inputFields[0].cols[1].disabled = true;
592
+ disabledFormSchema.standalone.sections[0].inputFields[1].cols[1].disabled = true;
593
+ disabledFormSchema.standalone.sections[0].inputFields[2].cols[1].disabled = true;
594
+ disabledFormSchema.standalone.sections[0].inputFields[3].cols[1].disabled = true;
595
+ disabledFormSchema.standalone.sections[0].inputFields[4].cols[1].disabled = true;
596
+ disabledFormSchema.standalone.sections[0].inputFields[5].cols[1].disabled = true;
597
+ disabledFormSchema.standalone.sections[0].inputFields[6].cols[1].disabled = true;
598
+ disabledFormSchema.standalone.sections[0].inputFields[7].cols[1].disabled = true;
599
+ schema = this.injectEvents(disabledFormSchema);
600
+ return schema;
601
+ }
602
+ schema = this.injectEvents(this.state.richmediaSchema);
603
+ return schema;
604
+ }
605
+ returnCurrentFormData = () => {
606
+ const formData = this.state.templateData && !_.isEmpty(this.state.templateData[this.state.currentContentId]) && this.state.templateData[this.state.currentContentId].formData ? _.cloneDeep(this.state.templateData[this.state.currentContentId].formData) : {};
607
+ return formData;
608
+ }
609
+ render() {
610
+ const cardLayout = this.returnCardLayout();
611
+ const contentMenu = this.returnContentMenu();
612
+ const schema = this.returnCurrentSchema();
613
+ const formData = this.returnCurrentFormData();
614
+ this.updateImageData();
615
+ return (
616
+ <CapSpinner spinning={this.state.loading}>
617
+ <div>
618
+ <Helmet
619
+ title="Wechat Richmedia"
620
+ />
621
+ <div className="wechat-container">
622
+ {!this.state.isIframe && <Header templateName={this.state.templateName} templateNameHandler={this.templateNameHandler} previewHandler={this.previewHandler} cancelHandler={this.cancelHandler} saveHandler={this.saveHandler} />}
623
+ <CapRow className="wechat-form-container">
624
+ <CapColumn span={6}>
625
+ {cardLayout}
626
+ {!this.state.isIframe && contentMenu}
627
+ </CapColumn>
628
+ <CapColumn span={18}>
629
+ <FormBuilder
630
+ key={this.state.currentContentId}
631
+ schema={schema}
632
+ onChange={this.onFormDataChange}
633
+ parent={this}
634
+ formData={formData}
635
+ onFormValidityChange={this.setFormValidity}
636
+ location={this.props.location}
637
+ usingTabContainer={false}
638
+ router={this.props.router}
639
+ modal={this.state.modalContent}
640
+ showModal={this.state.showModal}
641
+ />
642
+ </CapColumn>
643
+ </CapRow>
644
+ </div>
645
+ </div>
646
+ </CapSpinner>
647
+ );
648
+ }
649
+ }
650
+
651
+ Create.propTypes = {
652
+ location: PropTypes.object,
653
+ router: PropTypes.object,
654
+ mode: PropTypes.string,
655
+ templateData: PropTypes.object,
656
+ totalContentBlocks: PropTypes.integer,
657
+ templateName: PropTypes.string,
658
+ templateId: PropTypes.string,
659
+ mediaId: PropTypes.string,
660
+ Templates: PropTypes.object,
661
+ ImageData: PropTypes.object,
662
+ actions: PropTypes.object,
663
+ globalActions: PropTypes.object,
664
+ };
665
+
666
+ const mapStateToProps = createStructuredSelector({
667
+ Create: makeSelectCreate(),
668
+ Templates: makeSelectTemplates(),
669
+ ImageData: getAssetDetails(),
670
+ });
671
+
672
+ function mapDispatchToProps(dispatch) {
673
+ return {
674
+ actions: bindActionCreators(actions, dispatch),
675
+ globalActions: bindActionCreators(globalActions, dispatch),
676
+ };
677
+ }
678
+
679
+ export default connect(mapStateToProps, mapDispatchToProps)(Create);
@@ -0,0 +1,13 @@
1
+ /*
2
+ * Create Messages
3
+ *
4
+ * This contains all the text for the Create component.
5
+ */
6
+ import { defineMessages } from 'react-intl';
7
+
8
+ export default defineMessages({
9
+ header: {
10
+ id: 'app.containers.Create.header',
11
+ defaultMessage: 'This is Create container !',
12
+ },
13
+ });