git-svn-id: http://redmine.rubyforge.org/svn/trunk@38 e93f8b46-1217-0410-a6f0-8f06a7374b81

This commit is contained in:
Jean-Philippe Lang 2006-11-05 16:49:27 +00:00
parent 51e0989c49
commit 3628515b31
24 changed files with 226 additions and 38 deletions

View File

@ -63,6 +63,7 @@ class IssuesController < ApplicationController
@history.status = @issue.status
if @history.save
flash[:notice] = l(:notice_successful_update)
Mailer.deliver_issue_add_note(@history) if Permission.find_by_controller_and_action(@params[:controller], @params[:action]).mail_enabled?
redirect_to :action => 'show', :id => @issue
return
end

View File

@ -356,6 +356,48 @@ class ProjectsController < ApplicationController
@fixed_issues ||= []
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
@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|
@events_by_day[i.created_on.to_date] ||= []
@events_by_day[i.created_on.to_date] << i
}
@show_issues = 1
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|
@events_by_day[i.created_on.to_date] ||= []
@events_by_day[i.created_on.to_date] << i
}
@show_news = 1
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|
@events_by_day[i.created_on.to_date] ||= []
@events_by_day[i.created_on.to_date] << i
}
@show_files = 1
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|
@events_by_day[i.created_on.to_date] ||= []
@events_by_day[i.created_on.to_date] << i
}
@show_documents = 1
end
end
private
# Find project of id params[:id]
# if not found, redirect to project list

View File

@ -57,7 +57,7 @@ module CustomFieldsHelper
case custom_value.custom_field.field_format
when "date"
l_date(custom_value.value.to_date) if custom_value.value
custom_value.value.empty? ? "" : l_date(custom_value.value.to_date)
when "bool"
l_YesNo(custom_value.value == "1")
else

View File

@ -32,7 +32,7 @@ class Issue < ActiveRecord::Base
has_many :custom_values, :dependent => true, :as => :customized
has_many :custom_fields, :through => :custom_values
validates_presence_of :subject, :description, :priority, :tracker, :author
validates_presence_of :subject, :description, :priority, :tracker, :author, :status
validates_associated :custom_values, :on => :update
# set default status for new issues
@ -49,7 +49,7 @@ class Issue < ActiveRecord::Base
def before_create
build_history
end
def long_id
"%05d" % self.id
end

View File

@ -18,6 +18,7 @@
class IssueHistory < ActiveRecord::Base
belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
belongs_to :issue
validates_presence_of :status
end

View File

@ -21,9 +21,13 @@ class IssueStatus < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name
validates_length_of :html_color, :is=>6
validates_length_of :html_color, :is => 6
validates_format_of :html_color, :with => /^[a-f0-9]*$/i
def before_save
IssueStatus.update_all "is_default=false" if self.is_default?
end
# Returns the default status for new issues
def self.default
find(:first, :conditions =>["is_default=?", true])

View File

@ -20,30 +20,38 @@ 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"
@from = $RDM_MAIL_FROM
@subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
@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"
@from = $RDM_MAIL_FROM
@subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] #{issue.status.name} - #{issue.subject}"
@body['issue'] = issue
end
def issue_add_note(history)
# Sends to all project members
@recipients = history.issue.project.members.collect { |m| m.user.mail if m.user.mail_notification }
@from = $RDM_MAIL_FROM
@subject = "[#{history.issue.project.name} - #{history.issue.tracker.name} ##{history.issue.id}] #{history.issue.status.name} - #{history.issue.subject}"
@body['history'] = history
end
def lost_password(token)
@recipients = token.user.mail
@from = 'redmine@somenet.foo'
@subject = "redMine password"
@from = $RDM_MAIL_FROM
@subject = l(:mail_subject_lost_password)
@body['token'] = token
end
def register(token)
@recipients = token.user.mail
@from = 'redmine@somenet.foo'
@subject = "redMine account activation"
@from = $RDM_MAIL_FROM
@subject = l(:mail_subject_register)
@body['token'] = token
end
end

View File

