Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
admin_toolbox / lib / admin_toolbox / tools / previewable.rb
Size: Mime:
module AdminToolbox
  module Tools
    module Previewable
      def self.included(base)
        base.controller do
          private
          include ControllerMethods
          helper_method :param_key, :live_preview_javascript, :live_preview_link
        end

        def base.live_preview_action_item
          action_item 'Live Preview', only: [:edit, :new] do
            live_preview_link
          end
        end

        base.send :member_action, :preview do
          render_preview find_resource, preview_options
        end

        base.send :collection_action, :live_preview, method: [:patch, :post] do
          render_preview build_live_preview_resource, preview_options
        end
      end

      module ControllerMethods
        def previewable?(item)
          # Guard method for overriding in case an object needs to pass muster
          # before it can be properly previewed. Defaults to true/always allow.
          true
        end

        def build_live_preview_resource
          attrs = permitted_params[param_key.to_sym].to_h
                  .deep_except('id', '_destroy')
          resource_class.new(attrs)
        end

        def param_key
          active_admin_config.resource_name.param_key
        end

        def preview_options
          {}
        end

        def render_preview(item, **options)
          unless previewable?(item)
            flash[:alert] = I18n.t('admin_toolbox.preview.unpreviewable')
            redirect_to action: :index and return
          end

          default_options = {
            template:  "#{active_admin_config.resource_name.plural}/show",
            assigns: {},
            controller: 'ApplicationController'
          }

          instance_var_name = options.delete(:instance_var_name) || param_key
          options.reverse_merge!(default_options)
          options[:assigns][instance_var_name] ||= item

          renderer = options.delete(:controller).constantize.renderer
          renderer.instance_variable_set(:@env, request.env)
          render html: renderer.render(options)
        end

        def live_preview_link(options = {})
          label = options.delete(:label) || 'Live Preview'
          default_options = { class: 'button', onclick: live_preview_javascript }

          view_context.link_to label,
                url_for(action: :live_preview),
                default_options.merge(options)
        end

        def live_preview_javascript
          <<~JAVASCRIPT
            if(typeof(CKEDITOR) !== 'undefined') {
              Object.values(CKEDITOR.instances).forEach(
                (editor) => editor.updateElement()
              )
            }

            const form = document.querySelector('#main_content form')

            original_url = form['action'];
            original_target = form['target'];
            original_verb = form['data-method'];

            if(original_target == undefined)
              original_target = null

            if(original_verb == undefined)
              original_verb = null

            form.setAttribute('action', this.href)
            form.setAttribute('target', "_blank")
            form.setAttribute('data-method', 'post')

            form.submit()

            form.setAttribute('action', original_url)
            form.setAttribute('target', original_target)
            form.setAttribute('data-method', original_verb)

            return false;
          JAVASCRIPT
        end
      end
    end
  end
end

class ActionController::Parameters
  def deep_except(*keys)
    new_instance_with_inherited_permitted_status(@parameters.deep_except(*keys))
  end
end

class Hash
  def deep_except(*keys_for_removal)
    hash = except(*keys_for_removal)
    hash
      .select { |k,v| v.respond_to?(:deep_except)}
      .each_pair { |k,v| hash[k] = v.deep_except(*keys_for_removal) }

    hash
  end
end