##// END OF EJS Templates
Merged r8130 from trunk....
Jean-Philippe Lang -
r8041:ff02412e7518
parent child
Show More
@@ -1,258 +1,258
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'
9 map.home '', :controller => 'welcome'
10
10
11 map.signin 'login', :controller => 'account', :action => 'login'
11 map.signin 'login', :controller => 'account', :action => 'login'
12 map.signout 'logout', :controller => 'account', :action => 'logout'
12 map.signout 'logout', :controller => 'account', :action => 'logout'
13
13
14 map.connect 'roles/workflow/:id/:role_id/:tracker_id', :controller => 'roles', :action => 'workflow'
14 map.connect 'roles/workflow/:id/:role_id/:tracker_id', :controller => 'roles', :action => 'workflow'
15 map.connect 'help/:ctrl/:page', :controller => 'help'
15 map.connect 'help/:ctrl/:page', :controller => 'help'
16
16
17 map.with_options :controller => 'time_entry_reports', :action => 'report',:conditions => {:method => :get} do |time_report|
17 map.with_options :controller => 'time_entry_reports', :action => 'report',:conditions => {:method => :get} do |time_report|
18 time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report'
18 time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report'
19 time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report.:format'
19 time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report.:format'
20 time_report.connect 'projects/:project_id/time_entries/report'
20 time_report.connect 'projects/:project_id/time_entries/report'
21 time_report.connect 'projects/:project_id/time_entries/report.:format'
21 time_report.connect 'projects/:project_id/time_entries/report.:format'
22 time_report.connect 'time_entries/report'
22 time_report.connect 'time_entries/report'
23 time_report.connect 'time_entries/report.:format'
23 time_report.connect 'time_entries/report.:format'
24 end
24 end
25
25
26 map.bulk_edit_time_entry 'time_entries/bulk_edit',
26 map.bulk_edit_time_entry 'time_entries/bulk_edit',
27 :controller => 'timelog', :action => 'bulk_edit', :conditions => { :method => :get }
27 :controller => 'timelog', :action => 'bulk_edit', :conditions => { :method => :get }
28 map.bulk_update_time_entry 'time_entries/bulk_edit',
28 map.bulk_update_time_entry 'time_entries/bulk_edit',
29 :controller => 'timelog', :action => 'bulk_update', :conditions => { :method => :post }
29 :controller => 'timelog', :action => 'bulk_update', :conditions => { :method => :post }
30 map.time_entries_context_menu '/time_entries/context_menu',
30 map.time_entries_context_menu '/time_entries/context_menu',
31 :controller => 'context_menus', :action => 'time_entries'
31 :controller => 'context_menus', :action => 'time_entries'
32 # TODO: wasteful since this is also nested under issues, projects, and projects/issues
32 # TODO: wasteful since this is also nested under issues, projects, and projects/issues
33 map.resources :time_entries, :controller => 'timelog'
33 map.resources :time_entries, :controller => 'timelog'
34
34
35 map.connect 'projects/:id/wiki', :controller => 'wikis', :action => 'edit', :conditions => {:method => :post}
35 map.connect 'projects/:id/wiki', :controller => 'wikis', :action => 'edit', :conditions => {:method => :post}
36 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :get}
36 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :get}
37 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :post}
37 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :post}
38
38
39 map.with_options :controller => 'messages' do |messages_routes|
39 map.with_options :controller => 'messages' do |messages_routes|
40 messages_routes.with_options :conditions => {:method => :get} do |messages_views|
40 messages_routes.with_options :conditions => {:method => :get} do |messages_views|
41 messages_views.connect 'boards/:board_id/topics/new', :action => 'new'
41 messages_views.connect 'boards/:board_id/topics/new', :action => 'new'
42 messages_views.connect 'boards/:board_id/topics/:id', :action => 'show'
42 messages_views.connect 'boards/:board_id/topics/:id', :action => 'show'
43 messages_views.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
43 messages_views.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
44 end
44 end
45 messages_routes.with_options :conditions => {:method => :post} do |messages_actions|
45 messages_routes.with_options :conditions => {:method => :post} do |messages_actions|
46 messages_actions.connect 'boards/:board_id/topics/new', :action => 'new'
46 messages_actions.connect 'boards/:board_id/topics/new', :action => 'new'
47 messages_actions.connect 'boards/:board_id/topics/:id/replies', :action => 'reply'
47 messages_actions.connect 'boards/:board_id/topics/:id/replies', :action => 'reply'
48 messages_actions.connect 'boards/:board_id/topics/:id/:action', :action => /edit|destroy/
48 messages_actions.connect 'boards/:board_id/topics/:id/:action', :action => /edit|destroy/
49 end
49 end
50 end
50 end
51
51
52 map.with_options :controller => 'boards' do |board_routes|
52 map.with_options :controller => 'boards' do |board_routes|
53 board_routes.with_options :conditions => {:method => :get} do |board_views|
53 board_routes.with_options :conditions => {:method => :get} do |board_views|
54 board_views.connect 'projects/:project_id/boards', :action => 'index'
54 board_views.connect 'projects/:project_id/boards', :action => 'index'
55 board_views.connect 'projects/:project_id/boards/new', :action => 'new'
55 board_views.connect 'projects/:project_id/boards/new', :action => 'new'
56 board_views.connect 'projects/:project_id/boards/:id', :action => 'show'
56 board_views.connect 'projects/:project_id/boards/:id', :action => 'show'
57 board_views.connect 'projects/:project_id/boards/:id.:format', :action => 'show'
57 board_views.connect 'projects/:project_id/boards/:id.:format', :action => 'show'
58 board_views.connect 'projects/:project_id/boards/:id/edit', :action => 'edit'
58 board_views.connect 'projects/:project_id/boards/:id/edit', :action => 'edit'
59 end
59 end
60 board_routes.with_options :conditions => {:method => :post} do |board_actions|
60 board_routes.with_options :conditions => {:method => :post} do |board_actions|
61 board_actions.connect 'projects/:project_id/boards', :action => 'new'
61 board_actions.connect 'projects/:project_id/boards', :action => 'new'
62 board_actions.connect 'projects/:project_id/boards/:id/:action', :action => /edit|destroy/
62 board_actions.connect 'projects/:project_id/boards/:id/:action', :action => /edit|destroy/
63 end
63 end
64 end
64 end
65
65
66 map.with_options :controller => 'documents' do |document_routes|
66 map.with_options :controller => 'documents' do |document_routes|
67 document_routes.with_options :conditions => {:method => :get} do |document_views|
67 document_routes.with_options :conditions => {:method => :get} do |document_views|
68 document_views.connect 'projects/:project_id/documents', :action => 'index'
68 document_views.connect 'projects/:project_id/documents', :action => 'index'
69 document_views.connect 'projects/:project_id/documents/new', :action => 'new'
69 document_views.connect 'projects/:project_id/documents/new', :action => 'new'
70 document_views.connect 'documents/:id', :action => 'show'
70 document_views.connect 'documents/:id', :action => 'show'
71 document_views.connect 'documents/:id/edit', :action => 'edit'
71 document_views.connect 'documents/:id/edit', :action => 'edit'
72 end
72 end
73 document_routes.with_options :conditions => {:method => :post} do |document_actions|
73 document_routes.with_options :conditions => {:method => :post} do |document_actions|
74 document_actions.connect 'projects/:project_id/documents', :action => 'new'
74 document_actions.connect 'projects/:project_id/documents', :action => 'new'
75 document_actions.connect 'documents/:id/:action', :action => /destroy|edit/
75 document_actions.connect 'documents/:id/:action', :action => /destroy|edit/
76 end
76 end
77 end
77 end
78
78
79 map.resources :issue_moves, :only => [:new, :create], :path_prefix => '/issues', :as => 'move'
79 map.resources :issue_moves, :only => [:new, :create], :path_prefix => '/issues', :as => 'move'
80 map.resources :queries, :except => [:show]
80 map.resources :queries, :except => [:show]
81
81
82 # Misc issue routes. TODO: move into resources
82 # Misc issue routes. TODO: move into resources
83 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues'
83 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues', :conditions => { :method => :get }
84 map.preview_issue '/issues/preview/:id', :controller => 'previews', :action => 'issue' # TODO: would look nicer as /issues/:id/preview
84 map.preview_issue '/issues/preview/:id', :controller => 'previews', :action => 'issue' # TODO: would look nicer as /issues/:id/preview
85 map.issues_context_menu '/issues/context_menu', :controller => 'context_menus', :action => 'issues'
85 map.issues_context_menu '/issues/context_menu', :controller => 'context_menus', :action => 'issues'
86 map.issue_changes '/issues/changes', :controller => 'journals', :action => 'index'
86 map.issue_changes '/issues/changes', :controller => 'journals', :action => 'index'
87 map.bulk_edit_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_edit', :conditions => { :method => :get }
87 map.bulk_edit_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_edit', :conditions => { :method => :get }
88 map.bulk_update_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_update', :conditions => { :method => :post }
88 map.bulk_update_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_update', :conditions => { :method => :post }
89 map.quoted_issue '/issues/:id/quoted', :controller => 'journals', :action => 'new', :id => /\d+/, :conditions => { :method => :post }
89 map.quoted_issue '/issues/:id/quoted', :controller => 'journals', :action => 'new', :id => /\d+/, :conditions => { :method => :post }
90 map.connect '/issues/:id/destroy', :controller => 'issues', :action => 'destroy', :conditions => { :method => :post } # legacy
90 map.connect '/issues/:id/destroy', :controller => 'issues', :action => 'destroy', :conditions => { :method => :post } # legacy
91
91
92 map.with_options :controller => 'gantts', :action => 'show' do |gantts_routes|
92 map.with_options :controller => 'gantts', :action => 'show' do |gantts_routes|
93 gantts_routes.connect '/projects/:project_id/issues/gantt'
93 gantts_routes.connect '/projects/:project_id/issues/gantt'
94 gantts_routes.connect '/projects/:project_id/issues/gantt.:format'
94 gantts_routes.connect '/projects/:project_id/issues/gantt.:format'
95 gantts_routes.connect '/issues/gantt.:format'
95 gantts_routes.connect '/issues/gantt.:format'
96 end
96 end
97
97
98 map.with_options :controller => 'calendars', :action => 'show' do |calendars_routes|
98 map.with_options :controller => 'calendars', :action => 'show' do |calendars_routes|
99 calendars_routes.connect '/projects/:project_id/issues/calendar'
99 calendars_routes.connect '/projects/:project_id/issues/calendar'
100 calendars_routes.connect '/issues/calendar'
100 calendars_routes.connect '/issues/calendar'
101 end
101 end
102
102
103 map.with_options :controller => 'reports', :conditions => {:method => :get} do |reports|
103 map.with_options :controller => 'reports', :conditions => {:method => :get} do |reports|
104 reports.connect 'projects/:id/issues/report', :action => 'issue_report'
104 reports.connect 'projects/:id/issues/report', :action => 'issue_report'
105 reports.connect 'projects/:id/issues/report/:detail', :action => 'issue_report_details'
105 reports.connect 'projects/:id/issues/report/:detail', :action => 'issue_report_details'
106 end
106 end
107
107
108 # Following two routes conflict with the resources because #index allows POST
108 # Following two routes conflict with the resources because #index allows POST
109 map.connect '/issues', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
109 map.connect '/issues', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
110 map.connect '/issues/create', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
110 map.connect '/issues/create', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
111
111
112 map.resources :issues, :member => { :edit => :post }, :collection => {} do |issues|
112 map.resources :issues, :member => { :edit => :post }, :collection => {} do |issues|
113 issues.resources :time_entries, :controller => 'timelog'
113 issues.resources :time_entries, :controller => 'timelog'
114 issues.resources :relations, :shallow => true, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
114 issues.resources :relations, :shallow => true, :controller => 'issue_relations', :only => [:index, :show, :create, :destroy]
115 end
115 end
116
116
117 map.resources :issues, :path_prefix => '/projects/:project_id', :collection => { :create => :post } do |issues|
117 map.resources :issues, :path_prefix => '/projects/:project_id', :collection => { :create => :post } do |issues|
118 issues.resources :time_entries, :controller => 'timelog'
118 issues.resources :time_entries, :controller => 'timelog'
119 end
119 end
120
120
121 map.connect 'projects/:id/members/new', :controller => 'members', :action => 'new'
121 map.connect 'projects/:id/members/new', :controller => 'members', :action => 'new'
122
122
123 map.with_options :controller => 'users' do |users|
123 map.with_options :controller => 'users' do |users|
124 users.connect 'users/:id/edit/:tab', :action => 'edit', :tab => nil, :conditions => {:method => :get}
124 users.connect 'users/:id/edit/:tab', :action => 'edit', :tab => nil, :conditions => {:method => :get}
125
125
126 users.with_options :conditions => {:method => :post} do |user_actions|
126 users.with_options :conditions => {:method => :post} do |user_actions|
127 user_actions.connect 'users/:id/memberships', :action => 'edit_membership'
127 user_actions.connect 'users/:id/memberships', :action => 'edit_membership'
128 user_actions.connect 'users/:id/memberships/:membership_id', :action => 'edit_membership'
128 user_actions.connect 'users/:id/memberships/:membership_id', :action => 'edit_membership'
129 user_actions.connect 'users/:id/memberships/:membership_id/destroy', :action => 'destroy_membership'
129 user_actions.connect 'users/:id/memberships/:membership_id/destroy', :action => 'destroy_membership'
130 end
130 end
131 end
131 end
132
132
133 map.resources :users, :member => {
133 map.resources :users, :member => {
134 :edit_membership => :post,
134 :edit_membership => :post,
135 :destroy_membership => :post
135 :destroy_membership => :post
136 }
136 }
137
137
138 # For nice "roadmap" in the url for the index action
138 # For nice "roadmap" in the url for the index action
139 map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
139 map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
140
140
141 map.all_news 'news', :controller => 'news', :action => 'index'
141 map.all_news 'news', :controller => 'news', :action => 'index'
142 map.formatted_all_news 'news.:format', :controller => 'news', :action => 'index'
142 map.formatted_all_news 'news.:format', :controller => 'news', :action => 'index'
143 map.preview_news '/news/preview', :controller => 'previews', :action => 'news'
143 map.preview_news '/news/preview', :controller => 'previews', :action => 'news'
144 map.connect 'news/:id/comments', :controller => 'comments', :action => 'create', :conditions => {:method => :post}
144 map.connect 'news/:id/comments', :controller => 'comments', :action => 'create', :conditions => {:method => :post}
145 map.connect 'news/:id/comments/:comment_id', :controller => 'comments', :action => 'destroy', :conditions => {:method => :delete}
145 map.connect 'news/:id/comments/:comment_id', :controller => 'comments', :action => 'destroy', :conditions => {:method => :delete}
146
146
147 map.resources :projects, :member => {
147 map.resources :projects, :member => {
148 :copy => [:get, :post],
148 :copy => [:get, :post],
149 :settings => :get,
149 :settings => :get,
150 :modules => :post,
150 :modules => :post,
151 :archive => :post,
151 :archive => :post,
152 :unarchive => :post
152 :unarchive => :post
153 } do |project|
153 } do |project|
154 project.resource :project_enumerations, :as => 'enumerations', :only => [:update, :destroy]
154 project.resource :project_enumerations, :as => 'enumerations', :only => [:update, :destroy]
155 project.resources :files, :only => [:index, :new, :create]
155 project.resources :files, :only => [:index, :new, :create]
156 project.resources :versions, :shallow => true, :collection => {:close_completed => :put}, :member => {:status_by => :post}
156 project.resources :versions, :shallow => true, :collection => {:close_completed => :put}, :member => {:status_by => :post}
157 project.resources :news, :shallow => true
157 project.resources :news, :shallow => true
158 project.resources :time_entries, :controller => 'timelog', :path_prefix => 'projects/:project_id'
158 project.resources :time_entries, :controller => 'timelog', :path_prefix => 'projects/:project_id'
159 project.resources :queries, :only => [:new, :create]
159 project.resources :queries, :only => [:new, :create]
160 project.resources :issue_categories, :shallow => true
160 project.resources :issue_categories, :shallow => true
161
161
162 project.wiki_start_page 'wiki', :controller => 'wiki', :action => 'show', :conditions => {:method => :get}
162 project.wiki_start_page 'wiki', :controller => 'wiki', :action => 'show', :conditions => {:method => :get}
163 project.wiki_index 'wiki/index', :controller => 'wiki', :action => 'index', :conditions => {:method => :get}
163 project.wiki_index 'wiki/index', :controller => 'wiki', :action => 'index', :conditions => {:method => :get}
164 project.wiki_diff 'wiki/:id/diff/:version', :controller => 'wiki', :action => 'diff', :version => nil
164 project.wiki_diff 'wiki/:id/diff/:version', :controller => 'wiki', :action => 'diff', :version => nil
165 project.wiki_diff 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff'
165 project.wiki_diff 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff'
166 project.wiki_annotate 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate'
166 project.wiki_annotate 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate'
167 project.resources :wiki, :except => [:new, :create], :member => {
167 project.resources :wiki, :except => [:new, :create], :member => {
168 :rename => [:get, :post],
168 :rename => [:get, :post],
169 :history => :get,
169 :history => :get,
170 :preview => :any,
170 :preview => :any,
171 :protect => :post,
171 :protect => :post,
172 :add_attachment => :post
172 :add_attachment => :post
173 }, :collection => {
173 }, :collection => {
174 :export => :get,
174 :export => :get,
175 :date_index => :get
175 :date_index => :get
176 }
176 }
177
177
178 end
178 end
179
179
180 # Destroy uses a get request to prompt the user before the actual DELETE request
180 # Destroy uses a get request to prompt the user before the actual DELETE request
181 map.project_destroy_confirm 'projects/:id/destroy', :controller => 'projects', :action => 'destroy', :conditions => {:method => :get}
181 map.project_destroy_confirm 'projects/:id/destroy', :controller => 'projects', :action => 'destroy', :conditions => {:method => :get}
182
182
183 # TODO: port to be part of the resources route(s)
183 # TODO: port to be part of the resources route(s)
184 map.with_options :controller => 'projects' do |project_mapper|
184 map.with_options :controller => 'projects' do |project_mapper|
185 project_mapper.with_options :conditions => {:method => :get} do |project_views|
185 project_mapper.with_options :conditions => {:method => :get} do |project_views|
186 project_views.connect 'projects/:id/settings/:tab', :controller => 'projects', :action => 'settings'
186 project_views.connect 'projects/:id/settings/:tab', :controller => 'projects', :action => 'settings'
187 project_views.connect 'projects/:project_id/issues/:copy_from/copy', :controller => 'issues', :action => 'new'
187 project_views.connect 'projects/:project_id/issues/:copy_from/copy', :controller => 'issues', :action => 'new'
188 end
188 end
189 end
189 end
190
190
191 map.with_options :controller => 'activities', :action => 'index', :conditions => {:method => :get} do |activity|
191 map.with_options :controller => 'activities', :action => 'index', :conditions => {:method => :get} do |activity|
192 activity.connect 'projects/:id/activity'
192 activity.connect 'projects/:id/activity'
193 activity.connect 'projects/:id/activity.:format'
193 activity.connect 'projects/:id/activity.:format'
194 activity.connect 'activity', :id => nil
194 activity.connect 'activity', :id => nil
195 activity.connect 'activity.:format', :id => nil
195 activity.connect 'activity.:format', :id => nil
196 end
196 end
197
197
198 map.with_options :controller => 'repositories' do |repositories|
198 map.with_options :controller => 'repositories' do |repositories|
199 repositories.with_options :conditions => {:method => :get} do |repository_views|
199 repositories.with_options :conditions => {:method => :get} do |repository_views|
200 repository_views.connect 'projects/:id/repository', :action => 'show'
200 repository_views.connect 'projects/:id/repository', :action => 'show'
201 repository_views.connect 'projects/:id/repository/edit', :action => 'edit'
201 repository_views.connect 'projects/:id/repository/edit', :action => 'edit'
202 repository_views.connect 'projects/:id/repository/statistics', :action => 'stats'
202 repository_views.connect 'projects/:id/repository/statistics', :action => 'stats'
203 repository_views.connect 'projects/:id/repository/revisions', :action => 'revisions'
203 repository_views.connect 'projects/:id/repository/revisions', :action => 'revisions'
204 repository_views.connect 'projects/:id/repository/revisions.:format', :action => 'revisions'
204 repository_views.connect 'projects/:id/repository/revisions.:format', :action => 'revisions'
205 repository_views.connect 'projects/:id/repository/revisions/:rev', :action => 'revision'
205 repository_views.connect 'projects/:id/repository/revisions/:rev', :action => 'revision'
206 repository_views.connect 'projects/:id/repository/revisions/:rev/diff', :action => 'diff'
206 repository_views.connect 'projects/:id/repository/revisions/:rev/diff', :action => 'diff'
207 repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format', :action => 'diff'
207 repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format', :action => 'diff'
208 repository_views.connect 'projects/:id/repository/revisions/:rev/raw/*path', :action => 'entry', :format => 'raw', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
208 repository_views.connect 'projects/:id/repository/revisions/:rev/raw/*path', :action => 'entry', :format => 'raw', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
209 repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
209 repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
210 repository_views.connect 'projects/:id/repository/raw/*path', :action => 'entry', :format => 'raw'
210 repository_views.connect 'projects/:id/repository/raw/*path', :action => 'entry', :format => 'raw'
211 # TODO: why the following route is required?
211 # TODO: why the following route is required?
212 repository_views.connect 'projects/:id/repository/entry/*path', :action => 'entry'
212 repository_views.connect 'projects/:id/repository/entry/*path', :action => 'entry'
213 repository_views.connect 'projects/:id/repository/:action/*path'
213 repository_views.connect 'projects/:id/repository/:action/*path'
214 end
214 end
215
215
216 repositories.connect 'projects/:id/repository/:action', :conditions => {:method => :post}
216 repositories.connect 'projects/:id/repository/:action', :conditions => {:method => :post}
217 end
217 end
218
218
219 map.resources :attachments, :only => [:show, :destroy]
219 map.resources :attachments, :only => [:show, :destroy]
220 # additional routes for having the file name at the end of url
220 # additional routes for having the file name at the end of url
221 map.connect 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/
221 map.connect 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/
222 map.connect 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/
222 map.connect 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/
223
223
224 map.resources :groups, :member => {:autocomplete_for_user => :get}
224 map.resources :groups, :member => {:autocomplete_for_user => :get}
225 map.group_users 'groups/:id/users', :controller => 'groups', :action => 'add_users', :id => /\d+/, :conditions => {:method => :post}
225 map.group_users 'groups/:id/users', :controller => 'groups', :action => 'add_users', :id => /\d+/, :conditions => {:method => :post}
226 map.group_user 'groups/:id/users/:user_id', :controller => 'groups', :action => 'remove_user', :id => /\d+/, :conditions => {:method => :delete}
226 map.group_user 'groups/:id/users/:user_id', :controller => 'groups', :action => 'remove_user', :id => /\d+/, :conditions => {:method => :delete}
227
227
228 map.resources :trackers, :except => :show
228 map.resources :trackers, :except => :show
229 map.resources :issue_statuses, :except => :show, :collection => {:update_issue_done_ratio => :post}
229 map.resources :issue_statuses, :except => :show, :collection => {:update_issue_done_ratio => :post}
230
230
231 #left old routes at the bottom for backwards compat
231 #left old routes at the bottom for backwards compat
232 map.connect 'projects/:project_id/issues/:action', :controller => 'issues'
232 map.connect 'projects/:project_id/issues/:action', :controller => 'issues'
233 map.connect 'projects/:project_id/documents/:action', :controller => 'documents'
233 map.connect 'projects/:project_id/documents/:action', :controller => 'documents'
234 map.connect 'projects/:project_id/boards/:action/:id', :controller => 'boards'
234 map.connect 'projects/:project_id/boards/:action/:id', :controller => 'boards'
235 map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages'
235 map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages'
236 map.connect 'wiki/:id/:page/:action', :page => nil, :controller => 'wiki'
236 map.connect 'wiki/:id/:page/:action', :page => nil, :controller => 'wiki'
237 map.connect 'projects/:project_id/news/:action', :controller => 'news'
237 map.connect 'projects/:project_id/news/:action', :controller => 'news'
238 map.connect 'projects/:project_id/timelog/:action/:id', :controller => 'timelog', :project_id => /.+/
238 map.connect 'projects/:project_id/timelog/:action/:id', :controller => 'timelog', :project_id => /.+/
239 map.with_options :controller => 'repositories' do |omap|
239 map.with_options :controller => 'repositories' do |omap|
240 omap.repositories_show 'repositories/browse/:id/*path', :action => 'browse'
240 omap.repositories_show 'repositories/browse/:id/*path', :action => 'browse'
241 omap.repositories_changes 'repositories/changes/:id/*path', :action => 'changes'
241 omap.repositories_changes 'repositories/changes/:id/*path', :action => 'changes'
242 omap.repositories_diff 'repositories/diff/:id/*path', :action => 'diff'
242 omap.repositories_diff 'repositories/diff/:id/*path', :action => 'diff'
243 omap.repositories_entry 'repositories/entry/:id/*path', :action => 'entry'
243 omap.repositories_entry 'repositories/entry/:id/*path', :action => 'entry'
244 omap.repositories_entry 'repositories/annotate/:id/*path', :action => 'annotate'
244 omap.repositories_entry 'repositories/annotate/:id/*path', :action => 'annotate'
245 omap.connect 'repositories/revision/:id/:rev', :action => 'revision'
245 omap.connect 'repositories/revision/:id/:rev', :action => 'revision'
246 end
246 end
247
247
248 map.with_options :controller => 'sys' do |sys|
248 map.with_options :controller => 'sys' do |sys|
249 sys.connect 'sys/projects.:format', :action => 'projects', :conditions => {:method => :get}
249 sys.connect 'sys/projects.:format', :action => 'projects', :conditions => {:method => :get}
250 sys.connect 'sys/projects/:id/repository.:format', :action => 'create_project_repository', :conditions => {:method => :post}
250 sys.connect 'sys/projects/:id/repository.:format', :action => 'create_project_repository', :conditions => {:method => :post}
251 end
251 end
252
252
253 # Install the default route as the lowest priority.
253 # Install the default route as the lowest priority.
254 map.connect ':controller/:action/:id'
254 map.connect ':controller/:action/:id'
255 map.connect 'robots.txt', :controller => 'welcome', :action => 'robots'
255 map.connect 'robots.txt', :controller => 'welcome', :action => 'robots'
256 # Used for OpenID
256 # Used for OpenID
257 map.root :controller => 'account', :action => 'login'
257 map.root :controller => 'account', :action => 'login'
258 end
258 end
@@ -1,415 +1,417
1 /* redMine - project management software
1 /* redMine - project management software
2 Copyright (C) 2006-2008 Jean-Philippe Lang */
2 Copyright (C) 2006-2008 Jean-Philippe Lang */
3
3
4 function checkAll (id, checked) {
4 function checkAll (id, checked) {
5 var els = Element.descendants(id);
5 var els = Element.descendants(id);
6 for (var i = 0; i < els.length; i++) {
6 for (var i = 0; i < els.length; i++) {
7 if (els[i].disabled==false) {
7 if (els[i].disabled==false) {
8 els[i].checked = checked;
8 els[i].checked = checked;
9 }
9 }
10 }
10 }
11 }
11 }
12
12
13 function toggleCheckboxesBySelector(selector) {
13 function toggleCheckboxesBySelector(selector) {
14 boxes = $$(selector);
14 boxes = $$(selector);
15 var all_checked = true;
15 var all_checked = true;
16 for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } }
16 for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } }
17 for (i = 0; i < boxes.length; i++) { boxes[i].checked = !all_checked; }
17 for (i = 0; i < boxes.length; i++) { boxes[i].checked = !all_checked; }
18 }
18 }
19
19
20 function setCheckboxesBySelector(checked, selector) {
20 function setCheckboxesBySelector(checked, selector) {
21 var boxes = $$(selector);
21 var boxes = $$(selector);
22 boxes.each(function(ele) {
22 boxes.each(function(ele) {
23 ele.checked = checked;
23 ele.checked = checked;
24 });
24 });
25 }
25 }
26
26
27 function showAndScrollTo(id, focus) {
27 function showAndScrollTo(id, focus) {
28 Element.show(id);
28 Element.show(id);
29 if (focus!=null) { Form.Element.focus(focus); }
29 if (focus!=null) { Form.Element.focus(focus); }
30 Element.scrollTo(id);
30 Element.scrollTo(id);
31 }
31 }
32
32
33 function toggleRowGroup(el) {
33 function toggleRowGroup(el) {
34 var tr = Element.up(el, 'tr');
34 var tr = Element.up(el, 'tr');
35 var n = Element.next(tr);
35 var n = Element.next(tr);
36 tr.toggleClassName('open');
36 tr.toggleClassName('open');
37 while (n != undefined && !n.hasClassName('group')) {
37 while (n != undefined && !n.hasClassName('group')) {
38 Element.toggle(n);
38 Element.toggle(n);
39 n = Element.next(n);
39 n = Element.next(n);
40 }
40 }
41 }
41 }
42
42
43 function collapseAllRowGroups(el) {
43 function collapseAllRowGroups(el) {
44 var tbody = Element.up(el, 'tbody');
44 var tbody = Element.up(el, 'tbody');
45 tbody.childElements('tr').each(function(tr) {
45 tbody.childElements('tr').each(function(tr) {
46 if (tr.hasClassName('group')) {
46 if (tr.hasClassName('group')) {
47 tr.removeClassName('open');
47 tr.removeClassName('open');
48 } else {
48 } else {
49 tr.hide();
49 tr.hide();
50 }
50 }
51 })
51 })
52 }
52 }
53
53
54 function expandAllRowGroups(el) {
54 function expandAllRowGroups(el) {
55 var tbody = Element.up(el, 'tbody');
55 var tbody = Element.up(el, 'tbody');
56 tbody.childElements('tr').each(function(tr) {
56 tbody.childElements('tr').each(function(tr) {
57 if (tr.hasClassName('group')) {
57 if (tr.hasClassName('group')) {
58 tr.addClassName('open');
58 tr.addClassName('open');
59 } else {
59 } else {
60 tr.show();
60 tr.show();
61 }
61 }
62 })
62 })
63 }
63 }
64
64
65 function toggleAllRowGroups(el) {
65 function toggleAllRowGroups(el) {
66 var tr = Element.up(el, 'tr');
66 var tr = Element.up(el, 'tr');
67 if (tr.hasClassName('open')) {
67 if (tr.hasClassName('open')) {
68 collapseAllRowGroups(el);
68 collapseAllRowGroups(el);
69 } else {
69 } else {
70 expandAllRowGroups(el);
70 expandAllRowGroups(el);
71 }
71 }
72 }
72 }
73
73
74 function toggleFieldset(el) {
74 function toggleFieldset(el) {
75 var fieldset = Element.up(el, 'fieldset');
75 var fieldset = Element.up(el, 'fieldset');
76 fieldset.toggleClassName('collapsed');
76 fieldset.toggleClassName('collapsed');
77 Effect.toggle(fieldset.down('div'), 'slide', {duration:0.2});
77 Effect.toggle(fieldset.down('div'), 'slide', {duration:0.2});
78 }
78 }
79
79
80 function hideFieldset(el) {
80 function hideFieldset(el) {
81 var fieldset = Element.up(el, 'fieldset');
81 var fieldset = Element.up(el, 'fieldset');
82 fieldset.toggleClassName('collapsed');
82 fieldset.toggleClassName('collapsed');
83 fieldset.down('div').hide();
83 fieldset.down('div').hide();
84 }
84 }
85
85
86 var fileFieldCount = 1;
86 var fileFieldCount = 1;
87
87
88 function addFileField() {
88 function addFileField() {
89 var fields = $('attachments_fields');
89 var fields = $('attachments_fields');
90 if (fields.childElements().length >= 10) return false;
90 if (fields.childElements().length >= 10) return false;
91 fileFieldCount++;
91 fileFieldCount++;
92 var s = document.createElement("span");
92 var s = document.createElement("span");
93 s.update(fields.down('span').innerHTML);
93 s.update(fields.down('span').innerHTML);
94 s.down('input.file').name = "attachments[" + fileFieldCount + "][file]";
94 s.down('input.file').name = "attachments[" + fileFieldCount + "][file]";
95 s.down('input.description').name = "attachments[" + fileFieldCount + "][description]";
95 s.down('input.description').name = "attachments[" + fileFieldCount + "][description]";
96 fields.appendChild(s);
96 fields.appendChild(s);
97 }
97 }
98
98
99 function removeFileField(el) {
99 function removeFileField(el) {
100 var fields = $('attachments_fields');
100 var fields = $('attachments_fields');
101 var s = Element.up(el, 'span');
101 var s = Element.up(el, 'span');
102 if (fields.childElements().length > 1) {
102 if (fields.childElements().length > 1) {
103 s.remove();
103 s.remove();
104 } else {
104 } else {
105 s.update(s.innerHTML);
105 s.update(s.innerHTML);
106 }
106 }
107 }
107 }
108
108
109 function checkFileSize(el, maxSize, message) {
109 function checkFileSize(el, maxSize, message) {
110 var files = el.files;
110 var files = el.files;
111 if (files) {
111 if (files) {
112 for (var i=0; i<files.length; i++) {
112 for (var i=0; i<files.length; i++) {
113 if (files[i].size > maxSize) {
113 if (files[i].size > maxSize) {
114 alert(message);
114 alert(message);
115 el.value = "";
115 el.value = "";
116 }
116 }
117 }
117 }
118 }
118 }
119 }
119 }
120
120
121 function showTab(name) {
121 function showTab(name) {
122 var f = $$('div#content .tab-content');
122 var f = $$('div#content .tab-content');
123 for(var i=0; i<f.length; i++){
123 for(var i=0; i<f.length; i++){
124 Element.hide(f[i]);
124 Element.hide(f[i]);
125 }
125 }
126 var f = $$('div.tabs a');
126 var f = $$('div.tabs a');
127 for(var i=0; i<f.length; i++){
127 for(var i=0; i<f.length; i++){
128 Element.removeClassName(f[i], "selected");
128 Element.removeClassName(f[i], "selected");
129 }
129 }
130 Element.show('tab-content-' + name);
130 Element.show('tab-content-' + name);
131 Element.addClassName('tab-' + name, "selected");
131 Element.addClassName('tab-' + name, "selected");
132 return false;
132 return false;
133 }
133 }
134
134
135 function moveTabRight(el) {
135 function moveTabRight(el) {
136 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
136 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
137 var tabsWidth = 0;
137 var tabsWidth = 0;
138 var i;
138 var i;
139 for (i=0; i<lis.length; i++) {
139 for (i=0; i<lis.length; i++) {
140 if (lis[i].visible()) {
140 if (lis[i].visible()) {
141 tabsWidth += lis[i].getWidth() + 6;
141 tabsWidth += lis[i].getWidth() + 6;
142 }
142 }
143 }
143 }
144 if (tabsWidth < Element.up(el, 'div.tabs').getWidth() - 60) {
144 if (tabsWidth < Element.up(el, 'div.tabs').getWidth() - 60) {
145 return;
145 return;
146 }
146 }
147 i=0;
147 i=0;
148 while (i<lis.length && !lis[i].visible()) {
148 while (i<lis.length && !lis[i].visible()) {
149 i++;
149 i++;
150 }
150 }
151 lis[i].hide();
151 lis[i].hide();
152 }
152 }
153
153
154 function moveTabLeft(el) {
154 function moveTabLeft(el) {
155 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
155 var lis = Element.up(el, 'div.tabs').down('ul').childElements();
156 var i = 0;
156 var i = 0;
157 while (i<lis.length && !lis[i].visible()) {
157 while (i<lis.length && !lis[i].visible()) {
158 i++;
158 i++;
159 }
159 }
160 if (i>0) {
160 if (i>0) {
161 lis[i-1].show();
161 lis[i-1].show();
162 }
162 }
163 }
163 }
164
164
165 function displayTabsButtons() {
165 function displayTabsButtons() {
166 var lis;
166 var lis;
167 var tabsWidth = 0;
167 var tabsWidth = 0;
168 var i;
168 var i;
169 $$('div.tabs').each(function(el) {
169 $$('div.tabs').each(function(el) {
170 lis = el.down('ul').childElements();
170 lis = el.down('ul').childElements();
171 for (i=0; i<lis.length; i++) {
171 for (i=0; i<lis.length; i++) {
172 if (lis[i].visible()) {
172 if (lis[i].visible()) {
173 tabsWidth += lis[i].getWidth() + 6;
173 tabsWidth += lis[i].getWidth() + 6;
174 }
174 }
175 }
175 }
176 if ((tabsWidth < el.getWidth() - 60) && (lis[0].visible())) {
176 if ((tabsWidth < el.getWidth() - 60) && (lis[0].visible())) {
177 el.down('div.tabs-buttons').hide();
177 el.down('div.tabs-buttons').hide();
178 } else {
178 } else {
179 el.down('div.tabs-buttons').show();
179 el.down('div.tabs-buttons').show();
180 }
180 }
181 });
181 });
182 }
182 }
183
183
184 function setPredecessorFieldsVisibility() {
184 function setPredecessorFieldsVisibility() {
185 relationType = $('relation_relation_type');
185 relationType = $('relation_relation_type');
186 if (relationType && (relationType.value == "precedes" || relationType.value == "follows")) {
186 if (relationType && (relationType.value == "precedes" || relationType.value == "follows")) {
187 Element.show('predecessor_fields');
187 Element.show('predecessor_fields');
188 } else {
188 } else {
189 Element.hide('predecessor_fields');
189 Element.hide('predecessor_fields');
190 }
190 }
191 }
191 }
192
192
193 function promptToRemote(text, param, url) {
193 function promptToRemote(text, param, url) {
194 value = prompt(text + ':');
194 value = prompt(text + ':');
195 if (value) {
195 if (value) {
196 new Ajax.Request(url + '?' + param + '=' + encodeURIComponent(value), {asynchronous:true, evalScripts:true});
196 new Ajax.Request(url + '?' + param + '=' + encodeURIComponent(value), {asynchronous:true, evalScripts:true});
197 return false;
197 return false;
198 }
198 }
199 }
199 }
200
200
201 function showModal(id, width) {
201 function showModal(id, width) {
202 el = $(id);
202 el = $(id);
203 if (el == undefined || el.visible()) {return;}
203 if (el == undefined || el.visible()) {return;}
204 var h = $$('body')[0].getHeight();
204 var h = $$('body')[0].getHeight();
205 var d = document.createElement("div");
205 var d = document.createElement("div");
206 d.id = 'modalbg';
206 d.id = 'modalbg';
207 $('main').appendChild(d);
207 $('main').appendChild(d);
208 $('modalbg').setStyle({ width: '100%', height: h + 'px' });
208 $('modalbg').setStyle({ width: '100%', height: h + 'px' });
209 $('modalbg').show();
209 $('modalbg').show();
210
210
211 var pageWidth = document.viewport.getWidth();
211 var pageWidth = document.viewport.getWidth();
212 el.setStyle({'width': width});
212 el.setStyle({'width': width});
213 el.setStyle({'left': (((pageWidth - el.getWidth())/2 *100) / pageWidth) + '%'});
213 el.setStyle({'left': (((pageWidth - el.getWidth())/2 *100) / pageWidth) + '%'});
214 el.addClassName('modal');
214 el.addClassName('modal');
215 el.show();
215 el.show();
216
216
217 var submit = el.down("input[type=submit]");
217 var submit = el.down("input[type=submit]");
218 if (submit) {
218 if (submit) {
219 submit.focus();
219 submit.focus();
220 }
220 }
221 }
221 }
222
222
223 function hideModal(el) {
223 function hideModal(el) {
224 var modal = Element.up(el, 'div.modal');
224 var modal = Element.up(el, 'div.modal');
225 if (modal) {
225 if (modal) {
226 modal.hide();
226 modal.hide();
227 }
227 }
228 var bg = $('modalbg');
228 var bg = $('modalbg');
229 if (bg) {
229 if (bg) {
230 bg.remove();
230 bg.remove();
231 }
231 }
232 }
232 }
233
233
234 function collapseScmEntry(id) {
234 function collapseScmEntry(id) {
235 var els = document.getElementsByClassName(id, 'browser');
235 var els = document.getElementsByClassName(id, 'browser');
236 for (var i = 0; i < els.length; i++) {
236 for (var i = 0; i < els.length; i++) {
237 if (els[i].hasClassName('open')) {
237 if (els[i].hasClassName('open')) {
238 collapseScmEntry(els[i].id);
238 collapseScmEntry(els[i].id);
239 }
239 }
240 Element.hide(els[i]);
240 Element.hide(els[i]);
241 }
241 }
242 $(id).removeClassName('open');
242 $(id).removeClassName('open');
243 }
243 }
244
244
245 function expandScmEntry(id) {
245 function expandScmEntry(id) {
246 var els = document.getElementsByClassName(id, 'browser');
246 var els = document.getElementsByClassName(id, 'browser');
247 for (var i = 0; i < els.length; i++) {
247 for (var i = 0; i < els.length; i++) {
248 Element.show(els[i]);
248 Element.show(els[i]);
249 if (els[i].hasClassName('loaded') && !els[i].hasClassName('collapsed')) {
249 if (els[i].hasClassName('loaded') && !els[i].hasClassName('collapsed')) {
250 expandScmEntry(els[i].id);
250 expandScmEntry(els[i].id);
251 }
251 }
252 }
252 }
253 $(id).addClassName('open');
253 $(id).addClassName('open');
254 }
254 }
255
255
256 function scmEntryClick(id) {
256 function scmEntryClick(id) {
257 el = $(id);
257 el = $(id);
258 if (el.hasClassName('open')) {
258 if (el.hasClassName('open')) {
259 collapseScmEntry(id);
259 collapseScmEntry(id);
260 el.addClassName('collapsed');
260 el.addClassName('collapsed');
261 return false;
261 return false;
262 } else if (el.hasClassName('loaded')) {
262 } else if (el.hasClassName('loaded')) {
263 expandScmEntry(id);
263 expandScmEntry(id);
264 el.removeClassName('collapsed');
264 el.removeClassName('collapsed');
265 return false;
265 return false;
266 }
266 }
267 if (el.hasClassName('loading')) {
267 if (el.hasClassName('loading')) {
268 return false;
268 return false;
269 }
269 }
270 el.addClassName('loading');
270 el.addClassName('loading');
271 return true;
271 return true;
272 }
272 }
273
273
274 function scmEntryLoaded(id) {
274 function scmEntryLoaded(id) {
275 Element.addClassName(id, 'open');
275 Element.addClassName(id, 'open');
276 Element.addClassName(id, 'loaded');
276 Element.addClassName(id, 'loaded');
277 Element.removeClassName(id, 'loading');
277 Element.removeClassName(id, 'loading');
278 }
278 }
279
279
280 function randomKey(size) {
280 function randomKey(size) {
281 var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
281 var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
282 var key = '';
282 var key = '';
283 for (i = 0; i < size; i++) {
283 for (i = 0; i < size; i++) {
284 key += chars[Math.floor(Math.random() * chars.length)];
284 key += chars[Math.floor(Math.random() * chars.length)];
285 }
285 }
286 return key;
286 return key;
287 }
287 }
288
288
289 function observeParentIssueField(url) {
289 function observeParentIssueField(url) {
290 new Ajax.Autocompleter('issue_parent_issue_id',
290 new Ajax.Autocompleter('issue_parent_issue_id',
291 'parent_issue_candidates',
291 'parent_issue_candidates',
292 url,
292 url,
293 { minChars: 3,
293 { minChars: 3,
294 frequency: 0.5,
294 frequency: 0.5,
295 paramName: 'q',
295 paramName: 'q',
296 method: 'get',
296 updateElement: function(value) {
297 updateElement: function(value) {
297 document.getElementById('issue_parent_issue_id').value = value.id;
298 document.getElementById('issue_parent_issue_id').value = value.id;
298 }});
299 }});
299 }
300 }
300
301
301 function observeRelatedIssueField(url) {
302 function observeRelatedIssueField(url) {
302 new Ajax.Autocompleter('relation_issue_to_id',
303 new Ajax.Autocompleter('relation_issue_to_id',
303 'related_issue_candidates',
304 'related_issue_candidates',
304 url,
305 url,
305 { minChars: 3,
306 { minChars: 3,
306 frequency: 0.5,
307 frequency: 0.5,
307 paramName: 'q',
308 paramName: 'q',
309 method: 'get',
308 updateElement: function(value) {
310 updateElement: function(value) {
309 document.getElementById('relation_issue_to_id').value = value.id;
311 document.getElementById('relation_issue_to_id').value = value.id;
310 },
312 },
311 parameters: 'scope=all'
313 parameters: 'scope=all'
312 });
314 });
313 }
315 }
314
316
315 function setVisible(id, visible) {
317 function setVisible(id, visible) {
316 var el = $(id);
318 var el = $(id);
317 if (el) {if (visible) {el.show();} else {el.hide();}}
319 if (el) {if (visible) {el.show();} else {el.hide();}}
318 }
320 }
319
321
320 function observeProjectModules() {
322 function observeProjectModules() {
321 var f = function() {
323 var f = function() {
322 /* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */
324 /* Hides trackers and issues custom fields on the new project form when issue_tracking module is disabled */
323 var c = ($('project_enabled_module_names_issue_tracking').checked == true);
325 var c = ($('project_enabled_module_names_issue_tracking').checked == true);
324 setVisible('project_trackers', c);
326 setVisible('project_trackers', c);
325 setVisible('project_issue_custom_fields', c);
327 setVisible('project_issue_custom_fields', c);
326 };
328 };
327
329
328 Event.observe(window, 'load', f);
330 Event.observe(window, 'load', f);
329 Event.observe('project_enabled_module_names_issue_tracking', 'change', f);
331 Event.observe('project_enabled_module_names_issue_tracking', 'change', f);
330 }
332 }
331
333
332 /*
334 /*
333 * Class used to warn user when leaving a page with unsaved textarea
335 * Class used to warn user when leaving a page with unsaved textarea
334 * Author: mathias.fischer@berlinonline.de
336 * Author: mathias.fischer@berlinonline.de
335 */
337 */
336
338
337 var WarnLeavingUnsaved = Class.create({
339 var WarnLeavingUnsaved = Class.create({
338 observedForms: false,
340 observedForms: false,
339 observedElements: false,
341 observedElements: false,
340 changedForms: false,
342 changedForms: false,
341 message: null,
343 message: null,
342
344
343 initialize: function(message){
345 initialize: function(message){
344 this.observedForms = $$('form');
346 this.observedForms = $$('form');
345 this.observedElements = $$('textarea');
347 this.observedElements = $$('textarea');
346 this.message = message;
348 this.message = message;
347
349
348 this.observedElements.each(this.observeChange.bind(this));
350 this.observedElements.each(this.observeChange.bind(this));
349 this.observedForms.each(this.submitAction.bind(this));
351 this.observedForms.each(this.submitAction.bind(this));
350
352
351 window.onbeforeunload = this.unload.bind(this);
353 window.onbeforeunload = this.unload.bind(this);
352 },
354 },
353
355
354 unload: function(){
356 unload: function(){
355 this.observedElements.each(function(el) {el.blur();})
357 this.observedElements.each(function(el) {el.blur();})
356 if(this.changedForms)
358 if(this.changedForms)
357 return this.message;
359 return this.message;
358 },
360 },
359
361
360 setChanged: function(){
362 setChanged: function(){
361 this.changedForms = true;
363 this.changedForms = true;
362 },
364 },
363
365
364 setUnchanged: function(){
366 setUnchanged: function(){
365 this.changedForms = false;
367 this.changedForms = false;
366 },
368 },
367
369
368 observeChange: function(element){
370 observeChange: function(element){
369 element.observe('change',this.setChanged.bindAsEventListener(this));
371 element.observe('change',this.setChanged.bindAsEventListener(this));
370 },
372 },
371
373
372 submitAction: function(element){
374 submitAction: function(element){
373 element.observe('submit',this.setUnchanged.bindAsEventListener(this));
375 element.observe('submit',this.setUnchanged.bindAsEventListener(this));
374 }
376 }
375 });
377 });
376
378
377 /*
379 /*
378 * 1 - registers a callback which copies the csrf token into the
380 * 1 - registers a callback which copies the csrf token into the
379 * X-CSRF-Token header with each ajax request. Necessary to
381 * X-CSRF-Token header with each ajax request. Necessary to
380 * work with rails applications which have fixed
382 * work with rails applications which have fixed
381 * CVE-2011-0447
383 * CVE-2011-0447
382 * 2 - shows and hides ajax indicator
384 * 2 - shows and hides ajax indicator
383 */
385 */
384 Ajax.Responders.register({
386 Ajax.Responders.register({
385 onCreate: function(request){
387 onCreate: function(request){
386 var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
388 var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
387
389
388 if (csrf_meta_tag) {
390 if (csrf_meta_tag) {
389 var header = 'X-CSRF-Token',
391 var header = 'X-CSRF-Token',
390 token = csrf_meta_tag.readAttribute('content');
392 token = csrf_meta_tag.readAttribute('content');
391
393
392 if (!request.options.requestHeaders) {
394 if (!request.options.requestHeaders) {
393 request.options.requestHeaders = {};
395 request.options.requestHeaders = {};
394 }
396 }
395 request.options.requestHeaders[header] = token;
397 request.options.requestHeaders[header] = token;
396 }
398 }
397
399
398 if ($('ajax-indicator') && Ajax.activeRequestCount > 0) {
400 if ($('ajax-indicator') && Ajax.activeRequestCount > 0) {
399 Element.show('ajax-indicator');
401 Element.show('ajax-indicator');
400 }
402 }
401 },
403 },
402 onComplete: function(){
404 onComplete: function(){
403 if ($('ajax-indicator') && Ajax.activeRequestCount == 0) {
405 if ($('ajax-indicator') && Ajax.activeRequestCount == 0) {
404 Element.hide('ajax-indicator');
406 Element.hide('ajax-indicator');
405 }
407 }
406 }
408 }
407 });
409 });
408
410
409 function hideOnLoad() {
411 function hideOnLoad() {
410 $$('.hol').each(function(el) {
412 $$('.hol').each(function(el) {
411 el.hide();
413 el.hide();
412 });
414 });
413 }
415 }
414
416
415 Event.observe(window, 'load', hideOnLoad);
417 Event.observe(window, 'load', hideOnLoad);
General Comments 0
You need to be logged in to leave comments. Login now