summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGo MAEDA <maeda@farend.jp>2023-04-05 09:22:34 +0000
committerGo MAEDA <maeda@farend.jp>2023-04-05 09:22:34 +0000
commitd7d27374b86fd0fab73487b79d72f9095febebb3 (patch)
tree6a98c27118c2b83d38debab930cc1c8419086aa5
parent8ff33f64aa2d35ee9c641c89e8fe680fc239791c (diff)
downloadredmine-d7d27374b86fd0fab73487b79d72f9095febebb3.tar.gz
redmine-d7d27374b86fd0fab73487b79d72f9095febebb3.zip
Add "Any searchable text" filter for issues (#38402).
Patch by Go MAEDA and Holger Just. git-svn-id: https://svn.redmine.org/redmine/trunk@22164 e93f8b46-1217-0410-a6f0-8f06a7374b81
-rw-r--r--app/models/issue_query.rb29
-rw-r--r--app/models/query.rb1
-rw-r--r--config/locales/en.yml1
-rw-r--r--public/javascripts/application.js1
-rw-r--r--test/unit/query_test.rb30
5 files changed, 62 insertions, 0 deletions
diff --git a/app/models/issue_query.rb b/app/models/issue_query.rb
index 9f541cc54..1c60c6b61 100644
--- a/app/models/issue_query.rb
+++ b/app/models/issue_query.rb
@@ -272,6 +272,8 @@ class IssueQuery < Query
add_available_filter "issue_id", :type => :integer, :label => :label_issue
+ add_available_filter "any_searchable", :type => :search
+
Tracker.disabled_core_fields(trackers).each do |field|
delete_available_filter field
end
@@ -774,6 +776,33 @@ class IssueQuery < Query
sql_for_field(field, operator, value, Project.table_name, "status")
end
+ def sql_for_any_searchable_field(field, operator, value)
+ question = value.first
+
+ # Fetch search results only from the selected and visible (sub-)projects
+ project_scope = Project.allowed_to(:view_issues)
+ if project
+ projects = project_scope.where(project_statement)
+ elsif has_filter?('project_id')
+ projects = project_scope.where(
+ sql_for_field('project_id', operator_for('project_id'), values_for('project_id'), Project.table_name, 'id')
+ )
+ else
+ projects = nil
+ end
+
+ fetcher = Redmine::Search::Fetcher.new(
+ question, User.current, ['issue'], projects, attachments: '0'
+ )
+ ids = fetcher.result_ids.map(&:last)
+ if ids.present?
+ sw = operator == '!~' ? 'NOT' : ''
+ "#{Issue.table_name}.id #{sw} IN (#{ids.join(',')})"
+ else
+ '1=0'
+ end
+ end
+
def find_assigned_to_id_filter_values(values)
Principal.visible.where(:id => values).map {|p| [p.name, p.id.to_s]}
end
diff --git a/app/models/query.rb b/app/models/query.rb
index 473ea4d86..289d683f6 100644
--- a/app/models/query.rb
+++ b/app/models/query.rb
@@ -325,6 +325,7 @@ class Query < ActiveRecord::Base
:date_past => [ "=", ">=", "<=", "><", ">t-", "<t-", "><t-", "t-", "t", "ld", "w", "lw", "l2w", "m", "lm", "y", "!*", "*" ],
:string => [ "~", "=", "!~", "!", "^", "$", "!*", "*" ],
:text => [ "~", "!~", "^", "$", "!*", "*" ],
+ :search => [ "~", "!~" ],
:integer => [ "=", ">=", "<=", "><", "!*", "*" ],
:float => [ "=", ">=", "<=", "><", "!*", "*" ],
:relation => ["=", "!", "=p", "=!p", "!p", "*o", "!o", "!*", "*"],
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 2e1378ff7..678aab66d 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -417,6 +417,7 @@ en:
field_default_issue_query: Default issue query
field_default_project_query: Default project query
field_default_time_entry_activity: Default spent time activity
+ field_any_searchable: Any searchable text
setting_app_title: Application title
setting_welcome_text: Welcome text
diff --git a/public/javascripts/application.js b/public/javascripts/application.js
index 7b2e7725e..6d01dc2b9 100644
--- a/public/javascripts/application.js
+++ b/public/javascripts/application.js
@@ -220,6 +220,7 @@ function buildFilterRow(field, operator, values) {
break;
case "string":
case "text":
+ case "search":
tr.find('td.values').append(
'<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="30" class="value" /></span>'
);
diff --git a/test/unit/query_test.rb b/test/unit/query_test.rb
index b41aa507c..2b02a1e07 100644
--- a/test/unit/query_test.rb
+++ b/test/unit/query_test.rb
@@ -844,6 +844,36 @@ class QueryTest < ActiveSupport::TestCase
assert_equal [1, 3], find_issues_with_query(query).map(&:id).sort
end
+ def test_fileter_any_searchable
+ User.current = User.find(1)
+ query = IssueQuery.new(
+ :name => '_',
+ :filters => {
+ 'any_searchable' => {
+ :operator => '~',
+ :values => ['recipe']
+ }
+ }
+ )
+ result = find_issues_with_query(query)
+ assert_equal [1, 2, 3], result.map(&:id).sort
+ end
+
+ def test_fileter_any_searchable_should_search_searchable_custom_fields
+ User.current = User.find(1)
+ query = IssueQuery.new(
+ :name => '_',
+ :filters => {
+ 'any_searchable' => {
+ :operator => '~',
+ :values => ['125']
+ }
+ }
+ )
+ result = find_issues_with_query(query)
+ assert_equal [1, 3], result.map(&:id).sort
+ end
+
def test_filter_updated_by
user = User.generate!
Journal.create!(:user_id => user.id, :journalized => Issue.find(2), :notes => 'Notes')