Feature #15029 ยป redmine_add_relation_filters.patch
app/controllers/issues_controller.rb | ||
---|---|---|
1 | ||
1 | 2 |
# Redmine - project management software |
2 | 3 |
# Copyright (C) 2006-2013 Jean-Philippe Lang |
3 | 4 |
# |
app/models/issue_query.rb | ||
---|---|---|
66 | 66 |
versions = [] |
67 | 67 |
categories = [] |
68 | 68 |
issue_custom_fields = [] |
69 |
|
|
69 | ||
70 | 70 |
if project |
71 | 71 |
principals += project.principals.sort |
72 | 72 |
unless project.leaf? |
... | ... | |
389 | 389 |
op = (operator == "!p" ? 'NOT IN' : 'IN') |
390 | 390 |
comp = (operator == "=!p" ? '<>' : '=') |
391 | 391 |
"#{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})" |
392 |
when "!|c", "*&o" |
|
393 |
op = (operator == "!|c" ? 'NOT IN' : 'IN') |
|
394 |
"#{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.status_id IN (SELECT id FROM #{IssueStatus.table_name} WHERE is_closed=#{connection.quoted_false}))" |
|
392 | 395 |
end |
393 | 396 | |
394 | 397 |
if relation_options[:sym] == field && !options[:reverse] |
app/models/query.rb | ||
---|---|---|
159 | 159 |
"!~" => :label_not_contains, |
160 | 160 |
"=p" => :label_any_issues_in_project, |
161 | 161 |
"=!p" => :label_any_issues_not_in_project, |
162 |
"!p" => :label_no_issues_in_project |
|
162 |
"!p" => :label_no_issues_in_project, |
|
163 |
"*&o" => :label_any_open_issues, |
|
164 |
"!|c" => :label_none_or_closed_issues |
|
163 | 165 |
} |
164 | 166 | |
165 | 167 |
class_attribute :operators_by_filter_type |
... | ... | |
174 | 176 |
:text => [ "~", "!~", "!*", "*" ], |
175 | 177 |
:integer => [ "=", ">=", "<=", "><", "!*", "*" ], |
176 | 178 |
:float => [ "=", ">=", "<=", "><", "!*", "*" ], |
177 |
:relation => ["=", "=p", "=!p", "!p", "!*", "*"] |
|
179 |
:relation => ["=", "=p", "=!p", "!p", "*&o", "!|c", "!*", "*"]
|
|
178 | 180 |
} |
179 | 181 | |
180 | 182 |
class_attribute :available_columns |
... | ... | |
233 | 235 |
# filter requires one or more values |
234 | 236 |
(values_for(field) and !values_for(field).first.blank?) or |
235 | 237 |
# filter doesn't require any value |
236 |
["o", "c", "!*", "*", "t", "ld", "w", "lw", "l2w", "m", "lm", "y"].include? operator_for(field) |
|
238 |
["o", "c", "!*", "*", "t", "ld", "w", "lw", "l2w", "m", "lm", "y", "*&o", "!|c"].include? operator_for(field)
|
|
237 | 239 |
end if filters |
238 | 240 |
end |
239 | 241 |
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 | ||
---|---|---|
683 | 683 |
label_any_issues_in_project: any issues in project |
684 | 684 |
label_any_issues_not_in_project: any issues not in project |
685 | 685 |
label_no_issues_in_project: no issues in project |
686 |
label_any_open_issues: any open issues |
|
687 |
label_none_or_closed_issues: none or closed issues |
|
686 | 688 |
label_day_plural: days |
687 | 689 |
label_repository: Repository |
688 | 690 |
label_repository_new: New repository |
public/javascripts/application.js | ||
---|---|---|
251 | 251 |
case "y": |
252 | 252 |
case "o": |
253 | 253 |
case "c": |
254 |
case "!|c": |
|
255 |
case "*&o": |
|
254 | 256 |
enableValues(field, []); |
255 | 257 |
break; |
256 | 258 |
case "><": |
... | ... | |
551 | 553 |
function setupAjaxIndicator() { |
552 | 554 | |
553 | 555 |
$('#ajax-indicator').bind('ajaxSend', function(event, xhr, settings) { |
554 |
|
|
556 | ||
555 | 557 |
if ($('.ajax-loading').length === 0 && settings.contentType != 'application/octet-stream') { |
556 | 558 |
$('#ajax-indicator').show(); |
557 | 559 |
} |
558 | 560 |
}); |
559 |
|
|
561 | ||
560 | 562 |
$('#ajax-indicator').bind('ajaxStop', function() { |
561 | 563 |
$('#ajax-indicator').hide(); |
562 | 564 |
}); |