# HG changeset patch # User Toshi MARUYAMA # Date 1576636635 -32400 # Wed Dec 18 11:37:15 2019 +0900 # Branch issue-28492-01 # Node ID b17a89d46f0cfa7c5d2c816cbc930ee2c0ad4714 # Parent 588ba6dbb268099f7c2f9bd690eca10942071720 en.yml (#31322) diff --git a/config/locales/en.yml b/config/locales/en.yml --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1190,6 +1190,7 @@ en: text_time_logged_by_changeset: "Applied in changeset %{value}." text_issues_destroy_confirmation: 'Are you sure you want to delete the selected issue(s)?' text_issues_destroy_descendants_confirmation: "This will also delete %{count} subtask(s)." + text_close_parent_issue_whose_subtasks_are_open_confirmation: Are you sure you want to close parent issue whose subtasks are open? text_time_entries_destroy_confirmation: 'Are you sure you want to delete the selected time entr(y/ies)?' text_select_project_modules: 'Select modules to enable for this project:' text_default_administrator_account_changed: Default administrator account changed # HG changeset patch # User Toshi MARUYAMA # Date 1573729157 -32400 # Thu Nov 14 19:59:17 2019 +0900 # Branch issue-28492-01 # Node ID 20d54d2f4ba65ba948f318425501bae018909956 # Parent b17a89d46f0cfa7c5d2c816cbc930ee2c0ad4714 use jQuery submit() (#31322) diff --git a/app/views/issues/_edit.html.erb b/app/views/issues/_edit.html.erb --- a/app/views/issues/_edit.html.erb +++ b/app/views/issues/_edit.html.erb @@ -82,3 +82,21 @@ <%= hidden_field_tag 'issue_position', @issue_position if @issue_position %> <%= hidden_field_tag 'issue_count', @issue_count if @issue_count %> <% end %> +<%= javascript_tag do %> + $('#issue-form').submit(function(){ + var closedIssueStatusIds = + <%= @allowed_statuses.select{|i| i.is_closed?}.map{|i| i.id.to_s}.to_json.html_safe %> ; + var children = $("#issue_tree").find("tr.issue.child"); + if (($.inArray($("#issue_status_id").val(), closedIssueStatusIds) > -1) && + (children.length > 0) && + ((children.length - $("#issue_tree").find("tr.issue.child.closed").length) > 0)) { + if (!confirm( + "<%= l(:text_close_parent_issue_whose_subtasks_are_open_confirmation) %>" + )){ + return false; + } + } + $("#issue-form").off('submit'); + $("#issue-form").submit(); + }); +<% end %> # HG changeset patch # User Toshi MARUYAMA # Date 1571065645 -32400 # Tue Oct 15 00:07:25 2019 +0900 # Branch issue-28492-01 # Node ID 4daf7de2778826cfab6c3181be7edfc03ba8f40f # Parent 20d54d2f4ba65ba948f318425501bae018909956 add system test (#31322) diff --git a/test/system/issues_test.rb b/test/system/issues_test.rb --- a/test/system/issues_test.rb +++ b/test/system/issues_test.rb @@ -234,6 +234,90 @@ class IssuesSystemTest < ApplicationSyst assert_equal 5, issue.reload.status.id end + test "add confirm dialog to issue submit button" do + parent = Issue.generate!(:project_id => 1) + child = Issue.generate!(:project_id => 1, :parent_issue_id => parent.id) + + with_settings :close_parent_issue_whose_subtasks_are_open => 1 do + log_user('dlopper', 'foo') + + visit "/issues/#{parent.id}" + page.first(:link, 'Edit').click + assert page.has_select?("issue_status_id", {:selected => "New"}) + page.find("#issue_status_id").select("Closed") + assert_no_difference ['Issue.count', 'child.journals.count'] do + assert_no_difference 'parent.journals.count' do + page.dismiss_confirm /Are you sure/ do + page.first(:button, 'Submit').click + end + assert_equal 1, parent.reload.status.id + end + assert_difference 'parent.journals.count' do + page.accept_confirm /Are you sure/ do + page.first(:button, 'Submit').click + end + assert page.has_css?('#flash_notice') + assert_equal 5, parent.reload.status.id + end + end + + page.first(:link, 'Edit').click + assert page.has_select?("issue_status_id", {:selected => "Closed"}) + fill_in 'Subject', :with => 'test of confirm dialog' + assert_no_difference ['Issue.count', 'child.journals.count'] do + assert_no_difference 'parent.journals.count' do + page.dismiss_confirm /Are you sure/ do + page.first(:button, 'Submit').click + end + assert_equal 5, parent.reload.status.id + end + assert_difference 'parent.journals.count' do + page.accept_confirm /Are you sure/ do + page.first(:button, 'Submit').click + end + assert page.has_css?('#flash_notice') + assert_equal 5, parent.reload.status.id + assert_equal 'test of confirm dialog', parent.reload.subject + end + end + + page.first(:link, 'Edit').click + assert page.has_select?("issue_status_id", {:selected => "Closed"}) + page.find("#issue_status_id").select("New") + assert_no_difference ['Issue.count', 'child.journals.count'] do + assert_difference 'parent.journals.count' do + page.first(:button, 'Submit').click + assert page.has_css?('#flash_notice') + assert_equal 1, parent.reload.status.id + end + end + + visit "/issues/#{child.id}" + page.first(:link, 'Edit').click + assert page.has_select?("issue_status_id", {:selected => "New"}) + page.find("#issue_status_id").select("Closed") + assert_no_difference ['Issue.count', 'parent.journals.count'] do + assert_difference 'child.journals.count' do + page.first(:button, 'Submit').click + assert page.has_css?('#flash_notice') + assert_equal 5, child.reload.status.id + end + end + + visit "/issues/#{parent.id}" + page.first(:link, 'Edit').click + assert page.has_select?("issue_status_id", {:selected => "New"}) + page.find("#issue_status_id").select("Closed") + assert_no_difference ['Issue.count', 'child.journals.count'] do + assert_difference 'parent.journals.count' do + page.first(:button, 'Submit').click + assert page.has_css?('#flash_notice') + assert_equal 5, parent.reload.status.id + end + end + end + end + test "removing issue shows confirm dialog" do log_user('jsmith', 'jsmith') visit '/issues/1' # HG changeset patch # User Toshi MARUYAMA # Date 1575779246 -32400 # Sun Dec 08 13:27:26 2019 +0900 # Branch issue-28492-01 # Node ID e816dd4394b155cf865021a97774cb43c7148e89 # Parent 4daf7de2778826cfab6c3181be7edfc03ba8f40f use ajax check (#31322) diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -181,6 +181,27 @@ class IssuesController < ApplicationCont end def update + if request.xhr? + if params[:check_go_to_close_confirm] + result = true + status_id = params[:status_id].to_i + if status_id <= 0 + result = false + else + status = IssueStatus.find(status_id) + if !status.is_closed + result = false + else + result = !@issue.descendants.open.empty? + end + end + render :json => {:result => result} + return + end + + return + end + return unless update_issue_from_params @issue.save_attachments(params[:attachments] || diff --git a/app/views/issues/_edit.html.erb b/app/views/issues/_edit.html.erb --- a/app/views/issues/_edit.html.erb +++ b/app/views/issues/_edit.html.erb @@ -84,12 +84,26 @@ <% end %> <%= javascript_tag do %> $('#issue-form').submit(function(){ - var closedIssueStatusIds = - <%= @allowed_statuses.select{|i| i.is_closed?}.map{|i| i.id.to_s}.to_json.html_safe %> ; - var children = $("#issue_tree").find("tr.issue.child"); - if (($.inArray($("#issue_status_id").val(), closedIssueStatusIds) > -1) && - (children.length > 0) && - ((children.length - $("#issue_tree").find("tr.issue.child.closed").length) > 0)) { + var status_id = 0; + var result = false; + if ($("#issue_status_id").length > 0) { + status_id = $("#issue_status_id").val(); + } + $.ajax({ + url: $("#issue-form").attr('action'), + type: 'patch', + async: false, + data: { + "check_go_to_close_confirm": "", + "status_id": status_id + }, + }) + .then( + function(data){ + result = data["result"]; + } + ); + if (result) { if (!confirm( "<%= l(:text_close_parent_issue_whose_subtasks_are_open_confirmation) %>" )){ # HG changeset patch # User Toshi MARUYAMA # Date 1575717833 -32400 # Sat Dec 07 20:23:53 2019 +0900 # Branch issue-28492-01 # Node ID cb70ece3d9471cb1ca2a7b4d3f76cdae26303747 # Parent e816dd4394b155cf865021a97774cb43c7148e89 add ajax check functional tests (#31322) diff --git a/test/functional/issues_controller_test.rb b/test/functional/issues_controller_test.rb --- a/test/functional/issues_controller_test.rb +++ b/test/functional/issues_controller_test.rb @@ -6222,6 +6222,174 @@ class IssuesControllerTest < Redmine::Co assert_equal 2, issue.reload.assigned_to_id end + test "check_go_to_close_confirm returns false if status_id is not close" do + issue = Issue.find(1) + user = User.find(2) + assert issue.visible?(user) + assert_not issue.closed? + @request.session[:user_id] = user.id + put( + :update, + :params => { + :id => issue.id, + :check_go_to_close_confirm => "", + :status_id => 1 + }, + :xhr => true + ) + assert_response :success + assert_equal 'application/json', response.content_type + json = ActiveSupport::JSON.decode(response.body) + assert_equal({"result" => false}, json) + end + + test "check_go_to_close_confirm returns false if status_id is 0" do + issue = Issue.find(1) + user = User.find(2) + assert issue.visible?(user) + assert_not issue.closed? + @request.session[:user_id] = user.id + put( + :update, + :params => { + :id => issue.id, + :check_go_to_close_confirm => "", + :status_id => 0 + }, + :xhr => true + ) + assert_response :success + assert_equal 'application/json', response.content_type + json = ActiveSupport::JSON.decode(response.body) + assert_equal({"result" => false}, json) + end + + test "check_go_to_close_confirm returns false if issue does not have child" do + issue = Issue.generate! + user = User.find(2) + assert issue.visible?(user) + assert_not issue.closed? + @request.session[:user_id] = user.id + put( + :update, + :params => { + :id => issue.id, + :check_go_to_close_confirm => "", + :status_id => 5 + }, + :xhr => true + ) + assert_response :success + assert_equal 'application/json', response.content_type + json = ActiveSupport::JSON.decode(response.body) + + assert_equal 1, issue.reload.status.id + assert_equal({"result" => false}, json) + end + + test "check_go_to_close_confirm returns true if issue have open child" do + parent = Issue.generate! + child = Issue.generate!(:parent_issue_id => parent.id) + user = User.find(2) + assert parent.reload.visible?(user) + assert_not parent.closed? + assert child.reload.visible?(user) + assert_not child.closed? + + @request.session[:user_id] = user.id + put( + :update, + :params => { + :id => parent.id, + :check_go_to_close_confirm => "", + :status_id => 5 + }, + :xhr => true + ) + assert_response :success + assert_equal 'application/json', response.content_type + json = ActiveSupport::JSON.decode(response.body) + + assert_equal 1, parent.reload.status.id + assert_equal({"result" => true}, json) + end + + test "check_go_to_close_confirm returns false if child is closed" do + parent = Issue.generate! + child = Issue. + generate!( + :parent_issue_id => parent.id, + :status_id => 5 + ) + user = User.find(2) + assert parent.reload.visible?(user) + assert_not parent.closed? + assert child.reload.visible?(user) + assert child.closed? + + @request.session[:user_id] = user.id + put( + :update, + :params => { + :id => parent.id, + :check_go_to_close_confirm => "", + :status_id => 5 + }, + :xhr => true + ) + assert_response :success + assert_equal 'application/json', response.content_type + json = ActiveSupport::JSON.decode(response.body) + + assert_equal 1, parent.reload.status.id + assert_equal({"result" => false}, json) + end + + test "check_go_to_close_confirm returns true if child is open and not visible" do + user = User.generate! + project = Project.generate! + role = Role.generate! + role.add_permission! :view_issues, :edit_issues + role.set_permission_trackers :view_issues, [2] + role.set_permission_trackers :edit_issues, [2] + role.save! + User.add_to_project(user, project, role) + parent = Issue. + generate!( + :project => project, + :tracker_id => 2, + :status_id => 1 + ) + child = Issue. + generate!( + :project => project, + :tracker_id => 1, + :parent_issue_id => parent.id, + :status_id => 1 + ) + assert parent.reload.visible?(user) + assert_not parent.closed? + assert_not child.reload.visible?(user) + assert_not child.closed? + + @request.session[:user_id] = user.id + put( + :update, + :params => { + :id => parent.id, + :check_go_to_close_confirm => "", + :status_id => 5 + }, + :xhr => true + ) + assert_response :success + assert_equal 'application/json', response.content_type + json = ActiveSupport::JSON.decode(response.body) + + assert_equal 1, parent.reload.status.id + assert_equal({"result" => true}, json) + end + def test_get_bulk_edit @request.session[:user_id] = 2 get(:bulk_edit, :params => {:ids => [1, 3]})