From b9d7c22297206eca2562b94a32390725b57ad75e Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Thu, 4 Oct 2012 18:10:41 +0000 Subject: [PATCH] Adds no_issue_in_project operator for relations filter (#3265). git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@10559 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/models/query.rb | 14 ++++++++------ config/locales/en.yml | 1 + config/locales/fr.yml | 1 + public/javascripts/application.js | 1 + test/unit/query_test.rb | 16 ++++++++++++++++ 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/app/models/query.rb b/app/models/query.rb index dfb00825d..fb708dfb3 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -115,7 +115,8 @@ class Query < ActiveRecord::Base "~" => :label_contains, "!~" => :label_not_contains, "=p" => :label_any_issues_in_project, - "=!p" => :label_any_issues_not_in_project} + "=!p" => :label_any_issues_not_in_project, + "!p" => :label_no_issues_in_project} cattr_reader :operators @@ -129,7 +130,7 @@ class Query < ActiveRecord::Base :text => [ "~", "!~", "!*", "*" ], :integer => [ "=", ">=", "<=", "><", "!*", "*" ], :float => [ "=", ">=", "<=", "><", "!*", "*" ], - :relation => ["=", "=p", "=!p", "!*", "*"]} + :relation => ["=", "=p", "=!p", "!p", "!*", "*"]} cattr_reader :operators_by_filter_type @@ -807,14 +808,15 @@ class Query < ActiveRecord::Base when "=", "!" op = (operator == "=" ? 'IN' : 'NOT IN') "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name} WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = #{value.first.to_i})" - when "=p", "=!p" - op = (operator == "=p" ? '=' : '<>') - "#{Issue.table_name}.id IN (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name}, #{Issue.table_name} relissues WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = relissues.id AND relissues.project_id #{op} #{value.first.to_i})" + when "=p", "=!p", "!p" + op = (operator == "!p" ? 'NOT IN' : 'IN') + comp = (operator == "=!p" ? '<>' : '=') + "#{Issue.table_name}.id #{op} (SELECT DISTINCT #{IssueRelation.table_name}.#{join_column} FROM #{IssueRelation.table_name}, #{Issue.table_name} relissues WHERE #{IssueRelation.table_name}.relation_type = '#{connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = relissues.id AND relissues.project_id #{comp} #{value.first.to_i})" end if relation_options[:sym] == field && !options[:reverse] sqls = [sql, sql_for_relations(field, operator, value, :reverse => true)] - sqls.join(["!", "!*"].include?(operator) ? " AND " : " OR ") + sqls.join(["!", "!*", "!p"].include?(operator) ? " AND " : " OR ") else sql end diff --git a/config/locales/en.yml b/config/locales/en.yml index 9b1da6153..7fb787047 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -674,6 +674,7 @@ en: label_not_contains: doesn't contain label_any_issues_in_project: any issues in project label_any_issues_not_in_project: any issues not in project + label_no_issues_in_project: no issues in project label_day_plural: days label_repository: Repository label_repository_new: New repository diff --git a/config/locales/fr.yml b/config/locales/fr.yml index ba9311bc5..ca35df67b 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -664,6 +664,7 @@ fr: label_not_contains: ne contient pas label_any_issues_in_project: une demande du projet label_any_issues_not_in_project: une demande hors du projet + label_no_issues_in_project: aucune demande du projet label_day_plural: jours label_repository: Dépôt label_repository_new: Nouveau dépôt diff --git a/public/javascripts/application.js b/public/javascripts/application.js index 916a53709..0222dcf01 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -260,6 +260,7 @@ function toggleOperator(field) { break; case "=p": case "=!p": + case "!p": enableValues(field, [1]); break; default: diff --git a/test/unit/query_test.rb b/test/unit/query_test.rb index 53e2f5f79..3513e5a68 100644 --- a/test/unit/query_test.rb +++ b/test/unit/query_test.rb @@ -672,6 +672,22 @@ class QueryTest < ActiveSupport::TestCase assert_equal [1], find_issues_with_query(query).map(&:id).sort end + def test_filter_on_relations_with_no_issues_in_a_project + IssueRelation.delete_all + with_settings :cross_project_issue_relations => '1' do + IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Project.find(2).issues.first) + IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(2), :issue_to => Project.find(3).issues.first) + IssueRelation.create!(:relation_type => "relates", :issue_to => Project.find(2).issues.first, :issue_from => Issue.find(3)) + end + + query = Query.new(:name => '_') + query.filters = {"relates" => {:operator => '!p', :values => ['2']}} + ids = find_issues_with_query(query).map(&:id).sort + assert_include 2, ids + assert_not_include 1, ids + assert_not_include 3, ids + end + def test_filter_on_relations_with_no_issues IssueRelation.delete_all IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2))