backlog 0.22.1 → 0.23.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +28 -0
- data/README.txt +23 -2
- data/app/controllers/application.rb +15 -2
- data/app/controllers/periods_controller.rb +3 -0
- data/app/controllers/tasks_controller.rb +2 -2
- data/app/controllers/user_controller.rb +2 -2
- data/app/controllers/work_accounts_controller.rb +14 -0
- data/app/controllers/works_controller.rb +23 -3
- data/app/models/report_filter.rb +7 -3
- data/app/models/task.rb +11 -10
- data/app/models/work.rb +3 -2
- data/app/views/customers/_name_list.rhtml +5 -0
- data/app/views/periods/_show_active.rhtml +1 -0
- data/app/views/periods/_title.rhtml +8 -1
- data/app/views/periods/edit.rhtml +1 -1
- data/app/views/periods/order.rjs +0 -1
- data/app/views/tasks/_task.rhtml +6 -5
- data/app/views/user/login.rhtml +1 -1
- data/app/views/work_accounts/_title.rhtml +4 -0
- data/app/views/work_accounts/edit.rhtml +1 -3
- data/app/views/work_accounts/list.rhtml +9 -3
- data/app/views/work_accounts/show.rhtml +47 -30
- data/app/views/works/_form.rhtml +6 -0
- data/app/views/works/_row.rhtml +16 -9
- data/app/views/works/_row_field.rhtml +2 -2
- data/app/views/works/daily_work_sheet.rhtml +37 -7
- data/app/views/works/daily_work_sheet_old.rhtml +93 -0
- data/app/views/works/list.rhtml +11 -5
- data/app/views/works/update_row.rjs +5 -2
- data/config/environment.rb +19 -3
- data/lang/en.yaml +5 -0
- data/lang/no.yaml +5 -0
- data/lib/class_table_inheritance.rb +10 -3
- data/no_test.rb~ +6 -0
- data/test/client/login.rb +25 -0
- data/test/client/login.rb~ +33 -0
- data/test/client/login_test.rb +64 -0
- data/test/client/setup.rb +24 -0
- data/test/functional/works_controller_test.rb +3 -2
- data/test/unit/party_test.rb +10 -0
- data/test/unit/user_test.rb +15 -17
- metadata +12 -2
data/History.txt
CHANGED
@@ -1,3 +1,31 @@
|
|
1
|
+
== 0.23.0 2008-02-25
|
2
|
+
|
3
|
+
=== Features
|
4
|
+
|
5
|
+
* Improved input for daily_work_sheet
|
6
|
+
* Allowed override for development and test database with new config file
|
7
|
+
* Listed details for works without backlog in "Show Work Acoount" view.
|
8
|
+
* Added "List Works" view for Work Account.
|
9
|
+
* Added filtering of tasks grabbed by other users in the sprint view.
|
10
|
+
|
11
|
+
=== Fixes
|
12
|
+
|
13
|
+
* Improved work flow ("Back" links) several places.
|
14
|
+
* Fixed bug in layout when you had started tasks without a sprint.
|
15
|
+
* Some speedup of grabbing tasks.
|
16
|
+
* Fixed database corruption when trying to register users with duplicate login or email.
|
17
|
+
* Fixed display of welcome message after following link from "Forgot password" email.
|
18
|
+
* Fixed bug in daily work sheet when start time was not set for a work record.
|
19
|
+
* Starting work on a task grabs it.
|
20
|
+
* Changed to show "complete" check marks in sprint view for tasks that track time, but are not started.
|
21
|
+
* Display blank field for hours in daily work sheet if it has not been filled in yet.
|
22
|
+
* Always display row for new work record entry in daily work sheet.
|
23
|
+
Earlier, a row for new input was only shown if the previous row was ended.
|
24
|
+
* Removed message about missing database settings in main config file on startup since it is optional and deprecated.
|
25
|
+
* Fixed error in class table inheritance library. Validations for the subclass were not called.
|
26
|
+
* Added some Firewatir tests. EXPERIMENTAL!
|
27
|
+
* Added explenation on how to set database connection parameters.
|
28
|
+
|
1
29
|
== 0.22.1 2008-02-15
|
2
30
|
|
3
31
|
=== Features
|
data/README.txt
CHANGED
@@ -57,19 +57,40 @@ If you have concrete needs, and are willing to beta test the integration, please
|
|
57
57
|
|
58
58
|
=== Configuration
|
59
59
|
|
60
|
-
|
60
|
+
==== Setting port
|
61
|
+
|
62
|
+
You can set configuration parameters for backlog using the /etc/backlog.conf file on unix
|
63
|
+
and "c:\documents and settings\all\backlog.conf" on windows.
|
61
64
|
The format is YAML.
|
62
65
|
|
63
66
|
Example:
|
64
67
|
|
65
68
|
port: 3000
|
66
69
|
|
67
|
-
|
70
|
+
|
71
|
+
==== Setting database connection parameters
|
72
|
+
|
73
|
+
You can set database connnection parameters using the /etc/backlog/config/database.yml file on unix
|
74
|
+
and "c:\documents and settings\all\backlog\config\database.yml" on windows.
|
75
|
+
The format is YAML.
|
76
|
+
|
77
|
+
Example:
|
78
|
+
|
79
|
+
development:
|
80
|
+
adapter: postgresql
|
81
|
+
database: backlog_development
|
82
|
+
username: root
|
83
|
+
password: verySecret42
|
84
|
+
host: localhost
|
85
|
+
|
86
|
+
production:
|
68
87
|
adapter: postgresql
|
69
88
|
database: backlog_production
|
70
89
|
username: root
|
71
90
|
password: verySecret42
|
72
91
|
host: localhost
|
92
|
+
|
93
|
+
See the Rails documentation (http://rubyonrails.org) for more documentation on the databse connection seetings.
|
73
94
|
|
74
95
|
=== Charts
|
75
96
|
|
@@ -12,6 +12,7 @@ class ApplicationController < ActionController::Base
|
|
12
12
|
helper :user
|
13
13
|
before_filter :store_detour_from_params
|
14
14
|
before_filter :authenticate_user
|
15
|
+
before_filter :store_cookies_from_params
|
15
16
|
before_filter :populate_layout
|
16
17
|
|
17
18
|
def initialize
|
@@ -124,7 +125,20 @@ class ApplicationController < ActionController::Base
|
|
124
125
|
end
|
125
126
|
detour
|
126
127
|
end
|
127
|
-
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
def store_cookies_from_params
|
132
|
+
if params[:cookies]
|
133
|
+
params[:cookies].each_pair do |key, value|
|
134
|
+
logger.info "Storing cookie #{key.inspect}=#{value.inspect}"
|
135
|
+
#cookies[key] = {:value => value, :expires => 1.year.from_now}
|
136
|
+
session[key] = value
|
137
|
+
logger.info "Stored cookie #{key.inspect}=#{session[key].inspect}"
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
128
142
|
|
129
143
|
def populate_shortcuts
|
130
144
|
@shortcuts = [
|
@@ -182,7 +196,6 @@ class ApplicationController < ActionController::Base
|
|
182
196
|
end
|
183
197
|
end
|
184
198
|
|
185
|
-
private
|
186
199
|
|
187
200
|
def user_id
|
188
201
|
session[:user_id]
|
@@ -36,6 +36,9 @@ class PeriodsController < ApplicationController
|
|
36
36
|
if @selected_task.nil?
|
37
37
|
@selected_task = @period.open_tasks.first
|
38
38
|
end
|
39
|
+
# TODO (uwe): Switch to use cookie since the same behavior should work on next session.
|
40
|
+
# TODO (uwe): Problem: Cannot read cookie in the same request it was written...
|
41
|
+
@show_only_grabbed_tasks = session['show_only_grabbed_tasks'] == 'true'
|
39
42
|
load_tasks(@period)
|
40
43
|
end
|
41
44
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
class TasksController < ApplicationController
|
2
|
-
skip_before_filter :populate_layout, :except => [:edit, :list_started, :move_down, :move_to_bottom, :move_to_top, :move_up, :new, :specify]
|
2
|
+
skip_before_filter :populate_layout, :except => [:edit, :grab, :list_started, :move_down, :move_to_bottom, :move_to_top, :move_up, :new, :specify]
|
3
3
|
|
4
|
-
verify :method => :post, :except => [ :new, :show, :edit, :list_started, :move_to_next_period, :notes],
|
4
|
+
verify :method => :post, :except => [ :new, :show, :edit, :grab, :list_started, :move_to_next_period, :notes],
|
5
5
|
:redirect_to => { :controller => 'backlogs' }
|
6
6
|
|
7
7
|
def list_started
|
@@ -24,9 +24,9 @@ class UserController < ApplicationController
|
|
24
24
|
def signup
|
25
25
|
return if generate_blank_form
|
26
26
|
params['user'].delete('form')
|
27
|
-
@user = User.new(params['user'])
|
28
27
|
begin
|
29
28
|
User.transaction do
|
29
|
+
@user = User.new(params['user'])
|
30
30
|
@user.password_needs_confirmation = true
|
31
31
|
if @user.save
|
32
32
|
key = @user.generate_security_token
|
@@ -88,7 +88,7 @@ class UserController < ApplicationController
|
|
88
88
|
url = url_for(:action => 'change_password')
|
89
89
|
url += "?user[id]=#{user.id}&key=#{key}"
|
90
90
|
UserNotify.deliver_forgot_password(user, url)
|
91
|
-
flash[
|
91
|
+
flash[:notice] = "Instructions on resetting your password have been emailed to #{CGI.escapeHTML(params['user']['email'])}."
|
92
92
|
unless authenticated_user?
|
93
93
|
redirect_to :action => 'login'
|
94
94
|
return
|
@@ -19,6 +19,7 @@ class WorkAccountsController < ApplicationController
|
|
19
19
|
@task_totals = works.to_summarized_hash {|work| [work.task, work.hours]}
|
20
20
|
@task_totals_per_backlog = @task_totals.to_a.to_grouped_hash {|task, hours| [task && task.backlog, [task, hours]]}
|
21
21
|
@total_hours = works.inject(BigDecimal('0')) {|total, work| total += work.hours}
|
22
|
+
@works_without_backlog = works.select {|w| w.task_id.nil?}
|
22
23
|
end
|
23
24
|
|
24
25
|
def new
|
@@ -53,4 +54,17 @@ class WorkAccountsController < ApplicationController
|
|
53
54
|
WorkAccount.find(params[:id]).destroy
|
54
55
|
redirect_to :action => 'list'
|
55
56
|
end
|
57
|
+
|
58
|
+
def works
|
59
|
+
work_account = WorkAccount.find(params[:id])
|
60
|
+
@report_filter = ReportFilter.new(params[:report_filter])
|
61
|
+
@report_filter.title = "#{l :hours} for #{work_account.name} #{@report_filter.start_on && @report_filter.start_on.strftime('%Y-%m-%d - ')}#{@report_filter.end_on && @report_filter.end_on.strftime('%Y-%m-%d')}"
|
62
|
+
@works = Work.paginate :conditions => ["completed_at BETWEEN ? AND ? AND work_account_id = ?", @report_filter.start_on, @report_filter.end_on, work_account.id], :page => params[:page], :per_page => @report_filter.page_size
|
63
|
+
if params[:export] == 'excel'
|
64
|
+
render :template => '/works/list_excel', :layout => false
|
65
|
+
else
|
66
|
+
render :template => '/works/list'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
56
70
|
end
|
@@ -5,7 +5,7 @@ class WorksController < ApplicationController
|
|
5
5
|
in_place_edit_for :work, :completed_at_time
|
6
6
|
skip_before_filter :populate_layout, :except => [:create, :destroy, :edit, :index, :list, :new, :show, :update, :daily_work_sheet, :weekly_work_sheet_by_work_account]
|
7
7
|
auto_complete_for :work, :description
|
8
|
-
|
8
|
+
|
9
9
|
def index
|
10
10
|
list
|
11
11
|
render :action => 'list'
|
@@ -49,6 +49,14 @@ class WorksController < ApplicationController
|
|
49
49
|
account = WorkAccount.find_by_name(account_name)
|
50
50
|
params[:work][:work_account_id] = account.id
|
51
51
|
end
|
52
|
+
customer_name = params[:work].delete(:customer_name)
|
53
|
+
if customer_name && customer_name.size > 0
|
54
|
+
customer = Customer.find_by_name(customer_name)
|
55
|
+
if (customer.nil? )
|
56
|
+
customer = Customer.create!(:name => customer_name)
|
57
|
+
end
|
58
|
+
params[:work][:customer_id] = customer.id
|
59
|
+
end
|
52
60
|
end
|
53
61
|
convert_hours_param
|
54
62
|
convert_start_time_param
|
@@ -95,8 +103,11 @@ class WorksController < ApplicationController
|
|
95
103
|
def update_row
|
96
104
|
update_work
|
97
105
|
flash.discard
|
98
|
-
@
|
106
|
+
@next_field = params[:next_field] || 'work_account_name'
|
99
107
|
@work_accounts = WorkAccount.find(:all, :order => :name)
|
108
|
+
@customers = Customer.find(:all, :order => :name)
|
109
|
+
works = Work.find_work_for_day((@work.started_at || @work.completed_at).to_date)
|
110
|
+
@day_total = works.inject(BigDecimal('0')){|total,work|total+=work.hours}
|
100
111
|
end
|
101
112
|
|
102
113
|
def update_time
|
@@ -107,7 +118,6 @@ class WorksController < ApplicationController
|
|
107
118
|
|
108
119
|
def update_work
|
109
120
|
@work = Work.find(params[:id])
|
110
|
-
convert_start_time_param
|
111
121
|
convert_hours_param
|
112
122
|
if @work.update_attributes(params[:work])
|
113
123
|
flash[:notice] = 'Work was successfully updated.'
|
@@ -137,6 +147,7 @@ class WorksController < ApplicationController
|
|
137
147
|
@date = (params[:id] && Date.parse(params[:id])) || Date.today
|
138
148
|
@periods = []
|
139
149
|
@works = Work.find_work_for_day @date
|
150
|
+
@customers = Customer.find(:all, :order => :name)
|
140
151
|
@started_works = Task.find_started
|
141
152
|
@work = Work.new(:started_at => Time.now, :completed_at => Time.now)
|
142
153
|
@work_accounts = WorkAccount.find(:all, :order => :name)
|
@@ -182,6 +193,15 @@ class WorksController < ApplicationController
|
|
182
193
|
render :partial => '/work_accounts/name_list'
|
183
194
|
end
|
184
195
|
|
196
|
+
def auto_complete_for_work_customer_name
|
197
|
+
@customers = Customer.find(:all,
|
198
|
+
:conditions => [ 'LOWER(name) LIKE ?',
|
199
|
+
'%' + params[:work][:customer_name].downcase + '%' ],
|
200
|
+
:order => 'name ASC',
|
201
|
+
:limit => 16)
|
202
|
+
render :partial => '/customers/name_list'
|
203
|
+
end
|
204
|
+
|
185
205
|
def auto_complete_for_work_backlog_name
|
186
206
|
@backlogs = Backlog.find(:all,
|
187
207
|
:conditions => [ 'LOWER(name) LIKE ?',
|
data/app/models/report_filter.rb
CHANGED
@@ -5,17 +5,21 @@ class ReportFilter
|
|
5
5
|
attr_reader :page_size
|
6
6
|
|
7
7
|
def initialize(attributes)
|
8
|
+
@start_on = Date.civil(2007, 01, 01)
|
9
|
+
@end_on = Date.today
|
10
|
+
@page_size = 1000
|
11
|
+
|
8
12
|
if attributes
|
9
13
|
attributes = attributes.clone
|
10
14
|
|
11
15
|
start_on_param = attributes.delete(:start_on)
|
12
|
-
@start_on = start_on_param && start_on_param.size > 0
|
16
|
+
@start_on = Date.parse(start_on_param) if start_on_param && start_on_param.size > 0
|
13
17
|
|
14
18
|
end_on_param = attributes.delete(:end_on)
|
15
|
-
@end_on = end_on_param && end_on_param.size > 0
|
19
|
+
@end_on = Date.parse(end_on_param) if end_on_param && end_on_param.size > 0
|
16
20
|
|
17
21
|
page_size_param = attributes.delete(:page_size)
|
18
|
-
@page_size = page_size_param.to_i
|
22
|
+
@page_size = page_size_param.to_i if page_size_param.to_i > 0
|
19
23
|
|
20
24
|
raise "Unknown parameters: #{attributes.inspect}" unless attributes.empty?
|
21
25
|
end
|
data/app/models/task.rb
CHANGED
@@ -57,7 +57,7 @@ class Task < ActiveRecord::Base
|
|
57
57
|
end
|
58
58
|
conditions = "completed_at IS NULL AND (user_id IS NULL#{user_clause})"
|
59
59
|
Work.find(:all, :conditions => conditions).map {|work| work.task}.compact.sort_by do |t|
|
60
|
-
[t.root_task.backlog.name, t.root_task.period.end_on, t.position || 0]
|
60
|
+
[t.root_task.backlog.name, t.root_task.period ? t.root_task.period.end_on : 0, t.position || 0]
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
@@ -344,21 +344,22 @@ class Task < ActiveRecord::Base
|
|
344
344
|
def start_work
|
345
345
|
return if work_started?
|
346
346
|
open
|
347
|
+
grab if current_user
|
347
348
|
new_work = works.new
|
348
349
|
|
349
350
|
# TODO (uwe): Only needed for rails 1.2.x branch. Remove when moving to 1.3 or 2.0.
|
350
351
|
new_work.task = self
|
351
352
|
|
352
353
|
new_work.started_at = Time.previous_quarter
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
354
|
+
if current_user
|
355
|
+
last_work = current_user.works.select {|w| w.completed_at}.last
|
356
|
+
else
|
357
|
+
last_work = Work.find(:first, :conditions => 'completed_at IS NOT NULL', :order => 'completed_at DESC')
|
358
|
+
end
|
359
|
+
if last_work && last_work.completed_at > new_work.started_at
|
360
|
+
new_work.started_at = last_work.completed_at
|
361
|
+
end
|
362
|
+
|
362
363
|
new_work.user = current_user
|
363
364
|
new_work.work_account_id = work_account.id
|
364
365
|
new_work.save!
|
data/app/models/work.rb
CHANGED
@@ -110,8 +110,9 @@ class Work < ActiveRecord::Base
|
|
110
110
|
end
|
111
111
|
|
112
112
|
def started_at_time=(new_value)
|
113
|
-
|
114
|
-
|
113
|
+
new_value = '0:00' if new_value == ''
|
114
|
+
raise "invalid time format: #{new_value}" unless new_value =~ /(\d{0,2}):(\d{2})/
|
115
|
+
new_hour, new_minutes = $1.to_i, $2.to_i
|
115
116
|
t = started_at || Time.now
|
116
117
|
self.started_at = Time.local(t.year, t.month, t.day, new_hour, new_minutes)
|
117
118
|
end
|
@@ -36,6 +36,7 @@ function handleEvent(field, event, id) {
|
|
36
36
|
<%=render :partial => '/tasks/fields_header', :locals => { :backlog => nil, :active => true, :track_todo => @tasks.find {|t|t.period && t.period.active?}, :track_times => @tasks.find {|t|t.period && t.period.active?}, :track_done => @tasks.find {|t|t.period && t.period.active? }, :work_done => @tasks.find {|t| t.total_done > 0} } %>
|
37
37
|
<ul id="active_tasks_<%=@period.id%>" class="task_list">
|
38
38
|
<% for task in @tasks -%>
|
39
|
+
<% next if @show_only_grabbed_tasks && !(task.users.empty? || task.users.include?(current_user))%>
|
39
40
|
<%=render :partial => '/tasks/task', :locals => { :task => task, :i => i, :active => true, :highlight_task => task == @selected_task, :update => :spotlight, :show_backlog => true, :hidden => false } %>
|
40
41
|
<% i += 1 %>
|
41
42
|
<% end -%>
|
@@ -7,5 +7,12 @@
|
|
7
7
|
|
8
8
|
<%=if @period.higher_item then link_to(image_tag(url_for("arrow_left.png"), :alt => "#{l :previous} #{l :period}", :title => "#{l :previous} #{l :period}", :class => 'image-submit'), :controller => 'periods', :action => :show, :id => @period.higher_item) end%>
|
9
9
|
<%=unless @period.passed? then detour_to(image_tag(url_for("add.png"), :alt => l(:add_task), :title => l(:add_task), :class => 'image-submit'), :controller => 'tasks', :action => 'new', :task => {:period_id => (@period ? @period.id : (@backlog && @backlog.periods.first ? @backlog.periods.first.id : nil))} ) end %>
|
10
|
-
<h4><%=h @period.name %> (<%=@period.start_on%> - <%=@period.end_on%>)
|
10
|
+
<h4><%=h @period.name %> (<%=@period.start_on%> - <%=@period.end_on%>)
|
11
|
+
<% filter_style = {:style => 'float: none; vertical-align: bottom'} %>
|
12
|
+
<% if @show_only_grabbed_tasks %>
|
13
|
+
<%=image_link_to('grab.png', l(:release_task), {'cookies[show_only_grabbed_tasks]' => 'false'}, filter_style, false)%>
|
14
|
+
<% else %>
|
15
|
+
<%=image_link_to('grab_gray.png', l(:grab_task), {'cookies[show_only_grabbed_tasks]' => 'true'}, filter_style, false)%>
|
16
|
+
<% end %>
|
17
|
+
</h4>
|
11
18
|
</div>
|
@@ -4,7 +4,7 @@
|
|
4
4
|
<% form_tag :action => 'update', :id => @period do %>
|
5
5
|
<%= render :partial => 'form' %>
|
6
6
|
<%= submit_tag l(:save) %>
|
7
|
-
<%=
|
7
|
+
<%=back_or_link_to l(:back), :action => 'show', :id => @period %>
|
8
8
|
<% end %>
|
9
9
|
|
10
10
|
</div>
|
data/app/views/periods/order.rjs
CHANGED
@@ -1 +0,0 @@
|
|
1
|
-
record page, 'alert("hi");'
|
data/app/views/tasks/_task.rhtml
CHANGED
@@ -75,9 +75,10 @@
|
|
75
75
|
<% else -%>
|
76
76
|
<%=@task.todo %>
|
77
77
|
<% end -%>
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
<% else %>
|
79
|
+
<% if !@task.work_started? && (@task.period.nil? || @task.period.active?) %>
|
80
|
+
<%=image_link_to_remote('checkmark.png', l(:complete), {:action => :finish_task, :id => @task}, nil, true)%>
|
81
|
+
<% end -%>
|
81
82
|
<% end -%>
|
82
83
|
<% end -%>
|
83
84
|
</div>
|
@@ -87,9 +88,9 @@
|
|
87
88
|
<% unless @task.work_started? -%>
|
88
89
|
<% if @task.backlog.enable_users? %>
|
89
90
|
<% if @task.users.include?(current_user) %>
|
90
|
-
<%=image_link_to_remote('grab.png', l(:
|
91
|
+
<%=image_link_to_remote('grab.png', l(:release_task), with_detour({:controller => 'tasks', :action => :release, :id => @task}), nil, true)%>
|
91
92
|
<% else %>
|
92
|
-
<%=image_link_to_remote('grab_gray.png', l(:
|
93
|
+
<%=image_link_to_remote('grab_gray.png', "#{l:grab_task} #{" (#{l :not_grabbed})" if @task.users.empty?}", with_detour({:controller => 'tasks', :action => :grab, :id => @task}), nil, true)%>
|
93
94
|
<% end %>
|
94
95
|
<% end %>
|
95
96
|
<%=image_link_to_remote('arrow_right.png', l(:move_to_next_period), {:action => :move_task_to_next_period, :id => @task}, nil, true) if @task.backlog.enable_periods? || @task.period_id%>
|
data/app/views/user/login.rhtml
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
<% @page_title = "#{l(:editing)} #{l(:work_account)}" %>
|
2
2
|
|
3
3
|
<div id="spotlight">
|
4
|
-
|
5
|
-
<h4><%=@work_account.name%></h4>
|
6
|
-
</div>
|
4
|
+
<%=render :partial => 'title'%>
|
7
5
|
|
8
6
|
<% form_tag :action => 'update', :id => @work_account do %>
|
9
7
|
<%=render :partial => 'form' %>
|
@@ -1,4 +1,10 @@
|
|
1
|
-
|
1
|
+
<% @page_title = "#{l :work_accounts}"%>
|
2
|
+
|
3
|
+
<div id="spotlight">
|
4
|
+
<div class="btitle">
|
5
|
+
<%=image_detour_to 'add.png', l(:new_work_account), :action => 'new' %>
|
6
|
+
<h4><%=@page_title%></h4>
|
7
|
+
</div>
|
2
8
|
|
3
9
|
<table>
|
4
10
|
<tr>
|
@@ -21,6 +27,6 @@
|
|
21
27
|
|
22
28
|
<%=will_paginate @work_accounts %>
|
23
29
|
|
24
|
-
|
30
|
+
<%=back_or_link_to l(:back), :controller => 'welcome', :action => 'index' %>
|
25
31
|
|
26
|
-
|
32
|
+
</div>
|
@@ -1,33 +1,50 @@
|
|
1
1
|
<% @page_title = "#{l(:work_account)} #{l(:work_account)}" %>
|
2
|
-
|
3
2
|
<div id="spotlight">
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
3
|
+
<%=render :partial => 'title'%>
|
4
|
+
<table>
|
5
|
+
<% for backlog in @backlog_totals.keys %>
|
6
|
+
<tr>
|
7
|
+
<th>
|
8
|
+
<%=backlog ? backlog.name : l(:no_backlog) %>
|
9
|
+
</th>
|
10
|
+
<th>
|
11
|
+
<%=@backlog_totals[backlog] %>
|
12
|
+
</th>
|
13
|
+
</tr>
|
14
|
+
<% if backlog %>
|
15
|
+
<% for task, hours in @task_totals_per_backlog[backlog] %>
|
16
|
+
<tr>
|
17
|
+
<td>
|
18
|
+
<% if task %>
|
19
|
+
<%=link_to task.description, :controller => 'tasks', :action => :edit, :id => task.id %>
|
20
|
+
<% end %>
|
21
|
+
</td>
|
22
|
+
<td align="right" valign="top">
|
23
|
+
<%='%.2f' % hours %>
|
24
|
+
</td>
|
25
|
+
</tr>
|
26
|
+
<% end %>
|
27
|
+
<% else %>
|
28
|
+
<% for work in @works_without_backlog %>
|
29
|
+
<tr>
|
30
|
+
<td>
|
31
|
+
<%=work.description %>
|
32
|
+
</td>
|
33
|
+
<td align="right" valign="top">
|
34
|
+
<%='%.2f' % work.hours %>
|
35
|
+
</td>
|
36
|
+
</tr>
|
37
|
+
<% end %>
|
38
|
+
<% end %>
|
39
|
+
<% end %>
|
40
|
+
<tr>
|
41
|
+
<th>
|
42
|
+
Total hours
|
43
|
+
</th>
|
44
|
+
<th>
|
45
|
+
<%=@total_hours %>
|
46
|
+
</th>
|
47
|
+
</tr>
|
48
|
+
</table>
|
49
|
+
<%=detour_to l(:edit), :action => 'edit', :id => @work_account %>|<%=back_or_link_to l(:back), :action => 'list' %>
|
33
50
|
</div>
|