Module: Protege::Components::PaginationHelper

Included in:
ComponentsHelper
Defined in:
app/helpers/protege/components/pagination_helper.rb

Overview

Pagination for sidebar lists: paginate slices a relation into a page of records plus the page metadata, and sidebar_pagination renders that metadata as the sidebar's bottom bar — a prev arrow, the first/current/last page numbers, and a next arrow.

Pagy supplies only the page math (count + page → offset/limit and the prev/next/last numbers); the markup is ours so it matches the sidebar styling. Colors use the same CSS custom properties as the rest of the layout (--text, --text-muted, --text-faint, --border) so dark mode follows along.

Instance Method Summary collapse

Instance Method Details

#paginate(scope, page: params[:page], limit: 15) ⇒ Array(Pagy, ActiveRecord::Relation)

Paginate a relation for a sidebar list, returning the page metadata and the page of records.

Wraps Pagy's standalone object (no Pagy::Backend controller mixin needed): it counts the scope, resolves the requested page, and slices the relation with +offset+/+limit+. The page defaults to the ?page= query param; a nil or non-numeric value falls back to page 1, and an overflowing one is clamped to the last page (the :last_page overflow default set at boot).

Parameters:

  • scope (ActiveRecord::Relation)

    the relation to page through

  • page (String, Integer, nil) (defaults to: params[:page])

    the requested page (defaults to params[:page])

  • limit (Integer) (defaults to: 15)

    the page size

Returns:

  • (Array(Pagy, ActiveRecord::Relation))

    the pagy metadata and the page of records



24
25
26
27
# File 'app/helpers/protege/components/pagination_helper.rb', line 24

def paginate(scope, page: params[:page], limit: 15)
  pagy = ::Pagy.new(count: scope.count, page: [page.to_i, 1].max, limit:)
  [pagy, scope.offset(pagy.offset).limit(pagy.limit)]
end

Render the sidebar's bottom pagination bar from a Pagy object — a prev arrow, the first/current/last page numbers, and a next arrow. Mirrors sidebar_header (same bar shape, a top border) but pinned to the bottom of the sidebar. Renders nothing for a single page, so a sidebar can render it unconditionally and it only appears once the list outgrows one page.

Links target the current path with a merged :page, so paging the sidebar keeps the main view (e.g. an open thread) in place and re-pages only the list.

Parameters:

  • pagy (Pagy)

    the page metadata for the sidebar's collection

Returns:

  • (ActiveSupport::SafeBuffer)

    the footer markup, or an empty buffer for a single page



39
40
41
42
43
44
45
46
47
48
49
50
# File 'app/helpers/protege/components/pagination_helper.rb', line 39

def sidebar_pagination(pagy)
  return ''.html_safe if pagy.pages <= 1

  tag.div(class: 'flex h-10 flex-shrink-0 items-center justify-between px-4 text-xs',
          style: 'border-top: 1px solid var(--border)') do
    [
      sidebar_page_arrow('◀︎', pagy.prev),
      sidebar_page_numbers(pagy),
      sidebar_page_arrow('▶︎', pagy.next)
    ].join.html_safe
  end
end