@capillarytech/creatives-library 2.0.66 → 2.0.68

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 (42) hide show
  1. package/components/Ckeditor/index.js +30 -3
  2. package/components/FormBuilder/index.js +50 -27
  3. package/components/FormBuilder/test +1845 -0
  4. package/components/Header/index.js +7 -4
  5. package/components/Header/messages.js +12 -0
  6. package/components/TemplatePreview/WechatRichmediaTemplatePreview/_wechatRichmediaTemplatePrev.scss +42 -0
  7. package/components/TemplatePreview/WechatRichmediaTemplatePreview/index.js +104 -0
  8. package/components/TemplatePreview/WechatRichmediaTemplatePreview/messages.js +21 -0
  9. package/components/TemplatePreview/WechatRichmediaTemplatePreview/tests/index.test.js +10 -0
  10. package/containers/Cap/actions.js +6 -0
  11. package/containers/Cap/constants.js +2 -0
  12. package/containers/Cap/reducer.js +4 -2
  13. package/containers/Cap/selectors.js +13 -0
  14. package/containers/CreativesContainer/SlideBoxContent.js +2 -1
  15. package/containers/Ebill/index.js +4 -21
  16. package/containers/Email/index.js +9 -24
  17. package/containers/Line/Create/index.js +5 -17
  18. package/containers/Line/Edit/index.js +5 -25
  19. package/containers/MobilePush/Create/index.js +5 -22
  20. package/containers/MobilePush/Create/selectors.js +1 -1
  21. package/containers/MobilePush/Edit/index.js +9 -30
  22. package/containers/MobilePush/Edit/selectors.js +2 -2
  23. package/containers/MobilepushWrapper/index.js +3 -2
  24. package/containers/Sms/Create/index.js +17 -31
  25. package/containers/Sms/Edit/index.js +6 -20
  26. package/containers/Templates/index.js +60 -67
  27. package/containers/Templates/reducer.js +3 -3
  28. package/containers/WeChat/MapTemplates/index.js +6 -22
  29. package/containers/WeChat/RichmediaTemplates/Create/_createRichmedia.scss +46 -2
  30. package/containers/WeChat/RichmediaTemplates/Create/actions.js +4 -3
  31. package/containers/WeChat/RichmediaTemplates/Create/constants.js +1 -0
  32. package/containers/WeChat/RichmediaTemplates/Create/index.js +525 -165
  33. package/containers/WeChat/RichmediaTemplates/Create/messages.js +125 -1
  34. package/containers/WeChat/RichmediaTemplates/Create/reducer.js +15 -4
  35. package/containers/WeChat/RichmediaTemplates/Create/richmediaschema.js +497 -0
  36. package/containers/WeChat/RichmediaTemplates/Create/sagas.js +7 -3
  37. package/containers/WeChat/RichmediaTemplates/Create/selectors.js +5 -0
  38. package/containers/WeChat/RichmediaTemplates/Edit/index.js +24 -8
  39. package/containers/WeChat/RichmediaTemplates/Edit/selectors.js +6 -1
  40. package/initialState.js +1 -0
  41. package/package.json +2 -2
  42. package/routes.js +22 -4
@@ -9,19 +9,22 @@ import { connect } from 'react-redux';
9
9
  import Helmet from 'react-helmet';
10
10
  import { bindActionCreators } from 'redux';
11
11
  import { createStructuredSelector } from 'reselect';
12
+ import { injectIntl, intlShape, FormattedMessage } from 'react-intl';
12
13
  import _ from 'lodash';
13
14
  import { Menu, Dropdown } from 'antd';
14
15
  import { CapRow, CapColumn, CapButton, CapCard, CapSpinner } from '@capillarytech/cap-ui-library';
15
- import makeSelectCreate, {makeSelectTemplates, getAssetDetails} from './selectors';
16
+ import makeSelectCreate, {makeSelectTemplates, getAssetDetails, getContentAssetDetails} from './selectors';
16
17
  import * as actions from './actions';
17
- import testschema from './testschema';
18
+ import richmediaschema from './richmediaschema';
18
19
  import './_createRichmedia.scss';
20
+ import messages from './messages';
19
21
  import * as globalActions from '../../../../containers/Cap/actions';
20
22
  import {getMessageObject} from '../../../../utils/messageUtils';
21
23
  import FormBuilder from '../../../../components/FormBuilder';
22
24
  import Header from '../../../../components/Header';
25
+ import WechatRichmediaTemplatePreview from '../../../../components/TemplatePreview/WechatRichmediaTemplatePreview';
23
26
  const MenuItem = Menu.Item;
