Commit 7f767162 authored by jplang's avatar jplang
Browse files

Ability to save "sort order" in custom queries (#2899).

git-svn-id: https://svn.redmine.org/redmine/trunk@2572 e93f8b46-1217-0410-a6f0-8f06a7374b81
parent 7bb9a2ee
......@@ -45,7 +45,7 @@ class IssuesController < ApplicationController
def index
retrieve_query
sort_init 'id', 'desc'
sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria)
sort_update({'id' => "#{Issue.table_name}.id"}.merge(@query.columns.inject({}) {|h, c| h[c.name.to_s] = c.sortable; h}))
if @query.valid?
......@@ -471,6 +471,7 @@ private
@query = Query.find(params[:query_id], :conditions => cond)
@query.project = @project
session[:query] = {:id => @query.id, :project_id => @query.project_id}
sort_clear
else
if params[:set_filter] || session[:query].nil? || session[:query][:project_id] != (@project ? @project.id : nil)
# Give it a name, required to be valid
......
......@@ -69,6 +69,11 @@ module SortHelper
normalize!
end
def criteria=(arg)
@criteria = arg
normalize!
end
def to_param
@criteria.collect {|k,o| k + (o ? '' : ':desc')}.join(',')
end
......@@ -102,24 +107,42 @@ module SortHelper
@criteria.first && @criteria.first.last
end
def empty?
@criteria.empty?
end
private
def normalize!
@criteria = @criteria.collect {|s| [s.first, (s.last == false || s.last == 'desc') ? false : true]}
@criteria ||= []
@criteria = @criteria.collect {|s| s = s.to_a; [s.first, (s.last == false || s.last == 'desc') ? false : true]}
@criteria = @criteria.select {|k,o| @available_criteria.has_key?(k)} if @available_criteria
@criteria.slice!(3)
self
end
end
def sort_name
controller_name + '_' + action_name + '_sort'
end
# Initializes the default sort column (default_key) and sort order
# (default_order).
#
# - default_key is a column attribute name.
# - default_order is 'asc' or 'desc'.
# Initializes the default sort.
# Examples:
#
# sort_init 'name'
# sort_init 'id', 'desc'
# sort_init ['name', ['id', 'desc']]
# sort_init [['name', 'desc'], ['id', 'desc']]
#
def sort_init(default_key, default_order='asc')
@sort_default = "#{default_key}:#{default_order}"
def sort_init(*args)
case args.size
when 1
@sort_default = args.first.is_a?(Array) ? args.first : [[args.first]]
when 2
@sort_default = [[args.first, args.last]]
else
raise ArgumentError
end
end
# Updates the sort state. Call this in the controller prior to calling
......@@ -127,13 +150,18 @@ module SortHelper
# - criteria can be either an array or a hash of allowed keys
#
def sort_update(criteria)
sort_name = controller_name + '_' + action_name + '_sort'
@sort_criteria = SortCriteria.new
@sort_criteria.available_criteria = criteria
@sort_criteria.from_param(params[:sort] || session[sort_name] || @sort_default)
@sort_criteria.from_param(params[:sort] || session[sort_name])
@sort_criteria.criteria = @sort_default if @sort_criteria.empty?
session[sort_name] = @sort_criteria.to_param
end
# Clears the sort criteria session data
#
def sort_clear
session[sort_name] = nil
end
# Returns an SQL sort clause corresponding to the current sort state.
# Use this to sort the controller's table items collection.
......@@ -188,13 +216,6 @@ module SortHelper
#
# <%= sort_header_tag('id', :title => 'Sort by contact ID', :width => 40) %>
#
# Renders:
#
# <th title="Sort by contact ID" width="40">
# <a href="/contact/list?sort_order=desc&amp;sort_key=id">Id</a>
# &nbsp;&nbsp;<img alt="Sort_asc" src="/images/sort_asc.png" />
# </th>
#
def sort_header_tag(column, options = {})
caption = options.delete(:caption) || column.to_s.humanize
default_order = options.delete(:default_order) || 'asc'
......
......@@ -28,6 +28,11 @@ class QueryColumn
def caption
l("field_#{name}")
end
# Returns true if the column is sortable, otherwise false
def sortable?
!sortable.nil?
end
end
class QueryCustomFieldColumn < QueryColumn
......@@ -52,6 +57,7 @@ class Query < ActiveRecord::Base
belongs_to :user
serialize :filters
serialize :column_names
serialize :sort_criteria, Array
attr_protected :project_id, :user_id
......@@ -261,6 +267,27 @@ class Query < ActiveRecord::Base
column_names.nil? || column_names.empty?
end
def sort_criteria=(arg)
c = []
if arg.is_a?(Hash)
arg = arg.keys.sort.collect {|k| arg[k]}
end
c = arg.select {|k,o| !k.to_s.blank?}.slice(0,3).collect {|k,o| [k.to_s, o == 'desc' ? o : 'asc']}
write_attribute(:sort_criteria, c)
end
def sort_criteria
read_attribute(:sort_criteria) || []
end
def sort_criteria_key(arg)
sort_criteria && sort_criteria[arg] && sort_criteria[arg].first
end
def sort_criteria_order(arg)
sort_criteria && sort_criteria[arg] && sort_criteria[arg].last
end
def project_statement
project_clauses = []
if project && !@project.descendants.active.empty?
......
......@@ -25,5 +25,14 @@
<%= render :partial => 'queries/filters', :locals => {:query => query}%>
</fieldset>
<fieldset><legend><%= l(:label_sort) %></legend>
<% 3.times do |i| %>
<%= i+1 %>: <%= select_tag("query[sort_criteria][#{i}][]",
options_for_select([[]] + query.available_columns.select(&:sortable?).collect {|column| [column.caption, column.name.to_s]}, @query.sort_criteria_key(i))) %>
<%= select_tag("query[sort_criteria][#{i}][]",
options_for_select([[], [l(:label_ascending), 'asc'], [l(:label_descending), 'desc']], @query.sort_criteria_order(i))) %><br />
<% end %>
</fieldset>
<%= render :partial => 'queries/columns', :locals => {:query => query}%>
</div>
......@@ -778,3 +778,6 @@ bg:
field_identity_url: OpenID URL
label_login_with_open_id_option: or login with OpenID
field_content: Content
label_descending: Descending
label_sort: Sort
label_ascending: Ascending
......@@ -779,3 +779,6 @@ ca:
field_identity_url: OpenID URL
label_login_with_open_id_option: or login with OpenID
field_content: Content
label_descending: Descending
label_sort: Sort
label_ascending: Ascending
......@@ -783,3 +783,6 @@ cs:
field_identity_url: OpenID URL
label_login_with_open_id_option: or login with OpenID
field_content: Content
label_descending: Descending
label_sort: Sort
label_ascending: Ascending
......@@ -811,3 +811,6 @@ da:
setting_per_page_options: Objects per page options
mail_body_reminder: "{{count}} issue(s) that are assigned to you are due in the next {{days}} days:"
field_content: Content
label_descending: Descending
label_sort: Sort
label_ascending: Ascending
......@@ -810,3 +810,6 @@ de:
field_identity_url: OpenID URL
label_login_with_open_id_option: or login with OpenID
field_content: Content
label_descending: Descending
label_sort: Sort
label_ascending: Ascending
......@@ -662,6 +662,9 @@ en:
label_issue_watchers: Watchers
label_example: Example
label_display: Display
label_sort: Sort
label_ascending: Ascending
label_descending: Descending
button_login: Login
button_submit: Submit
......
......@@ -831,3 +831,6 @@ es:
field_identity_url: OpenID URL
label_login_with_open_id_option: or login with OpenID
field_content: Content
label_descending: Descending
label_sort: Sort
label_ascending: Ascending
......@@ -821,3 +821,6 @@ fi:
field_identity_url: OpenID URL
label_login_with_open_id_option: or login with OpenID
field_content: Content
label_descending: Descending
label_sort: Sort
label_ascending: Ascending
......@@ -694,6 +694,9 @@ fr:
label_issue_watchers: Observateurs
label_example: Exemple
label_display: Affichage
label_sort: Tri
label_ascending: Croissant
label_descending: Décroissant
button_login: Connexion
button_submit: Soumettre
......
......@@ -810,3 +810,6 @@ gl:
field_identity_url: OpenID URL
label_login_with_open_id_option: or login with OpenID
field_content: Content
label_descending: Descending
label_sort: Sort
label_ascending: Ascending
......@@ -793,3 +793,6 @@ he:
field_identity_url: OpenID URL
label_login_with_open_id_option: or login with OpenID
field_content: Content
label_descending: Descending
label_sort: Sort
label_ascending: Ascending
......@@ -816,3 +816,6 @@
field_identity_url: OpenID URL
label_login_with_open_id_option: bejelentkezés OpenID használatával
field_content: Content
label_descending: Descending
label_sort: Sort
label_ascending: Ascending
......@@ -796,3 +796,6 @@ it:
field_identity_url: OpenID URL
label_login_with_open_id_option: or login with OpenID
field_content: Content
label_descending: Descending
label_sort: Sort
label_ascending: Ascending
......@@ -809,3 +809,6 @@ ja:
field_identity_url: OpenID URL
label_login_with_open_id_option: or login with OpenID
field_content: Content
label_descending: Descending
label_sort: Sort
label_ascending: Ascending
......@@ -840,3 +840,6 @@ ko:
field_identity_url: OpenID URL
label_login_with_open_id_option: or login with OpenID
field_content: Content
label_descending: Descending
label_sort: Sort
label_ascending: Ascending
......@@ -821,3 +821,6 @@ lt:
field_identity_url: OpenID URL
label_login_with_open_id_option: or login with OpenID
field_content: Content
label_descending: Descending
label_sort: Sort
label_ascending: Ascending
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment