Merge pull request #22 from Popsch/implement_review_view

Implement review view
This commit is contained in:
Reinier Balt 2011-09-27 06:33:18 -07:00
commit d6390f28cf
19 changed files with 149 additions and 21 deletions

View file

@ -17,16 +17,11 @@ gem "rubycas-client", "~>2.2.1"
gem "ruby-openid", :require => "openid"
gem "sqlite3"
gem 'bcrypt-ruby', '~> 2.1.4'
gem 'htmlentities', '~> 4.3.0'
gem "webrat", ">=0.7.0", :groups => [:cucumber, :test]
gem "database_cleaner", ">=0.5.0", :groups => [:cucumber, :selenium]
gem "cucumber-rails", "~>0.3.0", :groups => :cucumber
group :development do
gem "ruby-debug"
end
group :test do
gem "flexmock"
gem "ZenTest", ">=4.0.0"

View file

@ -27,7 +27,6 @@ GEM
bcrypt-ruby (2.1.4)
builder (3.0.0)
cgi_multipart_eof_fix (2.5.0)
columnize (0.3.4)
cucumber (1.0.2)
builder (>= 2.1.2)
diff-lcs (>= 1.1.2)
@ -50,11 +49,8 @@ GEM
hoe (2.12.0)
rake (~> 0.8)
hpricot (0.8.4)
htmlentities (4.3.0)
httpclient (2.2.1)
json (1.5.3)
linecache (0.46)
rbx-require-relative (> 0.0.4)
memory_test_fix (0.1.3)
mongrel (1.1.5)
cgi_multipart_eof_fix (>= 2.4)
@ -73,16 +69,10 @@ GEM
activesupport (= 2.3.14)
rake (>= 0.8.3)
rake (0.8.7)
rbx-require-relative (0.0.5)
rspec (1.3.2)
rspec-rails (1.3.4)
rack (>= 1.0.0)
rspec (~> 1.3.1)
ruby-debug (0.10.4)
columnize (>= 0.1)
ruby-debug-base (~> 0.10.4.0)
ruby-debug-base (0.10.4)
linecache (>= 0.3)
ruby-openid (2.1.8)
rubycas-client (2.2.1)
activesupport
@ -117,14 +107,12 @@ DEPENDENCIES
highline (~> 1.5.0)
hoe
hpricot
htmlentities (~> 4.3.0)
memory_test_fix (~> 0.1.3)
mongrel
rack (= 1.1.0)
rails (~> 2.3.12)
rake (~> 0.8.7)
rspec-rails (~> 1.3.3)
ruby-debug
ruby-openid
rubycas-client (~> 2.2.1)
sanitize (~> 1.2.1)

View file

@ -33,6 +33,37 @@ class ProjectsController < ApplicationController
end
end
def review
## select project that need reviewing
@projects_to_review = current_user.projects.select {|p| p.needs_review?(current_user)}
## select project that are stalled
@stalled_projects = current_user.projects.select {|p| p.stalled?}
## select project that are stalled
@blocked_projects = current_user.projects.select {|p| p.blocked?}
@contexts = current_user.contexts.all
init_not_done_counts(['project'])
init_project_hidden_todo_counts(['project'])
if params[:only_active_with_no_next_actions]
@projects = current_user.projects.active.select { |p| count_undone_todos(p) == 0 }
else
@projects = current_user.projects.all
end
@page_title = t('projects.list_reviews')
@count = @projects_to_review.count + @blocked_projects.count + @stalled_projects.count
@no_projects = current_user.projects.empty?
current_user.projects.cache_note_counts
@new_project = current_user.projects.build
render
end
def done
@source_view = params['_source_view'] || 'project_list'
@page_title = t('projects.list_completed_projects')
@ -51,6 +82,13 @@ class ProjectsController < ApplicationController
render
end
def set_reviewed
@project = current_user.projects.find(params[:id])
@project.last_reviewed = Time.now
@project.save
redirect_to :action => 'show'
end
def projects_and_actions
@projects = current_user.projects.active
respond_to do |format|

View file

