@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.
Files changed (68) hide show
  1. package/containers/App/constants.js +1 -0
  2. package/package.json +1 -1
  3. package/services/api.js +1 -1
  4. package/tests/integration/TemplateCreation/TemplateCreation.integration.test.js +8 -3
  5. package/tests/integration/TemplateCreation/api-response.js +5 -0
  6. package/tests/integration/TemplateCreation/msw-handler.js +42 -63
  7. package/utils/common.js +7 -0
  8. package/utils/commonUtils.js +2 -6
  9. package/utils/createPayload.js +405 -0
  10. package/utils/tests/createPayload.test.js +785 -0
  11. package/v2Components/CapImageUpload/index.js +59 -46
  12. package/v2Components/CapInAppCTA/index.js +1 -0
  13. package/v2Components/CapMpushCTA/constants.js +25 -0
  14. package/v2Components/CapMpushCTA/index.js +402 -0
  15. package/v2Components/CapMpushCTA/index.scss +95 -0
  16. package/v2Components/CapMpushCTA/messages.js +101 -0
  17. package/v2Components/CapTagList/index.js +177 -120
  18. package/v2Components/CapVideoUpload/constants.js +3 -0
  19. package/v2Components/CapVideoUpload/index.js +167 -110
  20. package/v2Components/CapVideoUpload/messages.js +16 -0
  21. package/v2Components/Carousel/index.js +15 -13
  22. package/v2Components/ErrorInfoNote/style.scss +1 -0
  23. package/v2Components/MobilePushPreviewV2/index.js +37 -5
  24. package/v2Components/TemplatePreview/_templatePreview.scss +114 -72
  25. package/v2Components/TemplatePreview/assets/images/Android _ With date and time.svg +29 -0
  26. package/v2Components/TemplatePreview/assets/images/android.svg +9 -0
  27. package/v2Components/TemplatePreview/assets/images/iOS _ With date and time.svg +26 -0
  28. package/v2Components/TemplatePreview/assets/images/ios.svg +9 -0
  29. package/v2Components/TemplatePreview/index.js +178 -50
  30. package/v2Components/TemplatePreview/messages.js +4 -0
  31. package/v2Containers/CreativesContainer/SlideBoxContent.js +127 -62
  32. package/v2Containers/CreativesContainer/index.js +191 -136
  33. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +0 -22
  34. package/v2Containers/InApp/constants.js +1 -0
  35. package/v2Containers/InApp/index.js +13 -13
  36. package/v2Containers/MobilePush/Create/index.js +1 -0
  37. package/v2Containers/MobilePush/commonMethods.js +7 -14
  38. package/v2Containers/MobilePushNew/actions.js +116 -0
  39. package/v2Containers/MobilePushNew/components/CtaButtons.js +181 -0
  40. package/v2Containers/MobilePushNew/components/MediaUploaders.js +834 -0
  41. package/v2Containers/MobilePushNew/components/PlatformContentFields.js +345 -0
  42. package/v2Containers/MobilePushNew/components/index.js +5 -0
  43. package/v2Containers/MobilePushNew/components/tests/CtaButtons.test.js +798 -0
  44. package/v2Containers/MobilePushNew/components/tests/MediaUploaders.test.js +2114 -0
  45. package/v2Containers/MobilePushNew/components/tests/PlatformContentFields.test.js +343 -0
  46. package/v2Containers/MobilePushNew/constants.js +115 -0
  47. package/v2Containers/MobilePushNew/hooks/tests/usePlatformSync.test.js +1299 -0
  48. package/v2Containers/MobilePushNew/hooks/tests/useUpload.test.js +1223 -0
  49. package/v2Containers/MobilePushNew/hooks/usePlatformSync.js +246 -0
  50. package/v2Containers/MobilePushNew/hooks/useUpload.js +726 -0
  51. package/v2Containers/MobilePushNew/index.js +3412 -0
  52. package/v2Containers/MobilePushNew/index.scss +308 -0
  53. package/v2Containers/MobilePushNew/messages.js +242 -0
  54. package/v2Containers/MobilePushNew/reducer.js +160 -0
  55. package/v2Containers/MobilePushNew/sagas.js +198 -0
  56. package/v2Containers/MobilePushNew/selectors.js +55 -0
  57. package/v2Containers/MobilePushNew/tests/reducer.test.js +741 -0
  58. package/v2Containers/MobilePushNew/tests/sagas.test.js +863 -0
  59. package/v2Containers/MobilePushNew/tests/selectors.test.js +425 -0
  60. package/v2Containers/MobilePushNew/tests/utils.test.js +322 -0
  61. package/v2Containers/MobilePushNew/utils.js +33 -0
  62. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +5 -5
  63. package/v2Containers/TagList/index.js +56 -10
  64. package/v2Containers/Templates/_templates.scss +101 -1
  65. package/v2Containers/Templates/index.js +147 -35
  66. package/v2Containers/Templates/messages.js +8 -0
  67. package/v2Containers/Templates/sagas.js +2 -0
  68. 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;
@@ -0,0 +1,5 @@
1
+ import CtaButtons from './CtaButtons';
2
+ import MediaUploaders from './MediaUploaders';
3
+ import PlatformContentFields from './PlatformContentFields';
4
+
5
+ export { CtaButtons, MediaUploaders, PlatformContentFields };