@capillarytech/creatives-library 7.12.50 → 7.12.53

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 (57) hide show
  1. package/config/app.js +0 -1
  2. package/package.json +1 -1
  3. package/services/api.js +15 -2
  4. package/v2Components/CapImageUpload/index.js +33 -17
  5. package/v2Components/CapImageUpload/messages.js +11 -3
  6. package/v2Components/CapWhatsappCTA/constants.js +12 -1
  7. package/v2Components/CapWhatsappCTA/index.js +88 -29
  8. package/v2Components/CapWhatsappCTA/index.scss +4 -6
  9. package/v2Components/CapWhatsappCTA/messages.js +24 -0
  10. package/v2Components/TemplatePreview/_templatePreview.scss +9 -8
  11. package/v2Components/TemplatePreview/index.js +8 -6
  12. package/v2Components/TemplatePreview/tests/__snapshots__/index.test.js.snap +3 -19
  13. package/v2Components/TemplatePreview/tests/index.test.js +0 -2
  14. package/v2Components/WhatsappStatusContainer/index.js +42 -52
  15. package/v2Containers/Cap/tests/index.test.js +2 -2
  16. package/v2Containers/CreativesContainer/SlideBoxContent.js +8 -8
  17. package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +28 -36
  18. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +165 -344
  19. package/v2Containers/CreativesContainer/tests/index.test.js +0 -3
  20. package/v2Containers/Line/Container/ImageCarousel/Content.js +15 -29
  21. package/v2Containers/Line/Container/ImageCarousel/constants.js +3 -0
  22. package/v2Containers/Line/Container/ImageCarousel/index.js +28 -40
  23. package/v2Containers/Line/Container/ImageCarousel/messages.js +2 -2
  24. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +9851 -0
  25. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +21113 -0
  26. package/v2Containers/Line/Container/ImageCarousel/tests/content.test.js +71 -0
  27. package/v2Containers/Line/Container/ImageCarousel/tests/index.test.js +58 -0
  28. package/v2Containers/Line/Container/ImageCarousel/tests/mockData.js +1322 -0
  29. package/v2Containers/Line/Container/ImageCarousel/tests/utils.test.js +13 -0
  30. package/v2Containers/Line/Container/ImageCarousel/utils.js +12 -0
  31. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +84451 -0
  32. package/v2Containers/Line/Container/Wrapper/tests/index.test.js +58 -0
  33. package/v2Containers/Line/Container/Wrapper/tests/mockData.js +171 -0
  34. package/v2Containers/Line/Container/index.js +5 -1
  35. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +63597 -0
  36. package/v2Containers/Line/Container/tests/index.test.js +105 -0
  37. package/v2Containers/Line/Container/tests/mockData.js +1334 -0
  38. package/v2Containers/Templates/_templates.scss +5 -0
  39. package/v2Containers/Templates/actions.js +7 -0
  40. package/v2Containers/Templates/constants.js +9 -1
  41. package/v2Containers/Templates/index.js +45 -30
  42. package/v2Containers/Templates/messages.js +1 -1
  43. package/v2Containers/Templates/reducer.js +15 -0
  44. package/v2Containers/Templates/sagas.js +32 -0
  45. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1774 -1881
  46. package/v2Containers/Templates/tests/index.test.js +14 -3
  47. package/v2Containers/Whatsapp/actions.js +22 -0
  48. package/v2Containers/Whatsapp/constants.js +56 -23
  49. package/v2Containers/Whatsapp/index.js +204 -66
  50. package/v2Containers/Whatsapp/index.scss +18 -2
  51. package/v2Containers/Whatsapp/messages.js +35 -7
  52. package/v2Containers/Whatsapp/reducer.js +35 -1
  53. package/v2Containers/Whatsapp/sagas.js +30 -1
  54. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +44349 -32926
  55. package/v2Containers/Whatsapp/tests/__snapshots__/utils.test.js.snap +15 -21
  56. package/v2Containers/Whatsapp/utils.js +16 -9
  57. package/v2Containers/mockdata.js +210 -555
@@ -588,3 +588,8 @@
588
588
  text-align: center;
589
589
  margin-top: $CAP_SPACE_44;
590
590
  }
591
+ .whatsapp-image{
592
+ width: 100%;
593
+ max-height: 123px;
594
+ margin-bottom: 4px;
595
+ }
@@ -143,3 +143,10 @@ export function resetTemplateStoreData() {
143
143
  type: types.CLEAR_TEMPLATE_STORE_DATA,
144
144
  };
