Feature #16621 » filter-relations-d4e1f70-r14601.patch
| app/models/issue_query.rb | ||
|---|---|---|
| 529 | 529 |
op = (operator == "!p" ? 'NOT IN' : 'IN') |
| 530 | 530 |
comp = (operator == "=!p" ? '<>' : '=') |
| 531 | 531 |
"#{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 = '#{self.class.connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = relissues.id AND relissues.project_id #{comp} #{value.first.to_i})"
|
| 532 |
when "!|c", "*&o" |
|
| 533 |
op = (operator == "!|c" ? 'NOT IN' : 'IN') |
|
| 534 |
"#{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 = '#{self.class.connection.quote_string(relation_type)}' AND #{IssueRelation.table_name}.#{target_join_column} = relissues.id AND relissues.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{self.class.connection.quoted_false}))"
|
|
| 532 | 535 |
end |
| 533 | 536 | |
| 534 | 537 |
if relation_options[:sym] == field && !options[:reverse] |
| app/models/query.rb | ||
|---|---|---|
| 201 | 201 |
"!~" => :label_not_contains, |
| 202 | 202 |
"=p" => :label_any_issues_in_project, |
| 203 | 203 |
"=!p" => :label_any_issues_not_in_project, |
| 204 |
"!p" => :label_no_issues_in_project |
|
| 204 |
"!p" => :label_no_issues_in_project, |
|
| 205 |
"*&o" => :label_any_open_issues, |
|
| 206 |
"!|c" => :label_none_or_closed_issues |
|
| 205 | 207 |
} |
| 206 | 208 | |
| 207 | 209 |
class_attribute :operators_by_filter_type |
| ... | ... | |
| 216 | 218 |
:text => [ "~", "!~", "!*", "*" ], |
| 217 | 219 |
:integer => [ "=", ">=", "<=", "><", "!*", "*" ], |
| 218 | 220 |
:float => [ "=", ">=", "<=", "><", "!*", "*" ], |
| 219 |
:relation => ["=", "=p", "=!p", "!p", "!*", "*"], |
|
| 221 |
:relation => ["=", "=p", "=!p", "!p", "*&o", "!|c", "!*", "*"],
|
|
| 220 | 222 |
:tree => ["=", "~", "!*", "*"] |
| 221 | 223 |
} |
| 222 | 224 | |
| ... | ... | |
| 278 | 280 |
# filter requires one or more values |
| 279 | 281 |
(values_for(field) and !values_for(field).first.blank?) or |
| 280 | 282 |
# filter doesn't require any value |
| 281 |
["o", "c", "!*", "*", "t", "ld", "w", "lw", "l2w", "m", "lm", "y"].include? operator_for(field) |
|
| 283 |
["o", "c", "!*", "*", "t", "ld", "w", "lw", "l2w", "m", "lm", "y", "*&o", "!|c"].include? operator_for(field)
|
|
| 282 | 284 |
end if filters |
| 283 | 285 |
end |
| 284 | 286 | |
| config/locales/en-GB.yml | ||
|---|---|---|
| 1065 | 1065 |
permission_view_private_notes: View private notes |
| 1066 | 1066 |
permission_set_notes_private: Set notes as private |
| 1067 | 1067 |
label_no_issues_in_project: no issues in project |
| 1068 |
label_any_open_issues: any open issues |
|
| 1069 |
label_none_or_closed_issues: none or closed issues |
|
| 1068 | 1070 |
label_any: all |
| 1069 | 1071 |
label_last_n_weeks: last %{count} weeks
|
| 1070 | 1072 |
setting_cross_project_subtasks: Allow cross-project subtasks |
| config/locales/en.yml | ||
|---|---|---|
| 710 | 710 |
label_any_issues_in_project: any issues in project |
| 711 | 711 |
label_any_issues_not_in_project: any issues not in project |
| 712 | 712 |
label_no_issues_in_project: no issues in project |
| 713 |
label_any_open_issues: any open issues |
|
| 714 |
label_none_or_closed_issues: none or closed issues |
|
| 713 | 715 |
label_day_plural: days |
| 714 | 716 |
label_repository: Repository |
| 715 | 717 |
label_repository_new: New repository |
| public/javascripts/application.js | ||
|---|---|---|
| 275 | 275 |
case "y": |
| 276 | 276 |
case "o": |
| 277 | 277 |
case "c": |
| 278 |
case "!|c": |
|
| 279 |
case "*&o": |
|
| 278 | 280 |
enableValues(field, []); |
| 279 | 281 |
break; |
| 280 | 282 |
case "><": |
| test/unit/query_test.rb | ||
|---|---|---|
| 845 | 845 |
assert_not_include 3, ids |
| 846 | 846 |
end |
| 847 | 847 | |
| 848 |
def test_filter_on_relations_with_any_open_issues |
|
| 849 |
IssueRelation.delete_all |
|
| 850 |
# Issue 1 is blocked by 8, which is closed |
|
| 851 |
IssueRelation.create!(:relation_type => "blocked", :issue_from => Issue.find(1), :issue_to => Issue.find(8)) |
|
| 852 |
# Issue 2 is blocked by 3, which is open |
|
| 853 |
IssueRelation.create!(:relation_type => "blocked", :issue_from => Issue.find(2), :issue_to => Issue.find(3)) |
|
| 854 | ||
| 855 |
query = IssueQuery.new(:name => '_') |
|
| 856 |
query.filters = {"blocked" => {:operator => "*&o", :values => ['']}}
|
|
| 857 |
ids = find_issues_with_query(query).map(&:id) |
|
| 858 |
assert_equal [], ids & [1] |
|
| 859 |
assert_include 2, ids |
|
| 860 |
end |
|
| 861 | ||
| 862 |
def test_filter_on_relations_with_none_or_closed_issues |
|
| 863 |
IssueRelation.delete_all |
|
| 864 |
# Issue 1 is blocked by 8, which is closed |
|
| 865 |
IssueRelation.create!(:relation_type => "blocked", :issue_from => Issue.find(1), :issue_to => Issue.find(8)) |
|
| 866 |
# Issue 2 is blocked by 3, which is open |
|
| 867 |
IssueRelation.create!(:relation_type => "blocked", :issue_from => Issue.find(2), :issue_to => Issue.find(3)) |
|
| 868 | ||
| 869 |
query = IssueQuery.new(:name => '_') |
|
| 870 |
query.filters = {"blocked" => {:operator => "!|c", :values => ['']}}
|
|
| 871 |
ids = find_issues_with_query(query).map(&:id) |
|
| 872 |
assert_equal [], ids & [2] |
|
| 873 |
assert_include 1, ids |
|
| 874 |
end |
|
| 875 | ||
| 848 | 876 |
def test_filter_on_relations_with_no_issues |
| 849 | 877 |
IssueRelation.delete_all |
| 850 | 878 |
IssueRelation.create!(:relation_type => "relates", :issue_from => Issue.find(1), :issue_to => Issue.find(2)) |
- « Previous
- 1
- 2
- 3
- Next »