require 'ransack_simple_form' module Iquest module SimpleTable class TableBuilder attr_reader :parent, :table_id, :columns, :collection, :search_form, :actions, :collection_actions delegate :capture, :content_tag, :link_to, :paginate, :page_entries_info, :params, to: :parent delegate :sort_link, :search_form_for, to: :parent delegate :polymorphic_path, :polymorphic_url, to: :parent delegate :l, :t, :dom_id, to: :parent delegate :render, :render_to_string, to: :parent CLASS_DELIMITER = ' '.freeze EMPTY_STRING = ''.freeze DEFAULT_FORMATTER = ->(value) do case value when Time l(value) when Date l(value) else value end end def initialize(parent, collection_or_search, options = {}) @parent = parent if collection_or_search.is_a? Ransack::Search @collection = collection_or_search.result @search = collection_or_search @klass = @search.klass elsif collection_or_search.is_a?(ActiveRecord::Relation) || collection_or_search.is_a?(ActiveRecord::AssociationRelation) @collection = collection_or_search @klass = @collection.klass elsif collection_or_search.is_a?(Array) && (search = collection_or_search.detect { |o| o.is_a?(Ransack::Search) }) @search = search @collection = search.result @klass = @collection.klass options[:search_url] ||= polymorphic_path(collection_or_search.map { |o| o.is_a?(Ransack::Search) ? o.klass : o }) elsif collection_or_search.is_a?(Array) && (collection = collection_or_search.detect { |o| o.is_a?(ActiveRecord::Relation) || o.is_a?(ActiveRecord::AssociationRelation) }) @collection = collection @klass = @collection.klass elsif collection_or_search.is_a?(Array) && (collection_or_search.any? || options[:class]) @collection = collection_or_search @klass = options[:class] || collection_or_search.first.class else raise TypeError, 'ActiveRecord::Relation, ActiveRecord::AssociationRelation, Ransack::Search or Array of ActiveModel like objects expected' end apply_pagination # draper @collection = @collection.decorate if @collection.respond_to?(:decorate) options[:search_url] ||= begin polymorphic_path(@klass) rescue NoMethodError nil end @options = options @table_id = "table_#{@klass}".pluralize.parameterize @columns = {}.with_indifferent_access @actions = [] @collection_actions = [] @search_input_default_options = { label: false, placeholder: false }.with_indifferent_access @attr_classes = {} end def column(*args, &block) attr = args.first options = args.extract_options! search = options.delete(:search) @columns[attr] = options @columns[attr][:label] ||= column_label(attr) # iniciaizce search options if search.is_a?(Symbol) || search.is_a?(String) @columns[attr][:search] = { search.to_sym => {} } elsif search.is_a? Array @columns[attr][:search] = search.each_with_object({}) { |s, h| h[s.to_sym] = {}; } elsif search.is_a? Hash @columns[attr][:search] = search end @columns[attr][:formatter] ||= block_given? ? block : DEFAULT_FORMATTER @columns[attr][:sort] ||= attr.to_s.tr('.', '_') unless @columns[attr][:sort] == false # sort link attr @columns[attr][:html] ||= {} @columns[attr][:html][:class] = @columns[attr][:html][:class].join(CLASS_DELIMITER) if @columns[attr][:html][:class].is_a?(Array) @columns[attr][:html][:class] ||= '' end def action(*args, &block) _action = args.first options = args.extract_options! options[:proc] = block if block_given? @actions << options end def collection_action(*args) action = args.first if action.is_a? String @collection_actions << action elsif block_given? @collection_actions << yield end end def new_link(*_args) ActiveSupport::Deprecation.warn("Iquest::SimpleTable#new_link does nothing. Use collection_action") end def search_link(*_args, &block) @search_button = block if block_given? end def reset_link(*_args, &block) @reset_button = block if block_given? end WRAPPER_TEMPLATE = '
<%= @collection_actions.join %> | <% columns.each do |attr, options| %> <%= content_tag :th, class: options[:class], data: options[:data] do render_label(attr).html_safe end %> <% end %> <% if @search %> <%= render_search_inputs %> <% end %>
---|