@capillarytech/creatives-library 9.0.28 → 9.0.29-alpha.2

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 +99 -0
  7. package/utils/templateVarUtils.js +198 -0
  8. package/utils/tests/rcsPayloadUtils.test.js +243 -0
  9. package/utils/tests/templateVarUtils.test.js +204 -0
  10. package/v2Components/CapActionButton/constants.js +20 -1
  11. package/v2Components/CapActionButton/index.js +193 -144
  12. package/v2Components/CapActionButton/index.scss +232 -14
  13. package/v2Components/CapActionButton/messages.js +19 -3
  14. package/v2Components/CapActionButton/tests/index.test.js +42 -18
  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 -63
  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 +256 -0
  99. package/v2Containers/Rcs/components/CarouselCard.js +315 -0
  100. package/v2Containers/Rcs/components/CarouselCardButtons.js +93 -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 +137 -16
  105. package/v2Containers/Rcs/index.js +1912 -958
  106. package/v2Containers/Rcs/index.scss +443 -8
  107. package/v2Containers/Rcs/messages.js +45 -22
  108. package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +522 -0
  109. package/v2Containers/Rcs/tests/CarouselCard.test.js +465 -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 +400 -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 +762 -30
  121. package/v2Containers/Rcs/utils.js +571 -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
@@ -8,6 +8,7 @@ import CapRow from '@capillarytech/cap-ui-library/CapRow';
8
8
  import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
9
9
  import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
10
10
  import CapHeader from "@capillarytech/cap-ui-library/CapHeader";
11
+ import CapRadioGroup from '@capillarytech/cap-ui-library/CapRadioGroup';
11
12
  import CapSelect from '@capillarytech/cap-ui-library/CapSelect';
12
13
  import CapInput from '@capillarytech/cap-ui-library/CapInput';
13
14
  import CapIcon from '@capillarytech/cap-ui-library/CapIcon';
@@ -20,9 +21,18 @@ import globalMessages from '../../v2Containers/Cap/messages';import CapTagListWi
20
21
 
21
22
  import { isUrl, isValidText } from '../../v2Containers/Line/Container/Wrapper/utils';
22
23
  import messages from './messages';
23
- import { CTA_OPTIONS, BTN_MAX_LENGTH, URL_MAX_LENGTH, PHONE_NUMBER_MAX_LENGTH,invalidVarRegex, HANDLERS } from './constants';
24
+ import {
25
+ BTN_MAX_LENGTH,
26
+ URL_MAX_LENGTH,
27
+ PHONE_NUMBER_MAX_LENGTH,
28
+ invalidVarRegex,
29
+ HANDLERS,
30
+ RCS_CTA_URL_TYPE,
31
+ CTA_TYPE_RADIO_OPTIONS,
32
+ CTA_URL_TYPE_SELECT_OPTIONS,
33
+ } from './constants';
24
34
  import './index.scss';
25
- import { INITIAL_SUGGESTIONS, RCS_BUTTON_TYPES} from '../../v2Containers/Rcs/constants';
35
+ import { INITIAL_SUGGESTIONS, RCS_BUTTON_TYPES, HOST_ICS} from '../../v2Containers/Rcs/constants';
26
36
 
27
37
  const { TextArea } = CapInput;
28
38
 
@@ -41,9 +51,12 @@ export const CapActionButton = (props) => {
41
51
  injectedTags = {},
42
52
  location = {},
43
53
  selectedOfferDetails = [],
44
-
54
+ host = '',
45
55
  onContextChange,
56
+ minSavedSuggestions = 0,
57
+ hideDeleteSuggestionIndexes = [],
46
58
  } = props;
59
+ const isHostIcs = host === HOST_ICS;
47
60
  const [urlError, setUrlError] = useState(false);
48
61
  const [buttonError, setButtonError] = useState(false);
