##// END OF EJS Templates
Changed timelogs filters to use non-AJAX requests (#1965)....
Jean-Philippe Lang -
r5177:b0ade644d60c
parent child
Show More
@@ -1,76 +1,73
1 1 <div class="contextual">
2 2 <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'new', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time-add' %>
3 3 </div>
4 4
5 5 <%= render_timelog_breadcrumb %>
6 6
7 7 <h2><%= l(:label_spent_time) %></h2>
8 8
9 <% form_remote_tag(:url => {}, :html => {:method => :get, :id => 'query_form'}, :method => :get, :update => 'content') do %>
9 <% form_tag({:controller => 'time_entry_reports', :action => 'report', :project_id => @project, :issue_id => @issue}, :method => :get, :id => 'query_form') do %>
10 10 <% @criterias.each do |criteria| %>
11 11 <%= hidden_field_tag 'criterias[]', criteria, :id => nil %>
12 12 <% end %>
13 13 <%# TODO: get rid of the project_id field, that should already be in the URL %>
14 14 <%= hidden_field_tag('project_id', params[:project_id]) if @project %>
15 15 <%= hidden_field_tag('issue_id', params[:issue_id]) if @issue %>
16 16 <%= render :partial => 'timelog/date_range' %>
17 17
18 18 <p><%= l(:label_details) %>: <%= select_tag 'columns', options_for_select([[l(:label_year), 'year'],
19 19 [l(:label_month), 'month'],
20 20 [l(:label_week), 'week'],
21 21 [l(:label_day_plural).titleize, 'day']], @columns),
22 22 :onchange => "this.form.onsubmit();" %>
23 23
24 24 <%= l(:button_add) %>: <%= select_tag('criterias[]', options_for_select([[]] + (@available_criterias.keys - @criterias).collect{|k| [l_or_humanize(@available_criterias[k][:label]), k]}),
25 :onchange => "this.form.onsubmit();",
25 :onchange => "this.form.submit();",
26 26 :style => 'width: 200px',
27 27 :id => nil,
28 28 :disabled => (@criterias.length >= 3)) %>
29 <%= link_to_remote l(:button_clear), {:url => {:project_id => @project, :period_type => params[:period_type], :period => params[:period], :from => @from, :to => @to, :columns => @columns},
30 :method => :get,
31 :update => 'content'
32 }, :class => 'icon icon-reload' %></p>
29 <%= link_to l(:button_clear), {:project_id => @project, :issue_id => @issue, :period_type => params[:period_type], :period => params[:period], :from => @from, :to => @to, :columns => @columns}, :class => 'icon icon-reload' %></p>
33 30 <% end %>
34 31
35 32 <% unless @criterias.empty? %>
36 33 <div class="total-hours">
37 34 <p><%= l(:label_total) %>: <%= html_hours(l_hours(@total_hours)) %></p>
38 35 </div>
39 36
40 37 <% unless @hours.empty? %>
41 38 <table class="list" id="time-report">
42 39 <thead>
43 40 <tr>
44 41 <% @criterias.each do |criteria| %>
45 42 <th><%= l_or_humanize(@available_criterias[criteria][:label]) %></th>
46 43 <% end %>
47 44 <% columns_width = (40 / (@periods.length+1)).to_i %>
48 45 <% @periods.each do |period| %>
49 46 <th class="period" width="<%= columns_width %>%"><%= period %></th>
50 47 <% end %>
51 48 <th class="total" width="<%= columns_width %>%"><%= l(:label_total) %></th>
52 49 </tr>
53 50 </thead>
54 51 <tbody>
55 52 <%= render :partial => 'report_criteria', :locals => {:criterias => @criterias, :hours => @hours, :level => 0} %>
56 53 <tr class="total">
57 54 <td><%= l(:label_total) %></td>
58 55 <%= '<td></td>' * (@criterias.size - 1) %>
59 56 <% total = 0 -%>
60 57 <% @periods.each do |period| -%>
61 58 <% sum = sum_hours(select_hours(@hours, @columns, period.to_s)); total += sum -%>
62 59 <td class="hours"><%= html_hours("%.2f" % sum) if sum > 0 %></td>
63 60 <% end -%>
64 61 <td class="hours"><%= html_hours("%.2f" % total) if total > 0 %></td>
65 62 </tr>
66 63 </tbody>
67 64 </table>
68 65
69 66 <% other_formats_links do |f| %>
70 67 <%= f.link_to 'CSV', :url => params %>
71 68 <% end %>
72 69 <% end %>
73 70 <% end %>
74 71
75 72 <% html_title l(:label_spent_time), l(:label_report) %>
76 73
@@ -1,36 +1,32
1 1 <fieldset id="date-range" class="collapsible">
2 2 <legend onclick="toggleFieldset(this);"><%= l(:label_date_range) %></legend>
3 3 <div>
4 4 <p>
5 5 <%= radio_button_tag 'period_type', '1', !@free_period %>
6 6 <%= select_tag 'period', options_for_period_select(params[:period]),
7 :onchange => 'this.form.onsubmit();',
7 :onchange => 'this.form.submit();',
8 8 :onfocus => '$("period_type_1").checked = true;' %>
9 9 </p>
10 10 <p>
11 11 <%= radio_button_tag 'period_type', '2', @free_period %>
12 12 <span onclick="$('period_type_2').checked = true;">
13 13 <%= l(:label_date_from_to, :start => (text_field_tag('from', @from, :size => 10) + calendar_for('from')),
14 14 :end => (text_field_tag('to', @to, :size => 10) + calendar_for('to'))) %>
15 15 </span>
16 16 </p>
17 17 </div>
18 18 </fieldset>
19 19 <p class="buttons">
20 <%= link_to_remote l(:button_apply),
21 { :url => { },
22 :update => "content",
23 :with => "Form.serialize('query_form')",
24 :method => :get
25 }, :class => 'icon icon-checked' %>
20 <%= link_to_function l(:button_apply), '$("query_form").submit()', :class => 'icon icon-checked' %>
21 <%= link_to l(:button_clear), {:controller => controller_name, :action => action_name, :project_id => @project, :issue_id => @issue}, :class => 'icon icon-reload' %>
26 22 </p>
27 23
28 24 <div class="tabs">
29 25 <% url_params = @free_period ? { :from => @from, :to => @to } : { :period => params[:period] } %>
30 26 <ul>
31 27 <li><%= link_to(l(:label_details), url_params.merge({:controller => 'timelog', :action => 'index', :project_id => @project, :issue_id => @issue }),
32 28 :class => (@controller.action_name == 'index' ? 'selected' : nil)) %></li>
33 29 <li><%= link_to(l(:label_report), url_params.merge({:controller => 'time_entry_reports', :action => 'report', :project_id => @project, :issue_id => @issue}),
34 30 :class => (@controller.action_name == 'report' ? 'selected' : nil)) %></li>
35 31 </ul>
36 32 </div>
@@ -1,35 +1,31
1 1 <div class="contextual">
2 2 <%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'new', :project_id => @project, :issue_id => @issue}, :class => 'icon icon-time-add' %>
3 3 </div>
4 4
5 5 <%= render_timelog_breadcrumb %>
6 6
7 7 <h2><%= l(:label_spent_time) %></h2>
8 8
9 <% form_remote_tag( :url => {}, :html => {:method => :get, :id => 'query_form'}, :method => :get, :update => 'content' ) do %>
10 <%# TOOD: remove the project_id and issue_id hidden fields, that information is
11 already in the URI %>
12 <%= hidden_field_tag('project_id', params[:project_id]) if @project %>
13 <%= hidden_field_tag 'issue_id', params[:issue_id] if @issue %>
9 <% form_tag({:controller => 'timelog', :action => 'index', :project_id => @project, :issue_id => @issue}, :method => :get, :id => 'query_form') do %>
14 10 <%= render :partial => 'date_range' %>
15 11 <% end %>
16 12
17 13 <div class="total-hours">
18 14 <p><%= l(:label_total) %>: <%= html_hours(l_hours(@total_hours)) %></p>
19 15 </div>
20 16
21 17 <% unless @entries.empty? %>
22 18 <%= render :partial => 'list', :locals => { :entries => @entries }%>
23 19 <p class="pagination"><%= pagination_links_full @entry_pages, @entry_count %></p>
24 20
25 21 <% other_formats_links do |f| %>
26 22 <%= f.link_to 'Atom', :url => params.merge({:issue_id => @issue, :key => User.current.rss_key}) %>
27 23 <%= f.link_to 'CSV', :url => params %>
28 24 <% end %>
29 25 <% end %>
30 26
31 27 <% html_title l(:label_spent_time), l(:label_details) %>
32 28
33 29 <% content_for :header_tags do %>
34 30 <%= auto_discovery_link_tag(:atom, {:issue_id => @issue, :format => 'atom', :key => User.current.rss_key}, :title => l(:label_spent_time)) %>
35 31 <% end %>
@@ -1,252 +1,253
1 1 ActionController::Routing::Routes.draw do |map|
2 2 # Add your own custom routes here.
3 3 # The priority is based upon order of creation: first created -> highest priority.
4 4
5 5 # Here's a sample route:
6 6 # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
7 7 # Keep in mind you can assign values other than :controller and :action
8 8
9 9 map.home '', :controller => 'welcome'
10 10
11 11 map.signin 'login', :controller => 'account', :action => 'login'
12 12 map.signout 'logout', :controller => 'account', :action => 'logout'
13 13
14 14 map.connect 'roles/workflow/:id/:role_id/:tracker_id', :controller => 'roles', :action => 'workflow'
15 15 map.connect 'help/:ctrl/:page', :controller => 'help'
16 16
17 map.connect 'projects/:project_id/time_entries/report', :controller => 'time_entry_reports', :action => 'report'
18 17 map.with_options :controller => 'time_entry_reports', :action => 'report',:conditions => {:method => :get} do |time_report|
18 time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report'
19 time_report.connect 'projects/:project_id/issues/:issue_id/time_entries/report.:format'
20 time_report.connect 'projects/:project_id/time_entries/report'
21 time_report.connect 'projects/:project_id/time_entries/report.:format'
19 22 time_report.connect 'time_entries/report'
20 23 time_report.connect 'time_entries/report.:format'
21 time_report.connect 'projects/:project_id/time_entries/report.:format'
22 24 end
23 25
24 # TODO: wasteful since this is also nested under issues, projects, and projects/issues
25 26 map.resources :time_entries, :controller => 'timelog'
26 27
27 28 map.connect 'projects/:id/wiki', :controller => 'wikis', :action => 'edit', :conditions => {:method => :post}
28 29 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :get}
29 30 map.connect 'projects/:id/wiki/destroy', :controller => 'wikis', :action => 'destroy', :conditions => {:method => :post}
30 31
31 32 map.with_options :controller => 'messages' do |messages_routes|
32 33 messages_routes.with_options :conditions => {:method => :get} do |messages_views|
33 34 messages_views.connect 'boards/:board_id/topics/new', :action => 'new'
34 35 messages_views.connect 'boards/:board_id/topics/:id', :action => 'show'
35 36 messages_views.connect 'boards/:board_id/topics/:id/edit', :action => 'edit'
36 37 end
37 38 messages_routes.with_options :conditions => {:method => :post} do |messages_actions|
38 39 messages_actions.connect 'boards/:board_id/topics/new', :action => 'new'
39 40 messages_actions.connect 'boards/:board_id/topics/:id/replies', :action => 'reply'
40 41 messages_actions.connect 'boards/:board_id/topics/:id/:action', :action => /edit|destroy/
41 42 end
42 43 end
43 44
44 45 map.with_options :controller => 'boards' do |board_routes|
45 46 board_routes.with_options :conditions => {:method => :get} do |board_views|
46 47 board_views.connect 'projects/:project_id/boards', :action => 'index'
47 48 board_views.connect 'projects/:project_id/boards/new', :action => 'new'
48 49 board_views.connect 'projects/:project_id/boards/:id', :action => 'show'
49 50 board_views.connect 'projects/:project_id/boards/:id.:format', :action => 'show'
50 51 board_views.connect 'projects/:project_id/boards/:id/edit', :action => 'edit'
51 52 end
52 53 board_routes.with_options :conditions => {:method => :post} do |board_actions|
53 54 board_actions.connect 'projects/:project_id/boards', :action => 'new'
54 55 board_actions.connect 'projects/:project_id/boards/:id/:action', :action => /edit|destroy/
55 56 end
56 57 end
57 58
58 59 map.with_options :controller => 'documents' do |document_routes|
59 60 document_routes.with_options :conditions => {:method => :get} do |document_views|
60 61 document_views.connect 'projects/:project_id/documents', :action => 'index'
61 62 document_views.connect 'projects/:project_id/documents/new', :action => 'new'
62 63 document_views.connect 'documents/:id', :action => 'show'
63 64 document_views.connect 'documents/:id/edit', :action => 'edit'
64 65 end
65 66 document_routes.with_options :conditions => {:method => :post} do |document_actions|
66 67 document_actions.connect 'projects/:project_id/documents', :action => 'new'
67 68 document_actions.connect 'documents/:id/:action', :action => /destroy|edit/
68 69 end
69 70 end
70 71
71 72 map.resources :issue_moves, :only => [:new, :create], :path_prefix => '/issues', :as => 'move'
72 73
73 74 # Misc issue routes. TODO: move into resources
74 75 map.auto_complete_issues '/issues/auto_complete', :controller => 'auto_completes', :action => 'issues'
75 76 map.preview_issue '/issues/preview/:id', :controller => 'previews', :action => 'issue' # TODO: would look nicer as /issues/:id/preview
76 77 map.issues_context_menu '/issues/context_menu', :controller => 'context_menus', :action => 'issues'
77 78 map.issue_changes '/issues/changes', :controller => 'journals', :action => 'index'
78 79 map.bulk_edit_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_edit', :conditions => { :method => :get }
79 80 map.bulk_update_issue 'issues/bulk_edit', :controller => 'issues', :action => 'bulk_update', :conditions => { :method => :post }
80 81 map.quoted_issue '/issues/:id/quoted', :controller => 'journals', :action => 'new', :id => /\d+/, :conditions => { :method => :post }
81 82 map.connect '/issues/:id/destroy', :controller => 'issues', :action => 'destroy', :conditions => { :method => :post } # legacy
82 83
83 84 map.with_options :controller => 'gantts', :action => 'show' do |gantts_routes|
84 85 gantts_routes.connect '/projects/:project_id/issues/gantt'
85 86 gantts_routes.connect '/projects/:project_id/issues/gantt.:format'
86 87 gantts_routes.connect '/issues/gantt.:format'
87 88 end
88 89
89 90 map.with_options :controller => 'calendars', :action => 'show' do |calendars_routes|
90 91 calendars_routes.connect '/projects/:project_id/issues/calendar'
91 92 calendars_routes.connect '/issues/calendar'
92 93 end
93 94
94 95 map.with_options :controller => 'reports', :conditions => {:method => :get} do |reports|
95 96 reports.connect 'projects/:id/issues/report', :action => 'issue_report'
96 97 reports.connect 'projects/:id/issues/report/:detail', :action => 'issue_report_details'
97 98 end
98 99
99 100 # Following two routes conflict with the resources because #index allows POST
100 101 map.connect '/issues', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
101 102 map.connect '/issues/create', :controller => 'issues', :action => 'index', :conditions => { :method => :post }
102 103
103 104 map.resources :issues, :member => { :edit => :post }, :collection => {} do |issues|
104 105 issues.resources :time_entries, :controller => 'timelog'
105 106 end
106 107
107 108 map.resources :issues, :path_prefix => '/projects/:project_id', :collection => { :create => :post } do |issues|
108 109 issues.resources :time_entries, :controller => 'timelog'
109 110 end
110 111
111 112 map.with_options :controller => 'issue_relations', :conditions => {:method => :post} do |relations|
112 113 relations.connect 'issues/:issue_id/relations/:id', :action => 'new'
113 114 relations.connect 'issues/:issue_id/relations/:id/destroy', :action => 'destroy'
114 115 end
115 116
116 117 map.connect 'projects/:id/members/new', :controller => 'members', :action => 'new'
117 118
118 119 map.with_options :controller => 'users' do |users|
119 120 users.connect 'users/:id/edit/:tab', :action => 'edit', :tab => nil, :conditions => {:method => :get}
120 121
121 122 users.with_options :conditions => {:method => :post} do |user_actions|
122 123 user_actions.connect 'users/:id/memberships', :action => 'edit_membership'
123 124 user_actions.connect 'users/:id/memberships/:membership_id', :action => 'edit_membership'
124 125 user_actions.connect 'users/:id/memberships/:membership_id/destroy', :action => 'destroy_membership'
125 126 end
126 127 end
127 128
128 129 map.resources :users, :member => {
129 130 :edit_membership => :post,
130 131 :destroy_membership => :post
131 132 }
132 133
133 134 # For nice "roadmap" in the url for the index action
134 135 map.connect 'projects/:project_id/roadmap', :controller => 'versions', :action => 'index'
135 136
136 137 map.all_news 'news', :controller => 'news', :action => 'index'
137 138 map.formatted_all_news 'news.:format', :controller => 'news', :action => 'index'
138 139 map.preview_news '/news/preview', :controller => 'previews', :action => 'news'
139 140 map.connect 'news/:id/comments', :controller => 'comments', :action => 'create', :conditions => {:method => :post}
140 141 map.connect 'news/:id/comments/:comment_id', :controller => 'comments', :action => 'destroy', :conditions => {:method => :delete}
141 142
142 143 map.resources :projects, :member => {
143 144 :copy => [:get, :post],
144 145 :settings => :get,
145 146 :modules => :post,
146 147 :archive => :post,
147 148 :unarchive => :post
148 149 } do |project|
149 150 project.resource :project_enumerations, :as => 'enumerations', :only => [:update, :destroy]
150 151 project.resources :files, :only => [:index, :new, :create]
151 152 project.resources :versions, :collection => {:close_completed => :put}, :member => {:status_by => :post}
152 153 project.resources :news, :shallow => true
153 154 project.resources :time_entries, :controller => 'timelog', :path_prefix => 'projects/:project_id'
154 155
155 156 project.wiki_start_page 'wiki', :controller => 'wiki', :action => 'show', :conditions => {:method => :get}
156 157 project.wiki_index 'wiki/index', :controller => 'wiki', :action => 'index', :conditions => {:method => :get}
157 158 project.wiki_diff 'wiki/:id/diff/:version', :controller => 'wiki', :action => 'diff', :version => nil
158 159 project.wiki_diff 'wiki/:id/diff/:version/vs/:version_from', :controller => 'wiki', :action => 'diff'
159 160 project.wiki_annotate 'wiki/:id/annotate/:version', :controller => 'wiki', :action => 'annotate'
160 161 project.resources :wiki, :except => [:new, :create], :member => {
161 162 :rename => [:get, :post],
162 163 :history => :get,
163 164 :preview => :any,
164 165 :protect => :post,
165 166 :add_attachment => :post
166 167 }, :collection => {
167 168 :export => :get,
168 169 :date_index => :get
169 170 }
170 171
171 172 end
172 173
173 174 # Destroy uses a get request to prompt the user before the actual DELETE request
174 175 map.project_destroy_confirm 'projects/:id/destroy', :controller => 'projects', :action => 'destroy', :conditions => {:method => :get}
175 176
176 177 # TODO: port to be part of the resources route(s)
177 178 map.with_options :controller => 'projects' do |project_mapper|
178 179 project_mapper.with_options :conditions => {:method => :get} do |project_views|
179 180 project_views.connect 'projects/:id/settings/:tab', :controller => 'projects', :action => 'settings'
180 181 project_views.connect 'projects/:project_id/issues/:copy_from/copy', :controller => 'issues', :action => 'new'
181 182 end
182 183 end
183 184
184 185 map.with_options :controller => 'activities', :action => 'index', :conditions => {:method => :get} do |activity|
185 186 activity.connect 'projects/:id/activity'
186 187 activity.connect 'projects/:id/activity.:format'
187 188 activity.connect 'activity', :id => nil
188 189 activity.connect 'activity.:format', :id => nil
189 190 end
190 191
191 192
192 193 map.with_options :controller => 'issue_categories' do |categories|
193 194 categories.connect 'projects/:project_id/issue_categories/new', :action => 'new'
194 195 end
195 196
196 197 map.with_options :controller => 'repositories' do |repositories|
197 198 repositories.with_options :conditions => {:method => :get} do |repository_views|
198 199 repository_views.connect 'projects/:id/repository', :action => 'show'
199 200 repository_views.connect 'projects/:id/repository/edit', :action => 'edit'
200 201 repository_views.connect 'projects/:id/repository/statistics', :action => 'stats'
201 202 repository_views.connect 'projects/:id/repository/revisions', :action => 'revisions'
202 203 repository_views.connect 'projects/:id/repository/revisions.:format', :action => 'revisions'
203 204 repository_views.connect 'projects/:id/repository/revisions/:rev', :action => 'revision'
204 205 repository_views.connect 'projects/:id/repository/revisions/:rev/diff', :action => 'diff'
205 206 repository_views.connect 'projects/:id/repository/revisions/:rev/diff.:format', :action => 'diff'
206 207 repository_views.connect 'projects/:id/repository/revisions/:rev/raw/*path', :action => 'entry', :format => 'raw', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
207 208 repository_views.connect 'projects/:id/repository/revisions/:rev/:action/*path', :requirements => { :rev => /[a-z0-9\.\-_]+/ }
208 209 repository_views.connect 'projects/:id/repository/raw/*path', :action => 'entry', :format => 'raw'
209 210 # TODO: why the following route is required?
210 211 repository_views.connect 'projects/:id/repository/entry/*path', :action => 'entry'
211 212 repository_views.connect 'projects/:id/repository/:action/*path'
212 213 end
213 214
214 215 repositories.connect 'projects/:id/repository/:action', :conditions => {:method => :post}
215 216 end
216 217
217 218 map.connect 'attachments/:id', :controller => 'attachments', :action => 'show', :id => /\d+/
218 219 map.connect 'attachments/:id/:filename', :controller => 'attachments', :action => 'show', :id => /\d+/, :filename => /.*/
219 220 map.connect 'attachments/download/:id/:filename', :controller => 'attachments', :action => 'download', :id => /\d+/, :filename => /.*/
220 221
221 222 map.resources :groups
222 223
223 224 #left old routes at the bottom for backwards compat
224 225 map.connect 'projects/:project_id/queries/:action', :controller => 'queries'
225 226 map.connect 'projects/:project_id/issues/:action', :controller => 'issues'
226 227 map.connect 'projects/:project_id/documents/:action', :controller => 'documents'
227 228 map.connect 'projects/:project_id/boards/:action/:id', :controller => 'boards'
228 229 map.connect 'boards/:board_id/topics/:action/:id', :controller => 'messages'
229 230 map.connect 'wiki/:id/:page/:action', :page => nil, :controller => 'wiki'
230 231 map.connect 'issues/:issue_id/relations/:action/:id', :controller => 'issue_relations'
231 232 map.connect 'projects/:project_id/news/:action', :controller => 'news'
232 233 map.connect 'projects/:project_id/timelog/:action/:id', :controller => 'timelog', :project_id => /.+/
233 234 map.with_options :controller => 'repositories' do |omap|
234 235 omap.repositories_show 'repositories/browse/:id/*path', :action => 'browse'
235 236 omap.repositories_changes 'repositories/changes/:id/*path', :action => 'changes'
236 237 omap.repositories_diff 'repositories/diff/:id/*path', :action => 'diff'
237 238 omap.repositories_entry 'repositories/entry/:id/*path', :action => 'entry'
238 239 omap.repositories_entry 'repositories/annotate/:id/*path', :action => 'annotate'
239 240 omap.connect 'repositories/revision/:id/:rev', :action => 'revision'
240 241 end
241 242
242 243 map.with_options :controller => 'sys' do |sys|
243 244 sys.connect 'sys/projects.:format', :action => 'projects', :conditions => {:method => :get}
244 245 sys.connect 'sys/projects/:id/repository.:format', :action => 'create_project_repository', :conditions => {:method => :post}
245 246 end
246 247
247 248 # Install the default route as the lowest priority.
248 249 map.connect ':controller/:action/:id'
249 250 map.connect 'robots.txt', :controller => 'welcome', :action => 'robots'
250 251 # Used for OpenID
251 252 map.root :controller => 'account', :action => 'login'
252 253 end
@@ -1,134 +1,140
1 1 # -*- coding: utf-8 -*-
2 2 require File.expand_path('../../test_helper', __FILE__)
3 3
4 4 class TimeEntryReportsControllerTest < ActionController::TestCase
5 5 fixtures :projects, :enabled_modules, :roles, :members, :member_roles, :issues, :time_entries, :users, :trackers, :enumerations, :issue_statuses, :custom_fields, :custom_values
6 6
7 def test_report_no_criteria
8 get :report, :project_id => 1
7 def test_report_at_project_level
8 get :report, :project_id => 'ecookbook'
9 9 assert_response :success
10 10 assert_template 'report'
11 assert_tag :form,
12 :attributes => {:action => "/projects/ecookbook/time_entries/report", :id => 'query_form'}
11 13 end
12 14
13 15 def test_report_all_projects
14 16 get :report
15 17 assert_response :success
16 18 assert_template 'report'
19 assert_tag :form,
20 :attributes => {:action => "/time_entries/report", :id => 'query_form'}
17 21 end
18 22
19 23 def test_report_all_projects_denied
20 24 r = Role.anonymous
21 25 r.permissions.delete(:view_time_entries)
22 26 r.permissions_will_change!
23 27 r.save
24 28 get :report
25 29 assert_redirected_to '/login?back_url=http%3A%2F%2Ftest.host%2Ftime_entries%2Freport'
26 30 end
27 31
28 32 def test_report_all_projects_one_criteria
29 33 get :report, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criterias => ['project']
30 34 assert_response :success
31 35 assert_template 'report'
32 36 assert_not_nil assigns(:total_hours)
33 37 assert_equal "8.65", "%.2f" % assigns(:total_hours)
34 38 end
35 39
36 40 def test_report_all_time
37 41 get :report, :project_id => 1, :criterias => ['project', 'issue']
38 42 assert_response :success
39 43 assert_template 'report'
40 44 assert_not_nil assigns(:total_hours)
41 45 assert_equal "162.90", "%.2f" % assigns(:total_hours)
42 46 end
43 47
44 48 def test_report_all_time_by_day
45 49 get :report, :project_id => 1, :criterias => ['project', 'issue'], :columns => 'day'
46 50 assert_response :success
47 51 assert_template 'report'
48 52 assert_not_nil assigns(:total_hours)
49 53 assert_equal "162.90", "%.2f" % assigns(:total_hours)
50 54 assert_tag :tag => 'th', :content => '2007-03-12'
51 55 end
52 56
53 57 def test_report_one_criteria
54 58 get :report, :project_id => 1, :columns => 'week', :from => "2007-04-01", :to => "2007-04-30", :criterias => ['project']
55 59 assert_response :success
56 60 assert_template 'report'
57 61 assert_not_nil assigns(:total_hours)
58 62 assert_equal "8.65", "%.2f" % assigns(:total_hours)
59 63 end
60 64
61 65 def test_report_two_criterias
62 66 get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criterias => ["member", "activity"]
63 67 assert_response :success
64 68 assert_template 'report'
65 69 assert_not_nil assigns(:total_hours)
66 70 assert_equal "162.90", "%.2f" % assigns(:total_hours)
67 71 end
68 72
69 73 def test_report_one_day
70 74 get :report, :project_id => 1, :columns => 'day', :from => "2007-03-23", :to => "2007-03-23", :criterias => ["member", "activity"]
71 75 assert_response :success
72 76 assert_template 'report'
73 77 assert_not_nil assigns(:total_hours)
74 78 assert_equal "4.25", "%.2f" % assigns(:total_hours)
75 79 end
76 80
77 81 def test_report_at_issue_level
78 82 get :report, :project_id => 1, :issue_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-12-31", :criterias => ["member", "activity"]
79 83 assert_response :success
80 84 assert_template 'report'
81 85 assert_not_nil assigns(:total_hours)
82 86 assert_equal "154.25", "%.2f" % assigns(:total_hours)
87 assert_tag :form,
88 :attributes => {:action => "/projects/ecookbook/issues/1/time_entries/report", :id => 'query_form'}
83 89 end
84 90
85 91 def test_report_custom_field_criteria
86 92 get :report, :project_id => 1, :criterias => ['project', 'cf_1', 'cf_7']
87 93 assert_response :success
88 94 assert_template 'report'
89 95 assert_not_nil assigns(:total_hours)
90 96 assert_not_nil assigns(:criterias)
91 97 assert_equal 3, assigns(:criterias).size
92 98 assert_equal "162.90", "%.2f" % assigns(:total_hours)
93 99 # Custom field column
94 100 assert_tag :tag => 'th', :content => 'Database'
95 101 # Custom field row
96 102 assert_tag :tag => 'td', :content => 'MySQL',
97 103 :sibling => { :tag => 'td', :attributes => { :class => 'hours' },
98 104 :child => { :tag => 'span', :attributes => { :class => 'hours hours-int' },
99 105 :content => '1' }}
100 106 # Second custom field column
101 107 assert_tag :tag => 'th', :content => 'Billable'
102 108 end
103 109
104 110 def test_report_one_criteria_no_result
105 111 get :report, :project_id => 1, :columns => 'week', :from => "1998-04-01", :to => "1998-04-30", :criterias => ['project']
106 112 assert_response :success
107 113 assert_template 'report'
108 114 assert_not_nil assigns(:total_hours)
109 115 assert_equal "0.00", "%.2f" % assigns(:total_hours)
110 116 end
111 117
112 118 def test_report_all_projects_csv_export
113 119 get :report, :columns => 'month', :from => "2007-01-01", :to => "2007-06-30", :criterias => ["project", "member", "activity"], :format => "csv"
114 120 assert_response :success
115 121 assert_equal 'text/csv', @response.content_type
116 122 lines = @response.body.chomp.split("\n")
117 123 # Headers
118 124 assert_equal 'Project,Member,Activity,2007-1,2007-2,2007-3,2007-4,2007-5,2007-6,Total', lines.first
119 125 # Total row
120 126 assert_equal 'Total,"","","","",154.25,8.65,"","",162.90', lines.last
121 127 end
122 128
123 129 def test_report_csv_export
124 130 get :report, :project_id => 1, :columns => 'month', :from => "2007-01-01", :to => "2007-06-30", :criterias => ["project", "member", "activity"], :format => "csv"
125 131 assert_response :success
126 132 assert_equal 'text/csv', @response.content_type
127 133 lines = @response.body.chomp.split("\n")
128 134 # Headers
129 135 assert_equal 'Project,Member,Activity,2007-1,2007-2,2007-3,2007-4,2007-5,2007-6,Total', lines.first
130 136 # Total row
131 137 assert_equal 'Total,"","","","",154.25,8.65,"","",162.90', lines.last
132 138 end
133 139
134 140 end
@@ -1,251 +1,265
1 1 # -*- coding: utf-8 -*-
2 2 # redMine - project management software
3 3 # Copyright (C) 2006-2007 Jean-Philippe Lang
4 4 #
5 5 # This program is free software; you can redistribute it and/or
6 6 # modify it under the terms of the GNU General Public License
7 7 # as published by the Free Software Foundation; either version 2
8 8 # of the License, or (at your option) any later version.
9 9 #
10 10 # This program is distributed in the hope that it will be useful,
11 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 # GNU General Public License for more details.
14 14 #
15 15 # You should have received a copy of the GNU General Public License
16 16 # along with this program; if not, write to the Free Software
17 17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 18
19 19 require File.expand_path('../../test_helper', __FILE__)
20 20 require 'timelog_controller'
21 21
22 22 # Re-raise errors caught by the controller.
23 23 class TimelogController; def rescue_action(e) raise e end; end
24 24
25 25 class TimelogControllerTest < ActionController::TestCase
26 26 fixtures :projects, :enabled_modules, :roles, :members, :member_roles, :issues, :time_entries, :users, :trackers, :enumerations, :issue_statuses, :custom_fields, :custom_values
27 27
28 28 def setup
29 29 @controller = TimelogController.new
30 30 @request = ActionController::TestRequest.new
31 31 @response = ActionController::TestResponse.new
32 32 end
33 33
34 34 def test_get_new
35 35 @request.session[:user_id] = 3
36 36 get :new, :project_id => 1
37 37 assert_response :success
38 38 assert_template 'edit'
39 39 # Default activity selected
40 40 assert_tag :tag => 'option', :attributes => { :selected => 'selected' },
41 41 :content => 'Development'
42 42 end
43 43
44 44 def test_get_new_should_only_show_active_time_entry_activities
45 45 @request.session[:user_id] = 3
46 46 get :new, :project_id => 1
47 47 assert_response :success
48 48 assert_template 'edit'
49 49 assert_no_tag :tag => 'option', :content => 'Inactive Activity'
50 50
51 51 end
52 52
53 53 def test_get_edit_existing_time
54 54 @request.session[:user_id] = 2
55 55 get :edit, :id => 2, :project_id => nil
56 56 assert_response :success
57 57 assert_template 'edit'
58 58 # Default activity selected
59 59 assert_tag :tag => 'form', :attributes => { :action => '/projects/ecookbook/time_entries/2' }
60 60 end
61 61
62 62 def test_get_edit_with_an_existing_time_entry_with_inactive_activity
63 63 te = TimeEntry.find(1)
64 64 te.activity = TimeEntryActivity.find_by_name("Inactive Activity")
65 65 te.save!
66 66
67 67 @request.session[:user_id] = 1
68 68 get :edit, :project_id => 1, :id => 1
69 69 assert_response :success
70 70 assert_template 'edit'
71 71 # Blank option since nothing is pre-selected
72 72 assert_tag :tag => 'option', :content => '--- Please select ---'
73 73 end
74 74
75 75 def test_post_create
76 76 # TODO: should POST to issues’ time log instead of project. change form
77 77 # and routing
78 78 @request.session[:user_id] = 3
79 79 post :create, :project_id => 1,
80 80 :time_entry => {:comments => 'Some work on TimelogControllerTest',
81 81 # Not the default activity
82 82 :activity_id => '11',
83 83 :spent_on => '2008-03-14',
84 84 :issue_id => '1',
85 85 :hours => '7.3'}
86 86 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
87 87
88 88 i = Issue.find(1)
89 89 t = TimeEntry.find_by_comments('Some work on TimelogControllerTest')
90 90 assert_not_nil t
91 91 assert_equal 11, t.activity_id
92 92 assert_equal 7.3, t.hours
93 93 assert_equal 3, t.user_id
94 94 assert_equal i, t.issue
95 95 assert_equal i.project, t.project
96 96 end
97 97
98 98 def test_post_create_with_blank_issue
99 99 # TODO: should POST to issues’ time log instead of project. change form
100 100 # and routing
101 101 @request.session[:user_id] = 3
102 102 post :create, :project_id => 1,
103 103 :time_entry => {:comments => 'Some work on TimelogControllerTest',
104 104 # Not the default activity
105 105 :activity_id => '11',
106 106 :issue_id => '',
107 107 :spent_on => '2008-03-14',
108 108 :hours => '7.3'}
109 109 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
110 110
111 111 t = TimeEntry.find_by_comments('Some work on TimelogControllerTest')
112 112 assert_not_nil t
113 113 assert_equal 11, t.activity_id
114 114 assert_equal 7.3, t.hours
115 115 assert_equal 3, t.user_id
116 116 end
117 117
118 118 def test_update
119 119 entry = TimeEntry.find(1)
120 120 assert_equal 1, entry.issue_id
121 121 assert_equal 2, entry.user_id
122 122
123 123 @request.session[:user_id] = 1
124 124 put :update, :id => 1,
125 125 :time_entry => {:issue_id => '2',
126 126 :hours => '8'}
127 127 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
128 128 entry.reload
129 129
130 130 assert_equal 8, entry.hours
131 131 assert_equal 2, entry.issue_id
132 132 assert_equal 2, entry.user_id
133 133 end
134 134
135 135 def test_destroy
136 136 @request.session[:user_id] = 2
137 137 delete :destroy, :id => 1
138 138 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
139 139 assert_equal I18n.t(:notice_successful_delete), flash[:notice]
140 140 assert_nil TimeEntry.find_by_id(1)
141 141 end
142 142
143 143 def test_destroy_should_fail
144 144 # simulate that this fails (e.g. due to a plugin), see #5700
145 145 TimeEntry.class_eval do
146 146 before_destroy :stop_callback_chain
147 147 def stop_callback_chain ; return false ; end
148 148 end
149 149
150 150 @request.session[:user_id] = 2
151 151 delete :destroy, :id => 1
152 152 assert_redirected_to :action => 'index', :project_id => 'ecookbook'
153 153 assert_equal I18n.t(:notice_unable_delete_time_entry), flash[:error]
154 154 assert_not_nil TimeEntry.find_by_id(1)
155 155
156 156 # remove the simulation
157 157 TimeEntry.before_destroy.reject! {|callback| callback.method == :stop_callback_chain }
158 158 end
159 159
160 160 def test_index_all_projects
161 161 get :index
162 162 assert_response :success
163 163 assert_template 'index'
164 164 assert_not_nil assigns(:total_hours)
165 165 assert_equal "162.90", "%.2f" % assigns(:total_hours)
166 assert_tag :form,
167 :attributes => {:action => "/time_entries", :id => 'query_form'}
166 168 end
167 169
168 170 def test_index_at_project_level
169 get :index, :project_id => 1
171 get :index, :project_id => 'ecookbook'
170 172 assert_response :success
171 173 assert_template 'index'
172 174 assert_not_nil assigns(:entries)
173 175 assert_equal 4, assigns(:entries).size
174 176 # project and subproject
175 177 assert_equal [1, 3], assigns(:entries).collect(&:project_id).uniq.sort
176 178 assert_not_nil assigns(:total_hours)
177 179 assert_equal "162.90", "%.2f" % assigns(:total_hours)
178 180 # display all time by default
179 181 assert_equal '2007-03-12'.to_date, assigns(:from)
180 182 assert_equal '2007-04-22'.to_date, assigns(:to)
183 assert_tag :form,
184 :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
181 185 end
182 186
183 187 def test_index_at_project_level_with_date_range
184 get :index, :project_id => 1, :from => '2007-03-20', :to => '2007-04-30'
188 get :index, :project_id => 'ecookbook', :from => '2007-03-20', :to => '2007-04-30'
185 189 assert_response :success
186 190 assert_template 'index'
187 191 assert_not_nil assigns(:entries)
188 192 assert_equal 3, assigns(:entries).size
189 193 assert_not_nil assigns(:total_hours)
190 194 assert_equal "12.90", "%.2f" % assigns(:total_hours)
191 195 assert_equal '2007-03-20'.to_date, assigns(:from)
192 196 assert_equal '2007-04-30'.to_date, assigns(:to)
197 assert_tag :form,
198 :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
193 199 end
194 200
195 201 def test_index_at_project_level_with_period
196 get :index, :project_id => 1, :period => '7_days'
202 get :index, :project_id => 'ecookbook', :period => '7_days'
197 203 assert_response :success
198 204 assert_template 'index'
199 205 assert_not_nil assigns(:entries)
200 206 assert_not_nil assigns(:total_hours)
201 207 assert_equal Date.today - 7, assigns(:from)
202 208 assert_equal Date.today, assigns(:to)
209 assert_tag :form,
210 :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
203 211 end
204 212
205 213 def test_index_one_day
206 get :index, :project_id => 1, :from => "2007-03-23", :to => "2007-03-23"
214 get :index, :project_id => 'ecookbook', :from => "2007-03-23", :to => "2007-03-23"
207 215 assert_response :success
208 216 assert_template 'index'
209 217 assert_not_nil assigns(:total_hours)
210 218 assert_equal "4.25", "%.2f" % assigns(:total_hours)
219 assert_tag :form,
220 :attributes => {:action => "/projects/ecookbook/time_entries", :id => 'query_form'}
211 221 end
212 222
213 223 def test_index_at_issue_level
214 224 get :index, :issue_id => 1
215 225 assert_response :success
216 226 assert_template 'index'
217 227 assert_not_nil assigns(:entries)
218 228 assert_equal 2, assigns(:entries).size
219 229 assert_not_nil assigns(:total_hours)
220 230 assert_equal 154.25, assigns(:total_hours)
221 231 # display all time based on what's been logged
222 232 assert_equal '2007-03-12'.to_date, assigns(:from)
223 233 assert_equal '2007-04-22'.to_date, assigns(:to)
234 # TODO: remove /projects/:project_id/issues/:issue_id/time_entries routes
235 # to use /issues/:issue_id/time_entries
236 assert_tag :form,
237 :attributes => {:action => "/projects/ecookbook/issues/1/time_entries", :id => 'query_form'}
224 238 end
225 239
226 240 def test_index_atom_feed
227 241 get :index, :project_id => 1, :format => 'atom'
228 242 assert_response :success
229 243 assert_equal 'application/atom+xml', @response.content_type
230 244 assert_not_nil assigns(:items)
231 245 assert assigns(:items).first.is_a?(TimeEntry)
232 246 end
233 247
234 248 def test_index_all_projects_csv_export
235 249 Setting.date_format = '%m/%d/%Y'
236 250 get :index, :format => 'csv'
237 251 assert_response :success
238 252 assert_equal 'text/csv', @response.content_type
239 253 assert @response.body.include?("Date,User,Activity,Project,Issue,Tracker,Subject,Hours,Comment\n")
240 254 assert @response.body.include?("\n04/21/2007,redMine Admin,Design,eCookbook,3,Bug,Error 281 when updating a recipe,1.0,\"\"\n")
241 255 end
242 256
243 257 def test_index_csv_export
244 258 Setting.date_format = '%m/%d/%Y'
245 259 get :index, :project_id => 1, :format => 'csv'
246 260 assert_response :success
247 261 assert_equal 'text/csv', @response.content_type
248 262 assert @response.body.include?("Date,User,Activity,Project,Issue,Tracker,Subject,Hours,Comment\n")
249 263 assert @response.body.include?("\n04/21/2007,redMine Admin,Design,eCookbook,3,Bug,Error 281 when updating a recipe,1.0,\"\"\n")
250 264 end
251 265 end
General Comments 0
You need to be logged in to leave comments. Login now