backlog 0.21.1 → 0.21.2

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 CHANGED
@@ -1,3 +1,22 @@
1
+ == 0.21.2 2008-02-08
2
+
3
+ === Features
4
+
5
+ * Added ability to override the public application URL in the backlog.conf config file.
6
+
7
+ === Fixes
8
+
9
+ * Changed so that End Work -> Start Work operations don't generate overlapping work records by default.
10
+ * Added checking of return code to the 'setup_unix' task so the script fails unless it can successfully
11
+ change to the postgresql administration user.
12
+ * Added "debug" and "bsd" options to administration script.
13
+ The "debug" option turns on tracing in the rake scripts.
14
+ The "bsd" option changes the postgresql admin user from "postgres" to "pgsql".
15
+ * Fixed bug 16427: http://rubyforge.org/tracker/index.php?func=detail&aid=16427&group_id=3829&atid=14750
16
+ When postponing the first task to a new sprint, the sprint is created and the task is postponed directly.
17
+ A white screen is displayed during the dialog, but it was the best solution I could find.
18
+ * Fixed the default host/port for Work Lock Nag email from localhost:3000 to read from the local network settings and backlog.conf.
19
+
1
20
  == 0.21.1 2008-02-04
2
21
 
3
22
  === Features
@@ -71,7 +71,7 @@ class ApplicationController < ActionController::Base
71
71
  end
72
72
 
73
73
  def rjs_detour_to(options)
74
- store_detour(params)
74
+ store_detour(params, request.post?)
75
75
  rjs_redirect_to(options)
76
76
  end
77
77
 
@@ -80,7 +80,8 @@ class ApplicationController < ActionController::Base
80
80
  render :template => 'redirect', :layout => false
81
81
  end
82
82
 
83
- def store_detour(options)
83
+ def store_detour(options, post = false)
84
+ options[:request_method] = :post if post
84
85
  if session[:detours] && session[:detours].last == options
85
86
  logger.debug "duplicate detour: #{options}"
86
87
  return
@@ -102,7 +103,12 @@ class ApplicationController < ActionController::Base
102
103
  def back_or_redirect_to(options)
103
104
  if session[:detours]
104
105
  detour = pop_detour
105
- redirect_to detour
106
+ post = detour.delete(:request_method) == :post
107
+ if post
108
+ redirect_to_post(detour)
109
+ else
110
+ redirect_to detour
111
+ end
106
112
  else
107
113
  redirect_to options
108
114
  end
@@ -143,7 +149,7 @@ class ApplicationController < ActionController::Base
143
149
  # TODO (uwe): This does not scale!
144
150
  #periods = Period.find(:all).select {|period| period.active_or_future?(true) && period.party.includes?(user)}
145
151
  periods = Period.find_active_or_future(true)
146
-
152
+
147
153
 
148
154
  @sidebars = periods.sort_by {|p| p.required_speed}.reverse.map do |period|
149
155
  content = '<ul>'
@@ -186,4 +192,16 @@ class ApplicationController < ActionController::Base
186
192
  User.find_by_id(user_id) if user_id
187
193
  end
188
194
 
