@capillarytech/creatives-library 9.0.26 → 9.0.29-alpha.1

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 (149) hide show
  1. package/constants/unified.js +29 -0
  2. package/global-styles.js +1 -1
  3. package/package.json +1 -1
  4. package/services/tests/api.test.js +35 -20
  5. package/utils/commonUtils.js +22 -1
  6. package/utils/rcsPayloadUtils.js +102 -0
  7. package/utils/templateVarUtils.js +198 -0
  8. package/utils/tests/rcsPayloadUtils.test.js +295 -0
  9. package/utils/tests/templateVarUtils.test.js +204 -0
  10. package/v2Components/CapActionButton/constants.js +21 -1
  11. package/v2Components/CapActionButton/index.js +260 -144
  12. package/v2Components/CapActionButton/index.scss +245 -14
  13. package/v2Components/CapActionButton/messages.js +32 -3
  14. package/v2Components/CapActionButton/tests/index.test.js +74 -19
  15. package/v2Components/CapImageUpload/index.js +2 -2
  16. package/v2Components/CapTagList/index.js +9 -0
  17. package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +70 -48
  18. package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +8 -2
  19. package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +214 -21
  20. package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +16 -0
  21. package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +83 -9
  22. package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +30 -0
  23. package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +58 -11
  24. package/v2Components/CommonTestAndPreview/SendTestMessage.js +10 -5
  25. package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +186 -22
  26. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +381 -80
  27. package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +155 -8
  28. package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +11 -0
  29. package/v2Components/CommonTestAndPreview/constants.js +35 -2
  30. package/v2Components/CommonTestAndPreview/index.js +770 -231
  31. package/v2Components/CommonTestAndPreview/messages.js +45 -3
  32. package/v2Components/CommonTestAndPreview/previewApiUtils.js +59 -0
  33. package/v2Components/CommonTestAndPreview/sagas.js +25 -6
  34. package/v2Components/CommonTestAndPreview/tests/CommonTestAndPreview.addTestCustomer.test.js +1 -0
  35. package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +412 -257
  36. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +337 -63
  37. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +118 -5
  38. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +341 -0
  39. package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +8 -1
  40. package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +108 -15
  41. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +281 -283
  42. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +199 -1
  43. package/v2Components/CommonTestAndPreview/tests/index.test.js +133 -4
  44. package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +67 -0
  45. package/v2Components/CommonTestAndPreview/tests/sagas.test.js +31 -24
  46. package/v2Components/CommonTestAndPreview/tests/utils.test.js +151 -0
  47. package/v2Components/CommonTestAndPreview/utils.js +84 -0
  48. package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +91 -0
  49. package/v2Components/SmsFallback/constants.js +94 -0
  50. package/v2Components/SmsFallback/index.js +958 -0
  51. package/v2Components/SmsFallback/index.scss +266 -0
  52. package/v2Components/SmsFallback/messages.js +78 -0
  53. package/v2Components/SmsFallback/smsFallbackUtils.js +120 -0
  54. package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +50 -0
  55. package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +147 -0
  56. package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +304 -0
  57. package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +208 -0
  58. package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +309 -0
  59. package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +471 -0
  60. package/v2Components/SmsFallback/useLocalTemplateList.js +92 -0
  61. package/v2Components/TemplatePreview/_templatePreview.scss +45 -25
  62. package/v2Components/TemplatePreview/constants.js +2 -0
  63. package/v2Components/TemplatePreview/index.js +147 -32
  64. package/v2Components/TemplatePreview/tests/index.test.js +142 -0
  65. package/v2Components/TestAndPreviewSlidebox/CustomValuesEditor.js +6 -6
  66. package/v2Components/TestAndPreviewSlidebox/index.js +13 -1
  67. package/v2Components/TestAndPreviewSlidebox/sagas.js +11 -4
  68. package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +3 -1
  69. package/v2Components/VarSegmentMessageEditor/constants.js +2 -0
  70. package/v2Components/VarSegmentMessageEditor/index.js +125 -0
  71. package/v2Components/VarSegmentMessageEditor/index.scss +46 -0
  72. package/v2Containers/CommunicationFlow/Tests/CommunicationFlow.test.js +4 -1
  73. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/DeliverySettingsSection.test.js +4 -0
  74. package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js +20 -20
  75. package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +27 -0
  76. package/v2Containers/CreativesContainer/SlideBoxContent.js +37 -4
  77. package/v2Containers/CreativesContainer/SlideBoxFooter.js +14 -5
  78. package/v2Containers/CreativesContainer/SlideBoxHeader.js +36 -5
  79. package/v2Containers/CreativesContainer/constants.js +11 -0
  80. package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +77 -0
  81. package/v2Containers/CreativesContainer/index.js +328 -106
  82. package/v2Containers/CreativesContainer/index.scss +102 -1
  83. package/v2Containers/CreativesContainer/tests/CreativesSlideBoxWrapper.test.js +58 -0
  84. package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +90 -0
  85. package/v2Containers/CreativesContainer/tests/SlideBoxContent.smsDltPreview.test.js +73 -0
  86. package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +37 -0
  87. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +103 -34
  88. package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +193 -15
  89. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +88 -0
  90. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +549 -57
  91. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +20 -15
  92. package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +258 -0
  93. package/v2Containers/CreativesContainer/tests/index.test.js +71 -9
  94. package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +125 -0
  95. package/v2Containers/Email/index.js +3 -54
  96. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +4 -9
  97. package/v2Containers/MobilePush/Create/test/saga.test.js +2 -2
  98. package/v2Containers/Rcs/carouselUtils.js +224 -0
  99. package/v2Containers/Rcs/components/CarouselCard.js +317 -0
  100. package/v2Containers/Rcs/components/CarouselCardButtons.js +113 -0
  101. package/v2Containers/Rcs/components/CarouselCardMedia.js +136 -0
  102. package/v2Containers/Rcs/components/CarouselCharacterCount.js +31 -0
  103. package/v2Containers/Rcs/components/CarouselDimensionSelection.js +80 -0
  104. package/v2Containers/Rcs/constants.js +132 -16
  105. package/v2Containers/Rcs/index.js +1808 -949
  106. package/v2Containers/Rcs/index.scss +443 -8
  107. package/v2Containers/Rcs/messages.js +45 -22
  108. package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +484 -0
  109. package/v2Containers/Rcs/tests/CarouselCard.test.js +464 -0
  110. package/v2Containers/Rcs/tests/CarouselCardButtons.test.js +211 -0
  111. package/v2Containers/Rcs/tests/CarouselCardMedia.test.js +160 -0
  112. package/v2Containers/Rcs/tests/CarouselCharacterCount.test.js +50 -0
  113. package/v2Containers/Rcs/tests/CarouselDimensionSelection.test.js +119 -0
  114. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +74176 -39409
  115. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +10 -74
  116. package/v2Containers/Rcs/tests/carouselUtils.test.js +916 -0
  117. package/v2Containers/Rcs/tests/index.test.js +219 -40
  118. package/v2Containers/Rcs/tests/mockData.js +38 -0
  119. package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +873 -0
  120. package/v2Containers/Rcs/tests/utils.test.js +682 -30
  121. package/v2Containers/Rcs/utils.js +514 -12
  122. package/v2Containers/Sms/Create/index.js +115 -48
  123. package/v2Containers/Sms/smsFormDataHelpers.js +67 -0
  124. package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +253 -0
  125. package/v2Containers/SmsTrai/Create/index.js +9 -4
  126. package/v2Containers/SmsTrai/Edit/constants.js +2 -0
  127. package/v2Containers/SmsTrai/Edit/index.js +678 -169
  128. package/v2Containers/SmsTrai/Edit/index.scss +126 -0
  129. package/v2Containers/SmsTrai/Edit/messages.js +14 -4
  130. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +5615 -3014
  131. package/v2Containers/SmsWrapper/index.js +37 -8
  132. package/v2Containers/TagList/index.js +5 -0
  133. package/v2Containers/Templates/TemplatesActionBar.js +101 -0
  134. package/v2Containers/Templates/_templates.scss +196 -12
  135. package/v2Containers/Templates/actions.js +11 -0
  136. package/v2Containers/Templates/constants.js +2 -0
  137. package/v2Containers/Templates/index.js +131 -59
  138. package/v2Containers/Templates/sagas.js +57 -13
  139. package/v2Containers/Templates/tests/TemplatesActionBar.test.js +129 -0
  140. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1060 -1015
  141. package/v2Containers/Templates/tests/sagas.test.js +199 -16
  142. package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +180 -0
  143. package/v2Containers/Templates/utils/smsTemplatesListApi.js +79 -0
  144. package/v2Containers/TemplatesV2/TemplatesV2.style.js +72 -1
  145. package/v2Containers/TemplatesV2/index.js +88 -25
  146. package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +131 -0
  147. package/v2Containers/WeChat/MapTemplates/test/saga.test.js +9 -9
  148. package/v2Containers/Whatsapp/index.js +3 -20
  149. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +578 -34
