"use strict"; /** * Licensed Materials - Property of IBM * IBM Cognos Products: Cognos Analytics * Copyright IBM Corp. 2016, 2019 * US Government Users Restricted Rights - Use, duplication or disclosure * restricted by GSA ADP Schedule Contract with IBM Corp. */ define(['underscore', 'bi/glass/core/Class', 'bi/admin/nls/StringResource', 'bi/glass/common/ui/ProgressToast'], function (_, Class, StringResource, ProgressToast) { 'use strict'; //NOSONAR: meant to be strict var Uploader = Class.extend({ includeFileName: false, /** *@options.glassContext - glassContext *@options.$el - Container *@options.ajax() - ajax function to upload data *@options.ajaxOptions */ init: function init(options) { Uploader.inherited('init', this, arguments); _.extend(this, options); }, /** * For testing purposes */ _getWindow: function _getWindow() { return window; }, /** * For testing purposes */ _getNavigator: function _getNavigator() { return navigator; }, /** * Starting point for using uploader. Prompts user to select a file from browser/OS file selector */ doUpload: function doUpload() { return new Promise(function (resolve, reject) { var application = this.glassContext.appController; if (!this._getWindow().File || !this._getWindow().FileReader || !this._getWindow().FileList || !this._getWindow().Blob) { application.showErrorMessage(StringResource.get('errorHTML5Support'), StringResource.get('error')); reject(); } else if (/^((?!chrome).)*safari\/537/i.test(this._getNavigator().userAgent)) { application.showErrorMessage(StringResource.get('errorUploadSupport'), StringResource.get('error')); reject(); } else { this._removeInput(); var $input = this._getInput(); this.$el.append($input); $input.change(function (e) { this._verifyAndUpload(e).then(resolve, reject); }.bind(this)); // hack: this is for functional testing purpose to stop prompting with the browser file picker if (!document.getElementById('skipInvokingFileSelectionAdmin')) { $input.click(); } } }.bind(this)); }, _getBaseInputOptions: function _getBaseInputOptions() { return { 'type': 'file', 'id': 'idUploadUIElement', 'name': 'uploadfiles', 'style': 'display: none;', 'multiple': false }; }, _getInput: function _getInput() { var inputOptions = this._getBaseInputOptions(); if (this.fileType && this.fileType === 'csv') { inputOptions.accept = '.csv'; } else { inputOptions.accept = 'application/zip'; } return $('', inputOptions); }, _verifyAndUpload: function _verifyAndUpload(evt) { return Promise.try(function () { var currFile = evt.target.files[0]; var configMaxSize = 500; var maxFileSizeInByte = configMaxSize * 1024 * 1024; var errMsg; if (_.isUndefined(currFile.size) || currFile.size > maxFileSizeInByte) { errMsg = StringResource.get('msgHardLimitFileUpload', { 'message': configMaxSize }); this.glassContext.appController.showErrorMessage(errMsg, StringResource.get('error')); } else if (!this._isValidFileName(currFile.name)) { errMsg = this._getInvalidFileNameMessage(); this.glassContext.appController.showErrorMessage(errMsg, StringResource.get('msgFileNameUploadTitle')); } else { return this._uploadProcessor(currFile); } throw new Error(errMsg); }.bind(this)); }, _isValidFileName: function _isValidFileName(fileName) { if (this.fileType === 'csv') { return /^[a-z0-9_ \-\.]{1,200}\.csv$/i.test(fileName); } else { return /^[a-z0-9_ \-\.]{1,200}\.zip$/i.test(fileName); } }, // NB - the message returned should match regexp above _getInvalidFileNameMessage: function _getInvalidFileNameMessage() { return StringResource.get('msgFileNameUpload'); }, /** * For testing purposes */ _createFileReader: function _createFileReader() { return new FileReader(); }, /** * For testing purposes */ _createProgressToast: function _createProgressToast() { return new ProgressToast(); }, _uploadProcessor: function _uploadProcessor(currFile) { return new Promise(function (resolve, reject) { this.progressBar = this._createProgressToast(); var reader = this._createFileReader(); this.progressBar.show(StringResource.get('msgUploadStarted')); this.progressBar.progress(); this.progressBar.onCancel(function () { try { reader.abort(); } catch (e) { return; } }.bind(this)); reader.onerror = function () { this.progressBar.fail(StringResource.get('errorReadingFile')); reject(); }.bind(this); reader.onabort = function () { this.progressBar.fail(StringResource.get('abortReadingFile')); reject(); }.bind(this); reader.onprogress = function (e) { var percentLoaded = Math.round(e.loaded / e.total * 100); this.progressBar.setComplete(percentLoaded); }.bind(this); reader.onload = function (e) { this._readerOnload(currFile.name, e).then(resolve, reject); }.bind(this); reader.readAsArrayBuffer(currFile); }.bind(this)); }, _readerOnload: function _readerOnload(fileName, e) { this.progressBar.indefinite(StringResource.get('msgUploadToServer')); var options = { 'data': e.target.result, 'byteLength': e.target.result.byteLength }; if (this.includeFileName) { options.fileName = this._getFileName(fileName, e); } _.extend(options, this.ajaxOptions); return this.ajax(options).then(function () { this.progressBar.setComplete(100, { isComplete: true, completeMsg: StringResource.get('msgFileUploadSuccess') }); }.bind(this), function (err) { if (err.jqXHR) { var jqXHR = err.jqXHR; if (!_.isUndefined(jqXHR.responseJSON) && !_.isUndefined(jqXHR.responseJSON.errors)) { var errors = jqXHR.responseJSON.errors; if (errors.length > 0) { this.glassContext.appController.showErrorMessage(errors[0].message, errors[0].code); } } } this.progressBar.remove(""); throw jqXHR; }.bind(this)); }, _removeInput: function _removeInput() { this.$el.find('input#idUploadUIElement').remove(); }, _getFileName: function _getFileName(fileName, e) { return fileName; } }); return Uploader; });