189
- end
195
+ def redirect_to_post(options)
196
+ url = url_for options
197
+ render :text => <<EOF, :layout => false
198
+ <html>
199
+ <body onload="document.getElementById('form').submit()">
200
+ <form id="form" action="#{url}" method="POST">
201
+ </form>
202
+ </body>
203
+ </html>
204
+ EOF
205
+ end
206
+
207
+ end
@@ -0,0 +1,207 @@
1
+ class ApplicationController < ActionController::Base
2
+ include Localization
3
+ include UserSystem
4
+ include ApplicationHelper
5
+ include ActionView::Helpers::TagHelper
6
+ include ActionView::Helpers::JavaScriptHelper
7
+ include ActionView::Helpers::PrototypeHelper
8
+ include ActionView::Helpers::ScriptaculousHelper
9
+ include UrlForFix
10
+
11
+ layout :determine_layout
12
+ helper :user
13
+ before_filter :store_detour_from_params
14
+ before_filter :authenticate_user
15
+ before_filter :populate_layout
16
+
17
+ def initialize
18
+ @application_title = l :backlog
19
+ @application_description = l :backlog_description
20
+ end
21
+
22
+ def self.in_place_edit_for(object, attribute, options = {})
23
+ define_method("set_#{object}_#{attribute}") do
24
+ @item = object.to_s.camelize.constantize.find(params[:id])
25
+ @item.update_attribute(attribute, params[:value])
26
+ render :text => @item.send(attribute).to_s
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def determine_layout
33
+ if request.accepts.find {|mt| mt == 'xml'}
34
+ 'wap'
35
+ else
36
+ # Firefox
37
+ #<Mime::Type:0xb79cd374 @synonyms=["application/xhtml+xml"], @string="text/html", @symbol=:html>
38
+ #<Mime::Type:0xb79cd1e4 @synonyms=["text/xml", "application/x-xml"], @string="application/xml", @symbol=:xml>
39
+ #<Mime::Type:0xb746d16c @synonyms=[], @string="image/png", @symbol=nil>
40
+ #<Mime::Type:0xb79cd3ec @synonyms=[], @string="text/plain", @symbol=:text>
41
+ #<Mime::Type:0xb79cd43c @synonyms=[], @string="*/*", @symbol=:all>
42
+
43
+ # nokia N80
44
+ #<Mime::Type:0xb79ab374 @synonyms=["application/xhtml+xml"], @string="text/html", @symbol=:html>
45
+ #<Mime::Type:0xb7308408 @synonyms=[], @string="text/css", @symbol=nil>
46
+ #<Mime::Type:0xb73082f0 @synonyms=[], @string="text/x-vcard", @symbol=nil>
47
+ #<Mime::Type:0xb73081ec @synonyms=[], @string="text/x-vcalendar", @symbol=nil>
48
+ #<Mime::Type:0xb73080d4 @synonyms=[], @string="image/gif", @symbol=nil>
49
+ #<Mime::Type:0xb7307fd0 @synonyms=[], @string="image/vnd.wap.wbmp", @symbol=nil>
50
+ #<Mime::Type:0xb79ab43c @synonyms=[], @string="*/*", @symbol=:all>
51
+
52
+ # SonyEricson K810i
53
+ #<Mime::Type:0xb72509d4 @synonyms=[], @string="multipart/mixed", @symbol=nil>
54
+ #<Mime::Type:0xb7250934 @synonyms=[], @string="application/vnd.wap.multipart.mixed", @symbol=nil>
55
+ #<Mime::Type:0xb7250880 @synonyms=[], @string="application/vnd.wap.xhtml+xml", @symbol=nil>
56
+ #<Mime::Type:0xb79ab374 @synonyms=["application/xhtml+xml"], @string="text/html", @symbol=:html>
57
+ #<Mime::Type:0xb72507cc @synonyms=[], @string="text/vnd.wap.wml", @symbol=nil>
58
+ #<Mime::Type:0xb73082f0 @synonyms=[], @string="text/x-vcard", @symbol=nil>
59
+ #<Mime::Type:0xb73081ec @synonyms=[], @string="text/x-vcalendar", @symbol=nil>
60
+ #<Mime::Type:0xb73080d4 @synonyms=[], @string="image/gif", @symbol=nil>
61
+ #<Mime::Type:0xb7307fd0 @synonyms=[], @string="image/vnd.wap.wbmp", @symbol=nil>
62
+ #<Mime::Type:0xb79ab43c @synonyms=[], @string="*/*", @symbol=:all>
63
+
64
+ 'mwrt002'
65
+ end
66
+ end
67
+
68
+ def detour_to(options)
69
+ store_detour(params)
70
+ redirect_to(options)
71
+ end
72
+
73
+ def rjs_detour_to(options)
74
+ store_detour(params, request.post?)
75
+ rjs_redirect_to(options)
76
+ end
77
+
78
+ def rjs_redirect_to(options)
79
+ @options = options
80
+ render :template => 'redirect', :layout => false
81
+ end
82
+
83
+ def store_detour(options, post = false)
84
+ options[:request_method] = :post if post
85
+ if session[:detours] && session[:detours].last == options
86
+ logger.debug "duplicate detour: #{options}"
87
+ return
88
+ end
89
+ logger.debug "adding detour: #{options}"
90
+ session[:detours] ||= []
91
+ session[:detours] << options
92
+ end
93
+
94
+ def store_detour_from_params
95
+ if params[:detour]
96
+ store_detour(params[:detour])
97
+ end
98
+ if params[:return_from_detour] && session[:detours]
99
+ pop_detour
100
+ end
101
+ end
102
+
103
+ def back_or_redirect_to(options)
104
+ if session[:detours]
105
+ detour = pop_detour
106
+ post = detour.delete(:request_method) == :post
107
+ if post
108
+ redirect_to_post(detour)
109
+ else
110
+ redirect_to detour
111
+ end
112
+ else
113
+ redirect_to options
114
+ end
115
+ end
116
+
117
+ def pop_detour
118
+ detours = session[:detours]
119
+ return nil unless detours
120
+ detour = detours.pop
121
+ logger.debug "popped detour: #{detour.inspect} #{session[:detours].size} more"
122
+ if detours.empty?
123
+ session[:detours] = nil
124
+ end
125
+ detour
126
+ end
127
+ private :pop_detour
128
+
129
+ def populate_shortcuts
130
+ @shortcuts = [
131
+ {:key => 'Alt-N', :function => :new_task, :options => {:controller => 'tasks', :action => 'new', :period_id => (@period ? @period.id : (@backlog && @backlog.periods.first ? @backlog.periods.first.id : nil))}},
132
+ {:key => 'Alt-Shift-N', :function => :new_period, :options => {:controller => 'periods', :action => 'new'}},
133
+ {:key => 'Alt-Ctrl-N', :function => :new_backlog, :options => {:controller => 'backlogs', :action => 'new'}},
134
+ {:key => 'Alt-Ctrl-G', :function => :new_group, :options => {:controller => 'groups', :action => :new}},
135
+ {:key => "Alt-#{l :up}", :function => :up},
136
+ {:key => "Alt-#{l :down}", :function => :down},
137
+ {:key => "Alt-Shift-#{l :left}", :function => :move_to_top},
138
+ {:key => "Alt-Shift-#{l :right}", :function => :move_to_bottom},
139
+ {:key => 'Alt-X', :function => :complete},
140
+ {:key => 'Alt-Q', :function => :reopen},
141
+ ]
142
+ end
143
+
144
+ def populate_layout
145
+ return true if request.path_parameters[:action] =~ /_no_layout$/
146
+
147
+ populate_shortcuts
148
+
149
+ # TODO (uwe): This does not scale!
150
+ #periods = Period.find(:all).select {|period| period.active_or_future?(true) && period.party.includes?(user)}
151
+ periods = Period.find_active_or_future(true)
152
+
153
+
154
+ @sidebars = periods.sort_by {|p| p.required_speed}.reverse.map do |period|
155
+ content = '<ul>'
156
+ period.tasks.select {|task| task.in_list? }[0...5].map do |task|
157
+ "<li>#{task.description}</li>"
158
+ end.each do |period_link|
159
+ content << "#{period_link}"
160
+ end
161
+ content << "</ul>\n"
162
+ content << drop_receiving_element("sidebar_#{period.id}",
163
+ :url => with_detour({:action => "move_task_to_period", :period_id => period.id, :layout => false}),
164
+ :accept => "tasks", :loading => "", :complete => "",
165
+ :hoverclass => 'highlight')
166
+
167
+ { :id => period.id,
168
+ :title => "#{period.party.name}##{period.position} (#{'%0.1f' % period.required_speed})",
169
+ :options => {:controller => 'periods', :action => :show, :id => period},
170
+ :content => content
171
+ }
172
+ end
173
+ started_tasks = Task.find_started
174
+ if not started_tasks.empty?
175
+ links = started_tasks.map do |task|
176
+ "<li><a href=\"#{url_for :controller => 'tasks', :action => :list_started, :id => task.id}\">#{task.description}</a></li>"
177
+ end
178
+ @sidebars.unshift({ :title => l(:started_tasks),
179
+ :options => {:controller => 'tasks', :action => :list_started},
180
+ :content => "<ul>#{links}"
181
+ })
182
+ end
183
+ end
184
+
185
+ private
186
+
187
+ def user_id
188
+ session[:user_id]
189
+ end
190
+
191
+ def user
192
+ User.find_by_id(user_id) if user_id
193
+ end
194
+
195
+ def redirect_to_post(options)
196
+ url = url_for options
197
+ render :text => <<EOF, :layout => false
198
+ <html>
199
+ <body onload="alert('submitting');document.getElementById('form').submit()">
200
+ <form id="form" action="#{url}" method="POST">
201
+ </form>
202
+ </body>
203
+ </html>
204
+ EOF
205
+ end
206
+
207
+ end
@@ -130,12 +130,16 @@ class PeriodsController < ApplicationController
130
130
  next_task = @task.higher_item ? @task.higher_item : @task.lower_item ? @task.lower_item : @task
131
131
  @task.move_to_period period
132
132
  load_tasks(@task.period)
133
- render :action => :move_task_to_period, :layout => false
133
+ if request.xhr?
134
+ render :action => :move_task_to_period, :layout => false
135
+ else
136
+ redirect_to :action => :show, :id => @task.period, :task_id => @task.id, :layout => false
137
+ end
134
138
  else
135
- rjs_detour_to :controller => 'periods', :action => :new, :period => {:party_id => @task.period.party_id}, :layout => false
139
+ rjs_detour_to :action => :new, :period => {:party_id => @task.period.party_id}, :layout => false
136
140
  end
137
141
  else
138
- redirect_to :controller => 'periods', :action => :show, :id => @task.period, :task_id => @task.id, :layout => false
142
+ redirect_to :action => :show, :id => @task.period, :task_id => @task.id, :layout => false
139
143
  end
140
144
  end
141
145
 
data/app/models/task.rb CHANGED
@@ -348,17 +348,15 @@ class Task < ActiveRecord::Base
348
348
  new_work.task = self
349
349
 
350
350
  new_work.started_at = Time.previous_quarter
351
- if works.size > 0
352
351
  if current_user
353
- last_work = works.select {|work| work.user == current_user}.last
354
- end
355
- unless last_work
356
- last_work = works.select {|work| work.user.nil?}.last
352
+ last_work = current_user.works.last
353
+ else
354
+ last_work = Work.find(:first, :order => 'compeleted_at DESC')
357
355
  end
