diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb
index 24f37eda2..f094e34e8 100644
--- a/app/controllers/queries_controller.rb
+++ b/app/controllers/queries_controller.rb
@@ -134,6 +134,7 @@ class QueriesController < ApplicationController
@query.build_from_params(params)
@query.column_names = nil if params[:default_columns]
@query.sort_criteria = (params[:query] && params[:query][:sort_criteria]) || @query.sort_criteria
+ @query.keep_sort_order = params[:query] && params[:query][:keep_sort_order]
@query.name = params[:query] && params[:query][:name]
@query.description = params[:query] && params[:query][:description]
if User.current.allowed_to?(:manage_public_queries, @query.project) || User.current.admin?
diff --git a/app/helpers/queries_helper.rb b/app/helpers/queries_helper.rb
index 1001ea2d7..75a364ceb 100644
--- a/app/helpers/queries_helper.rb
+++ b/app/helpers/queries_helper.rb
@@ -359,7 +359,14 @@ module QueriesHelper
raise ::Unauthorized unless @query.visible?
@query.project = @project
- session[session_key] = {:id => @query.id, :project_id => @query.project_id} if use_session
+ if use_session
+ current_sort = sort_criteria_from_session(klass, session_key)
+ session[session_key] = {:id => @query.id, :project_id => @query.project_id}
+ if @query.keep_sort_order && current_sort.present?
+ @query.sort_criteria = current_sort
+ session[session_key][:sort] = @query.sort_criteria.to_a
+ end
+ end
elsif api_request? || params[:set_filter] || !use_session ||
session[session_key].nil? ||
session[session_key][:project_id] != (@project ? @project.id : nil)
@@ -401,6 +408,18 @@ module QueriesHelper
@query
end
+ # Returns the sort criteria of the query stored in the session
+ def sort_criteria_from_session(klass, session_key)
+ session_data = session[session_key]
+ return unless session_data
+
+ if session_data[:sort].present?
+ session_data[:sort]
+ elsif session_data[:id]
+ klass.find_by_id(session_data[:id])&.sort_criteria&.to_a
+ end
+ end
+
def retrieve_query_from_session(klass=IssueQuery)
session_key = klass.name.underscore.to_sym
session_data = session[session_key]
diff --git a/app/models/query.rb b/app/models/query.rb
index fc9b62b39..156d889f1 100644
--- a/app/models/query.rb
+++ b/app/models/query.rb
@@ -906,6 +906,14 @@ class Query < ApplicationRecord
[]
end
+ def keep_sort_order
+ options[:keep_sort_order] == '1'
+ end
+
+ def keep_sort_order=(arg)
+ options[:keep_sort_order] = (arg == '1' ? '1' : nil)
+ end
+
def sort_criteria=(arg)
c = Redmine::SortCriteria.new(arg)
write_attribute(:sort_criteria, c.to_a)
diff --git a/app/views/queries/_form.html.erb b/app/views/queries/_form.html.erb
index 293e92955..c579f46e9 100644
--- a/app/views/queries/_form.html.erb
+++ b/app/views/queries/_form.html.erb
@@ -97,6 +97,7 @@
:id => "query_sort_criteria_direction_" + i.to_s) %>
<% end %>
+
<% end %>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 279539b88..b0c2d2f89 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -1499,3 +1499,4 @@ en:
reaction_text_x_other_users:
one: "1 other"
other: "%{count} others"
+ label_keep_sort_order: Keep the current sort order when selecting this query
diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb
index f7ab77e84..1c157eee4 100644
--- a/test/functional/issues_controller_test.rb
+++ b/test/functional/issues_controller_test.rb
@@ -734,6 +734,50 @@ class IssuesControllerTest < Redmine::ControllerTest
assert_response :success
end
+ def test_index_with_saved_query_with_keep_sort_order_should_keep_the_current_sort_order
+ query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC,
+ :user_id => 1, :sort_criteria => [['id', 'asc']])
+ keeping = IssueQuery.create!(:name => 'keeping', :visibility => IssueQuery::VISIBILITY_PUBLIC,
+ :user_id => 1, :sort_criteria => [['id', 'asc']],
+ :keep_sort_order => '1')
+ get(:index, :params => {:query_id => query.id, :sort => 'id:desc'})
+ assert_response :success
+
+ get(:index, :params => {:query_id => keeping.id})
+ assert_response :success
+ ids = issues_in_list.map(&:id)
+ assert_equal ids.sort.reverse, ids
+ end
+
+ def test_index_with_saved_query_with_keep_sort_order_should_keep_the_sort_order_of_the_previous_query
+ query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC,
+ :user_id => 1, :sort_criteria => [['id', 'desc']])
+ keeping = IssueQuery.create!(:name => 'keeping', :visibility => IssueQuery::VISIBILITY_PUBLIC,
+ :user_id => 1, :sort_criteria => [['id', 'asc']],
+ :keep_sort_order => '1')
+ get(:index, :params => {:query_id => query.id})
+ assert_response :success
+
+ get(:index, :params => {:query_id => keeping.id})
+ assert_response :success
+ ids = issues_in_list.map(&:id)
+ assert_equal ids.sort.reverse, ids
+ end
+
+ def test_index_with_saved_query_without_keep_sort_order_should_use_its_sort_order
+ query = IssueQuery.create!(:name => 'test', :visibility => IssueQuery::VISIBILITY_PUBLIC,
+ :user_id => 1, :sort_criteria => [['id', 'asc']])
+ other = IssueQuery.create!(:name => 'other', :visibility => IssueQuery::VISIBILITY_PUBLIC,
+ :user_id => 1, :sort_criteria => [['id', 'asc']])
+ get(:index, :params => {:query_id => query.id, :sort => 'id:desc'})
+ assert_response :success
+
+ get(:index, :params => {:query_id => other.id})
+ assert_response :success
+ ids = issues_in_list.map(&:id)
+ assert_equal ids.sort, ids
+ end
+
def test_index_should_omit_page_param_in_export_links
get(:index, :params => {:page => 2})
assert_response :success
diff --git a/test/functional/queries_controller_test.rb b/test/functional/queries_controller_test.rb
index 297bfa232..f8d4b4443 100644
--- a/test/functional/queries_controller_test.rb
+++ b/test/functional/queries_controller_test.rb
@@ -670,6 +670,36 @@ class QueriesControllerTest < Redmine::ControllerTest
end
end
+ def test_create_with_keep_sort_order
+ @request.session[:user_id] = 1
+ post(
+ :create,
+ :params => {
+ :default_columns => '1',
+ :query => {:name => 'test_keep_sort_order', :visibility => '2', :keep_sort_order => '1'}
+ }
+ )
+ query = Query.find_by_name('test_keep_sort_order')
+ assert query.keep_sort_order
+ end
+
+ def test_update_without_keep_sort_order
+ @request.session[:user_id] = 1
+ query = Query.find(5)
+ query.update!(:keep_sort_order => '1')
+
+ put(:update, :params => {:id => 5, :default_columns => '1', :query => {:name => 'test_query'}})
+ assert_not query.reload.keep_sort_order
+ end
+
+ def test_edit_keep_sort_order
+ @request.session[:user_id] = 1
+ Query.find(5).update!(:keep_sort_order => '1')
+ get(:edit, :params => {:id => 5})
+ assert_response :success
+ assert_select 'input[type=checkbox][name=?][checked=checked]', 'query[keep_sort_order]'
+ end
+
def test_edit_description
@request.session[:user_id] = 1
get(:edit, :params => {:id => 5})
--
2.43.0