@capillarytech/creatives-library 7.17.220 → 7.17.223-alpha.0

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.
@@ -110,3 +110,4 @@ export const BADGES_ISSUE = 'BADGES_ISSUE';
110
110
 
111
111
  export const CUSTOMER_BARCODE_TAG = "customer_barcode";
112
112
  export const COPY_OF = "Copy of";
113
+ export const ENTRY_TRIGGER_TAG_REGEX = /\bentryTrigger\.\w+(?:\.\w+)?(?:\(\w+\))?/g;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "7.17.220",
4
+ "version": "7.17.223-alpha.0",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -8,6 +8,7 @@
8
8
 
9
9
  import lodashForEach from 'lodash/forEach';
10
10
  import lodashCloneDeep from 'lodash/cloneDeep';
11
+ import { ENTRY_TRIGGER_TAG_REGEX } from '../containers/App/constants';
11
12
 
12
13
  const DEFAULT = 'default';
13
14
  const SUBTAGS = 'subtags';
@@ -17,7 +18,7 @@ const SUBTAGS = 'subtags';
17
18
  * @param {Object} response - The response object to check.
18
19
  * @param {Object} tagObject - The tagLookupMap.
19
20
  */
20
- export const checkSupport = (response = {}, tagObject = {}, eventContextTags = []) => {
21
+ export const checkSupport = (response = {}, tagObject = {}, eventContextTags = [], isLiquidFlow = false) => {
21
22
  const supportedList = [];
22
23
  // Verifies the presence of the tag in the 'Add Labels' section.
23
24
  // Incase of journey event context the tags won't be available in the tagObject(tagLookupMap).
@@ -25,6 +26,13 @@ export const checkSupport = (response = {}, tagObject = {}, eventContextTags = [
25
26
 
26
27
  // Verify if childTag is a valid sub-tag of parentTag from the 'Add Labels' section or if it's unsupported.
27
28
  const checkSubtags = (parentTag, childName) => {
29
+ // For event context tags the parentTag will be the event context tag name and subtags will be the child attributes for leaderboards
30
+ if (checkNameInTagObjectOrEventContext(parentTag) && isLiquidFlow && eventContextTags?.length) {
31
+ const childNameAfterDot = childName?.split(".")?.[1];
32
+ if (eventContextTags?.some((tag) => tag?.subTags?.includes(childNameAfterDot))) {
33
+ supportedList.push(childName);
34
+ }
35
+ }
28
36
  if (!tagObject?.[parentTag]) return false;
29
37
  let updatedChildName = childName;
30
38
  if (childName?.includes(".")) {
@@ -195,6 +203,10 @@ const indexOfEnd = (targetString, string) => {
195
203
  }
196
204
 
197
205
  export const skipTags = (tag) => {
206
+ // If the tag contains the word "entryTrigger.", then it's an event context tag and should not be skipped.
207
+ if (tag?.match(ENTRY_TRIGGER_TAG_REGEX)) {
208
+ return false;
209
+ }
198
210
  const regexGroups = ["dynamic_expiry_date_after_\\d+_days.FORMAT_\\d", "unsubscribe\\(#[a-zA-Z\\d]{6}\\)","Link_to_[a-zA-z]","SURVEY.*.TOKEN", "^[A-Za-z].*\\([a-zA-Z\\d]*\\)"];
199
211
  let skipped = false;
200
212
  lodashForEach(regexGroups, (group) => {
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import '@testing-library/jest-dom';
3
- import { checkSupport, extractNames, getTagMapValue, preprocessHtml, validateIfTagClosed,validateTags} from '../tagValidations';
3
+ import { checkSupport, extractNames, getTagMapValue, preprocessHtml, validateIfTagClosed,validateTags, skipTags } from '../tagValidations';
4
4
  import { eventContextTags } from '../../v2Containers/TagList/tests/mockdata';
5
5
 
6
6
  describe("check if curly brackets are balanced", () => {
@@ -51,7 +51,7 @@ describe("validateTags", () => {
51
51
  },
52
52
  ];
53
53
  it("should return valid response when all tags are present", () => {
54
- const content = "Hello {{tag1}}, {{tag2}}, {{tag3}} {{lifetimePurchases}}";
54
+ const content = "Hello {{tag1}}, {{tag2}}, {{tag3}} {{entryTrigger.lifetimePurchases}}";
55
55
 
56
56
  const injectedTagsParams = [];
57
57
  const location = { query: { module: "DEFAULT" } };
@@ -276,11 +276,11 @@ describe("checkSupport", () => {
276
276
 
277
277
  it("should return event context tags even if tagObject is empty", () => {
278
278
  const response = {
279
- data: [{ name: "tag1" }, { name: "lifetimePurchases" }],
279
+ data: [{ name: "tag1" }, { name: "entryTrigger.lifetimePurchases" }],
280
280
  };
281
281
  const tagObject = {};
282
282
  const result = checkSupport(response, tagObject, eventContextTags);
283
- expect(result).toEqual(['lifetimePurchases']);
283
+ expect(result).toEqual(['entryTrigger.lifetimePurchases']);
284
284
  });
285
285
 
286
286
  it("should return an array of supported tags", () => {
@@ -376,6 +376,34 @@ describe("checkSupport", () => {
376
376
  const result = checkSupport(response, {});
377
377
  expect(result).toEqual([]);
378
378
  });
379
+
380
+ it("should add childName to supportedList if it is a subtag of parentTag in eventContextTags", () => {
381
+ const response = { data: [{ name: "leaderboard", children: [{name: "person.userId"}]}]};
382
+ const tagObject = {};
383
+ const eventContextTags = [{ tagName: "leaderboard", subTags: ["userId"]}];
384
+ const isLiquidFlow = true;
385
+ const result = checkSupport(response, tagObject, eventContextTags, isLiquidFlow);
386
+ expect(result).toEqual( [ 'leaderboard', 'person.userId' ]);
387
+ });
388
+
389
+ it("should not add childName to supportedList which does not have dot in eventContextTags", () => {
390
+ // This case is unlikely to happen as we are not supporting tags without dot in eventContextTags
391
+ const response = { data: [{ name: "entryTrigger.lifetimePoints", children: [{name: "userId"}] }]};
392
+ const tagObject = {};
393
+ const eventContextTags = [{ tagName: "entryTrigger.lifetimePoints", children: [{name: "userId"}] }];
394
+ const isLiquidFlow = true;
395
+ const result = checkSupport(response, tagObject, eventContextTags, isLiquidFlow);
396
+ expect(result).toEqual( [ "entryTrigger.lifetimePoints" ]);
397
+ });
398
+
399
+ it("should add only parent tag to supportedList if isLiquidFlow false", () => {
400
+ const response = { data: [{ name: "leaderboard", children: [{name: "person.userId"}]}]};
401
+ const tagObject = {};
402
+ const eventContextTags = [{ tagName: "leaderboard", subTags: ["userId"]}];
403
+ const isLiquidFlow = false;
404
+ const result = checkSupport(response, tagObject, eventContextTags, isLiquidFlow);
405
+ expect(result).toEqual( [ 'leaderboard' ]);
406
+ });
379
407
  });
380
408
 
381
409
  describe('preprocessHtml', () => {
@@ -454,4 +482,18 @@ describe("getTagMapValue", () => {
454
482
  const result = getTagMapValue(object);
455
483
  expect(result).toEqual({ name: "233" });
456
484
  });
485
+ });
486
+
487
+ describe("skipTags", () => {
488
+ it("should return false for event context tags", () => {
489
+ const tag = "entryTrigger.uniqueTagPrefix(raindrops_match)";
490
+ const result = skipTags(tag);
491
+ expect(result).toEqual(false);
492
+ });
493
+
494
+ it("should return true for tags matching regex patterns", () => {
495
+ const tag = "voucher(12345)";
496
+ const result = skipTags(tag);
497
+ expect(result).toEqual(true);
498
+ });
457
499
  });
@@ -55,7 +55,7 @@ import { convert } from 'html-to-text';
55
55
  import { OUTBOUND } from './constants';
56
56
  import { GET_TRANSLATION_MAPPED } from '../../containers/TagList/constants';
57
57
  import moment from 'moment';
58
- import { CUSTOMER_BARCODE_TAG , COPY_OF} from '../../containers/App/constants';
58
+ import { CUSTOMER_BARCODE_TAG , COPY_OF, ENTRY_TRIGGER_TAG_REGEX} from '../../containers/App/constants';
59
59
  import { hasLiquidSupportFeature, isEmailUnsubscribeTagMandatory } from '../../utils/common';
60
60
  import { isUrl } from '../../v2Containers/Line/Container/Wrapper/utils';
61
61
  import { bindActionCreators } from 'redux';
@@ -1121,7 +1121,8 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
1121
1121
  const supportedLiquidTags = checkSupport(
1122
1122
  result,
1123
1123
  this.props?.metaEntities?.tagLookupMap,
1124
- this.props?.eventContextTags
1124
+ this.props?.eventContextTags,
1125
+ this.liquidFlow,
1125
1126
  );
1126
1127
  const unsupportedLiquidTags = extractedLiquidTags?.filter(
1127
1128
  (tag) => !supportedLiquidTags?.includes(tag) && !this.skipTags(tag)
@@ -1197,6 +1198,10 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
1197
1198
  };
1198
1199
 
1199
1200
  skipTags(tag) {
1201
+ // If the tag contains the word "entryTrigger.", then it's an event context tag and it should not be skipped.
1202
+ if (tag?.match(ENTRY_TRIGGER_TAG_REGEX)) {
1203
+ return false;
1204
+ }
1200
1205
  const regexGroups = ["dynamic_expiry_date_after_\\d+_days.FORMAT_\\d", "unsubscribe\\(#[a-zA-Z\\d]{6}\\)","Link_to_[a-zA-z]","SURVEY.*.TOKEN","^[A-Za-z].*\\([a-zA-Z\\d]*\\)"];
1201
1206
  //const regexGroups = [];
1202
1207
  let skipped = false;
@@ -104,24 +104,36 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
104
104
  this.transformCouponTags(selectedOfferDetails, tags);
105
105
  }
106
106
  }
107
+ // Journey event context tags also should be displayed in the Add Labels.
107
108
  if (eventContextTags?.length) {
108
- const TAG_HEADER_MSG_LABEL = this.props.intl.formatMessage(messages.tagsBasedOnEntryTriggerEvent);
109
- eventContextTagsObj.EventContextTags = {
109
+ const TAG_HEADER_MSG_LABEL = this.props.intl.formatMessage(messages.entryEvent);
110
+ eventContextTagsObj.eventContextTags = {
110
111
  name: TAG_HEADER_MSG_LABEL,
111
112
  desc: TAG_HEADER_MSG_LABEL,
112
113
  resolved: true,
113
114
  'tag-header': true,
114
115
  subtags: {},
115
116
  };
116
- // Journey event context tags also should be displayed in the Add Labels.
117
+
117
118
  eventContextTags.forEach((tag) => {
118
- if (tag?.tagName) {
119
- eventContextTagsObj.EventContextTags.subtags[tag?.tagName] = {
120
- name: tag?.tagName,
121
- desc: tag?.tagName,
122
- resolved: true
123
- }
119
+ const { tagName, label, profileId, profileName } = tag || {};
120
+
121
+ // Initializing the tags profile if it doesn't exist
122
+ if (!eventContextTagsObj?.eventContextTags?.subtags?.[profileId]) {
123
+ eventContextTagsObj.eventContextTags.subtags[profileId] = {
124
+ name: profileName,
125
+ desc: profileName,
126
+ resolved: true,
127
+ "tag-header": true,
128
+ subtags: {},
129
+ };
124
130
  }
131
+ // Adding the current tag to the profile group
132
+ eventContextTagsObj.eventContextTags.subtags[profileId].subtags[tagName] = {
133
+ name: label,
134
+ desc: label,
135
+ resolved: true,
136
+ };
125
137
  });
126
138
  }
127
139
  this.setState({tags: _.merge( {}, tags, injectedTags, eventContextTagsObj )});
@@ -11,8 +11,8 @@ export default defineMessages({
11
11
  id: `${scope}.header`,
12
12
  defaultMessage: 'This is TagList container !',
13
13
  },
14
- tagsBasedOnEntryTriggerEvent: {
15
- id: `${scope}.tagsBasedOnEntryTriggerEvent`,
16
- defaultMessage: 'Tags based on entry trigger event',
14
+ entryEvent: {
15
+ id: `${scope}.entryEvent`,
16
+ defaultMessage: 'Entry event',
17
17
  },
18
18
  });
@@ -41,12 +41,20 @@ describe("TagList test : UNIT", () => {
41
41
  addLabelBtnAssertion();
42
42
  });
43
43
 
44
- it('should render event context tags correctly from generateTags', () => {
44
+ it('should render event context tags correctly from generateTags and show tags under profile', () => {
45
45
  initializeTagList({eventContextTags});
46
46
  addLabelBtnAssertion();
47
- const EVENT_CONTEXT_TAG_HEADER = getByText('Tags based on entry trigger event');
47
+ const EVENT_CONTEXT_TAG_HEADER = getByText(/Entry event/i);
48
48
  expect(EVENT_CONTEXT_TAG_HEADER).toBeInTheDocument();
49
49
  fireEvent.click(EVENT_CONTEXT_TAG_HEADER);
50
- expect(getByText('lifetimePurchases')).toBeInTheDocument();
50
+ // Customer profile tags
51
+ const CUSTOMER_PROFILE = getByText(/Current Customer/i);
52
+ fireEvent.click(CUSTOMER_PROFILE);
53
+ expect(getByText(/lifetimePurchases/i)).toBeInTheDocument();
54
+
55
+ // Behavioural event profile tags
56
+ const BEHAVIOURAL_EVENT_PROFILE = getByText(/Behavioural event/i);
57
+ fireEvent.click(BEHAVIOURAL_EVENT_PROFILE);
58
+ expect(getByText(/raindrops/i)).toBeInTheDocument();
51
59
  });
52
60
  });
@@ -110,6 +110,8 @@ export const TagListData = {
110
110
  export const eventContextTags = [
111
111
  {
112
112
  "profileId": "BEHAVIOURAL_EVENT_PROFILE",
113
+ "profileName": "Behavioural event",
114
+ "label": "butterfly",
113
115
  "method": "getEventData",
114
116
  "field": "butterfly",
115
117
  "params": null,
@@ -129,6 +131,8 @@ export const eventContextTags = [
129
131
  },
130
132
  {
131
133
  "profileId": "BEHAVIOURAL_EVENT_PROFILE",
134
+ "profileName": "Behavioural event",
135
+ "label": 'raindrops',
132
136
  "method": "getEventData",
133
137
  "field": "raindrops",
134
138
  "params": null,
@@ -149,6 +153,7 @@ export const eventContextTags = [
149
153
  {
150
154
  "factId": "5LFP9e",
151
155
  "profileId": "CUSTOMER_PROFILE",
156
+ "profileName": "Current Customer",
152
157
  "params": [],
153
158
  "returnType": {
154
159
  "isList": false,
@@ -158,7 +163,8 @@ export const eventContextTags = [
158
163
  },
159
164
  "list": false
160
165
  },
161
- "tagName": "lifetimePurchases",
166
+ "tagName": "entryTrigger.lifetimePurchases",
167
+ "label": 'lifetimePurchases',
162
168
  "isTaggable": true,
163
169
  "uniqueId": "yW_DH7vjKk__BEHAVIOURAL__monsoon",
164
170
  "isDynamicFact": false