Fixed #581, "Empty tickler screen should display a message", and handled the related ajax implications.

git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@630 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
lukemelia 2007-11-05 05:42:43 +00:00
parent 71010ff681
commit b440e2b2ee
12 changed files with 114 additions and 43 deletions

View file

@ -221,11 +221,9 @@ class TodosController < ApplicationController
format.js do
if @saved
determine_down_count
source_view do |from|
from.todo do
determine_remaining_in_context_count(@context_id)
end
end
if source_view_is_one_of(:todo, :deferred)
determine_remaining_in_context_count(@context_id)
end
end
render
end

View file

@ -73,8 +73,8 @@ module TodosHelper
elsif @todo.deferred?
show_date( @todo.show_from )
else
due_date( @todo.due )
end
due_date( @todo.due )
end
end
def tag_list_text
@ -132,31 +132,31 @@ module TodosHelper
# Check show_from date in comparison to today's date Flag up date
# appropriately with a 'traffic light' colour code
#
def show_date(due)
if due == nil
def show_date(d)
if d == nil
return ""
end
days = days_from_today(due)
days = days_from_today(d)
case days
# overdue or due very soon! sound the alarm!
when -1000..-1
"<a title='" + format_date(due) + "'><span class=\"red\">Shown on " + (days * -1).to_s + " days</span></a> "
"<a title=\"" + format_date(d) + "\"><span class=\"red\">Scheduled to show " + (days * -1).to_s + " days ago</span></a> "
when 0
"<a title='" + format_date(due) + "'><span class=\"amber\">Show Today</span></a> "
"<a title=\"" + format_date(d) + "\"><span class=\"amber\">Show Today</span></a> "
when 1
"<a title='" + format_date(due) + "'><span class=\"amber\">Show Tomorrow</span></a> "
"<a title=\"" + format_date(d) + "\"><span class=\"amber\">Show Tomorrow</span></a> "
# due 2-7 days away
when 2..7
if prefs.due_style == Preference.due_styles[:due_on]
"<a title='" + format_date(due) + "'><span class=\"orange\">Show on " + due.strftime("%A") + "</span></a> "
"<a title=\"" + format_date(d) + "\"><span class=\"orange\">Show on " + d.strftime("%A") + "</span></a> "
else
"<a title='" + format_date(due) + "'><span class=\"orange\">Show in " + days.to_s + " days</span></a> "
"<a title=\"" + format_date(d) + "\"><span class=\"orange\">Show in " + days.to_s + " days</span></a> "
end
# more than a week away - relax
else
"<a title='" + format_date(due) + "'><span class=\"green\">Show in " + days.to_s + " days</span></a> "
"<a title=\"" + format_date(d) + "\"><span class=\"green\">Show in " + days.to_s + " days</span></a> "
end
end

View file

@ -33,7 +33,7 @@ class Todo < ActiveRecord::Base
transitions :to => :deferred, :from => [:project_hidden], :guard => Proc.new{|t| !t.show_from.blank? }
transitions :to => :active, :from => [:project_hidden]
end
attr_protected :user
# Description field can't be empty, and must be < 100 bytes
@ -63,6 +63,10 @@ class Todo < ActiveRecord::Base
save!
end
def show_from
self[:show_from]
end
def show_from=(date)
activate! if deferred? && date.blank?
defer! if active? && !date.blank? && date > user.date
@ -84,6 +88,15 @@ class Todo < ActiveRecord::Base
original_set_initial_state
end
end
alias_method :original_run_initial_state_actions, :run_initial_state_actions
def run_initial_state_actions
#only run the initial state actions if the standard initial state hasn't been changed
if self.class.initial_state.to_sym == current_state
original_run_initial_state_actions
end
end
def self.feed_options(user)
{
@ -92,7 +105,6 @@ class Todo < ActiveRecord::Base
}
end
def starred?
tags.any? {|tag| tag.name == STARRED_TAG_NAME}
end

View file

@ -13,11 +13,12 @@ if @saved
if @new_context_created
page.insert_html :top, 'display_box', :partial => 'contexts/context', :locals => { :context => @todo.context, :collapsible => true }
else
page.call "todoItems.ensureVisibleWithEffectAppear", "c#{@todo.context_id}" if source_view_is(:todo)
page.call "todoItems.ensureVisibleWithEffectAppear", "c#{@todo.context_id}" if source_view_is_one_of(:todo, :deferred)
page.insert_html :bottom, item_container_id, :partial => 'todos/todo', :locals => { :parent_container_type => parent_container_type, :source_view => @source_view }
page.visual_effect :highlight, dom_id(@todo), :duration => 3
page[empty_container_msg_div_id].hide unless empty_container_msg_div_id.nil?
end
page['tickler-empty-nd'].hide if source_view_is :deferred
end
else
page.show 'status'

View file

@ -1,8 +1,9 @@
if @saved
page[@todo].remove
page['badge_count'].replace_html @down_count
page.visual_effect :fade, item_container_id, :duration => 0.4 if source_view_is(:todo) && @remaining_in_context == 0
page.visual_effect :fade, item_container_id, :duration => 0.4 if source_view_is_one_of(:todo, :deferred) && @remaining_in_context == 0
page[empty_container_msg_div_id].show if !empty_container_msg_div_id.nil? && @down_count == 0
page['tickler-empty-nd'].show if source_view_is(:deferred) && @down_count == 0
else
page.notify :error, "There was an error deleting the item #{@todo.description}", 8.0
end

View file

@ -1,5 +1,9 @@
<div id="display_box">
<div id="tickler-empty-nd" style="display:<%= (@count == 0) ? 'block' : 'none'%>;">
<div class="message"><p>Currently there are no deferred actions.</p></div>
</div>
<%= render :partial => "contexts/context", :collection => @contexts,
:locals => { :collapsible => true } %>

