##// END OF EJS Templates
Adds issue filters on parent/subtasks (#6118)....
Jean-Philippe Lang -
r13922:98f2b30ac587
parent child
Show More
@@ -24,7 +24,7 module QueriesHelper
24 ungrouped = []
24 ungrouped = []
25 grouped = {}
25 grouped = {}
26 query.available_filters.map do |field, field_options|
26 query.available_filters.map do |field, field_options|
27 if field_options[:type] == :relation
27 if [:tree, :relation].include?(field_options[:type])
28 group = :label_related_issues
28 group = :label_related_issues
29 elsif field =~ /^(.+)\./
29 elsif field =~ /^(.+)\./
30 # association filters
30 # association filters
@@ -241,6 +241,8 class IssueQuery < Query
241 IssueRelation::TYPES.each do |relation_type, options|
241 IssueRelation::TYPES.each do |relation_type, options|
242 add_available_filter relation_type, :type => :relation, :label => options[:name]
242 add_available_filter relation_type, :type => :relation, :label => options[:name]
243 end
243 end
244 add_available_filter "parent_id", :type => :tree, :label => :field_parent_issue
245 add_available_filter "child_id", :type => :tree, :label => :label_subtask_plural
244
246
245 Tracker.disabled_core_fields(trackers).each {|field|
247 Tracker.disabled_core_fields(trackers).each {|field|
246 delete_available_filter field
248 delete_available_filter field
@@ -451,6 +453,47 class IssueQuery < Query
451 "#{Issue.table_name}.is_private #{op} (#{va})"
453 "#{Issue.table_name}.is_private #{op} (#{va})"
452 end
454 end
453
455
456 def sql_for_parent_id_field(field, operator, value)
457 case operator
458 when "="
459 "#{Issue.table_name}.parent_id = #{value.first.to_i}"
460 when "~"
461 root_id, lft, rgt = Issue.where(:id => value.first.to_i).pluck(:root_id, :lft, :rgt).first
462 if root_id && lft && rgt
463 "#{Issue.table_name}.root_id = #{root_id} AND #{Issue.table_name}.lft > #{lft} AND #{Issue.table_name}.rgt < #{rgt}"
464 else
465 "1=0"
466 end
467 when "!*"
468 "#{Issue.table_name}.parent_id IS NULL"
469 when "*"
470 "#{Issue.table_name}.parent_id IS NOT NULL"
471 end
472 end
473
474 def sql_for_child_id_field(field, operator, value)
475 case operator
476 when "="
477 parent_id = Issue.where(:id => value.first.to_i).pluck(:parent_id).first
478 if parent_id
479 "#{Issue.table_name}.id = #{parent_id}"
480 else
481 "1=0"
482 end
483 when "~"
484 root_id, lft, rgt = Issue.where(:id => value.first.to_i).pluck(:root_id, :lft, :rgt).first
485 if root_id && lft && rgt
486 "#{Issue.table_name}.root_id = #{root_id} AND #{Issue.table_name}.lft < #{lft} AND #{Issue.table_name}.rgt > #{rgt}"
487 else
488 "1=0"
489 end
490 when "!*"
491 "#{Issue.table_name}.rgt - #{Issue.table_name}.lft = 1"
492 when "*"
493 "#{Issue.table_name}.rgt - #{Issue.table_name}.lft > 1"
494 end
495 end
496
454 def sql_for_relations(field, operator, value, options={})
497 def sql_for_relations(field, operator, value, options={})
455 relation_options = IssueRelation::TYPES[field]
498 relation_options = IssueRelation::TYPES[field]
456 return relation_options unless relation_options
499 return relation_options unless relation_options
@@ -216,7 +216,8 class Query < ActiveRecord::Base
216 :text => [ "~", "!~", "!*", "*" ],
216 :text => [ "~", "!~", "!*", "*" ],
217 :integer => [ "=", ">=", "<=", "><", "!*", "*" ],
217 :integer => [ "=", ">=", "<=", "><", "!*", "*" ],
218 :float => [ "=", ">=", "<=", "><", "!*", "*" ],
218 :float => [ "=", ">=", "<=", "><", "!*", "*" ],
219 :relation => ["=", "=p", "=!p", "!p", "!*", "*"]
219 :relation => ["=", "=p", "=!p", "!p", "!*", "*"],
220 :tree => ["=", "~", "!*", "*"]
220 }
221 }
221
222
222 class_attribute :available_columns
223 class_attribute :available_columns
@@ -217,6 +217,7 function buildFilterRow(field, operator, values) {
217 break;
217 break;
218 case "integer":
218 case "integer":
219 case "float":
219 case "float":
220 case "tree":
220 tr.find('td.values').append(
221 tr.find('td.values').append(
221 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="6" class="value" /></span>' +
222 '<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="6" class="value" /></span>' +
222 ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="6" class="value" /></span>'
223 ' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="6" class="value" /></span>'
@@ -879,6 +879,46 class QueryTest < ActiveSupport::TestCase
879 assert_equal [issue1], find_issues_with_query(query)
879 assert_equal [issue1], find_issues_with_query(query)
880 end
880 end
881
881
882 def test_filter_on_parent
883 Issue.delete_all
884 parent = Issue.generate_with_descendants!
885
886
887 query = IssueQuery.new(:name => '_')
888 query.filters = {"parent_id" => {:operator => '=', :values => [parent.id.to_s]}}
889 assert_equal parent.children.map(&:id).sort, find_issues_with_query(query).map(&:id).sort
890
891 query.filters = {"parent_id" => {:operator => '~', :values => [parent.id.to_s]}}
892 assert_equal parent.descendants.map(&:id).sort, find_issues_with_query(query).map(&:id).sort
893
894 query.filters = {"parent_id" => {:operator => '*', :values => ['']}}
895 assert_equal parent.descendants.map(&:id).sort, find_issues_with_query(query).map(&:id).sort
896
897 query.filters = {"parent_id" => {:operator => '!*', :values => ['']}}
898 assert_equal [parent.id], find_issues_with_query(query).map(&:id).sort
899 end
900
901 def test_filter_on_child
902 Issue.delete_all
903 parent = Issue.generate_with_descendants!
904 child, leaf = parent.children.sort_by(&:id)
905 grandchild = child.children.first
906
907
908 query = IssueQuery.new(:name => '_')
909 query.filters = {"child_id" => {:operator => '=', :values => [grandchild.id.to_s]}}
910 assert_equal [child.id], find_issues_with_query(query).map(&:id).sort
911
912 query.filters = {"child_id" => {:operator => '~', :values => [grandchild.id.to_s]}}
913 assert_equal [parent, child].map(&:id).sort, find_issues_with_query(query).map(&:id).sort
914
915 query.filters = {"child_id" => {:operator => '*', :values => ['']}}
916 assert_equal [parent, child].map(&:id).sort, find_issues_with_query(query).map(&:id).sort
917
918 query.filters = {"child_id" => {:operator => '!*', :values => ['']}}
919 assert_equal [grandchild, leaf].map(&:id).sort, find_issues_with_query(query).map(&:id).sort
920 end
921
882 def test_statement_should_be_nil_with_no_filters
922 def test_statement_should_be_nil_with_no_filters
883 q = IssueQuery.new(:name => '_')
923 q = IssueQuery.new(:name => '_')
884 q.filters = {}
924 q.filters = {}
General Comments 0
You need to be logged in to leave comments. Login now