box-ui-elements 23.4.0-beta.13 → 23.4.0-beta.14

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 (55) hide show
  1. package/es/elements/common/upload-dialog/UploadDialog.js +1 -0
  2. package/es/elements/common/upload-dialog/UploadDialog.js.flow +1 -0
  3. package/es/elements/common/upload-dialog/UploadDialog.js.map +1 -1
  4. package/es/elements/index.js +1 -0
  5. package/es/elements/index.js.flow +1 -0
  6. package/es/elements/index.js.map +1 -1
  7. package/es/elements/wrappers/ContentUploader.js +2 -0
  8. package/es/elements/wrappers/ContentUploader.js.flow +2 -0
  9. package/es/elements/wrappers/ContentUploader.js.map +1 -1
  10. package/i18n/ja-JP.js +2 -2
  11. package/i18n/ja-JP.properties +2 -2
  12. package/package.json +1 -1
  13. package/src/elements/common/upload-dialog/UploadDialog.js +1 -0
  14. package/src/elements/index.js +1 -0
  15. package/src/elements/wrappers/ContentUploader.js +2 -0
  16. package/es/elements/content-uploader/ContentUploader.js.flow +0 -1322
  17. package/es/elements/content-uploader/ContentUploaderPopup.js.flow +0 -11
  18. package/es/elements/content-uploader/DroppableContent.js.flow +0 -82
  19. package/es/elements/content-uploader/Footer.js.flow +0 -63
  20. package/es/elements/content-uploader/IconName.js.flow +0 -45
  21. package/es/elements/content-uploader/ItemAction.js.flow +0 -128
  22. package/es/elements/content-uploader/ItemList.js.flow +0 -79
  23. package/es/elements/content-uploader/ItemRemove.js.flow +0 -51
  24. package/es/elements/content-uploader/OverallUploadsProgressBar.js.flow +0 -111
  25. package/es/elements/content-uploader/ProgressBar.js.flow +0 -65
  26. package/es/elements/content-uploader/UploadInput.js.flow +0 -50
  27. package/es/elements/content-uploader/UploadState.js.flow +0 -114
  28. package/es/elements/content-uploader/UploadStateContent.js.flow +0 -71
  29. package/es/elements/content-uploader/UploadsManager.js.flow +0 -111
  30. package/es/elements/content-uploader/UploadsManagerAction.js.flow +0 -36
  31. package/es/elements/content-uploader/actionCellRenderer.js.flow +0 -18
  32. package/es/elements/content-uploader/index.js.flow +0 -4
  33. package/es/elements/content-uploader/nameCellRenderer.js.flow +0 -13
  34. package/es/elements/content-uploader/progressCellRenderer.js.flow +0 -81
  35. package/es/elements/content-uploader/removeCellRenderer.js.flow +0 -16
  36. package/src/elements/content-uploader/ContentUploader.js.flow +0 -1322
  37. package/src/elements/content-uploader/ContentUploaderPopup.js.flow +0 -11
  38. package/src/elements/content-uploader/DroppableContent.js.flow +0 -82
  39. package/src/elements/content-uploader/Footer.js.flow +0 -63
  40. package/src/elements/content-uploader/IconName.js.flow +0 -45
  41. package/src/elements/content-uploader/ItemAction.js.flow +0 -128
  42. package/src/elements/content-uploader/ItemList.js.flow +0 -79
  43. package/src/elements/content-uploader/ItemRemove.js.flow +0 -51
  44. package/src/elements/content-uploader/OverallUploadsProgressBar.js.flow +0 -111
  45. package/src/elements/content-uploader/ProgressBar.js.flow +0 -65
  46. package/src/elements/content-uploader/UploadInput.js.flow +0 -50
  47. package/src/elements/content-uploader/UploadState.js.flow +0 -114
  48. package/src/elements/content-uploader/UploadStateContent.js.flow +0 -71
  49. package/src/elements/content-uploader/UploadsManager.js.flow +0 -111
  50. package/src/elements/content-uploader/UploadsManagerAction.js.flow +0 -36
  51. package/src/elements/content-uploader/actionCellRenderer.js.flow +0 -18
  52. package/src/elements/content-uploader/index.js.flow +0 -4
  53. package/src/elements/content-uploader/nameCellRenderer.js.flow +0 -13
  54. package/src/elements/content-uploader/progressCellRenderer.js.flow +0 -81
  55. package/src/elements/content-uploader/removeCellRenderer.js.flow +0 -16