24
- export class Create extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
27
+ export class Create extends React.Component { // eslint-disable-line react/prefer-stateless-function
25
28
  constructor(props) {
26
29
  super(props);
27
30
  let templateData = {};
@@ -43,7 +46,7 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
43
46
  templateName = props.templateName;
44
47
  }
45
48
  this.state = {
46
- richmediaSchema: testschema,
49
+ richmediaSchema: richmediaschema,
47
50
  map: {
48
51
  "image-value": {
49
52
  onUpload: this.uploadImage,
@@ -61,7 +64,10 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
61
64
  onChange: this.onFormDataChange,
62
65
  },
63
66
  "content-value": {
64
- onChange: this.onFormDataChange,
67
+ getEditorInstanse: this.getEditorInstanse,
68
+ onContentChange: this.onContentChange,
69
+ onFocusOut: this.focusOutFromCkEditor,
70
+ onFocusIn: this.focusInFromCkeditor,
65
71
  },
66
72
  "show-cover-pic-value": {
67
73
  onChange: this.onFormDataChange,
@@ -69,6 +75,9 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
69
75
  "post-comments-value": {
70
76
  onChange: this.onFormDataChange,
71
77
  },
78
+ "content-image-value": {
79
+ onUpload: this.uploadImage,
80
+ },
72
81
  },
73
82
  isEdit,
74
83
  isFormValid: true,
@@ -81,10 +90,12 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
81
90
  isIframe,
82
91
  hovered: false,
83
92
  loading: false,
93
+ showPreview: false,
94
+ focusOut: true,
84
95
  showModal: false,
85
96
  modalContent: {
86
- title: "Alert",
87
- body: "Do you really want to go back? All your temporary changes will be lost!",
97
+ title: this.props.intl.formatMessage(messages.modalTitle),
98
+ body: this.props.intl.formatMessage(messages.modalBody),
88
99
  type: 'confirm',
89
100
  id: 'template-back-confirm-modal',
90
101
  },
@@ -114,6 +125,18 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
114
125
  // this.startLoading = this.startLoading.bind(this);
115
126
  this.moveToTemplates = this.moveToTemplates.bind(this);
116
127
  this.showNext = this.showNext.bind(this);
128
+ this.prepareWeChatRichmediaPreviewData = this.prepareWeChatRichmediaPreviewData.bind(this);
129
+ this.injectMessages = this.injectMessages.bind(this);
130
+ }
131
+ componentWillMount = () => {
132
+ if (_.isEmpty(this.props.Templates.selectedWeChatAccount)) {
133
+ const module = this.props.location.query.module ? this.props.location.query.module : 'default';
134
+ const type = this.props.location.query.type;
135
+ this.props.router.push({
136
+ pathname: `/wechat`,
137
+ query: type === 'embedded' ? {type: 'embedded', module} : {module},
138
+ });
139
+ }
117
140
  }
118
141
  componentDidMount = () => {
119
142
  if (!this.state.isEdit) {
@@ -125,13 +148,20 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
125
148
  }
126
149
  }
127
150
  componentWillReceiveProps = (nextProps) => {
128
- if (nextProps.Create.saveTemplateRes && !_.isEmpty(nextProps.Create.saveTemplateRes) && nextProps.Create.saveTemplateSuccess && !_.isEmpty(nextProps.Create.saveTemplateSuccess)) {
151
+ if (nextProps.Create.saveTemplateRes && !_.isEmpty(nextProps.Create.saveTemplateRes) && nextProps.Create.saveTemplateSuccess && !_.isEqual(nextProps.Create.saveTemplateRes, this.props.Create.saveTemplateRes)) {
152
+ this.setState({loading: false});
153
+ const message = getMessageObject('success', this.props.intl.formatMessage(messages.saveSuccess), true);
154
+ this.props.globalActions.addMessageToQueue(message);
129
155
  const type = nextProps.location.query.type;
130
- this.props.router.push({
156
+ nextProps.router.push({
131
157
  pathname: `/wechat`,
132
158
  query: type === 'embedded' ? {type: 'embedded'} : {},
133
159
  });
134
160
  }
161
+ if (!nextProps.Create.saveTemplateSuccess && nextProps.Create.saveTemplateSuccess !== undefined && nextProps.Create.saveTemplateErrorMessage && nextProps.Create.saveTemplateErrorMessage !== this.props.Create.saveTemplateErrorMessage) {
162
+ this.setState({loading: false});
163
+ this.showErrorMessage(nextProps.Create.saveTemplateErrorMessage);
164
+ }
135
165
  }
136
166
  componentWillUnmount() {
137
167
  if (this.state.isIframe) {
@@ -145,12 +175,26 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
145
175
  this.setState({hovered: data});
146
176
  }
147
177
  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
- }
178
+ const templateData = _.cloneDeep(this.state.templateData);
179
+ templateData[this.state.currentContentId].formData = _.cloneDeep(currentFormData);
180
+ this.setState({templateData});
181
+ }
182
+ onContentChange = (evt) => {
183
+ const templateData = _.cloneDeep(this.state.templateData);
184
+ console.log('oncontentchange onChange ', evt, evt.editor.getData(), templateData);
185
+ templateData[this.state.currentContentId].formData['content-value'] = evt.editor.getData();
186
+ this.setState({templateData});
187
+ }
188
+ getEditorInstanse = (instance, id) => {
189
+ console.log('Got editor Instance ', instance, id);
190
+ window.CKEDITOR.on( 'instanceReady', ( event ) => {
191
+ this.setState({editorInstanse: event.editor});
192
+ event.editor.on( 'focus', () => {
193
+ console.log( 'focused', event.editor, this );
194
+ this.setState({editorInstanse: event.editor});
195
+ });
196
+ });
197
+ //this.setState({editorInstanse: instance});
154
198
  }
155
199
  getMappedEvent = (id, event) => {
156
200
  const map = this.state.map;
@@ -162,6 +206,7 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
162
206
  this.setState({isFormValid});
163
207
  }
164
208
  getCurrentWindow(e) {
209
+ console.log("moveToTemplates richmedia getCurrentWindow");
165
210
  const response = {
166
211
  action: e.action,
167
212
  value: 'edit',
@@ -175,7 +220,7 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
175
220
  mediaList: this.props.templateData.templateDetails.versions.base.mediaList,
176
221
  media_id: this.props.templateData.templateDetails.versions.base.mediaId,
177
222
  definition: {
178
- msgtype: "IMAGE",
223
+ msgtype: "MPNEWS",
179
224
  msgcontent: "RICH_MEDIA_WECHAT",
180
225
  },
181
226
  };
@@ -197,28 +242,54 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
197
242
  console.log("getformdata2 wechat richmedia: ", data);
198
243
  e.source.postMessage(JSON.stringify(response), e.origin);
199
244
  }
245
+ injectMessages(elem) {
246
+ const temp = elem;
247
+ if (temp.value && messages[temp.value]) {
248
+ temp.value = this.props.intl.formatMessage(messages[temp.value]);
249
+ }
250
+ if (temp.label && messages[temp.label]) {
251
+ temp.label = this.props.intl.formatMessage(messages[temp.label]);
252
+ }
253
+ if (temp.errorMessage && messages[temp.errorMessage]) {
254
+ temp.errorMessage = this.props.intl.formatMessage(messages[temp.errorMessage]);
255
+ }
256
+ if (temp.placeholder && messages[temp.placeholder]) {
257
+ temp.placeholder = this.props.intl.formatMessage(messages[temp.placeholder]);
258
+ }
259
+ if (temp.options) {
260
+ _.forEach(temp.options, (option, id) => {
261
+ if (messages[option]) {
262
+ temp.options[id] = this.props.intl.formatMessage(messages[option]);
263
+ }
264
+ });
265
+ }
266
+ return temp;
267
+ }
200
268
  showErrorMessage = (errorMessage) => {
201
269
  const message = getMessageObject('error', errorMessage, true);
202
270
  this.props.globalActions.addMessageToQueue(message);
203
271
  }
204
- checkFormFieldsCount = (currentFormData) => {
272
+ checkFormFieldsCount = () => {
273
+ const templateData = _.cloneDeep(this.state.templateData);
205
274
  let isLimitExceeded = false;
206
- if (_.isEmpty(currentFormData)) {
207
- isLimitExceeded = true;
275
+ _.forEach(templateData, (content) => {
276
+ if (_.isEmpty(content)) {
277
+ isLimitExceeded = true;
278
+ }
279
+ if (content.formData['title-value'].length > 64) {
280
+ this.showErrorMessage(`${this.props.intl.formatMessage(messages.titleCharacterCount)} ${content.formData['title-value'].length - 64} characters`);
281
+ isLimitExceeded = true;
282
+ }
283
+ if (content.formData['author-value'].length > 8) {
284
+ this.showErrorMessage(`${this.props.intl.formatMessage(messages.authorCharacterCount)} ${content.formData['author-value'].length - 8} characters`);
285
+ isLimitExceeded = true;
286
+ }
287
+ if (content.formData['cover-abstract-value'].length > 120) {
288
+ this.showErrorMessage(`${this.props.intl.formatMessage(messages.coverAbstractCharacterCount)} ${content.formData['cover-abstract-value'].length - 120} characters`);
289
+ isLimitExceeded = true;
290
+ }
208
291
  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
- }
292
+ });
222
293
  return isLimitExceeded;
223
294
  }
224
295
  // startLoading(ifEdit) {
@@ -227,9 +298,10 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
227
298
  // }
228
299
  // }
229
300
  moveToTemplates() {
301
+ console.log("moveToTemplates richmedia");
230
302
  const modalContent = {
231
- title: "Alert",
232
- body: "Do you really want to go back? All your temporary changes will be lost!",
303
+ title: this.props.intl.formatMessage(messages.modalTitle),
304
+ body: this.props.intl.formatMessage(messages.modalBody),
233
305
  type: 'confirm',
234
306
  id: 'template-back-confirm-modal',
235
307
  show: true,
@@ -240,6 +312,7 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
240
312
  this.setState({showModal: false});
241
313
  }
242
314
  showNext() {
315
+ console.log("richmedia shownext");
243
316
  const response = {
244
317
  action: "showNext",
245
318
  value: true,
@@ -247,6 +320,7 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
247
320
  parent.postMessage(JSON.stringify(response), '*');
248
321
  }
249
322
  handleFrameTasks = (e) => {
323
+ console.log("richmedia handleFrameTasks: ", e.data);
250
324
  const type = e.data;
251
325
  if (typeof type === 'object') {
252
326
  const action = type.action;
@@ -266,6 +340,7 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
266
340
  this.getFormData(e);
267
341
  break;
268
342
  case "moveToTemplates":
343
+ console.log("moveToTemplates richmedia case");
269
344
  this.moveToTemplates();
270
345
  break;
271
346
  default:
@@ -317,19 +392,21 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
317
392
  }
318
393
  injectColLabelSection = (section) => {
319
394
  _.forEach(section.inputFields, (inputField) => {
320
- const temp = inputField;
395
+ let temp = inputField;
321
396
  temp.injectedEvents = {};
322
397
  _.forEach(inputField.supportedEvents, (event) => {
323
398
  temp.injectedEvents[event] = this.getMappedEvent(inputField.id, event);
324
399
  });
400
+ temp = this.injectMessages(temp);
325
401
  return true;
326
402
  });
327
403
  _.forEach(section.actionFields, (actionField) => {
328
- const temp = actionField;
404
+ let temp = actionField;
329
405
  temp.injectedEvents = {};
330
406
  _.forEach(actionField.supportedEvents, (event) => {
331
407
  temp.injectedEvents[event] = this.getMappedEvent(actionField.id, event);
332
408
  });
409
+ temp = this.injectMessages(temp);
333
410
  return true;
334
411
  });
335
412
  return section;
@@ -337,21 +414,23 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
337
414
  injectMultiColSection = (section) => {
338
415
  _.forEach(section.inputFields, (inputField) => {
339
416
  _.forEach(inputField.cols, (col) => {
340
- const temp = col;
417
+ let temp = col;
341
418
  temp.injectedEvents = {};
342
419
  _.forEach(col.supportedEvents, (event) => {
343
420
  temp.injectedEvents[event] = this.getMappedEvent(col.id, event);
344
421
  });
422
+ temp = this.injectMessages(temp);
345
423
  return true;
346
424
  });
347
425
  });
348
426
  _.forEach(section.actionFields, (actionField) => {
349
427
  _.forEach(actionField.cols, (col) => {
350
- const temp = col;
428
+ let temp = col;
351
429
  temp.injectedEvents = {};
352
430
  _.forEach(col.supportedEvents, (event) => {
353
431
  temp.injectedEvents[event] = this.getMappedEvent(col.id, event);
354
432
  });
433
+ temp = this.injectMessages(temp);
355
434
  return true;
356
435
  });
357
436
  });
@@ -368,31 +447,97 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
368
447
  query: type === 'embedded' ? {type: 'embedded'} : {},
369
448
  });
370
449
  }
450
+ closeSlideBox = () => {
451
+ this.setState({showPreview: false});
452
+ }
453
+ deducePostCommentsData = (data) => {
454
+ let postCommentsData = {};
455
+ if (data && data.toLowerCase() === 'anyone') {
456
+ postCommentsData = {
457
+ need_open_comment: 1,
458
+ only_fans_can_comment: 0,
459
+ };
460
+ } else if (data && data.toLowerCase() === 'only followers') {
461
+ postCommentsData = {
462
+ need_open_comment: 1,
463
+ only_fans_can_comment: 1,
464
+ };
465
+ } else {
466
+ postCommentsData = {
467
+ need_open_comment: 0,
468
+ only_fans_can_comment: 0,
469
+ };
470
+ }
471
+ return postCommentsData;
472
+ }
473
+ prepareMediaList = () => {
474
+ const templateData = _.cloneDeep(this.state.templateData);
475
+ const mediaList = [];
476
+ _.forEach(templateData, (contentData) => {
477
+ const postCommentsData = this.deducePostCommentsData(contentData.formData['post-comments-value']);
478
+ const filteredContent = {
479
+ title: contentData.formData['title-value'],
480
+ author: contentData.formData['author-value'] ? contentData.formData['author-value'] : '',
481
+ digest: contentData.formData['cover-abstract-value'] ? contentData.formData['cover-abstract-value'] : '',
482
+ content: contentData.formData['content-value'],
483
+ content_source_url: contentData.formData['source-link-value'],
484
+ show_cover_pic: contentData.formData['show-cover-pic-value'] === true ? 1 : 0,
485
+ need_open_comment: postCommentsData.need_open_comment,
486
+ only_fans_can_comment: postCommentsData.only_fans_can_comment,
487
+ thumb_media_id: contentData.mediaId,
488
+ image_url: contentData.imageUrl,
489
+ };
490
+ mediaList.push(filteredContent);
491
+ });
492
+ return mediaList;
493
+ }
494
+ prepareWeChatRichmediaPreviewData = () => {
495
+ const templateData = _.cloneDeep(this.state.templateData);
496
+ const returnObj = [];
497
+ _.forEach(templateData, (contentData, contentIndex) => {
498
+ const id = parseInt(contentIndex, 10);
499
+ if (id === 0) {
500
+ returnObj.push(
501
+ <div style={{ width: "100%", height: 116, position: "relative" }}>
502
+ <CapRow>
503
+ <img alt="default" width="100%" height="110px" src={contentData.imageUrl} />
504
+ <div style={{ position: "absolute", bottom: "5%", left: "5%" }}>{contentData.formData['title-value'] ? contentData.formData['title-value'] : ""}</div>
505
+ </CapRow>
506
+ {Object.keys(templateData).length === 1 ?
507
+ <CapRow style={{ height: 32 }}>
508
+ {contentData.formData['cover-abstract-value'] ? contentData.formData['cover-abstract-value'] : ""}
509
+ </CapRow>
510
+ :
511
+ ""
512
+ }
513
+ </div>
514
+ );
515
+ } else {
516
+ returnObj.push(
517
+ <CapRow style={{ "width": "100%", "height": 64, "border-bottom": "0.5px solid lightgrey" }}>
518
+ <CapColumn style={{ padding: "5% 0% 0% 5%", float: "left" }}>
519
+ {contentData.formData['title-value']}
520
+ </CapColumn>
521
+ <CapColumn style={{ float: "right" }}>
522
+ <img alt="default" width="60px" height="60px" src={contentData.imageUrl} style={{ "padding-right": "10%", "float": "left" }}/>
523
+ </CapColumn>
524
+ </CapRow>
525
+ );
526
+ }
527
+ });
528
+ return returnObj;
529
+ }
371
530
  previewHandler = () => {
531
+ this.setState({showPreview: true});
372
532
  }
373
533
  saveHandler = () => {
374
534
  let isFormValid = this.validateFormFields();
375
535
  if (_.isEmpty(this.state.templateName)) {
376
- this.showErrorMessage("Cannot leave template name empty");
536
+ this.showErrorMessage(this.props.intl.formatMessage(messages.emptyTemplateName));
377
537
  isFormValid = false;
378
538
  }
379
539
  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
- });
540
+ const mediaList = this.prepareMediaList();
396
541
  const saveObj = {};
397
542
  saveObj.name = this.state.templateName.trim();
398
543
  saveObj.appId = this.props.Templates.selectedWeChatAccount.configs.wechat_app_id;
@@ -405,7 +550,7 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
405
550
  history: [],
406
551
  };
407
552
  saveObj.definition = {
408
- msgtype: "IMAGE",
553
+ msgtype: "MPNEWS",
409
554
  msgcontent: "RICH_MEDIA_WECHAT",
410
555
  };
411
556
  if (this.state.isEdit) {
@@ -413,32 +558,29 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
413
558
  saveObj.mediaId = this.props.mediaId;
414
559
  saveObj.type = "WECHAT";
415
560
  }
561
+ this.setState({loading: true});
416
562
  this.props.actions.saveTemplate(saveObj);
417
563
  }
418
564
  }
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);
565
+ uploadImage = (data, uploadId) => {
566
+ if (data.type === "wrong file") {
567
+ this.showErrorMessage(this.props.intl.formatMessage(messages.wrongFormatFile));
423
568
  } else {
424
569
  const wechatParams = {
425
570
  appId: this.props.Templates.selectedWeChatAccount.configs.wechat_app_id,
426
571
  appSecret: this.props.Templates.selectedWeChatAccount.configs.wechat_app_secret,
427
572
  source: 'wechat',
428
573
  };
429
- this.props.actions.uploadAsset(data.file, data.type, data.fileParams, null, wechatParams, this.state.currentContentId);
574
+ this.setState({loading: true});
575
+ this.props.actions.uploadAsset(data.file, data.type, data.fileParams, null, wechatParams, this.state.currentContentId, uploadId);
430
576
  }
431
577
  }
432
578
  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
- }
579
+ this.setState({
580
+ totalContentBlocks: this.state.totalContentBlocks + 1,
581
+ }, () => {
582
+ this.insertTemplateData();
583
+ });
442
584
  }
443
585
  insertTemplateData = () => {
444
586
  const templateData = _.cloneDeep(this.state.templateData);
@@ -454,81 +596,256 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
454
596
  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
597
  templateData[this.state.currentContentId].imageUrl = this.props.ImageData[this.state.currentContentId].metaInfo.secure_file_path;
456
598
  templateData[this.state.currentContentId].mediaId = this.props.ImageData[this.state.currentContentId].metaInfo.mediaId;
457
- this.setState({templateData});
599
+ this.setState({templateData, loading: false});
458
600
  }
459
601
  }
460
- updateTemplateData = (e, id) => {
461
- //e.stopPropagation();
602
+ viewContent = (e, id) => {
462
603
  this.setState({currentContentId: id});
463
604
  }
605
+ deleteContent = (e, id) => {
606
+ const templateData = _.cloneDeep(this.state.templateData);
607
+ let totalContentBlocks = this.state.totalContentBlocks;
608
+ let currentContentId = this.state.currentContentId;
609
+ let index = 0;
610
+ for (index = id; index <= (totalContentBlocks - 2); index += 1) {
611
+ templateData[index] = templateData[index + 1];
612
+ }
613
+ delete templateData[index];
614
+ currentContentId = (totalContentBlocks - 1) === id ? id - 1 : id;
615
+ totalContentBlocks -= 1;
616
+ this.setState({templateData, totalContentBlocks, currentContentId});
617
+ }
618
+ moveContentDownward = (e, id) => {
619
+ const templateData = _.cloneDeep(this.state.templateData);
620
+ let currentContentId = this.state.currentContentId;
621
+ const temp = templateData[id];
622
+ templateData[id] = templateData[id + 1];
623
+ templateData[id + 1] = temp;
624
+ currentContentId = id + 1;
625
+ this.setState({templateData, currentContentId});
626
+ }
627
+ moveContentUpward = (e, id) => {
628
+ const templateData = _.cloneDeep(this.state.templateData);
629
+ let currentContentId = this.state.currentContentId;
630
+ const temp = templateData[id];
631
+ templateData[id] = templateData[id - 1];
632
+ templateData[id - 1] = temp;
633
+ currentContentId = id - 1;
634
+ this.setState({templateData, currentContentId});
635
+ }
464
636
  returnCardLayout = () => {
465
637
  const templateData = _.cloneDeep(this.state.templateData);
466
638
  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>
639
+ if (this.state.isIframe) {
640
+ _.forEach(templateData, (contentData, contentId) => {
641
+ const id = parseInt(contentId, 10);
642
+ const imageUrl = contentData.imageUrl;
643
+ if (id === 0) {
644
+ returnObj[id] = (
645
+ <div className="hover-container">
646
+ <CapCard
647
+ id={id}
648
+ style={{ width: 244, height: 221 }}
649
+ bodyStyle={{ "padding": 0, "background-color": "#707070", "height": 139 }}
650
+ onClick={(e) => this.viewContent(e, id)}
651
+ className={id === this.state.currentContentId ? "richmedia-card richmedia-card-clicked" : "richmedia-card"}
652
+ >
653
+ <div>
654
+ <div className="custom-image">
655
+ <img alt="" width="100%" height="139px" src={imageUrl} />
656
+ </div>
657
+ <div className="custom-card overflow-wrap-fields">
658
+ <p style={{ padding: "0px 8px" }}>{contentData && contentData.formData ? contentData.formData['cover-abstract-value'] : ""}</p>
659
+ </div>
660
+ </div>
661
+ </CapCard>
662
+ </div>
663
+ );
664
+ } else {
665
+ returnObj[id] = (
666
+ <div
667
+ id={id}
668
+ style={{ "margin-top": 10 }}
669
+ className="hover-container"
670
+ onClick={(e) => this.viewContent(e, id)}
671
+ >
672
+ <CapRow style={{ width: 244, height: 53 }} className={id === this.state.currentContentId ? "richmedia-card-rectangle richmedia-card-rectangle-clicked" : "richmedia-card-rectangle"}>
673
+ <CapColumn span={19} style={{ padding: "10px 8px 0px 8px" }} className="overflow-wrap-fields" >
674
+ {contentData && contentData.formData ? contentData.formData['title-value'] : ""}
675
+ </CapColumn>
676
+ <CapColumn span={5} style={{ "height": "100%", "background-color": "#707070" }}>
677
+ <img alt="" width="50px" height="100%" src={imageUrl} />
678
+ </CapColumn>
679
+ </CapRow>
680
+ </div>
681
+ );
682
+ }
683
+ });
684
+ } else {
685
+ _.forEach(templateData, (contentData, contentId) => {
686
+ const id = parseInt(contentId, 10);
687
+ const imageUrl = contentData.imageUrl;
688
+ if (id === 0) {
689
+ returnObj[id] = (
690
+ <div className="hover-container">
691
+ <CapCard
692
+ id={id}
693
+ style={{ width: 244, height: 221 }}
694
+ bodyStyle={{ "padding": 0, "background-color": "#707070", "height": 139 }}
695
+ className={id === this.state.currentContentId ? "richmedia-card richmedia-card-clicked" : "richmedia-card"}
696
+ >
697
+ <div>
698
+ <div className="custom-image">
699
+ <img alt="" width="100%" height="139px" src={imageUrl} />
700
+ </div>
701
+ <div className="custom-card overflow-wrap-fields">
702
+ <p style={{ padding: "0px 8px" }}>{contentData && contentData.formData ? contentData.formData['cover-abstract-value'] : ""}</p>
703
+ </div>
704
+ </div>
705
+ </CapCard>
706
+
707
+ {this.state.totalContentBlocks !== 1 ?
708
+ <div className="richmedia-icons">
709
+ <div id={id} onClick={(e) => this.moveContentDownward(e, id)}>
710
+ <i className="material-icons hover-icons">arrow_downward</i>
711
+ </div>
712
+ <div id={id} onClick={(e) => this.viewContent(e, id)} style={{ 'padding-left': '190px' }}>
713
+ <i className="material-icons hover-icons">visibility</i>
714
+ </div>
715
+ </div>
716
+ :
717
+ <div className="richmedia-icons">
718
+ <div id={id} onClick={(e) => this.viewContent(e, id)} style={{ 'padding-left': '214px' }}>
719
+ <i className="material-icons hover-icons">visibility</i>
720
+ </div>
721
+ </div>
722
+ }
723
+ </div>
724
+ );
725
+ } else {
726
+ returnObj[id] = (
727
+ <div
728
+ id={id}
729
+ style={{ "margin-top": 10 }}
730
+ className="hover-container"
731
+ >
732
+ <CapRow style={{ width: 244, height: 53 }} className={id === this.state.currentContentId ? "richmedia-card-rectangle richmedia-card-rectangle-clicked" : "richmedia-card-rectangle"}>
733
+ <CapColumn span={19} style={{ padding: "10px 8px 0px 8px" }} className="overflow-wrap-fields" >
734
+ {contentData && contentData.formData ? contentData.formData['title-value'] : ""}
735
+ </CapColumn>
736
+ <CapColumn span={5} style={{ "height": "100%", "background-color": "#707070" }}>
737
+ <img alt="" width="50px" height="100%" src={imageUrl} />
738
+ </CapColumn>
739
+ </CapRow>
740
+ <div className="richmedia-icons">
741
+ <div style={{display: 'inline-flex'}}>
742
+ <div id={id} onClick={(e) => this.moveContentUpward(e, id)}>
743
+ <i className="material-icons hover-icons">arrow_upward</i>
744
+ </div>
745
+ {id !== (this.state.totalContentBlocks - 1 ) ?
746
+ <div id={id} onClick={(e) => this.moveContentDownward(e, id)}>
747
+ <i className="material-icons hover-icons">arrow_downward</i>
748
+ </div>
749
+ :
750
+ ""
751
+ }
752
+ </div>
753
+ {id !== (this.state.totalContentBlocks - 1 ) ?
754
+ <div style={{'display': 'inline-flex', 'padding-left': '142px'}}>
755
+ <div id={id} onClick={(e) => this.viewContent(e, id)}>
756
+ <i className="material-icons hover-icons">visibility</i>
757
+ </div>
758
+ <div id={id} onClick={(e) => this.deleteContent(e, id)} >
759
+ <i className="material-icons hover-icons">delete</i>
760
+ </div>
761
+ </div>
762
+ :
763
+ <div style={{'display': 'inline-flex', 'padding-left': '166px'}}>
764
+ <div id={id} onClick={(e) => this.viewContent(e, id)}>
765
+ <i className="material-icons hover-icons">visibility</i>
766
+ </div>
767
+ <div id={id} onClick={(e) => this.deleteContent(e, id)} >
768
+ <i className="material-icons hover-icons">delete</i>
769
+ </div>
770
+ </div>
771
+ }
487
772
  </div>
488
773
  </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
- });
774
+ );
775
+ }
776
+ });
777
+ }
506
778
  return (
507
779
  <div>{returnObj}</div>
508
780
  );
509
781
  }
782
+ isTitleRepeated = () => {
783
+ const templateData = _.cloneDeep(this.state.templateData);
784
+ const titleSet = new Set();
785
+ let isRepeated = false;
786
+ _.forEach(templateData, (content) => {
787
+ const setSizeBefore = titleSet.size;
788
+ titleSet.add(content.formData['title-value'].toLowerCase());
789
+ const setSizeAfter = titleSet.size;
790
+ if (setSizeAfter === setSizeBefore) {
791
+ isRepeated = true;
792
+ }
793
+ });
794
+ return isRepeated;
795
+ }
796
+ isFormEmpty = () => {
797
+ const templateData = _.cloneDeep(this.state.templateData);
798
+ let isEmpty = false;
799
+ _.forEach(templateData, (content) => {
800
+ if (_.isEmpty(content.formData)) {
801
+ isEmpty = true;
802
+ }
803
+ });
804
+ return isEmpty;
805
+ }
510
806
  validateFormFields = () => {
511
807
  let isValid = true;
512
808
  const currentContent = this.state.templateData[this.state.currentContentId];
513
- if (_.isEmpty(currentContent.formData)) {
514
- this.showErrorMessage("Cannot leave form empty");
809
+ if (this.isFormEmpty()) {
810
+ this.showErrorMessage(this.props.intl.formatMessage(messages.formEmpty));
515
811
  isValid = false;
812
+ return isValid;
516
813
  }
517
814
  if (_.isEmpty(currentContent.formData['title-value'])) {
518
- this.showErrorMessage("Cannot leave title field empty");
815
+ this.showErrorMessage(this.props.intl.formatMessage(messages.titleEmpty));
519
816
  isValid = false;
817
+ return isValid;
818
+ }
819
+ if (_.isEmpty(currentContent.imageUrl) || _.isEmpty(currentContent.mediaId)) {
820
+ this.showErrorMessage(this.props.intl.formatMessage(messages.noImage));
821
+ isValid = false;
822
+ return isValid;
520
823
  }
521
824
  if (_.isEmpty(currentContent.formData['source-link-value'])) {
522
- this.showErrorMessage("Cannot leave source link field empty");
825
+ this.showErrorMessage(this.props.intl.formatMessage(messages.sourceLinkEmpty));
523
826
  isValid = false;
827
+ return isValid;
524
828
  }
525
829
  if (_.isEmpty(currentContent.formData['content-value'])) {
526
- this.showErrorMessage("Cannot leave content field empty");
830
+ this.showErrorMessage(this.props.intl.formatMessage(messages.contentEmpty));
527
831
  isValid = false;
832
+ return isValid;
528
833
  }
529
- if (_.isEmpty(currentContent.imageUrl) || _.isEmpty(currentContent.mediaId)) {
530
- this.showErrorMessage("Please upload an image");
834
+ if (this.checkFormFieldsCount(currentContent.formData)) {
531
835
  isValid = false;
836
+ return isValid;
837
+ }
838
+ if (this.isTitleRepeated()) {
839
+ this.showErrorMessage(this.props.intl.formatMessage(messages.titleNameRepeated));
840
+ isValid = false;
841
+ return isValid;
842
+ }
843
+ if (!_.isEmpty(currentContent.formData['source-link-value'])) {
844
+ isValid = currentContent.formData['source-link-value'].match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_+.~#?&//=]*)/g);
845
+ if (!isValid) {
846
+ this.showErrorMessage(this.props.intl.formatMessage(messages.wrongUrl));
847
+ return isValid;
848
+ }
532
849
  }
533
850
  return isValid;
534
851
  }
@@ -539,11 +856,15 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
539
856
  }
540
857
  switch (ev.key) {
541
858
  case "new_richmedia_content":
542
- this.setState({
543
- currentContentId: this.state.currentContentId + 1,
544
- }, () => {
545
- this.updateTotalContentBlocks();
546
- });
859
+ if (this.state.totalContentBlocks < 8) {
860
+ this.setState({
861
+ currentContentId: this.state.totalContentBlocks,
862
+ }, () => {
863
+ this.updateTotalContentBlocks();
864
+ });
865
+ } else {
866
+ this.showErrorMessage(this.props.intl.formatMessage(messages.maxContentCount));
867
+ }
547
868
  break;
548
869
  case "old_richmedia_content":
549
870
  this.setState({
@@ -554,13 +875,18 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
554
875
  break;
555
876
  default:
556
877
  this.setState({
557
- currentContentId: this.state.currentContentId + 1,
878
+ currentContentId: this.state.totalContentBlocks + 1,
558
879
  }, () => {
559
880
  this.updateTotalContentBlocks();
560
881
  });
561
882
  }
562
883
  return true;
563
884
  }
885
+ updateContentData = () => {
886
+ this.state.editorInstanse.insertHtml(`<img src='${this.props.ContentImageData.metaInfo.wechatUrl}' alt='Capillary Image'>`);
887
+ this.props.actions.clearContentImageStore();
888
+ this.setState({loading: false});
889
+ }
564
890
  returnContentMenu = () => {
565
891
  let actionButton = '';
566
892
  const createPushMenu = (
@@ -569,7 +895,7 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
569
895
  Add existing Richmedia content
570
896
  </MenuItem> */}
571
897
  <MenuItem key="new_richmedia_content">
572
- Add Richmedia content
898
+ <FormattedMessage {...messages.addNewRichmedia} />
573
899
  </MenuItem>
574
900
  </Menu>
575
901
  );
@@ -584,22 +910,36 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
584
910
  </Dropdown>);
585
911
  return actionButton;
586
912
  }
