##// END OF EJS Templates
ajaxified paginators...
Jean-Philippe Lang -
r31:6a0022d7a146
parent child
Show More
@@ -1,54 +1,56
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class AdminController < ApplicationController
19 19 layout 'base'
20 20 before_filter :require_admin
21 21
22 22 helper :sort
23 23 include SortHelper
24 24
25 25 def index
26 26 end
27 27
28 28 def projects
29 29 sort_init 'name', 'asc'
30 30 sort_update
31 31 @project_count = Project.count
32 32 @project_pages = Paginator.new self, @project_count,
33 33 15,
34 34 @params['page']
35 35 @projects = Project.find :all, :order => sort_clause,
36 36 :limit => @project_pages.items_per_page,
37 :offset => @project_pages.current.offset
37 :offset => @project_pages.current.offset
38
39 render :action => "projects", :layout => false if request.xhr?
38 40 end
39 41
40 42 def mail_options
41 43 @actions = Permission.find(:all, :conditions => ["mail_option=?", true]) || []
42 44 if request.post?
43 45 @actions.each { |a|
44 46 a.mail_enabled = (params[:action_ids] || []).include? a.id.to_s
45 47 a.save
46 48 }
47 49 flash.now[:notice] = l(:notice_successful_update)
48 50 end
49 51 end
50 52
51 53 def info
52 54 @adapter_name = ActiveRecord::Base.connection.adapter_name
53 55 end
54 56 end
@@ -1,82 +1,83
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class AuthSourcesController < ApplicationController
19 19 layout 'base'
20 20 before_filter :require_admin
21 21
22 22 def index
23 23 list
24 render :action => 'list'
24 render :action => 'list' unless request.xhr?
25 25 end
26 26
27 27 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
28 28 verify :method => :post, :only => [ :destroy, :create, :update ],
29 29 :redirect_to => { :action => :list }
30 30
31 31 def list
32 32 @auth_source_pages, @auth_sources = paginate :auth_sources, :per_page => 10
33 render :action => "list", :layout => false if request.xhr?
33 34 end
34 35
35 36 def new
36 37 @auth_source = AuthSourceLdap.new
37 38 end
38 39
39 40 def create
40 41 @auth_source = AuthSourceLdap.new(params[:auth_source])
41 42 if @auth_source.save
42 43 flash[:notice] = l(:notice_successful_create)
43 44 redirect_to :action => 'list'
44 45 else
45 46 render :action => 'new'
46 47 end
47 48 end
48 49
49 50 def edit
50 51 @auth_source = AuthSource.find(params[:id])
51 52 end
52 53
53 54 def update
54 55 @auth_source = AuthSource.find(params[:id])
55 56 if @auth_source.update_attributes(params[:auth_source])
56 57 flash[:notice] = l(:notice_successful_update)
57 58 redirect_to :action => 'list'
58 59 else
59 60 render :action => 'edit'
60 61 end
61 62 end
62 63
63 64 def test_connection
64 65 @auth_method = AuthSource.find(params[:id])
65 66 begin
66 67 @auth_method.test_connection
67 68 rescue => text
68 69 flash[:notice] = text
69 70 end
70 71 flash[:notice] ||= l(:notice_successful_connection)
71 72 redirect_to :action => 'list'
72 73 end
73 74
74 75 def destroy
75 76 @auth_source = AuthSource.find(params[:id])
76 77 unless @auth_source.users.find(:first)
77 78 @auth_source.destroy
78 79 flash[:notice] = l(:notice_successful_delete)
79 80 end
80 81 redirect_to :action => 'list'
81 82 end
82 83 end
@@ -1,70 +1,71
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class CustomFieldsController < ApplicationController
19 19 layout 'base'
20 20 before_filter :require_admin
21 21
22 22 def index
23 23 list
24 render :action => 'list'
24 render :action => 'list' unless request.xhr?
25 25 end
26 26
27 27 def list
28 @custom_field_pages, @custom_fields = paginate :custom_fields, :per_page => 15
28 @custom_field_pages, @custom_fields = paginate :custom_fields, :per_page => 15
29 render :action => "list", :layout => false if request.xhr?
29 30 end
30 31
31 32 def new
32 33 case params[:type]
33 34 when "IssueCustomField"
34 35 @custom_field = IssueCustomField.new(params[:custom_field])
35 36 @custom_field.trackers = Tracker.find(params[:tracker_ids]) if params[:tracker_ids]
36 37 when "UserCustomField"
37 38 @custom_field = UserCustomField.new(params[:custom_field])
38 39 when "ProjectCustomField"
39 40 @custom_field = ProjectCustomField.new(params[:custom_field])
40 41 else
41 42 redirect_to :action => 'list'
42 43 return
43 44 end
44 45 if request.post? and @custom_field.save
45 46 flash[:notice] = l(:notice_successful_create)
46 47 redirect_to :action => 'list'
47 48 end
48 49 @trackers = Tracker.find(:all)
49 50 end
50 51
51 52 def edit
52 53 @custom_field = CustomField.find(params[:id])
53 54 if request.post? and @custom_field.update_attributes(params[:custom_field])
54 55 if @custom_field.is_a? IssueCustomField
55 56 @custom_field.trackers = params[:tracker_ids] ? Tracker.find(params[:tracker_ids]) : []
56 57 end
57 58 flash[:notice] = l(:notice_successful_update)
58 59 redirect_to :action => 'list'
59 60 end
60 61 @trackers = Tracker.find(:all)
61 62 end
62 63
63 64 def destroy
64 65 CustomField.find(params[:id]).destroy
65 66 redirect_to :action => 'list'
66 67 rescue
67 68 flash[:notice] = "Unable to delete custom field"
68 69 redirect_to :action => 'list'
69 70 end
70 71 end
@@ -1,68 +1,69
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class IssueStatusesController < ApplicationController
19 19 layout 'base'
20 20 before_filter :require_admin
21 21
22 22 def index
23 23 list
24 render :action => 'list'
24 render :action => 'list' unless request.xhr?
25 25 end
26 26
27 27 def list
28 @issue_status_pages, @issue_statuses = paginate :issue_statuses, :per_page => 10
28 @issue_status_pages, @issue_statuses = paginate :issue_statuses, :per_page => 10
29 render :action => "list", :layout => false if request.xhr?
29 30 end
30 31
31 32 def new
32 33 @issue_status = IssueStatus.new
33 34 end
34 35
35 36 def create
36 37 @issue_status = IssueStatus.new(params[:issue_status])
37 38 if @issue_status.save
38 39 flash[:notice] = l(:notice_successful_create)
39 40 redirect_to :action => 'list'
40 41 else
41 42 render :action => 'new'
42 43 end
43 44 end
44 45
45 46 def edit
46 47 @issue_status = IssueStatus.find(params[:id])
47 48 end
48 49
49 50 def update
50 51 @issue_status = IssueStatus.find(params[:id])
51 52 if @issue_status.update_attributes(params[:issue_status])
52 53 flash[:notice] = l(:notice_successful_update)
53 54 redirect_to :action => 'list'
54 55 else
55 56 render :action => 'edit'
56 57 end
57 58 end
58 59
59 60 def destroy
60 61 IssueStatus.find(params[:id]).destroy
61 62 redirect_to :action => 'list'
62 63 rescue
63 64 flash[:notice] = "Unable to delete issue status"
64 65 redirect_to :action => 'list'
65 66 end
66 67
67 68
68 69 end
@@ -1,329 +1,334
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class ProjectsController < ApplicationController
19 19 layout 'base'
20 20 before_filter :find_project, :authorize, :except => [ :index, :list, :add ]
21 21 before_filter :require_admin, :only => [ :add, :destroy ]
22 22
23 23 helper :sort
24 24 include SortHelper
25 25 helper :search_filter
26 26 include SearchFilterHelper
27 27 helper :custom_fields
28 28 include CustomFieldsHelper
29 29
30 30 def index
31 31 list
32 render :action => 'list'
32 render :action => 'list' unless request.xhr?
33 33 end
34 34
35 35 # Lists public projects
36 36 def list
37 37 sort_init 'name', 'asc'
38 38 sort_update
39 39 @project_count = Project.count(["is_public=?", true])
40 40 @project_pages = Paginator.new self, @project_count,
41 41 15,
42 42 @params['page']
43 43 @projects = Project.find :all, :order => sort_clause,
44 44 :conditions => ["is_public=?", true],
45 45 :limit => @project_pages.items_per_page,
46 :offset => @project_pages.current.offset
46 :offset => @project_pages.current.offset
47
48 render :action => "list", :layout => false if request.xhr?
47 49 end
48 50
49 51 # Add a new project
50 52 def add
51 53 @custom_fields = IssueCustomField.find(:all)
52 54 @root_projects = Project.find(:all, :conditions => "parent_id is null")
53 55 @project = Project.new(params[:project])
54 56 if request.get?
55 57 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project) }
56 58 else
57 59 @project.custom_fields = CustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
58 60 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
59 61 @project.custom_values = @custom_values
60 62 if @project.save
61 63 flash[:notice] = l(:notice_successful_create)
62 64 redirect_to :controller => 'admin', :action => 'projects'
63 65 end
64 66 end
65 67 end
66 68
67 69 # Show @project
68 70 def show
69 71 @custom_values = @project.custom_values.find(:all, :include => :custom_field)
70 72 @members = @project.members.find(:all, :include => [:user, :role])
71 73 @subprojects = @project.children if @project.children_count > 0
72 74 @news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "news.created_on DESC")
73 75 @trackers = Tracker.find(:all)
74 76 end
75 77
76 78 def settings
77 79 @root_projects = Project::find(:all, :conditions => ["parent_id is null and id <> ?", @project.id])
78 80 @custom_fields = IssueCustomField::find_all
79 81 @issue_category ||= IssueCategory.new
80 82 @member ||= @project.members.new
81 83 @roles = Role.find_all
82 84 @users = User.find_all - @project.members.find(:all, :include => :user).collect{|m| m.user }
83 85 @custom_values ||= ProjectCustomField.find(:all).collect { |x| @project.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
84 86 end
85 87
86 88 # Edit @project
87 89 def edit
88 90 if request.post?
89 91 @project.custom_fields = IssueCustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
90 92 if params[:custom_fields]
91 93 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
92 94 @project.custom_values = @custom_values
93 95 end
94 96 if @project.update_attributes(params[:project])
95 97 flash[:notice] = l(:notice_successful_update)
96 98 redirect_to :action => 'settings', :id => @project
97 99 else
98 100 settings
99 101 render :action => 'settings'
100 102 end
101 103 end
102 104 end
103 105
104 106 # Delete @project
105 107 def destroy
106 108 if request.post? and params[:confirm]
107 109 @project.destroy
108 110 redirect_to :controller => 'admin', :action => 'projects'
109 111 end
110 112 end
111 113
112 114 # Add a new issue category to @project
113 115 def add_issue_category
114 116 if request.post?
115 117 @issue_category = @project.issue_categories.build(params[:issue_category])
116 118 if @issue_category.save
117 119 flash[:notice] = l(:notice_successful_create)
118 120 redirect_to :action => 'settings', :id => @project
119 121 else
120 122 settings
121 123 render :action => 'settings'
122 124 end
123 125 end
124 126 end
125 127
126 128 # Add a new version to @project
127 129 def add_version
128 130 @version = @project.versions.build(params[:version])
129 131 if request.post? and @version.save
130 132 flash[:notice] = l(:notice_successful_create)
131 133 redirect_to :action => 'settings', :id => @project
132 134 end
133 135 end
134 136
135 137 # Add a new member to @project
136 138 def add_member
137 139 @member = @project.members.build(params[:member])
138 140 if request.post?
139 141 if @member.save
140 142 flash[:notice] = l(:notice_successful_create)
141 143 redirect_to :action => 'settings', :id => @project
142 144 else
143 145 settings
144 146 render :action => 'settings'
145 147 end
146 148 end
147 149 end
148 150
149 151 # Show members list of @project
150 152 def list_members
151 153 @members = @project.members
152 154 end
153 155
154 156 # Add a new document to @project
155 157 def add_document
156 158 @categories = Enumeration::get_values('DCAT')
157 159 @document = @project.documents.build(params[:document])
158 160 if request.post?
159 161 # Save the attachment
160 162 if params[:attachment][:file].size > 0
161 163 @attachment = @document.attachments.build(params[:attachment])
162 164 @attachment.author_id = self.logged_in_user.id if self.logged_in_user
163 165 end
164 166 if @document.save
165 167 flash[:notice] = l(:notice_successful_create)
166 168 redirect_to :action => 'list_documents', :id => @project
167 169 end
168 170 end
169 171 end
170 172
171 173 # Show documents list of @project
172 174 def list_documents
173 175 @documents = @project.documents
174 176 end
175 177
176 178 # Add a new issue to @project
177 179 def add_issue
178 180 @tracker = Tracker.find(params[:tracker_id])
179 181 @priorities = Enumeration::get_values('IPRI')
180 182 @issue = Issue.new(:project => @project, :tracker => @tracker)
181 183 if request.get?
182 184 @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue) }
183 185 else
184 186 @issue.attributes = params[:issue]
185 187 @issue.author_id = self.logged_in_user.id if self.logged_in_user
186 188 # Create the document if a file was sent
187 189 if params[:attachment][:file].size > 0
188 190 @attachment = @issue.attachments.build(params[:attachment])
189 191 @attachment.author_id = self.logged_in_user.id if self.logged_in_user
190 192 end
191 193 @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
192 194 @issue.custom_values = @custom_values
193 195 if @issue.save
194 196 flash[:notice] = l(:notice_successful_create)
195 197 Mailer.deliver_issue_add(@issue) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
196 198 redirect_to :action => 'list_issues', :id => @project
197 199 end
198 200 end
199 201 end
200 202
201 203 # Show filtered/sorted issues list of @project
202 204 def list_issues
203 205 sort_init 'issues.id', 'desc'
204 206 sort_update
205 207
206 208 search_filter_init_list_issues
207 search_filter_update if params[:set_filter] or request.post?
209 search_filter_update if params[:set_filter]
208 210
209 211 @issue_count = Issue.count(:include => [:status, :project], :conditions => search_filter_clause)
210 212 @issue_pages = Paginator.new self, @issue_count, 15, @params['page']
211 213 @issues = Issue.find :all, :order => sort_clause,
212 214 :include => [ :author, :status, :tracker, :project ],
213 215 :conditions => search_filter_clause,
214 216 :limit => @issue_pages.items_per_page,
215 :offset => @issue_pages.current.offset
217 :offset => @issue_pages.current.offset
218
219 render :action => "list_issues", :layout => false if request.xhr?
216 220 end
217 221
218 222 # Export filtered/sorted issues list to CSV
219 223 def export_issues_csv
220 224 sort_init 'issues.id', 'desc'
221 225 sort_update
222 226
223 227 search_filter_init_list_issues
224 228
225 229 @issues = Issue.find :all, :order => sort_clause,
226 230 :include => [ :author, :status, :tracker, :project ],
227 231 :conditions => search_filter_clause
228 232
229 233 export = StringIO.new
230 234 CSV::Writer.generate(export, ',') do |csv|
231 235 csv << %w(Id Status Tracker Subject Author Created Updated)
232 236 @issues.each do |issue|
233 237 csv << [issue.id, issue.status.name, issue.tracker.name, issue.subject, issue.author.display_name, l_datetime(issue.created_on), l_datetime(issue.updated_on)]
234 238 end
235 239 end
236 240 export.rewind
237 241 send_data(export.read,
238 242 :type => 'text/csv; charset=utf-8; header=present',
239 243 :filename => 'export.csv')
240 244 end
241 245
242 246 def move_issues
243 247 @issues = @project.issues.find(params[:issue_ids]) if params[:issue_ids]
244 248 redirect_to :action => 'list_issues', :id => @project and return unless @issues
245 249 @projects = []
246 250 # find projects to which the user is allowed to move the issue
247 251 @logged_in_user.memberships.each {|m| @projects << m.project if Permission.allowed_to_role("projects/move_issues", m.role_id)}
248 252 # issue can be moved to any tracker
249 253 @trackers = Tracker.find(:all)
250 254 if request.post? and params[:new_project_id] and params[:new_tracker_id]
251 255 new_project = Project.find(params[:new_project_id])
252 256 new_tracker = Tracker.find(params[:new_tracker_id])
253 257 @issues.each { |i|
254 258 # category is project dependent
255 259 i.category = nil unless i.project_id == new_project.id
256 260 # move the issue
257 261 i.project = new_project
258 262 i.tracker = new_tracker
259 263 i.save
260 264 }
261 265 flash[:notice] = l(:notice_successful_update)
262 266 redirect_to :action => 'list_issues', :id => @project
263 267 end
264 268 end
265 269
266 270 # Add a news to @project
267 271 def add_news
268 272 @news = News.new(:project => @project)
269 273 if request.post?
270 274 @news.attributes = params[:news]
271 275 @news.author_id = self.logged_in_user.id if self.logged_in_user
272 276 if @news.save
273 277 flash[:notice] = l(:notice_successful_create)
274 278 redirect_to :action => 'list_news', :id => @project
275 279 end
276 280 end
277 281 end
278 282
279 283 # Show news list of @project
280 284 def list_news
281 285 @news_pages, @news = paginate :news, :per_page => 10, :conditions => ["project_id=?", @project.id], :include => :author, :order => "news.created_on DESC"
286 render :action => "list_news", :layout => false if request.xhr?
282 287 end
283 288
284 289 def add_file
285 290 if request.post?
286 291 # Save the attachment
287 292 if params[:attachment][:file].size > 0
288 293 @attachment = @project.versions.find(params[:version_id]).attachments.build(params[:attachment])
289 294 @attachment.author_id = self.logged_in_user.id if self.logged_in_user
290 295 if @attachment.save
291 296 flash[:notice] = l(:notice_successful_create)
292 297 redirect_to :controller => 'projects', :action => 'list_files', :id => @project
293 298 end
294 299 end
295 300 end
296 301 @versions = @project.versions
297 302 end
298 303
299 304 def list_files
300 305 @versions = @project.versions
301 306 end
302 307
303 308 # Show changelog for @project
304 309 def changelog
305 310 @trackers = Tracker.find(:all, :conditions => ["is_in_chlog=?", true])
306 311 if request.get?
307 312 @selected_tracker_ids = @trackers.collect {|t| t.id.to_s }
308 313 else
309 314 @selected_tracker_ids = params[:tracker_ids].collect { |id| id.to_i.to_s } if params[:tracker_ids] and params[:tracker_ids].is_a? Array
310 315 end
311 316 @selected_tracker_ids ||= []
312 317 @fixed_issues = @project.issues.find(:all,
313 318 :include => [ :fixed_version, :status, :tracker ],
314 319 :conditions => [ "issue_statuses.is_closed=? and issues.tracker_id in (#{@selected_tracker_ids.join(',')}) and issues.fixed_version_id is not null", true],
315 320 :order => "versions.effective_date DESC, issues.id DESC"
316 321 ) unless @selected_tracker_ids.empty?
317 322 @fixed_issues ||= []
318 323 end
319 324
320 325 private
321 326 # Find project of id params[:id]
322 327 # if not found, redirect to project list
323 328 # Used as a before_filter
324 329 def find_project
325 330 @project = Project.find(params[:id])
326 331 rescue
327 332 redirect_to :action => 'list'
328 333 end
329 334 end
@@ -1,83 +1,84
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class RolesController < ApplicationController
19 19 layout 'base'
20 20 before_filter :require_admin
21 21
22 22 def index
23 23 list
24 render :action => 'list'
24 render :action => 'list' unless request.xhr?
25 25 end
26 26
27 27 def list
28 @role_pages, @roles = paginate :roles, :per_page => 10
28 @role_pages, @roles = paginate :roles, :per_page => 10
29 render :action => "list", :layout => false if request.xhr?
29 30 end
30 31
31 32 def new
32 33 @role = Role.new(params[:role])
33 34 if request.post?
34 35 @role.permissions = Permission.find(@params[:permission_ids]) if @params[:permission_ids]
35 36 if @role.save
36 37 flash[:notice] = l(:notice_successful_create)
37 38 redirect_to :action => 'list'
38 39 end
39 40 end
40 41 @permissions = Permission.find(:all, :conditions => ["is_public=?", false], :order => 'sort ASC')
41 42 end
42 43
43 44 def edit
44 45 @role = Role.find(params[:id])
45 46 if request.post? and @role.update_attributes(params[:role])
46 47 @role.permissions = Permission.find(@params[:permission_ids] || [])
47 48 Permission.allowed_to_role_expired
48 49 flash[:notice] = l(:notice_successful_update)
49 50 redirect_to :action => 'list'
50 51 end
51 52 @permissions = Permission.find(:all, :conditions => ["is_public=?", false], :order => 'sort ASC')
52 53 end
53 54
54 55 def destroy
55 56 @role = Role.find(params[:id])
56 57 unless @role.members.empty?
57 58 flash[:notice] = 'Some members have this role. Can\'t delete it.'
58 59 else
59 60 @role.destroy
60 61 end
61 62 redirect_to :action => 'list'
62 63 end
63 64
64 65 def workflow
65 66 @role = Role.find_by_id(params[:role_id])
66 67 @tracker = Tracker.find_by_id(params[:tracker_id])
67 68
68 69 if request.post?
69 70 Workflow.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id])
70 71 (params[:issue_status] || []).each { |old, news|
71 72 news.each { |new|
72 73 @role.workflows.build(:tracker_id => @tracker.id, :old_status_id => old, :new_status_id => new)
73 74 }
74 75 }
75 76 if @role.save
76 77 flash[:notice] = l(:notice_successful_update)
77 78 end
78 79 end
79 80 @roles = Role.find_all
80 81 @trackers = Tracker.find_all
81 82 @statuses = IssueStatus.find(:all, :include => :workflows)
82 83 end
83 84 end
@@ -1,60 +1,61
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class TrackersController < ApplicationController
19 19 layout 'base'
20 20 before_filter :require_admin
21 21
22 22 def index
23 23 list
24 render :action => 'list'
24 render :action => 'list' unless request.xhr?
25 25 end
26 26
27 27 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
28 28 verify :method => :post, :only => [ :destroy ], :redirect_to => { :action => :list }
29 29
30 30 def list
31 @tracker_pages, @trackers = paginate :trackers, :per_page => 10
31 @tracker_pages, @trackers = paginate :trackers, :per_page => 10
32 render :action => "list", :layout => false if request.xhr?
32 33 end
33 34
34 35 def new
35 36 @tracker = Tracker.new(params[:tracker])
36 37 if request.post? and @tracker.save
37 38 flash[:notice] = l(:notice_successful_create)
38 39 redirect_to :action => 'list'
39 40 end
40 41 end
41 42
42 43 def edit
43 44 @tracker = Tracker.find(params[:id])
44 45 if request.post? and @tracker.update_attributes(params[:tracker])
45 46 flash[:notice] = l(:notice_successful_update)
46 47 redirect_to :action => 'list'
47 48 end
48 49 end
49 50
50 51 def destroy
51 52 @tracker = Tracker.find(params[:id])
52 53 unless @tracker.issues.empty?
53 54 flash[:notice] = "This tracker contains issues and can\'t be deleted."
54 55 else
55 56 @tracker.destroy
56 57 end
57 58 redirect_to :action => 'list'
58 59 end
59 60
60 61 end
@@ -1,88 +1,90
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class UsersController < ApplicationController
19 19 layout 'base'
20 20 before_filter :require_admin
21 21
22 22 helper :sort
23 23 include SortHelper
24 24 helper :custom_fields
25 25 include CustomFieldsHelper
26 26
27 27 def index
28 28 list
29 render :action => 'list'
29 render :action => 'list' unless request.xhr?
30 30 end
31 31
32 32 def list
33 33 sort_init 'login', 'asc'
34 34 sort_update
35 35 @user_count = User.count
36 36 @user_pages = Paginator.new self, @user_count,
37 37 15,
38 38 @params['page']
39 39 @users = User.find :all,:order => sort_clause,
40 40 :limit => @user_pages.items_per_page,
41 :offset => @user_pages.current.offset
41 :offset => @user_pages.current.offset
42
43 render :action => "list", :layout => false if request.xhr?
42 44 end
43 45
44 46 def add
45 47 if request.get?
46 48 @user = User.new(:language => $RDM_DEFAULT_LANG)
47 49 @custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user) }
48 50 else
49 51 @user = User.new(params[:user])
50 52 @user.admin = params[:user][:admin] || false
51 53 @user.login = params[:user][:login]
52 54 @user.password, @user.password_confirmation = params[:password], params[:password_confirmation]
53 55 @custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }
54 56 @user.custom_values = @custom_values
55 57 if @user.save
56 58 flash[:notice] = l(:notice_successful_create)
57 59 redirect_to :action => 'list'
58 60 end
59 61 end
60 62 end
61 63
62 64 def edit
63 65 @user = User.find(params[:id])
64 66 if request.get?
65 67 @custom_values = UserCustomField.find(:all).collect { |x| @user.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
66 68 else
67 69 @user.admin = params[:user][:admin] if params[:user][:admin]
68 70 @user.login = params[:user][:login] if params[:user][:login]
69 71 @user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless params[:password].nil? or params[:password].empty?
70 72 if params[:custom_fields]
71 73 @custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }
72 74 @user.custom_values = @custom_values
73 75 end
74 76 if @user.update_attributes(params[:user])
75 77 flash[:notice] = l(:notice_successful_update)
76 78 redirect_to :action => 'list'
77 79 end
78 80 end
79 81 end
80 82
81 83 def destroy
82 84 User.find(params[:id]).destroy
83 85 redirect_to :action => 'list'
84 86 rescue
85 87 flash[:notice] = "Unable to delete user"
86 88 redirect_to :action => 'list'
87 89 end
88 90 end
@@ -1,161 +1,171
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 module ApplicationHelper
19 19
20 20 # Return current logged in user or nil
21 21 def loggedin?
22 22 @logged_in_user
23 23 end
24 24
25 25 # Return true if user is logged in and is admin, otherwise false
26 26 def admin_loggedin?
27 27 @logged_in_user and @logged_in_user.admin?
28 28 end
29 29
30 30 # Return true if user is authorized for controller/action, otherwise false
31 31 def authorize_for(controller, action)
32 32 # check if action is allowed on public projects
33 33 if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ controller, action ]
34 34 return true
35 35 end
36 36 # check if user is authorized
37 37 if @logged_in_user and (@logged_in_user.admin? or Permission.allowed_to_role( "%s/%s" % [ controller, action ], @logged_in_user.role_for_project(@project.id) ) )
38 38 return true
39 39 end
40 40 return false
41 41 end
42 42
43 43 # Display a link if user is authorized
44 44 def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
45 45 link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller], options[:action])
46 46 end
47 47
48 48 # Display a link to user's account page
49 49 def link_to_user(user)
50 50 link_to user.display_name, :controller => 'account', :action => 'show', :id => user
51 51 end
52 52
53 53 def format_date(date)
54 54 l_date(date) if date
55 55 end
56 56
57 57 def format_time(time)
58 58 l_datetime(time) if time
59 59 end
60 60
61 61 def pagination_links_full(paginator, options={}, html_options={})
62 html =''
63 html << link_to(('&#171; ' + l(:label_previous) ), { :page => paginator.current.previous }) + ' ' if paginator.current.previous
64 html << (pagination_links(paginator, options, html_options) || '')
65 html << ' ' + link_to((l(:label_next) + ' &#187;'), { :page => paginator.current.next }) if paginator.current.next
62 html = ''
63 html << link_to_remote(('&#171; ' + l(:label_previous)),
64 {:update => "content", :url => { :page => paginator.current.previous }},
65 {:href => url_for(:action => 'list', :params => @params.merge({:page => paginator.current.previous}))}) + ' ' if paginator.current.previous
66
67 html << (pagination_links_each(paginator, options) do |n|
68 link_to_remote(n.to_s,
69 {:url => {:action => 'list', :params => @params.merge({:page => n})}, :update => 'content'},
70 {:href => url_for(:action => 'list', :params => @params.merge({:page => n}))})
71 end || '')
72
73 html << ' ' + link_to_remote((l(:label_next) + ' &#187;'),
74 {:update => "content", :url => { :page => paginator.current.next }},
75 {:href => url_for(:action => 'list', :params => @params.merge({:page => paginator.current.next}))}) if paginator.current.next
66 76 html
67 77 end
68 78
69 79 def error_messages_for(object_name, options = {})
70 80 options = options.symbolize_keys
71 81 object = instance_variable_get("@#{object_name}")
72 82 if object && !object.errors.empty?
73 83 # build full_messages here with controller current language
74 84 full_messages = []
75 85 object.errors.each do |attr, msg|
76 86 next if msg.nil?
77 87 if attr == "base"
78 88 full_messages << l(msg)
79 89 else
80 90 full_messages << "&#171; " + (l_has_string?("field_" + attr) ? l("field_" + attr) : object.class.human_attribute_name(attr)) + " &#187; " + l(msg) unless attr == "custom_values"
81 91 end
82 92 end
83 93 # retrieve custom values error messages
84 94 if object.errors[:custom_values]
85 95 object.custom_values.each do |v|
86 96 v.errors.each do |attr, msg|
87 97 next if msg.nil?
88 98 full_messages << "&#171; " + v.custom_field.name + " &#187; " + l(msg)
89 99 end
90 100 end
91 101 end
92 102 content_tag("div",
93 103 content_tag(
94 104 options[:header_tag] || "h2", lwr(:gui_validation_error, full_messages.length) + " :"
95 105 ) +
96 106 content_tag("ul", full_messages.collect { |msg| content_tag("li", msg) }),
97 107 "id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
98 108 )
99 109 else
100 110 ""
101 111 end
102 112 end
103 113
104 114 def lang_options_for_select
105 115 (GLoc.valid_languages.sort {|x,y| x.to_s <=> y.to_s }).collect {|lang| [ l_lang_name(lang.to_s, lang), lang.to_s]}
106 116 end
107 117
108 118 def label_tag_for(name, option_tags = nil, options = {})
109 119 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
110 120 content_tag("label", label_text)
111 121 end
112 122
113 123 def labelled_tabular_form_for(name, object, options, &proc)
114 124 options[:html] ||= {}
115 125 options[:html].store :class, "tabular"
116 126 form_for(name, object, options.merge({ :builder => TabularFormBuilder, :lang => current_language}), &proc)
117 127 end
118 128
119 129 def check_all_links(form_name)
120 130 link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
121 131 " | " +
122 132 link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
123 133 end
124 134
125 135 def calendar_for(field_id)
126 136 image_tag("calendar", {:id => "#{field_id}_trigger",:class => "calendar-trigger"}) +
127 137 javascript_tag("Calendar.setup({inputField : '#{field_id}', ifFormat : '%Y-%m-%d', button : '#{field_id}_trigger' });")
128 138 end
129 139 end
130 140
131 141 class TabularFormBuilder < ActionView::Helpers::FormBuilder
132 142 include GLoc
133 143
134 144 def initialize(object_name, object, template, options, proc)
135 145 set_language_if_valid options.delete(:lang)
136 146 @object_name, @object, @template, @options, @proc = object_name, object, template, options, proc
137 147 end
138 148
139 149 (field_helpers - %w(radio_button hidden_field) + %w(date_select)).each do |selector|
140 150 src = <<-END_SRC
141 151 def #{selector}(field, options = {})
142 152 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
143 153 label = @template.content_tag("label", label_text,
144 154 :class => (@object.errors[field] ? "error" : nil),
145 155 :for => (@object_name.to_s + "_" + field.to_s))
146 156 label + super
147 157 end
148 158 END_SRC
149 159 class_eval src, __FILE__, __LINE__
150 160 end
151 161
152 162 def select(field, choices, options = {})
153 163 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
154 164 label = @template.content_tag("label", label_text,
155 165 :class => (@object.errors[field] ? "error" : nil),
156 166 :for => (@object_name.to_s + "_" + field.to_s))
157 167 label + super
158 168 end
159 169
160 170 end
161 171
@@ -1,157 +1,160
1 1 # Helpers to sort tables using clickable column headers.
2 2 #
3 3 # Author: Stuart Rackham <srackham@methods.co.nz>, March 2005.
4 4 # License: This source code is released under the MIT license.
5 5 #
6 6 # - Consecutive clicks toggle the column's sort order.
7 7 # - Sort state is maintained by a session hash entry.
8 8 # - Icon image identifies sort column and state.
9 9 # - Typically used in conjunction with the Pagination module.
10 10 #
11 11 # Example code snippets:
12 12 #
13 13 # Controller:
14 14 #
15 15 # helper :sort
16 16 # include SortHelper
17 17 #
18 18 # def list
19 19 # sort_init 'last_name'
20 20 # sort_update
21 21 # @items = Contact.find_all nil, sort_clause
22 22 # end
23 23 #
24 24 # Controller (using Pagination module):
25 25 #
26 26 # helper :sort
27 27 # include SortHelper
28 28 #
29 29 # def list
30 30 # sort_init 'last_name'
31 31 # sort_update
32 32 # @contact_pages, @items = paginate :contacts,
33 33 # :order_by => sort_clause,
34 34 # :per_page => 10
35 35 # end
36 36 #
37 37 # View (table header in list.rhtml):
38 38 #
39 39 # <thead>
40 40 # <tr>
41 41 # <%= sort_header_tag('id', :title => 'Sort by contact ID') %>
42 42 # <%= sort_header_tag('last_name', :caption => 'Name') %>
43 43 # <%= sort_header_tag('phone') %>
44 44 # <%= sort_header_tag('address', :width => 200) %>
45 45 # </tr>
46 46 # </thead>
47 47 #
48 48 # - The ascending and descending sort icon images are sort_asc.png and
49 49 # sort_desc.png and reside in the application's images directory.
50 50 # - Introduces instance variables: @sort_name, @sort_default.
51 51 # - Introduces params :sort_key and :sort_order.
52 52 #
53 53 module SortHelper
54 54
55 55 # Initializes the default sort column (default_key) and sort order
56 56 # (default_order).
57 57 #
58 58 # - default_key is a column attribute name.
59 59 # - default_order is 'asc' or 'desc'.
60 60 # - name is the name of the session hash entry that stores the sort state,
61 61 # defaults to '<controller_name>_sort'.
62 62 #
63 63 def sort_init(default_key, default_order='asc', name=nil)
64 64 @sort_name = name || @params[:controller] + @params[:action] + '_sort'
65 65 @sort_default = {:key => default_key, :order => default_order}
66 66 end
67 67
68 68 # Updates the sort state. Call this in the controller prior to calling
69 69 # sort_clause.
70 70 #
71 71 def sort_update()
72 72 if @params[:sort_key]
73 73 sort = {:key => @params[:sort_key], :order => @params[:sort_order]}
74 74 elsif @session[@sort_name]
75 75 sort = @session[@sort_name] # Previous sort.
76 76 else
77 77 sort = @sort_default
78 78 end
79 79 @session[@sort_name] = sort
80 80 end
81 81
82 82 # Returns an SQL sort clause corresponding to the current sort state.
83 83 # Use this to sort the controller's table items collection.
84 84 #
85 85 def sort_clause()
86 86 @session[@sort_name][:key] + ' ' + @session[@sort_name][:order]
87 87 end
88 88
89 89 # Returns a link which sorts by the named column.
90 90 #
91 91 # - column is the name of an attribute in the sorted record collection.
92 92 # - The optional caption explicitly specifies the displayed link text.
93 93 # - A sort icon image is positioned to the right of the sort link.
94 94 #
95 95 def sort_link(column, caption=nil)
96 96 key, order = @session[@sort_name][:key], @session[@sort_name][:order]
97 97 if key == column
98 98 if order.downcase == 'asc'
99 99 icon = 'sort_asc'
100 100 order = 'desc'
101 101 else
102 102 icon = 'sort_desc'
103 103 order = 'asc'
104 104 end
105 105 else
106 106 icon = nil
107 107 order = 'desc' # changed for desc order by default
108 108 end
109 109 caption = titleize(Inflector::humanize(column)) unless caption
110 110 params = {:params => {:sort_key => column, :sort_order => order}}
111 link_to(caption, params) + (icon ? nbsp(2) + image_tag(icon) : '')
111 link_to_remote(caption,
112 {:update => "content", :url => { :sort_key => column, :sort_order => order}},
113 {:href => url_for(:params => { :sort_key => column, :sort_order => order})}) +
114 (icon ? nbsp(2) + image_tag(icon) : '')
112 115 end
113 116
114 117 # Returns a table header <th> tag with a sort link for the named column
115 118 # attribute.
116 119 #
117 120 # Options:
118 121 # :caption The displayed link name (defaults to titleized column name).
119 122 # :title The tag's 'title' attribute (defaults to 'Sort by :caption').
120 123 #
121 124 # Other options hash entries generate additional table header tag attributes.
122 125 #
123 126 # Example:
124 127 #
125 128 # <%= sort_header_tag('id', :title => 'Sort by contact ID', :width => 40) %>
126 129 #
127 130 # Renders:
128 131 #
129 132 # <th title="Sort by contact ID" width="40">
130 133 # <a href="/contact/list?sort_order=desc&amp;sort_key=id">Id</a>
131 134 # &nbsp;&nbsp;<img alt="Sort_asc" src="/images/sort_asc.png" />
132 135 # </th>
133 136 #
134 137 def sort_header_tag(column, options = {})
135 138 if options[:caption]
136 139 caption = options[:caption]
137 140 options.delete(:caption)
138 141 else
139 142 caption = titleize(Inflector::humanize(column))
140 143 end
141 144 options[:title]= "Sort by #{caption}" unless options[:title]
142 145 content_tag('th', sort_link(column, caption), options)
143 146 end
144 147
145 148 private
146 149
147 150 # Return n non-breaking spaces.
148 151 def nbsp(n)
149 152 '&nbsp;' * n
150 153 end
151 154
152 155 # Return capitalized title.
153 156 def titleize(title)
154 157 title.split.map {|w| w.capitalize }.join(' ')
155 158 end
156 159
157 160 end
@@ -1,30 +1,30
1 1 <h2><%=l(:label_auth_source_plural)%></h2>
2 2
3 3 <table class="listTableContent">
4 4 <tr class="ListHead">
5 <td><%=l(:field_name)%></td>
6 <td><%=l(:field_type)%></td>
7 <td><%=l(:field_host)%></td>
8 <td></td>
9 <td></td>
5 <th><%=l(:field_name)%></th>
6 <th><%=l(:field_type)%></th>
7 <th><%=l(:field_host)%></th>
8 <th></th>
9 <th></th>
10 10 </tr>
11 11
12 12 <% for source in @auth_sources %>
13 13 <tr class="<%= cycle("odd", "even") %>">
14 14 <td><%= link_to source.name, :action => 'edit', :id => source%></td>
15 15 <td align="center"><%= source.auth_method_name %></td>
16 16 <td align="center"><%= source.host %></td>
17 17 <td align="center">
18 18 <%= link_to l(:button_test), :action => 'test_connection', :id => source %>
19 19 </td>
20 20 <td align="center">
21 21 <%= button_to l(:button_delete), { :action => 'destroy', :id => source }, :confirm => l(:text_are_you_sure), :class => "button-small" %>
22 22 </td>
23 23 </tr>
24 24 <% end %>
25 25 </table>
26 26
27 27 <%= pagination_links_full @auth_source_pages %>
28 28 <br />
29 29 <%= link_to '&#187; ' + l(:label_auth_source_new), :action => 'new' %>
30 30
@@ -1,60 +1,60
1 1 <h2><%=l(:label_issue_plural)%></h2>
2 2
3 3 <form method="post" class="noborder">
4 4 <table cellpadding=2>
5 5 <tr>
6 6 <td><small><%=l(:field_status)%>:</small><br /><%= search_filter_tag 'status_id', :class => 'select-small' %></td>
7 7 <td><small><%=l(:field_tracker)%>:</small><br /><%= search_filter_tag 'tracker_id', :class => 'select-small' %></td>
8 8 <td><small><%=l(:field_priority)%>:</small><br /><%= search_filter_tag 'priority_id', :class => 'select-small' %></td>
9 9 <td><small><%=l(:field_category)%>:</small><br /><%= search_filter_tag 'category_id', :class => 'select-small' %></td>
10 10 <td><small><%=l(:field_fixed_version)%>:</small><br /><%= search_filter_tag 'fixed_version_id', :class => 'select-small' %></td>
11 11 <td><small><%=l(:field_assigned_to)%>:</small><br /><%= search_filter_tag 'assigned_to_id', :class => 'select-small' %></td>
12 12 <td><small><%=l(:label_subproject_plural)%>:</small><br /><%= search_filter_tag 'subproject_id', :class => 'select-small' %></td>
13
14 13 <td valign="bottom">
14 <%= hidden_field_tag 'set_filter', 1 %>
15 15 <%= submit_tag l(:button_apply), :class => 'button-small' %>
16 <%= end_form_tag %>
17
18 <%= start_form_tag %>
19 <%= submit_tag l(:button_clear), :class => 'button-small' %>
20 <%= end_form_tag %>
21 16 </td>
22 </tr>
17 <td valign="bottom">
18 <%= link_to l(:button_clear), :action => 'list_issues', :id => @project, :set_filter => 1 %>
19 </td>
20 </tr>
23 21 </table>
22 <%= end_form_tag %>
23
24 24 &nbsp;
25 25
26 26 <%= start_form_tag ({:controller => 'projects', :action => 'move_issues', :id => @project}, :id => 'issues_form' ) %>
27 27 <table class="listTableContent">
28 28 <tr>
29 29 <td colspan="6" align="left"><small><%= check_all_links 'issues_form' %></small></td>
30 30 <td colspan="2" align="right"><small><%= link_to l(:label_export_csv), :action => 'export_issues_csv', :id => @project.id %></small></td>
31 31 </tr>
32 32 <tr class="ListHead">
33 33 <td></td>
34 34 <%= sort_header_tag('issues.id', :caption => '#') %>
35 35 <%= sort_header_tag('issue_statuses.name', :caption => l(:field_status)) %>
36 36 <%= sort_header_tag('issues.tracker_id', :caption => l(:field_tracker)) %>
37 37 <th><%=l(:field_subject)%></th>
38 38 <%= sort_header_tag('users.lastname', :caption => l(:field_author)) %>
39 39 <%= sort_header_tag('issues.created_on', :caption => l(:field_created_on)) %>
40 40 <%= sort_header_tag('issues.updated_on', :caption => l(:field_updated_on)) %>
41 41 </tr>
42 42 <% for issue in @issues %>
43 43 <tr bgcolor="#<%= issue.status.html_color %>">
44 44 <td width="15"><%= check_box_tag "issue_ids[]", issue.id %></td>
45 45 <td align="center"><%= link_to issue.long_id, :controller => 'issues', :action => 'show', :id => issue %></td>
46 46 <td align="center"><%= issue.status.name %></td>
47 47 <td align="center"><%= issue.tracker.name %></td>
48 48 <td><%= link_to issue.subject, :controller => 'issues', :action => 'show', :id => issue %></td>
49 49 <td align="center"><%= issue.author.display_name %></td>
50 50 <td align="center"><%= format_time(issue.created_on) %></td>
51 51 <td align="center"><%= format_time(issue.updated_on) %></td>
52 52 </tr>
53 53 <% end %>
54 54 </table>
55 55 <p>
56 56 <%= pagination_links_full @issue_pages %>
57 57 [ <%= @issue_pages.current.first_item %> - <%= @issue_pages.current.last_item %> / <%= @issue_count %> ]
58 58 </p>
59 59 <%= submit_tag l(:button_move) %>
60 60 <%= end_form_tag %> No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now