diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb
index 13fa3ade76..1b83f3ee7e 100644
--- a/app/controllers/queries_controller.rb
+++ b/app/controllers/queries_controller.rb
@@ -20,7 +20,7 @@
class QueriesController < ApplicationController
menu_item :issues
before_action :find_query, :only => [:edit, :update, :destroy]
- before_action :find_optional_project, :only => [:new, :create]
+ before_action :find_optional_project, :only => [:new, :create, :edit, :update]
accept_api_auth :index
@@ -121,7 +121,7 @@ class QueriesController < ApplicationController
end
def update_query_from_params
- @query.project = params[:query_is_for_all] ? nil : @project
+ @query.project = (params[:query] && params[:query][:project_id].present?) ? Project.find(params[:query][:project_id]) : nil
@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
diff --git a/app/views/calendars/show.html.erb b/app/views/calendars/show.html.erb
index 76513f50e7..ec39089d58 100644
--- a/app/views/calendars/show.html.erb
+++ b/app/views/calendars/show.html.erb
@@ -33,7 +33,7 @@
:class => 'icon icon-save' %>
<% end %>
<% if !@query.new_record? && @query.editable_by?(User.current) %>
- <%= link_to l(:button_edit_object, object_name: l(:label_query).downcase), edit_query_path(@query, :calendar => 1), :class => 'icon icon-edit' %>
+ <%= link_to l(:button_edit_object, object_name: l(:label_query).downcase), edit_query_path(@query, :calendar => 1, :project_id => @project&.identifier), :class => 'icon icon-edit' %>
<%= delete_link query_path(@query, :calendar => 1), {}, l(:button_delete_object, object_name: l(:label_query).downcase) %>
<% end %>
diff --git a/app/views/gantts/show.html.erb b/app/views/gantts/show.html.erb
index e3bfa02ae9..31a3c8d5cd 100644
--- a/app/views/gantts/show.html.erb
+++ b/app/views/gantts/show.html.erb
@@ -96,7 +96,7 @@
:class => 'icon icon-save' %>
<% end %>
<% if !@query.new_record? && @query.editable_by?(User.current) %>
- <%= link_to l(:button_edit_object, object_name: l(:label_query).downcase), edit_query_path(@query, :gantt => 1), :class => 'icon icon-edit' %>
+ <%= link_to l(:button_edit_object, object_name: l(:label_query).downcase), edit_query_path(@query, :gantt => 1, :project_id => @project&.identifier), :class => 'icon icon-edit' %>
<%= delete_link query_path(@query, :gantt => 1), {}, l(:button_delete_object, object_name: l(:label_query).downcase) %>
<% end %>
diff --git a/app/views/queries/_form.html.erb b/app/views/queries/_form.html.erb
index 6a94712e01..fec1d9f479 100644
--- a/app/views/queries/_form.html.erb
+++ b/app/views/queries/_form.html.erb
@@ -24,8 +24,12 @@
<% end %>
<% unless @query.type == 'ProjectQuery' %>
-
- <%= check_box_tag 'query_is_for_all', 1, @query.project.nil?, :class => (User.current.admin? ? '' : 'disable-unless-private') %>
+
+ <%= radio_button_tag 'query[project_id]', '', @query.project.nil?, id: nil, class: ('disable-unless-private' unless User.current.admin?) %> <%= l(:field_is_for_all) %>
+ <% if @project %>
+ <%= radio_button_tag 'query[project_id]', @project.identifier, !@query.project.nil?, id: nil %> <%= @project.name %>
+ <% end%>
+
<% end %>
<% unless params[:calendar] %>
@@ -105,8 +109,10 @@ $(document).ready(function(){
var roles_checked = $('#query_visibility_1').is(':checked');
var private_checked = $('#query_visibility_0').is(':checked');
$("input[name='query[role_ids][]'][type=checkbox]").attr('disabled', !roles_checked);
- if (!private_checked) $("input.disable-unless-private").attr('checked', false);
- $("input.disable-unless-private").attr('disabled', !private_checked);
+ if($("input.disable-unless-private").length){
+ if (!private_checked) $("input[name='query[project_id]']:not([value=''])").prop('checked', true);
+ $("input.disable-unless-private").attr('disabled', !private_checked);
+ }
}).trigger('change');
});
diff --git a/app/views/queries/_query_form.html.erb b/app/views/queries/_query_form.html.erb
index 9f1f9ea7e5..0a8ccd8a9d 100644
--- a/app/views/queries/_query_form.html.erb
+++ b/app/views/queries/_query_form.html.erb
@@ -63,7 +63,7 @@
<% end %>
<% else %>
<% if @query.editable_by?(User.current) %>
- <%= link_to l(:button_edit_object, object_name: l(:label_query).downcase), edit_query_path(@query), :class => 'icon icon-edit' %>
+ <%= link_to l(:button_edit_object, object_name: l(:label_query).downcase), edit_query_path(@query, project_id: @project&.identifier), :class => 'icon icon-edit' %>
<%= delete_link query_path(@query), {}, l(:button_delete_object, object_name: l(:label_query).downcase) %>
<% end %>
<% end %>
diff --git a/app/views/queries/edit.html.erb b/app/views/queries/edit.html.erb
index 9db5137c2b..6a9c6df2e2 100644
--- a/app/views/queries/edit.html.erb
+++ b/app/views/queries/edit.html.erb
@@ -1,6 +1,6 @@
<%= l(:label_query) %>
-<%= form_tag(query_path(@query), :method => :put, :id => "query-form") do %>
+<%= form_tag(query_path(@query, project_id: @project&.identifier), :method => :put, :id => "query-form") do %>
<%= render :partial => 'form', :locals => {:query => @query} %>
<%= submit_tag l(:button_save) %>
<% end %>
diff --git a/test/functional/queries_controller_test.rb b/test/functional/queries_controller_test.rb
index c6b3fec74c..a7d40a1be0 100644
--- a/test/functional/queries_controller_test.rb
+++ b/test/functional/queries_controller_test.rb
@@ -43,7 +43,10 @@ class QueriesControllerTest < Redmine::ControllerTest
assert_response :success
assert_select 'input[name=?][value="0"][checked=checked]', 'query[visibility]'
- assert_select 'input[name=query_is_for_all][type=checkbox]:not([checked]):not([disabled])'
+ assert_select 'input[name=?][type=radio]', 'query[project_id]', 2 do
+ assert_select '[value=""][class="disable-unless-private"]:not([checked])'
+ assert_select '[value="ecookbook"][checked]'
+ end
assert_select 'select[name=?]', 'c[]' do
assert_select 'option[value=tracker]'
assert_select 'option[value=subject]'
@@ -56,7 +59,9 @@ class QueriesControllerTest < Redmine::ControllerTest
assert_response :success
assert_select 'input[name=?]', 'query[visibility]', 0
- assert_select 'input[name=query_is_for_all][type=checkbox][checked]:not([disabled])'
+ assert_select 'input[name=?][type=radio]', 'query[project_id]', 1 do
+ assert_select '[value=""][class="disable-unless-private"][checked]'
+ end
end
def test_new_on_invalid_project
@@ -84,6 +89,10 @@ class QueriesControllerTest < Redmine::ControllerTest
get(:new, :params => {:project_id => 1, :type => 'TimeEntryQuery'})
assert_response :success
assert_select 'input[name=type][value=?]', 'TimeEntryQuery'
+ assert_select 'input[name=?][type=radio]', 'query[project_id]', 2 do
+ assert_select '[value=""][class="disable-unless-private"]:not([checked])'
+ assert_select '[value="ecookbook"][checked]'
+ end
assert_select 'p[class=?]', 'totable_columns', 1
assert_select 'p[class=?]', 'block_columns', 0
end
@@ -93,6 +102,7 @@ class QueriesControllerTest < Redmine::ControllerTest
get(:new, :params => {:type => 'ProjectQuery'})
assert_response :success
assert_select 'input[name=type][value=?]', 'ProjectQuery'
+ assert_select 'input[name=?]', 'query[project_id]', 0
end
def test_new_project_query_should_not_render_roles_visibility_options
@@ -104,13 +114,6 @@ class QueriesControllerTest < Redmine::ControllerTest
assert_select 'input[id=?]', 'query_visibility_1', 0
end
- def test_new_project_query_should_not_render_for_all_projects_option
- @request.session[:user_id] = 1
- get(:new, :params => {:type => 'ProjectQuery'})
- assert_response :success
- assert_select 'input[name=?]', 'for_all_projects', 0
- end
-
def test_new_time_entry_query_should_select_spent_time_from_main_menu
@request.session[:user_id] = 2
get(
@@ -147,6 +150,7 @@ class QueriesControllerTest < Redmine::ControllerTest
assert_select 'fieldset#filters'
assert_select 'fieldset legend', {:text => 'Sort', :count => 0}
assert_select 'fieldset#columns'
+ assert_select 'input[name=?]', 'query[project_id]'
end
def test_new_with_calendar_params
@@ -159,6 +163,7 @@ class QueriesControllerTest < Redmine::ControllerTest
assert_select 'fieldset#filters'
assert_select 'fieldset legend', {:text => 'Sort', :count => 0}
assert_select 'fieldset#columns', :count => 0
+ assert_select 'input[name=?]', 'query[project_id]'
end
def test_new_without_gantt_and_calendar_params
@@ -187,7 +192,7 @@ class QueriesControllerTest < Redmine::ControllerTest
"assigned_to_id" => ["1"], "status_id" => ["1"]
},
:query => {
- "name" => "test_new_project_public_query", "visibility" => "2"
+ "name" => "test_new_project_public_query", "visibility" => "2", "project_id" => "ecookbook"
}
}
)
@@ -241,7 +246,8 @@ class QueriesControllerTest < Redmine::ControllerTest
:query => {
"name" => "test_create_project_roles_query",
"visibility" => "1",
- "role_ids" => ["1", "2", ""]
+ "role_ids" => ["1", "2", ""],
+ "project_id" => "ecookbook"
}
}
)
@@ -441,7 +447,7 @@ class QueriesControllerTest < Redmine::ControllerTest
:params => {
:project_id => 'ecookbook',
:query => {
- "name" => "name", "visibility" => "2"
+ "name" => "name", "visibility" => "2", "project_id" => "ecookbook"
}
}
)
@@ -458,9 +464,8 @@ class QueriesControllerTest < Redmine::ControllerTest
:create,
:params => {
:project_id => 'ecookbook',
- :query_is_for_all => '1',
:query => {
- "name" => "name", "visibility" => "2"
+ "name" => "name", "visibility" => "2", "project_id" => ""
}
}
)
@@ -478,7 +483,7 @@ class QueriesControllerTest < Redmine::ControllerTest
:params => {
:project_id => 'ecookbook',
:query => {
- "name" => "name", "visibility" => "2"
+ "name" => "name", "visibility" => "2", "project_id" => "ecookbook"
}
}
)
@@ -495,9 +500,8 @@ class QueriesControllerTest < Redmine::ControllerTest
:create,
:params => {
:project_id => 'ecookbook',
- :query_is_for_all => '1',
:query => {
- "name" => "name", "visibility" => "2"
+ "name" => "name", "visibility" => "2", "project_id" => ""
}
}
)
@@ -514,9 +518,8 @@ class QueriesControllerTest < Redmine::ControllerTest
:create,
:params => {
:project_id => 'ecookbook',
- :query_is_for_all => '1',
:query => {
- "name" => "name", "visibility" => "2"
+ "name" => "name", "visibility" => "2", "project_id" => ""
}
}
)
@@ -544,7 +547,7 @@ class QueriesControllerTest < Redmine::ControllerTest
"spent_on" => ["2016-07-14"]
},
:query => {
- "name" => "test_new_project_public_query", "visibility" => "2"
+ "name" => "test_new_project_public_query", "visibility" => "2", "project_id" => "ecookbook"
}
}
)
@@ -591,7 +594,9 @@ class QueriesControllerTest < Redmine::ControllerTest
assert_response :success
assert_select 'input[name=?][value="2"][checked=checked]', 'query[visibility]'
- assert_select 'input[name=query_is_for_all][type=checkbox][checked=checked]'
+ assert_select 'input[name=?][type=radio]', 'query[project_id]', 1 do
+ assert_select '[value=""][checked]:not([class="disable-unless-private"])'
+ end
end
def test_edit_global_private_query
@@ -600,25 +605,33 @@ class QueriesControllerTest < Redmine::ControllerTest
assert_response :success
assert_select 'input[name=?]', 'query[visibility]', 0
- assert_select 'input[name=query_is_for_all][type=checkbox][checked=checked]'
+ assert_select 'input[name=?][type=radio]', 'query[project_id]', 1 do
+ assert_select '[value=""][class="disable-unless-private"][checked]'
+ end
end
def test_edit_project_private_query
@request.session[:user_id] = 3
- get(:edit, :params => {:id => 2})
+ get(:edit, :params => {:id => 2, :project_id => 'ecookbook'})
assert_response :success
assert_select 'input[name=?]', 'query[visibility]', 0
- assert_select 'input[name=query_is_for_all][type=checkbox]:not([checked])'
+ assert_select 'input[name=?][type=radio]', 'query[project_id]', 2 do
+ assert_select '[value=""][class="disable-unless-private"]:not([checked])'
+ assert_select '[value="ecookbook"][checked]'
+ end
end
def test_edit_project_public_query
@request.session[:user_id] = 2
- get(:edit, :params => {:id => 1})
+ get(:edit, :params => {:id => 1, :project_id => 'ecookbook'})
assert_response :success
assert_select 'input[name=?][value="2"][checked=checked]', 'query[visibility]'
- assert_select 'input[name=query_is_for_all][type=checkbox]:not([checked])'
+ assert_select 'input[name=?][type=radio]', 'query[project_id]', 2 do
+ assert_select '[value=""][class="disable-unless-private"]:not([checked])'
+ assert_select '[value="ecookbook"][checked]'
+ end
end
def test_edit_sort_criteria
@@ -653,7 +666,7 @@ class QueriesControllerTest < Redmine::ControllerTest
"assigned_to_id" => ["me"], "status_id" => ["1"]
},
:query => {
- "name" => "test_edit_global_private_query", "visibility" => "2"
+ "name" => "test_edit_global_private_query", "visibility" => "2", "project_id" => ""
}
}
)
@@ -661,6 +674,7 @@ class QueriesControllerTest < Redmine::ControllerTest
q = Query.find_by_name('test_edit_global_private_query')
assert !q.is_public?
assert q.has_default_columns?
+ assert_nil q.project
assert q.valid?
end
@@ -679,7 +693,7 @@ class QueriesControllerTest < Redmine::ControllerTest
"assigned_to_id" => ["1"], "status_id" => ["1"]
},
:query => {
- "name" => "test_edit_global_public_query", "visibility" => "2"
+ "name" => "test_edit_global_public_query", "visibility" => "2", "project_id" => ""
}
}
)
@@ -687,9 +701,48 @@ class QueriesControllerTest < Redmine::ControllerTest
q = Query.find_by_name('test_edit_global_public_query')
assert q.is_public?
assert q.has_default_columns?
+ assert_nil q.project
assert q.valid?
end
+ def test_update_global_private_query_when_change_global_to_project_should_set_project
+ assert_nil Query.find_by_name('test_edit_global_private_query')
+ @request.session[:user_id] = 3
+ put(
+ :update,
+ :params => {
+ :id => 3,
+ :project_id => 'ecookbook',
+ :query => {
+ "name" => "test_edit_global_private_query", "visibility" => "0", "project_id" => "ecookbook"
+ }
+ }
+ )
+ assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => 3
+ q = Query.find_by_name('test_edit_global_private_query')
+ assert !q.is_global?
+ assert q.project
+ end
+
+ def test_update_project_private_query_when_change_project_to_global_should_not_set_project
+ assert_nil Query.find_by_name('test_edit_project_private_query')
+ @request.session[:user_id] = 3
+ put(
+ :update,
+ :params => {
+ :id => 2,
+ :project_id => 'ecookbook',
+ :query => {
+ "name" => "test_edit_project_private_query", "visibility" => "0", "project_id" => ""
+ }
+ }
+ )
+ assert_redirected_to :controller => 'issues', :action => 'index', :project_id => 'ecookbook', :query_id => 2
+ q = Query.find_by_name('test_edit_project_private_query')
+ assert q.is_global?
+ assert_nil q.project
+ end
+
def test_update_with_failure
@request.session[:user_id] = 1
put(