UNPKG

box-ui-elements-mlh

Version:
1,254 lines (1,043 loc) 46.6 kB
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