@capillarytech/creatives-library 8.0.90 → 8.0.91

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/package.json +1 -1
  2. package/services/api.js +7 -1
  3. package/services/tests/api.test.js +5 -1
  4. package/v2Components/CapImageUpload/index.js +13 -10
  5. package/v2Components/CapVideoUpload/index.js +12 -9
  6. package/v2Components/CapWhatsappCTA/messages.js +4 -0
  7. package/v2Components/CapWhatsappCarouselButton/constant.js +56 -0
  8. package/v2Components/CapWhatsappCarouselButton/index.js +446 -0
  9. package/v2Components/CapWhatsappCarouselButton/index.scss +39 -0
  10. package/v2Components/CapWhatsappCarouselButton/tests/index.test.js +237 -0
  11. package/v2Components/TemplatePreview/_templatePreview.scss +9 -0
  12. package/v2Components/TemplatePreview/assets/images/empty_image_preview.svg +4 -0
  13. package/v2Components/TemplatePreview/assets/images/empty_video_preview.svg +4 -0
  14. package/v2Components/TemplatePreview/index.js +171 -105
  15. package/v2Components/TemplatePreview/tests/__snapshots__/index.test.js.snap +6 -6
  16. package/v2Containers/CreativesContainer/index.js +91 -4
  17. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +1 -0
  18. package/v2Containers/Templates/_templates.scss +47 -0
  19. package/v2Containers/Templates/index.js +55 -5
  20. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +177 -156
  21. package/v2Containers/Whatsapp/constants.js +87 -1
  22. package/v2Containers/Whatsapp/index.js +707 -189
  23. package/v2Containers/Whatsapp/index.scss +52 -1
  24. package/v2Containers/Whatsapp/messages.js +38 -2
  25. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +30183 -90694
  26. package/v2Containers/Whatsapp/tests/__snapshots__/utils.test.js.snap +6 -0
  27. package/v2Containers/Whatsapp/tests/utils.test.js +80 -1
  28. package/v2Containers/Whatsapp/utils.js +34 -0
  29. package/v2Containers/mockdata.js +2 -0
