Compare commits

..

1 Commits

Author SHA1 Message Date
Jean-Philippe Lang
3fa3b14afe tagged version 0.6.0
git-svn-id: http://redmine.rubyforge.org/svn/tags/0.6.0@884 e93f8b46-1217-0410-a6f0-8f06a7374b81
2007-11-04 14:05:15 +00:00
344 changed files with 1745 additions and 14671 deletions

View File

@@ -21,7 +21,7 @@ class AccountController < ApplicationController
include CustomFieldsHelper
# prevents login action to be filtered by check_if_login_required application scope filter
skip_before_filter :check_if_login_required, :only => [:login, :lost_password, :register, :activate]
skip_before_filter :check_if_login_required, :only => [:login, :lost_password, :register]
# Show user's account
def show
@@ -30,7 +30,7 @@ class AccountController < ApplicationController
# show only public projects and private projects that the logged in user is also a member of
@memberships = @user.memberships.select do |membership|
membership.project.is_public? || (User.current.member_of?(membership.project))
membership.project.is_public? || (User.current.role_for_project(membership.project))
end
rescue ActiveRecord::RecordNotFound
render_404
@@ -106,62 +106,40 @@ class AccountController < ApplicationController
# User self-registration
def register
redirect_to(home_url) && return unless Setting.self_registration?
if request.get?
@user = User.new(:language => Setting.default_language)
@custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user) }
if params[:token]
token = Token.find_by_action_and_value("register", params[:token])
redirect_to(home_url) && return unless token and !token.expired?
user = token.user
redirect_to(home_url) && 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
@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"] ? params["custom_fields"][x.id.to_s] : nil)) }
@user.custom_values = @custom_values
case Setting.self_registration
when '1'
# Email activation
if request.get?
@user = User.new(:language => Setting.default_language)
@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.deliver_register(token)
flash[:notice] = l(:notice_account_register_done)
redirect_to :action => 'login'
end
when '3'
# Automatic activation
@user.status = User::STATUS_ACTIVE
if @user.save
flash[:notice] = l(:notice_account_activated)
redirect_to :action => 'login'
end
else
# Manual activation by the administrator
if @user.save
# Sends an email to the administrators
Mailer.deliver_account_activation_request(@user)
flash[:notice] = l(:notice_account_pending)
redirect_to :action => 'login'
redirect_to :controller => 'account', :action => 'login'
end
end
end
end
# Token based account activation
def activate
redirect_to(home_url) && return unless Setting.self_registration? && params[:token]
token = Token.find_by_action_and_value('register', params[:token])
redirect_to(home_url) && return unless token and !token.expired?
user = token.user
redirect_to(home_url) && return unless user.status == User::STATUS_REGISTERED
user.status = User::STATUS_ACTIVE
if user.save
token.destroy
flash[:notice] = l(:notice_account_activated)
end
redirect_to :action => 'login'
end
private
def logged_user=(user)
if user && user.is_a?(User)

View File

@@ -48,9 +48,8 @@ class AdminController < ApplicationController
def mail_options
@notifiables = %w(issue_added issue_updated news_added document_added file_added message_posted)
if request.post?
settings = (params[:settings] || {}).dup.symbolize_keys
settings[:notified_events] ||= []
settings.each { |name, value| Setting[name] = value }
Setting.notified_events = (params[:notified_events] || [])
Setting.emails_footer = params[:emails_footer] if params[:emails_footer]
flash[:notice] = l(:notice_successful_update)
redirect_to :controller => 'admin', :action => 'mail_options'
end

View File

@@ -23,6 +23,10 @@ class ApplicationController < ActionController::Base
require_dependency "repository/#{scm.underscore}"
end
def logged_in_user
User.current.logged? ? User.current : nil
end
def current_role
@current_role ||= User.current.role_for_project(@project)
end
@@ -144,19 +148,6 @@ class ApplicationController < ActionController::Base
def accept_key_auth_actions
self.class.read_inheritable_attribute('accept_key_auth_actions') || []
end
# TODO: move to model
def attach_files(obj, files)
attachments = []
if files && files.is_a?(Array)
files.each do |file|
next unless file.size > 0
a = Attachment.create(:container => obj, :file => file, :author => User.current)
attachments << a unless a.new_record?
end
end
attachments
end
# qvalues http header parser
# code taken from webrick

View File

@@ -32,6 +32,7 @@ class BoardsController < ApplicationController
if @boards.size == 1
@board = @boards.first
show
render :action => 'show'
end
end
@@ -41,11 +42,11 @@ class BoardsController < ApplicationController
@topic_count = @board.topics.count
@topic_pages = Paginator.new self, @topic_count, 25, params['page']
@topics = @board.topics.find :all, :order => "#{Message.table_name}.sticky DESC, #{sort_clause}",
@topics = @board.topics.find :all, :order => sort_clause,
:include => [:author, {:last_reply => :author}],
:limit => @topic_pages.items_per_page,
:offset => @topic_pages.current.offset
render :action => 'show', :layout => !request.xhr?
render :action => 'show', :layout => false if request.xhr?
end
verify :method => :post, :only => [ :destroy ], :redirect_to => { :action => :index }

View File

@@ -45,7 +45,7 @@ class CustomFieldsController < ApplicationController
end
if request.post? and @custom_field.save
flash[:notice] = l(:notice_successful_create)
redirect_to :action => 'list', :tab => @custom_field.class.name
redirect_to :action => 'list', :tab => @custom_field.type
end
@trackers = Tracker.find(:all, :order => 'position')
end
@@ -57,29 +57,14 @@ class CustomFieldsController < ApplicationController
@custom_field.trackers = params[:tracker_ids] ? Tracker.find(params[:tracker_ids]) : []
end
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'list', :tab => @custom_field.class.name
redirect_to :action => 'list', :tab => @custom_field.type
end
@trackers = Tracker.find(:all, :order => 'position')
end
def move
@custom_field = CustomField.find(params[:id])
case params[:position]
when 'highest'
@custom_field.move_to_top
when 'higher'
@custom_field.move_higher
when 'lower'
@custom_field.move_lower
when 'lowest'
@custom_field.move_to_bottom
end if params[:position]
redirect_to :action => 'list', :tab => @custom_field.class.name
end
def destroy
@custom_field = CustomField.find(params[:id]).destroy
redirect_to :action => 'list', :tab => @custom_field.class.name
redirect_to :action => 'list', :tab => @custom_field.type
rescue
flash[:error] = "Unable to delete custom field"
redirect_to :action => 'list'

View File

@@ -39,14 +39,20 @@ class DocumentsController < ApplicationController
def download
@attachment = @document.attachments.find(params[:attachment_id])
@attachment.increment_download
send_file @attachment.diskfile, :filename => @attachment.filename, :type => @attachment.content_type
send_file @attachment.diskfile, :filename => @attachment.filename
rescue
render_404
end
def add_attachment
attachments = attach_files(@document, params[:attachments])
Mailer.deliver_attachments_added(attachments) if !attachments.empty? && Setting.notified_events.include?('document_added')
# Save the attachments
@attachments = []
params[:attachments].each { |file|
next unless file.size > 0
a = Attachment.create(:container => @document, :file => file, :author => logged_in_user)
@attachments << a unless a.new_record?
} if params[:attachments] and params[:attachments].is_a? Array
Mailer.deliver_attachments_added(@attachments) if !@attachments.empty? && Setting.notified_events.include?('document_added')
redirect_to :action => 'show', :id => @document
end

View File

@@ -0,0 +1,98 @@
# redMine - project management software
# Copyright (C) 2006-2007 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 FeedsController < ApplicationController
before_filter :find_scope
session :off
helper :issues
include IssuesHelper
helper :custom_fields
include CustomFieldsHelper
# news feeds
def news
News.with_scope(:find => @find_options) do
@news = News.find :all, :order => "#{News.table_name}.created_on DESC", :include => [ :author, :project ]
end
headers["Content-Type"] = "application/rss+xml"
render :action => 'news_atom' if 'atom' == params[:format]
end
# issue feeds
def issues
if @project && params[:query_id]
query = Query.find(params[:query_id])
query.executed_by = @user
# ignore query if it's not valid
query = nil unless query.valid?
# override with query conditions
@find_options[:conditions] = query.statement if query.valid? and @project == query.project
end
Issue.with_scope(:find => @find_options) do
@issues = Issue.find :all, :include => [:project, :author, :tracker, :status],
:order => "#{Issue.table_name}.created_on DESC"
end
@title = (@project ? @project.name : Setting.app_title) + ": " + (query ? query.name : l(:label_reported_issues))
headers["Content-Type"] = "application/rss+xml"
render :action => 'issues_atom' if 'atom' == params[:format]
end
# issue changes feeds
def history
if @project && params[:query_id]
query = Query.find(params[:query_id])
query.executed_by = @user
# ignore query if it's not valid
query = nil unless query.valid?
# override with query conditions
@find_options[:conditions] = query.statement if query.valid? and @project == query.project
end
Journal.with_scope(:find => @find_options) do
@journals = Journal.find :all, :include => [ :details, :user, {:issue => [:project, :author, :tracker, :status]} ],
:order => "#{Journal.table_name}.created_on DESC"
end
@title = (@project ? @project.name : Setting.app_title) + ": " + (query ? query.name : l(:label_changes_details))
headers["Content-Type"] = "application/rss+xml"
render :action => 'history_atom' if 'atom' == params[:format]
end
private
# override for feeds specific authentication
def check_if_login_required
@user = User.find_by_rss_key(params[:key])
render(:nothing => true, :status => 403) and return false if !@user && Setting.login_required?
end
def find_scope
if params[:project_id]
# project feed
# check if project is public or if the user is a member
@project = Project.find(params[:project_id])
render(:nothing => true, :status => 403) and return false unless @project.is_public? || (@user && @user.role_for_project(@project))
scope = ["#{Project.table_name}.id=?", params[:project_id].to_i]
else
# global feed
scope = ["#{Project.table_name}.is_public=?", true]
end
@find_options = {:conditions => scope, :limit => Setting.feeds_limit.to_i}
return true
end
end

View File

@@ -16,10 +16,9 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
class IssuesController < ApplicationController
layout 'base'
before_filter :find_project, :authorize, :except => [:index, :changes, :preview]
before_filter :find_optional_project, :only => [:index, :changes]
accept_key_auth :index, :changes
layout 'base', :except => :export_pdf
before_filter :find_project, :authorize, :except => [:index, :preview]
accept_key_auth :index
cache_sweeper :issue_sweeper, :only => [ :edit, :change_status, :destroy ]
@@ -38,65 +37,47 @@ class IssuesController < ApplicationController
helper :queries
helper :sort
include SortHelper
include IssuesHelper
def index
sort_init "#{Issue.table_name}.id", "desc"
sort_update
retrieve_query
if @query.valid?
limit = %w(pdf csv).include?(params[:format]) ? Setting.issues_export_limit.to_i : 25
@issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
@issue_pages = Paginator.new self, @issue_count, limit, params['page']
@issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
@issue_pages = Paginator.new self, @issue_count, 25, params['page']
@issues = Issue.find :all, :order => sort_clause,
:include => [ :assigned_to, :status, :tracker, :project, :priority, :category, :fixed_version ],
:include => [ :assigned_to, :status, :tracker, :project, :priority, :category ],
:conditions => @query.statement,
:limit => limit,
:offset => @issue_pages.current.offset
respond_to do |format|
format.html { render :template => 'issues/index.rhtml', :layout => !request.xhr? }
format.atom { render_feed(@issues, :title => l(:label_issue_plural)) }
format.csv { send_data(issues_to_csv(@issues, @project).read, :type => 'text/csv; header=present', :filename => 'export.csv') }
format.pdf { send_data(render(:template => 'issues/index.rfpdf', :layout => false), :type => 'application/pdf', :filename => 'export.pdf') }
end
else
# Send html if the query is not valid
render(:template => 'issues/index.rhtml', :layout => !request.xhr?)
:limit => @issue_pages.items_per_page,
:offset => @issue_pages.current.offset
end
end
def changes
sort_init "#{Issue.table_name}.id", "desc"
sort_update
retrieve_query
if @query.valid?
@changes = Journal.find :all, :include => [ :details, :user, {:issue => [:project, :author, :tracker, :status]} ],
:conditions => @query.statement,
:limit => 25,
:order => "#{Journal.table_name}.created_on DESC"
respond_to do |format|
format.html { render :layout => false if request.xhr? }
format.atom { render_feed(@issues, :title => l(:label_issue_plural)) }
end
@title = (@project ? @project.name : Setting.app_title) + ": " + (@query.new_record? ? l(:label_changes_details) : @query.name)
render :layout => false, :content_type => 'application/atom+xml'
end
def show
@custom_values = @issue.custom_values.find(:all, :include => :custom_field, :order => "#{CustomField.table_name}.position")
@custom_values = @issue.custom_values.find(:all, :include => :custom_field)
@journals = @issue.journals.find(:all, :include => [:user, :details], :order => "#{Journal.table_name}.created_on ASC")
@status_options = @issue.status.find_new_statuses_allowed_to(User.current.role_for_project(@project), @issue.tracker)
respond_to do |format|
format.html { render :template => 'issues/show.rhtml' }
format.pdf { send_data(render(:template => 'issues/show.rfpdf', :layout => false), :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf") }
if params[:format]=='pdf'
@options_for_rfpdf ||= {}
@options_for_rfpdf[:file_name] = "#{@project.identifier}-#{@issue.id}.pdf"
render :template => 'issues/show.rfpdf', :layout => false
else
@status_options = @issue.status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker) if logged_in_user
render :template => 'issues/show.rhtml'
end
end
def edit
@priorities = Enumeration::get_values('IPRI')
@custom_values = []
if request.get?
@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
begin
@issue.init_journal(User.current)
@issue.init_journal(self.logged_in_user)
# Retrieve custom fields and values
if params["custom_fields"]
@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]) }
@@ -116,8 +97,13 @@ class IssuesController < ApplicationController
def add_note
journal = @issue.init_journal(User.current, params[:notes])
attachments = attach_files(@issue, params[:attachments])
attachments.each {|a| journal.details << JournalDetail.new(:property => 'attachment', :prop_key => a.id, :value => a.filename)}
params[:attachments].each { |file|
next unless file.size > 0
a = Attachment.create(:container => @issue, :file => file, :author => logged_in_user)
journal.details << JournalDetail.new(:property => 'attachment',
:prop_key => a.id,
:value => a.filename) unless a.new_record?
} if params[:attachments] and params[:attachments].is_a? Array
if journal.save
flash[:notice] = l(:notice_successful_update)
Mailer.deliver_issue_edit(journal) if Setting.notified_events.include?('issue_updated')
@@ -128,18 +114,25 @@ class IssuesController < ApplicationController
end
def change_status
@status_options = @issue.status.find_new_statuses_allowed_to(User.current.role_for_project(@project), @issue.tracker)
@status_options = @issue.status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker) if logged_in_user
@new_status = IssueStatus.find(params[:new_status_id])
if params[:confirm]
begin
journal = @issue.init_journal(User.current, params[:notes])
journal = @issue.init_journal(self.logged_in_user, params[:notes])
@issue.status = @new_status
if @issue.update_attributes(params[:issue])
attachments = attach_files(@issue, params[:attachments])
attachments.each {|a| journal.details << JournalDetail.new(:property => 'attachment', :prop_key => a.id, :value => a.filename)}
# Save attachments
params[:attachments].each { |file|
next unless file.size > 0
a = Attachment.create(:container => @issue, :file => file, :author => logged_in_user)
journal.details << JournalDetail.new(:property => 'attachment',
:prop_key => a.id,
:value => a.filename) unless a.new_record?
} if params[:attachments] and params[:attachments].is_a? Array
# Log time
if current_role.allowed_to?(:log_time)
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today)
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => logged_in_user, :spent_on => Date.today)
@time_entry.attributes = params[:time_entry]
@time_entry.save
end
@@ -159,13 +152,13 @@ class IssuesController < ApplicationController
def destroy
@issue.destroy
redirect_to :action => 'index', :project_id => @project
redirect_to :controller => 'projects', :action => 'list_issues', :id => @project
end
def destroy_attachment
a = @issue.attachments.find(params[:attachment_id])
a.destroy
journal = @issue.init_journal(User.current)
journal = @issue.init_journal(self.logged_in_user)
journal.details << JournalDetail.new(:property => 'attachment',
:prop_key => a.id,
:old_value => a.filename)
@@ -183,7 +176,6 @@ class IssuesController < ApplicationController
:change_status => User.current.allowed_to?(:change_issue_status, @project),
:add => User.current.allowed_to?(:add_issues, @project),
:move => User.current.allowed_to?(:move_issues, @project),
:copy => (@project.trackers.include?(@issue.tracker) && User.current.allowed_to?(:add_issues, @project)),
:delete => User.current.allowed_to?(:delete_issues, @project)}
render :layout => false
end
@@ -203,37 +195,23 @@ private
render_404
end
def find_optional_project
return true unless params[:project_id]
@project = Project.find(params[:project_id])
authorize
rescue ActiveRecord::RecordNotFound
render_404
end
# Retrieve query from session or build a new query
def retrieve_query
if params[:query_id]
@query = Query.find(params[:query_id], :conditions => {:project_id => (@project ? @project.id : nil)})
if params[:set_filter] or !session[:query] or session[:query].project_id
# Give it a name, required to be valid
@query = Query.new(:name => "_", :executed_by => logged_in_user)
if params[:fields] and params[:fields].is_a? Array
params[:fields].each do |field|
@query.add_filter(field, params[:operators][field], params[:values][field])
end
else
@query.available_filters.keys.each do |field|
@query.add_short_filter(field, params[field]) if params[field]
end
end
session[:query] = @query
else
if params[:set_filter] or !session[:query] or session[:query].project != @project
# Give it a name, required to be valid
@query = Query.new(:name => "_")
@query.project = @project
if params[:fields] and params[:fields].is_a? Array
params[:fields].each do |field|
@query.add_filter(field, params[:operators][field], params[:values][field])
end
else
@query.available_filters.keys.each do |field|
@query.add_short_filter(field, params[field]) if params[field]
end
end
session[:query] = @query
else
@query = session[:query]
end
@query = session[:query]
end
end
end

View File

@@ -17,81 +17,44 @@
class MessagesController < ApplicationController
layout 'base'
before_filter :find_board, :only => :new
before_filter :find_message, :except => :new
before_filter :authorize
before_filter :find_project, :authorize
verify :method => :post, :only => [ :reply, :destroy ], :redirect_to => { :action => :show }
helper :attachments
include AttachmentsHelper
# Show a topic and its replies
def show
@reply = Message.new(:subject => "RE: #{@message.subject}")
render :action => "show", :layout => false if request.xhr?
end
# Create a new topic
def new
@message = Message.new(params[:message])
@message.author = User.current
@message.board = @board
if params[:message] && User.current.allowed_to?(:edit_messages, @project)
@message.locked = params[:message]['locked']
@message.sticky = params[:message]['sticky']
end
@message.author = logged_in_user
@message.board = @board
if request.post? && @message.save
attach_files(@message, params[:attachments])
params[:attachments].each { |file|
next unless file.size > 0
Attachment.create(:container => @message, :file => file, :author => logged_in_user)
} if params[:attachments] and params[:attachments].is_a? Array
redirect_to :action => 'show', :id => @message
end
end
# Reply to a topic
def reply
@reply = Message.new(params[:reply])
@reply.author = User.current
@reply.author = logged_in_user
@reply.board = @board
@topic.children << @reply
if !@reply.new_record?
attach_files(@reply, params[:attachments])
end
redirect_to :action => 'show', :id => @topic
end
# Edit a message
def edit
if params[:message] && User.current.allowed_to?(:edit_messages, @project)
@message.locked = params[:message]['locked']
@message.sticky = params[:message]['sticky']
end
if request.post? && @message.update_attributes(params[:message])
attach_files(@message, params[:attachments])
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'show', :id => @topic
end
end
# Delete a messages
def destroy
@message.destroy
redirect_to @message.parent.nil? ?
{ :controller => 'boards', :action => 'show', :project_id => @project, :id => @board } :
{ :action => 'show', :id => @message.parent }
@message.children << @reply
redirect_to :action => 'show', :id => @message
end
private
def find_message
find_board
@message = @board.messages.find(params[:id], :include => :parent)
@topic = @message.root
rescue ActiveRecord::RecordNotFound
render_404
end
def find_board
def find_project
@board = Board.find(params[:board_id], :include => :project)
@project = @board.project
@message = @board.topics.find(params[:id]) if params[:id]
rescue ActiveRecord::RecordNotFound
render_404
end

View File

@@ -44,7 +44,7 @@ class MyController < ApplicationController
# Show user's page
def page
@user = User.current
@user = self.logged_in_user
@blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT
end
@@ -56,7 +56,6 @@ class MyController < ApplicationController
@user.attributes = params[:user]
@user.mail_notification = (params[:notification_option] == 'all')
@user.pref.attributes = params[:pref]
@user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
if @user.save
@user.pref.save
@user.notified_project_ids = (params[:notification_option] == 'selected' ? params[:notified_project_ids] : [])
@@ -76,7 +75,7 @@ class MyController < ApplicationController
# Manage user's password
def password
@user = User.current
@user = self.logged_in_user
flash[:error] = l(:notice_can_t_change_password) and redirect_to :action => 'account' and return if @user.auth_source_id
if request.post?
if @user.check_password?(params[:password])
@@ -102,7 +101,7 @@ class MyController < ApplicationController
# User's page layout configuration
def page_layout
@user = User.current
@user = self.logged_in_user
@blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT.dup
session[:page_layout] = @blocks
%w(top left right).each {|f| session[:page_layout][f] ||= [] }
@@ -116,7 +115,7 @@ class MyController < ApplicationController
def add_block
block = params[:block]
render(:nothing => true) and return unless block && (BLOCKS.keys.include? block)
@user = User.current
@user = self.logged_in_user
# remove if already present in a group
%w(top left right).each {|f| (session[:page_layout][f] ||= []).delete block }
# add it on top
@@ -151,7 +150,7 @@ class MyController < ApplicationController
# Save user's page layout
def page_layout_save
@user = User.current
@user = self.logged_in_user
@user.pref[:my_page_layout] = session[:page_layout] if session[:page_layout]
@user.pref.save
session[:page_layout] = nil

View File

@@ -17,22 +17,8 @@
class NewsController < ApplicationController
layout 'base'
before_filter :find_project, :authorize, :except => :index
before_filter :find_optional_project, :only => :index
accept_key_auth :index
def index
@news_pages, @newss = paginate :news,
:per_page => 10,
:conditions => (@project ? {:project_id => @project.id} : Project.visible_by(User.current)),
:include => [:author, :project],
:order => "#{News.table_name}.created_on DESC"
respond_to do |format|
format.html { render :layout => false if request.xhr? }
format.atom { render_feed(@newss, :title => (@project ? @project.name : Setting.app_title) + ": #{l(:label_news_plural)}") }
end
end
before_filter :find_project, :authorize
def show
end
@@ -45,7 +31,7 @@ class NewsController < ApplicationController
def add_comment
@comment = Comment.new(params[:comment])
@comment.author = User.current
@comment.author = logged_in_user
if @news.comments << @comment
flash[:notice] = l(:label_comment_added)
redirect_to :action => 'show', :id => @news
@@ -61,7 +47,7 @@ class NewsController < ApplicationController
def destroy
@news.destroy
redirect_to :action => 'index', :project_id => @project
redirect_to :controller => 'projects', :action => 'list_news', :id => @project
end
private
@@ -70,13 +56,5 @@ private
@project = @news.project
rescue ActiveRecord::RecordNotFound
render_404
end
def find_optional_project
return true unless params[:project_id]
@project = Project.find(params[:project_id])
authorize
rescue ActiveRecord::RecordNotFound
render_404
end
end
end

View File

@@ -15,6 +15,8 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require 'csv'
class ProjectsController < ApplicationController
layout 'base'
before_filter :find_project, :except => [ :index, :list, :add ]
@@ -48,7 +50,7 @@ class ProjectsController < ApplicationController
# Lists visible projects
def list
projects = Project.find :all,
:conditions => Project.visible_by(User.current),
:conditions => Project.visible_by(logged_in_user),
:include => :parent
@project_tree = projects.group_by {|p| p.parent || p}
@project_tree.each_key {|p| @project_tree[p] -= [p]}
@@ -56,19 +58,15 @@ class ProjectsController < ApplicationController
# Add a new project
def add
@custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
@trackers = Tracker.all
@root_projects = Project.find(:all,
:conditions => "parent_id IS NULL AND status = #{Project::STATUS_ACTIVE}",
:order => 'name')
@custom_fields = IssueCustomField.find(:all)
@root_projects = Project.find(:all, :conditions => "parent_id IS NULL AND status = #{Project::STATUS_ACTIVE}")
@project = Project.new(params[:project])
@project.enabled_module_names = Redmine::AccessControl.available_project_modules
if request.get?
@custom_values = ProjectCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @project) }
@project.trackers = Tracker.all
@custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project) }
else
@project.custom_fields = CustomField.find(params[:custom_field_ids]) if params[:custom_field_ids]
@custom_values = ProjectCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => (params[:custom_fields] ? params["custom_fields"][x.id.to_s] : nil)) }
@custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => (params[:custom_fields] ? params["custom_fields"][x.id.to_s] : nil)) }
@project.custom_values = @custom_values
if @project.save
@project.enabled_module_names = params[:enabled_modules]
@@ -80,11 +78,11 @@ class ProjectsController < ApplicationController
# Show @project
def show
@custom_values = @project.custom_values.find(:all, :include => :custom_field, :order => "#{CustomField.table_name}.position")
@custom_values = @project.custom_values.find(:all, :include => :custom_field)
@members_by_role = @project.members.find(:all, :include => [:user, :role], :order => 'position').group_by {|m| m.role}
@subprojects = @project.active_children
@news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC")
@trackers = @project.trackers
@trackers = Tracker.find(:all, :order => 'position')
@open_issues_by_tracker = Issue.count(:group => :tracker, :joins => "INNER JOIN #{IssueStatus.table_name} ON #{IssueStatus.table_name}.id = #{Issue.table_name}.status_id", :conditions => ["project_id=? and #{IssueStatus.table_name}.is_closed=?", @project.id, false])
@total_issues_by_tracker = Issue.count(:group => :tracker, :conditions => ["project_id=?", @project.id])
@total_hours = @project.time_entries.sum(:hours)
@@ -92,14 +90,11 @@ class ProjectsController < ApplicationController
end
def settings
@root_projects = Project.find(:all,
:conditions => ["parent_id IS NULL AND status = #{Project::STATUS_ACTIVE} AND id <> ?", @project.id],
:order => 'name')
@root_projects = Project::find(:all, :conditions => ["parent_id IS NULL AND status = #{Project::STATUS_ACTIVE} AND id <> ?", @project.id])
@custom_fields = IssueCustomField.find(:all)
@issue_category ||= IssueCategory.new
@member ||= @project.members.new
@trackers = Tracker.all
@custom_values ||= ProjectCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| @project.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
@custom_values ||= ProjectCustomField.find(:all).collect { |x| @project.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
@repository ||= @project.repository
@wiki ||= @project.wiki
end
@@ -109,7 +104,7 @@ class ProjectsController < ApplicationController
if request.post?
@project.custom_fields = IssueCustomField.find(params[:custom_field_ids]) if params[:custom_field_ids]
if params[:custom_fields]
@custom_values = ProjectCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
@custom_values = ProjectCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @project, :value => params["custom_fields"][x.id.to_s]) }
@project.custom_values = @custom_values
end
@project.attributes = params[:project]
@@ -181,7 +176,10 @@ class ProjectsController < ApplicationController
def add_document
@document = @project.documents.build(params[:document])
if request.post? and @document.save
attach_files(@document, params[:attachments])
# Save the attachments
params[:attachments].each { |a|
Attachment.create(:container => @document, :file => a, :author => logged_in_user) unless a.size == 0
} if params[:attachments] and params[:attachments].is_a? Array
flash[:notice] = l(:notice_successful_create)
Mailer.deliver_document_added(@document) if Setting.notified_events.include?('document_added')
redirect_to :action => 'list_documents', :id => @project
@@ -211,7 +209,7 @@ class ProjectsController < ApplicationController
@issue = params[:copy_from] ? Issue.new.copy_from(params[:copy_from]) : Issue.new(params[:issue])
@issue.project = @project
@issue.author = User.current
@issue.tracker ||= @project.trackers.find(params[:tracker_id])
@issue.tracker ||= Tracker.find(params[:tracker_id])
default_status = IssueStatus.default
unless default_status
@@ -220,7 +218,7 @@ class ProjectsController < ApplicationController
return
end
@issue.status = default_status
@allowed_statuses = ([default_status] + default_status.find_new_statuses_allowed_to(User.current.role_for_project(@project), @issue.tracker))
@allowed_statuses = ([default_status] + default_status.find_new_statuses_allowed_to(logged_in_user.role_for_project(@project), @issue.tracker))if logged_in_user
if request.get?
@issue.start_date ||= Date.today
@@ -234,16 +232,124 @@ class ProjectsController < ApplicationController
@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
if @issue.save
attach_files(@issue, params[:attachments])
if params[:attachments] && params[:attachments].is_a?(Array)
# Save attachments
params[:attachments].each {|a| Attachment.create(:container => @issue, :file => a, :author => User.current) unless a.size == 0}
end
flash[:notice] = l(:notice_successful_create)
Mailer.deliver_issue_add(@issue) if Setting.notified_events.include?('issue_added')
redirect_to :controller => 'issues', :action => 'index', :project_id => @project
redirect_to :action => 'list_issues', :id => @project
return
end
end
@priorities = Enumeration::get_values('IPRI')
end
# Show filtered/sorted issues list of @project
def list_issues
sort_init "#{Issue.table_name}.id", "desc"
sort_update
retrieve_query
@results_per_page_options = [ 15, 25, 50, 100 ]
if params[:per_page] and @results_per_page_options.include? params[:per_page].to_i
@results_per_page = params[:per_page].to_i
session[:results_per_page] = @results_per_page
else
@results_per_page = session[:results_per_page] || 25
end
if @query.valid?
@issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
@issue_pages = Paginator.new self, @issue_count, @results_per_page, params['page']
@issues = Issue.find :all, :order => sort_clause,
:include => [ :assigned_to, :status, :tracker, :project, :priority, :category ],
:conditions => @query.statement,
:limit => @issue_pages.items_per_page,
:offset => @issue_pages.current.offset
end
render :layout => false if request.xhr?
end
# Export filtered/sorted issues list to CSV
def export_issues_csv
sort_init "#{Issue.table_name}.id", "desc"
sort_update
retrieve_query
render :action => 'list_issues' and return unless @query.valid?
@issues = Issue.find :all, :order => sort_clause,
:include => [ :assigned_to, :author, :status, :tracker, :priority, :project, {:custom_values => :custom_field} ],
:conditions => @query.statement,
:limit => Setting.issues_export_limit.to_i
ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
export = StringIO.new
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
# csv header fields
headers = [ "#", l(:field_status),
l(:field_project),
l(:field_tracker),
l(:field_priority),
l(:field_subject),
l(:field_assigned_to),
l(:field_author),
l(:field_start_date),
l(:field_due_date),
l(:field_done_ratio),
l(:field_created_on),
l(:field_updated_on)
]
for custom_field in @project.all_custom_fields
headers << custom_field.name
end
csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
# csv lines
@issues.each do |issue|
fields = [issue.id, issue.status.name,
issue.project.name,
issue.tracker.name,
issue.priority.name,
issue.subject,
(issue.assigned_to ? issue.assigned_to.name : ""),
issue.author.name,
issue.start_date ? l_date(issue.start_date) : nil,
issue.due_date ? l_date(issue.due_date) : nil,
issue.done_ratio,
l_datetime(issue.created_on),
l_datetime(issue.updated_on)
]
for custom_field in @project.all_custom_fields
fields << (show_value issue.custom_value_for(custom_field))
end
csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
end
end
export.rewind
send_data(export.read, :type => 'text/csv; header=present', :filename => 'export.csv')
end
# Export filtered/sorted issues to PDF
def export_issues_pdf
sort_init "#{Issue.table_name}.id", "desc"
sort_update
retrieve_query
render :action => 'list_issues' and return unless @query.valid?
@issues = Issue.find :all, :order => sort_clause,
:include => [ :author, :status, :tracker, :priority, :project ],
:conditions => @query.statement,
:limit => Setting.issues_export_limit.to_i
@options_for_rfpdf ||= {}
@options_for_rfpdf[:file_name] = "export.pdf"
render :layout => false
end
# Bulk edit issues
def bulk_edit_issues
if request.post?
@@ -277,7 +383,7 @@ class ProjectsController < ApplicationController
else
flash[:error] = l(:notice_failed_to_save_issues, unsaved_issue_ids.size, issues.size, '#' + unsaved_issue_ids.join(', #'))
end
redirect_to :controller => 'issues', :action => 'index', :project_id => @project
redirect_to :action => 'list_issues', :id => @project
return
end
if current_role && User.current.allowed_to?(:change_issue_status, @project)
@@ -293,54 +399,70 @@ class ProjectsController < ApplicationController
def move_issues
@issues = @project.issues.find(params[:issue_ids]) if params[:issue_ids]
redirect_to :controller => 'issues', :action => 'index', :project_id => @project and return unless @issues
redirect_to :action => 'list_issues', :id => @project and return unless @issues
@projects = []
# find projects to which the user is allowed to move the issue
if User.current.admin?
# admin is allowed to move issues to any active (visible) project
@projects = Project.find(:all, :conditions => Project.visible_by(User.current), :order => 'name')
else
User.current.memberships.each {|m| @projects << m.project if m.role.allowed_to?(:move_issues)}
end
@target_project = @projects.detect {|p| p.id.to_s == params[:new_project_id]} if params[:new_project_id]
@target_project ||= @project
@trackers = @target_project.trackers
if request.post?
new_tracker = params[:new_tracker_id].blank? ? nil : @target_project.trackers.find_by_id(params[:new_tracker_id])
unsaved_issue_ids = []
@issues.each do |issue|
unsaved_issue_ids << issue.id unless issue.move_to(@target_project, new_tracker)
User.current.memberships.each {|m| @projects << m.project if m.role.allowed_to?(:controller => 'projects', :action => 'move_issues')}
# issue can be moved to any tracker
@trackers = Tracker.find(:all)
if request.post? and params[:new_project_id] and params[:new_tracker_id]
new_project = Project.find_by_id(params[:new_project_id])
new_tracker = Tracker.find_by_id(params[:new_tracker_id])
@issues.each do |i|
if new_project && i.project_id != new_project.id
# issue is moved to another project
i.category = nil
i.fixed_version = nil
# delete issue relations
i.relations_from.clear
i.relations_to.clear
i.project = new_project
end
if new_tracker
i.tracker = new_tracker
end
i.save
end
if unsaved_issue_ids.empty?
flash[:notice] = l(:notice_successful_update) unless @issues.empty?
else
flash[:error] = l(:notice_failed_to_save_issues, unsaved_issue_ids.size, @issues.size, '#' + unsaved_issue_ids.join(', #'))
end
redirect_to :controller => 'issues', :action => 'index', :project_id => @project
return
flash[:notice] = l(:notice_successful_update)
redirect_to :action => 'list_issues', :id => @project
end
render :layout => false if request.xhr?
end
# Add a news to @project
def add_news
@news = News.new(:project => @project, :author => User.current)
@news = News.new(:project => @project)
if request.post?
@news.attributes = params[:news]
@news.author_id = self.logged_in_user.id if self.logged_in_user
if @news.save
flash[:notice] = l(:notice_successful_create)
Mailer.deliver_news_added(@news) if Setting.notified_events.include?('news_added')
redirect_to :controller => 'news', :action => 'index', :project_id => @project
redirect_to :action => 'list_news', :id => @project
end
end
end
# Show news list of @project
def list_news
@news_pages, @newss = paginate :news, :per_page => 10, :conditions => ["project_id=?", @project.id], :include => :author, :order => "#{News.table_name}.created_on DESC"
respond_to do |format|
format.html { render :layout => false if request.xhr? }
format.atom { render_feed(@newss, :title => "#{@project.name}: #{l(:label_news_plural)}") }
end
end
def add_file
if request.post?
@version = @project.versions.find_by_id(params[:version_id])
attachments = attach_files(@version, params[:attachments])
Mailer.deliver_attachments_added(attachments) if !attachments.empty? && Setting.notified_events.include?('file_added')
# Save the attachments
@attachments = []
params[:attachments].each { |file|
next unless file.size > 0
a = Attachment.create(:container => @version, :file => file, :author => logged_in_user)
@attachments << a unless a.new_record?
} if params[:attachments] and params[:attachments].is_a? Array
Mailer.deliver_attachments_added(@attachments) if !@attachments.empty? && Setting.notified_events.include?('file_added')
redirect_to :controller => 'projects', :action => 'list_files', :id => @project
end
@versions = @project.versions.sort
@@ -352,13 +474,13 @@ class ProjectsController < ApplicationController
# Show changelog for @project
def changelog
@trackers = @project.trackers.find(:all, :conditions => ["is_in_chlog=?", true], :order => 'position')
@trackers = Tracker.find(:all, :conditions => ["is_in_chlog=?", true], :order => 'position')
retrieve_selected_tracker_ids(@trackers)
@versions = @project.versions.sort
end
def roadmap
@trackers = @project.trackers.find(:all, :conditions => ["is_in_roadmap=?", true])
@trackers = Tracker.find(:all, :conditions => ["is_in_roadmap=?", true], :order => 'position')
retrieve_selected_tracker_ids(@trackers)
@versions = @project.versions.sort
@versions = @versions.select {|v| !v.completed? } unless params[:completed]
@@ -385,22 +507,20 @@ class ProjectsController < ApplicationController
@date_to = @date_from >> 1
end
@event_types = %w(issues news files documents changesets wiki_pages messages)
@event_types = %w(issues news files documents wiki_pages changesets)
@event_types.delete('wiki_pages') unless @project.wiki
@event_types.delete('changesets') unless @project.repository
@event_types.delete('messages') unless @project.boards.any?
# only show what the user is allowed to view
@event_types = @event_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, @project)}
@scope = @event_types.select {|t| params["show_#{t}"]}
# default events if none is specified in parameters
@scope = (@event_types - %w(wiki_pages messages))if @scope.empty?
@scope = (@event_types - %w(wiki_pages))if @scope.empty?
@events = []
if @scope.include?('issues')
@events += @project.issues.find(:all, :include => [:author, :tracker], :conditions => ["#{Issue.table_name}.created_on>=? and #{Issue.table_name}.created_on<=?", @date_from, @date_to] )
@events += @project.issues_status_changes(@date_from, @date_to)
end
if @scope.include?('news')
@@ -430,13 +550,7 @@ class ProjectsController < ApplicationController
end
if @scope.include?('changesets')
@events += Changeset.find(:all, :include => :repository, :conditions => ["#{Repository.table_name}.project_id = ? AND #{Changeset.table_name}.committed_on BETWEEN ? AND ?", @project.id, @date_from, @date_to])
end
if @scope.include?('messages')
@events += Message.find(:all,
:include => [:board, :author],
:conditions => ["#{Board.table_name}.project_id=? AND #{Message.table_name}.parent_id IS NULL AND #{Message.table_name}.created_on BETWEEN ? AND ?", @project.id, @date_from, @date_to])
@events += @project.repository.changesets.find(:all, :conditions => ["#{Changeset.table_name}.committed_on BETWEEN ? AND ?", @date_from, @date_to])
end
@events_by_day = @events.group_by(&:event_date)
@@ -545,4 +659,31 @@ private
@selected_tracker_ids = selectable_trackers.collect {|t| t.id.to_s }
end
end
# Retrieve query from session or build a new query
def retrieve_query
if params[:query_id]
@query = @project.queries.find(params[:query_id])
@query.executed_by = logged_in_user
session[:query] = @query
else
if params[:set_filter] or !session[:query] or session[:query].project_id != @project.id
# Give it a name, required to be valid
@query = Query.new(:name => "_", :executed_by => logged_in_user)
@query.project = @project
if params[:fields] and params[:fields].is_a? Array
params[:fields].each do |field|
@query.add_filter(field, params[:operators][field], params[:values][field])
end
else
@query.available_filters.keys.each do |field|
@query.add_short_filter(field, params[field]) if params[field]
end
end
session[:query] = @query
else
@query = session[:query]
end
end
end
end

