##// 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
58 case custom_value.custom_field.field_format
57 format_value(custom_value.value, custom_value.custom_field.field_format)
58 end
59
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
65 end
69 value
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
29 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
28 txt = begin
29 @ic.iconv(txt)
30 rescue
31 txt
32 end
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 module IssuesHelper
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
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
66 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)
21 # Sends to all project members
22 @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
23 @from = $RDM_MAIL_FROM
24 @subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
25 @body['issue'] = issue
26 end
27
28 20 def issue_add(issue)
29 21 # Sends to all project members
30 22 @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
31 23 @from = $RDM_MAIL_FROM
32 24 @subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
33 25 @body['issue'] = issue
34 26 end
35 27
36 def issue_add_note(history)
28 def issue_edit(journal)
37 29 # Sends to all project members
38 @recipients = history.issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
30 issue = journal.journalized
31 @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
39 32 @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
33 @subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
34 @body['issue'] = issue
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 pdf.Cell(190,5, l(:label_history),"B")
71 pdf.Ln
72 for history in issue.histories.find(:all, :include => [:author, :status])
73 pdf.SetFont('Arial','B',8)
74 pdf.Cell(100,5, history.status.name)
75 pdf.SetFont('Arial','',8)
76 pdf.Cell(20,5, format_date(history.created_on))
77 pdf.Cell(70,5, history.author.name,0,0,"R")
78 pdf.SetFont('Arial','',8)
71 pdf.Cell(190,5, l(:label_history), "B")
72 pdf.Ln
73 for journal in issue.journals.find(:all, :include => :user, :order => "journals.created_on desc")
74 pdf.SetFont('Arial','B',8)
75 pdf.Cell(190,5, format_time(journal.created_on) + " - " + journal.user.name)
79 76 pdf.Ln
80 pdf.Cell(10,4, "") and pdf.MultiCell(180,4, history.notes) if history.notes?
77 pdf.SetFont('Arial','I',8)
78 for detail in journal.details
79 pdf.Cell(190,5, "- " + show_detail(detail, true))
80 pdf.Ln
81 end
82 if journal.notes?
83 pdf.SetFont('Arial','',8)
84 pdf.MultiCell(190,5, journal.notes)
85 end
86 pdf.Ln
81 87 end
82 pdf.Ln
83
88
84 89 pdf.SetFont('Arial','B',9)
85 90 pdf.Cell(190,5, l(:label_attachment_plural), "B")
86 pdf.Ln
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 </select></p>
29
30 <p><label for="history_notes"><%=l(:field_notes)%></label>
31 <%= text_area 'history', 'notes', :cols => 60, :rows => 10 %></p>
32 </div>
28 </select></p>
33 29
30 <p><label for="notes"><%= l(:field_notes) %></label>
31 <%= text_area_tag 'notes', @notes, :cols => 60, :rows => 10 %></p>
32
33 </div>
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>
95 <% end %>
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>
96 92 <% 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 <%= end_form_tag %>
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