diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb index e573f8782..ac40da35f 100644 --- a/app/models/issue_query.rb +++ b/app/models/issue_query.rb @@ -155,11 +155,11 @@ class IssueQuery < Query ) if project.nil? add_available_filter( "tracker_id", - :type => :list, :values => trackers.collect{|s| [s.name, s.id.to_s]} + :type => :list_with_history, :values => trackers.collect{|s| [s.name, s.id.to_s]} ) add_available_filter( "priority_id", - :type => :list, :values => IssuePriority.all.collect{|s| [s.name, s.id.to_s]} + :type => :list_with_history, :values => IssuePriority.all.collect{|s| [s.name, s.id.to_s]} ) add_available_filter( "author_id", @@ -167,7 +167,7 @@ class IssueQuery < Query ) add_available_filter( "assigned_to_id", - :type => :list_optional, :values => lambda {assigned_to_values} + :type => :list_optional_with_history, :values => lambda {assigned_to_values} ) add_available_filter( "member_of_group", @@ -179,7 +179,7 @@ class IssueQuery < Query ) add_available_filter( "fixed_version_id", - :type => :list_optional, :values => lambda {fixed_version_values} + :type => :list_optional_with_history, :values => lambda {fixed_version_values} ) add_available_filter( "fixed_version.due_date", @@ -194,7 +194,7 @@ class IssueQuery < Query ) add_available_filter( "category_id", - :type => :list_optional, + :type => :list_with_history, :values => lambda {project.issue_categories.collect{|s| [s.name, s.id.to_s]}} ) if project add_available_filter "subject", :type => :text diff --git a/app/models/query.rb b/app/models/query.rb index 00d99c24f..130ee1a8c 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -314,13 +314,18 @@ class Query < ActiveRecord::Base "!p" => :label_no_issues_in_project, "*o" => :label_any_open_issues, "!o" => :label_no_open_issues, + "cf" => :label_changed_from, + "ev" => :label_has_ever_been, + "!ev" => :label_has_never_been } class_attribute :operators_by_filter_type self.operators_by_filter_type = { :list => [ "=", "!" ], - :list_status => [ "o", "=", "!", "c", "*" ], + :list_with_history => [ "=", "!", "cf", "ev", "!ev" ], + :list_status => [ "o", "=", "!", "cf", "ev", "!ev", "c", "*" ], :list_optional => [ "=", "!", "!*", "*" ], + :list_optional_with_history => [ "=", "!", "cf", "ev", "!ev", "!*", "*" ], :list_subprojects => [ "*", "!*", "=", "!" ], :date => [ "=", ">=", "<=", "><", "t+", ">t-", " [ "=", ">=", "<=", "><", ">t-", " true) when "$" sql = sql_contains("#{db_table}.#{db_field}", value.first, :ends_with => true) + when "cf" + # changed from + subquery = + "SELECT 1 FROM journals, journal_details WHERE " + + queried_class.send(:sanitize_sql_array, + [ + "(#{Journal.table_name}.journalized_type = 'Issue' AND #{db_table}.id = #{Journal.table_name}.journalized_id AND #{JournalDetail.table_name}.journal_id = #{Journal.table_name}.id AND prop_key = '#{db_field}' AND old_value IN (?)) AND (#{Journal.visible_notes_condition(User.current, :skip_pre_condition => true)})", + value + ] + ) + sql = "EXISTS (#{subquery})" + when "ev", "!ev" + # has ever been / has never been + neg = (operator == '!ev' ? 'NOT' : '') + subquery = + "SELECT 1 FROM journals, journal_details WHERE " + + queried_class.send(:sanitize_sql_array, + [ + "((#{Journal.table_name}.journalized_type = 'Issue' AND #{db_table}.id = #{Journal.table_name}.journalized_id AND #{JournalDetail.table_name}.journal_id = #{Journal.table_name}.id AND prop_key = '#{db_field}' AND old_value IN (?)) OR (#{db_table}.#{db_field} IN (?))) AND (#{Journal.visible_notes_condition(User.current, :skip_pre_condition => true)})", + value, value + ] + ) + sql = "#{neg} EXISTS (#{subquery})" else raise QueryError, "Unknown query operator #{operator}" end diff --git a/config/locales/en.yml b/config/locales/en.yml index 637fe8a12..942fad2c5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -818,6 +818,9 @@ en: label_no_issues_in_project: no issues in project label_any_open_issues: any open issues label_no_open_issues: no open issues + label_changed_from: changed from + label_has_ever_been: has ever been + label_has_never_been: has never been label_day_plural: days label_repository: Repository label_repository_new: New repository diff --git a/public/javascripts/application.js b/public/javascripts/application.js index 6d01dc2b9..a183a2777 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -180,7 +180,9 @@ function buildFilterRow(field, operator, values) { switch (filterOptions['type']) { case "list": + case "list_with_history": case "list_optional": + case "list_optional_with_history": case "list_status": case "list_subprojects": tr.find('td.values').append(