box-ui-elements-mlh
Version:
1,254 lines (1,043 loc) • 46.6 kB
JavaScript
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/**
*
* @file Content Uploader component
* @author Box
*/
import 'regenerator-runtime/runtime';
import React, { Component } from 'react';
import classNames from 'classnames';
import getProp from 'lodash/get';
import noop from 'lodash/noop';
import uniqueid from 'lodash/uniqueId';
import cloneDeep from 'lodash/cloneDeep';
import { getTypedFileId, getTypedFolderId } from '../../utils/file';
import Browser from '../../utils/Browser';
import makeResponsive from '../common/makeResponsive';
import Internationalize from '../common/Internationalize';
import FolderUpload from '../../api/uploads/FolderUpload';
import API from '../../api';
import { getDataTransferItemId, getFileId, getFileFromDataTransferItem, getPackageFileFromDataTransferItem, getFile, getFileAPIOptions, getDataTransferItemAPIOptions, isDataTransferItemAFolder, isDataTransferItemAPackage, isMultiputSupported } from '../../utils/uploads';
import DroppableContent from './DroppableContent';
import UploadsManager from './UploadsManager';
import Footer from './Footer';
import { DEFAULT_ROOT, CLIENT_NAME_CONTENT_UPLOADER, DEFAULT_HOSTNAME_UPLOAD, DEFAULT_HOSTNAME_API, VIEW_ERROR, VIEW_UPLOAD_EMPTY, VIEW_UPLOAD_IN_PROGRESS, VIEW_UPLOAD_SUCCESS, STATUS_PENDING, STATUS_IN_PROGRESS, STATUS_STAGED, STATUS_COMPLETE, STATUS_ERROR, ERROR_CODE_UPLOAD_FILE_LIMIT } from '../../constants';
import '../common/fonts.scss';
import '../common/base.scss';
var CHUNKED_UPLOAD_MIN_SIZE_BYTES = 104857600; // 100MB
var FILE_LIMIT_DEFAULT = 100; // Upload at most 100 files at once by default
var HIDE_UPLOAD_MANAGER_DELAY_MS_DEFAULT = 8000;
var EXPAND_UPLOADS_MANAGER_ITEMS_NUM_THRESHOLD = 5;
var UPLOAD_CONCURRENCY = 6;
var ContentUploader = /*#__PURE__*/function (_Component) {
_inherits(ContentUploader, _Component);
var _super = _createSuper(ContentUploader);
/**
* [constructor]
*
* @return {ContentUploader}
*/
function ContentUploader(props) {
var _this;
_classCallCheck(this, ContentUploader);
_this = _super.call(this, props);
_defineProperty(_assertThisInitialized(_this), "isAutoExpanded", false);
_defineProperty(_assertThisInitialized(_this), "getBaseAPIOptions", function () {
var _this$props = _this.props,
token = _this$props.token,
sharedLink = _this$props.sharedLink,
sharedLinkPassword = _this$props.sharedLinkPassword,
apiHost = _this$props.apiHost,
uploadHost = _this$props.uploadHost,
clientName = _this$props.clientName,
requestInterceptor = _this$props.requestInterceptor,
responseInterceptor = _this$props.responseInterceptor;
return {
token: token,
sharedLink: sharedLink,
sharedLinkPassword: sharedLinkPassword,
apiHost: apiHost,
uploadHost: uploadHost,
clientName: clientName,
requestInterceptor: requestInterceptor,
responseInterceptor: responseInterceptor
};
});
_defineProperty(_assertThisInitialized(_this), "getNewFiles", function (files) {
var rootFolderId = _this.props.rootFolderId;
var itemIds = _this.state.itemIds;
return Array.from(files).filter(function (file) {
return !itemIds[getFileId(file, rootFolderId)];
});
});
_defineProperty(_assertThisInitialized(_this), "getNewDataTransferItems", function (items) {
var rootFolderId = _this.props.rootFolderId;
var itemIds = _this.state.itemIds;
return Array.from(items).filter(function (item) {
return !itemIds[getDataTransferItemId(item, rootFolderId)];
});
});
_defineProperty(_assertThisInitialized(_this), "addFilesToUploadQueue", function (files, itemUpdateCallback) {
var isRelativePathIgnored = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var _this$props2 = _this.props,
onBeforeUpload = _this$props2.onBeforeUpload,
rootFolderId = _this$props2.rootFolderId;
if (!files || files.length === 0) {
return;
}
var newFiles = _this.getNewFiles(files);
if (newFiles.length === 0) {
return;
}
var newItemIds = {};
newFiles.forEach(function (file) {
newItemIds[getFileId(file, rootFolderId)] = true;
});
clearTimeout(_this.resetItemsTimeout);
var firstFile = getFile(newFiles[0]);
_this.setState(function (state) {
return {
itemIds: _objectSpread(_objectSpread({}, state.itemIds), newItemIds)
};
}, function () {
onBeforeUpload(newFiles);
if (firstFile.webkitRelativePath && !isRelativePathIgnored) {
// webkitRelativePath should be ignored when the upload destination folder is known
_this.addFilesWithRelativePathToQueue(newFiles, itemUpdateCallback);
} else {
_this.addFilesWithoutRelativePathToQueue(newFiles, itemUpdateCallback);
}
});
});
_defineProperty(_assertThisInitialized(_this), "addDroppedItemsToUploadQueue", function (droppedItems, itemUpdateCallback) {
if (droppedItems.items) {
_this.addDataTransferItemsToUploadQueue(droppedItems.items, itemUpdateCallback);
} else {
Array.from(droppedItems.files).forEach(function (file) {
_this.addFilesToUploadQueue([file], itemUpdateCallback);
});
}
});
_defineProperty(_assertThisInitialized(_this), "addDataTransferItemsToUploadQueue", function (dataTransferItems, itemUpdateCallback) {
var isFolderUploadEnabled = _this.props.isFolderUploadEnabled;
if (!dataTransferItems || dataTransferItems.length === 0) {
return;
}
var folderItems = [];
var fileItems = [];
var packageItems = [];
Array.from(dataTransferItems).forEach(function (item) {
var isDirectory = isDataTransferItemAFolder(item);
if (Browser.isSafari() && isDataTransferItemAPackage(item)) {
packageItems.push(item);
} else if (isDirectory && isFolderUploadEnabled) {
folderItems.push(item);
} else if (!isDirectory) {
fileItems.push(item);
}
});
_this.addFileDataTransferItemsToUploadQueue(fileItems, itemUpdateCallback);
_this.addPackageDataTransferItemsToUploadQueue(packageItems, itemUpdateCallback);
_this.addFolderDataTransferItemsToUploadQueue(folderItems, itemUpdateCallback);
});
_defineProperty(_assertThisInitialized(_this), "addFileDataTransferItemsToUploadQueue", function (dataTransferItems, itemUpdateCallback) {
dataTransferItems.forEach( /*#__PURE__*/function () {
var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(item) {
var file;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return getFileFromDataTransferItem(item);
case 2:
file = _context.sent;
if (file) {
_context.next = 5;
break;
}
return _context.abrupt("return");
case 5:
_this.addFilesToUploadQueue([file], itemUpdateCallback);
case 6:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return function (_x) {
return _ref.apply(this, arguments);
};
}());
});
_defineProperty(_assertThisInitialized(_this), "addPackageDataTransferItemsToUploadQueue", function (dataTransferItems, itemUpdateCallback) {
dataTransferItems.forEach(function (item) {
var file = getPackageFileFromDataTransferItem(item);
if (!file) {
return;
}
_this.addFilesToUploadQueue([file], itemUpdateCallback);
});
});
_defineProperty(_assertThisInitialized(_this), "addFolderDataTransferItemsToUploadQueue", /*#__PURE__*/function () {
var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(dataTransferItems, itemUpdateCallback) {
var rootFolderId, itemIds, newItems, fileAPIOptions, _fileAPIOptions$folde, folderId;
return regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
rootFolderId = _this.props.rootFolderId;
itemIds = _this.state.itemIds;
if (!(dataTransferItems.length === 0)) {
_context3.next = 4;
break;
}
return _context3.abrupt("return");
case 4:
newItems = _this.getNewDataTransferItems(dataTransferItems);
newItems.forEach(function (item) {
itemIds[getDataTransferItemId(item, rootFolderId)] = true;
});
if (!(newItems.length === 0)) {
_context3.next = 8;
break;
}
return _context3.abrupt("return");
case 8:
fileAPIOptions = getDataTransferItemAPIOptions(newItems[0]);
_fileAPIOptions$folde = fileAPIOptions.folderId, folderId = _fileAPIOptions$folde === void 0 ? rootFolderId : _fileAPIOptions$folde;
newItems.forEach( /*#__PURE__*/function () {
var _ref3 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(item) {
var folderUpload;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
folderUpload = _this.getFolderUploadAPI(folderId);
_context2.next = 3;
return folderUpload.buildFolderTreeFromDataTransferItem(item);
case 3:
_this.addFolderToUploadQueue(folderUpload, itemUpdateCallback, fileAPIOptions);
case 4:
case "end":
return _context2.stop();
}
}
}, _callee2);
}));
return function (_x4) {
return _ref3.apply(this, arguments);
};
}());
case 11:
case "end":
return _context3.stop();
}
}
}, _callee3);
}));
return function (_x2, _x3) {
return _ref2.apply(this, arguments);
};
}());
_defineProperty(_assertThisInitialized(_this), "getFolderUploadAPI", function (folderId) {
var uploadBaseAPIOptions = _this.getBaseAPIOptions();
return new FolderUpload(_this.addFilesToUploadQueue, folderId, _this.addToQueue, uploadBaseAPIOptions);
});
_defineProperty(_assertThisInitialized(_this), "addFolderToUploadQueue", function (folderUpload, itemUpdateCallback, apiOptions) {
_this.addToQueue([// $FlowFixMe no file property
{
api: folderUpload,
extension: '',
isFolder: true,
name: folderUpload.folder.name,
options: apiOptions,
progress: 0,
size: 1,
status: STATUS_PENDING
}], itemUpdateCallback);
});
_defineProperty(_assertThisInitialized(_this), "addFilesWithoutRelativePathToQueue", function (files, itemUpdateCallback) {
var itemIds = _this.state.itemIds;
var rootFolderId = _this.props.rootFolderId; // Convert files from the file API to upload items
var newItems = files.map(function (file) {
var uploadFile = getFile(file);
var uploadAPIOptions = getFileAPIOptions(file);
var name = uploadFile.name,
size = uploadFile.size; // Extract extension or use empty string if file has no extension
var extension = name.substr(name.lastIndexOf('.') + 1);
if (extension.length === name.length) {
extension = '';
}
var api = _this.getUploadAPI(uploadFile, uploadAPIOptions);
var uploadItem = {
api: api,
extension: extension,
file: uploadFile,
name: name,
progress: 0,
size: size,
status: STATUS_PENDING
};
if (uploadAPIOptions) {
uploadItem.options = uploadAPIOptions;
}
itemIds[getFileId(uploadItem, rootFolderId)] = true;
return uploadItem;
});
if (newItems.length === 0) {
return;
}
_this.setState({
itemIds: itemIds
});
_this.addToQueue(newItems, itemUpdateCallback);
});
_defineProperty(_assertThisInitialized(_this), "addToQueue", function (newItems, itemUpdateCallback) {
var _this$props3 = _this.props,
fileLimit = _this$props3.fileLimit,
useUploadsManager = _this$props3.useUploadsManager;
var _this$state = _this.state,
items = _this$state.items,
isUploadsManagerExpanded = _this$state.isUploadsManagerExpanded;
var updatedItems = [];
var prevItemsNum = items.length;
var totalNumOfItems = prevItemsNum + newItems.length; // Don't add more than fileLimit # of items
if (totalNumOfItems > fileLimit) {
updatedItems = items.concat(newItems.slice(0, fileLimit - items.length));
_this.setState({
errorCode: ERROR_CODE_UPLOAD_FILE_LIMIT
});
} else {
updatedItems = items.concat(newItems);
_this.setState({
errorCode: ''
}); // If the number of items being uploaded passes the threshold, expand the upload manager
if (prevItemsNum < EXPAND_UPLOADS_MANAGER_ITEMS_NUM_THRESHOLD && totalNumOfItems >= EXPAND_UPLOADS_MANAGER_ITEMS_NUM_THRESHOLD && useUploadsManager && !isUploadsManagerExpanded) {
_this.isAutoExpanded = true;
_this.expandUploadsManager();
}
}
_this.updateViewAndCollection(updatedItems, function () {
if (itemUpdateCallback) {
itemUpdateCallback();
}
var view = _this.state.view; // Automatically start upload if other files are being uploaded
if (view === VIEW_UPLOAD_IN_PROGRESS) {
_this.upload();
}
});
});
_defineProperty(_assertThisInitialized(_this), "removeFileFromUploadQueue", function (item) {
var _this$props4 = _this.props,
onCancel = _this$props4.onCancel,
useUploadsManager = _this$props4.useUploadsManager;
var items = _this.state.items; // Clear any error errorCode in footer
_this.setState({
errorCode: ''
});
var api = item.api;
api.cancel();
items.splice(items.indexOf(item), 1);
onCancel([item]);
_this.updateViewAndCollection(items, function () {
// Minimize uploads manager if there are no more items
if (useUploadsManager && !items.length) {
_this.minimizeUploadsManager();
}
var view = _this.state.view;
if (view === VIEW_UPLOAD_IN_PROGRESS) {
_this.upload();
}
});
});
_defineProperty(_assertThisInitialized(_this), "cancel", function () {
var items = _this.state.items;
items.forEach(function (uploadItem) {
var api = uploadItem.api,
status = uploadItem.status;
if (status === STATUS_IN_PROGRESS) {
api.cancel();
}
}); // Reset upload collection
_this.updateViewAndCollection([]);
});
_defineProperty(_assertThisInitialized(_this), "upload", function () {
var items = _this.state.items;
items.forEach(function (uploadItem) {
if (uploadItem.status === STATUS_PENDING) {
_this.uploadFile(uploadItem);
}
});
});
_defineProperty(_assertThisInitialized(_this), "handleUploadSuccess", function (item, entries) {
var _this$props5 = _this.props,
onUpload = _this$props5.onUpload,
useUploadsManager = _this$props5.useUploadsManager;
item.progress = 100;
if (!item.error) {
item.status = STATUS_COMPLETE;
} // Cache Box File object of successfully uploaded item
if (entries && entries.length === 1) {
var _entries = _slicedToArray(entries, 1),
boxFile = _entries[0];
item.boxFile = boxFile;
}
var items = _this.state.items;
items[items.indexOf(item)] = item; // Broadcast that a file has been uploaded
if (useUploadsManager) {
onUpload(item);
_this.checkClearUploadItems();
} else {
onUpload(item.boxFile);
}
_this.updateViewAndCollection(items, function () {
var view = _this.state.view;
if (view === VIEW_UPLOAD_IN_PROGRESS) {
_this.upload();
}
});
});
_defineProperty(_assertThisInitialized(_this), "resetUploadManagerExpandState", function () {
_this.isAutoExpanded = false;
_this.setState({
isUploadsManagerExpanded: false
});
});
_defineProperty(_assertThisInitialized(_this), "handleUploadError", function (item, error) {
var _this$props6 = _this.props,
onError = _this$props6.onError,
useUploadsManager = _this$props6.useUploadsManager;
var file = item.file;
var items = _this.state.items;
item.status = STATUS_ERROR;
item.error = error;
var newItems = _toConsumableArray(items);
var index = newItems.findIndex(function (singleItem) {
return singleItem === item;
});
if (index !== -1) {
newItems[index] = item;
} // Broadcast that there was an error uploading a file
var errorData = useUploadsManager ? {
item: item,
error: error
} : {
file: file,
error: error
};
onError(errorData);
_this.updateViewAndCollection(newItems, function () {
if (useUploadsManager) {
_this.isAutoExpanded = true;
_this.expandUploadsManager();
}
var view = _this.state.view;
if (view === VIEW_UPLOAD_IN_PROGRESS) {
_this.upload();
}
});
});
_defineProperty(_assertThisInitialized(_this), "handleUploadProgress", function (item, event) {
if (!event.total || item.status === STATUS_COMPLETE || item.status === STATUS_STAGED) {
return;
}
item.progress = Math.min(Math.round(event.loaded / event.total * 100), 100);
item.status = item.progress === 100 ? STATUS_STAGED : STATUS_IN_PROGRESS;
var onProgress = _this.props.onProgress;
onProgress(item);
var items = _this.state.items;
items[items.indexOf(item)] = item;
_this.updateViewAndCollection(items);
});
_defineProperty(_assertThisInitialized(_this), "onClick", function (item) {
var _this$props7 = _this.props,
chunked = _this$props7.chunked,
isResumableUploadsEnabled = _this$props7.isResumableUploadsEnabled,
onClickCancel = _this$props7.onClickCancel,
onClickResume = _this$props7.onClickResume,
onClickRetry = _this$props7.onClickRetry;
var status = item.status,
file = item.file;
var isChunkedUpload = chunked && !item.isFolder && file.size > CHUNKED_UPLOAD_MIN_SIZE_BYTES && isMultiputSupported();
var isResumable = isResumableUploadsEnabled && isChunkedUpload && item.api.sessionId;
switch (status) {
case STATUS_IN_PROGRESS:
case STATUS_STAGED:
case STATUS_COMPLETE:
case STATUS_PENDING:
_this.removeFileFromUploadQueue(item);
onClickCancel(item);
break;
case STATUS_ERROR:
if (isResumable) {
item.bytesUploadedOnLastResume = item.api.totalUploadedBytes;
_this.resumeFile(item);
onClickResume(item);
} else {
_this.resetFile(item);
_this.uploadFile(item);
onClickRetry(item);
}
break;
default:
break;
}
});
_defineProperty(_assertThisInitialized(_this), "clickAllWithStatus", function (status) {
var items = _this.state.items;
items.forEach(function (item) {
if (!status || item.status === status) {
_this.onClick(item);
}
});
});
_defineProperty(_assertThisInitialized(_this), "expandUploadsManager", function () {
var useUploadsManager = _this.props.useUploadsManager;
if (!useUploadsManager) {
return;
}
clearTimeout(_this.resetItemsTimeout);
_this.setState({
isUploadsManagerExpanded: true
});
});
_defineProperty(_assertThisInitialized(_this), "minimizeUploadsManager", function () {
var _this$props8 = _this.props,
useUploadsManager = _this$props8.useUploadsManager,
onMinimize = _this$props8.onMinimize;
if (!useUploadsManager || !onMinimize) {
return;
}
clearTimeout(_this.resetItemsTimeout);
onMinimize();
_this.resetUploadManagerExpandState();
_this.checkClearUploadItems();
});
_defineProperty(_assertThisInitialized(_this), "checkClearUploadItems", function () {
_this.resetItemsTimeout = setTimeout(_this.resetUploadsManagerItemsWhenUploadsComplete, HIDE_UPLOAD_MANAGER_DELAY_MS_DEFAULT);
});
_defineProperty(_assertThisInitialized(_this), "toggleUploadsManager", function () {
var isUploadsManagerExpanded = _this.state.isUploadsManagerExpanded;
if (isUploadsManagerExpanded) {
_this.minimizeUploadsManager();
} else {
_this.expandUploadsManager();
}
});
_defineProperty(_assertThisInitialized(_this), "resetUploadsManagerItemsWhenUploadsComplete", function () {
var _this$state2 = _this.state,
view = _this$state2.view,
items = _this$state2.items,
isUploadsManagerExpanded = _this$state2.isUploadsManagerExpanded;
var _this$props9 = _this.props,
useUploadsManager = _this$props9.useUploadsManager,
onCancel = _this$props9.onCancel; // Do not reset items when upload manger is expanded or there're uploads in progress
if (isUploadsManagerExpanded && useUploadsManager && !!items.length || view === VIEW_UPLOAD_IN_PROGRESS) {
return;
}
onCancel(items);
_this.setState({
items: [],
itemIds: {}
});
});
_defineProperty(_assertThisInitialized(_this), "addFilesWithOptionsToUploadQueueAndStartUpload", function (files, dataTransferItems) {
_this.addFilesToUploadQueue(files, _this.upload);
_this.addDataTransferItemsToUploadQueue(dataTransferItems, _this.upload);
});
var _rootFolderId = props.rootFolderId,
_token = props.token,
_useUploadsManager = props.useUploadsManager;
_this.state = {
view: _rootFolderId && _token || _useUploadsManager ? VIEW_UPLOAD_EMPTY : VIEW_ERROR,
items: [],
errorCode: '',
itemIds: {},
isUploadsManagerExpanded: false
};
_this.id = uniqueid('bcu_');
return _this;
}
/**
* Fetches the root folder on load
*
* @private
* @inheritdoc
* @return {void}
*/
_createClass(ContentUploader, [{
key: "componentDidMount",
value: function componentDidMount() {
this.rootElement = document.getElementById(this.id);
this.appElement = this.rootElement;
}
/**
* Cancels pending uploads
*
* @private
* @inheritdoc
* @return {void}
*/
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.cancel();
}
/**
* Adds new items to the queue when files prop gets updated in window view
*
* @return {void}
*/
}, {
key: "componentDidUpdate",
value: function componentDidUpdate() {
var _this$props10 = this.props,
files = _this$props10.files,
dataTransferItems = _this$props10.dataTransferItems,
useUploadsManager = _this$props10.useUploadsManager;
var hasFiles = Array.isArray(files) && files.length > 0;
var hasItems = Array.isArray(dataTransferItems) && dataTransferItems.length > 0;
var hasUploads = hasFiles || hasItems;
if (!useUploadsManager || !hasUploads) {
return;
} // TODO: this gets called unnecessarily (upon each render regardless of the queue not changing)
this.addFilesWithOptionsToUploadQueueAndStartUpload(files, dataTransferItems);
}
/**
* Create and return new instance of API creator
*
* @param {UploadItemAPIOptions} [uploadAPIOptions]
* @return {API}
*/
}, {
key: "createAPIFactory",
value: function createAPIFactory(uploadAPIOptions) {
var rootFolderId = this.props.rootFolderId;
var folderId = getProp(uploadAPIOptions, 'folderId') || rootFolderId;
var fileId = getProp(uploadAPIOptions, 'fileId');
var itemFolderId = getTypedFolderId(folderId);
var itemFileId = fileId ? getTypedFileId(fileId) : null;
return new API(_objectSpread(_objectSpread({}, this.getBaseAPIOptions()), {}, {
id: itemFileId || itemFolderId
}, uploadAPIOptions));
}
/**
* Return base API options from props
*
* @private
* @returns {Object}
*/
}, {
key: "addFilesWithRelativePathToQueue",
value:
/**
* Converts File API to upload items and adds to upload queue for files with webkitRelativePath.
*
* @private
* @param {Array<UploadFileWithAPIOptions | File>} files - Files to be added to upload queue
* @param {Function} itemUpdateCallback - function to be invoked after items status are updated
* @return {void}
*/
function addFilesWithRelativePathToQueue(files, itemUpdateCallback) {
if (files.length === 0) {
return;
}
var rootFolderId = this.props.rootFolderId;
var fileAPIOptions = getFileAPIOptions(files[0]);
var _fileAPIOptions$folde2 = fileAPIOptions.folderId,
folderId = _fileAPIOptions$folde2 === void 0 ? rootFolderId : _fileAPIOptions$folde2;
var folderUpload = this.getFolderUploadAPI(folderId); // Only 1 folder tree can be built with files having webkitRelativePath properties
folderUpload.buildFolderTreeFromWebkitRelativePath(files);
this.addFolderToUploadQueue(folderUpload, itemUpdateCallback, fileAPIOptions);
}
/**
* Get folder upload API instance
*
* @private
* @param {string} folderId
* @return {FolderUpload}
*/
}, {
key: "getUploadAPI",
value:
/**
* Returns a new API instance for the given file.
*
* @private
* @param {File} file - File to get a new API instance for
* @param {UploadItemAPIOptions} [uploadAPIOptions]
* @return {UploadAPI} - Instance of Upload API
*/
function getUploadAPI(file, uploadAPIOptions) {
var _this$props11 = this.props,
chunked = _this$props11.chunked,
isResumableUploadsEnabled = _this$props11.isResumableUploadsEnabled,
isUploadFallbackLogicEnabled = _this$props11.isUploadFallbackLogicEnabled;
var size = file.size;
var factory = this.createAPIFactory(uploadAPIOptions);
if (chunked && size > CHUNKED_UPLOAD_MIN_SIZE_BYTES) {
if (isMultiputSupported()) {
var chunkedUploadAPI = factory.getChunkedUploadAPI();
if (isResumableUploadsEnabled) {
chunkedUploadAPI.isResumableUploadsEnabled = true;
}
if (isUploadFallbackLogicEnabled) {
chunkedUploadAPI.isUploadFallbackLogicEnabled = true;
}
return chunkedUploadAPI;
}
/* eslint-disable no-console */
console.warn('Chunked uploading is enabled, but not supported by your browser. You may need to enable HTTPS.');
/* eslint-enable no-console */
}
var plainUploadAPI = factory.getPlainUploadAPI();
if (isUploadFallbackLogicEnabled) {
plainUploadAPI.isUploadFallbackLogicEnabled = true;
}
return plainUploadAPI;
}
/**
* Removes an item from the upload queue. Cancels upload if in progress.
*
* @param {UploadItem} item - Item to remove
* @return {void}
*/
}, {
key: "uploadFile",
value:
/**
* Helper to upload a single file.
*
* @param {UploadItem} item - Upload item object
* @return {void}
*/
function uploadFile(item) {
var _this2 = this;
var _this$props12 = this.props,
overwrite = _this$props12.overwrite,
rootFolderId = _this$props12.rootFolderId;
var api = item.api,
file = item.file,
options = item.options;
var items = this.state.items;
var numItemsUploading = items.filter(function (item_t) {
return item_t.status === STATUS_IN_PROGRESS;
}).length;
if (numItemsUploading >= UPLOAD_CONCURRENCY) {
return;
}
var uploadOptions = {
file: file,
folderId: options && options.folderId ? options.folderId : rootFolderId,
errorCallback: function errorCallback(error) {
return _this2.handleUploadError(item, error);
},
progressCallback: function progressCallback(event) {
return _this2.handleUploadProgress(item, event);
},
successCallback: function successCallback(entries) {
return _this2.handleUploadSuccess(item, entries);
},
overwrite: overwrite,
fileId: options && options.fileId ? options.fileId : null
};
item.status = STATUS_IN_PROGRESS;
items[items.indexOf(item)] = item;
api.upload(uploadOptions);
this.updateViewAndCollection(items);
}
/**
* Helper to resume uploading a single file.
*
* @param {UploadItem} item - Upload item object
* @return {void}
*/
}, {
key: "resumeFile",
value: function resumeFile(item) {
var _this3 = this;
var _this$props13 = this.props,
overwrite = _this$props13.overwrite,
rootFolderId = _this$props13.rootFolderId,
onResume = _this$props13.onResume;
var api = item.api,
file = item.file,
options = item.options;
var items = this.state.items;
var numItemsUploading = items.filter(function (item_t) {
return item_t.status === STATUS_IN_PROGRESS;
}).length;
if (numItemsUploading >= UPLOAD_CONCURRENCY) {
return;
}
var resumeOptions = {
file: file,
folderId: options && options.folderId ? options.folderId : rootFolderId,
errorCallback: function errorCallback(error) {
return _this3.handleUploadError(item, error);
},
progressCallback: function progressCallback(event) {
return _this3.handleUploadProgress(item, event);
},
successCallback: function successCallback(entries) {
return _this3.handleUploadSuccess(item, entries);
},
overwrite: overwrite,
sessionId: api && api.sessionId ? api.sessionId : null,
fileId: options && options.fileId ? options.fileId : null
};
item.status = STATUS_IN_PROGRESS;
delete item.error;
items[items.indexOf(item)] = item;
onResume(item);
api.resume(resumeOptions);
this.updateViewAndCollection(items);
}
/**
* Helper to reset a file. Cancels any current upload and resets progress.
*
* @param {UploadItem} item - Upload item to reset
* @return {void}
*/
}, {
key: "resetFile",
value: function resetFile(item) {
var api = item.api,
file = item.file,
options = item.options;
if (api && typeof api.cancel === 'function') {
api.cancel();
} // Reset API, progress & status
item.api = this.getUploadAPI(file, options);
item.progress = 0;
item.status = STATUS_PENDING;
delete item.error;
var items = this.state.items;
items[items.indexOf(item)] = item;
this.updateViewAndCollection(items);
}
/**
* Handles a successful upload.
*
* @private
* @param {UploadItem} item - Upload item corresponding to success event
* @param {BoxItem[]} entries - Successfully uploaded Box File objects
* @return {void}
*/
}, {
key: "updateViewAndCollection",
value:
/**
* Updates view and internal upload collection with provided items.
*
* @private
* @param {UploadItem[]} item - Items to update collection with
* @param {Function} callback
* @return {void}
*/
function updateViewAndCollection(items, callback) {
var _this$props14 = this.props,
onComplete = _this$props14.onComplete,
useUploadsManager = _this$props14.useUploadsManager,
isResumableUploadsEnabled = _this$props14.isResumableUploadsEnabled;
var someUploadIsInProgress = items.some(function (uploadItem) {
return uploadItem.status !== STATUS_COMPLETE;
});
var someUploadHasFailed = items.some(function (uploadItem) {
return uploadItem.status === STATUS_ERROR;
});
var allItemsArePending = !items.some(function (uploadItem) {
return uploadItem.status !== STATUS_PENDING;
});
var noFileIsPendingOrInProgress = items.every(function (uploadItem) {
return uploadItem.status !== STATUS_PENDING && uploadItem.status !== STATUS_IN_PROGRESS;
});
var areAllItemsFinished = items.every(function (uploadItem) {
return uploadItem.status === STATUS_COMPLETE || uploadItem.status === STATUS_ERROR;
});
var uploadItemsStatus = isResumableUploadsEnabled ? areAllItemsFinished : noFileIsPendingOrInProgress;
var view = '';
if (items && items.length === 0 || allItemsArePending) {
view = VIEW_UPLOAD_EMPTY;
} else if (someUploadHasFailed && useUploadsManager) {
view = VIEW_ERROR;
} else if (someUploadIsInProgress) {
view = VIEW_UPLOAD_IN_PROGRESS;
} else {
view = VIEW_UPLOAD_SUCCESS;
if (!useUploadsManager) {
onComplete(cloneDeep(items.map(function (item) {
return item.boxFile;
}))); // Reset item collection after successful upload
items = [];
}
}
if (uploadItemsStatus && useUploadsManager) {
if (this.isAutoExpanded) {
this.resetUploadManagerExpandState();
} // Else manually expanded so don't close
onComplete(items);
}
var state = {
items: items,
view: view
};
if (items.length === 0) {
state.itemIds = {};
state.errorCode = '';
}
this.setState(state, callback);
}
/**
* Handles an upload error.
*
* @private
* @param {UploadItem} item - Upload item corresponding to error
* @param {Error} error - Upload error
* @return {void}
*/
}, {
key: "render",
value:
/**
* Renders the content uploader
*
* @inheritdoc
* @return {Component}
*/
function render() {
var _this$props15 = this.props,
language = _this$props15.language,
messages = _this$props15.messages,
onClose = _this$props15.onClose,
className = _this$props15.className,
measureRef = _this$props15.measureRef,
isTouch = _this$props15.isTouch,
fileLimit = _this$props15.fileLimit,
useUploadsManager = _this$props15.useUploadsManager,
isResumableUploadsEnabled = _this$props15.isResumableUploadsEnabled,
isFolderUploadEnabled = _this$props15.isFolderUploadEnabled,
_this$props15$isDragg = _this$props15.isDraggingItemsToUploadsManager,
isDraggingItemsToUploadsManager = _this$props15$isDragg === void 0 ? false : _this$props15$isDragg;
var _this$state3 = this.state,
view = _this$state3.view,
items = _this$state3.items,
errorCode = _this$state3.errorCode,
isUploadsManagerExpanded = _this$state3.isUploadsManagerExpanded;
var isEmpty = items.length === 0;
var isVisible = !isEmpty || !!isDraggingItemsToUploadsManager;
var hasFiles = items.length !== 0;
var isLoading = items.some(function (item) {
return item.status === STATUS_IN_PROGRESS;
});
var isDone = items.every(function (item) {
return item.status === STATUS_COMPLETE || item.status === STATUS_STAGED;
});
var styleClassName = classNames('bcu', className, {
'be-app-element': !useUploadsManager,
be: !useUploadsManager
});
return /*#__PURE__*/React.createElement(Internationalize, {
language: language,
messages: messages
}, useUploadsManager ? /*#__PURE__*/React.createElement("div", {
ref: measureRef,
className: styleClassName,
id: this.id
}, /*#__PURE__*/React.createElement(UploadsManager, {
isDragging: isDraggingItemsToUploadsManager,
isExpanded: isUploadsManagerExpanded,
isResumableUploadsEnabled: isResumableUploadsEnabled,
isVisible: isVisible,
items: items,
onItemActionClick: this.onClick,
onRemoveActionClick: this.removeFileFromUploadQueue,
onUploadsManagerActionClick: this.clickAllWithStatus,
toggleUploadsManager: this.toggleUploadsManager,
view: view
})) : /*#__PURE__*/React.createElement("div", {
ref: measureRef,
className: styleClassName,
id: this.id
}, /*#__PURE__*/React.createElement(DroppableContent, {
addDataTransferItemsToUploadQueue: this.addDroppedItemsToUploadQueue,
addFiles: this.addFilesToUploadQueue,
allowedTypes: ['Files'],
isFolderUploadEnabled: isFolderUploadEnabled,
isTouch: isTouch,
items: items,
onClick: this.onClick,
view: view
}), /*#__PURE__*/React.createElement(Footer, {
errorCode: errorCode,
fileLimit: fileLimit,
hasFiles: hasFiles,
isLoading: isLoading,
onCancel: this.cancel,
onClose: onClose,
onUpload: this.upload,
isDone: isDone
})));
}
}]);
return ContentUploader;
}(Component);
_defineProperty(ContentUploader, "defaultProps", {
rootFolderId: DEFAULT_ROOT,
apiHost: DEFAULT_HOSTNAME_API,
chunked: true,
className: '',
clientName: CLIENT_NAME_CONTENT_UPLOADER,
fileLimit: FILE_LIMIT_DEFAULT,
uploadHost: DEFAULT_HOSTNAME_UPLOAD,
onBeforeUpload: noop,
onClickCancel: noop,
onClickResume: noop,
onClickRetry: noop,
onClose: noop,
onComplete: noop,
onError: noop,
onResume: noop,
onUpload: noop,
onProgress: noop,
overwrite: true,
useUploadsManager: false,
files: [],
onMinimize: noop,
onCancel: noop,
isFolderUploadEnabled: false,
isResumableUploadsEnabled: false,
isUploadFallbackLogicEnabled: false,
dataTransferItems: [],
isDraggingItemsToUploadsManager: false
});
export default makeResponsive(ContentUploader);
export { ContentUploader as ContentUploaderComponent, CHUNKED_UPLOAD_MIN_SIZE_BYTES };
//# sourceMappingURL=ContentUploader.js.map