import '../css/ImportTaskPanel.scss'; import React from 'react'; import PropTypes from 'prop-types'; import Dropzone from '../vendor/dropzone'; import csrf from '../django/csrf'; import ErrorMessage from './ErrorMessage'; import UploadProgressBar from './UploadProgressBar'; import { _, interpolate } from '../classes/gettext'; import Trans from './Trans'; class ImportTaskPanel extends React.Component { static defaultProps = { }; static propTypes = { onImported: PropTypes.func.isRequired, onCancel: PropTypes.func, projectId: PropTypes.number.isRequired }; constructor(props){ super(props); this.state = { error: "", typeUrl: false, uploading: false, importingFromUrl: false, progress: 0, bytesSent: 0, importUrl: "" }; } defaultTaskName = () => { return `Task of ${new Date().toISOString()}`; } componentDidMount(){ Dropzone.autoDiscover = false; if (this.dropzone){ this.dz = new Dropzone(this.dropzone, { paramName: "file", url : `/api/projects/${this.props.projectId}/tasks/import`, parallelUploads: 1, maxFilesize: 2147483647, uploadMultiple: false, acceptedFiles: "application/zip,application/octet-stream,application/x-zip-compressed,multipart/x-zip", autoProcessQueue: true, createImageThumbnails: false, previewTemplate: '
', clickable: this.uploadButton, chunkSize: 2147483647, timeout: 2147483647, chunking: true, chunkSize: 16000000, // 16MB headers: { [csrf.header]: csrf.token } }); this.dz.on("error", (file) => { if (this.state.uploading) this.setState({error: _("Cannot upload file. Check your internet connection and try again.")}); }) .on("sending", () => { this.setState({typeUrl: false, uploading: true, totalCount: 1}); }) .on("reset", () => { this.setState({uploading: false, progress: 0, totalBytes: 0, totalBytesSent: 0}); }) .on("uploadprogress", (file, progress, bytesSent) => { if (progress == 100) return; // Workaround for chunked upload progress bar jumping around this.setState({ progress, totalBytes: file.size, totalBytesSent: bytesSent }); }) .on("sending", (file, xhr, formData) => { // Safari does not have support for has on FormData // as of December 2017 if (!formData.has || !formData.has("name")) formData.append("name", this.defaultTaskName()); }) .on("complete", (file) => { if (file.status === "success"){ this.setState({uploading: false}); try{ let response = JSON.parse(file.xhr.response); if (!response.id) throw new Error(`Expected id field, but none given (${response})`); this.props.onImported(); }catch(e){ this.setState({error: interpolate(_('Invalid response from server: %(error)s'), { error: e.message})}); } }else if (this.state.uploading){ this.setState({uploading: false, error: _("An error occured while uploading the file. Please try again.")}); } }); } } cancel = (e) => { this.cancelUpload(); this.props.onCancel(); } cancelUpload = (e) => { this.setState({uploading: false}); setTimeout(() => { this.dz.removeAllFiles(true); }, 0); } handleImportFromUrl = () => { this.setState({typeUrl: !this.state.typeUrl}); } handleCancelImportFromURL = () => { this.setState({typeUrl: false}); } handleChangeImportUrl = (e) => { this.setState({importUrl: e.target.value}); } handleConfirmImportUrl = () => { this.setState({importingFromUrl: true}); $.post(`/api/projects/${this.props.projectId}/tasks/import`, { url: this.state.importUrl, name: this.defaultTaskName() } ).done(json => { this.setState({importingFromUrl: false}); if (json.id){ this.props.onImported(); }else{ this.setState({error: json.error || interpolate(_("Invalid JSON response: %(error)s"), {error: JSON.stringify(json)})}); } }) .fail(() => { this.setState({importingFromUrl: false, error: _("Cannot import from URL. Check your internet connection.")}); }); } setRef = (prop) => { return (domNode) => { if (domNode != null) this[prop] = domNode; } } render() { return (

{_("Import Existing Assets")}

'}}>{_("You can import .zip files that have been exported from existing tasks via Download Assets %(arrow)s All Assets.")}

{this.state.typeUrl ?
: ""} {this.state.uploading ?
: ""}
); } } export default ImportTaskPanel;