@capillarytech/creatives-library 7.17.197 → 7.17.199

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "7.17.197",
4
+ "version": "7.17.199",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
@@ -1,8 +1,11 @@
1
1
  import React from 'react';
2
2
  import { FormattedMessage } from 'react-intl';
3
+ import get from 'lodash/get';
4
+ import { EMBEDDED } from '../v2Containers/Whatsapp/constants';
5
+ import { EDIT, PREVIEW } from '../v2Containers/App/constants';
3
6
 
4
7
  export const apiMessageFormatHandler = (id, fallback) => (
5
- <FormattedMessage id={id} defaultMessage={fallback} />
8
+ <FormattedMessage id={id} defaultMessage={fallback} />
6
9
  );
7
10
 
8
11
  export const addBaseToTemplate = (template) => {
@@ -20,3 +23,6 @@ export const addBaseToTemplate = (template) => {
20
23
  }
21
24
  return template;
22
25
  };
26
+
27
+ export const isEmbeddedEditOrPreview = (queryType, creativesMode) => queryType === EMBEDDED.toLowerCase() &&
28
+ (creativesMode === EDIT.toLowerCase() || creativesMode === PREVIEW.toLowerCase());
@@ -1,7 +1,11 @@
1
1
  import "@testing-library/jest-dom";
2
+ import get from 'lodash/get';
2
3
  import { getTreeStructuredTags } from "../common";
3
4
  import * as mockdata from "./common.mockdata";
4
- import { addBaseToTemplate } from "../commonUtils";
5
+ import { addBaseToTemplate, isEmbeddedEditOrPreview } from "../commonUtils";
6
+ import { EMBEDDED, FULL } from "../../v2Containers/Whatsapp/constants";
7
+ import { CREATE, EDIT, PREVIEW } from "../../v2Containers/App/constants";
8
+ import { query } from "express";
5
9
 
