]> source.dussan.org Git - redmine.git/commitdiff
Adds a "Manage related isses" permission to add/remove commits/issues relations manua...
authorJean-Philippe Lang <jp_lang@yahoo.fr>
Sun, 5 Feb 2012 10:56:27 +0000 (10:56 +0000)
committerJean-Philippe Lang <jp_lang@yahoo.fr>
Sun, 5 Feb 2012 10:56:27 +0000 (10:56 +0000)
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@8777 e93f8b46-1217-0410-a6f0-8f06a7374b81

56 files changed:
app/controllers/repositories_controller.rb
app/models/changeset.rb
app/views/repositories/_related_issues.html.erb [new file with mode: 0644]
app/views/repositories/revision.html.erb
config/locales/ar.yml
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
config/routes.rb
lib/redmine.rb
lib/redmine/default_data/loader.rb
public/stylesheets/application.css
test/fixtures/roles.yml
test/functional/repositories_controller_test.rb
test/integration/routing/repositories_test.rb

index cd467d2d721b4528df1d9575447949ac4dfbfc07..73892b1d8cacbc1862a6c5a7c52196013f1d4cf6 100644 (file)
@@ -30,6 +30,7 @@ class RepositoriesController < ApplicationController
   before_filter :find_project_by_project_id, :only => [:new, :create]
   before_filter :find_repository, :only => [:edit, :update, :destroy, :committers]
   before_filter :find_project_repository, :except => [:new, :create, :edit, :update, :destroy, :committers]
+  before_filter :find_changeset, :only => [:revision, :add_related_issue, :remove_related_issue]
   before_filter :authorize
   accept_rss_auth :revisions
 
@@ -185,16 +186,56 @@ class RepositoriesController < ApplicationController
   end
 
   def revision
-    raise ChangesetNotFound if @rev.blank?
-    @changeset = @repository.find_changeset_by_name(@rev)
-    raise ChangesetNotFound unless @changeset
-
     respond_to do |format|
       format.html
       format.js {render :layout => false}
     end
-  rescue ChangesetNotFound
-    show_error_not_found
+  end
+
+  # Adds a related issue to a changeset
+  # POST /projects/:project_id/repository/(:repository_id/)revisions/:rev/issues
+  def add_related_issue
+    @issue = @changeset.find_referenced_issue_by_id(params[:issue_id])
+    if @issue && (!@issue.visible? || @changeset.issues.include?(@issue))
+      @issue = nil
+    end
+
+    if @issue
+      @changeset.issues << @issue
+      respond_to do |format|
+        format.js {
+          render :update do |page|
+            page.replace_html "related-issues", :partial => "related_issues"
+            page.visual_effect :highlight, "related-issue-#{@issue.id}"
+          end
+        }
+      end
+    else
+      respond_to do |format|
+        format.js {
+          render :update do |page|
+            page.alert(l(:label_issue) + ' ' + l('activerecord.errors.messages.invalid'))
+          end
+        }
+      end
+    end
+  end
+
+  # Removes a related issue from a changeset
+  # DELETE /projects/:project_id/repository/(:repository_id/)revisions/:rev/issues/:issue_id
+  def remove_related_issue
+    @issue = Issue.visible.find_by_id(params[:issue_id])
+    if @issue 
+      @changeset.issues.delete(@issue)
+    end
+
+    respond_to do |format|
+      format.js {
+        render :update do |page|
+          page.remove "related-issue-#{@issue.id}"
+        end if @issue
+      }
+    end
   end
 
   def diff
@@ -282,6 +323,13 @@ class RepositoriesController < ApplicationController
     show_error_not_found
   end
 
+  def find_changeset
+    if @rev.present?
+      @changeset = @repository.find_changeset_by_name(@rev)
+    end
+    show_error_not_found unless @changeset
+  end
+
   def show_error_not_found
     render_error :message => l(:error_scm_not_found), :status => 404
   end
index d017ad03bd5cb98974c86dc5dda4cd16cf1c8a61..1e9a12e7cbe9f046110d6f3d38b4c525a03c57f7 100644 (file)
@@ -184,8 +184,6 @@ class Changeset < ActiveRecord::Base
                   :from_revision => change[:from_revision])
   end
 
-  private
-
   # Finds an issue that can be referenced by the commit message
   def find_referenced_issue_by_id(id)
     return nil if id.blank?
@@ -203,6 +201,8 @@ class Changeset < ActiveRecord::Base
     issue
   end
 
+  private
+
   def fix_issue(issue)
     status = IssueStatus.find_by_id(Setting.commit_fix_status_id.to_i)
     if status.nil?
diff --git a/app/views/repositories/_related_issues.html.erb b/app/views/repositories/_related_issues.html.erb
new file mode 100644 (file)
index 0000000..d65d079
--- /dev/null
@@ -0,0 +1,34 @@
+<% manage_allowed = User.current.allowed_to?(:manage_related_issues, @repository.project) %>
+
+<div id="related-issues">
+<% if manage_allowed %>
+  <div class="contextual">
+    <%= toggle_link l(:button_add), 'new-relation-form', {:focus => 'issue_id'} %>
+  </div>
+<% end %>
+
+<h3><%= l(:label_related_issues) %></h3>
+<ul>
+<% @changeset.issues.visible.each do |issue| %>
+  <li id="<%= "related-issue-#{issue.id}" %>"><%= link_to_issue issue %>
+    <%= link_to_remote(image_tag('link_break.png'), 
+      {:url => {:controller => 'repositories', :action => 'remove_related_issue', :id => @project, :repository_id => @repository.identifier_param, :rev => @changeset.identifier, :issue_id => issue},
+       :method => :delete,
+      }, :title => l(:label_relation_delete)) if manage_allowed %>
+
+  </li>
+<% end %>
+</ul>
+
+<% if manage_allowed %>
+  <% remote_form_for(:issue, @issue, 
+       :url => {:controller => 'repositories', :action => 'add_related_issue', :id => @project, :repository_id => @repository.identifier_param, :rev => @changeset.identifier},
+       :method => :post,
+       :complete => "Form.Element.focus('issue_id');",
+       :html => {:id => 'new-relation-form', :style => (@issue ? '' : 'display: none;')}) do |f| %>
+  <%= l(:label_issue) %> #<%= text_field_tag 'issue_id', '', :size => 10 %>
+  <%= submit_tag l(:button_add) %>
+  <%= toggle_link l(:button_cancel), 'new-relation-form'%>
+  <% end %>
+<% end %>
+</div>
index 7c44cd6746764ef6ad5d670e8dbfec884724db53..4e7ad4c2a6b54f8fb19a23eabd7a82b3f5b86a52 100644 (file)
 
 <%= textilizable @changeset.comments %>
 
-<% if @changeset.issues.visible.any? %>
-<h3><%= l(:label_related_issues) %></h3>
-<ul>
-<% @changeset.issues.visible.each do |issue| %>
-  <li><%= link_to_issue issue %></li>
-<% end %>
-</ul>
+<% if @changeset.issues.visible.any? || User.current.allowed_to?(:manage_related_issues, @repository.project) %>
+  <%= render :partial => 'related_issues' %>
 <% end %>
 
 <% if User.current.allowed_to?(:browse_repository, @project) %>
index 6cbc4b273ec6da299469644e76f134037c615879..2e262f83ee83f1a62a5f9c5afcd93f6cde5802e1 100644 (file)
@@ -1022,3 +1022,4 @@ ar:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 4684cb70851fe77947818a02d0e16c865eb429e0..8de05cd2c1e3e3fcddc07a5dfa8ce38cd6eb14c9 100644 (file)
@@ -1020,3 +1020,4 @@ bg:
   description_date_range_interval: Изберете диапазон чрез задаване на начална и крайна дати
   description_date_from: Въведете начална дата
   description_date_to: Въведете крайна дата
+  permission_manage_related_issues: Manage related issues
index 03113862368bc469999a7528e60a42eb2b36b449..147b687c21e550bd762a6d8c2935be9ac255e7af 100644 (file)
@@ -1036,3 +1036,4 @@ bs:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 77097eac1d9468a3b6c38a8acf255a5ae7f70224..86e997c2ebdfe7751951a685db87dd6493ad5351 100644 (file)
@@ -1024,3 +1024,4 @@ ca:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 09f265d6e1d33dfd1824c96500ff3f57f0027b2e..f2e08f4d699c082d95b12fe2f15c22315b877425 100644 (file)
@@ -1025,3 +1025,4 @@ cs:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 538a33bc02d5d3d6adb52cdd1000b27782ba72a8..386574965d17e6e7f6feff2b0ef43457273aac70 100644 (file)
@@ -1039,3 +1039,4 @@ da:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index b6f433ed1f9d23f35b72ee23533a9f5b1cee2942..aef54570925a56dbee673a53118dd96a860e4b67 100644 (file)
@@ -1042,3 +1042,4 @@ de:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 8c033eb363bf563a9d1ca24ba2e05323226a61c3..50537d5aac3a2a9375ac32cd2c9543886ed2450b 100644 (file)
@@ -1022,3 +1022,4 @@ el:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index a89dafaf1a4ec2204521d471d22171d7086fd056..2cbd77065b97fa5301603c362a2c6e65bf9f5dab 100644 (file)
@@ -1024,3 +1024,4 @@ en-GB:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 47f00983074e93ef068c3d6094d421606f8b9dfe..d2cdb82203fe17d0522b328e3f20398d4afa72fa 100644 (file)
@@ -440,6 +440,7 @@ en:
   permission_delete_own_messages: Delete own messages
   permission_export_wiki_pages: Export wiki pages
   permission_manage_subtasks: Manage subtasks
+  permission_manage_related_issues: Manage related issues
 
   project_module_issue_tracking: Issue tracking
   project_module_time_tracking: Time tracking
index 407e94c81fba335c2d48cc35838c89782112da21..19531ca77f5bea535a16ca9a314bec34a1a66712 100644 (file)
@@ -1059,3 +1059,4 @@ es:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 67c546a4a50db7e2c6090f448d852520ecf751fe..a85e7cd8bdb0293216ee30c1d9a4f823e636fa09 100644 (file)
@@ -1025,3 +1025,4 @@ eu:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 13e9161f91a53353a1c1f548b5772f1ac1686eef..bd10913a37751116c8647e98d4995670f221d11f 100644 (file)
@@ -1024,3 +1024,4 @@ fa:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 2f8c01249b1aed46f19b1efb1419bef977c2b16c..2da468723fce2223d0d03c410fd8a07f49396813 100644 (file)
@@ -1043,3 +1043,4 @@ fi:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 77241b29344999030d1149bd82e85f141936007e..7ba367c710d69370e50610e1fce7923c26ca3ca3 100644 (file)
@@ -436,6 +436,7 @@ fr:
   permission_export_wiki_pages: Exporter les pages
   permission_manage_project_activities: Gérer les activités
   permission_manage_subtasks: Gérer les sous-tâches
+  permission_manage_related_issues: Gérer les demandes associées
 
   project_module_issue_tracking: Suivi des demandes
   project_module_time_tracking: Suivi du temps passé
index c4e3216ed03596f9eefe8ab0f6a8acacf32a371d..17b583a08e6d49f5719c920fbdeff198e028e0b4 100644 (file)
@@ -1033,3 +1033,4 @@ gl:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 73ad5b368e4d97123ba3a092e3f89e4d951f4c3b..0a5671302f5f4a554f00840cb64f9d1fef6127ed 100644 (file)
@@ -1027,3 +1027,4 @@ he:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index f4fc6e91b14de7fc84a7f76b842f637abc60ec3e..462615d287897b5631159ad806fff93f7633c948 100644 (file)
@@ -1028,3 +1028,4 @@ hr:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 96ea2bbc1eaeec337029d20ef80572175b8fc99e..363575d44b27da7606ce1a4cfbc40dbf49ca4fe3 100644 (file)
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 9874afe1f8d12b6278507aea8a91d487b1ea5b10..e6ab8d1a7f5b7f64c91129c37217c6d89e6089e3 100644 (file)
@@ -1028,3 +1028,4 @@ id:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 4c2e2b08fa335f6e91616710a484bf1c0ce578d8..c91879396a0fb6679e46165259c65a9ccc3833c5 100644 (file)
@@ -1023,3 +1023,4 @@ it:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 0fbb23a9ec5ccf49d7622769162bc4b1d4044c52..f6635cbfea3a9273821dd885fa0f78e81933d66b 100644 (file)
@@ -1052,3 +1052,4 @@ ja:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index f38641bd73284ff3efd6a88335c16719f9e254b8..60f3af8ee2b95f3f5e868e4b2eafb4fb0c1fdd34 100644 (file)
@@ -1072,3 +1072,4 @@ ko:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index a1cd35bb1366a865f3fcdb9eb0d2599bc7cddaa8..921e437f29b360368249498b871472b6607aaeac 100644 (file)
@@ -1082,3 +1082,4 @@ lt:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index adeafaff3121cf36606e1b7e3b894628b1a6b1fa..05a1cc7636d1d0a34cdda3573b6331ca900b1fae 100644 (file)
@@ -1016,3 +1016,4 @@ lv:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index fb79c4cbee486d8f0c98ce43a2d0d81312838329..6f2fb2a0fca996b4fd0574046ee45167cbaf097a 100644 (file)
@@ -1022,3 +1022,4 @@ mk:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 4b589adbf9b6727d5e64ed2b0bb679d8563ecc7d..c4f3ca752df72b64350bf0615eaae177ea93d8de 100644 (file)
@@ -1022,3 +1022,4 @@ mn:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index f73b46bcfe26539aa551ffc0a7422537c24eb557..4db1f7425014e6e47a68e84295d7524370eb2dc3 100644 (file)
@@ -1004,3 +1004,4 @@ nl:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 1acd50d79383c4ce0f74ee0b1d76d331ac07089a..18689cb9261de0ca59f23d0fb5b902eeeff45b4a 100644 (file)
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 6d841e26d94051268641b7c2060225a41b33d31c..4aa4181676e30dcde7f03f647deaa660dec13222 100644 (file)
@@ -1039,3 +1039,4 @@ pl:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 1dc70a179a2fd6ef875b0a53e18702c5c3629f74..b26d133678edb8b59cd999523ae23f9f2951f6a9 100644 (file)
@@ -1045,3 +1045,4 @@ pt-BR:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 737d8044c3655aabce33ec9409654a512f5c841f..ecbca943110129b4c29ebeeb5bb04cbcd7676300 100644 (file)
@@ -1027,3 +1027,4 @@ pt:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 62378ce6e31bf938d75b517154ecb923ca67aa1e..6b243c65ea0159306f5acc62594d050911c3aff3 100644 (file)
@@ -1019,3 +1019,4 @@ ro:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 8ac0e590392d9b71652572abdfba038c40241920..ab1faecae91a74bc8a55cd64d05f2809e16f596f 100644 (file)
@@ -1135,3 +1135,4 @@ ru:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 2d210d36d5f5cfd67a5dfa38578f5c5977febe05..d8c71c6abd6868585334735ff411194ee7f4a157 100644 (file)
@@ -1022,3 +1022,4 @@ sk:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index e8476609466ba99e0e3f076b57ec01c258a37687..0016aceb158a2df50e2e1c22e1614f442463d0ba 100644 (file)
@@ -1022,3 +1022,4 @@ sl:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 6059c5ccfb306de1d718a236edf95e74992683ed..a98aaedb3613bb83723bb89fbbdb75e923b6ebff 100644 (file)
@@ -1022,3 +1022,4 @@ sr-YU:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 6baabf1ac895bd318e72d3494c17e8766a887e52..7c5b0f24984ce91ec77dc5239553fe2cd7248ace 100644 (file)
@@ -1023,3 +1023,4 @@ sr:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 7f38a2e9f124cd80e605f5745983895a3a9e20f4..e4a9dd893c18dc7b54acfe40f8a6b8a1bee22d06 100644 (file)
@@ -1063,3 +1063,4 @@ sv:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 81137e8f1b895dec8e12cbf60d864a3fab6d175c..26e468c118a39e350c1b03972816a7f3d1b99542 100644 (file)
@@ -1019,3 +1019,4 @@ th:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index e9b1b2fb20d8d7e5b4108a2c2ab1dec84167a630..d73663adfc9e8a9d4494721a8cef8ba20aa79f6b 100644 (file)
@@ -1041,3 +1041,4 @@ tr:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 1e7616cc12a3b118c5568469ff16f6696ee8b139..86d1d9e0cba6b2fd7b24d5dc314d2e722fde6743 100644 (file)
@@ -1019,3 +1019,4 @@ uk:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index ce72ef3f1ea3f2a84828b6ef6e215c2028f190ce..0d2068be9051a4c2d3a7887c1d14f96e3b24b91a 100644 (file)
@@ -1073,3 +1073,4 @@ vi:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 4d23b83b7b03bb404685f4574686d9cf6fdd12c3..196dd2d828424c35887f73c217fff5efa308d2d4 100644 (file)
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index 4fffcee9cb84c559ce1a908cce5079d1a4b88b8d..9da84db9e3c4e1405a1b14067bc8eb848b58ad07 100644 (file)
@@ -1024,3 +1024,4 @@ zh:
   text_issue_conflict_resolution_overwrite: Apply my changes anyway (previous notes will be kept but some changes may be overwritten)
   notice_issue_update_conflict: The issue has been updated by an other user while you were editing it.
   text_issue_conflict_resolution_cancel: Discard all my changes and redisplay %{link}
+  permission_manage_related_issues: Manage related issues
index d5794c91363d1f316a6df46f63b7473ee2893de7..15953076ff653f6e9afaec06752ec6bb0f10721d 100644 (file)
@@ -250,6 +250,10 @@ ActionController::Routing::Routes.draw do |map|
                                :action => 'revisions'
       repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev',
                                :action => 'revision'
+      repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev/issues',
+                                :action => 'add_related_issue', :conditions => {:method => :post}
+      repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev/issues/:issue_id',
+                                :action => 'remove_related_issue', :conditions => {:method => :delete}
       repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev/diff',
                                :action => 'diff'
       repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev/diff.:format',
@@ -272,6 +276,10 @@ ActionController::Routing::Routes.draw do |map|
                                :action => 'revisions'
       repository_views.connect 'projects/:id/repository/revisions/:rev',
                                :action => 'revision'
+      repository_views.connect 'projects/:id/repository/revisions/:rev/issues',
+                                :action => 'add_related_issue', :conditions => {:method => :post}
+      repository_views.connect 'projects/:id/repository/revisions/:rev/issues/:issue_id',
+                                :action => 'remove_related_issue', :conditions => {:method => :delete}
       repository_views.connect 'projects/:id/repository/revisions/:rev/diff',
                                :action => 'diff'
       repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format',
index b43a53b71011fa5aa9037d34d344c8420593bb03..6cb88a9bc568fa8fcfbe6a2d7744d718eac08eaa 100644 (file)
@@ -128,6 +128,7 @@ Redmine::AccessControl.map do |map|
     map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]
     map.permission :view_changesets, :repositories => [:show, :revisions, :revision]
     map.permission :commit_access, {}
+    map.permission :manage_related_issues, {:repositories => [:add_related_issue, :remove_related_issue]}
   end
 
   map.project_module :boards do |map|
index 5ebe69efa78f5b0f2b34554272491ed510907ca8..88029ba5484ba23744c4a3a772af44127ce70e34 100644 (file)
@@ -73,7 +73,8 @@ module Redmine
                                                       :manage_files,
                                                       :browse_repository,
                                                       :view_changesets,
-                                                      :commit_access]
+                                                      :commit_access,
+                                                      :manage_related_issues]
 
             reporter = Role.create! :name => l(:default_role_reporter),
                                     :position => 3,
