@@ -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 |
|
|
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. |
|
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: |
|
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-2 |
|
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