@capillarytech/creatives-library 0.1.26 → 0.1.28

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 (34) hide show
  1. package/components/CardGrid/index.js +1 -1
  2. package/components/FormBuilder/index.js +72 -0
  3. package/components/PreviewSideBar/index.js +10 -1
  4. package/components/TemplatePreview/index.js +16 -1
  5. package/containers/Cap/index.js +5 -1
  6. package/containers/Email/index.js +12 -2
  7. package/containers/Email/reducer.js +1 -1
  8. package/containers/Line/Create/_lineCreate.scss +37 -0
  9. package/containers/Line/Create/actions.js +90 -0
  10. package/containers/Line/Create/constants.js +39 -0
  11. package/containers/Line/Create/index.js +810 -0
  12. package/containers/Line/Create/messages.js +173 -0
  13. package/containers/Line/Create/reducer.js +99 -0
  14. package/containers/Line/Create/sagas.js +108 -0
  15. package/containers/Line/Create/selectors.js +36 -0
  16. package/containers/Line/Edit/_lineEdit.scss +25 -0
  17. package/containers/Line/Edit/actions.js +72 -0
  18. package/containers/Line/Edit/constants.js +27 -0
  19. package/containers/Line/Edit/index.js +1043 -0
  20. package/containers/Line/Edit/messages.js +157 -0
  21. package/containers/Line/Edit/reducer.js +83 -0
  22. package/containers/Line/Edit/sagas.js +81 -0
  23. package/containers/Line/Edit/selectors.js +29 -0
  24. package/containers/Line/Edit/tests/actions.test.js +18 -0
  25. package/containers/Line/Edit/tests/index.test.js +10 -0
  26. package/containers/Line/Edit/tests/reducer.test.js +9 -0
  27. package/containers/Line/Edit/tests/sagas.test.js +15 -0
  28. package/containers/Line/Edit/tests/selectors.test.js +10 -0
  29. package/containers/MobilePush/Create/index.js +0 -1
  30. package/containers/Templates/index.js +105 -22
  31. package/containers/Templates/messages.js +4 -0
  32. package/package.json +1 -1
  33. package/routes.js +110 -0
  34. package/services/api.js +8 -0
@@ -0,0 +1,1043 @@
1
+
2
+ /*
3
+ *
4
+ * Create
5
+ *
6
+ */
7
+
8
+ import React, { PropTypes } from 'react';
9
+ import {bindActionCreators} from "redux";
10
+ import { connect } from 'react-redux';
11
+ import { Row, Col, Spin, Breadcrumb, notification } from 'antd';
12
+ import { createStructuredSelector } from 'reselect';
13
+ import { injectIntl, intlShape } from 'react-intl';
14
+ import _ from 'lodash';
15
+ import {makeSelectEdit, makeSelectEditResponse, makeSelectTemplateDetailsResponse} from "../../MobilePush/Edit/selectors";
16
+ import {makeSelectMetaEntities} from "../../Cap/selectors";
17
+ import {getMessageObject} from "../../../utils/messageUtils";
18
+ import FormBuilder from '../../../components/FormBuilder';
19
+ import * as globalActions from "../../Cap/actions";
20
+ import * as actions from "../../MobilePush/Edit/actions";
21
+ import * as templatesActions from "../../Templates/actions";
22
+ import {makeSelectTemplates} from "../../Templates/selectors";
23
+ import messages from './messages';
24
+ import './_lineEdit.scss';
25
+ import {makeSelectCreate} from "../Create/selectors";
26
+ const BreadcrumbItem = Breadcrumb.Item;
27
+
28
+ export class Edit extends React.Component { // eslint-disable-line react/prefer-stateless-function
29
+ constructor(props) {
30
+ super(props);
31
+ const map = {
32
+ "template-name": {
33
+ "onChange": this.onTemplateNameChange,
34
+ },
35
+ "discard-button": {
36
+ "discardValues": this.discardValues,
37
+ },
38
+ "cancel-button": {
39
+ "cancelTemplate": this.cancelTemplate,
40
+ },
41
+ "save-button": {
42
+ saveFormData: this.saveFormData,
43
+ },
44
+ "message-editor": {
45
+ "onChange": this.onTemplateContentChange,
46
+ },
47
+ "message-editor2": {
48
+ "onChange": this.onTemplateContentChange,
49
+ },
50
+ "message-tagList": {
51
+ "onTagSelect": this.onTagSelect,
52
+ },
53
+ "message-tagList2": {
54
+ "onTagSelect": this.onTagSelect,
55
+ },
56
+ "title-tagList": {
57
+ "onTagSelect": this.onTagSelect,
58
+ },
59
+ "title-tagList2": {
60
+ "onTagSelect": this.onTagSelect,
61
+ },
62
+ "pane": {
63
+ onTabChange: this.onTabChange,
64
+ },
65
+ "image-upload": {
66
+ "onUpload": this.uploadImage,
67
+ },
68
+ "line-template": {
69
+ "onSelect": this.onTemplateChange,
70
+ },
71
+ };
72
+ this.state = {
73
+ formData: {},
74
+ tabCount: 1,
75
+ schema: {},
76
+ currentTab: 1,
77
+ editData: {},
78
+ loading: false,
79
+ isFormValid: true,
80
+ injectedTags: {},
81
+ showModal: false,
82
+ eventsMap: map,
83
+ modalContent: {title: "Alert", body: this.props.intl.formatMessage(messages['template not configured,']), type: 'confirm'},
84
+ };
85
+ }
86
+ componentWillMount() {
87
+ console.log('edit mounting line');
88
+ if (this.props.location.query.type !== 'embedded') {
89
+ const type = this.props.location.query.type;
90
+ const module = this.props.location.query.module ? this.props.location.query.module : 'default';
91
+ this.props.router.push({
92
+ pathname: `/line/`,
93
+ query: type === 'embedded' ? {type: 'embedded', module} : {module},
94
+ });
95
+ } else {
96
+ const query = {
97
+ layout: 'LINE',
98
+ type: 'LAYOUT',
99
+ };
100
+ this.props.globalActions.fetchSchemaForEntity(query);
101
+ }
102
+ }
103
+
104
+ componentDidMount() {
105
+ window.addEventListener("message", this.handleFrameTasks);
106
+ const type = this.props.location.query.type;
107
+ if (type === 'embedded') {
108
+ const response = {
109
+ action: 'startTemplateCreation',
110
+ };
111
+ parent.postMessage(JSON.stringify(response), '*');
112
+ }
113
+ if (!_.isEmpty(this.state.schema)) {
114
+ this.injectEvents(this.state.schema);
115
+ }
116
+ }
117
+
118
+ componentWillReceiveProps(nextProps) {
119
+ const params = {
120
+ name: '',
121
+ sortBy: 'Most Recent',
122
+ };
123
+ this.props.actions.getLineTemplatesList('line', params);
124
+
125
+ if (nextProps.metaEntities && nextProps.metaEntities.layouts && nextProps.metaEntities.layouts.length > 0 && _.isEmpty(this.state.fullSchema)) {
126
+ this.setState({fullSchema: nextProps.metaEntities.layouts[0].definition, schema: nextProps.location.query.module === 'loyalty' ? nextProps.metaEntities.layouts[0].definition.textSchema : {}}, () => {
127
+ if (nextProps.location.query.module !== 'loyalty') {
128
+ this.props.actions.getTemplateDetails(this.props.params.id);
129
+ }
130
+ });
131
+ if (this.props.location.query.type === 'embedded') {
132
+ this.showNext();
133
+ }
134
+ }
135
+
136
+ if (nextProps.metaEntities && nextProps.metaEntities.layouts && nextProps.metaEntities.layouts.length > 0 && nextProps.Edit.lineTemplates && !_.isEqual(nextProps.Edit.lineTemplates, this.props.Edit.lineTemplates)) { //used inloyalty
137
+ if (nextProps.location.query.type === 'embedded' && nextProps.location.query.module === 'loyalty') {
138
+ this.setTemplateOptions(nextProps.Edit.lineTemplates);
139
+ }
140
+ }
141
+ if (nextProps.templateDetails && nextProps.templateDetails.name && _.isEmpty(this.state.editData) && (this.props.location.query.type !== 'embedded' || (!_.isEmpty(this.state.fullSchema) && selectedWeChatAccount))) {
142
+ this.props = nextProps;
143
+ const mode = nextProps.templateDetails.definition ? nextProps.templateDetails.definition.mode : nextProps.templateDetails.mode;
144
+ const schema = mode === "text" ? this.state.fullSchema.textSchema : this.state.fullSchema.imageSchema;
145
+ this.setEditState(nextProps.templateDetails, schema);
146
+ const query = {
147
+ layout: 'line',
148
+ type: 'TAG',
149
+ context: this.props.location.query.type === 'embedded' ? this.props.location.query.module : 'default',
150
+ embedded: this.props.location.query.type === 'embedded' ? this.props.location.query.type : 'full',
151
+ };
152
+ this.props.globalActions.fetchSchemaForEntity(query);
153
+ }
154
+ if (nextProps.Edit.uploadedAssetData) {
155
+ const formData = _.cloneDeep(this.state.formData);
156
+ formData[this.state.currentTab - 1].image = nextProps.Edit.uploadedAssetData.metaInfo.public_url;
157
+ this.setState({formData});
158
+ this.props.actions.clearAsset();
159
+ }
160
+ if (nextProps.Edit.iosCtasData) {
161
+ this.setState({iosCtasData: nextProps.Edit.iosCtasData});
162
+ }
163
+ if (nextProps.Edit.editResponse && nextProps.Edit.editResponse.templateId) {
164
+ console.log('reseting schema');
165
+ this.resetSchema();
166
+ this.setState({
167
+ formData: {},
168
+ tabCount: 1,
169
+ currentTab: 1,
170
+ editData: {},
171
+ });
172
+ const message = getMessageObject('success', this.props.intl.formatMessage(messages['MOBILEPUSH Template Edited Successfully']), true);
173
+ this.props.globalActions.addMessageToQueue(message);
174
+ this.props.actions.clearEditResponse();
175
+ const module = this.props.location.query.module ? this.props.location.query.module : 'default';
176
+ const type = this.props.location.query.type;
177
+ this.props.router.push({
178
+ pathname: `/line/`,
179
+ query: type === 'embedded' ? {type: 'embedded', module} : {module},
180
+ });
181
+ }
182
+
183
+ if (nextProps.Edit.editTemplateError && !_.isEqual(nextProps.Edit.editTemplateError, this.props.Edit.editTemplateError)) {
184
+ const message = getMessageObject('error', (nextProps.Edit.editTemplateErrorMessage && nextProps.Edit.editTemplateErrorMessage !== '') ? nextProps.Edit.editTemplateErrorMessage : this.props.intl.formatMessage(messages.somethingWentWrong), true);
185
+ this.props.globalActions.addMessageToQueue(message);
186
+ }
187
+ // if (nextProps.metaEntities && nextProps.metaEntities.tags && nextProps.metaEntities.tags.custom && this.props.metaEntities.tags !== nextProps.metaEntities.tags) {
188
+ // let injectedTags = _.cloneDeep(this.state.injectedTags);
189
+ // injectedTags = _.merge({}, injectedTags, nextProps.metaEntities.tags.custom);
190
+ // this.setState({injectedTags});
191
+ // }
192
+ if (nextProps.metaEntities && nextProps.metaEntities.tags && nextProps.metaEntities.tags.custom && !_.isEqual(this.props.metaEntities.tags, nextProps.metaEntities.tags)) {
193
+ let injectedTags = _.cloneDeep(this.state.injectedTags);
194
+ delete injectedTags["Registration custom fields"];
195
+ delete injectedTags["Store custom fields"];
196
+ delete injectedTags["Transaction custom fields"];
197
+ injectedTags = _.merge({}, injectedTags, nextProps.metaEntities.tags.custom);
198
+ console.log('new injected tags', nextProps.metaEntities.tags.custom);
199
+ if (!_.has(nextProps.metaEntities.tags.custom, "Registration custom fields")) {
200
+ delete injectedTags["Registration custom fields"];
201
+ }
202
+ if (!_.has(nextProps.metaEntities.tags.custom, "Store custom fields")) {
203
+ delete injectedTags["Store custom fields"];
204
+ }
205
+ if (!_.has(nextProps.metaEntities.tags.custom, "Transaction custom fields")) {
206
+ delete injectedTags["Transaction custom fields"];
207
+ }
208
+ this.setState({injectedTags});
209
+ }
210
+ };
211
+
212
+ componentWillUnmount() {
213
+ this.props.actions.clearData();
214
+ window.removeEventListener("message", this.handleFrameTasks);
215
+ };
216
+
217
+ onTemplateChange = (isEvent, formData) => {
218
+ _.forEach(this.props.Edit.lineTemplates, (template) => {
219
+ if (template._id === formData['line-template']) {
220
+ this.setState({editData: {}, formData: {}}, () => {
221
+ this.props.actions.setSelectedTemplate(template);
222
+ });
223
+ }
224
+ });
225
+ };
226
+
227
+ onFormDataChange = (formData, tabCount, currentTab) => {
228
+ console.log('Form data changed is ', formData, tabCount, currentTab);
229
+ const newFormData = _.cloneDeep(formData);
230
+ if (newFormData[this.state.currentTab - 1] && newFormData[this.state.currentTab - 1][`secondary-cta-${this.state.currentTab - 1}-table`]) {
231
+ newFormData[this.state.currentTab - 1][`secondary-cta-${this.state.currentTab - 1}-label`] = newFormData[this.state.currentTab - 1][`secondary-cta-${this.state.currentTab - 1}-table`].name;
232
+ newFormData[this.state.currentTab - 1][`secondary-cta-${this.state.currentTab - 1}-action`] = newFormData[this.state.currentTab - 1][`secondary-cta-${this.state.currentTab - 1}-table`].ctaTemplateDetails[0].buttonText;
233
+ delete newFormData[this.state.currentTab - 1][`secondary-cta-${this.state.currentTab - 1}-action2`];
234
+ if (newFormData[this.state.currentTab - 1][`secondary-cta-${this.state.currentTab - 1}-table`].ctaTemplateDetails[1]) {
235
+ newFormData[this.state.currentTab - 1][`secondary-cta-${this.state.currentTab - 1}-action2`] = newFormData[this.state.currentTab - 1][`secondary-cta-${this.state.currentTab - 1}-table`].ctaTemplateDetails[1].buttonText;
236
+ }
237
+ }
238
+ if (newFormData["line-accounts"] !== this.state.formData["line-accounts"]) {
239
+ this.setMobilePushAccountOptions(this.props.Edit.weCrmAccounts, newFormData["line-accounts"]);
240
+ delete newFormData['line-template'];
241
+ delete newFormData['template-name'];
242
+ if (!_.isEmpty(newFormData[0])) {
243
+ delete newFormData[0];
244
+ }
245
+ if (!_.isEmpty(newFormData[1])) {
246
+ delete newFormData[1];
247
+ }
248
+ }
249
+ if (this.state.isSchemaChanged) {
250
+ this.setState({isSchemaChanged: false});
251
+ }
252
+ this.setState({formData: newFormData, tabCount});
253
+ if (currentTab) {
254
+ this.setState({currentTab});
255
+ }
256
+ };
257
+
258
+ onTabChange = (data) => {
259
+ console.log('inside parent ontabchange', data, this.state);
260
+ this.setState({currentTab: data});
261
+ };
262
+
263
+ onTagSelect = (data, currentTab, srcComp) => {
264
+ console.log('parent data tag', data, currentTab);
265
+ const editorId = srcComp.target;
266
+ this.insertAtCursor(document.getElementById(editorId), `{{${data}}}`);
267
+ document.getElementById(editorId).focus();
268
+ };
269
+ onModalCancel = () => {
270
+ if (this.state.modalContent && this.state.modalContent.show) {
271
+ this.setState({modalContent: {...this.state.modalContent, show: false}});
272
+ }
273
+ };
274
+ setTemplateOptions = (lineTemplates) => {
275
+ const templateOptions = [];
276
+ let selectedTemplate = {};
277
+ if (!_.isEmpty(lineTemplates)) {
278
+ _.forEach(lineTemplates, (template) => {
279
+ templateOptions.push({
280
+ key: template._id,
281
+ label: template.name,
282
+ value: template._id,
283
+ });
284
+ if (this.state.formData['line-template'] && template._id === this.state.formData['line-template']) {
285
+ selectedTemplate = template;
286
+ }
287
+ });
288
+ }
289
+ this.setState({templateOptions}, () => {
290
+ if (!_.isEmpty(selectedTemplate)) {
291
+ this.props.actions.setSelectedTemplate(selectedTemplate);
292
+ }
293
+ if (!_.isEmpty(this.state.schema)) {
294
+ this.injectEvents(this.state.schema);
295
+ }
296
+ });
297
+ };
298
+ setMobilePushAccountOptions = (accounts, newAccountId) => {
299
+ let accId = newAccountId || this.props.location.query.account_id;
300
+ if (this.props.location.query.module !== "loyalty") {
301
+ accId = Number(accId);
302
+ }
303
+ const formData = _.cloneDeep(this.state.formData);
304
+ let selectedAccount = {};
305
+ if (accId) {
306
+ _.forEach(accounts, (account) => {
307
+ let acccountId = account.id;
308
+ if (this.props.location.query.module === "loyalty" && typeof accId === 'string') {
309
+ acccountId = account.sourceAccountIdentifier;
310
+ }
311
+ if (acccountId === accId) {
312
+ this.props.templatesActions.setWeChatAccount(account);
313
+ selectedAccount = account;
314
+ formData['line-accounts'] = account.id;
315
+ if (this.props.location.query.account_id) {
316
+ formData['line-template'] = this.props.params.id;
317
+ }
318
+ }
319
+ });
320
+ } else {
321
+ selectedAccount = accounts[0];
322
+ formData['line-accounts'] = accounts[0].id;
323
+ }
324
+ this.props.actions.setWeChatAccount(selectedAccount);
325
+ this.setState({formData, accountsOptions: accounts.map((acc) => ({key: acc.id, label: acc.name, value: acc.id}))});
326
+ };
327
+
328
+ getTransformedData = (formData) => {
329
+ const selectedWeChatAccount = (!_.isEmpty(this.props.Templates.selectedWeChatAccount) ? this.props.Templates.selectedWeChatAccount : this.props.Edit.selectedWeChatAccount);
330
+ const obj = _.cloneDeep(this.state.editData);
331
+ obj.versions = {
332
+ base: {},
333
+ };
334
+ obj.name = formData['template-name'];
335
+ obj.definition = {
336
+ accountId: selectedWeChatAccount.id,
337
+ licenseCode: selectedWeChatAccount.sourceAccountIdentifier,
338
+ mode: this.props.Edit.templateDetails.mode,
339
+ };
340
+ const android = {};
341
+ Object.keys(formData[0]).forEach((data) => {
342
+ if (!!formData[0][data] && data !== "tabKey") {
343
+ android[data] = formData[0][data];
344
+ }
345
+ });
346
+ const ios = {};
347
+ Object.keys(formData[1]).forEach((data) => {
348
+ if (!!formData[1][data] && data !== "tabKey") {
349
+ ios[data] = formData[1][data];
350
+ }
351
+ });
352
+ obj.versions.base = {};
353
+ delete android.base;
354
+ if (!_.isEmpty(android)) {
355
+ obj.versions.base.ANDROID = {
356
+ "luid": "{{luid}}",
357
+ "cuid": "{{cuid}}",
358
+ "communicationId": "{{communicationId}}",
359
+ "title": android['message-title'],
360
+ "message": android['message-editor'],
361
+ expandableDetails: {
362
+ "style": "BIG_TEXT",
363
+ "message": android['message-editor'],
364
+ },
365
+ "custom": _.map(android, (field, key) => {
366
+ if (key.indexOf('custom-value') > -1) {
367
+ return field !== "" ? {key: key.replace('custom-value-', "").replace('-cta-deeplink-select', '').replace('-cta-deeplink-secondary-cta-0-select', '').replace('-cta-deeplink-secondary-cta-1-select', ''), value: field} : undefined;
368
+ }
369
+ return undefined;
370
+ }).filter((custom) => custom),
371
+ };
372
+ }
373
+ if (android['cta-deeplink'] && android['cta-deeplink'] !== "") {
374
+ obj.versions.base.ANDROID.cta = {
375
+ "type": android['cta-deeplink'] && android['cta-deeplink'].toLowerCase() === "deeplink" ? "DEEP_LINK" : "EXTERNAL_URL",
376
+ "actionLink": android['cta-deeplink'] && android['cta-deeplink'].toLowerCase() === "deeplink" ? android['cta-deeplink-select'] : android['cta-deeplink-text'],
377
+ "deepLinkName": android['cta-deeplink'] && android['cta-deeplink'].toLowerCase() === "deeplink" ? this.getLinkName(android['cta-deeplink-select']) : undefined,
378
+ };
379
+ if (this.props.location.query.type === 'embedded') {
380
+ delete obj.versions.base.ANDROID.cta.deepLinkName;
381
+ }
382
+ }
383
+ if (!_.isEmpty(ios)) {
384
+ obj.versions.base.IOS = {
385
+ "luid": "{{luid}}",
386
+ "cuid": "{{cuid}}",
387
+ "communicationId": "{{communicationId}}",
388
+ "title": ios['message-title2'],
389
+ "message": ios['message-editor2'],
390
+ "expandableDetails": {
391
+ "style": "BIG_TEXT",
392
+ "message": ios['message-title2'],
393
+ "ctas": [
394
+
395
+ ],
396
+ "categoryId": ios['secondary-cta-1-table'] ? ios['secondary-cta-1-table'].id : undefined,
397
+ },
398
+ "custom": _.map(ios, (field, key) => {
399
+ if (key.indexOf('custom-value') > -1) {
400
+ return field !== "" ? {key: key.replace('custom-value-', "").replace('-cta-deeplink2-select', '').replace('-cta-deeplink-secondary-cta-0-select', '').replace('-cta-deeplink-secondary-cta-1-select2', ''), value: field} : undefined;
401
+ }
402
+ return undefined;
403
+ }).filter((custom) => custom),
404
+ };
405
+ }
406
+ if (ios['cta-deeplink2'] && ios['cta-deeplink2'] !== "") {
407
+ obj.versions.base.IOS.cta = {
408
+ "type": ios['cta-deeplink2'] && ios['cta-deeplink2'].toLowerCase() === "deeplink" ? "DEEP_LINK" : "EXTERNAL_URL",
409
+ "actionLink": ios['cta-deeplink2'] && ios['cta-deeplink2'].toLowerCase() === "deeplink" ? ios['cta-deeplink2-select'] : ios['cta-deeplink2-text'],
410
+ "deepLinkName": ios['cta-deeplink2'] && ios['cta-deeplink2'].toLowerCase() === "deeplink" ? this.getLinkName(ios['cta-deeplink2-select']) : undefined,
411
+ };
412
+ if (this.props.location.query.type === 'embedded') {
413
+ delete obj.versions.base.IOS.cta.deepLinkName;
414
+ }
415
+ }
416
+ const imageLink = android.image;
417
+ if (imageLink) {
418
+ obj.versions.base.ANDROID.expandableDetails.image = imageLink;
419
+ obj.versions.base.ANDROID.expandableDetails.style = "BIG_PICTURE";
420
+ }
421
+ if (obj.versions.base.ANDROID && obj.versions.base.ANDROID.cta) {
422
+ if (obj.versions.base.ANDROID.cta.type === "DEEP_LINK") {
423
+ const params = _.map(android, (field, key) => {
424
+ let actionLink;
425
+ if (key.indexOf('custom-value') > -1 && key.indexOf('cta-deeplink-select') > -1) {
426
+ const param = key.replace('custom-value-', "").replace('-cta-deeplink-select', '');
427
+ actionLink = field !== "" ? `${param}=${field}` : undefined;
428
+ }
429
+ return actionLink;
430
+ }).filter((actionLink) => actionLink);
431
+ if (params.length) {
432
+ obj.versions.base.ANDROID.cta.actionLink = `${obj.versions.base.ANDROID.cta.actionLink}?${params.join('&')}`;
433
+ }
434
+ }
435
+ }
436
+ const secondaryCta1 = !!android["cta-deeplink-secondary-cta-0-select"] || !!android['secondary-cta-0-label'];
437
+ const secondaryCta2 = !!android['cta-deeplink-secondary-cta-1-select'] || !!android['secondary-cta-1-label'];
438
+ if (secondaryCta1 || secondaryCta2 ) {
439
+ obj.versions.base.ANDROID.expandableDetails.ctas = [];
440
+ if (secondaryCta1) {
441
+ const cta = {
442
+ "actionText": android['secondary-cta-0-label'],
443
+ "type": android['cta-deeplink-secondary-cta-0'].toLowerCase() === "deeplink" ? "DEEP_LINK" : "EXTERNAL_URL",
444
+ "actionLink": android['cta-deeplink-secondary-cta-0'].toLowerCase() === "deeplink" ? android['cta-deeplink-secondary-cta-0-select'] : android['cta-deeplink-secondary-cta-0-text'],
445
+ "seccdeepLinkName": this.getLinkName(android['cta-deeplink-secondary-cta-0-select']),
446
+ };
447
+ if (this.props.location.query.type === 'embedded') {
448
+ delete cta.seccdeepLinkName;
449
+ }
450
+ obj.versions.base.ANDROID.expandableDetails.ctas.push(cta);
451
+ if (obj.versions.base.ANDROID.expandableDetails.ctas[obj.versions.base.ANDROID.expandableDetails.ctas.length - 1].type === "DEEP_LINK") {
452
+ const params = _.map(android, (field, key) => {
453
+ let actionLink;
454
+ if (key.indexOf('custom-value') > -1 && key.indexOf('cta-deeplink-secondary-cta-0-select') > -1) {
455
+ const param = key.replace('custom-value-', "").replace('-cta-deeplink-secondary-cta-0-select', '');
456
+ actionLink = field !== "" ? `${param}=${field}` : undefined;
457
+ }
458
+ return actionLink;
459
+ }).filter((actionLink) => actionLink);
460
+ if (params.length) {
461
+ obj.versions.base.ANDROID.expandableDetails.ctas[obj.versions.base.ANDROID.expandableDetails.ctas.length - 1].actionLink = `${obj.versions.base.ANDROID.expandableDetails.ctas[obj.versions.base.ANDROID.expandableDetails.ctas.length - 1].actionLink}?${params.join('&')}`;
462
+ }
463
+ }
464
+ }
465
+ if (secondaryCta2) {
466
+ obj.versions.base.ANDROID.expandableDetails.ctas.push({
467
+ "actionText": android['secondary-cta-1-label'],
468
+ "type": android['cta-deeplink-secondary-cta-1'].toLowerCase() === "deeplink" ? "DEEP_LINK" : "EXTERNAL_URL",
469
+ "actionLink": android['cta-deeplink-secondary-cta-1'].toLowerCase() === "deeplink" ? android['cta-deeplink-secondary-cta-1-select'] : android['cta-deeplink-secondary-cta-1-text'],
470
+ "seccdeepLinkName": this.getLinkName(android['cta-deeplink-secondary-cta-1-select']),
471
+ });
472
+ if (obj.versions.base.ANDROID.expandableDetails.ctas[obj.versions.base.ANDROID.expandableDetails.ctas.length - 1].type === "DEEP_LINK") {
473
+ const params = _.map(android, (field, key) => {
474
+ let actionLink;
475
+ if (key.indexOf('custom-value') > -1 && key.indexOf('cta-deeplink-secondary-cta-1-select') > -1) {
476
+ const param = key.replace('custom-value-', "").replace('-cta-deeplink-secondary-cta-1-select', '');
477
+ actionLink = field !== "" ? `${param}=${field}` : undefined;
478
+ }
479
+ return actionLink;
480
+ }).filter((actionLink) => actionLink);
481
+ if (params.length) {
482
+ obj.versions.base.ANDROID.expandableDetails.ctas[obj.versions.base.ANDROID.expandableDetails.ctas.length - 1].actionLink = `${obj.versions.base.ANDROID.expandableDetails.ctas[obj.versions.base.ANDROID.expandableDetails.ctas.length - 1].actionLink}?${params.join('&')}`;
483
+ }
484
+ }
485
+ }
486
+ }
487
+ const imageLinkIos = ios.image;
488
+ if (imageLinkIos) {
489
+ obj.versions.base.IOS.expandableDetails.image = imageLinkIos;
490
+ obj.versions.base.IOS.expandableDetails.style = "BIG_PICTURE";
491
+ }
492
+ if (obj.versions.base.IOS && obj.versions.base.IOS.cta) {
493
+ if (obj.versions.base.IOS.cta.type === "DEEP_LINK") {
494
+ const params = _.map(ios, (field, key) => {
495
+ let actionLink;
496
+ if (key.indexOf('custom-value') > -1 && key.indexOf('cta-deeplink2-select') > -1) {
497
+ const param = key.replace('custom-value-', "").replace('-cta-deeplink2-select', '');
498
+ actionLink = field !== "" ? `${param}=${field}` : undefined;
499
+ }
500
+ return actionLink;
501
+ }).filter((actionLink) => actionLink);
502
+ if (params.length) {
503
+ obj.versions.base.IOS.cta.actionLink = `${obj.versions.base.IOS.cta.actionLink}?${params.join('&')}`;
504
+ }
505
+ }
506
+ }
507
+ const secondaryCtaIos = !!ios['cta-deeplink-secondary-cta-1-select'] || !!ios['secondary-cta-1-label'];
508
+
509
+ if (secondaryCtaIos) {
510
+ obj.versions.base.IOS.expandableDetails.ctas = [];
511
+ const cta = {
512
+ "actionText": ios['secondary-cta-1-label'],
513
+ "actionLabel": ios['secondary-cta-1-action'],
514
+ "actionLabel2": ios['secondary-cta-1-action2'],
515
+ "type": ios['cta-deeplink-secondary-cta-1'] && (ios['cta-deeplink-secondary-cta-1'].toLowerCase() === "deeplink" ? "DEEP_LINK" : "EXTERNAL_URL"),
516
+ "actionLink": ios['cta-deeplink-secondary-cta-1'] && (ios['cta-deeplink-secondary-cta-1'].toLowerCase() === "deeplink" ? ios['cta-deeplink-secondary-cta-1-select2'] : ios['cta-deeplink-secondary-cta-1-text2']),
517
+ "ioscdeepLinkName": this.getLinkName(ios['cta-deeplink-secondary-cta-1-select']),
518
+ 'templateCtaId': ios['secondary-cta-1-table'] ? ios['secondary-cta-1-table'].ctaTemplateDetails[0].id : undefined,
519
+ };
520
+ if (this.props.location.query.type === 'embedded') {
521
+ delete cta.ioscdeepLinkName;
522
+ }
523
+ obj.versions.base.IOS.expandableDetails.ctas.push(cta);
524
+ if (obj.versions.base.IOS.expandableDetails.ctas[obj.versions.base.IOS.expandableDetails.ctas.length - 1].type === "DEEP_LINK") {
525
+ const params = _.map(ios, (field, key) => {
526
+ let actionLink;
527
+ if (key.indexOf('custom-value') > -1 && key.indexOf('cta-deeplink-secondary-cta-1-select') > -1) {
528
+ const param = key.replace('custom-value-', "").replace('-cta-deeplink-secondary-cta-1-select2', '');
529
+ actionLink = field !== "" ? `${param}=${field}` : undefined;
530
+ }
531
+ return actionLink;
532
+ }).filter((actionLink) => actionLink);
533
+ if (params.length) {
534
+ obj.versions.base.IOS.expandableDetails.ctas[obj.versions.base.IOS.expandableDetails.ctas.length - 1].actionLink = `${obj.versions.base.IOS.expandableDetails.ctas[obj.versions.base.IOS.expandableDetails.ctas.length - 1].actionLink}?${params.join('&')}`;
535
+ }
536
+ }
537
+ }
538
+ return obj;
539
+ };
540
+
541
+ setFormValidity = (isFormValid) => {
542
+ this.setState({isFormValid});
543
+ };
544
+
545
+ getMappedEvent = (id, event) => {
546
+ const map = this.state.eventsMap;
547
+ if (!map[id] || !map[id][event]) {
548
+ console.log(`error map[id] ${map[id]}` );
549
+ }
550
+ return map[id][event];
551
+ };
552
+
553
+ getCurrentWindow = (e) => {
554
+ console.log('in line create', e);
555
+ const response = {
556
+ action: e.action,
557
+ value: 'edit',
558
+ direction: e.value,
559
+ };
560
+ parent.postMessage(JSON.stringify(response), '*');
561
+ };
562
+
563
+ getFormData = (e) => {
564
+ console.log('posting final result', this.state.formData);
565
+ const response = {
566
+ action: "getFormData",
567
+ value: this.getTransformedData(this.state.formData),
568
+ validity: this.state.isFormValid,
569
+ };
570
+ console.log('GetForm Data ', response);
571
+ this.setState({checkValidation: true});
572
+ e.source.postMessage(JSON.stringify(response), e.origin);
573
+ };
574
+
575
+
576
+ setEditState(data, schema) {
577
+ console.log('Test 1234', data, schema);
578
+ const tabCount = Object.keys(data.versions.base).length;
579
+ const formData = {};
580
+ if (this.props.location.query.type === 'embedded' && this.props.location.query.module === "loyalty") {
581
+ formData["line-accounts"] = this.state.formData["line-accounts"];
582
+ formData['line-template'] = this.state.formData['line-template'];
583
+ }
584
+ formData['template-name'] = data.name;
585
+ const androidData = data.versions.base.ANDROID;
586
+ const iosData = data.versions.base.IOS;
587
+ const android = {};
588
+ android[`message-title`] = androidData ? androidData.title : '';
589
+ android['message-editor'] = androidData ? androidData.message : '';
590
+ if (data.mode === "image") {
591
+ android.image = "";
592
+ }
593
+ formData[0] = android;
594
+ const ios = {};
595
+ ios[`message-title2`] = iosData ? iosData.title : '';
596
+ ios['message-editor2'] = iosData ? iosData.message : '';
597
+ if (data.mode === "image") {
598
+ ios.image = "";
599
+ }
600
+ if (iosData) {
601
+ if (iosData.cta) {
602
+ ios['cta-deeplink2'] = iosData.cta.type === "DEEP_LINK" ? "Deeplink" : "External Link";
603
+ if (iosData.cta.type === "DEEP_LINK") {
604
+ ios['cta-deeplink2-select'] = iosData ? iosData.cta.actionLink : '';
605
+ } else {
606
+ ios['cta-deeplink2-text'] = iosData ? iosData.cta.actionLink : '';
607
+ }
608
+ if (iosData.cta.type === "DEEP_LINK") {
609
+ const link = ios['cta-deeplink2-select'].split('?')[0];
610
+ let params = ios['cta-deeplink2-select'].split('?');
611
+ if (params[1]) {
612
+ params = params[1].split('&');
613
+ _.forEach(params, (param) => {
614
+ ios[`custom-value-${param.split('=')[0]}-cta-deeplink2-select`] = param.split('=')[1];
615
+ });
616
+ }
617
+ ios['cta-deeplink2-select'] = link;
618
+ }
619
+ }
620
+ if (iosData.expandableDetails && iosData.expandableDetails.image) {
621
+ ios.image = iosData.expandableDetails.image;
622
+ }
623
+ if (iosData.expandableDetails && iosData.expandableDetails.ctas && iosData.expandableDetails.ctas.length) {
624
+ if (iosData.expandableDetails.ctas[0].type) {
625
+ ios['cta-deeplink-secondary-cta-1'] = iosData.expandableDetails.ctas[0].type === "DEEP_LINK" ? "Deeplink" : "External Link";
626
+ }
627
+ if (iosData.expandableDetails.ctas[0].type === "DEEP_LINK") {
628
+ ios['cta-deeplink-secondary-cta-1-select2'] = iosData.expandableDetails.ctas[0].actionLink;
629
+ } else {
630
+ ios['cta-deeplink-secondary-cta-1-text2'] = iosData.expandableDetails.ctas[0].actionLink;
631
+ }
632
+ ios['secondary-cta-1-label'] = iosData.expandableDetails.ctas[0].actionText;
633
+ if (iosData.expandableDetails.ctas[0].type === "DEEP_LINK" && ios['cta-deeplink-secondary-cta-1-select2']) {
634
+ const link = ios['cta-deeplink-secondary-cta-1-select2'].split('?')[0];
635
+ const paramsIos = ios['cta-deeplink-secondary-cta-1-select2'].split('?')[1] && ios['cta-deeplink-secondary-cta-1-select2'].split('?')[1].split('&');
636
+ ios['cta-deeplink-secondary-cta-1-select2'] = link;
637
+ _.forEach(paramsIos, (param) => {
638
+ ios[`custom-value-${param.split('=')[0]}-cta-deeplink-secondary-cta-1-select2`] = param.split('=')[1];
639
+ });
640
+ }
641
+ ios['secondary-cta-1-action'] = iosData.expandableDetails.ctas[0].actionLabel;
642
+ if (iosData.expandableDetails.ctas[0].actionLabel2) {
643
+ ios['secondary-cta-1-action2'] = iosData.expandableDetails.ctas[0].actionLabel2;
644
+ }
645
+ }
646
+ }
647
+ formData[1] = ios;
648
+ formData.base = formData[0];
649
+ formData[0].base = true;
650
+ console.log('form data after discarding ', formData);
651
+ this.getSchemaForFormData(formData, schema);
652
+ this.setState({tabCount, formData, editData: data, currentTab: 1});
653
+ }
654
+
655
+ getSchemaForFormData = (formData, inputSchema) => {
656
+ let schema = inputSchema;
657
+ this.setState({schema, isSchemaChanged: true});
658
+ this.injectEvents(schema);
659
+ };
660
+
661
+ setModalContent = (type) => {
662
+ if (type === 'ios') {
663
+ const modalContent = {
664
+ title: "Alert",
665
+ body: "Android template is not configured. Save without Android template",
666
+ type: 'confirm',
667
+ id: 'ios',
668
+ };
669
+ this.setState({modalContent, showModal: true});
670
+ } else if (type === 'android') {
671
+ const modalContent = {
672
+ title: "Alert",
673
+ body: "IOS template is not configured, Save without IOS template",
674
+ type: 'confirm',
675
+ id: 'android',
676
+ };
677
+ this.setState({modalContent, showModal: true});
678
+ }
679
+ };
680
+
681
+ openNotificationWithIcon = (type, message) => {
682
+ const dur = (type === 'error' || type === 'warning') ? null : 5;
683
+ notification[type]({
684
+ message: (`${type.toUpperCase()} ! ! ! `),
685
+ description: message, //'This is the content of the notification. This is the content of the notification. This is the content of the notification.',
686
+ duration: dur,
687
+ });
688
+ };
689
+
690
+ handleCancelModal = () => {
691
+ this.setState({showModal: false});
692
+ };
693
+
694
+ insertAtCursor = (field, myValue) => {
695
+ //IE support
696
+ const myField = field;
697
+ if (document.selection) {
698
+ myField.focus();
699
+ const sel = document.selection.createRange();
700
+ sel.text = myValue;
701
+ } else if (myField.selectionStart || myField.selectionStart === '0') { //MOZILLA and others
702
+ const startPos = myField.selectionStart;
703
+ const endPos = myField.selectionEnd;
704
+ myField.value = myField.value.substring(0, startPos)
705
+ + myValue
706
+ + myField.value.substring(endPos, myField.value.length);
707
+ myField.selectionStart = startPos + myValue.length;
708
+ myField.selectionEnd = startPos + myValue.length;
709
+ } else {
710
+ myField.value += myValue;
711
+ }
712
+ const event = new Event('input', { bubbles: true });
713
+ myField.dispatchEvent(event);
714
+ };
715
+
716
+ selectCtaIos = (selectedConfig) => {
717
+ this.showSelectedIosCta(null, null, null, selectedConfig);
718
+ };
719
+
720
+ uploadImage = (data) => {
721
+ if (data.fileParams.error) {
722
+ const message = getMessageObject('error', this.props.intl.formatMessage(messages['File size cannot be more than 5mb']), true);
723
+ this.props.globalActions.addMessageToQueue(message);
724
+ } else {
725
+ const name = data.file.name.split('.');
726
+ const blob = data.file.slice(0, -1, 'image');
727
+ const newFile = new File([blob], `${name[0]}${Date.now()}.${name[1]}`, {type: 'image'});
728
+ this.props.actions.uploadAsset(newFile, data.type, data.fileParams);
729
+ }
730
+ };
731
+
732
+ startTemplateCreation = (data) => {
733
+ console.log('startTemplateCreation', data);
734
+ if (!data.edit) {
735
+ this.setState({injectedTags: data.tags});
736
+ }
737
+ };
738
+
739
+ discardValues = () => {
740
+ console.log('discarding', this.props.Edit);
741
+ this.resetSchema();
742
+ this.setState({
743
+ formData: {},
744
+ tabCount: 1,
745
+ currentTab: 1,
746
+ editData: {},
747
+ }, () => {
748
+ const schema = this.props.Edit.templateDetails.mode === "image" ? this.state.fullSchema.imageSchema : this.state.fullSchema.textSchema;
749
+ this.setEditState(this.props.Edit.templateDetails, schema);
750
+ });
751
+ };
752
+
753
+ resetSchema = () => {
754
+ this.setState({ schema: this.state.initialState ? this.state.initialState : this.state.schema});
755
+ };
756
+
757
+ showNext = () => {
758
+ const response = {
759
+ action: "showNext",
760
+ value: true,
761
+ };
762
+ parent.postMessage(JSON.stringify(response), '*');
763
+ };
764
+
765
+ moveToTemplates = () => {
766
+ console.log('in move to Templates');
767
+ const modalContent = {
768
+ title: "Alert",
769
+ body: "Do you really want to go back? All your temporary changes will be lost!",
770
+ type: 'confirm',
771
+ id: 'template-back-confirm-modal',
772
+ show: true,
773
+ };
774
+ this.setState({modalContent, showModal: true});
775
+ };
776
+
777
+ injectSections = (sections) => {
778
+ _.forEach(sections, (section) => {
779
+ let temp = section;
780
+ if (temp.type === 'col-label') {
781
+ temp = this.injectColLabelSection(temp);
782
+ } else if (section.type === 'multicols') {
783
+ temp = this.injectMultiColSection(temp);
784
+ } else if (section.type === 'parent') {
785
+ temp = this.injectSections(temp.childSections);
786
+ }
787
+ });
788
+ return sections;
789
+ };
790
+ injectMultiColSection = (section) => {
791
+ _.forEach(section.inputFields, (inputField) => {
792
+ _.forEach(inputField.cols, (col) => {
793
+ const temp = col;
794
+ if (temp.type === 'popover') {
795
+ temp.content.sections = this.injectSections(temp.content.sections);
796
+ temp.value.sections = this.injectSections(temp.value.sections);
797
+ return true;
798
+ }
799
+ temp.injectedEvents = {};
800
+ temp.className = temp.className ? temp.className : '';
801
+ if (this.props.location.query.type === 'embedded' && (temp.type === "div" || temp.type === "icon" || temp.type === "tag-list") && (temp.supportedEvents)) {
802
+ temp.className = `${temp.className} hide`;
803
+ }
804
+ if (this.props.location.query.type === 'embedded' && (temp.type === "input" || temp.type === "textarea" || temp.type === "radioGroup")) {
805
+ temp.className = `${temp.className} disabled`;
806
+ temp.disabled = true;
807
+ }
808
+ if (this.props.location.query.type === 'embedded' && temp.id === "line-template" ) {
809
+ temp.options = this.state.templateOptions ? this.state.templateOptions : [];
810
+ }
811
+ if (this.props.location.query.type === 'embedded' && temp.id === "line-accounts" ) {
812
+ temp.options = this.state.templateOptions ? this.state.accountsOptions : [];
813
+ }
814
+ if (temp.id === "mobile-push-preview" && this.props.Templates.selectedWeChatAccount && !_.isEmpty(this.props.Templates.selectedWeChatAccount)) {
815
+ temp.content.appName = this.props.Templates.selectedWeChatAccount.name;
816
+ }
817
+ _.forEach(col.supportedEvents, (event) => {
818
+ console.log('injected event for ', col, event, this.getMappedEvent(col.id, event));
819
+ temp.injectedEvents[event] = this.getMappedEvent(col.id, event);
820
+ });
821
+ return true;
822
+ });
823
+ });
824
+ _.forEach(section.actionFields, (actionField) => {
825
+ _.forEach(actionField.cols, (col) => {
826
+ const temp = col;
827
+ temp.disabled = this.props.location.query.type === 'embedded';
828
+ if (temp.type === 'popover') {
829
+ temp.content.sections = this.injectSections(temp.content.sections);
830
+ temp.value.sections = this.injectSections(temp.value.sections);
831
+ return true;
832
+ }
833
+ temp.injectedEvents = {};
834
+ _.forEach(col.supportedEvents, (event) => {
835
+ temp.injectedEvents[event] = this.getMappedEvent(col.id, event);
836
+ });
837
+ return true;
838
+ });
839
+ });
840
+ return section;
841
+ };
842
+
843
+ saveFormData = (formData) => {
844
+ console.log('Saving form data', formData, this.state.tabCount);
845
+ const obj = this.getTransformedData(formData);
846
+ console.log('obj', obj);
847
+ this.props.actions.editTemplate(obj);
848
+ };
849
+
850
+ handleFrameTasks = (e) => {
851
+ // console.log('data listened to is', e.data);
852
+ const type = e.data;
853
+ console.log('data type', typeof type);
854
+ if (typeof type === 'object') {
855
+ // console.log('received something', type);
856
+ const action = type.action;
857
+ switch (action) {
858
+ case "startTemplateCreation":
859
+ this.startTemplateCreation(type.value);
860
+ break;
861
+ case "startLoading":
862
+ this.startLoading(type.edit);
863
+ break;
864
+ case "getCurrentWindow":
865
+ this.getCurrentWindow(type);
866
+ break;
867
+ default:
868
+ break;
869
+ }
870
+ } else {
871
+ switch (type) {
872
+ case "getFormData":
873
+ this.getFormData(e);
874
+ break;
875
+ case "startTemplateCreation":
876
+ console.log('Starting to create template');
877
+ //this.getFormData(e);
878
+ break;
879
+ case "moveToTemplates":
880
+ console.log('moving to templates');
881
+ this.moveToTemplates();
882
+ break;
883
+ case "validateContent":
884
+ console.log('validating Content');
885
+ this.validateContent(e);
886
+ break;
887
+ default:
888
+ break;
889
+ }
890
+ }
891
+ };
892
+
893
+ cancelTemplate = () => {
894
+ const type = this.props.location.query.type;
895
+ const module = this.props.location.query.module ? this.props.location.query.module : 'default';
896
+ this.props.router.push({
897
+ pathname: `/line/`,
898
+ query: type === 'embedded' ? {type: 'embedded', module} : {module},
899
+ });
900
+ };
901
+
902
+ injectContainer = (container) => {
903
+ const temp = container;
904
+ if (temp.type === 'tabs') {
905
+ temp.injectedEvents = {};
906
+ _.forEach(temp.supportedEvents, (event) => {
907
+ temp.injectedEvents[event] = this.getMappedEvent(temp.id, event);
908
+ });
909
+ _.forEach(temp.panes, (pane) => {
910
+ const tempPane = pane;
911
+ tempPane.sectionsHeaders = this.injectSections(tempPane.sectionsHeaders);
912
+ tempPane.sections = this.injectSections(tempPane.sections);
913
+ });
914
+ }
915
+ return temp;
916
+ };
917
+
918
+ injectEvents = (schema) => {
919
+ const temp = schema;
920
+ if (this.injectSections) {
921
+ temp.standalone.sections = this.injectSections(temp.standalone.sections);
922
+ }
923
+ _.forEach(temp.containers, (container) => {
924
+ let tempContainer = container;
925
+ tempContainer = this.injectContainer(tempContainer);
926
+ return tempContainer;
927
+ });
928
+ console.log('final injected schema', schema);
929
+ this.setState({schema}, () => {
930
+ this.removeStandAlone();
931
+ });
932
+ return schema;
933
+ };
934
+
935
+ removeStandAlone = () => {
936
+ const schema = _.cloneDeep(this.state.schema);
937
+ if (this.props.location.query.type === 'embedded' && this.props.location.query.module === 'loyalty') {
938
+ if (schema.standalone.sections.length === 2) {
939
+ schema.standalone.sections.splice(0, 1);
940
+ }
941
+ } else if (this.props.location.query.type === 'embedded') {
942
+ delete schema.standalone;
943
+ } else {
944
+ schema.standalone.sections.splice(1, 1);
945
+ }
946
+ this.setState({ schema });
947
+ };
948
+
949
+ handleOnTagsContextChange = (data) => {
950
+ console.log('parent tags context', data);
951
+ const query = {
952
+ layout: 'line',
953
+ type: 'TAG',
954
+ context: data.toLowerCase() === 'all' ? 'default' : data.toLowerCase(),
955
+ embedded: this.props.location.query.type === 'embedded' ? this.props.location.query.type : 'full',
956
+ };
957
+ this.props.globalActions.fetchSchemaForEntity(query);
958
+ };
959
+
960
+ render() {
961
+ const schema = this.state.schema;
962
+ let tipText = this.props.Edit && ("getTemplateDetailsInProgress" in this.props.Edit && this.props.Edit.getTemplateDetailsInProgress) ? 'Getting template details...' : '';
963
+ tipText = this.props.Edit && ("editTemplateInProgress" in this.props.Edit && this.props.Edit.editTemplateInProgress) ? 'Saving Template...' : '';
964
+ const spinning = this.props.Edit.fetchingDefaultTemplates || this.props.Edit.assetUploading || this.state.loading || (this.props.Edit && (("getTemplateDetailsInProgress" in this.props.Edit && this.props.Edit.getTemplateDetailsInProgress) || ("editTemplateInProgress" in this.props.Edit && this.props.Edit.editTemplateInProgress)));
965
+ return (
966
+ <div>
967
+ <Spin tip={tipText} spinning={spinning}>
968
+ {<Row style={{marginBottom: '16px', marginLeft: '-40px'}}>
969
+ <Col offset={1}>
970
+ <Breadcrumb>
971
+ <BreadcrumbItem>Campaigns</BreadcrumbItem>
972
+ <BreadcrumbItem>Creatives</BreadcrumbItem>
973
+ <BreadcrumbItem>Mobile Push</BreadcrumbItem>
974
+ </Breadcrumb>
975
+ </Col>
976
+ </Row>}
977
+ <Row>
978
+ <Col>
979
+ <FormBuilder
980
+ schema={schema}
981
+ onSubmit={this.saveFormData}
982
+ onChange={this.onFormDataChange}
983
+ formData={_.cloneDeep(this.state.formData)}
984
+ currentTab={this.state.currentTab}
985
+ parent={this}
986
+ location={this.props.location}
987
+ isEdit
988
+ tabCount={2}
989
+ iosCtasData={this.state.iosCtasData}
990
+ tags={this.props.metaEntities && this.props.metaEntities.tags ? this.props.metaEntities.tags.standard : []}
991
+ injectedTags={this.state.injectedTags ? this.state.injectedTags : {}}
992
+ onFormValidityChange={this.setFormValidity}
993
+ usingTabContainer
994
+ checkValidation={this.state.checkValidation}
995
+ onContextChange={this.handleOnTagsContextChange}
996
+ showModal={this.state.showModal}
997
+ iframeParent={parent}
998
+ router={this.props.router}
999
+ isSchemaChanged={this.state.isSchemaChanged}
1000
+ handleCancelModal={this.handleCancelModal}
1001
+ modal={this.state.modalContent}
1002
+ setModalContent={this.setModalContent}
1003
+ />
1004
+ </Col>
1005
+ </Row>
1006
+ </Spin>
1007
+ </div>
1008
+ );
1009
+ }
1010
+ }
1011
+
1012
+ Edit.propTypes = {
1013
+ actions: PropTypes.object.isRequired,
1014
+ Edit: PropTypes.object,
1015
+ params: PropTypes.object,
1016
+ router: PropTypes.object,
1017
+ location: PropTypes.object,
1018
+ globalActions: PropTypes.object,
1019
+ templatesActions: PropTypes.object,
1020
+ Templates: PropTypes.object,
1021
+ metaEntities: PropTypes.object,
1022
+ templateDetails: PropTypes.object,
1023
+ intl: intlShape.isRequired,
1024
+ };
1025
+
1026
+ const mapStateToProps = createStructuredSelector({
1027
+ Edit: makeSelectEdit(),
1028
+ Create: makeSelectCreate(),
1029
+ editResponse: makeSelectEditResponse(),
1030
+ templateDetails: makeSelectTemplateDetailsResponse(),
1031
+ metaEntities: makeSelectMetaEntities(),
1032
+ Templates: makeSelectTemplates(),
1033
+ });
1034
+
1035
+ function mapDispatchToProps(dispatch) {
1036
+ return {
1037
+ actions: bindActionCreators(actions, dispatch),
1038
+ globalActions: bindActionCreators(globalActions, dispatch),
1039
+ templatesActions: bindActionCreators(templatesActions, dispatch),
1040
+ };
1041
+ }
1042
+
1043
+ export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(Edit));