Feature #38402 » 0001-Add-Any-serchable-text-filter-for-issues.patch
| app/models/issue_query.rb | ||
|---|---|---|
| 272 | 272 | |
| 273 | 273 |
add_available_filter "issue_id", :type => :integer, :label => :label_issue |
| 274 | 274 | |
| 275 |
add_available_filter "any_searchable", :type => :search |
|
| 276 | ||
| 275 | 277 |
Tracker.disabled_core_fields(trackers).each do |field| |
| 276 | 278 |
delete_available_filter field |
| 277 | 279 |
end |
| ... | ... | |
| 774 | 776 |
sql_for_field(field, operator, value, Project.table_name, "status") |
| 775 | 777 |
end |
| 776 | 778 | |
| 779 |
def sql_for_any_searchable_field(field, operator, value) |
|
| 780 |
question = value.first |
|
| 781 |
projects = project&.self_and_descendants |
|
| 782 |
fetcher = Redmine::Search::Fetcher.new( |
|
| 783 |
question, User.current, ['issue'], projects, attachments: '0' |
|
| 784 |
) |
|
| 785 |
ids = fetcher.result_ids.map(&:last) |
|
| 786 |
if ids.present? |
|
| 787 |
sw = operator == '!~' ? 'NOT' : '' |
|
| 788 |
"#{Issue.table_name}.id #{sw} IN (#{ids.join(',')})"
|
|
| 789 |
else |
|
| 790 |
'1=0' |
|
| 791 |
end |
|
| 792 |
end |
|
| 793 | ||
| 777 | 794 |
def find_assigned_to_id_filter_values(values) |
| 778 | 795 |
Principal.visible.where(:id => values).map {|p| [p.name, p.id.to_s]}
|
| 779 | 796 |
end |
| app/models/query.rb | ||
|---|---|---|
| 325 | 325 |
:date_past => [ "=", ">=", "<=", "><", ">t-", "<t-", "><t-", "t-", "t", "ld", "w", "lw", "l2w", "m", "lm", "y", "!*", "*" ], |
| 326 | 326 |
:string => [ "~", "=", "!~", "!", "^", "$", "!*", "*" ], |
| 327 | 327 |
:text => [ "~", "!~", "^", "$", "!*", "*" ], |
| 328 |
:search => [ "~", "!~" ], |
|
| 328 | 329 |
:integer => [ "=", ">=", "<=", "><", "!*", "*" ], |
| 329 | 330 |
:float => [ "=", ">=", "<=", "><", "!*", "*" ], |
| 330 | 331 |
:relation => ["=", "!", "=p", "=!p", "!p", "*o", "!o", "!*", "*"], |
| config/locales/en.yml | ||
|---|---|---|
| 417 | 417 |
field_default_issue_query: Default issue query |
| 418 | 418 |
field_default_project_query: Default project query |
| 419 | 419 |
field_default_time_entry_activity: Default spent time activity |
| 420 |
field_any_searchable: Any searchable text |
|
| 420 | 421 | |
| 421 | 422 |
setting_app_title: Application title |
| 422 | 423 |
setting_welcome_text: Welcome text |
| public/javascripts/application.js | ||
|---|---|---|
| 220 | 220 |
break; |
| 221 | 221 |
case "string": |
| 222 | 222 |
case "text": |
| 223 |
case "search": |
|
| 223 | 224 |
tr.find('td.values').append(
|
| 224 | 225 |
'<span style="display:none;"><input type="text" name="v['+field+'][]" id="values_'+fieldId+'" size="30" class="value" /></span>' |
| 225 | 226 |
); |
| test/unit/query_test.rb | ||
|---|---|---|
| 844 | 844 |
assert_equal [1, 3], find_issues_with_query(query).map(&:id).sort |
| 845 | 845 |
end |
| 846 | 846 | |
| 847 |
def test_fileter_any_searchable |
|
| 848 |
User.current = User.find(1) |
|
| 849 |
query = IssueQuery.new( |
|
| 850 |
:name => '_', |
|
| 851 |
:filters => {
|
|
| 852 |
'any_searchable' => {
|
|
| 853 |
:operator => '~', |
|
| 854 |
:values => ['recipe'] |
|
| 855 |
} |
|
| 856 |
} |
|
| 857 |
) |
|
| 858 |
result = find_issues_with_query(query) |
|
| 859 |
assert_equal [1, 2, 3], result.map(&:id).sort |
|
| 860 |
end |
|
| 861 | ||
| 862 |
def test_fileter_any_searchable_should_search_searchable_custom_fields |
|
| 863 |
User.current = User.find(1) |
|
| 864 |
query = IssueQuery.new( |
|
| 865 |
:name => '_', |
|
| 866 |
:filters => {
|
|
| 867 |
'any_searchable' => {
|
|
| 868 |
:operator => '~', |
|
| 869 |
:values => ['125'] |
|
| 870 |
} |
|
| 871 |
} |
|
| 872 |
) |
|
| 873 |
result = find_issues_with_query(query) |
|
| 874 |
assert_equal [1, 3], result.map(&:id).sort |
|
| 875 |
end |
|
| 876 | ||
| 847 | 877 |
def test_filter_updated_by |
| 848 | 878 |
user = User.generate! |
| 849 | 879 |
Journal.create!(:user_id => user.id, :journalized => Issue.find(2), :notes => 'Notes') |