@capillarytech/creatives-library 7.17.40-alpha.0 → 7.17.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.
Files changed (43) hide show
  1. package/components/CapTagList/index.js +1 -1
  2. package/components/CapTagList/messages.js +0 -4
  3. package/components/FormBuilder/index.js +2 -2
  4. package/components/FormBuilder/messages.js +0 -8
  5. package/containers/App/constants.js +0 -26
  6. package/containers/Assets/Gallery/index.js +1 -1
  7. package/containers/Assets/Gallery/messages.js +0 -4
  8. package/containers/Email/index.js +1 -1
  9. package/containers/Templates/index.js +1 -1
  10. package/containers/Templates/messages.js +0 -4
  11. package/index.js +2 -2
  12. package/package.json +1 -1
  13. package/services/api.js +6 -6
  14. package/utils/common.js +6 -13
  15. package/utils/tests/common.test.js +5 -5
  16. package/v2Components/CapTagList/index.js +2 -1
  17. package/v2Components/FormBuilder/index.js +1 -1
  18. package/v2Components/FormBuilder/messages.js +0 -4
  19. package/v2Components/TemplatePreview/_templatePreview.scss +40 -0
  20. package/v2Components/TemplatePreview/index.js +34 -0
  21. package/v2Components/TemplatePreview/tests/__snapshots__/index.test.js.snap +47 -0
  22. package/v2Components/TemplatePreview/tests/index.test.js +9 -0
  23. package/v2Containers/CreativesContainer/SlideBoxContent.js +12 -6
  24. package/v2Containers/CreativesContainer/SlideBoxHeader.js +2 -3
  25. package/v2Containers/CreativesContainer/index.js +57 -7
  26. package/v2Containers/CreativesContainer/messages.js +1 -9
  27. package/v2Containers/TagList/index.js +5 -18
  28. package/v2Containers/Templates/index.js +19 -4
  29. package/v2Containers/Templates/messages.js +4 -0
  30. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +28 -129
  31. package/v2Containers/TemplatesV2/tests/index.test.js +1 -0
  32. package/v2Containers/Zalo/constants.js +0 -1
  33. package/v2Containers/Zalo/index.js +280 -189
  34. package/v2Containers/Zalo/index.scss +3 -4
  35. package/v2Containers/Zalo/messages.js +17 -5
  36. package/v2Containers/Zalo/saga.js +10 -4
  37. package/v2Containers/Zalo/selectors.js +8 -10
  38. package/v2Containers/Zalo/tests/index.test.js +67 -48
  39. package/v2Containers/Zalo/tests/mockData.js +5056 -5045
  40. package/v2Containers/Zalo/tests/reducer.test.js +3 -3
  41. package/v2Containers/Zalo/tests/saga.test.js +5 -2
  42. package/v2Containers/Zalo/tests/selector.test.js +28 -0
  43. package/v2Containers/Zalo/tests/selectors.test.js +0 -52
@@ -1,8 +1,12 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import {
4
- CapSlideBox, CapHeader, CapLink, CapInput,
5
- } from '@capillarytech/cap-ui-library';
4
+ CapSlideBox,
5
+ CapHeader,
6
+ CapLink,
7
+ CapInput,
8
+ CapNotification,
9
+ } from "@capillarytech/cap-ui-library";
6
10
  import { injectIntl, FormattedMessage } from 'react-intl';
7
11
  import classnames from 'classnames';
8
12
  import {isEmpty, get, forEach, cloneDeep} from 'lodash';
@@ -23,8 +27,10 @@ import { gtmPush } from '../../utils/gtmTrackers';
23
27
  import './index.scss';
24
28
  import * as templateActions from '../Templates/actions';
25
29
  import * as globalActions from '../Cap/actions';
30
+ import * as zaloActions from '../Zalo/actions';
26
31
  import {isLoading as isLoadingSelector} from './selectors';
27
32
  import messages from './messages';
33
+ import zaloMessages from '../Zalo/messages';
28
34
  import { MAP_TEMPLATE } from '../WeChat/Wrapper/constants';
29
35
  import { makeSelectFetchingCmsData } from '../Email/selectors';
30
36
  import { IMAGE as LINE_IMAGE, IMAGE_MAP, IMAGE_CAROUSEL, VIDEO as LINE_VIDEO, TEMPLATE, STICKER } from '../Line/Container/constants';
@@ -97,12 +103,35 @@ export class Creatives extends React.Component {
97
103
  }
98
104
  this.setState(data);
99
105
  };
106
+
107
+ actionCallback = () => {
108
+ CapNotification.error({
109
+ message: <FormattedMessage {...zaloMessages.zaloFailureNotificationPreview}/>,
110
+ });
111
+ };
112
+
100
113
  onPreviewTemplate = (template) => {
101
- const templateData = template;
102
- const usersList = commonUtil.getMergedUserList(this.props.templateUserList);
103
- const userId = parseInt(template.updatedBy, 10);
104
- templateData.updatedByName = commonUtil.getUserNameById(userId, usersList );
105
- this.setState({ slidBoxContent: 'preview', templateData });
114
+ if (template.type !== constants.ZALO) {
115
+ const templateData = template;
116
+ const usersList = commonUtil.getMergedUserList(this.props.templateUserList);
117
+ const userId = parseInt(template.updatedBy, 10);
118
+ templateData.updatedByName = commonUtil.getUserNameById(userId, usersList );
119
+ this.setState({ slidBoxContent: 'preview', templateData });
120
+ } else {
121
+ const {
122
+ name = "",
123
+ sourceAccountIdentifier = "",
124
+ configs: { token = "" } = {},
125
+ } = get(this.props, "Templates.weCrmAccounts[0]", {});
126
+ this.props.zaloActions.getTemplateInfoById({
127
+ username: name,
128
+ oa_id: sourceAccountIdentifier,
129
+ token,
130
+ id: template?._id,
131
+ preview: true,
132
+ actionCallback: this.actionCallback,
133
+ });
134
+ }
106
135
  };
107
136
  onEditTemplate = () => {
108
137
  this.setState({ slidBoxContent: 'editTemplate', showSlideBox: true, templateNameExists: true });
@@ -471,6 +500,14 @@ export class Creatives extends React.Component {
471
500
  },
472
501
  },
473
502
  };
503
+ break;
504
+ }
505
+ case constants.ZALO: {
506
+ creativesTemplateData = {
507
+ type: constants.ZALO,
508
+ ...templateData,
509
+ };
510
+ break;
474
511
  }
475
512
  default:
476
513
  break;
@@ -771,6 +808,17 @@ export class Creatives extends React.Component {
771
808
  }
772
809
  }
773
810
  break;
811
+ case constants.ZALO: {
812
+ if (template.value) {
813
+ templateData = {
814
+ ...template.value,
815
+ };
816
+ if (templateData?.type) {
817
+ delete templateData.type;
818
+ }
819
+ }
820
+ }
821
+ break;
774
822
  default:
775
823
  break;
776
824
  }
@@ -1205,6 +1253,7 @@ Creatives.propTypes = {
1205
1253
  channel: PropTypes.string,
1206
1254
  templateActions: PropTypes.object,
1207
1255
  globalActions: PropTypes.object,
1256
+ zaloActions: PropTypes.object,
1208
1257
  cap: PropTypes.object,
1209
1258
  // isLoading: PropTypes.bool,
1210
1259
  templateUserList: PropTypes.array,
@@ -1233,6 +1282,7 @@ function mapDispatchToProps(dispatch) {
1233
1282
  templateActions: bindActionCreators(templateActions, dispatch),
1234
1283
  globalActions: bindActionCreators(globalActions, dispatch),
1235
1284
  actions: bindActionCreators(actions, dispatch),
1285
+ zaloActions: bindActionCreators(zaloActions, dispatch),
1236
1286
  };
1237
1287
  }
1238
1288
  export default connect(mapStatesToProps, mapDispatchToProps)(injectIntl(Creatives));
@@ -341,13 +341,5 @@ export default defineMessages({
341
341
  "wechat": {
342
342
  id: `${scope}.wechat`,
343
343
  defaultMessage: `Wechat`,
344
- },
345
- "ftp": {
346
- id: `${scope}.ftp`,
347
- defaultMessage: `FTP`,
348
- },
349
- "noCommunication": {
350
- id: `${scope}.noCommunication`,
351
- defaultMessage: `NO_COMMUNICATION`,
352
- },
344
+ }
353
345
  });
