diff --git a/DNN Platform/DotNetNuke.Web/InternalServices/FileUploadController.cs b/DNN Platform/DotNetNuke.Web/InternalServices/FileUploadController.cs index 991441a9660..52abe1ba7b6 100644 --- a/DNN Platform/DotNetNuke.Web/InternalServices/FileUploadController.cs +++ b/DNN Platform/DotNetNuke.Web/InternalServices/FileUploadController.cs @@ -419,91 +419,6 @@ public Task UploadFromLocal(int portalId) return task; } - [HttpPost] - [ValidateAntiForgeryToken] - [AllowAnonymous] - public HttpResponseMessage UploadFromUrl(UploadByUrlDto dto) - { - FileUploadDto result; - WebResponse response = null; - Stream responseStream = null; - var mediaTypeFormatter = new JsonMediaTypeFormatter(); - mediaTypeFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/plain")); - - if (this.VerifySafeUrl(dto.Url) == false) - { - return this.Request.CreateResponse(HttpStatusCode.BadRequest); - } - - try - { - var request = (HttpWebRequest)WebRequest.Create(dto.Url); - request.Credentials = CredentialCache.DefaultCredentials; - response = request.GetResponse(); - responseStream = response.GetResponseStream(); - if (responseStream == null) - { - throw new Exception("No server response"); - } - - var fileName = this.GetFileName(response); - if (string.IsNullOrEmpty(fileName)) - { - fileName = HttpUtility.UrlDecode(new Uri(dto.Url).Segments.Last()); - } - - var portalId = dto.PortalId; - if (portalId > -1) - { - if (!this.IsPortalIdValid(portalId)) - { - throw new HttpResponseException(HttpStatusCode.Unauthorized); - } - } - else - { - portalId = this.PortalSettings.PortalId; - } - - result = UploadFile(responseStream, portalId, this.UserInfo, dto.Folder.ValueOrEmpty(), dto.Filter.ValueOrEmpty(), - fileName, dto.Overwrite, dto.IsHostMenu, dto.Unzip, dto.ValidationCode); - - /* Response Content Type cannot be application/json - * because IE9 with iframe-transport manages the response - * as a file download - */ - return this.Request.CreateResponse( - HttpStatusCode.OK, - result, - mediaTypeFormatter, - "text/plain"); - } - catch (Exception ex) - { - result = new FileUploadDto - { - Message = ex.Message, - }; - return this.Request.CreateResponse( - HttpStatusCode.OK, - result, - mediaTypeFormatter, - "text/plain"); - } - finally - { - if (response != null) - { - response.Close(); - } - - if (responseStream != null) - { - responseStream.Close(); - } - } - } - private static string GetLocalizedString(string key) { const string resourceFile = "/App_GlobalResources/FileUpload.resx"; diff --git a/DNN Platform/Website/Resources/Shared/components/FileUpload/dnn.FileUpload.js b/DNN Platform/Website/Resources/Shared/components/FileUpload/dnn.FileUpload.js index 9e5ddbfa820..4264a77ef4e 100644 --- a/DNN Platform/Website/Resources/Shared/components/FileUpload/dnn.FileUpload.js +++ b/DNN Platform/Website/Resources/Shared/components/FileUpload/dnn.FileUpload.js @@ -81,9 +81,6 @@ $element("ul", { 'class': 'dnnButtonGroup' }).append( $element("li").append( $element("a", { href: "javascript:void(0);", 'class': 'upload-file active' }).text(this.options.resources.uploadFileMethod).on("click", $.proxy(this._selectUpload, this, this._uploadMethods.local)) - ), - $element("li").append( - $element("a", { href: "javascript:void(0);", 'class': 'from-url' }).text(this.options.resources.uploadFromWebMethod).on("click", $.proxy(this._selectUpload, this, this._uploadMethods.web)) ) ), this._$decompressOption = $element("span").append( @@ -101,25 +98,6 @@ $element("div", { 'class': 'fu-dialog-drag-and-drop-area-message' }) ) ), - $element("div", { style: 'display: none', 'class': 'fu-dialog-content-fileupload-web' }).append( - $element("table", { 'class': 'fu-dialog-url-upload-area' }).append( - $element("tbody").append( - $element("tr").append( - $element("td").append( - $element("div").append( - this._$url = $element("input", { type: 'text', title: this.options.resources.urlTooltip, placeholder: this.options.resources.urlTooltip }) - .onEnter($.proxy(this._uploadByUrl, this)) - .on("change keyup paste input propertychange", $.proxy(this._validateUrl, this)) - .prefixInput({ prefix: "http" }) - ) - ), - $element("td").append( - $element("a", { href: 'javascript:void(0);', 'class': 'dnnSecondaryAction' }).text(this.options.resources.uploadFromWebButtonText).on("click", $.proxy(this._uploadByUrl, this)) - ) - ) - ) - ) - ), $element("div", { style: 'display: none', 'class': 'fu-fileupload-statuses-container' }).append( $element("ul", { 'class': 'fu-fileupload-statuses' }) ) @@ -127,17 +105,7 @@ ); return dialog; - }, - - _validateUrl: function() { - var url = this._$url.val(); - if (dnn.isUrl(url)) { - this._$url.removeClass("fu-dialog-url-error"); - } - else { - this._$url.addClass("fu-dialog-url-error"); - } - }, + }, _getFileExtension: function(fileName) { var parts = fileName.split("."); @@ -161,55 +129,6 @@ return false; }, - _uploadByUrl: function(eventObject) { - var url = this._$url.val(); - if (!dnn.isUrl(url)) { - this._$url.addClass("fu-dialog-url-error"); - return; - } - - if (!this._isValidExtension(url, this.options.extensions)) { - this._$url.addClass("fu-dialog-url-error"); - $.dnnAlert({ title: this.options.resources.errorDialogTitle || "Error", text: this.options.resources.invalidFileExtensions }); - return; - } - - this._$url.removeClass("fu-dialog-url-error"); - this._$url.val(""); - - var status = this._getInitializedStatusElement({ fileName: url }).data("status"); - this._submitUrl(status); - }, - - _submitUrl: function (status) { - var serviceUrl = $.dnnSF().getServiceRoot("InternalServices"); - var serviceSettings = { - beforeSend: $.dnnSF(this.options.moduleId).setModuleHeaders, - url: serviceUrl + "FileUpload/UploadFromUrl", - type: "POST", - async: true, - success: $.proxy(this._onUploadByUrl, this, [status.fileName]), - error: $.onAjaxError - }; - serviceSettings.data = { - Url: status.fileName, - Folder: this._selectedPath(), - Overwrite: status.overwrite, - Unzip: this._extract(), - Filter: this.options.extensions.join(","), - IsHostMenu: this.options.parameters.isHostPortal, - ValidationCode: this.options.validationCode - }; - $.extend(serviceSettings.data, this.options.parameters); - $.ajax(serviceSettings); - }, - - _onUploadByUrl: function (url, data, textStatus, jqXhr) { - this._processResponse(url[0], data); - - this.$element.trigger($.Event("onfileuploadcomplete"), [data]); - }, - _createFileUploadStatusElement: function (status) { status.overwrite = false; status.path = this._selectedPath(); @@ -426,12 +345,7 @@ }, _submitResource: function(status) { - if (status.data) { - this._submitFile(status); - } - else { - this._submitUrl(status); - } + this._submitFile(status); }, _submitFile: function(status) { diff --git a/Dnn.AdminExperience/ClientSide/Dnn.React.Common/src/FileUpload/index.jsx b/Dnn.AdminExperience/ClientSide/Dnn.React.Common/src/FileUpload/index.jsx index e9b964b4e69..f716ccb235f 100644 --- a/Dnn.AdminExperience/ClientSide/Dnn.React.Common/src/FileUpload/index.jsx +++ b/Dnn.AdminExperience/ClientSide/Dnn.React.Common/src/FileUpload/index.jsx @@ -1,492 +1,449 @@ -import React, { Component } from "react"; -import PropTypes from "prop-types"; -import LinkInput from "./LinkInput"; -import Browse from "./Browse"; -import UploadBar from "./UploadBar"; - -import "./style.less"; - -const Buttons = [ - { name: "browse" }, - { name: "upload" }, - { name: "link" } -]; - -export default class FileUpload extends Component { - constructor(props) { - super(props); - let fileExist = false; - let selectedFile = null; - let selectedFolder = null; - - this.fileInput1Ref = React.createRef(); - this.fileInput2Ref = React.createRef(); - - this.state = { - text: props.defaultText, - showLinkInput: false, - showFolderPicker: false, - - selectedFile, - selectedFolder, - - linkPath: "", - fileUrl: "", - - fileExist, - draggedOver: false, - isDragging: false, - - fileName: "", - - uploading: false, - uploadComplete: false, - horizontalOrientation: false, - - errorText: "" - }; - this.compareTimeout = setTimeout(this.compareDimensions.bind(this), 2000); - } - - updateStateAndReloadImage(file) { - const selectedFolder = { value: file.folderPath, key: file.folderId }; - const selectedFile = { value: file.fileName, key: file.fileId }; - const fileExist = true; - - this.setState({fileExist, selectedFile, selectedFolder}, () => { - this.getPreviewUrl(file.fileId); - }); - } - - componentDidMount() { - const file = this.props.selectedFile; - if (file) { - this.updateStateAndReloadImage(file); - } - window.addEventListener("dragover", this.prevent); - window.addEventListener("drop", this.prevent); - } - - componentDidUpdate(prevProps) { - const { props } = this; - if (!props.selectedFile && props.selectedFile !== prevProps.selectedFile) { - this.setState({ fileExist: null, selectedFile: null, selectedFolder: null }, () => {}); - return; - } - if (props.selectedFile && props.selectedFile !== prevProps.selectedFile && this.state.selectedFile) - { - if (props.selectedFile.fileId !== (this.state.selectedFile.fileId || + this.state.selectedFile.key)) { - const file = props.selectedFile; - this.updateStateAndReloadImage(file); - } - } - if (props.portalId !== prevProps.portalId) { - this.setState({ showFolderPicker: false }); - } - } - - prevent(e) { - e.preventDefault(); - } - - componentWillUnmount() { - window.removeEventListener("dragover", this.prevent); - window.removeEventListener("drop", this.prevent); - - this._unmounted = true; - if (this.compareTimeout) { - clearTimeout(this.compareTimeout); - this.compareTimeout = null; - } - } - - onLink() { - if (window.dnn !== undefined) { - window.dnn.stopEscapeFromClosingPB = true; - } - this.setState({ showLinkInput: true }); - } - - onBrowse() { - if (window.dnn !== undefined) { - window.dnn.stopEscapeFromClosingPB = true; - } - this.setState({ showFolderPicker: true }); - } - - onButtonClick(action) { - switch (action) { - case "link": - return this.onLink(); - case "browse": - return this.onBrowse(); - } - } - - hideFields() { - if (window.dnn !== undefined) { - window.dnn.stopEscapeFromClosingPB = false; - } - this.setState({ showLinkInput: false, showFolderPicker: false }); - } - - onMouseEnter(text) { - this.setState({ text }); - } - - onMouseLeave() { - this.setState({ text: this.props.defaultText }); - } - - onFileSelect(selectedFolder, selectedFile) { - this.setState({ selectedFolder, selectedFile }, () => { - this.getPreviewUrl(); - this.sendResult(); - }); - this.hideFields(); - } - - - handleImageError() { - this.setState({ fileExist: false }); - } - - onFileUpload(e) { - this.uploadFile(e.target.files[0]); - } - - handleError(error) { - const errorText = error && typeof error === "string" ? error : this.props.uploadFailedText; - this.setState({ uploading: true, errorText }, () => { - setTimeout(() => { - this.setState({ uploading: false, errorText: "" }); - }, 2000); - }); - } - - uploadFile(file) { - if (!file) { - return; - } - const fileFormats = this.props.fileFormats; - this.setState({ fileName: file.name }); - if (fileFormats.length > 0) { - let format = file.type; - const isAcceptFormat = fileFormats.some(f => format === f); - if (!isAcceptFormat) { - return this.handleError(this.props.wrongFormatText); - } - } - - this.postFile(file); - } - - getServiceFramework() { - let sf = this.props.utils.utilities.sf; - sf.controller = "FileUpload"; - sf.moduleRoot = "InternalServices"; - return sf; - } - - uploadFromLink(fileUrl) { - this.setState({ fileUrl: "" }); - this.uploadFromUrl(fileUrl); - this.hideFields(); - } - - showPreview(fileUrl) { - if (this._unmounted) { - return; - } - - this.setState({ fileUrl: "" }); - if (typeof fileUrl !== "string") { - return; - } - this.getImageDimensions(fileUrl); - this.setState({ fileUrl, fileExist: true }); - } - - sendResult() { - const selectedFile = this.state.selectedFile; - const selectedFolder = this.state.selectedFolder; - const fileId = selectedFile ? selectedFile.fileId || +selectedFile.key : null; - const folderPath = selectedFolder ? selectedFolder.value : null; - const fileName = selectedFile ? selectedFile.value : null; - this.props.onSelectFile({ - folderPath, - fileId, - fileName - }); - } - - uploadFromUrl(url) { - const folder = this.props.folderName && typeof this.props.folderName === "string" ? this.props.folderName : ""; - const sf = this.getServiceFramework(); - sf.post("UploadFromUrl", { url, folder }, this.uploadComplete.bind(this), this.handleError.bind(this)); - this.setState({ uploading: true, uploadComplete: false }); - } - - getPreviewUrl() { - const fileId = this.state.selectedFile ? this.state.selectedFile.fileId || +this.state.selectedFile.key : ""; - if (!fileId) { - this.setState({ fileUrl: "", fileExist: false }, this.sendResult.bind(this)); - } else { - const sf = this.getServiceFramework(); - sf.get("loadimage", { fileId }, this.showPreview.bind(this), this.callback); - } - } - - getImageDimensions(src) { - let tempImage = new Image(); - tempImage.src = src; - tempImage.onload = this.compareDimensions.bind(this, tempImage); - } - - compareDimensions(image) { - if (!image) { - return; - } - const componentDimension = this.node.getBoundingClientRect(); - - if (image.height && image.width / image.height > componentDimension.width / componentDimension.height) { - this.setState({ horizontalOrientation: true }); - } else { - this.setState({ horizontalOrientation: false }); - } - } - - postFile(file) { - const formData = new FormData(); - formData.append("postfile", file); - const sf = this.getServiceFramework(); - if (this.props.folderName && typeof this.props.folderName === "string") { - formData.append("folder", this.props.folderName); - } - if (this.props.validationCode && typeof this.props.validationCode === "string") { - formData.append("validationCode", this.props.validationCode); - } - sf.postfile(`UploadFromLocal${this.props.portalId === -1 ? "" : "?portalId=" + this.props.portalId}` , formData, this.uploadComplete.bind(this), this.handleError.bind(this)); - this.setState({ uploading: true, uploadComplete: false }); - - this.clearFileUploaderValue(this.fileInput1Ref); - this.clearFileUploaderValue(this.fileInput2Ref); - } - - clearFileUploaderValue(fileInput) { - if (fileInput) { - fileInput.value = ""; - } - } - - uploadComplete(res) { - this.setState({ uploadComplete: true }, () => { - setTimeout(() => { - this.setState({ uploading: false }); - }, 1000); - }); - const response = typeof res === "string" ? JSON.parse(res) : res; - if (!response.path) { - return; - } - const selectedFile = { value: response.fileName, fileId: response.fileId }; - this.setState({ selectedFile }, () => { - this.getPreviewUrl(); - this.sendResult(); - }); - } - - callback(result) { - } - - onDragOver() { - this.setState({ draggedOver: true, text: this.props.onDragOverText }); - } - - onDragLeave() { - this.setState({ draggedOver: false, text: this.props.defaultText }); - } - - onDrop(e) { - e.preventDefault(); - this.uploadFile(e.dataTransfer.files[0]); - this.onDragLeave(); - } - - getImageStyle() { - const {cropImagePreview} = this.props; - const {horizontalOrientation} = this.state; - let style = { width: "100%", height: "auto" }; - - if (horizontalOrientation && cropImagePreview) { - style = { height: "100%", width: "auto" }; - } - if (!horizontalOrientation && !cropImagePreview) { - style = { height: "100%", width: "auto" }; - } - return style; - } - - onChangeUrl(url) { - const {props, state} = this; - this.setState({fileUrl: url}); - } - - render() { - const {props, state} = this; - - let buttons = Buttons; - if (props.buttons) { - buttons = buttons.filter((button) => { - return props.buttons.some((propButton) => { - return button.name === propButton; - }); - }); - } - - buttons = buttons.map((button) => { - const svg = require(`!raw-loader!./img/${button.name}.svg`).default; - const isUpload = button.name === "upload"; - /* eslint-disable react/no-danger */ - const accept = props.fileFormats.join(","); - return
-
- {isUpload && accept && } - {isUpload && !accept && } -
; - }); - - const buttonsStyle = { width: buttons.length * 67 }; - const src = state.fileUrl || ""; - const showImage = src && state.fileExist && !state.showLinkInput && !state.showFolderPicker; - const className = "overlay" + (src && state.fileExist ? " has-image" : "") + (state.draggedOver ? " hover" : ""); - - return
this.node = node}> -
-
-
- {buttons} -
- {state.text} -
- - {state.showLinkInput && } - {state.showFolderPicker && } - {showImage &&
- {props.imageText}/
} - {state.selectedFile && -
{state.selectedFile.value}
} -
- {state.uploading && } -
; - } -} - - -FileUpload.propTypes = { - //---REQUIRED PROPS--- - utils: PropTypes.object.isRequired, - onSelectFile: PropTypes.func.isRequired, - validationCode: PropTypes.string.isRequired, - - //---OPTIONAL PROPS--- - selectedFile: PropTypes.object, - cropImagePreview: PropTypes.bool, - buttons: PropTypes.array, - folderName: PropTypes.string, - portalId: PropTypes.number, - fileFormats: PropTypes.array, - - //-- Localization Props--- - browseButtonText: PropTypes.string, - uploadButtonText: PropTypes.string, - linkButtonText: PropTypes.string, - defaultText: PropTypes.string, - onDragOverText: PropTypes.string, - uploadFailedText: PropTypes.string, - wrongFormatText: PropTypes.string, - imageText: PropTypes.string, - linkInputTitleText: PropTypes.string, - linkInputPlaceholderText: PropTypes.string, - linkInputActionText: PropTypes.string, - uploadCompleteText: PropTypes.string, - uploadingText: PropTypes.string, - uploadDefaultText: PropTypes.string, - browseActionText: PropTypes.string, - notSpecifiedText: PropTypes.string, - searchFilesPlaceHolderText: PropTypes.string, - searchFoldersPlaceHolderText: PropTypes.string, - fileText: PropTypes.string, - folderText: PropTypes.string -}; - -FileUpload.defaultProps = { - cropImagePreview: false, - portalId: -1, - fileFormats: [], - browseButtonText: "Browse Filesystem", - uploadButtonText: "Upload a File", - linkButtonText: "Enter URL Link", - defaultText: "Drag and Drop a File or Select an Option", - onDragOverText: "Drag and Drop a File", - uploadFailedText: "Upload Failed", - wrongFormatText: "wrong format", - imageText: "Image", - linkInputTitleText: "URL Link", - linkInputPlaceholderText: "http://example.com/imagename.jpg", - linkInputActionText: "Press {save|[ENTER]} to save, or {cancel|[ESC]} to cancel", - uploadCompleteText: "Upload Complete", - uploadingText: "Uploading...", - uploadDefaultText: "", - browseActionText: "Press {save|[ENTER]} to save, or {cancel|[ESC]} to cancel", - notSpecifiedText: "", - searchFilesPlaceHolderText: "Search Files...", - searchFoldersPlaceHolderText: "Search Folders...", - fileText: "File", - folderText: "Folder" -}; - - +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import Browse from "./Browse"; +import UploadBar from "./UploadBar"; + +import "./style.less"; + +const Buttons = [ + { name: "browse" }, + { name: "upload" } +]; + +export default class FileUpload extends Component { + constructor(props) { + super(props); + let fileExist = false; + let selectedFile = null; + let selectedFolder = null; + + this.fileInput1Ref = React.createRef(); + this.fileInput2Ref = React.createRef(); + + this.state = { + text: props.defaultText, + showFolderPicker: false, + + selectedFile, + selectedFolder, + + fileUrl: "", + + fileExist, + draggedOver: false, + isDragging: false, + + fileName: "", + + uploading: false, + uploadComplete: false, + horizontalOrientation: false, + + errorText: "" + }; + this.compareTimeout = setTimeout(this.compareDimensions.bind(this), 2000); + } + + updateStateAndReloadImage(file) { + const selectedFolder = { value: file.folderPath, key: file.folderId }; + const selectedFile = { value: file.fileName, key: file.fileId }; + const fileExist = true; + + this.setState({fileExist, selectedFile, selectedFolder}, () => { + this.getPreviewUrl(file.fileId); + }); + } + + componentDidMount() { + const file = this.props.selectedFile; + if (file) { + this.updateStateAndReloadImage(file); + } + window.addEventListener("dragover", this.prevent); + window.addEventListener("drop", this.prevent); + } + + componentDidUpdate(prevProps) { + const { props } = this; + if (!props.selectedFile && props.selectedFile !== prevProps.selectedFile) { + this.setState({ fileExist: null, selectedFile: null, selectedFolder: null }, () => {}); + return; + } + if (props.selectedFile && props.selectedFile !== prevProps.selectedFile && this.state.selectedFile) + { + if (props.selectedFile.fileId !== (this.state.selectedFile.fileId || + this.state.selectedFile.key)) { + const file = props.selectedFile; + this.updateStateAndReloadImage(file); + } + } + if (props.portalId !== prevProps.portalId) { + this.setState({ showFolderPicker: false }); + } + } + + prevent(e) { + e.preventDefault(); + } + + componentWillUnmount() { + window.removeEventListener("dragover", this.prevent); + window.removeEventListener("drop", this.prevent); + + this._unmounted = true; + if (this.compareTimeout) { + clearTimeout(this.compareTimeout); + this.compareTimeout = null; + } + } + + onBrowse() { + if (window.dnn !== undefined) { + window.dnn.stopEscapeFromClosingPB = true; + } + this.setState({ showFolderPicker: true }); + } + + onButtonClick(action) { + switch (action) { + case "browse": + return this.onBrowse(); + } + } + + hideFields() { + if (window.dnn !== undefined) { + window.dnn.stopEscapeFromClosingPB = false; + } + this.setState({ showFolderPicker: false }); + } + + onMouseEnter(text) { + this.setState({ text }); + } + + onMouseLeave() { + this.setState({ text: this.props.defaultText }); + } + + onFileSelect(selectedFolder, selectedFile) { + this.setState({ selectedFolder, selectedFile }, () => { + this.getPreviewUrl(); + this.sendResult(); + }); + this.hideFields(); + } + + + handleImageError() { + this.setState({ fileExist: false }); + } + + onFileUpload(e) { + this.uploadFile(e.target.files[0]); + } + + handleError(error) { + const errorText = error && typeof error === "string" ? error : this.props.uploadFailedText; + this.setState({ uploading: true, errorText }, () => { + setTimeout(() => { + this.setState({ uploading: false, errorText: "" }); + }, 2000); + }); + } + + uploadFile(file) { + if (!file) { + return; + } + const fileFormats = this.props.fileFormats; + this.setState({ fileName: file.name }); + if (fileFormats.length > 0) { + let format = file.type; + const isAcceptFormat = fileFormats.some(f => format === f); + if (!isAcceptFormat) { + return this.handleError(this.props.wrongFormatText); + } + } + + this.postFile(file); + } + + getServiceFramework() { + let sf = this.props.utils.utilities.sf; + sf.controller = "FileUpload"; + sf.moduleRoot = "InternalServices"; + return sf; + } + + showPreview(fileUrl) { + if (this._unmounted) { + return; + } + + this.setState({ fileUrl: "" }); + if (typeof fileUrl !== "string") { + return; + } + this.getImageDimensions(fileUrl); + this.setState({ fileUrl, fileExist: true }); + } + + sendResult() { + const selectedFile = this.state.selectedFile; + const selectedFolder = this.state.selectedFolder; + const fileId = selectedFile ? selectedFile.fileId || +selectedFile.key : null; + const folderPath = selectedFolder ? selectedFolder.value : null; + const fileName = selectedFile ? selectedFile.value : null; + this.props.onSelectFile({ + folderPath, + fileId, + fileName + }); + } + + getPreviewUrl() { + const fileId = this.state.selectedFile ? this.state.selectedFile.fileId || +this.state.selectedFile.key : ""; + if (!fileId) { + this.setState({ fileUrl: "", fileExist: false }, this.sendResult.bind(this)); + } else { + const sf = this.getServiceFramework(); + sf.get("loadimage", { fileId }, this.showPreview.bind(this), this.callback); + } + } + + getImageDimensions(src) { + let tempImage = new Image(); + tempImage.src = src; + tempImage.onload = this.compareDimensions.bind(this, tempImage); + } + + compareDimensions(image) { + if (!image) { + return; + } + const componentDimension = this.node.getBoundingClientRect(); + + if (image.height && image.width / image.height > componentDimension.width / componentDimension.height) { + this.setState({ horizontalOrientation: true }); + } else { + this.setState({ horizontalOrientation: false }); + } + } + + postFile(file) { + const formData = new FormData(); + formData.append("postfile", file); + const sf = this.getServiceFramework(); + if (this.props.folderName && typeof this.props.folderName === "string") { + formData.append("folder", this.props.folderName); + } + if (this.props.validationCode && typeof this.props.validationCode === "string") { + formData.append("validationCode", this.props.validationCode); + } + sf.postfile(`UploadFromLocal${this.props.portalId === -1 ? "" : "?portalId=" + this.props.portalId}` , formData, this.uploadComplete.bind(this), this.handleError.bind(this)); + this.setState({ uploading: true, uploadComplete: false }); + + this.clearFileUploaderValue(this.fileInput1Ref); + this.clearFileUploaderValue(this.fileInput2Ref); + } + + clearFileUploaderValue(fileInput) { + if (fileInput) { + fileInput.value = ""; + } + } + + uploadComplete(res) { + this.setState({ uploadComplete: true }, () => { + setTimeout(() => { + this.setState({ uploading: false }); + }, 1000); + }); + const response = typeof res === "string" ? JSON.parse(res) : res; + if (!response.path) { + return; + } + const selectedFile = { value: response.fileName, fileId: response.fileId }; + this.setState({ selectedFile }, () => { + this.getPreviewUrl(); + this.sendResult(); + }); + } + + callback(result) { + } + + onDragOver() { + this.setState({ draggedOver: true, text: this.props.onDragOverText }); + } + + onDragLeave() { + this.setState({ draggedOver: false, text: this.props.defaultText }); + } + + onDrop(e) { + e.preventDefault(); + this.uploadFile(e.dataTransfer.files[0]); + this.onDragLeave(); + } + + getImageStyle() { + const {cropImagePreview} = this.props; + const {horizontalOrientation} = this.state; + let style = { width: "100%", height: "auto" }; + + if (horizontalOrientation && cropImagePreview) { + style = { height: "100%", width: "auto" }; + } + if (!horizontalOrientation && !cropImagePreview) { + style = { height: "100%", width: "auto" }; + } + return style; + } + + onChangeUrl(url) { + const {props, state} = this; + this.setState({fileUrl: url}); + } + + render() { + const {props, state} = this; + + let buttons = Buttons; + if (props.buttons) { + buttons = buttons.filter((button) => { + return props.buttons.some((propButton) => { + return button.name === propButton; + }); + }); + } + + buttons = buttons.map((button) => { + const svg = require(`!raw-loader!./img/${button.name}.svg`).default; + const isUpload = button.name === "upload"; + /* eslint-disable react/no-danger */ + const accept = props.fileFormats.join(","); + return
+
+ {isUpload && accept && } + {isUpload && !accept && } +
; + }); + + const buttonsStyle = { width: buttons.length * 67 }; + const src = state.fileUrl || ""; + const showImage = src && state.fileExist && !state.showFolderPicker; + const className = "overlay" + (src && state.fileExist ? " has-image" : "") + (state.draggedOver ? " hover" : ""); + + return
this.node = node}> +
+
+
+ {buttons} +
+ {state.text} +
+ + {state.showFolderPicker && } + {showImage &&
+ {props.imageText}/
} + {state.selectedFile && +
{state.selectedFile.value}
} +
+ {state.uploading && } +
; + } +} + + +FileUpload.propTypes = { + //---REQUIRED PROPS--- + utils: PropTypes.object.isRequired, + onSelectFile: PropTypes.func.isRequired, + validationCode: PropTypes.string.isRequired, + + //---OPTIONAL PROPS--- + selectedFile: PropTypes.object, + cropImagePreview: PropTypes.bool, + buttons: PropTypes.array, + folderName: PropTypes.string, + portalId: PropTypes.number, + fileFormats: PropTypes.array, + + //-- Localization Props--- + browseButtonText: PropTypes.string, + uploadButtonText: PropTypes.string, + defaultText: PropTypes.string, + onDragOverText: PropTypes.string, + uploadFailedText: PropTypes.string, + wrongFormatText: PropTypes.string, + imageText: PropTypes.string, + uploadCompleteText: PropTypes.string, + uploadingText: PropTypes.string, + uploadDefaultText: PropTypes.string, + browseActionText: PropTypes.string, + notSpecifiedText: PropTypes.string, + searchFilesPlaceHolderText: PropTypes.string, + searchFoldersPlaceHolderText: PropTypes.string, + fileText: PropTypes.string, + folderText: PropTypes.string +}; + +FileUpload.defaultProps = { + cropImagePreview: false, + portalId: -1, + fileFormats: [], + browseButtonText: "Browse Filesystem", + uploadButtonText: "Upload a File", + defaultText: "Drag and Drop a File or Select an Option", + onDragOverText: "Drag and Drop a File", + uploadFailedText: "Upload Failed", + wrongFormatText: "wrong format", + imageText: "Image", + uploadCompleteText: "Upload Complete", + uploadingText: "Uploading...", + uploadDefaultText: "", + browseActionText: "Press {save|[ENTER]} to save, or {cancel|[ESC]} to cancel", + notSpecifiedText: "", + searchFilesPlaceHolderText: "Search Files...", + searchFoldersPlaceHolderText: "Search Folders...", + fileText: "File", + folderText: "Folder" +}; + +