##// END OF EJS Templates
Adds date range filter and pagination on time entries detail view (closes #434)....
Jean-Philippe Lang -
r1159:328df74dd177
parent child
Show More
@@ -0,0 +1,32
1 <table class="list time-entries">
2 <thead>
3 <%= sort_header_tag('spent_on', :caption => l(:label_date), :default_order => 'desc') %>
4 <%= sort_header_tag('user_id', :caption => l(:label_member)) %>
5 <%= sort_header_tag('activity_id', :caption => l(:label_activity)) %>
6 <%= sort_header_tag('issue_id', :caption => l(:label_issue), :default_order => 'desc') %>
7 <th><%= l(:field_comments) %></th>
8 <%= sort_header_tag('hours', :caption => l(:field_hours)) %>
9 <th></th>
10 </thead>
11 <tbody>
12 <% entries.each do |entry| -%>
13 <tr class="time-entry <%= cycle("odd", "even") %>">
14 <td class="spent_on"><%= format_date(entry.spent_on) %></td>
15 <td class="user"><%= entry.user.name %></td>
16 <td class="activity"><%= entry.activity.name %></td>
17 <td class="subject">
18 <% if entry.issue -%>
19 <div class="tooltip"><%= link_to_issue entry.issue %>: <%= h(truncate(entry.issue.subject, 50)) -%>
20 <span class="tip"><%= render_issue_tooltip entry.issue %></span>
21 </div>
22 <% end -%>
23 </td>
24 <td class="comments"><%=h entry.comments %></td>
25 <td class="hours"><%= entry.hours %></td>
26 <td align="center"><%= link_to_if_authorized(l(:button_edit),
27 {:controller => 'timelog', :action => 'edit', :id => entry},
28 :class => 'icon icon-edit') if entry.editable_by?(User.current) %></td>
29 </tr>
30 <% end -%>
31 </tbdoy>
32 </table>
@@ -23,6 +23,7 class TimelogController < ApplicationController
23 helper :sort
23 helper :sort
24 include SortHelper
24 include SortHelper
25 helper :issues
25 helper :issues
26 include TimelogHelper
26
27
27 def report
28 def report
28 @available_criterias = { 'version' => {:sql => "#{Issue.table_name}.fixed_version_id",
29 @available_criterias = { 'version' => {:sql => "#{Issue.table_name}.fixed_version_id",
@@ -104,14 +105,84 class TimelogController < ApplicationController
104 def details
105 def details
105 sort_init 'spent_on', 'desc'
106 sort_init 'spent_on', 'desc'
106 sort_update
107 sort_update
107
108 @entries = (@issue ? @issue : @project).time_entries.find(:all, :include => [:activity, :user, {:issue => [:tracker, :assigned_to, :priority]}], :order => sort_clause)
109
108
110 @total_hours = @entries.inject(0) { |sum,entry| sum + entry.hours }
109 @free_period = false
111 @owner_id = User.current.id
110 @from, @to = nil, nil
111
112 if params[:period_type] == '1' || (params[:period_type].nil? && !params[:period].nil?)
113 case params[:period].to_s
114 when 'today'
115 @from = @to = Date.today
116 when 'yesterday'
117 @from = @to = Date.today - 1
118 when 'current_week'
119 @from = Date.today - (Date.today.cwday - 1)%7
120 @to = @from + 6
121 when 'last_week'
122 @from = Date.today - 7 - (Date.today.cwday - 1)%7
123 @to = @from + 6
124 when '7_days'
125 @from = Date.today - 7
126 @to = Date.today
127 when 'current_month'
128 @from = Date.civil(Date.today.year, Date.today.month, 1)
129 @to = (@from >> 1) - 1
130 when 'last_month'
131 @from = Date.civil(Date.today.year, Date.today.month, 1) << 1
132 @to = (@from >> 1) - 1
133 when '30_days'
134 @from = Date.today - 30
135 @to = Date.today
136 when 'current_year'
137 @from = Date.civil(Date.today.year, 1, 1)
138 @to = Date.civil(Date.today.year, 12, 31)
139 end
140 elsif params[:period_type] == '2' || (params[:period_type].nil? && (!params[:from].nil? || !params[:to].nil?))
141 begin; @from = params[:from].to_s.to_date unless params[:from].blank?; rescue; end
142 begin; @to = params[:to].to_s.to_date unless params[:to].blank?; rescue; end
143 @free_period = true
144 else
145 # default
146 end
147
148 @from, @to = @to, @from if @from && @to && @from > @to
112
149
113 send_csv and return if 'csv' == params[:export]
150 conditions = nil
114 render :action => 'details', :layout => false if request.xhr?
151 if @from
152 if @to
153 conditions = ['spent_on BETWEEN ? AND ?', @from, @to]
154 else
155 conditions = ['spent_on >= ?', @from]
156 end
157 elsif @to
158 conditions = ['spent_on <= ?', @to]
159 end
160
161 @owner_id = User.current.id
162
163 respond_to do |format|
164 format.html {
165 # Paginate results
166 @entry_count = (@issue ? @issue : @project).time_entries.count(:conditions => conditions)
167 @entry_pages = Paginator.new self, @entry_count, per_page_option, params['page']
168 @entries = (@issue ? @issue : @project).time_entries.find(:all,
169 :include => [:activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
170 :conditions => conditions,
171 :order => sort_clause,
172 :limit => @entry_pages.items_per_page,
173 :offset => @entry_pages.current.offset)
174 @total_hours = (@issue ? @issue : @project).time_entries.sum(:hours, :conditions => conditions).to_f
175 render :layout => !request.xhr?
176 }
177 format.csv {
178 # Export all entries
179 @entries = (@issue ? @issue : @project).time_entries.find(:all,
180 :include => [:activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
181 :conditions => conditions,
182 :order => sort_clause)
183 send_data(entries_to_csv(@entries).read, :type => 'text/csv; header=present', :filename => 'timelog.csv')
184 }
185 end
115 end
186 end
116
187
117 def edit
188 def edit
@@ -141,37 +212,4 private
141 return false
212 return false
142 end
213 end
143 end
214 end
144
145 def send_csv
146 ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
147 export = StringIO.new
148 CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
149 # csv header fields
150 headers = [l(:field_spent_on),
151 l(:field_user),
152 l(:field_activity),
153 l(:field_issue),
154 l(:field_tracker),
155 l(:field_subject),
156 l(:field_hours),
157 l(:field_comments)
158 ]
159 csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
160 # csv lines
161 @entries.each do |entry|
162 fields = [l_date(entry.spent_on),
163 entry.user,
164 entry.activity,
165 (entry.issue ? entry.issue.id : nil),
166 (entry.issue ? entry.issue.tracker : nil),
167 (entry.issue ? entry.issue.subject : nil),
168 entry.hours,
169 entry.comments
170 ]
171 csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
172 end
173 end
174 export.rewind
175 send_data(export.read, :type => 'text/csv; header=present', :filename => 'export.csv')
176 end
177 end
215 end
@@ -90,6 +90,10 module ApplicationHelper
90 include_date ? local.strftime("#{@date_format} #{@time_format}") : local.strftime(@time_format)
90 include_date ? local.strftime("#{@date_format} #{@time_format}") : local.strftime(@time_format)
91 end
91 end
92
92
93 def html_hours(text)
94 text.gsub(%r{(\d+)\.(\d+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>')
95 end
96
93 def authoring(created, author)
97 def authoring(created, author)
94 time_tag = content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created))
98 time_tag = content_tag('acronym', distance_of_time_in_words(Time.now, created), :title => format_time(created))
95 l(:label_added_time_by, author || 'Anonymous', time_tag)
99 l(:label_added_time_by, author || 'Anonymous', time_tag)
@@ -108,13 +108,13 module SortHelper
108 end
108 end
109 caption = titleize(Inflector::humanize(column)) unless caption
109 caption = titleize(Inflector::humanize(column)) unless caption
110
110
111 url = {:sort_key => column, :sort_order => order, :status => params[:status],
111 sort_options = { :sort_key => column, :sort_order => order }
112 :issue_id => params[:issue_id],
112 # don't reuse params if filters are present
113 :project_id => params[:project_id]}
113 url_options = params.has_key?(:set_filter) ? sort_options : params.merge(sort_options)
114
114
115 link_to_remote(caption,
115 link_to_remote(caption,
116 {:update => "content", :url => url},
116 {:update => "content", :url => url_options},
117 {:href => url_for(url)}) +
117 {:href => url_for(url_options)}) +
118 (icon ? nbsp(2) + image_tag(icon) : '')
118 (icon ? nbsp(2) + image_tag(icon) : '')
119 end
119 end
120
120
@@ -27,4 +27,51 module TimelogHelper
27 end
27 end
28 sum
28 sum
29 end
29 end
30
31 def options_for_period_select(value)
32 options_for_select([[l(:label_all_time), 'all'],
33 [l(:label_today), 'today'],
34 [l(:label_yesterday), 'yesterday'],
35 [l(:label_this_week), 'current_week'],
36 [l(:label_last_week), 'last_week'],
37 [l(:label_last_n_days, 7), '7_days'],
38 [l(:label_this_month), 'current_month'],
39 [l(:label_last_month), 'last_month'],
40 [l(:label_last_n_days, 30), '30_days'],
41 [l(:label_this_year), 'current_year']],
42 value)
43 end
44
45 def entries_to_csv(entries)
46 ic = Iconv.new(l(:general_csv_encoding), 'UTF-8')
47 export = StringIO.new
48 CSV::Writer.generate(export, l(:general_csv_separator)) do |csv|
49 # csv header fields
50 headers = [l(:field_spent_on),
51 l(:field_user),
52 l(:field_activity),
53 l(:field_issue),
54 l(:field_tracker),
55 l(:field_subject),
56 l(:field_hours),
57 l(:field_comments)
58 ]
59 csv << headers.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
60 # csv lines
61 entries.each do |entry|
62 fields = [l_date(entry.spent_on),
63 entry.user,
64 entry.activity,
65 (entry.issue ? entry.issue.id : nil),
66 (entry.issue ? entry.issue.tracker : nil),
67 (entry.issue ? entry.issue.subject : nil),
68 entry.hours,
69 entry.comments
70 ]
71 csv << fields.collect {|c| begin; ic.iconv(c.to_s); rescue; c.to_s; end }
72 end
73 end
74 export.rewind
75 export
76 end
30 end
77 end
@@ -46,5 +46,10 class TimeEntry < ActiveRecord::Base
46 self.tyear = spent_on ? spent_on.year : nil
46 self.tyear = spent_on ? spent_on.year : nil
47 self.tmonth = spent_on ? spent_on.month : nil
47 self.tmonth = spent_on ? spent_on.month : nil
48 self.tweek = spent_on ? Date.civil(spent_on.year, spent_on.month, spent_on.day).cweek : nil
48 self.tweek = spent_on ? Date.civil(spent_on.year, spent_on.month, spent_on.day).cweek : nil
49 end
49 end
50
51 # Returns true if the time entry can be edited by usr, otherwise false
52 def editable_by?(usr)
53 usr == self.user
54 end
50 end
55 end
@@ -4,48 +4,48
4
4
5 <h2><%= l(:label_spent_time) %></h2>
5 <h2><%= l(:label_spent_time) %></h2>
6
6
7 <h3><%= link_to(@project.name, {:action => 'details', :project_id => @project}) if @project %>
7 <% if @issue %>
8 <%= "/ " + link_to_issue(@issue) + h(": #{@issue.subject}") if @issue %></h3>
8 <h3><%= link_to(@project.name, {:action => 'details', :project_id => @project}) %> / <%= link_to_issue(@issue) %></h3>
9 <% end %>
9
10
10 <h3 class="textright"><%= l(:label_total) %>: <%= lwr(:label_f_hour, @total_hours) %></h3>
11 <% form_remote_tag( :url => {}, :method => :get, :update => 'content' ) do %>
12 <%= hidden_field_tag 'project_id', params[:project_id] %>
13 <%= hidden_field_tag 'issue_id', params[:issue_id] if @issue %>
11
14
12 <% unless @entries.empty? %>
15 <fieldset><legend><%= l(:label_date_range) %></legend>
13 <table class="list">
16 <p>
14 <thead>
17 <%= radio_button_tag 'period_type', '1', !@free_period %>
15 <%= sort_header_tag('spent_on', :caption => l(:label_date), :default_order => 'desc') %>
18 <%= select_tag 'period', options_for_period_select(params[:period]),
16 <%= sort_header_tag('user_id', :caption => l(:label_member)) %>
19 :onchange => 'this.form.onsubmit();',
17 <%= sort_header_tag('activity_id', :caption => l(:label_activity)) %>
20 :onfocus => '$("period_type_1").checked = true;' %>
18 <%= sort_header_tag('issue_id', :caption => l(:label_issue)) %>
21 </p>
19 <th><%= l(:field_comments) %></th>
22 <p>
20 <%= sort_header_tag('hours', :caption => l(:field_hours)) %>
23 <%= radio_button_tag 'period_type', '2', @free_period %>
21 <th></th>
24 <%= l(:label_date_from) %>
22 </thead>
25 <%= text_field_tag 'from', @from, :size => 10, :onfocus => '$("period_type_2").checked = true;' %> <%= calendar_for('from') %>
23 <tbody>
26 <%= l(:label_date_to) %>
24 <% @entries.each do |entry| %>
27 <%= text_field_tag 'to', @to, :size => 10, :onfocus => '$("period_type_2").checked = true;' %> <%= calendar_for('to') %>
25 <tr class="<%= cycle("odd", "even") %>">
28 <%= submit_tag l(:button_submit), :name => nil, :onclick => '$("period_type_2").checked = true;' %>
26 <td align="center"><%= format_date(entry.spent_on) %></td>
29 </p>
27 <td align="center"><%= entry.user.name %></td>
30 </fieldset>
28 <td align="center"><%= entry.activity.name %></td>
29 <td>
30 <% if entry.issue %>
31 <div class="tooltip">
32 <%= link_to_issue entry.issue %>: <%= h(truncate(entry.issue.subject, 50)) %>
33 <span class="tip">
34 <%= render_issue_tooltip entry.issue %>
35 </span>
36 </div>
37 <% end %>
38 </td>
39 <td><%=h entry.comments %></td>
40 <td align="center"><strong><%= entry.hours %></strong></td>
41 <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>
42 </tr>
43 <% end %>
31 <% end %>
44 </tbdoy>
45 </table>
46
32
33 <div class="total-hours">
34 <p><%= l(:label_total) %>: <%= html_hours(lwr(:label_f_hour, @total_hours)) %></p>
35 </div>
36
37 <% unless @entries.empty? %>
38 <%= render :partial => 'list', :locals => { :entries => @entries }%>
47 <div class="contextual">
39 <div class="contextual">
48 <%= l(:label_export_to) %>
40 <%= l(:label_export_to) %>
49 <%= link_to 'CSV', params.update(:export => 'csv'), :class => 'icon icon-csv' %>
41 <%= link_to 'CSV', params.merge(:format => 'csv'), :class => 'icon icon-csv' %>
50 </div>
42 </div>
51 <% end %> No newline at end of file
43 <p class="pagination"><%= pagination_links_full @entry_pages, @entry_count %></p>
44 <% end %>
45
46 <% content_for :header_tags do %>
47 <%= javascript_include_tag 'calendar/calendar' %>
48 <%= javascript_include_tag "calendar/lang/calendar-#{current_language}.js" %>
49 <%= javascript_include_tag 'calendar/calendar-setup' %>
50 <%= stylesheet_link_tag 'calendar' %>
51 <% end %>
@@ -592,3 +592,11 button_configure: Configure
592 label_plugins: Plugins
592 label_plugins: Plugins
593 label_ldap_authentication: LDAP authentication
593 label_ldap_authentication: LDAP authentication
594 label_downloads_abbr: D/L
594 label_downloads_abbr: D/L
595 label_this_month: this month
596 label_last_n_days: last %d days
597 label_all_time: all time
598 label_this_year: this year
599 label_date_range: Date range
600 label_last_week: last week
601 label_yesterday: yesterday
602 label_last_month: last month
@@ -592,3 +592,11 button_configure: Configure
592 label_plugins: Plugins
592 label_plugins: Plugins
593 label_ldap_authentication: LDAP authentication
593 label_ldap_authentication: LDAP authentication
594 label_downloads_abbr: D/L
594 label_downloads_abbr: D/L
595 label_this_month: this month
596 label_last_n_days: last %d days
597 label_all_time: all time
598 label_this_year: this year
599 label_date_range: Date range
600 label_last_week: last week
601 label_yesterday: yesterday
602 label_last_month: last month
@@ -592,3 +592,11 button_configure: Configure
592 label_plugins: Plugins
592 label_plugins: Plugins
593 label_ldap_authentication: LDAP authentication
593 label_ldap_authentication: LDAP authentication
594 label_downloads_abbr: D/L
594 label_downloads_abbr: D/L
595 label_this_month: this month
596 label_last_n_days: last %d days
597 label_all_time: all time
598 label_this_year: this year
599 label_date_range: Date range
600 label_last_week: last week
601 label_yesterday: yesterday
602 label_last_month: last month
@@ -362,7 +362,15 label_in_less_than: in less than
362 label_in_more_than: in more than
362 label_in_more_than: in more than
363 label_in: in
363 label_in: in
364 label_today: today
364 label_today: today
365 label_all_time: all time
366 label_yesterday: yesterday
365 label_this_week: this week
367 label_this_week: this week
368 label_last_week: last week
369 label_last_n_days: last %d days
370 label_this_month: this month
371 label_last_month: last month
372 label_this_year: this year
373 label_date_range: Date range
366 label_less_than_ago: less than days ago
374 label_less_than_ago: less than days ago
367 label_more_than_ago: more than days ago
375 label_more_than_ago: more than days ago
368 label_ago: days ago
376 label_ago: days ago
@@ -595,3 +595,11 button_configure: Configure
595 label_plugins: Plugins
595 label_plugins: Plugins
596 label_ldap_authentication: LDAP authentication
596 label_ldap_authentication: LDAP authentication
597 label_downloads_abbr: D/L
597 label_downloads_abbr: D/L
598 label_this_month: this month
599 label_last_n_days: last %d days
600 label_all_time: all time
601 label_this_year: this year
602 label_date_range: Date range
603 label_last_week: last week
604 label_yesterday: yesterday
605 label_last_month: last month
@@ -596,3 +596,11 button_configure: Configure
596 label_plugins: Plugins
596 label_plugins: Plugins
597 label_ldap_authentication: LDAP authentication
597 label_ldap_authentication: LDAP authentication
598 label_downloads_abbr: D/L
598 label_downloads_abbr: D/L
599 label_this_month: this month
600 label_last_n_days: last %d days
601 label_all_time: all time
602 label_this_year: this year
603 label_date_range: Date range
604 label_last_week: last week
605 label_yesterday: yesterday
606 label_last_month: last month
@@ -362,7 +362,15 label_in_less_than: dans moins de
362 label_in_more_than: dans plus de
362 label_in_more_than: dans plus de
363 label_in: dans
363 label_in: dans
364 label_today: aujourd'hui
364 label_today: aujourd'hui
365 label_all_time: toute la pΓ©riode
366 label_yesterday: hier
365 label_this_week: cette semaine
367 label_this_week: cette semaine
368 label_last_week: la semaine dernière
369 label_last_n_days: les %d derniers jours
370 label_this_month: ce mois-ci
371 label_last_month: le mois dernier
372 label_this_year: cette annΓ©e
373 label_date_range: PΓ©riode
366 label_less_than_ago: il y a moins de
374 label_less_than_ago: il y a moins de
367 label_more_than_ago: il y a plus de
375 label_more_than_ago: il y a plus de
368 label_ago: il y a
376 label_ago: il y a
@@ -592,3 +592,11 button_configure: Configure
592 label_plugins: Plugins
592 label_plugins: Plugins
593 label_ldap_authentication: LDAP authentication
593 label_ldap_authentication: LDAP authentication
594 label_downloads_abbr: D/L
594 label_downloads_abbr: D/L
595 label_this_month: this month
596 label_last_n_days: last %d days
597 label_all_time: all time
598 label_this_year: this year
599 label_date_range: Date range
600 label_last_week: last week
601 label_yesterday: yesterday
602 label_last_month: last month
@@ -592,3 +592,11 button_configure: Configure
592 label_plugins: Plugins
592 label_plugins: Plugins
593 label_ldap_authentication: LDAP authentication
593 label_ldap_authentication: LDAP authentication
594 label_downloads_abbr: D/L
594 label_downloads_abbr: D/L
595 label_this_month: this month
596 label_last_n_days: last %d days
597 label_all_time: all time
598 label_this_year: this year
599 label_date_range: Date range
600 label_last_week: last week
601 label_yesterday: yesterday
602 label_last_month: last month
@@ -593,3 +593,11 button_configure: Configure
593 label_plugins: Plugins
593 label_plugins: Plugins
594 label_ldap_authentication: LDAP authentication
594 label_ldap_authentication: LDAP authentication
595 label_downloads_abbr: D/L
595 label_downloads_abbr: D/L
596 label_this_month: this month
597 label_last_n_days: last %d days
598 label_all_time: all time
599 label_this_year: this year
600 label_date_range: Date range
601 label_last_week: last week
602 label_yesterday: yesterday
603 label_last_month: last month
@@ -592,3 +592,11 button_configure: Configure
592 label_plugins: Plugins
592 label_plugins: Plugins
593 label_ldap_authentication: LDAP authentication
593 label_ldap_authentication: LDAP authentication
594 label_downloads_abbr: D/L
594 label_downloads_abbr: D/L
595 label_this_month: this month
596 label_last_n_days: last %d days
597 label_all_time: all time
598 label_this_year: this year
599 label_date_range: Date range
600 label_last_week: last week
601 label_yesterday: yesterday
602 label_last_month: last month
@@ -593,3 +593,11 button_configure: Configure
593 label_plugins: Plugins
593 label_plugins: Plugins
594 label_ldap_authentication: LDAP authentication
594 label_ldap_authentication: LDAP authentication
595 label_downloads_abbr: D/L
595 label_downloads_abbr: D/L
596 label_this_month: this month
597 label_last_n_days: last %d days
598 label_all_time: all time
599 label_this_year: this year
600 label_date_range: Date range
601 label_last_week: last week
602 label_yesterday: yesterday
603 label_last_month: last month
@@ -593,3 +593,11 button_configure: Configure
593 label_plugins: Plugins
593 label_plugins: Plugins
594 label_ldap_authentication: LDAP authentication
594 label_ldap_authentication: LDAP authentication
595 label_downloads_abbr: D/L
595 label_downloads_abbr: D/L
596 label_this_month: this month
597 label_last_n_days: last %d days
598 label_all_time: all time
599 label_this_year: this year
600 label_date_range: Date range
601 label_last_week: last week
602 label_yesterday: yesterday
603 label_last_month: last month
@@ -592,3 +592,11 button_configure: Configure
592 label_plugins: Plugins
592 label_plugins: Plugins
593 label_ldap_authentication: LDAP authentication
593 label_ldap_authentication: LDAP authentication
594 label_downloads_abbr: D/L
594 label_downloads_abbr: D/L
595 label_this_month: this month
596 label_last_n_days: last %d days
597 label_all_time: all time
598 label_this_year: this year
599 label_date_range: Date range
600 label_last_week: last week
601 label_yesterday: yesterday
602 label_last_month: last month
@@ -592,3 +592,11 button_configure: Configure
592 label_plugins: Plugins
592 label_plugins: Plugins
593 label_ldap_authentication: LDAP authentication
593 label_ldap_authentication: LDAP authentication
594 label_downloads_abbr: D/L
594 label_downloads_abbr: D/L
595 label_this_month: this month
596 label_last_n_days: last %d days
597 label_all_time: all time
598 label_this_year: this year
599 label_date_range: Date range
600 label_last_week: last week
601 label_yesterday: yesterday
602 label_last_month: last month
@@ -592,3 +592,11 button_configure: Configure
592 label_plugins: Plugins
592 label_plugins: Plugins
593 label_ldap_authentication: LDAP authentication
593 label_ldap_authentication: LDAP authentication
594 label_downloads_abbr: D/L
594 label_downloads_abbr: D/L
595 label_this_month: this month
596 label_last_n_days: last %d days
597 label_all_time: all time
598 label_this_year: this year
599 label_date_range: Date range
600 label_last_week: last week
601 label_yesterday: yesterday
602 label_last_month: last month
@@ -592,3 +592,11 button_configure: Configure
592 label_plugins: Plugins
592 label_plugins: Plugins
593 label_ldap_authentication: LDAP authentication
593 label_ldap_authentication: LDAP authentication
594 label_downloads_abbr: D/L
594 label_downloads_abbr: D/L
595 label_this_month: this month
596 label_last_n_days: last %d days
597 label_all_time: all time
598 label_this_year: this year
599 label_date_range: Date range
600 label_last_week: last week
601 label_yesterday: yesterday
602 label_last_month: last month
@@ -596,3 +596,11 button_configure: Configure
596 label_plugins: Plugins
596 label_plugins: Plugins
597 label_ldap_authentication: LDAP authentication
597 label_ldap_authentication: LDAP authentication
598 label_downloads_abbr: D/L
598 label_downloads_abbr: D/L
599 label_this_month: this month
600 label_last_n_days: last %d days
601 label_all_time: all time
602 label_this_year: this year
603 label_date_range: Date range
604 label_last_week: last week
605 label_yesterday: yesterday
606 label_last_month: last month
@@ -593,3 +593,11 button_configure: Configure
593 label_plugins: Plugins
593 label_plugins: Plugins
594 label_ldap_authentication: LDAP authentication
594 label_ldap_authentication: LDAP authentication
595 label_downloads_abbr: D/L
595 label_downloads_abbr: D/L
596 label_this_month: this month
597 label_last_n_days: last %d days
598 label_all_time: all time
599 label_this_year: this year
600 label_date_range: Date range
601 label_last_week: last week
602 label_yesterday: yesterday
603 label_last_month: last month
@@ -593,3 +593,11 button_configure: Configure
593 label_plugins: Plugins
593 label_plugins: Plugins
594 label_ldap_authentication: LDAP authentication
594 label_ldap_authentication: LDAP authentication
595 label_downloads_abbr: D/L
595 label_downloads_abbr: D/L
596 label_this_month: this month
597 label_last_n_days: last %d days
598 label_all_time: all time
599 label_this_year: this year
600 label_date_range: Date range
601 label_last_week: last week
602 label_yesterday: yesterday
603 label_last_month: last month
@@ -594,3 +594,11 button_configure: Configure
594 label_plugins: Plugins
594 label_plugins: Plugins
595 label_ldap_authentication: LDAP authentication
595 label_ldap_authentication: LDAP authentication
596 label_downloads_abbr: D/L
596 label_downloads_abbr: D/L
597 label_this_month: this month
598 label_last_n_days: last %d days
599 label_all_time: all time
600 label_this_year: this year
601 label_date_range: Date range
602 label_last_week: last week
603 label_yesterday: yesterday
604 label_last_month: last month
@@ -592,3 +592,11 button_configure: Configure
592 label_plugins: Plugins
592 label_plugins: Plugins
593 label_ldap_authentication: LDAP authentication
593 label_ldap_authentication: LDAP authentication
594 label_downloads_abbr: D/L
594 label_downloads_abbr: D/L
595 label_this_month: this month
596 label_last_n_days: last %d days
597 label_all_time: all time
598 label_this_year: this year
599 label_date_range: Date range
600 label_last_week: last week
601 label_yesterday: yesterday
602 label_last_month: last month
@@ -595,3 +595,11 button_configure: Configure
595 label_plugins: Plugins
595 label_plugins: Plugins
596 label_ldap_authentication: LDAP authentication
596 label_ldap_authentication: LDAP authentication
597 label_downloads_abbr: D/L
597 label_downloads_abbr: D/L
598 label_this_month: this month
599 label_last_n_days: last %d days
600 label_all_time: all time
601 label_this_year: this year
602 label_date_range: Date range
603 label_last_week: last week
604 label_yesterday: yesterday
605 label_last_month: last month
@@ -110,6 +110,10 tr.user td { white-space: nowrap; }
110 tr.user.locked, tr.user.registered { color: #aaa; }
110 tr.user.locked, tr.user.registered { color: #aaa; }
111 tr.user.locked a, tr.user.registered a { color: #aaa; }
111 tr.user.locked a, tr.user.registered a { color: #aaa; }
112
112
113 tr.time-entry { text-align: center; white-space: nowrap; }
114 tr.time-entry td.subject, tr.time-entry td.comments { text-align: left; }
115 tr.time-entry td.hours { text-align: right; font-weight: bold; padding-right: 0.6em; }
116
113 table.list tbody tr:hover { background-color:#ffffdd; }
117 table.list tbody tr:hover { background-color:#ffffdd; }
114 table td {padding:2px;}
118 table td {padding:2px;}
115 table p {margin:0;}
119 table p {margin:0;}
@@ -169,6 +173,9 div#roadmap .wiki h1:first-child { display: none; }
169 div#roadmap .wiki h1 { font-size: 120%; }
173 div#roadmap .wiki h1 { font-size: 120%; }
170 div#roadmap .wiki h2 { font-size: 110%; }
174 div#roadmap .wiki h2 { font-size: 110%; }
171
175
176 div.total-hours { text-align: left; font-size: 110%; font-weight: bold; }
177 div.total-hours span.hours-int { font-size: 120%; }
178
172 .autoscroll {overflow-x: auto; padding:1px; width:100%; margin-bottom: 1.2em;}
179 .autoscroll {overflow-x: auto; padding:1px; width:100%; margin-bottom: 1.2em;}
173 #user_firstname, #user_lastname, #user_mail, #my_account_form select { width: 90%; }
180 #user_firstname, #user_lastname, #user_mail, #my_account_form select { width: 90%; }
174
181
@@ -6,7 +6,7 img.calendar-trigger {
6 margin-left: 4px;
6 margin-left: 4px;
7 }
7 }
8
8
9 div.calendar { position: relative; z-index: 15;}
9 div.calendar { position: relative; z-index: 30;}
10
10
11 .calendar, .calendar table {
11 .calendar, .calendar table {
12 border: 1px solid #556;
12 border: 1px solid #556;
@@ -21,7 +21,7 time_entries_002:
21 comments: ""
21 comments: ""
22 updated_on: 2007-03-23 14:11:04 +01:00
22 updated_on: 2007-03-23 14:11:04 +01:00
23 activity_id: 8
23 activity_id: 8
24 spent_on: 2007-03-23
24 spent_on: 2007-03-12
25 issue_id: 1
25 issue_id: 1
26 id: 2
26 id: 2
27 hours: 150.0
27 hours: 150.0
@@ -22,7 +22,7 require 'timelog_controller'
22 class TimelogController; def rescue_action(e) raise e end; end
22 class TimelogController; def rescue_action(e) raise e end; end
23
23
24 class TimelogControllerTest < Test::Unit::TestCase
24 class TimelogControllerTest < Test::Unit::TestCase
25 fixtures :time_entries, :issues
25 fixtures :projects, :issues, :time_entries, :users, :trackers, :enumerations, :issue_statuses
26
26
27 def setup
27 def setup
28 @controller = TimelogController.new
28 @controller = TimelogController.new
@@ -49,4 +49,52 class TimelogControllerTest < Test::Unit::TestCase
49 assert_template 'report'
49 assert_template 'report'
50 assert_not_nil assigns(:hours)
50 assert_not_nil assigns(:hours)
51 end
51 end
52
53 def test_details_at_project_level
54 get :details, :project_id => 1
55 assert_response :success
56 assert_template 'details'
57 assert_not_nil assigns(:entries)
58 assert_equal 3, assigns(:entries).size
59 assert_not_nil assigns(:total_hours)
60 assert_equal 155.25, assigns(:total_hours)
61 # display all time by default
62 assert_nil assigns(:from)
63 assert_nil assigns(:to)
64 end
65
66 def test_details_at_project_level_with_date_range
67 get :details, :project_id => 1, :from => '2007-03-20', :to => '2007-04-30'
68 assert_response :success
69 assert_template 'details'
70 assert_not_nil assigns(:entries)
71 assert_equal 2, assigns(:entries).size
72 assert_not_nil assigns(:total_hours)
73 assert_equal 5.25, assigns(:total_hours)
74 assert_equal '2007-03-20'.to_date, assigns(:from)
75 assert_equal '2007-04-30'.to_date, assigns(:to)
76 end
77
78 def test_details_at_project_level_with_period
79 get :details, :project_id => 1, :period => '7_days'
80 assert_response :success
81 assert_template 'details'
82 assert_not_nil assigns(:entries)
83 assert_not_nil assigns(:total_hours)
84 assert_equal Date.today - 7, assigns(:from)
85 assert_equal Date.today, assigns(:to)
86 end
87
88 def test_details_at_issue_level
89 get :details, :issue_id => 1
90 assert_response :success
91 assert_template 'details'
92 assert_not_nil assigns(:entries)
93 assert_equal 2, assigns(:entries).size
94 assert_not_nil assigns(:total_hours)
95 assert_equal 154.25, assigns(:total_hours)
96 # display all time by default
97 assert_nil assigns(:from)
98 assert_nil assigns(:to)
99 end
52 end
100 end
General Comments 0
You need to be logged in to leave comments. Login now