mirror of
https://github.com/TracksApp/tracks.git
synced 2025-12-17 07:40:12 +01:00
migrate dependencies
without functional changes
This commit is contained in:
parent
bf5e378301
commit
a02f1d2584
14 changed files with 334 additions and 143 deletions
|
|
@ -36,7 +36,7 @@ class ApplicationController < ActionController::Base
|
||||||
before_filter :set_locale
|
before_filter :set_locale
|
||||||
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_locale
|
# after_filter :set_locale
|
||||||
after_filter :set_charset
|
after_filter :set_charset
|
||||||
|
|
||||||
include ActionView::Helpers::TextHelper
|
include ActionView::Helpers::TextHelper
|
||||||
|
|
@ -137,6 +137,12 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def auto_complete_result2(entries, phrase = nil)
|
||||||
|
json_elems = "[{" + entries.map {|item| "\"id\" : \"#{item.id}\", \"value\" : \"#{item.specification()}\""}.join("},{") + "}]"
|
||||||
|
return json_elems == "[{}]" ? "" : json_elems
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
# Uses RedCloth to transform text using either Textile or Markdown Need to
|
# Uses RedCloth to transform text using either Textile or Markdown Need to
|
||||||
# require redcloth above RedCloth 3.0 or greater is needed to use Markdown,
|
# require redcloth above RedCloth 3.0 or greater is needed to use Markdown,
|
||||||
# otherwise it only handles Textile
|
# otherwise it only handles Textile
|
||||||
|
|
|
||||||
|
|
@ -250,11 +250,12 @@ class TodosController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_predecessor
|
def remove_predecessor
|
||||||
@todo = current_user.todos.find(params['id'])
|
|
||||||
@source_view = params['_source_view'] || 'todo'
|
@source_view = params['_source_view'] || 'todo'
|
||||||
|
@todo = current_user.todos.find(params['id'])
|
||||||
@predecessor = current_user.todos.find(params['predecessor'])
|
@predecessor = current_user.todos.find(params['predecessor'])
|
||||||
@successor = @todo
|
@successor = @todo
|
||||||
@removed = @successor.remove_predecessor(@predecessor)
|
@removed = @successor.remove_predecessor(@predecessor)
|
||||||
|
determine_remaining_in_context_count
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.js
|
format.js
|
||||||
end
|
end
|
||||||
|
|
@ -361,8 +362,13 @@ class TodosController < ApplicationController
|
||||||
update_attributes_of_todo
|
update_attributes_of_todo
|
||||||
|
|
||||||
@saved = @todo.save
|
@saved = @todo.save
|
||||||
|
|
||||||
|
# this is set after save and cleared after reload, so save it here
|
||||||
|
@removed_predecessors = @todo.removed_predecessors
|
||||||
|
|
||||||
@todo.reload # refresh context and project object too (not only their id's)
|
@todo.reload # refresh context and project object too (not only their id's)
|
||||||
|
|
||||||
|
update_dependency_state
|
||||||
update_todo_state_if_project_changed
|
update_todo_state_if_project_changed
|
||||||
|
|
||||||
determine_changes_by_this_update
|
determine_changes_by_this_update
|
||||||
|
|
@ -660,7 +666,7 @@ class TodosController < ApplicationController
|
||||||
:conditions => [ '(todos.state = ? OR todos.state = ? OR todos.state = ?) AND ' +
|
:conditions => [ '(todos.state = ? OR todos.state = ? OR todos.state = ?) AND ' +
|
||||||
'NOT (id = ?) AND lower(description) LIKE ?',
|
'NOT (id = ?) AND lower(description) LIKE ?',
|
||||||
'active', 'pending', 'deferred',
|
'active', 'pending', 'deferred',
|
||||||
params[:id], '%' + params[:q].downcase + '%' ],
|
params[:id], '%' + params[:term].downcase + '%' ],
|
||||||
:order => 'description ASC',
|
:order => 'description ASC',
|
||||||
:limit => 10
|
:limit => 10
|
||||||
)
|
)
|
||||||
|
|
@ -671,12 +677,12 @@ class TodosController < ApplicationController
|
||||||
:select => 'description, project_id, context_id, created_at',
|
:select => 'description, project_id, context_id, created_at',
|
||||||
:conditions => [ '(todos.state = ? OR todos.state = ? OR todos.state = ?) AND lower(description) LIKE ?',
|
:conditions => [ '(todos.state = ? OR todos.state = ? OR todos.state = ?) AND lower(description) LIKE ?',
|
||||||
'active', 'pending', 'deferred',
|
'active', 'pending', 'deferred',
|
||||||
'%' + params[:q].downcase + '%' ],
|
'%' + params[:term].downcase + '%' ],
|
||||||
:order => 'description ASC',
|
:order => 'description ASC',
|
||||||
:limit => 10
|
:limit => 10
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
render :inline => "<%= auto_complete_result2(@items) %>"
|
render :inline => auto_complete_result2(@items)
|
||||||
end
|
end
|
||||||
|
|
||||||
def convert_to_project
|
def convert_to_project
|
||||||
|
|
@ -1106,6 +1112,7 @@ class TodosController < ApplicationController
|
||||||
@original_item_project_id = @todo.project_id
|
@original_item_project_id = @todo.project_id
|
||||||
@original_item_was_deferred = @todo.deferred?
|
@original_item_was_deferred = @todo.deferred?
|
||||||
@original_item_was_hidden = @todo.hidden?
|
@original_item_was_hidden = @todo.hidden?
|
||||||
|
@original_item_was_pending = @todo.pending?
|
||||||
@original_item_due = @todo.due
|
@original_item_due = @todo.due
|
||||||
@original_item_due_id = get_due_id_for_calendar(@todo.due)
|
@original_item_due_id = get_due_id_for_calendar(@todo.due)
|
||||||
@original_item_predecessor_list = @todo.predecessors.map{|t| t.specification}.join(', ')
|
@original_item_predecessor_list = @todo.predecessors.map{|t| t.specification}.join(', ')
|
||||||
|
|
@ -1191,6 +1198,10 @@ class TodosController < ApplicationController
|
||||||
|
|
||||||
def update_dependencies
|
def update_dependencies
|
||||||
@todo.add_predecessor_list(params[:predecessor_list])
|
@todo.add_predecessor_list(params[:predecessor_list])
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_dependency_state
|
||||||
|
# assumes @todo.save was called so that the predecessor_list is persistent
|
||||||
if @original_item_predecessor_list != params[:predecessor_list]
|
if @original_item_predecessor_list != params[:predecessor_list]
|
||||||
# Possible state change with new dependencies
|
# Possible state change with new dependencies
|
||||||
if @todo.uncompleted_predecessors.empty?
|
if @todo.uncompleted_predecessors.empty?
|
||||||
|
|
@ -1206,12 +1217,17 @@ class TodosController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def determine_changes_by_this_update
|
def determine_changes_by_this_update
|
||||||
@todo_was_activated_from_deferred_state = @original_item_was_deferred && @todo.active?
|
@todo_was_activated_from_deferred_state = @todo.active? && @original_item_was_deferred
|
||||||
|
@todo_was_activated_from_pending_state = @todo.active? && @original_item_was_pending
|
||||||
@todo_was_deferred_from_active_state = @todo.deferred? && !@original_item_was_deferred
|
@todo_was_deferred_from_active_state = @todo.deferred? && !@original_item_was_deferred
|
||||||
@todo_deferred_state_changed = @todo_was_deferred_from_active_state || @todo_was_activated_from_deferred_state
|
@todo_was_blocked_from_active_state = @todo.pending? && !@original_item_was_pending
|
||||||
@due_date_changed = @original_item_due != @todo.due
|
|
||||||
|
@todo_deferred_state_changed = @original_item_was_deferred != @todo.deferred?
|
||||||
|
@todo_pending_state_changed = @original_item_was_pending != @todo.pending?
|
||||||
@todo_hidden_state_changed = @original_item_was_hidden != @todo.hidden?
|
@todo_hidden_state_changed = @original_item_was_hidden != @todo.hidden?
|
||||||
|
|
||||||
|
@due_date_changed = @original_item_due != @todo.due
|
||||||
|
|
||||||
source_view do |page|
|
source_view do |page|
|
||||||
page.calendar do
|
page.calendar do
|
||||||
@old_due_empty = is_old_due_empty(@original_item_due_id)
|
@old_due_empty = is_old_due_empty(@original_item_due_id)
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
module TodosHelper
|
module TodosHelper
|
||||||
|
|
||||||
def remote_star_icon
|
def remote_star_icon(todo=@todo)
|
||||||
link_to( image_tag_for_star(@todo),
|
link_to( image_tag_for_star(todo),
|
||||||
toggle_star_todo_path(@todo),
|
toggle_star_todo_path(todo),
|
||||||
:class => "icon star_item", :title => t('todos.star_action_with_description', :description => @todo.description))
|
:class => "icon star_item", :title => t('todos.star_action_with_description', :description => todo.description))
|
||||||
end
|
end
|
||||||
|
|
||||||
def remote_edit_button
|
def remote_edit_button(todo=@todo)
|
||||||
link_to(
|
link_to(
|
||||||
image_tag("blank.png", :alt => t('todos.edit'), :align => "absmiddle", :id => 'edit_icon_todo_'+@todo.id.to_s, :class => 'edit_item'),
|
image_tag("blank.png", :alt => t('todos.edit'), :align => "absmiddle", :id => 'edit_icon_todo_'+todo.id.to_s, :class => 'edit_item'),
|
||||||
{:controller => 'todos', :action => 'edit', :id => @todo.id},
|
{:controller => 'todos', :action => 'edit', :id => todo.id},
|
||||||
:class => "icon edit_item",
|
:class => "icon edit_item",
|
||||||
:title => t('todos.edit_action_with_description', :description => @todo.description))
|
:title => t('todos.edit_action_with_description', :description => todo.description))
|
||||||
end
|
end
|
||||||
|
|
||||||
def remote_delete_menu_item(todo)
|
def remote_delete_menu_item(todo)
|
||||||
|
|
@ -28,9 +28,9 @@ module TodosHelper
|
||||||
:_source_view => (@source_view.underscore.gsub(/\s+/,'_') rescue "")}
|
:_source_view => (@source_view.underscore.gsub(/\s+/,'_') rescue "")}
|
||||||
url[:_tag_name] = @tag_name if @source_view == 'tag'
|
url[:_tag_name] = @tag_name if @source_view == 'tag'
|
||||||
|
|
||||||
futuredate = (@todo.show_from || @todo.user.date) + days.days
|
futuredate = (todo.show_from || todo.user.date) + days.days
|
||||||
options = {:x_defer_alert => false, :class => "icon_defer_item" }
|
options = {:x_defer_alert => false, :class => "icon_defer_item" }
|
||||||
if @todo.due && futuredate > @todo.due
|
if todo.due && futuredate > todo.due
|
||||||
options[:x_defer_alert] = true
|
options[:x_defer_alert] = true
|
||||||
options[:x_defer_date_after_due_date] = t('todos.defer_date_after_due_date')
|
options[:x_defer_date_after_due_date] = t('todos.defer_date_after_due_date')
|
||||||
end
|
end
|
||||||
|
|
@ -38,6 +38,14 @@ module TodosHelper
|
||||||
return link_to(image_tag_for_defer(days), url, options)
|
return link_to(image_tag_for_defer(days), url, options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def remote_delete_dependency(todo, predecessor)
|
||||||
|
link_to(
|
||||||
|
image_tag("blank.png", :title => t('todos.remove_dependency'), :align => "absmiddle", :class => "delete_item"),
|
||||||
|
url_for({:controller => 'todos', :action => 'remove_predecessor', :id => todo.id}),
|
||||||
|
{:class => "delete_dependency_button", :x_predecessors_id => predecessor.id}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
def remote_promote_to_project_menu_item(todo)
|
def remote_promote_to_project_menu_item(todo)
|
||||||
url = {:controller => 'todos', :action => 'convert_to_project', :id => todo.id,
|
url = {:controller => 'todos', :action => 'convert_to_project', :id => todo.id,
|
||||||
:_source_view => (@source_view.underscore.gsub(/\s+/,'_') rescue "")}
|
:_source_view => (@source_view.underscore.gsub(/\s+/,'_') rescue "")}
|
||||||
|
|
@ -77,51 +85,51 @@ module TodosHelper
|
||||||
:class => "recurring_icon", :title => recurrence_pattern_as_text(todo.recurring_todo))
|
:class => "recurring_icon", :title => recurrence_pattern_as_text(todo.recurring_todo))
|
||||||
end
|
end
|
||||||
|
|
||||||
def remote_toggle_checkbox
|
def remote_toggle_checkbox(todo=@todo)
|
||||||
check_box_tag('item_id', toggle_check_todo_path(@todo), @todo.completed?, :class => 'item-checkbox',
|
check_box_tag('item_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?)
|
:title => todo.pending? ? t('todos.blocked_by', :predecessors => todo.uncompleted_predecessors.map(&:description).join(', ')) : "", :readonly => todo.pending?)
|
||||||
end
|
end
|
||||||
|
|
||||||
def date_span
|
def date_span(todo=@todo)
|
||||||
if @todo.completed?
|
if todo.completed?
|
||||||
"<span class=\"grey\">#{format_date( @todo.completed_at )}</span>"
|
"<span class=\"grey\">#{format_date( todo.completed_at )}</span>"
|
||||||
elsif @todo.pending?
|
elsif todo.pending?
|
||||||
"<a title='#{t('todos.depends_on')}: #{@todo.uncompleted_predecessors.map(&:description).join(', ')}'><span class=\"orange\">#{t('todos.pending')}</span></a> "
|
"<a title='#{t('todos.depends_on')}: #{todo.uncompleted_predecessors.map(&:description).join(', ')}'><span class=\"orange\">#{t('todos.pending')}</span></a> "
|
||||||
elsif @todo.deferred?
|
elsif todo.deferred?
|
||||||
show_date( @todo.show_from )
|
show_date( todo.show_from )
|
||||||
else
|
else
|
||||||
due_date( @todo.due )
|
due_date( todo.due )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def successors_span
|
def successors_span(todo=@todo)
|
||||||
unless @todo.pending_successors.empty?
|
unless todo.pending_successors.empty?
|
||||||
pending_count = @todo.pending_successors.length
|
pending_count = todo.pending_successors.length
|
||||||
title = "#{t('todos.has_x_pending', :count => pending_count)}: #{@todo.pending_successors.map(&:description).join(', ')}"
|
title = "#{t('todos.has_x_pending', :count => pending_count)}: #{todo.pending_successors.map(&:description).join(', ')}"
|
||||||
image_tag( 'successor_off.png', :width=>'10', :height=>'16', :border=>'0', :title => title )
|
image_tag( 'successor_off.png', :width=>'10', :height=>'16', :border=>'0', :title => title )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def grip_span
|
def grip_span(todo=@todo)
|
||||||
unless @todo.completed?
|
unless todo.completed?
|
||||||
image_tag('grip.png', :width => '7', :height => '16', :border => '0',
|
image_tag('grip.png', :width => '7', :height => '16', :border => '0',
|
||||||
:title => t('todos.drag_action_title'),
|
:title => t('todos.drag_action_title'),
|
||||||
:class => 'grip')
|
:class => 'grip')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag_list_text
|
def tag_list_text(todo=@todo)
|
||||||
@todo.tags.collect{|t| t.name}.join(', ')
|
todo.tags.collect{|t| t.name}.join(', ')
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag_list
|
def tag_list(todo=@todo)
|
||||||
tags_except_starred = @todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME}
|
tags_except_starred = todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME}
|
||||||
tag_list = tags_except_starred.collect{|t| "<span class=\"tag #{t.name.gsub(' ','-')}\">" + link_to(t.name, :controller => "todos", :action => "tag", :id => t.name) + "</span>"}.join('')
|
tag_list = tags_except_starred.collect{|t| "<span class=\"tag #{t.name.gsub(' ','-')}\">" + link_to(t.name, :controller => "todos", :action => "tag", :id => t.name) + "</span>"}.join('')
|
||||||
"<span class='tags'>#{tag_list}</span>"
|
"<span class='tags'>#{tag_list}</span>"
|
||||||
end
|
end
|
||||||
|
|
||||||
def tag_list_mobile
|
def tag_list_mobile(todo=@todo)
|
||||||
tags_except_starred = @todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME}
|
tags_except_starred = todo.tags.reject{|t| t.name == Todo::STARRED_TAG_NAME}
|
||||||
# removed the link. TODO: add link to mobile view of tagged actions
|
# removed the link. TODO: add link to mobile view of tagged actions
|
||||||
tag_list = tags_except_starred.collect{|t|
|
tag_list = tags_except_starred.collect{|t|
|
||||||
"<span class=\"tag\">" +
|
"<span class=\"tag\">" +
|
||||||
|
|
@ -130,30 +138,30 @@ module TodosHelper
|
||||||
if tag_list.empty? then "" else "<span class=\"tags\">#{tag_list}</span>" end
|
if tag_list.empty? then "" else "<span class=\"tags\">#{tag_list}</span>" end
|
||||||
end
|
end
|
||||||
|
|
||||||
def predecessor_list_text
|
def predecessor_list_text(todo=@todo)
|
||||||
@todo.predecessors.map{|t| t.specification}.join(', ')
|
todo.predecessors.map{|t| t.specification}.join(', ')
|
||||||
end
|
end
|
||||||
|
|
||||||
def deferred_due_date
|
def deferred_due_date(todo=@todo)
|
||||||
if @todo.deferred? && @todo.due
|
if todo.deferred? && todo.due
|
||||||
t('todos.action_due_on', :date => format_date(@todo.due))
|
t('todos.action_due_on', :date => format_date(todo.due))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def project_and_context_links(parent_container_type, opts = {})
|
def project_and_context_links(todo, parent_container_type, opts = {})
|
||||||
str = ''
|
str = ''
|
||||||
if @todo.completed?
|
if todo.completed?
|
||||||
str += @todo.context.name unless opts[:suppress_context]
|
str += todo.context.name unless opts[:suppress_context]
|
||||||
should_suppress_project = opts[:suppress_project] || @todo.project.nil?
|
should_suppress_project = opts[:suppress_project] || todo.project.nil?
|
||||||
str += ", " unless str.blank? || should_suppress_project
|
str += ", " unless str.blank? || should_suppress_project
|
||||||
str += @todo.project.name unless should_suppress_project
|
str += todo.project.name unless should_suppress_project
|
||||||
str = "(#{str})" unless str.blank?
|
str = "(#{str})" unless str.blank?
|
||||||
else
|
else
|
||||||
if (['project', 'tag', 'stats', 'search'].include?(parent_container_type))
|
if (['project', 'tag', 'stats', 'search'].include?(parent_container_type))
|
||||||
str << item_link_to_context( @todo )
|
str << item_link_to_context( todo )
|
||||||
end
|
end
|
||||||
if (['context', 'tickler', 'tag', 'stats', 'search'].include?(parent_container_type)) && @todo.project_id
|
if (['context', 'tickler', 'tag', 'stats', 'search'].include?(parent_container_type)) && @todo.project_id
|
||||||
str << item_link_to_project( @todo )
|
str << item_link_to_project( todo )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return str
|
return str
|
||||||
|
|
@ -295,7 +303,7 @@ module TodosHelper
|
||||||
def update_needs_to_remove_todo_from_container
|
def update_needs_to_remove_todo_from_container
|
||||||
source_view do |page|
|
source_view do |page|
|
||||||
page.context { return @context_changed || @todo.deferred? || @todo.pending? }
|
page.context { return @context_changed || @todo.deferred? || @todo.pending? }
|
||||||
page.project { return @todo_deferred_state_changed }
|
page.project { return @todo_deferred_state_changed || @todo_pending_state_changed }
|
||||||
page.deferred { return @context_changed || !(@todo.deferred? || @todo.pending?) }
|
page.deferred { return @context_changed || !(@todo.deferred? || @todo.pending?) }
|
||||||
page.calendar { return @due_date_changed || !@todo.due }
|
page.calendar { return @due_date_changed || !@todo.due }
|
||||||
page.stats { return @todo.completed? }
|
page.stats { return @todo.completed? }
|
||||||
|
|
@ -308,7 +316,7 @@ module TodosHelper
|
||||||
def replace_with_updated_todo
|
def replace_with_updated_todo
|
||||||
source_view do |page|
|
source_view do |page|
|
||||||
page.context { return !update_needs_to_remove_todo_from_container }
|
page.context { return !update_needs_to_remove_todo_from_container }
|
||||||
page.project { return !@todo_deferred_state_changed}
|
page.project { return !update_needs_to_remove_todo_from_container }
|
||||||
page.deferred { return !@context_changed && (@todo.deferred? || @todo.pending?) }
|
page.deferred { return !@context_changed && (@todo.deferred? || @todo.pending?) }
|
||||||
page.calendar { return !@due_date_changed && @todo.due }
|
page.calendar { return !@due_date_changed && @todo.due }
|
||||||
page.stats { return !@todo.completed? }
|
page.stats { return !@todo.completed? }
|
||||||
|
|
@ -321,7 +329,7 @@ module TodosHelper
|
||||||
def append_updated_todo
|
def append_updated_todo
|
||||||
source_view do |page|
|
source_view do |page|
|
||||||
page.context { return false }
|
page.context { return false }
|
||||||
page.project { return @todo_deferred_state_changed }
|
page.project { return @todo_deferred_state_changed || @todo_pending_state_changed }
|
||||||
page.deferred { return @context_changed && (@todo.deferred? || @todo.pending?) }
|
page.deferred { return @context_changed && (@todo.deferred? || @todo.pending?) }
|
||||||
page.calendar { return @due_date_changed && @todo.due }
|
page.calendar { return @due_date_changed && @todo.due }
|
||||||
page.stats { return false }
|
page.stats { return false }
|
||||||
|
|
@ -346,7 +354,7 @@ module TodosHelper
|
||||||
|
|
||||||
source_view do |page|
|
source_view do |page|
|
||||||
page.project {
|
page.project {
|
||||||
return "tickler-empty-nd" if @todo_was_deferred_from_active_state
|
return "tickler-empty-nd" if @todo_was_deferred_from_active_state || @todo_was_blocked_from_active_state
|
||||||
return "p#{todo.project_id}empty-nd"
|
return "p#{todo.project_id}empty-nd"
|
||||||
}
|
}
|
||||||
page.tag {
|
page.tag {
|
||||||
|
|
@ -367,8 +375,9 @@ module TodosHelper
|
||||||
source_view do |page|
|
source_view do |page|
|
||||||
page.project {
|
page.project {
|
||||||
container_id = "p#{@original_item_project_id}empty-nd" if @remaining_in_context == 0
|
container_id = "p#{@original_item_project_id}empty-nd" if @remaining_in_context == 0
|
||||||
container_id = "tickler-empty-nd" if (@todo_was_activated_from_deferred_state && @remaining_deferred_or_pending_count == 0) ||
|
container_id = "tickler-empty-nd" if (
|
||||||
(@original_item_was_deferred && @remaining_deferred_or_pending_count == 0 && @todo.completed?)
|
( (@todo_was_activated_from_deferred_state || @todo_was_activated_from_pending_state) && @remaining_deferred_or_pending_count == 0) ||
|
||||||
|
(@original_item_was_deferred && @remaining_deferred_or_pending_count == 0 && @todo.completed?) )
|
||||||
container_id = "empty-d" if @completed_count && @completed_count == 0 && !@todo.completed?
|
container_id = "empty-d" if @completed_count && @completed_count == 0 && !@todo.completed?
|
||||||
}
|
}
|
||||||
page.deferred { container_id = "c#{@original_item_context_id}empty-nd" if @remaining_in_context == 0 }
|
page.deferred { container_id = "c#{@original_item_context_id}empty-nd" if @remaining_in_context == 0 }
|
||||||
|
|
@ -404,8 +413,4 @@ module TodosHelper
|
||||||
image_tag("blank.png", :title =>t('todos.star_action'), :class => class_str, :id => "star_img_"+todo.id.to_s)
|
image_tag("blank.png", :title =>t('todos.star_action'), :class => class_str, :id => "star_img_"+todo.id.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
def auto_complete_result2(entries, phrase = nil)
|
|
||||||
return entries.map{|e| e.specification()}.join("\n") rescue ''
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -39,11 +39,11 @@ class Todo < ActiveRecord::Base
|
||||||
STARRED_TAG_NAME = "starred"
|
STARRED_TAG_NAME = "starred"
|
||||||
|
|
||||||
# regular expressions for dependencies
|
# regular expressions for dependencies
|
||||||
RE_TODO = /[^"]+/
|
RE_TODO = /[^']+/
|
||||||
RE_CONTEXT = /[^"]+/
|
RE_CONTEXT = /[^']+/
|
||||||
RE_PROJECT = /[^"]+/
|
RE_PROJECT = /[^']+/
|
||||||
RE_PARTS = /"(#{RE_TODO})"\s<"(#{RE_CONTEXT})";\s"(#{RE_PROJECT})">/ # results in array
|
RE_PARTS = /'(#{RE_TODO})'\s<'(#{RE_CONTEXT})';\s'(#{RE_PROJECT})'>/ # results in array
|
||||||
RE_SPEC = /"#{RE_TODO}"\s<"#{RE_CONTEXT}";\s"#{RE_PROJECT}">/ # results in string
|
RE_SPEC = /'#{RE_TODO}'\s<'#{RE_CONTEXT}';\s'#{RE_PROJECT}'>/ # results in string
|
||||||
|
|
||||||
acts_as_state_machine :initial => :active, :column => 'state'
|
acts_as_state_machine :initial => :active, :column => 'state'
|
||||||
|
|
||||||
|
|
@ -95,6 +95,7 @@ class Todo < ActiveRecord::Base
|
||||||
def initialize(*args)
|
def initialize(*args)
|
||||||
super(*args)
|
super(*args)
|
||||||
@predecessor_array = nil # Used for deferred save of predecessors
|
@predecessor_array = nil # Used for deferred save of predecessors
|
||||||
|
@removed_predecessors = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def no_uncompleted_predecessors_or_deferral?
|
def no_uncompleted_predecessors_or_deferral?
|
||||||
|
|
@ -108,7 +109,7 @@ class Todo < ActiveRecord::Base
|
||||||
# Returns a string with description <context, project>
|
# Returns a string with description <context, project>
|
||||||
def specification
|
def specification
|
||||||
project_name = project.is_a?(NullProject) ? "(none)" : project.name
|
project_name = project.is_a?(NullProject) ? "(none)" : project.name
|
||||||
return "\"#{description}\" <\"#{context.title}\"; \"#{project_name}\">"
|
return "\'#{description}\' <\'#{context.title}\'; \'#{project_name}\'>"
|
||||||
end
|
end
|
||||||
|
|
||||||
def todo_from_specification(specification)
|
def todo_from_specification(specification)
|
||||||
|
|
@ -139,6 +140,7 @@ class Todo < ActiveRecord::Base
|
||||||
:project_id => project_id
|
:project_id => project_id
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
return nil if todos.empty?
|
return nil if todos.empty?
|
||||||
|
|
||||||
# TODO: what todo if there are more than one todo that fit the specification
|
# TODO: what todo if there are more than one todo that fit the specification
|
||||||
|
|
@ -168,10 +170,14 @@ class Todo < ActiveRecord::Base
|
||||||
remove_array = current_array - @predecessor_array
|
remove_array = current_array - @predecessor_array
|
||||||
add_array = @predecessor_array - current_array
|
add_array = @predecessor_array - current_array
|
||||||
|
|
||||||
|
@removed_predecessors = []
|
||||||
# This is probably a bit naive code...
|
# This is probably a bit naive code...
|
||||||
remove_array.each do |specification|
|
remove_array.each do |specification|
|
||||||
t = todo_from_specification(specification)
|
t = todo_from_specification(specification)
|
||||||
self.predecessors.delete(t) unless t.nil?
|
unless t.nil?
|
||||||
|
@removed_predecessors << t
|
||||||
|
self.predecessors.delete(t)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
# ... as is this?
|
# ... as is this?
|
||||||
add_array.each do |specification|
|
add_array.each do |specification|
|
||||||
|
|
@ -185,6 +191,10 @@ class Todo < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def removed_predecessors
|
||||||
|
return @removed_predecessors
|
||||||
|
end
|
||||||
|
|
||||||
def remove_predecessor(predecessor)
|
def remove_predecessor(predecessor)
|
||||||
# remove predecessor and activate myself
|
# remove predecessor and activate myself
|
||||||
predecessors.delete(predecessor)
|
predecessors.delete(predecessor)
|
||||||
|
|
|
||||||
|
|
@ -11,15 +11,27 @@ parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag'
|
||||||
<div class="description<%= staleness_class( successor ) %>" style="margin-left: 20px">
|
<div class="description<%= staleness_class( successor ) %>" style="margin-left: 20px">
|
||||||
<span class="todo.descr"><%= h sanitize(successor.description) %></span>
|
<span class="todo.descr"><%= h sanitize(successor.description) %></span>
|
||||||
|
|
||||||
<%= link_to_remote(
|
<%= remote_delete_dependency(successor, predecessor) %>
|
||||||
|
|
||||||
|
<%# link_to_remote(
|
||||||
image_tag("blank.png", :title => t('todos.remove_dependency'), :align => "absmiddle", :class => "delete_item"),
|
image_tag("blank.png", :title => t('todos.remove_dependency'), :align => "absmiddle", :class => "delete_item"),
|
||||||
{:url => {:controller => 'todos', :action => 'remove_predecessor', :id => successor.id},
|
{:url => {:controller => 'todos', :action => 'remove_predecessor', :id => successor.id},
|
||||||
:method => 'delete',
|
:method => 'delete',
|
||||||
:with => "'#{parameters}&predecessor=#{predecessor.id}'",
|
:with => "'#{parameters}&predecessor=#{predecessor.id}'",
|
||||||
:before => successor_start_waiting_js(successor)},
|
:before => successor_start_waiting_js(successor)},
|
||||||
{:style => "background: transparent;"}) %>
|
{:style => "background: transparent;"}) %>
|
||||||
|
|
||||||
<%= render(:partial => "todos/toggle_successors", :object => successor, :locals => { :suppress_button => true }) unless successor.pending_successors.empty? %>
|
<% unless successor.pending_successors.empty? %>
|
||||||
|
<div class="todo_successors" id="<%= dom_id(successor, 'successors') %>">
|
||||||
|
<%= render :partial => "todos/successor",
|
||||||
|
:collection => successor.pending_successors,
|
||||||
|
:locals => { :todo => successor,
|
||||||
|
:parent_container_type => parent_container_type,
|
||||||
|
:suppress_dependencies => true,
|
||||||
|
:predecessor => successor }
|
||||||
|
%>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
<%
|
<%
|
||||||
@todo = todo
|
|
||||||
suppress_context ||= false
|
suppress_context ||= false
|
||||||
suppress_project ||= false
|
suppress_project ||= false
|
||||||
suppress_edit_button ||= todo.completed?
|
suppress_edit_button ||= todo.completed?
|
||||||
|
|
@ -9,9 +8,9 @@ parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag'
|
||||||
%>
|
%>
|
||||||
<div id="<%= dom_id(todo) %>" class="item-container">
|
<div id="<%= dom_id(todo) %>" class="item-container">
|
||||||
<div id="<%= dom_id(todo, 'line') %>" class="item-show">
|
<div id="<%= dom_id(todo, 'line') %>" class="item-show">
|
||||||
<%= remote_star_icon %>
|
<%= remote_star_icon(todo) %>
|
||||||
<%= remote_toggle_checkbox unless source_view_is :deferred %>
|
<%= remote_toggle_checkbox(todo) unless source_view_is :deferred %>
|
||||||
<%= remote_edit_button unless suppress_edit_button %>
|
<%= remote_edit_button(todo) unless suppress_edit_button %>
|
||||||
<ul class="sf-menu sf-item-menu">
|
<ul class="sf-menu sf-item-menu">
|
||||||
<li style="z-index:<%=@z_index_counter%>"><%= image_tag "downarrow.png", :alt=> "" %>
|
<li style="z-index:<%=@z_index_counter%>"><%= image_tag "downarrow.png", :alt=> "" %>
|
||||||
<ul id="ul<%= dom_id(todo) %>">
|
<ul id="ul<%= dom_id(todo) %>">
|
||||||
|
|
@ -25,13 +24,13 @@ parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag'
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="description<%= staleness_class( todo ) %>">
|
<div class="description<%= staleness_class( todo ) %>">
|
||||||
<%= grip_span %>
|
<%= grip_span(todo) %>
|
||||||
<%= date_span -%>
|
<%= date_span(todo) -%>
|
||||||
<span class="todo.descr"><%= h todo.description %></span>
|
<span class="todo.descr"><%= h todo.description %></span>
|
||||||
<%= image_tag_for_recurring_todo(todo) if @todo.from_recurring_todo? %>
|
<%= image_tag_for_recurring_todo(todo) if todo.from_recurring_todo? %>
|
||||||
<%= tag_list %>
|
<%= tag_list(todo) %>
|
||||||
<%= deferred_due_date %>
|
<%= deferred_due_date(todo) %>
|
||||||
<%= project_and_context_links( parent_container_type, :suppress_context => suppress_context, :suppress_project => suppress_project ) %>
|
<%= project_and_context_links( todo, parent_container_type, :suppress_context => suppress_context, :suppress_project => suppress_project ) %>
|
||||||
<%= collapsed_notes_image(todo) if todo.notes? %>
|
<%= collapsed_notes_image(todo) if todo.notes? %>
|
||||||
<%= collapsed_successors_image(todo) unless todo.pending_successors.empty? %>
|
<%= collapsed_successors_image(todo) unless todo.pending_successors.empty? %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ function replace_updated_predecessor() {
|
||||||
|
|
||||||
function show_in_tickler_box() {
|
function show_in_tickler_box() {
|
||||||
$("#tickler-empty-nd").hide();
|
$("#tickler-empty-nd").hide();
|
||||||
$('#tickler').html( html_for_deferred_todos() );
|
$('#tickler').append( html_for_deferred_todo() );
|
||||||
}
|
}
|
||||||
|
|
||||||
function regenerate_predecessor_family() {
|
function regenerate_predecessor_family() {
|
||||||
|
|
@ -37,12 +37,8 @@ function html_for_predecessor() {
|
||||||
return "<%= escape_javascript(render(:partial => @predecessor, :locals => { :parent_container_type => parent_container_type })) %>";
|
return "<%= escape_javascript(render(:partial => @predecessor, :locals => { :parent_container_type => parent_container_type })) %>";
|
||||||
}
|
}
|
||||||
|
|
||||||
function html_for_deferred_todos() {
|
function html_for_deferred_todo() {
|
||||||
return "<%= escape_javascript(render(:partial => 'todos/deferred', :locals => { :deferred => @todo.project.deferred_todos,
|
return "<%= escape_javascript(render(:partial => @todo, :locals => { :parent_container_type => parent_container_type })) %>";
|
||||||
:collapsible => false,
|
|
||||||
:append_descriptor => t('todos.append_in_this_project'),
|
|
||||||
:parent_container_type => 'project',
|
|
||||||
:pending => @todo.project.pending_todos })) %>";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<% end # if !@saved
|
<% end # if !@saved
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,63 @@
|
||||||
if @removed
|
<% # TODO: lots of overlap with add_predecessor --> helpers?
|
||||||
status_message = t('todos.removed_predecessor', :successor => @successor.description, :predecessor => @predecessor.description)
|
if @removed -%>
|
||||||
page.notify :notice, status_message, 5.0
|
TracksPages.page_notify('notice', "<%= t('todos.removed_predecessor', :successor => @successor.description, :predecessor => @predecessor.description) %>", 8);
|
||||||
|
|
||||||
# replace old predecessor with one without the successor
|
replace_updated_predecessor();
|
||||||
page.replace dom_id(@predecessor), :partial => 'todos/todo', :locals => {
|
regenerate_predecessor_family();
|
||||||
:todo => @predecessor, :parent_container_type => parent_container_type }
|
update_successor();
|
||||||
|
<% else -%>
|
||||||
|
TracksPages.page_notify('error', "<%=t('todos.error_removing_dependency')%>", 8);
|
||||||
|
<% end -%>
|
||||||
|
|
||||||
# regenerate predecessor family
|
function replace_updated_predecessor() {
|
||||||
|
$('#<%= dom_id(@predecessor) %>').html( html_for_predecessor() );
|
||||||
|
}
|
||||||
|
|
||||||
|
function regenerate_predecessor_family() {
|
||||||
|
<%
|
||||||
parents = @predecessor.predecessors
|
parents = @predecessor.predecessors
|
||||||
until parents.empty?
|
until parents.empty?
|
||||||
parent = parents.pop
|
parent = parents.pop
|
||||||
parents += parent.predecessors
|
parents += parent.predecessors -%>
|
||||||
page[parent].replace_html :partial => 'todos/todo', :locals => { :todo => parent, :parent_container_type => parent_container_type }
|
$('#<%= dom_id(parent) %>').html("<%= escape_javascript(render(:partial => parent, :locals => { :parent_container_type => parent_container_type })) %>");
|
||||||
end
|
<%end -%>
|
||||||
|
}
|
||||||
|
|
||||||
# update display if pending->active
|
function update_successor() {
|
||||||
if @successor.active?
|
<%
|
||||||
page[@successor].remove unless source_view_is_one_of(:todo, :context)
|
if @successor.active? -%>
|
||||||
page[empty_container_msg_div_id].hide unless empty_container_msg_div_id.nil?
|
<%= "remove_successor();" unless source_view_is_one_of(:todo, :context) %>
|
||||||
page.call "todoItems.ensureVisibleWithEffectAppear", "c#{@successor.context_id}"
|
<%= "hide_empty_message();" unless empty_container_msg_div_id.nil? %>
|
||||||
page.insert_html :bottom, item_container_id(@successor), :partial => 'todos/todo', :locals => {
|
<%= "show_empty_deferred_message(); " if @remaining_deferred_or_pending_count == 0 %>
|
||||||
:todo => @successor, :parent_container_type => parent_container_type }
|
<% if source_view_is_one_of(:todo, :deferred, :tag) -%>
|
||||||
page.visual_effect :highlight, dom_id(@successor, 'line'), {'startcolor' => "'#99ff99'"}
|
$('#c<%= @successor.context_id %>').fadeIn(500, function() {});
|
||||||
|
$('#no_todos_in_tag_view').slideUp(100);
|
||||||
|
<% end -%>
|
||||||
|
$('#<%=item_container_id(@successor)%>').append(html_for_new_successor());
|
||||||
|
$('#<%= dom_id(@successor, 'line')%>').effect('highlight', {}, 2000 ); <%
|
||||||
|
elsif @successor.deferred? -%>
|
||||||
|
$('#<%= dom_id(@successor)%>').html(html_for_new_successor()); <%
|
||||||
end
|
end
|
||||||
|
%>
|
||||||
|
}
|
||||||
|
|
||||||
# update display if pending->deferred
|
function hide_empty_message() {
|
||||||
if @successor.deferred?
|
$('#<%=empty_container_msg_div_id%>').hide();
|
||||||
page.replace dom_id(@successor), :partial => 'todos/todo', :locals => {
|
}
|
||||||
:todo => @successor, :parent_container_type => parent_container_type }
|
|
||||||
end
|
function show_empty_deferred_message() {
|
||||||
page << "enable_rich_interaction();"
|
$('#tickler-empty-nd').slideDown(100);
|
||||||
else
|
}
|
||||||
page.notify :error, t('todos.error_removing_dependency'), 8.0
|
function remove_successor() {
|
||||||
end
|
<% # TODO: last todo in context --> remove context??
|
||||||
|
-%>
|
||||||
|
$('#<%=dom_id(@successor)%>').remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function html_for_predecessor() {
|
||||||
|
return "<%= @removed ? escape_javascript(render(:partial => @predecessor, :locals => { :parent_container_type => parent_container_type })) : "" %>";
|
||||||
|
}
|
||||||
|
|
||||||
|
function html_for_new_successor() {
|
||||||
|
return "<%= @removed ? escape_javascript(render(:partial => @successor, :locals => { :parent_container_type => parent_container_type })) : "" %>";
|
||||||
|
}
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
animation << "hide_context" if update_needs_to_hide_context
|
animation << "hide_context" if update_needs_to_hide_context
|
||||||
animation << "highlight_updated_todo"
|
animation << "highlight_updated_todo"
|
||||||
animation << "update_empty_tag_container" if source_view_is(:tag)
|
animation << "update_empty_tag_container" if source_view_is(:tag)
|
||||||
|
animation << "update_predecessors"
|
||||||
%>
|
%>
|
||||||
|
|
||||||
<%= render_animation(animation) %>
|
<%= render_animation(animation) %>
|
||||||
|
|
@ -35,7 +36,7 @@ function add_to_existing_container(next_steps) {
|
||||||
$('#<%= item_container_id(@todo) %>').append(html_for_todo());
|
$('#<%= item_container_id(@todo) %>').append(html_for_todo());
|
||||||
<% if source_view_is_one_of(:project,:calendar) -%>
|
<% if source_view_is_one_of(:project,:calendar) -%>
|
||||||
next_steps.go();
|
next_steps.go();
|
||||||
<% if (@target_context_count==1) || (@todo.deferred? && @remaining_deferred_or_pending_count == 1) -%>
|
<% if (@target_context_count==1) || ( (@todo.deferred? || @todo.pending?) && @remaining_deferred_or_pending_count == 1) -%>
|
||||||
$("#<%= empty_container_msg_div_id %>").slideUp(100);
|
$("#<%= empty_container_msg_div_id %>").slideUp(100);
|
||||||
<% end -%>
|
<% end -%>
|
||||||
<% else -%>
|
<% else -%>
|
||||||
|
|
@ -109,4 +110,9 @@ function update_predecessors() {
|
||||||
$('#<%=dom_id(p)%>').html('<%=escape_javascript(render(:partial => p, :locals => { :parent_container_type => parent_container_type }))%>');
|
$('#<%=dom_id(p)%>').html('<%=escape_javascript(render(:partial => p, :locals => { :parent_container_type => parent_container_type }))%>');
|
||||||
}
|
}
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
<% @removed_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 }))%>');
|
||||||
|
}
|
||||||
|
<% end -%>
|
||||||
}
|
}
|
||||||
|
|
@ -9,21 +9,21 @@ Feature: dependencies
|
||||||
| testuser | secret | false |
|
| testuser | secret | false |
|
||||||
And I have logged in as "testuser" with password "secret"
|
And I have logged in as "testuser" with password "secret"
|
||||||
|
|
||||||
@selenium @wip
|
@selenium
|
||||||
Scenario: Adding dependency to dependency
|
Scenario: Adding dependency to dependency by drag and drop
|
||||||
Given I have a project "dependencies" with 3 todos
|
Given I have a project "dependencies" with 3 todos
|
||||||
And "Todo 2" depends on "Todo 1"
|
And "Todo 2" depends on "Todo 1"
|
||||||
When I visit the "dependencies" project
|
When I visit the "dependencies" project
|
||||||
And I drag "Todo 3" to "Todo 2"
|
And I drag "Todo 3" to "Todo 2"
|
||||||
Then the dependencies of "Todo 2" should include "Todo 1"
|
Then the successors of "Todo 1" should include "Todo 2"
|
||||||
And the dependencies of "Todo 3" should include "Todo 2"
|
And the successors of "Todo 2" should include "Todo 3"
|
||||||
When I expand the dependencies of "Todo 1"
|
When I expand the dependencies of "Todo 1"
|
||||||
Then I should see "Todo 2" within the dependencies of "Todo 1"
|
Then I should see "Todo 2" within the dependencies of "Todo 1"
|
||||||
And I should see "Todo 3" within the dependencies of "Todo 1"
|
And I should see "Todo 3" within the dependencies of "Todo 1"
|
||||||
When I expand the dependencies of "Todo 2"
|
When I expand the dependencies of "Todo 2"
|
||||||
Then I should see "Todo 3" within the dependencies of "Todo 2"
|
Then I should see "Todo 3" within the dependencies of "Todo 2"
|
||||||
|
|
||||||
@selenium @wip
|
@selenium
|
||||||
Scenario: Adding dependency with comma to todo # for #975
|
Scenario: Adding dependency with comma to todo # for #975
|
||||||
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
|
||||||
|
|
@ -32,9 +32,49 @@ Feature: dependencies
|
||||||
| test me | @pc |
|
| test me | @pc |
|
||||||
When I visit the "dependencies" project
|
When I visit the "dependencies" project
|
||||||
And I drag "test me" to "test,1, 2,3"
|
And I drag "test me" to "test,1, 2,3"
|
||||||
Then the dependencies of "test me" should include "test,1, 2,3"
|
Then the successors of "test,1, 2,3" should include "test me"
|
||||||
When I edit the dependency of "test me" to '"test,1, 2,3" <"@pc"; "dependencies">,"test,1, 2,3" <"@pc"; "dependencies">'
|
When I edit the dependency of "test me" to "'test,1, 2,3' <'@pc'; 'dependencies'>,'test,1, 2,3' <'@pc'; 'dependencies'>"
|
||||||
Then there should not be an error
|
Then there should not be an error
|
||||||
|
|
||||||
Scenario: Deleting a predecessor will activate successors
|
Scenario: Deleting a predecessor will activate successors
|
||||||
Given this is a pending scenario
|
Given this is a pending scenario
|
||||||
|
|
||||||
|
@selenium
|
||||||
|
Scenario: I can edit a todo to add the todo as a dependency to another
|
||||||
|
Given I have a context called "@pc"
|
||||||
|
And I have a project "dependencies" that has the following todos
|
||||||
|
| description | context |
|
||||||
|
| test 1 | @pc |
|
||||||
|
| test 2 | @pc |
|
||||||
|
| test 3 | @pc |
|
||||||
|
When I visit the "dependencies" project
|
||||||
|
When I edit the dependency of "test 1" to "'test 2' <'@pc'; 'dependencies'>"
|
||||||
|
Then I should see "test 1" within the dependencies of "test 2"
|
||||||
|
And I should see "test 1" in the deferred container
|
||||||
|
When I edit the dependency of "test 1" to "'test 2' <'@pc'; 'dependencies'>, 'test 3' <'@pc'; 'dependencies'>"
|
||||||
|
Then I should see "test 1" within the dependencies of "test 2"
|
||||||
|
Then I should see "test 1" within the dependencies of "test 3"
|
||||||
|
When I edit the dependency of "test 1" to "'test 2' <'@pc'; 'dependencies'>"
|
||||||
|
And I edit the dependency of "test 2" to "'test 3' <'@pc'; 'dependencies'>"
|
||||||
|
Then I should see "test 1" within the dependencies of "test 3"
|
||||||
|
Then I should see "test 2" within the dependencies of "test 3"
|
||||||
|
|
||||||
|
@selenium
|
||||||
|
Scenario: I can remove a dependency by editing the todo
|
||||||
|
Given I have a context called "@pc"
|
||||||
|
And I have a project "dependencies" that has the following todos
|
||||||
|
| description | context |
|
||||||
|
| test 1 | @pc |
|
||||||
|
| test 2 | @pc |
|
||||||
|
And "test 1" depends on "test 2"
|
||||||
|
When I visit the "dependencies" project
|
||||||
|
Then I should see "test 1" in the deferred container
|
||||||
|
When I edit the dependency of "test 1" to ""
|
||||||
|
Then I should not see "test 1" within the dependencies of "test 2"
|
||||||
|
And I should not see "test 1" in the deferred container
|
||||||
|
|
||||||
|
Scenario: Deleting a predecessor will activate successors
|
||||||
|
Given this is a pending scenario
|
||||||
|
|
||||||
|
Scenario: Deleting a successor will update predecessor
|
||||||
|
Given this is a pending scenario
|
||||||
|
|
@ -162,14 +162,15 @@ When /^I submit the new multiple actions form with$/ do |multi_line_descriptions
|
||||||
submit_multiple_next_action_form
|
submit_multiple_next_action_form
|
||||||
end
|
end
|
||||||
|
|
||||||
When /^I edit the dependency of "([^"]*)" to '([^'']*)'$/ do |todo_name, deps|
|
When /^I edit the dependency of "([^"]*)" to "([^"]*)"$/ do |todo_name, deps|
|
||||||
todo = @dep_todo = @current_user.todos.find_by_description(todo_name)
|
todo = @dep_todo = @current_user.todos.find_by_description(todo_name)
|
||||||
todo.should_not be_nil
|
todo.should_not be_nil
|
||||||
# click edit
|
# click edit
|
||||||
selenium.click("//div[@id='line_todo_#{todo.id}']//img[@id='edit_icon_todo_#{todo.id}']", :wait_for => :ajax, :javascript_framework => :jquery)
|
selenium.click("//div[@id='line_todo_#{todo.id}']//img[@id='edit_icon_todo_#{todo.id}']", :wait_for => :ajax, :javascript_framework => :jquery)
|
||||||
fill_in "predecessor_list_todo_#{todo.id}", :with => deps
|
fill_in "predecessor_list_todo_#{todo.id}", :with => deps
|
||||||
# submit form
|
|
||||||
selenium.click("//div[@id='edit_todo_#{todo.id}']//button[@id='submit_todo_#{todo.id}']", :wait_for => :ajax, :javascript_framework => :jquery)
|
submit_edit_todo_form(todo)
|
||||||
|
sleep(1) # TODO: replace with some wait_for
|
||||||
end
|
end
|
||||||
|
|
||||||
Then /^I should see ([0-9]+) todos$/ do |count|
|
Then /^I should see ([0-9]+) todos$/ do |count|
|
||||||
|
|
@ -179,11 +180,12 @@ Then /^I should see ([0-9]+) todos$/ do |count|
|
||||||
end
|
end
|
||||||
|
|
||||||
Then /^there should not be an error$/ do
|
Then /^there should not be an error$/ do
|
||||||
# form should be gone and thus not errors visible
|
sleep(5)
|
||||||
|
# form should be gone and thus no errors visible
|
||||||
selenium.is_visible("edit_todo_#{@dep_todo.id}").should == false
|
selenium.is_visible("edit_todo_#{@dep_todo.id}").should == false
|
||||||
end
|
end
|
||||||
|
|
||||||
Then /^the dependencies of "(.*)" should include "(.*)"$/ do |child_name, parent_name|
|
Then /^the successors of "(.*)" should include "(.*)"$/ do |parent_name, child_name|
|
||||||
parent = @current_user.todos.find_by_description(parent_name)
|
parent = @current_user.todos.find_by_description(parent_name)
|
||||||
parent.should_not be_nil
|
parent.should_not be_nil
|
||||||
|
|
||||||
|
|
@ -206,6 +208,17 @@ Then /^I should see "([^\"]*)" within the dependencies of "([^\"]*)"$/ do |succe
|
||||||
selenium.wait_for_element(xpath, :timeout_in_seconds => 5)
|
selenium.wait_for_element(xpath, :timeout_in_seconds => 5)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Then /^I should not see "([^"]*)" within the dependencies of "([^"]*)"$/ do |successor_description, todo_description|
|
||||||
|
todo = @current_user.todos.find_by_description(todo_description)
|
||||||
|
todo.should_not be_nil
|
||||||
|
successor = @current_user.todos.find_by_description(successor_description)
|
||||||
|
successor.should_not be_nil
|
||||||
|
# let selenium look for the presence of the successor
|
||||||
|
xpath = "xpath=//div[@id='line_todo_#{todo.id}']//div[@id='successor_line_todo_#{successor.id}']//span"
|
||||||
|
selenium.is_element_present(xpath).should be_false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
Then /^I should see the todo "([^\"]*)"$/ do |todo_description|
|
Then /^I should see the todo "([^\"]*)"$/ do |todo_description|
|
||||||
selenium.is_element_present("//span[.=\"#{todo_description}\"]").should be_true
|
selenium.is_element_present("//span[.=\"#{todo_description}\"]").should be_true
|
||||||
end
|
end
|
||||||
|
|
@ -237,3 +250,21 @@ end
|
||||||
Then /^a confirmation for adding a new context "([^"]*)" should be asked$/ do |context_name|
|
Then /^a confirmation for adding a new context "([^"]*)" should be asked$/ do |context_name|
|
||||||
selenium.get_confirmation.should == "New context \"#{context_name}\" will be also created. Are you sure?"
|
selenium.get_confirmation.should == "New context \"#{context_name}\" will be also created. Are you sure?"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Then /^I should see "([^"]*)" in the deferred container$/ do |todo_description|
|
||||||
|
todo = @current_user.todos.find_by_description(todo_description)
|
||||||
|
todo.should_not be_nil
|
||||||
|
|
||||||
|
xpath = "//div[@id='tickler']//div[@id='line_todo_#{todo.id}']"
|
||||||
|
|
||||||
|
selenium.is_element_present(xpath).should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
Then /^I should not see "([^"]*)" in the deferred container$/ do |todo_description|
|
||||||
|
todo = @current_user.todos.find_by_description(todo_description)
|
||||||
|
todo.should_not be_nil
|
||||||
|
|
||||||
|
xpath = "//div[@id='tickler']//div[@id='line_todo_#{todo.id}']"
|
||||||
|
|
||||||
|
selenium.is_element_present(xpath).should be_false
|
||||||
|
end
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,10 @@ module TracksStepHelper
|
||||||
selenium.click("xpath=//form[@id='project_form']//button[@id='project_new_project_submit']", :wait_for => :ajax, :javascript_framework => :jquery)
|
selenium.click("xpath=//form[@id='project_form']//button[@id='project_new_project_submit']", :wait_for => :ajax, :javascript_framework => :jquery)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def submit_edit_todo_form (todo)
|
||||||
|
selenium.click("//div[@id='edit_todo_#{todo.id}']//button[@id='submit_todo_#{todo.id}']", :wait_for => :ajax, :javascript_framework => :jquery)
|
||||||
|
end
|
||||||
|
|
||||||
def format_date(date)
|
def format_date(date)
|
||||||
# copy-and-past from ApplicationController::format_date
|
# copy-and-past from ApplicationController::format_date
|
||||||
return date ? date.in_time_zone(@current_user.prefs.time_zone).strftime("#{@current_user.prefs.date_format}") : ''
|
return date ? date.in_time_zone(@current_user.prefs.time_zone).strftime("#{@current_user.prefs.date_format}") : ''
|
||||||
|
|
|
||||||
|
|
@ -338,7 +338,7 @@ var TodoItems = {
|
||||||
|
|
||||||
/* set behavior for toggle checkboxes for Recurring Todos */
|
/* set behavior for toggle checkboxes for Recurring Todos */
|
||||||
$(".item-container input.item-checkbox").live('click', function(ev){
|
$(".item-container input.item-checkbox").live('click', function(ev){
|
||||||
put_with_ajax_and_block_element(this.value, $(this));
|
put_with_ajax_and_block_element(this.value, $(this).parents(".item-container"));
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -362,14 +362,23 @@ var TodoItems = {
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// defer a todo
|
||||||
$(".item-container a.icon_defer_item").live('click', function(ev){
|
$(".item-container a.icon_defer_item").live('click', function(ev){
|
||||||
if ($(this).attr("x_defer_alert") == "true")
|
if ($(this).attr("x_defer_alert") == "true")
|
||||||
alert ($(this).attr("x_defer_date_after_due_date"));
|
alert ($(this).attr("x_defer_date_after_due_date"));
|
||||||
else
|
else
|
||||||
put_with_ajax_and_block_element(this.href, $(this));
|
put_with_ajax_and_block_element(this.href, $(this).parents(".item-container"));
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* delete button to delete a project from the list */
|
||||||
|
$('.item-container a.delete_dependency_button').live('click', function(evt){
|
||||||
|
predecessor_id=$(this).attr("x_predecessors_id");
|
||||||
|
ajax_options = default_ajax_options_for_scripts('DELETE', this.href, $(this).parents('.item-container'));
|
||||||
|
ajax_options.data += "&predecessor="+predecessor_id
|
||||||
|
$.ajax(ajax_options);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -941,8 +950,37 @@ function enable_rich_interaction(){
|
||||||
/* multiple: true,
|
/* multiple: true,
|
||||||
multipleSeparator:',' */
|
multipleSeparator:',' */
|
||||||
|
|
||||||
$('input[name=predecessor_list]:not(.ac_input)').autocomplete({
|
$('input[name=predecessor_list]:not(.ac_input)')
|
||||||
source: relative_to_root('auto_complete_for_predecessor')
|
.bind( "keydown", function( event ) { // don't navigate away from the field on tab when selecting an item
|
||||||
|
if ( event.keyCode === $.ui.keyCode.TAB &&
|
||||||
|
$( this ).data( "autocomplete" ).menu.active ) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.autocomplete({
|
||||||
|
minLength: 0,
|
||||||
|
source: function( request, response ) {
|
||||||
|
last_term = extractLast( request.term );
|
||||||
|
if (last_term != "" && last_term != " ")
|
||||||
|
$.getJSON( relative_to_root('auto_complete_for_predecessor'), {
|
||||||
|
term: last_term
|
||||||
|
}, response );
|
||||||
|
},
|
||||||
|
focus: function() {
|
||||||
|
// prevent value inserted on focus
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
select: function( event, ui ) {
|
||||||
|
var terms = split( this.value );
|
||||||
|
// remove the current input
|
||||||
|
terms.pop();
|
||||||
|
// add the selected item
|
||||||
|
terms.push( ui.item.value );
|
||||||
|
// add placeholder to get the comma-and-space at the end
|
||||||
|
//terms.push( "" );
|
||||||
|
this.value = terms.join( ", " );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* have to bind on keypress because of limitations of live() */
|
/* have to bind on keypress because of limitations of live() */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue