mirror of
https://github.com/redmine/redmine.git
synced 2025-11-18 03:00:52 +01:00
Filter by issue id (#4806).
A shortcut is added to the context menu to filter the selected issues. git-svn-id: http://svn.redmine.org/redmine/trunk@15371 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
@@ -245,6 +245,8 @@ class IssueQuery < Query
|
|||||||
add_available_filter "parent_id", :type => :tree, :label => :field_parent_issue
|
add_available_filter "parent_id", :type => :tree, :label => :field_parent_issue
|
||||||
add_available_filter "child_id", :type => :tree, :label => :label_subtask_plural
|
add_available_filter "child_id", :type => :tree, :label => :label_subtask_plural
|
||||||
|
|
||||||
|
add_available_filter "issue_id", :type => :integer, :label => :label_issue
|
||||||
|
|
||||||
Tracker.disabled_core_fields(trackers).each {|field|
|
Tracker.disabled_core_fields(trackers).each {|field|
|
||||||
delete_available_filter field
|
delete_available_filter field
|
||||||
}
|
}
|
||||||
@@ -509,6 +511,15 @@ class IssueQuery < Query
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def sql_for_issue_id_field(field, operator, value)
|
||||||
|
ids = value.first.to_s.scan(/\d+/).map(&:to_i).join(",")
|
||||||
|
if ids.present?
|
||||||
|
"#{Issue.table_name}.id IN (#{ids})"
|
||||||
|
else
|
||||||
|
"1=0"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def sql_for_relations(field, operator, value, options={})
|
def sql_for_relations(field, operator, value, options={})
|
||||||
relation_options = IssueRelation::TYPES[field]
|
relation_options = IssueRelation::TYPES[field]
|
||||||
return relation_options unless relation_options
|
return relation_options unless relation_options
|
||||||
|
|||||||
@@ -264,9 +264,9 @@ class Query < ActiveRecord::Base
|
|||||||
if values_for(field)
|
if values_for(field)
|
||||||
case type_for(field)
|
case type_for(field)
|
||||||
when :integer
|
when :integer
|
||||||
add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^[+-]?\d+$/) }
|
add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/\A[+-]?\d+(,[+-]?\d+)*\z/) }
|
||||||
when :float
|
when :float
|
||||||
add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/^[+-]?\d+(\.\d*)?$/) }
|
add_filter_error(field, :invalid) if values_for(field).detect {|v| v.present? && !v.match(/\A[+-]?\d+(\.\d*)?\z/) }
|
||||||
when :date, :date_past
|
when :date, :date_past
|
||||||
case operator_for(field)
|
case operator_for(field)
|
||||||
when "=", ">=", "<=", "><"
|
when "=", ">=", "<=", "><"
|
||||||
@@ -771,10 +771,15 @@ class Query < ActiveRecord::Base
|
|||||||
when :date, :date_past
|
when :date, :date_past
|
||||||
sql = date_clause(db_table, db_field, parse_date(value.first), parse_date(value.first), is_custom_filter)
|
sql = date_clause(db_table, db_field, parse_date(value.first), parse_date(value.first), is_custom_filter)
|
||||||
when :integer
|
when :integer
|
||||||
|
int_values = value.first.to_s.scan(/[+-]?\d+/).map(&:to_i).join(",")
|
||||||
|
if int_values.present?
|
||||||
if is_custom_filter
|
if is_custom_filter
|
||||||
sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) = #{value.first.to_i})"
|
sql = "(#{db_table}.#{db_field} <> '' AND CAST(CASE #{db_table}.#{db_field} WHEN '' THEN '0' ELSE #{db_table}.#{db_field} END AS decimal(30,3)) IN (#{int_values}))"
|
||||||
else
|
else
|
||||||
sql = "#{db_table}.#{db_field} = #{value.first.to_i}"
|
sql = "#{db_table}.#{db_field} IN (#{int_values})"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
sql = "1=0"
|
||||||
end
|
end
|
||||||
when :float
|
when :float
|
||||||
if is_custom_filter
|
if is_custom_filter
|
||||||
|
|||||||
@@ -133,6 +133,11 @@
|
|||||||
<li><%= watcher_link(@issues, User.current) %></li>
|
<li><%= watcher_link(@issues, User.current) %></li>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<% unless @issue %>
|
||||||
|
<li><%= context_menu_link l(:button_filter), _project_issues_path(@project, :set_filter => 1, :issue_id => @issue_ids.join(",")),
|
||||||
|
:class => 'icon-list' %></li>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<% if @issue.present? %>
|
<% if @issue.present? %>
|
||||||
<% if @can[:log_time] -%>
|
<% if @can[:log_time] -%>
|
||||||
<li><%= context_menu_link l(:button_log_time), new_issue_time_entry_path(@issue),
|
<li><%= context_menu_link l(:button_log_time), new_issue_time_entry_path(@issue),
|
||||||
|
|||||||
@@ -1044,6 +1044,7 @@ en:
|
|||||||
button_close: Close
|
button_close: Close
|
||||||
button_reopen: Reopen
|
button_reopen: Reopen
|
||||||
button_import: Import
|
button_import: Import
|
||||||
|
button_filter: Filter
|
||||||
|
|
||||||
status_active: active
|
status_active: active
|
||||||
status_registered: registered
|
status_registered: registered
|
||||||
|
|||||||
@@ -1054,6 +1054,7 @@ fr:
|
|||||||
button_close: Fermer
|
button_close: Fermer
|
||||||
button_reopen: Réouvrir
|
button_reopen: Réouvrir
|
||||||
button_import: Importer
|
button_import: Importer
|
||||||
|
button_filter: Filtrer
|
||||||
|
|
||||||
status_active: actif
|
status_active: actif
|
||||||
status_registered: enregistré
|
status_registered: enregistré
|
||||||
|
|||||||
@@ -219,8 +219,8 @@ function buildFilterRow(field, operator, values) {
|
|||||||
case "float":
|
case "float":
|
||||||
case "tree":
|
case "tree":
|
||||||
tr.find('td.values').append(
|
tr.find('td.values').append(
|
||||||
'<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="6" class="value" /></span>' +
|
'<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_1" size="14" class="value" /></span>' +
|
||||||
' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="6" class="value" /></span>'
|
' <span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'_2" size="14" class="value" /></span>'
|
||||||
);
|
);
|
||||||
$('#values_'+fieldId+'_1').val(values[0]);
|
$('#values_'+fieldId+'_1').val(values[0]);
|
||||||
$('#values_'+fieldId+'_2').val(values[1]);
|
$('#values_'+fieldId+'_2').val(values[1]);
|
||||||
|
|||||||
@@ -1181,6 +1181,7 @@ a.icon-only::after {
|
|||||||
.icon-ok { background-image: url(../images/true.png); }
|
.icon-ok { background-image: url(../images/true.png); }
|
||||||
.icon-not-ok { background-image: url(../images/false.png); }
|
.icon-not-ok { background-image: url(../images/false.png); }
|
||||||
.icon-link-break { background-image: url(../images/link_break.png); }
|
.icon-link-break { background-image: url(../images/link_break.png); }
|
||||||
|
.icon-list { background-image: url(../images/text_list_bullets.png); }
|
||||||
|
|
||||||
.icon-file { background-image: url(../images/files/default.png); }
|
.icon-file { background-image: url(../images/files/default.png); }
|
||||||
.icon-file.text-plain { background-image: url(../images/files/text.png); }
|
.icon-file.text-plain { background-image: url(../images/files/text.png); }
|
||||||
|
|||||||
@@ -235,6 +235,14 @@ class QueryTest < ActiveSupport::TestCase
|
|||||||
assert_equal 2, issues.first.id
|
assert_equal 2, issues.first.id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_operator_is_on_integer_should_accept_comma_separated_values
|
||||||
|
query = IssueQuery.new(:name => '_')
|
||||||
|
query.add_filter("issue_id", '=', ['1,3'])
|
||||||
|
issues = find_issues_with_query(query)
|
||||||
|
assert_equal 2, issues.size
|
||||||
|
assert_equal [1,3], issues.map(&:id).sort
|
||||||
|
end
|
||||||
|
|
||||||
def test_operator_is_on_integer_custom_field
|
def test_operator_is_on_integer_custom_field
|
||||||
f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_for_all => true, :is_filter => true, :trackers => Tracker.all)
|
f = IssueCustomField.create!(:name => 'filter', :field_format => 'int', :is_for_all => true, :is_filter => true, :trackers => Tracker.all)
|
||||||
CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
|
CustomValue.create!(:custom_field => f, :customized => Issue.find(1), :value => '7')
|
||||||
|
|||||||
Reference in New Issue
Block a user