From 85885f9b9b686c73fa31fdd50885091e24dbb7f2 Mon Sep 17 00:00:00 2001 From: lukemelia Date: Tue, 6 Mar 2007 13:18:31 +0000 Subject: [PATCH] Add next-previous links to project detail pages. Closes #379 git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@470 a4c988fc-2ded-0310-b66e-134b36920a42 --- tracks/app/controllers/projects_controller.rb | 2 ++ tracks/app/helpers/projects_helper.rb | 14 ++++++++++ tracks/app/models/user.rb | 15 +++++++++++ tracks/app/views/projects/show.rhtml | 3 +++ tracks/public/stylesheets/standard.css | 3 +++ .../functional/projects_controller_test.rb | 19 ++++++++++++-- tracks/test/unit/user_test.rb | 26 ++++++++++++++++++- 7 files changed, 79 insertions(+), 3 deletions(-) diff --git a/tracks/app/controllers/projects_controller.rb b/tracks/app/controllers/projects_controller.rb index 9aa7de1b..3a1372df 100644 --- a/tracks/app/controllers/projects_controller.rb +++ b/tracks/app/controllers/projects_controller.rb @@ -26,6 +26,8 @@ class ProjectsController < ApplicationController @deferred = @project.deferred_todos @done = @project.done_todos @count = @not_done.size + @next_project = @user.projects.next_from(@project) + @previous_project = @user.projects.previous_from(@project) end # Example XML usage: curl -H 'Accept: application/xml' -H 'Content-Type: application/xml' diff --git a/tracks/app/helpers/projects_helper.rb b/tracks/app/helpers/projects_helper.rb index e0d7f482..3c844f04 100644 --- a/tracks/app/helpers/projects_helper.rb +++ b/tracks/app/helpers/projects_helper.rb @@ -9,4 +9,18 @@ module ProjectsHelper } end + def project_next_prev + html = '' + unless @previous_project.nil? + project_name = truncate(@previous_project.name, 40, "...") + html << link_to_project(@previous_project, "« #{project_name}") + end + html << '|' if @previous_project && @next_project + unless @next_project.nil? + project_name = truncate(@next_project.name, 40, "...") + html << link_to_project(@next_project, "#{project_name} »") + end + html + end + end diff --git a/tracks/app/models/user.rb b/tracks/app/models/user.rb index d884308f..b944351b 100644 --- a/tracks/app/models/user.rb +++ b/tracks/app/models/user.rb @@ -37,6 +37,21 @@ class User < ActiveRecord::Base project.update_attribute(:position, position + 1) end end + def projects_in_state_by_position(state) + self.sort{ |a,b| a.position <=> b.position }.select{ |p| p.state == state } + end + def next_from(project) + self.offset_from(project, 1) + end + def previous_from(project) + self.offset_from(project, -1) + end + def offset_from(project, offset) + projects = self.projects_in_state_by_position(project.state) + position = projects.index(project) + return nil if position == 0 && offset < 0 + projects.at( position + offset) + end end has_many :todos, :order => 'completed_at DESC, todos.created_at DESC', diff --git a/tracks/app/views/projects/show.rhtml b/tracks/app/views/projects/show.rhtml index afef1406..a66602c6 100644 --- a/tracks/app/views/projects/show.rhtml +++ b/tracks/app/views/projects/show.rhtml @@ -1,4 +1,7 @@
+
+ <%= project_next_prev %> +
<%= render :partial => "projects/project", :locals => { :project => @project, :collapsible => false } %> <%= render :partial => "todos/deferred", :locals => { :deferred => @deferred, :collapsible => false, :append_descriptor => "in this project" } %> diff --git a/tracks/public/stylesheets/standard.css b/tracks/public/stylesheets/standard.css index 8567ca3e..86c3e3ab 100644 --- a/tracks/public/stylesheets/standard.css +++ b/tracks/public/stylesheets/standard.css @@ -548,6 +548,9 @@ div.project_description { shadowed text */ /* text-shadow: rgba(0,0,0,.4) 0px 2px 5px; */ } +#project-next-prev { + text-align:right; +} /* Form elements */ form { diff --git a/tracks/test/functional/projects_controller_test.rb b/tracks/test/functional/projects_controller_test.rb index bfe17a19..822598a3 100644 --- a/tracks/test/functional/projects_controller_test.rb +++ b/tracks/test/functional/projects_controller_test.rb @@ -18,9 +18,8 @@ class ProjectsControllerTest < TodoContainerControllerTestBase end def test_show_exposes_deferred_todos - @request.session['user_id'] = users(:admin_user).id p = projects(:timemachine) - get :show, :id => p.to_param + show p assert_not_nil assigns['deferred'] assert_equal 1, assigns['deferred'].size @@ -32,6 +31,16 @@ class ProjectsControllerTest < TodoContainerControllerTestBase assert_equal 2, assigns['deferred'].size end + def test_show_exposes_next_project_in_same_state + show projects(:timemachine) + assert_equal(projects(:moremoney), assigns['next_project']) + end + + def test_show_exposes_previous_project_in_same_state + show projects(:moremoney) + assert_equal(projects(:timemachine), assigns['previous_project']) + end + def test_create_project_via_ajax_increments_number_of_projects assert_ajax_create_increments_count 'My New Project' end @@ -190,5 +199,11 @@ class ProjectsControllerTest < TodoContainerControllerTestBase get :index, { :format => "txt", :token => users(:admin_user).word } assert_response :ok end + + private + def show(project) + @request.session['user_id'] = project.user_id + get :show, :id => project.to_param + end end diff --git a/tracks/test/unit/user_test.rb b/tracks/test/unit/user_test.rb index e8e95608..ab643ec1 100644 --- a/tracks/test/unit/user_test.rb +++ b/tracks/test/unit/user_test.rb @@ -1,7 +1,7 @@ require File.dirname(__FILE__) + '/../test_helper' class UserTest < Test::Unit::TestCase - fixtures :users, :preferences + fixtures :users, :preferences, :projects, :todos def setup assert_equal "test", ENV['RAILS_ENV'] @@ -150,6 +150,30 @@ class UserTest < Test::Unit::TestCase assert_nil User.authenticate(@admin_user.login, "abracadabra") assert_not_nil User.authenticate(@admin_user.login, "foobar") end + + def test_projects_next_project + moremoney = projects(:moremoney) + next_project = @admin_user.projects.next_from(moremoney) + assert_equal projects(:gardenclean), next_project + end + + def test_projects_previous_project + moremoney = projects(:moremoney) + previous_project = @admin_user.projects.previous_from(moremoney) + assert_equal projects(:timemachine), previous_project + end + + def test_projects_next_project_nil + gardenclean = projects(:gardenclean) + next_project = @admin_user.projects.next_from(gardenclean) + assert_nil next_project + end + + def test_projects_previous_project_nil + timemachine = projects(:timemachine) + previous_project = @admin_user.projects.previous_from(timemachine) + assert_nil previous_project + end end