Compare commits
47 Commits
Author | SHA1 | Date |
---|---|---|
Kolan Sh | 9ec90a50d4 | |
Jean-Philippe Lang | 9f3239a25a | |
Jean-Philippe Lang | 048036da81 | |
Jean-Philippe Lang | a8d3f491e6 | |
Jean-Philippe Lang | 1807093b75 | |
Jean-Philippe Lang | 665767db44 | |
Jean-Philippe Lang | 23ae3d1fa6 | |
Jean-Philippe Lang | 2344dfe7f7 | |
Jean-Philippe Lang | 33a7f6bc11 | |
Jean-Philippe Lang | 65c9223fe5 | |
Jean-Philippe Lang | df7f00afce | |
Jean-Philippe Lang | c5b52ec29f | |
Jean-Philippe Lang | 58786e8d80 | |
Toshi MARUYAMA | d10f17f216 | |
Toshi MARUYAMA | 323527beb7 | |
Toshi MARUYAMA | 0d3cb4e8e1 | |
Toshi MARUYAMA | 75855f21bb | |
Jean-Philippe Lang | c61a6a707f | |
Jean-Philippe Lang | 4aab2ed303 | |
Toshi MARUYAMA | e0a8e692da | |
Toshi MARUYAMA | 5e06374eb7 | |
Toshi MARUYAMA | 9686c078f9 | |
Toshi MARUYAMA | b3ac538a18 | |
Toshi MARUYAMA | a43716d6bb | |
Jean-Philippe Lang | 91a161fadb | |
Jean-Philippe Lang | c75e07f8d3 | |
Jean-Philippe Lang | dbe03f5443 | |
Jean-Philippe Lang | 5b1799f245 | |
Jean-Philippe Lang | 8b1a61d856 | |
Jean-Philippe Lang | 9cb17f598d | |
Toshi MARUYAMA | 0d5dd6fc19 | |
Toshi MARUYAMA | fcc1f198e7 | |
Toshi MARUYAMA | 41667cd5de | |
Toshi MARUYAMA | 51175ede2c | |
Toshi MARUYAMA | 9abdbd423d | |
Jean-Philippe Lang | 63212e5c16 | |
Jean-Philippe Lang | 88b3872179 | |
Jean-Philippe Lang | 066e9b7f94 | |
Jean-Philippe Lang | 805debddd0 | |
Jean-Philippe Lang | 01aa2db0af | |
Toshi MARUYAMA | 645749eea8 | |
Jean-Philippe Lang | 8b9a2ff871 | |
Jean-Philippe Lang | 97434b5aaa | |
Jean-Philippe Lang | 4308dd7d4c | |
Jean-Philippe Lang | 449a92640b | |
Jean-Philippe Lang | 448c0a72ee | |
Jean-Philippe Lang | 20180db41e |
|
@ -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:
|
||||
|
|
8
Gemfile
8
Gemfile
|
@ -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"
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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? %>
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 %>
|
||||
|
|
|
@ -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">»</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">»</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 %>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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: Изпращане
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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} 小時. 您的選擇是?
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)}
|
||||
|
|
|
@ -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
|
|
@ -1,8 +0,0 @@
|
|||
awesome_nested_set.sqlite3.db
|
||||
spec/debug.log
|
||||
rdoc
|
||||
coverage
|
||||
pkg
|
||||
*.gem
|
||||
Gemfile.lock
|
||||
gemfiles/Gemfile*.lock
|
|
@ -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
|
|
@ -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
|
|
@ -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'
|
|
@ -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.
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -1,4 +0,0 @@
|
|||
MYSQL2_VERSION = '~> 0.2.18'
|
||||
RAILS_VERSION = '~> 3.0.17'
|
||||
|
||||
eval File.read(File.expand_path('../../Gemfile', __FILE__))
|
|
@ -1,4 +0,0 @@
|
|||
MYSQL2_VERSION = '>= 0.3'
|
||||
RAILS_VERSION = '~> 3.1.0'
|
||||
|
||||
eval File.read(File.expand_path('../../Gemfile', __FILE__))
|
|
@ -1,4 +0,0 @@
|
|||
MYSQL2_VERSION = '>= 0.3'
|
||||
RAILS_VERSION = '~> 3.2.0'
|
||||
|
||||
eval File.read(File.expand_path('../../Gemfile', __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
Loading…
Reference in New Issue