913
+ focusOutFromCkEditor = () => {
914
+ this.setState({focusOut: true});
915
+ }
916
+ focusInFromCkeditor = () => {
917
+ this.setState({focusOut: false});
918
+ }
587
919
  returnCurrentSchema = () => {
588
- let schema = {};
920
+ let schema = _.cloneDeep(this.state.richmediaSchema);
589
921
  if (this.state.isIframe) {
590
922
  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;
923
+ disabledFormSchema.standalone.sections[0].childSections[0].inputFields[0].cols[1].disabled = true;
924
+ disabledFormSchema.standalone.sections[0].childSections[0].inputFields[1].cols[1].disabled = true;
925
+ disabledFormSchema.standalone.sections[0].childSections[0].inputFields[2].cols[1].disabled = true;
926
+ disabledFormSchema.standalone.sections[0].childSections[0].inputFields[3].cols[1].disabled = true;
927
+ disabledFormSchema.standalone.sections[0].childSections[0].inputFields[4].cols[0].disabled = true;
928
+ disabledFormSchema.standalone.sections[0].childSections[0].inputFields[5].cols[1].disabled = true;
929
+ disabledFormSchema.standalone.sections[0].childSections[2].inputFields[0].cols[1].disabled = true;
930
+ disabledFormSchema.standalone.sections[0].childSections[1].childSections[1].childSections[0].inputFields[0].cols[1].disabled = true;
931
+ if (this.state.editorInstanse) {
932
+ this.state.editorInstanse.setReadOnly(true);
933
+ }
599
934
  schema = this.injectEvents(disabledFormSchema);
600
935
  return schema;
601
936
  }
602
- schema = this.injectEvents(this.state.richmediaSchema);
937
+ if (this.state.editorInstanse && this.state.focusOut) {
938
+ schema.standalone.sections[0].childSections[1].childSections[1].childSections[0].inputFields[0].cols[1].disabled = true;
939
+ } else if (this.state.editorInstanse && !this.state.focusOut) {
940
+ schema.standalone.sections[0].childSections[1].childSections[1].childSections[0].inputFields[0].cols[1].disabled = false;
941
+ }
942
+ schema = this.injectEvents(schema);
603
943
  return schema;
604
944
  }
605
945
  returnCurrentFormData = () => {
@@ -612,38 +952,54 @@ export class Create extends React.PureComponent { // eslint-disable-line react/p
612
952
  const schema = this.returnCurrentSchema();
613
953
  const formData = this.returnCurrentFormData();
614
954
  this.updateImageData();
955
+ if (this.props.ContentImageData && this.props.ContentImageData.metaInfo && this.props.ContentImageData.metaInfo.wechatUrl) {
956
+ this.updateContentData();
957
+ }
615
958
  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>
959
+ <div className="richmedia-container">
960
+ <CapSpinner spinning={this.state.loading}>
961
+ {this.state.showPreview && <WechatRichmediaTemplatePreview
962
+ show={this.state.showPreview}
963
+ closeSlideBox={this.closeSlideBox}
964
+ header={this.state.templateName}
965
+ width={50}
966
+ showSlidebox
967
+ const type={this.props.location && this.props.location.query.type ? this.props.location.query.type : ''}
968
+ content={this.prepareMediaList()}
969
+ />}
970
+ <div>
971
+ <Helmet
972
+ title="Wechat Richmedia"
973
+ />
974
+ <div className="wechat-container">
975
+ {!this.state.isIframe && <Header templateName={this.state.templateName} templateNameHandler={this.templateNameHandler} previewHandler={this.previewHandler} cancelHandler={this.cancelHandler} saveHandler={this.saveHandler} />}
976
+ <CapRow className="wechat-form-container">
977
+ <CapColumn span={6}>
978
+ {cardLayout}
979
+ {!this.state.isIframe && contentMenu}
980
+ </CapColumn>
981
+ <CapColumn span={18}>
982
+ <FormBuilder
983
+ key={this.state.currentContentId}
984
+ schema={schema}
985
+ onChange={this.onFormDataChange}
986
+ parent={this}
987
+ formData={formData}
988
+ onFormValidityChange={this.setFormValidity}
989
+ location={this.props.location}
990
+ usingTabContainer={false}
991
+ router={this.props.router}
992
+ modal={this.state.modalContent}
993
+ showModal={this.state.showModal}
994
+ handleCancelModal={this.handleCancelModal}
995
+ iframeParent={parent}
996
+ />
997
+ </CapColumn>
998
+ </CapRow>
999
+ </div>
644
1000
  </div>
645
- </div>
646
- </CapSpinner>
1001
+ </CapSpinner>
1002
+ </div>
647
1003
  );
648
1004
  }
649
1005
  }
@@ -661,12 +1017,16 @@ Create.propTypes = {
661
1017
  ImageData: PropTypes.object,
662
1018
  actions: PropTypes.object,
663
1019
  globalActions: PropTypes.object,
1020
+ Create: PropTypes.object,
1021
+ intl: intlShape.isRequired,
1022
+ ContentImageData: PropTypes.object,
664
1023
  };
665
1024
 
666
1025
  const mapStateToProps = createStructuredSelector({
667
1026
  Create: makeSelectCreate(),
668
1027
  Templates: makeSelectTemplates(),
669
1028
  ImageData: getAssetDetails(),
1029
+ ContentImageData: getContentAssetDetails(),
670
1030
  });
671
1031
 
672
1032
  function mapDispatchToProps(dispatch) {
@@ -676,4 +1036,4 @@ function mapDispatchToProps(dispatch) {
676
1036
  };
677
1037
  }
678
1038
 
679
- export default connect(mapStateToProps, mapDispatchToProps)(Create);
1039
+ export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(Create));