@capillarytech/creatives-library 8.0.253 → 8.0.254

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 (143) hide show
  1. package/assets/Android.png +0 -0
  2. package/assets/iOS.png +0 -0
  3. package/constants/unified.js +1 -2
  4. package/initialReducer.js +0 -2
  5. package/package.json +1 -1
  6. package/services/api.js +0 -10
  7. package/services/tests/api.test.js +0 -34
  8. package/utils/common.js +0 -5
  9. package/utils/commonUtils.js +5 -28
  10. package/utils/tests/commonUtil.test.js +0 -224
  11. package/utils/transformTemplateConfig.js +10 -0
  12. package/v2Components/CapDeviceContent/index.js +56 -61
  13. package/v2Components/CapTagList/index.js +1 -6
  14. package/v2Components/CapTagListWithInput/index.js +1 -5
  15. package/v2Components/CapTagListWithInput/messages.js +1 -1
  16. package/v2Components/CapWhatsappCTA/tests/index.test.js +0 -5
  17. package/v2Components/ErrorInfoNote/index.js +72 -457
  18. package/v2Components/ErrorInfoNote/messages.js +6 -36
  19. package/v2Components/ErrorInfoNote/style.scss +6 -282
  20. package/v2Components/FormBuilder/tests/index.test.js +4 -13
  21. package/v2Components/HtmlEditor/HTMLEditor.js +94 -547
  22. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +133 -1358
  23. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +16 -27
  24. package/v2Components/HtmlEditor/_htmlEditor.scss +45 -108
  25. package/v2Components/HtmlEditor/_index.lazy.scss +1 -0
  26. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +101 -22
  27. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +140 -146
  28. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +1 -2
  29. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
  30. package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +0 -9
  31. package/v2Components/HtmlEditor/components/EditorToolbar/index.js +1 -1
  32. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +0 -22
  33. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +7 -4
  34. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +45 -35
  35. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +3 -1
  36. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
  37. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +6 -7
  38. package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +6 -3
  39. package/v2Components/HtmlEditor/components/PreviewPane/index.js +34 -24
  40. package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
  41. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +152 -0
  42. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +31 -49
  43. package/v2Components/HtmlEditor/components/ValidationPanel/_validationPanel.scss +34 -50
  44. package/v2Components/HtmlEditor/components/ValidationPanel/index.js +41 -70
  45. package/v2Components/HtmlEditor/constants.js +20 -42
  46. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +16 -373
  47. package/v2Components/HtmlEditor/hooks/useEditorContent.js +2 -5
  48. package/v2Components/HtmlEditor/hooks/useInAppContent.js +146 -88
  49. package/v2Components/HtmlEditor/hooks/useValidation.js +53 -189
  50. package/v2Components/HtmlEditor/index.js +1 -1
  51. package/v2Components/HtmlEditor/messages.js +85 -95
  52. package/v2Components/HtmlEditor/utils/__tests__/htmlValidator.enhanced.test.js +45 -94
  53. package/v2Components/HtmlEditor/utils/__tests__/validationAdapter.test.js +0 -134
  54. package/v2Components/HtmlEditor/utils/contentSanitizer.js +41 -40
  55. package/v2Components/HtmlEditor/utils/htmlValidator.js +72 -71
  56. package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +102 -134
  57. package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +25 -23
  58. package/v2Components/HtmlEditor/utils/validationAdapter.js +41 -66
  59. package/v2Components/MobilePushPreviewV2/index.js +7 -32
  60. package/v2Components/TemplatePreview/_templatePreview.scss +24 -55
  61. package/v2Components/TemplatePreview/index.js +32 -47
  62. package/v2Components/TemplatePreview/messages.js +0 -4
  63. package/v2Components/TestAndPreviewSlidebox/_testAndPreviewSlidebox.scss +0 -1
  64. package/v2Containers/BeeEditor/index.js +90 -172
  65. package/v2Containers/CreativesContainer/SlideBoxContent.js +51 -128
  66. package/v2Containers/CreativesContainer/SlideBoxFooter.js +13 -163
  67. package/v2Containers/CreativesContainer/SlideBoxHeader.js +1 -2
  68. package/v2Containers/CreativesContainer/constants.js +0 -1
  69. package/v2Containers/CreativesContainer/index.js +46 -239
  70. package/v2Containers/CreativesContainer/messages.js +0 -8
  71. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +2 -11
  72. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +50 -38
  73. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +0 -106
  74. package/v2Containers/Email/actions.js +0 -7
  75. package/v2Containers/Email/constants.js +1 -5
  76. package/v2Containers/Email/index.js +32 -241
  77. package/v2Containers/Email/messages.js +0 -32
  78. package/v2Containers/Email/reducer.js +1 -12
  79. package/v2Containers/Email/sagas.js +7 -61
  80. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +0 -2
  81. package/v2Containers/Email/tests/reducer.test.js +0 -46
  82. package/v2Containers/Email/tests/sagas.test.js +29 -320
  83. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +19 -207
  84. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +74 -40
  85. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +67 -2
  86. package/v2Containers/EmailWrapper/constants.js +0 -2
  87. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +77 -629
  88. package/v2Containers/EmailWrapper/index.js +23 -103
  89. package/v2Containers/EmailWrapper/messages.js +1 -61
  90. package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +214 -0
  91. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +77 -594
  92. package/v2Containers/InApp/actions.js +0 -7
  93. package/v2Containers/InApp/constants.js +4 -20
  94. package/v2Containers/InApp/index.js +359 -802
  95. package/v2Containers/InApp/index.scss +3 -4
  96. package/v2Containers/InApp/messages.js +3 -7
  97. package/v2Containers/InApp/reducer.js +3 -21
  98. package/v2Containers/InApp/sagas.js +9 -29
  99. package/v2Containers/InApp/selectors.js +5 -25
  100. package/v2Containers/InApp/tests/index.test.js +50 -154
  101. package/v2Containers/InApp/tests/reducer.test.js +0 -34
  102. package/v2Containers/InApp/tests/sagas.test.js +9 -61
  103. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +0 -3
  104. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +0 -2
  105. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +0 -2
  106. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +0 -9
  107. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +0 -12
  108. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +0 -4
  109. package/v2Containers/TagList/index.js +19 -62
  110. package/v2Containers/Templates/_templates.scss +1 -60
  111. package/v2Containers/Templates/index.js +4 -89
  112. package/v2Containers/Templates/messages.js +0 -4
  113. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +0 -34
  114. package/v2Components/ErrorInfoNote/constants.js +0 -1
  115. package/v2Components/HtmlEditor/__tests__/HTMLEditor.apiErrors.test.js +0 -874
  116. package/v2Components/HtmlEditor/components/ValidationPanel/constants.js +0 -6
  117. package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +0 -254
  118. package/v2Components/HtmlEditor/components/ValidationTabs/index.js +0 -364
  119. package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +0 -51
  120. package/v2Components/HtmlEditor/hooks/__tests__/useValidation.apiErrors.test.js +0 -795
  121. package/v2Components/HtmlEditor/utils/validationConstants.js +0 -40
  122. package/v2Containers/BeePopupEditor/_beePopupEditor.scss +0 -14
  123. package/v2Containers/BeePopupEditor/constants.js +0 -10
  124. package/v2Containers/BeePopupEditor/index.js +0 -194
  125. package/v2Containers/BeePopupEditor/tests/index.test.js +0 -627
  126. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +0 -1285
  127. package/v2Containers/EmailWrapper/components/__tests__/EmailHTMLEditor.test.js +0 -1870
  128. package/v2Containers/EmailWrapper/components/__tests__/EmailWrapperView.test.js +0 -520
  129. package/v2Containers/EmailWrapper/tests/useEmailWrapper.edgeCases.test.js +0 -643
  130. package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +0 -376
  131. package/v2Containers/InApp/__tests__/sagas.test.js +0 -363
  132. package/v2Containers/InApp/tests/selectors.test.js +0 -612
  133. package/v2Containers/InAppWrapper/components/InAppWrapperView.js +0 -151
  134. package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +0 -267
  135. package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +0 -23
  136. package/v2Containers/InAppWrapper/constants.js +0 -16
  137. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +0 -473
  138. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +0 -198
  139. package/v2Containers/InAppWrapper/index.js +0 -148
  140. package/v2Containers/InAppWrapper/messages.js +0 -49
  141. package/v2Containers/InappAdvance/index.js +0 -1099
  142. package/v2Containers/InappAdvance/index.scss +0 -10
  143. package/v2Containers/InappAdvance/tests/index.test.js +0 -448
Binary file
package/assets/iOS.png CHANGED
Binary file
@@ -45,7 +45,6 @@ export const GIFT_CARDS = 'GIFT_CARDS';
45
45
  export const PROMO_ENGINE = 'PROMO_ENGINE';
46
46
  export const LIQUID_SUPPORT = 'ENABLE_LIQUID_SUPPORT';
47
47
  export const ENABLE_NEW_MPUSH = 'ENABLE_NEW_MPUSH';
48
- export const SUPPORT_CK_EDITOR = 'SUPPORT_CK_EDITOR';
49
48
  export const CUSTOM_TAG = 'CustomTagMessage';
50
49
  export const CUSTOMER_EXTENDED_FIELD = 'Customer extended fields';
51
50
  export const EXTENDED_TAG = 'ExtendedTagMessage';
@@ -169,7 +168,7 @@ export const JAPANESE_HIDE_DATE_TAGS = [
169
168
  "dd.mm.yy",
170
169
  "dd Mon",
171
170
  "dd/m/yyyy",
172
- ];
171
+ ];
173
172
 
174
173
  export const LIQUID_SUPPORTED_CHANNELS = [EMAIL, SMS, MOBILE_PUSH, INAPP];
175
174
 
package/initialReducer.js CHANGED
@@ -15,7 +15,6 @@ import galleryReducer from './v2Containers/Assets/Gallery/reducer';
15
15
  import CapCollapsibleLeftNavigationReducer from '@capillarytech/cap-ui-library/CapCollapsibleLeftNavigation/reducer';
