@capillarytech/creatives-library 7.10.39 → 7.10.41
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/containers/Assets/Gallery/tests/__snapshots__/reducer.test.js.snap +0 -2
- package/containers/Email/index.js +2 -3
- package/index.js +6 -0
- package/package.json +1 -1
- package/routes.js +5 -0
- package/services/api.js +6 -1
- package/v2Components/TemplatePreview/_templatePreview.scss +7 -0
- package/v2Components/TemplatePreview/assets/images/whatsapp_mobile_android.svg +2041 -0
- package/v2Components/TemplatePreview/index.js +57 -3
- package/v2Components/TemplatePreview/messages.js +8 -0
- package/v2Containers/Assets/Gallery/tests/__snapshots__/reducer.test.js.snap +0 -2
- package/v2Containers/Assets/images/whatsappIllustration.png +0 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +31 -2
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +31 -3
- package/v2Containers/CreativesContainer/constants.js +1 -0
- package/v2Containers/CreativesContainer/messages.js +4 -0
- package/v2Containers/Email/index.js +1 -3
- package/v2Containers/Line/Container/index.js +1 -1
- package/v2Containers/Templates/_templates.scss +43 -0
- package/v2Containers/Templates/actions.js +18 -10
- package/v2Containers/Templates/constants.js +3 -1
- package/v2Containers/Templates/index.js +296 -44
- package/v2Containers/Templates/messages.js +32 -0
- package/v2Containers/Templates/reducer.js +3 -1
- package/v2Containers/TemplatesV2/index.js +2 -0
- package/v2Containers/TemplatesV2/messages.js +4 -0
- package/v2Containers/Whatsapp/actions.js +34 -0
- package/v2Containers/Whatsapp/constants.js +125 -0
- package/v2Containers/Whatsapp/index.js +831 -0
- package/v2Containers/Whatsapp/index.scss +56 -0
- package/v2Containers/Whatsapp/messages.js +221 -0
- package/v2Containers/Whatsapp/reducer.js +54 -0
- package/v2Containers/Whatsapp/sagas.js +77 -0
- package/v2Containers/Whatsapp/selectors.js +12 -0
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +120831 -0
- package/v2Containers/Whatsapp/tests/index.test.js +132 -0
- package/v2Containers/Whatsapp/tests/mockData.js +10 -0
- package/v2Containers/Whatsapp/utils.js +106 -0
|
@@ -22,7 +22,7 @@ import find from 'lodash/find';
|
|
|
22
22
|
import map from 'lodash/map';
|
|
23
23
|
import { bindActionCreators } from 'redux';
|
|
24
24
|
import { Modal, Form} from 'antd';
|
|
25
|
-
import {CapMenu, CapDropdown, CapButton, CapInput, CapIcon, CapRadioCard, CapPopover, CapSpin, CapCustomCard, CapRow, CapSlideBox, CapLink, CapHeading, CapNotification, CapIllustration, CapHeader, CapLabel, CapRadio} from '@capillarytech/cap-ui-library';
|
|
25
|
+
import {CapMenu, CapDropdown, CapButton, CapInput, CapIcon, CapRadioCard, CapPopover, CapSpin, CapCustomCard, CapRow, CapSlideBox, CapLink, CapHeading, CapNotification, CapIllustration, CapHeader, CapLabel, CapRadio, CapSelectFilter, CapTag, CapTooltip, CapAlert } from '@capillarytech/cap-ui-library';
|
|
26
26
|
import { makeSelectTemplates, makeSelectTemplatesResponse } from './selectors';
|
|
27
27
|
import { makeSelectCreate as makeSelectCreateSms} from '../Sms/Create/selectors';
|
|
28
28
|
import { makeSelectCreate as makeSelectCreateMobilePush } from '../MobilePush/Create/selectors';
|
|
@@ -43,7 +43,7 @@ import * as emailActions from '../Email/actions';
|
|
|
43
43
|
import * as lineActions from '../Line/Container/actions';
|
|
44
44
|
import * as viberActions from '../Viber/actions';
|
|
45
45
|
import * as facebookActions from '../Facebook/actions';
|
|
46
|
-
|
|
46
|
+
import * as whatsappActions from '../Whatsapp/actions';
|
|
47
47
|
import CardGrid from '../../v2Components/CardGrid';
|
|
48
48
|
import config from '../../config/app';
|
|
49
49
|
import './_templates.scss';
|
|
@@ -60,13 +60,23 @@ import {
|
|
|
60
60
|
VIBER as VIBER_CHANNEL,
|
|
61
61
|
FACEBOOK as FACEBOOK_CHANNEL,
|
|
62
62
|
} from '../App/constants';
|
|
63
|
-
import {
|
|
63
|
+
import { MAX_WHATSAPP_TEMPLATES } from './constants';
|
|
64
|
+
import {
|
|
65
|
+
CATEGORY_OPTIONS,
|
|
66
|
+
STATUS_OPTIONS,
|
|
67
|
+
CATEGORY as WHATSAPP_CATEGORY,
|
|
68
|
+
STATUS as WHATSAPP_STATUS,
|
|
69
|
+
WHATSAPP_STATUSES,
|
|
70
|
+
} from '../Whatsapp/constants';
|
|
71
|
+
import { getWhatsappContent, getWhatsappStatusContainer, getWhatsappStatus, getWhatsappCategory } from '../Whatsapp/utils';
|
|
72
|
+
import { MOBILE_PUSH, WECHAT, SMS, EMAIL, EBILL, LINE, VIBER, FACEBOOK, WHATSAPP } from '../CreativesContainer/constants';
|
|
64
73
|
|
|
65
74
|
import {CREATIVE} from '../Facebook/constants';
|
|
66
75
|
|
|
67
76
|
import emailIllustration from '../Assets/images/emailIllustration.svg';
|
|
68
77
|
import smsIllustration from '../Assets/images/smsIllustration.svg';
|
|
69
78
|
import pushIllustration from '../Assets/images/pushIllustration.svg';
|
|
79
|
+
import whatsappIllustration from '../Assets/images/whatsappIllustration.png';
|
|
70
80
|
import { CAP_SPACE_16 } from '@capillarytech/cap-ui-library/styled/variables';
|
|
71
81
|
import { GA } from '@capillarytech/cap-ui-utils';
|
|
72
82
|
const { timeTracker } = GA;
|
|
@@ -105,6 +115,7 @@ const SMS_FILTERS = {
|
|
|
105
115
|
SERVICE_IMPLICIT: 'implicit',
|
|
106
116
|
};
|
|
107
117
|
|
|
118
|
+
const WHATSAPP_LOWERCASE = WHATSAPP.toLowerCase();
|
|
108
119
|
export class Templates extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
|
109
120
|
constructor(props) {
|
|
110
121
|
super(props);
|
|
@@ -133,6 +144,8 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
133
144
|
wechatFilter: WECHAT_FILTERS.ALL,
|
|
134
145
|
lineFilter: LINE_FILTERS.ALL,
|
|
135
146
|
smsFilter: SMS_FILTERS.ALL,
|
|
147
|
+
selectedWhatsappStatus: '',
|
|
148
|
+
selectedWhatsappCategory: ''
|
|
136
149
|
};
|
|
137
150
|
|
|
138
151
|
this.handleOnHoverItem = this.handleOnHoverItem.bind(this);
|
|
@@ -198,6 +211,11 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
198
211
|
activeMode = ACCOUNT_SELECTION_MODE;
|
|
199
212
|
this.props.actions.getAccountsSettings();
|
|
200
213
|
break;
|
|
214
|
+
case WHATSAPP:
|
|
215
|
+
channel = 'Whatsapp';
|
|
216
|
+
activeMode = ACCOUNT_SELECTION_MODE;
|
|
217
|
+
this.props.actions.getWeCrmAccounts(channel);
|
|
218
|
+
break;
|
|
201
219
|
default:
|
|
202
220
|
channel = '';
|
|
203
221
|
}
|
|
@@ -245,9 +263,8 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
245
263
|
};
|
|
246
264
|
const { totalCount: nextPropsTotalTemplatesCount } = nextProps?.TemplatesList?.[0] || {};
|
|
247
265
|
const { totalCount: propsTotalTemplatesCount } = this.props?.TemplatesList?.[0] || {};
|
|
248
|
-
const { templatesCount } = this.state || {};
|
|
249
266
|
|
|
250
|
-
if (nextPropsTotalTemplatesCount && nextPropsTotalTemplatesCount !== propsTotalTemplatesCount
|
|
267
|
+
if (nextPropsTotalTemplatesCount && nextPropsTotalTemplatesCount !== propsTotalTemplatesCount) {
|
|
251
268
|
this.setState({ templatesCount: nextPropsTotalTemplatesCount });
|
|
252
269
|
}
|
|
253
270
|
if (!isEqual(nextProps.route.name, this.props.route.name)) {
|
|
@@ -422,6 +439,8 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
422
439
|
this.props.viberActions.clearCreateResponse();
|
|
423
440
|
} else if (this.state.channel.toLowerCase() === FACEBOOK_CHANNEL) {
|
|
424
441
|
this.props.facebookActions.clearCreateResponse();
|
|
442
|
+
}else if (this.state.channel.toLowerCase() === WHATSAPP_LOWERCASE) {
|
|
443
|
+
this.props.whatsappActions.clearCreateResponse();
|
|
425
444
|
}
|
|
426
445
|
}
|
|
427
446
|
}
|
|
@@ -463,16 +482,25 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
463
482
|
this.setState({previewTemplate: nextProps.Templates.templateDetails});
|
|
464
483
|
}
|
|
465
484
|
|
|
466
|
-
if (nextProps.Templates.weCrmAccounts !== undefined && nextProps.Templates.weCrmAccounts.length === 1 && this.state.defaultAccount && (['wechat'].indexOf(this.state.channel.toLowerCase()) > -1)) {
|
|
485
|
+
if (nextProps.Templates.weCrmAccounts !== undefined && nextProps.Templates.weCrmAccounts.length === 1 && this.state.defaultAccount && (['wechat', WHATSAPP_LOWERCASE].indexOf(this.state.channel.toLowerCase()) > -1 )) {
|
|
467
486
|
const paramsDefault = {
|
|
468
487
|
name: this.state.searchText,
|
|
469
488
|
sortBy: this.state.sortBy,
|
|
470
489
|
};
|
|
471
|
-
if (this.state.channel.toLowerCase()
|
|
490
|
+
if (['wechat', WHATSAPP_LOWERCASE].includes(this.state.channel.toLowerCase())) {
|
|
472
491
|
paramsDefault.wecrmId = nextProps.Templates.weCrmAccounts[0].configs.wecrm_app_id;
|
|
473
492
|
paramsDefault.wecrmToken = nextProps.Templates.weCrmAccounts[0].configs.wecrm_token;
|
|
474
493
|
paramsDefault.originalId = nextProps.Templates.weCrmAccounts[0].sourceAccountIdentifier;
|
|
475
|
-
|
|
494
|
+
if (WHATSAPP_LOWERCASE === this.state.channel.toLowerCase()) {
|
|
495
|
+
nextProps.actions.setChannelAccount(
|
|
496
|
+
WHATSAPP,
|
|
497
|
+
nextProps.Templates.weCrmAccounts[0],
|
|
498
|
+
);
|
|
499
|
+
} else {
|
|
500
|
+
nextProps.actions.setWeChatAccount(
|
|
501
|
+
nextProps.Templates.weCrmAccounts[0],
|
|
502
|
+
);
|
|
503
|
+
}
|
|
476
504
|
}
|
|
477
505
|
this.setState({defaultAccount: false, activeMode: TEMPLATES_MODE, selectedAccount: nextProps.Templates.weCrmAccounts[0].name });
|
|
478
506
|
this.getAllTemplates({params: paramsDefault}, true);
|
|
@@ -512,8 +540,10 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
512
540
|
} else {
|
|
513
541
|
this.setState({selectedAccountError: false});
|
|
514
542
|
}
|
|
515
|
-
} else if (this.state.channel.toLowerCase() ===
|
|
516
|
-
this.props.actions.
|
|
543
|
+
} else if (this.state.channel.toLowerCase() === LINE.toLowerCase()) {
|
|
544
|
+
this.props.actions.setChannelAccount(LINE, this.props.Templates.weCrmAccounts.find((item) => item.name === this.state.selectedAccount));
|
|
545
|
+
} else if (this.state.channel.toLowerCase() === WHATSAPP_LOWERCASE) {
|
|
546
|
+
this.props.actions.setChannelAccount(WHATSAPP, this.props.Templates.weCrmAccounts.find((item) => item.name === this.state.selectedAccount));
|
|
517
547
|
}
|
|
518
548
|
|
|
519
549
|
this.setState({activeMode: TEMPLATES_MODE});
|
|
@@ -525,8 +555,9 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
525
555
|
this.getAllTemplates({getNextPage: true});
|
|
526
556
|
}
|
|
527
557
|
onCreateComplete = (isReloadTemplates) => {
|
|
558
|
+
const isWhatsappEdit = this.state.routeParams?.pathname?.includes(`${WHATSAPP_LOWERCASE}/edit`);
|
|
528
559
|
this.setState({routeParams: null, previewOpen: false}, () => {
|
|
529
|
-
if (this.isFullMode() && isReloadTemplates) {
|
|
560
|
+
if (this.isFullMode() && (isReloadTemplates || isWhatsappEdit)) {
|
|
530
561
|
this.getAllTemplates({params: {}}, true);
|
|
531
562
|
}
|
|
532
563
|
});
|
|
@@ -546,7 +577,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
546
577
|
const { pathname } = routeParams;
|
|
547
578
|
if (pathname.includes('create')) {
|
|
548
579
|
creativesParams.mode = 'create';
|
|
549
|
-
} else if (pathname.includes('edit')) {
|
|
580
|
+
} else if (pathname.includes('edit') || pathname.includes('overview')) {
|
|
550
581
|
creativesParams.mode = 'edit';
|
|
551
582
|
if (pathname.includes('richmedia')) {
|
|
552
583
|
creativesParams._id = pathname.split('/')[4];
|
|
@@ -557,6 +588,11 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
557
588
|
creativesParams._id = pathname.split('/')[3];
|
|
558
589
|
creativesParams.modeType = pathname.split('/')[4];
|
|
559
590
|
creativesParams.account = pathname.split('/')[5];
|
|
591
|
+
if(this.state.channel.toLowerCase() === WHATSAPP_LOWERCASE){
|
|
592
|
+
const whatsappSelectedTemplateData = this.selectTemplate(creativesParams._id) || {};
|
|
593
|
+
creativesParams.whatsappTemplateName = get(whatsappSelectedTemplateData, `name`, '');
|
|
594
|
+
creativesParams.whatsappTemplateCategory = get(whatsappSelectedTemplateData, `versions.base.content.whatsapp.category`, '');
|
|
595
|
+
}
|
|
560
596
|
}
|
|
561
597
|
creativesParams.type = this.state.channel.toUpperCase();
|
|
562
598
|
}
|
|
@@ -654,6 +690,32 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
654
690
|
return templates;
|
|
655
691
|
}
|
|
656
692
|
}
|
|
693
|
+
|
|
694
|
+
isStatusMatching = (status, selectedWhatsappStatus) => {
|
|
695
|
+
if ( [WHATSAPP_STATUSES.unsubmitted, WHATSAPP_STATUSES.pending].includes(status) ) {
|
|
696
|
+
return selectedWhatsappStatus === WHATSAPP_STATUSES.awaitingApproval;
|
|
697
|
+
}
|
|
698
|
+
return selectedWhatsappStatus === status;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
filterWhatsappTemplates = (templates) => {
|
|
702
|
+
const { selectedWhatsappStatus, selectedWhatsappCategory } = this.state;
|
|
703
|
+
return templates.filter((template) => {
|
|
704
|
+
const { [WHATSAPP_CATEGORY]: category, [WHATSAPP_STATUS]: status } = template?.versions?.base?.content?.[WHATSAPP_LOWERCASE] || {};
|
|
705
|
+
|
|
706
|
+
// if status or category filter is applied, filter templates which match these filters
|
|
707
|
+
return (
|
|
708
|
+
selectedWhatsappStatus
|
|
709
|
+
? this.isStatusMatching(status, selectedWhatsappStatus)
|
|
710
|
+
: true
|
|
711
|
+
) && (
|
|
712
|
+
selectedWhatsappCategory
|
|
713
|
+
? category === selectedWhatsappCategory
|
|
714
|
+
: true
|
|
715
|
+
);
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
|
|
657
719
|
filterSMSTemplates = (templates) => {
|
|
658
720
|
const { smsFilter } = this.state;
|
|
659
721
|
if (SMS_FILTERS.ALL === smsFilter) {
|
|
@@ -662,22 +724,44 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
662
724
|
return templates.filter((template) => template.versions.base.type?.toLowerCase()?.includes(smsFilter));
|
|
663
725
|
}
|
|
664
726
|
|
|
727
|
+
getCreativesEditText = (channel) => {
|
|
728
|
+
if (channel === WHATSAPP_LOWERCASE) {
|
|
729
|
+
return messages.whatsappOverview;
|
|
730
|
+
}
|
|
731
|
+
return messages.creativesTemplatesEdit;
|
|
732
|
+
}
|
|
733
|
+
|
|
665
734
|
getTemplateDataForGrid = ({templates, handlers, filterContent, channel, isLoading, loadingTip}) => {
|
|
666
735
|
const currentChannel = channel.toUpperCase();
|
|
667
736
|
const {channel: stateChannel} = this.state;
|
|
668
737
|
const channelLowerCase = stateChannel.toLowerCase();
|
|
669
738
|
let filteredTemplates = templates;
|
|
670
739
|
let isTraiDltFeature = false;
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
740
|
+
switch (currentChannel) {
|
|
741
|
+
case WECHAT:
|
|
742
|
+
filteredTemplates = this.filterWechatTemplates(templates);
|
|
743
|
+
break;
|
|
744
|
+
case WHATSAPP:
|
|
745
|
+
filteredTemplates = this.filterWhatsappTemplates(templates);
|
|
746
|
+
break;
|
|
747
|
+
case LINE:
|
|
748
|
+
filteredTemplates = this.filterLineTemplates(templates);
|
|
749
|
+
break;
|
|
750
|
+
case SMS:
|
|
751
|
+
filteredTemplates = this.filterSMSTemplates(templates);
|
|
752
|
+
isTraiDltFeature = this.checkDLTfeatureEnable();
|
|
753
|
+
break;
|
|
754
|
+
default:
|
|
755
|
+
break;
|
|
680
756
|
}
|
|
757
|
+
|
|
758
|
+
const hoverButtonText =
|
|
759
|
+
this.props.intl.formatMessage(
|
|
760
|
+
this.props.isFullMode
|
|
761
|
+
? this.getCreativesEditText(channelLowerCase)
|
|
762
|
+
: messages.selectButton
|
|
763
|
+
);
|
|
764
|
+
|
|
681
765
|
const cardDataList = filteredTemplates && filteredTemplates.length ? map(filteredTemplates, (template) => {
|
|
682
766
|
const templateData =
|
|
683
767
|
{
|
|
@@ -691,13 +775,13 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
691
775
|
onClick={() => { if (this.props.isFullMode) { handlers.handlePreviewClick(template); } else { this.props.handlePeviewTemplate(template); } }}
|
|
692
776
|
/>,
|
|
693
777
|
],
|
|
694
|
-
hoverOption: <CapButton className={this.props.isFullMode ? `edit-${channelLowerCase}` : `select-${channelLowerCase}`} onClick={(e) => handlers.handleEditClick(e, template, undefined, undefined, {account: this.state.selectedAccount})}>{
|
|
778
|
+
hoverOption: <CapButton className={this.props.isFullMode ? `edit-${channelLowerCase}` : `select-${channelLowerCase}`} onClick={(e) => handlers.handleEditClick(e, template, undefined, undefined, {account: this.state.selectedAccount})}>{hoverButtonText}</CapButton>,
|
|
695
779
|
};
|
|
696
780
|
if (this.props.isFullMode) {
|
|
697
781
|
templateData.extra.push(<CapDropdown
|
|
698
782
|
overlay={
|
|
699
783
|
<CapMenu>
|
|
700
|
-
{this.state.channel.toUpperCase()
|
|
784
|
+
{ ![WECHAT, WHATSAPP].includes(this.state.channel.toUpperCase()) && !isTraiDltFeature && <CapMenu.Item className={`duplicate-${channelLowerCase}`} onClick={() => this.duplicateTemplate(template)}>
|
|
701
785
|
<FormattedMessage {...messages.duplicateButton} />
|
|
702
786
|
</CapMenu.Item>}
|
|
703
787
|
<CapMenu.Item
|
|
@@ -834,6 +918,16 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
834
918
|
}
|
|
835
919
|
break;
|
|
836
920
|
}
|
|
921
|
+
case WHATSAPP:
|
|
922
|
+
templateData.title = (
|
|
923
|
+
<div className="whatsapp-card-title">
|
|
924
|
+
<span title={template.name} >{template.name}</span>
|
|
925
|
+
{getWhatsappStatusContainer(template)}
|
|
926
|
+
</div>
|
|
927
|
+
);
|
|
928
|
+
|
|
929
|
+
templateData.content = getWhatsappContent(template);
|
|
930
|
+
break;
|
|
837
931
|
default:
|
|
838
932
|
templateData.content = "";
|
|
839
933
|
}
|
|
@@ -842,8 +936,9 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
842
936
|
const accountId = get(this.props, 'Templates.selectedWeChatAccount.uuid');
|
|
843
937
|
const accounts = get(this.props, 'Templates.weCrmAccounts');
|
|
844
938
|
return (<div>
|
|
845
|
-
{
|
|
939
|
+
{[WECHAT, MOBILE_PUSH].includes(currentChannel) && this.showAccountName()}
|
|
846
940
|
{filterContent}
|
|
941
|
+
{[WHATSAPP].includes(currentChannel) && this.selectedFilters()}
|
|
847
942
|
<CapSpin spinning={isLoading} tip={loadingTip} style={{width: '100%'}}>
|
|
848
943
|
{<div>
|
|
849
944
|
{!isEmpty(filteredTemplates) || !isEmpty(this.state.searchText) || !isEmpty(this.props.Templates.templateError) ? (
|
|
@@ -865,7 +960,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
865
960
|
</div>
|
|
866
961
|
}
|
|
867
962
|
|
|
868
|
-
{ !isEmpty(this.props.Templates.selectedWeChatAccount) && this.state.channel.toLowerCase()
|
|
963
|
+
{ !isEmpty(this.props.Templates.selectedWeChatAccount) && ["mobilepush"].includes(this.state.channel.toLowerCase()) && this.state.selectedAccountError ?
|
|
869
964
|
<div style={{ height: '65vh', textAlign: 'center', lineHeight: '65vh'}}>
|
|
870
965
|
<CapHeading type="h6" >
|
|
871
966
|
{this.props.intl.formatMessage(messages.accountConfigError)}
|
|
@@ -882,6 +977,24 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
882
977
|
</div>
|
|
883
978
|
)
|
|
884
979
|
}
|
|
980
|
+
{ !isEmpty(this.props.Templates.selectedWhatsappAccount) && [WHATSAPP_LOWERCASE].includes(this.state.channel.toLowerCase()) && this.state.selectedAccountError ?
|
|
981
|
+
<div style={{ height: '65vh', textAlign: 'center', lineHeight: '65vh'}}>
|
|
982
|
+
<CapHeading type="h6" >
|
|
983
|
+
{this.props.intl.formatMessage(messages.accountConfigError)}
|
|
984
|
+
<InlineDiv>
|
|
985
|
+
<CapLink title="here" style={{display: 'inline'}} onClick={() => { window.open(config.production.accountConfig`${accountId}`); }}/>
|
|
986
|
+
</InlineDiv>
|
|
987
|
+
</CapHeading>
|
|
988
|
+
</div> : (
|
|
989
|
+
[WHATSAPP_LOWERCASE].includes(this.state.channel.toLowerCase()) &&
|
|
990
|
+
isEmpty(filteredTemplates) &&
|
|
991
|
+
isEmpty(this.state.searchText) &&
|
|
992
|
+
!isLoading &&
|
|
993
|
+
<div style={this.isFullMode() ? { height: "calc(100vh - 325px)", overflow: 'auto'} : {}}>
|
|
994
|
+
<CapIllustration buttonClassName={`create-new-${channelLowerCase}`} {...this.getChannelTypeIllustrationInfo(currentChannel)} />
|
|
995
|
+
</div>
|
|
996
|
+
)
|
|
997
|
+
}
|
|
885
998
|
</div>
|
|
886
999
|
}
|
|
887
1000
|
|
|
@@ -1456,6 +1569,9 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1456
1569
|
pathName = `/wechat/edit/${id}`;
|
|
1457
1570
|
}
|
|
1458
1571
|
}
|
|
1572
|
+
if (this.state.channel.toUpperCase() === WHATSAPP) {
|
|
1573
|
+
pathName = `/whatsapp/edit/${id}/`;
|
|
1574
|
+
}
|
|
1459
1575
|
if (this.isEnabledInLibraryModule("callSelectFromProps")) {
|
|
1460
1576
|
let data = id;
|
|
1461
1577
|
if (this.props.fbAdManager) {
|
|
@@ -1716,7 +1832,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1716
1832
|
if (this.props.location.query.type === "embedded" && this.props.location.query.module === "library") {
|
|
1717
1833
|
switch (property) {
|
|
1718
1834
|
case "showAccountSelection":
|
|
1719
|
-
return (this.props.route && (
|
|
1835
|
+
return (this.props.route && (['wechat', 'mobilepush', WHATSAPP_LOWERCASE].includes(this.props.route.name.toLowerCase())));
|
|
1720
1836
|
case "setLocale":
|
|
1721
1837
|
return true;
|
|
1722
1838
|
case "callCreateFromProps":
|
|
@@ -1734,9 +1850,13 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1734
1850
|
isCreateDisabled = () => {
|
|
1735
1851
|
let isDisabled = this.isLoading();
|
|
1736
1852
|
const channel = this.state.channel.toUpperCase();
|
|
1737
|
-
if (channel === MOBILE_PUSH || channel === WECHAT) {
|
|
1853
|
+
if (channel === MOBILE_PUSH || channel === WECHAT || channel === WHATSAPP) {
|
|
1738
1854
|
isDisabled = isDisabled || isEmpty(this.props.Templates.selectedWeChatAccount);
|
|
1739
1855
|
}
|
|
1856
|
+
if (channel === WHATSAPP) {
|
|
1857
|
+
// limit on max number of templates allowed for whatsapp
|
|
1858
|
+
isDisabled = this.state.templatesCount >= MAX_WHATSAPP_TEMPLATES;
|
|
1859
|
+
}
|
|
1740
1860
|
if (channel === MOBILE_PUSH) {
|
|
1741
1861
|
isDisabled = this.checkSearchDisabled();
|
|
1742
1862
|
}
|
|
@@ -1758,6 +1878,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1758
1878
|
const facebookLoader = (getAllTemplatesInProgress && this.state.channel.toLowerCase() === FACEBOOK_CHANNEL);
|
|
1759
1879
|
|
|
1760
1880
|
const wechatLoader = (((this.state.selectedAccount !== '' && getAllTemplatesInProgress) || (fetchingWeCrmAccounts)) && this.state.channel.toLowerCase() === 'wechat');
|
|
1881
|
+
const whatsappLoader = (((this.state.selectedAccount !== '' && getAllTemplatesInProgress) || (fetchingWeCrmAccounts)) && this.state.channel.toLowerCase() === WHATSAPP_LOWERCASE);
|
|
1761
1882
|
const mobilePushLoader = (((getAllTemplatesInProgress) || (fetchingWeCrmAccounts)) && this.state.channel.toLowerCase() === 'mobilepush');
|
|
1762
1883
|
const emailLoader = (
|
|
1763
1884
|
(getAllTemplatesInProgress ||
|
|
@@ -1766,6 +1887,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1766
1887
|
EmailCreate.duplicateTemplateInProgress) && this.state.channel.toLowerCase() === 'email');
|
|
1767
1888
|
const ebillLoader = ((getAllTemplatesInProgress || sendingFile) && this.state.channel.toLowerCase() === 'ebill');
|
|
1768
1889
|
const isLoading = ((wechatLoader !== undefined) ? wechatLoader : false) ||
|
|
1890
|
+
(whatsappLoader !== undefined ? whatsappLoader : false) ||
|
|
1769
1891
|
(smsLoader !== undefined ? smsLoader : false) ||
|
|
1770
1892
|
(emailLoader !== undefined ? emailLoader : false) ||
|
|
1771
1893
|
(ebillLoader !== undefined ? ebillLoader : false) ||
|
|
@@ -1801,6 +1923,16 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1801
1923
|
illustrationImage: pushIllustration,
|
|
1802
1924
|
title: <FormattedMessage {...messages.pushTitleIllustartion} values={{ template: templateText }} />,
|
|
1803
1925
|
};
|
|
1926
|
+
case WHATSAPP:
|
|
1927
|
+
return {
|
|
1928
|
+
buttonLabel: <FormattedMessage {...messages.newWhatsappTemplate} values={{ template: templateText }} />,
|
|
1929
|
+
onClick: this.createTemplate,
|
|
1930
|
+
illustrationImage: whatsappIllustration,
|
|
1931
|
+
title: <FormattedMessage {...messages.whatsappTitleIllustration} values={{ template: templateText }} />,
|
|
1932
|
+
description: <FormattedMessage {...messages.whatsappDescIllustration} />,
|
|
1933
|
+
descriptionPosition: 'bottom',
|
|
1934
|
+
descriptionClassName: 'whatsapp-illustration-desc',
|
|
1935
|
+
};
|
|
1804
1936
|
default:
|
|
1805
1937
|
return {};
|
|
1806
1938
|
}
|
|
@@ -1852,13 +1984,11 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1852
1984
|
const { weCrmAccounts = [], fetchingWeCrmAccounts = false, campaignSettings = {} } = templates;
|
|
1853
1985
|
const isWechatChannel = channel === WECHAT;
|
|
1854
1986
|
const isMobilePushChannel = channel === MOBILE_PUSH;
|
|
1855
|
-
const
|
|
1856
|
-
const isFacebookChannel = channel === FACEBOOK;
|
|
1857
|
-
|
|
1987
|
+
const isFacebookChannel = channel === FACEBOOK;
|
|
1858
1988
|
|
|
1859
|
-
if (
|
|
1989
|
+
if ([WECHAT, MOBILE_PUSH, LINE, WHATSAPP].includes(channel) && !isEmpty(weCrmAccounts) && !isFacebookChannel) {
|
|
1860
1990
|
forEach(weCrmAccounts, (account) => {
|
|
1861
|
-
if ((isWechatChannel && account.configs && account.configs.is_wecrm_enabled) ||
|
|
1991
|
+
if ((isWechatChannel && account.configs && account.configs.is_wecrm_enabled) || [MOBILE_PUSH, LINE, WHATSAPP].includes(channel)) {
|
|
1862
1992
|
if (query.type === 'embedded' && (!query.module || (query.module && query.module !== 'library'))) {
|
|
1863
1993
|
if (query.source_account_id && account.sourceAccountIdentifier === query.source_account_id) {
|
|
1864
1994
|
accountOptions.push(
|
|
@@ -1922,6 +2052,11 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1922
2052
|
noAccountHeader = messages.noAccountsPresentFacebook;
|
|
1923
2053
|
break;
|
|
1924
2054
|
}
|
|
2055
|
+
case WHATSAPP: {
|
|
2056
|
+
accountHeader = formatMessage(messages.whatsappAccount);
|
|
2057
|
+
noAccountHeader = messages.noAccountsPresentWhatsapp;
|
|
2058
|
+
break;
|
|
2059
|
+
}
|
|
1925
2060
|
default:
|
|
1926
2061
|
break;
|
|
1927
2062
|
}
|
|
@@ -1977,27 +2112,97 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1977
2112
|
this.setState({activeMode: TEMPLATES_MODE});
|
|
1978
2113
|
}
|
|
1979
2114
|
|
|
2115
|
+
accountNameMessage = (channel) => {
|
|
2116
|
+
const {
|
|
2117
|
+
intl: {
|
|
2118
|
+
formatMessage,
|
|
2119
|
+
},
|
|
2120
|
+
} = this.props;
|
|
2121
|
+
switch (channel?.toUpperCase()) {
|
|
2122
|
+
case MOBILE_PUSH:
|
|
2123
|
+
return formatMessage(messages.mobilepushAccount);
|
|
2124
|
+
case WECHAT:
|
|
2125
|
+
return formatMessage(messages.wechatAccount);
|
|
2126
|
+
case WHATSAPP:
|
|
2127
|
+
return formatMessage(messages.whatsappAccount);
|
|
2128
|
+
default:
|
|
2129
|
+
return '';
|
|
2130
|
+
}
|
|
2131
|
+
}
|
|
2132
|
+
|
|
1980
2133
|
showAccountName = () => {
|
|
1981
2134
|
const { activeMode, selectedAccount, channel } = this.state;
|
|
1982
2135
|
const { Templates: templates = {}} = this.props;
|
|
1983
|
-
const { weCrmAccounts = []} = templates;
|
|
1984
|
-
const isMobilePushChannel = channel === MOBILE_PUSH;
|
|
2136
|
+
const { weCrmAccounts = [] } = templates;
|
|
1985
2137
|
return (activeMode !== ACCOUNT_CHANGE_MODE &&
|
|
1986
2138
|
<CapHeader
|
|
1987
|
-
title={<CapHeading type="h4">{
|
|
2139
|
+
title={<CapHeading type="h4">{this.accountNameMessage(channel)}</CapHeading>}
|
|
1988
2140
|
description={<><CapHeading type="h3">{selectedAccount} {weCrmAccounts.length > 1 && <CapLink onClick={this.setAccountChangeMode} style={{display: 'inline-block', position: 'relative', top: '3px'}} fontWeight="regular" fontSize="14px" title="change"/>} </CapHeading></>}
|
|
1989
2141
|
size="regular"
|
|
1990
2142
|
/>);
|
|
1991
2143
|
}
|
|
1992
2144
|
|
|
2145
|
+
removeWhatsappFilter = (filter) => {
|
|
2146
|
+
switch (filter) {
|
|
2147
|
+
case WHATSAPP_STATUS:
|
|
2148
|
+
this.setState({ selectedWhatsappStatus: null });
|
|
2149
|
+
break;
|
|
2150
|
+
case WHATSAPP_CATEGORY:
|
|
2151
|
+
this.setState({ selectedWhatsappCategory: null });
|
|
2152
|
+
break;
|
|
2153
|
+
default:
|
|
2154
|
+
break;
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
|
|
2158
|
+
selectedFilters = () => {
|
|
2159
|
+
const { selectedWhatsappStatus, selectedWhatsappCategory } = this.state;
|
|
2160
|
+
return (
|
|
2161
|
+
<CapRow type="flex" align="middle" className="selected-whatsapp-filters">
|
|
2162
|
+
{
|
|
2163
|
+
selectedWhatsappStatus ? (
|
|
2164
|
+
<CapTag closable onClose={() => this.removeWhatsappFilter(WHATSAPP_STATUS)}>
|
|
2165
|
+
Status: {getWhatsappStatus(selectedWhatsappStatus)?.label || selectedWhatsappStatus}
|
|
2166
|
+
</CapTag>
|
|
2167
|
+
) : null
|
|
2168
|
+
}
|
|
2169
|
+
{
|
|
2170
|
+
selectedWhatsappCategory ? (
|
|
2171
|
+
<CapTag closable onClose={() => this.removeWhatsappFilter(WHATSAPP_CATEGORY)}>
|
|
2172
|
+
Category: {getWhatsappCategory(selectedWhatsappCategory)?.label || selectedWhatsappCategory}
|
|
2173
|
+
</CapTag>
|
|
2174
|
+
) : null
|
|
2175
|
+
}
|
|
2176
|
+
{
|
|
2177
|
+
(selectedWhatsappStatus || selectedWhatsappCategory) ? (
|
|
2178
|
+
<CapLink
|
|
2179
|
+
onClick={() => {
|
|
2180
|
+
this.removeWhatsappFilter(WHATSAPP_STATUS);
|
|
2181
|
+
this.removeWhatsappFilter(WHATSAPP_CATEGORY);
|
|
2182
|
+
}}
|
|
2183
|
+
title={this.props.intl.formatMessage(messages.clearAll)}
|
|
2184
|
+
/>
|
|
2185
|
+
) : null
|
|
2186
|
+
}
|
|
2187
|
+
</CapRow>
|
|
2188
|
+
);
|
|
2189
|
+
}
|
|
2190
|
+
|
|
1993
2191
|
setWechatFilter = (e) => this.setState({wechatFilter: e.target.value});
|
|
2192
|
+
setWhatsappStatus = (value) => this.setState({selectedWhatsappStatus: value?.item?.props?.value});
|
|
2193
|
+
setWhatsappCategory = (value) => this.setState({selectedWhatsappCategory: value?.item?.props?.value});
|
|
1994
2194
|
setLineFilter = (e) => this.setState({lineFilter: e.target.value});
|
|
1995
2195
|
setSMSFilter = (e) => this.setState({smsFilter: e.target.value});
|
|
1996
2196
|
|
|
1997
2197
|
|
|
1998
2198
|
render() {
|
|
1999
2199
|
const isFullMode = this.isFullMode();
|
|
2000
|
-
const { activeMode, channel, wechatFilter, lineFilter, smsFilter } = this.state;
|
|
2200
|
+
const { activeMode, channel, wechatFilter, lineFilter, smsFilter, templatesCount } = this.state;
|
|
2201
|
+
const {
|
|
2202
|
+
intl: {
|
|
2203
|
+
formatMessage,
|
|
2204
|
+
} = {},
|
|
2205
|
+
} = this.props || {};
|
|
2001
2206
|
let showFbAds = false;
|
|
2002
2207
|
if (channel.toLowerCase() === FACEBOOK_CHANNEL) {
|
|
2003
2208
|
const {campaignSettings, fetchedOrgLevelCampaignSettings} = this?.props?.Templates || {};
|
|
@@ -2061,6 +2266,19 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2061
2266
|
const isWechatEmbedded = !this.props.isFullMode && channel.toUpperCase() === WECHAT;
|
|
2062
2267
|
const channelLowerCase = (channel || '').toLowerCase();
|
|
2063
2268
|
const isTraiDltFeature = this.checkDLTfeatureEnable();
|
|
2269
|
+
|
|
2270
|
+
const createButton = (<CapButton
|
|
2271
|
+
className={`create-new-${channelLowerCase}`}
|
|
2272
|
+
type={"primary"}
|
|
2273
|
+
disabled={this.isCreateDisabled()}
|
|
2274
|
+
style={{marginLeft: '8px', marginBottom: '12px'}}
|
|
2275
|
+
onClick={this.createTemplate} >
|
|
2276
|
+
{ this.props.intl.formatMessage((isTraiDltFeature && channel.toUpperCase() === SMS ) ? messages.uploadTemplate : messages.createNewActionButton) }
|
|
2277
|
+
</CapButton>);
|
|
2278
|
+
|
|
2279
|
+
const isWhatsappCountExeeded = templatesCount >= MAX_WHATSAPP_TEMPLATES;
|
|
2280
|
+
const whatsappCountExceedText = <FormattedMessage {...messages.whatsappMaxTemplates} values={{ maxCount: MAX_WHATSAPP_TEMPLATES }}/>;
|
|
2281
|
+
|
|
2064
2282
|
const filterContent = (( isfilterContentVisisble || [WECHAT, MOBILE_PUSH].includes(this.state.channel.toUpperCase())) && <div className="action-container">
|
|
2065
2283
|
{isfilterContentVisisble && <CapInput.Search
|
|
2066
2284
|
className="search-text"
|
|
@@ -2085,6 +2303,31 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2085
2303
|
</CapLabel></CapRadio.Button>
|
|
2086
2304
|
</CapRadio.CapRadioGroup>
|
|
2087
2305
|
}
|
|
2306
|
+
{
|
|
2307
|
+
channel.toUpperCase() === WHATSAPP && (
|
|
2308
|
+
<div className="whatsapp-filters">
|
|
2309
|
+
<CapSelectFilter
|
|
2310
|
+
placement="bottomLeft"
|
|
2311
|
+
data={STATUS_OPTIONS}
|
|
2312
|
+
onSelect={this.setWhatsappStatus}
|
|
2313
|
+
selectedValue={this.state.selectedWhatsappStatus}
|
|
2314
|
+
placeholder="Status"
|
|
2315
|
+
showBadge={true}
|
|
2316
|
+
width="90px"
|
|
2317
|
+
/>
|
|
2318
|
+
<CapSelectFilter
|
|
2319
|
+
placement="bottomLeft"
|
|
2320
|
+
data={CATEGORY_OPTIONS}
|
|
2321
|
+
onSelect={this.setWhatsappCategory}
|
|
2322
|
+
selectedValue={this.state.selectedWhatsappCategory}
|
|
2323
|
+
placeholder="Category"
|
|
2324
|
+
showBadge={true}
|
|
2325
|
+
width="105px"
|
|
2326
|
+
/>
|
|
2327
|
+
</div>
|
|
2328
|
+
|
|
2329
|
+
)
|
|
2330
|
+
}
|
|
2088
2331
|
{
|
|
2089
2332
|
channel.toUpperCase() === LINE &&
|
|
2090
2333
|
isFullMode
|
|
@@ -2152,14 +2395,16 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2152
2395
|
: () => null
|
|
2153
2396
|
}
|
|
2154
2397
|
<div style={{display: "flex", justifyContent: "space-between", alignItems: 'center'}}>
|
|
2155
|
-
{
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2398
|
+
{
|
|
2399
|
+
this.state.channel.toLowerCase() === WHATSAPP_LOWERCASE && isWhatsappCountExeeded ? (
|
|
2400
|
+
<CapTooltip title={whatsappCountExceedText}>
|
|
2401
|
+
<div className="button-disabled-tooltip-wrapper">
|
|
2402
|
+
{createButton}
|
|
2403
|
+
</div>
|
|
2404
|
+
</CapTooltip>
|
|
2405
|
+
)
|
|
2406
|
+
: isfilterContentVisisble && !isWechatEmbedded && createButton
|
|
2407
|
+
}
|
|
2163
2408
|
</div>
|
|
2164
2409
|
|
|
2165
2410
|
</div>);
|
|
@@ -2193,6 +2438,11 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2193
2438
|
<div className={`creatives-templates-list ${this.props.isFullMode ? 'full-mode' : 'library-mode'}`}>
|
|
2194
2439
|
<input type="file" id="filename" style={{ display: 'none'}} accept=".zip, .html, .htm" onChange={(event) => this.handleFileUpload(event, {files: event.target.files})} />
|
|
2195
2440
|
|
|
2441
|
+
{
|
|
2442
|
+
channel.toLowerCase() === WHATSAPP_LOWERCASE && isWhatsappCountExeeded ? (
|
|
2443
|
+
<CapAlert message={whatsappCountExceedText} type="info" />
|
|
2444
|
+
) : null
|
|
2445
|
+
}
|
|
2196
2446
|
|
|
2197
2447
|
<CapRow>
|
|
2198
2448
|
<Pagination onPageChange={templates.length ? this.onPaginationChange : () => {}} paginationSelector="pagination-container">
|
|
@@ -2277,6 +2527,7 @@ Templates.propTypes = {
|
|
|
2277
2527
|
router: PropTypes.object,
|
|
2278
2528
|
viberActions: PropTypes.object,
|
|
2279
2529
|
facebookActions: PropTypes.object,
|
|
2530
|
+
whatsappActions: PropTypes.object,
|
|
2280
2531
|
smsRegister: PropTypes.any,
|
|
2281
2532
|
};
|
|
2282
2533
|
|
|
@@ -2305,6 +2556,7 @@ function mapDispatchToProps(dispatch) {
|
|
|
2305
2556
|
lineActions: bindActionCreators(lineActions, dispatch),
|
|
2306
2557
|
viberActions: bindActionCreators(viberActions, dispatch),
|
|
2307
2558
|
facebookActions: bindActionCreators(facebookActions, dispatch),
|
|
2559
|
+
whatsappActions: bindActionCreators(whatsappActions, dispatch),
|
|
2308
2560
|
};
|
|
2309
2561
|
}
|
|
2310
2562
|
|