cubesystems/releaf

View on GitHub
releaf-core/app/builders/releaf/builders/pagination_builder.rb

Summary

Maintainability
A
0 mins
Test Coverage
class Releaf::Builders::PaginationBuilder
  include Releaf::Builders::Base
  include Releaf::Builders::Template

  attr_accessor :collection
  attr_accessor :params

  delegate :total_pages, :current_page, :total_entries, :per_page, to: :collection

  def initialize( template, options = {} )
    self.collection = options[:collection]
    self.params     = options[:params]
    super template
  end

  def output
    return nil unless collection.total_pages > 1
    pagination_block
  end

  def pagination_block
    content_tag( :div, class: :pagination ) do
      safe_join { pagination_parts }
    end
  end

  def pagination_parts
    [
      previous_page_button,
      pagination_select,
      next_page_button
    ]
  end

  def previous_page_button
    page_button( -1, 'previous', 'chevron-left' )
  end

  def next_page_button
    page_button( 1, 'next', 'chevron-right' )
  end

  def page_button( offset, class_name, icon_name )
    attributes =
    {
      class: ['secondary', class_name ],
      title: t( "#{class_name.capitalize} page", scope: 'pagination')
    }

    page_number = relative_page_number( offset )

    if page_number.present?
      attributes[:rel]  = relative_page_relationship(offset)
      attributes[:href] = page_url(page_number)
    else
      attributes[:disabled] = true
    end

    button( nil, icon_name, attributes )
  end

  def page_numbers
    (1..total_pages).to_a
  end

  def relative_page_number( offset )
    page_number = current_page + offset
    page_numbers.include?(page_number) ? page_number : nil
  end

  def relative_page_relationship(offset)
    if offset == -1
      :prev
    elsif offset == 1
      :next
    else
      nil
    end
  end

  def page_url(page_number)
    template.url_for( params.merge( page: page_number ).permit! )
  end

  def pagination_select
    content_tag('select', name: :page) do
      safe_join do
        pagination_options
      end
    end
  end

  def pagination_options
    page_numbers.map do |page_number|
      attributes = { value: page_number }
      attributes[:selected] = true if page_number == current_page
      content_tag(:option, attributes) { page_label(page_number) }
    end
  end

  def page_label page_number
    first_item_in_page = (page_number - 1) * per_page + 1
    last_item_in_page  = [page_number * per_page, total_entries].min
    "#{first_item_in_page}-#{last_item_in_page}"
  end

end