@@ -1,1322 +0,0 @@
1
- /**
2
- * @flow
3
- * @file Content Uploader component
4
- * @author Box
5
- */
6
-
7
- import 'regenerator-runtime/runtime';
8
- import React, { Component } from 'react';
9
- import classNames from 'classnames';
10
- import getProp from 'lodash/get';
11
- import noop from 'lodash/noop';
12
- import uniqueid from 'lodash/uniqueId';
13
- import cloneDeep from 'lodash/cloneDeep';
14
- import { TooltipProvider } from '@box/blueprint-web';
15
- import { getTypedFileId, getTypedFolderId } from '../../utils/file';
16
- import Browser from '../../utils/Browser';
17
-
18
- import makeResponsive from '../common/makeResponsive';
19
- import Internationalize from '../common/Internationalize';
20
- import FolderUpload from '../../api/uploads/FolderUpload';
21
- import API from '../../api';
22
- import {
23
- getDataTransferItemId,
24
- getFileId,
25
- getFileFromDataTransferItem,
26
- getPackageFileFromDataTransferItem,
27
- getFile,
28
- getFileAPIOptions,
29
- getDataTransferItemAPIOptions,
30
- isDataTransferItemAFolder,
31
- isDataTransferItemAPackage,
32
- isMultiputSupported,
33
- } from '../../utils/uploads';
34
- import DroppableContent from './DroppableContent';
35
- import UploadsManager from './UploadsManager';
36
- import Footer from './Footer';
37
- import {
38
- DEFAULT_ROOT,
39
- CLIENT_NAME_CONTENT_UPLOADER,
40
- DEFAULT_HOSTNAME_UPLOAD,
41
- DEFAULT_HOSTNAME_API,
42
- VIEW_ERROR,
43
- VIEW_UPLOAD_EMPTY,
44
- VIEW_UPLOAD_IN_PROGRESS,
45
- VIEW_UPLOAD_SUCCESS,
46
- STATUS_PENDING,
47
- STATUS_IN_PROGRESS,
48
- STATUS_STAGED,
49
- STATUS_COMPLETE,
50
- STATUS_ERROR,
51
- ERROR_CODE_UPLOAD_FILE_LIMIT,
52
- } from '../../constants';
53
- import type {
54
- UploadItem,
55
- UploadDataTransferItemWithAPIOptions,
56
- UploadFileWithAPIOptions,
57
- UploadFile,
58
- UploadItemAPIOptions,
59
- UploadStatus,
60
- } from '../../common/types/upload';
61
- import type { StringMap, Token, View, BoxItem } from '../../common/types/core';
62
- import '../common/fonts.scss';
63
- import '../common/base.scss';
64
-
65
- type Props = {
66
- apiHost: string,
67
- chunked: boolean,
68
- className: string,
69
- clientName: string,
70
- dataTransferItems: Array<DataTransferItem | UploadDataTransferItemWithAPIOptions>,
71
- fileLimit: number,
72
- files?: Array<UploadFileWithAPIOptions | File>,
73
- isDraggingItemsToUploadsManager?: boolean,
74
- isFolderUploadEnabled: boolean,
75
- isLarge: boolean,
76
- isPartialUploadEnabled: boolean,
77
- isPrepopulateFilesEnabled?: boolean,
78
- isResumableUploadsEnabled: boolean,
79
- isSmall: boolean,
80
- isTouch: boolean,
81
- isUploadFallbackLogicEnabled: boolean,
82
- language?: string,
83
- measureRef: Function,
84
- messages?: StringMap,
85
- onBeforeUpload: (file: Array<UploadFileWithAPIOptions | File>) => void,
86
- onCancel: Function,
87
- onClickCancel: UploadItem => void,
88
- onClickResume: UploadItem => void,
89
- onClickRetry: UploadItem => void,
90
- onClose: Function,
91
- onComplete: Function,
92
- onError: Function,
93
- onMinimize?: Function,
94
- onProgress: Function,
95
- onResume: Function,
96
- onUpgradeCTAClick?: Function,
97
- onUpload: Function,
98
- overwrite: boolean,
99
- requestInterceptor?: Function,
100
- responseInterceptor?: Function,
101
- rootFolderId: string,
102
- sharedLink?: string,
103
- sharedLinkPassword?: string,
104
- token?: Token,
105
- uploadHost: string,
106
- useUploadsManager?: boolean,
107
- };
108
-
109
- type State = {
110
- errorCode?: string,
111
- isUploadsManagerExpanded: boolean,
112
- itemIds: Object,
113
- items: UploadItem[],
114
- view: View,
115
- };
116
-
117
- const CHUNKED_UPLOAD_MIN_SIZE_BYTES = 104857600; // 100MB
118
- const FILE_LIMIT_DEFAULT = 100; // Upload at most 100 files at once by default
119
- const HIDE_UPLOAD_MANAGER_DELAY_MS_DEFAULT = 8000;
120
- const EXPAND_UPLOADS_MANAGER_ITEMS_NUM_THRESHOLD = 5;
121
- const UPLOAD_CONCURRENCY = 6;
122
-
123
- class ContentUploader extends Component<Props, State> {
124
- id: string;
125
-
126
- state: State;
127
-
128
- props: Props;
129
-
130
- rootElement: HTMLElement;
131
-
132
- appElement: HTMLElement;
133
-
134
- resetItemsTimeout: TimeoutID;
135
-
136
- isAutoExpanded: boolean = false;
137
-
138
- static defaultProps = {
139
- rootFolderId: DEFAULT_ROOT,
140
- apiHost: DEFAULT_HOSTNAME_API,
141
- chunked: true,
142
- className: '',
143
- clientName: CLIENT_NAME_CONTENT_UPLOADER,
144
- fileLimit: FILE_LIMIT_DEFAULT,
145
- uploadHost: DEFAULT_HOSTNAME_UPLOAD,
146
- onBeforeUpload: noop,
147
- onClickCancel: noop,
148
- onClickResume: noop,
149
- onClickRetry: noop,
150
- onClose: noop,
151
- onComplete: noop,
152
- onError: noop,
153
- onResume: noop,
154
- onUpload: noop,
155
- onProgress: noop,
156
- overwrite: true,
157
- useUploadsManager: false,
158
- files: [],
159
- onMinimize: noop,
160
- onCancel: noop,
161
- isFolderUploadEnabled: false,
162
- isResumableUploadsEnabled: false,
163
- isUploadFallbackLogicEnabled: false,
164
- dataTransferItems: [],
165
- isDraggingItemsToUploadsManager: false,
166
- isPartialUploadEnabled: false,
167
- isPrepopulateFilesEnabled: false,
168
- };
169
-
170
- /**
171
- * [constructor]
172
- *
173
- * @return {ContentUploader}
174
- */
175
- constructor(props: Props) {
176
- super(props);
177
-
178
- const { rootFolderId, token, useUploadsManager } = props;
179
- this.state = {
180
- view: (rootFolderId && token) || useUploadsManager ? VIEW_UPLOAD_EMPTY : VIEW_ERROR,
181
- items: [],
182
- errorCode: '',
183
- itemIds: {},
184
- isUploadsManagerExpanded: false,
185
- };
186
- this.id = uniqueid('bcu_');
187
- }
188
-
189
- /**
190
- * Fetches the root folder on load
191
- *
192
- * @private
193
- * @inheritdoc
194
- * @return {void}
195
- */
196
- componentDidMount() {
197
- this.rootElement = ((document.getElementById(this.id): any): HTMLElement);
198
- this.appElement = this.rootElement;
199
- const { files, isPrepopulateFilesEnabled } = this.props;
200
- // isPrepopulateFilesEnabled is a prop used to pre-populate files without clicking upload button.
201
- if (isPrepopulateFilesEnabled && files && files.length > 0) {
202
- this.addFilesToUploadQueue(files, this.upload);
203
- }
204
- }
205
-
206
- /**
207
- * Cancels pending uploads
208
- *
209
- * @private
210
- * @inheritdoc
211
- * @return {void}
212
- */
213
- componentWillUnmount() {
214
- this.cancel();
215
- }
216
-
217
- /**
218
- * Adds new items to the queue when files prop gets updated in window view
219
- *
220
- * @return {void}
221
- */
222
- componentDidUpdate(): void {
223
- const { files, dataTransferItems, useUploadsManager } = this.props;
224
-
225
- const hasFiles = Array.isArray(files) && files.length > 0;
226
- const hasItems = Array.isArray(dataTransferItems) && dataTransferItems.length > 0;
227
- const hasUploads = hasFiles || hasItems;
228
-
229
- if (!useUploadsManager || !hasUploads) {
230
- return;
231
- }
232
-
233
- // TODO: this gets called unnecessarily (upon each render regardless of the queue not changing)
234
- this.addFilesWithOptionsToUploadQueueAndStartUpload(files, dataTransferItems);
235
- }
236
-
237
- /**
238
- * Create and return new instance of API creator
239
- *
240
- * @param {UploadItemAPIOptions} [uploadAPIOptions]
241
- * @return {API}
242
- */
243
- createAPIFactory(uploadAPIOptions?: UploadItemAPIOptions): API {
244
- const { rootFolderId } = this.props;
245
- const folderId = getProp(uploadAPIOptions, 'folderId') || rootFolderId;
246
- const fileId = getProp(uploadAPIOptions, 'fileId');
247
- const itemFolderId = getTypedFolderId(folderId);
248
- const itemFileId = fileId ? getTypedFileId(fileId) : null;
249
-
250
- return new API({
251
- ...this.getBaseAPIOptions(),
252
- id: itemFileId || itemFolderId,
253
- ...uploadAPIOptions,
254
- });
255
- }
256
-
257
- /**
258
- * Return base API options from props
259
- *
260
- * @private
261
- * @returns {Object}
262
- */
263
- getBaseAPIOptions = (): Object => {
264
- const {
265
- token,
266
- sharedLink,
267
- sharedLinkPassword,
268
- apiHost,
269
- uploadHost,
270
- clientName,
271
- requestInterceptor,
272
- responseInterceptor,
273
- } = this.props;
274
-
275
- return {
276
- token,
277
- sharedLink,
278
- sharedLinkPassword,
279
- apiHost,
280
- uploadHost,
281
- clientName,
282
- requestInterceptor,
283
- responseInterceptor,
284
- };
285
- };
286
-
287
- /**
288
- * Given an array of files, return the files that are new to the Content Uploader
289
- *
290
- * @param {Array<UploadFileWithAPIOptions | File>} files
291
- */
292
- getNewFiles = (files: Array<UploadFileWithAPIOptions | File>): Array<UploadFileWithAPIOptions | File> => {
293
- const { rootFolderId } = this.props;
294
- const { itemIds } = this.state;
295
-
296
- return Array.from(files).filter(file => !itemIds[getFileId(file, rootFolderId)]);
297
- };
298
-
299
- /**
300
- * Given an array of files, return the files that are new to the Content Uploader
301
- *
302
- * @param {Array<UploadFileWithAPIOptions | File>} files
303
- */
304
- getNewDataTransferItems = (
305
- items: Array<DataTransferItem | UploadDataTransferItemWithAPIOptions>,
306
- ): Array<DataTransferItem | UploadDataTransferItemWithAPIOptions> => {
307
- const { rootFolderId } = this.props;
308
- const { itemIds } = this.state;
309
-
310
- return Array.from(items).filter(item => !itemIds[getDataTransferItemId(item, rootFolderId)]);
311
- };
312
-
313
- /**
314
- * Converts File API to upload items and adds to upload queue.
315
- *
316
- * @private
317
- * @param {Array<UploadFileWithAPIOptions | UploadFile>} files - Files to be added to upload queue
318
- * @param {Function} itemUpdateCallback - function to be invoked after items status are updated
319
- * @param {boolean} [isRelativePathIgnored] - if true webkitRelativePath property is ignored
320
- * @return {void}
321
- */
322
- addFilesToUploadQueue = (
323
- files?: Array<UploadFileWithAPIOptions | UploadFile>,
324
- itemUpdateCallback: Function,
325
- isRelativePathIgnored?: boolean = false,
326
- ) => {
327
- const { onBeforeUpload, rootFolderId, isPrepopulateFilesEnabled } = this.props;
328
- if (!files || files.length === 0) {
329
- return;
330
- }
331
-
332
- const newFiles = this.getNewFiles(files);
333
-
334
- if (newFiles.length === 0) {
335
- return;
336
- }
337
-
338
- const newItemIds = {};
339
-
340
- newFiles.forEach(file => {
341
- newItemIds[getFileId(file, rootFolderId)] = true;
342
- });
343
-
344
- clearTimeout(this.resetItemsTimeout);
345
-
346
- const firstFile = getFile(newFiles[0]);
347
-
348
- this.setState(
349
- state => ({
350
- itemIds: {
351
- ...state.itemIds,
352
- ...newItemIds,
353
- },
354
- }),
355
- () => {
356
- onBeforeUpload(newFiles);
357
- if (firstFile.webkitRelativePath && !isRelativePathIgnored) {
358
- // webkitRelativePath should be ignored when the upload destination folder is known
359
- this.addFilesWithRelativePathToQueue(newFiles, itemUpdateCallback);
360
- } else {
361
- this.addFilesWithoutRelativePathToQueue(
362
- newFiles,
363
- isPrepopulateFilesEnabled ? this.upload : itemUpdateCallback,
364
- );
365
- }
366
- },
367
- );
368
- };
369
-
370
- /**
371
- * Add dropped items to the upload queue
372
- *
373
- * @private
374
- * @param {DataTransfer} droppedItems
375
- * @param {Function} itemUpdateCallback
376
- * @returns {Promise<any>}
377
- */
378
- addDroppedItemsToUploadQueue = (droppedItems: DataTransfer, itemUpdateCallback: Function): void => {
379
- if (droppedItems.items) {
380
- this.addDataTransferItemsToUploadQueue(droppedItems.items, itemUpdateCallback);
381
- } else {
382
- this.addFilesToUploadQueue(Array.from(droppedItems.files), itemUpdateCallback);
383
- }
384
- };
385
-
386
- /**
387
- * Add dataTransferItems to the upload queue
388
- *
389
- * @private
390
- * @param {DataTransferItemList} dataTransferItems
391
- * @param {Function} itemUpdateCallback
392
- * @returns {Promise<any>}
393
- */
394
- addDataTransferItemsToUploadQueue = (
395
- dataTransferItems: DataTransferItemList | Array<DataTransferItem | UploadDataTransferItemWithAPIOptions>,
396
- itemUpdateCallback: Function,
397
- ): void => {
398
- const { isFolderUploadEnabled } = this.props;
399
- if (!dataTransferItems || dataTransferItems.length === 0) {
400
- return;
401
- }
402
-
403
- const folderItems = [];
404
- const fileItems = [];
405
- const packageItems = [];
406
- Array.from(dataTransferItems).forEach(item => {
407
- const isDirectory = isDataTransferItemAFolder(item);
408
- if (Browser.isSafari() && isDataTransferItemAPackage(item)) {
409
- packageItems.push(item);
410
- } else if (isDirectory && isFolderUploadEnabled) {
411
- folderItems.push(item);
412
- } else if (!isDirectory) {
413
- fileItems.push(item);
414
- }
415
- });
416
-
417
- this.addFileDataTransferItemsToUploadQueue(fileItems, itemUpdateCallback);
418
- this.addPackageDataTransferItemsToUploadQueue(packageItems, itemUpdateCallback);
419
- this.addFolderDataTransferItemsToUploadQueue(folderItems, itemUpdateCallback);
420
- };
421
-
422
- /**
423
- * Add dataTransferItem of file type to the upload queue
424
- *
425
- * @private
426
- * @param {Array<DataTransferItem | UploadDataTransferItemWithAPIOptions>} dataTransferItems
427
- * @param {Function} itemUpdateCallback
428
- * @returns {Promise<any>}
429
- */
430
- addFileDataTransferItemsToUploadQueue = async (
431
- dataTransferItems: Array<DataTransferItem | UploadDataTransferItemWithAPIOptions>,
432
- itemUpdateCallback: Function,
433
- ): Promise<any> => {
434
- const files = await Promise.all(dataTransferItems.map(async item => getFileFromDataTransferItem(item)));
435
- const filesArray = [];
436
- files.forEach(file => {
437
- if (file) {
438
- filesArray.push(file);
439
- }
440
- });
441
- this.addFilesToUploadQueue(filesArray, itemUpdateCallback);
442
- };
443
-
444
- /**
445
- * Add dataTransferItem of package type to the upload queue
446
- *
447
- * @private
448
- * @param {Array<DataTransferItem | UploadDataTransferItemWithAPIOptions>} dataTransferItems
449
- * @param {Function} itemUpdateCallback
450
- * @returns {Promise<any>}
451
- */
452
- addPackageDataTransferItemsToUploadQueue = async (
453
- dataTransferItems: Array<DataTransferItem | UploadDataTransferItemWithAPIOptions>,
454
- itemUpdateCallback: Function,
455
- ): Promise<any> => {
456
- const packageFiles = await Promise.all(
457
- dataTransferItems.map(async item => getPackageFileFromDataTransferItem(item)),
458
- );
459
- const packageFilesArray = [];
460
- packageFiles.forEach(packageFile => {
461
- if (packageFile) {
462
- packageFilesArray.push(packageFile);
463
- }
464
- });
465
- this.addFilesToUploadQueue(packageFilesArray, itemUpdateCallback);
466
- };
467
-
468
- /**
469
- * Add dataTransferItem of folder type to the upload queue
470
- *
471
- * @private
472
- * @param {Array<DataTransferItem | UploadDataTransferItemWithAPIOptions>} dataTransferItems
473
- * @param {Function} itemUpdateCallback
474
- * @returns {Promise<any>}
475
- */
476
- addFolderDataTransferItemsToUploadQueue = async (
477
- dataTransferItems: Array<DataTransferItem | UploadDataTransferItemWithAPIOptions>,
478
- itemUpdateCallback: Function,
479
- ): Promise<any> => {
480
- const { rootFolderId } = this.props;
481
- const { itemIds } = this.state;
482
- if (dataTransferItems.length === 0) {
483
- return;
484
- }
485
-
486
- const newItems = this.getNewDataTransferItems(dataTransferItems);
487
- newItems.forEach(item => {
488
- itemIds[getDataTransferItemId(item, rootFolderId)] = true;
489
- });
490
-
491
- if (newItems.length === 0) {
492
- return;
493
- }
494
-
495
- const fileAPIOptions: Object = getDataTransferItemAPIOptions(newItems[0]);
496
- const { folderId = rootFolderId } = fileAPIOptions;
497
- const folderUploads = await Promise.all(
498
- newItems.map(async item => {
499
- const folderUpload = this.getFolderUploadAPI(folderId);
500
- await folderUpload.buildFolderTreeFromDataTransferItem(item);
501
- return folderUpload;
502
- }),
503
- );
504
- const folderUploadsArray = [];
505
- folderUploads.forEach(folderUpload => {
506
- // $FlowFixMe no file property
507
- folderUploadsArray.push({
508
- api: folderUpload,
509
- extension: '',
510
- isFolder: true,
511
- name: folderUpload.folder.name,
512
- options: fileAPIOptions,
513
- progress: 0,
514
- size: 1,
515
- status: STATUS_PENDING,
516
- });
517
- });
518
- this.addToQueue(folderUploadsArray, itemUpdateCallback);
519
- };
520
-
521
- /**
522
- * Converts File API to upload items and adds to upload queue for files with webkitRelativePath.
523
- *
524
- * @private
525
- * @param {Array<UploadFileWithAPIOptions | File>} files - Files to be added to upload queue
526
- * @param {Function} itemUpdateCallback - function to be invoked after items status are updated
527
- * @return {void}
528
- */
529
- addFilesWithRelativePathToQueue(files: Array<UploadFileWithAPIOptions | File>, itemUpdateCallback: Function) {
530
- if (files.length === 0) {
531
- return;
532
- }
533
-
534
- const { rootFolderId } = this.props;
535
- const fileAPIOptions: Object = getFileAPIOptions(files[0]);
536
- const { folderId = rootFolderId } = fileAPIOptions;
537
- const folderUpload = this.getFolderUploadAPI(folderId);
538
-
539
- // Only 1 folder tree can be built with files having webkitRelativePath properties
540
- folderUpload.buildFolderTreeFromWebkitRelativePath(files);
541
-
542
- this.addFolderToUploadQueue(folderUpload, itemUpdateCallback, fileAPIOptions);
543
- }
544
-
545
- /**
546
- * Get folder upload API instance
547
- *
548
- * @private
549
- * @param {string} folderId
550
- * @return {FolderUpload}
551
- */
552
- getFolderUploadAPI = (folderId: string): FolderUpload => {
553
- const uploadBaseAPIOptions = this.getBaseAPIOptions();
554
-
555
- return new FolderUpload(this.addFilesToUploadQueue, folderId, this.addToQueue, uploadBaseAPIOptions);
556
- };
557
-
558
- /**
559
- * Add folder to upload queue
560
- *
561
- * @private
562
- * @param {FolderUpload} folderUpload
563
- * @param {Function} itemUpdateCallback
564
- * @param {Object} apiOptions
565
- * @return {void}
566
- */
567
- addFolderToUploadQueue = (folderUpload: FolderUpload, itemUpdateCallback: Function, apiOptions: Object): void => {
568
- this.addToQueue(
569
- [
570
- // $FlowFixMe no file property
571
- {
572
- api: folderUpload,
573
- extension: '',
574
- isFolder: true,
575
- name: folderUpload.folder.name,
576
- options: apiOptions,
577
- progress: 0,
578
- size: 1,
579
- status: STATUS_PENDING,
580
- },
581
- ],
582
- itemUpdateCallback,
583
- );
584
- };
585
-
586
- /**
587
- * Converts File API to upload items and adds to upload queue for files with webkitRelativePath missing or ignored.
588
- *
589
- * @private
590
- * @param {Array<UploadFileWithAPIOptions | File>} files - Files to be added to upload queue
591
- * @param {Function} itemUpdateCallback - function to be invoked after items status are updated
592
- * @return {void}
593
- */
594
- addFilesWithoutRelativePathToQueue = (
595
- files: Array<UploadFileWithAPIOptions | File>,
596
- itemUpdateCallback: Function,
597
- ) => {
598
- const { itemIds } = this.state;
599
- const { rootFolderId } = this.props;
600
-
601
- // Convert files from the file API to upload items
602
- const newItems = files.map(file => {
603
- const uploadFile = getFile(file);
604
- const uploadAPIOptions = getFileAPIOptions(file);
605
- const { name, size } = uploadFile;
606
-
607
- // Extract extension or use empty string if file has no extension
608
- let extension = name.substr(name.lastIndexOf('.') + 1);
609
- if (extension.length === name.length) {
610
- extension = '';
611
- }
612
-
613
- const api = this.getUploadAPI(uploadFile, uploadAPIOptions);
614
- const uploadItem: Object = {
615
- api,
616
- extension,
617
- file: uploadFile,
618
- name,
619
- progress: 0,
620
- size,
621
- status: STATUS_PENDING,
622
- };
623
-
624
- if (uploadAPIOptions) {
625
- uploadItem.options = uploadAPIOptions;
626
- }
627
-
628
- itemIds[getFileId(uploadItem, rootFolderId)] = true;
629
-
630
- return uploadItem;
631
- });
632
-
633
- if (newItems.length === 0) {
634
- return;
635
- }
636
-
637
- this.setState({
638
- itemIds,
639
- });
640
- this.addToQueue(newItems, itemUpdateCallback);
641
- };
642
-
643
- /**
644
- * Add new items to the upload queue
645
- *
646
- * @private
647
- * @param {Array<UploadFileWithAPIOptions | File>} newItems - Files to be added to upload queue
648
- * @param {Function} itemUpdateCallback - function to be invoked after items status are updated
649
- * @return {void}
650
- */
651
- addToQueue = (newItems: UploadItem[], itemUpdateCallback: Function) => {
652
- const { fileLimit, useUploadsManager } = this.props;
653
- const { items, isUploadsManagerExpanded } = this.state;
654
-
655
- let updatedItems = [];
656
- const prevItemsNum = items.length;
657
- const totalNumOfItems = prevItemsNum + newItems.length;
658
-
659
- // Don't add more than fileLimit # of items
660
- if (totalNumOfItems > fileLimit) {
661
- updatedItems = items.concat(newItems.slice(0, fileLimit - items.length));
662
- this.setState({
663
- errorCode: ERROR_CODE_UPLOAD_FILE_LIMIT,
664
- });
665
- } else {
666
- updatedItems = items.concat(newItems);
667
- this.setState({ errorCode: '' });
668
-
669
- // If the number of items being uploaded passes the threshold, expand the upload manager
670
- if (
671
- prevItemsNum < EXPAND_UPLOADS_MANAGER_ITEMS_NUM_THRESHOLD &&
672
- totalNumOfItems >= EXPAND_UPLOADS_MANAGER_ITEMS_NUM_THRESHOLD &&
673
- useUploadsManager &&
674
- !isUploadsManagerExpanded
675
- ) {
676
- this.isAutoExpanded = true;
677
- this.expandUploadsManager();
678
- }
679
- }
680
-
681
- this.updateViewAndCollection(updatedItems, () => {
682
- if (itemUpdateCallback) {
683
- itemUpdateCallback();
684
- }
685
-
686
- const { view } = this.state;
687
- // Automatically start upload if other files are being uploaded
688
- if (view === VIEW_UPLOAD_IN_PROGRESS) {
689
- this.upload();
690
- }
691
- });
692
- };
693
-
694
- /**
695
- * Returns a new API instance for the given file.
696
- *
697
- * @private
698
- * @param {File} file - File to get a new API instance for
699
- * @param {UploadItemAPIOptions} [uploadAPIOptions]
700
- * @return {UploadAPI} - Instance of Upload API
701
- */
702
- getUploadAPI(file: File, uploadAPIOptions?: UploadItemAPIOptions) {
703
- const { chunked, isResumableUploadsEnabled, isUploadFallbackLogicEnabled } = this.props;
704
- const { size } = file;
705
- const factory = this.createAPIFactory(uploadAPIOptions);
706
-
707
- if (chunked && size > CHUNKED_UPLOAD_MIN_SIZE_BYTES) {
708
- if (isMultiputSupported()) {
709
- const chunkedUploadAPI = factory.getChunkedUploadAPI();
710
- if (isResumableUploadsEnabled) {
711
- chunkedUploadAPI.isResumableUploadsEnabled = true;
712
- }
713
- if (isUploadFallbackLogicEnabled) {
714
- chunkedUploadAPI.isUploadFallbackLogicEnabled = true;
715
- }
716
- return chunkedUploadAPI;
717
- }
718
-
719
- /* eslint-disable no-console */
720
- console.warn(
721
- 'Chunked uploading is enabled, but not supported by your browser. You may need to enable HTTPS.',
722
- );
723
- /* eslint-enable no-console */
724
- }
725
-
726
- const plainUploadAPI = factory.getPlainUploadAPI();
727
- if (isUploadFallbackLogicEnabled) {
728
- plainUploadAPI.isUploadFallbackLogicEnabled = true;
729
- }
730
-
731
- return plainUploadAPI;
732
- }
733
-
734
- /**
735
- * Removes an item from the upload queue. Cancels upload if in progress.
736
- *
737
- * @param {UploadItem} item - Item to remove
738
- * @return {void}
739
- */
740
- removeFileFromUploadQueue = (item: UploadItem) => {
741
- const { onCancel, useUploadsManager } = this.props;
742
- const { items } = this.state;
743
- // Clear any error errorCode in footer
744
- this.setState({ errorCode: '' });
745
-
746
- const { api } = item;
747
- api.cancel();
748
-
749
- items.splice(items.indexOf(item), 1);
750
-
751
- onCancel([item]);
752
- this.updateViewAndCollection(items, () => {
753
- // Minimize uploads manager if there are no more items
754
- if (useUploadsManager && !items.length) {
755
- this.minimizeUploadsManager();
756
- }
757
-
758
- const { view } = this.state;
759
- if (view === VIEW_UPLOAD_IN_PROGRESS) {
760
- this.upload();
761
- }
762
- });
763
- };
764
-
765
- /**
766
- * Aborts uploads in progress and clears upload list.
767
- *
768
- * @private
769
- * @return {void}
770
- */
771
- cancel = () => {
772
- const { items } = this.state;
773
- items.forEach(uploadItem => {
774
- const { api, status } = uploadItem;
775
- if (status === STATUS_IN_PROGRESS) {
776
- api.cancel();
777
- }
778
- });
779
-
780
- // Reset upload collection
781
- this.updateViewAndCollection([]);
782
- };
783
-
784
- /**
785
- * Uploads all items in the upload collection.
786
- *
787
- * @private
788
- * @return {void}
789
- */
790
- upload = () => {
791
- const { items } = this.state;
792
- items.forEach(uploadItem => {
793
- if (uploadItem.status === STATUS_PENDING) {
794
- this.uploadFile(uploadItem);
795
- }
796
- });
797
- };
798
-
799
- /**
800
- * Helper to upload a single file.
801
- *
802
- * @param {UploadItem} item - Upload item object
803
- * @return {void}
804
- */
805
- uploadFile(item: UploadItem) {
806
- const { overwrite, rootFolderId } = this.props;
807
- const { api, file, options } = item;
808
- const { items } = this.state;
809
-
810
- const numItemsUploading = items.filter(item_t => item_t.status === STATUS_IN_PROGRESS).length;
811
-
812
- if (numItemsUploading >= UPLOAD_CONCURRENCY) {
813
- return;
814
- }
815
-
816
- const uploadOptions: Object = {
817
- file,
818
- folderId: options && options.folderId ? options.folderId : rootFolderId,
819
- errorCallback: error => this.handleUploadError(item, error),
820
- progressCallback: event => this.handleUploadProgress(item, event),
821
- successCallback: entries => this.handleUploadSuccess(item, entries),
822
- overwrite,
823
- fileId: options && options.fileId ? options.fileId : null,
824
- };
825
-
826
- item.status = STATUS_IN_PROGRESS;
827
- items[items.indexOf(item)] = item;
828
-
829
- api.upload(uploadOptions);
830
-
831
- this.updateViewAndCollection(items);
832
- }
833
-
834
- /**
835
- * Helper to resume uploading a single file.
836
- *
837
- * @param {UploadItem} item - Upload item object
838
- * @return {void}
839
- */
840
- resumeFile(item: UploadItem) {
841
- const { overwrite, rootFolderId, onResume } = this.props;
842
- const { api, file, options } = item;
843
- const { items } = this.state;
844
-
845
- const numItemsUploading = items.filter(item_t => item_t.status === STATUS_IN_PROGRESS).length;
846
-
847
- if (numItemsUploading >= UPLOAD_CONCURRENCY) {
848
- return;
849
- }
850
-
851
- const resumeOptions: Object = {
852
- file,
853
- folderId: options && options.folderId ? options.folderId : rootFolderId,
854
- errorCallback: error => this.handleUploadError(item, error),
855
- progressCallback: event => this.handleUploadProgress(item, event),
856
- successCallback: entries => this.handleUploadSuccess(item, entries),
857
- overwrite,
858
- sessionId: api && api.sessionId ? api.sessionId : null,
859
- fileId: options && options.fileId ? options.fileId : null,
860
- };
861
-
862
- item.status = STATUS_IN_PROGRESS;
863
- delete item.error;
864
- items[items.indexOf(item)] = item;
865
-
866
- onResume(item);
867
- api.resume(resumeOptions);
868
-
869
- this.updateViewAndCollection(items);
870
- }
871
-
872
- /**
873
- * Helper to reset a file. Cancels any current upload and resets progress.
874
- *
875
- * @param {UploadItem} item - Upload item to reset
876
- * @return {void}
877
- */
878
- resetFile(item: UploadItem) {
879
- const { api, file, options } = item;
880
- if (api && typeof api.cancel === 'function') {
881
- api.cancel();
882
- }
883
-
884
- // Reset API, progress & status
885
- item.api = this.getUploadAPI(file, options);
886
- item.progress = 0;
887
- item.status = STATUS_PENDING;
888
- delete item.error;
889
-
890
- const { items } = this.state;
891
- items[items.indexOf(item)] = item;
892
-
893
- this.updateViewAndCollection(items);
894
- }
895
-
896
- /**
897
- * Handles a successful upload.
898
- *
899
- * @private
900
- * @param {UploadItem} item - Upload item corresponding to success event
901
- * @param {BoxItem[]} entries - Successfully uploaded Box File objects
902
- * @return {void}
903
- */
904
- handleUploadSuccess = (item: UploadItem, entries?: BoxItem[]) => {
905
- const { onUpload, useUploadsManager } = this.props;
906
-
907
- item.progress = 100;
908
- if (!item.error) {
909
- item.status = STATUS_COMPLETE;
910
- }
911
-
912
- // Cache Box File object of successfully uploaded item
913
- if (entries && entries.length === 1) {
914
- const [boxFile] = entries;
915
- item.boxFile = boxFile;
916
- }
917
-
918
- const { items } = this.state;
919
- items[items.indexOf(item)] = item;
920
-
921
- // Broadcast that a file has been uploaded
922
- if (useUploadsManager) {
923
- onUpload(item);
924
- this.checkClearUploadItems();
925
- } else {
926
- onUpload(item.boxFile);
927
- }
928
-
929
- this.updateViewAndCollection(items, () => {
930
- const { view } = this.state;
931
- if (view === VIEW_UPLOAD_IN_PROGRESS) {
932
- this.upload();
933
- }
934
- });
935
- };
936
-
937
- resetUploadManagerExpandState = () => {
938
- this.isAutoExpanded = false;
939
- this.setState({
940
- isUploadsManagerExpanded: false,
941
- });
942
- };
943
-
944
- /**
945
- * Updates view and internal upload collection with provided items.
946
- *
947
- * @private
948
- * @param {UploadItem[]} item - Items to update collection with
949
- * @param {Function} callback
950
- * @return {void}
951
- */
952
- updateViewAndCollection(items: UploadItem[], callback?: Function) {
953
- const { onComplete, useUploadsManager, isResumableUploadsEnabled, isPartialUploadEnabled }: Props = this.props;
954
- const someUploadIsInProgress = items.some(uploadItem => uploadItem.status !== STATUS_COMPLETE);
955
- const someUploadHasFailed = items.some(uploadItem => uploadItem.status === STATUS_ERROR);
956
- const allItemsArePending = !items.some(uploadItem => uploadItem.status !== STATUS_PENDING);
957
- const noFileIsPendingOrInProgress = items.every(
958
- uploadItem => uploadItem.status !== STATUS_PENDING && uploadItem.status !== STATUS_IN_PROGRESS,
959
- );
960
- const areAllItemsFinished = items.every(
961
- uploadItem => uploadItem.status === STATUS_COMPLETE || uploadItem.status === STATUS_ERROR,
962
- );
963
- const uploadItemsStatus = isResumableUploadsEnabled ? areAllItemsFinished : noFileIsPendingOrInProgress;
964
-
965
- let view = '';
966
- if ((items && items.length === 0) || allItemsArePending) {
967
- view = VIEW_UPLOAD_EMPTY;
968
- } else if (isPartialUploadEnabled && areAllItemsFinished) {
969
- const filesToBeUploaded = items.filter(item => item.status === STATUS_COMPLETE);
970
- view = VIEW_UPLOAD_SUCCESS;
971
-
972
- if (!useUploadsManager) {
973
- onComplete(cloneDeep(filesToBeUploaded.map(item => item.boxFile)));
974
- // Reset item collection after successful upload
975
- items = [];
976
- }
977
- } else if (someUploadHasFailed && useUploadsManager) {
978
- view = VIEW_ERROR;
979
- } else if (someUploadIsInProgress) {
980
- view = VIEW_UPLOAD_IN_PROGRESS;
981
- } else {
982
- view = VIEW_UPLOAD_SUCCESS;
983
-
984
- if (!useUploadsManager) {
985
- onComplete(cloneDeep(items.map(item => item.boxFile)));
986
- // Reset item collection after successful upload
987
- items = [];
988
- }
989
- }
990
-
991
- if (uploadItemsStatus && useUploadsManager) {
992
- if (this.isAutoExpanded) {
993
- this.resetUploadManagerExpandState();
994
- } // Else manually expanded so don't close
995
- onComplete(items);
996
- }
997
-
998
- const state: Object = {
999
- items,
1000
- view,
1001
- };
1002
-
1003
- if (items.length === 0) {
1004
- state.itemIds = {};
1005
- state.errorCode = '';
1006
- }
1007
-
1008
- this.setState(state, callback);
1009
- }
1010
-
1011
- /**
1012
- * Handles an upload error.
1013
- *
1014
- * @private
1015
- * @param {UploadItem} item - Upload item corresponding to error
1016
- * @param {Error} error - Upload error
1017
- * @return {void}
1018
- */
1019
- handleUploadError = (item: UploadItem, error: Error) => {
1020
- const { onError, useUploadsManager } = this.props;
1021
- const { file } = item;
1022
- const { items } = this.state;
1023
-
1024
- item.status = STATUS_ERROR;
1025
- item.error = error;
1026
-
1027
- const newItems = [...items];
1028
- const index = newItems.findIndex(singleItem => singleItem === item);
1029
- if (index !== -1) {
1030
- newItems[index] = item;
1031
- }
1032
-
1033
- // Broadcast that there was an error uploading a file
1034
- const errorData = useUploadsManager
1035
- ? {
1036
- item,
1037
- error,
1038
- }
1039
- : {
1040
- file,
1041
- error,
1042
- };
1043
-
1044
- onError(errorData);
1045
-
1046
- this.updateViewAndCollection(newItems, () => {
1047
- if (useUploadsManager) {
1048
- this.isAutoExpanded = true;
1049
- this.expandUploadsManager();
1050
- }
1051
- const { view } = this.state;
1052
- if (view === VIEW_UPLOAD_IN_PROGRESS) {
1053
- this.upload();
1054
- }
1055
- });
1056
- };
1057
-
1058
- /**
1059
- * Handles an upload progress event.
1060
- *
1061
- * @private
1062
- * @param {UploadItem} item - Upload item corresponding to progress event
1063
- * @param {ProgressEvent} event - Progress event
1064
- * @return {void}
1065
- */
1066
- handleUploadProgress = (item: UploadItem, event: any) => {
1067
- if (!event.total || item.status === STATUS_COMPLETE || item.status === STATUS_STAGED) {
1068
- return;
1069
- }
1070
-
1071
- item.progress = Math.min(Math.round((event.loaded / event.total) * 100), 100);
1072
- item.status = item.progress === 100 ? STATUS_STAGED : STATUS_IN_PROGRESS;
1073
-
1074
- const { onProgress } = this.props;
1075
- onProgress(item);
1076
-
1077
- const { items } = this.state;
1078
- items[items.indexOf(item)] = item;
1079
-
1080
- this.updateViewAndCollection(items);
1081
- };
1082
-
1083
- /**
1084
- * Updates item based on its status.
1085
- *
1086
- * @private
1087
- * @param {UploadItem} item - The upload item to update
1088
- * @return {void}
1089
- */
1090
- onClick = (item: UploadItem) => {
1091
- const { chunked, isResumableUploadsEnabled, onClickCancel, onClickResume, onClickRetry } = this.props;
1092
- const { status, file } = item;
1093
- const isChunkedUpload =
1094
- chunked && !item.isFolder && file.size > CHUNKED_UPLOAD_MIN_SIZE_BYTES && isMultiputSupported();
1095
- const isResumable = isResumableUploadsEnabled && isChunkedUpload && item.api.sessionId;
1096
-
1097
- switch (status) {
1098
- case STATUS_IN_PROGRESS:
1099
- case STATUS_STAGED:
1100
- case STATUS_COMPLETE:
1101
- case STATUS_PENDING:
1102
- this.removeFileFromUploadQueue(item);
1103
- onClickCancel(item);
1104
- break;
1105
- case STATUS_ERROR:
1106
- if (isResumable) {
1107
- item.bytesUploadedOnLastResume = item.api.totalUploadedBytes;
1108
- this.resumeFile(item);
1109
- onClickResume(item);
1110
- } else {
1111
- this.resetFile(item);
1112
- this.uploadFile(item);
1113
- onClickRetry(item);
1114
- }
1115
- break;
1116
- default:
1117
- break;
1118
- }
1119
- };
1120
-
1121
- /**
1122
- * Click action button for all uploads in the Uploads Manager with the given status.
1123
- *
1124
- * @private
1125
- * @param {UploadStatus} - the status that items should have for their action button to be clicked
1126
- * @return {void}
1127
- */
1128
- clickAllWithStatus = (status?: UploadStatus) => {
1129
- const { items } = this.state;
1130
-
1131
- items.forEach(item => {
1132
- if (!status || item.status === status) {
1133
- this.onClick(item);
1134
- }
1135
- });
1136
- };
1137
-
1138
- /**
1139
- * Expands the upload manager
1140
- *
1141
- * @return {void}
1142
- */
1143
- expandUploadsManager = (): void => {
1144
- const { useUploadsManager } = this.props;
1145
-
1146
- if (!useUploadsManager) {
1147
- return;
1148
- }
1149
-
1150
- clearTimeout(this.resetItemsTimeout);
1151
-
1152
- this.setState({ isUploadsManagerExpanded: true });
1153
- };
1154
-
1155
- /**
1156
- * Minimizes the upload manager
1157
- *
1158
- * @return {void}
1159
- */
1160
- minimizeUploadsManager = (): void => {
1161
- const { useUploadsManager, onMinimize } = this.props;
1162
-
1163
- if (!useUploadsManager || !onMinimize) {
1164
- return;
1165
- }
1166
-
1167
- clearTimeout(this.resetItemsTimeout);
1168
-
1169
- onMinimize();
1170
- this.resetUploadManagerExpandState();
1171
- this.checkClearUploadItems();
1172
- };
1173
-
1174
- /**
1175
- * Checks if the upload items should be cleared after a timeout
1176
- *
1177
- * @return {void}
1178
- */
1179
- checkClearUploadItems = () => {
1180
- this.resetItemsTimeout = setTimeout(
1181
- this.resetUploadsManagerItemsWhenUploadsComplete,
1182
- HIDE_UPLOAD_MANAGER_DELAY_MS_DEFAULT,
1183
- );
1184
- };
1185
-
1186
- /**
1187
- * Toggles the upload manager
1188
- *
1189
- * @return {void}
1190
- */
1191
- toggleUploadsManager = (): void => {
1192
- const { isUploadsManagerExpanded } = this.state;
1193
-
1194
- if (isUploadsManagerExpanded) {
1195
- this.minimizeUploadsManager();
1196
- } else {
1197
- this.expandUploadsManager();
1198
- }
1199
- };
1200
-
1201
- /**
1202
- * Empties the items queue
1203
- *
1204
- * @return {void}
1205
- */
1206
- resetUploadsManagerItemsWhenUploadsComplete = (): void => {
1207
- const { view, items, isUploadsManagerExpanded } = this.state;
1208
- const { useUploadsManager, onCancel } = this.props;
1209
-
1210
- // Do not reset items when upload manger is expanded or there're uploads in progress
1211
- if ((isUploadsManagerExpanded && useUploadsManager && !!items.length) || view === VIEW_UPLOAD_IN_PROGRESS) {
1212
- return;
1213
- }
1214
-
1215
- onCancel(items);
1216
-
1217
- this.setState({
1218
- items: [],
1219
- itemIds: {},
1220
- });
1221
- };
1222
-
1223
- /**
1224
- * Adds file to the upload queue and starts upload immediately
1225
- *
1226
- * @param {Array<UploadFileWithAPIOptions | File>} files - Files to be added to upload queue
1227
- * @return {void}
1228
- */
1229
- addFilesWithOptionsToUploadQueueAndStartUpload = (
1230
- files?: Array<UploadFileWithAPIOptions | File>,
1231
- dataTransferItems: Array<DataTransferItem | UploadDataTransferItemWithAPIOptions>,
1232
- ): void => {
1233
- this.addFilesToUploadQueue(files, this.upload);
1234
- this.addDataTransferItemsToUploadQueue(dataTransferItems, this.upload);
1235
- };
1236
-
1237
- /**
1238
- * Renders the content uploader
1239
- *
1240
- * @inheritdoc
1241
- * @return {Component}
1242
- */
1243
- render() {
1244
- const {
1245
- className,
1246
- fileLimit,
1247
- isDraggingItemsToUploadsManager = false,
1248
- isFolderUploadEnabled,
1249
- isResumableUploadsEnabled,
1250
- isTouch,
1251
- language,
1252
- measureRef,
1253
- messages,
1254
- onClose,
1255
- onUpgradeCTAClick,
1256
- useUploadsManager,
1257
- }: Props = this.props;
1258
- const { view, items, errorCode, isUploadsManagerExpanded }: State = this.state;
1259
- const isEmpty = items.length === 0;
1260
- const isVisible = !isEmpty || !!isDraggingItemsToUploadsManager;
1261
-
1262
- const hasFiles = items.length !== 0;
1263
- const isLoading = items.some(item => item.status === STATUS_IN_PROGRESS);
1264
- const isDone = items.every(item => item.status === STATUS_COMPLETE || item.status === STATUS_STAGED);
1265
-
1266
- const styleClassName = classNames('bcu', className, {
1267
- 'be-app-element': !useUploadsManager,
1268
- be: !useUploadsManager,
1269
- });
1270
-
1271
- return (
1272
- <Internationalize language={language} messages={messages}>
1273
- <TooltipProvider>
1274
- {useUploadsManager ? (
1275
- <div ref={measureRef} className={styleClassName} id={this.id}>
1276
- <UploadsManager
1277
- isDragging={isDraggingItemsToUploadsManager}
1278
- isExpanded={isUploadsManagerExpanded}
1279
- isResumableUploadsEnabled={isResumableUploadsEnabled}
1280
- isVisible={isVisible}
1281
- items={items}
1282
- onItemActionClick={this.onClick}
1283
- onRemoveActionClick={this.removeFileFromUploadQueue}
1284
- onUpgradeCTAClick={onUpgradeCTAClick}
1285
- onUploadsManagerActionClick={this.clickAllWithStatus}
1286
- toggleUploadsManager={this.toggleUploadsManager}
1287
- view={view}
1288
- />
1289
- </div>
1290
- ) : (
1291
- <div ref={measureRef} className={styleClassName} id={this.id}>
1292
- <DroppableContent
1293
- addDataTransferItemsToUploadQueue={this.addDroppedItemsToUploadQueue}
1294
- addFiles={this.addFilesToUploadQueue}
1295
- allowedTypes={['Files']}
1296
- isFolderUploadEnabled={isFolderUploadEnabled}
1297
- isTouch={isTouch}
1298
- items={items}
1299
- onClick={this.onClick}
1300
- view={view}
1301
- />
1302
- <Footer
1303
- errorCode={errorCode}
1304
- fileLimit={fileLimit}
1305
- hasFiles={hasFiles}
1306
- isLoading={isLoading}
1307
- onCancel={this.cancel}
1308
- onClose={onClose}
1309
- onUpload={this.upload}
1310
- isDone={isDone}
1311
- />
1312
- </div>
1313
- )}
1314
- </TooltipProvider>
1315
- </Internationalize>
1316
- );
1317
- }
1318
- }
1319
-
1320
- export type ContentUploaderProps = Props;
1321
- export default makeResponsive(ContentUploader);
1322
- export { ContentUploader as ContentUploaderComponent, CHUNKED_UPLOAD_MIN_SIZE_BYTES };