@capillarytech/creatives-library 8.0.345-alpha.15 → 8.0.345-alpha.16

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 (130) hide show
  1. package/constants/unified.js +0 -29
  2. package/package.json +1 -1
  3. package/services/tests/api.test.js +0 -13
  4. package/utils/commonUtils.js +1 -19
  5. package/v2Components/CapActionButton/constants.js +0 -7
  6. package/v2Components/CapActionButton/index.js +109 -167
  7. package/v2Components/CapActionButton/index.scss +6 -157
  8. package/v2Components/CapActionButton/messages.js +3 -19
  9. package/v2Components/CapActionButton/tests/index.test.js +17 -41
  10. package/v2Components/CapTagList/index.js +0 -10
  11. package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +49 -70
  12. package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +2 -8
  13. package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +21 -207
  14. package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +0 -16
  15. package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +10 -85
  16. package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +0 -30
  17. package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +11 -79
  18. package/v2Components/CommonTestAndPreview/SendTestMessage.js +5 -10
  19. package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +15 -160
  20. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +76 -341
  21. package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +4 -133
  22. package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +0 -11
  23. package/v2Components/CommonTestAndPreview/constants.js +2 -38
  24. package/v2Components/CommonTestAndPreview/index.js +186 -676
  25. package/v2Components/CommonTestAndPreview/messages.js +3 -49
  26. package/v2Components/CommonTestAndPreview/sagas.js +6 -15
  27. package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +284 -308
  28. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +65 -231
  29. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +5 -118
  30. package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +0 -341
  31. package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +1 -8
  32. package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +13 -34
  33. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +283 -281
  34. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +1 -199
  35. package/v2Components/CommonTestAndPreview/tests/index.test.js +4 -132
  36. package/v2Components/CommonTestAndPreview/tests/sagas.test.js +2 -2
  37. package/v2Components/FormBuilder/index.js +10 -8
  38. package/v2Components/TemplatePreview/_templatePreview.scss +23 -33
  39. package/v2Components/TemplatePreview/index.js +28 -143
  40. package/v2Components/TemplatePreview/tests/index.test.js +0 -142
  41. package/v2Components/TestAndPreviewSlidebox/index.js +1 -13
  42. package/v2Components/TestAndPreviewSlidebox/sagas.js +4 -11
  43. package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +1 -3
  44. package/v2Containers/CreativesContainer/SlideBoxContent.js +4 -36
  45. package/v2Containers/CreativesContainer/SlideBoxFooter.js +1 -10
  46. package/v2Containers/CreativesContainer/SlideBoxHeader.js +4 -29
  47. package/v2Containers/CreativesContainer/constants.js +0 -9
  48. package/v2Containers/CreativesContainer/index.js +103 -300
  49. package/v2Containers/CreativesContainer/index.scss +1 -51
  50. package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +34 -78
  51. package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +16 -79
  52. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -8
  53. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +98 -357
  54. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +15 -20
  55. package/v2Containers/CreativesContainer/tests/index.test.js +9 -71
  56. package/v2Containers/Email/reducer.js +12 -3
  57. package/v2Containers/Email/sagas.js +9 -4
  58. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +4 -0
  59. package/v2Containers/Email/tests/reducer.test.js +47 -0
  60. package/v2Containers/Email/tests/sagas.test.js +146 -6
  61. package/v2Containers/Rcs/constants.js +8 -119
  62. package/v2Containers/Rcs/index.js +811 -2383
  63. package/v2Containers/Rcs/index.scss +6 -276
  64. package/v2Containers/Rcs/messages.js +3 -38
  65. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +70073 -98018
  66. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +5 -0
  67. package/v2Containers/Rcs/tests/index.test.js +121 -152
  68. package/v2Containers/Rcs/tests/mockData.js +0 -38
  69. package/v2Containers/Rcs/tests/utils.test.js +30 -646
  70. package/v2Containers/Rcs/utils.js +11 -478
  71. package/v2Containers/Sms/Create/index.js +40 -100
  72. package/v2Containers/SmsTrai/Create/index.js +4 -9
  73. package/v2Containers/SmsTrai/Edit/constants.js +0 -2
  74. package/v2Containers/SmsTrai/Edit/index.js +130 -636
  75. package/v2Containers/SmsTrai/Edit/messages.js +4 -14
  76. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2296 -4249
  77. package/v2Containers/SmsWrapper/index.js +8 -37
  78. package/v2Containers/TagList/index.js +0 -6
  79. package/v2Containers/Templates/_templates.scss +2 -163
  80. package/v2Containers/Templates/actions.js +0 -11
  81. package/v2Containers/Templates/constants.js +0 -2
  82. package/v2Containers/Templates/index.js +54 -119
  83. package/v2Containers/Templates/sagas.js +12 -57
  84. package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1079 -1043
  85. package/v2Containers/Templates/tests/sagas.test.js +123 -193
  86. package/v2Containers/TemplatesV2/TemplatesV2.style.js +1 -72
  87. package/v2Containers/TemplatesV2/index.js +23 -86
  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/templateVarUtils.test.js +0 -204
  93. package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js.rej +0 -18
  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 -87
  97. package/v2Components/SmsFallback/constants.js +0 -73
  98. package/v2Components/SmsFallback/index.js +0 -955
  99. package/v2Components/SmsFallback/index.scss +0 -265
  100. package/v2Components/SmsFallback/messages.js +0 -78
  101. package/v2Components/SmsFallback/smsFallbackUtils.js +0 -118
  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 -197
  106. package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +0 -277
  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 -67
  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/index.js.rej +0 -1336
  119. package/v2Containers/Rcs/index.scss.rej +0 -74
  120. package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +0 -225
  121. package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap.rej +0 -128
  122. package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +0 -318
  123. package/v2Containers/Sms/smsFormDataHelpers.js +0 -67
  124. package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +0 -253
  125. package/v2Containers/SmsTrai/Edit/index.scss +0 -121
  126. package/v2Containers/Templates/TemplatesActionBar.js +0 -101
  127. package/v2Containers/Templates/tests/TemplatesActionBar.test.js +0 -120
  128. package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +0 -180
  129. package/v2Containers/Templates/utils/smsTemplatesListApi.js +0 -79
  130. package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +0 -131
