|
|
|
/*
|
|
|
|
* Minio Cloud Storage (C) 2016 Minio, Inc.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
import React from 'react'
|
|
|
|
import humanize from 'humanize'
|
|
|
|
import classNames from 'classnames'
|
|
|
|
import connect from 'react-redux/lib/components/connect'
|
|
|
|
|
|
|
|
import ProgressBar from 'react-bootstrap/lib/ProgressBar'
|
|
|
|
import ConfirmModal from './ConfirmModal'
|
|
|
|
|
|
|
|
import * as actions from '../actions'
|
|
|
|
|
|
|
|
// UploadModal is a modal that handles multiple file uploads.
|
|
|
|
// During the upload, it displays a progress bar, and can transform into an
|
|
|
|
// abort modal if the user decides to abort the uploads.
|
|
|
|
class UploadModal extends React.Component {
|
|
|
|
|
|
|
|
// Abort all the current uploads.
|
|
|
|
abortUploads(e) {
|
|
|
|
e.preventDefault()
|
|
|
|
const {dispatch, uploads} = this.props
|
|
|
|
|
|
|
|
for (var slug in uploads) {
|
|
|
|
let upload = uploads[slug]
|
|
|
|
upload.xhr.abort()
|
|
|
|
dispatch(actions.stopUpload({
|
|
|
|
slug
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
|
|
|
this.hideAbort(e)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Show the abort modal instead of the progress modal.
|
|
|
|
showAbort(e) {
|
|
|
|
e.preventDefault()
|
|
|
|
const {dispatch} = this.props
|
|
|
|
|
|
|
|
dispatch(actions.setShowAbortModal(true))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Show the progress modal instead of the abort modal.
|
|
|
|
hideAbort(e) {
|
|
|
|
e.preventDefault()
|
|
|
|
const {dispatch} = this.props
|
|
|
|
|
|
|
|
dispatch(actions.setShowAbortModal(false))
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const {uploads, showAbortModal} = this.props
|
|
|
|
|
|
|
|
// Show the abort modal.
|
|
|
|
if (showAbortModal) {
|
|
|
|
let baseClass = classNames({
|
|
|
|
'abort-upload': true
|
|
|
|
})
|
|
|
|
let okIcon = classNames({
|
|
|
|
'fa': true,
|
|
|
|
'fa-times': true
|
|
|
|
})
|
|
|
|
let cancelIcon = classNames({
|
|
|
|
'fa': true,
|
|
|
|
'fa-cloud-upload': true
|
|
|
|
})
|
|
|
|
|
|
|
|
return (
|
|
|
|
<ConfirmModal show={ true }
|
|
|
|
baseClass={ baseClass }
|
|
|
|
text='Abort uploads in progress?'
|
|
|
|
icon='fa fa-info-circle mci-amber'
|
|
|
|
sub='This cannot be undone!'
|
|
|
|
okText='Abort'
|
|
|
|
okIcon={ okIcon }
|
|
|
|
cancelText='Upload'
|
|
|
|
cancelIcon={ cancelIcon }
|
|
|
|
okHandler={ this.abortUploads.bind(this) }
|
|
|
|
cancelHandler={ this.hideAbort.bind(this) }>
|
|
|
|
</ConfirmModal>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we don't have any files uploading, don't show anything.
|
|
|
|
let numberUploading = Object.keys(uploads).length
|
|
|
|
if (numberUploading == 0)
|
|
|
|
return ( <noscript></noscript> )
|
|
|
|
|
|
|
|
let totalLoaded = 0
|
|
|
|
let totalSize = 0
|
|
|
|
|
|
|
|
// Iterate over each upload, adding together the total size and that
|
|
|
|
// which has been uploaded.
|
|
|
|
for (var slug in uploads) {
|
|
|
|
let upload = uploads[slug]
|
|
|
|
totalLoaded += upload.loaded
|
|
|
|
totalSize += upload.size
|
|
|
|
}
|
|
|
|
|
|
|
|
let percent = (totalLoaded / totalSize) * 100
|
|
|
|
|
|
|
|
// If more than one: "Uploading files (5)..."
|
|
|
|
// If only one: "Uploading myfile.txt..."
|
|
|
|
let text = 'Uploading ' + (numberUploading == 1 ? `'${uploads[Object.keys(uploads)[0]].name}'` : `files (${numberUploading})`) + '...'
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className="alert alert-info progress animated fadeInUp ">
|
|
|
|
<button type="button" className="close" onClick={ this.showAbort.bind(this) }>
|
|
|
|
<span>×</span>
|
|
|
|
</button>
|
|
|
|
<div className="text-center">
|
|
|
|
<small>{ text }</small>
|
|
|
|
</div>
|
|
|
|
<ProgressBar now={ percent } />
|
|
|
|
<div className="text-center">
|
|
|
|
<small>{ humanize.filesize(totalLoaded) } ({ percent.toFixed(2) } %)</small>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default connect(state => {
|
|
|
|
return {
|
|
|
|
uploads: state.uploads,
|
|
|
|
showAbortModal: state.showAbortModal
|
|
|
|
}
|
|
|
|
})(UploadModal)
|