358
356
  if last_work && last_work.completed_at > new_work.started_at
359
357
  new_work.started_at = last_work.completed_at
360
358
  end
361
- end
359
+
362
360
  new_work.user = current_user
363
361
  new_work.work_account_id = work_account.id
364
362
  new_work.save!
data/app/models/user.rb CHANGED
@@ -9,6 +9,7 @@ class User < Party
9
9
  # even if they follow the defaults since ClassTableInheritanceInRails breaks it.
10
10
  has_and_belongs_to_many :groups, :join_table => "groups_users", :foreign_key => "user_id", :association_foreign_key => 'group_id'
11
11
  has_and_belongs_to_many :work_lock_subscribers, :class_name => 'User', :join_table => "user_work_lock_subscriptions", :foreign_key => "user_id", :association_foreign_key => 'subscriber_user_id'
12
+ has_many :works, :foreign_key => :user_id, :order => :completed_at
12
13
  has_many :work_locks, :foreign_key => :user_id, :order => :end_on
13
14
 
14
15
  attr_accessor :password_needs_confirmation
@@ -1,16 +1,18 @@
1
1
  class WorkLockNagger
2
2
  include ActionController::UrlWriter
3
3
 
4
- puts "Loading class"
5
-
6
4
  def initialize
7
- puts "Worker initialized"
8
5
  end
9
6
 
10
7
  def nag
11
- puts "Nag called"
8
+ sleep 1.minute
9
+ puts "Work Lock Nagger started"
12
10
  begin
13
- url = url_for(:host => 'localhost', :port => 3000, :controller => 'works', :action => :weekly_work_sheet_by_work_account)
11
+ host = Socket::gethostbyname('localhost')[1][1]
12
+ config = YAML::load(ERB.new(IO.read(APP_CONFIG_FILE)).result) || {}
13
+ port = config[:port] || 3000
14
+
15
+ url = url_for(:host => host, :port => port, :controller => 'works', :action => :weekly_work_sheet_by_work_account)
14
16
  rescue Exception => e
15
17
  puts e.message
16
18
  puts e.backtrace
data/bin/backlog CHANGED
@@ -114,23 +114,31 @@ when 'status'
114
114
  exit 3
115
115
  end
116
116
  when 'setup_unix'
117
+ puts "Starting setup on #{RUBY_PLATFORM}"
118
+ bsd = ARGV[1..-1].include? 'bsd'
119
+ debug = ARGV[1..-1].include? 'debug'
120
+ pg_admin_user = bsd ? 'pgsql' : 'postgres'
117
121
  current_user = `whoami`
118
- users = `su - postgres -c "echo '\\du' | psql template1"`
122
+ users = `su - #{pg_admin_user} -c "echo '\\du' | psql template1"`
123
+ raise "Could not list users: #{$? >> 8}:#{$? & 0xff}" unless ($? >> 8) == 0
119
124
  unless users =~ /root/
120
125
  puts users
121
126
  createuser_command = `which createuser`.chomp
122
- puts `su - postgres -c "#{createuser_command} -dAR #{current_user}"`
127
+ puts `su - #{pg_admin_user} -c "#{createuser_command} -dAR #{current_user}"`
123
128
  end
124
- dbs = `su - postgres -c "echo '\\l' | psql template1"`
129
+ dbs = `su - #{pg_admin_user} -c "echo '\\l' | psql template1"`
125
130
  unless dbs =~ /#{APPLICATION}_production/
126
131
  puts dbs
127
132
  createdb_command = `which createdb`.chomp
128
- puts `su - postgres -c "#{createdb_command} #{APPLICATION}_production"`
133
+ puts `su - #{pg_admin_user} -c "#{createdb_command} #{APPLICATION}_production"`
134
+ raise "Could not create database: #{$? >> 8}:#{$? & 0xff}" unless ($? >> 8) == 0
129
135
  end
136
+ FileUtils.mkdir_p INSTALL_DIR
130
137
  Dir.chdir INSTALL_DIR
131
138
  Dir.mkdir LOG_DIR unless File.exists? LOG_DIR
132
139
  ENV['RAILS_ENV'] = 'production'
133
- puts `rake db:migrate`
140
+ puts `rake db:migrate #{'--trace' if debug}`
141
+ raise "Could not migrate database: #{$? >> 8}:#{$? & 0xff}" unless ($? >> 8) == 0
134
142
 
135
143
  # TODO: provide startup information based on launchd in OS X versions >= 10.4
136
144
  if File.directory? '/etc/init.d'
@@ -144,7 +152,7 @@ when 'setup_unix'
144
152
  `su - -c "chkconfig #{APPLICATION} on"`
145
153
  puts
146
154
  else
147
- puts "Usage: #$0 {start|stop|restart|status|setup_unix}"
155
+ puts "Usage: #$0 {start|stop|restart|status|setup_unix [bsd] [debug]}"
148
156
  exit 1
149
157
  end
150
158
 
data/etc/backlog.conf CHANGED
@@ -1,9 +1,17 @@
1
+ # Uncomment the following line to set the public url for this server.
2
+ # Default url is http://localhost:3000/
3
+
4
+ # Examples:
5
+ # app_url: http://localhost:3000/
6
+ # app_url: http://myhost.mydomain/
7
+ # app_url: http://myhost.mydomain/backlog
8
+
1
9
  # Uncomment the following line to override the network port to listen on.
2
10
  # Default port is 3000.
3
11
 
4
12
  # port: 3000
5
13
 
6
- # Uncomment one of the following sections to override the database connection settings.
14
+ # Uncomment _one_ of the following sections to override the database connection settings.
7
15
 
8
16
  # database:
9
17
  # adapter: postgresql
@@ -126,15 +126,19 @@ class PeriodsControllerTest < Test::Unit::TestCase
126
126
 
127
127
  post :move_task_to_next_period, :id => tasks(:another).id
128
128
 
129
- assert_response :success
129
+ assert_response :redirect
130
130
 
131
- after = Task.find(tasks(:another).id)
132
- assert_equal tasks(:another).period_id, after.period_id
131
+ check_move_effects(before, :future)
132
+ end
133
+
134
+ def test_move_task_to_next_period_xhr
135
+ before = Task.find(tasks(:another).id)
133
136
 
134
- new_task = Task.find_by_period_id_and_previous_task_id(periods(:future).id, before.id)
135
- assert_nil new_task.finished_at
136
- assert_nil new_task.resolution
137
- assert_equal 1, new_task.position
137
+ xhr :post, :move_task_to_next_period, :id => tasks(:another).id
138
+
139
+ assert_response :success
140
+
141
+ check_move_effects(before, :future)
138
142
  end
139
143
 
140
144
  def test_move_task_to_next_period_from_past
