OSDN Git Service

Warn about subtasks before deleting a parent issue (#6562).
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Sun, 17 Apr 2011 15:17:18 +0000 (15:17 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Sun, 17 Apr 2011 15:17:18 +0000 (15:17 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@5495 e93f8b46-1217-0410-a6f0-8f06a7374b81

49 files changed:
app/controllers/context_menus_controller.rb
app/helpers/issues_helper.rb
app/views/context_menus/issues.html.erb
app/views/issues/_action_menu.rhtml
config/locales/bg.yml
config/locales/bs.yml
config/locales/ca.yml
config/locales/cs.yml
config/locales/da.yml
config/locales/de.yml
config/locales/el.yml
config/locales/en-GB.yml
config/locales/en.yml
config/locales/es.yml
config/locales/eu.yml
config/locales/fa.yml
config/locales/fi.yml
config/locales/fr.yml
config/locales/gl.yml
config/locales/he.yml
config/locales/hr.yml
config/locales/hu.yml
config/locales/id.yml
config/locales/it.yml
config/locales/ja.yml
config/locales/ko.yml
config/locales/lt.yml
config/locales/lv.yml
config/locales/mk.yml
config/locales/mn.yml
config/locales/nl.yml
config/locales/no.yml
config/locales/pl.yml
config/locales/pt-BR.yml
config/locales/pt.yml
config/locales/ro.yml
config/locales/ru.yml
config/locales/sk.yml
config/locales/sl.yml
config/locales/sr-YU.yml
config/locales/sr.yml
config/locales/sv.yml
config/locales/th.yml
config/locales/tr.yml
config/locales/uk.yml
config/locales/vi.yml
config/locales/zh-TW.yml
config/locales/zh.yml
test/unit/helpers/issues_helper_test.rb

index f2ff702..4d69f4f 100644 (file)
@@ -1,5 +1,6 @@
 class ContextMenusController < ApplicationController
   helper :watchers
+  helper :issues
   
   def issues
     @issues = Issue.visible.all(:conditions => {:id => params[:ids]}, :include => :project)
index 86f11c7..078fca6 100644 (file)
@@ -109,6 +109,24 @@ module IssuesHelper
     s
   end
   
+  def issues_destroy_confirmation_message(issues)
+    issues = [issues] unless issues.is_a?(Array)
+    message = l(:text_issues_destroy_confirmation)
+    descendant_count = issues.inject(0) {|memo, i| memo += (i.right - i.left - 1)/2}
+    if descendant_count > 0
+      issues.each do |issue|
+        next if issue.root?
+        issues.each do |other_issue|
+          descendant_count -= 1 if issue.is_descendant_of?(other_issue)
+        end
+      end
+      if descendant_count > 0
+        message << "\n" + l(:text_issues_destroy_descendants_confirmation, :count => descendant_count)
+      end
+    end
+    message
+  end
+  
   def sidebar_queries
     unless @sidebar_queries
       # User can see public queries and his own queries
index f0fa350..7b67c65 100644 (file)
   <li><%= context_menu_link l(:button_move), new_issue_move_path(:ids => @issues.collect(&:id)),
                                :class => 'icon-move', :disabled => !@can[:move]  %></li>
   <li><%= context_menu_link l(:button_delete), {:controller => 'issues', :action => 'destroy', :ids => @issues.collect(&:id), :back_url => @back},
-                            :method => :post, :confirm => l(:text_issues_destroy_confirmation), :class => 'icon-del', :disabled => !@can[:delete] %></li>
+                            :method => :post, :confirm => issues_destroy_confirmation_message(@issues), :class => 'icon-del', :disabled => !@can[:delete] %></li>
 
   <%= call_hook(:view_issues_context_menu_end, {:issues => @issues, :can => @can, :back => @back }) %>
 </ul>
index 67eec6c..0235775 100644 (file)
@@ -5,5 +5,5 @@
 <%= link_to_if_authorized l(:button_duplicate), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue }, :class => 'icon icon-duplicate' %>
 <%= link_to_if_authorized l(:button_copy), {:controller => 'issue_moves', :action => 'new', :id => @issue, :copy_options => {:copy => 't'}}, :class => 'icon icon-copy' %>
 <%= link_to_if_authorized l(:button_move), {:controller => 'issue_moves', :action => 'new', :id => @issue}, :class => 'icon icon-move' %>
-<%= link_to_if_authorized l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, :confirm => (@issue.leaf? ? l(:text_are_you_sure) : l(:text_are_you_sure_with_children)), :method => :post, :class => 'icon icon-del' %>
+<%= link_to_if_authorized l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, :confirm => issues_destroy_confirmation_message(@issue), :method => :post, :class => 'icon icon-del' %>
 </div>
index 1bbf8bd..821d594 100644 (file)
@@ -960,3 +960,4 @@ bg:
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
 
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index e55019e..4948d97 100644 (file)
@@ -973,3 +973,4 @@ bs:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index d73b584..7157e4c 100644 (file)
@@ -962,3 +962,4 @@ ca:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 19d79b7..b80f590 100644 (file)
@@ -963,3 +963,4 @@ cs:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 2837d99..cde8839 100644 (file)
@@ -975,3 +975,4 @@ da:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 4b8777b..aae1495 100644 (file)
@@ -976,3 +976,4 @@ de:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 9a10114..a65cefb 100644 (file)
@@ -959,3 +959,4 @@ el:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index f61d7f3..7c11f7e 100644 (file)
@@ -962,3 +962,4 @@ en-GB:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 82c568f..f5a3ffa 100644 (file)
@@ -906,6 +906,7 @@ en:
   text_status_changed_by_changeset: "Applied in changeset %{value}."
   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_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
index 381ff82..924adfe 100644 (file)
@@ -996,3 +996,4 @@ es:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 7902810..b35f02e 100644 (file)
@@ -963,3 +963,4 @@ eu:
   field_is_private: Private\r
   permission_set_issues_private: Set issues public or private\r
   label_issues_visibility_public: All non private issues\r
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).\r
index 3ac9c72..477eebe 100644 (file)
@@ -962,3 +962,4 @@ fa:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 08714a3..78d43fd 100644 (file)
@@ -980,3 +980,4 @@ fi:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 7d799af..687ce4b 100644 (file)
@@ -883,7 +883,8 @@ fr:
   text_load_default_configuration: Charger le paramétrage par défaut
   text_status_changed_by_changeset: "Appliqué par commit %{value}."
   text_time_logged_by_changeset: "Appliqué par commit %{value}"
-  text_issues_destroy_confirmation: 'Êtes-vous sûr de vouloir supprimer le(s) demandes(s) selectionnée(s) ?'
+  text_issues_destroy_confirmation: 'Êtes-vous sûr de vouloir supprimer la ou les demandes(s) selectionnée(s) ?'
+  text_issues_destroy_descendants_confirmation: "Cela entrainera également la suppression de %{count} sous-tâche(s)."
   text_select_project_modules: 'Sélectionner les modules à activer pour ce projet :'
   text_default_administrator_account_changed: Compte administrateur par défaut changé
   text_file_repository_writable: Répertoire de stockage des fichiers accessible en écriture
index 4e75255..95a6885 100644 (file)
@@ -971,3 +971,4 @@ gl:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index a0416d2..0f57e3f 100644 (file)
@@ -964,3 +964,4 @@ he:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 840a8f8..7dffacf 100644 (file)
@@ -966,3 +966,4 @@ hr:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 6232ce7..94e01d8 100644 (file)
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index e6694b9..e362881 100644 (file)
@@ -967,3 +967,4 @@ id:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index a3b7243..0b164f6 100644 (file)
@@ -960,3 +960,4 @@ it:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 1e64fff..167d336 100644 (file)
@@ -982,3 +982,4 @@ ja:
   field_is_private: プライベート
   permission_set_issues_private: チケットをプライベートに設定
   label_issues_visibility_public: プライベートチケット以外
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 0c205da..342022e 100644 (file)
@@ -1011,3 +1011,4 @@ ko:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index a832d70..225bda2 100644 (file)
@@ -1019,3 +1019,4 @@ lt:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 2089e71..124a15d 100644 (file)
@@ -954,3 +954,4 @@ lv:
   field_is_private: Private\r
   permission_set_issues_private: Set issues public or private\r
   label_issues_visibility_public: All non private issues\r
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).\r
index 6816898..f9e0959 100644 (file)
@@ -959,3 +959,4 @@ mk:
   field_is_private: Private\r
   permission_set_issues_private: Set issues public or private\r
   label_issues_visibility_public: All non private issues\r
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).\r
index 7b29054..d79a248 100644 (file)
@@ -960,3 +960,4 @@ mn:
   field_is_private: Private\r
   permission_set_issues_private: Set issues public or private\r
   label_issues_visibility_public: All non private issues\r
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).\r
index 2a4d637..4243701 100644 (file)
@@ -941,3 +941,4 @@ nl:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 7a0a17b..273de20 100644 (file)
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 734768d..64fc446 100644 (file)
@@ -976,3 +976,4 @@ pl:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index e0e27b4..4b90202 100644 (file)
@@ -979,3 +979,4 @@ pt-BR:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 9916bcb..de5a755 100644 (file)
@@ -964,3 +964,4 @@ pt:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 37ac673..8a9062c 100644 (file)
@@ -952,3 +952,4 @@ ro:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 3395bbe..c56cc37 100644 (file)
@@ -1072,3 +1072,4 @@ ru:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 41fc938..1f00bb3 100644 (file)
@@ -954,3 +954,4 @@ sk:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 653a060..5f8669c 100644 (file)
@@ -955,3 +955,4 @@ sl:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 3c9f2e1..71f919a 100644 (file)
@@ -959,3 +959,4 @@ sr-YU:
   field_is_private: Private\r
   permission_set_issues_private: Set issues public or private\r
   label_issues_visibility_public: All non private issues\r
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).\r
index 42bef34..b069f0e 100644 (file)
@@ -960,3 +960,4 @@ sr:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 8be2c23..aace0e8 100644 (file)
@@ -1000,3 +1000,4 @@ sv:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 6b1afc7..8a9ddc8 100644 (file)
@@ -956,3 +956,4 @@ th:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 8ba316f..c5646f9 100644 (file)
@@ -978,3 +978,4 @@ tr:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index a3c373f..50b5064 100644 (file)
@@ -955,3 +955,4 @@ uk:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 2d9f6ca..188b3e9 100644 (file)
@@ -1010,3 +1010,4 @@ vi:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index cd6f208..b2220e6 100644 (file)
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index 14e0fa9..4b08626 100644 (file)
@@ -973,3 +973,4 @@ zh:
   field_is_private: Private
   permission_set_issues_private: Set issues public or private
   label_issues_visibility_public: All non private issues
+  text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
index dcb1aed..7a40abe 100644 (file)
@@ -47,6 +47,25 @@ class IssuesHelperTest < HelperTestCase
   def test_issue_heading
     assert_equal "Bug #1", issue_heading(Issue.find(1))
   end
+  
+  def test_issues_destroy_confirmation_message_with_one_root_issue
+    assert_equal l(:text_issues_destroy_confirmation), issues_destroy_confirmation_message(Issue.find(1))
+  end
+  
+  def test_issues_destroy_confirmation_message_with_an_arrayt_of_root_issues
+    assert_equal l(:text_issues_destroy_confirmation), issues_destroy_confirmation_message(Issue.find([1, 2]))
+  end
+  
+  def test_issues_destroy_confirmation_message_with_one_parent_issue
+    Issue.find(2).update_attribute :parent_issue_id, 1
+    assert_equal l(:text_issues_destroy_confirmation) + "\n" + l(:text_issues_destroy_descendants_confirmation, :count => 1),
+      issues_destroy_confirmation_message(Issue.find(1))
+  end
+  
+  def test_issues_destroy_confirmation_message_with_one_parent_issue_and_its_child
+    Issue.find(2).update_attribute :parent_issue_id, 1
+    assert_equal l(:text_issues_destroy_confirmation), issues_destroy_confirmation_message(Issue.find([1, 2]))
+  end
 
   context "IssuesHelper#show_detail" do
     context "with no_html" do