diff --git a/app/models/issue.rb b/app/models/issue.rb index d6d6c7c8b..f727853e2 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -1184,6 +1184,10 @@ class Issue < ActiveRecord::Base end end + def watchers_count + @watchers_count ||= self.watchers.count(:id) + end + # Preloads relations for a collection of issues def self.load_relations(issues) if issues.any? diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index a0420c994..c64eaef57 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -45,6 +45,15 @@ class IssueQuery < Query QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name", :groupable => true), QueryColumn.new(:fixed_version, :sortable => lambda {Version.fields_for_order_statement}, :groupable => true), + QueryColumn.new( + :watchers_count, + :sortable => + lambda do + "COALESCE((SELECT COUNT(user_id) FROM #{Watcher.table_name}" \ + " WHERE #{Watcher.table_name}.watchable_type = 'Issue'" \ + " AND #{Watcher.table_name}.watchable_id = #{Issue.table_name}.id), 0)" + end, + :default_order => 'desc'), QueryColumn.new(:start_date, :sortable => "#{Issue.table_name}.start_date", :groupable => true), QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date", :groupable => true), QueryColumn.new(:estimated_hours, :sortable => "#{Issue.table_name}.estimated_hours", diff --git a/app/views/watchers/_set_watcher.js.erb b/app/views/watchers/_set_watcher.js.erb index 4090ef6ce..79620842e 100644 --- a/app/views/watchers/_set_watcher.js.erb +++ b/app/views/watchers/_set_watcher.js.erb @@ -1,3 +1,8 @@ -<% selector = ".#{watcher_css(watched)}" %> -$("<%= selector %>").each(function(){$(this).replaceWith("<%= escape_javascript watcher_link(watched, user) %>")}); -$('#watchers').html('<%= escape_javascript(render(:partial => 'watchers/watchers', :locals => {:watched => watched.first})) %>'); +var back_url = $('input[name="back_url"]').val() || ''; +if (back_url.length > 0) { + window.location.href = back_url; +} else { + <% selector = ".#{watcher_css(watched)}" %> + $("<%= selector %>").each(function(){$(this).replaceWith("<%= escape_javascript watcher_link(watched, user) %>")}); + $('#watchers').html('<%= escape_javascript(render(:partial => 'watchers/watchers', :locals => {:watched => watched.first})) %>'); +} diff --git a/app/views/watchers/create.js.erb b/app/views/watchers/create.js.erb index b0421bc3a..6bf9ffec1 100644 --- a/app/views/watchers/create.js.erb +++ b/app/views/watchers/create.js.erb @@ -3,7 +3,5 @@ $('#ajax-modal').html( render(:partial => 'watchers/new', :locals => {:watchables => @watchables, :users => @users})) %>'); -<% if @watchables.size == 1 %> - <%= render(:partial => 'watchers/set_watcher', - :locals => {:watched => @watchables, :user => User.current}) %> -<% end %> +<%= render(:partial => 'watchers/set_watcher', + :locals => {:watched => @watchables, :user => User.current}) %> diff --git a/config/locales/en.yml b/config/locales/en.yml index f9064c866..a20874799 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -369,6 +369,7 @@ en: field_parent_title: Parent page field_editable: Editable field_watcher: Watcher + field_watchers_count: Watchers count field_content: Content field_group_by: Group results by field_sharing: Sharing diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 0215e7555..e4ac5f1de 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -328,6 +328,7 @@ ja: field_parent_title: 親ページ field_editable: 編集可能 field_watcher: ウォッチャー + field_watchers_count: ウォッチ数 field_content: 内容 field_group_by: グループ条件 field_sharing: 共有 diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb index c19534b78..86f450821 100644 --- a/test/functional/issues_controller_test.rb +++ b/test/functional/issues_controller_test.rb @@ -1377,6 +1377,17 @@ class IssuesControllerTest < Redmine::ControllerTest assert_equal hours.sort.reverse, hours end + def test_index_sort_by_watchers_count + Watcher.delete_all + User.find([2, 3]).each do |user| + Watcher.create!(:user => user, :watchable => Issue.find(1)) + end + Watcher.create!(:user => User.find(2), :watchable => Issue.find(2)) + get(:index, :params => {:sort => 'watchers_count:desc'}) + assert_response :success + assert_equal [2, 1, 0], issues_in_list.map {|issue| issue.watchers_count}.first(3) + end + def test_index_sort_by_user_custom_field cf = IssueCustomField. create!( diff --git a/test/unit/issue_test.rb b/test/unit/issue_test.rb index 188230022..50c6586c2 100644 --- a/test/unit/issue_test.rb +++ b/test/unit/issue_test.rb @@ -3524,4 +3524,12 @@ class IssueTest < ActiveSupport::TestCase r = Issue.like('issue today') assert_include Issue.find(7), r end + + def test_watchers_count + issue = Issue.generate! + User.find([2, 3]).each do |user| + Watcher.create!(:user => user, :watchable => issue) + end + assert_equal 2, issue.watchers_count + end end