Commit 310a0f92 authored by Jean-Philippe Lang's avatar Jean-Philippe Lang

0.3 unstable

git-svn-id: http://redmine.rubyforge.org/svn/trunk@12 e93f8b46-1217-0410-a6f0-8f06a7374b81
parent 7e57db1e
...@@ -17,11 +17,14 @@ ...@@ -17,11 +17,14 @@
class AccountController < ApplicationController class AccountController < ApplicationController
layout 'base' layout 'base'
helper :custom_fields
include CustomFieldsHelper
# prevents login action to be filtered by check_if_login_required application scope filter # prevents login action to be filtered by check_if_login_required application scope filter
skip_before_filter :check_if_login_required, :only => :login skip_before_filter :check_if_login_required, :only => [:login, :lost_password, :register]
before_filter :require_login, :except => [:show, :login] before_filter :require_login, :except => [:show, :login, :lost_password, :register]
# Show user's account
def show def show
@user = User.find(params[:id]) @user = User.find(params[:id])
end end
...@@ -29,49 +32,123 @@ class AccountController < ApplicationController ...@@ -29,49 +32,123 @@ class AccountController < ApplicationController
# Login request and validation # Login request and validation
def login def login
if request.get? if request.get?
session[:user] = nil # Logout user
self.logged_in_user = nil
else else
logged_in_user = User.try_to_login(params[:login], params[:password]) # Authenticate user
if logged_in_user user = User.try_to_login(params[:login], params[:password])
session[:user] = logged_in_user if user
self.logged_in_user = user
redirect_back_or_default :controller => 'account', :action => 'my_page' redirect_back_or_default :controller => 'account', :action => 'my_page'
else else
flash[:notice] = _('Invalid user/password') flash[:notice] = l(:notice_account_invalid_creditentials)
end end
end end
end end
# Log out current user and redirect to welcome page
def logout
session[:user] = nil
redirect_to(:controller => '')
end
def my_page # Log out current user and redirect to welcome page
@user = session[:user] def logout
@reported_issues = Issue.find(:all, :conditions => ["author_id=?", @user.id], :limit => 10, :include => [ :status, :project, :tracker ], :order => 'issues.updated_on DESC') self.logged_in_user = nil
@assigned_issues = Issue.find(:all, :conditions => ["assigned_to_id=?", @user.id], :limit => 10, :include => [ :status, :project, :tracker ], :order => 'issues.updated_on DESC') redirect_to :controller => ''
end end
# Edit current user's account # Show logged in user's page
def my_account def my_page
@user = User.find(session[:user].id) @user = self.logged_in_user
if request.post? and @user.update_attributes(@params[:user]) @reported_issues = Issue.find(:all, :conditions => ["author_id=?", @user.id], :limit => 10, :include => [ :status, :project, :tracker ], :order => 'issues.updated_on DESC')
flash[:notice] = 'Account was successfully updated.' @assigned_issues = Issue.find(:all, :conditions => ["assigned_to_id=?", @user.id], :limit => 10, :include => [ :status, :project, :tracker ], :order => 'issues.updated_on DESC')
session[:user] = @user end
# Edit logged in user's account
def my_account
@user = self.logged_in_user
if request.post? and @user.update_attributes(@params[:user])
set_localization set_localization
end flash[:notice] = l(:notice_account_updated)
end self.logged_in_user.reload
end
end
# Change current user's password # Change logged in user's password
def change_password def change_password
@user = User.find(session[:user].id) @user = self.logged_in_user
if @user.check_password?(@params[:password]) if @user.check_password?(@params[:password])
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation] @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
flash[:notice] = 'Password was successfully updated.' if @user.save flash[:notice] = l(:notice_account_password_updated) if @user.save
else else
flash[:notice] = 'Wrong password' flash[:notice] = l(:notice_account_wrong_password)
end end
render :action => 'my_account' render :action => 'my_account'
end end
# Enable user to choose a new password
def lost_password
if params[:token]
@token = Token.find_by_action_and_value("recovery", params[:token])
redirect_to :controller => '' and return unless @token and !@token.expired?
@user = @token.user
if request.post?
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
if @user.save
@token.destroy
flash[:notice] = l(:notice_account_password_updated)
redirect_to :action => 'login'
return
end
end
render :template => "account/password_recovery"
return
else
if request.post?
user = User.find_by_mail(params[:mail])
flash[:notice] = l(:notice_account_unknown_email) and return unless user
token = Token.new(:user => user, :action => "recovery")
if token.save
Mailer.set_language_if_valid(Localization.lang)
Mailer.deliver_lost_password(token)
flash[:notice] = l(:notice_account_lost_email_sent)
redirect_to :action => 'login'
return
end
end
end
end
# User self-registration
def register
redirect_to :controller => '' and return if $RDM_SELF_REGISTRATION == false
if params[:token]
token = Token.find_by_action_and_value("register", params[:token])
redirect_to :controller => '' and return unless token and !token.expired?
user = token.user
redirect_to :controller => '' and return unless user.status == User::STATUS_REGISTERED
user.status = User::STATUS_ACTIVE
if user.save
token.destroy
flash[:notice] = l(:notice_account_activated)
redirect_to :action => 'login'
return
end
else
if request.get?
@user = User.new(:language => $RDM_DEFAULT_LANG)
@custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user) }
else
@user = User.new(params[:user])
@user.admin = false
@user.login = params[:user][:login]
@user.status = User::STATUS_REGISTERED
@user.password, @user.password_confirmation = params[:password], params[:password_confirmation]
@custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }
@user.custom_values = @custom_values
token = Token.new(:user => @user, :action => "register")
if @user.save and token.save
Mailer.set_language_if_valid(Localization.lang)
Mailer.deliver_register(token)
flash[:notice] = l(:notice_account_register_done)
redirect_to :controller => ''
end
end
end
end
end end
...@@ -18,43 +18,59 @@ ...@@ -18,43 +18,59 @@
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
before_filter :check_if_login_required, :set_localization before_filter :check_if_login_required, :set_localization
def logged_in_user=(user)
@logged_in_user = user
session[:user_id] = (user ? user.id : nil)
end
def logged_in_user
if session[:user_id]
@logged_in_user ||= User.find(session[:user_id], :include => :memberships)
else
nil
end
end
# check if login is globally required to access the application # check if login is globally required to access the application
def check_if_login_required def check_if_login_required
require_login if RDM_LOGIN_REQUIRED require_login if $RDM_LOGIN_REQUIRED
end end
def set_localization def set_localization
Localization.lang = begin Localization.lang = begin
if session[:user] if self.logged_in_user and Localization.langs.keys.include? self.logged_in_user.language
session[:user].language self.logged_in_user.language
elsif request.env['HTTP_ACCEPT_LANGUAGE'] elsif request.env['HTTP_ACCEPT_LANGUAGE']
accept_lang = HTTPUtils.parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.split('-').first accept_lang = HTTPUtils.parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.split('-').first
if Localization.langs.collect{ |l| l[1] }.include? accept_lang if Localization.langs.keys.include? accept_lang
accept_lang accept_lang
end end
end end
rescue rescue
nil nil
end || RDM_DEFAULT_LANG end || $RDM_DEFAULT_LANG
set_language_if_valid(Localization.lang)
end end
def require_login def require_login
unless session[:user] unless self.logged_in_user
store_location store_location
redirect_to(:controller => "account", :action => "login") redirect_to(:controller => "account", :action => "login")
return false
end end
true
end end
def require_admin def require_admin
if session[:user].nil? return unless require_login
store_location unless self.logged_in_user.admin?
redirect_to(:controller => "account", :action => "login") flash[:notice] = "Acces denied"
else redirect_to:controller => ''
unless session[:user].admin? return false
flash[:notice] = "Acces not allowed"
redirect_to(:controller => "projects", :action => "list")
end
end end
true
end end
# authorizes the user for the requested action. # authorizes the user for the requested action.
...@@ -62,19 +78,18 @@ class ApplicationController < ActionController::Base ...@@ -62,19 +78,18 @@ class ApplicationController < ActionController::Base
# check if action is allowed on public projects # check if action is allowed on public projects
if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ @params[:controller], @params[:action] ] if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ @params[:controller], @params[:action] ]
return true return true
end end
# if user not logged in, redirect to login form # if action is not public, force login
unless session[:user] return unless require_login
store_location # admin is always authorized
redirect_to(:controller => "account", :action => "login") return true if self.logged_in_user.admin?
return false # if not admin, check membership permission
end @user_membership ||= Member.find(:first, :conditions => ["user_id=? and project_id=?", self.logged_in_user.id, @project.id])
# if logged in, check if authorized if @user_membership and Permission.allowed_to_role( "%s/%s" % [ @params[:controller], @params[:action] ], @user_membership.role_id )
if session[:user].admin? or Permission.allowed_to_role( "%s/%s" % [ @params[:controller], @params[:action] ], session[:user].role_for_project(@project.id) )
return true return true
end end
flash[:notice] = "Acces denied" flash[:notice] = "Acces denied"
redirect_to(:controller => "") redirect_to :controller => ''
false false
end end
......
# redMine - project management software
# Copyright (C) 2006 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class AuthSourcesController < ApplicationController
layout 'base'
before_filter :require_admin
def index
list
render :action => 'list'
end
# GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
verify :method => :post, :only => [ :destroy, :create, :update ],
:redirect_to => { :action => :list }
def list
@auth_source_pages, @auth_sources = paginate :auth_sources, :per_page => 10
end
def new
@auth_source = AuthSourceLdap.new
end
def create
@auth_source = AuthSourceLdap.new(params[:auth_source])
if @auth_source.save
flash[:notice] = l(:notice_successful_create)
redirect_to :action => 'list'
else
render :action => 'new'
end
end
def edit
@auth_source = AuthSource.find(params[:id])
end
def update
@auth_source = AuthSource.find(params[:id])
if @auth_source.update_attributes(params[:auth_source])
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'list'
else
render :action => 'edit'
end
end
def test_connection
@auth_method = AuthSource.find(params[:id])
begin
@auth_method.test_connection
rescue => text
flash[:notice] = text
end
flash[:notice] ||= l(:notice_successful_connection)
redirect_to :action => 'list'
end
def destroy
@auth_source = AuthSource.find(params[:id])
unless @auth_source.users.find(:first)
@auth_source.destroy
flash[:notice] = l(:notice_successful_delete)
end
redirect_to :action => 'list'
end
end
...@@ -16,37 +16,48 @@ ...@@ -16,37 +16,48 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class CustomFieldsController < ApplicationController class CustomFieldsController < ApplicationController
layout 'base' layout 'base'
before_filter :require_admin before_filter :require_admin
def index def index
list list
render :action => 'list' render :action => 'list'
end end
def list def list
@custom_field_pages, @custom_fields = paginate :custom_fields, :per_page => 10 @custom_field_pages, @custom_fields = paginate :custom_fields, :per_page => 15
end end
def new def new
if request.get? case params[:type]
@custom_field = CustomField.new when "IssueCustomField"
else @custom_field = IssueCustomField.new(params[:custom_field])
@custom_field = CustomField.new(params[:custom_field]) @custom_field.trackers = Tracker.find(params[:tracker_ids]) if params[:tracker_ids]
if @custom_field.save when "UserCustomField"
flash[:notice] = 'CustomField was successfully created.' @custom_field = UserCustomField.new(params[:custom_field])
redirect_to :action => 'list' when "ProjectCustomField"
@custom_field = ProjectCustomField.new(params[:custom_field])
else
redirect_to :action => 'list'
return
end
if request.post? and @custom_field.save
redirect_to :action => 'list'
end
@trackers = Tracker.find(:all)
end
def edit
@custom_field = CustomField.find(params[:id])
if request.post? and @custom_field.update_attributes(params[:custom_field])
if @custom_field.is_a? IssueCustomField
@custom_field.trackers = params[:tracker_ids] ? Tracker.find(params[:tracker_ids]) : []
end end
end flash[:notice] = 'Custom field was successfully updated.'
end redirect_to :action => 'list'
end
def edit @trackers = Tracker.find(:all)
@custom_field = CustomField.find(params[:id]) end
if request.post? and @custom_field.update_attributes(params[:custom_field])
flash[:notice] = 'CustomField was successfully updated.'
redirect_to :action => 'list'
end
end
def destroy def destroy
CustomField.find(params[:id]).destroy CustomField.find(params[:id]).destroy
...@@ -54,5 +65,5 @@ class CustomFieldsController < ApplicationController ...@@ -54,5 +65,5 @@ class CustomFieldsController < ApplicationController
rescue rescue
flash[:notice] = "Unable to delete custom field" flash[:notice] = "Unable to delete custom field"
redirect_to :action => 'list' redirect_to :action => 'list'
end end
end end
...@@ -45,7 +45,7 @@ class DocumentsController < ApplicationController ...@@ -45,7 +45,7 @@ class DocumentsController < ApplicationController
# Save the attachment # Save the attachment
if params[:attachment][:file].size > 0 if params[:attachment][:file].size > 0
@attachment = @document.attachments.build(params[:attachment]) @attachment = @document.attachments.build(params[:attachment])
@attachment.author_id = session[:user].id unless session[:user].nil? @attachment.author_id = self.logged_in_user.id if self.logged_in_user
@attachment.save @attachment.save
end end
render :action => 'show' render :action => 'show'
......
...@@ -23,21 +23,21 @@ class IssuesController < ApplicationController ...@@ -23,21 +23,21 @@ class IssuesController < ApplicationController
include CustomFieldsHelper include CustomFieldsHelper
def show def show
@status_options = @issue.status.workflows.find(:all, :conditions => ["role_id=? and tracker_id=?", session[:user].role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if session[:user] @status_options = @issue.status.workflows.find(:all, :conditions => ["role_id=? and tracker_id=?", self.logged_in_user.role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if self.logged_in_user
@custom_values = @issue.custom_values.find(:all, :include => :custom_field)
end end
def edit def edit
@trackers = Tracker.find(:all)
@priorities = Enumeration::get_values('IPRI') @priorities = Enumeration::get_values('IPRI')
if request.get? if request.get?
@custom_values = @project.custom_fields_for_issues.collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) } @custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x, :customized => @issue) }
else else
# Retrieve custom fields and values # Retrieve custom fields and values
@custom_values = @project.custom_fields_for_issues.collect { |x| CustomValue.new(:custom_field => x, :value => params["custom_fields"][x.id.to_s]) } @custom_values = @project.custom_fields_for_issues(@issue.tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue, :value => params["custom_fields"][x.id.to_s]) }
@issue.custom_values = @custom_values @issue.custom_values = @custom_values
if @issue.update_attributes(params[:issue]) @issue.attributes = params[:issue]
if @issue.save
flash[:notice] = 'Issue was successfully updated.' flash[:notice] = 'Issue was successfully updated.'
redirect_to :action => 'show', :id => @issue redirect_to :action => 'show', :id => @issue
end end
...@@ -46,12 +46,11 @@ class IssuesController < ApplicationController ...@@ -46,12 +46,11 @@ class IssuesController < ApplicationController
def change_status def change_status
@history = @issue.histories.build(params[:history]) @history = @issue.histories.build(params[:history])
@status_options = @issue.status.workflows.find(:all, :conditions => ["role_id=? and tracker_id=?", session[:user].role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if session[:user] @status_options = @issue.status.workflows.find(:all, :conditions => ["role_id=? and tracker_id=?", self.logged_in_user.role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if self.logged_in_user
if params[:confirm] if params[:confirm]
unless session[:user].nil? @history.author_id = self.logged_in_user.id if self.logged_in_user
@history.author = session[:user]
end
if @history.save if @history.save
@issue.status = @history.status @issue.status = @history.status
@issue.fixed_version_id = (params[:issue][:fixed_version_id]) @issue.fixed_version_id = (params[:issue][:fixed_version_id])
...@@ -76,7 +75,7 @@ class IssuesController < ApplicationController ...@@ -76,7 +75,7 @@ class IssuesController < ApplicationController
# Save the attachment # Save the attachment
if params[:attachment][:file].size > 0 if params[:attachment][:file].size > 0
@attachment = @issue.attachments.build(params[:attachment]) @attachment = @issue.attachments.build(params[:attachment])
@attachment.author_id = session[:user].id unless session[:user].nil? @attachment.author_id = self.logged_in_user.id if self.logged_in_user
@attachment.save @attachment.save
end end
redirect_to :action => 'show', :id => @issue redirect_to :action => 'show', :id => @issue
...@@ -86,17 +85,16 @@ class IssuesController < ApplicationController ...@@ -86,17 +85,16 @@ class IssuesController < ApplicationController
@issue.attachments.find(params[:attachment_id]).destroy @issue.attachments.find(params[:attachment_id]).destroy
redirect_to :action => 'show', :id => @issue redirect_to :action => 'show', :id => @issue
end end
# Send the file in stream mode # Send the file in stream mode
def download def download
@attachment = @issue.attachments.find(params[:attachment_id]) @attachment = @issue.attachments.find(params[:attachment_id])
send_file @attachment.diskfile, :filename => @attachment.filename send_file @attachment.diskfile, :filename => @attachment.filename
end end
private private
def find_project def find_project
@issue = Issue.find(params[:id]) @issue = Issue.find(params[:id])
@project = @issue.project @project = @issue.project
end end
end end
...@@ -21,6 +21,8 @@ class UsersController < ApplicationController ...@@ -21,6 +21,8 @@ class UsersController < ApplicationController
helper :sort helper :sort
include SortHelper include SortHelper
helper :custom_fields
include CustomFieldsHelper
def index def index
list list
...@@ -41,12 +43,15 @@ class UsersController < ApplicationController ...@@ -41,12 +43,15 @@ class UsersController < ApplicationController
def add def add
if request.get? if request.get?
@user = User.new @user = User.new(:language => $RDM_DEFAULT_LANG)
@custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user) }
else else
@user = User.new(params[:user]) @user = User.new(params[:user])
@user.admin = params[:user][:admin] || false @user.admin = params[:user][:admin] || false
@user.login = params[:user][:login] @user.login = params[:user][:login]
@user.password, @user.password_confirmation = params[:password], params[:password_confirmation] @user.password, @user.password_confirmation = params[:password], params[:password_confirmation]
@custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }
@user.custom_values = @custom_values
if @user.save if @user.save
flash[:notice] = 'User was successfully created.' flash[:notice] = 'User was successfully created.'
redirect_to :action => 'list' redirect_to :action => 'list'
...@@ -56,10 +61,16 @@ class UsersController < ApplicationController ...@@ -56,10 +61,16 @@ class UsersController < ApplicationController
def edit def edit
@user = User.find(params[:id]) @user = User.find(params[:id])
if request.post? if request.get?
@custom_values = UserCustomField.find(:all).collect { |x| @user.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
else
@user.admin = params[:user][:admin] if params[:user][:admin] @user.admin = params[:user][:admin] if params[:user][:admin]
@user.login = params[:user][:login] if params[:user][:login] @user.login = params[:user][:login] if params[:user][:login]
@user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless params[:password].nil? or params[:password].empty? @user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless params[:password].nil? or params[:password].empty?
if params[:custom_fields]
@custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }
@user.custom_values = @custom_values
end
if @user.update_attributes(params[:user]) if @user.update_attributes(params[:user])
flash[:notice] = 'User was successfully updated.' flash[:notice] = 'User was successfully updated.'
redirect_to :action => 'list' redirect_to :action => 'list'
......
...@@ -16,11 +16,10 @@ ...@@ -16,11 +16,10 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class WelcomeController < ApplicationController class WelcomeController < ApplicationController
layout 'base' layout 'base'
def index def index
@news = News.latest @news = News.latest
@projects = Project.latest @projects = Project.latest
end end
end end
...@@ -17,35 +17,38 @@ ...@@ -17,35 +17,38 @@
module ApplicationHelper module ApplicationHelper
def loggedin? # return current logged in user or nil
session[:user] def loggedin?
end @logged_in_user
end
# return true if user is loggend in and is admin, otherwise false
def admin_loggedin?
@logged_in_user and @logged_in_user.admin?
end
def admin_loggedin? def authorize_for(controller, action)
session[:user] && session[:user].admin
end
def authorize_for(controller, action)
# check if action is allowed on public projects # check if action is allowed on public projects
if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ controller, action ] if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ controller, action ]
return true return true
end end
# check if user is authorized # check if user is authorized
if session[:user] and (session[:user].admin? or Permission.allowed_to_role( "%s/%s" % [ controller, action ], session[:user].role_for_project(@project.id) ) ) if @logged_in_user and (@logged_in_user.admin? or Permission.allowed_to_role( "%s/%s" % [ controller, action ], @logged_in_user.role_for_project(@project.id) ) )
return true return true
end end
return false return false
end end
def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference) # Display a link if user is authorized
link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller], options[:action]) def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
end link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller], options[:action])
end
# Display a link to user's account page
def link_to_user(user) # Display a link to user's account page
link_to user.display_name, :controller => 'account', :action => 'show', :id => user def link_to_user(user)
end link_to user.display_name, :controller => 'account', :action => 'show', :id => user
end
def format_date(date) def format_date(date)
_('(date)', date) if date _('(date)', date) if date
end end
...@@ -61,5 +64,30 @@ module ApplicationHelper ...@@ -61,5 +64,30 @@ module ApplicationHelper
html << ' ' + link_to((_('Next') + ' &#187;'), { :page => paginator.current.next }) if paginator.current.next html << ' ' + link_to((_('Next') + ' &#187;'), { :page => paginator.current.next }) if paginator.current.next
html html
end end
def error_messages_for(object_name, options = {})
options = options.symbolize_keys
object = instance_variable_get("@#{object_name}")
if object && !object.errors.empty?
# build full_messages here with controller current language
full_messages = []
object.errors.each do |attr, msg|
next if msg.nil?
if attr == "base"
full_messages << l(msg)
else
full_messages << "&#171; " + (l_has_string?("field_" + attr) ? l("field_" + attr) : object.class.human_attribute_name(attr)) + " &#187; " + l(msg)
end
end
content_tag("div",
content_tag(
options[:header_tag] || "h2", lwr(:gui_validation_error, object.errors.count) + " :"
) +
content_tag("ul", full_messages.collect { |msg| content_tag("li", msg) }),
"id" => options[:id] || "errorExplanation", "class" => options[:class] || "errorExplanation"
)
else
""
end
end
end end
# redMine - project management software
# Copyright (C) 2006 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module AuthSourcesHelper
end
...@@ -16,21 +16,49 @@ ...@@ -16,21 +16,49 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module CustomFieldsHelper module CustomFieldsHelper
def custom_field_tag(custom_value)
def custom_field_tag(custom_value)
custom_field = custom_value.custom_field custom_field = custom_value.custom_field
field_name = "custom_fields[#{custom_field.id}]"
field_name = "custom_fields[#{custom_field.id}]" case custom_field.field_format
when "string", "int", "date"
case custom_field.typ text_field_tag field_name, custom_value.value
when 0 .. 2 when "text"
text_field_tag field_name, custom_value.value text_area_tag field_name, custom_value.value, :cols => 60, :rows => 3
when 3 when "bool"
check_box field_name check_box_tag(field_name, "1", custom_value.value == "1") +
when 4 hidden_field_tag(field_name, "0")
select_tag field_name, when "list"
options_for_select(custom_field.possible_values.split('|'), select_tag field_name,
custom_value.value) "<option></option>" + options_for_select(custom_field.possible_values.split('|'),
end custom_value.value)
end end
end
def custom_field_label_tag(custom_value)
content_tag "label", custom_value.custom_field.name +
(custom_value.custom_field.is_required? ? " <span class=\"required\">*</span>" : "")
end
def custom_field_tag_with_label(custom_value)
case custom_value.custom_field.field_format
when "bool"
custom_field_tag(custom_value) + " " + custom_field_label_tag(custom_value)
else
custom_field_label_tag(custom_value) + "<br />" + custom_field_tag(custom_value)
end
end
def show_value(custom_value)
case custom_value.custom_field.field_format
when "bool"
l_YesNo(custom_value.value == "1")
else
custom_value.value
end
end
def custom_field_formats_for_select
CustomField::FIELD_FORMATS.keys.collect { |k| [ l(CustomField::FIELD_FORMATS[k]), k ] }
end
end end
...@@ -55,7 +55,7 @@ class Attachment < ActiveRecord::Base ...@@ -55,7 +55,7 @@ class Attachment < ActiveRecord::Base
# Returns file's location on disk # Returns file's location on disk
def diskfile def diskfile
"#{RDM_STORAGE_PATH}/#{self.disk_filename}" "#{$RDM_STORAGE_PATH}/#{self.disk_filename}"
end end
def increment_download def increment_download
......
# redMine - project management software
# Copyright (C) 2006 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class AuthSource < ActiveRecord::Base
has_many :users
validates_presence_of :name
validates_uniqueness_of :name
def authenticate(login, password)
end
def test_connection
end
def auth_method_name
"Abstract"
end
# Try to authenticate a user not yet registered against available sources
def self.authenticate(login, password)
AuthSource.find(:all, :conditions => ["onthefly_register=?", true]).each do |source|
begin
logger.debug "Authenticating '#{login}' against '#{source.name}'" if logger && logger.debug?
attrs = source.authenticate(login, password)
rescue
attrs = nil
end
return attrs if attrs
end
return nil
end
end
# redMine - project management software
# Copyright (C) 2006 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require 'net/ldap'
require 'iconv'
class AuthSourceLdap < AuthSource
validates_presence_of :host, :port, :attr_login
def after_initialize
self.port = 389 if self.port == 0
end
def authenticate(login, password)
attrs = []
# get user's DN
ldap_con = initialize_ldap_con(self.account, self.account_password)
login_filter = Net::LDAP::Filter.eq( self.attr_login, login )
object_filter = Net::LDAP::Filter.eq( "objectClass", "organizationalPerson" )
dn = String.new
ldap_con.search( :base => self.base_dn,
:filter => object_filter & login_filter,
:attributes=> ['dn', self.attr_firstname, self.attr_lastname, self.attr_mail]) do |entry|
dn = entry.dn
attrs = [:firstname => AuthSourceLdap.get_attr(entry, self.attr_firstname),
:lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname),
:mail => AuthSourceLdap.get_attr(entry, self.attr_mail),
:auth_source_id => self.id ]
end
return nil if dn.empty?
logger.debug "DN found for #{login}: #{dn}" if logger && logger.debug?
# authenticate user
ldap_con = initialize_ldap_con(dn, password)
return nil unless ldap_con.bind
# return user's attributes
logger.debug "Authentication successful for '#{login}'" if logger && logger.debug?
attrs
rescue Net::LDAP::LdapError => text
raise "LdapError: " + text
end
# test the connection to the LDAP
def test_connection
ldap_con = initialize_ldap_con(self.account, self.account_password)
ldap_con.open { }
rescue Net::LDAP::LdapError => text
raise "LdapError: " + text
end
def auth_method_name
"LDAP"
end
private
def initialize_ldap_con(ldap_user, ldap_password)
Net::LDAP.new( {:host => self.host,
:port => self.port,
:auth => { :method => :simple, :username => Iconv.new('iso-8859-15', 'utf-8').iconv(ldap_user), :password => Iconv.new('iso-8859-15', 'utf-8').iconv(ldap_password) }}
)
end
def self.get_attr(entry, attr_name)
entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name]
end
end
...@@ -16,23 +16,27 @@ ...@@ -16,23 +16,27 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class CustomField < ActiveRecord::Base class CustomField < ActiveRecord::Base
has_many :custom_values, :dependent => true
has_and_belongs_to_many :projects FIELD_FORMATS = { "list" => :label_list,
has_many :custom_values, :dependent => true "date" => :label_date,
has_many :issues, :through => :issue_custom_values "bool" => :label_boolean,
"int" => :label_integer,
"string" => :label_string,
"text" => :label_text
}.freeze
validates_presence_of :name, :typ validates_presence_of :name, :field_format
validates_uniqueness_of :name validates_uniqueness_of :name
validates_inclusion_of :field_format, :in => FIELD_FORMATS.keys
validates_presence_of :possible_values, :if => Proc.new { |field| field.field_format == "list" }
TYPES = [ # to move in project_custom_field
[ "Integer", 0 ], def self.for_all
[ "String", 1 ], find(:all, :conditions => ["is_for_all=?", true])
[ "Date", 2 ], end
[ "Boolean", 3 ],
[ "List", 4 ] def type_name
].freeze nil
end
def self.for_all end
find(:all, :conditions => ["is_for_all=?", true])
end
end
...@@ -16,26 +16,28 @@ ...@@ -16,26 +16,28 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class CustomValue < ActiveRecord::Base class CustomValue < ActiveRecord::Base
belongs_to :issue belongs_to :custom_field
belongs_to :custom_field belongs_to :customized, :polymorphic => true
protected protected
def validate def validate
errors.add(custom_field.name, "can't be blank") if custom_field.is_required? and value.empty? # errors are added to customized object unless it's nil
errors.add(custom_field.name, "is not valid") unless custom_field.regexp.empty? or value =~ Regexp.new(custom_field.regexp) object = customized || self
case custom_field.typ object.errors.add(custom_field.name, :activerecord_error_blank) if custom_field.is_required? and value.empty?
when 0 object.errors.add(custom_field.name, :activerecord_error_invalid) unless custom_field.regexp.empty? or value =~ Regexp.new(custom_field.regexp)
errors.add(custom_field.name, "must be an integer") unless value =~ /^[0-9]*$/
when 1 object.errors.add(custom_field.name, :activerecord_error_too_short) if custom_field.min_length > 0 and value.length < custom_field.min_length and value.length > 0
errors.add(custom_field.name, "is too short") if custom_field.min_length > 0 and value.length < custom_field.min_length and value.length > 0 object.errors.add(custom_field.name, :activerecord_error_too_long) if custom_field.max_length > 0 and value.length > custom_field.max_length
errors.add(custom_field.name, "is too long") if custom_field.max_length > 0 and value.length > custom_field.max_length
when 2 case custom_field.field_format
errors.add(custom_field.name, "must be a valid date") unless value =~ /^(\d+)\/(\d+)\/(\d+)$/ or value.empty? when "int"
when 3 object.errors.add(custom_field.name, :activerecord_error_not_a_number) unless value =~ /^[0-9]*$/
when "date"
when 4 object.errors.add(custom_field.name, :activerecord_error_invalid) unless value =~ /^(\d+)\/(\d+)\/(\d+)$/ or value.empty?
errors.add(custom_field.name, "is not a valid value") unless custom_field.possible_values.split('|').include? value or value.empty? when "list"
end object.errors.add(custom_field.name, :activerecord_error_inclusion) unless custom_field.possible_values.split('|').include? value or value.empty?
end
end end
end end
...@@ -20,5 +20,5 @@ class Document < ActiveRecord::Base ...@@ -20,5 +20,5 @@ class Document < ActiveRecord::Base
belongs_to :category, :class_name => "Enumeration", :foreign_key => "category_id" belongs_to :category, :class_name => "Enumeration", :foreign_key => "category_id"
has_many :attachments, :as => :container, :dependent => true has_many :attachments, :as => :container, :dependent => true
validates_presence_of :title validates_presence_of :project, :title, :category
end end
...@@ -29,15 +29,19 @@ class Issue < ActiveRecord::Base ...@@ -29,15 +29,19 @@ class Issue < ActiveRecord::Base
has_many :histories, :class_name => 'IssueHistory', :dependent => true, :order => "issue_histories.created_on DESC", :include => :status has_many :histories, :class_name => 'IssueHistory', :dependent => true, :order => "issue_histories.created_on DESC", :include => :status
has_many :attachments, :as => :container, :dependent => true has_many :attachments, :as => :container, :dependent => true
has_many :custom_values, :dependent => true has_many :custom_values, :dependent => true, :as => :customized
has_many :custom_fields, :through => :custom_values has_many :custom_fields, :through => :custom_values
validates_presence_of :subject, :descr, :priority, :tracker, :author validates_presence_of :subject, :description, :priority, :tracker, :author
validates_associated :custom_values, :on => :update
# set default status for new issues # set default status for new issues
def before_validation
self.status = IssueStatus.default if new_record?
end
def before_create def before_create
self.status = IssueStatus.default build_history
build_history
end end
def long_id def long_id
......
# redMine - project management software
# Copyright (C) 2006 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class IssueCustomField < CustomField
has_and_belongs_to_many :projects, :join_table => "custom_fields_projects", :foreign_key => "custom_field_id"
has_and_belongs_to_many :trackers, :join_table => "custom_fields_trackers", :foreign_key => "custom_field_id"
has_many :issues, :through => :issue_custom_values
def type_name
:label_issue_plural
end
end
...@@ -17,20 +17,34 @@ ...@@ -17,20 +17,34 @@
class Mailer < ActionMailer::Base class Mailer < ActionMailer::Base
def issue_change_status(issue) def issue_change_status(issue)
# Sends to all project members # Sends to all project members
@recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification } @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
@from = 'redmine@somenet.foo' @from = 'redmine@somenet.foo'
@subject = "Issue ##{issue.id} has been updated" @subject = "Issue ##{issue.id} has been updated"
@body['issue'] = issue @body['issue'] = issue
end end
def issue_add(issue) def issue_add(issue)
# Sends to all project members # Sends to all project members
@recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification } @recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
@from = 'redmine@somenet.foo' @from = 'redmine@somenet.foo'
@subject = "Issue ##{issue.id} has been reported" @subject = "Issue ##{issue.id} has been reported"
@body['issue'] = issue @body['issue'] = issue
end end
def lost_password(token)
@recipients = token.user.mail
@from = 'redmine@somenet.foo'
@subject = "redMine password"
@body['token'] = token
end
def register(token)
@recipients = token.user.mail
@from = 'redmine@somenet.foo'
@subject = "redMine account activation"
@body['token'] = token
end
end end
...@@ -19,7 +19,7 @@ class News < ActiveRecord::Base ...@@ -19,7 +19,7 @@ class News < ActiveRecord::Base
belongs_to :project belongs_to :project
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
validates_presence_of :title, :shortdescr, :descr validates_presence_of :title, :description
# returns last created news # returns last created news
def self.latest def self.latest
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
class Permission < ActiveRecord::Base class Permission < ActiveRecord::Base
has_and_belongs_to_many :roles has_and_belongs_to_many :roles
validates_presence_of :controller, :action, :descr validates_presence_of :controller, :action, :description
GROUPS = { GROUPS = {
100 => "Project", 100 => "Project",
......
...@@ -16,30 +16,34 @@ ...@@ -16,30 +16,34 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class Project < ActiveRecord::Base class Project < ActiveRecord::Base
has_many :versions, :dependent => true, :order => "versions.effective_date DESC" has_many :versions, :dependent => true, :order => "versions.effective_date DESC, versions.name DESC"
has_many :members, :dependent => true has_many :members, :dependent => true
has_many :users, :through => :members has_many :users, :through => :members
has_many :issues, :dependent => true, :order => "issues.created_on DESC", :include => :status has_many :custom_values, :dependent => true, :as => :customized
has_many :documents, :dependent => true has_many :issues, :dependent => true, :order => "issues.created_on DESC", :include => :status
has_many :news, :dependent => true, :include => :author has_many :documents, :dependent => true
has_many :issue_categories, :dependent => true has_many :news, :dependent => true, :include => :author
has_and_belongs_to_many :custom_fields has_many :issue_categories, :dependent => true, :order => "issue_categories.name"
acts_as_tree :order => "name", :counter_cache => true has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => 'custom_fields_projects', :association_foreign_key => 'custom_field_id'
acts_as_tree :order => "name", :counter_cache => true
validates_presence_of :name, :descr
validates_uniqueness_of :name validates_presence_of :name, :description
validates_uniqueness_of :name
# returns 5 last created projects validates_associated :custom_values, :on => :update
def self.latest
find(:all, :limit => 5, :order => "created_on DESC") # returns 5 last created projects
end def self.latest
find(:all, :limit => 5, :order => "created_on DESC")
# Returns an array of all custom fields enabled for project issues end
# (explictly associated custom fields and custom fields enabled for all projects)
def custom_fields_for_issues # Returns an array of all custom fields enabled for project issues
(CustomField.for_all + custom_fields).uniq # (explictly associated custom fields and custom fields enabled for all projects)
end def custom_fields_for_issues(tracker)
tracker.custom_fields.find(:all, :include => :projects,
:conditions => ["is_for_all=? or project_id=?", true, self.id])
#(CustomField.for_all + custom_fields).uniq
end
protected protected
def validate def validate
errors.add(parent_id, " must be a root project") if parent and parent.parent errors.add(parent_id, " must be a root project") if parent and parent.parent
......
# redMine - project management software
# Copyright (C) 2006 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class ProjectCustomField < CustomField
def type_name
:label_project_plural
end
end
# redMine - project management software
# Copyright (C) 2006 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class Token < ActiveRecord::Base
belongs_to :user
@@validity_time = 1.day
def before_create
self.value = Token.generate_token_value
end
# Return true if token has expired
def expired?
return Time.now > self.created_on + @@validity_time
end
# Delete all expired tokens
def self.destroy_expired
Token.delete_all ["created_on < ?", Time.now - @@validity_time]
end
private
def self.generate_token_value
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
token_value = ''
40.times { |i| token_value << chars[rand(chars.size-1)] }
token_value
end
end
...@@ -19,7 +19,8 @@ class Tracker < ActiveRecord::Base ...@@ -19,7 +19,8 @@ class Tracker < ActiveRecord::Base
before_destroy :check_integrity before_destroy :check_integrity
has_many :issues has_many :issues
has_many :workflows, :dependent => true has_many :workflows, :dependent => true
has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => 'custom_fields_trackers', :association_foreign_key => 'custom_field_id'
validates_presence_of :name validates_presence_of :name
validates_uniqueness_of :name validates_uniqueness_of :name
......
...@@ -19,7 +19,9 @@ require "digest/sha1" ...@@ -19,7 +19,9 @@ require "digest/sha1"
class User < ActiveRecord::Base class User < ActiveRecord::Base
has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :dependent => true has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :dependent => true
has_many :custom_values, :dependent => true, :as => :customized
belongs_to :auth_source
attr_accessor :password, :password_confirmation attr_accessor :password, :password_confirmation
attr_accessor :last_before_login_on attr_accessor :last_before_login_on
# Prevents unauthorized assignments # Prevents unauthorized assignments
...@@ -33,6 +35,12 @@ class User < ActiveRecord::Base ...@@ -33,6 +35,12 @@ class User < ActiveRecord::Base
# Password length between 4 and 12 # Password length between 4 and 12
validates_length_of :password, :in => 4..12, :allow_nil => true validates_length_of :password, :in => 4..12, :allow_nil => true
validates_confirmation_of :password, :allow_nil => true validates_confirmation_of :password, :allow_nil => true
validates_associated :custom_values, :on => :update
# Account statuses
STATUS_ACTIVE = 1
STATUS_REGISTERED = 2
STATUS_LOCKED = 3
def before_save def before_save
# update hashed_password if password was set # update hashed_password if password was set
...@@ -41,23 +49,52 @@ class User < ActiveRecord::Base ...@@ -41,23 +49,52 @@ class User < ActiveRecord::Base
# Returns the user that matches provided login and password, or nil # Returns the user that matches provided login and password, or nil
def self.try_to_login(login, password) def self.try_to_login(login, password)
user = find(:first, :conditions => ["login=? and hashed_password=? and locked=?", login, User.hash_password(password), false]) user = find(:first, :conditions => ["login=?", login])
if user if user
user.last_before_login_on = user.last_login_on # user is already in local database
user.update_attribute(:last_login_on, Time.now) return nil if !user.active?
end if user.auth_source
# user has an external authentication method
return nil unless user.auth_source.authenticate(login, password)
else
# local authentication
return nil unless User.hash_password(password) == user.hashed_password
end
else
# user is not yet registered, try to authenticate with available sources
attrs = AuthSource.authenticate(login, password)
if attrs
onthefly = new(*attrs)
onthefly.login = login
onthefly.language = $RDM_DEFAULT_LANG
if onthefly.save
user = find(:first, :conditions => ["login=?", login])
end
end
end
user.update_attribute(:last_login_on, Time.now) if user
user user
rescue => text
raise text
end end
# Return user's full name for display # Return user's full name for display
def display_name def display_name
firstname + " " + lastname firstname + " " + lastname
end end
def active?
self.status == STATUS_ACTIVE
end
def locked?
self.status == STATUS_LOCKED
end
def check_password?(clear_password) def check_password?(clear_password)
User.hash_password(clear_password) == self.hashed_password User.hash_password(clear_password) == self.hashed_password
end end
def role_for_project(project_id) def role_for_project(project_id)
@role_for_projects ||= @role_for_projects ||=
......
# redMine - project management software
# Copyright (C) 2006 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class UserCustomField < CustomField
def type_name
:label_user_plural
end
end
<div class="box"> <center>
<h2><%=_('Please login') %></h2> <div class="box login">
<h2><%= image_tag 'login' %>&nbsp;&nbsp;<%=l(:label_please_login)%></h2>
<%= start_form_tag :action=> "login" %> <%= start_form_tag :action=> "login" %>
<p><label for="login"><%=_ 'Login' %>:</label><br/> <table cellpadding="4">
<%= text_field_tag 'login', nil, :size => 25 %></p> <tr>
<td><label for="login"><%=l(:field_login)%>:</label></td>
<p><label for="user_password"><%=_ 'Password' %>:</label><br/> <td><%= text_field_tag 'login', nil, :size => 25 %></td>
<%= password_field_tag 'password', nil, :size => 25 %></p> </tr>
<tr>
<td><label for="password"><%=l(:field_password)%>:</label></td>
<td><%= password_field_tag 'password', nil, :size => 25 %></td>
</tr>
</table>
&nbsp;
<p><input type="submit" name="login" value="<%=_ 'Log in' %> &#187;" class="primary" /></p> <p><center><input type="submit" name="login" value="<%=l(:button_login)%> &#187;" class="primary" /></center></p>
<%= end_form_tag %> <%= end_form_tag %>
</div> <br />
\ No newline at end of file <% unless $RDM_SELF_REGISTRATION == false %><%= link_to l(:label_register), :action => 'register' %> |<% end %>
<%= link_to l(:label_password_lost), :action => 'lost_password' %>
</div>
</center>
\ No newline at end of file
<center>
<div class="box login">
<h2><%=l(:label_password_lost)%></h2>
<%= start_form_tag %>
<p><label for="mail"><%=l(:field_mail)%> <span class="required">*</span></label><br/>
<%= text_field_tag 'mail', nil, :size => 40 %></p>
<p><center><%= submit_tag l(:button_submit) %></center></p>
<%= end_form_tag %>
</div>
</center>
\ No newline at end of file
<h2><%=_('My account')%></h2> <h2><%=l(:label_my_account)%></h2>
<p><%=_('Login')%>: <strong><%= @user.login %></strong><br /> <p><%=l(:field_login)%>: <strong><%= @user.login %></strong><br />
<%=_('Created on')%>: <%= format_time(@user.created_on) %>, <%=l(:field_created_on)%>: <%= format_time(@user.created_on) %>,
<%=_('Last update')%>: <%= format_time(@user.updated_on) %></p> <%=l(:field_updated_on)%>: <%= format_time(@user.updated_on) %></p>
<%= error_messages_for 'user' %> <%= error_messages_for 'user' %>
<div class="splitcontentleft"> <div class="splitcontentleft">
<div class="box"> <div class="box">
<h3><%=_('Information')%></h3> <h3><%=l(:label_information_plural)%></h3>
&nbsp; &nbsp;
<%= start_form_tag :action => 'my_account' %> <%= start_form_tag :action => 'my_account' %>
<!--[form:user]--> <!--[form:user]-->
<p><label for="user_firstname"><%=_('Firstname')%> <span class="required">*</span></label><br/> <p><label for="user_firstname"><%=l(:field_firstname)%> <span class="required">*</span></label><br/>
<%= text_field 'user', 'firstname' %></p> <%= text_field 'user', 'firstname' %></p>
<p><label for="user_lastname"><%=_('Lastname')%> <span class="required">*</span></label><br/> <p><label for="user_lastname"><%=l(:field_lastname)%> <span class="required">*</span></label><br/>
<%= text_field 'user', 'lastname' %></p> <%= text_field 'user', 'lastname' %></p>
<p><label for="user_mail"><%=_('Mail')%> <span class="required">*</span></label><br/> <p><label for="user_mail"><%=l(:field_mail)%> <span class="required">*</span></label><br/>
<%= text_field 'user', 'mail' %></p> <%= text_field 'user', 'mail' %></p>
<p><label for="user_language"><%=_('Language')%></label><br/> <p><label for="user_language"><%=l(:field_language)%></label><br/>
<%= select("user", "language", Localization.langs) %></p> <%= select("user", "language", Localization.langs.invert) %></p>
<!--[eoform:user]--> <!--[eoform:user]-->
<p><%= check_box 'user', 'mail_notification' %> <label for="user_mail_notification"><%=_('Mail notifications')%></label></p> <p><%= check_box 'user', 'mail_notification' %> <label for="user_mail_notification"><%=l(:field_mail_notification)%></label></p>
<center><%= submit_tag _('Save') %></center> <center><%= submit_tag l(:button_save) %></center>
<%= end_form_tag %> <%= end_form_tag %>
</div> </div>
</div> </div>
...@@ -36,20 +36,20 @@ ...@@ -36,20 +36,20 @@
<div class="splitcontentright"> <div class="splitcontentright">
<div class="box"> <div class="box">
<h3><%=_('Password')%></h3> <h3><%=l(:field_password)%></h3>
&nbsp; &nbsp;
<%= start_form_tag :action => 'change_password' %> <%= start_form_tag :action => 'change_password' %>
<p><label for="password"><%=_('Password')%> <span class="required">*</span></label><br/> <p><label for="password"><%=l(:field_password)%> <span class="required">*</span></label><br/>
<%= password_field_tag 'password', nil, :size => 25 %></p> <%= password_field_tag 'password', nil, :size => 25 %></p>
<p><label for="new_password"><%=_('New password')%> <span class="required">*</span></label><br/> <p><label for="new_password"><%=l(:field_new_password)%> <span class="required">*</span></label><br/>
<%= password_field_tag 'new_password', nil, :size => 25 %></p> <%= password_field_tag 'new_password', nil, :size => 25 %></p>
<p><label for="new_password_confirmation"><%=_('Confirmation')%> <span class="required">*</span></label><br/> <p><label for="new_password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label><br/>
<%= password_field_tag 'new_password_confirmation', nil, :size => 25 %></p> <%= password_field_tag 'new_password_confirmation', nil, :size => 25 %></p>
<center><%= submit_tag _('Save') %></center> <center><%= submit_tag l(:button_save) %></center>
<%= end_form_tag %> <%= end_form_tag %>
</div> </div>
</div> </div>
\ No newline at end of file
<h2><%=_('My page') %></h2> <h2><%=l(:label_my_page)%></h2>
<p> <p>
<%=_('Welcome')%> <b><%= @user.firstname %></b><br />
<% unless @user.last_before_login_on.nil? %> <% unless @user.last_before_login_on.nil? %>
<%=_('Last login')%>: <%= format_time(@user.last_before_login_on) %> <%=l(:label_last_login)%>: <%= format_time(@user.last_before_login_on) %>
<% end %> <% end %>
</p> </p>
<div class="splitcontentleft"> <div class="splitcontentleft">
<h3><%=_('Reported issues')%></h3> <h3><%=l(:label_reported_issues)%></h3>
<%= render :partial => 'issues/list_simple', :locals => { :issues => @reported_issues } %> <%= render :partial => 'issues/list_simple', :locals => { :issues => @reported_issues } %>
<%= "<p>(Last #{@reported_issues.length} updated)</p>" if @reported_issues.length > 0 %> <% if @reported_issues.length > 0 %>
<p><%=lwr(:label_last_updates, @reported_issues.length)%></p>
<% end %>
</div> </div>
<div class="splitcontentright"> <div class="splitcontentright">
<h3><%=_('Assigned to me')%></h3> <h3><%=l(:label_assigned_to_me_issues)%></h3>
<%= render :partial => 'issues/list_simple', :locals => { :issues => @assigned_issues } %> <%= render :partial => 'issues/list_simple', :locals => { :issues => @assigned_issues } %>
<%= "<p>(Last #{@assigned_issues.length} updated)</p>" if @assigned_issues.length > 0 %> <% if @assigned_issues.length > 0 %>
<p><%=lwr(:label_last_updates, @assigned_issues.length)%></p>
<% end %>
</div> </div>
\ No newline at end of file
<center>
<div class="box login">
<h2><%=l(:label_password_lost)%></h2>
<p><%=l(:field_login)%>: <strong><%= @user.login %></strong><br />
<%= error_messages_for 'user' %>
<%= start_form_tag :token => @token.value %>
<p><label for="new_password"><%=l(:field_new_password)%> <span class="required">*</span></label><br/>
<%= password_field_tag 'new_password', nil, :size => 25 %></p>
<p><label for="new_password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label><br/>
<%= password_field_tag 'new_password_confirmation', nil, :size => 25 %></p>
<p><center><%= submit_tag l(:button_save) %></center></p>
<%= end_form_tag %>
</div>
</center>
\ No newline at end of file
<h2><%=l(:label_register)%></h2>
<%= start_form_tag %>
<%= error_messages_for 'user' %>
<div class="box">
<!--[form:user]-->
<p><label for="user_login"><%=l(:field_login)%></label> <span class="required">*</span><br/>
<%= text_field 'user', 'login', :size => 25 %></p>
<p><label for="password"><%=l(:field_password)%></label> <span class="required">*</span><br/>
<%= password_field_tag 'password', nil, :size => 25 %></p>
<p><label for="password_confirmation"><%=l(:field_password_confirmation)%></label> <span class="required">*</span><br/>
<%= password_field_tag 'password_confirmation', nil, :size => 25 %></p>
<p><label for="user_firstname"><%=l(:field_firstname)%></label> <span class="required">*</span><br/>
<%= text_field 'user', 'firstname' %></p>
<p><label for="user_lastname"><%=l(:field_lastname)%></label> <span class="required">*</span><br/>
<%= text_field 'user', 'lastname' %></p>
<p><label for="user_mail"><%=l(:field_mail)%></label> <span class="required">*</span><br/>
<%= text_field 'user', 'mail' %></p>
<p><label for="user_language"><%=l(:field_language)%></label><br/>
<%= select("user", "language", Localization.langs.invert) %></p>
<% for custom_value in @custom_values %>
<div style="float:left;margin-right:10px;">
<p><%= content_tag "label", custom_value.custom_field.name %>
<% if custom_value.custom_field.is_required? %><span class="required">*</span><% end %>
<br />
<%= custom_field_tag custom_value %></p>
</div>
<% end %>
<div style="clear: both;"></div>
<p><%= check_box 'user', 'mail_notification' %> <label for="user_mail_notification"><%=l(:field_mail_notification)%></label></p>
<!--[eoform:user]-->
</div>
<%= submit_tag l(:button_submit) %>
<%= end_form_tag %>
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
<p> <p>
<%= mail_to @user.mail %><br /> <%= mail_to @user.mail %><br />
<%=_('Registered on')%>: <%= format_date(@user.created_on) %> <%=l(:label_registered_on)%>: <%= format_date(@user.created_on) %>
</p> </p>
<h3><%=_('Projects')%></h3> <h3><%=l(:label_project_plural)%></h3>
<p> <p>
<% for membership in @user.memberships %> <% for membership in @user.memberships %>
<%= membership.project.name %> (<%= membership.role.name %>, <%= format_date(membership.created_on) %>) <%= membership.project.name %> (<%= membership.role.name %>, <%= format_date(membership.created_on) %>)
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<% end %> <% end %>
</p> </p>
<h3><%=_('Activity')%></h3> <h3><%=l(:label_activity)%></h3>
<p> <p>
<%=_('Reported issues')%>: <%= Issue.count( [ "author_id=?", @user.id]) %> <%=l(:label_reported_issues)%>: <%= Issue.count(["author_id=?", @user.id]) %>
</p> </p>
\ No newline at end of file
<h2><%=_('Administration')%></h2> <h2><%=l(:label_administration)%></h2>
<p> <p>
<%= image_tag "projects" %> <%= image_tag "projects" %>
<%= link_to _('Projects'), :controller => 'admin', :action => 'projects' %> | <%= link_to l(:label_project_plural), :controller => 'admin', :action => 'projects' %> |
<%= link_to _('New'), :controller => 'projects', :action => 'add' %> <%= link_to l(:label_new), :controller => 'projects', :action => 'add' %>
</p> </p>
<p> <p>
<%= image_tag "users" %> <%= image_tag "users" %>
<%= link_to _('Users'), :controller => 'users' %> | <%= link_to l(:label_user_plural), :controller => 'users' %> |
<%= link_to _('New'), :controller => 'users', :action => 'add' %> <%= link_to l(:label_new), :controller => 'users', :action => 'add' %>
</p> </p>
<p> <p>
<%= image_tag "role" %> <%= image_tag "role" %>
<%= link_to _('Roles and permissions'), :controller => 'roles' %> <%= link_to l(:label_role_and_permissions), :controller => 'roles' %>
</p> </p>
<p> <p>
<%= image_tag "tracker" %> <%= image_tag "tracker" %>
<%= link_to _('Trackers'), :controller => 'trackers' %> | <%= link_to l(:label_tracker_plural), :controller => 'trackers' %> |
<%= link_to _('Custom fields'), :controller => 'custom_fields' %> <%= link_to l(:label_custom_field_plural), :controller => 'custom_fields' %>
</p> </p>
<p> <p>
<%= image_tag "workflow" %> <%= image_tag "workflow" %>
<%= link_to _('Issue Statuses'), :controller => 'issue_statuses' %> | <%= link_to l(:label_issue_status_plural), :controller => 'issue_statuses' %> |
<%= link_to _('Workflow'), :controller => 'roles', :action => 'workflow' %> <%= link_to l(:label_workflow), :controller => 'roles', :action => 'workflow' %>
</p> </p>
<p> <p>
<%= image_tag "options" %> <%= image_tag "options" %>
<%= link_to _('Enumerations'), :controller => 'enumerations' %> <%= link_to l(:label_enumerations), :controller => 'enumerations' %>
</p> </p>
<p> <p>
<%= image_tag "mailer" %> <%= image_tag "mailer" %>
<%= link_to _('Mail notifications'), :controller => 'admin', :action => 'mail_options' %> <%= link_to l(:field_mail_notification), :controller => 'admin', :action => 'mail_options' %>
</p>
<p>
<%= image_tag "login" %>
<%= link_to l(:label_authentication), :controller => 'auth_sources' %>
</p> </p>
<p> <p>
<%= image_tag "help" %> <%= image_tag "help" %>
<%= link_to _('Information'), :controller => 'admin', :action => 'info' %> <%= link_to l(:label_information_plural), :controller => 'admin', :action => 'info' %>
</p> </p>
\ No newline at end of file
<h2><%=_('Information')%></h2> <h2><%=_('Information')%></h2>
<p><%=_('Version')%>: <strong><%= RDM_APP_NAME %> <%= RDM_APP_VERSION %></strong></p> <p><%=l(:field_version)%>: <strong><%= RDM_APP_NAME %> <%= RDM_APP_VERSION %></strong></p>
Environment: <%=l(:label_environment)%>:
<ul> <ul>
<% Rails::Info.properties.each do |name, value| %> <% Rails::Info.properties.each do |name, value| %>
<li><%= name %>: <%= value %></li> <li><%= name %>: <%= value %></li>
......
<h2><%=_('Mail notifications')%></h2> <h2><%=l(:field_mail_notification)%></h2>
<p><%=_('Select actions for which mail notification should be enabled.')%></p> <p><%=l(:text_select_mail_notifications)%></p>
<%= start_form_tag ({}, :id => 'mail_options_form')%> <%= start_form_tag ({}, :id => 'mail_options_form')%>
<% for action in @actions %> <% for action in @actions %>
<%= check_box_tag "action_ids[]", action.id, action.mail_enabled? %> <%= check_box_tag "action_ids[]", action.id, action.mail_enabled? %>
<%= action.descr %><br /> <%= action.description %><br />
<% end %> <% end %>
<br /> <br />
<p> <p>
<a href="javascript:checkAll('mail_options_form', true)"><%=_('Check all')%></a> | <a href="javascript:checkAll('mail_options_form', true)"><%=l(:button_check_all)%></a> |
<a href="javascript:checkAll('mail_options_form', false)"><%=_('Uncheck all')%></a> <a href="javascript:checkAll('mail_options_form', false)"><%=l(:button_uncheck_all)%></a>
</p> </p>
<%= submit_tag _('Save') %> <%= submit_tag l(:button_save) %>
<%= end_form_tag %> <%= end_form_tag %>
\ No newline at end of file
<h2><%=_('Projects')%></h2> <h2><%=l(:label_project_plural)%></h2>
<table width="100%" cellspacing="1" cellpadding="2" class="listTableContent"> <table width="100%" cellspacing="1" cellpadding="2" class="listTableContent">
<tr class="ListHead"> <tr class="ListHead">
<%= sort_header_tag('name', :caption => _('Project')) %> <%= sort_header_tag('name', :caption => l(:label_project)) %>
<th><%=_('Description')%></th> <th><%=l(:field_description)%></th>
<th><%=_('Public')%></th> <th><%=l(:field_is_public)%></th>
<th><%=_('Subprojects')%></th> <th><%=l(:label_subproject_plural)%></th>
<%= sort_header_tag('created_on', :caption => _('Created on')) %> <%= sort_header_tag('created_on', :caption => l(:field_created_on)) %>
<th></th> <th></th>
</tr> </tr>
<% for project in @projects %> <% for project in @projects %>
<tr class="<%= cycle("odd", "even") %>"> <tr class="<%= cycle("odd", "even") %>">
<td><%= link_to project.name, :controller => 'projects', :action => 'settings', :id => project %> <td><%= link_to project.name, :controller => 'projects', :action => 'settings', :id => project %>
<td><%= project.descr %> <td><%= project.description %>
<td align="center"><%= image_tag 'true' if project.is_public? %> <td align="center"><%= image_tag 'true' if project.is_public? %>
<td align="center"><%= project.projects_count %> <td align="center"><%= project.projects_count %>
<td align="center"><%= format_date(project.created_on) %> <td align="center"><%= format_date(project.created_on) %>
<td align="center"> <td align="center">
<%= start_form_tag({:controller => 'projects', :action => 'destroy', :id => project}) %> <%= start_form_tag({:controller => 'projects', :action => 'destroy', :id => project}) %>
<%= submit_tag _('Delete'), :class => "button-small" %> <%= submit_tag l(:button_delete), :class => "button-small" %>
<%= end_form_tag %> <%= end_form_tag %>
</td> </td>
</tr> </tr>
...@@ -29,4 +29,4 @@ ...@@ -29,4 +29,4 @@
<p><%= pagination_links_full @project_pages %> <p><%= pagination_links_full @project_pages %>
[ <%= @project_pages.current.first_item %> - <%= @project_pages.current.last_item %> / <%= @project_count %> ]</p> [ <%= @project_pages.current.first_item %> - <%= @project_pages.current.last_item %> / <%= @project_count %> ]</p>
<p><%= link_to ('&#187; ' + _('New project')), :controller => 'projects', :action => 'add' %></p> <p><%= link_to ('&#187; ' + l(:label_project_new)), :controller => 'projects', :action => 'add' %></p>
\ No newline at end of file \ No newline at end of file
<%= error_messages_for 'auth_source' %>
<div class="box">
<!--[form:auth_source]-->
<p><label for="auth_source_name"><%=l(:field_name)%></label> <span class="required">*</span><br/>
<%= text_field 'auth_source', 'name' %></p>
<p><label for="auth_source_host"><%=l(:field_host)%></label> <span class="required">*</span><br/>
<%= text_field 'auth_source', 'host' %></p>
<p><label for="auth_source_port"><%=l(:field_port)%></label> <span class="required">*</span><br/>
<%= text_field 'auth_source', 'port', :size => 6 %></p>
<p><label for="auth_source_account"><%=l(:field_account)%></label><br/>
<%= text_field 'auth_source', 'account' %></p>
<p><label for="auth_source_account_password"><%=l(:field_password)%></label><br/>
<%= password_field 'auth_source', 'account_password' %></p>
<p><label for="auth_source_base_dn"><%=l(:field_base_dn)%></label> <span class="required">*</span><br/>
<%= text_field 'auth_source', 'base_dn', :size => 60 %></p>
<p><%= check_box 'auth_source', 'onthefly_register' %>
<label for="auth_source_onthefly_register"><%=l(:field_onthefly)%></label></p>
<fieldset><legend><%=l(:label_attribute_plural)%></legend>
<div style="float:left;margin-right:10px;">
<p><label for="auth_source_attr_login"><%=l(:field_login)%></label> <span class="required">*</span><br/>
<%= text_field 'auth_source', 'attr_login', :size => 20 %></p>
</div>
<div style="float:left;margin-right:10px;">
<p><label for="auth_source_attr_firstname"><%=l(:field_firstname)%></label><br/>
<%= text_field 'auth_source', 'attr_firstname', :size => 20 %></p>
</div>
<div style="float:left;margin-right:10px;">
<p><label for="auth_source_attr_lastname"><%=l(:field_lastname)%></label><br/>
<%= text_field 'auth_source', 'attr_lastname', :size => 20 %></p>
</div>
<div>
<p><label for="auth_source_attr_mail"><%=l(:field_mail)%></label><br/>
<%= text_field 'auth_source', 'attr_mail', :size => 20 %></p>
</div>
</fieldset>
<!--[eoform:auth_source]-->
</div>
<h2><%=l(:label_auth_source)%> (<%= @auth_source.auth_method_name %>)</h2>
<%= start_form_tag :action => 'update', :id => @auth_source %>
<%= render :partial => 'form' %>
<%= submit_tag l(:button_save) %>
<%= end_form_tag %>
<h2><%=l(:label_auth_source_plural)%></h2>
<table border="0" cellspacing="1" cellpadding="2" class="listTableContent">
<tr class="ListHead">
<td><%=l(:field_name)%></td>
<td><%=l(:field_type)%></td>
<td><%=l(:field_host)%></td>
<td></td>
<td></td>
</tr>
<% for source in @auth_sources %>
<tr class="<%= cycle("odd", "even") %>">
<td><%= link_to source.name, :action => 'edit', :id => source%></td>
<td align="center"><%= source.auth_method_name %></td>
<td align="center"><%= source.host %></td>
<td align="center">
<%= link_to l(:button_test), :action => 'test_connection', :id => source %>
</td>
<td align="center">
<%= start_form_tag :action => 'destroy', :id => source %>
<%= submit_tag l(:button_delete), :class => "button-small" %>
<%= end_form_tag %>
</td>
</tr>
<% end %>
</table>
<%= pagination_links_full @auth_source_pages %>
<br />
<%= link_to '&#187; ' + l(:label_auth_source_new), :action => 'new' %>
<h2><%=l(:label_auth_source_new)%> (<%= @auth_source.auth_method_name %>)</h2>
<%= start_form_tag :action => 'create' %>
<%= render :partial => 'form' %>
<%= submit_tag l(:button_create) %>
<%= end_form_tag %>
<%= error_messages_for 'custom_field' %> <%= error_messages_for 'custom_field' %>
<!--[form:custom_field]--> <!--[form:custom_field]-->
<p><label for="custom_field_name"><%=_('Name')%></label><br/> <div class="box">
<%= text_field 'custom_field', 'name' %></p> <p><label for="custom_field_name"><%=l(:field_name)%></label> <span class="required">*</span><br/>
<%= text_field 'custom_field', 'name' %></p>
<p><label for="custom_field_typ"><%=_('Type')%></label><br/> <p><label for="custom_field_typ"><%=l(:field_field_format)%></label><br/>
<%= select("custom_field", "typ", CustomField::TYPES) %></p> <%= select("custom_field", "field_format", custom_field_formats_for_select) %></p>
<p><%= check_box 'custom_field', 'is_required' %> <p><label for="custom_field_min_length"><%=l(:label_min_max_length)%></label> (<%=l(:text_min_max_length_info)%>)<br/>
<label for="custom_field_is_required"><%=_('Required')%></label></p>
<p><%= check_box 'custom_field', 'is_for_all' %>
<label for="custom_field_is_for_all"><%=_('For all projects')%></label></p>
<p><label for="custom_field_min_length"><%=_('Min - max length')%></label> (<%=_('0 means no restriction')%>)<br/>
<%= text_field 'custom_field', 'min_length', :size => 5 %> - <%= text_field 'custom_field', 'min_length', :size => 5 %> -
<%= text_field 'custom_field', 'max_length', :size => 5 %></p> <%= text_field 'custom_field', 'max_length', :size => 5 %></p>
<p><label for="custom_field_regexp"><%=_('Regular expression pattern')%></label> (eg. ^[A-Z0-9]+$)<br/> <p><label for="custom_field_regexp"><%=l(:field_regexp)%></label> (<%=l(:text_regexp_info)%>)<br/>
<%= text_field 'custom_field', 'regexp', :size => 50 %></p> <%= text_field 'custom_field', 'regexp', :size => 50 %></p>
<p><label for="custom_field_possible_values"><%=_('Possible values')%></label> (separator: |)<br/> <p><label for="custom_field_possible_values"><%=l(:field_possible_values)%></label> (<%=l(:text_possible_values_info)%>)<br/>
<%= text_area 'custom_field', 'possible_values', :rows => 5, :cols => 60 %></p> <%= text_area 'custom_field', 'possible_values', :rows => 5, :cols => 60 %></p>
</div>
<!--[eoform:custom_field]--> <!--[eoform:custom_field]-->
<div class="box">
<% case type.to_s
when "IssueCustomField" %>
<fieldset><legend><%=l(:label_tracker_plural)%></legend>
<% for tracker in @trackers %>
<input type="checkbox"
name="tracker_ids[]"
value="<%= tracker.id %>"
<%if @custom_field.trackers.include? tracker%>checked="checked"<%end%>
> <%= tracker.name %>
<% end %></fieldset>
&nbsp;
<p><%= check_box 'custom_field', 'is_required' %>
<label for="custom_field_is_required"><%=l(:field_is_required)%></label></p>
<p><%= check_box 'custom_field', 'is_for_all' %>
<label for="custom_field_is_for_all"><%=l(:field_is_for_all)%></label></p>
<% when "UserCustomField" %>
<p><%= check_box 'custom_field', 'is_required' %>
<label for="custom_field_is_required"><%=l(:field_is_required)%></label></p>
<% when "ProjectCustomField" %>
<p><%= check_box 'custom_field', 'is_required' %>
<label for="custom_field_is_required"><%=l(:field_is_required)%></label></p>
<% end %>
</div>
<h2><%=_('Custom field')%></h2> <h2><%=l(:label_custom_field)%> (<%=l(@custom_field.type_name)%>)</h2>
<%= start_form_tag :action => 'edit', :id => @custom_field %> <%= start_form_tag :action => 'edit', :id => @custom_field %>
<%= render :partial => 'form' %> <%= render :partial => 'form', :locals => { :type => @custom_field.type } %>
<%= submit_tag _('Save') %> <%= submit_tag l(:button_save) %>
<%= end_form_tag %> <%= end_form_tag %>
<h2><%=_('Custom fields')%></h2> <h2><%=l(:label_custom_field_plural)%></h2>
<table border="0" cellspacing="1" cellpadding="2" class="listTableContent"> <table border="0" cellspacing="1" cellpadding="2" class="listTableContent">
<tr class="ListHead"> <tr class="ListHead">
<th><%=_('Name')%></th> <th><%=l(:field_name)%></th>
<th><%=_('Type')%></th> <th><%=l(:field_type)%></th>
<th><%=_('Required')%></th> <th><%=l(:field_field_format)%></th>
<th><%=_('For all projects')%></th> <th><%=l(:field_is_required)%></th>
<th><%=l(:field_is_for_all)%></th>
<th><%=_('Used by')%></th> <th><%=_('Used by')%></th>
<th></th> <th></th>
</tr> </tr>
<% for custom_field in @custom_fields %> <% for custom_field in @custom_fields %>
<tr class="<%= cycle("odd", "even") %>"> <tr class="<%= cycle("odd", "even") %>">
<td><%= link_to custom_field.name, :action => 'edit', :id => custom_field %></td> <td><%= link_to custom_field.name, :action => 'edit', :id => custom_field %></td>
<td align="center"><%= CustomField::TYPES[custom_field.typ][0] %></td> <td align="center"><%= l(custom_field.type_name) %></td>
<td align="center"><%= l(CustomField::FIELD_FORMATS[custom_field.field_format]) %></td>
<td align="center"><%= image_tag 'true' if custom_field.is_required? %></td> <td align="center"><%= image_tag 'true' if custom_field.is_required? %></td>
<td align="center"><%= image_tag 'true' if custom_field.is_for_all? %></td> <td align="center"><%= image_tag 'true' if custom_field.is_for_all? %></td>
<td align="center"><%= custom_field.projects.count.to_s + ' ' + _('Project') + '(s)' unless custom_field.is_for_all? %></td> <td align="center"><%= custom_field.projects.count.to_s + ' ' + lwr(:label_project, custom_field.projects.count) if custom_field.is_a? IssueCustomField and !custom_field.is_for_all? %></td>
<td align="center"> <td align="center">
<%= start_form_tag :action => 'destroy', :id => custom_field %> <%= start_form_tag :action => 'destroy', :id => custom_field %>
<%= submit_tag _('Delete'), :class => "button-small" %> <%= submit_tag l(:button_delete), :class => "button-small" %>
<%= end_form_tag %> </td> <%= end_form_tag %> </td>
</tr> </tr>
<% end %> <% end %>
</table> </table>
<%= link_to ('&#171; ' + _('Previous')), { :page => @custom_field_pages.current.previous } if @custom_field_pages.current.previous %> <%= pagination_links_full @custom_field_pages %>
<%= link_to (_('Next') + ' &#187;'), { :page => @custom_field_pages.current.next } if @custom_field_pages.current.next %>
<br /> <br />
<%=l(:label_custom_field_new)%>:
<%= link_to ('&#187; ' + _('New custom field')), :action => 'new' %> <ul>
<li><%= link_to l(:label_issue_plural), :action => 'new', :type => 'IssueCustomField' %></li>
<li><%= link_to l(:label_project_plural), :action => 'new', :type => 'ProjectCustomField' %></li>
<li><%= link_to l(:label_user_plural), :action => 'new', :type => 'UserCustomField' %></li>
</ul>
<h2><%=_('New custom field')%></h2> <h2><%=l(:label_custom_field_new)%> (<%=l(@custom_field.type_name)%>)</h2>
<%= start_form_tag :action => 'new' %> <%= start_form_tag :action => 'new' %>
<%= render :partial => 'form' %> <%= render :partial => 'form', :locals => { :type => @custom_field.type } %>
<%= submit_tag _('Create') %> <%= hidden_field_tag 'type', @custom_field.type %>
<%= submit_tag l(:button_save) %>
<%= end_form_tag %> <%= end_form_tag %>
<%= error_messages_for 'document' %> <%= error_messages_for 'document' %>
<!--[form:document]--> <!--[form:document]-->
<p><label for="document_category_id"><%=_('Category')%></label><br /> <p><label for="document_category_id"><%=l(:field_category)%></label><br />
<select name="document[category_id]"> <select name="document[category_id]">
<%= options_from_collection_for_select @categories, "id", "name",@document.category_id %> <%= options_from_collection_for_select @categories, "id", "name", @document.category_id %>
</select></p> </select></p>
<p><label for="document_title"><%=_('Title')%> <span class="required">*</span></label><br /> <p><label for="document_title"><%=l(:field_title)%> <span class="required">*</span></label><br />
<%= text_field 'document', 'title', :size => 60 %></p> <%= text_field 'document', 'title', :size => 60 %></p>
<p><label for="document_descr"><%=_('Description')%> <span class="required">*</span></label><br /> <p><label for="document_description"><%=l(:field_description)%> <span class="required">*</span></label><br />
<%= text_area 'document', 'descr', :cols => 60, :rows => 5 %></p> <%= text_area 'document', 'description', :cols => 60, :rows => 5 %></p>
<!--[eoform:document]--> <!--[eoform:document]-->
<h2><%= @document.title %></h2> <h2><%= @document.title %></h2>
<strong><%=_('Description')%>:</strong> <%= @document.descr %><br /> <strong><%=_('Description')%>:</strong> <%= @document.description %><br />
<strong><%=_('Category')%>:</strong> <%= @document.category.name %><br /> <strong><%=_('Category')%>:</strong> <%= @document.category.name %><br />
<br /> <br />
......
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
<%= hidden_field_tag 'confirm', 1 %> <%= hidden_field_tag 'confirm', 1 %>
<%= hidden_field 'history', 'status_id' %> <%= hidden_field 'history', 'status_id' %>
<div class="box">
<p><%=_('New status')%>: <b><%= @history.status.name %></b></p> <p><%=_('New status')%>: <b><%= @history.status.name %></b></p>
<div> <div>
...@@ -24,6 +25,8 @@ ...@@ -24,6 +25,8 @@
<p><label for="history_notes"><%=_('Notes')%></label><br /> <p><label for="history_notes"><%=_('Notes')%></label><br />
<%= text_area 'history', 'notes', :cols => 60, :rows => 10 %></p> <%= text_area 'history', 'notes', :cols => 60, :rows => 10 %></p>
</div>
<%= submit_tag _('Save') %> <%= submit_tag _('Save') %>
<%= end_form_tag %> <%= end_form_tag %>
<h2><%=_('Issue')%> #<%= @issue.id %></h2> <h2><%=_@issue.tracker.name%> #<%= @issue.id %> - <%= @issue.subject %></h2>
<%= error_messages_for 'issue' %> <%= error_messages_for 'issue' %>
<%= start_form_tag :action => 'edit', :id => @issue %> <%= start_form_tag :action => 'edit', :id => @issue %>
<div class="box">
<!--[form:issue]--> <!--[form:issue]-->
<p><%=_('Status')%>: <b><%= @issue.status.name %></b></p> <p><%=_('Status')%>: <b><%= @issue.status.name %></b></p>
<div style="float:left;margin-right:10px;">
<p><label for="issue_tracker_id"><%=_('Tracker')%> <span class="required">*</span></label><br/>
<select name="issue[tracker_id]">
<%= options_from_collection_for_select @trackers, "id", "name", @issue.tracker_id %></p>
</select></p>
</div>
<div style="float:left;margin-right:10px;"> <div style="float:left;margin-right:10px;">
<p><label for="issue_priority_id"><%=_('Priority')%> <span class="required">*</span></label><br/> <p><label for="issue_priority_id"><%=_('Priority')%> <span class="required">*</span></label><br/>
<select name="issue[priority_id]"> <select name="issue[priority_id]">
...@@ -39,24 +33,21 @@ ...@@ -39,24 +33,21 @@
<p><label for="issue_subject"><%=_('Subject')%></label><span class="required">*</span><br/> <p><label for="issue_subject"><%=_('Subject')%></label><span class="required">*</span><br/>
<%= text_field 'issue', 'subject', :size => 60 %></p> <%= text_field 'issue', 'subject', :size => 60 %></p>
<p><label for="issue_descr"><%=_('Description')%></label><span class="required">*</span><br/> <p><label for="issue_description"><%=_('Description')%></label><span class="required">*</span><br/>
<%= text_area 'issue', 'descr', :cols => 60, :rows => 10 %></p> <%= text_area 'issue', 'description', :cols => 60, :rows => 10 %></p>
<% for custom_value in @custom_values %>
<% for custom_value in @custom_values %> <p><%= custom_field_tag_with_label custom_value %></p>
<p><%= content_tag "label", custom_value.custom_field.name %>
<% if custom_value.custom_field.is_required? %><span class="required">*</span><% end %>
<br />
<%= custom_field_tag custom_value %></p>
<% end %> <% end %>
<p><label for="issue_fixed_version"><%=_('Fixed in version')%></label><br/> <p><label for="issue_fixed_version"><%=_('Fixed in version')%></label><br/>
<select name="issue[fixed_version_id]"> <select name="issue[fixed_version_id]">
<option value="">--none--</option> <option value="">--none--</option>
<%= options_from_collection_for_select @project.versions, "id", "name", @issue.fixed_version_id %> <%= options_from_collection_for_select @project.versions, "id", "name", @issue.fixed_version_id %>
</select></p> </select></p>
<!--[eoform:issue]--> <!--[eoform:issue]-->
</div>
<center><%= submit_tag _('Save') %></center> <%= submit_tag _('Save') %>
<%= end_form_tag %> <%= end_form_tag %>
<h2><%=_('Issue')%> #<%= @issue.id %> - <%= @issue.subject %></h2> <h2><%=_(@issue.tracker.name)%> #<%= @issue.id %> - <%= @issue.subject %></h2>
<div class="box"> <div class="box">
<p><b><%=_('Tracker')%>:</b> <%= @issue.tracker.name %></p> <p><b><%=_('Status')%>:</b> <%= @issue.status.name %></p>
<p><b><%=_('Priority')%>:</b> <%= @issue.priority.name %></p> <p><b><%=_('Priority')%>:</b> <%= @issue.priority.name %></p>
<p><b><%=_('Category')%>:</b> <%= @issue.category.name unless @issue.category_id.nil? %></p> <p><b><%=_('Category')%>:</b> <%= @issue.category.name unless @issue.category_id.nil? %></p>
<p><b><%=_('Status')%>:</b> <%= @issue.status.name %></p>
<p><b><%=_('Author')%>:</b> <%= @issue.author.display_name %></p> <p><b><%=_('Author')%>:</b> <%= @issue.author.display_name %></p>
<p><b><%=_('Assigned to')%>:</b> <%= @issue.assigned_to.display_name unless @issue.assigned_to.nil? %></p> <p><b><%=_('Assigned to')%>:</b> <%= @issue.assigned_to.display_name unless @issue.assigned_to.nil? %></p>
<p><b><%=_('Subject')%>:</b> <%= @issue.subject %></p> <p><b><%=_('Subject')%>:</b> <%= @issue.subject %></p>
<p><b><%=_('Description')%>:</b> <%= simple_format auto_link @issue.descr %></p> <p><b><%=_('Description')%>:</b> <%= simple_format auto_link @issue.description %></p>
<p><b><%=_('Created on')%>:</b> <%= format_date(@issue.created_on) %></p> <p><b><%=_('Created on')%>:</b> <%= format_date(@issue.created_on) %></p>
<% for custom_value in @custom_values %>
<p><b><%= custom_value.custom_field.name %></b>: <%= show_value custom_value %></p>
<% end %>
<% if authorize_for('issues', 'edit') %> <% if authorize_for('issues', 'edit') %>
<%= start_form_tag ({:controller => 'issues', :action => 'edit', :id => @issue}, :method => "get" ) %> <%= start_form_tag ({:controller => 'issues', :action => 'edit', :id => @issue}, :method => "get" ) %>
<%= submit_tag _('Edit') %> <%= submit_tag _('Edit') %>
......
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head> <head>
<title>redMine</title> <title><%= $RDM_HEADER_TITLE %></title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="description" content="redMine" /> <meta name="description" content="redMine" />
<meta name="keywords" content="issue,bug,tracker" /> <meta name="keywords" content="issue,bug,tracker" />
<%= stylesheet_link_tag "application" %> <%= stylesheet_link_tag "application" %>
<%= stylesheet_link_tag "menu" %>
<%= stylesheet_link_tag "rails" %> <%= stylesheet_link_tag "rails" %>
<%= javascript_include_tag :defaults %> <%= javascript_include_tag :defaults %>
<%= javascript_include_tag 'menu' %>
<script type='text/javascript'>
var menu_contenu=' \
<div id="menuAdmin" class="menu" onmouseover="menuMouseover(event)"> \
<a class="menuItem" href="\/admin\/projects" onmouseover="menuItemMouseover(event,\'menuProjects\');"><span class="menuItemText"><%=_('Projects')%><\/span><span class="menuItemArrow">&#9654;<\/span><\/a> \
<a class="menuItem" href="\/users" onmouseover="menuItemMouseover(event,\'menuUsers\');"><span class="menuItemText"><%=_('Users')%><\/span><span class="menuItemArrow">&#9654;<\/span><\/a> \
<a class="menuItem" href="\/roles"><%=_('Roles and permissions')%><\/a> \
<a class="menuItem" href="\/trackers" onmouseover="menuItemMouseover(event,\'menuTrackers\');"><span class="menuItemText"><%=_('Trackers')%><\/span><span class="menuItemArrow">&#9654;<\/span><\/a> \
<a class="menuItem" href="\/custom_fields"><%=_('Custom fields')%><\/a> \
<a class="menuItem" href="\/enumerations"><%=_('Enumerations')%><\/a> \
<a class="menuItem" href="\/admin\/mail_options"><%=_('Mail notifications')%><\/a> \
<a class="menuItem" href="\/auth_sources"><%=l(:label_authentication)%><\/a> \
<a class="menuItem" href="\/admin\/info"><%=_('Information')%><\/a> \
<\/div> \
<div id="menuTrackers" class="menu"> \
<a class="menuItem" href="\/issue_statuses"><%=_('Issue Statuses')%><\/a> \
<a class="menuItem" href="\/roles\/workflow"><%=_('Workflow')%><\/a> \
<\/div> \
<div id="menuProjects" class="menu"><a class="menuItem" href="\/projects\/add"><%=_('New')%><\/a><\/div> \
<div id="menuUsers" class="menu"><a class="menuItem" href="\/users\/add"><%=_('New')%><\/a><\/div> \
\
<% unless @project.nil? || @project.id.nil? %> \
<div id="menuProject" class="menu" onmouseover="menuMouseover(event)"> \
<%= link_to _('Issues'), {:controller => 'projects', :action => 'list_issues', :id => @project }, :class => "menuItem" %> \
<%= link_to _('Reports'), {:controller => 'reports', :action => 'issue_report', :id => @project }, :class => "menuItem" %> \
<%= link_to _('News'), {:controller => 'projects', :action => 'list_news', :id => @project }, :class => "menuItem" %> \
<%= link_to _('Change log'), {:controller => 'projects', :action => 'changelog', :id => @project }, :class => "menuItem" %> \
<%= link_to _('Documents'), {:controller => 'projects', :action => 'list_documents', :id => @project }, :class => "menuItem" %> \
<%= link_to _('Members'), {:controller => 'projects', :action => 'list_members', :id => @project }, :class => "menuItem" %> \
<%= link_to _('Files'), {:controller => 'projects', :action => 'list_files', :id => @project }, :class => "menuItem" %> \
<%= link_to_if_authorized _('Settings'), {:controller => 'projects', :action => 'settings', :id => @project }, :class => "menuItem" %> \
<\/div> \
<% end %> \
';
</script>
</head> </head>
<body> <body>
...@@ -15,37 +53,42 @@ ...@@ -15,37 +53,42 @@
<div id="header"> <div id="header">
<div style="float: left;"> <div style="float: left;">
<h1><%= RDM_APP_NAME %></h1> <h1><%= $RDM_HEADER_TITLE %></h1>
<h2>Project management</h2> <h2><%= $RDM_HEADER_SUBTITLE %></h2>
</div> </div>
<div style="float: right; padding-right: 1em; padding-top: 0.2em;"> <div style="float: right; padding-right: 1em; padding-top: 0.2em;">
<% unless session[:user].nil? %><small><%=_('Logged as')%> <b><%= session[:user].login %></b></small><% end %> <% if loggedin? %><small><%=l(:label_logged_as)%> <b><%= @logged_in_user.login %></b></small><% end %>
</div> </div>
</div> </div>
<div id="navigation"> <div id="navigation">
<ul> <ul>
<li class="selected"><%= link_to _('Home'), { :controller => '' }, :class => "picHome" %></li> <li class="selected"><%= link_to l(:label_home), { :controller => '' }, :class => "picHome" %></li>
<li><%= link_to _('My page'), { :controller => 'account', :action => 'my_page'}, :class => "picUserPage" %></li> <li><%= link_to l(:label_my_page), { :controller => 'account', :action => 'my_page'}, :class => "picUserPage" %></li>
<li><%= link_to _('Projects'), { :controller => 'projects' }, :class => "picProject" %></li> <li><%= link_to l(:label_project_plural), { :controller => 'projects' }, :class => "picProject" %></li>
<% unless session[:user].nil? %> <% unless @project.nil? || @project.id.nil? %>
<li><%= link_to _('My account'), { :controller => 'account', :action => 'my_account' }, :class => "picUser" %></li> <li><%= link_to @project.name, { :controller => 'projects', :action => 'show', :id => @project }, :class => "picProject", :onmouseover => "buttonMouseover(event, 'menuProject');" %></li>
<% end %> <% end %>
<% if admin_loggedin? %> <% if loggedin? %>
<li><%= link_to _('Administration'), { :controller => 'admin' }, :class => "picAdmin" %></li> <li><%= link_to l(:label_my_account), { :controller => 'account', :action => 'my_account' }, :class => "picUser" %></li>
<% end %> <% end %>
<li class="right"><%= link_to _('Help'), { :controller => 'help', :ctrl => @params[:controller], :page => @params[:action] }, :target => "new", :class => "picHelp" %></li> <% if admin_loggedin? %>
<% if session[:user].nil? %> <li><%= link_to l(:label_administration), { :controller => 'admin' }, :class => "picAdmin", :onmouseover => "buttonMouseover(event, 'menuAdmin');" %></li>
<li class="right"><%= link_to _('Log in'), { :controller => 'account', :action => 'login' }, :class => "picUser" %></li> <% end %>
<% else %>
<li class="right"><%= link_to _('Logout'), { :controller => 'account', :action => 'logout' }, :class => "picUser" %></li> <li class="right"><%= link_to l(:label_help), { :controller => 'help', :ctrl => @params[:controller], :page => @params[:action] }, :target => "new", :class => "picHelp" %></li>
<% end %>
</ul> <% if loggedin? %>
<li class="right"><%= link_to l(:label_logout), { :controller => 'account', :action => 'logout' }, :class => "picUser" %></li>
<% else %>
<li class="right"><%= link_to l(:label_login), { :controller => 'account', :action => 'login' }, :class => "picUser" %></li>
<% end %>
</ul>
</div> </div>
<script type='text/javascript'>if(document.getElementById) {document.write(menu_contenu);}</script>
<div id="subcontent"> <div id="subcontent">
...@@ -64,15 +107,14 @@ ...@@ -64,15 +107,14 @@
</ul> </ul>
<% end %> <% end %>
<% unless session[:user].nil? %> <% if loggedin? and @logged_in_user.memberships.length > 0 %>
<h2><%=_('My projects') %></h2> <h2><%=_('My projects') %></h2>
<ul class="menublock"> <ul class="menublock">
<% for membership in session[:user].memberships %> <% for membership in @logged_in_user.memberships %>
<li><%= link_to membership.project.name, :controller => 'projects', :action => 'show', :id => membership.project %></li> <li><%= link_to membership.project.name, :controller => 'projects', :action => 'show', :id => membership.project %></li>
<% end %> <% end %>
</ul> </ul>
<% end %> <% end %>
</div> </div>
<div id="content"> <div id="content">
...@@ -81,7 +123,10 @@ ...@@ -81,7 +123,10 @@
</div> </div>
<div id="footer"> <div id="footer">
<p><a href="http://redmine.org/" target="_new"><%= RDM_APP_NAME %></a> <%= RDM_APP_VERSION %></p> <p>
<%= auto_link $RDM_FOOTER_SIG %> |
<a href="http://redmine.org/" target="_new"><%= RDM_APP_NAME %></a> <%= RDM_APP_VERSION %>
</p>
</div> </div>
</div> </div>
......
<%=_('Issue')%> #<%= issue.id %> - <%= issue.subject %> <%=_('Issue')%> #<%= issue.id %> - <%= issue.subject %>
<%=_('Author')%>: <%= issue.author.display_name %> <%=_('Author')%>: <%= issue.author.display_name %>
<%= issue.descr %> <%= issue.description %>
http://<%= RDM_HOST_NAME %>/issues/show/<%= issue.id %> http://<%= $RDM_HOST_NAME %>/issues/show/<%= issue.id %>
\ No newline at end of file \ No newline at end of file
Une nouvelle demande (#<%= @issue.id %>) a été soumise.
----------------------------------------
<%= render :file => "_issue", :use_full_path => true, :locals => { :issue => @issue } %>
\ No newline at end of file
La demande #<%= @issue.id %> a été mise à jour au statut "<%= @issue.status.name %>".
----------------------------------------
<%= render :file => "_issue", :use_full_path => true, :locals => { :issue => @issue } %>
\ No newline at end of file
To change your password, use the following link:
http://<%= $RDM_HOST_NAME %>/account/lost_password?token=<%= @token.value %>
\ No newline at end of file
Pour changer votre mot de passe, utilisez le lien suivant:
http://<%= $RDM_HOST_NAME %>/account/lost_password?token=<%= @token.value %>
\ No newline at end of file
To activate your redMine account, use the following link:
http://<%= $RDM_HOST_NAME %>/account/register?token=<%= @token.value %>
\ No newline at end of file
Pour activer votre compte sur redMine, utilisez le lien suivant:
http://<%= $RDM_HOST_NAME %>/account/register?token=<%= @token.value %>
\ No newline at end of file
...@@ -4,10 +4,10 @@ ...@@ -4,10 +4,10 @@
<p><label for="news_title"><%=_('Title')%></label> <span class="required">*</span><br/> <p><label for="news_title"><%=_('Title')%></label> <span class="required">*</span><br/>
<%= text_field 'news', 'title', :size => 60 %></p> <%= text_field 'news', 'title', :size => 60 %></p>
<p><label for="news_shortdescr"><%=_('Summary')%> <span class="required">*</span></label><br/> <p><label for="news_summary"><%=_('Summary')%></label><br/>
<%= text_area 'news', 'shortdescr', :cols => 60, :rows => 2 %></p> <%= text_area 'news', 'summary', :cols => 60, :rows => 2 %></p>
<p><label for="news_descr"><%=_('Description')%> <span class="required">*</span></label><br/> <p><label for="news_description"><%=_('Description')%> <span class="required">*</span></label><br/>
<%= text_area 'news', 'descr', :cols => 60, :rows => 10 %></p> <%= text_area 'news', 'description', :cols => 60, :rows => 10 %></p>
<!--[eoform:news]--> <!--[eoform:news]-->
<h2><%= @news.title %></h2> <h2><%= @news.title %></h2>
<p> <p>
<b><%=_('Summary')%></b>: <%= @news.shortdescr %><br /> <b><%=_('Summary')%></b>: <%= @news.summary %><br />
<b><%=_('By')%></b>: <%= @news.author.display_name %><br /> <b><%=_('By')%></b>: <%= @news.author.display_name %><br />
<b><%=_('Date')%></b>: <%= format_time(@news.created_on) %> <b><%=_('Date')%></b>: <%= format_time(@news.created_on) %>
</p> </p>
<%= simple_format auto_link @news.descr %> <%= simple_format auto_link @news.description %>
<%= error_messages_for 'project' %> <%= error_messages_for 'project' %>
<div class="box">
<!--[form:project]--> <!--[form:project]-->
<p><label for="project_name"><%=_('Name')%> <span class="required">*</span></label><br/> <p><label for="project_name"><%=_('Name')%> <span class="required">*</span></label><br/>
<%= text_field 'project', 'name' %></p> <%= text_field 'project', 'name' %></p>
<% if session[:user].admin %> <% if admin_loggedin? %>
<p><label for="project_parent_id"><%=_('Subproject of')%></label><br/> <p><label for="project_parent_id"><%=_('Subproject of')%></label><br/>
<select name="project[parent_id]"> <select name="project[parent_id]">
<option value=""></option> <option value=""></option>
...@@ -12,15 +13,19 @@ ...@@ -12,15 +13,19 @@
</select></p> </select></p>
<% end %> <% end %>
<p><label for="project_descr"><%=_('Description')%> <span class="required">*</span></label><br/> <p><label for="project_description"><%=_('Description')%> <span class="required">*</span></label><br/>
<%= text_area 'project', 'descr', :cols => 60, :rows => 3 %></p> <%= text_area 'project', 'description', :cols => 60, :rows => 3 %></p>
<p><label for="project_homepage"><%=_('Homepage')%></label><br/> <p><label for="project_homepage"><%=_('Homepage')%></label><br/>
<%= text_field 'project', 'homepage', :size => 40 %></p> <%= text_field 'project', 'homepage', :size => 40 %></p>
<p><%= check_box 'project', 'is_public' %> <p><%= check_box 'project', 'is_public' %>
<label for="project_is_public"><%=_('Public')%></label></p> <label for="project_is_public"><%=_('Public')%></label></p>
<% for custom_value in @custom_values %>
<p><%= custom_field_tag_with_label custom_value %></p>
<% end %>
<fieldset><legend><%=_('Custom fields')%></legend> <fieldset><legend><%=_('Custom fields')%></legend>
<% for custom_field in @custom_fields %> <% for custom_field in @custom_fields %>
<input type="checkbox" <input type="checkbox"
...@@ -31,6 +36,6 @@ ...@@ -31,6 +36,6 @@
> <%= custom_field.name %> > <%= custom_field.name %>
<% end %></fieldset> <% end %></fieldset>
<br />
</div>
<!--[eoform:project]--> <!--[eoform:project]-->
...@@ -4,4 +4,3 @@ ...@@ -4,4 +4,3 @@
<%= render :partial => 'form' %> <%= render :partial => 'form' %>
<%= submit_tag _('Create') %> <%= submit_tag _('Create') %>
<%= end_form_tag %> <%= end_form_tag %>
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
<p><label for="document_title"><%=_('Title')%> <span class="required">*</span></label><br /> <p><label for="document_title"><%=_('Title')%> <span class="required">*</span></label><br />
<%= text_field 'document', 'title', :size => 60 %></p> <%= text_field 'document', 'title', :size => 60 %></p>
<p><label for="document_descr"><%=_('Description')%> <span class="required">*</span></label><br /> <p><label for="document_description"><%=_('Description')%> <span class="required">*</span></label><br />
<%= text_area 'document', 'descr', :cols => 60, :rows => 5 %></p> <%= text_area 'document', 'description', :cols => 60, :rows => 5 %></p>
<p><label for="attachment_file"><%=_('File')%></label><br/> <p><label for="attachment_file"><%=_('File')%></label><br/>
<%= file_field 'attachment', 'file' %></p> <%= file_field 'attachment', 'file' %></p>
......
<h2><%=_('New issue')%></h2> <h2><%=_('New issue')%>: <%=_(@tracker.name)%></h2>
<%= start_form_tag( { :action => 'add_issue', :id => @project }, :multipart => true) %> <%= start_form_tag( { :action => 'add_issue', :id => @project }, :multipart => true) %>
<%= error_messages_for 'issue' %> <%= error_messages_for 'issue' %>
<div class="box">
<!--[form:issue]--> <!--[form:issue]-->
<div style="float:left;margin-right:10px;"> <%= hidden_field_tag 'tracker_id', @tracker.id %>
<p><label for="issue_tracker_id"><%=_('Tracker')%> <span class="required">*</span></label><br/>
<select name="issue[tracker_id]">
<%= options_from_collection_for_select @trackers, "id", "name", @issue.tracker_id %></p>
</select></p>
</div>
<div style="float:left;margin-right:10px;"> <div style="float:left;margin-right:10px;">
<p><label for="issue_priority_id"><%=_('Priority')%> <span class="required">*</span></label><br/> <p><label for="issue_priority_id"><%=_('Priority')%> <span class="required">*</span></label><br/>
...@@ -30,33 +26,26 @@ ...@@ -30,33 +26,26 @@
<div> <div>
<p><label for="issue_category_id"><%=_('Category')%></label><br/> <p><label for="issue_category_id"><%=_('Category')%></label><br/>
<select name="issue[category_id]"> <select name="issue[category_id]">
<option value=""></option> <option value=""></option><%= options_from_collection_for_select @project.issue_categories, "id", "name", @issue.category_id %>
<%= options_from_collection_for_select @project.issue_categories, "id", "name", @issue.category_id %></p>
</select></p> </select></p>
</div> </div>
<p><label for="issue_subject"><%=_('Subject')%> <span class="required">*</span></label><br/> <p><label for="issue_subject"><%=_('Subject')%> <span class="required">*</span></label><br/>
<%= text_field 'issue', 'subject', :size => 80 %></p> <%= text_field 'issue', 'subject', :size => 80 %></p>
<p><label for="issue_descr"><%=_('Description')%> <span class="required">*</span></label><br/> <p><label for="issue_description"><%=_('Description')%> <span class="required">*</span></label><br/>
<%= text_area 'issue', 'descr', :cols => 60, :rows => 10 %></p> <%= text_area 'issue', 'description', :cols => 60, :rows => 10 %></p>
<% for custom_value in @custom_values %> <% for custom_value in @custom_values %>
<div style="float:left;margin-right:10px;"> <p><%= custom_field_tag_with_label custom_value %></p>
<p><%= content_tag "label", custom_value.custom_field.name %>
<% if custom_value.custom_field.is_required? %><span class="required">*</span><% end %>
<br />
<%= custom_field_tag custom_value %></p>
</div>
<% end %> <% end %>
<div style="clear: both;">
<p><label for="attachment_file"><%=_('Attachment')%></label><br/> <p><label for="attachment_file"><%=_('Attachment')%></label><br/>
<%= file_field 'attachment', 'file' %></p> <%= file_field 'attachment', 'file' %></p>
</div>
<!--[eoform:issue]--> <!--[eoform:issue]-->
</div>
<%= submit_tag _('Create') %> <%= submit_tag _('Create') %>
<%= end_form_tag %> <%= end_form_tag %>
\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<% fixed_issues = @fixed_issues.group_by {|i| i.fixed_version } %> <% fixed_issues = @fixed_issues.group_by {|i| i.fixed_version } %>
<% fixed_issues.each do |version, issues| %> <% fixed_issues.each do |version, issues| %>
<p><strong><%= version.name %></strong> - <%= format_date(version.effective_date) %><br /> <p><strong><%= version.name %></strong> - <%= format_date(version.effective_date) %><br />
<%=h version.descr %></p> <%=h version.description %></p>
<ul> <ul>
<% issues.each do |i| %> <% issues.each do |i| %>
<li><%= link_to i.long_id, :controller => 'issues', :action => 'show', :id => i %> [<%= i.tracker.name %>]: <%= i.subject %></li> <li><%= link_to i.long_id, :controller => 'issues', :action => 'show', :id => i %> [<%= i.tracker.name %>]: <%= i.subject %></li>
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<% for project in @projects %> <% for project in @projects %>
<tr class="<%= cycle("odd", "even") %>"> <tr class="<%= cycle("odd", "even") %>">
<td><%= link_to project.name, :action => 'show', :id => project %> <td><%= link_to project.name, :action => 'show', :id => project %>
<td><%= project.descr %> <td><%= project.description %>
<td align="center"><%= format_date(project.created_on) %> <td align="center"><%= format_date(project.created_on) %>
</tr> </tr>
<% end %> <% end %>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<li> <li>
<b><%= link_to d.title, :controller => 'documents', :action => 'show', :id => d %></b> <b><%= link_to d.title, :controller => 'documents', :action => 'show', :id => d %></b>
<br /> <br />
<%=_('Desciption')%>: <%= d.descr %><br /> <%=_('Desciption')%>: <%= d.description %><br />
<%= format_time(d.created_on) %> <%= format_time(d.created_on) %>
</li> </li>
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
<td><small><%=_('Tracker')%>:</small><br /><%= search_filter_tag 'tracker_id', :class => 'select-small' %></td> <td><small><%=_('Tracker')%>:</small><br /><%= search_filter_tag 'tracker_id', :class => 'select-small' %></td>
<td><small><%=_('Priority')%>:</small><br /><%= search_filter_tag 'priority_id', :class => 'select-small' %></td> <td><small><%=_('Priority')%>:</small><br /><%= search_filter_tag 'priority_id', :class => 'select-small' %></td>
<td><small><%=_('Category')%>:</small><br /><%= search_filter_tag 'category_id', :class => 'select-small' %></td> <td><small><%=_('Category')%>:</small><br /><%= search_filter_tag 'category_id', :class => 'select-small' %></td>
<td><small><%=_('Fixed in version')%>:</small><br /><%= search_filter_tag 'fixed_version_id', :class => 'select-small' %></td>
<td><small><%=_('Assigned to')%>:</small><br /><%= search_filter_tag 'assigned_to_id', :class => 'select-small' %></td> <td><small><%=_('Assigned to')%>:</small><br /><%= search_filter_tag 'assigned_to_id', :class => 'select-small' %></td>
<td><small><%=_('Subprojects')%>:</small><br /><%= search_filter_tag 'subproject_id', :class => 'select-small' %></td> <td><small><%=_('Subprojects')%>:</small><br /><%= search_filter_tag 'subproject_id', :class => 'select-small' %></td>
...@@ -52,9 +53,4 @@ ...@@ -52,9 +53,4 @@
<p> <p>
<%= pagination_links_full @issue_pages %> <%= pagination_links_full @issue_pages %>
[ <%= @issue_pages.current.first_item %> - <%= @issue_pages.current.last_item %> / <%= @issue_count %> ] [ <%= @issue_pages.current.first_item %> - <%= @issue_pages.current.last_item %> / <%= @issue_count %> ]
</p> </p>
\ No newline at end of file
<p>
<%= link_to_if_authorized '&#187; ' + _('Report an issue'), :controller => 'projects', :action => 'add_issue', :id => @project %>
</p>
\ No newline at end of file
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<%= link_to_if_authorized image_tag('edit_small'), :controller => 'news', :action => 'edit', :id => news %> <%= link_to_if_authorized image_tag('edit_small'), :controller => 'news', :action => 'edit', :id => news %>
<%= link_to_if_authorized image_tag('delete'), { :controller => 'news', :action => 'destroy', :id => news }, :confirm => 'Are you sure?' %> <%= link_to_if_authorized image_tag('delete'), { :controller => 'news', :action => 'destroy', :id => news }, :confirm => 'Are you sure?' %>
<br /> <br />
<%= news.shortdescr %> <%= news.summary %>
<small>[<%= link_to _('Read...'), :controller => 'news', :action => 'show', :id => news %>]</small> <small>[<%= link_to _('Read...'), :controller => 'news', :action => 'show', :id => news %>]</small>
</p> </p>
<% end %> <% end %>
......
<h2><%=_('Settings')%></h2> <h2><%=_('Settings')%></h2>
<div class="box">
<%= start_form_tag :action => 'edit', :id => @project %> <%= start_form_tag :action => 'edit', :id => @project %>
<%= render :partial => 'form' %> <%= render :partial => 'form' %>
<center><%= submit_tag _('Save') %></center> <center><%= submit_tag _('Save') %></center>
<%= end_form_tag %> <%= end_form_tag %>
</div>
&nbsp;
<div class="box"> <div class="box">
<h3><%=_('Members')%></h3> <h3><%=_('Members')%></h3>
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
<% for version in @project.versions %> <% for version in @project.versions %>
<tr> <tr>
<td><%= link_to version.name, :controller => 'versions', :action => 'edit', :id => version %></td> <td><%= link_to version.name, :controller => 'versions', :action => 'edit', :id => version %></td>
<td><%=h version.descr %></td> <td><%=h version.description %></td>
<td> <td>
<%= start_form_tag :controller => 'versions', :action => 'destroy', :id => version %> <%= start_form_tag :controller => 'versions', :action => 'destroy', :id => version %>
<%= submit_tag _('Delete'), :class => "button-small" %> <%= submit_tag _('Delete'), :class => "button-small" %>
......
<h2><%=_('Overview')%></h2> <h2><%=_('Overview')%></h2>
<div class="splitcontentleft"> <div class="splitcontentleft">
<%= @project.descr %> <%= @project.description %>
<ul> <ul>
<li><%=_('Homepage')%>: <%= link_to @project.homepage, @project.homepage %></li> <li><%=_('Homepage')%>: <%= link_to @project.homepage, @project.homepage %></li>
<li><%=_('Created on')%>: <%= format_date(@project.created_on) %></li> <li><%=_('Created on')%>: <%= format_date(@project.created_on) %></li>
<% for custom_value in @custom_values %>
<% if !custom_value.value.empty? %>
<li><%= custom_value.custom_field.name%>: <%= custom_value.value%></li>
<% end %>
<% end %>
</ul> </ul>
<div class="box"> <div class="box">
<h3><%= image_tag "tracker" %> <%=_('Trackers')%></h3> <h3><%= image_tag "tracker" %> <%=_('Trackers')%></h3>
<ul> <ul>
<% for tracker in Tracker.find_all %> <% for tracker in @trackers %>
<li><%= link_to tracker.name, :controller => 'projects', :action => 'list_issues', :id => @project, <li><%= link_to tracker.name, :controller => 'projects', :action => 'list_issues', :id => @project,
:set_filter => 1, :set_filter => 1,
"tracker_id" => tracker.id %>: "tracker_id" => tracker.id %>:
...@@ -18,8 +23,14 @@ ...@@ -18,8 +23,14 @@
</li> </li>
<% end %> <% end %>
</ul> </ul>
<%= link_to_if_authorized '&#187; ' + _('Report an issue'), :controller => 'projects', :action => 'add_issue', :id => @project %> <% if authorize_for 'projects', 'add_issue' %>
<br /> &#187; <%=_('Report an issue')%>:
<ul>
<% @trackers.each do |tracker| %>
<li><%= link_to _(tracker.name), :controller => 'projects', :action => 'add_issue', :id => @project, :tracker_id => tracker %></li>
<% end %>
</ul>
<% end %>
<center><small>[ <%= link_to _('View all issues'), :controller => 'projects', :action => 'list_issues', :id => @project, :set_filter => 1 %> ]</small></center> <center><small>[ <%= link_to _('View all issues'), :controller => 'projects', :action => 'list_issues', :id => @project, :set_filter => 1 %> ]</small></center>
</div> </div>
</div> </div>
...@@ -46,7 +57,7 @@ ...@@ -46,7 +57,7 @@
<% for news in @news %> <% for news in @news %>
<p> <p>
<b><%= news.title %></b> <small>(<%= link_to_user news.author %> <%= format_time(news.created_on) %>)</small><br /> <b><%= news.title %></b> <small>(<%= link_to_user news.author %> <%= format_time(news.created_on) %>)</small><br />
<%= news.shortdescr %> <%= news.summary %>
<small>[<%= link_to _('Read...'), :controller => 'news', :action => 'show', :id => news %>]</small> <small>[<%= link_to _('Read...'), :controller => 'news', :action => 'show', :id => news %>]</small>
</p> </p>
<hr /> <hr />
......
<%= error_messages_for 'role' %> <%= error_messages_for 'role' %>
<div class="box">
<!--[form:role]--> <!--[form:role]-->
<p><label for="role_name"><%=_('Name')%> <span class="required">*</span></label><br /> <p><label for="role_name"><%=_('Name')%> <span class="required">*</span></label><br />
<%= text_field 'role', 'name' %></p> <%= text_field 'role', 'name' %></p>
...@@ -10,7 +11,7 @@ ...@@ -10,7 +11,7 @@
<fieldset><legend><%= _(Permission::GROUPS[group_id]) %></legend> <fieldset><legend><%= _(Permission::GROUPS[group_id]) %></legend>
<% permissions[group_id].each do |p| %> <% permissions[group_id].each do |p| %>
<div style="width:200px;float:left;"><%= check_box_tag "permission_ids[]", p.id, (@role.permissions.include? p) %> <div style="width:200px;float:left;"><%= check_box_tag "permission_ids[]", p.id, (@role.permissions.include? p) %>
<%= _(p.descr) %> <%= _(p.description) %>
</div> </div>
<% end %> <% end %>
</fieldset> </fieldset>
...@@ -19,4 +20,4 @@ ...@@ -19,4 +20,4 @@
<a href="javascript:checkAll('role_form', true)"><%=_('Check all')%></a> | <a href="javascript:checkAll('role_form', true)"><%=_('Check all')%></a> |
<a href="javascript:checkAll('role_form', false)"><%=_('Uncheck all')%></a><br /> <a href="javascript:checkAll('role_form', false)"><%=_('Uncheck all')%></a><br />
<!--[eoform:role]--> <!--[eoform:role]-->
</div>
<%= error_messages_for 'tracker' %> <%= error_messages_for 'tracker' %>
<!--[form:tracker]--> <!--[form:tracker]-->
<p><label for="tracker_name"><%=_('Name')%></label><br/> <p><label for="tracker_name"><%=_('Name')%></label> <span class="required">*</span><br/>
<%= text_field 'tracker', 'name' %></p> <%= text_field 'tracker', 'name' %></p>
<p><%= check_box 'tracker', 'is_in_chlog' %> <p><%= check_box 'tracker', 'is_in_chlog' %>
......
<%= error_messages_for 'user' %> <%= error_messages_for 'user' %>
<div class="box">
<!--[form:user]--> <!--[form:user]-->
<p><label for="user_login"><%=_('Login')%></label><br/> <p><label for="user_login"><%=_('Login')%></label> <span class="required">*</span><br/>
<%= text_field 'user', 'login', :size => 25 %></p> <%= text_field 'user', 'login', :size => 25 %></p>
<p><label for="password"><%=_('Password')%></label><br/> <p><label for="password"><%=_('Password')%></label> <span class="required">*</span><br/>
<%= password_field_tag 'password', nil, :size => 25 %></p> <%= password_field_tag 'password', nil, :size => 25 %></p>
<p><label for="password_confirmation"><%=_('Confirmation')%></label><br/> <p><label for="password_confirmation"><%=_('Confirmation')%></label> <span class="required">*</span><br/>
<%= password_field_tag 'password_confirmation', nil, :size => 25 %></p> <%= password_field_tag 'password_confirmation', nil, :size => 25 %></p>
<p><label for="user_firstname"><%=_('Firstname')%></label><br/> <p><label for="user_firstname"><%=_('Firstname')%></label> <span class="required">*</span><br/>
<%= text_field 'user', 'firstname' %></p> <%= text_field 'user', 'firstname' %></p>
<p><label for="user_lastname"><%=_('Lastname')%></label><br/> <p><label for="user_lastname"><%=_('Lastname')%></label> <span class="required">*</span><br/>
<%= text_field 'user', 'lastname' %></p> <%= text_field 'user', 'lastname' %></p>
<p><label for="user_mail"><%=_('Mail')%></label><br/> <p><label for="user_mail"><%=_('Mail')%></label> <span class="required">*</span><br/>
<%= text_field 'user', 'mail' %></p> <%= text_field 'user', 'mail' %></p>
<p><label for="user_language"><%=_('Language')%></label><br/> <p><label for="user_language"><%=_('Language')%></label><br/>
<%= select("user", "language", Localization.langs) %></p> <%= select("user", "language", Localization.langs.invert) %></p>
<% for custom_value in @custom_values %>
<p><%= custom_field_tag_with_label custom_value %></p>
<% end %>
<div style="clear: both;"></div>
<p><%= check_box 'user', 'admin' %> <label for="user_admin"><%=_('Administrator')%></label></p> <p><%= check_box 'user', 'admin' %> <label for="user_admin"><%=_('Administrator')%></label></p>
<p><%= check_box 'user', 'mail_notification' %> <label for="user_mail_notification"><%=_('Mail notifications')%></label></p> <p><%= check_box 'user', 'mail_notification' %> <label for="user_mail_notification"><%=_('Mail notifications')%></label></p>
<p><%= check_box 'user', 'locked' %> <label for="user_locked"><%=_('Locked')%></label></p>
<!--[eoform:user]--> <!--[eoform:user]-->
</div>
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<%= sort_header_tag('lastname', :caption => _('Lastname')) %> <%= sort_header_tag('lastname', :caption => _('Lastname')) %>
<th><%=_('Mail')%></th> <th><%=_('Mail')%></th>
<%= sort_header_tag('admin', :caption => _('Admin')) %> <%= sort_header_tag('admin', :caption => _('Admin')) %>
<%= sort_header_tag('locked', :caption => _('Locked')) %> <%= sort_header_tag('status', :caption => _('Status')) %>
<%= sort_header_tag('created_on', :caption => _('Created on')) %> <%= sort_header_tag('created_on', :caption => _('Created on')) %>
<%= sort_header_tag('last_login_on', :caption => _('Last login')) %> <%= sort_header_tag('last_login_on', :caption => _('Last login')) %>
<th></th> <th></th>
...@@ -25,10 +25,10 @@ ...@@ -25,10 +25,10 @@
<td align="center"> <td align="center">
<%= start_form_tag :action => 'edit', :id => user %> <%= start_form_tag :action => 'edit', :id => user %>
<% if user.locked? %> <% if user.locked? %>
<%= hidden_field_tag 'user[locked]', 0 %> <%= hidden_field_tag 'user[status]', User::STATUS_ACTIVE %>
<%= submit_tag _('Unlock'), :class => "button-small" %> <%= submit_tag _('Unlock'), :class => "button-small" %>
<% else %> <% else %>
<%= hidden_field_tag 'user[locked]', 1 %> <%= hidden_field_tag 'user[status]', User::STATUS_LOCKED %>
<%= submit_tag _('Lock'), :class => "button-small" %> <%= submit_tag _('Lock'), :class => "button-small" %>
<% end %> <% end %>
<%= end_form_tag %> <%= end_form_tag %>
......
...@@ -4,8 +4,8 @@ ...@@ -4,8 +4,8 @@
<p><label for="version_name"><%=_('Version')%></label> <span class="required">*</span><br/> <p><label for="version_name"><%=_('Version')%></label> <span class="required">*</span><br/>
<%= text_field 'version', 'name', :size => 20 %></p> <%= text_field 'version', 'name', :size => 20 %></p>
<p><label for="version_descr"><%=_('Description')%></label><br/> <p><label for="version_description"><%=_('Description')%></label><br/>
<%= text_field 'version', 'descr', :size => 60 %></p> <%= text_field 'version', 'description', :size => 60 %></p>
<p><label for="version_effective_date"><%=_('Date')%></label><br/> <p><label for="version_effective_date"><%=_('Date')%></label><br/>
<%= date_select 'version', 'effective_date' %></p> <%= date_select 'version', 'effective_date' %></p>
......
<div class="splitcontentleft"> <div class="splitcontentleft">
<h2><%=_('Welcome')%> !</h2> <h2><%= $RDM_WELCOME_TITLE || _('Welcome') %> !</h2>
<p><%= $RDM_WELCOME_TEXT %></p>
<div class="box"> <div class="box">
<h3><%=_('Latest news')%></h3> <h3><%=_('Latest news')%></h3>
<% for news in @news %> <% for news in @news %>
<p> <p>
<b><%= news.title %></b> (<%= link_to_user news.author %> <%= format_time(news.created_on) %> - <%= news.project.name %>)<br /> <b><%= news.title %></b> (<%= link_to_user news.author %> <%= format_time(news.created_on) %> - <%= news.project.name %>)<br />
<%= news.shortdescr %><br /> <%= news.summary %><br />
[<%= link_to 'Read...', :controller => 'news', :action => 'show', :id => news %>] [<%= link_to 'Read...', :controller => 'news', :action => 'show', :id => news %>]
</p> </p>
<hr /> <hr />
...@@ -21,7 +22,7 @@ ...@@ -21,7 +22,7 @@
<% for project in @projects %> <% for project in @projects %>
<li> <li>
<%= link_to project.name, :controller => 'projects', :action => 'show', :id => project %> (added <%= format_time(project.created_on) %>)<br /> <%= link_to project.name, :controller => 'projects', :action => 'show', :id => project %> (added <%= format_time(project.created_on) %>)<br />
<%= project.descr %> <%= project.description %>
</li> </li>
<% end %> <% end %>
</ul> </ul>
......
# redMine - project management software
# Copyright (C) 2006 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# To set your own configuration, rename this file to config_custom.rb
# and edit parameters below
# Don't forget to restart the application after any change.
# Application host name
# Used to provide absolute links in mail notifications
# $RDM_HOST_NAME = "somenet.foo"
# File storage path
# Directory used to store uploaded files
# #{RAILS_ROOT} represents application's home directory
# $RDM_STORAGE_PATH = "#{RAILS_ROOT}/files"
# Set $RDM_LOGIN_REQUIRED to true if you want to force users to login
# to access any page of the application
# $RDM_LOGIN_REQUIRED = false
# Uncomment to disable user self-registration
# $RDM_SELF_REGISTRATION = false
# Default langage ('en', 'es', 'fr' are available)
# $RDM_DEFAULT_LANG = 'en'
# Page title
# $RDM_HEADER_TITLE = "Title"
# Page sub-title
# $RDM_HEADER_SUBTITLE = "Sub title"
# Welcome page title
# $RDM_WELCOME_TITLE = "Welcome"
# Welcome page text
# $RDM_WELCOME_TEXT = ""
# Signature displayed in footer
# Email adresses will be automatically displayed as a mailto link
# $RDM_FOOTER_SIG = "admin@somenet.foo"
...@@ -68,18 +68,67 @@ end ...@@ -68,18 +68,67 @@ end
# inflect.uncountable %w( fish sheep ) # inflect.uncountable %w( fish sheep )
# end # end
# Include your application configuration below if File.exist? File.join(File.dirname(__FILE__), 'config_custom.rb')
begin
# application name print "=> Loading config_custom.rb... "
RDM_APP_NAME = "redMine" require File.join(File.dirname(__FILE__), 'config_custom')
# application version puts "done."
RDM_APP_VERSION = "0.2.0" rescue Exception => detail
puts
puts detail
puts detail.backtrace.join("\n")
puts "=> Error in config_custom.rb. Check your configuration."
exit
end
end
# IMPORTANT !!! DO NOT MODIFY PARAMETERS HERE
# Instead, rename config_custom.example.rb to config_custom.rb
# and set your own configuration in that file
# Parameters defined in config_custom.rb override those defined below
# application host name # application host name
RDM_HOST_NAME = "somenet.foo" $RDM_HOST_NAME ||= "localhost:3000"
# file storage path # file storage path
RDM_STORAGE_PATH = "#{RAILS_ROOT}/files" $RDM_STORAGE_PATH ||= "#{RAILS_ROOT}/files"
# if RDM_LOGIN_REQUIRED is set to true, login is required to access the application # if RDM_LOGIN_REQUIRED is set to true, login is required to access the application
RDM_LOGIN_REQUIRED = false $RDM_LOGIN_REQUIRED ||= false
# default langage # default langage
RDM_DEFAULT_LANG = 'en' $RDM_DEFAULT_LANG ||= 'en'
# page title
$RDM_HEADER_TITLE ||= "redMine"
# page sub-title
$RDM_HEADER_SUBTITLE ||= "Project management"
# footer signature
$RDM_FOOTER_SIG = "admin@somenet.foo"
# application name
RDM_APP_NAME = "redMine"
# application version
RDM_APP_VERSION = "0.3.0"
ActiveRecord::Errors.default_error_messages = {
:inclusion => "activerecord_error_inclusion",
:exclusion => "activerecord_error_exclusion",
:invalid => "activerecord_error_invalid",
:confirmation => "activerecord_error_confirmation",
:accepted => "activerecord_error_accepted",
:empty => "activerecord_error_empty",
:blank => "activerecord_error_blank",
:too_long => "activerecord_error_too_long",
:too_short => "activerecord_error_too_short",
:wrong_length => "activerecord_error_wrong_length",
:taken => "activerecord_error_taken",
:not_a_number => "activerecord_error_not_a_number"
}
ActionView::Base.field_error_proc = Proc.new{ |html_tag, instance| "<span class=\"fieldWithErrors\">#{html_tag}</span>" }
GLoc.set_config :default_language => $RDM_DEFAULT_LANG
GLoc.clear_strings
GLoc.set_kcode
GLoc.load_localized_strings
GLoc.set_config(:raise_string_not_found_errors => false)
...@@ -13,3 +13,4 @@ config.whiny_nils = true ...@@ -13,3 +13,4 @@ config.whiny_nils = true
config.action_controller.consider_all_requests_local = true config.action_controller.consider_all_requests_local = true
config.action_controller.perform_caching = false config.action_controller.perform_caching = false
config.action_mailer.delivery_method = :test
...@@ -5,6 +5,34 @@ Copyright (C) 2006 Jean-Philippe Lang ...@@ -5,6 +5,34 @@ Copyright (C) 2006 Jean-Philippe Lang
http://redmine.org/ http://redmine.org/
== xx/xx/2006 v0.3.0
* user authentication against multiple LDAP
* token based "lost password" functionality
* user self-registration functionality (optional)
* custom fields now available for issues, users and projects
* new custom field format "text" (textarea)
* project & administration drop down menus in navigation bar
* error messages internationalization
* Localization plugin replaced with GLoc 1.1.0
* new filter in issues list: "Fixed version"
* colored background for active filters on issues list
* custom configuration is now defined in config/config_custom.rb
* user object no more stored in session (only user_id)
* news summary field is no longer required
* Fixed: boolean custom field not working
* Fixed: error messages for custom fields are not displayed
* Fixed: custom fields values are not validated on issue update
* Fixed: user unable to choose an empty value for 'List' custom fields
* Fixed: no issue categories sorting
* Fixed: incorrect versions sorting
== 07/12/2006 - v0.2.2
* Fixed: bug in "issues list"
== 07/09/2006 - v0.2.1 == 07/09/2006 - v0.2.1
* new databases supported: Oracle, PostgreSQL, SQL Server * new databases supported: Oracle, PostgreSQL, SQL Server
......
...@@ -49,21 +49,11 @@ Supported databases: ...@@ -49,21 +49,11 @@ Supported databases:
== Configuration == Configuration
You can setup a few things in config/environment.rb: A sample configuration file is provided: "config/config_custom.example.rb"
Rename it to config_custom.rb and edit parameters.
Don't forget to restart the application after any change. Don't forget to restart the application after any change.
config.action_mailer.server_settings: SMTP server configuration config.action_mailer.server_settings: SMTP server configuration
config.action_mailer.perform_deliveries: set to false to disable mail delivering config.action_mailer.perform_deliveries: set to false to disable mail delivering
RDM_HOST_NAME: hostname used to provide urls in notification mails
RDM_STORAGE_PATH: path for all attachments storage (default: "#{RAILS_ROOT}/files")
"#{RAILS_ROOT}/" represents application main directory
RDM_LOGIN_REQUIRED: set to true if you want to force users to login to access
any part of the application (default: false)
RDM_DEFAULT_LANG: default language for anonymous users: 'en' (default), 'es', 'fr' available
_gloc_rule_default: '|n| n==1 ? "" : "_plural" '
actionview_datehelper_select_day_prefix:
actionview_datehelper_select_month_names: January,February,March,April,May,June,July,August,September,October,November,December
actionview_datehelper_select_month_names_abbr: Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
actionview_datehelper_select_month_prefix:
actionview_datehelper_select_year_prefix:
actionview_datehelper_time_in_words_day: 1 day
actionview_datehelper_time_in_words_day_plural: %d days
actionview_datehelper_time_in_words_hour_about: about an hour
actionview_datehelper_time_in_words_hour_about_plural: about %d hours
actionview_datehelper_time_in_words_hour_about_single: about an hour
actionview_datehelper_time_in_words_minute: 1 minute
actionview_datehelper_time_in_words_minute_half: half a minute
actionview_datehelper_time_in_words_minute_less_than: less than a minute
actionview_datehelper_time_in_words_minute_plural: %d minutes
actionview_datehelper_time_in_words_minute_single: 1 minute
actionview_datehelper_time_in_words_second_less_than: less than a second
actionview_datehelper_time_in_words_second_less_than_plural: less than %d seconds
actionview_instancetag_blank_option: Please select
activerecord_error_inclusion: is not included in the list
activerecord_error_exclusion: is reserved
activerecord_error_invalid: is invalid
activerecord_error_confirmation: doesn't match confirmation
activerecord_error_accepted: must be accepted
activerecord_error_empty: can't be empty
activerecord_error_blank: can't be blank
activerecord_error_too_long: is too long
activerecord_error_too_short: is too short
activerecord_error_wrong_length: is the wrong length
activerecord_error_taken: has already been taken
activerecord_error_not_a_number: is not a number
general_fmt_age: %d yr
general_fmt_age_plural: %d yrs
general_fmt_date: %%b %%d, %%Y (%%a)
general_fmt_datetime: %%b %%d, %%Y (%%a), %%I:%%M %%p
general_fmt_datetime_short: %%b %%d, %%I:%%M %%p
general_fmt_time: %%I:%%M %%p
general_text_No: 'No'
general_text_Yes: 'Yes'
general_text_no: 'no'
general_text_yes: 'yes'
notice_account_updated: Account was successfully updated.
notice_account_invalid_creditentials: Invalid user or password
notice_account_password_updated: Password was successfully updated.
notice_account_wrong_password: Wrong password
notice_account_register_done: Account was successfully created.
notice_account_unknown_email: Unknown user.
notice_account_lost_email_sent: An email with instructions to choose a new password has been sent to you.
gui_menu_home: Home
gui_menu_my_page: My page
gui_menu_projects: Projects
gui_menu_my_account: My account
gui_menu_admin: Administration
gui_menu_login: Login
gui_menu_logout: Logout
gui_menu_help: Help
gui_validation_error: 1 error
gui_validation_error_plural: %d errors
field_name: Name
field_description: Description
field_summary: Summary
field_is_required: Required
field_firstname: Firstname
field_lastname: Lastname
field_mail: Email
field_filename: File
field_filesize: Size
field_downloads: Downloads
field_author: Author
field_created_on: Created
field_updated_on: Updated
field_field_format: Format
field_is_for_all: For all projects
field_possible_values: Possible values
field_regexp: Regular expression
field_min_length: Minimum length
field_max_length: Maximum length
field_value: Value
field_category: Catogory
field_title: Title
field_project: Project
field_issue: Issue
field_status: Status
field_notes: Notes
field_is_closed: Issue closed
field_is_default: Default status
field_html_color: Color
field_tracker: Tracker
field_subject: Subject
field_assigned_to: Assigned to
field_priority: Priority
field_fixed_version: Fixed version
field_user: User
field_role: Role
field_homepage: Homepage
field_is_public: Public
field_parent: Subproject de
field_is_in_chlog: Issues displayed in changelog
field_login: Login
field_mail_notification: Mail notifications
field_admin: Administrator
field_locked: Locked
field_last_login_on: Last connection
field_language: Language
field_effective_date: Date
field_password: Password
field_password_confirmation: Confirmation
\ No newline at end of file
Localization.define('en', 'English') do |l| Localization.define('en', 'English') do |l|
l.store '(date)', lambda { |t| t.strftime('%m/%d/%Y') } l.store '(date)', lambda { |t| t.strftime('%m/%d/%Y') }
l.store '(time)', lambda { |t| t.strftime('%m/%d/%Y %I:%M%p') } l.store '(time)', lambda { |t| t.strftime('%m/%d/%Y %I:%M%p') }
l.store '%d errors', ['1 error', '%d errors']
end end
\ No newline at end of file
_gloc_rule_default: '|n| n==1 ? "" : "_plural" '
actionview_datehelper_select_day_prefix:
actionview_datehelper_select_month_names: Janvier,Février,Mars,Avril,Mai,Juin,Juillet,Août,Septembre,Octobre,Novembre,Décembre
actionview_datehelper_select_month_names_abbr: Jan,Fév,Mars,Avril,Mai,Juin,Juil,Août,Sept,Oct,Nov,Déc
actionview_datehelper_select_month_prefix:
actionview_datehelper_select_year_prefix:
actionview_datehelper_time_in_words_day: 1 jour
actionview_datehelper_time_in_words_day_plural: %d jours
actionview_datehelper_time_in_words_hour_about: about an hour
actionview_datehelper_time_in_words_hour_about_plural: about %d hours
actionview_datehelper_time_in_words_hour_about_single: about an hour
actionview_datehelper_time_in_words_minute: 1 minute
actionview_datehelper_time_in_words_minute_half: 30 secondes
actionview_datehelper_time_in_words_minute_less_than: moins d'une minute
actionview_datehelper_time_in_words_minute_plural: %d minutes
actionview_datehelper_time_in_words_minute_single: 1 minute
actionview_datehelper_time_in_words_second_less_than: moins d'une seconde
actionview_datehelper_time_in_words_second_less_than_plural: moins de %d secondes
actionview_instancetag_blank_option: Choisir
activerecord_error_inclusion: n'est pas inclus dans la liste
activerecord_error_exclusion: est reservé
activerecord_error_invalid: est invalide
activerecord_error_confirmation: ne correspond pas à la confirmation
activerecord_error_accepted: doit être accepté
activerecord_error_empty: doit être renseigné
activerecord_error_blank: doit être renseigné
activerecord_error_too_long: est trop long
activerecord_error_too_short: est trop court
activerecord_error_wrong_length: n'est pas de la bonne longueur
activerecord_error_taken: est déjà utilisé
activerecord_error_not_a_number: n'est pas un nombre
general_fmt_age: %d an
general_fmt_age_plural: %d ans
general_fmt_date: %%d/%%m/%%Y
general_fmt_datetime: %%d/%%m/%%Y %%H:%%M
general_fmt_datetime_short: %%d/%%m %%H:%%M
general_fmt_time: %%H:%%M
general_text_No: 'Non'
general_text_Yes: 'Oui'
general_text_no: 'non'
general_text_yes: 'oui'
notice_account_updated: Le compte a été mis à jour avec succès.
notice_account_invalid_creditentials: Identifiant ou mot de passe invalide.
notice_account_password_updated: Mot de passe mis à jour avec succès.
notice_account_wrong_password: Mot de passe incorrect
notice_account_register_done: Un message contenant les instructions pour activer votre compte vous a été envoyé.
notice_account_unknown_email: Aucun compte ne correspond à cette adresse.
notice_account_lost_email_sent: Un message contenant les instructions pour choisir un nouveau mot de passe vous a été envoyé.
notice_account_activated: Votre compte a été activé. Vous pouvez à présent vous connecter.
notice_successful_update: Mise à jour effectuée avec succès.
notice_successful_create: Création effectuée avec succès.
notice_successful_delete: Suppression effectuée avec succès.
notice_successful_connection: Connection réussie.
gui_validation_error: 1 erreur
gui_validation_error_plural: %d erreurs
field_name: Nom
field_description: Description
field_summary: Résumé
field_is_required: Obligatoire
field_firstname: Prénom
field_lastname: Nom
field_mail: Email
field_filename: Fichier
field_filesize: Taille
field_downloads: Téléchargements
field_author: Auteur
field_created_on: Créé
field_updated_on: Mis à jour
field_field_format: Format
field_is_for_all: Pour tous les projets
field_possible_values: Valeurs possibles
field_regexp: Expression régulière
field_min_length: Longueur minimum
field_max_length: Longueur maximum
field_value: Valeur
field_category: Catégorie
field_title: Titre
field_project: Projet
field_issue: Demande
field_status: Statut
field_notes: Notes
field_is_closed: Demande fermée
field_is_default: Statut par défaut
field_html_color: Couleur
field_tracker: Tracker
field_subject: Sujet
field_assigned_to: Assigné à
field_priority: Priorité
field_fixed_version: Version corrigée
field_user: Utilisateur
field_role: Rôle
field_homepage: Site web
field_is_public: Public
field_parent: Sous-projet de
field_is_in_chlog: Demandes affichées dans l'historique
field_login: Identifiant
field_mail_notification: Notifications par mail
field_admin: Administrateur
field_locked: Verrouillé
field_last_login_on: Dernière connexion
field_language: Langue
field_effective_date: Date
field_password: Mot de passe
field_new_password: Nouveau mot de passe
field_password_confirmation: Confirmation
field_version: Version
field_type: Type
field_host: Hôte
field_port: Port
field_account: Compte
field_base_dn: Base DN
field_attr_login: Attribut Identifiant
field_attr_firstname: Attribut Prénom
field_attr_lastname: Attribut Nom
field_attr_mail: Attribut Email
field_onthefly: Création des utilisateurs à la volée
label_user: Utilisateur
label_user_plural: Utilisateurs
label_user_new: Nouvel utilisateur
label_project: Projet
label_project_new: Nouveau projet
label_project_plural: Projets
label_issue: Demande
label_issue_new: Nouvelle demande
label_issue_plural: Demandes
label_role: Rôle
label_role_plural: Rôles
label_role_add: Nouveau rôle
label_role_and_permissions: Rôles et permissions
label_tracker: Tracker
label_tracker_plural: Trackers
label_tracker_add: Nouveau tracker
label_workflow: Workflow
label_issue_status: Statut de demandes
label_issue_status_plural: Statuts de demandes
label_issue_status_add: Nouveau statut
label_custom_field: Champ personnalisé
label_custom_field_plural: Champs personnalisés
label_custom_field_new: Nouveau champ personnalisé
label_enumerations: Listes de valeurs
label_information: Information
label_information_plural: Informations
label_please_login: Identification
label_register: S'enregistrer
label_password_lost: Mot de passe perdu
label_home: Accueil
label_my_page: Ma page
label_my_account: Mon compte
label_administration: Administration
label_login: Connexion
label_logout: Déconnexion
label_help: Aide
label_reported_issues: Demandes soumises
label_assigned_to_me_issues: Demandes qui me sont assignées
label_last_login: Dernière connexion
label_last_updates: Dernière mise à jour
label_last_updates_plural: %d dernières mises à jour
label_registered_on: Inscrit le
label_activity: Activité
label_new: Nouveau
label_logged_as: Connecté en tant que
label_environment: Environnement
label_authentication: Authentification
label_auth_source: Mode d'authentification
label_auth_source_new: Nouveau mode d'authentification
label_auth_source_plural: Modes d'authentification
label_subproject: Sous-projet
label_subproject_plural: Sous-projets
label_min_max_length: Longueurs mini - maxi
label_list: Liste
label_date: Date
label_integer: Entier
label_boolean: Booléen
label_string: Chaîne
label_text: Texte
label_attribute: Attribut
label_attribute_plural: Attributs
button_login: Connexion
button_submit: Soumettre
button_save: Valider
button_check_all: Tout cocher
button_uncheck_all: Tout décocher
button_delete: Supprimer
button_create: Créer
button_test: Tester
text_select_mail_notifications: Sélectionner les actions pour lesquelles la notification par mail doit être activée.
text_regexp_info: eg. ^[A-Z0-9]+$
text_min_max_length_info: 0 pour aucune restriction
text_possible_values_info: valeurs séparées par |
\ No newline at end of file
...@@ -27,12 +27,36 @@ Localization.define('fr', 'Français') do |l| ...@@ -27,12 +27,36 @@ Localization.define('fr', 'Français') do |l|
l.store 'Document categories', 'Catégories de documents' l.store 'Document categories', 'Catégories de documents'
l.store 'Uncategorized', 'Sans catégorie' l.store 'Uncategorized', 'Sans catégorie'
l.store 'User documentation', 'Documentation utilisateur' l.store 'User documentation', 'Documentation utilisateur'
l.store 'Technical documentation', 'Documentation technique' l.store 'Technical documentation', 'Documentation technique'
# custom fields formats
l.store 'String', 'Chaîne'
l.store 'Integer', 'Entier'
l.store 'Date', 'Date'
l.store 'Boolean', 'Booléen'
l.store 'List', 'Liste'
# dates # dates
l.store '(date)', lambda { |t| t.strftime('%d/%m/%Y') } l.store '(date)', lambda { |t| t.strftime('%d/%m/%Y') }
l.store '(time)', lambda { |t| t.strftime('%d/%m/%Y %H:%M') } l.store '(time)', lambda { |t| t.strftime('%d/%m/%Y %H:%M') }
# ./script/../config/../app/views/account/login.rhtml
# error messages
l.store '%d errors', ['1 erreur', '%d erreurs']
l.store "is not included in the list", "n'est pas inclus dans la liste"
l.store "is reserved", "est réservé"
l.store "is invalid", "n'est pas valide"
l.store "doesn't match confirmation", "ne correspond pas à la confirmation"
l.store "must be accepted", "doit être accepté"
l.store "can't be empty", "ne doit pas être vide"
l.store "can't be blank", "doit être renseigné"
l.store "is too long", "est trop long"
l.store "is too short", "est trop court"
l.store "is the wrong length", "n'est pas de la bonne longueur"
l.store "has already been taken", "est déjà utilisé"
l.store "is not a number", "doit être un nombre"
# notice messages
l.store 'Invalid user/password', 'Identifiant/Mot de passe invalide'
# ./script/../config/../app/views/account/my_account.rhtml # ./script/../config/../app/views/account/my_account.rhtml
l.store 'My account', 'Mon compte' l.store 'My account', 'Mon compte'
...@@ -59,6 +83,9 @@ Localization.define('fr', 'Français') do |l| ...@@ -59,6 +83,9 @@ Localization.define('fr', 'Français') do |l|
# ./script/../config/../app/views/account/login.rhtml # ./script/../config/../app/views/account/login.rhtml
l.store 'Please login', 'Identification' l.store 'Please login', 'Identification'
l.store 'Register', "S'enregistrer"
l.store 'Password lost', 'Mot de passe perdu'
l.store 'Submit', 'Soumettre'
# ./script/../config/../app/views/account/show.rhtml # ./script/../config/../app/views/account/show.rhtml
l.store 'Registered on', 'Inscrit le' l.store 'Registered on', 'Inscrit le'
...@@ -97,6 +124,7 @@ Localization.define('fr', 'Français') do |l| ...@@ -97,6 +124,7 @@ Localization.define('fr', 'Français') do |l|
# ./script/../config/../app/views/custom_fields/list.rhtml # ./script/../config/../app/views/custom_fields/list.rhtml
l.store 'Name', 'Nom' l.store 'Name', 'Nom'
l.store 'For', 'Pour'
l.store 'Type', 'Type' l.store 'Type', 'Type'
l.store 'Required', 'Obligatoire' l.store 'Required', 'Obligatoire'
l.store 'For all projects', 'Pour tous les projets' l.store 'For all projects', 'Pour tous les projets'
......
desc 'Create YAML test fixtures from data in an existing database.
Defaults to development database. Set RAILS_ENV to override.'
task :extract_fixtures => :environment do
sql = "SELECT * FROM %s"
skip_tables = ["schema_info"]
ActiveRecord::Base.establish_connection
(ActiveRecord::Base.connection.tables - skip_tables).each do |table_name|
i = "000"
File.open("#{RAILS_ROOT}/#{table_name}.yml", 'w' ) do |file|
data = ActiveRecord::Base.connection.select_all(sql % table_name)
file.write data.inject({}) { |hash, record|
# cast extracted values
ActiveRecord::Base.connection.columns(table_name).each { |col|
record[col.name] = col.type_cast(record[col.name]) if record[col.name]
}
hash["#{table_name}_#{i.succ!}"] = record
hash
}.to_yaml
end
end
end
\ No newline at end of file
This diff is collapsed.
...@@ -15,6 +15,7 @@ color:#303030; ...@@ -15,6 +15,7 @@ color:#303030;
background:#e8eaec; background:#e8eaec;
} }
a{ a{
color:#467aa7; color:#467aa7;
font-weight:bold; font-weight:bold;
...@@ -136,7 +137,6 @@ padding:20px 10px 10px 20px; ...@@ -136,7 +137,6 @@ padding:20px 10px 10px 20px;
/*position: absolute;*/ /*position: absolute;*/
margin: 0 0 0 140px; margin: 0 0 0 140px;
border-left: 1px dashed #c0c0c0; border-left: 1px dashed #c0c0c0;
} }
#content h2{ #content h2{
...@@ -180,6 +180,11 @@ form { ...@@ -180,6 +180,11 @@ form {
width:100%; width:100%;
} }
textarea {
padding:0;
margin:0;
}
input { input {
vertical-align: top; vertical-align: top;
} }
...@@ -191,7 +196,15 @@ input.button-small ...@@ -191,7 +196,15 @@ input.button-small
select.select-small select.select-small
{ {
font-size: 0.8em; border: 1px solid #7F9DB9;
padding: 1px;
font-size: 0.8em;
}
.active-filter
{
background-color: #F9FA9E;
} }
label { label {
...@@ -201,6 +214,12 @@ label { ...@@ -201,6 +214,12 @@ label {
fieldset { fieldset {
border:1px solid #7F9DB9; border:1px solid #7F9DB9;
padding: 6px;
}
legend {
color: #505050;
} }
.required { .required {
...@@ -328,4 +347,8 @@ color:#505050; ...@@ -328,4 +347,8 @@ color:#505050;
line-height:1.5em; line-height:1.5em;
} }
.login {
width: 50%;
text-align: left;
}
/*========== Drop down menu ==============*/
div.menu {
background-color: #FFFFFF;
border-style: solid;
border-width: 1px;
border-color: #7F9DB9;
position: absolute;
top: 0px;
left: 0px;
padding: 0;
visibility: hidden;
z-index: 101;
}
div.menu a.menuItem {
font-size: 10px;
font-weight: normal;
line-height: 2em;
color: #000000;
background-color: #FFFFFF;
cursor: default;
display: block;
padding: 0 1em;
margin: 0;
border: 0;
text-decoration: none;
white-space: nowrap;
}
div.menu a.menuItem:hover, div.menu a.menuItemHighlight {
background-color: #80b0da;
color: #ffffff;
}
div.menu a.menuItem span.menuItemText {}
div.menu a.menuItem span.menuItemArrow {
margin-right: -.75em;
}
.fieldWithErrors { .fieldWithErrors {
padding: 2px; padding: 2px;
margin: 0px;
background-color: red; background-color: red;
display: table; display: table;
} }
#errorExplanation { #errorExplanation {
width: 400px; width: 400px;
border: 2px solid red; border: 0;
padding: 7px; padding: 7px;
padding-bottom: 12px; padding-bottom: 3px;
margin-bottom: 20px; margin-bottom: 0px;
background-color: #f0f0f0; /*background-color: #f0f0f0;*/
} }
#errorExplanation h2 { #errorExplanation h2 {
text-align: left; text-align: left;
font-weight: bold; font-weight: bold;
padding: 5px 5px 5px 15px; padding: 5px 5px 10px 26px;
font-size: 12px; font-size: 1em;
margin: -7px; margin: -7px;
background-color: #c00; background: url(../images/alert.png) no-repeat 6px 6px;
color: #fff;
} }
#errorExplanation p { #errorExplanation p {
...@@ -31,8 +31,9 @@ ...@@ -31,8 +31,9 @@
} }
#errorExplanation ul li { #errorExplanation ul li {
font-size: 12px; font-size: 1em;
list-style: square; list-style: none;
margin-left: -16px;
} }
div.uploadStatus { div.uploadStatus {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment