Compare commits

..

47 Commits

Author SHA1 Message Date
Kolan Sh 9ec90a50d4 Automatic character encoding detection in Mercurial repos. 2014-05-09 22:41:50 +04:00
Jean-Philippe Lang 9f3239a25a tagged version 2.5.1
git-svn-id: http://svn.redmine.org/redmine/tags/2.5.1@13035 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 16:56:15 +00:00
Jean-Philippe Lang 048036da81 Updates for 2.5.1 release.
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13032 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 16:08:43 +00:00
Jean-Philippe Lang a8d3f491e6 Merged r13029 (#16415).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13030 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 16:04:07 +00:00
Jean-Philippe Lang 1807093b75 Merged r13018 (#16466).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13027 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:53:13 +00:00
Jean-Philippe Lang 665767db44 Merged r12969 and r12973 (#16353).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13026 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:41:09 +00:00
Jean-Philippe Lang 23ae3d1fa6 Merged r12986 (#16381).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13025 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:39:24 +00:00
Jean-Philippe Lang 2344dfe7f7 Merged r12968 (#16319).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13024 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:38:47 +00:00
Jean-Philippe Lang 33a7f6bc11 Merged r12990 and r12991 (#16326).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13023 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:38:11 +00:00
Jean-Philippe Lang 65c9223fe5 Merged r12990 (#16338).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13022 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:37:17 +00:00
Jean-Philippe Lang df7f00afce Merged r12970 (#16259).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13021 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:36:29 +00:00
Jean-Philippe Lang c5b52ec29f Merged r12989 and r12997 (#16236).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13020 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:35:47 +00:00
Jean-Philippe Lang 58786e8d80 Merged r12985 (#14298).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13019 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-29 14:34:28 +00:00
Toshi MARUYAMA d10f17f216 Merged r13015 from trunk to 2.5-stable (#16453)
Czech translation for 2.5-stable updated by Karel Pičman.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13017 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-28 11:23:20 +00:00
Toshi MARUYAMA 323527beb7 Merged r13004 from trunk to 2.5-stable.
add ChangeLog note that #15781 was forgotten to merge to v2.4.3.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13005 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-25 08:39:07 +00:00
Toshi MARUYAMA 0d3cb4e8e1 Merged r13001 from trunk to 2.5-stable.
Gemfile: pin rake version 10.1.

rake 10.2.0 requires Ruby version >= 1.9.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@13002 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-25 08:17:07 +00:00
Toshi MARUYAMA 75855f21bb Merged r12981 from trunk to 2.5-stable (#16368)
Polish translation updated by Jan Inowolski.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12982 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-18 03:42:06 +00:00
Jean-Philippe Lang c61a6a707f Merged r12971 (#16255).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12979 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-17 08:30:30 +00:00
Jean-Philippe Lang 4aab2ed303 Merged r12967 (#16321).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12978 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-17 08:29:20 +00:00
Toshi MARUYAMA e0a8e692da Merged r12965 from trunk to 2.5-stable (#16356)
Spanish translation updated by Jesus Gutierrez de la Vega.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12966 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-15 06:27:34 +00:00
Toshi MARUYAMA 5e06374eb7 Merged r12963 from trunk to 2.5-stable (#16336)
Russian translation updated by Kirill Bezrukov.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12964 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-13 11:38:41 +00:00
Toshi MARUYAMA 9686c078f9 Merged r12961 from trunk to 2.5-stable (#16334)
Korean Translation updated by Jong-Ha Ahn.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12962 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-13 08:53:17 +00:00
Toshi MARUYAMA b3ac538a18 Merged r12959 from trunk to 2.5-stable (#16320)
fix Turkish translation typo by Gürkan Gür.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12960 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-12 00:37:58 +00:00
Toshi MARUYAMA a43716d6bb Merged r12955 from trunk to 2.5-stable (#16291)
Japanese translation updated by Go MAEDA.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12956 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-11 09:57:15 +00:00
Jean-Philippe Lang 91a161fadb Merged r12951.
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12952 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-02 11:24:13 +00:00
Jean-Philippe Lang c75e07f8d3 Updates for 2.5.0 release.
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12950 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-02 09:39:31 +00:00
Jean-Philippe Lang dbe03f5443 Merged r12944 (#16143).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12947 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-02 09:34:00 +00:00
Jean-Philippe Lang 5b1799f245 Merged r12896 (#16081).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12945 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-03-02 09:29:22 +00:00
Jean-Philippe Lang 8b1a61d856 Merged r12941 (#16161).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12942 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-28 12:53:05 +00:00
Jean-Philippe Lang 9cb17f598d Merged r12938 (#16169).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12939 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-28 11:39:01 +00:00
Toshi MARUYAMA 0d5dd6fc19 Merged r12935 from trunk to 2.5-stable (#16177)
use Python getattr instead of hasattr.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12936 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-26 16:53:51 +00:00
Toshi MARUYAMA fcc1f198e7 Merged r12930 from trunk to 2.5-stable (#16177)
Mercurial 2.9 compatibility.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12932 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-26 13:02:03 +00:00
Toshi MARUYAMA 41667cd5de Merged r12929 from trunk to 2.5-stable (#16177)
scm: mercurial: add one "closed" branch to test repository.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12931 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-26 13:01:43 +00:00
Toshi MARUYAMA 51175ede2c revert r12925 of 2.5-stable
I mistook to commit in stable branch.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12926 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-25 06:53:35 +00:00
Toshi MARUYAMA 9abdbd423d prevent issue tree hierarchy is broken in race conditions (#6579)
awesome_nested_set 2.1.6 uses lock.
Issue model uses as same way.

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12925 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-25 06:49:53 +00:00
Jean-Philippe Lang 63212e5c16 Merged r12915 to 12918 (#16107).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12923 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-23 08:20:42 +00:00
Jean-Philippe Lang 88b3872179 Merged r12914 (#16134).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12922 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-23 08:15:37 +00:00
Jean-Philippe Lang 066e9b7f94 Merged r12912 and r12913 from trunk.
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12921 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-23 08:14:59 +00:00
Jean-Philippe Lang 805debddd0 Merged r12910 and r12911 (#16091).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12920 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-23 08:11:59 +00:00
Jean-Philippe Lang 01aa2db0af Merged r12899 (#16077).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12919 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-23 08:10:31 +00:00
Toshi MARUYAMA 645749eea8 Merged r12906 from trunk to 2.5-stable
update Rails to 3.2.17

git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12907 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-19 10:17:14 +00:00
Jean-Philippe Lang 8b9a2ff871 Merged r12897.
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12898 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-15 10:04:48 +00:00
Jean-Philippe Lang 97434b5aaa Merged r12894 (#16091).
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12895 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-15 09:01:16 +00:00
Jean-Philippe Lang 4308dd7d4c Merged r12892.
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12893 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-15 08:34:57 +00:00
Jean-Philippe Lang 449a92640b Merged r12888 to r12890.
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12891 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-15 08:31:07 +00:00
Jean-Philippe Lang 448c0a72ee Set version to 2.5.0.stable.
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12887 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-15 07:40:56 +00:00
Jean-Philippe Lang 20180db41e 2.5-stable branch added
git-svn-id: http://svn.redmine.org/redmine/branches/2.5-stable@12885 e93f8b46-1217-0410-a6f0-8f06a7374b81
2014-02-15 07:37:46 +00:00
161 changed files with 845 additions and 4457 deletions

View File

@ -5,8 +5,8 @@ language: ruby
rvm:
- 1.8.7
- 1.9.3
- 2.0
- 2.1
- 2.0.0
- 2.1.0
- jruby
matrix:
allow_failures:

View File

@ -1,13 +1,15 @@
source 'https://rubygems.org'
gem "rails", "3.2.18"
gem "rails", "3.2.17"
gem "rake", "~> 10.1.1"
gem "jquery-rails", "~> 2.0.2"
gem "coderay", "~> 1.1.0"
gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby]
gem "builder", "3.0.0"
gem "request_store"
gem "mime-types"
gem "awesome_nested_set", "2.1.6"
gem "chardet", ">= 0.9.0"
# Optional gem for LDAP authentication
group :ldap do
@ -86,7 +88,7 @@ end
group :test do
gem "shoulda", "~> 3.3.2"
gem "mocha", "~> 1.0.0", :require => 'mocha/api'
gem "mocha", ">= 0.14", :require => 'mocha/api'
if RUBY_VERSION >= '1.9.3'
gem "capybara", "~> 2.1.0"
gem "selenium-webdriver"

View File

@ -44,7 +44,6 @@ class ApplicationController < ActionController::Base
unless api_request?
super
cookies.delete(autologin_cookie_name)
self.logged_user = nil
render_error :status => 422, :message => "Invalid form authenticity token."
end
end
@ -380,7 +379,7 @@ class ApplicationController < ActionController::Base
begin
uri = URI.parse(back_url)
# do not redirect user to another host or to the login or register page
if ((uri.relative? && back_url.match(%r{\A/(\w.*)?\z})) || (uri.host == request.host)) && !uri.path.match(%r{/(login|account/register)})
if ((uri.relative? && back_url.match(%r{\A/\w})) || (uri.host == request.host)) && !uri.path.match(%r{/(login|account/register)})
redirect_to(back_url)
return
end
@ -558,7 +557,7 @@ class ApplicationController < ActionController::Base
# Returns a string that can be used as filename value in Content-Disposition header
def filename_for_content_disposition(name)
request.env['HTTP_USER_AGENT'] =~ %r{(MSIE|Trident)} ? ERB::Util.url_encode(name) : name
request.env['HTTP_USER_AGENT'] =~ %r{MSIE} ? ERB::Util.url_encode(name) : name
end
def api_request?

View File

@ -55,7 +55,7 @@ class ContextMenusController < ApplicationController
@options_by_custom_field = {}
if @can[:edit]
custom_fields = @issues.map(&:editable_custom_fields).reduce(:&).reject(&:multiple?)
custom_fields = @issues.map(&:available_custom_fields).reduce(:&).reject(&:multiple?)
custom_fields.each do |field|
values = field.possible_values_options(@projects)
if values.present?

View File

@ -411,7 +411,7 @@ class RepositoriesController < ApplicationController
commits_data = commits_data + [0]*(10 - commits_data.length) if commits_data.length<10
changes_data = changes_data + [0]*(10 - changes_data.length) if changes_data.length<10
# Remove email address in usernames
# Remove email adress in usernames
fields = fields.collect {|c| c.gsub(%r{<.+@.+>}, '') }
graph = SVG::Graph::BarHorizontal.new(

View File

@ -18,30 +18,40 @@
class WorkflowsController < ApplicationController
layout 'admin'
before_filter :require_admin
before_filter :require_admin, :find_roles, :find_trackers
def index
@workflow_counts = WorkflowTransition.count_by_tracker_and_role
end
def edit
find_trackers_roles_and_statuses_for_edit
@role = Role.find_by_id(params[:role_id]) if params[:role_id]
@tracker = Tracker.find_by_id(params[:tracker_id]) if params[:tracker_id]
if request.post? && @roles && @trackers && params[:transitions]
transitions = params[:transitions].deep_dup
transitions.each do |old_status_id, transitions_by_new_status|
transitions_by_new_status.each do |new_status_id, transition_by_rule|
transition_by_rule.reject! {|rule, transition| transition == 'no_change'}
end
if request.post?
WorkflowTransition.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id])
(params[:issue_status] || []).each { |status_id, transitions|
transitions.each { |new_status_id, options|
author = options.is_a?(Array) && options.include?('author') && !options.include?('always')
assignee = options.is_a?(Array) && options.include?('assignee') && !options.include?('always')
WorkflowTransition.create(:role_id => @role.id, :tracker_id => @tracker.id, :old_status_id => status_id, :new_status_id => new_status_id, :author => author, :assignee => assignee)
}
}
if @role.save
flash[:notice] = l(:notice_successful_update)
redirect_to workflows_edit_path(:role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only])
return
end
WorkflowTransition.replace_transitions(@trackers, @roles, transitions)
flash[:notice] = l(:notice_successful_update)
redirect_to_referer_or workflows_edit_path
return
end
if @trackers && @roles && @statuses.any?
workflows = WorkflowTransition.where(:role_id => @roles.map(&:id), :tracker_id => @trackers.map(&:id))
@used_statuses_only = (params[:used_statuses_only] == '0' ? false : true)
if @tracker && @used_statuses_only && @tracker.issue_statuses.any?
@statuses = @tracker.issue_statuses
end
@statuses ||= IssueStatus.sorted.all
if @tracker && @role && @statuses.any?
workflows = WorkflowTransition.where(:role_id => @role.id, :tracker_id => @tracker.id).all
@workflows = {}
@workflows['always'] = workflows.select {|w| !w.author && !w.assignee}
@workflows['author'] = workflows.select {|w| w.author}
@ -50,31 +60,36 @@ class WorkflowsController < ApplicationController
end
def permissions
find_trackers_roles_and_statuses_for_edit
@role = Role.find_by_id(params[:role_id]) if params[:role_id]
@tracker = Tracker.find_by_id(params[:tracker_id]) if params[:tracker_id]
if request.post? && @roles && @trackers && params[:permissions]
permissions = params[:permissions].deep_dup
permissions.each { |field, rule_by_status_id|
rule_by_status_id.reject! {|status_id, rule| rule == 'no_change'}
}
WorkflowPermission.replace_permissions(@trackers, @roles, permissions)
if request.post? && @role && @tracker
WorkflowPermission.replace_permissions(@tracker, @role, params[:permissions] || {})
flash[:notice] = l(:notice_successful_update)
redirect_to_referer_or workflows_permissions_path
redirect_to workflows_permissions_path(:role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only])
return
end
if @roles && @trackers
@fields = (Tracker::CORE_FIELDS_ALL - @trackers.map(&:disabled_core_fields).reduce(:&)).map {|field| [field, l("field_"+field.sub(/_id$/, ''))]}
@custom_fields = @trackers.map(&:custom_fields).flatten.uniq.sort
@permissions = WorkflowPermission.rules_by_status_id(@trackers, @roles)
@used_statuses_only = (params[:used_statuses_only] == '0' ? false : true)
if @tracker && @used_statuses_only && @tracker.issue_statuses.any?
@statuses = @tracker.issue_statuses
end
@statuses ||= IssueStatus.sorted.all
if @role && @tracker
@fields = (Tracker::CORE_FIELDS_ALL - @tracker.disabled_core_fields).map {|field| [field, l("field_"+field.sub(/_id$/, ''))]}
@custom_fields = @tracker.custom_fields
@permissions = WorkflowPermission.
where(:tracker_id => @tracker.id, :role_id => @role.id).inject({}) do |h, w|
h[w.old_status_id] ||= {}
h[w.old_status_id][w.field_name] = w.rule
h
end
@statuses.each {|status| @permissions[status.id] ||= {}}
end
end
def copy
@roles = Role.sorted
@trackers = Tracker.sorted
if params[:source_tracker_id].blank? || params[:source_tracker_id] == 'any'
@source_tracker = nil
else
@ -104,37 +119,11 @@ class WorkflowsController < ApplicationController
private
def find_trackers_roles_and_statuses_for_edit
find_roles
find_trackers
find_statuses
end
def find_roles
ids = Array.wrap(params[:role_id])
if ids == ['all']
@roles = Role.sorted.all
elsif ids.present?
@roles = Role.where(:id => ids).all
end
@roles = nil if @roles.blank?
@roles = Role.sorted.all
end
def find_trackers
ids = Array.wrap(params[:tracker_id])
if ids == ['all']
@trackers = Tracker.sorted.all
elsif ids.present?
@trackers = Tracker.where(:id => ids).all
end
@trackers = nil if @trackers.blank?
end
def find_statuses
@used_statuses_only = (params[:used_statuses_only] == '0' ? false : true)
if @trackers && @used_statuses_only
@statuses = @trackers.map(&:issue_statuses).flatten.uniq.sort.presence
end
@statuses ||= IssueStatus.sorted.all
@trackers = Tracker.sorted.all
end
end

View File

@ -24,12 +24,4 @@ module AdminHelper
[l(:project_status_closed), '5'],
[l(:project_status_archived), '9']], selected.to_s)
end
def plugin_data_for_updates(plugins)
data = {"v" => Redmine::VERSION.to_s, "p" => {}}
plugins.each do |plugin|
data["p"].merge! plugin.id => {"v" => plugin.version, "n" => plugin.name, "a" => plugin.author}
end
data
end
end

View File

@ -158,10 +158,7 @@ module ApplicationHelper
end
# Helper that formats object for html or text rendering
def format_object(object, html=true, &block)
if block_given?
object = yield object
end
def format_object(object, html=true)
case object.class.name
when 'Array'
object.map {|o| format_object(o, html)}.join(', ').html_safe
@ -191,7 +188,7 @@ module ApplicationHelper
if f.nil? || f.is_a?(String)
f
else
format_object(f, html, &block)
format_object(f, html)
end
else
object.value.to_s
@ -822,7 +819,6 @@ module ApplicationHelper
elsif sep == ':'
# removes the double quotes if any
name = identifier.gsub(%r{^"(.*)"$}, "\\1")
name = CGI.unescapeHTML(name)
case prefix
when 'document'
if project && document = project.documents.visible.find_by_title(name)
@ -1332,7 +1328,7 @@ module ApplicationHelper
def api_meta(options)
if params[:nometa].present? || request.headers['X-Redmine-Nometa']
# compatibility mode for activeresource clients that raise
# an error when deserializing an array with attributes
# an error when unserializing an array with attributes
nil
else
options

View File

@ -20,7 +20,7 @@
module ProjectsHelper
def link_to_version(version, options = {})
return '' unless version && version.is_a?(Version)
link_to_if version.visible?, format_version_name(version), version_path(version), options
link_to_if version.visible?, format_version_name(version), { :controller => 'versions', :action => 'show', :id => version }, options
end
def project_settings_tabs
@ -53,16 +53,10 @@ module ProjectsHelper
def render_project_action_links
links = []
if User.current.allowed_to?(:add_project, nil, :global => true)
links << link_to(l(:label_project_new), new_project_path, :class => 'icon icon-add')
end
if User.current.allowed_to?(:view_issues, nil, :global => true)
links << link_to(l(:label_issue_view_all), issues_path)
end
if User.current.allowed_to?(:view_time_entries, nil, :global => true)
links << link_to(l(:label_overall_spent_time), time_entries_path)
end
links << link_to(l(:label_overall_activity), activity_path)
links << link_to(l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add') if User.current.allowed_to?(:add_project, nil, :global => true)
links << link_to(l(:label_issue_view_all), issues_path) if User.current.allowed_to?(:view_issues, nil, :global => true)
links << link_to(l(:label_overall_spent_time), time_entries_path) if User.current.allowed_to?(:view_time_entries, nil, :global => true)
links << link_to(l(:label_overall_activity), { :controller => 'activities', :action => 'index', :id => nil })
links.join(" | ").html_safe
end

View File

@ -18,8 +18,6 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module QueriesHelper
include ApplicationHelper
def filters_options_for_select(query)
options_for_select(filters_options(query))
end
@ -83,7 +81,7 @@ module QueriesHelper
end
def column_content(column, issue)
value = column.value_object(issue)
value = column.value(issue)
if value.is_a?(Array)
value.collect {|v| column_value(column, issue, v)}.compact.join(', ').html_safe
else
@ -112,7 +110,7 @@ module QueriesHelper
end
def csv_content(column, issue)
value = column.value_object(issue)
value = column.value(issue)
if value.is_a?(Array)
value.collect {|v| csv_value(column, issue, v)}.compact.join(', ')
else
@ -121,16 +119,22 @@ module QueriesHelper
end
def csv_value(column, issue, value)
format_object(value, false) do |value|
case value.class.name
when 'Float'
sprintf("%.2f", value).gsub('.', l(:general_csv_decimal_separator))
when 'IssueRelation'
other = value.other_issue(issue)
l(value.label_for(issue)) + " ##{other.id}"
else
value
end
case value.class.name
when 'Time'
format_time(value)
when 'Date'
format_date(value)
when 'Float'
sprintf("%.2f", value).gsub('.', l(:general_csv_decimal_separator))
when 'IssueRelation'
other = value.other_issue(issue)
l(value.label_for(issue)) + " ##{other.id}"
when 'TrueClass'
l(:general_text_Yes)
when 'FalseClass'
l(:general_text_No)
else
value.to_s
end
end

View File

@ -84,24 +84,12 @@ module SettingsHelper
# Renders a notification field for a Redmine::Notifiable option
def notification_field(notifiable)
tag_data = notifiable.parent.present? ?
{:parent_notifiable => notifiable.parent} :
{:disables => "input[data-parent-notifiable=#{notifiable.name}]"}
tag = check_box_tag('settings[notified_events][]',
notifiable.name,
Setting.notified_events.include?(notifiable.name),
:id => nil,
:data => tag_data)
text = l_or_humanize(notifiable.name, :prefix => 'label_')
options = {}
if notifiable.parent.present?
options[:class] = "parent"
end
content_tag(:label, tag + text, options)
return content_tag(:label,
check_box_tag('settings[notified_events][]',
notifiable.name,
Setting.notified_events.include?(notifiable.name), :id => nil).html_safe +
l_or_humanize(notifiable.name, :prefix => 'label_').html_safe,
:class => notifiable.parent.present? ? "parent" : '').html_safe
end
def cross_project_subtasks_options

View File

@ -18,78 +18,24 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module WorkflowsHelper
def options_for_workflow_select(name, objects, selected, options={})
option_tags = ''.html_safe
multiple = false
if selected
if selected.size == objects.size
selected = 'all'
else
selected = selected.map(&:id)
if selected.size > 1
multiple = true
end
end
else
selected = objects.first.try(:id)
end
all_tag_options = {:value => 'all', :selected => (selected == 'all')}
if multiple
all_tag_options.merge!(:style => "display:none;")
end
option_tags << content_tag('option', l(:label_all), all_tag_options)
option_tags << options_from_collection_for_select(objects, "id", "name", selected)
select_tag name, option_tags, {:multiple => multiple}.merge(options)
end
def field_required?(field)
field.is_a?(CustomField) ? field.is_required? : %w(project_id tracker_id subject priority_id is_private).include?(field)
end
def field_permission_tag(permissions, status, field, roles)
def field_permission_tag(permissions, status, field, role)
name = field.is_a?(CustomField) ? field.id.to_s : field
options = [["", ""], [l(:label_readonly), "readonly"]]
options << [l(:label_required), "required"] unless field_required?(field)
html_options = {}
if perm = permissions[status.id][name]
if perm.uniq.size > 1 || perm.size < @roles.size * @trackers.size
options << [l(:label_no_change_option), "no_change"]
selected = 'no_change'
else
selected = perm.first
end
end
hidden = field.is_a?(CustomField) &&
!field.visible? &&
!roles.detect {|role| role.custom_fields.to_a.include?(field)}
selected = permissions[status.id][name]
hidden = field.is_a?(CustomField) && !field.visible? && !role.custom_fields.to_a.include?(field)
if hidden
options[0][0] = l(:label_hidden)
selected = ''
html_options[:disabled] = true
end
select_tag("permissions[#{status.id}][#{name}]", options_for_select(options, selected), html_options)
end
def transition_tag(workflows, old_status, new_status, name)
w = workflows.select {|w| w.old_status_id == old_status.id && w.new_status_id == new_status.id}.size
tag_name = "transitions[#{ old_status.id }][#{new_status.id}][#{name}]"
if w == 0 || w == @roles.size * @trackers.size
hidden_field_tag(tag_name, "0") +
check_box_tag(tag_name, "1", w != 0,
:class => "old-status-#{old_status.id} new-status-#{new_status.id}")
else
select_tag tag_name,
options_for_select([
[l(:general_text_Yes), "1"],
[l(:general_text_No), "0"],
[l(:label_no_change_option), "no_change"]
], "no_change")
end
select_tag("permissions[#{name}][#{status.id}]", options_for_select(options, selected), html_options)
end
end

View File

@ -73,7 +73,7 @@ class Enumeration < ActiveRecord::Base
self.objects_count != 0
end
# Is this enumeration overriding a system level enumeration?
# Is this enumeration overiding a system level enumeration?
def is_override?
!self.parent.nil?
end
@ -103,14 +103,8 @@ class Enumeration < ActiveRecord::Base
subclasses
end
# TODO: remove in Redmine 3.0
def self.overridding_change?(new, previous)
ActiveSupport::Deprecation.warn "Enumeration#overridding_change? is deprecated and will be removed in Redmine 3.0. Please use #overriding_change?."
overriding_change?(new, previous)
end
# Does the +new+ Hash override the previous Enumeration?
def self.overriding_change?(new, previous)
def self.overridding_change?(new, previous)
if (same_active_state?(new['active'], previous.active)) && same_custom_values?(new,previous)
return false
else

View File

@ -33,7 +33,7 @@ class Issue < ActiveRecord::Base
has_many :visible_journals,
:class_name => 'Journal',
:as => :journalized,
:conditions => Proc.new {
:conditions => Proc.new {
["(#{Journal.table_name}.private_notes = ? OR (#{Project.allowed_to_condition(User.current, :view_private_notes)}))", false]
},
:readonly => true
@ -94,7 +94,7 @@ class Issue < ActiveRecord::Base
before_create :default_assign
before_save :close_duplicates, :update_done_ratio_from_issue_status,
:force_updated_on_change, :update_closed_on, :set_assigned_to_was
after_save {|issue| issue.send :after_project_change if !issue.id_changed? && issue.project_id_changed?}
after_save {|issue| issue.send :after_project_change if !issue.id_changed? && issue.project_id_changed?}
after_save :reschedule_following_issues, :update_nested_set_attributes,
:update_parent_attributes, :create_journal
# Should be after_create but would be called before previous after_save callbacks
@ -218,7 +218,7 @@ class Issue < ActiveRecord::Base
self.status = issue.status
self.author = User.current
unless options[:attachments] == false
self.attachments = issue.attachments.map do |attachement|
self.attachments = issue.attachments.map do |attachement|
attachement.copy(:container => self)
end
end
@ -394,10 +394,10 @@ class Issue < ActiveRecord::Base
:if => lambda {|issue, user| user.allowed_to?(:add_issue_notes, issue.project)}
safe_attributes 'private_notes',
:if => lambda {|issue, user| !issue.new_record? && user.allowed_to?(:set_notes_private, issue.project)}
:if => lambda {|issue, user| !issue.new_record? && user.allowed_to?(:set_notes_private, issue.project)}
safe_attributes 'watcher_user_ids',
:if => lambda {|issue, user| issue.new_record? && user.allowed_to?(:add_issue_watchers, issue.project)}
:if => lambda {|issue, user| issue.new_record? && user.allowed_to?(:add_issue_watchers, issue.project)}
safe_attributes 'is_private',
:if => lambda {|issue, user|
@ -483,11 +483,6 @@ class Issue < ActiveRecord::Base
end
end
# Returns the custom fields that can be edited by the given user
def editable_custom_fields(user=nil)
editable_custom_field_values(user).map(&:custom_field).uniq
end
# Returns the names of attributes that are read-only for user or the current user
# For users with multiple roles, the read-only fields are the intersection of
# read-only fields of each role
@ -529,7 +524,7 @@ class Issue < ActiveRecord::Base
return {} if roles.empty?
result = {}
workflow_permissions = WorkflowPermission.where(:tracker_id => tracker_id, :old_status_id => status_id, :role_id => roles.map(&:id))
workflow_permissions = WorkflowPermission.where(:tracker_id => tracker_id, :old_status_id => status_id, :role_id => roles.map(&:id)).all
if workflow_permissions.any?
workflow_rules = workflow_permissions.inject({}) do |h, wp|
h[wp.field_name] ||= []
@ -767,7 +762,7 @@ class Issue < ActiveRecord::Base
initial_status ||= status
initial_assigned_to_id = assigned_to_id_changed? ? assigned_to_id_was : assigned_to_id
assignee_transitions_allowed = initial_assigned_to_id.present? &&
assignee_transitions_allowed = initial_assigned_to_id.present? &&
(user.id == initial_assigned_to_id || user.group_ids.include?(initial_assigned_to_id))
statuses = initial_status.find_new_statuses_allowed_to(
@ -1061,7 +1056,7 @@ class Issue < ActiveRecord::Base
if leaf.start_date
# Only move subtask if it starts at the same date as the parent
# or if it starts before the given date
if start_date == leaf.start_date || date > leaf.start_date
if start_date == leaf.start_date || date > leaf.start_date
leaf.reschedule_on!(date)
end
else
@ -1112,10 +1107,7 @@ class Issue < ActiveRecord::Base
def self.update_versions_from_hierarchy_change(project)
moved_project_ids = project.self_and_descendants.reload.collect(&:id)
# Update issues of the moved projects and issues assigned to a version of a moved project
Issue.update_versions(
["#{Version.table_name}.project_id IN (?) OR #{Issue.table_name}.project_id IN (?)",
moved_project_ids, moved_project_ids]
)
Issue.update_versions(["#{Version.table_name}.project_id IN (?) OR #{Issue.table_name}.project_id IN (?)", moved_project_ids, moved_project_ids])
end
def parent_issue_id=(arg)
@ -1199,13 +1191,13 @@ class Issue < ActiveRecord::Base
end
def self.by_subproject(project)
ActiveRecord::Base.connection.select_all("select s.id as status_id,
s.is_closed as closed,
ActiveRecord::Base.connection.select_all("select s.id as status_id,
s.is_closed as closed,
#{Issue.table_name}.project_id as project_id,
count(#{Issue.table_name}.id) as total
from
count(#{Issue.table_name}.id) as total
from
#{Issue.table_name}, #{Project.table_name}, #{IssueStatus.table_name} s
where
where
#{Issue.table_name}.status_id=s.id
and #{Issue.table_name}.project_id = #{Project.table_name}.id
and #{visible_condition(User.current, :project => project, :with_subprojects => true)}
@ -1295,7 +1287,9 @@ class Issue < ActiveRecord::Base
if root_id.nil?
# issue was just created
self.root_id = (@parent_issue.nil? ? id : @parent_issue.root_id)
Issue.where(["id = ?", id]).update_all(["root_id = ?", root_id])
set_default_left_and_right
Issue.where(["id = ?", id]).
update_all(["root_id = ?, lft = ?, rgt = ?", root_id, lft, rgt])
if @parent_issue
move_to_child_of(@parent_issue)
end
@ -1318,18 +1312,13 @@ class Issue < ActiveRecord::Base
move_to_right_of(root)
end
old_root_id = root_id
in_tenacious_transaction do
@parent_issue.reload_nested_set if @parent_issue
self.reload_nested_set
self.root_id = (@parent_issue.nil? ? id : @parent_issue.root_id)
cond = ["root_id = ? AND lft >= ? AND rgt <= ? ", old_root_id, lft, rgt]
self.class.base_class.select('id').lock(true).where(cond)
offset = right_most_bound + 1 - lft
Issue.where(cond).
update_all(["root_id = ?, lft = lft + ?, rgt = rgt + ?", root_id, offset, offset])
self[left_column_name] = lft + offset
self[right_column_name] = rgt + offset
end
self.root_id = (@parent_issue.nil? ? id : @parent_issue.root_id )
target_maxright = nested_set_scope.maximum(right_column_name) || 0
offset = target_maxright + 1 - lft
Issue.where(["root_id = ? AND lft >= ? AND rgt <= ? ", old_root_id, lft, rgt]).
update_all(["root_id = ?, lft = lft + ?, rgt = rgt + ?", root_id, offset, offset])
self[left_column_name] = lft + offset
self[right_column_name] = rgt + offset
if @parent_issue
move_to_child_of(@parent_issue)
end
@ -1441,7 +1430,7 @@ class Issue < ActiveRecord::Base
def close_duplicates
if closing?
duplicates.each do |duplicate|
# Reload is needed in case the duplicate was updated by a previous duplicate
# Reload is need in case the duplicate was updated by a previous duplicate
duplicate.reload
# Don't re-close it if it's already closed
next if duplicate.closed?
@ -1496,11 +1485,11 @@ class Issue < ActiveRecord::Base
before = @custom_values_before_change[c.custom_field_id]
after = c.value
next if before == after || (before.blank? && after.blank?)
if before.is_a?(Array) || after.is_a?(Array)
before = [before] unless before.is_a?(Array)
after = [after] unless after.is_a?(Array)
# values removed
(before - after).reject(&:blank?).each do |value|
@current_journal.details << JournalDetail.new(:property => 'cf',
@ -1561,14 +1550,14 @@ class Issue < ActiveRecord::Base
where = "#{Issue.table_name}.#{select_field}=j.id"
ActiveRecord::Base.connection.select_all("select s.id as status_id,
s.is_closed as closed,
ActiveRecord::Base.connection.select_all("select s.id as status_id,
s.is_closed as closed,
j.id as #{select_field},
count(#{Issue.table_name}.id) as total
from
count(#{Issue.table_name}.id) as total
from
#{Issue.table_name}, #{Project.table_name}, #{IssueStatus.table_name} s, #{joins} j
where
#{Issue.table_name}.status_id=s.id
where
#{Issue.table_name}.status_id=s.id
and #{where}
and #{Issue.table_name}.project_id=#{Project.table_name}.id
and #{visible_condition(User.current, :project => project)}

View File

@ -80,20 +80,15 @@ class Journal < ActiveRecord::Base
end
end
# Returns the JournalDetail for the given attribute, or nil if the attribute
# was not updated
def detail_for_attribute(attribute)
details.detect {|detail| detail.prop_key == attribute}
end
# Returns the new status if the journal contains a status change, otherwise nil
def new_status
s = new_value_for('status_id')
s ? IssueStatus.find_by_id(s.to_i) : nil
c = details.detect {|detail| detail.prop_key == 'status_id'}
(c && c.value) ? IssueStatus.find_by_id(c.value.to_i) : nil
end
def new_value_for(prop)
detail_for_attribute(prop).try(:value)
c = details.detect {|detail| detail.prop_key == prop}
c ? c.value : nil
end
def editable_by?(usr)
@ -190,7 +185,6 @@ class Journal < ActiveRecord::Base
if notify? && (Setting.notified_events.include?('issue_updated') ||
(Setting.notified_events.include?('issue_note_added') && notes.present?) ||
(Setting.notified_events.include?('issue_status_updated') && new_status.present?) ||
(Setting.notified_events.include?('issue_assigned_to_updated') && detail_for_attribute('assigned_to_id').present?) ||
(Setting.notified_events.include?('issue_priority_updated') && new_value_for('priority_id').present?)
)
Mailer.deliver_issue_edit(self)

View File

@ -46,14 +46,6 @@ class MailHandler < ActionMailer::Base
super(email)
end
# Receives an email and rescues any exception
def self.safe_receive(*args)
receive(*args)
rescue => e
logger.error "An unexpected error occurred when receiving email: #{e.message}" if logger
return false
end
# Extracts MailHandler options from environment variables
# Use when receiving emails with rake tasks
def self.extract_options_from_env(env)
@ -198,7 +190,6 @@ class MailHandler < ActionMailer::Base
issue.subject = '(no subject)'
end
issue.description = cleaned_up_text_body
issue.start_date ||= Date.today if Setting.default_issue_start_date_to_creation_date?
# add To and Cc as watchers before saving so the watchers can reply to Redmine
add_watchers(issue)

View File

@ -464,7 +464,7 @@ class Mailer < ActionMailer::Base
if rand
hash << Redmine::Utils.random_hex(8)
end
host = Setting.mail_from.to_s.strip.gsub(%r{^.*@|>}, '')
host = Setting.mail_from.to_s.gsub(%r{^.*@}, '')
host = "#{::Socket.gethostname}.redmine" if host.empty?
"#{hash.join('.')}@#{host}"
end

View File

@ -89,7 +89,7 @@ class Member < ActiveRecord::Base
end
end
# Find or initialize a Member with an id, attributes, and for a Principal
# Find or initilize a Member with an id, attributes, and for a Principal
def self.edit_membership(id, new_attributes, principal=nil)
@membership = id.present? ? Member.find(id) : Member.new(:principal => principal)
@membership.attributes = new_attributes

View File

@ -26,7 +26,7 @@ class Project < ActiveRecord::Base
# Maximum length for project identifiers
IDENTIFIER_MAX_LENGTH = 100
# Specific overridden Activities
# Specific overidden Activities
has_many :time_entry_activities
has_many :members, :include => [:principal, :roles], :conditions => "#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}"
has_many :memberships, :class_name => 'Member'
@ -74,7 +74,7 @@ class Project < ActiveRecord::Base
validates_length_of :name, :maximum => 255
validates_length_of :homepage, :maximum => 255
validates_length_of :identifier, :in => 1..IDENTIFIER_MAX_LENGTH
# downcase letters, digits, dashes but not digits only
# donwcase letters, digits, dashes but not digits only
validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :if => Proc.new { |p| p.identifier_changed? }
# reserved words
validates_exclusion_of :identifier, :in => %w( new )
@ -252,10 +252,10 @@ class Project < ActiveRecord::Base
parent_activity = TimeEntryActivity.find(activity['parent_id'])
activity['name'] = parent_activity.name
activity['position'] = parent_activity.position
if Enumeration.overriding_change?(activity, parent_activity)
if Enumeration.overridding_change?(activity, parent_activity)
project_activity = self.time_entry_activities.create(activity)
if project_activity.new_record?
raise ActiveRecord::Rollback, "Overriding TimeEntryActivity was not successfully saved"
raise ActiveRecord::Rollback, "Overridding TimeEntryActivity was not successfully saved"
else
self.time_entries.
where(["activity_id = ?", parent_activity.id]).
@ -502,7 +502,7 @@ class Project < ActiveRecord::Base
assignable.select {|m| m.roles.detect {|role| role.assignable?}}.collect {|m| m.principal}.sort
end
# Returns the mail addresses of users that should be always notified on project events
# Returns the mail adresses of users that should be always notified on project events
def recipients
notified_users.collect {|user| user.mail}
end
@ -514,7 +514,7 @@ class Project < ActiveRecord::Base
end
# Returns a scope of all custom fields enabled for project issues
# (explicitly associated custom fields and custom fields enabled for all projects)
# (explictly associated custom fields and custom fields enabled for all projects)
def all_issue_custom_fields
@all_issue_custom_fields ||= IssueCustomField.
sorted.
@ -847,7 +847,7 @@ class Project < ActiveRecord::Base
# Copies issues from +project+
def copy_issues(project)
# Stores the source issue id as a key and the copied issues as the
# value. Used to map the two together for issue relations.
# value. Used to map the two togeather for issue relations.
issues_map = {}
# Store status and reopen locked/closed versions

View File

@ -57,10 +57,6 @@ class QueryColumn
object.send name
end
def value_object(object)
object.send name
end
def css_classes
name
end
@ -84,21 +80,10 @@ class QueryCustomFieldColumn < QueryColumn
@cf
end
def value_object(object)
if custom_field.visible_by?(object.project, User.current)
cv = object.custom_values.select {|v| v.custom_field_id == @cf.id}
cv.size > 1 ? cv.sort {|a,b| a.value.to_s <=> b.value.to_s} : cv.first
else
nil
end
end
def value(object)
raw = value_object(object)
if raw.is_a?(Array)
raw.map {|r| @cf.cast_value(r.value)}
elsif raw
@cf.cast_value(raw.value)
if custom_field.visible_by?(object.project, User.current)
cv = object.custom_values.select {|v| v.custom_field_id == @cf.id}.collect {|v| @cf.cast_value(v.value)}
cv.size > 1 ? cv.sort {|a,b| a.to_s <=> b.to_s} : cv.first
else
nil
end
@ -120,7 +105,7 @@ class QueryAssociationCustomFieldColumn < QueryCustomFieldColumn
@association = association
end
def value_object(object)
def value(object)
if assoc = object.send(@association)
super(assoc)
end
@ -159,8 +144,8 @@ class Query < ActiveRecord::Base
after_save do |query|
if query.visibility_changed? && query.visibility != VISIBILITY_ROLES
query.roles.clear
end
query.roles.clear
end
end
class_attribute :operators
@ -556,7 +541,7 @@ class Query < ActiveRecord::Base
next unless v and !v.empty?
operator = operator_for(field)
# "me" value substitution
# "me" value subsitution
if %w(assigned_to_id author_id user_id watcher_id).include?(field)
if v.delete("me")
if User.current.logged?

View File

@ -40,7 +40,7 @@ class Repository < ActiveRecord::Base
validates_length_of :identifier, :maximum => IDENTIFIER_MAX_LENGTH, :allow_blank => true
validates_presence_of :identifier, :unless => Proc.new { |r| r.is_default? || r.set_as_default? }
validates_uniqueness_of :identifier, :scope => :project_id, :allow_blank => true
validates_exclusion_of :identifier, :in => %w(browse show entry raw changes annotate diff statistics graph revisions revision)
validates_exclusion_of :identifier, :in => %w(show entry raw changes annotate diff show stats graph)
# donwcase letters, digits, dashes, underscores but not digits only
validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :allow_blank => true
# Checks if the SCM is enabled when creating a repository

View File

@ -138,9 +138,9 @@ class Repository::Cvs < Repository
# is not exclusive at all.
tmp_time = revision.time.clone
unless filechanges.find_by_path_and_revision(
scm.with_leading_slash(revision.paths[0][:path]),
revision.paths[0][:revision]
)
scm.with_leading_slash(revision.paths[0][:path]),
revision.paths[0][:revision]
)
cmt = Changeset.normalize_comments(revision.message, repo_log_encoding)
author_utf8 = Changeset.to_utf8(revision.author, repo_log_encoding)
cs = changesets.where(
@ -150,7 +150,7 @@ class Repository::Cvs < Repository
).first
# create a new changeset....
unless cs
# we use a temporary revision number here (just for inserting)
# we use a temporaray revision number here (just for inserting)
# later on, we calculate a continous positive number
tmp_time2 = tmp_time.clone.gmtime
branch = revision.paths[0][:branch]

View File

@ -155,7 +155,7 @@ class Repository::Mercurial < Repository
# Revisions in root directory and sub directory are not equal.
# So, in order to get correct limit, we need to get all revisions.
# But, it is very heavy.
# Mercurial does not treat directory.
# Mercurial does not treat direcotry.
# So, "hg log DIR" is very heavy.
branch_limit = path.blank? ? limit : ( limit * 5 )
args << nodes_in_branch(rev, branch_limit)

View File

@ -626,11 +626,11 @@ class User < Principal
end
def self.current=(user)
RequestStore.store[:current_user] = user
Thread.current[:current_user] = user
end
def self.current
RequestStore.store[:current_user] ||= User.anonymous
Thread.current[:current_user] ||= User.anonymous
end
# Returns the anonymous user. If the anonymous user does not exist, it is created. There can be only

View File

@ -256,7 +256,7 @@ class Version < ActiveRecord::Base
# Returns the average estimated time of assigned issues
# or 1 if no issue has an estimated time
# Used to weight unestimated issues in progress calculation
# Used to weigth unestimated issues in progress calculation
def estimated_average
if @estimated_average.nil?
average = fixed_issues.average(:estimated_hours).to_f

View File

@ -40,7 +40,7 @@ class WikiContent < ActiveRecord::Base
page.nil? ? [] : page.attachments
end
# Returns the mail addresses of users that should be notified
# Returns the mail adresses of users that should be notified
def recipients
notified = project.notified_users
notified.reject! {|user| !visible?(user)}

View File

@ -19,43 +19,20 @@ class WorkflowPermission < WorkflowRule
validates_inclusion_of :rule, :in => %w(readonly required)
validate :validate_field_name
# Returns the workflow permissions for the given trackers and roles
# grouped by status_id
# Replaces the workflow permissions for the given tracker and role
#
# Example:
# WorkflowPermission.rules_by_status_id trackers, roles
# # => {1 => {'start_date' => 'required', 'due_date' => 'readonly'}}
def self.rules_by_status_id(trackers, roles)
WorkflowPermission.where(:tracker_id => trackers.map(&:id), :role_id => roles.map(&:id)).inject({}) do |h, w|
h[w.old_status_id] ||= {}
h[w.old_status_id][w.field_name] ||= []
h[w.old_status_id][w.field_name] << w.rule
h
end
end
# WorkflowPermission.replace_permissions role, tracker, {'due_date' => {'1' => 'readonly', '2' => 'required'}}
def self.replace_permissions(tracker, role, permissions)
destroy_all(:tracker_id => tracker.id, :role_id => role.id)
# Replaces the workflow permissions for the given trackers and roles
#
# Example:
# WorkflowPermission.replace_permissions trackers, roles, {'1' => {'start_date' => 'required', 'due_date' => 'readonly'}}
def self.replace_permissions(trackers, roles, permissions)
trackers = Array.wrap trackers
roles = Array.wrap roles
transaction do
permissions.each { |status_id, rule_by_field|
rule_by_field.each { |field, rule|
destroy_all(:tracker_id => trackers.map(&:id), :role_id => roles.map(&:id), :old_status_id => status_id, :field_name => field)
if rule.present?
trackers.each do |tracker|
roles.each do |role|
WorkflowPermission.create(:role_id => role.id, :tracker_id => tracker.id, :old_status_id => status_id, :field_name => field, :rule => rule)
end
end
end
}
permissions.each { |field, rule_by_status_id|
rule_by_status_id.each { |status_id, rule|
if rule.present?
WorkflowPermission.create(:role_id => role.id, :tracker_id => tracker.id, :old_status_id => status_id, :field_name => field, :rule => rule)
end
}
end
}
end
protected

View File

@ -21,8 +21,9 @@ class WorkflowTransition < WorkflowRule
# Returns workflow transitions count by tracker and role
def self.count_by_tracker_and_role
counts = connection.select_all("SELECT role_id, tracker_id, count(id) AS c FROM #{table_name} WHERE type = 'WorkflowTransition' GROUP BY role_id, tracker_id")
roles = Role.sorted
trackers = Tracker.sorted
roles = Role.sorted.all
trackers = Tracker.sorted.all
result = []
trackers.each do |tracker|
t = []
@ -32,71 +33,7 @@ class WorkflowTransition < WorkflowRule
end
result << [tracker, t]
end
result
end
def self.replace_transitions(trackers, roles, transitions)
trackers = Array.wrap trackers
roles = Array.wrap roles
transaction do
records = WorkflowTransition.where(:tracker_id => trackers.map(&:id), :role_id => roles.map(&:id)).all
transitions.each do |old_status_id, transitions_by_new_status|
transitions_by_new_status.each do |new_status_id, transition_by_rule|
transition_by_rule.each do |rule, transition|
trackers.each do |tracker|
roles.each do |role|
w = records.select {|r|
r.old_status_id == old_status_id.to_i &&
r.new_status_id == new_status_id.to_i &&
r.tracker_id == tracker.id &&
r.role_id == role.id &&
!r.destroyed?
}
if rule == 'always'
w = w.select {|r| !r.author && !r.assignee}
else
w = w.select {|r| r.author || r.assignee}
end
if w.size > 1
w[1..-1].each(&:destroy)
end
w = w.first
if transition == "1" || transition == true
unless w
w = WorkflowTransition.new(:old_status_id => old_status_id, :new_status_id => new_status_id, :tracker_id => tracker.id, :role_id => role.id)
records << w
end
w.author = true if rule == "author"
w.assignee = true if rule == "assignee"
w.save if w.changed?
elsif w
if rule == 'always'
w.destroy
elsif rule == 'author'
if w.assignee
w.author = false
w.save if w.changed?
else
w.destroy
end
elsif rule == 'assignee'
if w.author
w.assignee = false
w.save if w.changed?
else
w.destroy
end
end
end
end
end
end
end
end
end
end
end

View File

@ -9,55 +9,11 @@
<%= content_tag('span', link_to(h(plugin.url), plugin.url), :class => 'url') unless plugin.url.blank? %>
</td>
<td class="author"><%= plugin.author_url.blank? ? h(plugin.author) : link_to(h(plugin.author), plugin.author_url) %></td>
<td class="version"><span class="icon"><%= plugin.version %></span></td>
<td class="version"><%=h plugin.version %></td>
<td class="configure"><%= link_to(l(:button_configure), plugin_settings_path(plugin)) if plugin.configurable? %></td>
</tr>
<% end %>
</table>
<p><a href="#" id="check-for-updates"><%= l(:label_check_for_updates) %></a></p>
<% else %>
<p class="nodata"><%= l(:label_no_data) %></p>
<% end %>
<%= javascript_tag do %>
$(document).ready(function(){
$("#check-for-updates").click(function(e){
e.preventDefault();
$.ajax({
dataType: "jsonp",
url: "http://www.redmine.org/plugins/check_updates",
data: <%= raw_json plugin_data_for_updates(@plugins) %>,
timeout: 3000,
beforeSend: function(){
$('#ajax-indicator').show();
},
success: function(data){
$('#ajax-indicator').hide();
$("table.plugins td.version span").addClass("unknown");
$.each(data, function(plugin_id, plugin_data){
var s = $("tr#plugin-"+plugin_id+" td.version span");
s.removeClass("icon-checked icon-warning unknown");
if (plugin_data.url) {
if (s.parent("a").length>0) {
s.unwrap();
}
s.addClass("found");
s.wrap($("<a></a>").attr("href", plugin_data.url).attr("target", "_blank"));
}
if (plugin_data.c == s.text()) {
s.addClass("icon-checked");
} else if (plugin_data.c) {
s.addClass("icon-warning");
s.attr("title", "<%= escape_javascript l(:label_latest_compatible_version) %>: "+plugin_data.c);
}
});
$("table.plugins td.version span.unknown").addClass("icon-help").attr("title", "<%= escape_javascript l(:label_unknown_plugin) %>");
},
error: function(){
$('#ajax-indicator').hide();
alert("Unable to retrieve plugin informations from www.redmine.org");
}
});
});
});
<% end if @plugins.any? %>

View File

@ -8,8 +8,8 @@
<% end -%>
</ul>
<div class="tabs-buttons" style="display:none;">
<button class="tab-left" onclick="moveTabLeft(this); return false;"></button>
<button class="tab-right" onclick="moveTabRight(this); return false;"></button>
<button class="tab-left" onclick="moveTabLeft(this);"></button>
<button class="tab-right" onclick="moveTabRight(this);"></button>
</div>
</div>

View File

@ -27,12 +27,12 @@ api.array :custom_fields do
end
if field.is_a?(IssueCustomField)
api.array :trackers do
api.trackers do
field.trackers.each do |tracker|
api.tracker :id => tracker.id, :name => tracker.name
end
end
api.array :roles do
api.roles do
field.roles.each do |role|
api.role :id => role.id, :name => role.name
end

View File

@ -1,4 +1,4 @@
<table class="list workflows transitions transitions-<%= name %>">
<table class="list transitions transitions-<%= name %>">
<thead>
<tr>
<th>
@ -31,7 +31,8 @@
<% for new_status in @statuses -%>
<% checked = workflows.detect {|w| w.old_status_id == old_status.id && w.new_status_id == new_status.id} %>
<td class="<%= checked ? 'enabled' : '' %>">
<%= transition_tag workflows, old_status, new_status, name %>
<%= check_box_tag "issue_status[#{ old_status.id }][#{new_status.id}][]", name, checked,
:class => "old-status-#{old_status.id} new-status-#{new_status.id}" %>
</td>
<% end -%>
</tr>

View File

@ -4,8 +4,8 @@
<div class="tabs">
<ul>
<li><%= link_to l(:label_status_transitions), workflows_edit_path(:role_id => @roles, :tracker_id => @trackers), :class => 'selected' %></li>
<li><%= link_to l(:label_fields_permissions), workflows_permissions_path(:role_id => @roles, :tracker_id => @trackers) %></li>
<li><%= link_to l(:label_status_transitions), {:action => 'edit', :role_id => @role, :tracker_id => @tracker}, :class => 'selected' %></li>
<li><%= link_to l(:label_fields_permissions), {:action => 'permissions', :role_id => @role, :tracker_id => @tracker} %></li>
</ul>
</div>
@ -14,14 +14,10 @@
<%= form_tag({}, :method => 'get') do %>
<p>
<label><%=l(:label_role)%>:
<%= options_for_workflow_select 'role_id[]', Role.sorted, @roles, :id => 'role_id', :class => 'expandable' %>
</label>
<a href="#" data-expands="#role_id"><%= image_tag 'bullet_toggle_plus.png' %></a>
<%= select_tag 'role_id', options_from_collection_for_select(@roles, "id", "name", @role && @role.id) %></label>
<label><%=l(:label_tracker)%>:
<%= options_for_workflow_select 'tracker_id[]', Tracker.sorted, @trackers, :id => 'tracker_id', :class => 'expandable' %>
</label>
<a href="#" data-expands="#tracker_id"><%= image_tag 'bullet_toggle_plus.png' %></a>
<%= select_tag 'tracker_id', options_from_collection_for_select(@trackers, "id", "name", @tracker && @tracker.id) %></label>
<%= submit_tag l(:button_edit), :name => nil %>
@ -31,10 +27,10 @@
</p>
<% end %>
<% if @trackers && @roles && @statuses.any? %>
<% if @tracker && @role && @statuses.any? %>
<%= form_tag({}, :id => 'workflow_form' ) do %>
<%= @trackers.map {|tracker| hidden_field_tag 'tracker_id[]', tracker.id}.join.html_safe %>
<%= @roles.map {|role| hidden_field_tag 'role_id[]', role.id}.join.html_safe %>
<%= hidden_field_tag 'tracker_id', @tracker.id %>
<%= hidden_field_tag 'role_id', @role.id %>
<%= hidden_field_tag 'used_statuses_only', params[:used_statuses_only] %>
<div class="autoscroll">
<%= render :partial => 'form', :locals => {:name => 'always', :workflows => @workflows['always']} %>
@ -58,18 +54,3 @@
<%= submit_tag l(:button_save) %>
<% end %>
<% end %>
<%= javascript_tag do %>
$("a[data-expands]").click(function(e){
e.preventDefault();
var target = $($(this).attr("data-expands"));
if (target.attr("multiple")) {
target.attr("multiple", false);
target.find("option[value=all]").show();
} else {
target.attr("multiple", true);
target.find("option[value=all]").attr("selected", false).hide();
}
});
<% end %>

View File

@ -4,8 +4,8 @@
<div class="tabs">
<ul>
<li><%= link_to l(:label_status_transitions), workflows_edit_path(:role_id => @roles, :tracker_id => @trackers) %></li>
<li><%= link_to l(:label_fields_permissions), workflows_permissions_path(:role_id => @roles, :tracker_id => @trackers), :class => 'selected' %></li>
<li><%= link_to l(:label_status_transitions), {:action => 'edit', :role_id => @role, :tracker_id => @tracker} %></li>
<li><%= link_to l(:label_fields_permissions), {:action => 'permissions', :role_id => @role, :tracker_id => @tracker}, :class => 'selected' %></li>
</ul>
</div>
@ -14,14 +14,10 @@
<%= form_tag({}, :method => 'get') do %>
<p>
<label><%=l(:label_role)%>:
<%= options_for_workflow_select 'role_id[]', Role.sorted, @roles, :id => 'role_id', :class => 'expandable' %>
</label>
<a href="#" data-expands="#role_id"><%= image_tag 'bullet_toggle_plus.png' %></a>
<%= select_tag 'role_id', options_from_collection_for_select(@roles, "id", "name", @role && @role.id) %></label>
<label><%=l(:label_tracker)%>:
<%= options_for_workflow_select 'tracker_id[]', Tracker.sorted, @trackers, :id => 'tracker_id', :class => 'expandable' %>
</label>
<a href="#" data-expands="#tracker_id"><%= image_tag 'bullet_toggle_plus.png' %></a>
<%= select_tag 'tracker_id', options_from_collection_for_select(@trackers, "id", "name", @tracker && @tracker.id) %></label>
<%= submit_tag l(:button_edit), :name => nil %>
@ -30,13 +26,13 @@
</p>
<% end %>
<% if @trackers && @roles && @statuses.any? %>
<% if @tracker && @role && @statuses.any? %>
<%= form_tag({}, :id => 'workflow_form' ) do %>
<%= @trackers.map {|tracker| hidden_field_tag 'tracker_id[]', tracker.id}.join.html_safe %>
<%= @roles.map {|role| hidden_field_tag 'role_id[]', role.id}.join.html_safe %>
<%= hidden_field_tag 'tracker_id', @tracker.id %>
<%= hidden_field_tag 'role_id', @role.id %>
<%= hidden_field_tag 'used_statuses_only', params[:used_statuses_only] %>
<div class="autoscroll">
<table class="list workflows fields_permissions">
<table class="list fields_permissions">
<thead>
<tr>
<th>
@ -66,7 +62,7 @@
</td>
<% for status in @statuses -%>
<td class="<%= @permissions[status.id][field] %>">
<%= field_permission_tag(@permissions, status, field, @roles) %>
<%= field_permission_tag(@permissions, status, field, @role) %>
<% unless status == @statuses.last %><a href="#" class="repeat-value">&#187;</a><% end %>
</td>
<% end -%>
@ -86,7 +82,7 @@
</td>
<% for status in @statuses -%>
<td class="<%= @permissions[status.id][field.id.to_s] %>">
<%= field_permission_tag(@permissions, status, field, @roles) %>
<%= field_permission_tag(@permissions, status, field, @role) %>
<% unless status == @statuses.last %><a href="#" class="repeat-value">&#187;</a><% end %>
</td>
<% end -%>
@ -107,17 +103,4 @@ $("a.repeat-value").click(function(e){
var selected = td.find("select").find(":selected").val();
td.nextAll('td').find("select").val(selected);
});
$("a[data-expands]").click(function(e){
e.preventDefault();
var target = $($(this).attr("data-expands"));
if (target.attr("multiple")) {
target.attr("multiple", false);
target.find("option[value=all]").show();
} else {
target.attr("multiple", true);
target.find("option[value=all]").attr("selected", false).hide();
}
});
<% end %>

View File

@ -72,9 +72,10 @@
#
# === More configuration options
#
# See following page:
# See the "Configuration options" at the following website for a list of the
# full options allowed:
#
# http://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration
# http://wiki.rubyonrails.org/rails/pages/HowToSendEmailsWithActionMailer
# default configuration options for all environments

View File

@ -203,30 +203,6 @@ module ActionController
end
end
if Rails::VERSION::MAJOR < 4 && RUBY_VERSION >= "2.1"
module ActiveSupport
class HashWithIndifferentAccess
def select(*args, &block)
dup.tap { |hash| hash.select!(*args, &block) }
end
def reject(*args, &block)
dup.tap { |hash| hash.reject!(*args, &block) }
end
end
class OrderedHash
def select(*args, &block)
dup.tap { |hash| hash.select!(*args, &block) }
end
def reject(*args, &block)
dup.tap { |hash| hash.reject!(*args, &block) }
end
end
end
end
require 'awesome_nested_set/version'
module CollectiveIdea

View File

@ -1112,7 +1112,3 @@ ar:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1209,7 +1209,3 @@ az:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -511,7 +511,6 @@ bg:
label_issue_updated: Обновена задача
label_issue_note_added: Добавена бележка
label_issue_status_updated: Обновено състояние
label_issue_assigned_to_updated: Задачата е с назначен нов изпълнител
label_issue_priority_updated: Обновен приоритет
label_document: Документ
label_document_new: Нов документ
@ -915,9 +914,6 @@ bg:
label_checkboxes: чек-бокс
label_link_values_to: URL (опция)
label_custom_field_select_type: "Изберете тип на обект, към който потребителското поле да бъде асоциирано"
label_check_for_updates: Проверка за нови версии
label_latest_compatible_version: Последна съвместима версия
label_unknown_plugin: Непознат плъгин
button_login: Вход
button_submit: Изпращане

View File

@ -1125,7 +1125,3 @@ bs:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1114,7 +1114,3 @@ ca:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1114,7 +1114,3 @@ cs:
setting_force_default_language_for_loggedin: Vynutit výchozí jazyk pro přihlášené uživatele
users
label_custom_field_select_type: Vybrat typ objektu, ke kterému bude přiřazeno uživatelské pole
label_issue_assigned_to_updated: Přiřazený uživatel aktualizován
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1129,7 +1129,3 @@ da:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -460,7 +460,6 @@ de:
label_changes_details: Details aller Änderungen
label_changeset_plural: Changesets
label_checkboxes: Checkboxen
label_check_for_updates: Auf Updates prüfen
label_child_revision: Nachfolger
label_chronological_order: in zeitlicher Reihenfolge
label_close_versions: Vollständige Versionen schließen
@ -569,7 +568,6 @@ de:
label_internal: Intern
label_issue: Ticket
label_issue_added: Ticket hinzugefügt
label_issue_assigned_to_updated: Bearbeiter aktualisiert
label_issue_category: Ticket-Kategorie
label_issue_category_new: Neue Kategorie
label_issue_category_plural: Ticket-Kategorien
@ -598,13 +596,11 @@ de:
label_last_n_days: "die letzten %{count} Tage"
label_last_n_weeks: letzte %{count} Wochen
label_last_week: vorige Woche
label_latest_compatible_version: Letzte kompatible Version
label_latest_revision: Aktuellste Revision
label_latest_revision_plural: Aktuellste Revisionen
label_ldap_authentication: LDAP-Authentifizierung
label_less_or_equal: "<="
label_less_than_ago: vor weniger als
label_link: Link
label_link_values_to: Werte mit URL verknüpfen
label_list: Liste
label_loading: Lade...
@ -761,7 +757,6 @@ de:
label_tracker: Tracker
label_tracker_new: Neuer Tracker
label_tracker_plural: Tracker
label_unknown_plugin: Unbekanntes Plugin
label_update_issue_done_ratios: Ticket-Fortschritt aktualisieren
label_updated_time: "Vor %{value} aktualisiert"
label_updated_time_by: "Von %{author} vor %{age} aktualisiert"
@ -1125,3 +1120,4 @@ de:
version_status_open: offen
warning_attachments_not_saved: "%{count} Datei(en) konnten nicht gespeichert werden."
label_link: Link

View File

@ -1112,7 +1112,3 @@ el:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1114,7 +1114,3 @@ en-GB:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -508,7 +508,6 @@ en:
label_issue_updated: Issue updated
label_issue_note_added: Note added
label_issue_status_updated: Status updated
label_issue_assigned_to_updated: Assignee updated
label_issue_priority_updated: Priority updated
label_document: Document
label_document_new: New document
@ -912,9 +911,6 @@ en:
label_checkboxes: checkboxes
label_link_values_to: Link values to URL
label_custom_field_select_type: Select the type of object to which the custom field is to be attached
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin
button_login: Login
button_submit: Submit

View File

@ -1145,7 +1145,3 @@ es:
setting_force_default_language_for_anonymous: Forzar lenguaje por defecto a usuarios anónimos
setting_force_default_language_for_loggedin: Forzar lenguaje por defecto para usuarios identificados
label_custom_field_select_type: Seleccione el tipo de objeto al que unir el campo personalizado
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1125,7 +1125,3 @@ et:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1113,7 +1113,3 @@ eu:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

File diff suppressed because it is too large Load Diff

View File

@ -1133,7 +1133,3 @@ fi:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -15,11 +15,8 @@ fr:
day_names: [dimanche, lundi, mardi, mercredi, jeudi, vendredi, samedi]
abbr_day_names: [dim, lun, mar, mer, jeu, ven, sam]
# Don't forget the nil at the beginning; there's no such thing as a 0th month
month_names: [~, janvier, février, mars, avril, mai, juin, juillet, août, septembre, octobre, novembre, décembre]
abbr_month_names: [~, jan., fév., mar., avr., mai, juin, juil., août, sept., oct., nov., déc.]
# Used in date_select and datime_select.
order:
- :day
- :month
@ -186,16 +183,14 @@ fr:
notice_email_sent: "Un email a été envoyé à %{value}"
notice_email_error: "Erreur lors de l'envoi de l'email (%{value})"
notice_feeds_access_key_reseted: "Votre clé d'accès aux flux Atom a été réinitialisée."
notice_api_access_key_reseted: Votre clé d'accès API a été réinitialisée.
notice_failed_to_save_issues: "%{count} demande(s) sur les %{total} sélectionnées n'ont pas pu être mise(s) à jour : %{ids}."
notice_failed_to_save_time_entries: "%{count} temps passé(s) sur les %{total} sélectionnés n'ont pas pu être mis à jour: %{ids}."
notice_failed_to_save_members: "Erreur lors de la sauvegarde des membres: %{errors}."
notice_no_issue_selected: "Aucune demande sélectionnée ! Cochez les demandes que vous voulez mettre à jour."
notice_account_pending: "Votre compte a été créé et attend l'approbation de l'administrateur."
notice_default_data_loaded: Paramétrage par défaut chargé avec succès.
notice_unable_delete_version: Impossible de supprimer cette version.
notice_unable_delete_time_entry: Impossible de supprimer le temps passé.
notice_issue_done_ratios_updated: L'avancement des demandes a été mis à jour.
notice_api_access_key_reseted: Votre clé d'accès API a été réinitialisée.
notice_gantt_chart_truncated: "Le diagramme a été tronqué car il excède le nombre maximal d'éléments pouvant être affichés (%{max})"
notice_issue_successful_create: "Demande %{id} créée."
notice_issue_update_conflict: "La demande a été mise à jour par un autre utilisateur pendant que vous la modifiez."
@ -207,22 +202,15 @@ fr:
error_scm_not_found: "L'entrée et/ou la révision demandée n'existe pas dans le dépôt."
error_scm_command_failed: "Une erreur s'est produite lors de l'accès au dépôt : %{value}"
error_scm_annotate: "L'entrée n'existe pas ou ne peut pas être annotée."
error_scm_annotate_big_text_file: Cette entrée ne peut pas être annotée car elle excède la taille maximale.
error_issue_not_found_in_project: "La demande n'existe pas ou n'appartient pas à ce projet"
error_no_tracker_in_project: "Aucun tracker n'est associé à ce projet. Vérifier la configuration du projet."
error_no_default_issue_status: "Aucun statut de demande n'est défini par défaut. Vérifier votre configuration (Administration -> Statuts de demandes)."
error_can_not_delete_custom_field: Impossible de supprimer le champ personnalisé
error_can_not_delete_tracker: Ce tracker contient des demandes et ne peut pas être supprimé.
error_can_not_remove_role: Ce rôle est utilisé et ne peut pas être supprimé.
error_can_not_reopen_issue_on_closed_version: 'Une demande assignée à une version fermée ne peut pas être réouverte'
error_can_not_archive_project: "Ce projet ne peut pas être archivé"
error_issue_done_ratios_not_updated: L'avancement des demandes n'a pas pu être mis à jour.
error_workflow_copy_source: 'Veuillez sélectionner un tracker et/ou un rôle source'
error_workflow_copy_target: 'Veuillez sélectionner les trackers et rôles cibles'
error_unable_delete_issue_status: Impossible de supprimer le statut de demande
error_unable_to_connect: Connexion impossible (%{value})
error_issue_done_ratios_not_updated: L'avancement des demandes n'a pas pu être mis à jour.
error_attachment_too_big: Ce fichier ne peut pas être attaché car il excède la taille maximale autorisée (%{max_size})
error_session_expired: "Votre session a expiré. Veuillez vous reconnecter."
warning_attachments_not_saved: "%{count} fichier(s) n'ont pas pu être sauvegardés."
mail_subject_lost_password: "Votre mot de passe %{value}"
@ -240,6 +228,7 @@ fr:
mail_subject_wiki_content_updated: "Page wiki '%{id}' mise à jour"
mail_body_wiki_content_updated: "La page wiki '%{id}' a été mise à jour par %{author}."
field_name: Nom
field_description: Description
field_summary: Résumé
@ -276,7 +265,6 @@ fr:
field_priority: Priorité
field_fixed_version: Version cible
field_user: Utilisateur
field_principal: Principal
field_role: Rôle
field_homepage: Site web
field_is_public: Public
@ -321,7 +309,6 @@ fr:
field_redirect_existing_links: Rediriger les liens existants
field_estimated_hours: Temps estimé
field_column_names: Colonnes
field_time_entries: Temps passé
field_time_zone: Fuseau horaire
field_searchable: Utilisé pour les recherches
field_default_value: Valeur par défaut
@ -333,20 +320,13 @@ fr:
field_content: Contenu
field_group_by: Grouper par
field_sharing: Partage
field_active: Actif
field_parent_issue: Tâche parente
field_member_of_group: Groupe de l'assigné
field_assigned_to_role: Rôle de l'assigné
field_text: Champ texte
field_visible: Visible
field_warn_on_leaving_unsaved: "M'avertir lorsque je quitte une page contenant du texte non sauvegardé"
field_issues_visibility: Visibilité des demandes
field_is_private: Privée
field_commit_logs_encoding: Encodage des messages de commit
field_scm_path_encoding: Encodage des chemins
field_path_to_repository: Chemin du dépôt
field_root_directory: Répertoire racine
field_cvsroot: CVSROOT
field_cvs_module: Module
field_repository_is_default: Dépôt principal
field_multiple: Valeurs multiples
field_auth_source_ldap_filter: Filtre LDAP
@ -384,8 +364,6 @@ fr:
setting_cross_project_issue_relations: Autoriser les relations entre demandes de différents projets
setting_cross_project_subtasks: Autoriser les sous-tâches dans des projets différents
setting_issue_list_default_columns: Colonnes affichées par défaut sur la liste des demandes
setting_repositories_encodings: Encodages des fichiers et des dépôts
setting_emails_header: En-tête des emails
setting_emails_footer: Pied-de-page des emails
setting_protocol: Protocole
setting_per_page_options: Options d'objets affichés par page
@ -398,7 +376,6 @@ fr:
setting_mail_handler_api_key: Clé de protection de l'API
setting_sequential_project_identifiers: Générer des identifiants de projet séquentiels
setting_gravatar_enabled: Afficher les Gravatar des utilisateurs
setting_gravatar_default: Image Gravatar par défaut
setting_diff_max_lines_displayed: Nombre maximum de lignes de diff affichées
setting_file_max_size_displayed: Taille maximum des fichiers texte affichés en ligne
setting_repository_log_display_limit: "Nombre maximum de révisions affichées sur l'historique d'un fichier"
@ -407,12 +384,12 @@ fr:
setting_new_project_user_role_id: Rôle donné à un utilisateur non-administrateur qui crée un projet
setting_default_projects_modules: Modules activés par défaut pour les nouveaux projets
setting_issue_done_ratio: Calcul de l'avancement des demandes
setting_issue_done_ratio_issue_field: 'Utiliser le champ % effectué'
setting_issue_done_ratio_issue_status: Utiliser le statut
setting_start_of_week: Jour de début des calendriers
setting_issue_done_ratio_issue_field: 'Utiliser le champ % effectué'
setting_rest_api_enabled: Activer l'API REST
setting_gravatar_default: Image Gravatar par défaut
setting_start_of_week: Jour de début des calendriers
setting_cache_formatted_text: Mettre en cache le texte formaté
setting_default_notification_option: Option de notification par défaut
setting_commit_logtime_enabled: Permettre la saisie de temps
setting_commit_logtime_activity_id: Activité pour le temps saisi
setting_gantt_items_limit: Nombre maximum d'éléments affichés sur le gantt
@ -437,7 +414,6 @@ fr:
permission_close_project: Fermer / réouvrir le projet
permission_select_project_modules: Choisir les modules
permission_manage_members: Gérer les membres
permission_manage_project_activities: Gérer les activités
permission_manage_versions: Gérer les versions
permission_manage_categories: Gérer les catégories de demandes
permission_view_issues: Voir les demandes
@ -492,6 +468,7 @@ fr:
permission_delete_messages: Supprimer les messages
permission_delete_own_messages: Supprimer ses propres messages
permission_export_wiki_pages: Exporter les pages
permission_manage_project_activities: Gérer les activités
permission_manage_subtasks: Gérer les sous-tâches
permission_manage_related_issues: Gérer les demandes associées
@ -503,8 +480,6 @@ fr:
project_module_wiki: Wiki
project_module_repository: Dépôt de sources
project_module_boards: Forums de discussion
project_module_calendar: Calendrier
project_module_gantt: Gantt
label_user: Utilisateur
label_user_plural: Utilisateurs
@ -523,13 +498,12 @@ fr:
label_issue_new: Nouvelle demande
label_issue_plural: Demandes
label_issue_view_all: Voir toutes les demandes
label_issues_by: "Demandes par %{value}"
label_issue_added: Demande ajoutée
label_issue_updated: Demande mise à jour
label_issue_note_added: Note ajoutée
label_issue_status_updated: Statut changé
label_issue_assigned_to_updated: Assigné changé
label_issue_priority_updated: Priorité changée
label_issues_by: "Demandes par %{value}"
label_document: Document
label_document_new: Nouveau document
label_document_plural: Documents
@ -622,7 +596,6 @@ fr:
label_version: Version
label_version_new: Nouvelle version
label_version_plural: Versions
label_close_versions: Fermer les versions terminées
label_confirmation: Confirmation
label_export_to: 'Formats disponibles :'
label_read: Lire...
@ -690,9 +663,6 @@ fr:
label_in_more_than: dans plus de
label_in_the_next_days: dans les prochains jours
label_in_the_past_days: dans les derniers jours
label_greater_or_equal: '>='
label_less_or_equal: '<='
label_between: entre
label_in: dans
label_today: aujourd'hui
label_all_time: toute la période
@ -718,11 +688,8 @@ fr:
label_repository_new: Nouveau dépôt
label_repository_plural: Dépôts
label_browse: Parcourir
label_branch: Branche
label_tag: Tag
label_revision: Révision
label_revision_plural: Révisions
label_revision_id: "Révision %{value}"
label_associated_revisions: Révisions associées
label_added: ajouté
label_modified: modifié
@ -732,7 +699,6 @@ fr:
label_latest_revision: Dernière révision
label_latest_revision_plural: Dernières révisions
label_view_revisions: Voir les révisions
label_view_all_revisions: Voir toutes les révisions
label_max_size: Taille maximale
label_sort_highest: Remonter en premier
label_sort_higher: Remonter
@ -758,7 +724,6 @@ fr:
label_changes_details: Détails de tous les changements
label_issue_tracking: Suivi des demandes
label_spent_time: Temps passé
label_overall_spent_time: Temps passé global
label_f_hour: "%{value} heure"
label_f_hour_plural: "%{value} heures"
label_time_tracking: Suivi du temps
@ -766,7 +731,6 @@ fr:
label_statistics: Statistiques
label_commits_per_month: Commits par mois
label_commits_per_author: Commits par auteur
label_diff: diff
label_view_diff: Voir les différences
label_diff_inline: en ligne
label_diff_side_by_side: côte à côte
@ -799,8 +763,6 @@ fr:
label_board: Forum
label_board_new: Nouveau forum
label_board_plural: Forums
label_board_locked: Verrouillé
label_board_sticky: Sticky
label_topic_plural: Discussions
label_message_plural: Messages
label_message_last: Dernier message
@ -816,8 +778,6 @@ fr:
label_language_based: Basé sur la langue de l'utilisateur
label_sort_by: "Trier par %{value}"
label_send_test_email: Envoyer un email de test
label_feeds_access_key: Clé d'accès Atom
label_missing_feeds_access_key: Clé d'accès Atom manquante
label_feeds_access_key_created_on: "Clé d'accès Atom créée il y a %{value}"
label_module_plural: Modules
label_added_time_by: "Ajouté par %{author} il y a %{age}"
@ -829,16 +789,11 @@ fr:
label_default_columns: Colonnes par défaut
label_no_change_option: (Pas de changement)
label_bulk_edit_selected_issues: Modifier les demandes sélectionnées
label_bulk_edit_selected_time_entries: Modifier les temps passés sélectionnés
label_theme: Thème
label_default: Défaut
label_search_titles_only: Uniquement dans les titres
label_user_mail_option_all: "Pour tous les événements de tous mes projets"
label_user_mail_option_selected: "Pour tous les événements des projets sélectionnés..."
label_user_mail_option_none: Aucune notification
label_user_mail_option_only_my_events: Seulement pour ce que je surveille
label_user_mail_option_only_assigned: Seulement pour ce qui m'est assigné
label_user_mail_option_only_owner: Seulement pour ce que j'ai créé
label_user_mail_no_self_notified: "Je ne veux pas être notifié des changements que j'effectue"
label_registration_activation_by_email: activation du compte par email
label_registration_manual_activation: activation manuelle du compte
@ -869,8 +824,8 @@ fr:
label_date_from_to: Du %{start} au %{end}
label_wiki_content_added: Page wiki ajoutée
label_wiki_content_updated: Page wiki mise à jour
label_group: Groupe
label_group_plural: Groupes
label_group: Groupe
label_group_new: Nouveau groupe
label_time_entry_plural: Temps passé
label_version_sharing_none: Non partagé
@ -878,14 +833,18 @@ fr:
label_version_sharing_hierarchy: Avec toute la hiérarchie
label_version_sharing_tree: Avec tout l'arbre
label_version_sharing_system: Avec tous les projets
label_update_issue_done_ratios: Mettre à jour l'avancement des demandes
label_copy_source: Source
label_copy_target: Cible
label_copy_same_as_target: Comme la cible
label_update_issue_done_ratios: Mettre à jour l'avancement des demandes
label_display_used_statuses_only: N'afficher que les statuts utilisés dans ce tracker
label_api_access_key: Clé d'accès API
label_missing_api_access_key: Clé d'accès API manquante
label_api_access_key_created_on: Clé d'accès API créée il y a %{value}
label_feeds_access_key: Clé d'accès Atom
label_missing_api_access_key: Clé d'accès API manquante
label_missing_feeds_access_key: Clé d'accès Atom manquante
label_close_versions: Fermer les versions terminées
label_revision_id: Révision %{value}
label_profile: Profil
label_subtask_plural: Sous-tâches
label_project_copy_notifications: Envoyer les notifications durant la copie du projet
@ -896,15 +855,11 @@ fr:
label_issues_visibility_all: Toutes les demandes
label_issues_visibility_public: Toutes les demandes non privées
label_issues_visibility_own: Demandes créées par ou assignées à l'utilisateur
label_git_report_last_commit: Afficher le dernier commit des fichiers et répertoires
label_parent_revision: Parent
label_child_revision: Enfant
label_export_options: Options d'exportation %{export_format}
label_copy_attachments: Copier les fichiers
label_copy_subtasks: Copier les sous-tâches
label_item_position: "%{position} sur %{count}"
label_completed_versions: Versions passées
label_search_for_watchers: Rechercher des observateurs
label_session_expiration: Expiration des sessions
label_show_closed_projects: Voir les projets fermés
label_status_transitions: Changements de statut
@ -932,9 +887,6 @@ fr:
label_checkboxes: cases à cocher
label_link_values_to: Lier les valeurs vers l'URL
label_custom_field_select_type: Selectionner le type d'objet auquel attacher le champ personnalisé
label_check_for_updates: Vérifier les mises à jour
label_latest_compatible_version: Dernière version compatible
label_unknown_plugin: Plugin inconnu
button_login: Connexion
button_submit: Soumettre
@ -948,7 +900,6 @@ fr:
button_create_and_continue: Créer et continuer
button_test: Tester
button_edit: Modifier
button_edit_associated_wikipage: "Modifier la page wiki associée: %{page_title}"
button_add: Ajouter
button_change: Changer
button_apply: Appliquer
@ -1001,8 +952,6 @@ fr:
version_status_locked: verrouillé
version_status_closed: fermé
field_active: Actif
text_select_mail_notifications: Actions pour lesquelles une notification par e-mail est envoyée
text_regexp_info: ex. ^[A-Z0-9]+$
text_min_max_length_info: 0 pour aucune restriction
@ -1010,11 +959,6 @@ fr:
text_subprojects_destroy_warning: "Ses sous-projets : %{value} seront également supprimés."
text_workflow_edit: Sélectionner un tracker et un rôle pour éditer le workflow
text_are_you_sure: Êtes-vous sûr ?
text_journal_changed: "%{label} changé de %{old} à %{new}"
text_journal_changed_no_detail: "%{label} mis à jour"
text_journal_set_to: "%{label} mis à %{value}"
text_journal_deleted: "%{label} %{old} supprimé"
text_journal_added: "%{label} %{value} ajouté"
text_tip_issue_begin_day: tâche commençant ce jour
text_tip_issue_end_day: tâche finissant ce jour
text_tip_issue_begin_end_day: tâche commençant et finissant ce jour
@ -1040,13 +984,11 @@ fr:
text_time_logged_by_changeset: "Appliqué par commit %{value}"
text_issues_destroy_confirmation: 'Êtes-vous sûr de vouloir supprimer la ou les demandes(s) selectionnée(s) ?'
text_issues_destroy_descendants_confirmation: "Cela entrainera également la suppression de %{count} sous-tâche(s)."
text_time_entries_destroy_confirmation: "Etes-vous sûr de vouloir supprimer les temps passés sélectionnés ?"
text_select_project_modules: 'Sélectionner les modules à activer pour ce projet :'
text_default_administrator_account_changed: Compte administrateur par défaut changé
text_file_repository_writable: Répertoire de stockage des fichiers accessible en écriture
text_plugin_assets_writable: Répertoire public des plugins accessible en écriture
text_rmagick_available: Bibliothèque RMagick présente (optionnelle)
text_convert_available: Binaire convert de ImageMagick présent (optionel)
text_destroy_time_entries_question: "%{hours} heures ont été enregistrées sur les demandes à supprimer. Que voulez-vous faire ?"
text_destroy_time_entries: Supprimer les heures
text_assign_time_entries_to_project: Reporter les heures sur le projet
@ -1063,16 +1005,7 @@ fr:
text_wiki_page_destroy_children: "Supprimer les sous-pages et toutes leurs descedantes"
text_wiki_page_reassign_children: "Réaffecter les sous-pages à cette page"
text_own_membership_delete_confirmation: "Vous allez supprimer tout ou partie de vos permissions sur ce projet et ne serez peut-être plus autorisé à modifier ce projet.\nEtes-vous sûr de vouloir continuer ?"
text_zoom_in: Zoom avant
text_zoom_out: Zoom arrière
text_warn_on_leaving_unsaved: "Cette page contient du texte non sauvegardé qui sera perdu si vous quittez la page."
text_scm_path_encoding_note: "Défaut : UTF-8"
text_git_repository_note: "Le dépôt est vide et local (exemples : /gitrepo, c:\\gitrepo)"
text_mercurial_repository_note: "Dépôt local (exemples : /hgrepo, c:\\hgrepo)"
text_scm_command: Commande
text_scm_command_version: Version
text_scm_config: Vous pouvez configurer les commandes des SCM dans config/configuration.yml. Redémarrer l'application après modification.
text_scm_command_not_available: Ce SCM n'est pas disponible. Vérifier les paramètres dans la section administration.
text_issue_conflict_resolution_overwrite: "Appliquer quand même ma mise à jour (les notes précédentes seront conservées mais des changements pourront être écrasés)"
text_issue_conflict_resolution_add_notes: "Ajouter mes notes et ignorer mes autres changements"
text_issue_conflict_resolution_cancel: "Annuler ma mise à jour et réafficher %{link}"
@ -1106,23 +1039,84 @@ fr:
enumeration_issue_priorities: Priorités des demandes
enumeration_doc_categories: Catégories des documents
enumeration_activities: Activités (suivi du temps)
label_greater_or_equal: ">="
label_less_or_equal: "<="
label_between: entre
label_view_all_revisions: Voir toutes les révisions
label_tag: Tag
label_branch: Branche
error_no_tracker_in_project: "Aucun tracker n'est associé à ce projet. Vérifier la configuration du projet."
error_no_default_issue_status: "Aucun statut de demande n'est défini par défaut. Vérifier votre configuration (Administration -> Statuts de demandes)."
text_journal_changed: "%{label} changé de %{old} à %{new}"
text_journal_changed_no_detail: "%{label} mis à jour"
text_journal_set_to: "%{label} mis à %{value}"
text_journal_deleted: "%{label} %{old} supprimé"
text_journal_added: "%{label} %{value} ajouté"
enumeration_system_activity: Activité système
description_filter: Filtre
description_search: Champ de recherche
description_choose_project: Projets
description_project_scope: Périmètre de recherche
description_notes: Notes
description_message_content: Contenu du message
description_query_sort_criteria_attribute: Critère de tri
label_board_sticky: Sticky
label_board_locked: Verrouillé
error_unable_delete_issue_status: Impossible de supprimer le statut de demande
error_can_not_delete_custom_field: Impossible de supprimer le champ personnalisé
error_unable_to_connect: Connexion impossible (%{value})
error_can_not_remove_role: Ce rôle est utilisé et ne peut pas être supprimé.
error_can_not_delete_tracker: Ce tracker contient des demandes et ne peut pas être supprimé.
field_principal: Principal
notice_failed_to_save_members: "Erreur lors de la sauvegarde des membres: %{errors}."
text_zoom_out: Zoom arrière
text_zoom_in: Zoom avant
notice_unable_delete_time_entry: Impossible de supprimer le temps passé.
label_overall_spent_time: Temps passé global
field_time_entries: Temps passé
project_module_gantt: Gantt
project_module_calendar: Calendrier
button_edit_associated_wikipage: "Modifier la page wiki associée: %{page_title}"
field_text: Champ texte
label_user_mail_option_only_owner: Seulement pour ce que j'ai créé
setting_default_notification_option: Option de notification par défaut
label_user_mail_option_only_my_events: Seulement pour ce que je surveille
label_user_mail_option_only_assigned: Seulement pour ce qui m'est assigné
label_user_mail_option_none: Aucune notification
field_member_of_group: Groupe de l'assigné
field_assigned_to_role: Rôle de l'assigné
setting_emails_header: En-tête des emails
label_bulk_edit_selected_time_entries: Modifier les temps passés sélectionnés
text_time_entries_destroy_confirmation: "Etes-vous sûr de vouloir supprimer les temps passés sélectionnés ?"
field_scm_path_encoding: Encodage des chemins
text_scm_path_encoding_note: "Défaut : UTF-8"
field_path_to_repository: Chemin du dépôt
field_root_directory: Répertoire racine
field_cvs_module: Module
field_cvsroot: CVSROOT
text_mercurial_repository_note: "Dépôt local (exemples : /hgrepo, c:\\hgrepo)"
text_scm_command: Commande
text_scm_command_version: Version
label_git_report_last_commit: Afficher le dernier commit des fichiers et répertoires
text_scm_config: Vous pouvez configurer les commandes des SCM dans config/configuration.yml. Redémarrer l'application après modification.
text_scm_command_not_available: Ce SCM n'est pas disponible. Vérifier les paramètres dans la section administration.
label_diff: diff
text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
description_query_sort_criteria_direction: Ordre de tri
description_project_scope: Périmètre de recherche
description_filter: Filtre
description_user_mail_notification: Option de notification
description_available_columns: Colonnes disponibles
description_selected_columns: Colonnes sélectionnées
description_all_columns: Toutes les colonnes
description_issue_category_reassign: Choisir une catégorie
description_wiki_subpages_reassign: Choisir une nouvelle page parent
description_date_range_list: Choisir une période prédéfinie
description_date_range_interval: Choisir une période
description_date_from: Date de début
description_message_content: Contenu du message
description_available_columns: Colonnes disponibles
description_all_columns: Toutes les colonnes
description_date_range_interval: Choisir une période
description_issue_category_reassign: Choisir une catégorie
description_search: Champ de recherche
description_notes: Notes
description_date_range_list: Choisir une période prédéfinie
description_choose_project: Projets
description_date_to: Date de fin
description_query_sort_criteria_attribute: Critère de tri
description_wiki_subpages_reassign: Choisir une nouvelle page parent
description_selected_columns: Colonnes sélectionnées
label_parent_revision: Parent
label_child_revision: Enfant
error_scm_annotate_big_text_file: Cette entrée ne peut pas être annotée car elle excède la taille maximale.
setting_repositories_encodings: Encodages des fichiers et des dépôts
label_search_for_watchers: Rechercher des observateurs
text_repository_identifier_info: 'Seuls les lettres minuscules (a-z), chiffres, tirets et tirets bas sont autorisés.<br />Un fois sauvegardé, l''identifiant ne pourra plus être modifié.'
text_convert_available: Binaire convert de ImageMagick présent (optionel)

View File

@ -1123,7 +1123,3 @@ gl:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1117,7 +1117,3 @@ he:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1113,7 +1113,3 @@ hr:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1131,7 +1131,3 @@
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1116,7 +1116,3 @@ id:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1111,7 +1111,3 @@ it:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -354,8 +354,8 @@ ja:
setting_attachment_max_size: 添付ファイルサイズの上限
setting_issues_export_limit: エクスポートするチケット数の上限
setting_mail_from: 送信元メールアドレス
setting_bcc_recipients: 宛先を非表示(bcc)
setting_plain_text_mail: プレインテキスト形式(HTMLなし)
setting_bcc_recipients: ブラインドカーボンコピーで受信(bcc)
setting_plain_text_mail: プレインテキストのみ(HTMLなし)
setting_host_name: ホスト名
setting_text_formatting: テキストの書式
setting_cache_formatted_text: 書式化されたテキストをキャッシュする
@ -489,12 +489,12 @@ ja:
label_issue_plural: チケット
label_issue_view_all: すべてのチケットを見る
label_issues_by: "%{value} 別のチケット"
label_issue_added: チケットの追加
label_issue_updated: チケットの更新
label_issue_added: チケットが追加されました
label_issue_updated: チケットが更新されました
label_document: 文書
label_document_new: 新しい文書
label_document_plural: 文書
label_document_added: 文書の追加
label_document_added: 文書が追加されました
label_role: ロール
label_role_plural: ロール
label_role_new: 新しいロール
@ -566,7 +566,7 @@ ja:
label_attachment_new: 新しいファイル
label_attachment_delete: ファイルを削除
label_attachment_plural: ファイル
label_file_added: ファイルの追加
label_file_added: ファイルが追加されました
label_report: レポート
label_report_plural: レポート
label_news: ニュース
@ -574,8 +574,8 @@ ja:
label_news_plural: ニュース
label_news_latest: 最新ニュース
label_news_view_all: すべてのニュースを見る
label_news_added: ニュースの追加
label_news_comment_added: ニュースへのコメント追加
label_news_added: ニュースが追加されました
label_news_comment_added: ニュースにコメントが追加されました
label_settings: 設定
label_overview: 概要
label_version: バージョン
@ -748,7 +748,7 @@ ja:
label_message_plural: メッセージ
label_message_last: 最新のメッセージ
label_message_new: 新しいメッセージ
label_message_posted: メッセージの追加
label_message_posted: メッセージが追加されました
label_reply_plural: 返答
label_send_information: アカウント情報をユーザーに送信
label_year:
@ -809,8 +809,8 @@ ja:
label_ascending: 昇順
label_descending: 降順
label_date_from_to: "%{start}から%{end}まで"
label_wiki_content_added: Wikiページの追加
label_wiki_content_updated: Wikiページの更新
label_wiki_content_added: Wikiページが追加されました
label_wiki_content_updated: Wikiページが更新されました
label_group: グループ
label_group_plural: グループ
label_group_new: 新しいグループ
@ -894,7 +894,7 @@ ja:
field_active: 有効
text_select_mail_notifications: メール通知の送信対象とする操作を選択してください。
text_select_mail_notifications: どのメール通知を送信するか、アクションを選択してください。
text_regexp_info: 例) ^[A-Z0-9]+$
text_min_max_length_info: 0だと無制限になります
text_project_destroy_confirmation: 本当にこのプロジェクトと関連データを削除しますか?
@ -995,9 +995,9 @@ ja:
label_role_anonymous: 匿名ユーザー
label_role_non_member: 非メンバー
label_issue_note_added: 注記の追加
label_issue_status_updated: ステータスの更新
label_issue_priority_updated: 優先度の更新
label_issue_note_added: 注記が追加されました
label_issue_status_updated: ステータスが更新されました
label_issue_priority_updated: 優先度が更新されました
label_issues_visibility_own: 作成者か担当者であるチケット
field_issues_visibility: 表示できるチケット
label_issues_visibility_all: すべてのチケット
@ -1136,7 +1136,3 @@ ja:
setting_force_default_language_for_anonymous: 匿名ユーザーに既定の言語を強制
setting_force_default_language_for_loggedin: ログインユーザーに既定の言語を強制
label_custom_field_select_type: カスタムフィールドを追加するオブジェクトを選択してください
label_issue_assigned_to_updated: 担当者の更新
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1156,7 +1156,3 @@ ko:
setting_force_default_language_for_anonymous: 익명 사용자의 기본 언어 강제
setting_force_default_language_for_loggedin: 로그인 사용자의 기본 언어 강제
label_custom_field_select_type: 사용자 정의 필드에 추가할 대상을 선택해주세요.
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1171,7 +1171,3 @@ lt:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1106,7 +1106,3 @@ lv:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1112,7 +1112,3 @@ mk:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1113,7 +1113,3 @@ mn:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1091,7 +1091,3 @@ nl:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1102,7 +1102,3 @@
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1132,7 +1132,3 @@ pl:
setting_force_default_language_for_loggedin: Wymuś domyślny język dla zalogowanych użytkowników
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Uaktualniono osobę przypisaną
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1131,7 +1131,3 @@ pt-BR:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1118,7 +1118,3 @@ pt:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1107,7 +1107,3 @@ ro:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1218,7 +1218,3 @@ ru:
setting_force_default_language_for_anonymous: Не определять язык для анонимных пользователей
setting_force_default_language_for_loggedin: Не определять язык для зарегистрированных пользователей
label_custom_field_select_type: Выберите тип объекта для которого будет создано настраиваемое поле
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1102,7 +1102,3 @@ sk:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1112,7 +1112,3 @@ sl:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1108,7 +1108,3 @@ sq:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1114,7 +1114,3 @@ sr-YU:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1113,7 +1113,3 @@ sr:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1150,7 +1150,3 @@ sv:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1109,7 +1109,3 @@ th:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1121,7 +1121,3 @@ tr:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1107,7 +1107,3 @@ uk:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1165,7 +1165,3 @@ vi:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -278,7 +278,7 @@
error_can_not_delete_custom_field: 無法刪除自訂欄位
error_can_not_delete_tracker: "此追蹤標籤已包含問題,無法被刪除。"
error_can_not_remove_role: "此角色已被使用,無法將其刪除。"
error_can_not_reopen_issue_on_closed_version: '派給「已結束」版本的問題,無法再將其狀態變更為「進行中」'
error_can_not_reopen_issue_on_closed_version: '派給「已結束」版本的問題,無法再將其狀態變更為「進行中」'
error_can_not_archive_project: 此專案無法被封存
error_issue_done_ratios_not_updated: "問題完成百分比未更新。"
error_workflow_copy_source: '請選擇一個來源問題追蹤標籤或角色'
@ -298,7 +298,7 @@
mail_subject_account_activation_request: Redmine 帳號啟用需求通知
mail_body_account_activation_request: "有位新用戶 (%{value}) 已經完成註冊,正等候您的審核:"
mail_subject_reminder: "您有 %{count} 個問題即將到期 (%{days})"
mail_body_reminder: "%{count} 個派給您的問題,將於 %{days} 天之內到期:"
mail_body_reminder: "%{count} 個派給您的問題,將於 %{days} 天之內到期:"
mail_subject_wiki_content_added: "'%{id}' wiki 頁面已被新增"
mail_body_wiki_content_added: "此 '%{id}' wiki 頁面已被 %{author} 新增。"
mail_subject_wiki_content_updated: "'%{id}' wiki 頁面已被更新"
@ -337,7 +337,7 @@
field_tracker: 追蹤標籤
field_subject: 主旨
field_due_date: 完成日期
field_assigned_to: 被分派者
field_assigned_to: 分派給
field_priority: 優先權
field_fixed_version: 版本
field_user: 用戶
@ -399,8 +399,8 @@
field_group_by: 結果分組方式
field_sharing: 共用
field_parent_issue: 父問題
field_member_of_group: "被派者的群組"
field_assigned_to_role: "被派者的角色"
field_member_of_group: "被派者的群組"
field_assigned_to_role: "被派者的角色"
field_text: 內容文字
field_visible: 可被看見
field_warn_on_leaving_unsaved: "提醒我將要離開的頁面中尚有未儲存的資料"
@ -469,7 +469,7 @@
setting_repository_log_display_limit: 修訂版顯示數目之最大值
setting_openid: 允許使用 OpenID 登入與註冊
setting_password_min_length: 密碼最小長度
setting_new_project_user_role_id: 管理者以外之用戶建立新專案時,將被派的角色
setting_new_project_user_role_id: 管理者以外之用戶建立新專案時,將被派的角色
setting_default_projects_modules: 新專案預設啟用的模組
setting_issue_done_ratio: 計算問題完成百分比之方式
setting_issue_done_ratio_issue_field: 依據問題完成百分比欄位
@ -481,7 +481,7 @@
setting_commit_logtime_enabled: 啟用認可中的時間記錄
setting_commit_logtime_activity_id: 時間記錄對應的活動
setting_gantt_items_limit: 甘特圖中項目顯示數量的最大值
setting_issue_group_assignment: 允許問題被派至群組
setting_issue_group_assignment: 允許問題被派至群組
setting_default_issue_start_date_to_creation_date: 設定新問題的起始日期為今天的日期
setting_commit_cross_project_ref: 允許關聯並修正其他專案的問題
setting_unsubscribe: 允許用戶取消註冊(刪除帳戶)
@ -593,7 +593,6 @@
label_issue_updated: 問題已更新
label_issue_note_added: 筆記已新增
label_issue_status_updated: 狀態已更新
label_issue_assigned_to_updated: 被分派者已更新
label_issue_priority_updated: 優先權已更新
label_document: 文件
label_document_new: 建立新文件
@ -902,7 +901,7 @@
label_user_mail_option_selected: "只提醒我所選擇專案中的事件..."
label_user_mail_option_none: "取消提醒"
label_user_mail_option_only_my_events: "只提醒我觀察中或參與中的事物"
label_user_mail_option_only_assigned: "只提醒我被派的事物"
label_user_mail_option_only_assigned: "只提醒我被派的事物"
label_user_mail_option_only_owner: "只提醒我作為擁有者的事物"
label_user_mail_no_self_notified: "不提醒我自己所做的變更"
label_registration_activation_by_email: 透過電子郵件啟用帳戶
@ -914,7 +913,7 @@
label_general: 一般
label_more: 更多 »
label_scm: 版本控管
label_plugins: 外掛程式
label_plugins: 附加元件
label_ldap_authentication: LDAP 認證
label_downloads_abbr: 下載
label_optional_description: 額外的說明
@ -957,10 +956,10 @@
label_principal_search: "搜尋用戶或群組:"
label_user_search: "搜尋用戶:"
label_additional_workflow_transitions_for_author: 用戶為作者時額外允許的流程轉換
label_additional_workflow_transitions_for_assignee: 用戶為被分派者時額外允許的流程轉換
label_additional_workflow_transitions_for_assignee: 用戶為被指定者時額外允許的流程轉換
label_issues_visibility_all: 所有問題
label_issues_visibility_public: 所有非私人問題
label_issues_visibility_own: 使用者所建立的或被派的問題
label_issues_visibility_own: 使用者所建立的或被派的問題
label_git_report_last_commit: 報告最後認可的文件和目錄
label_parent_revision: 父項
label_child_revision: 子項
@ -980,7 +979,7 @@
label_attribute_of_project: "專案是 %{name}"
label_attribute_of_issue: "問題是 %{name}"
label_attribute_of_author: "作者是 %{name}"
label_attribute_of_assigned_to: "被派者是 %{name}"
label_attribute_of_assigned_to: "被派者是 %{name}"
label_attribute_of_user: "用戶是 %{name}"
label_attribute_of_fixed_version: "版本是 %{name}"
label_cross_project_descendants: 與子專案共用
@ -997,9 +996,6 @@
label_checkboxes: 核取方塊
label_link_values_to: 連結欄位值至此網址
label_custom_field_select_type: 請選擇連結此自訂欄位的物件類型
label_check_for_updates: 檢查更新
label_latest_compatible_version: 最新的相容版本
label_unknown_plugin: 無法辨識的外掛程式
button_login: 登入
button_submit: 送出
@ -1095,10 +1091,10 @@
text_issue_added: "問題 %{id} 已被 %{author} 通報。"
text_issue_updated: "問題 %{id} 已被 %{author} 更新。"
text_wiki_destroy_confirmation: 您確定要刪除這個 wiki 和其中的所有內容?
text_issue_category_destroy_question: "有 (%{count}) 個問題被派到此分類. 請選擇您想要的動作?"
text_issue_category_destroy_question: "有 (%{count}) 個問題被派到此分類. 請選擇您想要的動作?"
text_issue_category_destroy_assignments: 移除這些問題的分類
text_issue_category_reassign_to: 重新派這些問題至其它分類
text_user_mail_option: "對於那些未被選擇的專案,將只會接收到您正在觀察中,或是參與中的問題通知。(「參與中的問題」包含您建立的或是派給您的問題)"
text_issue_category_reassign_to: 重新派這些問題至其它分類
text_user_mail_option: "對於那些未被選擇的專案,將只會接收到您正在觀察中,或是參與中的問題通知。(「參與中的問題」包含您建立的或是派給您的問題)"
text_no_configuration_data: "角色、追蹤標籤、問題狀態與流程尚未被設定完成。\n強烈建議您先載入預設的組態。將預設組態載入之後您可再變更其中之值。"
text_load_default_configuration: 載入預設組態
text_status_changed_by_changeset: "已套用至變更集 %{value}."
@ -1109,7 +1105,7 @@
text_select_project_modules: '選擇此專案可使用之模組:'
text_default_administrator_account_changed: 已變更預設管理員帳號內容
text_file_repository_writable: 可寫入附加檔案目錄
text_plugin_assets_writable: 可寫入外掛程式目錄
text_plugin_assets_writable: 可寫入附加元件目錄
text_rmagick_available: 可使用 RMagick (選配)
text_convert_available: 可使用 ImageMagick 轉換圖片格式 (選配)
text_destroy_time_entries_question: 您即將刪除的問題已報工 %{hours} 小時. 您的選擇是?

View File

@ -1113,7 +1113,3 @@ zh:
users
label_custom_field_select_type: Select the type of object to which the custom field
is to be attached
label_issue_assigned_to_updated: Assignee updated
label_check_for_updates: Check for updates
label_latest_compatible_version: Latest compatible version
label_unknown_plugin: Unknown plugin

View File

@ -1441,7 +1441,7 @@ It is in v2.5.0.
* #819: Add a body ID and class to all pages
* #871: Commit new CSS styles!
* #3301: Add favicon to base layout
* #4656: On Issue#show page, clicking on "Add related issue" should focus on the input
* #4656: On Issue#show page, clicking on “Add related issueâ€<C3A2> should focus on the input
* #4896: Project identifier should be a limited field
* #5084: Filter all isssues by projects
* #5477: Replace Test::Unit::TestCase with ActiveSupport::TestCase
@ -2450,7 +2450,7 @@ It is in v2.5.0.
* Search engines now supports pagination. Results are sorted in reverse chronological order
* Added "Estimated hours" attribute on issues
* A category with assigned issue can now be deleted. 2 options are proposed: remove assignments or reassign issues to another category
* Forum notifications are now also sent to the authors of the thread, even if they don't watch the board
* Forum notifications are now also sent to the authors of the thread, even if they don�t watch the board
* Added an application setting to specify the application protocol (http or https) used to generate urls in emails
* Gantt chart: now starts at the current month by default
* Gantt chart: month count and zoom factor are automatically saved as user preferences
@ -2458,7 +2458,7 @@ It is in v2.5.0.
* Added wiki index by date
* Added preview on add/edit issue form
* Emails footer can now be customized from the admin interface (Admin -> Email notifications)
* Default encodings for repository files can now be set in application settings (used to convert files content and diff to UTF-8 so that they're properly displayed)
* Default encodings for repository files can now be set in application settings (used to convert files content and diff to UTF-8 so that they�re properly displayed)
* Calendar: first day of week can now be set in lang files
* Automatic closing of duplicate issues
* Added a cross-project issue list
@ -2470,7 +2470,7 @@ It is in v2.5.0.
* Added some accesskeys
* Added "Float" as a custom field format
* Added basic Theme support
* Added the ability to set the "done ratio" of issues fixed by commit (Nikolay Solakov)
* Added the ability to set the �done ratio� of issues fixed by commit (Nikolay Solakov)
* Added custom fields in issue related mail notifications
* Email notifications are now sent in plain text and html
* Gantt chart can now be exported to a graphic file (png). This functionality is only available if RMagick is installed.
@ -2503,7 +2503,7 @@ It is in v2.5.0.
* Added Korean translation (Choi Jong Yoon)
* Fixed: the link to delete issue relations is displayed even if the user is not authorized to delete relations
* Performance improvement on calendar and gantt
* Fixed: wiki preview doesn't work on long entries
* Fixed: wiki preview doesn�t work on long entries
* Fixed: queries with multiple custom fields return no result
* Fixed: Can not authenticate user against LDAP if its DN contains non-ascii characters
* Fixed: URL with ~ broken in wiki formatting
@ -2514,7 +2514,7 @@ It is in v2.5.0.
* per project forums added
* added the ability to archive projects
* added "Watch" functionality on issues. It allows users to receive notifications about issue changes
* added �Watch� functionality on issues. It allows users to receive notifications about issue changes
* custom fields for issues can now be used as filters on issue list
* added per user custom queries
* commit messages are now scanned for referenced or fixed issue IDs (keywords defined in Admin -> Settings)
@ -2555,7 +2555,7 @@ It is in v2.5.0.
* added swedish translation (Thomas Habets)
* italian translation update (Alessio Spadaro)
* japanese translation update (Satoru Kurashiki)
* fixed: error on history atom feed when there's no notes on an issue change
* fixed: error on history atom feed when there�s no notes on an issue change
* fixed: error in journalizing an issue with longtext custom fields (Postgresql)
* fixed: creation of Oracle schema
* fixed: last day of the month not included in project activity

View File

@ -87,7 +87,7 @@ module Redmine
a = Attachment.find_by_token(token)
next unless a
a.filename = attachment['filename'] unless attachment['filename'].blank?
a.content_type = attachment['content_type'] unless attachment['content_type'].blank?
a.content_type = attachment['content_type']
end
next unless a
a.description = attachment['description'].to_s.strip

View File

@ -81,7 +81,7 @@ module Redmine
end
end
# Returns the mail addresses of users that should be notified
# Returns the mail adresses of users that should be notified
def recipients
notified = project.notified_users
notified.reject! {|user| !visible?(user)}

View File

@ -1,13 +0,0 @@
Autotest.add_hook :initialize do |at|
at.clear_mappings
at.add_mapping %r%^lib/(.*)\.rb$% do |_, m|
at.files_matching %r%^test/#{m[1]}_test.rb$%
end
at.add_mapping(%r%^test/.*\.rb$%) {|filename, _| filename }
at.add_mapping %r%^test/fixtures/(.*)s.yml% do |_, _|
at.files_matching %r%^test/.*\.rb$%
end
end

View File

@ -1,8 +0,0 @@
awesome_nested_set.sqlite3.db
spec/debug.log
rdoc
coverage
pkg
*.gem
Gemfile.lock
gemfiles/Gemfile*.lock

View File

@ -1,22 +0,0 @@
language: ruby
notifications:
email:
- parndt@gmail.com
script: bundle exec rspec spec
env:
- DB=sqlite3
- DB=sqlite3mem
- DB=postgresql
- DB=mysql
rvm:
- 2.0.0
- 1.9.3
- 1.8.7
- rbx-19mode
- jruby-19mode
- rbx-18mode
- jruby-18mode
gemfile:
- gemfiles/Gemfile.rails-3.0.rb
- gemfiles/Gemfile.rails-3.1.rb
- gemfiles/Gemfile.rails-3.2.rb

View File

@ -1,57 +0,0 @@
2.1.6
* Fixed rebuild! when there is a default_scope with order [Adrian Serafin]
* Testing with stable bundler, ruby 2.0, MySQL and PostgreSQL [Philip Arndt]
* Optimized move_to for large trees [ericsmith66]
2.1.5
* Worked around issues where AR#association wasn't present on Rails 3.0.x. [Philip Arndt]
* Adds option 'order_column' which defaults to 'left_column_name'. [gudata]
* Added moving with order functionality. [Sytse Sijbrandij]
* Use tablename in all select queries. [Mikhail Dieterle]
* Made sure all descendants' depths are updated when moving parent, not just immediate child. [Phil Thompson]
* Add documentation of the callbacks. [Tobias Maier]
2.1.4
* nested_set_options accept both Class & AR Relation. [Semyon Perepelitsa]
* Reduce the number of queries triggered by the canonical usage of `i.level` in the `nested_set` helpers. [thedarkone]
* Specifically require active_record [Bogdan Gusiev]
* compute_level now checks for a non nil association target. [Joel Nimety]
2.1.3
* Update child depth when parent node is moved. [Amanda Wagener]
* Added move_to_child_with_index. [Ben Zhang]
* Optimised self_and_descendants for when there's an index on lft. [Mark Torrance]
* Added support for an unsaved record to return the right 'root'. [Philip Arndt]
2.1.2
* Fixed regressions introduced. [Philip Arndt]
2.1.1
* Added 'depth' which indicates how many levels deep the node is.
This only works when you have a column called 'depth' in your table,
otherwise it doesn't set itself. [Philip Arndt]
* Rails 3.2 support added. [Gabriel Sobrinho]
* Oracle compatibility added. [Pikender Sharma]
* Adding row locking to deletion, locking source of pivot values, and adding retry on collisions. [Markus J. Q. Roberts]
* Added method and helper for sorting children by column. [bluegod]
* Fixed .all_roots_valid? to work with Postgres. [Joshua Clayton]
* Made compatible with polymorphic belongs_to. [Graham Randall]
* Added in the association callbacks to the children :has_many association. [Michael Deering]
* Modified helper to allow using array of objects as argument. [Rahmat Budiharso]
* Fixed cases where we were calling attr_protected. [Jacob Swanner]
* Fixed nil cases involving lft and rgt. [Stuart Coyle] and [Patrick Morgan]
2.0.2
* Fixed deprecation warning under Rails 3.1 [Philip Arndt]
* Converted Test::Unit matchers to RSpec. [Uģis Ozols]
* Added inverse_of to associations to improve performance rendering trees. [Sergio Cambra]
* Added row locking and fixed some race conditions. [Markus J. Q. Roberts]
2.0.1
* Fixed a bug with move_to not using nested_set_scope [Andreas Sekine]
2.0.0.pre
* Expect Rails 3
* Changed how callbacks work. Returning false in a before_move action does not block save operations. Use a validation or exception in the callback if you need that.
* Switched to RSpec
* Remove use of Comparable

View File

@ -1,31 +0,0 @@
gem 'combustion', :github => 'pat/combustion'
source 'https://rubygems.org'
gemspec :path => File.expand_path('../', __FILE__)
platforms :jruby do
gem 'activerecord-jdbcsqlite3-adapter'
gem 'activerecord-jdbcmysql-adapter'
gem 'activerecord-jdbcpostgresql-adapter'
gem 'jruby-openssl'
end
platforms :ruby do
gem 'sqlite3'
gem 'mysql2', (MYSQL2_VERSION if defined? MYSQL2_VERSION)
gem 'pg'
end
RAILS_VERSION = nil unless defined? RAILS_VERSION
gem 'railties', RAILS_VERSION
gem 'activerecord', RAILS_VERSION
gem 'actionpack', RAILS_VERSION
# Add Oracle Adapters
# gem 'ruby-oci8'
# gem 'activerecord-oracle_enhanced-adapter'
# Debuggers
# gem 'pry'
# gem 'pry-nav'

View File

@ -1,20 +0,0 @@
Copyright (c) 2007-2011 Collective Idea
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,153 +0,0 @@
= AwesomeNestedSet
Awesome Nested Set is an implementation of the nested set pattern for ActiveRecord models. It is replacement for acts_as_nested_set and BetterNestedSet, but more awesome.
Version 2 supports Rails 3. Gem versions prior to 2.0 support Rails 2.
== What makes this so awesome?
This is a new implementation of nested set based off of BetterNestedSet that fixes some bugs, removes tons of duplication, adds a few useful methods, and adds STI support.
== Installation
Add to your Gemfile:
gem 'awesome_nested_set'
== Usage
To make use of awesome_nested_set, your model needs to have 3 fields: lft, rgt, and parent_id.
You can also have an optional field: depth:
class CreateCategories < ActiveRecord::Migration
def self.up
create_table :categories do |t|
t.string :name
t.integer :parent_id
t.integer :lft
t.integer :rgt
t.integer :depth # this is optional.
end
end
def self.down
drop_table :categories
end
end
Enable the nested set functionality by declaring acts_as_nested_set on your model
class Category < ActiveRecord::Base
acts_as_nested_set
end
Run `rake rdoc` to generate the API docs and see CollectiveIdea::Acts::NestedSet for more info.
== Callbacks
There are three callbacks called when moving a node. `before_move`, `after_move` and `around_move`.
class Category < ActiveRecord::Base
acts_as_nested_set
after_move :rebuild_slug
around_move :da_fancy_things_around
private
def rebuild_slug
# do whatever
end
def da_fancy_things_around
# do something...
yield # actually moves
# do something else...
end
end
Beside this there are also hooks to act on the newly added or removed children.
class Category < ActiveRecord::Base
acts_as_nested_set :before_add => :do_before_add_stuff,
:after_add => :do_after_add_stuff,
:before_remove => :do_before_remove_stuff,
:after_remove => :do_after_remove_stuff
private
def do_before_add_stuff(child_node)
# do whatever with the child
end
def do_after_add_stuff(child_node)
# do whatever with the child
end
def do_before_remove_stuff(child_node)
# do whatever with the child
end
def do_after_remove_stuff(child_node)
# do whatever with the child
end
end
== Protecting attributes from mass assignment
It's generally best to "white list" the attributes that can be used in mass assignment:
class Category < ActiveRecord::Base
acts_as_nested_set
attr_accessible :name, :parent_id
end
If for some reason that is not possible, you will probably want to protect the lft and rgt attributes:
class Category < ActiveRecord::Base
acts_as_nested_set
attr_protected :lft, :rgt
end
== Conversion from other trees
Coming from acts_as_tree or another system where you only have a parent_id? No problem. Simply add the lft & rgt fields as above, and then run
Category.rebuild!
Your tree will be converted to a valid nested set. Awesome!
== View Helper
The view helper is called #nested_set_options.
Example usage:
<%= f.select :parent_id, nested_set_options(Category, @category) {|i| "#{'-' * i.level} #{i.name}" } %>
<%= select_tag 'parent_id', options_for_select(nested_set_options(Category) {|i| "#{'-' * i.level} #{i.name}" } ) %>
See CollectiveIdea::Acts::NestedSet::Helper for more information about the helpers.
== References
You can learn more about nested sets at: http://threebit.net/tutorials/nestedset/tutorial1.html
== How to contribute
If you find what you might think is a bug:
1. Check the GitHub issue tracker to see if anyone else has had the same issue.
https://github.com/collectiveidea/awesome_nested_set/issues/
2. If you don't see anything, create an issue with information on how to reproduce it.
If you want to contribute an enhancement or a fix:
1. Fork the project on GitHub.
https://github.com/collectiveidea/awesome_nested_set/
2. Make your changes with tests.
3. Commit the changes without making changes to the Rakefile, VERSION, or any other files that aren't related to your enhancement or fix
4. Send a pull request.
Copyright ©2008 Collective Idea, released under the MIT license

View File

@ -1,32 +0,0 @@
# -*- encoding: utf-8 -*-
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
require 'rubygems'
require 'bundler/setup'
require 'awesome_nested_set/version'
task :default => :spec
task :spec do
%w(3.0 3.1 3.2).each do |rails_version|
puts "\n" + (cmd = "BUNDLE_GEMFILE='gemfiles/Gemfile.rails-#{rails_version}.rb' bundle exec rspec spec")
system cmd
end
end
task :build do
system "gem build awesome_nested_set.gemspec"
end
task :release => :build do
system "gem push awesome_nested_set-#{ActsAsGeocodable::VERSION}.gem"
end
require 'rdoc/task'
desc 'Generate documentation for the awesome_nested_set plugin.'
Rake::RDocTask.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'AwesomeNestedSet'
rdoc.options << '--line-numbers' << '--inline-source'
rdoc.rdoc_files.include('README.rdoc')
rdoc.rdoc_files.include('lib/**/*.rb')
end

View File

@ -1,24 +0,0 @@
# -*- encoding: utf-8 -*-
require File.expand_path('../lib/awesome_nested_set/version', __FILE__)
Gem::Specification.new do |s|
s.name = %q{awesome_nested_set}
s.version = ::AwesomeNestedSet::VERSION
s.authors = ["Brandon Keepers", "Daniel Morrison", "Philip Arndt"]
s.description = %q{An awesome nested set implementation for Active Record}
s.email = %q{info@collectiveidea.com}
s.extra_rdoc_files = %w[README.rdoc]
s.files = Dir.glob("lib/**/*") + %w(MIT-LICENSE README.rdoc CHANGELOG)
s.homepage = %q{http://github.com/collectiveidea/awesome_nested_set}
s.rdoc_options = ["--main", "README.rdoc", "--inline-source", "--line-numbers"]
s.require_paths = ["lib"]
s.rubygems_version = %q{1.3.6}
s.summary = %q{An awesome nested set implementation for Active Record}
s.license = %q{MIT}
s.add_runtime_dependency 'activerecord', '>= 3.0.0'
s.add_development_dependency 'rspec-rails', '~> 2.12'
s.add_development_dependency 'rake', '~> 10'
s.add_development_dependency 'combustion', '>= 0.3.3'
end

View File

@ -1,4 +0,0 @@
MYSQL2_VERSION = '~> 0.2.18'
RAILS_VERSION = '~> 3.0.17'
eval File.read(File.expand_path('../../Gemfile', __FILE__))

View File

@ -1,4 +0,0 @@
MYSQL2_VERSION = '>= 0.3'
RAILS_VERSION = '~> 3.1.0'
eval File.read(File.expand_path('../../Gemfile', __FILE__))

View File

@ -1,4 +0,0 @@
MYSQL2_VERSION = '>= 0.3'
RAILS_VERSION = '~> 3.2.0'
eval File.read(File.expand_path('../../Gemfile', __FILE__))

View File

@ -1 +0,0 @@
require File.dirname(__FILE__) + '/lib/awesome_nested_set'

Some files were not shown because too many files have changed in this diff Show More