@capillarytech/creatives-library 8.0.353-alpha.6 → 8.0.354

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 (127) hide show
  1. package/constants/unified.js +0 -29
  2. package/index.html +1 -0
  3. package/package.json +1 -1
  4. package/services/tests/api.test.js +20 -35
  5. package/utils/cdnTransformation.js +63 -3
  6. package/utils/commonUtils.js +1 -19
  7. package/utils/tests/cdnTransformation.test.js +111 -0
  8. package/v2Components/CapActionButton/constants.js +0 -7
  9. package/v2Components/CapActionButton/index.js +108 -166
  10. package/v2Components/CapActionButton/index.scss +6 -157
  11. package/v2Components/CapActionButton/messages.js +3 -19
  12. package/v2Components/CapActionButton/tests/index.test.js +17 -41
  13. package/v2Components/CapTagList/index.js +0 -10
  14. package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +49 -72
  15. package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +2 -8
  16. package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +21 -213
  17. package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +0 -16
  18. package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +10 -85
  19. package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +0 -30
  20. package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +11 -79
  21. package/v2Components/CommonTestAndPreview/SendTestMessage.js +5 -10
  22. package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +15 -157
  23. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +76 -346
  24. package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +4 -133
  25. package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +0 -11
  26. package/v2Components/CommonTestAndPreview/constants.js +2 -38
  27. package/v2Components/CommonTestAndPreview/index.js +186 -691
  28. package/v2Components/CommonTestAndPreview/messages.js +3 -45
  29. package/v2Components/CommonTestAndPreview/sagas.js +6 -25
  30. package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +284 -308
  31. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +65 -231
  32. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +5 -118
  33. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +0 -341
  34. package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +1 -8
  35. package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +13 -34
  36. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +283 -281
  37. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +1 -199
  38. package/v2Components/CommonTestAndPreview/tests/index.test.js +4 -132
  39. package/v2Components/CommonTestAndPreview/tests/sagas.test.js +26 -36
  40. package/v2Components/FormBuilder/index.js +6 -11
  41. package/v2Components/TemplatePreview/_templatePreview.scss +23 -38
  42. package/v2Components/TemplatePreview/index.js +31 -143
  43. package/v2Components/TemplatePreview/tests/index.test.js +0 -142
  44. package/v2Components/TestAndPreviewSlidebox/index.js +1 -13
  45. package/v2Components/TestAndPreviewSlidebox/sagas.js +4 -11
  46. package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +1 -3
  47. package/v2Containers/CreativesContainer/SlideBoxContent.js +4 -36
  48. package/v2Containers/CreativesContainer/SlideBoxFooter.js +1 -10
  49. package/v2Containers/CreativesContainer/SlideBoxHeader.js +4 -29
  50. package/v2Containers/CreativesContainer/constants.js +0 -9
  51. package/v2Containers/CreativesContainer/index.js +103 -322
  52. package/v2Containers/CreativesContainer/index.scss +1 -51
  53. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +34 -78
  54. package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +16 -79
  55. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -8
  56. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +98 -357
  57. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +15 -20
  58. package/v2Containers/CreativesContainer/tests/index.test.js +9 -71
  59. package/v2Containers/MobilePush/Create/test/saga.test.js +2 -2
  60. package/v2Containers/Rcs/constants.js +10 -119
  61. package/v2Containers/Rcs/index.js +818 -2450
  62. package/v2Containers/Rcs/index.scss +8 -280
  63. package/v2Containers/Rcs/messages.js +3 -34
  64. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +70073 -98018
  65. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +5 -0
  66. package/v2Containers/Rcs/tests/index.test.js +121 -152
  67. package/v2Containers/Rcs/tests/mockData.js +0 -38
  68. package/v2Containers/Rcs/tests/utils.test.js +30 -646
  69. package/v2Containers/Rcs/utils.js +11 -478
  70. package/v2Containers/Sms/Create/index.js +40 -106
  71. package/v2Containers/SmsTrai/Create/index.js +4 -9
  72. package/v2Containers/SmsTrai/Edit/constants.js +0 -2
  73. package/v2Containers/SmsTrai/Edit/index.js +130 -640
  74. package/v2Containers/SmsTrai/Edit/messages.js +4 -14
  75. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2296 -4249
  76. package/v2Containers/SmsWrapper/index.js +8 -37
  77. package/v2Containers/TagList/index.js +0 -6
  78. package/v2Containers/Templates/_templates.scss +9 -166
  79. package/v2Containers/Templates/actions.js +0 -11
  80. package/v2Containers/Templates/constants.js +0 -2
  81. package/v2Containers/Templates/index.js +52 -120
  82. package/v2Containers/Templates/sagas.js +18 -57
  83. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1017 -1062
  84. package/v2Containers/Templates/tests/sagas.test.js +39 -205
  85. package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -72
  86. package/v2Containers/TemplatesV2/index.js +23 -86
  87. package/v2Containers/WeChat/MapTemplates/test/saga.test.js +9 -9
  88. package/v2Containers/Whatsapp/index.js +20 -3
  89. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +34 -578
  90. package/utils/rcsPayloadUtils.js +0 -92
  91. package/utils/templateVarUtils.js +0 -201
  92. package/utils/tests/rcsPayloadUtils.test.js +0 -226
  93. package/utils/tests/templateVarUtils.test.js +0 -204
  94. package/v2Components/CommonTestAndPreview/previewApiUtils.js +0 -59
  95. package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +0 -67
  96. package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +0 -91
  97. package/v2Components/SmsFallback/constants.js +0 -73
  98. package/v2Components/SmsFallback/index.js +0 -956
  99. package/v2Components/SmsFallback/index.scss +0 -265
  100. package/v2Components/SmsFallback/messages.js +0 -78
  101. package/v2Components/SmsFallback/smsFallbackUtils.js +0 -119
  102. package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +0 -50
  103. package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +0 -147
  104. package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +0 -304
  105. package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +0 -223
  106. package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +0 -309
  107. package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +0 -422
  108. package/v2Components/SmsFallback/useLocalTemplateList.js +0 -92
  109. package/v2Components/TemplatePreview/constants.js +0 -2
  110. package/v2Components/VarSegmentMessageEditor/constants.js +0 -2
  111. package/v2Components/VarSegmentMessageEditor/index.js +0 -125
  112. package/v2Components/VarSegmentMessageEditor/index.scss +0 -46
  113. package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +0 -43
  114. package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +0 -79
  115. package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +0 -90
  116. package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +0 -258
  117. package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +0 -125
  118. package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +0 -225
  119. package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +0 -318
  120. package/v2Containers/Sms/smsFormDataHelpers.js +0 -67
  121. package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +0 -253
  122. package/v2Containers/SmsTrai/Edit/index.scss +0 -121
  123. package/v2Containers/Templates/TemplatesActionBar.js +0 -101
  124. package/v2Containers/Templates/tests/TemplatesActionBar.test.js +0 -120
  125. package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +0 -180
  126. package/v2Containers/Templates/utils/smsTemplatesListApi.js +0 -79
  127. package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +0 -131
