diff --git a/tracks/app/controllers/application.rb b/tracks/app/controllers/application.rb index cedfbe1d..0cd8a5d9 100644 --- a/tracks/app/controllers/application.rb +++ b/tracks/app/controllers/application.rb @@ -2,6 +2,7 @@ # Likewise will all the methods added be available for all controllers. require_dependency "login_system" +require_dependency "source_view" require "redcloth" require 'date' @@ -73,6 +74,7 @@ class ApplicationController < ActionController::Base end def parse_date_per_user_prefs( s ) + return nil if s == '' Date.strptime(s, @user.preferences["date_format"]) end diff --git a/tracks/app/controllers/context_controller.rb b/tracks/app/controllers/context_controller.rb index 2f7f4e03..6d3329f7 100644 --- a/tracks/app/controllers/context_controller.rb +++ b/tracks/app/controllers/context_controller.rb @@ -29,7 +29,6 @@ class ContextController < ApplicationController init check_user_set_context init_todos - @on_page = "context" @page_title = "TRACKS::Context: #{@context.name}" end @@ -58,7 +57,6 @@ class ContextController < ApplicationController end @saved = @item.save - @on_page = "context" if @saved # This reports real count +1 for some reason that I don't understand # Almost identical code for add_item in projects reports correct num @@ -85,36 +83,6 @@ class ContextController < ApplicationController end end - # Delete a next action - # - def destroy_action - self.init - @item = check_user_return_item - - @saved = @item.destroy - if @saved - @down_count = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = ? and todos.context_id IN (?)", @user.id, false, @item.context_id]).size.to_s - end - - return if request.xhr? - - # fallback for standard requests - if @saved - flash["notice"] = 'Successfully deleted next action' - redirect_to :controller => 'todo', :action => 'list' - else - render :controller => 'todo', :action => 'list' - end - - rescue - if request.xhr? # be sure to include an error.rjs - render :action => 'error' - else - flash["warning"] = 'An error occurred on the server.' - render :controller => 'todo', :action => 'list' - end - end - # Toggles the 'done' status of the action # def toggle_check @@ -217,6 +185,7 @@ class ContextController < ApplicationController end def init + @source_view = params['_source_view'] || 'context' @projects = @user.projects.collect { |x| x.done? ? nil:x }.compact @contexts = @user.contexts @todos = @user.todos diff --git a/tracks/app/controllers/deferred_controller.rb b/tracks/app/controllers/deferred_controller.rb index 837d58f2..a2b13a58 100644 --- a/tracks/app/controllers/deferred_controller.rb +++ b/tracks/app/controllers/deferred_controller.rb @@ -11,6 +11,7 @@ class DeferredController < ApplicationController def index + @source_view = 'deferred' init_projects_and_contexts init_not_done_counts @page_title = "TRACKS::Tickler" @@ -19,6 +20,7 @@ class DeferredController < ApplicationController end def create + @source_view = 'deferred' @item = Deferred.new @item.attributes = params["todo"] if params["todo"]["show_from"] @@ -46,12 +48,14 @@ class DeferredController < ApplicationController end def edit + @source_view = 'deferred' init_projects_and_contexts @item = check_user_return_item render :layout => false end def update + @source_view = 'deferred' @item = check_user_return_item @original_item_context_id = @item.context_id @item.attributes = params["item"] diff --git a/tracks/app/controllers/project_controller.rb b/tracks/app/controllers/project_controller.rb index cb0e4d3a..2e1a9dd3 100644 --- a/tracks/app/controllers/project_controller.rb +++ b/tracks/app/controllers/project_controller.rb @@ -31,7 +31,6 @@ class ProjectController < ApplicationController init init_todos @notes = @project.notes - @on_page = "project" @page_title = "TRACKS::Project: #{@project.name}" if @contexts.empty? @@ -80,7 +79,6 @@ class ProjectController < ApplicationController end @saved = @item.save - @on_page = "project" if @saved @up_count = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = ? and todos.project_id IN (?)", @user.id, false, @item.project_id]).size.to_s end @@ -104,37 +102,6 @@ class ProjectController < ApplicationController redirect_to :controller => 'todo', :action => 'index' end end - - # Delete a next action - # - def destroy_action - self.init - @item = check_user_return_item - - @saved = @item.destroy - @on_page = "project" - if @saved - @down_count = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = ? and todos.project_id IN (?)", @user.id, false, @item.project_id]).size.to_s - end - - return if request.xhr? - - # fallback for standard requests - if @saved - flash["notice"] = 'Successfully deleted next action' - redirect_to :controller => 'todo', :action => 'index' - else - render :controller => 'todo', :action => 'index' - end - - rescue - if request.xhr? # be sure to include an error.rjs - render :action => 'error' - else - flash["warning"] = 'An error occurred on the server.' - render :controller => 'todo', :action => 'index' - end - end # Toggles the 'done' status of the action # @@ -145,7 +112,6 @@ class ProjectController < ApplicationController @item.toggle!('done') @item.completed = Time.now() # For some reason, the before_save in todo.rb stopped working @saved = @item.save - @on_page = "project" if @saved @down_count = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = ? and todos.project_id IN (?)", @user.id, false, @item.project_id]).size.to_s @done_count = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = ? and todos.project_id IN (?)", @user.id, true, @item.project_id]).size.to_s @@ -249,6 +215,7 @@ class ProjectController < ApplicationController end def init + @source_view = params['_source_view'] || 'project' @projects = @user.projects @contexts = @user.contexts @todos = @user.todos diff --git a/tracks/app/controllers/todo_controller.rb b/tracks/app/controllers/todo_controller.rb index 0173b2e9..da68ee6c 100644 --- a/tracks/app/controllers/todo_controller.rb +++ b/tracks/app/controllers/todo_controller.rb @@ -17,7 +17,6 @@ class TodoController < ApplicationController @projects = @user.projects.find(:all, :include => [ :todos ]) @contexts = @user.contexts.find(:all, :include => [ :todos ]) - @on_page = "home" @page_title = "TRACKS::List tasks" # If you've set no_completed to zero, the completed items box @@ -54,7 +53,6 @@ class TodoController < ApplicationController self.init @item = @user.todos.build @item.attributes = params["todo"] - @on_page = "home" if @item.due? @item.due = parse_date_per_user_prefs(params["todo"]["due"]) @@ -82,13 +80,13 @@ class TodoController < ApplicationController wants.html do flash["warning"] = 'An error occurred on the server.' render :action => "index" - end + end wants.js { render :action => 'error' } wants.xml { render :text => 'An error occurred on the server.' + $! } end end - def edit_action + def edit self.init @item = check_user_return_item render :layout => false @@ -111,7 +109,6 @@ class TodoController < ApplicationController @item.toggle!('done') @item.completed = Time.now() # For some reason, the before_save in todo.rb stopped working @saved = @item.save - @on_page = "home" @remaining_undone_in_context = Todo.count(:conditions => ['user_id = ? and context_id = ? and type = ? and done = ?', @user.id, @item.context_id, "Immediate", false]) if @saved @down_count = @todos.collect { |x| ( !x.done? and !x.context.hide? ) ? x:nil }.compact.size.to_s @@ -130,9 +127,6 @@ class TodoController < ApplicationController # def update_action self.init - if params["on_project_page"] == true - @on_page = "project" - end @item = check_user_return_item @original_item_context_id = @item.context_id @item.attributes = params["item"] @@ -180,38 +174,61 @@ class TodoController < ApplicationController end end - # Delete a next action - # - def destroy_action - self.init + def destroy @item = check_user_return_item context_id = @item.context_id - + project_id = @item.project_id @saved = @item.destroy - @on_page = "home" - @remaining_undone_in_context = Todo.count(:conditions => ['user_id = ? and context_id = ? and type = ? and done = ?', @user.id, context_id, "Immediate", false]) - if @saved - self.init - @down_count = @todos.reject { |x| x.done? or x.context.hide? }.size.to_s - end - return if request.xhr? + respond_to do |wants| + + wants.html do + if @saved + flash["notice"] = 'Successfully deleted next action' + redirect_to :action => 'index' + else + flash["warning"] = 'Failed to delete the action.' + redirect_to :action => 'index' + end + end + + wants.js do + if @saved + @down_count = 0 + source_view do |from| + from.todo do + @down_count = Todo.count(:conditions => ['todos.user_id = ? and todos.type = ? and todos.done = ? and contexts.hide = ?', + @user.id, "Immediate", false, false], + :include => [ :context ]) + @remaining_undone_in_context = Todo.count(:conditions => ['user_id = ? and context_id = ? and type = ? and done = ?', + @user.id, context_id, "Immediate", false]) + end + from.context do + @down_count = Todo.count(:conditions => ['todos.user_id = ? and todos.type = ? and todos.done = ? and todos.context_id = ?', + @user.id, "Immediate", false, context_id]) + end + from.project do + @down_count = Todo.count(:conditions => ['todos.user_id = ? and todos.type = ? and todos.done = ? and todos.project_id = ?', + @user.id, "Immediate", false, project_id]) unless project_id == nil + end + end + end + render + end + + wants.xml { render :text => '200 OK. Action deleted.', :status => 200 } - # fallback for standard requests - if @saved - flash["notice"] = 'Successfully deleted next action' - redirect_to :action => 'index' - else - render :action => 'index' end rescue - if request.xhr? # be sure to include an error.rjs - render :action => 'error' - else - flash["warning"] = 'An error occurred on the server.' - render :action => 'index' - end + respond_to do |wants| + wants.html do + flash["warning"] = 'An error occurred on the server.' + redirect_to :action => 'index' + end + wants.js { render :action => 'error' } + wants.xml { render :text => 'An error occurred on the server.' + $! } + end end # List the completed tasks, sorted by completion date @@ -250,12 +267,20 @@ class TodoController < ApplicationController if @user == item.user return item else - flash["warning"] = "Item and session user mis-match: #{item.user.name} and #{@user.name}!" - render_text "" + @error_message = 'Item and session user mis-match: #{item.user.name} and #{@user.name}!' + respond_to do |wants| + wants.html do + flash["warning"] = @error_message + render :action => "index" + end + wants.js { render :action => 'error' } + wants.xml { render :text => @error_message, :status => 403 } + end end end def init + @source_view = params['_source_view'] || 'todo' @projects = @user.projects @contexts = @user.contexts init_todos diff --git a/tracks/app/helpers/todo_helper.rb b/tracks/app/helpers/todo_helper.rb index 6bc0dba3..a5cbc815 100644 --- a/tracks/app/helpers/todo_helper.rb +++ b/tracks/app/helpers/todo_helper.rb @@ -15,19 +15,19 @@ module TodoHelper ) end - def link_to_remote_todo( item, handled_by, type) - (type == "deferred") ? destroy_act = 'destroy' : destroy_act = 'destroy_action' + def link_to_remote_todo( item, options = {}) + (options[:type] == "deferred") ? controller_name = 'deferred' : controller_name = 'todo' + url_options = { :controller => controller_name, :action => 'destroy', :id => item.id, :_source_view => @source_view } str = link_to_remote( image_tag("blank", :title =>"Delete action", :class=>"delete_item"), - {:url => { :controller => handled_by, :action => destroy_act, :id => item.id }, - :confirm => "Are you sure that you want to delete the action, \'#{item.description}\'?"}, - {:class => "icon"}) + "\n" + { :url => url_options, :confirm => "Are you sure that you want to delete the action, \'#{item.description}\'?" }, + { :class => "icon" } + ) + "\n" if !item.done? - (type == "deferred") ? edit_act = 'edit' : edit_act = 'edit_action' str << link_to_remote( image_tag("blank", :title =>"Edit action", :class=>"edit_item", :id=>"action-#{item.id}-edit-icon"), { :update => "form-action-#{item.id}", :loading => visual_effect(:pulsate, "action-#{item.id}-edit-icon"), - :url => { :controller => handled_by, :action => edit_act, :id => item.id }, + :url => { :controller => 'todo', :action => 'edit', :id => item.id, :_source_view => @source_view }, :success => "Element.toggle('item-#{item.id}','action-#{item.id}-edit-form'); new Effect.Appear('action-#{item.id}-edit-form', { duration: .2 }); Form.focusFirstElement('form-action-#{item.id}')" }, { diff --git a/tracks/app/views/context/_show_items.rhtml b/tracks/app/views/context/_show_items.rhtml index ec8f6485..01ab892f 100644 --- a/tracks/app/views/context/_show_items.rhtml +++ b/tracks/app/views/context/_show_items.rhtml @@ -16,7 +16,7 @@ link_to_remote( image_tag("blank", :title =>"Delete this action", :class=>"delete_item"), :update => "item-#{item.id}-container", :loading => visual_effect(:fade, "item-#{item.id}-container"), - :url => { :controller => "todo", :action => "destroy_action", :id => item.id }, :confirm => "Are you sure that you want to delete the action \'#{item.description}\'?" ) + " " + + :url => { :controller => "todo", :action => "destroy", :id => item.id }, :confirm => "Are you sure that you want to delete the action \'#{item.description}\'?" ) + " " + link_to_function(image_tag( "blank", :title => "Edit item", :class=>"edit_item"), "Element.toggle('item-#{item.id}','action-#{item.id}-edit-form'); new Effect.Appear('action-#{item.id}-edit-form'); Form.focusFirstElement('form-action-#{item.id}');" ) + " " %> @@ -58,7 +58,7 @@ <% else %>
| diff --git a/tracks/app/views/todo/error.rjs b/tracks/app/views/todo/error.rjs index 9a5a0dcc..ba0e53d1 100644 --- a/tracks/app/views/todo/error.rjs +++ b/tracks/app/views/todo/error.rjs @@ -1 +1 @@ -page["status"].replace_html "An error occurred on the server." \ No newline at end of file +page["status"].replace_html @error_message || "An error occurred on the server." \ No newline at end of file diff --git a/tracks/lib/source_view.rb b/tracks/lib/source_view.rb new file mode 100644 index 00000000..aa0f6acd --- /dev/null +++ b/tracks/lib/source_view.rb @@ -0,0 +1,48 @@ +# Inspiration from Bruce Williams [http://codefluency.com/articles/2006/07/01/rails-views-getting-in-context/] +module Tracks + + module SourceViewSwitching + + class Responder + + def initialize(source_view) + @source_view = source_view.underscore.gsub(/\s+/,'_').to_sym rescue nil + end + + def nil? + yield if @source_view.nil? && block_given? + end + + def method_missing(check_source_view,*args) + yield if check_source_view == @source_view && block_given? + end + + end + + module Controller + + def self.included(base) + base.send(:helper, Tracks::SourceViewSwitching::Helper) + base.send(:helper_method, :source_view) + end + + def source_view + responder = Tracks::SourceViewSwitching::Responder.new(params[:_source_view]) + block_given? ? yield(responder) : responder + end + + end + + module Helper + + def source_view_tag(name) + hidden_field_tag :_source_view, name.underscore.gsub(/\s+/,'_') + end + + end + + end + +end + +ActionController::Base.send(:include, Tracks::SourceViewSwitching::Controller) \ No newline at end of file diff --git a/tracks/test/functional/login_controller_test.rb b/tracks/test/functional/login_controller_test.rb index 4d046752..6100b81a 100644 --- a/tracks/test/functional/login_controller_test.rb +++ b/tracks/test/functional/login_controller_test.rb @@ -42,9 +42,9 @@ class LoginControllerTest < Test::Unit::TestCase user = login('jane','sesame', 'off') assert_equal user.id, @response.session['user_id'] assert_equal user.login, "jane" - assert !user.is_admin + assert user.is_admin == false || user.is_admin == 0 assert_equal "Login successful: session will expire after 1 hour of inactivity.", flash['notice'] - assert_redirected_to :controller => 'todo', :action => 'list' + assert_redirected_to :controller => 'todo', :action => 'index' end def test_logout @@ -82,16 +82,16 @@ class LoginControllerTest < Test::Unit::TestCase assert admin.is_admin newbie = create('newbie', 'newbiepass') assert_equal "Signup successful for user newbie.", flash['notice'] - assert_redirected_to :controller => 'todo', :action => 'list' + assert_redirected_to :controller => 'todo', :action => 'index' assert_valid newbie get :logout # logout the admin user assert_equal newbie.login, "newbie" - assert !newbie.is_admin + assert newbie.is_admin == false || newbie.is_admin == 0 assert_not_nil newbie.preferences # have user preferences been created? user = login('newbie', 'newbiepass', 'on') # log in the new user - assert_redirected_to :controller => 'todo', :action => 'list' + assert_redirected_to :controller => 'todo', :action => 'index' assert_equal 'newbie', user.login - assert !user.is_admin + assert user.is_admin == false || user.is_admin == 0 num_users = User.find(:all) assert_equal num_users.length, 3 end @@ -100,7 +100,7 @@ class LoginControllerTest < Test::Unit::TestCase # def test_create_by_non_admin non_admin = login('jane', 'sesame', 'on') - assert !non_admin.is_admin + assert non_admin.is_admin == false || non_admin.is_admin == 0 post :signup, :user => {:login => 'newbie2', :password => 'newbiepass2', :password_confirmation => 'newbiepass2'} assert_template 'login/nosignup' diff --git a/tracks/test/integration/stories_test.rb b/tracks/test/integration/stories_test.rb index 1f86c17c..95df9c7e 100644 --- a/tracks/test/integration/stories_test.rb +++ b/tracks/test/integration/stories_test.rb @@ -37,7 +37,7 @@ class StoriesTest < ActionController::IntegrationTest assert_response :redirect follow_redirect! assert_response :success - assert_template "todo/list" + assert_template "todo/index" end def goes_to_login @@ -63,7 +63,7 @@ class StoriesTest < ActionController::IntegrationTest assert_response :redirect follow_redirect! assert_response :success - assert_template "todo/list" + assert_template "todo/index" end end diff --git a/tracks/test/unit/context_test.rb b/tracks/test/unit/context_test.rb index 275ef18b..56828a93 100644 --- a/tracks/test/unit/context_test.rb +++ b/tracks/test/unit/context_test.rb @@ -25,6 +25,7 @@ class ContextTest < Test::Unit::TestCase def test_validate_name_is_unique newcontext = Context.new newcontext.name = contexts(:agenda).name + newcontext.user_id = contexts(:agenda).user_id assert !newcontext.save assert_equal 1, newcontext.errors.count assert_equal "already exists", newcontext.errors.on(:name) diff --git a/tracks/test/unit/project_test.rb b/tracks/test/unit/project_test.rb index e7eb8578..7d07c449 100644 --- a/tracks/test/unit/project_test.rb +++ b/tracks/test/unit/project_test.rb @@ -24,7 +24,8 @@ class ProjectTest < Test::Unit::TestCase def test_validate_name_is_unique newproj = Project.new - newproj.name = "Build a working time machine" + newproj.name = projects(:timemachine).name + newproj.user_id = projects(:timemachine).user_id assert !newproj.save assert_equal 1, newproj.errors.count assert_equal "already exists", newproj.errors.on(:name) diff --git a/tracks/test/unit/todo_test.rb b/tracks/test/unit/todo_test.rb index 86c0633b..de2cc04a 100644 --- a/tracks/test/unit/todo_test.rb +++ b/tracks/test/unit/todo_test.rb @@ -18,7 +18,7 @@ class TodoTest < Test::Unit::TestCase assert_equal 2, @not_completed1.project_id assert_equal "Call Bill Gates to find out how much he makes per day", @not_completed1.description assert_nil @not_completed1.notes - assert !@not_completed1.done + assert @not_completed1.done == false || @not_completed1.done == 0 assert_equal 1.week.ago.strftime("%Y-%m-%d %H:%M"), @not_completed1.created_at.strftime("%Y-%m-%d %H:%M") assert_equal 2.week.from_now.strftime("%Y-%m-%d"), @not_completed1.due.strftime("%Y-%m-%d") assert_nil @not_completed1.completed diff --git a/tracks/test/unit/user_test.rb b/tracks/test/unit/user_test.rb index 546696e4..560a17df 100644 --- a/tracks/test/unit/user_test.rb +++ b/tracks/test/unit/user_test.rb @@ -28,7 +28,7 @@ class UserTest < Test::Unit::TestCase assert_equal "jane", @other_user.login assert_equal "#{Digest::SHA1.hexdigest("#{SALT}--sesame--")}", @other_user.password assert_not_nil @other_user.word - assert !@other_user.is_admin + assert @other_user.is_admin == false || @other_user.is_admin == 0 end # ============================================ |