make adding of todos from sidebar work in context and project grouping

This commit is contained in:
Reinier Balt 2013-04-11 10:53:35 +02:00
parent 783d4dd774
commit 9c0445fcb7
17 changed files with 528 additions and 389 deletions

View file

@ -3,7 +3,7 @@ class TodosController < ApplicationController
skip_before_filter :login_required, :only => [:index, :calendar, :tag]
prepend_before_filter :login_or_feed_token_required, :only => [:index, :calendar, :tag]
append_before_filter :find_and_activate_ready, :only => [:index, :list_deferred]
append_before_filter :set_group_view_by, :only => [:index, :tag]
append_before_filter :set_group_view_by, :only => [:index, :tag, :create, :list_deferred, :destroy, :defer, :update]
protect_from_forgery :except => :check_deferred
@ -93,6 +93,7 @@ class TodosController < ApplicationController
if p.project_specified_by_name?
project = current_user.projects.where(:name => p.project_name).first_or_create
@new_project_created = project.new_record_before_save?
@not_done_todos = [@todo] if @new_project_created
@todo.project_id = project.id
elsif !(p.project_id.nil? || p.project_id.blank?)
project = current_user.projects.where(:id => p.project_id).first
@ -197,12 +198,11 @@ class TodosController < ApplicationController
# first build all todos and check if they would validate on save
params[:todo][:multiple_todos].split("\n").map do |line|
unless line.blank?
@todo = current_user.todos.build(
:description => line)
unless line.blank? #ignore blank lines
@todo = current_user.todos.build(:description => line)
@todo.project_id = @project_id
@todo.context_id = @context_id
validates = false if @todo.invalid?
validates &&= @todo.valid?
@todos_init << @todo
end
@ -358,7 +358,7 @@ class TodosController < ApplicationController
respond_to do |format|
format.js do
if @saved
determine_remaining_in_context_count(@todo.context_id)
determine_remaining_in_container_count(@todo)
determine_down_count
determine_completed_count
determine_deferred_tag_count(params['_tag_name']) if source_view_is(:tag)
@ -441,11 +441,12 @@ class TodosController < ApplicationController
end
def update
@todo = current_user.todos.find(params['id'])
@source_view = params['_source_view'] || 'todo'
# init_data_for_sidebar unless mobile?
cache_attributes_from_before_update
@todo = current_user.todos.find(params['id'])
@original_item = current_user.todos.build(@todo.attributes) # create a (unsaved) copy of the original todo
cache_attributes_from_before_update # TODO: remove in favor of @orininal_item
update_tags
update_project
@ -466,7 +467,7 @@ class TodosController < ApplicationController
update_todo_state_if_project_changed
determine_changes_by_this_update
determine_remaining_in_context_count(@context_changed ? @original_item_context_id : @todo.context_id)
determine_remaining_in_container_count(@context_changed || @project_changed ? @original_item : @todo)
determine_down_count
determine_deferred_tag_count(params['_tag_name']) if source_view_is(:tag)
@ -495,6 +496,7 @@ class TodosController < ApplicationController
@original_item_due = @todo.due
@context_id = @todo.context_id
@project_id = @todo.project_id
@todo_was_destroyed = true
@todo_was_destroyed_from_deferred_state = @todo.deferred?
@todo_was_destroyed_from_pending_state = @todo.pending?
@todo_was_destroyed_from_deferred_or_pending_state = @todo_was_destroyed_from_deferred_state || @todo_was_destroyed_from_pending_state
@ -540,8 +542,8 @@ class TodosController < ApplicationController
format.js do
if @saved
determine_down_count
if source_view_is_one_of(:todo, :deferred, :project, :context)
determine_remaining_in_context_count(@context_id)
if source_view_is_one_of(:todo, :deferred, :project, :context, :tag)
determine_remaining_in_container_count(@todo)
elsif source_view_is :calendar
@original_item_due_id = get_due_id_for_calendar(@original_item_due)
@old_due_empty = is_old_due_empty(@original_item_due_id)
@ -656,6 +658,7 @@ class TodosController < ApplicationController
blocked.
reorder('todos.show_from ASC, todos.created_at DESC').
includes(Todo::DEFAULT_INCLUDES)
@todos_without_project = @not_done_todos.select{|t| t.project.nil?}
# If you've set no_completed to zero, the completed items box isn't shown on
# the tag page
@ -735,6 +738,8 @@ class TodosController < ApplicationController
numdays = params['days'].to_i
@todo = current_user.todos.find(params[:id])
@original_item = current_user.todos.build(@todo.attributes) # create a (unsaved) copy of the original todo
@original_item_context_id = @todo.context_id
@todo_deferred_state_changed = true
@new_context_created = false
@ -748,7 +753,7 @@ class TodosController < ApplicationController
@status_message = t('todos.action_saved_to_tickler')
determine_down_count
determine_remaining_in_context_count(@todo.context_id)
determine_remaining_in_container_count(@todo)
source_view do |page|
page.project {
@remaining_undone_in_project = current_user.projects.find(@todo.project_id).todos.not_completed.count
@ -886,7 +891,7 @@ class TodosController < ApplicationController
private
def set_group_view_by
@group_view_by = params['group_view_by'] || cookies['group_view_by'] || 'context'
@group_view_by = params['_group_view_by'] || cookies['group_view_by'] || 'context'
end
def do_mobile_todo_redirection
@ -1005,21 +1010,48 @@ class TodosController < ApplicationController
end
end
def determine_remaining_in_context_count(context_id = @todo.context_id)
def find_todos_in_project_container(todo)
if todo.project.nil?
# container with todos without project
todos_in_container = current_user.todos.where(:project_id => nil).active.not_hidden
else
todos_in_container = current_user.projects.find(todo.project_id).todos.active.not_hidden
end
end
def find_todos_in_container_and_target_container(todo, target_todo)
if @group_view_by == 'context'
todos_in_container = current_user.contexts.find(todo.context_id).todos.active.not_hidden
todos_in_target_container = current_user.contexts.find(@todo.context_id).todos.active.not_hidden
else
todos_in_container = find_todos_in_project_container(todo)
todos_in_target_container = find_todos_in_project_container(@todo)
end
return todos_in_container, todos_in_target_container
end
def determine_remaining_in_container_count(todo = @todo)
source_view do |from|
from.deferred {
# force reload to todos to get correct count and not a cached one
@remaining_in_context = current_user.contexts.find(context_id).todos.deferred_or_blocked.count
@remaining_in_context = current_user.contexts.find(todo.context_id).todos.deferred_or_blocked.count
@target_context_count = current_user.contexts.find(@todo.context_id).todos.deferred_or_blocked.count
}
from.todo {
todos_in_container, todos_in_target_container = find_todos_in_container_and_target_container(todo, @todo)
@remaining_in_context = todos_in_container.active.not_hidden.count
@target_context_count = todos_in_target_container.active.not_hidden.count
}
from.tag {
tag = Tag.where(:name => params['_tag_name']).first
tag = Tag.new(:name => params['tag']) if tag.nil?
@remaining_deferred_or_pending_count = current_user.todos.with_tag(tag.id).deferred_or_blocked.count
@remaining_in_context = current_user.contexts.find(context_id).todos.active.not_hidden.with_tag(tag.id).count
@target_context_count = current_user.contexts.find(@todo.context_id).todos.active.not_hidden.with_tag(tag.id).count
todos_in_container, todos_in_target_container = find_todos_in_container_and_target_container(todo, @todo)
@remaining_in_context = todos_in_container.with_tag(tag.id).count
@target_context_count = todos_in_target_container.with_tag(tag.id).count
@remaining_hidden_count = current_user.todos.hidden.with_tag(tag.id).count
@remaining_deferred_or_pending_count = current_user.todos.with_tag(tag.id).deferred_or_blocked.count
}
from.project {
project_id = @project_changed ? @original_item_project_id : @todo.project_id
@ -1037,7 +1069,7 @@ class TodosController < ApplicationController
@target_context_count = @new_due_id.blank? ? 0 : count_old_due_empty(@new_due_id)
}
from.context {
context = current_user.contexts.find(context_id)
context = current_user.contexts.find(todo.context_id)
@remaining_deferred_or_pending_count = context.todos.deferred_or_blocked.count
remaining_actions_in_context = context.todos(true).active
@ -1056,8 +1088,6 @@ class TodosController < ApplicationController
@remaining_in_context = DoneTodos.remaining_in_container(current_user, @original_completed_period)
}
end
@remaining_in_context = current_user.contexts.find(context_id).todos(true).active.not_hidden.count if @remaining_in_context.nil?
@target_context_count = current_user.contexts.find(@todo.context_id).todos(true).active.not_hidden.count if !@target_context_count.nil?
end
def determine_completed_count

View file

@ -1,5 +1,7 @@
module TodosHelper
# === helpers for rendering container
def empty_message_holder(container_name, show, title_param=nil)
content_tag(:div, :id => "no_todos_in_view", :class => "container #{container_name}", :style => "display:" + (show ? "block" : "none") ) do
content_tag(:h2) { t("todos.no_actions.title", :param=>title_param) } +
@ -126,6 +128,8 @@ module TodosHelper
end
end
# === helpers for rendering a todo
def remote_star_icon(todo=@todo)
link_to( image_tag_for_star(todo),
toggle_star_todo_path(todo),
@ -212,6 +216,10 @@ module TodosHelper
:class => "recurring_icon", :title => recurrence_pattern_as_text(todo.recurring_todo))
end
def image_tag_for_star(todo)
image_tag("blank.png", :title =>t('todos.star_action'), :class => "todo_star"+(todo.starred? ? " starred":""), :id => "star_img_"+todo.id.to_s)
end
def remote_toggle_checkbox(todo=@todo)
check_box_tag("mark_complete_#{todo.id}", toggle_check_todo_path(todo), todo.completed?, :class => 'item-checkbox',
:title => todo.pending? ? t('todos.blocked_by', :predecessors => todo.uncompleted_predecessors.map(&:description).join(', ')) : "", :readonly => todo.pending?)
@ -348,51 +356,11 @@ module TodosHelper
end
end
def should_show_new_item
source_view do |page|
page.todo { return !@todo.hidden? }
page.deferred { return @todo.deferred? || @todo.pending? }
page.context {
return @todo.context_id==@default_context.id && ( (@todo.hidden? && @todo.context.hidden?) || (!@todo.hidden?) )
}
page.tag {
return ( (@todo.pending? && @todo.has_tag?(@tag_name)) ||
(@todo.has_tag?(@tag_name)) ||
(@todo.starred? && @tag_name == Todo::STARRED_TAG_NAME)
)
}
page.project {
return (@todo.active? && @todo.project && @todo.project.id == @default_project.id) ||
(@todo.project.hidden? && @todo.project_hidden?) ||
( @todo.deferred? && (@todo.project.id == @default_project.id) ) ||
@todo.pending?
}
end
return false
def date_field_tag(name, id, value = nil, options = {})
text_field_tag name, value, {"size" => 12, "id" => id, "class" => "Date", "autocomplete" => "off"}.update(options.stringify_keys)
end
def should_make_context_visible
return @todo.active? && (!@todo.hidden? && !source_view_is(:project) )
end
def should_add_new_context
return @new_context_created && !source_view_is(:project)
end
def parent_container_type
return 'tickler' if source_view_is :deferred
return 'project' if source_view_is :project
return 'stats' if source_view_is :stats
return 'tag' if source_view_is :tag
return 'context'
end
def todo_container_is_empty
default_container_empty = ( @down_count == 0 )
deferred_container_empty = ( @todo.deferred? && @remaining_deferred_count == 0)
return default_container_empty || deferred_container_empty
end
# === helpers for default layout
def default_contexts_for_autocomplete
projects = current_user.projects.uncompleted.includes(:default_context).where('NOT(default_context_id IS NULL)')
@ -404,6 +372,13 @@ module TodosHelper
Hash[*projects.map{ |p| [escape_javascript(p.name), p.default_tags] }.flatten].to_json
end
# === various helpers
def formatted_pagination(total)
s = will_paginate(@todos)
(s.gsub(/(<\/[^<]+>)/, '\1 ')).chomp(' ')
end
def format_ical_notes(notes)
unless notes.nil? || notes.blank?
split_notes = notes.split(/\n/)
@ -412,145 +387,12 @@ module TodosHelper
joined_notes || ""
end
def formatted_pagination(total)
s = will_paginate(@todos)
(s.gsub(/(<\/[^<]+>)/, '\1 ')).chomp(' ')
end
def date_field_tag(name, id, value = nil, options = {})
text_field_tag name, value, {"size" => 12, "id" => id, "class" => "Date", "autocomplete" => "off"}.update(options.stringify_keys)
end
def update_needs_to_hide_context
return (@remaining_in_context == 0 && (@todo_hidden_state_changed && @todo.hidden?)) ||
(@remaining_in_context == 0 && @todo_was_deferred_from_active_state) ||
(@remaining_in_context == 0 && @tag_was_removed) ||
(@remaining_in_context == 0 && @todo.completed? && !(@original_item_was_deferred || @original_item_was_hidden)) if source_view_is(:tag)
return false if source_view_is_one_of(:project, :calendar, :done)
return (@remaining_in_context == 0) && !source_view_is(:context)
end
def update_needs_to_remove_todo_from_container
source_view do |page|
page.context { return @context_changed || @todo_deferred_state_changed || @todo_pending_state_changed || @todo_should_be_hidden }
page.project { return @todo_deferred_state_changed || @todo_pending_state_changed || @project_changed}
page.deferred { return @context_changed || !(@todo.deferred? || @todo.pending?) }
page.calendar { return @due_date_changed || !@todo.due }
page.stats { return @todo.completed? }
page.tag { return (@context_changed && !@todo.hidden?) || @tag_was_removed || @todo_hidden_state_changed || @todo_deferred_state_changed }
page.todo { return @context_changed || @todo.hidden? || @todo.deferred? || @todo.pending?}
page.search { return false }
end
return false
end
def replace_with_updated_todo
source_view do |page|
page.context { return !update_needs_to_remove_todo_from_container }
page.project { return !update_needs_to_remove_todo_from_container }
page.deferred { return !@context_changed && (@todo.deferred? || @todo.pending?) }
page.calendar { return !@due_date_changed && @todo.due }
page.stats { return !@todo.completed? }
page.tag { return !update_needs_to_remove_todo_from_container && !@tag_was_removed }
page.todo { return !update_needs_to_remove_todo_from_container }
page.search { return true }
end
return false
end
def append_updated_todo
source_view do |page|
page.context { return @todo_deferred_state_changed || @todo_pending_state_changed }
page.project { return @todo_deferred_state_changed || @todo_pending_state_changed }
page.deferred { return @context_changed && (@todo.deferred? || @todo.pending?) }
page.calendar { return @due_date_changed && @todo.due }
page.stats { return false }
page.tag { return update_needs_to_remove_todo_from_container && !@tag_was_removed}
page.todo { return @context_changed && !(@todo.deferred? || @todo.pending? || @todo.hidden?) }
end
return false
end
def item_container_id (todo)
return "hidden_container_items" if source_view_is(:tag) && todo.hidden?
return "c#{todo.context_id}_items" if source_view_is :deferred
return @new_due_id if source_view_is :calendar
return "deferred_pending_container_items" if !source_view_is(:todo) && (todo.deferred? || todo.pending?)
return "completed_container_items" if todo.completed?
return "p#{todo.project_id}_items" if source_view_is :project
return "c#{todo.context_id}_items"
end
def empty_container_msg_div_id(todo = @todo || @successor)
raise Exception.new, "no @todo or @successor set" if !todo
source_view do |page|
page.project {
return "deferred_pending_container-empty-d" if empty_criteria_met
return "p#{todo.project_id}-empty-d"
}
page.tag {
return "deferred_pending_container-empty-d" if empty_criteria_met
return "hidden_container-empty-d" if @todo.hidden?
return "c#{todo.context_id}-empty-d"
}
page.calendar {
return "deferred_pending_container-empty-d" if empty_criteria_met
return "empty_#{@new_due_id}"
}
page.context {
return "deferred_pending_container-empty-d" if empty_criteria_met
return "c#{todo.context_id}-empty-d"
}
end
return "c#{todo.context_id}-empty-d"
end
def empty_criteria_met
@todo_was_deferred_from_active_state ||
@todo_was_blocked_from_active_state ||
@todo_was_destroyed_from_deferred_state ||
@todo_was_created_deferred ||
@todo_was_blocked_from_completed_state ||
@todo_was_created_blocked
end
def todo_was_removed_from_deferred_or_blocked_container
return @todo_was_activated_from_deferred_state ||
@todo_was_activated_from_pending_state ||
@todo_was_destroyed_from_deferred_or_pending_state ||
@todo_was_completed_from_deferred_or_blocked_state
end
def show_empty_message_in_source_container
container_id = ""
source_view do |page|
page.project {
container_id = "p#{@original_item_project_id}-empty-d" if @remaining_in_context == 0
container_id = "deferred_pending_container-empty-d" if todo_was_removed_from_deferred_or_blocked_container && @remaining_deferred_or_pending_count == 0
container_id = "completed_container-empty-d" if @completed_count && @completed_count == 0 && !@todo.completed?
}
page.deferred { container_id = "c#{@original_item_context_id}empty-d" if @remaining_in_context == 0 }
page.calendar { container_id = "empty_#{@original_item_due_id}" if @old_due_empty }
page.tag {
container_id = "hidden_container-empty-d" if (@remaining_hidden_count == 0 && !@todo.hidden? && @todo_hidden_state_changed) ||
(@remaining_hidden_count == 0 && @todo.completed? && @original_item_was_hidden)
container_id = "deferred_pending_container-empty-d" if (todo_was_removed_from_deferred_or_blocked_container && @remaining_deferred_or_pending_count == 0) ||
(@original_item_was_deferred && @remaining_deferred_or_pending_count == 0 && (@todo.completed? || @tag_was_removed))
container_id = "completed_container-empty-d" if @completed_count && @completed_count == 0 && !@todo.completed?
}
page.context {
container_id = "c#{@original_item_context_id}-empty-d" if @remaining_in_context == 0
container_id = "deferred_pending_container-empty-d" if todo_was_removed_from_deferred_or_blocked_container && @remaining_deferred_or_pending_count == 0
container_id = "completed_container-empty-d" if @completed_count && @completed_count == 0 && !@todo.completed?
}
page.todo { container_id = "c#{@original_item_context_id}-empty-d" if @remaining_in_context == 0 }
page.done { container_id = "completed_#{@original_completed_period}_container-empty-d" if @remaining_in_context == 0 }
end
return container_id.blank? ? "" : "$(\"##{container_id}\").slideDown(100);".html_safe
def parent_container_type
return 'tickler' if source_view_is :deferred
return 'project' if source_view_is :project
return 'stats' if source_view_is :stats
return 'tag' if source_view_is :tag
return 'context'
end
def render_animation(animation)
@ -587,10 +429,208 @@ module TodosHelper
content_tag(:div, "#{t('common.context')}: #{context_link}")
end
private
# === handle CRUD actions for todos
def image_tag_for_star(todo)
image_tag("blank.png", :title =>t('todos.star_action'), :class => "todo_star"+(todo.starred? ? " starred":""), :id => "star_img_"+todo.id.to_s)
def show_todo_on_current_context_page
return @todo.context_id==@default_context.id
end
def todo_should_not_be_hidden_on_context_page
return !@todo.hidden? || # todo is not hidden --> show
(@todo.hidden? && @todo.context.hidden?) # todo is hidden, but context is hidden too --> show
end
def show_todo_on_current_project_page
return @todo.project.id == @default_project.id
end
def todo_should_not_be_hidden_on_project_page
return !@todo.hidden? ||
(@todo.project_hidden? && @todo.project.hidden?)
end
def should_show_new_item(todo = @todo)
return false if todo.nil?
source_view do |page|
page.todo { return !todo.hidden? }
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.tag { return todo.has_tag?(@tag_name) }
page.project { return show_todo_on_current_project_page && todo_should_not_be_hidden_on_project_page }
end
return false
end
def should_make_context_visible
return @todo.active? && (!@todo.hidden? && !source_view_is(:project) )
end
def should_add_new_container
if @group_view_by == 'project'
return @new_project_created && !source_view_is(:context)
else
return @new_context_created && !source_view_is(:project)
end
end
def todo_container_is_empty
default_container_empty = ( @down_count == 0 )
deferred_container_empty = ( @todo.deferred? && @remaining_deferred_count == 0)
return default_container_empty || deferred_container_empty
end
def todo_moved_out_of_container
return (@project_changed && @group_view_by=='project') || (@context_changed && @group_view_by='context')
end
def update_needs_to_hide_container
return (@remaining_in_context == 0 && todo_moved_out_of_container ) ||
(@remaining_in_context == 0 && (@todo_hidden_state_changed && @todo.hidden?)) ||
(@remaining_in_context == 0 && @todo_was_deferred_from_active_state) ||
(@remaining_in_context == 0 && @tag_was_removed) ||
(@remaining_in_context == 0 && @todo_was_destroyed) ||
(@remaining_in_context == 0 && @todo.completed? && !(@original_item_was_deferred || @original_item_was_hidden)) if source_view_is(:tag)
return false if source_view_is_one_of(:project, :calendar, :done)
return (@remaining_in_context == 0) && !source_view_is(:context)
end
def update_needs_to_remove_todo_from_container
source_view do |page|
page.context { return @context_changed || @todo_deferred_state_changed || @todo_pending_state_changed || @todo_should_be_hidden }
page.project { return @todo_deferred_state_changed || @todo_pending_state_changed || @project_changed}
page.deferred { return @context_changed || !(@todo.deferred? || @todo.pending?) }
page.calendar { return @due_date_changed || !@todo.due }
page.stats { return @todo.completed? }
page.tag { return ( (@context_changed | @project_changed) && !@todo.hidden?) || @tag_was_removed || @todo_hidden_state_changed || @todo_deferred_state_changed }
page.todo { return todo_moved_out_of_container || @todo.hidden? || @todo.deferred? || @todo.pending?}
page.search { return false }
end
return false
end
def replace_with_updated_todo
source_view do |page|
page.context { return !update_needs_to_remove_todo_from_container }
page.project { return !update_needs_to_remove_todo_from_container }
page.deferred { return !@context_changed && (@todo.deferred? || @todo.pending?) }
page.calendar { return !@due_date_changed && @todo.due }
page.stats { return !@todo.completed? }
page.tag { return !update_needs_to_remove_todo_from_container && !@tag_was_removed }
page.todo { return !update_needs_to_remove_todo_from_container }
page.search { return true }
end
return false
end
def append_updated_todo
source_view do |page|
page.context { return @todo_deferred_state_changed || @todo_pending_state_changed }
page.project { return @todo_deferred_state_changed || @todo_pending_state_changed }
page.deferred { return @context_changed && (@todo.deferred? || @todo.pending?) }
page.calendar { return @due_date_changed && @todo.due }
page.stats { return false }
page.tag { return update_needs_to_remove_todo_from_container && !@tag_was_removed}
page.todo { return todo_moved_out_of_container && !(@todo.deferred? || @todo.pending? || @todo.hidden?) }
end
return false
end
def project_container_id(todo)
return "p#{todo.project_id}" unless todo.project.nil?
return "without_project_container"
end
def project_container_empty_id(todo)
return "p#{todo.project_id}-empty-d" unless todo.project.nil?
return "without_project_container-empty-d"
end
def item_container_id (todo)
return "hidden_container_items" if source_view_is(:tag) && todo.hidden?
return "c#{todo.context_id}_items" if source_view_is :deferred
return @new_due_id if source_view_is :calendar
return "deferred_pending_container_items" if !source_view_is(:todo) && (todo.deferred? || todo.pending?)
return "completed_container_items" if todo.completed?
return "p#{todo.project_id}_items" if source_view_is :project
return project_container_id(todo) if source_view_is_one_of(:todo, :tag) && @group_view_by == 'project'
return "c#{todo.context_id}"
end
def empty_container_msg_div_id(todo = @todo || @successor)
raise Exception.new, "no @todo or @successor set" if !todo
source_view do |page|
page.project {
return "deferred_pending_container-empty-d" if empty_criteria_met
return "p#{todo.project_id}-empty-d"
}
page.tag {
return "deferred_pending_container-empty-d" if empty_criteria_met
return "hidden_container-empty-d" if @todo.hidden?
return "c#{todo.context_id}-empty-d" if @group_view_by == 'context'
return project_container_empty_id(todo)
}
page.calendar {
return "deferred_pending_container-empty-d" if empty_criteria_met
return "empty_#{@new_due_id}"
}
page.context {
return "deferred_pending_container-empty-d" if empty_criteria_met
return "c#{todo.context_id}-empty-d"
}
page.todo {
return "c#{todo.context_id}-empty-d" if @group_view_by == 'context'
return project_container_empty_id(todo)
}
end
return "c#{todo.context_id}-empty-d"
end
def empty_criteria_met
return @todo_was_deferred_from_active_state ||
@todo_was_blocked_from_active_state ||
@todo_was_destroyed_from_deferred_state ||
@todo_was_created_deferred ||
@todo_was_blocked_from_completed_state ||
@todo_was_created_blocked
end
def todo_was_removed_from_deferred_or_blocked_container
return @todo_was_activated_from_deferred_state ||
@todo_was_activated_from_pending_state ||
@todo_was_destroyed_from_deferred_or_pending_state ||
@todo_was_completed_from_deferred_or_blocked_state
end
def show_empty_message_in_source_container
container_id = ""
source_view do |page|
page.project {
container_id = "p#{@original_item_project_id}-empty-d" if @remaining_in_context == 0
container_id = "deferred_pending_container-empty-d" if todo_was_removed_from_deferred_or_blocked_container && @remaining_deferred_or_pending_count == 0
container_id = "completed_container-empty-d" if @completed_count && @completed_count == 0 && !@todo.completed?
}
page.deferred { container_id = "c#{@original_item_context_id}empty-d" if @remaining_in_context == 0 }
page.calendar { container_id = "empty_#{@original_item_due_id}" if @old_due_empty }
page.tag {
container_id = "hidden_container-empty-d" if (@remaining_hidden_count == 0 && !@todo.hidden? && @todo_hidden_state_changed) ||
(@remaining_hidden_count == 0 && @todo.completed? && @original_item_was_hidden)
container_id = "deferred_pending_container-empty-d" if (todo_was_removed_from_deferred_or_blocked_container && @remaining_deferred_or_pending_count == 0) ||
(@original_item_was_deferred && @remaining_deferred_or_pending_count == 0 && (@todo.completed? || @tag_was_removed))
container_id = "completed_container-empty-d" if @completed_count && @completed_count == 0 && !@todo.completed?
}
page.context {
container_id = "c#{@original_item_context_id}-empty-d" if @remaining_in_context == 0
container_id = "deferred_pending_container-empty-d" if todo_was_removed_from_deferred_or_blocked_container && @remaining_deferred_or_pending_count == 0
container_id = "completed_container-empty-d" if @completed_count && @completed_count == 0 && !@todo.completed?
}
page.todo { container_id = "c#{@original_item_context_id}-empty-d" if @remaining_in_context == 0 }
page.done { container_id = "completed_#{@original_completed_period}_container-empty-d" if @remaining_in_context == 0 }
end
return container_id.blank? ? "" : "$(\"##{container_id}\").slideDown(100);".html_safe
end
end

View file

@ -10,6 +10,7 @@
var SOURCE_VIEW = '<%=@source_view%>';
var AUTH_TOKEN = '<%= raw(protect_against_forgery? ? form_authenticity_token.inspect : "") %>'
var TAG_NAME = '<%= @tag_name ? @tag_name : "" %>'
var GROUP_VIEW_BY = '<%= @group_view_by ? @group_view_by : "" %>'
var defaultContexts = <%= default_contexts_for_autocomplete.html_safe rescue '{}' %>;
var defaultTags = <%= default_tags_for_autocomplete.html_safe rescue '{}' %>;
var dateFormat = '<%= date_format_for_date_picker %>';

View file

@ -3,9 +3,10 @@
# invalidate the cache every day because of staleness or
# 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
%>
<%= render :partial => "project_settings_container", :locals => {:project => project} if source_view_is :project %>
-%>
<% 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)
@ -19,5 +20,4 @@ cache [project, @source_view, current_user.date.strftime("%Y%m%d")] do
:show_empty_containers => settings[:show_empty_containers]
}}
%>
<% end %>
<% end -%>