@ -23,4 +23,32 @@
</div>
<%= f.hidden_field :lock_version %>
<%= submit_tag l(:button_save) %>
<% end %>
<% end %>
<%= javascript_include_tag 'jstoolbar' %>
<script type="text/javascript">
//<![CDATA[
jsToolBar.prototype.base_url = 'http://callmepep.org';
jsToolBar.prototype.legend_msg = 'You can use the following shortcuts to format your text.';
jsToolBar.prototype.elements.strong.title = 'Strong emphasis';
jsToolBar.prototype.elements.em.title = 'Emphasis';
jsToolBar.prototype.elements.ins.title = 'Inserted';
jsToolBar.prototype.elements.del.title = 'Deleted';
jsToolBar.prototype.elements.quote.title = 'Inline quote';
jsToolBar.prototype.elements.code.title = 'Code';
jsToolBar.prototype.elements.br.title = 'Line break';
jsToolBar.prototype.elements.ul.title = 'Unordered list';
jsToolBar.prototype.elements.ol.title = 'Ordered list';
jsToolBar.prototype.elements.link.title = 'Link';
jsToolBar.prototype.elements.link.href_prompt = 'URL?';
jsToolBar.prototype.elements.link.hreflang_prompt = 'Language?';
if (document.getElementById) {
if (document.getElementById('issue_description')) {
var commentTb = new jsToolBar(document.getElementById('issue_description'));
commentTb.draw();
}
}
//]]>
</script>

View File

@ -6,25 +6,42 @@
</div>
<div class="box">
<table width="100%">
<tr>
<td width="15%"><b><%=l(:field_status)%> :</b></td><td width="35%"><%= @issue.status.name %></td>
<td width="15%"><b><%=l(:field_priority)%> :</b></td><td width="35%"><%= @issue.priority.name %></td>
</tr>
<tr>
<td><b><%=l(:field_author)%> :</b></td><td><%= link_to_user @issue.author %></td>
<td><b><%=l(:field_category)%> :</b></td><td><%= @issue.category ? @issue.category.name : "-" %></td>
</tr>
<tr>
<td><b><%=l(:field_created_on)%> :</b></td><td><%= format_date(@issue.created_on) %></td>
<td><b><%=l(:field_assigned_to)%> :</b></td><td><%= @issue.assigned_to ? @issue.assigned_to.name : "-" %></td>
</tr>
<tr>
<td><b><%=l(:field_updated_on)%> :</b></td><td><%= format_date(@issue.updated_on) %></td>
<td><b><%=l(:field_due_date)%> :</b></td><td><%= format_date(@issue.due_date) %></td>
</tr>
<tr>
<% n = 0
for custom_value in @custom_values %>
<td><b><%= custom_value.custom_field.name %> :</b></td><td><%= show_value custom_value %></td>
<% n = n + 1
if (n > 1)
n = 0 %>
</tr><tr>
<%end
end %>
</tr>
</table>
<hr />
<br />
<b><%=l(:field_description)%> :</b><br /><br />
<%= textilize @issue.description %>
<p>
<b><%=l(:field_status)%> :</b> <%= @issue.status.name %> &nbsp &nbsp
<b><%=l(:field_priority)%> :</b> <%= @issue.priority.name %> &nbsp &nbsp
<b><%=l(:field_assigned_to)%> :</b> <%= @issue.assigned_to ? @issue.assigned_to.display_name : "-" %> &nbsp &nbsp
<b><%=l(:field_category)%> :</b> <%= @issue.category ? @issue.category.name : "-" %>
</p>
<div class="tabular">
<p><label><%=l(:field_author)%> :</label> <%= link_to_user @issue.author %>&nbsp;</p>
<p><label><%=l(:field_created_on)%> :</label> <%= format_date(@issue.created_on) %>&nbsp;</p>
<p><label><%=l(:field_subject)%> :</label> <%= @issue.subject %>&nbsp;</p>
<%= simple_format ("<label>" + l(:field_description) + ": </label>" + auto_link(@issue.description)) %>
<p><label><%=l(:field_due_date)%> :</label> <%= format_date(@issue.due_date) %>&nbsp;</p>
<% for custom_value in @custom_values %>
<p><label><%= custom_value.custom_field.name %> :</label> <%= show_value custom_value %></p>
<% end %>
&nbsp;
</div>
<% if authorize_for('issues', 'edit') %>
<%= start_form_tag ({:controller => 'issues', :action => 'edit', :id => @issue}, :method => "get" ) %>
<%= submit_tag l(:button_edit) %>
@ -57,6 +74,7 @@
<%= end_form_tag %>
&nbsp;&nbsp;
<% end %>
</p>
</div>
<% if authorize_for('issues', 'add_note') %>

View File

@ -14,6 +14,7 @@
<%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
<%= javascript_include_tag 'calendar/calendar-setup' %>
<%= stylesheet_link_tag 'calendar' %>
<%= stylesheet_link_tag 'jstoolbar' %>
<script type='text/javascript'>
var menu_contenu=' \
<div id="menuAdmin" class="menu" onmouseover="menuMouseover(event)"> \
@ -38,6 +39,7 @@ var menu_contenu=' \
<div id="menuProject" class="menu" onmouseover="menuMouseover(event)"> \
<%= link_to l(:label_issue_plural), {:controller => 'projects', :action => 'list_issues', :id => @project }, :class => "menuItem" %> \
<%= link_to l(:label_report_plural), {:controller => 'reports', :action => 'issue_report', :id => @project }, :class => "menuItem" %> \
<%= link_to l(:label_activity), {:controller => 'projects', :action => 'activity', :id => @project }, :class => "menuItem" %> \
<%= link_to l(:label_news_plural), {:controller => 'projects', :action => 'list_news', :id => @project }, :class => "menuItem" %> \
<%= link_to l(:label_change_log), {:controller => 'projects', :action => 'changelog', :id => @project }, :class => "menuItem" %> \
<%= link_to l(:label_document_plural), {:controller => 'projects', :action => 'list_documents', :id => @project }, :class => "menuItem" %> \
@ -101,6 +103,7 @@ var menu_contenu=' \
<li><%= link_to l(:label_overview), :controller => 'projects', :action => 'show', :id => @project %></li>
<li><%= link_to l(:label_issue_plural), :controller => 'projects', :action => 'list_issues', :id => @project %></li>
<li><%= link_to l(:label_report_plural), :controller => 'reports', :action => 'issue_report', :id => @project %></li>
<li><%= link_to l(:label_activity), :controller => 'projects', :action => 'activity', :id => @project %></li>
<li><%= link_to l(:label_news_plural), :controller => 'projects', :action => 'list_news', :id => @project %></li>
<li><%= link_to l(:label_change_log), :controller => 'projects', :action => 'changelog', :id => @project %></li>
<li><%= link_to l(:label_document_plural), :controller => 'projects', :action => 'list_documents', :id => @project %></li>

View File

@ -0,0 +1,3 @@
Note added to issue #<%= @history.issue_id %> by <%= @history.author.name %>
----------------------------------------
<%= @history.notes %>

View File

@ -0,0 +1,3 @@
Note added to issue #<%= @history.issue_id %> by <%= @history.author.name %>
----------------------------------------
<%= @history.notes %>

View File

@ -0,0 +1,3 @@
Note added to issue #<%= @history.issue_id %> by <%= @history.author.name %>
----------------------------------------
<%= @history.notes %>

View File

@ -0,0 +1,3 @@
Note ajoutée à la demande #<%= @history.issue_id %> par <%= @history.author.name %>
----------------------------------------
<%= @history.notes %>

View File

@ -0,0 +1,43 @@
<h2><%=l(:label_activity)%></h2>
<div>
<div class="rightbox">
<%= start_form_tag %>
<p>From <%= text_field_tag 'date_from', @date_from, :size => 10, :class => 'button-small' %>
and <%= text_field_tag 'days_back', @days_back, :size => 2, :class => 'button-small' %> days back</p>
<%= check_box_tag 'show_issues', 1, @show_issues %><%= hidden_field_tag 'show_issues', 0 %> <%=l(:label_issue_plural)%><br />
<%= check_box_tag 'show_news', 1, @show_news %><%= hidden_field_tag 'show_news', 0 %> <%=l(:label_news_plural)%><br />
<%= check_box_tag 'show_files', 1, @show_files %><%= hidden_field_tag 'show_files', 0 %> <%=l(:label_attachment_plural)%><br />
<%= check_box_tag 'show_documents', 1, @show_documents %><%= hidden_field_tag 'show_documents', 0 %> <%=l(:label_document_plural)%><br />
<p><center><%= submit_tag l(:button_apply), :class => 'button-small' %></center></p>
<%= end_form_tag %>
</div>
<% @events_by_day.keys.sort {|x,y| y <=> x }.each do |day| %>
<h3><%= format_date(day) %></h3>
<ul>
<% @events_by_day[day].each do |e| %>
<li><p>
<% if e.is_a? Issue %>
<%= e.created_on.strftime("%H:%M") %> <%= e.tracker.name %> <%= link_to e.long_id, :controller => 'issues', :action => 'show', :id => e %> (<%= e.status.name %>): <%= e.subject %><br />
<i><%= e.author.name %></i>
<% elsif e.is_a? News %>
<%= e.created_on.strftime("%H:%M") %> <%=l(:label_news)%>: <%= link_to e.title, :controller => 'news', :action => 'show', :id => e %><br />
<% unless e.summary.empty? %><%= e.summary %><br /><% end %>
<i><%= e.author.name %></i>
<% elsif (e.is_a? Attachment) and (e.container.is_a? Version) %>
<%= e.created_on.strftime("%H:%M") %> <%=l(:label_attachment)%> (Version <%= e.container.name %>): <%= link_to e.filename, :controller => 'projects', :action => 'list_files', :id => @project %><br />
<i><%= e.author.name %></i>
<% elsif (e.is_a? Attachment) and (e.container.is_a? Document) %>
<%= e.created_on.strftime("%H:%M") %> <%=l(:label_document)%>: <%= link_to e.container.title, :controller => 'documents', :action => 'show', :id => e %><br />
<i><%= e.author.name %></i>
<% end %>
</p></li>
<% end %>
</ul>
<% end %>
<br />
</div>

