class TodoController < ApplicationController model :user model :project model :context helper :todo prepend_before_filter :login_required layout "standard" def index list render_action "list" end # Main method for listing tasks # Set page title, and fill variables with contexts and done and not-done tasks # Number of completed actions to show is determined by a setting in settings.yml # def list self.init @on_page = "home" @page_title = "TRACKS::List tasks" # If you've set no_completed to zero, the completed items box # isn't shown on the home page max_completed = @user.preferences["no_completed"].to_i-1 @done = (max_completed > 0) ? @done[0..max_completed] : nil @contexts_to_show = @contexts.reject {|x| x.hide? } if @contexts.empty? flash['warning'] = 'You must add at least one context before adding next actions.' end # Set count badge to number of not-done, not hidden context items @count = @todos.reject { |x| x.done? || x.context.hide? }.size respond_to do |wants| wants.html wants.xml { render :action => 'list.rxml', :layout => false } end end # Is this used? Seems like it should be deleted. -lukemelia, 2006-07-16 def update_element end # Called by a form button # Parameters from form fields are passed to create new action # in the selected context. def add_item self.init @item = @user.todos.build @item.attributes = params["todo"] @on_page = "home" perform_add_item('list') end # Adding deferred actions from form on todo/tickler # def add_deferred_item self.init @item = Deferred.create(params["todo"]) @item.user_id = @user.id @on_page = "tickler" perform_add_item('tickler') end def edit_action self.init @item = check_user_return_item render :layout => false end def show self.init item = check_user_return_item respond_to do |wants| wants.xml { render :xml => item.to_xml( :root => 'todo', :except => :user_id ) } end end # Toggles the 'done' status of the action # def toggle_check self.init @item = check_user_return_item @item.toggle!('done') @item.completed = Time.now() # For some reason, the before_save in todo.rb stopped working @saved = @item.save @on_page = "home" if @saved @down_count = @todos.collect { |x| ( !x.done? and !x.context.hide? ) ? x:nil }.compact.size.to_s end return if request.xhr? if @saved flash['notice'] = "The action '#{@item.description}' was marked as #{@item.done? ? 'complete' : 'incomplete' }" else flash['notice'] = "The action '#{@item.description}' was NOT marked as #{@item.done? ? 'complete' : 'incomplete' } due to an error on the server." end redirect_to :action => "list" end # Edit the details of an action # 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"] if @item.due? @item.due = Date.strptime(params["item"]["due"], @user.preferences["date_format"]) else @item.due = "" end @saved = @item.save end def deferred_update_action #self.init @tickle = check_user_return_item @original_item_context_id = @tickle.context_id @tickle.attributes = params["item"] if @tickle.due? @tickle.due = Date.strptime(params["item"]["due"], @user.preferences["date_format"]) else @tickle.due = "" end @saved = @tickle.save end def update_context self.init @item = check_user_return_item context = Context.find(params['context_id']); if @user == context.user @original_item_context_id = @item.context_id @item.context_id = context.id @item.context = context @saved = @item.save render :action => 'update_action' else render :update do |page| page.replace_html "info", content_tag("div", "Error updating the context of the dragged item. Item and context user mis-match: #{@item.user.name} and #{@context.user.name}! - refresh the page to see them.", "class" => "warning") end end end def update_project self.init @item = check_user_return_item project = Project.find(params['project_id']); if @user == project.user @original_item_context_id = @item.context_id @item.project_id = project.id @item.project = project @saved = @item.save render :action => 'update_action' else render :update do |page| page.replace_html "info", content_tag("div", "Error updating the project of the dragged item. Item and project user mis-match: #{@item.user.name} and #{@project.user.name}! - refresh the page to see them.", "class" => "warning") end end end # Delete a next action # def destroy_action self.init @item = check_user_return_item @saved = @item.destroy @on_page = "home" if @saved self.init @down_count = @todos.reject { |x| x.done? or x.context.hide? }.size.to_s end return if request.xhr? # fallback for standard requests if @saved flash["notice"] = 'Successfully deleted next action' redirect_to :action => 'list' else render :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 :action => 'list' end end # List the completed tasks, sorted by completion date # @done_today: in the last 24 hours # @done_this_week: in the last week # @done_this_month: in the last 4 weeks (<=28 days) def completed self.init @page_title = "TRACKS::Completed tasks" unless @done.nil? @done_today = @done.collect { |x| x.completed >= 1.day.ago ? x:nil }.compact @done_this_week = @done.collect { |x| 1.week.ago <= x.completed ? x:nil }.compact @done_this_month = @done.collect { |x| 4.week.ago <= x.completed ? x:nil }.compact end end # Archived completed items, older than 28 days # def completed_archive self.init @page_title = "TRACKS::Archived completed tasks" @done_archive = @done.collect { |x| 28.day.ago > x.completed ? x:nil }.compact end def feeds self.init @page_title = "TRACKS::Feeds" end def tickler self.init @page_title = "TRACKS::Tickler" @tickles = @user.todos.find(:all, :conditions => ['type = ?', "Deferred"], :order => "show_from ASC") @count = @tickles.size @on_page = "tickler" end # Called by periodically_call_remote # Check for any due tickler items, change them to type Immediate and show # on the page # def check_tickler self.init now = Date.today() @due_tickles = @user.todos.find(:all, :conditions => ['type = ? AND (show_from < ? OR show_from = ?)', "Deferred", now, now ], :order => "show_from ASC") unless @due_tickles.empty? # Change the due tickles to type "Immediate" @due_tickles.each do |t| t[:type] = "Immediate" t.show_from = nil t.save end end end protected def check_user_return_item item = Todo.find( params['id'] ) if @user == item.user return item else flash["warning"] = "Item and session user mis-match: #{item.user.name} and #{@user.name}!" render_text "" end end def init @projects = @user.projects @contexts = @user.contexts init_todos end def init_todos @todos = Todo.find(:all, :conditions => ['user_id = ? and type = ?', @user.id, "Immediate"]) @done = Todo.find(:all, :conditions => ['user_id = ? and done = ?', @user.id, true], :order => 'completed DESC') end def perform_add_item(redirect_action) if @item.due? @item.due = Date.strptime(params["todo"]["due"], @user.preferences["date_format"]) else @item.due = "" end @saved = @item.save if @saved init_todos @up_count = @todos.reject { |x| x.done? or x.context.hide? }.size.to_s end respond_to do |wants| wants.html { redirect_to :action => redirect_action } wants.js wants.xml { render :xml => @item.to_xml( :root => 'todo', :except => :user_id ) } end # if you're seeing the message 'An error occurred on the server.' and you want to debug, comment out the rescue section and check the Ajax response for an exception message rescue respond_to do |wants| wants.html { render :action => redirect_action } # TODO: would prefer something like: flash["warning"] = 'An error occurred on the server.' render :action => 'list' wants.js { render :action => 'error' } wants.xml { render :text => 'An error occurred on the server.' + $! } end end end