Add user filter
Users can now either look at the whole list or only tasks assigned to them. Currently this waits for the refresh to change the list, this should be fixed in the future.
This commit is contained in:
parent
f897aa6287
commit
9aed878305
5 changed files with 51 additions and 3 deletions
|
@ -25,6 +25,9 @@
|
||||||
(define-method get-all-stories ()
|
(define-method get-all-stories ()
|
||||||
"Get all of the stories in the datastore.")
|
"Get all of the stories in the datastore.")
|
||||||
|
|
||||||
|
(define-method get-stories-for (username)
|
||||||
|
"Get all of the storiess for USERNAME.")
|
||||||
|
|
||||||
(define-method get-story (id)
|
(define-method get-story (id)
|
||||||
"Get a story from the datastore.")
|
"Get a story from the datastore.")
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,13 @@
|
||||||
(query (:order-by (:select :* (:as (:md5 'assignee) 'md5)
|
(query (:order-by (:select :* (:as (:md5 'assignee) 'md5)
|
||||||
:from 'story) 'priority) :alists)))
|
:from 'story) 'priority) :alists)))
|
||||||
|
|
||||||
|
(defmethod datastore-get-stories-for ((datastore pg-datastore) username)
|
||||||
|
(with-connection (connection-spec datastore)
|
||||||
|
(query (:order-by (:select :* (:as (:md5 'assignee) 'md5)
|
||||||
|
:from 'story
|
||||||
|
:where (:= 'assignee username))
|
||||||
|
'priority) :alists)))
|
||||||
|
|
||||||
(defmethod datastore-get-story ((datastore pg-datastore) id)
|
(defmethod datastore-get-story ((datastore pg-datastore) id)
|
||||||
(with-connection (connection-spec datastore)
|
(with-connection (connection-spec datastore)
|
||||||
(append (query (:select :* (:as (:md5 'assignee) 'md5) :from 'story
|
(append (query (:select :* (:as (:md5 'assignee) 'md5) :from 'story
|
||||||
|
|
|
@ -102,6 +102,12 @@
|
||||||
(encode-json-to-string (get-all-stories))
|
(encode-json-to-string (get-all-stories))
|
||||||
403))
|
403))
|
||||||
|
|
||||||
|
(define-route my-stories-json ("stories/mine" :content-type "text/json")
|
||||||
|
(if (logged-in-p)
|
||||||
|
(encode-json-to-string (get-stories-for
|
||||||
|
(hunchentoot:session-value :username)))
|
||||||
|
403))
|
||||||
|
|
||||||
(defmacro with-post-parameters (parameters &body body)
|
(defmacro with-post-parameters (parameters &body body)
|
||||||
`(let ,(mapcar (lambda (p)
|
`(let ,(mapcar (lambda (p)
|
||||||
(list (intern (string-upcase p))
|
(list (intern (string-upcase p))
|
||||||
|
|
|
@ -393,15 +393,18 @@ var StoryForm = React.createClass({
|
||||||
|
|
||||||
var StoryPage = React.createClass({
|
var StoryPage = React.createClass({
|
||||||
loadStoriesFromServer: function() {
|
loadStoriesFromServer: function() {
|
||||||
$.get(this.props.url)
|
$.get(this.state.url)
|
||||||
.done(function(data) {
|
.done(function(data) {
|
||||||
this.setState({data: []});
|
this.setState({data: []});
|
||||||
this.setState({data: data});
|
this.setState({data: data});
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {data: []};
|
return {data: [], url: this.props.url};
|
||||||
},
|
},
|
||||||
|
setUrl: React.autoBind(function(url) {
|
||||||
|
this.setState({url: url});
|
||||||
|
}),
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
this.loadStoriesFromServer();
|
this.loadStoriesFromServer();
|
||||||
setInterval(
|
setInterval(
|
||||||
|
@ -456,7 +459,35 @@ var StoryPage = React.createClass({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var StoryFilter = React.createClass({
|
||||||
|
getInitialState: function() {
|
||||||
|
return {filter: 'all'};
|
||||||
|
},
|
||||||
|
handleClick: React.autoBind(function(event) {
|
||||||
|
this.setState({filter: (this.state.filter != 'all'
|
||||||
|
? 'all' : 'user')});
|
||||||
|
scrumli_page.setUrl((this.state.filter == "all"
|
||||||
|
? "/stories" : "/stories/mine"));
|
||||||
|
}),
|
||||||
|
render: function() {
|
||||||
|
var classes = {all: ['icon-group', 'All'],
|
||||||
|
user: ['icon-user', 'Mine']};
|
||||||
|
|
||||||
|
return (<a onClick={this.handleClick}>
|
||||||
|
<i class={classes[this.state.filter][0] + ' icon-light'}></i>
|
||||||
|
{" "} {classes[this.state.filter][1]}
|
||||||
|
</a>);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var scrumli_page = <StoryPage url="/stories" pollInterval={5000} />;
|
||||||
|
|
||||||
React.renderComponent(
|
React.renderComponent(
|
||||||
<StoryPage url="/stories" pollInterval={5000} />,
|
scrumli_page,
|
||||||
document.getElementById('content')
|
document.getElementById('content')
|
||||||
);
|
);
|
||||||
|
|
||||||
|
React.renderComponent(
|
||||||
|
<StoryFilter />,
|
||||||
|
document.getElementById('filter')
|
||||||
|
);
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
<li class="divider-vertical"></li>
|
<li class="divider-vertical"></li>
|
||||||
|
<li id="filter"></li>
|
||||||
<li><a href="{$ulogout}">Logout</a></li>
|
<li><a href="{$ulogout}">Logout</a></li>
|
||||||
<li class="divider-vertical"></li>
|
<li class="divider-vertical"></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
Loading…
Reference in a new issue