@capillarytech/creatives-library 8.0.235 → 8.0.236-alpha.1

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 (86) hide show
  1. package/assets/Android.png +0 -0
  2. package/assets/iOS.png +0 -0
  3. package/config/app.js +0 -1
  4. package/constants/unified.js +1 -1
  5. package/initialReducer.js +2 -0
  6. package/package.json +1 -1
  7. package/services/api.js +5 -2
  8. package/services/tests/api.test.js +18 -0
  9. package/utils/common.js +1 -2
  10. package/utils/commonUtils.js +14 -1
  11. package/utils/transformTemplateConfig.js +0 -10
  12. package/v2Components/CapDeviceContent/index.js +61 -56
  13. package/v2Components/CapTagList/index.js +4 -0
  14. package/v2Components/CapWhatsappCTA/tests/index.test.js +5 -0
  15. package/v2Components/HtmlEditor/HTMLEditor.js +165 -80
  16. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +532 -0
  17. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +17 -12
  18. package/v2Components/HtmlEditor/_htmlEditor.scss +0 -4
  19. package/v2Components/HtmlEditor/_index.lazy.scss +0 -1
  20. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +0 -98
  21. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +125 -148
  22. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +1 -0
  23. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
  24. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +4 -7
  25. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +35 -45
  26. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +1 -3
  27. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
  28. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +7 -6
  29. package/v2Components/HtmlEditor/constants.js +29 -20
  30. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +158 -17
  31. package/v2Components/HtmlEditor/hooks/useInAppContent.js +53 -143
  32. package/v2Components/HtmlEditor/index.js +1 -1
  33. package/v2Components/HtmlEditor/messages.js +85 -85
  34. package/v2Components/MobilePushPreviewV2/index.js +32 -7
  35. package/v2Components/TemplatePreview/_templatePreview.scss +31 -21
  36. package/v2Components/TemplatePreview/index.js +47 -32
  37. package/v2Components/TemplatePreview/messages.js +4 -0
  38. package/v2Containers/BeeEditor/index.js +82 -80
  39. package/v2Containers/BeePopupEditor/constants.js +10 -0
  40. package/v2Containers/BeePopupEditor/index.js +180 -0
  41. package/v2Containers/BeePopupEditor/tests/index.test.js +627 -0
  42. package/v2Containers/CreativesContainer/SlideBoxContent.js +69 -34
  43. package/v2Containers/CreativesContainer/SlideBoxHeader.js +2 -1
  44. package/v2Containers/CreativesContainer/constants.js +1 -0
  45. package/v2Containers/CreativesContainer/index.js +65 -13
  46. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +4 -12
  47. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +15 -0
  48. package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +376 -0
  49. package/v2Containers/InApp/__tests__/sagas.test.js +363 -0
  50. package/v2Containers/InApp/actions.js +7 -0
  51. package/v2Containers/InApp/constants.js +18 -4
  52. package/v2Containers/InApp/index.js +642 -355
  53. package/v2Containers/InApp/index.scss +4 -3
  54. package/v2Containers/InApp/messages.js +7 -3
  55. package/v2Containers/InApp/reducer.js +21 -3
  56. package/v2Containers/InApp/sagas.js +29 -9
  57. package/v2Containers/InApp/selectors.js +25 -5
  58. package/v2Containers/InApp/tests/index.test.js +154 -50
  59. package/v2Containers/InApp/tests/reducer.test.js +34 -0
  60. package/v2Containers/InApp/tests/sagas.test.js +61 -9
  61. package/v2Containers/InApp/tests/selectors.test.js +612 -0
  62. package/v2Containers/InAppWrapper/components/InAppWrapperView.js +162 -0
  63. package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +267 -0
  64. package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +9 -0
  65. package/v2Containers/InAppWrapper/constants.js +16 -0
  66. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +473 -0
  67. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +198 -0
  68. package/v2Containers/InAppWrapper/index.js +148 -0
  69. package/v2Containers/InAppWrapper/messages.js +49 -0
  70. package/v2Containers/InappAdvance/index.js +1006 -0
  71. package/v2Containers/InappAdvance/index.scss +10 -0
  72. package/v2Containers/InappAdvance/tests/index.test.js +448 -0
  73. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +3 -0
  74. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +2 -0
  75. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +2 -0
  76. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +9 -0
  77. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +12 -0
  78. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +4 -0
  79. package/v2Containers/TagList/index.js +65 -1
  80. package/v2Containers/Templates/_templates.scss +49 -1
  81. package/v2Containers/Templates/index.js +93 -5
  82. package/v2Containers/Templates/messages.js +4 -0
  83. package/v2Containers/Templates/reducer.js +20 -7
  84. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +8 -88
  85. package/v2Containers/Templates/tests/reducer.test.js +125 -0
  86. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +35 -0
@@ -37,14 +37,8 @@ import {
37
37
  import { VIBER, FACEBOOK } from '../../v2Containers/App/constants';
38
38
  import Carousel from '../Carousel';
39
39
  import whatsappMobileAndroid from './assets/images/whatsapp_mobile_android.svg';
40
- import inAppMobileAndroidModal from './assets/images/inapp_mobile_android_modal.svg';
41
- import inAppMobileAndroidTop from './assets/images/inapp_mobile_android_top.svg';
42
- import inAppMobileAndroidBottom from './assets/images/inapp_mobile_android_bottom.svg';
43
- import inAppMobileAndroidFull from './assets/images/inapp_mobile_android_full.svg';
44
- import inAppMobileIOSModal from './assets/images/inapp_mobile_ios_modal.svg';
45
- import inAppMobileIOSTop from './assets/images/inapp_mobile_ios_top.svg';
46
- import inAppMobileIOSBottom from './assets/images/inapp_mobile_ios_bottom.svg';
47
- import inAppMobileIOSFull from './assets/images/inapp_mobile_ios_full.svg';
40
+ import inAppMobileDeviceAndroid from '../../assets/Android.png';
41
+ import inAppMobileDeviceIos from '../../assets/iOS.png';
48
42
  import whatsappImageEmptyPreview from './assets/images/empty_image_preview.svg';
49
43
  import whatsappVideoEmptyPreview from './assets/images/empty_video_preview.svg';
50
44
  import videoPlay from '../../assets/videoPlay.svg';
@@ -239,7 +233,7 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
239
233
  } = this.props;
240
234
  let content = channel && channel.toLowerCase() === 'sms' ? [this.props.content] : this.props.content;
241
235
  const { formatMessage } = intl;
242
- const { rcsPreviewContent, inAppPreviewContent, viberPreviewContent } = content || {};
236
+ const { rcsPreviewContent, inAppPreviewContent, viberPreviewContent, isBeeFreeTemplate } = content || {};
243
237
  const { rcsImageSrc, rcsVideoSrc, rcsTitle, rcsDesc, rcsSuggestions } = rcsPreviewContent || {};
244
238
  const {
245
239
  videoParams,
@@ -247,7 +241,11 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
247
241
  buttonText: viberButtonText,
248
242
  messageContent: viberMessageContent,
249
243
  } = viberPreviewContent || {};
244
+ let isHTMLContent = true;
250
245
  const {mediaPreview = {}, templateTitle = "", templateMsg = "", ctaData} = inAppPreviewContent || {};
246
+ if(templateTitle !== undefined && ctaData !== undefined && templateMsg !== undefined) {
247
+ isHTMLContent = false;
248
+ }
251
249
  let smsDetails = {};
252
250
  // let smsText = '';
253
251
  if (this.props.content && this.props.charCounterEnabled) {
@@ -464,27 +462,9 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
464
462
 
465
463
  const getPreviewImage = () => {
466
464
  if (this.props.device === ANDROID) {
467
- switch (templateLayoutType) {
468
- case INAPP_MESSAGE_LAYOUT_TYPES.MODAL:
469
- return inAppMobileAndroidModal;
470
- case INAPP_MESSAGE_LAYOUT_TYPES.TOPBANNER:
471
- return inAppMobileAndroidTop;
472
- case INAPP_MESSAGE_LAYOUT_TYPES.BOTTOMBANNER:
473
- return inAppMobileAndroidBottom;
474
- default:
475
- return inAppMobileAndroidFull;
476
- }
465
+ return inAppMobileDeviceAndroid;
477
466
  } else {
478
- switch (templateLayoutType) {
479
- case INAPP_MESSAGE_LAYOUT_TYPES.MODAL:
480
- return inAppMobileIOSModal;
481
- case INAPP_MESSAGE_LAYOUT_TYPES.TOPBANNER:
482
- return inAppMobileIOSTop;
483
- case INAPP_MESSAGE_LAYOUT_TYPES.BOTTOMBANNER:
484
- return inAppMobileIOSBottom;
485
- default:
486
- return inAppMobileIOSFull;
487
- }
467
+ return inAppMobileDeviceIos;
488
468
  }
489
469
  };
490
470
 
@@ -1406,7 +1386,34 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
1406
1386
  </div>
1407
1387
  )}
1408
1388
  {channel?.toUpperCase() === INAPP && (
1409
- <div className="shell-v2 align-center">
1389
+ isBeeFreeTemplate ? (
1390
+ <div className="shell-v2 align-center">
1391
+ <div style={{ position: 'relative', display: 'inline-block', width: '100%', height: '100%' }}>
1392
+ <CapImage
1393
+ className="preview-image"
1394
+ src={this.props.device === ANDROID ? inAppMobileDeviceAndroid : inAppMobileDeviceIos}
1395
+ alt={formatMessage(messages.previewGenerated)}
1396
+ />
1397
+ <iframe
1398
+ srcDoc={inAppPreviewContent?.value}
1399
+ title={formatMessage(messages.inappPreview)}
1400
+ style={{
1401
+ position: 'absolute',
1402
+ top: '3rem',
1403
+ left: '5rem',
1404
+ width: '60%',
1405
+ height: '89%',
1406
+ zIndex: 1,
1407
+ pointerEvents: 'none',
1408
+ backgroundColor: 'white',
1409
+ borderRadius: `${CAP_SPACE_08}`,
1410
+ }}
1411
+ frameBorder="0"
1412
+ />
1413
+ </div>
1414
+ </div>
1415
+ ): (
1416
+ <div className="shell-v2 align-center">
1410
1417
  <CapImage
1411
1418
  className="preview-image"
1412
1419
  src={getPreviewImage()}
@@ -1414,9 +1421,15 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
1414
1421
  />
1415
1422
  <div className="preview-image">
1416
1423
  <div
1417
- className={`inapp-message-container-${templateLayoutType}-${device} sms`}
1424
+ className={`inapp-message-container-${templateLayoutType}-${device} inapp`}
1418
1425
  >
1419
- <div className="preview-inapp-screen">
1426
+ {isHTMLContent ? (
1427
+ <div
1428
+ className="inapp-html-content"
1429
+ dangerouslySetInnerHTML={{ __html: templateMsg }}
1430
+ />
1431
+ ) : (
1432
+ <div className="preview-inapp-screen">
1420
1433
  {
1421
1434
  <CapLabel
1422
1435
  type="label15"
@@ -1481,9 +1494,11 @@ export class TemplatePreview extends React.Component { // eslint-disable-line re
1481
1494
  </CapButton>
1482
1495
  )}
1483
1496
  </div>
1497
+ )}
1484
1498
  </div>
1485
1499
  </div>
1486
1500
  </div>
1501
+ )
1487
1502
  )}
1488
1503
  </CapRow>
1489
1504
  </CapColumn>
@@ -94,4 +94,8 @@ export default defineMessages({
94
94
  id: 'creatives.componentsV2.TemplatePreview.videoNotSupported',
95
95
  defaultMessage: 'Your browser does not support the video tag.',
96
96
  },
97
+ inappPreview: {
98
+ id: 'creatives.componentsV2.TemplatePreview.inappPreview',
99
+ defaultMessage: 'Inapp Preview',
100
+ },
97
101
  });
@@ -3,16 +3,14 @@
3
3
  * Beeeditor
4
4
  *
5
5
  */
6
- import React, { useEffect, useState, useRef, useCallback } from 'react';
6
+ import React, {
7
+ useEffect, useState, useRef, useCallback,
8
+ } from 'react';
7
9
  import PropTypes from 'prop-types';
8
10
  import { injectIntl, intlShape, FormattedMessage } from 'react-intl';
9
11
  import { connect } from 'react-redux';
10
- import TagList from '../TagList';
11
- import { bindActionCreators } from 'redux';
12
+ import { bindActionCreators, compose } from 'redux';
12
13
  import { createStructuredSelector } from 'reselect';
13
- import makeSelectBEE from './selectors';
14
- import { UserIsAuthenticated } from '../../utils/authWrapper';
15
- import config from '../../config/app';
16
14
  import { loadItem } from 'services/localStorageApi';
17
15
  import './index.scss';
18
16
  import CapModal from "@capillarytech/cap-ui-library/CapModal";
@@ -21,18 +19,18 @@ import CapInput from "@capillarytech/cap-ui-library/CapInput";
21
19
  import CapSelect from "@capillarytech/cap-ui-library/CapSelect";
22
20
  import CapSpin from "@capillarytech/cap-ui-library/CapSpin";
23
21
  import CapNotification from "@capillarytech/cap-ui-library/CapNotification";
24
- import CapAskAira from '@capillarytech/cap-ui-library/CapAskAira';
25
- import { request,getAPICallObject } from '../../services/api';
22
+ import config from '../../config/app';
23
+ import makeSelectBEE from './selectors';
26
24
  import messages from './messages';
27
25
  import * as beeActions from './actions';
28
- import injectSaga from '../../utils/injectSaga';
29
26
  import injectReducer from '../../utils/injectReducer';
30
27
  import { v2BeeEditionSagas } from './sagas';
31
28
  import v2BeeEditionReducer from './reducer';
32
- import { compose } from 'redux';
29
+
30
+ import TagList from '../TagList';
31
+ import injectSaga from '../../utils/injectSaga';
33
32
 
34
33
  import { selectCurrentOrgDetails } from '../Cap/selectors';
35
- import { ENABLE_AI_SUGGESTIONS } from './constants';
36
34
  function BeeEditor(props) {
37
35
  const {
38
36
  uid,
@@ -61,10 +59,10 @@ function BeeEditor(props) {
61
59
  const UNSUBSCRIBE = 'unsubscribe';
62
60
  let beePluginInstance = null;
63
61
  const categoryOptions = [{key: 'cta', value: 'cta', label: formatMessage(messages.cta)},
64
- {key: 'footer', value: 'footer', label: formatMessage(messages.footer)},
65
- {key: 'header', value: 'header', label: formatMessage(messages.header)},
66
- {key: 'sp', value: 'sp', label: formatMessage(messages.socialPlatform)},
67
- {key: 'others', value: 'others', label: formatMessage(messages.others)},
62
+ {key: 'footer', value: 'footer', label: formatMessage(messages.footer)},
63
+ {key: 'header', value: 'header', label: formatMessage(messages.header)},
64
+ {key: 'sp', value: 'sp', label: formatMessage(messages.socialPlatform)},
65
+ {key: 'others', value: 'others', label: formatMessage(messages.others)},
68
66
  ];
69
67
  const [visibleTaglist, setVisibleTaglist] = useState(false);
70
68
  const [showRowMetaModal, setRowMetaModal] = useState(false);
@@ -94,8 +92,8 @@ function BeeEditor(props) {
94
92
  locale = JSON.parse(user).lang;
95
93
  }
96
94
  const defaultFormattedUrl = locale !== DEFAULT_LOCALE && ['zh-cn', 'zh', 'jp', 'ja-JP'].includes(locale)
97
- ? `${API_ENDPOINT}/common/getBEECustomLangunage?langid=${MAPPED_LOCALE[locale]}`
98
- : "";
95
+ ? `${API_ENDPOINT}/common/getBEECustomLangunage?langid=${MAPPED_LOCALE[locale]}`
96
+ : "";
99
97
  useEffect(() => {
100
98
  savedCallback.current = Object.keys(selectedTag).length > 0 ? selectedTag : rowMetaInfo;
101
99
  }, [selectedTag, rowMetaInfo]);
@@ -246,70 +244,74 @@ function BeeEditor(props) {
246
244
  const onChangeCategoy = (e) => {
247
245
  setRowCategory(e);
248
246
  };
249
- const contentSection = <>
250
- <CapInput
251
- label={<FormattedMessage {...messages.rowName} />}
252
- placeholder={formatMessage(messages.rowPlaceHolder)}
253
- onChange={onRowChange}
254
- value={rowName}
255
- maxLength={50}
256
- style={{ width: 324, paddingBottom: 21 }}
257
- />
258
- <CapSelect
259
- label="Category"
260
- style={{ width: 324, paddingBottom: 24}}
261
- options={categoryOptions}
262
- value={rowCategory || undefined}
263
- placeholder={<FormattedMessage {...messages.selectCategoyPlaceholder} />}
264
- onChange={onChangeCategoy}
265
- />
247
+ const contentSection = (
248
+ <>
249
+ <CapInput
250
+ label={<FormattedMessage {...messages.rowName} />}
251
+ placeholder={formatMessage(messages.rowPlaceHolder)}
252
+ onChange={onRowChange}
253
+ value={rowName}
254
+ maxLength={50}
255
+ style={{ width: 324, paddingBottom: 21 }}
256
+ />
257
+ <CapSelect
258
+ label="Category"
259
+ style={{ width: 324, paddingBottom: 24}}
260
+ options={categoryOptions}
261
+ value={rowCategory || undefined}
262
+ placeholder={<FormattedMessage {...messages.selectCategoyPlaceholder} />}
263
+ onChange={onChangeCategoy}
264
+ />
266
265
 
267
- </>;
266
+ </>
267
+ );
268
268
  return (
269
- <CapSpin spinning={saveRowRequest || false}>
270
- <div id="bee-plugin-container" style={{ height: "650px" }}></div>
271
- <TagList
272
- moduleFilterEnabled={moduleFilterEnabled}
273
- label={label}
274
- onTagSelect={onTagSelect}
275
- location={location}
276
- tags={filteredTags}
277
- injectedTags={injectedTags}
278
- className={className}
279
- id={id}
280
- userLocale={userLocale}
281
- selectedOfferDetails={selectedOfferDetails}
282
- visibleTaglist={visibleTaglist}
283
- hidePopover
284
- modalProps={{
285
- onCancel: onCancelTagList,
286
- style: { left: 135, top: 250 },
287
- className: "bee-editor-tag-list",
288
- }}
289
- onContextChange={onContextChange}
290
- eventContextTags={eventContextTags}
291
- />
292
- <CapModal
293
- className="custom-row-modal"
294
- visible={showRowMetaModal}
295
- onCancel={onCustomRowCancel}
296
- title={formatMessage(messages.customRows)}
297
- style={{ width: 372, height: 296, left: 135, top: 300 }}
298
- footer={[
299
- <CapButton
300
- key="submit"
301
- type="primary"
302
- id="delete-version"
303
- onClick={onCustomRowSave}
304
- disabled={isDisableSave()}
305
- >
306
- {formatMessage(messages.done)}
307
- </CapButton>,
308
- ]}
309
- >
310
- {contentSection}
311
- </CapModal>
312
- </CapSpin>
269
+ <CapSpin spinning={saveRowRequest || false}>
270
+ <div id="bee-plugin-container" style={{ height: "650px" }}></div>
271
+ <TagList
272
+ moduleFilterEnabled={moduleFilterEnabled}
273
+ label={label}
274
+ onTagSelect={onTagSelect}
275
+ location={location}
276
+ tags={filteredTags}
277
+ injectedTags={injectedTags}
278
+ className={className}
279
+ id={id}
280
+ userLocale={userLocale}
281
+ selectedOfferDetails={selectedOfferDetails}
282
+ visibleTaglist={visibleTaglist}
283
+ hidePopover
284
+ modalProps={{
285
+ onCancel: onCancelTagList,
286
+ style: { left: 135, top: 250 },
287
+ className: "bee-editor-tag-list",
288
+ }}
289
+ onContextChange={onContextChange}
290
+ eventContextTags={eventContextTags}
291
+ />
292
+ <CapModal
293
+ className="custom-row-modal"
294
+ visible={showRowMetaModal}
295
+ onCancel={onCustomRowCancel}
296
+ title={formatMessage(messages.customRows)}
297
+ style={{
298
+ width: 372, height: 296, left: 135, top: 300,
299
+ }}
300
+ footer={[
301
+ <CapButton
302
+ key="submit"
303
+ type="primary"
304
+ id="delete-version"
305
+ onClick={onCustomRowSave}
306
+ disabled={isDisableSave()}
307
+ >
308
+ {formatMessage(messages.done)}
309
+ </CapButton>,
310
+ ]}
311
+ >
312
+ {contentSection}
313
+ </CapModal>
314
+ </CapSpin>
313
315
  );
314
316
  }
315
317
 
@@ -336,7 +338,7 @@ BeeEditor.propTypes = {
336
338
 
337
339
  const mapStateToProps = () => createStructuredSelector({
338
340
  BEESelect: makeSelectBEE(),
339
- currentOrgDetails: selectCurrentOrgDetails()
341
+ currentOrgDetails: selectCurrentOrgDetails(),
340
342
  });
341
343
 
342
344
  function mapDispatchToProps(dispatch) {
@@ -0,0 +1,10 @@
1
+ export const BEE_LAYOUT_OPTIONS = {
2
+ POPUP: "classic-center",
3
+ HEADER: "bar-top",
4
+ FOOTER: "bar-bottom",
5
+ FULLSCREEN: "classic-center",
6
+ };
7
+ export const MOBILE = "mobile";
8
+ export const UNSUBSCRIBE = 'unsubscribe';
9
+ export const ANDROID = 'ANDROID';
10
+ export const IOS = 'IOS';
@@ -0,0 +1,180 @@
1
+ import React, { useEffect, useRef, useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { injectIntl } from 'react-intl';
4
+ import { connect } from 'react-redux';
5
+ // import { bindActionCreators } from 'redux';
6
+ import { createStructuredSelector } from 'reselect';
7
+ import { UserIsAuthenticated } from '../../utils/authWrapper';
8
+ import TagList from '../TagList';
9
+ import {
10
+ ANDROID, BEE_LAYOUT_OPTIONS, MOBILE, UNSUBSCRIBE,
11
+ } from './constants';
12
+ import emptyAndroidSvg from '../../assets/Android.png';
13
+ import emptyIosSvg from '../../assets/iOS.png';
14
+ function BeePopupEditor(props) {
15
+ const {
16
+ uid,
17
+ id,
18
+ tokenData,
19
+ saveBeeInstance,
20
+ saveBeeData,
21
+ saveBeeHtmlValue,
22
+ beeJson,
23
+ templateLayoutType,
24
+ moduleFilterEnabled,
25
+ label,
26
+ location,
27
+ injectedTags,
28
+ className,
29
+ userLocale,
30
+ selectedOfferDetails,
31
+ tags,
32
+ onContextChange,
33
+ device,
34
+ } = props;
35
+
36
+ let beePluginInstance = null;
37
+ let intervalTimer;
38
+ const savedCallback = useRef();
39
+
40
+ const [visibleTaglist, setVisibleTaglist] = useState(false);
41
+ const [selectedTag, setSelectedTag] = useState({});
42
+ const filteredTags = (tags || []).filter((obj) => obj.definition.value !== UNSUBSCRIBE);
43
+
44
+ useEffect(() => {
45
+ const beeConfig = {
46
+ uid,
47
+ trackChanges: true,
48
+ container: 'bee-plugin-container',
49
+ workspace: {
50
+ popup: {
51
+ backgroundImageMobile: device === ANDROID ? emptyAndroidSvg : emptyIosSvg,
52
+ layout: BEE_LAYOUT_OPTIONS[templateLayoutType],
53
+ customStyles: {
54
+ container: {
55
+ width: "90%",
56
+ margin: "1.5rem",
57
+ },
58
+ },
59
+ },
60
+ stage: MOBILE,
61
+ hideStageToggle: true,
62
+ },
63
+ contentDialog: {
64
+ mergeTags: {
65
+ label: 'Add Label',
66
+ handler: async (resolve, reject) => {
67
+ // this will open tag modal
68
+ await setVisibleTaglist(true);
69
+ // until tag modal will not open promise will not execute
70
+ // once tag modal is opened it will start 2 sec interval to wait use has selected any tag or cancel the tag selection
71
+ const promise = new Promise((resolveP) => {
72
+ intervalTimer = setInterval(() => {
73
+ // this will execute, if user cancel the tag selection
74
+ if ((savedCallback.current || {}).close === true) {
75
+ reject();
76
+ clearInterval(intervalTimer);
77
+ return;
78
+ }
79
+ // this block is checking use has selected any tag or not
80
+ if (Object.keys(savedCallback.current || {}).length > 0) {
81
+ resolveP(savedCallback.current);
82
+ setSelectedTag({});
83
+ clearInterval(intervalTimer);
84
+ }
85
+ }, 2000);
86
+ });
87
+ // once prmise will resolve , pass the resolve data to handler to show tags in bee edior
88
+ const result = await promise;
89
+ resolve(result);
90
+ },
91
+ },
92
+ },
93
+ onChange: (jsonFile, htmlFile) => {
94
+ saveBeeData(jsonFile, htmlFile, device);
95
+ },
96
+ onSave: (jsonFile, htmlFile) => {
97
+ // onSave provides the actual HTML value, use it to update beeHtml.value
98
+ if (saveBeeHtmlValue && htmlFile) {
99
+ saveBeeHtmlValue(htmlFile, device);
100
+ }
101
+ // Also call saveBeeData to update JSON
102
+ saveBeeData(jsonFile, htmlFile, device);
103
+ },
104
+ };
105
+ window.BeePlugin.create(tokenData, beeConfig, (instance) => {
106
+ beePluginInstance = instance;
107
+ const parseJson = JSON.parse(beeJson);
108
+ beePluginInstance.start(parseJson);
109
+ saveBeeInstance(beePluginInstance, device);
110
+ });
111
+ return () => clearInterval(intervalTimer);
112
+ }, [templateLayoutType]);
113
+
114
+ useEffect(() => {
115
+ savedCallback.current = Object?.keys(selectedTag)?.length > 0 && selectedTag;
116
+ }, [selectedTag]);
117
+
118
+ const onTagSelect = (result) => {
119
+ const msg = {
120
+ name: result,
121
+ value: `{{${result}}}`,
122
+ };
123
+ setSelectedTag(msg);
124
+ setVisibleTaglist(false);
125
+ };
126
+
127
+ const onCancelTagList = () => {
128
+ setVisibleTaglist(false);
129
+ setSelectedTag({close: true});
130
+ };
131
+
132
+ return (
133
+ <>
134
+ <div id="bee-plugin-container" style={{ height: "46.5rem" }}></div>
135
+ <TagList
136
+ moduleFilterEnabled={moduleFilterEnabled}
137
+ label={label}
138
+ onTagSelect={onTagSelect}
139
+ location={location}
140
+ tags={filteredTags}
141
+ injectedTags={injectedTags}
142
+ className={className}
143
+ id={id}
144
+ userLocale={userLocale}
145
+ selectedOfferDetails={selectedOfferDetails}
146
+ visibleTaglist={visibleTaglist}
147
+ hidePopover
148
+ modalProps={{
149
+ onCancel: onCancelTagList,
150
+ style: { left: 135, top: 250 },
151
+ className: "bee-editor-tag-list",
152
+ }}
153
+ onContextChange={onContextChange}
154
+ />
155
+ </>
156
+ );
157
+ }
158
+ BeePopupEditor.propTypes = {
159
+ saveBeeData: PropTypes.func.isRequired,
160
+ saveBeeInstance: PropTypes.func.isRequired,
161
+ beeJson: PropTypes.object.isRequired,
162
+ tokenData: PropTypes.object.isRequired,
163
+ uid: PropTypes.string.isRequired,
164
+ templateLayoutType: PropTypes.string.isRequired,
165
+ id: PropTypes.string.isRequired,
166
+ moduleFilterEnabled: PropTypes.bool.isRequired,
167
+ label: PropTypes.string.isRequired,
168
+ location: PropTypes.object.isRequired,
169
+ injectedTags: PropTypes.array.isRequired,
170
+ className: PropTypes.string.isRequired,
171
+ userLocale: PropTypes.string.isRequired,
172
+ selectedOfferDetails: PropTypes.object.isRequired,
173
+ tags: PropTypes.array.isRequired,
174
+ onContextChange: PropTypes.func.isRequired,
175
+ device: PropTypes.string.isRequired,
176
+ };
177
+ const mapStateToProps = () => createStructuredSelector({});
178
+
179
+ function mapDispatchToProps() {}
180
+ export default UserIsAuthenticated(connect(mapStateToProps, mapDispatchToProps)(injectIntl(BeePopupEditor)));