index d0043fa11d7902dd941714e17af1a91b22b3460d..29102fcb6919a5d681e73f4d4daa24d1dc88374c 100644 (file)
@@ -399,6 +399,8 @@ ul.projects div.root a.project { font-family: "Trebuchet MS", Verdana, sans-seri
 #tracker_project_ids ul { margin: 0;  padding-left: 1em; }
 #tracker_project_ids li { list-style-type:none; }
 
+#related-issues li img {vertical-align:middle;}
+
 ul.properties {padding:0; font-size: 0.9em; color: #777;}
 ul.properties li {list-style-type:none;}
 ul.properties li span {font-style:italic;}
index 0549ebe6c2c001006fa6ee1794ef1762ba28a93a..0eaaafe7230c64aac11f6a75389e4e470bf21092 100644 (file)
@@ -53,6 +53,7 @@ roles_001:
     - :browse_repository
     - :manage_repository
     - :view_changesets
+    - :manage_related_issues
     - :manage_project_activities
 
   position: 1
index 6bcbb6bebe76628f94c437a8772c2c9ebe804853..844e8fa87597150adfedc01d7a0231712c4ce329 100644 (file)
@@ -160,6 +160,38 @@ class RepositoriesControllerTest < ActionController::TestCase
     }
   end
 
+  def test_add_related_issue
+    @request.session[:user_id] = 2
+    assert_difference 'Changeset.find(103).issues.size' do
+      post :add_related_issue, :id => 1, :rev => 4, :issue_id => 2
+      assert_response :success
+    end
+    assert_select_rjs :replace_html, 'related-issues'
+    assert_equal [2], Changeset.find(103).issue_ids
+  end
+
+  def test_add_related_issue_with_invalid_issue_id
+    @request.session[:user_id] = 2
+    assert_no_difference 'Changeset.find(103).issues.size' do
+      post :add_related_issue, :id => 1, :rev => 4, :issue_id => 9999
+      assert_response :success
+    end
+    assert_include 'alert("Issue is invalid")', @response.body
+  end
+
+  def test_remove_related_issue
+    Changeset.find(103).issues << Issue.find(1)
+    Changeset.find(103).issues << Issue.find(2)
+
+    @request.session[:user_id] = 2
+    assert_difference 'Changeset.find(103).issues.size', -1 do
+      delete :remove_related_issue, :id => 1, :rev => 4, :issue_id => 2
+      assert_response :success
+    end
+    assert_select_rjs :remove, 'related-issue-2'
+    assert_equal [1], Changeset.find(103).issue_ids
+  end
+
   def test_graph_commits_per_month
     get :graph, :id => 1, :graph => 'commits_per_month'
     assert_response :success
index 5b2ccbcac240fae4d590880dc5297fb83cb5620b..44fe7309e563575eca21fcb3c66135cfd19c3973 100644 (file)
@@ -341,6 +341,32 @@ class RoutingRepositoriesTest < ActionController::IntegrationTest
       )
   end
 
+  def test_repositories_related_issues
+    assert_routing(
+        { :method => 'post',
+          :path => "/projects/redmine/repository/revisions/123/issues" },
+        { :controller => 'repositories', :action => 'add_related_issue', :id => 'redmine', :rev => '123' }
+      )
+    assert_routing(
+        { :method => 'delete',
+          :path => "/projects/redmine/repository/revisions/123/issues/25" },
+        { :controller => 'repositories', :action => 'remove_related_issue', :id => 'redmine', :rev => '123', :issue_id => '25' }
+      )
+  end
+
+  def test_repositories_related_issues_with_repository_id
+    assert_routing(
+        { :method => 'post',
+          :path => "/projects/redmine/repository/foo/revisions/123/issues" },
+        { :controller => 'repositories', :action => 'add_related_issue', :id => 'redmine', :repository_id => 'foo', :rev => '123' }
+      )
+    assert_routing(
+        { :method => 'delete',
+          :path => "/projects/redmine/repository/foo/revisions/123/issues/25" },
+        { :controller => 'repositories', :action => 'remove_related_issue', :id => 'redmine', :repository_id => 'foo', :rev => '123', :issue_id => '25' }
+      )
+  end
+
   private
 
   def repository_path_hash(arr)