@@ -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&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&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&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&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&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&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&ids%5B%5D=2&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&ids%5B%5D=2&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&ids%5B%5D=1&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&ids%5B%5D=2', | |
|
73 | :class => 'icon-move' } | |
|
74 | assert_tag :tag => 'a', :content => 'Delete', | |
|
75 | :attributes => { :href => '/issues/destroy?ids%5B%5D=1&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 | 22 | before_filter :find_issue, :only => [:show, :edit, :update] |
|
23 | 23 | before_filter :find_issues, :only => [:bulk_edit, :move, :perform_move, :destroy] |
|
24 | 24 | before_filter :find_project, :only => [:new, :create, :update_form] |
|
25 |
before_filter :authorize, :except => [:index, :changes |
|
|
25 | before_filter :authorize, :except => [:index, :changes] | |
|
26 | 26 | before_filter :find_optional_project, :only => [:index, :changes] |
|
27 | 27 | before_filter :check_for_default_issue_status, :only => [:new, :create] |
|
28 | 28 | before_filter :build_new_issue_from_params, :only => [:new, :create] |
@@ -258,35 +258,6 class IssuesController < ApplicationController | |||
|
258 | 258 | end |
|
259 | 259 | end |
|
260 | 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 | ||
|
290 | 261 | def update_form |
|
291 | 262 | if params[:id].blank? |
|
292 | 263 | @issue = Issue.new |
|
1 | NO CONTENT: file renamed from app/views/issues/context_menu.rhtml to app/views/context_menus/issues.html.erb |
@@ -81,4 +81,4 | |||
|
81 | 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 | 82 | <% end %> |
|
83 | 83 | |
|
84 |
<%= context_menu |
|
|
84 | <%= context_menu issues_context_menu_path %> |
@@ -130,4 +130,4 | |||
|
130 | 130 | <%= stylesheet_link_tag 'context_menu' %> |
|
131 | 131 | <% end %> |
|
132 | 132 | <div id="context-menu" style="display: none;"></div> |
|
133 |
<%= javascript_tag "new ContextMenu('#{ |
|
|
133 | <%= javascript_tag "new ContextMenu('#{issues_context_menu_path}')" %> |
@@ -107,6 +107,7 ActionController::Routing::Routes.draw do |map| | |||
|
107 | 107 | map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues' |
|
108 | 108 | # TODO: would look nicer as /issues/:id/preview |
|
109 | 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 | 112 | map.with_options :controller => 'issues' do |issues_routes| |
|
112 | 113 | issues_routes.with_options :conditions => {:method => :get} do |issues_views| |
@@ -58,8 +58,9 Redmine::AccessControl.map do |map| | |||
|
58 | 58 | map.permission :manage_categories, {:projects => :settings, :issue_categories => [:new, :edit, :destroy]}, :require => :member |
|
59 | 59 | # Issues |
|
60 | 60 | map.permission :view_issues, {:projects => :roadmap, |
|
61 |
:issues => [:index, :changes, :show |
|
|
61 | :issues => [:index, :changes, :show], | |
|
62 | 62 | :auto_complete => [:issues], |
|
63 | :context_menus => [:issues], | |
|
63 | 64 | :versions => [:show, :status_by], |
|
64 | 65 | :queries => :index, |
|
65 | 66 | :reports => [:issue_report, :issue_report_details]} |
@@ -1024,89 +1024,6 class IssuesControllerTest < ActionController::TestCase | |||
|
1024 | 1024 | assert_redirected_to :controller => 'issues', :action => 'index', :project_id => Project.find(1).identifier |
|
1025 | 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&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&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&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&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&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&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&ids%5B%5D=2&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&ids%5B%5D=2&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&ids%5B%5D=1&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&ids%5B%5D=2', | |
|
1094 | :class => 'icon-move' } | |
|
1095 | assert_tag :tag => 'a', :content => 'Delete', | |
|
1096 | :attributes => { :href => '/issues/destroy?ids%5B%5D=1&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 | 1027 | def test_destroy_issue_with_no_time_entries |
|
1111 | 1028 | assert_nil TimeEntry.find_by_issue_id(2) |
|
1112 | 1029 | @request.session[:user_id] = 2 |
@@ -104,6 +104,8 class RoutingTest < ActionController::IntegrationTest | |||
|
104 | 104 | |
|
105 | 105 | should_route :get, "/issues/preview/123", :controller => 'previews', :action => 'issue', :id => '123' |
|
106 | 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 | 109 | end |
|
108 | 110 | |
|
109 | 111 | context "issue categories" do |
General Comments 0
You need to be logged in to leave comments.
Login now