]> source.dussan.org Git - redmine.git/commitdiff
Adds ability to filter watched issues (#846).
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Thu, 12 Feb 2009 17:35:57 +0000 (17:35 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Thu, 12 Feb 2009 17:35:57 +0000 (17:35 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2456 e93f8b46-1217-0410-a6f0-8f06a7374b81

37 files changed:
app/models/query.rb
lang/bg.yml
lang/ca.yml
lang/cs.yml
lang/da.yml
lang/de.yml
lang/en.yml
lang/es.yml
lang/fi.yml
lang/fr.yml
lang/gl.yml
lang/he.yml
lang/hu.yml
lang/it.yml
lang/ja.yml
lang/ko.yml
lang/lt.yml
lang/mk.yml
lang/nl.yml
lang/no.yml
lang/pl.yml
lang/pt-br.yml
lang/pt.yml
lang/ro.yml
lang/ru.yml
lang/sk.yml
lang/sl.yml
lang/sr.yml
lang/sv.yml
lang/th.yml
lang/tr.yml
lang/uk.yml
lang/vn.yml
lang/zh-tw.yml
lang/zh.yml
test/fixtures/watchers.yml
test/unit/query_test.rb

index 4689f5fb8b9c45966b54c5b339877ea9faac89c0..23742cfa5b57b047b8ff2196951d79bd7fd7528c 100644 (file)
@@ -165,6 +165,10 @@ class Query < ActiveRecord::Base
     end
     @available_filters["assigned_to_id"] = { :type => :list_optional, :order => 4, :values => user_values } unless user_values.empty?
     @available_filters["author_id"] = { :type => :list, :order => 5, :values => user_values } unless user_values.empty?
+    
+    if User.current.logged?
+      @available_filters["watcher_id"] = { :type => :list, :order => 15, :values => [["<< #{l(:label_me)} >>", "me"]] }
+    end
   
     if project
       # project specific filters
@@ -288,31 +292,34 @@ class Query < ActiveRecord::Base
       next if field == "subproject_id"
       v = values_for(field).clone
       next unless v and !v.empty?
-            
+      operator = operator_for(field)
+      
+      # "me" value subsitution
+      if %w(assigned_to_id author_id watcher_id).include?(field)
+        v.push(User.current.logged? ? User.current.id.to_s : "0") if v.delete("me")
+      end
+      
       sql = ''
-      is_custom_filter = false
       if field =~ /^cf_(\d+)$/
         # custom field
         db_table = CustomValue.table_name
         db_field = 'value'
         is_custom_filter = true
         sql << "#{Issue.table_name}.id IN (SELECT #{Issue.table_name}.id FROM #{Issue.table_name} LEFT OUTER JOIN #{db_table} ON #{db_table}.customized_type='Issue' AND #{db_table}.customized_id=#{Issue.table_name}.id AND #{db_table}.custom_field_id=#{$1} WHERE "
+        sql << sql_for_field(field, operator, v, db_table, db_field, true) + ')'
+      elsif field == 'watcher_id'
+        db_table = Watcher.table_name
+        db_field = 'user_id'
+        sql << "#{Issue.table_name}.id #{ operator == '=' ? 'IN' : 'NOT IN' } (SELECT #{db_table}.watchable_id FROM #{db_table} WHERE #{db_table}.watchable_type='Issue' AND "
+        sql << sql_for_field(field, '=', v, db_table, db_field) + ')'
       else
         # regular field
         db_table = Issue.table_name
         db_field = field
-        sql << '('
+        sql << '(' + sql_for_field(field, operator, v, db_table, db_field) + ')'
       end
-      
-      # "me" value subsitution
-      if %w(assigned_to_id author_id).include?(field)
-        v.push(User.current.logged? ? User.current.id.to_s : "0") if v.delete("me")
-      end
-      
-      sql = sql + sql_for_field(field, v, db_table, db_field, is_custom_filter)
-      
-      sql << ')'
       filters_clauses << sql
+      
     end if filters and valid?
     
     (filters_clauses << project_statement).join(' AND ')
@@ -320,10 +327,10 @@ class Query < ActiveRecord::Base
   
   private
   
-  # Helper method to generate the WHERE sql for a +field+ with a +value+
-  def sql_for_field(field, value, db_table, db_field, is_custom_filter)
+  # Helper method to generate the WHERE sql for a +field+, +operator+ and a +value+
+  def sql_for_field(field, operator, value, db_table, db_field, is_custom_filter=false)
     sql = ''
-    case operator_for field
+    case operator
     when "="
       sql = "#{db_table}.#{db_field} IN (" + value.collect{|val| "'#{connection.quote_string(val)}'"}.join(",") + ")"
     when "!"
index 379ff4fcc0ac802e2959d2258d93b11e5d62fd79..0079c4ab2bad39a40153bae2da92fb3e8b03d4d8 100644 (file)
@@ -706,3 +706,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index f4e5375e35dac69a373cb71ea796218e87e329c3..770cc305c4a93b3dfdde822bcfa7f3d3f3bfe682 100644 (file)
@@ -707,3 +707,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL\r
 setting_openid: Allow OpenID login and registration\r
 label_login_with_open_id_option: or login with OpenID\r
+field_watcher: Watcher\r
index 947c9e46cd9e30d8daf71edb30cd605bbc082246..bbfdfae4d0fad2510733418e2aa2531962a6f553 100644 (file)
@@ -711,3 +711,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index 910a51b116016a97c8a23f31b3d77d1aacd5b507..c07d6be882af6a546c94f6598091a686e68bc2ae 100644 (file)
@@ -708,3 +708,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index fef1f79692169b3387328ec4f634629aa61fc2fd..366b7dd068398c4dd42926f88c92bced09aad593 100644 (file)
@@ -709,3 +709,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index 1bb9fff85526a0b4ae52c86b910ed9d87c9f8efe..f4f59df2294258ab9ce3b8cf96de6ea3ca5d2bd2 100644 (file)
@@ -188,6 +188,7 @@ field_default_value: Default value
 field_comments_sorting: Display comments
 field_parent_title: Parent page
 field_editable: Editable
+field_watcher: Watcher
 
 setting_app_title: Application title
 setting_app_subtitle: Application subtitle
index 52eac46caee6245317922e2a1ef5383f44e2d085..67f1034162a1001e0004176bfec87b66320b7801 100644 (file)
@@ -691,3 +691,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index 973ff7ee949551c75fc4e43c7d82a889c1d64f6e..65478776d5c167bac6fdeb4232f5f604358dc1fd 100644 (file)
@@ -706,3 +706,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index 71f44de8fd28f2bef3ec1d0fe6d8bf2e339cd75b..4a7c517082273d781da3644696fbbadddad88c7d 100644 (file)
@@ -188,6 +188,7 @@ field_comments_sorting: Afficher les commentaires
 field_parent_title: Page parent
 field_editable: Modifiable
 field_identity_url: URL OpenID
+field_watcher: Observateur
 
 setting_app_title: Titre de l'application
 setting_app_subtitle: Sous-titre de l'application
index 119e86063310119cb4ddaaedffbc10eb31e375c2..701fe22c79e98b7e2d09538a8c22dc5e5b63458c 100644 (file)
@@ -691,3 +691,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL\r
 setting_openid: Allow OpenID login and registration\r
 label_login_with_open_id_option: or login with OpenID\r
+field_watcher: Watcher\r
index dba80c698767063a147e02e7ce3bc6d508208ad5..7a1519ae025f5176183b616bf40a803108e0b003 100644 (file)
@@ -706,3 +706,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index bdf110d7e5fa137af44ce8cf541a8e2ea6a28748..697b26a1cd20a90c4f77e8a2b81474cdf75c99c3 100644 (file)
@@ -707,3 +707,4 @@ setting_repository_log_display_limit: Maximum hány revízió jelenjen meg a fá
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index 07e41cbb121c1f740bab853b2b30d5afebe03f1a..418f3529d693463547cc3edbd200af561e270bf3 100644 (file)
@@ -706,3 +706,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index b450380d67552f6b4815626e4f98f5acfd89b444..b92287678f0b42827c709a257f268f9f0ae9d975 100644 (file)
@@ -707,3 +707,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index fd8ba9f95a44ad3a4f8972fd35f02a4385588f7c..008fe866cf647e68699aedd4b50f78fc8a193e4f 100644 (file)
@@ -706,3 +706,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index 6bcd87b924420a978969eb94384a6278bfb83d49..0a732a59afdd15baecfd57095610aa6caf622565 100644 (file)
@@ -708,3 +708,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index b2e7d4bea840b67576d5510d38a8a07e3a828a30..269d4dddbd675a7ad42d54f120b547c924f9de04 100644 (file)
@@ -708,3 +708,4 @@ text_custom_field_possible_values_info: 'One line for each value'
 field_identity_url: OpenID URL\r
 setting_openid: Allow OpenID login and registration\r
 label_login_with_open_id_option: or login with OpenID\r
+field_watcher: Watcher\r
index 122779fecca2da5b705a20f62982a18804aa7f6d..859972ee007a19717b6c5a4d294ce7c297278b66 100644 (file)
@@ -691,3 +691,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index e00e3650140535d4381fdf377c5d1368fb6d8bc2..10bf48427966947a00c1e4cbabf9afe88df47e96 100644 (file)
@@ -707,3 +707,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index f8d6a5ef9933d71b01eaf466648516c767204cd7..1ca3da32cb488e49ccfbb209481914225fd84c25 100644 (file)
@@ -725,3 +725,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index eb18eb330c754083addaec8dc122918bcae576d7..073c8e377de1adcdf8d8313279e6f0b4f153078e 100644 (file)
@@ -707,3 +707,4 @@ setting_repository_log_display_limit: Número máximo de revisões exibidas no a
 field_identity_url: OpenID URL\r
 setting_openid: Allow OpenID login and registration\r
 label_login_with_open_id_option: or login with OpenID\r
+field_watcher: Watcher\r
index cf76ccb1178802c59af9912a2e4e4046f50a3dd6..7836f0fc617dc2c0e50903c4a1afbbe197488b12 100644 (file)
@@ -708,3 +708,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index 4c6f3cbaae16807964ec244834f7f08a6772319d..ac06ccda5b19ab00dfa1efeac58db60854105216 100644 (file)
@@ -706,3 +706,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index 1d067286b049f47222a5b77607362f46a1cb37a5..87be71e2c9a1107cdddb929c5b8029590738610b 100644 (file)
@@ -741,3 +741,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index 4d41041eb72f1e488a01c5ded3a0c7c79e6e0713..351173a32fa9230358e38845b930414604e0052d 100644 (file)
@@ -711,3 +711,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL\r
 setting_openid: Allow OpenID login and registration\r
 label_login_with_open_id_option: or login with OpenID\r
+field_watcher: Watcher\r
index ea142ce4a4be0c6e00bdabf54821eb47072ab692..bd51bda3526fd749867edf71c23fa640fb75f940 100644 (file)
@@ -708,3 +708,4 @@ text_custom_field_possible_values_info: 'One line for each value'
 field_identity_url: OpenID URL\r
 setting_openid: Allow OpenID login and registration\r
 label_login_with_open_id_option: or login with OpenID\r
+field_watcher: Watcher\r
index 86ca019ec025604d0cf83e9ad49e84d4d3c7a276..7455d20e083bb9d176d1373ea1dccfe315e26eb5 100644 (file)
@@ -707,3 +707,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index ad20e0d3a5c021277a9b01cfe95e525cd52c8bd9..884dd16a4e912f593d5011483411061cb3e2e55a 100644 (file)
@@ -708,3 +708,4 @@ enumeration_activities: Aktiviteter (tidsuppföljning)
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index d1910c727810bf356bc355e0659e3e2a1c0cbdb9..7cb03a1b8b163e6dfc10be883658fcaddb4bb8f7 100644 (file)
@@ -709,3 +709,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index cc3d67fc893d86cb05847d05e0c0d5ac7697649c..8766b11270ac3a2ef9efd63cec43daeaca76b032 100644 (file)
@@ -707,3 +707,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index 779c94386ea299977f9d698c70bb927ce4bcb1f3..235bbadb86b0a5995fca2c4c87978b4874ba6b2b 100644 (file)
@@ -708,3 +708,4 @@ text_custom_field_possible_values_info: 'One line for each value'
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index 75f294edccbd48e0176841efb9712350db1d5cd7..e4f4fd47c61888a934140d16e74a10c0c6a0f0cb 100644 (file)
@@ -709,3 +709,4 @@ setting_repository_log_display_limit: Maximum number of revisions displayed on f
 field_identity_url: OpenID URL\r
 setting_openid: Allow OpenID login and registration\r
 label_login_with_open_id_option: or login with OpenID\r
+field_watcher: Watcher\r
index 598023c0ce62653abeef413108d8ff87930cf101..9f3788a85c6caa90e0bc735ccb67b55a0978ae74 100644 (file)
@@ -709,3 +709,4 @@ enumeration_activities: 活動 (時間追蹤)
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index cac4377b678a3be60b7c84a532c33fb7d7f20fa0..4be80b3bba0752e185962338c0e49b4ea89ae6e9 100644 (file)
@@ -709,3 +709,4 @@ enumeration_activities: 活动(时间跟踪)
 field_identity_url: OpenID URL
 setting_openid: Allow OpenID login and registration
 label_login_with_open_id_option: or login with OpenID
+field_watcher: Watcher
index 6c8cdfb5e59ea8748a7390488430ffdc0371aa93..803b03e5ecc5fb97410e6cf40af85716be2904c7 100644 (file)
@@ -7,4 +7,8 @@ watchers_002:
   watchable_type: Message
   watchable_id: 1
   user_id: 1
+watchers_003: 
+  watchable_type: Issue
+  watchable_id: 2
+  user_id: 1
   
\ No newline at end of file
index 3bdc4a7a2f630ab53a535a3dd2f5a919385473f4..d568604c3509f489a03e23cf8a1fab93ecedf67b 100644 (file)
@@ -18,7 +18,7 @@
 require File.dirname(__FILE__) + '/../test_helper'
 
 class QueryTest < Test::Unit::TestCase
-  fixtures :projects, :enabled_modules, :users, :members, :roles, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values, :versions, :queries
+  fixtures :projects, :enabled_modules, :users, :members, :roles, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :watchers, :custom_fields, :custom_values, :versions, :queries
 
   def test_custom_fields_for_all_projects_should_be_available_in_global_queries
     query = Query.new(:project => nil, :name => '_')
@@ -162,6 +162,26 @@ class QueryTest < Test::Unit::TestCase
     find_issues_with_query(query)
   end
   
+  def test_filter_watched_issues
+    User.current = User.find(1)
+    query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '=', :values => ['me']}})
+    result = find_issues_with_query(query)
+    assert_not_nil result
+    assert !result.empty?
+    assert_equal Issue.visible.watched_by(User.current).sort_by(&:id), result.sort_by(&:id)
+    User.current = nil
+  end
+  
+  def test_filter_unwatched_issues
+    User.current = User.find(1)
+    query = Query.new(:name => '_', :filters => { 'watcher_id' => {:operator => '!', :values => ['me']}})
+    result = find_issues_with_query(query)
+    assert_not_nil result
+    assert !result.empty?
+    assert_equal((Issue.visible - Issue.watched_by(User.current)).sort_by(&:id).size, result.sort_by(&:id).size)
+    User.current = nil
+  end
+  
   def test_default_columns
     q = Query.new
     assert !q.columns.empty?