Sort the issue list by author/assignee according to user display format (#9669).
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@7938 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
0293ba7e9f
commit
5a1fcf826f
|
@ -36,7 +36,11 @@ class QueryColumn
|
||||||
|
|
||||||
# Returns true if the column is sortable, otherwise false
|
# Returns true if the column is sortable, otherwise false
|
||||||
def sortable?
|
def sortable?
|
||||||
!sortable.nil?
|
!@sortable.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def sortable
|
||||||
|
@sortable.is_a?(Proc) ? @sortable.call : @sortable
|
||||||
end
|
end
|
||||||
|
|
||||||
def value(issue)
|
def value(issue)
|
||||||
|
@ -136,8 +140,8 @@ class Query < ActiveRecord::Base
|
||||||
QueryColumn.new(:status, :sortable => "#{IssueStatus.table_name}.position", :groupable => true),
|
QueryColumn.new(:status, :sortable => "#{IssueStatus.table_name}.position", :groupable => true),
|
||||||
QueryColumn.new(:priority, :sortable => "#{IssuePriority.table_name}.position", :default_order => 'desc', :groupable => true),
|
QueryColumn.new(:priority, :sortable => "#{IssuePriority.table_name}.position", :default_order => 'desc', :groupable => true),
|
||||||
QueryColumn.new(:subject, :sortable => "#{Issue.table_name}.subject"),
|
QueryColumn.new(:subject, :sortable => "#{Issue.table_name}.subject"),
|
||||||
QueryColumn.new(:author, :sortable => ["authors.lastname", "authors.firstname", "authors.id"], :groupable => true),
|
QueryColumn.new(:author, :sortable => lambda {User.fields_for_order_statement("authors")}, :groupable => true),
|
||||||
QueryColumn.new(:assigned_to, :sortable => ["#{User.table_name}.lastname", "#{User.table_name}.firstname", "#{User.table_name}.id"], :groupable => true),
|
QueryColumn.new(:assigned_to, :sortable => lambda {User.fields_for_order_statement}, :groupable => true),
|
||||||
QueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on", :default_order => 'desc'),
|
QueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on", :default_order => 'desc'),
|
||||||
QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name", :groupable => true),
|
QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name", :groupable => true),
|
||||||
QueryColumn.new(:fixed_version, :sortable => ["#{Version.table_name}.effective_date", "#{Version.table_name}.name"], :default_order => 'desc', :groupable => true),
|
QueryColumn.new(:fixed_version, :sortable => ["#{Version.table_name}.effective_date", "#{Version.table_name}.name"], :default_order => 'desc', :groupable => true),
|
||||||
|
|
|
@ -26,12 +26,13 @@ class User < Principal
|
||||||
STATUS_REGISTERED = 2
|
STATUS_REGISTERED = 2
|
||||||
STATUS_LOCKED = 3
|
STATUS_LOCKED = 3
|
||||||
|
|
||||||
|
# Different ways of displaying/sorting users
|
||||||
USER_FORMATS = {
|
USER_FORMATS = {
|
||||||
:firstname_lastname => '#{firstname} #{lastname}',
|
:firstname_lastname => {:string => '#{firstname} #{lastname}', :order => %w(firstname lastname id)},
|
||||||
:firstname => '#{firstname}',
|
:firstname => {:string => '#{firstname}', :order => %w(firstname id)},
|
||||||
:lastname_firstname => '#{lastname} #{firstname}',
|
:lastname_firstname => {:string => '#{lastname} #{firstname}', :order => %w(lastname firstname id)},
|
||||||
:lastname_coma_firstname => '#{lastname}, #{firstname}',
|
:lastname_coma_firstname => {:string => '#{lastname}, #{firstname}', :order => %w(lastname firstname id)},
|
||||||
:username => '#{login}'
|
:username => {:string => '#{login}', :order => %w(login id)},
|
||||||
}
|
}
|
||||||
|
|
||||||
MAIL_NOTIFICATION_OPTIONS = [
|
MAIL_NOTIFICATION_OPTIONS = [
|
||||||
|
@ -169,12 +170,28 @@ class User < Principal
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.name_formatter(formatter = nil)
|
||||||
|
USER_FORMATS[formatter || Setting.user_format] || USER_FORMATS[:firstname_lastname]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns an array of fields names than can be used to make an order statement for users
|
||||||
|
# according to how user names are displayed
|
||||||
|
# Examples:
|
||||||
|
#
|
||||||
|
# User.fields_for_order_statement => ['users.login', 'users.id']
|
||||||
|
# User.fields_for_order_statement('authors') => ['authors.login', 'authors.id']
|
||||||
|
def self.fields_for_order_statement(table=nil)
|
||||||
|
table ||= table_name
|
||||||
|
name_formatter[:order].map {|field| "#{table}.#{field}"}
|
||||||
|
end
|
||||||
|
|
||||||
# Return user's full name for display
|
# Return user's full name for display
|
||||||
def name(formatter = nil)
|
def name(formatter = nil)
|
||||||
|
f = self.class.name_formatter(formatter)
|
||||||
if formatter
|
if formatter
|
||||||
eval('"' + (USER_FORMATS[formatter] || USER_FORMATS[:firstname_lastname]) + '"')
|
eval('"' + f[:string] + '"')
|
||||||
else
|
else
|
||||||
@name ||= eval('"' + (USER_FORMATS[Setting.user_format] || USER_FORMATS[:firstname_lastname]) + '"')
|
@name ||= eval('"' + f[:string] + '"')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -276,11 +276,6 @@ class IssuesControllerTest < ActionController::TestCase
|
||||||
assert_response :success
|
assert_response :success
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_index_sort_by_field_not_included_in_columns
|
|
||||||
Setting.issue_list_default_columns = %w(subject author)
|
|
||||||
get :index, :sort => 'tracker'
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_index_csv
|
def test_index_csv
|
||||||
get :index, :format => 'csv'
|
get :index, :format => 'csv'
|
||||||
assert_response :success
|
assert_response :success
|
||||||
|
@ -422,9 +417,42 @@ class IssuesControllerTest < ActionController::TestCase
|
||||||
assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
|
assert_equal issues.sort {|a,b| a.tracker == b.tracker ? b.id <=> a.id : a.tracker <=> b.tracker }.collect(&:id), issues.collect(&:id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_index_sort_by_field_not_included_in_columns
|
||||||
|
Setting.issue_list_default_columns = %w(subject author)
|
||||||
|
get :index, :sort => 'tracker'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_index_sort_by_assigned_to
|
||||||
|
get :index, :sort => 'assigned_to'
|
||||||
|
assert_response :success
|
||||||
|
assignees = assigns(:issues).collect(&:assigned_to).compact
|
||||||
|
assert_equal assignees.sort, assignees
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_index_sort_by_assigned_to_desc
|
||||||
|
get :index, :sort => 'assigned_to:desc'
|
||||||
|
assert_response :success
|
||||||
|
assignees = assigns(:issues).collect(&:assigned_to).compact
|
||||||
|
assert_equal assignees.sort.reverse, assignees
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_index_group_by_assigned_to
|
||||||
|
get :index, :group_by => 'assigned_to', :sort => 'priority'
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
|
|
||||||
def test_index_sort_by_author
|
def test_index_sort_by_author
|
||||||
get :index, :sort => 'author'
|
get :index, :sort => 'author'
|
||||||
assert_response :success
|
assert_response :success
|
||||||
|
authors = assigns(:issues).collect(&:author)
|
||||||
|
assert_equal authors.sort, authors
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_index_sort_by_author_desc
|
||||||
|
get :index, :sort => 'author:desc'
|
||||||
|
assert_response :success
|
||||||
|
authors = assigns(:issues).collect(&:author)
|
||||||
|
assert_equal authors.sort.reverse, authors
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_index_group_by_author
|
def test_index_group_by_author
|
||||||
|
|
|
@ -98,11 +98,11 @@ class ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def with_settings(options, &block)
|
def with_settings(options, &block)
|
||||||
saved_settings = options.keys.inject({}) {|h, k| h[k] = Setting[k].dup; h}
|
saved_settings = options.keys.inject({}) {|h, k| h[k] = Setting[k].is_a?(Symbol) ? Setting[k] : Setting[k].dup; h}
|
||||||
options.each {|k, v| Setting[k] = v}
|
options.each {|k, v| Setting[k] = v}
|
||||||
yield
|
yield
|
||||||
ensure
|
ensure
|
||||||
saved_settings.each {|k, v| Setting[k] = v}
|
saved_settings.each {|k, v| Setting[k] = v} if saved_settings
|
||||||
end
|
end
|
||||||
|
|
||||||
def change_user_password(login, new_password)
|
def change_user_password(login, new_password)
|
||||||
|
|
|
@ -444,6 +444,22 @@ class QueryTest < ActiveSupport::TestCase
|
||||||
assert_nil q.group_by_statement
|
assert_nil q.group_by_statement
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_sortable_columns_should_sort_assignees_according_to_user_format_setting
|
||||||
|
with_settings :user_format => 'lastname_coma_firstname' do
|
||||||
|
q = Query.new
|
||||||
|
assert q.sortable_columns.has_key?('assigned_to')
|
||||||
|
assert_equal %w(users.lastname users.firstname users.id), q.sortable_columns['assigned_to']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_sortable_columns_should_sort_authors_according_to_user_format_setting
|
||||||
|
with_settings :user_format => 'lastname_coma_firstname' do
|
||||||
|
q = Query.new
|
||||||
|
assert q.sortable_columns.has_key?('author')
|
||||||
|
assert_equal %w(authors.lastname authors.firstname authors.id), q.sortable_columns['author']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_default_sort
|
def test_default_sort
|
||||||
q = Query.new
|
q = Query.new
|
||||||
assert_equal [], q.sort_criteria
|
assert_equal [], q.sort_criteria
|
||||||
|
|
|
@ -398,6 +398,30 @@ class UserTest < ActiveSupport::TestCase
|
||||||
assert_equal 'jsmith', @jsmith.reload.name
|
assert_equal 'jsmith', @jsmith.reload.name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_fields_for_order_statement_should_return_fields_according_user_format_setting
|
||||||
|
with_settings :user_format => 'lastname_coma_firstname' do
|
||||||
|
assert_equal ['users.lastname', 'users.firstname', 'users.id'], User.fields_for_order_statement
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_fields_for_order_statement_width_table_name_should_prepend_table_name
|
||||||
|
with_settings :user_format => 'lastname_firstname' do
|
||||||
|
assert_equal ['authors.lastname', 'authors.firstname', 'authors.id'], User.fields_for_order_statement('authors')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_fields_for_order_statement_with_blank_format_should_return_default
|
||||||
|
with_settings :user_format => '' do
|
||||||
|
assert_equal ['users.firstname', 'users.lastname', 'users.id'], User.fields_for_order_statement
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_fields_for_order_statement_with_invalid_format_should_return_default
|
||||||
|
with_settings :user_format => 'foo' do
|
||||||
|
assert_equal ['users.firstname', 'users.lastname', 'users.id'], User.fields_for_order_statement
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_lock
|
def test_lock
|
||||||
user = User.try_to_login("jsmith", "jsmith")
|
user = User.try_to_login("jsmith", "jsmith")
|
||||||
assert_equal @jsmith, user
|
assert_equal @jsmith, user
|
||||||
|
|
Loading…
Reference in New Issue