@@ -1,27 +1,14 @@
1
1
  @import '~@capillarytech/cap-ui-library/styles/_variables';
2
2
 
3
- // Horizontal RCS button type radios (Phone number | URL | Quick reply)
4
- .cap-rcs-cta-type-radio.cap-radio-group-v2 {
5
- display: flex;
6
- flex-wrap: wrap;
7
- align-items: center;
8
- margin-top: 0.5rem;
9
-
10
- .ant-radio-wrapper {
11
- margin-right: $CAP_SPACE_24;
12
- margin-bottom: 0;
13
-
14
- &:last-child {
15
- margin-right: 0;
16
- }
17
- }
3
+ #rcs-cta-type{
4
+ width: 90%;
18
5
  }
19
6
 
20
7
  .cap-rcs-saved-cta {
21
8
  position: relative;
22
9
  border: solid $CAP_SPACE_01 $CAP_G06;
23
10
  padding: 0.625rem;
24
- border-radius: 0.25rem; // 4px
11
+ border-radius: $CAP_SPACE_04;
25
12
  margin-bottom: $CAP_SPACE_12;
26
13
 
27
14
  div:not(:last-child) {
@@ -52,139 +39,9 @@
52
39
  }
53
40
  }
54
41
 
55
- // Button text / URL: count via CapInput `suffix` (antd affix, right-aligned inside field).
56
- // Phone: react-phone-input-2 overlay count + padding on .form-control
57
- .rcs-cta-inner-char-count {
58
- font-size: 0.75rem;
59
- line-height: 1.25rem;
60
- color: $FONT_COLOR_03;
61
- white-space: nowrap;
62
- }
63
-
64
- .rcs-cta-input-with-inner-count {
65
- position: relative;
66
- width: 100%;
67
-
68
- &--phone .rcs-cta-inner-char-count {
69
- position: absolute;
70
- right: 0.6875rem;
71
- top: 50%;
72
- transform: translateY(-50%);
73
- z-index: 2;
74
- pointer-events: none;
75
- }
76
- }
77
-
78
- // RCS phone field: Figma — one light border, 4px radius, ~antd Input large height, full width, count inside right
79
- .rcs-button-cta-create-container .rcs-cta-input-with-inner-count--phone {
80
- .react-tel-input.rcs-cta-phone-input {
81
- width: 100%;
82
- }
83
-
84
- .rcs-cta-phone-input .form-control {
85
- width: 100% !important;
86
- max-width: none;
87
- height: 2.5rem;
88
- min-height: 2.5rem;
89
- padding-top: 0;
90
- padding-bottom: 0;
91
- padding-left: 3rem;
92
- padding-right: 3.5rem;
93
- margin: 0;
94
- font-size: 0.875rem;
95
- line-height: 2.5rem;
96
- color: $CAP_G01;
97
- background: $CAP_WHITE;
98
- border: 1px solid $CAP_G06;
99
- border-radius: 0.25rem;
100
- box-shadow: none;
101
-
102
- &::placeholder {
103
- color: $CAP_G05;
104
- }
105
-
106
- &:hover {
107
- border-color: $CAP_G11;
108
- }
109
-
110
- &:focus {
111
- border-color: $CAP_G01;
112
- box-shadow: none;
113
- outline: none;
114
- }
115
- }
116
-
117
- .rcs-cta-phone-input .flag-dropdown {
118
- top: 1px;
119
- bottom: 1px;
120
- left: 1px;
121
- padding: 0;
122
- background: $CAP_WHITE;
123
- border: none;
124
- border-radius: 0.1875rem 0 0 0.1875rem; // inset from outer 4px radius
125
- }
126
-
127
- .rcs-cta-phone-input .flag-dropdown.open {
128
- border-radius: 0.1875rem 0 0 0;
129
- }
130
-
131
- .rcs-cta-phone-input .selected-flag {
132
- width: 2.75rem;
133
- padding: 0 0 0 0.5rem;
134
- background: transparent;
135
- border-radius: 0.1875rem 0 0 0.1875rem;
136
- }
137
-
138
- .rcs-cta-phone-input .selected-flag:hover,
139
- .rcs-cta-phone-input .selected-flag:focus {
140
- background: $CAP_G09;
141
- }
142
-
143
- .rcs-cta-phone-input .selected-flag .arrow {
144
- left: 1.375rem;
145
- border-top-color: $CAP_G04;
146
- }
147
- }
148
-
149
- // URL CTA: URL type (narrow) + URL field (~1:3) per Figma
150
- .rcs-cta-url-fields-row {
151
- .rcs-cta-url-type-col .ant-select {
152
- width: 100%;
153
- }
154
- }
155
-
156
- // RCS “create CTA” card: 0.5rem padding + gaps (Figma-tight; fixes excess space above first label)
157
- .rcs-button-cta-create-container.cap-row-v2 {
158
- display: flex;
159
- flex-direction: column;
160
- flex-wrap: nowrap;
161
- width: 100%;
162
- border: solid 1px $CAP_G06;
163
- padding: 1.25rem;
164
- border-radius: 0.25rem; // 4px — match .cap-rcs-saved-cta
165
-
166
- // Stack “Button type” (radios) above “Button text”
167
- .rcs-button-cta-create.cap-row-v2 {
168
- display: flex;
169
- flex-direction: column;
170
- flex-wrap: nowrap;
171
- margin: 0;
172
- }
173
-
174
- // Space after each field label (CapHeading margins are often zeroed by the library)
175
- .cta-label {
176
- margin-bottom: 0;
177
- margin-top: 0.75rem;
178
- }
179
-
180
- .cta-label + * {
181
- margin-top: 0.5rem;
182
- }
183
-
184
- // “Button type” heading has no .cta-label — keep same label→control gap as other fields
185
- .rcs-button-cta-create > .ant-col:first-of-type .cap-rcs-cta-type-radio {
186
- margin-top: 0.5rem;
187
- }
42
+ .rcs-button-cta-create-container {
43
+ border: solid 1px $CAP_G06;
44
+ padding: 10px;
188
45
  }
189
46
 
190
47
  .disabled {
@@ -198,12 +55,4 @@
198
55
 
199
56
  .button-disabled-tooltip-wrapper {
200
57
  display: inline-block;
201
- margin-top: 1.25rem;
202
- }
203
-
204
- // Space between Save and Delete on RCS / carousel CTA rows
205
- .rcs-cta-save-delete-btn {
206
- .rcs-cta-delete-btn {
207
- margin-left: 0.75rem;
208
- }
209
58
  }
@@ -12,7 +12,7 @@ export default defineMessages({
12
12
  },
13
13
  ctaQr: {
14
14
  id: `${prefix}.ctaQr`,
15
- defaultMessage: 'Quick reply',
15
+ defaultMessage: 'Quick Reply',
16
16
  },
17
17
  ctaPhoneNo: {
18
18
  id: `${prefix}.ctaPhoneNo`,
@@ -47,17 +47,9 @@ export default defineMessages({
47
47
  id: `${prefix}.templateMessageLength`,
48
48
  defaultMessage: 'Characters count: {currentLength}/{maxLength}',
49
49
  },
50
- ctaFieldCharCountInline: {
51
- id: `${prefix}.ctaFieldCharCountInline`,
52
- defaultMessage: '{current}/{max}',
53
- },
54
50
  ctaType: {
55
51
  id: `${prefix}.ctaType`,
56
- defaultMessage: 'Button type',
57
- },
58
- ctaUrlRadio: {
59
- id: `${prefix}.ctaUrlRadio`,
60
- defaultMessage: 'URL',
52
+ defaultMessage: 'Type of action',
61
53
  },
62
54
  templateButtonTextPlaceholder: {
63
55
  id: `${prefix}.templateButtonTextPlaceholder`,
@@ -153,15 +145,7 @@ export default defineMessages({
153
145
  },
154
146
  ctaWebsiteType: {
155
147
  id: `${prefix}.ctaWebsiteType`,
156
- defaultMessage: 'URL type',
157
- },
158
- ctaUrlField: {
159
- id: `${prefix}.ctaUrlField`,
160
- defaultMessage: 'URL',
161
- },
162
- ctaEnterUrlPlaceholder: {
163
- id: `${prefix}.ctaEnterUrlPlaceholder`,
164
- defaultMessage: 'Enter URL',
148
+ defaultMessage: 'URL Type',
165
149
  },
166
150
  ctaWebsiteTypeStatic: {
167
151
  id: `${prefix}.ctaWebsiteTypeStatic`,
@@ -4,7 +4,7 @@ import '@testing-library/jest-dom';
4
4
  import { render, screen, fireEvent } from '../../../utils/test-utils';
5
5
  import { CapActionButton } from '../index';
6
6
  import { BTN_MAX_LENGTH, PHONE_NUMBER_MAX_LENGTH, URL_MAX_LENGTH } from '../constants';
7
- import { RCS_BUTTON_TYPES, HOST_ICS } from '../../../v2Containers/Rcs/constants';
7
+ import { RCS_BUTTON_TYPES } from '../../../v2Containers/Rcs/constants';
8
8
 
9
9
  const updateHandler = jest.fn();
10
10
  const deleteHandler = jest.fn();
@@ -12,7 +12,6 @@ const initializeComponent = (
12
12
  data,
13
13
  isEditFlow = false,
14
14
  maxButtons = 3,
15
- host = '',
16
15
  ) => {
17
16
  // Normalize legacy test data shape to match component props
18
17
  const normalizeType = (legacyType) => {
@@ -38,7 +37,6 @@ const initializeComponent = (
38
37
  isEditFlow={isEditFlow}
39
38
  maxButtons={maxButtons}
40
39
  isFullMode={true}
41
- host={host}
42
40
  />,
43
41
  );
44
42
  };
@@ -61,7 +59,7 @@ describe('CapActionButton', () => {
61
59
  isSaved: false,
62
60
  },
63
61
  ]);
64
- expect(screen.getByText('Button type')).toBeInTheDocument();
62
+ expect(screen.getByText('Type of action')).toBeInTheDocument();
65
63
  expect(screen.getByText('Button text')).toBeInTheDocument();
66
64
  expect(screen.getAllByText('Phone number')[1]).toBeInTheDocument();
67
65
  expect(screen.getByRole('button', { name: /save/i })).toBeDisabled();
@@ -124,7 +122,7 @@ describe('CapActionButton', () => {
124
122
  id: 1,
125
123
  },
126
124
  };
127
- const urlInput = await screen.getByPlaceholderText('Enter URL');
125
+ const urlInput = await screen.getByPlaceholderText('Enter website URL');
128
126
  fireEvent.change(urlInput, urlEvent);
129
127
  expect(updateHandler).toHaveBeenCalledWith(
130
128
  {
@@ -164,27 +162,6 @@ describe('CapActionButton', () => {
164
162
  );
165
163
  });
166
164
 
167
- it('should show delete for quick reply index 0 for non-ICS hosts but hide it for ICS (stop button)', () => {
168
- const button = {
169
- index: 0,
170
- type: RCS_BUTTON_TYPES.QUICK_REPLY,
171
- text: 'Reply',
172
- phoneNumber: '',
173
- url: '',
174
- postback: 'Reply',
175
- isSaved: false,
176
- };
177
-
178
- // Non-ICS (Infobip/others): delete should be available
179
- const { unmount } = initializeComponent([button], false, 3, 'rcsinfobipbulk');
180
- expect(screen.getByRole('button', { name: /delete/i })).toBeInTheDocument();
181
- unmount();
182
-
183
- // ICS: index 0 is reserved; delete should be hidden
184
- initializeComponent([button], false, 3, HOST_ICS);
185
- expect(screen.queryByRole('button', { name: /delete/i })).not.toBeInTheDocument();
186
- });
187
-
188
165
  it('should respect character length limits', async () => {
189
166
  const initialData = {
190
167
  index: 0,
@@ -221,7 +198,7 @@ describe('CapActionButton', () => {
221
198
  isSaved: false,
222
199
  };
223
200
  initializeComponent([initialData]);
224
- const urlInput = await screen.getByPlaceholderText('Enter URL');
201
+ const urlInput = await screen.getByPlaceholderText('Enter website URL');
225
202
  const longUrl = 'https://example.com/' + 'a'.repeat(URL_MAX_LENGTH + 1);
226
203
  fireEvent.change(urlInput, { target: { value: longUrl, id: 0 } });
227
204
  expect(urlInput.value.length).toBeLessThanOrEqual(URL_MAX_LENGTH);
@@ -268,8 +245,7 @@ describe('CapActionButton', () => {
268
245
  { index: 0, ctaType: RCS_BUTTON_TYPES.QUICK_REPLY, displayText: 'stop', phoneNumber: '', url: '', postback: 'stop', isSaved: true },
269
246
  { index: 1, ctaType: RCS_BUTTON_TYPES.QUICK_REPLY, displayText: 'Saved', phoneNumber: '', url: '', postback: 'Saved', isSaved: true },
270
247
  ];
271
- // Use ICS host so index 0 (STOP) stays non-deletable and we only get delete icon for index 1
272
- const { container } = initializeComponent(suggestions, false, 3, HOST_ICS);
248
+ const { container } = initializeComponent(suggestions);
273
249
  const deleteIcons = container.querySelectorAll('.rcs-saved-cta-delete-icon');
274
250
  expect(deleteIcons.length).toBeGreaterThan(0);
275
251
  fireEvent.click(deleteIcons[0]);
@@ -327,8 +303,7 @@ describe('CapActionButton', () => {
327
303
  postback: 'stop',
328
304
  isSaved: true,
329
305
  };
330
- // Only ICS treats index 0 as a mandatory STOP quick reply
331
- const { container } = initializeComponent([stopButton], false, 3, HOST_ICS);
306
+ const { container } = initializeComponent([stopButton]);
332
307
  expect(container.querySelector('.rcs-saved-cta-delete-icon')).not.toBeInTheDocument();
333
308
  });
334
309
 
@@ -449,7 +424,7 @@ describe('CapActionButton', () => {
449
424
  isSaved: false,
450
425
  };
451
426
  initializeComponent([button]);
452
- expect(screen.getByPlaceholderText(/enter url/i)).toBeInTheDocument();
427
+ expect(screen.getByPlaceholderText(/enter website url/i)).toBeInTheDocument();
453
428
  });
454
429
 
455
430
  it('should update both displayText and postback when button text changes (updateDisplayAndPostback)', () => {
@@ -529,7 +504,7 @@ describe('CapActionButton', () => {
529
504
  isSaved: false,
530
505
  };
531
506
  initializeComponent([initial]);
532
- const urlInput = screen.getByPlaceholderText('Enter URL');
507
+ const urlInput = screen.getByPlaceholderText('Enter website URL');
533
508
  fireEvent.change(urlInput, { target: { value: 'http://localhost:3030/creatives/ui/v2', id: 1 } });
534
509
  expect(screen.getByText(/url is not valid/i)).toBeInTheDocument();
535
510
  });
@@ -615,7 +590,7 @@ describe('CapActionButton', () => {
615
590
  isSaved: false,
616
591
  };
617
592
  initializeComponent([initial]);
618
- const urlInput = screen.getByPlaceholderText('Enter URL');
593
+ const urlInput = screen.getByPlaceholderText('Enter website URL');
619
594
  // Enter invalid URL
620
595
  fireEvent.change(urlInput, { target: { value: 'badurl', id: 0 } });
621
596
  expect(screen.getByText(/url is not valid/i)).toBeInTheDocument();
@@ -874,14 +849,15 @@ describe('CapActionButton function logic', () => {
874
849
  expect(renderCtaOptions(label, tooltipLabel, false)).toBe('Test');
875
850
  });
876
851
 
877
- it('inner char count uses current/max format', () => {
878
- const formatMessage = (msg, values) => `${values.current}/${values.max}`;
879
- const renderInnerCharCount = (len, max) => (
880
- <span className="rcs-cta-inner-char-count">
881
- {formatMessage({}, { current: len, max })}
882
- </span>
852
+ it('renderLength returns correct CapHeading', () => {
853
+ const CapHeading = ({ type, className, children }) => <div className={className}>{children}</div>;
854
+ const formatMessage = (msg, values) => `${values.currentLength}/${values.maxLength}`;
855
+ const renderLength = (len, max) => (
856
+ <CapHeading type="label1" className="rcs-render-btn-length">
857
+ {formatMessage({}, { currentLength: len, maxLength: max })}
858
+ </CapHeading>
883
859
  );
884
- const result = renderInnerCharCount(5, 25);
860
+ const result = renderLength(5, 25);
885
861
  expect(result.props.children).toBe('5/25');
886
862
  });
887
863
  });
@@ -386,9 +386,6 @@ class CapTagList extends React.Component { // eslint-disable-line react/prefer-s
386
386
  render() {
387
387
  const {
388
388
  hidePopover = false, intl = {}, moduleFilterEnabled, label, modalProps, channel, fetchingSchemaError = false,
389
- overlayStyle,
390
- overlayClassName,
391
- getPopupContainer,
392
389
  } = this.props;
393
390
  const {formatMessage} = intl;
394
391
  const {
@@ -481,9 +478,6 @@ class CapTagList extends React.Component { // eslint-disable-line react/prefer-s
481
478
  content={contentSection}
482
479
  trigger="click"
483
480
  placement={this.props.popoverPlacement || (channel === EMAIL.toUpperCase() ? "leftTop" : "rightTop")}
484
- overlayStyle={overlayStyle}
485
- overlayClassName={overlayClassName}
486
- getPopupContainer={getPopupContainer}
487
481
  >
488
482
  <CapTooltip
489
483
  title={
@@ -555,10 +549,6 @@ CapTagList.propTypes = {
555
549
  disableTooltipMsg: PropTypes.string,
556
550
  fetchingSchemaError: PropTypes.bool,
557
551
  popoverPlacement: PropTypes.string,
558
- overlayStyle: PropTypes.object,
559
- overlayClassName: PropTypes.string,
560
- /** e.g. () => document.body — avoids overflow/stacking issues inside slideboxes */
561
- getPopupContainer: PropTypes.func,
562
552
  };
563
553
 
564
554
  CapTagList.defaultValue = {
@@ -8,7 +8,6 @@ import CapButton from '@capillarytech/cap-ui-library/CapButton';
8
8
  import CapInput from '@capillarytech/cap-ui-library/CapInput';
9
9
  import CapLabel from '@capillarytech/cap-ui-library/CapLabel';
10
10
  import messages from './messages';
11
- import { CUSTOM_VALUES_EDITOR_SECTION_FALLBACK_KEY } from './constants';
12
11
 
13
12
  const CustomValuesEditor = ({
14
13
  isExtractingTags,
@@ -17,16 +16,15 @@ const CustomValuesEditor = ({
17
16
  setShowJSON,
18
17
  customValues,
19
18
  handleJSONTextChange,
20
- sections,
19
+ extractedTags,
20
+ requiredTags,
21
+ optionalTags,
21
22
  handleCustomValueChange,
22
23
  handleDiscardCustomValues,
23
24
  handleUpdatePreview,
24
25
  isUpdatingPreview,
25
26
  formatMessage,
26
27
  }) => {
27
- /** Same as SMS Test & Preview: show token path from extract-tags (fullPath or name). */
28
- const getPersonalizationTagColumnLabel = (tagNode) => tagNode?.fullPath ?? tagNode?.name ?? '';
29
-
30
28
  if (isExtractingTags) {
31
29
  return (
32
30
  <CapRow className="loading-container">
@@ -79,68 +77,52 @@ const CustomValuesEditor = ({
79
77
  </CapRow>
80
78
  ) : (
81
79
  <>
82
- {(sections || []).filter((tagsSection) =>
83
- (tagsSection?.requiredTags?.length || 0) + (tagsSection?.optionalTags?.length || 0) > 0).map((section) => (
84
- <React.Fragment key={section.key || section.title?.id || section.title || CUSTOM_VALUES_EDITOR_SECTION_FALLBACK_KEY}>
85
- {section.title ? (
86
- <CapLabel type="label2" className="tags-section-title">
87
- {typeof section.title === 'string' ? section.title : <FormattedMessage {...section.title} />}
80
+ {extractedTags?.length > 0 && (
81
+ <CapRow className="values-table">
82
+ <CapRow className="table-header">
83
+ <CapLabel type="label31" className="header-cell">
84
+ <FormattedMessage {...messages.personalizationTags} />
88
85
  </CapLabel>
89
- ) : null}
90
- <CapRow className="values-table">
91
- <CapRow className="table-header">
92
- <CapLabel type="label31" className="header-cell">
93
- <FormattedMessage {...messages.personalizationTags} />
94
- </CapLabel>
95
- <CapLabel type="label31" className="header-cell">
96
- <FormattedMessage {...messages.customValues} />
97
- </CapLabel>
98
- </CapRow>
99
- {(section?.requiredTags || []).map((tag, tagIndex) => {
100
- const personalizationTagColumnText = getPersonalizationTagColumnLabel(tag);
101
- return (
102
- <CapRow key={tag?.fullPath ?? `required-${tagIndex}`} className="value-row">
103
- <CapRow className="tag-name">
104
- {personalizationTagColumnText}
105
- <span className="required-tag-indicator">*</span>
106
- </CapRow>
107
- <CapRow className="tag-input">
108
- <CapInput
109
- type="text"
110
- isRequired
111
- className="tag-input-field"
112
- value={customValues?.[tag?.fullPath] ?? ''}
113
- onChange={(e) => handleCustomValueChange(tag?.fullPath, e.target.value)}
114
- placeholder={formatMessage(messages.enterValue)}
115
- size="small"
116
- />
117
- </CapRow>
86
+ <CapLabel type="label31" className="header-cell">
87
+ <FormattedMessage {...messages.customValues} />
88
+ </CapLabel>
89
+ </CapRow>
90
+ {requiredTags.map((tag) => (
91
+ <CapRow key={tag.fullPath} className="value-row">
92
+ <CapRow className="tag-name">
93
+ {tag.fullPath}
94
+ <span className="required-tag-indicator">*</span>
118
95
  </CapRow>
119
- );
120
- })}
121
- {(section?.optionalTags || []).map((tag, tagIndex) => {
122
- const personalizationTagColumnText = getPersonalizationTagColumnLabel(tag);
123
- return (
124
- <CapRow key={tag?.fullPath ?? `optional-${tagIndex}`} className="value-row">
125
- <CapRow className="tag-name">
126
- {personalizationTagColumnText}
127
- </CapRow>
128
- <CapRow className="tag-input">
129
- <CapInput
130
- type="text"
131
- className="tag-input-field"
132
- value={customValues?.[tag?.fullPath] ?? ''}
133
- onChange={(e) => handleCustomValueChange(tag?.fullPath, e.target.value)}
134
- placeholder={formatMessage(messages.enterValue)}
135
- size="small"
136
- />
137
- </CapRow>
96
+ <CapRow className="tag-input">
97
+ <CapInput
98
+ type="text"
99
+ isRequired
100
+ className="tag-input-field"
101
+ value={customValues[tag.fullPath] || ''}
102
+ onChange={(e) => handleCustomValueChange(tag.fullPath, e.target.value)}
103
+ placeholder={formatMessage(messages.enterValue)}
104
+ size="small"
105
+ />
138
106
  </CapRow>
139
- );
140
- })}
141
- </CapRow>
142
- </React.Fragment>
143
- ))}
107
+ </CapRow>
108
+ ))}
109
+ {optionalTags?.map((tag) => (
110
+ <CapRow key={tag.fullPath} className="value-row">
111
+ <CapRow className="tag-name">{tag.fullPath}</CapRow>
112
+ <CapRow className="tag-input">
113
+ <CapInput
114
+ type="text"
115
+ className="tag-input-field"
116
+ value={customValues[tag.fullPath] || ''}
117
+ onChange={(e) => handleCustomValueChange(tag.fullPath, e.target.value)}
118
+ placeholder={formatMessage(messages.enterValue)}
119
+ size="small"
120
+ />
121
+ </CapRow>
122
+ </CapRow>
123
+ ))}
124
+ </CapRow>
125
+ )}
144
126
  </>
145
127
  )}
146
128
  <CapRow className="editor-actions">
@@ -174,12 +156,9 @@ CustomValuesEditor.propTypes = {
174
156
  setShowJSON: PropTypes.func.isRequired,
175
157
  customValues: PropTypes.object.isRequired,
176
158
  handleJSONTextChange: PropTypes.func.isRequired,
177
- sections: PropTypes.arrayOf(PropTypes.shape({
178
- key: PropTypes.string,
179
- title: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
180
- requiredTags: PropTypes.array,
181
- optionalTags: PropTypes.array,
182
- })).isRequired,
159
+ extractedTags: PropTypes.array.isRequired,
160
+ requiredTags: PropTypes.array.isRequired,
161
+ optionalTags: PropTypes.array.isRequired,
183
162
  handleCustomValueChange: PropTypes.func.isRequired,
184
163
  handleDiscardCustomValues: PropTypes.func.isRequired,
185
164
  handleUpdatePreview: PropTypes.func.isRequired,
@@ -18,17 +18,11 @@
18
18
  }
19
19
 
20
20
  &__summary-entry {
21
- display: flex;
22
- align-items: baseline;
23
- gap: 0;
24
21
  margin-right: $CAP_SPACE_18;
25
22
  }
26
23
 
27
- &__summary-key,
28
- &__summary-value {
29
- line-height: 1.4;
30
- margin-top: 0;
31
- margin-bottom: 0;
24
+ &__summary-key {
25
+ line-height: $CAP_SPACE_16;
32
26
  }
33
27
 
34
28
  &__edit-icon {