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.
Files changed (40) hide show
  1. data/History.txt +15 -0
  2. data/app/controllers/application.rb +17 -0
  3. data/app/controllers/customers_controller.rb +51 -0
  4. data/app/controllers/estimates_controller.rb +3 -4
  5. data/app/controllers/tasks_controller.rb +20 -32
  6. data/app/helpers/application_helper.rb +11 -2
  7. data/app/helpers/customers_helper.rb +2 -0
  8. data/app/helpers/tasks_helper.rb +69 -0
  9. data/app/views/customers/_form.rhtml +7 -0
  10. data/app/views/customers/edit.rhtml +9 -0
  11. data/app/views/customers/list.rhtml +27 -0
  12. data/app/views/customers/new.rhtml +8 -0
  13. data/app/views/customers/show.rhtml +8 -0
  14. data/app/views/periods/_show_active.rhtml +13 -10
  15. data/app/views/redirect.rjs +1 -0
  16. data/app/views/redirect.rjs~ +0 -0
  17. data/app/views/tasks/_fields_header.rhtml +1 -1
  18. data/app/views/tasks/_form.rhtml +6 -1
  19. data/app/views/tasks/_task.rhtml +3 -3
  20. data/app/views/tasks/finish.rjs +4 -0
  21. data/app/views/tasks/move_to_period.rjs +4 -0
  22. data/app/views/tasks/reopen.rjs +4 -24
  23. data/config/boot.rb +1 -10
  24. data/public/javascripts/builder.js +136 -0
  25. data/public/javascripts/controls.js +486 -354
  26. data/public/javascripts/dragdrop.js +82 -52
  27. data/public/javascripts/effects.js +398 -364
  28. data/public/javascripts/prototype.js +2764 -1095
  29. data/public/javascripts/scriptaculous.js +58 -0
  30. data/public/javascripts/slider.js +275 -0
  31. data/public/javascripts/sound.js +55 -0
  32. data/public/javascripts/unittest.js +568 -0
  33. data/test/functional/backlogs_controller_test.rb +1 -1
  34. data/test/functional/customers_controller_test.rb +93 -0
  35. data/test/functional/tasks_controller_test.rb +4 -8
  36. data/test/functional/work_accounts_controller_test.rb +1 -1
  37. data/test/performance/test_threaded.rb +40 -31
  38. data/test/test_helper.rb +4 -2
  39. metadata +20 -3
  40. 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
- @last_active = @task.lower_item.nil?
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(with_layout = false)
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
- task.move_to_period period
196
- if with_layout
197
- back_or_redirect_to :controller => 'periods', :action => :show, :id => next_task.period, :task_id => next_task.id
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
- detour_to :controller => 'periods', :action => :new, :period => {:party_id => task.period.party_id}, :layout => with_layout && determine_layout
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 => with_layout && determine_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(true)
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
- @task.finish(Task::COMPLETED, true)
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
- task.abort
240
- back_or_redirect_to(:controller => "periods", :action => "show", :id => task.period)
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
@@ -0,0 +1,2 @@
1
+ module CustomersHelper
2
+ end
@@ -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,7 @@
1
+ <%= error_messages_for 'customer' %>
2
+
3
+ <!--[form:customer]-->
4
+ <p><label for="customer_name">Name</label><br/>
5
+ <%= text_field 'customer', 'name' %></p>
6
+ <!--[eoform:customer]-->
7
+
@@ -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' %>
@@ -0,0 +1,8 @@
1
+ <h1>New customer</h1>
2
+
3
+ <% form_tag :action => 'create' do %>
4
+ <%= render :partial => 'form' %>
5
+ <%= submit_tag "Create" %>
6
+ <% end %>
7
+
8
+ <%= link_to 'Back', :action => 'list' %>
@@ -0,0 +1,8 @@
1
+ <% for column in Customer.content_columns %>
2
+ <p>
3
+ <b><%= column.human_name %>:</b> <%=h @customer.send(column.name) %>
4
+ </p>
5
+ <% end %>
6
+
7
+ <%= link_to 'Edit', :action => 'edit', :id => @customer %> |
8
+ <%= link_to 'Back', :action => 'list' %>
@@ -32,19 +32,22 @@ function handleEvent(field, event, id) {
32
32
  </script>
33
33
 
34
34
 
35
- <table id="active_tasks" class="input"<%=' 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
- <%= '<tr><td>&nbsp;</td></tr>' if current_backlog %>
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
- <% end %>
41
+ <table class="input" style="width: 100%;">
42
+ <%= '<tr><td>&nbsp;</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