backlog 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,3 +1,8 @@
1
+ == 0.3.0 2007-08-02
2
+
3
+ * Improved workflow
4
+ * Added task list to backlog edit view
5
+
1
6
  == 0.2.1 2007-07-31
2
7
 
3
8
  * Improved workflow
data/Rakefile CHANGED
@@ -11,7 +11,7 @@ require 'tasks/rails'
11
11
 
12
12
  require 'hoe'
13
13
 
14
- Hoe.new("backlog", '0.2.1') do |p|
14
+ Hoe.new("backlog", '0.3.0') do |p|
15
15
  p.rubyforge_name = "backlog"
16
16
  p.summary = "Application to aid collecting, processing, organizing, reviewing and doing tasks."
17
17
  p.description = p.paragraphs_of('README.txt', 0..-1).join("\n\n")
@@ -67,6 +67,10 @@ class ApplicationController < ActionController::Base
67
67
  end
68
68
 
69
69
  def store_detour(options)
70
+ if session[:detours] && session[:detours].last == options
71
+ puts "duplicate detour: #{options}"; STDOUT.flush
72
+ return
73
+ end
70
74
  puts "adding detour: #{options}"; STDOUT.flush
71
75
  session[:detours] ||= []
72
76
  session[:detours] << options
@@ -118,8 +122,8 @@ class ApplicationController < ActionController::Base
118
122
  end
119
123
 
120
124
  def populate_layout
121
- @period = Period.find(:first, params[:id]) if params[:id]
122
- @owner = @period.party if @period
125
+ # @period = Period.find(:first, params[:id]) if params[:id]
126
+ # @owner = @period.party if @period
123
127
  populate_shortcuts
124
128
 
125
129
  # TODO (uwe): This does not scale!
@@ -48,6 +48,10 @@ class BacklogsController < ApplicationController
48
48
 
49
49
  def edit
50
50
  @backlog = Backlog.find(params[:id])
51
+ @tasks = @backlog.tasks.sort do |t1, t2|
52
+ (t1.position && (t2.position ? t1.position <=> t2.position : -1)) ||
53
+ (t2.position ? 1 : t1.finished_at <=> t2.finished_at)
54
+ end
51
55
  end
52
56
 
53
57
  def update
@@ -31,6 +31,8 @@ class TasksController < ApplicationController
31
31
  redirect_to :controller => 'periods', :action => 'show', :id => @task.period, :task => @task.id
32
32
  else
33
33
  populate_layout
34
+ @backlogs = Backlog.find(:all, :order => 'name')
35
+ @periods = Period.find_active_or_future
34
36
  render :action => 'new'
35
37
  end
36
38
  end
@@ -122,7 +124,7 @@ class TasksController < ApplicationController
122
124
  period = params[:period_id] && Period.find(params[:period_id])
123
125
  if period && period.active_or_future?
124
126
  next_task = task.higher_item ? task.higher_item : task.lower_item ? task.lower_item : task
125
- task.move_to_period period, user
127
+ task.move_to_period period
126
128
  if with_layout
127
129
  back_or_redirect_to :controller => 'periods', :action => :show, :id => next_task.period, :task_id => next_task.id
128
130
  else
@@ -151,13 +153,13 @@ class TasksController < ApplicationController
151
153
  def abort
152
154
  task = Task.find params[:id]
153
155
  task.abort(user)
154
- redirect_to(:controller => "periods", :action => "show", :id => task.period)
156
+ back_or_redirect_to(:controller => "periods", :action => "show", :id => task.period)
155
157
  end
156
158
 
157
159
  def reopen
158
160
  task = Task.find(params[:id])
159
161
  task.reopen(user)
160
- redirect_to :controller => 'periods', :action => :show, :id => task.period, :task => task.id
162
+ back_or_redirect_to :controller => 'periods', :action => :show, :id => task.period, :task => task.id
161
163
  end
162
164
 
163
165
  def start_work
@@ -12,20 +12,19 @@ module ApplicationHelper
12
12
  end
13
13
 
14
14
  def detour_to(title, options, html_options = nil)
15
- #link_to title, options.update({:detour => {:controller => @controller.controller_name, :action => @controller.action_name, :id => params[:id]}}), html_options
16
15
  link_to title, options.update({:detour => params.reject {|k, v| [:detour, :return_from_detour].include? k.to_sym}}), html_options
17
16
  end
18
17
 
19
- def image_detour_to(image_source, title, image_options, options )
18
+ def image_detour_to(image_source, title, url_options, image_options = nil, post = false)
20
19
  image_options ||= {:class => 'image-submit'}
21
20
  image_options.update :alt => title, :title => title
22
- detour_to image_tag(image_source, image_options), options
21
+ detour_to image_tag(image_source, image_options), url_options, :method => post ? :post : :get
23
22
  end
24
23
 
25
24
  def back_or_link_to(title, options)
26
25
  if session[:detours]
27
- options = session[:detours].last.update({:return_from_detour => true})
28
- puts "linked detour: #{options}"
26
+ options = {:return_from_detour => true}.update(session[:detours].last)
27
+ puts "linked return from detour: #{options}"
29
28
  end
30
29
  link_to title, options
31
30
  end
data/app/models/party.rb CHANGED
@@ -9,4 +9,8 @@ class Party < ActiveRecord::Base
9
9
  self.class.name.downcase.pluralize
10
10
  end
11
11
 
12
+ def icon
13
+ to_sym.to_s + '.png'
14
+ end
15
+
12
16
  end
data/app/models/task.rb CHANGED
@@ -17,6 +17,9 @@ class Task < ActiveRecord::Base
17
17
  validates_size_of :customer, :maximum => 64, :if => :customer
18
18
  validates_presence_of :backlog_id, :if => Proc.new { |task| task.parent_id.nil? }
19
19
  validates_presence_of :parent_id, :if => Proc.new { |task| task.backlog_id.nil? }
20
+ #validates_absence_of :position, :if => :finished_at
21
+ #validates_absence_of :finished_at, :if => :position
22
+ validates_presence_of :resolution, :if => :finished_at
20
23
  validates_uniqueness_of :description, :scope => :period_id
21
24
  validates_uniqueness_of :position, :scope => :period_id, :allow_nil => true
22
25
 
@@ -24,7 +27,7 @@ class Task < ActiveRecord::Base
24
27
  unless (self.period_id || self.parent_id) && !(self.period_id && self.parent_id)
25
28
  errors.add :parent_id, "A task may have either period or parent task set, not both."
26
29
  end
27
- if new_record? && self.period.passed?
30
+ if new_record? && self.period && self.period.passed?
28
31
  errors.add :period_id, "You may not add a task to a past period."
29
32
  end
30
33
  end
@@ -49,7 +52,7 @@ class Task < ActiveRecord::Base
49
52
  estimates.last ? estimates.last.todo : initial_estimate
50
53
  end
51
54
 
52
- def estimate(new_todo, user)
55
+ def estimate(new_todo)
53
56
  return unless new_todo && new_todo != ''
54
57
  previous_estimate = estimates.last
55
58
  new_estimate = Estimate.new
@@ -61,13 +64,13 @@ class Task < ActiveRecord::Base
61
64
  now = Time.now
62
65
  if previous_estimate && (now < previous_estimate.created_at || now.strftime('%Y-%m-%DT%H:%M:%S') == previous_estimate.created_at.strftime('%Y-%m-%DT%H:%M:%S'))
63
66
  previous_estimate.todo = new_todo
64
- previous_estimate.user = user
67
+ previous_estimate.user = current_user
65
68
  previous_estimate.save!
66
69
  else
67
70
  new_estimate.task_id = self.id
68
71
  new_estimate.todo = new_todo
69
72
  new_estimate.created_at = now
70
- new_estimate.user = user
73
+ new_estimate.user = current_user
71
74
  new_estimate.save!
72
75
  estimates << new_estimate
73
76
  end
@@ -94,13 +97,13 @@ class Task < ActiveRecord::Base
94
97
  total
95
98
  end
96
99
 
97
- def open(user)
100
+ def open
98
101
  if finished_at
99
102
  self.finished_at = nil
100
103
  self.resolution = nil
101
- estimate(initial_estimate, user)
104
+ estimate(initial_estimate)
102
105
  insert_at 1
103
- parent.open(user) if parent
106
+ parent.open if parent
104
107
  end
105
108
  end
106
109
 
@@ -114,7 +117,7 @@ class Task < ActiveRecord::Base
114
117
  end
115
118
  end
116
119
 
117
- def move_to_period(period, user)
120
+ def move_to_period(period)
118
121
  raise "Period missing" unless period
119
122
  raise "Cannot move finished tasks" unless active?
120
123
 
@@ -122,26 +125,26 @@ class Task < ActiveRecord::Base
122
125
  new_task = Task.find_by_period_id_and_id(period.id, ancestor_id)
123
126
  new_task ||= Task.find_by_period_id_and_previous_task_id(period.id, ancestor_id)
124
127
  new_task ||= Task.new
125
- new_task.open(user)
128
+ new_task.open
126
129
  new_task.previous_task_id = self.previous_task_id || self.id
127
- new_task.backlog = backlog
130
+ new_task.backlog = root_task.backlog
128
131
  new_task.period = period
129
132
  new_task.description = self.description
130
133
  new_task.save!
131
- new_task.estimate(self.todo, user)
134
+ new_task.estimate(self.todo)
132
135
  new_task.move_to_top
133
- new_task.estimate(self.todo, user)
134
- self.finish(new_task.period.party == self.period.party ? Task::POSTPONED : Task::MOVED, true, user)
136
+ new_task.estimate(self.todo)
137
+ self.finish(new_task.period.party == self.period.party ? Task::POSTPONED : Task::MOVED, true, current_user)
135
138
  end
136
139
 
137
140
  def finish(resolution, save_work, user)
138
141
  unless finished_at || work_started?
139
- remove_from_list
140
142
  self.finished_at = Time.now
141
143
  self.resolution = resolution
142
144
  self.position = nil
143
145
  save!
144
- estimate(0, user) if save_work
146
+ remove_from_list
147
+ estimate(0) if save_work
145
148
  parent.check_finished(self.finished_at, resolution, save_work, user) if parent
146
149
  end
147
150
  end
@@ -7,3 +7,20 @@
7
7
  <%= back_or_link_to l(:back), :action => 'show', :id => @backlog %>
8
8
  <% end %>
9
9
  </div>
10
+
11
+ <div id="maincontent">
12
+ <div class="mainblock">
13
+ <div class="btitle">
14
+ <h4><%=l :tasks%></h4>
15
+ </div>
16
+
17
+ <table>
18
+ <%= render :partial => '/tasks/backlog_header', :locals => {:backlog => @backlog} %>
19
+ <% i = 0 %>
20
+ <% for @task in @tasks %>
21
+ <%= render :partial => '/tasks/task/', :locals => {:task => @task, :i => i += 1, :active => true, :highlight => false} %>
22
+ <% end %>
23
+ </table>
24
+ </div>
25
+
26
+ </div>
@@ -10,7 +10,7 @@
10
10
  <%= hidden_field 'period', 'party_id' %><%=detour_to h(@period.party.name), :controller => @period.party.type.name.downcase.pluralize, :action => :edit, :id => @period.party%>
11
11
  <% end %>
12
12
  <% if @period.party %>
13
- <%=image_detour_to(@period.party.to_sym.to_s + '.png', "#{l(@period.party.to_sym)} #{@period.party.name}", nil, :controller => @period.party.to_s, :action => :edit, :id => @period.party) %>
13
+ <%=image_detour_to(@period.party.icon, "#{l(@period.party.to_sym)} #{@period.party.name}", :controller => @period.party.controller, :action => :edit, :id => @period.party) %>
14
14
  <% end %>
15
15
  </p>
16
16
 
@@ -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
+ <%= link_to l(:back), :action => 'show', :id => @period %>
7
8
  <% end %>
8
9
 
9
- <%= link_to l(:back), :action => 'show', :id => @period %>
10
10
  </div>
@@ -2,12 +2,11 @@
2
2
 
3
3
  <tr valign="top">
4
4
  <td>
5
- <%= image_detour_to('add.png', l(:new_task), nil, :controller => 'tasks', :action => :new, :task => {:backlog_id => @backlog.id, :period_id => @period.id})%>
5
+ <%= image_detour_to('add.png', l(:new_task), :controller => 'tasks', :action => :new, :task => {:backlog_id => @backlog.id, :period_id => @period && @period.id})%>
6
6
  </td>
7
- <td colspan="4" valign="top">
7
+ <td colspan="4" style="vertical-align: middle">
8
8
  <h5>
9
- <%=h backlog.name %>
10
- <%=image_detour_to("clipboard.png", l(:backlog), nil, :controller => 'backlogs', :action => :edit, :id => @backlog) %>
9
+ <%=detour_to(h(backlog.name), :controller => 'backlogs', :action => :edit, :id => @backlog) %>
11
10
  </h5>
12
11
  </td>
13
12
  <td width="*"/>
@@ -16,9 +15,7 @@
16
15
  <th/>
17
16
  <th align="center">#</th>
18
17
  <th><%=l :task %></th>
19
- <th><%=l :start if @period.track_times? && @period.active? %></th>
20
- <% if @period.track_work? -%>
21
- <th><%=l :done %></th>
22
- <% end %>
18
+ <th><%=l :start if @backlog.track_times? && @tasks.find {|t|t.period && t.period.active?} %></th>
19
+ <th><%=l :done if @backlog.track_done? %></th>
23
20
  <th width="*"><% l :todo if @backlog.track_todo? %></th>
24
21
  </tr>
@@ -10,7 +10,7 @@
10
10
  <%= hidden_field 'task', 'backlog_id' %><%=h @task.backlog.name%>
11
11
  <% end %>
12
12
  <% if @task.backlog %>
13
- <%=image_detour_to('clipboard.png', "#{l(:backlog)} #{@task.backlog.name}", {:class => 'image-submit', :style => 'vertical-align: bottom'}, :controller => 'backlogs', :action => :edit, :id => @task.backlog) %>
13
+ <%=image_detour_to('clipboard.png', "#{l(:backlog)} #{@task.backlog.name}", {:controller => 'backlogs', :action => :edit, :id => @task.backlog}, {:class => 'image-submit', :style => 'vertical-align: bottom'}) %>
14
14
  <% end %>
15
15
  </p>
16
16
 
@@ -18,7 +18,7 @@
18
18
  <p><label for="task_period_id"><%=l :period%></label><br/>
19
19
  <%= select 'task', 'period_id', [['', '']] + @periods.map{|p| [p.name, p.id]}, {}, :onchange => "form.action = '#{url_for}'; form.submit();" %>
20
20
  <% if @task.period %>
21
- <%=image_detour_to(@task.period.party.to_sym.to_s + '.png', "#{l(@task.period.party.to_sym)} #{@task.period.party.name}", nil, :controller => @task.period.party.to_s, :action => :edit, :id => @task.period.party) %>
21
+ <%=image_detour_to('period.png', "#{l :period} #{@task.period.name}", :controller => 'periods', :action => :edit, :id => @task.period) %>
22
22
  <% end %>
23
23
  <%=detour_to l(:new_period), :controller => 'periods', :action => :new %>
24
24
  </p>
@@ -8,7 +8,7 @@
8
8
  <% end %>
9
9
  </td>
10
10
  <td align="left" valign="top" width="1" nowrap="true">
11
- <%= @task.position if @task.depth == 0 %>
11
+ <%=detour_to @task.position.to_s, :controller => 'tasks', :action => :edit, :id => @task.id if @task.depth == 0 %>
12
12
  <%= ("&nbsp;" * @task.depth * 4) if @task.depth > 0 %>
13
13
  <%= l(@task.resolution.downcase) if @task.finished_at %>
14
14
  <%= "-" if @task.children.size > 0 %>
@@ -72,12 +72,12 @@
72
72
  <% if @task.active? %>
73
73
  <% if @task.loggable? %>
74
74
  <% unless @task.work_started? %>
75
- <%= image_button_to('arrow_right.png', l(:move_to_next_period), :controller => 'tasks', :action => :move_to_next_period, :id => @task)%>
76
- <%= image_button_to('ernes_stop.png', l(:abort), :controller => 'tasks', :action => :abort, :id => @task)%>
75
+ <%= image_detour_to('arrow_right.png', l(:move_to_next_period), {:controller => 'tasks', :action => :move_to_next_period, :id => @task}, nil, true)%>
76
+ <%= image_detour_to('ernes_stop.png', l(:abort), {:controller => 'tasks', :action => :abort, :id => @task}, nil, true)%>
77
77
  <% end %>
78
78
  <% end %>
79
79
  <% elsif not @task.period.passed? && @task.leaf? %>