@@ -22,8 +22,7 @@ import './_tagList.scss';
22
22
  import { selectCurrentOrgDetails } from '../Cap/selectors';
23
23
  import { injectIntl } from 'react-intl';
24
24
  import { scope } from './messages';
25
- import { handleInjectedData, hasGiftVoucherFeature, hasPromoFeature } from '../../utils/common';
26
- import { GIFT_VOUCHER_RELATED_TAGS, PROMO_ENGINE_RELATED_TAGS } from '../../containers/App/constants';
25
+ import { handleInjectedData } from '../../utils/common';
27
26
 
28
27
  const TreeNode = Tree.TreeNode;
29
28
 
@@ -96,24 +95,10 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
96
95
  }
97
96
  populateTags(tagsList) {
98
97
  const mainTags = {};
99
- const excludedTags = [];
100
- if (!hasPromoFeature()) {
101
- excludedTags.push(...PROMO_ENGINE_RELATED_TAGS);
102
- //filtering PROMO_ENGINE_RELATED_TAGS if org does not have PROMO_ENGINE feature enabled
103
- }
104
- if (!hasGiftVoucherFeature()) {
105
- //filtering GIFT_VOUCHER_RELATED_TAGS if org does not have GIFT_CARDS feature enabled
106
- excludedTags.push(...GIFT_VOUCHER_RELATED_TAGS);
107
- }
108
98
  //Form tags object with tag headers
109
99
  _.forEach(tagsList, (temp) => {
110
100
  const tag = temp.definition;
111
- const { locale: userLocale } = this.props?.intl || {};
112
-
113
- // Check if the tag.value should be skipped based on feature control
114
- if (_.includes(excludedTags, tag.value)) {
115
- return; // Skip processing this tag
116
- }
101
+ const { locale : userLocale } = this.props?.intl || {};
117
102
  if (!tag['tag-header']) {
118
103
  mainTags[tag.value] = {
119
104
  "name": tag?.label[userLocale] ? tag?.label[userLocale] : tag?.label?.en,
@@ -132,7 +117,7 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
132
117
  });
133
118
 
134
119
  const mainTagsCloned = _.cloneDeep(mainTags);
135
- //Insert subtags in tag headers and remove them from top level
120
+ //Insert subtags in tag headers and reomve them from top level
136
121
  const result = {};
137
122
  _.forEach(mainTagsCloned, (tag, key) => {
138
123
  if (tag['tag-header']) {
@@ -275,6 +260,7 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
275
260
  modalProps={this.props.modalProps}
276
261
  currentOrgDetails={this.props.currentOrgDetails}
277
262
  channel={this.props.channel}
263
+ disabled={this.props.disabled}
278
264
  />
279
265
  </div>
280
266
  );
@@ -301,6 +287,7 @@ TagList.propTypes = {
301
287
  modalProps: PropTypes.any,
302
288
  currentOrgDetails: PropTypes.object,
303
289
  channel: PropTypes.string,
290
+ disabled: PropTypes.bool
304
291
  };
305
292
 
306
293
  const mapStateToProps = createStructuredSelector({
@@ -109,6 +109,7 @@ import { ZALO_STATUS_OPTIONS, ZALO_STATUSES } from '../Zalo/constants';
109
109
  import { getWhatsappContent, getWhatsappStatus, getWhatsappCategory, getWhatsappCta } from '../Whatsapp/utils';
110
110
  import { getRCSContent } from '../Rcs/utils';
111
111
  import zaloMessages from '../Zalo/messages'
112
+ import { handlePreviewInNewTab } from '../../utils/common';
112
113
 
113
114
  import { MOBILE_PUSH, WECHAT, SMS, EMAIL, EBILL, LINE, VIBER, FACEBOOK, WHATSAPP, RCS, ZALO } from '../CreativesContainer/constants';
114
115
 
@@ -621,7 +622,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
621
622
  }
622
623
  const zaloPreviewUrl = get(nextProps, 'Zalo.zaloTemplatePreviewData.versions.base.content.zalo.previewUrl', '');
623
624
  if (zaloPreviewUrl && this.state.channel.toLowerCase() === ZALO_LOWERCASE) {
624
- window.open(zaloPreviewUrl, '_blank');
625
+ handlePreviewInNewTab(zaloPreviewUrl);
625
626
  this.props.zaloActions.resetTemplateInfoData();
626
627
  }
627
628
  }
@@ -869,10 +870,11 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
869
870
  }
870
871
 
871
872
  filterZaloTemplates = (templates) => {
872
- const { selectedZaloStatus } = this.state;
873
+ let { selectedZaloStatus } = this.state;
874
+ selectedZaloStatus = !this.props.isFullMode ? ZALO_STATUSES.ENABLE : selectedZaloStatus;
873
875
  if (selectedZaloStatus) {
874
- return templates?.filter((template) => template?.versions?.base?.content?.zalo.status === selectedZaloStatus);
875
- }
876
+ return templates?.filter((template) => template?.versions?.base?.content?.zalo?.status === selectedZaloStatus);
877
+ }
876
878
  return templates;
877
879
  }
878
880
 
@@ -1909,6 +1911,12 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1909
1911
 
1910
1912
  selectTemplate = (id) => find(this.props.TemplatesList, {_id: id})
1911
1913
 
1914
+ actionCallback = () => {
1915
+ CapNotification.error({
1916
+ message: this.props.intl.formatMessage(zaloMessages.zaloFailureNotificationPreview),
1917
+ });
1918
+ };
1919
+
1912
1920
  handlePreviewClick(template, modeType) {
1913
1921
  if (this.state.channel.toLowerCase() !== ZALO_LOWERCASE) {
1914
1922
  this.togglePreview();
@@ -1951,6 +1959,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1951
1959
  token: token,
1952
1960
  id: template?._id,
1953
1961
  preview: true,
1962
+ actionCallback: this.actionCallback,
1954
1963
  });
1955
1964
  }
1956
1965
  }
@@ -2900,6 +2909,12 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2900
2909
  ) : null
2901
2910
  }
2902
2911
 
2912
+ {
2913
+ channel.toLowerCase() === ZALO_LOWERCASE && !isFullMode ? (
2914
+ <CapInfoNote message={formatMessage(messages.zaloOnlyApprovedTemplates)} />
2915
+ ) : null
2916
+ }
2917
+
2903
2918
  <CapRow>
2904
2919
  <Pagination onPageChange={templates.length ? this.onPaginationChange : () => {}} paginationSelector="pagination-container">
2905
2920
  {this.getTemplateDataForGrid({ isLoading, loadingTip, channel: this.state.channel, templates: this.state.searchingZaloTemplate ? this.state.searchedZaloTemplates : this.props.TemplatesList, filterContent, handlers: { handlePreviewClick: this.handlePreviewClick, handleEditClick: this.handleEditClick}})}
@@ -502,4 +502,8 @@ export default defineMessages({
502
502
  id: `${scope}.zaloPreview`,
503
503
  defaultMessage: 'Open preview in new tab',
504
504
  },
505
+ "zaloOnlyApprovedTemplates": {
506
+ id: `${scope}.zaloOnlyApprovedTemplates`,
507
+ defaultMessage: 'Only enabled/approved templates are shown here',
508
+ },
505
509
  });
@@ -1038,134 +1038,6 @@ exports[`Test Templates container Should render temlates when zalo templates are
1038
1038
  tip="Getting all templates..."
1039
1039
  >
1040
1040
  <div>
1041
- <div
1042
- className="pagination-container"
1043
- >
1044
- <CapCustomCardList
1045
- cardList={
1046
- Array [
1047
- Object {
1048
- "content": <CapLabel
1049
- className="zalo-listing-content desc"
1050
- type="label19"
1051
- >
1052
- Test1
1053
- </CapLabel>,
1054
- "extra": Array [
1055
- <CapTooltip
1056
- title="Open preview in new tab"
1057
- >
1058
- <CapIcon
1059
- className="view-zalo"
1060
- onClick={[Function]}
1061
- style={
1062
- Object {
1063
- "marginRight": "16px",
1064
- }
1065
- }
1066
- type="eye"
1067
- />
1068
- </CapTooltip>,
1069
- ],
1070
- "hoverOption": <CapButton
1071
- className="select-zalo"
1072
- isAddBtn={false}
1073
- onClick={[Function]}
1074
- type="primary"
1075
- >
1076
- Select
1077
- </CapButton>,
1078
- "key": "ZALO-card-Test1",
1079
- "title": <CapRow>
1080
- <CapLabel
1081
- className="zalo-template-name"
1082
- type="label1"
1083
- >
1084
-
1085
- </CapLabel>
1086
- <CapRow
1087
- align="middle"
1088
- className="zalo-status-container"
1089
- type="flex"
1090
- >
1091
- <CapStatus
1092
- color=""
1093
- height="0.571rem"
1094
- labelType="label3"
1095
- text=""
1096
- type="pending"
1097
- width="0.571rem"
1098
- />
1099
- </CapRow>
1100
- </CapRow>,
1101
- },
1102
- Object {
1103
- "content": <CapLabel
1104
- className="zalo-listing-content desc"
1105
- type="label19"
1106
- >
1107
- Test2
1108
- </CapLabel>,
1109
- "extra": Array [
1110
- <CapTooltip
1111
- title="Open preview in new tab"
1112
- >
1113
- <CapIcon
1114
- className="view-zalo"
1115
- onClick={[Function]}
1116
- style={
1117
- Object {
1118
- "marginRight": "16px",
1119
- }
1120
- }
1121
- type="eye"
1122
- />
1123
- </CapTooltip>,
1124
- ],
1125
- "hoverOption": <CapButton
1126
- className="select-zalo"
1127
- isAddBtn={false}
1128
- onClick={[Function]}
1129
- type="primary"
1130
- >
1131
- Select
1132
- </CapButton>,
1133
- "key": "ZALO-card-Test2",
1134
- "title": <CapRow>
1135
- <CapLabel
1136
- className="zalo-template-name"
1137
- type="label1"
1138
- >
1139
-
1140
- </CapLabel>
1141
- <CapRow
1142
- align="middle"
1143
- className="zalo-status-container"
1144
- type="flex"
1145
- >
1146
- <CapStatus
1147
- color=""
1148
- height="0.571rem"
1149
- labelType="label3"
1150
- text=""
1151
- type="pending"
1152
- width="0.571rem"
1153
- />
1154
- </CapRow>
1155
- </CapRow>,
1156
- },
1157
- ]
1158
- }
1159
- fbType="list"
1160
- key="ZALO-card-list"
1161
- style={
1162
- Object {
1163
- "marginLeft": "16px",
1164
- }
1165
- }
1166
- type="ZALO"
1167
- />
1168
- </div>
1169
1041
  <div
1170
1042
  style={
1171
1043
  Object {
@@ -1173,7 +1045,34 @@ exports[`Test Templates container Should render temlates when zalo templates are
1173
1045
  "overflow": "auto",
1174
1046
  }
