@capillarytech/creatives-library 9.0.15-alpha.3 → 9.0.16-beta.0
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.
- package/AppRoot.js +80 -0
- package/app.js +5 -3
- package/constants/unified.js +0 -29
- package/entry.js +67 -1
- package/global-styles.js +1 -1
- package/mfe-exposed-components.js +2 -4
- package/package.json +2 -2
- package/services/api.js +1 -1
- package/services/tests/api.test.js +20 -35
- package/styles/containers/layout/_layoutPage.scss +8 -6
- package/utils/commonUtils.js +1 -19
- package/utils/getDataLayer.js +15 -0
- package/utils/gtmTrackers/gtmEvents/creativeDetails.js +2 -1
- package/utils/mfeDetect.js +1 -0
- package/v2Components/CapActionButton/constants.js +1 -8
- package/v2Components/CapActionButton/index.js +144 -202
- package/v2Components/CapActionButton/index.scss +14 -232
- package/v2Components/CapActionButton/messages.js +3 -19
- package/v2Components/CapActionButton/tests/index.test.js +18 -42
- package/v2Components/CapImageUpload/index.js +2 -2
- package/v2Components/CapTagList/index.js +0 -10
- package/v2Components/CommonTestAndPreview/CustomValuesEditor.js +48 -70
- package/v2Components/CommonTestAndPreview/DeliverySettings/DeliverySettings.scss +2 -8
- package/v2Components/CommonTestAndPreview/DeliverySettings/ModifyDeliverySettings.js +21 -214
- package/v2Components/CommonTestAndPreview/DeliverySettings/constants.js +0 -16
- package/v2Components/CommonTestAndPreview/DeliverySettings/index.js +9 -83
- package/v2Components/CommonTestAndPreview/DeliverySettings/messages.js +0 -30
- package/v2Components/CommonTestAndPreview/DeliverySettings/utils/parseSenderDetailsResponse.js +11 -60
- package/v2Components/CommonTestAndPreview/SendTestMessage.js +5 -10
- package/v2Components/CommonTestAndPreview/UnifiedPreview/RcsPreviewContent.js +22 -202
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +80 -381
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +8 -155
- package/v2Components/CommonTestAndPreview/_commonTestAndPreview.scss +0 -11
- package/v2Components/CommonTestAndPreview/constants.js +2 -38
- package/v2Components/CommonTestAndPreview/index.js +222 -761
- package/v2Components/CommonTestAndPreview/messages.js +3 -45
- package/v2Components/CommonTestAndPreview/sagas.js +6 -25
- package/v2Components/CommonTestAndPreview/tests/CommonTestAndPreview.addTestCustomer.test.js +0 -1
- package/v2Components/CommonTestAndPreview/tests/CustomValuesEditor.test.js +267 -284
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/ModifyDeliverySettings.test.js +65 -231
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/index.test.js +5 -118
- package/v2Components/CommonTestAndPreview/tests/DeliverySettings/utils/parseSenderDetailsResponse.test.js +0 -341
- package/v2Components/CommonTestAndPreview/tests/PreviewSection.test.js +1 -8
- package/v2Components/CommonTestAndPreview/tests/SendTestMessage.test.js +13 -34
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/RcsPreviewContent.test.js +283 -281
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +1 -199
- package/v2Components/CommonTestAndPreview/tests/index.test.js +4 -133
- package/v2Components/CommonTestAndPreview/tests/sagas.test.js +24 -31
- package/v2Components/NavigationBar/index.js +9 -7
- package/v2Components/NavigationBar/mfeModuleHeader.config.js +16 -0
- package/v2Components/Pagination/_pagination.scss +2 -0
- package/v2Components/TemplatePreview/_templatePreview.scss +25 -45
- package/v2Components/TemplatePreview/index.js +32 -147
- package/v2Components/TemplatePreview/tests/index.test.js +0 -142
- package/v2Components/TestAndPreviewSlidebox/CustomValuesEditor.js +6 -6
- package/v2Components/TestAndPreviewSlidebox/index.js +1 -13
- package/v2Components/TestAndPreviewSlidebox/sagas.js +4 -11
- package/v2Components/TestAndPreviewSlidebox/tests/saga.test.js +1 -3
- package/v2Containers/Cap/constants.js +1 -0
- package/v2Containers/Cap/index.js +47 -21
- package/v2Containers/Cap/sagas.js +19 -0
- package/v2Containers/CommunicationFlow/Tests/CommunicationFlow.test.js +1 -4
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/DeliverySettingsSection.test.js +0 -4
- package/v2Containers/CommunicationFlow/steps/DeliverySettingsStep/Tests/SenderDetails.test.js +20 -20
- package/v2Containers/CreativesContainer/SlideBoxContent.js +7 -37
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +5 -14
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +5 -36
- package/v2Containers/CreativesContainer/constants.js +0 -11
- package/v2Containers/CreativesContainer/index.js +104 -323
- package/v2Containers/CreativesContainer/index.scss +1 -83
- package/v2Containers/CreativesContainer/tests/SlideBoxFooter.test.js +34 -79
- package/v2Containers/CreativesContainer/tests/SlideBoxHeader.test.js +16 -79
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -8
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxHeader.test.js.snap +90 -333
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +15 -20
- package/v2Containers/CreativesContainer/tests/index.test.js +9 -71
- package/v2Containers/MobilePush/Create/test/saga.test.js +2 -2
- package/v2Containers/Rcs/constants.js +11 -131
- package/v2Containers/Rcs/index.js +829 -2682
- package/v2Containers/Rcs/index.scss +8 -443
- package/v2Containers/Rcs/messages.js +6 -45
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +39409 -74176
- package/v2Containers/Rcs/tests/__snapshots__/utils.test.js.snap +74 -10
- package/v2Containers/Rcs/tests/index.test.js +40 -151
- package/v2Containers/Rcs/tests/mockData.js +0 -38
- package/v2Containers/Rcs/tests/utils.test.js +30 -643
- package/v2Containers/Rcs/utils.js +12 -466
- package/v2Containers/Sms/Create/index.js +48 -115
- package/v2Containers/SmsTrai/Create/index.js +4 -9
- package/v2Containers/SmsTrai/Edit/constants.js +0 -2
- package/v2Containers/SmsTrai/Edit/index.js +169 -678
- package/v2Containers/SmsTrai/Edit/messages.js +4 -14
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +2854 -5455
- package/v2Containers/SmsWrapper/index.js +8 -37
- package/v2Containers/TagList/index.js +0 -6
- package/v2Containers/Templates/_templates.scss +11 -196
- package/v2Containers/Templates/actions.js +0 -11
- package/v2Containers/Templates/constants.js +0 -2
- package/v2Containers/Templates/index.js +60 -131
- package/v2Containers/Templates/sagas.js +13 -57
- package/v2Containers/Templates/tests/__snapshots__/index.test.js.snap +1015 -1060
- package/v2Containers/Templates/tests/sagas.test.js +16 -199
- package/v2Containers/TemplatesV2/TemplatesV2.style.js +10 -75
- package/v2Containers/TemplatesV2/index.js +43 -86
- package/v2Containers/WeChat/MapTemplates/test/saga.test.js +9 -9
- package/v2Containers/Whatsapp/index.js +25 -4
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +34 -578
- package/utils/rcsPayloadUtils.js +0 -92
- package/utils/templateVarUtils.js +0 -201
- package/utils/tests/rcsPayloadUtils.test.js +0 -226
- package/utils/tests/templateVarUtils.test.js +0 -204
- package/v2Components/CommonTestAndPreview/previewApiUtils.js +0 -59
- package/v2Components/CommonTestAndPreview/tests/previewApiUtils.test.js +0 -67
- package/v2Components/CommonTestAndPreview/utils.js +0 -84
- package/v2Components/SmsFallback/SmsFallbackLocalSelector.js +0 -91
- package/v2Components/SmsFallback/constants.js +0 -94
- package/v2Components/SmsFallback/index.js +0 -958
- package/v2Components/SmsFallback/index.scss +0 -266
- package/v2Components/SmsFallback/messages.js +0 -78
- package/v2Components/SmsFallback/smsFallbackUtils.js +0 -120
- package/v2Components/SmsFallback/tests/SmsFallbackLocalSelector.test.js +0 -50
- package/v2Components/SmsFallback/tests/rcsSmsFallback.acceptance.test.js +0 -147
- package/v2Components/SmsFallback/tests/smsFallbackHandlers.test.js +0 -304
- package/v2Components/SmsFallback/tests/smsFallbackUi.test.js +0 -208
- package/v2Components/SmsFallback/tests/smsFallbackUtils.test.js +0 -309
- package/v2Components/SmsFallback/tests/useLocalTemplateList.test.js +0 -422
- package/v2Components/SmsFallback/useLocalTemplateList.js +0 -92
- package/v2Components/TemplatePreview/constants.js +0 -2
- package/v2Components/VarSegmentMessageEditor/constants.js +0 -2
- package/v2Components/VarSegmentMessageEditor/index.js +0 -125
- package/v2Components/VarSegmentMessageEditor/index.scss +0 -46
- package/v2Containers/CreativesContainer/CreativesSlideBoxWrapper.js +0 -17
- package/v2Containers/CreativesContainer/embeddedSlideboxUtils.js +0 -79
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.localTemplates.test.js +0 -90
- package/v2Containers/CreativesContainer/tests/embeddedSlideboxUtils.test.js +0 -258
- package/v2Containers/CreativesContainer/tests/useLocalTemplatesProp.test.js +0 -125
- package/v2Containers/Rcs/rcsLibraryHydrationUtils.js +0 -227
- package/v2Containers/Rcs/tests/rcsLibraryHydrationUtils.test.js +0 -318
- package/v2Containers/Sms/smsFormDataHelpers.js +0 -67
- package/v2Containers/Sms/tests/smsFormDataHelpers.test.js +0 -253
- package/v2Containers/SmsTrai/Edit/index.scss +0 -126
- package/v2Containers/Templates/TemplatesActionBar.js +0 -101
- package/v2Containers/Templates/tests/TemplatesActionBar.test.js +0 -120
- package/v2Containers/Templates/tests/smsTemplatesListApi.test.js +0 -180
- package/v2Containers/Templates/utils/smsTemplatesListApi.js +0 -79
- package/v2Containers/TemplatesV2/tests/TemplatesV2.localTemplates.test.js +0 -131
|
@@ -1,20 +1,7 @@
|
|
|
1
1
|
@import '~@capillarytech/cap-ui-library/styles/_variables';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
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 {
|
|
@@ -23,36 +10,13 @@
|
|
|
23
10
|
padding: 0.625rem;
|
|
24
11
|
border-radius: $CAP_SPACE_04;
|
|
25
12
|
margin-bottom: $CAP_SPACE_12;
|
|
26
|
-
flex-wrap: nowrap;
|
|
27
13
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// span that has to add up to exactly 24 alongside its siblings — with a
|
|
31
|
-
// fixed span, the gutter/margin between columns had nowhere to come from
|
|
32
|
-
// and pushed this column's content past the card's right border.
|
|
33
|
-
.rcs-saved-cta-value-column {
|
|
34
|
-
min-width: 0;
|
|
14
|
+
div:not(:last-child) {
|
|
15
|
+
margin-right: 0.5625rem;
|
|
35
16
|
}
|
|
36
17
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// instead of the old fixed-span column + absolutely-positioned icon combo
|
|
40
|
-
// (which drifted out of alignment with variable-length URLs/numbers).
|
|
41
|
-
.rcs-saved-cta-value-actions {
|
|
42
|
-
display: flex;
|
|
43
|
-
align-items: center;
|
|
44
|
-
justify-content: flex-end;
|
|
45
|
-
gap: $CAP_SPACE_08;
|
|
46
|
-
width: 100%;
|
|
47
|
-
min-width: 0;
|
|
48
|
-
|
|
49
|
-
.url-type {
|
|
50
|
-
flex-shrink: 0;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
.url, .phone {
|
|
54
|
-
min-width: 0;
|
|
55
|
-
}
|
|
18
|
+
.rcs-url-preview-wrapper {
|
|
19
|
+
max-width: 5.714rem;
|
|
56
20
|
}
|
|
57
21
|
|
|
58
22
|
.url {
|
|
@@ -73,189 +37,20 @@
|
|
|
73
37
|
font-weight: 500;
|
|
74
38
|
}
|
|
75
39
|
|
|
76
|
-
.rcs-saved-cta-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
gap: $CAP_SPACE_08;
|
|
80
|
-
flex-shrink: 0;
|
|
40
|
+
.rcs-saved-cta-edit-icon {
|
|
41
|
+
position: absolute;
|
|
42
|
+
right: 0.4375rem;
|
|
81
43
|
}
|
|
82
44
|
|
|
83
|
-
.rcs-saved-cta-edit-icon,
|
|
84
45
|
.rcs-saved-cta-delete-icon {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Button text / URL: count via CapInput `suffix` (antd affix, right-aligned inside field).
|
|
90
|
-
// Phone: react-phone-input-2 — overlay count + padding on .form-control
|
|
91
|
-
// Selector needs `.cap-heading.h5` too — CapHeading's own `.cap-heading.h5` rule (2 classes)
|
|
92
|
-
// otherwise beats a single-class `.rcs-cta-inner-char-count` selector and forces dark text,
|
|
93
|
-
// regardless of source order (light-grey placeholder look per Figma).
|
|
94
|
-
.cap-heading.h5.rcs-cta-inner-char-count {
|
|
95
|
-
font-size: 0.75rem;
|
|
96
|
-
line-height: 1.25rem;
|
|
97
|
-
color: $FONT_COLOR_03;
|
|
98
|
-
white-space: nowrap;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Button text: match the phone field's full-width treatment (Figma reference).
|
|
102
|
-
// `className` on CapInput lands on componentWithLabelHOC's OUTER wrapper div
|
|
103
|
-
// (confirmed via rendered DOM), not on the `.ant-input-affix-wrapper` itself —
|
|
104
|
-
// force the wrapper full-width directly rather than relying on descendant rules.
|
|
105
|
-
.rcs-cta-button-text {
|
|
106
|
-
width: 100%;
|
|
107
|
-
|
|
108
|
-
.ant-input-affix-wrapper {
|
|
109
|
-
width: 100%;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.rcs-cta-input-with-inner-count {
|
|
114
|
-
position: relative;
|
|
115
|
-
width: 100%;
|
|
116
|
-
|
|
117
|
-
&--phone .rcs-cta-inner-char-count {
|
|
118
|
-
position: absolute;
|
|
119
|
-
right: 0.6875rem;
|
|
120
|
-
top: 50%;
|
|
121
|
-
transform: translateY(-50%);
|
|
122
|
-
z-index: 2;
|
|
123
|
-
pointer-events: none;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// RCS phone field: Figma — one light border, 4px radius, ~antd Input large height, full width, count inside right
|
|
128
|
-
.rcs-button-cta-create-container .rcs-cta-input-with-inner-count--phone {
|
|
129
|
-
.react-tel-input.rcs-cta-phone-input {
|
|
130
|
-
width: 100%;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
.rcs-cta-phone-input .form-control {
|
|
134
|
-
width: 100% !important;
|
|
135
|
-
max-width: none;
|
|
136
|
-
height: 2.5rem;
|
|
137
|
-
min-height: 2.5rem;
|
|
138
|
-
padding-top: 0;
|
|
139
|
-
padding-bottom: 0;
|
|
140
|
-
padding-left: 3rem;
|
|
141
|
-
padding-right: 3.5rem;
|
|
142
|
-
margin: 0;
|
|
143
|
-
font-size: 0.875rem;
|
|
144
|
-
line-height: 2.5rem;
|
|
145
|
-
color: $CAP_G01;
|
|
146
|
-
background: $CAP_WHITE;
|
|
147
|
-
border: 1px solid $CAP_G06;
|
|
148
|
-
border-radius: 0.25rem;
|
|
149
|
-
box-shadow: none;
|
|
150
|
-
|
|
151
|
-
&::placeholder {
|
|
152
|
-
color: $CAP_G05;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
&:hover {
|
|
156
|
-
border-color: $CAP_G11;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
&:focus {
|
|
160
|
-
border-color: $CAP_G01;
|
|
161
|
-
box-shadow: none;
|
|
162
|
-
outline: none;
|
|
46
|
+
position: absolute;
|
|
47
|
+
right: $CAP_SPACE_02;
|
|
163
48
|
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// The flag-dropdown sits on top of .form-control's left edge, so hovering the
|
|
167
|
-
// flag itself doesn't trigger `.form-control:hover` — bind the border-color
|
|
168
|
-
// change to the whole wrapper so the border reacts consistently everywhere.
|
|
169
|
-
.react-tel-input.rcs-cta-phone-input:hover .form-control {
|
|
170
|
-
border-color: $CAP_G11;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
.react-tel-input.rcs-cta-phone-input:focus-within .form-control {
|
|
174
|
-
border-color: $CAP_G01;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
.rcs-cta-phone-input .flag-dropdown {
|
|
178
|
-
// Raw px, not rem: must exactly match .form-control's 1px border width.
|
|
179
|
-
// At this app's 14px root font-size, 0.0625rem resolved to 0.875px — the
|
|
180
|
-
// sub-pixel gap left the outer border looking "cut off" right where the
|
|
181
|
-
// flag-dropdown's opaque background sat, most visible on hover when the
|
|
182
|
-
// border color changed and made the gap's anti-aliasing stand out.
|
|
183
|
-
top: 1px;
|
|
184
|
-
bottom: 1px;
|
|
185
|
-
left: 1px;
|
|
186
|
-
padding: 0;
|
|
187
|
-
background: $CAP_WHITE;
|
|
188
|
-
border: none;
|
|
189
|
-
border-radius: 0.1875rem 0 0 0.1875rem; // inset from outer 4px radius
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
.rcs-cta-phone-input .flag-dropdown.open {
|
|
193
|
-
border-radius: 0.1875rem 0 0 0;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
.rcs-cta-phone-input .selected-flag {
|
|
197
|
-
width: 2.75rem;
|
|
198
|
-
padding: 0 0 0 0.5rem;
|
|
199
|
-
background: transparent;
|
|
200
|
-
border-radius: 0.1875rem 0 0 0.1875rem;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
.rcs-cta-phone-input .selected-flag:hover,
|
|
204
|
-
.rcs-cta-phone-input .selected-flag:focus {
|
|
205
|
-
background: $CAP_G09;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
.rcs-cta-phone-input .selected-flag .arrow {
|
|
209
|
-
left: 1.375rem;
|
|
210
|
-
border-top-color: $CAP_G04;
|
|
211
|
-
}
|
|
212
49
|
}
|
|
213
50
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
width: 100%;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// RCS “create CTA” card: 0.5rem padding + gaps (Figma-tight; fixes excess space above first label)
|
|
222
|
-
.rcs-button-cta-create-container.cap-row-v2 {
|
|
223
|
-
display: flex;
|
|
224
|
-
flex-direction: column;
|
|
225
|
-
// Cross-axis (=width, since this is a column-flex row) defaults to `align-items: flex-start`
|
|
226
|
-
// via antd's `.ant-row-top`, which lets child Cols shrink to content instead of filling the
|
|
227
|
-
// row — same issue CapRow's own `.cap-row-vertical` guards against. Force stretch here too,
|
|
228
|
-
// otherwise fields with no explicit width of their own (e.g. Button text) render too narrow.
|
|
229
|
-
align-items: stretch;
|
|
230
|
-
flex-wrap: nowrap;
|
|
231
|
-
width: 100%;
|
|
232
|
-
border: solid 1px $CAP_G06;
|
|
233
|
-
padding: 1.25rem;
|
|
234
|
-
border-radius: 0.25rem; // 4px — match .cap-rcs-saved-cta
|
|
235
|
-
|
|
236
|
-
// Stack “Button type” (radios) above “Button text”
|
|
237
|
-
.rcs-button-cta-create.cap-row-v2 {
|
|
238
|
-
display: flex;
|
|
239
|
-
flex-direction: column;
|
|
240
|
-
align-items: stretch;
|
|
241
|
-
flex-wrap: nowrap;
|
|
242
|
-
margin: 0;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Space after each field label (CapHeading margins are often zeroed by the library)
|
|
246
|
-
.cta-label {
|
|
247
|
-
margin-bottom: 0;
|
|
248
|
-
margin-top: 0.75rem;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
.cta-label + * {
|
|
252
|
-
margin-top: 0.5rem;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// “Button type” heading has no .cta-label — keep same label→control gap as other fields
|
|
256
|
-
.rcs-button-cta-create > .ant-col:first-of-type .cap-rcs-cta-type-radio {
|
|
257
|
-
margin-top: 0.5rem;
|
|
258
|
-
}
|
|
51
|
+
.rcs-button-cta-create-container {
|
|
52
|
+
border: solid 1px $CAP_G06;
|
|
53
|
+
padding: 10px;
|
|
259
54
|
}
|
|
260
55
|
|
|
261
56
|
.disabled {
|
|
@@ -270,16 +65,3 @@
|
|
|
270
65
|
.button-disabled-tooltip-wrapper {
|
|
271
66
|
display: inline-block;
|
|
272
67
|
}
|
|
273
|
-
|
|
274
|
-
// Space above Save/Delete row: kept on this stable outer wrapper (not on
|
|
275
|
-
// .button-disabled-tooltip-wrapper) since that inner CapRow's own display
|
|
276
|
-
// (flex vs inline-block) flips depending on whether CapTooltip renders its
|
|
277
|
-
// extra trigger span (title set vs empty), which made the gap disappear
|
|
278
|
-
// whenever the Save button was enabled.
|
|
279
|
-
.rcs-cta-save-delete-btn {
|
|
280
|
-
margin-top: 1.25rem;
|
|
281
|
-
|
|
282
|
-
.rcs-cta-delete-btn {
|
|
283
|
-
margin-left: 0.75rem;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
@@ -12,7 +12,7 @@ export default defineMessages({
|
|
|
12
12
|
},
|
|
13
13
|
ctaQr: {
|
|
14
14
|
id: `${prefix}.ctaQr`,
|
|
15
|
-
defaultMessage: 'Quick
|
|
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: '
|
|
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
|
|
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`,
|
|
@@ -5,7 +5,7 @@ import { render, screen, fireEvent } from '../../../utils/test-utils';
|
|
|
5
5
|
import { waitFor } from '@testing-library/react';
|
|
6
6
|
import { CapActionButton } from '../index';
|
|
7
7
|
import { BTN_MAX_LENGTH, PHONE_NUMBER_MAX_LENGTH, URL_MAX_LENGTH } from '../constants';
|
|
8
|
-
import { RCS_BUTTON_TYPES
|
|
8
|
+
import { RCS_BUTTON_TYPES } from '../../../v2Containers/Rcs/constants';
|
|
9
9
|
|
|
10
10
|
const updateHandler = jest.fn();
|
|
11
11
|
const deleteHandler = jest.fn();
|
|
@@ -13,7 +13,6 @@ const initializeComponent = (
|
|
|
13
13
|
data,
|
|
14
14
|
isEditFlow = false,
|
|
15
15
|
maxButtons = 3,
|
|
16
|
-
host = '',
|
|
17
16
|
) => {
|
|
18
17
|
// Normalize legacy test data shape to match component props
|
|
19
18
|
const normalizeType = (legacyType) => {
|
|
@@ -39,7 +38,6 @@ const initializeComponent = (
|
|
|
39
38
|
isEditFlow={isEditFlow}
|
|
40
39
|
maxButtons={maxButtons}
|
|
41
40
|
isFullMode={true}
|
|
42
|
-
host={host}
|
|
43
41
|
/>,
|
|
44
42
|
);
|
|
45
43
|
};
|
|
@@ -62,7 +60,7 @@ describe('CapActionButton', () => {
|
|
|
62
60
|
isSaved: false,
|
|
63
61
|
},
|
|
64
62
|
]);
|
|
65
|
-
expect(screen.getByText('
|
|
63
|
+
expect(screen.getByText('Type of action')).toBeInTheDocument();
|
|
66
64
|
expect(screen.getByText('Button text')).toBeInTheDocument();
|
|
67
65
|
expect(screen.getAllByText('Phone number')[1]).toBeInTheDocument();
|
|
68
66
|
expect(screen.getByRole('button', { name: /save/i })).toBeDisabled();
|
|
@@ -125,7 +123,7 @@ describe('CapActionButton', () => {
|
|
|
125
123
|
id: 1,
|
|
126
124
|
},
|
|
127
125
|
};
|
|
128
|
-
const urlInput = await screen.getByPlaceholderText('Enter URL');
|
|
126
|
+
const urlInput = await screen.getByPlaceholderText('Enter website URL');
|
|
129
127
|
fireEvent.change(urlInput, urlEvent);
|
|
130
128
|
expect(updateHandler).toHaveBeenCalledWith(
|
|
131
129
|
{
|
|
@@ -165,27 +163,6 @@ describe('CapActionButton', () => {
|
|
|
165
163
|
);
|
|
166
164
|
});
|
|
167
165
|
|
|
168
|
-
it('should show delete for quick reply index 0 for non-ICS hosts but hide it for ICS (stop button)', () => {
|
|
169
|
-
const button = {
|
|
170
|
-
index: 0,
|
|
171
|
-
type: RCS_BUTTON_TYPES.QUICK_REPLY,
|
|
172
|
-
text: 'Reply',
|
|
173
|
-
phoneNumber: '',
|
|
174
|
-
url: '',
|
|
175
|
-
postback: 'Reply',
|
|
176
|
-
isSaved: false,
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
// Non-ICS (Infobip/others): delete should be available
|
|
180
|
-
const { unmount } = initializeComponent([button], false, 3, 'rcsinfobipbulk');
|
|
181
|
-
expect(screen.getByRole('button', { name: /delete/i })).toBeInTheDocument();
|
|
182
|
-
unmount();
|
|
183
|
-
|
|
184
|
-
// ICS: index 0 is reserved; delete should be hidden
|
|
185
|
-
initializeComponent([button], false, 3, HOST_ICS);
|
|
186
|
-
expect(screen.queryByRole('button', { name: /delete/i })).not.toBeInTheDocument();
|
|
187
|
-
});
|
|
188
|
-
|
|
189
166
|
it('should respect character length limits', async () => {
|
|
190
167
|
const initialData = {
|
|
191
168
|
index: 0,
|
|
@@ -224,7 +201,7 @@ describe('CapActionButton', () => {
|
|
|
224
201
|
isSaved: false,
|
|
225
202
|
};
|
|
226
203
|
initializeComponent([initialData]);
|
|
227
|
-
const urlInput = await screen.getByPlaceholderText('Enter URL');
|
|
204
|
+
const urlInput = await screen.getByPlaceholderText('Enter website URL');
|
|
228
205
|
const longUrl = 'https://example.com/' + 'a'.repeat(URL_MAX_LENGTH + 1);
|
|
229
206
|
fireEvent.change(urlInput, { target: { value: longUrl, id: 0 } });
|
|
230
207
|
expect(urlInput.value.length).toBeLessThanOrEqual(URL_MAX_LENGTH);
|
|
@@ -271,8 +248,7 @@ describe('CapActionButton', () => {
|
|
|
271
248
|
{ index: 0, ctaType: RCS_BUTTON_TYPES.QUICK_REPLY, displayText: 'stop', phoneNumber: '', url: '', postback: 'stop', isSaved: true },
|
|
272
249
|
{ index: 1, ctaType: RCS_BUTTON_TYPES.QUICK_REPLY, displayText: 'Saved', phoneNumber: '', url: '', postback: 'Saved', isSaved: true },
|
|
273
250
|
];
|
|
274
|
-
|
|
275
|
-
const { container } = initializeComponent(suggestions, false, 3, HOST_ICS);
|
|
251
|
+
const { container } = initializeComponent(suggestions);
|
|
276
252
|
const deleteIcons = container.querySelectorAll('.rcs-saved-cta-delete-icon');
|
|
277
253
|
expect(deleteIcons.length).toBeGreaterThan(0);
|
|
278
254
|
fireEvent.click(deleteIcons[0]);
|
|
@@ -330,8 +306,7 @@ describe('CapActionButton', () => {
|
|
|
330
306
|
postback: 'stop',
|
|
331
307
|
isSaved: true,
|
|
332
308
|
};
|
|
333
|
-
|
|
334
|
-
const { container } = initializeComponent([stopButton], false, 3, HOST_ICS);
|
|
309
|
+
const { container } = initializeComponent([stopButton]);
|
|
335
310
|
expect(container.querySelector('.rcs-saved-cta-delete-icon')).not.toBeInTheDocument();
|
|
336
311
|
});
|
|
337
312
|
|
|
@@ -452,7 +427,7 @@ describe('CapActionButton', () => {
|
|
|
452
427
|
isSaved: false,
|
|
453
428
|
};
|
|
454
429
|
initializeComponent([button]);
|
|
455
|
-
expect(screen.getByPlaceholderText(/enter url/i)).toBeInTheDocument();
|
|
430
|
+
expect(screen.getByPlaceholderText(/enter website url/i)).toBeInTheDocument();
|
|
456
431
|
});
|
|
457
432
|
|
|
458
433
|
it('should update both displayText and postback when button text changes (updateDisplayAndPostback)', () => {
|
|
@@ -532,7 +507,7 @@ describe('CapActionButton', () => {
|
|
|
532
507
|
isSaved: false,
|
|
533
508
|
};
|
|
534
509
|
initializeComponent([initial]);
|
|
535
|
-
const urlInput = screen.getByPlaceholderText('Enter URL');
|
|
510
|
+
const urlInput = screen.getByPlaceholderText('Enter website URL');
|
|
536
511
|
fireEvent.change(urlInput, { target: { value: 'http://localhost:3030/creatives/ui/v2', id: 1 } });
|
|
537
512
|
expect(screen.getByText(/url is not valid/i)).toBeInTheDocument();
|
|
538
513
|
});
|
|
@@ -632,12 +607,12 @@ describe('CapActionButton', () => {
|
|
|
632
607
|
);
|
|
633
608
|
};
|
|
634
609
|
render(<StatefulWrapper />);
|
|
635
|
-
let urlInput = screen.getByPlaceholderText('Enter URL');
|
|
610
|
+
let urlInput = screen.getByPlaceholderText('Enter website URL');
|
|
636
611
|
// Enter invalid URL
|
|
637
612
|
fireEvent.change(urlInput, { target: { value: 'badurl', id: 0 } });
|
|
638
613
|
expect(await screen.findByText(/url is not valid/i)).toBeInTheDocument();
|
|
639
614
|
// Re-grab input after re-render and enter valid URL
|
|
640
|
-
urlInput = screen.getByPlaceholderText('Enter URL');
|
|
615
|
+
urlInput = screen.getByPlaceholderText('Enter website URL');
|
|
641
616
|
fireEvent.change(urlInput, { target: { value: 'https://good.com', id: 0 } });
|
|
642
617
|
await waitFor(() => expect(screen.queryByText(/url is not valid/i)).not.toBeInTheDocument());
|
|
643
618
|
});
|
|
@@ -892,14 +867,15 @@ describe('CapActionButton function logic', () => {
|
|
|
892
867
|
expect(renderCtaOptions(label, tooltipLabel, false)).toBe('Test');
|
|
893
868
|
});
|
|
894
869
|
|
|
895
|
-
it('
|
|
896
|
-
const
|
|
897
|
-
const
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
870
|
+
it('renderLength returns correct CapHeading', () => {
|
|
871
|
+
const CapHeading = ({ type, className, children }) => <div className={className}>{children}</div>;
|
|
872
|
+
const formatMessage = (msg, values) => `${values.currentLength}/${values.maxLength}`;
|
|
873
|
+
const renderLength = (len, max) => (
|
|
874
|
+
<CapHeading type="label1" className="rcs-render-btn-length">
|
|
875
|
+
{formatMessage({}, { currentLength: len, maxLength: max })}
|
|
876
|
+
</CapHeading>
|
|
901
877
|
);
|
|
902
|
-
const result =
|
|
878
|
+
const result = renderLength(5, 25);
|
|
903
879
|
expect(result.props.children).toBe('5/25');
|
|
904
880
|
});
|
|
905
881
|
});
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import React, { useState, useEffect, useCallback
|
|
8
|
+
import React, { useState, useEffect, useCallback } from 'react';
|
|
9
9
|
import PropTypes from "prop-types";
|
|
10
10
|
|
|
11
11
|
import LabelHOC from '@capillarytech/cap-ui-library/assets/HOCs/ComponentWithLabelHOC';
|
|
@@ -92,7 +92,7 @@ function CapImageUpload(props) {
|
|
|
92
92
|
[imageSrc],
|
|
93
93
|
);
|
|
94
94
|
|
|
95
|
-
const WithLabel =
|
|
95
|
+
const WithLabel = LabelHOC(ImageComponent);
|
|
96
96
|
|
|
97
97
|
const uploadImages = useCallback((e, { files }) => {
|
|
98
98
|
if (e) {
|
|
@@ -346,9 +346,6 @@ class CapTagList extends React.Component { // eslint-disable-line react/prefer-s
|
|
|
346
346
|
render() {
|
|
347
347
|
const {
|
|
348
348
|
hidePopover = false, intl = {}, moduleFilterEnabled, label, modalProps, channel, fetchingSchemaError = false,
|
|
349
|
-
overlayStyle,
|
|
350
|
-
overlayClassName,
|
|
351
|
-
getPopupContainer,
|
|
352
349
|
} = this.props;
|
|
353
350
|
const {formatMessage} = intl;
|
|
354
351
|
const {
|
|
@@ -442,9 +439,6 @@ class CapTagList extends React.Component { // eslint-disable-line react/prefer-s
|
|
|
442
439
|
classNames={{
|
|
443
440
|
container: 'tag-list-popover-container'
|
|
444
441
|
}}
|
|
445
|
-
overlayStyle={overlayStyle}
|
|
446
|
-
overlayClassName={overlayClassName}
|
|
447
|
-
getPopupContainer={getPopupContainer}
|
|
448
442
|
>
|
|
449
443
|
<CapTooltip
|
|
450
444
|
title={
|
|
@@ -516,10 +510,6 @@ CapTagList.propTypes = {
|
|
|
516
510
|
disableTooltipMsg: PropTypes.string,
|
|
517
511
|
fetchingSchemaError: PropTypes.bool,
|
|
518
512
|
popoverPlacement: PropTypes.string,
|
|
519
|
-
overlayStyle: PropTypes.object,
|
|
520
|
-
overlayClassName: PropTypes.string,
|
|
521
|
-
/** e.g. () => document.body — avoids overflow/stacking issues inside slideboxes */
|
|
522
|
-
getPopupContainer: PropTypes.func,
|
|
523
513
|
};
|
|
524
514
|
|
|
525
515
|
CapTagList.defaultValue = {
|
|
@@ -8,8 +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
|
-
import { getPersonalizationTagColumnLabel } from './utils';
|
|
13
11
|
|
|
14
12
|
const CustomValuesEditor = ({
|
|
15
13
|
isExtractingTags,
|
|
@@ -18,7 +16,9 @@ const CustomValuesEditor = ({
|
|
|
18
16
|
setShowJSON,
|
|
19
17
|
customValues,
|
|
20
18
|
handleJSONTextChange,
|
|
21
|
-
|
|
19
|
+
extractedTags,
|
|
20
|
+
requiredTags,
|
|
21
|
+
optionalTags,
|
|
22
22
|
handleCustomValueChange,
|
|
23
23
|
handleDiscardCustomValues,
|
|
24
24
|
handleUpdatePreview,
|
|
@@ -77,70 +77,51 @@ const CustomValuesEditor = ({
|
|
|
77
77
|
</CapRow>
|
|
78
78
|
) : (
|
|
79
79
|
<>
|
|
80
|
-
{
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
{typeof section.title === 'string' ? section.title : <FormattedMessage {...section.title} />}
|
|
80
|
+
{extractedTags?.length > 0 && (
|
|
81
|
+
<CapRow className="values-table">
|
|
82
|
+
<CapRow className="table-header" align='middle' justify='space-between'>
|
|
83
|
+
<CapLabel type="label31" className="header-cell">
|
|
84
|
+
<FormattedMessage {...messages.personalizationTags} />
|
|
86
85
|
</CapLabel>
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
<
|
|
94
|
-
|
|
95
|
-
</CapLabel>
|
|
96
|
-
</CapRow>
|
|
97
|
-
{(section?.requiredTags || []).map((tag, tagIndex) => {
|
|
98
|
-
const personalizationTagColumnText = getPersonalizationTagColumnLabel(tag);
|
|
99
|
-
const tagKey = tag?.fullPath ?? `required-${tagIndex}`;
|
|
100
|
-
return (
|
|
101
|
-
<CapRow key={tagKey} type="flex" noWrap className="value-row">
|
|
102
|
-
<CapRow type="flex" className="tag-name">
|
|
103
|
-
{personalizationTagColumnText}
|
|
104
|
-
<span className="required-tag-indicator" aria-hidden="true">*</span>
|
|
105
|
-
</CapRow>
|
|
106
|
-
<CapRow type="flex" className="tag-input">
|
|
107
|
-
<CapInput
|
|
108
|
-
type="text"
|
|
109
|
-
isRequired
|
|
110
|
-
className="tag-input-field"
|
|
111
|
-
value={customValues?.[tagKey] ?? ''}
|
|
112
|
-
onChange={(e) => handleCustomValueChange(tagKey, e.target.value)}
|
|
113
|
-
placeholder={formatMessage(messages.enterValue)}
|
|
114
|
-
size="small"
|
|
115
|
-
/>
|
|
116
|
-
</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" align='middle' justify='start'>
|
|
92
|
+
<CapRow className="tag-name" align='top' justify='start'>
|
|
93
|
+
{`${tag.fullPath}*`}
|
|
117
94
|
</CapRow>
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
<CapRow type="flex" className="tag-input">
|
|
129
|
-
<CapInput
|
|
130
|
-
type="text"
|
|
131
|
-
className="tag-input-field"
|
|
132
|
-
value={customValues?.[tagKey] ?? ''}
|
|
133
|
-
onChange={(e) => handleCustomValueChange(tagKey, e.target.value)}
|
|
134
|
-
placeholder={formatMessage(messages.enterValue)}
|
|
135
|
-
size="small"
|
|
136
|
-
/>
|
|
137
|
-
</CapRow>
|
|
95
|
+
<CapRow className="tag-input">
|
|
96
|
+
<CapInput
|
|
97
|
+
type="text"
|
|
98
|
+
isRequired
|
|
99
|
+
className="tag-input-field"
|
|
100
|
+
value={customValues[tag.fullPath] || ''}
|
|
101
|
+
onChange={(e) => handleCustomValueChange(tag.fullPath, e.target.value)}
|
|
102
|
+
placeholder={formatMessage(messages.enterValue)}
|
|
103
|
+
size="small"
|
|
104
|
+
/>
|
|
138
105
|
</CapRow>
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
106
|
+
</CapRow>
|
|
107
|
+
))}
|
|
108
|
+
{optionalTags?.map((tag) => (
|
|
109
|
+
<CapRow key={tag.fullPath} className="value-row" align='middle' justify='start'>
|
|
110
|
+
<CapRow className="tag-name" justify='start'>{tag.fullPath}</CapRow>
|
|
111
|
+
<CapRow className="tag-input">
|
|
112
|
+
<CapInput
|
|
113
|
+
type="text"
|
|
114
|
+
className="tag-input-field"
|
|
115
|
+
value={customValues[tag.fullPath] || ''}
|
|
116
|
+
onChange={(e) => handleCustomValueChange(tag.fullPath, e.target.value)}
|
|
117
|
+
placeholder={formatMessage(messages.enterValue)}
|
|
118
|
+
size="small"
|
|
119
|
+
/>
|
|
120
|
+
</CapRow>
|
|
121
|
+
</CapRow>
|
|
122
|
+
))}
|
|
123
|
+
</CapRow>
|
|
124
|
+
)}
|
|
144
125
|
</>
|
|
145
126
|
)}
|
|
146
127
|
<CapRow type='flex' align='middle' justify='space-between' className="editor-actions">
|
|
@@ -174,12 +155,9 @@ CustomValuesEditor.propTypes = {
|
|
|
174
155
|
setShowJSON: PropTypes.func.isRequired,
|
|
175
156
|
customValues: PropTypes.object.isRequired,
|
|
176
157
|
handleJSONTextChange: PropTypes.func.isRequired,
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
requiredTags: PropTypes.array,
|
|
181
|
-
optionalTags: PropTypes.array,
|
|
182
|
-
})).isRequired,
|
|
158
|
+
extractedTags: PropTypes.array.isRequired,
|
|
159
|
+
requiredTags: PropTypes.array.isRequired,
|
|
160
|
+
optionalTags: PropTypes.array.isRequired,
|
|
183
161
|
handleCustomValueChange: PropTypes.func.isRequired,
|
|
184
162
|
handleDiscardCustomValues: PropTypes.func.isRequired,
|
|
185
163
|
handleUpdatePreview: PropTypes.func.isRequired,
|