From 7136b85f21201b9611977ae4ff8004aeb1ba47bb Mon Sep 17 00:00:00 2001
From: Jean-Philippe Lang
Date: Sun, 12 Nov 2006 18:50:30 +0000
Subject: * new report: project activity * "start date" and "% done" fields
added on issues * project calendar added * gantt chart added (exportable to
pdf) * multiple file upload for issues attachments * user custom field
displayed on account/show * default configuration improved (default roles,
trackers, status, permissions and workflows) * fixed: project settings now
displayed according to user's permissions
git-svn-id: http://redmine.rubyforge.org/svn/trunk@44 e93f8b46-1217-0410-a6f0-8f06a7374b81
---
redmine/app/controllers/account_controller.rb | 1 +
redmine/app/controllers/issues_controller.rb | 2 +
redmine/app/controllers/projects_controller.rb | 85 +++++++--
redmine/app/controllers/users_controller.rb | 8 +-
redmine/app/helpers/application_helper.rb | 8 +
redmine/app/models/issue.rb | 5 +
redmine/app/views/account/show.rhtml | 11 +-
redmine/app/views/issues/change_status.rhtml | 6 +
redmine/app/views/issues/edit.rhtml | 33 ++--
redmine/app/views/issues/show.rhtml | 18 +-
redmine/app/views/layouts/base.rhtml | 6 +-
redmine/app/views/news/_form.rhtml | 16 +-
redmine/app/views/news/show.rhtml | 2 +-
redmine/app/views/projects/_form.rhtml | 12 +-
redmine/app/views/projects/activity.rhtml | 12 +-
redmine/app/views/projects/add_issue.rhtml | 35 +++-
redmine/app/views/projects/calendar.rhtml | 71 +++++++
redmine/app/views/projects/gantt.rfpdf | 161 ++++++++++++++++
redmine/app/views/projects/gantt.rhtml | 241 ++++++++++++++++++++++++
redmine/app/views/projects/list_issues.rhtml | 2 +-
redmine/app/views/projects/list_news.rhtml | 2 +-
redmine/app/views/projects/settings.rhtml | 133 +++++++------
redmine/app/views/projects/show.rhtml | 2 +-
redmine/app/views/reports/issue_report.rhtml | 8 +-
redmine/app/views/users/_form.rhtml | 24 ++-
redmine/config/config_custom.example.rb | 65 +++++++
redmine/config/config_custom.rb | 60 ------
redmine/config/environment.rb | 4 +
redmine/db/migrate/005_issue_start_date.rb | 11 ++
redmine/db/migrate/006_calendar_and_activity.rb | 13 ++
redmine/doc/CHANGELOG | 26 ++-
redmine/doc/INSTALL | 7 +-
redmine/lang/de.yml | 114 +++++------
redmine/lang/en.yml | 16 +-
redmine/lang/es.yml | 94 ++++-----
redmine/lang/fr.yml | 13 +-
redmine/lib/tasks/load_default_data.rake | 85 +++++++--
redmine/public/images/add.png | Bin 0 -> 336 bytes
redmine/public/images/arrow_bw.png | Bin 0 -> 997 bytes
redmine/public/images/arrow_from.png | Bin 0 -> 994 bytes
redmine/public/images/arrow_to.png | Bin 0 -> 991 bytes
redmine/public/images/attachment.png | Bin 0 -> 259 bytes
redmine/public/images/details.png | Bin 0 -> 224 bytes
redmine/public/images/gantt.png | Bin 0 -> 218 bytes
redmine/public/images/jstoolbar/bt_br.png | Bin 0 -> 244 bytes
redmine/public/images/jstoolbar/bt_code.png | Bin 0 -> 338 bytes
redmine/public/images/jstoolbar/bt_del.png | Bin 0 -> 368 bytes
redmine/public/images/jstoolbar/bt_em.png | Bin 0 -> 311 bytes
redmine/public/images/jstoolbar/bt_ins.png | Bin 0 -> 322 bytes
redmine/public/images/jstoolbar/bt_link.png | Bin 0 -> 900 bytes
redmine/public/images/jstoolbar/bt_ol.png | Bin 0 -> 249 bytes
redmine/public/images/jstoolbar/bt_quote.png | Bin 0 -> 323 bytes
redmine/public/images/jstoolbar/bt_strong.png | Bin 0 -> 355 bytes
redmine/public/images/jstoolbar/bt_ul.png | Bin 0 -> 239 bytes
redmine/public/images/zoom_in.png | Bin 0 -> 593 bytes
redmine/public/images/zoom_in_g.png | Bin 0 -> 312 bytes
redmine/public/images/zoom_out.png | Bin 0 -> 588 bytes
redmine/public/images/zoom_out_g.png | Bin 0 -> 311 bytes
redmine/public/javascripts/application.js | 1 +
redmine/public/javascripts/jstoolbar.js | 42 ++---
redmine/public/stylesheets/application.css | 23 ++-
61 files changed, 1121 insertions(+), 357 deletions(-)
create mode 100644 redmine/app/views/projects/calendar.rhtml
create mode 100644 redmine/app/views/projects/gantt.rfpdf
create mode 100644 redmine/app/views/projects/gantt.rhtml
create mode 100644 redmine/config/config_custom.example.rb
delete mode 100644 redmine/config/config_custom.rb
create mode 100644 redmine/db/migrate/005_issue_start_date.rb
create mode 100644 redmine/db/migrate/006_calendar_and_activity.rb
create mode 100644 redmine/public/images/add.png
create mode 100644 redmine/public/images/arrow_bw.png
create mode 100644 redmine/public/images/arrow_from.png
create mode 100644 redmine/public/images/arrow_to.png
create mode 100644 redmine/public/images/attachment.png
create mode 100644 redmine/public/images/details.png
create mode 100644 redmine/public/images/gantt.png
create mode 100644 redmine/public/images/jstoolbar/bt_br.png
create mode 100644 redmine/public/images/jstoolbar/bt_code.png
create mode 100644 redmine/public/images/jstoolbar/bt_del.png
create mode 100644 redmine/public/images/jstoolbar/bt_em.png
create mode 100644 redmine/public/images/jstoolbar/bt_ins.png
create mode 100644 redmine/public/images/jstoolbar/bt_link.png
create mode 100644 redmine/public/images/jstoolbar/bt_ol.png
create mode 100644 redmine/public/images/jstoolbar/bt_quote.png
create mode 100644 redmine/public/images/jstoolbar/bt_strong.png
create mode 100644 redmine/public/images/jstoolbar/bt_ul.png
create mode 100644 redmine/public/images/zoom_in.png
create mode 100644 redmine/public/images/zoom_in_g.png
create mode 100644 redmine/public/images/zoom_out.png
create mode 100644 redmine/public/images/zoom_out_g.png
diff --git a/redmine/app/controllers/account_controller.rb b/redmine/app/controllers/account_controller.rb
index 22ac8609a..7031d71ec 100644
--- a/redmine/app/controllers/account_controller.rb
+++ b/redmine/app/controllers/account_controller.rb
@@ -27,6 +27,7 @@ class AccountController < ApplicationController
# Show user's account
def show
@user = User.find(params[:id])
+ @custom_values = @user.custom_values.find(:all, :include => :custom_field)
end
# Login request and validation
diff --git a/redmine/app/controllers/issues_controller.rb b/redmine/app/controllers/issues_controller.rb
index d428c75bf..c279e6430 100644
--- a/redmine/app/controllers/issues_controller.rb
+++ b/redmine/app/controllers/issues_controller.rb
@@ -81,6 +81,7 @@ class IssuesController < ApplicationController
@issue.status = @history.status
@issue.fixed_version_id = (params[:issue][:fixed_version_id])
@issue.assigned_to_id = (params[:issue][:assigned_to_id])
+ @issue.done_ratio = (params[:issue][:done_ratio])
@issue.lock_version = (params[:issue][:lock_version])
if @issue.save
flash[:notice] = l(:notice_successful_update)
@@ -124,5 +125,6 @@ private
def find_project
@issue = Issue.find(params[:id], :include => [:project, :tracker, :status, :author, :priority, :category])
@project = @issue.project
+ @html_title = "#{@project.name} - #{@issue.tracker.name} ##{@issue.id}"
end
end
diff --git a/redmine/app/controllers/projects_controller.rb b/redmine/app/controllers/projects_controller.rb
index 9e1dc14ef..0198e975f 100644
--- a/redmine/app/controllers/projects_controller.rb
+++ b/redmine/app/controllers/projects_controller.rb
@@ -182,7 +182,8 @@ class ProjectsController < ApplicationController
@tracker = Tracker.find(params[:tracker_id])
@priorities = Enumeration::get_values('IPRI')
@issue = Issue.new(:project => @project, :tracker => @tracker)
- if request.get?
+ if request.get?
+ @issue.start_date = Date.today
@custom_values = @project.custom_fields_for_issues(@tracker).collect { |x| CustomValue.new(:custom_field => x, :customized => @issue) }
else
@issue.attributes = params[:issue]
@@ -214,7 +215,7 @@ class ProjectsController < ApplicationController
@results_per_page = params[:per_page].to_i
session[:results_per_page] = @results_per_page
else
- @results_per_page = session[:results_per_page] || @results_per_page_options.first
+ @results_per_page = session[:results_per_page] || 25
end
@issue_count = Issue.count(:include => [:status, :project], :conditions => search_filter_clause)
@@ -356,16 +357,22 @@ class ProjectsController < ApplicationController
end
def activity
- @date_from = begin
- params[:date_from].to_date
- rescue
- end || Date.today
- @days_back = params[:days_back] ? params[:days_back].to_i : 15
- @date_to = @date_from - @days_back
+ if params[:year] and params[:year].to_i > 1900
+ @year = params[:year].to_i
+ if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
+ @month = params[:month].to_i
+ end
+ end
+ @year ||= Date.today.year
+ @month ||= Date.today.month
+
+ @date_from = Date.civil(@year, @month, 1)
+ @date_to = (@date_from >> 1)-1
+
@events_by_day = {}
unless params[:show_issues] == "0"
- @project.issues.find(:all, :include => [:author, :status], :conditions => ["issues.created_on<=? and issues.created_on>=?", @date_from+1, @date_to], :order => "issues.created_on asc" ).each { |i|
+ @project.issues.find(:all, :include => [:author, :status], :conditions => ["issues.created_on>=? and issues.created_on<=?", @date_from, @date_to] ).each { |i|
@events_by_day[i.created_on.to_date] ||= []
@events_by_day[i.created_on.to_date] << i
}
@@ -373,7 +380,7 @@ class ProjectsController < ApplicationController
end
unless params[:show_news] == "0"
- @project.news.find(:all, :conditions => ["news.created_on<=? and news.created_on>=?", @date_from+1, @date_to], :order => "news.created_on asc" ).each { |i|
+ @project.news.find(:all, :conditions => ["news.created_on>=? and news.created_on<=?", @date_from, @date_to] ).each { |i|
@events_by_day[i.created_on.to_date] ||= []
@events_by_day[i.created_on.to_date] << i
}
@@ -381,7 +388,7 @@ class ProjectsController < ApplicationController
end
unless params[:show_files] == "0"
- Attachment.find(:all, :joins => "LEFT JOIN versions ON versions.id = attachments.container_id", :conditions => ["attachments.container_type='Version' and versions.project_id=? and attachments.created_on<=? and attachments.created_on>=?", @project.id, @date_from+1, @date_to], :order => "attachments.created_on asc" ).each { |i|
+ Attachment.find(:all, :joins => "LEFT JOIN versions ON versions.id = attachments.container_id", :conditions => ["attachments.container_type='Version' and versions.project_id=? and attachments.created_on>=? and attachments.created_on<=?", @project.id, @date_from, @date_to] ).each { |i|
@events_by_day[i.created_on.to_date] ||= []
@events_by_day[i.created_on.to_date] << i
}
@@ -389,7 +396,7 @@ class ProjectsController < ApplicationController
end
unless params[:show_documentss] == "0"
- Attachment.find(:all, :joins => "LEFT JOIN documents ON documents.id = attachments.container_id", :conditions => ["attachments.container_type='Document' and documents.project_id=? and attachments.created_on<=? and attachments.created_on>=?", @project.id, @date_from+1, @date_to], :order => "attachments.created_on asc" ).each { |i|
+ Attachment.find(:all, :joins => "LEFT JOIN documents ON documents.id = attachments.container_id", :conditions => ["attachments.container_type='Document' and documents.project_id=? and attachments.created_on>=? and attachments.created_on<=?", @project.id, @date_from, @date_to] ).each { |i|
@events_by_day[i.created_on.to_date] ||= []
@events_by_day[i.created_on.to_date] << i
}
@@ -397,12 +404,64 @@ class ProjectsController < ApplicationController
end
end
+
+ def calendar
+ if params[:year] and params[:year].to_i > 1900
+ @year = params[:year].to_i
+ if params[:month] and params[:month].to_i > 0 and params[:month].to_i < 13
+ @month = params[:month].to_i
+ end
+ end
+ @year ||= Date.today.year
+ @month ||= Date.today.month
+
+ @date_from = Date.civil(@year, @month, 1)
+ @date_to = (@date_from >> 1)-1
+ # start on monday
+ @date_from = @date_from - (@date_from.cwday-1)
+ # finish on sunday
+ @date_to = @date_to + (7-@date_to.cwday)
+
+ @issues = @project.issues.find(:all, :include => :tracker, :conditions => ["((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?))", @date_from, @date_to, @date_from, @date_to])
+ render :layout => false if request.xhr?
+ end
+
+ def gantt
+ if params[:year] and params[:year].to_i >0
+ @year_from = params[:year].to_i
+ if params[:month] and params[:month].to_i >=1 and params[:month].to_i <= 12
+ @month_from = params[:month].to_i
+ else
+ @month_from = 1
+ end
+ else
+ @month_from ||= (Date.today << 1).month
+ @year_from ||= (Date.today << 1).year
+ end
+
+ @zoom = (params[:zoom].to_i > 0 and params[:zoom].to_i < 5) ? params[:zoom].to_i : 2
+ @months = (params[:months].to_i > 0 and params[:months].to_i < 25) ? params[:months].to_i : 6
+
+ @date_from = Date.civil(@year_from, @month_from, 1)
+ @date_to = (@date_from >> @months) - 1
+ @issues = @project.issues.find(:all, :order => "start_date, due_date", :conditions => ["(((start_date>=? and start_date<=?) or (due_date>=? and due_date<=?) or (start_date and due_date>?)) and start_date is not null and due_date is not null)", @date_from, @date_to, @date_from, @date_to, @date_from, @date_to])
+
+ if params[:output]=='pdf'
+ @options_for_rfpdf ||= {}
+ @options_for_rfpdf[:file_name] = "gantt.pdf"
+ render :template => "projects/gantt.rfpdf", :layout => false
+ else
+ render :template => "projects/gantt.rhtml"
+ end
+ 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])
+ @project = Project.find(params[:id])
+ @html_title = @project.name
rescue
redirect_to :action => 'list'
end
diff --git a/redmine/app/controllers/users_controller.rb b/redmine/app/controllers/users_controller.rb
index dee9e9d6b..47d0e51c9 100644
--- a/redmine/app/controllers/users_controller.rb
+++ b/redmine/app/controllers/users_controller.rb
@@ -51,14 +51,15 @@ class UsersController < ApplicationController
@user = User.new(params[:user])
@user.admin = params[:user][:admin] || false
@user.login = params[:user][:login]
- @user.password, @user.password_confirmation = params[:password], params[:password_confirmation]
+ @user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless @user.auth_source_id
@custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }
@user.custom_values = @custom_values
if @user.save
flash[:notice] = l(:notice_successful_create)
redirect_to :action => 'list'
end
- end
+ end
+ @auth_sources = AuthSource.find(:all)
end
def edit
@@ -68,7 +69,7 @@ class UsersController < ApplicationController
else
@user.admin = params[:user][:admin] if params[:user][:admin]
@user.login = params[:user][:login] if params[:user][:login]
- @user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless params[:password].nil? or params[:password].empty?
+ @user.password, @user.password_confirmation = params[:password], params[:password_confirmation] unless params[:password].nil? or params[:password].empty? or @user.auth_source_id
if params[:custom_fields]
@custom_values = UserCustomField.find(:all).collect { |x| CustomValue.new(:custom_field => x, :customized => @user, :value => params["custom_fields"][x.id.to_s]) }
@user.custom_values = @custom_values
@@ -78,6 +79,7 @@ class UsersController < ApplicationController
redirect_to :action => 'list'
end
end
+ @auth_sources = AuthSource.find(:all)
end
def destroy
diff --git a/redmine/app/helpers/application_helper.rb b/redmine/app/helpers/application_helper.rb
index 835ac4859..378545eb1 100644
--- a/redmine/app/helpers/application_helper.rb
+++ b/redmine/app/helpers/application_helper.rb
@@ -57,6 +57,10 @@ module ApplicationHelper
def format_time(time)
l_datetime(time) if time
end
+
+ def day_name(day)
+ l(:general_day_names).split(',')[day-1]
+ end
def pagination_links_full(paginator, options={}, html_options={})
html = ''
@@ -76,6 +80,10 @@ module ApplicationHelper
html
end
+ def textilizable(text)
+ $RDM_TEXTILE_DISABLED ? text : textilize(text)
+ end
+
def error_messages_for(object_name, options = {})
options = options.symbolize_keys
object = instance_variable_get("@#{object_name}")
diff --git a/redmine/app/models/issue.rb b/redmine/app/models/issue.rb
index 5f2a600e1..4834e069f 100644
--- a/redmine/app/models/issue.rb
+++ b/redmine/app/models/issue.rb
@@ -33,6 +33,7 @@ class Issue < ActiveRecord::Base
has_many :custom_fields, :through => :custom_values
validates_presence_of :subject, :description, :priority, :tracker, :author, :status
+ validates_inclusion_of :done_ratio, :in => 0..100
validates_associated :custom_values, :on => :update
# set default status for new issues
@@ -44,6 +45,10 @@ class Issue < ActiveRecord::Base
if self.due_date.nil? && @attributes['due_date'] && !@attributes['due_date'].empty?
errors.add :due_date, :activerecord_error_not_a_date
end
+
+ if self.due_date and self.start_date and self.due_date < self.start_date
+ errors.add :due_date, :activerecord_error_greater_than_start_date
+ end
end
def before_create
diff --git a/redmine/app/views/account/show.rhtml b/redmine/app/views/account/show.rhtml
index 78fe0a679..4fa306764 100644
--- a/redmine/app/views/account/show.rhtml
+++ b/redmine/app/views/account/show.rhtml
@@ -1,8 +1,15 @@
<%= @user.display_name %>
-<%= mail_to @user.mail %>
-<%=l(:label_registered_on)%>: <%= format_date(@user.created_on) %>
+<%= mail_to @user.mail %>
+
+ - <%=l(:label_registered_on)%>: <%= format_date(@user.created_on) %>
+<% for custom_value in @custom_values %>
+<% if !custom_value.value.empty? %>
+ - <%= custom_value.custom_field.name%>: <%= show_value(custom_value) %>
+<% end %>
+<% end %>
+
<%=l(:label_project_plural)%>
diff --git a/redmine/app/views/issues/change_status.rhtml b/redmine/app/views/issues/change_status.rhtml
index e525de60d..0fe07ad23 100644
--- a/redmine/app/views/issues/change_status.rhtml
+++ b/redmine/app/views/issues/change_status.rhtml
@@ -14,6 +14,12 @@
<%= options_from_collection_for_select @assignable_to, "id", "display_name", @issue.assigned_to_id %>
+
+
+
+<%= select("issue", "done_ratio", ((0..10).to_a.collect {|r| ["#{r*10} %", r*10] }) ) %>
+
+