View File

@@ -22,13 +22,14 @@ class QueriesController < ApplicationController
def index
@queries = @project.queries.find(:all,
:order => "name ASC",
:conditions => ["is_public = ? or user_id = ?", true, (User.current.logged? ? User.current.id : 0)])
:conditions => ["is_public = ? or user_id = ?", true, (logged_in_user ? logged_in_user.id : 0)])
end
def new
@query = Query.new(params[:query])
@query.project = @project
@query.user = User.current
@query.user = logged_in_user
@query.executed_by = logged_in_user
@query.is_public = false unless current_role.allowed_to?(:manage_public_queries)
@query.column_names = nil if params[:default_columns]
@@ -38,7 +39,7 @@ class QueriesController < ApplicationController
if request.post? && params[:confirm] && @query.save
flash[:notice] = l(:notice_successful_create)
redirect_to :controller => 'issues', :action => 'index', :project_id => @project, :query_id => @query
redirect_to :controller => 'projects', :action => 'list_issues', :id => @project, :query_id => @query
return
end
render :layout => false if request.xhr?
@@ -56,7 +57,7 @@ class QueriesController < ApplicationController
if @query.save
flash[:notice] = l(:notice_successful_update)
redirect_to :controller => 'issues', :action => 'index', :project_id => @project, :query_id => @query
redirect_to :controller => 'projects', :action => 'list_issues', :id => @project, :query_id => @query
end
end
end
@@ -70,8 +71,9 @@ private
def find_project
if params[:id]
@query = Query.find(params[:id])
@query.executed_by = logged_in_user
@project = @query.project
render_403 unless @query.editable_by?(User.current)
render_403 unless @query.editable_by?(logged_in_user)
else
@project = Project.find(params[:project_id])
end

View File

@@ -25,7 +25,7 @@ class ReportsController < ApplicationController
case params[:detail]
when "tracker"
@field = "tracker_id"
@rows = @project.trackers
@rows = Tracker.find :all, :order => 'position'
@data = issues_by_tracker
@report_title = l(:field_tracker)
render :template => "reports/issue_report_details"
@@ -60,7 +60,7 @@ class ReportsController < ApplicationController
@report_title = l(:field_subproject)
render :template => "reports/issue_report_details"
else
@trackers = @project.trackers
@trackers = Tracker.find(:all, :order => 'position')
@versions = @project.versions.sort
@priorities = Enumeration::get_values('IPRI')
@categories = @project.issue_categories

View File

@@ -19,9 +19,6 @@ require 'SVG/Graph/Bar'
require 'SVG/Graph/BarHorizontal'
require 'digest/sha1'
class ChangesetNotFound < Exception
end
class RepositoriesController < ApplicationController
layout 'base'
before_filter :find_repository, :except => :edit
@@ -92,44 +89,24 @@ class RepositoriesController < ApplicationController
show_error and return unless @content
if 'raw' == params[:format]
send_data @content, :filename => @path.split('/').last
else
# Prevent empty lines when displaying a file with Windows style eol
@content.gsub!("\r\n", "\n")
end
end
def annotate
@annotate = @repository.scm.annotate(@path, @rev)
show_error and return if @annotate.nil? || @annotate.empty?
end
def revision
@changeset = @repository.changesets.find_by_revision(@rev)
raise ChangesetNotFound unless @changeset
show_error and return unless @changeset
@changes_count = @changeset.changes.size
@changes_pages = Paginator.new self, @changes_count, 150, params['page']
@changes = @changeset.changes.find(:all,
:limit => @changes_pages.items_per_page,
:offset => @changes_pages.current.offset)
respond_to do |format|
format.html
format.js {render :layout => false}
end
rescue ChangesetNotFound
show_error
render :action => "revision", :layout => false if request.xhr?
end
def diff
@rev_to = params[:rev_to] ? params[:rev_to].to_i : (@rev - 1)
@diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
@diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
# Save diff type as user preference
if User.current.logged? && @diff_type != User.current.pref[:diff_type]
User.current.pref[:diff_type] = @diff_type
User.current.preference.save
end
@diff_type = ('sbs' == params[:type]) ? 'sbs' : 'inline'
@cache_key = "repositories/diff/#{@repository.id}/" + Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}")
unless read_fragment(@cache_key)

View File

@@ -33,8 +33,7 @@ class RolesController < ApplicationController
end
def new
# Prefills the form with 'Non member' role permissions
@role = Role.new(params[:role] || {:permissions => Role.non_member.permissions})
@role = Role.new(params[:role])
if request.post? && @role.save
flash[:notice] = l(:notice_successful_create)
redirect_to :action => 'list'
@@ -94,7 +93,7 @@ class RolesController < ApplicationController
end
@roles = Role.find(:all, :order => 'builtin, position')
@trackers = Tracker.find(:all, :order => 'position')
@statuses = IssueStatus.find(:all, :order => 'position')
@statuses = IssueStatus.find(:all, :include => :workflows, :order => 'position')
end
def report

View File

@@ -31,7 +31,7 @@ class SearchController < ApplicationController
begin; offset = params[:offset].to_time if params[:offset]; rescue; end
# quick jump to an issue
if @question.match(/^#?(\d+)$/) && Issue.find_by_id($1, :include => :project, :conditions => Project.visible_by(User.current))
if @question.match(/^#?(\d+)$/) && Issue.find_by_id($1, :include => :project, :conditions => Project.visible_by(logged_in_user))
redirect_to :controller => "issues", :action => "show", :id => $1
return
end
@@ -52,11 +52,8 @@ class SearchController < ApplicationController
@object_types = @scope = %w(projects)
end
# extract tokens from the question
# eg. hello "bye bye" => ["hello", "bye bye"]
@tokens = @question.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect {|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')}
# tokens must be at least 3 character long
@tokens = @tokens.uniq.select {|w| w.length > 2 }
@tokens = @question.split.uniq.select {|w| w.length > 2 }
if !@tokens.empty?
# no more than 5 tokens to search for
@@ -90,13 +87,13 @@ class SearchController < ApplicationController
end
else
operator = @all_words ? ' AND ' : ' OR '
@results += Project.find(:all,
:limit => limit,
:conditions => [ (["(#{Project.visible_by(User.current)}) AND (LOWER(name) like ? OR LOWER(description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort]
) if @scope.include? 'projects'
Project.with_scope(:find => {:conditions => Project.visible_by(logged_in_user)}) do
@results += Project.find(:all, :limit => limit, :conditions => [ (["(LOWER(name) like ? OR LOWER(description) like ?)"] * like_tokens.size).join(operator), * (like_tokens * 2).sort] ) if @scope.include? 'projects'
end
# if only one project is found, user is redirected to its overview
redirect_to :controller => 'projects', :action => 'show', :id => @results.first and return if @results.size == 1
end
@question = @tokens.join(" ")
else
@question = ""
end

View File

@@ -54,7 +54,7 @@ class TimelogController < ApplicationController
begin; @date_to = params[:date_to].to_date; rescue; end
end
@date_from ||= Date.civil(Date.today.year, 1, 1)
@date_to ||= (Date.civil(Date.today.year, Date.today.month, 1) >> 1) - 1
@date_to ||= Date.civil(Date.today.year, Date.today.month+1, 1) - 1
unless @criterias.empty?
sql_select = @criterias.collect{|criteria| @available_criterias[criteria][:sql] + " AS " + criteria}.join(', ')
@@ -107,15 +107,15 @@ class TimelogController < ApplicationController
@entries = (@issue ? @issue : @project).time_entries.find(:all, :include => [:activity, :user, {:issue => [:tracker, :assigned_to, :priority]}], :order => sort_clause)
@total_hours = @entries.inject(0) { |sum,entry| sum + entry.hours }
@owner_id = User.current.id
@owner_id = logged_in_user ? logged_in_user.id : 0
send_csv and return if 'csv' == params[:export]
render :action => 'details', :layout => false if request.xhr?
end
def edit
render_404 and return if @time_entry && @time_entry.user != User.current
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => Date.today)
render_404 and return if @time_entry && @time_entry.user != logged_in_user
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => logged_in_user, :spent_on => Date.today)
@time_entry.attributes = params[:time_entry]
if request.post? and @time_entry.save
flash[:notice] = l(:notice_successful_update)

View File

@@ -37,10 +37,8 @@ class TrackersController < ApplicationController
if request.post? and @tracker.save
# workflow copy
if !params[:copy_workflow_from].blank? && (copy_from = Tracker.find_by_id(params[:copy_workflow_from]))
Workflow.transaction do
copy_from.workflows.find(:all, :include => [:role, :old_status, :new_status]).each do |w|
Workflow.create(:tracker_id => @tracker.id, :role => w.role, :old_status => w.old_status, :new_status => w.new_status)
end
copy_from.workflows.each do |w|
@tracker.workflows << w.clone
end
end
flash[:notice] = l(:notice_successful_create)

View File

@@ -52,13 +52,13 @@ class UsersController < ApplicationController
def add
if request.get?
@user = User.new(:language => Setting.default_language)
@custom_values = UserCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @user) }
@custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user) }
else
@user = User.new(params[:user])
@user.admin = params[:user][:admin] || false
@user.login = params[:user][:login]
@user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless @user.auth_source_id
@custom_values = UserCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => (params[:custom_fields] ? params["custom_fields"][x.id.to_s] : nil)) }
@custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => (params[:custom_fields] ? params["custom_fields"][x.id.to_s] : nil)) }
@user.custom_values = @custom_values
if @user.save
Mailer.deliver_account_information(@user, params[:password]) if params[:send_information]
@@ -72,13 +72,13 @@ class UsersController < ApplicationController
def edit
@user = User.find(params[:id])
if request.get?
@custom_values = UserCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| @user.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
@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.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? or @user.auth_source_id
if params[:custom_fields]
@custom_values = UserCustomField.find(:all, :order => "#{CustomField.table_name}.position").collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }
@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])
@@ -109,4 +109,12 @@ class UsersController < ApplicationController
end
redirect_to :action => 'edit', :id => @user and return
end
def destroy
User.find(params[:id]).destroy
redirect_to :action => 'list'
rescue
flash[:error] = "Unable to delete user"
redirect_to :action => 'list'
end
end

View File

@@ -21,9 +21,6 @@ class VersionsController < ApplicationController
cache_sweeper :version_sweeper, :only => [ :edit, :destroy ]
def show
end
def edit
if request.post? and @version.update_attributes(params[:version])
flash[:notice] = l(:notice_successful_update)
@@ -42,7 +39,7 @@ class VersionsController < ApplicationController
def download
@attachment = @version.attachments.find(params[:attachment_id])
@attachment.increment_download
send_file @attachment.diskfile, :filename => @attachment.filename, :type => @attachment.content_type
send_file @attachment.diskfile, :filename => @attachment.filename
rescue
render_404
end
@@ -52,13 +49,6 @@ class VersionsController < ApplicationController
flash[:notice] = l(:notice_successful_delete)
redirect_to :controller => 'projects', :action => 'list_files', :id => @project
end
def status_by
respond_to do |format|
format.html { render :action => 'show' }
format.js { render(:update) {|page| page.replace_html 'status_by', render_issue_status_by(@version, params[:status_by])} }
end
end
private
def find_project

View File

@@ -19,7 +19,7 @@ class WelcomeController < ApplicationController
layout 'base'
def index
@news = News.latest User.current
@projects = Project.latest User.current
@news = News.latest logged_in_user
@projects = Project.latest logged_in_user
end
end

View File

@@ -69,7 +69,7 @@ class WikiController < ApplicationController
#@content.text = params[:content][:text]
#@content.comments = params[:content][:comments]
@content.attributes = params[:content]
@content.author = User.current
@content.author = logged_in_user
# if page is new @page.save will also save content, but not if page isn't a new record
if (@page.new_record? ? @page.save : @content.save)
redirect_to :action => 'index', :id => @project, :page => @page.title
@@ -154,7 +154,11 @@ class WikiController < ApplicationController
def add_attachment
@page = @wiki.find_page(params[:page])
attach_files(@page, params[:attachments])
# Save the attachments
params[:attachments].each { |file|
next unless file.size > 0
a = Attachment.create(:container => @page, :file => file, :author => logged_in_user)
} if params[:attachments] and params[:attachments].is_a? Array
redirect_to :action => 'index', :page => @page.title
end

