class ContextsController < ApplicationController helper :todos before_filter :init, :except => [:index, :create, :destroy, :order] before_filter :init_todos, :only => :show before_filter :set_context_from_params, :only => [:update, :destroy] skip_before_filter :login_required, :only => [:index] prepend_before_filter :login_or_feed_token_required, :only => [:index] def index # #true is passed here to force an immediate load so that size and empty? # checks later don't result in separate SQL queries @active_contexts = current_user.contexts.active(true) @hidden_contexts = current_user.contexts.hidden(true) @new_context = current_user.contexts.build # save all contexts here as @new_context will add an empty one to current_user.contexts @all_contexts = @active_contexts + @hidden_contexts @count = @all_contexts.size init_not_done_counts(['context']) respond_to do |format| format.html &render_contexts_html format.m &render_contexts_mobile format.xml { render :xml => @all_contexts.to_xml( :except => :user_id ) } format.rss &render_contexts_rss_feed format.atom &render_contexts_atom_feed format.text do @all_contexts = current_user.contexts.all render :action => 'index', :layout => false, :content_type => Mime::TEXT end format.autocomplete { render :text => for_autocomplete(@active_contexts + @hidden_contexts, params[:term])} end end def show @contexts = current_user.contexts(true) if @context.nil? respond_to do |format| format.html { render :text => 'Context not found', :status => 404 } format.xml { render :xml => 'Context not found', :status => 404 } end else @page_title = "TRACKS::Context: #{@context.name}" respond_to do |format| format.html format.m &render_context_mobile format.xml { render :xml => @context.to_xml( :except => :user_id ) } end end end # Example XML usage: curl -H 'Accept: application/xml' -H 'Content-Type: # application/xml' # -u username:password # -d 'new context_name' # http://our.tracks.host/contexts # def create if params[:format] == 'application/xml' && params['exception'] render_failure "Expected post format is valid xml like so: context name.", 400 return end @context = current_user.contexts.build params_are_invalid = true if (params['context'] || (params['request'] && params['request']['context'])) @context.attributes = params['context'] || params['request']['context'] params_are_invalid = false end @saved = @context.save @context_not_done_counts = { @context.id => 0 } respond_to do |format| format.js do @down_count = current_user.contexts.size end format.xml do if @context.new_record? && params_are_invalid render_failure "Expected post format is valid xml like so: context name.", 400 elsif @context.new_record? render_failure @context.errors.to_xml, 409 else head :created, :location => context_url(@context) end end end end # Edit the details of the context # def update params['context'] ||= {} success_text = if params['field'] == 'name' && params['value'] params['context']['id'] = params['id'] params['context']['name'] = params['value'] end @original_context_hidden = @context.hidden? @context.attributes = params["context"] @saved = @context.save if @saved if boolean_param('wants_render') @state_changed = (@original_context_hidden != @context.hidden?) @new_state = (@context.hidden? ? "hidden" : "active") if @state_changed respond_to do |format| format.js end # TODO is this param ever used? is this dead code? elsif boolean_param('update_context_name') @contexts = current_user.projects render :template => 'contexts/update_context_name.js.rjs' return else render :text => success_text || 'Success' end else respond_to do |format| format.js format.xml { if @saved render :xml => @context.to_xml( :except => :user_id ) else render :text => "Error on update: #{@context.errors.full_messages.inject("") {|v, e| v + e + " " }}", :status => 409 end } end end end def edit @context = Context.find(params[:id]) respond_to do |format| format.js end end # Fairly self-explanatory; deletes the context If the context contains # actions, you'll get a warning dialogue. If you choose to go ahead, any # actions in the context will also be deleted. def destroy # make sure the deleted recurring patterns are removed from associated todos @context.recurring_todos.each { |rt| rt.clear_todos_association } unless @context.recurring_todos.nil? @context.destroy respond_to do |format| format.js do @down_count = current_user.contexts.size update_state_counts end format.xml { render :text => "Deleted context #{@context.name}" } end end # Methods for changing the sort order of the contexts in the list # def order context_ids = params["container_context"] @projects = current_user.contexts.update_positions( context_ids ) render :nothing => true rescue notify :error, $! redirect_to :action => 'index' end def done_todos @source_view = 'context' @context = current_user.contexts.find(params[:id]) @page_title = t('contexts.completed_tasks_title', :context_name => @context.name) completed_todos = @context.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 = 'context' @context = current_user.contexts.find(params[:id]) @page_title = t('contexts.all_completed_tasks_title', :context_name => @context.name) @done = @context.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_contexts_count = current_user.contexts.active.count @hidden_contexts_count = current_user.contexts.hidden.count @show_active_contexts = @active_contexts_count > 0 @show_hidden_contexts = @hidden_contexts_count > 0 end def render_contexts_html lambda do @page_title = "TRACKS::List Contexts" @no_active_contexts = @active_contexts.empty? @no_hidden_contexts = @hidden_contexts.empty? @active_count = @active_contexts.size @hidden_count = @hidden_contexts.size render end end def render_contexts_mobile lambda do @page_title = "TRACKS::List Contexts" @active_contexts = current_user.contexts.active @hidden_contexts = current_user.contexts.hidden @down_count = @active_contexts.size + @hidden_contexts.size cookies[:mobile_url]= {:value => request.request_uri, :secure => SITE_CONFIG['secure_cookies']} render :action => 'index_mobile' end end def render_context_mobile lambda do @page_title = "TRACKS::List actions in "+@context.name @not_done = @not_done_todos.select {|t| t.context_id == @context.id } @down_count = @not_done.size cookies[:mobile_url]= {:value => request.request_uri, :secure => SITE_CONFIG['secure_cookies']} @mobile_from_context = @context.id render :action => 'mobile_show_context' end end def render_contexts_rss_feed lambda do render_rss_feed_for current_user.contexts.all, :feed => feed_options, :item => { :description => lambda { |c| @template.summary(c, count_undone_todos_phrase(c)) } } end end def render_contexts_atom_feed lambda do render_atom_feed_for current_user.contexts.all, :feed => feed_options, :item => { :description => lambda { |c| @template.summary(c, count_undone_todos_phrase(c)) }, :author => lambda { |c| nil } } end end def feed_options Context.feed_options(current_user) end def set_context_from_params @context = current_user.contexts.find_by_params(params) rescue @context = nil end def init @source_view = params['_source_view'] || 'context' init_data_for_sidebar end def init_todos set_context_from_params unless @context.nil? @context.todos.send :with_scope, :find => { :include => Todo::DEFAULT_INCLUDES } do @done = @context.done_todos end @max_completed = current_user.prefs.show_number_completed # @not_done_todos = @context.not_done_todos 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 = @context.todos.active( :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", :include => Todo::DEFAULT_INCLUDES) @projects = current_user.projects @count = @not_done_todos.size end end end