View file

@ -6,7 +6,7 @@ if @saved
page.notify :notice, status_message, 5.0
page << "contextAutoCompleter.options.array = #{context_names_for_autocomplete}; contextAutoCompleter.changed = true" if @new_context_created
page << "projectAutoCompleter.options.array = #{project_names_for_autocomplete}; projectAutoCompleter.changed = true" if @new_project_created
if source_view_is_one_of [:todo, :context]
if source_view_is_one_of(:todo, :context)
if @context_changed || @todo.deferred?
page[@todo].remove
if (@remaining_in_context == 0)

View file

@ -29,6 +29,10 @@ module Tracks
def source_view_is( s )
s == (params[:_source_view] || @source_view).to_sym
end
def source_view_is_one_of( *s )
s.include?(params[:_source_view].to_sym)
end
def source_view
responder = Tracks::SourceViewSwitching::Responder.new(params[:_source_view] || @source_view)
@ -47,7 +51,7 @@ module Tracks
s == (params[:_source_view] || @source_view).to_sym
end
def source_view_is_one_of( s=[] )
def source_view_is_one_of( *s )
s.include?(params[:_source_view].to_sym)
end

View file

@ -1,10 +1,12 @@
setup :fixtures => :all
setup :fixtures => [:users, :preferences, :contexts, :projects], :clear_tables => [:todos]
login :as => 'admin'
open "/tickler"
store_eval "this.browserbot.getCurrentWindow().$$('.context').length", 'initial_context_count'
type "todo_description", "a new action"
type "todo_context_name", "errands"
type "todo_show_from", "1/1/2030"
click "css=#todo-form-new-action .submit_box button"
store_eval "${initial_context_count} + 1", 'expected_context_count'
wait_for_eval "this.browserbot.getCurrentWindow().$$('.context').length", "${expected_context_count}"
assert_context_count_incremented do
type "todo_description", "a new action"
type "todo_context_name", "errands"
type "todo_project_name", "None"
type "todo_show_from", "1/1/2030"
click "css=#todo-form-new-action .submit_box button"
end
wait_for_not_visible "tickler-empty-nd"
wait_for_element_present "xpath=//div[@class='item-container'] //a[@title='01/01/2030']"

View file

@ -1,10 +1,9 @@
setup :fixtures => :all
login :as => 'admin'
open "/tickler"
store_eval "this.browserbot.getCurrentWindow().$$('.context').length", 'initial_context_count'
type "todo_description", "a new action"
type "todo_context_name", "Brand new context"
type "todo_show_from", "1/1/2030"
click "css=#todo-form-new-action .submit_box button"
store_eval "${initial_context_count} + 1", 'expected_context_count'
wait_for_eval "this.browserbot.getCurrentWindow().$$('.context').length", "${expected_context_count}"
assert_context_count_incremented do
type "todo_description", "a new action"
type "todo_context_name", "Brand new context"
type "todo_show_from", "1/1/2030"
click "css=#todo-form-new-action .submit_box button"
end

View file

@ -77,12 +77,19 @@ class TodoTest < Test::Rails::TestCase
def test_create_a_new_deferred_todo
user = users(:other_user)
item = user.todos.build
item.show_from = next_week
item.context_id = 1
item.description = 'foo'
assert item.save, "should have saved successfully" + item.errors.to_xml
assert_equal :deferred, item.current_state
todo = user.todos.build
todo.show_from = next_week
todo.context_id = 1
todo.description = 'foo'
assert todo.save, "should have saved successfully" + todo.errors.to_xml
assert_equal :deferred, todo.current_state
end
def test_create_a_new_deferred_todo_by_passing_attributes
user = users(:other_user)
todo = user.todos.build(:show_from => next_week, :context_id => 1, :description => 'foo')
assert todo.save, "should have saved successfully" + todo.errors.to_xml
assert_equal :deferred, todo.current_state
end
def test_feed_options

View file

@ -6,8 +6,51 @@ class TodosHelperTest < Test::Rails::HelperTestCase
super
end
include ActionView::Helpers::DateHelper
include ApplicationHelper
include TodosHelper
def user_time
Time.now
end
def format_date(date)
if date
date_format = "%d/%m/%Y"
date.strftime("#{date_format}")
else
''
end
end
def test_show_date_in_past
date = 3.days.ago.to_date
html = show_date(date)
formatted_date = format_date(date)
assert_equal %Q{<a title="#{formatted_date}"><span class="red">Scheduled to show 3 days ago</span></a> }, html
end
def test_show_date_today
date = Time.now.to_date
html = show_date(date)
formatted_date = format_date(date)
assert_equal %Q{<a title="#{formatted_date}"><span class="amber">Show Today</span></a> }, html
end
def test_show_date_tomorrow
date = 1.day.from_now.to_date
html = show_date(date)
formatted_date = format_date(date)
assert_equal %Q{<a title="#{formatted_date}"><span class="amber">Show Tomorrow</span></a> }, html
end
def test_show_date_future
date = 10.days.from_now.to_date
html = show_date(date)
formatted_date = format_date(date)
assert_equal %Q{<a title="#{formatted_date}"><span class="green">Show in 10 days</span></a> }, html
end
def test_remote_star_icon_unstarred
@todo = flexmock(:id => 1, :to_param => 1, :description => 'Get gas', :starred? => false)
assert_remote_star_icon_helper_matches %r{<a href="/todos/1;toggle_star" class="icon star_item" title="star the action 'Get gas'"><img alt="Blank" class="unstarred_todo" src="/images/blank.png[?0-9]*" title="Star action" /></a>}