@@ -143,15 +147,20 @@ class PeriodsControllerTest < Test::Unit::TestCase
143
147
 
144
148
  post :move_task_to_next_period, :id => task.id
145
149
 
146
- assert_response :success
150
+ assert_response :redirect
147
151
 
148
- after = Task.find(task.id)
149
- assert_equal task.period_id, after.period_id
152
+ check_move_effects(before, :active)
153
+ end
154
+
155
+ def test_move_task_to_next_period_from_past_xhr
156
+ task = tasks(:first)
157
+ before = Task.find(task.id)
150
158
 
151
- new_task = Task.find_by_period_id_and_previous_task_id(periods(:active).id, task.id)
152
- assert_nil new_task.finished_at
153
- assert_nil new_task.resolution
154
- assert_equal 1, new_task.position
159
+ xhr :post, :move_task_to_next_period, :id => task.id
160
+
161
+ assert_response :success
162
+
163
+ check_move_effects(before, :active)
155
164
  end
156
165
 
157
166
  def test_move_to_next_period_at_end
@@ -175,17 +184,20 @@ class PeriodsControllerTest < Test::Unit::TestCase
175
184
 
176
185
  post :move_task_to_next_period, :id => before.id
177
186
 
178
- assert_response :success
187
+ assert_response :redirect
179
188
 
180
- after = Task.find(before.id)
181
- assert_equal before.period_id, after.period_id
182
- assert_equal Task::POSTPONED, after.resolution
183
- assert_not_nil after.finished_at
189
+ check_move_effects(before, :active)
190
+ end
191
+
192
+ def test_move_to_next_period_from_ancient_xhr
193
+ before = tasks(:in_ancient)
194
+ previous_last_id = Task.find(:first, :order => 'id DESC').id
195
+
196
+ xhr :post, :move_task_to_next_period, :id => before.id
197
+
198
+ assert_response :success
184
199
 
185
- new = Task.find(:first, :order => 'id DESC', :conditions => "id > #{previous_last_id}")
186
- assert_not_nil new
187
- assert_equal before.id, new.previous_task_id
188
- assert_equal 1, new.position
200
+ check_move_effects(before, :active)
189
201
  end
190
202
 
191
203
  def test_move_task_to_period_back_to_earlier_period
@@ -253,4 +265,23 @@ class PeriodsControllerTest < Test::Unit::TestCase
253
265
  assert_nil after.resolution
254
266
  end
255
267
 
268
+ private
269
+
270
+ def check_move_effects(before, period_sym)
271
+ after = Task.find(before.id)
272
+ assert_equal before.period_id, after.period_id
273
+ assert_equal Task::POSTPONED, after.resolution
274
+ assert_not_nil after.finished_at
275
+
276
+ newest_task = Task.find(:first, :order => 'id DESC')
277
+ new_task = Task.find_by_period_id_and_previous_task_id(periods(period_sym).id, before.id)
278
+ assert_not_nil newest_task
279
+ assert_not_nil new_task
280
+ assert_equal newest_task.id, new_task.id
281
+ assert_equal before.previous_task_id || before.id, new_task.previous_task_id
282
+ assert_nil new_task.finished_at
283
+ assert_nil new_task.resolution
284
+ assert_equal 1, new_task.position
285
+ end
286
+
256
287
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: backlog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.21.1
4
+ version: 0.21.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Uwe Kubosch
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-02-05 00:00:00 +01:00
12
+ date: 2008-02-08 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -64,7 +64,7 @@ dependencies:
64
64
  requirements:
65
65
  - - ">="
66
66
  - !ruby/object:Gem::Version
67
- version: 1.4.0
67
+ version: 1.5.0
68
68
  version:
69
69
  description: Backlog is a tool to help you collect and organize all your tasks, whether you are a single person or a small or large group. A time keeping module is also included to track time spent on the different tasks.
70
70
  email: uwe@kubosch.no
@@ -209,6 +209,7 @@ files:
209
209
  - app/controllers/welcome_controller.rb
210
210
  - app/controllers/backlogs_controller.rb
211
211
  - app/controllers/estimates_controller.rb
212
+ - app/controllers/application.rb~
212
213
  - app/controllers/application.rb
213
214
  - app/controllers/parties_controller.rb
214
215
  - app/controllers/periods_controller.rb