diff --git a/app/controllers/account_controller.rb b/app/controllers/account_controller.rb index b1e502e55a..ffc0a7d817 100644 --- a/app/controllers/account_controller.rb +++ b/app/controllers/account_controller.rb @@ -20,9 +20,9 @@ class AccountController < ApplicationController # Login request and validation def login - if request.get? - logout_user - else + if User.current.logged? + redirect_to home_url + elsif request.post? authenticate_user end end @@ -143,7 +143,12 @@ class AccountController < ApplicationController user = User.try_to_login(params[:username], params[:password]) if user.nil? - invalid_credentials + u = User.find_by_login(params[:username]) + if u && !u.active? && u.check_password?(params[:password]) + inactive_account + else + invalid_credentials + end elsif user.new_record? onthefly_creation_failed(user, {:login => user.login, :auth_source_id => user.auth_source_id }) else @@ -237,6 +242,11 @@ class AccountController < ApplicationController flash.now[:error] = l(:notice_account_invalid_creditentials) end + def inactive_account + logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc} (INACTIVE)" + flash.now[:error] = l(:notice_account_inactive) + end + # Register a user for email activation. # # Pass a block for behavior when a user fails to save diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index ab3e0d48da..9b953aaa9f 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -24,10 +24,12 @@ class AdminController < ApplicationController menu_item :info, :only => [:info] def index - @no_configuration_data = Redmine::DefaultData::Loader::no_data? + redirect_to :action => 'projects' end def projects + @no_configuration_data = Redmine::DefaultData::Loader::no_data? + @status = params[:status] ? params[:status].to_i : 1 c = ARCondition.new(@status == 0 ? "status <> 0" : ["status = ?", @status]) @@ -83,4 +85,15 @@ class AdminController < ApplicationController [:text_rmagick_available, Object.const_defined?(:Magick)] ] end + + def default_breadcrumb + case params[:action] + when 'projects' + l(:label_project_plural) + when 'plugins' + l(:label_plugins) + when 'info' + l(:label_information) + end + end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ca9c20f23a..2d3fb63d19 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -307,6 +307,34 @@ class ApplicationController < ActionController::Base return false end + def render_500(options={}) + message = t(:notice_internal_server_error, :app_title => Setting.app_title) + + if $!.is_a?(ActionView::ActionViewError) + @template.instance_variable_set("@project", nil) + @template.instance_variable_set("@status", 500) + @template.instance_variable_set("@message", message) + else + @project = nil + end + + render_error({:message => message}.merge(options)) + return false + end + + def render_optional_error_file(status_code) + user_setup unless User.current.id == session[:user_id] + + case status_code + when :not_found + render_404 + when :internal_server_error + render_500 + else + super + end + end + # Renders an error response def render_error(arg) arg = {:message => arg} unless arg.is_a?(Hash) @@ -502,4 +530,13 @@ class ApplicationController < ActionController::Base def pick_layout(*args) api_request? ? nil : super end + + def default_breadcrumb + name = l("label_" + self.class.name.gsub("Controller", "").underscore.singularize + "_plural") + if name =~ /translation missing/i + name = l("label_" + self.class.name.gsub("Controller", "").underscore.singularize) + end + name + end + helper_method :default_breadcrumb end diff --git a/app/controllers/auth_sources_controller.rb b/app/controllers/auth_sources_controller.rb index ba468826d8..66cb344ddd 100644 --- a/app/controllers/auth_sources_controller.rb +++ b/app/controllers/auth_sources_controller.rb @@ -81,4 +81,8 @@ class AuthSourcesController < ApplicationController def auth_source_class AuthSource end + + def default_breadcrumb + l(:label_auth_source_plural) + end end diff --git a/app/controllers/enumerations_controller.rb b/app/controllers/enumerations_controller.rb index 5749a35e7a..6e7aedcfbc 100644 --- a/app/controllers/enumerations_controller.rb +++ b/app/controllers/enumerations_controller.rb @@ -84,4 +84,8 @@ class EnumerationsController < ApplicationController # flash[:error] = 'Unable to delete enumeration' # redirect_to :action => 'index' end + + def default_breadcrumb + l(:label_enumerations) + end end diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 978891b96a..42e6f1f3bc 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -13,6 +13,8 @@ #++ class IssuesController < ApplicationController + EXPORT_FORMATS = %w[atom rss api xls csv pdf] + menu_item :new_issue, :only => [:new, :create] menu_item :view_all_issues, :only => [:all] default_search_scope :issues @@ -22,6 +24,7 @@ class IssuesController < ApplicationController before_filter :check_project_uniqueness, :only => [:move, :perform_move] before_filter :find_project, :only => [:new, :create] before_filter :authorize, :except => [:index, :all] + before_filter :protect_from_unauthorized_export, :only => [:index, :all] before_filter :find_optional_project, :only => [:index, :all] before_filter :check_for_default_issue_status, :only => [:new, :create] before_filter :build_new_issue_from_params, :only => [:new, :create] @@ -52,7 +55,7 @@ class IssuesController < ApplicationController verify :method => :put, :only => :update, :render => {:nothing => true, :status => :method_not_allowed } def index - sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria) + sort_init(@query.sort_criteria.empty? ? [['parent', 'desc']] : @query.sort_criteria) sort_update(@query.sortable_columns) if @query.valid? @@ -93,11 +96,12 @@ class IssuesController < ApplicationController def all params[:set_filter] = '1' + retrieve_query index end def show - @journals = @issue.journals.find(:all, :include => [:user], :order => "#{Journal.table_name}.created_at ASC") + @journals = @issue.journals.changing.find(:all, :include => [:user], :order => "#{Journal.table_name}.created_at ASC") @journals.reverse! if User.current.wants_comments_in_reverse_order? @changesets = @issue.changesets.visible.all @changesets.reverse! if User.current.wants_comments_in_reverse_order? @@ -319,4 +323,16 @@ private attributes[:custom_field_values].reject! {|k,v| v.blank?} if attributes[:custom_field_values] attributes end + + def protect_from_unauthorized_export + return true unless EXPORT_FORMATS.include? params[:format] + + find_optional_project + return true if User.current.allowed_to? :export_issues, @project + + # otherwise deny access + params[:format] = 'html' + deny_access + return false + end end diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 6b4efbec2a..e2b831cdf7 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -110,7 +110,7 @@ class MessagesController < ApplicationController content = "#{ll(Setting.default_language, :text_user_wrote, user)}\\n> " content << text.to_s.strip.gsub(%r{
((.|\s)*?)
}m, '[...]').gsub('"', '\"').gsub(/(\r?\n|\r\n?)/, "\\n> ") + "\\n\\n" render(:update) { |page| - page << "$('reply_subject').value = \"#{subject}\";" + page << "$('message_subject').value = \"#{subject}\";" page.<< "$('message_content').value = \"#{content}\";" page.show 'reply' page << "Form.Element.focus('message_content');" diff --git a/app/controllers/my_controller.rb b/app/controllers/my_controller.rb index f123a73c3c..b6fb1da807 100644 --- a/app/controllers/my_controller.rb +++ b/app/controllers/my_controller.rb @@ -184,4 +184,8 @@ class MyController < ApplicationController end render :nothing => true end + + def default_breadcrumb + l(:label_my_account) + end end diff --git a/app/controllers/news_controller.rb b/app/controllers/news_controller.rb index 32e4590b47..e59690b49c 100644 --- a/app/controllers/news_controller.rb +++ b/app/controllers/news_controller.rb @@ -22,6 +22,8 @@ class NewsController < ApplicationController before_filter :find_optional_project, :only => :index accept_key_auth :index + menu_item :new_news, :only => [:new, :create] + def index case params[:format] diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index 943ba77e78..21ececb995 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -72,7 +72,7 @@ class ReportsController < ApplicationController @field = "project_id" @rows = @project.descendants.visible @data = Issue.by_subproject(@project) || [] - @report_title = l(:field_subproject) + @report_title = l(:label_subproject_plural) end respond_to do |format| @@ -89,4 +89,8 @@ class ReportsController < ApplicationController def find_issue_statuses @statuses = IssueStatus.find(:all, :order => 'position') end + + def default_breadcrumb + l(:label_summary) + end end diff --git a/app/controllers/settings_controller.rb b/app/controllers/settings_controller.rb index 0bf5180b84..522ce6ec66 100644 --- a/app/controllers/settings_controller.rb +++ b/app/controllers/settings_controller.rb @@ -58,4 +58,8 @@ class SettingsController < ApplicationController rescue Redmine::PluginNotFound render_404 end + + def default_breadcrumb + l(:label_settings) + end end diff --git a/app/controllers/watchers_controller.rb b/app/controllers/watchers_controller.rb index e9479f435b..52e2b8b503 100644 --- a/app/controllers/watchers_controller.rb +++ b/app/controllers/watchers_controller.rb @@ -63,7 +63,7 @@ class WatchersController < ApplicationController private def find_project - klass = Object.const_get(params[:object_type].camelcase) + klass = params[:object_type].camelcase.constantize return false unless klass.respond_to?('watched_by') @watched = klass.find(params[:object_id]) @project = @watched.project diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index e9816e25ca..0c6be91ef6 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -34,8 +34,25 @@ module ApplicationHelper # @param [Hash] options Hash params. This will checked by authorize_for to see if the user is authorized # @param [optional, Hash] html_options Options passed to link_to # @param [optional, Hash] parameters_for_method_reference Extra parameters for link_to - def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference) - link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller] || params[:controller], options[:action]) + # + # When a block is given, skip the name parameter + def link_to_if_authorized(*args, &block) + name = args.shift unless block_given? + options = args.shift || {} + html_options = args.shift + parameters_for_method_reference = args + + return unless authorize_for(options[:controller] || params[:controller], options[:action]) + + if block_given? + link_to(options, html_options, *parameters_for_method_reference, &block) + else + link_to(name, options, html_options, *parameters_for_method_reference) + end + end + + def li_unless_nil(link) + content_tag(:li, link) if link end # Display a link to remote if user is authorized @@ -105,11 +122,10 @@ module ApplicationHelper subject = truncate(subject, :length => options[:truncate]) end end - closed = issue.closed? ? content_tag(:span, l(:label_closed_issues), :class => "hidden-for-sighted") : nil - s = link_to "#{h(issue.tracker)} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue}, + closed = issue.closed? ? content_tag(:span, l(:label_closed_issues), :class => "hidden-for-sighted") : "" + s = link_to closed + options[:before_text].to_s + "#{h(issue.tracker)} ##{issue.id}", {:controller => "issues", :action => "show", :id => issue}, :class => issue.css_classes, :title => title - s << closed unless closed.nil? s << ": #{h subject}" if subject s = "#{h issue.project} - " + s if options[:project] s @@ -159,12 +175,18 @@ module ApplicationHelper # link_to_project(project, {:only_path => false}, :class => "project") # => 3rd arg adds html options # link_to_project(project, {}, :class => "project") # => html options with default url (project overview) # - def link_to_project(project, options={}, html_options = nil) + def link_to_project(project, options={}, html_options = nil, show_icon = false) + if show_icon && User.current.member_of?(project) + icon = image_tag('fav.png', :alt => l(:description_my_project), :title => l(:description_my_project)) + else + icon = "" + end + if project.active? url = {:controller => 'projects', :action => 'show', :id => project}.merge(options) - link_to(h(project), url, html_options) + icon + link_to(h(project), url, html_options) else - h(project) + icon + h(project) end end @@ -232,11 +254,11 @@ module ApplicationHelper # Renders flash messages def render_flash_messages - s = '' - flash.each do |k,v| - s << content_tag('div', content_tag('a',v, :href => 'javascript:;'), :class => "flash #{k}") + if User.current.impaired? + flash.map { |k,v| content_tag('div', content_tag('a', v, :href => 'javascript:;'), :class => "flash #{k}") }.join + else + flash.map { |k,v| content_tag('div', v, :class => "flash #{k}") }.join end - s end # Renders tabs and their content @@ -268,7 +290,7 @@ module ApplicationHelper def project_tree_options_for_select(projects, options = {}) s = '' project_tree(projects) do |project, level| - name_prefix = (level > 0 ? (' ' * 2 * level + '» ') : '') + name_prefix = (level > 0 ? (' ' * 3 * level + '» ') : '') tag_options = {:value => project.id, :title => h(project)} if project == options[:selected] || (options[:selected].respond_to?(:include?) && options[:selected].include?(project)) tag_options[:selected] = 'selected' @@ -398,10 +420,13 @@ module ApplicationHelper end def reorder_links(name, url) - link_to(image_tag('2uparrow.png', :alt => l(:label_sort_highest)), url.merge({"#{name}[move_to]" => 'highest'}), :method => :post, :title => l(:label_sort_highest)) + - link_to(image_tag('1uparrow.png', :alt => l(:label_sort_higher)), url.merge({"#{name}[move_to]" => 'higher'}), :method => :post, :title => l(:label_sort_higher)) + - link_to(image_tag('1downarrow.png', :alt => l(:label_sort_lower)), url.merge({"#{name}[move_to]" => 'lower'}), :method => :post, :title => l(:label_sort_lower)) + - link_to(image_tag('2downarrow.png', :alt => l(:label_sort_lowest)), url.merge({"#{name}[move_to]" => 'lowest'}), :method => :post, :title => l(:label_sort_lowest)) + content_tag(:span, + link_to(image_tag('2uparrow.png', :alt => l(:label_sort_highest)), url.merge({"#{name}[move_to]" => 'highest'}), :method => :post, :title => l(:label_sort_highest)) + + link_to(image_tag('1uparrow.png', :alt => l(:label_sort_higher)), url.merge({"#{name}[move_to]" => 'higher'}), :method => :post, :title => l(:label_sort_higher)) + + link_to(image_tag('1downarrow.png', :alt => l(:label_sort_lower)), url.merge({"#{name}[move_to]" => 'lower'}), :method => :post, :title => l(:label_sort_lower)) + + link_to(image_tag('2downarrow.png', :alt => l(:label_sort_lowest)), url.merge({"#{name}[move_to]" => 'lowest'}), :method => :post, :title => l(:label_sort_lowest)), + :class => "reorder-icons" + ) end def breadcrumb(*args) @@ -409,12 +434,38 @@ module ApplicationHelper elements.any? ? content_tag('p', args.join(' » ') + ' » ', :class => 'breadcrumb') : nil end + def breadcrumb_list(*args) + elements = args.flatten + cutme_elements = [] + breadcrumb_elements = [content_tag(:li, elements.shift.to_s, :class => 'first-breadcrumb-element', :style => 'list-style-image:none;')] + + breadcrumb_elements += elements.collect do |element| + content_tag(:li, element.to_s) if element + end + + content_tag(:ul, breadcrumb_elements, :class => 'breadcrumb') + end + def other_formats_links(&block) concat('

' + l(:label_export_to)) yield Redmine::Views::OtherFormatsBuilder.new(self) concat('

') end + def link_to_project_ancestors(project) + if @project + ancestors = (project.root? ? [] : project.ancestors.visible) + ancestors << project + ancestors.collect do |p| + if p == project + link_to_project(p, {:jump => current_menu_item}, {:title => p, :class => 'breadcrumb-project-title nocut'}) + else + link_to_project(p, {:jump => current_menu_item}, {:title => p}) + end + end + end + end + def page_header_title if @page_header_title.present? h(@page_header_title) @@ -458,8 +509,11 @@ module ApplicationHelper css << 'theme-' + theme.name end - css << 'controller-' + params[:controller] - css << 'action-' + params[:action] + if params[:controller] && params[:action] + css << 'controller-' + params[:controller] + css << 'action-' + params[:action] + end + css.join(' ') end @@ -845,8 +899,8 @@ module ApplicationHelper back_url = params[:back_url] if back_url.present? back_url = back_url.to_s - else - back_url = url_for(params) if request.get? + elsif request.get? and !params.blank? + back_url = url_for(params) end hidden_field_tag('back_url', back_url) unless back_url.blank? end @@ -942,9 +996,16 @@ module ApplicationHelper end def content_for(name, content = nil, &block) - @has_content ||= {} - @has_content[name] = true super(name, content, &block) + + # only care for non whitespace contents; + # rails 2.3 specific implementation + if instance_variable_get("@content_for_#{name}").match /\S+/ + @has_content ||= {} + @has_content[name] = true + end + + nil end def has_content?(name) @@ -974,7 +1035,7 @@ module ApplicationHelper unless User.current.pref.warn_on_leaving_unsaved == '0' tags << "\n" + javascript_tag("Event.observe(window, 'load', function(){ new WarnLeavingUnsaved('#{escape_javascript( l(:text_warn_on_leaving_unsaved) )}'); });") end - tags << "\n" + javascript_include_tag("accessibility.js") if ( User.current.impaired? or User.current.anonymous? ) + tags << "\n" + javascript_include_tag("accessibility.js") if User.current.impaired? and accessibility_js_enabled? tags end @@ -1081,6 +1142,22 @@ module ApplicationHelper @top_menu_split end + def disable_accessibility_css! + @accessibility_css_disabled = true + end + + def accessibility_css_enabled? + !@accessibility_css_disabled + end + + def disable_accessibility_js! + @accessibility_js_disabled = true + end + + def accessibility_js_enabled? + !@accessibility_js_disabled + end + private def wiki_helper @@ -1097,4 +1174,14 @@ module ApplicationHelper "" + l(:text_caracters_minimum, :count => Setting.password_min_length) + "" end + def breadcrumb_paths(*args) + if args.nil? + nil + elsif args.empty? + @breadcrumb_paths ||= [default_breadcrumb] + else + @breadcrumb_paths ||= [] + @breadcrumb_paths += args + end + end end diff --git a/app/helpers/journals_helper.rb b/app/helpers/journals_helper.rb index 0196a5fbcd..ba7b366fd1 100644 --- a/app/helpers/journals_helper.rb +++ b/app/helpers/journals_helper.rb @@ -34,18 +34,14 @@ module JournalsHelper # This renders a journal entry with a header and details def render_journal_details(journal, header_label = :label_updated_time_by, model=nil, options={}) header = <<-HTML +
+ #{avatar(journal.user, :size => "40")} +

#{authoring journal.created_at, journal.user, :label => header_label} #{content_tag('a', '', :name => "note-#{journal.anchor}")}

- -
- #{avatar(journal.user, :size => "40")} -
- - #{render_notes(model, journal, options) unless journal.notes.blank?} - HTML if journal.details.any? @@ -58,7 +54,10 @@ module JournalsHelper end end - content_tag("div", "#{header}#{details}", :id => "change-#{journal.id}", :class => "journal") + notes = <<-HTML + #{render_notes(model, journal, options) unless journal.notes.blank?} + HTML + content_tag("div", "#{header}#{details}#{notes}", :id => "change-#{journal.id}", :class => "journal") end def render_notes(model, journal, options={}) diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index cc2b90e751..0ec718177f 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -13,9 +13,10 @@ #++ module ProjectsHelper - def link_to_version(version, options = {}) + def link_to_version(version, html_options = {}, options={}) return '' unless version && version.is_a?(Version) - link_to_if version.visible?, format_version_name(version), { :controller => 'versions', :action => 'show', :id => version }, options + options + link_to_if version.visible?, options[:before_text].to_s + format_version_name(version), { :controller => 'versions', :action => 'show', :id => version }, html_options end def project_settings_tabs @@ -69,7 +70,7 @@ module ProjectsHelper end classes = (ancestors.empty? ? 'root' : 'child') s << "
  • " + - link_to_project(project, {}, :class => "project #{User.current.member_of?(project) ? 'my-project' : nil}") + link_to_project(project, {}, {:class => "project"}, true) s << "
    #{textilizable(project.short_description, :project => project)}
    " unless project.description.blank? s << "
    \n" ancestors << project diff --git a/app/models/issue.rb b/app/models/issue.rb index ea3e480365..ce396ea097 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -43,7 +43,8 @@ class Issue < ActiveRecord::Base else t << (IssueStatus.find_by_id(o.new_value_for(:status_id)).try(:is_closed?) ? '-closed' : '-edit') end - t } + t }, + :except => ["root_id"] register_on_journal_formatter(:id, 'parent_id') register_on_journal_formatter(:named_association, 'project_id', 'status_id', 'tracker_id', 'assigned_to_id', @@ -557,7 +558,7 @@ class Issue < ActiveRecord::Base s << ' assigned-to-me' if User.current.logged? && assigned_to_id == User.current.id s end - + # Saves an issue, time_entry, attachments, and a journal from the parameters # Returns false if save fails def save_issue_with_child_records(params, existing_time_entry=nil) @@ -586,7 +587,18 @@ class Issue < ActiveRecord::Base end rescue ActiveRecord::StaleObjectError attachments[:files].each(&:destroy) - errors.add_to_base l(:notice_locking_conflict) + error_message = l(:notice_locking_conflict) + + journals_since = self.journals.after(lock_version) + + if journals_since.any? + changes = journals_since.map { |j| "#{j.user.name} (#{j.created_at.to_s(:short)})" } + error_message << " " << l(:notice_locking_conflict_additional_information, :users => changes.join(', ')) + end + + error_message << " " << l(:notice_locking_conflict_reload_page) + + errors.add_to_base error_message raise ActiveRecord::Rollback end end @@ -610,9 +622,11 @@ class Issue < ActiveRecord::Base def parent_issue_id=(arg) parent_issue_id = arg.blank? ? nil : arg.to_i if parent_issue_id && @parent_issue = Issue.find_by_id(parent_issue_id) + journal_changes["parent_id"] = [self.parent_id, @parent_issue.id] @parent_issue.id else @parent_issue = nil + journal_changes["parent_id"] = [self.parent_id, nil] nil end end diff --git a/app/models/issue_status.rb b/app/models/issue_status.rb index 7078237d1a..2117507dec 100644 --- a/app/models/issue_status.rb +++ b/app/models/issue_status.rb @@ -56,7 +56,7 @@ class IssueStatus < ActiveRecord::Base (author || !w.author) && (assignee || !w.assignee) end - transitions.collect{|w| w.new_status}.compact.sort + transitions.collect{|w| w.new_status}.uniq.compact.sort else [] end diff --git a/app/models/journal.rb b/app/models/journal.rb index 621fadca31..06713eae3b 100644 --- a/app/models/journal.rb +++ b/app/models/journal.rb @@ -42,6 +42,10 @@ class Journal < ActiveRecord::Base # undef_method :changes serialize :changes, Hash + # Scopes to all journals excluding the initial journal - useful for change + # logs like the history on issue#show + named_scope "changing", :conditions => ["version > 1"] + def touch_journaled_after_creation journaled.touch end diff --git a/app/models/setting.rb b/app/models/setting.rb index c13d5988dd..83f6be4a75 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -158,8 +158,10 @@ private def self.find_or_default(name) name = name.to_s raise "There's no setting named #{name}" unless @@available_settings.has_key?(name) - setting = find_by_name(name) - setting ||= new(:name => name, :value => @@available_settings[name]['default']) if @@available_settings.has_key? name + find_by_name(name) or new do |s| + s.name = name + s.value = @@available_settings[name]['default'] + end end def self.cache_key(name) diff --git a/app/models/user.rb b/app/models/user.rb index 9aada25b1f..e3ffbd5924 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -116,6 +116,26 @@ class User < Principal self.read_attribute(:identity_url) end + def self.register_allowance_evaluator(filter) + self.registered_allowance_evaluators ||= [] + + registered_allowance_evaluators << filter + end + + # replace by class_attribute when on rails 3.x + class_eval do + def self.registered_allowance_evaluators() nil end + def self.registered_allowance_evaluators=(val) + singleton_class.class_eval do + define_method(:registered_allowance_evaluators) do + val + end + end + end + end + + register_allowance_evaluator ChiliProject::PrincipalAllowanceEvaluator::Default + # Returns the user that matches provided login and password, or nil def self.try_to_login(login, password) # Make sure no one can sign in with an empty password @@ -256,7 +276,7 @@ class User < Principal end def impaired - !!self.pref.impaired + anonymous? || !!self.pref.impaired end def impaired? @@ -406,41 +426,59 @@ class User < Principal # * nil with options[:global] set : check if user has at least one role allowed for this action, # or falls back to Non Member / Anonymous permissions depending if the user is logged def allowed_to?(action, context, options={}) - if context && context.is_a?(Project) - # No action allowed on archived projects - return false unless context.active? - # No action allowed on disabled modules - return false unless context.allows_to?(action) - # Admin users are authorized for anything else - return true if admin? - - roles = roles_for_project(context) - return false unless roles - roles.detect {|role| (context.is_public? || role.member?) && role.allowed_to?(action)} - - elsif context && context.is_a?(Array) + if context.is_a?(Project) + allowed_to_in_project?(action, context, options) + elsif context.is_a?(Array) # Authorize if user is authorized on every element of the array - context.map do |project| + context.present? && context.all? do |project| allowed_to?(action,project,options) - end.inject do |memo,allowed| - memo && allowed end elsif options[:global] - # Admin users are always authorized - return true if admin? - - # authorize if user has at least one role that has this permission - roles = memberships.collect {|m| m.roles}.flatten.uniq - roles.detect {|r| r.allowed_to?(action)} || (self.logged? ? Role.non_member.allowed_to?(action) : Role.anonymous.allowed_to?(action)) + allowed_to_globally?(action, options) else false end end + def allowed_to_in_project?(action, project, options = {}) + initialize_allowance_evaluators + + # No action allowed on archived projects + return false unless project.active? + # No action allowed on disabled modules + return false unless project.allows_to?(action) + # Admin users are authorized for anything else + return true if admin? + + candidates_for_project_allowance(project).any? do |candidate| + denied = @registered_allowance_evaluators.any? do |filter| + filter.denied_for_project? candidate, action, project, options + end + + !denied && @registered_allowance_evaluators.any? do |filter| + filter.granted_for_project? candidate, action, project, options + end + end + end + # Is the user allowed to do the specified action on any project? # See allowed_to? for the actions and valid options. - def allowed_to_globally?(action, options) - allowed_to?(action, nil, options.reverse_merge(:global => true)) + def allowed_to_globally?(action, options = {}) + initialize_allowance_evaluators + + # Admin users are always authorized + return true if admin? + + # authorize if user has at least one membership granting this permission + candidates_for_global_allowance.any? do |candidate| + denied = @registered_allowance_evaluators.any? do |evaluator| + evaluator.denied_for_global? candidate, action, options + end + + !denied && @registered_allowance_evaluators.any? do |evaluator| + evaluator.granted_for_global? candidate, action, options + end + end end safe_attributes 'login', @@ -554,6 +592,19 @@ class User < Principal ActiveSupport::SecureRandom.hex(16) end + def initialize_allowance_evaluators + @registered_allowance_evaluators ||= self.class.registered_allowance_evaluators.collect do |evaluator| + evaluator.new(self) + end + end + + def candidates_for_global_allowance + @registered_allowance_evaluators.map(&:global_granting_candidates).flatten.uniq + end + + def candidates_for_project_allowance project + @registered_allowance_evaluators.map{ |f| f.project_granting_candidates(project) }.flatten.uniq + end end class AnonymousUser < User diff --git a/app/views/account/login.rhtml b/app/views/account/login.rhtml index c54366de9a..276ee1caa6 100644 --- a/app/views/account/login.rhtml +++ b/app/views/account/login.rhtml @@ -1,3 +1,6 @@ +<% disable_accessibility_css! %> + +<% breadcrumb_paths(l(:label_login)) %> <%= call_hook :view_account_login_top %>
    <% form_tag({:action=> "login"}) do %> diff --git a/app/views/account/lost_password.rhtml b/app/views/account/lost_password.rhtml index 420e8f9b14..142daab096 100644 --- a/app/views/account/lost_password.rhtml +++ b/app/views/account/lost_password.rhtml @@ -1,3 +1,5 @@ +<% disable_accessibility_css! %> +

    <%=l(:label_password_lost)%>

    diff --git a/app/views/account/password_recovery.rhtml b/app/views/account/password_recovery.rhtml index 31a1617ee9..203055ac5c 100644 --- a/app/views/account/password_recovery.rhtml +++ b/app/views/account/password_recovery.rhtml @@ -1,3 +1,5 @@ +<% disable_accessibility_css! %> +

    <%=l(:label_password_lost)%>

    <%= error_messages_for 'user' %> diff --git a/app/views/account/register.rhtml b/app/views/account/register.rhtml index 3964b54e79..b409326fcf 100644 --- a/app/views/account/register.rhtml +++ b/app/views/account/register.rhtml @@ -1,3 +1,5 @@ +<% disable_accessibility_css! %> +

    <%=l(:label_register)%> <%=link_to l(:label_login_with_open_id_option), signin_url if Setting.openid? %>

    <% form_tag({:action => 'register'}, :class => "tabular") do %> diff --git a/app/views/activities/index.html.erb b/app/views/activities/index.html.erb index ffc7a5fe70..6b490bf001 100644 --- a/app/views/activities/index.html.erb +++ b/app/views/activities/index.html.erb @@ -21,14 +21,16 @@ <%= content_tag('p', l(:label_no_data), :class => 'nodata') if @events_by_day.empty? %>
    -<%= link_to_content_update('« ' + l(:label_previous_week), - params.merge(:from => @date_to - @days - 1), - :title => l(:label_date_from_to, :start => format_date(@date_to - 2*@days), :end => format_date(@date_to - @days - 1))) %> +<%= link_to_content_update(l(:label_previous_week), + params.merge(:from => @date_to - @days - 1), + {:title => l(:label_date_from_to, :start => format_date(@date_to - 2*@days), :end => format_date(@date_to - @days - 1)), + :class => 'navigate-left'}) %>
    -<%= link_to_content_update(l(:label_next_week) + ' »', - params.merge(:from => @date_to + @days - 1), - :title => l(:label_date_from_to, :start => format_date(@date_to), :end => format_date(@date_to + @days - 1))) unless @date_to >= Date.today %> +<%= link_to_content_update(l(:label_next_week), + params.merge(:from => @date_to + @days - 1), + {:title => l(:label_date_from_to, :start => format_date(@date_to), :end => format_date(@date_to + @days - 1)), + :class => 'navigate-right'}) unless @date_to >= Date.today %>
      <% other_formats_links do |f| %> diff --git a/app/views/admin/index.rhtml b/app/views/admin/index.rhtml deleted file mode 100644 index f9b81b9e0a..0000000000 --- a/app/views/admin/index.rhtml +++ /dev/null @@ -1,5 +0,0 @@ -
    - <%= render :partial => 'no_data' if @no_configuration_data %> -
    - -<% html_title(l(:label_administration)) -%> diff --git a/app/views/admin/projects.rhtml b/app/views/admin/projects.rhtml index 423a804a7b..42f3541591 100644 --- a/app/views/admin/projects.rhtml +++ b/app/views/admin/projects.rhtml @@ -1,3 +1,7 @@ +
    + <%= render :partial => 'no_data' if @no_configuration_data %> +
    +
    <%= link_to l(:label_project_new), {:controller => 'projects', :action => 'new'}, :class => 'icon icon-add' %>
    diff --git a/app/views/attachments/_form.rhtml b/app/views/attachments/_form.rhtml index 6d387d1c2e..9613daaef9 100644 --- a/app/views/attachments/_form.rhtml +++ b/app/views/attachments/_form.rhtml @@ -1,8 +1,16 @@ -<%= file_field_tag 'attachments[1][file]', :size => 30, :id => nil -%> + + <%= file_field_tag 'attachments[1][file]', :size => 15, :id => nil, :class => "attachment_choose_file" -%> + +
    -<%= link_to l(:label_add_another_file), '#', :onclick => 'addFileField(); return false;' %> -(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>) - + + <%= link_to l(:label_add_another_file), '#', :onclick => 'addFileField(); return false;' %> + (<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>) + diff --git a/app/views/boards/show.rhtml b/app/views/boards/show.rhtml index 8c52f1197b..7fe8e5c871 100644 --- a/app/views/boards/show.rhtml +++ b/app/views/boards/show.rhtml @@ -1,5 +1,3 @@ -<%= breadcrumb link_to(l(:label_board_plural), {:controller => 'boards', :action => 'index', :project_id => @project}) %> -
    <%= link_to_if_authorized l(:label_message_new), {:controller => 'messages', :action => 'new', :board_id => @board}, diff --git a/app/views/common/_calendar.rhtml b/app/views/common/_calendar.rhtml index 147c49b2cf..792a1a4380 100644 --- a/app/views/common/_calendar.rhtml +++ b/app/views/common/_calendar.rhtml @@ -11,15 +11,27 @@ while day <= calendar.enddt %>

    <%= day.day %>

    <% calendar.events_on(day).each do |i| %> <% if i.is_a? Issue %> -
    +
    <%= h("#{i.project} -") unless @project && @project == i.project %> - <%= link_to_issue i, :truncate => 30 %> + <% date_img = '' %> + <% if day == i.start_date and day == i.due_date %> + <% date_img = image_tag("bullet_diamond.png", :title => l(:text_tip_issue_begin_end_day), :alt => l(:text_tip_issue_begin_end_day), + :class => "imgtag-icon") %> + <% elsif day == i.start_date %> + <% date_img = image_tag("bullet_go.png", :title => l(:text_tip_issue_begin_day), :alt => l(:text_tip_issue_begin_day), + :class => "imgtag-icon") %> + <% elsif day == i.due_date %> + <% date_img = image_tag("bullet_end.png", :title => l(:text_tip_issue_end_day), :alt => l(:text_tip_issue_end_day), + :class => "imgtag-icon") %> + <% end %> + + <%= link_to_issue i, :truncate => 30, :before_text => date_img %> <%= render_issue_tooltip i %>
    <% else %> - + <%= h("#{i.project} -") unless @project && @project == i.project %> - <%= link_to_version i%> + <%= link_to_version i, {}, {:before_text => image_tag("package.png", :title => l(:label_version), :alt => l(:label_version), :class => "imgtag-icon") }%> <% end %> <% end %> diff --git a/app/views/issues/_action_menu.rhtml b/app/views/issues/_action_menu.rhtml index 4be7fdce25..1993b29727 100644 --- a/app/views/issues/_action_menu.rhtml +++ b/app/views/issues/_action_menu.rhtml @@ -1,12 +1,14 @@ -
    -<%= link_to_if_authorized(l(:button_update), {:controller => 'issues', :action => 'edit', :id => @issue }, :onclick => 'showAndScrollTo("update", "notes"); return false;', :class => 'icon icon-edit', :accesskey => accesskey(:edit)) %> -<%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'new', :issue_id => @issue}, :class => 'icon icon-time-add' %> -<%= watcher_link(@issue, - User.current, - { :class => 'watcher_link', - :replace => User.current.allowed_to?(:view_issue_watchers, @project) ? ['#watchers', '.watcher_link'] : ['.watcher_link'] }) %> -<%= link_to_if_authorized l(:button_duplicate), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue }, :class => 'icon icon-duplicate' %> -<%= link_to_if_authorized l(:button_copy), {:controller => 'issue_moves', :action => 'new', :id => @issue, :copy_options => {:copy => 't'}}, :class => 'icon icon-copy' %> -<%= link_to_if_authorized l(:button_move), {:controller => 'issue_moves', :action => 'new', :id => @issue}, :class => 'icon icon-move' %> -<%= link_to_if_authorized l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, :confirm => (@issue.leaf? ? l(:text_are_you_sure) : l(:text_are_you_sure_with_children)), :method => :post, :class => 'icon icon-del' %> -
    +<% content_for :action_menu_main do %> + <%= li_unless_nil(link_to_if_authorized(l(:button_update), {:controller => 'issues', :action => 'edit', :id => @issue }, :onclick => 'showAndScrollTo("update", "notes"); return false;', :class => 'icon icon-edit', :accesskey => accesskey(:edit))) %> + <%= li_unless_nil(watcher_link(@issue, + User.current, + { :class => 'watcher_link', + :replace => User.current.allowed_to?(:view_issue_watchers, @project) ? ['#watchers', '.watcher_link'] : ['.watcher_link'] })) %> +<% end %> +<% content_for :action_menu_more do %> + <%= li_unless_nil(link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'new', :issue_id => @issue}, :class => 'icon icon-time-add') %> + <%= li_unless_nil(link_to_if_authorized l(:button_duplicate), {:controller => 'issues', :action => 'new', :project_id => @project, :copy_from => @issue }, :class => 'icon icon-duplicate') %> + <%= li_unless_nil(link_to_if_authorized l(:button_copy), {:controller => 'issue_moves', :action => 'new', :id => @issue, :copy_options => {:copy => 't'}}, :class => 'icon icon-copy') %> + <%= li_unless_nil(link_to_if_authorized l(:button_move), {:controller => 'issue_moves', :action => 'new', :id => @issue}, :class => 'icon icon-move') %> + <%= li_unless_nil(link_to_if_authorized l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, :confirm => (@issue.leaf? ? l(:text_are_you_sure) : l(:text_are_you_sure_with_children)), :method => :post, :class => 'icon icon-del') %> +<% end %> \ No newline at end of file diff --git a/app/views/issues/_form.rhtml b/app/views/issues/_form.rhtml index bc89c630a6..f3dcef6763 100644 --- a/app/views/issues/_form.rhtml +++ b/app/views/issues/_form.rhtml @@ -26,7 +26,10 @@
    <% if @issue.new_record? %> -

    <%= label_tag('attachments[1][file]', l(:label_attachment_plural))%><%= render :partial => 'attachments/form' %>

    +

    + <%= label_tag('attachments[1][file]', l(:label_attachment_plural))%> + <%= render :partial => 'attachments/form' %> +

    <% end %> <% if @issue.new_record? && User.current.allowed_to?(:add_issue_watchers, @project) -%> diff --git a/app/views/issues/_subissue_row.rhtml b/app/views/issues/_subissue_row.rhtml new file mode 100644 index 0000000000..6942f5b0f8 --- /dev/null +++ b/app/views/issues/_subissue_row.rhtml @@ -0,0 +1,36 @@ +<% + css_classes = ["issue"] + css_classes << "issue-#{issue.id}" + css_classes << "idnt" << "idnt-#{level}" if level > 0 + + if relation == "root" + issue_text = link_to("#{h(issue.tracker.name)} ##{issue.id}", + 'javascript:void(0)', + :style => "color:inherit; font-weight: bold; text-decoration:none; cursor:default;", + :class => issue.css_classes) + else + title = '' + + if relation == "parent" + title << content_tag(:span, l(:description_parent_issue), :class => "hidden-for-sighted") + elsif relation == "child" + title << content_tag(:span, l(:description_sub_issue), :class => "hidden-for-sighted") + end + title << " #{h(issue.tracker.name)} ##{issue.id}" + + issue_text = link_to(title, issue, :class => issue.css_classes) + end + issue_text << ": " + issue_text << truncate(issue.subject, :length => 60) +%> +<%= + content_tag('tr', [ + content_tag('td', check_box_tag("ids[]", issue.id, false, :id => nil), :class => 'checkbox'), + content_tag('td', issue_text, :class => 'subject'), + content_tag('td', h(issue.status)), + content_tag('td', link_to_user(issue.assigned_to)), + content_tag('td', link_to_version(issue.fixed_version)) + ].join, + :class => css_classes.join(' ') + ) +%> diff --git a/app/views/issues/_subissues_paragraph.rhtml b/app/views/issues/_subissues_paragraph.rhtml new file mode 100644 index 0000000000..7ded4541e5 --- /dev/null +++ b/app/views/issues/_subissues_paragraph.rhtml @@ -0,0 +1,27 @@ +<%= l(:label_issue_hierarchy) %> +(<%= link_to(l(:label_add_subtask), {:controller => 'issues', :action => 'new', :project_id => @project, :issue => {:parent_issue_id => @issue}}) if User.current.allowed_to?(:manage_subtasks, @project) %>) + +<% if !@issue.leaf? || @issue.parent %> + <% indent = 0 %> + +
    + + + + <% @issue.ancestors.each do |issue| %> + <%= render :partial => 'subissue_row', :locals => { :issue => issue, :level => indent, :relation => "parent" } %> + <% indent += 1 %> + <% end %> + + + <%= render :partial => 'subissue_row', :locals => { :issue => @issue, :level => indent, :relation => "root" } %> + <% indent += 1 %> + + + <% issue_list(@issue.descendants.sort_by(&:lft)) do |issue, level| %> + <%= render :partial => 'subissue_row', :locals => { :issue => issue, :level => indent + level, :relation => "child" } %> + <% end %> + +
    +
    +<% end %> diff --git a/app/views/issues/index.rhtml b/app/views/issues/index.rhtml index 7c991c3980..f66c0fb43a 100644 --- a/app/views/issues/index.rhtml +++ b/app/views/issues/index.rhtml @@ -1,16 +1,14 @@ -
    - +
    + <% if !@query.new_record? && @query.editable_by?(User.current) %> + <%= link_to l(:button_edit), {:controller => 'queries', :action => 'edit', :id => @query}, :class => 'icon icon-edit' %> + <%= link_to l(:button_delete), {:controller => 'queries', :action => 'destroy', :id => @query}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %> + <% end %> +

    <%= @query.new_record? ? l(:label_issue_plural) : h(@query.name) %>

    +
    -
    -<% if !@query.new_record? && @query.editable_by?(User.current) %> - <%= link_to l(:button_edit), {:controller => 'queries', :action => 'edit', :id => @query}, :class => 'icon icon-edit' %> - <%= link_to l(:button_delete), {:controller => 'queries', :action => 'destroy', :id => @query}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %> -<% end %> -<%= link_to_if_authorized(l(:label_issue_new), {:controller => 'issues', :action => 'new', :project_id => @project}, :class => 'icon icon-add') if @project %> -
    <% html_title(@query.new_record? ? l(:label_issue_plural) : h(@query.name)) %> @@ -78,7 +76,7 @@ <%= f.link_to 'Atom', :url => { :project_id => @project, :query_id => (@query.new_record? ? nil : @query), :key => User.current.rss_key } %> <%= f.link_to 'CSV', :url => { :project_id => @project } %> <%= f.link_to 'PDF', :url => { :project_id => @project } %> -<% end %> +<% end if User.current.allowed_to? :export_issues, @project %> <% end %> <%= call_hook(:view_issues_index_bottom, { :issues => @issues, :project => @project, :query => @query }) %> diff --git a/app/views/issues/show.rhtml b/app/views/issues/show.rhtml index 9d13d5c54f..05bdd8ec50 100644 --- a/app/views/issues/show.rhtml +++ b/app/views/issues/show.rhtml @@ -1,10 +1,7 @@ -
    -
    <%= content_tag('h2', h(@issue.tracker.name) + ' #' +@issue.id.to_s) %>
    +<%= render :partial => 'action_menu' %> -
    - <%= render :partial => 'action_menu' %> -
    -
    +<% breadcrumb_paths(*[link_to(l(:label_issue_plural), {:controller => 'issues', :action => 'index'})] << @issue.ancestors.collect {|parent| link_to '#' + h(parent.id), {:controller => 'issues', :action => 'show', :id => parent}}) unless @issue.ancestors.empty? %> +<%= content_tag('h2', h(@issue.tracker.name) + ' #' +@issue.id.to_s) %>
    @@ -13,7 +10,6 @@

    <%=h(@issue.subject) %>

    -

    <%= authoring @issue.created_on, @issue.author %>. @@ -21,7 +17,6 @@ <%= l(:label_updated_time, time_tag(@issue.updated_on)) %>. <% end %>

    -
    @@ -56,48 +51,43 @@ <% if @issue.description? %> -
    +
    <%= link_to_remote_if_authorized(l(:button_quote), { :url => {:controller => 'journals', :action => 'new', :id => @issue} }, :class => 'icon icon-comment') %>
    -

    <%=l(:field_description)%>

    -
    - <%= textilizable @issue, :description, :attachments => @issue.attachments %> -
    -
    +

    <%=l(:field_description)%>

    +
    + <%= textilizable @issue, :description, :attachments => @issue.attachments %> +
    + <% end %> <% if @issue.attachments.any? -%> -
    - <%= link_to_attachments @issue %> +<%= link_to_attachments @issue %> <% end -%> <%= call_hook(:view_issues_show_description_bottom, :issue => @issue) %> -<% if !@issue.leaf? || User.current.allowed_to?(:manage_subtasks, @project) %>
    -
    -

    - <%=l(:label_subtask_plural)%> - (<%= link_to(l(:label_add_subtask), {:controller => 'issues', :action => 'new', :project_id => @project, :issue => {:parent_issue_id => @issue}}) if User.current.allowed_to?(:manage_subtasks, @project) %>) -

    -<%= render_descendants_tree(@issue) unless @issue.leaf? %> -
    -<% end %> +<%= render :partial => 'subissues_paragraph' %> <% if authorize_for('issue_relations', 'new') || @issue.relations.present? %> -
    <%= render :partial => 'relations' %>
    -
    <% end %> - + <% if User.current.allowed_to?(:add_issue_watchers, @project) || + (@issue.watchers.present? && User.current.allowed_to?(:view_issue_watchers, @project)) %> +
    + <%= render :partial => 'watchers/watchers', :locals => {:watched => @issue} %> +
    + <% end %> +
    <% if @changesets.present? %>
    @@ -117,15 +107,12 @@
    -
    - <%= render :partial => 'action_menu', :locals => {:replace_watcher => 'watcher2' } %> -
    + <%= javascript_include_tag 'copy_issue_actions' %>
    <% if authorize_for('issues', 'edit') %> - -
      -

      <%= l(:label_top_menu) %>

      +

      <%= l(:label_top_menu) %>

      +
    <% main_menu = render_main_menu(@project) %> - <% if (side_displayed = has_content?(:sidebar) || has_content?(:main_menu) || !main_menu.blank?) %> - <% display_sidebar = true %> - <% else %> - <% display_sidebar = false %> - <% end %> + <% side_displayed = has_content?(:sidebar) || has_content?(:main_menu) || !main_menu.blank? %>
    "> <% if (side_displayed) %>
    - - -
    <%=h board.name %> <%=h board.description %> + <% if authorize_for("boards", "edit") %> <%= reorder_links('board', {:controller => 'boards', :action => 'edit', :project_id => @project, :id => board}) %> <% end %> diff --git a/app/views/projects/show.rhtml b/app/views/projects/show.rhtml index b7036a5600..816ed04457 100644 --- a/app/views/projects/show.rhtml +++ b/app/views/projects/show.rhtml @@ -5,6 +5,7 @@

    <%=l(:label_overview)%>

    +<% breadcrumb_paths(l(:label_overview)) %>
    diff --git a/app/views/queries/_columns.rhtml b/app/views/queries/_columns.rhtml index 853b139839..a93d5f78e1 100644 --- a/app/views/queries/_columns.rhtml +++ b/app/views/queries/_columns.rhtml @@ -7,7 +7,7 @@ options_for_select((query.available_columns - query.columns).collect {|column| [column.caption, column.name]}), :multiple => true, :size => 10, :style => "width:150px" %>
    +
    @@ -22,7 +22,7 @@ options_for_select(query.columns.collect {|column| [column.caption, column.name]}), :id => 'selected_columns', :multiple => true, :size => 10, :style => "width:150px" %>
    +
    <%=l(:label_report_plural)%> +

    <%=l(:label_summary)%>

    <%=l(:field_tracker)%>   @@ -46,7 +46,7 @@ <%= render :partial => 'simple', :locals => { :data => @issues_by_version, :field_name => "fixed_version_id", :rows => @versions } %>
    <% if @project.children.any? %> -

    <%=l(:field_subproject)%>   +

    <%=l(:label_suproject_plural)%>   <%= link_to image_tag('zoom_in.png', :alt => l(:text_analyze, :subject => l(:field_subproject)), :title => l(:text_analyze, :subject => l(:field_subproject))), diff --git a/app/views/reports/issue_report_details.rhtml b/app/views/reports/issue_report_details.rhtml index 6b4b422325..b44c0186f9 100644 --- a/app/views/reports/issue_report_details.rhtml +++ b/app/views/reports/issue_report_details.rhtml @@ -1,4 +1,4 @@ -

    <%=l(:label_report_plural)%>

    +

    <%=l(:label_summary)%>

    <%=@report_title%>

    <%= render :partial => 'details', :locals => { :data => @data, :field_name => @field, :rows => @rows } %> diff --git a/app/views/users/_form.rhtml b/app/views/users/_form.rhtml index 1f8aa0cc66..d6f568de53 100644 --- a/app/views/users/_form.rhtml +++ b/app/views/users/_form.rhtml @@ -20,7 +20,7 @@
    -

    <%=l(:field_impaired_settings)%>

    +

    <%=l(:field_ui, :app_title => Setting.app_title)%>

    <%= render :partial => "users/impaired_settings" %>
    diff --git a/app/views/users/_impaired_settings.rhtml b/app/views/users/_impaired_settings.rhtml index ebdfa4717a..938eeb27e7 100644 --- a/app/views/users/_impaired_settings.rhtml +++ b/app/views/users/_impaired_settings.rhtml @@ -1,3 +1,6 @@ -<% fields_for :pref, @user.pref, :builder => TabularFormBuilder, :lang => current_language do |pref_fields| %> -

    <%= pref_fields.check_box :impaired %>

    +<% fields_for :pref, @user.pref, :lang => current_language do |pref_fields| %> +

    + <%= pref_fields.label(:impaired, t(:field_impaired, :app_title => Setting.app_title))%> + <%= pref_fields.check_box :impaired %> +

    <% end %> diff --git a/app/views/users/show.rhtml b/app/views/users/show.rhtml index a9cd0100e2..31f32c9a72 100644 --- a/app/views/users/show.rhtml +++ b/app/views/users/show.rhtml @@ -15,7 +15,6 @@
  • <%=h custom_value.custom_field.name%>: <%=h show_value(custom_value) %>
  • <% end %> <% end %> -
  • <%=l(:label_registered_on)%>: <%= format_date(@user.created_on) %>
  • <% unless @user.last_login_on.nil? %>
  • <%=l(:field_last_login_on)%>: <%= format_date(@user.last_login_on) %>
  • <% end %> diff --git a/app/views/versions/index.html.erb b/app/views/versions/index.html.erb index 5d0adb7add..3d54c3089b 100644 --- a/app/views/versions/index.html.erb +++ b/app/views/versions/index.html.erb @@ -13,9 +13,9 @@ <%= render(:partial => "wiki/content", :locals => {:content => version.wiki_page.content}) if version.wiki_page %> <% if (issues = @issues_by_version[version]) && issues.size > 0 %> + <%= l(:label_related_issues) %> <% form_tag({}) do -%> - <%- issues.each do |issue| -%> diff --git a/app/views/watchers/_watchers.rhtml b/app/views/watchers/_watchers.rhtml index 4da8c0dd21..9d4748cbbd 100644 --- a/app/views/watchers/_watchers.rhtml +++ b/app/views/watchers/_watchers.rhtml @@ -1,13 +1,11 @@ -
    -<%= link_to_remote l(:button_add), +<%= l(:label_issue_watchers) %> (<%= watched.watcher_users.size %>) +(<%= link_to_remote(l(:button_add_watcher), :url => {:controller => 'watchers', :action => 'new', :object_type => watched.class.name.underscore, - :object_id => watched} if User.current.allowed_to?(:add_issue_watchers, @project) %> -
    - -

    <%= l(:label_issue_watchers) %> (<%= watched.watcher_users.size %>)

    - + :object_id => watched}, + :method => :get) if User.current.allowed_to?(:add_issue_watchers, @project) +%>) <% unless @watcher.nil? %> <% remote_form_for(:watcher, @watcher, :url => {:controller => 'watchers', diff --git a/app/views/welcome/index.rhtml b/app/views/welcome/index.rhtml index 7011ee1fab..58c9435dfc 100644 --- a/app/views/welcome/index.rhtml +++ b/app/views/welcome/index.rhtml @@ -1,10 +1,14 @@ +<% breadcrumb_paths(nil) %>
    <%= textilizable Setting.welcome_text %>
    <% if @news.any? %> -
    +

    <%=l(:label_news_latest)%>

    +
    <%= render :partial => 'news/news', :collection => @news %> <%= link_to l(:label_news_view_all), :controller => 'news' %> + +
    <% end %> <%= call_hook(:view_welcome_index_left, :projects => @projects) %> @@ -12,7 +16,7 @@
    <% if @projects.any? %> -
    +

    <%=l(:label_project_latest)%>

      <% for project in @projects %> diff --git a/app/views/wiki/_content.rhtml b/app/views/wiki/_content.rhtml index 421d26cbbe..abcf05284f 100644 --- a/app/views/wiki/_content.rhtml +++ b/app/views/wiki/_content.rhtml @@ -1,3 +1,3 @@ -
      +
      <%= textilizable content, :text, :attachments => content.page.attachments %>
      diff --git a/app/views/wiki/_sidebar.rhtml b/app/views/wiki/_sidebar.rhtml index 98bd2dbe53..7dce1b1ee2 100644 --- a/app/views/wiki/_sidebar.rhtml +++ b/app/views/wiki/_sidebar.rhtml @@ -1,9 +1,3 @@ <% if @wiki && @wiki.sidebar -%> <%= textilizable @wiki.sidebar.content, :text %> <% end -%> - -

      <%= l(:label_wiki_navigation) %>

      - -<%= link_to l(:field_start_page), {:action => 'show', :id => nil} %>
      -<%= link_to l(:label_index_by_title), {:action => 'index'} %>
      -<%= link_to l(:label_index_by_date), {:action => 'date_index'} %>
      diff --git a/app/views/wiki/show.rhtml b/app/views/wiki/show.rhtml index c144fb1d82..8ab6c71c14 100644 --- a/app/views/wiki/show.rhtml +++ b/app/views/wiki/show.rhtml @@ -1,17 +1,22 @@ -
      -<% if @editable %> -<%= link_to_if_authorized(l(:button_edit), {:action => 'edit', :id => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) if @content.version == @page.content.version %> -<%= watcher_link(@page, User.current) %> -<%= link_to_if_authorized(l(:button_lock), {:action => 'protect', :id => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? %> -<%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :id => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? %> -<%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move') if @content.version == @page.content.version %> -<%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :id => @page.title}, :method => :delete, :confirm => l(:text_are_you_sure), :class => 'icon icon-del') %> -<%= link_to_if_authorized(l(:button_rollback), {:action => 'edit', :id => @page.title, :version => @content.version }, :class => 'icon icon-cancel') if @content.version < @page.content.version %> +<%= call_hook :wiki_navigation %> +<% content_for :action_menu_main do %> + <% if @editable %> + <%= li_unless_nil(link_to_if_authorized(l(:button_edit), {:action => 'edit', :id => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit))) if @content.version == @page.content.version %> + <%= li_unless_nil(watcher_link(@page, User.current)) if Setting.notified_events.include?("wiki_content_added") or Setting.notified_events.include?("wiki_content_updated") %> + <% end %> +<% end %> +<% content_for :action_menu_more do %> + <% if @editable %> + <%= li_unless_nil(link_to_if_authorized(l(:button_lock), {:action => 'protect', :id => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock')) if !@page.protected? %> + <%= li_unless_nil(link_to_if_authorized(l(:button_unlock), {:action => 'protect', :id => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock')) if @page.protected? %> + <%= li_unless_nil(link_to_if_authorized(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move')) if @content.version == @page.content.version %> + <%= li_unless_nil(link_to_if_authorized(l(:button_delete), {:action => 'destroy', :id => @page.title}, :method => :delete, :confirm => l(:text_are_you_sure), :class => 'icon icon-del')) %> + <%= li_unless_nil(link_to_if_authorized(l(:button_rollback), {:action => 'edit', :id => @page.title, :version => @content.version }, :class => 'icon icon-cancel')) if @content.version < @page.content.version %> + <% end %> + <%= li_unless_nil(link_to_if_authorized(l(:label_history), {:action => 'history', :id => @page.title}, :class => 'icon icon-history')) %> <% end %> -<%= link_to_if_authorized(l(:label_history), {:action => 'history', :id => @page.title}, :class => 'icon icon-history') %> -
      -<%= breadcrumb(@page.ancestors.reverse.collect {|parent| link_to h(parent.pretty_title), {:id => parent.title, :project_id => parent.project}}) %> +<% breadcrumb_paths(*@page.ancestors.reverse.collect {|parent| link_to h(parent.pretty_title), {:id => parent.title, :project_id => parent.project}}) %> <% if @content.version != @page.content.version %>

      diff --git a/config/locales/bg.yml b/config/locales/bg.yml index 8d02d9d398..c8fcd1e184 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -983,3 +983,28 @@ bg: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/bs.yml b/config/locales/bs.yml index 0cd4fd4247..8f52460172 100644 --- a/config/locales/bs.yml +++ b/config/locales/bs.yml @@ -997,3 +997,28 @@ bs: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/ca.yml b/config/locales/ca.yml index c59ab948f5..d2cf15b7f9 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -986,3 +986,28 @@ ca: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/cs.yml b/config/locales/cs.yml index c681fb0f5d..4a178b20b1 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -1207,3 +1207,28 @@ cs: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/da.yml b/config/locales/da.yml index 0b1502e8ee..58f979a31b 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -999,3 +999,28 @@ da: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/de.yml b/config/locales/de.yml index 89b61285a3..b059bff29b 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -162,18 +162,22 @@ de: notice_account_invalid_creditentials: Benutzer oder Kennwort ist ungültig. notice_account_password_updated: Kennwort wurde erfolgreich aktualisiert. notice_account_wrong_password: Falsches Kennwort. - notice_account_register_done: Konto wurde erfolgreich angelegt. + notice_account_register_done: Konto wurde erfolgreich angelegt. Zur Aktivierung folgen Sie dem Link, der Ihnen per E-Mail zugeschickt wurde. notice_account_unknown_email: Unbekannter Benutzer. notice_account_update_failed: Konto konnte nicht aktualisiert werden. Bitte besuchen Sie ihre Profilseite und überprüfen Sie die Einstellungen. notice_can_t_change_password: Dieses Konto verwendet eine externe Authentifizierungs-Quelle. Unmöglich, das Kennwort zu ändern. notice_account_lost_email_sent: Eine E-Mail mit Anweisungen, ein neues Kennwort zu wählen, wurde Ihnen geschickt. notice_account_activated: Ihr Konto ist aktiviert. Sie können sich jetzt anmelden. + notice_account_inactive: Ihr Konto ist nicht aktiviert. Zur Aktivierung folgen Sie dem Link, der Ihnen bei der Registrierung per E-Mail zugeschickt wurde. notice_successful_create: Erfolgreich angelegt notice_successful_update: Erfolgreich aktualisiert. notice_successful_delete: Erfolgreich gelöscht. notice_successful_connection: Verbindung erfolgreich. notice_file_not_found: Anhang existiert nicht oder ist gelöscht worden. - notice_locking_conflict: Datum wurde von einem anderen Benutzer geändert. + notice_internal_server_error: "Auf der von Ihnen aufgerufenen Seite ist ein Fehler aufgetreten. Kontaktieren Sie bitte ihren %{app_title} Administrator wenn sie wiederholt Probleme mit dem Aufrufen der Seite haben." + notice_locking_conflict: Die Informationen wurde zwischenzeitlich von einem anderen Benutzer geändert. + notice_locking_conflict_additional_information: "Die Änderungen wurden durchgeführt von %{users}." + notice_locking_conflict_reload_page: Bitte laden Sie die Seite neu, machen Sie sich mit den Änderungen vertraut und geben Sie Ihre Änderungen noch einmal ein. notice_not_authorized: Sie sind nicht berechtigt, auf diese Seite zuzugreifen. notice_email_sent: "Eine E-Mail wurde an %{value} gesendet." notice_email_error: "Beim Senden einer E-Mail ist ein Fehler aufgetreten (%{value})." @@ -279,6 +283,7 @@ de: field_host: Host field_port: Port field_account: Konto + field_base: "Allgemeiner Fehler:" field_base_dn: Base DN field_attr_login: Mitgliedsname-Attribut field_attr_firstname: Vorname-Attribut @@ -382,6 +387,7 @@ de: permission_manage_versions: Versionen verwalten permission_manage_categories: Ticket-Kategorien verwalten permission_view_issues: Tickets anzeigen + permission_export_issues: Tickets exportieren permission_add_issues: Tickets hinzufügen permission_edit_issues: Tickets bearbeiten permission_manage_issue_relations: Ticket-Beziehungen verwalten @@ -499,6 +505,7 @@ de: label_password_lost: Kennwort vergessen label_home: Hauptseite label_my_page: Meine Seite + label_account: Konto label_my_account: Mein Konto label_my_account_data: Meine Kontodaten label_my_projects: Meine Projekte @@ -553,6 +560,8 @@ de: label_news_view_all: Alle News anzeigen label_news_added: News hinzugefügt label_settings: Konfiguration + label_summary: Zusammenfassung + label_project_settings: Projektkonfiguration label_overview: Übersicht label_version: Version label_version_new: Neue Version @@ -678,8 +687,8 @@ de: label_wiki_edit_plural: Wiki-Bearbeitungen label_wiki_page: Wiki-Seite label_wiki_page_plural: Wiki-Seiten - label_index_by_title: Seiten nach Titel sortiert - label_index_by_date: Seiten nach Datum sortiert + label_index_by_title: Seiten nach Titel + label_index_by_date: Seiten nach Datum label_current_version: Gegenwärtige Version label_preview: Vorschau label_feed_plural: Feeds @@ -775,7 +784,7 @@ de: label_plugins: Plugins label_ldap_authentication: LDAP-Authentifizierung label_downloads_abbr: D/L - label_optional_description: Beschreibung (optional) + label_optional_description: Beschreibung label_add_another_file: Eine weitere Datei hinzufügen label_preferences: Präferenzen label_chronological_order: in zeitlicher Reihenfolge @@ -784,6 +793,7 @@ de: label_incoming_emails: Eingehende E-Mails label_generate_key: Generieren label_issue_watchers: Beobachter + button_add_watcher: Beobachter hinzufügen label_example: Beispiel label_display: Anzeige label_sort: Sortierung @@ -1000,8 +1010,8 @@ de: field_effective_date: "Abgabedatum" label_news_comment_added: "Kommentar einer News hinzugefügt" field_warn_on_leaving_unsaved: "Beim Verlassen einer Seite mit ungespeichertem Text warnen" - field_impaired_settings: "ChiliProject bietet eine optimierte Oberfläche für motorisch- oder seh-behinderte Nutzer" - field_impaired: "Angepasste ChiliProject-Oberfläche benutzen" + field_impaired: Für die barrierefreie Nutzung optimierte Oberfläche + field_ui: Nutzeroberfläche text_warn_on_leaving_unsaved: "Der eingegebene Text wird nicht gespeichert, wenn sie die Seite jetzt verlassen." text_default_encoding: "Default: UTF-8" text_git_repo_example: a bare and local repository (e.g. /gitrepo, c:\gitrepo) @@ -1041,3 +1051,9 @@ de: description_attachment_toggle: Dateien aus/einblenden description_autocomplete: Für dieses Feld werden sie mit einer Autovervollständigung unterstützt. Sie können einen Teil des Tickettitels schreiben und bekommen eine Liste von möglichen Tickets angezeigt. Wählen Sie mit den Pfeiltasten den gewünschten Eintrag und bestätigen Sie mit Tab oder Enter. Sie können aber auch die Ticketnummer direkt eintragen. description_noscript: Sie müssen JavaScript aktiveren, um Chiliproject nutzen zu können! + description_my_project: Sie sind Mitglied + description_parent_issue: Übergeordnetes Ticket + description_sub_issue: Untergeordnetes Ticket + label_issue_hierarchy: "Tickethierarchie" + more_actions: Weitere Funktionen + show_hide_project_menu: Projektnavigation aus/einblenden diff --git a/config/locales/el.yml b/config/locales/el.yml index 04484eddd9..fe4a51da2f 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -983,3 +983,28 @@ el: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index 84772faa89..238cfa248e 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -159,7 +159,9 @@ en-GB: notice_successful_delete: Successful deletion. notice_successful_connection: Successful connection. notice_file_not_found: The page you were trying to access doesn't exist or has been removed. - notice_locking_conflict: Data has been updated by another user. + notice_locking_conflict: Information has been updated by at least one other user in the meantime. + notice_locking_conflict_additional_information: "The update(s) came from %{users}." + notice_locking_conflict_reload_page: Please reload the page, review the changes and reapply your updates. notice_not_authorized: You are not authorised to access this page. notice_not_authorized_archived_project: The project you're trying to access has been archived. notice_email_sent: "An email was sent to %{value}" @@ -268,6 +270,7 @@ en-GB: field_host: Host field_port: Port field_account: Account + field_base: "General Error:" field_base_dn: Base DN field_attr_login: Login attribute field_attr_firstname: Firstname attribute @@ -381,6 +384,7 @@ en-GB: permission_manage_versions: Manage versions permission_manage_categories: Manage issue categories permission_view_issues: View Issues + permission_export_issues: Export Issues permission_add_issues: Add issues permission_edit_issues: Edit issues permission_manage_issue_relations: Manage issue relations @@ -493,6 +497,7 @@ en-GB: label_password_lost: Lost password label_home: Home label_my_page: My page + label_account: Account label_my_account: My account label_my_projects: My projects label_my_page_block: My page block @@ -987,3 +992,28 @@ en-GB: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/en.yml b/config/locales/en.yml index 244761ff03..d4469e2df6 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -151,12 +151,16 @@ en: notice_can_t_change_password: This account uses an external authentication source. Impossible to change the password. notice_account_lost_email_sent: An email with instructions to choose a new password has been sent to you. notice_account_activated: Your account has been activated. You can now log in. + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. notice_successful_create: Successful creation. notice_successful_update: Successful update. notice_successful_delete: Successful deletion. notice_successful_connection: Successful connection. notice_file_not_found: The page you were trying to access doesn't exist or has been removed. - notice_locking_conflict: Data has been updated by another user. + notice_internal_server_error: "An error occurred on the page you were trying to access. If you continue to experience problems please contact your %{app_title} administrator for assistance." + notice_locking_conflict: Information has been updated by at least one other user in the meantime. + notice_locking_conflict_additional_information: "The update(s) came from %{users}." + notice_locking_conflict_reload_page: Please reload the page, review the changes and reapply your updates. notice_not_authorized: You are not authorized to access this page. notice_not_authorized_archived_project: The project you're trying to access has been archived. notice_email_sent: "An email was sent to %{value}" @@ -265,6 +269,7 @@ en: field_host: Host field_port: Port field_account: Account + field_base: "General Error:" field_base_dn: Base DN field_attr_login: Login attribute field_attr_firstname: Firstname attribute @@ -308,9 +313,8 @@ en: field_text: Text field field_visible: Visible field_warn_on_leaving_unsaved: "Warn me when leaving a page with unsaved text" - field_impaired_settings: "ChiliProject offers a slightly different User Interface for visually/motorically impaired Users" - field_impaired: "Use adjusted ChiliProject Interface" - + field_impaired: Accessibility mode + field_ui: User Interface setting_app_title: Application title setting_app_subtitle: Application subtitle setting_welcome_text: Welcome text @@ -380,6 +384,7 @@ en: permission_manage_versions: Manage versions permission_manage_categories: Manage issue categories permission_view_issues: View Issues + permission_export_issues: Export Issues permission_add_issues: Add issues permission_edit_issues: Edit issues permission_manage_issue_relations: Manage issue relations @@ -497,6 +502,7 @@ en: label_password_lost: Lost password label_home: Home label_my_page: My page + label_account: Account label_my_account: My account label_my_account_data: My account data label_my_projects: My projects @@ -552,6 +558,8 @@ en: label_news_added: News added label_news_comment_added: Comment added to a news label_settings: Settings + label_summary: Summary + label_project_settings: Project settings label_overview: Overview label_version: Version label_version_new: New version @@ -780,7 +788,7 @@ en: label_plugins: Plugins label_ldap_authentication: LDAP authentication label_downloads_abbr: D/L - label_optional_description: Optional description + label_optional_description: Description label_add_another_file: Add another file label_preferences: Preferences label_chronological_order: In chronological order @@ -789,6 +797,7 @@ en: label_incoming_emails: Incoming emails label_generate_key: Generate a key label_issue_watchers: Watchers + button_add_watcher: Add watcher label_example: Example label_display: Display label_sort: Sort @@ -1023,3 +1032,9 @@ en: description_attachment_toggle: Show/Hide attachments description_autocomplete: This field uses autocomplete. While typing the title of an issue you will receive a list of possible candidates. Choose one using the arrow up and arrow down key and select it with tab or enter. Alternatively you can enter the issue number directly. description_noscript: You need to activate JavaScript in order to use Chiliproject! + description_my_project: You are member + description_parent_issue: Parent issue of current + description_sub_issue: Subissue of current + label_issue_hierarchy: "Issue Hierarchy" + more_actions: More functions + show_hide_project_menu: Hide/Show project menu diff --git a/config/locales/es.yml b/config/locales/es.yml index 57792641fc..6828f20b41 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1020,3 +1020,28 @@ es: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/eu.yml b/config/locales/eu.yml index c853b62c70..947213f788 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -987,3 +987,28 @@ eu: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/fa.yml b/config/locales/fa.yml index cab17df438..1ef1a989ff 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -986,3 +986,28 @@ fa: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/fi.yml b/config/locales/fi.yml index a4be9a382a..7b66aefabb 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -1004,3 +1004,28 @@ fi: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/fr.yml b/config/locales/fr.yml index b3a38b9dd8..a386b81305 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1001,3 +1001,28 @@ fr: description_filter: Filter description_choose_project: Projects description_date_from: Enter start date + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/gl.yml b/config/locales/gl.yml index 061af18bea..43a274c763 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -995,3 +995,28 @@ gl: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/he.yml b/config/locales/he.yml index 3e6e099dbf..e8aed9b8ee 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -988,3 +988,28 @@ he: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/hr.yml b/config/locales/hr.yml index 9d793697b4..47f9b8d24b 100644 --- a/config/locales/hr.yml +++ b/config/locales/hr.yml @@ -990,3 +990,28 @@ hr: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/hu.yml b/config/locales/hu.yml index e236ffa1d7..dd4c22f573 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -1002,3 +1002,28 @@ description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/id.yml b/config/locales/id.yml index f3ca947d53..6bdf320707 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -991,3 +991,28 @@ id: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/it.yml b/config/locales/it.yml index 4d3d36c2be..9598f435b0 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -984,3 +984,28 @@ it: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/ja.yml b/config/locales/ja.yml index a674f60686..cf444019e9 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -1005,3 +1005,28 @@ ja: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 9c57a6d5ee..984f7a500a 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -1035,3 +1035,28 @@ ko: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/lt.yml b/config/locales/lt.yml index e6bd2b5367..1a96d46e34 100644 --- a/config/locales/lt.yml +++ b/config/locales/lt.yml @@ -1043,3 +1043,28 @@ lt: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/lv.yml b/config/locales/lv.yml index 29eb0f73e4..4c721302ab 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -978,3 +978,28 @@ lv: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/mk.yml b/config/locales/mk.yml index 77063c5235..a9999317c0 100644 --- a/config/locales/mk.yml +++ b/config/locales/mk.yml @@ -983,3 +983,28 @@ mk: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/mn.yml b/config/locales/mn.yml index d5494c02df..5583ae968b 100644 --- a/config/locales/mn.yml +++ b/config/locales/mn.yml @@ -984,3 +984,28 @@ mn: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 3f070a1f28..aded5643da 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -965,3 +965,28 @@ nl: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/no.yml b/config/locales/no.yml index 5df97464f3..a83f33d167 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -970,3 +970,28 @@ description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/pl.yml b/config/locales/pl.yml index d7309ab870..e86474b243 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -1000,3 +1000,28 @@ pl: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 3ec2859554..85cf795fbe 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -1007,3 +1007,28 @@ pt-BR: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 708d87033b..6a988c01c6 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -987,3 +987,28 @@ pt: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/ro.yml b/config/locales/ro.yml index 693e3a0296..6db26dcaa9 100644 --- a/config/locales/ro.yml +++ b/config/locales/ro.yml @@ -976,3 +976,28 @@ ro: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 3c2570c94a..7cb0805399 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -1096,3 +1096,28 @@ ru: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/sk.yml b/config/locales/sk.yml index b886095307..58250680b6 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -978,3 +978,28 @@ sk: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/sl.yml b/config/locales/sl.yml index 06a8cae159..498f718e61 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -979,3 +979,28 @@ sl: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/sr-YU.yml b/config/locales/sr-YU.yml index a22625f9cb..16667add33 100644 --- a/config/locales/sr-YU.yml +++ b/config/locales/sr-YU.yml @@ -983,3 +983,28 @@ sr-YU: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/sr.yml b/config/locales/sr.yml index de5eb8dda8..df166011f9 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -984,3 +984,28 @@ sr: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/sv.yml b/config/locales/sv.yml index c5d546523b..4262dbb183 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -1025,3 +1025,28 @@ sv: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/th.yml b/config/locales/th.yml index 45e926830a..178b748ad5 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -980,3 +980,28 @@ th: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/tr.yml b/config/locales/tr.yml index ab5c585aef..d03494a95f 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -1002,3 +1002,28 @@ tr: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/uk.yml b/config/locales/uk.yml index bb1074bd70..45a4be0ef6 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -979,3 +979,28 @@ uk: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/vi.yml b/config/locales/vi.yml index c9d39ab5b9..edc8eec50d 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -1034,3 +1034,28 @@ vi: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index a5700fa2f8..3b2f72814c 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -1065,3 +1065,28 @@ description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/config/locales/zh.yml b/config/locales/zh.yml index 007c772e0c..b79b50dc53 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -997,3 +997,28 @@ zh: description_choose_project: Projects description_date_from: Enter start date label_deleted_custom_field: (deleted custom field) + label_checked: checked + label_calendar_show: Show Calendar + description_compare_to: Compare to version + description_active: Active? + label_main_menu: Side Menu + label_enable_multi_select: Toggle multiselect + label_remove_columns: Remove selected columns + notice_account_inactive: Your account has not yet been activated. To activate your account, click on the link that was emailed to you. + description_enter_text: Enter text + label_content: Content + description_current_position: "You are here:" + label_top_menu: Top Menu + description_compare_from: Compare from version + label_add_columns: Add selected columns + button_remove_widget: Remove widget + label_modules: Modules + notice_account_update_failed: Account setting could not be safed. Please have a look at your account page. + description_enter_number: Enter number + description_select_issue: Select issue + label_table_of_contents: Table of Contents + field_impaired: Accessibility mode + search_input_placeholder: search ... + text_analyze: "Further analyze: %{subject}" + label_project_view_all: View all projects + description_subissue: Subissue of diff --git a/extra/svn/reposman.rb b/extra/svn/reposman.rb index 4be5233530..138d94b2dd 100755 --- a/extra/svn/reposman.rb +++ b/extra/svn/reposman.rb @@ -42,6 +42,10 @@ # share repositories through Redmine.pm, you need # to use the apache owner. # -g, --group=GROUP group of the repository. (default: root) +# --public-mode=MODE file mode for new public repositories +# (default: 0775) +# --private-mode=MODE file mode for new private repositories +# (default: 0770) # --scm=SCM the kind of SCM repository you want to create (and # register) in Redmine (default: Subversion). # reposman is able to create Git and Subversion @@ -93,6 +97,8 @@ opts = GetoptLong.new( ['--owner', '-o', GetoptLong::REQUIRED_ARGUMENT], ['--group', '-g', GetoptLong::REQUIRED_ARGUMENT], ['--url', '-u', GetoptLong::REQUIRED_ARGUMENT], + ['--public-mode', GetoptLong::REQUIRED_ARGUMENT], + ['--private-mode', GetoptLong::REQUIRED_ARGUMENT], ['--command' , '-c', GetoptLong::REQUIRED_ARGUMENT], ['--scm', GetoptLong::REQUIRED_ARGUMENT], ['--test', '-t', GetoptLong::NO_ARGUMENT], @@ -109,6 +115,8 @@ $redmine_host = '' $repos_base = '' $svn_owner = 'root' $svn_group = 'root' +$public_mode = '0775' +$private_mode = '0770' $use_groupid = true $svn_url = false $test = false @@ -153,6 +161,8 @@ begin when '--key'; $api_key = arg.dup when '--owner'; $svn_owner = arg.dup; $use_groupid = false; when '--group'; $svn_group = arg.dup; $use_groupid = false; + when '--public-mode'; $public_mode = arg.dup; + when '--private-mode'; $private_mode = arg.dup; when '--url'; $svn_url = arg.dup when '--scm'; $scm = arg.dup.capitalize; log("Invalid SCM: #{$scm}", :exit => true) unless SUPPORTED_SCM.include?($scm) when '--command'; $command = arg.dup @@ -226,7 +236,8 @@ def set_owner_and_rights(project, repos_path, &block) yield if block_given? else uid, gid = Etc.getpwnam($svn_owner).uid, ($use_groupid ? Etc.getgrnam(project.identifier).gid : Etc.getgrnam($svn_group).gid) - right = project.is_public ? 0775 : 0770 + right = project.is_public ? $public_mode : $private_mode + right = right.to_i(8) & 007777 yield if block_given? Find.find(repos_path) do |f| File.chmod right, f diff --git a/lib/chili_project/principal_allowance_evaluator/base.rb b/lib/chili_project/principal_allowance_evaluator/base.rb new file mode 100644 index 0000000000..df8e05287c --- /dev/null +++ b/lib/chili_project/principal_allowance_evaluator/base.rb @@ -0,0 +1,29 @@ +class ChiliProject::PrincipalAllowanceEvaluator::Base + def initialize(user) + @user = user + end + + def granted_for_global? candidate, action, options + false + end + + def denied_for_global? candidate, action, options + false + end + + def granted_for_project? candidate, action, project, options = {} + false + end + + def denied_for_project? candidate, action, project, options = {} + false + end + + def global_granting_candidates + [] + end + + def project_granting_candidates project + [] + end +end diff --git a/lib/chili_project/principal_allowance_evaluator/default.rb b/lib/chili_project/principal_allowance_evaluator/default.rb new file mode 100644 index 0000000000..405ee0ec03 --- /dev/null +++ b/lib/chili_project/principal_allowance_evaluator/default.rb @@ -0,0 +1,30 @@ +class ChiliProject::PrincipalAllowanceEvaluator::Default < ChiliProject::PrincipalAllowanceEvaluator::Base + def granted_for_global?(candidate, action, options) + granted = super + + granted || if candidate.is_a?(Member) + candidate.roles.any?{ |r| r.allowed_to?(action) } + elsif candidate.is_a?(Role) + candidate.allowed_to?(action) + end + end + + def granted_for_project?(role, action, project, options) + return false unless role.is_a?(Role) + granted = super + + granted || (project.is_public? || role.member?) && role.allowed_to?(action) + end + + def global_granting_candidates + role = @user.logged? ? + Role.non_member : + Role.anonymous + + @user.memberships + [role] + end + + def project_granting_candidates(project) + @user.roles_for_project project + end +end diff --git a/lib/redmine.rb b/lib/redmine.rb index 3ce1684147..e70f5f223c 100644 --- a/lib/redmine.rb +++ b/lib/redmine.rb @@ -81,6 +81,7 @@ Redmine::AccessControl.map do |map| :journals => [:index, :diff], :queries => :index, :reports => [:issue_report, :issue_report_details]} + map.permission :export_issues, {:issues => [:index, :all]} map.permission :add_issues, {:issues => [:new, :create, :update_form]} map.permission :edit_issues, {:issues => [:edit, :update, :bulk_edit, :bulk_update, :update_form], :journals => [:new]} map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]} @@ -216,15 +217,19 @@ Redmine::MenuManager.map :project_menu do |menu| menu.push :gantt, { :controller => 'gantts', :action => 'show' }, :param => :project_id, :caption => :label_gantt menu.push :calendar, { :controller => 'calendars', :action => 'show' }, :param => :project_id, :caption => :label_calendar menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural + menu.push :new_news, { :controller => 'news', :action => 'new' }, :param => :project_id, :caption => :label_news_new, :parent => :news, + :if => Proc.new { |p| User.current.allowed_to?(:manage_news, p.project) } menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural menu.push :wiki, { :controller => 'wiki', :action => 'show', :id => nil }, :param => :project_id, :if => Proc.new { |p| p.wiki && !p.wiki.new_record? } + menu.push :wiki_index_by_title, {:action => 'index', :controller => 'wiki'}, :param => :project_id, :caption => :label_index_by_title, :parent => :wiki, :last => true + menu.push :wiki_index_by_date, {:action => 'date_index', :controller => 'wiki'}, :param => :project_id, :caption => :label_index_by_date, :parent => :wiki, :last => true menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id, :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural menu.push :files, { :controller => 'files', :action => 'index' }, :caption => :label_file_plural, :param => :project_id menu.push :repository, { :controller => 'repositories', :action => 'show' }, :if => Proc.new { |p| p.repository && !p.repository.new_record? } - menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true + menu.push :settings, { :controller => 'projects', :action => 'settings' }, :caption => :label_project_settings, :last => true end Redmine::Activity.map do |activity| diff --git a/lib/redmine/menu_manager/menu_helper.rb b/lib/redmine/menu_manager/menu_helper.rb index f04d16c8c3..2447082d90 100644 --- a/lib/redmine/menu_manager/menu_helper.rb +++ b/lib/redmine/menu_manager/menu_helper.rb @@ -33,7 +33,7 @@ module Redmine::MenuManager::MenuHelper menu_items_for(menu, project) do |node| links << render_menu_node(node, project) end - links.empty? ? nil : content_tag('ul', links.join("\n")) + links.empty? ? nil : content_tag('ul', links.join("\n"), :class => "menu_root") end def render_menu_node(node, project=nil) diff --git a/public/images/1downarrow.png b/public/images/1downarrow.png index a6d07e92b2..e63ad4ef1d 100644 Binary files a/public/images/1downarrow.png and b/public/images/1downarrow.png differ diff --git a/public/images/1uparrow.png b/public/images/1uparrow.png index 6c0eae469a..42b07abf2d 100644 Binary files a/public/images/1uparrow.png and b/public/images/1uparrow.png differ diff --git a/public/images/2downarrow.png b/public/images/2downarrow.png index 1796516895..fafa309b76 100644 Binary files a/public/images/2downarrow.png and b/public/images/2downarrow.png differ diff --git a/public/images/2uparrow.png b/public/images/2uparrow.png index 352cc2bb9d..84bb638b4f 100644 Binary files a/public/images/2uparrow.png and b/public/images/2uparrow.png differ diff --git a/public/images/arrow_left_darkred.png b/public/images/arrow_left_darkred.png new file mode 100644 index 0000000000..87514742ae Binary files /dev/null and b/public/images/arrow_left_darkred.png differ diff --git a/public/images/arrow_right_darkred.png b/public/images/arrow_right_darkred.png new file mode 100644 index 0000000000..d54a6a1975 Binary files /dev/null and b/public/images/arrow_right_darkred.png differ diff --git a/public/images/block.png b/public/images/block.png new file mode 100644 index 0000000000..08f249365a Binary files /dev/null and b/public/images/block.png differ diff --git a/public/images/breadcrumb-list.png b/public/images/breadcrumb-list.png new file mode 100644 index 0000000000..ab290b143c Binary files /dev/null and b/public/images/breadcrumb-list.png differ diff --git a/public/images/bullet_arrow_right.png b/public/images/bullet_arrow_right.png index cbcc70ded3..2005bc273c 100644 Binary files a/public/images/bullet_arrow_right.png and b/public/images/bullet_arrow_right.png differ diff --git a/public/images/delete.png b/public/images/delete.png index 08f249365a..d04a554ee1 100644 Binary files a/public/images/delete.png and b/public/images/delete.png differ diff --git a/public/images/delete.png.oxygen b/public/images/delete.png.oxygen deleted file mode 100644 index d04a554ee1..0000000000 Binary files a/public/images/delete.png.oxygen and /dev/null differ diff --git a/public/images/double_arrows_grey_white_sprite.png b/public/images/double_arrows_grey_white_sprite.png new file mode 100644 index 0000000000..6afc0d5b50 Binary files /dev/null and b/public/images/double_arrows_grey_white_sprite.png differ diff --git a/public/images/home_black_white_sprite.png b/public/images/home_black_white_sprite.png new file mode 100644 index 0000000000..5117de639d Binary files /dev/null and b/public/images/home_black_white_sprite.png differ diff --git a/public/images/projectnavi_arrow_left.png b/public/images/projectnavi_arrow_left.png new file mode 100644 index 0000000000..d635403f84 Binary files /dev/null and b/public/images/projectnavi_arrow_left.png differ diff --git a/public/images/projectnavi_arrow_right.png b/public/images/projectnavi_arrow_right.png new file mode 100644 index 0000000000..8907b60f11 Binary files /dev/null and b/public/images/projectnavi_arrow_right.png differ diff --git a/public/images/question_mark_grey_white_sprite.png b/public/images/question_mark_grey_white_sprite.png new file mode 100644 index 0000000000..494eb3fd79 Binary files /dev/null and b/public/images/question_mark_grey_white_sprite.png differ diff --git a/public/images/sources/breadcrumb-list.xcf b/public/images/sources/breadcrumb-list.xcf new file mode 100644 index 0000000000..15bd78d677 Binary files /dev/null and b/public/images/sources/breadcrumb-list.xcf differ diff --git a/public/images/sources/double_arrows_grey_white_sprite.xcf b/public/images/sources/double_arrows_grey_white_sprite.xcf new file mode 100644 index 0000000000..9d92e14d41 Binary files /dev/null and b/public/images/sources/double_arrows_grey_white_sprite.xcf differ diff --git a/public/images/sources/home_black_white_sprite.xcf b/public/images/sources/home_black_white_sprite.xcf new file mode 100644 index 0000000000..2ddb0b95ac Binary files /dev/null and b/public/images/sources/home_black_white_sprite.xcf differ diff --git a/public/images/sources/question_mark_grey_white_sprite.xcf b/public/images/sources/question_mark_grey_white_sprite.xcf new file mode 100644 index 0000000000..bce72a8f1f Binary files /dev/null and b/public/images/sources/question_mark_grey_white_sprite.xcf differ diff --git a/public/images/sources/top_menu_arrow_grey_white_sprite.xcf b/public/images/sources/top_menu_arrow_grey_white_sprite.xcf new file mode 100644 index 0000000000..4c7b3c65ce Binary files /dev/null and b/public/images/sources/top_menu_arrow_grey_white_sprite.xcf differ diff --git a/public/images/top_menu_arrow_grey_white_sprite.png b/public/images/top_menu_arrow_grey_white_sprite.png new file mode 100644 index 0000000000..1353abcd53 Binary files /dev/null and b/public/images/top_menu_arrow_grey_white_sprite.png differ diff --git a/public/javascripts/application.js b/public/javascripts/application.js index d09d91ebb1..ee14c17b56 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -74,38 +74,24 @@ function toggleAllRowGroups(el) { function toggleFieldset(el) { var fieldset = Element.up(el, 'fieldset'); fieldset.toggleClassName('collapsed'); - Effect.toggle(fieldset.down('div'), 'slide', {duration:0.2}); + Effect.toggle(fieldset.down('>div'), 'slide', {duration:0.2}); } function hideFieldset(el) { var fieldset = Element.up(el, 'fieldset'); fieldset.toggleClassName('collapsed'); - fieldset.down('div').hide(); + fieldset.down('>div').hide(); } var fileFieldCount = 1; function addFileField() { - if (fileFieldCount >= 10) return false - fileFieldCount++; - var f = document.createElement("input"); - f.type = "file"; - f.name = "attachments[" + fileFieldCount + "][file]"; - f.size = 30; - var d = document.createElement("input"); - d.type = "text"; - d.name = "attachments[" + fileFieldCount + "][description]"; - d.size = 60; - var dLabel = new Element('label'); - dLabel.addClassName('inline'); - // Pulls the languge value used for Optional Description - dLabel.update($('attachment_description_label_content').innerHTML) - p = document.getElementById("attachments_fields"); - p.appendChild(document.createElement("br")); - p.appendChild(f); - p.appendChild(dLabel); - dLabel.appendChild(d); - + fileFieldCount++; + if (fileFieldCount >= 10) return false + $('attachments_fields').insert($('attachment_template').innerHTML.replace(/\[1\]/g, '['+ fileFieldCount + ']')) + // + // Pulls the languge value used for Optional Description + $('attachments_fields').down('label:last').down('span').update($$('.attachment_description_label_content').first().innerHTML) } function showTab(name) { @@ -164,7 +150,7 @@ function displayTabsButtons() { tabsWidth += lis[i].getWidth() + 6; } } - if ((tabsWidth < el.getWidth() - 60) && (lis[0].visible())) { + if ((tabsWidth < el.getWidth() - 20) && (lis[0].visible())) { el.down('div.tabs-buttons').hide(); } else { el.down('div.tabs-buttons').show(); @@ -465,7 +451,9 @@ function addClickEventToAllErrorMessages() { // Cut off '_id' (necessary for select boxes) field = $($(a).readAttribute('href').substr(1).concat('_id')); } - field.down('input, textarea, select').focus(); + if (field) { + field.down('input, textarea, select').focus(); + } Event.stop(event); return false; }); @@ -473,9 +461,16 @@ function addClickEventToAllErrorMessages() { } $(document).observe('dom:loaded', function() { // Set focus on first error message - var focus = $$('a.afocus').first(); - if (focus != undefined) { - focus.focus(); + var error_focus = $$('a.afocus').first(); + var input_focus = $$('.autofocus').first(); + if (error_focus != undefined) { + error_focus.focus(); + } + else if (input_focus != undefined){ + input_focus.focus(); + if (input_focus.tagName === "INPUT") { + input_focus.select(); + } } // Focus on field with error addClickEventToAllErrorMessages(); @@ -558,6 +553,45 @@ jQuery(document).ready(function($) { return this; }; + $.fn.onClickDropDown = function(){ + var that = this; + $('html').click(function() { + that.find(" > li.drop-down.open").removeClass("open").find("> ul").mySlide(); + that.removeClass("hover"); + }); + + // Do not close the login window when using it + that.find("li li").click(function(event){ + event.stopPropagation(); + }); + + this.find(" > li.drop-down").click(function() { + // if an h2 tag follows the submenu should unfold out at the border + var menu_start_position; + if (that.next().get(0) != undefined && (that.next().get(0).tagName == 'H2')){ + menu_start_position = that.next().innerHeight() + that.next().position().top; + that.find("ul.action_menu_more").css({ top: menu_start_position }); + } + else if(that.next().hasClass("wiki-content") && that.next().children().next().first().get(0) != undefined && that.next().children().next().first().get(0).tagName == 'H1'){ + var wiki_heading = that.next().children().next().first(); + menu_start_position = wiki_heading.innerHeight() + wiki_heading.position().top; + that.find("ul.action_menu_more").css({ top: menu_start_position }); + } + + $(this).toggleSubmenu(that); + return false; + }); + }; + + $.fn.toggleSubmenu = function(menu){ + if (menu.find(" > li.drop-down.open").get(0) !== $(this).get(0)){ + menu.find(" > li.drop-down.open").removeClass("open").find("> ul").mySlide(); + } + + $(this).slideAndFocus(); + menu.toggleClass("hover"); + } + // open and close the main-menu sub-menus $("#main-menu li:has(ul) > a").not("ul ul a") .append("") @@ -603,15 +637,8 @@ jQuery(document).ready(function($) { function(){ return false; }); - jQuery("#account-nav > li.drop-down").click(function() { - if (($("#account-nav > li.drop-down.open").get(0) !== $(this).get(0))){ - $("#account-nav > li.drop-down.open").toggleClass("open").find("> ul").mySlide(); - } - $(this).slideAndFocus(); - $("#account-nav").toggleClass("hover"); - - return false; - }); + $("#account-nav").onClickDropDown(); + $(".action_menu_main").onClickDropDown(); // deal with potentially problematic super-long titles $(".title-bar h2").css({paddingRight: $(".title-bar-actions").outerWidth() + 15 }); @@ -619,6 +646,20 @@ jQuery(document).ready(function($) { // rejigger the main-menu sub-menu functionality. $("#main-menu .toggler").remove(); // remove the togglers so they're inserted properly later. +$(window).resize(function() { + // wait 200 milliseconds for no further resize event + // then readjust breadcrumb + + if(this.resizeTO) clearTimeout(this.resizeTO); + this.resizeTO = setTimeout(function() { + $(this).trigger('resizeEnd'); + }, 200); +}); + +$(window).bind('resizeEnd', function() { + jQuery("div#breadcrumb ul.breadcrumb").adjustBreadcrumbToWindowSize(); +}); + $("#main-menu li:has(ul) > a").not("ul ul a") // 1. unbind the current click functions .unbind("click") @@ -659,14 +700,7 @@ jQuery(document).ready(function($) { }); }); - $('html').click(function() { - $("#header .drop-down.open").toggleClass("open").find("> ul").mySlide(); - $("#account-nav.hover").toggleClass("hover"); - }); // Do not close the login window when using it - $('#account-nav li li').click(function(event){ - event.stopPropagation(); - }); $('#nav-login-content').click(function(event){ event.stopPropagation(); }); @@ -680,4 +714,22 @@ jQuery(document).ready(function($) { div.removeClass('hover'); }); }); + + jQuery('#main-menu #toggle-project-menu a.navigation-toggler').click(function(){ + if ($('#main-menu #toggle-project-menu').hasClass('show')) { + // Show project navigation + $('#menu-sidebar').removeClass('hidden'); + $('#main-menu #toggle-project-menu').removeClass('show'); + $('#main-menu #toggle-project-menu').removeAttr("style"); + $('#content').removeClass('hidden-navigation'); + } + else { + // Hide project navigation + var height = $(document).height(); + $('#menu-sidebar').addClass('hidden'); + $('#main-menu #toggle-project-menu').addClass('show'); + $('#main-menu #toggle-project-menu.show').css({height:height}); + $('#content').addClass('hidden-navigation'); + }; + }); }); diff --git a/public/javascripts/breadcrumb.js b/public/javascripts/breadcrumb.js new file mode 100644 index 0000000000..9c13cc81ed --- /dev/null +++ b/public/javascripts/breadcrumb.js @@ -0,0 +1,51 @@ +jQuery.fn.reverse = [].reverse; +(function($){ + $.fn.adjustBreadcrumbToWindowSize = function(){ + var breadcrumbElements = this.find(' > li'); + var breadcrumb = this; + var lastChanged; + + if (breadcrumb.breadcrumbOutOfBounds()){ + breadcrumbElements.each(function(index) { + if (breadcrumb.breadcrumbOutOfBounds()){ + if (!$(this).find(' > a').hasClass('nocut')){ + $(this).addClass('cutme ellipsis'); + } + } + else { + return false; + } + }); + } + else { + breadcrumbElements.reverse().each(function(index) { + if (!breadcrumb.breadcrumbOutOfBounds()){ + if (!$(this).find(' > a').hasClass('nocut')){ + $(this).removeClass('cutme ellipsis'); + lastChanged = $(this); + } + } + }); + + if (breadcrumb.breadcrumbOutOfBounds()){ + if (lastChanged != undefined){ + lastChanged.addClass('cutme ellipsis'); + return false; + } + } + } + }; + + $.fn.breadcrumbOutOfBounds = function(){ + var lastElement = this.find(' > li').last(); + var rightCorner = lastElement.width() + lastElement.offset().left; + var windowSize = jQuery(window).width(); + + if ((Math.max(1000,windowSize) - rightCorner) < 10) { + return true; + } + else { + return false; + } + }; +})(jQuery) diff --git a/public/javascripts/chosen.js b/public/javascripts/chosen.js index d9fea70bb3..c73a6ed3f6 100644 --- a/public/javascripts/chosen.js +++ b/public/javascripts/chosen.js @@ -69,9 +69,9 @@ container_div.html('

        '); } else { if (this.options.floating_free != null) { - container_div.html('
          '); + container_div.html('
            '); } else { - container_div.html('' + this.default_text + '
              '); + container_div.html('' + this.default_text + '
                '); } } this.form_field_jq.hide().after(container_div); @@ -94,7 +94,7 @@ this.selected_item = this.container.find('.chzn-single').first(); } this.results_build(); - return this.set_tab_index(); + return; }; Chosen.prototype.register_observers = function() { this.container.mousedown(__bind(function(evt) { @@ -119,7 +119,9 @@ return this.search_results_mouseout(evt); }, this)); this.form_field_jq.bind("liszt:updated", __bind(function(evt) { - return this.results_update_field(evt); + this.results_update_field(evt); + this.results_show(); + return false; }, this)); this.search_field.blur(__bind(function(evt) { return this.input_blur(evt); @@ -215,10 +217,6 @@ return; }; Chosen.prototype.activate_field = function() { - if (!this.is_multiple && !this.active_field) { - this.search_field.attr("tabindex", this.selected_item.attr("tabindex")); - this.selected_item.attr("tabindex", -1); - } this.container.addClass("chzn-container-active"); this.active_field = true; this.search_field.val(this.search_field.val()); @@ -354,19 +352,6 @@ }); return this.results_showing = false; }; - Chosen.prototype.set_tab_index = function(el) { - var ti; - if (this.form_field_jq.attr("tabindex")) { - ti = this.form_field_jq.attr("tabindex"); - this.form_field_jq.attr("tabindex", -1); - if (this.is_multiple) { - return this.search_field.attr("tabindex", ti); - } else { - this.selected_item.attr("tabindex", ti); - return this.search_field.attr("tabindex", -1); - } - } - }; Chosen.prototype.show_search_field_default = function() { if (this.is_multiple && this.choices < 1 && !this.active_field) { this.search_field.val(this.default_text); diff --git a/public/javascripts/context_menu.js b/public/javascripts/context_menu.js index 79d8ebbade..b708914872 100644 --- a/public/javascripts/context_menu.js +++ b/public/javascripts/context_menu.js @@ -100,7 +100,7 @@ ContextMenu.prototype = { var mouse_x = Event.pointerX(e); var mouse_y = Event.pointerY(e); var render_x = mouse_x; - var render_y = mouse_y; + var render_y = mouse_y - $('top-menu').getHeight(); var dims; var menu_width; var menu_height; @@ -122,9 +122,9 @@ ContextMenu.prototype = { dims = $('context-menu').getDimensions(); menu_width = dims.width; menu_height = dims.height; - max_width = mouse_x + 2*menu_width; - max_height = mouse_y + menu_height; - + max_width = render_x + 2*menu_width; + max_height = render_y + menu_height; + var ws = window_size(); window_width = ws.width; window_height = ws.height; diff --git a/public/javascripts/copy_issue_actions.js b/public/javascripts/copy_issue_actions.js new file mode 100644 index 0000000000..95203328d0 --- /dev/null +++ b/public/javascripts/copy_issue_actions.js @@ -0,0 +1,5 @@ +jQuery(document).ready(function(){ + var clone = jQuery('.action_menu_main').clone(); + jQuery('#lower-title-bar').append(clone); + clone.onClickDropDown(); +}); diff --git a/public/stylesheets/accessibility.css b/public/stylesheets/accessibility.css new file mode 100644 index 0000000000..82244d6848 --- /dev/null +++ b/public/stylesheets/accessibility.css @@ -0,0 +1,7 @@ +a:focus, +input:focus, +select:focus, +textarea:focus, +button:focus { + outline: 3px solid darkblue; +} diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css index dd66049f5f..1aa4eaff9a 100644 --- a/public/stylesheets/application.css +++ b/public/stylesheets/application.css @@ -1,11 +1,9 @@ html {overflow-y:scroll;} -body { font-size: 12px; margin: 0; padding: 0; min-width: 900px; } +body { margin: 0; padding: 0; min-width: 900px; } -h1, h2, h3, h4 { font-family:"Arial", Arial, sans-serif; } h1 {margin:0; padding:0; font-size: 24px;} -h2, .wiki h1 {font-size: 20px;padding: 2px 10px 1px 0px;margin: 0 0 10px 0; border-bottom: 1px solid #bbbbbb; } h3, .wiki h2 {font-size: 16px;padding: 2px 10px 1px 0px;margin: 0 0 10px 0; border-bottom: 1px solid #bbbbbb; } -h4, .wiki h3 {font-size: 13px;padding: 2px 10px 1px 0px;margin-bottom: 5px; border-bottom: 1px dotted #bbbbbb;} +h4, .wiki h3 {font-size: 13px;padding: 0px 10px 1px 0px;margin-bottom: 5px; border-bottom: 1px dotted #bbbbbb;} /***** Layout *****/ #wrapper {background: none;} @@ -26,15 +24,19 @@ h4, .wiki h3 {font-size: 13px;padding: 2px 10px 1px 0px;margin-bottom: 5px; bord #quick-search {float:right;} #main-menu {position: absolute; bottom: auto; left:6px; margin-right: -500px;} -#main-menu ul {margin: 0; padding: 0;} -#main-menu li { +#main-menu ul { + margin: 0; + padding: 0; + border-right: 1px solid #ddd; +} +#main-menu ul.menu_root li { float: none; list-style-type:none; margin: 0px; padding: 0px 0px 0px 0px; white-space:nowrap; } -#main-menu li a { +#main-menu ul.menu_root li a { display: block; text-decoration: none; font-weight: normal; @@ -42,13 +44,12 @@ h4, .wiki h3 {font-size: 13px;padding: 2px 10px 1px 0px;margin-bottom: 5px; bord margin: 0; padding: 0 0 0 24px; } -#main-menu li a:hover {color:#555; text-decoration: none;} +#main-menu ul.menu_root li a:hover {color:#555; text-decoration: none;} #content { width: 75%; background-color: #fff; margin: 0px; - border: 1px #ddd; border-style: none solid solid solid; padding: 6px 10px 10px 10px; z-index: 10; @@ -60,7 +61,7 @@ html>body #content { min-height: 600px; } #main.nosidebar #sidebar{ display: none; } #main.nosidebar #content{ width: auto } -#footer {clear: both; font-size: 0.9em; color: #aaa; padding: 5px; text-align:center;} +#footer {clear: both; font-size: 0.9em; color: #aaa; padding: 5px; text-align:right;} #login-form table {margin-top:5em; padding:1em; margin-left: auto; margin-right: auto; border: 2px solid #FDBF3B; background-color:#FFEBC1; } #login-form table td {padding: 6px;} @@ -81,19 +82,30 @@ input#openid_url { background: url(../images/openid-bg.gif) no-repeat; backgroun .clear:after{ content: "."; display: block; height: 0; clear: both; visibility: hidden; } /***** Links *****/ -a, a:link, a:visited { +a, a:link, a:visited, input.input-as-link { text-decoration: none; color: #6a0406; font-weight:bold; } -a:hover, a:active{ text-decoration: underline;} +a:hover, a:active, input.input-as-link:hover { text-decoration: underline;} + +input.input-as-link { + border: none; + background-color: transparent; + font-size: 13px; + font-family: Arial; + cursor: pointer; + vertical-align: 0; +} a img{ border: 0; } -a.issue.closed, a.issue.closed:link, a.issue.closed:visited { text-decoration: line-through; } +a.issue.closed, a.issue.closed:link, a.issue.closed:visited { + text-decoration: line-through; +} /***** Tables *****/ table.list { border: 1px solid #e4e4e4; border-collapse: collapse; width: 100%; margin-bottom: 4px; } -table.list th { background-color:#EEEEEE; padding: 4px; white-space:nowrap; } +table.list th { background-color:#E6E6E6; padding: 4px; white-space:nowrap; } table.list td { vertical-align: top; } table.list td.id { width: 2%; text-align: center;} table.list td.checkbox { width: 15px; padding: 2px 0 0 0; } @@ -153,7 +165,7 @@ table.members td.roles, table.memberships td.roles { width: 45%; } tr.message { height: 2.6em; } tr.message td.created_on { white-space: nowrap; } -tr.message td.last_message { font-size: 80%; white-space: nowrap; } +tr.message td.last_message { white-space: nowrap; } tr.version td.closed, tr.version td.closed a { text-decoration: line-through; } tr.version td.name { padding-left: 20px; } @@ -208,8 +220,8 @@ div.news h3 { background: url(../images/news.png) no-repeat 0% 50%; padding-left div.projects h3 { background: url(../images/projects.png) no-repeat 0% 50%; padding-left: 20px; } #watchers ul {margin: 0; padding: 0;} -#watchers li {list-style-type:none;margin: 0px 2px 0px 0px; padding: 0px 0px 0px 0px;} -#watchers select {width: 95%; display: block;} +#watchers li {list-style-type:none;margin: 0px 2px 0px 0px; padding: 0px 0px 0px 0px;float:left;} +#watchers select {width: 200px; display: block;float:left;margin-right:10px;} #watchers a.delete {opacity: 0.4;} #watchers a.delete:hover {opacity: 1;} #watchers img.gravatar {vertical-align: middle;margin: 0 4px 2px 0;} @@ -233,7 +245,7 @@ div.square { overflow: hidden; width: .6em; height: .6em; } -.contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top:5px; padding-left: 10px; font-size:0.9em;} +.contextual {float:right; white-space: nowrap; line-height:1.4em;margin-top: 8px; padding-left: 10px;} .contextual input, .contextual select {font-size:0.9em;} .message .contextual { margin-top: 0; } @@ -241,14 +253,13 @@ div.square { .splitcontentright{float:right; width:49%;} form {display: inline;} input, select {vertical-align: middle; margin-top: 1px; margin-bottom: 1px;} -fieldset {border: 1px solid #e4e4e4; margin:0; padding:4px;} +fieldset {border: 1px solid #e4e4e4; margin:0} hr { width: 100%; height: 1px; background: #ccc; border: 0;} blockquote { font-style: italic; border-left: 3px solid #e0e0e0; padding-left: 0.6em; margin-left: 2.4em;} blockquote blockquote { margin-left: 0;} .news label.timestamp { border-bottom: 1px dotted; cursor: help; } textarea.wiki-edit { width: 99%; } li p {margin-top: 0;} -div.issue {padding:6px; margin-bottom:6px;} p.breadcrumb { font-size: 0.9em; margin: 4px 0 4px 0;} p.subtitle { font-size: 0.9em; margin: -6px 0 12px 0; font-style: italic; } p.footnote { font-size: 0.9em; margin-top: 0px; margin-bottom: 0px; } @@ -256,35 +267,21 @@ p.footnote { font-size: 0.9em; margin-top: 0px; margin-bottom: 0px; } div.issue div.subject div div { padding-left: 16px; } div.issue div.subject p {margin: 0; margin-bottom: 0.1em; font-size: 90%; color: #999;} div.issue div.subject>div>p { margin-top: 0.5em; } -div.issue div.subject h3 {margin: 0; margin-bottom: 0.1em;} +#issue_tree { border: 0; } #issue_tree table.issues { border: 0; } #issue_tree td.checkbox {display:none;} #content fieldset#filters { padding-bottom:10px; } -fieldset#filters legend { - -moz-border-radius-bottomleft:0px; - -moz-border-radius-bottomright:0px; - -webkit-border-bottom-left-radius:0px; - -webkit-border-bottom-right-radius:0px; - border-bottom-left-radius:0px; - border-bottom-right-radius:0px; - } -fieldset#column_options legend { - -moz-border-radius-topleft:0px; - -moz-border-radius-topright:0px; - -webkit-border-top-left-radius:0px; - -webkit-border-top-right-radius:0px; - border-top-left-radius:0px; - border-top-right-radius:0px; - } #content fieldset.collapsible.header_collapsible { padding-top:0px; padding-bottom:0px; border:0px; margin:0px; + margin-right:10px; + margin-left:1px; } fieldset.collapsible.header_collapsible > div { padding-top:5px; @@ -295,26 +292,13 @@ fieldset.collapsible.header_collapsible > * { border-right:1px solid #E6E6E6; border-bottom:1px solid #E6E6E6; width:100%; + padding-left:6px; } fieldset.collapsible.header_collapsible legend { background:#E6E6E6 url(../images/projectnavi_arrow_up.png) no-repeat 99% 50%; cursor:pointer; - padding-left:0px; width:100%; height:23px; line-height:24px; - text-indent:8px; - -moz-border-radius-topleft:5px; - -moz-border-radius-topright:5px; - -webkit-border-top-left-radius:5px; - -webkit-border-top-right-radius:5px; - border-top-left-radius:5px; - border-top-right-radius:5px; - -moz-border-radius-bottomleft:0px; - -moz-border-radius-bottomright:0px; - -webkit-border-bottom-left-radius:0px; - -webkit-border-bottom-right-radius:0px; - border-bottom-left-radius:0px; - border-bottom-right-radius:0px; } fieldset.collapsible.header_collapsible legend:hover { @@ -322,11 +306,8 @@ fieldset.collapsible.header_collapsible legend:hover { } fieldset.collapsible.collapsed.header_collapsible legend { background-image:url(../images/projectnavi_arrow_down.png); - -moz-border-radius:5px; - -webkit-border-radius:5px; - border-radius:5px; } -fieldset.collapsible { border-width: 1px 0 0 0; font-size: 0.9em; } +fieldset.collapsible { border-width: 1px 0 0 0; } fieldset.collapsible.borders { border-width: 1px; } fieldset.collapsible.collapsed.borders { border-width: 1px 0 0 0; } fieldset.collapsible legend { padding-left: 16px; background: url(../images/arrow_expanded.png) no-repeat 0% 40%; cursor:pointer; } @@ -337,7 +318,7 @@ fieldset#filters table { border-collapse: collapse; } fieldset#filters table td { padding: 0; vertical-align: middle; } fieldset#filters tr.filter { height: 2em; } fieldset#filters td.add-filter { text-align: right; vertical-align: top; } -.buttons { font-size: 0.9em; margin-bottom: 1.4em; margin-top: 1em; } +.buttons { margin-bottom: 1.4em; margin-top: 1em; } div#issue-changesets {float:right; width:45%; margin-left: 1em; margin-bottom: 1em; background: #fff; padding-left: 1em; font-size: 90%;} div#issue-changesets div.changeset { padding: 4px;} @@ -378,7 +359,10 @@ dt.time-entry { background-image: url(../images/time.png); } .search-pagination { text-align: center; } .search-pagination a {padding: 0 5px; } -div#roadmap .related-issues { margin-bottom: 1em; } +div#roadmap .related-issues { + border: 0; + margin-bottom: 1em; +} div#roadmap .related-issues td.checkbox { display: none; } div#roadmap .wiki h1:first-child { display: none; } div#roadmap .wiki h1 { font-size: 120%; } @@ -490,6 +474,9 @@ fieldset#notified_events .parent { padding-left: 20px; } .required {color: #bb0000;} .summary {font-style: italic;} +input.attachment_choose_file { + float:left; +} #attachments {font-size: 1em; } #attachments_fields input[type=text] {margin-left: 8px; } @@ -507,7 +494,7 @@ a.atom { background: url(../images/feed.png) no-repeat 1px 50%; padding: 2px 0px div#tab-content-members .splitcontentleft, div#tab-content-memberships .splitcontentleft, div#tab-content-users .splitcontentleft { width: 64% } div#tab-content-members .splitcontentright, div#tab-content-memberships .splitcontentright, div#tab-content-users .splitcontentright { width: 34% } div#tab-content-members fieldset, div#tab-content-memberships fieldset, div#tab-content-users fieldset { padding:1em; margin-bottom: 1em; } -div#tab-content-members fieldset legend, div#tab-content-memberships fieldset legend, div#tab-content-users fieldset legend { font-weight: bold; } +div#tab-content-info fieldset legend, div#tab-content-members fieldset legend, div#tab-content-memberships fieldset legend, div#tab-content-users fieldset legend { font-weight: bold; } div#tab-content-members fieldset label, div#tab-content-memberships fieldset label, div#tab-content-users fieldset label { display: block; } div#tab-content-members fieldset div, div#tab-content-users fieldset div { max-height: 400px; overflow:auto; } div#tab-content-members .user.status_registered, div#tab-content-members label.status_registered { filter: alpha(opacity=80); -khtml-opacity: 0.8; opacity: 0.8; -moz-opacity: 0.8; } @@ -522,7 +509,6 @@ input#principal_search, input#user_search {width:100%} #errorExplanation, div.flash, .nodata, .warning { padding: 4px 4px 4px 30px; margin-bottom: 12px; - font-size: 1.1em; border: 2px solid; margin:0 0 10px; border:1px solid; @@ -667,8 +653,17 @@ p.pourcent {font-size: 80%;} p.progress-info {clear: left; font-style: italic; font-size: 80%;} /***** Tabs *****/ -#content .tabs {height: 2.6em; margin-bottom:1.2em; z-index:1; overflow:hidden;} +#content .tabs { + position: relative; + height: 2.6em; + margin-bottom:1.2em; + z-index:1; + overflow:hidden; +} #content .tabs ul { + position: absolute; + left: 0px; + right: 60px; margin:0; bottom:0; padding-left:1em; @@ -854,9 +849,8 @@ padding: 15px 0 15px 0; .mypage-box { margin-top:20px; - padding: 0px 10px 0px 10px; + padding: 8px 10px 0px 10px; border: #C4C4C4 solid 1px; - font-size:11px; background: #FFFFFF url(../images/background_widgets.png) repeat-x 0 0; min-height: 65px; @@ -882,7 +876,6 @@ padding: 15px 0 15px 0; } .mypage-box h3, .mypage-box a { - font-size:11px; font-weight:bold; } @@ -1018,6 +1011,7 @@ padding-bottom: 3px; .icon-issue { background-image: url(../images/ticket.png); } .icon-zoom-in { background-image: url(../images/zoom_in.png); } .icon-zoom-out { background-image: url(../images/zoom_out.png); } +.icon-more { background-image: url(../images/text_list_bullets.png); } .icon-file { background-image: url(../images/files/default.png); } .icon-file.text-plain { background-image: url(../images/files/text.png); } @@ -1035,7 +1029,6 @@ padding-bottom: 3px; .icon-file.application-x-gzip { background-image: url(../images/files/zip.png); } img.gravatar { - padding: 2px; border: solid 1px #d5d5d5; background: #fff; } @@ -1055,13 +1048,11 @@ div.issue table img.gravatar { } h2 img.gravatar { - padding: 3px; margin: -2px 4px -4px 0; vertical-align: top; } h4 img.gravatar { - padding: 3px; margin: -6px 0 -4px 0; vertical-align: top; } @@ -1119,8 +1110,8 @@ h2 img { vertical-align:middle; } ------------------------------------------------------------------------------*/ body { - font: normal normal normal 12px/1.5 arial,'lucida grandriale','lucida sans unicode',tahom,sans-serif; - background:#f3f3f3; + font: normal normal normal 13px/1.5 arial,'lucida grandriale','lucida sans unicode',tahom,sans-serif; + background:white; color:#333; } @@ -1131,12 +1122,14 @@ h1,h2,h3,h4,h5,h6 { h1 { font-size:21px; } -h2 { - font-size:18px; +h2, .wiki h1 { + font-size: 18px; + padding: 2px 10px 1px 0px; + margin: 0 0 10px 0; + border-bottom: 1px solid #bbbbbb; } h3 { font-size:16px; - font-weight:normal; margin-bottom:16px; } h4 { @@ -1222,21 +1215,29 @@ a:hover { width:100%; } #header li.drop-down > a { - background:url(../images/arrow-down-white.png) no-repeat right center; + /* Arrow down white */ + background-image:url(../images/top_menu_arrow_grey_white_sprite.png); + background-position:right -40px; + background-repeat:no-repeat; padding-right:35px; } #header li > a:hover { background-color:#700407; } #header li.drop-down > a:hover { - background:#700407 url(../images/arrow-down-grey.png) no-repeat right center; + /* Arrow down grey */ + background-image:url(../images/top_menu_arrow_grey_white_sprite.png); + background-position:right -2px; + background-repeat:no-repeat; + + background-color:#700407; padding-right:35px; } #header li li a:hover { background-color:#FFFFFF; color:#222222; } -#header li.drop-down li > a:hover, #main-menu li a.selected, #main-menu li a:hover { +#header li.drop-down li > a:hover, #main-menu ul.menu_root li a.selected, #main-menu ul.menu_root li a:hover { -moz-border-radius-topleft:5px; -moz-border-radius-topright:5px; -webkit-border-top-left-radius:5px; @@ -1257,17 +1258,30 @@ li a.home { text-indent:-999em; width:20px; height:43px; - background:url(../images/icon_home.png) no-repeat 50% 50%; + + /* Home Black */ + background-image:url(../images/home_black_white_sprite.png); + background-position:center -3px; + background-repeat:no-repeat; +} + +li a.home:hover { + background-position:center -35px; } li a.help { text-indent:-999em; width:20px; height:43px; - background:url(../images/icon_help.png) no-repeat 50% 50%; + + /* Question mark white */ + background-image:url(../images/question_mark_grey_white_sprite.png); + background-repeat:no-repeat; + background-position:center -6px; } li a.help:hover { - background-image:url(../images/icon_help_grey.png); + /* Question mark grey */ + background-position:center -41px; } #header li.drop-down.open > a { background:#FFFFFF url(../images/arrow-down-grey.png) no-repeat right center; @@ -1282,17 +1296,23 @@ li a.help:hover { padding:0px 9px 0px; } #header .search_field { + position: relative; border:0px; color:white; - background:transparent url(../images/background_suche.png); - background-repeat:repeat-x; - margin-right:15px; - margin-top:6px; - margin-bottom:4px; - padding-left:10px; - padding-right:27px; - width:125px; - height:30px; + background: none; + top: 6px; + width: 119px; + left: 8px; + outline: 0px; +} +#header #search_wrap { + background:transparent url(../images/background_suche.png); + background-repeat:repeat-x; + width:162px; + height: 30px; + margin-right:15px; + margin-top:6px; + margin-bottom:4px; } input::-webkit-input-placeholder { color: white; @@ -1348,17 +1368,26 @@ input:-moz-placeholder { height:15px; line-height:15px; } + +#breadcrumb { + height:38px; + overflow:hidden; + background:url(../images/background_breadcrumb.png) repeat-x left top; + min-width:1000px; +} + #breadcrumb h1 { - height:38px; - line-height:38px; - background:url(../images/background_breadcrumb.png) repeat-x left top; - border-bottom: 1px #d9d9d9; - color:#333333; - padding-left:15px; - font-family:"Arial", Arial, sans-serif; - font-style:normal; - font-weight:normal; - font-size: 13px; + height:16px; + line-height:16px; + border-bottom: 1px #d9d9d9; + color:#333333; + font-family:"Arial", Arial, sans-serif; + font-style:normal; + font-weight:normal; + font-size: 11px; + margin-top: 12px; + margin-bottom:0px; + margin-left:20px; } #breadcrumb a { text-decoration:underline; @@ -1430,24 +1459,24 @@ div#optional_login_fields { border:1px solid #AFAFAF; background:#f3f3f3; } -#main-menu li { +#main-menu ul.menu_root li { border-top:1px solid #f5f5f5; border-bottom:1px solid #e2e2e2; position:relative; min-height:23px; background-color:#e9e9e9; } -#main-menu li li { +#main-menu ul.menu_root li li { border:0; background-color:white; } -#main-menu li li li { +#main-menu ul.menu_root li li li { padding:0; width:100%; border-bottom:1px solid #DDDDDD; border-top:1px solid #FFFFFF; } -#main-menu li li li:first-child { +#main-menu ul.menu_root li li li:first-child { border-top:0; } #main-menu a { @@ -1462,73 +1491,78 @@ div#optional_login_fields { font-family:"Arial", Arial, sans-serif; font-style:normal; } -#main-menu li a { +#main-menu ul.menu_root li a { margin:6px; font-weight:bold; padding: 0 0 0 20px; } #main-menu a.selected, #main-menu a:hover { } -#main-menu li li a { +#main-menu ul.menu_root li li a { font-weight:normal; } -#main-menu li li.current a { +#main-menu ul.menu_root li li.current a { font-weight:bold; } -#main-menu li li a span { +#main-menu ul.menu_root li li a span { font-weight:normal; color:#999; float:right; padding-right:9px; } -#main-menu li li li a span { +#main-menu ul.menu_root li li li a span { padding:0; } #main-menu .toggler { position:absolute; right:0px; top:0px; - background:url(../images/projectnavi_arrow_down.png) no-repeat 22px 7px; width:40px; height:25px; } -#main-menu li .open .toggler { - background-image:url(../images/projectnavi_arrow_up.png); -} -#main-menu li .open:hover .toggler { - background-image:url(../images/projectnavi_arrow_up_white.png); +#main-menu .toggler { + /* Arrow down */ + background-image: url(../images/double_arrows_grey_white_sprite.png); + background-position: 10px -1px; } -#main-menu li .selected .toggler { - background-image:url(../images/projectnavi_arrow_down_white.png); + +#main-menu ul.menu_root li .open .toggler { + /* Arrow up */ + background-image: url(../images/double_arrows_grey_white_sprite.png); + background-position: 10px -26px; } -#main-menu li .selected.open .toggler { - background-image:url(../images/projectnavi_arrow_up_white.png); +#main-menu ul.menu_root li .selected.open .toggler, #main-menu ul.menu_root li .open:hover .toggler { + /* Arrow up white */ + background-image: url(../images/double_arrows_grey_white_sprite.png); + background-position: 10px -159px; } -#main-menu li a:hover .toggler { - background-image:url(../images/projectnavi_arrow_down_white.png); +#main-menu ul.menu_root li a:hover .toggler, #main-menu ul.menu_root li .selected .toggler { + /* Arrow down white */ + background-image: url(../images/double_arrows_grey_white_sprite.png); + background-position: 10px -120px; } -#main-menu li li .toggler { +#main-menu ul.menu_root li li .toggler { display:none; } -#main-menu li li li a { +#main-menu ul.menu_root li li li a { padding:0 12px; } -#main-menu li li ul.profile-box li { +#main-menu ul.menu_root li li ul.profile-box li { padding:6px 12px; } -#main-menu li li ul.profile-box li a { +#main-menu ul.menu_root li li ul.profile-box li a { display:inline; padding:0; color:#226D81; line-height:1.5; } -#main-menu li li ul.profile-box li a:hover { +#main-menu ul.menu_root li li ul.profile-box li a:hover { text-decoration:underline; } /* Mimic ".icon .icon-time" */ -#main-menu li a.time-details, #main-menu li a.billable-time-details, #main-menu li a.overhead-time-details { background-image:url(../../../images/time.png); background-position:30px 40%; background-repeat:no-repeat; padding-left:50px; } +#main-menu ul.menu_root li a.time-details, #main-menu ul.menu_root li a.billable-time-details, #main-menu ul.menu_root li a.overhead-time-details { background-image:url(../../../images/time.png); background-position:30px 40%; background-repeat:no-repeat; padding-left:50px; } #main-menu p.password { font-weight: bold; margin: 25px 0; } @@ -1540,31 +1574,27 @@ div#optional_login_fields { * This section includes the layout and styles for the main content area. ------------------------------------------------------------------------------*/ #main { - background:#f3f3f3; + background:white; position:relative; z-index:20; } -#footer { color: #aaa; padding-left: 186px } +#footer { + color: #aaa; + border-top:0px; +} h1.title { margin:12px 24px 9px; } #content { - margin:0 15px 10px 185px; + margin:0 15px 10px 187px; padding:10px; - font-size:11px; width: auto; } #content .title-bar { position:relative; - margin-bottom:10px; -} -.title-bar h2 { - padding:9px 100px 9px 12px; - color:#000; - font-weight:normal; - font-weight:bold; } + .title-bar h2 span { font-weight:bold; } @@ -1656,11 +1686,10 @@ form#issue-list { } #content table th { font-weight:normal; - background:#f3f3f3 url(../images/gradient-down.png) repeat-x; } #content table.issues td, #content table th { border:1px solid #e6e6e6; - padding:6px; + padding: 3px 6px; text-align:left; position:relative; vertical-align:top; @@ -1669,6 +1698,10 @@ form#issue-list { color:#111; text-decoration:none; } +#content table th a:hover { + color:#6a0406; + text-decoration:underline; +} #content table th.current-sort { background:#fff url(../images/gradient-up.png) repeat-x; } @@ -1677,14 +1710,17 @@ form#issue-list { padding-right:16px; display:block; } +#content table tr.odd { + background-color:white; +} #content table tr.even { - background-color:#f9f9f9; + background-color:#f6f7f8; } -#content table tr.context-menu-selection { - background:#FEFBD0 url(../images/selected-gradient.jpg) repeat-x left top; +#content table tr.even:hover, #content table tr.odd:hover { + background-color: #FFD; } -#content table td.priority { - text-align:center; +#content table tr.context-menu-selection, #content table tr.context-menu-selection:hover { + background-color:#FFFFB2; } #content table td.issue { background:url(../images/arrow-bottom-right.png) no-repeat right bottom; @@ -1726,6 +1762,7 @@ form#issue-list { top:0; padding:0 100px 0 10px; height:100%; + margin-top: 2px; } .title-bar .title-bar-actions .contextual { /* line-height:3.5;*/ @@ -1735,8 +1772,7 @@ form#issue-list { /* color:#fff;*/ } .title-bar .title-bar-actions .contextual a.icon { - color:#000000; - margin-right: 0px; + margin-right: 0px; } .title-bar .update { right:0; @@ -1747,15 +1783,16 @@ form#issue-list { font-weight:bold; } div.issue { - padding:10px; } div.issue hr { - margin:10px -10px; + margin-top:10px; + margin-bottom:10px; clear:both; } -div.issue h3 { - font-size:14px; - border:0px; +#content div.issue h3, div.issue h3 { + border:0px; + margin-top: -6px; + margin-bottom: 0px; } #content .meta table { border:0 none; @@ -1767,6 +1804,7 @@ div.issue h3 { background: none; border:0 none; padding:0 3px; + padding-left: 0px; } #content .meta table th { font-weight:bold; @@ -1815,34 +1853,35 @@ table.files { } #history { margin:20px 0; + margin-bottom:0px; } #history h3 { - font-size:14px; border-bottom:1px solid #ddd; - padding-left:10px; margin-bottom:20px; } #history .journal { position:relative; - padding-left:50px; margin:0 0 15px; - clear:both; + margin-bottom:45px; min-height:40px; + clear:left; + margin-left: 3px; } .journal .profile-wrap { - float:none; - position:absolute; + float:left; + position:relative; left:0; top:0; + padding-left:4px; + padding-right:4px; } .journal h4 { font-size:12px; font-weight:normal; - margin-bottom:-1px; - padding-bottom:12px; - background:url(../images/speech-white.png) no-repeat 30px bottom; position:relative; z-index:5; + border: 0; + margin-bottom: 0px; } .journal.question h4 { background-image:url(../images/speech-blue.png); @@ -1852,8 +1891,9 @@ table.files { color:#999; } .journal .wiki { - padding:10px 10px 5px; + padding:10px 10px 5px 0px; overflow:auto; + margin-left:50px; } .journal .contextual { float:right; @@ -1887,7 +1927,7 @@ blockquote { background:url(../images/blockquote-bg.png) no-repeat 25px 3px; } .wiki ul li { - list-style: disc outside none; + list-style: disc inside none; } .file-thumbs { margin:20px 0 0; @@ -1909,7 +1949,16 @@ blockquote { border:0; } -.journal-attributes {color: #333333;} +.journal-attributes { + color: #333333; + font-size: 11px; +} +ul.journal-attributes { + list-style-type: disc; +} +ul.journal-attributes li { + margin-left: 75px; +} /*------------------------------------------------------------------------------- * =06 - Projects Page @@ -1920,7 +1969,6 @@ blockquote { #content.nosidebar { margin-left:20px; padding:15px 60px 15px 25px; - font-size:12px; } #project-links { @@ -1987,6 +2035,8 @@ ul.projects li div.root { position:relative; width:42px; height:42px; + top: 7px; + right: 14px; } .profile-box { position:absolute; @@ -2246,6 +2296,10 @@ ul.projects div.root a.project { border:0 none; } +div.issue div#relations { + margin-top: 25px; +} + /* sidebar cleanup */ #sidebar { padding:10px 10px 2px 20px; @@ -2256,23 +2310,29 @@ ul.projects div.root a.project { font-family:"Arial", Arial, sans-serif; font-style:normal; } + #sidebar h3 { color:#333333; font-weight:bold; - font-size:12px; + font-size:14px; font-family:"Arial", Arial, sans-serif; font-style:normal; margin:0px; padding:0px; + margin-top:20px; margin-bottom:8px; } + +div#sidebar > h3:first-child { + margin-top: 0px; +} + #sidebar a, #sidebar a:link, #sidebar a:visited { color: #6a0406; font-weight:bold; height:auto; display:inline; position:static; - font-size:11px; font-style:normal; line-height:1.5; } @@ -2286,13 +2346,13 @@ ul.projects div.root a.project { #sidebar li {border: none; } #sidebar li a {padding: 0px; } -#main-menu li li a { +#main-menu ul.menu_root li li a { padding-left:30px; padding-right:3px; text-indent:-6px; letter-spacing:-.01em; } -#main-menu li a.time-details, #main-menu li a.overhead-time-details, #main-menu li a.billable-time-details { +#main-menu ul.menu_root li a.time-details, #main-menu ul.menu_root li a.overhead-time-details, #main-menu ul.menu_root li a.billable-time-details { padding-left:40px; background-position:12px 45%; } @@ -2356,13 +2416,10 @@ div.issue hr { .question .wiki { margin:0; } -.wiki { - font-size:12px; -} .wiki ol, .wiki ul { margin-bottom:6px; } -#content h3 { +#content h3, #history h3 { margin:12px 0 6px; } #content h2 + h3 { @@ -2374,7 +2431,7 @@ div.issue img.gravatar, #history img.gravatar { padding:0; } p.author { - margin-bottom:3px; + margin-bottom: 15px; font-style:italic; } /* add filter select box on non-issue pages */ @@ -2462,11 +2519,6 @@ tr.time-entry { height:25px; } -/* Weird Safari cascade bug. More specificity */ -div.issue p, div.issue div, #content td { - font-size:11px; -} - /* comments */ .wiki ol li { list-style: decimal outside; @@ -2476,10 +2528,6 @@ div.issue p, div.issue div, #content td { #content table .changeset td.id a:hover { text-decoration:underline; } -#history .journal { - clear:left; - margin-bottom:45px; -} /* issue updates */ #update form#issue-form .attributes p { @@ -2637,6 +2685,11 @@ Additional wiki styles border: 1px solid #C7CFCA; } +.reorder-icons img { + padding-right: 3px; + padding-left: 3px; +} + /* Accessibility specific styles */ .hidden-for-sighted { @@ -2657,3 +2710,241 @@ Additional wiki styles -o-text-overflow: ellipsis; -ms-text-overflow: ellipsis; } + +label.label-with-input { + display: block; + white-space: nowrap; + zoom: 1; + margin-left: 0px; + float: none; +} + +fieldset#attachments input, fieldset#attachments span.add_another_file { + zoom: 1; + margin-left: 10px; + margin-right: 10px; +} + +#query_form_content { + padding-top: 10px; +} +#lower-title-bar div.contextual { + margin-top: -8px; +} +#lower-title-bar { + margin-top: 30px; + margin-left: 10px; +} +#watchers .contextual { + margin-top:0px; +} +div.description, div.issue_tree, div.relations { + padding-left: 3px; +} +div.box-actions { + float:right; + margin-right:16px; + z-index:500; +} +div.block-receiver div.mypage-box { + margin-top: 8px; + padding-bottom: 8px; +} +div.block-receiver div.mypage-box div.box-actions { + margin-top: 5px; +} +h4.overview { + margin-bottom: 0px; + border: 0; +} +div.mypage-box p.summary { + font-style: normal; +} +div.mypage-box div.overview p.author { + margin-bottom: 7px; +} +#content .additional-information { + font-size: 11px; +} +div.issues.box > p, div.mypage-box p { + margin-top: 15px; +} + +div.news.box > p { + margin-top: -15px; +} +div.news { + margin-bottom: 30px; +} +div.overview { + padding:6px; + margin-bottom: 10px; + line-height:1.5em; +} +td.table-buttons { + vertical-align:middle; +} +select#available_columns { + margin-right: 0px; +} +.pages-hierarchy { + padding-left: 10px; + list-style-type: disc; + list-style-position: inside; +} +ul.action_menu_main { + float:right; + margin-top: 7px; +} +ul.action_menu_main > li { + float:left; +} +ul.action_menu_more > li { + padding-top: 5px; +} +ul.action_menu_more { + position: absolute; + top: 40px; + right: 25px; + z-index: 100; + + padding: 10px; + padding-top: 5px; + + background: white; + border: 1px solid #B7B7B7; + + box-shadow: 1px 1px 2px #aaa; +} +#lower-title-bar ul.action_menu_more { + bottom: 0; + right: 0; + margin-bottom: 25px; + top: auto; +} +#lower-title-bar ul.action_menu_main > li.drop-down { + position: relative; +} +#toggle-project-menu { + height:15px; + width:184px; + border-bottom: 1px solid #DDD; + border-right: 1px solid #DDD; + background-color:#E9E9E9; +} +#toggle-project-menu:hover { + background-color: #D8D8D8; +} +#toggle-project-menu.show { + width:15px; +} +#content.hidden-navigation { + margin-left: 15px; +} +#main-menu #toggle-project-menu a.navigation-toggler { + position:relative; + float:right; + width:100%; + height:15px; + + /* Arrow left */ + background-image:url(../images/double_arrows_grey_white_sprite.png); + background-position:148px -91px; + background-repeat:no-repeat; +} +#main-menu #toggle-project-menu.show a.navigation-toggler { + width:15px; + height:100%; + + /* Arrow right */ + background-image:url(../images/double_arrows_grey_white_sprite.png); + background-position:-8px -200px; + background-repeat:no-repeat; +} +#main-menu #toggle-project-menu a.navigation-toggler:hover { + /* Arrow left white */ + background-position:148px -58px; + background-repeat:no-repeat; +} +#main-menu #toggle-project-menu.show a.navigation-toggler:hover { + /* Arrow right white */ + background-position:-39px -200px; + background-repeat:no-repeat; +} +.navigate-left { + background: url(../images/arrow_left_darkred.png) 0 0px no-repeat; + width:100%; + height:15px; + padding-left: 18px; +} +.navigate-right { + background: url(../images/arrow_right_darkred.png) right 0px no-repeat; + width:100%; + height:15px; + padding-right: 18px; +} +#menu-sidebar.hidden { + display:none; +} +div#history div.journal div.wiki { + overflow:visible; +} + +ul.breadcrumb { + list-style-image: url(../images/breadcrumb-list.png); + list-style-position: inside; + width:10000px; +} +#top-menu ul.breadcrumb li.first-breadcrumb-element { + padding-left:0px; +} +#top-menu ul.breadcrumb li { + float:left; + padding-left: 6px; +} +#breadcrumb a { + font-weight: normal; + text-decoration: none; +} + +#breadcrumb a:hover { + text-decoration: underline; +} + +#breadcrumb li.cutme { + max-width: 40px; +} + +div#watchers{ + margin-top:25px; +} + +div#watchers > form > p { + margin-top:5px; +} + +a > img.imgtag-icon { + float: left; + margin-right: 3px; +} + +#breadcrumb a.breadcrumb-project-title { + font-weight: bold; + font-size: 13px; +} + +th.checkbox img { + margin-left: 3px; + margin-top: 3px; +} + +p.buttons { + margin-left: 10px; +} +div.contextual > a.icon, p.buttons > a, ul.action_menu_main > li { + padding-right:10px; +} +strong.related-issues-heading { + display:block; + margin-top: 10px; +} diff --git a/public/stylesheets/chosen.css b/public/stylesheets/chosen.css index 17866b440c..d203ebf594 100644 --- a/public/stylesheets/chosen.css +++ b/public/stylesheets/chosen.css @@ -114,7 +114,7 @@ border: 1px solid #aaa; font-family: sans-serif; font-size: 1em; - min-width: 150px; + min-width: 236px; } .chzn-container-single .chzn-drop { -moz-background-clip : padding; @@ -215,7 +215,7 @@ /* @group Results */ .chzn-container .chzn-results { margin: 0 4px 4px 0; - max-height: 190px; + max-height: 500px; overflow-x: hidden; overflow-y: auto; color: #222; diff --git a/public/stylesheets/context_menu.css b/public/stylesheets/context_menu.css index 9307404b7e..aa5df74dcd 100644 --- a/public/stylesheets/context_menu.css +++ b/public/stylesheets/context_menu.css @@ -15,6 +15,7 @@ border-right:1px solid #777; background:white; list-style:none; + position:relative; } #context-menu li { @@ -42,10 +43,6 @@ #context-menu li a.submenu { background:url("../images/bullet_arrow_right.png") right no-repeat; } #context-menu li:hover { border:1px solid gray; background-color:#eee; } #context-menu a:hover {color:#2A5685;} -#context-menu li.folder:hover { z-index:40; } +#context-menu li.folder:hover { z-index:40; } #context-menu ul ul, #context-menu li:hover ul ul { display:none; } #context-menu li:hover ul, #context-menu li:hover li:hover ul { display:block; } - -/* selected element */ -.context-menu-selection { background-color:#507AAA !important; color:#000 !important; } -.context-menu-selection:hover { background-color:#507AAA !important; color:#000 !important; } diff --git a/test/fixtures/issues.yml b/test/fixtures/issues.yml index 4fe0e92b28..d8683c75a8 100644 --- a/test/fixtures/issues.yml +++ b/test/fixtures/issues.yml @@ -18,6 +18,7 @@ issues_001: root_id: 1 lft: 1 rgt: 2 + lock_version: 3 issues_002: created_on: 2006-07-19 21:04:21 +02:00 project_id: 1 diff --git a/test/fixtures/roles.yml b/test/fixtures/roles.yml index cd2538cca9..afd33d0bc8 100644 --- a/test/fixtures/roles.yml +++ b/test/fixtures/roles.yml @@ -52,6 +52,7 @@ roles_001: - :manage_repository - :view_changesets - :manage_project_activities + - :export_issues position: 1 roles_002: diff --git a/test/functional/account_controller_test.rb b/test/functional/account_controller_test.rb index e664fa861b..3380f2937f 100644 --- a/test/functional/account_controller_test.rb +++ b/test/functional/account_controller_test.rb @@ -48,6 +48,17 @@ class AccountControllerTest < ActionController::TestCase :content => /Invalid user or password/ end + def test_login + get :login + assert_template 'login' + end + + def test_login_with_logged_account + @request.session[:user_id] = 2 + get :login + assert_redirected_to home_url + end + if Object.const_defined?(:OpenID) def test_login_with_openid_for_existing_user diff --git a/test/functional/issues_controller_transaction_test.rb b/test/functional/issues_controller_transaction_test.rb index 8e0acb9952..ea876769b6 100644 --- a/test/functional/issues_controller_transaction_test.rb +++ b/test/functional/issues_controller_transaction_test.rb @@ -53,7 +53,7 @@ class IssuesControllerTransactionTest < ActionController::TestCase def test_put_update_stale_issue issue = Issue.find(2) @request.session[:user_id] = 2 - + assert_no_difference 'Journal.count' do assert_no_difference 'TimeEntry.count' do assert_no_difference 'Attachment.count' do @@ -73,6 +73,33 @@ class IssuesControllerTransactionTest < ActionController::TestCase assert_response :success assert_template 'edit' assert_tag :tag => 'div', :attributes => { :id => 'errorExplanation' }, - :content => /Data has been updated by another user/ + :content => /Information has been updated by at least one other user in the meantime./ end + + def test_put_update_stale_issue_prints_users_that_were_changing_it + issue = Issue.find(1) + @request.session[:user_id] = 3 + + put :update, + :id => issue.id, + :issue => { + :fixed_version_id => 4, + :lock_version => 0 + }, + :notes => '', + :attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain')}}, + :time_entry => { :hours => '2.5', :comments => '', :activity_id => TimeEntryActivity.first.id } + + assert_response :success + assert_template 'edit' + + assert_tag :tag => 'div', :attributes => { :id => 'errorExplanation' }, + :content => /redMine Admin \(19 Mar 00:00\), John Smith \(21 Mar 00:00\)/ + assert_tag :tag => 'div', :attributes => { :id => 'errorExplanation' }, + :content => /Please reload the page/ + end + end + + + diff --git a/test/unit/project_test.rb b/test/unit/project_test.rb index 575621ed39..7d7ec54a6c 100644 --- a/test/unit/project_test.rb +++ b/test/unit/project_test.rb @@ -725,7 +725,12 @@ class ProjectTest < ActiveSupport::TestCase assert_nil project.versions.detect {|v| v.completed? && v.status != 'closed'} assert_not_nil project.versions.detect {|v| !v.completed? && v.status == 'open'} end - + + def test_export_issues_is_allowed + project = Project.find(1) + assert project.allows_to?(:export_issues) + end + context "Project#copy" do setup do ProjectCustomField.destroy_all # Custom values are a mess to isolate in tests diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index b677eee30f..d1a295e933 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -432,17 +432,26 @@ class UserTest < ActiveSupport::TestCase should "authorize nearly everything for admin users" do project = Project.find(1) + project.enabled_module_names = ["issue_tracking", "news", "wiki", "repository"] assert ! @admin.member_of?(project) - %w(edit_issues delete_issues manage_news manage_documents manage_wiki).each do |p| + %w(edit_issues delete_issues manage_news manage_repository manage_wiki).each do |p| assert @admin.allowed_to?(p.to_sym, project) end end should "authorize normal users depending on their roles" do project = Project.find(1) + project.enabled_module_names = ["boards"] assert @jsmith.allowed_to?(:delete_messages, project) #Manager assert ! @dlopper.allowed_to?(:delete_messages, project) #Developper end + + should "only managers are allowed to export tickets" do + project = Project.find(1) + project.enabled_module_names = ["issue_tracking"] + assert @jsmith.allowed_to?(:export_issues, project) #Manager + assert ! @dlopper.allowed_to?(:export_issues, project) #Developper + end end context "with multiple projects" do @@ -451,6 +460,11 @@ class UserTest < ActiveSupport::TestCase end should "return true only if user has permission on all these projects" do + Project.all.each do |project| + project.enabled_module_names = ["issue_tracking"] + project.save! + end + assert @admin.allowed_to?(:view_project, Project.all) assert ! @dlopper.allowed_to?(:view_project, Project.all) #cannot see Project(2) assert @jsmith.allowed_to?(:edit_issues, @jsmith.projects) #Manager or Developer everywhere diff --git a/vendor/plugins/acts_as_journalized/lib/journal_formatter.rb b/vendor/plugins/acts_as_journalized/lib/journal_formatter.rb index 44c6bf368b..c6130e10db 100644 --- a/vendor/plugins/acts_as_journalized/lib/journal_formatter.rb +++ b/vendor/plugins/acts_as_journalized/lib/journal_formatter.rb @@ -46,7 +46,7 @@ module JournalFormatter registered_fields[klazz] ||= {} registered_fields[klazz].merge!(hash) else - formatters.merge(hash) + formatters.merge!(hash) end end @@ -140,7 +140,7 @@ module JournalFormatter detail end end - + def values(detail) key = prop_key(detail) if detail != key diff --git a/vendor/plugins/acts_as_journalized/lib/redmine/acts/journalized/creation.rb b/vendor/plugins/acts_as_journalized/lib/redmine/acts/journalized/creation.rb index a4e046b0d4..154092fbb5 100644 --- a/vendor/plugins/acts_as_journalized/lib/redmine/acts/journalized/creation.rb +++ b/vendor/plugins/acts_as_journalized/lib/redmine/acts/journalized/creation.rb @@ -75,24 +75,46 @@ module Redmine::Acts::Journalized def recreate_initial_journal! new_journal = journals.find_by_version(1) new_journal ||= journals.build - # Mock up a list of changes for the creation journal based on Class defaults - new_attributes = self.class.new.attributes.except(self.class.primary_key, - self.class.inheritance_column, - :updated_on, - :updated_at, - :lock_version, - :lft, - :rgt) - creation_changes = {} - new_attributes.each do |name, default_value| - # Set changes based on the initial value to current. Can't get creation value without - # rebuiling the object history - creation_changes[name] = [default_value, self.send(name)] # [initial_value, creation_value] + + initial_changes = {} + + self.attributes.keys.reject{|attribute| self.class.vestal_journals_options[:except].include?(attribute)}.each do |name| + + # Set the current attributes as initial attributes + # This works as a fallback if no prior change is found + initial_changes[name] = self.send(name) + + # Try to find the real initial values + unless self.journals.empty? + self.journals[1..-1].each do |journal| + unless journal.changes[name].nil? + # Found the first change in journals + # Copy the first value as initial change value + initial_changes[name] = journal.changes[name].first + break + end + end + end end - new_journal.changes = creation_changes + + fill_object = self.class.new + + # The parent id is set via awesome_nested set + # we need to use the correct accessor which is 'parent_issue_id' for issues + initial_changes["parent_issue_id"] = initial_changes.delete("parent_id") if self.class == Issue and initial_changes.has_key?("parent_id") + + # Force the gathered attributes onto the fill object + attributes_setter = ActiveRecord::Base.instance_method(:attributes=) + attributes_setter = attributes_setter.bind(fill_object) + + attributes_setter.call(initial_changes, false) + + # Call the journal creating method + new_journal.changes = fill_object.send(:merge_journal_changes) + new_journal.version = 1 - new_journal.activity_type = self.class.send(:journalized_activity_hash, {})[:type] - + new_journal.activity_type = activity_type + if respond_to?(:author) new_journal.user = author elsif respond_to?(:user) @@ -101,7 +123,7 @@ module Redmine::Acts::Journalized new_journal.save! new_journal.reload - + # Backdate journal if respond_to?(:created_at) new_journal.update_attribute(:created_at, created_at) @@ -110,7 +132,7 @@ module Redmine::Acts::Journalized end new_journal end - + private # Returns whether a new journal should be created upon updating the parent record. # A new journal will be created if @@ -161,7 +183,7 @@ module Redmine::Acts::Journalized # Specifies the attributes used during journal creation. This is separated into its own # method so that it can be overridden by the VestalVersions::Users feature. def journal_attributes - attributes = { :journaled_id => self.id, :activity_type => activity_type, + attributes = { :journaled_id => self.id, :activity_type => activity_type, :changes => journal_changes, :version => last_version + 1, :notes => journal_notes, :user_id => (journal_user.try(:id) || User.current.try(:id)) }.merge(extra_journal_attributes || {}) diff --git a/vendor/plugins/acts_as_watchable/lib/acts_as_watchable.rb b/vendor/plugins/acts_as_watchable/lib/acts_as_watchable.rb index 2b15838347..d55ceae015 100644 --- a/vendor/plugins/acts_as_watchable/lib/acts_as_watchable.rb +++ b/vendor/plugins/acts_as_watchable/lib/acts_as_watchable.rb @@ -3,24 +3,24 @@ module Redmine module Acts module Watchable - def self.included(base) + def self.included(base) base.extend ClassMethods - end + end module ClassMethods def acts_as_watchable(options = {}) - return if self.included_modules.include?(Redmine::Acts::Watchable::InstanceMethods) + return if self.included_modules.include?(Redmine::Acts::Watchable::InstanceMethods) send :include, Redmine::Acts::Watchable::InstanceMethods - + class_eval do has_many :watchers, :as => :watchable, :dependent => :delete_all has_many :watcher_users, :through => :watchers, :source => :user, :validate => false - + named_scope :watched_by, lambda { |user_id| { :include => :watchers, :conditions => ["#{Watcher.table_name}.user_id = ?", user_id] } } - attr_protected :watcher_ids, :watcher_user_ids + attr_protected :watcher_ids, :watcher_user_ids if accessible_attributes.nil? end end end @@ -29,38 +29,38 @@ module Redmine def self.included(base) base.extend ClassMethods end - + # Returns an array of users that are proposed as watchers def addable_watcher_users self.project.users.sort - self.watcher_users end - + # Adds user as a watcher def add_watcher(user) self.watchers << Watcher.new(:user => user) end - + # Removes user from the watchers list def remove_watcher(user) return nil unless user && user.is_a?(User) Watcher.delete_all "watchable_type = '#{self.class}' AND watchable_id = #{self.id} AND user_id = #{user.id}" end - + # Adds/removes watcher def set_watcher(user, watching=true) watching ? add_watcher(user) : remove_watcher(user) end - + # Returns true if object is watched by +user+ def watched_by?(user) !!(user && self.watcher_user_ids.detect {|uid| uid == user.id }) end - + # Returns an array of watchers' email addresses def watcher_recipients notified = watcher_users.active notified.reject! {|user| user.mail_notification == 'none'} - + if respond_to?(:visible?) notified.reject! {|user| !visible?(user)} end