@capillarytech/creatives-library 8.0.64-alpha.0 → 8.0.65-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.
@@ -21,6 +21,7 @@ import cloneDeep from 'lodash/cloneDeep';
21
21
  import find from 'lodash/find';
22
22
  import map from 'lodash/map';
23
23
  import { bindActionCreators } from 'redux';
24
+ import { Modal, Form} from 'antd';
24
25
  import {
25
26
  CapMenu,
26
27
  CapDropdown,
@@ -96,16 +97,18 @@ import {
96
97
  FACEBOOK as FACEBOOK_CHANNEL,
97
98
  CREATE,
98
99
  } from '../App/constants';
99
- import {MAX_WHATSAPP_TEMPLATES, WARNING_WHATSAPP_TEMPLATES } from './constants';
100
+ import {MAX_WHATSAPP_TEMPLATES, WARNING_WHATSAPP_TEMPLATES , ACCOUNT_MAPPING_ON_CHANNEL} from './constants';
100
101
  import { COPY_OF } from '../../containers/App/constants';
101
102
  import {
103
+ TWILIO_CATEGORY_OPTIONS,
104
+ KARIX_GUPSHUP_CATEGORY_OPTIONS,
102
105
  STATUS_OPTIONS,
103
106
  CATEGORY,
104
107
  WHATSAPP_CATEGORIES,
105
108
  STATUS as WHATSAPP_STATUS,
106
109
  WHATSAPP_STATUSES,
110
+ HOST_TWILIO,
107
111
  HOST_GUPSHUP,
108
- CATEGORY_OPTIONS_MAP,
109
112
  } from '../Whatsapp/constants';
110
113
  import { INAPP_LAYOUT_DETAILS } from '../InApp/constants';
111
114
  import { ZALO_STATUS_OPTIONS, ZALO_STATUSES } from '../Zalo/constants';
@@ -123,6 +126,7 @@ import emailIllustration from '../Assets/images/emailIllustration.svg';
123
126
  import smsIllustration from '../Assets/images/smsIllustration.svg';
124
127
  import pushIllustration from '../Assets/images/pushIllustration.svg';
125
128
  import whatsappIllustration from '../Assets/images/whatsappIllustration.png';
129
+ import whatsappOrZaloAccountIllustration from '../Assets/images/whatsappOrZaloAccountIllustration.svg';
126
130
  import rcsIllustration from '../Assets/images/rcsIllustration.png';
127
131
  import zaloillustration from '@capillarytech/cap-ui-library/assets/images/featureUiNotEnabledIllustration.svg';
128
132
  import inAppIllustration from '@capillarytech/cap-ui-library/assets/images/featureUiNotEnabledIllustration.svg';
@@ -247,6 +251,22 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
247
251
  this.delayTimer = 0;
248
252
  }
249
253
 
