@capillarytech/creatives-library 8.0.126 → 8.0.127-alpha.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.
Files changed (78) hide show
  1. package/containers/App/constants.js +1 -0
  2. package/index.html +3 -1
  3. package/package.json +1 -1
  4. package/services/api.js +4 -4
  5. package/tests/integration/TemplateCreation/TemplateCreation.integration.test.js +8 -3
  6. package/tests/integration/TemplateCreation/api-response.js +5 -0
  7. package/tests/integration/TemplateCreation/msw-handler.js +42 -63
  8. package/utils/common.js +7 -0
  9. package/utils/commonUtils.js +2 -6
  10. package/utils/createPayload.js +272 -0
  11. package/utils/tests/createPayload.test.js +761 -0
  12. package/v2Components/CapImageUpload/index.js +59 -46
  13. package/v2Components/CapInAppCTA/index.js +1 -0
  14. package/v2Components/CapMpushCTA/constants.js +25 -0
  15. package/v2Components/CapMpushCTA/index.js +332 -0
  16. package/v2Components/CapMpushCTA/index.scss +95 -0
  17. package/v2Components/CapMpushCTA/messages.js +89 -0
  18. package/v2Components/CapTagList/index.js +177 -120
  19. package/v2Components/CapVideoUpload/constants.js +3 -0
  20. package/v2Components/CapVideoUpload/index.js +167 -110
  21. package/v2Components/CapVideoUpload/messages.js +16 -0
  22. package/v2Components/Carousel/index.js +15 -13
  23. package/v2Components/CustomerSearchSection/index.js +12 -7
  24. package/v2Components/ErrorInfoNote/style.scss +1 -0
  25. package/v2Components/MobilePushPreviewV2/index.js +37 -5
  26. package/v2Components/TemplatePreview/_templatePreview.scss +114 -72
  27. package/v2Components/TemplatePreview/assets/images/Android _ With date and time.svg +29 -0
  28. package/v2Components/TemplatePreview/assets/images/android.svg +9 -0
  29. package/v2Components/TemplatePreview/assets/images/iOS _ With date and time.svg +26 -0
  30. package/v2Components/TemplatePreview/assets/images/ios.svg +9 -0
  31. package/v2Components/TemplatePreview/index.js +178 -50
  32. package/v2Components/TemplatePreview/messages.js +4 -0
  33. package/v2Components/TestAndPreviewSlidebox/CustomValuesEditor.js +169 -0
  34. package/v2Components/TestAndPreviewSlidebox/LeftPanelContent.js +95 -0
  35. package/v2Components/TestAndPreviewSlidebox/PreviewSection.js +69 -0
  36. package/v2Components/TestAndPreviewSlidebox/SendTestMessage.js +68 -0
  37. package/v2Components/TestAndPreviewSlidebox/index.js +67 -246
  38. package/v2Components/TestAndPreviewSlidebox/tests/CustomValuesEditor.test.js +425 -0
  39. package/v2Components/TestAndPreviewSlidebox/tests/LeftPanelContent.test.js +400 -0
  40. package/v2Components/TestAndPreviewSlidebox/tests/SendTestMessage.test.js +448 -0
  41. package/v2Containers/CreativesContainer/SlideBoxContent.js +9 -9
  42. package/v2Containers/CreativesContainer/index.js +193 -134
  43. package/v2Containers/Email/index.js +15 -2
  44. package/v2Containers/InApp/constants.js +1 -0
  45. package/v2Containers/InApp/index.js +13 -13
  46. package/v2Containers/MobilePush/Create/index.js +1 -0
  47. package/v2Containers/MobilePush/commonMethods.js +7 -14
  48. package/v2Containers/MobilePushNew/actions.js +116 -0
  49. package/v2Containers/MobilePushNew/components/CtaButtons.js +170 -0
  50. package/v2Containers/MobilePushNew/components/MediaUploaders.js +754 -0
  51. package/v2Containers/MobilePushNew/components/PlatformContentFields.js +279 -0
  52. package/v2Containers/MobilePushNew/components/index.js +5 -0
  53. package/v2Containers/MobilePushNew/components/tests/CtaButtons.test.js +779 -0
  54. package/v2Containers/MobilePushNew/components/tests/MediaUploaders.test.js +2114 -0
  55. package/v2Containers/MobilePushNew/components/tests/PlatformContentFields.test.js +343 -0
  56. package/v2Containers/MobilePushNew/constants.js +115 -0
  57. package/v2Containers/MobilePushNew/hooks/tests/usePlatformSync.test.js +1299 -0
  58. package/v2Containers/MobilePushNew/hooks/tests/useUpload.test.js +1223 -0
  59. package/v2Containers/MobilePushNew/hooks/usePlatformSync.js +246 -0
  60. package/v2Containers/MobilePushNew/hooks/useUpload.js +726 -0
  61. package/v2Containers/MobilePushNew/index.js +2280 -0
  62. package/v2Containers/MobilePushNew/index.scss +308 -0
  63. package/v2Containers/MobilePushNew/messages.js +226 -0
  64. package/v2Containers/MobilePushNew/reducer.js +160 -0
  65. package/v2Containers/MobilePushNew/sagas.js +198 -0
  66. package/v2Containers/MobilePushNew/selectors.js +55 -0
  67. package/v2Containers/MobilePushNew/tests/reducer.test.js +741 -0
  68. package/v2Containers/MobilePushNew/tests/sagas.test.js +863 -0
  69. package/v2Containers/MobilePushNew/tests/selectors.test.js +425 -0
  70. package/v2Containers/MobilePushNew/tests/utils.test.js +322 -0
  71. package/v2Containers/MobilePushNew/utils.js +33 -0
  72. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +5 -5
  73. package/v2Containers/TagList/index.js +56 -10
  74. package/v2Containers/Templates/_templates.scss +101 -1
  75. package/v2Containers/Templates/index.js +147 -35
  76. package/v2Containers/Templates/messages.js +8 -0
  77. package/v2Containers/Templates/sagas.js +2 -0
  78. package/v2Containers/Whatsapp/constants.js +1 -0
@@ -3,7 +3,9 @@
3
3
  * CapVideoUpload
4
4
  *
5
5
  */
6
- import React, { useCallback, useState, Fragment, useRef, useEffect } from 'react';
6
+ import React, {
7
+ useCallback, useState, Fragment, useRef, useEffect,
8
+ } from 'react';
7
9
  import PropTypes from "prop-types";
8
10
  import get from 'lodash/get';
9
11
  import CapDrawer from '@capillarytech/cap-ui-library/CapDrawer';
@@ -19,9 +21,12 @@ import {
19
21
  } from '@capillarytech/cap-ui-library';
20
22
  import messages from './messages';
21
23
  import {bytes2Size, getDecodedFileName} from '../../utils/common';
22
- import { SUPPORTED_FILE_FORMATS, WHATSAPP, DEFAULT, VIBER_MAX_DURATION } from './constants';
24
+ import {
25
+ SUPPORTED_FILE_FORMATS, WHATSAPP, DEFAULT, MAX_DURATION, MOBILEPUSH,
26
+ } from './constants';
23
27
  import './index.scss';
24
28
  import { VIBER } from '../../v2Containers/CreativesContainer/constants';
29
+ import { GIF, VIDEO } from '../../v2Containers/MobilePushNew/constants';
25
30
 
26
31
  function CapVideoUpload(props) {
27
32
  const {
@@ -40,6 +45,7 @@ function CapVideoUpload(props) {
40
45
  showVideoNameAndDuration = true,
41
46
  formClassName = 'video-form',
42
47
  showReUploadButton = true,
48
+ mediaType = VIDEO.toLowerCase(),
43
49
  } = props;
44
50
  const [isVideoError, updateVideoErrorMessage] = useState(false);
45
51
  const [isVideo, updateVideoStatus] = useState(false);
@@ -68,6 +74,7 @@ function CapVideoUpload(props) {
68
74
  const _URL = window.URL || window.webkitURL;
69
75
  let incorrectFile = false;
70
76
  const file = files[0];
77
+
71
78
  if (!allowedExtensionsRegex.test(file.name)) {
72
79
  incorrectFile = true;
73
80
  }
@@ -79,7 +86,7 @@ function CapVideoUpload(props) {
79
86
  error: false,
80
87
  isGenerateVideoThumbnail: true,
81
88
  };
82
- submitVideoAction({ file, type: 'video', fileParams }, incorrectFile);
89
+ submitVideoAction({ file, type: mediaType, fileParams }, incorrectFile);
83
90
  if (e) {
84
91
  const event = e;
85
92
  event.target.value = null;
@@ -87,10 +94,18 @@ function CapVideoUpload(props) {
87
94
  }, []);
88
95
 
89
96
  useEffect(() => {
90
- if (videoData[`uploadedAssetData${index}`] && Object.keys(videoData[`uploadedAssetData${index}`]).length) {
91
- const metaVideoSrc = get(videoData, `uploadedAssetData${index}.metaInfo.secure_file_path`, '');
92
- const previewImgUrl = get(videoData, `uploadedAssetData${index}.metaInfo.video_file_path_preview`, '');
93
- const metaVideoName = get(videoData, `uploadedAssetData${index}.metaInfo.name`, '');
97
+ }, [videoData, index]);
98
+
99
+ useEffect(() => {
100
+ if (!isEmpty(videoData[`uploadedAssetData${index}`])) {
101
+ const {
102
+ metaInfo: {
103
+ secure_file_path: metaVideoSrc = '',
104
+ file_name: metaVideoName = '',
105
+ preview_image_url: previewImgUrl = '',
106
+ } = {},
107
+ } = videoData[`uploadedAssetData${index}`] || {};
108
+
94
109
  const metaVideoId = get(videoData, `uploadedAssetData${index}.videoIdResponse.fbVideo.id`, '');
95
110
  const karixFileHandle = get(videoData, `uploadedAssetData${index}.metaInfo.karixFileHandle`, '');
96
111
 
@@ -102,14 +117,13 @@ function CapVideoUpload(props) {
102
117
  videoId: metaVideoId,
103
118
  fileHandle: karixFileHandle,
104
119
  videoDuration: null,
105
- },
106
- );
120
+ });
107
121
  }
108
122
  }
109
- }, [videoData[`uploadedAssetData${index}`]]);
123
+ }, [videoData, index, videoSrc, onVideoUploadUpdateAssestList]);
110
124
 
111
125
  useEffect(() => {
112
- if (videoData[`assetUploadingVideo_${index}`] && videoData[`assetUploading`] !== false) {
126
+ if (videoData[`assetUploadingVideo_${index}`] && videoData.assetUploading !== false) {
113
127
  const isSpinner = get(videoData, `assetUploadingVideo_${index}`, false);
114
128
  setSpinning(isSpinner);
115
129
  }
@@ -123,7 +137,12 @@ function CapVideoUpload(props) {
123
137
  } = uploadedAssetList || {};
124
138
  if (metaVideoSrc) {
125
139
  updateVideoStatus(true);
140
+ } else {
141
+ updateVideoStatus(false);
126
142
  }
143
+ } else {
144
+ // When uploadedAssetList is empty, reset video status to show upload interface
145
+ updateVideoStatus(false);
127
146
  }
128
147
  }, [uploadedAssetList]);
129
148
 
@@ -136,6 +155,7 @@ function CapVideoUpload(props) {
136
155
  fileParams,
137
156
  type,
138
157
  } = data;
