##// END OF EJS Templates
calendar and activity views edited (previous/next links)...
Jean-Philippe Lang -
r70:2c335dbf32f7
parent child
Show More
@@ -1,469 +1,470
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', :except => :export_issues_pdf
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 helper :ifpdf
30 30 include IfpdfHelper
31 31 helper IssuesHelper
32 32
33 33 def index
34 34 list
35 35 render :action => 'list' unless request.xhr?
36 36 end
37 37
38 38 # Lists public projects
39 39 def list
40 40 sort_init 'name', 'asc'
41 41 sort_update
42 42 @project_count = Project.count(["is_public=?", true])
43 43 @project_pages = Paginator.new self, @project_count,
44 44 15,
45 45 @params['page']
46 46 @projects = Project.find :all, :order => sort_clause,
47 47 :conditions => ["is_public=?", true],
48 48 :limit => @project_pages.items_per_page,
49 49 :offset => @project_pages.current.offset
50 50
51 51 render :action => "list", :layout => false if request.xhr?
52 52 end
53 53
54 54 # Add a new project
55 55 def add
56 56 @custom_fields = IssueCustomField.find(:all)
57 57 @root_projects = Project.find(:all, :conditions => "parent_id is null")
58 58 @project = Project.new(params[:project])
59 59 if request.get?
60 60 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project) }
61 61 else
62 62 @project.custom_fields = CustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
63 63 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
64 64 @project.custom_values = @custom_values
65 65 if @project.save
66 66 flash[:notice] = l(:notice_successful_create)
67 67 redirect_to :controller => 'admin', :action => 'projects'
68 68 end
69 69 end
70 70 end
71 71
72 72 # Show @project
73 73 def show
74 74 @custom_values = @project.custom_values.find(:all, :include => :custom_field)
75 75 @members = @project.members.find(:all, :include => [:user, :role])
76 76 @subprojects = @project.children if @project.children_count > 0
77 77 @news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "news.created_on DESC")
78 78 @trackers = Tracker.find(:all)
79 79 end
80 80
81 81 def settings
82 82 @root_projects = Project::find(:all, :conditions => ["parent_id is null and id <> ?", @project.id])
83 83 @custom_fields = IssueCustomField::find_all
84 84 @issue_category ||= IssueCategory.new
85 85 @member ||= @project.members.new
86 86 @roles = Role.find_all
87 87 @users = User.find_all - @project.members.find(:all, :include => :user).collect{|m| m.user }
88 88 @custom_values ||= ProjectCustomField.find(:all).collect { |x| @project.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
89 89 end
90 90
91 91 # Edit @project
92 92 def edit
93 93 if request.post?
94 94 @project.custom_fields = IssueCustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
95 95 if params[:custom_fields]
96 96 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
97 97 @project.custom_values = @custom_values
98 98 end
99 99 if @project.update_attributes(params[:project])
100 100 flash[:notice] = l(:notice_successful_update)
101 101 redirect_to :action => 'settings', :id => @project
102 102 else
103 103 settings
104 104 render :action => 'settings'
105 105 end
106 106 end
107 107 end
108 108
109 109 # Delete @project
110 110 def destroy
111 111 if request.post? and params[:confirm]
112 112 @project.destroy
113 113 redirect_to :controller => 'admin', :action => 'projects'
114 114 end
115 115 end
116 116
117 117 # Add a new issue category to @project
118 118 def add_issue_category
119 119 if request.post?
120 120 @issue_category = @project.issue_categories.build(params[:issue_category])
121 121 if @issue_category.save
122 122 flash[:notice] = l(:notice_successful_create)
123 123 redirect_to :action => 'settings', :id => @project
124 124 else
125 125 settings
126 126 render :action => 'settings'
127 127 end
128 128 end
129 129 end
130 130
131 131 # Add a new version to @project
132 132 def add_version
133 133 @version = @project.versions.build(params[:version])
134 134 if request.post? and @version.save
135 135 flash[:notice] = l(:notice_successful_create)
136 136 redirect_to :action => 'settings', :id => @project
137 137 end
138 138 end
139 139
140 140 # Add a new member to @project
141 141 def add_member
142 142 @member = @project.members.build(params[:member])
143 143 if request.post?
144 144 if @member.save
145 145 flash[:notice] = l(:notice_successful_create)
146 146 redirect_to :action => 'settings', :id => @project
147 147 else
148 148 settings
149 149 render :action => 'settings'
150 150 end
151 151 end
152 152 end
153 153
154 154 # Show members list of @project
155 155 def list_members
156 156 @members = @project.members
157 157 end
158 158
159 159 # Add a new document to @project
160 160 def add_document
161 161 @categories = Enumeration::get_values('DCAT')
162 162 @document = @project.documents.build(params[:document])
163 163 if request.post?
164 164 # Save the attachment
165 165 if params[:attachment][:file].size > 0
166 166 @attachment = @document.attachments.build(params[:attachment])
167 167 @attachment.author_id = self.logged_in_user.id if self.logged_in_user
168 168 end
169 169 if @document.save
170 170 flash[:notice] = l(:notice_successful_create)
171 171 redirect_to :action => 'list_documents', :id => @project
172 172 end
173 173 end
174 174 end
175 175
176 176 # Show documents list of @project
177 177 def list_documents
178 178 @documents = @project.documents
179 179 end
180 180
181 181 # Add a new issue to @project
182 182 def add_issue
183 183 @tracker = Tracker.find(params[:tracker_id])
184 184 @priorities = Enumeration::get_values('IPRI')
185 185 @issue = Issue.new(:project => @project, :tracker => @tracker)
186 186 if request.get?
187 187 @issue.start_date = Date.today
188 188 @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue) }
189 189 else
190 190 @issue.attributes = params[:issue]
191 191 @issue.author_id = self.logged_in_user.id if self.logged_in_user
192 192 # Multiple file upload
193 193 params[:attachments].each { |a|
194 194 @attachment = @issue.attachments.build(:file => a, :author => self.logged_in_user) unless a.size == 0
195 195 } if params[:attachments] and params[:attachments].is_a? Array
196 196 @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]) }
197 197 @issue.custom_values = @custom_values
198 198 if @issue.save
199 199 flash[:notice] = l(:notice_successful_create)
200 200 Mailer.deliver_issue_add(@issue) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
201 201 redirect_to :action => 'list_issues', :id => @project
202 202 end
203 203 end
204 204 end
205 205
206 206 # Show filtered/sorted issues list of @project
207 207 def list_issues
208 208 sort_init 'issues.id', 'desc'
209 209 sort_update
210 210
211 211 search_filter_init_list_issues
212 212 search_filter_update if params[:set_filter]
213 213
214 214 @results_per_page_options = [ 15, 25, 50, 100 ]
215 215 if params[:per_page] and @results_per_page_options.include? params[:per_page].to_i
216 216 @results_per_page = params[:per_page].to_i
217 217 session[:results_per_page] = @results_per_page
218 218 else
219 219 @results_per_page = session[:results_per_page] || 25
220 220 end
221 221
222 222 @issue_count = Issue.count(:include => [:status, :project], :conditions => search_filter_clause)
223 223 @issue_pages = Paginator.new self, @issue_count, @results_per_page, @params['page']
224 224 @issues = Issue.find :all, :order => sort_clause,
225 225 :include => [ :author, :status, :tracker, :project ],
226 226 :conditions => search_filter_clause,
227 227 :limit => @issue_pages.items_per_page,
228 228 :offset => @issue_pages.current.offset
229 229
230 230 render :layout => false if request.xhr?
231 231 end
232 232
233 233 # Export filtered/sorted issues list to CSV
234 234 def export_issues_csv
235 235 sort_init 'issues.id', 'desc'
236 236 sort_update
237 237
238 238 search_filter_init_list_issues
239 239
240 240 @issues = Issue.find :all, :order => sort_clause,
241 241 :include => [ :author, :status, :tracker, :project, :custom_values ],
242 242 :conditions => search_filter_clause
243 243
244 244 ic = Iconv.new('ISO-8859-1', 'UTF-8')
245 245 export = StringIO.new
246 246 CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
247 247 # csv header fields
248 248 headers = [ "#", l(:field_status), l(:field_tracker), l(:field_subject), l(:field_author), l(:field_created_on), l(:field_updated_on) ]
249 249 for custom_field in @project.all_custom_fields
250 250 headers << custom_field.name
251 251 end
252 252 csv << headers.collect {|c| ic.iconv(c) }
253 253 # csv lines
254 254 @issues.each do |issue|
255 255 fields = [issue.id, issue.status.name, issue.tracker.name, issue.subject, issue.author.display_name, l_datetime(issue.created_on), l_datetime(issue.updated_on)]
256 256 for custom_field in @project.all_custom_fields
257 257 fields << (show_value issue.custom_value_for(custom_field))
258 258 end
259 259 csv << fields.collect {|c| ic.iconv(c.to_s) }
260 260 end
261 261 end
262 262 export.rewind
263 263 send_data(export.read, :type => 'text/csv; header=present', :filename => 'export.csv')
264 264 end
265 265
266 266 # Export filtered/sorted issues to PDF
267 267 def export_issues_pdf
268 268 sort_init 'issues.id', 'desc'
269 269 sort_update
270 270
271 271 search_filter_init_list_issues
272 272
273 273 @issues = Issue.find :all, :order => sort_clause,
274 274 :include => [ :author, :status, :tracker, :project, :custom_values ],
275 275 :conditions => search_filter_clause
276 276
277 277 @options_for_rfpdf ||= {}
278 278 @options_for_rfpdf[:file_name] = "export.pdf"
279 279 end
280 280
281 281 def move_issues
282 282 @issues = @project.issues.find(params[:issue_ids]) if params[:issue_ids]
283 283 redirect_to :action => 'list_issues', :id => @project and return unless @issues
284 284 @projects = []
285 285 # find projects to which the user is allowed to move the issue
286 286 @logged_in_user.memberships.each {|m| @projects << m.project if Permission.allowed_to_role("projects/move_issues", m.role_id)}
287 287 # issue can be moved to any tracker
288 288 @trackers = Tracker.find(:all)
289 289 if request.post? and params[:new_project_id] and params[:new_tracker_id]
290 290 new_project = Project.find(params[:new_project_id])
291 291 new_tracker = Tracker.find(params[:new_tracker_id])
292 292 @issues.each { |i|
293 293 # category is project dependent
294 294 i.category = nil unless i.project_id == new_project.id
295 295 # move the issue
296 296 i.project = new_project
297 297 i.tracker = new_tracker
298 298 i.save
299 299 }
300 300 flash[:notice] = l(:notice_successful_update)
301 301 redirect_to :action => 'list_issues', :id => @project
302 302 end
303 303 end
304 304
305 305 # Add a news to @project
306 306 def add_news
307 307 @news = News.new(:project => @project)
308 308 if request.post?
309 309 @news.attributes = params[:news]
310 310 @news.author_id = self.logged_in_user.id if self.logged_in_user
311 311 if @news.save
312 312 flash[:notice] = l(:notice_successful_create)
313 313 redirect_to :action => 'list_news', :id => @project
314 314 end
315 315 end
316 316 end
317 317
318 318 # Show news list of @project
319 319 def list_news
320 320 @news_pages, @news = paginate :news, :per_page => 10, :conditions => ["project_id=?", @project.id], :include => :author, :order => "news.created_on DESC"
321 321 render :action => "list_news", :layout => false if request.xhr?
322 322 end
323 323
324 324 def add_file
325 325 if request.post?
326 326 # Save the attachment
327 327 if params[:attachment][:file].size > 0
328 328 @attachment = @project.versions.find(params[:version_id]).attachments.build(params[:attachment])
329 329 @attachment.author_id = self.logged_in_user.id if self.logged_in_user
330 330 if @attachment.save
331 331 flash[:notice] = l(:notice_successful_create)
332 332 redirect_to :controller => 'projects', :action => 'list_files', :id => @project
333 333 end
334 334 end
335 335 end
336 336 @versions = @project.versions
337 337 end
338 338
339 339 def list_files
340 340 @versions = @project.versions
341 341 end
342 342
343 343 # Show changelog for @project
344 344 def changelog
345 345 @trackers = Tracker.find(:all, :conditions => ["is_in_chlog=?", true])
346 346 if request.get?
347 347 @selected_tracker_ids = @trackers.collect {|t| t.id.to_s }
348 348 else
349 349 @selected_tracker_ids = params[:tracker_ids].collect { |id| id.to_i.to_s } if params[:tracker_ids] and params[:tracker_ids].is_a? Array
350 350 end
351 351 @selected_tracker_ids ||= []
352 352 @fixed_issues = @project.issues.find(:all,
353 353 :include => [ :fixed_version, :status, :tracker ],
354 354 :conditions => [ "issue_statuses.is_closed=? and issues.tracker_id in (#{@selected_tracker_ids.join(',')}) and issues.fixed_version_id is not null", true],
355 355 :order => "versions.effective_date DESC, issues.id DESC"
356 356 ) unless @selected_tracker_ids.empty?
357 357 @fixed_issues ||= []
358 358 end
359 359
360 360 def activity
361 361 if params[:year] and params[:year].to_i > 1900
362 362 @year = params[:year].to_i
363 363 if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
364 364 @month = params[:month].to_i
365 365 end
366 366 end
367 367 @year ||= Date.today.year
368 368 @month ||= Date.today.month
369 369
370 370 @date_from = Date.civil(@year, @month, 1)
371 371 @date_to = (@date_from >> 1)-1
372 372
373 373 @events_by_day = {}
374 374
375 375 unless params[:show_issues] == "0"
376 376 @project.issues.find(:all, :include => [:author, :status], :conditions => ["issues.created_on>=? and issues.created_on<=?", @date_from, @date_to] ).each { |i|
377 377 @events_by_day[i.created_on.to_date] ||= []
378 378 @events_by_day[i.created_on.to_date] << i
379 379 }
380 380 @show_issues = 1
381 381 end
382 382
383 383 unless params[:show_news] == "0"
384 384 @project.news.find(:all, :conditions => ["news.created_on>=? and news.created_on<=?", @date_from, @date_to] ).each { |i|
385 385 @events_by_day[i.created_on.to_date] ||= []
386 386 @events_by_day[i.created_on.to_date] << i
387 387 }
388 388 @show_news = 1
389 389 end
390 390
391 391 unless params[:show_files] == "0"
392 392 Attachment.find(:all, :joins => "LEFT JOIN versions ON versions.id = attachments.container_id", :conditions => ["attachments.container_type='Version' and versions.project_id=? and attachments.created_on>=? and attachments.created_on<=?", @project.id, @date_from, @date_to] ).each { |i|
393 393 @events_by_day[i.created_on.to_date] ||= []
394 394 @events_by_day[i.created_on.to_date] << i
395 395 }
396 396 @show_files = 1
397 397 end
398 398
399 399 unless params[:show_documents] == "0"
400 400 Attachment.find(:all, :joins => "LEFT JOIN documents ON documents.id = attachments.container_id", :conditions => ["attachments.container_type='Document' and documents.project_id=? and attachments.created_on>=? and attachments.created_on<=?", @project.id, @date_from, @date_to] ).each { |i|
401 401 @events_by_day[i.created_on.to_date] ||= []
402 402 @events_by_day[i.created_on.to_date] << i
403 403 }
404 404 @show_documents = 1
405 405 end
406
406
407 render :layout => false if request.xhr?
407 408 end
408 409
409 410 def calendar
410 411 if params[:year] and params[:year].to_i > 1900
411 412 @year = params[:year].to_i
412 413 if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
413 414 @month = params[:month].to_i
414 415 end
415 416 end
416 417 @year ||= Date.today.year
417 418 @month ||= Date.today.month
418 419
419 420 @date_from = Date.civil(@year, @month, 1)
420 421 @date_to = (@date_from >> 1)-1
421 422 # start on monday
422 423 @date_from = @date_from - (@date_from.cwday-1)
423 424 # finish on sunday
424 425 @date_to = @date_to + (7-@date_to.cwday)
425 426
426 427 @issues = @project.issues.find(:all, :include => :tracker, :conditions => ["((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?))", @date_from, @date_to, @date_from, @date_to])
427 428 render :layout => false if request.xhr?
428 429 end
429 430
430 431 def gantt
431 432 if params[:year] and params[:year].to_i >0
432 433 @year_from = params[:year].to_i
433 434 if params[:month] and params[:month].to_i >=1 and params[:month].to_i <= 12
434 435 @month_from = params[:month].to_i
435 436 else
436 437 @month_from = 1
437 438 end
438 439 else
439 440 @month_from ||= (Date.today << 1).month
440 441 @year_from ||= (Date.today << 1).year
441 442 end
442 443
443 444 @zoom = (params[:zoom].to_i > 0 and params[:zoom].to_i < 5) ? params[:zoom].to_i : 2
444 445 @months = (params[:months].to_i > 0 and params[:months].to_i < 25) ? params[:months].to_i : 6
445 446
446 447 @date_from = Date.civil(@year_from, @month_from, 1)
447 448 @date_to = (@date_from >> @months) - 1
448 449 @issues = @project.issues.find(:all, :order => "start_date, due_date", :conditions => ["(((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?) or (start_date<? and due_date>?)) and start_date is not null and due_date is not null)", @date_from, @date_to, @date_from, @date_to, @date_from, @date_to])
449 450
450 451 if params[:output]=='pdf'
451 452 @options_for_rfpdf ||= {}
452 453 @options_for_rfpdf[:file_name] = "gantt.pdf"
453 454 render :template => "projects/gantt.rfpdf", :layout => false
454 455 else
455 456 render :template => "projects/gantt.rhtml"
456 457 end
457 458 end
458 459
459 460 private
460 461 # Find project of id params[:id]
461 462 # if not found, redirect to project list
462 463 # Used as a before_filter
463 464 def find_project
464 465 @project = Project.find(params[:id])
465 466 @html_title = @project.name
466 467 rescue
467 468 redirect_to :action => 'list'
468 469 end
469 470 end
@@ -1,179 +1,183
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 day_name(day)
62 62 l(:general_day_names).split(',')[day-1]
63 63 end
64
65 def month_name(month)
66 l(:actionview_datehelper_select_month_names).split(',')[month-1]
67 end
64 68
65 69 def pagination_links_full(paginator, options={}, html_options={})
66 70 html = ''
67 71 html << link_to_remote(('&#171; ' + l(:label_previous)),
68 72 {:update => "content", :url => { :page => paginator.current.previous }},
69 73 {:href => url_for(:action => 'list', :params => @params.merge({:page => paginator.current.previous}))}) + ' ' if paginator.current.previous
70 74
71 75 html << (pagination_links_each(paginator, options) do |n|
72 76 link_to_remote(n.to_s,
73 77 {:url => {:action => 'list', :params => @params.merge({:page => n})}, :update => 'content'},
74 78 {:href => url_for(:action => 'list', :params => @params.merge({:page => n}))})
75 79 end || '')
76 80
77 81 html << ' ' + link_to_remote((l(:label_next) + ' &#187;'),
78 82 {:update => "content", :url => { :page => paginator.current.next }},
79 83 {:href => url_for(:action => 'list', :params => @params.merge({:page => paginator.current.next}))}) if paginator.current.next
80 84 html
81 85 end
82 86
83 87 def textilizable(text)
84 88 $RDM_TEXTILE_DISABLED ? text : RedCloth.new(text).to_html
85 89 end
86 90
87 91 def error_messages_for(object_name, options = {})
88 92 options = options.symbolize_keys
89 93 object = instance_variable_get("@#{object_name}")
90 94 if object && !object.errors.empty?
91 95 # build full_messages here with controller current language
92 96 full_messages = []
93 97 object.errors.each do |attr, msg|
94 98 next if msg.nil?
95 99 if attr == "base"
96 100 full_messages << l(msg)
97 101 else
98 102 full_messages << "&#171; " + (l_has_string?("field_" + attr) ? l("field_" + attr) : object.class.human_attribute_name(attr)) + " &#187; " + l(msg) unless attr == "custom_values"
99 103 end
100 104 end
101 105 # retrieve custom values error messages
102 106 if object.errors[:custom_values]
103 107 object.custom_values.each do |v|
104 108 v.errors.each do |attr, msg|
105 109 next if msg.nil?
106 110 full_messages << "&#171; " + v.custom_field.name + " &#187; " + l(msg)
107 111 end
108 112 end
109 113 end
110 114 content_tag("div",
111 115 content_tag(
112 116 options[:header_tag] || "h2", lwr(:gui_validation_error, full_messages.length) + " :"
113 117 ) +
114 118 content_tag("ul", full_messages.collect { |msg| content_tag("li", msg) }),
115 119 "id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
116 120 )
117 121 else
118 122 ""
119 123 end
120 124 end
121 125
122 126 def lang_options_for_select
123 127 (GLoc.valid_languages.sort {|x,y| x.to_s <=> y.to_s }).collect {|lang| [ l_lang_name(lang.to_s, lang), lang.to_s]}
124 128 end
125 129
126 130 def label_tag_for(name, option_tags = nil, options = {})
127 131 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
128 132 content_tag("label", label_text)
129 133 end
130 134
131 135 def labelled_tabular_form_for(name, object, options, &proc)
132 136 options[:html] ||= {}
133 137 options[:html].store :class, "tabular"
134 138 form_for(name, object, options.merge({ :builder => TabularFormBuilder, :lang => current_language}), &proc)
135 139 end
136 140
137 141 def check_all_links(form_name)
138 142 link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
139 143 " | " +
140 144 link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
141 145 end
142 146
143 147 def calendar_for(field_id)
144 148 image_tag("calendar", {:id => "#{field_id}_trigger",:class => "calendar-trigger"}) +
145 149 javascript_tag("Calendar.setup({inputField : '#{field_id}', ifFormat : '%Y-%m-%d', button : '#{field_id}_trigger' });")
146 150 end
147 151 end
148 152
149 153 class TabularFormBuilder < ActionView::Helpers::FormBuilder
150 154 include GLoc
151 155
152 156 def initialize(object_name, object, template, options, proc)
153 157 set_language_if_valid options.delete(:lang)
154 158 @object_name, @object, @template, @options, @proc = object_name, object, template, options, proc
155 159 end
156 160
157 161 (field_helpers - %w(radio_button hidden_field) + %w(date_select)).each do |selector|
158 162 src = <<-END_SRC
159 163 def #{selector}(field, options = {})
160 164 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
161 165 label = @template.content_tag("label", label_text,
162 166 :class => (@object.errors[field] ? "error" : nil),
163 167 :for => (@object_name.to_s + "_" + field.to_s))
164 168 label + super
165 169 end
166 170 END_SRC
167 171 class_eval src, __FILE__, __LINE__
168 172 end
169 173
170 174 def select(field, choices, options = {})
171 175 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
172 176 label = @template.content_tag("label", label_text,
173 177 :class => (@object.errors[field] ? "error" : nil),
174 178 :for => (@object_name.to_s + "_" + field.to_s))
175 179 label + super
176 180 end
177 181
178 182 end
179 183
@@ -1,41 +1,54
1 <h2><%=l(:label_activity)%></h2>
1 <h2><%=l(:label_activity)%>: <%= "#{month_name(@month).downcase} #{@year}" %></h2>
2 2
3 3 <div>
4 4 <div class="rightbox">
5 5 <%= start_form_tag %>
6 6 <p><%= select_month(@month, :prefix => "month", :discard_type => true) %>
7 7 <%= select_year(@year, :prefix => "year", :discard_type => true) %></p>
8 8 <%= check_box_tag 'show_issues', 1, @show_issues %><%= hidden_field_tag 'show_issues', 0 %> <%=l(:label_issue_plural)%><br />
9 9 <%= check_box_tag 'show_news', 1, @show_news %><%= hidden_field_tag 'show_news', 0 %> <%=l(:label_news_plural)%><br />
10 10 <%= check_box_tag 'show_files', 1, @show_files %><%= hidden_field_tag 'show_files', 0 %> <%=l(:label_attachment_plural)%><br />
11 11 <%= check_box_tag 'show_documents', 1, @show_documents %><%= hidden_field_tag 'show_documents', 0 %> <%=l(:label_document_plural)%><br />
12 12 <p><center><%= submit_tag l(:button_apply), :class => 'button-small' %></center></p>
13 13 <%= end_form_tag %>
14 14 </div>
15 15 <% @events_by_day.keys.sort {|x,y| y <=> x }.each do |day| %>
16 <h3><%= day_name(day.cwday) %> <%= format_date(day) %></h3>
16 <h3><%= day_name(day.cwday) %> <%= day.day %></h3>
17 17 <ul>
18 18 <% @events_by_day[day].sort {|x,y| y.created_on <=> x.created_on }.each do |e| %>
19 19 <li><p>
20 20 <% if e.is_a? Issue %>
21 21 <%= e.created_on.strftime("%H:%M") %> <%= link_to "#{e.tracker.name} ##{e.id}", :controller => 'issues', :action => 'show', :id => e %> (<%= e.status.name %>): <%= e.subject %><br />
22 22 <i><%= e.author.name %></i>
23 23 <% elsif e.is_a? News %>
24 24 <%= e.created_on.strftime("%H:%M") %> <%=l(:label_news)%>: <%= link_to e.title, :controller => 'news', :action => 'show', :id => e %><br />
25 25 <% unless e.summary.empty? %><%= e.summary %><br /><% end %>
26 26 <i><%= e.author.name %></i>
27 27 <% elsif (e.is_a? Attachment) and (e.container.is_a? Version) %>
28 28 <%= e.created_on.strftime("%H:%M") %> <%=l(:label_attachment)%> (Version <%= e.container.name %>): <%= link_to e.filename, :controller => 'projects', :action => 'list_files', :id => @project %><br />
29 29 <i><%= e.author.name %></i>
30 30 <% elsif (e.is_a? Attachment) and (e.container.is_a? Document) %>
31 31 <%= e.created_on.strftime("%H:%M") %> <%=l(:label_document)%>: <%= link_to e.container.title, :controller => 'documents', :action => 'show', :id => e %><br />
32 32 <i><%= e.author.name %></i>
33 33 <% end %>
34 34 </p></li>
35 35
36 36 <% end %>
37 37 </ul>
38 38 <% end %>
39 39 <% if @events_by_day.empty? %><p><i><%= l(:label_no_data) %></i></p><% end %>
40
41 <div style="float:left;">
42 <%= link_to_remote ('&#171; ' + (@month==1 ? "#{month_name(12)} #{@year-1}" : "#{month_name(@month-1)}")),
43 {:update => "content", :url => { :year => (@month==1 ? @year-1 : @year), :month =>(@month==1 ? 12 : @month-1) }},
44 {:href => url_for(:action => 'activity', :year => (@month==1 ? @year-1 : @year), :month =>(@month==1 ? 12 : @month-1))}
45 %>
46 </div>
47 <div style="float:right;">
48 <%= link_to_remote ((@month==12 ? "#{month_name(1)} #{@year+1}" : "#{month_name(@month+1)}") + ' &#187;'),
49 {:update => "content", :url => { :year => (@month==12 ? @year+1 : @year), :month =>(@month==12 ? 1 : @month+1) }},
50 {:href => url_for(:action => 'activity', :year => (@month==12 ? @year+1 : @year), :month =>(@month==12 ? 1 : @month+1))}
51 %>&nbsp;
52 </div>
40 53 <br />
41 54 </div> No newline at end of file
@@ -1,75 +1,75
1 1 <h2><%= l(:label_calendar) %></h2>
2 2
3 3 <table width="100%">
4 4 <tr>
5 5 <td align="left">
6 6 <%= start_form_tag :action => 'calendar', :id => @project %>
7 7 <%= select_month(@month, :prefix => "month", :discard_type => true) %>
8 8 <%= select_year(@year, :prefix => "year", :discard_type => true) %>
9 9 <%= submit_tag l(:button_submit), :class => "button-small" %>
10 10 <%= end_form_tag %>
11 11 </td>
12 12 <td align="right">
13 13 <%= image_tag 'gantt' %>
14 14 <%= link_to l(:label_gantt_chart), :action => 'gantt', :id => @project %>&nbsp;
15 15 </td>
16 16 </tr>
17 17 </table>
18 18 <br />
19 19
20 20 <table class="calenderTable">
21 21 <tr class="ListHead">
22 22 <td></td>
23 23 <% 1.upto(7) do |d| %>
24 24 <td align="center" width="14%"><%= day_name(d) %></td>
25 25 <% end %>
26 26 </tr>
27 27 <tr height="100">
28 28 <% day = @date_from
29 29 while day <= @date_to
30 30 if day.cwday == 1 %>
31 31 <td valign="middle"><%= day.cweek %></td>
32 32 <% end %>
33 33 <td valign="top" width="14%" class="<%= day.month==@month ? "even" : "odd" %>">
34 34 <p align="right"><%= day==Date.today ? "<b>#{day.day}</b>" : day.day %></p>
35 35 <% day_issues = []
36 36 @issues.each { |i| day_issues << i if i.start_date == day or i.due_date == day }
37 37 day_issues.each do |i| %>
38 38 <%= if day == i.start_date and day == i.due_date
39 39 image_tag('arrow_bw')
40 40 elsif day == i.start_date
41 41 image_tag('arrow_from')
42 42 elsif day == i.due_date
43 43 image_tag('arrow_to')
44 44 end %>
45 45 <small><%= link_to "#{i.tracker.name} ##{i.id}", :controller => 'issues', :action => 'show', :id => i %>: <%= i.subject.sub(/^(.{30}[^\s]*\s).*$/, '\1 (...)') %></small><br />
46 46 <% end %>
47 47 </td>
48 48 <%= '</tr><tr height="100">' if day.cwday >= 7 and day!=@date_to %>
49 49 <%
50 50 day = day + 1
51 51 end %>
52 52 </tr>
53 53 </table>
54 54
55 55 <table width="100%">
56 56 <tr>
57 57 <td align="left">
58 <%= link_to_remote ('&#171; ' + l(:label_previous)),
58 <%= link_to_remote ('&#171; ' + (@month==1 ? "#{month_name(12)} #{@year-1}" : "#{month_name(@month-1)}")),
59 59 {:update => "content", :url => { :year => (@month==1 ? @year-1 : @year), :month =>(@month==1 ? 12 : @month-1) }},
60 60 {:href => url_for(:action => 'calendar', :year => (@month==1 ? @year-1 : @year), :month =>(@month==1 ? 12 : @month-1))}
61 61 %>
62 62 </td>
63 63 <td align="right">
64 <%= link_to_remote (l(:label_next) + ' &#187;'),
64 <%= link_to_remote ((@month==12 ? "#{month_name(1)} #{@year+1}" : "#{month_name(@month+1)}") + ' &#187;'),
65 65 {:update => "content", :url => { :year => (@month==12 ? @year+1 : @year), :month =>(@month==12 ? 1 : @month+1) }},
66 66 {:href => url_for(:action => 'calendar', :year => (@month==12 ? @year+1 : @year), :month =>(@month==12 ? 1 : @month+1))}
67 67 %>
68 68 &nbsp;
69 69 </td>
70 70 </tr>
71 71 </table>
72 72 <br />
73 73 <%= image_tag 'arrow_from' %>&nbsp;&nbsp;<%= l(:text_tip_task_begin_day) %><br />
74 74 <%= image_tag 'arrow_to' %>&nbsp;&nbsp;<%= l(:text_tip_task_end_day) %><br />
75 75 <%= image_tag 'arrow_bw' %>&nbsp;&nbsp;<%= l(:text_tip_task_begin_end_day) %><br /> No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now