class ContextsController < ApplicationController helper :todos before_action :init, :except => [:index, :create, :destroy, :order] before_action :set_context_from_params, :only => [:update, :destroy] skip_before_action :login_required, :only => [:index, :show] prepend_before_action :login_or_feed_token_required, :only => [:index, :show] def index @all_contexts = current_user.contexts @active_contexts = current_user.contexts.active @hidden_contexts = current_user.contexts.hidden @closed_contexts = current_user.contexts.closed unless request.format == :autocomplete init_not_done_counts(['context']) init_hidden_todo_counts(['context']) end respond_to do |format| format.html &render_contexts_html format.m &render_contexts_mobile format.xml { render :xml => @all_contexts.to_xml(:root => :contexts, :except => :user_id) } format.any(:rss, :atom) do @feed_title = 'Tracks Contexts' @feed_description = "Lists all the contexts for #{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 render :action => 'index', :layout => false, :content_type => Mime[:text] end format.autocomplete &render_autocomplete end end def show set_context_from_params unless @context.nil? @max_completed = current_user.prefs.show_number_completed @done = @context.todos.completed.limit(@max_completed).reorder(Arel.sql("todos.completed_at DESC, todos.created_at DESC")).includes(Todo::DEFAULT_INCLUDES) @not_done_todos = @context.todos.active_or_hidden.not_project_hidden.reorder(Arel.sql('todos.due IS NULL, todos.due ASC, todos.created_at ASC')).includes(Todo::DEFAULT_INCLUDES) @todos_without_project = @not_done_todos.select { |t| t.project.nil? } @deferred_todos = @context.todos.deferred.includes(Todo::DEFAULT_INCLUDES) @pending_todos = @context.todos.pending.includes(Todo::DEFAULT_INCLUDES) @projects = current_user.projects @contexts = current_user.contexts @projects_to_show = @projects.active @contexts_to_show = [@context] @count = @not_done_todos.count + @deferred_todos.count + @pending_todos.count @page_title = "TRACKS::Context: #{@context.name}" respond_to do |format| format.html format.m &render_context_mobile format.xml { render :xml => @context.to_xml(:root => :context, :except => :user_id) } end else respond_to do |format| format.html { render :body => 'Context not found', :status => 404 } format.xml { render :xml => 'Context not found', :status => 404 } end end end 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(context_params) @context.hide! if params['context_state'] && params['context_state']['hide'] == '1' @saved = @context.save @context_not_done_counts = { @context.id => 0 } respond_to do |format| format.js do @down_count = current_user.contexts.size init_not_done_counts init_hidden_todo_counts(['context']) end format.xml do if @context.new_record? render_failure @context.errors.full_messages.to_xml(root: "errors", skip_types: true).html_safe, 409 else head :created, :location => context_url(@context) end end end end # Edit the details of the context def update process_params_for_update @context.attributes = context_params @saved = @context.save @state_saved = set_state_for_update(@new_state) @saved &&= @state_saved if @saved @state_changed = (@original_context_state != @context.state) @new_state = @context.state if @state_changed @active_contexts = current_user.contexts.active @hidden_contexts = current_user.contexts.hidden @closed_contexts = current_user.contexts.closed end respond_to do |format| format.js format.xml do if @saved render :xml => @context.to_xml(:except => :user_id) else render :body => "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 recurrence patterns are removed from associated todos @context.recurring_todos.each(&: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 :body => "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) head :ok rescue notify :error, $! redirect_to :action => 'index' end def done_todos done_todos_for current_user.contexts.find(params[:id]) end def all_done_todos all_done_todos_for current_user.contexts.find(params[:id]) end private def context_params params.require(:context).permit(:name, :position, :state) end protected def update_state_counts @active_contexts_count = current_user.contexts.active.count @hidden_contexts_count = current_user.contexts.hidden.count @closed_contexts_count = current_user.contexts.closed.count @show_active_contexts = @active_contexts_count > 0 @show_hidden_contexts = @hidden_contexts_count > 0 @show_closed_contexts = @closed_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? @no_closed_contexts = @closed_contexts.empty? @active_count = @active_contexts.size @hidden_count = @hidden_contexts.size @closed_count = @closed_contexts.size @count = @active_count + @hidden_count + @closed_count @new_context = current_user.contexts.build 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.fullpath, :secure => SITE_CONFIG['secure_cookies'] } render 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.fullpath, :secure => SITE_CONFIG['secure_cookies'] } @mobile_from_context = @context.id render end end def render_autocomplete lambda do render :body => for_autocomplete(current_user.contexts, params[:term]) end end def feed_options Context.feed_options(current_user) end def set_context_from_params @context = current_user.contexts.find(params[:id]) rescue @context = nil end def init @source_view = params['_source_view'] || 'context' init_data_for_sidebar end def process_params_for_update params['context'] ||= {} @success_text = if params['field'] == 'name' && params['value'] params['context']['id'] = params['id'] params['context']['name'] = params['value'] end @original_context_state = @context.state @new_state = params['context']['state'] params['context'].delete('state') end def set_state_for_update(new_state) begin unless @original_context_state == new_state if new_state == 'active' @context.activate! elsif new_state == 'hidden' @context.hide! elsif new_state == 'closed' @context.close! end end return true rescue AASM::InvalidTransition @context.errors.add(:state, "cannot be changed. The context cannot be closed if you have uncompleted actions in this context") return false end end end