@ -67,4 +67,14 @@ module ProjectsHelper
project_description
end
def needsreview_class(item)
raise "item must be a Project " unless item.kind_of? Project
if item.needs_review?(current_user)
return "needsreview"
else
return "needsnoreview"
end
end
end

View file

@ -107,6 +107,34 @@ class Project < ActiveRecord::Base
end
end
def needs_review?(current_user)
return false unless !nil?
return true if last_reviewed.nil?
return (active? && (last_reviewed < current_user.time - current_user.prefs.review_period.days))
end
def blocked?
## mutually exclusive for stalled and blocked
return false if stalled?
return false if completed?
is_blocked = true
todos.each do |t|
is_blocked = false if (!t.completed? && !t.deferred? && !t.pending?)
end
return is_blocked
end
def stalled?
return true if todos.count == 0
return false if completed?
is_stalled = true
todos.each do |t|
is_stalled = false if (!t.completed?)
end
return is_stalled
end
def name=(value)
self[:name] = value.gsub(/\s{2,}/, " ").strip
end

View file

@ -64,6 +64,7 @@
<ul>
<li><%= navigation_link( t('common.contexts'), contexts_path, {:accesskey=>"c", :title=>t('layouts.navigation.contexts_title')} ) %></li>
<li><%= navigation_link( t('common.notes'), notes_path, {:accesskey => "o", :title => t('layouts.navigation.notes_title')} ) %></li>
<li><%= navigation_link( t('common.review'), review_path, {:accesskey => "r", :title => t('layouts.navigation.review_title')} ) %></li>
<li><%= navigation_link( t('layouts.navigation.recurring_todos'), {:controller => "recurring_todos", :action => "index"}, :title => t('layouts.navigation.recurring_todos_title')) %></li>
</ul>
</li>

View file

@ -5,6 +5,7 @@
<%= pref_with_select_field('prefs', "show_hidden_contexts_in_sidebar") %>
<%= pref_with_select_field('prefs', "show_project_on_todo_done") %>
<%= pref_with_text_field('prefs', 'staleness_starts') %>
<%= pref_with_text_field('prefs', 'review_period') %>
<%= pref_with_text_field('prefs', 'show_number_completed') %>
<%= pref_with_text_field('prefs', 'refresh') %>
<%= pref_with_select_field('prefs', "verbose_action_descriptors") %>

View file

@ -0,0 +1,6 @@
<%= hidden_field( "project", "id" ) %>
MUUUUUAAHAHAHAHAH!!!!
<label for="project_name">Project name</label><br />
<%= text_field( "project", "name" ) %>
<br />
<br />

View file

@ -40,6 +40,10 @@ project = project_form
<%=image_tag("cancel.png", :alt => "") %>
Cancel
</a>
<a href="<%=project.id.to_s+"/set_reviewed"%>" id="<%= dom_id(project, 'reviewed') %>" class="reviewed">
<%=image_tag("reviewed.png", :alt => "") %>
Reviewed
</a>
</div>
</div>
<br/><br/>

View file

@ -12,8 +12,12 @@ suppress_edit_button ||= false
</div>
<% end -%>
<div class="data">
<%= link_to_project( project ) %><%= " (" + count_undone_todos_and_notes_phrase(project,"actions") + ")" %>
<span class="<%= needsreview_class( project ) %>">
<%= link_to_project( project ) %>
<%= " (" + count_undone_todos_and_notes_phrase(project,"actions") + ")" %>
</span>
</div>
<div class="buttons">

View file

@ -5,7 +5,11 @@
<div class="project-state-group" id="list-<%= state %>-projects-container" <%= " style=\"display:none\"" if project_state_group.empty? %>>
<h2>
<span id="<%= state %>-projects-count" class="badge"><%= project_state_group.length%><%= total_count_string%></span>
<%= t('common.last' )%> <%= t('states.'+state+'_plural' )%> <%= t('common.projects') %><%= total_count==-1 ? "" : " ("+link_to("Show all", done_projects_path)+")"%>
<%= t('common.last' ) unless (state == 'review' || state == 'stalled' || state == 'blocked')%>
<%= t('states.'+state+'_plural' )%>
<%= t('common.projects') %><%= total_count==-1 ? "" : " ("+link_to("Show all", done_projects_path)+")"%>
</h2>
<div class="menu_sort"><span class="sort_separator"><%= t('common.sort.sort') %>&nbsp;</span>
<div class="alpha_sort">
@ -18,6 +22,6 @@
</div>
<div id="list-<%= state %>-projects" class="project-list">
<%= render :partial => 'project_listing', :collection => project_state_group %>
<%= render :partial => 'projects/project_listing', :collection => project_state_group %>
</div>
</div>

View file

@ -0,0 +1,6 @@
<div id="projects-empty-nd" style="<%= @no_projects ? 'display:block' : 'display:none'%>">
<div class="message"><p><%= t('projects.no_projects') %></p></div>
</div>
<%= render :partial => 'project_state_group', :object => @projects_to_review, :locals => { :state => 'review'} %>
<%= render :partial => 'project_state_group', :object => @stalled_projects, :locals => { :state => 'stalled'} %>
<%= render :partial => 'project_state_group', :object => @blocked_projects, :locals => { :state => 'blocked'} %>

View file

@ -22,6 +22,7 @@ en:
feeds: Feeds
starred: Starred
notes_title: Show all notes
review_title: Make review
stats: Statistics
tickler_title: Tickler
manage_users: Manage users
@ -102,6 +103,7 @@ en:
server_error: An error occurred on the server.
forum: Forum
notes: Notes
review: Review
last: Last
projects: Projects
action: Action
@ -579,6 +581,12 @@ en:
active_plural: Active
hidden: Hidden
active: Active
review_plural: Dated
review: Dated
stalled_plural: Stalled
stalled: Stalled
blocked_plural: Blocked
blocked: Blocked
projects:
was_marked_hidden: has been marked as hidden
edit_project_title: Edit project
@ -616,6 +624,7 @@ en:
completed_projects: Completed projects
with_default_tags: and with '%{tags}' as the default tags
list_projects: TRACKS::List Projects
list_reviews: TRACKS::Review
project_saved_status: Project saved
add_project: Add Project
add_note: Add a note

View file

@ -13,10 +13,15 @@ ActionController::Routing::Routes.draw do |map|
end
map.resources :projects, :collection => {:order => :post, :alphabetize => :post, :actionize => :post, :done => :get},
:member => {:done_todos => :get, :all_done_todos => :get} do |projects|
:member => {:done_todos => :get, :all_done_todos => :get, :set_reviewed => :get} do |projects|
projects.resources :todos, :name_prefix => "project_"
end
map.with_options :controller => :projects do |projects|
# projects.home '', :action => "index"
projects.review 'review', :action => :review
end
map.resources :notes
map.resources :todos,
@ -24,6 +29,7 @@ ActionController::Routing::Routes.draw do |map|
:collection => {:check_deferred => :post, :filter_to_context => :post, :filter_to_project => :post, :done => :get, :all_done => :get
}
map.with_options :controller => :todos do |todos|
todos.home '', :action => "index"
todos.tickler 'tickler.:format', :action => "list_deferred"

View file

@ -0,0 +1,9 @@
class AddLastReviewedToProject < ActiveRecord::Migration
def self.up
add_column :projects, :last_reviewed, :timestamp
execute 'update projects set last_reviewed = created_at where last_reviewed IS NULL'
end
def self.down
remove_column :projects, :last_reviewed
end
end

View file

@ -0,0 +1,8 @@
class AddNextReviewPreferences < ActiveRecord::Migration
def self.up
add_column :preferences, :review_period, :integer, :default => 14, :null => false
end
def self.down
remove_column :preferences, :review_period
end
end

View file

@ -61,6 +61,9 @@ module NavigationHelpers
notes_path(options)
when /the calendar page/
calendar_path(options)
when /the review page/
@source_view = "review"
review_path(options)
when /the contexts page/
@source_view = "contexts"
contexts_path(options)

BIN
public/images/reviewed.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 B

View file

@ -1,3 +1,11 @@
.needsreview {
background: #ffC;
}
.widgets a.reviewed, button.reviewed {
float:right;
}
div.depends_on label {
float: left;
}