View File

@@ -23,7 +23,7 @@ class WikisController < ApplicationController
def edit
@wiki = @project.wiki || Wiki.new(:project => @project)
@wiki.attributes = params[:wiki]
@wiki.save if request.post?
@wiki.save if @request.post?
render(:update) {|page| page.replace_html "tab-content-wiki", :partial => 'projects/settings/wiki'}
end

View File

@@ -16,7 +16,6 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module ApplicationHelper
include Redmine::WikiFormatting::Macros::Definitions
def current_role
@current_role ||= User.current.role_for_project(@project)
@@ -34,7 +33,7 @@ module ApplicationHelper
# Display a link to user's account page
def link_to_user(user)
user ? link_to(user, :controller => 'account', :action => 'show', :id => user) : 'Anonymous'
link_to user.name, :controller => 'account', :action => 'show', :id => user
end
def link_to_issue(issue)
@@ -71,28 +70,20 @@ module ApplicationHelper
def format_date(date)
return nil unless date
# "Setting.date_format.size < 2" is a temporary fix (content of date_format setting changed)
@date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
@date_format ||= (Setting.date_format.to_i == 0 ? l(:general_fmt_date) : "%Y-%m-%d")
date.strftime(@date_format)
end
def format_time(time, include_date = true)
def format_time(time)
return nil unless time
@date_format_setting ||= Setting.date_format.to_i
time = time.to_time if time.is_a?(String)
zone = User.current.time_zone
if time.utc?
local = zone ? zone.adjust(time) : time.getlocal
else
local = zone ? zone.adjust(time.getutc) : time
end
@date_format ||= (Setting.date_format.blank? || Setting.date_format.size < 2 ? l(:general_fmt_date) : Setting.date_format)
@time_format ||= (Setting.time_format.blank? ? l(:general_fmt_time) : Setting.time_format)
include_date ? local.strftime("#{@date_format} #{@time_format}") : local.strftime(@time_format)
@date_format_setting == 0 ? l_datetime(time) : (time.strftime("%Y-%m-%d") + ' ' + l_time(time))
end
def authoring(created, author)
time_tag = content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created))
l(:label_added_time_by, author || 'Anonymous', time_tag)
l(:label_added_time_by, author.name, time_tag)
end
def day_name(day)
@@ -139,28 +130,15 @@ module ApplicationHelper
:preview => 'r',
:quick_search => 'f',
:search => '4',
}.freeze unless const_defined?(:ACCESSKEYS)
}.freeze
def accesskey(s)
ACCESSKEYS[s]
end
# Formats text according to system settings.
# 2 ways to call this method:
# * with a String: textilizable(text, options)
# * with an object and one of its attribute: textilizable(issue, :description, options)
def textilizable(*args)
options = args.last.is_a?(Hash) ? args.pop : {}
case args.size
when 1
obj = nil
text = args.shift || ''
when 2
obj = args.shift
text = obj.send(args.shift)
else
raise ArgumentError, 'invalid arguments to textilizable'
end
# format text according to system settings
def textilizable(text, options = {})
return "" if text.blank?
# when using an image link, try to use an attachment, if possible
attachments = options[:attachments]
@@ -180,8 +158,7 @@ module ApplicationHelper
end
text = (Setting.text_formatting == 'textile') ?
Redmine::WikiFormatting.to_html(text) { |macro, args| exec_macro(macro, obj, args) } :
simple_format(auto_link(h(text)))
Redmine::WikiFormatting.to_html(text) : simple_format(auto_link(h(text)))
# different methods for formatting wiki links
case options[:wiki_links]
@@ -231,7 +208,7 @@ module ApplicationHelper
# example:
# #52 -> <a href="/issues/show/52">#52</a>
# r52 -> <a href="/repositories/revision/6?rev=52">r52</a> (project.id is 6)
text = text.gsub(%r{([\s\(,-^])(#|r)(\d+)(?=[[:punct:]]|\s|<|$)}) do |m|
text = text.gsub(%r{([\s,-^])(#|r)(\d+)(?=[[:punct:]]|\s|<|$)}) do |m|
leading, otype, oid = $1, $2, $3
link = nil
if otype == 'r'
@@ -299,7 +276,7 @@ module ApplicationHelper
def lang_options_for_select(blank=true)
(blank ? [["(auto)", ""]] : []) +
GLoc.valid_languages.collect{|lang| [ ll(lang.to_s, :general_lang_name), lang.to_s]}.sort{|x,y| x.last <=> y.last }
GLoc.valid_languages.collect{|lang| [ ll(lang.to_s, :general_lang_name), lang.to_s]}.sort{|x,y| x.first <=> y.first }
end
def label_tag_for(name, option_tags = nil, options = {})
@@ -319,21 +296,6 @@ module ApplicationHelper
link_to_function(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
end
def progress_bar(pcts, options={})
pcts = [pcts, pcts] unless pcts.is_a?(Array)
pcts[1] = pcts[1] - pcts[0]
pcts << (100 - pcts[1] - pcts[0])
width = options[:width] || '100px;'
legend = options[:legend] || ''
content_tag('table',
content_tag('tr',
(pcts[0] > 0 ? content_tag('td', '', :width => "#{pcts[0].floor}%;", :class => 'closed') : '') +
(pcts[1] > 0 ? content_tag('td', '', :width => "#{pcts[1].floor}%;", :class => 'done') : '') +
(pcts[2] > 0 ? content_tag('td', '', :width => "#{pcts[2].floor}%;", :class => 'todo') : '')
), :class => 'progress', :style => "width: #{width};") +
content_tag('p', legend, :class => 'pourcent')
end
def context_menu_link(name, url, options={})
options[:class] ||= ''
if options.delete(:selected)

View File

@@ -1,5 +1,5 @@
# redMine - project management software
# Copyright (C) 2006-2007 Jean-Philippe Lang
# 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
@@ -15,25 +15,5 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require File.dirname(__FILE__) + '/../test_helper'
class JournalTest < Test::Unit::TestCase
fixtures :issues, :issue_statuses, :journals, :journal_details
def setup
@journal = Journal.find 1
end
def test_journalized_is_an_issue
issue = @journal.issue
assert_kind_of Issue, issue
assert_equal 1, issue.id
end
def test_new_status
status = @journal.new_status
assert_not_nil status
assert_kind_of IssueStatus, status
assert_equal 2, status.id
end
module FeedsHelper
end

View File

@@ -15,10 +15,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require 'csv'
module IssuesHelper
include ApplicationHelper
def render_issue_tooltip(issue)
@cached_label_start_date ||= l(:field_start_date)
@@ -104,56 +101,4 @@ module IssuesHelper
end
end
end
def issues_to_csv(issues, project = nil)
ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
export = StringIO.new
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
# csv header fields
headers = [ "#",
l(:field_status),
l(:field_project),
l(:field_tracker),
l(:field_priority),
l(:field_subject),
l(:field_assigned_to),
l(:field_category),
l(:field_fixed_version),
l(:field_author),
l(:field_start_date),
l(:field_due_date),
l(:field_done_ratio),
l(:field_created_on),
l(:field_updated_on)
]
# Export project custom fields if project is given
# otherwise export custom fields marked as "For all projects"
custom_fields = project.nil? ? IssueCustomField.for_all : project.all_custom_fields
custom_fields.each {|f| headers << f.name}
csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
# csv lines
issues.each do |issue|
fields = [issue.id,
issue.status.name,
issue.project.name,
issue.tracker.name,
issue.priority.name,
issue.subject,
issue.assigned_to,
issue.category,
issue.fixed_version,
issue.author.name,
format_date(issue.start_date),
format_date(issue.due_date),
issue.done_ratio,
format_time(issue.created_on),
format_time(issue.updated_on)
]
custom_fields.each {|f| fields << show_value(issue.custom_value_for(f)) }
csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
end
end
export.rewind
export
end
end

View File

@@ -179,9 +179,9 @@ module ProjectsHelper
end
# today red line
if Date.today >= date_from and Date.today <= date_to
if Date.today >= @date_from and Date.today <= @date_to
gc.stroke('red')
x = (Date.today-date_from+1)*zoom + subject_width
x = (Date.today-@date_from+1)*zoom + subject_width
gc.line(x, headers_heigth, x, headers_heigth + g_height-1)
end
@@ -190,7 +190,7 @@ module ProjectsHelper
end if Object.const_defined?(:Magick)
def new_issue_selector
trackers = @project.trackers
trackers = Tracker.find(:all, :order => 'position')
# can't use form tag inside helper
content_tag('form',
select_tag('tracker_id', '<option></option>' + options_from_collection_for_select(trackers, 'id', 'name'), :onchange => "if (this.value != '') {this.form.submit()}"),

View File

@@ -22,30 +22,24 @@ module QueriesHelper
end
def column_header(column)
column.sortable ? sort_header_tag(column.sortable, :caption => column.caption) : content_tag('th', column.caption)
if column.sortable
sort_header_tag(column.sortable, :caption => l("field_#{column.name}"))
else
content_tag('th', l("field_#{column.name}"))
end
end
def column_content(column, issue)
if column.is_a?(QueryCustomFieldColumn)
cv = issue.custom_values.detect {|v| v.custom_field_id == column.custom_field.id}
show_value(cv)
value = issue.send(column.name)
if value.is_a?(Date)
format_date(value)
elsif value.is_a?(Time)
format_time(value)
elsif column.name == :subject
((@project.nil? || @project != issue.project) ? "#{issue.project.name} - " : '') +
link_to(h(value), :controller => 'issues', :action => 'show', :id => issue)
else
value = issue.send(column.name)
if value.is_a?(Date)
format_date(value)
elsif value.is_a?(Time)
format_time(value)
else
case column.name
when :subject
h((@project.nil? || @project != issue.project) ? "#{issue.project.name} - " : '') +
link_to(h(value), :controller => 'issues', :action => 'show', :id => issue)
when :done_ratio
progress_bar(value, :width => '80px')
else
h(value)
end
end
h(value)
end
end
end

View File

@@ -62,10 +62,7 @@ module RepositoriesHelper
content_tag('p', form.text_field(:url, :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)) +
'<br />(http://, https://, svn://, file:///)') +
content_tag('p', form.text_field(:login, :size => 30)) +
content_tag('p', form.password_field(:password, :size => 30, :name => 'ignore',
:value => ((repository.new_record? || repository.password.blank?) ? '' : ('x'*15)),
:onfocus => "this.value=''; this.name='repository[password]';",
:onchange => "this.name='repository[password]';"))
content_tag('p', form.password_field(:password, :size => 30))
end
def darcs_field_tags(form, repository)
@@ -80,8 +77,4 @@ module RepositoriesHelper
content_tag('p', form.text_field(:root_url, :label => 'CVSROOT', :size => 60, :required => true, :disabled => !repository.new_record?)) +
content_tag('p', form.text_field(:url, :label => 'Module', :size => 30, :required => true, :disabled => !repository.new_record?))
end
def bazaar_field_tags(form, repository)
content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.new_record?)))
end
end

View File

@@ -16,32 +16,4 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module VersionsHelper
STATUS_BY_CRITERIAS = %w(category tracker priority author assigned_to)
def render_issue_status_by(version, criteria)
criteria ||= 'category'
raise 'Unknown criteria' unless STATUS_BY_CRITERIAS.include?(criteria)
h = Hash.new {|k,v| k[v] = [0, 0]}
begin
# Total issue count
Issue.count(:group => criteria,
:conditions => ["#{Issue.table_name}.fixed_version_id = ?", version.id]).each {|c,s| h[c][0] = s}
# Open issues count
Issue.count(:group => criteria,
:include => :status,
:conditions => ["#{Issue.table_name}.fixed_version_id = ? AND #{IssueStatus.table_name}.is_closed = ?", version.id, false]).each {|c,s| h[c][1] = s}
rescue ActiveRecord::RecordNotFound
# When grouping by an association, Rails throws this exception if there's no result (bug)
end
counts = h.keys.compact.sort.collect {|k| {:group => k, :total => h[k][0], :open => h[k][1], :closed => (h[k][0] - h[k][1])}}
max = counts.collect {|c| c[:total]}.max
render :partial => 'issue_counts', :locals => {:version => version, :criteria => criteria, :counts => counts, :max => max}
end
def status_by_options_for_select(value)
options_for_select(STATUS_BY_CRITERIAS.collect {|criteria| [l("field_#{criteria}".to_sym), criteria]}, value)
end
end

View File

@@ -21,7 +21,7 @@ class Attachment < ActiveRecord::Base
belongs_to :container, :polymorphic => true
belongs_to :author, :class_name => "User", :foreign_key => "author_id"
validates_presence_of :container, :filename, :author
validates_presence_of :container, :filename
validates_length_of :filename, :maximum => 255
validates_length_of :disk_filename, :maximum => 255
@@ -82,9 +82,14 @@ class Attachment < ActiveRecord::Base
def increment_download
increment!(:downloads)
end
# returns last created projects
def self.most_downloaded
find(:all, :limit => 5, :order => "downloads DESC")
end
def project
container.project
container.is_a?(Project) ? container : container.project
end
def image?

View File

@@ -20,10 +20,6 @@ class AuthSource < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name
validates_length_of :name, :host, :maximum => 60
validates_length_of :account_password, :maximum => 60, :allow_nil => true
validates_length_of :account, :base_dn, :maximum => 255
validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30
def authenticate(login, password)
end

View File

@@ -27,7 +27,6 @@ class AuthSourceLdap < AuthSource
end
def authenticate(login, password)
return nil if login.blank? || password.blank?
attrs = []
# get user's DN
ldap_con = initialize_ldap_con(self.account, self.account_password)

View File

@@ -63,14 +63,6 @@ class Changeset < ActiveRecord::Base
return if kw_regexp.blank?
referenced_issues = []
if ref_keywords.delete('*')
# find any issue ID in the comments
target_issue_ids = []
comments.scan(%r{([\s\(,-^])#(\d+)(?=[[:punct:]]|\s|<|$)}).each { |m| target_issue_ids << m[1] }
referenced_issues += repository.project.issues.find_all_by_id(target_issue_ids)
end
comments.scan(Regexp.new("(#{kw_regexp})[\s:]+(([\s,;&]*#?\\d+)+)", Regexp::IGNORECASE)).each do |match|
action = match[0]
target_issue_ids = match[1].scan(/\d+/)
@@ -88,17 +80,6 @@ class Changeset < ActiveRecord::Base
end
referenced_issues += target_issues
end
self.issues = referenced_issues.uniq
end
# Returns the previous changeset
def previous
@previous ||= Changeset.find(:first, :conditions => ['revision < ? AND repository_id = ?', self.revision, self.repository_id], :order => 'revision DESC')
end
# Returns the next changeset
def next
@next ||= Changeset.find(:first, :conditions => ['revision > ? AND repository_id = ?', self.revision, self.repository_id], :order => 'revision ASC')
end
end

View File

@@ -17,7 +17,6 @@
class CustomField < ActiveRecord::Base
has_many :custom_values, :dependent => :delete_all
acts_as_list :scope => 'type = \'#{self.class}\''
serialize :possible_values
FIELD_FORMATS = { "string" => { :name => :label_string, :order => 1 },
@@ -43,9 +42,6 @@ class CustomField < ActiveRecord::Base
def before_validation
# remove empty values
self.possible_values = self.possible_values.collect{|v| v unless v.empty?}.compact
# make sure these fields are not searchable
self.searchable = false if %w(int float date bool).include?(field_format)
true
end
def validate
@@ -55,10 +51,6 @@ class CustomField < ActiveRecord::Base
end
end
def <=>(field)
position <=> field.position
end
# to move in project_custom_field
def self.for_all
find(:all, :conditions => ["is_for_all=?", true])

View File

@@ -31,9 +31,9 @@ protected
when 'float'
begin; !value.blank? && Kernel.Float(value); rescue; errors.add(:value, :activerecord_error_invalid) end
when 'date'
errors.add(:value, :activerecord_error_not_a_date) unless value =~ /^\d{4}-\d{2}-\d{2}$/ or value.blank?
errors.add(:value, :activerecord_error_not_a_date) unless value =~ /^\d{4}-\d{2}-\d{2}$/ or value.empty?
when 'list'
errors.add(:value, :activerecord_error_inclusion) unless custom_field.possible_values.include?(value) or value.blank?
errors.add(:value, :activerecord_error_inclusion) unless custom_field.possible_values.include? value or value.empty?
end
end
end

View File

@@ -22,7 +22,6 @@ class Document < ActiveRecord::Base
acts_as_searchable :columns => ['title', 'description']
acts_as_event :title => Proc.new {|o| "#{l(:label_document)}: #{o.title}"},
:author => Proc.new {|o| (a = o.attachments.find(:first, :order => "#{Attachment.table_name}.created_on ASC")) ? a.author : nil },
:url => Proc.new {|o| {:controller => 'documents', :action => 'show', :id => o.id}}
validates_presence_of :project, :title, :category

View File

@@ -40,7 +40,7 @@ class Issue < ActiveRecord::Base
acts_as_event :title => Proc.new {|o| "#{o.tracker.name} ##{o.id}: #{o.subject}"},
:url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.id}}
validates_presence_of :subject, :description, :priority, :project, :tracker, :author, :status
validates_presence_of :subject, :description, :priority, :tracker, :author, :status
validates_length_of :subject, :maximum => 255
validates_inclusion_of :done_ratio, :in => 0..100
validates_numericality_of :estimated_hours, :allow_nil => true
@@ -61,32 +61,6 @@ class Issue < ActiveRecord::Base
self
end
# Move an issue to a new project and tracker
def move_to(new_project, new_tracker = nil)
transaction do
if new_project && project_id != new_project.id
# delete issue relations
self.relations_from.clear
self.relations_to.clear
# issue is moved to another project
self.category = nil
self.fixed_version = nil
self.project = new_project
end
if new_tracker
self.tracker = new_tracker
end
if save
# Manually update project_id on related time entries
TimeEntry.update_all("project_id = #{new_project.id}", {:issue_id => id})
else
rollback_db_transaction
return false
end
end
return true
end
def priority_id=(pid)
self.priority = nil
write_attribute(:priority_id, pid)
@@ -106,10 +80,6 @@ class Issue < ActiveRecord::Base
end
end
def validate_on_create
errors.add :tracker_id, :activerecord_error_invalid unless project.trackers.include?(tracker)
end
def before_create
# default assignment based on category
if assigned_to.nil? && category && category.assigned_to

View File

@@ -35,9 +35,5 @@ class IssueCategory < ActiveRecord::Base
destroy_without_reassign
end
def <=>(category)
name <=> category.name
end
def to_s; name end
end

View File

@@ -29,19 +29,8 @@ class Journal < ActiveRecord::Base
:project_key => "#{Issue.table_name}.project_id",
:date_column => "#{Issue.table_name}.created_on"
acts_as_event :title => Proc.new {|o| "#{o.issue.tracker.name} ##{o.issue.id}: #{o.issue.subject}" + ((s = o.new_status) ? " (#{s})" : '') },
:description => :notes,
:author => :user,
:url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id}}
def save
# Do not save an empty journal
(details.empty? && notes.blank?) ? false : super
end
# Returns the new status if the journal contains a status change, otherwise nil
def new_status
c = details.detect {|detail| detail.prop_key == 'status_id'}
(c && c.value) ? IssueStatus.find_by_id(c.value.to_i) : nil
end
end

View File

@@ -88,14 +88,6 @@ class Mailer < ActionMailer::Base
:password => password,
:login_url => url_for(:controller => 'account', :action => 'login')
end
def account_activation_request(user)
# Send the email to all active administrators
recipients User.find_active(:all, :conditions => {:admin => true}).collect { |u| u.mail }.compact
subject l(:mail_subject_account_activation_request)
body :user => user,
:url => url_for(:controller => 'users', :action => 'index', :status => User::STATUS_REGISTERED, :sort_key => 'created_on', :sort_order => 'desc')
end
def lost_password(token)
set_language_if_valid(token.user.language)
@@ -110,7 +102,7 @@ class Mailer < ActionMailer::Base
recipients token.user.mail
subject l(:mail_subject_register)
body :token => token,
:url => url_for(:controller => 'account', :action => 'activate', :token => token.value)
:url => url_for(:controller => 'account', :action => 'register', :token => token.value)
end
def test(user)
@@ -129,32 +121,10 @@ class Mailer < ActionMailer::Base
default_url_options[:protocol] = Setting.protocol
end
# Overrides the create_mail method
def create_mail
# Removes the current user from the recipients and cc
# if he doesn't want to receive notifications about what he does
if User.current.pref[:no_self_notified]
recipients.delete(User.current.mail) if recipients
cc.delete(User.current.mail) if cc
end
# Blind carbon copy recipients
if Setting.bcc_recipients?
bcc([recipients, cc].flatten.compact.uniq)
recipients []
cc []
end
super
end
# Renders a message with the corresponding layout
def render_message(method_name, body)
layout = method_name.match(%r{text\.html\.(rhtml|rxml)}) ? 'layout.text.html.rhtml' : 'layout.text.plain.rhtml'
body[:content_for_layout] = render(:file => method_name, :body => body)
ActionView::Base.new(template_root, body, self).render(:file => "mailer/#{layout}")
ActionView::Base.new(File.join(template_root, 'mailer'), body, self).render(:file => layout)
end
# Makes partial rendering work with Rails 1.2 (retro-compatibility)
def self.controller_path
''
end unless respond_to?('controller_path')
end

View File

@@ -30,15 +30,9 @@ class Message < ActiveRecord::Base
:description => :content,
:url => Proc.new {|o| {:controller => 'messages', :action => 'show', :board_id => o.board_id, :id => o.id}}
attr_protected :locked, :sticky
validates_presence_of :subject, :content
validates_length_of :subject, :maximum => 255
def validate_on_create
# Can not reply to a locked topic
errors.add_to_base 'Topic is locked' if root.locked?
end
def after_create
board.update_attribute(:last_message_id, self.id)
board.increment! :messages_count
@@ -49,18 +43,6 @@ class Message < ActiveRecord::Base
end
end
def after_destroy
# The following line is required so that the previous counter
# updates (due to children removal) are not overwritten
board.reload
board.decrement! :messages_count
board.decrement! :topics_count unless parent
end
def sticky?
sticky == 1
end
def project
board.project
end

View File

@@ -20,11 +20,10 @@ class Project < ActiveRecord::Base
STATUS_ACTIVE = 1
STATUS_ARCHIVED = 9
has_many :members, :include => :user, :conditions => "#{User.table_name}.status=#{User::STATUS_ACTIVE}"
has_many :members, :dependent => :delete_all, :include => :user, :conditions => "#{User.table_name}.status=#{User::STATUS_ACTIVE}"
has_many :users, :through => :members
has_many :custom_values, :dependent => :delete_all, :as => :customized
has_many :enabled_modules, :dependent => :delete_all
has_and_belongs_to_many :trackers, :order => "#{Tracker.table_name}.position"
has_many :issues, :dependent => :destroy, :order => "#{Issue.table_name}.created_on DESC", :include => [:status, :tracker]
has_many :issue_changes, :through => :issues, :source => :journals
has_many :versions, :dependent => :destroy, :order => "#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC"
@@ -37,13 +36,7 @@ class Project < ActiveRecord::Base
has_one :repository, :dependent => :destroy
has_many :changesets, :through => :repository
has_one :wiki, :dependent => :destroy
# Custom field for the project issues
has_and_belongs_to_many :custom_fields,
:class_name => 'IssueCustomField',
:order => "#{CustomField.table_name}.position",
:join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}",
:association_foreign_key => 'custom_field_id'
has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", :association_foreign_key => 'custom_field_id'
acts_as_tree :order => "name", :counter_cache => true
acts_as_searchable :columns => ['name', 'description'], :project_key => 'id'
@@ -57,13 +50,12 @@ class Project < ActiveRecord::Base
validates_associated :custom_values, :on => :update
validates_associated :repository, :wiki
validates_length_of :name, :maximum => 30
validates_format_of :name, :with => /^[\w\s\'\-]*$/i
validates_length_of :description, :maximum => 255
validates_length_of :homepage, :maximum => 60
validates_length_of :identifier, :in => 3..20
validates_length_of :identifier, :in => 3..12
validates_format_of :identifier, :with => /^[a-z0-9\-]*$/
before_destroy :delete_all_members
def identifier=(identifier)
super unless identifier_frozen?
end
@@ -79,22 +71,11 @@ class Project < ActiveRecord::Base
conditions = ["#{Issue.table_name}.project_id IN (#{ids.join(',')})"]
end
conditions ||= ["#{Issue.table_name}.project_id = ?", id]
# Quick and dirty fix for Rails 2 compatibility
Issue.send(:with_scope, :find => { :conditions => conditions }) do
Issue.with_scope :find => { :conditions => conditions } do
yield
end
end
# Return all issues status changes for the project between the 2 given dates
def issues_status_changes(from, to)
Journal.find(:all, :include => [:issue, :details, :user],
:conditions => ["#{Journal.table_name}.journalized_type = 'Issue'" +
" AND #{Issue.table_name}.project_id = ?" +
" AND #{JournalDetail.table_name}.prop_key = 'status_id'" +
" AND #{Journal.table_name}.created_on BETWEEN ? AND ?",
id, from, to+1])
end
# returns latest created projects
# non public projects will be returned only if user is a member of those
def self.latest(user=nil, count=5)
@@ -132,14 +113,9 @@ class Project < ActiveRecord::Base
children.select {|child| child.active?}
end
# Deletes all project's members
def delete_all_members
Member.delete_all(['project_id = ?', id])
end
# Users issues can be assigned to
def assignable_users
members.select {|m| m.role.assignable?}.collect {|m| m.user}.sort
members.select {|m| m.role.assignable?}.collect {|m| m.user}
end
# Returns the mail adresses of users that should be always notified on project events
@@ -158,7 +134,7 @@ class Project < ActiveRecord::Base
end
def <=>(project)
name.downcase <=> project.name.downcase
name <=> project.name
end
def allows_to?(action)

View File

@@ -17,34 +17,13 @@
class QueryColumn
attr_accessor :name, :sortable
include GLoc
def initialize(name, options={})
self.name = name
self.sortable = options[:sortable]
end
def caption
set_language_if_valid(User.current.language)
l("field_#{name}")
end
end
class QueryCustomFieldColumn < QueryColumn
def initialize(custom_field)
self.name = "cf_#{custom_field.id}".to_sym
self.sortable = false
@cf = custom_field
end
def caption
@cf.name
end
def custom_field
@cf
end
def default?; default end
end
class Query < ActiveRecord::Base
@@ -54,6 +33,7 @@ class Query < ActiveRecord::Base
serialize :column_names
attr_protected :project, :user
attr_accessor :executed_by
validates_presence_of :name, :on => :save
validates_length_of :name, :maximum => 255
@@ -99,7 +79,6 @@ class Query < ActiveRecord::Base
QueryColumn.new(:assigned_to, :sortable => "#{User.table_name}.lastname"),
QueryColumn.new(:updated_on, :sortable => "#{Issue.table_name}.updated_on"),
QueryColumn.new(:category, :sortable => "#{IssueCategory.table_name}.name"),
QueryColumn.new(:fixed_version),
QueryColumn.new(:start_date, :sortable => "#{Issue.table_name}.start_date"),
QueryColumn.new(:due_date, :sortable => "#{Issue.table_name}.due_date"),
QueryColumn.new(:estimated_hours, :sortable => "#{Issue.table_name}.estimated_hours"),
@@ -111,7 +90,11 @@ class Query < ActiveRecord::Base
def initialize(attributes = nil)
super attributes
self.filters ||= { 'status_id' => {:operator => "o", :values => [""]} }
set_language_if_valid(User.current.language)
end
def executed_by=(user)
@executed_by = user
set_language_if_valid(user.language) if user
end
def validate
@@ -143,12 +126,12 @@ class Query < ActiveRecord::Base
"done_ratio" => { :type => :integer, :order => 13 }}
user_values = []
user_values << ["<< #{l(:label_me)} >>", "me"] if User.current.logged?
if project
user_values += project.users.sort.collect{|s| [s.name, s.id.to_s] }
else
user_values += project.users.collect{|s| [s.name, s.id.to_s] }
elsif executed_by
user_values << ["<< #{l(:label_me)} >>", "me"] if executed_by
# members of the user's projects
user_values += User.current.projects.collect(&:users).flatten.uniq.sort.collect{|s| [s.name, s.id.to_s] }
user_values += executed_by.projects.collect(&:users).flatten.uniq.sort.collect{|s| [s.name, s.id.to_s] }
end
@available_filters["assigned_to_id"] = { :type => :list_optional, :order => 4, :values => user_values } unless user_values.empty?
@available_filters["author_id"] = { :type => :list, :order => 5, :values => user_values } unless user_values.empty?
@@ -162,6 +145,8 @@ class Query < ActiveRecord::Base
end
@project.all_custom_fields.select(&:is_filter?).each do |field|
case field.field_format
when "string", "int"
options = { :type => :string, :order => 20 }
when "text"
options = { :type => :text, :order => 20 }
when "list"
@@ -170,8 +155,6 @@ class Query < ActiveRecord::Base
options = { :type => :date, :order => 20 }
when "bool"
options = { :type => :list, :values => [[l(:general_text_yes), "1"], [l(:general_text_no), "0"]], :order => 20 }
else
options = { :type => :string, :order => 20 }
end
@available_filters["cf_#{field.id}"] = options.merge({ :name => field.name })
end
@@ -220,12 +203,7 @@ class Query < ActiveRecord::Base
end
def available_columns
return @available_columns if @available_columns
@available_columns = Query.available_columns
@available_columns += (project ?
project.custom_fields :
IssueCustomField.find(:all, :conditions => {:is_for_all => true})
).collect {|cf| QueryCustomFieldColumn.new(cf) }
cols = Query.available_columns
end
def columns
@@ -265,7 +243,7 @@ class Query < ActiveRecord::Base
elsif project
clause << "#{Issue.table_name}.project_id=%d" % project.id
else
clause << Project.visible_by(User.current)
clause << Project.visible_by(executed_by)
end
# filters clauses
@@ -290,7 +268,7 @@ class Query < ActiveRecord::Base
# "me" value subsitution
if %w(assigned_to_id author_id).include?(field)
v.push(User.current.logged? ? User.current.id.to_s : "0") if v.delete("me")
v.push(executed_by ? executed_by.id.to_s : "0") if v.delete("me")
end
case operator_for field

View File

@@ -33,10 +33,6 @@ class Repository < ActiveRecord::Base
def supports_cat?
scm.supports_cat?
end
def supports_annotate?
scm.supports_annotate?
end
def entries(path=nil, identifier=nil)
scm.entries(path, identifier)

View File

@@ -1,86 +0,0 @@
# redMine - project management software
# Copyright (C) 2006-2007 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 'redmine/scm/adapters/bazaar_adapter'
class Repository::Bazaar < Repository
attr_protected :root_url
validates_presence_of :url
def scm_adapter
Redmine::Scm::Adapters::BazaarAdapter
end
def self.scm_name
'Bazaar'
end
def entries(path=nil, identifier=nil)
entries = scm.entries(path, identifier)
if entries
entries.each do |e|
next if e.lastrev.revision.blank?
c = Change.find(:first,
:include => :changeset,
:conditions => ["#{Change.table_name}.revision = ? and #{Changeset.table_name}.repository_id = ?", e.lastrev.revision, id],
:order => "#{Changeset.table_name}.revision DESC")
if c
e.lastrev.identifier = c.changeset.revision
e.lastrev.name = c.changeset.revision
e.lastrev.author = c.changeset.committer
end
end
end
end
def fetch_changesets
scm_info = scm.info
if scm_info
# latest revision found in database
db_revision = latest_changeset ? latest_changeset.revision : 0
# latest revision in the repository
scm_revision = scm_info.lastrev.identifier.to_i
if db_revision < scm_revision
logger.debug "Fetching changesets for repository #{url}" if logger && logger.debug?
identifier_from = db_revision + 1
while (identifier_from <= scm_revision)
# loads changesets by batches of 200
identifier_to = [identifier_from + 199, scm_revision].min
revisions = scm.revisions('', identifier_to, identifier_from, :with_paths => true)
transaction do
revisions.reverse_each do |revision|
changeset = Changeset.create(:repository => self,
:revision => revision.identifier,
:committer => revision.author,
:committed_on => revision.time,
:scmid => revision.scmid,
:comments => revision.message)
revision.paths.each do |change|
Change.create(:changeset => changeset,
:action => change[:action],
:path => change[:path],
:revision => change[:revision])
end
end
end unless revisions.nil?
identifier_from = identifier_to + 1
end
end
end
end
end

View File

@@ -17,23 +17,6 @@
class Setting < ActiveRecord::Base
DATE_FORMATS = [
'%Y-%m-%d',
'%d/%m/%Y',
'%d.%m.%Y',
'%d-%m-%Y',
'%m/%d/%Y',
'%d %b %Y',
'%d %B %Y',
'%b %d, %Y',
'%B %d, %Y'
]
TIME_FORMATS = [
'%H:%M',
'%I:%M %p'
]
cattr_accessor :available_settings
@@available_settings = YAML::load(File.open("#{RAILS_ROOT}/config/settings.yml"))
Redmine::Plugin.registered_plugins.each do |id, plugin|

View File

@@ -29,14 +29,6 @@ class Tracker < ActiveRecord::Base
def to_s; name end
def <=>(tracker)
name <=> tracker.name
end
def self.all
find(:all, :order => 'position')
end
private
def check_integrity
raise "Can't delete tracker" if Issue.find(:first, :conditions => ["tracker_id=?", self.id])

View File

@@ -19,7 +19,6 @@ require "digest/sha1"
class User < ActiveRecord::Base
# Account statuses
STATUS_ANONYMOUS = 0
STATUS_ACTIVE = 1
STATUS_REGISTERED = 2
STATUS_LOCKED = 3
@@ -37,16 +36,17 @@ class User < ActiveRecord::Base
# Prevents unauthorized assignments
attr_protected :login, :admin, :password, :password_confirmation, :hashed_password
validates_presence_of :login, :firstname, :lastname, :mail, :if => Proc.new { |user| !user.is_a?(AnonymousUser) }
validates_presence_of :login, :firstname, :lastname, :mail
validates_uniqueness_of :login, :mail
# Login must contain lettres, numbers, underscores only
validates_format_of :login, :with => /^[a-z0-9_\-@\.]*$/i
validates_format_of :login, :with => /^[a-z0-9_\-@\.]+$/i
validates_length_of :login, :maximum => 30
validates_format_of :firstname, :lastname, :with => /^[\w\s\'\-]*$/i
validates_length_of :firstname, :lastname, :maximum => 30
validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :allow_nil => true
validates_length_of :mail, :maximum => 60, :allow_nil => true
validates_length_of :password, :minimum => 4, :allow_nil => true
validates_format_of :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
validates_length_of :mail, :maximum => 60
# Password length between 4 and 12
validates_length_of :password, :in => 4..12, :allow_nil => true
validates_confirmation_of :password, :allow_nil => true
validates_associated :custom_values, :on => :update
@@ -74,8 +74,6 @@ class User < ActiveRecord::Base
# Returns the user that matches provided login and password, or nil
def self.try_to_login(login, password)
# Make sure no one can sign in with an empty password
return nil if password.to_s.empty?
user = find(:first, :conditions => ["login=?", login])
if user
# user is already in local database
@@ -132,10 +130,6 @@ class User < ActiveRecord::Base
self.preference ||= UserPreference.new(:user => self)
end
def time_zone
self.pref.time_zone.nil? ? nil : TimeZone[self.pref.time_zone]
end
# Return user's RSS key (a 40 chars long string), used to access feeds
def rss_key
token = self.rss_token || Token.create(:user => self, :action => 'feeds')
@@ -165,7 +159,7 @@ class User < ActiveRecord::Base
end
def <=>(user)
user.nil? ? -1 : (lastname == user.lastname ? firstname <=> user.firstname : lastname <=> user.lastname)
lastname == user.lastname ? firstname <=> user.firstname : lastname <=> user.lastname
end
def to_s
@@ -180,16 +174,14 @@ class User < ActiveRecord::Base
def role_for_project(project)
# No role on archived projects
return nil unless project && project.active?
if logged?
# Find project membership
membership = memberships.detect {|m| m.project_id == project.id}
if membership
membership.role
else
@role_non_member ||= Role.non_member
end
# Find project membership
membership = memberships.detect {|m| m.project_id == project.id}
if membership
membership.role
elsif logged?
Role.non_member
else
@role_anonymous ||= Role.anonymous
Role.anonymous
end
end
@@ -220,17 +212,11 @@ class User < ActiveRecord::Base
end
def self.current
@current_user ||= User.anonymous
@current_user ||= AnonymousUser.new
end
def self.anonymous
return @anonymous_user if @anonymous_user
anonymous_user = AnonymousUser.find(:first)
if anonymous_user.nil?
anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0)
raise 'Unable to create the anonymous user.' if anonymous_user.new_record?
end
@anonymous_user = anonymous_user
AnonymousUser.new
end
private
@@ -241,17 +227,12 @@ private
end
class AnonymousUser < User
def validate_on_create
# There should be only one AnonymousUser in the database
errors.add_to_base 'An anonymous user already exists.' if AnonymousUser.find(:first)
def logged?
false
end
# Overrides a few properties
def logged?; false end
def admin; false end
def name; 'Anonymous' end
def mail; nil end
def time_zone; nil end
def rss_key; nil end
# Anonymous user has no RSS key
def rss_key
nil
end
end

View File

@@ -39,24 +39,6 @@ class Version < ActiveRecord::Base
effective_date && (effective_date <= Date.today) && (open_issues_count == 0)
end
def completed_pourcent
if fixed_issues.count == 0
0
elsif open_issues_count == 0
100
else
(closed_issues_count * 100 + Issue.sum('done_ratio', :include => 'status', :conditions => ["fixed_version_id = ? AND is_closed = ?", id, false]).to_f) / fixed_issues.count
end
end
def closed_pourcent
if fixed_issues.count == 0
0
else
closed_issues_count * 100.0 / fixed_issues.count
end
end
# Returns true if the version is overdue: due date reached and some open issues
def overdue?
effective_date && (effective_date < Date.today) && (open_issues_count > 0)

View File

@@ -25,8 +25,8 @@ class WikiContent < ActiveRecord::Base
acts_as_versioned
class Version
belongs_to :page, :class_name => '::WikiPage', :foreign_key => 'page_id'
belongs_to :author, :class_name => '::User', :foreign_key => 'author_id'
belongs_to :page, :class_name => 'WikiPage', :foreign_key => 'page_id'
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
attr_protected :data
acts_as_event :title => Proc.new {|o| "#{l(:label_wiki_edit)}: #{o.page.title} (##{o.version})"},

View File

@@ -6,7 +6,7 @@
<div class="box tabular">
<p><label for="new_password"><%=l(:field_new_password)%> <span class="required">*</span></label>
<%= password_field_tag 'new_password', nil, :size => 25 %><br />
<em><%= l(:text_caracters_minimum, 4) %></em></p>
<em><%= l(:text_length_between, 4, 12) %></em></p>
<p><label for="new_password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label>
<%= password_field_tag 'new_password_confirmation', nil, :size => 25 %></p>

View File

@@ -9,8 +9,7 @@
<%= text_field 'user', 'login', :size => 25 %></p>
<p><label for="password"><%=l(:field_password)%> <span class="required">*</span></label>
<%= password_field_tag 'password', nil, :size => 25 %><br />
<em><%= l(:text_caracters_minimum, 4) %></em></p>
<%= password_field_tag 'password', nil, :size => 25 %></p>
<p><label for="password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label>
<%= password_field_tag 'password_confirmation', nil, :size => 25 %></p>
@@ -30,6 +29,9 @@
<% for @custom_value in @custom_values %>
<p><%= custom_field_tag_with_label @custom_value %></p>
<% end %>
<p><label for="user_mail_notification"><%=l(:field_mail_notification)%></label>
<%= check_box 'user', 'mail_notification' %></p>
<!--[eoform:user]-->
</div>

View File

@@ -42,6 +42,4 @@
<p class="icon22 icon22-info">
<%= link_to l(:label_information_plural), :controller => 'admin', :action => 'info' %>
</p>
<% set_html_title l(:label_administration) -%>
</p>

View File

@@ -12,7 +12,7 @@
&nbsp;
<h3 class="icon22 icon22-plugin">Plugins</h3>
<table class="list">
<% @plugins.keys.sort {|x,y| x.to_s <=> y.to_s}.each do |plugin| %>
<% @plugins.keys.sort.each do |plugin| %>
<tr class="<%= cycle('odd', 'even') %>">
<td><%=h @plugins[plugin].name %></td>
<td><%=h @plugins[plugin].description %></td>
@@ -23,5 +23,3 @@
<% end %>
</table>
<% end %>
<% set_html_title(l(:label_information_plural)) -%>

View File

@@ -6,28 +6,17 @@
<% form_tag({:action => 'mail_options'}, :id => 'mail-options-form') do %>
<fieldset class="box tabular settings"><legend><%=l(:label_settings)%></legend>
<p><label><%= l(:setting_mail_from) %></label>
<%= text_field_tag 'settings[mail_from]', Setting.mail_from, :size => 60 %></p>
<p><label><%= l(:setting_bcc_recipients) %></label>
<%= check_box_tag 'settings[bcc_recipients]', 1, Setting.bcc_recipients? %>
<%= hidden_field_tag 'settings[bcc_recipients]', 0 %></p>
</fieldset>
<fieldset class="box"><legend><%=l(:text_select_mail_notifications)%></legend>
<% @notifiables.each do |notifiable| %>
<label><%= check_box_tag 'settings[notified_events][]', notifiable, Setting.notified_events.include?(notifiable) %>
<label><%= check_box_tag "notified_events[]", notifiable, Setting.notified_events.include?(notifiable) %>
<%= notifiable.humanize %></label><br />
<% end %>
<p><%= check_all_links('mail-options-form') %></p>
</fieldset>
<fieldset class="box"><legend><%= l(:setting_emails_footer) %></legend>
<%= text_area_tag 'settings[emails_footer]', Setting.emails_footer, :class => 'wiki-edit', :rows => 5 %>
<%= text_area_tag 'emails_footer', Setting.emails_footer, :class => 'wiki-edit', :rows => 5 %>
</fieldset>
<%= submit_tag l(:button_save) %>
<% end %>
<% set_html_title(l(:field_mail_notification)) -%>

View File

@@ -26,7 +26,7 @@
<tbody>
<% for project in @projects %>
<tr class="<%= cycle("odd", "even") %>">
<td><%= project.active? ? link_to(h(project.name), :controller => 'projects', :action => 'settings', :id => project) : h(project.name) %>
<td><%= project.active? ? link_to(project.name, :controller => 'projects', :action => 'settings', :id => project) : h(project.name) %>
<td><%= textilizable project.description, :project => project %>
<td align="center"><%= image_tag 'true.png' if project.is_public? %>
<td align="center"><%= project.children.size %>
@@ -47,5 +47,3 @@
<p><%= pagination_links_full @project_pages, :status => @status %>
[ <%= @project_pages.current.first_item %> - <%= @project_pages.current.last_item %> / <%= @project_count %> ]</p>
<% set_html_title l(:label_project_plural) -%>

View File

@@ -15,10 +15,7 @@
<%= text_field 'auth_source', 'account' %></p>
<p><label for="auth_source_account_password"><%=l(:field_password)%></label>
<%= password_field 'auth_source', 'account_password', :name => 'ignore',
:value => ((@auth_source.new_record? || @auth_source.account_password.blank?) ? '' : ('x'*15)),
:onfocus => "this.value=''; this.name='auth_source[account_password]';",
:onchange => "this.name='auth_source[account_password]';" %></p>
<%= password_field 'auth_source', 'account_password' %></p>
<p><label for="auth_source_base_dn"><%=l(:field_base_dn)%> <span class="required">*</span></label>
<%= text_field 'auth_source', 'base_dn', :size => 60 %></p>

View File

@@ -19,7 +19,7 @@
<td>
<small>
<% if board.last_message %>
<%= authoring board.last_message.created_on, board.last_message.author %><br />
<%= board.last_message.author.name %>, <%= format_time(board.last_message.created_on) %><br />
<%= link_to_message board.last_message %>
<% end %>
</small>

View File

@@ -18,7 +18,7 @@
<h2><%=h @board.name %></h2>
<% if @topics.any? %>
<table class="list messages">
<table class="list">
<thead><tr>
<th><%= l(:field_subject) %></th>
<th><%= l(:field_author) %></th>
@@ -28,16 +28,18 @@
</tr></thead>
<tbody>
<% @topics.each do |topic| %>
<tr class="message <%= cycle 'odd', 'even' %> <%= topic.sticky? ? 'sticky' : '' %> <%= topic.locked? ? 'locked' : '' %>">
<td class="subject"><%= link_to h(topic.subject), { :controller => 'messages', :action => 'show', :board_id => @board, :id => topic }, :class => 'icon' %></td>
<td class="author" align="center"><%= topic.author %></td>
<td class="created_on" align="center"><%= format_time(topic.created_on) %></td>
<td class="replies" align="center"><%= topic.replies_count %></td>
<td class="last_message">
<tr class="<%= cycle 'odd', 'even' %>">
<td><%= link_to h(topic.subject), :controller => 'messages', :action => 'show', :board_id => @board, :id => topic %></td>
<td align="center"><%= link_to_user topic.author %></td>
<td align="center"><%= format_time(topic.created_on) %></td>
<td align="center"><%= topic.replies_count %></td>
<td>
<small>
<% if topic.last_reply %>
<%= authoring topic.last_reply.created_on, topic.last_reply.author %><br />
<%= topic.last_reply.author.name %>, <%= format_time(topic.last_reply.created_on) %><br />
<%= link_to_message topic.last_reply %>
<% end %>
</small>
</td>
</tr>
<% end %>

View File

@@ -7,32 +7,21 @@ function toggle_custom_field_format() {
p_length = $("custom_field_min_length");
p_regexp = $("custom_field_regexp");
p_values = $("custom_field_possible_values");
p_searchable = $("custom_field_searchable");
switch (format.value) {
case "list":
Element.hide(p_length.parentNode);
Element.hide(p_regexp.parentNode);
Element.show(p_searchable.parentNode);
Element.show(p_values);
break;
case "date":
case "bool":
Element.hide(p_length.parentNode);
Element.hide(p_regexp.parentNode);
Element.hide(p_searchable.parentNode);
Element.hide(p_values);
break;
case "float":
case "int":
Element.show(p_length.parentNode);
Element.show(p_regexp.parentNode);
Element.hide(p_searchable.parentNode);
Element.hide(p_values);
break;
default:
Element.show(p_length.parentNode);
Element.show(p_regexp.parentNode);
Element.show(p_searchable.parentNode);
Element.hide(p_values);
break;
}
@@ -58,6 +47,7 @@ function deleteValueField(e) {
//]]>
</script>
<!--[form:custom_field]-->
<div class="box">
<p><%= f.text_field :name, :required => true %></p>
<p><%= f.select :field_format, custom_field_formats_for_select, {}, :onchange => "toggle_custom_field_format();" %></p>
@@ -69,8 +59,11 @@ function deleteValueField(e) {
<% (@custom_field.possible_values.to_a + [""]).each do |value| %>
<span><%= text_field_tag 'custom_field[possible_values][]', value, :size => 30 %> <%= image_to_function "delete.png", "deleteValueField(this);return false" %><br /></span>
<% end %>
</p>
</div>
<%= javascript_tag "toggle_custom_field_format();" %>
<!--[eoform:custom_field]-->
<div class="box">
<% case @custom_field.type.to_s
@@ -85,7 +78,6 @@ when "IssueCustomField" %>
<p><%= f.check_box :is_required %></p>
<p><%= f.check_box :is_for_all %></p>
<p><%= f.check_box :is_filter %></p>
<p><%= f.check_box :searchable %></p>
<% when "UserCustomField" %>
<p><%= f.check_box :is_required %></p>
@@ -95,4 +87,3 @@ when "IssueCustomField" %>
<% end %>
</div>
<%= javascript_tag "toggle_custom_field_format();" %>

View File

@@ -19,11 +19,10 @@
<th><%=l(:field_is_for_all)%></th>
<th><%=l(:label_used_by)%></th>
<% end %>
<th><%=l(:button_sort)%></th>
<th width="10%"></th>
</tr></thead>
<tbody>
<% for custom_field in (@custom_fields_by_type[type] || []).sort %>
<% for custom_field in (@custom_fields_by_type[type] || []) %>
<tr class="<%= cycle("odd", "even") %>">
<td><%= link_to custom_field.name, :action => 'edit', :id => custom_field %></td>
<td align="center"><%= l(CustomField::FIELD_FORMATS[custom_field.field_format][:name]) %></td>
@@ -32,12 +31,6 @@
<td align="center"><%= image_tag 'true.png' if 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>
<% end %>
<td align="center" style="width:15%;">
<%= link_to image_tag('2uparrow.png', :alt => l(:label_sort_highest)), {:action => 'move', :id => custom_field, :position => 'highest'}, :method => :post, :title => l(:label_sort_highest) %>
<%= link_to image_tag('1uparrow.png', :alt => l(:label_sort_higher)), {:action => 'move', :id => custom_field, :position => 'higher'}, :method => :post, :title => l(:label_sort_higher) %> -
<%= link_to image_tag('1downarrow.png', :alt => l(:label_sort_lower)), {:action => 'move', :id => custom_field, :position => 'lower'}, :method => :post, :title => l(:label_sort_lower) %>
<%= link_to image_tag('2downarrow.png', :alt => l(:label_sort_lowest)), {:action => 'move', :id => custom_field, :position => 'lowest'}, :method => :post, :title => l(:label_sort_lowest) %>
</td>
<td align="center">
<%= button_to l(:button_delete), { :action => 'destroy', :id => custom_field }, :confirm => l(:text_are_you_sure), :class => "button-small" %>
</td>
@@ -50,6 +43,4 @@
</div>
<% end %>
<%= javascript_tag "showTab('#{@tab}');" %>
<% set_html_title(l(:label_custom_field_plural)) -%>
<%= javascript_tag "showTab('#{@tab}');" %>

View File

@@ -3,9 +3,9 @@
<%= link_to_if_authorized l(:button_delete), {:controller => 'documents', :action => 'destroy', :id => @document}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %>
</div>
<h2><%=h @document.title %></h2>
<h2><%= @document.title %></h2>
<p><em><%=h @document.category.name %><br />
<p><em><%= @document.category.name %><br />
<%= format_date @document.created_on %></em></p>
<%= textilizable @document.description, :attachments => @document.attachments %>
<br />
@@ -34,5 +34,3 @@
<%= submit_tag l(:button_add) %>
<% end %>
<% end %>
<% set_html_title h(@document.title) -%>

View File

@@ -24,5 +24,3 @@
<p><%= link_to l(:label_enumeration_new), { :action => 'new', :opt => option } %></p>
<% end %>
<% set_html_title(l(:label_enumerations)) -%>

View File

@@ -0,0 +1,28 @@
xml.instruct!
xml.rss "version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/" do
xml.channel do
xml.title @title
xml.link url_for(:controller => 'welcome', :only_path => false)
xml.pubDate CGI.rfc1123_date(@journals.first ? @journals.first.created_on : Time.now)
xml.description l(:label_changes_details)
@journals.each do |journal|
issue = journal.issue
xml.item do
xml.title "#{issue.project.name} - #{issue.tracker.name} ##{issue.id}: #{issue.subject}"
url = url_for(:controller => 'issues' , :action => 'show', :id => issue, :only_path => false)
xml.link url
xml.description do
xml.text! h(journal.notes)
xml.text! "<ul>"
journal.details.each do |detail|
xml.text! "<li>" + show_detail(detail, false) + "</li>"
end
xml.text! "</ul>"
end
xml.pubDate CGI.rfc1123_date(journal.created_on)
xml.guid url
xml.author h(journal.user.name)
end
end
end
end

View File

@@ -4,26 +4,24 @@ xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
xml.link "rel" => "self", "href" => url_for(:controller => 'feeds', :action => 'history', :format => 'atom', :only_path => false)
xml.link "rel" => "alternate", "href" => url_for(:controller => 'welcome', :only_path => false)
xml.id url_for(:controller => 'welcome', :only_path => false)
xml.updated((@changes.first ? @changes.first.event_datetime : Time.now).xmlschema)
xml.updated CGI.rfc1123_date(@journals.first.created_on) if @journals.any?
xml.author { xml.name "#{Setting.app_title}" }
@changes.each do |change|
issue = change.issue
@journals.each do |journal|
issue = journal.issue
xml.entry do
xml.title "#{issue.project.name} - #{issue.tracker.name} ##{issue.id}: #{issue.subject}"
xml.link "rel" => "alternate", "href" => url_for(:controller => 'issues' , :action => 'show', :id => issue, :only_path => false)
xml.id url_for(:controller => 'issues' , :action => 'show', :id => issue, :journal_id => change, :only_path => false)
xml.updated change.created_on.xmlschema
xml.author do
xml.name change.user.name
xml.email(change.user.mail)
end
xml.id url_for(:controller => 'issues' , :action => 'show', :id => issue, :only_path => false)
xml.updated CGI.rfc1123_date(journal.created_on)
xml.author { xml.name journal.user.name }
xml.summary journal.notes
xml.content "type" => "html" do
xml.text! '<ul>'
change.details.each do |detail|
xml.text! '<li>' + show_detail(detail, false) + '</li>'
xml.text! journal.notes if journal.notes
xml.text! "<ul>"
journal.details.each do |detail|
xml.text! "<li>" + show_detail(detail, false) + "</li>"
end
xml.text! '</ul>'
xml.text! textilizable(change.notes) unless change.notes.blank?
xml.text! "</ul>"
end
end
end

View File

@@ -0,0 +1,20 @@
xml.instruct!
xml.rss "version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/" do
xml.channel do
xml.title @title
xml.link url_for(:controller => 'welcome', :only_path => false)
xml.pubDate CGI.rfc1123_date(@issues.first ? @issues.first.created_on : Time.now)
xml.description l(:label_reported_issues)
@issues.each do |issue|
xml.item do
xml.title "#{issue.project.name} - #{issue.tracker.name} ##{issue.id}: #{issue.subject}"
url = url_for(:controller => 'issues' , :action => 'show', :id => issue, :only_path => false)
xml.link url
xml.description h(issue.description)
xml.pubDate CGI.rfc1123_date(issue.created_on)
xml.guid url
xml.author h(issue.author.name)
end
end
end
end

View File

@@ -0,0 +1,22 @@
xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
xml.title @title
xml.link "rel" => "self", "href" => url_for(:controller => 'feeds', :action => 'issues', :format => 'atom', :only_path => false)
xml.link "rel" => "alternate", "href" => url_for(:controller => 'welcome', :only_path => false)
xml.id url_for(:controller => 'welcome', :only_path => false)
xml.updated CGI.rfc1123_date(@issues.first.updated_on) if @issues.any?
xml.author { xml.name "#{Setting.app_title}" }
@issues.each do |issue|
xml.entry do
xml.title "#{issue.project.name} - #{issue.tracker.name} ##{issue.id}: #{issue.subject}"
xml.link "rel" => "alternate", "href" => url_for(:controller => 'issues' , :action => 'show', :id => issue, :only_path => false)
xml.id url_for(:controller => 'issues' , :action => 'show', :id => issue, :only_path => false)
xml.updated CGI.rfc1123_date(issue.updated_on)
xml.author { xml.name issue.author.name }
xml.summary issue.description
xml.content "type" => "html" do
xml.text! issue.description
end
end
end
end

20
app/views/feeds/news.rxml Normal file
View File

@@ -0,0 +1,20 @@
xml.instruct!
xml.rss "version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/" do
xml.channel do
xml.title "#{Setting.app_title}: #{l(:label_news_latest)}"
xml.link url_for(:controller => 'welcome', :only_path => false)
xml.pubDate CGI.rfc1123_date(@news.first ? @news.first.created_on : Time.now)
xml.description l(:label_news_latest)
@news.each do |news|
xml.item do
xml.title "#{news.project.name}: #{news.title}"
news_url = url_for(:controller => 'news' , :action => 'show', :id => news, :only_path => false)
xml.link news_url
xml.description h(news.summary)
xml.pubDate CGI.rfc1123_date(news.created_on)
xml.guid news_url
xml.author h(news.author.name)
end
end
end
end

View File

@@ -0,0 +1,22 @@
xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
xml.title "#{Setting.app_title}: #{l(:label_news_latest)}"
xml.link "rel" => "self", "href" => url_for(:controller => 'feeds', :action => 'news', :format => 'atom', :only_path => false)
xml.link "rel" => "alternate", "href" => url_for(:controller => 'welcome', :only_path => false)
xml.id url_for(:controller => 'welcome', :only_path => false)
xml.updated CGI.rfc1123_date(@news.first.created_on) if @news.any?
xml.author { xml.name "#{Setting.app_title}" }
@news.each do |news|
xml.entry do
xml.title news.title
xml.link "rel" => "alternate", "href" => url_for(:controller => 'news' , :action => 'show', :id => news, :only_path => false)
xml.id url_for(:controller => 'news' , :action => 'show', :id => news, :only_path => false)
xml.updated CGI.rfc1123_date(news.created_on)
xml.author { xml.name news.author.name }
xml.summary h(news.summary)
xml.content "type" => "html" do
xml.text! news.description
end
end
end
end

View File

@@ -32,6 +32,4 @@
</tbody>
</table>
<%= pagination_links_full @issue_status_pages %>
<% set_html_title(l(:label_issue_status_plural)) -%>
<%= pagination_links_full @issue_status_pages %>

View File

@@ -7,14 +7,14 @@
</tr></thead>
<tbody>
<% for issue in issues %>
<tr id="issue-<%= issue.id %>" class="issue hascontextmenu <%= cycle('odd', 'even') %> <%= "status-#{issue.status.position} priority-#{issue.priority.position}" %>">
<tr class="<%= cycle("odd", "even") %> <%= "status-#{issue.status.position} priority-#{issue.priority.position}" %>">
<td class="id">
<%= link_to issue.id, :controller => 'issues', :action => 'show', :id => issue %>
</td>
<td><%=h issue.project.name %> - <%= issue.tracker.name %><br />
<%= issue.status.name %> - <%= format_time(issue.updated_on) %></td>
<td class="subject">
<%= link_to h(issue.subject), :controller => 'issues', :action => 'show', :id => issue %>
<td><p class="small"><%= issue.project.name %> - <%= issue.tracker.name %><br />
<%= issue.status.name %> - <%= format_time(issue.updated_on) %></p></td>
<td>
<p class="small"><%= link_to h(issue.subject), :controller => 'issues', :action => 'show', :id => issue %></p>
</td>
</tr>
<% end %>

View File

@@ -1,10 +1,10 @@
<% if authorize_for('projects', 'add_issue') && @project.trackers.any? %>
<% if authorize_for('projects', 'add_issue') %>
<h3><%= l(:label_issue_new) %></h3>
<%= l(:label_tracker) %>: <%= new_issue_selector %>
<% end %>
<h3><%= l(:label_issue_plural) %></h3>
<%= link_to l(:label_issue_view_all), { :controller => 'issues', :action => 'index', :project_id => @project, :set_filter => 1 } %><br />
<%= link_to l(:label_issue_view_all), :controller => 'projects', :action => 'list_issues', :id => @project, :set_filter => 1 %><br />
<%= link_to l(:field_summary), :controller => 'reports', :action => 'issue_report', :id => @project %><br />
<%= link_to l(:label_change_log), :controller => 'projects', :action => 'changelog', :id => @project %>
@@ -14,5 +14,5 @@
:order => "name ASC",
:conditions => ["is_public = ? or user_id = ?", true, (User.current.logged? ? User.current.id : 0)])
queries.each do |query| %>
<%= link_to query.name, :controller => 'issues', :action => 'index', :project_id => @project, :query_id => query %><br />
<%= link_to query.name, :controller => 'projects', :action => 'list_issues', :id => @project, :query_id => query %><br />
<% end %>

View File

@@ -29,9 +29,11 @@
<p><label for="notes"><%= l(:field_notes) %></label>
<%= text_area_tag 'notes', @notes, :cols => 60, :rows => 10, :class => 'wiki-edit' %></p>
<% if authorize_for('issues', 'add_attachment') %>
<p id="attachments_p"><label><%=l(:label_attachment_new)%>
<%= image_to_function "add.png", "addFileField();return false" %></label>
<%= file_field_tag 'attachments[]', :size => 30 %> <em>(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>)</em></p>
<% end %>
</div>
<%= submit_tag l(:button_save) %>

View File

@@ -1,4 +1,4 @@
<% back_to = url_for(:controller => 'issues', :action => 'index', :project_id => @project) %>
<% back_to = url_for(:controller => 'projects', :action => 'list_issues', :id => @project) %>
<ul>
<li><%= context_menu_link l(:button_edit), {:controller => 'issues', :action => 'edit', :id => @issue},
:class => 'icon-edit', :disabled => !@can[:edit] %></li>
@@ -32,7 +32,7 @@
</ul>
</li>
<li><%= context_menu_link l(:button_copy), {:controller => 'projects', :action => 'add_issue', :id => @project, :copy_from => @issue},
:class => 'icon-copy', :disabled => !@can[:copy] %></li>
:class => 'icon-copy', :disabled => !@can[:add] %></li>
<li><%= context_menu_link l(:button_move), {:controller => 'projects', :action => 'move_issues', :id => @project, "issue_ids[]" => @issue.id },
:class => 'icon-move', :disabled => !@can[:move] %>
<li><%= context_menu_link l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue},

View File

@@ -1,73 +1,35 @@
<% if @query.new_record? %>
<h2><%=l(:label_issue_plural)%></h2>
<% set_html_title l(:label_issue_plural) %>
<h2><%=l(:label_issue_plural)%></h2>
<% form_tag({ :controller => 'queries', :action => 'new' }, :id => 'query_form') do %>
<%= hidden_field_tag('project_id', @project.id) if @project %>
<%= render :partial => 'queries/filters', :locals => {:query => @query} %>
<div class="contextual">
<%= link_to_remote l(:button_apply),
{ :url => { :set_filter => 1 },
:update => "content",
:with => "Form.serialize('query_form')"
}, :class => 'icon icon-checked' %>
<%= link_to_remote l(:button_clear),
{ :url => { :set_filter => 1 },
:update => "content",
}, :class => 'icon icon-reload' %>
<% if current_role && current_role.allowed_to?(:save_queries) %>
<%= link_to l(:button_save), {}, :onclick => "$('query_form').submit(); return false;", :class => 'icon icon-save' %>
<% end %>
</div>
<br />
&nbsp;
<% end %>
<% else %>
<div class="contextual">
<% if @query.editable_by?(User.current) %>
<%= link_to l(:button_edit), {:controller => 'queries', :action => 'edit', :id => @query}, :class => 'icon icon-edit' %>
<%= link_to l(:button_delete), {:controller => 'queries', :action => 'destroy', :id => @query}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %>
<% end %>
</div>
<h2><%= @query.name %></h2>
<div id="query_form"></div>
<% set_html_title @query.name %>
<% form_tag({}, :id => 'query_form') do %>
<%= render :partial => 'queries/filters', :locals => {:query => @query} %>
<% end %>
<div class="contextual">
<%= link_to_remote l(:button_apply),
{ :url => { :set_filter => 1 },
:update => "content",
:with => "Form.serialize('query_form')"
}, :class => 'icon icon-edit' %>
<%= link_to_remote l(:button_clear),
{ :url => { :set_filter => 1 },
:update => "content",
}, :class => 'icon icon-reload' %>
</div>
<br />&nbsp;
<%= error_messages_for 'query' %>
<% if @query.valid? %>
<% if @issues.empty? %>
<p class="nodata"><%= l(:label_no_data) %></p>
<p><i><%= l(:label_no_data) %></i></p>
<% else %>
<% form_tag({:controller => 'projects', :action => 'bulk_edit_issues', :id => @project}, :id => 'issues_form', :onsubmit => "if (!checkBulkEdit(this)) {alert('#{l(:notice_no_issue_selected)}'); return false;}" ) do %>
&nbsp;
<%= render :partial => 'issues/list', :locals => {:issues => @issues, :query => @query} %>
<div class="contextual">
<%= l(:label_export_to) %>
<%= link_to 'CSV', {:format => 'csv'}, :class => 'icon icon-csv' %>,
<%= link_to 'PDF', {:format => 'pdf'}, :class => 'icon icon-pdf' %>
</div>
<p><%= pagination_links_full @issue_pages %>
[ <%= @issue_pages.current.first_item %> - <%= @issue_pages.current.last_item %> / <%= @issue_count %> ]</p>
<% end %>
<% end %>
<% end %>
<% content_for :sidebar do %>
<%= render :partial => 'issues/sidebar' %>
<% end if @project%>
<% content_for :header_tags do %>
<%= auto_discovery_link_tag(:atom, {:query_id => @query, :format => 'atom', :page => nil, :key => User.current.rss_key}, :title => l(:label_issue_plural)) %>
<%= auto_discovery_link_tag(:atom, {:action => 'changes', :query_id => @query, :format => 'atom', :page => nil, :key => User.current.rss_key}, :title => l(:label_changes_details)) %>
<%= javascript_include_tag 'calendar/calendar' %>
<%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
<%= javascript_include_tag 'calendar/calendar-setup' %>
<%= stylesheet_link_tag 'calendar' %>
<%= javascript_include_tag 'context_menu' %>
<%= stylesheet_link_tag 'context_menu' %>
<%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :page => nil, :key => User.current.rss_key})) %>
<% end %>
<div id="context-menu" style="display: none;"></div>
<%= javascript_tag 'new ContextMenu({})' %>

View File

@@ -10,7 +10,7 @@
<h2><%= @issue.tracker.name %> #<%= @issue.id %></h2>
<div class="issue <%= "status-#{@issue.status.position} priority-#{@issue.priority.position}" %>">
<div class="issue">
<h3><%=h @issue.subject %></h3>
<p class="author">
<%= authoring @issue.created_on, @issue.author %>.
@@ -28,7 +28,7 @@
</tr>
<tr>
<td><b><%=l(:field_assigned_to)%> :</b></td><td><%= @issue.assigned_to ? link_to_user(@issue.assigned_to) : "-" %></td>
<td><b><%=l(:field_done_ratio)%> :</b></td><td><%= progress_bar @issue.done_ratio, :width => '80px', :legend => "#{@issue.done_ratio}%" %></td>
<td><b><%=l(:field_done_ratio)%> :</b></td><td><%= @issue.done_ratio %> %</td>
</tr>
<tr>
<td><b><%=l(:field_category)%> :</b></td><td><%=h @issue.category ? @issue.category.name : "-" %></td>
@@ -64,7 +64,7 @@ end %>
<% end %>
<p><strong><%=l(:field_description)%></strong></p>
<%= textilizable @issue, :description, :attachments => @issue.attachments %>
<%= textilizable @issue.description, :attachments => @issue.attachments %>
<% if @issue.attachments.any? %>
<%= link_to_attachments @issue.attachments, :delete_url => (authorize_for('issues', 'destroy_attachment') ? {:controller => 'issues', :action => 'destroy_attachment', :id => @issue} : nil) %>

View File

@@ -1,12 +1,12 @@
<% user_projects_by_root = User.current.projects.find(:all, :include => :parent).group_by(&:root) %>
<select onchange="if (this.value != '') { window.location = this.value; }">
<option selected="selected"><%= l(:label_jump_to_a_project) %></option>
<option disabled="disabled">---</option>
<option selected><%= l(:label_jump_to_a_project) %></option>
<option disabled>---</option>
<% user_projects_by_root.keys.sort.each do |root| %>
<%= content_tag('option', h(root.name), :value => url_for(:controller => 'projects', :action => 'show', :id => root)) %>
<%= content_tag('option', root.name, :value => url_for(:controller => 'projects', :action => 'show', :id => root)) %>
<% user_projects_by_root[root].sort.each do |project| %>
<% next if project == root %>
<%= content_tag('option', ('&#187; ' + h(project.name)), :value => url_for(:controller => 'projects', :action => 'show', :id => project)) %>
<%= content_tag('option', ('&#187; ' + project.name), :value => url_for(:controller => 'projects', :action => 'show', :id => project)) %>
<% end %>
<% end %>
</select>

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.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">
<head>
<title><%=h html_title %></title>
@@ -22,18 +22,18 @@
<div id="account">
<% if User.current.logged? %>
<%=l(:label_logged_as)%> <%= User.current.login %> -
<%= link_to l(:label_my_account), { :controller => 'my', :action => 'account' }, :class => 'myaccount' %>
<%= link_to l(:label_logout), { :controller => 'account', :action => 'logout' }, :class => 'logout' %>
<%= link_to l(:label_my_account), { :controller => 'my', :action => 'account' } %>
<%= link_to l(:label_logout), { :controller => 'account', :action => 'logout' } %>
<% else %>
<%= link_to l(:label_login), { :controller => 'account', :action => 'login' }, :class => 'signin' %>
<%= link_to(l(:label_register), { :controller => 'account',:action => 'register' }, :class => 'register') if Setting.self_registration? %>
<%= link_to l(:label_login), { :controller => 'account', :action => 'login' } %>
<%= link_to(l(:label_register), :controller => 'account',:action => 'register') if Setting.self_registration? %>
<% end %>
</div>
<%= link_to l(:label_home), home_url, :class => 'home' %>
<%= link_to l(:label_my_page), { :controller => 'my', :action => 'page'}, :class => 'mypage' if User.current.logged? %>
<%= link_to l(:label_project_plural), { :controller => 'projects' }, :class => 'projects' %>
<%= link_to l(:label_administration), { :controller => 'admin' }, :class => 'admin' if User.current.admin? %>
<%= link_to l(:label_help), Redmine::Info.help_url, :class => 'help' %>
<%= link_to l(:label_home), home_url %>
<%= link_to l(:label_my_page), { :controller => 'my', :action => 'page'} if User.current.logged? %>
<%= link_to l(:label_project_plural), { :controller => 'projects' } %>
<%= link_to l(:label_administration), { :controller => 'admin' } if User.current.admin? %>
<%= link_to l(:label_help), Redmine::Info.help_url %>
</div>
<div id="header">
@@ -73,7 +73,7 @@
<div id="ajax-indicator" style="display:none;"><span><%= l(:label_loading) %></span></div>
<div id="footer">
Powered by <%= link_to Redmine::Info.app_name, Redmine::Info.url %> <%= Redmine::VERSION %> &copy; 2006-2007 Jean-Philippe Lang
Powered by <%= link_to Redmine::Info.app_name, Redmine::Info.url %> <%= Redmine::VERSION %> &copy 2006-2007 Jean-Philippe Lang
</div>
</body>
</html>

View File

@@ -1,2 +0,0 @@
<p><%= l(:mail_body_account_activation_request, @user.login) %></p>
<p><%= link_to @url, @url %></p>

View File

@@ -1,2 +0,0 @@
<%= l(:mail_body_account_activation_request, @user.login) %>
<%= @url %>

View File

@@ -1,3 +1,3 @@
<%= l(:text_issue_added, "##{@issue.id}") %>
<hr />
<%= render :partial => "issue_text_html", :locals => { :issue => @issue, :issue_url => @issue_url } %>
<%= render :file => "_issue_text_html", :use_full_path => true, :locals => { :issue => @issue, :issue_url => @issue_url } %>

View File

@@ -1,3 +1,3 @@
<%= l(:text_issue_added, "##{@issue.id}") %>
----------------------------------------
<%= render :partial => "issue_text_plain", :locals => { :issue => @issue, :issue_url => @issue_url } %>
<%= render :file => "_issue_text_plain", :use_full_path => true, :locals => { :issue => @issue, :issue_url => @issue_url } %>

View File

@@ -7,4 +7,4 @@
</ul>
<%= textilizable(@journal.notes) %>
<hr />
<%= render :partial => "issue_text_html", :locals => { :issue => @issue, :issue_url => @issue_url } %>
<%= render :file => "_issue_text_html", :use_full_path => true, :locals => { :issue => @issue, :issue_url => @issue_url } %>

View File

@@ -5,4 +5,4 @@
<% end %>
<%= @journal.notes if @journal.notes? %>
----------------------------------------
<%= render :partial => "issue_text_plain", :locals => { :issue => @issue, :issue_url => @issue_url } %>
<%= render :file => "_issue_text_plain", :use_full_path => true, :locals => { :issue => @issue, :issue_url => @issue_url } %>

View File

@@ -1,4 +1,4 @@
<h1><%=h @message.board.project.name %> - <%=h @message.board.name %>: <%= link_to @message.subject, @message_url %></h1>
<em><%= @message.author %></em>
<em><%= @message.author.name %></em>
<%= textilizable @message.content %>

View File

@@ -1,4 +1,4 @@
<%= @message_url %>
<%= @message.author %>
<%= @message.author.name %>
<%= @message.content %>

View File

@@ -3,19 +3,12 @@
<div class="box">
<!--[form:message]-->
<p><label><%= l(:field_subject) %></label><br />
<%= f.text_field :subject, :required => true, :size => 120 %>
<%= f.text_field :subject, :required => true, :size => 120 %></p>
<% if User.current.allowed_to?(:edit_messages, @project) %>
<label><%= f.check_box :sticky %> Sticky</label>
<label><%= f.check_box :locked %> Locked</label>
<% end %>
</p>
<p><%= f.text_area :content, :required => true, :cols => 80, :rows => 15, :class => 'wiki-edit', :id => 'message_content' %></p>
<p><%= f.text_area :content, :required => true, :cols => 80, :rows => 15, :class => 'wiki-edit' %></p>
<%= wikitoolbar_for 'message_content' %>
<!--[eoform:message]-->
<span class="tabular">
<%= render :partial => 'attachments/form' %>
</span>
</div>

View File

@@ -1,6 +0,0 @@
<h2><%= link_to h(@board.name), :controller => 'boards', :action => 'show', :project_id => @project, :id => @board %> &#187; <%=h @message.subject %></h2>
<% form_for :message, @message, :url => {:action => 'edit'}, :html => {:multipart => true} do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %>
<%= submit_tag l(:button_save) %>
<% end %>

View File

@@ -1,39 +1,27 @@
<div class="contextual">
<%= link_to_if_authorized l(:button_edit), {:action => 'edit', :id => @topic}, :class => 'icon icon-edit' %>
<%= link_to_if_authorized l(:button_delete), {:action => 'destroy', :id => @topic}, :method => :post, :confirm => l(:text_are_you_sure), :class => 'icon icon-del' %>
</div>
<h2><%= link_to h(@board.name), :controller => 'boards', :action => 'show', :project_id => @project, :id => @board %> &#187; <%=h @message.subject %></h2>
<h2><%= link_to h(@board.name), :controller => 'boards', :action => 'show', :project_id => @project, :id => @board %> &#187; <%=h @topic.subject %></h2>
<div class="message">
<p><span class="author"><%= authoring @topic.created_on, @topic.author %></span></p>
<p><span class="author"><%= authoring @message.created_on, @message.author %></span></p>
<div class="wiki">
<%= textilizable(@topic.content, :attachments => @topic.attachments) %>
</div>
<%= link_to_attachments @topic.attachments, :no_author => true %>
<%= textilizable(@message.content, :attachments => @message.attachments) %>
</div>
<%= link_to_attachments @message.attachments, :no_author => true %>
<br />
<h3 class="icon22 icon22-comment"><%= l(:label_reply_plural) %></h3>
<% @topic.children.each do |message| %>
<% @message.children.each do |message| %>
<a name="<%= "message-#{message.id}" %>"></a>
<div class="contextual">
<%= link_to_if_authorized l(:button_edit), {:action => 'edit', :id => message}, :class => 'icon icon-edit' %>
<%= link_to_if_authorized l(:button_delete), {:action => 'destroy', :id => message}, :method => :post, :confirm => l(:text_are_you_sure), :class => 'icon icon-del' %>
</div>
<div class="message reply">
<h4><%=h message.subject %> - <%= authoring message.created_on, message.author %></h4>
<h4><%=h message.subject %> - <%= message.author.name %>, <%= format_time(message.created_on) %></h4>
<div class="wiki"><%= textilizable message.content %></div>
<%= link_to_attachments message.attachments, :no_author => true %>
</div>
<% end %>
<% if !@topic.locked? && authorize_for('messages', 'reply') %>
<p><%= toggle_link l(:button_reply), "reply", :focus => 'message_content' %></p>
<% if authorize_for('messages', 'reply') %>
<p><%= toggle_link l(:button_reply), "reply", :focus => "reply_content" %></p>
<div id="reply" style="display:none;">
<% form_for :reply, @reply, :url => {:action => 'reply', :id => @topic}, :html => {:multipart => true} do |f| %>
<%= render :partial => 'form', :locals => {:f => f} %>
<%= submit_tag l(:button_submit) %>
<%= error_messages_for 'message' %>
<% form_for :reply, @reply, :url => {:action => 'reply', :id => @message} do |f| %>
<p><%= f.text_field :subject, :required => true, :size => 60 %></p>
<p><%= f.text_area :content, :required => true, :cols => 80, :rows => 10 %></p>
<p><%= submit_tag l(:button_submit) %></p>
<% end %>
</div>
<% end %>

View File

@@ -4,10 +4,7 @@
<h2><%=l(:label_my_account)%></h2>
<%= error_messages_for 'user' %>
<% form_for :user, @user, :url => { :action => "account" },
:builder => TabularFormBuilder,
:lang => current_language,
:html => { :id => 'my_account_form' } do |f| %>
<% form_for :user, @user, :url => { :action => "account" }, :builder => TabularFormBuilder, :lang => current_language do |f| %>
<div class="splitcontentleft">
<h3><%=l(:label_information_plural)%></h3>
<div class="box tabular">
@@ -17,7 +14,6 @@
<p><%= f.select :language, lang_options_for_select %></p>
<% fields_for :pref, @user.pref, :builder => TabularFormBuilder, :lang => current_language do |pref_fields| %>
<p><%= pref_fields.select :time_zone, TimeZone.all.collect {|z| [ z.to_s, z.name ]}, :include_blank => true %></p>
<p><%= pref_fields.check_box :hide_mail %></p>
<% end %>
</div>
@@ -32,11 +28,10 @@
:onchange => 'if ($("notification_option").value == "selected") {Element.show("notified-projects")} else {Element.hide("notified-projects")}' %>
<% content_tag 'div', :id => 'notified-projects', :style => (@notification_option == 'selected' ? '' : 'display:none;') do %>
<p><% User.current.projects.each do |project| %>
<label><%= check_box_tag 'notified_project_ids[]', project.id, @user.notified_projects_ids.include?(project.id) %> <%=h project.name %></label><br />
<label><%= check_box_tag 'notified_project_ids[]', project.id, @user.notified_projects_ids.include?(project.id) %> <%= project.name %></label><br />
<% end %></p>
<p><em><%= l(:text_user_mail_option) %></em></p>
<% end %>
<p><label><%= check_box_tag 'no_self_notified', 1, @user.pref[:no_self_notified] %> <%= l(:label_user_mail_no_self_notified) %></label></p>
</div>
</div>
<% end %>
@@ -44,5 +39,3 @@
<% content_for :sidebar do %>
<%= render :partial => 'sidebar' %>
<% end %>
<% set_html_title l(:label_my_account) -%>

View File

@@ -31,12 +31,3 @@
<% end if @blocks['right'] %>
</div>
<% content_for :header_tags do %>
<%= javascript_include_tag 'context_menu' %>
<%= stylesheet_link_tag 'context_menu' %>
<% end %>
<div id="context-menu" style="display: none;"></div>
<%= javascript_tag 'new ContextMenu({})' %>
<% set_html_title l(:label_my_page) -%>

View File

@@ -9,7 +9,7 @@
<p><label for="new_password"><%=l(:field_new_password)%> <span class="required">*</span></label>
<%= password_field_tag 'new_password', nil, :size => 25 %><br />
<em><%= l(:text_caracters_minimum, 4) %></em></p>
<em><%= l(:text_length_between, 4, 12) %></em></p>
<p><label for="new_password_confirmation"><%=l(:field_password_confirmation)%> <span class="required">*</span></label>
<%= password_field_tag 'new_password_confirmation', nil, :size => 25 %></p>

View File

@@ -1,6 +1,6 @@
<p><%= link_to(h(news.project.name), :controller => 'projects', :action => 'show', :id => news.project) + ': ' unless @project %>
<%= link_to h(news.title), :controller => 'news', :action => 'show', :id => news %>
<%= "(#{news.comments_count} #{lwr(:label_comment, news.comments_count).downcase})" if news.comments_count > 0 %>
<%= "(#{news.comments_count} #{lwr(:label_comment, news.comments_count).downcase})" if news.comments_count > 0 %></span>
<br />
<% unless news.summary.blank? %><span class="summary"><%=h news.summary %></span><br /><% end %>
<span class="author"><%= authoring news.created_on, news.author %></span></p>
<span class="author"><%= authoring news.created_on, news.author %></p>

View File

@@ -26,21 +26,18 @@
<h3 class="icon22 icon22-comment"><%= l(:label_comment_plural) %></h3>
<% @news.comments.each do |comment| %>
<% next if comment.new_record? %>
<h4><%= authoring comment.created_on, comment.author %></h4>
<h4><%= format_time(comment.created_on) %> - <%= comment.author.name %></h4>
<div class="contextual">
<%= link_to_if_authorized l(:button_delete), {:controller => 'news', :action => 'destroy_comment', :id => @news, :comment_id => comment}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %>
</div>
<%= textilizable(comment.comments) %>
<%= simple_format(auto_link(h comment.comments))%>
<% end if @news.comments_count > 0 %>
</div>
<% if authorize_for 'news', 'add_comment' %>
<p><%= toggle_link l(:label_comment_add), "add_comment_form", :focus => "comment_comments" %></p>
<% form_tag({:action => 'add_comment', :id => @news}, :id => "add_comment_form", :style => "display:none;") do %>
<%= text_area 'comment', 'comments', :cols => 80, :rows => 15, :class => 'wiki-edit' %>
<%= wikitoolbar_for 'comment_comments' %>
<%= text_area 'comment', 'comments', :cols => 60, :rows => 6 %>
<p><%= submit_tag l(:button_add) %></p>
<% end %>
<% end %>
<% set_html_title(h(@news.title)) -%>

View File

@@ -9,7 +9,7 @@
<% end %>
<p><%= f.text_area :description, :required => true, :cols => 60, :rows => 5 %><em><%= l(:text_caracters_maximum, 255) %></em></p>
<p><%= f.text_field :identifier, :required => true, :disabled => @project.identifier_frozen? %><br /><em><%= l(:text_length_between, 3, 20) %> <%= l(:text_project_identifier_info) unless @project.identifier_frozen? %></em></p>
<p><%= f.text_field :identifier, :required => true, :size => 15, :disabled => @project.identifier_frozen? %><br /><em><%= l(:text_length_between, 3, 12) %> <%= l(:text_project_identifier_info) unless @project.identifier_frozen? %></em></p>
<p><%= f.text_field :homepage, :size => 40 %></p>
<p><%= f.check_box :is_public %></p>
<%= wikitoolbar_for 'project_description' %>
@@ -17,32 +17,16 @@
<% for @custom_value in @custom_values %>
<p><%= custom_field_tag_with_label @custom_value %></p>
<% end %>
</div>
<% unless @trackers.empty? %>
<fieldset class="box"><legend><%=l(:label_tracker_plural)%></legend>
<% @trackers.each do |tracker| %>
<label class="floating">
<%= check_box_tag 'project[tracker_ids][]', tracker.id, @project.trackers.include?(tracker) %>
<%= tracker %>
</label>
<% end %>
<%= hidden_field_tag 'project[tracker_ids][]', '' %>
</fieldset>
<% end %>
<% unless @custom_fields.empty? %>
<fieldset class="box"><legend><%=l(:label_custom_field_plural)%></legend>
<p><label><%=l(:label_custom_field_plural)%></label>
<% for custom_field in @custom_fields %>
<label class="floating">
<%= check_box_tag "custom_field_ids[]", custom_field.id, ((@project.custom_fields.include? custom_field) or custom_field.is_for_all?), (custom_field.is_for_all? ? {:disabled => "disabled"} : {}) %>
<%= custom_field.name %>
</label>
<% end %>
</fieldset>
<%= custom_field.name %>
<% end %></p>
<% end %>
<!--[eoform:project]-->
</div>
<% content_for :header_tags do %>
<%= javascript_include_tag 'calendar/calendar' %>

View File

@@ -4,9 +4,9 @@
<h3><%= day_name(day.cwday) %> <%= day.day %></h3>
<ul>
<% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| %>
<li><p><%= format_time(e.event_datetime, false) %> <%= link_to truncate(e.event_title, 100), e.event_url %><br />
<li><p><%= e.event_datetime.strftime("%H:%M") %> <%= link_to truncate(e.event_title, 100), e.event_url %><br />
<% unless e.event_description.blank? %><em><%= truncate(e.event_description, 500) %></em><br /><% end %>
<span class="author"><%= e.event_author if e.respond_to?(:event_author) %></span></p></li>
<span class="author"><%= e.event_author if e.respond_to?(:author) %></span></p></li>
<% end %>
</ul>
<% end %>
@@ -39,5 +39,3 @@
<p><%= submit_tag l(:button_apply), :class => 'button-small' %></p>
<% end %>
<% end %>
<% set_html_title l(:label_activity) -%>

View File

@@ -3,13 +3,13 @@
<% labelled_tabular_form_for :project, @project, :url => { :action => "add" } do |f| %>
<%= render :partial => 'form', :locals => { :f => f } %>
<fieldset class="box"><legend><%= l(:label_module_plural) %></legend>
<div class="box">
<p><label><%= l(:label_module_plural) %></label>
<% Redmine::AccessControl.available_project_modules.each do |m| %>
<label class="floating">
<%= check_box_tag 'enabled_modules[]', m, @project.module_enabled?(m) %> <%= m.to_s.humanize %>
</label>
<% end %>
</fieldset>
<%= check_box_tag 'enabled_modules[]', m, @project.module_enabled?(m) %> <%= m.to_s.humanize %>
<% end %></p>
</div>
<%= submit_tag l(:button_save) %>
<% end %>

View File

@@ -38,5 +38,3 @@
<p><%= submit_tag l(:button_apply), :class => 'button-small' %></p>
<% end %>
<% end %>
<% set_html_title l(:label_calendar) -%>

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