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