Add a button to apply issues filter to search results (#38481).

Patch by Go MAEDA.


git-svn-id: https://svn.redmine.org/redmine/trunk@22212 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Go MAEDA
2023-04-27 04:10:33 +00:00
parent 135606bcf5
commit ccf8e7d299
5 changed files with 96 additions and 0 deletions

View File

@@ -69,4 +69,50 @@ module SearchHelper
links.map {|link| content_tag('li', link)}.join(' ').html_safe +
'</ul>'.html_safe) unless links.empty?
end
def issues_filter_path(question, options)
projects_scope = options[:projects_scope]
titles_only = options[:titles_only]
all_words = options[:all_words]
open_issues = options[:open_issues]
field_to_search = titles_only ? 'subject' : 'any_searchable'
params = {
:set_filter => 1,
:f => ['status_id', field_to_search],
:op => {
'status_id' => open_issues ? 'o' : '*',
field_to_search => all_words ? '~' : '*~'
},
:v => {field_to_search => [question]},
:sort => 'updated_on:desc'
}
case projects_scope
when 'all'
# nothing to do
when 'my_projects'
params[:f] << 'project_id'
params[:op]['project_id'] = '='
params[:v]['project_id'] = ['mine']
when 'bookmarks'
params[:f] << 'project_id'
params[:op]['project_id'] = '='
params[:v]['project_id'] = ['bookmarks']
when 'subprojects'
params[:f] << 'subproject_id'
params[:op]['subproject_id'] = '*'
params[:project_id] = @project.id
else
if @project
# current project only
params[:f] << 'subproject_id'
params[:op]['subproject_id'] = '!*'
params[:project_id] = @project.id
end
# else all projects
end
issues_path(params)
end
end

View File

@@ -46,6 +46,11 @@
<%= render_results_by_type(@result_count_by_type) unless @scope.size == 1 %>
</div>
<h3><%= l(:label_result_plural) %> (<%= @result_count %>)</h3>
<% if @result_count_by_type['issues'].to_i > 0 && @search_attachments == '0' %>
<p class="buttons">
<%= link_to l(:button_apply_issues_filter), issues_filter_path(@question, projects_scope: params[:scope], all_words: @all_words, titles_only: @titles_only, open_issues: @open_issues), :class => 'icon icon-list' %>
</p>
<% end %>
<dl id="search-results">
<% @results.each do |e| %>
<dt class="<%= e.event_type %> icon icon-<%= e.event_type %>">

View File

@@ -1198,6 +1198,7 @@ en:
button_edit_object: "Edit %{object_name}"
button_delete_object: "Delete %{object_name}"
button_create_and_follow: Create and follow
button_apply_issues_filter: Apply issues filter
status_active: active
status_registered: registered

View File

@@ -95,6 +95,7 @@ class SearchControllerTest < Redmine::ControllerTest
assert_select 'input[name=all_words][checked=checked]'
assert_select 'input[name=titles_only]:not([checked])'
assert_select 'p.buttons a', :text => 'Apply issues filter'
assert_select '#search-results' do
assert_select 'dt.issue a', :text => /Bug #5/
assert_select 'dt.issue-closed a', :text => /Bug #8 \(Closed\)/
@@ -457,4 +458,15 @@ class SearchControllerTest < Redmine::ControllerTest
assert_select '#search-results dt.project', 0
end
def test_search_should_not_show_apply_issues_filter_button_if_no_issues_found
get :index, :params => {:q => 'commits'}
assert_response :success
assert_select 'p.buttons a', :text => 'Apply issues filter', :count => 0
assert_select '#search-results' do
assert_select 'dt.issue', :count => 0
assert_select 'dt.issue-closed', :count => 0
end
end
end

View File

@@ -54,4 +54,36 @@ class SearchHelperTest < Redmine::HelperTest
r
)
end
def test_issues_filter_path
# rubocop:disable Layout/LineLength
assert_equal(
'/issues?f[]=status_id&f[]=any_searchable&f[]=project_id&op[any_searchable]=*~&op[project_id]==&op[status_id]=*&set_filter=1&sort=updated_on:desc&v[any_searchable][]=recipe&v[project_id][]=mine',
Addressable::URI.unencode(issues_filter_path('recipe', projects_scope: 'my_projects'))
)
assert_equal(
'/issues?f[]=status_id&f[]=any_searchable&f[]=project_id&op[any_searchable]=*~&op[project_id]==&op[status_id]=*&set_filter=1&sort=updated_on:desc&v[any_searchable][]=recipe&v[project_id][]=bookmarks',
Addressable::URI.unencode(issues_filter_path('recipe', projects_scope: 'bookmarks'))
)
assert_equal(
'/issues?f[]=status_id&f[]=any_searchable&op[any_searchable]=*~&op[status_id]=*&set_filter=1&sort=updated_on:desc&v[any_searchable][]=recipe',
Addressable::URI.unencode(issues_filter_path('recipe', projects_scope: 'all'))
)
# f[]=subject
assert_equal(
'/issues?f[]=status_id&f[]=subject&op[status_id]=*&op[subject]=*~&set_filter=1&sort=updated_on:desc&v[subject][]=recipe',
Addressable::URI.unencode(issues_filter_path('recipe', projects_scope: 'all', titles_only: '1'))
)
# op[subject]=~ (contains)
assert_equal(
'/issues?f[]=status_id&f[]=subject&op[status_id]=*&op[subject]=~&set_filter=1&sort=updated_on:desc&v[subject][]=recipe',
Addressable::URI.unencode(issues_filter_path('recipe', projects_scope: 'all', titles_only: '1', all_words: ''))
)
# op[status_id]=o (open)
assert_equal(
'/issues?f[]=status_id&f[]=subject&op[status_id]=o&op[subject]=*~&set_filter=1&sort=updated_on:desc&v[subject][]=recipe',
Addressable::URI.unencode(issues_filter_path('recipe', projects_scope: 'all', titles_only: '1', open_issues: '1'))
)
# rubocop:enable Layout/LineLength
end
end