##// END OF EJS Templates
"queries" branch merged...
Jean-Philippe Lang -
r92:2b0142580f9c
parent child
Show More
@@ -0,0 +1,49
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 QueriesController < ApplicationController
19 layout 'base'
20 before_filter :require_login, :find_query
21
22 def edit
23 if request.post?
24 @query.filters = {}
25 params[:fields].each do |field|
26 @query.add_filter(field, params[:operators][field], params[:values][field])
27 end if params[:fields]
28 @query.attributes = params[:query]
29
30 if @query.save
31 flash[:notice] = l(:notice_successful_update)
32 redirect_to :controller => 'projects', :action => 'list_issues', :id => @project, :query_id => @query
33 end
34 end
35 end
36
37 def destroy
38 @query.destroy if request.post?
39 redirect_to :controller => 'reports', :action => 'issue_report', :id => @project
40 end
41
42 private
43 def find_query
44 @query = Query.find(params[:id])
45 @project = @query.project
46 # check if user is allowed to manage queries (same permission as add_query)
47 authorize('projects', 'add_query')
48 end
49 end
@@ -0,0 +1,6
1 module QueriesHelper
2
3 def operators_for_select(filter_type)
4 Query.operators_by_filter_type[filter_type].collect {|o| [l(Query.operators[o]), o]}
5 end
6 end
@@ -0,0 +1,166
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 Query < ActiveRecord::Base
19 belongs_to :project
20 belongs_to :user
21 serialize :filters
22
23 attr_protected :project, :user
24
25 validates_presence_of :name, :on => :save
26
27 @@operators = { "=" => :label_equals,
28 "!" => :label_not_equals,
29 "o" => :label_open_issues,
30 "c" => :label_closed_issues,
31 "!*" => :label_none,
32 "*" => :label_all,
33 "<t+" => :label_in_less_than,
34 ">t+" => :label_in_more_than,
35 "t+" => :label_in,
36 "t" => :label_today,
37 ">t-" => :label_less_than_ago,
38 "<t-" => :label_more_than_ago,
39 "t-" => :label_ago,
40 "~" => :label_contains,
41 "!~" => :label_not_contains }
42
43 cattr_reader :operators
44
45 @@operators_by_filter_type = { :list => [ "=", "!" ],
46 :list_status => [ "o", "=", "!", "c", "*" ],
47 :list_optional => [ "=", "!", "!*", "*" ],
48 :date => [ "<t+", ">t+", "t+", "t", ">t-", "<t-", "t-" ],
49 :date_past => [ ">t-", "<t-", "t-", "t" ],
50 :text => [ "~", "!~" ] }
51
52 cattr_reader :operators_by_filter_type
53
54 def initialize(attributes = nil)
55 super attributes
56 self.filters ||= { 'status_id' => {:operator => "o", :values => [""]} }
57 self.is_public = true
58 end
59
60 def validate
61 filters.each_key do |field|
62 errors.add field.gsub(/\_id$/, ""), :activerecord_error_blank unless
63 # filter requires one or more values
64 (values_for(field) and !values_for(field).first.empty?) or
65 # filter doesn't require any value
66 ["o", "c", "!*", "*", "t"].include? operator_for(field)
67 end if filters
68 end
69
70 def available_filters
71 return @available_filters if @available_filters
72 @available_filters = { "status_id" => { :type => :list_status, :order => 1, :values => IssueStatus.find(:all).collect{|s| [s.name, s.id.to_s] } },
73 "tracker_id" => { :type => :list, :order => 2, :values => Tracker.find(:all).collect{|s| [s.name, s.id.to_s] } },
74 "priority_id" => { :type => :list, :order => 3, :values => Enumeration.find(:all, :conditions => ['opt=?','IPRI']).collect{|s| [s.name, s.id.to_s] } },
75 "subject" => { :type => :text, :order => 7 },
76 "created_on" => { :type => :date_past, :order => 8 },
77 "updated_on" => { :type => :date_past, :order => 9 },
78 "start_date" => { :type => :date, :order => 10 },
79 "due_date" => { :type => :date, :order => 11 } }
80 unless project.nil?
81 # project specific filters
82 @available_filters["assigned_to_id"] = { :type => :list_optional, :order => 4, :values => @project.users.collect{|s| [s.name, s.id.to_s] } }
83 @available_filters["author_id"] = { :type => :list, :order => 5, :values => @project.users.collect{|s| [s.name, s.id.to_s] } }
84 @available_filters["category_id"] = { :type => :list_optional, :order => 6, :values => @project.issue_categories.collect{|s| [s.name, s.id.to_s] } }
85 # remove category filter if no category defined
86 @available_filters.delete "category_id" if @available_filters["category_id"][:values].empty?
87 end
88 @available_filters
89 end
90
91 def add_filter(field, operator, values)
92 # values must be an array
93 return unless values and values.is_a? Array # and !values.first.empty?
94 # check if field is defined as an available filter
95 if available_filters.has_key? field
96 filter_options = available_filters[field]
97 # check if operator is allowed for that filter
98 #if @@operators_by_filter_type[filter_options[:type]].include? operator
99 # allowed_values = values & ([""] + (filter_options[:values] || []).collect {|val| val[1]})
100 # filters[field] = {:operator => operator, :values => allowed_values } if (allowed_values.first and !allowed_values.first.empty?) or ["o", "c", "!*", "*", "t"].include? operator
101 #end
102 filters[field] = {:operator => operator, :values => values }
103 end
104 end
105
106 def add_short_filter(field, expression)
107 return unless expression
108 parms = expression.scan(/^(o|c|\!|\*)?(.*)$/).first
109 add_filter field, (parms[0] || "="), [parms[1] || ""]
110 end
111
112 def has_filter?(field)
113 filters and filters[field]
114 end
115
116 def operator_for(field)
117 has_filter?(field) ? filters[field][:operator] : nil
118 end
119
120 def values_for(field)
121 has_filter?(field) ? filters[field][:values] : nil
122 end
123
124 def statement
125 sql = "1=1"
126 sql << " AND issues.project_id=%d" % project.id if project
127 filters.each_key do |field|
128 v = values_for field
129 next unless v and !v.empty?
130 sql = sql + " AND " unless sql.empty?
131 case operator_for field
132 when "="
133 sql = sql + "issues.#{field} IN (" + v.each(&:to_i).join(",") + ")"
134 when "!"
135 sql = sql + "issues.#{field} NOT IN (" + v.each(&:to_i).join(",") + ")"
136 when "!*"
137 sql = sql + "issues.#{field} IS NULL"
138 when "*"
139 sql = sql + "issues.#{field} IS NOT NULL"
140 when "o"
141 sql = sql + "issue_statuses.is_closed=#{connection.quoted_false}" if field == "status_id"
142 when "c"
143 sql = sql + "issue_statuses.is_closed=#{connection.quoted_true}" if field == "status_id"
144 when ">t-"
145 sql = sql + "issues.#{field} >= '%s'" % connection.quoted_date(Date.today - v.first.to_i)
146 when "<t-"
147 sql = sql + "issues.#{field} <= '" + (Date.today - v.first.to_i).strftime("%Y-%m-%d") + "'"
148 when "t-"
149 sql = sql + "issues.#{field} = '" + (Date.today - v.first.to_i).strftime("%Y-%m-%d") + "'"
150 when ">t+"
151 sql = sql + "issues.#{field} >= '" + (Date.today + v.first.to_i).strftime("%Y-%m-%d") + "'"
152 when "<t+"
153 sql = sql + "issues.#{field} <= '" + (Date.today + v.first.to_i).strftime("%Y-%m-%d") + "'"
154 when "t+"
155 sql = sql + "issues.#{field} = '" + (Date.today + v.first.to_i).strftime("%Y-%m-%d") + "'"
156 when "t"
157 sql = sql + "issues.#{field} = '%s'" % connection.quoted_date(Date.today)
158 when "~"
159 sql = sql + "issues.#{field} LIKE '%#{connection.quote_string(v.first)}%'"
160 when "!~"
161 sql = sql + "issues.#{field} NOT LIKE '%#{connection.quote_string(v.first)}%'"
162 end
163 end if filters and valid?
164 sql
165 end
166 end
@@ -0,0 +1,6
1 <h2><%= l(:label_query_new) %></h2>
2
3 <%= start_form_tag :action => 'add_query', :id => @project %>
4 <%= render :partial => 'queries/form', :locals => {:query => @query} %>
5 <%= submit_tag l(:button_create) %>
6 <%= end_form_tag %> No newline at end of file
@@ -0,0 +1,100
1 <script>
2
3 function add_filter() {
4 select = $('add_filter_select');
5 field = select.value
6 Element.show('tr_' + field);
7 check_box = $('cb_' + field);
8 check_box.checked = true;
9 toggle_filter(field);
10 select.selectedIndex = 0;
11
12 for (i=0; i<select.options.length; i++) {
13 if (select.options[i].value == field) {
14 select.options[i].disabled = true;
15 }
16 }
17 }
18
19 function toggle_filter(field) {
20 check_box = $('cb_' + field);
21
22 if (check_box.checked) {
23 Element.show("operators[" + field + "]");
24 toggle_operator(field);
25 } else {
26 Element.hide("operators[" + field + "]");
27 Element.hide("values_div[" + field + "]");
28 }
29 }
30
31 function toggle_operator(field) {
32 operator = $("operators[" + field + "]");
33 switch (operator.value) {
34 case "!*":
35 case "*":
36 case "t":
37 case "o":
38 case "c":
39 Element.hide("values_div[" + field + "]");
40 break;
41 default:
42 Element.show("values_div[" + field + "]");
43 break;
44 }
45 }
46
47 function toggle_multi_select(field) {
48 select = $('values[' + field + '][]');
49 if (select.multiple == true) {
50 select.multiple = false;
51 } else {
52 select.multiple = true;
53 }
54 }
55
56 </script>
57
58 <fieldset style="margin:0;"><legend><%= l(:label_filter_plural) %></legend>
59 <table width="100%" cellpadding=0 cellspacing=0>
60 <tr>
61 <td>
62 <table>
63 <% query.available_filters.sort{|a,b| a[1][:order]<=>b[1][:order]}.each do |filter| %>
64 <% field = filter[0]
65 options = filter[1] %>
66 <tr <%= 'style="display:none;"' unless query.has_filter?(field) %> id="tr_<%= field %>">
67 <td valign="top" width="200">
68 <%= check_box_tag 'fields[]', field, query.has_filter?(field), :onclick => "toggle_filter('#{field}');", :id => "cb_#{field}" %>
69 <label for="cb_<%= field %>"><%= l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) %></label>
70 </td>
71 <td valign="top" width="150">
72 <%= select_tag "operators[#{field}]", options_for_select(operators_for_select(options[:type]), query.operator_for(field)), :onchange => "toggle_operator('#{field}');", :class => "select-small", :style => "vertical-align: top;" %>
73 </td>
74 <td valign="top">
75 <div id="values_div[<%= field %>]">
76 <% case options[:type]
77 when :list, :list_optional, :list_status %>
78 <select <%= "multiple=true" if query.values_for(field) and query.values_for(field).length > 1 %>" name="values[<%= field %>][]" id="values[<%= field %>][]" class="select-small" style="vertical-align: top;">
79 <%= options_for_select options[:values], query.values_for(field) %>
80 </select>
81 <%= link_to_function image_tag('expand'), "toggle_multi_select('#{field}');" %>
82 <% when :date, :date_past %>
83 <%= text_field_tag "values[#{field}][]", query.values_for(field), :size => 3, :class => "select-small" %> <%= l(:label_day_plural) %>
84 <% when :text %>
85 <%= text_field_tag "values[#{field}][]", query.values_for(field), :size => 30, :class => "select-small" %>
86 <% end %>
87 </div>
88 </td>
89 </tr>
90 <script>toggle_filter('<%= field %>');</script>
91 <% end %>
92 </table>
93 </td>
94 <td align="right" valign="top">
95 <%= l(:label_filter_add) %>:
96 <%= select_tag 'add_filter_select', options_for_select([["",""]] + query.available_filters.sort{|a,b| a[1][:order]<=>b[1][:order]}.collect{|field| [l(("field_"+field[0].to_s.gsub(/\_id$/, "")).to_sym), field[0]] unless query.has_filter?(field[0])}.compact), :onchange => "add_filter();", :class => "select-small" %>
97 </td>
98 </tr>
99 </table>
100 </fieldset> No newline at end of file
@@ -0,0 +1,12
1 <%= error_messages_for 'query' %>
2
3 <!--[form:query]-->
4 <div class="box">
5 <div class="tabular">
6 <p><label for="query_name"><%=l(:field_name)%></label>
7 <%= text_field 'query', 'name', :size => 80 %></p>
8 </div>
9
10 <%= render :partial => 'queries/filters', :locals => {:query => query}%>
11 </div>
12 <!--[eoform:query]--> No newline at end of file
@@ -0,0 +1,6
1 <h2><%= l(:label_query) %></h2>
2
3 <%= start_form_tag :action => 'edit', :id => @query %>
4 <%= render :partial => 'form', :locals => {:query => @query} %>
5 <%= submit_tag l(:button_save) %>
6 <%= end_form_tag %> No newline at end of file
@@ -0,0 +1,15
1 class CreateQueries < ActiveRecord::Migration
2 def self.up
3 create_table :queries, :force => true do |t|
4 t.column "project_id", :integer
5 t.column "name", :string, :default => "", :null => false
6 t.column "filters", :text
7 t.column "user_id", :integer, :default => 0, :null => false
8 t.column "is_public", :boolean, :default => false, :null => false
9 end
10 end
11
12 def self.down
13 drop_table :queries
14 end
15 end
@@ -0,0 +1,9
1 class AddQueriesPermissions < ActiveRecord::Migration
2 def self.up
3 Permission.create :controller => "projects", :action => "add_query", :description => "button_create", :sort => 600, :is_public => false, :mail_option => 0, :mail_enabled => 0
4 end
5
6 def self.down
7 Permission.find(:first, :conditions => ["controller=? and action=?", 'projects', 'add_query']).destroy
8 end
9 end
1 NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
@@ -1,126 +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 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 def authorize
74 def authorize(ctrl = @params[:controller], action = @params[:action])
75 75 # check if action is allowed on public projects
76 if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ @params[:controller], @params[:action] ]
76 if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ ctrl, 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 if @user_membership and Permission.allowed_to_role( "%s/%s" % [ @params[:controller], @params[:action] ], @user_membership.role_id )
85 if @user_membership and Permission.allowed_to_role( "%s/%s" % [ ctrl, 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 107
108 108 # qvalues http header parser
109 109 # code taken from webrick
110 110 def parse_qvalues(value)
111 111 tmp = []
112 112 if value
113 113 parts = value.split(/,\s*/)
114 114 parts.each {|part|
115 115 if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
116 116 val = m[1]
117 117 q = (m[2] or 1).to_f
118 118 tmp.push([val, q])
119 119 end
120 120 }
121 121 tmp = tmp.sort_by{|val, q| -q}
122 122 tmp.collect!{|val, q| val}
123 123 end
124 124 return tmp
125 125 end
126 126 end No newline at end of file
@@ -1,474 +1,518
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 layout 'base', :except => :export_issues_pdf
19 layout 'base'
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 helper :search_filter
26 include SearchFilterHelper
27 25 helper :custom_fields
28 26 include CustomFieldsHelper
29 27 helper :ifpdf
30 28 include IfpdfHelper
31 29 helper IssuesHelper
30 helper :queries
31 include QueriesHelper
32 32
33 33 def index
34 34 list
35 35 render :action => 'list' unless request.xhr?
36 36 end
37 37
38 38 # Lists public projects
39 39 def list
40 40 sort_init 'name', 'asc'
41 41 sort_update
42 42 @project_count = Project.count(["is_public=?", true])
43 43 @project_pages = Paginator.new self, @project_count,
44 44 15,
45 45 @params['page']
46 46 @projects = Project.find :all, :order => sort_clause,
47 47 :conditions => ["is_public=?", true],
48 48 :limit => @project_pages.items_per_page,
49 49 :offset => @project_pages.current.offset
50 50
51 51 render :action => "list", :layout => false if request.xhr?
52 52 end
53 53
54 54 # Add a new project
55 55 def add
56 56 @custom_fields = IssueCustomField.find(:all)
57 57 @root_projects = Project.find(:all, :conditions => "parent_id is null")
58 58 @project = Project.new(params[:project])
59 59 if request.get?
60 60 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project) }
61 61 else
62 62 @project.custom_fields = CustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
63 63 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
64 64 @project.custom_values = @custom_values
65 65 if @project.save
66 66 flash[:notice] = l(:notice_successful_create)
67 67 redirect_to :controller => 'admin', :action => 'projects'
68 68 end
69 69 end
70 70 end
71 71
72 72 # Show @project
73 73 def show
74 74 @custom_values = @project.custom_values.find(:all, :include => :custom_field)
75 75 @members = @project.members.find(:all, :include => [:user, :role])
76 76 @subprojects = @project.children if @project.children_count > 0
77 77 @news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "news.created_on DESC")
78 78 @trackers = Tracker.find(:all)
79 79 end
80 80
81 81 def settings
82 82 @root_projects = Project::find(:all, :conditions => ["parent_id is null and id <> ?", @project.id])
83 83 @custom_fields = IssueCustomField::find_all
84 84 @issue_category ||= IssueCategory.new
85 85 @member ||= @project.members.new
86 86 @roles = Role.find_all
87 87 @users = User.find_all - @project.members.find(:all, :include => :user).collect{|m| m.user }
88 88 @custom_values ||= ProjectCustomField.find(:all).collect { |x| @project.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
89 89 end
90 90
91 91 # Edit @project
92 92 def edit
93 93 if request.post?
94 94 @project.custom_fields = IssueCustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
95 95 if params[:custom_fields]
96 96 @custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
97 97 @project.custom_values = @custom_values
98 98 end
99 99 if @project.update_attributes(params[:project])
100 100 flash[:notice] = l(:notice_successful_update)
101 101 redirect_to :action => 'settings', :id => @project
102 102 else
103 103 settings
104 104 render :action => 'settings'
105 105 end
106 106 end
107 107 end
108 108
109 109 # Delete @project
110 110 def destroy
111 111 if request.post? and params[:confirm]
112 112 @project.destroy
113 113 redirect_to :controller => 'admin', :action => 'projects'
114 114 end
115 115 end
116 116
117 117 # Add a new issue category to @project
118 118 def add_issue_category
119 119 if request.post?
120 120 @issue_category = @project.issue_categories.build(params[:issue_category])
121 121 if @issue_category.save
122 122 flash[:notice] = l(:notice_successful_create)
123 123 redirect_to :action => 'settings', :id => @project
124 124 else
125 125 settings
126 126 render :action => 'settings'
127 127 end
128 128 end
129 129 end
130 130
131 131 # Add a new version to @project
132 132 def add_version
133 133 @version = @project.versions.build(params[:version])
134 134 if request.post? and @version.save
135 135 flash[:notice] = l(:notice_successful_create)
136 136 redirect_to :action => 'settings', :id => @project
137 137 end
138 138 end
139 139
140 140 # Add a new member to @project
141 141 def add_member
142 142 @member = @project.members.build(params[:member])
143 143 if request.post?
144 144 if @member.save
145 145 flash[:notice] = l(:notice_successful_create)
146 146 redirect_to :action => 'settings', :id => @project
147 147 else
148 148 settings
149 149 render :action => 'settings'
150 150 end
151 151 end
152 152 end
153 153
154 154 # Show members list of @project
155 155 def list_members
156 156 @members = @project.members
157 157 end
158 158
159 159 # Add a new document to @project
160 160 def add_document
161 161 @categories = Enumeration::get_values('DCAT')
162 162 @document = @project.documents.build(params[:document])
163 163 if request.post?
164 164 # Save the attachment
165 165 if params[:attachment][:file].size > 0
166 166 @attachment = @document.attachments.build(params[:attachment])
167 167 @attachment.author_id = self.logged_in_user.id if self.logged_in_user
168 168 end
169 169 if @document.save
170 170 flash[:notice] = l(:notice_successful_create)
171 171 redirect_to :action => 'list_documents', :id => @project
172 172 end
173 173 end
174 174 end
175 175
176 176 # Show documents list of @project
177 177 def list_documents
178 178 @documents = @project.documents
179 179 end
180 180
181 181 # Add a new issue to @project
182 182 def add_issue
183 183 @tracker = Tracker.find(params[:tracker_id])
184 184 @priorities = Enumeration::get_values('IPRI')
185 185 @issue = Issue.new(:project => @project, :tracker => @tracker)
186 186 if request.get?
187 187 @issue.start_date = Date.today
188 188 @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue) }
189 189 else
190 190 @issue.attributes = params[:issue]
191 191 @issue.author_id = self.logged_in_user.id if self.logged_in_user
192 192 # Multiple file upload
193 193 params[:attachments].each { |a|
194 194 @attachment = @issue.attachments.build(:file => a, :author => self.logged_in_user) unless a.size == 0
195 195 } if params[:attachments] and params[:attachments].is_a? Array
196 196 @custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
197 197 @issue.custom_values = @custom_values
198 198 if @issue.save
199 199 flash[:notice] = l(:notice_successful_create)
200 200 Mailer.deliver_issue_add(@issue) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
201 201 redirect_to :action => 'list_issues', :id => @project
202 202 end
203 203 end
204 204 end
205 205
206 206 # Show filtered/sorted issues list of @project
207 207 def list_issues
208 208 sort_init 'issues.id', 'desc'
209 209 sort_update
210 210
211 search_filter_init_list_issues
212 search_filter_update if params[:set_filter]
211 retrieve_query
213 212
214 213 @results_per_page_options = [ 15, 25, 50, 100 ]
215 214 if params[:per_page] and @results_per_page_options.include? params[:per_page].to_i
216 215 @results_per_page = params[:per_page].to_i
217 216 session[:results_per_page] = @results_per_page
218 217 else
219 218 @results_per_page = session[:results_per_page] || 25
220 219 end
221 220
222 @issue_count = Issue.count(:include => [:status, :project], :conditions => search_filter_clause)
221 if @query.valid?
222 @issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
223 223 @issue_pages = Paginator.new self, @issue_count, @results_per_page, @params['page']
224 224 @issues = Issue.find :all, :order => sort_clause,
225 225 :include => [ :author, :status, :tracker, :project ],
226 :conditions => search_filter_clause,
226 :conditions => @query.statement,
227 227 :limit => @issue_pages.items_per_page,
228 228 :offset => @issue_pages.current.offset
229
229 end
230 230 render :layout => false if request.xhr?
231 231 end
232 232
233 233 # Export filtered/sorted issues list to CSV
234 234 def export_issues_csv
235 235 sort_init 'issues.id', 'desc'
236 236 sort_update
237 237
238 search_filter_init_list_issues
238 retrieve_query
239 render :action => 'list_issues' and return unless @query.valid?
239 240
240 241 @issues = Issue.find :all, :order => sort_clause,
241 242 :include => [ :author, :status, :tracker, :project, :custom_values ],
242 :conditions => search_filter_clause
243 :conditions => @query.statement
243 244
244 245 ic = Iconv.new('ISO-8859-1', 'UTF-8')
245 246 export = StringIO.new
246 247 CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
247 248 # csv header fields
248 249 headers = [ "#", l(:field_status), l(:field_tracker), l(:field_subject), l(:field_author), l(:field_created_on), l(:field_updated_on) ]
249 250 for custom_field in @project.all_custom_fields
250 251 headers << custom_field.name
251 252 end
252 253 csv << headers.collect {|c| ic.iconv(c) }
253 254 # csv lines
254 255 @issues.each do |issue|
255 256 fields = [issue.id, issue.status.name, issue.tracker.name, issue.subject, issue.author.display_name, l_datetime(issue.created_on), l_datetime(issue.updated_on)]
256 257 for custom_field in @project.all_custom_fields
257 258 fields << (show_value issue.custom_value_for(custom_field))
258 259 end
259 260 csv << fields.collect {|c| ic.iconv(c.to_s) }
260 261 end
261 262 end
262 263 export.rewind
263 264 send_data(export.read, :type => 'text/csv; header=present', :filename => 'export.csv')
264 265 end
265 266
266 267 # Export filtered/sorted issues to PDF
267 268 def export_issues_pdf
268 269 sort_init 'issues.id', 'desc'
269 270 sort_update
270 271
271 search_filter_init_list_issues
272 retrieve_query
273 render :action => 'list_issues' and return unless @query.valid?
272 274
273 275 @issues = Issue.find :all, :order => sort_clause,
274 276 :include => [ :author, :status, :tracker, :project, :custom_values ],
275 :conditions => search_filter_clause
277 :conditions => @query.statement
276 278
277 279 @options_for_rfpdf ||= {}
278 280 @options_for_rfpdf[:file_name] = "export.pdf"
281 render :layout => false
279 282 end
280 283
281 284 def move_issues
282 285 @issues = @project.issues.find(params[:issue_ids]) if params[:issue_ids]
283 286 redirect_to :action => 'list_issues', :id => @project and return unless @issues
284 287 @projects = []
285 288 # find projects to which the user is allowed to move the issue
286 289 @logged_in_user.memberships.each {|m| @projects << m.project if Permission.allowed_to_role("projects/move_issues", m.role_id)}
287 290 # issue can be moved to any tracker
288 291 @trackers = Tracker.find(:all)
289 292 if request.post? and params[:new_project_id] and params[:new_tracker_id]
290 293 new_project = Project.find(params[:new_project_id])
291 294 new_tracker = Tracker.find(params[:new_tracker_id])
292 295 @issues.each { |i|
293 296 # category is project dependent
294 297 i.category = nil unless i.project_id == new_project.id
295 298 # move the issue
296 299 i.project = new_project
297 300 i.tracker = new_tracker
298 301 i.save
299 302 }
300 303 flash[:notice] = l(:notice_successful_update)
301 304 redirect_to :action => 'list_issues', :id => @project
302 305 end
303 306 end
304 307
308 def add_query
309 @query = Query.new(params[:query])
310 @query.project = @project
311 @query.user = logged_in_user
312
313 params[:fields].each do |field|
314 @query.add_filter(field, params[:operators][field], params[:values][field])
315 end if params[:fields]
316
317 if request.post? and @query.save
318 flash[:notice] = l(:notice_successful_create)
319 redirect_to :controller => 'reports', :action => 'issue_report', :id => @project
320 end
321 render :layout => false if request.xhr?
322 end
323
305 324 # Add a news to @project
306 325 def add_news
307 326 @news = News.new(:project => @project)
308 327 if request.post?
309 328 @news.attributes = params[:news]
310 329 @news.author_id = self.logged_in_user.id if self.logged_in_user
311 330 if @news.save
312 331 flash[:notice] = l(:notice_successful_create)
313 332 redirect_to :action => 'list_news', :id => @project
314 333 end
315 334 end
316 335 end
317 336
318 337 # Show news list of @project
319 338 def list_news
320 339 @news_pages, @news = paginate :news, :per_page => 10, :conditions => ["project_id=?", @project.id], :include => :author, :order => "news.created_on DESC"
321 340 render :action => "list_news", :layout => false if request.xhr?
322 341 end
323 342
324 343 def add_file
325 344 if request.post?
326 345 # Save the attachment
327 346 if params[:attachment][:file].size > 0
328 347 @attachment = @project.versions.find(params[:version_id]).attachments.build(params[:attachment])
329 348 @attachment.author_id = self.logged_in_user.id if self.logged_in_user
330 349 if @attachment.save
331 350 flash[:notice] = l(:notice_successful_create)
332 351 redirect_to :controller => 'projects', :action => 'list_files', :id => @project
333 352 end
334 353 end
335 354 end
336 355 @versions = @project.versions
337 356 end
338 357
339 358 def list_files
340 359 @versions = @project.versions
341 360 end
342 361
343 362 # Show changelog for @project
344 363 def changelog
345 364 @trackers = Tracker.find(:all, :conditions => ["is_in_chlog=?", true])
346 365 if request.get?
347 366 @selected_tracker_ids = @trackers.collect {|t| t.id.to_s }
348 367 else
349 368 @selected_tracker_ids = params[:tracker_ids].collect { |id| id.to_i.to_s } if params[:tracker_ids] and params[:tracker_ids].is_a? Array
350 369 end
351 370 @selected_tracker_ids ||= []
352 371 @fixed_issues = @project.issues.find(:all,
353 372 :include => [ :fixed_version, :status, :tracker ],
354 373 :conditions => [ "issue_statuses.is_closed=? and issues.tracker_id in (#{@selected_tracker_ids.join(',')}) and issues.fixed_version_id is not null", true],
355 374 :order => "versions.effective_date DESC, issues.id DESC"
356 375 ) unless @selected_tracker_ids.empty?
357 376 @fixed_issues ||= []
358 377 end
359 378
360 379 def activity
361 380 if params[:year] and params[:year].to_i > 1900
362 381 @year = params[:year].to_i
363 382 if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
364 383 @month = params[:month].to_i
365 384 end
366 385 end
367 386 @year ||= Date.today.year
368 387 @month ||= Date.today.month
369 388
370 389 @date_from = Date.civil(@year, @month, 1)
371 390 @date_to = (@date_from >> 1)-1
372 391
373 392 @events_by_day = {}
374 393
375 394 unless params[:show_issues] == "0"
376 395 @project.issues.find(:all, :include => [:author, :status], :conditions => ["issues.created_on>=? and issues.created_on<=?", @date_from, @date_to] ).each { |i|
377 396 @events_by_day[i.created_on.to_date] ||= []
378 397 @events_by_day[i.created_on.to_date] << i
379 398 }
380 399 @show_issues = 1
381 400 end
382 401
383 402 unless params[:show_news] == "0"
384 403 @project.news.find(:all, :conditions => ["news.created_on>=? and news.created_on<=?", @date_from, @date_to] ).each { |i|
385 404 @events_by_day[i.created_on.to_date] ||= []
386 405 @events_by_day[i.created_on.to_date] << i
387 406 }
388 407 @show_news = 1
389 408 end
390 409
391 410 unless params[:show_files] == "0"
392 411 Attachment.find(:all, :select => "attachments.*", :joins => "LEFT JOIN versions ON versions.id = attachments.container_id", :conditions => ["attachments.container_type='Version' and versions.project_id=? and attachments.created_on>=? and attachments.created_on<=?", @project.id, @date_from, @date_to] ).each { |i|
393 412 @events_by_day[i.created_on.to_date] ||= []
394 413 @events_by_day[i.created_on.to_date] << i
395 414 }
396 415 @show_files = 1
397 416 end
398 417
399 418 unless params[:show_documents] == "0"
400 419 @project.documents.find(:all, :conditions => ["documents.created_on>=? and documents.created_on<=?", @date_from, @date_to] ).each { |i|
401 420 @events_by_day[i.created_on.to_date] ||= []
402 421 @events_by_day[i.created_on.to_date] << i
403 422 }
404 423 Attachment.find(:all, :select => "attachments.*", :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|
405 424 @events_by_day[i.created_on.to_date] ||= []
406 425 @events_by_day[i.created_on.to_date] << i
407 426 }
408 427 @show_documents = 1
409 428 end
410 429
411 430 render :layout => false if request.xhr?
412 431 end
413 432
414 433 def calendar
415 434 if params[:year] and params[:year].to_i > 1900
416 435 @year = params[:year].to_i
417 436 if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
418 437 @month = params[:month].to_i
419 438 end
420 439 end
421 440 @year ||= Date.today.year
422 441 @month ||= Date.today.month
423 442
424 443 @date_from = Date.civil(@year, @month, 1)
425 444 @date_to = (@date_from >> 1)-1
426 445 # start on monday
427 446 @date_from = @date_from - (@date_from.cwday-1)
428 447 # finish on sunday
429 448 @date_to = @date_to + (7-@date_to.cwday)
430 449
431 450 @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])
432 451 render :layout => false if request.xhr?
433 452 end
434 453
435 454 def gantt
436 455 if params[:year] and params[:year].to_i >0
437 456 @year_from = params[:year].to_i
438 457 if params[:month] and params[:month].to_i >=1 and params[:month].to_i <= 12
439 458 @month_from = params[:month].to_i
440 459 else
441 460 @month_from = 1
442 461 end
443 462 else
444 463 @month_from ||= (Date.today << 1).month
445 464 @year_from ||= (Date.today << 1).year
446 465 end
447 466
448 467 @zoom = (params[:zoom].to_i > 0 and params[:zoom].to_i < 5) ? params[:zoom].to_i : 2
449 468 @months = (params[:months].to_i > 0 and params[:months].to_i < 25) ? params[:months].to_i : 6
450 469
451 470 @date_from = Date.civil(@year_from, @month_from, 1)
452 471 @date_to = (@date_from >> @months) - 1
453 472 @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])
454 473
455 474 if params[:output]=='pdf'
456 475 @options_for_rfpdf ||= {}
457 476 @options_for_rfpdf[:file_name] = "gantt.pdf"
458 477 render :template => "projects/gantt.rfpdf", :layout => false
459 478 else
460 479 render :template => "projects/gantt.rhtml"
461 480 end
462 481 end
463 482
464 483 private
465 484 # Find project of id params[:id]
466 485 # if not found, redirect to project list
467 486 # Used as a before_filter
468 487 def find_project
469 488 @project = Project.find(params[:id])
470 489 @html_title = @project.name
471 490 rescue
472 491 redirect_to :action => 'list'
473 492 end
493
494 # Retrieve query from session or build a new query
495 def retrieve_query
496 if params[:query_id]
497 @query = @project.queries.find(params[:query_id])
498 else
499 if params[:set_filter] or !session[:query] or session[:query].project_id != @project.id
500 # Give it a name, required to be valid
501 @query = Query.new(:name => "_")
502 @query.project = @project
503 if params[:fields] and params[:fields].is_a? Array
504 params[:fields].each do |field|
505 @query.add_filter(field, params[:operators][field], params[:values][field])
506 end
507 else
508 @query.available_filters.keys.each do |field|
509 @query.add_short_filter(field, params[field]) if params[field]
510 end
511 end
512 session[:query] = @query
513 else
514 @query = session[:query]
515 end
516 end
517 end
474 518 end
@@ -1,164 +1,165
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 ReportsController < ApplicationController
19 19 layout 'base'
20 20 before_filter :find_project, :authorize
21 21
22 22 def issue_report
23 23 @statuses = IssueStatus.find_all
24 24
25 25 case params[:detail]
26 26 when "tracker"
27 27 @field = "tracker_id"
28 28 @rows = Tracker.find_all
29 29 @data = issues_by_tracker
30 30 @report_title = l(:field_tracker)
31 31 render :template => "reports/issue_report_details"
32 32 when "priority"
33 33 @field = "priority_id"
34 34 @rows = Enumeration::get_values('IPRI')
35 35 @data = issues_by_priority
36 36 @report_title = l(:field_priority)
37 37 render :template => "reports/issue_report_details"
38 38 when "category"
39 39 @field = "category_id"
40 40 @rows = @project.issue_categories
41 41 @data = issues_by_category
42 42 @report_title = l(:field_category)
43 43 render :template => "reports/issue_report_details"
44 44 when "author"
45 45 @field = "author_id"
46 46 @rows = @project.members.collect { |m| m.user }
47 47 @data = issues_by_author
48 48 @report_title = l(:field_author)
49 49 render :template => "reports/issue_report_details"
50 50 else
51 @queries = @project.queries.find :all, :conditions => ["is_public=? or user_id=?", true, (logged_in_user ? logged_in_user.id : 0)]
51 52 @trackers = Tracker.find(:all)
52 53 @priorities = Enumeration::get_values('IPRI')
53 54 @categories = @project.issue_categories
54 55 @authors = @project.members.collect { |m| m.user }
55 56 issues_by_tracker
56 57 issues_by_priority
57 58 issues_by_category
58 59 issues_by_author
59 60 render :template => "reports/issue_report"
60 61 end
61 62 end
62 63
63 64 def delays
64 65 @trackers = Tracker.find(:all)
65 66 if request.get?
66 67 @selected_tracker_ids = @trackers.collect {|t| t.id.to_s }
67 68 else
68 69 @selected_tracker_ids = params[:tracker_ids].collect { |id| id.to_i.to_s } if params[:tracker_ids] and params[:tracker_ids].is_a? Array
69 70 end
70 71 @selected_tracker_ids ||= []
71 72 @raw =
72 73 ActiveRecord::Base.connection.select_all("SELECT datediff( a.created_on, b.created_on ) as delay, count(a.id) as total
73 74 FROM issue_histories a, issue_histories b, issues i
74 75 WHERE a.status_id =5
75 76 AND a.issue_id = b.issue_id
76 77 AND a.issue_id = i.id
77 78 AND i.tracker_id in (#{@selected_tracker_ids.join(',')})
78 79 AND b.id = (
79 80 SELECT min( c.id )
80 81 FROM issue_histories c
81 82 WHERE b.issue_id = c.issue_id )
82 83 GROUP BY delay") unless @selected_tracker_ids.empty?
83 84 @raw ||=[]
84 85
85 86 @x_from = 0
86 87 @x_to = 0
87 88 @y_from = 0
88 89 @y_to = 0
89 90 @sum_total = 0
90 91 @sum_delay = 0
91 92 @raw.each do |r|
92 93 @x_to = [r['delay'].to_i, @x_to].max
93 94 @y_to = [r['total'].to_i, @y_to].max
94 95 @sum_total = @sum_total + r['total'].to_i
95 96 @sum_delay = @sum_delay + r['total'].to_i * r['delay'].to_i
96 97 end
97 98 end
98 99
99 100 private
100 101 # Find project of id params[:id]
101 102 def find_project
102 103 @project = Project.find(params[:id])
103 104 end
104 105
105 106 def issues_by_tracker
106 107 @issues_by_tracker ||=
107 108 ActiveRecord::Base.connection.select_all("select s.id as status_id,
108 109 s.is_closed as closed,
109 110 t.id as tracker_id,
110 111 count(i.id) as total
111 112 from
112 113 issues i, issue_statuses s, trackers t
113 114 where
114 115 i.status_id=s.id
115 116 and i.tracker_id=t.id
116 117 and i.project_id=#{@project.id}
117 118 group by s.id, s.is_closed, t.id")
118 119 end
119 120
120 121 def issues_by_priority
121 122 @issues_by_priority ||=
122 123 ActiveRecord::Base.connection.select_all("select s.id as status_id,
123 124 s.is_closed as closed,
124 125 p.id as priority_id,
125 126 count(i.id) as total
126 127 from
127 128 issues i, issue_statuses s, enumerations p
128 129 where
129 130 i.status_id=s.id
130 131 and i.priority_id=p.id
131 132 and i.project_id=#{@project.id}
132 133 group by s.id, s.is_closed, p.id")
133 134 end
134 135
135 136 def issues_by_category
136 137 @issues_by_category ||=
137 138 ActiveRecord::Base.connection.select_all("select s.id as status_id,
138 139 s.is_closed as closed,
139 140 c.id as category_id,
140 141 count(i.id) as total
141 142 from
142 143 issues i, issue_statuses s, issue_categories c
143 144 where
144 145 i.status_id=s.id
145 146 and i.category_id=c.id
146 147 and i.project_id=#{@project.id}
147 148 group by s.id, s.is_closed, c.id")
148 149 end
149 150
150 151 def issues_by_author
151 152 @issues_by_author ||=
152 153 ActiveRecord::Base.connection.select_all("select s.id as status_id,
153 154 s.is_closed as closed,
154 155 a.id as author_id,
155 156 count(i.id) as total
156 157 from
157 158 issues i, issue_statuses s, users a
158 159 where
159 160 i.status_id=s.id
160 161 and i.author_id=a.id
161 162 and i.project_id=#{@project.id}
162 163 group by s.id, s.is_closed, a.id")
163 164 end
164 165 end
@@ -1,63 +1,64
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 Permission < ActiveRecord::Base
19 19 has_and_belongs_to_many :roles
20 20
21 21 validates_presence_of :controller, :action, :description
22 22
23 23 GROUPS = {
24 24 100 => :label_project,
25 25 200 => :label_member_plural,
26 26 300 => :label_version_plural,
27 27 400 => :label_issue_category_plural,
28 600 => :label_query_plural,
28 29 1000 => :label_issue_plural,
29 30 1100 => :label_news_plural,
30 31 1200 => :label_document_plural,
31 32 1300 => :label_attachment_plural,
32 33 }.freeze
33 34
34 35 @@cached_perms_for_public = nil
35 36 @@cached_perms_for_roles = nil
36 37
37 38 def name
38 39 self.controller + "/" + self.action
39 40 end
40 41
41 42 def group_id
42 43 (self.sort / 100)*100
43 44 end
44 45
45 46 def self.allowed_to_public(action)
46 47 @@cached_perms_for_public ||= find(:all, :conditions => ["is_public=?", true]).collect {|p| "#{p.controller}/#{p.action}"}
47 48 @@cached_perms_for_public.include? action
48 49 end
49 50
50 51 def self.allowed_to_role(action, role)
51 52 @@cached_perms_for_roles ||=
52 53 begin
53 54 perms = {}
54 55 find(:all, :include => :roles).each {|p| perms.store "#{p.controller}/#{p.action}", p.roles.collect {|r| r.id } }
55 56 perms
56 57 end
57 58 @@cached_perms_for_roles[action] and @@cached_perms_for_roles[action].include? role
58 59 end
59 60
60 61 def self.allowed_to_role_expired
61 62 @@cached_perms_for_roles = nil
62 63 end
63 64 end
@@ -1,57 +1,58
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 Project < ActiveRecord::Base
19 19 has_many :versions, :dependent => true, :order => "versions.effective_date DESC, versions.name DESC"
20 20 has_many :members, :dependent => true
21 21 has_many :users, :through => :members
22 22 has_many :custom_values, :dependent => true, :as => :customized
23 23 has_many :issues, :dependent => true, :order => "issues.created_on DESC", :include => :status
24 has_many :queries, :dependent => true
24 25 has_many :documents, :dependent => true
25 26 has_many :news, :dependent => true, :include => :author
26 27 has_many :issue_categories, :dependent => true, :order => "issue_categories.name"
27 28 has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => 'custom_fields_projects', :association_foreign_key => 'custom_field_id'
28 29 acts_as_tree :order => "name", :counter_cache => true
29 30
30 31 validates_presence_of :name, :description
31 32 validates_uniqueness_of :name
32 33 validates_associated :custom_values, :on => :update
33 34
34 35 # returns 5 last created projects
35 36 def self.latest
36 37 find(:all, :limit => 5, :order => "created_on DESC")
37 38 end
38 39
39 40 # Returns an array of all custom fields enabled for project issues
40 41 # (explictly associated custom fields and custom fields enabled for all projects)
41 42 def custom_fields_for_issues(tracker)
42 43 tracker.custom_fields.find(:all, :include => :projects,
43 44 :conditions => ["is_for_all=? or project_id=?", true, self.id])
44 45 #(CustomField.for_all + custom_fields).uniq
45 46 end
46 47
47 48 def all_custom_fields
48 49 @all_custom_fields ||= IssueCustomField.find(:all, :include => :projects,
49 50 :conditions => ["is_for_all=? or project_id=?", true, self.id])
50 51 end
51 52
52 53 protected
53 54 def validate
54 55 errors.add(parent_id, " must be a root project") if parent and parent.parent
55 56 errors.add_to_base("A project with subprojects can't be a subproject") if parent and projects_count > 0
56 57 end
57 58 end
@@ -1,75 +1,87
1 <div class="contextual">
2 <%= l(:label_export_to) %>
3 <%= link_to 'CSV', {:action => 'export_issues_csv', :id => @project}, :class => 'pic picCsv' %>,
4 <%= link_to 'PDF', {:action => 'export_issues_pdf', :id => @project}, :class => 'pic picPdf' %>
5 </div>
6
1 <% if @query.new_record? %>
7 2 <h2><%=l(:label_issue_plural)%></h2>
8 3
9 <%= start_form_tag :action => 'list_issues' %>
10 <table cellpadding=2>
11 <tr>
12 <td valign="bottom"><small><%=l(:field_status)%>:</small><br /><%= search_filter_tag 'status_id', :class => 'select-small' %></td>
13 <td valign="bottom"><small><%=l(:field_tracker)%>:</small><br /><%= search_filter_tag 'tracker_id', :class => 'select-small' %></td>
14 <td valign="bottom"><small><%=l(:field_priority)%>:</small><br /><%= search_filter_tag 'priority_id', :class => 'select-small' %></td>
15 <td valign="bottom"><small><%=l(:field_category)%>:</small><br /><%= search_filter_tag 'category_id', :class => 'select-small' %></td>
16 <td valign="bottom"><small><%=l(:field_fixed_version)%>:</small><br /><%= search_filter_tag 'fixed_version_id', :class => 'select-small' %></td>
17 <td valign="bottom"><small><%=l(:field_author)%>:</small><br /><%= search_filter_tag 'author_id', :class => 'select-small' %></td>
18 <td valign="bottom"><small><%=l(:field_assigned_to)%>:</small><br /><%= search_filter_tag 'assigned_to_id', :class => 'select-small' %></td>
19 <td valign="bottom"><small><%=l(:label_subproject_plural)%>:</small><br /><%= search_filter_tag 'subproject_id', :class => 'select-small' %></td>
20 <td valign="bottom">
21 <%= hidden_field_tag 'set_filter', 1 %>
22 <%= submit_tag l(:button_apply), :class => 'button-small' %>
23 </td>
24 <td valign="bottom">
25 <%= link_to l(:button_clear), :action => 'list_issues', :id => @project, :set_filter => 1 %>
26 </td>
27 </tr>
28 </table>
4 <%= start_form_tag({:action => 'list_issues'}, :id => 'query_form') %>
5 <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
29 6 <%= end_form_tag %>
7 <div class="contextual">
8 <%= link_to_remote l(:button_apply),
9 { :url => { :controller => 'projects', :action => 'list_issues', :id => @project, :set_filter => 1 },
10 :update => "content",
11 :with => "Form.serialize('query_form')"
12 }, :class => 'pic picCheck' %>
30 13
14 <%= link_to l(:button_clear), {:controller => 'projects', :action => 'list_issues', :id => @project, :set_filter => 1}, :class => 'pic picDelete' %>
15 <% if authorize_for('projects', 'add_query') %>
16
17 <%= link_to_remote l(:button_save),
18 { :url => { :controller => 'projects', :action => "add_query", :id => @project },
19 :method => 'get',
20 :update => "content",
21 :with => "Form.serialize('query_form')"
22 }, :class => 'pic picEdit' %>
23 <% end %>
24 </div>
25 <br />
26 <% else %>
27 <% if authorize_for('projects', 'add_query') %>
28 <div class="contextual">
29 <%= link_to l(:button_edit), {:controller => 'queries', :action => 'edit', :id => @query}, :class => 'pic picEdit' %>
30 <%= link_to l(:button_delete), {:controller => 'queries', :action => 'destroy', :id => @query}, :confirm => l(:text_are_you_sure), :post => true, :class => 'pic picDelete' %>
31 </div>
32 <% end %>
33 <h2><%= @query.name %></h2>
34 <% end %>
35 <%= error_messages_for 'query' %>
36 <% if @query.valid? %>
31 37 &nbsp;
32 38 <table class="listTableContent">
33 39 <tr>
34 40 <td colspan="6" align="left"><small><%= check_all_links 'issues_form' %></small></td>
35 41 <td colspan="2" align="right">
36 42 <small><%= l(:label_per_page) %>:</small>
37 43 <%= start_form_tag %>
38 44 <%= select_tag 'per_page', options_for_select(@results_per_page_options, @results_per_page), :class => 'select-small'%>
39 45 <%= submit_tag l(:button_apply), :class => 'button-small'%>
40 46 <%= end_form_tag %>
41 47 </td>
42 48 </tr>
43 49 </table>
44 50 <%= start_form_tag({:controller => 'projects', :action => 'move_issues', :id => @project}, :id => 'issues_form' ) %>
45 51 <table class="listTableContent">
46 52
47 53 <tr class="ListHead">
48 54 <td></td>
49 55 <%= sort_header_tag('issues.id', :caption => '#') %>
50 56 <%= sort_header_tag('issue_statuses.name', :caption => l(:field_status)) %>
51 57 <%= sort_header_tag('issues.tracker_id', :caption => l(:field_tracker)) %>
52 58 <th><%=l(:field_subject)%></th>
53 59 <%= sort_header_tag('users.lastname', :caption => l(:field_author)) %>
54 60 <%= sort_header_tag('issues.created_on', :caption => l(:field_created_on)) %>
55 61 <%= sort_header_tag('issues.updated_on', :caption => l(:field_updated_on)) %>
56 62 </tr>
57 63 <% for issue in @issues %>
58 64 <tr class="<%= cycle("odd", "even") %>">
59 65 <td width="15"><%= check_box_tag "issue_ids[]", issue.id %></td>
60 66 <td align="center"><%= link_to issue.long_id, :controller => 'issues', :action => 'show', :id => issue %></td>
61 67 <td align="center" style="font-weight:bold;color:#<%= issue.status.html_color %>;"><%= issue.status.name %></font></td>
62 68 <td align="center"><%= issue.tracker.name %></td>
63 69 <td><%= link_to issue.subject, :controller => 'issues', :action => 'show', :id => issue %></td>
64 70 <td align="center"><%= issue.author.display_name %></td>
65 71 <td align="center"><%= format_time(issue.created_on) %></td>
66 72 <td align="center"><%= format_time(issue.updated_on) %></td>
67 73 </tr>
68 74 <% end %>
69 75 </table>
76 <div class="contextual">
77 <%= l(:label_export_to) %>
78 <%= link_to 'CSV', {:action => 'export_issues_csv', :id => @project}, :class => 'pic picCsv' %>,
79 <%= link_to 'PDF', {:action => 'export_issues_pdf', :id => @project}, :class => 'pic picPdf' %>
80 </div>
70 81 <p>
71 82 <%= pagination_links_full @issue_pages %>
72 83 [ <%= @issue_pages.current.first_item %> - <%= @issue_pages.current.last_item %> / <%= @issue_count %> ]
73 84 </p>
74 85 <%= submit_tag l(:button_move) %>
75 86 <%= end_form_tag %>
87 <% end %> No newline at end of file
@@ -1,47 +1,47
1 1 <% if @statuses.empty? or rows.empty? %>
2 2 <p><i><%=l(:label_no_data)%></i></p>
3 3 <% else %>
4 4 <% col_width = 70 / (@statuses.length+3) %>
5 5 <table class="reportTableContent">
6 6 <tr>
7 7 <td width="25%"></td>
8 8 <% for status in @statuses %>
9 9 <td align="center" width="<%= col_width %>%" bgcolor="#<%= status.html_color %>"><small><%= status.name %></small></td>
10 10 <% end %>
11 11 <td align="center" width="<%= col_width %>%"><strong><%=l(:label_open_issues_plural)%></strong></td>
12 12 <td align="center" width="<%= col_width %>%"><strong><%=l(:label_closed_issues_plural)%></strong></td>
13 13 <td align="center" width="<%= col_width %>%"><strong><%=l(:label_total)%></strong></td>
14 14 </tr>
15 15
16 16 <% for row in rows %>
17 17 <tr class="<%= cycle("odd", "even") %>">
18 18 <td><%= link_to row.name, :controller => 'projects', :action => 'list_issues', :id => @project,
19 19 :set_filter => 1,
20 20 "#{field_name}" => row.id %></td>
21 21 <% for status in @statuses %>
22 22 <td align="center"><%= link_to (aggregate data, { field_name => row.id, "status_id" => status.id }),
23 23 :controller => 'projects', :action => 'list_issues', :id => @project,
24 24 :set_filter => 1,
25 25 "status_id" => status.id,
26 26 "#{field_name}" => row.id %></td>
27 27 <% end %>
28 28 <td align="center"><%= link_to (aggregate data, { field_name => row.id, "closed" => 0 }),
29 29 :controller => 'projects', :action => 'list_issues', :id => @project,
30 30 :set_filter => 1,
31 31 "#{field_name}" => row.id,
32 "status_id" => "O" %></td>
32 "status_id" => "o" %></td>
33 33 <td align="center"><%= link_to (aggregate data, { field_name => row.id, "closed" => 1 }),
34 34 :controller => 'projects', :action => 'list_issues', :id => @project,
35 35 :set_filter => 1,
36 36 "#{field_name}" => row.id,
37 "status_id" => "C" %></td>
37 "status_id" => "c" %></td>
38 38 <td align="center"><%= link_to (aggregate data, { field_name => row.id }),
39 39 :controller => 'projects', :action => 'list_issues', :id => @project,
40 40 :set_filter => 1,
41 41 "#{field_name}" => row.id,
42 "status_id" => "A" %></td>
42 "status_id" => "*" %></td>
43 43 <% end %>
44 44 </tr>
45 45 </table>
46 46 <% end
47 47 reset_cycle %> No newline at end of file
@@ -1,36 +1,36
1 1 <% if @statuses.empty? or rows.empty? %>
2 2 <p><i><%=l(:label_no_data)%></i></p>
3 3 <% else %>
4 4 <table class="reportTableContent">
5 5 <tr>
6 6 <td width="25%"></td>
7 7 <td align="center" width="25%"><%=l(:label_open_issues_plural)%></td>
8 8 <td align="center" width="25%"><%=l(:label_closed_issues_plural)%></td>
9 9 <td align="center" width="25%"><%=l(:label_total)%></td>
10 10 </tr>
11 11
12 12 <% for row in rows %>
13 13 <tr class="<%= cycle("odd", "even") %>">
14 14 <td><%= link_to row.name, :controller => 'projects', :action => 'list_issues', :id => @project,
15 15 :set_filter => 1,
16 16 "#{field_name}" => row.id %></td>
17 17 <td align="center"><%= link_to (aggregate data, { field_name => row.id, "closed" => 0 }),
18 18 :controller => 'projects', :action => 'list_issues', :id => @project,
19 19 :set_filter => 1,
20 20 "#{field_name}" => row.id,
21 "status_id" => "O" %></td>
21 "status_id" => "o" %></td>
22 22 <td align="center"><%= link_to (aggregate data, { field_name => row.id, "closed" => 1 }),
23 23 :controller => 'projects', :action => 'list_issues', :id => @project,
24 24 :set_filter => 1,
25 25 "#{field_name}" => row.id,
26 "status_id" => "C" %></td>
26 "status_id" => "c" %></td>
27 27 <td align="center"><%= link_to (aggregate data, { field_name => row.id }),
28 28 :controller => 'projects', :action => 'list_issues', :id => @project,
29 29 :set_filter => 1,
30 30 "#{field_name}" => row.id,
31 "status_id" => "A" %></td>
31 "status_id" => "*" %></td>
32 32 <% end %>
33 33 </tr>
34 34 </table>
35 35 <% end
36 36 reset_cycle %> No newline at end of file
@@ -1,20 +1,32
1 1 <h2><%=l(:label_report_plural)%></h2>
2 2
3 <h3><%= l(:label_query_plural) %></h3>
4 <div class="contextual">
5 <%= link_to_if_authorized l(:label_query_new), {:controller => 'projects', :action => 'add_query', :id => @project}, :class => 'pic picAdd' %>
6 </div>
7
8 <% if @queries.empty? %><p><i><%=l(:label_no_data)%></i></p><% end %>
9 <ul>
10 <% @queries.each do |query| %>
11 <li><%= link_to query.name, :controller => 'projects', :action => 'list_issues', :id => @project, :query_id => query %></li>
12 <% end %>
13 </ul>
14
3 15 <div class="splitcontentleft">
4 <h3><%=l(:field_tracker)%>&nbsp;&nbsp;<%= link_to image_tag('details'), :detail => 'author' %></h3>
16 <h3><%=l(:field_tracker)%>&nbsp;&nbsp;<%= link_to image_tag('details'), :detail => 'tracker' %></h3>
5 17 <%= render :partial => 'simple', :locals => { :data => @issues_by_tracker, :field_name => "tracker_id", :rows => @trackers } %>
6 18 <br />
7 <h3><%=l(:field_priority)%>&nbsp;&nbsp;<%= link_to image_tag('details'), :detail => 'priority' %></h3>
8 <%= render :partial => 'simple', :locals => { :data => @issues_by_priority, :field_name => "priority_id", :rows => @priorities } %>
9 <br />
10 19 <h3><%=l(:field_author)%>&nbsp;&nbsp;<%= link_to image_tag('details'), :detail => 'author' %></h3>
11 20 <%= render :partial => 'simple', :locals => { :data => @issues_by_author, :field_name => "author_id", :rows => @authors } %>
12 21 <br />
13 22 </div>
14 23
15 24 <div class="splitcontentright">
25 <h3><%=l(:field_priority)%>&nbsp;&nbsp;<%= link_to image_tag('details'), :detail => 'priority' %></h3>
26 <%= render :partial => 'simple', :locals => { :data => @issues_by_priority, :field_name => "priority_id", :rows => @priorities } %>
27 <br />
16 28 <h3><%=l(:field_category)%>&nbsp;&nbsp;<%= link_to image_tag('details'), :detail => 'category' %></h3>
17 29 <%= render :partial => 'simple', :locals => { :data => @issues_by_category, :field_name => "category_id", :rows => @categories } %>
18 30 <br />
19 31 </div>
20 32
@@ -1,326 +1,343
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 field_hide_mail: Mein email address verstecken
138 138 field_comment: Anmerkung
139 139
140 140 label_user: Benutzer
141 141 label_user_plural: Benutzer
142 142 label_user_new: Neuer Benutzer
143 143 label_project: Projekt
144 144 label_project_new: Neues Projekt
145 145 label_project_plural: Projekte
146 146 label_project_latest: Neueste Projekte
147 147 label_issue: Antrag
148 148 label_issue_new: Neue Antrag
149 149 label_issue_plural: Anträge
150 150 label_issue_view_all: Alle Anträge ansehen
151 151 label_document: Dokument
152 152 label_document_new: Neues Dokument
153 153 label_document_plural: Dokumente
154 154 label_role: Rolle
155 155 label_role_plural: Rollen
156 156 label_role_new: Neue Rolle
157 157 label_role_and_permissions: Rollen und Rechte
158 158 label_member: Mitglied
159 159 label_member_new: Neues Mitglied
160 160 label_member_plural: Mitglieder
161 161 label_tracker: Tracker
162 162 label_tracker_plural: Tracker
163 163 label_tracker_new: Neuer Tracker
164 164 label_workflow: Workflow
165 165 label_issue_status: Antrag Status
166 166 label_issue_status_plural: Antrag Stati
167 167 label_issue_status_new: Neuer Status
168 168 label_issue_category: Antrag Kategorie
169 169 label_issue_category_plural: Antrag Kategorien
170 170 label_issue_category_new: Neue Kategorie
171 171 label_custom_field: Benutzerdefiniertes Feld
172 172 label_custom_field_plural: Benutzerdefinierte Felder
173 173 label_custom_field_new: Neues Feld
174 174 label_enumerations: Enumerationen
175 175 label_enumeration_new: Neuer Wert
176 176 label_information: Information
177 177 label_information_plural: Informationen
178 178 label_please_login: Anmelden
179 179 label_register: Anmelden
180 180 label_password_lost: Passwort vergessen
181 181 label_home: Hauptseite
182 182 label_my_page: Meine Seite
183 183 label_my_account: Mein Konto
184 184 label_my_projects: Meine Projekte
185 185 label_administration: Administration
186 186 label_login: Einloggen
187 187 label_logout: Abmelden
188 188 label_help: Hilfe
189 189 label_reported_issues: Gemeldete Issues
190 190 label_assigned_to_me_issues: Mir zugewiesen
191 191 label_last_login: Letzte Anmeldung
192 192 label_last_updates: Letztes aktualisiertes
193 193 label_last_updates_plural: %d Letztes aktualisiertes
194 194 label_registered_on: Angemeldet am
195 195 label_activity: Aktivität
196 196 label_new: Neue
197 197 label_logged_as: Angemeldet als
198 198 label_environment: Environment
199 199 label_authentication: Authentisierung
200 200 label_auth_source: Authentisierung Modus
201 201 label_auth_source_new: Neuer Authentisierung Modus
202 202 label_auth_source_plural: Authentisierung Modi
203 203 label_subproject: Vorprojekt von
204 204 label_subproject_plural: Vorprojekte
205 205 label_min_max_length: Min - Max Länge
206 206 label_list: Liste
207 207 label_date: Date
208 208 label_integer: Zahl
209 209 label_boolean: Boolesch
210 210 label_string: Text
211 211 label_text: Langer Text
212 212 label_attribute: Attribut
213 213 label_attribute_plural: Attribute
214 214 label_download: %d Herunterlade
215 215 label_download_plural: %d Herunterlade
216 216 label_no_data: Nichts anzuzeigen
217 217 label_change_status: Statuswechsel
218 218 label_history: Historie
219 219 label_attachment: Datei
220 220 label_attachment_new: Neue Datei
221 221 label_attachment_delete: Löschungakten
222 222 label_attachment_plural: Dateien
223 223 label_report: Bericht
224 224 label_report_plural: Berichte
225 225 label_news: Neuigkeit
226 226 label_news_new: Neuigkeite addieren
227 227 label_news_plural: Neuigkeiten
228 228 label_news_latest: Letzte Neuigkeiten
229 229 label_news_view_all: Alle Neuigkeiten anzeigen
230 230 label_change_log: Change log
231 231 label_settings: Konfiguration
232 232 label_overview: Übersicht
233 233 label_version: Version
234 234 label_version_new: Neue Version
235 235 label_version_plural: Versionen
236 236 label_confirmation: Bestätigung
237 237 label_export_to: Export zu
238 238 label_read: Lesen...
239 239 label_public_projects: Öffentliche Projekte
240 240 label_open_issues: Geöffnet
241 241 label_open_issues_plural: Geöffnet
242 242 label_closed_issues: Geschlossen
243 243 label_closed_issues_plural: Geschlossen
244 244 label_total: Gesamtzahl
245 245 label_permissions: Berechtigungen
246 246 label_current_status: Gegenwärtiger Status
247 247 label_new_statuses_allowed: Neue Status gewährten
248 248 label_all: Alle
249 249 label_none: Kein
250 250 label_next: Weiter
251 251 label_previous: Zurück
252 252 label_used_by: Benutzt von
253 253 label_details: Details...
254 254 label_add_note: Eine Anmerkung addieren
255 255 label_per_page: Pro Seite
256 256 label_calendar: Kalender
257 257 label_months_from: Monate von
258 258 label_gantt: Gantt
259 259 label_internal: Intern
260 260 label_last_changes: %d änderungen des Letzten
261 261 label_change_view_all: Alle änderungen ansehen
262 262 label_personalize_page: Diese Seite personifizieren
263 263 label_comment: Anmerkung
264 264 label_comment_plural: Anmerkungen
265 265 label_comment_add: Anmerkung addieren
266 266 label_comment_added: Anmerkung fügte hinzu
267 267 label_comment_delete: Anmerkungen löschen
268 label_query: Benutzerdefiniertes Frage
269 label_query_plural: Benutzerdefinierte Fragen
270 label_query_new: Neue Frage
271 label_filter_add: Filter addieren
272 label_filter_plural: Filter
273 label_equals: ist
274 label_not_equals: ist nicht
275 label_in_less_than: an weniger als
276 label_in_more_than: an mehr als
277 label_in: an
278 label_today: heute
279 label_less_than_ago: vor weniger als
280 label_more_than_ago: vor mehr als
281 label_ago: vor
282 label_contains: enthält
283 label_not_contains: enthält nicht
284 label_day_plural: Tage
268 285
269 286 button_login: Einloggen
270 287 button_submit: Einreichen
271 288 button_save: Speichern
272 289 button_check_all: Alles auswählen
273 290 button_uncheck_all: Alles abwählen
274 291 button_delete: Löschen
275 292 button_create: Anlegen
276 293 button_test: Testen
277 294 button_edit: Bearbeiten
278 295 button_add: Hinzufügen
279 296 button_change: Wechseln
280 297 button_apply: Anwenden
281 298 button_clear: Zurücksetzen
282 299 button_lock: Verriegeln
283 300 button_unlock: Entriegeln
284 301 button_download: Fernzuladen
285 302 button_list: Aufzulisten
286 303 button_view: Siehe
287 304 button_move: Bewegen
288 305 button_back: Rückkehr
289 306 button_cancel: Annullieren
290 307
291 308 text_select_mail_notifications: Aktionen für die Mailbenachrichtigung aktiviert werden soll.
292 309 text_regexp_info: eg. ^[A-Z0-9]+$
293 310 text_min_max_length_info: 0 heisst keine Beschränkung
294 311 text_possible_values_info: Werte trennten sich mit |
295 312 text_project_destroy_confirmation: Sind sie sicher, daß sie das Projekt löschen wollen ?
296 313 text_workflow_edit: Auswahl Workflow zum Bearbeiten
297 314 text_are_you_sure: Sind sie sicher ?
298 315 text_journal_changed: geändert von %s zu %s
299 316 text_journal_set_to: gestellt zu %s
300 317 text_journal_deleted: gelöscht
301 318 text_tip_task_begin_day: Aufgabe, die an diesem Tag beginnt
302 319 text_tip_task_end_day: Aufgabe, die an diesem Tag beendet
303 320 text_tip_task_begin_end_day: Aufgabe, die an diesem Tag beginnt und beendet
304 321
305 322 default_role_manager: Manager
306 323 default_role_developper: Developer
307 324 default_role_reporter: Reporter
308 325 default_tracker_bug: Fehler
309 326 default_tracker_feature: Feature
310 327 default_tracker_support: Support
311 328 default_issue_status_new: Neu
312 329 default_issue_status_assigned: Zugewiesen
313 330 default_issue_status_resolved: Gelöst
314 331 default_issue_status_feedback: Feedback
315 332 default_issue_status_closed: Erledigt
316 333 default_issue_status_rejected: Abgewiesen
317 334 default_doc_category_user: Benutzerdokumentation
318 335 default_doc_category_tech: Technische Dokumentation
319 336 default_priority_low: Niedrig
320 337 default_priority_normal: Normal
321 338 default_priority_high: Hoch
322 339 default_priority_urgent: Dringend
323 340 default_priority_immediate: Sofort
324 341
325 342 enumeration_issue_priorities: Issue-Prioritäten
326 343 enumeration_doc_categories: Dokumentenkategorien
@@ -1,326 +1,343
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 field_hide_mail: Hide my email address
138 138 field_comment: Comment
139 139
140 140 label_user: User
141 141 label_user_plural: Users
142 142 label_user_new: New user
143 143 label_project: Project
144 144 label_project_new: New project
145 145 label_project_plural: Projects
146 146 label_project_latest: Latest projects
147 147 label_issue: Issue
148 148 label_issue_new: New issue
149 149 label_issue_plural: Issues
150 150 label_issue_view_all: View all issues
151 151 label_document: Document
152 152 label_document_new: New document
153 153 label_document_plural: Documents
154 154 label_role: Role
155 155 label_role_plural: Roles
156 156 label_role_new: New role
157 157 label_role_and_permissions: Roles and permissions
158 158 label_member: Member
159 159 label_member_new: New member
160 160 label_member_plural: Members
161 161 label_tracker: Tracker
162 162 label_tracker_plural: Trackers
163 163 label_tracker_new: New tracker
164 164 label_workflow: Workflow
165 165 label_issue_status: Issue status
166 166 label_issue_status_plural: Issue statuses
167 167 label_issue_status_new: New status
168 168 label_issue_category: Issue category
169 169 label_issue_category_plural: Issue categories
170 170 label_issue_category_new: New category
171 171 label_custom_field: Custom field
172 172 label_custom_field_plural: Custom fields
173 173 label_custom_field_new: New custom field
174 174 label_enumerations: Enumerations
175 175 label_enumeration_new: New value
176 176 label_information: Information
177 177 label_information_plural: Information
178 178 label_please_login: Please login
179 179 label_register: Register
180 180 label_password_lost: Lost password
181 181 label_home: Home
182 182 label_my_page: My page
183 183 label_my_account: My account
184 184 label_my_projects: My projects
185 185 label_administration: Administration
186 186 label_login: Login
187 187 label_logout: Logout
188 188 label_help: Help
189 189 label_reported_issues: Reported issues
190 190 label_assigned_to_me_issues: Issues assigned to me
191 191 label_last_login: Last connection
192 192 label_last_updates: Last updated
193 193 label_last_updates_plural: %d last updated
194 194 label_registered_on: Registered on
195 195 label_activity: Activity
196 196 label_new: New
197 197 label_logged_as: Logged as
198 198 label_environment: Environment
199 199 label_authentication: Authentication
200 200 label_auth_source: Authentication mode
201 201 label_auth_source_new: New authentication mode
202 202 label_auth_source_plural: Authentication modes
203 203 label_subproject: Subproject
204 204 label_subproject_plural: Subprojects
205 205 label_min_max_length: Min - Max length
206 206 label_list: List
207 207 label_date: Date
208 208 label_integer: Integer
209 209 label_boolean: Boolean
210 210 label_string: Text
211 211 label_text: Long text
212 212 label_attribute: Attribute
213 213 label_attribute_plural: Attributes
214 214 label_download: %d Download
215 215 label_download_plural: %d Downloads
216 216 label_no_data: No data to display
217 217 label_change_status: Change status
218 218 label_history: History
219 219 label_attachment: File
220 220 label_attachment_new: New file
221 221 label_attachment_delete: Delete file
222 222 label_attachment_plural: Files
223 223 label_report: Report
224 224 label_report_plural: Reports
225 225 label_news: News
226 226 label_news_new: Add news
227 227 label_news_plural: News
228 228 label_news_latest: Latest news
229 229 label_news_view_all: View all news
230 230 label_change_log: Change log
231 231 label_settings: Settings
232 232 label_overview: Overview
233 233 label_version: Version
234 234 label_version_new: New version
235 235 label_version_plural: Versions
236 236 label_confirmation: Confirmation
237 237 label_export_to: Export to
238 238 label_read: Read...
239 239 label_public_projects: Public projects
240 240 label_open_issues: Open
241 241 label_open_issues_plural: Open
242 242 label_closed_issues: Closed
243 243 label_closed_issues_plural: Closed
244 244 label_total: Total
245 245 label_permissions: Permissions
246 246 label_current_status: Current status
247 247 label_new_statuses_allowed: New statuses allowed
248 248 label_all: All
249 249 label_none: None
250 250 label_next: Next
251 251 label_previous: Previous
252 252 label_used_by: Used by
253 253 label_details: Details...
254 254 label_add_note: Add a note
255 255 label_per_page: Per page
256 256 label_calendar: Calendar
257 257 label_months_from: months from
258 258 label_gantt: Gantt
259 259 label_internal: Internal
260 260 label_last_changes: last %d changes
261 261 label_change_view_all: View all changes
262 262 label_personalize_page: Personalize this page
263 263 label_comment: Comment
264 264 label_comment_plural: Comments
265 265 label_comment_add: Add a comment
266 266 label_comment_added: Comment added
267 267 label_comment_delete: Delete comments
268 label_query: Custom query
269 label_query_plural: Custom queries
270 label_query_new: New query
271 label_filter_add: Add filter
272 label_filter_plural: Filters
273 label_equals: is
274 label_not_equals: is not
275 label_in_less_than: in less than
276 label_in_more_than: in more than
277 label_in: in
278 label_today: today
279 label_less_than_ago: less than days ago
280 label_more_than_ago: more than days ago
281 label_ago: days ago
282 label_contains: contains
283 label_not_contains: doesn't contain
284 label_day_plural: days
268 285
269 286 button_login: Login
270 287 button_submit: Submit
271 288 button_save: Save
272 289 button_check_all: Check all
273 290 button_uncheck_all: Uncheck all
274 291 button_delete: Delete
275 292 button_create: Create
276 293 button_test: Test
277 294 button_edit: Edit
278 295 button_add: Add
279 296 button_change: Change
280 297 button_apply: Apply
281 298 button_clear: Clear
282 299 button_lock: Lock
283 300 button_unlock: Unlock
284 301 button_download: Download
285 302 button_list: List
286 303 button_view: View
287 304 button_move: Move
288 305 button_back: Back
289 306 button_cancel: Cancel
290 307
291 308 text_select_mail_notifications: Select actions for which mail notifications should be sent.
292 309 text_regexp_info: eg. ^[A-Z0-9]+$
293 310 text_min_max_length_info: 0 means no restriction
294 311 text_possible_values_info: values separated with |
295 312 text_project_destroy_confirmation: Are you sure you want to delete this project and all related data ?
296 313 text_workflow_edit: Select a role and a tracker to edit the workflow
297 314 text_are_you_sure: Are you sure ?
298 315 text_journal_changed: changed from %s to %s
299 316 text_journal_set_to: set to %s
300 317 text_journal_deleted: deleted
301 318 text_tip_task_begin_day: task beginning this day
302 319 text_tip_task_end_day: task ending this day
303 320 text_tip_task_begin_end_day: task beginning and ending this day
304 321
305 322 default_role_manager: Manager
306 323 default_role_developper: Developer
307 324 default_role_reporter: Reporter
308 325 default_tracker_bug: Bug
309 326 default_tracker_feature: Feature
310 327 default_tracker_support: Support
311 328 default_issue_status_new: New
312 329 default_issue_status_assigned: Assigned
313 330 default_issue_status_resolved: Resolved
314 331 default_issue_status_feedback: Feedback
315 332 default_issue_status_closed: Closed
316 333 default_issue_status_rejected: Rejected
317 334 default_doc_category_user: User documentation
318 335 default_doc_category_tech: Technical documentation
319 336 default_priority_low: Low
320 337 default_priority_normal: Normal
321 338 default_priority_high: High
322 339 default_priority_urgent: Urgent
323 340 default_priority_immediate: Immediate
324 341
325 342 enumeration_issue_priorities: Issue priorities
326 343 enumeration_doc_categories: Document categories
@@ -1,326 +1,343
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 field_hide_mail: Ocultar mi email address
138 138 field_comment: Comentario
139 139
140 140 label_user: Usuario
141 141 label_user_plural: Usuarios
142 142 label_user_new: Nuevo usuario
143 143 label_project: Proyecto
144 144 label_project_new: Nuevo proyecto
145 145 label_project_plural: Proyectos
146 146 label_project_latest: Los proyectos más últimos
147 147 label_issue: Petición
148 148 label_issue_new: Nueva petición
149 149 label_issue_plural: Peticiones
150 150 label_issue_view_all: Ver todas las peticiones
151 151 label_document: Documento
152 152 label_document_new: Nuevo documento
153 153 label_document_plural: Documentos
154 154 label_role: Papel
155 155 label_role_plural: Papeles
156 156 label_role_new: Nuevo papel
157 157 label_role_and_permissions: Papeles y permisos
158 158 label_member: Miembro
159 159 label_member_new: Nuevo miembro
160 160 label_member_plural: Miembros
161 161 label_tracker: Tracker
162 162 label_tracker_plural: Trackers
163 163 label_tracker_new: Nuevo tracker
164 164 label_workflow: Workflow
165 165 label_issue_status: Estatuto de petición
166 166 label_issue_status_plural: Estatutos de las peticiones
167 167 label_issue_status_new: Nuevo estatuto
168 168 label_issue_category: Categoría de las peticiones
169 169 label_issue_category_plural: Categorías de las peticiones
170 170 label_issue_category_new: Nueva categoría
171 171 label_custom_field: Campo personalizado
172 172 label_custom_field_plural: Campos personalizados
173 173 label_custom_field_new: Nuevo campo personalizado
174 174 label_enumerations: Listas de valores
175 175 label_enumeration_new: Nuevo valor
176 176 label_information: Informacion
177 177 label_information_plural: Informaciones
178 178 label_please_login: Conexión
179 179 label_register: Registrar
180 180 label_password_lost: ¿Olvidaste la contraseña?
181 181 label_home: Acogida
182 182 label_my_page: Mi página
183 183 label_my_account: Mi cuenta
184 184 label_my_projects: Mis proyectos
185 185 label_administration: Administración
186 186 label_login: Conexión
187 187 label_logout: Desconexión
188 188 label_help: Ayuda
189 189 label_reported_issues: Peticiones registradas
190 190 label_assigned_to_me_issues: Peticiones que me están asignadas
191 191 label_last_login: Última conexión
192 192 label_last_updates: Actualizado
193 193 label_last_updates_plural: %d Actualizados
194 194 label_registered_on: Inscrito el
195 195 label_activity: Actividad
196 196 label_new: Nuevo
197 197 label_logged_as: Conectado como
198 198 label_environment: Environment
199 199 label_authentication: Autentificación
200 200 label_auth_source: Modo de la autentificación
201 201 label_auth_source_new: Nuevo modo de la autentificación
202 202 label_auth_source_plural: Modos de la autentificación
203 203 label_subproject: Proyecto secundario
204 204 label_subproject_plural: Proyectos secundarios
205 205 label_min_max_length: Longitud mín - máx
206 206 label_list: Lista
207 207 label_date: Fecha
208 208 label_integer: Número
209 209 label_boolean: Boleano
210 210 label_string: Texto
211 211 label_text: Texto largo
212 212 label_attribute: Cualidad
213 213 label_attribute_plural: Cualidades
214 214 label_download: %d Telecarga
215 215 label_download_plural: %d Telecargas
216 216 label_no_data: Ningunos datos a exhibir
217 217 label_change_status: Cambiar el estatuto
218 218 label_history: Histórico
219 219 label_attachment: Fichero
220 220 label_attachment_new: Nuevo fichero
221 221 label_attachment_delete: Suprimir el fichero
222 222 label_attachment_plural: Ficheros
223 223 label_report: Informe
224 224 label_report_plural: Informes
225 225 label_news: Noticia
226 226 label_news_new: Nueva noticia
227 227 label_news_plural: Noticias
228 228 label_news_latest: Últimas noticias
229 229 label_news_view_all: Ver todas las noticias
230 230 label_change_log: Cambios
231 231 label_settings: Configuración
232 232 label_overview: Vistazo
233 233 label_version: Versión
234 234 label_version_new: Nueva versión
235 235 label_version_plural: Versiónes
236 236 label_confirmation: Confirmación
237 237 label_export_to: Exportar a
238 238 label_read: Leer...
239 239 label_public_projects: Proyectos publicos
240 240 label_open_issues: Abierta
241 241 label_open_issues_plural: Abiertas
242 242 label_closed_issues: Cerrada
243 243 label_closed_issues_plural: Cerradas
244 244 label_total: Total
245 245 label_permissions: Permisos
246 246 label_current_status: Estado actual
247 247 label_new_statuses_allowed: Nuevos estatutos autorizados
248 248 label_all: Todos
249 249 label_none: Ninguno
250 250 label_next: Próximo
251 251 label_previous: Precedente
252 252 label_used_by: Utilizado por
253 253 label_details: Detalles...
254 254 label_add_note: Agregar una nota
255 255 label_per_page: Por la página
256 256 label_calendar: Calendario
257 257 label_months_from: meses de
258 258 label_gantt: Gantt
259 259 label_internal: Interno
260 260 label_last_changes: %d cambios del último
261 261 label_change_view_all: Ver todos los cambios
262 262 label_personalize_page: Personalizar esta página
263 263 label_comment: Comentario
264 264 label_comment_plural: Comentarios
265 265 label_comment_add: Agregar un comentario
266 266 label_comment_added: Comentario agregó
267 267 label_comment_delete: Suprimir comentarios
268 label_query: Pregunta personalizada
269 label_query_plural: Preguntas personalizadas
270 label_query_new: Nueva preguntas
271 label_filter_add: Agregar el filtro
272 label_filter_plural: Filtros
273 label_equals: igual
274 label_not_equals: no igual
275 label_in_less_than: en menos que
276 label_in_more_than: en más que
277 label_in: en
278 label_today: hoy
279 label_less_than_ago: hace menos de
280 label_more_than_ago: hace más de
281 label_ago: hace
282 label_contains: contiene
283 label_not_contains: no contiene
284 label_day_plural: días
268 285
269 286 button_login: Conexión
270 287 button_submit: Someter
271 288 button_save: Validar
272 289 button_check_all: Seleccionar todo
273 290 button_uncheck_all: No seleccionar nada
274 291 button_delete: Suprimir
275 292 button_create: Crear
276 293 button_test: Testar
277 294 button_edit: Modificar
278 295 button_add: Añadir
279 296 button_change: Cambiar
280 297 button_apply: Aplicar
281 298 button_clear: Anular
282 299 button_lock: Bloquear
283 300 button_unlock: Desbloquear
284 301 button_download: Telecargar
285 302 button_list: Listar
286 303 button_view: Ver
287 304 button_move: Mover
288 305 button_back: Atrás
289 306 button_cancel: Cancelar
290 307
291 308 text_select_mail_notifications: Seleccionar las actividades que necesitan la activación de la notificación por mail.
292 309 text_regexp_info: eg. ^[A-Z0-9]+$
293 310 text_min_max_length_info: 0 para ninguna restricción
294 311 text_possible_values_info: Los valores se separaron con |
295 312 text_project_destroy_confirmation: ¿ Estás seguro de querer eliminar el proyecto ?
296 313 text_workflow_edit: Seleccionar un workflow para actualizar
297 314 text_are_you_sure: ¿ Estás seguro ?
298 315 text_journal_changed: cambiado de %s a %s
299 316 text_journal_set_to: fijado a %s
300 317 text_journal_deleted: suprimido
301 318 text_tip_task_begin_day: tarea que comienza este día
302 319 text_tip_task_end_day: tarea que termina este día
303 320 text_tip_task_begin_end_day: tarea que comienza y termina este día
304 321
305 322 default_role_manager: Manager
306 323 default_role_developper: Desarrollador
307 324 default_role_reporter: Informador
308 325 default_tracker_bug: Anomalía
309 326 default_tracker_feature: Evolución
310 327 default_tracker_support: Asistencia
311 328 default_issue_status_new: Nuevo
312 329 default_issue_status_assigned: Asignada
313 330 default_issue_status_resolved: Resuelta
314 331 default_issue_status_feedback: Comentario
315 332 default_issue_status_closed: Cerrada
316 333 default_issue_status_rejected: Rechazada
317 334 default_doc_category_user: Documentación del usuario
318 335 default_doc_category_tech: Documentación tecnica
319 336 default_priority_low: Bajo
320 337 default_priority_normal: Normal
321 338 default_priority_high: Alto
322 339 default_priority_urgent: Urgente
323 340 default_priority_immediate: Ahora
324 341
325 342 enumeration_issue_priorities: Prioridad de las peticiones
326 343 enumeration_doc_categories: Categorías del documento
@@ -1,327 +1,344
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 field_hide_mail: Cacher mon adresse mail
139 139 field_comment: Commentaire
140 140
141 141 label_user: Utilisateur
142 142 label_user_plural: Utilisateurs
143 143 label_user_new: Nouvel utilisateur
144 144 label_project: Projet
145 145 label_project_new: Nouveau projet
146 146 label_project_plural: Projets
147 147 label_project_latest: Derniers projets
148 148 label_issue: Demande
149 149 label_issue_new: Nouvelle demande
150 150 label_issue_plural: Demandes
151 151 label_issue_view_all: Voir toutes les demandes
152 152 label_document: Document
153 153 label_document_new: Nouveau document
154 154 label_document_plural: Documents
155 155 label_role: Rôle
156 156 label_role_plural: Rôles
157 157 label_role_new: Nouveau rôle
158 158 label_role_and_permissions: Rôles et permissions
159 159 label_member: Membre
160 160 label_member_new: Nouveau membre
161 161 label_member_plural: Membres
162 162 label_tracker: Tracker
163 163 label_tracker_plural: Trackers
164 164 label_tracker_new: Nouveau tracker
165 165 label_workflow: Workflow
166 166 label_issue_status: Statut de demandes
167 167 label_issue_status_plural: Statuts de demandes
168 168 label_issue_status_new: Nouveau statut
169 169 label_issue_category: Catégorie de demandes
170 170 label_issue_category_plural: Catégories de demandes
171 171 label_issue_category_new: Nouvelle catégorie
172 172 label_custom_field: Champ personnalisé
173 173 label_custom_field_plural: Champs personnalisés
174 174 label_custom_field_new: Nouveau champ personnalisé
175 175 label_enumerations: Listes de valeurs
176 176 label_enumeration_new: Nouvelle valeur
177 177 label_information: Information
178 178 label_information_plural: Informations
179 179 label_please_login: Identification
180 180 label_register: S'enregistrer
181 181 label_password_lost: Mot de passe perdu
182 182 label_home: Accueil
183 183 label_my_page: Ma page
184 184 label_my_account: Mon compte
185 185 label_my_projects: Mes projets
186 186 label_administration: Administration
187 187 label_login: Connexion
188 188 label_logout: Déconnexion
189 189 label_help: Aide
190 190 label_reported_issues: Demandes soumises
191 191 label_assigned_to_me_issues: Demandes qui me sont assignées
192 192 label_last_login: Dernière connexion
193 193 label_last_updates: Dernière mise à jour
194 194 label_last_updates_plural: %d dernières mises à jour
195 195 label_registered_on: Inscrit le
196 196 label_activity: Activité
197 197 label_new: Nouveau
198 198 label_logged_as: Connecté en tant que
199 199 label_environment: Environnement
200 200 label_authentication: Authentification
201 201 label_auth_source: Mode d'authentification
202 202 label_auth_source_new: Nouveau mode d'authentification
203 203 label_auth_source_plural: Modes d'authentification
204 204 label_subproject: Sous-projet
205 205 label_subproject_plural: Sous-projets
206 206 label_min_max_length: Longueurs mini - maxi
207 207 label_list: Liste
208 208 label_date: Date
209 209 label_integer: Entier
210 210 label_boolean: Booléen
211 211 label_string: Texte
212 212 label_text: Texte long
213 213 label_attribute: Attribut
214 214 label_attribute_plural: Attributs
215 215 label_download: %d Téléchargement
216 216 label_download_plural: %d Téléchargements
217 217 label_no_data: Aucune donnée à afficher
218 218 label_change_status: Changer le statut
219 219 label_history: Historique
220 220 label_attachment: Fichier
221 221 label_attachment_new: Nouveau fichier
222 222 label_attachment_delete: Supprimer le fichier
223 223 label_attachment_plural: Fichiers
224 224 label_report: Rapport
225 225 label_report_plural: Rapports
226 226 label_news: Annonce
227 227 label_news_new: Nouvelle annonce
228 228 label_news_plural: Annonces
229 229 label_news_latest: Dernières annonces
230 230 label_news_view_all: Voir toutes les annonces
231 231 label_change_log: Historique
232 232 label_settings: Configuration
233 233 label_overview: Aperçu
234 234 label_version: Version
235 235 label_version_new: Nouvelle version
236 236 label_version_plural: Versions
237 237 label_confirmation: Confirmation
238 238 label_export_to: Exporter en
239 239 label_read: Lire...
240 240 label_public_projects: Projets publics
241 label_open_issues: Ouverte
242 label_open_issues_plural: Ouvertes
243 label_closed_issues: Fermée
244 label_closed_issues_plural: Fermées
241 label_open_issues: ouvert
242 label_open_issues_plural: ouverts
243 label_closed_issues: fermé
244 label_closed_issues_plural: fermés
245 245 label_total: Total
246 246 label_permissions: Permissions
247 247 label_current_status: Statut actuel
248 248 label_new_statuses_allowed: Nouveaux statuts autorisés
249 label_all: Tous
250 label_none: Aucun
249 label_all: tous
250 label_none: aucun
251 251 label_next: Suivant
252 252 label_previous: Précédent
253 253 label_used_by: Utilisé par
254 254 label_details: Détails...
255 255 label_add_note: Ajouter une note
256 256 label_per_page: Par page
257 257 label_calendar: Calendrier
258 258 label_months_from: mois depuis
259 259 label_gantt: Gantt
260 260 label_internal: Interne
261 261 label_last_changes: %d derniers changements
262 262 label_change_view_all: Voir tous les changements
263 263 label_personalize_page: Personnaliser cette page
264 264 label_comment: Commentaire
265 265 label_comment_plural: Commentaires
266 266 label_comment_add: Ajouter un commentaire
267 267 label_comment_added: Commentaire ajouté
268 268 label_comment_delete: Supprimer les commentaires
269 label_query: Rapport personnalisé
270 label_query_plural: Rapports personnalisés
271 label_query_new: Nouveau rapport
272 label_filter_add: Ajouter le filtre
273 label_filter_plural: Filtres
274 label_equals: égal
275 label_not_equals: différent
276 label_in_less_than: dans moins de
277 label_in_more_than: dans plus de
278 label_in: dans
279 label_today: aujourd'hui
280 label_less_than_ago: il y a moins de
281 label_more_than_ago: il y a plus de
282 label_ago: il y a
283 label_contains: contient
284 label_not_contains: ne contient pas
285 label_day_plural: jours
269 286
270 287 button_login: Connexion
271 288 button_submit: Soumettre
272 289 button_save: Sauvegarder
273 290 button_check_all: Tout cocher
274 291 button_uncheck_all: Tout décocher
275 292 button_delete: Supprimer
276 293 button_create: Créer
277 294 button_test: Tester
278 295 button_edit: Modifier
279 296 button_add: Ajouter
280 297 button_change: Changer
281 298 button_apply: Appliquer
282 299 button_clear: Effacer
283 300 button_lock: Verrouiller
284 301 button_unlock: Déverrouiller
285 302 button_download: Télécharger
286 303 button_list: Lister
287 304 button_view: Voir
288 305 button_move: Déplacer
289 306 button_back: Retour
290 307 button_cancel: Annuler
291 308
292 309 text_select_mail_notifications: Sélectionner les actions pour lesquelles la notification par mail doit être activée.
293 310 text_regexp_info: ex. ^[A-Z0-9]+$
294 311 text_min_max_length_info: 0 pour aucune restriction
295 312 text_possible_values_info: valeurs séparées par |
296 313 text_project_destroy_confirmation: Etes-vous sûr de vouloir supprimer ce projet et tout ce qui lui est rattaché ?
297 314 text_workflow_edit: Sélectionner un tracker et un rôle pour éditer le workflow
298 315 text_are_you_sure: Etes-vous sûr ?
299 316 text_journal_changed: changé de %s à %s
300 317 text_journal_set_to: mis à %s
301 318 text_journal_deleted: supprimé
302 319 text_tip_task_begin_day: tâche commençant ce jour
303 320 text_tip_task_end_day: tâche finissant ce jour
304 321 text_tip_task_begin_end_day: tâche commençant et finissant ce jour
305 322
306 323 default_role_manager: Manager
307 324 default_role_developper: Développeur
308 325 default_role_reporter: Rapporteur
309 326 default_tracker_bug: Anomalie
310 327 default_tracker_feature: Evolution
311 328 default_tracker_support: Assistance
312 329 default_issue_status_new: Nouveau
313 330 default_issue_status_assigned: Assigné
314 331 default_issue_status_resolved: Résolu
315 332 default_issue_status_feedback: Commentaire
316 333 default_issue_status_closed: Fermé
317 334 default_issue_status_rejected: Rejeté
318 335 default_doc_category_user: Documentation utilisateur
319 336 default_doc_category_tech: Documentation technique
320 337 default_priority_low: Bas
321 338 default_priority_normal: Normal
322 339 default_priority_high: Haut
323 340 default_priority_urgent: Urgent
324 341 default_priority_immediate: Immédiat
325 342
326 343 enumeration_issue_priorities: Priorités des demandes
327 344 enumeration_doc_categories: Catégories des documents
1 NO CONTENT: file renamed from public/images/edit_small.png to public/images/edit.png
@@ -1,505 +1,506
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 .picEdit { background: url(../images/edit_small.png) no-repeat 4px 50%; }
131 .picEdit { background: url(../images/edit.png) no-repeat 4px 50%; }
132 132 .picDelete { background: url(../images/delete.png) no-repeat 4px 50%; }
133 133 .picAdd { background: url(../images/add.png) no-repeat 4px 50%; }
134 134 .picMove { background: url(../images/move.png) no-repeat 4px 50%; }
135 .picCheck { background: url(../images/check.png) no-repeat 4px 70%; }
135 136 .picPdf { background: url(../images/pdf.png) no-repeat 4px 50%;}
136 137 .picCsv { background: url(../images/csv.png) no-repeat 4px 50%;}
137 138
138 139 .pic { padding-left: 18px; margin-left: 3px; }
139 140 /**************** Content styles ****************/
140 141
141 142 html>body #content {
142 143 height: auto;
143 144 min-height: 500px;
144 145 }
145 146
146 147 #content{
147 148 /*float:right;*/
148 149 /*width:530px;*/
149 150 width: auto;
150 151 height:500px;
151 152 font-size:0.9em;
152 153 padding:20px 10px 10px 20px;
153 154 /*position: absolute;*/
154 155 margin-left: 120px;
155 156 border-left: 1px dashed #c0c0c0;
156 157
157 158 }
158 159
159 160 #content h2{
160 161 display:block;
161 162 margin:0 0 16px 0;
162 163 font-size:1.7em;
163 164 font-weight:normal;
164 165 letter-spacing:-1px;
165 166 color:#606060;
166 167 background-color:inherit;
167 168 font-family: Trebuchet MS,Georgia,"Times New Roman",serif;
168 169 }
169 170
170 171 #content h2 a{font-weight:normal;}
171 172 #content h3{margin:0 0 12px 0; font-size:1.4em;color:#707070;font-family: Trebuchet MS,Georgia,"Times New Roman",serif;}
172 173 #content a:hover,#subcontent a:hover{text-decoration:underline;}
173 174 #content ul,#content ol{margin:0 5px 16px 35px;}
174 175 #content dl{margin:0 5px 10px 25px;}
175 176 #content dt{font-weight:bold; margin-bottom:5px;}
176 177 #content dd{margin:0 0 10px 15px;}
177 178
178 179
179 180 /***********************************************/
180 181
181 182 /*
182 183 form{
183 184 padding:15px;
184 185 margin:0 0 20px 0;
185 186 border:1px solid #c0c0c0;
186 187 background-color:#CEE1ED;
187 188 width:600px;
188 189 }
189 190 */
190 191
191 192 form {
192 193 display: inline;
193 194 }
194 195
195 196 .noborder {
196 197 border:0px;
197 198 background-color:#fff;
198 199 width:100%;
199 200 }
200 201
201 202 textarea {
202 203 padding:0;
203 204 margin:0;
204 205 }
205 206
206 207 blockquote {
207 208 padding-left: 6px;
208 209 border-left: 2px solid #ccc;
209 210 }
210 211
211 212 input {
212 213 vertical-align: middle;
213 214 }
214 215
215 216 input.button-small
216 217 {
217 218 font-size: 0.8em;
218 219 }
219 220
220 221 select {
221 222 vertical-align: middle;
222 223 }
223 224
224 select.select-small
225 .select-small
225 226 {
226 227 border: 1px solid #7F9DB9;
227 228 padding: 1px;
228 229 font-size: 0.8em;
229 230 }
230 231
231 232 .active-filter
232 233 {
233 234 background-color: #F9FA9E;
234 235
235 236 }
236 237
237 238 label {
238 239 font-weight: bold;
239 240 font-size: 1em;
240 241 }
241 242
242 243 fieldset {
243 244 border:1px solid #7F9DB9;
244 245 padding: 6px;
245 246 }
246 247
247 248 legend {
248 249 color: #505050;
249 250
250 251 }
251 252
252 253 .required {
253 254 color: #bb0000;
254 255 }
255 256
256 257 table.listTableContent {
257 258 border:1px solid #578bb8;
258 259 width:100%;
259 260 border-collapse: collapse;
260 261 }
261 262
262 263 table.listTableContent td {
263 264 padding:2px;
264 265 }
265 266
266 267 tr.ListHead {
267 268 background-color:#467aa7;
268 269 color:#FFFFFF;
269 270 text-align:center;
270 271 }
271 272
272 273 tr.ListHead a {
273 274 color:#FFFFFF;
274 275 text-decoration:underline;
275 276 }
276 277
277 278 .odd {
278 279 background-color:#f0f1f2;
279 280 }
280 281 .even {
281 282 background-color: #fff;
282 283 }
283 284
284 285 table.reportTableContent {
285 286 border:1px solid #c0c0c0;
286 287 width:99%;
287 288 border-collapse: collapse;
288 289 }
289 290
290 291 table.reportTableContent td {
291 292 padding:2px;
292 293 }
293 294
294 295 table.calenderTable {
295 296 border:1px solid #578bb8;
296 297 width:99%;
297 298 border-collapse: collapse;
298 299 }
299 300
300 301 table.calenderTable td {
301 302 border:1px solid #578bb8;
302 303 }
303 304
304 305 hr { border:none; border-bottom: dotted 1px #c0c0c0; }
305 306
306 307
307 308 /**************** Sidebar styles ****************/
308 309
309 310 #subcontent{
310 311 position: absolute;
311 312 left: 0px;
312 313 width:110px;
313 314 padding:20px 20px 10px 5px;
314 315 }
315 316
316 317 #subcontent h2{
317 318 display:block;
318 319 margin:0 0 5px 0;
319 320 font-size:1.0em;
320 321 font-weight:bold;
321 322 text-align:left;
322 323 color:#606060;
323 324 background-color:inherit;
324 325 font-family: Trebuchet MS,Georgia,"Times New Roman",serif;
325 326 }
326 327
327 328 #subcontent p{margin:0 0 16px 0; font-size:0.9em;}
328 329
329 330 /**************** Menublock styles ****************/
330 331
331 332 .menublock{margin:0 0 20px 8px; font-size:0.8em;}
332 333 .menublock li{list-style:none; display:block; padding:1px; margin-bottom:0px;}
333 334 .menublock li a{font-weight:bold; text-decoration:none;}
334 335 .menublock li a:hover{text-decoration:none;}
335 336 .menublock li ul{margin:0; font-size:1em; font-weight:normal;}
336 337 .menublock li ul li{margin-bottom:0;}
337 338 .menublock li ul a{font-weight:normal;}
338 339
339 340 /**************** Searchbar styles ****************/
340 341
341 342 #searchbar{margin:0 0 20px 0;}
342 343 #searchbar form fieldset{margin-left:10px; border:0 solid;}
343 344
344 345 #searchbar #s{
345 346 height:1.2em;
346 347 width:110px;
347 348 margin:0 5px 0 0;
348 349 border:1px solid #a0a0a0;
349 350 }
350 351
351 352 #searchbar #searchbutton{
352 353 width:auto;
353 354 padding:0 1px;
354 355 border:1px solid #808080;
355 356 font-size:0.9em;
356 357 text-align:center;
357 358 }
358 359
359 360 /**************** Footer styles ****************/
360 361
361 362 #footer{
362 363 clear:both;
363 364 /*width:758px;*/
364 365 padding:5px 0;
365 366 margin:0;
366 367 font-size:0.9em;
367 368 color:#f0f0f0;
368 369 background:#467aa7;
369 370 }
370 371
371 372 #footer p{padding:0; margin:0; text-align:center;}
372 373 #footer a{color:#f0f0f0; background-color:inherit; font-weight:bold;}
373 374 #footer a:hover{color:#ffffff; background-color:inherit; text-decoration: underline;}
374 375
375 376 /**************** Misc classes and styles ****************/
376 377
377 378 .splitcontentleft{float:left; width:49%;}
378 379 .splitcontentright{float:right; width:49%;}
379 380 .clear{clear:both;}
380 381 .small{font-size:0.8em;line-height:1.4em;padding:0 0 0 0;}
381 382 .hide{display:none;}
382 383 .textcenter{text-align:center;}
383 384 .textright{text-align:right;}
384 385 .important{color:#f02025; background-color:inherit; font-weight:bold;}
385 386
386 387 .box{
387 388 margin:0 0 20px 0;
388 389 padding:10px;
389 390 border:1px solid #c0c0c0;
390 391 background-color:#fafbfc;
391 392 color:#505050;
392 393 line-height:1.5em;
393 394 }
394 395
395 396 a.close-icon {
396 397 display:block;
397 398 margin-top:3px;
398 399 overflow:hidden;
399 400 width:12px;
400 401 height:12px;
401 402 background-repeat: no-repeat;
402 403 cursor:hand;
403 404 cursor:pointer;
404 405 background-image:url('../images/close.png');
405 406 }
406 407
407 408 a.close-icon:hover {
408 409 background-image:url('../images/close_hl.png');
409 410 }
410 411
411 412 .rightbox{
412 413 background: #fafbfc;
413 414 border: 1px solid #c0c0c0;
414 415 float: right;
415 416 padding: 8px;
416 417 position: relative;
417 418 margin: 0 5px 5px;
418 419 }
419 420
420 421 .layout-active {
421 422 background: #ECF3E1;
422 423 }
423 424
424 425 .block-receiver {
425 426 border:1px dashed #c0c0c0;
426 427 margin-bottom: 20px;
427 428 padding: 15px 0 15px 0;
428 429 }
429 430
430 431 .mypage-box {
431 432 margin:0 0 20px 0;
432 433 color:#505050;
433 434 line-height:1.5em;
434 435 }
435 436
436 437 .handle {
437 438 cursor: move;
438 439 }
439 440
440 441 .topright{
441 442 position: absolute;
442 443 right: 25px;
443 444 top: 100px;
444 445 }
445 446
446 447 .login {
447 448 width: 50%;
448 449 text-align: left;
449 450 }
450 451
451 452 img.calendar-trigger {
452 453 cursor: pointer;
453 454 vertical-align: middle;
454 455 margin-left: 4px;
455 456 }
456 457
457 458 #history h4, #comments h4 {
458 459 font-size: 1em;
459 460 margin-bottom: 12px;
460 461 margin-top: 20px;
461 462 font-weight: normal;
462 463 border-bottom: dotted 1px #c0c0c0;
463 464 }
464 465
465 466 #history p {
466 467 margin-left: 34px;
467 468 }
468 469
469 470 /***** Contextual links div *****/
470 471 .contextual {
471 472 float: right;
472 473 font-size: 0.8em;
473 474 }
474 475
475 476
476 477
477 478 /***** CSS FORM ******/
478 479 .tabular p{
479 480 margin: 0;
480 481 padding: 5px 0 8px 0;
481 482 padding-left: 180px; /*width of left column containing the label elements*/
482 483 height: 1%;
483 484 }
484 485
485 486 .tabular label{
486 487 font-weight: bold;
487 488 float: left;
488 489 margin-left: -180px; /*width of left column*/
489 490 width: 175px; /*width of labels. Should be smaller than left column to create some right
490 491 margin*/
491 492 }
492 493
493 494 .error {
494 495 color: #cc0000;
495 496 }
496 497
497 498
498 499 /*.threepxfix class below:
499 500 Targets IE6- ONLY. Adds 3 pixel indent for multi-line form contents.
500 501 to account for 3 pixel bug: http://www.positioniseverything.net/explorer/threepxtest.html
501 502 */
502 503
503 504 * html .threepxfix{
504 505 margin-left: 3px;
505 506 } No newline at end of file
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now