##// END OF EJS Templates
improved issues change history...
Jean-Philippe Lang -
r52:42181112ff73
parent child
Show More
@@ -0,0 +1,22
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 class Journal < ActiveRecord::Base
19 belongs_to :journalized, :polymorphic => true
20 belongs_to :user
21 has_many :details, :class_name => "JournalDetail", :dependent => true
22 end
@@ -0,0 +1,20
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 class JournalDetail < ActiveRecord::Base
19 belongs_to :journal
20 end
@@ -0,0 +1,11
1 <% for journal in journals %>
2 <h4><%= format_time(journal.created_on) %> - <%= journal.user.name %></h4>
3 <ul>
4 <% for detail in journal.details %>
5 <li><%= show_detail(detail) %></li>
6 <% end %>
7 </ul>
8 <% if journal.notes? %>
9 <%= simple_format auto_link journal.notes %>
10 <% end %>
11 <% end %>
@@ -0,0 +1,6
1 <h3><%=l(:label_history)%></h3>
2 <div id="history">
3 <%= render :partial => 'history', :locals => { :journals => @journals } %>
4 </div>
5 <br />
6 <p><%= link_to l(:button_back), :action => 'show', :id => @issue %></p> No newline at end of file
@@ -0,0 +1,8
1 Issue #<%= @issue.id %> has been updated.
2 <%= @journal.user.name %>
3 <% for detail in @journal.details %>
4 <%= show_detail(detail) %>
5 <% end %>
6 <%= @journal.notes if @journal.notes? %>
7 ----------------------------------------
8 <%= render :file => "_issue", :use_full_path => true, :locals => { :issue => @issue } %> No newline at end of file
@@ -0,0 +1,8
1 Issue #<%= @issue.id %> has been updated.
2 <%= @journal.user.name %>
3 <% for detail in @journal.details %>
4 <%= show_detail(detail) %>
5 <% end %>
6 <%= @journal.notes if @journal.notes? %>
7 ----------------------------------------
8 <%= render :file => "_issue", :use_full_path => true, :locals => { :issue => @issue } %> No newline at end of file
@@ -0,0 +1,8
1 Issue #<%= @issue.id %> has been updated.
2 <%= @journal.user.name %>
3 <% for detail in @journal.details %>
4 <%= show_detail(detail) %>
5 <% end %>
6 <%= @journal.notes if @journal.notes? %>
7 ----------------------------------------
8 <%= render :file => "_issue", :use_full_path => true, :locals => { :issue => @issue } %> No newline at end of file
@@ -0,0 +1,8
1 La demande #<%= @issue.id %> a été mise à jour.
2 <%= @journal.user.name %> - <%= format_date(@journal.created_on) %>
3 <% for detail in @journal.details %>
4 <%= show_detail(detail) %>
5 <% end %>
6 <%= journal.notes if journal.notes? %>
7 ----------------------------------------
8 <%= render :file => "_issue", :use_full_path => true, :locals => { :issue => @issue } %> No newline at end of file
@@ -0,0 +1,54
1 class CreateJournals < ActiveRecord::Migration
2
3 # model removed, but needed for data migration
4 class IssueHistory < ActiveRecord::Base; belongs_to :issue; end
5
6 def self.up
7 create_table :journals, :force => true do |t|
8 t.column "journalized_id", :integer, :default => 0, :null => false
9 t.column "journalized_type", :string, :limit => 30, :default => "", :null => false
10 t.column "user_id", :integer, :default => 0, :null => false
11 t.column "notes", :text
12 t.column "created_on", :datetime, :null => false
13 end
14 create_table :journal_details, :force => true do |t|
15 t.column "journal_id", :integer, :default => 0, :null => false
16 t.column "property", :string, :limit => 30, :default => "", :null => false
17 t.column "prop_key", :string, :limit => 30, :default => "", :null => false
18 t.column "old_value", :string
19 t.column "value", :string
20 end
21
22 # indexes
23 add_index "journals", ["journalized_id", "journalized_type"], :name => "journals_journalized_id"
24 add_index "journal_details", ["journal_id"], :name => "journal_details_journal_id"
25
26 Permission.create :controller => "issues", :action => "history", :description => "label_history", :sort => 1006, :is_public => true, :mail_option => 0, :mail_enabled => 0
27
28 # data migration
29 IssueHistory.find(:all, :include => :issue).each {|h|
30 j = Journal.new(:journalized => h.issue, :user_id => h.author_id, :notes => h.notes, :created_on => h.created_on)
31 j.details << JournalDetail.new(:property => 'attr', :prop_key => 'status_id', :value => h.status_id)
32 j.save
33 }
34
35 drop_table :issue_histories
36 end
37
38 def self.down
39 drop_table :journal_details
40 drop_table :journals
41
42 create_table "issue_histories", :force => true do |t|
43 t.column "issue_id", :integer, :default => 0, :null => false
44 t.column "status_id", :integer, :default => 0, :null => false
45 t.column "author_id", :integer, :default => 0, :null => false
46 t.column "notes", :text, :default => ""
47 t.column "created_on", :timestamp
48 end
49
50 add_index "issue_histories", ["issue_id"], :name => "issue_histories_issue_id"
51
52 Permission.find(:first, :conditions => ["controller=? and action=?", 'issues', 'history']).destroy
53 end
54 end
@@ -1,107 +1,126
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class ApplicationController < ActionController::Base
19 19 before_filter :check_if_login_required, :set_localization
20 20
21 21 def logged_in_user=(user)
22 22 @logged_in_user = user
23 23 session[:user_id] = (user ? user.id : nil)
24 24 end
25 25
26 26 def logged_in_user
27 27 if session[:user_id]
28 28 @logged_in_user ||= User.find(session[:user_id], :include => :memberships)
29 29 else
30 30 nil
31 31 end
32 32 end
33 33
34 34 # check if login is globally required to access the application
35 35 def check_if_login_required
36 36 require_login if $RDM_LOGIN_REQUIRED
37 37 end
38 38
39 39 def set_localization
40 40 lang = begin
41 41 if self.logged_in_user and self.logged_in_user.language and !self.logged_in_user.language.empty? and GLoc.valid_languages.include? self.logged_in_user.language.to_sym
42 42 self.logged_in_user.language
43 43 elsif request.env['HTTP_ACCEPT_LANGUAGE']
44 accept_lang = HTTPUtils.parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.split('-').first
44 accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.split('-').first
45 45 if accept_lang and !accept_lang.empty? and GLoc.valid_languages.include? accept_lang.to_sym
46 46 accept_lang
47 47 end
48 48 end
49 49 rescue
50 50 nil
51 51 end || $RDM_DEFAULT_LANG
52 52 set_language_if_valid(lang)
53 53 end
54 54
55 55 def require_login
56 56 unless self.logged_in_user
57 57 store_location
58 58 redirect_to :controller => "account", :action => "login"
59 59 return false
60 60 end
61 61 true
62 62 end
63 63
64 64 def require_admin
65 65 return unless require_login
66 66 unless self.logged_in_user.admin?
67 67 render :nothing => true, :status => 403
68 68 return false
69 69 end
70 70 true
71 71 end
72 72
73 73 # authorizes the user for the requested action.
74 74 def authorize
75 75 # check if action is allowed on public projects
76 76 if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ @params[:controller], @params[:action] ]
77 77 return true
78 78 end
79 79 # if action is not public, force login
80 80 return unless require_login
81 81 # admin is always authorized
82 82 return true if self.logged_in_user.admin?
83 83 # if not admin, check membership permission
84 84 @user_membership ||= Member.find(:first, :conditions => ["user_id=? and project_id=?", self.logged_in_user.id, @project.id])
85 85 if @user_membership and Permission.allowed_to_role( "%s/%s" % [ @params[:controller], @params[:action] ], @user_membership.role_id )
86 86 return true
87 87 end
88 88 render :nothing => true, :status => 403
89 89 false
90 90 end
91 91
92 92 # store current uri in session.
93 93 # return to this location by calling redirect_back_or_default
94 94 def store_location
95 95 session[:return_to] = @request.request_uri
96 96 end
97 97
98 98 # move to the last store_location call or to the passed default one
99 99 def redirect_back_or_default(default)
100 100 if session[:return_to].nil?
101 101 redirect_to default
102 102 else
103 103 redirect_to_url session[:return_to]
104 104 session[:return_to] = nil
105 105 end
106 106 end
107
108 # qvalues http header parser
109 # code taken from webrick
110 def parse_qvalues(value)
111 tmp = []
112 if value
113 parts = value.split(/,\s*/)
114 parts.each {|part|
115 if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
116 val = m[1]
117 q = (m[2] or 1).to_f
118 tmp.push([val, q])
119 end
120 }
121 tmp = tmp.sort_by{|val, q| -q}
122 tmp.collect!{|val, q| val}
123 end
124 return tmp
125 end
107 126 end No newline at end of file
@@ -1,133 +1,145
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class IssuesController < ApplicationController
19 19 layout 'base', :except => :export_pdf
20 20 before_filter :find_project, :authorize
21 21
22 22 helper :custom_fields
23 23 include CustomFieldsHelper
24 24 helper :ifpdf
25 25 include IfpdfHelper
26 26
27 27 def show
28 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
29 29 @custom_values = @issue.custom_values.find(:all, :include => :custom_field)
30 @journals_count = @issue.journals.count
31 @journals = @issue.journals.find(:all, :include => [:user, :details], :limit => 15, :order => "journals.created_on desc")
32 end
33
34 def history
35 @journals = @issue.journals.find(:all, :include => [:user, :details], :order => "journals.created_on desc")
36 @journals_count = @journals.length
30 37 end
31 38
32 39 def export_pdf
33 40 @custom_values = @issue.custom_values.find(:all, :include => :custom_field)
34 41 @options_for_rfpdf ||= {}
35 42 @options_for_rfpdf[:file_name] = "#{@project.name}_#{@issue.long_id}.pdf"
36 43 end
37 44
38 45 def edit
39 46 @priorities = Enumeration::get_values('IPRI')
40 47 if request.get?
41 48 @custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x, :customized => @issue) }
42 49 else
43 50 begin
51 @issue.init_journal(self.logged_in_user)
44 52 # Retrieve custom fields and values
45 53 @custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
46 54 @issue.custom_values = @custom_values
47 55 @issue.attributes = params[:issue]
48 56 if @issue.save
49 57 flash[:notice] = l(:notice_successful_update)
50 58 redirect_to :action => 'show', :id => @issue
51 59 end
52 60 rescue ActiveRecord::StaleObjectError
53 61 # Optimistic locking exception
54 62 flash[:notice] = l(:notice_locking_conflict)
55 63 end
56 64 end
57 65 end
58 66
59 67 def add_note
60 unless params[:history][:notes].empty?
61 @history = @issue.histories.build(params[:history])
62 @history.author_id = self.logged_in_user.id if self.logged_in_user
63 @history.status = @issue.status
64 if @history.save
68 unless params[:notes].empty?
69 journal = @issue.init_journal(self.logged_in_user, params[:notes])
70 #@history = @issue.histories.build(params[:history])
71 #@history.author_id = self.logged_in_user.id if self.logged_in_user
72 #@history.status = @issue.status
73 if @issue.save
65 74 flash[:notice] = l(:notice_successful_update)
66 Mailer.deliver_issue_add_note(@history) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
75 Mailer.deliver_issue_edit(journal) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
67 76 redirect_to :action => 'show', :id => @issue
68 77 return
69 78 end
70 79 end
71 80 show
72 81 render :action => 'show'
73 82 end
74 83
75 84 def change_status
76 @history = @issue.histories.build(params[:history])
85 #@history = @issue.histories.build(params[:history])
77 86 @status_options = @issue.status.workflows.find(:all, :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
87 @new_status = IssueStatus.find(params[:new_status_id])
78 88 if params[:confirm]
79 89 begin
80 @history.author_id = self.logged_in_user.id if self.logged_in_user
81 @issue.status = @history.status
82 @issue.fixed_version_id = (params[:issue][:fixed_version_id])
83 @issue.assigned_to_id = (params[:issue][:assigned_to_id])
84 @issue.done_ratio = (params[:issue][:done_ratio])
85 @issue.lock_version = (params[:issue][:lock_version])
86 if @issue.save
90 #@history.author_id = self.logged_in_user.id if self.logged_in_user
91 #@issue.status = @history.status
92 #@issue.fixed_version_id = (params[:issue][:fixed_version_id])
93 #@issue.assigned_to_id = (params[:issue][:assigned_to_id])
94 #@issue.done_ratio = (params[:issue][:done_ratio])
95 #@issue.lock_version = (params[:issue][:lock_version])
96 @issue.init_journal(self.logged_in_user, params[:notes])
97 @issue.status = @new_status
98 if @issue.update_attributes(params[:issue])
87 99 flash[:notice] = l(:notice_successful_update)
88 100 Mailer.deliver_issue_change_status(@issue) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
89 101 redirect_to :action => 'show', :id => @issue
90 102 end
91 103 rescue ActiveRecord::StaleObjectError
92 104 # Optimistic locking exception
93 105 flash[:notice] = l(:notice_locking_conflict)
94 106 end
95 107 end
96 108 @assignable_to = @project.members.find(:all, :include => :user).collect{ |m| m.user }
97 109 end
98 110
99 111 def destroy
100 112 @issue.destroy
101 113 redirect_to :controller => 'projects', :action => 'list_issues', :id => @project
102 114 end
103 115
104 116 def add_attachment
105 117 # Save the attachments
106 118 params[:attachments].each { |a|
107 119 @attachment = @issue.attachments.build(:file => a, :author => self.logged_in_user) unless a.size == 0
108 120 @attachment.save
109 121 } if params[:attachments] and params[:attachments].is_a? Array
110 122 redirect_to :action => 'show', :id => @issue
111 123 end
112 124
113 125 def destroy_attachment
114 126 @issue.attachments.find(params[:attachment_id]).destroy
115 127 redirect_to :action => 'show', :id => @issue
116 128 end
117 129
118 130 # Send the file in stream mode
119 131 def download
120 132 @attachment = @issue.attachments.find(params[:attachment_id])
121 133 send_file @attachment.diskfile, :filename => @attachment.filename
122 134 rescue
123 135 flash.now[:notice] = l(:notice_file_not_found)
124 136 render :text => "", :layout => true, :status => 404
125 137 end
126 138
127 139 private
128 140 def find_project
129 141 @issue = Issue.find(params[:id], :include => [:project, :tracker, :status, :author, :priority, :category])
130 142 @project = @issue.project
131 143 @html_title = "#{@project.name} - #{@issue.tracker.name} ##{@issue.id}"
132 144 end
133 145 end
@@ -1,468 +1,469
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class ProjectsController < ApplicationController
19 19 layout 'base', :except => :export_issues_pdf
20 20 before_filter :find_project, :authorize, :except => [ :index, :list, :add ]
21 21 before_filter :require_admin, :only => [ :add, :destroy ]
22 22
23 23 helper :sort
24 24 include SortHelper
25 25 helper :search_filter
26 26 include SearchFilterHelper
27 27 helper :custom_fields
28 28 include CustomFieldsHelper
29 29 helper :ifpdf
30 30 include IfpdfHelper
31 helper IssuesHelper
31 32
32 33 def index
33 34 list
34 35 render :action => 'list' unless request.xhr?
35 36 end
36 37
37 38 # Lists public projects
38 39 def list
39 40 sort_init 'name', 'asc'
40 41 sort_update
41 42 @project_count = Project.count(["is_public=?", true])
42 43 @project_pages = Paginator.new self, @project_count,
43 44 15,
44 45 @params['page']
45 46 @projects = Project.find :all, :order => sort_clause,
46 47 :conditions => ["is_public=?", true],
47 48 :limit => @project_pages.items_per_page,
48 49 :offset => @project_pages.current.offset
49 50
50 51 render :action => "list", :layout => false if request.xhr?
51 52 end
52 53
53 54 # Add a new project
54 55 def add
55 56 @custom_fields = IssueCustomField.find(:all)
56 57 @root_projects = Project.find(:all, :conditions => "parent_id is null")
57 58 @project = Project.new(params[:project])
58 59 if request.get?
59 60 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project) }
60 61 else
61 62 @project.custom_fields = CustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
62 63 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
63 64 @project.custom_values = @custom_values
64 65 if @project.save
65 66 flash[:notice] = l(:notice_successful_create)
66 67 redirect_to :controller => 'admin', :action => 'projects'
67 68 end
68 69 end
69 70 end
70 71
71 72 # Show @project
72 73 def show
73 74 @custom_values = @project.custom_values.find(:all, :include => :custom_field)
74 75 @members = @project.members.find(:all, :include => [:user, :role])
75 76 @subprojects = @project.children if @project.children_count > 0
76 77 @news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "news.created_on DESC")
77 78 @trackers = Tracker.find(:all)
78 79 end
79 80
80 81 def settings
81 82 @root_projects = Project::find(:all, :conditions => ["parent_id is null and id <> ?", @project.id])
82 83 @custom_fields = IssueCustomField::find_all
83 84 @issue_category ||= IssueCategory.new
84 85 @member ||= @project.members.new
85 86 @roles = Role.find_all
86 87 @users = User.find_all - @project.members.find(:all, :include => :user).collect{|m| m.user }
87 88 @custom_values ||= ProjectCustomField.find(:all).collect { |x| @project.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
88 89 end
89 90
90 91 # Edit @project
91 92 def edit
92 93 if request.post?
93 94 @project.custom_fields = IssueCustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
94 95 if params[:custom_fields]
95 96 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
96 97 @project.custom_values = @custom_values
97 98 end
98 99 if @project.update_attributes(params[:project])
99 100 flash[:notice] = l(:notice_successful_update)
100 101 redirect_to :action => 'settings', :id => @project
101 102 else
102 103 settings
103 104 render :action => 'settings'
104 105 end
105 106 end
106 107 end
107 108
108 109 # Delete @project
109 110 def destroy
110 111 if request.post? and params[:confirm]
111 112 @project.destroy
112 113 redirect_to :controller => 'admin', :action => 'projects'
113 114 end
114 115 end
115 116
116 117 # Add a new issue category to @project
117 118 def add_issue_category
118 119 if request.post?
119 120 @issue_category = @project.issue_categories.build(params[:issue_category])
120 121 if @issue_category.save
121 122 flash[:notice] = l(:notice_successful_create)
122 123 redirect_to :action => 'settings', :id => @project
123 124 else
124 125 settings
125 126 render :action => 'settings'
126 127 end
127 128 end
128 129 end
129 130
130 131 # Add a new version to @project
131 132 def add_version
132 133 @version = @project.versions.build(params[:version])
133 134 if request.post? and @version.save
134 135 flash[:notice] = l(:notice_successful_create)
135 136 redirect_to :action => 'settings', :id => @project
136 137 end
137 138 end
138 139
139 140 # Add a new member to @project
140 141 def add_member
141 142 @member = @project.members.build(params[:member])
142 143 if request.post?
143 144 if @member.save
144 145 flash[:notice] = l(:notice_successful_create)
145 146 redirect_to :action => 'settings', :id => @project
146 147 else
147 148 settings
148 149 render :action => 'settings'
149 150 end
150 151 end
151 152 end
152 153
153 154 # Show members list of @project
154 155 def list_members
155 156 @members = @project.members
156 157 end
157 158
158 159 # Add a new document to @project
159 160 def add_document
160 161 @categories = Enumeration::get_values('DCAT')
161 162 @document = @project.documents.build(params[:document])
162 163 if request.post?
163 164 # Save the attachment
164 165 if params[:attachment][:file].size > 0
165 166 @attachment = @document.attachments.build(params[:attachment])
166 167 @attachment.author_id = self.logged_in_user.id if self.logged_in_user
167 168 end
168 169 if @document.save
169 170 flash[:notice] = l(:notice_successful_create)
170 171 redirect_to :action => 'list_documents', :id => @project
171 172 end
172 173 end
173 174 end
174 175
175 176 # Show documents list of @project
176 177 def list_documents
177 178 @documents = @project.documents
178 179 end
179 180
180 181 # Add a new issue to @project
181 182 def add_issue
182 183 @tracker = Tracker.find(params[:tracker_id])
183 184 @priorities = Enumeration::get_values('IPRI')
184 185 @issue = Issue.new(:project => @project, :tracker => @tracker)
185 186 if request.get?
186 187 @issue.start_date = Date.today
187 188 @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue) }
188 189 else
189 190 @issue.attributes = params[:issue]
190 191 @issue.author_id = self.logged_in_user.id if self.logged_in_user
191 192 # Multiple file upload
192 193 params[:attachments].each { |a|
193 194 @attachment = @issue.attachments.build(:file => a, :author => self.logged_in_user) unless a.size == 0
194 195 } if params[:attachments] and params[:attachments].is_a? Array
195 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 197 @issue.custom_values = @custom_values
197 198 if @issue.save
198 199 flash[:notice] = l(:notice_successful_create)
199 200 Mailer.deliver_issue_add(@issue) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
200 201 redirect_to :action => 'list_issues', :id => @project
201 202 end
202 203 end
203 204 end
204 205
205 206 # Show filtered/sorted issues list of @project
206 207 def list_issues
207 208 sort_init 'issues.id', 'desc'
208 209 sort_update
209 210
210 211 search_filter_init_list_issues
211 212 search_filter_update if params[:set_filter]
212 213
213 214 @results_per_page_options = [ 15, 25, 50, 100 ]
214 215 if params[:per_page] and @results_per_page_options.include? params[:per_page].to_i
215 216 @results_per_page = params[:per_page].to_i
216 217 session[:results_per_page] = @results_per_page
217 218 else
218 219 @results_per_page = session[:results_per_page] || 25
219 220 end
220 221
221 222 @issue_count = Issue.count(:include => [:status, :project], :conditions => search_filter_clause)
222 223 @issue_pages = Paginator.new self, @issue_count, @results_per_page, @params['page']
223 224 @issues = Issue.find :all, :order => sort_clause,
224 225 :include => [ :author, :status, :tracker, :project ],
225 226 :conditions => search_filter_clause,
226 227 :limit => @issue_pages.items_per_page,
227 228 :offset => @issue_pages.current.offset
228 229
229 230 render :layout => false if request.xhr?
230 231 end
231 232
232 233 # Export filtered/sorted issues list to CSV
233 234 def export_issues_csv
234 235 sort_init 'issues.id', 'desc'
235 236 sort_update
236 237
237 238 search_filter_init_list_issues
238 239
239 240 @issues = Issue.find :all, :order => sort_clause,
240 241 :include => [ :author, :status, :tracker, :project, :custom_values ],
241 242 :conditions => search_filter_clause
242 243
243 244 ic = Iconv.new('ISO-8859-1', 'UTF-8')
244 245 export = StringIO.new
245 246 CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
246 247 # csv header fields
247 248 headers = [ "#", l(:field_status), l(:field_tracker), l(:field_subject), l(:field_author), l(:field_created_on), l(:field_updated_on) ]
248 249 for custom_field in @project.all_custom_fields
249 250 headers << custom_field.name
250 251 end
251 252 csv << headers.collect {|c| ic.iconv(c) }
252 253 # csv lines
253 254 @issues.each do |issue|
254 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 256 for custom_field in @project.all_custom_fields
256 257 fields << (show_value issue.custom_value_for(custom_field))
257 258 end
258 259 csv << fields.collect {|c| ic.iconv(c.to_s) }
259 260 end
260 261 end
261 262 export.rewind
262 263 send_data(export.read, :type => 'text/csv; header=present', :filename => 'export.csv')
263 264 end
264 265
265 266 # Export filtered/sorted issues to PDF
266 267 def export_issues_pdf
267 268 sort_init 'issues.id', 'desc'
268 269 sort_update
269 270
270 271 search_filter_init_list_issues
271 272
272 273 @issues = Issue.find :all, :order => sort_clause,
273 274 :include => [ :author, :status, :tracker, :project, :custom_values ],
274 275 :conditions => search_filter_clause
275 276
276 277 @options_for_rfpdf ||= {}
277 278 @options_for_rfpdf[:file_name] = "export.pdf"
278 279 end
279 280
280 281 def move_issues
281 282 @issues = @project.issues.find(params[:issue_ids]) if params[:issue_ids]
282 283 redirect_to :action => 'list_issues', :id => @project and return unless @issues
283 284 @projects = []
284 285 # find projects to which the user is allowed to move the issue
285 286 @logged_in_user.memberships.each {|m| @projects << m.project if Permission.allowed_to_role("projects/move_issues", m.role_id)}
286 287 # issue can be moved to any tracker
287 288 @trackers = Tracker.find(:all)
288 289 if request.post? and params[:new_project_id] and params[:new_tracker_id]
289 290 new_project = Project.find(params[:new_project_id])
290 291 new_tracker = Tracker.find(params[:new_tracker_id])
291 292 @issues.each { |i|
292 293 # category is project dependent
293 294 i.category = nil unless i.project_id == new_project.id
294 295 # move the issue
295 296 i.project = new_project
296 297 i.tracker = new_tracker
297 298 i.save
298 299 }
299 300 flash[:notice] = l(:notice_successful_update)
300 301 redirect_to :action => 'list_issues', :id => @project
301 302 end
302 303 end
303 304
304 305 # Add a news to @project
305 306 def add_news
306 307 @news = News.new(:project => @project)
307 308 if request.post?
308 309 @news.attributes = params[:news]
309 310 @news.author_id = self.logged_in_user.id if self.logged_in_user
310 311 if @news.save
311 312 flash[:notice] = l(:notice_successful_create)
312 313 redirect_to :action => 'list_news', :id => @project
313 314 end
314 315 end
315 316 end
316 317
317 318 # Show news list of @project
318 319 def list_news
319 320 @news_pages, @news = paginate :news, :per_page => 10, :conditions => ["project_id=?", @project.id], :include => :author, :order => "news.created_on DESC"
320 321 render :action => "list_news", :layout => false if request.xhr?
321 322 end
322 323
323 324 def add_file
324 325 if request.post?
325 326 # Save the attachment
326 327 if params[:attachment][:file].size > 0
327 328 @attachment = @project.versions.find(params[:version_id]).attachments.build(params[:attachment])
328 329 @attachment.author_id = self.logged_in_user.id if self.logged_in_user
329 330 if @attachment.save
330 331 flash[:notice] = l(:notice_successful_create)
331 332 redirect_to :controller => 'projects', :action => 'list_files', :id => @project
332 333 end
333 334 end
334 335 end
335 336 @versions = @project.versions
336 337 end
337 338
338 339 def list_files
339 340 @versions = @project.versions
340 341 end
341 342
342 343 # Show changelog for @project
343 344 def changelog
344 345 @trackers = Tracker.find(:all, :conditions => ["is_in_chlog=?", true])
345 346 if request.get?
346 347 @selected_tracker_ids = @trackers.collect {|t| t.id.to_s }
347 348 else
348 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 350 end
350 351 @selected_tracker_ids ||= []
351 352 @fixed_issues = @project.issues.find(:all,
352 353 :include => [ :fixed_version, :status, :tracker ],
353 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 355 :order => "versions.effective_date DESC, issues.id DESC"
355 356 ) unless @selected_tracker_ids.empty?
356 357 @fixed_issues ||= []
357 358 end
358 359
359 360 def activity
360 361 if params[:year] and params[:year].to_i > 1900
361 362 @year = params[:year].to_i
362 363 if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
363 364 @month = params[:month].to_i
364 365 end
365 366 end
366 367 @year ||= Date.today.year
367 368 @month ||= Date.today.month
368 369
369 370 @date_from = Date.civil(@year, @month, 1)
370 371 @date_to = (@date_from >> 1)-1
371 372
372 373 @events_by_day = {}
373 374
374 375 unless params[:show_issues] == "0"
375 376 @project.issues.find(:all, :include => [:author, :status], :conditions => ["issues.created_on>=? and issues.created_on<=?", @date_from, @date_to] ).each { |i|
376 377 @events_by_day[i.created_on.to_date] ||= []
377 378 @events_by_day[i.created_on.to_date] << i
378 379 }
379 380 @show_issues = 1
380 381 end
381 382
382 383 unless params[:show_news] == "0"
383 384 @project.news.find(:all, :conditions => ["news.created_on>=? and news.created_on<=?", @date_from, @date_to] ).each { |i|
384 385 @events_by_day[i.created_on.to_date] ||= []
385 386 @events_by_day[i.created_on.to_date] << i
386 387 }
387 388 @show_news = 1
388 389 end
389 390
390 391 unless params[:show_files] == "0"
391 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 393 @events_by_day[i.created_on.to_date] ||= []
393 394 @events_by_day[i.created_on.to_date] << i
394 395 }
395 396 @show_files = 1
396 397 end
397 398
398 399 unless params[:show_documents] == "0"
399 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 401 @events_by_day[i.created_on.to_date] ||= []
401 402 @events_by_day[i.created_on.to_date] << i
402 403 }
403 404 @show_documents = 1
404 405 end
405 406
406 407 end
407 408
408 409 def calendar
409 410 if params[:year] and params[:year].to_i > 1900
410 411 @year = params[:year].to_i
411 412 if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
412 413 @month = params[:month].to_i
413 414 end
414 415 end
415 416 @year ||= Date.today.year
416 417 @month ||= Date.today.month
417 418
418 419 @date_from = Date.civil(@year, @month, 1)
419 420 @date_to = (@date_from >> 1)-1
420 421 # start on monday
421 422 @date_from = @date_from - (@date_from.cwday-1)
422 423 # finish on sunday
423 424 @date_to = @date_to + (7-@date_to.cwday)
424 425
425 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])
426 427 render :layout => false if request.xhr?
427 428 end
428 429
429 430 def gantt
430 431 if params[:year] and params[:year].to_i >0
431 432 @year_from = params[:year].to_i
432 433 if params[:month] and params[:month].to_i >=1 and params[:month].to_i <= 12
433 434 @month_from = params[:month].to_i
434 435 else
435 436 @month_from = 1
436 437 end
437 438 else
438 439 @month_from ||= (Date.today << 1).month
439 440 @year_from ||= (Date.today << 1).year
440 441 end
441 442
442 443 @zoom = (params[:zoom].to_i > 0 and params[:zoom].to_i < 5) ? params[:zoom].to_i : 2
443 444 @months = (params[:months].to_i > 0 and params[:months].to_i < 25) ? params[:months].to_i : 6
444 445
445 446 @date_from = Date.civil(@year_from, @month_from, 1)
446 447 @date_to = (@date_from >> @months) - 1
447 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])
448 449
449 450 if params[:output]=='pdf'
450 451 @options_for_rfpdf ||= {}
451 452 @options_for_rfpdf[:file_name] = "gantt.pdf"
452 453 render :template => "projects/gantt.rfpdf", :layout => false
453 454 else
454 455 render :template => "projects/gantt.rhtml"
455 456 end
456 457 end
457 458
458 459 private
459 460 # Find project of id params[:id]
460 461 # if not found, redirect to project list
461 462 # Used as a before_filter
462 463 def find_project
463 464 @project = Project.find(params[:id])
464 465 @html_title = @project.name
465 466 rescue
466 467 redirect_to :action => 'list'
467 468 end
468 469 end
@@ -1,179 +1,179
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 module ApplicationHelper
19 19
20 20 # Return current logged in user or nil
21 21 def loggedin?
22 22 @logged_in_user
23 23 end
24 24
25 25 # Return true if user is logged in and is admin, otherwise false
26 26 def admin_loggedin?
27 27 @logged_in_user and @logged_in_user.admin?
28 28 end
29 29
30 30 # Return true if user is authorized for controller/action, otherwise false
31 31 def authorize_for(controller, action)
32 32 # check if action is allowed on public projects
33 33 if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ controller, action ]
34 34 return true
35 35 end
36 36 # check if user is authorized
37 37 if @logged_in_user and (@logged_in_user.admin? or Permission.allowed_to_role( "%s/%s" % [ controller, action ], @logged_in_user.role_for_project(@project.id) ) )
38 38 return true
39 39 end
40 40 return false
41 41 end
42 42
43 43 # Display a link if user is authorized
44 44 def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
45 45 link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller], options[:action])
46 46 end
47 47
48 48 # Display a link to user's account page
49 49 def link_to_user(user)
50 50 link_to user.display_name, :controller => 'account', :action => 'show', :id => user
51 51 end
52 52
53 53 def format_date(date)
54 54 l_date(date) if date
55 55 end
56 56
57 57 def format_time(time)
58 58 l_datetime(time) if time
59 59 end
60 60
61 61 def day_name(day)
62 62 l(:general_day_names).split(',')[day-1]
63 63 end
64 64
65 65 def pagination_links_full(paginator, options={}, html_options={})
66 66 html = ''
67 67 html << link_to_remote(('&#171; ' + l(:label_previous)),
68 68 {:update => "content", :url => { :page => paginator.current.previous }},
69 69 {:href => url_for(:action => 'list', :params => @params.merge({:page => paginator.current.previous}))}) + ' ' if paginator.current.previous
70 70
71 71 html << (pagination_links_each(paginator, options) do |n|
72 72 link_to_remote(n.to_s,
73 73 {:url => {:action => 'list', :params => @params.merge({:page => n})}, :update => 'content'},
74 74 {:href => url_for(:action => 'list', :params => @params.merge({:page => n}))})
75 75 end || '')
76 76
77 77 html << ' ' + link_to_remote((l(:label_next) + ' &#187;'),
78 78 {:update => "content", :url => { :page => paginator.current.next }},
79 79 {:href => url_for(:action => 'list', :params => @params.merge({:page => paginator.current.next}))}) if paginator.current.next
80 80 html
81 81 end
82 82
83 83 def textilizable(text)
84 $RDM_TEXTILE_DISABLED ? text : textilize(text)
84 $RDM_TEXTILE_DISABLED ? text : RedCloth.new(text).to_html
85 85 end
86 86
87 87 def error_messages_for(object_name, options = {})
88 88 options = options.symbolize_keys
89 89 object = instance_variable_get("@#{object_name}")
90 90 if object && !object.errors.empty?
91 91 # build full_messages here with controller current language
92 92 full_messages = []
93 93 object.errors.each do |attr, msg|
94 94 next if msg.nil?
95 95 if attr == "base"
96 96 full_messages << l(msg)
97 97 else
98 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"
99 99 end
100 100 end
101 101 # retrieve custom values error messages
102 102 if object.errors[:custom_values]
103 103 object.custom_values.each do |v|
104 104 v.errors.each do |attr, msg|
105 105 next if msg.nil?
106 106 full_messages << "&#171; " + v.custom_field.name + " &#187; " + l(msg)
107 107 end
108 108 end
109 109 end
110 110 content_tag("div",
111 111 content_tag(
112 112 options[:header_tag] || "h2", lwr(:gui_validation_error, full_messages.length) + " :"
113 113 ) +
114 114 content_tag("ul", full_messages.collect { |msg| content_tag("li", msg) }),
115 115 "id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
116 116 )
117 117 else
118 118 ""
119 119 end
120 120 end
121 121
122 122 def lang_options_for_select
123 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]}
124 124 end
125 125
126 126 def label_tag_for(name, option_tags = nil, options = {})
127 127 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
128 128 content_tag("label", label_text)
129 129 end
130 130
131 131 def labelled_tabular_form_for(name, object, options, &proc)
132 132 options[:html] ||= {}
133 133 options[:html].store :class, "tabular"
134 134 form_for(name, object, options.merge({ :builder => TabularFormBuilder, :lang => current_language}), &proc)
135 135 end
136 136
137 137 def check_all_links(form_name)
138 138 link_to_function(l(:button_check_all), "checkAll('#{form_name}', true)") +
139 139 " | " +
140 140 link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
141 141 end
142 142
143 143 def calendar_for(field_id)
144 144 image_tag("calendar", {:id => "#{field_id}_trigger",:class => "calendar-trigger"}) +
145 145 javascript_tag("Calendar.setup({inputField : '#{field_id}', ifFormat : '%Y-%m-%d', button : '#{field_id}_trigger' });")
146 146 end
147 147 end
148 148
149 149 class TabularFormBuilder < ActionView::Helpers::FormBuilder
150 150 include GLoc
151 151
152 152 def initialize(object_name, object, template, options, proc)
153 153 set_language_if_valid options.delete(:lang)
154 154 @object_name, @object, @template, @options, @proc = object_name, object, template, options, proc
155 155 end
156 156
157 157 (field_helpers - %w(radio_button hidden_field) + %w(date_select)).each do |selector|
158 158 src = <<-END_SRC
159 159 def #{selector}(field, options = {})
160 160 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
161 161 label = @template.content_tag("label", label_text,
162 162 :class => (@object.errors[field] ? "error" : nil),
163 163 :for => (@object_name.to_s + "_" + field.to_s))
164 164 label + super
165 165 end
166 166 END_SRC
167 167 class_eval src, __FILE__, __LINE__
168 168 end
169 169
170 170 def select(field, choices, options = {})
171 171 label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "")
172 172 label = @template.content_tag("label", label_text,
173 173 :class => (@object.errors[field] ? "error" : nil),
174 174 :for => (@object_name.to_s + "_" + field.to_s))
175 175 label + super
176 176 end
177 177
178 178 end
179 179
@@ -1,72 +1,77
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 module CustomFieldsHelper
19 19
20 20 # Return custom field html tag corresponding to its format
21 21 def custom_field_tag(custom_value)
22 22 custom_field = custom_value.custom_field
23 23 field_name = "custom_fields[#{custom_field.id}]"
24 24 field_id = "custom_fields_#{custom_field.id}"
25 25
26 26 case custom_field.field_format
27 27 when "string", "int"
28 28 text_field 'custom_value', 'value', :name => field_name, :id => field_id
29 29 when "date"
30 30 text_field('custom_value', 'value', :name => field_name, :id => field_id, :size => 10) +
31 31 calendar_for(field_id)
32 32 when "text"
33 33 text_area 'custom_value', 'value', :name => field_name, :id => field_id, :cols => 60, :rows => 3
34 34 when "bool"
35 35 check_box 'custom_value', 'value', :name => field_name, :id => field_id
36 36 when "list"
37 37 select 'custom_value', 'value', custom_field.possible_values.split('|'), { :include_blank => true }, :name => field_name, :id => field_id
38 38 end
39 39 end
40 40
41 41 # Return custom field label tag
42 42 def custom_field_label_tag(custom_value)
43 43 content_tag "label", custom_value.custom_field.name +
44 44 (custom_value.custom_field.is_required? ? " <span class=\"required\">*</span>" : ""),
45 45 :for => "custom_fields_#{custom_value.custom_field.id}",
46 46 :class => (custom_value.errors.empty? ? nil : "error" )
47 47 end
48 48
49 49 # Return custom field tag with its label tag
50 50 def custom_field_tag_with_label(custom_value)
51 51 custom_field_label_tag(custom_value) + custom_field_tag(custom_value)
52 52 end
53 53
54 54 # Return a string used to display a custom value
55 55 def show_value(custom_value)
56 56 return "" unless custom_value
57 format_value(custom_value.value, custom_value.custom_field.field_format)
58 end
57 59
58 case custom_value.custom_field.field_format
60 # Return a string used to display a custom value
61 def format_value(value, field_format)
62 return "" unless value
63 case field_format
59 64 when "date"
60 custom_value.value.empty? ? "" : l_date(custom_value.value.to_date)
65 value.empty? ? "" : l_date(value.to_date)
61 66 when "bool"
62 l_YesNo(custom_value.value == "1")
67 l_YesNo(value == "1")
63 68 else
64 custom_value.value
69 value
65 70 end
66 71 end
67 72
68 73 # Return an array of custom field formats which can be used in select_tag
69 74 def custom_field_formats_for_select
70 75 CustomField::FIELD_FORMATS.keys.collect { |k| [ l(CustomField::FIELD_FORMATS[k]), k ] }
71 76 end
72 77 end
@@ -1,48 +1,48
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require 'iconv'
19 19
20 20 module IfpdfHelper
21 21
22 22 class IFPDF < FPDF
23 23
24 24 attr_accessor :footer_date
25 25
26 26 def Cell(w,h=0,txt='',border=0,ln=0,align='',fill=0,link='')
27 27 @ic ||= Iconv.new('ISO-8859-1', 'UTF-8')
28 super w,h,@ic.iconv(txt),border,ln,align,fill,link
28 txt = begin
29 @ic.iconv(txt)
30 rescue
31 txt
29 32 end
30
31 def MultiCell(w,h,txt,border=0,align='J',fill=0)
32 @ic ||= Iconv.new('ISO-8859-1', 'UTF-8')
33 super w,h,txt,border,align,fill
33 super w,h,txt,border,ln,align,fill,link
34 34 end
35 35
36 36 def Footer
37 37 SetFont('Helvetica', 'I', 8)
38 38 SetY(-15)
39 39 SetX(15)
40 40 Cell(0, 5, @footer_date, 0, 0, 'L')
41 41 SetY(-15)
42 42 SetX(-30)
43 43 Cell(0, 5, PageNo().to_s + '/{nb}', 0, 0, 'C')
44 44 end
45 45
46 46 end
47 47
48 48 end
@@ -1,19 +1,74
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 module IssuesHelper
19
20 def show_detail(detail, no_html=false)
21 case detail.property
22 when 'attr'
23 label = l(("field_" + detail.prop_key.to_s.gsub(/\_id$/, "")).to_sym)
24 case detail.prop_key
25 when 'due_date', 'start_date'
26 value = format_date(detail.value.to_date) if detail.value
27 old_value = format_date(detail.old_value.to_date) if detail.old_value
28 when 'status_id'
29 s = IssueStatus.find_by_id(detail.value) and value = s.name if detail.value
30 s = IssueStatus.find_by_id(detail.old_value) and old_value = s.name if detail.old_value
31 when 'assigned_to_id'
32 u = User.find_by_id(detail.value) and value = u.name if detail.value
33 u = User.find_by_id(detail.old_value) and old_value = u.name if detail.old_value
34 when 'priority_id'
35 e = Enumeration.find_by_id(detail.value) and value = e.name if detail.value
36 e = Enumeration.find_by_id(detail.old_value) and old_value = e.name if detail.old_value
37 when 'category_id'
38 c = IssueCategory.find_by_id(detail.value) and value = c.name if detail.value
39 c = IssueCategory.find_by_id(detail.old_value) and old_value = c.name if detail.old_value
40 when 'fixed_version_id'
41 v = Version.find_by_id(detail.value) and value = v.name if detail.value
42 v = Version.find_by_id(detail.old_value) and old_value = v.name if detail.old_value
43 end
44 when 'cf'
45 custom_field = CustomField.find_by_id(detail.prop_key)
46 if custom_field
47 label = custom_field.name
48 value = format_value(detail.value, custom_field.field_format) if detail.value
49 old_value = format_value(detail.old_value, custom_field.field_format) if detail.old_value
50 end
51 end
52
53 label ||= detail.prop_key
54 value ||= detail.value
55 old_value ||= detail.old_value
56
57 unless no_html
58 label = content_tag('strong', label)
59 old_value = content_tag("i", old_value) if old_value
60 old_value = content_tag("strike", old_value) if old_value and !value
61 value = content_tag("i", value) if value
62 end
63
64 if value
65 if old_value
66 label + " " + l(:text_journal_changed, old_value, value)
67 else
68 label + " " + l(:text_journal_set_to, value)
69 end
70 else
71 label + " " + l(:text_journal_deleted) + " (#{old_value})"
72 end
73 end
19 74 end
@@ -1,74 +1,103
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class Issue < ActiveRecord::Base
19 19
20 20 belongs_to :project
21 21 belongs_to :tracker
22 22 belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
23 23 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
24 24 belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id'
25 25 belongs_to :fixed_version, :class_name => 'Version', :foreign_key => 'fixed_version_id'
26 26 belongs_to :priority, :class_name => 'Enumeration', :foreign_key => 'priority_id'
27 27 belongs_to :category, :class_name => 'IssueCategory', :foreign_key => 'category_id'
28 28
29 has_many :histories, :class_name => 'IssueHistory', :dependent => true, :order => "issue_histories.created_on DESC", :include => :status
29 #has_many :histories, :class_name => 'IssueHistory', :dependent => true, :order => "issue_histories.created_on DESC", :include => :status
30 has_many :journals, :as => :journalized, :dependent => true
30 31 has_many :attachments, :as => :container, :dependent => true
31 32
32 33 has_many :custom_values, :dependent => true, :as => :customized
33 34 has_many :custom_fields, :through => :custom_values
34 35
35 36 validates_presence_of :subject, :description, :priority, :tracker, :author, :status
36 37 validates_inclusion_of :done_ratio, :in => 0..100
37 38 validates_associated :custom_values, :on => :update
38 39
39 40 # set default status for new issues
40 41 def before_validation
41 42 self.status = IssueStatus.default if new_record?
42 43 end
43 44
44 45 def validate
45 46 if self.due_date.nil? && @attributes['due_date'] && !@attributes['due_date'].empty?
46 47 errors.add :due_date, :activerecord_error_not_a_date
47 48 end
48 49
49 50 if self.due_date and self.start_date and self.due_date < self.start_date
50 51 errors.add :due_date, :activerecord_error_greater_than_start_date
51 52 end
52 53 end
53 54
54 def before_create
55 build_history
55 #def before_create
56 # build_history
57 #end
58
59 def before_save
60 if @current_journal
61 # attributes changes
62 (Issue.column_names - %w(id description)).each {|c|
63 @current_journal.details << JournalDetail.new(:property => 'attr',
64 :prop_key => c,
65 :old_value => @issue_before_change.send(c),
66 :value => send(c)) unless send(c)==@issue_before_change.send(c)
67 }
68 # custom fields changes
69 custom_values.each {|c|
70 @current_journal.details << JournalDetail.new(:property => 'cf',
71 :prop_key => c.custom_field_id,
72 :old_value => @custom_values_before_change[c.custom_field_id],
73 :value => c.value) unless @custom_values_before_change[c.custom_field_id]==c.value
74 }
75 @current_journal.save unless @current_journal.details.empty? and @current_journal.notes.empty?
76 end
56 77 end
57 78
58 79 def long_id
59 80 "%05d" % self.id
60 81 end
61 82
62 83 def custom_value_for(custom_field)
63 84 self.custom_values.each {|v| return v if v.custom_field_id == custom_field.id }
64 85 return nil
65 86 end
66 87
88 def init_journal(user, notes = "")
89 @current_journal ||= Journal.new(:journalized => self, :user => user, :notes => notes)
90 @issue_before_change = self.clone
91 @custom_values_before_change = {}
92 self.custom_values.each {|c| @custom_values_before_change.store c.custom_field_id, c.value }
93 @current_journal
94 end
95
67 96 private
68 97 # Creates an history for the issue
69 def build_history
70 @history = self.histories.build
71 @history.status = self.status
72 @history.author = self.author
73 end
98 #def build_history
99 # @history = self.histories.build
100 # @history.status = self.status
101 # @history.author = self.author
102 #end
74 103 end
@@ -1,57 +1,51
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class Mailer < ActionMailer::Base
19 19
20 def issue_change_status(issue)
20 def issue_add(issue)
21 21 # Sends to all project members
22 22 @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
23 23 @from = $RDM_MAIL_FROM
24 24 @subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
25 25 @body['issue'] = issue
26 26 end
27 27
28 def issue_add(issue)
28 def issue_edit(journal)
29 29 # Sends to all project members
30 issue = journal.journalized
30 31 @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
31 32 @from = $RDM_MAIL_FROM
32 33 @subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
33 34 @body['issue'] = issue
34 end
35
36 def issue_add_note(history)
37 # Sends to all project members
38 @recipients = history.issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
39 @from = $RDM_MAIL_FROM
40 @subject = "[#{history.issue.project.name} - #{history.issue.tracker.name} ##{history.issue.id}] #{history.issue.status.name} - #{history.issue.subject}"
41 @body['history'] = history
35 @body['journal']= journal
42 36 end
43 37
44 38 def lost_password(token)
45 39 @recipients = token.user.mail
46 40 @from = $RDM_MAIL_FROM
47 41 @subject = l(:mail_subject_lost_password)
48 42 @body['token'] = token
49 43 end
50 44
51 45 def register(token)
52 46 @recipients = token.user.mail
53 47 @from = $RDM_MAIL_FROM
54 48 @subject = l(:mail_subject_register)
55 49 @body['token'] = token
56 50 end
57 51 end
@@ -1,95 +1,100
1 1 <% pdf.SetFont('Arial','B',11)
2 2 pdf.Cell(190,10, "#{issue.project.name} - #{issue.tracker.name} # #{issue.long_id} - #{issue.subject}")
3 3 pdf.Ln
4 4
5 5 y0 = pdf.GetY
6 6
7 7 pdf.SetFont('Arial','B',9)
8 8 pdf.Cell(35,5, l(:field_status) + ":","LT")
9 9 pdf.SetFont('Arial','',9)
10 10 pdf.Cell(60,5, issue.status.name,"RT")
11 11 pdf.SetFont('Arial','B',9)
12 12 pdf.Cell(35,5, l(:field_priority) + ":","LT")
13 13 pdf.SetFont('Arial','',9)
14 14 pdf.Cell(60,5, issue.priority.name,"RT")
15 15 pdf.Ln
16 16
17 17 pdf.SetFont('Arial','B',9)
18 18 pdf.Cell(35,5, l(:field_author) + ":","L")
19 19 pdf.SetFont('Arial','',9)
20 20 pdf.Cell(60,5, issue.author.name,"R")
21 21 pdf.SetFont('Arial','B',9)
22 22 pdf.Cell(35,5, l(:field_category) + ":","L")
23 23 pdf.SetFont('Arial','',9)
24 24 pdf.Cell(60,5, (issue.category ? issue.category.name : "-"),"R")
25 25 pdf.Ln
26 26
27 27 pdf.SetFont('Arial','B',9)
28 28 pdf.Cell(35,5, l(:field_created_on) + ":","L")
29 29 pdf.SetFont('Arial','',9)
30 30 pdf.Cell(60,5, format_date(issue.created_on),"R")
31 31 pdf.SetFont('Arial','B',9)
32 32 pdf.Cell(35,5, l(:field_assigned_to) + ":","L")
33 33 pdf.SetFont('Arial','',9)
34 34 pdf.Cell(60,5, (issue.assigned_to ? issue.assigned_to.name : "-"),"R")
35 35 pdf.Ln
36 36
37 37 pdf.SetFont('Arial','B',9)
38 38 pdf.Cell(35,5, l(:field_updated_on) + ":","LB")
39 39 pdf.SetFont('Arial','',9)
40 40 pdf.Cell(60,5, format_date(issue.updated_on),"RB")
41 41 pdf.SetFont('Arial','B',9)
42 42 pdf.Cell(35,5, l(:field_due_date) + ":","LB")
43 43 pdf.SetFont('Arial','',9)
44 44 pdf.Cell(60,5, format_date(issue.due_date),"RB")
45 45 pdf.Ln
46 46
47 47 for custom_value in issue.custom_values
48 48 pdf.SetFont('Arial','B',9)
49 49 pdf.Cell(35,5, custom_value.custom_field.name + ":","L")
50 50 pdf.SetFont('Arial','',9)
51 51 pdf.MultiCell(155,5, (show_value custom_value),"R")
52 52 end
53 53
54 54 pdf.SetFont('Arial','B',9)
55 55 pdf.Cell(35,5, l(:field_subject) + ":","LTB")
56 56 pdf.SetFont('Arial','',9)
57 57 pdf.Cell(155,5, issue.subject,"RTB")
58 58 pdf.Ln
59 59
60 60 pdf.SetFont('Arial','B',9)
61 61 pdf.Cell(35,5, l(:field_description) + ":")
62 62 pdf.SetFont('Arial','',9)
63 63 pdf.MultiCell(155,5, issue.description,"BR")
64 64
65 65 pdf.Line(pdf.GetX, y0, pdf.GetX, pdf.GetY)
66 66 pdf.Line(pdf.GetX, pdf.GetY, 170, pdf.GetY)
67 67
68 68 pdf.Ln
69
69 70 pdf.SetFont('Arial','B',9)
70 71 pdf.Cell(190,5, l(:label_history),"B")
71 72 pdf.Ln
72 for history in issue.histories.find(:all, :include => [:author, :status])
73 for journal in issue.journals.find(:all, :include => :user, :order => "journals.created_on desc")
73 74 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)
75 pdf.Cell(190,5, format_time(journal.created_on) + " - " + journal.user.name)
76 pdf.Ln
77 pdf.SetFont('Arial','I',8)
78 for detail in journal.details
79 pdf.Cell(190,5, "- " + show_detail(detail, true))
79 80 pdf.Ln
80 pdf.Cell(10,4, "") and pdf.MultiCell(180,4, history.notes) if history.notes?
81 end
82 if journal.notes?
83 pdf.SetFont('Arial','',8)
84 pdf.MultiCell(190,5, journal.notes)
81 85 end
82 86 pdf.Ln
87 end
83 88
84 89 pdf.SetFont('Arial','B',9)
85 90 pdf.Cell(190,5, l(:label_attachment_plural), "B")
86 91 pdf.Ln
87 92 for attachment in issue.attachments
88 93 pdf.SetFont('Arial','',8)
89 94 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))
95 pdf.Cell(20,5, human_size(attachment.filesize),0,0,"R")
96 pdf.Cell(20,5, format_date(attachment.created_on),0,0,"R")
92 97 pdf.Cell(70,5, attachment.author.name,0,0,"R")
93 98 pdf.Ln
94 99 end
95 100 %> No newline at end of file
@@ -1,36 +1,37
1 1 <h2><%=l(:label_issue)%> #<%= @issue.id %>: <%= @issue.subject %></h2>
2 2
3 <%= error_messages_for 'history' %>
3 <%= error_messages_for 'issue' %>
4 4 <%= start_form_tag({:action => 'change_status', :id => @issue}, :class => "tabular") %>
5 5
6 6 <%= hidden_field_tag 'confirm', 1 %>
7 <%= hidden_field 'history', 'status_id' %>
7 <%= hidden_field_tag 'new_status_id', @new_status.id %>
8 8
9 9 <div class="box">
10 <p><label><%=l(:label_issue_status_new)%></label> <%= @history.status.name %></p>
10 <p><label><%=l(:label_issue_status_new)%></label> <%= @new_status.name %></p>
11 11
12 12 <p><label for="issue_assigned_to_id"><%=l(:field_assigned_to)%></label>
13 13 <select name="issue[assigned_to_id]">
14 14 <option value=""></option>
15 15 <%= options_from_collection_for_select @assignable_to, "id", "display_name", @issue.assigned_to_id %></p>
16 16 </select></p>
17 17
18 18
19 19 <p><label for="issue_done_ratio"><%=l(:field_done_ratio)%></label>
20 20 <%= select("issue", "done_ratio", ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) ) %>
21 21 </select></p>
22 22
23 23
24 24 <p><label for="issue_fixed_version"><%=l(:field_fixed_version)%></label>
25 25 <select name="issue[fixed_version_id]">
26 26 <option value="">--none--</option>
27 27 <%= options_from_collection_for_select @issue.project.versions, "id", "name", @issue.fixed_version_id %>
28 28 </select></p>
29 29
30 <p><label for="history_notes"><%=l(:field_notes)%></label>
31 <%= text_area 'history', 'notes', :cols => 60, :rows => 10 %></p>
30 <p><label for="notes"><%= l(:field_notes) %></label>
31 <%= text_area_tag 'notes', @notes, :cols => 60, :rows => 10 %></p>
32
32 33 </div>
33 34
34 35 <%= hidden_field 'issue', 'lock_version' %>
35 36 <%= submit_tag l(:button_save) %>
36 37 <%= end_form_tag %>
@@ -1,49 +1,49
1 1 <h2><%= @issue.tracker.name %> #<%= @issue.id %> - <%= @issue.subject %></h2>
2 2
3 3 <% labelled_tabular_form_for :issue, @issue, :url => {:action => 'edit'} do |f| %>
4 4 <%= error_messages_for 'issue' %>
5 5 <div class="box">
6 6 <!--[form:issue]-->
7 7 <div class="splitcontentleft">
8 8 <p><label><%=l(:field_status)%></label> <%= @issue.status.name %></p>
9 9 <p><%= f.select :priority_id, (@priorities.collect {|p| [p.name, p.id]}), :required => true %></p>
10 10 <p><%= f.select :assigned_to_id, (@issue.project.members.collect {|m| [m.name, m.user_id]}), :include_blank => true %></p>
11 11 <p><%= f.select :category_id, (@project.issue_categories.collect {|c| [c.name, c.id]}) %></p>
12 12 </div>
13 13
14 14 <div class="splitcontentright">
15 15 <p><%= f.text_field :start_date, :size => 10 %><%= calendar_for('issue_start_date') %></p>
16 16 <p><%= f.text_field :due_date, :size => 10 %><%= calendar_for('issue_due_date') %></p>
17 17 <p><%= f.select :done_ratio, ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) %></p>
18 18 </div>
19 19
20 20 <div class="clear">
21 21 <p><%= f.text_field :subject, :size => 80, :required => true %></p>
22 <p><%= f.text_area :description, :cols => 60, :rows => 10, :required => true %></p>
22 <p><%= f.text_area :description, :cols => 60, :rows => [[10, @issue.description.length / 50].max, 100].min, :required => true %></p>
23 23
24 24 <% for @custom_value in @custom_values %>
25 25 <p><%= custom_field_tag_with_label @custom_value %></p>
26 26 <% end %>
27 27
28 28 <p><%= f.select :fixed_version_id, (@project.versions.collect {|v| [v.name, v.id]}), { :include_blank => true } %>
29 29 </select></p>
30 30 </div>
31 31 <!--[eoform:issue]-->
32 32 </div>
33 33 <%= f.hidden_field :lock_version %>
34 34 <%= submit_tag l(:button_save) %>
35 35 <% end %>
36 36
37 37 <% unless $RDM_TEXTILE_DISABLED %>
38 38 <%= javascript_include_tag 'jstoolbar' %>
39 39 <script type="text/javascript">
40 40 //<![CDATA[
41 41 if (document.getElementById) {
42 42 if (document.getElementById('issue_description')) {
43 43 var commentTb = new jsToolBar(document.getElementById('issue_description'));
44 44 commentTb.draw();
45 45 }
46 46 }
47 47 //]]>
48 48 </script>
49 49 <% end %> No newline at end of file
@@ -1,138 +1,133
1 1 <h2><%= @issue.tracker.name %> #<%= @issue.id %> - <%= @issue.subject %></h2>
2 2 <div class="topright">
3 3 <small>
4 4 <%= link_to 'PDF', :action => 'export_pdf', :id => @issue %>
5 5 </small>
6 6 </div>
7 7
8 8 <div class="box">
9 9 <table width="100%">
10 10 <tr>
11 11 <td width="15%"><b><%=l(:field_status)%> :</b></td><td width="35%"><%= @issue.status.name %></td>
12 12 <td width="15%"><b><%=l(:field_priority)%> :</b></td><td width="35%"><%= @issue.priority.name %></td>
13 13 </tr>
14 14 <tr>
15 15 <td><b><%=l(:field_assigned_to)%> :</b></td><td><%= @issue.assigned_to ? @issue.assigned_to.name : "-" %></td>
16 16 <td><b><%=l(:field_category)%> :</b></td><td><%= @issue.category ? @issue.category.name : "-" %></td>
17 17 </tr>
18 18 <tr>
19 19 <td><b><%=l(:field_author)%> :</b></td><td><%= link_to_user @issue.author %></td>
20 20 <td><b><%=l(:field_start_date)%> :</b></td><td><%= format_date(@issue.start_date) %></td>
21 21 </tr>
22 22 <tr>
23 23 <td><b><%=l(:field_created_on)%> :</b></td><td><%= format_date(@issue.created_on) %></td>
24 24 <td><b><%=l(:field_due_date)%> :</b></td><td><%= format_date(@issue.due_date) %></td>
25 25 </tr>
26 26 <tr>
27 27 <td><b><%=l(:field_updated_on)%> :</b></td><td><%= format_date(@issue.updated_on) %></td>
28 28 <td><b><%=l(:field_done_ratio)%> :</b></td><td><%= @issue.done_ratio %> %</td>
29 29 </tr>
30 30 <tr>
31 31 <% n = 0
32 32 for custom_value in @custom_values %>
33 33 <td><b><%= custom_value.custom_field.name %> :</b></td><td><%= show_value custom_value %></td>
34 34 <% n = n + 1
35 35 if (n > 1)
36 36 n = 0 %>
37 37 </tr><tr>
38 38 <%end
39 39 end %>
40 40 </tr>
41 41 </table>
42 42 <hr />
43 43 <br />
44 44
45 45 <b><%=l(:field_description)%> :</b><br /><br />
46 46 <%= textilizable @issue.description %>
47
48 <p>
47 <br />
48 <div style="float:left;">
49 49 <% if authorize_for('issues', 'edit') %>
50 50 <%= start_form_tag ({:controller => 'issues', :action => 'edit', :id => @issue}, :method => "get" ) %>
51 51 <%= submit_tag l(:button_edit) %>
52 52 <%= end_form_tag %>
53 53 &nbsp;&nbsp;
54 54 <% end %>
55 55
56 56 <% if authorize_for('issues', 'change_status') and @status_options and !@status_options.empty? %>
57 57 <%= start_form_tag ({:controller => 'issues', :action => 'change_status', :id => @issue}) %>
58 58 <%=l(:label_change_status)%> :
59 <select name="history[status_id]">
59 <select name="new_status_id">
60 60 <%= options_from_collection_for_select @status_options, "id", "name" %>
61 61 </select>
62 62 <%= submit_tag l(:button_change) %>
63 63 <%= end_form_tag %>
64 64 &nbsp;&nbsp;
65 65 <% end %>
66 66
67 67 <% if authorize_for('projects', 'move_issues') %>
68 68 <%= start_form_tag ({:controller => 'projects', :action => 'move_issues', :id => @project} ) %>
69 69 <%= hidden_field_tag "issue_ids[]", @issue.id %>
70 70 <%= submit_tag l(:button_move) %>
71 71 <%= end_form_tag %>
72 72 &nbsp;&nbsp;
73 73 <% end %>
74
74 </div>
75 <div style="float:right;">
75 76 <% if authorize_for('issues', 'destroy') %>
76 77 <%= start_form_tag ({:controller => 'issues', :action => 'destroy', :id => @issue} ) %>
77 78 <%= submit_tag l(:button_delete) %>
78 79 <%= end_form_tag %>
79 80 &nbsp;&nbsp;
80 81 <% end %>
81 </p>
82 </div>
83 <div class="clear"></div>
82 84 </div>
83 85
84 <div class="box">
85 <h3><%=l(:label_history)%></h3>
86 <table width="100%">
87 <% for history in @issue.histories.find(:all, :include => [:author, :status]) %>
88 <tr>
89 <td><%= format_date(history.created_on) %></td>
90 <td><%= history.author.display_name %></td>
91 <td><b><%= history.status.name %></b></td>
92 </tr>
93 <% if history.notes? %>
94 <tr><td colspan=3><%= simple_format auto_link history.notes %></td></tr>
86 <div id="history" class="box">
87 <h3><%=l(:label_history)%>
88 <% if @journals_count > @journals.length %>(<%= l(:label_last_changes, @journals.length) %>)<% end %></h3>
89 <%= render :partial => 'history', :locals => { :journals => @journals } %>
90 <% if @journals_count > @journals.length %>
91 <p><center><small>[ <%= link_to l(:label_change_view_all), :action => 'history', :id => @issue %> ]</small></center></p>
95 92 <% end %>
96 <% end %>
97 </table>
98 93 </div>
99 94
100 95 <div class="box">
101 96 <h3><%=l(:label_attachment_plural)%></h3>
102 97 <table width="100%">
103 98 <% for attachment in @issue.attachments %>
104 99 <tr>
105 100 <td><%= image_tag('attachment') %> <%= link_to attachment.filename, :action => 'download', :id => @issue, :attachment_id => attachment %> (<%= human_size(attachment.filesize) %>)</td>
106 101 <td><%= format_date(attachment.created_on) %></td>
107 102 <td><%= attachment.author.display_name %></td>
108 103 <% if authorize_for('issues', 'destroy_attachment') %>
109 104 <td>
110 105 <%= start_form_tag :action => 'destroy_attachment', :id => @issue, :attachment_id => attachment %>
111 106 <%= submit_tag l(:button_delete), :class => "button-small" %>
112 107 <%= end_form_tag %>
113 108 </td>
114 109 <% end %>
115 110 </tr>
116 111 <% end %>
117 112 </table>
118 113 <br />
119 114 <% if authorize_for('issues', 'add_attachment') %>
120 115 <%= start_form_tag ({ :controller => 'issues', :action => 'add_attachment', :id => @issue }, :multipart => true, :class => "tabular") %>
121 116 <p id="attachments_p"><label><%=l(:label_attachment_new)%>&nbsp;
122 117 <%= link_to_function image_tag('add'), "addFileField()" %></label>
123 118 <%= file_field_tag 'attachments[]', :size => 30 %></p>
124 119 <%= submit_tag l(:button_add) %>
125 120 <%= end_form_tag %>
126 121 <% end %>
127 122 </div>
128 123
129 124 <% if authorize_for('issues', 'add_note') %>
130 125 <div class="box">
131 126 <h3><%= l(:label_add_note) %></h3>
132 127 <%= start_form_tag ({:controller => 'issues', :action => 'add_note', :id => @issue}, :class => "tabular" ) %>
133 <p><label for="history_notes"><%=l(:field_notes)%></label>
134 <%= text_area 'history', 'notes', :cols => 60, :rows => 10 %></p>
128 <p><label for="notes"><%=l(:field_notes)%></label>
129 <%= text_area_tag 'notes', '', :cols => 60, :rows => 10 %></p>
135 130 <%= submit_tag l(:button_add) %>
136 131 <%= end_form_tag %>
137 132 </div>
138 133 <% end %>
@@ -1,142 +1,142
1 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2 2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
3 3 <head>
4 4 <title><%= $RDM_HEADER_TITLE + (@html_title ? ": #{@html_title}" : "") %></title>
5 5 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
6 6 <meta name="description" content="redMine" />
7 7 <meta name="keywords" content="issue,bug,tracker" />
8 8 <%= stylesheet_link_tag "application" %>
9 9 <%= stylesheet_link_tag "menu" %>
10 10 <%= stylesheet_link_tag "rails" %>
11 11 <%= javascript_include_tag :defaults %>
12 12 <%= javascript_include_tag 'menu' %>
13 13 <%= javascript_include_tag 'calendar/calendar' %>
14 14 <%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
15 15 <%= javascript_include_tag 'calendar/calendar-setup' %>
16 16 <%= stylesheet_link_tag 'calendar' %>
17 17 <%= stylesheet_link_tag 'jstoolbar' %>
18 18 <script type='text/javascript'>
19 19 var menu_contenu=' \
20 20 <div id="menuAdmin" class="menu" onmouseover="menuMouseover(event)"> \
21 21 <a class="menuItem" href="\/admin\/projects" onmouseover="menuItemMouseover(event,\'menuProjects\');"><span class="menuItemText"><%=l(:label_project_plural)%><\/span><span class="menuItemArrow">&#9654;<\/span><\/a> \
22 22 <a class="menuItem" href="\/users" onmouseover="menuItemMouseover(event,\'menuUsers\');"><span class="menuItemText"><%=l(:label_user_plural)%><\/span><span class="menuItemArrow">&#9654;<\/span><\/a> \
23 23 <a class="menuItem" href="\/roles"><%=l(:label_role_and_permissions)%><\/a> \
24 24 <a class="menuItem" href="\/trackers" onmouseover="menuItemMouseover(event,\'menuTrackers\');"><span class="menuItemText"><%=l(:label_tracker_plural)%><\/span><span class="menuItemArrow">&#9654;<\/span><\/a> \
25 25 <a class="menuItem" href="\/custom_fields"><%=l(:label_custom_field_plural)%><\/a> \
26 26 <a class="menuItem" href="\/enumerations"><%=l(:label_enumerations)%><\/a> \
27 27 <a class="menuItem" href="\/admin\/mail_options"><%=l(:field_mail_notification)%><\/a> \
28 28 <a class="menuItem" href="\/auth_sources"><%=l(:label_authentication)%><\/a> \
29 29 <a class="menuItem" href="\/admin\/info"><%=l(:label_information_plural)%><\/a> \
30 30 <\/div> \
31 31 <div id="menuTrackers" class="menu"> \
32 32 <a class="menuItem" href="\/issue_statuses"><%=l(:label_issue_status_plural)%><\/a> \
33 33 <a class="menuItem" href="\/roles\/workflow"><%=l(:label_workflow)%><\/a> \
34 34 <\/div> \
35 35 <div id="menuProjects" class="menu"><a class="menuItem" href="\/projects\/add"><%=l(:label_new)%><\/a><\/div> \
36 36 <div id="menuUsers" class="menu"><a class="menuItem" href="\/users\/add"><%=l(:label_new)%><\/a><\/div> \
37 37 \
38 38 <% unless @project.nil? || @project.id.nil? %> \
39 39 <div id="menuProject" class="menu" onmouseover="menuMouseover(event)"> \
40 40 <%= link_to l(:label_calendar), {:controller => 'projects', :action => 'calendar', :id => @project }, :class => "menuItem" %> \
41 41 <%= link_to l(:label_issue_plural), {:controller => 'projects', :action => 'list_issues', :id => @project }, :class => "menuItem" %> \
42 42 <%= link_to l(:label_report_plural), {:controller => 'reports', :action => 'issue_report', :id => @project }, :class => "menuItem" %> \
43 43 <%= link_to l(:label_activity), {:controller => 'projects', :action => 'activity', :id => @project }, :class => "menuItem" %> \
44 44 <%= link_to l(:label_news_plural), {:controller => 'projects', :action => 'list_news', :id => @project }, :class => "menuItem" %> \
45 45 <%= link_to l(:label_change_log), {:controller => 'projects', :action => 'changelog', :id => @project }, :class => "menuItem" %> \
46 46 <%= link_to l(:label_document_plural), {:controller => 'projects', :action => 'list_documents', :id => @project }, :class => "menuItem" %> \
47 47 <%= link_to l(:label_member_plural), {:controller => 'projects', :action => 'list_members', :id => @project }, :class => "menuItem" %> \
48 48 <%= link_to l(:label_attachment_plural), {:controller => 'projects', :action => 'list_files', :id => @project }, :class => "menuItem" %> \
49 49 <%= link_to_if_authorized l(:label_settings), {:controller => 'projects', :action => 'settings', :id => @project }, :class => "menuItem" %> \
50 50 <\/div> \
51 51 <% end %> \
52 52 ';
53 53 </script>
54 54
55 55 </head>
56 56
57 57 <body>
58 58 <div id="container" >
59 59
60 60 <div id="header">
61 61 <div style="float: left;">
62 62 <h1><%= $RDM_HEADER_TITLE %></h1>
63 63 <h2><%= $RDM_HEADER_SUBTITLE %></h2>
64 64 </div>
65 65 <div style="float: right; padding-right: 1em; padding-top: 0.2em;">
66 66 <% if loggedin? %><small><%=l(:label_logged_as)%> <b><%= @logged_in_user.login %></b></small><% end %>
67 67 </div>
68 68 </div>
69 69
70 70 <div id="navigation">
71 71 <ul>
72 72 <li class="selected"><%= link_to l(:label_home), { :controller => '' }, :class => "picHome" %></li>
73 73 <li><%= link_to l(:label_my_page), { :controller => 'account', :action => 'my_page'}, :class => "picUserPage" %></li>
74 74 <li><%= link_to l(:label_project_plural), { :controller => 'projects' }, :class => "picProject" %></li>
75 75
76 76 <% unless @project.nil? || @project.id.nil? %>
77 77 <li><%= link_to @project.name, { :controller => 'projects', :action => 'show', :id => @project }, :class => "picProject", :onmouseover => "buttonMouseover(event, 'menuProject');" %></li>
78 78 <% end %>
79 79
80 80 <% if loggedin? %>
81 81 <li><%= link_to l(:label_my_account), { :controller => 'account', :action => 'my_account' }, :class => "picUser" %></li>
82 82 <% end %>
83 83
84 84 <% if admin_loggedin? %>
85 85 <li><%= link_to l(:label_administration), { :controller => 'admin' }, :class => "picAdmin", :onmouseover => "buttonMouseover(event, 'menuAdmin');" %></li>
86 86 <% end %>
87 87
88 88 <li class="right"><%= link_to l(:label_help), { :controller => 'help', :ctrl => @params[:controller], :page => @params[:action] }, :target => "new", :class => "picHelp" %></li>
89 89
90 90 <% if loggedin? %>
91 91 <li class="right"><%= link_to l(:label_logout), { :controller => 'account', :action => 'logout' }, :class => "picUser" %></li>
92 92 <% else %>
93 93 <li class="right"><%= link_to l(:label_login), { :controller => 'account', :action => 'login' }, :class => "picUser" %></li>
94 94 <% end %>
95 95 </ul>
96 96 </div>
97 97 <script type='text/javascript'>if(document.getElementById) {document.write(menu_contenu);}</script>
98 98
99 99 <div id="subcontent">
100 100
101 101 <% unless @project.nil? || @project.id.nil? %>
102 102 <h2><%= @project.name %></h2>
103 103 <ul class="menublock">
104 104 <li><%= link_to l(:label_overview), :controller => 'projects', :action => 'show', :id => @project %></li>
105 105 <li><%= link_to l(:label_calendar), :controller => 'projects', :action => 'calendar', :id => @project %></li>
106 106 <li><%= link_to l(:label_issue_plural), :controller => 'projects', :action => 'list_issues', :id => @project %></li>
107 107 <li><%= link_to l(:label_report_plural), :controller => 'reports', :action => 'issue_report', :id => @project %></li>
108 108 <li><%= link_to l(:label_activity), :controller => 'projects', :action => 'activity', :id => @project %></li>
109 109 <li><%= link_to l(:label_news_plural), :controller => 'projects', :action => 'list_news', :id => @project %></li>
110 110 <li><%= link_to l(:label_change_log), :controller => 'projects', :action => 'changelog', :id => @project %></li>
111 111 <li><%= link_to l(:label_document_plural), :controller => 'projects', :action => 'list_documents', :id => @project %></li>
112 112 <li><%= link_to l(:label_member_plural), :controller => 'projects', :action => 'list_members', :id => @project %></li>
113 113 <li><%= link_to l(:label_attachment_plural), :controller => 'projects', :action => 'list_files', :id => @project %></li>
114 114 <li><%= link_to_if_authorized l(:label_settings), :controller => 'projects', :action => 'settings', :id => @project %></li>
115 115 </ul>
116 116 <% end %>
117 117
118 118 <% if loggedin? and @logged_in_user.memberships.length > 0 %>
119 119 <h2><%=l(:label_my_projects) %></h2>
120 120 <ul class="menublock">
121 121 <% for membership in @logged_in_user.memberships %>
122 122 <li><%= link_to membership.project.name, :controller => 'projects', :action => 'show', :id => membership.project %></li>
123 123 <% end %>
124 124 </ul>
125 125 <% end %>
126 126 </div>
127 127
128 128 <div id="content">
129 129 <% if flash[:notice] %><p style="color: green"><%= flash[:notice] %></p><% end %>
130 130 <%= @content_for_layout %>
131 131 </div>
132 132
133 133 <div id="footer">
134 134 <p>
135 135 <%= auto_link $RDM_FOOTER_SIG %> |
136 <a href="http://redmine.org/" target="_new"><%= RDM_APP_NAME %></a> <%= RDM_APP_VERSION %>
136 <a href="http://redmine.rubyforge.org/" target="_new"><%= RDM_APP_NAME %></a> <%= RDM_APP_VERSION %>
137 137 </p>
138 138 </div>
139 139
140 140 </div>
141 141 </body>
142 142 </html> No newline at end of file
@@ -1,94 +1,95
1 1 == redMine changelog
2 2
3 3 redMine - project management software
4 4 Copyright (C) 2006 Jean-Philippe Lang
5 5 http://redmine.org/
6 6
7 7
8 8 == xx/xx/2006 v0.x.x
9 9
10 * improved issues change history
10 11 * new functionality: move an issue to another project or tracker
11 12 * new functionality: add a note to an issue
12 13 * new report: project activity
13 14 * "start date" and "% done" fields added on issues
14 15 * project calendar added
15 16 * gantt chart added (exportable to pdf)
16 17 * single/multiple issues pdf export added
17 18 * issues reports improvements
18 19 * multiple file upload for issues attachments
19 20 * textile formating of issue and news descritions (RedCloth required)
20 21 * integration of DotClear jstoolbar for textile formatting
21 22 * calendar date picker for date fields (LGPL DHTML Calendar http://sourceforge.net/projects/jscalendar)
22 23 * new filter in issues list: Author
23 24 * ajaxified paginators
24 25 * option to set number of results per page on issues list
25 26 * localized csv separator (comma/semicolon)
26 27 * csv output encoded to ISO-8859-1
27 28 * user custom field displayed on account/show
28 29 * default configuration improved (default roles, trackers, status, permissions and workflows)
29 30 * fixed: custom fields not in csv exports
30 31 * fixed: project settings now displayed according to user's permissions
31 32
32 33 == 10/08/2006 v0.3.0
33 34
34 35 * user authentication against multiple LDAP (optional)
35 36 * token based "lost password" functionality
36 37 * user self-registration functionality (optional)
37 38 * custom fields now available for issues, users and projects
38 39 * new custom field format "text" (displayed as a textarea field)
39 40 * project & administration drop down menus in navigation bar for quicker access
40 41 * text formatting is preserved for long text fields (issues, projects and news descriptions)
41 42 * urls and emails are turned into clickable links in long text fields
42 43 * "due date" field added on issues
43 44 * tracker selection filter added on change log
44 45 * Localization plugin replaced with GLoc 1.1.0 (iconv required)
45 46 * error messages internationalization
46 47 * german translation added (thanks to Karim Trott)
47 48 * data locking for issues to prevent update conflicts (using ActiveRecord builtin optimistic locking)
48 49 * new filter in issues list: "Fixed version"
49 50 * active filters are displayed with colored background on issues list
50 51 * custom configuration is now defined in config/config_custom.rb
51 52 * user object no more stored in session (only user_id)
52 53 * news summary field is no longer required
53 54 * tables and forms redesign
54 55 * Fixed: boolean custom field not working
55 56 * Fixed: error messages for custom fields are not displayed
56 57 * Fixed: invalid custom fields should have a red border
57 58 * Fixed: custom fields values are not validated on issue update
58 59 * Fixed: unable to choose an empty value for 'List' custom fields
59 60 * Fixed: no issue categories sorting
60 61 * Fixed: incorrect versions sorting
61 62
62 63
63 64 == 07/12/2006 - v0.2.2
64 65
65 66 * Fixed: bug in "issues list"
66 67
67 68
68 69 == 07/09/2006 - v0.2.1
69 70
70 71 * new databases supported: Oracle, PostgreSQL, SQL Server
71 72 * projects/subprojects hierarchy (1 level of subprojects only)
72 73 * environment information display in admin/info
73 74 * more filter options in issues list (rev6)
74 75 * default language based on browser settings (Accept-Language HTTP header)
75 76 * issues list exportable to CSV (rev6)
76 77 * simple_format and auto_link on long text fields
77 78 * more data validations
78 79 * Fixed: error when all mail notifications are unchecked in admin/mail_options
79 80 * Fixed: all project news are displayed on project summary
80 81 * Fixed: Can't change user password in users/edit
81 82 * Fixed: Error on tables creation with PostgreSQL (rev5)
82 83 * Fixed: SQL error in "issue reports" view with PostgreSQL (rev5)
83 84
84 85
85 86 == 06/25/2006 - v0.1.0
86 87
87 88 * multiple users/multiple projects
88 89 * role based access control
89 90 * issue tracking system
90 91 * fully customizable workflow
91 92 * documents/files repository
92 93 * email notifications on issue creation and update
93 94 * multilanguage support (except for error messages):english, french, spanish
94 95 * online manual in french (unfinished) No newline at end of file
@@ -1,310 +1,315
1 1 _gloc_rule_default: '|n| n==1 ? "" : "_plural" '
2 2
3 3 actionview_datehelper_select_day_prefix:
4 4 actionview_datehelper_select_month_names: January,February,March,April,May,June,July,August,September,October,November,December
5 5 actionview_datehelper_select_month_names_abbr: Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
6 6 actionview_datehelper_select_month_prefix:
7 7 actionview_datehelper_select_year_prefix:
8 8 actionview_datehelper_time_in_words_day: 1 day
9 9 actionview_datehelper_time_in_words_day_plural: %d days
10 10 actionview_datehelper_time_in_words_hour_about: about an hour
11 11 actionview_datehelper_time_in_words_hour_about_plural: about %d hours
12 12 actionview_datehelper_time_in_words_hour_about_single: about an hour
13 13 actionview_datehelper_time_in_words_minute: 1 minute
14 14 actionview_datehelper_time_in_words_minute_half: half a minute
15 15 actionview_datehelper_time_in_words_minute_less_than: less than a minute
16 16 actionview_datehelper_time_in_words_minute_plural: %d minutes
17 17 actionview_datehelper_time_in_words_minute_single: 1 minute
18 18 actionview_datehelper_time_in_words_second_less_than: less than a second
19 19 actionview_datehelper_time_in_words_second_less_than_plural: less than %d seconds
20 20 actionview_instancetag_blank_option: Bitte auserwählt
21 21
22 22 activerecord_error_inclusion: ist nicht in der Liste eingeschlossen
23 23 activerecord_error_exclusion: ist reserviert
24 24 activerecord_error_invalid: ist unzulässig
25 25 activerecord_error_confirmation: bringt nicht Bestätigung zusammen
26 26 activerecord_error_accepted: muß angenommen werden
27 27 activerecord_error_empty: kann nicht leer sein
28 28 activerecord_error_blank: kann nicht leer sein
29 29 activerecord_error_too_long: ist zu lang
30 30 activerecord_error_too_short: ist zu kurz
31 31 activerecord_error_wrong_length: ist die falsche Länge
32 32 activerecord_error_taken: ist bereits genommen worden
33 33 activerecord_error_not_a_number: ist nicht eine Zahl
34 34 activerecord_error_not_a_date: ist nicht ein gültiges Datum
35 35 activerecord_error_greater_than_start_date: muß als grösser sein beginnen Datum
36 36
37 37 general_fmt_age: %d yr
38 38 general_fmt_age_plural: %d yrs
39 39 general_fmt_date: %%b %%d, %%Y (%%a)
40 40 general_fmt_datetime: %%b %%d, %%Y (%%a), %%I:%%M %%p
41 41 general_fmt_datetime_short: %%b %%d, %%I:%%M %%p
42 42 general_fmt_time: %%I:%%M %%p
43 43 general_text_No: 'Nein'
44 44 general_text_Yes: 'Ja'
45 45 general_text_no: 'nein'
46 46 general_text_yes: 'ja'
47 47 general_lang_de: 'Deutsch'
48 48 general_csv_separator: ';'
49 49 general_day_names: Montag,Dienstag,Mittwoch,Donnerstag,Freitag,Samstag,Sonntag
50 50
51 51 notice_account_updated: Konto wurde erfolgreich aktualisiert.
52 52 notice_account_invalid_creditentials: Unzulässiger Benutzer oder Passwort
53 53 notice_account_password_updated: Passwort wurde erfolgreich aktualisiert.
54 54 notice_account_wrong_password: Falsches Passwort
55 55 notice_account_register_done: Konto wurde erfolgreich verursacht.
56 56 notice_account_unknown_email: Unbekannter Benutzer.
57 57 notice_can_t_change_password: Dieses Konto verwendet eine externe Authentisierung Quelle. Unmöglich, das Kennwort zu ändern.
58 58 notice_account_lost_email_sent: Ein email mit Anweisungen, ein neues Kennwort zu wählen ist dir geschickt worden.
59 59 notice_account_activated: Dein Konto ist aktiviert worden. Du kannst jetzt einloggen.
60 60 notice_successful_create: Erfolgreiche Kreation.
61 61 notice_successful_update: Erfolgreiches Update.
62 62 notice_successful_delete: Erfolgreiche Auslassung.
63 63 notice_successful_connection: Erfolgreicher Anschluß.
64 64 notice_file_not_found: Erbetene Akte besteht nicht oder ist gelöscht worden.
65 65 notice_locking_conflict: Data have been updated by another user.
66 66
67 67 mail_subject_lost_password: Dein redMine Kennwort
68 68 mail_subject_register: redMine Kontoaktivierung
69 69
70 70 gui_validation_error: 1 Störung
71 71 gui_validation_error_plural: %d Störungen
72 72
73 73 field_name: Name
74 74 field_description: Beschreibung
75 75 field_summary: Zusammenfassung
76 76 field_is_required: Erforderlich
77 77 field_firstname: Vorname
78 78 field_lastname: Nachname
79 79 field_mail: Email
80 80 field_filename: Datei
81 81 field_filesize: Grootte
82 82 field_downloads: Downloads
83 83 field_author: Autor
84 84 field_created_on: Angelegt
85 85 field_updated_on: aktualisiert
86 86 field_field_format: Format
87 87 field_is_for_all: Für alle Projekte
88 88 field_possible_values: Mögliche Werte
89 89 field_regexp: Regulärer Ausdruck
90 90 field_min_length: Minimale Länge
91 91 field_max_length: Maximale Länge
92 92 field_value: Wert
93 93 field_category: Kategorie
94 94 field_title: Títel
95 95 field_project: Projekt
96 96 field_issue: Antrag
97 97 field_status: Status
98 98 field_notes: Anmerkungen
99 99 field_is_closed: Problem erledigt
100 100 field_is_default: Rückstellung status
101 101 field_html_color: Farbe
102 102 field_tracker: Tracker
103 103 field_subject: Thema
104 104 field_due_date: Abgabedatum
105 105 field_assigned_to: Zugewiesen an
106 106 field_priority: Priorität
107 107 field_fixed_version: Erledigt in Version
108 108 field_user: Benutzer
109 109 field_role: Rolle
110 110 field_homepage: Startseite
111 111 field_is_public: Öffentlich
112 112 field_parent: Subprojekt von
113 113 field_is_in_chlog: Ansicht der Issues in der Historie
114 114 field_login: Mitgliedsname
115 115 field_mail_notification: Mailbenachrichtigung
116 116 field_admin: Administrator
117 117 field_locked: Gesperrt
118 118 field_last_login_on: Letzte Anmeldung
119 119 field_language: Sprache
120 120 field_effective_date: Datum
121 121 field_password: Passwort
122 122 field_new_password: Neues Passwort
123 123 field_password_confirmation: Bestätigung
124 124 field_version: Version
125 125 field_type: Typ
126 126 field_host: Host
127 127 field_port: Port
128 128 field_account: Konto
129 129 field_base_dn: Base DN
130 130 field_attr_login: Mitgliedsnameattribut
131 131 field_attr_firstname: Vornamensattribut
132 132 field_attr_lastname: Namenattribut
133 133 field_attr_mail: Emailattribut
134 134 field_onthefly: On-the-fly Benutzerkreation
135 135 field_start_date: Beginn
136 136 field_done_ratio: %% Getan
137 137
138 138 label_user: Benutzer
139 139 label_user_plural: Benutzer
140 140 label_user_new: Neuer Benutzer
141 141 label_project: Projekt
142 142 label_project_new: Neues Projekt
143 143 label_project_plural: Projekte
144 144 label_project_latest: Neueste Projekte
145 145 label_issue: Antrag
146 146 label_issue_new: Neue Antrag
147 147 label_issue_plural: Anträge
148 148 label_issue_view_all: Alle Anträge ansehen
149 149 label_document: Dokument
150 150 label_document_new: Neues Dokument
151 151 label_document_plural: Dokumente
152 152 label_role: Rolle
153 153 label_role_plural: Rollen
154 154 label_role_new: Neue Rolle
155 155 label_role_and_permissions: Rollen und Rechte
156 156 label_member: Mitglied
157 157 label_member_new: Neues Mitglied
158 158 label_member_plural: Mitglieder
159 159 label_tracker: Tracker
160 160 label_tracker_plural: Tracker
161 161 label_tracker_new: Neuer Tracker
162 162 label_workflow: Workflow
163 163 label_issue_status: Antrag Status
164 164 label_issue_status_plural: Antrag Stati
165 165 label_issue_status_new: Neuer Status
166 166 label_issue_category: Antrag Kategorie
167 167 label_issue_category_plural: Antrag Kategorien
168 168 label_issue_category_new: Neue Kategorie
169 169 label_custom_field: Benutzerdefiniertes Feld
170 170 label_custom_field_plural: Benutzerdefinierte Felder
171 171 label_custom_field_new: Neues Feld
172 172 label_enumerations: Enumerationen
173 173 label_enumeration_new: Neuer Wert
174 174 label_information: Information
175 175 label_information_plural: Informationen
176 176 label_please_login: Anmelden
177 177 label_register: Anmelden
178 178 label_password_lost: Passwort vergessen
179 179 label_home: Hauptseite
180 180 label_my_page: Meine Seite
181 181 label_my_account: Mein Konto
182 182 label_my_projects: Meine Projekte
183 183 label_administration: Administration
184 184 label_login: Einloggen
185 185 label_logout: Abmelden
186 186 label_help: Hilfe
187 187 label_reported_issues: Gemeldete Issues
188 188 label_assigned_to_me_issues: Mir zugewiesen
189 189 label_last_login: Letzte Anmeldung
190 190 label_last_updates: Letztes aktualisiertes
191 191 label_last_updates_plural: %d Letztes aktualisiertes
192 192 label_registered_on: Angemeldet am
193 193 label_activity: Aktivität
194 194 label_new: Neue
195 195 label_logged_as: Angemeldet als
196 196 label_environment: Environment
197 197 label_authentication: Authentisierung
198 198 label_auth_source: Authentisierung Modus
199 199 label_auth_source_new: Neuer Authentisierung Modus
200 200 label_auth_source_plural: Authentisierung Modi
201 201 label_subproject: Vorprojekt von
202 202 label_subproject_plural: Vorprojekte
203 203 label_min_max_length: Min - Max Länge
204 204 label_list: Liste
205 205 label_date: Date
206 206 label_integer: Zahl
207 207 label_boolean: Boolesch
208 208 label_string: Text
209 209 label_text: Langer Text
210 210 label_attribute: Attribut
211 211 label_attribute_plural: Attribute
212 212 label_download: %d Herunterlade
213 213 label_download_plural: %d Herunterlade
214 214 label_no_data: Nichts anzuzeigen
215 215 label_change_status: Statuswechsel
216 216 label_history: Historie
217 217 label_attachment: Datei
218 218 label_attachment_new: Neue Datei
219 219 label_attachment_delete: Löschungakten
220 220 label_attachment_plural: Dateien
221 221 label_report: Bericht
222 222 label_report_plural: Berichte
223 223 label_news: Neuigkeit
224 224 label_news_new: Neuigkeite addieren
225 225 label_news_plural: Neuigkeiten
226 226 label_news_latest: Letzte Neuigkeiten
227 227 label_news_view_all: Alle Neuigkeiten anzeigen
228 228 label_change_log: Change log
229 229 label_settings: Konfiguration
230 230 label_overview: Übersicht
231 231 label_version: Version
232 232 label_version_new: Neue Version
233 233 label_version_plural: Versionen
234 234 label_confirmation: Bestätigung
235 235 label_export_csv: Export zu CSV
236 236 label_export_pdf: Export zu PDF
237 237 label_read: Lesen...
238 238 label_public_projects: Öffentliche Projekte
239 239 label_open_issues: Geöffnet
240 240 label_open_issues_plural: Geöffnet
241 241 label_closed_issues: Geschlossen
242 242 label_closed_issues_plural: Geschlossen
243 243 label_total: Gesamtzahl
244 244 label_permissions: Berechtigungen
245 245 label_current_status: Gegenwärtiger Status
246 246 label_new_statuses_allowed: Neue Status gewährten
247 247 label_all: Alle
248 248 label_none: Kein
249 249 label_next: Weiter
250 250 label_previous: Zurück
251 251 label_used_by: Benutzt von
252 252 label_details: Details...
253 253 label_add_note: Eine Anmerkung addieren
254 254 label_per_page: Pro Seite
255 255 label_calendar: Kalender
256 256 label_months_from: Monate von
257 257 label_gantt_chart: Gantt Diagramm
258 258 label_internal: Intern
259 label_last_changes: %d änderungen des Letzten
260 label_change_view_all: Alle änderungen ansehen
259 261
260 262 button_login: Einloggen
261 263 button_submit: Einreichen
262 264 button_save: Speichern
263 265 button_check_all: Alles auswählen
264 266 button_uncheck_all: Alles abwählen
265 267 button_delete: Löschen
266 268 button_create: Anlegen
267 269 button_test: Testen
268 270 button_edit: Bearbeiten
269 271 button_add: Hinzufügen
270 272 button_change: Wechseln
271 273 button_apply: Anwenden
272 274 button_clear: Zurücksetzen
273 275 button_lock: Verriegeln
274 276 button_unlock: Entriegeln
275 277 button_download: Fernzuladen
276 278 button_list: Aufzulisten
277 279 button_view: Siehe
278 280 button_move: Bewegen
279 281 button_back: Rückkehr
280 282
281 283 text_select_mail_notifications: Aktionen für die Mailbenachrichtigung aktiviert werden soll.
282 284 text_regexp_info: eg. ^[A-Z0-9]+$
283 285 text_min_max_length_info: 0 heisst keine Beschränkung
284 286 text_possible_values_info: Werte trennten sich mit |
285 287 text_project_destroy_confirmation: Sind sie sicher, daß sie das Projekt löschen wollen ?
286 288 text_workflow_edit: Auswahl Workflow zum Bearbeiten
287 289 text_are_you_sure: Sind sie sicher ?
290 text_journal_changed: geändert von %s zu %s
291 text_journal_set_to: gestellt zu %s
292 text_journal_deleted: gelöscht
288 293
289 294 default_role_manager: Manager
290 295 default_role_developper: Developer
291 296 default_role_reporter: Reporter
292 297 default_tracker_bug: Fehler
293 298 default_tracker_feature: Feature
294 299 default_tracker_support: Support
295 300 default_issue_status_new: Neu
296 301 default_issue_status_assigned: Zugewiesen
297 302 default_issue_status_resolved: Gelöst
298 303 default_issue_status_feedback: Feedback
299 304 default_issue_status_closed: Erledigt
300 305 default_issue_status_rejected: Abgewiesen
301 306 default_doc_category_user: Benutzerdokumentation
302 307 default_doc_category_tech: Technische Dokumentation
303 308 default_priority_low: Niedrig
304 309 default_priority_normal: Normal
305 310 default_priority_high: Hoch
306 311 default_priority_urgent: Dringend
307 312 default_priority_immediate: Sofort
308 313
309 314 enumeration_issue_priorities: Issue-Prioritäten
310 315 enumeration_doc_categories: Dokumentenkategorien
@@ -1,310 +1,315
1 1 _gloc_rule_default: '|n| n==1 ? "" : "_plural" '
2 2
3 3 actionview_datehelper_select_day_prefix:
4 4 actionview_datehelper_select_month_names: January,February,March,April,May,June,July,August,September,October,November,December
5 5 actionview_datehelper_select_month_names_abbr: Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
6 6 actionview_datehelper_select_month_prefix:
7 7 actionview_datehelper_select_year_prefix:
8 8 actionview_datehelper_time_in_words_day: 1 day
9 9 actionview_datehelper_time_in_words_day_plural: %d days
10 10 actionview_datehelper_time_in_words_hour_about: about an hour
11 11 actionview_datehelper_time_in_words_hour_about_plural: about %d hours
12 12 actionview_datehelper_time_in_words_hour_about_single: about an hour
13 13 actionview_datehelper_time_in_words_minute: 1 minute
14 14 actionview_datehelper_time_in_words_minute_half: half a minute
15 15 actionview_datehelper_time_in_words_minute_less_than: less than a minute
16 16 actionview_datehelper_time_in_words_minute_plural: %d minutes
17 17 actionview_datehelper_time_in_words_minute_single: 1 minute
18 18 actionview_datehelper_time_in_words_second_less_than: less than a second
19 19 actionview_datehelper_time_in_words_second_less_than_plural: less than %d seconds
20 20 actionview_instancetag_blank_option: Please select
21 21
22 22 activerecord_error_inclusion: is not included in the list
23 23 activerecord_error_exclusion: is reserved
24 24 activerecord_error_invalid: is invalid
25 25 activerecord_error_confirmation: doesn't match confirmation
26 26 activerecord_error_accepted: must be accepted
27 27 activerecord_error_empty: can't be empty
28 28 activerecord_error_blank: can't be blank
29 29 activerecord_error_too_long: is too long
30 30 activerecord_error_too_short: is too short
31 31 activerecord_error_wrong_length: is the wrong length
32 32 activerecord_error_taken: has already been taken
33 33 activerecord_error_not_a_number: is not a number
34 34 activerecord_error_not_a_date: is not a valid date
35 35 activerecord_error_greater_than_start_date: must be greater than start date
36 36
37 37 general_fmt_age: %d yr
38 38 general_fmt_age_plural: %d yrs
39 39 general_fmt_date: %%m/%%d/%%Y
40 40 general_fmt_datetime: %%m/%%d/%%Y %%I:%%M %%p
41 41 general_fmt_datetime_short: %%b %%d, %%I:%%M %%p
42 42 general_fmt_time: %%I:%%M %%p
43 43 general_text_No: 'No'
44 44 general_text_Yes: 'Yes'
45 45 general_text_no: 'no'
46 46 general_text_yes: 'yes'
47 47 general_lang_en: 'English'
48 48 general_csv_separator: ','
49 49 general_day_names: Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
50 50
51 51 notice_account_updated: Account was successfully updated.
52 52 notice_account_invalid_creditentials: Invalid user or password
53 53 notice_account_password_updated: Password was successfully updated.
54 54 notice_account_wrong_password: Wrong password
55 55 notice_account_register_done: Account was successfully created.
56 56 notice_account_unknown_email: Unknown user.
57 57 notice_can_t_change_password: This account uses an external authentication source. Impossible to change the password.
58 58 notice_account_lost_email_sent: An email with instructions to choose a new password has been sent to you.
59 59 notice_account_activated: Your account has been activated. You can now log in.
60 60 notice_successful_create: Successful creation.
61 61 notice_successful_update: Successful update.
62 62 notice_successful_delete: Successful deletion.
63 63 notice_successful_connection: Successful connection.
64 64 notice_file_not_found: Requested file doesn't exist or has been deleted.
65 65 notice_locking_conflict: Data have been updated by another user.
66 66
67 67 mail_subject_lost_password: Your redMine password
68 68 mail_subject_register: redMine account activation
69 69
70 70 gui_validation_error: 1 error
71 71 gui_validation_error_plural: %d errors
72 72
73 73 field_name: Name
74 74 field_description: Description
75 75 field_summary: Summary
76 76 field_is_required: Required
77 77 field_firstname: Firstname
78 78 field_lastname: Lastname
79 79 field_mail: Email
80 80 field_filename: File
81 81 field_filesize: Size
82 82 field_downloads: Downloads
83 83 field_author: Author
84 84 field_created_on: Created
85 85 field_updated_on: Updated
86 86 field_field_format: Format
87 87 field_is_for_all: For all projects
88 88 field_possible_values: Possible values
89 89 field_regexp: Regular expression
90 90 field_min_length: Minimum length
91 91 field_max_length: Maximum length
92 92 field_value: Value
93 93 field_category: Category
94 94 field_title: Title
95 95 field_project: Project
96 96 field_issue: Issue
97 97 field_status: Status
98 98 field_notes: Notes
99 99 field_is_closed: Issue closed
100 100 field_is_default: Default status
101 101 field_html_color: Color
102 102 field_tracker: Tracker
103 103 field_subject: Subject
104 104 field_due_date: Due date
105 105 field_assigned_to: Assigned to
106 106 field_priority: Priority
107 107 field_fixed_version: Fixed version
108 108 field_user: User
109 109 field_role: Role
110 110 field_homepage: Homepage
111 111 field_is_public: Public
112 112 field_parent: Subproject of
113 113 field_is_in_chlog: Issues displayed in changelog
114 114 field_login: Login
115 115 field_mail_notification: Mail notifications
116 116 field_admin: Administrator
117 117 field_locked: Locked
118 118 field_last_login_on: Last connection
119 119 field_language: Language
120 120 field_effective_date: Date
121 121 field_password: Password
122 122 field_new_password: New password
123 123 field_password_confirmation: Confirmation
124 124 field_version: Version
125 125 field_type: Type
126 126 field_host: Host
127 127 field_port: Port
128 128 field_account: Account
129 129 field_base_dn: Base DN
130 130 field_attr_login: Login attribute
131 131 field_attr_firstname: Firstname attribute
132 132 field_attr_lastname: Lastname attribute
133 133 field_attr_mail: Email attribute
134 134 field_onthefly: On-the-fly user creation
135 135 field_start_date: Start
136 136 field_done_ratio: %% Done
137 137
138 138 label_user: User
139 139 label_user_plural: Users
140 140 label_user_new: New user
141 141 label_project: Project
142 142 label_project_new: New project
143 143 label_project_plural: Projects
144 144 label_project_latest: Latest projects
145 145 label_issue: Issue
146 146 label_issue_new: New issue
147 147 label_issue_plural: Issues
148 148 label_issue_view_all: View all issues
149 149 label_document: Document
150 150 label_document_new: New document
151 151 label_document_plural: Documents
152 152 label_role: Role
153 153 label_role_plural: Roles
154 154 label_role_new: New role
155 155 label_role_and_permissions: Roles and permissions
156 156 label_member: Member
157 157 label_member_new: New member
158 158 label_member_plural: Members
159 159 label_tracker: Tracker
160 160 label_tracker_plural: Trackers
161 161 label_tracker_new: New tracker
162 162 label_workflow: Workflow
163 163 label_issue_status: Issue status
164 164 label_issue_status_plural: Issue statuses
165 165 label_issue_status_new: New status
166 166 label_issue_category: Issue category
167 167 label_issue_category_plural: Issue categories
168 168 label_issue_category_new: New category
169 169 label_custom_field: Custom field
170 170 label_custom_field_plural: Custom fields
171 171 label_custom_field_new: New custom field
172 172 label_enumerations: Enumerations
173 173 label_enumeration_new: New value
174 174 label_information: Information
175 175 label_information_plural: Information
176 176 label_please_login: Please login
177 177 label_register: Register
178 178 label_password_lost: Lost password
179 179 label_home: Home
180 180 label_my_page: My page
181 181 label_my_account: My account
182 182 label_my_projects: My projects
183 183 label_administration: Administration
184 184 label_login: Login
185 185 label_logout: Logout
186 186 label_help: Help
187 187 label_reported_issues: Reported issues
188 188 label_assigned_to_me_issues: Issues assigned to me
189 189 label_last_login: Last connection
190 190 label_last_updates: Last updated
191 191 label_last_updates_plural: %d last updated
192 192 label_registered_on: Registered on
193 193 label_activity: Activity
194 194 label_new: New
195 195 label_logged_as: Logged as
196 196 label_environment: Environment
197 197 label_authentication: Authentication
198 198 label_auth_source: Authentication mode
199 199 label_auth_source_new: New authentication mode
200 200 label_auth_source_plural: Authentication modes
201 201 label_subproject: Subproject
202 202 label_subproject_plural: Subprojects
203 203 label_min_max_length: Min - Max length
204 204 label_list: List
205 205 label_date: Date
206 206 label_integer: Integer
207 207 label_boolean: Boolean
208 208 label_string: Text
209 209 label_text: Long text
210 210 label_attribute: Attribute
211 211 label_attribute_plural: Attributes
212 212 label_download: %d Download
213 213 label_download_plural: %d Downloads
214 214 label_no_data: No data to display
215 215 label_change_status: Change status
216 216 label_history: History
217 217 label_attachment: File
218 218 label_attachment_new: New file
219 219 label_attachment_delete: Delete file
220 220 label_attachment_plural: Files
221 221 label_report: Report
222 222 label_report_plural: Reports
223 223 label_news: News
224 224 label_news_new: Add news
225 225 label_news_plural: News
226 226 label_news_latest: Latest news
227 227 label_news_view_all: View all news
228 228 label_change_log: Change log
229 229 label_settings: Settings
230 230 label_overview: Overview
231 231 label_version: Version
232 232 label_version_new: New version
233 233 label_version_plural: Versions
234 234 label_confirmation: Confirmation
235 235 label_export_csv: Export to CSV
236 236 label_export_pdf: Export to PDF
237 237 label_read: Read...
238 238 label_public_projects: Public projects
239 239 label_open_issues: Open
240 240 label_open_issues_plural: Open
241 241 label_closed_issues: Closed
242 242 label_closed_issues_plural: Closed
243 243 label_total: Total
244 244 label_permissions: Permissions
245 245 label_current_status: Current status
246 246 label_new_statuses_allowed: New statuses allowed
247 247 label_all: All
248 248 label_none: None
249 249 label_next: Next
250 250 label_previous: Previous
251 251 label_used_by: Used by
252 252 label_details: Details...
253 253 label_add_note: Add a note
254 254 label_per_page: Per page
255 255 label_calendar: Calendar
256 256 label_months_from: months from
257 257 label_gantt_chart: Gantt chart
258 258 label_internal: Internal
259 label_last_changes: last %d changes
260 label_change_view_all: View all changes
259 261
260 262 button_login: Login
261 263 button_submit: Submit
262 264 button_save: Save
263 265 button_check_all: Check all
264 266 button_uncheck_all: Uncheck all
265 267 button_delete: Delete
266 268 button_create: Create
267 269 button_test: Test
268 270 button_edit: Edit
269 271 button_add: Add
270 272 button_change: Change
271 273 button_apply: Apply
272 274 button_clear: Clear
273 275 button_lock: Lock
274 276 button_unlock: Unlock
275 277 button_download: Download
276 278 button_list: List
277 279 button_view: View
278 280 button_move: Move
279 281 button_back: Back
280 282
281 283 text_select_mail_notifications: Select actions for which mail notifications should be sent.
282 284 text_regexp_info: eg. ^[A-Z0-9]+$
283 285 text_min_max_length_info: 0 means no restriction
284 286 text_possible_values_info: values separated with |
285 287 text_project_destroy_confirmation: Are you sure you want to delete this project and all related data ?
286 288 text_workflow_edit: Select a role and a tracker to edit the workflow
287 289 text_are_you_sure: Are you sure ?
290 text_journal_changed: changed from %s to %s
291 text_journal_set_to: set to %s
292 text_journal_deleted: deleted
288 293
289 294 default_role_manager: Manager
290 295 default_role_developper: Developer
291 296 default_role_reporter: Reporter
292 297 default_tracker_bug: Bug
293 298 default_tracker_feature: Feature
294 299 default_tracker_support: Support
295 300 default_issue_status_new: New
296 301 default_issue_status_assigned: Assigned
297 302 default_issue_status_resolved: Resolved
298 303 default_issue_status_feedback: Feedback
299 304 default_issue_status_closed: Closed
300 305 default_issue_status_rejected: Rejected
301 306 default_doc_category_user: User documentation
302 307 default_doc_category_tech: Technical documentation
303 308 default_priority_low: Low
304 309 default_priority_normal: Normal
305 310 default_priority_high: High
306 311 default_priority_urgent: Urgent
307 312 default_priority_immediate: Immediate
308 313
309 314 enumeration_issue_priorities: Issue priorities
310 315 enumeration_doc_categories: Document categories
@@ -1,310 +1,315
1 1 _gloc_rule_default: '|n| n==1 ? "" : "_plural" '
2 2
3 3 actionview_datehelper_select_day_prefix:
4 4 actionview_datehelper_select_month_names: Enero,Febrero,Marzo,Abril,Mayo,Junio,Julio,Agosto,Septiembre,Octubre,Noviembre,Diciembre
5 5 actionview_datehelper_select_month_names_abbr: Ene,Feb,Mar,Abr,Mayo,Jun,Jul,Ago,Sep,Oct,Nov,Dic
6 6 actionview_datehelper_select_month_prefix:
7 7 actionview_datehelper_select_year_prefix:
8 8 actionview_datehelper_time_in_words_day: 1 day
9 9 actionview_datehelper_time_in_words_day_plural: %d days
10 10 actionview_datehelper_time_in_words_hour_about: about an hour
11 11 actionview_datehelper_time_in_words_hour_about_plural: about %d hours
12 12 actionview_datehelper_time_in_words_hour_about_single: about an hour
13 13 actionview_datehelper_time_in_words_minute: 1 minute
14 14 actionview_datehelper_time_in_words_minute_half: half a minute
15 15 actionview_datehelper_time_in_words_minute_less_than: less than a minute
16 16 actionview_datehelper_time_in_words_minute_plural: %d minutes
17 17 actionview_datehelper_time_in_words_minute_single: 1 minute
18 18 actionview_datehelper_time_in_words_second_less_than: less than a second
19 19 actionview_datehelper_time_in_words_second_less_than_plural: less than %d seconds
20 20 actionview_instancetag_blank_option: Please select
21 21
22 22 activerecord_error_inclusion: is not included in the list
23 23 activerecord_error_exclusion: is reserved
24 24 activerecord_error_invalid: is invalid
25 25 activerecord_error_confirmation: doesn't match confirmation
26 26 activerecord_error_accepted: must be accepted
27 27 activerecord_error_empty: can't be empty
28 28 activerecord_error_blank: can't be blank
29 29 activerecord_error_too_long: is too long
30 30 activerecord_error_too_short: is too short
31 31 activerecord_error_wrong_length: is the wrong length
32 32 activerecord_error_taken: has already been taken
33 33 activerecord_error_not_a_number: is not a number
34 34 activerecord_error_not_a_date: no es una fecha válida
35 35 activerecord_error_greater_than_start_date: debe ser la fecha mayor que del comienzo
36 36
37 37 general_fmt_age: %d año
38 38 general_fmt_age_plural: %d años
39 39 general_fmt_date: %%d/%%m/%%Y
40 40 general_fmt_datetime: %%d/%%m/%%Y %%H:%%M
41 41 general_fmt_datetime_short: %%d/%%m %%H:%%M
42 42 general_fmt_time: %%H:%%M
43 43 general_text_No: 'No'
44 44 general_text_Yes: 'Sí'
45 45 general_text_no: 'no'
46 46 general_text_yes: 'sí'
47 47 general_lang_es: 'Español'
48 48 general_csv_separator: ';'
49 49 general_day_names: Lunes,Martes,Miércoles,Jueves,Viernes,Sábado,Domingo
50 50
51 51 notice_account_updated: Account was successfully updated.
52 52 notice_account_invalid_creditentials: Invalid user or password
53 53 notice_account_password_updated: Password was successfully updated.
54 54 notice_account_wrong_password: Wrong password
55 55 notice_account_register_done: Account was successfully created.
56 56 notice_account_unknown_email: Unknown user.
57 57 notice_can_t_change_password: This account uses an external authentication source. Impossible to change the password.
58 58 notice_account_lost_email_sent: An email with instructions to choose a new password has been sent to you.
59 59 notice_account_activated: Your account has been activated. You can now log in.
60 60 notice_successful_create: Successful creation.
61 61 notice_successful_update: Successful update.
62 62 notice_successful_delete: Successful deletion.
63 63 notice_successful_connection: Successful connection.
64 64 notice_file_not_found: Requested file doesn't exist or has been deleted.
65 65 notice_locking_conflict: Data have been updated by another user.
66 66
67 67 mail_subject_lost_password: Tu contraseña del redMine
68 68 mail_subject_register: Activación de la cuenta del redMine
69 69
70 70 gui_validation_error: 1 error
71 71 gui_validation_error_plural: %d errores
72 72
73 73 field_name: Nombre
74 74 field_description: Descripción
75 75 field_summary: Resumen
76 76 field_is_required: Obligatorio
77 77 field_firstname: Nombre
78 78 field_lastname: Apellido
79 79 field_mail: Email
80 80 field_filename: Fichero
81 81 field_filesize: Tamaño
82 82 field_downloads: Telecargas
83 83 field_author: Autor
84 84 field_created_on: Creado
85 85 field_updated_on: Actualizado
86 86 field_field_format: Formato
87 87 field_is_for_all: Para todos los proyectos
88 88 field_possible_values: Valores posibles
89 89 field_regexp: Expresión regular
90 90 field_min_length: Longitud mínima
91 91 field_max_length: Longitud máxima
92 92 field_value: Valor
93 93 field_category: Categoría
94 94 field_title: Título
95 95 field_project: Proyecto
96 96 field_issue: Petición
97 97 field_status: Estatuto
98 98 field_notes: Notas
99 99 field_is_closed: Petición resuelta
100 100 field_is_default: Estatuto por defecto
101 101 field_html_color: Color
102 102 field_tracker: Tracker
103 103 field_subject: Tema
104 104 field_due_date: Fecha debida
105 105 field_assigned_to: Asignado a
106 106 field_priority: Prioridad
107 107 field_fixed_version: Versión corregida
108 108 field_user: Usuario
109 109 field_role: Papel
110 110 field_homepage: Sitio web
111 111 field_is_public: Público
112 112 field_parent: Proyecto secundario de
113 113 field_is_in_chlog: Consultar las peticiones en el histórico
114 114 field_login: Identificador
115 115 field_mail_notification: Notificación por mail
116 116 field_admin: Administrador
117 117 field_locked: Cerrado
118 118 field_last_login_on: Última conexión
119 119 field_language: Lengua
120 120 field_effective_date: Fecha
121 121 field_password: Contraseña
122 122 field_new_password: Nueva contraseña
123 123 field_password_confirmation: Confirmación
124 124 field_version: Versión
125 125 field_type: Tipo
126 126 field_host: Anfitrión
127 127 field_port: Puerto
128 128 field_account: Cuenta
129 129 field_base_dn: Base DN
130 130 field_attr_login: Cualidad del identificador
131 131 field_attr_firstname: Cualidad del nombre
132 132 field_attr_lastname: Cualidad del apellido
133 133 field_attr_mail: Cualidad del Email
134 134 field_onthefly: Creación del usuario On-the-fly
135 135 field_start_date: Comienzo
136 136 field_done_ratio: %% Realizado
137 137
138 138 label_user: Usuario
139 139 label_user_plural: Usuarios
140 140 label_user_new: Nuevo usuario
141 141 label_project: Proyecto
142 142 label_project_new: Nuevo proyecto
143 143 label_project_plural: Proyectos
144 144 label_project_latest: Los proyectos más últimos
145 145 label_issue: Petición
146 146 label_issue_new: Nueva petición
147 147 label_issue_plural: Peticiones
148 148 label_issue_view_all: Ver todas las peticiones
149 149 label_document: Documento
150 150 label_document_new: Nuevo documento
151 151 label_document_plural: Documentos
152 152 label_role: Papel
153 153 label_role_plural: Papeles
154 154 label_role_new: Nuevo papel
155 155 label_role_and_permissions: Papeles y permisos
156 156 label_member: Miembro
157 157 label_member_new: Nuevo miembro
158 158 label_member_plural: Miembros
159 159 label_tracker: Tracker
160 160 label_tracker_plural: Trackers
161 161 label_tracker_new: Nuevo tracker
162 162 label_workflow: Workflow
163 163 label_issue_status: Estatuto de petición
164 164 label_issue_status_plural: Estatutos de las peticiones
165 165 label_issue_status_new: Nuevo estatuto
166 166 label_issue_category: Categoría de las peticiones
167 167 label_issue_category_plural: Categorías de las peticiones
168 168 label_issue_category_new: Nueva categoría
169 169 label_custom_field: Campo personalizado
170 170 label_custom_field_plural: Campos personalizados
171 171 label_custom_field_new: Nuevo campo personalizado
172 172 label_enumerations: Listas de valores
173 173 label_enumeration_new: Nuevo valor
174 174 label_information: Informacion
175 175 label_information_plural: Informaciones
176 176 label_please_login: Conexión
177 177 label_register: Registrar
178 178 label_password_lost: ¿Olvidaste la contraseña?
179 179 label_home: Acogida
180 180 label_my_page: Mi página
181 181 label_my_account: Mi cuenta
182 182 label_my_projects: Mis proyectos
183 183 label_administration: Administración
184 184 label_login: Conexión
185 185 label_logout: Desconexión
186 186 label_help: Ayuda
187 187 label_reported_issues: Peticiones registradas
188 188 label_assigned_to_me_issues: Peticiones que me están asignadas
189 189 label_last_login: Última conexión
190 190 label_last_updates: Actualizado
191 191 label_last_updates_plural: %d Actualizados
192 192 label_registered_on: Inscrito el
193 193 label_activity: Actividad
194 194 label_new: Nuevo
195 195 label_logged_as: Conectado como
196 196 label_environment: Environment
197 197 label_authentication: Autentificación
198 198 label_auth_source: Modo de la autentificación
199 199 label_auth_source_new: Nuevo modo de la autentificación
200 200 label_auth_source_plural: Modos de la autentificación
201 201 label_subproject: Proyecto secundario
202 202 label_subproject_plural: Proyectos secundarios
203 203 label_min_max_length: Longitud mín - máx
204 204 label_list: Lista
205 205 label_date: Fecha
206 206 label_integer: Número
207 207 label_boolean: Boleano
208 208 label_string: Texto
209 209 label_text: Texto largo
210 210 label_attribute: Cualidad
211 211 label_attribute_plural: Cualidades
212 212 label_download: %d Telecarga
213 213 label_download_plural: %d Telecargas
214 214 label_no_data: Ningunos datos a exhibir
215 215 label_change_status: Cambiar el estatuto
216 216 label_history: Histórico
217 217 label_attachment: Fichero
218 218 label_attachment_new: Nuevo fichero
219 219 label_attachment_delete: Suprimir el fichero
220 220 label_attachment_plural: Ficheros
221 221 label_report: Informe
222 222 label_report_plural: Informes
223 223 label_news: Noticia
224 224 label_news_new: Nueva noticia
225 225 label_news_plural: Noticias
226 226 label_news_latest: Últimas noticias
227 227 label_news_view_all: Ver todas las noticias
228 228 label_change_log: Cambios
229 229 label_settings: Configuración
230 230 label_overview: Vistazo
231 231 label_version: Versión
232 232 label_version_new: Nueva versión
233 233 label_version_plural: Versiónes
234 234 label_confirmation: Confirmación
235 235 label_export_csv: Exportar a CSV
236 236 label_export_pdf: Exportar a PDF
237 237 label_read: Leer...
238 238 label_public_projects: Proyectos publicos
239 239 label_open_issues: Abierta
240 240 label_open_issues_plural: Abiertas
241 241 label_closed_issues: Cerrada
242 242 label_closed_issues_plural: Cerradas
243 243 label_total: Total
244 244 label_permissions: Permisos
245 245 label_current_status: Estado actual
246 246 label_new_statuses_allowed: Nuevos estatutos autorizados
247 247 label_all: Todos
248 248 label_none: Ninguno
249 249 label_next: Próximo
250 250 label_previous: Precedente
251 251 label_used_by: Utilizado por
252 252 label_details: Detalles...
253 253 label_add_note: Agregar una nota
254 254 label_per_page: Por la página
255 255 label_calendar: Calendario
256 256 label_months_from: meses de
257 257 label_gantt_chart: Diagrama de Gantt
258 258 label_internal: Interno
259 label_last_changes: %d cambios del último
260 label_change_view_all: Ver todos los cambios
259 261
260 262 button_login: Conexión
261 263 button_submit: Someter
262 264 button_save: Validar
263 265 button_check_all: Seleccionar todo
264 266 button_uncheck_all: No seleccionar nada
265 267 button_delete: Suprimir
266 268 button_create: Crear
267 269 button_test: Testar
268 270 button_edit: Modificar
269 271 button_add: Añadir
270 272 button_change: Cambiar
271 273 button_apply: Aplicar
272 274 button_clear: Anular
273 275 button_lock: Bloquear
274 276 button_unlock: Desbloquear
275 277 button_download: Telecargar
276 278 button_list: Listar
277 279 button_view: Ver
278 280 button_move: Mover
279 281 button_back: Atrás
280 282
281 283 text_select_mail_notifications: Seleccionar las actividades que necesitan la activación de la notificación por mail.
282 284 text_regexp_info: eg. ^[A-Z0-9]+$
283 285 text_min_max_length_info: 0 para ninguna restricción
284 286 text_possible_values_info: Los valores se separaron con |
285 287 text_project_destroy_confirmation: ¿ Estás seguro de querer eliminar el proyecto ?
286 288 text_workflow_edit: Seleccionar un workflow para actualizar
287 289 text_are_you_sure: ¿ Estás seguro ?
290 text_journal_changed: cambiado de %s a %s
291 text_journal_set_to: fijado a %s
292 text_journal_deleted: suprimido
288 293
289 294 default_role_manager: Manager
290 295 default_role_developper: Desarrollador
291 296 default_role_reporter: Informador
292 297 default_tracker_bug: Anomalía
293 298 default_tracker_feature: Evolución
294 299 default_tracker_support: Asistencia
295 300 default_issue_status_new: Nuevo
296 301 default_issue_status_assigned: Asignada
297 302 default_issue_status_resolved: Resuelta
298 303 default_issue_status_feedback: Comentario
299 304 default_issue_status_closed: Cerrada
300 305 default_issue_status_rejected: Rechazada
301 306 default_doc_category_user: Documentación del usuario
302 307 default_doc_category_tech: Documentación tecnica
303 308 default_priority_low: Bajo
304 309 default_priority_normal: Normal
305 310 default_priority_high: Alto
306 311 default_priority_urgent: Urgente
307 312 default_priority_immediate: Ahora
308 313
309 314 enumeration_issue_priorities: Prioridad de las peticiones
310 315 enumeration_doc_categories: Categorías del documento
@@ -1,311 +1,316
1 1 _gloc_rule_default: '|n| n<=1 ? "" : "_plural" '
2 2
3 3 actionview_datehelper_select_day_prefix:
4 4 actionview_datehelper_select_month_names: Janvier,Février,Mars,Avril,Mai,Juin,Juillet,Août,Septembre,Octobre,Novembre,Décembre
5 5 actionview_datehelper_select_month_names_abbr: Jan,Fév,Mars,Avril,Mai,Juin,Juil,Août,Sept,Oct,Nov,Déc
6 6 actionview_datehelper_select_month_prefix:
7 7 actionview_datehelper_select_year_prefix:
8 8 actionview_datehelper_time_in_words_day: 1 jour
9 9 actionview_datehelper_time_in_words_day_plural: %d jours
10 10 actionview_datehelper_time_in_words_hour_about: about an hour
11 11 actionview_datehelper_time_in_words_hour_about_plural: about %d hours
12 12 actionview_datehelper_time_in_words_hour_about_single: about an hour
13 13 actionview_datehelper_time_in_words_minute: 1 minute
14 14 actionview_datehelper_time_in_words_minute_half: 30 secondes
15 15 actionview_datehelper_time_in_words_minute_less_than: moins d'une minute
16 16 actionview_datehelper_time_in_words_minute_plural: %d minutes
17 17 actionview_datehelper_time_in_words_minute_single: 1 minute
18 18 actionview_datehelper_time_in_words_second_less_than: moins d'une seconde
19 19 actionview_datehelper_time_in_words_second_less_than_plural: moins de %d secondes
20 20 actionview_instancetag_blank_option: Choisir
21 21
22 22 activerecord_error_inclusion: n'est pas inclus dans la liste
23 23 activerecord_error_exclusion: est reservé
24 24 activerecord_error_invalid: est invalide
25 25 activerecord_error_confirmation: ne correspond pas à la confirmation
26 26 activerecord_error_accepted: doit être accepté
27 27 activerecord_error_empty: doit être renseigné
28 28 activerecord_error_blank: doit être renseigné
29 29 activerecord_error_too_long: est trop long
30 30 activerecord_error_too_short: est trop court
31 31 activerecord_error_wrong_length: n'est pas de la bonne longueur
32 32 activerecord_error_taken: est déjà utilisé
33 33 activerecord_error_not_a_number: n'est pas un nombre
34 34 activerecord_error_not_a_date: n'est pas une date valide
35 35 activerecord_error_greater_than_start_date: doit être postérieur à la date de début
36 36
37 37 general_fmt_age: %d an
38 38 general_fmt_age_plural: %d ans
39 39 general_fmt_date: %%d/%%m/%%Y
40 40 general_fmt_datetime: %%d/%%m/%%Y %%H:%%M
41 41 general_fmt_datetime_short: %%d/%%m %%H:%%M
42 42 general_fmt_time: %%H:%%M
43 43 general_text_No: 'Non'
44 44 general_text_Yes: 'Oui'
45 45 general_text_no: 'non'
46 46 general_text_yes: 'oui'
47 47 general_lang_fr: 'Français'
48 48 general_csv_separator: ';'
49 49 general_day_names: Lundi,Mardi,Mercredi,Jeudi,Vendredi,Samedi,Dimanche
50 50
51 51 notice_account_updated: Le compte a été mis à jour avec succès.
52 52 notice_account_invalid_creditentials: Identifiant ou mot de passe invalide.
53 53 notice_account_password_updated: Mot de passe mis à jour avec succès.
54 54 notice_account_wrong_password: Mot de passe incorrect
55 55 notice_account_register_done: Un message contenant les instructions pour activer votre compte vous a été envoyé.
56 56 notice_account_unknown_email: Aucun compte ne correspond à cette adresse.
57 57 notice_can_t_change_password: Ce compte utilise une authentification externe. Impossible de changer le mot de passe.
58 58 notice_account_lost_email_sent: Un message contenant les instructions pour choisir un nouveau mot de passe vous a été envoyé.
59 59 notice_account_activated: Votre compte a été activé. Vous pouvez à présent vous connecter.
60 60 notice_successful_create: Création effectuée avec succès.
61 61 notice_successful_update: Mise à jour effectuée avec succès.
62 62 notice_successful_delete: Suppression effectuée avec succès.
63 63 notice_successful_connection: Connection réussie.
64 64 notice_file_not_found: Le fichier demandé n'existe pas ou a été supprimé.
65 65 notice_locking_conflict: Les données ont été mises à jour par un autre utilisateur. Mise à jour impossible.
66 66
67 67 mail_subject_lost_password: Votre mot de passe redMine
68 68 mail_subject_register: Activation de votre compte redMine
69 69
70 70 gui_validation_error: 1 erreur
71 71 gui_validation_error_plural: %d erreurs
72 72
73 73 field_name: Nom
74 74 field_description: Description
75 75 field_summary: Résumé
76 76 field_is_required: Obligatoire
77 77 field_firstname: Prénom
78 78 field_lastname: Nom
79 79 field_mail: Email
80 80 field_filename: Fichier
81 81 field_filesize: Taille
82 82 field_downloads: Téléchargements
83 83 field_author: Auteur
84 84 field_created_on: Créé
85 85 field_updated_on: Mis à jour
86 86 field_field_format: Format
87 87 field_is_for_all: Pour tous les projets
88 88 field_possible_values: Valeurs possibles
89 89 field_regexp: Expression régulière
90 90 field_min_length: Longueur minimum
91 91 field_max_length: Longueur maximum
92 92 field_value: Valeur
93 93 field_category: Catégorie
94 94 field_title: Titre
95 95 field_project: Projet
96 96 field_issue: Demande
97 97 field_status: Statut
98 98 field_notes: Notes
99 99 field_is_closed: Demande fermée
100 100 field_is_default: Statut par défaut
101 101 field_html_color: Couleur
102 102 field_tracker: Tracker
103 103 field_subject: Sujet
104 104 field_due_date: Date d'échéance
105 105 field_assigned_to: Assigné à
106 106 field_priority: Priorité
107 107 field_fixed_version: Version corrigée
108 108 field_user: Utilisateur
109 109 field_role: Rôle
110 110 field_homepage: Site web
111 111 field_is_public: Public
112 112 field_parent: Sous-projet de
113 113 field_is_in_chlog: Demandes affichées dans l'historique
114 114 field_login: Identifiant
115 115 field_mail_notification: Notifications par mail
116 116 field_admin: Administrateur
117 117 field_locked: Verrouillé
118 118 field_last_login_on: Dernière connexion
119 119 field_language: Langue
120 120 field_effective_date: Date
121 121 field_password: Mot de passe
122 122 field_new_password: Nouveau mot de passe
123 123 field_password_confirmation: Confirmation
124 124 field_version: Version
125 125 field_type: Type
126 126 field_host: Hôte
127 127 field_port: Port
128 128 field_account: Compte
129 129 field_base_dn: Base DN
130 130 field_attr_login: Attribut Identifiant
131 131 field_attr_firstname: Attribut Prénom
132 132 field_attr_lastname: Attribut Nom
133 133 field_attr_mail: Attribut Email
134 134 field_onthefly: Création des utilisateurs à la volée
135 135 field_start_date: Début
136 136 field_done_ratio: %% Réalisé
137 137 field_auth_source: Mode d'authentification
138 138
139 139 label_user: Utilisateur
140 140 label_user_plural: Utilisateurs
141 141 label_user_new: Nouvel utilisateur
142 142 label_project: Projet
143 143 label_project_new: Nouveau projet
144 144 label_project_plural: Projets
145 145 label_project_latest: Derniers projets
146 146 label_issue: Demande
147 147 label_issue_new: Nouvelle demande
148 148 label_issue_plural: Demandes
149 149 label_issue_view_all: Voir toutes les demandes
150 150 label_document: Document
151 151 label_document_new: Nouveau document
152 152 label_document_plural: Documents
153 153 label_role: Rôle
154 154 label_role_plural: Rôles
155 155 label_role_new: Nouveau rôle
156 156 label_role_and_permissions: Rôles et permissions
157 157 label_member: Membre
158 158 label_member_new: Nouveau membre
159 159 label_member_plural: Membres
160 160 label_tracker: Tracker
161 161 label_tracker_plural: Trackers
162 162 label_tracker_new: Nouveau tracker
163 163 label_workflow: Workflow
164 164 label_issue_status: Statut de demandes
165 165 label_issue_status_plural: Statuts de demandes
166 166 label_issue_status_new: Nouveau statut
167 167 label_issue_category: Catégorie de demandes
168 168 label_issue_category_plural: Catégories de demandes
169 169 label_issue_category_new: Nouvelle catégorie
170 170 label_custom_field: Champ personnalisé
171 171 label_custom_field_plural: Champs personnalisés
172 172 label_custom_field_new: Nouveau champ personnalisé
173 173 label_enumerations: Listes de valeurs
174 174 label_enumeration_new: Nouvelle valeur
175 175 label_information: Information
176 176 label_information_plural: Informations
177 177 label_please_login: Identification
178 178 label_register: S'enregistrer
179 179 label_password_lost: Mot de passe perdu
180 180 label_home: Accueil
181 181 label_my_page: Ma page
182 182 label_my_account: Mon compte
183 183 label_my_projects: Mes projets
184 184 label_administration: Administration
185 185 label_login: Connexion
186 186 label_logout: Déconnexion
187 187 label_help: Aide
188 188 label_reported_issues: Demandes soumises
189 189 label_assigned_to_me_issues: Demandes qui me sont assignées
190 190 label_last_login: Dernière connexion
191 191 label_last_updates: Dernière mise à jour
192 192 label_last_updates_plural: %d dernières mises à jour
193 193 label_registered_on: Inscrit le
194 194 label_activity: Activité
195 195 label_new: Nouveau
196 196 label_logged_as: Connecté en tant que
197 197 label_environment: Environnement
198 198 label_authentication: Authentification
199 199 label_auth_source: Mode d'authentification
200 200 label_auth_source_new: Nouveau mode d'authentification
201 201 label_auth_source_plural: Modes d'authentification
202 202 label_subproject: Sous-projet
203 203 label_subproject_plural: Sous-projets
204 204 label_min_max_length: Longueurs mini - maxi
205 205 label_list: Liste
206 206 label_date: Date
207 207 label_integer: Entier
208 208 label_boolean: Booléen
209 209 label_string: Texte
210 210 label_text: Texte long
211 211 label_attribute: Attribut
212 212 label_attribute_plural: Attributs
213 213 label_download: %d Téléchargement
214 214 label_download_plural: %d Téléchargements
215 215 label_no_data: Aucune donnée à afficher
216 216 label_change_status: Changer le statut
217 217 label_history: Historique
218 218 label_attachment: Fichier
219 219 label_attachment_new: Nouveau fichier
220 220 label_attachment_delete: Supprimer le fichier
221 221 label_attachment_plural: Fichiers
222 222 label_report: Rapport
223 223 label_report_plural: Rapports
224 224 label_news: Annonce
225 225 label_news_new: Nouvelle annonce
226 226 label_news_plural: Annonces
227 227 label_news_latest: Dernières annonces
228 228 label_news_view_all: Voir toutes les annonces
229 229 label_change_log: Historique
230 230 label_settings: Configuration
231 231 label_overview: Aperçu
232 232 label_version: Version
233 233 label_version_new: Nouvelle version
234 234 label_version_plural: Versions
235 235 label_confirmation: Confirmation
236 236 label_export_csv: Exporter en CSV
237 237 label_export_pdf: Exporter en PDF
238 238 label_read: Lire...
239 239 label_public_projects: Projets publics
240 240 label_open_issues: Ouverte
241 241 label_open_issues_plural: Ouvertes
242 242 label_closed_issues: Fermée
243 243 label_closed_issues_plural: Fermées
244 244 label_total: Total
245 245 label_permissions: Permissions
246 246 label_current_status: Statut actuel
247 247 label_new_statuses_allowed: Nouveaux statuts autorisés
248 248 label_all: Tous
249 249 label_none: Aucun
250 250 label_next: Suivant
251 251 label_previous: Précédent
252 252 label_used_by: Utilisé par
253 253 label_details: Détails...
254 254 label_add_note: Ajouter une note
255 255 label_per_page: Par page
256 256 label_calendar: Calendrier
257 257 label_months_from: mois depuis
258 258 label_gantt_chart: Diagramme de Gantt
259 259 label_internal: Interne
260 label_last_changes: %d derniers changements
261 label_change_view_all: Voir tous les changements
260 262
261 263 button_login: Connexion
262 264 button_submit: Soumettre
263 265 button_save: Valider
264 266 button_check_all: Tout cocher
265 267 button_uncheck_all: Tout décocher
266 268 button_delete: Supprimer
267 269 button_create: Créer
268 270 button_test: Tester
269 271 button_edit: Modifier
270 272 button_add: Ajouter
271 273 button_change: Changer
272 274 button_apply: Appliquer
273 275 button_clear: Effacer
274 276 button_lock: Verrouiller
275 277 button_unlock: Déverrouiller
276 278 button_download: Télécharger
277 279 button_list: Lister
278 280 button_view: Voir
279 281 button_move: Déplacer
280 282 button_back: Retour
281 283
282 284 text_select_mail_notifications: Sélectionner les actions pour lesquelles la notification par mail doit être activée.
283 285 text_regexp_info: ex. ^[A-Z0-9]+$
284 286 text_min_max_length_info: 0 pour aucune restriction
285 287 text_possible_values_info: valeurs séparées par |
286 288 text_project_destroy_confirmation: Etes-vous sûr de vouloir supprimer ce projet et tout ce qui lui est rattaché ?
287 289 text_workflow_edit: Sélectionner un tracker et un rôle pour éditer le workflow
288 290 text_are_you_sure: Etes-vous sûr ?
291 text_journal_changed: changé de %s à %s
292 text_journal_set_to: mis à %s
293 text_journal_deleted: supprimé
289 294
290 295 default_role_manager: Manager
291 296 default_role_developper: Développeur
292 297 default_role_reporter: Rapporteur
293 298 default_tracker_bug: Anomalie
294 299 default_tracker_feature: Evolution
295 300 default_tracker_support: Assistance
296 301 default_issue_status_new: Nouveau
297 302 default_issue_status_assigned: Assigné
298 303 default_issue_status_resolved: Résolu
299 304 default_issue_status_feedback: Commentaire
300 305 default_issue_status_closed: Fermé
301 306 default_issue_status_rejected: Rejeté
302 307 default_doc_category_user: Documentation utilisateur
303 308 default_doc_category_tech: Documentation technique
304 309 default_priority_low: Bas
305 310 default_priority_normal: Normal
306 311 default_priority_high: Haut
307 312 default_priority_urgent: Urgent
308 313 default_priority_immediate: Immédiat
309 314
310 315 enumeration_issue_priorities: Priorités des demandes
311 316 enumeration_doc_categories: Catégories des documents
@@ -1,441 +1,448
1 1 /* andreas08 - an open source xhtml/css website layout by Andreas Viklund - http://andreasviklund.com . Free to use in any way and for any purpose as long as the proper credits are given to the original designer. Version: 1.0, November 28, 2005 */
2 2 /* Edited by Jean-Philippe Lang *>
3 3 /**************** Body and tag styles ****************/
4 4
5 5
6 6 #header * {margin:0; padding:0;}
7 7 p, ul, ol, li {margin:0; padding:0;}
8 8
9 9
10 10 body{
11 11 font:76% Verdana,Tahoma,Arial,sans-serif;
12 12 line-height:1.4em;
13 13 text-align:center;
14 14 color:#303030;
15 15 background:#e8eaec;
16 16 margin:0;
17 17 }
18 18
19 19
20 20 a{
21 21 color:#467aa7;
22 22 font-weight:bold;
23 23 text-decoration:none;
24 24 background-color:inherit;
25 25 }
26 26
27 27 a:hover{color:#2a5a8a; text-decoration:none; background-color:inherit;}
28 28 a img{border:none;}
29 29
30 30 p{padding:0 0 1em 0;}
31 31 p form{margin-top:0; margin-bottom:20px;}
32 32
33 33 img.left,img.center,img.right{padding:4px; border:1px solid #a0a0a0;}
34 34 img.left{float:left; margin:0 12px 5px 0;}
35 35 img.center{display:block; margin:0 auto 5px auto;}
36 36 img.right{float:right; margin:0 0 5px 12px;}
37 37
38 38 /**************** Header and navigation styles ****************/
39 39
40 40 #container{
41 41 width:100%;
42 42 min-width: 800px;
43 43 margin:0;
44 44 padding:0;
45 45 text-align:left;
46 46 background:#ffffff;
47 47 color:#303030;
48 48 }
49 49
50 50 #header{
51 51 height:4.5em;
52 52 /*width:758px;*/
53 53 margin:0;
54 54 background:#467aa7;
55 55 color:#ffffff;
56 56 margin-bottom:1px;
57 57 }
58 58
59 59 #header h1{
60 60 padding:10px 0 0 20px;
61 61 font-size:2em;
62 62 background-color:inherit;
63 63 color:#fff; /*rgb(152, 26, 33);*/
64 64 letter-spacing:-1px;
65 65 font-weight:bold;
66 66 font-family: Trebuchet MS,Georgia,"Times New Roman",serif;
67 67 }
68 68
69 69 #header h2{
70 70 margin:3px 0 0 40px;
71 71 font-size:1.5em;
72 72 background-color:inherit;
73 73 color:#f0f2f4;
74 74 letter-spacing:-1px;
75 75 font-weight:normal;
76 76 font-family: Trebuchet MS,Georgia,"Times New Roman",serif;
77 77 }
78 78
79 79 #navigation{
80 80 height:2.2em;
81 81 line-height:2.2em;
82 82 /*width:758px;*/
83 83 margin:0;
84 84 background:#578bb8;
85 85 color:#ffffff;
86 86 }
87 87
88 88 #navigation li{
89 89 float:left;
90 90 list-style-type:none;
91 91 border-right:1px solid #ffffff;
92 92 white-space:nowrap;
93 93 }
94 94
95 95 #navigation li.right {
96 96 float:right;
97 97 list-style-type:none;
98 98 border-right:0;
99 99 border-left:1px solid #ffffff;
100 100 white-space:nowrap;
101 101 }
102 102
103 103 #navigation li a{
104 104 display:block;
105 105 padding:0px 10px 0px 22px;
106 106 font-size:0.8em;
107 107 font-weight:normal;
108 108 /*text-transform:uppercase;*/
109 109 text-decoration:none;
110 110 background-color:inherit;
111 111 color: #ffffff;
112 112 }
113 113
114 114 * html #navigation a {width:1%;}
115 115
116 116 #navigation .selected,#navigation a:hover{
117 117 color:#ffffff;
118 118 text-decoration:none;
119 119 background-color: #80b0da;
120 120 }
121 121
122 122 /**************** Icons links *******************/
123 123 .picHome { background: url(../images/home.png) no-repeat 4px 50%; }
124 124 .picUser { background: url(../images/user.png) no-repeat 4px 50%; }
125 125 .picUserPage { background: url(../images/user_page.png) no-repeat 4px 50%; }
126 126 .picAdmin { background: url(../images/admin.png) no-repeat 4px 50%; }
127 127 .picProject { background: url(../images/projects.png) no-repeat 4px 50%; }
128 128 .picLogout { background: url(../images/logout.png) no-repeat 4px 50%; }
129 129 .picHelp { background: url(../images/help.png) no-repeat 4px 50%; }
130 130
131 131 /**************** Content styles ****************/
132 132
133 133 html>body #content {
134 134 height: auto;
135 135 min-height: 500px;
136 136 }
137 137
138 138 #content{
139 139 /*float:right;*/
140 140 /*width:530px;*/
141 141 width: auto;
142 142 height:500px;
143 143 font-size:0.9em;
144 144 padding:20px 10px 10px 20px;
145 145 /*position: absolute;*/
146 146 margin-left: 120px;
147 147 border-left: 1px dashed #c0c0c0;
148 148
149 149 }
150 150
151 151 #content h2{
152 152 display:block;
153 153 margin:0 0 16px 0;
154 154 font-size:1.7em;
155 155 font-weight:normal;
156 156 letter-spacing:-1px;
157 157 color:#606060;
158 158 background-color:inherit;
159 159 font-family: Trebuchet MS,Georgia,"Times New Roman",serif;
160 160 }
161 161
162 162 #content h2 a{font-weight:normal;}
163 163 #content h3{margin:0 0 12px 0; font-size:1.4em;color:#707070;font-family: Trebuchet MS,Georgia,"Times New Roman",serif;}
164 164 #content a:hover,#subcontent a:hover{text-decoration:underline;}
165 165 #content ul,#content ol{margin:0 5px 16px 35px;}
166 166 #content dl{margin:0 5px 10px 25px;}
167 167 #content dt{font-weight:bold; margin-bottom:5px;}
168 168 #content dd{margin:0 0 10px 15px;}
169 169
170 170
171 171 /***********************************************/
172 172
173 173 /*
174 174 form{
175 175 padding:15px;
176 176 margin:0 0 20px 0;
177 177 border:1px solid #c0c0c0;
178 178 background-color:#CEE1ED;
179 179 width:600px;
180 180 }
181 181 */
182 182
183 183 form {
184 184 display: inline;
185 185 }
186 186
187 187 .noborder {
188 188 border:0px;
189 Exception exceptions.AssertionError: <exceptions.AssertionError instance at 0xb7c0b20c> in <bound
190 method SubversionRepository.__del__ of <vclib.svn.SubversionRepository instance at 0xb7c1252c>>
191 ignored
192
193 189 background-color:#fff;
194 190 width:100%;
195 191 }
196 192
197 193 textarea {
198 194 padding:0;
199 195 margin:0;
200 196 }
201 197
202 198 input {
203 199 vertical-align: middle;
204 200 }
205 201
206 202 input.button-small
207 203 {
208 204 font-size: 0.8em;
209 205 }
210 206
211 207 select {
212 208 vertical-align: middle;
213 209 }
214 210
215 211 select.select-small
216 212 {
217 213 border: 1px solid #7F9DB9;
218 214 padding: 1px;
219 215 font-size: 0.8em;
220 216 }
221 217
222 218 .active-filter
223 219 {
224 220 background-color: #F9FA9E;
225 221
226 222 }
227 223
228 224 label {
229 225 font-weight: bold;
230 226 font-size: 1em;
231 227 }
232 228
233 229 fieldset {
234 230 border:1px solid #7F9DB9;
235 231 padding: 6px;
236 232 }
237 233
238 234 legend {
239 235 color: #505050;
240 236
241 237 }
242 238
243 239 .required {
244 240 color: #bb0000;
245 241 }
246 242
247 243 table.listTableContent {
248 244 border:1px solid #578bb8;
249 245 width:99%;
250 246 border-collapse: collapse;
251 247 }
252 248
253 249 table.listTableContent td {
254 250 padding:2px;
255 251 }
256 252
257 253 tr.ListHead {
258 254 background-color:#467aa7;
259 255 color:#FFFFFF;
260 256 text-align:center;
261 257 }
262 258
263 259 tr.ListHead a {
264 260 color:#FFFFFF;
265 261 text-decoration:underline;
266 262 }
267 263
268 264 .odd {
269 265 background-color:#f0f1f2;
270 266 }
271 267 .even {
272 268 background-color: #fff;
273 269 }
274 270
275 271 table.reportTableContent {
276 272 border:1px solid #c0c0c0;
277 273 width:99%;
278 274 border-collapse: collapse;
279 275 }
280 276
281 277 table.reportTableContent td {
282 278 padding:2px;
283 279 }
284 280
285 281 table.calenderTable {
286 282 border:1px solid #578bb8;
287 283 width:99%;
288 284 border-collapse: collapse;
289 285 }
290 286
291 287 table.calenderTable td {
292 288 border:1px solid #578bb8;
293 289 }
294 290
295 hr { border:none; border-bottom: dotted 2px #c0c0c0; }
291 hr { border:none; border-bottom: dotted 1px #c0c0c0; }
296 292
297 293
298 294 /**************** Sidebar styles ****************/
299 295
300 296 #subcontent{
301 297 position: absolute;
302 298 left: 0px;
303 299 width:110px;
304 300 padding:20px 20px 10px 5px;
305 301 }
306 302
307 303 #subcontent h2{
308 304 display:block;
309 305 margin:0 0 5px 0;
310 306 font-size:1.0em;
311 307 font-weight:bold;
312 308 text-align:left;
313 309 color:#606060;
314 310 background-color:inherit;
315 311 font-family: Trebuchet MS,Georgia,"Times New Roman",serif;
316 312 }
317 313
318 314 #subcontent p{margin:0 0 16px 0; font-size:0.9em;}
319 315
320 316 /**************** Menublock styles ****************/
321 317
322 318 .menublock{margin:0 0 20px 8px; font-size:0.8em;}
323 319 .menublock li{list-style:none; display:block; padding:1px; margin-bottom:0px;}
324 320 .menublock li a{font-weight:bold; text-decoration:none;}
325 321 .menublock li a:hover{text-decoration:none;}
326 322 .menublock li ul{margin:0; font-size:1em; font-weight:normal;}
327 323 .menublock li ul li{margin-bottom:0;}
328 324 .menublock li ul a{font-weight:normal;}
329 325
330 326 /**************** Searchbar styles ****************/
331 327
332 328 #searchbar{margin:0 0 20px 0;}
333 329 #searchbar form fieldset{margin-left:10px; border:0 solid;}
334 330
335 331 #searchbar #s{
336 332 height:1.2em;
337 333 width:110px;
338 334 margin:0 5px 0 0;
339 335 border:1px solid #a0a0a0;
340 336 }
341 337
342 338 #searchbar #searchbutton{
343 339 width:auto;
344 340 padding:0 1px;
345 341 border:1px solid #808080;
346 342 font-size:0.9em;
347 343 text-align:center;
348 344 }
349 345
350 346 /**************** Footer styles ****************/
351 347
352 348 #footer{
353 349 clear:both;
354 350 /*width:758px;*/
355 351 padding:5px 0;
356 352 margin:0;
357 353 font-size:0.9em;
358 354 color:#f0f0f0;
359 355 background:#467aa7;
360 356 }
361 357
362 358 #footer p{padding:0; margin:0; text-align:center;}
363 359 #footer a{color:#f0f0f0; background-color:inherit; font-weight:bold;}
364 360 #footer a:hover{color:#ffffff; background-color:inherit; text-decoration: underline;}
365 361
366 362 /**************** Misc classes and styles ****************/
367 363
368 364 .splitcontentleft{float:left; width:49%;}
369 365 .splitcontentright{float:right; width:49%;}
370 366 .clear{clear:both;}
371 367 .small{font-size:0.8em;line-height:1.4em;padding:0 0 0 0;}
372 368 .hide{display:none;}
373 369 .textcenter{text-align:center;}
374 370 .textright{text-align:right;}
375 371 .important{color:#f02025; background-color:inherit; font-weight:bold;}
376 372
377 373 .box{
378 374 margin:0 0 20px 0;
379 375 padding:10px;
380 376 border:1px solid #c0c0c0;
381 377 background-color:#fafbfc;
382 378 color:#505050;
383 379 line-height:1.5em;
384 380 }
385 381
386 382 .rightbox{
387 383 background: #fafbfc;
388 384 border: 1px solid #c0c0c0;
389 385 float: right;
390 386 padding: 8px;
391 387 position: relative;
392 388 margin: 0 5px 5px;
393 389 }
394 390
395 391 .topright{
396 392 position: absolute;
397 393 right: 25px;
398 394 top: 100px;
399 395 }
400 396
401 397 .login {
402 398 width: 50%;
403 399 text-align: left;
404 400 }
405 401
406 402 img.calendar-trigger {
407 403 cursor: pointer;
408 404 vertical-align: middle;
409 405 margin-left: 4px;
410 406 }
411 407
408 #history h4 {
409 font-size: 1em;
410 margin-bottom: 12px;
411 margin-top: 20px;
412 font-weight: normal;
413 border-bottom: dotted 1px #c0c0c0;
414 }
415
416 #history p {
417 margin-left: 34px;
418 }
412 419
413 420 /***** CSS FORM ******/
414 421 .tabular p{
415 422 margin: 0;
416 423 padding: 5px 0 8px 0;
417 424 padding-left: 180px; /*width of left column containing the label elements*/
418 425 height: 1%;
419 426 }
420 427
421 428 .tabular label{
422 429 font-weight: bold;
423 430 float: left;
424 431 margin-left: -180px; /*width of left column*/
425 432 width: 175px; /*width of labels. Should be smaller than left column to create some right
426 433 margin*/
427 434 }
428 435
429 436 .error {
430 437 color: #cc0000;
431 438 }
432 439
433 440
434 441 /*.threepxfix class below:
435 442 Targets IE6- ONLY. Adds 3 pixel indent for multi-line form contents.
436 443 to account for 3 pixel bug: http://www.positioniseverything.net/explorer/threepxtest.html
437 444 */
438 445
439 446 * html .threepxfix{
440 447 margin-left: 3px;
441 448 } No newline at end of file
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now