mirror of
https://github.com/TracksApp/tracks.git
synced 2025-09-22 05:50:47 +02:00
Merge branch 'master' into rails4
Conflicts: Gemfile.lock config/routes.rb
This commit is contained in:
commit
4a485558e2
51 changed files with 5475 additions and 5015 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -3,6 +3,8 @@
|
||||||
.dotest
|
.dotest
|
||||||
.idea
|
.idea
|
||||||
.rvmrc
|
.rvmrc
|
||||||
|
.ruby-gemset
|
||||||
|
.ruby-version
|
||||||
.sass-cache/
|
.sass-cache/
|
||||||
.yardoc
|
.yardoc
|
||||||
/.bundle
|
/.bundle
|
||||||
|
|
68
Gemfile.lock
68
Gemfile.lock
|
@ -9,9 +9,15 @@ GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
RedCloth (4.2.9)
|
RedCloth (4.2.9)
|
||||||
|
<<<<<<< HEAD
|
||||||
aasm (3.0.18)
|
aasm (3.0.18)
|
||||||
actionmailer (4.0.0.rc1)
|
actionmailer (4.0.0.rc1)
|
||||||
actionpack (= 4.0.0.rc1)
|
actionpack (= 4.0.0.rc1)
|
||||||
|
=======
|
||||||
|
aasm (3.0.19)
|
||||||
|
actionmailer (3.2.13)
|
||||||
|
actionpack (= 3.2.13)
|
||||||
|
>>>>>>> master
|
||||||
mail (~> 2.5.3)
|
mail (~> 2.5.3)
|
||||||
actionpack (4.0.0.rc1)
|
actionpack (4.0.0.rc1)
|
||||||
activesupport (= 4.0.0.rc1)
|
activesupport (= 4.0.0.rc1)
|
||||||
|
@ -36,7 +42,11 @@ GEM
|
||||||
tzinfo (~> 0.3.37)
|
tzinfo (~> 0.3.37)
|
||||||
acts_as_list (0.2.0)
|
acts_as_list (0.2.0)
|
||||||
activerecord (>= 3.0)
|
activerecord (>= 3.0)
|
||||||
|
<<<<<<< HEAD
|
||||||
arel (4.0.0)
|
arel (4.0.0)
|
||||||
|
=======
|
||||||
|
arel (3.0.2)
|
||||||
|
>>>>>>> master
|
||||||
aruba (0.5.3)
|
aruba (0.5.3)
|
||||||
childprocess (>= 0.3.6)
|
childprocess (>= 0.3.6)
|
||||||
cucumber (>= 1.1.1)
|
cucumber (>= 1.1.1)
|
||||||
|
@ -73,6 +83,10 @@ GEM
|
||||||
capybara (>= 1.1.2)
|
capybara (>= 1.1.2)
|
||||||
cucumber (>= 1.1.8)
|
cucumber (>= 1.1.8)
|
||||||
nokogiri (>= 1.5.0)
|
nokogiri (>= 1.5.0)
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
rails (~> 3.0)
|
||||||
|
>>>>>>> master
|
||||||
database_cleaner (1.0.1)
|
database_cleaner (1.0.1)
|
||||||
diff-lcs (1.2.4)
|
diff-lcs (1.2.4)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
|
@ -83,33 +97,49 @@ GEM
|
||||||
factory_girl_rails (4.2.1)
|
factory_girl_rails (4.2.1)
|
||||||
factory_girl (~> 4.2.0)
|
factory_girl (~> 4.2.0)
|
||||||
railties (>= 3.0.0)
|
railties (>= 3.0.0)
|
||||||
ffi (1.8.1)
|
ffi (1.9.0)
|
||||||
gherkin (2.12.0)
|
gherkin (2.12.0)
|
||||||
multi_json (~> 1.3)
|
multi_json (~> 1.3)
|
||||||
hike (1.2.2)
|
hike (1.2.3)
|
||||||
htmlentities (4.3.1)
|
htmlentities (4.3.1)
|
||||||
|
<<<<<<< HEAD
|
||||||
i18n (0.6.4)
|
i18n (0.6.4)
|
||||||
jquery-rails (2.2.1)
|
jquery-rails (2.2.1)
|
||||||
railties (>= 3.0, < 5.0)
|
railties (>= 3.0, < 5.0)
|
||||||
thor (>= 0.14, < 2.0)
|
thor (>= 0.14, < 2.0)
|
||||||
|
=======
|
||||||
|
i18n (0.6.1)
|
||||||
|
journey (1.0.4)
|
||||||
|
jquery-rails (3.0.1)
|
||||||
|
railties (>= 3.0, < 5.0)
|
||||||
|
thor (>= 0.14, < 2.0)
|
||||||
|
json (1.8.0)
|
||||||
|
>>>>>>> master
|
||||||
libv8 (3.11.8.17)
|
libv8 (3.11.8.17)
|
||||||
mail (2.5.4)
|
mail (2.5.4)
|
||||||
mime-types (~> 1.16)
|
mime-types (~> 1.16)
|
||||||
treetop (~> 1.4.8)
|
treetop (~> 1.4.8)
|
||||||
metaclass (0.0.1)
|
metaclass (0.0.1)
|
||||||
mime-types (1.23)
|
mime-types (1.23)
|
||||||
|
<<<<<<< HEAD
|
||||||
minitest (4.7.4)
|
minitest (4.7.4)
|
||||||
mocha (0.14.0)
|
mocha (0.14.0)
|
||||||
metaclass (~> 0.0.1)
|
metaclass (~> 0.0.1)
|
||||||
multi_json (1.7.3)
|
multi_json (1.7.3)
|
||||||
|
=======
|
||||||
|
mocha (0.14.0)
|
||||||
|
metaclass (~> 0.0.1)
|
||||||
|
multi_json (1.7.6)
|
||||||
|
>>>>>>> master
|
||||||
mysql2 (0.3.11)
|
mysql2 (0.3.11)
|
||||||
nokogiri (1.5.9)
|
nokogiri (1.5.10)
|
||||||
polyglot (0.3.3)
|
polyglot (0.3.3)
|
||||||
rack (1.5.2)
|
rack (1.5.2)
|
||||||
rack-mini-profiler (0.1.26)
|
rack-mini-profiler (0.1.26)
|
||||||
rack (>= 1.1.3)
|
rack (>= 1.1.3)
|
||||||
rack-test (0.6.2)
|
rack-test (0.6.2)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
|
<<<<<<< HEAD
|
||||||
rails (4.0.0.rc1)
|
rails (4.0.0.rc1)
|
||||||
actionmailer (= 4.0.0.rc1)
|
actionmailer (= 4.0.0.rc1)
|
||||||
actionpack (= 4.0.0.rc1)
|
actionpack (= 4.0.0.rc1)
|
||||||
|
@ -123,23 +153,49 @@ GEM
|
||||||
railties (4.0.0.rc1)
|
railties (4.0.0.rc1)
|
||||||
actionpack (= 4.0.0.rc1)
|
actionpack (= 4.0.0.rc1)
|
||||||
activesupport (= 4.0.0.rc1)
|
activesupport (= 4.0.0.rc1)
|
||||||
|
=======
|
||||||
|
rails (3.2.13)
|
||||||
|
actionmailer (= 3.2.13)
|
||||||
|
actionpack (= 3.2.13)
|
||||||
|
activerecord (= 3.2.13)
|
||||||
|
activeresource (= 3.2.13)
|
||||||
|
activesupport (= 3.2.13)
|
||||||
|
bundler (~> 1.0)
|
||||||
|
railties (= 3.2.13)
|
||||||
|
rails_autolink (1.1.0)
|
||||||
|
rails (> 3.1)
|
||||||
|
railties (3.2.13)
|
||||||
|
actionpack (= 3.2.13)
|
||||||
|
activesupport (= 3.2.13)
|
||||||
|
rack-ssl (~> 1.3.2)
|
||||||
|
>>>>>>> master
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
thor (>= 0.18.1, < 2.0)
|
thor (>= 0.18.1, < 2.0)
|
||||||
rake (10.0.4)
|
rake (10.0.4)
|
||||||
|
<<<<<<< HEAD
|
||||||
|
=======
|
||||||
|
rdoc (3.12.2)
|
||||||
|
json (~> 1.4)
|
||||||
|
>>>>>>> master
|
||||||
ref (1.0.5)
|
ref (1.0.5)
|
||||||
rspec-expectations (2.13.0)
|
rspec-expectations (2.13.0)
|
||||||
diff-lcs (>= 1.1.3, < 2.0)
|
diff-lcs (>= 1.1.3, < 2.0)
|
||||||
rubyzip (0.9.9)
|
rubyzip (0.9.9)
|
||||||
safe_yaml (0.9.1)
|
safe_yaml (0.9.3)
|
||||||
sanitize (2.0.3)
|
sanitize (2.0.3)
|
||||||
nokogiri (>= 1.4.4, < 1.6)
|
nokogiri (>= 1.4.4, < 1.6)
|
||||||
sass (3.2.9)
|
sass (3.2.9)
|
||||||
|
<<<<<<< HEAD
|
||||||
sass-rails (4.0.0.rc1)
|
sass-rails (4.0.0.rc1)
|
||||||
railties (>= 4.0.0.beta, < 5.0)
|
railties (>= 4.0.0.beta, < 5.0)
|
||||||
|
=======
|
||||||
|
sass-rails (3.2.6)
|
||||||
|
railties (~> 3.2.0)
|
||||||
|
>>>>>>> master
|
||||||
sass (>= 3.1.10)
|
sass (>= 3.1.10)
|
||||||
sprockets-rails (~> 2.0.0.rc0)
|
sprockets-rails (~> 2.0.0.rc0)
|
||||||
tilt (~> 1.3)
|
tilt (~> 1.3)
|
||||||
selenium-webdriver (2.32.1)
|
selenium-webdriver (2.33.0)
|
||||||
childprocess (>= 0.2.5)
|
childprocess (>= 0.2.5)
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
rubyzip
|
rubyzip
|
||||||
|
@ -172,7 +228,7 @@ GEM
|
||||||
tolk (1.3.9)
|
tolk (1.3.9)
|
||||||
safe_yaml (~> 0.8)
|
safe_yaml (~> 0.8)
|
||||||
will_paginate
|
will_paginate
|
||||||
treetop (1.4.12)
|
treetop (1.4.14)
|
||||||
polyglot
|
polyglot
|
||||||
polyglot (>= 0.3.1)
|
polyglot (>= 0.3.1)
|
||||||
tzinfo (0.3.37)
|
tzinfo (0.3.37)
|
||||||
|
|
|
@ -34,8 +34,9 @@ var TracksForm = {
|
||||||
$('#default_project_name_id').val(name);
|
$('#default_project_name_id').val(name);
|
||||||
$('#project_name').html(name);
|
$('#project_name').html(name);
|
||||||
},
|
},
|
||||||
set_tag_list: function (name) {
|
set_tag_list_and_default_tag_list: function (name) {
|
||||||
$('input#tag_list').val(name);
|
$('input#tag_list').val(name);
|
||||||
|
$('input#initial_tag_list').val(name);
|
||||||
},
|
},
|
||||||
set_tag_list_for_multi_add: function (name) {
|
set_tag_list_for_multi_add: function (name) {
|
||||||
$('#multi_tag_list').val(name);
|
$('#multi_tag_list').val(name);
|
||||||
|
|
|
@ -21,6 +21,7 @@ class ApplicationController < ActionController::Base
|
||||||
before_filter :set_time_zone
|
before_filter :set_time_zone
|
||||||
before_filter :set_zindex_counter
|
before_filter :set_zindex_counter
|
||||||
before_filter :set_locale
|
before_filter :set_locale
|
||||||
|
append_before_filter :set_group_view_by
|
||||||
prepend_before_filter :login_required
|
prepend_before_filter :login_required
|
||||||
prepend_before_filter :enable_mobile_content_negotiation
|
prepend_before_filter :enable_mobile_content_negotiation
|
||||||
after_filter :set_charset
|
after_filter :set_charset
|
||||||
|
@ -291,4 +292,8 @@ class ApplicationController < ActionController::Base
|
||||||
render :template => 'todos/done'
|
render :template => 'todos/done'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_group_view_by
|
||||||
|
@group_view_by = params['_group_view_by'] || cookies['group_view_by'] || 'context'
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,6 +42,7 @@ class ContextsController < ApplicationController
|
||||||
@max_completed = current_user.prefs.show_number_completed
|
@max_completed = current_user.prefs.show_number_completed
|
||||||
@done = @context.todos.completed.limit(@max_completed).reorder("todos.completed_at DESC, todos.created_at DESC").includes(Todo::DEFAULT_INCLUDES)
|
@done = @context.todos.completed.limit(@max_completed).reorder("todos.completed_at DESC, todos.created_at DESC").includes(Todo::DEFAULT_INCLUDES)
|
||||||
@not_done_todos = @context.todos.active.reorder("todos.due IS NULL, todos.due ASC, todos.created_at ASC").includes(Todo::DEFAULT_INCLUDES)
|
@not_done_todos = @context.todos.active.reorder("todos.due IS NULL, todos.due ASC, todos.created_at ASC").includes(Todo::DEFAULT_INCLUDES)
|
||||||
|
@todos_without_project = @not_done_todos.select{|t| t.project.nil?}
|
||||||
|
|
||||||
@deferred_todos = @context.todos.deferred.includes(Todo::DEFAULT_INCLUDES)
|
@deferred_todos = @context.todos.deferred.includes(Todo::DEFAULT_INCLUDES)
|
||||||
@pending_todos = @context.todos.pending.includes(Todo::DEFAULT_INCLUDES)
|
@pending_todos = @context.todos.pending.includes(Todo::DEFAULT_INCLUDES)
|
||||||
|
@ -49,6 +50,9 @@ class ContextsController < ApplicationController
|
||||||
@projects = current_user.projects
|
@projects = current_user.projects
|
||||||
@contexts = current_user.contexts
|
@contexts = current_user.contexts
|
||||||
|
|
||||||
|
@projects_to_show = @projects.active
|
||||||
|
@contexts_to_show = [@context]
|
||||||
|
|
||||||
@count = @not_done_todos.count + @deferred_todos.count + @pending_todos.count
|
@count = @not_done_todos.count + @deferred_todos.count + @pending_todos.count
|
||||||
@page_title = "TRACKS::Context: #{@context.name}"
|
@page_title = "TRACKS::Context: #{@context.name}"
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
|
|
|
@ -47,29 +47,6 @@ class LoginController < ApplicationController
|
||||||
logout_user
|
logout_user
|
||||||
end
|
end
|
||||||
|
|
||||||
def expire_session
|
|
||||||
# this is a hack to enable cucumber to expire a session by calling this
|
|
||||||
# method. The method will be unavailable for production environment
|
|
||||||
|
|
||||||
@user.forget_me if logged_in?
|
|
||||||
cookies.delete :auth_token
|
|
||||||
session['user_id'] = nil
|
|
||||||
reset_session
|
|
||||||
|
|
||||||
unless Rails.env.production?
|
|
||||||
session['expiry_time'] = Time.now
|
|
||||||
respond_to do |format|
|
|
||||||
format.html { render :text => "Session expired for test purposes"}
|
|
||||||
format.js { render :text => "" }
|
|
||||||
end
|
|
||||||
else
|
|
||||||
respond_to do |format|
|
|
||||||
format.html { render :text => "Not available for production use"}
|
|
||||||
format.js { render :text => "" }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_expiry
|
def check_expiry
|
||||||
# Gets called by periodically_call_remote to check whether
|
# Gets called by periodically_call_remote to check whether
|
||||||
# the session has timed out yet
|
# the session has timed out yet
|
||||||
|
|
|
@ -131,12 +131,14 @@ class ProjectsController < ApplicationController
|
||||||
@not_done_todos = @project.todos.active_or_hidden.includes(Todo::DEFAULT_INCLUDES)
|
@not_done_todos = @project.todos.active_or_hidden.includes(Todo::DEFAULT_INCLUDES)
|
||||||
@deferred_todos = @project.todos.deferred.includes(Todo::DEFAULT_INCLUDES)
|
@deferred_todos = @project.todos.deferred.includes(Todo::DEFAULT_INCLUDES)
|
||||||
@pending_todos = @project.todos.pending.includes(Todo::DEFAULT_INCLUDES)
|
@pending_todos = @project.todos.pending.includes(Todo::DEFAULT_INCLUDES)
|
||||||
|
@contexts_to_show = current_user.contexts.active
|
||||||
|
@projects_to_show = [@project]
|
||||||
|
|
||||||
@done = {}
|
@done = {}
|
||||||
@done = @project.todos.completed.
|
@done = @project.todos.completed.
|
||||||
reorder("todos.completed_at DESC").
|
reorder("todos.completed_at DESC").
|
||||||
limit(current_user.prefs.show_number_completed).
|
limit(current_user.prefs.show_number_completed).
|
||||||
includes(Todo::DEFAULT_INCLUDES) unless current_user.prefs.show_number_completed == 0
|
includes(Todo::DEFAULT_INCLUDES) unless @max_completed == 0
|
||||||
|
|
||||||
@count = @not_done_todos.size
|
@count = @not_done_todos.size
|
||||||
@down_count = @count + @deferred_todos.size + @pending_todos.size
|
@down_count = @count + @deferred_todos.size + @pending_todos.size
|
||||||
|
|
|
@ -3,7 +3,6 @@ class TodosController < ApplicationController
|
||||||
skip_before_filter :login_required, :only => [:index, :tag]
|
skip_before_filter :login_required, :only => [:index, :tag]
|
||||||
prepend_before_filter :login_or_feed_token_required, :only => [:index, :tag]
|
prepend_before_filter :login_or_feed_token_required, :only => [:index, :tag]
|
||||||
append_before_filter :find_and_activate_ready, :only => [:index, :list_deferred]
|
append_before_filter :find_and_activate_ready, :only => [:index, :list_deferred]
|
||||||
append_before_filter :set_group_view_by, :only => [:index, :tag, :create, :list_deferred, :destroy, :defer, :update, :toggle_check]
|
|
||||||
|
|
||||||
protect_from_forgery :except => :check_deferred
|
protect_from_forgery :except => :check_deferred
|
||||||
|
|
||||||
|
@ -594,13 +593,8 @@ class TodosController < ApplicationController
|
||||||
get_params_for_tag_view
|
get_params_for_tag_view
|
||||||
@page_title = t('todos.tagged_page_title', :tag_name => @tag_title)
|
@page_title = t('todos.tagged_page_title', :tag_name => @tag_title)
|
||||||
@source_view = params['_source_view'] || 'tag'
|
@source_view = params['_source_view'] || 'tag'
|
||||||
|
|
||||||
if mobile?
|
init_data_for_sidebar unless mobile?
|
||||||
# mobile tags are routed with :name ending on .m. So we need to chomp it
|
|
||||||
@tag_name = @tag_name.chomp('.m')
|
|
||||||
else
|
|
||||||
init_data_for_sidebar
|
|
||||||
end
|
|
||||||
|
|
||||||
todos_with_tag_ids = find_todos_with_tag_expr(@tag_expr)
|
todos_with_tag_ids = find_todos_with_tag_expr(@tag_expr)
|
||||||
|
|
||||||
|
@ -833,8 +827,9 @@ class TodosController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_params_for_tag_view
|
def get_params_for_tag_view
|
||||||
# use sanitize to prevent XSS attacks
|
filter_format_for_tag_view
|
||||||
|
|
||||||
|
# use sanitize to prevent XSS attacks
|
||||||
@tag_expr = []
|
@tag_expr = []
|
||||||
@tag_expr << sanitize(params[:name]).split(',')
|
@tag_expr << sanitize(params[:name]).split(',')
|
||||||
@tag_expr << sanitize(params[:and]).split(',') if params[:and]
|
@tag_expr << sanitize(params[:and]).split(',') if params[:and]
|
||||||
|
@ -850,6 +845,27 @@ class TodosController < ApplicationController
|
||||||
@tag_title = @single_tag ? @tag_name : tag_title(@tag_expr)
|
@tag_title = @single_tag ? @tag_name : tag_title(@tag_expr)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def filter_format_for_tag_view
|
||||||
|
# routes for tag view do not set :format
|
||||||
|
if params[:name] =~ /.*\.m$/
|
||||||
|
set_format_for_tag_view(:m)
|
||||||
|
elsif params[:name] =~ /.*\.txt$/
|
||||||
|
set_format_for_tag_view(:txt)
|
||||||
|
# set content-type to text/plain or it remains text/html
|
||||||
|
response.headers["Content-Type"] = 'text/plain'
|
||||||
|
elsif params[:format].nil?
|
||||||
|
# if no format is given, default to html
|
||||||
|
# note that if url has ?format=m, we should not overwrite it here
|
||||||
|
request.format, params[:format] = :html, :html
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_format_for_tag_view(format)
|
||||||
|
# tag name ends with .m, set format to :m en remove .m from name
|
||||||
|
request.format, params[:format] = format, format
|
||||||
|
params[:name] = params[:name].chomp(".#{format.to_s}")
|
||||||
|
end
|
||||||
|
|
||||||
def get_ids_from_tag_expr(tag_expr)
|
def get_ids_from_tag_expr(tag_expr)
|
||||||
ids = []
|
ids = []
|
||||||
tag_expr.each do |tag_list|
|
tag_expr.each do |tag_list|
|
||||||
|
|
|
@ -21,13 +21,13 @@ module TodosHelper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def show_grouped_todos
|
def show_grouped_todos(settings = {})
|
||||||
collection = (@group_view_by == 'context') ? @contexts_to_show : @projects_to_show
|
collection = (@group_view_by == 'context') ? @contexts_to_show : @projects_to_show
|
||||||
render(:partial => collection, :locals => { :settings => {
|
render(:partial => collection, :locals => { :settings => settings.reverse_merge!({
|
||||||
:collapsible => true,
|
:collapsible => true,
|
||||||
:show_empty_containers => @show_empty_containers,
|
:show_empty_containers => @show_empty_containers,
|
||||||
:parent_container_type => @group_view_by
|
:parent_container_type => @group_view_by
|
||||||
}})
|
})})
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_collection_settings
|
def default_collection_settings
|
||||||
|
@ -80,14 +80,14 @@ module TodosHelper
|
||||||
:locals => {:settings => settings.reverse_merge!(default_collection_settings)}
|
:locals => {:settings => settings.reverse_merge!(default_collection_settings)}
|
||||||
end
|
end
|
||||||
|
|
||||||
def show_todos_without_project(todos_without_project)
|
def show_todos_without_project(todos_without_project, settings = {})
|
||||||
render :partial => 'todos/collection',
|
render :partial => 'todos/collection',
|
||||||
:object => todos_without_project,
|
:object => todos_without_project,
|
||||||
:locals => {:settings => {
|
:locals => {:settings => settings.reverse_merge!({
|
||||||
:collapsible => true,
|
:collapsible => true,
|
||||||
:container_name => "without_project",
|
:container_name => "without_project",
|
||||||
:parent_container_type => "home"
|
:parent_container_type => "home"
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -480,7 +480,7 @@ module TodosHelper
|
||||||
def should_show_new_item(todo = @todo)
|
def should_show_new_item(todo = @todo)
|
||||||
return false if todo.nil?
|
return false if todo.nil?
|
||||||
source_view do |page|
|
source_view do |page|
|
||||||
page.todo { return !todo.hidden? }
|
page.todo { return !todo.hidden? && !todo.deferred? }
|
||||||
page.deferred { return todo.deferred? || todo.pending? }
|
page.deferred { return todo.deferred? || todo.pending? }
|
||||||
page.context { return show_todo_on_current_context_page && todo_should_not_be_hidden_on_context_page }
|
page.context { return show_todo_on_current_context_page && todo_should_not_be_hidden_on_context_page }
|
||||||
page.tag { return todo.has_tag?(@tag_name) }
|
page.tag { return todo.has_tag?(@tag_name) }
|
||||||
|
@ -512,18 +512,18 @@ module TodosHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_needs_to_hide_container
|
def update_needs_to_hide_container
|
||||||
if source_view_is(:tag)
|
if source_view_is_one_of(:tag, :context, :project)
|
||||||
return @remaining_in_context == 0 && (
|
return @remaining_in_context == 0 && (
|
||||||
todo_moved_out_of_container ||
|
todo_moved_out_of_container ||
|
||||||
(@todo_hidden_state_changed && @todo.hidden?) ||
|
(@todo_hidden_state_changed && @todo.hidden?) ||
|
||||||
@todo_was_deferred_from_active_state ||
|
@todo_was_deferred_from_active_state ||
|
||||||
@tag_was_removed ||
|
@tag_was_removed ||
|
||||||
@todo_was_destroyed ||
|
@todo_was_destroyed ||
|
||||||
(@todo.completed? && !(@original_item_was_deferred || @original_item_was_hidden))
|
(@todo.completed? && !(@original_item_was_deferred || @original_item_was_hidden || @original_item_was_pending))
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
return false if source_view_is_one_of(:project, :calendar, :done, :context)
|
return false if source_view_is_one_of(:calendar, :done)
|
||||||
|
|
||||||
return @remaining_in_context == 0
|
return @remaining_in_context == 0
|
||||||
end
|
end
|
||||||
|
@ -599,7 +599,7 @@ module TodosHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def todo_container_empty_id(todo)
|
def todo_container_empty_id(todo)
|
||||||
raise Exception.new, "no todo set in TodosHelper::todo_container_empty_id. You probably not assign @original_item" if !todo
|
raise Exception.new, "no todo set in TodosHelper::todo_container_empty_id. You probably did not assign @original_item" if !todo
|
||||||
@group_view_by == "project" ? project_container_empty_id(todo) : context_container_empty_id(todo)
|
@group_view_by == "project" ? project_container_empty_id(todo) : context_container_empty_id(todo)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -609,8 +609,7 @@ module TodosHelper
|
||||||
return "#{@new_due_id}_container" if source_view_is :calendar
|
return "#{@new_due_id}_container" if source_view_is :calendar
|
||||||
return "deferred_pending_container" if !source_view_is(:todo) && (todo.deferred? || todo.pending?)
|
return "deferred_pending_container" if !source_view_is(:todo) && (todo.deferred? || todo.pending?)
|
||||||
return "completed_container" if todo.completed?
|
return "completed_container" if todo.completed?
|
||||||
return "p#{todo.project_id}" if source_view_is :project
|
return project_container_id(todo) if source_view_is_one_of(:todo, :tag, :project, :context) && @group_view_by == 'project'
|
||||||
return project_container_id(todo) if source_view_is_one_of(:todo, :tag) && @group_view_by == 'project'
|
|
||||||
return context_container_id(todo)
|
return context_container_id(todo)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -620,7 +619,7 @@ module TodosHelper
|
||||||
source_view do |page|
|
source_view do |page|
|
||||||
page.project {
|
page.project {
|
||||||
return "deferred_pending_container-empty-d" if empty_criteria_met
|
return "deferred_pending_container-empty-d" if empty_criteria_met
|
||||||
return project_container_empty_id(todo)
|
return todo_container_empty_id(todo)
|
||||||
}
|
}
|
||||||
page.tag {
|
page.tag {
|
||||||
return "deferred_pending_container-empty-d" if empty_criteria_met
|
return "deferred_pending_container-empty-d" if empty_criteria_met
|
||||||
|
@ -633,7 +632,7 @@ module TodosHelper
|
||||||
}
|
}
|
||||||
page.context {
|
page.context {
|
||||||
return "deferred_pending_container-empty-d" if empty_criteria_met
|
return "deferred_pending_container-empty-d" if empty_criteria_met
|
||||||
return context_container_empty_id(todo)
|
return todo_container_empty_id(todo)
|
||||||
}
|
}
|
||||||
page.todo {
|
page.todo {
|
||||||
return todo_container_empty_id(todo)
|
return todo_container_empty_id(todo)
|
||||||
|
|
|
@ -539,14 +539,13 @@ class RecurringTodo < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_monthly_date(previous)
|
def get_monthly_date(previous)
|
||||||
|
|
||||||
start = determine_start(previous)
|
start = determine_start(previous)
|
||||||
day = self.every_other1
|
day = self.every_other1
|
||||||
n = self.every_other2
|
n = self.every_other2
|
||||||
|
|
||||||
case self.recurrence_selector
|
case self.recurrence_selector
|
||||||
when 0 # specific day of the month
|
when 0 # specific day of the month
|
||||||
if start.mday >= day
|
if start.mday > day
|
||||||
# there is no next day n in this month, search in next month
|
# there is no next day n in this month, search in next month
|
||||||
#
|
#
|
||||||
# start += n.months
|
# start += n.months
|
||||||
|
|
|
@ -99,7 +99,7 @@ class Todo < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
event :block do
|
event :block do
|
||||||
transitions :to => :pending, :from => [:active, :deferred]
|
transitions :to => :pending, :from => [:active, :deferred, :project_hidden]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -152,6 +152,14 @@ class Todo < ActiveRecord::Base
|
||||||
return !( uncompleted_predecessors.empty? || state == 'project_hidden' )
|
return !( uncompleted_predecessors.empty? || state == 'project_hidden' )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def guard_for_transition_from_deferred_to_pending
|
||||||
|
no_uncompleted_predecessors? && not_part_of_hidden_container?
|
||||||
|
end
|
||||||
|
|
||||||
|
def not_part_of_hidden_container?
|
||||||
|
!( (self.project && self.project.hidden?) || self.context.hidden? )
|
||||||
|
end
|
||||||
|
|
||||||
# Returns a string with description <context, project>
|
# Returns a string with description <context, project>
|
||||||
def specification
|
def specification
|
||||||
project_name = self.project.is_a?(NullProject) ? "(none)" : self.project.name
|
project_name = self.project.is_a?(NullProject) ? "(none)" : self.project.name
|
||||||
|
@ -195,7 +203,7 @@ class Todo < ActiveRecord::Base
|
||||||
def remove_predecessor(predecessor)
|
def remove_predecessor(predecessor)
|
||||||
self.predecessors.delete(predecessor)
|
self.predecessors.delete(predecessor)
|
||||||
if self.predecessors.empty?
|
if self.predecessors.empty?
|
||||||
self.activate!
|
self.not_part_of_hidden_container? ? self.activate! : self.hide!
|
||||||
else
|
else
|
||||||
save!
|
save!
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# invalidate the cache every day because of staleness or
|
# invalidate the cache every day because of staleness or
|
||||||
# rendering of "due in x days" that change without touching updated at of the todo
|
# rendering of "due in x days" that change without touching updated at of the todo
|
||||||
cache [context, @source_view, current_user.date.strftime("%Y%m%d"), @tag_name] do
|
cache [context, @source_view, current_user.date.strftime("%Y%m%d"), @tag_name] do
|
||||||
%>
|
-%>
|
||||||
<%=
|
<%=
|
||||||
render :partial => 'todos/collection',
|
render :partial => 'todos/collection',
|
||||||
:object => @not_done,
|
:object => @not_done,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="list-stategroup-contexts-container" id="list-<%= state %>-contexts-container">
|
<div class="list-stategroup-contexts-container" id="list-<%= state %>-contexts-container">
|
||||||
<h2>
|
<h2>
|
||||||
<span id="<%= state %>-contexts-count" class="badge"><%= context_state_group.length %></span>
|
<span id="<%= state %>-contexts-count" class="badge"><%= context_state_group.length %></span>
|
||||||
<%= t("states."+ state +"_plural")%> <%= t('common.contexts') %>
|
<%= t("states.contexts."+ state) %>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div id="<%= state%>-contexts-empty-nd" style="<%= no_contexts ? 'display:block' : 'display:none'%>">
|
<div id="<%= state%>-contexts-empty-nd" style="<%= no_contexts ? 'display:block' : 'display:none'%>">
|
||||||
|
|
|
@ -2,9 +2,17 @@
|
||||||
suffix_completed = t('contexts.last_completed_in_context', :number=>prefs.show_number_completed)
|
suffix_completed = t('contexts.last_completed_in_context', :number=>prefs.show_number_completed)
|
||||||
deferred_pending_options = {:append_descriptor => nil, :parent_container_type => 'context'}
|
deferred_pending_options = {:append_descriptor => nil, :parent_container_type => 'context'}
|
||||||
done_todo_options = {:append_descriptor => suffix_completed, :suppress_context => true, :parent_container_type => 'context'}
|
done_todo_options = {:append_descriptor => suffix_completed, :suppress_context => true, :parent_container_type => 'context'}
|
||||||
|
show_empty_containers = (@group_view_by == 'context')
|
||||||
-%>
|
-%>
|
||||||
<div id="display_box">
|
<div id="display_box">
|
||||||
<%= render :partial => @context, :locals => { :settings => {:collapsible => false, :show_empty_containers => true, :parent_container_type => 'context' }} %>
|
|
||||||
|
<%= empty_message_holder("not_done_project", @not_done_todos.empty?) %>
|
||||||
|
|
||||||
|
<%= show_grouped_todos({:collapsible => false, :show_empty_containers => show_empty_containers, :parent_container_type => 'context'}) %>
|
||||||
|
|
||||||
|
<% if @group_view_by == 'project' -%>
|
||||||
|
<%= show_todos_without_project(@todos_without_project, {:collapsible => false, :parent_container_type => 'context', :title_param => @context.name}) -%>
|
||||||
|
<% end -%>
|
||||||
|
|
||||||
<%= show_deferred_pending_todos(@deferred_todos, @pending_todos, deferred_pending_options) %>
|
<%= show_deferred_pending_todos(@deferred_todos, @pending_todos, deferred_pending_options) %>
|
||||||
|
|
||||||
|
|
|
@ -46,10 +46,6 @@
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div id="minilinks">
|
<div id="minilinks">
|
||||||
<%= link_to(t('layouts.toggle_contexts'), "#", {:title => t('layouts.toggle_contexts_title'), :id => "toggle-contexts-nav"}) %>
|
|
||||||
|
|
|
||||||
<%= link_to(t('layouts.toggle_notes'), "#", {:accesskey => "S", :title => t('layouts.toggle_notes_title'), :id => "toggle-notes-nav"}) %>
|
|
||||||
|
|
|
||||||
<%= link_to("#{t('common.logout')} (#{current_user.display_name}) »".html_safe, logout_path) %>
|
<%= link_to("#{t('common.logout')} (#{current_user.display_name}) »".html_safe, logout_path) %>
|
||||||
</div>
|
</div>
|
||||||
<div id="navcontainer">
|
<div id="navcontainer">
|
||||||
|
@ -66,13 +62,15 @@
|
||||||
<li><%= navigation_link( t('layouts.navigation.recurring_todos'), {:controller => "recurring_todos", :action => "index"}, :title => t('layouts.navigation.recurring_todos_title')) %></li>
|
<li><%= navigation_link( t('layouts.navigation.recurring_todos'), {:controller => "recurring_todos", :action => "index"}, :title => t('layouts.navigation.recurring_todos_title')) %></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="#"><%= t('layouts.navigation.view') %></a>
|
<li id="menu_view"><a href="#" id="menu_view_link"><%= t('layouts.navigation.view') %></a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><%= navigation_link( t('layouts.navigation.calendar'), calendar_path, :title => t('layouts.navigation.calendar_title')) %></li>
|
<li><%= navigation_link( t('layouts.navigation.calendar'), calendar_path, :title => t('layouts.navigation.calendar_title')) %></li>
|
||||||
<li><%= navigation_link( t('layouts.navigation.completed_tasks'), done_overview_path, {:accesskey=>"d", :title=>t('layouts.navigation.completed_tasks_title')} ) %></li>
|
<li><%= navigation_link( t('layouts.navigation.completed_tasks'), done_overview_path, {:accesskey=>"d", :title=>t('layouts.navigation.completed_tasks_title')} ) %></li>
|
||||||
<li><%= navigation_link( t('layouts.navigation.feeds'), feeds_path, :title => t('layouts.navigation.feeds_title')) %></li>
|
<li><%= navigation_link( t('layouts.navigation.feeds'), feeds_path, :title => t('layouts.navigation.feeds_title')) %></li>
|
||||||
<li><%= navigation_link( t('layouts.navigation.stats'), stats_path, :title => t('layouts.navigation.stats_title')) %></li>
|
<li><%= navigation_link( t('layouts.navigation.stats'), stats_path, :title => t('layouts.navigation.stats_title')) %></li>
|
||||||
<li><hr/></li>
|
<li><hr/></li>
|
||||||
|
<li id="menu_view_toggle_contexts"><%= link_to(t('layouts.toggle_contexts'), "#", {:title => t('layouts.toggle_contexts_title'), :id => "toggle-contexts-nav"}) %></li>
|
||||||
|
<li><%= link_to(t('layouts.toggle_notes'), "#", {:accesskey => "S", :title => t('layouts.toggle_notes_title'), :id => "toggle-notes-nav"}) %></li>
|
||||||
<%= group_view_by_menu_entry %>
|
<%= group_view_by_menu_entry %>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -2,11 +2,8 @@
|
||||||
@not_done = @not_done_todos.select {|t| t.project_id == project.id }
|
@not_done = @not_done_todos.select {|t| t.project_id == project.id }
|
||||||
# invalidate the cache every day because of staleness or
|
# invalidate the cache every day because of staleness or
|
||||||
# rendering of "due in x days" that change without touching updated at of the todo
|
# rendering of "due in x days" that change without touching updated at of the todo
|
||||||
cache [project, @source_view, current_user.date.strftime("%Y%m%d")] do
|
cache [project, @source_view, current_user.date.strftime("%Y%m%d"), @tag_name] do
|
||||||
-%>
|
-%>
|
||||||
<% if source_view_is :project -%>
|
|
||||||
<%= render :partial => "project_settings_container", :locals => {:project => project} %>
|
|
||||||
<% end -%>
|
|
||||||
<%=
|
<%=
|
||||||
title = source_view_is(:project) ? t('projects.actions_in_project_title') : show_project_name(project)
|
title = source_view_is(:project) ? t('projects.actions_in_project_title') : show_project_name(project)
|
||||||
|
|
||||||
|
|
|
@ -8,14 +8,9 @@
|
||||||
<h2>
|
<h2>
|
||||||
<span id="<%= state %>-projects-count" class="badge"><%= project_state_group.length%><%= total_count_string%></span>
|
<span id="<%= state %>-projects-count" class="badge"><%= project_state_group.length%><%= total_count_string%></span>
|
||||||
|
|
||||||
<%= t('common.last' ) unless ( ['review','stalled','blocked','current'].include?(state) )%>
|
<%= t('common.last' ) if state == 'completed' %>
|
||||||
<% if (I18n.locale == :fr) %>
|
<%= t('states.projects.'+state) %>
|
||||||
<%= t('common.projects').downcase %>
|
<%= total_count==-1 ? "" : " (#{link_to(t('common.show_all'), done_projects_path)})".html_safe%>
|
||||||
<%= t('states.'+state+'_plural' ).downcase %><%= total_count==-1 ? "" : " (#{link_to(t('common.show_all'), done_projects_path)})".html_safe%>
|
|
||||||
<% else %>
|
|
||||||
<%= t('states.'+state+'_plural' )%>
|
|
||||||
<%= t('common.projects') %><%= total_count==-1 ? "" : " (#{link_to(t('common.show_all'), done_projects_path)})".html_safe%>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
</h2>
|
</h2>
|
||||||
<% unless suppress_sort_menu %>
|
<% unless suppress_sort_menu %>
|
||||||
|
|
|
@ -5,11 +5,19 @@
|
||||||
:suppress_project => true,
|
:suppress_project => true,
|
||||||
:parent_container_type => 'project'
|
:parent_container_type => 'project'
|
||||||
}
|
}
|
||||||
|
if @not_done_todos.count == 0
|
||||||
|
# force project view so one empty container will be shown with an empty message
|
||||||
|
@group_view_by = 'project'
|
||||||
|
end
|
||||||
-%>
|
-%>
|
||||||
<div id="display_box">
|
<div id="display_box">
|
||||||
<%= project_next_prev %>
|
<%= project_next_prev %>
|
||||||
|
|
||||||
<%= render :partial => @project, :locals => {:settings => {:collapsible => false, :show_empty_containers => true, :parent_container_type => 'project' }} %>
|
<%= render :partial => "project_settings_container", :locals => {:project => @project} %>
|
||||||
|
|
||||||
|
<%= empty_message_holder("not_done_context", @not_done_todos.empty?) %>
|
||||||
|
|
||||||
|
<%= show_grouped_todos({:collapsible => false, :show_empty_containers => false, :parent_container_type => 'project' }) %>
|
||||||
|
|
||||||
<%= show_deferred_pending_todos(@deferred_todos, @pending_todos, deferred_pending_options) %>
|
<%= show_deferred_pending_todos(@deferred_todos, @pending_todos, deferred_pending_options) %>
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ function update_project_page() {
|
||||||
TracksForm.set_context_name_and_default_context_name("<%= escape_javascript(@project.default_context.name)%>");
|
TracksForm.set_context_name_and_default_context_name("<%= escape_javascript(@project.default_context.name)%>");
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if @project.default_tags %>
|
<% if @project.default_tags %>
|
||||||
TracksForm.set_tag_list("<%= escape_javascript(@project.default_tags)%>");
|
TracksForm.set_tag_list_and_default_tag_list("<%= escape_javascript(@project.default_tags)%>");
|
||||||
<% end %>
|
<% end %>
|
||||||
TracksPages.update_sidebar(html_for_sidebar());
|
TracksPages.update_sidebar(html_for_sidebar());
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,12 +84,12 @@
|
||||||
:month => select_tag('recurring_todo[yearly_month_of_year2]', options_for_select(@months_of_year, @recurring_todo.yearly_month_of_year2))) %><br/>
|
:month => select_tag('recurring_todo[yearly_month_of_year2]', options_for_select(@months_of_year, @recurring_todo.yearly_month_of_year2))) %><br/>
|
||||||
</div>
|
</div>
|
||||||
<div id="recurring_target">
|
<div id="recurring_target">
|
||||||
<label><%= t('todos.recurrence.recurrence_on_options') %></label><br/>
|
<label><%= t('todos.recurrence.recurrence_on.options') %></label><br/>
|
||||||
<%= radio_button_tag('recurring_todo[recurring_target]', 'due_date', @recurring_todo.target == 'due_date')%> <%= t('todos.recurrence.recurrence_on_due_date') %>. <%= t('todos.recurrence.show_options') %>:
|
<%= radio_button_tag('recurring_todo[recurring_target]', 'due_date', @recurring_todo.target == 'due_date')%> <%= t('todos.recurrence.recurrence_on.due_date') %>. <%= t('todos.recurrence.recurrence_on.show_options') %>:
|
||||||
<%= radio_button_tag('recurring_todo[recurring_show_always]', '1', @recurring_todo.show_always?)%> <%= t('todos.recurrence.show_option_always') %>
|
<%= radio_button_tag('recurring_todo[recurring_show_always]', '1', @recurring_todo.show_always?)%> <%= t('todos.recurrence.recurrence_on.show_always') %>
|
||||||
<%= radio_button_tag('recurring_todo[recurring_show_always]', '0', !@recurring_todo.show_always?)%>
|
<%= radio_button_tag('recurring_todo[recurring_show_always]', '0', !@recurring_todo.show_always?)%>
|
||||||
<%= raw t('todos.recurrence.show_days_before', :days => text_field_tag( 'recurring_todo[recurring_show_days_before]', @recurring_todo.show_from_delta, {"size" => 3})) %><br/>
|
<%= raw t('todos.recurrence.recurrence_on.show_days_before', :days => text_field_tag( 'recurring_todo[recurring_show_days_before]', @recurring_todo.show_from_delta, {"size" => 3})) %><br/>
|
||||||
<%= radio_button_tag('recurring_todo[recurring_target]', 'show_from_date', @recurring_todo.target == 'show_from_date')%> <%= t('todos.recurrence.from_tickler') %><br/>
|
<%= radio_button_tag('recurring_todo[recurring_target]', 'show_from_date', @recurring_todo.target == 'show_from_date')%> <%= t('todos.recurrence.recurrence_on.from_tickler') %><br/>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -76,13 +76,13 @@
|
||||||
:month => select_tag('recurring_todo[yearly_month_of_year2]', options_for_select(@months_of_year, Time.zone.now.month))) %><br/>
|
:month => select_tag('recurring_todo[yearly_month_of_year2]', options_for_select(@months_of_year, Time.zone.now.month))) %><br/>
|
||||||
</div>
|
</div>
|
||||||
<div id="recurring_target">
|
<div id="recurring_target">
|
||||||
<label><%= t('todos.recurrence.recurrence_on_options') %></label><br/>
|
<label><%= t('todos.recurrence.recurrence_on.options') %></label><br/>
|
||||||
<%= radio_button_tag('recurring_todo[recurring_target]', 'due_date', true)%> <%= t('todos.recurrence.recurrence_on_due_date') %>. <%= t('todos.recurrence.show_options') %>:
|
<%= radio_button_tag('recurring_todo[recurring_target]', 'due_date', true)%> <%= t('todos.recurrence.recurrence_on.due_date') %>. <%= t('todos.recurrence.recurrence_on.show_options') %>:
|
||||||
<%= radio_button_tag('recurring_todo[recurring_show_always]', '1', true)%> <%= t('todos.recurrence.show_option_always') %>
|
<%= radio_button_tag('recurring_todo[recurring_show_always]', '1', true)%> <%= t('todos.recurrence.recurrence_on.show_always') %>
|
||||||
<%= radio_button_tag('recurring_todo[recurring_show_always]', '0', false)%>
|
<%= radio_button_tag('recurring_todo[recurring_show_always]', '0', false)%>
|
||||||
<%= raw t('todos.recurrence.show_days_before', :days => text_field_tag( 'recurring_todo[recurring_show_days_before]', "0", {"size" => 3})) %>
|
<%= raw t('todos.recurrence.recurrence_on.show_days_before', :days => text_field_tag( 'recurring_todo[recurring_show_days_before]', "0", {"size" => 3})) %>
|
||||||
<br/>
|
<br/>
|
||||||
<%= radio_button_tag('recurring_todo[recurring_target]', 'show_from_date', false)%> <%= t('todos.recurrence.from_tickler') %><br/>
|
<%= radio_button_tag('recurring_todo[recurring_target]', 'show_from_date', false)%> <%= t('todos.recurrence.recurrence_on.from_tickler') %><br/>
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
$('#todo-form-new-action').clearDeps();
|
$('#todo-form-new-action').clearDeps();
|
||||||
TracksForm.set_context_name('<%=escape_javascript @initial_context_name%>');
|
TracksForm.set_context_name('<%=escape_javascript @initial_context_name%>');
|
||||||
TracksForm.set_project_name('<%=escape_javascript @initial_project_name%>');
|
TracksForm.set_project_name('<%=escape_javascript @initial_project_name%>');
|
||||||
TracksForm.set_tag_list('<%=escape_javascript @initial_tags%>');
|
TracksForm.set_tag_list_and_default_tag_list('<%=escape_javascript @initial_tags%>');
|
||||||
$('#todo-form-new-action input:text:first').focus();
|
$('#todo-form-new-action input:text:first').focus();
|
||||||
$('#new_todo_starred_link .todo_star').removeClass('starred');
|
$('#new_todo_starred_link .todo_star').removeClass('starred');
|
||||||
$('#new_todo_starred').val('false');
|
$('#new_todo_starred').val('false');
|
||||||
|
@ -86,4 +86,4 @@
|
||||||
return "<%= @saved ? escape_javascript(render(:partial => @todo, :locals => { :parent_container_type => parent_container_type, :source_view => @source_view })) : "" %>";
|
return "<%= @saved ? escape_javascript(render(:partial => @todo, :locals => { :parent_container_type => parent_container_type, :source_view => @source_view })) : "" %>";
|
||||||
}
|
}
|
||||||
|
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
animation << "add_todo_to_container" unless source_view_is(:done)
|
animation << "add_todo_to_container" unless source_view_is(:done)
|
||||||
animation << "block_predecessors"
|
animation << "block_predecessors"
|
||||||
end
|
end
|
||||||
animation << "update_empty_container" if source_view_is_one_of(:tag, :todo, :deferred)
|
animation << "update_empty_container" if source_view_is_one_of(:tag, :todo, :deferred, :project, :context)
|
||||||
animation << "regenerate_predecessor_family"
|
animation << "regenerate_predecessor_family"
|
||||||
else
|
else
|
||||||
animation << "replace_todo"
|
animation << "replace_todo"
|
||||||
|
@ -63,15 +63,14 @@ function replace_todo(next_steps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_todo_to_container(next_steps) {
|
function add_todo_to_container(next_steps) {
|
||||||
// <%= @group_view_by %>
|
|
||||||
$('#<%= item_container_id(@todo) %>_items').append(html_for_todo());
|
$('#<%= item_container_id(@todo) %>_items').append(html_for_todo());
|
||||||
<% if should_make_context_visible -%>
|
<% if should_make_context_visible -%>
|
||||||
$('#<%= item_container_id(@todo) %>').slideDown(500, function() {
|
$('#<%= item_container_id(@todo) %>').slideDown(500, function() {
|
||||||
$("#<%= empty_container_msg_div_id %>").slideUp(100);
|
$("#<%= empty_container_msg_div_id %>").slideUp(100);
|
||||||
highlight_updated_todo(next_steps);
|
highlight_updated_todo(next_steps);
|
||||||
});
|
});
|
||||||
<% else -%>
|
<% else -%>
|
||||||
$("#<%= empty_container_msg_div_id(@todo) %>").slideUp(100);
|
$("#<%= empty_container_msg_div_id(@todo) %>").slideUp(100);
|
||||||
highlight_updated_todo(next_steps);
|
highlight_updated_todo(next_steps);
|
||||||
<% end -%>
|
<% end -%>
|
||||||
<% if @completed_count == 0 -%>
|
<% if @completed_count == 0 -%>
|
||||||
|
@ -120,7 +119,7 @@ function highlight_updated_todo(next_steps) {
|
||||||
|
|
||||||
function activate_pending_todos(next_steps) {
|
function activate_pending_todos(next_steps) {
|
||||||
<% # Activate pending todos that are successors of the completed
|
<% # Activate pending todos that are successors of the completed
|
||||||
if @saved && @pending_to_activate
|
if @pending_to_activate
|
||||||
# do not render the js in case of an error or if no todos to activate
|
# do not render the js in case of an error or if no todos to activate
|
||||||
@pending_to_activate.each do |t|
|
@pending_to_activate.each do |t|
|
||||||
html = escape_javascript(render(:partial => t, :locals => { :parent_container_type => parent_container_type }))
|
html = escape_javascript(render(:partial => t, :locals => { :parent_container_type => parent_container_type }))
|
||||||
|
@ -173,7 +172,7 @@ end
|
||||||
|
|
||||||
function html_for_recurring_todo() {
|
function html_for_recurring_todo() {
|
||||||
<%-
|
<%-
|
||||||
js = @saved && @new_recurring_todo ? escape_javascript(render(:partial => @new_recurring_todo, :locals => { :parent_container_type => parent_container_type })) : ""
|
js = @new_recurring_todo ? escape_javascript(render(:partial => @new_recurring_todo, :locals => { :parent_container_type => parent_container_type })) : ""
|
||||||
-%>
|
-%>
|
||||||
return "<%= js %>";
|
return "<%= js %>";
|
||||||
}
|
}
|
||||||
|
@ -181,7 +180,7 @@ function html_for_recurring_todo() {
|
||||||
function html_for_todo() {
|
function html_for_todo() {
|
||||||
<%-
|
<%-
|
||||||
js = ""
|
js = ""
|
||||||
if @saved && !source_view_is(:done)
|
if !source_view_is(:done)
|
||||||
js = escape_javascript(render(
|
js = escape_javascript(render(
|
||||||
:partial => @todo,
|
:partial => @todo,
|
||||||
:locals => {
|
:locals => {
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
end
|
end
|
||||||
animation << "hide_container" if update_needs_to_hide_container
|
animation << "hide_container" if update_needs_to_hide_container
|
||||||
animation << "highlight_updated_todo"
|
animation << "highlight_updated_todo"
|
||||||
animation << "update_empty_container" if source_view_is_one_of(:tag, :todo, :deferred)
|
animation << "update_empty_container" if source_view_is_one_of(:tag, :todo, :deferred, :project, :context)
|
||||||
animation << "update_predecessors"
|
animation << "update_predecessors"
|
||||||
%>
|
%>
|
||||||
TracksPages.page_notify('notice', '<%=escape_javascript @status_message%>', 5);
|
TracksPages.page_notify('notice', '<%=escape_javascript @status_message%>', 5);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -333,6 +333,14 @@ en:
|
||||||
hide_action_form_title: Hide new action form
|
hide_action_form_title: Hide new action form
|
||||||
make_actions_dependent: Make actions dependent on each other
|
make_actions_dependent: Make actions dependent on each other
|
||||||
states:
|
states:
|
||||||
|
contexts:
|
||||||
|
hidden: Hidden contexts
|
||||||
|
active: Active contexts
|
||||||
|
closed: Closed contexts
|
||||||
|
projects:
|
||||||
|
hidden: Hidden projects
|
||||||
|
active: Active projects
|
||||||
|
closed: Closed projects
|
||||||
hidden_plural: Hidden
|
hidden_plural: Hidden
|
||||||
completed: Completed
|
completed: Completed
|
||||||
completed_plural: Completed
|
completed_plural: Completed
|
||||||
|
@ -427,6 +435,8 @@ en:
|
||||||
completed: Currently there are no completed actions
|
completed: Currently there are no completed actions
|
||||||
title: No actions found
|
title: No actions found
|
||||||
not_done_with_tag: "Currently there are no incomplete actions with the tag '%{param}'"
|
not_done_with_tag: "Currently there are no incomplete actions with the tag '%{param}'"
|
||||||
|
not_done_project: Currently there are no incomplete actions in this project
|
||||||
|
not_done_context: Currently there are no incomplete actions in this context
|
||||||
completed_recurring: Currently there are no completed recurring todos
|
completed_recurring: Currently there are no completed recurring todos
|
||||||
not_done: Currently there are no incomplete actions
|
not_done: Currently there are no incomplete actions
|
||||||
project: Currently there are no incomplete actions in this project
|
project: Currently there are no incomplete actions in this project
|
||||||
|
@ -444,6 +454,7 @@ en:
|
||||||
home_completed: Completed actions
|
home_completed: Completed actions
|
||||||
tag_completed: "Completed actions tagged with '%{param}'"
|
tag_completed: "Completed actions tagged with '%{param}'"
|
||||||
home_without_project: "Actions without project"
|
home_without_project: "Actions without project"
|
||||||
|
context_without_project: "Actions without project in %{param}"
|
||||||
project_project: "Actions in this project"
|
project_project: "Actions in this project"
|
||||||
project_deferred_pending: Deferred/pending actions in this project
|
project_deferred_pending: Deferred/pending actions in this project
|
||||||
context_deferred_pending: Deferred/pending actions in this context
|
context_deferred_pending: Deferred/pending actions in this context
|
||||||
|
@ -584,7 +595,6 @@ en:
|
||||||
ends_on_number_times: Ends after %{number} times
|
ends_on_number_times: Ends after %{number} times
|
||||||
ends_on_date: Ends on %{date}
|
ends_on_date: Ends on %{date}
|
||||||
every_work_day: Every work day
|
every_work_day: Every work day
|
||||||
recurrence_on_due_date: the date that the todo is due
|
|
||||||
weekly_options: Settings for weekly recurring actions
|
weekly_options: Settings for weekly recurring actions
|
||||||
weekly: Weekly
|
weekly: Weekly
|
||||||
monthly_options: Settings for monthly recurring actions
|
monthly_options: Settings for monthly recurring actions
|
||||||
|
@ -633,16 +643,18 @@ en:
|
||||||
due: due
|
due: due
|
||||||
until: until
|
until: until
|
||||||
every_month: every month
|
every_month: every month
|
||||||
show_option_always: always
|
|
||||||
daily: Daily
|
daily: Daily
|
||||||
yearly_every_x_day: Every %{month} %{day}
|
yearly_every_x_day: Every %{month} %{day}
|
||||||
recurrence_on_options: Set recurrence on
|
recurrence_on:
|
||||||
|
options: Use the calculated date to
|
||||||
|
due_date: set the actions due date
|
||||||
|
show_options: Show the action
|
||||||
|
show_always: always
|
||||||
|
show_days_before: "not until %{days} days before the due date"
|
||||||
|
from_tickler: set the date the action should be shown (do not set a due date)
|
||||||
daily_every_number_day: Every %{number} day(s)
|
daily_every_number_day: Every %{number} day(s)
|
||||||
show_options: Show the todo
|
|
||||||
weekly_every_number_week: Returns every %{number} week on
|
weekly_every_number_week: Returns every %{number} week on
|
||||||
ends_on: Ends on
|
ends_on: Ends on
|
||||||
show_days_before: "%{days} days before the todo is due"
|
|
||||||
from_tickler: the date todo comes from tickler (no due date set)
|
|
||||||
no_end_date: No end date
|
no_end_date: No end date
|
||||||
day_x_on_every_x_month: Day %{day} on every %{month} month
|
day_x_on_every_x_month: Day %{day} on every %{month} month
|
||||||
yearly_options: Settings for yearly recurring actions
|
yearly_options: Settings for yearly recurring actions
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -5,7 +5,6 @@ Tracksapp::Application.routes.draw do
|
||||||
|
|
||||||
post 'login' => 'login#login'
|
post 'login' => 'login#login'
|
||||||
get 'login' => 'login#login'
|
get 'login' => 'login#login'
|
||||||
get 'login/expire_session' => 'login#expire_session'
|
|
||||||
get 'login/check_expiry' => 'login#check_expiry'
|
get 'login/check_expiry' => 'login#check_expiry'
|
||||||
get 'logout' => 'login#logout'
|
get 'logout' => 'login#logout'
|
||||||
|
|
||||||
|
@ -102,9 +101,13 @@ Tracksapp::Application.routes.draw do
|
||||||
post 'add_predecessor'
|
post 'add_predecessor'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
get 'todos/tag/:name' => 'todos#tag', :as => :tag
|
|
||||||
get 'tags.autocomplete' => "todos#tags", :format => 'autocomplete'
|
|
||||||
|
|
||||||
|
# match /todos/tag and put everything in :name, including extensions like .m and .txt.
|
||||||
|
# This means the controller action needs to parse the extension and set format/content type
|
||||||
|
# Needed for /todos/tag/first.last.m to work
|
||||||
|
get 'todos/tag/:name' => 'todos#tag', :as => :tag, :format => false, :name => /.*/
|
||||||
|
|
||||||
|
get 'tags.autocomplete' => "todos#tags", :format => 'autocomplete'
|
||||||
get 'todos/done/tag/:name' => "todos#done_tag", :as => :done_tag
|
get 'todos/done/tag/:name' => "todos#done_tag", :as => :done_tag
|
||||||
get 'todos/all_done/tag/:name' => "todos#all_done_tag", :as => :all_done_tag
|
get 'todos/all_done/tag/:name' => "todos#all_done_tag", :as => :all_done_tag
|
||||||
get 'auto_complete_for_predecessor' => 'todos#auto_complete_for_predecessor'
|
get 'auto_complete_for_predecessor' => 'todos#auto_complete_for_predecessor'
|
||||||
|
|
|
@ -16,10 +16,23 @@
|
||||||
== Version 2.3devel
|
== Version 2.3devel
|
||||||
|
|
||||||
New and changed features
|
New and changed features
|
||||||
* you can select to group todos on the home page by context or by
|
* You can select to group todos on the home page by context or by
|
||||||
project (using the view menu). This also works for tag page
|
project (using the view menu). This also works for tag page, the project page,
|
||||||
|
the tickler and the context page
|
||||||
* You can now change the state of a context to closed
|
* You can now change the state of a context to closed
|
||||||
* Czech locale has been renamed from cz to cs to follow ISO standards
|
* Czech locale has been renamed from cz to cs to follow ISO standards
|
||||||
|
* The toggle-notes and toggle-collapsed-containers have been moved into the view
|
||||||
|
menu
|
||||||
|
* Bugfixes
|
||||||
|
* Tracks is tested on Ruby 1.9.3 and on Ruby 2.0
|
||||||
|
|
||||||
|
Removed features
|
||||||
|
* This version of Tracks dropped support for Ruby 1.8.x. Please use Ruby 1.9 or
|
||||||
|
Ruby 2.0
|
||||||
|
|
||||||
|
Under the hood
|
||||||
|
* Upgrade to Rails 3.213
|
||||||
|
* Several refactorings al over the place for easier maintenance
|
||||||
|
|
||||||
== Version 2.2.2
|
== Version 2.2.2
|
||||||
|
|
||||||
|
|
|
@ -68,10 +68,10 @@ Feature: dependencies
|
||||||
And "test 2" depends on "test 1"
|
And "test 2" depends on "test 1"
|
||||||
When I go to the "dependencies" project
|
When I go to the "dependencies" project
|
||||||
Then I should see "test 2" in the deferred container
|
Then I should see "test 2" in the deferred container
|
||||||
And I should see "test 1" in the action container
|
And I should see "test 1" in the context container for "@pc"
|
||||||
When I mark "test 1" as complete
|
When I mark "test 1" as complete
|
||||||
Then I should see "test 1" in the completed container
|
Then I should see "test 1" in the completed container
|
||||||
And I should see "test 2" in the action container
|
And I should see "test 2" in the context container for "@pc"
|
||||||
And I should not see "test 2" in the deferred container
|
And I should not see "test 2" in the deferred container
|
||||||
And I should see empty message for deferred todos of project
|
And I should see empty message for deferred todos of project
|
||||||
|
|
||||||
|
@ -86,9 +86,9 @@ Feature: dependencies
|
||||||
And "test 2" depends on "test 1"
|
And "test 2" depends on "test 1"
|
||||||
When I go to the "dependencies" project
|
When I go to the "dependencies" project
|
||||||
Then I should see "test 2" in the deferred container
|
Then I should see "test 2" in the deferred container
|
||||||
And I should see "test 1" in the action container
|
And I should see "test 1" in the context container for "@pc"
|
||||||
When I delete the action "test 1"
|
When I delete the action "test 1"
|
||||||
Then I should see "test 2" in the action container
|
Then I should see "test 2" in the context container for "@pc"
|
||||||
And I should not see "test 2" in the deferred container
|
And I should not see "test 2" in the deferred container
|
||||||
And I should see empty message for deferred todos of project
|
And I should see empty message for deferred todos of project
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ Feature: dependencies
|
||||||
Then I should see "test 3" within the dependencies of "test 1"
|
Then I should see "test 3" within the dependencies of "test 1"
|
||||||
And I should not see "test 2"
|
And I should not see "test 2"
|
||||||
|
|
||||||
@javascript
|
@javascript
|
||||||
Scenario: Dragging an action to a completed action will not add it as a dependency
|
Scenario: Dragging an action to a completed action will not add it as a dependency
|
||||||
Given I have a context called "@pc"
|
Given I have a context called "@pc"
|
||||||
And I have a project "dependencies" that has the following todos
|
And I have a project "dependencies" that has the following todos
|
||||||
|
@ -122,7 +122,7 @@ Feature: dependencies
|
||||||
When I go to the "dependencies" project
|
When I go to the "dependencies" project
|
||||||
And I drag "test 1" to "test 3"
|
And I drag "test 1" to "test 3"
|
||||||
Then I should see an error flash message saying "Cannot add this action as a dependency to a completed action!"
|
Then I should see an error flash message saying "Cannot add this action as a dependency to a completed action!"
|
||||||
And I should see "test 1" in the project container of "dependencies"
|
And I should see "test 1" in the context container for "@pc"
|
||||||
|
|
||||||
@javascript
|
@javascript
|
||||||
Scenario Outline: Marking a successor as complete will update predecessor
|
Scenario Outline: Marking a successor as complete will update predecessor
|
||||||
|
@ -148,7 +148,7 @@ Feature: dependencies
|
||||||
| tag page for "bla" | context |
|
| tag page for "bla" | context |
|
||||||
| tag page for "bla" | project |
|
| tag page for "bla" | project |
|
||||||
|
|
||||||
@javascript
|
@javascript
|
||||||
Scenario Outline: Marking a successor as active will update predecessor
|
Scenario Outline: Marking a successor as active will update predecessor
|
||||||
Given I have a context called "@pc"
|
Given I have a context called "@pc"
|
||||||
And I have selected the view for group by <grouping>
|
And I have selected the view for group by <grouping>
|
||||||
|
@ -171,5 +171,6 @@ Feature: dependencies
|
||||||
Scenarios:
|
Scenarios:
|
||||||
| page | grouping |
|
| page | grouping |
|
||||||
| "dependencies" project | project |
|
| "dependencies" project | project |
|
||||||
|
| "dependencies" project | context |
|
||||||
| tag page for "bla" | context |
|
| tag page for "bla" | context |
|
||||||
| tag page for "bla" | project |
|
| tag page for "bla" | project |
|
|
@ -55,7 +55,7 @@ Feature: Edit a next action from every page
|
||||||
@javascript @wip
|
@javascript @wip
|
||||||
Scenario Outline: Changing container of the todo in that container will hide it
|
Scenario Outline: Changing container of the todo in that container will hide it
|
||||||
# this script fails on https://code.google.com/p/selenium/issues/detail?id=3075 for selenium-webdriver > 2.14.
|
# this script fails on https://code.google.com/p/selenium/issues/detail?id=3075 for selenium-webdriver > 2.14.
|
||||||
# and selenium-webdriver < 2.20 fails on firefox 11 :-( So @wip for now. This may work on webkit though
|
# and selenium-webdriver < 2.20 fails on firefox 11 :-( So @wip for now. This may work with webkit though
|
||||||
Given I have a todo "delete me" in the context "@home" in the project "do it"
|
Given I have a todo "delete me" in the context "@home" in the project "do it"
|
||||||
And I have a project "go for it"
|
And I have a project "go for it"
|
||||||
And I have selected the view for group by <grouping>
|
And I have selected the view for group by <grouping>
|
||||||
|
@ -77,6 +77,7 @@ Feature: Edit a next action from every page
|
||||||
@javascript
|
@javascript
|
||||||
Scenario Outline: Deleting the last todo in container will show empty message # only project, context, tag, not todo
|
Scenario Outline: Deleting the last todo in container will show empty message # only project, context, tag, not todo
|
||||||
Given I have a context called "@home"
|
Given I have a context called "@home"
|
||||||
|
And I have selected the view for group by <grouping>
|
||||||
And I have a project "my project" that has the following todos
|
And I have a project "my project" that has the following todos
|
||||||
| context | description | tags |
|
| context | description | tags |
|
||||||
| @home | first action | test, bla |
|
| @home | first action | test, bla |
|
||||||
|
@ -90,12 +91,15 @@ Feature: Edit a next action from every page
|
||||||
Then I should see empty message for todos of <page type>
|
Then I should see empty message for todos of <page type>
|
||||||
|
|
||||||
Scenarios:
|
Scenarios:
|
||||||
| page | page type |
|
| page | page type | grouping |
|
||||||
| "my project" project | project |
|
| "my project" project | project | project |
|
||||||
| context page for "@home" | context |
|
| "my project" project | project | context |
|
||||||
| tag page for "bla" | tag |
|
| context page for "@home" | context | context |
|
||||||
|
| context page for "@home" | context | project |
|
||||||
|
| tag page for "bla" | tag | context |
|
||||||
|
| tag page for "bla" | tag | project |
|
||||||
|
|
||||||
@javascript
|
@javascript
|
||||||
Scenario Outline: I can mark an active todo complete and it will update empty messages
|
Scenario Outline: I can mark an active todo complete and it will update empty messages
|
||||||
Given I have a context called "visible context"
|
Given I have a context called "visible context"
|
||||||
And I have a project called "visible project"
|
And I have a project called "visible project"
|
||||||
|
@ -134,7 +138,7 @@ Feature: Edit a next action from every page
|
||||||
| "visible project" project | project |
|
| "visible project" project | project |
|
||||||
| context page for "visible context" | context |
|
| context page for "visible context" | context |
|
||||||
|
|
||||||
@javascript
|
@javascript
|
||||||
Scenario Outline: I can mark a completed todo active and it will update empty messages and context containers
|
Scenario Outline: I can mark a completed todo active and it will update empty messages and context containers
|
||||||
Given I have a completed todo with description "visible todo" in project "visible project" with tags "starred" in the context "visible context"
|
Given I have a completed todo with description "visible todo" in project "visible project" with tags "starred" in the context "visible context"
|
||||||
And I have selected the view for group by <grouping>
|
And I have selected the view for group by <grouping>
|
||||||
|
@ -155,8 +159,8 @@ Feature: Edit a next action from every page
|
||||||
| home page | home | context | container for context "visible context" |
|
| home page | home | context | container for context "visible context" |
|
||||||
| home page | home | project | container for project "visible project" |
|
| home page | home | project | container for project "visible project" |
|
||||||
|
|
||||||
@javascript
|
@javascript
|
||||||
Scenario Outline: I can mark a completed todo active and it will update empty messages for pages without context containers
|
Scenario Outline: I can mark a completed todo active and it will update empty messages for pages without hideable containers
|
||||||
Given I have a completed todo with description "visible todo" in project "visible project" with tags "starred" in the context "visible context"
|
Given I have a completed todo with description "visible todo" in project "visible project" with tags "starred" in the context "visible context"
|
||||||
When I go to the <page>
|
When I go to the <page>
|
||||||
Then I should see empty message for todos of <page type>
|
Then I should see empty message for todos of <page type>
|
||||||
|
|
|
@ -42,7 +42,7 @@ Feature: View, add, remove notes
|
||||||
And I edit the first note to "edited note"
|
And I edit the first note to "edited note"
|
||||||
Then I should see "edited note"
|
Then I should see "edited note"
|
||||||
|
|
||||||
@javascript
|
@javascript
|
||||||
Scenario: Toggle all notes
|
Scenario: Toggle all notes
|
||||||
Given I have a context called "@pc"
|
Given I have a context called "@pc"
|
||||||
And I have a project "take notes" that has the following todos
|
And I have a project "take notes" that has the following todos
|
||||||
|
|
|
@ -123,7 +123,7 @@ Feature: Edit a project
|
||||||
Scenario: Moving the todo to the tickler will move todo to tickler container and update empty messages
|
Scenario: Moving the todo to the tickler will move todo to tickler container and update empty messages
|
||||||
Given I have a project "test" with 1 todos
|
Given I have a project "test" with 1 todos
|
||||||
When I go to the "test" project
|
When I go to the "test" project
|
||||||
Then I should see "todo 1" in the action container
|
Then I should see "todo 1" in the context container for "Context A"
|
||||||
And I should see empty message for deferred todos of project
|
And I should see empty message for deferred todos of project
|
||||||
And I should see empty message for completed todos of project
|
And I should see empty message for completed todos of project
|
||||||
When I defer "todo 1" for 1 day
|
When I defer "todo 1" for 1 day
|
||||||
|
|
|
@ -97,7 +97,9 @@ Feature: Add new next action from every page
|
||||||
| tickler page | context | not see |
|
| tickler page | context | not see |
|
||||||
| tickler page | project | not see |
|
| tickler page | project | not see |
|
||||||
| "test project" project | context | see |
|
| "test project" project | context | see |
|
||||||
|
| "test project" project | project | see |
|
||||||
| context page for "test context" | context | see |
|
| context page for "test context" | context | see |
|
||||||
|
| context page for "test context" | project | see |
|
||||||
| tag page for "starred" | context | see |
|
| tag page for "starred" | context | see |
|
||||||
| tag page for "starred" | project | see |
|
| tag page for "starred" | project | see |
|
||||||
|
|
||||||
|
@ -124,7 +126,9 @@ Feature: Add new next action from every page
|
||||||
| tickler page | not see | 0 | 3 | context |
|
| tickler page | not see | 0 | 3 | context |
|
||||||
| tickler page | not see | 0 | 3 | project |
|
| tickler page | not see | 0 | 3 | project |
|
||||||
| "testing" project | see | 3 | 3 | context |
|
| "testing" project | see | 3 | 3 | context |
|
||||||
|
| "testing" project | see | 3 | 3 | project |
|
||||||
| context page for "test context" | see | 2 | 3 | context |
|
| context page for "test context" | see | 2 | 3 | context |
|
||||||
|
| context page for "test context" | see | 2 | 3 | project |
|
||||||
| tag page for "starred" | see | 2 | 3 | context |
|
| tag page for "starred" | see | 2 | 3 | context |
|
||||||
| tag page for "starred" | see | 2 | 3 | project |
|
| tag page for "starred" | see | 2 | 3 | project |
|
||||||
|
|
||||||
|
@ -199,9 +203,13 @@ Feature: Add new next action from every page
|
||||||
| tickler page | context | not see | not see |
|
| tickler page | context | not see | not see |
|
||||||
| tickler page | project | not see | not see |
|
| tickler page | project | not see | not see |
|
||||||
| "visible project" project | project | not see | see |
|
| "visible project" project | project | not see | see |
|
||||||
|
| "visible project" project | context | not see | see |
|
||||||
| "hidden project" project | project | see | not see |
|
| "hidden project" project | project | see | not see |
|
||||||
|
| "hidden project" project | context | see | not see |
|
||||||
| context page for "visible context" | context | not see | see |
|
| context page for "visible context" | context | not see | see |
|
||||||
|
| context page for "visible context" | project | not see | see |
|
||||||
| context page for "other context" | context | not see | not see |
|
| context page for "other context" | context | not see | not see |
|
||||||
|
| context page for "other context" | project | not see | not see |
|
||||||
| tag page for "starred" | context | not see | not see |
|
| tag page for "starred" | context | not see | not see |
|
||||||
| tag page for "starred" | project | not see | not see |
|
| tag page for "starred" | project | not see | not see |
|
||||||
| tag page for "test" | context | see | see |
|
| tag page for "test" | context | see | see |
|
||||||
|
|
|
@ -11,7 +11,9 @@ When(/^I collapse the project container of "(.*?)"$/) do |project_name|
|
||||||
end
|
end
|
||||||
|
|
||||||
When /^I toggle all collapsed context containers$/ do
|
When /^I toggle all collapsed context containers$/ do
|
||||||
click_link 'Toggle collapsed contexts'
|
open_view_menu do
|
||||||
|
click_link 'Toggle collapsed contexts'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
####### Context #######
|
####### Context #######
|
||||||
|
@ -91,7 +93,6 @@ Then(/^I should (not see|see) "([^"]*)" in the (completed|done today|done this w
|
||||||
id = 'completed_rest_of_month_container' if container == 'done this month'
|
id = 'completed_rest_of_month_container' if container == 'done this month'
|
||||||
|
|
||||||
css = "div##{id} div#line_todo_#{find_todo(todo_description).id}"
|
css = "div##{id} div#line_todo_#{find_todo(todo_description).id}"
|
||||||
page.should have_css(css)
|
|
||||||
check_css_visibility(visible, css)
|
check_css_visibility(visible, css)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -138,9 +139,8 @@ end
|
||||||
|
|
||||||
Then /^I should (see|not see) empty message for (done today|done this week|done this month|completed todos|deferred todos|todos) (of done actions|of context|of project|of home|of tag)/ do |visible, state, type|
|
Then /^I should (see|not see) empty message for (done today|done this week|done this month|completed todos|deferred todos|todos) (of done actions|of context|of project|of home|of tag)/ do |visible, state, type|
|
||||||
css = "error: wrong state"
|
css = "error: wrong state"
|
||||||
css = "div#c#{@context.id}-empty-d" if state == "todos" && type == "of context"
|
css = "div#c#{@context.id}-empty-d" if state == "todos"
|
||||||
css = "div#p#{@project.id}-empty-d" if state == "todos" && type == "of project"
|
css = "div#no_todos_in_view" if state == "todos" && ["of home", "of tag", "of context", "of project"].include?(type)
|
||||||
css = "div#no_todos_in_view" if state == "todos" && (type == "of home" || type == "of tag")
|
|
||||||
css = "div#completed_today_container" if state == "done today"
|
css = "div#completed_today_container" if state == "done today"
|
||||||
css = "div#completed_rest_of_week_container" if state == "done this week"
|
css = "div#completed_rest_of_week_container" if state == "done this week"
|
||||||
css = "div#completed_rest_of_month_container" if state == "done this month"
|
css = "div#completed_rest_of_month_container" if state == "done this month"
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
Given /^I have logged in as "(.*)" with password "(.*)"$/ do |username, password|
|
Given /^I have logged in as "(.*)" with password "(.*)"$/ do |username, password|
|
||||||
step "I go to the login page"
|
user = User.where(:login => username).first
|
||||||
fill_in "user_login", :with => username
|
request_signin_as(user)
|
||||||
fill_in "user_password", :with => password
|
@current_user = user
|
||||||
uncheck "user_noexpiry"
|
|
||||||
click_button "Sign in"
|
|
||||||
|
|
||||||
logout_regexp = @mobile_interface ? "Logout" : "Logout \(#{username}\)"
|
|
||||||
page.should have_content(logout_regexp)
|
|
||||||
@current_user = User.where(:login => username).first
|
|
||||||
end
|
end
|
||||||
|
|
||||||
When /^I submit the login form as user "([^\"]*)" with password "([^\"]*)"$/ do |username, password|
|
When /^I submit the login form as user "([^\"]*)" with password "([^\"]*)"$/ do |username, password|
|
||||||
|
|
|
@ -30,7 +30,7 @@ When /^I edit the first note to "([^"]*)"$/ do |note_body|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
When /^I toggle the note of "([^"]*)"$/ do |todo_description|
|
When(/^I toggle the note of "([^"]*)"$/) do |todo_description|
|
||||||
todo = @current_user.todos.where(:description => todo_description).first
|
todo = @current_user.todos.where(:description => todo_description).first
|
||||||
todo.should_not be_nil
|
todo.should_not be_nil
|
||||||
|
|
||||||
|
@ -39,7 +39,9 @@ When /^I toggle the note of "([^"]*)"$/ do |todo_description|
|
||||||
end
|
end
|
||||||
|
|
||||||
When /^I click Toggle Notes$/ do
|
When /^I click Toggle Notes$/ do
|
||||||
click_link 'Toggle notes'
|
open_view_menu do
|
||||||
|
click_link 'Toggle notes'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
When /^I toggle all notes$/ do
|
When /^I toggle all notes$/ do
|
||||||
|
|
|
@ -70,9 +70,9 @@ Given /^I have ([0-9]+) todos$/ do |count|
|
||||||
end
|
end
|
||||||
|
|
||||||
Given /^I have a todo with description "([^"]*)" in project "([^"]*)" with tags "([^"]*)" in the context "([^"]*)"$/ do |action_description, project_name, tags, context_name|
|
Given /^I have a todo with description "([^"]*)" in project "([^"]*)" with tags "([^"]*)" in the context "([^"]*)"$/ do |action_description, project_name, tags, context_name|
|
||||||
context = @current_user.contexts.where(:name => context_name).first_or_create
|
@context = @current_user.contexts.where(:name => context_name).first_or_create
|
||||||
project = @current_user.projects.where(:name => project_name).first_or_create
|
@project = @current_user.projects.where(:name => project_name).first_or_create
|
||||||
@todo = @current_user.todos.create!(:context_id => context.id, :project_id => project.id, :description => action_description)
|
@todo = @current_user.todos.create!(:context_id => @context.id, :project_id => @project.id, :description => action_description)
|
||||||
@todo.tag_with(tags)
|
@todo.tag_with(tags)
|
||||||
@todo.save
|
@todo.save
|
||||||
end
|
end
|
||||||
|
|
52
features/support/tracks_login_helper.rb
Normal file
52
features/support/tracks_login_helper.rb
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
class SessionBackdoorController < ::ApplicationController
|
||||||
|
skip_before_filter :login_required
|
||||||
|
|
||||||
|
def create
|
||||||
|
session['user_id'] = params[:user_id]
|
||||||
|
user = User.find(params[:user_id])
|
||||||
|
set_current_user(user)
|
||||||
|
user.remember_me
|
||||||
|
cookies[:auth_token] = { :value => user.remember_token, :expires => user.remember_token_expires_at }
|
||||||
|
redirect_to root_path
|
||||||
|
end
|
||||||
|
|
||||||
|
def expire_session
|
||||||
|
current_user.forget_me if logged_in?
|
||||||
|
cookies.delete :auth_token
|
||||||
|
session['user_id'] = nil
|
||||||
|
reset_session
|
||||||
|
session['expiry_time'] = Time.now
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { render :text => "Session expired for test purposes"}
|
||||||
|
format.js { render :text => "" }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module TracksLoginHelper
|
||||||
|
begin
|
||||||
|
_routes = Rails.application.routes
|
||||||
|
_routes.disable_clear_and_finalize = true
|
||||||
|
_routes.clear!
|
||||||
|
Rails.application.routes_reloader.paths.each{ |path| load(path) }
|
||||||
|
_routes.draw do
|
||||||
|
# here you can add any route you want
|
||||||
|
match "/test_login_backdoor", to: "session_backdoor#create"
|
||||||
|
match "login/expire_session", to: "session_backdoor#expire_session"
|
||||||
|
end
|
||||||
|
ActiveSupport.on_load(:action_controller) { _routes.finalize! }
|
||||||
|
ensure
|
||||||
|
_routes.disable_clear_and_finalize = false
|
||||||
|
end
|
||||||
|
|
||||||
|
def request_signin_as(user)
|
||||||
|
visit "/test_login_backdoor?user_id=#{user.id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def signin_as(user)
|
||||||
|
session[:user_id] = user.id
|
||||||
|
@current_user = user
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -97,6 +97,23 @@ module TracksStepHelper
|
||||||
execute_javascript("$('#{sortable_css}').simulateDragSortable({move: #{delta}, handle: '.grip'});")
|
execute_javascript("$('#{sortable_css}').simulateDragSortable({move: #{delta}, handle: '.grip'});")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def open_view_menu
|
||||||
|
view_menu = "ul.sf-menu li#menu_view"
|
||||||
|
|
||||||
|
# click menu
|
||||||
|
view_menu_link = "#{view_menu} a#menu_view_link"
|
||||||
|
page.should have_css(view_menu_link, :visible => true)
|
||||||
|
page.find(view_menu_link).click
|
||||||
|
|
||||||
|
# wait for menu to be visible
|
||||||
|
view_menu_item = "#{view_menu} li#menu_view_toggle_contexts"
|
||||||
|
page.should have_css(view_menu_item)
|
||||||
|
|
||||||
|
within view_menu do
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def open_submenu_for(todo)
|
def open_submenu_for(todo)
|
||||||
submenu_arrow = "div#line_todo_#{todo.id} img.todo-submenu"
|
submenu_arrow = "div#line_todo_#{todo.id} img.todo-submenu"
|
||||||
page.should have_css(submenu_arrow, :visible=>true)
|
page.should have_css(submenu_arrow, :visible=>true)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
World(TracksLoginHelper)
|
||||||
World(TracksStepHelper)
|
World(TracksStepHelper)
|
||||||
World(TracksFormHelper)
|
World(TracksFormHelper)
|
||||||
World(TracksIdHelper)
|
World(TracksIdHelper)
|
||||||
|
|
|
@ -60,7 +60,7 @@ Feature: Toggle the containers
|
||||||
And I should not see the todo "test 2"
|
And I should not see the todo "test 2"
|
||||||
And I should not see the todo "test 3"
|
And I should not see the todo "test 3"
|
||||||
|
|
||||||
@javascript
|
@javascript
|
||||||
Scenario: I can hide all collapsed context containers
|
Scenario: I can hide all collapsed context containers
|
||||||
Given I have the following contexts
|
Given I have the following contexts
|
||||||
| context | hide |
|
| context | hide |
|
||||||
|
@ -87,7 +87,7 @@ Feature: Toggle the containers
|
||||||
And I should not see the context container for "@boss"
|
And I should not see the context container for "@boss"
|
||||||
And I should not see the context container for "@ipad"
|
And I should not see the context container for "@ipad"
|
||||||
|
|
||||||
@javascript
|
@javascript
|
||||||
Scenario: I can hide all collapsed project containers
|
Scenario: I can hide all collapsed project containers
|
||||||
Given I have the following contexts
|
Given I have the following contexts
|
||||||
| context | hide |
|
| context | hide |
|
||||||
|
|
|
@ -235,6 +235,52 @@ class RecurringTodosControllerTest < ActionController::TestCase
|
||||||
assert_equal true, recurring_todo.show_always?
|
assert_equal true, recurring_todo.show_always?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_start_on_monthly_rec_todo
|
||||||
|
Timecop.travel(Time.local(2012,1,1)) do
|
||||||
|
|
||||||
|
login_as(:admin_user)
|
||||||
|
|
||||||
|
put :create,
|
||||||
|
"context_name"=>"library",
|
||||||
|
"project_name"=>"Build a working time machine",
|
||||||
|
"recurring_todo" =>
|
||||||
|
{
|
||||||
|
"daily_every_x_days"=>"1",
|
||||||
|
"daily_selector"=>"daily_every_x_day",
|
||||||
|
"description"=>"new recurring pattern",
|
||||||
|
"end_date" => nil,
|
||||||
|
"ends_on" => "no_end_date",
|
||||||
|
"monthly_day_of_week" => "2",
|
||||||
|
"monthly_every_x_day" => "2",
|
||||||
|
"monthly_every_x_month2" => "1",
|
||||||
|
"monthly_every_x_month" => "3",
|
||||||
|
"monthly_every_xth_day"=>"1",
|
||||||
|
"monthly_selector"=>"monthly_every_x_day",
|
||||||
|
"notes"=>"with some notes",
|
||||||
|
"number_of_occurences" => nil,
|
||||||
|
"recurring_period"=>"monthly",
|
||||||
|
"recurring_show_days_before"=>"0",
|
||||||
|
"recurring_target"=>"show_from_date",
|
||||||
|
"recurring_show_always" => "1",
|
||||||
|
"start_from"=>"2/1/2013",
|
||||||
|
"weekly_every_x_week"=>"1",
|
||||||
|
"weekly_return_monday"=>"m",
|
||||||
|
"yearly_day_of_week"=>"1",
|
||||||
|
"yearly_every_x_day"=>"8",
|
||||||
|
"yearly_every_xth_day"=>"1",
|
||||||
|
"yearly_month_of_year2"=>"8",
|
||||||
|
"yearly_month_of_year"=>"6",
|
||||||
|
"yearly_selector"=>"yearly_every_x_day"
|
||||||
|
},
|
||||||
|
"tag_list"=>"one, two, three, four"
|
||||||
|
|
||||||
|
assert_equal "new recurring pattern", assigns['recurring_todo'].description
|
||||||
|
assert_equal "2013-01-02 00:00:00 +0000", assigns['recurring_todo'].start_from.to_s
|
||||||
|
todo = assigns['recurring_todo'].todos.first
|
||||||
|
assert_equal "2013-01-02 00:00:00 +0000", todo.show_from.to_s
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_find_and_inactivate
|
def test_find_and_inactivate
|
||||||
login_as(:admin_user)
|
login_as(:admin_user)
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,28 @@ class TodosControllerTest < ActionController::TestCase
|
||||||
assert_response :success
|
assert_response :success
|
||||||
assert_equal 3, @tagged
|
assert_equal 3, @tagged
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_find_tagged_with_terms_separated_with_dot
|
||||||
|
login_as :admin_user
|
||||||
|
create_todo(description: "test dotted tag", tag_list: "first.last, second")
|
||||||
|
t = assigns['todo']
|
||||||
|
assert_equal "first.last, second", t.tag_list
|
||||||
|
|
||||||
|
get :tag, name: 'first.last.m'
|
||||||
|
assert_equal "text/html", request.format, "controller should set right content type"
|
||||||
|
assert_equal "text/html", @response.content_type
|
||||||
|
assert_equal "first.last", assigns['tag_name'], ".m should be chomped"
|
||||||
|
|
||||||
|
get :tag, name: 'first.last.txt'
|
||||||
|
assert_equal "text/plain", request.format, "controller should set right content type"
|
||||||
|
assert_equal "text/plain", @response.content_type
|
||||||
|
assert_equal "first.last", assigns['tag_name'], ".txt should be chomped"
|
||||||
|
|
||||||
|
get :tag, name: 'first.last'
|
||||||
|
assert_equal "text/html", request.format, "controller should set right content type"
|
||||||
|
assert_equal "text/html", @response.content_type
|
||||||
|
assert_equal "first.last", assigns['tag_name'], ":name should be correct"
|
||||||
|
end
|
||||||
|
|
||||||
def test_get_boolean_expression_from_parameters_of_tag_view_single_tag
|
def test_get_boolean_expression_from_parameters_of_tag_view_single_tag
|
||||||
login_as(:admin_user)
|
login_as(:admin_user)
|
||||||
|
@ -669,7 +691,7 @@ class TodosControllerTest < ActionController::TestCase
|
||||||
recurring_todo_1 = RecurringTodo.find(1)
|
recurring_todo_1 = RecurringTodo.find(1)
|
||||||
#set_user_to_current_time_zone(recurring_todo_1.user)
|
#set_user_to_current_time_zone(recurring_todo_1.user)
|
||||||
todo_1 = Todo.where(:recurring_todo_id => 1).first
|
todo_1 = Todo.where(:recurring_todo_id => 1).first
|
||||||
today = Time.zone.now.at_midnight
|
today = Time.zone.now.at_midnight - 1.day
|
||||||
|
|
||||||
# change recurrence pattern to monthly and set show_from to today
|
# change recurrence pattern to monthly and set show_from to today
|
||||||
recurring_todo_1.target = 'show_from_date'
|
recurring_todo_1.target = 'show_from_date'
|
||||||
|
@ -708,7 +730,7 @@ class TodosControllerTest < ActionController::TestCase
|
||||||
assert !new_todo.show_from.nil?
|
assert !new_todo.show_from.nil?
|
||||||
|
|
||||||
# do not use today here. It somehow gets messed up with the timezone calculation.
|
# do not use today here. It somehow gets messed up with the timezone calculation.
|
||||||
next_month = (Time.zone.now + 1.month).at_midnight
|
next_month = (Time.zone.now - 1.day + 1.month).at_midnight
|
||||||
|
|
||||||
assert_equal next_month.utc.to_date.to_s(:db), new_todo.show_from.utc.to_date.to_s(:db)
|
assert_equal next_month.utc.to_date.to_s(:db), new_todo.show_from.utc.to_date.to_s(:db)
|
||||||
end
|
end
|
||||||
|
@ -920,4 +942,19 @@ class TodosControllerTest < ActionController::TestCase
|
||||||
assert t4.pending?, "t4 should remain pending"
|
assert t4.pending?, "t4 should remain pending"
|
||||||
assert t4.predecessors.map(&:id).include?(t3.id)
|
assert t4.predecessors.map(&:id).include?(t3.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def create_todo(params={})
|
||||||
|
defaults = { source_view: 'todo',
|
||||||
|
context_name: "library", project_name: "Build a working time machine",
|
||||||
|
notes: "note", description: "a new todo", due: nil, tag_list: "a,b,c"}
|
||||||
|
|
||||||
|
params=params.reverse_merge(defaults)
|
||||||
|
|
||||||
|
put :create, _source_view: params[:_source_view],
|
||||||
|
context_name: params[:context_name], project_name: params[:project_name], tag_list: params[:tag_list],
|
||||||
|
todo: {notes: params[:notes], description: params[:description], due: params[:due]}
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -175,6 +175,9 @@ class RecurringTodoTest < ActiveSupport::TestCase
|
||||||
assert_equal @sunday, due_date # june 8th
|
assert_equal @sunday, due_date # june 8th
|
||||||
|
|
||||||
due_date = @monthly.get_due_date(@sunday) # june 8th
|
due_date = @monthly.get_due_date(@sunday) # june 8th
|
||||||
|
assert_equal Time.zone.local(2008,6,8), due_date # june 8th
|
||||||
|
|
||||||
|
due_date = @monthly.get_due_date(@monday) # june 9th
|
||||||
assert_equal Time.zone.local(2008,8,8), due_date # aug 8th
|
assert_equal Time.zone.local(2008,8,8), due_date # aug 8th
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,6 @@ class TaggingTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
tagging.destroy
|
tagging.destroy
|
||||||
|
|
||||||
assert_nil Tag.where(:name => "hello").first
|
assert_nil Tag.where(:name => "hello").first, "Tag should be destroyed when last use in tagging was removed"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -239,6 +239,26 @@ class TodoTest < ActiveSupport::TestCase
|
||||||
assert !@not_completed1.starred?
|
assert !@not_completed1.starred?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_hidden_todo_remains_hidden_after_getting_unblokked
|
||||||
|
todo = todos(:call_bill)
|
||||||
|
project=todo.project
|
||||||
|
project.hide!
|
||||||
|
|
||||||
|
assert todo.reload.hidden?, "todo in hidden project should be hidden"
|
||||||
|
|
||||||
|
todo2 = todos(:call_dino_ext)
|
||||||
|
todo.add_predecessor(todo2)
|
||||||
|
todo.block!
|
||||||
|
|
||||||
|
assert todo.pending?, "todo with predecessor should be blocked"
|
||||||
|
|
||||||
|
# cannot activate if part of hidden project
|
||||||
|
assert_raise(AASM::InvalidTransition) { todo.activate! }
|
||||||
|
|
||||||
|
todo.remove_predecessor(todo2)
|
||||||
|
assert todo.reload.hidden?, "todo should be put back in hidden state"
|
||||||
|
end
|
||||||
|
|
||||||
def test_todo_specification_handles_null_project
|
def test_todo_specification_handles_null_project
|
||||||
# @not_completed1 has a project
|
# @not_completed1 has a project
|
||||||
todo_desc = @not_completed1.description
|
todo_desc = @not_completed1.description
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue