@capillarytech/creatives-library 7.7.1 → 7.7.4

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 (46) hide show
  1. package/index.js +3 -3
  2. package/package.json +1 -1
  3. package/v2Components/TemplatePreview/index.js +1 -0
  4. package/v2Containers/Cap/index.js +6 -5
  5. package/v2Containers/CapFacebookPreview/index.js +11 -9
  6. package/v2Containers/CapFacebookPreview/index.scss +4 -0
  7. package/v2Containers/CapFacebookPreview/messages.js +2 -2
  8. package/v2Containers/CreativesContainer/SlideBoxContent.js +16 -1
  9. package/v2Containers/CreativesContainer/index.js +122 -12
  10. package/v2Containers/Facebook/Advertisement/index.js +64 -35
  11. package/v2Containers/Facebook/Advertisement/index.scss +1 -1
  12. package/v2Containers/Facebook/Facebook.style.js +1 -1
  13. package/v2Containers/Facebook/constants.js +4 -0
  14. package/v2Containers/Facebook/index.js +198 -122
  15. package/v2Containers/Facebook/messages.js +24 -4
  16. package/v2Containers/Templates/index.js +37 -21
  17. package/v2Containers/Templates/messages.js +1 -1
  18. package/v2Containers/Templates/reducer.js +1 -1
  19. package/v2Containers/TemplatesV2/index.js +23 -6
  20. package/v2Containers/TemplatesV2/messages.js +4 -0
  21. package/v2Components/TemplatePreview/assets/images/mobile.svg +0 -24
  22. package/v2Containers/Line/Create/_lineCreate.scss +0 -64
  23. package/v2Containers/Line/Create/actions.js +0 -94
  24. package/v2Containers/Line/Create/constants.js +0 -43
  25. package/v2Containers/Line/Create/index.js +0 -1132
  26. package/v2Containers/Line/Create/initialSchema.js +0 -378
  27. package/v2Containers/Line/Create/messages.js +0 -229
  28. package/v2Containers/Line/Create/reducer.js +0 -99
  29. package/v2Containers/Line/Create/sagas.js +0 -113
  30. package/v2Containers/Line/Create/selectors.js +0 -30
  31. package/v2Containers/Line/CreateWrapper/constants.js +0 -2
  32. package/v2Containers/Line/CreateWrapper/index.js +0 -117
  33. package/v2Containers/Line/CreateWrapper/messages.js +0 -55
  34. package/v2Containers/Line/Edit/_lineEdit.scss +0 -23
  35. package/v2Containers/Line/Edit/actions.js +0 -79
  36. package/v2Containers/Line/Edit/constants.js +0 -27
  37. package/v2Containers/Line/Edit/index.js +0 -1051
  38. package/v2Containers/Line/Edit/messages.js +0 -173
  39. package/v2Containers/Line/Edit/reducer.js +0 -83
  40. package/v2Containers/Line/Edit/sagas.js +0 -81
  41. package/v2Containers/Line/Edit/selectors.js +0 -29
  42. package/v2Containers/Line/Edit/tests/actions.test.js +0 -18
  43. package/v2Containers/Line/Edit/tests/index.test.js +0 -10
  44. package/v2Containers/Line/Edit/tests/reducer.test.js +0 -9
  45. package/v2Containers/Line/Edit/tests/sagas.test.js +0 -15
  46. package/v2Containers/Line/Edit/tests/selectors.test.js +0 -10
@@ -1,1132 +0,0 @@
1
- import PropTypes from 'prop-types';
2
- import React, { Component } from 'react';
3
- import get from 'lodash/get';
4
- import set from 'lodash/set';
5
- import { bindActionCreators } from 'redux';
6
- import { intlShape } from 'react-intl';
7
- import { createStructuredSelector } from 'reselect';
8
- import _ from 'lodash';
9
- import { CapSpin, CapHeading, CapRow, CapColumn, CapNotification } from '@capillarytech/cap-ui-library';
10
- import { GA } from '@capillarytech/cap-ui-utils';
11
- import messages from './messages';
12
- import * as actions from './actions';
13
- import Gallery from '../../Assets/Gallery';
14
- import FormBuilder from '../../../v2Components/FormBuilder';
15
- //import { makeSelectCreate, makeSelectCreateResponse, makeSelectEdit, makeSelectEditResponse, makeSelectTemplateDetailsResponse } from './selectors';
16
- import {makeSelectCreateLine, makeSelectLine} from './selectors';
17
- import { makeSelectMetaEntities, setInjectedTags } from '../../Cap/selectors';
18
- import {getMessageObject} from '../../../utils/messageUtils';
19
- import { makeSelectTemplates } from '../../Templates/selectors';
20
- import './_lineCreate.scss';
21
- import withCreatives from '../../../hoc/withCreatives';
22
- import {
23
- LINE_IMG_HEIGHT,
24
- LINE_IMG_WIDTH,
25
- LINE_IMG_SIZE,
26
- } from './constants';
27
- import { TRACK_CREATE_LINE, TRACK_EDIT_LINE } from '../../App/constants';
28
-
29
- export class Line extends Component {
30
- constructor(props) {
31
- super(props);
32
- const map = {
33
- 'save-button': {
34
- saveFormData: this.saveFormData,
35
- },
36
- 'template-name': {
37
- onChange: this.onTemplateNameChange,
38
- },
39
- 'discard-button': {
40
- discardValues: this.discardValues,
41
- },
42
- 'message-editor': {
43
- onChange: this.onTemplateContentChange,
44
- },
45
- 'message-editor2': {
46
- onChange: this.onTemplateContentChange,
47
- },
48
- 'message-tagList': {
49
- onTagSelect: this.onTagSelect,
50
- },
51
- 'title-tagList': {
52
- onTagSelect: this.onTagSelectTitle,
53
- },
54
- 'pane': {
55
- onTabChange: this.onTabChange,
56
- },
57
- 'line-template': {
58
- onSelect: this.onTemplateChange,
59
- },
60
- 'image-upload-line': {
61
- onUpload: this.uploadImage,
62
- },
63
- 'tagList': {
64
- onTagSelect: this.onTagSelect,
65
- },
66
- 'line-editor': {
67
- onChange: this.onTemplateContentChange,
68
- },
69
- };
70
-
71
- this.state = {
72
- schema: {},
73
- isSchemaChanged: false,
74
- formData: {},
75
- tabCount: 1,
76
- currentTab: 1,
77
- loading: false,
78
- isFormValid: true,
79
- tabKey: '',
80
- checkValidation: false,
81
- eventsMap: map,
82
- errorData: {},
83
- displayProps: {},
84
- modalContent: {
85
- title: this.props.intl.formatMessage(messages.alertMessage),
86
- body: this.props.intl.formatMessage(
87
- messages.templateNotConfigured
88
- ),
89
- type: 'confirm',
90
- },
91
- injectedTags: {},
92
- isEdit: false,
93
- isEdited: false,
94
- editTemplateData: {},
95
- isReady: false,
96
- modeType: null,
97
- isDrawerRequired: false,
98
- startValidation: false,
99
- };
100
- }
101
-
102
- componentWillMount() {
103
- if (this.props.params.id) {
104
- const editTemplateId = this.props.params.id;
105
- this.props.actions.getTemplateDetails(editTemplateId, 'LINE');
106
- this.setState({ isEdit: true });
107
- }
108
- }
109
-
110
- componentDidMount() {
111
- const getSchemaQuery = {
112
- layout: 'LINE',
113
- type: 'LAYOUT',
114
- version: 'v2',
115
- };
116
- this.props.globalActions.fetchSchemaForEntity(getSchemaQuery);
117
- }
118
-
119
- componentWillReceiveProps(nextProps) {
120
- //// Create template logic ////
121
-
122
- let modeType;
123
- const { layouts, tags } = nextProps.metaEntities;
124
- const isSchemaReady = layouts !== undefined && layouts.length > 0;
125
- const editModeType = nextProps.route.name;
126
- if (
127
- nextProps.params.mode === 'text' ||
128
- nextProps.route.name === 'edit_text'
129
- ) {
130
- modeType = 'text';
131
- } else {
132
- modeType = 'image';
133
- }
134
- if (modeType) {
135
- this.setState({ modeType, schema: {} });
136
- }
137
- const {
138
- isGetFormData,
139
- templateData,
140
- } = nextProps;
141
- if (isGetFormData) {
142
- const {
143
- lineData,
144
- getFormSubscriptionData,
145
- } = nextProps;
146
- let selectedAccount = {};
147
- if (lineData) {
148
- const {
149
- weCrmAccounts = [],
150
- } = lineData;
151
- selectedAccount = weCrmAccounts.filter((account) => account === selectedAccount);
152
- }
153
- getFormSubscriptionData({ ...this.getFormData(), accountDetails: selectedAccount, type: 'LINE' });
154
- }
155
- if (templateData && templateData.edit) {
156
- this.setEditState(templateData);
157
- }
158
- if (isSchemaReady) {
159
- // set schema value as per mode type. Supported mode (text & image)
160
- const { textSchema, imageSchema } = this.updateSchemaWithLabels(
161
- layouts[0].definition
162
- );
163
- const schema =
164
- modeType === 'text' || editModeType === 'edit_text'
165
- ? textSchema
166
- : imageSchema;
167
- this.setState({ schema }, () => {
168
- // Once schema is ready and set, then inject the available events from the schema
169
- if (!_.isEmpty(this.state.schema)) {
170
- this.injectEvents(this.state.schema);
171
- }
172
- // Once schema is ready, then only get the tags.
173
- const getTagsQuery = {
174
- layout: 'LINE',
175
- type: 'TAG',
176
- context:
177
- this.props.location.query.type === 'embedded'
178
- ? 'outbound'
179
- : 'default',
180
- embedded:
181
- this.props.location.query.type === 'embedded'
182
- ? this.props.location.query.type
183
- : 'full',
184
- };
185
- if (this.props.getDefaultTags) {
186
- getTagsQuery.context = this.props.getDefaultTags;
187
- }
188
- if (!Object.keys(tags || {}).length && modeType !== 'image') {
189
- this.props.globalActions.fetchSchemaForEntity(getTagsQuery);
190
- } else {
191
- this.setState({ isReady: true });
192
- }
193
- });
194
- }
195
-
196
- const lineTemplateId = get(nextProps, 'Line.response.templateId', '');
197
- if (lineTemplateId) {
198
- this.discardValues();
199
- const message = getMessageObject(
200
- 'success',
201
- this.props.intl.formatMessage(
202
- messages.lineTemplateCreatedSuccessfully
203
- ),
204
- true
205
- );
206
- this.props.globalActions.addMessageToQueue(message);
207
- this.props.actions.clearCreateResponse();
208
- }
209
-
210
- if (
211
- nextProps.Line.createTemplateError &&
212
- !_.isEqual(
213
- nextProps.Line.createTemplateError,
214
- this.props.Line.createTemplateError
215
- )
216
- ) {
217
- const {
218
- Line: {
219
- createTemplateErrorMessage,
220
- },
221
- } = nextProps;
222
- const message = getMessageObject(
223
- 'error',
224
- createTemplateErrorMessage || this.props.intl.formatMessage(messages.somethingWentWrong),
225
- true
226
- );
227
- this.props.globalActions.addMessageToQueue(message);
228
- }
229
-
230
- //// Edit Template Logic ////
231
- const isEdit =
232
- this.state.isEdit &&
233
- this.props.params.id &&
234
- (this.props.route.name === 'edit_text' ||
235
- this.props.route.name === 'edit_image') &&
236
- this.props.Line.templateDetails &&
237
- this.props.Line.templateDetails.versions;
238
- if (isEdit) {
239
- const formData = this.getEditTransformedData(
240
- this.props.Line.templateDetails
241
- );
242
- this.setState({
243
- formData,
244
- editTemplateData: this.props.Line.templateDetails,
245
- });
246
- this.props.actions.clearData();
247
- }
248
-
249
- if (
250
- nextProps.Line.editTemplateError &&
251
- !_.isEqual(
252
- nextProps.Line.editTemplateError,
253
- this.props.Line.editTemplateError
254
- )
255
- ) {
256
- const message = getMessageObject(
257
- 'error',
258
- nextProps.Line.editTemplateErrorMessage &&
259
- nextProps.Line.editTemplateErrorMessage !== ''
260
- ? nextProps.Line.editTemplateErrorMessage
261
- : this.props.intl.formatMessage(messages.somethingWentWrong),
262
- true
263
- );
264
- this.props.globalActions.addMessageToQueue(message);
265
- }
266
-
267
- if (
268
- nextProps.Line.uploadAssetSuccess &&
269
- nextProps.Line.uploadedAssetData
270
- ) {
271
- const formData = _.cloneDeep(this.state.formData);
272
- // TODO: if multiple image upload supports, change below accordingly.
273
- formData[this.state.currentTab - 1].image =
274
- nextProps.Line.uploadedAssetData.metaInfo.secure_file_path;
275
- formData[this.state.currentTab - 1].imagePreview =
276
- nextProps.Line.uploadedAssetData.metaInfo.secure_file_path_preview;
277
- this.setState({ formData });
278
- this.props.actions.clearAsset();
279
- }
280
- }
281
-
282
- setEditSuccessMessage = () => {
283
- this.setState({ formData: {} });
284
- const message = getMessageObject(
285
- 'success',
286
- this.props.intl.formatMessage(
287
- messages['Line Template Edited Successfully']
288
- ),
289
- true
290
- );
291
- this.props.globalActions.addMessageToQueue(message);
292
- this.props.actions.clearEditResponse();
293
- }
294
-
295
- setEditState = (data) => {
296
- const { formData: previousFormData } = this.state;
297
- const { text, originalContentUrl, imagePreview, image, previewImageUrl } = get(data, "versions.base.content.messages[0]", {});
298
- const retrievedData = {
299
- ...previousFormData[0],
300
- };
301
- if (text) {
302
- retrievedData["message-editor"] = text;
303
- }
304
- const lineImage = originalContentUrl || image;
305
- if (lineImage) {
306
- retrievedData.image = lineImage;
307
- retrievedData.imagePreview = imagePreview || previewImageUrl;
308
- }
309
- const formData = {
310
- 0: retrievedData,
311
- base: retrievedData,
312
- };
313
- this.setState({ formData });
314
- }
315
-
316
- componentWillUnmount() {
317
- window.removeEventListener('message', this.handleFrameTasks);
318
- }
319
-
320
- onTagSelect(data, currentTab) {
321
- const editorId = 'message-editor';
322
- this.insertAtCursor(
323
- document.getElementById(editorId),
324
- `{{${data}}}`,
325
- currentTab
326
- );
327
- document.getElementById(editorId).focus();
328
- }
329
-
330
- onTagSelectTitle(data, currentTab) {
331
- const editorId = 'message-title';
332
- this.insertAtCursor(
333
- document.getElementById(editorId),
334
- `{{${data}}}`,
335
- currentTab
336
- );
337
- document.getElementById(editorId).focus();
338
- }
339
-
340
- onFormDataChange = (formData, tabCount, currentTab) => {
341
- this.setState({ formData: { ...formData } });
342
- if (tabCount) {
343
- this.setState({ tabCount });
344
- }
345
- if (currentTab) {
346
- this.setState({ currentTab });
347
- }
348
- };
349
-
350
- getTransformedData = (formData) => {
351
- const modeType = this.state.modeType;
352
- const obj = {};
353
- const msgData = {};
354
- obj.versions = {
355
- base: {
356
- content: {
357
- to: '{{line_id}}',
358
- messages: [],
359
- },
360
- },
361
- };
362
- obj.type = 'LINE';
363
- obj.name = formData['template-name'];
364
- obj.definition = {
365
- mode: modeType,
366
- };
367
- if (modeType && modeType !== undefined) {
368
- msgData.type = modeType;
369
- }
370
- if (modeType === 'text') {
371
- if (this.state.isEdit) {
372
- const editTemplateId = this.state.editTemplateData._id;
373
- if (editTemplateId && editTemplateId !== undefined) {
374
- obj._id = this.state.editTemplateData._id;
375
- msgData.text = formData['0']['message-editor'];
376
- }
377
- } else {
378
- msgData.text = formData.base['message-editor'];
379
- }
380
- } else if (modeType === 'image') {
381
- const formImage = formData['0'].image;
382
- if (formImage && formImage.length < 1) {
383
- return 'IMAGE_ERROR';
384
- }
385
- if (this.state.isEdit) {
386
- const editTemplateId = this.state.editTemplateData._id;
387
- if (editTemplateId && editTemplateId !== undefined) {
388
- obj._id = editTemplateId;
389
- msgData.originalContentUrl = formData['0'].image;
390
- msgData.previewImageUrl = formData['0'].imagePreview;
391
- }
392
- } else {
393
- msgData.originalContentUrl = formData['0'].image;
394
- msgData.previewImageUrl = formData['0'].imagePreview;
395
- }
396
- }
397
- obj.versions.base.content.messages.push(msgData);
398
- return obj;
399
- };
400
-
401
- getEditTransformedData = ({ name, versions }) => {
402
- const modeType = this.state.modeType;
403
- const obj = {};
404
- obj['0'] = {};
405
- obj.base = {
406
- base: true,
407
- };
408
- obj['template-name'] = name;
409
- if (modeType === 'text') {
410
- obj.base['message-editor'] =
411
- versions.base.content.messages[0].text;
412
- obj['0']['message-editor'] =
413
- versions.base.content.messages[0].text;
414
- } else if (modeType === 'image') {
415
- const {
416
- base: {
417
- content: {
418
- messages: [{
419
- originalContentUrl,
420
- previewImageUrl,
421
- }],
422
- },
423
- },
424
- } = versions;
425
- obj.base.image = originalContentUrl;
426
- obj['0'].image = originalContentUrl;
427
- obj['0'].imagePreview = previewImageUrl;
428
- obj.base.imagePreview = previewImageUrl;
429
- }
430
- return obj;
431
- };
432
-
433
- setFormValidity = (isFormValid) => {
434
- this.setState({ isFormValid });
435
- };
436
-
437
- getMappedEvent = (id, event) => {
438
- const map = this.state.eventsMap;
439
- return map[id][event];
440
- };
441
-
442
- getCurrentWindow(e) {
443
- const response = {
444
- action: e.action,
445
- value: 'edit',
446
- direction: e.value,
447
- };
448
- parent.postMessage(JSON.stringify(response), '*');
449
- }
450
-
451
- getFormData = (e) => {
452
- const response = {
453
- action: 'getFormData',
454
- value: this.getTransformedData(this.state.formData),
455
- validity: this.state.isFormValid,
456
- };
457
- this.setState({ checkValidation: true });
458
- if (e) {
459
- e.source.postMessage(JSON.stringify(response), e.origin);
460
- }
461
- return response;
462
- };
463
-
464
- injectEvents = (schema) => {
465
- const temp = schema;
466
- if (temp.standalone) {
467
- temp.standalone.sections = this.injectSections(
468
- temp.standalone.sections
469
- );
470
- }
471
- _.forEach(temp.containers, (container) => {
472
- let tempContainer = container;
473
- tempContainer = this.injectContainer(tempContainer);
474
- return tempContainer;
475
- });
476
- this.setState({ schema, isSchemaChanged: true }, () => {
477
- this.removeStandAlone();
478
- });
479
- return schema;
480
- };
481
-
482
- saveFormData = () => {
483
- const obj = this.getTransformedData(this.state.formData);
484
- if (obj === 'IMAGE_ERROR') {
485
- const message = getMessageObject(
486
- 'error',
487
- this.props.intl.formatMessage(
488
- messages['Please upload an image to proceed']
489
- ),
490
- true
491
- );
492
- this.props.globalActions.addMessageToQueue(message);
493
- return;
494
- }
495
- if (
496
- obj !== 'IMAGE_ERROR' &&
497
- obj.versions.base.content.messages[0].type === 'text'
498
- ) {
499
- const text = obj.versions.base.content.messages[0].text;
500
- const charCount = text ? text.length : 0;
501
- if (charCount > 1600) {
502
- const message = getMessageObject(
503
- 'error',
504
- this.props.intl.formatMessage(
505
- messages['Maximum characters length exceeds']
506
- ),
507
- true
508
- );
509
- this.props.globalActions.addMessageToQueue(message);
510
- return;
511
- }
512
- }
513
- if (!this.state.startValidation) {
514
- this.setState({
515
- startValidation: true,
516
- });
517
- } else {
518
- const {
519
- isFullMode,
520
- saveMessage,
521
- actions,
522
- onCreateComplete,
523
- } = this.props;
524
- const { text, originalContentUrl, image } = get(obj, "versions.base.content.messages[0]", {});
525
- const { name } = obj || {};
526
- const {stopTimer} = GA.timeTracker;
527
- const modeType = obj.definition.mode;
528
- const type = this.state.isEdit ? TRACK_EDIT_LINE : TRACK_CREATE_LINE;
529
- if ((text || originalContentUrl || image) && (isFullMode ? name : true)) {
530
- if (!isFullMode) {
531
- saveMessage();
532
- } else if (this.state.isEdit) {
533
- actions.editTemplate(obj, () => {
534
- // stop timer for edit line
535
- stopTimer(type, {
536
- category: 'Creatives',
537
- action: type,
538
- label: modeType,
539
- });
540
- this.setEditSuccessMessage();
541
- onCreateComplete();
542
- });
543
- } else {
544
- actions.createTemplate(
545
- obj,
546
- () => {
547
- // stop timer for create line
548
- stopTimer(type, {
549
- category: 'Creatives',
550
- action: type,
551
- label: modeType,
552
- });
553
- this.setEditSuccessMessage();
554
- onCreateComplete();
555
- }
556
- );
557
- }
558
- }
559
- }
560
- };
561
-
562
- injectSections = (sections) => {
563
- _.forEach(sections, (section) => {
564
- let temp = section;
565
- if (temp.type === 'col-label') {
566
- temp = this.injectColLabelSection(temp);
567
- } else if (section.type === 'multicols') {
568
- temp = this.injectMultiColSection(temp);
569
- } else if (section.type === 'parent') {
570
- temp = this.injectSections(temp.childSections);
571
- }
572
- });
573
- return sections;
574
- };
575
-
576
- injectMultiColSection = (section) => {
577
- _.forEach(section.inputFields, (inputField) => {
578
- _.forEach(inputField.cols, (col) => {
579
- const temp = col;
580
- if (temp.type === 'popover') {
581
- temp.content.sections = this.injectSections(
582
- temp.content.sections
583
- );
584
- temp.value.sections = this.injectSections(temp.value.sections);
585
- return true;
586
- }
587
- if (temp.id === 'discard-button') {
588
- temp.colStyle = { ...temp.colStyle, display: 'none' };
589
- }
590
- if (temp.id === 'cancel-button') {
591
- temp.offset = 11;
592
- }
593
- if (temp.id === 'line-push-preview') {
594
- temp.content.appName = this.props.Templates.selectedWeChatAccount.name;
595
- }
596
- temp.injectedEvents = {};
597
-
598
- _.forEach(col.supportedEvents, (event) => {
599
- temp.injectedEvents[event] = this.getMappedEvent(
600
- col.id,
601
- event
602
- );
603
- });
604
- return true;
605
- });
606
- });
607
- _.forEach(section.actionFields, (actionField) => {
608
- _.forEach(actionField.cols, (col) => {
609
- const temp = col;
610
- if (temp.type === 'popover') {
611
- temp.content.sections = this.injectSections(
612
- temp.content.sections
613
- );
614
- temp.value.sections = this.injectSections(temp.value.sections);
615
- return true;
616
- }
617
- temp.injectedEvents = {};
618
- _.forEach(col.supportedEvents, (event) => {
619
- temp.injectedEvents[event] = this.getMappedEvent(
620
- col.id,
621
- event
622
- );
623
- });
624
- return true;
625
- });
626
- });
627
- return section;
628
- };
629
-
630
- injectColLabelSection = (section) => {
631
- _.forEach(section.inputFields, (inputField) => {
632
- const temp = inputField;
633
- if (temp.type === 'popover') {
634
- temp.content.sections = this.injectSections(
635
- temp.content.sections
636
- );
637
- temp.value.sections = this.injectSections(temp.value.sections);
638
- return true;
639
- }
640
- temp.injectedEvents = {};
641
- _.forEach(inputField.supportedEvents, (event) => {
642
- temp.injectedEvents[event] = this.getMappedEvent(
643
- inputField.id,
644
- event
645
- );
646
- });
647
- return true;
648
- });
649
- _.forEach(section.actionFields, (actionField) => {
650
- const temp = actionField;
651
- if (temp.type === 'popover') {
652
- temp.content.sections = this.injectSections(
653
- temp.content.sections
654
- );
655
- temp.value.sections = this.injectSections(temp.value.sections);
656
- return true;
657
- }
658
- temp.injectedEvents = {};
659
- _.forEach(actionField.supportedEvents, (event) => {
660
- temp.injectedEvents[event] = this.getMappedEvent(
661
- actionField.id,
662
- event
663
- );
664
- });
665
- return true;
666
- });
667
- return section;
668
- };
669
-
670
- injectParentSection = (section) => {
671
- _.forEach(section.childSections, (childSection) => {
672
- let temp = childSection;
673
- if (temp.type === 'col-label') {
674
- temp = this.injectColLabelSection(temp);
675
- } else if (section.type === 'multicols') {
676
- temp = this.injectMultiColSection(temp);
677
- } else if (section.type === 'parent') {
678
- temp = this.injectParentSection(temp);
679
- }
680
- });
681
- return section;
682
- };
683
-
684
- insertAtCursor = (field, myValue, currentTab) => {
685
- //IE support
686
- const myField = field;
687
- if (document.selection) {
688
- myField.focus();
689
- const sel = document.selection.createRange();
690
- sel.text = myValue;
691
- } else if (
692
- myField.selectionStart ||
693
- myField.selectionStart === '0'
694
- ) {
695
- //MOZILLA and others
696
- const startPos = myField.selectionStart;
697
- const endPos = myField.selectionEnd;
698
- myField.value =
699
- myField.value.substring(0, startPos) +
700
- myValue +
701
- myField.value.substring(endPos, myField.value.length);
702
- myField.selectionStart = startPos + myValue.length;
703
- myField.selectionEnd = startPos + myValue.length;
704
- } else {
705
- myField.value += myValue;
706
- }
707
- const formData = _.cloneDeep(this.state.formData);
708
- formData[currentTab - 1][field.id] = myField.value;
709
- this.setState({ formData });
710
- };
711
-
712
- startTemplateCreation = (data) => {
713
- const getSchemaQuery = {
714
- layout: 'LINE',
715
- type: 'LAYOUT',
716
- };
717
- this.props.globalActions.fetchSchemaForEntity(getSchemaQuery);
718
- const content = data.content;
719
- const obj = {};
720
- obj['0'] = {};
721
- obj.base = {
722
- base: true,
723
- };
724
- if (data.type === 'text') {
725
- obj.base['message-editor'] = content;
726
- obj['0']['message-editor'] = content;
727
- } else {
728
- obj.base.image = content;
729
- obj['0'].image = content;
730
- }
731
- this.setState({
732
- formData: obj,
733
- loading: false,
734
- injectedTags: data.tags,
735
- });
736
- this.props.globalActions.setInjectedTags(data.tags);
737
- };
738
-
739
- startLoading = (ifEdit) => {
740
- if (ifEdit) {
741
- this.setState({ loading: true });
742
- }
743
- };
744
-
745
- injectContainer = (container) => {
746
- const temp = container;
747
- if (temp.type === 'tabs') {
748
- temp.injectedEvents = {};
749
- _.forEach(temp.supportedEvents, (event) => {
750
- temp.injectedEvents[event] = this.getMappedEvent(temp.id, event);
751
- });
752
- _.forEach(temp.panes, (pane) => {
753
- const tempPane = pane;
754
- tempPane.sectionsHeaders = this.injectSections(
755
- tempPane.sectionsHeaders
756
- );
757
- tempPane.sections = this.injectSections(tempPane.sections);
758
- });
759
- }
760
- return temp;
761
- };
762
-
763
- resetSchema = () => {
764
- this.setState({
765
- schema: this.state.initialState
766
- ? this.state.initialState
767
- : this.state.schema,
768
- });
769
- };
770
-
771
- resetState = () => {
772
- this.setState({
773
- formData: {},
774
- tabCount: 1,
775
- currentTab: 1,
776
- });
777
- };
778
-
779
- discardValues = () => {
780
- this.resetSchema();
781
- this.resetState();
782
- };
783
-
784
- moveToTemplates() {
785
- const modalContent = {
786
- title: this.props.intl.formatMessage(messages.alertMessage),
787
- body: this.props.intl.formatMessage(messages.goBackTemporaryLost),
788
- type: 'confirm',
789
- id: 'template-back-confirm-modal',
790
- show: true,
791
- };
792
- this.setState({ modalContent, showModal: true });
793
- }
794
-
795
- showNext() {
796
- const response = {
797
- action: 'showNext',
798
- value: true,
799
- };
800
- parent.postMessage(JSON.stringify(response), '*');
801
- }
802
-
803
- discardValues = () => {
804
- this.resetSchema();
805
- this.resetState();
806
- };
807
-
808
- handleFrameTasks = (e) => {
809
- const type = e.data;
810
- if (typeof type === 'object') {
811
- const action = type.action;
812
- switch (action) {
813
- case 'startTemplateCreation':
814
- this.startTemplateCreation(type.value);
815
- break;
816
- case 'startLoading':
817
- this.startLoading(type.edit);
818
- break;
819
- case 'getCurrentWindow':
820
- this.getCurrentWindow(type);
821
- break;
822
- default:
823
- break;
824
- }
825
- } else {
826
- switch (type) {
827
- case 'getFormData':
828
- this.getFormData(e);
829
- break;
830
- case 'startTemplateCreation':
831
- //this.getFormData(e);
832
- break;
833
- case 'moveToTemplates':
834
- this.moveToTemplates();
835
- break;
836
- case 'validateContent':
837
- this.validateContent(e);
838
- break;
839
- default:
840
- break;
841
- }
842
- }
843
- };
844
-
845
- removeStandAlone = () => {
846
- const schema = _.cloneDeep(this.state.schema);
847
- const {
848
- location: {
849
- query: {
850
- type,
851
- mode,
852
- module,
853
- },
854
- },
855
- } = this.props;
856
- if (type === 'embedded' && module === 'loyalty') {
857
- schema.standalone.sections.splice(0, 1);
858
- } else if (type === 'embedded' && typeof mode !== 'undefined') {
859
- delete schema.standalone;
860
- } else if (!this.props.isFullMode) {
861
- const childSections = get(schema, 'standalone.sections[0].childSections');
862
- const fields = get(childSections, '[1].childSections[0].childSections');//removing template name section
863
- fields.splice(0, 1);
864
- set(childSections, '[1].childSections[0].childSections', fields);
865
- } else {
866
- schema.standalone.sections.splice(1, 1);
867
- }
868
- this.setState({ schema });
869
- };
870
-
871
- validateContent = (e) => {
872
- const response = {
873
- action: 'validateContent',
874
- value: this.state.isFormValid,
875
- };
876
- e.source.postMessage(JSON.stringify(response), e.origin);
877
- };
878
-
879
- handleOnTagsContextChange = (data) => {
880
- const query = {
881
- layout: 'LINE',
882
- type: 'TAG',
883
- context:
884
- (data || '').toLowerCase() === 'all' ? 'default' : (data || '').toLowerCase(),
885
- embedded:
886
- this.props.location.query.type === 'embedded'
887
- ? this.props.location.query.type
888
- : 'full',
889
- };
890
- this.props.globalActions.fetchSchemaForEntity(query);
891
- };
892
-
893
- uploadImage = (pearmData) => {
894
- const data = pearmData;
895
- const {
896
- file: {
897
- size,
898
- },
899
- fileParams: {
900
- height,
901
- width,
902
- },
903
- type,
904
- } = pearmData;
905
- if (type === "wrong file" || size > LINE_IMG_SIZE || height > LINE_IMG_HEIGHT || width > LINE_IMG_WIDTH) {
906
- CapNotification.error({
907
- message: this.props.intl.formatMessage(
908
- messages.lineImageIncorrectSize
909
- ),
910
- });
911
- } else {
912
- data.fileParams.isGeneratePreview = true;
913
- this.props.actions.uploadAsset(
914
- data.file,
915
- data.type,
916
- data.fileParams,
917
- );
918
- }
919
- };
920
-
921
- onGalleryImageSelect = (imageTemplate) => {
922
- const { formData } = this.state;
923
- const image = get(imageTemplate, 'metaInfo.secure_file_path');
924
- const imagePreview = get(imageTemplate, 'metaInfo.secure_file_path_preview');
925
- this.setState({
926
- isDrawerRequired: false,
927
- formData: {
928
- ...formData,
929
- 0: {
930
- ...formData[0],
931
- image,
932
- imagePreview,
933
- },
934
- base: {
935
- ...formData.base,
936
- image,
937
- imagePreview,
938
- },
939
- },
940
- });
941
- }
942
-
943
- getGalleryDrawerContent = () => {
944
- const location = {
945
- pathname: `/assets`,
946
- search: '',
947
- query: !this.props.isFullMode ? {type: 'embedded', module: 'library'} : {},
948
- };
949
- const content = (
950
- <Gallery
951
- location={location}
952
- isFullMode={this.props.isFullMode}
953
- isLineAsset
954
- onGalleryImageSelect={this.onGalleryImageSelect}
955
- />);
956
- return (
957
- <>
958
- <CapHeading type="h3">
959
- {this.props.intl.formatMessage(messages.imageGallery)}
960
- </CapHeading>
961
- {content}
962
- </>
963
- );
964
- };
965
-
966
- updateSchemaWithLabels = (schema) => {
967
- /* eslint-disable no-param-reassign */
968
- schema.textSchema.standalone.sections[0].childSections[1].childSections[0].childSections[0].inputFields[0].cols[0].placeholder = this.props.intl.formatMessage(
969
- messages.templatePlaceholder
970
- );
971
- schema.textSchema.standalone.sections[0].childSections[1].childSections[0].childSections[0].inputFields[0].cols[0].errorMessage = this.props.intl.formatMessage(
972
- messages.templateNameErrorPlaceholder
973
- );
974
- schema.textSchema.standalone.sections[0].childSections[1].childSections[0].childSections[1].inputFields[0].cols[0].label = this.props.intl.formatMessage(
975
- messages.templateAddTag
976
- );
977
- schema.textSchema.standalone.sections[0].childSections[1].childSections[0].childSections[2].inputFields[0].cols[0].placeholder = this.props.intl.formatMessage(
978
- messages.templateMessagePlaceholder
979
- );
980
- schema.textSchema.standalone.sections[0].childSections[1].childSections[0].childSections[2].inputFields[0].cols[0].errorMessage = this.props.intl.formatMessage(
981
- messages.templateMessageError
982
- );
983
- schema.imageSchema.standalone.sections[0].childSections[1].childSections[0].childSections[0].inputFields[0].cols[0].placeholder = this.props.intl.formatMessage(
984
- messages.templatePlaceholder
985
- );
986
- schema.imageSchema.standalone.sections[0].childSections[1].childSections[0].childSections[0].inputFields[0].cols[0].errorMessage = this.props.intl.formatMessage(
987
- messages.templateNameErrorPlaceholder
988
- );
989
- schema.imageSchema.standalone.sections[0].childSections[1].childSections[0].childSections[1].inputFields[0].cols[0].previewProps.label = this.props.intl.formatMessage(
990
- messages.templateMessagePreviewPropsLabel
991
- );
992
- schema.imageSchema.standalone.sections[0].childSections[1].childSections[0].childSections[1].inputFields[0].cols[0].previewProps.inductiveText = this.props.intl.formatMessage(
993
- messages.templateMessagePreviewPropsInductiveText
994
- );
995
- schema.imageSchema.standalone.sections[0].childSections[1].childSections[0].childSections[1].inputFields[0].cols[0].previewProps.errorMessage = this.props.intl.formatMessage(
996
- messages.templateMessagePreviewPropsError
997
- );
998
- return schema;
999
- };
1000
-
1001
- stopValidation = () => {
1002
- this.setState({
1003
- startValidation: false,
1004
- })
1005
- }
1006
-
1007
- render() {
1008
- const {
1009
- Line: {
1010
- createTemplateInProgress,
1011
- assetUploading,
1012
- } = {},
1013
- templateData,
1014
- params: {
1015
- id,
1016
- } = {},
1017
- isFullMode,
1018
- } = this.props;
1019
- const {
1020
- edit,
1021
- mode,
1022
- orgId,
1023
- isDefault,
1024
- } = templateData || {};
1025
- let loading = createTemplateInProgress || false;
1026
- loading = !!assetUploading;
1027
- if (!isDefault && (edit || mode === 'edit' || (orgId && id))) {
1028
- const {
1029
- base: {
1030
- 'message-editor': msgEditor,
1031
- image: uploadedAsset,
1032
- } = {},
1033
- reUpload,
1034
- } = this.state.formData;
1035
- loading = typeof reUpload === 'undefined' ? !(msgEditor || uploadedAsset) : !reUpload;
1036
- if (templateData && !isFullMode) {
1037
- const { text, originalContentUrl } = get(templateData, "versions.base.content.messages[0]", {});
1038
- loading = !(text || originalContentUrl);
1039
- }
1040
- }
1041
- let tags =
1042
- this.props.metaEntities && this.props.metaEntities.tags
1043
- ? this.props.metaEntities.tags.standard
1044
- : [];
1045
- if (this.props.supportedTags) {
1046
- tags = this.props.supportedTags;
1047
- }
1048
- return (
1049
- <CapSpin spinning={loading}>
1050
- <CapRow>
1051
- <CapColumn>
1052
- <FormBuilder
1053
- key={'form builder'}
1054
- schema={this.state.schema}
1055
- onSubmit={this.saveFormData}
1056
- onChange={this.onFormDataChange}
1057
- currentTab={this.state.currentTab}
1058
- parent={this}
1059
- formData={_.cloneDeep(this.state.formData)}
1060
- location={this.props.location}
1061
- tags={tags}
1062
- injectedTags={
1063
- this.props.injectedTags ? this.props.injectedTags : {}
1064
- }
1065
- onFormValidityChange={this.setFormValidity}
1066
- usingTabContainer
1067
- checkValidation={this.state.checkValidation}
1068
- tabKey={this.state.tabKey}
1069
- tabCount={2}
1070
- showModal={this.state.showModal}
1071
- isSchemaChanged={this.state.isSchemaChanged}
1072
- modal={this.state.modalContent}
1073
- handleCancelModal={this.handleCancelModal}
1074
- iframeParent={parent}
1075
- router={this.props.router}
1076
- onContextChange={this.handleOnTagsContextChange}
1077
- setModalContent={this.setModalContent}
1078
- capDrawerContent={this.getGalleryDrawerContent()}
1079
- isDrawerRequired={this.state.isDrawerRequired}
1080
- setDrawerVisibility={(drawervisibleFlag) =>
1081
- this.setState({ isDrawerRequired: drawervisibleFlag })
1082
- }
1083
- startValidation={this.state.startValidation}
1084
- stopValidation={this.stopValidation}
1085
- />
1086
- </CapColumn>
1087
- </CapRow>
1088
- </CapSpin>
1089
- );
1090
- }
1091
- }
1092
-
1093
- Line.propTypes = {
1094
- actions: PropTypes.object.isRequired,
1095
- globalActions: PropTypes.object,
1096
- Templates: PropTypes.object,
1097
- location: PropTypes.object,
1098
- router: PropTypes.object,
1099
- params: PropTypes.object,
1100
- metaEntities: PropTypes.object,
1101
- intl: intlShape.isRequired,
1102
- route: PropTypes.object,
1103
- Line: PropTypes.object,
1104
- supportedTags: PropTypes.any,
1105
- getDefaultTags: PropTypes.string,
1106
- injectedTags: PropTypes.object,
1107
- onCreateComplete: PropTypes.func,
1108
- isFullMode: PropTypes.bool,
1109
- saveMessage: PropTypes.func,
1110
- templateData: PropTypes.object,
1111
- };
1112
-
1113
- const mapStateToProps = createStructuredSelector({
1114
- Line: makeSelectCreateLine(),
1115
- lineData: makeSelectLine(),
1116
- Templates: makeSelectTemplates(),
1117
- metaEntities: makeSelectMetaEntities(),
1118
- injectedTags: setInjectedTags(),
1119
- });
1120
-
1121
- function mapDispatchToProps(dispatch) {
1122
- return {
1123
- actions: bindActionCreators(actions, dispatch),
1124
- };
1125
- }
1126
-
1127
- export default withCreatives({
1128
- WrappedComponent: Line,
1129
- mapStateToProps,
1130
- mapDispatchToProps,
1131
- userAuth: true,
1132
- });