16
16
  import { AIRA_REDUCER_DOMAIN, askAiraReducer } from '@capillarytech/cap-ui-library/CapAskAira';
17
17
  import previewAndTestReducer from './v2Components/TestAndPreviewSlidebox/reducer';
18
- import inAppReducer from './v2Containers/InApp/reducer';
19
18
 
20
19
  export const initialReducer = {
21
20
  language: languageProviderReducer,
@@ -34,5 +33,4 @@ export const initialReducer = {
34
33
  gallery: galleryReducer,
35
34
  navigationConfig: CapCollapsibleLeftNavigationReducer,
36
35
  previewAndTest: previewAndTestReducer,
37
- inApp: inAppReducer,
38
36
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@capillarytech/creatives-library",
3
3
  "author": "meharaj",
4
- "version": "8.0.253",
4
+ "version": "8.0.254",
5
5
  "description": "Capillary creatives ui",
6
6
  "main": "./index.js",
7
7
  "module": "./index.es.js",
package/services/api.js CHANGED
@@ -465,11 +465,6 @@ export const getCmsTemplateSettingsV2 = (cmsType, projectId, cmsMode, langId, is
465
465
  return API.get(url);
466
466
  };
467
467
 
468
- export const getCmsAccounts = (cmsType) => {
469
- const url = `${API_ENDPOINT}/cms/accounts?type=${cmsType}`;
470
- return API.get(url);
471
- };
472
-
473
468
  export const getCmsTemplateData = (cmsType, projectId, langId) => {
474
469
  const url = `${API_ENDPOINT}/cms/getContent?type=${cmsType}&projectId=${projectId}&langId=${langId}`;
475
470
  return API.get(url);
@@ -725,9 +720,4 @@ export const getAssetStatus = (type, assetId) => {
725
720
  return request(url, getAPICallObject('GET'));
726
721
  };
727
722
 
728
- export const getBeePopupBuilderToken = () => {
729
- const url = `${API_ENDPOINT}/common/getInappTokenData`;
730
- return request(url, getAPICallObject('GET'));
731
- };
732
-
733
723
  export {request, getAPICallObject};
@@ -26,8 +26,6 @@ import {
26
26
  updateMetaConfig,
27
27
  getMediaDetails,
28
28
  getAssetStatus,
29
- getBeePopupBuilderToken,
30
- getCmsAccounts,
31
29
  } from '../api';
32
30
  import { mockData } from './mockData';
33
31
  import getSchema from '../getSchema';
@@ -975,35 +973,3 @@ describe('getAssetStatus', () => {
975
973
  expect(callArgs[0]).toContain('/assets/video/asset-456/status');
976
974
  });
977
975
  });
978
-
979
- describe('getBeePopupBuilderToken', () => {
980
- it('should return correct response', async () => {
981
- global.fetch.mockReturnValue(Promise.resolve({
982
- status: 200,
983
- json: () => Promise.resolve({
984
- status: 200,
985
- response: 'test',
986
- }),
987
- }));
988
- const result = await getBeePopupBuilderToken();
989
- expect(result).toEqual({
990
- status: 200,
991
- response: 'test',
992
- });
993
- });
994
- });
995
-
996
- describe('getCmsAccounts', () => {
997
- it('should return a promise (line 473-476)', () => {
998
- // Similar to other API tests, just verify it returns a Promise
999
- const result = getCmsAccounts('bee');
1000
- expect(result).toBeInstanceOf(Promise);
1001
- });
1002
-
1003
- it('should be callable with cmsType parameter', () => {
1004
- // Verify function exists and can be called
1005
- expect(typeof getCmsAccounts).toBe('function');
1006
- const result = getCmsAccounts('bee');
1007
- expect(result).toBeInstanceOf(Promise);
1008
- });
1009
- });
package/utils/common.js CHANGED
@@ -22,7 +22,6 @@ import {
22
22
  BADGES_ISSUE,
23
23
  ENABLE_WECHAT,
24
24
  LIQUID_SUPPORT,
25
- SUPPORT_CK_EDITOR,
26
25
  ENABLE_NEW_MPUSH
27
26
  } from '../constants/unified';
28
27
  import { apiMessageFormatHandler } from './commonUtils';
@@ -96,10 +95,6 @@ export const hasLiquidSupportFeature = Auth.hasFeatureAccess.bind(
96
95
  LIQUID_SUPPORT,
97
96
  );
98
97
 
99
- export const hasSupportCKEditor = Auth.hasFeatureAccess.bind(
100
- null,
101
- SUPPORT_CK_EDITOR,
102
- );
103
98
 
104
99
  export const hasGiftVoucherFeature = Auth.hasFeatureAccess.bind(
105
100
  null,
@@ -173,30 +173,20 @@ export const validateLiquidTemplateContent = async (
173
173
  // Handle API errors or empty content
174
174
  if (result?.errors?.length > 0 || !validString || isError) {
175
175
  let standardErrors = [];
176
- let liquidErrors = [];
177
-
178
- // Empty content errors are NOT from liquid endpoints, so they go to standardErrors
179
176
  if (!validString) {
180
177
  standardErrors = [emptyBodyError];
181
178
  }
182
-
183
- // IMPORTANT: Errors from extractTags and liquidValidation endpoints should ALWAYS be categorized as liquidErrors
184
- // These endpoints are: /extractTags and /ask-aira-service/creatives_ai/liquidValidation
185
- // Only errors from these endpoints should appear in Liquid Issues tab
186
- if (result && Array.isArray(result?.errors) && result.errors.length > 0) {
187
- // Errors from extractTags or liquidValidation endpoints
188
- liquidErrors = result.errors.map((error) => {
179
+ let liquidErrors;
180
+ if (result && Array.isArray(result?.errors)) {
181
+ liquidErrors = result?.errors?.map((error) => {
189
182
  const message = typeof error?.message === "string"
190
183
  ? error.message
191
184
  : somethingWrongMsg;
192
185
  return message;
193
186
  });
194
- } else if (isError) {
195
- // If isError is true, it means the API call to extractTags/liquidValidation failed
196
- // This is also a liquid endpoint error, so categorize as liquidErrors
187
+ } else {
197
188
  liquidErrors = [somethingWrongMsg];
198
189
  }
199
-
200
190
  onError({
201
191
  standardErrors,
202
192
  liquidErrors,
@@ -408,20 +398,7 @@ export const validateMobilePushContent = async (formData, options) => {
408
398
  // Helper function to extract content for a platform
409
399
  export const extractContent = (platformData) => {
410
400
  if (!platformData) return '';
411
- const { title, message, ctas, isBEEeditor, beeHtml } = platformData;
412
-
413
- // For BEE editor, extract content from beeHtml
414
- if (isBEEeditor && beeHtml) {
415
- // beeHtml can be an object with value property or a string
416
- const beeHtmlContent = typeof beeHtml === 'string' ? beeHtml : (beeHtml?.value || '');
417
- return [
418
- title,
419
- beeHtmlContent,
420
- ...((ctas?.map((cta) => cta?.text || cta?.actionLink)) || []),
421
- ].filter(Boolean).join(' ');
422
- }
423
-
424
- // For regular content
401
+ const { title, message, ctas } = platformData;
425
402
  return [
426
403
  title,
427
404
  message,
@@ -1376,228 +1376,4 @@ describe("validateCarouselCards", () => {
1376
1376
  expect(result.isValid).toBe(true);
1377
1377
  });
1378
1378
  });
1379
-
1380
- describe('extractContent BEE Editor Logic (L404-L412)', () => {
1381
- it('extracts content from beeHtml as string', () => {
1382
- const platformData = {
1383
- title: 'Test Title',
1384
- isBEEeditor: true,
1385
- beeHtml: '<p>BEE HTML Content</p>',
1386
- ctas: [
1387
- { text: 'Click Here', actionLink: 'https://example.com' },
1388
- ],
1389
- };
1390
-
1391
- const result = extractContent(platformData);
1392
-
1393
- expect(result).toContain(platformData.title);
1394
- expect(result).toContain(platformData.beeHtml);
1395
- expect(result).toContain(platformData.ctas[0].text);
1396
- });
1397
-
1398
- it('extracts content from beeHtml as object with value property', () => {
1399
- const platformData = {
1400
- title: 'Test Title',
1401
- isBEEeditor: true,
1402
- beeHtml: { value: '<p>BEE HTML from Object</p>' },
1403
- ctas: [
1404
- { text: 'Button Text' },
1405
- ],
1406
- };
1407
-
1408
- const result = extractContent(platformData);
1409
-
1410
- expect(result).toContain(platformData.title);
1411
- expect(result).toContain(platformData.beeHtml.value);
1412
- expect(result).toContain(platformData.ctas[0].text);
1413
- });
1414
-
1415
- it('handles beeHtml as object without value property', () => {
1416
- const platformData = {
1417
- title: 'Test Title',
1418
- isBEEeditor: true,
1419
- beeHtml: { someOtherProperty: 'data' },
1420
- ctas: [],
1421
- };
1422
-
1423
- const result = extractContent(platformData);
1424
-
1425
- // Should extract title and empty beeHtml (since value is undefined)
1426
- expect(result).toContain('Test Title');
1427
- expect(result).not.toContain('someOtherProperty');
1428
- });
1429
-
1430
- it('extracts ctas with text property', () => {
1431
- const platformData = {
1432
- title: 'Title',
1433
- isBEEeditor: true,
1434
- beeHtml: '<p>Content</p>',
1435
- ctas: [
1436
- { text: 'CTA Text 1' },
1437
- { text: 'CTA Text 2' },
1438
- ],
1439
- };
1440
-
1441
- const result = extractContent(platformData);
1442
-
1443
- expect(result).toContain('CTA Text 1');
1444
- expect(result).toContain('CTA Text 2');
1445
- });
1446
-
1447
- it('extracts ctas with actionLink when text is missing', () => {
1448
- const platformData = {
1449
- title: 'Title',
1450
- isBEEeditor: true,
1451
- beeHtml: '<p>Content</p>',
1452
- ctas: [
1453
- { actionLink: 'https://link1.com' },
1454
- { actionLink: 'https://link2.com' },
1455
- ],
1456
- };
1457
-
1458
- const result = extractContent(platformData);
1459
-
1460
- expect(result).toContain('https://link1.com');
1461
- expect(result).toContain('https://link2.com');
1462
- });
1463
-
1464
- it('filters out falsy values with filter(Boolean)', () => {
1465
- const platformData = {
1466
- title: '',
1467
- isBEEeditor: true,
1468
- beeHtml: null,
1469
- ctas: [
1470
- { text: null, actionLink: null },
1471
- { text: 'Valid Text' },
1472
- ],
1473
- };
1474
-
1475
- const result = extractContent(platformData);
1476
-
1477
- // Should only contain 'Valid Text' after filtering
1478
- expect(result).toBe('Valid Text');
1479
- });
1480
-
1481
- it('handles empty ctas array', () => {
1482
- const platformData = {
1483
- title: 'Title Only',
1484
- isBEEeditor: true,
1485
- beeHtml: '<p>BEE Content</p>',
1486
- ctas: [],
1487
- };
1488
-
1489
- const result = extractContent(platformData);
1490
-
1491
- expect(result).toContain('Title Only');
1492
- expect(result).toContain('<p>BEE Content</p>');
1493
- });
1494
-
1495
- it('handles undefined ctas', () => {
1496
- const platformData = {
1497
- title: 'Title',
1498
- isBEEeditor: true,
1499
- beeHtml: '<p>Content</p>',
1500
- ctas: undefined,
1501
- };
1502
-
1503
- const result = extractContent(platformData);
1504
-
1505
- expect(result).toContain('Title');
1506
- expect(result).toContain('<p>Content</p>');
1507
- });
1508
-
1509
- it('joins all content with spaces', () => {
1510
- const platformData = {
1511
- title: 'Title',
1512
- isBEEeditor: true,
1513
- beeHtml: 'HTML',
1514
- ctas: [
1515
- { text: 'CTA1' },
1516
- { text: 'CTA2' },
1517
- ],
1518
- };
1519
-
1520
- const result = extractContent(platformData);
1521
-
1522
- expect(result).toBe('Title HTML CTA1 CTA2');
1523
- });
1524
-
1525
- it('falls back to regular content when not BEE editor', () => {
1526
- const platformData = {
1527
- title: 'Title',
1528
- message: 'Message',
1529
- isBEEeditor: false,
1530
- beeHtml: '<p>Should be ignored</p>',
1531
- ctas: [
1532
- { text: 'CTA' },
1533
- ],
1534
- };
1535
-
1536
- const result = extractContent(platformData);
1537
-
1538
- expect(result).toContain('Title');
1539
- expect(result).toContain('Message');
1540
- expect(result).toContain('CTA');
1541
- expect(result).not.toContain('<p>Should be ignored</p>');
1542
- });
1543
-
1544
- it('handles null beeHtml', () => {
1545
- const platformData = {
1546
- title: 'Title',
1547
- isBEEeditor: true,
1548
- beeHtml: null,
1549
- ctas: [{ text: 'CTA' }],
1550
- };
1551
-
1552
- const result = extractContent(platformData);
1553
-
1554
- expect(result).toContain('Title');
1555
- expect(result).toContain('CTA');
1556
- });
1557
-
1558
- it('handles undefined beeHtml', () => {
1559
- const platformData = {
1560
- title: 'Title',
1561
- isBEEeditor: true,
1562
- beeHtml: undefined,
1563
- ctas: [],
1564
- };
1565
-
1566
- const result = extractContent(platformData);
1567
-
1568
- expect(result).toBe('Title');
1569
- });
1570
-
1571
- it('handles complex ctas with both text and actionLink', () => {
1572
- const platformData = {
1573
- title: 'Title',
1574
- isBEEeditor: true,
1575
- beeHtml: 'Content',
1576
- ctas: [
1577
- { text: 'CTA Text', actionLink: 'https://example.com' },
1578
- ],
1579
- };
1580
-
1581
- const result = extractContent(platformData);
1582
-
1583
- // Should prefer text over actionLink
1584
- expect(result).toContain('CTA Text');
1585
- expect(result).toContain('Title');
1586
- expect(result).toContain('Content');
1587
- });
1588
-
1589
- it('handles empty string beeHtml', () => {
1590
- const platformData = {
1591
- title: 'Title',
1592
- isBEEeditor: true,
1593
- beeHtml: '',
1594
- ctas: [{ text: 'CTA' }],
1595
- };
1596
-
1597
- const result = extractContent(platformData);
1598
-
1599
- expect(result).toBe('Title CTA');
1600
- });
1601
- });
1602
1379
  });
1603
-
@@ -101,6 +101,7 @@ export async function transformTemplateConfigWithMediaDetails(templateConfig, ch
101
101
  const contentType = detectMediaContentType(templateConfig);
102
102
 
103
103
  if (contentType === MEDIA_CONTENT_TYPE.NONE) {
104
+ console.log('No media content detected, returning original config');
104
105
  return templateConfig;
105
106
  }
106
107
 
@@ -108,19 +109,24 @@ export async function transformTemplateConfigWithMediaDetails(templateConfig, ch
108
109
  let transformDirection;
109
110
  if (forceDirection) {
110
111
  transformDirection = forceDirection;
112
+ console.log(`Forced transformation direction: ${transformDirection}`);
111
113
  } else {
112
114
  // Auto-detect based on content
113
115
  if (contentType === MEDIA_CONTENT_TYPE.URLS) {
114
116
  transformDirection = TRANSFORM_DIRECTION.FORWARD; // URLs → tags
117
+ console.log('Detected URLs, applying forward transformation (URLs → tags)');
115
118
  } else if (contentType === MEDIA_CONTENT_TYPE.TAGS) {
116
119
  transformDirection = TRANSFORM_DIRECTION.REVERSE; // tags → URLs
120
+ console.log('Detected media_content tags, applying reverse transformation (tags → URLs)');
117
121
  } else if (contentType === MEDIA_CONTENT_TYPE.MIXED) {
118
122
  transformDirection = TRANSFORM_DIRECTION.SMART; // Handle mixed content intelligently
123
+ console.log('Detected mixed content, applying smart transformation');
119
124
  }
120
125
  }
121
126
 
122
127
  const newConfig = cloneDeep(templateConfig);
123
128
  try {
129
+ console.log(`Fetching media details for ${transformDirection} transformation, ID: ${mediaDetailsId}`);
124
130
 
125
131
  // Fetch media details mapping from API
126
132
  const response = await getMediaDetails({ id: mediaDetailsId })
@@ -139,6 +145,7 @@ export async function transformTemplateConfigWithMediaDetails(templateConfig, ch
139
145
  idToUrlMapping[mediaId] = url;
140
146
  });
141
147
 
148
+ console.log(`Processing ${Object.keys(urlToIdMapping).length} media mappings`);
142
149
 
143
150
  // Apply transformations based on direction
144
151
  newConfig?.cards?.forEach(card => {
@@ -150,6 +157,7 @@ export async function transformTemplateConfigWithMediaDetails(templateConfig, ch
150
157
  // Forward transformation: URL → tag
151
158
  const mediaDetailId = urlToIdMapping[currentUrl];
152
159
  if (mediaDetailId) {
160
+ console.log(`Forward: ${currentUrl} → {{media_content(${mediaDetailId})}}`);
153
161
  card.media.url = `{{media_content(${mediaDetailId})}}`;
154
162
  } else {
155
163
  console.warn(`No media detail ID found for URL: ${currentUrl}`);
@@ -161,6 +169,7 @@ export async function transformTemplateConfigWithMediaDetails(templateConfig, ch
161
169
  if (mediaId) {
162
170
  const actualUrl = idToUrlMapping[mediaId];
163
171
  if (actualUrl) {
172
+ console.log(`Reverse: {{media_content(${mediaId})}} → ${actualUrl}`);
164
173
  card.media.url = actualUrl;
165
174
  } else {
166
175
  console.warn(`No URL found for media ID: ${mediaId}`);
@@ -176,6 +185,7 @@ export async function transformTemplateConfigWithMediaDetails(templateConfig, ch
176
185
  console.error('Failed to fetch media details for transformation:', error);
177
186
 
178
187
  // Fallback: try to extract/convert what we can without API
188
+ console.log('Falling back to URL extraction method');
179
189
  newConfig.cards.forEach(card => {
180
190
  if (card.media && card.media.url) {
181
191
  if (transformDirection === TRANSFORM_DIRECTION.FORWARD) {
@@ -69,7 +69,7 @@ const CapDeviceContent = (props) => {
69
69
  templateDescErrorHandler,
70
70
  templateTitleError,
71
71
  setTemplateTitleError,
72
- isAiContentBotDisabled,
72
+ isAiContentBotDisabled
73
73
  } = props || {};
74
74
  const { TextArea } = CapInput;
75
75
  const { formatMessage } = intl;
@@ -167,22 +167,21 @@ const CapDeviceContent = (props) => {
167
167
  return (
168
168
  <>
169
169
  <CapRow className="creatives-device-content">
170
- <CapLink
170
+ <CapLink
171
171
  title={isAndroid
172
- ? formatMessage(messages.copyContentFromIOS)
173
- : formatMessage(messages.copyCotentFromAndroid)}
172
+ ? formatMessage(messages.copyContentFromIOS)
173
+ : formatMessage(messages.copyCotentFromAndroid)}
174
174
  className="inapp-copy-content"
175
175
  onClick={onCopyTitleAndContent}
176
- />
176
+ />
177
177
  <CapRow className="creatives-inapp-title">
178
178
  <CapColumn
179
- className="inapp-content-main"
179
+ className="inapp-content-main"
180
180
  >
181
181
  <CapHeading type="h5" className="inapp-title">
182
182
  {formatMessage(messages.title)}
183
183
  </CapHeading>
184
- {getTagList(0)}
185
- {/* here 0 signifies the tags for template title */}
184
+ {getTagList(0)} {/* here 0 signifies the tags for template title */}
186
185
  </CapColumn>
187
186
  <CapInput
188
187
  id="inapp-title-name-input"
@@ -214,7 +213,7 @@ const CapDeviceContent = (props) => {
214
213
  </CapRow>
215
214
  <CapRow className={`creatives-inapp-message ${!isMediaTypeImage && "message-bottom-margin"}`}>
216
215
  <CapColumn
217
- className="inapp-message-header"
216
+ className="inapp-message-header"
218
217
  >
219
218
  <CapHeading type="h5" className="inapp-message-header-style">
220
219
  {formatMessage(messages.message)}
@@ -223,37 +222,37 @@ const CapDeviceContent = (props) => {
223
222
  {/* here 1 signifies the tags for template message */}
224
223
  </CapColumn>
225
224
  <div className="inapp-create-template-message-input-wrapper">
226
- <TextArea
227
- id="inapp-create-template-message-input"
228
- className="inapp-create-template-message-input"
229
- placeholder={formatMessage(messages.textAreaInputPlaceholder)}
230
- onChange={onTemplateMessageChange}
231
- value={templateMessage || ""}
232
- autosize={{ minRows: 5, maxRows: 5 }}
233
- errorMessage={
234
- templateMessageError && (
235
- <CapError className="inapp-template-message-error">
236
- {templateMessageError}
237
- </CapError>
238
- )
239
- }
225
+ <TextArea
226
+ id="inapp-create-template-message-input"
227
+ className="inapp-create-template-message-input"
228
+ placeholder={formatMessage(messages.textAreaInputPlaceholder)}
229
+ onChange={onTemplateMessageChange}
230
+ value={templateMessage || ""}
231
+ autosize={{ minRows: 5, maxRows: 5 }}
232
+ errorMessage={
233
+ templateMessageError && (
234
+ <CapError className="inapp-template-message-error">
235
+ {templateMessageError}
236
+ </CapError>
237
+ )
238
+ }
239
+ />
240
+ {!isAiContentBotDisabled && (
241
+ <CapAskAira.ContentGenerationBot
242
+ text={templateMessage || ""}
243
+ setText={(text) => {
244
+ onTemplateMessageChange({ target: { value: text } });
245
+ }}
246
+ iconPlacement="float-br"
247
+ iconSize="1.6rem"
248
+ rootStyle={{
249
+ bottom: "0.2rem",
250
+ right: "0.2rem",
251
+ left: "auto",
252
+ position: "absolute",
253
+ }}
240
254
  />
241
- {!isAiContentBotDisabled && (
242
- <CapAskAira.ContentGenerationBot
243
- text={templateMessage || ""}
244
- setText={(text) => {
245
- onTemplateMessageChange({ target: { value: text } });
246
- }}
247
- iconPlacement="float-br"
248
- iconSize="1.6rem"
249
- rootStyle={{
250
- bottom: "0.2rem",
251
- right: "0.2rem",
252
- left: "auto",
253
- position: "absolute",
254
- }}
255
- />
256
- )}
255
+ )}
257
256
  </div>
258
257
  {isMediaTypeImage && (
259
258
  <>
@@ -280,16 +279,14 @@ const CapDeviceContent = (props) => {
280
279
  </CapRow>
281
280
  </CapRow>
282
281
  <CapRow className="inapp-action-link">
283
- <CapCheckbox onChange={onActionLinkCheckBoxChange} checked={addActionLink} />
282
+ <CapCheckbox onChange={onActionLinkCheckBoxChange} checked={addActionLink}/>
284
283
  <CapRow className="inapp-render-heading">
285
284
  <CapHeader
286
- title={(
287
- <CapRow type="flex">
288
- <CapHeading type="h4">
289
- {formatMessage(messages.addActionLink)}
290
- </CapHeading>
291
- </CapRow>
292
- )}
285
+ title={<CapRow type="flex">
286
+ <CapHeading type="h4">
287
+ {formatMessage(messages.addActionLink)}
288
+ </CapHeading>
289
+ </CapRow>}
293
290
  description={<CapLabel type="label3">{formatMessage(messages.addActionLinkDesc)}</CapLabel>}
294
291
  />
295
292
  {addActionLink && (
@@ -313,21 +310,19 @@ const CapDeviceContent = (props) => {
313
310
  <CapRow className="inapp-cta-button">
314
311
  <CapHeader
315
312
  className="inapp-render-heading-cta-button"
316
- title={(
317
- <CapRow type="flex">
318
- <CapHeading type="h4">
319
- {formatMessage(messages.btnLabel)}
320
- </CapHeading>
321
- <CapHeading
322
- type="h6"
323
- className="inapp-optional-label"
324
- >
325
- {formatMessage(messages.optional)}
326
- </CapHeading>
327
- </CapRow>
328
- )}
313
+ title={<CapRow type="flex">
314
+ <CapHeading type="h4">
315
+ {formatMessage(messages.btnLabel)}
316
+ </CapHeading>
317
+ <CapHeading
318
+ type="h6"
319
+ className="inapp-optional-label"
320
+ >
321
+ {formatMessage(messages.optional)}
322
+ </CapHeading>
323
+ </CapRow>}
329
324
  description={<CapLabel type="label3">{formatMessage(messages.btnDesc)}</CapLabel>}
330
- />
325
+ />
331
326
  <CapRadioGroup
332
327
  options={BUTTON_RADIO_OPTIONS}
333
328
  value={buttonType}
@@ -227,10 +227,6 @@ class CapTagList extends React.Component { // eslint-disable-line react/prefer-s
227
227
 
228
228
  togglePopoverVisibility = (visible) => {
229
229
  this.setState({visible});
230
- // Call onVisibleChange callback if provided (for triggering API calls when popover opens)
231
- if (this.props.onVisibleChange) {
232
- this.props.onVisibleChange(visible);
233
- }
234
230
  };
235
231
 
236
232
  renderDynamicTagFlow = () => {
@@ -472,7 +468,7 @@ class CapTagList extends React.Component { // eslint-disable-line react/prefer-s
472
468
  onVisibleChange={this.togglePopoverVisibility}
473
469
  content={contentSection}
474
470
  trigger="click"
475
- placement={this.props.popoverPlacement || (channel === EMAIL.toUpperCase() ? "leftTop" : "rightTop")}
471
+ placement={channel === EMAIL.toUpperCase() ? "leftTop" : "rightTop"}
476
472
  >
477
473
  <CapTooltip
478
474
  title={
@@ -539,7 +535,6 @@ CapTagList.propTypes = {
539
535
  channel: PropTypes.string,
540
536
  disabled: PropTypes.bool,
541
537
  fetchingSchemaError: PropTypes.bool,
542
- popoverPlacement: PropTypes.string,
543
538
  };
544
539
 
545
540
  CapTagList.defaultValue = {