Handle task interaction like story interaction

When moving or adding tasks, instead of waiting for the user to
reselect the task reload the task each time.
This commit is contained in:
Tom Willemse 2013-07-13 21:09:40 +02:00
parent bdd07b68ca
commit 84ae7a5fd4
3 changed files with 54 additions and 15 deletions

View file

@ -46,11 +46,13 @@
(defmethod datastore-get-story ((datastore pg-datastore) id)
(with-connection (connection-spec datastore)
(append (query (:select :* :from 'story :where (:= 'id id)) :alist)
`((tasks . ,(query (:order-by
(:select :* :from 'task
:where (:= 'story-id id))
'priority)
:alists))))))
`((tasks . ,(datastore-get-tasks-for-story datastore id))))))
(defmethod datastore-get-tasks-for-story ((datastore pg-datastore) id)
(with-connection (connection-spec datastore)
(query (:order-by (:select :* :from 'task :where (:= 'story-id id))
'priority)
:alists)))
(defmethod datastore-post-story
((datastore pg-datastore) role necessity title content reporter)

View file

@ -105,12 +105,13 @@
(encode-json-to-string '((status . "ok"))))
403))
(define-route tasks-new ("stories/tasks/new" :method :post)
(define-route tasks-new ("stories/tasks/new" :method :post
:content-type "text/json")
(if (logged-in-p)
(with-post-parameters ("storyId" "description")
(post-task storyid description
(hunchentoot:session-value :username))
200)
(encode-json-to-string '((status . "ok"))))
403))
(define-route stories-state ("stories/state" :method :post
@ -148,12 +149,13 @@
(encode-json-to-string '((status . "ok"))))
403))
(define-route task-priority ("tasks/:dir" :method :post)
(define-route task-priority ("tasks/:dir" :method :post
:content-type "text/json")
(if (logged-in-p)
(let* ((id (hunchentoot:post-parameter "id")))
(story-change-priority
'task id (intern (string-upcase dir) :keyword))
200)
(encode-json-to-string '((status . "ok"))))
403))
(define-route login-page ("login")
@ -217,3 +219,9 @@
(if (logged-in-p)
(encode-json-to-string (get-story id))
403))
(define-route scrumli-story-tasks ("stories/:id/tasks"
:content-type "json")
(if (logged-in-p)
(encode-json-to-string (get-tasks-for-story id))
403))

View file

@ -20,10 +20,18 @@ var StoryTaskRow = React.createClass({
return {state: this.props.task.state};
},
moveUp: React.autoBind(function(event) {
$.post("/tasks/up", {'id': this.props.task.id});
$.post("/tasks/up", {'id': this.props.task.id})
.done(function (data) {
if (data.status == "ok")
this.props.onMoved(1);
}.bind(this));
}),
moveDown: React.autoBind(function(event) {
$.post("/tasks/down", {'id': this.props.task.id});
$.post("/tasks/down", {'id': this.props.task.id})
.done(function (data) {
if (data.status == "ok")
this.props.onMoved(-1);
}.bind(this));
}),
render: function() {
return (
@ -50,7 +58,8 @@ var StoryTaskRow = React.createClass({
var StoryTaskTable = React.createClass({
render: function() {
var taskNodes = this.props.tasks.map(function (task) {
return <StoryTaskRow task={task} />;
return <StoryTaskRow task={task}
onMoved={this.props.onTaskMoved} />;
}.bind(this));
return (
@ -91,14 +100,32 @@ var StoryTaskForm = React.createClass({
var StoryData = React.createClass({
handleTaskSubmit: React.autoBind(function (task) {
task.storyId = this.state.data.id;
$.post("/stories/tasks/new", task);
$.post("/stories/tasks/new", task)
.done(function(data) {
if (data.status == "ok")
this.loadStoryFromServer();
}.bind(this));
}),
loadStoryFromServer: function() {
$.get("/stories/" + this.state.data.id)
.done(this.setData.bind(this));
},
componentWillMount: function() {
setInterval(
this.loadStoryFromServer.bind(this),
this.props.pollInterval
);
},
getInitialState: function() {
return {data: null};
},
setData: function(data) {
this.setState({data: null});
this.setState({data: data});
},
handleTaskMoved: React.autoBind(function(direction) {
this.loadStoryFromServer();
}),
render: function() {
if (this.state.data) {
return (<div>
@ -107,7 +134,8 @@ var StoryData = React.createClass({
<div class="well">
{this.state.data.content}
</div>
<StoryTaskTable tasks={this.state.data.tasks || []} />
<StoryTaskTable tasks={this.state.data.tasks || []}
onTaskMoved={this.handleTaskMoved} />
<StoryTaskForm onTaskSubmit={this.handleTaskSubmit} />
</div>);
}
@ -283,7 +311,8 @@ var StoryPage = React.createClass({
<StoryForm onStorySubmit={this.handleStorySubmit} />
</div>
<div class="span6">
<StoryData ref="data" />
<StoryData ref="data"
pollInterval={this.props.pollInterval} />
</div>
</div>
);