6
10
  jest.mock('@capillarytech/cap-ui-utils', () => ({
7
11
  Auth: {
@@ -12,6 +16,8 @@ jest.mock('@capillarytech/cap-ui-utils', () => ({
12
16
  },
13
17
  }));
14
18
 
19
+ jest.mock('lodash/get');
20
+
15
21
  describe("common utils test", () => {
16
22
  it("test for getTreeStructuredTags when tagsList is not empty", () => {
17
23
  expect(getTreeStructuredTags({tagsList: mockdata.tagsList})).toEqual(mockdata.output2);
@@ -77,3 +83,33 @@ describe('addBaseToTemplate', () => {
77
83
  expect(template).toEqual(originalTemplateCopy);
78
84
  });
79
85
  });
86
+
87
+ describe('isEmbeddedEditOrPreview', () => {
88
+ beforeEach(() => {
89
+ get.mockClear();
90
+ });
91
+
92
+ it('should return true when query type is embedded and creatives mode is edit', () => {
93
+ const queryType = EMBEDDED;
94
+ const creativesMode = EDIT;
95
+ expect(isEmbeddedEditOrPreview(queryType, creativesMode)).toBe(true);
96
+ });
97
+
98
+ it('should return true when query type is embedded and creatives mode is preview', () => {
99
+ const queryType = EMBEDDED;
100
+ const creativesMode = PREVIEW;
101
+ expect(isEmbeddedEditOrPreview(queryType, creativesMode)).toBe(true);
102
+ });
103
+
104
+ it('should return false when query type is not embedded', () => {
105
+ const queryType = FULL;
106
+ const creativesMode = PREVIEW;
107
+ expect(isEmbeddedEditOrPreview(queryType, creativesMode)).toBe(false);
108
+ });
109
+
110
+ it('should return false when creatives mode is not edit or preview', () => {
111
+ const queryType = EMBEDDED;
112
+ const creativesMode = CREATE;
113
+ expect(isEmbeddedEditOrPreview(queryType, creativesMode)).toBe(false);
114
+ });
115
+ });
@@ -154,6 +154,7 @@ export function SlideBoxContent(props) {
154
154
  getCmsTemplatesInProgress = false,
155
155
  moduleType,
156
156
  showLiquidErrorInFooter,
157
+ creativesMode,
157
158
  } = props;
158
159
  const type = (messageDetails.type || '').toLowerCase(); // type is context in get tags values : outbound | dvs | referral | loyalty | coupons
159
160
  const query = { type: !isFullMode && 'embedded', module: isFullMode ? 'default' : 'library', isEditFromCampaigns: (templateData || {}).isEditFromCampaigns};
@@ -655,6 +656,7 @@ export function SlideBoxContent(props) {
655
656
  onTestContentClicked={onTestContentClicked}
656
657
  type={type}
657
658
  hideTestAndPreviewBtn={hideTestAndPreviewBtn}
659
+ creativesMode={creativesMode}
658
660
  />
659
661
  }
660
662
  {isCreateMPush &&
@@ -921,5 +923,6 @@ SlideBoxContent.propTypes = {
921
923
  getCmsTemplatesInProgress: PropTypes.bool,
922
924
  moduleType: PropTypes.string,
923
925
  showLiquidErrorInFooter: PropTypes.bool,
926
+ creativesMode: PropTypes.string,
924
927
  };
925
928
  export default SlideBoxContent;
@@ -1312,7 +1312,8 @@ export class Creatives extends React.Component {
1312
1312
  getCmsTemplatesInProgress={this.props.Templates?.getCmsTemplatesInProgress}
1313
1313
  moduleType={this.props.messageDetails?.type}
1314
1314
  showLiquidErrorInFooter={this.showLiquidErrorInFooter}
1315
- />
1315
+ creativesMode={creativesMode} // An existing prop that we're using here. Required to ensure correct account details in Edit or Preview in case of Embedded mode.
1316
+ />
1316
1317
  }
1317
1318
  footer={this.shouldShowFooter() &&
1318
1319
  <SlideBoxFooter
@@ -33,3 +33,5 @@ export const GET_WECRM_ACCOUNTS_FAILURE = "app/v2Containers/MobilePush/GET_WECRM
33
33
  export const GET_MOBILEPUSH_TEMPLATES_LIST_REQUEST = 'app/v2Containers/WeChat/GET_MOBILEPUSH_TEMPLATES_LIST_REQUEST';
34
34
  export const GET_MOBILEPUSH_TEMPLATES_LIST_SUCCESS = 'app/v2Containers/WeChat/GET_MOBILEPUSH_TEMPLATES_LIST_SUCCESS';
35
35
  export const GET_MOBILEPUSH_TEMPLATES_LIST_FAILURE = 'app/v2Containers/WeChat/GET_MOBILEPUSH_TEMPLATES_LIST_FAILURE';
36
+
37
+ export const MAPP_SDK = 'MAPP_SDK';
@@ -34,6 +34,8 @@ import { GA } from '@capillarytech/cap-ui-utils';
34
34
  import { EDIT, TRACK_EDIT_MPUSH } from '../../App/constants';
35
35
  import { MOBILE_PUSH } from '../../CreativesContainer/constants';
36
36
  import { getCdnUrl } from '../../../utils/cdnTransformation';
37
+ import { MAPP_SDK } from './constants';
38
+ import { isEmbeddedEditOrPreview } from '../../../utils/commonUtils';
37
39
 
38
40
  const PrefixWrapper = styled.div`
39
41
  margin-right: 16px;
@@ -105,11 +107,25 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
105
107
  } else if (nextProps.isGetFormData && this.props.isGetFormData !== nextProps.isGetFormData && this.props.isFullMode && !this.props.Create.createTemplateInProgress) {
106
108
  this.startValidation();
107
109
  }
108
- const selectedWeChatAccount = (!_.isEmpty(this.props.Templates.selectedWeChatAccount) ? this.props.Templates.selectedWeChatAccount :
109
- (!_.isEmpty(this.props.Edit.selectedWeChatAccount) ? this.props.Edit.selectedWeChatAccount : nextProps.Edit.selectedWeChatAccount));
110
+ let selectedWeChatAccount = {};
111
+ const queryType = String(get(this.props, 'location.query.type', ''))?.toLowerCase();
112
+ const creativesMode = String(get(this.props, 'creativesMode', ''))?.toLowerCase();
113
+ if (isEmbeddedEditOrPreview(queryType, creativesMode)) {
114
+ selectedWeChatAccount = !_.isEmpty(this.props.Edit.selectedWeChatAccount)
115
+ ? this.props.Edit.selectedWeChatAccount
116
+ : nextProps.Edit.selectedWeChatAccount;
117
+ } else if (!_.isEmpty(this.props.Templates.selectedWeChatAccount)) {
118
+ selectedWeChatAccount = this.props.Templates.selectedWeChatAccount;
119
+ }
120
+
110
121
  if (this.props.location.query.type === 'embedded' && !nextProps.Edit.fetchingWeCrmAccounts && !_.isEqual(this.props.Edit.weCrmAccounts, nextProps.Edit.weCrmAccounts) && (!selectedWeChatAccount || _.isEmpty(selectedWeChatAccount))) {
111
122
  this.setMobilePushAccountOptions(nextProps.Edit.weCrmAccounts, get(this.props, "templateData.definition.accountId"));
112
123
  }
124
+ // Check if the query type is 'embedded' and the creatives mode is either 'edit' or 'preview'. Also, ensure that the selected WeChat account ID is not equal to the account ID in the template details.
125
+ // If all conditions are met, set the mobile push account options using the provided weCrmAccounts and the account ID from templateData.
126
+ if (isEmbeddedEditOrPreview(queryType, creativesMode) && !_.isEqual(this.props.Edit.selectedWeChatAccount?.id, this.props.Edit.templateDetails?.definition?.accountId)) {
127
+ this.setMobilePushAccountOptions(nextProps.Edit.weCrmAccounts, get(this.props, "templateData.definition.accountId"));
128
+ }
113
129
  if (!_.isEmpty(nextProps.Edit.selectedWeChatAccount) && !_.isEqual(this.props.Edit.selectedWeChatAccount, nextProps.Edit.selectedWeChatAccount) && (this.props.location.query.type === 'embedded') && this.props.location.query.module === "loyalty") {
114
130
  const params = {
115
131
  name: '',
@@ -213,8 +229,22 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
213
229
  }
214
230
  };
215
231
 
232
+ getWeChatAccount = () => {
233
+ let selectedWeChatAccount = {};
234
+ const queryType = String(get(this.props, 'location.query.type', ''))?.toLowerCase();
235
+ const creativesMode = String(get(this.props, 'creativesMode', ''))?.toLowerCase();
236
+ if (isEmbeddedEditOrPreview(queryType, creativesMode)) {
237
+ selectedWeChatAccount = !_.isEmpty(this.props.Edit.selectedWeChatAccount)
238
+ ? this.props.Edit.selectedWeChatAccount
239
+ : this.props.Templates.selectedWeChatAccount;
240
+ } else if (!_.isEmpty(this.props.Templates.selectedWeChatAccount)) {
241
+ selectedWeChatAccount = this.props.Templates.selectedWeChatAccount;
242
+ }
243
+ return selectedWeChatAccount;
244
+ }
245
+
216
246
  onLinkTypeChange = (eventTriggered, formData, field, currentTab, inputSchema) => {
217
- const selectedWeChatAccount = (!_.isEmpty(this.props.Templates.selectedWeChatAccount) ? this.props.Templates.selectedWeChatAccount : this.props.Edit.selectedWeChatAccount);
247
+ const selectedWeChatAccount = this.getWeChatAccount();
218
248
  const schema = inputSchema ? _.cloneDeep(inputSchema) : _.cloneDeep(this.state.schema);
219
249
  const tabIndex = currentTab || this.state.currentTab;
220
250
  const inputFields = get(schema, `containers[0].panes[${tabIndex - 1}].sections[0].childSections[0].childSections[0].inputFields`);
@@ -330,27 +360,41 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
330
360
  this.setState({formData, accountsOptions: accounts.map((acc) => ({key: acc.id, label: acc.name, value: acc.id}))});
331
361
  };
332
362
 
363
+ createDefinition = (account) => ({
364
+ accountId: account?.id,
365
+ licenseCode: account?.sourceAccountIdentifier,
366
+ gatewayId: account?.configs?.gatewayId,
367
+ gatewayAccountId: account?.configs?.gatewayAccountId,
368
+ sourceType: account?.sourceTypeName,
369
+ });
370
+
333
371
  getTransformedData = (formData) => {
334
- const selectedWeChatAccount = (!_.isEmpty(this.props.Templates.selectedWeChatAccount) ? this.props.Templates.selectedWeChatAccount : this.props.Edit.selectedWeChatAccount);
372
+ const selectedWeChatAccount = this.getWeChatAccount();
335
373
  const obj = _.cloneDeep(this.state.editData);
336
374
  obj.versions = {
337
375
  base: {},
338
376
  };
339
377
  obj.type = 'MOBILEPUSH';
340
378
  obj.name = formData['template-name'];
341
- if(this.props?.Templates?.selectedWeChatAccount?.sourceTypeName === 'MAPP_SDK') {
342
- obj.definition = {
343
- accountId: selectedWeChatAccount.id,
344
- licenseCode: selectedWeChatAccount.sourceAccountIdentifier,
345
- gatewayId: selectedWeChatAccount.configs.gatewayId,
346
- gatewayAccountId: selectedWeChatAccount.configs.gatewayAccountId,
347
- sourceType: selectedWeChatAccount.sourceTypeName,
348
- };
379
+ const queryType = String(get(this.props, 'location.query.type', ''))?.toLowerCase();
380
+ const creativesMode = String(get(this.props, 'creativesMode', ''))?.toLowerCase();
381
+ if (isEmbeddedEditOrPreview(queryType, creativesMode)) {
382
+ if (get(this.props, 'Edit.selectedWeChatAccount.sourceTypeName') === MAPP_SDK) {
383
+ obj.definition = this.createDefinition(selectedWeChatAccount);
384
+ } else {
385
+ obj.definition = {
386
+ accountId: selectedWeChatAccount?.id,
387
+ licenseCode: selectedWeChatAccount?.sourceAccountIdentifier,
388
+ sourceType: selectedWeChatAccount?.sourceTypeName,
389
+ };
390
+ }
391
+ } else if (get(this.props, 'Templates.selectedWeChatAccount.sourceTypeName') === MAPP_SDK) {
392
+ obj.definition = this.createDefinition(selectedWeChatAccount);
349
393
  } else {
350
394
  obj.definition = {
351
395
  accountId: selectedWeChatAccount?.id,
352
- licenseCode: selectedWeChatAccount.sourceAccountIdentifier,
353
- sourceType: selectedWeChatAccount.sourceTypeName,
396
+ licenseCode: selectedWeChatAccount?.sourceAccountIdentifier,
397
+ sourceType: selectedWeChatAccount?.sourceTypeName,
354
398
  };
355
399
  }
356
400
  if (this.props.location.query && this.props.location.query.module !== 'dvs') {
@@ -561,7 +605,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
561
605
  };
562
606
 
563
607
  getLinkName = (link) => {
564
- const selectedWeChatAccount = (!_.isEmpty(this.props.Templates.selectedWeChatAccount) ? this.props.Templates.selectedWeChatAccount : this.props.Edit.selectedWeChatAccount);
608
+ const selectedWeChatAccount = this.getWeChatAccount();
565
609
  const ck = selectedWeChatAccount.configs ? !!selectedWeChatAccount.configs.deeplink : false;
566
610
  const deepLinkOptions = _.filter(JSON.parse(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (l) => l.link === link);
567
611
  if (deepLinkOptions[0]) {
@@ -960,7 +1004,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
960
1004
  showSelectedIosCta = (inputSchema, field, tab, selectedConfig) => {
961
1005
  const currentTab = tab || this.state.currentTab;
962
1006
  const schema = inputSchema ? _.cloneDeep(inputSchema) : _.cloneDeep(this.state.schema);
963
- const selectedWeChatAccount = (!_.isEmpty(this.props.Templates.selectedWeChatAccount) ? this.props.Templates.selectedWeChatAccount : this.props.Edit.selectedWeChatAccount);
1007
+ const selectedWeChatAccount = this.getWeChatAccount();
964
1008
  const ck = selectedWeChatAccount.configs ? !!selectedWeChatAccount.configs.deeplink : false;
965
1009
  const deepLinkOptions = _.map(JSON.parse(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (link) => ({label: link.name, value: link.link, title: link.link }) );
966
1010
 
@@ -1088,7 +1132,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
1088
1132
  };
1089
1133
 
1090
1134
  deletePrimaryCTA = (event) => {
1091
- const selectedWeChatAccount = (!_.isEmpty(this.props.Templates.selectedWeChatAccount) ? this.props.Templates.selectedWeChatAccount : this.props.Edit.selectedWeChatAccount);
1135
+ const selectedWeChatAccount = this.getWeChatAccount();
1092
1136
  const id = event.currentTarget.id;
1093
1137
  const schema = _.cloneDeep(this.state.schema);
1094
1138
  // const eventsMap = _.cloneDeep(this.state.eventsMap);
@@ -1188,7 +1232,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
1188
1232
  };
1189
1233
 
1190
1234
  deleteSecondaryCTA = (event) => {
1191
- const selectedWeChatAccount = (!_.isEmpty(this.props.Templates.selectedWeChatAccount) ? this.props.Templates.selectedWeChatAccount : this.props.Edit.selectedWeChatAccount);
1235
+ const selectedWeChatAccount = this.getWeChatAccount();
1192
1236
  const id = event.currentTarget.id;
1193
1237
  if (id === "secondary-cta-0-delete") {
1194
1238
  const secCta2 = document.getElementById("secondary-cta-1-delete");
@@ -1475,8 +1519,14 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
1475
1519
  if (this.props.location.query.type === 'embedded' && temp.id === "mobilepush-accounts" ) {
1476
1520
  temp.options = this.state.templateOptions ? this.state.accountsOptions : [];
1477
1521
  }
1478
- if (temp.id === "mobile-push-preview" && this.props.Templates.selectedWeChatAccount && !_.isEmpty(this.props.Templates.selectedWeChatAccount)) {
1479
- temp.content.appName = this.props.Templates.selectedWeChatAccount.name;
1522
+ if (temp.id === "mobile-push-preview") {
1523
+ const queryType = String(get(this.props, 'location.query.type', ''))?.toLowerCase();
1524
+ const creativesMode = String(get(this.props, 'creativesMode', ''))?.toLowerCase();
1525
+ if (isEmbeddedEditOrPreview(queryType, creativesMode) && this.props.Edit.selectedWeChatAccount && !_.isEmpty(this.props.Edit.selectedWeChatAccount)) {
1526
+ temp.content.appName = this.props.Edit.selectedWeChatAccount.name;
1527
+ } else if (this.props.Templates.selectedWeChatAccount && !_.isEmpty(this.props.Templates.selectedWeChatAccount)) {
1528
+ temp.content.appName = this.props.Templates.selectedWeChatAccount.name;
1529
+ }
1480
1530
  }
1481
1531
  _.forEach(col.supportedEvents, (event) => {
1482
1532
  temp.injectedEvents[event] = this.getMappedEvent(col.id, event);
@@ -1561,7 +1611,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
1561
1611
  };
1562
1612
 
1563
1613
  showCtaKeys = (eventTriggered, formData, field, tabIndex, schemaInput) => {
1564
- const selectedWeChatAccount = (!_.isEmpty(this.props.Templates.selectedWeChatAccount) ? this.props.Templates.selectedWeChatAccount : this.props.Edit.selectedWeChatAccount);
1614
+ const selectedWeChatAccount = this.getWeChatAccount();
1565
1615
  const currentTab = tabIndex || this.state.currentTab;
1566
1616
  const schema = _.cloneDeep(schemaInput || this.state.schema);
1567
1617
  const eventsMap = _.cloneDeep(this.state.eventsMap);
@@ -1616,7 +1666,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
1616
1666
  return schema;
1617
1667
  };
1618
1668
  addPrimaryCta = (flag, formData, field, inputSchema, currentTab) => {
1619
- const selectedWeChatAccount = (!_.isEmpty(this.props.Templates.selectedWeChatAccount) ? this.props.Templates.selectedWeChatAccount : this.props.Edit.selectedWeChatAccount);
1669
+ const selectedWeChatAccount = this.getWeChatAccount();
1620
1670
  const id = field.id;
1621
1671
  const schema = inputSchema ? _.cloneDeep(inputSchema) : _.cloneDeep(this.state.schema);
1622
1672
  const ck = selectedWeChatAccount.configs ? !!selectedWeChatAccount.configs.deeplink : false;
@@ -1649,7 +1699,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
1649
1699
  const tabIndex = currentTab || this.state.currentTab;
1650
1700
  const formDataCopy = cloneDeep(formData);
1651
1701
  const schema = inputSchema ? _.cloneDeep(inputSchema) : _.cloneDeep(this.state.schema);
1652
- const selectedWeChatAccount = (!_.isEmpty(this.props.Templates.selectedWeChatAccount) ? this.props.Templates.selectedWeChatAccount : this.props.Edit.selectedWeChatAccount);
1702
+ const selectedWeChatAccount = this.getWeChatAccount();
1653
1703
  const ck = selectedWeChatAccount.configs ? !!selectedWeChatAccount.configs.deeplink : false;
1654
1704
  const deepLinkOptions = selectedWeChatAccount ? _.map(JSON.parse(ck ? selectedWeChatAccount.configs.deeplink : '[]'), (link) => ({label: link.name, value: link.link, title: link.link }) ) : [];
1655
1705
  const inputFields = get(schema, `containers[0].panes[${tabIndex - 1}].sections[0].childSections[0].childSections[0].inputFields`);
@@ -1698,7 +1748,14 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
1698
1748
  if (!_.isEmpty(actionText)) {
1699
1749
  this.deleteSecondaryCtaIos();
1700
1750
  }
1701
- this.props.actions.getIosCtas(this.props.Templates.selectedWeChatAccount.sourceAccountIdentifier);//TODO: need to get license code of accoutn and send as arg
1751
+ const queryType = String(get(this.props, 'location.query.type', ''))?.toLowerCase();
1752
+ const creativesMode = String(get(this.props, 'creativesMode', ''))?.toLowerCase();
1753
+ if (isEmbeddedEditOrPreview(queryType, creativesMode)) {
1754
+ this.props.actions.getIosCtas(this.props.Edit.selectedWeChatAccount.sourceAccountIdentifier);
1755
+ } else {
1756
+ this.props.actions.getIosCtas(this.props.Templates.selectedWeChatAccount.sourceAccountIdentifier);
1757
+ }
1758
+ //TODO: need to get license code of accoutn and send as arg
1702
1759
  } else {
1703
1760
  this.deleteSecondaryCtaIos(() => { // oncick of change
1704
1761
  this.setState({showIosCtaTable: true});
@@ -1953,6 +2010,7 @@ Edit.propTypes = {
1953
2010
  onValidationFail: PropTypes.bool,
1954
2011
  onPreviewContentClicked: PropTypes.func,
1955
2012
  onTestContentClicked: PropTypes.func,
2013
+ creativesMode: PropTypes.string,
1956
2014
  };
1957
2015
 
1958
2016
  const mapStateToProps = createStructuredSelector({