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' @new_project = current_user.projects.build if params[:projects_and_actions] projects_and_actions else @contexts = current_user.contexts.all 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 respond_to do |format| format.html &render_projects_html format.m &render_projects_mobile format.xml { render :xml => @projects.to_xml( :except => :user_id ) } format.rss &render_rss_feed format.atom &render_atom_feed format.text &render_text_feed format.autocomplete { render :text => for_autocomplete(current_user.projects.uncompleted, params[:term]) } 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 { 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(:include => Todo::DEFAULT_INCLUDES) @deferred = @project.todos.deferred(:include => Todo::DEFAULT_INCLUDES) @pending = @project.todos.pending(:include => Todo::DEFAULT_INCLUDES) @done = {} @done = @project.todos.find_in_state(:all, :completed, :order => "todos.completed_at DESC", :limit => current_user.prefs.show_number_completed, :include => 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 &render_project_mobile format.xml { 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 # Example XML usage: curl -H 'Accept: application/xml' -H 'Content-Type: # application/xml' # -u username:password # -d 'new project_name' # http://our.tracks.host/projects # def create if params[:format] == 'application/xml' && params['exception'] render_failure "Expected post format is valid xml like so: project name." return end @project = current_user.projects.build params_are_invalid = true if (params['project'] || (params['request'] && params['request']['project'])) @project.attributes = params['project'] || params['request']['project'] params_are_invalid = false end @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 { @down_count = current_user.projects.size } format.xml do if @project.new_record? && params_are_invalid render_failure "Expected post format is valid xml like so: project name." elsif @project.new_record? render_failure @project.errors.full_messages.join(', ') 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') if (@project.hidden?) @project_project_hidden_todo_counts = Hash.new @project_project_hidden_todo_counts[@project.id] = @project.reload().todos.active_or_hidden.count else @project_not_done_counts = Hash.new @project_not_done_counts[@project.id] = @project.reload().todos.active_or_hidden.count end @contexts = current_user.contexts update_state_counts init_data_for_sidebar template = 'projects/update.js.erb' # TODO: are these params ever set? or is this dead code? elsif boolean_param('update_status') template = 'projects/update_status.js.rjs' elsif boolean_param('update_default_context') @initial_context_name = @project.default_context.name template = 'projects/update_default_context.js.rjs' elsif boolean_param('update_default_tags') template = 'projects/update_default_tags.js.rjs' elsif boolean_param('update_project_name') @projects = current_user.projects template = 'projects/update_project_name.js.rjs' else render :text => success_text || 'Success' return end else init_data_for_sidebar template = 'projects/update.js.erb' 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']) end def actionize @state = params['state'] @projects = current_user.projects.actionize(:state => @state) if @state @contexts = current_user.contexts init_not_done_counts(['project']) 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) completed_todos = @project.todos.completed @done_today = get_done_today(completed_todos) @done_this_week = get_done_this_week(completed_todos) @done_this_month = get_done_this_month(completed_todos) @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 render_projects_html lambda do @page_title = t('projects.list_projects') @count = current_user.projects.count @active_projects = current_user.projects.active @hidden_projects = current_user.projects.hidden @completed_projects = current_user.projects.completed.find(:all, :limit => 10) @completed_count = current_user.projects.completed.count @no_projects = current_user.projects.empty? current_user.projects.cache_note_counts @new_project = current_user.projects.build render end end def render_projects_mobile lambda do @active_projects = current_user.projects.active @hidden_projects = current_user.projects.hidden @completed_projects = current_user.projects.completed @down_count = @active_projects.size + @hidden_projects.size + @completed_projects.size cookies[:mobile_url]= {:value => request.request_uri, :secure => SITE_CONFIG['secure_cookies']} render :action => 'index_mobile' end end def render_project_mobile lambda 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.request_uri, :secure => SITE_CONFIG['secure_cookies']} @mobile_from_project = @project.id render :action => 'project_mobile' end end def render_rss_feed lambda do render_rss_feed_for @projects, :feed => feed_options, :title => :name, :item => { :description => lambda { |p| @template.summary(p) } } end end def render_atom_feed lambda do render_atom_feed_for @projects, :feed => feed_options, :item => { :description => lambda { |p| @template.summary(p) }, :title => :name, :author => lambda { |p| nil } } end end def feed_options Project.feed_options(current_user) end def render_text_feed lambda do render :action => 'index', :layout => false, :content_type => Mime::TEXT end 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