@@ -66,10 +66,10 @@ exports[`Test Templates container Should render correct preview component for wh
66
66
  test
67
67
  </CapLabel>
68
68
  <div
69
- className="msg-container whatsapp-message-container"
69
+ className="msg-container whatsapp-message-container undefined"
70
70
  >
71
71
  <div
72
- className="message-pop align-left"
72
+ className="message-pop align-left undefined"
73
73
  style={
74
74
  Object {
75
75
  "background-color": "#ffffff",
@@ -163,10 +163,10 @@ exports[`Test Templates container Should render correct preview component for wh
163
163
  test
164
164
  </CapLabel>
165
165
  <div
166
- className="msg-container whatsapp-message-container"
166
+ className="msg-container whatsapp-message-container undefined"
167
167
  >
168
168
  <div
169
- className="message-pop align-left"
169
+ className="message-pop align-left undefined"
170
170
  style={
171
171
  Object {
172
172
  "background-color": "#ffffff",
@@ -235,10 +235,10 @@ exports[`Test Templates container Should render correct preview component for wh
235
235
  test
236
236
  </CapLabel>
237
237
  <div
238
- className="msg-container whatsapp-message-container"
238
+ className="msg-container whatsapp-message-container undefined"
239
239
  >
240
240
  <div
241
- className="message-pop align-left"
241
+ className="message-pop align-left undefined"
242
242
  style={
243
243
  Object {
244
244
  "background-color": "#ffffff",
@@ -44,7 +44,7 @@ import {
44
44
  import { IMAGE, VIDEO } from '../Facebook/Advertisement/constant';
45
45
  import { CREATIVE } from '../Facebook/constants';
46
46
  import { LOYALTY } from '../App/constants';
47
- import { WHATSAPP_STATUSES, WHATSAPP_MEDIA_TYPES } from '../Whatsapp/constants';
47
+ import { WHATSAPP_STATUSES, WHATSAPP_MEDIA_TYPES, PHONE_NUMBER, URL } from '../Whatsapp/constants';
48
48
 
49
49
  import { updateImagesInHtml } from '../../utils/cdnTransformation';
50
50
  import { IOS } from '../InApp/constants';
@@ -58,6 +58,7 @@ import {
58
58
  CAP_SPACE_32, CAP_SPACE_56, CAP_SPACE_64,
59
59
  } from '@capillarytech/cap-ui-library/styled/variables';
60
60
  import { DAEMON } from '@capillarytech/vulcan-react-sdk/utils/sagaInjectorTypes';
61
+ import { DYNAMIC_URL } from '../../v2Components/CapWhatsappCTA/constants';
61
62
 
62
63
  const classPrefix = 'add-creatives-section';
63
64
  const CREATIVES_CONTAINER = 'creativesContainer';
@@ -229,6 +230,39 @@ export class Creatives extends React.Component {
229
230
  this.setState({ isGetFormData: false });
230
231
  };
231
232
 
233
+ mapCarouselDataToCreatives = (cards) => {
234
+ return cards.map((card) => {
235
+ const { cardVarMapped, bodyTemplate, media, buttons, mediaType } = card || {};
236
+ const buttonData = buttons?.map((button) => {
237
+ const { type, text, phoneNumber, url, dynamicUrlPayload } = button || {};
238
+ const buttonObj = { type, text };
239
+ if (type === PHONE_NUMBER) {
240
+ buttonObj.phone_number = phoneNumber;
241
+ }
242
+ if (type === URL) {
243
+ buttonObj.url = url;
244
+ if (dynamicUrlPayload) {
245
+ buttonObj.urlType = DYNAMIC_URL;
246
+ }
247
+ }
248
+ return buttonObj;
249
+ });
250
+ return {
251
+ bodyText: bodyTemplate,
252
+ varMap: cardVarMapped,
253
+ ...(mediaType === IMAGE && {
254
+ imageUrl: media?.url,
255
+ }),
256
+ ...(mediaType === VIDEO && {
257
+ videoUrl: media?.url,
258
+ videoPreviewImg: media?.previewUrl,
259
+ }),
260
+ buttons: buttonData,
261
+ mediaType: mediaType?.toLowerCase(),
262
+ };
263
+ });
264
+ }
265
+
232
266
  getTemplateData = (templateData) => { //from consumers to creatives
233
267
  const { isFullMode, messageDetails = {}, smsRegister } = this.props;
234
268
  const { additionalProperties = {} } = messageDetails;
@@ -470,6 +504,7 @@ export class Creatives extends React.Component {
470
504
  mediaType = 'TEXT',
471
505
  whatsappMedia = {},
472
506
  isPreviewUrl = false,
507
+ cards = [],
473
508
  } = {},
474
509
  } = templateData;
475
510
  const mediaParams = {};
@@ -536,6 +571,10 @@ export class Creatives extends React.Component {
536
571
  },
537
572
  ],
538
573
  isPreviewUrl,
574
+ carouselData: this.mapCarouselDataToCreatives(cards),
575
+ ...(cards?.length && {
576
+ mediaType: WHATSAPP_MEDIA_TYPES.CAROUSEL,
577
+ }),
539
578
  },
540
579
  },
541
580
  },
@@ -582,6 +621,47 @@ export class Creatives extends React.Component {
582
621
  return templateData || null;
583
622
  }
584
623
 
624
+ getCarouselMappedData = (carouselData = []) => {
625
+ return carouselData.map((carousel) => {
626
+ const { bodyText, imageUrl, videoUrl, videoPreviewImg, buttons, mediaType, cardVarMapped, bodyTemplate } = carousel || {};
627
+ const buttonData = buttons.map((button, index) => {
628
+ const { type, text, phone_number, urlType, url } = button || {};
629
+ const buttonObj = {
630
+ type,
631
+ text,
632
+ index,
633
+ };
634
+ if (type === PHONE_NUMBER) {
635
+ buttonObj.phoneNumber = phone_number;
636
+ }
637
+ if (type === URL) {
638
+ buttonObj.url = url;
639
+ if (urlType === DYNAMIC_URL) {
640
+ const dynamicUrlPayload = url?.match(/{{(.*?)}}/g);
641
+ buttonObj.dynamicUrlPayload = dynamicUrlPayload?.length === 1 ? dynamicUrlPayload[0] : '';
642
+ }
643
+ }
644
+ return buttonObj;
645
+ });
646
+ return {
647
+ body: bodyText,
648
+ cardVarMapped,
649
+ bodyTemplate,
650
+ media: {
651
+ ...(mediaType?.toLowerCase() === IMAGE.toLowerCase() && {
652
+ url: imageUrl,
653
+ }),
654
+ ...(mediaType?.toLowerCase() === VIDEO.toLowerCase() && {
655
+ url: videoUrl,
656
+ previewUrl: videoPreviewImg,
657
+ }),
658
+ },
659
+ buttons: buttonData,
660
+ mediaType: mediaType?.toUpperCase(),
661
+ };
662
+ });
663
+ };
664
+
585
665
  getCreativesData = async (channel, template, templateRecords) => { //from creatives to consumers
586
666
  let templateData = { channel };
587
667
  switch (channel) {
@@ -754,6 +834,7 @@ export class Creatives extends React.Component {
754
834
  headerTemplate = '',
755
835
  } = {},
756
836
  isPreviewUrl = false,
837
+ carouselData = [],
757
838
  } = cloneDeep(versions.base.content.whatsapp);
758
839
 
759
840
  const modifiedButtons = cloneDeep(buttons).map((btn) => {
@@ -820,11 +901,17 @@ export class Creatives extends React.Component {
820
901
  varMapped,
821
902
  category,
822
903
  language: languages[0].language,
823
- buttonType,
824
- buttons: modifiedButtons,
904
+ ...(mediaType !== WHATSAPP_MEDIA_TYPES.CAROUSEL && {
905
+ buttonType,
906
+ buttons: modifiedButtons,
907
+ whatsappMedia,
908
+ }),
825
909
  mediaType,
826
- whatsappMedia,
827
910
  isPreviewUrl,
911
+ ...(mediaType === WHATSAPP_MEDIA_TYPES.CAROUSEL && {
912
+ cards: this.getCarouselMappedData(carouselData),
913
+ mediaType: carouselData[0]?.mediaType,
914
+ }),
828
915
  },
829
916
  };
830
917
  }
@@ -935,6 +935,7 @@ exports[`Test SlideBoxContent container Should render correct component for what
935
935
  charCounterEnabled={false}
936
936
  content={
937
937
  Object {
938
+ "carouselData": Array [],
938
939
  "charCount": 151,
939
940
  "ctaData": Array [
940
941
  Object {
@@ -172,6 +172,53 @@
172
172
  }
173
173
 
174
174
  }
175
+
176
+ .WHATSAPP {
177
+ .cap-custom-card {
178
+ .ant-card-body {
179
+ .ant-card-meta {
180
+ background-color: $CAP_G09;
181
+ padding: 0;
182
+ .ant-card-meta-description {
183
+ .whatsapp-container {
184
+ background-color: $CAP_WHITE;
185
+ padding: $CAP_SPACE_12;
186
+ }
187
+ .scroll-container {
188
+ overflow-x: auto;
189
+ display: flex;
190
+ padding-top: $CAP_SPACE_06;
191
+ padding-right: $CAP_SPACE_06;
192
+ white-space: nowrap;
193
+ scrollbar-width: none; // Hide scrollbar in Firefox
194
+ &::-webkit-scrollbar {
195
+ display: none; // Hide scrollbar in Chrome/Safari/Opera
196
+ }
197
+ overflow: hidden;
198
+ .whatsapp-carousel-container {
199
+ padding: $CAP_SPACE_04 0px $CAP_SPACE_08;
200
+ border-radius: $CAP_SPACE_06;
201
+ background-color: $CAP_WHITE;
202
+ width: 80%;
203
+ flex-shrink: 0;
204
+ margin-right: $CAP_SPACE_04;
205
+ white-space: pre-wrap;
206
+ word-break: break-word;
207
+ overflow: auto;
208
+ text-align: left;
209
+ .whatsapp-carousel-card {
210
+ margin: $CAP_SPACE_02 $CAP_SPACE_06 $CAP_SPACE_01 $CAP_SPACE_08;
211
+ .whatsapp-carousel-body {
212
+ margin-bottom: $CAP_SPACE_08;
213
+ }
214
+ }
215
+ }
216
+ }
217
+ }
218
+ }
219
+ }
220
+ }
221
+ }
175
222
  }
176
223
 
177
224
  .create-new-link{
@@ -113,10 +113,12 @@ import {
113
113
  KARIX_GUPSHUP_CATEGORY_OPTIONS,
114
114
  ICS_CATEGORY_OPTIONS,
115
115
  HOST_ICS,
116
+ IMAGE,
117
+ VIDEO,
116
118
  } from '../Whatsapp/constants';
117
119
  import { INAPP_LAYOUT_DETAILS } from '../InApp/constants';
118
120
  import { ZALO_STATUS_OPTIONS, ZALO_STATUSES } from '../Zalo/constants';
119
- import { getWhatsappContent, getWhatsappStatus, getWhatsappCategory, getWhatsappCta, getWhatsappQuickReply, getWhatsappAutoFill } from '../Whatsapp/utils';
121
+ import { getWhatsappContent, getWhatsappStatus, getWhatsappCategory, getWhatsappCta, getWhatsappQuickReply, getWhatsappAutoFill, getWhatsappCarouselButtonView } from '../Whatsapp/utils';
120
122
  import { getRCSContent } from '../Rcs/utils';
121
123
  import zaloMessages from '../Zalo/messages';
122
124
  import globalMessages from '../../v2Containers/Cap/messages';
@@ -134,7 +136,8 @@ import whatsappOrZaloAccountIllustration from '../Assets/images/whatsappOrZaloAc
134
136
  import rcsIllustration from '../Assets/images/rcsIllustration.png';
135
137
  import zaloillustration from '@capillarytech/cap-ui-library/assets/images/featureUiNotEnabledIllustration.svg';
136
138
  import inAppIllustration from '@capillarytech/cap-ui-library/assets/images/featureUiNotEnabledIllustration.svg';
137
-
139
+ import whatsappImageEmptyPreview from '../../v2Components/TemplatePreview/assets/images/empty_image_preview.svg';
140
+ import whatsappVideoEmptyPreview from '../../v2Components/TemplatePreview/assets/images/empty_video_preview.svg';
138
141
  import { CAP_SPACE_16 } from '@capillarytech/cap-ui-library/styled/variables';
139
142
  import { GA } from '@capillarytech/cap-ui-utils';
140
143
  import { MAPP_SDK } from '../InApp/constants';
@@ -1110,8 +1113,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1110
1113
  ? this.getCreativesEditText(channelLowerCase)
1111
1114
  : messages.selectButton
1112
1115
  );
1113
-
1114
- const cardDataList = filteredTemplates && filteredTemplates.length ? map(filteredTemplates, (template) => {
1116
+ const cardDataList = filteredTemplates && filteredTemplates.length ? map(filteredTemplates, (template) => {
1115
1117
  const androidBodyType = get(template, 'versions.base.content.ANDROID.bodyType');
1116
1118
  const iosBodyType = get(template, 'versions.base.content.IOS.bodyType');
1117
1119
  const inappBodyType = androidBodyType || iosBodyType;
@@ -1366,7 +1368,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1366
1368
  break;
1367
1369
  }
1368
1370
  case WHATSAPP: {
1369
- const { whatsappImageSrc = '', templateMsg, docPreview, whatsappVideoPreviewImg = '', templateHeaderPreview, templateFooterPreview} = getWhatsappContent(template);
1371
+ const { whatsappImageSrc = '', templateMsg, docPreview, whatsappVideoPreviewImg = '', templateHeaderPreview, templateFooterPreview, carouselData = [] } = getWhatsappContent(template);
1370
1372
  templateData.title = (
1371
1373
  <CapRow>
1372
1374
  <CapLabel className="whatsapp-rcs-template-name">{template?.name}</CapLabel>
@@ -1375,6 +1377,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1375
1377
  );
1376
1378
  templateData.content = (
1377
1379
  <>
1380
+ <div className='whatsapp-container'>
1378
1381
  {whatsappImageSrc && (
1379
1382
  <CapImage src={whatsappImageSrc} className="whatsapp-image" />
1380
1383
  )}
@@ -1404,6 +1407,53 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1404
1407
  {getWhatsappCta(template)}
1405
1408
  {getWhatsappQuickReply(template)}
1406
1409
  {getWhatsappAutoFill(template)}
1410
+ </div>
1411
+ <div className="scroll-container">
1412
+ {carouselData.map((data, index) => {
1413
+ return (
1414
+ <div
1415
+ key={`carousel-${index + 1}`}
1416
+ className="whatsapp-carousel-container"
1417
+ role="group"
1418
+ >
1419
+ <div className="whatsapp-carousel-card">
1420
+ {data?.mediaType === IMAGE.toLowerCase() && (
1421
+ <CapImage
1422
+ src={data?.imageUrl ? data?.imageUrl : whatsappImageEmptyPreview}
1423
+ className="whatsapp-image"
1424
+ />
1425
+ )}
1426
+ {data?.mediaType === VIDEO.toLowerCase() && (
1427
+ <div className="video-preview">
1428
+ <CapImage
1429
+ src={data?.videoPreviewImg ? data?.videoPreviewImg : whatsappVideoEmptyPreview}
1430
+ className="whatsapp-image"
1431
+ />
1432
+ <div className="icon-position">
1433
+ <CapImage
1434
+ className="video-icon"
1435
+ src={videoPlay}
1436
+ />
1437
+ </div>
1438
+ </div>
1439
+ )}
1440
+ <span
1441
+ className={`${
1442
+ (data?.imageUrl || data?.videoPreviewImg)
1443
+ ? 'whatsapp-message-with-media'
1444
+ : 'whatsapp-message-without-media'
1445
+ }`}
1446
+ >
1447
+ <CapLabel type="label9" className='whatsapp-carousel-body'>
1448
+ {data?.bodyText}
1449
+ </CapLabel>
1450
+ </span>
1451
+ {getWhatsappCarouselButtonView(data?.buttons, false)}
1452
+ </div>
1453
+ </div>
1454
+ )
1455
+ })}
1456
+ </div>
1407
1457
  </>
1408
1458
  );
1409
1459
  break;