49
62
  const updateHandler = (type, value, index) => {
@@ -66,6 +79,7 @@ export const CapActionButton = (props) => {
66
79
 
67
80
  const onCtaTypeChange = (value, index) => {
68
81
  let clonedCta = cloneDeep(suggestions[index]);
82
+ const isCta = value === RCS_BUTTON_TYPES.CTA;
69
83
  clonedCta = {
70
84
  ...clonedCta,
71
85
  type: value,
@@ -73,6 +87,7 @@ export const CapActionButton = (props) => {
73
87
  phoneNumber: '',
74
88
  postback: '',
75
89
  url: value === RCS_BUTTON_TYPES.PHONE_NUMBER ? null : '',
90
+ urlType: isCta ? RCS_CTA_URL_TYPE.STATIC : undefined,
76
91
  isSaved: false,
77
92
  };
78
93
  setUrlError(false);
@@ -84,7 +99,7 @@ export const CapActionButton = (props) => {
84
99
  const { value, id } = target;
85
100
  let errorMessage = '';
86
101
  if (value.length > BTN_MAX_LENGTH) {
87
- errorMessage = formatMessage(messages.ctaButtonTextLengthError);
102
+ errorMessage = formatMessage(messages.ctaButtonTextLengthError, { maxLength: BTN_MAX_LENGTH });
88
103
  } if (!isValidText(value)) {
89
104
  errorMessage = formatMessage(messages.ctaButtonErrorMessage);
90
105
  }
@@ -92,39 +107,61 @@ export const CapActionButton = (props) => {
92
107
  updateDisplayAndPostback(value, id);
93
108
  };
94
109
 
95
- const renderLength = (len, max) => (
96
- <CapHeading type="label1" className="rcs-render-btn-length">
97
- {formatMessage(messages.templateMessageLength, {
98
- currentLength: len,
99
- maxLength: max,
100
- })}
110
+ const renderInnerCharCount = (len, max) => (
111
+ <CapHeading type="h5" className="rcs-cta-inner-char-count">
112
+ {formatMessage(messages.ctaFieldCharCountInline, { current: len, max })}
101
113
  </CapHeading>
102
114
  );
103
115
 
104
- const onUrlChange = ({ target }) => {
105
- let { value, id } = target;
106
- let errorMessage = false;
107
- if (!isUrl(value)) {
108
- errorMessage = formatMessage(messages.ctaWebsiteUrlErrorMessage);
109
- } else if (value.match(invalidVarRegex)?.length > 0) {
110
- errorMessage = formatMessage(messages.staticUrlWithVarErrorMessage);
116
+ const validateCtaUrlValue = (value, urlSubtype) => {
117
+ const trimmedUrl = String(value || '').trim();
118
+ if (!trimmedUrl) {
119
+ return formatMessage(messages.ctaWebsiteUrlErrorMessage);
120
+ }
121
+ if (trimmedUrl.length > URL_MAX_LENGTH) {
122
+ return formatMessage(messages.ctaWebsiteUrlErrorMessage);
123
+ }
124
+ if (urlSubtype === RCS_CTA_URL_TYPE.DYNAMIC) {
125
+ return false;
126
+ }
127
+ if (!isUrl(trimmedUrl)) {
128
+ return formatMessage(messages.ctaWebsiteUrlErrorMessage);
111
129
  }
112
- setUrlError(errorMessage);
130
+ if (trimmedUrl.match(invalidVarRegex)?.length > 0) {
131
+ return formatMessage(messages.staticUrlWithVarErrorMessage);
132
+ }
133
+ return false;
134
+ };
135
+
136
+ const onUrlChange = ({ target }) => {
137
+ const { value, id } = target;
138
+ const row = suggestions[id] || {};
139
+ const subtype = row.urlType || RCS_CTA_URL_TYPE.STATIC;
140
+ setUrlError(validateCtaUrlValue(value, subtype));
113
141
  updateHandler(HANDLERS.URL, value, id);
114
142
  };
115
143
 
144
+ const onUrlSubtypeChange = (nextSubtype, index) => {
145
+ const cloned = cloneDeep(suggestions[index]);
146
+ cloned.urlType = nextSubtype;
147
+ cloned.isSaved = false;
148
+ setUrlError(validateCtaUrlValue(cloned.url || '', nextSubtype));
149
+ updateButtonChange(cloned, index);
150
+ };
151
+
116
152
  const onPhoneNoChange = (value, index) => {
117
153
  updateHandler(HANDLERS.PHONE_NUMBER, value, index);
118
154
  };
119
155
 
120
156
  const ctaSaveDisabled = (index) => {
121
- const { type, text, phoneNumber, url } = suggestions[index] || {};
157
+ const { type, text, phoneNumber, url, urlType } = suggestions[index] || {};
122
158
  if (text === '' || buttonError) {
123
159
  return true;
124
- } if (type === RCS_BUTTON_TYPES.PHONE_NUMBER && phoneNumber.length < 5) {
125
- return true;
126
- } if (type === RCS_BUTTON_TYPES.CTA && (url === '' || urlError)) {
160
+ } if (type === RCS_BUTTON_TYPES.PHONE_NUMBER && (phoneNumber || '').length < 5) {
127
161
  return true;
162
+ } if (type === RCS_BUTTON_TYPES.CTA) {
163
+ const subtype = urlType || RCS_CTA_URL_TYPE.STATIC;
164
+ return !!validateCtaUrlValue(url, subtype);
128
165
  }
129
166
  return false;
130
167
  };
@@ -143,64 +180,48 @@ export const CapActionButton = (props) => {
143
180
  updateButtonChange(newSuggestion, suggestions?.length);
144
181
  };
145
182
 
146
- const renderCtaOptions = (label, tooltipLabel, isDisabled) => {
147
- if (isDisabled) {
148
- return (
149
- <CapRow>
150
- <CapColumn span={23}>{label}</CapColumn>
151
- <CapColumn span={1}>
152
- <CapTooltipWithInfo
153
- // autoAdjustOverflow
154
- placement="right"
155
- title={tooltipLabel}
156
- />
157
- </CapColumn>
158
- </CapRow>
159
- );
160
- }
161
- return label;
162
- };
163
-
164
183
  const { formatMessage } = intl;
184
+
185
+ const hideDeleteForSuggestionIndex = (idx) =>
186
+ Array.isArray(hideDeleteSuggestionIndexes) && hideDeleteSuggestionIndexes.includes(idx);
187
+
165
188
  const renderedContent = () => {
166
189
  const renderArray = [];
167
- const addBtnDisabled = suggestions.length >= maxButtons || !suggestions[suggestions.length - 1]?.isSaved;
168
-
169
- const ctaOptions = CTA_OPTIONS.map((option) => {
170
- const { value, label } = option;
171
- const isDisabled = suggestions.length >= maxButtons && !suggestions[suggestions.length - 1];
172
- return {
173
- value,
174
- label: renderCtaOptions(label, formatMessage(messages.ctaButtonTypeDisabled), isDisabled),
175
- disabled: isDisabled,
176
- };
177
- });
190
+ const addBtnDisabled = suggestions?.length > 0 && (suggestions.length >= maxButtons || !suggestions[suggestions.length - 1]?.isSaved);
191
+ const savedSuggestionsCount = (suggestions || []).filter((s) => s && s.isSaved).length;
192
+ const cannotDeleteSavedMandatory = (idx) => {
193
+ const row = suggestions[idx];
194
+ if (!row || !row.isSaved) return false;
195
+ return minSavedSuggestions > 0 && savedSuggestionsCount <= minSavedSuggestions;
196
+ };
178
197
 
179
- suggestions.forEach((cta) => {
198
+ suggestions?.length > 0 && suggestions.forEach((cta) => {
180
199
  const {
181
200
  index, type, text, isSaved,
182
201
  } = cta || {};
183
202
 
184
203
  const url = type !== RCS_BUTTON_TYPES.CTA ? null : cta.url;
204
+ const urlSubtype = type === RCS_BUTTON_TYPES.CTA
205
+ ? (cta.urlType || RCS_CTA_URL_TYPE.STATIC)
206
+ : RCS_CTA_URL_TYPE.STATIC;
185
207
  const phoneNumber = type !== RCS_BUTTON_TYPES.PHONE_NUMBER ? null : cta.phoneNumber;
186
208
  if (isFullMode && !isEditFlow && !isSaved) {
187
209
  renderArray.push(
188
- <div className="rcs-button-cta-create-container" key={`cta-edit-${index}`}>
189
- <CapRow type='flex' justify='space-between' className="rcs-button-cta-create margin-t-16">
190
- <CapColumn span={11}>
191
- {/* Type of action */}
192
- <CapHeading type="h4" className="cta-label">
210
+ <CapRow className="rcs-button-cta-create-container" key={`cta-edit-${index}`} gutter={0}>
211
+ <CapRow className="rcs-button-cta-create" gutter={0}>
212
+ <CapColumn span={24}>
213
+ <CapHeading type="h4">
193
214
  {formatMessage(messages.ctaType)}
194
215
  </CapHeading>
195
- <CapSelect
196
- id="rcs-cta-type"
197
- options={ctaOptions || []}
198
- onChange={(value) => onCtaTypeChange(value, index)}
216
+ <CapRadioGroup
217
+ id={`rcs-cta-type-radio-${index}`}
218
+ className="cap-rcs-cta-type-radio"
219
+ options={CTA_TYPE_RADIO_OPTIONS}
199
220
  value={type}
200
- disabled={false}
221
+ onChange={(e) => onCtaTypeChange(e.target.value, index)}
201
222
  />
202
223
  </CapColumn>
203
- <CapColumn span={12}>
224
+ <CapColumn span={24}>
204
225
  <CapHeading type="h4" className="cta-label">
205
226
  {formatMessage(messages.ctaButtonText)}
206
227
  <CapTooltipWithInfo
@@ -221,28 +242,34 @@ export const CapActionButton = (props) => {
221
242
  size="large"
222
243
  maxLength={BTN_MAX_LENGTH}
223
244
  errorMessage={buttonError}
245
+ suffix={renderInnerCharCount((text || '').length, BTN_MAX_LENGTH)}
224
246
  />
225
- {renderLength(text.length, BTN_MAX_LENGTH)}
226
247
  </CapColumn>
227
248
  </CapRow>
228
249
  {type === RCS_BUTTON_TYPES.PHONE_NUMBER && (
229
250
  <>
230
251
  <CapRow>
231
- <CapColumn span={11}>
232
- {/* phone number */}
252
+ <CapColumn span={24}>
233
253
  <CapHeading type="h4" className="cta-label">
234
254
  {formatMessage(messages.ctaPhoneNo)}
235
255
  </CapHeading>
236
- <PhoneInput
237
- placeholder={formatMessage(messages.ctaPhoneNoPlaceholder)}
238
- autoFormat={false}
239
- countryCodeEditable={false}
240
- value={phoneNumber}
241
- onChange={(value) => onPhoneNoChange(value, index)}
242
- country="in"
243
- className="cta-phone-number"
244
- />
245
- {renderLength(phoneNumber.length, PHONE_NUMBER_MAX_LENGTH)}
256
+ <CapRow
257
+ className="rcs-cta-input-with-inner-count rcs-cta-input-with-inner-count--phone"
258
+ gutter={0}
259
+ >
260
+ <CapColumn span={24}>
261
+ <PhoneInput
262
+ placeholder={formatMessage(messages.ctaPhoneNoPlaceholder)}
263
+ autoFormat={false}
264
+ countryCodeEditable={false}
265
+ value={phoneNumber}
266
+ onChange={(value) => onPhoneNoChange(value, index)}
267
+ country="in"
268
+ className="cta-phone-number rcs-cta-phone-input"
269
+ />
270
+ {renderInnerCharCount((phoneNumber || '').length, PHONE_NUMBER_MAX_LENGTH)}
271
+ </CapColumn>
272
+ </CapRow>
246
273
  </CapColumn>
247
274
  </CapRow>
248
275
  <CapRow useLegacy className="rcs-cta-save-delete-btn">
@@ -250,7 +277,7 @@ export const CapActionButton = (props) => {
250
277
  title={ctaSaveDisabled(index) && formatMessage(messages.ctaSaveDisabled)}
251
278
  placement="bottom"
252
279
  >
253
- <div className="button-disabled-tooltip-wrapper">
280
+ <CapRow className="button-disabled-tooltip-wrapper">
254
281
  <CapButton
255
282
  onClick={() => saveCta(index)}
256
283
  disabled={ctaSaveDisabled(index)}
@@ -258,36 +285,49 @@ export const CapActionButton = (props) => {
258
285
  >
259
286
  {formatMessage(globalMessages.save)}
260
287
  </CapButton>
261
- </div>
288
+ </CapRow>
262
289
  </CapTooltip>
263
- <CapButton
264
- onClick={() => deleteButtonHandler(index)}
265
- className="rcs-cta-delete-btn"
266
- type="secondary"
267
- >
268
- {formatMessage(globalMessages.delete)}
269
- </CapButton>
290
+ {!hideDeleteForSuggestionIndex(index) && !cannotDeleteSavedMandatory(index) && (
291
+ <CapButton
292
+ onClick={() => deleteButtonHandler(index)}
293
+ className="rcs-cta-delete-btn"
294
+ type="secondary"
295
+ >
296
+ {formatMessage(globalMessages.delete)}
297
+ </CapButton>
298
+ )}
270
299
  </CapRow>
271
300
  </>
272
301
  )}
273
302
  {type === RCS_BUTTON_TYPES.CTA && (
274
303
  <>
275
- <CapRow>
276
- <CapColumn span={24}>
304
+ <CapRow className="rcs-cta-url-fields-row" gutter={8}>
305
+ <CapColumn span={6} className="rcs-cta-url-type-col">
306
+ <CapHeading type="h4" className="cta-label">
307
+ {formatMessage(messages.ctaWebsiteType)}
308
+ </CapHeading>
309
+ <CapSelect
310
+ id={`rcs-cta-url-type-${index}`}
311
+ options={CTA_URL_TYPE_SELECT_OPTIONS}
312
+ value={urlSubtype}
313
+ onChange={(value) => onUrlSubtypeChange(value, index)}
314
+ />
315
+ </CapColumn>
316
+ <CapColumn span={18} className="rcs-cta-url-value-col">
277
317
  <CapHeading type="h4" className="cta-label">
278
- {formatMessage(messages.ctaWebsite)}
318
+ {formatMessage(messages.ctaUrlField)}
279
319
  </CapHeading>
280
320
  <CapInput
281
321
  id={index}
282
322
  className="rcs-cta-url"
283
323
  onChange={onUrlChange}
284
- placeholder={formatMessage(messages.ctaStaticPlaceholder)}
285
- value={url}
324
+ placeholder={formatMessage(messages.ctaEnterUrlPlaceholder)}
325
+ value={url || ''}
286
326
  size="large"
287
327
  maxLength={URL_MAX_LENGTH}
288
328
  errorMessage={urlError}
329
+ suffix={renderInnerCharCount((url || '').length, URL_MAX_LENGTH)}
289
330
  />
290
- {renderLength(url.length, URL_MAX_LENGTH)}
291
331
  </CapColumn>
292
332
  </CapRow>
293
333
  <CapRow useLegacy className="rcs-cta-save-delete-btn">
@@ -297,7 +337,7 @@ export const CapActionButton = (props) => {
297
337
  }
298
338
  placement="bottom"
299
339
  >
300
- <div className="button-disabled-tooltip-wrapper">
340
+ <CapRow className="button-disabled-tooltip-wrapper">
301
341
  <CapButton
302
342
  onClick={() => saveCta(index)}
303
343
  disabled={ctaSaveDisabled(index)}
@@ -305,15 +345,17 @@ export const CapActionButton = (props) => {
305
345
  >
306
346
  {formatMessage(globalMessages.save)}
307
347
  </CapButton>
308
- </div>
348
+ </CapRow>
309
349
  </CapTooltip>
310
- <CapButton
311
- onClick={() => deleteButtonHandler(index)}
312
- className="rcs-cta-delete-btn"
313
- type="secondary"
314
- >
315
- {formatMessage(globalMessages.delete)}
316
- </CapButton>
350
+ {!hideDeleteForSuggestionIndex(index) && !cannotDeleteSavedMandatory(index) && (
351
+ <CapButton
352
+ onClick={() => deleteButtonHandler(index)}
353
+ className="rcs-cta-delete-btn"
354
+ type="secondary"
355
+ >
356
+ {formatMessage(globalMessages.delete)}
357
+ </CapButton>
358
+ )}
317
359
  </CapRow>
318
360
  </>
319
361
  )}
@@ -323,7 +365,7 @@ export const CapActionButton = (props) => {
323
365
  title={ctaSaveDisabled(index) && formatMessage(messages.ctaSaveDisabled)}
324
366
  placement="bottom"
325
367
  >
326
- <div className="button-disabled-tooltip-wrapper">
368
+ <CapRow className="button-disabled-tooltip-wrapper">
327
369
  <CapButton
328
370
  onClick={() => saveCta(index)}
329
371
  disabled={ctaSaveDisabled(index)}
@@ -331,9 +373,9 @@ export const CapActionButton = (props) => {
331
373
  >
332
374
  {formatMessage(globalMessages.save)}
333
375
  </CapButton>
334
- </div>
376
+ </CapRow>
335
377
  </CapTooltip>
336
- {index !== 0 && (
378
+ {!(isHostIcs && index === 0) && !hideDeleteForSuggestionIndex(index) && !cannotDeleteSavedMandatory(index) && (
337
379
  <CapButton
338
380
  onClick={() => deleteButtonHandler(index)}
339
381
  className="rcs-cta-delete-btn"
@@ -344,23 +386,24 @@ export const CapActionButton = (props) => {
344
386
  )}
345
387
  </CapRow>
346
388
  )}
347
- </div>
389
+ </CapRow>
348
390
  );
349
391
  } else {
350
392
  const ctaIsPhone = type === RCS_BUTTON_TYPES.PHONE_NUMBER;
351
393
  const ctaIsReply = type === RCS_BUTTON_TYPES.QUICK_REPLY;
352
- renderArray.push(
394
+ suggestions?.length > 0 && renderArray?.push(
353
395
  <CapRow
354
396
  key={`cta-saved-${index}`}
355
397
  className="cap-rcs-saved-cta margin-t-12"
356
398
  align="middle"
357
399
  type="flex"
400
+ gutter={9}
358
401
  >
359
402
  <CapColumn
360
403
  span={1}
361
404
  className={`${ctaIsPhone ? 'whatsapp-saved-cta-phone-icon' : ''}`}
362
405
  >
363
- <CapIcon size="s" type={ctaIsPhone ? 'call' : 'launch'} />
406
+ <CapIcon size="s" type={ctaIsPhone ? 'call' : (ctaIsReply ? 'small-link' : 'launch')} />
364
407
  </CapColumn>
365
408
  <CapColumn span={6}>
366
409
  <CapLabel
@@ -370,49 +413,49 @@ export const CapActionButton = (props) => {
370
413
  {text}
371
414
  </CapLabel>
372
415
  </CapColumn>
373
- {ctaIsPhone && (
374
- <CapColumn span={10} align="left">
375
- <CapLabel className="phone">+{phoneNumber}</CapLabel>
376
- </CapColumn>
377
- )}
378
- {!ctaIsPhone && !ctaIsReply && (
379
- <>
380
- <CapColumn span={3}>
381
- <CapLabel className="url-type" type="label2">
382
- {formatMessage(messages.ctaWebsiteTypeStatic)}
383
- </CapLabel>
384
- </CapColumn>
385
- <CapRow type='flex' className="rcs-url-preview-wrapper">
386
- <CapTooltip title={url} placement="top">
387
- <CapColumn span={14} className="margin-r-0">
416
+ <CapColumn flex={1} className="rcs-saved-cta-value-column">
417
+ <div className="rcs-saved-cta-value-actions">
418
+ {ctaIsPhone && (
419
+ <CapLabel className="phone">+{phoneNumber}</CapLabel>
420
+ )}
421
+ {!ctaIsPhone && !ctaIsReply && (
422
+ <>
423
+ <CapLabel className="url-type" type="label2">
424
+ {(cta.urlType || RCS_CTA_URL_TYPE.STATIC) === RCS_CTA_URL_TYPE.DYNAMIC
425
+ ? formatMessage(messages.ctaWebsiteTypeDynamic)
426
+ : formatMessage(messages.ctaWebsiteTypeStatic)}
427
+ </CapLabel>
428
+ <CapTooltip title={url} placement="top">
388
429
  <CapLabel className="url">{url}</CapLabel>
389
- </CapColumn>
390
- </CapTooltip>
391
- </CapRow>
392
- </>
393
- )}
394
- {(isFullMode && !isEditFlow) && (
395
- <>
396
- <CapColumn
397
- span={1}
398
- className="rcs-saved-cta-edit-icon"
399
- onClick={() => editCta(index)}
400
- >
401
- <CapIcon size="s" type="edit" />
402
- </CapColumn>
403
- {index !== 0 && (
404
- <CapColumn className="rcs-saved-cta-delete-icon" span={1} onClick={() => deleteButtonHandler(index)}>
405
- <CapIcon size="s" type="delete" />
406
- </CapColumn>
430
+ </CapTooltip>
431
+ </>
407
432
  )}
408
- </>
409
- )}
433
+ {(isFullMode && !isEditFlow) && (
434
+ <div className="rcs-saved-cta-action-icons">
435
+ <CapIcon
436
+ size="s"
437
+ type="edit"
438
+ className="rcs-saved-cta-edit-icon"
439
+ onClick={() => editCta(index)}
440
+ />
441
+ {!(isHostIcs && index === 0) && !hideDeleteForSuggestionIndex(index) && !cannotDeleteSavedMandatory(index) && (
442
+ <CapIcon
443
+ size="s"
444
+ type="delete"
445
+ className="rcs-saved-cta-delete-icon"
446
+ onClick={() => deleteButtonHandler(index)}
447
+ />
448
+ )}
449
+ </div>
450
+ )}
451
+ </div>
452
+ </CapColumn>
410
453
  </CapRow>
411
454
  );
412
455
  }
413
456
  });
414
457
  {
415
- suggestions.length < maxButtons &&
458
+ suggestions?.length < maxButtons &&
416
459
  (isFullMode && !isEditFlow)
417
460
  && renderArray.push(
418
461
  <CapRow useLegacy>
@@ -422,7 +465,7 @@ export const CapActionButton = (props) => {
422
465
  }
423
466
  placement={'right'}
424
467
  >
425
- <div className="button-disabled-tooltip-wrapper">
468
+ <CapRow className="button-disabled-tooltip-wrapper">
426
469
  <CapButton
427
470
  type="flat"
428
471
  id="rcs-cta-add-button"
@@ -433,7 +476,7 @@ export const CapActionButton = (props) => {
433
476
  >
434
477
  {formatMessage(messages.addButton)}
435
478
  </CapButton>
436
- </div>
479
+ </CapRow>
437
480
  </CapTooltip>
438
481
  </CapRow>,
439
482
  );
@@ -446,6 +489,8 @@ export const CapActionButton = (props) => {
446
489
  CapActionButton.propTypes = {
447
490
  intl: intlShape.isRequired,
448
491
  updateButtonChange: PropTypes.func,
492
+ minSavedSuggestions: PropTypes.number,
493
+ hideDeleteSuggestionIndexes: PropTypes.arrayOf(PropTypes.number),
449
494
  suggestions: PropTypes.array,
450
495
  tags: PropTypes.array,
451
496
  injectedTags: PropTypes.object,
@@ -453,12 +498,15 @@ CapActionButton.propTypes = {
453
498
  selectedOfferDetails: PropTypes.array,
454
499
  onTagSelect: PropTypes.func,
455
500
  onContextChange: PropTypes.func,
501
+ host: PropTypes.string,
456
502
  };
457
503
 
458
504
  CapActionButton.defaultProps = {
459
505
  buttonTextlen: 20,
460
506
  type: '',
461
507
  updateButtonChange: () => {},
508
+ minSavedSuggestions: 0,
509
+ hideDeleteSuggestionIndexes: [],
462
510
  suggestions: [],
463
511
  tags: [],
464
512
  injectedTags: {},
@@ -466,6 +514,7 @@ CapActionButton.defaultProps = {
466
514
  selectedOfferDetails: [],
467
515
  onTagSelect: () => {},
468
516
  onContextChange: () => {},
517
+ host: '',
469
518
  };
470
519
 
471
520
  export default injectIntl(CapActionButton);