View file

@ -1,24 +1,32 @@
<% unless @saved -%>
TracksPages.show_errors(html_for_error_messages());
function html_for_error_messages() {
return "<%= escape_javascript(get_list_of_error_messages_for(@todo)) %>";
}
<% else -%>
<% else
animation = []
if should_show_new_item
if should_add_new_container
animation << "insert_new_container_with_new_todo";
else
animation << "add_todo_to_existing_container";
end
end
animation << "remove_empty_message_container";
animation << "update_predecessors";
animation << "clear_form";
-%>
<%= render_animation(animation) %>
TracksPages.page_notify('notice', "<%=escape_javascript @status_message%>", 8);
TracksPages.hide_errors();
TracksPages.set_page_badge(<%= @down_count %>);
<% if should_show_new_item -%>
<% if should_add_new_context -%>
insert_new_context_with_new_todo();
<% else -%>
add_todo_to_existing_context();
<% end -%>
<% end -%>
update_predecessors();
clear_form();
function clear_form() {
function clear_form(next_steps) {
$('#todo-form-new-action').clearForm();
$('#todo-form-new-action').clearDeps();
TracksForm.set_context_name('<%=escape_javascript @initial_context_name%>');
@ -27,43 +35,55 @@
$('#todo-form-new-action input:text:first').focus();
$('#new_todo_starred_link .todo_star').removeClass('starred');
$('#new_todo_starred').val('false');
next_steps.go();
}
function insert_new_context_with_new_todo() {
function insert_new_container_with_new_todo(next_steps) {
<%-
empty_id = '#no_todos_in_view'
empty_id = '#deferred_pending_container-empty-d' if source_view_is :tickler
-%>
$('<%=empty_id%>').slideUp(100);
$('#display_box').prepend(html_for_new_context());
$('<%=empty_id%>').slideUp(100, function() {
$('#display_box').prepend(html_for_new_container());
next_steps.go();
});
}
function add_todo_to_existing_context() {
<% if source_view_is_one_of(:todo, :deferred, :tag) -%>
<% unless source_view_is_one_of(:todo, :tag) && (@todo.deferred?||@todo.hidden?) -%>
$('#c<%= @todo.context_id %>').fadeIn(500, function() {});
$('#no_todos_in_view').slideUp(100);
<%= "$('#deferred_pending_container-empty-nd').slideUp(100);".html_safe if source_view_is(:deferred) && @todo.deferred? %>
<% end -%>
<% end -%>
$('#<%=empty_container_msg_div_id%>').hide();
$('#<%=item_container_id(@todo)%>').append(html_for_new_todo());
$('#<%= dom_id(@todo)%>').effect('highlight', {}, 2000 );
function add_todo_to_existing_container(next_steps) {
$('#<%= empty_container_msg_div_id %>').hide();
$('#<%= item_container_id(@todo) %>').append(html_for_new_todo());
$('#<%= item_container_id(@todo) %>').slideDown(500, function() {
$('#<%= dom_id(@todo) %>').effect('highlight', {}, 2000 );
next_steps.go();
});
}
function update_predecessors() {
function remove_empty_message_container(next_steps) {
$('#no_todos_in_view').slideUp(100, function() { });
<%# = "$('#deferred_pending_container-empty-nd').slideUp(100);".html_safe if source_view_is(:deferred) && @todo.deferred? %>
next_steps.go();
}
function update_predecessors(next_steps) {
<% @todo.uncompleted_predecessors.each do |p| -%>
if ($('<%=item_container_id(p)%>')) {
$('#<%=dom_id(p)%>').html('<%= escape_javascript(render(:partial => p, :locals => { :parent_container_type => parent_container_type, :source_view => @source_view }))%>');
}
<% end -%>
next_steps.go();
}
function html_for_new_context() {
return "<%= @saved && @new_context_created ? escape_javascript(render(:partial => @todo.context, :locals => { :settings => {:collapsible => true} })) : "" %>";
function html_for_new_container() {
<%
want_render = @group_view_by == 'project' ? @new_project_created : @new_context_created
container = @group_view_by == 'project' ? @todo.project : @todo.context
js = want_render ? escape_javascript(render(:partial => container, :locals => { :settings => {:collapsible => true} })) : ""
%>
return "<%= js %>";
}
function html_for_new_todo() {
return "<%= @saved ? escape_javascript(render(:partial => @todo, :locals => { :parent_container_type => parent_container_type, :source_view => @source_view })) : "" %>";
}
<% end -%>
<% end -%>

View file

@ -1,5 +1,21 @@
<% if @saved -%>
set_notification();
<% unless @saved -%>
TracksPages.show_errors_for_multi_add(html_for_error_messages());
function html_for_error_messages() {
<%
# add error about missing todo description that is not available in @todos
@multiple_error = content_tag(:div, content_tag(:p, @multiple_error), {:class => 'errorExplanation', :id => 'errorExplanation'}) unless @multiple_error.blank?
error_messages = @multiple_error || ""
# add errors of individual @todos
@todos.each do |todo|
error_messages += get_list_of_error_messages_for(todo)
end
-%>
return "<%= escape_javascript(error_messages.html_safe)%>";
}
<% else -%>
TracksPages.page_notify('notice', "<%=@status_message%>", 5);
hide_empty_message();
TracksPages.hide_errors();
TracksPages.set_page_badge(<%= @down_count %>);
@ -11,67 +27,44 @@
<% end -%>
<% end -%>
clear_form();
<% else -%>
TracksPages.show_errors_for_multi_add(html_for_error_messages());
function clear_form() {
$('#todo-form-multi-new-action').clearForm();
TracksForm.set_context_name_for_multi_add('<%=escape_javascript @initial_context_name%>');
TracksForm.set_project_name_for_multi_add('<%=escape_javascript @initial_project_name%>');
TracksForm.set_tag_list_for_multi_add('<%=escape_javascript @initial_tags%>');
$('#todo-form-multi-new-action input:text:first').focus();
}
function insert_new_context_with_new_todo() {
$('#display_box').prepend(html_for_new_context());
}
function hide_empty_message() {
<% if (source_view_is :project and @todo.pending?) or (source_view_is :deferred) -%>
$('#deferred_pending_container-empty-d').hide();
<% else -%>
$('#no_todos_in_view').hide();
<% end -%>
}
function add_todo_to_existing_context() {
<%
@todos.each do |todo|
if should_show_new_item(todo)
html = escape_javascript(render(:partial => todo, :locals => { :parent_container_type => parent_container_type, :source_view => @source_view }))
-%>
$('#<%= empty_container_msg_div_id(todo) %>').hide();
$('#<%= item_container_id(todo) %>').append('<%= html %>');
$('#<%= item_container_id(todo) %>').fadeIn(500, function() {
$('#<%= dom_id(todo) %>').effect('highlight', {}, 2000 );
});
<% end %>
<% end %>
}
function html_for_new_context() {
return "<%= @saved && @new_context_created ? escape_javascript(render(:partial => @todo.context, :locals => { :settings => {:collapsible => true} })) : "" %>";
}
<% end -%>
<% if @saved
# the following functions assume a todo is saved or at least not nil,
# so leave them out in case of an error
-%>
function set_notification() {
TracksPages.page_notify('notice', "<%=@status_message%>", 5);
}
function clear_form() {
$('#todo-form-multi-new-action').clearForm();
TracksForm.set_context_name_for_multi_add('<%=escape_javascript @initial_context_name%>');
TracksForm.set_project_name_for_multi_add('<%=escape_javascript @initial_project_name%>');
TracksForm.set_tag_list_for_multi_add('<%=escape_javascript @initial_tags%>');
$('#todo-form-multi-new-action input:text:first').focus();
}
function insert_new_context_with_new_todo() {
$('#display_box').prepend(html_for_new_context());
}
function hide_empty_message() {
$('#<%=empty_container_msg_div_id%>').hide();
<% if (source_view_is :project and @todo.pending?) or (source_view_is :deferred) -%>
$('#deferred_pending_container-empty-d').hide();
<% end -%>
}
function add_todo_to_existing_context() {
<% if source_view_is_one_of(:todo, :deferred, :tag) -%>
TodoItemsContainer.ensureVisibleWithEffectAppear("c<%=@todo.context_id%>");
<% end
show = should_show_new_item # to hide html if not necessary
@todos.each do |todo|
html = show ? escape_javascript(render(:partial => todo, :locals => { :parent_container_type => parent_container_type, :source_view => @source_view })) : "" -%>
$('#<%=item_container_id(todo)%>').append('<%= html %>');
$('#<%= dom_id(todo)%>').effect('highlight', {}, 3000);
<% end %>
}
function html_for_new_context() {
return "<%= @saved && @new_context_created ? escape_javascript(render(:partial => @todo.context, :locals => { :settings => {:collapsible => true} })) : "" %>";
}
<% else # if @saved -%>
function html_for_error_messages() {
<%
# add error about missing todo description that is not available in @todos
@multiple_error = content_tag(:div, content_tag(:p, @multiple_error), {:class => 'errorExplanation', :id => 'errorExplanation'}) unless @multiple_error.blank?
error_messages = @multiple_error || ""
# add errors of individual @todos
@todos.each do |todo|
error_messages += get_list_of_error_messages_for(todo)
end
-%>
return "<%= escape_javascript(error_messages.html_safe)%>";
}
<% end # if @saved -%>

View file

@ -1,4 +1,6 @@
<%- if @saved -%>
<%- unless @saved -%>
TracksPages.page_notify('error', "<%= t('todos.error_deleting_item', :description => @todo.description) %>", 8);
<%- else -%>
TracksPages.page_notify('notice', '<%= escape_javascript(t('todos.deleted_success')) %>', 5);
TracksPages.set_page_badge(<%=@down_count%>);
remove_todo_from_page();
@ -6,20 +8,14 @@
activate_pending_todos();
update_predecessors();
show_empty_messages();
<%- else -%>
TracksPages.page_notify('error', "<%= t('todos.error_deleting_item', :description => @todo.description) %>", 8);
<%- end -%>
<% if @saved
# do not send the js in case of an error
-%>
function show_empty_messages() {
<% if @old_due_empty -%>
$('#empty_<%=@original_item_due_id%>').slideDown(1000);
<% end -%>
<% if empty_container_msg_div_id && todo_container_is_empty -%>
<% if todo_container_is_empty -%>
$('#<%=empty_container_msg_div_id%>').slideDown(1000);
<% if @down_count == 0 -%>
$('#no_todos_in_view').slideDown(1000);
@ -32,10 +28,10 @@ function show_empty_messages() {
}
function remove_todo_from_page() {
<% if (@remaining_in_context == 0) && update_needs_to_hide_context
<% if (@remaining_in_context == 0) && update_needs_to_hide_container
# remove context with deleted todo
-%>
$('#c<%=@todo.context_id%>').fadeOut(400, function() {
$('#<%=item_container_id(@todo)%>').fadeOut(400, function() {
$('#<%=dom_id(@todo)%>').remove();
});
<%= show_empty_message_in_source_container -%>
@ -104,8 +100,4 @@ function update_predecessors() {
function html_for_new_recurring_todo() {
return "<%= @saved && @new_recurring_todo ? escape_javascript(render(:partial => @new_recurring_todo, :locals => { :parent_container_type => parent_container_type })) : "" %>";
}
<% end
# if @saved
-%>
}

View file

@ -4,7 +4,7 @@
<%= show_grouped_todos %>
<% if @group_view_by == 'project' -%>
<%= show_todos_without_project(@todos_without_project) unless @todos_without_project.nil? -%>
<%= show_todos_without_project(@todos_without_project) -%>
<% end -%>
<%= show_done_todos(@done, {:parent_container_type => 'home', :collapsible => true}) unless @done.nil? %>

View file

@ -13,6 +13,10 @@
<%= show_grouped_todos %>
<% if @group_view_by == 'project' -%>
<%= show_todos_without_project(@todos_without_project) -%>
<% end -%>
<%= show_deferred_pending_todos(@deferred_todos, @pending_todos, deferred_pending_options) %>
<%= show_hidden_todos(@hidden_todos, hidden_options) unless @hidden_todos.nil? %>

View file

@ -32,7 +32,7 @@ function redirect_after_complete() {
}
function remove_todo(next_steps) {
<% if (@remaining_in_context == 0) && update_needs_to_hide_context
<% if (@remaining_in_context == 0) && update_needs_to_hide_container
# remove context with deleted todo
-%>
$('#c<%=@todo.context_id%>').fadeOut(400, function() {

View file

@ -1,5 +1,10 @@
<% if !@saved -%>
<% unless @saved -%>
TracksPages.show_edit_errors(html_for_error_messages());
function html_for_error_messages() {
return "<%= escape_javascript(get_list_of_error_messages_for(@todo)) %>";
}
<% else
# jquery animations are async, so first collect all animation steps that need
@ -13,15 +18,14 @@
elsif append_updated_todo
animation << (@new_context_created ? "insert_new_context_with_updated_todo" : "add_to_existing_container")
end
animation << "hide_context" if update_needs_to_hide_context
animation << "hide_container" if update_needs_to_hide_container
animation << "highlight_updated_todo"
animation << "update_empty_container" if source_view_is_one_of(:tag, :todo, :deferred)
animation << "update_predecessors"
%>
<%= render_animation(animation) %>
TracksPages.page_notify('notice', '<%=escape_javascript @status_message%>', 5);
TracksPages.set_page_badge(<%= @down_count %>);
<%= render_animation(animation) %>
<% end %>
function remove_todo(next_steps) {
@ -46,7 +50,7 @@ function add_to_existing_container(next_steps) {
<% end -%>
<% else -%>
<% unless (@todo_hidden_state_changed && @todo.hidden?) || @todo_was_deferred_from_active_state -%>
$('#c<%= @todo.context_id %>').fadeIn(500, function() {
$('#<%= item_container_id(@todo) %>').fadeIn(500, function() {
next_steps.go();
<% if @target_context_count==1 -%>
$("#<%= empty_container_msg_div_id %>").slideUp(100);
@ -69,9 +73,8 @@ function replace_todo(next_steps) {
next_steps.go();
}
function hide_context(next_steps) {
<% context_id = @context_changed ? @original_item_context_id : @todo.context_id -%>
$('#c<%= context_id %>').fadeOut(400, function(){ next_steps.go(); });
function hide_container(next_steps) {
$('#<%= item_container_id(@original_item) %>').fadeOut(400, function(){ next_steps.go(); });
<%= "$('#deferred_pending_container_empty-nd').slideDown(400);".html_safe if source_view_is(:deferred) && @down_count == 0 %>
}
@ -109,10 +112,6 @@ function html_for_new_context() {
return "<%= @saved && @new_context_created ? escape_javascript(render(:partial => @new_context, :locals => { :settings => {:collapsible => true }})) : "" %>";
}
function html_for_error_messages() {
return "<%= escape_javascript(get_list_of_error_messages_for(@todo)) %>";
}
function update_predecessors(next_steps) {
regenerate_predecessor_family();
<% if @removed_predecessors

View file

@ -57,7 +57,7 @@ Feature: dependencies
Then I should not see "test 1" within the dependencies of "test 2"
And I should not see "test 1" in the deferred container
@javascript @wip
@javascript
Scenario: Completing a predecessor will activate successors
Given I have a context called "@pc"
And I have a project "dependencies" that has the following todos

View file

@ -85,21 +85,26 @@ Feature: Add new next action from every page
@javascript
Scenario Outline: I can add a todo from several pages
Given I have selected the view for group by <grouping>
When I go to the <page>
And I submit a new action with description "a new next action"
And I submit a new action with description "a new next action"
Then I should <see> the todo "a new next action"
Scenarios:
| page | see |
| home page | see |
| tickler page | not see |
| "test project" project | see |
| context page for "test context" | see |
| tag page for "starred" | see |
| page | grouping | see |
| home page | context | see |
| home page | project | see |
| tickler page | context | not see |
| tickler page | project | not see |
| "test project" project | context | see |
| context page for "test context" | context | see |
| tag page for "starred" | context | see |
| tag page for "starred" | project | see |
@javascript
Scenario Outline: I can add multiple todos from several pages
Given I have a project "testing" with 1 todos
And I have selected the view for group by <grouping>
When I go to the <page>
And I follow "Add multiple next actions"
And I submit multiple actions with using
@ -113,15 +118,18 @@ Feature: Add new next action from every page
And the number of actions should be <count>
Scenarios:
| page | see | badge | count |
| home page | see | 3 | 3 |
| tickler page | not see | 0 | 3 |
| "testing" project | see | 3 | 3 |
| context page for "test context" | see | 2 | 3 |
| tag page for "starred" | not see | 0 | 3 |
| page | see | badge | count | grouping |
| home page | see | 3 | 3 | context |
| home page | see | 3 | 3 | project |
| tickler page | not see | 0 | 3 | context |
| tickler page | not see | 0 | 3 | project |
| "testing" project | see | 3 | 3 | context |
| context page for "test context" | see | 2 | 3 | context |
| tag page for "starred" | see | 2 | 3 | context |
| tag page for "starred" | see | 2 | 3 | project |
@javascript
Scenario: Adding a todo to another project does not show the todo
Scenario: Adding a todo to another project does not show the todo in project view
Given I have a project called "another project"
When I go to the "test project" project
And I submit a new action with description "can you see me?" to project "another project" in the context "test context"
@ -140,7 +148,7 @@ Feature: Add new next action from every page
Then I should see the todo "another new next action"
@javascript
Scenario Outline: Adding a todo with a new context shows the new context
Scenario Outline: Adding a todo with a new context shows the new context when page groups todos by context
When I go to the <page>
And I submit a new <todo> with description "do at new context" and the tags "starred" in the context "New"
Then a confirmation for adding a new context "New" should be asked
@ -155,12 +163,29 @@ Feature: Add new next action from every page
| context page for "test context" | action | 1 | not be visible |
| tag page for "starred" | action | 1 | be visible |
@javascript
Scenario Outline: Adding a todo with a new project shows the new project when page groups todos by project
And I have selected the view for group by project
When I go to the <page>
And I submit a new <todo> with description "do in new project" to project "New" with tags "starred"
Then the container for the project "New" should <visible>
And the badge should show <badge>
Scenarios:
| page | todo | badge | visible |
| home page | action | 1 | be visible |
| tickler page | deferred action | 1 | be visible |
| "test project" project | action | 1 | not be visible |
| context page for "test context" | action | 1 | not be visible |
| tag page for "starred" | action | 1 | be visible |
@javascript
Scenario Outline: Adding a todo to a hidden project does not show the todo
Given I have a hidden project called "hidden project"
And I have a project called "visible project"
And I have a context called "visible context"
And I have a context called "other context"
And I have selected the view for group by <grouping>
When I go to the <page>
And I submit a new action with description "hidden todo" to project "hidden project" with tags "test" in the context "visible context"
Then I should <see_hidden> "hidden todo"
@ -168,17 +193,21 @@ Feature: Add new next action from every page
Then I should <see_visible> "visible todo"
Scenarios:
| page | see_hidden | see_visible |
| home page | not see | see |
| tickler page | not see | not see |
| "visible project" project | not see | see |
| "hidden project" project | see | not see |
| context page for "visible context" | not see | see |
| context page for "other context" | not see | not see |
| tag page for "starred" | not see | not see |
| tag page for "test" | see | see |
| page | grouping | see_hidden | see_visible |
| home page | context | not see | see |
| home page | project | not see | see |
| tickler page | context | not see | not see |
| tickler page | project | not see | not see |
| "visible project" project | project | not see | see |
| "hidden project" project | project | see | not see |
| context page for "visible context" | context | not see | see |
| context page for "other context" | 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 "test" | context | see | see |
| tag page for "test" | project | see | see |
@javascript
@javascript
Scenario: Adding a todo to a hidden context from home page does not show the todo
Given I have a context called "visible context"
And I have a hidden context called "hidden context"
@ -200,14 +229,21 @@ Feature: Add new next action from every page
Then I should see "another new todo"
@javascript
Scenario: Adding a todo to an empty container hides the empty message # TODO: make outline
Scenario Outline: Adding a todo to an empty container hides the empty message
Given I have a context called "visible context"
And I have a project called "visible project"
And I have selected the view for group by <grouping>
When I go to the tag page for "test"
Then I should see empty message for todos of tag
When I submit a new action with description "a new todo" and the tags "test" in the context "visible context"
When I submit a new action with description "a new todo" to project "visible project" with tags "test" in the context "visible context"
Then I should see "a new todo"
And I should not see empty message for todos of tag
Scenarios:
| grouping |
| context |
| project |
@javascript
Scenario Outline: Adding a dependency to a todo updates the successor
Given I have a <list_type> "test" with 1 todos
@ -224,7 +260,7 @@ Feature: Add new next action from every page
| project |
| context |
@javascript
@javascript
Scenario: Adding a dependency to a todo in another project
Given I have a project "testing" with 1 todos
And I have a project "another project"
@ -233,8 +269,9 @@ Feature: Add new next action from every page
Then I should not see "a new todo" in the project container of "another project"
And I should not see empty message for deferred todos of project
@javascript
Scenario: I can add multiple todos in a new project and a new context
@javascript @wip
Scenario Outline: I can add multiple todos in a new project and a new context
Given I have selected the view for group by <grouping>
When I go to the home page
And I follow "Add multiple next actions"
And I fill the multiple actions form with "", "a next project", "@anywhere", "new tag"
@ -253,7 +290,13 @@ Feature: Add new next action from every page
And I should see "b"
And I should see "c"
@javascript
Scenarios:
| grouping |
| project |
| context |
@javascript
Scenario: I need to fill in at least one description and a context
When I go to the home page
And I follow "Add multiple next actions"

View file

@ -98,7 +98,7 @@ end
####### Project #######
Then /^I should not see "([^"]*)" in the project container of "([^"]*)"$/ do |todo_description, project_name|
Then /^I should (see|not see) "([^"]*)" in the project container of "([^"]*)"$/ do |visible, todo_description, project_name|
todo = @current_user.todos.where(:description => todo_description).first
todo.should_not be_nil
@ -106,30 +106,20 @@ Then /^I should not see "([^"]*)" in the project container of "([^"]*)"$/ do |to
project.should_not be_nil
xpath = "//div[@id='p#{todo.project.id}_items']//div[@id='line_todo_#{todo.id}']"
page.should_not have_xpath(xpath)
page.send( visible=='see' ? :should : :should_not, have_xpath(xpath))
end
Then /^I should see "([^"]*)" in project container for "([^"]*)"$/ do |todo_description, project_name|
todo = @current_user.todos.where(:description => todo_description).first
todo.should_not be_nil
project = @current_user.projects.where(:name => project_name).first
project.should_not be_nil
xpath = "//div[@id='p#{project.id}_items']//div[@id='line_todo_#{todo.id}']"
page.should have_xpath(xpath)
end
Then(/^I should see "(.*?)" in the project container for "(.*?)"$/) do |todo_description, project_name|
step "I should see \"#{todo_description}\" in project container for \"#{project_name}\""
end
Then /^I should not see the project container for "([^"]*)"$/ do |project_name|
Then(/^I should (see|not see) the project container for "([^"]*)"$/) do |visible, project_name|
project = @current_user.projects.where(:name => project_name).first
project.should_not be_nil
xpath = "//div[@id='p#{project.id}']"
page.should_not have_xpath(xpath, :visible => true)
page.send( visible=='see' ? :should : :should_not, have_xpath(xpath, :visible => true))
end
Then(/^the container for the project "(.*?)" should (be visible|not be visible)$/) do |project_name, visible|
map = { "be visible" => "see", "not be visible" => "not see"}
step("I should #{map[visible]} the project container for \"#{project_name}\"")
end
####### Completed #######

View file

@ -15,8 +15,8 @@ Given /^the date is "(.*?)"$/ do |date|
Timecop.travel(date)
end
Given(/^I have selected the view for group by project$/) do
@group_view_by='projects'
Given(/^I have selected the view for group by (project|context)$/) do |grouping|
@group_view_by = grouping
end
Then /the badge should show (.*)/ do |number|

View file

@ -203,6 +203,23 @@ When /^I submit a new action with description "([^"]*)"$/ do |description|
submit_next_action_form
end
When /^I submit a new action with description "([^"]*)" in the project "(.*?)"$/ do |description, project_name|
within "form#todo-form-new-action" do
fill_in "todo[description]", :with => description
fill_in "project_name", :with => project_name
end
submit_next_action_form
end
When(/^I submit a new action with description "([^"]*)" to project "([^"]*)" with tags "([^"]*)"$/) do |description, project_name, tags|
within "form#todo-form-new-action" do
fill_in "todo[description]", :with => description
fill_in "project_name", :with => project_name
fill_in "tag_list", :with => tags
end
submit_next_action_form
end
When /^I submit a new action with description "([^"]*)" with a dependency on "([^"]*)"$/ do |todo_description, predecessor_description|
predecessor = @current_user.todos.where(:description => predecessor_description).first
predecessor.should_not be_nil
@ -287,6 +304,16 @@ When /^I submit a new deferred action with description "([^"]*)" and the tags "(
submit_next_action_form
end
When(/^I submit a new deferred action with description "([^"]*)" to project "(.*?)" with tags "([^"]*)"$/) do |description, project_name, tags|
within "form#todo-form-new-action" do
fill_in "todo[description]", :with => description
fill_in "todo_project_name", :with => project_name
fill_in "tag_list", :with => tags
fill_in "todo[show_from]", :with => format_date(@current_user.time + 1.week)
end
submit_next_action_form
end
When /^I submit a new deferred action with description "([^"]*)" to project "([^"]*)" with tags "([^"]*)" in the context "([^"]*)"$/ do |description, project_name, tags, context_name|
fill_in "todo[description]", :with => description

View file

@ -9,7 +9,7 @@ module NavigationHelpers
options = {}
options[:format] = :m if @mobile_interface
options[:locale] = @locale if @locale
options[:group_view_by] = @group_view_by if @group_view_by
options[:_group_view_by] = @group_view_by if @group_view_by
@source_view = nil
case page_name