Patch #1708 » user-sorting-r1711.patch
| test/unit/user_test.rb (working copy) | ||
|---|---|---|
| 83 | 83 |
Setting.user_format = :username |
| 84 | 84 |
assert_equal 'jsmith', @jsmith.name |
| 85 | 85 |
end |
| 86 |
|
|
| 86 | ||
| 87 |
def test_sort_format |
|
| 88 |
assert_equal 'users.lastname ASC', User::USER_SORT_FORMATS[:lastname] |
|
| 89 |
assert_equal 'users.firstname ASC', User::USER_SORT_FORMATS[:firstname] |
|
| 90 |
assert_equal 'users.login ASC', User::USER_SORT_FORMATS[:username] |
|
| 91 |
end |
|
| 92 | ||
| 87 | 93 |
def test_lock |
| 88 | 94 |
user = User.try_to_login("jsmith", "jsmith")
|
| 89 | 95 |
assert_equal @jsmith, user |
| ... | ... | |
| 152 | 158 |
@jsmith.pref.comments_sorting = 'desc' |
| 153 | 159 |
assert @jsmith.wants_comments_in_reverse_order? |
| 154 | 160 |
end |
| 161 |
|
|
| 162 |
def test_find_missing_members |
|
| 163 |
# Project has members 2, 3, 5 (locked) |
|
| 164 |
@project = Project.find(1) |
|
| 165 |
missing_members = User.find_missing_members(@project) |
|
| 166 |
# Users 1, 4 missing. User 6 Anonymous |
|
| 167 |
assert missing_members.include?(User.find(1)) |
|
| 168 |
assert missing_members.include?(User.find(4)) |
|
| 169 |
end |
|
| 155 | 170 |
end |
| test/unit/project_test.rb (working copy) | ||
|---|---|---|
| 130 | 130 |
assert_equal [1, 2, 3], parent.rolled_up_trackers.collect(&:id) |
| 131 | 131 |
assert_equal [2, 3], child.rolled_up_trackers.collect(&:id) |
| 132 | 132 |
end |
| 133 |
|
|
| 134 |
def test_assignable_user |
|
| 135 |
assert @ecookbook.assignable_users.include?(User.find(2)) |
|
| 136 |
assert @ecookbook.assignable_users.include?(User.find(3)) |
|
| 137 |
end |
|
| 138 |
|
|
| 139 |
def test_assignable_user_sorted_by_lastname |
|
| 140 |
Setting.user_sort = :lastname |
|
| 141 |
new_user = create_user_for_sorting(@ecookbook) |
|
| 142 |
|
|
| 143 |
assert_equal User.find(3), @ecookbook.assignable_users[0] # Lopper |
|
| 144 |
assert_equal User.find(2), @ecookbook.assignable_users[1] # Smith |
|
| 145 |
assert_equal User.find(new_user.id), @ecookbook.assignable_users[2] # Zimmer |
|
| 146 |
end |
|
| 147 |
|
|
| 148 |
def test_assignable_user_sorted_by_firstname |
|
| 149 |
Setting.user_sort = :firstname |
|
| 150 |
new_user = create_user_for_sorting(@ecookbook) |
|
| 151 |
|
|
| 152 |
assert_equal User.find(new_user.id), @ecookbook.assignable_users[0] # Alan |
|
| 153 |
assert_equal User.find(3), @ecookbook.assignable_users[1] # Dave |
|
| 154 |
assert_equal User.find(2), @ecookbook.assignable_users[2] # John |
|
| 155 |
end |
|
| 156 |
|
|
| 157 |
def test_assignable_user_sorted_by_username |
|
| 158 |
Setting.user_sort = :username |
|
| 159 |
new_user = create_user_for_sorting(@ecookbook) |
|
| 160 |
|
|
| 161 |
assert_equal User.find(3), @ecookbook.assignable_users[0] # dlopper |
|
| 162 |
assert_equal User.find(new_user.id), @ecookbook.assignable_users[1] # good_user |
|
| 163 |
assert_equal User.find(2), @ecookbook.assignable_users[2] # jsmith |
|
| 164 |
end |
|
| 165 |
|
|
| 166 |
private |
|
| 167 |
def create_user_for_sorting(project) |
|
| 168 |
u = User.new( |
|
| 169 |
:firstname => "Alan", |
|
| 170 |
:lastname => "Zimmer", |
|
| 171 |
:mail => "newuser@somenet.foo", |
|
| 172 |
:password => 'password', |
|
| 173 |
:password_confirmation => 'password' |
|
| 174 |
) |
|
| 175 |
u.login = 'good_user' |
|
| 176 |
u.save! |
|
| 177 |
|
|
| 178 |
Member.create(:project => project, :user => u, :role_id => 1) |
|
| 179 |
return u |
|
| 180 |
end |
|
| 133 | 181 |
end |
| app/models/user.rb (working copy) | ||
|---|---|---|
| 32 | 32 |
:lastname_coma_firstname => '#{lastname}, #{firstname}',
|
| 33 | 33 |
:username => '#{login}'
|
| 34 | 34 |
} |
| 35 |
|
|
| 36 |
USER_SORT_FORMATS = {
|
|
| 37 |
:lastname => "#{User.table_name}.lastname ASC",
|
|
| 38 |
:firstname => "#{User.table_name}.firstname ASC",
|
|
| 39 |
:username => "#{User.table_name}.login ASC"
|
|
| 40 |
} |
|
| 35 | 41 | |
| 36 | 42 |
has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :conditions => "#{Project.table_name}.status=#{Project::STATUS_ACTIVE}", :order => "#{Project.table_name}.name", :dependent => :delete_all
|
| 37 | 43 |
has_many :projects, :through => :memberships |
| ... | ... | |
| 115 | 121 |
rescue => text |
| 116 | 122 |
raise text |
| 117 | 123 |
end |
| 118 |
|
|
| 124 | ||
| 125 |
# Given +project+ find all users who are not yet a member on the project |
|
| 126 |
def self.find_missing_members(project) |
|
| 127 |
self.find_active(:all, :order => (USER_SORT_FORMATS[Setting.user_sort] || USER_SORT_FORMATS[:lastname])) - project.users |
|
| 128 |
end |
|
| 129 |
|
|
| 119 | 130 |
# Return user's full name for display |
| 120 | 131 |
def name(formatter = nil) |
| 121 | 132 |
f = USER_FORMATS[formatter || Setting.user_format] || USER_FORMATS[:firstname_lastname] |
| app/models/project.rb (working copy) | ||
|---|---|---|
| 187 | 187 |
|
| 188 | 188 |
# Users issues can be assigned to |
| 189 | 189 |
def assignable_users |
| 190 |
members.select {|m| m.role.assignable?}.collect {|m| m.user}.sort
|
|
| 190 |
members.find(:all, :order => (User::USER_SORT_FORMATS[Setting.user_sort] || User::USER_SORT_FORMATS[:lastname])).select {|m| m.role.assignable?}.collect {|m| m.user}
|
|
| 191 | 191 |
end |
| 192 | 192 |
|
| 193 | 193 |
# Returns the mail adresses of users that should be always notified on project events |
| app/controllers/settings_controller.rb (working copy) | ||
|---|---|---|
| 39 | 39 |
end |
| 40 | 40 |
@options = {}
|
| 41 | 41 |
@options[:user_format] = User::USER_FORMATS.keys.collect {|f| [User.current.name(f), f.to_s] }
|
| 42 |
@options[:user_sort] = User::USER_SORT_FORMATS.keys.collect {|f| [Inflector.humanize(f), f.to_s] }
|
|
| 42 | 43 |
@deliveries = ActionMailer::Base.perform_deliveries |
| 43 | 44 |
end |
| 44 | 45 |
|
| app/views/settings/_general.rhtml (working copy) | ||
|---|---|---|
| 23 | 23 |
<p><label><%= l(:setting_user_format) %></label> |
| 24 | 24 |
<%= select_tag 'settings[user_format]', options_for_select( @options[:user_format], Setting.user_format.to_s ) %></p> |
| 25 | 25 | |
| 26 |
<p><label><%= l(:setting_user_sort) %></label> |
|
| 27 |
<%= select_tag 'settings[user_sort]', options_for_select( @options[:user_sort], Setting.user_sort.to_s ) %></p> |
|
| 28 | ||
| 26 | 29 |
<p><label><%= l(:setting_attachment_max_size) %></label> |
| 27 | 30 |
<%= text_field_tag 'settings[attachment_max_size]', Setting.attachment_max_size, :size => 6 %> KB</p> |
| 28 | 31 | |
| app/views/projects/settings/_members.rhtml (working copy) | ||
|---|---|---|
| 1 | 1 |
<%= error_messages_for 'member' %> |
| 2 | 2 |
<% roles = Role.find_all_givable %> |
| 3 |
<% users = User.find_active(:all).sort - @project.users %>
|
|
| 3 |
<% users = User.find_missing_members(@project) %>
|
|
| 4 | 4 |
<% # members sorted by role position |
| 5 | 5 |
members = @project.members.find(:all, :include => [:role, :user]).sort %> |
| 6 | 6 |
|
| lang/en.yml (working copy) | ||
|---|---|---|
| 218 | 218 |
setting_enabled_scm: Enabled SCM |
| 219 | 219 |
setting_mail_handler_api_enabled: Enable WS for incoming emails |
| 220 | 220 |
setting_mail_handler_api_key: API key |
| 221 |
setting_user_sort: Sort users by |
|
| 221 | 222 | |
| 222 | 223 |
project_module_issue_tracking: Issue tracking |
| 223 | 224 |
project_module_time_tracking: Time tracking |
| config/settings.yml (working copy) | ||
|---|---|---|
| 94 | 94 |
user_format: |
| 95 | 95 |
default: :firstname_lastname |
| 96 | 96 |
format: symbol |
| 97 |
user_sort: |
|
| 98 |
default: :lastname |
|
| 99 |
format: symbol |
|
| 97 | 100 |
cross_project_issue_relations: |
| 98 | 101 |
default: 0 |
| 99 | 102 |
notified_events: |