@capillarytech/creatives-library 6.3.3 → 6.3.5

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.
@@ -1,3 +1,5 @@
1
1
  export const GET_SIDEBAR_REQUEST = 'app/App/GET_SIDEBAR_REQUEST';
2
2
  export const GET_SIDEBAR_SUCCESS = 'app/App/GET_SIDEBAR_SUCCESS';
3
3
  export const GET_SIDEBAR_FAILURE = 'app/App/GET_SIDEBAR_FAILURE';
4
+
5
+ export const STORE2DOOR_PLUS_ENABLED = 'STORE2DOOR_PLUS_ENABLED';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "6.3.3",
4
+ "version": "6.3.5",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -13,7 +13,7 @@
13
13
  "license": "LicenseRef-LICENSE",
14
14
  "dependencies": {
15
15
  "@babel/polyfill": "7.4.3",
16
- "@capillarytech/cap-ui-utils": "1.2.3",
16
+ "@capillarytech/cap-ui-utils": "1.2.4",
17
17
  "babel-cli": "^6.26.0",
18
18
  "chalk": "1.1.3",
19
19
  "jquery": "^3.3.1",
package/services/api.js CHANGED
@@ -22,7 +22,7 @@ if (process.env.NODE_ENV === 'production') {
22
22
  }
23
23
  let requestCallerName = '';
24
24
  const isProd = process.env.NODE_ENV === 'production';
25
-
25
+ const { getCallerName, tracker } = GA;
26
26
  function parseJSON(response) {
27
27
  return response.json();
28
28
  }
@@ -62,7 +62,7 @@ function clearLocalStorage() {
62
62
  function checkStatus(response) {
63
63
  const { status, statusText } = response || {};
64
64
  if (status < 200 || status > 300) {
65
- GA.tracker.trackException({
65
+ tracker.trackException({
66
66
  description: `API Error ${requestCallerName} returned ${status}`,
67
67
  fatal: true,
68
68
  });
@@ -89,31 +89,7 @@ function request(url, options) {
89
89
  .then(checkStatus)
90
90
  .then(parseJSON);
91
91
  }
92
- const getCallerName = () => {
93
- let nameTrace;
94
- try {
95
- throw new Error();
96
- } catch (e) {
97
- // Error.prototype.stack Manually throw an error and catch the function name by tracing the stack
98
- //As per MDN, the use of Error.prototype.stack is discouraged because of it's non-standard behaviour and it's behaviour might change on different browsers
99
- //once we find better solution we will make the changes
100
- const stackLines = e.stack.split('\n');
101
- let callerIndex = 0;
102
- for (const i in stackLines) {
103
- if (stackLines.hasOwnProperty(i)) {
104
- if (!stackLines[i].match(/http[s]?:\/\//)) continue;
105
- callerIndex = Number(i) + 2;
106
- break;
107
- }
108
- }
109
- nameTrace = stackLines[callerIndex].match(/([^(]+)@|at ([^(]+) \(/);
110
- if (nameTrace === null) {
111
- callerIndex -= 2;
112
- nameTrace = stackLines[callerIndex].match(/([^(]+)@|at ([^(]+) \(/);
113
- }
114
- }
115
- return nameTrace !== null ? nameTrace[1] || nameTrace[2] : '';
116
- };
92
+
117
93
  function getAPICallObject(method, body, isFileUpload = false, loadCampaignHeaders = false) {
118
94
  const token = loadItem('token');
119
95
  const orgID = loadItem('orgID');
@@ -26,12 +26,15 @@
26
26
  "creatives.components.Footer.header": "This is the Footer component !",
27
27
  "creatives.components.FormBuilder.cancel": "Cancel",
28
28
  "creatives.components.FormBuilder.contentNotValidLanguage": "Content is not valid for language:",
29
+ "creatives.components.FormBuilder.genericTagsValidationError": "Please check the message content for unsupported/missing tags",
29
30
  "creatives.components.FormBuilder.header": "This is the FormBuilder component !",
30
31
  "creatives.components.FormBuilder.layoutSelection": "Layout Selection",
31
32
  "creatives.components.FormBuilder.loadingEDMTemplates": "Loading EDM Templates",
32
33
  "creatives.components.FormBuilder.missingTags": "Missing tags are:",
34
+ "creatives.components.FormBuilder.missingTagsValidationError": "Missing tags: {missingTags}. Please add them to this message.",
33
35
  "creatives.components.FormBuilder.ok": "Ok",
34
36
  "creatives.components.FormBuilder.unsupportedTags": "Unsupported tags are:",
37
+ "creatives.components.FormBuilder.unsupportedTagsValidationError": "Unsupported tags: {unsupportedTags}. Please remove them from this message.",
35
38
  "creatives.components.FormBuilder.yes": "Yes",
36
39
  "creatives.components.Header.cancel": "Cancel",
37
40
  "creatives.components.Header.enterTemplateName": "Enter template name*",
@@ -156,6 +159,7 @@
156
159
  "creatives.componentsV2.NewCallTask.done": "Done",
157
160
  "creatives.componentsV2.NewCallTask.messageHeader": "Message",
158
161
  "creatives.componentsV2.NewCallTask.personalisationTags": "Add Labels",
162
+ "creatives.componentsV2.NewCallTask.useInS2D": "Use in Store2Door",
159
163
  "creatives.componentsV2.PreviewSideBar.duplicate": "Duplicate",
160
164
  "creatives.componentsV2.PreviewSideBar.edit": "Edit",
161
165
  "creatives.componentsV2.PreviewSideBar.header": "This is the PreviewSideBar component !",
@@ -721,6 +725,18 @@
721
725
  "creatives.containers.WeChat.loadingEDMTemplates": "loading EDM Templates",
722
726
  "creatives.containers.WeChat.mapTemplateFooter": "Footer",
723
727
  "creatives.containers.WeChat.mapTemplateHeader": "Header",
728
+ "creatives.containers.WeChat.miniWeChatPlaceholder": "E.g. ab4892njkl4l2op",
729
+ "creatives.containers.WeChat.miniWechatIdError": "Mini-Program ID cannot be empty",
730
+ "creatives.containers.WeChat.miniWechatIdInductive": "Unique alpha numeric code for this specific app",
731
+ "creatives.containers.WeChat.miniWechatIdLabel": "Mini-Program ID",
732
+ "creatives.containers.WeChat.pagePathError": "Page path cannot be empty.",
733
+ "creatives.containers.WeChat.pagePathInductive": "User will be redirected to the Mini-Program path provided here",
734
+ "creatives.containers.WeChat.pagePathLabel": "Page path",
735
+ "creatives.containers.WeChat.pagePathPlaceholder": "E.g. pages/user/profile",
736
+ "creatives.containers.WeChat.redirectOptionMiniProgram": "Mini-Program",
737
+ "creatives.containers.WeChat.redirectOptionURL": "URL",
738
+ "creatives.containers.WeChat.redirectOptionsHeadingValue": "URL or Mini-Program",
739
+ "creatives.containers.WeChat.redirectionOptionError": "Please select a redirect option",
724
740
  "creatives.containers.WeChat.save": "Save",
725
741
  "creatives.containers.WeChat.selectWechatAccount": "Select wechat account",
726
742
  "creatives.containers.WeChat.selectWechatTemplate": "Select wechat template",
@@ -1420,11 +1436,24 @@
1420
1436
  "creatives.containersV2.WeChat.hasInvalidContent": "has invalid content.",
1421
1437
  "creatives.containersV2.WeChat.hasValidContent": "has valid content.",
1422
1438
  "creatives.containersV2.WeChat.header": "WeChat",
1439
+ "creatives.containersV2.WeChat.internalUrlLabel": "Is this internal url",
1423
1440
  "creatives.containersV2.WeChat.isInternalUrl": "Is this internal url",
1424
1441
  "creatives.containersV2.WeChat.link": "Link",
1425
1442
  "creatives.containersV2.WeChat.linkCantEmpty": "has valid content.",
1426
1443
  "creatives.containersV2.WeChat.linkErrorMessage": "Link cannot be empty.",
1444
+ "creatives.containersV2.WeChat.miniWeChatPlaceholder": "E.g. ab4892njkl4l2op",
1445
+ "creatives.containersV2.WeChat.miniWechatIdError": "Mini-Program ID cannot be empty",
1446
+ "creatives.containersV2.WeChat.miniWechatIdInductive": "Unique alpha numeric code for this specific app",
1447
+ "creatives.containersV2.WeChat.miniWechatIdLabel": "Mini-Program ID",
1427
1448
  "creatives.containersV2.WeChat.newWechat": "New wechat",
1449
+ "creatives.containersV2.WeChat.pagePathError": "Page path cannot be empty.",
1450
+ "creatives.containersV2.WeChat.pagePathInductive": "User will be redirected to the Mini-Program path provided here",
1451
+ "creatives.containersV2.WeChat.pagePathLabel": "Page path",
1452
+ "creatives.containersV2.WeChat.pagePathPlaceholder": "E.g. pages/user/profile",
1453
+ "creatives.containersV2.WeChat.redirectOptionMiniProgram": "Mini-Program",
1454
+ "creatives.containersV2.WeChat.redirectOptionURL": "URL",
1455
+ "creatives.containersV2.WeChat.redirectOptionsHeadingValue": "URL or Mini-Program",
1456
+ "creatives.containersV2.WeChat.redirectionOptionError": "Please select a redirect option",
1428
1457
  "creatives.containersV2.WeChat.save": "Save",
1429
1458
  "creatives.containersV2.WeChat.select": "Select",
1430
1459
  "creatives.containersV2.WeChat.selectWechatAccount": "Select wechat account",
@@ -1432,6 +1461,8 @@
1432
1461
  "creatives.containersV2.WeChat.somethingWentWrong": "Something went wrong!!",
1433
1462
  "creatives.containersV2.WeChat.tagsLabel": "Tags",
1434
1463
  "creatives.containersV2.WeChat.template": "Template",
1464
+ "creatives.containersV2.WeChat.templateLinkError": "Link cannot be empty.",
1465
+ "creatives.containersV2.WeChat.templateLinkLabel": "Link",
1435
1466
  "creatives.containersV2.WeChat.templateMapping": "Template mapping",
1436
1467
  "creatives.containersV2.WeChat.templateName": "Template Name",
1437
1468
  "creatives.containersV2.WeChat.wechatCreateSuccess": "WeChat template mapped successfully",
@@ -26,12 +26,15 @@
26
26
  "creatives.components.Footer.header": "",
27
27
  "creatives.components.FormBuilder.cancel": "",
28
28
  "creatives.components.FormBuilder.contentNotValidLanguage": "",
29
+ "creatives.components.FormBuilder.genericTagsValidationError": "",
29
30
  "creatives.components.FormBuilder.header": "",
30
31
  "creatives.components.FormBuilder.layoutSelection": "",
31
32
  "creatives.components.FormBuilder.loadingEDMTemplates": "",
32
33
  "creatives.components.FormBuilder.missingTags": "",
34
+ "creatives.components.FormBuilder.missingTagsValidationError": "",
33
35
  "creatives.components.FormBuilder.ok": "",
34
36
  "creatives.components.FormBuilder.unsupportedTags": "",
37
+ "creatives.components.FormBuilder.unsupportedTagsValidationError": "",
35
38
  "creatives.components.FormBuilder.yes": "",
36
39
  "creatives.components.Header.cancel": "",
37
40
  "creatives.components.Header.enterTemplateName": "",
@@ -156,6 +159,7 @@
156
159
  "creatives.componentsV2.NewCallTask.done": "",
157
160
  "creatives.componentsV2.NewCallTask.messageHeader": "",
158
161
  "creatives.componentsV2.NewCallTask.personalisationTags": "",
162
+ "creatives.componentsV2.NewCallTask.useInS2D": "",
159
163
  "creatives.componentsV2.PreviewSideBar.duplicate": "",
160
164
  "creatives.componentsV2.PreviewSideBar.edit": "",
161
165
  "creatives.componentsV2.PreviewSideBar.header": "",
@@ -721,6 +725,18 @@
721
725
  "creatives.containers.WeChat.loadingEDMTemplates": "",
722
726
  "creatives.containers.WeChat.mapTemplateFooter": "",
723
727
  "creatives.containers.WeChat.mapTemplateHeader": "",
728
+ "creatives.containers.WeChat.miniWeChatPlaceholder": "",
729
+ "creatives.containers.WeChat.miniWechatIdError": "",
730
+ "creatives.containers.WeChat.miniWechatIdInductive": "",
731
+ "creatives.containers.WeChat.miniWechatIdLabel": "",
732
+ "creatives.containers.WeChat.pagePathError": "",
733
+ "creatives.containers.WeChat.pagePathInductive": "",
734
+ "creatives.containers.WeChat.pagePathLabel": "",
735
+ "creatives.containers.WeChat.pagePathPlaceholder": "",
736
+ "creatives.containers.WeChat.redirectOptionMiniProgram": "",
737
+ "creatives.containers.WeChat.redirectOptionURL": "",
738
+ "creatives.containers.WeChat.redirectOptionsHeadingValue": "",
739
+ "creatives.containers.WeChat.redirectionOptionError": "",
724
740
  "creatives.containers.WeChat.save": "",
725
741
  "creatives.containers.WeChat.selectWechatAccount": "",
726
742
  "creatives.containers.WeChat.selectWechatTemplate": "",
@@ -1420,11 +1436,24 @@
1420
1436
  "creatives.containersV2.WeChat.hasInvalidContent": "",
1421
1437
  "creatives.containersV2.WeChat.hasValidContent": "",
1422
1438
  "creatives.containersV2.WeChat.header": "",
1439
+ "creatives.containersV2.WeChat.internalUrlLabel": "",
1423
1440
  "creatives.containersV2.WeChat.isInternalUrl": "",
1424
1441
  "creatives.containersV2.WeChat.link": "",
1425
1442
  "creatives.containersV2.WeChat.linkCantEmpty": "",
1426
1443
  "creatives.containersV2.WeChat.linkErrorMessage": "",
1444
+ "creatives.containersV2.WeChat.miniWeChatPlaceholder": "",
1445
+ "creatives.containersV2.WeChat.miniWechatIdError": "",
1446
+ "creatives.containersV2.WeChat.miniWechatIdInductive": "",
1447
+ "creatives.containersV2.WeChat.miniWechatIdLabel": "",
1427
1448
  "creatives.containersV2.WeChat.newWechat": "",
1449
+ "creatives.containersV2.WeChat.pagePathError": "",
1450
+ "creatives.containersV2.WeChat.pagePathInductive": "",
1451
+ "creatives.containersV2.WeChat.pagePathLabel": "",
1452
+ "creatives.containersV2.WeChat.pagePathPlaceholder": "",
1453
+ "creatives.containersV2.WeChat.redirectOptionMiniProgram": "",
1454
+ "creatives.containersV2.WeChat.redirectOptionURL": "",
1455
+ "creatives.containersV2.WeChat.redirectOptionsHeadingValue": "",
1456
+ "creatives.containersV2.WeChat.redirectionOptionError": "",
1428
1457
  "creatives.containersV2.WeChat.save": "",
1429
1458
  "creatives.containersV2.WeChat.select": "",
1430
1459
  "creatives.containersV2.WeChat.selectWechatAccount": "",
@@ -1432,6 +1461,8 @@
1432
1461
  "creatives.containersV2.WeChat.somethingWentWrong": "",
1433
1462
  "creatives.containersV2.WeChat.tagsLabel": "",
1434
1463
  "creatives.containersV2.WeChat.template": "",
1464
+ "creatives.containersV2.WeChat.templateLinkError": "",
1465
+ "creatives.containersV2.WeChat.templateLinkLabel": "",
1435
1466
  "creatives.containersV2.WeChat.templateMapping": "",
1436
1467
  "creatives.containersV2.WeChat.templateName": "",
1437
1468
  "creatives.containersV2.WeChat.wechatCreateSuccess": "",
package/utils/common.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import _ from 'lodash';
2
+ import { Auth } from '@capillarytech/cap-ui-utils';
3
+ import { STORE2DOOR_PLUS_ENABLED } from '../containers/App/constants';
2
4
 
3
5
  export function getUserNameById(userId, allUserList) {
4
6
  let userName = "";
@@ -30,3 +32,8 @@ export function removeLinksFromHtmlContent(content) {
30
32
  doc.remove();
31
33
  return copyContent;
32
34
  }
35
+
36
+ export const hasStore2DoorFeature = Auth.hasFeatureAccess.bind(
37
+ null,
38
+ STORE2DOOR_PLUS_ENABLED,
39
+ );
@@ -15,6 +15,7 @@ import TagList from '../../v2Containers/TagList';
15
15
  import CallTaskPreview from '../CallTaskPreview';
16
16
  import messages from './messages';
17
17
  import './_newCallTask.scss';
18
+ import { hasStore2DoorFeature } from '../../utils/common';
18
19
 
19
20
  const CALL = 'CALL';
20
21
  const STOREMAX_WHATSAPP = 'STOREMAX_WHATSAPP';
@@ -102,6 +103,7 @@ class NewCallTask extends React.Component { // eslint-disable-line react/prefer-
102
103
  const { formatMessage } = intl;
103
104
  const { subject, messageBody, description, callTaskActionType } = this.state;
104
105
  const tags = metaEntities && metaEntities.tags ? metaEntities.tags.standard : [];
106
+ const isStore2DoorEnabled = hasStore2DoorFeature();
105
107
  return (
106
108
  <CapSpin spinning={isLoading}>
107
109
  <CapRow gutter={16}>
@@ -138,13 +140,13 @@ class NewCallTask extends React.Component { // eslint-disable-line react/prefer-
138
140
  value={description}
139
141
  isRequired
140
142
  />
141
- <CapCheckbox
143
+ {isStore2DoorEnabled && <CapCheckbox
142
144
  onChange={this.onS2DCheckChange}
143
145
  checked={callTaskActionType === STOREMAX_WHATSAPP}
144
146
  style={{marginTop: FONT_SIZE_S}}
145
147
  >
146
148
  <FormattedMessage {...messages.useInS2D}/>
147
- </CapCheckbox>
149
+ </CapCheckbox>}
148
150
  </div>
149
151
  <CapButton
150
152
  disabled={!subject || !messageBody || !description}
@@ -18,6 +18,7 @@ export const TRACK_CREATE_EMAIL = 'createEmail';
18
18
  export const TRACK_CREATE_MPUSH = 'createMpush';
19
19
  export const TRACK_CREATE_WECHAT = 'createWeChat';
20
20
  export const TRACK_CREATE_IMAGE = 'createImage';
21
+ export const TRACK_CREATE_LINE = 'createLine';
21
22
 
22
23
 
23
24
  export const TRACK_EDIT_SMS = 'editSms';
@@ -25,6 +26,7 @@ export const TRACK_EDIT_EMAIL = 'editEmail';
25
26
  export const TRACK_EDIT_MPUSH = 'editMpush';
26
27
  export const TRACK_EDIT_WECHAT = 'editWeChat';
27
28
  export const TRACK_EDIT_IMAGE = 'editImage';
29
+ export const TRACK_EDIT_LINE = 'editLine';
28
30
 
29
31
  export const CHANNEL_CREATE_TRACK_MAPPING = {
30
32
  sms: TRACK_CREATE_SMS,
@@ -32,6 +34,7 @@ export const CHANNEL_CREATE_TRACK_MAPPING = {
32
34
  mobilepush: TRACK_CREATE_MPUSH,
33
35
  wechat: TRACK_CREATE_WECHAT,
34
36
  gallery: TRACK_CREATE_IMAGE,
37
+ line: TRACK_CREATE_LINE,
35
38
  };
36
39
 
37
40
  export const CHANNEL_EDIT_TRACK_MAPPING = {
@@ -40,5 +43,6 @@ export const CHANNEL_EDIT_TRACK_MAPPING = {
40
43
  mobilepush: TRACK_EDIT_MPUSH,
41
44
  wechat: TRACK_EDIT_WECHAT,
42
45
  gallery: TRACK_EDIT_IMAGE,
46
+ line: TRACK_EDIT_LINE,
43
47
  };
44
48
  export const GTM_TRACKING_ID = 'UA-110024621-2';
@@ -35,7 +35,7 @@ const CapWrapper = styled.div`
35
35
  padding: 0;
36
36
  flex-direction: column;
37
37
  `;
38
- GA.initialize({ accessKey: GTM_TRACKING_ID, trackUIError: true });
38
+ GA.initialize({ accessKey: GTM_TRACKING_ID, trackUIError: true, trackLoadPerformance: 'creatives' });
39
39
 
40
40
 
41
41
  export class Cap extends React.Component { // eslint-disable-line react/prefer-stateless-function
@@ -624,11 +624,17 @@ export class Email extends React.Component { // eslint-disable-line react/prefer
624
624
  });
625
625
  }
626
626
  onUpdateTemplateComplete = (createResponse) => {
627
- const isEdit = this.state.isEdit;
627
+ const {isEdit, formData = {} } = this.state || {};
628
+ const base = formData.base || {};
629
+ const isDragDrop = _.get(base[base.activeTab], 'is_drag_drop', false);
630
+ let editorType = 'ckEditor';
631
+ if ( isDragDrop ) {
632
+ editorType = 'edmEditor';
633
+ }
628
634
  GA.timeTracker.stopTimer(isEdit ? TRACK_EDIT_EMAIL : TRACK_CREATE_EMAIL, {
629
635
  category: 'Creatives',
630
636
  action: isEdit ? TRACK_EDIT_EMAIL : TRACK_CREATE_EMAIL,
631
- label: 'using editor',
637
+ label: `using ${editorType}`,
632
638
  });
633
639
  if (createResponse && createResponse.templateId) {
634
640
  // this.resetSchema();
@@ -7,6 +7,7 @@ import { intlShape } from 'react-intl';
7
7
  import { createStructuredSelector } from 'reselect';
8
8
  import _ from 'lodash';
9
9
  import { CapSpin, CapHeading, CapRow, CapColumn, CapNotification } from '@capillarytech/cap-ui-library';
10
+ import { GA } from '@capillarytech/cap-ui-utils';
10
11
  import messages from './messages';
11
12
  import * as actions from './actions';
12
13
  import Gallery from '../../Assets/Gallery';
@@ -23,6 +24,7 @@ import {
23
24
  LINE_IMG_WIDTH,
24
25
  LINE_IMG_SIZE,
25
26
  } from './constants';
27
+ import { TRACK_CREATE_LINE, TRACK_EDIT_LINE } from '../../App/constants';
26
28
 
27
29
  export class Line extends Component {
28
30
  constructor(props) {
@@ -521,18 +523,36 @@ export class Line extends Component {
521
523
  } = this.props;
522
524
  const { text, originalContentUrl, image } = get(obj, "versions.base.content.messages[0]", {});
523
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;
524
529
  if ((text || originalContentUrl || image) && (isFullMode ? name : true)) {
525
530
  if (!isFullMode) {
526
531
  saveMessage();
527
532
  } else if (this.state.isEdit) {
528
533
  actions.editTemplate(obj, () => {
534
+ // stop timer for edit line
535
+ stopTimer(type, {
536
+ category: 'Creatives',
537
+ action: type,
538
+ label: modeType,
539
+ });
529
540
  this.setEditSuccessMessage();
530
541
  onCreateComplete();
531
542
  });
532
543
  } else {
533
544
  actions.createTemplate(
534
545
  obj,
535
- onCreateComplete
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
+ }
536
556
  );
537
557
  }
538
558
  }
@@ -971,7 +971,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
971
971
  break;
972
972
  }
973
973
  };
974
-
974
+
975
975
  createTemplate(ev) {
976
976
  const type = this.props.location.query.type;
977
977
  const module = this.props.location.query.module ? this.props.location.query.module : 'default';