mirror of
https://github.com/TracksApp/tracks.git
synced 2026-03-09 14:12:37 +01:00
* Converted Todo to acts_as_state_machine. It's states are active, deferred, completed, and project_hidden. This replaces the old single inheritance model of Immediate and Deferred. Also renamed todo.completed to todo.completed_at for clarity
* Consolidated toggle_check handling to todo_controller and rjs * Introduced user preference to show/hide hidden projects section in sidebar * Fixed a bug in parse_date_per_user_prefs that was causing due dates to be set in the todo model as Times and not Dates * Upgraded ARTS plugin * This changeset includes migrations, so remember to db:migrate. * Lots of code changes here, so bug reports will be gratefully accepted! git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@343 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
parent
883bcb30bb
commit
c51587e422
47 changed files with 487 additions and 301 deletions
|
|
@ -83,23 +83,28 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
def parse_date_per_user_prefs( s )
|
||||
return nil if s == ''
|
||||
Chronic.parse(s)
|
||||
Chronic.parse(s).to_date
|
||||
end
|
||||
|
||||
def init_data_for_sidebar
|
||||
@projects = @user.projects
|
||||
@contexts = @user.contexts
|
||||
init_not_done_counts
|
||||
if @prefs.show_hidden_projects_in_sidebar
|
||||
init_project_hidden_todo_counts(['project'])
|
||||
end
|
||||
end
|
||||
|
||||
def init_not_done_counts(parents = ['project','context'])
|
||||
parents.each do |parent|
|
||||
eval("@#{parent}_not_done_counts = Todo.count(:all,
|
||||
:conditions => ['todos.user_id = ? and todos.type = ? and todos.done = ? and (projects.state != ? or todos.project_id is ?)',
|
||||
@user.id, \"Immediate\", false, \"hidden\", nil],
|
||||
:joins => 'LEFT JOIN projects on projects.id = todos.project_id',
|
||||
:group => :#{parent}_id)")
|
||||
eval("@#{parent}_not_done_counts = Todo.count(:conditions => ['user_id = ? and state = ?', @user.id, 'active'], :group => :#{parent}_id)")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def init_project_hidden_todo_counts(parents = ['project','context'])
|
||||
parents.each do |parent|
|
||||
eval("@#{parent}_project_hidden_todo_counts = Todo.count(:conditions => ['user_id = ? and state = ?', @user.id, 'project_hidden'], :group => :#{parent}_id)")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -102,29 +102,6 @@ class ContextController < ApplicationController
|
|||
redirect_to :controller => 'todo', :action => 'list'
|
||||
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
|
||||
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
|
||||
@done_count = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = ? and todos.context_id IN (?)", @user.id, true, @item.context_id]).size.to_s
|
||||
end
|
||||
return if request.xhr?
|
||||
|
||||
if @saved
|
||||
flash[:notice] = "The action <strong>'#{@item.description}'</strong> was marked as <strong>#{@item.done? ? 'complete' : 'incomplete' }</strong>"
|
||||
else
|
||||
flash[:notice] = "The action <strong>'#{@item.description}'</strong> was NOT marked as <strong>#{@item.done? ? 'complete' : 'incomplete' } due to an error on the server.</strong>"
|
||||
end
|
||||
redirect_to :action => "list"
|
||||
end
|
||||
|
||||
# Edit the details of the context
|
||||
#
|
||||
|
|
@ -210,11 +187,9 @@ class ContextController < ApplicationController
|
|||
# If we exclude completed projects, then we can't display them in the sidebar
|
||||
# if the user sets the preference for them to be shown
|
||||
# @projects = @user.projects.reject { |x| x.completed? }
|
||||
@projects = @user.projects
|
||||
@contexts = @user.contexts
|
||||
init_data_for_sidebar
|
||||
@todos = @user.todos
|
||||
@done = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = ?", @user.id, true], :include => [:project], :order => "completed DESC")
|
||||
init_not_done_counts
|
||||
@done = @user.todos.find_in_state(:all, :completed, :order => "todos.completed_at DESC")
|
||||
end
|
||||
|
||||
def init_todos
|
||||
|
|
@ -224,10 +199,7 @@ class ContextController < ApplicationController
|
|||
# TODO: Temporarily doing this search manually until I can work out a way
|
||||
# to do the same thing using not_done_todos acts_as_todo_container method
|
||||
# Hides actions in hidden projects from context.
|
||||
@not_done_todos = Todo.find(:all,
|
||||
:conditions => ["todos.context_id = ? and todos.done = ? and todos.type = ? and (projects.state != ? or todos.project_id is ?)", @context.id, false, "Immediate", "hidden", nil],
|
||||
:order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC",
|
||||
:include => [:project])
|
||||
@not_done_todos = @context.todos.find_in_state(:all, :active, :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC")
|
||||
@count = @not_done_todos.size
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -12,16 +12,16 @@ class DeferredController < ApplicationController
|
|||
|
||||
def index
|
||||
@source_view = 'deferred'
|
||||
init_projects_and_contexts
|
||||
init_not_done_counts
|
||||
init_data_for_sidebar
|
||||
@page_title = "TRACKS::Tickler"
|
||||
@tickles = @user.todos.find(:all, :conditions => ['type = ?', "Deferred"], :order => "show_from ASC")
|
||||
@tickles = @user.todos.find_in_state(:all, :deferred, :order => "show_from ASC")
|
||||
@count = @tickles.size
|
||||
end
|
||||
|
||||
def create
|
||||
@source_view = 'deferred'
|
||||
@item = Deferred.new
|
||||
@item = Todo.new
|
||||
@item.defer!
|
||||
@item.attributes = params["todo"]
|
||||
if params["todo"]["show_from"]
|
||||
@item.show_from = parse_date_per_user_prefs(params["todo"]["show_from"])
|
||||
|
|
@ -37,7 +37,7 @@ class DeferredController < ApplicationController
|
|||
@saved = @item.save
|
||||
|
||||
if @saved
|
||||
@up_count = @user.todos.count(['type = ?', "Deferred"])
|
||||
@up_count = @user.todos.count_in_state(:deferred)
|
||||
end
|
||||
|
||||
respond_to do |wants|
|
||||
|
|
@ -84,7 +84,7 @@ class DeferredController < ApplicationController
|
|||
redirect_to :action => "index"
|
||||
end
|
||||
wants.js do
|
||||
@down_count = @user.todos.count(['type = ?', "Deferred"]) if @saved
|
||||
@down_count = @user.todos.count_in_state(:deferred) if @saved
|
||||
render
|
||||
end
|
||||
wants.xml { render :xml => @item.to_xml( :root => 'todo', :except => :user_id ) }
|
||||
|
|
@ -101,30 +101,22 @@ class DeferredController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
# Check for any due tickler items, change them to type Immediate.
|
||||
# Check for any due tickler items, activate them
|
||||
# Called by periodically_call_remote
|
||||
def check_tickler
|
||||
now = Date.today()
|
||||
@due_tickles = @user.todos.find(:all, :conditions => ['type = ? AND (show_from < ? OR show_from = ?)', "Deferred", now, now ], :order => "show_from ASC")
|
||||
# Change the due tickles to type "Immediate"
|
||||
@due_tickles = @user.todos.find_in_state(:all, :deferred, :conditions => ['show_from < ? OR show_from = ?', now, now ], :order => "show_from ASC")
|
||||
# Change the due tickles to active
|
||||
@due_tickles.each do |t|
|
||||
t[:type] = "Immediate"
|
||||
t.show_from = nil
|
||||
t.save_with_validation(false)
|
||||
t.activate!
|
||||
t.save
|
||||
end
|
||||
respond_to do |wants|
|
||||
wants.html { redirect_to :controller => 'todo', :action => 'index' }
|
||||
wants.js
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def init_projects_and_contexts
|
||||
@projects = @user.projects
|
||||
@contexts = @user.contexts
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
def check_user_return_item
|
||||
|
|
|
|||
|
|
@ -84,9 +84,9 @@ protected
|
|||
options = Hash.new
|
||||
|
||||
if params.key?('done')
|
||||
condition_builder.add 'todos.done = ?', true
|
||||
condition_builder.add 'todos.state = ?', 'completed'
|
||||
else
|
||||
condition_builder.add 'todos.done = ?', false
|
||||
condition_builder.add 'todos.state = ?', 'active'
|
||||
end
|
||||
|
||||
if params.key?('limit')
|
||||
|
|
@ -107,7 +107,7 @@ protected
|
|||
|
||||
if params.key?('done')
|
||||
done_in_last = params['done'].to_i
|
||||
condition_builder.add('todos.completed >= ?', done_in_last.days.ago)
|
||||
condition_builder.add('todos.completed_at >= ?', done_in_last.days.ago)
|
||||
@title << " actions completed"
|
||||
@description << " in the last #{done_in_last.to_s} days"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ class MobileController < ApplicationController
|
|||
self.init
|
||||
@page_title = @desc = "All actions"
|
||||
@todos_pages, @todos = paginate( :todos, :order => 'due IS NULL, due ASC, created_at ASC',
|
||||
:conditions => ['user_id = ? and type = ? and done = ?', @user.id, "Immediate", false],
|
||||
:conditions => ['user_id = ? and state = ?', @user.id, "active"],
|
||||
:per_page => 6 )
|
||||
@count = @all_todos.reject { |x| x.done? || x.context.hide? }.size
|
||||
@count = @all_todos.reject { |x| !x.active? || x.context.hide? }.size
|
||||
end
|
||||
|
||||
def detail
|
||||
|
|
@ -32,10 +32,11 @@ class MobileController < ApplicationController
|
|||
@item = check_user_return_item
|
||||
else
|
||||
if params[:item][:"show_from(1i)"] == ""
|
||||
@item = Immediate.create(params[:item]) if params[:item]
|
||||
@item = Todo.create(params[:item]) if params[:item]
|
||||
else
|
||||
@item = Deferred.create(params[:item]) if params[:item]
|
||||
end
|
||||
@item = Todo.create(params[:item]) if params[:item]
|
||||
@item.defer!
|
||||
end
|
||||
end
|
||||
|
||||
@item.user_id = @user.id
|
||||
|
|
@ -64,14 +65,14 @@ class MobileController < ApplicationController
|
|||
@context = Context.find( params[:context][:id] )
|
||||
@page_title = @desc = "#{@context.name}"
|
||||
@todos_pages, @todos = paginate( :todos, :order => 'due IS NULL, due ASC, created_at ASC',
|
||||
:conditions => ['user_id = ? and type = ? and done = ? and context_id = ?', @user.id, "Immediate", false, @context.id], :per_page => 6 )
|
||||
@count = @all_todos.reject { |x| x.done? || x.context_id != @context.id }.size
|
||||
:conditions => ['user_id = ? and state = ? and context_id = ?', @user.id, "active", @context.id], :per_page => 6 )
|
||||
@count = @all_todos.reject { |x| x.completed? || x.context_id != @context.id }.size
|
||||
when 'project'
|
||||
@project = Project.find( params[:project][:id] )
|
||||
@page_title = @desc = "#{@project.name}"
|
||||
@todos_pages, @todos = paginate( :todos, :order => 'due IS NULL, due ASC, created_at ASC',
|
||||
:conditions => ['user_id = ? and type = ? and done = ? and project_id = ?', @user.id, "Immediate", false, @project.id], :per_page => 6 )
|
||||
@count = @all_todos.reject { |x| x.done? || x.project_id != @project.id }.size
|
||||
:conditions => ['user_id = ? and state = ? and project_id = ?', @user.id, "active", @project.id], :per_page => 6 )
|
||||
@count = @all_todos.reject { |x| x.completed? || x.project_id != @project.id }.size
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -88,11 +89,9 @@ class MobileController < ApplicationController
|
|||
end
|
||||
|
||||
def init
|
||||
@contexts = Context.find :all, :order => 'position ASC',
|
||||
:conditions => ['user_id = ?', @user.id]
|
||||
@projects = Project.find :all, :order => 'position ASC',
|
||||
:conditions => ['user_id = ? and state = ?', @user.id, "active"]
|
||||
@all_todos = Todo.find(:all, :conditions => ['user_id = ? and type = ?', @user.id, "Immediate"])
|
||||
@contexts = @user.contexts.find(:all, :order => 'position ASC')
|
||||
@projects = @user.projects.find_in_state(:all, :active, :order => 'position ASC')
|
||||
@all_todos = @user.todos.find(:all, :conditions => ['state = ? or state =?', "active", "completed"])
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ class ProjectController < ApplicationController
|
|||
#
|
||||
def list
|
||||
init
|
||||
init_project_hidden_todo_counts
|
||||
@page_title = "TRACKS::List Projects"
|
||||
respond_to do |wants|
|
||||
wants.html
|
||||
|
|
@ -125,38 +126,27 @@ class ProjectController < ApplicationController
|
|||
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
|
||||
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
|
||||
end
|
||||
return if request.xhr?
|
||||
|
||||
if @saved
|
||||
flash[:notice] = "The action <strong>'#{@item.description}'</strong> was marked as <strong>#{@item.done? ? 'complete' : 'incomplete' }</strong>"
|
||||
else
|
||||
flash[:notice] = "The action <strong>'#{@item.description}'</strong> was NOT marked as <strong>#{@item.done? ? 'complete' : 'incomplete' } due to an error on the server.</strong>"
|
||||
end
|
||||
redirect_to :action => "list"
|
||||
end
|
||||
|
||||
# Edit the details of the project
|
||||
#
|
||||
def update
|
||||
self.init
|
||||
check_user_set_project
|
||||
@project.transition_to(params['project']['state'])
|
||||
params['project'].delete('state')
|
||||
@project.attributes = params['project']
|
||||
@project.name = deurlize(@project.name)
|
||||
if @project.save
|
||||
render :partial => 'project_listing', :object => @project
|
||||
if params['wants_render']
|
||||
if (@project.hidden?)
|
||||
@project_project_hidden_todo_counts = Hash.new
|
||||
@project_project_hidden_todo_counts[@project.id] = @project.reload().not_done_todo_count(:include_project_hidden_todos => true)
|
||||
else
|
||||
@project_not_done_counts[@project.id] = @project.reload().not_done_todo_count(:include_project_hidden_todos => true)
|
||||
end
|
||||
render :partial => 'project_listing', :object => @project
|
||||
else
|
||||
render :text => 'Success'
|
||||
end
|
||||
else
|
||||
flash[:warning] = "Couldn't update project"
|
||||
render :text => ''
|
||||
|
|
@ -242,14 +232,14 @@ class ProjectController < ApplicationController
|
|||
@projects = @user.projects
|
||||
@contexts = @user.contexts
|
||||
@todos = @user.todos
|
||||
@done = Todo.find(:all, :conditions => ["todos.user_id = ? and todos.done = ?", @user.id, true], :include => [:project], :order => "completed DESC")
|
||||
init_not_done_counts
|
||||
@done = @user.todos.find_in_state(:all, :completed, :order => "completed_at DESC")
|
||||
init_data_for_sidebar
|
||||
end
|
||||
|
||||
def init_todos
|
||||
check_user_set_project
|
||||
@done = @project.done_todos
|
||||
@not_done = @project.not_done_todos
|
||||
@not_done = @project.not_done_todos(:include_project_hidden_todos => true)
|
||||
@count = @not_done.size
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ class TodoController < ApplicationController
|
|||
@done = nil
|
||||
if max_completed > 0
|
||||
@done = Todo.find(:all,
|
||||
:conditions => ['todos.user_id = ? and todos.done = ?', @user.id, true],
|
||||
:order => 'todos.completed DESC',
|
||||
:conditions => ['todos.user_id = ? and todos.state = ?', @user.id, 'completed'],
|
||||
:order => 'todos.completed_at DESC',
|
||||
:limit => max_completed,
|
||||
:include => [ :project, :context ])
|
||||
end
|
||||
|
|
@ -39,7 +39,7 @@ class TodoController < ApplicationController
|
|||
end
|
||||
|
||||
# Set count badge to number of not-done, not hidden context items
|
||||
@count = @todos.reject { |x| x.done? || x.context.hide? }.size
|
||||
@count = @todos.reject { |x| !x.active? || x.context.hide? }.size
|
||||
|
||||
respond_to do |wants|
|
||||
wants.html
|
||||
|
|
@ -79,7 +79,7 @@ class TodoController < ApplicationController
|
|||
wants.js do
|
||||
if @saved
|
||||
init_todos
|
||||
@up_count = @todos.reject { |x| x.done? or x.context.hide? }.size.to_s
|
||||
@up_count = @todos.reject { |x| !x.active? or x.context.hide? }.size.to_s
|
||||
end
|
||||
render :action => 'create'
|
||||
end
|
||||
|
|
@ -119,21 +119,20 @@ class TodoController < ApplicationController
|
|||
#
|
||||
def toggle_check
|
||||
init
|
||||
|
||||
logger.info "source view is " + @source_view
|
||||
@item = check_user_return_item
|
||||
@item.toggle!('done')
|
||||
@item.completed = Time.now() # For some reason, the before_save in todo.rb stopped working
|
||||
@item.toggle_completion()
|
||||
@saved = @item.save
|
||||
@remaining_undone_in_context = @user.contexts.find(@item.context_id).not_done_todos.length
|
||||
if @saved
|
||||
@down_count = @todos.reject { |x| x.done? || x.context.hide? }.size.to_s
|
||||
@remaining_undone_in_context = @user.contexts.find(@item.context_id).not_done_todo_count
|
||||
determine_down_count
|
||||
end
|
||||
return if request.xhr?
|
||||
|
||||
if @saved
|
||||
redirect_with_notice "The action <strong>'#{@item.description}'</strong> was marked as <strong>#{@item.done? ? 'complete' : 'incomplete' }</strong>", :action => "index"
|
||||
redirect_with_notice "The action <strong>'#{@item.description}'</strong> was marked as <strong>#{@item.completed? ? 'complete' : 'incomplete' }</strong>", :action => "index"
|
||||
else
|
||||
redirect_with_notice "The action <strong>'#{@item.description}'</strong> was NOT marked as <strong>#{@item.done? ? 'complete' : 'incomplete' } due to an error on the server.</strong>", :action => "index"
|
||||
redirect_with_notice "The action <strong>'#{@item.description}'</strong> was NOT marked as <strong>#{@item.completed? ? 'complete' : 'incomplete' } due to an error on the server.</strong>", :action => "index"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -207,7 +206,7 @@ class TodoController < ApplicationController
|
|||
|
||||
wants.js do
|
||||
if @saved
|
||||
@down_count = determine_down_count
|
||||
determine_down_count
|
||||
source_view do |from|
|
||||
from.todo do
|
||||
@remaining_undone_in_context = @user.contexts.find(@context_id).not_done_todos.length
|
||||
|
|
@ -249,7 +248,7 @@ class TodoController < ApplicationController
|
|||
private
|
||||
|
||||
def check_user_return_item
|
||||
item = Todo.find( params['id'] )
|
||||
item = Todo.find( params['id'].to_i )
|
||||
if @user == item.user
|
||||
return item
|
||||
else
|
||||
|
|
@ -267,39 +266,30 @@ class TodoController < ApplicationController
|
|||
|
||||
def init
|
||||
@source_view = params['_source_view'] || 'todo'
|
||||
@projects = @user.projects
|
||||
@contexts = @user.contexts
|
||||
init_todos
|
||||
init_not_done_counts
|
||||
init_data_for_sidebar
|
||||
init_todos
|
||||
end
|
||||
|
||||
def init_todos
|
||||
# Exclude hidden projects from count on home page
|
||||
@todos = Todo.find(:all,
|
||||
:conditions => ['todos.user_id = ? and todos.type = ? and (projects.state != ? or todos.project_id is ?)', @user.id, "Immediate", "hidden", nil],
|
||||
:include => [ :project, :context ])
|
||||
@todos = @user.todos.find(:all, :conditions => ['todos.state = ? or todos.state = ?', 'active', 'complete'], :include => [ :project, :context ])
|
||||
|
||||
# Exclude hidden projects from the home page
|
||||
@not_done_todos = Todo.find(:all,
|
||||
:conditions => ['todos.user_id = ? and todos.type = ? and todos.done = ? and (projects.state != ? or todos.project_id is ?)', @user.id, "Immediate", false, "hidden", nil],
|
||||
:order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC",
|
||||
:include => [ :project, :context ])
|
||||
@not_done_todos = @user.todos.find(:all, :conditions => ['todos.state = ?', 'active'], :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", :include => [ :project, :context ])
|
||||
end
|
||||
|
||||
def determine_down_count
|
||||
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 ])
|
||||
@down_count = Todo.count_by_sql(['SELECT COUNT(*) FROM todos, contexts WHERE todos.context_id = contexts.id and todos.user_id = ? and todos.state = ? and contexts.hide = ?', @user.id, 'active', 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])
|
||||
@down_count = @user.contexts.find(@item.context_id).todos.count_in_state(:active)
|
||||
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
|
||||
unless @item.project_id == nil
|
||||
@down_count = @user.projects.find(@item.project_id).todos.count_in_state(:active)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue