@capillarytech/creatives-library 8.0.108 → 8.0.109

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 (29) hide show
  1. package/initialState.js +1 -0
  2. package/package.json +1 -1
  3. package/services/api.js +9 -4
  4. package/utils/cdnTransformation.js +1 -1
  5. package/utils/tests/__snapshots__/cdnTransformation.test.js.snap +9 -9
  6. package/utils/tests/cdnTransformation.mockdata.js +27 -28
  7. package/utils/tests/transformerUtils.test.js +2127 -0
  8. package/utils/transformerUtils.js +421 -0
  9. package/v2Components/FormBuilder/index.js +7 -3
  10. package/v2Containers/Cap/actions.js +8 -0
  11. package/v2Containers/Cap/constants.js +4 -0
  12. package/v2Containers/Cap/reducer.js +6 -0
  13. package/v2Containers/Cap/sagas.js +23 -0
  14. package/v2Containers/Cap/selectors.js +6 -0
  15. package/v2Containers/Cap/tests/__snapshots__/index.test.js.snap +1 -0
  16. package/v2Containers/Cap/tests/saga.test.js +90 -1
  17. package/v2Containers/CreativesContainer/SlideBoxContent.js +5 -1
  18. package/v2Containers/CreativesContainer/constants.js +14 -1
  19. package/v2Containers/CreativesContainer/index.js +50 -2
  20. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +2 -0
  21. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +25 -0
  22. package/v2Containers/CreativesContainer/tests/index.test.js +2 -0
  23. package/v2Containers/MobilePush/Create/index.js +1 -0
  24. package/v2Containers/Sms/Edit/index.js +1 -0
  25. package/v2Containers/TemplatesV2/index.js +8 -1
  26. package/v2Containers/Whatsapp/constants.js +2 -0
  27. package/v2Containers/Whatsapp/index.js +7 -3
  28. package/v2Containers/Zalo/index.js +5 -2
  29. package/v2Containers/mockdata.js +3 -0
@@ -1,8 +1,22 @@
1
1
  import { take, fork, cancel, takeLatest } from 'redux-saga/effects';
2
2
  import { expectSaga } from 'redux-saga-test-plan';
3
3
  import * as matchers from 'redux-saga-test-plan/matchers';
4
- import { authorize, loginFlow, fetchSchemaForEntity,v2CapSagas, getSupportVideosConfig, watchForGetVideosConfig, watchFetchSchemaForEntity,watchLiquidEntity, getLiquidTags, logoutFlow, capSagaLiquidEntity } from '../sagas';
5
4
  import { throwError } from 'redux-saga-test-plan/providers';
5
+ import {
6
+ authorize,
7
+ loginFlow,
8
+ fetchSchemaForEntity,
9
+ v2CapSagas,
10
+ getSupportVideosConfig,
11
+ watchForGetVideosConfig,
12
+ watchFetchSchemaForEntity,
13
+ watchLiquidEntity,
14
+ getLiquidTags,
15
+ logoutFlow,
16
+ capSagaLiquidEntity,
17
+ createCentralCommsMetaId,
18
+ watchMetaId,
19
+ } from '../sagas';
6
20
  import * as api from '../../../services/api';
7
21
  import {
8
22
  LOGIN_REQUEST,
@@ -17,6 +31,9 @@ import {
17
31
  GET_LIQUID_TAGS_SUCCESS,
18
32
  GET_LIQUID_TAGS_FAILURE,
19
33
  GET_LIQUID_TAGS_REQUEST,
34
+ CREATE_CENTRAL_COMMS_META_ID_SUCCESS,
35
+ CREATE_CENTRAL_COMMS_META_ID_FAILURE,
36
+ CREATE_CENTRAL_COMMS_META_ID_REQUEST,
20
37
  } from '../constants';
21
38
  import { callback, error, error2, videoConfigData } from '../../mockdata';
22
39
  import { LOGOUT_FAILURE, LOGOUT_REQUEST, LOGOUT_SUCCESS } from '../../../containers/Cap/constants';
@@ -365,4 +382,76 @@ describe('watchForGetLiquidTags saga', () => {
365
382
  takeLatest(GET_LIQUID_TAGS_REQUEST, getLiquidTags),
366
383
  );
367
384
  });
385
+ });
386
+
387
+ describe('createCentralCommsMetaId saga', () => {
388
+ const mockCallback = jest.fn();
389
+
390
+ it('handles successful API response', () => {
391
+ const action = {
392
+ data: { templateId: '123456' },
393
+ callback: mockCallback
394
+ };
395
+ const result = {
396
+ status: { code: 200 },
397
+ data: { id: '123456' }
398
+ };
399
+
400
+ expectSaga(createCentralCommsMetaId, action)
401
+ .provide([
402
+ [matchers.call.fn(api.createCentralCommsMetaId, action.data), result],
403
+ ])
404
+ .call(action.callback, result)
405
+ .put({
406
+ type: CREATE_CENTRAL_COMMS_META_ID_SUCCESS,
407
+ result,
408
+ })
409
+ .run();
410
+ });
411
+
412
+ it('handles unsuccessful API response', () => {
413
+ const action = {
414
+ data: { templateId: '123456' }
415
+ };
416
+ const result = {
417
+ status: { code: 400 },
418
+ message: 'Failed to create meta ID'
419
+ };
420
+
421
+ expectSaga(createCentralCommsMetaId, action)
422
+ .provide([
423
+ [matchers.call.fn(api.createCentralCommsMetaId, action.data), result],
424
+ ])
425
+ .put({
426
+ type: CREATE_CENTRAL_COMMS_META_ID_FAILURE,
427
+ error: result.message,
428
+ })
429
+ .run();
430
+ });
431
+
432
+ it('handles error thrown during API call', () => {
433
+ const action = {
434
+ data: { templateId: '123456' }
435
+ };
436
+ const error = new Error('API error');
437
+
438
+ expectSaga(createCentralCommsMetaId, action)
439
+ .provide([
440
+ [matchers.call.fn(api.createCentralCommsMetaId, action.data), throwError(error)],
441
+ ])
442
+ .put({
443
+ type: CREATE_CENTRAL_COMMS_META_ID_FAILURE,
444
+ error,
445
+ })
446
+ .run();
447
+ });
448
+ });
449
+
450
+ describe('watchMetaId saga', () => {
451
+ it('should watch for CREATE_CENTRAL_COMMS_META_ID_REQUEST actions', () => {
452
+ const generator = watchMetaId();
453
+ expect(generator.next().value).toEqual(
454
+ takeLatest(CREATE_CENTRAL_COMMS_META_ID_REQUEST, createCentralCommsMetaId),
455
+ );
456
+ });
368
457
  });
@@ -158,6 +158,7 @@ export function SlideBoxContent(props) {
158
158
  hostName = '',
159
159
  eventContextTags,
160
160
  isLoyaltyModule,
161
+ loyaltyMetaData = {},
161
162
  } = props;
162
163
  const type = (messageDetails.type || '').toLowerCase(); // type is context in get tags values : outbound | dvs | referral | loyalty | coupons
163
164
  const query = { type: !isFullMode && 'embedded', module: isFullMode ? 'default' : 'library', isEditFromCampaigns: (templateData || {}).isEditFromCampaigns};
@@ -434,6 +435,8 @@ export function SlideBoxContent(props) {
434
435
  enableNewChannels={enableNewChannels}
435
436
  hideTestAndPreviewBtn={hideTestAndPreviewBtn}
436
437
  eventContextTags={eventContextTags}
438
+ loyaltyMetaData={loyaltyMetaData}
439
+ isLoyaltyModule={isLoyaltyModule}
437
440
  />
438
441
  )}
