Initial commit
git-svn-id: http://redmine.rubyforge.org/svn/trunk@4 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
73e0b8f8b3
commit
6b7650e2f0
|
@ -0,0 +1,10 @@
|
||||||
|
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||||
|
# for example lib/tasks/switchtower.rake, and they will automatically be available to Rake.
|
||||||
|
|
||||||
|
require(File.join(File.dirname(__FILE__), 'config', 'boot'))
|
||||||
|
|
||||||
|
require 'rake'
|
||||||
|
require 'rake/testtask'
|
||||||
|
require 'rake/rdoctask'
|
||||||
|
|
||||||
|
require 'tasks/rails'
|
|
@ -0,0 +1,83 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class AccountController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
# prevents login action to be filtered by check_if_login_required application scope filter
|
||||||
|
skip_before_filter :check_if_login_required, :only => :login
|
||||||
|
before_filter :require_login, :except => [:show, :login]
|
||||||
|
|
||||||
|
def show
|
||||||
|
@user = User.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
# Login request and validation
|
||||||
|
def login
|
||||||
|
if request.get?
|
||||||
|
session[:user] = nil
|
||||||
|
@user = User.new
|
||||||
|
else
|
||||||
|
@user = User.new(params[:user])
|
||||||
|
logged_in_user = @user.try_to_login
|
||||||
|
if logged_in_user
|
||||||
|
session[:user] = logged_in_user
|
||||||
|
redirect_back_or_default :controller => 'account', :action => 'my_page'
|
||||||
|
else
|
||||||
|
flash[:notice] = _('Invalid user/password')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Log out current user and redirect to welcome page
|
||||||
|
def logout
|
||||||
|
session[:user] = nil
|
||||||
|
redirect_to(:controller => '')
|
||||||
|
end
|
||||||
|
|
||||||
|
def my_page
|
||||||
|
@user = session[:user]
|
||||||
|
@reported_issues = Issue.find(:all, :conditions => ["author_id=?", @user.id], :limit => 10, :include => [ :status, :project, :tracker ], :order => 'issues.updated_on DESC')
|
||||||
|
@assigned_issues = Issue.find(:all, :conditions => ["assigned_to_id=?", @user.id], :limit => 10, :include => [ :status, :project, :tracker ], :order => 'issues.updated_on DESC')
|
||||||
|
end
|
||||||
|
|
||||||
|
# Edit current user's account
|
||||||
|
def my_account
|
||||||
|
@user = User.find(session[:user].id)
|
||||||
|
if request.post? and @user.update_attributes(@params[:user])
|
||||||
|
flash[:notice] = 'Account was successfully updated.'
|
||||||
|
session[:user] = @user
|
||||||
|
set_localization
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Change current user's password
|
||||||
|
def change_password
|
||||||
|
@user = User.find(session[:user].id)
|
||||||
|
if @user.check_password?(@params[:old_password])
|
||||||
|
if @params[:new_password] == @params[:new_password_confirmation]
|
||||||
|
if @user.change_password(@params[:old_password], @params[:new_password])
|
||||||
|
flash[:notice] = 'Password was successfully updated.'
|
||||||
|
end
|
||||||
|
else
|
||||||
|
flash[:notice] = 'Password confirmation doesn\'t match!'
|
||||||
|
end
|
||||||
|
else
|
||||||
|
flash[:notice] = 'Wrong password'
|
||||||
|
end
|
||||||
|
render :action => 'my_account'
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,49 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class AdminController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
before_filter :require_admin
|
||||||
|
|
||||||
|
helper :sort
|
||||||
|
include SortHelper
|
||||||
|
|
||||||
|
def index
|
||||||
|
end
|
||||||
|
|
||||||
|
def projects
|
||||||
|
sort_init 'projects.name', 'asc'
|
||||||
|
sort_update
|
||||||
|
@project_pages, @projects = paginate :projects, :per_page => 15, :order => sort_clause
|
||||||
|
end
|
||||||
|
|
||||||
|
def mail_options
|
||||||
|
@actions = Permission.find(:all, :conditions => ["mail_option=?", true]) || []
|
||||||
|
if request.post?
|
||||||
|
@actions.each { |a|
|
||||||
|
a.mail_enabled = params[:action_ids].include? a.id.to_s
|
||||||
|
a.save
|
||||||
|
}
|
||||||
|
flash[:notice] = "Mail options were successfully updated."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def info
|
||||||
|
@adapter_name = ActiveRecord::Base.connection.adapter_name
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,86 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class ApplicationController < ActionController::Base
|
||||||
|
before_filter :check_if_login_required, :set_localization
|
||||||
|
|
||||||
|
# check if login is globally required to access the application
|
||||||
|
def check_if_login_required
|
||||||
|
require_login if RDM_LOGIN_REQUIRED
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_localization
|
||||||
|
Localization.lang = session[:user].nil? ? RDM_DEFAULT_LANG : (session[:user].language || RDM_DEFAULT_LANG)
|
||||||
|
end
|
||||||
|
|
||||||
|
def require_login
|
||||||
|
unless session[:user]
|
||||||
|
store_location
|
||||||
|
redirect_to(:controller => "account", :action => "login")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def require_admin
|
||||||
|
if session[:user].nil?
|
||||||
|
store_location
|
||||||
|
redirect_to(:controller => "account", :action => "login")
|
||||||
|
else
|
||||||
|
unless session[:user].admin?
|
||||||
|
flash[:notice] = "Acces not allowed"
|
||||||
|
redirect_to(:controller => "projects", :action => "list")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# authorizes the user for the requested action.
|
||||||
|
def authorize
|
||||||
|
# check if action is allowed on public projects
|
||||||
|
if @project.public? and Permission.allowed_to_public "%s/%s" % [ @params[:controller], @params[:action] ]
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
# if user is not logged in, he is redirect to login form
|
||||||
|
unless session[:user]
|
||||||
|
store_location
|
||||||
|
redirect_to(:controller => "account", :action => "login")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
# check if user is authorized
|
||||||
|
if session[:user].admin? or Permission.allowed_to_role( "%s/%s" % [ @params[:controller], @params[:action] ], session[:user].role_for_project(@project.id) )
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
flash[:notice] = "Acces denied"
|
||||||
|
redirect_to(:controller => "")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
# store current uri in the session.
|
||||||
|
# we can return to this location by calling redirect_back_or_default
|
||||||
|
def store_location
|
||||||
|
session[:return_to] = @request.request_uri
|
||||||
|
end
|
||||||
|
|
||||||
|
# move to the last store_location call or to the passed default one
|
||||||
|
def redirect_back_or_default(default)
|
||||||
|
if session[:return_to].nil?
|
||||||
|
redirect_to default
|
||||||
|
else
|
||||||
|
redirect_to_url session[:return_to]
|
||||||
|
session[:return_to] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,58 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class CustomFieldsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
before_filter :require_admin
|
||||||
|
|
||||||
|
def index
|
||||||
|
list
|
||||||
|
render :action => 'list'
|
||||||
|
end
|
||||||
|
|
||||||
|
def list
|
||||||
|
@custom_field_pages, @custom_fields = paginate :custom_fields, :per_page => 10
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
if request.get?
|
||||||
|
@custom_field = CustomField.new
|
||||||
|
else
|
||||||
|
@custom_field = CustomField.new(params[:custom_field])
|
||||||
|
if @custom_field.save
|
||||||
|
flash[:notice] = 'CustomField was successfully created.'
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@custom_field = CustomField.find(params[:id])
|
||||||
|
if request.post? and @custom_field.update_attributes(params[:custom_field])
|
||||||
|
flash[:notice] = 'CustomField was successfully updated.'
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
CustomField.find(params[:id]).destroy
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
rescue
|
||||||
|
flash[:notice] = "Unable to delete custom field"
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,65 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class DocumentsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@categories = Enumeration::get_values('DCAT')
|
||||||
|
if request.post? and @document.update_attributes(params[:document])
|
||||||
|
flash[:notice] = 'Document was successfully updated.'
|
||||||
|
redirect_to :action => 'show', :id => @document
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@document.destroy
|
||||||
|
redirect_to :controller => 'projects', :action => 'list_documents', :id => @project
|
||||||
|
end
|
||||||
|
|
||||||
|
def download
|
||||||
|
@attachment = @document.attachments.find(params[:attachment_id])
|
||||||
|
@attachment.increment_download
|
||||||
|
send_file @attachment.diskfile, :filename => @attachment.filename
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_attachment
|
||||||
|
# Save the attachment
|
||||||
|
if params[:attachment][:file].size > 0
|
||||||
|
@attachment = @document.attachments.build(params[:attachment])
|
||||||
|
@attachment.author_id = session[:user].id unless session[:user].nil?
|
||||||
|
@attachment.save
|
||||||
|
end
|
||||||
|
render :action => 'show'
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy_attachment
|
||||||
|
@document.attachments.find(params[:attachment_id]).destroy
|
||||||
|
render :action => 'show'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def find_project
|
||||||
|
@document = Document.find(params[:id])
|
||||||
|
@project = @document.project
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,69 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class EnumerationsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
before_filter :require_admin
|
||||||
|
|
||||||
|
def index
|
||||||
|
list
|
||||||
|
render :action => 'list'
|
||||||
|
end
|
||||||
|
|
||||||
|
# GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
|
||||||
|
verify :method => :post, :only => [ :destroy, :create, :update ],
|
||||||
|
:redirect_to => { :action => :list }
|
||||||
|
|
||||||
|
def list
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@enumeration = Enumeration.new(:opt => params[:opt])
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@enumeration = Enumeration.new(params[:enumeration])
|
||||||
|
if @enumeration.save
|
||||||
|
flash[:notice] = 'Enumeration was successfully created.'
|
||||||
|
redirect_to :action => 'list', :opt => @enumeration.opt
|
||||||
|
else
|
||||||
|
render :action => 'new'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@enumeration = Enumeration.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@enumeration = Enumeration.find(params[:id])
|
||||||
|
if @enumeration.update_attributes(params[:enumeration])
|
||||||
|
flash[:notice] = 'Enumeration was successfully updated.'
|
||||||
|
redirect_to :action => 'list', :opt => @enumeration.opt
|
||||||
|
else
|
||||||
|
render :action => 'edit'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
Enumeration.find(params[:id]).destroy
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
rescue
|
||||||
|
flash[:notice] = "Unable to delete enumeration"
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,43 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class HelpController < ApplicationController
|
||||||
|
|
||||||
|
skip_before_filter :check_if_login_required
|
||||||
|
before_filter :load_help_config
|
||||||
|
|
||||||
|
def index
|
||||||
|
if @params[:ctrl] and @help_config[@params[:ctrl]]
|
||||||
|
if @params[:page] and @help_config[@params[:ctrl]][@params[:page]]
|
||||||
|
template = @help_config[@params[:ctrl]][@params[:page]]
|
||||||
|
else
|
||||||
|
template = @help_config[@params[:ctrl]]['index']
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if template
|
||||||
|
redirect_to "/manual/#{template}"
|
||||||
|
else
|
||||||
|
redirect_to "/manual/"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def load_help_config
|
||||||
|
@help_config = YAML::load(File.open("#{RAILS_ROOT}/config/help.yml"))
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,42 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class IssueCategoriesController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
|
def edit
|
||||||
|
if request.post? and @category.update_attributes(params[:category])
|
||||||
|
flash[:notice] = 'Issue category was successfully updated.'
|
||||||
|
redirect_to :controller => 'projects', :action => 'settings', :id => @project
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@category.destroy
|
||||||
|
redirect_to :controller => 'projects', :action => 'settings', :id => @project
|
||||||
|
rescue
|
||||||
|
flash[:notice] = "Categorie can't be deleted"
|
||||||
|
redirect_to :controller => 'projects', :action => 'settings', :id => @project
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def find_project
|
||||||
|
@category = IssueCategory.find(params[:id])
|
||||||
|
@project = @category.project
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,68 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class IssueStatusesController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
before_filter :require_admin
|
||||||
|
|
||||||
|
def index
|
||||||
|
list
|
||||||
|
render :action => 'list'
|
||||||
|
end
|
||||||
|
|
||||||
|
def list
|
||||||
|
@issue_status_pages, @issue_statuses = paginate :issue_statuses, :per_page => 10
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@issue_status = IssueStatus.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@issue_status = IssueStatus.new(params[:issue_status])
|
||||||
|
if @issue_status.save
|
||||||
|
flash[:notice] = 'IssueStatus was successfully created.'
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
else
|
||||||
|
render :action => 'new'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@issue_status = IssueStatus.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@issue_status = IssueStatus.find(params[:id])
|
||||||
|
if @issue_status.update_attributes(params[:issue_status])
|
||||||
|
flash[:notice] = 'IssueStatus was successfully updated.'
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
else
|
||||||
|
render :action => 'edit'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
IssueStatus.find(params[:id]).destroy
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
rescue
|
||||||
|
flash[:notice] = "Unable to delete issue status"
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,102 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class IssuesController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
|
helper :custom_fields
|
||||||
|
include CustomFieldsHelper
|
||||||
|
|
||||||
|
def show
|
||||||
|
@status_options = @issue.status.workflows.find(:all, :conditions => ["role_id=? and tracker_id=?", session[:user].role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if session[:user]
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@trackers = Tracker.find(:all)
|
||||||
|
@priorities = Enumeration::get_values('IPRI')
|
||||||
|
|
||||||
|
if request.get?
|
||||||
|
@custom_values = @project.custom_fields_for_issues.collect { |x| @issue.custom_values.find_by_custom_field_id(x.id) || CustomValue.new(:custom_field => x) }
|
||||||
|
else
|
||||||
|
# Retrieve custom fields and values
|
||||||
|
@custom_values = @project.custom_fields_for_issues.collect { |x| CustomValue.new(:custom_field => x, :value => params["custom_fields"][x.id.to_s]) }
|
||||||
|
|
||||||
|
@issue.custom_values = @custom_values
|
||||||
|
if @issue.update_attributes(params[:issue])
|
||||||
|
flash[:notice] = 'Issue was successfully updated.'
|
||||||
|
redirect_to :action => 'show', :id => @issue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def change_status
|
||||||
|
@history = @issue.histories.build(params[:history])
|
||||||
|
@status_options = @issue.status.workflows.find(:all, :conditions => ["role_id=? and tracker_id=?", session[:user].role_for_project(@project.id), @issue.tracker.id]).collect{ |w| w.new_status } if session[:user]
|
||||||
|
|
||||||
|
if params[:confirm]
|
||||||
|
unless session[:user].nil?
|
||||||
|
@history.author = session[:user]
|
||||||
|
end
|
||||||
|
if @history.save
|
||||||
|
@issue.status = @history.status
|
||||||
|
@issue.fixed_version_id = (params[:issue][:fixed_version_id])
|
||||||
|
@issue.assigned_to_id = (params[:issue][:assigned_to_id])
|
||||||
|
if @issue.save
|
||||||
|
flash[:notice] = 'Issue was successfully updated.'
|
||||||
|
Mailer.deliver_issue_change_status(@issue) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
|
||||||
|
redirect_to :action => 'show', :id => @issue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@assignable_to = @project.members.find(:all, :include => :user).collect{ |m| m.user }
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@issue.destroy
|
||||||
|
redirect_to :controller => 'projects', :action => 'list_issues', :id => @project
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_attachment
|
||||||
|
# Save the attachment
|
||||||
|
if params[:attachment][:file].size > 0
|
||||||
|
@attachment = @issue.attachments.build(params[:attachment])
|
||||||
|
@attachment.author_id = session[:user].id unless session[:user].nil?
|
||||||
|
@attachment.save
|
||||||
|
end
|
||||||
|
redirect_to :action => 'show', :id => @issue
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy_attachment
|
||||||
|
@issue.attachments.find(params[:attachment_id]).destroy
|
||||||
|
redirect_to :action => 'show', :id => @issue
|
||||||
|
end
|
||||||
|
|
||||||
|
# Send the file in stream mode
|
||||||
|
def download
|
||||||
|
@attachment = @issue.attachments.find(params[:attachment_id])
|
||||||
|
send_file @attachment.diskfile, :filename => @attachment.filename
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def find_project
|
||||||
|
@issue = Issue.find(params[:id])
|
||||||
|
@project = @issue.project
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,41 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class MembersController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
|
def edit
|
||||||
|
if request.post? and @member.update_attributes(params[:member])
|
||||||
|
flash[:notice] = 'Member was successfully updated.'
|
||||||
|
redirect_to :controller => 'projects', :action => 'settings', :id => @project
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@member.destroy
|
||||||
|
flash[:notice] = 'Member was successfully removed.'
|
||||||
|
redirect_to :controller => 'projects', :action => 'settings', :id => @project
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def find_project
|
||||||
|
@member = Member.find(params[:id])
|
||||||
|
@project = @member.project
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,42 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class NewsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
if request.post? and @news.update_attributes(params[:news])
|
||||||
|
flash[:notice] = 'News was successfully updated.'
|
||||||
|
redirect_to :action => 'show', :id => @news
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@news.destroy
|
||||||
|
redirect_to :controller => 'projects', :action => 'list_news', :id => @project
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def find_project
|
||||||
|
@news = News.find(params[:id])
|
||||||
|
@project = @news.project
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,260 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class ProjectsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
before_filter :find_project, :authorize, :except => [ :index, :list, :add ]
|
||||||
|
before_filter :require_admin, :only => [ :add, :destroy ]
|
||||||
|
|
||||||
|
helper :sort
|
||||||
|
include SortHelper
|
||||||
|
helper :search_filter
|
||||||
|
include SearchFilterHelper
|
||||||
|
helper :custom_fields
|
||||||
|
include CustomFieldsHelper
|
||||||
|
|
||||||
|
def index
|
||||||
|
list
|
||||||
|
render :action => 'list'
|
||||||
|
end
|
||||||
|
|
||||||
|
# Lists public projects
|
||||||
|
def list
|
||||||
|
sort_init 'projects.name', 'asc'
|
||||||
|
sort_update
|
||||||
|
@project_count = Project.count(["public=?", true])
|
||||||
|
@project_pages = Paginator.new self, @project_count,
|
||||||
|
15,
|
||||||
|
@params['page']
|
||||||
|
@projects = Project.find :all, :order => sort_clause,
|
||||||
|
:conditions => ["public=?", true],
|
||||||
|
:limit => @project_pages.items_per_page,
|
||||||
|
:offset => @project_pages.current.offset
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add a new project
|
||||||
|
def add
|
||||||
|
@custom_fields = CustomField::find_all
|
||||||
|
@project = Project.new(params[:project])
|
||||||
|
if request.post?
|
||||||
|
@project.custom_fields = CustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
|
||||||
|
if @project.save
|
||||||
|
flash[:notice] = 'Project was successfully created.'
|
||||||
|
redirect_to :controller => 'admin', :action => 'projects'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Show @project
|
||||||
|
def show
|
||||||
|
@members = @project.members.find(:all, :include => [:user, :role])
|
||||||
|
end
|
||||||
|
|
||||||
|
def settings
|
||||||
|
@custom_fields = CustomField::find_all
|
||||||
|
@issue_category ||= IssueCategory.new
|
||||||
|
@member ||= @project.members.new
|
||||||
|
@roles = Role.find_all
|
||||||
|
@users = User.find_all - @project.members.find(:all, :include => :user).collect{|m| m.user }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Edit @project
|
||||||
|
def edit
|
||||||
|
if request.post?
|
||||||
|
@project.custom_fields = CustomField.find(@params[:custom_field_ids]) if @params[:custom_field_ids]
|
||||||
|
if @project.update_attributes(params[:project])
|
||||||
|
flash[:notice] = 'Project was successfully updated.'
|
||||||
|
redirect_to :action => 'settings', :id => @project
|
||||||
|
else
|
||||||
|
settings
|
||||||
|
render :action => 'settings'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Delete @project
|
||||||
|
def destroy
|
||||||
|
if request.post? and params[:confirm]
|
||||||
|
@project.destroy
|
||||||
|
redirect_to :controller => 'admin', :action => 'projects'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add a new issue category to @project
|
||||||
|
def add_issue_category
|
||||||
|
if request.post?
|
||||||
|
@issue_category = @project.issue_categories.build(params[:issue_category])
|
||||||
|
if @issue_category.save
|
||||||
|
redirect_to :action => 'settings', :id => @project
|
||||||
|
else
|
||||||
|
settings
|
||||||
|
render :action => 'settings'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add a new version to @project
|
||||||
|
def add_version
|
||||||
|
@version = @project.versions.build(params[:version])
|
||||||
|
if request.post? and @version.save
|
||||||
|
redirect_to :action => 'settings', :id => @project
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add a new member to @project
|
||||||
|
def add_member
|
||||||
|
@member = @project.members.build(params[:member])
|
||||||
|
if request.post?
|
||||||
|
if @member.save
|
||||||
|
flash[:notice] = 'Member was successfully added.'
|
||||||
|
redirect_to :action => 'settings', :id => @project
|
||||||
|
else
|
||||||
|
settings
|
||||||
|
render :action => 'settings'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Show members list of @project
|
||||||
|
def list_members
|
||||||
|
@members = @project.members
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add a new document to @project
|
||||||
|
def add_document
|
||||||
|
@categories = Enumeration::get_values('DCAT')
|
||||||
|
@document = @project.documents.build(params[:document])
|
||||||
|
if request.post?
|
||||||
|
# Save the attachment
|
||||||
|
if params[:attachment][:file].size > 0
|
||||||
|
@attachment = @document.attachments.build(params[:attachment])
|
||||||
|
@attachment.author_id = session[:user].id unless session[:user].nil?
|
||||||
|
end
|
||||||
|
if @document.save
|
||||||
|
redirect_to :action => 'list_documents', :id => @project
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Show documents list of @project
|
||||||
|
def list_documents
|
||||||
|
@documents = @project.documents
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add a new issue to @project
|
||||||
|
def add_issue
|
||||||
|
@trackers = Tracker.find(:all)
|
||||||
|
@priorities = Enumeration::get_values('IPRI')
|
||||||
|
if request.get?
|
||||||
|
@issue = @project.issues.build
|
||||||
|
@custom_values = @project.custom_fields_for_issues.collect { |x| CustomValue.new(:custom_field => x) }
|
||||||
|
else
|
||||||
|
# Create the issue and set the author
|
||||||
|
@issue = @project.issues.build(params[:issue])
|
||||||
|
@issue.author = session[:user] unless session[:user].nil?
|
||||||
|
# Create the document if a file was sent
|
||||||
|
if params[:attachment][:file].size > 0
|
||||||
|
@attachment = @issue.attachments.build(params[:attachment])
|
||||||
|
@attachment.author_id = session[:user].id unless session[:user].nil?
|
||||||
|
end
|
||||||
|
@custom_values = @project.custom_fields_for_issues.collect { |x| CustomValue.new(:custom_field => x, :value => params["custom_fields"][x.id.to_s]) }
|
||||||
|
@issue.custom_values = @custom_values
|
||||||
|
if @issue.save
|
||||||
|
flash[:notice] = "Issue was successfully added."
|
||||||
|
Mailer.deliver_issue_add(@issue) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
|
||||||
|
redirect_to :action => 'list_issues', :id => @project
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Show issues list of @project
|
||||||
|
def list_issues
|
||||||
|
sort_init 'issues.id', 'desc'
|
||||||
|
sort_update
|
||||||
|
|
||||||
|
search_filter_criteria 'issues.tracker_id', :values => "Tracker.find(:all)"
|
||||||
|
search_filter_criteria 'issues.priority_id', :values => "Enumeration.find(:all, :conditions => ['opt=?','IPRI'])"
|
||||||
|
search_filter_criteria 'issues.category_id', :values => "@project.issue_categories"
|
||||||
|
search_filter_criteria 'issues.status_id', :values => "IssueStatus.find(:all)"
|
||||||
|
search_filter_criteria 'issues.author_id', :values => "User.find(:all)", :label => "display_name"
|
||||||
|
search_filter_update if params[:set_filter] or request.post?
|
||||||
|
|
||||||
|
@issue_count = @project.issues.count(search_filter_clause)
|
||||||
|
@issue_pages = Paginator.new self, @issue_count,
|
||||||
|
15,
|
||||||
|
@params['page']
|
||||||
|
@issues = @project.issues.find :all, :order => sort_clause,
|
||||||
|
:include => [ :author, :status, :tracker ],
|
||||||
|
:conditions => search_filter_clause,
|
||||||
|
:limit => @issue_pages.items_per_page,
|
||||||
|
:offset => @issue_pages.current.offset
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add a news to @project
|
||||||
|
def add_news
|
||||||
|
@news = @project.news.build(params[:news])
|
||||||
|
if request.post?
|
||||||
|
@news.author = session[:user] unless session[:user].nil?
|
||||||
|
if @news.save
|
||||||
|
redirect_to :action => 'list_news', :id => @project
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Show news list of @project
|
||||||
|
def list_news
|
||||||
|
@news_pages, @news = paginate :news, :per_page => 10, :conditions => ["project_id=?", @project.id], :include => :author, :order => "news.created_on DESC"
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_file
|
||||||
|
if request.post?
|
||||||
|
# Save the attachment
|
||||||
|
if params[:attachment][:file].size > 0
|
||||||
|
@attachment = @project.versions.find(params[:version_id]).attachments.build(params[:attachment])
|
||||||
|
@attachment.author_id = session[:user].id unless session[:user].nil?
|
||||||
|
if @attachment.save
|
||||||
|
redirect_to :controller => 'projects', :action => 'list_files', :id => @project
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@versions = @project.versions
|
||||||
|
end
|
||||||
|
|
||||||
|
def list_files
|
||||||
|
@versions = @project.versions
|
||||||
|
end
|
||||||
|
|
||||||
|
# Show changelog of @project
|
||||||
|
def changelog
|
||||||
|
@fixed_issues = @project.issues.find(:all,
|
||||||
|
:include => [ :fixed_version, :status, :tracker ],
|
||||||
|
:conditions => [ "issue_statuses.is_closed=? and trackers.is_in_chlog=? and issues.fixed_version_id is not null", true, true]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
# Find project of id params[:id]
|
||||||
|
# if not found, redirect to project list
|
||||||
|
# used as a before_filter
|
||||||
|
def find_project
|
||||||
|
@project = Project.find(params[:id])
|
||||||
|
rescue
|
||||||
|
flash[:notice] = 'Project not found.'
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,71 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class ReportsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
|
def issue_report
|
||||||
|
@statuses = IssueStatus.find_all
|
||||||
|
@trackers = Tracker.find_all
|
||||||
|
@issues_by_tracker =
|
||||||
|
ActiveRecord::Base.connection.select_all("select s.id as status_id,
|
||||||
|
s.is_closed as closed,
|
||||||
|
t.id as tracker_id,
|
||||||
|
count(i.id) as total
|
||||||
|
from
|
||||||
|
issues i, issue_statuses s, trackers t
|
||||||
|
where
|
||||||
|
i.status_id=s.id
|
||||||
|
and i.tracker_id=t.id
|
||||||
|
and i.project_id=#{@project.id}
|
||||||
|
group by s.id, t.id")
|
||||||
|
@priorities = Enumeration::get_values('IPRI')
|
||||||
|
@issues_by_priority =
|
||||||
|
ActiveRecord::Base.connection.select_all("select s.id as status_id,
|
||||||
|
s.is_closed as closed,
|
||||||
|
p.id as priority_id,
|
||||||
|
count(i.id) as total
|
||||||
|
from
|
||||||
|
issues i, issue_statuses s, enumerations p
|
||||||
|
where
|
||||||
|
i.status_id=s.id
|
||||||
|
and i.priority_id=p.id
|
||||||
|
and i.project_id=#{@project.id}
|
||||||
|
group by s.id, p.id")
|
||||||
|
@categories = @project.issue_categories
|
||||||
|
@issues_by_category =
|
||||||
|
ActiveRecord::Base.connection.select_all("select s.id as status_id,
|
||||||
|
s.is_closed as closed,
|
||||||
|
c.id as category_id,
|
||||||
|
count(i.id) as total
|
||||||
|
from
|
||||||
|
issues i, issue_statuses s, issue_categories c
|
||||||
|
where
|
||||||
|
i.status_id=s.id
|
||||||
|
and i.category_id=c.id
|
||||||
|
and i.project_id=#{@project.id}
|
||||||
|
group by s.id, c.id")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
private
|
||||||
|
# Find project of id params[:id]
|
||||||
|
def find_project
|
||||||
|
@project = Project.find(params[:id])
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,84 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class RolesController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
before_filter :require_admin
|
||||||
|
|
||||||
|
def index
|
||||||
|
list
|
||||||
|
render :action => 'list'
|
||||||
|
end
|
||||||
|
|
||||||
|
def list
|
||||||
|
@role_pages, @roles = paginate :roles, :per_page => 10
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@role = Role.new(params[:role])
|
||||||
|
if request.post?
|
||||||
|
@role.permissions = Permission.find(@params[:permission_ids]) if @params[:permission_ids]
|
||||||
|
if @role.save
|
||||||
|
flash[:notice] = 'Role was successfully created.'
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@permissions = Permission.find(:all, :order => 'sort ASC')
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@role = Role.find(params[:id])
|
||||||
|
if request.post? and @role.update_attributes(params[:role])
|
||||||
|
@role.permissions = Permission.find(@params[:permission_ids] || [])
|
||||||
|
Permission.allowed_to_role_expired
|
||||||
|
flash[:notice] = 'Role was successfully updated.'
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
@permissions = Permission.find(:all, :order => 'sort ASC')
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@role = Role.find(params[:id])
|
||||||
|
unless @role.members.empty?
|
||||||
|
flash[:notice] = 'Some members have this role. Can\'t delete it.'
|
||||||
|
else
|
||||||
|
@role.destroy
|
||||||
|
end
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
|
||||||
|
def workflow
|
||||||
|
@roles = Role.find_all
|
||||||
|
@trackers = Tracker.find_all
|
||||||
|
@statuses = IssueStatus.find_all
|
||||||
|
|
||||||
|
@role = Role.find_by_id(params[:role_id])
|
||||||
|
@tracker = Tracker.find_by_id(params[:tracker_id])
|
||||||
|
|
||||||
|
if request.post?
|
||||||
|
Workflow.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id])
|
||||||
|
(params[:issue_status] || []).each { |old, news|
|
||||||
|
news.each { |new|
|
||||||
|
@role.workflows.build(:tracker_id => @tracker.id, :old_status_id => old, :new_status_id => new)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if @role.save
|
||||||
|
flash[:notice] = 'Workflow was successfully updated.'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,60 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class TrackersController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
before_filter :require_admin
|
||||||
|
|
||||||
|
def index
|
||||||
|
list
|
||||||
|
render :action => 'list'
|
||||||
|
end
|
||||||
|
|
||||||
|
# GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
|
||||||
|
verify :method => :post, :only => [ :destroy ], :redirect_to => { :action => :list }
|
||||||
|
|
||||||
|
def list
|
||||||
|
@tracker_pages, @trackers = paginate :trackers, :per_page => 10
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@tracker = Tracker.new(params[:tracker])
|
||||||
|
if request.post? and @tracker.save
|
||||||
|
flash[:notice] = 'Tracker was successfully created.'
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@tracker = Tracker.find(params[:id])
|
||||||
|
if request.post? and @tracker.update_attributes(params[:tracker])
|
||||||
|
flash[:notice] = 'Tracker was successfully updated.'
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@tracker = Tracker.find(params[:id])
|
||||||
|
unless @tracker.issues.empty?
|
||||||
|
flash[:notice] = "This tracker contains issues and can\'t be deleted."
|
||||||
|
else
|
||||||
|
@tracker.destroy
|
||||||
|
end
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,73 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class UsersController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
before_filter :require_admin
|
||||||
|
|
||||||
|
helper :sort
|
||||||
|
include SortHelper
|
||||||
|
|
||||||
|
def index
|
||||||
|
list
|
||||||
|
render :action => 'list'
|
||||||
|
end
|
||||||
|
|
||||||
|
def list
|
||||||
|
sort_init 'users.login', 'asc'
|
||||||
|
sort_update
|
||||||
|
@user_count = User.count
|
||||||
|
@user_pages = Paginator.new self, @user_count,
|
||||||
|
15,
|
||||||
|
@params['page']
|
||||||
|
@users = User.find :all, :order => sort_clause,
|
||||||
|
:limit => @user_pages.items_per_page,
|
||||||
|
:offset => @user_pages.current.offset
|
||||||
|
end
|
||||||
|
|
||||||
|
def add
|
||||||
|
if request.get?
|
||||||
|
@user = User.new
|
||||||
|
else
|
||||||
|
@user = User.new(params[:user])
|
||||||
|
@user.admin = params[:user][:admin]
|
||||||
|
if @user.save
|
||||||
|
flash[:notice] = 'User was successfully created.'
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@user = User.find(params[:id])
|
||||||
|
if request.post?
|
||||||
|
@user.admin = params[:user][:admin] if params[:user][:admin]
|
||||||
|
if @user.update_attributes(params[:user])
|
||||||
|
flash[:notice] = 'User was successfully updated.'
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
User.find(params[:id]).destroy
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
rescue
|
||||||
|
flash[:notice] = "Unable to delete user"
|
||||||
|
redirect_to :action => 'list'
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,53 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class VersionsController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
before_filter :find_project, :authorize
|
||||||
|
|
||||||
|
def edit
|
||||||
|
if request.post? and @version.update_attributes(params[:version])
|
||||||
|
flash[:notice] = 'Version was successfully updated.'
|
||||||
|
redirect_to :controller => 'projects', :action => 'settings', :id => @project
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@version.destroy
|
||||||
|
redirect_to :controller => 'projects', :action => 'settings', :id => @project
|
||||||
|
rescue
|
||||||
|
flash[:notice] = "Unable to delete version"
|
||||||
|
redirect_to :controller => 'projects', :action => 'settings', :id => @project
|
||||||
|
end
|
||||||
|
|
||||||
|
def download
|
||||||
|
@attachment = @version.attachments.find(params[:attachment_id])
|
||||||
|
@attachment.increment_download
|
||||||
|
send_file @attachment.diskfile, :filename => @attachment.filename
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy_file
|
||||||
|
@version.attachments.find(params[:attachment_id]).destroy
|
||||||
|
redirect_to :controller => 'projects', :action => 'list_files', :id => @project
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def find_project
|
||||||
|
@version = Version.find(params[:id])
|
||||||
|
@project = @version.project
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,26 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class WelcomeController < ApplicationController
|
||||||
|
layout 'base'
|
||||||
|
|
||||||
|
def index
|
||||||
|
@news = News.latest
|
||||||
|
@projects = Project.latest
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module AccountHelper
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module AdminHelper
|
||||||
|
end
|
|
@ -0,0 +1,65 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module ApplicationHelper
|
||||||
|
|
||||||
|
def loggedin?
|
||||||
|
session[:user]
|
||||||
|
end
|
||||||
|
|
||||||
|
def admin_loggedin?
|
||||||
|
session[:user] && session[:user].admin
|
||||||
|
end
|
||||||
|
|
||||||
|
def authorize_for(controller, action)
|
||||||
|
# check if action is allowed on public projects
|
||||||
|
if @project.public? and Permission.allowed_to_public "%s/%s" % [ controller, action ]
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
# check if user is authorized
|
||||||
|
if session[:user] and (session[:user].admin? or Permission.allowed_to_role( "%s/%s" % [ controller, action ], session[:user].role_for_project(@project.id) ) )
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference)
|
||||||
|
link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller], options[:action])
|
||||||
|
end
|
||||||
|
|
||||||
|
# Display a link to user's account page
|
||||||
|
def link_to_user(user)
|
||||||
|
link_to user.display_name, :controller => 'account', :action => 'show', :id => user
|
||||||
|
end
|
||||||
|
|
||||||
|
def format_date(date)
|
||||||
|
_('(date)', date) if date
|
||||||
|
end
|
||||||
|
|
||||||
|
def format_time(time)
|
||||||
|
_('(time)', time) if time
|
||||||
|
end
|
||||||
|
|
||||||
|
def pagination_links_full(paginator, options={}, html_options={})
|
||||||
|
html =''
|
||||||
|
html << link_to(('« ' + _('Previous') ), { :page => paginator.current.previous }) + ' ' if paginator.current.previous
|
||||||
|
html << (pagination_links(paginator, options, html_options) || '')
|
||||||
|
html << ' ' + link_to((_('Next') + ' »'), { :page => paginator.current.next }) if paginator.current.next
|
||||||
|
html
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,36 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module CustomFieldsHelper
|
||||||
|
def custom_field_tag(custom_value)
|
||||||
|
|
||||||
|
custom_field = custom_value.custom_field
|
||||||
|
|
||||||
|
field_name = "custom_fields[#{custom_field.id}]"
|
||||||
|
|
||||||
|
case custom_field.typ
|
||||||
|
when 0 .. 2
|
||||||
|
text_field_tag field_name, custom_value.value
|
||||||
|
when 3
|
||||||
|
check_box field_name
|
||||||
|
when 4
|
||||||
|
select_tag field_name,
|
||||||
|
options_for_select(custom_field.possible_values.split('|'),
|
||||||
|
custom_value.value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module DocumentsHelper
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module EnumerationsHelper
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module HelpHelper
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module IssueCategoriesHelper
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module IssueStatusesHelper
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module IssuesHelper
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module MembersHelper
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module NewsHelper
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module ProjectsHelper
|
||||||
|
end
|
|
@ -0,0 +1,32 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module ReportsHelper
|
||||||
|
|
||||||
|
def aggregate(data, criteria)
|
||||||
|
a = 0
|
||||||
|
data.each { |row|
|
||||||
|
match = 1
|
||||||
|
criteria.each { |k, v|
|
||||||
|
match = 0 unless row[k].to_s == v.to_s
|
||||||
|
} unless criteria.nil?
|
||||||
|
a = a + row["total"].to_i if match == 1
|
||||||
|
} unless data.nil?
|
||||||
|
a
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module RolesHelper
|
||||||
|
end
|
|
@ -0,0 +1,55 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module SearchFilterHelper
|
||||||
|
|
||||||
|
def search_filter_criteria(field, options = {})
|
||||||
|
session[:search_filter] ||= {}
|
||||||
|
session[:search_filter][field] ||= options
|
||||||
|
# session[:search_filter][field][:values] = options[:values] unless options[:values].nil?
|
||||||
|
# session[:search_filter][field][:label] = options[:label] unless options[:label].nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_filter_update
|
||||||
|
session[:search_filter].each_key {|field| session[:search_filter][field][:value] = params[field] }
|
||||||
|
#@search_filter[:value] = params[@search_filter[:field]]
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_filter_clause
|
||||||
|
clause = "1=1"
|
||||||
|
session[:search_filter].each {|field, criteria| clause = clause + " AND " + field + "='" + session[:search_filter][field][:value] + "'" unless session[:search_filter][field][:value].nil? || session[:search_filter][field][:value].empty? }
|
||||||
|
clause
|
||||||
|
#@search_filter[:field] + "='" + @search_filter[:value] + "'" unless @search_filter[:value].nil? || @search_filter[:value].empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_filter_tag(field)
|
||||||
|
option_values = []
|
||||||
|
#values = eval @search_filter[:values_expr]
|
||||||
|
option_values = eval session[:search_filter][field][:values]
|
||||||
|
|
||||||
|
content_tag("select",
|
||||||
|
content_tag("option", "[All]", :value => "") +
|
||||||
|
options_from_collection_for_select(option_values,
|
||||||
|
"id",
|
||||||
|
session[:search_filter][field][:label] || "name",
|
||||||
|
session[:search_filter][field][:value].to_i
|
||||||
|
),
|
||||||
|
:name => field
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,157 @@
|
||||||
|
# Helpers to sort tables using clickable column headers.
|
||||||
|
#
|
||||||
|
# Author: Stuart Rackham <srackham@methods.co.nz>, March 2005.
|
||||||
|
# License: This source code is released under the MIT license.
|
||||||
|
#
|
||||||
|
# - Consecutive clicks toggle the column's sort order.
|
||||||
|
# - Sort state is maintained by a session hash entry.
|
||||||
|
# - Icon image identifies sort column and state.
|
||||||
|
# - Typically used in conjunction with the Pagination module.
|
||||||
|
#
|
||||||
|
# Example code snippets:
|
||||||
|
#
|
||||||
|
# Controller:
|
||||||
|
#
|
||||||
|
# helper :sort
|
||||||
|
# include SortHelper
|
||||||
|
#
|
||||||
|
# def list
|
||||||
|
# sort_init 'last_name'
|
||||||
|
# sort_update
|
||||||
|
# @items = Contact.find_all nil, sort_clause
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# Controller (using Pagination module):
|
||||||
|
#
|
||||||
|
# helper :sort
|
||||||
|
# include SortHelper
|
||||||
|
#
|
||||||
|
# def list
|
||||||
|
# sort_init 'last_name'
|
||||||
|
# sort_update
|
||||||
|
# @contact_pages, @items = paginate :contacts,
|
||||||
|
# :order_by => sort_clause,
|
||||||
|
# :per_page => 10
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# View (table header in list.rhtml):
|
||||||
|
#
|
||||||
|
# <thead>
|
||||||
|
# <tr>
|
||||||
|
# <%= sort_header_tag('id', :title => 'Sort by contact ID') %>
|
||||||
|
# <%= sort_header_tag('last_name', :caption => 'Name') %>
|
||||||
|
# <%= sort_header_tag('phone') %>
|
||||||
|
# <%= sort_header_tag('address', :width => 200) %>
|
||||||
|
# </tr>
|
||||||
|
# </thead>
|
||||||
|
#
|
||||||
|
# - The ascending and descending sort icon images are sort_asc.png and
|
||||||
|
# sort_desc.png and reside in the application's images directory.
|
||||||
|
# - Introduces instance variables: @sort_name, @sort_default.
|
||||||
|
# - Introduces params :sort_key and :sort_order.
|
||||||
|
#
|
||||||
|
module SortHelper
|
||||||
|
|
||||||
|
# Initializes the default sort column (default_key) and sort order
|
||||||
|
# (default_order).
|
||||||
|
#
|
||||||
|
# - default_key is a column attribute name.
|
||||||
|
# - default_order is 'asc' or 'desc'.
|
||||||
|
# - name is the name of the session hash entry that stores the sort state,
|
||||||
|
# defaults to '<controller_name>_sort'.
|
||||||
|
#
|
||||||
|
def sort_init(default_key, default_order='asc', name=nil)
|
||||||
|
@sort_name = name || @params[:controller] + @params[:action] + '_sort'
|
||||||
|
@sort_default = {:key => default_key, :order => default_order}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Updates the sort state. Call this in the controller prior to calling
|
||||||
|
# sort_clause.
|
||||||
|
#
|
||||||
|
def sort_update()
|
||||||
|
if @params[:sort_key]
|
||||||
|
sort = {:key => @params[:sort_key], :order => @params[:sort_order]}
|
||||||
|
elsif @session[@sort_name]
|
||||||
|
sort = @session[@sort_name] # Previous sort.
|
||||||
|
else
|
||||||
|
sort = @sort_default
|
||||||
|
end
|
||||||
|
@session[@sort_name] = sort
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns an SQL sort clause corresponding to the current sort state.
|
||||||
|
# Use this to sort the controller's table items collection.
|
||||||
|
#
|
||||||
|
def sort_clause()
|
||||||
|
@session[@sort_name][:key] + ' ' + @session[@sort_name][:order]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns a link which sorts by the named column.
|
||||||
|
#
|
||||||
|
# - column is the name of an attribute in the sorted record collection.
|
||||||
|
# - The optional caption explicitly specifies the displayed link text.
|
||||||
|
# - A sort icon image is positioned to the right of the sort link.
|
||||||
|
#
|
||||||
|
def sort_link(column, caption=nil)
|
||||||
|
key, order = @session[@sort_name][:key], @session[@sort_name][:order]
|
||||||
|
if key == column
|
||||||
|
if order.downcase == 'asc'
|
||||||
|
icon = 'sort_asc'
|
||||||
|
order = 'desc'
|
||||||
|
else
|
||||||
|
icon = 'sort_desc'
|
||||||
|
order = 'asc'
|
||||||
|
end
|
||||||
|
else
|
||||||
|
icon = nil
|
||||||
|
order = 'desc' # changed for desc order by default
|
||||||
|
end
|
||||||
|
caption = titleize(Inflector::humanize(column)) unless caption
|
||||||
|
params = {:params => {:sort_key => column, :sort_order => order}}
|
||||||
|
link_to(caption, params) + (icon ? nbsp(2) + image_tag(icon) : '')
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns a table header <th> tag with a sort link for the named column
|
||||||
|
# attribute.
|
||||||
|
#
|
||||||
|
# Options:
|
||||||
|
# :caption The displayed link name (defaults to titleized column name).
|
||||||
|
# :title The tag's 'title' attribute (defaults to 'Sort by :caption').
|
||||||
|
#
|
||||||
|
# Other options hash entries generate additional table header tag attributes.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# <%= sort_header_tag('id', :title => 'Sort by contact ID', :width => 40) %>
|
||||||
|
#
|
||||||
|
# Renders:
|
||||||
|
#
|
||||||
|
# <th title="Sort by contact ID" width="40">
|
||||||
|
# <a href="/contact/list?sort_order=desc&sort_key=id">Id</a>
|
||||||
|
# <img alt="Sort_asc" src="/images/sort_asc.png" />
|
||||||
|
# </th>
|
||||||
|
#
|
||||||
|
def sort_header_tag(column, options = {})
|
||||||
|
if options[:caption]
|
||||||
|
caption = options[:caption]
|
||||||
|
options.delete(:caption)
|
||||||
|
else
|
||||||
|
caption = titleize(Inflector::humanize(column))
|
||||||
|
end
|
||||||
|
options[:title]= "Sort by #{caption}" unless options[:title]
|
||||||
|
content_tag('th', sort_link(column, caption), options)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# Return n non-breaking spaces.
|
||||||
|
def nbsp(n)
|
||||||
|
' ' * n
|
||||||
|
end
|
||||||
|
|
||||||
|
# Return capitalized title.
|
||||||
|
def titleize(title)
|
||||||
|
title.split.map {|w| w.capitalize }.join(' ')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module TrackersHelper
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module UsersHelper
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module VersionsHelper
|
||||||
|
end
|
|
@ -0,0 +1,19 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
module WelcomeHelper
|
||||||
|
end
|
|
@ -0,0 +1,81 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
require "digest/md5"
|
||||||
|
|
||||||
|
class Attachment < ActiveRecord::Base
|
||||||
|
belongs_to :container, :polymorphic => true
|
||||||
|
belongs_to :author, :class_name => "User", :foreign_key => "author_id"
|
||||||
|
|
||||||
|
validates_presence_of :filename
|
||||||
|
|
||||||
|
def file=(incomming_file)
|
||||||
|
unless incomming_file.nil?
|
||||||
|
@temp_file = incomming_file
|
||||||
|
if @temp_file.size > 0
|
||||||
|
self.filename = sanitize_filename(@temp_file.original_filename)
|
||||||
|
self.disk_filename = DateTime.now.strftime("%y%m%d%H%M%S") + "_" + self.filename
|
||||||
|
self.content_type = @temp_file.content_type
|
||||||
|
self.size = @temp_file.size
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Copy temp file to its final location
|
||||||
|
def before_save
|
||||||
|
if @temp_file && (@temp_file.size > 0)
|
||||||
|
logger.debug("saving '#{self.diskfile}'")
|
||||||
|
File.open(diskfile, "wb") do |f|
|
||||||
|
f.write(@temp_file.read)
|
||||||
|
end
|
||||||
|
self.digest = Digest::MD5.hexdigest(File.read(diskfile))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Deletes file on the disk
|
||||||
|
def after_destroy
|
||||||
|
if self.filename?
|
||||||
|
File.delete(diskfile) if File.exist?(diskfile)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns file's location on disk
|
||||||
|
def diskfile
|
||||||
|
"#{RDM_STORAGE_PATH}/#{self.disk_filename}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def increment_download
|
||||||
|
increment!(:downloads)
|
||||||
|
end
|
||||||
|
|
||||||
|
# returns last created projects
|
||||||
|
def self.most_downloaded
|
||||||
|
find(:all, :limit => 5, :order => "downloads DESC")
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def sanitize_filename(value)
|
||||||
|
# get only the filename, not the whole path
|
||||||
|
just_filename = value.gsub(/^.*(\\|\/)/, '')
|
||||||
|
# NOTE: File.basename doesn't work right with Windows paths on Unix
|
||||||
|
# INCORRECT: just_filename = File.basename(value.gsub('\\\\', '/'))
|
||||||
|
|
||||||
|
# Finally, replace all non alphanumeric, underscore or periods with underscore
|
||||||
|
@filename = just_filename.gsub(/[^\w\.\-]/,'_')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,38 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class CustomField < ActiveRecord::Base
|
||||||
|
|
||||||
|
has_and_belongs_to_many :projects
|
||||||
|
has_many :custom_values, :dependent => true
|
||||||
|
has_many :issues, :through => :issue_custom_values
|
||||||
|
|
||||||
|
validates_presence_of :name, :typ
|
||||||
|
validates_uniqueness_of :name
|
||||||
|
|
||||||
|
TYPES = [
|
||||||
|
[ "Integer", 0 ],
|
||||||
|
[ "String", 1 ],
|
||||||
|
[ "Date", 2 ],
|
||||||
|
[ "Boolean", 3 ],
|
||||||
|
[ "List", 4 ]
|
||||||
|
].freeze
|
||||||
|
|
||||||
|
def self.for_all
|
||||||
|
find(:all, :conditions => ["is_for_all=?", true])
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,41 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class CustomValue < ActiveRecord::Base
|
||||||
|
belongs_to :issue
|
||||||
|
belongs_to :custom_field
|
||||||
|
|
||||||
|
protected
|
||||||
|
def validate
|
||||||
|
errors.add(custom_field.name, "can't be blank") if custom_field.is_required? and value.empty?
|
||||||
|
errors.add(custom_field.name, "is not valid") unless custom_field.regexp.empty? or value =~ Regexp.new(custom_field.regexp)
|
||||||
|
|
||||||
|
case custom_field.typ
|
||||||
|
when 0
|
||||||
|
errors.add(custom_field.name, "must be an integer") unless value =~ /^[0-9]*$/
|
||||||
|
when 1
|
||||||
|
errors.add(custom_field.name, "is too short") if custom_field.min_length > 0 and value.length < custom_field.min_length and value.length > 0
|
||||||
|
errors.add(custom_field.name, "is too long") if custom_field.max_length > 0 and value.length > custom_field.max_length
|
||||||
|
when 2
|
||||||
|
errors.add(custom_field.name, "must be a valid date") unless value =~ /^(\d+)\/(\d+)\/(\d+)$/ or value.empty?
|
||||||
|
when 3
|
||||||
|
|
||||||
|
when 4
|
||||||
|
errors.add(custom_field.name, "is not a valid value") unless custom_field.possible_values.split('|').include? value or value.empty?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,24 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class Document < ActiveRecord::Base
|
||||||
|
belongs_to :project
|
||||||
|
belongs_to :category, :class_name => "Enumeration", :foreign_key => "category_id"
|
||||||
|
has_many :attachments, :as => :container, :dependent => true
|
||||||
|
|
||||||
|
validates_presence_of :title
|
||||||
|
end
|
|
@ -0,0 +1,45 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class Enumeration < ActiveRecord::Base
|
||||||
|
before_destroy :check_integrity
|
||||||
|
|
||||||
|
validates_presence_of :opt, :name
|
||||||
|
|
||||||
|
OPTIONS = [
|
||||||
|
["Issue priorities", "IPRI"],
|
||||||
|
["Document categories", "DCAT"]
|
||||||
|
].freeze
|
||||||
|
|
||||||
|
def self.get_values(option)
|
||||||
|
find(:all, :conditions => ['opt=?', option])
|
||||||
|
end
|
||||||
|
|
||||||
|
def name
|
||||||
|
_ self.attributes['name']
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def check_integrity
|
||||||
|
case self.opt
|
||||||
|
when "IPRI"
|
||||||
|
raise "Can't delete enumeration" if Issue.find(:first, :conditions => ["priority_id=?", self.id])
|
||||||
|
when "DCAT"
|
||||||
|
raise "Can't delete enumeration" if Document.find(:first, :conditions => ["category_id=?", self.id])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,55 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class Issue < ActiveRecord::Base
|
||||||
|
|
||||||
|
belongs_to :project
|
||||||
|
belongs_to :tracker
|
||||||
|
belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
|
||||||
|
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
|
||||||
|
belongs_to :assigned_to, :class_name => 'User', :foreign_key => 'assigned_to_id'
|
||||||
|
belongs_to :fixed_version, :class_name => 'Version', :foreign_key => 'fixed_version_id'
|
||||||
|
belongs_to :priority, :class_name => 'Enumeration', :foreign_key => 'priority_id'
|
||||||
|
belongs_to :category, :class_name => 'IssueCategory', :foreign_key => 'category_id'
|
||||||
|
|
||||||
|
has_many :histories, :class_name => 'IssueHistory', :dependent => true, :order => "issue_histories.created_on DESC", :include => :status
|
||||||
|
has_many :attachments, :as => :container, :dependent => true
|
||||||
|
|
||||||
|
has_many :custom_values, :dependent => true
|
||||||
|
has_many :custom_fields, :through => :custom_values
|
||||||
|
|
||||||
|
validates_presence_of :subject, :descr, :priority, :tracker, :author
|
||||||
|
|
||||||
|
# set default status for new issues
|
||||||
|
def before_create
|
||||||
|
self.status = IssueStatus.default
|
||||||
|
build_history
|
||||||
|
end
|
||||||
|
|
||||||
|
def long_id
|
||||||
|
"%05d" % self.id
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
# Creates an history for the issue
|
||||||
|
def build_history
|
||||||
|
@history = self.histories.build
|
||||||
|
@history.status = self.status
|
||||||
|
@history.author = self.author
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,28 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class IssueCategory < ActiveRecord::Base
|
||||||
|
before_destroy :check_integrity
|
||||||
|
belongs_to :project
|
||||||
|
|
||||||
|
validates_presence_of :name
|
||||||
|
|
||||||
|
private
|
||||||
|
def check_integrity
|
||||||
|
raise "Can't delete category" if Issue.find(:first, :conditions => ["category_id=?", self.id])
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,23 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class IssueHistory < ActiveRecord::Base
|
||||||
|
belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
|
||||||
|
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
|
||||||
|
|
||||||
|
validates_presence_of :status
|
||||||
|
end
|
|
@ -0,0 +1,47 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class IssueStatus < ActiveRecord::Base
|
||||||
|
before_destroy :check_integrity
|
||||||
|
has_many :workflows, :foreign_key => "old_status_id"
|
||||||
|
|
||||||
|
validates_presence_of :name
|
||||||
|
validates_uniqueness_of :name
|
||||||
|
|
||||||
|
# Returns the default status for new issues
|
||||||
|
def self.default
|
||||||
|
find(:first, :conditions =>["is_default=?", true])
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns an array of all statuses the given role can switch to
|
||||||
|
def new_statuses_allowed_to(role, tracker)
|
||||||
|
statuses = []
|
||||||
|
for workflow in self.workflows.find(:all, :include => :new_status)
|
||||||
|
statuses << workflow.new_status if workflow.role_id == role.id and workflow.tracker_id == tracker.id
|
||||||
|
end unless role.nil?
|
||||||
|
statuses
|
||||||
|
end
|
||||||
|
|
||||||
|
def name
|
||||||
|
_ self.attributes['name']
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def check_integrity
|
||||||
|
raise "Can't delete status" if Issue.find(:first, :conditions => ["status_id=?", self.id]) or IssueHistory.find(:first, :conditions => ["status_id=?", self.id])
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,36 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class Mailer < ActionMailer::Base
|
||||||
|
|
||||||
|
def issue_change_status(issue)
|
||||||
|
# Sends to all project members
|
||||||
|
@recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
|
||||||
|
@from = 'redmine@somenet.foo'
|
||||||
|
@subject = "Issue ##{issue.id} has been updated"
|
||||||
|
@body['issue'] = issue
|
||||||
|
end
|
||||||
|
|
||||||
|
def issue_add(issue)
|
||||||
|
# Sends to all project members
|
||||||
|
@recipients = issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
|
||||||
|
@from = 'redmine@somenet.foo'
|
||||||
|
@subject = "Issue ##{issue.id} has been reported"
|
||||||
|
@body['issue'] = issue
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,29 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class Member < ActiveRecord::Base
|
||||||
|
belongs_to :user
|
||||||
|
belongs_to :role
|
||||||
|
belongs_to :project
|
||||||
|
|
||||||
|
validates_presence_of :role, :user, :project
|
||||||
|
validates_uniqueness_of :user_id, :scope => :project_id
|
||||||
|
|
||||||
|
def name
|
||||||
|
self.user.display_name
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,28 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class News < ActiveRecord::Base
|
||||||
|
belongs_to :project
|
||||||
|
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
|
||||||
|
|
||||||
|
validates_presence_of :title, :shortdescr, :descr
|
||||||
|
|
||||||
|
# returns last created news
|
||||||
|
def self.latest
|
||||||
|
find(:all, :limit => 5, :include => [ :author, :project ], :order => "news.created_on DESC")
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,63 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class Permission < ActiveRecord::Base
|
||||||
|
has_and_belongs_to_many :roles
|
||||||
|
|
||||||
|
validates_presence_of :controller, :action, :descr
|
||||||
|
|
||||||
|
GROUPS = {
|
||||||
|
100 => "Project",
|
||||||
|
200 => "Membres",
|
||||||
|
300 => "Versions",
|
||||||
|
400 => "Issue categories",
|
||||||
|
1000 => "Issues",
|
||||||
|
1100 => "News",
|
||||||
|
1200 => "Documents",
|
||||||
|
1300 => "Files",
|
||||||
|
}.freeze
|
||||||
|
|
||||||
|
@@cached_perms_for_public = nil
|
||||||
|
@@cached_perms_for_roles = nil
|
||||||
|
|
||||||
|
def name
|
||||||
|
self.controller + "/" + self.action
|
||||||
|
end
|
||||||
|
|
||||||
|
def group_id
|
||||||
|
(self.sort / 100)*100
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.allowed_to_public(action)
|
||||||
|
@@cached_perms_for_public ||= find(:all, :conditions => ["public=?", true]).collect {|p| "#{p.controller}/#{p.action}"}
|
||||||
|
@@cached_perms_for_public.include? action
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.allowed_to_role(action, role)
|
||||||
|
@@cached_perms_for_roles ||=
|
||||||
|
begin
|
||||||
|
perms = {}
|
||||||
|
find(:all, :include => :roles).each {|p| perms.store "#{p.controller}/#{p.action}", p.roles.collect {|r| r.id } }
|
||||||
|
perms
|
||||||
|
end
|
||||||
|
@@cached_perms_for_roles[action] and @@cached_perms_for_roles[action].include? role
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.allowed_to_role_expired
|
||||||
|
@@cached_perms_for_roles = nil
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,44 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class Project < ActiveRecord::Base
|
||||||
|
has_many :versions, :dependent => true, :order => "versions.date DESC"
|
||||||
|
has_many :members, :dependent => true
|
||||||
|
has_many :issues, :dependent => true, :order => "issues.created_on DESC", :include => :status
|
||||||
|
has_many :documents, :dependent => true
|
||||||
|
has_many :news, :dependent => true, :order => "news.created_on DESC", :include => :author
|
||||||
|
has_many :issue_categories, :dependent => true
|
||||||
|
has_and_belongs_to_many :custom_fields
|
||||||
|
|
||||||
|
validates_presence_of :name, :descr
|
||||||
|
|
||||||
|
# returns 5 last created projects
|
||||||
|
def self.latest
|
||||||
|
find(:all, :limit => 5, :order => "created_on DESC")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns current version of the project
|
||||||
|
def current_version
|
||||||
|
versions.find(:first, :conditions => [ "date <= ?", Date.today ], :order => "date DESC, id DESC")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns an array of all custom fields enabled for project issues
|
||||||
|
# (explictly associated custom fields and custom fields enabled for all projects)
|
||||||
|
def custom_fields_for_issues
|
||||||
|
(CustomField.for_all + custom_fields).uniq
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,31 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class Role < ActiveRecord::Base
|
||||||
|
before_destroy :check_integrity
|
||||||
|
has_and_belongs_to_many :permissions
|
||||||
|
has_many :workflows, :dependent => true
|
||||||
|
has_many :members
|
||||||
|
|
||||||
|
validates_presence_of :name
|
||||||
|
validates_uniqueness_of :name
|
||||||
|
|
||||||
|
private
|
||||||
|
def check_integrity
|
||||||
|
raise "Can't delete role" if Member.find(:first, :conditions =>["role_id=?", self.id])
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,31 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class Tracker < ActiveRecord::Base
|
||||||
|
before_destroy :check_integrity
|
||||||
|
has_many :issues
|
||||||
|
has_many :workflows, :dependent => true
|
||||||
|
|
||||||
|
def name
|
||||||
|
_ self.attributes['name']
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def check_integrity
|
||||||
|
raise "Can't delete tracker" if Issue.find(:first, :conditions => ["tracker_id=?", self.id])
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,89 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
require "digest/sha1"
|
||||||
|
|
||||||
|
class User < ActiveRecord::Base
|
||||||
|
has_many :memberships, :class_name => 'Member', :include => [ :project, :role ], :dependent => true
|
||||||
|
|
||||||
|
attr_accessor :password
|
||||||
|
attr_accessor :last_before_login_on
|
||||||
|
# Prevents unauthorized assignments
|
||||||
|
attr_protected :admin
|
||||||
|
|
||||||
|
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 :mail, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
|
||||||
|
|
||||||
|
def before_create
|
||||||
|
self.hashed_password = User.hash_password(self.password)
|
||||||
|
end
|
||||||
|
|
||||||
|
def after_create
|
||||||
|
@password = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the user that matches user's login and password
|
||||||
|
def try_to_login
|
||||||
|
@user = User.login(self.login, self.password)
|
||||||
|
unless @user.nil?
|
||||||
|
@user.last_before_login_on = @user.last_login_on
|
||||||
|
@user.update_attribute(:last_login_on, DateTime.now)
|
||||||
|
end
|
||||||
|
@user
|
||||||
|
end
|
||||||
|
|
||||||
|
# Return user's full name for display
|
||||||
|
def display_name
|
||||||
|
firstname + " " + lastname #+ (self.admin ? " (Admin)" : "" )
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns the user that matches the given login and password
|
||||||
|
def self.login(login, password)
|
||||||
|
hashed_password = hash_password(password || "")
|
||||||
|
find(:first,
|
||||||
|
:conditions => ["login = ? and hashed_password = ? and locked = ?", login, hashed_password, false])
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_password?(clear_password)
|
||||||
|
User.hash_password(clear_password) == self.hashed_password
|
||||||
|
end
|
||||||
|
|
||||||
|
def change_password(current_password, new_password)
|
||||||
|
self.hashed_password = User.hash_password(new_password)
|
||||||
|
save
|
||||||
|
end
|
||||||
|
|
||||||
|
def role_for_project(project_id)
|
||||||
|
@role_for_projects ||=
|
||||||
|
begin
|
||||||
|
roles = {}
|
||||||
|
self.memberships.each { |m| roles.store m.project_id, m.role_id }
|
||||||
|
roles
|
||||||
|
end
|
||||||
|
@role_for_projects[project_id]
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
# Return password digest
|
||||||
|
def self.hash_password(clear_password)
|
||||||
|
Digest::SHA1.hexdigest(clear_password)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,30 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class Version < ActiveRecord::Base
|
||||||
|
before_destroy :check_integrity
|
||||||
|
belongs_to :project
|
||||||
|
has_many :fixed_issues, :class_name => 'Issue', :foreign_key => 'fixed_version_id'
|
||||||
|
has_many :attachments, :as => :container, :dependent => true
|
||||||
|
|
||||||
|
validates_presence_of :name, :descr
|
||||||
|
|
||||||
|
private
|
||||||
|
def check_integrity
|
||||||
|
raise "Can't delete version" if self.fixed_issues.find(:first)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,25 @@
|
||||||
|
# redMine - project management software
|
||||||
|
# Copyright (C) 2006 Jean-Philippe Lang
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
class Workflow < ActiveRecord::Base
|
||||||
|
|
||||||
|
belongs_to :role
|
||||||
|
belongs_to :old_status, :class_name => 'IssueStatus', :foreign_key => 'old_status_id'
|
||||||
|
belongs_to :new_status, :class_name => 'IssueStatus', :foreign_key => 'new_status_id'
|
||||||
|
|
||||||
|
validates_presence_of :role, :old_status, :new_status
|
||||||
|
end
|
|
@ -0,0 +1,13 @@
|
||||||
|
<div class="box">
|
||||||
|
<h2><%=_ 'Please login' %></h2>
|
||||||
|
|
||||||
|
<%= start_form_tag :action=> "login" %>
|
||||||
|
<p><label for="user_login"><%=_ 'Login' %>:</label><br/>
|
||||||
|
<input type="text" name="user[login]" id="user_login" size="30" /></p>
|
||||||
|
|
||||||
|
<p><label for="user_password"><%=_ 'Password' %>:</label><br/>
|
||||||
|
<input type="password" name="user[password]" id="user_password" size="30"/></p>
|
||||||
|
|
||||||
|
<p><input type="submit" name="login" value="<%=_ 'Log in' %> »" class="primary" /></p>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
</div>
|
|
@ -0,0 +1,54 @@
|
||||||
|
<h2><%=_('My account')%></h2>
|
||||||
|
|
||||||
|
<p><%=_('Login')%>: <strong><%= @user.login %></strong><br />
|
||||||
|
<%=_('Created on')%>: <%= format_time(@user.created_on) %>,
|
||||||
|
<%=_('Last update')%>: <%= format_time(@user.updated_on) %></p>
|
||||||
|
|
||||||
|
<div class="splitcontentleft">
|
||||||
|
<div class="box">
|
||||||
|
<h3><%=_('Information')%></h3>
|
||||||
|
|
||||||
|
<%= start_form_tag :action => 'my_account' %>
|
||||||
|
<%= error_messages_for 'user' %>
|
||||||
|
|
||||||
|
<!--[form:user]-->
|
||||||
|
<p><label for="user_firstname"><%=_('Firstname')%> <span class="required">*</span></label><br/>
|
||||||
|
<%= text_field 'user', 'firstname' %></p>
|
||||||
|
|
||||||
|
<p><label for="user_lastname"><%=_('Lastname')%> <span class="required">*</span></label><br/>
|
||||||
|
<%= text_field 'user', 'lastname' %></p>
|
||||||
|
|
||||||
|
<p><label for="user_mail"><%=_('Mail')%> <span class="required">*</span></label><br/>
|
||||||
|
<%= text_field 'user', 'mail' %></p>
|
||||||
|
|
||||||
|
<p><label for="user_language"><%=_('Language')%></label><br/>
|
||||||
|
<%= select("user", "language", Localization.langs) %></p>
|
||||||
|
<!--[eoform:user]-->
|
||||||
|
|
||||||
|
<p><%= check_box 'user', 'mail_notification' %> <label for="user_mail_notification"><%=_('Mail notifications')%></label></p>
|
||||||
|
|
||||||
|
<center><%= submit_tag _('Save') %></center>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="splitcontentright">
|
||||||
|
<div class="box">
|
||||||
|
<h3><%=_('Password')%></h3>
|
||||||
|
|
||||||
|
<%= start_form_tag :action => 'change_password' %>
|
||||||
|
|
||||||
|
<p><label for="old_password"><%=_('Password')%> <span class="required">*</span></label><br/>
|
||||||
|
<%= password_field_tag 'old_password' %></p>
|
||||||
|
|
||||||
|
<p><label for="new_password"><%=_('New password')%> <span class="required">*</span></label><br/>
|
||||||
|
<%= password_field_tag 'new_password' %></p>
|
||||||
|
|
||||||
|
<p><label for="new_password_confirmation"><%=_('Confirmation')%> <span class="required">*</span></label><br/>
|
||||||
|
<%= password_field_tag 'new_password_confirmation' %></p>
|
||||||
|
|
||||||
|
<center><%= submit_tag _('Save') %></center>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,19 @@
|
||||||
|
<h2><%=_('My page') %></h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%=_('Welcome')%> <b><%= @user.firstname %></b><br />
|
||||||
|
<% unless @user.last_before_login_on.nil? %>
|
||||||
|
<%=_('Last login')%>: <%= format_time(@user.last_before_login_on) %>
|
||||||
|
<% end %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="splitcontentleft">
|
||||||
|
<h3><%=_('Reported issues')%></h3>
|
||||||
|
<%= render :partial => 'issues/list_simple', :locals => { :issues => @reported_issues } %>
|
||||||
|
<%= "<p>(Last #{@reported_issues.length} updated)</p>" if @reported_issues.length > 0 %>
|
||||||
|
</div>
|
||||||
|
<div class="splitcontentright">
|
||||||
|
<h3><%=_('Assigned to me')%></h3>
|
||||||
|
<%= render :partial => 'issues/list_simple', :locals => { :issues => @assigned_issues } %>
|
||||||
|
<%= "<p>(Last #{@assigned_issues.length} updated)</p>" if @assigned_issues.length > 0 %>
|
||||||
|
</div>
|
|
@ -0,0 +1,19 @@
|
||||||
|
<h2><%= @user.display_name %></h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= mail_to @user.mail %><br />
|
||||||
|
<%=_('Registered on')%>: <%= format_date(@user.created_on) %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3><%=_('Projects')%></h3>
|
||||||
|
<p>
|
||||||
|
<% for membership in @user.memberships %>
|
||||||
|
<%= membership.project.name %> (<%= membership.role.name %>, <%= format_date(membership.created_on) %>)
|
||||||
|
<br />
|
||||||
|
<% end %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3><%=_('Activity')%></h3>
|
||||||
|
<p>
|
||||||
|
<%=_('Reported issues')%>: <%= Issue.count( [ "author_id=?", @user.id]) %>
|
||||||
|
</p>
|
|
@ -0,0 +1,45 @@
|
||||||
|
<h2><%=_('Administration')%></h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= image_tag "projects" %>
|
||||||
|
<%= link_to _('Projects'), :controller => 'admin', :action => 'projects' %> |
|
||||||
|
<%= link_to _('New'), :controller => 'projects', :action => 'add' %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= image_tag "users" %>
|
||||||
|
<%= link_to _('Users'), :controller => 'users' %> |
|
||||||
|
<%= link_to _('New'), :controller => 'users', :action => 'add' %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= image_tag "role" %>
|
||||||
|
<%= link_to _('Roles and permissions'), :controller => 'roles' %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= image_tag "tracker" %>
|
||||||
|
<%= link_to _('Trackers'), :controller => 'trackers' %> |
|
||||||
|
<%= link_to _('Custom fields'), :controller => 'custom_fields' %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= image_tag "workflow" %>
|
||||||
|
<%= link_to _('Issue Statuses'), :controller => 'issue_statuses' %> |
|
||||||
|
<%= link_to _('Workflow'), :controller => 'roles', :action => 'workflow' %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= image_tag "options" %>
|
||||||
|
<%= link_to _('Enumerations'), :controller => 'enumerations' %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= image_tag "mailer" %>
|
||||||
|
<%= link_to _('Mail notifications'), :controller => 'admin', :action => 'mail_options' %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<%= image_tag "help" %>
|
||||||
|
<%= link_to _('Information'), :controller => 'admin', :action => 'info' %>
|
||||||
|
</p>
|
|
@ -0,0 +1,4 @@
|
||||||
|
<h2><%=_('Information')%></h2>
|
||||||
|
|
||||||
|
<%=_('Version')%>: <%= RDM_APP_NAME %> <%= RDM_APP_VERSION %><br />
|
||||||
|
<%=_('Database')%>: <%= @adapter_name %>
|
|
@ -0,0 +1,16 @@
|
||||||
|
<h2><%=_('Mail notifications')%></h2>
|
||||||
|
|
||||||
|
<p><%=_('Select actions for which mail notification should be enabled.')%></p>
|
||||||
|
|
||||||
|
<%= start_form_tag ({}, :id => 'mail_options_form')%>
|
||||||
|
<% for action in @actions %>
|
||||||
|
<%= check_box_tag "action_ids[]", action.id, action.mail_enabled? %>
|
||||||
|
<%= action.descr %><br />
|
||||||
|
<% end %>
|
||||||
|
<br />
|
||||||
|
<p>
|
||||||
|
<a href="javascript:checkAll('mail_options_form', true)"><%=_('Check all')%></a> |
|
||||||
|
<a href="javascript:checkAll('mail_options_form', false)"><%=_('Uncheck all')%></a>
|
||||||
|
</p>
|
||||||
|
<%= submit_tag _('Save') %>
|
||||||
|
<%= end_form_tag %>
|
|
@ -0,0 +1,35 @@
|
||||||
|
<h2><%=_('Projects')%></h2>
|
||||||
|
|
||||||
|
<table width="100%" cellspacing="1" cellpadding="2" class="listTableContent">
|
||||||
|
<tr class="ListHead">
|
||||||
|
<%= sort_header_tag('projects.name', :caption => _('Project')) %>
|
||||||
|
<th><%=_('Description')%></th>
|
||||||
|
<th><%=_('Public')%></th>
|
||||||
|
<%= sort_header_tag('projects.created_on', :caption => _('Created on')) %>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<% odd_or_even = 1
|
||||||
|
for project in @projects
|
||||||
|
odd_or_even = 1 - odd_or_even %>
|
||||||
|
<tr class="ListLine<%= odd_or_even %>">
|
||||||
|
<td><%= link_to project.name, :controller => 'projects', :action => 'settings', :id => project %>
|
||||||
|
<td><%= project.descr %>
|
||||||
|
<td align="center"><%= image_tag 'true' if project.public? %>
|
||||||
|
<td align="center"><%= format_date(project.created_on) %>
|
||||||
|
<td align="center">
|
||||||
|
<%= start_form_tag({:controller => 'projects', :action => 'destroy', :id => project}) %>
|
||||||
|
<%= submit_tag _('Delete'), :class => "button-small" %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<%= link_to ('« ' + _('Previous')), { :page => @project_pages.current.previous } if @project_pages.current.previous %>
|
||||||
|
<%= pagination_links(@project_pages) %>
|
||||||
|
<%= link_to (_('Next') + ' »'), { :page => @project_pages.current.next } if @project_pages.current.next %>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<%= link_to ('» ' + _('New project')), :controller => 'projects', :action => 'add' %>
|
|
@ -0,0 +1,26 @@
|
||||||
|
<%= error_messages_for 'custom_field' %>
|
||||||
|
|
||||||
|
<!--[form:custom_field]-->
|
||||||
|
<p><label for="custom_field_name"><%=_('Name')%></label><br/>
|
||||||
|
<%= text_field 'custom_field', 'name' %></p>
|
||||||
|
|
||||||
|
<p><label for="custom_field_typ"><%=_('Type')%></label><br/>
|
||||||
|
<%= select("custom_field", "typ", CustomField::TYPES) %></p>
|
||||||
|
|
||||||
|
<p><%= check_box 'custom_field', 'is_required' %>
|
||||||
|
<label for="custom_field_is_required"><%=_('Required')%></label></p>
|
||||||
|
|
||||||
|
<p><%= check_box 'custom_field', 'is_for_all' %>
|
||||||
|
<label for="custom_field_is_for_all"><%=_('For all projects')%></label></p>
|
||||||
|
|
||||||
|
<p><label for="custom_field_min_length"><%=_('Min - max length')%></label> (<%=_('0 means no restriction')%>)<br/>
|
||||||
|
<%= text_field 'custom_field', 'min_length', :size => 5 %> -
|
||||||
|
<%= text_field 'custom_field', 'max_length', :size => 5 %></p>
|
||||||
|
|
||||||
|
<p><label for="custom_field_regexp"><%=_('Regular expression pattern')%></label> (eg. ^[A-Z0-9]+$)<br/>
|
||||||
|
<%= text_field 'custom_field', 'regexp', :size => 50 %></p>
|
||||||
|
|
||||||
|
<p><label for="custom_field_possible_values"><%=_('Possible values')%></label> (separator: |)<br/>
|
||||||
|
<%= text_area 'custom_field', 'possible_values', :rows => 5, :cols => 60 %></p>
|
||||||
|
<!--[eoform:custom_field]-->
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<h2><%=_('Custom field')%></h2>
|
||||||
|
|
||||||
|
<%= start_form_tag :action => 'edit', :id => @custom_field %>
|
||||||
|
<%= render :partial => 'form' %>
|
||||||
|
<%= submit_tag _('Save') %>
|
||||||
|
<%= end_form_tag %>
|
|
@ -0,0 +1,32 @@
|
||||||
|
<h2><%=_('Custom fields')%></h2>
|
||||||
|
|
||||||
|
<table border="0" cellspacing="1" cellpadding="2" class="listTableContent">
|
||||||
|
<tr class="ListHead">
|
||||||
|
<th><%=_('Name')%></th>
|
||||||
|
<th><%=_('Type')%></th>
|
||||||
|
<th><%=_('Required')%></th>
|
||||||
|
<th><%=_('For all projects')%></th>
|
||||||
|
<th><%=_('Used by')%></th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
<% for custom_field in @custom_fields %>
|
||||||
|
<tr style="background-color:#CEE1ED">
|
||||||
|
<td><%= link_to custom_field.name, :action => 'edit', :id => custom_field %></td>
|
||||||
|
<td align="center"><%= CustomField::TYPES[custom_field.typ][0] %></td>
|
||||||
|
<td align="center"><%= image_tag 'true' if custom_field.is_required? %></td>
|
||||||
|
<td align="center"><%= image_tag 'true' if custom_field.is_for_all? %></td>
|
||||||
|
<td align="center"><%= custom_field.projects.count.to_s + ' ' + _('Project') + '(s)' unless custom_field.is_for_all? %></td>
|
||||||
|
<td align="center">
|
||||||
|
<%= start_form_tag :action => 'destroy', :id => custom_field %>
|
||||||
|
<%= submit_tag _('Delete'), :class => "button-small" %>
|
||||||
|
<%= end_form_tag %> </td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<%= link_to ('« ' + _('Previous')), { :page => @custom_field_pages.current.previous } if @custom_field_pages.current.previous %>
|
||||||
|
<%= link_to (_('Next') + ' »'), { :page => @custom_field_pages.current.next } if @custom_field_pages.current.next %>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<%= link_to ('» ' + _('New custom field')), :action => 'new' %>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<h2><%=_('New custom field')%></h2>
|
||||||
|
|
||||||
|
<%= start_form_tag :action => 'new' %>
|
||||||
|
<%= render :partial => 'form' %>
|
||||||
|
<%= submit_tag _('Create') %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
<%= error_messages_for 'document' %>
|
||||||
|
|
||||||
|
<!--[form:document]-->
|
||||||
|
<p><label for="document_category_id"><%=_('Category')%></label><br />
|
||||||
|
<select name="document[category_id]">
|
||||||
|
<%= options_from_collection_for_select @categories, "id", "name",@document.category_id %>
|
||||||
|
</select></p>
|
||||||
|
|
||||||
|
<p><label for="document_title"><%=_('Title')%> <span class="required">*</span></label><br />
|
||||||
|
<%= text_field 'document', 'title', :size => 60 %></p>
|
||||||
|
|
||||||
|
<p><label for="document_descr"><%=_('Description')%> <span class="required">*</span></label><br />
|
||||||
|
<%= text_area 'document', 'descr', :cols => 60, :rows => 5 %></p>
|
||||||
|
<!--[eoform:document]-->
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<h2><%=_('Document')%></h2>
|
||||||
|
|
||||||
|
<%= start_form_tag :action => 'edit', :id => @document %>
|
||||||
|
<%= render :partial => 'form' %>
|
||||||
|
<%= submit_tag _('Save') %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
<h2><%= @document.title %></h2>
|
||||||
|
|
||||||
|
<strong><%=_('Description')%>:</strong> <%= @document.descr %><br />
|
||||||
|
<strong><%=_('Category')%>:</strong> <%= @document.category.name %><br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<% if authorize_for('documents', 'edit') %>
|
||||||
|
<%= start_form_tag ({ :controller => 'documents', :action => 'edit', :id => @document }, :method => 'get' ) %>
|
||||||
|
<%= submit_tag _('Edit') %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if authorize_for('documents', 'destroy') %>
|
||||||
|
<%= start_form_tag ({ :controller => 'documents', :action => 'destroy', :id => @document } ) %>
|
||||||
|
<%= submit_tag _('Delete') %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<br /><br />
|
||||||
|
|
||||||
|
<table border="0" cellspacing="1" cellpadding="2" width="100%">
|
||||||
|
<% for attachment in @document.attachments %>
|
||||||
|
<tr style="background-color:#CEE1ED">
|
||||||
|
<td><%= link_to attachment.filename, :action => 'download', :id => @document, :attachment_id => attachment %></td>
|
||||||
|
<td align="center"><%= format_date(attachment.created_on) %></td>
|
||||||
|
<td align="center"><%= attachment.author.display_name %></td>
|
||||||
|
<td><%= human_size(attachment.size) %><br /><%= attachment.downloads %> <%=_('download')%>(s)</td>
|
||||||
|
<% if authorize_for('documents', 'destroy_attachment') %>
|
||||||
|
<td align="center">
|
||||||
|
<%= start_form_tag :action => 'destroy_attachment', :id => @document, :attachment_id => attachment %>
|
||||||
|
<%= submit_tag _('Delete'), :class => "button-small" %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<% if authorize_for('documents', 'add_attachment') %>
|
||||||
|
<%= start_form_tag ({ :controller => 'documents', :action => 'add_attachment', :id => @document }, :multipart => true) %>
|
||||||
|
<%=_('Add file')%><br /><%= file_field 'attachment', 'file' %>
|
||||||
|
<%= submit_tag _('Add') %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
<% end %>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<%= error_messages_for 'enumeration' %>
|
||||||
|
|
||||||
|
<!--[form:optvalue]-->
|
||||||
|
<%= hidden_field 'enumeration', 'opt' %>
|
||||||
|
|
||||||
|
<p><label for="enumeration_name"><%=_('Name')%></label><br/>
|
||||||
|
<%= text_field 'enumeration', 'name' %></p>
|
||||||
|
<!--[eoform:optvalue]-->
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<h2><%=_('Enumerations')%></h2>
|
||||||
|
|
||||||
|
<%= start_form_tag :action => 'update', :id => @enumeration %>
|
||||||
|
<%= render :partial => 'form' %>
|
||||||
|
<%= submit_tag _('Save') %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
|
||||||
|
<%= start_form_tag :action => 'destroy', :id => @enumeration %>
|
||||||
|
<%= submit_tag _('Delete') %>
|
||||||
|
<%= end_form_tag %>
|
|
@ -0,0 +1,22 @@
|
||||||
|
<h2><%=_('Enumerations')%></h2>
|
||||||
|
|
||||||
|
<% for option in Enumeration::OPTIONS %>
|
||||||
|
|
||||||
|
<% if @params[:opt]==option[1] %>
|
||||||
|
|
||||||
|
<p><%= image_tag 'dir_open' %> <b><%=_ option[0] %></b></p>
|
||||||
|
<ul>
|
||||||
|
<% for value in Enumeration::find(:all, :conditions => [ "opt = ?", option[1]]) %>
|
||||||
|
<li><%= link_to value.name, :action => 'edit', :id => value %></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
<ul>
|
||||||
|
<li><%= link_to ('» ' + _('New')), :action => 'new', :opt => option[1] %></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<% else %>
|
||||||
|
<p><%= image_tag 'dir' %> <%= link_to _(option[0]), :opt => option[1] %></p>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% end %>
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<h2><%=_('New enumeration')%></h2>
|
||||||
|
|
||||||
|
<%= start_form_tag :action => 'create' %>
|
||||||
|
<%= render :partial => 'form' %>
|
||||||
|
<%= submit_tag _('Create') %>
|
||||||
|
<%= end_form_tag %>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<%= error_messages_for 'issue_category' %>
|
||||||
|
|
||||||
|
<!--[form:issue_category]-->
|
||||||
|
<p><label for="issue_category_name"><%=_('Name')%></label><br/>
|
||||||
|
<%= text_field 'issue_category', 'name' %></p>
|
||||||
|
<!--[eoform:issue_category]-->
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<h2>Editing issue category</h2>
|
||||||
|
|
||||||
|
<%= start_form_tag :action => 'edit', :id => @category %>
|
||||||
|
<%= render :partial => 'form' %>
|
||||||
|
<%= submit_tag _('Save') %>
|
||||||
|
<%= end_form_tag %>
|
|
@ -0,0 +1,17 @@
|
||||||
|
<%= error_messages_for 'issue_status' %>
|
||||||
|
|
||||||
|
<!--[form:issue_status]-->
|
||||||
|
<p><label for="issue_status_name"><%=_('Name')%></label><br/>
|
||||||
|
<%= text_field 'issue_status', 'name' %></p>
|
||||||
|
|
||||||
|
<p><%= check_box 'issue_status', 'is_closed' %>
|
||||||
|
<label for="issue_status_is_closed"><%=_('Issue closed')%></label></p>
|
||||||
|
|
||||||
|
<p><%= check_box 'issue_status', 'is_default' %>
|
||||||
|
<label for="issue_status_is_default"><%=_('Default status')%></label></p>
|
||||||
|
|
||||||
|
<p><label for="issue_status_html_color"><%=_('Color')%></label>
|
||||||
|
#<%= text_field 'issue_status', 'html_color', :size => 6 %></p>
|
||||||
|
|
||||||
|
<!--[eoform:issue_status]-->
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<h2><%=_('Issue status')%></h2>
|
||||||
|
|
||||||
|
<%= start_form_tag :action => 'update', :id => @issue_status %>
|
||||||
|
<%= render :partial => 'form' %>
|
||||||
|
<%= submit_tag _('Save') %>
|
||||||
|
<%= end_form_tag %>
|
|
@ -0,0 +1,30 @@
|
||||||
|
<h2><%=_('Issue statuses')%></h2>
|
||||||
|
|
||||||
|
<table border="0" cellspacing="1" cellpadding="2" class="listTableContent">
|
||||||
|
<tr class="ListHead">
|
||||||
|
<th><%=_('Status')%></th>
|
||||||
|
<th><%=_('Default status')%></th>
|
||||||
|
<th><%=_('Issue closed')%></th>
|
||||||
|
<th><%=_('Color')%></th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<% for status in @issue_statuses %>
|
||||||
|
<tr style="background-color:#CEE1ED">
|
||||||
|
<td><%= link_to status.name, :action => 'edit', :id => status %></td>
|
||||||
|
<td align="center"><%= image_tag 'true' if status.is_default %></td>
|
||||||
|
<td align="center"><%= image_tag 'true' if status.is_closed %></td>
|
||||||
|
<td bgcolor="#<%= status.html_color %>"> </td>
|
||||||
|
<td align="center">
|
||||||
|
<%= start_form_tag :action => 'destroy', :id => status %>
|
||||||
|
<%= submit_tag _('Delete'), :class => "button-small" %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<%= pagination_links_full @issue_status_pages %>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<%= link_to '» ' + _('New issue status'), :action => 'new' %>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<h2><%=_('New issue status')%></h2>
|
||||||
|
|
||||||
|
<%= start_form_tag :action => 'create' %>
|
||||||
|
<%= render :partial => 'form' %>
|
||||||
|
<%= submit_tag _('Create') %>
|
||||||
|
<%= end_form_tag %>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<% if issues.length > 0 %>
|
||||||
|
<table cellspacing="0" cellpadding="1" width="100%" border="0" class="listTable">
|
||||||
|
<tr><td>
|
||||||
|
<table width="100%" border="0" cellspacing="1" cellpadding="2" class="listTableContent">
|
||||||
|
<tr class="ListHead">
|
||||||
|
<th>#</th>
|
||||||
|
<th><%=_('Tracker')%></th>
|
||||||
|
<th><%=_('Subject')%></th>
|
||||||
|
</tr>
|
||||||
|
<% for issue in issues %>
|
||||||
|
<tr bgcolor="#<%= issue.status.html_color %>">
|
||||||
|
<td align="center">
|
||||||
|
<%= link_to issue.id, :controller => 'issues', :action => 'show', :id => issue %><br />
|
||||||
|
</td>
|
||||||
|
<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 issue.subject, :controller => 'issues', :action => 'show', :id => issue %></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<% else %>
|
||||||
|
<%=_('No issue')%>
|
||||||
|
<% end %>
|
|
@ -0,0 +1,29 @@
|
||||||
|
<h2><%=_('Issue')%> #<%= @issue.id %>: <%= @issue.subject %></h2>
|
||||||
|
|
||||||
|
<%= error_messages_for 'history' %>
|
||||||
|
<%= start_form_tag :action => 'change_status', :id => @issue %>
|
||||||
|
|
||||||
|
<%= hidden_field_tag 'confirm', 1 %>
|
||||||
|
<%= hidden_field 'history', 'status_id' %>
|
||||||
|
|
||||||
|
<p><%=_('New status')%>: <b><%= @history.status.name %></b></p>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p><label for="issue_assigned_to_id"><%=_('Assigned to')%></label><br/>
|
||||||
|
<select name="issue[assigned_to_id]">
|
||||||
|
<option value=""></option>
|
||||||
|
<%= options_from_collection_for_select @assignable_to, "id", "display_name", @issue.assigned_to_id %></p>
|
||||||
|
</select></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p><label for="issue_fixed_version"><%=_('Fixed in version')%></label><br/>
|
||||||
|
<select name="issue[fixed_version_id]">
|
||||||
|
<option value="">--none--</option>
|
||||||
|
<%= options_from_collection_for_select @issue.project.versions, "id", "name", @issue.fixed_version_id %>
|
||||||
|
</select></p>
|
||||||
|
|
||||||
|
<p><label for="history_notes"><%=_('Notes')%></label><br />
|
||||||
|
<%= text_area 'history', 'notes', :cols => 60, :rows => 10 %></p>
|
||||||
|
|
||||||
|
<%= submit_tag _('Save') %>
|
||||||
|
<%= end_form_tag %>
|
|
@ -0,0 +1,62 @@
|
||||||
|
<h2><%=_('Issue')%> #<%= @issue.id %></h2>
|
||||||
|
|
||||||
|
<%= error_messages_for 'issue' %>
|
||||||
|
<%= start_form_tag :action => 'edit', :id => @issue %>
|
||||||
|
|
||||||
|
<!--[form:issue]-->
|
||||||
|
<p><%=_('Status')%>: <b><%= @issue.status.name %></b></p>
|
||||||
|
|
||||||
|
<div style="float:left;margin-right:10px;">
|
||||||
|
<p><label for="issue_tracker_id"><%=_('Tracker')%> <span class="required">*</span></label><br/>
|
||||||
|
<select name="issue[tracker_id]">
|
||||||
|
<%= options_from_collection_for_select @trackers, "id", "name", @issue.tracker_id %></p>
|
||||||
|
</select></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="float:left;margin-right:10px;">
|
||||||
|
<p><label for="issue_priority_id"><%=_('Priority')%> <span class="required">*</span></label><br/>
|
||||||
|
<select name="issue[priority_id]">
|
||||||
|
<%= options_from_collection_for_select @priorities, "id", "name", @issue.priority_id %></p>
|
||||||
|
</select></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="float:left;margin-right:10px;">
|
||||||
|
<p><label for="issue_assigned_to_id"><%=_('Assigned to')%></label><br/>
|
||||||
|
<select name="issue[assigned_to_id]">
|
||||||
|
<option value=""></option>
|
||||||
|
<%= options_from_collection_for_select @issue.project.members, "user_id", "name", @issue.assigned_to_id %></p>
|
||||||
|
</select></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<p><label for="issue_category_id"><%=_('Category')%></label><br/>
|
||||||
|
<select name="issue[category_id]">
|
||||||
|
<option value=""></option>
|
||||||
|
<%= options_from_collection_for_select @project.issue_categories, "id", "name", @issue.category_id %></p>
|
||||||
|
</select></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p><label for="issue_subject"><%=_('Subject')%></label><span class="required">*</span><br/>
|
||||||
|
<%= text_field 'issue', 'subject', :size => 60 %></p>
|
||||||
|
|
||||||
|
<p><label for="issue_descr"><%=_('Description')%></label><span class="required">*</span><br/>
|
||||||
|
<%= text_area 'issue', 'descr', :cols => 60, :rows => 10 %></p>
|
||||||
|
|
||||||
|
|
||||||
|
<% for custom_value in @custom_values %>
|
||||||
|
<p><%= content_tag "label", custom_value.custom_field.name %>
|
||||||
|
<% if custom_value.custom_field.is_required? %><span class="required">*</span><% end %>
|
||||||
|
<br />
|
||||||
|
<%= custom_field_tag custom_value %></p>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
|
||||||
|
<p><label for="issue_fixed_version"><%=_('Fixed in version')%></label><br/>
|
||||||
|
<select name="issue[fixed_version_id]">
|
||||||
|
<option value="">--none--</option>
|
||||||
|
<%= options_from_collection_for_select @project.versions, "id", "name", @issue.fixed_version_id %>
|
||||||
|
</select></p>
|
||||||
|
<!--[eoform:issue]-->
|
||||||
|
|
||||||
|
<center><%= submit_tag _('Save') %></center>
|
||||||
|
<%= end_form_tag %>
|
|
@ -0,0 +1,90 @@
|
||||||
|
|
||||||
|
<h2><%=_('Issue')%> #<%= @issue.id %> - <%= @issue.subject %></h2>
|
||||||
|
|
||||||
|
<div class="box">
|
||||||
|
<p><b><%=_('Tracker')%>:</b> <%= @issue.tracker.name %></p>
|
||||||
|
<p><b><%=_('Priority')%>:</b> <%= @issue.priority.name %></p>
|
||||||
|
<p><b><%=_('Category')%>:</b> <%= @issue.category.name unless @issue.category_id.nil? %></p>
|
||||||
|
<p><b><%=_('Status')%>:</b> <%= @issue.status.name %></p>
|
||||||
|
<p><b><%=_('Author')%>:</b> <%= @issue.author.display_name %></p>
|
||||||
|
<p><b><%=_('Assigned to')%>:</b> <%= @issue.assigned_to.display_name unless @issue.assigned_to.nil? %></p>
|
||||||
|
|
||||||
|
<p><b><%=_('Subject')%>:</b> <%= @issue.subject %></p>
|
||||||
|
<p><b><%=_('Description')%>:</b> <%= @issue.descr %></p>
|
||||||
|
<p><b><%=_('Created on')%>:</b> <%= format_date(@issue.created_on) %></p>
|
||||||
|
|
||||||
|
<% if authorize_for('issues', 'edit') %>
|
||||||
|
<%= start_form_tag ({:controller => 'issues', :action => 'edit', :id => @issue}, :method => "get" ) %>
|
||||||
|
<%= submit_tag _('Edit') %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if authorize_for('issues', 'change_status') and @status_options and !@status_options.empty? %>
|
||||||
|
<%= start_form_tag ({:controller => 'issues', :action => 'change_status', :id => @issue}) %>
|
||||||
|
<label for="history_status_id"><%=_('Change status')%>:</label>
|
||||||
|
<select name="history[status_id]">
|
||||||
|
<%= options_from_collection_for_select @status_options, "id", "name" %>
|
||||||
|
</select>
|
||||||
|
<%= submit_tag _ "Update..." %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if authorize_for('issues', 'destroy') %>
|
||||||
|
<%= start_form_tag ({:controller => 'issues', :action => 'destroy', :id => @issue} ) %>
|
||||||
|
<%= submit_tag _ "Delete" %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="splitcontentleft">
|
||||||
|
<div class="box">
|
||||||
|
<h3><%=_('History')%></h3>
|
||||||
|
<table width="100%">
|
||||||
|
<% for history in @issue.histories.find(:all, :include => :author) %>
|
||||||
|
<tr>
|
||||||
|
<td><%= format_date(history.created_on) %></td>
|
||||||
|
<td><%= history.author.display_name %></td>
|
||||||
|
<td><b><%= history.status.name %></b></td>
|
||||||
|
</tr>
|
||||||
|
<% if history.notes? %>
|
||||||
|
<tr><td colspan=3><div class="notes"><%= history.notes %></td></tr>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="splitcontentright">
|
||||||
|
<div class="box">
|
||||||
|
<h3><%=_('Attachments')%></h3>
|
||||||
|
<table width="100%">
|
||||||
|
<% for attachment in @issue.attachments %>
|
||||||
|
<tr>
|
||||||
|
<td><%= link_to attachment.filename, :action => 'download', :id => @issue, :attachment_id => attachment %> (<%= human_size(attachment.size) %>)</td>
|
||||||
|
<td><%= format_date(attachment.created_on) %></td>
|
||||||
|
<td><%= attachment.author.display_name %></td>
|
||||||
|
<% if authorize_for('issues', 'destroy_attachment') %>
|
||||||
|
<td>
|
||||||
|
<%= start_form_tag :action => 'destroy_attachment', :id => @issue, :attachment_id => attachment %>
|
||||||
|
<%= submit_tag _('Delete'), :class => "button-small" %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
</td>
|
||||||
|
<% end %>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</table>
|
||||||
|
<br />
|
||||||
|
<% if authorize_for('issues', 'add_attachment') %>
|
||||||
|
<%= start_form_tag ({ :controller => 'issues', :action => 'add_attachment', :id => @issue }, :multipart => true) %>
|
||||||
|
<%=_('Add file')%>: <%= file_field 'attachment', 'file' %>
|
||||||
|
<%= submit_tag _('Add') %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
<!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>redMine</title>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||||
|
<meta name="description" content="redMine" />
|
||||||
|
<meta name="keywords" content="issue,bug,tracker" />
|
||||||
|
<%= stylesheet_link_tag "application" %>
|
||||||
|
<%= stylesheet_link_tag "rails" %>
|
||||||
|
<%= javascript_include_tag :defaults %>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="container" >
|
||||||
|
|
||||||
|
<div id="header">
|
||||||
|
<div style="float: left;">
|
||||||
|
<h1><%= RDM_APP_NAME %></h1>
|
||||||
|
<h2>Project management</h2>
|
||||||
|
</div>
|
||||||
|
<div style="float: right; padding-right: 1em; padding-top: 0.2em;">
|
||||||
|
<% unless session[:user].nil? %><small><%=_('Logged as')%> <b><%= session[:user].login %></b></small><% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="navigation">
|
||||||
|
<ul>
|
||||||
|
<li class="selected"><%= link_to _('Home'), { :controller => '' }, :class => "picHome" %></li>
|
||||||
|
<li><%= link_to _('My page'), { :controller => 'account', :action => 'my_page'}, :class => "picUserPage" %></li>
|
||||||
|
<li><%= link_to _('Projects'), { :controller => 'projects' }, :class => "picProject" %></li>
|
||||||
|
|
||||||
|
<% unless session[:user].nil? %>
|
||||||
|
<li><%= link_to _('My account'), { :controller => 'account', :action => 'my_account' }, :class => "picUser" %></li>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% if admin_loggedin? %>
|
||||||
|
<li><%= link_to _('Administration'), { :controller => 'admin' }, :class => "picAdmin" %></li>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<li class="right"><%= link_to _('Help'), { :controller => 'help', :ctrl => @params[:controller], :page => @params[:action] }, :target => "new", :class => "picHelp" %></li>
|
||||||
|
<% if session[:user].nil? %>
|
||||||
|
<li class="right"><%= link_to _('Log in'), { :controller => 'account', :action => 'login' }, :class => "picUser" %></li>
|
||||||
|
<% else %>
|
||||||
|
<li class="right"><%= link_to _('Logout'), { :controller => 'account', :action => 'logout' }, :class => "picUser" %></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="subcontent">
|
||||||
|
|
||||||
|
<% unless @project.nil? || @project.id.nil? %>
|
||||||
|
<h2><%= @project.name %></h2>
|
||||||
|
<ul class="menublock">
|
||||||
|
<li><%= link_to _('Overview'), :controller => 'projects', :action => 'show', :id => @project %></li>
|
||||||
|
<li><%= link_to _('Issues'), :controller => 'projects', :action => 'list_issues', :id => @project %></li>
|
||||||
|
<li><%= link_to _('Reports'), :controller => 'reports', :action => 'issue_report', :id => @project %></li>
|
||||||
|
<li><%= link_to _('News'), :controller => 'projects', :action => 'list_news', :id => @project %></li>
|
||||||
|
<li><%= link_to _('Change log'), :controller => 'projects', :action => 'changelog', :id => @project %></li>
|
||||||
|
<li><%= link_to _('Documents'), :controller => 'projects', :action => 'list_documents', :id => @project %></li>
|
||||||
|
<li><%= link_to _('Members'), :controller => 'projects', :action => 'list_members', :id => @project %></li>
|
||||||
|
<li><%= link_to _('Files'), :controller => 'projects', :action => 'list_files', :id => @project %></li>
|
||||||
|
<li><%= link_to_if_authorized _('Settings'), :controller => 'projects', :action => 'settings', :id => @project %></li>
|
||||||
|
</ul>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% unless session[:user].nil? %>
|
||||||
|
<h2><%=_('My projects') %></h2>
|
||||||
|
<ul class="menublock">
|
||||||
|
<% for membership in session[:user].memberships %>
|
||||||
|
<li><%= link_to membership.project.name, :controller => 'projects', :action => 'show', :id => membership.project %></li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content">
|
||||||
|
<% if flash[:notice] %><p style="color: green"><%= flash[:notice] %></p><% end %>
|
||||||
|
<%= @content_for_layout %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="footer">
|
||||||
|
<p><a href="http://redmine.sourceforge.net/" target="_new"><%= RDM_APP_NAME %></a> <%= RDM_APP_VERSION %></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<%=_('Issue')%> #<%= issue.id %> - <%= issue.subject %>
|
||||||
|
<%=_('Author')%>: <%= issue.author.display_name %>
|
||||||
|
|
||||||
|
<%= issue.descr %>
|
||||||
|
|
||||||
|
http://<%= RDM_HOST_NAME %>/issues/show/<%= issue.id %>
|
|
@ -0,0 +1,3 @@
|
||||||
|
Issue #<%= @issue.id %> has been reported.
|
||||||
|
----------------------------------------
|
||||||
|
<%= render :file => "_issue", :use_full_path => true, :locals => { :issue => @issue } %>
|
|
@ -0,0 +1,3 @@
|
||||||
|
Issue #<%= @issue.id %> has been updated to "<%= @issue.status.name %>" status.
|
||||||
|
----------------------------------------
|
||||||
|
<%= render :file => "_issue", :use_full_path => true, :locals => { :issue => @issue } %>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<%= error_messages_for 'news' %>
|
||||||
|
|
||||||
|
<!--[form:news]-->
|
||||||
|
<p><label for="news_title"><%=_('Title')%></label> <span class="required">*</span><br/>
|
||||||
|
<%= text_field 'news', 'title', :size => 60 %></p>
|
||||||
|
|
||||||
|
<p><label for="news_shortdescr"><%=_('Summary')%> <span class="required">*</span></label><br/>
|
||||||
|
<%= text_area 'news', 'shortdescr', :cols => 60, :rows => 2 %></p>
|
||||||
|
|
||||||
|
<p><label for="news_descr"><%=_('Description')%> <span class="required">*</span></label><br/>
|
||||||
|
<%= text_area 'news', 'descr', :cols => 60, :rows => 10 %></p>
|
||||||
|
<!--[eoform:news]-->
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<h2><%=_('News')%></h2>
|
||||||
|
|
||||||
|
<%= start_form_tag :action => 'edit', :id => @news %>
|
||||||
|
<%= render :partial => 'form' %>
|
||||||
|
<%= submit_tag _('Save') %>
|
||||||
|
<%= end_form_tag %>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<h2><%= @news.title %></h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<b><%=_('Summary')%></b>: <%= @news.shortdescr %><br />
|
||||||
|
<b><%=_('By')%></b>: <%= @news.author.display_name %><br />
|
||||||
|
<b><%=_('Date')%></b>: <%= format_time(@news.created_on) %>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<%= @news.descr %>
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<%= error_messages_for 'project' %>
|
||||||
|
|
||||||
|
<!--[form:project]-->
|
||||||
|
<p><label for="project_name"><%=_('Name')%> <span class="required">*</span></label><br/>
|
||||||
|
<%= text_field 'project', 'name' %></p>
|
||||||
|
|
||||||
|
<p><label for="project_descr"><%=_('Description')%> <span class="required">*</span></label><br/>
|
||||||
|
<%= text_field 'project', 'descr', :size => 60 %></p>
|
||||||
|
|
||||||
|
<p><label for="project_homepage"><%=_('Homepage')%></label><br/>
|
||||||
|
<%= text_field 'project', 'homepage', :size => 40 %></p>
|
||||||
|
|
||||||
|
<p><%= check_box 'project', 'public' %>
|
||||||
|
<label for="project_public"><%=_('Public')%></label></p>
|
||||||
|
|
||||||
|
<fieldset><legend><%=_('Custom fields')%></legend>
|
||||||
|
<% for custom_field in @custom_fields %>
|
||||||
|
<input type="checkbox"
|
||||||
|
|
||||||
|
name="custom_field_ids[]"
|
||||||
|
value="<%= custom_field.id %>"
|
||||||
|
<%if @project.custom_fields.include? custom_field%>checked="checked"<%end%>
|
||||||
|
> <%= custom_field.name %>
|
||||||
|
|
||||||
|
<% end %></fieldset>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<!--[eoform:project]-->
|
|
@ -0,0 +1,7 @@
|
||||||
|
<h2><%=_('New project')%></h2>
|
||||||
|
|
||||||
|
<%= start_form_tag :action => 'add' %>
|
||||||
|
<%= render :partial => 'form' %>
|
||||||
|
<%= submit_tag _('Create') %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
<h2><%=_('New document')%></h2>
|
||||||
|
|
||||||
|
<%= error_messages_for 'document' %>
|
||||||
|
<%= start_form_tag( { :action => 'add_document', :id => @project }, :multipart => true) %>
|
||||||
|
|
||||||
|
<!--[form:document]-->
|
||||||
|
<p><label for="document_category_id"><%=_('Category')%></label><br />
|
||||||
|
<select name="document[category_id]">
|
||||||
|
<%= options_from_collection_for_select @categories, "id", "name",@document.category_id %>
|
||||||
|
</select></p>
|
||||||
|
|
||||||
|
<p><label for="document_title"><%=_('Title')%> <span class="required">*</span></label><br />
|
||||||
|
<%= text_field 'document', 'title', :size => 60 %></p>
|
||||||
|
|
||||||
|
<p><label for="document_descr"><%=_('Description')%> <span class="required">*</span></label><br />
|
||||||
|
<%= text_area 'document', 'descr', :cols => 60, :rows => 5 %></p>
|
||||||
|
|
||||||
|
<p><label for="attachment_file"><%=_('File')%></label><br/>
|
||||||
|
<%= file_field 'attachment', 'file' %></p>
|
||||||
|
|
||||||
|
<!--[eoform:document]-->
|
||||||
|
|
||||||
|
<%= submit_tag _('Create') %>
|
||||||
|
<%= end_form_tag %>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
<h2><%=_('New file')%></h2>
|
||||||
|
|
||||||
|
<%= start_form_tag ({ :action => 'add_file', :project => @project }, :multipart => true) %>
|
||||||
|
|
||||||
|
<p><label for="version_id"><%=_('Version')%></label><br />
|
||||||
|
<select name="version_id">
|
||||||
|
<%= options_from_collection_for_select @versions, "id", "name" %>
|
||||||
|
</select></p>
|
||||||
|
|
||||||
|
<p><b><%=_('File')%><b><br /><%= file_field 'attachment', 'file' %></p>
|
||||||
|
<br/>
|
||||||
|
<%= submit_tag _('Add') %>
|
||||||
|
<%= end_form_tag %>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue