backlog 0.12.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +15 -0
- data/app/controllers/application.rb +17 -0
- data/app/controllers/customers_controller.rb +51 -0
- data/app/controllers/estimates_controller.rb +3 -4
- data/app/controllers/tasks_controller.rb +20 -32
- data/app/helpers/application_helper.rb +11 -2
- data/app/helpers/customers_helper.rb +2 -0
- data/app/helpers/tasks_helper.rb +69 -0
- data/app/views/customers/_form.rhtml +7 -0
- data/app/views/customers/edit.rhtml +9 -0
- data/app/views/customers/list.rhtml +27 -0
- data/app/views/customers/new.rhtml +8 -0
- data/app/views/customers/show.rhtml +8 -0
- data/app/views/periods/_show_active.rhtml +13 -10
- data/app/views/redirect.rjs +1 -0
- data/app/views/redirect.rjs~ +0 -0
- data/app/views/tasks/_fields_header.rhtml +1 -1
- data/app/views/tasks/_form.rhtml +6 -1
- data/app/views/tasks/_task.rhtml +3 -3
- data/app/views/tasks/finish.rjs +4 -0
- data/app/views/tasks/move_to_period.rjs +4 -0
- data/app/views/tasks/reopen.rjs +4 -24
- data/config/boot.rb +1 -10
- data/public/javascripts/builder.js +136 -0
- data/public/javascripts/controls.js +486 -354
- data/public/javascripts/dragdrop.js +82 -52
- data/public/javascripts/effects.js +398 -364
- data/public/javascripts/prototype.js +2764 -1095
- data/public/javascripts/scriptaculous.js +58 -0
- data/public/javascripts/slider.js +275 -0
- data/public/javascripts/sound.js +55 -0
- data/public/javascripts/unittest.js +568 -0
- data/test/functional/backlogs_controller_test.rb +1 -1
- data/test/functional/customers_controller_test.rb +93 -0
- data/test/functional/tasks_controller_test.rb +4 -8
- data/test/functional/work_accounts_controller_test.rb +1 -1
- data/test/performance/test_threaded.rb +40 -31
- data/test/test_helper.rb +4 -2
- metadata +20 -3
- data/app/views/tasks/finish_ajax.rjs +0 -25
data/History.txt
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
== 0.12.1 2007-11-07
|
2
|
+
|
3
|
+
===Features
|
4
|
+
|
5
|
+
* Made "Move to next sprint" and "Abort" functions use ajax to speed up response.
|
6
|
+
* Added scaffold for Customers.
|
7
|
+
|
8
|
+
=== Fixes
|
9
|
+
|
10
|
+
* Fixed some errors in the Show Sprint view.
|
11
|
+
|
12
|
+
=== Known bugs
|
13
|
+
|
14
|
+
* Finishing or reopening tasks makes remaining tasks show wrong priority number.
|
15
|
+
|
1
16
|
== 0.12.0 2007-11-06
|
2
17
|
|
3
18
|
===Features
|
@@ -74,6 +74,16 @@ class ApplicationController < ActionController::Base
|
|
74
74
|
redirect_to(options)
|
75
75
|
end
|
76
76
|
|
77
|
+
def rjs_detour_to(options)
|
78
|
+
store_detour(params)
|
79
|
+
rjs_redirect_to(options)
|
80
|
+
end
|
81
|
+
|
82
|
+
def rjs_redirect_to(options)
|
83
|
+
@options = options
|
84
|
+
render :template => 'redirect', :layout => false
|
85
|
+
end
|
86
|
+
|
77
87
|
def store_detour(options)
|
78
88
|
if session[:detours] && session[:detours].last == options
|
79
89
|
logger.debug "duplicate detour: #{options}"
|
@@ -177,4 +187,11 @@ class ApplicationController < ActionController::Base
|
|
177
187
|
User.find_by_id(user_id) if user_id
|
178
188
|
end
|
179
189
|
|
190
|
+
def setup_remove
|
191
|
+
@last_active = @task.higher_item.nil? && @task.lower_item.nil?
|
192
|
+
@last_active_in_backlog = @last_active || ((@task.higher_item.nil? || @task.higher_item.backlog != @task.backlog) && (@task.lower_item.nil? || @task.lower_item.backlog != @task.backlog))
|
193
|
+
finished_count = Task.count(:conditions => ['period_id = ? AND finished_at IS NOT NULL', @task.period_id])
|
194
|
+
@first_finished = finished_count == 0
|
195
|
+
end
|
196
|
+
|
180
197
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class CustomersController < ApplicationController
|
2
|
+
def index
|
3
|
+
list
|
4
|
+
render :action => 'list'
|
5
|
+
end
|
6
|
+
|
7
|
+
# GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
|
8
|
+
verify :method => :post, :only => [ :destroy, :create, :update ],
|
9
|
+
:redirect_to => { :action => :list }
|
10
|
+
|
11
|
+
def list
|
12
|
+
@customer_pages, @customers = paginate :customers, :per_page => 10
|
13
|
+
end
|
14
|
+
|
15
|
+
def show
|
16
|
+
@customer = Customer.find(params[:id])
|
17
|
+
end
|
18
|
+
|
19
|
+
def new
|
20
|
+
@customer = Customer.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def create
|
24
|
+
@customer = Customer.new(params[:customer])
|
25
|
+
if @customer.save
|
26
|
+
flash[:notice] = 'Customer was successfully created.'
|
27
|
+
redirect_to :action => 'list'
|
28
|
+
else
|
29
|
+
render :action => 'new'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def edit
|
34
|
+
@customer = Customer.find(params[:id])
|
35
|
+
end
|
36
|
+
|
37
|
+
def update
|
38
|
+
@customer = Customer.find(params[:id])
|
39
|
+
if @customer.update_attributes(params[:customer])
|
40
|
+
flash[:notice] = 'Customer was successfully updated.'
|
41
|
+
redirect_to :action => 'show', :id => @customer
|
42
|
+
else
|
43
|
+
render :action => 'edit'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def destroy
|
48
|
+
Customer.find(params[:id]).destroy
|
49
|
+
redirect_to :action => 'list'
|
50
|
+
end
|
51
|
+
end
|
@@ -1,4 +1,6 @@
|
|
1
1
|
class EstimatesController < ApplicationController
|
2
|
+
helper :tasks
|
3
|
+
|
2
4
|
verify :method => :post, :redirect_to => ''
|
3
5
|
|
4
6
|
def create
|
@@ -16,10 +18,7 @@ class EstimatesController < ApplicationController
|
|
16
18
|
|
17
19
|
def create_ajax
|
18
20
|
if @task = Task.find_by_id(params[:id])
|
19
|
-
|
20
|
-
@last_active_in_backlog = @last_active || @task.lower_item.backlog != @task.backlog
|
21
|
-
finished_count = Task.count(:conditions => ['period_id = ? AND finished_at IS NOT NULL', @task.period_id])
|
22
|
-
@first_finished = finished_count == 0
|
21
|
+
setup_remove
|
23
22
|
end
|
24
23
|
@success, @message = do_create
|
25
24
|
# Only necessary since we have an unecessary complex update of estimates
|
@@ -17,6 +17,7 @@ class TasksController < ApplicationController
|
|
17
17
|
@task.backlog_id ||= @task.period && @task.period.most_frequent_backlog
|
18
18
|
@backlogs = Backlog.find(:all, :order => 'name')
|
19
19
|
@periods = Period.find_active_or_future
|
20
|
+
@customers = Customer.find(:all)
|
20
21
|
end
|
21
22
|
|
22
23
|
def create
|
@@ -52,6 +53,7 @@ class TasksController < ApplicationController
|
|
52
53
|
@task.period_id = params[:task][:period_id] if params[:task] && params[:task][:period_id]
|
53
54
|
@periods = Period.find_active_or_future
|
54
55
|
@backlogs = Backlog.find(:all, :order => 'name')
|
56
|
+
@customers = Customer.find(:all)
|
55
57
|
end
|
56
58
|
|
57
59
|
def update
|
@@ -185,59 +187,47 @@ class TasksController < ApplicationController
|
|
185
187
|
back_or_redirect_to :controller => 'periods', :action => :show_no_layout, :id => task.period_id, :task => task.id
|
186
188
|
end
|
187
189
|
|
188
|
-
def move_to_period
|
190
|
+
def move_to_period
|
189
191
|
params[:id] = $1 if params[:id] =~ /^task_(\d*)$/
|
190
|
-
task = Task.find(params[:id])
|
192
|
+
@task = Task.find(params[:id])
|
191
193
|
if request.post?
|
192
194
|
period = params[:period_id] && Period.find(params[:period_id])
|
193
195
|
if period && period.active_or_future?
|
194
|
-
next_task = task.higher_item ? task.higher_item : task.lower_item ? task.lower_item : task
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
else
|
199
|
-
back_or_redirect_to :controller => 'periods', :action => :show_no_layout, :id => next_task.period, :task_id => next_task.id
|
200
|
-
end
|
196
|
+
next_task = @task.higher_item ? @task.higher_item : @task.lower_item ? @task.lower_item : @task
|
197
|
+
setup_remove
|
198
|
+
@task.move_to_period period
|
199
|
+
render :action => :move_to_period, :layout => false
|
201
200
|
else
|
202
|
-
|
201
|
+
rjs_detour_to :controller => 'periods', :action => :new, :period => {:party_id => @task.period.party_id}, :layout => false
|
203
202
|
end
|
204
203
|
else
|
205
|
-
redirect_to :controller => 'periods', :action => :show, :id => task.period, :task_id => task.id, :layout =>
|
204
|
+
redirect_to :controller => 'periods', :action => :show, :id => @task.period, :task_id => @task.id, :layout => false
|
206
205
|
end
|
207
206
|
end
|
208
207
|
|
209
208
|
def move_to_next_period
|
210
|
-
task = Task.find(params[:id])
|
211
|
-
if task.period
|
212
|
-
next_period = task.period.lower_item
|
209
|
+
@task = Task.find(params[:id])
|
210
|
+
if @task.period
|
211
|
+
next_period = @task.period.lower_item
|
213
212
|
next_period = next_period.lower_item while next_period && next_period.passed?
|
214
213
|
params[:period_id] = next_period && next_period.id
|
215
|
-
move_to_period
|
214
|
+
move_to_period
|
216
215
|
else
|
217
|
-
redirect_to :action => :edit, :id => task
|
216
|
+
redirect_to :action => :edit, :id => @task
|
218
217
|
end
|
219
218
|
end
|
220
219
|
|
221
220
|
def finish
|
222
221
|
@task = Task.find(params[:id])
|
223
|
-
|
224
|
-
back_or_redirect_to :controller => 'periods', :action => :show, :id => @task.period, :task_id => @task.id
|
225
|
-
end
|
226
|
-
|
227
|
-
def finish_ajax
|
228
|
-
@task = Task.find(params[:id])
|
229
|
-
lower_item = @task.lower_item
|
230
|
-
@last_active = @task.lower_item.nil?
|
231
|
-
@last_active_in_backlog = @last_active || @task.lower_item.backlog != @task.backlog
|
232
|
-
finished_count = Task.count(:conditions => ['period_id = ? AND finished_at IS NOT NULL', @task.period_id])
|
233
|
-
@first_finished = finished_count == 0
|
222
|
+
setup_remove
|
234
223
|
@task.finish(Task::COMPLETED, true)
|
235
224
|
end
|
236
225
|
|
237
226
|
def abort
|
238
|
-
task = Task.find params[:id]
|
239
|
-
|
240
|
-
|
227
|
+
@task = Task.find params[:id]
|
228
|
+
setup_remove
|
229
|
+
@task.abort
|
230
|
+
render :action => :finish
|
241
231
|
end
|
242
232
|
|
243
233
|
def reopen
|
@@ -246,13 +236,11 @@ class TasksController < ApplicationController
|
|
246
236
|
@task.reload
|
247
237
|
finished_count = Task.count(:conditions => ['period_id = ? AND finished_at IS NOT NULL', @task.period_id])
|
248
238
|
@last_finished = finished_count == 0
|
249
|
-
# back_or_redirect_to :controller => 'periods', :action => :show, :id => @task.period, :task => @task.id
|
250
239
|
end
|
251
240
|
|
252
241
|
def start_work
|
253
242
|
@task = Task.find(params[:id])
|
254
243
|
@task.start_work
|
255
|
-
# back_or_redirect_to :controller => 'periods', :action => :show, :id => task.period, :task => task.id
|
256
244
|
end
|
257
245
|
|
258
246
|
def end_work
|
@@ -38,13 +38,13 @@ module ApplicationHelper
|
|
38
38
|
image_options.update :alt => title, :title => title
|
39
39
|
link_to image_tag(image_source, image_options), url_options, post ? {:method => :post} : nil
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
def image_link_to_remote(image_source, title, url_options, image_options = nil, post = false)
|
43
43
|
image_options ||= {:class => 'image-submit'}
|
44
44
|
image_options.update :alt => title, :title => title
|
45
45
|
link_to_remote image_tag(image_source, image_options), {:url => url_options}, post ? {:method => :post} : nil
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def detour?
|
49
49
|
not session[:detours].nil?
|
50
50
|
end
|
@@ -85,4 +85,13 @@ module ApplicationHelper
|
|
85
85
|
image_tag image_file, :title => l(@task.resolution.downcase)
|
86
86
|
end
|
87
87
|
|
88
|
+
def display_notice(page)
|
89
|
+
if @message
|
90
|
+
page.replace_html :notice, @message
|
91
|
+
page.visual_effect(:appear, :notice)
|
92
|
+
else
|
93
|
+
page.visual_effect(:fade, :notice)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
88
97
|
end
|
data/app/helpers/tasks_helper.rb
CHANGED
@@ -1,4 +1,73 @@
|
|
1
1
|
module TasksHelper
|
2
|
+
def remove_active_task(page)
|
3
|
+
page.visual_effect :blind_up, "task_#{@task.id}"
|
4
|
+
if @last_active_in_backlog
|
5
|
+
page["task_#{@task.id}"].ancestors.first.ancestors.first.remove
|
6
|
+
else
|
7
|
+
page.remove "task_#{@task.id}"
|
8
|
+
end
|
9
|
+
|
10
|
+
if @last_active
|
11
|
+
page.visual_effect :blind_up, "active_tasks"
|
12
|
+
page.visual_effect :appear, "no_tasks_message"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def remove_finished_task(page)
|
17
|
+
page.visual_effect :fade, "task_#{@task.id}"
|
18
|
+
page.remove "task_#{@task.id}"
|
19
|
+
|
20
|
+
if @last_finished
|
21
|
+
page.select('#completed_tasks tr').first.remove
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_active_task(page)
|
26
|
+
if @task.lower_item.nil? || @task.lower_item.backlog != @task.backlog
|
27
|
+
page.insert_html :top, :active_tasks, '<table class="input" style="width: 100%;"/>'
|
28
|
+
elsif @task.lower_item
|
29
|
+
page.select('#active_tasks table tr').first.remove
|
30
|
+
page.select('#active_tasks table tr').first.remove
|
31
|
+
end
|
32
|
+
|
33
|
+
insert(page, render(:partial => "/tasks/task", :locals => { :task => @task, :i => 1, :active => true, :highlight_task => false, :update => :spotlight, :hidden => true }), '#active_tasks table')
|
34
|
+
|
35
|
+
fields_header = render(:partial => '/tasks/fields_header', :locals => { :backlog => @task.backlog, :active => true } )
|
36
|
+
insert(page, fields_header, '#active_tasks table')
|
37
|
+
insert(page, render(:partial => "/tasks/backlog_header", :locals => {:backlog => @task.backlog}), '#active_tasks table')
|
38
|
+
|
39
|
+
page[:no_tasks_message].hide
|
40
|
+
|
41
|
+
if @task.lower_item.nil?
|
42
|
+
page.visual_effect :appear, "active_tasks"
|
43
|
+
end
|
44
|
+
page.visual_effect :appear, "task_#{@task.id}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_finished_task(page)
|
48
|
+
unless @first_finished
|
49
|
+
page.select('#completed_tasks tr').first.remove
|
50
|
+
end
|
51
|
+
|
52
|
+
page.insert_html :top, :completed_tasks, :partial => '/tasks/task', :locals => {:active => false, :hidden => true, :highlight_task => false}
|
53
|
+
page.visual_effect :appear, "task_#{@task.id}"
|
54
|
+
|
55
|
+
page.insert_html :top, :completed_tasks, :partial => '/tasks/fields_header', :locals => {:backlog => @task.backlog, :active => false}
|
56
|
+
end
|
57
|
+
|
58
|
+
def update_burn_down_chart(page)
|
59
|
+
page['burn_down_chart'].src = url_for(:controller => 'periods', :action => :burn_down_chart_thumbnail, :id => @task.period_id, :rnd => rand)
|
60
|
+
end
|
61
|
+
|
62
|
+
def record(page, script)
|
63
|
+
page.call("#{script};//")
|
64
|
+
end
|
65
|
+
|
66
|
+
def insert(page, content, selector, position = :top)
|
67
|
+
escaped_content = content.gsub("\n", '').gsub("'", "\\\\'")
|
68
|
+
record(page, "new Insertion.#{position.to_s.capitalize}($$('#{selector}').first(), '#{escaped_content}')")
|
69
|
+
end
|
70
|
+
|
2
71
|
end
|
3
72
|
|
4
73
|
class Time
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<h1>Editing customer</h1>
|
2
|
+
|
3
|
+
<% form_tag :action => 'update', :id => @customer do %>
|
4
|
+
<%= render :partial => 'form' %>
|
5
|
+
<%= submit_tag 'Edit' %>
|
6
|
+
<% end %>
|
7
|
+
|
8
|
+
<%= link_to 'Show', :action => 'show', :id => @customer %> |
|
9
|
+
<%= link_to 'Back', :action => 'list' %>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<h1>Listing customers</h1>
|
2
|
+
|
3
|
+
<table>
|
4
|
+
<tr>
|
5
|
+
<% for column in Customer.content_columns %>
|
6
|
+
<th><%= column.human_name %></th>
|
7
|
+
<% end %>
|
8
|
+
</tr>
|
9
|
+
|
10
|
+
<% for customer in @customers %>
|
11
|
+
<tr>
|
12
|
+
<% for column in Customer.content_columns %>
|
13
|
+
<td><%=h customer.send(column.name) %></td>
|
14
|
+
<% end %>
|
15
|
+
<td><%= link_to 'Show', :action => 'show', :id => customer %></td>
|
16
|
+
<td><%= link_to 'Edit', :action => 'edit', :id => customer %></td>
|
17
|
+
<td><%= link_to 'Destroy', { :action => 'destroy', :id => customer }, :confirm => 'Are you sure?', :method => :post %></td>
|
18
|
+
</tr>
|
19
|
+
<% end %>
|
20
|
+
</table>
|
21
|
+
|
22
|
+
<%= link_to 'Previous page', { :page => @customer_pages.current.previous } if @customer_pages.current.previous %>
|
23
|
+
<%= link_to 'Next page', { :page => @customer_pages.current.next } if @customer_pages.current.next %>
|
24
|
+
|
25
|
+
<br />
|
26
|
+
|
27
|
+
<%= link_to 'New customer', :action => 'new' %>
|
@@ -32,19 +32,22 @@ function handleEvent(field, event, id) {
|
|
32
32
|
</script>
|
33
33
|
|
34
34
|
|
35
|
-
<
|
36
|
-
<% current_backlog = nil
|
37
|
-
<% for task in @tasks
|
38
|
-
<% if task.backlog != current_backlog
|
39
|
-
<%=
|
40
|
-
<%=render :partial => '/tasks/backlog_header', :locals => { :backlog => task.backlog, :track_times => @tasks.find {|t|t.period && t.period.active?} } %>
|
41
|
-
<%=render :partial => '/tasks/fields_header', :locals => { :backlog => task.backlog, :active => true, :track_times => @tasks.find {|t|t.period && t.period.active?} } %>
|
35
|
+
<div id="active_tasks"<%=' style="display: none;"' unless @tasks and not @tasks.empty?%>>
|
36
|
+
<% current_backlog = nil -%>
|
37
|
+
<% for task in @tasks -%>
|
38
|
+
<% if task.backlog != current_backlog -%>
|
39
|
+
<%='</table>' if current_backlog%>
|
42
40
|
<% current_backlog = task.backlog %>
|
43
|
-
|
41
|
+
<table class="input" style="width: 100%;">
|
42
|
+
<%= '<tr><td> </td></tr>' if false && current_backlog %>
|
43
|
+
<%=render :partial => '/tasks/backlog_header', :locals => { :backlog => task.backlog, :track_times => @tasks.find {|t|t.period && t.period.active?} } %>
|
44
|
+
<%=render :partial => '/tasks/fields_header', :locals => { :backlog => task.backlog, :active => true, :track_times => @tasks.find {|t|t.period && t.period.active?} } %>
|
45
|
+
<% end -%>
|
44
46
|
<%=render :partial => '/tasks/task', :locals => { :task => task, :i => i, :active => true, :highlight_task => task == @selected_task, :update => :spotlight, :hidden => false } %>
|
45
47
|
<% i += 1 %>
|
46
|
-
<% end
|
47
|
-
</table>
|
48
|
+
<% end -%>
|
49
|
+
<%='</table>' if current_backlog%>
|
50
|
+
</div>
|
48
51
|
|
49
52
|
<p id="no_tasks_message"<%=' style="display: none;"' if @tasks and not @tasks.empty?%>><%=l :no_pending_tasks%></p>
|
50
53
|
|
@@ -0,0 +1 @@
|
|
1
|
+
page.redirect_to @options
|
File without changes
|