Task moving functionality working

pull/1031/head
Piero Toffanin 2021-08-04 16:20:51 -04:00
rodzic 9a70c07aca
commit 9bb8b1bed5
11 zmienionych plików z 74 dodań i 38 usunięć

Wyświetl plik

@ -310,9 +310,6 @@ class Task(models.Model):
self.move_assets(self.__original_project_id, self.project.id)
self.__original_project_id = self.project.id
# Autovalidate on save
self.full_clean()
super(Task, self).save(*args, **kwargs)
def assets_path(self, *args):

Wyświetl plik

@ -123,7 +123,7 @@ def build_plugins():
# Check for webpack.config.js (if we need to build it)
if plugin.path_exists("public/webpack.config.js"):
if settings.DEV and webpack_watch_process_count() <= 2:
if settings.DEV and webpack_watch_process_count() <= 2 and settings.DEV_WATCH_PLUGINS:
logger.info("Running webpack with watcher for {}".format(plugin.get_name()))
subprocess.Popen(['webpack-cli', '--watch'], cwd=plugin.get_path("public"))
elif not plugin.path_exists("public/build"):

Wyświetl plik

@ -95,6 +95,10 @@ class FormDialog extends React.Component {
hide(){
this.setState({showModal: false});
if (this.props.onHide) this.props.onHide();
if (this.serverRequest){
this.serverRequest.abort();
this.serverRequest = null;
}
}
handleSave(e){
@ -105,13 +109,20 @@ class FormDialog extends React.Component {
let formData = {};
if (this.props.getFormData) formData = this.props.getFormData();
this.props.saveAction(formData).fail(e => {
this.setState({error: e.message || (e.responseJSON || {}).detail || e.responseText || _("Could not apply changes")});
}).always(() => {
this.serverRequest = this.props.saveAction(formData);
if (this.serverRequest){
this.serverRequest.fail(e => {
this.setState({error: e.message || (e.responseJSON || {}).detail || e.responseText || _("Could not apply changes")});
}).always(() => {
this.setState({saving: false});
this.serverRequest = null;
}).done(() => {
this.hide();
});
}else{
this.setState({saving: false});
}).done(() => {
this.hide();
});
}
}
handleDelete(){

Wyświetl plik

@ -27,7 +27,7 @@ class MoveTaskDialog extends React.Component {
super(props);
this.state = {
projectId: props.task.project.id,
projectId: props.task.project,
projects: [],
loading: true
};
@ -37,7 +37,7 @@ class MoveTaskDialog extends React.Component {
}
getFormData(){
return this.state;
return {project: this.state.projectId};
}
onShow(){
@ -82,20 +82,22 @@ class MoveTaskDialog extends React.Component {
getFormData={this.getFormData}
onShow={this.onShow}
ref={(domNode) => { this.dialog = domNode; }}>
{!this.state.loading ?
<div className="form-group">
<label className="col-sm-2 control-label">{_("Project")}</label>
<div className="col-sm-10">
<select className="form-control"
value={this.state.projectId}
onChange={this.handleProjectChange}>
{this.state.projects.map(p =>
<option value={p.id} key={p.id}>{p.name}</option>
)}
</select>
<div style={{minHeight: '50px'}}>
{!this.state.loading ?
<div className="form-group">
<label className="col-sm-2 control-label">{_("Project")}</label>
<div className="col-sm-10">
<select className="form-control"
value={this.state.projectId}
onChange={this.handleProjectChange}>
{this.state.projects.map(p =>
<option value={p.id} key={p.id}>{p.name}</option>
)}
</select>
</div>
</div>
: <i className="fa fa-circle-notch fa-spin fa-fw name-loading"></i>}
</div>
: <i className="fa fa-circle-notch fa-spin fa-fw name-loading"></i>}
</FormDialog>
);
}

Wyświetl plik

@ -85,6 +85,12 @@ class ProjectList extends Paginated {
});
}
handleTaskMoved = (task) => {
if (this["projectListItem_" + task.project]){
this["projectListItem_" + task.project].newTaskAdded();
}
}
render() {
if (this.state.loading){
return (<div className="project-list text-center"><i className="fa fa-sync fa-spin fa-2x fa-fw"></i></div>);
@ -95,9 +101,11 @@ class ProjectList extends Paginated {
<ul className={"list-group project-list " + (this.state.refreshing ? "refreshing" : "")}>
{this.state.projects.map(p => (
<ProjectListItem
ref={(domNode) => { this["projectListItem_" + p.id] = domNode }}
key={p.id}
data={p}
onDelete={this.handleDelete}
onDelete={this.handleDelete}
onTaskMoved={this.handleTaskMoved}
history={this.props.history} />
))}
</ul>

Wyświetl plik

@ -20,7 +20,8 @@ class ProjectListItem extends React.Component {
static propTypes = {
history: PropTypes.object.isRequired,
data: PropTypes.object.isRequired, // project json
onDelete: PropTypes.func
onDelete: PropTypes.func,
onTaskMoved: PropTypes.func,
}
constructor(props){
@ -305,8 +306,9 @@ class ProjectListItem extends React.Component {
this.refresh();
}
taskMoved(){
this.refresh();
taskMoved(task){
this.refresh();
if (this.props.onTaskMoved) this.props.onTaskMoved(task);
}
handleDelete(){
@ -575,7 +577,7 @@ class ProjectListItem extends React.Component {
ref={this.setRef("taskList")}
source={`/api/projects/${data.id}/tasks/?ordering=-created_at`}
onDelete={this.taskDeleted}
onMove={this.taskMoved}
onTaskMoved={this.taskMoved}
hasPermission={this.hasPermission}
history={this.props.history}
/> : ""}

Wyświetl plik

@ -10,7 +10,7 @@ class TaskList extends React.Component {
history: PropTypes.object.isRequired,
source: PropTypes.string.isRequired, // URL where to load task list
onDelete: PropTypes.func,
onMove: PropTypes.func,
onTaskMoved: PropTypes.func,
hasPermission: PropTypes.func.isRequired
}
@ -71,11 +71,9 @@ class TaskList extends React.Component {
if (this.props.onDelete) this.props.onDelete(id);
}
moveTask(id){
this.setState({
tasks: this.state.tasks.filter(t => t.id !== id)
});
if (this.props.onMove) this.props.onMove(id);
moveTask = (task) => {
this.refresh();
if (this.props.onTaskMoved) this.props.onTaskMoved(task);
}
render() {
@ -85,7 +83,7 @@ class TaskList extends React.Component {
}else if (this.state.error){
message = (<span>{interpolate(_("Error: %(error)s"), {error: this.state.error})} <a href="javascript:void(0);" onClick={this.retry}>{_("Try again")}</a></span>);
}else if (this.state.tasks.length === 0){
message = (<span>{_("This project has no tasks. Create one by uploading some images!")}</span>);
message = (<span></span>);
}
return (

Wyświetl plik

@ -370,6 +370,18 @@ class TaskListItem extends React.Component {
};
}
moveTaskAction = (formData) => {
if (formData.project !== this.state.task.project){
return $.ajax({
url: `/api/projects/${this.state.task.project}/tasks/${this.state.task.id}/`,
contentType: 'application/json',
data: JSON.stringify(formData),
dataType: 'json',
type: 'PATCH'
}).done(this.props.onMove);
}else return false;
}
render() {
const task = this.state.task;
const name = task.name !== null ? task.name : interpolate(_("Task #%(number)s"), { number: task.id });
@ -626,10 +638,9 @@ class TaskListItem extends React.Component {
}
// Ability to change options
const canAddDelPerms = this.props.hasPermission("add") && this.props.hasPermission("delete");
const editable = [statusCodes.FAILED, statusCodes.COMPLETED, statusCodes.CANCELED].indexOf(task.status) !== -1;
if (canAddDelPerms){
if (this.props.hasPermission("change")){
if (editable || (!task.processing_node)){
taskActions.push(<li key="edit"><a href="javascript:void(0)" onClick={this.startEditing}><i className="glyphicon glyphicon-pencil"></i>{_("Edit")}</a></li>);
}
@ -661,7 +672,7 @@ class TaskListItem extends React.Component {
task={task}
ref={(domNode) => { this.moveTaskDialog = domNode; }}
onHide={() => this.setState({showMoveDialog: false})}
saveAction={() => {}}
saveAction={this.moveTaskAction}
/>
: ""}
<div className="row">

Wyświetl plik

@ -32,6 +32,7 @@ services:
- WO_DEBUG
- WO_BROKER
- WO_DEV
- WO_DEV_WATCH_PLUGINS
restart: unless-stopped
oom_score_adj: 0
broker:

Wyświetl plik

@ -82,6 +82,10 @@ case $key in
export WO_DEBUG=YES
shift # past argument
;;
--dev-watch-plugins)
export WO_DEV_WATCH_PLUGINS=YES
shift # past argument
;;
--dev)
export WO_DEBUG=YES
export WO_DEV=YES
@ -148,6 +152,7 @@ usage(){
echo " --ssl-insecure-port-redirect <port> Insecure port number to redirect from when SSL is enabled (default: $DEFAULT_SSL_INSECURE_PORT_REDIRECT)"
echo " --debug Enable debug for development environments (default: disabled)"
echo " --dev Enable development mode. In development mode you can make modifications to WebODM source files and changes will be reflected live. (default: disabled)"
echo " --dev-watch-plugins Automatically build plugins while in dev mode. (default: disabled)"
echo " --broker Set the URL used to connect to the celery broker (default: $DEFAULT_BROKER)"
echo " --detached Run WebODM in detached mode. This means WebODM will run in the background, without blocking the terminal (default: disabled)"
exit

Wyświetl plik

@ -52,6 +52,7 @@ WORKER_RUNNING = sys.argv[2:3] == ["worker"]
# SECURITY WARNING: don't run with debug turned on a public facing server!
DEBUG = os.environ.get('WO_DEBUG', 'YES') == 'YES' or TESTING
DEV = os.environ.get('WO_DEV', 'NO') == 'YES' and not TESTING
DEV_WATCH_PLUGINS = DEV and os.environ.get('WO_DEV_WATCH_PLUGINS', 'NO') == 'YES'
SESSION_COOKIE_SECURE = CSRF_COOKIE_SECURE = os.environ.get('WO_SSL', 'NO') == 'YES'
INTERNAL_IPS = ['127.0.0.1']