@capillarytech/creatives-library 8.0.128 → 8.0.129
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/containers/App/constants.js +1 -0
- package/package.json +1 -1
- package/services/api.js +1 -1
- package/tests/integration/TemplateCreation/TemplateCreation.integration.test.js +8 -3
- package/tests/integration/TemplateCreation/api-response.js +5 -0
- package/tests/integration/TemplateCreation/msw-handler.js +42 -63
- package/utils/common.js +7 -0
- package/utils/commonUtils.js +2 -6
- package/utils/createPayload.js +405 -0
- package/utils/tests/createPayload.test.js +785 -0
- package/v2Components/CapImageUpload/index.js +59 -46
- package/v2Components/CapInAppCTA/index.js +1 -0
- package/v2Components/CapMpushCTA/constants.js +25 -0
- package/v2Components/CapMpushCTA/index.js +402 -0
- package/v2Components/CapMpushCTA/index.scss +95 -0
- package/v2Components/CapMpushCTA/messages.js +101 -0
- package/v2Components/CapTagList/index.js +177 -120
- package/v2Components/CapVideoUpload/constants.js +3 -0
- package/v2Components/CapVideoUpload/index.js +167 -110
- package/v2Components/CapVideoUpload/messages.js +16 -0
- package/v2Components/Carousel/index.js +15 -13
- package/v2Components/ErrorInfoNote/style.scss +1 -0
- package/v2Components/MobilePushPreviewV2/index.js +37 -5
- package/v2Components/TemplatePreview/_templatePreview.scss +114 -72
- package/v2Components/TemplatePreview/assets/images/Android _ With date and time.svg +29 -0
- package/v2Components/TemplatePreview/assets/images/android.svg +9 -0
- package/v2Components/TemplatePreview/assets/images/iOS _ With date and time.svg +26 -0
- package/v2Components/TemplatePreview/assets/images/ios.svg +9 -0
- package/v2Components/TemplatePreview/index.js +178 -50
- package/v2Components/TemplatePreview/messages.js +4 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +127 -62
- package/v2Containers/CreativesContainer/index.js +191 -136
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -22
- package/v2Containers/InApp/constants.js +1 -0
- package/v2Containers/InApp/index.js +13 -13
- package/v2Containers/MobilePush/Create/index.js +1 -0
- package/v2Containers/MobilePush/commonMethods.js +7 -14
- package/v2Containers/MobilePushNew/actions.js +116 -0
- package/v2Containers/MobilePushNew/components/CtaButtons.js +181 -0
- package/v2Containers/MobilePushNew/components/MediaUploaders.js +834 -0
- package/v2Containers/MobilePushNew/components/PlatformContentFields.js +345 -0
- package/v2Containers/MobilePushNew/components/index.js +5 -0
- package/v2Containers/MobilePushNew/components/tests/CtaButtons.test.js +798 -0
- package/v2Containers/MobilePushNew/components/tests/MediaUploaders.test.js +2114 -0
- package/v2Containers/MobilePushNew/components/tests/PlatformContentFields.test.js +343 -0
- package/v2Containers/MobilePushNew/constants.js +115 -0
- package/v2Containers/MobilePushNew/hooks/tests/usePlatformSync.test.js +1299 -0
- package/v2Containers/MobilePushNew/hooks/tests/useUpload.test.js +1223 -0
- package/v2Containers/MobilePushNew/hooks/usePlatformSync.js +246 -0
- package/v2Containers/MobilePushNew/hooks/useUpload.js +726 -0
- package/v2Containers/MobilePushNew/index.js +3412 -0
- package/v2Containers/MobilePushNew/index.scss +308 -0
- package/v2Containers/MobilePushNew/messages.js +242 -0
- package/v2Containers/MobilePushNew/reducer.js +160 -0
- package/v2Containers/MobilePushNew/sagas.js +198 -0
- package/v2Containers/MobilePushNew/selectors.js +55 -0
- package/v2Containers/MobilePushNew/tests/reducer.test.js +741 -0
- package/v2Containers/MobilePushNew/tests/sagas.test.js +863 -0
- package/v2Containers/MobilePushNew/tests/selectors.test.js +425 -0
- package/v2Containers/MobilePushNew/tests/utils.test.js +322 -0
- package/v2Containers/MobilePushNew/utils.js +33 -0
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +5 -5
- package/v2Containers/TagList/index.js +56 -10
- package/v2Containers/Templates/_templates.scss +101 -1
- package/v2Containers/Templates/index.js +147 -35
- package/v2Containers/Templates/messages.js +8 -0
- package/v2Containers/Templates/sagas.js +2 -0
- package/v2Containers/Whatsapp/constants.js +1 -0
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import React, { useCallback } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { FormattedMessage } from "react-intl";
|
|
4
|
+
import CapRow from "@capillarytech/cap-ui-library/CapRow";
|
|
5
|
+
import CapInput from "@capillarytech/cap-ui-library/CapInput";
|
|
6
|
+
import CapColumn from "@capillarytech/cap-ui-library/CapColumn";
|
|
7
|
+
import CapHeading from "@capillarytech/cap-ui-library/CapHeading";
|
|
8
|
+
import CapError from "@capillarytech/cap-ui-library/CapError";
|
|
9
|
+
import CapDivider from "@capillarytech/cap-ui-library/CapDivider";
|
|
10
|
+
import CapSelect from "@capillarytech/cap-ui-library/CapSelect";
|
|
11
|
+
import CapCheckbox from "@capillarytech/cap-ui-library/CapCheckbox";
|
|
12
|
+
import CapLabel from "@capillarytech/cap-ui-library/CapLabel";
|
|
13
|
+
import CapInfoNote from "@capillarytech/cap-ui-library/CapInfoNote";
|
|
14
|
+
import TagList from "../../TagList";
|
|
15
|
+
import {
|
|
16
|
+
ANDROID,
|
|
17
|
+
IOS,
|
|
18
|
+
MEDIA_TYPES_OPTIONS,
|
|
19
|
+
LINK_TYPE_OPTIONS,
|
|
20
|
+
DEEP_LINK,
|
|
21
|
+
EXTERNAL_LINK,
|
|
22
|
+
} from "../constants";
|
|
23
|
+
import messages from "../messages";
|
|
24
|
+
import MediaUploaders from "./MediaUploaders";
|
|
25
|
+
import CtaButtons from "./CtaButtons";
|
|
26
|
+
|
|
27
|
+
const PlatformContentFields = ({
|
|
28
|
+
deviceType,
|
|
29
|
+
content,
|
|
30
|
+
errors,
|
|
31
|
+
handlers,
|
|
32
|
+
tagListProps,
|
|
33
|
+
mediaUploaderProps,
|
|
34
|
+
ctaButtonProps,
|
|
35
|
+
linkProps,
|
|
36
|
+
sameContent,
|
|
37
|
+
formatMessage,
|
|
38
|
+
}) => {
|
|
39
|
+
const { title: titleError, message: messageError } = errors;
|
|
40
|
+
const {
|
|
41
|
+
handleTitleChange,
|
|
42
|
+
handleMessageChange,
|
|
43
|
+
handleMediaTypeChange,
|
|
44
|
+
handleActionOnClickChange,
|
|
45
|
+
handleLinkTypeChange,
|
|
46
|
+
handleDeepLinkChange,
|
|
47
|
+
handleDeepLinkKeysChange,
|
|
48
|
+
handleExternalLinkChange,
|
|
49
|
+
onTagSelect,
|
|
50
|
+
handleOnTagsContextChange,
|
|
51
|
+
} = handlers;
|
|
52
|
+
|
|
53
|
+
const {
|
|
54
|
+
deepLink,
|
|
55
|
+
deepLinkValue,
|
|
56
|
+
deepLinkKeysValue,
|
|
57
|
+
externalLinkValue,
|
|
58
|
+
} = linkProps;
|
|
59
|
+
|
|
60
|
+
// Debug logging removed - issue identified and fixed
|
|
61
|
+
|
|
62
|
+
// Get the selected deep link object to extract keys
|
|
63
|
+
const selectedDeepLink = deepLink?.find((link) => link?.value === deepLinkValue);
|
|
64
|
+
const deepLinkKeysFromSelection = selectedDeepLink?.keys;
|
|
65
|
+
|
|
66
|
+
// Handle deep link keys value - could be array or string
|
|
67
|
+
let deepLinkKeysArray = [];
|
|
68
|
+
if (Array.isArray(deepLinkKeysValue)) {
|
|
69
|
+
deepLinkKeysArray = deepLinkKeysValue;
|
|
70
|
+
} else if (deepLinkKeysValue) {
|
|
71
|
+
deepLinkKeysArray = [deepLinkKeysValue];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let deepLinkKeysFromSelectionArray = [];
|
|
75
|
+
if (Array.isArray(deepLinkKeysFromSelection)) {
|
|
76
|
+
deepLinkKeysFromSelectionArray = deepLinkKeysFromSelection;
|
|
77
|
+
} else if (deepLinkKeysFromSelection) {
|
|
78
|
+
deepLinkKeysFromSelectionArray = [deepLinkKeysFromSelection];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const onTitleChange = useCallback(
|
|
82
|
+
({ target: { value } }) => {
|
|
83
|
+
handleTitleChange(deviceType, value);
|
|
84
|
+
},
|
|
85
|
+
[handleTitleChange, deviceType]
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const onMessageChange = useCallback(
|
|
89
|
+
({ target: { value } }) => {
|
|
90
|
+
handleMessageChange(deviceType, value);
|
|
91
|
+
},
|
|
92
|
+
[handleMessageChange, deviceType]
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const onMediaTypeChange = useCallback(
|
|
96
|
+
(value) => {
|
|
97
|
+
handleMediaTypeChange(deviceType, value);
|
|
98
|
+
},
|
|
99
|
+
[handleMediaTypeChange, deviceType]
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
const onActionOnClickChange = useCallback(
|
|
103
|
+
(e) => handleActionOnClickChange(deviceType, e.target.checked),
|
|
104
|
+
[handleActionOnClickChange, deviceType]
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
const onLinkTypeChange = useCallback(
|
|
108
|
+
(value) => handleLinkTypeChange(deviceType, value),
|
|
109
|
+
[handleLinkTypeChange, deviceType]
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const onDeepLinkChange = useCallback((value) => handleDeepLinkChange(value), [
|
|
113
|
+
handleDeepLinkChange,
|
|
114
|
+
]);
|
|
115
|
+
|
|
116
|
+
const onDeepLinkKeysChange = useCallback(
|
|
117
|
+
({ target: { value } }) => {
|
|
118
|
+
// Parse comma-separated values into array
|
|
119
|
+
const keysArray = value.split(',').map((key) => key.trim()).filter((key) => key.length > 0);
|
|
120
|
+
handleDeepLinkKeysChange(keysArray);
|
|
121
|
+
},
|
|
122
|
+
[handleDeepLinkKeysChange]
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
const onExternalLinkChange = useCallback(
|
|
126
|
+
(e) => handleExternalLinkChange(e.target.value),
|
|
127
|
+
[handleExternalLinkChange]
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const getTagList = useCallback(
|
|
131
|
+
(index) => (
|
|
132
|
+
<TagList
|
|
133
|
+
{...tagListProps}
|
|
134
|
+
onTagSelect={(value) => onTagSelect(value, index)}
|
|
135
|
+
onContextChange={handleOnTagsContextChange}
|
|
136
|
+
/>
|
|
137
|
+
),
|
|
138
|
+
[tagListProps, onTagSelect, handleOnTagsContextChange]
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<>
|
|
143
|
+
{sameContent && (
|
|
144
|
+
<CapInfoNote message={formatMessage(messages.sameContentNote)} />
|
|
145
|
+
)}
|
|
146
|
+
<CapRow className="content-fields">
|
|
147
|
+
<CapRow className="creatives-mpush-title">
|
|
148
|
+
<CapColumn className="mpush-title-main">
|
|
149
|
+
<CapHeading type="h4" className="mpush-title">
|
|
150
|
+
<FormattedMessage {...messages.title} />
|
|
151
|
+
</CapHeading>
|
|
152
|
+
{getTagList(0)}
|
|
153
|
+
</CapColumn>
|
|
154
|
+
<CapInput
|
|
155
|
+
id={`mobile-push-title-name-input-${deviceType}`}
|
|
156
|
+
onChange={onTitleChange}
|
|
157
|
+
placeholder={formatMessage(messages.titlePlaceholder)}
|
|
158
|
+
value={content.title}
|
|
159
|
+
size="default"
|
|
160
|
+
isRequired
|
|
161
|
+
errorMessage={
|
|
162
|
+
titleError && (
|
|
163
|
+
<CapError className="mobile-push-template-title-error">
|
|
164
|
+
{titleError}
|
|
165
|
+
</CapError>
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
/>
|
|
169
|
+
</CapRow>
|
|
170
|
+
|
|
171
|
+
<CapRow className="creatives-mpush-message">
|
|
172
|
+
<CapColumn className="mpush-message-main">
|
|
173
|
+
<CapHeading type="h4" className="mpush-message">
|
|
174
|
+
<FormattedMessage {...messages.message} />
|
|
175
|
+
</CapHeading>
|
|
176
|
+
{getTagList(1)}
|
|
177
|
+
</CapColumn>
|
|
178
|
+
<CapInput
|
|
179
|
+
id={`mobile-push-message-name-input-${deviceType}`}
|
|
180
|
+
onChange={onMessageChange}
|
|
181
|
+
placeholder={formatMessage(messages.messagePlaceholder)}
|
|
182
|
+
value={content.message}
|
|
183
|
+
size="default"
|
|
184
|
+
isRequired
|
|
185
|
+
errorMessage={
|
|
186
|
+
messageError && (
|
|
187
|
+
<CapError className="mobile-push-template-message-error">
|
|
188
|
+
{messageError}
|
|
189
|
+
</CapError>
|
|
190
|
+
)
|
|
191
|
+
}
|
|
192
|
+
/>
|
|
193
|
+
</CapRow>
|
|
194
|
+
<CapDivider />
|
|
195
|
+
<CapRow className="creatives-mpush-media">
|
|
196
|
+
<CapHeading type="h4" className="mpush-media-type">
|
|
197
|
+
<FormattedMessage {...messages.mediaType} />
|
|
198
|
+
</CapHeading>
|
|
199
|
+
<CapSelect.CapCustomSelect
|
|
200
|
+
width="100%"
|
|
201
|
+
className="margin-t-4"
|
|
202
|
+
options={MEDIA_TYPES_OPTIONS}
|
|
203
|
+
value={content.mediaType}
|
|
204
|
+
onChange={onMediaTypeChange}
|
|
205
|
+
/>
|
|
206
|
+
<MediaUploaders
|
|
207
|
+
mediaType={content.mediaType}
|
|
208
|
+
{...mediaUploaderProps}
|
|
209
|
+
formatMessage={formatMessage}
|
|
210
|
+
/>
|
|
211
|
+
</CapRow>
|
|
212
|
+
{content.mediaType !== "CAROUSEL" && (
|
|
213
|
+
<>
|
|
214
|
+
<CapDivider />
|
|
215
|
+
<CapRow className="creatives-mpush-actions">
|
|
216
|
+
<CapRow className="mpush-actions-main">
|
|
217
|
+
<CapHeading type="h4" className="mpush-actions">
|
|
218
|
+
<FormattedMessage {...messages.buttonsAndLinks} />
|
|
219
|
+
</CapHeading>
|
|
220
|
+
<CapLabel className="optional-text">
|
|
221
|
+
<FormattedMessage {...messages.optionalText} />
|
|
222
|
+
</CapLabel>
|
|
223
|
+
</CapRow>
|
|
224
|
+
<CapCheckbox
|
|
225
|
+
checked={content.actionOnClick}
|
|
226
|
+
onChange={onActionOnClickChange}
|
|
227
|
+
className="action-on-click-checkbox"
|
|
228
|
+
>
|
|
229
|
+
<FormattedMessage {...messages.actionOnClickBody} />
|
|
230
|
+
</CapCheckbox>
|
|
231
|
+
<CapRow>
|
|
232
|
+
<CapLabel className="action-description">
|
|
233
|
+
<FormattedMessage {...messages.actionDescription} />
|
|
234
|
+
</CapLabel>
|
|
235
|
+
</CapRow>
|
|
236
|
+
{content.actionOnClick && (
|
|
237
|
+
<CapRow style={{ display: "flex", justifyContent: "space-around" }}>
|
|
238
|
+
<CapColumn span={6}>
|
|
239
|
+
<CapHeading type="h4" className="buttons-heading">
|
|
240
|
+
<FormattedMessage {...messages.linkType} />
|
|
241
|
+
</CapHeading>
|
|
242
|
+
<CapSelect.CapCustomSelect
|
|
243
|
+
options={LINK_TYPE_OPTIONS}
|
|
244
|
+
value={content.linkType}
|
|
245
|
+
onChange={onLinkTypeChange}
|
|
246
|
+
key="mobile-push-link-type"
|
|
247
|
+
selectPlaceholder={formatMessage(messages.selectDeepLink)}
|
|
248
|
+
/>
|
|
249
|
+
</CapColumn>
|
|
250
|
+
{content.linkType === DEEP_LINK && (
|
|
251
|
+
<CapColumn span={14}>
|
|
252
|
+
<CapHeading type="h4" className="buttons-heading">
|
|
253
|
+
{formatMessage(messages.deepLink)}
|
|
254
|
+
</CapHeading>
|
|
255
|
+
<CapSelect.CapCustomSelect
|
|
256
|
+
options={deepLink || []}
|
|
257
|
+
value={deepLinkValue}
|
|
258
|
+
onChange={onDeepLinkChange}
|
|
259
|
+
key="mobile-push-deep-link-type"
|
|
260
|
+
placeholder={formatMessage(messages.selectDeepLink)}
|
|
261
|
+
style={{ marginTop: "10px" }}
|
|
262
|
+
/>
|
|
263
|
+
</CapColumn>
|
|
264
|
+
)}
|
|
265
|
+
{content.linkType === EXTERNAL_LINK && (
|
|
266
|
+
<CapColumn span={14}>
|
|
267
|
+
<CapHeading type="h4" className="buttons-heading">
|
|
268
|
+
{formatMessage(messages.externalLink)}
|
|
269
|
+
</CapHeading>
|
|
270
|
+
<CapInput
|
|
271
|
+
id="mobile-push-external-link-input"
|
|
272
|
+
onChange={onExternalLinkChange}
|
|
273
|
+
placeholder={formatMessage(messages.enterExternalLink)}
|
|
274
|
+
value={externalLinkValue}
|
|
275
|
+
size="default"
|
|
276
|
+
isRequired
|
|
277
|
+
errorMessage={
|
|
278
|
+
errors.externalLink && (
|
|
279
|
+
<CapError className="mobile-push-external-link-error">
|
|
280
|
+
{errors.externalLink}
|
|
281
|
+
</CapError>
|
|
282
|
+
)
|
|
283
|
+
}
|
|
284
|
+
/>
|
|
285
|
+
</CapColumn>
|
|
286
|
+
)}
|
|
287
|
+
</CapRow>
|
|
288
|
+
)}
|
|
289
|
+
{content.actionOnClick && content.linkType === DEEP_LINK && deepLinkValue && deepLinkKeysFromSelectionArray.length > 0 && (
|
|
290
|
+
<CapRow style={{ marginTop: "10px", left: "6%", width: '115%'}}>
|
|
291
|
+
<CapColumn span={7}>
|
|
292
|
+
<CapHeading type="h4" className="deep-link-keys-heading">
|
|
293
|
+
{formatMessage(messages.deepLinkKeys)}
|
|
294
|
+
</CapHeading>
|
|
295
|
+
<CapLabel type="label2" className="deep-link-keys-value">
|
|
296
|
+
{(() => {
|
|
297
|
+
if (deepLinkKeysFromSelectionArray.length > 0) {
|
|
298
|
+
return deepLinkKeysFromSelectionArray.join(', ');
|
|
299
|
+
}
|
|
300
|
+
if (deepLinkKeysArray.length > 0) {
|
|
301
|
+
return deepLinkKeysArray.join(', ');
|
|
302
|
+
}
|
|
303
|
+
return "No value set";
|
|
304
|
+
})()}
|
|
305
|
+
</CapLabel>
|
|
306
|
+
<CapInput
|
|
307
|
+
id="mobile-push-deep-link-keys-input"
|
|
308
|
+
onChange={onDeepLinkKeysChange}
|
|
309
|
+
placeholder={formatMessage(messages.deepLinkKeysPlaceholder, { key: deepLinkKeysFromSelectionArray.join(', ') || 'deep link keys' })}
|
|
310
|
+
value={Array.isArray(deepLinkKeysValue) ? deepLinkKeysValue.join(', ') : (deepLinkKeysValue || "")}
|
|
311
|
+
size="default"
|
|
312
|
+
style={{ marginTop: "10px" }}
|
|
313
|
+
error={errors?.deepLinkKeys}
|
|
314
|
+
/>
|
|
315
|
+
</CapColumn>
|
|
316
|
+
</CapRow>
|
|
317
|
+
)}
|
|
318
|
+
</CapRow>
|
|
319
|
+
<CtaButtons {...ctaButtonProps} />
|
|
320
|
+
</>
|
|
321
|
+
)}
|
|
322
|
+
</CapRow>
|
|
323
|
+
</>
|
|
324
|
+
);
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
PlatformContentFields.propTypes = {
|
|
328
|
+
deviceType: PropTypes.oneOf([ANDROID, IOS]).isRequired,
|
|
329
|
+
content: PropTypes.object.isRequired,
|
|
330
|
+
errors: PropTypes.shape({
|
|
331
|
+
title: PropTypes.string,
|
|
332
|
+
message: PropTypes.string,
|
|
333
|
+
externalLink: PropTypes.string,
|
|
334
|
+
deepLinkKeys: PropTypes.string,
|
|
335
|
+
}).isRequired,
|
|
336
|
+
handlers: PropTypes.object.isRequired,
|
|
337
|
+
tagListProps: PropTypes.object.isRequired,
|
|
338
|
+
mediaUploaderProps: PropTypes.object.isRequired,
|
|
339
|
+
ctaButtonProps: PropTypes.object.isRequired,
|
|
340
|
+
linkProps: PropTypes.object.isRequired,
|
|
341
|
+
sameContent: PropTypes.bool.isRequired,
|
|
342
|
+
formatMessage: PropTypes.func.isRequired,
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
export default PlatformContentFields;
|