backlog 0.12.0 → 0.12.1

Sign up to get free protection for your applications and to get access to all the features.
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