Adds date range filter and pagination on time entries detail view (closes #434).
git-svn-id: http://redmine.rubyforge.org/svn/trunk@1173 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
parent
792b7f30e3
commit
328df74dd1
|
@ -23,6 +23,7 @@ class TimelogController < ApplicationController
|
||||||
helper :sort
|
helper :sort
|
||||||
include SortHelper
|
include SortHelper
|
||||||
helper :issues
|
helper :issues
|
||||||
|
include TimelogHelper
|
||||||
|
|
||||||
def report
|
def report
|
||||||
@available_criterias = { 'version' => {:sql => "#{Issue.table_name}.fixed_version_id",
|
@available_criterias = { 'version' => {:sql => "#{Issue.table_name}.fixed_version_id",
|
||||||
|
@ -104,14 +105,84 @@ class TimelogController < ApplicationController
|
||||||
def details
|
def details
|
||||||
sort_init 'spent_on', 'desc'
|
sort_init 'spent_on', 'desc'
|
||||||
sort_update
|
sort_update
|
||||||
|
|
||||||
@entries = (@issue ? @issue : @project).time_entries.find(:all, :include => [:activity, :user, {:issue => [:tracker, :assigned_to, :priority]}], :order => sort_clause)
|
|
||||||
|
|
||||||
@total_hours = @entries.inject(0) { |sum,entry| sum + entry.hours }
|
@free_period = false
|
||||||
@owner_id = User.current.id
|
@from, @to = nil, nil
|
||||||
|
|
||||||
|
if params[:period_type] == '1' || (params[:period_type].nil? && !params[:period].nil?)
|
||||||
|
case params[:period].to_s
|
||||||
|
when 'today'
|
||||||
|
@from = @to = Date.today
|
||||||
|
when 'yesterday'
|
||||||
|
@from = @to = Date.today - 1
|
||||||
|
when 'current_week'
|
||||||
|
@from = Date.today - (Date.today.cwday - 1)%7
|
||||||
|
@to = @from + 6
|
||||||
|
when 'last_week'
|
||||||
|
@from = Date.today - 7 - (Date.today.cwday - 1)%7
|
||||||
|
@to = @from + 6
|
||||||
|
when '7_days'
|
||||||
|
@from = Date.today - 7
|
||||||
|
@to = Date.today
|
||||||
|
when 'current_month'
|
||||||
|
@from = Date.civil(Date.today.year, Date.today.month, 1)
|
||||||
|
@to = (@from >> 1) - 1
|
||||||
|
when 'last_month'
|
||||||
|
@from = Date.civil(Date.today.year, Date.today.month, 1) << 1
|
||||||
|
@to = (@from >> 1) - 1
|
||||||
|
when '30_days'
|
||||||
|
@from = Date.today - 30
|
||||||
|
@to = Date.today
|
||||||
|
when 'current_year'
|
||||||
|
@from = Date.civil(Date.today.year, 1, 1)
|
||||||
|
@to = Date.civil(Date.today.year, 12, 31)
|
||||||
|
end
|
||||||
|
elsif params[:period_type] == '2' || (params[:period_type].nil? && (!params[:from].nil? || !params[:to].nil?))
|
||||||
|
begin; @from = params[:from].to_s.to_date unless params[:from].blank?; rescue; end
|
||||||
|
begin; @to = params[:to].to_s.to_date unless params[:to].blank?; rescue; end
|
||||||
|
@free_period = true
|
||||||
|
else
|
||||||
|
# default
|
||||||
|
end
|
||||||
|
|
||||||
send_csv and return if 'csv' == params[:export]
|
@from, @to = @to, @from if @from && @to && @from > @to
|
||||||
render :action => 'details', :layout => false if request.xhr?
|
|
||||||
|
conditions = nil
|
||||||
|
if @from
|
||||||
|
if @to
|
||||||
|
conditions = ['spent_on BETWEEN ? AND ?', @from, @to]
|
||||||
|
else
|
||||||
|
conditions = ['spent_on >= ?', @from]
|
||||||
|
end
|
||||||
|
elsif @to
|
||||||
|
conditions = ['spent_on <= ?', @to]
|
||||||
|
end
|
||||||
|
|
||||||
|
@owner_id = User.current.id
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html {
|
||||||
|
# Paginate results
|
||||||
|
@entry_count = (@issue ? @issue : @project).time_entries.count(:conditions => conditions)
|
||||||
|
@entry_pages = Paginator.new self, @entry_count, per_page_option, params['page']
|
||||||
|
@entries = (@issue ? @issue : @project).time_entries.find(:all,
|
||||||
|
:include => [:activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
|
||||||
|
:conditions => conditions,
|
||||||
|
:order => sort_clause,
|
||||||
|
:limit => @entry_pages.items_per_page,
|
||||||
|
:offset => @entry_pages.current.offset)
|
||||||
|
@total_hours = (@issue ? @issue : @project).time_entries.sum(:hours, :conditions => conditions).to_f
|
||||||
|
render :layout => !request.xhr?
|
||||||
|
}
|
||||||
|
format.csv {
|
||||||
|
# Export all entries
|
||||||
|
@entries = (@issue ? @issue : @project).time_entries.find(:all,
|
||||||
|
:include => [:activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
|
||||||
|
:conditions => conditions,
|
||||||
|
:order => sort_clause)
|
||||||
|
send_data(entries_to_csv(@entries).read, :type => 'text/csv; header=present', :filename => 'timelog.csv')
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
|
@ -141,37 +212,4 @@ private
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def send_csv
|
|
||||||
ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
|
|
||||||
export = StringIO.new
|
|
||||||
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
|
|
||||||
# csv header fields
|
|
||||||
headers = [l(:field_spent_on),
|
|
||||||
l(:field_user),
|
|
||||||
l(:field_activity),
|
|
||||||
l(:field_issue),
|
|
||||||
l(:field_tracker),
|
|
||||||
l(:field_subject),
|
|
||||||
l(:field_hours),
|
|
||||||
l(:field_comments)
|
|
||||||
]
|
|
||||||
csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
|
|
||||||
# csv lines
|
|
||||||
@entries.each do |entry|
|
|
||||||
fields = [l_date(entry.spent_on),
|
|
||||||
entry.user,
|
|
||||||
entry.activity,
|
|
||||||
(entry.issue ? entry.issue.id : nil),
|
|
||||||
(entry.issue ? entry.issue.tracker : nil),
|
|
||||||
(entry.issue ? entry.issue.subject : nil),
|
|
||||||
entry.hours,
|
|
||||||
entry.comments
|
|
||||||
]
|
|
||||||
csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
export.rewind
|
|
||||||
send_data(export.read, :type => 'text/csv; header=present', :filename => 'export.csv')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -90,6 +90,10 @@ module ApplicationHelper
|
||||||
include_date ? local.strftime("#{@date_format} #{@time_format}") : local.strftime(@time_format)
|
include_date ? local.strftime("#{@date_format} #{@time_format}") : local.strftime(@time_format)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def html_hours(text)
|
||||||
|
text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>')
|
||||||
|
end
|
||||||
|
|
||||||
def authoring(created, author)
|
def authoring(created, author)
|
||||||
time_tag = content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created))
|
time_tag = content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created))
|
||||||
l(:label_added_time_by, author || 'Anonymous', time_tag)
|
l(:label_added_time_by, author || 'Anonymous', time_tag)
|
||||||
|
|
|
@ -108,13 +108,13 @@ module SortHelper
|
||||||
end
|
end
|
||||||
caption = titleize(Inflector::humanize(column)) unless caption
|
caption = titleize(Inflector::humanize(column)) unless caption
|
||||||
|
|
||||||
url = {:sort_key => column, :sort_order => order, :status => params[:status],
|
sort_options = { :sort_key => column, :sort_order => order }
|
||||||
:issue_id => params[:issue_id],
|
# don't reuse params if filters are present
|
||||||
:project_id => params[:project_id]}
|
url_options = params.has_key?(:set_filter) ? sort_options : params.merge(sort_options)
|
||||||
|
|
||||||
link_to_remote(caption,
|
link_to_remote(caption,
|
||||||
{:update => "content", :url => url},
|
{:update => "content", :url => url_options},
|
||||||
{:href => url_for(url)}) +
|
{:href => url_for(url_options)}) +
|
||||||
(icon ? nbsp(2) + image_tag(icon) : '')
|
(icon ? nbsp(2) + image_tag(icon) : '')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -27,4 +27,51 @@ module TimelogHelper
|
||||||
end
|
end
|
||||||
sum
|
sum
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def options_for_period_select(value)
|
||||||
|
options_for_select([[l(:label_all_time), 'all'],
|
||||||
|
[l(:label_today), 'today'],
|
||||||
|
[l(:label_yesterday), 'yesterday'],
|
||||||
|
[l(:label_this_week), 'current_week'],
|
||||||
|
[l(:label_last_week), 'last_week'],
|
||||||
|
[l(:label_last_n_days, 7), '7_days'],
|
||||||
|
[l(:label_this_month), 'current_month'],
|
||||||
|
[l(:label_last_month), 'last_month'],
|
||||||
|
[l(:label_last_n_days, 30), '30_days'],
|
||||||
|
[l(:label_this_year), 'current_year']],
|
||||||
|
value)
|
||||||
|
end
|
||||||
|
|
||||||
|
def entries_to_csv(entries)
|
||||||
|
ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
|
||||||
|
export = StringIO.new
|
||||||
|
CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
|
||||||
|
# csv header fields
|
||||||
|
headers = [l(:field_spent_on),
|
||||||
|
l(:field_user),
|
||||||
|
l(:field_activity),
|
||||||
|
l(:field_issue),
|
||||||
|
l(:field_tracker),
|
||||||
|
l(:field_subject),
|
||||||
|
l(:field_hours),
|
||||||
|
l(:field_comments)
|
||||||
|
]
|
||||||
|
csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
|
||||||
|
# csv lines
|
||||||
|
entries.each do |entry|
|
||||||
|
fields = [l_date(entry.spent_on),
|
||||||
|
entry.user,
|
||||||
|
entry.activity,
|
||||||
|
(entry.issue ? entry.issue.id : nil),
|
||||||
|
(entry.issue ? entry.issue.tracker : nil),
|
||||||
|
(entry.issue ? entry.issue.subject : nil),
|
||||||
|
entry.hours,
|
||||||
|
entry.comments
|
||||||
|
]
|
||||||
|
csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
export.rewind
|
||||||
|
export
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -46,5 +46,10 @@ class TimeEntry < ActiveRecord::Base
|
||||||
self.tyear = spent_on ? spent_on.year : nil
|
self.tyear = spent_on ? spent_on.year : nil
|
||||||
self.tmonth = spent_on ? spent_on.month : nil
|
self.tmonth = spent_on ? spent_on.month : nil
|
||||||
self.tweek = spent_on ? Date.civil(spent_on.year, spent_on.month, spent_on.day).cweek : nil
|
self.tweek = spent_on ? Date.civil(spent_on.year, spent_on.month, spent_on.day).cweek : nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns true if the time entry can be edited by usr, otherwise false
|
||||||
|
def editable_by?(usr)
|
||||||
|
usr == self.user
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<table class="list time-entries">
|
||||||
|
<thead>
|
||||||
|
<%= sort_header_tag('spent_on', :caption => l(:label_date), :default_order => 'desc') %>
|
||||||
|
<%= sort_header_tag('user_id', :caption => l(:label_member)) %>
|
||||||
|
<%= sort_header_tag('activity_id', :caption => l(:label_activity)) %>
|
||||||
|
<%= sort_header_tag('issue_id', :caption => l(:label_issue), :default_order => 'desc') %>
|
||||||
|
<th><%= l(:field_comments) %></th>
|
||||||
|
<%= sort_header_tag('hours', :caption => l(:field_hours)) %>
|
||||||
|
<th></th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% entries.each do |entry| -%>
|
||||||
|
<tr class="time-entry <%= cycle("odd", "even") %>">
|
||||||
|
<td class="spent_on"><%= format_date(entry.spent_on) %></td>
|
||||||
|
<td class="user"><%= entry.user.name %></td>
|
||||||
|
<td class="activity"><%= entry.activity.name %></td>
|
||||||
|
<td class="subject">
|
||||||
|
<% if entry.issue -%>
|
||||||
|
<div class="tooltip"><%= link_to_issue entry.issue %>: <%= h(truncate(entry.issue.subject, 50)) -%>
|
||||||
|
<span class="tip"><%= render_issue_tooltip entry.issue %></span>
|
||||||
|
</div>
|
||||||
|
<% end -%>
|
||||||
|
</td>
|
||||||
|
<td class="comments"><%=h entry.comments %></td>
|
||||||
|
<td class="hours"><%= entry.hours %></td>
|
||||||
|
<td align="center"><%= link_to_if_authorized(l(:button_edit),
|
||||||
|
{:controller => 'timelog', :action => 'edit', :id => entry},
|
||||||
|
:class => 'icon icon-edit') if entry.editable_by?(User.current) %></td>
|
||||||
|
</tr>
|
||||||
|
<% end -%>
|
||||||
|
</tbdoy>
|
||||||
|
</table>
|
|
@ -4,48 +4,48 @@
|
||||||
|
|
||||||
<h2><%= l(:label_spent_time) %></h2>
|
<h2><%= l(:label_spent_time) %></h2>
|
||||||
|
|
||||||
<h3><%= link_to(@project.name, {:action => 'details', :project_id => @project}) if @project %>
|
<% if @issue %>
|
||||||
<%= "/ " + link_to_issue(@issue) + h(": #{@issue.subject}") if @issue %></h3>
|
<h3><%= link_to(@project.name, {:action => 'details', :project_id => @project}) %> / <%= link_to_issue(@issue) %></h3>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<h3 class="textright"><%= l(:label_total) %>: <%= lwr(:label_f_hour, @total_hours) %></h3>
|
<% form_remote_tag( :url => {}, :method => :get, :update => 'content' ) do %>
|
||||||
|
<%= hidden_field_tag 'project_id', params[:project_id] %>
|
||||||
|
<%= hidden_field_tag 'issue_id', params[:issue_id] if @issue %>
|
||||||
|
|
||||||
|
<fieldset><legend><%= l(:label_date_range) %></legend>
|
||||||
|
<p>
|
||||||
|
<%= radio_button_tag 'period_type', '1', !@free_period %>
|
||||||
|
<%= select_tag 'period', options_for_period_select(params[:period]),
|
||||||
|
:onchange => 'this.form.onsubmit();',
|
||||||
|
:onfocus => '$("period_type_1").checked = true;' %>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<%= radio_button_tag 'period_type', '2', @free_period %>
|
||||||
|
<%= l(:label_date_from) %>
|
||||||
|
<%= text_field_tag 'from', @from, :size => 10, :onfocus => '$("period_type_2").checked = true;' %> <%= calendar_for('from') %>
|
||||||
|
<%= l(:label_date_to) %>
|
||||||
|
<%= text_field_tag 'to', @to, :size => 10, :onfocus => '$("period_type_2").checked = true;' %> <%= calendar_for('to') %>
|
||||||
|
<%= submit_tag l(:button_submit), :name => nil, :onclick => '$("period_type_2").checked = true;' %>
|
||||||
|
</p>
|
||||||
|
</fieldset>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="total-hours">
|
||||||
|
<p><%= l(:label_total) %>: <%= html_hours(lwr(:label_f_hour, @total_hours)) %></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<% unless @entries.empty? %>
|
<% unless @entries.empty? %>
|
||||||
<table class="list">
|
<%= render :partial => 'list', :locals => { :entries => @entries }%>
|
||||||
<thead>
|
|
||||||
<%= sort_header_tag('spent_on', :caption => l(:label_date), :default_order => 'desc') %>
|
|
||||||
<%= sort_header_tag('user_id', :caption => l(:label_member)) %>
|
|
||||||
<%= sort_header_tag('activity_id', :caption => l(:label_activity)) %>
|
|
||||||
<%= sort_header_tag('issue_id', :caption => l(:label_issue)) %>
|
|
||||||
<th><%= l(:field_comments) %></th>
|
|
||||||
<%= sort_header_tag('hours', :caption => l(:field_hours)) %>
|
|
||||||
<th></th>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<% @entries.each do |entry| %>
|
|
||||||
<tr class="<%= cycle("odd", "even") %>">
|
|
||||||
<td align="center"><%= format_date(entry.spent_on) %></td>
|
|
||||||
<td align="center"><%= entry.user.name %></td>
|
|
||||||
<td align="center"><%= entry.activity.name %></td>
|
|
||||||
<td>
|
|
||||||
<% if entry.issue %>
|
|
||||||
<div class="tooltip">
|
|
||||||
<%= link_to_issue entry.issue %>: <%= h(truncate(entry.issue.subject, 50)) %>
|
|
||||||
<span class="tip">
|
|
||||||
<%= render_issue_tooltip entry.issue %>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
</td>
|
|
||||||
<td><%=h entry.comments %></td>
|
|
||||||
<td align="center"><strong><%= entry.hours %></strong></td>
|
|
||||||
<td align="center"><%= link_to_if_authorized(l(:button_edit), {:controller => 'timelog', :action => 'edit', :id => entry}, :class => "icon icon-edit") if entry.user_id == @owner_id %></td>
|
|
||||||
</tr>
|
|
||||||
<% end %>
|
|
||||||
</tbdoy>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<div class="contextual">
|
<div class="contextual">
|
||||||
<%= l(:label_export_to) %>
|
<%= l(:label_export_to) %>
|
||||||
<%= link_to 'CSV', params.update(:export => 'csv'), :class => 'icon icon-csv' %>
|
<%= link_to 'CSV', params.merge(:format => 'csv'), :class => 'icon icon-csv' %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<p class="pagination"><%= pagination_links_full @entry_pages, @entry_count %></p>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% content_for :header_tags do %>
|
||||||
|
<%= javascript_include_tag 'calendar/calendar' %>
|
||||||
|
<%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
|
||||||
|
<%= javascript_include_tag 'calendar/calendar-setup' %>
|
||||||
|
<%= stylesheet_link_tag 'calendar' %>
|
||||||
|
<% end %>
|
||||||
|
|
|
@ -592,3 +592,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -592,3 +592,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -592,3 +592,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -362,7 +362,15 @@ label_in_less_than: in less than
|
||||||
label_in_more_than: in more than
|
label_in_more_than: in more than
|
||||||
label_in: in
|
label_in: in
|
||||||
label_today: today
|
label_today: today
|
||||||
|
label_all_time: all time
|
||||||
|
label_yesterday: yesterday
|
||||||
label_this_week: this week
|
label_this_week: this week
|
||||||
|
label_last_week: last week
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_month: last month
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
label_less_than_ago: less than days ago
|
label_less_than_ago: less than days ago
|
||||||
label_more_than_ago: more than days ago
|
label_more_than_ago: more than days ago
|
||||||
label_ago: days ago
|
label_ago: days ago
|
||||||
|
|
|
@ -595,3 +595,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -596,3 +596,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -362,7 +362,15 @@ label_in_less_than: dans moins de
|
||||||
label_in_more_than: dans plus de
|
label_in_more_than: dans plus de
|
||||||
label_in: dans
|
label_in: dans
|
||||||
label_today: aujourd'hui
|
label_today: aujourd'hui
|
||||||
|
label_all_time: toute la période
|
||||||
|
label_yesterday: hier
|
||||||
label_this_week: cette semaine
|
label_this_week: cette semaine
|
||||||
|
label_last_week: la semaine dernière
|
||||||
|
label_last_n_days: les %d derniers jours
|
||||||
|
label_this_month: ce mois-ci
|
||||||
|
label_last_month: le mois dernier
|
||||||
|
label_this_year: cette année
|
||||||
|
label_date_range: Période
|
||||||
label_less_than_ago: il y a moins de
|
label_less_than_ago: il y a moins de
|
||||||
label_more_than_ago: il y a plus de
|
label_more_than_ago: il y a plus de
|
||||||
label_ago: il y a
|
label_ago: il y a
|
||||||
|
|
|
@ -592,3 +592,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -592,3 +592,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -593,3 +593,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -592,3 +592,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -593,3 +593,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -593,3 +593,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -592,3 +592,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -592,3 +592,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -592,3 +592,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -592,3 +592,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -596,3 +596,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -593,3 +593,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -593,3 +593,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -594,3 +594,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -592,3 +592,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -595,3 +595,11 @@ button_configure: Configure
|
||||||
label_plugins: Plugins
|
label_plugins: Plugins
|
||||||
label_ldap_authentication: LDAP authentication
|
label_ldap_authentication: LDAP authentication
|
||||||
label_downloads_abbr: D/L
|
label_downloads_abbr: D/L
|
||||||
|
label_this_month: this month
|
||||||
|
label_last_n_days: last %d days
|
||||||
|
label_all_time: all time
|
||||||
|
label_this_year: this year
|
||||||
|
label_date_range: Date range
|
||||||
|
label_last_week: last week
|
||||||
|
label_yesterday: yesterday
|
||||||
|
label_last_month: last month
|
||||||
|
|
|
@ -110,6 +110,10 @@ tr.user td { white-space: nowrap; }
|
||||||
tr.user.locked, tr.user.registered { color: #aaa; }
|
tr.user.locked, tr.user.registered { color: #aaa; }
|
||||||
tr.user.locked a, tr.user.registered a { color: #aaa; }
|
tr.user.locked a, tr.user.registered a { color: #aaa; }
|
||||||
|
|
||||||
|
tr.time-entry { text-align: center; white-space: nowrap; }
|
||||||
|
tr.time-entry td.subject, tr.time-entry td.comments { text-align: left; }
|
||||||
|
tr.time-entry td.hours { text-align: right; font-weight: bold; padding-right: 0.6em; }
|
||||||
|
|
||||||
table.list tbody tr:hover { background-color:#ffffdd; }
|
table.list tbody tr:hover { background-color:#ffffdd; }
|
||||||
table td {padding:2px;}
|
table td {padding:2px;}
|
||||||
table p {margin:0;}
|
table p {margin:0;}
|
||||||
|
@ -169,6 +173,9 @@ div#roadmap .wiki h1:first-child { display: none; }
|
||||||
div#roadmap .wiki h1 { font-size: 120%; }
|
div#roadmap .wiki h1 { font-size: 120%; }
|
||||||
div#roadmap .wiki h2 { font-size: 110%; }
|
div#roadmap .wiki h2 { font-size: 110%; }
|
||||||
|
|
||||||
|
div.total-hours { text-align: left; font-size: 110%; font-weight: bold; }
|
||||||
|
div.total-hours span.hours-int { font-size: 120%; }
|
||||||
|
|
||||||
.autoscroll {overflow-x: auto; padding:1px; width:100%; margin-bottom: 1.2em;}
|
.autoscroll {overflow-x: auto; padding:1px; width:100%; margin-bottom: 1.2em;}
|
||||||
#user_firstname, #user_lastname, #user_mail, #my_account_form select { width: 90%; }
|
#user_firstname, #user_lastname, #user_mail, #my_account_form select { width: 90%; }
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ img.calendar-trigger {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.calendar { position: relative; z-index: 15;}
|
div.calendar { position: relative; z-index: 30;}
|
||||||
|
|
||||||
.calendar, .calendar table {
|
.calendar, .calendar table {
|
||||||
border: 1px solid #556;
|
border: 1px solid #556;
|
||||||
|
|
|
@ -21,7 +21,7 @@ time_entries_002:
|
||||||
comments: ""
|
comments: ""
|
||||||
updated_on: 2007-03-23 14:11:04 +01:00
|
updated_on: 2007-03-23 14:11:04 +01:00
|
||||||
activity_id: 8
|
activity_id: 8
|
||||||
spent_on: 2007-03-23
|
spent_on: 2007-03-12
|
||||||
issue_id: 1
|
issue_id: 1
|
||||||
id: 2
|
id: 2
|
||||||
hours: 150.0
|
hours: 150.0
|
||||||
|
|
|
@ -22,7 +22,7 @@ require 'timelog_controller'
|
||||||
class TimelogController; def rescue_action(e) raise e end; end
|
class TimelogController; def rescue_action(e) raise e end; end
|
||||||
|
|
||||||
class TimelogControllerTest < Test::Unit::TestCase
|
class TimelogControllerTest < Test::Unit::TestCase
|
||||||
fixtures :time_entries, :issues
|
fixtures :projects, :issues, :time_entries, :users, :trackers, :enumerations, :issue_statuses
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@controller = TimelogController.new
|
@controller = TimelogController.new
|
||||||
|
@ -49,4 +49,52 @@ class TimelogControllerTest < Test::Unit::TestCase
|
||||||
assert_template 'report'
|
assert_template 'report'
|
||||||
assert_not_nil assigns(:hours)
|
assert_not_nil assigns(:hours)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_details_at_project_level
|
||||||
|
get :details, :project_id => 1
|
||||||
|
assert_response :success
|
||||||
|
assert_template 'details'
|
||||||
|
assert_not_nil assigns(:entries)
|
||||||
|
assert_equal 3, assigns(:entries).size
|
||||||
|
assert_not_nil assigns(:total_hours)
|
||||||
|
assert_equal 155.25, assigns(:total_hours)
|
||||||
|
# display all time by default
|
||||||
|
assert_nil assigns(:from)
|
||||||
|
assert_nil assigns(:to)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_details_at_project_level_with_date_range
|
||||||
|
get :details, :project_id => 1, :from => '2007-03-20', :to => '2007-04-30'
|
||||||
|
assert_response :success
|
||||||
|
assert_template 'details'
|
||||||
|
assert_not_nil assigns(:entries)
|
||||||
|
assert_equal 2, assigns(:entries).size
|
||||||
|
assert_not_nil assigns(:total_hours)
|
||||||
|
assert_equal 5.25, assigns(:total_hours)
|
||||||
|
assert_equal '2007-03-20'.to_date, assigns(:from)
|
||||||
|
assert_equal '2007-04-30'.to_date, assigns(:to)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_details_at_project_level_with_period
|
||||||
|
get :details, :project_id => 1, :period => '7_days'
|
||||||
|
assert_response :success
|
||||||
|
assert_template 'details'
|
||||||
|
assert_not_nil assigns(:entries)
|
||||||
|
assert_not_nil assigns(:total_hours)
|
||||||
|
assert_equal Date.today - 7, assigns(:from)
|
||||||
|
assert_equal Date.today, assigns(:to)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_details_at_issue_level
|
||||||
|
get :details, :issue_id => 1
|
||||||
|
assert_response :success
|
||||||
|
assert_template 'details'
|
||||||
|
assert_not_nil assigns(:entries)
|
||||||
|
assert_equal 2, assigns(:entries).size
|
||||||
|
assert_not_nil assigns(:total_hours)
|
||||||
|
assert_equal 154.25, assigns(:total_hours)
|
||||||
|
# display all time by default
|
||||||
|
assert_nil assigns(:from)
|
||||||
|
assert_nil assigns(:to)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue