##// END OF EJS Templates
Warn about subtasks before deleting a parent issue (#6562)....
Jean-Philippe Lang -
r5375:f89d04074e56
parent child
Show More
@@ -1,5 +1,6
1 class ContextMenusController < ApplicationController
1 class ContextMenusController < ApplicationController
2 helper :watchers
2 helper :watchers
3 helper :issues
3
4
4 def issues
5 def issues
5 @issues = Issue.visible.all(:conditions => {:id => params[:ids]}, :include => :project)
6 @issues = Issue.visible.all(:conditions => {:id => params[:ids]}, :include => :project)
@@ -109,6 +109,24 module IssuesHelper
109 s
109 s
110 end
110 end
111
111
112 def issues_destroy_confirmation_message(issues)
113 issues = [issues] unless issues.is_a?(Array)
114 message = l(:text_issues_destroy_confirmation)
115 descendant_count = issues.inject(0) {|memo, i| memo += (i.right - i.left - 1)/2}
116 if descendant_count > 0
117 issues.each do |issue|
118 next if issue.root?
119 issues.each do |other_issue|
120 descendant_count -= 1 if issue.is_descendant_of?(other_issue)
121 end
122 end
123 if descendant_count > 0
124 message << "\n" + l(:text_issues_destroy_descendants_confirmation, :count => descendant_count)
125 end
126 end
127 message
128 end
129
112 def sidebar_queries
130 def sidebar_queries
113 unless @sidebar_queries
131 unless @sidebar_queries
114 # User can see public queries and his own queries
132 # User can see public queries and his own queries
@@ -115,7 +115,7
115 <li><%= context_menu_link l(:button_move), new_issue_move_path(:ids => @issues.collect(&:id)),
115 <li><%= context_menu_link l(:button_move), new_issue_move_path(:ids => @issues.collect(&:id)),
116 :class => 'icon-move', :disabled => !@can[:move] %></li>
116 :class => 'icon-move', :disabled => !@can[:move] %></li>
117 <li><%= context_menu_link l(:button_delete), {:controller => 'issues', :action => 'destroy', :ids => @issues.collect(&:id), :back_url => @back},
117 <li><%= context_menu_link l(:button_delete), {:controller => 'issues', :action => 'destroy', :ids => @issues.collect(&:id), :back_url => @back},
118 :method => :post, :confirm => l(:text_issues_destroy_confirmation), :class => 'icon-del', :disabled => !@can[:delete] %></li>
118 :method => :post, :confirm => issues_destroy_confirmation_message(@issues), :class => 'icon-del', :disabled => !@can[:delete] %></li>
119
119
120 <%= call_hook(:view_issues_context_menu_end, {:issues => @issues, :can => @can, :back => @back }) %>
120 <%= call_hook(:view_issues_context_menu_end, {:issues => @issues, :can => @can, :back => @back }) %>
121 </ul>
121 </ul>
@@ -5,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' %>
5 <%= link_to_if_authorized l(:button_duplicate), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue }, :class => 'icon icon-duplicate' %>
6 <%= link_to_if_authorized l(:button_copy), {:controller => 'issue_moves', :action => 'new', :id => @issue, :copy_options => {:copy => 't'}}, :class => 'icon icon-copy' %>
6 <%= link_to_if_authorized l(:button_copy), {:controller => 'issue_moves', :action => 'new', :id => @issue, :copy_options => {:copy => 't'}}, :class => 'icon icon-copy' %>
7 <%= link_to_if_authorized l(:button_move), {:controller => 'issue_moves', :action => 'new', :id => @issue}, :class => 'icon icon-move' %>
7 <%= link_to_if_authorized l(:button_move), {:controller => 'issue_moves', :action => 'new', :id => @issue}, :class => 'icon icon-move' %>
8 <%= 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' %>
8 <%= 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' %>
9 </div>
9 </div>
@@ -960,3 +960,4 bg:
960 permission_set_issues_private: Set issues public or private
960 permission_set_issues_private: Set issues public or private
961 label_issues_visibility_public: All non private issues
961 label_issues_visibility_public: All non private issues
962
962
963 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -973,3 +973,4 bs:
973 field_is_private: Private
973 field_is_private: Private
974 permission_set_issues_private: Set issues public or private
974 permission_set_issues_private: Set issues public or private
975 label_issues_visibility_public: All non private issues
975 label_issues_visibility_public: All non private issues
976 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -962,3 +962,4 ca:
962 field_is_private: Private
962 field_is_private: Private
963 permission_set_issues_private: Set issues public or private
963 permission_set_issues_private: Set issues public or private
964 label_issues_visibility_public: All non private issues
964 label_issues_visibility_public: All non private issues
965 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -963,3 +963,4 cs:
963 field_is_private: Private
963 field_is_private: Private
964 permission_set_issues_private: Set issues public or private
964 permission_set_issues_private: Set issues public or private
965 label_issues_visibility_public: All non private issues
965 label_issues_visibility_public: All non private issues
966 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -975,3 +975,4 da:
975 field_is_private: Private
975 field_is_private: Private
976 permission_set_issues_private: Set issues public or private
976 permission_set_issues_private: Set issues public or private
977 label_issues_visibility_public: All non private issues
977 label_issues_visibility_public: All non private issues
978 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -976,3 +976,4 de:
976 field_is_private: Private
976 field_is_private: Private
977 permission_set_issues_private: Set issues public or private
977 permission_set_issues_private: Set issues public or private
978 label_issues_visibility_public: All non private issues
978 label_issues_visibility_public: All non private issues
979 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -959,3 +959,4 el:
959 field_is_private: Private
959 field_is_private: Private
960 permission_set_issues_private: Set issues public or private
960 permission_set_issues_private: Set issues public or private
961 label_issues_visibility_public: All non private issues
961 label_issues_visibility_public: All non private issues
962 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -962,3 +962,4 en-GB:
962 field_is_private: Private
962 field_is_private: Private
963 permission_set_issues_private: Set issues public or private
963 permission_set_issues_private: Set issues public or private
964 label_issues_visibility_public: All non private issues
964 label_issues_visibility_public: All non private issues
965 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -906,6 +906,7 en:
906 text_status_changed_by_changeset: "Applied in changeset %{value}."
906 text_status_changed_by_changeset: "Applied in changeset %{value}."
907 text_time_logged_by_changeset: "Applied in changeset %{value}."
907 text_time_logged_by_changeset: "Applied in changeset %{value}."
908 text_issues_destroy_confirmation: 'Are you sure you want to delete the selected issue(s)?'
908 text_issues_destroy_confirmation: 'Are you sure you want to delete the selected issue(s)?'
909 text_issues_destroy_descendants_confirmation: "This will also delete %{count} subtask(s)."
909 text_time_entries_destroy_confirmation: 'Are you sure you want to delete the selected time entr(y/ies)?'
910 text_time_entries_destroy_confirmation: 'Are you sure you want to delete the selected time entr(y/ies)?'
910 text_select_project_modules: 'Select modules to enable for this project:'
911 text_select_project_modules: 'Select modules to enable for this project:'
911 text_default_administrator_account_changed: Default administrator account changed
912 text_default_administrator_account_changed: Default administrator account changed
@@ -996,3 +996,4 es:
996 field_is_private: Private
996 field_is_private: Private
997 permission_set_issues_private: Set issues public or private
997 permission_set_issues_private: Set issues public or private
998 label_issues_visibility_public: All non private issues
998 label_issues_visibility_public: All non private issues
999 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -963,3 +963,4 eu:
963 field_is_private: Private
963 field_is_private: Private
964 permission_set_issues_private: Set issues public or private
964 permission_set_issues_private: Set issues public or private
965 label_issues_visibility_public: All non private issues
965 label_issues_visibility_public: All non private issues
966 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -962,3 +962,4 fa:
962 field_is_private: Private
962 field_is_private: Private
963 permission_set_issues_private: Set issues public or private
963 permission_set_issues_private: Set issues public or private
964 label_issues_visibility_public: All non private issues
964 label_issues_visibility_public: All non private issues
965 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -980,3 +980,4 fi:
980 field_is_private: Private
980 field_is_private: Private
981 permission_set_issues_private: Set issues public or private
981 permission_set_issues_private: Set issues public or private
982 label_issues_visibility_public: All non private issues
982 label_issues_visibility_public: All non private issues
983 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -883,7 +883,8 fr:
883 text_load_default_configuration: Charger le paramétrage par défaut
883 text_load_default_configuration: Charger le paramétrage par défaut
884 text_status_changed_by_changeset: "Appliqué par commit %{value}."
884 text_status_changed_by_changeset: "Appliqué par commit %{value}."
885 text_time_logged_by_changeset: "Appliqué par commit %{value}"
885 text_time_logged_by_changeset: "Appliqué par commit %{value}"
886 text_issues_destroy_confirmation: 'Êtes-vous sûr de vouloir supprimer le(s) demandes(s) selectionnée(s) ?'
886 text_issues_destroy_confirmation: 'Êtes-vous sûr de vouloir supprimer la ou les demandes(s) selectionnée(s) ?'
887 text_issues_destroy_descendants_confirmation: "Cela entrainera également la suppression de %{count} sous-tâche(s)."
887 text_select_project_modules: 'Sélectionner les modules à activer pour ce projet :'
888 text_select_project_modules: 'Sélectionner les modules à activer pour ce projet :'
888 text_default_administrator_account_changed: Compte administrateur par défaut changé
889 text_default_administrator_account_changed: Compte administrateur par défaut changé
889 text_file_repository_writable: Répertoire de stockage des fichiers accessible en écriture
890 text_file_repository_writable: Répertoire de stockage des fichiers accessible en écriture
@@ -971,3 +971,4 gl:
971 field_is_private: Private
971 field_is_private: Private
972 permission_set_issues_private: Set issues public or private
972 permission_set_issues_private: Set issues public or private
973 label_issues_visibility_public: All non private issues
973 label_issues_visibility_public: All non private issues
974 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -964,3 +964,4 he:
964 field_is_private: Private
964 field_is_private: Private
965 permission_set_issues_private: Set issues public or private
965 permission_set_issues_private: Set issues public or private
966 label_issues_visibility_public: All non private issues
966 label_issues_visibility_public: All non private issues
967 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -966,3 +966,4 hr:
966 field_is_private: Private
966 field_is_private: Private
967 permission_set_issues_private: Set issues public or private
967 permission_set_issues_private: Set issues public or private
968 label_issues_visibility_public: All non private issues
968 label_issues_visibility_public: All non private issues
969 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -978,3 +978,4
978 field_is_private: Private
978 field_is_private: Private
979 permission_set_issues_private: Set issues public or private
979 permission_set_issues_private: Set issues public or private
980 label_issues_visibility_public: All non private issues
980 label_issues_visibility_public: All non private issues
981 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -967,3 +967,4 id:
967 field_is_private: Private
967 field_is_private: Private
968 permission_set_issues_private: Set issues public or private
968 permission_set_issues_private: Set issues public or private
969 label_issues_visibility_public: All non private issues
969 label_issues_visibility_public: All non private issues
970 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -960,3 +960,4 it:
960 field_is_private: Private
960 field_is_private: Private
961 permission_set_issues_private: Set issues public or private
961 permission_set_issues_private: Set issues public or private
962 label_issues_visibility_public: All non private issues
962 label_issues_visibility_public: All non private issues
963 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -982,3 +982,4 ja:
982 field_is_private: プライベート
982 field_is_private: プライベート
983 permission_set_issues_private: チケットをプライベートに設定
983 permission_set_issues_private: チケットをプライベートに設定
984 label_issues_visibility_public: プライベートチケット以外
984 label_issues_visibility_public: プライベートチケット以外
985 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -1011,3 +1011,4 ko:
1011 field_is_private: Private
1011 field_is_private: Private
1012 permission_set_issues_private: Set issues public or private
1012 permission_set_issues_private: Set issues public or private
1013 label_issues_visibility_public: All non private issues
1013 label_issues_visibility_public: All non private issues
1014 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -1019,3 +1019,4 lt:
1019 field_is_private: Private
1019 field_is_private: Private
1020 permission_set_issues_private: Set issues public or private
1020 permission_set_issues_private: Set issues public or private
1021 label_issues_visibility_public: All non private issues
1021 label_issues_visibility_public: All non private issues
1022 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -954,3 +954,4 lv:
954 field_is_private: Private
954 field_is_private: Private
955 permission_set_issues_private: Set issues public or private
955 permission_set_issues_private: Set issues public or private
956 label_issues_visibility_public: All non private issues
956 label_issues_visibility_public: All non private issues
957 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -959,3 +959,4 mk:
959 field_is_private: Private
959 field_is_private: Private
960 permission_set_issues_private: Set issues public or private
960 permission_set_issues_private: Set issues public or private
961 label_issues_visibility_public: All non private issues
961 label_issues_visibility_public: All non private issues
962 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -960,3 +960,4 mn:
960 field_is_private: Private
960 field_is_private: Private
961 permission_set_issues_private: Set issues public or private
961 permission_set_issues_private: Set issues public or private
962 label_issues_visibility_public: All non private issues
962 label_issues_visibility_public: All non private issues
963 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -941,3 +941,4 nl:
941 field_is_private: Private
941 field_is_private: Private
942 permission_set_issues_private: Set issues public or private
942 permission_set_issues_private: Set issues public or private
943 label_issues_visibility_public: All non private issues
943 label_issues_visibility_public: All non private issues
944 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -946,3 +946,4
946 field_is_private: Private
946 field_is_private: Private
947 permission_set_issues_private: Set issues public or private
947 permission_set_issues_private: Set issues public or private
948 label_issues_visibility_public: All non private issues
948 label_issues_visibility_public: All non private issues
949 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -976,3 +976,4 pl:
976 field_is_private: Private
976 field_is_private: Private
977 permission_set_issues_private: Set issues public or private
977 permission_set_issues_private: Set issues public or private
978 label_issues_visibility_public: All non private issues
978 label_issues_visibility_public: All non private issues
979 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -979,3 +979,4 pt-BR:
979 field_is_private: Private
979 field_is_private: Private
980 permission_set_issues_private: Set issues public or private
980 permission_set_issues_private: Set issues public or private
981 label_issues_visibility_public: All non private issues
981 label_issues_visibility_public: All non private issues
982 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -964,3 +964,4 pt:
964 field_is_private: Private
964 field_is_private: Private
965 permission_set_issues_private: Set issues public or private
965 permission_set_issues_private: Set issues public or private
966 label_issues_visibility_public: All non private issues
966 label_issues_visibility_public: All non private issues
967 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -952,3 +952,4 ro:
952 field_is_private: Private
952 field_is_private: Private
953 permission_set_issues_private: Set issues public or private
953 permission_set_issues_private: Set issues public or private
954 label_issues_visibility_public: All non private issues
954 label_issues_visibility_public: All non private issues
955 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -1072,3 +1072,4 ru:
1072 field_is_private: Private
1072 field_is_private: Private
1073 permission_set_issues_private: Set issues public or private
1073 permission_set_issues_private: Set issues public or private
1074 label_issues_visibility_public: All non private issues
1074 label_issues_visibility_public: All non private issues
1075 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -954,3 +954,4 sk:
954 field_is_private: Private
954 field_is_private: Private
955 permission_set_issues_private: Set issues public or private
955 permission_set_issues_private: Set issues public or private
956 label_issues_visibility_public: All non private issues
956 label_issues_visibility_public: All non private issues
957 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -955,3 +955,4 sl:
955 field_is_private: Private
955 field_is_private: Private
956 permission_set_issues_private: Set issues public or private
956 permission_set_issues_private: Set issues public or private
957 label_issues_visibility_public: All non private issues
957 label_issues_visibility_public: All non private issues
958 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -959,3 +959,4 sr-YU:
959 field_is_private: Private
959 field_is_private: Private
960 permission_set_issues_private: Set issues public or private
960 permission_set_issues_private: Set issues public or private
961 label_issues_visibility_public: All non private issues
961 label_issues_visibility_public: All non private issues
962 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -960,3 +960,4 sr:
960 field_is_private: Private
960 field_is_private: Private
961 permission_set_issues_private: Set issues public or private
961 permission_set_issues_private: Set issues public or private
962 label_issues_visibility_public: All non private issues
962 label_issues_visibility_public: All non private issues
963 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -1000,3 +1000,4 sv:
1000 field_is_private: Private
1000 field_is_private: Private
1001 permission_set_issues_private: Set issues public or private
1001 permission_set_issues_private: Set issues public or private
1002 label_issues_visibility_public: All non private issues
1002 label_issues_visibility_public: All non private issues
1003 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -956,3 +956,4 th:
956 field_is_private: Private
956 field_is_private: Private
957 permission_set_issues_private: Set issues public or private
957 permission_set_issues_private: Set issues public or private
958 label_issues_visibility_public: All non private issues
958 label_issues_visibility_public: All non private issues
959 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -978,3 +978,4 tr:
978 field_is_private: Private
978 field_is_private: Private
979 permission_set_issues_private: Set issues public or private
979 permission_set_issues_private: Set issues public or private
980 label_issues_visibility_public: All non private issues
980 label_issues_visibility_public: All non private issues
981 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -955,3 +955,4 uk:
955 field_is_private: Private
955 field_is_private: Private
956 permission_set_issues_private: Set issues public or private
956 permission_set_issues_private: Set issues public or private
957 label_issues_visibility_public: All non private issues
957 label_issues_visibility_public: All non private issues
958 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -1010,3 +1010,4 vi:
1010 field_is_private: Private
1010 field_is_private: Private
1011 permission_set_issues_private: Set issues public or private
1011 permission_set_issues_private: Set issues public or private
1012 label_issues_visibility_public: All non private issues
1012 label_issues_visibility_public: All non private issues
1013 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -1041,3 +1041,4
1041 field_is_private: Private
1041 field_is_private: Private
1042 permission_set_issues_private: Set issues public or private
1042 permission_set_issues_private: Set issues public or private
1043 label_issues_visibility_public: All non private issues
1043 label_issues_visibility_public: All non private issues
1044 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -973,3 +973,4 zh:
973 field_is_private: Private
973 field_is_private: Private
974 permission_set_issues_private: Set issues public or private
974 permission_set_issues_private: Set issues public or private
975 label_issues_visibility_public: All non private issues
975 label_issues_visibility_public: All non private issues
976 text_issues_destroy_descendants_confirmation: This will also delete %{count} subtask(s).
@@ -47,6 +47,25 class IssuesHelperTest < HelperTestCase
47 def test_issue_heading
47 def test_issue_heading
48 assert_equal "Bug #1", issue_heading(Issue.find(1))
48 assert_equal "Bug #1", issue_heading(Issue.find(1))
49 end
49 end
50
51 def test_issues_destroy_confirmation_message_with_one_root_issue
52 assert_equal l(:text_issues_destroy_confirmation), issues_destroy_confirmation_message(Issue.find(1))
53 end
54
55 def test_issues_destroy_confirmation_message_with_an_arrayt_of_root_issues
56 assert_equal l(:text_issues_destroy_confirmation), issues_destroy_confirmation_message(Issue.find([1, 2]))
57 end
58
59 def test_issues_destroy_confirmation_message_with_one_parent_issue
60 Issue.find(2).update_attribute :parent_issue_id, 1
61 assert_equal l(:text_issues_destroy_confirmation) + "\n" + l(:text_issues_destroy_descendants_confirmation, :count => 1),
62 issues_destroy_confirmation_message(Issue.find(1))
63 end
64
65 def test_issues_destroy_confirmation_message_with_one_parent_issue_and_its_child
66 Issue.find(2).update_attribute :parent_issue_id, 1
67 assert_equal l(:text_issues_destroy_confirmation), issues_destroy_confirmation_message(Issue.find([1, 2]))
68 end
50
69
51 context "IssuesHelper#show_detail" do
70 context "IssuesHelper#show_detail" do
52 context "with no_html" do
71 context "with no_html" do
General Comments 0
You need to be logged in to leave comments. Login now