1175
1047
  }
1176
- />
1048
+ >
1049
+ <CapHeader
1050
+ description={
1051
+ <CapLabel
1052
+ style={
1053
+ Object {
1054
+ "textAlign": "center",
1055
+ }
1056
+ }
1057
+ type="label1"
1058
+ >
1059
+ Please try searching with another term or apply different filter
1060
+ </CapLabel>
1061
+ }
1062
+ descriptionClass=""
1063
+ inline={false}
1064
+ size="large"
1065
+ title={
1066
+ <CapHeading
1067
+ className="channel-specific-illustration-text"
1068
+ type="h3"
1069
+ >
1070
+ Sorry, we couldn’t find any matches
1071
+ </CapHeading>
1072
+ }
1073
+ titleClass=""
1074
+ />
1075
+ </div>
1177
1076
  </div>
1178
1077
  </CapSpin>
1179
1078
  </div>
@@ -93,6 +93,7 @@ describe("Test TemplatesV2", () => {
93
93
  expect(getByText('Viber')).toBeInTheDocument();
94
94
  expect(getByText('Facebook')).toBeInTheDocument();
95
95
  expect(getByText('WhatsApp')).toBeInTheDocument();
96
+ expect(getByText('Zalo')).toBeInTheDocument();
96
97
  expect(getByText('Gallery')).toBeInTheDocument();
97
98
  });
98
99
  });
@@ -10,7 +10,6 @@ export const ERROR = 'ERROR';
10
10
  export const STRING = 'STRING';
11
11
  export const NUMBER = 'NUMBER';
12
12
  export const DATE = 'DATE';
13
- export const ENABLE = 'ENABLE';
14
13
 
15
14
  export const TAG = 'TAG';
16
15
  export const EMBEDDED = 'embedded';