1
0
mirror of https://github.com/ascribe/onion.git synced 2024-12-23 01:39:36 +01:00

Merge remote-tracking branch 'remotes/origin/AD-496-add-control-buttons-to-fineupload' into AD-368-harmonize-functionality-of-ascrib

Conflicts:
	js/components/ascribe_uploader/react_s3_fine_uploader.js
This commit is contained in:
diminator 2015-06-29 16:15:08 +02:00
commit e36681ad4d
11 changed files with 300 additions and 105 deletions

View File

@ -7,6 +7,7 @@ import FileDragAndDropPreviewIterator from './file_drag_and_drop_preview_iterato
// Taken from: https://github.com/fedosejev/react-file-drag-and-drop // Taken from: https://github.com/fedosejev/react-file-drag-and-drop
var FileDragAndDrop = React.createClass({ var FileDragAndDrop = React.createClass({
propTypes: { propTypes: {
className: React.PropTypes.string,
onDragStart: React.PropTypes.func, onDragStart: React.PropTypes.func,
onDrop: React.PropTypes.func.isRequired, onDrop: React.PropTypes.func.isRequired,
onDrag: React.PropTypes.func, onDrag: React.PropTypes.func,
@ -17,6 +18,7 @@ var FileDragAndDrop = React.createClass({
onDragEnd: React.PropTypes.func, onDragEnd: React.PropTypes.func,
filesToUpload: React.PropTypes.array, filesToUpload: React.PropTypes.array,
handleDeleteFile: React.PropTypes.func, handleDeleteFile: React.PropTypes.func,
handleCancelFile: React.PropTypes.func,
multiple: React.PropTypes.bool, multiple: React.PropTypes.bool,
dropzoneInactive: React.PropTypes.bool dropzoneInactive: React.PropTypes.bool
}, },
@ -59,7 +61,6 @@ var FileDragAndDrop = React.createClass({
} }
}, },
handleDrop(event) { handleDrop(event) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
@ -85,6 +86,13 @@ var FileDragAndDrop = React.createClass({
this.props.handleDeleteFile(fileId); this.props.handleDeleteFile(fileId);
}, },
handleCancelFile(fileId) {
// input's value is not change the second time someone
// inputs the same file again, therefore we need to reset its value
this.refs.fileinput.getDOMNode().value = '';
this.props.handleCancelFile(fileId);
},
handleOnClick() { handleOnClick() {
// when multiple is set to false and the user already uploaded a piece, // when multiple is set to false and the user already uploaded a piece,
// do not propagate event // do not propagate event
@ -99,9 +107,11 @@ var FileDragAndDrop = React.createClass({
}, },
render: function () { render: function () {
let hasFiles = this.props.filesToUpload.length > 0; // has files only is true if there are files that do not have the status deleted or canceled
let className = hasFiles ? 'file-drag-and-drop has-files ' : 'file-drag-and-drop '; let hasFiles = this.props.filesToUpload.filter((file) => file.status !== 'deleted' && file.status !== 'canceled').length > 0;
let className = hasFiles ? 'has-files ' : '';
className += this.props.dropzoneInactive ? 'inactive-dropzone' : 'active-dropzone'; className += this.props.dropzoneInactive ? 'inactive-dropzone' : 'active-dropzone';
className += this.props.className ? ' ' + this.props.className : '';
return ( return (
<div <div
@ -114,10 +124,11 @@ var FileDragAndDrop = React.createClass({
onDragOver={this.handleDragOver} onDragOver={this.handleDragOver}
onDrop={this.handleDrop} onDrop={this.handleDrop}
onDragEnd={this.handleDragEnd}> onDragEnd={this.handleDragEnd}>
{hasFiles ? null : this.props.multiple ? <span>Click or drag to add files</span> : <span>Click or drag to add a file</span>} {hasFiles ? null : this.props.multiple ? <span className="file-drag-and-drop-dialog">Click or drag to add files</span> : <span className="file-drag-and-drop-dialog">Click or drag to add a file</span>}
<FileDragAndDropPreviewIterator <FileDragAndDropPreviewIterator
files={this.props.filesToUpload} files={this.props.filesToUpload}
handleDeleteFile={this.handleDeleteFile}/> handleDeleteFile={this.handleDeleteFile}
handleCancelFile={this.handleCancelFile}/>
<input <input
multiple={this.props.multiple} multiple={this.props.multiple}
ref="fileinput" ref="fileinput"

View File

@ -13,17 +13,19 @@ let FileDragAndDropPreview = React.createClass({
url: React.PropTypes.string, url: React.PropTypes.string,
type: React.PropTypes.string type: React.PropTypes.string
}).isRequired, }).isRequired,
handleDeleteFile: React.PropTypes.func handleDeleteFile: React.PropTypes.func,
handleCancelFile: React.PropTypes.func
}, },
handleDeleteFile(event) { handleDeleteFile() {
event.preventDefault();
event.stopPropagation();
// handleDeleteFile is optional, so if its not submitted, // handleDeleteFile is optional, so if its not submitted,
// don't run it // don't run it
if(this.props.handleDeleteFile) { // On the other hand, if the files progress is not yet at a 100%,
// just run fineuploader.cancel
if(this.props.handleDeleteFile && this.props.file.progress === 100) {
this.props.handleDeleteFile(this.props.file.id); this.props.handleDeleteFile(this.props.file.id);
} else if(this.props.handleCancelFile && this.props.file.progress !== 100) {
this.props.handleCancelFile(this.props.file.id);
} }
}, },

View File

@ -3,6 +3,8 @@
import React from 'react'; import React from 'react';
import ProgressBar from 'react-progressbar'; import ProgressBar from 'react-progressbar';
import AppConstants from '../../constants/application_constants';
let FileDragAndDropPreviewImage = React.createClass({ let FileDragAndDropPreviewImage = React.createClass({
propTypes: { propTypes: {
progress: React.PropTypes.number, progress: React.PropTypes.number,
@ -10,19 +12,36 @@ let FileDragAndDropPreviewImage = React.createClass({
onClick: React.PropTypes.func onClick: React.PropTypes.func
}, },
getInitialState() {
return {
loading: false
};
},
onClick(e) {
e.preventDefault();
e.stopPropagation();
this.setState({
loading: true
});
this.props.onClick(e);
},
render() { render() {
let imageStyle = { let imageStyle = {
backgroundImage: 'url("' + this.props.url + '")', backgroundImage: 'url("' + this.props.url + '")',
backgroundSize: 'cover' backgroundSize: 'cover'
}; };
let actionSymbol = this.state.loading ? <img src={AppConstants.baseUrl + 'static/img/ascribe_animated_medium.gif'} /> : <span className="glyphicon glyphicon-remove delete-file" aria-hidden="true" title="Delete or cancel upload" onClick={this.onClick} />;
return ( return (
<div <div
onClick={this.props.onClick}
className="file-drag-and-drop-preview-image" className="file-drag-and-drop-preview-image"
style={imageStyle}> style={imageStyle}>
<ProgressBar completed={this.props.progress} color="black"/> <ProgressBar completed={this.props.progress} color="black"/>
{this.props.progress === 100 ? <span className="glyphicon glyphicon-remove delete-file" aria-hidden="true" title="Delete"></span> : null} {actionSymbol}
</div> </div>
); );
} }

View File

@ -7,7 +7,8 @@ import FileDragAndDropPreview from './file_drag_and_drop_preview';
let FileDragAndDropPreviewIterator = React.createClass({ let FileDragAndDropPreviewIterator = React.createClass({
propTypes: { propTypes: {
files: React.PropTypes.array, files: React.PropTypes.array,
handleDeleteFile: React.PropTypes.func handleDeleteFile: React.PropTypes.func,
handleCancelFile: React.PropTypes.func
}, },
render() { render() {
@ -15,12 +16,17 @@ let FileDragAndDropPreviewIterator = React.createClass({
return ( return (
<div> <div>
{this.props.files.map((file, i) => { {this.props.files.map((file, i) => {
if(file.status !== 'deleted' && file.status !== 'canceled') {
return ( return (
<FileDragAndDropPreview <FileDragAndDropPreview
key={i} key={i}
file={file} file={file}
handleDeleteFile={this.props.handleDeleteFile}/> handleDeleteFile={this.props.handleDeleteFile}
handleCancelFile={this.props.handleCancelFile}/>
); );
} else {
return null;
}
})} })}
</div> </div>
); );

View File

@ -3,6 +3,8 @@
import React from 'react'; import React from 'react';
import ProgressBar from 'react-progressbar'; import ProgressBar from 'react-progressbar';
import AppConstants from '../../constants/application_constants';
let FileDragAndDropPreviewOther = React.createClass({ let FileDragAndDropPreviewOther = React.createClass({
propTypes: { propTypes: {
type: React.PropTypes.string, type: React.PropTypes.string,
@ -10,15 +12,32 @@ let FileDragAndDropPreviewOther = React.createClass({
onClick: React.PropTypes.func onClick: React.PropTypes.func
}, },
getInitialState() {
return {
loading: false
};
},
onClick(e) {
e.preventDefault();
e.stopPropagation();
this.setState({
loading: true
});
this.props.onClick(e);
},
render() { render() {
let actionSymbol = this.state.loading ? <img src={AppConstants.baseUrl + 'static/img/ascribe_animated_medium.gif'} /> : <span className="glyphicon glyphicon-remove delete-file" aria-hidden="true" title="Delete or cancel upload" onClick={this.onClick} />;
return ( return (
<div <div
onClick={this.props.onClick}
className="file-drag-and-drop-preview"> className="file-drag-and-drop-preview">
<ProgressBar completed={this.props.progress} color="black"/> <ProgressBar completed={this.props.progress} color="black"/>
<div className="file-drag-and-drop-preview-table-wrapper"> <div className="file-drag-and-drop-preview-table-wrapper">
<div className="file-drag-and-drop-preview-other"> <div className="file-drag-and-drop-preview-other">
{this.props.progress === 100 ? <span className="glyphicon glyphicon-remove delete-file" aria-hidden="true" title="Delete"></span> : null} {actionSymbol}
<span>{'.' + this.props.type}</span> <span>{'.' + this.props.type}</span>
</div> </div>
</div> </div>

View File

@ -0,0 +1,13 @@
'use strict';
import React from 'react';
let FileDragAndDropToolbar = React.createClass({
render() {
return (
<div></div>
);
}
});
export default FileDragAndDropToolbar;

View File

@ -12,6 +12,7 @@ import { getCookie } from '../../utils/fetch_api_utils';
import fineUploader from 'fineUploader'; import fineUploader from 'fineUploader';
import FileDragAndDrop from './file_drag_and_drop'; import FileDragAndDrop from './file_drag_and_drop';
import FileDragAndDropToolbar from './file_drag_and_drop_toolbar';
import GlobalNotificationModel from '../../models/global_notification_model'; import GlobalNotificationModel from '../../models/global_notification_model';
import GlobalNotificationActions from '../../actions/global_notification_actions'; import GlobalNotificationActions from '../../actions/global_notification_actions';
@ -27,7 +28,7 @@ var ReactS3FineUploader = React.createClass({
createBlobRoutine: React.PropTypes.shape({ createBlobRoutine: React.PropTypes.shape({
url: React.PropTypes.string url: React.PropTypes.string
}), }),
handleChange: React.PropTypes.func, submitKey: React.PropTypes.func,
autoUpload: React.PropTypes.bool, autoUpload: React.PropTypes.bool,
debug: React.PropTypes.bool, debug: React.PropTypes.bool,
objectProperties: React.PropTypes.shape({ objectProperties: React.PropTypes.shape({
@ -63,7 +64,8 @@ var ReactS3FineUploader = React.createClass({
deleteFile: React.PropTypes.shape({ deleteFile: React.PropTypes.shape({
enabled: React.PropTypes.bool, enabled: React.PropTypes.bool,
method: React.PropTypes.string, method: React.PropTypes.string,
endpoint: React.PropTypes.string endpoint: React.PropTypes.string,
customHeaders: React.PropTypes.object
}), }),
session: React.PropTypes.shape({ session: React.PropTypes.shape({
endpoint: React.PropTypes.bool endpoint: React.PropTypes.bool
@ -79,15 +81,11 @@ var ReactS3FineUploader = React.createClass({
multiple: React.PropTypes.bool, multiple: React.PropTypes.bool,
retry: React.PropTypes.shape({ retry: React.PropTypes.shape({
enableAuto: React.PropTypes.bool enableAuto: React.PropTypes.bool
}) }),
setUploadStatus: React.PropTypes.func,
isReadyForFormSubmission: React.PropTypes.func
}, },
getInitialState() {
return {
filesToUpload: [],
uploader: new fineUploader.s3.FineUploaderBasic(this.propsToConfig())
};
},
getDefaultProps() { getDefaultProps() {
return { return {
autoUpload: true, autoUpload: true,
@ -147,6 +145,14 @@ var ReactS3FineUploader = React.createClass({
multiple: false multiple: false
}; };
}, },
getInitialState() {
return {
filesToUpload: [],
uploader: new fineUploader.s3.FineUploaderBasic(this.propsToConfig())
};
},
propsToConfig() { propsToConfig() {
let objectProperties = this.props.objectProperties; let objectProperties = this.props.objectProperties;
objectProperties.key = this.requestKey; objectProperties.key = this.requestKey;
@ -171,6 +177,7 @@ var ReactS3FineUploader = React.createClass({
callbacks: { callbacks: {
onSubmit: this.onSubmit, onSubmit: this.onSubmit,
onComplete: this.onComplete, onComplete: this.onComplete,
onCancel: this.onCancel,
onDelete: this.onDelete, onDelete: this.onDelete,
onSessionRequestComplete: this.onSessionRequestComplete, onSessionRequestComplete: this.onSessionRequestComplete,
onProgress: this.onProgress, onProgress: this.onProgress,
@ -235,8 +242,16 @@ var ReactS3FineUploader = React.createClass({
}); });
this.setState(newState); this.setState(newState);
this.createBlob(files[id]); this.createBlob(files[id]);
this.props.handleChange(); this.props.submitKey(files[id].key);
console.log('completed ' + files[id].name);
// also, lets check if after the completion of this upload,
// the form is ready for submission or not
if(this.props.isReadyForFormSubmission && this.props.isReadyForFormSubmission(this.state.filesToUpload)) {
// if so, set uploadstatus to true
this.props.setUploadStatus(true);
} else {
this.props.setUploadStatus(false);
}
}, },
createBlob(file) { createBlob(file) {
@ -282,13 +297,18 @@ var ReactS3FineUploader = React.createClass({
console.log('delete'); console.log('delete');
}, },
onCancel() { onCancel(id) {
console.log('cancel'); this.removeFileWithIdFromFilesToUpload(id);
// handle file removal here, for this.state.filesToUpload (same as in onDeleteComplete)
},
onSessionRequestComplete() { let notification = new GlobalNotificationModel('File upload canceled', 'success', 5000);
console.log('sessionrequestcomplete'); GlobalNotificationActions.appendGlobalNotification(notification);
if(this.props.isReadyForFormSubmission && this.props.isReadyForFormSubmission(this.state.filesToUpload)) {
// if so, set uploadstatus to true
this.props.setUploadStatus(true);
} else {
this.props.setUploadStatus(false);
}
}, },
onDeleteComplete(id, xhr, isError) { onDeleteComplete(id, xhr, isError) {
@ -296,21 +316,18 @@ var ReactS3FineUploader = React.createClass({
let notification = new GlobalNotificationModel('Couldn\'t delete file', 'danger', 10000); let notification = new GlobalNotificationModel('Couldn\'t delete file', 'danger', 10000);
GlobalNotificationActions.appendGlobalNotification(notification); GlobalNotificationActions.appendGlobalNotification(notification);
} else { } else {
// also, sync files from state with the ones from fineuploader this.removeFileWithIdFromFilesToUpload(id);
let filesToUpload = JSON.parse(JSON.stringify(this.state.filesToUpload));
// splice because I can let notification = new GlobalNotificationModel('File deleted', 'success', 5000);
filesToUpload.splice(id, 1);
// set state
let newState = React.addons.update(this.state, {
filesToUpload: { $set: filesToUpload }
});
this.setState(newState);
let notification = new GlobalNotificationModel('File deleted', 'success', 10000);
GlobalNotificationActions.appendGlobalNotification(notification); GlobalNotificationActions.appendGlobalNotification(notification);
} }
if(this.props.isReadyForFormSubmission && this.props.isReadyForFormSubmission(this.state.filesToUpload)) {
// if so, set uploadstatus to true
this.props.setUploadStatus(true);
} else {
this.props.setUploadStatus(false);
}
}, },
onProgress(id, name, uploadedBytes, totalBytes) { onProgress(id, name, uploadedBytes, totalBytes) {
@ -330,11 +347,15 @@ var ReactS3FineUploader = React.createClass({
// promise // promise
}, },
handleCancelFile(fileId) {
this.state.uploader.cancel(fileId);
},
handleUploadFile(files) { handleUploadFile(files) {
// If multiple set and user already uploaded its work, // If multiple set and user already uploaded its work,
// cancel upload // cancel upload
if(!this.props.multiple && this.state.filesToUpload.length > 0) { if(!this.props.multiple && this.state.filesToUpload.filter((file) => file.status !== 'deleted' && file.status !== 'canceled').length > 0) {
return; return;
} }
@ -373,24 +394,45 @@ var ReactS3FineUploader = React.createClass({
oldAndNewFiles[i].progress = oldFiles[j].progress; oldAndNewFiles[i].progress = oldFiles[j].progress;
oldAndNewFiles[i].type = oldFiles[j].type; oldAndNewFiles[i].type = oldFiles[j].type;
oldAndNewFiles[i].url = oldFiles[j].url; oldAndNewFiles[i].url = oldFiles[j].url;
oldAndNewFiles[i].key = oldFiles[j].key;
} }
} }
} }
// set the new file array
let newState = React.addons.update(this.state, { let newState = React.addons.update(this.state, {
filesToUpload: { $set: oldAndNewFiles } filesToUpload: { $set: oldAndNewFiles }
}); });
this.setState(newState); this.setState(newState);
}, },
removeFileWithIdFromFilesToUpload(fileId) {
// also, sync files from state with the ones from fineuploader
let filesToUpload = JSON.parse(JSON.stringify(this.state.filesToUpload));
// splice because I can
filesToUpload.splice(fileId, 1);
// set state
let newState = React.addons.update(this.state, {
filesToUpload: { $set: filesToUpload }
});
this.setState(newState);
},
render() { render() {
return ( return (
<div>
<FileDragAndDrop <FileDragAndDrop
className="file-drag-and-drop"
onDrop={this.handleUploadFile} onDrop={this.handleUploadFile}
filesToUpload={this.state.filesToUpload} filesToUpload={this.state.filesToUpload}
handleDeleteFile={this.handleDeleteFile} handleDeleteFile={this.handleDeleteFile}
handleCancelFile={this.handleCancelFile}
multiple={this.props.multiple} multiple={this.props.multiple}
dropzoneInactive={!this.props.multiple && this.state.filesToUpload.length > 0} /> dropzoneInactive={!this.props.multiple && this.state.filesToUpload.filter((file) => file.status !== 'deleted' && file.status !== 'canceled').length > 0} />
<FileDragAndDropToolbar />
</div>
); );
} }

View File

@ -434,12 +434,40 @@ let EditionFurtherDetails = React.createClass({
edition: React.PropTypes.object, edition: React.PropTypes.object,
handleSuccess: React.PropTypes.func handleSuccess: React.PropTypes.func
}, },
getInitialState() {
return {
loading: false
};
},
showNotification(){ showNotification(){
this.props.handleSuccess(); this.props.handleSuccess();
let notification = new GlobalNotificationModel('Details updated', 'success'); let notification = new GlobalNotificationModel('Details updated', 'success');
GlobalNotificationActions.appendGlobalNotification(notification); GlobalNotificationActions.appendGlobalNotification(notification);
}, },
submitKey(key){
this.setState({
otherDataKey: key
});
},
setUploadStatus(isReady) {
this.setState({
uploadStatus: isReady
});
},
isReadyForFormSubmission(files) {
files = files.filter((file) => file.status !== 'deleted' && file.status !== 'canceled');
if(files.length > 0 && files[0].status === 'upload successful') {
return true;
} else {
return false;
}
},
render() { render() {
let editable = this.props.edition.acl.indexOf('edit') > -1; let editable = this.props.edition.acl.indexOf('edit') > -1;
return ( return (
@ -464,22 +492,26 @@ let EditionFurtherDetails = React.createClass({
editable={editable} editable={editable}
edition={this.props.edition} /> edition={this.props.edition} />
<FileUploader <FileUploader
edition={this.props.edition} submitKey={this.submitKey}
ref='uploader'/> setUploadStatus={this.setUploadStatus}
isReadyForFormSubmission={this.isReadyForFormSubmission}
edition={this.props.edition}/>
</Col> </Col>
</Row> </Row>
); );
} }
}); });
let FileUploader = React.createClass( { let FileUploader = React.createClass({
handleChange(){ propTypes: {
this.setState({other_data_key: this.refs.fineuploader.state.filesToUpload[0].key}); setUploadStatus: React.PropTypes.func,
submitKey: React.PropTypes.func,
isReadyForFormSubmission: React.PropTypes.func
}, },
render() { render() {
return ( return (
<ReactS3FineUploader <ReactS3FineUploader
ref='fineuploader'
keyRoutine={{ keyRoutine={{
url: AppConstants.serverUrl + 's3/key/', url: AppConstants.serverUrl + 's3/key/',
fileClass: 'otherdata', fileClass: 'otherdata',
@ -488,11 +520,13 @@ let FileUploader = React.createClass( {
createBlobRoutine={{ createBlobRoutine={{
url: apiUrls.blob_digitalworks url: apiUrls.blob_digitalworks
}} }}
handleChange={this.handleChange}
validation={{ validation={{
itemLimit: 100000, itemLimit: 100000,
sizeLimit: '10000000' sizeLimit: '10000000'
}}/> }}
submitKey={this.props.submitKey}
setUploadStatus={this.props.setUploadStatus}
isReadyForFormSubmission={this.props.isReadyForFormSubmission}/>
); );
} }
}); });

View File

@ -24,8 +24,12 @@ let RegisterPiece = React.createClass( {
mixins: [Router.Navigation], mixins: [Router.Navigation],
getInitialState(){ getInitialState(){
return {digital_work_key: null}; return {
digitalWorkKey: null,
uploadStatus: false
};
}, },
handleSuccess(){ handleSuccess(){
let notification = new GlobalNotificationModel('Login successsful', 'success', 10000); let notification = new GlobalNotificationModel('Login successsful', 'success', 10000);
GlobalNotificationActions.appendGlobalNotification(notification); GlobalNotificationActions.appendGlobalNotification(notification);
@ -37,30 +41,44 @@ let RegisterPiece = React.createClass( {
for (let ref in this.refs.form.refs){ for (let ref in this.refs.form.refs){
data[this.refs.form.refs[ref].props.name] = this.refs.form.refs[ref].state.value; data[this.refs.form.refs[ref].props.name] = this.refs.form.refs[ref].state.value;
} }
data.digital_work_key = this.state.digital_work_key; data.digital_work_key = this.state.digitalWorkKey;
return data; return data;
}, },
handleChange(){
this.setState({digital_work_key: this.refs.uploader.refs.fineuploader.state.filesToUpload[0].key}); submitKey(key){
this.setState({
digitalWorkKey: key
});
},
setUploadStatus(isReady) {
this.setState({
uploadStatus: isReady
});
},
isReadyForFormSubmission(files) {
files = files.filter((file) => file.status !== 'deleted' && file.status !== 'canceled');
if(files.length > 0 && files[0].status === 'upload successful') {
return true;
} else {
return false;
}
}, },
render() { render() {
let buttons = null; let buttons = null;
if (this.refs.uploader && this.refs.uploader.refs.fineuploader.state.filesToUpload[0].status === 'upload successful'){
if (this.state.uploadStatus){
buttons = ( buttons = (
<button type="submit" className="btn ascribe-btn ascribe-btn-login"> <button type="submit" className="btn ascribe-btn ascribe-btn-login">
Register your artwork Register your artwork
</button>); </button>);
} }
return ( return (
<div className="row ascribe-row"> <div className="row ascribe-row">
<div className="col-md-5"> <div className="col-md-12">
<FileUploader
ref='uploader'
handleChange={this.handleChange}/>
<br />
</div>
<div className="col-md-7">
<h3 style={{'marginTop': 0}}>Lock down title</h3> <h3 style={{'marginTop': 0}}>Lock down title</h3>
<Form <Form
ref='form' ref='form'
@ -73,6 +91,13 @@ let RegisterPiece = React.createClass( {
<img src="https://s3-us-west-2.amazonaws.com/ascribe0/media/thumbnails/ascribe_animated_medium.gif" /> <img src="https://s3-us-west-2.amazonaws.com/ascribe0/media/thumbnails/ascribe_animated_medium.gif" />
</button> </button>
}> }>
<Property
label="Files to upload">
<FileUploader
submitKey={this.submitKey}
setUploadStatus={this.setUploadStatus}
isReadyForFormSubmission={this.isReadyForFormSubmission}/>
</Property>
<Property <Property
name='artist_name' name='artist_name'
label="Artist Name"> label="Artist Name">
@ -116,11 +141,16 @@ let RegisterPiece = React.createClass( {
}); });
let FileUploader = React.createClass( { let FileUploader = React.createClass({
propTypes: {
setUploadStatus: React.PropTypes.func,
submitKey: React.PropTypes.func,
isReadyForFormSubmission: React.PropTypes.func
},
render() { render() {
return ( return (
<ReactS3FineUploader <ReactS3FineUploader
ref='fineuploader'
keyRoutine={{ keyRoutine={{
url: AppConstants.serverUrl + 's3/key/', url: AppConstants.serverUrl + 's3/key/',
fileClass: 'digitalwork' fileClass: 'digitalwork'
@ -128,11 +158,13 @@ let FileUploader = React.createClass( {
createBlobRoutine={{ createBlobRoutine={{
url: apiUrls.blob_digitalworks url: apiUrls.blob_digitalworks
}} }}
handleChange={this.props.handleChange} submitKey={this.props.submitKey}
validation={{ validation={{
itemLimit: 100000, itemLimit: 100000,
sizeLimit: '25000000000' sizeLimit: '25000000000'
}}/> }}
setUploadStatus={this.props.setUploadStatus}
isReadyForFormSubmission={this.props.isReadyForFormSubmission}/>
); );
} }
}); });

View File

@ -68,12 +68,14 @@
padding-top: 1em; padding-top: 1em;
padding-left: 1.5em; padding-left: 1.5em;
padding-right: 1.5em;
cursor:pointer; cursor:pointer;
input, div, span, pre, textarea, select { input, div, span:not(.glyphicon), pre, textarea, select {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
} }
span { span {
font-weight: normal; font-weight: normal;
font-size: 0.9em; font-size: 0.9em;
@ -81,8 +83,8 @@
} }
div { div {
margin-top: 10px; /* margin-top: 10px; */
div { div:not(.file-drag-and-drop div) {
padding-left: 0; padding-left: 0;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-weight: normal; font-weight: normal;
@ -92,6 +94,10 @@
} }
} }
.progressbar-container, .progressbar-progress {
margin-top: 0 !important;
}
input, pre, textarea, select { input, pre, textarea, select {
font-weight: 400; font-weight: 400;
font-size: 1.1em; font-size: 1.1em;

View File

@ -1,13 +1,15 @@
.file-drag-and-drop { .file-drag-and-drop {
display: table-cell; display: block;
outline: 1px dashed #616161; outline: 1px dashed #616161;
cursor: pointer; cursor: pointer;
vertical-align: middle; vertical-align: middle;
text-align: center; text-align: center;
height:208px; height: auto;
width: 672px;
background-color: #FAFAFA; background-color: #FAFAFA;
transition: .1s linear background-color; overflow: auto;
margin-top: 1em;
padding: 3em;
} }
.inactive-dropzone { .inactive-dropzone {
@ -22,25 +24,34 @@
background-color: rgba(72, 218, 203, 0.2); background-color: rgba(72, 218, 203, 0.2);
} }
.file-drag-and-drop > span { .file-drag-and-drop .file-drag-and-drop-dialog {
font-size: 1.5em; font-size: 1.25em !important;
margin-top: 1em;
&:before {
content: ' ';
display: inline-block;
vertical-align: middle; /* vertical alignment of the inline element */
height: 100%;
}
} }
.has-files { .has-files {
text-align: left; text-align: left;
padding: 3em 0 0 0; padding: 4% 0 0 0;
} }
.file-drag-and-drop-position { .file-drag-and-drop-position {
display: inline-block; display: inline-block;
margin: 0 0 3em 3em; margin: 0 0 4% 4%;
float:left; float:left;
} }
.file-drag-and-drop-preview-table-wrapper { .file-drag-and-drop-preview-table-wrapper {
display: table; display: table;
height:94px; height:64px;
width:104px; width:74px;
} }
.file-drag-and-drop-preview { .file-drag-and-drop-preview {
@ -52,16 +63,16 @@
.file-drag-and-drop-preview-image { .file-drag-and-drop-preview-image {
display: table; display: table;
height:104px; height:74px;
width:104px; width:74px;
overflow:hidden; overflow:hidden;
border: 1px solid #616161; border: 1px solid #616161;
text-align: center; text-align: center;
} }
.file-drag-and-drop-preview-image .delete-file { .file-drag-and-drop-preview-image .delete-file {
font-size: 3em; font-size: 2.5em;
margin-top: .5em; margin-top: .3em;
color: white; color: white;
text-shadow: -2px 0 black, 0 2px black, 2px 0 black, 0 -2px black; text-shadow: -2px 0 black, 0 2px black, 2px 0 black, 0 -2px black;
cursor: pointer; cursor: pointer;
@ -73,9 +84,9 @@
.file-drag-and-drop-preview-other .delete-file { .file-drag-and-drop-preview-other .delete-file {
position: relative; position: relative;
top: .45em; top: .3em;
margin-top: 0; margin-top: 0;
font-size: 3em; font-size: 2.5em;
color: white; color: white;
text-shadow: -2px 0 black, 0 2px black, 2px 0 black, 0 -2px black; text-shadow: -2px 0 black, 0 2px black, 2px 0 black, 0 -2px black;
cursor: pointer; cursor: pointer;
@ -94,5 +105,5 @@
.file-drag-and-drop-preview-other span:not(:first-child) { .file-drag-and-drop-preview-other span:not(:first-child) {
display: block; display: block;
margin-top: 1.5em; margin-top: .5em;
} }