app/controllers/admin/base_controller.rb in ab_admin-0.3.6 vs app/controllers/admin/base_controller.rb in ab_admin-0.4.0

- old
+ new

@@ -1,38 +1,43 @@ class Admin::BaseController < ::InheritedResources::Base use Rack::Pjax, only: :index layout :set_layout + include AbAdmin::Controllers::Fv include AbAdmin::Controllers::Callbacks + define_admin_callbacks :save, :create - before_filter :authenticate_user!, :require_moderator - before_filter :add_breadcrumbs, :set_title, :set_user_vars, unless: :xhr? + before_action :authenticate_user!, :require_require_admin_access, :set_user_vars + before_action :add_breadcrumbs, :set_title, unless: :xhr? class_attribute :export_builder, :batch_action_list, :button_scopes, instance_reader: false, instance_writer: false - has_scope :ids, type: :array + defaults finder: :friendly_find + has_scope :by_ids, type: :array + helper_method :admin?, :moderator? helper_method :button_scopes, :collection_action?, :action_items, :resource_action_items, - :preview_resource_path, :get_subject, :settings, :batch_action_list, :tree_node_renderer + :preview_resource_path, :get_subject, :settings, :batch_action_list, :tree_node_renderer, + :normalized_index_views, :current_index_view, :pjax?, :xhr? - respond_to :json - rescue_from ::CanCan::AccessDenied, with: :render_unauthorized def index super do |format| format.js { render layout: false } format.csv do + authorize! :export, resource_class doc = AbAdmin::Utils::CsvDocument.new(collection, export_options) send_data(doc.render, filename: doc.filename, type: Mime::CSV, disposition: 'attachment') end if defined?(Mime::XLSX) format.xls do + authorize! :export, resource_class doc = AbAdmin::Utils::XlsDocument.new(collection, export_options) send_data(doc.render, filename: doc.filename, type: Mime::XLSX, disposition: 'attachment') end end end @@ -50,17 +55,30 @@ update! do |success, failure| success.html { redirect_to redirect_to_on_success } failure.html { render :edit } success.js { render layout: false } failure.js { render :edit, layout: false } + unless Admin::ManagerController.mimes_for_respond_to[:json] + success.json { head :no_content } + failure.json { head :unprocessable } + end end end def destroy - destroy! { redirect_to_on_success } + destroy! do + track_action! if settings[:history] + redirect_to_on_success + end end + def show + show! do |format| + format.js { render layout: false } + end + end + def edit edit! do |format| format.js { render layout: false } end end @@ -70,35 +88,53 @@ format.js { render layout: false } end end def batch - raise 'No ids specified for batch action' unless params[:ids].present? + raise 'No ids specified for batch action' unless params[:by_ids].present? batch_action = params[:batch_action].to_sym if allow_batch_action?(batch_action) && collection.all?{|item| can?(batch_action, item) } count = collection.inject(0) { |c, item| apply_batch_action(item, batch_action) ? c + 1 : c } - flash[:success] = I18n.t('admin.batch_actions.status', count: count, action: I18n.t("admin.actions.batch_#{batch_action}.title")) + batch_action_name = I18n.t("admin.actions.batch_#{batch_action}.title", default: batch_action.to_s.humanize) + flash[:success] = I18n.t('admin.batch_actions.status', count: count, action: batch_action_name) else raise CanCan::AccessDenied end - redirect_to :back + redirect_to_back_or_root end + protected + + def default_url_options + options = {format: nil} + options.update instance_exec(&AbAdmin.default_url_options) if AbAdmin.default_url_options + options.update instance_exec(&settings[:default_url_options]) if settings[:default_url_options] + options + end + def apply_batch_action(item, batch_action) - item.send(batch_action) + success = item.send(batch_action) + track_action!("batch_#{batch_action}", item) if settings[:history] + success end def allow_batch_action?(batch_action) resource_class.batch_actions.include?(batch_action) end - protected + def redirect_to_back_or_root + redirect_to request.env['HTTP_REFERER'] ? :back : admin_root_path + end - def default_url_options - {format: nil} + def track_action(key=nil, item=nil) + (item || resource).track(key: key || action_name, user: current_user) end + def track_action!(*args) + track_action(*args).save! + end + def batch_action_list self.class.batch_action_list ||= begin resource_class.batch_actions.map do |a| opts = a == :destroy ? {confirm: I18n.t('admin.delete_confirmation')} : {} AbAdmin::Config::BatchAction.new(a, opts) @@ -109,10 +145,11 @@ def self.inherited(base) super base.class_eval do before_create :bind_current_user before_save :bind_current_updater + before_save { track_action if settings[:history] } end end def interpolation_options return {} if collection_action? || resource.errors.empty? @@ -134,11 +171,11 @@ def preview_resource_path(item) nil end def settings - {index_view: 'table', sidebar: collection_action?, well: (collection_action? || action_name == 'show'), + {index_view: 'table', sidebar: collection_action?, well: (collection_action? || %w(show history).include?(action_name)), search: true, batch: true, hotkeys: true} end def action_items case action_name.to_sym @@ -158,23 +195,17 @@ def collection_action? %w(index search batch rebuild).include?(action_name) end def button_scopes - self.class.button_scopes ||= begin - res = {} - self.class.scopes_configuration.except(:ids).each do |k, v| - res[k] = v if v[:type] == :default - end - res - end + self.class.button_scopes ||= self.class.scopes_configuration.except(:ids).find_all{|_, s| s[:type] == :boolean }.to_h end def add_breadcrumbs @breadcrumbs = [] if parent? - @breadcrumbs << {name: parent_class.model_name.human(count: 9), url: parent_collection_path} + @breadcrumbs << {name: parent.class.model_name.human(count: 9), url: parent_collection_path} @breadcrumbs << {name: AbAdmin.display_name(parent), url: parent_path} end @breadcrumbs << {name: resource_class.model_name.human(count: 9), url: collection_path} if params[:id] && resource.persisted? @breadcrumbs << {name: AbAdmin.display_name(resource), url: resource_path} @@ -190,11 +221,11 @@ name_for_lookup] @page_title ||= t(lookups.shift, default: lookups) end def parent_collection_path - {action: :index, controller: "admin/#{parent_class.model_name.plural}"} + {action: :index, controller: "admin/#{parent.class.model_name.plural}"} end def tree_node_renderer @tree_node_renderer ||= lambda { |r| link_to AbAdmin.display_name(r), resource_path(r), class: 'tree-item_link' } end @@ -210,25 +241,35 @@ @collection ||= search_collection.paginate(page: params[:page], per_page: per_page, large: true) end def per_page return params[:per_page] if params[:per_page].present? - if settings[:index_view] == 'tree' + if current_index_view == 'tree' params[:per_page] = 1000 else params[:per_page] = cookies[:pp] || 50 end end def set_layout pjax? ? false : 'admin/application' end - def pjax? - request.headers['X-PJAX'] + def normalized_index_views + Array(settings[:index_view]) end + def current_index_view + index_view = params[:index_view].presence || cookies[:iv].presence + if index_view && normalized_index_views.include?(index_view) + cookies[:iv] = index_view + index_view + else + normalized_index_views.first + end + end + def back_or_collection if params[:return_to].present? && (params[:return_to] != request.fullpath) params[:return_to] else smart_collection_url @@ -251,26 +292,44 @@ back_or_collection end end def set_user_vars - I18n.locale = Rails.application.config.i18n.default_locale - gon.locale = I18n.locale - gon.bg_color = current_user.bg_color - gon.admin = admin? - gon.test = Rails.env.test? - gon.hotkeys = settings[:hotkeys] + I18n.locale = AbAdmin.locale + fv.locale = I18n.locale + fv.bg_color = current_user.bg_color + fv.admin = admin? + fv.hotkeys = settings[:hotkeys] + fv.env = Rails.env + if AbAdmin.test_env? + fv.test = true + AbAdmin.test_settings.each { |k, v| fv.set_variable k, v } + end end + # utility methods + def pjax? + request.headers['X-PJAX'] + end + + def xhr? + request.xhr? + end + + # user role logic def moderator? user_signed_in? && current_user.moderator? end def admin? user_signed_in? && current_user.admin? end + def require_require_admin_access + raise CanCan::AccessDenied unless current_user.admin_access? + end + def require_moderator raise CanCan::AccessDenied unless moderator? end def require_admin @@ -283,14 +342,10 @@ def bind_current_updater(*args) resource.updater_id = current_user.id if resource.respond_to?(:updater_id) end - def xhr? - request.xhr? - end - # roles logic def role_given? fetch_role end @@ -317,10 +372,10 @@ Rails.logger.debug "Access denied on #{exception.action} #{exception.subject.inspect}, user: #{current_user.try(:id)}" if pjax? render partial: 'admin/shared/flash', locals: {flash: {alert: exception.message}} elsif request.format.try(:html?) - redirect_to (moderator? ? admin_root_path : root_path), alert: exception.message + redirect_to (current_user.try(:admin_access?) ? admin_root_path : root_path), alert: exception.message else head :unauthorized end end \ No newline at end of file