439
442
  {isPreview && (
@@ -934,6 +937,7 @@ SlideBoxContent.propTypes = {
934
937
  weChatTemplateType: PropTypes.string,
935
938
  onWechatTemplateChange: PropTypes.func,
936
939
  selectedWeChatAccount: PropTypes.object,
940
+ loyaltyMetaData: PropTypes.object,
937
941
  onWeChatMaptemplateStepChange: PropTypes.func,
938
942
  weChatMaptemplateStep: PropTypes.string,
939
943
  onFacebookSubmit: PropTypes.func,
@@ -950,6 +954,6 @@ SlideBoxContent.propTypes = {
950
954
  moduleType: PropTypes.string,
951
955
  showLiquidErrorInFooter: PropTypes.bool,
952
956
  creativesMode: PropTypes.string,
953
- hostName: PropTypes.string,
957
+ hostName: PropTypes.string
954
958
  };
955
959
  export default SlideBoxContent;
@@ -17,6 +17,7 @@ export const FTP = "FTP";
17
17
  export const NO_COMMUNICATION = "NO_COMMUNICATION";
18
18
  export const VIBER = "VIBER";
19
19
  export const WHATSAPP = "WHATSAPP";
20
+ export const PUSH = "PUSH";
20
21
  export const RCS = "RCS";
21
22
  export const ZALO = "ZALO";
22
23
  export const INAPP = "INAPP";
@@ -24,10 +25,22 @@ export const PREVIEW = "preview";
24
25
  export const EDIT_TEMPLATE = "editTemplate";
25
26
  export const JOURNEY = "journey";
26
27
 
28
+ export const LOYALTY_SUPPORTED_ACTION = "SEND_COMMUNICATION_ACTION";
29
+
27
30
  export const SHOW_CONTANER_LOADER = "app/CreativesContainer/SHOW_CONTANER_LOADER";
28
31
  export const HIDE_CONTAINER_LOADER = "app/CreativesContainer/HIDE_CONTAINER_LOADER";
29
32
 
30
33
  export const WHATSAPP_HELP_DOC_LINK = "https://docs.capillarytech.com/docs/create-whatsapp-template";
31
34
 
32
35
  export const ENABLE_AI_SUGGESTIONS = "ENABLE_AI_SUGGESTIONS";
33
- export const LIQUID_SUPPORTED_CHANNELS = [EMAIL];
36
+ export const LIQUID_SUPPORTED_CHANNELS = [EMAIL];
37
+
38
+ export const EMF = "EMF";
39
+ export const VENENO = "VENENO";
40
+ export const TEXT = "TEXT";
41
+ export const IOS = "IOS";
42
+ export const ANDROID = "ANDROID";
43
+ export const EXTERNAL_URL = "EXTERNAL_URL";
44
+
45
+ export const TRANSACTION = "TRANSACTION";
46
+ export const BIG_TEXT = "BIG_TEXT";
@@ -60,6 +60,11 @@ import {
60
60
  import { DAEMON } from '@capillarytech/vulcan-react-sdk/utils/sagaInjectorTypes';
61
61
  import { DYNAMIC_URL } from '../../v2Components/CapWhatsappCTA/constants';
62
62
 
63
+ import {
64
+ transformChannelPayload,
65
+ // getTemplateDiffState
66
+ } from "../../utils/transformerUtils";
67
+
63
68
  const classPrefix = 'add-creatives-section';
64
69
  const CREATIVES_CONTAINER = 'creativesContainer';
65
70
 
@@ -490,7 +495,8 @@ export class Creatives extends React.Component {
490
495
  };
491
496
  break;
492
497
  }
493
- case constants.WHATSAPP: {
498
+ case constants.WHATSAPP:
499
+ case constants.WHATSAPP?.toLowerCase(): {
494
500
  const {
495
501
  messageBody = '',
496
502
  templateConfigs: {
@@ -1109,11 +1115,50 @@ export class Creatives extends React.Component {
1109
1115
  const creativesData = this.getCreativesData(channel, template, templateData);// convers data to consumer understandable format
1110
1116
  creativesData.then((data) => {
1111
1117
  this.logGTMEvent(channel, data);
1112
- this.props.getCreativesData(data);// send data to consumer
1118
+ this.processCentralCommsMetaId(channel, data);
1113
1119
  });
1114
1120
  },
1115
1121
  );
1116
1122
  }
1123
+ }
1124
+
1125
+ processCentralCommsMetaId = (channel, creativesData) => {
1126
+ // Create the payload for the centralcommnsmetaId API call
1127
+ const { isLoyaltyModule = false, loyaltyMetaData = {} } = this.props;
1128
+ const { actionName, setMetaData = () => {} } = loyaltyMetaData;
1129
+
1130
+ // const isTemplateModified = getTemplateDiffState(
1131
+ // channel,
1132
+ // loyaltyMetaData,
1133
+ // creativesData
1134
+ // );
1135
+ if (
1136
+ loyaltyMetaData
1137
+ && isLoyaltyModule
1138
+ // && isTemplateModified
1139
+ && actionName === constants.LOYALTY_SUPPORTED_ACTION
1140
+ ) {
1141
+ const payload = transformChannelPayload(creativesData, {
1142
+ channel,
1143
+ loyaltyMetaData,
1144
+ });
1145
+
1146
+ // Callback function to handle API response
1147
+ const handleMetaIDResult = (result) => {
1148
+ if (result?.status?.code === 200) {
1149
+ setMetaData(result);
1150
+ this.props.getCreativesData(creativesData);
1151
+ } else {
1152
+ CapNotification.error({ message: <FormattedMessage {...messages.somethingWentWrong} /> });
1153
+ }
1154
+ };
1155
+
1156
+ // Call the action to create central comms meta ID
1157
+ this.props.globalActions.createCentralCommsMetaId(payload, handleMetaIDResult);
1158
+ } else {
1159
+ // If not a loyalty module or different action, should work as usual
1160
+ this.props.getCreativesData(creativesData);
1161
+ }
1117
1162
  };
1118
1163
 
1119
1164
  setIsLoadingContent = (isLoadingContent) => {
@@ -1365,6 +1410,7 @@ export class Creatives extends React.Component {
1365
1410
  enableNewChannels,
1366
1411
  eventContextTags,
1367
1412
  isLoyaltyModule,
1413
+ loyaltyMetaData = {},
1368
1414
  } = this.props;
1369
1415
  const mapTemplateCreate =
1370
1416
  slidBoxContent === "createTemplate" &&
@@ -1470,6 +1516,7 @@ export class Creatives extends React.Component {
1470
1516
  hostName={this.props?.hostName || ''}
1471
1517
  eventContextTags={eventContextTags}
1472
1518
  isLoyaltyModule={isLoyaltyModule}
1519
+ loyaltyMetaData={loyaltyMetaData}
1473
1520
  />
1474
1521
  )}
1475
1522
  footer={this.shouldShowFooter() && (
@@ -1530,6 +1577,7 @@ Creatives.propTypes = {
1530
1577
  orgUnitId: PropTypes.number,
1531
1578
  hostName: PropTypes.string,
1532
1579
  eventContextTags: PropTypes.array,
1580
+ stopValidation: PropTypes.func,
1533
1581
  };
1534
1582
  const mapStatesToProps = () => createStructuredSelector({
1535
1583
  isLoading: isLoadingSelector(),
@@ -651,6 +651,7 @@ exports[`Test SlideBoxContent container Should render correct component for rcs
651
651
  "search": "",
652
652
  }
653
653
  }
654
+ loyaltyMetaData={Object {}}
654
655
  messageDetails={Object {}}
655
656
  onCreateComplete={[MockFunction]}
656
657
  slidBoxContent="templates"
@@ -1042,6 +1043,7 @@ exports[`Test SlideBoxContent container Should render correct component for what
1042
1043
  "search": "",
1043
1044
  }
1044
1045
  }
1046
+ loyaltyMetaData={Object {}}
1045
1047
  messageDetails={Object {}}
1046
1048
  onCreateComplete={[MockFunction]}
1047
1049
  slidBoxContent="templates"
@@ -15,6 +15,11 @@ exports[`Test SlideBoxContent container campaign message, add creative click rcs
15
15
  getFormData={[Function]}
16
16
  handleClose={[Function]}
17
17
  hostName=""
18
+ loyaltyMetaData={
19
+ Object {
20
+ "actionName": "SEND_COMMUNICATION_ACTION",
21
+ }
22
+ }
18
23
  onCallTaskSubmit={[Function]}
19
24
  onChannelChange={[Function]}
20
25
  onCreateComplete={[MockFunction]}
@@ -92,6 +97,11 @@ exports[`Test SlideBoxContent container campaign message, add creative click wha
92
97
  getFormData={[Function]}
93
98
  handleClose={[Function]}
94
99
  hostName=""
100
+ loyaltyMetaData={
101
+ Object {
102
+ "actionName": "SEND_COMMUNICATION_ACTION",
103
+ }
104
+ }
95
105
  onCallTaskSubmit={[Function]}
96
106
  onChannelChange={[Function]}
97
107
  onCreateComplete={[MockFunction]}
@@ -169,6 +179,11 @@ exports[`Test SlideBoxContent container campaign message, whatsapp edit all data
169
179
  getFormData={[Function]}
170
180
  handleClose={[Function]}
171
181
  hostName=""
182
+ loyaltyMetaData={
183
+ Object {
184
+ "actionName": "SEND_COMMUNICATION_ACTION",
185
+ }
186
+ }
172
187
  onCallTaskSubmit={[Function]}
173
188
  onChannelChange={[Function]}
174
189
  onCreateComplete={[MockFunction]}
@@ -250,6 +265,11 @@ exports[`Test SlideBoxContent container campaign message, whatsapp edit min data
250
265
  getFormData={[Function]}
251
266
  handleClose={[Function]}
252
267
  hostName=""
268
+ loyaltyMetaData={
269
+ Object {
270
+ "actionName": "SEND_COMMUNICATION_ACTION",
271
+ }
272
+ }
253
273
  onCallTaskSubmit={[Function]}
254
274
  onChannelChange={[Function]}
255
275
  onCreateComplete={[MockFunction]}
@@ -331,6 +351,11 @@ exports[`Test SlideBoxContent container it should clear the url, on channel chan
331
351
  getFormData={[Function]}
332
352
  handleClose={[Function]}
333
353
  hostName=""
354
+ loyaltyMetaData={
355
+ Object {
356
+ "actionName": "SEND_COMMUNICATION_ACTION",
357
+ }
358
+ }
334
359
  onCallTaskSubmit={[Function]}
335
360
  onChannelChange={[Function]}
336
361
  onCreateComplete={[MockFunction]}
@@ -16,6 +16,7 @@ const {
16
16
  smsTemplates,
17
17
  emailEditTemplateData,
18
18
  emailTemplates,
19
+ loyaltyMetaData,
19
20
  } = mockdata;
20
21
 
21
22
  jest.mock('../../../v2Components/FormBuilder', () => ({
@@ -40,6 +41,7 @@ describe('Test SlideBoxContent container', () => {
40
41
  const renderFunction = (channel, mode, templates, templateData) => {
41
42
  renderedComponent = shallowWithIntl(
42
43
  <Creatives
44
+ loyaltyMetaData={loyaltyMetaData}
43
45
  Templates={templates}
44
46
  channel={channel}
45
47
  slidBoxContent={mode}
@@ -1809,6 +1809,7 @@ export class Create extends React.Component { // eslint-disable-line react/prefe
1809
1809
  hideTestAndPreviewBtn={this.props.hideTestAndPreviewBtn}
1810
1810
  isFullMode={this.props.isFullMode}
1811
1811
  eventContextTags={this.props?.eventContextTags}
1812
+ messageDetails={this.props?.messageDetails}
1812
1813
  />
1813
1814
  </CapColumn>
1814
1815
  {this.props.iosCtasData && this.state.showIosCtaTable &&
@@ -992,6 +992,7 @@ export class Edit extends React.Component { // eslint-disable-line react/prefer-
992
992
  onPreviewContentClicked={this.props.onPreviewContentClicked}
993
993
  onTestContentClicked={this.props.onTestContentClicked}
994
994
  eventContextTags={this.props?.eventContextTags}
995
+ messageDetails={this.props?.messageDetails}
995
996
  />
996
997
  </CapColumn>
997
998
  </CapRow>
@@ -34,7 +34,7 @@ import { CREATIVES_UI_VIEW, LOYALTY, WHATSAPP, RCS, LINE, EMAIL, ASSETS, JP_LOCA
34
34
  import AccessForbidden from '../../v2Components/AccessForbidden';
35
35
  import { getObjFromQueryParams } from '../../utils/v2common';
36
36
  import { makeSelectAuthenticated, selectCurrentOrgDetails } from "../../v2Containers/Cap/selectors";
37
-
37
+ import { LOYALTY_SUPPORTED_ACTION } from "../CreativesContainer/constants";
38
38
 
39
39
  const {CapCustomCardList} = CapCustomCard;
40
40
 
@@ -56,6 +56,8 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
56
56
  enableNewChannels = [],
57
57
  currentOrgDetails = {},
58
58
  cap = {},
59
+ loyaltyMetaData = {},
60
+ isLoyaltyModule = false,
59
61
  } = props;
60
62
 
61
63
  const defaultPanes = {
@@ -98,6 +100,11 @@ export class TemplatesV2 extends React.Component { // eslint-disable-line react/
98
100
  }
99
101
  const commonChannels = ['sms', 'email', 'wechat', 'mobilepush', 'line', 'viber', 'facebook', 'call_task', 'ftp', 'assets'];
100
102
 
103
+ const { actionName = ''} = loyaltyMetaData;
104
+ if (isLoyaltyModule && actionName === LOYALTY_SUPPORTED_ACTION) {
105
+ commonChannels.push(WHATSAPP, ZALO);
106
+ }
107
+
101
108
  // we only show channels which other than commonChannels
102
109
  // if it is coming in enableNewChannels array
103
110
  filteredPanes = filteredPanes.filter((item) => {
@@ -653,3 +653,5 @@ export const CATEGORY_OPTIONS_MAP = {
653
653
  [HOST_GUPSHUP]: KARIX_GUPSHUP_CATEGORY_OPTIONS,
654
654
  [HOST_ICS]: ICS_CATEGORY_OPTIONS,
655
655
  };
656
+
657
+ export const REQUEST = "REQUEST";
@@ -44,7 +44,8 @@ import {
44
44
  makeSelectMetaEntities,
45
45
  selectCurrentOrgDetails,
46
46
  setInjectedTags,
47
- } from '../Cap/selectors';
47
+ selectMetaDataStatus,
48
+ } from "../Cap/selectors";
48
49
  import * as WhatsappActions from './actions';
49
50
  import './index.scss';
50
51
  import {
@@ -97,6 +98,7 @@ import {
97
98
  IMAGE,
98
99
  VIDEO,
99
100
  URL,
101
+ REQUEST
100
102
  } from './constants';
101
103
  import { DATE_DISPLAY_FORMAT, TIME_DISPLAY_FORMAT } from '../App/constants';
102
104
  import messages from './messages';
@@ -152,6 +154,7 @@ export const Whatsapp = (props) => {
152
154
  selectedOfferDetails,
153
155
  currentOrgDetails,
154
156
  eventContextTags,
157
+ metaDataStatus = "",
155
158
  } = props || {};
156
159
  const { formatMessage } = intl;
157
160
  const { TextArea } = CapInput;
@@ -2807,7 +2810,7 @@ const isAuthenticationTemplate = isEqual(templateCategory, WHATSAPP_CATEGORIES.a
2807
2810
  }
2808
2811
 
2809
2812
  return (
2810
- <CapSpin spinning={spin}>
2813
+ <CapSpin spinning={spin || metaDataStatus === REQUEST}>
2811
2814
  <CapRow className="cap-whatsapp-creatives">
2812
2815
  <CapColumn span={14}>
2813
2816
  {isEditFlow ? editModeContent() : createModeContent()}
@@ -2878,7 +2881,8 @@ const mapStateToProps = createStructuredSelector({
2878
2881
  metaEntities: makeSelectMetaEntities(),
2879
2882
  loadingTags: isLoadingMetaEntities(),
2880
2883
  injectedTags: setInjectedTags(),
2881
- currentOrgDetails: selectCurrentOrgDetails()
2884
+ currentOrgDetails: selectCurrentOrgDetails(),
2885
+ metaDataStatus: selectMetaDataStatus(),
2882
2886
  });
2883
2887
 
2884
2888
  const mapDispatchToProps = (dispatch) => ({
@@ -24,7 +24,7 @@ import {
24
24
  CAP_WHITE,
25
25
  } from '@capillarytech/cap-ui-library/styled/variables';
26
26
  import { makeSelectZalo, makeSelectAccount } from './selectors';
27
- import { makeSelectMetaEntities, setInjectedTags } from '../Cap/selectors';
27
+ import { makeSelectMetaEntities, setInjectedTags, selectMetaDataStatus } from '../Cap/selectors';
28
28
  import * as zaloActions from './actions';
29
29
  import './index.scss';
30
30
  import {
@@ -56,6 +56,7 @@ import { v2ZaloSagas } from './saga';
56
56
  import { CapIcon } from '@capillarytech/cap-ui-library';
57
57
  import { isTagIncluded } from '../../utils/commonUtils';
58
58
 
59
+
59
60
  export const Zalo = (props) => {
60
61
  const {
61
62
  intl,
@@ -74,6 +75,7 @@ export const Zalo = (props) => {
74
75
  selectedOfferDetails,
75
76
  hostName: zaloHostName = '',
76
77
  eventContextTags,
78
+ metaDataStatus = "",
77
79
  } = props || {};
78
80
  // Since zalo supports now multiple accounts, we need to get the hostname from the selected account or passed props.
79
81
  const hostName = selectedZaloAccount?.hostName || zaloHostName;
@@ -435,7 +437,7 @@ export const Zalo = (props) => {
435
437
  });
436
438
 
437
439
  return (
438
- <CapSpin spinning={zaloTemplateInfoStatus === REQUEST}>
440
+ <CapSpin spinning={[zaloTemplateInfoStatus, metaDataStatus].includes(REQUEST)}>
439
441
  <CapRow type="flex" className="cap-zalo-creatives">
440
442
  <CapColumn span={14}>
441
443
  {templateStatus && (
@@ -530,6 +532,7 @@ const mapStateToProps = createStructuredSelector({
530
532
  accountData: makeSelectAccount(),
531
533
  metaEntities: makeSelectMetaEntities(),
532
534
  injectedTags: setInjectedTags(),
535
+ metaDataStatus: selectMetaDataStatus(),
533
536
  });
534
537
 
535
538
  const mapDispatchToProps = (dispatch) => ({
@@ -2584,6 +2584,9 @@ export default {
2584
2584
  },
2585
2585
  demoVideoAndLinkJSONStatus: "SUCCESS",
2586
2586
  },
2587
+ loyaltyMetaData: {
2588
+ actionName: "SEND_COMMUNICATION_ACTION",
2589
+ },
2587
2590
  getWhatsappAutoFillData:
2588
2591
  < CapLabel
2589
2592
  className="whatsapp-autofill-btn"