##// END OF EJS Templates
Merged r4006 from trunk....
Eric Davis -
r3904:27ef72c35eb9
parent child
Show More
@@ -0,0 +1,33
1 class ContextMenusController < ApplicationController
2 helper :watchers
3
4 def issues
5 @issues = Issue.find_all_by_id(params[:ids], :include => :project)
6 if (@issues.size == 1)
7 @issue = @issues.first
8 @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
9 end
10 projects = @issues.collect(&:project).compact.uniq
11 @project = projects.first if projects.size == 1
12
13 @can = {:edit => (@project && User.current.allowed_to?(:edit_issues, @project)),
14 :log_time => (@project && User.current.allowed_to?(:log_time, @project)),
15 :update => (@project && (User.current.allowed_to?(:edit_issues, @project) || (User.current.allowed_to?(:change_status, @project) && @allowed_statuses && !@allowed_statuses.empty?))),
16 :move => (@project && User.current.allowed_to?(:move_issues, @project)),
17 :copy => (@issue && @project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)),
18 :delete => (@project && User.current.allowed_to?(:delete_issues, @project))
19 }
20 if @project
21 @assignables = @project.assignable_users
22 @assignables << @issue.assigned_to if @issue && @issue.assigned_to && !@assignables.include?(@issue.assigned_to)
23 @trackers = @project.trackers
24 end
25
26 @priorities = IssuePriority.all.reverse
27 @statuses = IssueStatus.find(:all, :order => 'position')
28 @back = back_url
29
30 render :layout => false
31 end
32
33 end
@@ -0,0 +1,89
1 require File.dirname(__FILE__) + '/../test_helper'
2
3 class ContextMenusControllerTest < ActionController::TestCase
4 fixtures :all
5
6 def test_context_menu_one_issue
7 @request.session[:user_id] = 2
8 get :issues, :ids => [1]
9 assert_response :success
10 assert_template 'context_menu'
11 assert_tag :tag => 'a', :content => 'Edit',
12 :attributes => { :href => '/issues/1/edit',
13 :class => 'icon-edit' }
14 assert_tag :tag => 'a', :content => 'Closed',
15 :attributes => { :href => '/issues/1/edit?issue%5Bstatus_id%5D=5',
16 :class => '' }
17 assert_tag :tag => 'a', :content => 'Immediate',
18 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bpriority_id%5D=8',
19 :class => '' }
20 # Versions
21 assert_tag :tag => 'a', :content => '2.0',
22 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=3',
23 :class => '' }
24 assert_tag :tag => 'a', :content => 'eCookbook Subproject 1 - 2.0',
25 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=4',
26 :class => '' }
27
28 assert_tag :tag => 'a', :content => 'Dave Lopper',
29 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=3',
30 :class => '' }
31 assert_tag :tag => 'a', :content => 'Duplicate',
32 :attributes => { :href => '/projects/ecookbook/issues/1/copy',
33 :class => 'icon-duplicate' }
34 assert_tag :tag => 'a', :content => 'Copy',
35 :attributes => { :href => '/issues/move/new?copy_options%5Bcopy%5D=t&amp;ids%5B%5D=1',
36 :class => 'icon-copy' }
37 assert_tag :tag => 'a', :content => 'Move',
38 :attributes => { :href => '/issues/move/new?ids%5B%5D=1',
39 :class => 'icon-move' }
40 assert_tag :tag => 'a', :content => 'Delete',
41 :attributes => { :href => '/issues/destroy?ids%5B%5D=1',
42 :class => 'icon-del' }
43 end
44
45 def test_context_menu_one_issue_by_anonymous
46 get :issues, :ids => [1]
47 assert_response :success
48 assert_template 'context_menu'
49 assert_tag :tag => 'a', :content => 'Delete',
50 :attributes => { :href => '#',
51 :class => 'icon-del disabled' }
52 end
53
54 def test_context_menu_multiple_issues_of_same_project
55 @request.session[:user_id] = 2
56 get :issues, :ids => [1, 2]
57 assert_response :success
58 assert_template 'context_menu'
59 assert_tag :tag => 'a', :content => 'Edit',
60 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2',
61 :class => 'icon-edit' }
62 assert_tag :tag => 'a', :content => 'Immediate',
63 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bpriority_id%5D=8',
64 :class => '' }
65 assert_tag :tag => 'a', :content => 'Dave Lopper',
66 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bassigned_to_id%5D=3',
67 :class => '' }
68 assert_tag :tag => 'a', :content => 'Copy',
69 :attributes => { :href => '/issues/move/new?copy_options%5Bcopy%5D=t&amp;ids%5B%5D=1&amp;ids%5B%5D=2',
70 :class => 'icon-copy' }
71 assert_tag :tag => 'a', :content => 'Move',
72 :attributes => { :href => '/issues/move/new?ids%5B%5D=1&amp;ids%5B%5D=2',
73 :class => 'icon-move' }
74 assert_tag :tag => 'a', :content => 'Delete',
75 :attributes => { :href => '/issues/destroy?ids%5B%5D=1&amp;ids%5B%5D=2',
76 :class => 'icon-del' }
77 end
78
79 def test_context_menu_multiple_issues_of_different_project
80 @request.session[:user_id] = 2
81 get :issues, :ids => [1, 2, 4]
82 assert_response :success
83 assert_template 'context_menu'
84 assert_tag :tag => 'a', :content => 'Delete',
85 :attributes => { :href => '#',
86 :class => 'icon-del disabled' }
87 end
88
89 end
@@ -22,7 +22,7 class IssuesController < ApplicationController
22 before_filter :find_issue, :only => [:show, :edit, :update]
22 before_filter :find_issue, :only => [:show, :edit, :update]
23 before_filter :find_issues, :only => [:bulk_edit, :move, :perform_move, :destroy]
23 before_filter :find_issues, :only => [:bulk_edit, :move, :perform_move, :destroy]
24 before_filter :find_project, :only => [:new, :create, :update_form]
24 before_filter :find_project, :only => [:new, :create, :update_form]
25 before_filter :authorize, :except => [:index, :changes, :context_menu]
25 before_filter :authorize, :except => [:index, :changes]
26 before_filter :find_optional_project, :only => [:index, :changes]
26 before_filter :find_optional_project, :only => [:index, :changes]
27 before_filter :check_for_default_issue_status, :only => [:new, :create]
27 before_filter :check_for_default_issue_status, :only => [:new, :create]
28 before_filter :build_new_issue_from_params, :only => [:new, :create]
28 before_filter :build_new_issue_from_params, :only => [:new, :create]
@@ -257,35 +257,6 class IssuesController < ApplicationController
257 format.json { head :ok }
257 format.json { head :ok }
258 end
258 end
259 end
259 end
260
261 def context_menu
262 @issues = Issue.find_all_by_id(params[:ids], :include => :project)
263 if (@issues.size == 1)
264 @issue = @issues.first
265 @allowed_statuses = @issue.new_statuses_allowed_to(User.current)
266 end
267 projects = @issues.collect(&:project).compact.uniq
268 @project = projects.first if projects.size == 1
269
270 @can = {:edit => (@project && User.current.allowed_to?(:edit_issues, @project)),
271 :log_time => (@project && User.current.allowed_to?(:log_time, @project)),
272 :update => (@project && (User.current.allowed_to?(:edit_issues, @project) || (User.current.allowed_to?(:change_status, @project) && @allowed_statuses && !@allowed_statuses.empty?))),
273 :move => (@project && User.current.allowed_to?(:move_issues, @project)),
274 :copy => (@issue && @project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)),
275 :delete => (@project && User.current.allowed_to?(:delete_issues, @project))
276 }
277 if @project
278 @assignables = @project.assignable_users
279 @assignables << @issue.assigned_to if @issue && @issue.assigned_to && !@assignables.include?(@issue.assigned_to)
280 @trackers = @project.trackers
281 end
282
283 @priorities = IssuePriority.all.reverse
284 @statuses = IssueStatus.find(:all, :order => 'position')
285 @back = back_url
286
287 render :layout => false
288 end
289
260
290 def update_form
261 def update_form
291 if params[:id].blank?
262 if params[:id].blank?
1 NO CONTENT: file renamed from app/views/issues/context_menu.rhtml to app/views/context_menus/issues.html.erb
NO CONTENT: file renamed from app/views/issues/context_menu.rhtml to app/views/context_menus/issues.html.erb
@@ -81,4 +81,4
81 <%= auto_discovery_link_tag(:atom, {:action => 'changes', :query_id => @query, :format => 'atom', :page => nil, :key => User.current.rss_key}, :title => l(:label_changes_details)) %>
81 <%= auto_discovery_link_tag(:atom, {:action => 'changes', :query_id => @query, :format => 'atom', :page => nil, :key => User.current.rss_key}, :title => l(:label_changes_details)) %>
82 <% end %>
82 <% end %>
83
83
84 <%= context_menu :controller => 'issues', :action => 'context_menu' %>
84 <%= context_menu issues_context_menu_path %>
@@ -130,4 +130,4
130 <%= stylesheet_link_tag 'context_menu' %>
130 <%= stylesheet_link_tag 'context_menu' %>
131 <% end %>
131 <% end %>
132 <div id="context-menu" style="display: none;"></div>
132 <div id="context-menu" style="display: none;"></div>
133 <%= javascript_tag "new ContextMenu('#{url_for(:controller => 'issues', :action => 'context_menu')}')" %>
133 <%= javascript_tag "new ContextMenu('#{issues_context_menu_path}')" %>
@@ -107,6 +107,7 ActionController::Routing::Routes.draw do |map|
107 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues'
107 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues'
108 # TODO: would look nicer as /issues/:id/preview
108 # TODO: would look nicer as /issues/:id/preview
109 map.preview_issue '/issues/preview/:id', :controller => 'previews', :action => 'issue'
109 map.preview_issue '/issues/preview/:id', :controller => 'previews', :action => 'issue'
110 map.issues_context_menu '/issues/context_menu', :controller => 'context_menus', :action => 'issues'
110
111
111 map.with_options :controller => 'issues' do |issues_routes|
112 map.with_options :controller => 'issues' do |issues_routes|
112 issues_routes.with_options :conditions => {:method => :get} do |issues_views|
113 issues_routes.with_options :conditions => {:method => :get} do |issues_views|
@@ -58,8 +58,9 Redmine::AccessControl.map do |map|
58 map.permission :manage_categories, {:projects => :settings, :issue_categories => [:new, :edit, :destroy]}, :require => :member
58 map.permission :manage_categories, {:projects => :settings, :issue_categories => [:new, :edit, :destroy]}, :require => :member
59 # Issues
59 # Issues
60 map.permission :view_issues, {:projects => :roadmap,
60 map.permission :view_issues, {:projects => :roadmap,
61 :issues => [:index, :changes, :show, :context_menu],
61 :issues => [:index, :changes, :show],
62 :auto_complete => [:issues],
62 :auto_complete => [:issues],
63 :context_menus => [:issues],
63 :versions => [:show, :status_by],
64 :versions => [:show, :status_by],
64 :queries => :index,
65 :queries => :index,
65 :reports => [:issue_report, :issue_report_details]}
66 :reports => [:issue_report, :issue_report_details]}
@@ -1024,89 +1024,6 class IssuesControllerTest < ActionController::TestCase
1024 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
1024 assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier
1025 end
1025 end
1026
1026
1027 def test_context_menu_one_issue
1028 @request.session[:user_id] = 2
1029 get :context_menu, :ids => [1]
1030 assert_response :success
1031 assert_template 'context_menu'
1032 assert_tag :tag => 'a', :content => 'Edit',
1033 :attributes => { :href => '/issues/1/edit',
1034 :class => 'icon-edit' }
1035 assert_tag :tag => 'a', :content => 'Closed',
1036 :attributes => { :href => '/issues/1/edit?issue%5Bstatus_id%5D=5',
1037 :class => '' }
1038 assert_tag :tag => 'a', :content => 'Immediate',
1039 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bpriority_id%5D=8',
1040 :class => '' }
1041 # Versions
1042 assert_tag :tag => 'a', :content => '2.0',
1043 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=3',
1044 :class => '' }
1045 assert_tag :tag => 'a', :content => 'eCookbook Subproject 1 - 2.0',
1046 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bfixed_version_id%5D=4',
1047 :class => '' }
1048
1049 assert_tag :tag => 'a', :content => 'Dave Lopper',
1050 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;issue%5Bassigned_to_id%5D=3',
1051 :class => '' }
1052 assert_tag :tag => 'a', :content => 'Duplicate',
1053 :attributes => { :href => '/projects/ecookbook/issues/1/copy',
1054 :class => 'icon-duplicate' }
1055 assert_tag :tag => 'a', :content => 'Copy',
1056 :attributes => { :href => '/issues/move/new?copy_options%5Bcopy%5D=t&amp;ids%5B%5D=1',
1057 :class => 'icon-copy' }
1058 assert_tag :tag => 'a', :content => 'Move',
1059 :attributes => { :href => '/issues/move/new?ids%5B%5D=1',
1060 :class => 'icon-move' }
1061 assert_tag :tag => 'a', :content => 'Delete',
1062 :attributes => { :href => '/issues/destroy?ids%5B%5D=1',
1063 :class => 'icon-del' }
1064 end
1065
1066 def test_context_menu_one_issue_by_anonymous
1067 get :context_menu, :ids => [1]
1068 assert_response :success
1069 assert_template 'context_menu'
1070 assert_tag :tag => 'a', :content => 'Delete',
1071 :attributes => { :href => '#',
1072 :class => 'icon-del disabled' }
1073 end
1074
1075 def test_context_menu_multiple_issues_of_same_project
1076 @request.session[:user_id] = 2
1077 get :context_menu, :ids => [1, 2]
1078 assert_response :success
1079 assert_template 'context_menu'
1080 assert_tag :tag => 'a', :content => 'Edit',
1081 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2',
1082 :class => 'icon-edit' }
1083 assert_tag :tag => 'a', :content => 'Immediate',
1084 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bpriority_id%5D=8',
1085 :class => '' }
1086 assert_tag :tag => 'a', :content => 'Dave Lopper',
1087 :attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&amp;ids%5B%5D=2&amp;issue%5Bassigned_to_id%5D=3',
1088 :class => '' }
1089 assert_tag :tag => 'a', :content => 'Copy',
1090 :attributes => { :href => '/issues/move/new?copy_options%5Bcopy%5D=t&amp;ids%5B%5D=1&amp;ids%5B%5D=2',
1091 :class => 'icon-copy' }
1092 assert_tag :tag => 'a', :content => 'Move',
1093 :attributes => { :href => '/issues/move/new?ids%5B%5D=1&amp;ids%5B%5D=2',
1094 :class => 'icon-move' }
1095 assert_tag :tag => 'a', :content => 'Delete',
1096 :attributes => { :href => '/issues/destroy?ids%5B%5D=1&amp;ids%5B%5D=2',
1097 :class => 'icon-del' }
1098 end
1099
1100 def test_context_menu_multiple_issues_of_different_project
1101 @request.session[:user_id] = 2
1102 get :context_menu, :ids => [1, 2, 4]
1103 assert_response :success
1104 assert_template 'context_menu'
1105 assert_tag :tag => 'a', :content => 'Delete',
1106 :attributes => { :href => '#',
1107 :class => 'icon-del disabled' }
1108 end
1109
1110 def test_destroy_issue_with_no_time_entries
1027 def test_destroy_issue_with_no_time_entries
1111 assert_nil TimeEntry.find_by_issue_id(2)
1028 assert_nil TimeEntry.find_by_issue_id(2)
1112 @request.session[:user_id] = 2
1029 @request.session[:user_id] = 2
@@ -104,6 +104,8 class RoutingTest < ActionController::IntegrationTest
104
104
105 should_route :get, "/issues/preview/123", :controller => 'previews', :action => 'issue', :id => '123'
105 should_route :get, "/issues/preview/123", :controller => 'previews', :action => 'issue', :id => '123'
106 should_route :post, "/issues/preview/123", :controller => 'previews', :action => 'issue', :id => '123'
106 should_route :post, "/issues/preview/123", :controller => 'previews', :action => 'issue', :id => '123'
107 should_route :get, "/issues/context_menu", :controller => 'context_menus', :action => 'issues'
108 should_route :post, "/issues/context_menu", :controller => 'context_menus', :action => 'issues'
107 end
109 end
108
110
109 context "issue categories" do
111 context "issue categories" do
General Comments 0
You need to be logged in to leave comments. Login now