@capillarytech/creatives-library 9.0.15-alpha.0 → 9.0.15-alpha.3

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