145
145
  }
146
+
147
+ export function getSenderDetails(data = {}) {
148
+ return {
149
+ type: types.GET_SENDER_DETAILS_REQUEST,
150
+ ...data,
151
+ };
152
+ }
@@ -59,4 +59,12 @@ export const GET_ORG_LEVEL_CAMPAIGN_SETTINGS_SUCCESS =
59
59
  export const GET_ORG_LEVEL_CAMPAIGN_SETTINGS_FAILURE =
60
60
  'app/v2Containers/Templates/GET_ORG_LEVEL_CAMPAIGN_SETTINGS_FAILURE';
61
61
 
62
- export const MAX_WHATSAPP_TEMPLATES = 250;
62
+ export const MAX_WHATSAPP_TEMPLATES = 1500;
63
+ export const WARNING_WHATSAPP_TEMPLATES = 1400;
64
+
65
+ export const GET_SENDER_DETAILS_REQUEST =
66
+ 'app/v2Containers/Templates/GET_SENDER_DETAILS_REQUEST';
67
+ export const GET_SENDER_DETAILS_SUCCESS =
68
+ 'app/v2Containers/Templates/GET_SENDER_DETAILS_SUCCESS';
69
+ export const GET_SENDER_DETAILS_FAILURE =
70
+ 'app/v2Containers/Templates/GET_SENDER_DETAILS_FAILURE';
@@ -47,6 +47,7 @@ import {
47
47
  CapAlert,
48
48
  CapModal,
49
49
  CapInfoNote,
50
+ CapImage,
50
51
  } from '@capillarytech/cap-ui-library';
51
52
  import { makeSelectTemplates, makeSelectTemplatesResponse } from './selectors';
52
53
  import { makeSelectCreate as makeSelectCreateSms} from '../Sms/Create/selectors';
@@ -91,11 +92,13 @@ import {
91
92
  } from '../App/constants';
92
93
  import { MAX_WHATSAPP_TEMPLATES, WARNING_WHATSAPP_TEMPLATES } from './constants';
93
94
  import {
94
- CATEGORY_OPTIONS,
95
+ TWILIO_CATEGORY_OPTIONS,
96
+ KARIX_CATEGORY_OPTIONS,
95
97
  STATUS_OPTIONS,
96
98
  CATEGORY as WHATSAPP_CATEGORY,
97
99
  STATUS as WHATSAPP_STATUS,
98
100
  WHATSAPP_STATUSES,
101
+ HOST_KARIX,
99
102
  } from '../Whatsapp/constants';
100
103
  import { getWhatsappContent, getWhatsappStatus, getWhatsappCategory, getWhatsappCta } from '../Whatsapp/utils';
101
104
  import { getRCSContent } from '../Rcs/utils';
@@ -191,6 +194,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
191
194
  smsFilter: SMS_FILTERS.ALL,
192
195
  selectedWhatsappStatus: '',
193
196
  selectedWhatsappCategory: '',
197
+ hostName: '',
194
198
  };
195
199
 
196
200
  this.handleOnHoverItem = this.handleOnHoverItem.bind(this);
@@ -259,7 +263,10 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
259
263
  case WHATSAPP:
260
264
  channel = 'Whatsapp';
261
265
  activeMode = ACCOUNT_SELECTION_MODE;
262
- this.props.actions.getWeCrmAccounts(channel);
266
+ this.props.actions.getSenderDetails({
267
+ channel: WHATSAPP,
268
+ orgUnitId: -1,
269
+ });
263
270
  break;
264
271
  case RCS:
265
272
  channel = 'Rcs';
@@ -294,7 +301,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
294
301
  if (this.props.location.query.type === 'embedded') {
295
302
  this.props.actions.resetAccount();
296
303
  }
297
- if (['line', VIBER_CHANNEL, FACEBOOK_CHANNEL, 'sms', 'email', 'ebill', RCS_LOWERCASE].includes((this.state.channel || '').toLowerCase())) {
304
+ if (['line', VIBER_CHANNEL, FACEBOOK_CHANNEL, 'sms', 'email', 'ebill', RCS_LOWERCASE, WHATSAPP_LOWERCASE].includes((this.state.channel || '').toLowerCase())) {
298
305
  const queryParams = {
299
306
  // name: this.state.searchText,
300
307
  // sortBy: this.state.sortBy,
@@ -421,6 +428,21 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
421
428
  }
422
429
  }
423
430
 
431
+ if (
432
+ selectedChannel === WHATSAPP_LOWERCASE &&
433
+ isEmpty(nextProps.Templates.selectedWhatsappAccount)
434
+ ) {
435
+ const { connectionProperties = {}, hostName = '' } = get(nextProps.Templates, 'senderDetails.data[0].domainProperties', {});
436
+ if (isEmpty(connectionProperties) || hostName === '') {
437
+ return;
438
+ }
439
+ this.setState({activeMode: TEMPLATES_MODE, hostName}, () => {
440
+ this.props.actions.setChannelAccount(WHATSAPP, { connectionProperties, hostName });
441
+ this.getAllTemplates({ params });
442
+ }
443
+ );
444
+ }
445
+
424
446
  if ((selectedChannel === 'wechat' || selectedChannel === 'mobilepush') && isEmpty(nextProps.Templates.selectedWeChatAccount) && (this.props.location.query.type === 'embedded') && !this.isEnabledInLibraryModule("showAccountSelection")) {
425
447
  let selectedAccount = '';
426
448
  if (isEmpty(nextProps.Templates.weCrmAccounts)) {
@@ -551,7 +573,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
551
573
  this.setState({previewTemplate: nextProps.Templates.templateDetails});
552
574
  }
553
575
  const weCrmAccountsList = get(nextProps, `Templates.weCrmAccounts`, []);
554
- const weCrmChannels = ['wechat', WHATSAPP_LOWERCASE];
576
+ const weCrmChannels = ['wechat'];
555
577
 
556
578
  if (weCrmAccountsList.length === 1 && this.state.defaultAccount && (weCrmChannels.indexOf(selectedChannel) > -1)) {
557
579
  const paramsDefault = {
@@ -562,16 +584,9 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
562
584
  paramsDefault.wecrmId = weCrmAccountsList[0].configs.wecrm_app_id;
563
585
  paramsDefault.wecrmToken = weCrmAccountsList[0].configs.wecrm_token;
564
586
  paramsDefault.originalId = weCrmAccountsList[0].sourceAccountIdentifier;
565
- if ([WHATSAPP_LOWERCASE].includes(selectedChannel)) {
566
- nextProps.actions.setChannelAccount(
567
- selectedChannel.toUpperCase(),
568
- weCrmAccountsList[0],
569
- );
570
- } else {
571
587
  nextProps.actions.setWeChatAccount(
572
588
  weCrmAccountsList[0],
573
589
  );
574
- }
575
590
  }
576
591
  this.setState({ defaultAccount: false, activeMode: TEMPLATES_MODE, selectedAccount: weCrmAccountsList[0].name });
577
592
  this.getAllTemplates({params: paramsDefault}, true);
@@ -612,7 +627,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
612
627
  } else {
613
628
  this.setState({selectedAccountError: false});
614
629
  }
615
- } else if ([LINE.toLowerCase(), WHATSAPP_LOWERCASE, RCS_LOWERCASE].includes(selectedChannel)) {
630
+ } else if ([LINE.toLowerCase(), RCS_LOWERCASE].includes(selectedChannel)) {
616
631
  this.props.actions.setChannelAccount(selectedChannel?.toUpperCase(), this.props.Templates.weCrmAccounts.find((item) => item.name === this.state.selectedAccount));
617
632
  }
618
633
 
@@ -1058,6 +1073,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1058
1073
  break;
1059
1074
  }
1060
1075
  case WHATSAPP: {
1076
+ const { whatsappImageSrc = '', templateMsg} = getWhatsappContent(template);
1061
1077
  templateData.title = (
1062
1078
  <CapRow className="whatsapp-card-title">
1063
1079
  <CapLabel>{template.name}</CapLabel>
@@ -1066,7 +1082,8 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1066
1082
  );
1067
1083
  templateData.content = (
1068
1084
  <>
1069
- {getWhatsappContent(template).templateMsg}
1085
+ {whatsappImageSrc && <CapImage src={whatsappImageSrc} className="whatsapp-image" />}
1086
+ {templateMsg}
1070
1087
  {getWhatsappCta(template)}
1071
1088
  </>
1072
1089
  );
@@ -2034,7 +2051,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2034
2051
  const rcsLoader = this.checkLoader(RCS_LOWERCASE);
2035
2052
 
2036
2053
  const wechatLoader = (((this.state.selectedAccount !== '' && getAllTemplatesInProgress) || (fetchingWeCrmAccounts)) && this.state.channel.toLowerCase() === 'wechat');
2037
- const whatsappLoader = (((this.state.selectedAccount !== '' && getAllTemplatesInProgress) || (fetchingWeCrmAccounts)) && this.state.channel.toLowerCase() === WHATSAPP_LOWERCASE);
2054
+ const whatsappLoader = this.checkLoader(WHATSAPP_LOWERCASE) || this.props.Templates?.senderDetails?.status === 'REQUEST';
2038
2055
  const mobilePushLoader = (((getAllTemplatesInProgress) || (fetchingWeCrmAccounts)) && this.state.channel.toLowerCase() === 'mobilepush');
2039
2056
  const emailLoader = (
2040
2057
  (getAllTemplatesInProgress ||
@@ -2150,16 +2167,22 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2150
2167
  const { selectedAccount } = this.state;
2151
2168
  let { channel = '' } = this.state;
2152
2169
  channel = channel.toUpperCase();
2153
- const { Templates: templates = {}, location = {} } = this.props;
2170
+ const { Templates: templates = {}, location = {}, intl: {formatMessage}} = this.props;
2154
2171
  const { query = {} } = location;
2155
- const { weCrmAccounts = [], fetchingWeCrmAccounts = false, campaignSettings = {} } = templates;
2172
+ const { weCrmAccounts = [], fetchingWeCrmAccounts = false, campaignSettings = {}, selectedWhatsappAccount = {} } = templates;
2156
2173
  const isWechatChannel = channel === WECHAT;
2157
2174
  const isMobilePushChannel = channel === MOBILE_PUSH;
2158
2175
  const isFacebookChannel = channel === FACEBOOK;
2159
2176
 
2160
- if ([WECHAT, MOBILE_PUSH, LINE, WHATSAPP].includes(channel) && !isEmpty(weCrmAccounts) && !isFacebookChannel) {
2177
+ if (channel === WHATSAPP && isEmpty(selectedWhatsappAccount)) {
2178
+ return <CapHeading>{formatMessage(messages.noAccountsPresentWhatsapp)}</CapHeading>;
2179
+ } else if (channel === WHATSAPP && !isEmpty(selectedWhatsappAccount)) {
2180
+ this.setTemplatesMode();
2181
+ }
2182
+
2183
+ if ([WECHAT, MOBILE_PUSH, LINE].includes(channel) && !isEmpty(weCrmAccounts) && !isFacebookChannel) {
2161
2184
  forEach(weCrmAccounts, (account) => {
2162
- if ((isWechatChannel && account.configs && account.configs.is_wecrm_enabled) || [MOBILE_PUSH, LINE, WHATSAPP].includes(channel)) {
2185
+ if ((isWechatChannel && account.configs && account.configs.is_wecrm_enabled) || [MOBILE_PUSH, LINE].includes(channel)) {
2163
2186
  if (query.type === 'embedded' && (!query.module || (query.module && query.module !== 'library'))) {
2164
2187
  if (query.source_account_id && account.sourceAccountIdentifier === query.source_account_id) {
2165
2188
  accountOptions.push(
@@ -2192,11 +2215,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2192
2215
  }
2193
2216
  });
2194
2217
  }
2195
- const {
2196
- intl: {
2197
- formatMessage,
2198
- },
2199
- } = this.props;
2200
2218
  let accountHeader = formatMessage(messages.mobilepushAccount);
2201
2219
  let noAccountHeader = messages.noAccountsPresent;
2202
2220
  switch (channel) {
@@ -2223,11 +2241,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2223
2241
  noAccountHeader = messages.noAccountsPresentFacebook;
2224
2242
  break;
2225
2243
  }
2226
- case WHATSAPP: {
2227
- accountHeader = formatMessage(messages.whatsappAccount);
2228
- noAccountHeader = messages.noAccountsPresentWhatsapp;
2229
- break;
2230
- }
2231
2244
  default:
2232
2245
  break;
2233
2246
  }
@@ -2342,7 +2355,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2342
2355
  {
2343
2356
  selectedWhatsappCategory ? (
2344
2357
  <CapTag closable onClose={() => this.removeWhatsappFilter(WHATSAPP_CATEGORY)}>
2345
- {formatMessage(messages.category)}: {getWhatsappCategory(selectedWhatsappCategory)?.label || selectedWhatsappCategory}
2358
+ {formatMessage(messages.category)}: {getWhatsappCategory(selectedWhatsappCategory, this.state.hostName)?.label || selectedWhatsappCategory}
2346
2359
  </CapTag>
2347
2360
  ) : null
2348
2361
  }
@@ -2510,7 +2523,9 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2510
2523
  }
2511
2524
  <CapSelectFilter
2512
2525
  placement="bottomLeft"
2513
- data={CATEGORY_OPTIONS}
2526
+ data={this.state.hostName === HOST_KARIX
2527
+ ? KARIX_CATEGORY_OPTIONS
2528
+ : TWILIO_CATEGORY_OPTIONS}
2514
2529
  onSelect={this.setWhatsappCategory}
2515
2530
  selectedValue={this.state.selectedWhatsappCategory}
2516
2531
  placeholder="Category"
@@ -124,7 +124,7 @@ export default defineMessages({
124
124
  },
125
125
  "noAccountsPresent": {
126
126
  id: `${scope}.noAccountsPresent`,
127
- defaultMessage: "Push notifications are not setup for your brand",
127
+ defaultMessage: "Account not setup for your brand",
128
128
  },
129
129
  "noAccountsPresentWeChat": {
130
130
  id: `${scope}.noAccountsPresentWeChat`,
@@ -21,6 +21,7 @@ const initialState = fromJS({
21
21
  alertsSettings: {},
22
22
  reportsSettings: {},
23
23
  },
24
+ senderDetails: {},
24
25
  });
25
26
 
26
27
  function templatesReducer(state = initialState, action) {
@@ -175,6 +176,20 @@ function templatesReducer(state = initialState, action) {
175
176
  );
176
177
  case types.GET_ORG_LEVEL_CAMPAIGN_SETTINGS_FAILURE:
177
178
  return state.set('fetchedOrgLevelCampaignSettings', false);
179
+ case types.GET_SENDER_DETAILS_REQUEST:
180
+ return state.set('senderDetails', { status: 'REQUEST' });
181
+ case types.GET_SENDER_DETAILS_SUCCESS:
182
+ return state.set('senderDetails', {
183
+ status: 'SUCCESS',
184
+ data: action.payload,
185
+ errors: [],
186
+ });
187
+ case types.GET_SENDER_DETAILS_FAILURE:
188
+ return state.set('senderDetails', {
189
+ status: 'FAILURE',
190
+ data: [],
191
+ errors: action.payload,
192
+ });
178
193
  default:
179
194
  return state;
180
195
  }
@@ -148,6 +148,31 @@ export function* getTemplateDetails(id, channel) {
148
148
  }
149
149
  }
150
150
 
151
+ export function* getSenderDetails({
152
+ channel,
153
+ orgUnitId,
154
+ } = {}) {
155
+ try {
156
+ const apiResponse = yield call(Api.getSenderDetails, channel, orgUnitId);
157
+ if (!apiResponse?.errors?.length) {
158
+ yield put({
159
+ type: types.GET_SENDER_DETAILS_SUCCESS,
160
+ payload: apiResponse.entity.WHATSAPP,
161
+ });
162
+ } else {
163
+ yield put({
164
+ type: types.GET_SENDER_DETAILS_FAILURE,
165
+ payload: apiResponse.errors,
166
+ });
167
+ }
168
+ } catch (error) {
169
+ yield put({
170
+ type: types.GET_SENDER_DETAILS_FAILURE,
171
+ payload: [],
172
+ });
173
+ }
174
+ }
175
+
151
176
  function* watchGetAllTemplates() {
152
177
  const watcher = yield takeLatest(types.GET_ALL_TEMPLATES_REQUEST, getAllTemplates);
153
178
  yield take(LOCATION_CHANGE);
@@ -191,6 +216,12 @@ function* watchGetTemplateDetails() {
191
216
  yield cancel(watcher);
192
217
  }
193
218
 
219
+ function* watchGetSenderDetails() {
220
+ const watcher = yield takeLatest(types.GET_SENDER_DETAILS_REQUEST, getSenderDetails);
221
+ yield take(LOCATION_CHANGE);
222
+ yield cancel(watcher);
223
+ }
224
+
194
225
  // All sagas to be loaded
195
226
  export default [
196
227
  watchGetAllTemplates,
@@ -201,4 +232,5 @@ export default [
201
232
  watchGetDefaultBeeTemplates,
202
233
  watchGetTemplateDetails,
203
234
  watchGetOrgLevelCampaignSettings,
235
+ watchGetSenderDetails,
204
236
  ];