kopia lustrzana https://github.com/OpenDroneMap/WebODM
Task edit panel, upload improvements
rodzic
58a7f9ea4c
commit
6036e613f6
|
@ -24,7 +24,7 @@ class TaskViewSet(viewsets.ViewSet):
|
|||
Once a processing node completes processing, results are stored in the task.
|
||||
"""
|
||||
queryset = models.Task.objects.all()
|
||||
|
||||
|
||||
# We don't use object level permissions on tasks, relying on
|
||||
# project's object permissions instead (but standard model permissions still apply)
|
||||
permission_classes = (permissions.DjangoModelPermissions, )
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
import '../css/EditTaskPanel.scss';
|
||||
import React from 'react';
|
||||
|
||||
class EditTaskPanel extends React.Component {
|
||||
constructor(){
|
||||
super();
|
||||
|
||||
this.namePlaceholder = "Task of " + (new Date()).toISOString();
|
||||
|
||||
this.state = {
|
||||
name: "",
|
||||
advancedOptions: false
|
||||
};
|
||||
|
||||
this.handleNameChange = this.handleNameChange.bind(this);
|
||||
this.setAdvancedOptions = this.setAdvancedOptions.bind(this);
|
||||
this.save = this.save.bind(this);
|
||||
}
|
||||
|
||||
handleNameChange(e){
|
||||
this.setState({name: e.target.value});
|
||||
}
|
||||
|
||||
setAdvancedOptions(flag){
|
||||
return () => {
|
||||
this.setState({advancedOptions: flag});
|
||||
};
|
||||
}
|
||||
|
||||
save(){
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="edit-task-panel">
|
||||
<form className="form-horizontal">
|
||||
<p>Your images are being uploaded. In the meanwhile, set these additional options:</p>
|
||||
<div className="form-group">
|
||||
<label className="col-sm-2 control-label">Name</label>
|
||||
<div className="col-sm-10">
|
||||
<input type="text" onChange={this.handleNameChange} className="form-control" placeholder={this.namePlaceholder} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="col-sm-2 control-label">Processing Node</label>
|
||||
<div className="col-sm-10">
|
||||
<select className="form-control">
|
||||
<option>Auto</option>
|
||||
<option>1</option>
|
||||
<option>2</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="col-sm-2 control-label">Options</label>
|
||||
<div className="col-sm-10">
|
||||
<div className="btn-group" role="group">
|
||||
<button type="button" className={"btn " + (!this.state.advancedOptions ? "btn-default" : "btn-secondary")} onClick={this.setAdvancedOptions(false)}>Default</button>
|
||||
<button type="button" className={"btn " + (this.state.advancedOptions ? "btn-default" : "btn-secondary")} onClick={this.setAdvancedOptions(true)}>Advanced</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<div className="col-sm-offset-2 col-sm-10 text-right">
|
||||
<button type="submit" className="btn btn-default" onClick={this.save}>Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default EditTaskPanel;
|
|
@ -2,6 +2,7 @@ import '../css/ProjectListItem.scss';
|
|||
import React from 'react';
|
||||
import update from 'react-addons-update';
|
||||
import ProjectListItemPanel from './ProjectListItemPanel';
|
||||
import EditTaskPanel from './EditTaskPanel';
|
||||
import UploadProgressBar from './UploadProgressBar';
|
||||
import Dropzone from '../vendor/dropzone';
|
||||
import csrf from '../django/csrf';
|
||||
|
@ -13,16 +14,21 @@ class ProjectListItem extends React.Component {
|
|||
|
||||
this.state = {
|
||||
showPanel: false,
|
||||
upload: this.getDefaultUploadState()
|
||||
upload: this.getDefaultUploadState(),
|
||||
taskId: null
|
||||
};
|
||||
|
||||
this.togglePanel = this.togglePanel.bind(this);
|
||||
this.handleUpload = this.handleUpload.bind(this);
|
||||
this.closeUploadError = this.closeUploadError.bind(this);
|
||||
this.cancelUpload = this.cancelUpload.bind(this);
|
||||
}
|
||||
|
||||
getDefaultUploadState(){
|
||||
return {
|
||||
uploading: false,
|
||||
showEditTask: false,
|
||||
error: "",
|
||||
progress: 0,
|
||||
totalCount: 0,
|
||||
totalBytes: 0,
|
||||
|
@ -45,7 +51,7 @@ class ProjectListItem extends React.Component {
|
|||
componentDidMount(){
|
||||
Dropzone.autoDiscover = false;
|
||||
|
||||
let dz = new Dropzone(this.dropzone, {
|
||||
this.dz = new Dropzone(this.dropzone, {
|
||||
paramName: "images",
|
||||
url : `/api/projects/${this.props.data.id}/tasks/`,
|
||||
parallelUploads: 9999999,
|
||||
|
@ -60,7 +66,7 @@ class ProjectListItem extends React.Component {
|
|||
}
|
||||
});
|
||||
|
||||
dz.on("totaluploadprogress", (progress, totalBytes, totalBytesSent) => {
|
||||
this.dz.on("totaluploadprogress", (progress, totalBytes, totalBytesSent) => {
|
||||
this.setUploadState({
|
||||
progress, totalBytes, totalBytesSent
|
||||
});
|
||||
|
@ -72,13 +78,22 @@ class ProjectListItem extends React.Component {
|
|||
})
|
||||
.on("processingmultiple", () => {
|
||||
this.setUploadState({
|
||||
uploading: true
|
||||
uploading: true,
|
||||
showEditTask: true
|
||||
})
|
||||
})
|
||||
.on("completemultiple", () => {
|
||||
this.setUploadState({
|
||||
uploading: false
|
||||
})
|
||||
.on("completemultiple", (files) => {
|
||||
// Check
|
||||
let success = files.filter(file => file.status !== "success").length === 0;
|
||||
|
||||
if (success){
|
||||
this.setUploadState({uploading: false});
|
||||
}else{
|
||||
this.setUploadState({
|
||||
uploading: false,
|
||||
error: "Could not upload all files. An error occured."
|
||||
});
|
||||
}
|
||||
})
|
||||
.on("reset", () => {
|
||||
this.resetUploadState();
|
||||
|
@ -97,46 +112,76 @@ class ProjectListItem extends React.Component {
|
|||
});
|
||||
}
|
||||
|
||||
closeUploadError(){
|
||||
this.setUploadState({error: ""});
|
||||
}
|
||||
|
||||
cancelUpload(e){
|
||||
this.dz.removeAllFiles(true);
|
||||
}
|
||||
|
||||
handleUpload(){
|
||||
this.resetUploadState();
|
||||
}
|
||||
|
||||
render() {
|
||||
// TODO: Task Options Component
|
||||
|
||||
return (
|
||||
<li className="project-list-item list-group-item"
|
||||
href="javascript:void(0);">
|
||||
<div className="row no-margin">
|
||||
<div className="btn-group pull-right">
|
||||
<button type="button" className="btn btn-primary btn-sm" onClick={this.handleUpload} ref={this.setRef("uploadButton")}>
|
||||
<i className="glyphicon glyphicon-upload"></i>
|
||||
Upload Images
|
||||
</button>
|
||||
<button type="button" className="btn btn-default btn-sm">
|
||||
<i className="fa fa-globe"></i> Map View
|
||||
</button>
|
||||
<button type="button" className="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown">
|
||||
<span className="caret"></span>
|
||||
</button>
|
||||
<ul className="dropdown-menu">
|
||||
<li><a href="javascript:alert('TODO!');"><i className="fa fa-cube"></i> 3D View</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="row no-margin">
|
||||
<div className="btn-group pull-right">
|
||||
<button type="button"
|
||||
className={"btn btn-primary btn-sm " + (this.state.upload.uploading ? "hide" : "")}
|
||||
onClick={this.handleUpload}
|
||||
ref={this.setRef("uploadButton")}>
|
||||
<i className="glyphicon glyphicon-upload"></i>
|
||||
Upload Images
|
||||
</button>
|
||||
|
||||
<button disabled={this.state.upload.error !== ""}
|
||||
type="button"
|
||||
className={"btn btn-primary btn-sm " + (!this.state.upload.uploading ? "hide" : "")}
|
||||
onClick={this.cancelUpload}>
|
||||
<i className="glyphicon glyphicon-remove-circle"></i>
|
||||
Cancel Upload
|
||||
</button>
|
||||
|
||||
<i style={{width: 14}} className={'fa ' + (this.state.showPanel ? 'fa-caret-down' : 'fa-caret-right')}>
|
||||
</i> <a href="javascript:void(0);" onClick={this.togglePanel}>
|
||||
{this.props.data.name}
|
||||
</a>
|
||||
<button type="button" className="btn btn-default btn-sm">
|
||||
<i className="fa fa-globe"></i> Map View
|
||||
</button>
|
||||
<button type="button" className="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown">
|
||||
<span className="caret"></span>
|
||||
</button>
|
||||
<ul className="dropdown-menu">
|
||||
<li><a href="javascript:alert('TODO!');"><i className="fa fa-cube"></i> 3D View</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="dropzone" ref={this.setRef("dropzone")}>
|
||||
<div className="dz-default dz-message text-center">
|
||||
</div>
|
||||
<i style={{width: 14}} className={'fa ' + (this.state.showPanel ? 'fa-caret-down' : 'fa-caret-right')}>
|
||||
</i> <a href="javascript:void(0);" onClick={this.togglePanel}>
|
||||
{this.props.data.name}
|
||||
</a>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="dropzone" ref={this.setRef("dropzone")}>
|
||||
<div className="dz-default dz-message text-center">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{this.state.upload.uploading ? <UploadProgressBar {...this.state.upload}/> : ""}
|
||||
{this.state.upload.uploading ? <UploadProgressBar {...this.state.upload}/> : ""}
|
||||
|
||||
{this.state.upload.error !== "" ?
|
||||
<div className="alert alert-warning alert-dismissible">
|
||||
<button type="button" className="close" aria-label="Close" onClick={this.closeUploadError}><span aria-hidden="true">×</span></button>
|
||||
{this.state.upload.error}
|
||||
</div>
|
||||
: ""}
|
||||
|
||||
{this.state.showPanel ? <ProjectListItemPanel /> : ""}
|
||||
<EditTaskPanel className={!this.state.upload.showEditTask ? "hide" : ""} />
|
||||
|
||||
{this.state.showPanel ? <ProjectListItemPanel /> : ""}
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
min-height: 100px;
|
||||
}
|
||||
|
||||
.row.no-margin{
|
||||
margin: 0;
|
||||
.row{
|
||||
&.no-margin{
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.progress{
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
.edit-task-panel{
|
||||
background-color: #ecf0f1;
|
||||
padding: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
|
@ -4,4 +4,10 @@
|
|||
.dz-preview{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.row{
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue