@@ -0,0 +1,43 | |||||
|
1 | # redMine - project management software | |||
|
2 | # Copyright (C) 2006 Jean-Philippe Lang | |||
|
3 | # | |||
|
4 | # This program is free software; you can redistribute it and/or | |||
|
5 | # modify it under the terms of the GNU General Public License | |||
|
6 | # as published by the Free Software Foundation; either version 2 | |||
|
7 | # of the License, or (at your option) any later version. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
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 | |||
|
16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
|
17 | ||||
|
18 | require 'iconv' | |||
|
19 | ||||
|
20 | module IfpdfHelper | |||
|
21 | ||||
|
22 | class IFPDF < FPDF | |||
|
23 | ||||
|
24 | def Cell(w,h=0,txt='',border=0,ln=0,align='',fill=0,link='') | |||
|
25 | @ic ||= Iconv.new('ISO-8859-1', 'UTF-8') | |||
|
26 | super w,h,@ic.iconv(txt),border,ln,align,fill,link | |||
|
27 | end | |||
|
28 | ||||
|
29 | def MultiCell(w,h,txt,border=0,align='J',fill=0) | |||
|
30 | @ic ||= Iconv.new('ISO-8859-1', 'UTF-8') | |||
|
31 | super w,h,txt,border,align,fill | |||
|
32 | end | |||
|
33 | ||||
|
34 | def Footer | |||
|
35 | SetY(-15) | |||
|
36 | SetX(-30) | |||
|
37 | SetFont('Helvetica', 'I', 8) | |||
|
38 | Cell(0, 5, PageNo().to_s + '/{nb}', 0, 0, 'C') | |||
|
39 | end | |||
|
40 | ||||
|
41 | end | |||
|
42 | ||||
|
43 | end |
@@ -0,0 +1,95 | |||||
|
1 | <% pdf.SetFont('Arial','B',11) | |||
|
2 | pdf.Cell(190,10, "#{issue.project.name} - #{issue.tracker.name} # #{issue.long_id} - #{issue.subject}") | |||
|
3 | pdf.Ln | |||
|
4 | ||||
|
5 | y0 = pdf.GetY | |||
|
6 | ||||
|
7 | pdf.SetFont('Arial','B',9) | |||
|
8 | pdf.Cell(35,5, l(:field_status) + ":","LT") | |||
|
9 | pdf.SetFont('Arial','',9) | |||
|
10 | pdf.Cell(60,5, issue.status.name,"RT") | |||
|
11 | pdf.SetFont('Arial','B',9) | |||
|
12 | pdf.Cell(35,5, l(:field_priority) + ":","LT") | |||
|
13 | pdf.SetFont('Arial','',9) | |||
|
14 | pdf.Cell(60,5, issue.priority.name,"RT") | |||
|
15 | pdf.Ln | |||
|
16 | ||||
|
17 | pdf.SetFont('Arial','B',9) | |||
|
18 | pdf.Cell(35,5, l(:field_author) + ":","L") | |||
|
19 | pdf.SetFont('Arial','',9) | |||
|
20 | pdf.Cell(60,5, issue.author.name,"R") | |||
|
21 | pdf.SetFont('Arial','B',9) | |||
|
22 | pdf.Cell(35,5, l(:field_category) + ":","L") | |||
|
23 | pdf.SetFont('Arial','',9) | |||
|
24 | pdf.Cell(60,5, (issue.category ? issue.category.name : "-"),"R") | |||
|
25 | pdf.Ln | |||
|
26 | ||||
|
27 | pdf.SetFont('Arial','B',9) | |||
|
28 | pdf.Cell(35,5, l(:field_created_on) + ":","L") | |||
|
29 | pdf.SetFont('Arial','',9) | |||
|
30 | pdf.Cell(60,5, format_date(issue.created_on),"R") | |||
|
31 | pdf.SetFont('Arial','B',9) | |||
|
32 | pdf.Cell(35,5, l(:field_assigned_to) + ":","L") | |||
|
33 | pdf.SetFont('Arial','',9) | |||
|
34 | pdf.Cell(60,5, (issue.assigned_to ? issue.assigned_to.name : "-"),"R") | |||
|
35 | pdf.Ln | |||
|
36 | ||||
|
37 | pdf.SetFont('Arial','B',9) | |||
|
38 | pdf.Cell(35,5, l(:field_updated_on) + ":","LB") | |||
|
39 | pdf.SetFont('Arial','',9) | |||
|
40 | pdf.Cell(60,5, format_date(issue.updated_on),"RB") | |||
|
41 | pdf.SetFont('Arial','B',9) | |||
|
42 | pdf.Cell(35,5, l(:field_due_date) + ":","LB") | |||
|
43 | pdf.SetFont('Arial','',9) | |||
|
44 | pdf.Cell(60,5, format_date(issue.due_date),"RB") | |||
|
45 | pdf.Ln | |||
|
46 | ||||
|
47 | for custom_value in issue.custom_values | |||
|
48 | pdf.SetFont('Arial','B',9) | |||
|
49 | pdf.Cell(35,5, custom_value.custom_field.name + ":","L") | |||
|
50 | pdf.SetFont('Arial','',9) | |||
|
51 | pdf.MultiCell(155,5, (show_value custom_value),"R") | |||
|
52 | end | |||
|
53 | ||||
|
54 | pdf.SetFont('Arial','B',9) | |||
|
55 | pdf.Cell(35,5, l(:field_subject) + ":","LTB") | |||
|
56 | pdf.SetFont('Arial','',9) | |||
|
57 | pdf.Cell(155,5, issue.subject,"RTB") | |||
|
58 | pdf.Ln | |||
|
59 | ||||
|
60 | pdf.SetFont('Arial','B',9) | |||
|
61 | pdf.Cell(35,5, l(:field_description) + ":") | |||
|
62 | pdf.SetFont('Arial','',9) | |||
|
63 | pdf.MultiCell(155,5, issue.description,"BR") | |||
|
64 | ||||
|
65 | pdf.Line(pdf.GetX, y0, pdf.GetX, pdf.GetY) | |||
|
66 | pdf.Line(pdf.GetX, pdf.GetY, 170, pdf.GetY) | |||
|
67 | ||||
|
68 | pdf.Ln | |||
|
69 | pdf.SetFont('Arial','B',9) | |||
|
70 | pdf.Cell(190,5, l(:label_history),"B") | |||
|
71 | pdf.Ln | |||
|
72 | for history in issue.histories.find(:all, :include => [:author, :status]) | |||
|
73 | pdf.SetFont('Arial','B',8) | |||
|
74 | pdf.Cell(100,5, history.status.name) | |||
|
75 | pdf.SetFont('Arial','',8) | |||
|
76 | pdf.Cell(20,5, format_date(history.created_on)) | |||
|
77 | pdf.Cell(70,5, history.author.name,0,0,"R") | |||
|
78 | pdf.SetFont('Arial','',8) | |||
|
79 | pdf.Ln | |||
|
80 | pdf.Cell(10,4, "") and pdf.MultiCell(180,4, history.notes) if history.notes? | |||
|
81 | end | |||
|
82 | pdf.Ln | |||
|
83 | ||||
|
84 | pdf.SetFont('Arial','B',9) | |||
|
85 | pdf.Cell(190,5, l(:label_attachment_plural), "B") | |||
|
86 | pdf.Ln | |||
|
87 | for attachment in issue.attachments | |||
|
88 | pdf.SetFont('Arial','',8) | |||
|
89 | pdf.Cell(80,5, attachment.filename) | |||
|
90 | pdf.Cell(20,5, human_size(attachment.filesize)) | |||
|
91 | pdf.Cell(20,5, format_date(attachment.created_on)) | |||
|
92 | pdf.Cell(70,5, attachment.author.name,0,0,"R") | |||
|
93 | pdf.Ln | |||
|
94 | end | |||
|
95 | %> No newline at end of file |
@@ -0,0 +1,8 | |||||
|
1 | <% pdf=IfpdfHelper::IFPDF.new | |||
|
2 | pdf.AliasNbPages | |||
|
3 | pdf.AddPage | |||
|
4 | ||||
|
5 | render :partial => 'issues/pdf', :locals => { :pdf => pdf, :issue => @issue } | |||
|
6 | %> | |||
|
7 | ||||
|
8 | <%= pdf.Output %> No newline at end of file |
@@ -0,0 +1,3 | |||||
|
1 | Issue #<%= @issue.id %> has been reported. | |||
|
2 | ---------------------------------------- | |||
|
3 | <%= render :file => "_issue", :use_full_path => true, :locals => { :issue => @issue } %> No newline at end of file |
@@ -0,0 +1,3 | |||||
|
1 | Issue #<%= @issue.id %> has been reported. | |||
|
2 | ---------------------------------------- | |||
|
3 | <%= render :file => "_issue", :use_full_path => true, :locals => { :issue => @issue } %> No newline at end of file |
@@ -0,0 +1,3 | |||||
|
1 | Issue #<%= @issue.id %> has been updated to "<%= @issue.status.name %>" status. | |||
|
2 | ---------------------------------------- | |||
|
3 | <%= render :file => "_issue", :use_full_path => true, :locals => { :issue => @issue } %> No newline at end of file |
@@ -0,0 +1,3 | |||||
|
1 | Issue #<%= @issue.id %> has been updated to "<%= @issue.status.name %>" status. | |||
|
2 | ---------------------------------------- | |||
|
3 | <%= render :file => "_issue", :use_full_path => true, :locals => { :issue => @issue } %> No newline at end of file |
@@ -0,0 +1,3 | |||||
|
1 | To change your password, use the following link: | |||
|
2 | ||||
|
3 | http://<%= $RDM_HOST_NAME %>/account/lost_password?token=<%= @token.value %> No newline at end of file |
@@ -0,0 +1,3 | |||||
|
1 | To change your password, use the following link: | |||
|
2 | ||||
|
3 | http://<%= $RDM_HOST_NAME %>/account/lost_password?token=<%= @token.value %> No newline at end of file |
@@ -0,0 +1,3 | |||||
|
1 | To activate your redMine account, use the following link: | |||
|
2 | ||||
|
3 | http://<%= $RDM_HOST_NAME %>/account/register?token=<%= @token.value %> No newline at end of file |
@@ -0,0 +1,3 | |||||
|
1 | To activate your redMine account, use the following link: | |||
|
2 | ||||
|
3 | http://<%= $RDM_HOST_NAME %>/account/register?token=<%= @token.value %> No newline at end of file |
@@ -0,0 +1,10 | |||||
|
1 | <% pdf=IfpdfHelper::IFPDF.new | |||
|
2 | pdf.AliasNbPages | |||
|
3 | pdf.AddPage | |||
|
4 | @issues.each {|i| | |||
|
5 | render :partial => 'issues/pdf', :locals => { :pdf => pdf, :issue => i } | |||
|
6 | pdf.AddPage | |||
|
7 | } | |||
|
8 | %> | |||
|
9 | ||||
|
10 | <%= pdf.Output %> No newline at end of file |
@@ -0,0 +1,11 | |||||
|
1 | class ExportPdf < ActiveRecord::Migration | |||
|
2 | def self.up | |||
|
3 | Permission.create :controller => "projects", :action => "export_issues_pdf", :description => "label_export_pdf", :sort => 1002, :is_public => true, :mail_option => 0, :mail_enabled => 0 | |||
|
4 | Permission.create :controller => "issues", :action => "export_pdf", :description => "label_export_pdf", :sort => 1015, :is_public => true, :mail_option => 0, :mail_enabled => 0 | |||
|
5 | end | |||
|
6 | ||||
|
7 | def self.down | |||
|
8 | Permission.find(:first, :conditions => ["controller=? and action=?", 'projects', 'export_issues_pdf']).destroy | |||
|
9 | Permission.find(:first, :conditions => ["controller=? and action=?", 'issues', 'export_pdf']).destroy | |||
|
10 | end | |||
|
11 | end |
@@ -88,7 +88,7 class ApplicationController < ActionController::Base | |||||
88 | render :nothing => true, :status => 403 |
|
88 | render :nothing => true, :status => 403 | |
89 | false |
|
89 | false | |
90 | end |
|
90 | end | |
91 |
|
91 | |||
92 | # store current uri in session. |
|
92 | # store current uri in session. | |
93 | # return to this location by calling redirect_back_or_default |
|
93 | # return to this location by calling redirect_back_or_default | |
94 | def store_location |
|
94 | def store_location |
@@ -16,15 +16,23 | |||||
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 IssuesController < ApplicationController |
|
18 | class IssuesController < ApplicationController | |
19 | layout 'base' |
|
19 | layout 'base', :except => :export_pdf | |
20 | before_filter :find_project, :authorize |
|
20 | before_filter :find_project, :authorize | |
21 |
|
21 | |||
22 | helper :custom_fields |
|
22 | helper :custom_fields | |
23 | include CustomFieldsHelper |
|
23 | include CustomFieldsHelper | |
|
24 | helper :ifpdf | |||
|
25 | include IfpdfHelper | |||
24 |
|
26 | |||
25 | def show |
|
27 | def show | |
26 | @status_options = @issue.status.workflows.find(:all, :include => :new_status, :conditions => ["role_id=? and tracker_id=?", self.logged_in_user.role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if self.logged_in_user |
|
28 | @status_options = @issue.status.workflows.find(:all, :include => :new_status, :conditions => ["role_id=? and tracker_id=?", self.logged_in_user.role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if self.logged_in_user | |
27 | @custom_values = @issue.custom_values.find(:all, :include => :custom_field) |
|
29 | @custom_values = @issue.custom_values.find(:all, :include => :custom_field) | |
|
30 | end | |||
|
31 | ||||
|
32 | def export_pdf | |||
|
33 | @custom_values = @issue.custom_values.find(:all, :include => :custom_field) | |||
|
34 | @options_for_rfpdf ||= {} | |||
|
35 | @options_for_rfpdf[:file_name] = "#{@project.name}_#{@issue.long_id}.pdf" | |||
28 | end |
|
36 | end | |
29 |
|
37 | |||
30 | def edit |
|
38 | def edit |
@@ -16,7 +16,7 | |||||
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' |
|
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 | |||
@@ -26,7 +26,9 class ProjectsController < ApplicationController | |||||
26 | include SearchFilterHelper |
|
26 | include SearchFilterHelper | |
27 | helper :custom_fields |
|
27 | helper :custom_fields | |
28 | include CustomFieldsHelper |
|
28 | include CustomFieldsHelper | |
29 |
|
29 | helper :ifpdf | ||
|
30 | include IfpdfHelper | |||
|
31 | ||||
30 | def index |
|
32 | def index | |
31 | list |
|
33 | list | |
32 | render :action => 'list' unless request.xhr? |
|
34 | render :action => 'list' unless request.xhr? | |
@@ -208,15 +210,23 class ProjectsController < ApplicationController | |||||
208 | search_filter_init_list_issues |
|
210 | search_filter_init_list_issues | |
209 | search_filter_update if params[:set_filter] |
|
211 | search_filter_update if params[:set_filter] | |
210 |
|
212 | |||
|
213 | @results_per_page_options = [ 15, 25, 50, 100 ] | |||
|
214 | if params[:per_page] and @results_per_page_options.include? params[:per_page].to_i | |||
|
215 | @results_per_page = params[:per_page].to_i | |||
|
216 | session[:results_per_page] = @results_per_page | |||
|
217 | else | |||
|
218 | @results_per_page = session[:results_per_page] || @results_per_page_options.first | |||
|
219 | end | |||
|
220 | ||||
211 | @issue_count = Issue.count(:include => [:status, :project], :conditions => search_filter_clause) |
|
221 | @issue_count = Issue.count(:include => [:status, :project], :conditions => search_filter_clause) | |
212 |
@issue_pages = Paginator.new self, @issue_count, |
|
222 | @issue_pages = Paginator.new self, @issue_count, @results_per_page, @params['page'] | |
213 | @issues = Issue.find :all, :order => sort_clause, |
|
223 | @issues = Issue.find :all, :order => sort_clause, | |
214 | :include => [ :author, :status, :tracker, :project ], |
|
224 | :include => [ :author, :status, :tracker, :project ], | |
215 | :conditions => search_filter_clause, |
|
225 | :conditions => search_filter_clause, | |
216 | :limit => @issue_pages.items_per_page, |
|
226 | :limit => @issue_pages.items_per_page, | |
217 | :offset => @issue_pages.current.offset |
|
227 | :offset => @issue_pages.current.offset | |
218 |
|
228 | |||
219 |
render |
|
229 | render :layout => false if request.xhr? | |
220 | end |
|
230 | end | |
221 |
|
231 | |||
222 | # Export filtered/sorted issues list to CSV |
|
232 | # Export filtered/sorted issues list to CSV | |
@@ -227,20 +237,44 class ProjectsController < ApplicationController | |||||
227 | search_filter_init_list_issues |
|
237 | search_filter_init_list_issues | |
228 |
|
238 | |||
229 | @issues = Issue.find :all, :order => sort_clause, |
|
239 | @issues = Issue.find :all, :order => sort_clause, | |
230 | :include => [ :author, :status, :tracker, :project ], |
|
240 | :include => [ :author, :status, :tracker, :project, :custom_values ], | |
231 | :conditions => search_filter_clause |
|
241 | :conditions => search_filter_clause | |
232 |
|
242 | |||
|
243 | ic = Iconv.new('ISO-8859-1', 'UTF-8') | |||
233 | export = StringIO.new |
|
244 | export = StringIO.new | |
234 |
CSV::Writer.generate(export, |
|
245 | CSV::Writer.generate(export, l(:general_csv_separator)) do |csv| | |
235 | csv << %w(Id Status Tracker Subject Author Created Updated) |
|
246 | # csv header fields | |
|
247 | headers = [ "#", l(:field_status), l(:field_tracker), l(:field_subject), l(:field_author), l(:field_created_on), l(:field_updated_on) ] | |||
|
248 | for custom_field in @project.all_custom_fields | |||
|
249 | headers << custom_field.name | |||
|
250 | end | |||
|
251 | csv << headers.collect {|c| ic.iconv(c) } | |||
|
252 | # csv lines | |||
236 | @issues.each do |issue| |
|
253 | @issues.each do |issue| | |
237 |
|
|
254 | 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 | for custom_field in @project.all_custom_fields | |||
|
256 | fields << (show_value issue.custom_value_for(custom_field)) | |||
|
257 | end | |||
|
258 | csv << fields.collect {|c| ic.iconv(c.to_s) } | |||
238 | end |
|
259 | end | |
239 | end |
|
260 | end | |
240 | export.rewind |
|
261 | export.rewind | |
241 | send_data(export.read, |
|
262 | send_data(export.read, :type => 'text/csv; header=present', :filename => 'export.csv') | |
242 | :type => 'text/csv; charset=utf-8; header=present', |
|
263 | end | |
243 | :filename => 'export.csv') |
|
264 | ||
|
265 | # Export filtered/sorted issues to PDF | |||
|
266 | def export_issues_pdf | |||
|
267 | sort_init 'issues.id', 'desc' | |||
|
268 | sort_update | |||
|
269 | ||||
|
270 | search_filter_init_list_issues | |||
|
271 | ||||
|
272 | @issues = Issue.find :all, :order => sort_clause, | |||
|
273 | :include => [ :author, :status, :tracker, :project, :custom_values ], | |||
|
274 | :conditions => search_filter_clause | |||
|
275 | ||||
|
276 | @options_for_rfpdf ||= {} | |||
|
277 | @options_for_rfpdf[:file_name] = "export.pdf" | |||
244 | end |
|
278 | end | |
245 |
|
279 | |||
246 | def move_issues |
|
280 | def move_issues |
@@ -49,7 +49,7 module ApplicationHelper | |||||
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 | |
@@ -57,7 +57,7 module ApplicationHelper | |||||
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 pagination_links_full(paginator, options={}, html_options={}) |
|
61 | def pagination_links_full(paginator, options={}, html_options={}) | |
62 | html = '' |
|
62 | html = '' | |
63 | html << link_to_remote(('« ' + l(:label_previous)), |
|
63 | html << link_to_remote(('« ' + l(:label_previous)), |
@@ -53,9 +53,11 module CustomFieldsHelper | |||||
53 |
|
53 | |||
54 | # Return a string used to display a custom value |
|
54 | # Return a string used to display a custom value | |
55 | def show_value(custom_value) |
|
55 | def show_value(custom_value) | |
|
56 | return "" unless custom_value | |||
|
57 | ||||
56 | case custom_value.custom_field.field_format |
|
58 | case custom_value.custom_field.field_format | |
57 | when "date" |
|
59 | when "date" | |
58 |
|
|
60 | l_date(custom_value.value.to_date) if custom_value.value | |
59 | when "bool" |
|
61 | when "bool" | |
60 | l_YesNo(custom_value.value == "1") |
|
62 | l_YesNo(custom_value.value == "1") | |
61 | else |
|
63 | else |
@@ -86,6 +86,11 module SearchFilterHelper | |||||
86 | ] + @project.versions.collect {|s| [s.name, s.id, ["issues.fixed_version_id=?", s.id]] } |
|
86 | ] + @project.versions.collect {|s| [s.name, s.id, ["issues.fixed_version_id=?", s.id]] } | |
87 | } |
|
87 | } | |
88 |
|
88 | |||
|
89 | search_filter_criteria('author_id') { | |||
|
90 | [ [('['+l(:label_all)+']'), "A", nil], | |||
|
91 | ] + @project.users.collect {|s| [s.display_name, s.id, ["issues.author_id=?", s.id]] } | |||
|
92 | } | |||
|
93 | ||||
89 | search_filter_criteria('assigned_to_id') { |
|
94 | search_filter_criteria('assigned_to_id') { | |
90 | [ [('['+l(:label_all)+']'), "A", nil], |
|
95 | [ [('['+l(:label_all)+']'), "A", nil], | |
91 | [('['+l(:label_none)+']'), "N", ["issues.assigned_to_id is null"]] |
|
96 | [('['+l(:label_none)+']'), "N", ["issues.assigned_to_id is null"]] |
@@ -29,6 +29,10 class Enumeration < ActiveRecord::Base | |||||
29 | def self.get_values(option) |
|
29 | def self.get_values(option) | |
30 | find(:all, :conditions => ['opt=?', option]) |
|
30 | find(:all, :conditions => ['opt=?', option]) | |
31 | end |
|
31 | end | |
|
32 | ||||
|
33 | def option_name | |||
|
34 | OPTIONS[self.opt] | |||
|
35 | end | |||
32 |
|
36 | |||
33 | private |
|
37 | private | |
34 | def check_integrity |
|
38 | def check_integrity |
@@ -53,6 +53,11 class Issue < ActiveRecord::Base | |||||
53 | def long_id |
|
53 | def long_id | |
54 | "%05d" % self.id |
|
54 | "%05d" % self.id | |
55 | end |
|
55 | end | |
|
56 | ||||
|
57 | def custom_value_for(custom_field) | |||
|
58 | self.custom_values.each {|v| return v if v.custom_field_id == custom_field.id } | |||
|
59 | return nil | |||
|
60 | end | |||
56 |
|
61 | |||
57 | private |
|
62 | private | |
58 | # Creates an history for the issue |
|
63 | # Creates an history for the issue |
@@ -43,6 +43,11 class Project < ActiveRecord::Base | |||||
43 | :conditions => ["is_for_all=? or project_id=?", true, self.id]) |
|
43 | :conditions => ["is_for_all=? or project_id=?", true, self.id]) | |
44 | #(CustomField.for_all + custom_fields).uniq |
|
44 | #(CustomField.for_all + custom_fields).uniq | |
45 | end |
|
45 | end | |
|
46 | ||||
|
47 | def all_custom_fields | |||
|
48 | @all_custom_fields ||= IssueCustomField.find(:all, :include => :projects, | |||
|
49 | :conditions => ["is_for_all=? or project_id=?", true, self.id]) | |||
|
50 | end | |||
46 |
|
51 | |||
47 | protected |
|
52 | protected | |
48 | def validate |
|
53 | def validate |
@@ -18,7 +18,7 | |||||
18 |
|
18 | |||
19 | <br /><br /> |
|
19 | <br /><br /> | |
20 |
|
20 | |||
21 |
<table class=" |
|
21 | <table class="reportTableContent"> | |
22 | <% for attachment in @attachments %> |
|
22 | <% for attachment in @attachments %> | |
23 | <tr class="<%= cycle("odd", "even") %>"> |
|
23 | <tr class="<%= cycle("odd", "even") %>"> | |
24 | <td><%= format_date(attachment.created_on) %></td> |
|
24 | <td><%= format_date(attachment.created_on) %></td> |
@@ -1,4 +1,4 | |||||
1 | <h2><%=l(:label_enumeration_new)%></h2> |
|
1 | <h2><%= l(@enumeration.option_name) %>: <%=l(:label_enumeration_new)%></h2> | |
2 |
|
2 | |||
3 | <%= start_form_tag({:action => 'create'}, :class => "tabular") %> |
|
3 | <%= start_form_tag({:action => 'create'}, :class => "tabular") %> | |
4 | <%= render :partial => 'form' %> |
|
4 | <%= render :partial => 'form' %> |
@@ -1,4 +1,9 | |||||
1 | <h2><%= @issue.tracker.name %> #<%= @issue.id %> - <%= @issue.subject %></h2> |
|
1 | <h2><%= @issue.tracker.name %> #<%= @issue.id %> - <%= @issue.subject %></h2> | |
|
2 | <div class="topright"> | |||
|
3 | <small> | |||
|
4 | <%= link_to 'PDF', :action => 'export_pdf', :id => @issue %> | |||
|
5 | </small> | |||
|
6 | </div> | |||
2 |
|
7 | |||
3 | <div class="box"> |
|
8 | <div class="box"> | |
4 | <p> |
|
9 | <p> | |
@@ -7,15 +12,18 | |||||
7 | <b><%=l(:field_assigned_to)%> :</b> <%= @issue.assigned_to ? @issue.assigned_to.display_name : "-" %>     |
|
12 | <b><%=l(:field_assigned_to)%> :</b> <%= @issue.assigned_to ? @issue.assigned_to.display_name : "-" %>     | |
8 | <b><%=l(:field_category)%> :</b> <%= @issue.category ? @issue.category.name : "-" %> |
|
13 | <b><%=l(:field_category)%> :</b> <%= @issue.category ? @issue.category.name : "-" %> | |
9 | </p> |
|
14 | </p> | |
10 | <p><b><%=l(:field_author)%> :</b> <%= @issue.author.display_name %></p> |
|
15 | <div class="tabular"> | |
11 |
<p><b><%=l(:field_ |
|
16 | <p><label><%=l(:field_author)%> :</label> <%= link_to_user @issue.author %> </p> | |
12 |
<p><b><%=l(:field_ |
|
17 | <p><label><%=l(:field_created_on)%> :</label> <%= format_date(@issue.created_on) %> </p> | |
13 |
<p><b><%=l(:field_ |
|
18 | <p><label><%=l(:field_subject)%> :</label> <%= @issue.subject %> </p> | |
14 | <p><b><%=l(:field_created_on)%> :</b> <%= format_date(@issue.created_on) %></p> |
|
19 | <%= simple_format ("<label>" + l(:field_description) + ": </label>" + auto_link(@issue.description)) %> | |
|
20 | <p><label><%=l(:field_due_date)%> :</label> <%= format_date(@issue.due_date) %> </p> | |||
15 |
|
21 | |||
16 | <% for custom_value in @custom_values %> |
|
22 | <% for custom_value in @custom_values %> | |
17 |
<p><b><%= custom_value.custom_field.name %></b> |
|
23 | <p><label><%= custom_value.custom_field.name %> :</label> <%= show_value custom_value %></p> | |
18 | <% end %> |
|
24 | <% end %> | |
|
25 | | |||
|
26 | </div> | |||
19 |
|
27 | |||
20 | <% if authorize_for('issues', 'edit') %> |
|
28 | <% if authorize_for('issues', 'edit') %> | |
21 | <%= start_form_tag ({:controller => 'issues', :action => 'edit', :id => @issue}, :method => "get" ) %> |
|
29 | <%= start_form_tag ({:controller => 'issues', :action => 'edit', :id => @issue}, :method => "get" ) %> | |
@@ -26,7 +34,7 | |||||
26 |
|
34 | |||
27 | <% if authorize_for('issues', 'change_status') and @status_options and !@status_options.empty? %> |
|
35 | <% if authorize_for('issues', 'change_status') and @status_options and !@status_options.empty? %> | |
28 | <%= start_form_tag ({:controller => 'issues', :action => 'change_status', :id => @issue}) %> |
|
36 | <%= start_form_tag ({:controller => 'issues', :action => 'change_status', :id => @issue}) %> | |
29 |
|
|
37 | <%=l(:label_change_status)%> : | |
30 | <select name="history[status_id]"> |
|
38 | <select name="history[status_id]"> | |
31 | <%= options_from_collection_for_select @status_options, "id", "name" %> |
|
39 | <%= options_from_collection_for_select @status_options, "id", "name" %> | |
32 | </select> |
|
40 | </select> |
@@ -1,5 +1,6 | |||||
1 | <%=l(:label_issue)%> #<%= issue.id %> - <%= issue.subject %> |
|
1 | <%=l(:label_issue)%> #<%= issue.id %> - <%= issue.subject %> | |
2 | <%=l(:field_author)%>: <%= issue.author.display_name %> |
|
2 | <%=l(:field_author)%>: <%= issue.author.display_name %> | |
|
3 | <%=l(:field_status)%>: <%= issue.status.name %> | |||
3 |
|
4 | |||
4 | <%= issue.description %> |
|
5 | <%= issue.description %> | |
5 |
|
6 |
@@ -1,4 +1,10 | |||||
1 | <h2><%=l(:label_issue_plural)%></h2> |
|
1 | <h2><%=l(:label_issue_plural)%></h2> | |
|
2 | <div class="topright"> | |||
|
3 | <small> | |||
|
4 | <%= link_to 'PDF ', :action => 'export_issues_pdf', :id => @project %> | | |||
|
5 | <%= link_to 'CSV ', :action => 'export_issues_csv', :id => @project %> | |||
|
6 | </small> | |||
|
7 | </div> | |||
2 |
|
8 | |||
3 | <form method="post" class="noborder"> |
|
9 | <form method="post" class="noborder"> | |
4 | <table cellpadding=2> |
|
10 | <table cellpadding=2> | |
@@ -8,6 +14,7 | |||||
8 | <td><small><%=l(:field_priority)%>:</small><br /><%= search_filter_tag 'priority_id', :class => 'select-small' %></td> |
|
14 | <td><small><%=l(:field_priority)%>:</small><br /><%= search_filter_tag 'priority_id', :class => 'select-small' %></td> | |
9 | <td><small><%=l(:field_category)%>:</small><br /><%= search_filter_tag 'category_id', :class => 'select-small' %></td> |
|
15 | <td><small><%=l(:field_category)%>:</small><br /><%= search_filter_tag 'category_id', :class => 'select-small' %></td> | |
10 | <td><small><%=l(:field_fixed_version)%>:</small><br /><%= search_filter_tag 'fixed_version_id', :class => 'select-small' %></td> |
|
16 | <td><small><%=l(:field_fixed_version)%>:</small><br /><%= search_filter_tag 'fixed_version_id', :class => 'select-small' %></td> | |
|
17 | <td><small><%=l(:field_author)%>:</small><br /><%= search_filter_tag 'author_id', :class => 'select-small' %></td> | |||
11 | <td><small><%=l(:field_assigned_to)%>:</small><br /><%= search_filter_tag 'assigned_to_id', :class => 'select-small' %></td> |
|
18 | <td><small><%=l(:field_assigned_to)%>:</small><br /><%= search_filter_tag 'assigned_to_id', :class => 'select-small' %></td> | |
12 | <td><small><%=l(:label_subproject_plural)%>:</small><br /><%= search_filter_tag 'subproject_id', :class => 'select-small' %></td> |
|
19 | <td><small><%=l(:label_subproject_plural)%>:</small><br /><%= search_filter_tag 'subproject_id', :class => 'select-small' %></td> | |
13 | <td valign="bottom"> |
|
20 | <td valign="bottom"> | |
@@ -22,13 +29,21 | |||||
22 | <%= end_form_tag %> |
|
29 | <%= end_form_tag %> | |
23 |
|
30 | |||
24 | |
|
31 | | |
25 |
|
||||
26 | <%= start_form_tag ({:controller => 'projects', :action => 'move_issues', :id => @project}, :id => 'issues_form' ) %> |
|
|||
27 | <table class="listTableContent"> |
|
32 | <table class="listTableContent"> | |
28 | <tr> |
|
33 | <tr> | |
29 | <td colspan="6" align="left"><small><%= check_all_links 'issues_form' %></small></td> |
|
34 | <td colspan="6" align="left"><small><%= check_all_links 'issues_form' %></small></td> | |
30 | <td colspan="2" align="right"><small><%= link_to l(:label_export_csv), :action => 'export_issues_csv', :id => @project.id %></small></td> |
|
35 | <td colspan="2" align="right"> | |
31 | </tr> |
|
36 | <small><%= l(:label_per_page) %>:</small> | |
|
37 | <%= start_form_tag %> | |||
|
38 | <%= select_tag 'per_page', options_for_select(@results_per_page_options, @results_per_page), :class => 'select-small'%> | |||
|
39 | <%= submit_tag l(:button_apply), :class => 'button-small'%> | |||
|
40 | <%= end_form_tag %> | |||
|
41 | </td> | |||
|
42 | </tr> | |||
|
43 | </table> | |||
|
44 | <%= start_form_tag ({:controller => 'projects', :action => 'move_issues', :id => @project}, :id => 'issues_form' ) %> | |||
|
45 | <table class="listTableContent"> | |||
|
46 | ||||
32 | <tr class="ListHead"> |
|
47 | <tr class="ListHead"> | |
33 | <td></td> |
|
48 | <td></td> | |
34 | <%= sort_header_tag('issues.id', :caption => '#') %> |
|
49 | <%= sort_header_tag('issues.id', :caption => '#') %> |
@@ -1,22 +1,20 | |||||
1 | <h2><%=l(:label_report_plural)%></h2> |
|
1 | <h2><%=l(:label_report_plural)%></h2> | |
2 |
|
2 | |||
3 | <div class="splitcontentleft"> |
|
3 | <div class="splitcontentleft"> | |
4 | <strong><%=l(:field_tracker)%></strong> |
|
4 | <strong><%=l(:field_tracker)%></strong> <small>[ <%= link_to l(:label_details), :detail => 'author' %> ]</small> | |
5 | <%= render :partial => 'simple', :locals => { :data => @issues_by_tracker, :field_name => "tracker_id", :rows => @trackers } %> |
|
5 | <%= render :partial => 'simple', :locals => { :data => @issues_by_tracker, :field_name => "tracker_id", :rows => @trackers } %> | |
6 | <p align="right"><small><%= link_to l(:label_details), :detail => 'tracker' %></small> </p> |
|
6 | <br /> | |
7 |
|
7 | <strong><%=l(:field_priority)%></strong> <small>[ <%= link_to l(:label_details), :detail => 'priority' %> ]</small> | ||
8 | <strong><%=l(:field_priority)%></strong> |
|
|||
9 | <%= render :partial => 'simple', :locals => { :data => @issues_by_priority, :field_name => "priority_id", :rows => @priorities } %> |
|
8 | <%= render :partial => 'simple', :locals => { :data => @issues_by_priority, :field_name => "priority_id", :rows => @priorities } %> | |
10 | <p align="right"><small><%= link_to l(:label_details), :detail => 'priority' %></small> </p> |
|
9 | <br /> | |
11 |
|
10 | <strong><%=l(:field_author)%></strong> <small>[ <%= link_to l(:label_details), :detail => 'author' %> ]</small> | ||
12 | <strong><%=l(:field_author)%></strong> |
|
|||
13 | <%= render :partial => 'simple', :locals => { :data => @issues_by_author, :field_name => "author_id", :rows => @authors } %> |
|
11 | <%= render :partial => 'simple', :locals => { :data => @issues_by_author, :field_name => "author_id", :rows => @authors } %> | |
14 | <p align="right"><small><%= link_to l(:label_details), :detail => 'author' %></small> </p> |
|
12 | <br /> | |
15 | </div> |
|
13 | </div> | |
16 |
|
14 | |||
17 | <div class="splitcontentright"> |
|
15 | <div class="splitcontentright"> | |
18 | <strong><%=l(:field_category)%></strong> |
|
16 | <strong><%=l(:field_category)%></strong> <small>[ <%= link_to l(:label_details), :detail => 'category' %> ]</small> | |
19 | <%= render :partial => 'simple', :locals => { :data => @issues_by_category, :field_name => "category_id", :rows => @categories } %> |
|
17 | <%= render :partial => 'simple', :locals => { :data => @issues_by_category, :field_name => "category_id", :rows => @categories } %> | |
20 | <p align="right"><small><%= link_to l(:label_details), :detail => 'category' %></small> </p> |
|
18 | <br /> | |
21 | </div> |
|
19 | </div> | |
22 |
|
20 |
@@ -44,6 +44,7 general_text_Yes: 'Ja' | |||||
44 | general_text_no: 'nein' |
|
44 | general_text_no: 'nein' | |
45 | general_text_yes: 'ja' |
|
45 | general_text_yes: 'ja' | |
46 | general_lang_de: 'Deutsch' |
|
46 | general_lang_de: 'Deutsch' | |
|
47 | general_csv_separator: ';' | |||
47 |
|
48 | |||
48 | notice_account_updated: Konto wurde erfolgreich aktualisiert. |
|
49 | notice_account_updated: Konto wurde erfolgreich aktualisiert. | |
49 | notice_account_invalid_creditentials: UnzulΓ€ssiger Benutzer oder Passwort |
|
50 | notice_account_invalid_creditentials: UnzulΓ€ssiger Benutzer oder Passwort | |
@@ -225,6 +226,7 label_version_new: Neue Version | |||||
225 | label_version_plural: Versionen |
|
226 | label_version_plural: Versionen | |
226 | label_confirmation: BestΓ€tigung |
|
227 | label_confirmation: BestΓ€tigung | |
227 | #label_export_csv: Export to CSV |
|
228 | #label_export_csv: Export to CSV | |
|
229 | #label_export_pdf: Export to PDF | |||
228 | label_read: Lesen... |
|
230 | label_read: Lesen... | |
229 | label_public_projects: Γffentliche Projekte |
|
231 | label_public_projects: Γffentliche Projekte | |
230 | #label_open_issues: Open |
|
232 | #label_open_issues: Open | |
@@ -242,6 +244,7 label_previous: ZurΓΌck | |||||
242 | label_used_by: Benutzt von |
|
244 | label_used_by: Benutzt von | |
243 | #label_details: Details... |
|
245 | #label_details: Details... | |
244 | #label_add_note: Add a note |
|
246 | #label_add_note: Add a note | |
|
247 | #label_per_page: Per page | |||
245 |
|
248 | |||
246 | button_login: Einloggen |
|
249 | button_login: Einloggen | |
247 | button_submit: Einreichen |
|
250 | button_submit: Einreichen |
@@ -44,6 +44,7 general_text_Yes: 'Yes' | |||||
44 | general_text_no: 'no' |
|
44 | general_text_no: 'no' | |
45 | general_text_yes: 'yes' |
|
45 | general_text_yes: 'yes' | |
46 | general_lang_en: 'English' |
|
46 | general_lang_en: 'English' | |
|
47 | general_csv_separator: ',' | |||
47 |
|
48 | |||
48 | notice_account_updated: Account was successfully updated. |
|
49 | notice_account_updated: Account was successfully updated. | |
49 | notice_account_invalid_creditentials: Invalid user or password |
|
50 | notice_account_invalid_creditentials: Invalid user or password | |
@@ -225,6 +226,7 label_version_new: New version | |||||
225 | label_version_plural: Versions |
|
226 | label_version_plural: Versions | |
226 | label_confirmation: Confirmation |
|
227 | label_confirmation: Confirmation | |
227 | label_export_csv: Export to CSV |
|
228 | label_export_csv: Export to CSV | |
|
229 | label_export_pdf: Export to PDF | |||
228 | label_read: Read... |
|
230 | label_read: Read... | |
229 | label_public_projects: Public projects |
|
231 | label_public_projects: Public projects | |
230 | label_open_issues: Open |
|
232 | label_open_issues: Open | |
@@ -242,6 +244,7 label_previous: Previous | |||||
242 | label_used_by: Used by |
|
244 | label_used_by: Used by | |
243 | label_details: Details... |
|
245 | label_details: Details... | |
244 | label_add_note: Add a note |
|
246 | label_add_note: Add a note | |
|
247 | label_per_page: Per page | |||
245 |
|
248 | |||
246 | button_login: Login |
|
249 | button_login: Login | |
247 | button_submit: Submit |
|
250 | button_submit: Submit |
@@ -44,6 +44,7 general_text_Yes: 'SΓ' | |||||
44 | general_text_no: 'no' |
|
44 | general_text_no: 'no' | |
45 | general_text_yes: 'sΓ' |
|
45 | general_text_yes: 'sΓ' | |
46 | general_lang_es: 'EspaΓ±ol' |
|
46 | general_lang_es: 'EspaΓ±ol' | |
|
47 | general_csv_separator: ';' | |||
47 |
|
48 | |||
48 | notice_account_updated: Account was successfully updated. |
|
49 | notice_account_updated: Account was successfully updated. | |
49 | notice_account_invalid_creditentials: Invalid user or password |
|
50 | notice_account_invalid_creditentials: Invalid user or password | |
@@ -225,6 +226,7 label_version_new: Nueva versiΓ³n | |||||
225 | label_version_plural: VersiΓ³nes |
|
226 | label_version_plural: VersiΓ³nes | |
226 | label_confirmation: ConfirmaciΓ³n |
|
227 | label_confirmation: ConfirmaciΓ³n | |
227 | label_export_csv: Exportar a CSV |
|
228 | label_export_csv: Exportar a CSV | |
|
229 | label_export_pdf: Exportar a PDF | |||
228 | label_read: Leer... |
|
230 | label_read: Leer... | |
229 | label_public_projects: Proyectos publicos |
|
231 | label_public_projects: Proyectos publicos | |
230 | label_open_issues: Abierta |
|
232 | label_open_issues: Abierta | |
@@ -242,6 +244,7 label_previous: Precedente | |||||
242 | label_used_by: Utilizado por |
|
244 | label_used_by: Utilizado por | |
243 | #label_details: Details... |
|
245 | #label_details: Details... | |
244 | #label_add_note: Add a note |
|
246 | #label_add_note: Add a note | |
|
247 | #label_per_page: Per page | |||
245 |
|
248 | |||
246 | button_login: ConexiΓ³n |
|
249 | button_login: ConexiΓ³n | |
247 | button_submit: Someter |
|
250 | button_submit: Someter |
@@ -44,6 +44,7 general_text_Yes: 'Oui' | |||||
44 | general_text_no: 'non' |
|
44 | general_text_no: 'non' | |
45 | general_text_yes: 'oui' |
|
45 | general_text_yes: 'oui' | |
46 | general_lang_fr: 'FranΓ§ais' |
|
46 | general_lang_fr: 'FranΓ§ais' | |
|
47 | general_csv_separator: ';' | |||
47 |
|
48 | |||
48 | notice_account_updated: Le compte a été mis à jour avec succès. |
|
49 | notice_account_updated: Le compte a été mis à jour avec succès. | |
49 | notice_account_invalid_creditentials: Identifiant ou mot de passe invalide. |
|
50 | notice_account_invalid_creditentials: Identifiant ou mot de passe invalide. | |
@@ -225,6 +226,7 label_version_new: Nouvelle version | |||||
225 | label_version_plural: Versions |
|
226 | label_version_plural: Versions | |
226 | label_confirmation: Confirmation |
|
227 | label_confirmation: Confirmation | |
227 | label_export_csv: Exporter en CSV |
|
228 | label_export_csv: Exporter en CSV | |
|
229 | label_export_pdf: Exporter en PDF | |||
228 | label_read: Lire... |
|
230 | label_read: Lire... | |
229 | label_public_projects: Projets publics |
|
231 | label_public_projects: Projets publics | |
230 | label_open_issues: Ouverte |
|
232 | label_open_issues: Ouverte | |
@@ -242,6 +244,7 label_previous: PrΓ©cΓ©dent | |||||
242 | label_used_by: UtilisΓ© par |
|
244 | label_used_by: UtilisΓ© par | |
243 | label_details: DΓ©tails... |
|
245 | label_details: DΓ©tails... | |
244 | label_add_note: Ajouter une note |
|
246 | label_add_note: Ajouter une note | |
|
247 | label_per_page: Par page | |||
245 |
|
248 | |||
246 | button_login: Connexion |
|
249 | button_login: Connexion | |
247 | button_submit: Soumettre |
|
250 | button_submit: Soumettre |
@@ -205,10 +205,14 input.button-small | |||||
205 | font-size: 0.8em; |
|
205 | font-size: 0.8em; | |
206 | } |
|
206 | } | |
207 |
|
207 | |||
|
208 | select { | |||
|
209 | vertical-align: middle; | |||
|
210 | } | |||
|
211 | ||||
208 | select.select-small |
|
212 | select.select-small | |
209 | { |
|
213 | { | |
210 | border: 1px solid #7F9DB9; |
|
214 | border: 1px solid #7F9DB9; | |
211 | padding: 1px; |
|
215 | padding: 1px; | |
212 | font-size: 0.8em; |
|
216 | font-size: 0.8em; | |
213 | } |
|
217 | } | |
214 |
|
218 | |||
@@ -244,7 +248,7 table.listTableContent { | |||||
244 | } |
|
248 | } | |
245 |
|
249 | |||
246 | table.listTableContent td { |
|
250 | table.listTableContent td { | |
247 |
padding: |
|
251 | padding:2px; | |
248 | } |
|
252 | } | |
249 |
|
253 | |||
250 | tr.ListHead { |
|
254 | tr.ListHead { | |
@@ -366,6 +370,12 color:#505050; | |||||
366 | line-height:1.5em; |
|
370 | line-height:1.5em; | |
367 | } |
|
371 | } | |
368 |
|
372 | |||
|
373 | .topright{ | |||
|
374 | position: absolute; | |||
|
375 | right: 25px; | |||
|
376 | top: 100px; | |||
|
377 | } | |||
|
378 | ||||
369 | .login { |
|
379 | .login { | |
370 | width: 50%; |
|
380 | width: 50%; | |
371 | text-align: left; |
|
381 | text-align: left; |
General Comments 0
You need to be logged in to leave comments.
Login now