diff --git a/app/controllers/rates_controller.rb b/app/controllers/rates_controller.rb index 13ebeff..255e269 100644 --- a/app/controllers/rates_controller.rb +++ b/app/controllers/rates_controller.rb @@ -1,5 +1,8 @@ class RatesController < ApplicationController helper :users + helper :sort + include SortHelper + before_filter :require_admin before_filter :require_user_id, :only => [:index, :new] before_filter :set_back_url, :only => [:new, :edit] @@ -7,10 +10,13 @@ class RatesController < ApplicationController # GET /rates?user_id=1 # GET /rates.xml?user_id=1 def index - @rates = Rate.history_for_user(@user) + sort_init "#{Rate.table_name}.date_in_effect", "desc" + sort_update # 'date_in_effect' => "#{Rate.table_name}.date_in_effect" + + @rates = Rate.history_for_user(@user, sort_clause) respond_to do |format| - format.html # index.html.erb + format.html { render :action => 'index', :layout => !request.xhr?} format.xml { render :xml => @rates } end end diff --git a/app/models/rate.rb b/app/models/rate.rb index 74bd96e..d247121 100644 --- a/app/models/rate.rb +++ b/app/models/rate.rb @@ -11,13 +11,13 @@ class Rate < ActiveRecord::Base before_save :unlocked? before_destroy :unlocked? - named_scope :history_for_user, lambda { |user| + named_scope :history_for_user, lambda { |user, order| { :conditions => { :user_id => user.id }, - :order => 'date_in_effect DESC' + :order => order } } - + def locked? return self.time_entries.length > 0 end diff --git a/app/views/rates/_list.html.erb b/app/views/rates/_list.html.erb index 46153e7..16bf63a 100644 --- a/app/views/rates/_list.html.erb +++ b/app/views/rates/_list.html.erb @@ -1,7 +1,18 @@ - - + <%= rate_sort_header_tag("date_in_effect", + :caption => l(:label_date), + :default_order => 'desc', + :style => "width: 15%", + :method => :get, + :update => "rate-history", + :user_id => @user.id) %> + <%= rate_sort_header_tag("project_id", + :caption => l(:label_project), + :default_order => 'asc', + :method => :get, + :update => "rate-history", + :user_id => @user.id) %> diff --git a/app/views/rates/index.html.erb b/app/views/rates/index.html.erb index 8c664e4..e1ea43e 100644 --- a/app/views/rates/index.html.erb +++ b/app/views/rates/index.html.erb @@ -1,3 +1,5 @@ +

<%= l(:rate_label_rate_history) %>

-<%= render :partial => 'list' %> \ No newline at end of file +<%= render :partial => 'list' %> +
diff --git a/app/views/users/_rates.html.erb b/app/views/users/_rates.html.erb index 04550f6..59841aa 100644 --- a/app/views/users/_rates.html.erb +++ b/app/views/users/_rates.html.erb @@ -4,9 +4,15 @@ <% @back_url = url_for(:controller => 'users', :action => 'edit', :id => @user, :tab => 'rates') %> <%= render :partial => 'rates/form' %> +

<%= l(:rate_label_rate_history) %>

<%# TODO: Refactor out of the view once there is a hook in the controller (Post 0.8.0). %> <%# Can't expect everyone to upgrade at the moment %> -<% @rates = Rate.history_for_user(@user) %> +<% sort_init "#{Rate.table_name}.date_in_effect", "desc" %> +<% sort_update # 'date_in_effect' => "#{Rate.table_name}.date_in_effect" %> + + +<% @rates = Rate.history_for_user(@user, "#{Rate.table_name}.date_in_effect desc") %> <%= render :partial => 'rates/list' %> +
\ No newline at end of file diff --git a/init.rb b/init.rb index a7e0a75..ac43e65 100644 --- a/init.rb +++ b/init.rb @@ -1,6 +1,7 @@ require 'redmine' require 'rate_users_helper_patch' +require 'rate_sort_helper_patch' Redmine::Plugin.register :redmine_rate do name 'Rate Plugin' diff --git a/lib/rate_sort_helper_patch.rb b/lib/rate_sort_helper_patch.rb new file mode 100644 index 0000000..1746e7d --- /dev/null +++ b/lib/rate_sort_helper_patch.rb @@ -0,0 +1,63 @@ +require_dependency 'sort_helper' + +module RateSortHelperPatch + def self.included(base) # :nodoc: + base.send(:include, InstanceMethods) + end + + module InstanceMethods + # Allows more parameters than the standard sort_header_tag + def rate_sort_header_tag(column, options = {}) + caption = options.delete(:caption) || titleize(Inflector::humanize(column)) + default_order = options.delete(:default_order) || 'asc' + options[:title]= l(:label_sort_by, "\"#{caption}\"") unless options[:title] + content_tag('th', + rate_sort_link(column, + caption, + default_order, + { :method => options[:method], :update => options[:update], :user_id => options[:user_id] }), + options) + end + + # Allows more parameters than the standard sort_link and is hard coded to use + # the RatesController + def rate_sort_link(column, caption, default_order, options = { }) + key, order = session[@sort_name][:key], session[@sort_name][:order] + if key == column + if order.downcase == 'asc' + icon = 'sort_asc.png' + order = 'desc' + else + icon = 'sort_desc.png' + order = 'asc' + end + else + icon = nil + order = default_order + end + caption = titleize(Inflector::humanize(column)) unless caption + + sort_options = { :sort_key => column, :sort_order => order} + # don't reuse params if filters are present + url_options = params.has_key?(:set_filter) ? sort_options : params.merge(sort_options) + + # Hard code url to the Rates index + url_options[:controller] = 'rates' + url_options[:action] = 'index' + url_options[:user_id] ||= options[:user_id] + + link_to_remote(caption, + { + :update => options[:update] || "content", + :url => url_options, + :method => options[:method] || :post + }, + {:href => url_for(url_options)}) + + (icon ? nbsp(2) + image_tag(icon) : '') + end + + end +end + +SortHelper.send(:include, RateSortHelperPatch) + diff --git a/spec/controllers/rates_controller_spec.rb b/spec/controllers/rates_controller_spec.rb index 423c9b3..c79250c 100644 --- a/spec/controllers/rates_controller_spec.rb +++ b/spec/controllers/rates_controller_spec.rb @@ -160,10 +160,11 @@ describe RatesController, "as an administrator" do describe "responding to GET index with user" do before(:each) do User.stub!(:find).with(@user.id.to_s).and_return(@user) + @default_sort = "#{Rate.table_name}.date_in_effect desc" end it "should expose all historic rates for the user as @rates" do - Rate.should_receive(:history_for_user).with(@user).and_return([mock_rate]) + Rate.should_receive(:history_for_user).with(@user, @default_sort).and_return([mock_rate]) get :index, :user_id => @user.id assigns[:rates].should == [mock_rate] end @@ -172,7 +173,7 @@ describe RatesController, "as an administrator" do it "should render all rates as xml" do request.env["HTTP_ACCEPT"] = "application/xml" - Rate.should_receive(:history_for_user).with(@user).and_return(rates = mock("Array of Rates")) + Rate.should_receive(:history_for_user).with(@user, @default_sort).and_return(rates = mock("Array of Rates")) rates.should_receive(:to_xml).and_return("generated XML") get :index, :user_id => @user.id response.body.should == "generated XML"
<%= l(:label_date) %><%= l(:label_project) %><%= l(:rate_label_rate) %>