diff --git a/tracks/app/controllers/projects_controller.rb b/tracks/app/controllers/projects_controller.rb
index cae0a7d2..a72d6581 100644
--- a/tracks/app/controllers/projects_controller.rb
+++ b/tracks/app/controllers/projects_controller.rb
@@ -127,6 +127,11 @@ class ProjectsController < ApplicationController
redirect_to :action => 'index'
end
+ def alphabetize
+ @state = params['state']
+ @projects = @user.projects.alphabetize(:state => @state) if @state
+ end
+
protected
def render_projects_html
diff --git a/tracks/app/models/user.rb b/tracks/app/models/user.rb
index bb929327..22920265 100644
--- a/tracks/app/models/user.rb
+++ b/tracks/app/models/user.rb
@@ -42,6 +42,12 @@ class User < ActiveRecord::Base
project.cached_note_count = project_note_counts[project.id] || 0
end
end
+ def alphabetize(scope_conditions = {})
+ projects = find(:all, :conditions => scope_conditions)
+ projects.sort!{ |x,y| x.name <=> y.name }
+ self.update_positions(projects.map{ |p| p.id })
+ return projects
+ end
end
has_many :todos,
:order => 'completed_at DESC, todos.created_at DESC',
diff --git a/tracks/app/views/projects/_project_state_group.rhtml b/tracks/app/views/projects/_project_state_group.rhtml
index 6ec2cc18..9a82bb28 100644
--- a/tracks/app/views/projects/_project_state_group.rhtml
+++ b/tracks/app/views/projects/_project_state_group.rhtml
@@ -1,5 +1,15 @@
>
<%= project_state_group.length %><%= state.titlecase %> Projects
+
+ <%= link_to("Sort Alphabetically", alphabetize_projects_path(:state => state),
+ :class => "alphabetize_link", :title => "Sort these projects alphabetically") %>
+ <% apply_behavior '.alphabetize_link:click', :prevent_default => true do |page|
+ page << "if (confirm('Are you sure that you want to sort these projects alphabetically? This will replace the existing sort order.')) {"
+ page << " new Ajax.Request(this.href, { asynchronous : true, evalScripts : true, method : 'post' })"
+ page << "}"
+ end
+ %>
+
<%= render :partial => 'project_listing', :collection => project_state_group %>
diff --git a/tracks/app/views/projects/alphabetize.rjs b/tracks/app/views/projects/alphabetize.rjs
new file mode 100644
index 00000000..1522948d
--- /dev/null
+++ b/tracks/app/views/projects/alphabetize.rjs
@@ -0,0 +1,3 @@
+page.replace_html "list-#{@state}-projects",
+ :partial => 'project_listing',
+ :collection => @projects
\ No newline at end of file
diff --git a/tracks/config/routes.rb b/tracks/config/routes.rb
index f516d944..930526e6 100644
--- a/tracks/config/routes.rb
+++ b/tracks/config/routes.rb
@@ -19,7 +19,7 @@ ActionController::Routing::Routes.draw do |map|
end
# Projects Routes
- map.resources :projects, :collection => {:order => :post} do |projects|
+ map.resources :projects, :collection => {:order => :post, :alphabetize => :post} do |projects|
projects.resources :todos, :name_prefix => "project_"
end
diff --git a/tracks/public/stylesheets/standard.css b/tracks/public/stylesheets/standard.css
index 8274b3c3..8f022713 100644
--- a/tracks/public/stylesheets/standard.css
+++ b/tracks/public/stylesheets/standard.css
@@ -526,8 +526,15 @@ div.buttons, div.buttons a, div.buttons a:hover {
}
div#list-active-projects, div#list-hidden-projects, div#list-completed-projects, div#list-contexts, div#projects-empty-nd {
- border: 1px solid #999;
+ clear:right;
+ border: 1px solid #999;
}
+
+div.alpha_sort {
+ margin-top:-20px;
+ float:right;
+}
+
.container td {
border: none;
diff --git a/tracks/test/functional/projects_controller_test.rb b/tracks/test/functional/projects_controller_test.rb
index 81b077b8..c3aa0564 100644
--- a/tracks/test/functional/projects_controller_test.rb
+++ b/tracks/test/functional/projects_controller_test.rb
@@ -214,6 +214,31 @@ class ProjectsControllerTest < TodoContainerControllerTestBase
get :index, { :format => "txt", :token => users(:admin_user).word }
assert_response :ok
end
+
+ def test_alphabetize_sorts_active_projects_alphabetically
+ u = users(:admin_user)
+ @request.session['user_id'] = u.id
+ post :alphabetize, { :state => "active" }
+ assert_equal 1, projects(:timemachine).position
+ assert_equal 2, projects(:gardenclean).position
+ assert_equal 3, projects(:moremoney).position
+ end
+
+ def test_alphabetize_assigns_state
+ @request.session['user_id'] = users(:admin_user).id
+ post :alphabetize, { :state => "active" }
+ assert_equal "active", assigns['state']
+ end
+
+ def test_alphabetize_assigns_projects
+ @request.session['user_id'] = users(:admin_user).id
+ post :alphabetize, { :state => "active" }
+ exposed_projects = assigns['projects']
+ assert_equal 3, exposed_projects.length
+ assert_equal projects(:timemachine), exposed_projects[0]
+ assert_equal projects(:gardenclean), exposed_projects[1]
+ assert_equal projects(:moremoney), exposed_projects[2]
+ end
private
def show(project)
diff --git a/tracks/test/unit/user_test.rb b/tracks/test/unit/user_test.rb
index faaf74c2..387e3944 100644
--- a/tracks/test/unit/user_test.rb
+++ b/tracks/test/unit/user_test.rb
@@ -269,5 +269,14 @@ class UserTest < Test::Unit::TestCase
todos = @admin_user.completed_todos.completed_more_than(@admin_user.time - 1.day)
assert_equal 1, todos.length
end
+
+ def test_sort_active_projects_alphabetically
+ u = users(:admin_user)
+ u.projects.alphabetize(:state => "active")
+ assert_equal 1, projects(:timemachine).position
+ assert_equal 2, projects(:gardenclean).position
+ assert_equal 3, projects(:moremoney).position
+ end
+
end