View File

@ -1,15 +1,18 @@
<h2><%=l(:label_change_log)%></h2>
<div>
<div class="rightbox" style="width:140px;">
<%= start_form_tag %>
<strong><%=l(:label_tracker_plural)%></strong><br />
<% @trackers.each do |tracker| %>
<%= check_box_tag "tracker_ids[]", tracker.id, (@selected_tracker_ids.include? tracker.id.to_s) %>
<%= tracker.name %>
<%= tracker.name %><br />
<% end %>
&nbsp;&nbsp;<%= submit_tag l(:button_apply), :class => 'button-small' %>
<%= end_form_tag %><br />
&nbsp;
<p><center><%= submit_tag l(:button_apply), :class => 'button-small' %></center></p>
<%= end_form_tag %>
</div>
<div class="box">
<% ver_id = nil
@fixed_issues.each do |issue| %>
<% unless ver_id == issue.fixed_version_id %>
@ -21,5 +24,4 @@
end %>
<li><%= link_to issue.long_id, :controller => 'issues', :action => 'show', :id => issue %> [<%= issue.tracker.name %>]: <%= issue.subject %></li>
<% end %>
</div>

View File

@ -40,6 +40,9 @@
# Default langage ('en', 'es', 'fr' are available)
# $RDM_DEFAULT_LANG = 'en'
# Email adress used to send mail notifications
# $RDM_MAIL_FROM = "redmine@somenet.foo"
# Page title
# $RDM_HEADER_TITLE = "Title"

View File

@ -95,6 +95,8 @@ $RDM_STORAGE_PATH ||= "#{RAILS_ROOT}/files"
$RDM_LOGIN_REQUIRED ||= false
# default langage
$RDM_DEFAULT_LANG ||= 'en'
# email sender adress
$RDM_MAIL_FROM ||= "redmine@somenet.foo"
# page title
$RDM_HEADER_TITLE ||= "redMine"

View File

@ -1,6 +1,6 @@
class IssueMove < ActiveRecord::Migration
def self.up
Permission.create :controller => "projects", :action => "move_issues", :description => "button_move", :sort => 1061, :mail_option => 1, :mail_enabled => 0
Permission.create :controller => "projects", :action => "move_issues", :description => "button_move", :sort => 1061, :mail_option => 0, :mail_enabled => 0
end
def self.down

View File

@ -62,6 +62,9 @@ notice_successful_connection: Erfolgreicher Anschluß.
notice_file_not_found: Erbetene Akte besteht nicht oder ist gelöscht worden.
notice_locking_conflict: Data have been updated by another user.
#mail_subject_lost_password: Your redMine password
#mail_subject_register: redMine account activation
gui_validation_error: 1 Störung
gui_validation_error_plural: %d Störungen

View File

@ -62,6 +62,9 @@ notice_successful_connection: Successful connection.
notice_file_not_found: Requested file doesn't exist or has been deleted.
notice_locking_conflict: Data have been updated by another user.
mail_subject_lost_password: Your redMine password
mail_subject_register: redMine account activation
gui_validation_error: 1 error
gui_validation_error_plural: %d errors

View File

@ -62,6 +62,9 @@ notice_successful_connection: Successful connection.
notice_file_not_found: Requested file doesn't exist or has been deleted.
notice_locking_conflict: Data have been updated by another user.
#mail_subject_lost_password: Your redMine password
#mail_subject_register: redMine account activation
gui_validation_error: 1 error
gui_validation_error_plural: %d errores

View File

@ -62,6 +62,9 @@ notice_successful_connection: Connection réussie.
notice_file_not_found: Le fichier demandé n'existe pas ou a été supprimé.
notice_locking_conflict: Les données ont été mises à jour par un autre utilisateur. Mise à jour impossible.
mail_subject_lost_password: Votre mot de passe redMine
mail_subject_register: Activation de votre compte redMine
gui_validation_error: 1 erreur
gui_validation_error_plural: %d erreurs

View File

@ -370,6 +370,15 @@ color:#505050;
line-height:1.5em;
}
.rightbox{
background: #fafbfc;
border: 1px solid #c0c0c0;
float: right;
padding: 8px;
position: relative;
margin: 0 5px 5px;
}
.topright{
position: absolute;
right: 25px;