@@ -122,7 +122,7 @@ import { INAPP_LAYOUT_DETAILS, INAPP_MESSAGE_LAYOUT_TYPES } from '../InApp/const
122
122
  import { ZALO_STATUS_OPTIONS, ZALO_STATUSES } from '../Zalo/constants';
123
123
  import { getWhatsappContent, getWhatsappStatus, getWhatsappCategory, getWhatsappCta, getWhatsappQuickReply, getWhatsappAutoFill, getWhatsappCarouselButtonView } from '../Whatsapp/utils';
124
124
  import { getRCSContent } from '../Rcs/utils';
125
- import { RCS_STATUSES, HOST_INFOBIP } from '../Rcs/constants';
125
+ import {RCS_STATUSES} from '../Rcs/constants';
126
126
  import zaloMessages from '../Zalo/messages';
127
127
  import rcsMessages from '../Rcs/messages';
128
128
  import inAppMessages from '../InApp/messages';
@@ -460,13 +460,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
460
460
  if (this.props.location.query.type === 'embedded') {
461
461
  this.props.actions.resetAccount();
462
462
  }
463
- // When using local templates (e.g. SMS fallback selector), do not fetch from API or we overwrite global store and break background RCS list
464
- const useLocalTemplates = get(
465
- this.props,
466
- 'localTemplatesConfig.useLocalTemplates',
467
- get(this.props, 'useLocalTemplates', false),
468
- );
469
- if (!useLocalTemplates && ['line', VIBER_CHANNEL, FACEBOOK_CHANNEL, 'sms', 'email', 'ebill'].includes((this.state.channel || '').toLowerCase())) {
463
+ if (['line', VIBER_CHANNEL, FACEBOOK_CHANNEL, 'sms', 'email', 'ebill'].includes((this.state.channel || '').toLowerCase())) {
470
464
  const queryParams = {
471
465
  // name: this.state.searchText,
472
466
  // sortBy: this.state.sortBy,
@@ -1012,16 +1006,8 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1012
1006
 
1013
1007
  componentWillUnmount() {
1014
1008
  window.removeEventListener("message", this.handleFrameTasks);
1015
- // When using local templates (e.g. SMS fallback selector), do not clear global store or background RCS list is wiped
1016
- const useLocalTemplates = get(
1017
- this.props,
1018
- 'localTemplatesConfig.useLocalTemplates',
1019
- get(this.props, 'useLocalTemplates', false),
1020
- );
1021
- if (!useLocalTemplates) {
1022
- this.props.actions.resetTemplateStoreData();
1023
- this.props.globalActions.clearMetaEntities();
1024
- }
1009
+ this.props.actions.resetTemplateStoreData();
1010
+ this.props.globalActions.clearMetaEntities();
1025
1011
  // Clear any pending timeouts to prevent memory leaks
1026
1012
  if (this._clearEditTimeout) {
1027
1013
  clearTimeout(this._clearEditTimeout);
@@ -1811,20 +1797,12 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
1811
1797
  }
1812
1798
 
1813
1799
  filterRcsTemplates = (templates) => {
1814
- const selectedRcsAccountName = this.props?.Templates?.selectedRcsAccount?.name || '';
1815
- const hostName = this.state?.hostName;
1816
- let nextTemplates = templates || [];
1817
- if (selectedRcsAccountName) {
1818
- nextTemplates = nextTemplates.filter(
1819
- (t) => get(t, 'versions.base.content.RCS.rcsContent.accountName', '') === selectedRcsAccountName
1820
- );
1800
+ let { selectedRcsStatus } = this.state;
1801
+ selectedRcsStatus = !this.props.isFullMode ? RCS_STATUSES.approved : '';
1802
+ if (selectedRcsStatus) {
1803
+ return templates?.filter((template) => template?.versions?.base?.content?.RCS?.rcsContent?.cardContent?.[0]?.Status === selectedRcsStatus);
1821
1804
  }
1822
- if (!this.props.isFullMode && hostName !== HOST_INFOBIP) {
1823
- return nextTemplates.filter(
1824
- (t) => get(t, 'versions.base.content.RCS.rcsContent.cardContent[0].Status', 'unavailable') === RCS_STATUSES.approved
1825
- );
1826
- }
1827
- return nextTemplates;
1805
+ return templates;
1828
1806
  }
1829
1807
 
1830
1808
  filterZaloTemplates = (templates) => {
@@ -2014,7 +1992,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2014
1992
  style={{ marginRight: "16px" }}
2015
1993
  type="eye"
2016
1994
  onClick={() => {
2017
- if (!this.props.isFullMode || this.props.isDltFromRcs || this.props.isSmsFallbackFromRcs) {
1995
+ if (!this.props.isFullMode || this.props.isDltFromRcs) {
2018
1996
  if (!get(template, "versions.base.content.zalo.previewUrl", "")) {
2019
1997
  this.setState({ zaloPreviewItemId: template?._id });
2020
1998
  }
@@ -2496,14 +2474,13 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
2496
2474
  <CapRow type="flex" align="middle">
2497
2475
  {isCardArchiveEligible && this.renderCardSelectionCheckbox({ templateId: template._id, selectedIds: selectedIdsArrayForCard, isDisabled: isAnyArchiveInProgress })}
2498
2476
  <CapLabel className="whatsapp-rcs-template-name">{name}</CapLabel>
2499
- {this.state.hostName !== HOST_INFOBIP && <CapRow type="flex" align="middle" className="rcs-status-container zalo-status-color">
2477
+ <CapRow type="flex" align="middle" className="rcs-status-container zalo-status-color">
2500
2478
  <CapStatus
2501
2479
  type={statusDisplay}
2502
- text={statusDisplay && this.props.intl.formatMessage(rcsMessages?.[`${statusDisplay}_STATUS`])}
2503
- labelType="label3"
2504
- />
2505
- </CapRow>
2506
- }
2480
+ text={statusDisplay && this.props.intl.formatMessage(rcsMessages?.[`${statusDisplay}_STATUS`])}
2481
+ labelType="label3"
2482
+ />
2483
+ </CapRow>
2507
2484
  </CapRow>
2508
2485
  );
2509
2486
 
@@ -3079,7 +3056,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
3079
3056
  let routeParams = {};
3080
3057
  const {fbAdManager} = this.props;
3081
3058
  const isLibraryMode = this.isEnabledInLibraryModule("callCreateFromProps");
3082
-
3083
3059
  if (!isLibraryMode) {
3084
3060
  timeTracker.startTimer(CHANNEL_CREATE_TRACK_MAPPING[channel]);
3085
3061
  }
@@ -3429,13 +3405,6 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
3429
3405
  this.setState({modeType});
3430
3406
  }
3431
3407
  const { _id: id } = template;
3432
- const {
3433
- localTemplatesConfig,
3434
- fbAdManager,
3435
- isDltFromRcs,
3436
- isSmsFallbackFromRcs,
3437
- onSelectTemplate,
3438
- } = this.props;
3439
3408
  const type = this.props.location.query.type;
3440
3409
  const module = this.props.location.query.module;
3441
3410
  const isLanguageSupport = (this.props.location.query.isLanguageSupport) ? this.props.location.query.isLanguageSupport : false;
@@ -3521,12 +3490,10 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
3521
3490
  }
3522
3491
  if (this.isEnabledInLibraryModule("callSelectFromProps")) {
3523
3492
  let data = id;
3524
- if (localTemplatesConfig?.useLocalTemplates) {
3525
- data = template;
3526
- } else if (fbAdManager || isDltFromRcs || isSmsFallbackFromRcs) {
3493
+ if (this.props.fbAdManager || this.props.isDltFromRcs) {
3527
3494
  data = this.selectTemplate(id);
3528
3495
  }
3529
- onSelectTemplate(data, fbAdManager);
3496
+ this.props.onSelectTemplate(data, this.props.fbAdManager);
3530
3497
  } else {
3531
3498
  timeTracker.startTimer(CHANNEL_EDIT_TRACK_MAPPING[this.state.channel.toLowerCase()]);
3532
3499
  if (this.state.channel.toLowerCase() === 'ebill') {
@@ -4485,14 +4452,9 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
4485
4452
  const isWechatEmbedded = !this.props.isFullMode && channel.toUpperCase() === WECHAT;
4486
4453
  const channelLowerCase = (channel || '').toLowerCase();
4487
4454
  const isTraiDltFeature = this.checkDLTfeatureEnable();
4455
+
4488
4456
  const createButton =
4489
- (
4490
- (
4491
- channelLowerCase === WHATSAPP_LOWERCASE
4492
- || channelLowerCase === RCS_LOWERCASE
4493
- )
4494
- && !this.props.isFullMode
4495
- )
4457
+ ( (channelLowerCase === WHATSAPP_LOWERCASE || channelLowerCase === RCS_LOWERCASE) && !this.props.isFullMode )
4496
4458
  ? (
4497
4459
  <CapLink
4498
4460
  onClick={this.openCreativesFullMode}
@@ -4524,22 +4486,17 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
4524
4486
  const _renderSelectedIdsArray = _renderSelectedIds && typeof _renderSelectedIds.toJS === 'function' ? _renderSelectedIds.toJS() : (Array.isArray(_renderSelectedIds) ? _renderSelectedIds : []);
4525
4487
  const _renderHasSelection = _isArchivalEnabled && this.props.isFullMode && _renderSelectedIdsArray.length > 0;
4526
4488
 
4527
- const useLocalTemplates = this.props.localTemplatesConfig?.useLocalTemplates;
4528
- const builtFilterContent = ((isfilterContentVisisble || [WECHAT, MOBILE_PUSH, INAPP].includes(this.state.channel.toUpperCase())) && (
4529
- <div className="action-container">
4530
- <div className="action-container__toolbar-row">
4531
- {isfilterContentVisisble ? (
4532
- <CapInput.Search
4533
- className="search-text"
4534
- placeholder={this.props.intl.formatMessage(messages.searchText)}
4535
- value={this.state.searchText}
4536
- onChange={(e) => this.searchTemplate(e.target.value, this.state.channel)}
4537
- onSearch={() => this.searchTemplate(this.state.searchText, this.state.channel)}
4538
- onClear={() => this.searchTemplate('', this.state.channel)}
4539
- onScroll={(e) => e.stopPropagation()}
4540
- disabled={this.checkSearchDisabled()}
4541
- />
4542
- ) : null}
4489
+ const filterContent = (( isfilterContentVisisble || [WECHAT, MOBILE_PUSH, INAPP].includes(this.state.channel.toUpperCase())) && <div className="action-container">
4490
+ {isfilterContentVisisble && <CapInput.Search
4491
+ className="search-text"
4492
+ style={{width: '210px'}}
4493
+ placeholder={_isArchivedMode ? this.props.intl.formatMessage(messages.searchArchivedTemplates) : this.props.intl.formatMessage(messages.searchText)}
4494
+ value={this.state.searchText}
4495
+ onChange={(e) => this.searchTemplate(e.target.value, this.state.channel)}
4496
+ disabled={this.checkSearchDisabled()}
4497
+ onClear={() => this.searchTemplate('', this.state.channel)}
4498
+ onScroll={(e) => e.stopPropagation()}
4499
+ />}
4543
4500
  {
4544
4501
  channel.toUpperCase() === WECHAT && <CapRadio.CapRadioGroup className="wechat-filters" defaultValue={wechatFilter} onChange={this.setWechatFilter}>
4545
4502
  <CapRadio.Button value={WECHAT_FILTERS.ALL}><CapLabel type="label2">
@@ -4686,6 +4643,16 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
4686
4643
  )
4687
4644
  }
4688
4645
  <div className="template-listing-header-actions">
4646
+ {!_isArchivedMode && !_renderHasSelection && (
4647
+ this.state?.channel?.toLowerCase() === WHATSAPP_LOWERCASE && (isWhatsappCountExeeded) ? (
4648
+ <CapTooltip title={whatsappCountExceedText}>
4649
+ <div className="button-disabled-tooltip-wrapper">
4650
+ {createButton}
4651
+ </div>
4652
+ </CapTooltip>
4653
+ )
4654
+ : isfilterContentVisisble && !isWechatEmbedded && !this.props.isDltFromRcs && createButton
4655
+ )}
4689
4656
  {/* More (⋯) menu: full mode only, not archived mode, not Zalo (no archive support), not when selection active, archive flag enabled */}
4690
4657
  {commonUtil.hasCreativesArchivalEnabled() && !_isArchivedMode && !_renderHasSelection && this.props.isFullMode && this.props.location.query.type !== EMBEDDED && channelLowerCase !== ZALO_LOWERCASE && (
4691
4658
  <CapDropdown
@@ -4708,28 +4675,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
4708
4675
  </CapDropdown>
4709
4676
  )}
4710
4677
  </div>
4711
- </div>
4712
- <div>
4713
- <div className="action-container__create-row">
4714
- {
4715
- isfilterContentVisisble && !isWechatEmbedded && !this.props.isDltFromRcs && !this.props.isSmsFallbackFromRcs && (
4716
- this.state?.channel?.toLowerCase() === WHATSAPP_LOWERCASE && isWhatsappCountExeeded ? (
4717
- <CapTooltip title={whatsappCountExceedText}>
4718
- <div className="button-disabled-tooltip-wrapper">
4719
- {createButton}
4720
- </div>
4721
- </CapTooltip>
4722
- ) : createButton
4723
- )
4724
- }
4725
- </div>
4726
- </div>
4727
- </div>
4728
- ));
4729
- const localTemplatesFilterContent = get(this.props, 'localTemplatesConfig.localTemplatesFilterContent', null);
4730
- const filterContent = (useLocalTemplates && localTemplatesFilterContent) != null
4731
- ? localTemplatesFilterContent
4732
- : builtFilterContent;
4678
+ </div>);
4733
4679
  let htmlPreviewContent = "";
4734
4680
  if (this.state.channel.toLowerCase() === 'ebill') {
4735
4681
  htmlPreviewContent = this.state.previewTemplate && this.state.previewTemplate.versions && this.state.previewTemplate.versions.base && this.state.previewTemplate.versions.base['ebill-editor'];
@@ -4739,10 +4685,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
4739
4685
 
4740
4686
 
4741
4687
  const creativesParams = this.getCreativesParams();
4742
- const templates = useLocalTemplates
4743
- ? (this.props.localTemplatesConfig?.localTemplates || [])
4744
- : (this.props.TemplatesList || []);
4745
- const isLoadingWhenLocal = useLocalTemplates && !!this.props.localTemplatesConfig?.localTemplatesLoading;
4688
+ const templates = this.props.TemplatesList || [];
4746
4689
  const {route} = this.props;
4747
4690
  const loadingTipMap = {
4748
4691
  sendingFile: 'uploadingFile',
@@ -4757,11 +4700,9 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
4757
4700
  (deleteRcsTemplateInProgress && 'deletingTemplate') ||
4758
4701
  (this.props.EmailCreate.duplicateTemplateInProgress && 'duplicatingTemplate');
4759
4702
 
4760
- const loadingTip = useLocalTemplates && this.props.localTemplatesConfig?.localTemplatesLoadingTip
4761
- ? this.props.localTemplatesConfig.localTemplatesLoadingTip
4762
- : (messages[loadingTipIntl] ? this.props.intl.formatMessage(messages[loadingTipIntl]) : this.props.intl.formatMessage(messages.gettingAllTemplates));
4703
+ const loadingTip = messages[loadingTipIntl] ? this.props.intl.formatMessage(messages[loadingTipIntl]) : this.props.intl.formatMessage(messages.gettingAllTemplates);
4763
4704
  const showNoTemplatesFoundZalo = this.state.channel.toUpperCase() === ZALO && isEmpty(this.state.searchedZaloTemplates) && this.state.searchingZaloTemplate;
4764
- const showNoTemplatesFoundOther = ![ZALO].includes(this.state.channel.toUpperCase()) && isEmpty(templates) && (useLocalTemplates ? !isLoadingWhenLocal : !this.props.Templates.getAllTemplatesInProgress) && (useLocalTemplates || !isEmpty(this.state.searchText));
4705
+ const showNoTemplatesFoundOther = ![ZALO].includes(this.state.channel.toUpperCase()) && isEmpty(this.props.TemplatesList) && !this.props.Templates.getAllTemplatesInProgress && !isEmpty(this.state.searchText);
4765
4706
  const showNoTemplatesFound = showNoTemplatesFoundZalo || showNoTemplatesFoundOther;
4766
4707
 
4767
4708
  return (
@@ -4805,7 +4746,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
4805
4746
  />
4806
4747
  ) : null}
4807
4748
 
4808
- {channel.toLowerCase() === RCS_LOWERCASE && !isFullMode && this.state?.hostName !== HOST_INFOBIP ? (
4749
+ {channel.toLowerCase() === RCS_LOWERCASE && !isFullMode ? (
4809
4750
  <CapInfoNote
4810
4751
  message={formatMessage(messages.rcsOnlyApprovedTemplates)}
4811
4752
  />
@@ -4818,22 +4759,22 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
4818
4759
  ) : null}
4819
4760
  <CapRow>
4820
4761
  <Pagination
4821
- templateInProgress={useLocalTemplates ? isLoadingWhenLocal : this.props.Templates.getAllTemplatesInProgress}
4762
+ templateInProgress={
4763
+ this.props.Templates.getAllTemplatesInProgress
4764
+ }
4822
4765
  onPageChange={
4823
- templates.length
4824
- ? (useLocalTemplates ? (this.props.localTemplatesConfig?.localTemplatesOnPageChange || (() => {})) : this.onPaginationChange)
4825
- : () => {}
4766
+ templates.length ? this.onPaginationChange : () => {}
4826
4767
  }
4827
4768
  >
4828
4769
  {this.getTemplateDataForGrid({
4829
4770
  previewTemplateId: this.state.zaloPreviewItemId,
4830
- isLoading: useLocalTemplates ? isLoadingWhenLocal : isLoading,
4831
- isInitialLoading: useLocalTemplates ? isLoadingWhenLocal && templates.length === 0 : isInitialLoading,
4771
+ isLoading,
4772
+ isInitialLoading,
4832
4773
  loadingTip,
4833
4774
  channel: this.state.channel,
4834
4775
  templates: this.state.searchingZaloTemplate
4835
4776
  ? this.state.searchedZaloTemplates
4836
- : templates,
4777
+ : this.props.TemplatesList,
4837
4778
  filterContent,
4838
4779
  handlers: {
4839
4780
  handlePreviewClick: this.handlePreviewClick,
@@ -5016,15 +4957,6 @@ Templates.propTypes = {
5016
4957
  WebPush: PropTypes.object,
5017
4958
  smsRegister: PropTypes.any,
5018
4959
  isDltFromRcs: PropTypes.bool,
5019
- isSmsFallbackFromRcs: PropTypes.bool,
5020
- localTemplatesConfig: PropTypes.shape({
5021
- useLocalTemplates: PropTypes.bool,
5022
- localTemplates: PropTypes.arrayOf(PropTypes.object),
5023
- localTemplatesLoading: PropTypes.bool,
5024
- localTemplatesLoadingTip: PropTypes.string,
5025
- localTemplatesFilterContent: PropTypes.node,
5026
- localTemplatesOnPageChange: PropTypes.func,
5027
- }),
5028
4960
  };
5029
4961
 
5030
4962
  const mapStateToProps = createStructuredSelector({
@@ -1,76 +1,39 @@
1
1
  import {
2
- call, put, takeLatest, takeEvery, all,
2
+ call, put, takeLatest, all,
3
3
  } from 'redux-saga/effects';
4
4
  import get from 'lodash/get';
5
5
  import { CapNotification } from '@capillarytech/cap-ui-library';
6
6
  // import { schema, normalize } from 'normalizr';
7
7
  import * as Api from '../../services/api';
8
8
  import * as types from './constants';
9
- import { saveCdnConfigs, removeAllCdnLocalStorageItems } from '../../utils/cdnTransformation';
9
+ import { saveCdnConfigs, removeAllCdnLocalStorageItems, initCdnConfigFromEnv } from '../../utils/cdnTransformation';
10
10
  import { COPY_OF } from '../../constants/unified';
11
- import { fetchSmsTemplatesFromQuery } from './utils/smsTemplatesListApi';
12
11
  import { ZALO_TEMPLATE_INFO_REQUEST } from '../Zalo/constants';
13
12
  import { getTemplateInfoById } from '../Zalo/saga';
14
13
 
15
- export function* getLocalSmsTemplates(action) {
14
+ // Individual exports for testing
15
+ export function* getAllTemplates(channel, queryParams) {
16
16
  try {
17
- const fetched = yield call(
18
- fetchSmsTemplatesFromQuery,
19
- action.queryParams,
20
- action.intlCopyOf,
21
- );
22
- if (typeof action.onSuccess === 'function') {
23
- yield call(action.onSuccess, fetched);
24
- }
25
- } catch (error) {
26
- if (typeof action.onFailure === 'function') {
27
- yield call(action.onFailure, error);
28
- }
29
- }
30
- }
31
-
32
- export function* getAllTemplates(action) {
33
- try {
34
- if (action.channel && String(action.channel).toLowerCase() === 'sms') {
35
- const fetched = yield call(
36
- fetchSmsTemplatesFromQuery,
37
- action.queryParams,
38
- action.intlCopyOf,
39
- );
40
- yield put({
41
- type: types.GET_ALL_TEMPLATES_SUCCESS,
42
- data: fetched.channelTemplates,
43
- weCRMTemplate: fetched.weCRMTemplate,
44
- isReset: get(action, 'queryParams.page') === 1,
45
- });
46
- return;
47
- }
48
-
49
- const result = yield call(Api.getAllTemplates, action);
50
- const channelTemplates = (action.channel === 'wechat')
51
- ? { templates: [...result.response.mapped, ...result.response.richmedia] }
52
- : result.response;
53
- if (action.channel === 'wechat' && action.queryParams && action.queryParams.sortBy && action.queryParams.sortBy.toLocaleLowerCase() === ("Most Recent").toLocaleLowerCase()) {
17
+ const result = yield call(Api.getAllTemplates, channel, queryParams);
18
+ const channelTemplates = (channel.channel === 'wechat') ? { templates: [...result.response.mapped, ...result.response.richmedia] } : result.response;
19
+ // const sidebar = result.response.sidebar;
20
+ if (channel.channel === 'wechat' && channel.queryParams && channel.queryParams.sortBy && channel.queryParams.sortBy.toLocaleLowerCase() === ("Most Recent").toLocaleLowerCase()) {
54
21
  channelTemplates.templates.sort((a, b) => {
55
22
  const dateA = new Date(a.updatedAt);
56
23
  const dateB = new Date(b.updatedAt);
57
24
  return dateB - dateA;
58
25
  });
59
- } else if (action.channel === 'wechat' && action.queryParams && action.queryParams.sortBy && action.queryParams.sortBy.toLocaleLowerCase() === ("Alphabetically").toLocaleLowerCase()) {
26
+ } else if (channel.channel === 'wechat' && channel.queryParams && channel.queryParams.sortBy && channel.queryParams.sortBy.toLocaleLowerCase() === ("Alphabetically").toLocaleLowerCase()) {
60
27
  channelTemplates.templates.sort((a, b) => b.name - a.name);
61
28
  }
62
- if (action.intlCopyOf && channelTemplates?.templates) {
29
+ // Update the "name" property in each template
30
+ if (channel.intlCopyOf && channelTemplates?.templates) {
63
31
  channelTemplates.templates = channelTemplates.templates.map((template) => ({
64
32
  ...template,
65
- name: template.name.replace(new RegExp(COPY_OF, 'g'), action.intlCopyOf),
33
+ name: template.name.replace(new RegExp(COPY_OF, 'g'), channel.intlCopyOf),
66
34
  }));
67
35
  }
68
- yield put({
69
- type: types.GET_ALL_TEMPLATES_SUCCESS,
70
- data: channelTemplates,
71
- weCRMTemplate: result.response.unMapped,
72
- isReset: get(action, 'queryParams.page') === 1,
73
- });
36
+ yield put({ type: types.GET_ALL_TEMPLATES_SUCCESS, data: channelTemplates, weCRMTemplate: result.response.unMapped, isReset: channel.queryParams.page === 1 });
74
37
  } catch (error) {
75
38
  yield put({ type: types.GET_ALL_TEMPLATES_FAILURE, error });
76
39
  }
@@ -144,6 +107,11 @@ export function* getOrgLevelCampaignSettings() {
144
107
 
145
108
  export function* getCdnTransformationConfig() {
146
109
  try {
110
+ // VAPT CAP-183204: prefer env vars injected via window.APP_ENV — avoids the
111
+ // API response that leaked CDN/S3 infrastructure details. Fallback to API
112
+ // keeps clusters that haven't received the env vars yet working during rollout.
113
+ if (initCdnConfigFromEnv()) return;
114
+
147
115
  const res = yield call(Api.getCdnTransformationConfig);
148
116
  if (res?.success && res?.status?.code === 200) {
149
117
  const cdnConfigs = res?.response;
@@ -302,11 +270,6 @@ export function* watchGetAllTemplates() {
302
270
  yield takeLatest(types.GET_ALL_TEMPLATES_REQUEST, getAllTemplates);
303
271
  }
304
272
 
305
-
306
- export function* watchGetLocalSmsTemplates() {
307
- yield takeEvery(types.GET_LOCAL_SMS_TEMPLATES_REQUEST, getLocalSmsTemplates);
308
- }
309
-
310
273
  export function* watchDeleteTemplate() {
311
274
  yield takeLatest(types.DELETE_TEMPLATE_REQUEST, deleteTemplate);
312
275
  }
@@ -360,7 +323,6 @@ export function* watchForGetTemplateInfoById() {
360
323
  // All sagas to be loaded
361
324
  export default [
362
325
  watchGetAllTemplates,
363
- watchGetLocalSmsTemplates,
364
326
  watchDeleteTemplate,
365
327
  watchDeleteRcsTemplate,
366
328
  watchGetUserList,
@@ -377,7 +339,6 @@ export default [
377
339
  export function* v2TemplateSaga() {
378
340
  yield all([
379
341
  watchGetAllTemplates(),
380
- watchGetLocalSmsTemplates(),
381
342
  watchDeleteTemplate(),
382
343
  watchDeleteRcsTemplate(),
383
344
  watchGetUserList(),