254
+ getHostName(selectedSourceAccountIdentifier, domainPropertiesData = []) {
255
+ if (isEmpty(domainPropertiesData) || !selectedSourceAccountIdentifier) {
256
+ return '';
257
+ }
258
+ for (const domainData of domainPropertiesData) {
259
+ const { hostName, connectionProperties: { account_sid, wabaId, userid, sourceAccountIdentifier, oa_id } = {}} = domainData?.domainProperties || {};
260
+ // If sourceAccountIdentifier is not present in the domainProperties, then it will try to find in account_sid, wabaId, user_id.
261
+ // wabaId, user_id is, account_sid are for Karix, Gupshup, and Twilio (Whatsapp) respectively and oa_id is for Zalo.
262
+ const sourceAccountIdentifiersArray = [account_sid, wabaId, userid, oa_id, sourceAccountIdentifier];
263
+ if (sourceAccountIdentifiersArray.includes(selectedSourceAccountIdentifier)) {
264
+ this.setState({hostName});
265
+ return hostName;
266
+ }
267
+ }
268
+ };
269
+
250
270
  componentWillMount() {
251
271
  if (this.state.channel === '') {
252
272
  let channel = '';
@@ -609,11 +629,11 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
609
629
  if (!isEmpty(nextProps.Templates.templateDetails) && !isEqual(nextProps.Templates.templateDetails, this.props.Templates.templateDetails)) {
610
630
  this.setState({ previewTemplate: nextProps.Templates.templateDetails });
611
631
  }
612
- const { weCrmAccounts: weCrmAccountsList = [], senderDetails: { hostName = '' } = {} } = get(nextProps, 'Templates', {});
613
- const weCrmChannels = ['wechat', WHATSAPP_LOWERCASE, ZALO_LOWERCASE];
632
+ const { weCrmAccounts: weCrmAccountsList = [], senderDetails = {} } = get(nextProps, 'Templates', {});
633
+ const weCrmChannels = [WHATSAPP_LOWERCASE, ZALO_LOWERCASE];
614
634
 
615
- if (weCrmAccountsList.length === 1 && this.state.defaultAccount && (weCrmChannels.indexOf(selectedChannel) > -1) && !isEmpty(hostName)) {
616
- let paramsDefault = {};
635
+ // Keeping the wechat flow separate as it has different logic for setting the account.
636
+ if (weCrmAccountsList?.length === 1 && this.state?.defaultAccount && selectedChannel === WECHAT_LOWERCASE && !isEmpty(senderDetails?.hostName)) {
617
637
  if (this.state.channel.toLowerCase() !== ZALO_LOWERCASE) {
618
638
  paramsDefault = {
619
639
  name: this.state.searchText,
@@ -621,38 +641,65 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
621
641
  };
622
642
  }
623
643
 
624
- const {name, sourceAccountIdentifier, configs } = weCrmAccountsList?.[0] || {};
644
+ const { sourceAccountIdentifier, configs } = weCrmAccountsList?.[0] || {};
625
645
  const {
626
- token,
627
646
  wecrm_app_id,
628
647
  wecrm_token
629
648
  } = configs || {};
630
- if (weCrmChannels.includes(selectedChannel)) {
631
- if ([WHATSAPP_LOWERCASE, ZALO_LOWERCASE].includes(selectedChannel)) {
632
- if (hostName === '') {
633
- return;
634
- }
635
649
 
636
- weCrmAccountsList[0].hostName = hostName;
637
- nextProps.actions.setChannelAccount(selectedChannel.toUpperCase(), weCrmAccountsList[0]);
638
- if (selectedChannel === ZALO_LOWERCASE) {
639
- paramsDefault.username = name;
640
- paramsDefault.oa_id = sourceAccountIdentifier;
641
- paramsDefault.token = token;
642
- paramsDefault.host = hostName || this.props.Templates?.senderDetails?.hostName || this.props.Templates?.selectedZaloAccount?.hostName || this.state.hostName;
643
- }
644
- } else {
645
- paramsDefault.wecrmId = wecrm_app_id;
646
- paramsDefault.wecrmToken = wecrm_token;
647
- paramsDefault.originalId = sourceAccountIdentifier;
648
- nextProps.actions.setWeChatAccount(
649
- weCrmAccountsList[0],
650
- );
651
- }
652
-
650
+ const paramsDefault = {
651
+ wecrmId: wecrm_app_id,
652
+ wecrmToken: wecrm_token,
653
+ originalId: sourceAccountIdentifier,
653
654
  }
655
+ nextProps.actions.setWeChatAccount(
656
+ weCrmAccountsList[0],
657
+ );
658
+
654
659
  this.setState({ defaultAccount: false, activeMode: TEMPLATES_MODE, selectedAccount: weCrmAccountsList[0].name, hostName: weCrmAccountsList[0].hostName });
655
- this.getAllTemplates({params: paramsDefault}, true);
660
+ this.getAllTemplates({ params: paramsDefault }, true);
661
+ }
662
+
663
+ if (weCrmAccountsList?.length && this.state?.defaultAccount && (weCrmChannels.includes(selectedChannel))) {
664
+ const isSingleAccount = weCrmAccountsList?.length === 1;
665
+ const selectedAccount = this.props.Templates[ACCOUNT_MAPPING_ON_CHANNEL[selectedChannel]] || {};
666
+ const hostName = this.getHostName(isSingleAccount ? weCrmAccountsList[0]?.sourceAccountIdentifier : selectedAccount?.sourceAccountIdentifier, senderDetails?.domainProperties);
667
+
668
+ if (!isEmpty(hostName)) {
669
+ let paramsDefault = {};
670
+ if (this.state.channel.toLowerCase() !== ZALO_LOWERCASE) {
671
+ paramsDefault = {
672
+ name: this.state.searchText,
673
+ sortBy: this.state.sortBy,
674
+ };
675
+ }
676
+
677
+ const {name, sourceAccountIdentifier, configs } = weCrmAccountsList?.[0] || {};
678
+ if (isSingleAccount) {
679
+ weCrmAccountsList[0].hostName = hostName;
680
+ } else {
681
+ selectedAccount.hostName = hostName;
682
+ }
683
+ nextProps.actions.setChannelAccount(selectedChannel?.toUpperCase(), isSingleAccount ? weCrmAccountsList[0] : selectedAccount);
684
+ if (selectedChannel === ZALO_LOWERCASE) {
685
+ paramsDefault.username = name;
686
+ paramsDefault.oa_id = sourceAccountIdentifier;
687
+ paramsDefault.token = configs?.token;
688
+ paramsDefault.host = hostName || this.props.Templates?.selectedZaloAccount?.hostName;
689
+ }
690
+ if (selectedChannel === WHATSAPP_LOWERCASE) {
691
+ paramsDefault.accountId = sourceAccountIdentifier;
692
+ paramsDefault.host = hostName || this.props.Templates?.selectedWhatsappAccount?.hostName;
693
+ }
694
+ this.setState({ defaultAccount: false, activeMode: TEMPLATES_MODE, selectedAccount: isSingleAccount ? weCrmAccountsList[0]?.name : selectedAccount?.name });
695
+ /**
696
+ * Incase of multiple accounts, getAllTemplates is called on selecting the account. It's handled in onAccountSelect function.
697
+ * But for single account, onAccountSelect function won't get executed and getAllTemplates will be excuted.
698
+ */
699
+ if (weCrmAccountsList?.length === 1) {
700
+ this.getAllTemplates({params: paramsDefault}, true);
701
+ }
702
+ }
656
703
  }
657
704
  const zaloPreviewUrl = get(nextProps, 'Zalo.zaloTemplatePreviewData.versions.base.content.zalo.previewUrl', '');
658
705
  if (zaloPreviewUrl && this.state.channel.toLowerCase() === ZALO_LOWERCASE) {
@@ -678,6 +725,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
678
725
  params.sortBy = this.state.sortBy;
679
726
  }
680
727
  const selectedChannel = this.state.channel.toLowerCase();
728
+ const isZaloOrWhatsapp = [ZALO_LOWERCASE, WHATSAPP_LOWERCASE].includes(selectedChannel);
681
729
  if (selectedChannel === 'wechat') {
682
730
  params.wecrmId = this.props.Templates.weCrmAccounts[findIndex(this.props.Templates.weCrmAccounts, { name: value})].configs.wecrm_app_id;
683
731
  params.wecrmToken = this.props.Templates.weCrmAccounts[findIndex(this.props.Templates.weCrmAccounts, { name: value})].configs.wecrm_token;
@@ -697,26 +745,43 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
697
745
  } else {
698
746
  this.setState({ selectedAccountError: false });
699
747
  }
700
- } else if ([LINE.toLowerCase(), RCS_LOWERCASE, ZALO_LOWERCASE].includes(selectedChannel)) {
748
+ } else if ([LINE.toLowerCase(), RCS_LOWERCASE, ZALO_LOWERCASE, WHATSAPP_LOWERCASE].includes(selectedChannel)) {
701
749
  const setAcc = this.props?.Templates?.weCrmAccounts?.find((item) => item?.name === this.state.selectedAccount);
750
+ const { domainProperties = [] } = this.props?.Templates?.senderDetails || {};
751
+ let hostName = '';
752
+ if (isZaloOrWhatsapp) {
753
+ hostName = this.getHostName(setAcc?.sourceAccountIdentifier, domainProperties);
754
+ setAcc.hostName = hostName;
755
+ }
702
756
  this.props.actions.setChannelAccount(selectedChannel?.toUpperCase(), setAcc);
703
- if(selectedChannel === ZALO_LOWERCASE){
704
- const {
705
- name = "",
706
- sourceAccountIdentifier = "",
707
- configs: { token = "" } = {},
708
- } = setAcc || {};
757
+
758
+ const {
759
+ name = "",
760
+ sourceAccountIdentifier = "",
761
+ configs: { token = "" } = {},
762
+ } = setAcc || {};
763
+
764
+ if(selectedChannel === ZALO_LOWERCASE && hostName) {
709
765
  params.username = name;
710
766
  params.oa_id = sourceAccountIdentifier;
711
767
  params.token = token;
712
768
  params.isAccountSelection = true;
713
- params.host = this.props.Templates?.senderDetails?.hostName || this.props.Templates?.selectedZaloAccount?.hostName || this.state.hostName;
769
+ params.host = hostName;
770
+ }
771
+ if (selectedChannel === WHATSAPP_LOWERCASE && hostName) {
772
+ params.accountId = sourceAccountIdentifier;
773
+ params.host = hostName;
714
774
  }
715
775
  }
716
776
 
717
- this.setState({activeMode: TEMPLATES_MODE});
718
-
719
- this.getAllTemplates({params, resetPage: true});
777
+ // Always set activeMode before getAllTemplates call
778
+ this.setState({ activeMode: TEMPLATES_MODE }, () => {
779
+ // Restrict getAllTemplates call only if selectedChannel is ZALO or WHATSAPP and hostName is empty
780
+ if (!(isZaloOrWhatsapp && !params?.host)) {
781
+ console.log(">>> GETALLTEMPLATES onaccount select ", { params });
782
+ this.getAllTemplates({ params, resetPage: true });
783
+ }
784
+ });
720
785
  });
721
786
  }
722
787
  onPaginationChange = () => {
@@ -794,6 +859,12 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
794
859
 
795
860
  moment.locale(locale);
796
861
  };
862
+
863
+ setWhatsappQueryParams = (queryParams, params) => {
864
+ queryParams.accountId = params?.accountId || this.props.Templates?.selectedWhatsappAccount?.sourceAccountIdentifier;
865
+ queryParams.host = params?.host || this.state?.hostName;
866
+ };
867
+
797
868
  getAllTemplates = ({params, getNextPage, resetPage}, resetTemplates) => {
798
869
  let queryParams = params || {};
799
870
  let page = this.state.page;
@@ -822,6 +893,9 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
822
893
  if (([MOBILE_PUSH_LOWERCASE, INAPP_LOWERCASE].includes(channel.toLowerCase())) && !isEmpty(this.props.Templates.selectedWeChatAccount)) {
823
894
  queryParams.accountId = this.props.Templates?.selectedWeChatAccount?.id;
824
895
  }
896
+ if (this.state?.channel?.toLowerCase() === WHATSAPP_LOWERCASE) {
897
+ this.setWhatsappQueryParams(queryParams, params);
898
+ }
825
899
  this.props.actions.getAllTemplates(channel, queryParams,`${copyOf}`);
826
900
  } else if ((resetPage || (page === 1 && this.state.templatesCount === 0) || page <= (this.state.templatesCount / this.state.perPageLimit))) {
827
901
  if (getNextPage) {
@@ -871,6 +945,9 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
871
945
  queryParams.token = token;
872
946
  queryParams.host = hostName || this.props.Templates?.senderDetails?.hostName ||this.state.hostName;
873
947
  }
948
+ if (this.state?.channel?.toLowerCase() === WHATSAPP_LOWERCASE) {
949
+ this.setWhatsappQueryParams(queryParams, params);
950
+ }
874
951
  this.setState({ page, templatesCount }, () => {
875
952
  queryParams.page = page;
876
953
  queryParams.perPage = this.state.perPageLimit;
@@ -1017,7 +1094,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1017
1094
  filteredTemplates = this.filterWechatTemplates(templates);
1018
1095
  break;
1019
1096
  case WHATSAPP:
1020
- filteredTemplates = this.filterWhatsappTemplates(templates);
1097
+ filteredTemplates = this.state?.hostName ? this.filterWhatsappTemplates(templates) : [];
1021
1098
  break;
1022
1099
  case LINE:
1023
1100
  filteredTemplates = this.filterLineTemplates(templates);
@@ -1378,16 +1455,21 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1378
1455
 
1379
1456
  const accountId = get(this.props, 'Templates.selectedWeChatAccount.uuid');
1380
1457
  const accounts = get(this.props, 'Templates.weCrmAccounts');
1381
- const noWhatsappZaloTemplates = this.isFullMode() && isEmpty(templates);
1458
+ const noWhatsappZaloTemplates = this.isFullMode() && isEmpty(templates) || !this.state.hostName;
1382
1459
  const noFilteredWhatsappZaloTemplates = this.isFullMode() && !isEmpty(templates) && isEmpty(filteredTemplates);
1383
1460
  const noApprovedWhatsappZaloTemplates = !this.isFullMode() && isEmpty(filteredTemplates);
1384
- const showWhatsappIllustration = !isEmpty(this.props.Templates.selectedWhatsappAccount) && [WHATSAPP_LOWERCASE].includes(channelLowerCase);
1461
+ const showWhatsappIllustration = (!isEmpty(this.props.Templates.selectedWhatsappAccount) && [WHATSAPP_LOWERCASE].includes(channelLowerCase)) || !this.state.hostName ;
1385
1462
  const showZaloIllustration = !isEmpty(this.props.Templates.selectedZaloAccount) && [ZALO_LOWERCASE].includes(channelLowerCase);
1386
1463
  const showRcsIllustration = channelLowerCase === RCS_LOWERCASE && isEmpty(templates);
1387
1464
  const showInAppIllustration = channelLowerCase === INAPP_LOWERCASE && isEmpty(templates);
1388
1465
  const noLoaderAndSearchText = isEmpty(this.state.searchText) && !isLoading;
1466
+ console.log(">>> state ", {showWhatsappIllustration, showZaloIllustration, noLoaderAndSearchText, noApprovedWhatsappZaloTemplates, noFilteredWhatsappZaloTemplates, noWhatsappZaloTemplates, channelLowerCase, host: this.state.hostName, templates: this.props.Templates,
1467
+ mp: (["mobilepush"].includes(this.state.channel.toLowerCase()) &&
1468
+ isEmpty(filteredTemplates) &&
1469
+ isEmpty(this.state.searchText))
1470
+ })
1389
1471
  return (<div>
1390
- {[WECHAT, MOBILE_PUSH, INAPP].includes(currentChannel) && this.showAccountName()}
1472
+ {[WECHAT, MOBILE_PUSH, INAPP, WHATSAPP, ZALO].includes(currentChannel) && this.showAccountName()}
1391
1473
  {filterContent}
1392
1474
  {[WHATSAPP, ZALO].includes(currentChannel) && this.selectedFilters()}
1393
1475
  <CapCustomSkeleton loader={isLoading}>
@@ -1424,15 +1506,15 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1424
1506
  isEmpty(filteredTemplates) &&
1425
1507
  isEmpty(this.state.searchText) &&
1426
1508
  <div style={this.isFullMode() ? { height: "calc(100vh - 325px)", overflow: 'auto'} : {}}>
1427
- <CapIllustration buttonClassName={`create-new-${channelLowerCase}`} {...this.getChannelTypeIllustrationInfo(currentChannel)} />
1509
+ <CapIllustration buttonClassName={`create-new-${channelLowerCase}`} {...this.getChannelTypeIllustrationInfo(currentChannel, this.state?.hostName)} />
1428
1510
  </div>
1429
1511
  )
1430
1512
  }
1431
1513
  {(showWhatsappIllustration || showZaloIllustration) && (
1432
1514
  noLoaderAndSearchText &&
1433
1515
  <div style={this.isFullMode() ? { height: "calc(100vh - 325px)", overflow: 'auto' } : {}}>
1434
- {noWhatsappZaloTemplates && <CapIllustration buttonClassName={`create-new-${channelLowerCase}`} {...this.getChannelTypeIllustrationInfo(currentChannel)} />}
1435
- {noFilteredWhatsappZaloTemplates && this.whatsappZaloIllustrationText('noFilteredWhatsappZaloTemplatesTitle', 'noFilteredWhatsappZaloTemplatesDesc')}
1516
+ {noWhatsappZaloTemplates && <CapIllustration buttonClassName={`create-new-${channelLowerCase}`} {...this.getChannelTypeIllustrationInfo(currentChannel, isEmpty(this.state?.hostName))} />}
1517
+ {noFilteredWhatsappZaloTemplates && this.state?.hostName && this.whatsappZaloIllustrationText('noFilteredWhatsappZaloTemplatesTitle', 'noFilteredWhatsappZaloTemplatesDesc')}
1436
1518
  {noApprovedWhatsappZaloTemplates && this.whatsappZaloIllustrationText('noApprovedWhatsappZaloTemplatesTitle', showWhatsappIllustration ? 'noApprovedWhatsappTemplatesDesc' : 'zaloDescIllustration')}
1437
1519
  </div>
1438
1520
  )
@@ -1577,6 +1659,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1577
1659
  prepareWeChatPreviewData(template) {
1578
1660
  if (template && template.versions && template.versions.base && !isEmpty(template.versions.base)) {
1579
1661
  if (template.definition && template.definition.msgcontent && template.definition.msgcontent === "RICH_MEDIA_WECHAT") {
1662
+ console.log("prepareWeChatPreviewData", template, JSON.stringify(template), template.versions.base.mediaList, JSON.stringify(template.versions.base.mediaList));
1580
1663
  return template.versions.base.mediaList;
1581
1664
  }
1582
1665
  return this.prepareWeChatMappedPreviewData(template.versions.base.content, template.versions.base.Tag, template.versions.base.data);
@@ -1836,6 +1919,9 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1836
1919
  }
1837
1920
  if (this.state.channel.toLowerCase() === MOBILE_PUSH_LOWERCASE) {
1838
1921
  params.accountId = this.props.Templates.selectedWeChatAccount.id;
1922
+ } else if (this.state.channel.toLowerCase() === WHATSAPP_LOWERCASE) {
1923
+ params.accountId = this.props.Templates?.selectedWhatsappAccount?.sourceAccountIdentifier;
1924
+ params.host = this.state?.hostName;
1839
1925
  }
1840
1926
  this.delay(() => {
1841
1927
  this.getAllTemplates({params, resetPage: true});
@@ -2439,7 +2525,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2439
2525
  (rcsLoader !== undefined ? rcsLoader : false);
2440
2526
  return isLoading;
2441
2527
  }
2442
- getChannelTypeIllustrationInfo = (type) => {
2528
+ getChannelTypeIllustrationInfo = (type, hostNameNotFound) => {
2443
2529
  const { isFullMode, intl } = this.props;
2444
2530
  const templateIntlMsg = intl.formatMessage(messages.template);
2445
2531
  const templateText = isFullMode ? templateIntlMsg : '';
@@ -2465,16 +2551,28 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2465
2551
  illustrationImage: pushIllustration,
2466
2552
  title: <FormattedMessage {...messages.pushTitleIllustartion} values={{ template: templateText }} />,
2467
2553
  };
2468
- case WHATSAPP:
2469
- return {
2470
- buttonLabel: <FormattedMessage {...messages.newWhatsappTemplate} values={{ template: templateText }} />,
2471
- onClick: this.createTemplate,
2472
- illustrationImage: whatsappIllustration,
2473
- title: <FormattedMessage {...messages.whatsappTitleIllustration} values={{ template: templateText }} />,
2474
- description: <FormattedMessage {...messages.whatsappDescIllustration} />,
2475
- descriptionPosition: 'bottom',
2476
- descriptionClassName: 'illustration-desc',
2477
- };
2554
+ case WHATSAPP: {
2555
+ if (hostNameNotFound) {
2556
+ return {
2557
+ illustrationImage: whatsappOrZaloAccountIllustration,
2558
+ title: <FormattedMessage {...messages.whatsappAccountNotConfiguredTitle} />,
2559
+ description: <FormattedMessage {...messages.accountNotConfiguredDescription} />,
2560
+ descriptionPosition: 'bottom',
2561
+ descriptionClassName: 'illustration-desc zalo-illustration',
2562
+ buttonClassName: "zalo-illustration-button",
2563
+ };
2564
+ } else {
2565
+ return {
2566
+ buttonLabel: <FormattedMessage {...messages.newWhatsappTemplate} values={{ template: templateText }} />,
2567
+ onClick: this.createTemplate,
2568
+ illustrationImage: whatsappIllustration,
2569
+ title: <FormattedMessage {...messages.whatsappTitleIllustration} values={{ template: templateText }} />,
2570
+ description: <FormattedMessage {...messages.whatsappDescIllustration} />,
2571
+ descriptionPosition: 'bottom',
2572
+ descriptionClassName: 'illustration-desc',
2573
+ };
2574
+ }
2575
+ }
2478
2576
  case RCS:
2479
2577
  return {
2480
2578
  buttonLabel: <FormattedMessage {...messages.newRCSTemplate} values={{ template: templateText }} />,
@@ -2485,15 +2583,27 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2485
2583
  descriptionPosition: 'bottom',
2486
2584
  descriptionClassName: 'illustration-desc rcs-illustration',
2487
2585
  };
2488
- case ZALO:
2489
- return {
2490
- illustrationImage: zaloillustration,
2491
- title: <FormattedMessage {...messages.zaloTitleIllustration} />,
2492
- description: <FormattedMessage {...messages.zaloDescIllustration} />,
2493
- descriptionPosition: 'bottom',
2494
- descriptionClassName: 'illustration-desc zalo-illustration',
2495
- buttonClassName: "zalo-illustration-button",
2496
- };
2586
+ case ZALO:{
2587
+ if (hostNameNotFound) {
2588
+ return {
2589
+ illustrationImage: whatsappOrZaloAccountIllustration,
2590
+ title: <FormattedMessage {...messages.zaloAccountNotConfiguredTitle} />,
2591
+ description: <FormattedMessage {...messages.accountNotConfiguredDescription} />,
2592
+ descriptionPosition: 'bottom',
2593
+ descriptionClassName: 'illustration-desc zalo-illustration',
2594
+ buttonClassName: "zalo-illustration-button",
2595
+ };
2596
+ } else {
2597
+ return {
2598
+ illustrationImage: zaloillustration,
2599
+ title: <FormattedMessage {...messages.zaloTitleIllustration} />,
2600
+ description: <FormattedMessage {...messages.zaloDescIllustration} />,
2601
+ descriptionPosition: 'bottom',
2602
+ descriptionClassName: 'illustration-desc zalo-illustration',
2603
+ buttonClassName: "zalo-illustration-button",
2604
+ };
2605
+ }
2606
+ }
2497
2607
  case INAPP:
2498
2608
  return {
2499
2609
  illustrationImage: inAppIllustration,
@@ -2560,10 +2670,9 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2560
2670
  const isMobilePushChannel = channel === MOBILE_PUSH;
2561
2671
  const isInAppChannel = channel === INAPP;
2562
2672
  const isFacebookChannel = channel === FACEBOOK;
2563
-
2564
- if ([WECHAT, MOBILE_PUSH, INAPP, LINE, ZALO].includes(channel) && !isEmpty(weCrmAccounts) && !isFacebookChannel) {
2673
+ if ([WECHAT, MOBILE_PUSH, INAPP, LINE, ZALO, WHATSAPP].includes(channel) && !isEmpty(weCrmAccounts) && !isFacebookChannel) {
2565
2674
  forEach(weCrmAccounts, (account) => {
2566
- if ((isWechatChannel && account.configs && account.configs.is_wecrm_enabled) || [MOBILE_PUSH, INAPP, LINE, ZALO].includes(channel)) {
2675
+ if ((isWechatChannel && account.configs && account.configs.is_wecrm_enabled) || [MOBILE_PUSH, INAPP, LINE, ZALO, WHATSAPP].includes(channel)) {
2567
2676
  if (query.type === 'embedded' && (!query.module || (query.module && query.module !== 'library'))) {
2568
2677
  if (query.source_account_id && account.sourceAccountIdentifier === query.source_account_id) {
2569
2678
  accountOptions.push(
@@ -2646,9 +2755,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2646
2755
  break;
2647
2756
  }
2648
2757
  let showNoAccountHeader = isEmpty(weCrmAccounts) && !fetchingWeCrmAccounts;
2649
- if (channel === WHATSAPP && this.state.hostName === '') {
2650
- showNoAccountHeader = true;
2651
- }
2652
2758
  if (channel === FACEBOOK && !isEmpty(campaignSettings) ) {
2653
2759
  const fbSetting = get(campaignSettings, 'accountSettings.socialAccountSettings.facebookAccountSettings', []);
2654
2760
  const { orgUnitFacebookPageSettingsMap } = fbSetting[0] || {};
@@ -2857,10 +2963,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2857
2963
  }
2858
2964
  }
2859
2965
 
2860
- const getCategoryOptions = (hostName) => {
2861
- return CATEGORY_OPTIONS_MAP[hostName];
2862
- };
2863
-
2864
2966
  const cmsTemplateSelectionContent = (
2865
2967
  <CardGrid
2866
2968
  className={""}
@@ -2874,7 +2976,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2874
2976
  );
2875
2977
  //TODO -> uncomment the following line
2876
2978
  // const isfilterContentVisisble = !isEmpty(this.props.TemplatesList) || !isEmpty(this.state.searchText) || !isEmpty(this.props.Templates.templateError);
2877
- const isfilterContentVisisble = true;
2979
+ let isfilterContentVisisble = true;
2878
2980
  const isWechatEmbedded = !this.props.isFullMode && channel.toUpperCase() === WECHAT;
2879
2981
  const channelLowerCase = (channel || '').toLowerCase();
2880
2982
  const isTraiDltFeature = this.checkDLTfeatureEnable();
@@ -2889,7 +2991,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2889
2991
  className="create-new-link"
2890
2992
  />
2891
2993
  )
2892
- : this.state.channel.toLowerCase() === ZALO_LOWERCASE ? <></> : (
2994
+ : this.state?.channel?.toLowerCase() === ZALO_LOWERCASE || (channelLowerCase === WHATSAPP_LOWERCASE && isEmpty(this.state?.hostName)) ? <></> : (
2893
2995
  <CapButton
2894
2996
  className={`create-new-${channelLowerCase} margin-l-8 margin-b-12`}
2895
2997
  type={"primary"}
@@ -2903,7 +3005,9 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2903
3005
  const isWhatsappCountExeeded = templatesCount >= MAX_WHATSAPP_TEMPLATES;
2904
3006
  const showWhatsappCountWarning = templatesCount >= WARNING_WHATSAPP_TEMPLATES;
2905
3007
  const whatsappCountExceedText = <FormattedMessage {...messages.whatsappMaxTemplates} values={{ maxCount: MAX_WHATSAPP_TEMPLATES }}/>;
2906
-
3008
+ if (([WHATSAPP_LOWERCASE, ZALO_LOWERCASE].includes(this.state?.channel?.toLocaleLowerCase()) && isEmpty(this.state?.hostName))) {
3009
+ isfilterContentVisisble = false;
3010
+ }
2907
3011
  const filterContent = (( isfilterContentVisisble || [WECHAT, MOBILE_PUSH, INAPP].includes(this.state.channel.toUpperCase())) && <div className="action-container">
2908
3012
  {isfilterContentVisisble && <CapInput.Search
2909
3013
  className="search-text"
@@ -2932,7 +3036,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2932
3036
  channel.toUpperCase() === ZALO && (
2933
3037
  <div className="zalo-filters">
2934
3038
  {
2935
- this.props.isFullMode ? (
3039
+ this.props?.isFullMode && this.state?.hostName ? (
2936
3040
  <CapSelectFilter
2937
3041
  placement="bottomLeft"
2938
3042
  data={ZALO_STATUS_OPTIONS}
@@ -2951,7 +3055,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2951
3055
  channel.toUpperCase() === WHATSAPP && (
2952
3056
  <div className="whatsapp-filters">
2953
3057
  {
2954
- this.props.isFullMode ? (
3058
+ this.props?.isFullMode && this.state?.hostName ? (
2955
3059
  <CapSelectFilter
2956
3060
  placement="bottomLeft"
2957
3061
  data={STATUS_OPTIONS}
@@ -2963,16 +3067,20 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2963
3067
  />
2964
3068
  ) : null
2965
3069
  }
2966
- <CapSelectFilter
2967
- placement="bottomLeft"
2968
- data={getCategoryOptions(this.state.hostName)}
2969
- onSelect={this.setWhatsappCategory}
2970
- selectedValue={this.state.selectedWhatsappCategory}
2971
- placeholder="Category"
2972
- showBadge
2973
- width="105px"
2974
- overlayStyle={{ overflowY: "hidden" }}
2975
- />
3070
+ {this.state?.hostName ? (
3071
+ <CapSelectFilter
3072
+ placement="bottomLeft"
3073
+ data={this.state.hostName === HOST_TWILIO
3074
+ ? TWILIO_CATEGORY_OPTIONS
3075
+ : KARIX_GUPSHUP_CATEGORY_OPTIONS}
3076
+ onSelect={this.setWhatsappCategory}
3077
+ selectedValue={this.state.selectedWhatsappCategory}
3078
+ placeholder="Category"
3079
+ showBadge
3080
+ width="105px"
3081
+ overlayStyle={{ overflowY: "hidden" }}
3082
+ />
3083
+ ) : null}
2976
3084
  </div>
2977
3085
 
2978
3086
  )
@@ -3045,7 +3153,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
3045
3153
  }
3046
3154
  <div style={{display: "flex", justifyContent: "space-between", alignItems: 'center'}}>
3047
3155
  {
3048
- this.state.channel.toLowerCase() === WHATSAPP_LOWERCASE && isWhatsappCountExeeded ? (
3156
+ this.state?.channel?.toLowerCase() === WHATSAPP_LOWERCASE && (isWhatsappCountExeeded)? (
3049
3157
  <CapTooltip title={whatsappCountExceedText}>
3050
3158
  <div className="button-disabled-tooltip-wrapper">
3051
3159
  {createButton}
@@ -354,6 +354,18 @@ export default defineMessages({
354
354
  id: `${scope}.whatsappDescIllustration`,
355
355
  defaultMessage: 'These templates can be reused when creating a\nnew message content.',
356
356
  },
357
+ "whatsappAccountNotConfiguredTitle": {
358
+ id: `${scope}.whatsappAccountNotConfiguredTitle`,
359
+ defaultMessage: 'Whatsapp account is not configured',
360
+ },
361
+ "accountNotConfiguredDescription": {
362
+ id: `${scope}.accountNotConfiguredDescription`,
363
+ defaultMessage: 'Please contact your Customer Success Manager to fix the issue.',
364
+ },
365
+ "zaloAccountNotConfiguredTitle": {
366
+ id: `${scope}.zaloAccountNotConfiguredTitle`,
367
+ defaultMessage: 'Zalo account is not configured',
368
+ },
357
369
  "zaloTitleIllustration": {
358
370
  id: `${scope}.zaloTitleIllustration`,
359
371
  defaultMessage: 'There are no approved templates available',
@@ -180,12 +180,17 @@ function templatesReducer(state = initialState, action) {
180
180
  return state.set('fetchedOrgLevelCampaignSettings', false);
181
181
  case types.GET_SENDER_DETAILS_REQUEST:
182
182
  return state.set('senderDetails', { status: 'REQUEST' });
183
- case types.GET_SENDER_DETAILS_SUCCESS:
183
+ case types.GET_SENDER_DETAILS_SUCCESS: {
184
+ const { channel, domainProperties = {} } = action?.payload || {};
185
+ const isMultiAccountChannel = ['WHATSAPP', 'ZALO'].includes(channel);
186
+ const senderDetailsKey = isMultiAccountChannel ? 'domainProperties' : 'hostName';
187
+ // For Whatsapp and Zalo we need to store domainProperties instead of only hostName
184
188
  return state.set('senderDetails', {
185
189
  status: 'SUCCESS',
186
- hostName: action.payload,
190
+ [senderDetailsKey]: isMultiAccountChannel ? domainProperties : action?.payload,
187
191
  errors: [],
188
192
  });
193
+ }
189
194
  case types.GET_SENDER_DETAILS_FAILURE:
190
195
  return state.set('senderDetails', {
191
196
  status: 'FAILURE',
@@ -161,8 +161,13 @@ export function* getSenderDetails({
161
161
  if (!apiResponse?.errors?.length) {
162
162
  yield put({
163
163
  type: types.GET_SENDER_DETAILS_SUCCESS,
164
- payload: get(apiResponse, `entity.${channel}[0].domainProperties.hostName`, ''),
164
+ payload: ['WHATSAPP', 'ZALO'].includes(channel) ?
165
+ { channel,
166
+ domainProperties: get(apiResponse, `entity.${channel}`, '')
167
+ } :
168
+ get(apiResponse, `entity.${channel}[0].domainProperties.hostName`, ''),
165
169
  });
170
+
166
171
  } else {
167
172
  yield put({
168
173
  type: types.GET_SENDER_DETAILS_FAILURE,