158
+
139
159
  if (incorrectFile || size > videoSize) {
140
160
  if (errorMessage) {
141
161
  updateVideoErrorMessage(errorMessage);
@@ -155,11 +175,7 @@ function CapVideoUpload(props) {
155
175
 
156
176
  const {
157
177
  formatMessage,
158
- } = intl || {};
159
-
160
- const capUploaderCustomVideoRequest = useCallback((uploadData) => {
161
- uploadVideo(undefined, { files: [uploadData.file] });
162
- }, []);
178
+ } = intl || {};
163
179
 
164
180
  const playVideo = useCallback((e) => {
165
181
  if (e.target.paused && !isPlaying) {
@@ -173,78 +189,86 @@ function CapVideoUpload(props) {
173
189
  }
174
190
  }, [isPlaying]);
175
191
 
192
+ const onReUpload = useCallback(() => {
193
+ updateVideoStatus(false);
194
+ updateVideoDuration(null);
195
+ onVideoUploadUpdateAssestList(
196
+ index,
197
+ {
198
+ previewUrl: "",
199
+ videoName: "",
200
+ videoHeight: "",
201
+ videoWidth: "",
202
+ videoSrc: "",
203
+ videoDuration: null,
204
+ videoId: "",
205
+ fileHandle: "",
206
+ }
207
+ );
208
+ setTimeout(() => {
209
+ const fileInput = document.getElementById("videoFileName");
210
+ if (fileInput) {
211
+ fileInput.click();
212
+ }
213
+ }, 100);
214
+ }, [index, onVideoUploadUpdateAssestList]);
215
+
216
+ const updateMetadataLoaded = useCallback(() => {
217
+ const { current: { duration, videoHeight: metaVideoHeight, videoWidth: metaVideoWidth } = {} } = videoEl;
218
+ if (duration) {
219
+ updateVideoDuration(duration);
220
+ if (videoWidth === undefined && videoHeight === undefined) {
221
+ if (duration <= MAX_DURATION) {
222
+ onVideoUploadUpdateAssestList(index, {
223
+ videoSrc,
224
+ videoId,
225
+ videoName,
226
+ videoHeight: metaVideoHeight,
227
+ videoWidth: metaVideoWidth,
228
+ previewUrl,
229
+ fileHandle,
230
+ videoDuration: duration,
231
+ });
232
+ } else {
233
+ onReUpload();
234
+ updateVideoErrorMessage(formatMessage(messages.videoDurationError));
235
+ }
236
+ }
237
+ }
238
+ }, [videoSrc, videoId, videoName, previewUrl, fileHandle, videoWidth, videoHeight, index, onVideoUploadUpdateAssestList, formatMessage, onReUpload]);
239
+
240
+ const videoDurationValue = videoDuration ? moment('1900-01-01 00:00:00').add(videoDuration, 'seconds').format("HH.mm.ss") : '';
241
+
242
+ const capUploaderCustomVideoRequest = useCallback((uploadData) => {
243
+ uploadVideo(undefined, { files: [uploadData.file] });
244
+ }, [uploadVideo]);
245
+
176
246
  const getVideoSection = () => {
177
247
  if (!isVideo) {
178
248
  return (
179
- (
180
- <>
181
- <CapUploader.CapDragger
182
- customRequest={(data) => capUploaderCustomVideoRequest(data)}
183
- className="form-builder-dragger whatsapp-background"
184
- showUploadList={!isVideoError}
185
- >
186
- <CapHeading className="dragger-title" type="h7">
187
- <FormattedMessage {...messages.dragAndDrop} />
188
- </CapHeading>
189
- <CapHeading className="dragger-or" type="label6">
190
- <FormattedMessage {...messages.or} />
191
- </CapHeading>
192
- <CapButton className="dragger-button upload-video" type="secondary">
193
- <FormattedMessage {...messages.selectFromComputer} />
194
- </CapButton>
195
- </CapUploader.CapDragger>
196
- <CapError type="error" className="upload-video-error">
197
- {isVideoError}
198
- </CapError>
199
- </>
200
- )
249
+ <>
250
+ <CapUploader.CapDragger
251
+ customRequest={(data) => capUploaderCustomVideoRequest(data)}
252
+ className="form-builder-dragger whatsapp-background"
253
+ showUploadList={!isVideoError}
254
+ >
255
+ <CapHeading className="dragger-title" type="h7">
256
+ <FormattedMessage {...messages.dragAndDrop} />
257
+ </CapHeading>
258
+ <CapHeading className="dragger-or" type="label6">
259
+ <FormattedMessage {...messages.or} />
260
+ </CapHeading>
261
+ <CapButton className="dragger-button upload-video" type="secondary">
262
+ <FormattedMessage {...messages.selectFromComputer} />
263
+ </CapButton>
264
+ </CapUploader.CapDragger>
265
+ <CapError type="error" className="upload-video-error">
266
+ {isVideoError}
267
+ </CapError>
268
+ </>
201
269
  );
202
270
  }
203
- const onReUpload = () => {
204
- updateVideoStatus(false);
205
- updateVideoDuration(null);
206
- onVideoUploadUpdateAssestList(
207
- index,
208
- {
209
- previewUrl: "",
210
- videoName: "",
211
- videoHeight: "",
212
- videoWidth: "",
213
- videoSrc: "",
214
- videoDuration: null,
215
- videoId: "",
216
- fileHandle: "",
217
- }
218
- );
219
- };
220
271
 
221
- const updateMetadataLoaded = () => {
222
- const { current: { duration, videoHeight: metaVideoHeight, videoWidth: metaVideoWidth } = {} } = videoEl;
223
- if (duration) {
224
- updateVideoDuration(duration);
225
- if (videoWidth === undefined && videoHeight === undefined) {
226
- if (
227
- channel !== VIBER ||
228
- (channel === VIBER && duration <= VIBER_MAX_DURATION)
229
- ) {
230
- onVideoUploadUpdateAssestList(index, {
231
- videoSrc,
232
- videoId,
233
- videoName,
234
- videoHeight: metaVideoHeight,
235
- videoWidth: metaVideoWidth,
236
- previewUrl,
237
- fileHandle,
238
- videoDuration: duration,
239
- });
240
- } else {
241
- onReUpload();
242
- updateVideoErrorMessage(formatMessage(messages.videoDurationError));
243
- }
244
- }
245
- }
246
- };
247
- const videoDurationValue = moment('1900-01-01 00:00:00').add(videoDuration, 'seconds').format("HH.mm.ss"); // to get the duration of video
248
272
  return (
249
273
  <Fragment key={videoSrc}>
250
274
  {showReUploadButton && (
@@ -259,21 +283,35 @@ function CapVideoUpload(props) {
259
283
  </div>
260
284
  )}
261
285
  <div className={showVideoNameAndDuration ? 'video-panel' : 'video-panel-wp'}>
262
- <video
263
- width="230"
264
- poster={previewUrl}
265
- className="line-image-src"
266
- key={`${index}-video`}
267
- onLoadedMetadata={() => updateMetadataLoaded()}
268
- onPlaying={() => updateIsPlaying(true)}
269
- onPause={() => updateIsPlaying(false)}
270
- onMouseOver={playVideo}
271
- onMouseOut={pauseVideo}
272
- ref={videoEl}
273
- >
274
- <source src={videoSrc} type="video/mp4" />
275
- </video>
276
- {showVideoNameAndDuration &&
286
+ {mediaType === GIF.toLowerCase() ? (
287
+ <img
288
+ width="230"
289
+ src={videoSrc}
290
+ alt="GIF preview"
291
+ className="line-image-src"
292
+ key={`${index}-gif`}
293
+ style={{ maxWidth: '230px', maxHeight: '200px', objectFit: 'contain' }}
294
+ />
295
+ ) : (
296
+ <video
297
+ width="230"
298
+ poster={previewUrl}
299
+ className="line-image-src"
300
+ key={`${index}-video`}
301
+ onLoadedMetadata={updateMetadataLoaded}
302
+ onPlaying={() => updateIsPlaying(true)}
303
+ onPause={() => updateIsPlaying(false)}
304
+ onMouseOver={playVideo}
305
+ onMouseOut={pauseVideo}
306
+ onFocus={playVideo}
307
+ onBlur={pauseVideo}
308
+ ref={videoEl}
309
+ >
310
+ <source src={videoSrc} type="video/mp4" />
311
+ <track kind="captions" />
312
+ </video>
313
+ )}
314
+ {showVideoNameAndDuration && (
277
315
  <div className="video-info">
278
316
  <CapHeading type="h4">
279
317
  {getDecodedFileName(videoName)}
@@ -282,7 +320,7 @@ function CapVideoUpload(props) {
282
320
  {videoDurationValue}
283
321
  </CapHeading>
284
322
  </div>
285
- }
323
+ )}
286
324
  </div>
287
325
  </Fragment>
288
326
  );
@@ -300,23 +338,24 @@ function CapVideoUpload(props) {
300
338
  return (
301
339
  <CapSpin spinning={isSpinning}>
302
340
  <div style={style} className="cap-custom-video-upload">
303
- <form encType="multipart/form-data" id={`form`} className={formClassName}>
341
+ <form encType="multipart/form-data" id="form" className={formClassName}>
304
342
  <input
305
- key={`videoFile`}
343
+ key="videoFile"
306
344
  style={{ display: 'none' }}
307
- id="fileName"
345
+ id="videoFileName"
308
346
  type="file"
309
347
  onChange={(e) => uploadVideo(e, { files: e.target.files })}
310
- accept={supportedExtensions || "video/*"}
311
- />
348
+ accept={mediaType === GIF.toLowerCase() ? '.gif' : (supportedExtensions || "video/*")}
349
+ />
312
350
  {getVideoSection()}
313
351
  <CapDrawer
314
352
  visible={isTemplateDrawerRequired}
315
353
  width={624}
316
354
  onClose={() => updateTemplateDrawerRequirement(false)}
317
- />
355
+ />
318
356
  </form>
319
- {![WHATSAPP, VIBER].includes(channel) &&
357
+ {![WHATSAPP, VIBER, MOBILEPUSH].includes(channel)
358
+ && (
320
359
  <>
321
360
  <CapHeading.CapHeadingSpan type="h6" className="video-description">
322
361
  <FormattedMessage {...messages.videoRatioDescription} />
@@ -328,15 +367,18 @@ function CapVideoUpload(props) {
328
367
  <CapHeading.CapHeadingSpan type="h6" className="video-description video-details">
329
368
  <FormattedMessage {...messages.videoSizeDescription} values={{size: bytes2Size(videoSize)}} />
330
369
  </CapHeading.CapHeadingSpan>
331
- </>}
332
- {channel === WHATSAPP &&
370
+ </>
371
+ )}
372
+ {channel === WHATSAPP
373
+ && (
333
374
  <>
334
375
  {getVideoSizeDescription()}
335
376
  <CapHeading.CapHeadingSpan type="label2" className="whatsapp-format">
336
377
  <FormattedMessage {...messages.channelFileFormat} values={{ format: SUPPORTED_FILE_FORMATS[DEFAULT] }} />
337
378
  </CapHeading.CapHeadingSpan>
338
- </>}
339
- {channel === VIBER &&
379
+ </>
380
+ )}
381
+ {channel === VIBER && (
340
382
  <>
341
383
  {getVideoSizeDescription()}
342
384
  <CapHeading.CapHeadingSpan type="label2" className="whatsapp-format">
@@ -345,7 +387,20 @@ function CapVideoUpload(props) {
345
387
  <CapHeading.CapHeadingSpan type="label2" className="video-duration">
346
388
  <FormattedMessage {...messages.viberMaxDuration} />
347
389
  </CapHeading.CapHeadingSpan>
348
- </>}
390
+ </>
391
+ )}
392
+ {channel === MOBILEPUSH
393
+ && (
394
+ <>
395
+ {getVideoSizeDescription()}
396
+ <CapHeading.CapHeadingSpan type="label2" className="whatsapp-format">
397
+ <FormattedMessage {...messages.channelFileFormat} values={{ format: SUPPORTED_FILE_FORMATS.MOBILEPUSH }} />
398
+ </CapHeading.CapHeadingSpan>
399
+ <CapHeading.CapHeadingSpan type="label2" className="video-duration">
400
+ <FormattedMessage {...messages.maxDuration} />
401
+ </CapHeading.CapHeadingSpan>
402
+ </>
403
+ )}
349
404
  </div>
350
405
  </CapSpin>
351
406
  );
@@ -366,6 +421,8 @@ CapVideoUpload.propTypes = {
366
421
  channel: PropTypes.string,
367
422
  errorMessage: PropTypes.string,
368
423
  formClassName: PropTypes.string,
424
+ showReUploadButton: PropTypes.bool,
425
+ mediaType: PropTypes.string,
369
426
  };
370
427
 
371
428
  export default injectIntl(CapVideoUpload);
@@ -63,8 +63,24 @@ export default defineMessages({
63
63
  id: `${scope}.viberMaxDuration`,
64
64
  defaultMessage: 'Max Duration: 600 seconds',
65
65
  },
66
+ maxDuration: {
67
+ id: `${scope}.maxDuration`,
68
+ defaultMessage: 'Max duration: 600 seconds',
69
+ },
66
70
  videoDurationError: {
67
71
  id: `${scope}.videoDurationError`,
68
72
  defaultMessage: 'Video duration should not exceed 600 seconds',
69
73
  },
74
+ uploadVideo: {
75
+ id: `${scope}.uploadVideo`,
76
+ defaultMessage: 'Upload Video',
77
+ },
78
+ reUpload: {
79
+ id: `${scope}.reUpload`,
80
+ defaultMessage: 'Re-upload',
81
+ },
82
+ videoDuration: {
83
+ id: `${scope}.videoDuration`,
84
+ defaultMessage: 'Duration: {duration}',
85
+ },
70
86
  });
@@ -1,11 +1,11 @@
1
- import React, { Component } from "react";
2
- import { Carousel, Icon } from 'antd';
1
+ import React from "react";
2
+ import { Carousel } from 'antd';
3
3
  import './style.scss';
4
4
  import CapImage from '@capillarytech/cap-ui-library/CapImage';
5
5
  import CapButton from '@capillarytech/cap-ui-library/CapButton';
6
6
  import CapIcon from '@capillarytech/cap-ui-library/CapIcon';
7
+ import { CAP_WHITE } from '@capillarytech/cap-ui-library/styled/variables';
7
8
  const lineImgPlaceholder = require('../../assets/line-image-placeholder.svg');
8
- import { CAP_WHITE, CAP_G08 } from '@capillarytech/cap-ui-library/styled/variables';
9
9
 
10
10
  const arrowStyle = {
11
11
  background: 'rgba(0, 0, 0, 0.1)',
@@ -16,10 +16,12 @@ const arrowStyle = {
16
16
  height: 24,
17
17
  width: 24,
18
18
  borderRadius: '50%',
19
- }
19
+ };
20
20
 
21
- const Arrow = props => {
22
- const { className, style, onClick, extraStyle, type } = props
21
+ const Arrow = (props) => {
22
+ const {
23
+ className, style, onClick, extraStyle, type,
24
+ } = props;
23
25
  return (
24
26
  <CapButton
25
27
  className={className}
@@ -35,8 +37,8 @@ const Arrow = props => {
35
37
  type={type}
36
38
  />
37
39
  </CapButton>
38
- )
39
- }
40
+ );
41
+ };
40
42
 
41
43
  const settings = {
42
44
  nextArrow: (
@@ -56,7 +58,7 @@ const settings = {
56
58
  type="chevron-left"
57
59
  />
58
60
  ),
59
- }
61
+ };
60
62
 
61
63
  const CarouselComponent = ({
62
64
  imageCarousel,
@@ -81,11 +83,11 @@ const CarouselComponent = ({
81
83
 
82
84
  return (
83
85
  <div style={{ position: 'relative' }} className={`template-carousel ${imageCarouselLength ? 'single-img' : ''}`}>
84
- <Carousel ref={node => (carousel = node)} {...prop} {...settings}>
86
+ <Carousel ref={(node) => (carousel = node)} {...prop} {...settings}>
85
87
  {
86
88
  imageCarousel.map(({
87
89
  actionLabel,
88
- imageUrl = lineImgPlaceholder
90
+ imageUrl = lineImgPlaceholder,
89
91
  }) => (
90
92
  <div className="carousel-section">
91
93
  <CapImage
@@ -115,6 +117,6 @@ const CarouselComponent = ({
115
117
  </Carousel>
116
118
  </div>
117
119
  );
118
- }
120
+ };
119
121
 
120
- export default CarouselComponent;
122
+ export default CarouselComponent;
@@ -51,6 +51,7 @@ const CustomerSearchSection = ({
51
51
  }) => {
52
52
  const [showDropdown, setShowDropdown] = useState(false);
53
53
  const [customerSearchValue, setCustomerSearchValue] = useState('');
54
+ const [processedSearchData, setProcessedSearchData] = useState([]);
54
55
 
55
56
  const searchContainerRef = useRef(null);
56
57
 
@@ -114,6 +115,12 @@ const CustomerSearchSection = ({
114
115
  }
115
116
  }, [customerSearchValue, isSearchingCustomer, hasSearched]);
116
117
 
118
+ // Compute search data when dependencies change
119
+ useEffect(() => {
120
+ const computedData = searchData();
121
+ setProcessedSearchData(computedData);
122
+ }, [isSearchingCustomer, customers, customerSearchValue]);
123
+
117
124
  const getCompleteName = (data) => {
118
125
  const { firstName = '', lastName = '' } = data?.[0] || {};
119
126
  return `${firstName} ${lastName}`.trim() || NA;
@@ -140,8 +147,6 @@ const CustomerSearchSection = ({
140
147
  return finalSearchData || [];
141
148
  };
142
149
 
143
- const getSearchData = searchData();
144
-
145
150
  const showIdentifiers = (data) => {
146
151
  if (!Array.isArray(data) || data.length === 0) return null;
147
152
 
@@ -197,7 +202,7 @@ const CustomerSearchSection = ({
197
202
  {showDropdown && !selectedCustomer && (
198
203
  <CapRow className="search-dropdown-container">
199
204
  <CapRow type="flex" justify="center" align="middle">
200
- {(getSearchData?.length === 0 && customerSearchValue != null && !isSearchingCustomer) && (
205
+ {(processedSearchData?.length === 0 && customerSearchValue != null && !isSearchingCustomer) && (
201
206
  <CapCard className="validation-card">
202
207
  <CapHeading type="h6">
203
208
  {formatMessage(messages.noCustomersFound)}
@@ -213,11 +218,11 @@ const CustomerSearchSection = ({
213
218
  )}
214
219
  </CapRow>
215
220
  <CapRow type="flex" justify="center" align="middle">
216
- {getSearchData?.length > 0 && (
221
+ {processedSearchData?.length > 0 && (
217
222
  <CapCard className="search-result-card scroll-bar">
218
223
  {
219
224
  <CapRow className="identifier-row">
220
- {getSearchData?.map((d) => (
225
+ {processedSearchData?.map((d) => (
221
226
  <>
222
227
  <CapLink
223
228
  key={d?.customerId}
@@ -294,7 +299,7 @@ const SearchInput = ({
294
299
  );
295
300
 
296
301
  const SelectedCustomerView = ({ customer, onClear, showIdentifiers }) => (
297
- <CapRow className="selected-customer-view">
302
+ <div className="selected-customer-view">
298
303
  <CapRow type="flex" align="middle" gutter={8}>
299
304
  <CapColumn>
300
305
  <CapRow className="customer-common-profile">{getNamingIcon(customer?.name)}</CapRow>
@@ -311,7 +316,7 @@ const SelectedCustomerView = ({ customer, onClear, showIdentifiers }) => (
311
316
  </CapColumn>
312
317
  </CapRow>
313
318
  <CapIcon size="s" type="close" className="clear-icon" onClick={onClear} />
314
- </CapRow>
319
+ </div>
315
320
  );
316
321
 
317
322
  SelectedCustomerView.propTypes = {
@@ -1,6 +1,7 @@
1
1
  @import "~@capillarytech/cap-ui-library/styles/_variables.scss";
2
2
 
3
3
  .error-container {
4
+ width: max-content;
4
5
  margin-bottom: $CAP_SPACE_08;
5
6
  margin-top: $CAP_SPACE_12;
6
7
  background-color: $CAP_COLOR_05;