mirror of
https://github.com/TracksApp/tracks.git
synced 2025-12-24 11:10:12 +01:00
Move the get_done_today, get_done_this_week, and get_done_this month methods into their own class in lib/tracks and use the new class in the context, project, and todo controllers. This removes the complexity from the application controller, silos it off, and slightly reduces the complexity of the other controllers so that they don't have to duplicate as much code. The tradeoff here is that the code that was moved out into its own class was also duplicated in the todos controller due to a different use case that I didn't see before. This is still an improvement however and so I'm ok with going back and tackling the extra complexity added to TodoController at a later date.
357 lines
12 KiB
Ruby
357 lines
12 KiB
Ruby
class ProjectsController < ApplicationController
|
|
|
|
helper :application, :todos, :notes
|
|
before_filter :set_source_view
|
|
before_filter :set_project_from_params, :only => [:update, :destroy, :show, :edit, :set_reviewed]
|
|
before_filter :default_context_filter, :only => [:create, :update]
|
|
skip_before_filter :login_required, :only => [:index]
|
|
prepend_before_filter :login_or_feed_token_required, :only => [:index]
|
|
|
|
def index
|
|
@source_view = params['_source_view'] || 'project_list'
|
|
if params[:projects_and_actions]
|
|
projects_and_actions
|
|
else
|
|
@contexts = current_user.contexts
|
|
init_not_done_counts(['project'])
|
|
init_project_hidden_todo_counts(['project'])
|
|
if params[:only_active_with_no_next_actions]
|
|
@projects = current_user.projects.active.select { |p| count_undone_todos(p) == 0 }
|
|
else
|
|
@projects = current_user.projects.all
|
|
end
|
|
@new_project = current_user.projects.build
|
|
@active_projects = current_user.projects.active
|
|
@hidden_projects = current_user.projects.hidden
|
|
respond_to do |format|
|
|
format.html do
|
|
@page_title = t('projects.list_projects')
|
|
@count = current_user.projects.count
|
|
@completed_projects = current_user.projects.completed.limit(10)
|
|
@completed_count = current_user.projects.completed.count
|
|
@no_projects = current_user.projects.empty?
|
|
current_user.projects.cache_note_counts
|
|
end
|
|
format.m do
|
|
@completed_projects = current_user.projects.completed
|
|
@down_count = @active_projects.size + @hidden_projects.size + @completed_projects.size
|
|
cookies[:mobile_url]= {:value => request.fullpath, :secure => SITE_CONFIG['secure_cookies']}
|
|
end
|
|
format.xml { render :xml => @projects.to_xml( :except => :user_id ) }
|
|
format.rss do
|
|
@feed_title = I18n.t('models.project.feed_title')
|
|
@feed_description = I18n.t('models.project.feed_description', :username => current_user.display_name)
|
|
end
|
|
format.atom do
|
|
@feed_title = I18n.t('models.project.feed_title')
|
|
@feed_description = I18n.t('models.project.feed_description', :username => current_user.display_name)
|
|
end
|
|
format.text do
|
|
# somehow passing Mime::TEXT using content_type to render does not work
|
|
headers['Content-Type']=Mime::TEXT.to_s
|
|
end
|
|
format.autocomplete do
|
|
projects = current_user.projects.active + current_user.projects.hidden
|
|
render :text => for_autocomplete(projects, params[:term])
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def review
|
|
@source_view = params['_source_view'] || 'review'
|
|
@page_title = t('projects.list_reviews')
|
|
@projects = current_user.projects.all
|
|
@contexts = current_user.contexts.all
|
|
@projects_to_review = current_user.projects.select {|p| p.needs_review?(current_user)}
|
|
@stalled_projects = current_user.projects.select {|p| p.stalled?}
|
|
@blocked_projects = current_user.projects.select {|p| p.blocked?}
|
|
@current_projects = current_user.projects.uncompleted.select {|p| not(p.needs_review?(current_user))}
|
|
|
|
init_not_done_counts(['project'])
|
|
init_project_hidden_todo_counts(['project'])
|
|
current_user.projects.cache_note_counts
|
|
|
|
@page_title = t('projects.list_reviews')
|
|
@count = @projects_to_review.count + @blocked_projects.count + @stalled_projects.count + @current_projects.count
|
|
|
|
@no_projects = current_user.projects.empty?
|
|
@new_project = current_user.projects.build
|
|
end
|
|
|
|
def done
|
|
@source_view = params['_source_view'] || 'project_list'
|
|
@page_title = t('projects.list_completed_projects')
|
|
|
|
page = params[:page] || 1
|
|
projects_per_page = 20
|
|
@projects = current_user.projects.completed.paginate :page => page, :per_page => projects_per_page
|
|
@count = @projects.count
|
|
@total = current_user.projects.completed.count
|
|
@no_projects = @projects.empty?
|
|
|
|
@range_low = (page.to_i-1) * projects_per_page + 1
|
|
@range_high = @range_low + @projects.size - 1
|
|
|
|
init_not_done_counts(['project'])
|
|
end
|
|
|
|
def set_reviewed
|
|
@project.last_reviewed = Time.zone.now
|
|
@project.save
|
|
|
|
case @source_view
|
|
when "project"
|
|
redirect_to :action => 'show'
|
|
when "project_list"
|
|
redirect_to :action => 'index'
|
|
when "review"
|
|
redirect_to :action => 'review'
|
|
else
|
|
redirect_to :action => 'index'
|
|
end
|
|
end
|
|
|
|
def projects_and_actions
|
|
@projects = current_user.projects.active
|
|
respond_to do |format|
|
|
format.text {
|
|
# somehow passing Mime::TEXT using content_type to render does not work
|
|
headers['Content-Type']=Mime::TEXT.to_s
|
|
render :action => 'index_text_projects_and_actions', :layout => false, :content_type => Mime::TEXT
|
|
}
|
|
end
|
|
end
|
|
|
|
def show
|
|
@max_completed = current_user.prefs.show_number_completed
|
|
init_data_for_sidebar unless mobile?
|
|
@page_title = t('projects.page_title', :project => @project.name)
|
|
|
|
@not_done = @project.todos.active_or_hidden.includes(Todo::DEFAULT_INCLUDES)
|
|
@deferred = @project.todos.deferred.includes(Todo::DEFAULT_INCLUDES)
|
|
@pending = @project.todos.pending.includes(Todo::DEFAULT_INCLUDES)
|
|
|
|
@done = {}
|
|
@done = @project.todos.completed.
|
|
reorder("todos.completed_at DESC").
|
|
limit(current_user.prefs.show_number_completed).
|
|
includes(Todo::DEFAULT_INCLUDES) unless current_user.prefs.show_number_completed == 0
|
|
|
|
@count = @not_done.size
|
|
@down_count = @count + @deferred.size + @pending.size
|
|
@next_project = current_user.projects.next_from(@project)
|
|
@previous_project = current_user.projects.previous_from(@project)
|
|
@default_tags = @project.default_tags
|
|
@new_note = current_user.notes.new
|
|
@new_note.project_id = @project.id
|
|
@contexts = current_user.contexts
|
|
respond_to do |format|
|
|
format.html
|
|
format.m do
|
|
if @project.default_context.nil?
|
|
@project_default_context = t('projects.no_default_context')
|
|
else
|
|
@project_default_context = t('projects.default_context', :context => @project.default_context.name)
|
|
end
|
|
cookies[:mobile_url]= {:value => request.fullpath, :secure => SITE_CONFIG['secure_cookies']}
|
|
@mobile_from_project = @project.id
|
|
end
|
|
format.xml do
|
|
render :xml => @project.to_xml(:except => :user_id) { |xml|
|
|
xml.not_done { @not_done.each { |child| child.to_xml(:builder => xml, :skip_instruct => true) } }
|
|
xml.deferred { @deferred.each { |child| child.to_xml(:builder => xml, :skip_instruct => true) } }
|
|
xml.pending { @pending.each { |child| child.to_xml(:builder => xml, :skip_instruct => true) } }
|
|
xml.done { @done.each { |child| child.to_xml(:builder => xml, :skip_instruct => true) } }
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
def create
|
|
if params[:format] == 'application/xml' && params['exception']
|
|
render_failure "Expected post format is valid xml like so: <project><name>project name</name></project>.", 400
|
|
return
|
|
end
|
|
@project = current_user.projects.build(params['project'])
|
|
@go_to_project = params['go_to_project']
|
|
@saved = @project.save
|
|
@project_not_done_counts = { @project.id => 0 }
|
|
@active_projects_count = current_user.projects.active.count
|
|
@contexts = current_user.contexts
|
|
|
|
respond_to do |format|
|
|
format.js do
|
|
@down_count = current_user.projects.size
|
|
init_not_done_counts
|
|
end
|
|
format.xml do
|
|
if @project.new_record?
|
|
render_failure @project.errors.to_xml.html_safe, 409
|
|
else
|
|
head :created, :location => project_url(@project), :text => @project.id
|
|
end
|
|
end
|
|
format.html {redirect_to :action => 'index'}
|
|
end
|
|
end
|
|
|
|
# Edit the details of the project
|
|
#
|
|
def update
|
|
template = ""
|
|
|
|
params['project'] ||= {}
|
|
if params['project']['state']
|
|
@new_state = params['project']['state']
|
|
@state_changed = @project.state != @new_state
|
|
params['project'].delete('state')
|
|
end
|
|
success_text = if params['field'] == 'name' && params['value']
|
|
params['project']['id'] = params['id']
|
|
params['project']['name'] = params['value']
|
|
end
|
|
|
|
@project.attributes = params['project']
|
|
@saved = @project.save
|
|
if @saved
|
|
@project.transition_to(@new_state) if @state_changed
|
|
if boolean_param('wants_render')
|
|
@contexts = current_user.contexts
|
|
update_state_counts
|
|
init_data_for_sidebar
|
|
|
|
template = 'projects/update'
|
|
|
|
# TODO: are these params ever set? or is this dead code?
|
|
elsif boolean_param('update_status')
|
|
template = 'projects/update_status'
|
|
elsif boolean_param('update_default_context')
|
|
@initial_context_name = @project.default_context.name
|
|
template = 'projects/update_default_context'
|
|
elsif boolean_param('update_default_tags')
|
|
template = 'projects/update_default_tags'
|
|
elsif boolean_param('update_project_name')
|
|
@projects = current_user.projects
|
|
template = 'projects/update_project_name'
|
|
else
|
|
render :text => success_text || 'Success'
|
|
return
|
|
end
|
|
else
|
|
init_data_for_sidebar
|
|
template = 'projects/update'
|
|
end
|
|
|
|
respond_to do |format|
|
|
format.js { render :template => template }
|
|
format.html { redirect_to :action => 'index'}
|
|
format.xml {
|
|
if @saved
|
|
render :xml => @project.to_xml( :except => :user_id )
|
|
else
|
|
render :text => "Error on update: #{@project.errors.full_messages.inject("") {|v, e| v + e + " " }}", :status => 409
|
|
end
|
|
}
|
|
end
|
|
|
|
end
|
|
|
|
def edit
|
|
respond_to do |format|
|
|
format.js
|
|
end
|
|
end
|
|
|
|
def destroy
|
|
@project.recurring_todos.each {|rt| rt.remove_from_project!}
|
|
@project.destroy
|
|
|
|
respond_to do |format|
|
|
format.js {
|
|
@down_count = current_user.projects.size
|
|
update_state_counts
|
|
}
|
|
format.xml { render :text => "Deleted project #{@project.name}" }
|
|
end
|
|
end
|
|
|
|
def order
|
|
project_ids = params["container_project"]
|
|
@projects = current_user.projects.update_positions( project_ids )
|
|
render :nothing => true
|
|
rescue
|
|
notify :error, $!
|
|
redirect_to :action => 'index'
|
|
end
|
|
|
|
def alphabetize
|
|
@state = params['state']
|
|
@projects = current_user.projects.alphabetize(:state => @state) if @state
|
|
@contexts = current_user.contexts
|
|
init_not_done_counts(['project'])
|
|
init_project_hidden_todo_counts(['project']) if @state == 'hidden'
|
|
end
|
|
|
|
def actionize
|
|
@state = params['state']
|
|
@projects = current_user.projects.actionize(:state => @state) if @state
|
|
@contexts = current_user.contexts
|
|
init_not_done_counts(['project'])
|
|
init_project_hidden_todo_counts(['project']) if @state == 'hidden'
|
|
end
|
|
|
|
def done_todos
|
|
@source_view = 'project'
|
|
@project = current_user.projects.find(params[:id])
|
|
@page_title = t('projects.completed_tasks_title', :project_name => @project.name)
|
|
|
|
@done_today, @done_this_week, @done_this_month = DoneTodos.done_todos_for_container(@project)
|
|
@count = @done_today.size + @done_this_week.size + @done_this_month.size
|
|
|
|
render :template => 'todos/done'
|
|
end
|
|
|
|
def all_done_todos
|
|
@source_view = 'project'
|
|
@project = current_user.projects.find(params[:id])
|
|
@page_title = t('projects.all_completed_tasks_title', :project_name => @project.name)
|
|
|
|
@done = @project.todos.completed.paginate :page => params[:page], :per_page => 20, :order => 'completed_at DESC', :include => Todo::DEFAULT_INCLUDES
|
|
@count = @done.size
|
|
render :template => 'todos/all_done'
|
|
end
|
|
|
|
protected
|
|
|
|
def update_state_counts
|
|
@active_projects_count = current_user.projects.active.count
|
|
@hidden_projects_count = current_user.projects.hidden.count
|
|
@completed_projects_count = current_user.projects.completed.count
|
|
@show_active_projects = @active_projects_count > 0
|
|
@show_hidden_projects = @hidden_projects_count > 0
|
|
@show_completed_projects = @completed_projects_count > 0
|
|
end
|
|
|
|
def set_project_from_params
|
|
@project = current_user.projects.find_by_params(params)
|
|
end
|
|
|
|
def set_source_view
|
|
@source_view = params['_source_view'] || 'project'
|
|
end
|
|
|
|
def default_context_filter
|
|
p = params['project']
|
|
p = params['request']['project'] if p.nil? && params['request']
|
|
p = {} if p.nil?
|
|
default_context_name = p['default_context_name']
|
|
p.delete('default_context_name')
|
|
|
|
unless default_context_name.blank?
|
|
default_context = current_user.contexts.find_or_create_by_name(default_context_name)
|
|
p['default_context_id'] = default_context.id
|
|
end
|
|
end
|
|
|
|
end
|