80
- <%=image_button_to('/images/eraser.png', l(:reopen), :controller => 'tasks', :action => :reopen, :id => @task) %>
80
+ <%=image_detour_to('/images/eraser.png', l(:reopen), {:controller => 'tasks', :action => :reopen, :id => @task}, nil, true) %>
81
81
  <% end -%>
82
82
  <% end -%>
83
83
  </td>
@@ -1,7 +1,5 @@
1
1
  <div id="spotlight">
2
- <h1>Editing task</h1>
3
-
4
- <%=h @task.inspect%>
2
+ <% @page_title = "#{l :editing} #{l :task}" %>
5
3
 
6
4
  <% form_tag :action => 'update', :id => @task do %>
7
5
  <%= render :partial => 'form' %>
@@ -1,3 +1,3 @@
1
- <%=image_detour_to('hammer.png', l(:weekly_work_sheet), nil, :controller => 'works', :action => :weekly_work_sheet)%>
1
+ <%=image_detour_to('hammer.png', l(:weekly_work_sheet), :controller => 'works', :action => :weekly_work_sheet)%>
2
2
  <%=link_to(image_tag(url_for("hammer.png"), :alt => l(:daily_work_sheet), :title => l(:daily_work_sheet), :class => 'image-submit'), :controller => 'works', :action => :daily_work_sheet)%>
3
3
  <%=link_to(image_tag(url_for("hammer.png"), :alt => l(:edit_works), :title => l(:edit_works), :class => 'image-submit'), :controller => 'periods', :action => 'list_work', :id => (@period ? @period.id : (@backlog && @backlog.periods.first ? @backlog.periods.first.id : nil)))%>
@@ -20,7 +20,7 @@
20
20
  <% day_total += @work.hours if @work %>
21
21
  <tr>
22
22
  <td>
23
- <%=image_detour_to('period.png', l(:period), nil, :controller => 'periods', :action => :show, :id => @work.task.period) %>
23
+ <%=image_detour_to('period.png', l(:period), :controller => 'periods', :action => :show, :id => @work.task.period) %>
24
24
  </td>
25
25
  <td>
26
26
  <form>
data/lang/en.yaml CHANGED
@@ -72,6 +72,7 @@ started_at: Started at
72
72
  started_tasks: Started tasks
73
73
  sunday: Sunday
74
74
  task: Task
75
+ tasks: Tasks
75
76
  thursday: Thursday
76
77
  todo: Todo
77
78
  totals: Totals
data/lang/no.yaml CHANGED
@@ -71,6 +71,7 @@ start_work: Start arbeid
71
71
  started_at: Start tid
72
72
  sunday: Søndag
73
73
  task: Oppgave
74
+ tasks: Oppgaver
74
75
  thursday: Torsdag
75
76
  todo: Igjen
76
77
  totals: Totalt
@@ -5,10 +5,12 @@ first:
5
5
  backlog_id: 1
6
6
  period_id: 1
7
7
  description: first task
8
+ position: 1
8
9
  another:
9
10
  id: 2
10
11
  created_at: 2007-06-12
11
12
  backlog_id: 1
12
13
  period_id: 2
13
14
  description: second task
15
+ position: 2
14
16
 
@@ -56,6 +56,9 @@ class TasksControllerTest < Test::Unit::TestCase
56
56
 
57
57
  post :create, :task => {:description => 'an important task', :backlog_id => '2', :period_id => '2'}
58
58
 
59
+ task = assigns(:task)
60
+ assert_equal [], task.errors.full_messages
61
+
59
62
  assert_response :redirect
60
63
  assert_redirected_to :controller => 'periods', :action => 'show', :id => Period.find(2)
61
64
 
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: backlog
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.2.1
7
- date: 2007-07-31 00:00:00 +02:00
6
+ version: 0.3.0
7
+ date: 2007-08-02 00:00:00 +02:00
8
8
  summary: Application to aid collecting, processing, organizing, reviewing and doing tasks.
9
9
  require_paths:
10
10
  - lib
@@ -226,6 +226,7 @@ files:
226
226
  - config/environments/datek_production.rb
227
227
  - LICENSE_LOCALIZATION
228
228
  - README.txt
229
+ - doc
229
230
  - Manifest.txt
230
231
  - vendor
231
232
  - vendor/plugins