##// END OF EJS Templates
Resourcified project memberships....
Jean-Philippe Lang -
r8669:78bd24c6f738
parent child
Show More
@@ -0,0 +1,1
1 <%= principals_check_box_tags 'membership[user_ids][]', @principals %>
@@ -1,100 +1,103
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class MembersController < ApplicationController
18 class MembersController < ApplicationController
19 model_object Member
19 model_object Member
20 before_filter :find_model_object, :except => [:new, :autocomplete_for_member]
20 before_filter :find_model_object, :except => [:create, :autocomplete]
21 before_filter :find_project_from_association, :except => [:new, :autocomplete_for_member]
21 before_filter :find_project_from_association, :except => [:create, :autocomplete]
22 before_filter :find_project, :only => [:new, :autocomplete_for_member]
22 before_filter :find_project_by_project_id, :only => [:create, :autocomplete]
23 before_filter :authorize
23 before_filter :authorize
24
24
25 def new
25 def create
26 members = []
26 members = []
27 if params[:member] && request.post?
27 if params[:membership] && request.post?
28 attrs = params[:member].dup
28 attrs = params[:membership].dup
29 if (user_ids = attrs.delete(:user_ids))
29 if (user_ids = attrs.delete(:user_ids))
30 user_ids.each do |user_id|
30 user_ids.each do |user_id|
31 members << Member.new(attrs.merge(:user_id => user_id))
31 members << Member.new(attrs.merge(:user_id => user_id))
32 end
32 end
33 else
33 else
34 members << Member.new(attrs)
34 members << Member.new(attrs)
35 end
35 end
36 @project.members << members
36 @project.members << members
37 end
37 end
38 respond_to do |format|
38 respond_to do |format|
39 if members.present? && members.all? {|m| m.valid? }
39 if members.present? && members.all? {|m| m.valid? }
40
40
41 format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
41 format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
42
42
43 format.js {
43 format.js {
44 render(:update) {|page|
44 render(:update) {|page|
45 page.replace_html "tab-content-members", :partial => 'projects/settings/members'
45 page.replace_html "tab-content-members", :partial => 'projects/settings/members'
46 page << 'hideOnLoad()'
46 page << 'hideOnLoad()'
47 members.each {|member| page.visual_effect(:highlight, "member-#{member.id}") }
47 members.each {|member| page.visual_effect(:highlight, "member-#{member.id}") }
48 }
48 }
49 }
49 }
50 else
50 else
51
51
52 format.js {
52 format.js {
53 render(:update) {|page|
53 render(:update) {|page|
54 errors = members.collect {|m|
54 errors = members.collect {|m|
55 m.errors.full_messages
55 m.errors.full_messages
56 }.flatten.uniq
56 }.flatten.uniq
57
57
58 page.alert(l(:notice_failed_to_save_members, :errors => errors.join(', ')))
58 page.alert(l(:notice_failed_to_save_members, :errors => errors.join(', ')))
59 }
59 }
60 }
60 }
61
61
62 end
62 end
63 end
63 end
64 end
64 end
65
65
66 def edit
66 def update
67 if request.post? and @member.update_attributes(params[:member])
67 if params[:membership]
68 @member.role_ids = params[:membership][:role_ids]
69 end
70 if request.put? && @member.save
68 respond_to do |format|
71 respond_to do |format|
69 format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
72 format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
70 format.js {
73 format.js {
71 render(:update) {|page|
74 render(:update) {|page|
72 page.replace_html "tab-content-members", :partial => 'projects/settings/members'
75 page.replace_html "tab-content-members", :partial => 'projects/settings/members'
73 page << 'hideOnLoad()'
76 page << 'hideOnLoad()'
74 page.visual_effect(:highlight, "member-#{@member.id}")
77 page.visual_effect(:highlight, "member-#{@member.id}")
75 }
78 }
76 }
79 }
77 end
80 end
78 end
81 end
79 end
82 end
80
83
81 def destroy
84 def destroy
82 if request.post? && @member.deletable?
85 if request.delete? && @member.deletable?
83 @member.destroy
86 @member.destroy
84 end
87 end
85 respond_to do |format|
88 respond_to do |format|
86 format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
89 format.html { redirect_to :controller => 'projects', :action => 'settings', :tab => 'members', :id => @project }
87 format.js { render(:update) {|page|
90 format.js { render(:update) {|page|
88 page.replace_html "tab-content-members", :partial => 'projects/settings/members'
91 page.replace_html "tab-content-members", :partial => 'projects/settings/members'
89 page << 'hideOnLoad()'
92 page << 'hideOnLoad()'
90 }
93 }
91 }
94 }
92 end
95 end
93 end
96 end
94
97
95 def autocomplete_for_member
98 def autocomplete
96 @principals = Principal.active.like(params[:q]).find(:all, :limit => 100) - @project.principals
99 @principals = Principal.active.like(params[:q]).find(:all, :limit => 100) - @project.principals
97 render :layout => false
100 render :layout => false
98 end
101 end
99
102
100 end
103 end
@@ -1,90 +1,89
1 <%= error_messages_for 'member' %>
1 <%= error_messages_for 'member' %>
2 <% roles = Role.find_all_givable
2 <% roles = Role.find_all_givable
3 members = @project.member_principals.find(:all, :include => [:roles, :principal]).sort %>
3 members = @project.member_principals.find(:all, :include => [:roles, :principal]).sort %>
4
4
5 <div class="splitcontentleft">
5 <div class="splitcontentleft">
6 <% if members.any? %>
6 <% if members.any? %>
7 <table class="list members">
7 <table class="list members">
8 <thead><tr>
8 <thead><tr>
9 <th><%= l(:label_user) %> / <%= l(:label_group) %></th>
9 <th><%= l(:label_user) %> / <%= l(:label_group) %></th>
10 <th><%= l(:label_role_plural) %></th>
10 <th><%= l(:label_role_plural) %></th>
11 <th style="width:15%"></th>
11 <th style="width:15%"></th>
12 <%= call_hook(:view_projects_settings_members_table_header, :project => @project) %>
12 <%= call_hook(:view_projects_settings_members_table_header, :project => @project) %>
13 </tr></thead>
13 </tr></thead>
14 <tbody>
14 <tbody>
15 <% members.each do |member| %>
15 <% members.each do |member| %>
16 <% next if member.new_record? %>
16 <% next if member.new_record? %>
17 <tr id="member-<%= member.id %>" class="<%= cycle 'odd', 'even' %> member">
17 <tr id="member-<%= member.id %>" class="<%= cycle 'odd', 'even' %> member">
18 <td class="<%= member.principal.class.name.downcase %>"><%= link_to_user member.principal %></td>
18 <td class="<%= member.principal.class.name.downcase %>"><%= link_to_user member.principal %></td>
19 <td class="roles">
19 <td class="roles">
20 <span id="member-<%= member.id %>-roles"><%=h member.roles.sort.collect(&:to_s).join(', ') %></span>
20 <span id="member-<%= member.id %>-roles"><%=h member.roles.sort.collect(&:to_s).join(', ') %></span>
21 <% if authorize_for('members', 'edit') %>
21 <% remote_form_for(:membership, member, :url => membership_path(member),
22 <% remote_form_for(:member, member, :url => {:controller => 'members', :action => 'edit', :id => member},
22 :method => :put,
23 :method => :post,
24 :html => { :id => "member-#{member.id}-roles-form", :class => 'hol' }) do |f| %>
23 :html => { :id => "member-#{member.id}-roles-form", :class => 'hol' }) do |f| %>
25 <p><% roles.each do |role| %>
24 <p><% roles.each do |role| %>
26 <label><%= check_box_tag 'member[role_ids][]', role.id, member.roles.include?(role),
25 <label><%= check_box_tag 'membership[role_ids][]', role.id, member.roles.include?(role),
27 :disabled => member.member_roles.detect {|mr| mr.role_id == role.id && !mr.inherited_from.nil?} %> <%=h role %></label><br />
26 :disabled => member.member_roles.detect {|mr| mr.role_id == role.id && !mr.inherited_from.nil?} %> <%=h role %></label><br />
28 <% end %></p>
27 <% end %></p>
29 <%= hidden_field_tag 'member[role_ids][]', '' %>
28 <%= hidden_field_tag 'membership[role_ids][]', '' %>
30 <p><%= submit_tag l(:button_change), :class => "small" %>
29 <p><%= submit_tag l(:button_change), :class => "small" %>
31 <%= link_to_function l(:button_cancel),
30 <%= link_to_function l(:button_cancel),
32 "$('member-#{member.id}-roles').show(); $('member-#{member.id}-roles-form').hide(); return false;"
31 "$('member-#{member.id}-roles').show(); $('member-#{member.id}-roles-form').hide(); return false;"
33 %></p>
32 %></p>
34 <% end %>
33 <% end %>
35 <% end %>
36 </td>
34 </td>
37 <td class="buttons">
35 <td class="buttons">
38 <%= link_to_function l(:button_edit),
36 <%= link_to_function l(:button_edit),
39 "$('member-#{member.id}-roles').hide(); $('member-#{member.id}-roles-form').show(); return false;",
37 "$('member-#{member.id}-roles').hide(); $('member-#{member.id}-roles-form').show(); return false;",
40 :class => 'icon icon-edit' %>
38 :class => 'icon icon-edit' %>
41 <%= link_to_remote(
39 <%= link_to_remote(
42 l(:button_delete),
40 l(:button_delete),
43 { :url => {:controller => 'members', :action => 'destroy', :id => member},
41 { :url => membership_path(member),
44 :method => :post,
42 :method => :delete,
45 :confirm => (!User.current.admin? && member.include?(User.current) ? l(:text_own_membership_delete_confirmation) : nil) },
43 :confirm => (!User.current.admin? && member.include?(User.current) ? l(:text_own_membership_delete_confirmation) : nil) },
46 :title => l(:button_delete),
44 :title => l(:button_delete),
47 :class => 'icon icon-del'
45 :class => 'icon icon-del'
48 ) if member.deletable? %>
46 ) if member.deletable? %>
49 </td>
47 </td>
50 <%= call_hook(:view_projects_settings_members_table_row, { :project => @project, :member => member}) %>
48 <%= call_hook(:view_projects_settings_members_table_row, { :project => @project, :member => member}) %>
51 </tr>
49 </tr>
52 <% end; reset_cycle %>
50 <% end; reset_cycle %>
53 </tbody>
51 </tbody>
54 </table>
52 </table>
55 <% else %>
53 <% else %>
56 <p class="nodata"><%= l(:label_no_data) %></p>
54 <p class="nodata"><%= l(:label_no_data) %></p>
57 <% end %>
55 <% end %>
58 </div>
56 </div>
59
57
60 <% principals = Principal.active.find(:all, :limit => 100, :order => 'type, login, lastname ASC') - @project.principals %>
58 <% principals = Principal.active.find(:all, :limit => 100, :order => 'type, login, lastname ASC') - @project.principals %>
61
59
62 <div class="splitcontentright">
60 <div class="splitcontentright">
63 <% if roles.any? && principals.any? %>
61 <% if roles.any? && principals.any? %>
64 <% remote_form_for(:member, @member, :url => {:controller => 'members', :action => 'new', :id => @project}, :method => :post,
62 <% remote_form_for(:membership, @member, :url => project_memberships_path(@project), :method => :post,
65 :loading => '$(\'member-add-submit\').disable();',
63 :loading => '$(\'member-add-submit\').disable();',
66 :complete => 'if($(\'member-add-submit\')) $(\'member-add-submit\').enable();') do |f| %>
64 :complete => 'if($(\'member-add-submit\')) $(\'member-add-submit\').enable();') do |f| %>
67 <fieldset><legend><%=l(:label_member_new)%></legend>
65 <fieldset><legend><%=l(:label_member_new)%></legend>
68
66
69 <p><%= label_tag "principal_search", l(:label_principal_search) %><%= text_field_tag 'principal_search', nil %></p>
67 <p><%= label_tag "principal_search", l(:label_principal_search) %><%= text_field_tag 'principal_search', nil %></p>
70 <%= observe_field(:principal_search,
68 <%= observe_field(:principal_search,
71 :frequency => 0.5,
69 :frequency => 0.5,
72 :update => :principals,
70 :update => :principals,
73 :url => { :controller => 'members', :action => 'autocomplete_for_member', :id => @project },
71 :url => autocomplete_project_memberships_path(@project),
72 :method => :get,
74 :with => 'q')
73 :with => 'q')
75 %>
74 %>
76
75
77 <div id="principals">
76 <div id="principals">
78 <%= principals_check_box_tags 'member[user_ids][]', principals %>
77 <%= principals_check_box_tags 'membership[user_ids][]', principals %>
79 </div>
78 </div>
80
79
81 <p><%= l(:label_role_plural) %>:
80 <p><%= l(:label_role_plural) %>:
82 <% roles.each do |role| %>
81 <% roles.each do |role| %>
83 <label><%= check_box_tag 'member[role_ids][]', role.id %> <%=h role %></label>
82 <label><%= check_box_tag 'membership[role_ids][]', role.id %> <%=h role %></label>
84 <% end %></p>
83 <% end %></p>
85
84
86 <p><%= submit_tag l(:button_add), :id => 'member-add-submit' %></p>
85 <p><%= submit_tag l(:button_add), :id => 'member-add-submit' %></p>
87 </fieldset>
86 </fieldset>
88 <% end %>
87 <% end %>
89 <% end %>
88 <% end %>
90 </div>
89 </div>
@@ -1,421 +1,415
1 ActionController::Routing::Routes.draw do |map|
1 ActionController::Routing::Routes.draw do |map|
2 # Add your own custom routes here.
2 # Add your own custom routes here.
3 # The priority is based upon order of creation: first created -> highest priority.
3 # The priority is based upon order of creation: first created -> highest priority.
4
4
5 # Here's a sample route:
5 # Here's a sample route:
6 # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
6 # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
7 # Keep in mind you can assign values other than :controller and :action
7 # Keep in mind you can assign values other than :controller and :action
8
8
9 map.home '', :controller => 'welcome', :conditions => {:method => :get}
9 map.home '', :controller => 'welcome', :conditions => {:method => :get}
10
10
11 map.signin 'login', :controller => 'account', :action => 'login',
11 map.signin 'login', :controller => 'account', :action => 'login',
12 :conditions => {:method => [:get, :post]}
12 :conditions => {:method => [:get, :post]}
13 map.signout 'logout', :controller => 'account', :action => 'logout',
13 map.signout 'logout', :controller => 'account', :action => 'logout',
14 :conditions => {:method => :get}
14 :conditions => {:method => :get}
15 map.connect 'account/register', :controller => 'account', :action => 'register',
15 map.connect 'account/register', :controller => 'account', :action => 'register',
16 :conditions => {:method => [:get, :post]}
16 :conditions => {:method => [:get, :post]}
17 map.connect 'account/lost_password', :controller => 'account', :action => 'lost_password',
17 map.connect 'account/lost_password', :controller => 'account', :action => 'lost_password',
18 :conditions => {:method => [:get, :post]}
18 :conditions => {:method => [:get, :post]}
19 map.connect 'account/activate', :controller => 'account', :action => 'activate',
19 map.connect 'account/activate', :controller => 'account', :action => 'activate',
20 :conditions => {:method => :get}
20 :conditions => {:method => :get}
21
21
22 map.connect 'projects/:id/wiki', :controller => 'wikis',
22 map.connect 'projects/:id/wiki', :controller => 'wikis',
23 :action => 'edit', :conditions => {:method => :post}
23 :action => 'edit', :conditions => {:method => :post}
24 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis',
24 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis',
25 :action => 'destroy', :conditions => {:method => [:get, :post]}
25 :action => 'destroy', :conditions => {:method => [:get, :post]}
26
26
27 map.with_options :controller => 'messages' do |messages_routes|
27 map.with_options :controller => 'messages' do |messages_routes|
28 messages_routes.with_options :conditions => {:method => :get} do |messages_views|
28 messages_routes.with_options :conditions => {:method => :get} do |messages_views|
29 messages_views.connect 'boards/:board_id/topics/new', :action => 'new'
29 messages_views.connect 'boards/:board_id/topics/new', :action => 'new'
30 messages_views.connect 'boards/:board_id/topics/:id', :action => 'show'
30 messages_views.connect 'boards/:board_id/topics/:id', :action => 'show'
31 messages_views.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
31 messages_views.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
32 end
32 end
33 messages_routes.with_options :conditions => {:method => :post} do |messages_actions|
33 messages_routes.with_options :conditions => {:method => :post} do |messages_actions|
34 messages_actions.connect 'boards/:board_id/topics/new', :action => 'new'
34 messages_actions.connect 'boards/:board_id/topics/new', :action => 'new'
35 messages_actions.connect 'boards/:board_id/topics/preview', :action => 'preview'
35 messages_actions.connect 'boards/:board_id/topics/preview', :action => 'preview'
36 messages_actions.connect 'boards/:board_id/topics/quote/:id', :action => 'quote'
36 messages_actions.connect 'boards/:board_id/topics/quote/:id', :action => 'quote'
37 messages_actions.connect 'boards/:board_id/topics/:id/replies', :action => 'reply'
37 messages_actions.connect 'boards/:board_id/topics/:id/replies', :action => 'reply'
38 messages_actions.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
38 messages_actions.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
39 messages_actions.connect 'boards/:board_id/topics/:id/destroy', :action => 'destroy'
39 messages_actions.connect 'boards/:board_id/topics/:id/destroy', :action => 'destroy'
40 end
40 end
41 end
41 end
42
42
43 # Misc issue routes. TODO: move into resources
43 # Misc issue routes. TODO: move into resources
44 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes',
44 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes',
45 :action => 'issues', :conditions => { :method => :get }
45 :action => 'issues', :conditions => { :method => :get }
46 # TODO: would look nicer as /issues/:id/preview
46 # TODO: would look nicer as /issues/:id/preview
47 map.preview_issue '/issues/preview/:id', :controller => 'previews',
47 map.preview_issue '/issues/preview/:id', :controller => 'previews',
48 :action => 'issue'
48 :action => 'issue'
49 map.issues_context_menu '/issues/context_menu',
49 map.issues_context_menu '/issues/context_menu',
50 :controller => 'context_menus', :action => 'issues'
50 :controller => 'context_menus', :action => 'issues'
51
51
52 map.issue_changes '/issues/changes', :controller => 'journals', :action => 'index'
52 map.issue_changes '/issues/changes', :controller => 'journals', :action => 'index'
53 map.quoted_issue '/issues/:id/quoted', :controller => 'journals', :action => 'new',
53 map.quoted_issue '/issues/:id/quoted', :controller => 'journals', :action => 'new',
54 :id => /\d+/, :conditions => { :method => :post }
54 :id => /\d+/, :conditions => { :method => :post }
55
55
56 map.connect '/journals/diff/:id', :controller => 'journals', :action => 'diff',
56 map.connect '/journals/diff/:id', :controller => 'journals', :action => 'diff',
57 :id => /\d+/, :conditions => { :method => :get }
57 :id => /\d+/, :conditions => { :method => :get }
58 map.connect '/journals/edit/:id', :controller => 'journals', :action => 'edit',
58 map.connect '/journals/edit/:id', :controller => 'journals', :action => 'edit',
59 :id => /\d+/, :conditions => { :method => [:get, :post] }
59 :id => /\d+/, :conditions => { :method => [:get, :post] }
60
60
61 map.with_options :controller => 'gantts', :action => 'show' do |gantts_routes|
61 map.with_options :controller => 'gantts', :action => 'show' do |gantts_routes|
62 gantts_routes.connect '/projects/:project_id/issues/gantt'
62 gantts_routes.connect '/projects/:project_id/issues/gantt'
63 gantts_routes.connect '/projects/:project_id/issues/gantt.:format'
63 gantts_routes.connect '/projects/:project_id/issues/gantt.:format'
64 gantts_routes.connect '/issues/gantt.:format'
64 gantts_routes.connect '/issues/gantt.:format'
65 end
65 end
66
66
67 map.with_options :controller => 'calendars', :action => 'show' do |calendars_routes|
67 map.with_options :controller => 'calendars', :action => 'show' do |calendars_routes|
68 calendars_routes.connect '/projects/:project_id/issues/calendar'
68 calendars_routes.connect '/projects/:project_id/issues/calendar'
69 calendars_routes.connect '/issues/calendar'
69 calendars_routes.connect '/issues/calendar'
70 end
70 end
71
71
72 map.with_options :controller => 'reports', :conditions => {:method => :get} do |reports|
72 map.with_options :controller => 'reports', :conditions => {:method => :get} do |reports|
73 reports.connect 'projects/:id/issues/report', :action => 'issue_report'
73 reports.connect 'projects/:id/issues/report', :action => 'issue_report'
74 reports.connect 'projects/:id/issues/report/:detail', :action => 'issue_report_details'
74 reports.connect 'projects/:id/issues/report/:detail', :action => 'issue_report_details'
75 end
75 end
76
76
77 map.connect 'my/account', :controller => 'my', :action => 'account',
77 map.connect 'my/account', :controller => 'my', :action => 'account',
78 :conditions => {:method => [:get, :post]}
78 :conditions => {:method => [:get, :post]}
79 map.connect 'my/page', :controller => 'my', :action => 'page',
79 map.connect 'my/page', :controller => 'my', :action => 'page',
80 :conditions => {:method => :get}
80 :conditions => {:method => :get}
81 # Redirects to my/page
81 # Redirects to my/page
82 map.connect 'my', :controller => 'my', :action => 'index',
82 map.connect 'my', :controller => 'my', :action => 'index',
83 :conditions => {:method => :get}
83 :conditions => {:method => :get}
84 map.connect 'my/reset_rss_key', :controller => 'my', :action => 'reset_rss_key',
84 map.connect 'my/reset_rss_key', :controller => 'my', :action => 'reset_rss_key',
85 :conditions => {:method => :post}
85 :conditions => {:method => :post}
86 map.connect 'my/reset_api_key', :controller => 'my', :action => 'reset_api_key',
86 map.connect 'my/reset_api_key', :controller => 'my', :action => 'reset_api_key',
87 :conditions => {:method => :post}
87 :conditions => {:method => :post}
88 map.connect 'my/password', :controller => 'my', :action => 'password',
88 map.connect 'my/password', :controller => 'my', :action => 'password',
89 :conditions => {:method => [:get, :post]}
89 :conditions => {:method => [:get, :post]}
90 map.connect 'my/page_layout', :controller => 'my', :action => 'page_layout',
90 map.connect 'my/page_layout', :controller => 'my', :action => 'page_layout',
91 :conditions => {:method => :get}
91 :conditions => {:method => :get}
92 map.connect 'my/add_block', :controller => 'my', :action => 'add_block',
92 map.connect 'my/add_block', :controller => 'my', :action => 'add_block',
93 :conditions => {:method => :post}
93 :conditions => {:method => :post}
94 map.connect 'my/remove_block', :controller => 'my', :action => 'remove_block',
94 map.connect 'my/remove_block', :controller => 'my', :action => 'remove_block',
95 :conditions => {:method => :post}
95 :conditions => {:method => :post}
96 map.connect 'my/order_blocks', :controller => 'my', :action => 'order_blocks',
96 map.connect 'my/order_blocks', :controller => 'my', :action => 'order_blocks',
97 :conditions => {:method => :post}
97 :conditions => {:method => :post}
98
98
99 map.connect 'projects/:id/members/new', :controller => 'members',
100 :action => 'new', :conditions => { :method => :post }
101 map.connect 'members/edit/:id', :controller => 'members',
102 :action => 'edit', :id => /\d+/, :conditions => { :method => :post }
103 map.connect 'members/destroy/:id', :controller => 'members',
104 :action => 'destroy', :id => /\d+/, :conditions => { :method => :post }
105 map.connect 'members/autocomplete_for_member/:id', :controller => 'members',
106 :action => 'autocomplete_for_member', :conditions => { :method => :post }
107
108 map.with_options :controller => 'users' do |users|
99 map.with_options :controller => 'users' do |users|
109 users.user_membership 'users/:id/memberships/:membership_id',
100 users.user_membership 'users/:id/memberships/:membership_id',
110 :action => 'edit_membership',
101 :action => 'edit_membership',
111 :conditions => {:method => :put}
102 :conditions => {:method => :put}
112 users.connect 'users/:id/memberships/:membership_id',
103 users.connect 'users/:id/memberships/:membership_id',
113 :action => 'destroy_membership',
104 :action => 'destroy_membership',
114 :conditions => {:method => :delete}
105 :conditions => {:method => :delete}
115 users.user_memberships 'users/:id/memberships',
106 users.user_memberships 'users/:id/memberships',
116 :action => 'edit_membership',
107 :action => 'edit_membership',
117 :conditions => {:method => :post}
108 :conditions => {:method => :post}
118 end
109 end
119 map.resources :users
110 map.resources :users
120
111
121 # For nice "roadmap" in the url for the index action
112 # For nice "roadmap" in the url for the index action
122 map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
113 map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
123
114
124 map.preview_news '/news/preview', :controller => 'previews', :action => 'news'
115 map.preview_news '/news/preview', :controller => 'previews', :action => 'news'
125 map.connect 'news/:id/comments', :controller => 'comments',
116 map.connect 'news/:id/comments', :controller => 'comments',
126 :action => 'create', :conditions => {:method => :post}
117 :action => 'create', :conditions => {:method => :post}
127 map.connect 'news/:id/comments/:comment_id', :controller => 'comments',
118 map.connect 'news/:id/comments/:comment_id', :controller => 'comments',
128 :action => 'destroy', :conditions => {:method => :delete}
119 :action => 'destroy', :conditions => {:method => :delete}
129
120
130 map.connect 'watchers/new', :controller=> 'watchers', :action => 'new',
121 map.connect 'watchers/new', :controller=> 'watchers', :action => 'new',
131 :conditions => {:method => :get}
122 :conditions => {:method => :get}
132 map.connect 'watchers', :controller=> 'watchers', :action => 'create',
123 map.connect 'watchers', :controller=> 'watchers', :action => 'create',
133 :conditions => {:method => :post}
124 :conditions => {:method => :post}
134 map.connect 'watchers/destroy', :controller=> 'watchers', :action => 'destroy',
125 map.connect 'watchers/destroy', :controller=> 'watchers', :action => 'destroy',
135 :conditions => {:method => :post}
126 :conditions => {:method => :post}
136 map.connect 'watchers/watch', :controller=> 'watchers', :action => 'watch',
127 map.connect 'watchers/watch', :controller=> 'watchers', :action => 'watch',
137 :conditions => {:method => :post}
128 :conditions => {:method => :post}
138 map.connect 'watchers/unwatch', :controller=> 'watchers', :action => 'unwatch',
129 map.connect 'watchers/unwatch', :controller=> 'watchers', :action => 'unwatch',
139 :conditions => {:method => :post}
130 :conditions => {:method => :post}
140 map.connect 'watchers/autocomplete_for_user', :controller=> 'watchers', :action => 'autocomplete_for_user',
131 map.connect 'watchers/autocomplete_for_user', :controller=> 'watchers', :action => 'autocomplete_for_user',
141 :conditions => {:method => :get}
132 :conditions => {:method => :get}
142
133
143 # TODO: port to be part of the resources route(s)
134 # TODO: port to be part of the resources route(s)
144 map.with_options :conditions => {:method => :get} do |project_views|
135 map.with_options :conditions => {:method => :get} do |project_views|
145 project_views.connect 'projects/:id/settings/:tab',
136 project_views.connect 'projects/:id/settings/:tab',
146 :controller => 'projects', :action => 'settings'
137 :controller => 'projects', :action => 'settings'
147 project_views.connect 'projects/:project_id/issues/:copy_from/copy',
138 project_views.connect 'projects/:project_id/issues/:copy_from/copy',
148 :controller => 'issues', :action => 'new'
139 :controller => 'issues', :action => 'new'
149 end
140 end
150
141
151 map.resources :projects, :member => {
142 map.resources :projects, :member => {
152 :copy => [:get, :post],
143 :copy => [:get, :post],
153 :settings => :get,
144 :settings => :get,
154 :modules => :post,
145 :modules => :post,
155 :archive => :post,
146 :archive => :post,
156 :unarchive => :post
147 :unarchive => :post
157 } do |project|
148 } do |project|
158 project.resource :enumerations, :controller => 'project_enumerations',
149 project.resource :enumerations, :controller => 'project_enumerations',
159 :only => [:update, :destroy]
150 :only => [:update, :destroy]
160 # issue form update
151 # issue form update
161 project.issue_form 'issues/new', :controller => 'issues',
152 project.issue_form 'issues/new', :controller => 'issues',
162 :action => 'new', :conditions => {:method => [:post, :put]}
153 :action => 'new', :conditions => {:method => [:post, :put]}
163 project.resources :issues, :only => [:index, :new, :create] do |issues|
154 project.resources :issues, :only => [:index, :new, :create] do |issues|
164 issues.resources :time_entries, :controller => 'timelog',
155 issues.resources :time_entries, :controller => 'timelog',
165 :collection => {:report => :get}
156 :collection => {:report => :get}
166 end
157 end
167
158
168 project.resources :files, :only => [:index, :new, :create]
159 project.resources :files, :only => [:index, :new, :create]
169 project.resources :versions, :shallow => true,
160 project.resources :versions, :shallow => true,
170 :collection => {:close_completed => :put},
161 :collection => {:close_completed => :put},
171 :member => {:status_by => :post}
162 :member => {:status_by => :post}
172 project.resources :news, :shallow => true
163 project.resources :news, :shallow => true
173 project.resources :time_entries, :controller => 'timelog',
164 project.resources :time_entries, :controller => 'timelog',
174 :collection => {:report => :get}
165 :collection => {:report => :get}
175 project.resources :queries, :only => [:new, :create]
166 project.resources :queries, :only => [:new, :create]
176 project.resources :issue_categories, :shallow => true
167 project.resources :issue_categories, :shallow => true
177 project.resources :documents, :shallow => true, :member => {:add_attachment => :post}
168 project.resources :documents, :shallow => true, :member => {:add_attachment => :post}
178 project.resources :boards
169 project.resources :boards
179 project.resources :repositories, :shallow => true, :except => [:index, :show],
170 project.resources :repositories, :shallow => true, :except => [:index, :show],
180 :member => {:committers => [:get, :post]}
171 :member => {:committers => [:get, :post]}
172 project.resources :memberships, :shallow => true, :controller => 'members',
173 :only => [:create, :update, :destroy],
174 :collection => {:autocomplete => :get}
181
175
182 project.wiki_start_page 'wiki', :controller => 'wiki', :action => 'show', :conditions => {:method => :get}
176 project.wiki_start_page 'wiki', :controller => 'wiki', :action => 'show', :conditions => {:method => :get}
183 project.wiki_index 'wiki/index', :controller => 'wiki', :action => 'index', :conditions => {:method => :get}
177 project.wiki_index 'wiki/index', :controller => 'wiki', :action => 'index', :conditions => {:method => :get}
184 project.wiki_diff 'wiki/:id/diff/:version', :controller => 'wiki', :action => 'diff', :version => nil
178 project.wiki_diff 'wiki/:id/diff/:version', :controller => 'wiki', :action => 'diff', :version => nil
185 project.wiki_diff 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff'
179 project.wiki_diff 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff'
186 project.wiki_annotate 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate'
180 project.wiki_annotate 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate'
187 project.resources :wiki, :except => [:new, :create], :member => {
181 project.resources :wiki, :except => [:new, :create], :member => {
188 :rename => [:get, :post],
182 :rename => [:get, :post],
189 :history => :get,
183 :history => :get,
190 :preview => :any,
184 :preview => :any,
191 :protect => :post,
185 :protect => :post,
192 :add_attachment => :post
186 :add_attachment => :post
193 }, :collection => {
187 }, :collection => {
194 :export => :get,
188 :export => :get,
195 :date_index => :get
189 :date_index => :get
196 }
190 }
197 end
191 end
198
192
199 map.connect 'news', :controller => 'news', :action => 'index'
193 map.connect 'news', :controller => 'news', :action => 'index'
200 map.connect 'news.:format', :controller => 'news', :action => 'index'
194 map.connect 'news.:format', :controller => 'news', :action => 'index'
201
195
202 map.resources :queries, :except => [:show]
196 map.resources :queries, :except => [:show]
203 map.resources :issues,
197 map.resources :issues,
204 :collection => {:bulk_edit => [:get, :post], :bulk_update => :post} do |issues|
198 :collection => {:bulk_edit => [:get, :post], :bulk_update => :post} do |issues|
205 issues.resources :time_entries, :controller => 'timelog',
199 issues.resources :time_entries, :controller => 'timelog',
206 :collection => {:report => :get}
200 :collection => {:report => :get}
207 issues.resources :relations, :shallow => true,
201 issues.resources :relations, :shallow => true,
208 :controller => 'issue_relations',
202 :controller => 'issue_relations',
209 :only => [:index, :show, :create, :destroy]
203 :only => [:index, :show, :create, :destroy]
210 end
204 end
211 # Bulk deletion
205 # Bulk deletion
212 map.connect '/issues', :controller => 'issues', :action => 'destroy',
206 map.connect '/issues', :controller => 'issues', :action => 'destroy',
213 :conditions => {:method => :delete}
207 :conditions => {:method => :delete}
214
208
215 map.connect '/time_entries/destroy',
209 map.connect '/time_entries/destroy',
216 :controller => 'timelog', :action => 'destroy',
210 :controller => 'timelog', :action => 'destroy',
217 :conditions => { :method => :delete }
211 :conditions => { :method => :delete }
218 map.time_entries_context_menu '/time_entries/context_menu',
212 map.time_entries_context_menu '/time_entries/context_menu',
219 :controller => 'context_menus', :action => 'time_entries'
213 :controller => 'context_menus', :action => 'time_entries'
220
214
221 map.resources :time_entries, :controller => 'timelog',
215 map.resources :time_entries, :controller => 'timelog',
222 :collection => {:report => :get, :bulk_edit => :get, :bulk_update => :post}
216 :collection => {:report => :get, :bulk_edit => :get, :bulk_update => :post}
223
217
224 map.with_options :controller => 'activities', :action => 'index',
218 map.with_options :controller => 'activities', :action => 'index',
225 :conditions => {:method => :get} do |activity|
219 :conditions => {:method => :get} do |activity|
226 activity.connect 'projects/:id/activity'
220 activity.connect 'projects/:id/activity'
227 activity.connect 'projects/:id/activity.:format'
221 activity.connect 'projects/:id/activity.:format'
228 activity.connect 'activity', :id => nil
222 activity.connect 'activity', :id => nil
229 activity.connect 'activity.:format', :id => nil
223 activity.connect 'activity.:format', :id => nil
230 end
224 end
231
225
232 map.with_options :controller => 'repositories' do |repositories|
226 map.with_options :controller => 'repositories' do |repositories|
233 repositories.with_options :conditions => {:method => :get} do |repository_views|
227 repositories.with_options :conditions => {:method => :get} do |repository_views|
234 repository_views.connect 'projects/:id/repository',
228 repository_views.connect 'projects/:id/repository',
235 :action => 'show'
229 :action => 'show'
236
230
237 repository_views.connect 'projects/:id/repository/:repository_id/statistics',
231 repository_views.connect 'projects/:id/repository/:repository_id/statistics',
238 :action => 'stats'
232 :action => 'stats'
239 repository_views.connect 'projects/:id/repository/:repository_id/graph',
233 repository_views.connect 'projects/:id/repository/:repository_id/graph',
240 :action => 'graph'
234 :action => 'graph'
241
235
242 repository_views.connect 'projects/:id/repository/statistics',
236 repository_views.connect 'projects/:id/repository/statistics',
243 :action => 'stats'
237 :action => 'stats'
244 repository_views.connect 'projects/:id/repository/graph',
238 repository_views.connect 'projects/:id/repository/graph',
245 :action => 'graph'
239 :action => 'graph'
246
240
247 repository_views.connect 'projects/:id/repository/:repository_id/revisions',
241 repository_views.connect 'projects/:id/repository/:repository_id/revisions',
248 :action => 'revisions'
242 :action => 'revisions'
249 repository_views.connect 'projects/:id/repository/:repository_id/revisions.:format',
243 repository_views.connect 'projects/:id/repository/:repository_id/revisions.:format',
250 :action => 'revisions'
244 :action => 'revisions'
251 repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev',
245 repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev',
252 :action => 'revision'
246 :action => 'revision'
253 repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev/issues',
247 repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev/issues',
254 :action => 'add_related_issue', :conditions => {:method => :post}
248 :action => 'add_related_issue', :conditions => {:method => :post}
255 repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev/issues/:issue_id',
249 repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev/issues/:issue_id',
256 :action => 'remove_related_issue', :conditions => {:method => :delete}
250 :action => 'remove_related_issue', :conditions => {:method => :delete}
257 repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev/diff',
251 repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev/diff',
258 :action => 'diff'
252 :action => 'diff'
259 repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev/diff.:format',
253 repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev/diff.:format',
260 :action => 'diff'
254 :action => 'diff'
261 repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev/raw/*path',
255 repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev/raw/*path',
262 :action => 'entry', :format => 'raw'
256 :action => 'entry', :format => 'raw'
263 repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev/:action/*path',
257 repository_views.connect 'projects/:id/repository/:repository_id/revisions/:rev/:action/*path',
264 :requirements => {
258 :requirements => {
265 :action => /(browse|show|entry|changes|annotate|diff)/,
259 :action => /(browse|show|entry|changes|annotate|diff)/,
266 :rev => /[a-z0-9\.\-_]+/
260 :rev => /[a-z0-9\.\-_]+/
267 }
261 }
268 repository_views.connect 'projects/:id/repository/:repository_id/raw/*path',
262 repository_views.connect 'projects/:id/repository/:repository_id/raw/*path',
269 :action => 'entry', :format => 'raw'
263 :action => 'entry', :format => 'raw'
270 repository_views.connect 'projects/:id/repository/:repository_id/:action/*path',
264 repository_views.connect 'projects/:id/repository/:repository_id/:action/*path',
271 :requirements => { :action => /(browse|show|entry|changes|annotate|diff)/ }
265 :requirements => { :action => /(browse|show|entry|changes|annotate|diff)/ }
272
266
273 repository_views.connect 'projects/:id/repository/revisions',
267 repository_views.connect 'projects/:id/repository/revisions',
274 :action => 'revisions'
268 :action => 'revisions'
275 repository_views.connect 'projects/:id/repository/revisions.:format',
269 repository_views.connect 'projects/:id/repository/revisions.:format',
276 :action => 'revisions'
270 :action => 'revisions'
277 repository_views.connect 'projects/:id/repository/revisions/:rev',
271 repository_views.connect 'projects/:id/repository/revisions/:rev',
278 :action => 'revision'
272 :action => 'revision'
279 repository_views.connect 'projects/:id/repository/revisions/:rev/issues',
273 repository_views.connect 'projects/:id/repository/revisions/:rev/issues',
280 :action => 'add_related_issue', :conditions => {:method => :post}
274 :action => 'add_related_issue', :conditions => {:method => :post}
281 repository_views.connect 'projects/:id/repository/revisions/:rev/issues/:issue_id',
275 repository_views.connect 'projects/:id/repository/revisions/:rev/issues/:issue_id',
282 :action => 'remove_related_issue', :conditions => {:method => :delete}
276 :action => 'remove_related_issue', :conditions => {:method => :delete}
283 repository_views.connect 'projects/:id/repository/revisions/:rev/diff',
277 repository_views.connect 'projects/:id/repository/revisions/:rev/diff',
284 :action => 'diff'
278 :action => 'diff'
285 repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format',
279 repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format',
286 :action => 'diff'
280 :action => 'diff'
287 repository_views.connect 'projects/:id/repository/revisions/:rev/raw/*path',
281 repository_views.connect 'projects/:id/repository/revisions/:rev/raw/*path',
288 :action => 'entry', :format => 'raw'
282 :action => 'entry', :format => 'raw'
289 repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path',
283 repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path',
290 :requirements => {
284 :requirements => {
291 :action => /(browse|show|entry|changes|annotate|diff)/,
285 :action => /(browse|show|entry|changes|annotate|diff)/,
292 :rev => /[a-z0-9\.\-_]+/
286 :rev => /[a-z0-9\.\-_]+/
293 }
287 }
294 repository_views.connect 'projects/:id/repository/raw/*path',
288 repository_views.connect 'projects/:id/repository/raw/*path',
295 :action => 'entry', :format => 'raw'
289 :action => 'entry', :format => 'raw'
296 repository_views.connect 'projects/:id/repository/:action/*path',
290 repository_views.connect 'projects/:id/repository/:action/*path',
297 :requirements => { :action => /(browse|show|entry|changes|annotate|diff)/ }
291 :requirements => { :action => /(browse|show|entry|changes|annotate|diff)/ }
298
292
299 repository_views.connect 'projects/:id/repository/:repository_id',
293 repository_views.connect 'projects/:id/repository/:repository_id',
300 :action => 'show'
294 :action => 'show'
301 end
295 end
302
296
303 repositories.connect 'projects/:id/repository/revision',
297 repositories.connect 'projects/:id/repository/revision',
304 :action => 'revision',
298 :action => 'revision',
305 :conditions => {:method => [:get, :post]}
299 :conditions => {:method => [:get, :post]}
306 end
300 end
307
301
308 # additional routes for having the file name at the end of url
302 # additional routes for having the file name at the end of url
309 map.connect 'attachments/:id/:filename', :controller => 'attachments',
303 map.connect 'attachments/:id/:filename', :controller => 'attachments',
310 :action => 'show', :id => /\d+/, :filename => /.*/,
304 :action => 'show', :id => /\d+/, :filename => /.*/,
311 :conditions => {:method => :get}
305 :conditions => {:method => :get}
312 map.connect 'attachments/download/:id/:filename', :controller => 'attachments',
306 map.connect 'attachments/download/:id/:filename', :controller => 'attachments',
313 :action => 'download', :id => /\d+/, :filename => /.*/,
307 :action => 'download', :id => /\d+/, :filename => /.*/,
314 :conditions => {:method => :get}
308 :conditions => {:method => :get}
315 map.connect 'attachments/download/:id', :controller => 'attachments',
309 map.connect 'attachments/download/:id', :controller => 'attachments',
316 :action => 'download', :id => /\d+/,
310 :action => 'download', :id => /\d+/,
317 :conditions => {:method => :get}
311 :conditions => {:method => :get}
318 map.resources :attachments, :only => [:show, :destroy]
312 map.resources :attachments, :only => [:show, :destroy]
319
313
320 map.resources :groups, :member => {:autocomplete_for_user => :get}
314 map.resources :groups, :member => {:autocomplete_for_user => :get}
321 map.group_users 'groups/:id/users', :controller => 'groups',
315 map.group_users 'groups/:id/users', :controller => 'groups',
322 :action => 'add_users', :id => /\d+/,
316 :action => 'add_users', :id => /\d+/,
323 :conditions => {:method => :post}
317 :conditions => {:method => :post}
324 map.group_user 'groups/:id/users/:user_id', :controller => 'groups',
318 map.group_user 'groups/:id/users/:user_id', :controller => 'groups',
325 :action => 'remove_user', :id => /\d+/,
319 :action => 'remove_user', :id => /\d+/,
326 :conditions => {:method => :delete}
320 :conditions => {:method => :delete}
327 map.connect 'groups/destroy_membership/:id', :controller => 'groups',
321 map.connect 'groups/destroy_membership/:id', :controller => 'groups',
328 :action => 'destroy_membership', :id => /\d+/,
322 :action => 'destroy_membership', :id => /\d+/,
329 :conditions => {:method => :post}
323 :conditions => {:method => :post}
330 map.connect 'groups/edit_membership/:id', :controller => 'groups',
324 map.connect 'groups/edit_membership/:id', :controller => 'groups',
331 :action => 'edit_membership', :id => /\d+/,
325 :action => 'edit_membership', :id => /\d+/,
332 :conditions => {:method => :post}
326 :conditions => {:method => :post}
333
327
334 map.resources :trackers, :except => :show
328 map.resources :trackers, :except => :show
335 map.resources :issue_statuses, :except => :show, :collection => {:update_issue_done_ratio => :post}
329 map.resources :issue_statuses, :except => :show, :collection => {:update_issue_done_ratio => :post}
336 map.resources :custom_fields, :except => :show
330 map.resources :custom_fields, :except => :show
337 map.resources :roles, :except => :show, :collection => {:permissions => [:get, :post]}
331 map.resources :roles, :except => :show, :collection => {:permissions => [:get, :post]}
338 map.resources :enumerations, :except => :show
332 map.resources :enumerations, :except => :show
339
333
340 map.connect 'search', :controller => 'search', :action => 'index', :conditions => {:method => :get}
334 map.connect 'search', :controller => 'search', :action => 'index', :conditions => {:method => :get}
341
335
342 map.connect 'mail_handler', :controller => 'mail_handler',
336 map.connect 'mail_handler', :controller => 'mail_handler',
343 :action => 'index', :conditions => {:method => :post}
337 :action => 'index', :conditions => {:method => :post}
344
338
345 map.connect 'admin', :controller => 'admin', :action => 'index',
339 map.connect 'admin', :controller => 'admin', :action => 'index',
346 :conditions => {:method => :get}
340 :conditions => {:method => :get}
347 map.connect 'admin/projects', :controller => 'admin', :action => 'projects',
341 map.connect 'admin/projects', :controller => 'admin', :action => 'projects',
348 :conditions => {:method => :get}
342 :conditions => {:method => :get}
349 map.connect 'admin/plugins', :controller => 'admin', :action => 'plugins',
343 map.connect 'admin/plugins', :controller => 'admin', :action => 'plugins',
350 :conditions => {:method => :get}
344 :conditions => {:method => :get}
351 map.connect 'admin/info', :controller => 'admin', :action => 'info',
345 map.connect 'admin/info', :controller => 'admin', :action => 'info',
352 :conditions => {:method => :get}
346 :conditions => {:method => :get}
353 map.connect 'admin/test_email', :controller => 'admin', :action => 'test_email',
347 map.connect 'admin/test_email', :controller => 'admin', :action => 'test_email',
354 :conditions => {:method => :get}
348 :conditions => {:method => :get}
355 map.connect 'admin/default_configuration', :controller => 'admin',
349 map.connect 'admin/default_configuration', :controller => 'admin',
356 :action => 'default_configuration', :conditions => {:method => :post}
350 :action => 'default_configuration', :conditions => {:method => :post}
357
351
358 # Used by AuthSourcesControllerTest
352 # Used by AuthSourcesControllerTest
359 # TODO : refactor *AuthSourcesController to remove these routes
353 # TODO : refactor *AuthSourcesController to remove these routes
360 map.connect 'auth_sources', :controller => 'auth_sources',
354 map.connect 'auth_sources', :controller => 'auth_sources',
361 :action => 'index', :conditions => {:method => :get}
355 :action => 'index', :conditions => {:method => :get}
362 map.connect 'auth_sources/new', :controller => 'auth_sources',
356 map.connect 'auth_sources/new', :controller => 'auth_sources',
363 :action => 'new', :conditions => {:method => :get}
357 :action => 'new', :conditions => {:method => :get}
364 map.connect 'auth_sources/create', :controller => 'auth_sources',
358 map.connect 'auth_sources/create', :controller => 'auth_sources',
365 :action => 'create', :conditions => {:method => :post}
359 :action => 'create', :conditions => {:method => :post}
366 map.connect 'auth_sources/destroy/:id', :controller => 'auth_sources',
360 map.connect 'auth_sources/destroy/:id', :controller => 'auth_sources',
367 :action => 'destroy', :id => /\d+/, :conditions => {:method => :post}
361 :action => 'destroy', :id => /\d+/, :conditions => {:method => :post}
368 map.connect 'auth_sources/test_connection/:id', :controller => 'auth_sources',
362 map.connect 'auth_sources/test_connection/:id', :controller => 'auth_sources',
369 :action => 'test_connection', :conditions => {:method => :get}
363 :action => 'test_connection', :conditions => {:method => :get}
370 map.connect 'auth_sources/edit/:id', :controller => 'auth_sources',
364 map.connect 'auth_sources/edit/:id', :controller => 'auth_sources',
371 :action => 'edit', :id => /\d+/, :conditions => {:method => :get}
365 :action => 'edit', :id => /\d+/, :conditions => {:method => :get}
372 map.connect 'auth_sources/update/:id', :controller => 'auth_sources',
366 map.connect 'auth_sources/update/:id', :controller => 'auth_sources',
373 :action => 'update', :id => /\d+/, :conditions => {:method => :post}
367 :action => 'update', :id => /\d+/, :conditions => {:method => :post}
374
368
375 map.connect 'ldap_auth_sources', :controller => 'ldap_auth_sources',
369 map.connect 'ldap_auth_sources', :controller => 'ldap_auth_sources',
376 :action => 'index', :conditions => {:method => :get}
370 :action => 'index', :conditions => {:method => :get}
377 map.connect 'ldap_auth_sources/new', :controller => 'ldap_auth_sources',
371 map.connect 'ldap_auth_sources/new', :controller => 'ldap_auth_sources',
378 :action => 'new', :conditions => {:method => :get}
372 :action => 'new', :conditions => {:method => :get}
379 map.connect 'ldap_auth_sources/create', :controller => 'ldap_auth_sources',
373 map.connect 'ldap_auth_sources/create', :controller => 'ldap_auth_sources',
380 :action => 'create', :conditions => {:method => :post}
374 :action => 'create', :conditions => {:method => :post}
381 map.connect 'ldap_auth_sources/destroy/:id', :controller => 'ldap_auth_sources',
375 map.connect 'ldap_auth_sources/destroy/:id', :controller => 'ldap_auth_sources',
382 :action => 'destroy', :id => /\d+/, :conditions => {:method => :post}
376 :action => 'destroy', :id => /\d+/, :conditions => {:method => :post}
383 map.connect 'ldap_auth_sources/test_connection/:id', :controller => 'ldap_auth_sources',
377 map.connect 'ldap_auth_sources/test_connection/:id', :controller => 'ldap_auth_sources',
384 :action => 'test_connection', :conditions => {:method => :get}
378 :action => 'test_connection', :conditions => {:method => :get}
385 map.connect 'ldap_auth_sources/edit/:id', :controller => 'ldap_auth_sources',
379 map.connect 'ldap_auth_sources/edit/:id', :controller => 'ldap_auth_sources',
386 :action => 'edit', :id => /\d+/, :conditions => {:method => :get}
380 :action => 'edit', :id => /\d+/, :conditions => {:method => :get}
387 map.connect 'ldap_auth_sources/update/:id', :controller => 'ldap_auth_sources',
381 map.connect 'ldap_auth_sources/update/:id', :controller => 'ldap_auth_sources',
388 :action => 'update', :id => /\d+/, :conditions => {:method => :post}
382 :action => 'update', :id => /\d+/, :conditions => {:method => :post}
389
383
390 map.connect 'workflows', :controller => 'workflows',
384 map.connect 'workflows', :controller => 'workflows',
391 :action => 'index', :conditions => {:method => :get}
385 :action => 'index', :conditions => {:method => :get}
392 map.connect 'workflows/edit', :controller => 'workflows',
386 map.connect 'workflows/edit', :controller => 'workflows',
393 :action => 'edit', :conditions => {:method => [:get, :post]}
387 :action => 'edit', :conditions => {:method => [:get, :post]}
394 map.connect 'workflows/copy', :controller => 'workflows',
388 map.connect 'workflows/copy', :controller => 'workflows',
395 :action => 'copy', :conditions => {:method => [:get, :post]}
389 :action => 'copy', :conditions => {:method => [:get, :post]}
396
390
397 map.connect 'settings', :controller => 'settings',
391 map.connect 'settings', :controller => 'settings',
398 :action => 'index', :conditions => {:method => :get}
392 :action => 'index', :conditions => {:method => :get}
399 map.connect 'settings/edit', :controller => 'settings',
393 map.connect 'settings/edit', :controller => 'settings',
400 :action => 'edit', :conditions => {:method => [:get, :post]}
394 :action => 'edit', :conditions => {:method => [:get, :post]}
401 map.connect 'settings/plugin/:id', :controller => 'settings',
395 map.connect 'settings/plugin/:id', :controller => 'settings',
402 :action => 'plugin', :conditions => {:method => [:get, :post]}
396 :action => 'plugin', :conditions => {:method => [:get, :post]}
403
397
404 map.with_options :controller => 'sys' do |sys|
398 map.with_options :controller => 'sys' do |sys|
405 sys.connect 'sys/projects.:format',
399 sys.connect 'sys/projects.:format',
406 :action => 'projects',
400 :action => 'projects',
407 :conditions => {:method => :get}
401 :conditions => {:method => :get}
408 sys.connect 'sys/projects/:id/repository.:format',
402 sys.connect 'sys/projects/:id/repository.:format',
409 :action => 'create_project_repository',
403 :action => 'create_project_repository',
410 :conditions => {:method => :post}
404 :conditions => {:method => :post}
411 sys.connect 'sys/fetch_changesets',
405 sys.connect 'sys/fetch_changesets',
412 :action => 'fetch_changesets',
406 :action => 'fetch_changesets',
413 :conditions => {:method => :get}
407 :conditions => {:method => :get}
414 end
408 end
415
409
416 map.connect 'robots.txt', :controller => 'welcome',
410 map.connect 'robots.txt', :controller => 'welcome',
417 :action => 'robots', :conditions => {:method => :get}
411 :action => 'robots', :conditions => {:method => :get}
418
412
419 # Used for OpenID
413 # Used for OpenID
420 map.root :controller => 'account', :action => 'login'
414 map.root :controller => 'account', :action => 'login'
421 end
415 end
@@ -1,238 +1,238
1 require 'redmine/access_control'
1 require 'redmine/access_control'
2 require 'redmine/menu_manager'
2 require 'redmine/menu_manager'
3 require 'redmine/activity'
3 require 'redmine/activity'
4 require 'redmine/search'
4 require 'redmine/search'
5 require 'redmine/custom_field_format'
5 require 'redmine/custom_field_format'
6 require 'redmine/mime_type'
6 require 'redmine/mime_type'
7 require 'redmine/core_ext'
7 require 'redmine/core_ext'
8 require 'redmine/themes'
8 require 'redmine/themes'
9 require 'redmine/hook'
9 require 'redmine/hook'
10 require 'redmine/plugin'
10 require 'redmine/plugin'
11 require 'redmine/notifiable'
11 require 'redmine/notifiable'
12 require 'redmine/wiki_formatting'
12 require 'redmine/wiki_formatting'
13 require 'redmine/scm/base'
13 require 'redmine/scm/base'
14
14
15 begin
15 begin
16 require_library_or_gem 'RMagick' unless Object.const_defined?(:Magick)
16 require_library_or_gem 'RMagick' unless Object.const_defined?(:Magick)
17 rescue LoadError
17 rescue LoadError
18 # RMagick is not available
18 # RMagick is not available
19 end
19 end
20
20
21 if RUBY_VERSION < '1.9'
21 if RUBY_VERSION < '1.9'
22 require 'faster_csv'
22 require 'faster_csv'
23 else
23 else
24 require 'csv'
24 require 'csv'
25 FCSV = CSV
25 FCSV = CSV
26 end
26 end
27
27
28 Redmine::Scm::Base.add "Subversion"
28 Redmine::Scm::Base.add "Subversion"
29 Redmine::Scm::Base.add "Darcs"
29 Redmine::Scm::Base.add "Darcs"
30 Redmine::Scm::Base.add "Mercurial"
30 Redmine::Scm::Base.add "Mercurial"
31 Redmine::Scm::Base.add "Cvs"
31 Redmine::Scm::Base.add "Cvs"
32 Redmine::Scm::Base.add "Bazaar"
32 Redmine::Scm::Base.add "Bazaar"
33 Redmine::Scm::Base.add "Git"
33 Redmine::Scm::Base.add "Git"
34 Redmine::Scm::Base.add "Filesystem"
34 Redmine::Scm::Base.add "Filesystem"
35
35
36 Redmine::CustomFieldFormat.map do |fields|
36 Redmine::CustomFieldFormat.map do |fields|
37 fields.register Redmine::CustomFieldFormat.new('string', :label => :label_string, :order => 1)
37 fields.register Redmine::CustomFieldFormat.new('string', :label => :label_string, :order => 1)
38 fields.register Redmine::CustomFieldFormat.new('text', :label => :label_text, :order => 2)
38 fields.register Redmine::CustomFieldFormat.new('text', :label => :label_text, :order => 2)
39 fields.register Redmine::CustomFieldFormat.new('int', :label => :label_integer, :order => 3)
39 fields.register Redmine::CustomFieldFormat.new('int', :label => :label_integer, :order => 3)
40 fields.register Redmine::CustomFieldFormat.new('float', :label => :label_float, :order => 4)
40 fields.register Redmine::CustomFieldFormat.new('float', :label => :label_float, :order => 4)
41 fields.register Redmine::CustomFieldFormat.new('list', :label => :label_list, :order => 5)
41 fields.register Redmine::CustomFieldFormat.new('list', :label => :label_list, :order => 5)
42 fields.register Redmine::CustomFieldFormat.new('date', :label => :label_date, :order => 6)
42 fields.register Redmine::CustomFieldFormat.new('date', :label => :label_date, :order => 6)
43 fields.register Redmine::CustomFieldFormat.new('bool', :label => :label_boolean, :order => 7)
43 fields.register Redmine::CustomFieldFormat.new('bool', :label => :label_boolean, :order => 7)
44 fields.register Redmine::CustomFieldFormat.new('user', :label => :label_user, :only => %w(Issue TimeEntry Version Project), :edit_as => 'list', :order => 8)
44 fields.register Redmine::CustomFieldFormat.new('user', :label => :label_user, :only => %w(Issue TimeEntry Version Project), :edit_as => 'list', :order => 8)
45 fields.register Redmine::CustomFieldFormat.new('version', :label => :label_version, :only => %w(Issue TimeEntry Version Project), :edit_as => 'list', :order => 9)
45 fields.register Redmine::CustomFieldFormat.new('version', :label => :label_version, :only => %w(Issue TimeEntry Version Project), :edit_as => 'list', :order => 9)
46 end
46 end
47
47
48 # Permissions
48 # Permissions
49 Redmine::AccessControl.map do |map|
49 Redmine::AccessControl.map do |map|
50 map.permission :view_project, {:projects => [:show], :activities => [:index]}, :public => true
50 map.permission :view_project, {:projects => [:show], :activities => [:index]}, :public => true
51 map.permission :search_project, {:search => :index}, :public => true
51 map.permission :search_project, {:search => :index}, :public => true
52 map.permission :add_project, {:projects => [:new, :create]}, :require => :loggedin
52 map.permission :add_project, {:projects => [:new, :create]}, :require => :loggedin
53 map.permission :edit_project, {:projects => [:settings, :edit, :update]}, :require => :member
53 map.permission :edit_project, {:projects => [:settings, :edit, :update]}, :require => :member
54 map.permission :select_project_modules, {:projects => :modules}, :require => :member
54 map.permission :select_project_modules, {:projects => :modules}, :require => :member
55 map.permission :manage_members, {:projects => :settings, :members => [:new, :edit, :destroy, :autocomplete_for_member]}, :require => :member
55 map.permission :manage_members, {:projects => :settings, :members => [:create, :update, :destroy, :autocomplete]}, :require => :member
56 map.permission :manage_versions, {:projects => :settings, :versions => [:new, :create, :edit, :update, :close_completed, :destroy]}, :require => :member
56 map.permission :manage_versions, {:projects => :settings, :versions => [:new, :create, :edit, :update, :close_completed, :destroy]}, :require => :member
57 map.permission :add_subprojects, {:projects => [:new, :create]}, :require => :member
57 map.permission :add_subprojects, {:projects => [:new, :create]}, :require => :member
58
58
59 map.project_module :issue_tracking do |map|
59 map.project_module :issue_tracking do |map|
60 # Issue categories
60 # Issue categories
61 map.permission :manage_categories, {:projects => :settings, :issue_categories => [:index, :show, :new, :create, :edit, :update, :destroy]}, :require => :member
61 map.permission :manage_categories, {:projects => :settings, :issue_categories => [:index, :show, :new, :create, :edit, :update, :destroy]}, :require => :member
62 # Issues
62 # Issues
63 map.permission :view_issues, {:issues => [:index, :show],
63 map.permission :view_issues, {:issues => [:index, :show],
64 :auto_complete => [:issues],
64 :auto_complete => [:issues],
65 :context_menus => [:issues],
65 :context_menus => [:issues],
66 :versions => [:index, :show, :status_by],
66 :versions => [:index, :show, :status_by],
67 :journals => [:index, :diff],
67 :journals => [:index, :diff],
68 :queries => :index,
68 :queries => :index,
69 :reports => [:issue_report, :issue_report_details]}
69 :reports => [:issue_report, :issue_report_details]}
70 map.permission :add_issues, {:issues => [:new, :create, :update_form]}
70 map.permission :add_issues, {:issues => [:new, :create, :update_form]}
71 map.permission :edit_issues, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new]}
71 map.permission :edit_issues, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new]}
72 map.permission :manage_issue_relations, {:issue_relations => [:index, :show, :create, :destroy]}
72 map.permission :manage_issue_relations, {:issue_relations => [:index, :show, :create, :destroy]}
73 map.permission :manage_subtasks, {}
73 map.permission :manage_subtasks, {}
74 map.permission :set_issues_private, {}
74 map.permission :set_issues_private, {}
75 map.permission :set_own_issues_private, {}, :require => :loggedin
75 map.permission :set_own_issues_private, {}, :require => :loggedin
76 map.permission :add_issue_notes, {:issues => [:edit, :update], :journals => [:new]}
76 map.permission :add_issue_notes, {:issues => [:edit, :update], :journals => [:new]}
77 map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
77 map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
78 map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin
78 map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin
79 map.permission :move_issues, {:issues => [:bulk_edit, :bulk_update]}, :require => :loggedin
79 map.permission :move_issues, {:issues => [:bulk_edit, :bulk_update]}, :require => :loggedin
80 map.permission :delete_issues, {:issues => :destroy}, :require => :member
80 map.permission :delete_issues, {:issues => :destroy}, :require => :member
81 # Queries
81 # Queries
82 map.permission :manage_public_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :member
82 map.permission :manage_public_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :member
83 map.permission :save_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :loggedin
83 map.permission :save_queries, {:queries => [:new, :create, :edit, :update, :destroy]}, :require => :loggedin
84 # Watchers
84 # Watchers
85 map.permission :view_issue_watchers, {}
85 map.permission :view_issue_watchers, {}
86 map.permission :add_issue_watchers, {:watchers => :new}
86 map.permission :add_issue_watchers, {:watchers => :new}
87 map.permission :delete_issue_watchers, {:watchers => :destroy}
87 map.permission :delete_issue_watchers, {:watchers => :destroy}
88 end
88 end
89
89
90 map.project_module :time_tracking do |map|
90 map.project_module :time_tracking do |map|
91 map.permission :log_time, {:timelog => [:new, :create]}, :require => :loggedin
91 map.permission :log_time, {:timelog => [:new, :create]}, :require => :loggedin
92 map.permission :view_time_entries, :timelog => [:index, :report, :show]
92 map.permission :view_time_entries, :timelog => [:index, :report, :show]
93 map.permission :edit_time_entries, {:timelog => [:edit, :update, :destroy, :bulk_edit, :bulk_update]}, :require => :member
93 map.permission :edit_time_entries, {:timelog => [:edit, :update, :destroy, :bulk_edit, :bulk_update]}, :require => :member
94 map.permission :edit_own_time_entries, {:timelog => [:edit, :update, :destroy,:bulk_edit, :bulk_update]}, :require => :loggedin
94 map.permission :edit_own_time_entries, {:timelog => [:edit, :update, :destroy,:bulk_edit, :bulk_update]}, :require => :loggedin
95 map.permission :manage_project_activities, {:project_enumerations => [:update, :destroy]}, :require => :member
95 map.permission :manage_project_activities, {:project_enumerations => [:update, :destroy]}, :require => :member
96 end
96 end
97
97
98 map.project_module :news do |map|
98 map.project_module :news do |map|
99 map.permission :manage_news, {:news => [:new, :create, :edit, :update, :destroy], :comments => [:destroy]}, :require => :member
99 map.permission :manage_news, {:news => [:new, :create, :edit, :update, :destroy], :comments => [:destroy]}, :require => :member
100 map.permission :view_news, {:news => [:index, :show]}, :public => true
100 map.permission :view_news, {:news => [:index, :show]}, :public => true
101 map.permission :comment_news, {:comments => :create}
101 map.permission :comment_news, {:comments => :create}
102 end
102 end
103
103
104 map.project_module :documents do |map|
104 map.project_module :documents do |map|
105 map.permission :manage_documents, {:documents => [:new, :create, :edit, :update, :destroy, :add_attachment]}, :require => :loggedin
105 map.permission :manage_documents, {:documents => [:new, :create, :edit, :update, :destroy, :add_attachment]}, :require => :loggedin
106 map.permission :view_documents, :documents => [:index, :show, :download]
106 map.permission :view_documents, :documents => [:index, :show, :download]
107 end
107 end
108
108
109 map.project_module :files do |map|
109 map.project_module :files do |map|
110 map.permission :manage_files, {:files => [:new, :create]}, :require => :loggedin
110 map.permission :manage_files, {:files => [:new, :create]}, :require => :loggedin
111 map.permission :view_files, :files => :index, :versions => :download
111 map.permission :view_files, :files => :index, :versions => :download
112 end
112 end
113
113
114 map.project_module :wiki do |map|
114 map.project_module :wiki do |map|
115 map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
115 map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
116 map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member
116 map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member
117 map.permission :delete_wiki_pages, {:wiki => :destroy}, :require => :member
117 map.permission :delete_wiki_pages, {:wiki => :destroy}, :require => :member
118 map.permission :view_wiki_pages, :wiki => [:index, :show, :special, :date_index]
118 map.permission :view_wiki_pages, :wiki => [:index, :show, :special, :date_index]
119 map.permission :export_wiki_pages, :wiki => [:export]
119 map.permission :export_wiki_pages, :wiki => [:export]
120 map.permission :view_wiki_edits, :wiki => [:history, :diff, :annotate]
120 map.permission :view_wiki_edits, :wiki => [:history, :diff, :annotate]
121 map.permission :edit_wiki_pages, :wiki => [:edit, :update, :preview, :add_attachment]
121 map.permission :edit_wiki_pages, :wiki => [:edit, :update, :preview, :add_attachment]
122 map.permission :delete_wiki_pages_attachments, {}
122 map.permission :delete_wiki_pages_attachments, {}
123 map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member
123 map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member
124 end
124 end
125
125
126 map.project_module :repository do |map|
126 map.project_module :repository do |map|
127 map.permission :manage_repository, {:repositories => [:new, :create, :edit, :update, :committers, :destroy]}, :require => :member
127 map.permission :manage_repository, {:repositories => [:new, :create, :edit, :update, :committers, :destroy]}, :require => :member
128 map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]
128 map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]
129 map.permission :view_changesets, :repositories => [:show, :revisions, :revision]
129 map.permission :view_changesets, :repositories => [:show, :revisions, :revision]
130 map.permission :commit_access, {}
130 map.permission :commit_access, {}
131 map.permission :manage_related_issues, {:repositories => [:add_related_issue, :remove_related_issue]}
131 map.permission :manage_related_issues, {:repositories => [:add_related_issue, :remove_related_issue]}
132 end
132 end
133
133
134 map.project_module :boards do |map|
134 map.project_module :boards do |map|
135 map.permission :manage_boards, {:boards => [:new, :create, :edit, :update, :destroy]}, :require => :member
135 map.permission :manage_boards, {:boards => [:new, :create, :edit, :update, :destroy]}, :require => :member
136 map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true
136 map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true
137 map.permission :add_messages, {:messages => [:new, :reply, :quote]}
137 map.permission :add_messages, {:messages => [:new, :reply, :quote]}
138 map.permission :edit_messages, {:messages => :edit}, :require => :member
138 map.permission :edit_messages, {:messages => :edit}, :require => :member
139 map.permission :edit_own_messages, {:messages => :edit}, :require => :loggedin
139 map.permission :edit_own_messages, {:messages => :edit}, :require => :loggedin
140 map.permission :delete_messages, {:messages => :destroy}, :require => :member
140 map.permission :delete_messages, {:messages => :destroy}, :require => :member
141 map.permission :delete_own_messages, {:messages => :destroy}, :require => :loggedin
141 map.permission :delete_own_messages, {:messages => :destroy}, :require => :loggedin
142 end
142 end
143
143
144 map.project_module :calendar do |map|
144 map.project_module :calendar do |map|
145 map.permission :view_calendar, :calendars => [:show, :update]
145 map.permission :view_calendar, :calendars => [:show, :update]
146 end
146 end
147
147
148 map.project_module :gantt do |map|
148 map.project_module :gantt do |map|
149 map.permission :view_gantt, :gantts => [:show, :update]
149 map.permission :view_gantt, :gantts => [:show, :update]
150 end
150 end
151 end
151 end
152
152
153 Redmine::MenuManager.map :top_menu do |menu|
153 Redmine::MenuManager.map :top_menu do |menu|
154 menu.push :home, :home_path
154 menu.push :home, :home_path
155 menu.push :my_page, { :controller => 'my', :action => 'page' }, :if => Proc.new { User.current.logged? }
155 menu.push :my_page, { :controller => 'my', :action => 'page' }, :if => Proc.new { User.current.logged? }
156 menu.push :projects, { :controller => 'projects', :action => 'index' }, :caption => :label_project_plural
156 menu.push :projects, { :controller => 'projects', :action => 'index' }, :caption => :label_project_plural
157 menu.push :administration, { :controller => 'admin', :action => 'index' }, :if => Proc.new { User.current.admin? }, :last => true
157 menu.push :administration, { :controller => 'admin', :action => 'index' }, :if => Proc.new { User.current.admin? }, :last => true
158 menu.push :help, Redmine::Info.help_url, :last => true
158 menu.push :help, Redmine::Info.help_url, :last => true
159 end
159 end
160
160
161 Redmine::MenuManager.map :account_menu do |menu|
161 Redmine::MenuManager.map :account_menu do |menu|
162 menu.push :login, :signin_path, :if => Proc.new { !User.current.logged? }
162 menu.push :login, :signin_path, :if => Proc.new { !User.current.logged? }
163 menu.push :register, { :controller => 'account', :action => 'register' }, :if => Proc.new { !User.current.logged? && Setting.self_registration? }
163 menu.push :register, { :controller => 'account', :action => 'register' }, :if => Proc.new { !User.current.logged? && Setting.self_registration? }
164 menu.push :my_account, { :controller => 'my', :action => 'account' }, :if => Proc.new { User.current.logged? }
164 menu.push :my_account, { :controller => 'my', :action => 'account' }, :if => Proc.new { User.current.logged? }
165 menu.push :logout, :signout_path, :if => Proc.new { User.current.logged? }
165 menu.push :logout, :signout_path, :if => Proc.new { User.current.logged? }
166 end
166 end
167
167
168 Redmine::MenuManager.map :application_menu do |menu|
168 Redmine::MenuManager.map :application_menu do |menu|
169 # Empty
169 # Empty
170 end
170 end
171
171
172 Redmine::MenuManager.map :admin_menu do |menu|
172 Redmine::MenuManager.map :admin_menu do |menu|
173 menu.push :projects, {:controller => 'admin', :action => 'projects'}, :caption => :label_project_plural
173 menu.push :projects, {:controller => 'admin', :action => 'projects'}, :caption => :label_project_plural
174 menu.push :users, {:controller => 'users'}, :caption => :label_user_plural
174 menu.push :users, {:controller => 'users'}, :caption => :label_user_plural
175 menu.push :groups, {:controller => 'groups'}, :caption => :label_group_plural
175 menu.push :groups, {:controller => 'groups'}, :caption => :label_group_plural
176 menu.push :roles, {:controller => 'roles'}, :caption => :label_role_and_permissions
176 menu.push :roles, {:controller => 'roles'}, :caption => :label_role_and_permissions
177 menu.push :trackers, {:controller => 'trackers'}, :caption => :label_tracker_plural
177 menu.push :trackers, {:controller => 'trackers'}, :caption => :label_tracker_plural
178 menu.push :issue_statuses, {:controller => 'issue_statuses'}, :caption => :label_issue_status_plural,
178 menu.push :issue_statuses, {:controller => 'issue_statuses'}, :caption => :label_issue_status_plural,
179 :html => {:class => 'issue_statuses'}
179 :html => {:class => 'issue_statuses'}
180 menu.push :workflows, {:controller => 'workflows', :action => 'edit'}, :caption => :label_workflow
180 menu.push :workflows, {:controller => 'workflows', :action => 'edit'}, :caption => :label_workflow
181 menu.push :custom_fields, {:controller => 'custom_fields'}, :caption => :label_custom_field_plural,
181 menu.push :custom_fields, {:controller => 'custom_fields'}, :caption => :label_custom_field_plural,
182 :html => {:class => 'custom_fields'}
182 :html => {:class => 'custom_fields'}
183 menu.push :enumerations, {:controller => 'enumerations'}
183 menu.push :enumerations, {:controller => 'enumerations'}
184 menu.push :settings, {:controller => 'settings'}
184 menu.push :settings, {:controller => 'settings'}
185 menu.push :ldap_authentication, {:controller => 'ldap_auth_sources', :action => 'index'},
185 menu.push :ldap_authentication, {:controller => 'ldap_auth_sources', :action => 'index'},
186 :html => {:class => 'server_authentication'}
186 :html => {:class => 'server_authentication'}
187 menu.push :plugins, {:controller => 'admin', :action => 'plugins'}, :last => true
187 menu.push :plugins, {:controller => 'admin', :action => 'plugins'}, :last => true
188 menu.push :info, {:controller => 'admin', :action => 'info'}, :caption => :label_information_plural, :last => true
188 menu.push :info, {:controller => 'admin', :action => 'info'}, :caption => :label_information_plural, :last => true
189 end
189 end
190
190
191 Redmine::MenuManager.map :project_menu do |menu|
191 Redmine::MenuManager.map :project_menu do |menu|
192 menu.push :overview, { :controller => 'projects', :action => 'show' }
192 menu.push :overview, { :controller => 'projects', :action => 'show' }
193 menu.push :activity, { :controller => 'activities', :action => 'index' }
193 menu.push :activity, { :controller => 'activities', :action => 'index' }
194 menu.push :roadmap, { :controller => 'versions', :action => 'index' }, :param => :project_id,
194 menu.push :roadmap, { :controller => 'versions', :action => 'index' }, :param => :project_id,
195 :if => Proc.new { |p| p.shared_versions.any? }
195 :if => Proc.new { |p| p.shared_versions.any? }
196 menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
196 menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
197 menu.push :new_issue, { :controller => 'issues', :action => 'new' }, :param => :project_id, :caption => :label_issue_new,
197 menu.push :new_issue, { :controller => 'issues', :action => 'new' }, :param => :project_id, :caption => :label_issue_new,
198 :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
198 :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
199 menu.push :gantt, { :controller => 'gantts', :action => 'show' }, :param => :project_id, :caption => :label_gantt
199 menu.push :gantt, { :controller => 'gantts', :action => 'show' }, :param => :project_id, :caption => :label_gantt
200 menu.push :calendar, { :controller => 'calendars', :action => 'show' }, :param => :project_id, :caption => :label_calendar
200 menu.push :calendar, { :controller => 'calendars', :action => 'show' }, :param => :project_id, :caption => :label_calendar
201 menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural
201 menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural
202 menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural
202 menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural
203 menu.push :wiki, { :controller => 'wiki', :action => 'show', :id => nil }, :param => :project_id,
203 menu.push :wiki, { :controller => 'wiki', :action => 'show', :id => nil }, :param => :project_id,
204 :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
204 :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
205 menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id,
205 menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id,
206 :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural
206 :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural
207 menu.push :files, { :controller => 'files', :action => 'index' }, :caption => :label_file_plural, :param => :project_id
207 menu.push :files, { :controller => 'files', :action => 'index' }, :caption => :label_file_plural, :param => :project_id
208 menu.push :repository, { :controller => 'repositories', :action => 'show' },
208 menu.push :repository, { :controller => 'repositories', :action => 'show' },
209 :if => Proc.new { |p| p.repository && !p.repository.new_record? }
209 :if => Proc.new { |p| p.repository && !p.repository.new_record? }
210 menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true
210 menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true
211 end
211 end
212
212
213 Redmine::Activity.map do |activity|
213 Redmine::Activity.map do |activity|
214 activity.register :issues, :class_name => %w(Issue Journal)
214 activity.register :issues, :class_name => %w(Issue Journal)
215 activity.register :changesets
215 activity.register :changesets
216 activity.register :news
216 activity.register :news
217 activity.register :documents, :class_name => %w(Document Attachment)
217 activity.register :documents, :class_name => %w(Document Attachment)
218 activity.register :files, :class_name => 'Attachment'
218 activity.register :files, :class_name => 'Attachment'
219 activity.register :wiki_edits, :class_name => 'WikiContent::Version', :default => false
219 activity.register :wiki_edits, :class_name => 'WikiContent::Version', :default => false
220 activity.register :messages, :default => false
220 activity.register :messages, :default => false
221 activity.register :time_entries, :default => false
221 activity.register :time_entries, :default => false
222 end
222 end
223
223
224 Redmine::Search.map do |search|
224 Redmine::Search.map do |search|
225 search.register :issues
225 search.register :issues
226 search.register :news
226 search.register :news
227 search.register :documents
227 search.register :documents
228 search.register :changesets
228 search.register :changesets
229 search.register :wiki_pages
229 search.register :wiki_pages
230 search.register :messages
230 search.register :messages
231 search.register :projects
231 search.register :projects
232 end
232 end
233
233
234 Redmine::WikiFormatting.map do |format|
234 Redmine::WikiFormatting.map do |format|
235 format.register :textile, Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting::Textile::Helper
235 format.register :textile, Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting::Textile::Helper
236 end
236 end
237
237
238 ActionView::Template.register_template_handler :rsb, Redmine::Views::ApiTemplateHandler
238 ActionView::Template.register_template_handler :rsb, Redmine::Views::ApiTemplateHandler
@@ -1,110 +1,110
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19 require 'members_controller'
19 require 'members_controller'
20
20
21 # Re-raise errors caught by the controller.
21 # Re-raise errors caught by the controller.
22 class MembersController; def rescue_action(e) raise e end; end
22 class MembersController; def rescue_action(e) raise e end; end
23
23
24
24
25 class MembersControllerTest < ActionController::TestCase
25 class MembersControllerTest < ActionController::TestCase
26 fixtures :projects, :members, :member_roles, :roles, :users
26 fixtures :projects, :members, :member_roles, :roles, :users
27
27
28 def setup
28 def setup
29 @controller = MembersController.new
29 @controller = MembersController.new
30 @request = ActionController::TestRequest.new
30 @request = ActionController::TestRequest.new
31 @response = ActionController::TestResponse.new
31 @response = ActionController::TestResponse.new
32 User.current = nil
32 User.current = nil
33 @request.session[:user_id] = 2
33 @request.session[:user_id] = 2
34 end
34 end
35
35
36 def test_create
36 def test_create
37 assert_difference 'Member.count' do
37 assert_difference 'Member.count' do
38 post :new, :id => 1, :member => {:role_ids => [1], :user_id => 7}
38 post :create, :project_id => 1, :membership => {:role_ids => [1], :user_id => 7}
39 end
39 end
40 assert_redirected_to '/projects/ecookbook/settings/members'
40 assert_redirected_to '/projects/ecookbook/settings/members'
41 assert User.find(7).member_of?(Project.find(1))
41 assert User.find(7).member_of?(Project.find(1))
42 end
42 end
43
43
44 def test_create_multiple
44 def test_create_multiple
45 assert_difference 'Member.count', 3 do
45 assert_difference 'Member.count', 3 do
46 post :new, :id => 1, :member => {:role_ids => [1], :user_ids => [7, 8, 9]}
46 post :create, :project_id => 1, :membership => {:role_ids => [1], :user_ids => [7, 8, 9]}
47 end
47 end
48 assert_redirected_to '/projects/ecookbook/settings/members'
48 assert_redirected_to '/projects/ecookbook/settings/members'
49 assert User.find(7).member_of?(Project.find(1))
49 assert User.find(7).member_of?(Project.find(1))
50 end
50 end
51
51
52 def test_xhr_create
52 def test_xhr_create
53 assert_difference 'Member.count', 3 do
53 assert_difference 'Member.count', 3 do
54 post :new, :format => "js", :id => 1, :member => {:role_ids => [1], :user_ids => [7, 8, 9]}
54 post :create, :project_id => 1, :membership => {:role_ids => [1], :user_ids => [7, 8, 9]}, :format => "js"
55 end
55 end
56 assert_select_rjs :replace_html, 'tab-content-members'
56 assert_select_rjs :replace_html, 'tab-content-members'
57 assert User.find(7).member_of?(Project.find(1))
57 assert User.find(7).member_of?(Project.find(1))
58 assert User.find(8).member_of?(Project.find(1))
58 assert User.find(8).member_of?(Project.find(1))
59 assert User.find(9).member_of?(Project.find(1))
59 assert User.find(9).member_of?(Project.find(1))
60 end
60 end
61
61
62 def test_xhr_create_with_failure
62 def test_xhr_create_with_failure
63 assert_no_difference 'Member.count' do
63 assert_no_difference 'Member.count' do
64 post :new, :format => "js", :id => 1, :member => {:role_ids => [], :user_ids => [7, 8, 9]}
64 post :create, :project_id => 1, :membership => {:role_ids => [], :user_ids => [7, 8, 9]}, :format => "js"
65 end
65 end
66 assert_select '#tab-content-members', 0
66 assert_select '#tab-content-members', 0
67 assert @response.body.match(/alert/i), "Alert message not sent"
67 assert @response.body.match(/alert/i), "Alert message not sent"
68 end
68 end
69
69
70 def test_edit
70 def test_edit
71 assert_no_difference 'Member.count' do
71 assert_no_difference 'Member.count' do
72 post :edit, :id => 2, :member => {:role_ids => [1], :user_id => 3}
72 put :update, :id => 2, :membership => {:role_ids => [1], :user_id => 3}
73 end
73 end
74 assert_redirected_to '/projects/ecookbook/settings/members'
74 assert_redirected_to '/projects/ecookbook/settings/members'
75 end
75 end
76
76
77 def test_xhr_edit
77 def test_xhr_edit
78 assert_no_difference 'Member.count' do
78 assert_no_difference 'Member.count' do
79 xhr :post, :edit, :id => 2, :member => {:role_ids => [1], :user_id => 3}
79 xhr :put, :update, :id => 2, :membership => {:role_ids => [1], :user_id => 3}
80 end
80 end
81 assert_select_rjs :replace_html, 'tab-content-members'
81 assert_select_rjs :replace_html, 'tab-content-members'
82 member = Member.find(2)
82 member = Member.find(2)
83 assert_equal [1], member.role_ids
83 assert_equal [1], member.role_ids
84 assert_equal 3, member.user_id
84 assert_equal 3, member.user_id
85 end
85 end
86
86
87 def test_destroy
87 def test_destroy
88 assert_difference 'Member.count', -1 do
88 assert_difference 'Member.count', -1 do
89 post :destroy, :id => 2
89 delete :destroy, :id => 2
90 end
90 end
91 assert_redirected_to '/projects/ecookbook/settings/members'
91 assert_redirected_to '/projects/ecookbook/settings/members'
92 assert !User.find(3).member_of?(Project.find(1))
92 assert !User.find(3).member_of?(Project.find(1))
93 end
93 end
94
94
95 def test_xhr_destroy
95 def test_xhr_destroy
96 assert_difference 'Member.count', -1 do
96 assert_difference 'Member.count', -1 do
97 xhr :post, :destroy, :id => 2
97 xhr :delete, :destroy, :id => 2
98 end
98 end
99 assert_select_rjs :replace_html, 'tab-content-members'
99 assert_select_rjs :replace_html, 'tab-content-members'
100 end
100 end
101
101
102 def test_autocomplete_for_member
102 def test_autocomplete
103 get :autocomplete_for_member, :id => 1, :q => 'mis'
103 get :autocomplete, :project_id => 1, :q => 'mis'
104 assert_response :success
104 assert_response :success
105 assert_template 'autocomplete_for_member'
105 assert_template 'autocomplete'
106
106
107 assert_tag :label, :content => /User Misc/,
107 assert_tag :label, :content => /User Misc/,
108 :child => { :tag => 'input', :attributes => { :name => 'member[user_ids][]', :value => '8' } }
108 :child => { :tag => 'input', :attributes => { :name => 'membership[user_ids][]', :value => '8' } }
109 end
109 end
110 end
110 end
@@ -1,39 +1,39
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../../test_helper', __FILE__)
18 require File.expand_path('../../../test_helper', __FILE__)
19
19
20 class RoutingMembersTest < ActionController::IntegrationTest
20 class RoutingMembersTest < ActionController::IntegrationTest
21 def test_members
21 def test_members
22 assert_routing(
22 assert_routing(
23 { :method => 'post', :path => "/projects/5234/members/new" },
23 { :method => 'post', :path => "/projects/5234/memberships" },
24 { :controller => 'members', :action => 'new', :id => '5234' }
24 { :controller => 'members', :action => 'create', :project_id => '5234' }
25 )
25 )
26 assert_routing(
26 assert_routing(
27 { :method => 'post', :path => "/members/edit/5234" },
27 { :method => 'put', :path => "/memberships/5234" },
28 { :controller => 'members', :action => 'edit', :id => '5234' }
28 { :controller => 'members', :action => 'update', :id => '5234' }
29 )
29 )
30 assert_routing(
30 assert_routing(
31 { :method => 'post', :path => "/members/destroy/5234" },
31 { :method => 'delete', :path => "/memberships/5234" },
32 { :controller => 'members', :action => 'destroy', :id => '5234' }
32 { :controller => 'members', :action => 'destroy', :id => '5234' }
33 )
33 )
34 assert_routing(
34 assert_routing(
35 { :method => 'post', :path => "/members/autocomplete_for_member/5234" },
35 { :method => 'get', :path => "/projects/5234/memberships/autocomplete" },
36 { :controller => 'members', :action => 'autocomplete_for_member', :id => '5234' }
36 { :controller => 'members', :action => 'autocomplete', :project_id => '5234' }
37 )
37 )
38 end
38 end
39 end
39 end
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now