@@ -10,12 +10,14 @@ import { isTraiDLTEnable } from '../../utils/common';
10
10
  import SmsEdit from '../Sms/Edit';
11
11
  import SmsTraiCreate from '../SmsTrai/Create';
12
12
  import SmsTraiEdit from '../SmsTrai/Edit';
13
+
13
14
  const SmsWrapper = (props) => {
14
15
  const {
15
16
  isCreateSms,
16
17
  isEditSms,
17
18
  setIsLoadingContent,
18
19
  location,
20
+ route: routeFromProps,
19
21
  isGetFormData,
20
22
  getFormSubscriptionData,
21
23
  isFullMode,
@@ -38,15 +40,33 @@ const SmsWrapper = (props) => {
38
40
  handleCloseTestAndPreview,
39
41
  isTestAndPreviewMode,
40
42
  onValidationFail,
43
+ embeddedSmsFallback = false,
44
+ onEmbeddedSmsFooterValidity,
45
+ forceFullTagContext = false,
41
46
  } = props;
42
47
 
48
+ /** FormBuilder / SMS Create assume `location.query`; connected-router shapes may omit it. */
49
+ const smsLocation = (() => {
50
+ const loc = location || {};
51
+ const query = loc.query;
52
+ if (query && typeof query === 'object') {
53
+ return { ...loc, query: { ...query } };
54
+ }
55
+ return {
56
+ pathname: loc.pathname || '/sms/create',
57
+ search: loc.search || '',
58
+ query: { type: 'embedded', module: 'library' },
59
+ };
60
+ })();
61
+
43
62
  const smsProps = {
44
63
  onCreateComplete,
45
64
  setIsLoadingContent,
46
- location,
47
- route: { name: 'sms' },
65
+ location: smsLocation,
66
+ route: routeFromProps || { name: 'sms' },
48
67
  isGetFormData,
49
68
  getFormSubscriptionData,
69
+ templateData,
50
70
  getDefaultTags,
51
71
  isFullMode,
52
72
  forwardedTags,
@@ -62,24 +82,33 @@ const SmsWrapper = (props) => {
62
82
  handleCloseTestAndPreview,
63
83
  isTestAndPreviewMode,
64
84
  onValidationFail,
85
+ forceFullTagContext,
86
+ embeddedSmsFallback,
87
+ onEmbeddedSmsFooterValidity,
88
+ ...(embeddedSmsFallback
89
+ ? {
90
+ tagListGetPopupContainer: () => document.body,
91
+ tagListPopoverOverlayStyle: { zIndex: 10020 },
92
+ tagListPopoverOverlayClassName: 'sms-fallback-taglist-popover rcs-sms-fallback-taglist-popover',
93
+ }
94
+ : {}),
65
95
  };
66
- const isTraiDlt = isTraiDLTEnable(isFullMode, smsRegister);
96
+ const useTraiSmsFlow = isTraiDLTEnable(isFullMode, smsRegister);
67
97
  return <>
68
98
  {
69
- isCreateSms && (isTraiDlt ?
99
+ isCreateSms && (useTraiSmsFlow ?
70
100
  <SmsTraiCreate
71
101
  isComponent
72
102
  {...smsProps}
73
103
  onShowTemplates={onShowTemplates}
74
104
  /> :
75
105
  <SmsCreate
76
- isComponent {
77
- ...smsProps
78
- }
106
+ isComponent
107
+ {...smsProps}
79
108
  />
80
109
  )
81
110
  }
82
- {isEditSms && (isTraiDlt ?
111
+ {isEditSms && (useTraiSmsFlow ?
83
112
  <SmsTraiEdit
84
113
  {...smsProps}
85
114
  params={{id: templateData._id}}
@@ -477,6 +477,8 @@ export class TagList extends React.Component { // eslint-disable-line react/pref
477
477
  disableTooltipMsg={tooltipMsg}
478
478
  fetchingSchemaError={this?.state?.tagsError}
479
479
  popoverPlacement={this.props.popoverPlacement}
480
+ overlayStyle={this.props.popoverOverlayStyle}
481
+ overlayClassName={this.props.popoverOverlayClassName}
480
482
  getPopupContainer={this.props.getPopupContainer}
481
483
  />
482
484
  </div>
@@ -514,6 +516,9 @@ TagList.propTypes = {
514
516
  // message to show when Add Label button is disabled (e.g. personalization restriction)
515
517
  disableTooltipMsg: PropTypes.string,
516
518
  restrictPersonalization: PropTypes.bool,
519
+ popoverOverlayStyle: PropTypes.object,
520
+ popoverOverlayClassName: PropTypes.string,
521
+ getPopupContainer: PropTypes.func,
517
522
  intl: PropTypes.shape({
518
523
  formatMessage: PropTypes.func.isRequired,
519
524
  locale: PropTypes.string,
@@ -0,0 +1,101 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import CapInput from '@capillarytech/cap-ui-library/CapInput';
4
+ import CapButton from '@capillarytech/cap-ui-library/CapButton';
5
+
6
+ /**
7
+ * Reusable action bar for template pickers.
8
+ * Layout and spacing live in `_templates.scss` (`.action-container`, `.action-container__toolbar-row`).
9
+ * Default search field width: `.action-container__toolbar-row .search-text` (13.125rem).
10
+ * Pass `searchInputClassName` / `searchInputStyle` to override (defaults match Templates list: 210px per master).
11
+ */
12
+ const TemplatesActionBar = ({
13
+ searchValue,
14
+ onSearchChange,
15
+ onSearch,
16
+ onClear,
17
+ searchPlaceholder,
18
+ searchInputClassName,
19
+ searchInputStyle,
20
+ ctaLabel,
21
+ onCtaClick,
22
+ ctaDisabled,
23
+ ctaClassName,
24
+ ctaNode,
25
+ children,
26
+ showCta = true,
27
+ }) => (
28
+ <div className="action-container">
29
+ <div className="action-container__toolbar-row">
30
+ {searchPlaceholder && (
31
+ <CapInput.Search
32
+ className={['search-text', searchInputClassName].filter(Boolean).join(' ')}
33
+ placeholder={searchPlaceholder}
34
+ value={searchValue}
35
+ onChange={onSearchChange}
36
+ /* antd `Input` (used by CapInput.Search) has no `onSearch`; only `Input.Search` does. */
37
+ onPressEnter={(e) => {
38
+ if (onSearch) {
39
+ const value = e?.target && 'value' in e.target ? e.target.value : searchValue;
40
+ onSearch(value);
41
+ }
42
+ }}
43
+ onSearch={onSearch}
44
+ onClear={onClear}
45
+ onScroll={(e) => e.stopPropagation()}
46
+ />
47
+ )}
48
+ {children}
49
+ </div>
50
+ {showCta && (
51
+ <div>
52
+ {ctaNode || (
53
+ <CapButton
54
+ className={ctaClassName}
55
+ type="primary"
56
+ disabled={ctaDisabled}
57
+ onClick={onCtaClick}
58
+ >
59
+ {ctaLabel}
60
+ </CapButton>
61
+ )}
62
+ </div>
63
+ )}
64
+ </div>
65
+ );
66
+
67
+ TemplatesActionBar.propTypes = {
68
+ searchValue: PropTypes.string,
69
+ onSearchChange: PropTypes.func,
70
+ onSearch: PropTypes.func,
71
+ onClear: PropTypes.func,
72
+ searchPlaceholder: PropTypes.string,
73
+ searchInputClassName: PropTypes.string,
74
+ searchInputStyle: PropTypes.object,
75
+ ctaLabel: PropTypes.node,
76
+ onCtaClick: PropTypes.func,
77
+ ctaDisabled: PropTypes.bool,
78
+ ctaClassName: PropTypes.string,
79
+ ctaNode: PropTypes.node,
80
+ children: PropTypes.node,
81
+ showCta: PropTypes.bool,
82
+ };
83
+
84
+ TemplatesActionBar.defaultProps = {
85
+ searchValue: '',
86
+ onSearchChange: () => {},
87
+ onSearch: () => {},
88
+ onClear: () => {},
89
+ searchPlaceholder: '',
90
+ searchInputClassName: '',
91
+ searchInputStyle: { width: '210px' },
92
+ ctaLabel: null,
93
+ onCtaClick: () => {},
94
+ ctaDisabled: false,
95
+ ctaClassName: '',
96
+ ctaNode: null,
97
+ children: null,
98
+ };
99
+
100
+ export default TemplatesActionBar;
101
+
@@ -1,11 +1,13 @@
1
1
  @import '~@capillarytech/cap-ui-library/styles/_variables.scss';
2
2
 
3
3
  .ant-tabs-content{
4
- margin-top: $CAP_SPACE_16;
5
- .ant-tabs-tabpane-active{
6
- padding: unset;
4
+ // .creatives-templates-list.full-mode{
5
+ .v2-pagination-container, .v2-pagination-container-half {
6
+ .ant-tabs-tabpane-active{
7
+ padding: unset;
8
+ }
7
9
  }
8
- }
10
+ }
9
11
  //removing current one as not required now in each row we'll have 3 cards for which css has been added
10
12
 
11
13
  // 3 cards per row across all breakpoints
@@ -24,6 +26,7 @@
24
26
  }
25
27
  }
26
28
 
29
+
27
30
  .creatives-templates-list {
28
31
  position: relative;
29
32
 
@@ -45,8 +48,10 @@
45
48
  .ant-modal-footer {
46
49
  padding: $CAP_SPACE_16 $CAP_SPACE_24 $CAP_SPACE_24 $CAP_SPACE_24;
47
50
  }
51
+ }
48
52
 
49
53
  .ant-modal-header {
54
+ .v2-pagination-container, .v2-pagination-container-half {
50
55
  padding: $CAP_SPACE_24 $CAP_SPACE_24 $CAP_SPACE_08 $CAP_SPACE_24;
51
56
  }
52
57
 
@@ -59,7 +64,8 @@
59
64
  }
60
65
  }
61
66
 
62
- .v2-pagination-container {
67
+ .v2-pagination-container,
68
+ .v2-pagination-container-half {
63
69
  .FACEBOOK {
64
70
  .ant-card-body {
65
71
  background-color: $CAP_G09;
@@ -192,10 +198,14 @@
192
198
  .whatsapp-container {
193
199
  background-color: $CAP_WHITE;
194
200
  padding: $CAP_SPACE_12;
201
+ overflow-y: hidden;
195
202
  }
196
203
  .scroll-container {
197
204
  overflow-x: auto;
205
+ overflow-y: hidden;
198
206
  display: flex;
207
+ flex-wrap: nowrap;
208
+ width: 100%;
199
209
  padding-top: $CAP_SPACE_06;
200
210
  padding-right: $CAP_SPACE_06;
201
211
  white-space: nowrap;
@@ -203,9 +213,8 @@
203
213
  &::-webkit-scrollbar {
204
214
  display: none; // Hide scrollbar in Chrome/Safari/Opera
205
215
  }
206
- overflow: hidden;
207
216
  .whatsapp-carousel-container {
208
- padding: $CAP_SPACE_04 0px $CAP_SPACE_08;
217
+ padding: $CAP_SPACE_04 0 $CAP_SPACE_08;
209
218
  border-radius: $CAP_SPACE_06;
210
219
  background-color: $CAP_WHITE;
211
220
  width: 80%;
@@ -253,6 +262,119 @@
253
262
  }
254
263
  }
255
264
 
265
+ // RCS template listing preview: match WhatsApp carousel "peek" behavior
266
+ .RCS {
267
+ .cap-custom-card {
268
+ .ant-card-body {
269
+ .ant-card-meta {
270
+ background-color: $CAP_G09;
271
+ padding: 0;
272
+ .ant-card-meta-description {
273
+ .whatsapp-container,.cap-rcs-creatives {
274
+ background-color: $CAP_WHITE;
275
+ padding: $CAP_SPACE_12;
276
+ border-radius: 0.25rem;
277
+ overflow-y: hidden;
278
+ .cap-divider-v2{
279
+ margin: $CAP_SPACE_12 0;
280
+ }
281
+ }
282
+ // Listing preview shows only the first card — no scroll/peek (Figma).
283
+ .whatsapp-carousel-container {
284
+ padding: $CAP_SPACE_04;
285
+ width: 100%;
286
+ box-sizing: border-box;
287
+ white-space: pre-wrap;
288
+ word-break: break-word;
289
+ overflow: auto;
290
+ text-align: left;
291
+ .whatsapp-carousel-card {
292
+ display: flex;
293
+ flex-direction: column;
294
+ gap: $CAP_SPACE_04;
295
+ }
296
+ // Text and media are two separate rounded cards, not one merged
297
+ // box (Figma listing reference) — text first, then media below it.
298
+ // Borderless + shadow-only elevation, matching the established
299
+ // convention for preview carousel cards (see .mobile-push-carousel-card
300
+ // in v2Components/TemplatePreview/_templatePreview.scss) — a visible
301
+ // border read as "boxed in" against the $CAP_G09 card background.
302
+ .rcs-carousel-listing-text-box {
303
+ background-color: $CAP_WHITE;
304
+ border-radius: $CAP_SPACE_04;
305
+ padding: $CAP_SPACE_12;
306
+ box-shadow: 0 0 0.625rem 0 rgba(0, 0, 0, 0.08);
307
+ .whatsapp-carousel-body {
308
+ white-space: pre-wrap;
309
+ overflow: hidden;
310
+ text-overflow: ellipsis;
311
+ display: -webkit-box;
312
+ -webkit-line-clamp: 2;
313
+ line-clamp: 2;
314
+ -webkit-box-orient: vertical;
315
+ }
316
+ }
317
+ .rcs-carousel-listing-media-box {
318
+ background-color: $CAP_WHITE;
319
+ border-radius: $CAP_SPACE_08;
320
+ padding: $CAP_SPACE_04;
321
+ box-sizing: border-box;
322
+ box-shadow: 0 0 0.625rem 0 rgba(0, 0, 0, 0.08);
323
+ .whatsapp-image,
324
+ .rcs-video-preview-placeholder {
325
+ display: block;
326
+ width: 100%;
327
+ // Neutralize the global .whatsapp-image { max-height: 123px;
328
+ // margin-bottom: 4px; } rule (_templates.scss line ~1202) — that
329
+ // margin was leaving a background sliver inside this rounded box,
330
+ // making the radius clip look uneven between top and bottom.
331
+ height: 11rem;
332
+ max-height: none;
333
+ margin: 0;
334
+ object-fit: cover;
335
+ overflow: hidden;
336
+ border-radius: $CAP_SPACE_04;
337
+ }
338
+ }
339
+ }
340
+
341
+ // RCS CTA buttons in listing (reuse WhatsApp-ish look)
342
+ .rcs-cta-preview {
343
+ margin: $CAP_SPACE_12 0;
344
+ display: flex;
345
+ justify-content: center;
346
+ font-size: $FONT_SIZE_M;
347
+ align-items: center;
348
+ color: #1970DA;
349
+ svg {
350
+ margin-right: $CAP_SPACE_04;
351
+ }
352
+ }
353
+
354
+ .rcs-video-preview-placeholder {
355
+ background: #f5f5f5;
356
+ display: flex;
357
+ align-items: center;
358
+ justify-content: center;
359
+ }
360
+
361
+ .rcs-video-preview-label {
362
+ color: #7a7a7a;
363
+ }
364
+
365
+ .rcs-listing-title {
366
+ font-weight: 600;
367
+ }
368
+
369
+ .whatsapp-divider {
370
+ margin: 0;
371
+ }
372
+ }
373
+ }
374
+ }
375
+ }
376
+ }
377
+
256
378
  .MOBILEPUSH {
257
379
  .ant-card-body {
258
380
  padding: 0;
@@ -298,6 +420,7 @@
298
420
  }
299
421
  .scroll-container {
300
422
  overflow-x: auto;
423
+ overflow-y: hidden;
301
424
  display: flex;
302
425
  padding-top: $CAP_SPACE_06;
303
426
  padding-right: $CAP_SPACE_06;
@@ -306,12 +429,11 @@
306
429
  &::-webkit-scrollbar {
307
430
  display: none; // Hide scrollbar in Chrome/Safari/Opera
308
431
  }
309
- overflow: hidden;
310
432
  height: 100%;
311
433
  width: 100%;
312
434
  margin-left: 1.65rem;
313
435
  .whatsapp-carousel-container {
314
- padding: $CAP_SPACE_04 0px $CAP_SPACE_08;
436
+ padding: $CAP_SPACE_04 0 $CAP_SPACE_08;
315
437
  border-radius: $CAP_SPACE_06;
316
438
  background-color: $CAP_WHITE;
317
439
  width: 80%;
@@ -701,11 +823,30 @@
701
823
  }
702
824
 
703
825
  .action-container{
704
- margin-top: 8px;
705
- margin-bottom: 16px;
826
+ margin-top: $CAP_SPACE_08;
827
+ margin-bottom: $CAP_SPACE_16;
706
828
  display: flex;
707
829
  justify-content: space-between;
708
830
  align-items: center;
831
+
832
+ &__toolbar-row {
833
+ display: flex;
834
+ align-items: center;
835
+ gap: 0.75rem;
836
+ }
837
+
838
+ &__toolbar-row .search-text {
839
+ width: 13.125rem;
840
+ min-width: 13.125rem;
841
+ flex: 1;
842
+ }
843
+
844
+ &__create-row {
845
+ display: flex;
846
+ justify-content: space-between;
847
+ align-items: center;
848
+ margin-right: $CAP_SPACE_32;
849
+ }
709
850
  }
710
851
 
711
852
  .popover-action-container:hover{
@@ -1164,6 +1305,49 @@
1164
1305
  overflow: 'auto';
1165
1306
  }
1166
1307
 
1308
+ /* Local SMS / slidebox: viewport-based .v2-pagination-container-half height leaves empty space below and clips cards */
1309
+ .creatives-templates-container--local-sms.library-mode {
1310
+ .creatives-templates-list.library-mode > .cap-row:first-of-type > div {
1311
+ display: flex;
1312
+ flex-direction: column;
1313
+ flex: 1 1 auto;
1314
+ min-height: 0;
1315
+ overflow: hidden;
1316
+ }
1317
+
1318
+ .creatives-templates-list.library-mode > .cap-row:first-of-type > div > div:first-child {
1319
+ display: flex;
1320
+ flex-direction: column;
1321
+ flex: 1 1 auto;
1322
+ min-height: 0;
1323
+ overflow: hidden;
1324
+ }
1325
+
1326
+ /* Block below search/filter: grid + skeletons — must grow to use space above footer */
1327
+ .creatives-templates-list.library-mode > .cap-row:first-of-type > div > div:first-child > div:nth-child(2) {
1328
+ flex: 1 1 auto;
1329
+ min-height: 0;
1330
+ display: flex;
1331
+ flex-direction: column;
1332
+ overflow: hidden;
1333
+ }
1334
+
1335
+ /*
1336
+ * Scroll needs a definite height. Pure flex + height:auto + max-height:100% often won’t bound (no % base), so no scrollbar.
1337
+ * Use a taller slice than global 100vh-20rem so the grid uses space under search; still overflow-y:auto for long lists.
1338
+ */
1339
+ .v2-pagination-container,
1340
+ .v2-pagination-container-half {
1341
+ flex: 0 1 auto;
1342
+ min-height: 0;
1343
+ height: calc(100vh - 12rem);
1344
+ max-height: calc(100vh - 12rem);
1345
+ overflow-y: auto;
1346
+ overflow-x: hidden;
1347
+ -webkit-overflow-scrolling: touch;
1348
+ }
1349
+ }
1350
+
1167
1351
  // Archive feature layout classes
1168
1352
  .illustration-scroll-wrapper {
1169
1353
  height: calc(100vh - 20.3125rem);
@@ -1174,7 +1358,7 @@
1174
1358
  display: flex;
1175
1359
  align-items: baseline;
1176
1360
  justify-content: space-between;
1177
- width: 102%;
1361
+ width: 100%;
1178
1362
  }
1179
1363
 
1180
1364
  .filter-row-content {
@@ -15,6 +15,17 @@ export function getAllTemplates(channel, queryParams, intlCopyOf = '') {
15
15
  };
16
16
  }
17
17
 
18
+
19
+ export function getLocalSmsTemplates(queryParams, intlCopyOf = '', onSuccess, onFailure) {
20
+ return {
21
+ type: types.GET_LOCAL_SMS_TEMPLATES_REQUEST,
22
+ queryParams,
23
+ intlCopyOf,
24
+ onSuccess,
25
+ onFailure,
26
+ };
27
+ }
28
+
18
29
  export function resetTemplate() {
19
30
  return {
20
31
  type: types.RESET_TEMPLATE,
@@ -10,6 +10,8 @@ export const GET_ALL_TEMPLATES_REQUEST = 'app/v2Containers/Templates/GET_ALL_TEM
10
10
  export const GET_ALL_TEMPLATES_SUCCESS = 'app/v2Containers/Templates/GET_ALL_TEMPLATES_SUCCESS';
11
11
  export const GET_ALL_TEMPLATES_FAILURE = 'app/v2Containers/Templates/GET_ALL_TEMPLATES_FAILURE';
12
12
 
13
+ export const GET_LOCAL_SMS_TEMPLATES_REQUEST = 'app/v2Containers/Templates/GET_LOCAL_SMS_TEMPLATES_REQUEST';
14
+
13
15
  export const DELETE_TEMPLATE_REQUEST = 'app/v2Containers/Templates/DELETE_TEMPLATE_REQUEST';
14
16
  export const DELETE_RCS_TEMPLATE_REQUEST = 'app/v2Containers/Templates/DELETE_RCS_TEMPLATE_REQUEST';
15
17
  export const DELETE_TEMPLATE_SUCCESS = 'app/v2Containers/Templates/DELETE_TEMPLATE_SUCCESS';