Class: CrudComponents::Presenters::Collection
- Includes:
- ColumnSelection
- Defined in:
- lib/crud_components/presenters/collection.rb
Overview
The single ‘collection` local every layout partial receives.
query: :auto (default) → build a Query from the request params and apply it query: :static → no filter row, no sort links, params ignored query: <Query> → manual mode (records arrive already filtered)
picker: false (default) → no column picker; true → render the gear picked_columns: :auto (default) → read ?cols=; an Array → that exact
selection (no param read — the backend resolved it)
Defined Under Namespace
Classes: Group
Constant Summary
Constants inherited from Base
Instance Attribute Summary collapse
-
#fieldset ⇒ Object
readonly
Returns the value of attribute fieldset.
-
#layout ⇒ Object
readonly
Returns the value of attribute layout.
-
#model ⇒ Object
readonly
Returns the value of attribute model.
-
#owner ⇒ Object
readonly
Returns the value of attribute owner.
-
#param_prefix ⇒ Object
readonly
Returns the value of attribute param_prefix.
-
#query ⇒ Object
readonly
Returns the value of attribute query.
-
#structure ⇒ Object
readonly
Returns the value of attribute structure.
Attributes inherited from Base
Instance Method Summary collapse
-
#actions_column? ⇒ Boolean
── actions ──────────────────────────────────────────────────────────.
-
#available_fields ⇒ Object
Every column this user is allowed to see — declared fieldset fields plus the dynamic columns — regardless of the current visibility selection.
-
#cell(field, record) ⇒ Object
── cells ────────────────────────────────────────────────────────────.
-
#cell_context ⇒ Object
Click-to-filter context for value renderers — only when this collection actually has a live query.
- #collection_actions ⇒ Object
-
#column_header(field) ⇒ Object
The ‘<th>` title for `field`: a custom `header:` (a String — html_safe to carry markup — or a view-context block, e.g. a link) replaces the plain `human_name`; otherwise the `human_name` itself.
-
#column_header_actions(field) ⇒ Object
The header actions for ‘field` as an Actions presenter (collection-kind: they act on the column’s object × — for a :selection action — the ticked rows, not a single row), or nil.
-
#column_param_name ⇒ Object
The checkbox param name the picker submits (respects param_prefix).
-
#column_picker? ⇒ Boolean
Whether to offer the column picker UI for this collection.
-
#column_selection_actions? ⇒ Boolean
A visible column may host an ‘on: :selection` action in its header (acting on the ticked rows × that column’s object).
- #columns_count ⇒ Object
- #current_page ⇒ Object
- #custom_actions_partial ⇒ Object
-
#custom_header?(field) ⇒ Boolean
Whether ‘field` brings its own header markup or header actions.
- #filter_fields ⇒ Object
- #filter_form_id ⇒ Object
-
#filterable? ⇒ Boolean
── filtering ────────────────────────────────────────────────────────.
- #filterable_field?(field) ⇒ Boolean
- #filtered? ⇒ Boolean
-
#group_open?(group) ⇒ Boolean
Default: every group open below the collapse threshold, only the first above it.
-
#group_toggle_url(group) ⇒ Object
Toggle this group in ‘?open=`, materializing the current open set so the first click on a default view keeps the others as they are.
- #grouped? ⇒ Boolean
-
#groups ⇒ Object
The records split into groups, in group order (the relation is ordered by the group key first, so consecutive records form each group).
-
#initialize(view:, records:, fieldset: nil, query: :auto, layout: :table, param_prefix: nil, actions: true, group_by: nil, extra_columns: nil, picker: false, picked_columns: :auto) ⇒ Collection
constructor
A new instance of Collection.
- #label_link_field?(field) ⇒ Boolean
- #label_link_present?(record) ⇒ Boolean
-
#own_param_keys ⇒ Object
Every param key this collection owns (for reset).
-
#page_scope ⇒ Object
The underlying (possibly paginated) relation, for custom layouts that would rather drive their own pager — e.g.
-
#page_url(n) ⇒ Object
A URL for page n that keeps this collection’s filters/search/sort and every other collection’s params (only our own ‘page` changes) — so the pager composes with everything and respects `param_prefix:`.
-
#pager_pages(window: 2) ⇒ Object
Page numbers to show, with :gap markers for elided ranges: [1, :gap, 4, 5, 6, :gap, 10].
-
#paginated? ⇒ Boolean
── pagination ───────────────────────────────────────────────────────── We render a footer pager only when the relation handed to us is already paginated — i.e.
-
#picker_preserved_params ⇒ Object
Hidden inputs for the picker’s GET form: keep every other param (filters, search, sort, other collections) but drop our own cols (the checkboxes resubmit it) and page (a column change resets paging).
-
#preserved_params ⇒ Object
Hidden inputs for the filter form: keep this collection’s sort and every param that belongs to someone else (other prefixes, the page’s own params).
- #record_link(record) ⇒ Object
- #records ⇒ Object
-
#reset_url ⇒ Object
Reset clears this collection’s filter/search/sort/page params and keeps everyone else’s (other prefixes, the page’s own params).
- #row_actions(record) ⇒ Object
- #search_param_name ⇒ Object
- #search_value ⇒ Object
-
#searchable? ⇒ Boolean
── header search (?q=) and reset ──────────────────────────────────────.
- #select_form_id ⇒ Object
-
#select_param_name ⇒ Object
The checkbox param name (respects param_prefix) — value is each row’s identify_by, resolved back with CrudComponents.selected.
- #select_value(record) ⇒ Object
- #selectable? ⇒ Boolean
-
#selection_actions ⇒ Object
── selection (bulk actions) ────────────────────────────────────────── Selection actions (‘action :x, on: :selection`) operate on the rows the user ticks.
-
#show_pager? ⇒ Boolean
Whether to draw the footer at all — a single page needs no pager.
-
#show_toolbar? ⇒ Boolean
Whether the toolbar (search + collection actions) has anything to show — lets a layout skip an empty header row.
-
#sort_active?(field) ⇒ Boolean
Is this the column the result is currently sorted by?.
-
#sort_direction(field) ⇒ Object
The active sort direction for a column — :asc / :desc, or nil when the result isn’t sorted by it.
-
#sort_numeric?(field) ⇒ Boolean
Whether this column sorts numerically (vs alphabetically) — numbers and dates do — so a layout can pick a sort-numeric vs sort-alpha glyph.
- #sort_url(field) ⇒ Object
-
#sortable_field?(field) ⇒ Boolean
── sorting ──────────────────────────────────────────────────────────.
- #static? ⇒ Boolean
- #surface ⇒ Object
- #total_count ⇒ Object
- #total_pages ⇒ Object
-
#trailing_column? ⇒ Boolean
The trailing column exists when there are row actions or a column picker (its gear lives in that column’s header cell) — so the header, rows and width all agree even on a picker-only, action-less table.
Methods included from ColumnSelection
#column_visible?, #field_groups, #fields, #group_heading, #group_icon, #visible_columns
Methods inherited from Base
#ability, #config, #css, #permission_context, #render_cell, #render_filter_control
Constructor Details
#initialize(view:, records:, fieldset: nil, query: :auto, layout: :table, param_prefix: nil, actions: true, group_by: nil, extra_columns: nil, picker: false, picked_columns: :auto) ⇒ Collection
Returns a new instance of Collection.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/crud_components/presenters/collection.rb', line 17 def initialize(view:, records:, fieldset: nil, query: :auto, layout: :table, param_prefix: nil, actions: true, group_by: nil, extra_columns: nil, picker: false, picked_columns: :auto) super(view: view) unless records.respond_to?(:klass) raise ArgumentError, "crud_collection expects an ActiveRecord relation (e.g. Book.all, @books, or an " \ "authorized scope like Book.accessible_by(current_ability)), got #{records.class}. " \ 'Pass a scope so your authorization and filtering apply before the gem renders.' end relation = records @model = relation.klass @structure = Structure.for(@model) @owner = relation.respond_to?(:proxy_association) ? relation.proxy_association.owner : nil @layout = layout @param_prefix = param_prefix @actions_enabled = actions # Two orthogonal column-picker knobs (see ColumnSelection): the gear is on # iff `picker`; the selection comes from the param (`:auto`) or verbatim # from the resolved Array — they never both read the param. @picker = picker @picked_columns = normalize_picked_columns(picked_columns) # User-defined columns whose data lives outside the model's table. Built # fresh per request (never on the immutable Structure), so they may carry # the per-page value cache. @dynamic_fields = Array(extra_columns).map { |c| c.to_field(@model) } case query when :static @static = true @fieldset = @structure.fieldset(fieldset || :index) when :auto, nil @fieldset = @structure.fieldset(fieldset || :index) @query = Query.new(@model, view.request.query_parameters, fieldset: @fieldset, ability: ability, param_prefix: param_prefix, extra_fields: @dynamic_fields) relation = @query.apply(relation) when Query @query = query @fieldset = fieldset ? @structure.fieldset(fieldset) : query.fieldset @param_prefix = query.param_prefix else raise ArgumentError, "crud_collection query: expects :auto, :static or a CrudComponents::Query, got #{query.inspect}" end @relation = eager_load(relation) setup_grouping(group_by) if group_by end |
Instance Attribute Details
#fieldset ⇒ Object (readonly)
Returns the value of attribute fieldset.
15 16 17 |
# File 'lib/crud_components/presenters/collection.rb', line 15 def fieldset @fieldset end |
#layout ⇒ Object (readonly)
Returns the value of attribute layout.
15 16 17 |
# File 'lib/crud_components/presenters/collection.rb', line 15 def layout @layout end |
#model ⇒ Object (readonly)
Returns the value of attribute model.
15 16 17 |
# File 'lib/crud_components/presenters/collection.rb', line 15 def model @model end |
#owner ⇒ Object (readonly)
Returns the value of attribute owner.
15 16 17 |
# File 'lib/crud_components/presenters/collection.rb', line 15 def owner @owner end |
#param_prefix ⇒ Object (readonly)
Returns the value of attribute param_prefix.
15 16 17 |
# File 'lib/crud_components/presenters/collection.rb', line 15 def param_prefix @param_prefix end |
#query ⇒ Object (readonly)
Returns the value of attribute query.
15 16 17 |
# File 'lib/crud_components/presenters/collection.rb', line 15 def query @query end |
#structure ⇒ Object (readonly)
Returns the value of attribute structure.
15 16 17 |
# File 'lib/crud_components/presenters/collection.rb', line 15 def structure @structure end |
Instance Method Details
#actions_column? ⇒ Boolean
── actions ──────────────────────────────────────────────────────────
354 355 356 |
# File 'lib/crud_components/presenters/collection.rb', line 354 def actions_column? @actions_enabled && (custom_actions_partial.present? || row_action_definitions.any?) end |
#available_fields ⇒ Object
Every column this user is allowed to see — declared fieldset fields plus the dynamic columns — regardless of the current visibility selection. This is what a column picker offers as the universe to choose from. (‘fields`, `column_visible?` and the picker knobs come from ColumnSelection.)
83 84 85 86 |
# File 'lib/crud_components/presenters/collection.rb', line 83 def available_fields @available_fields ||= (structure.fieldset_fields(fieldset) + @dynamic_fields).select { |f| f.permitted?() } end |
#cell(field, record) ⇒ Object
── cells ────────────────────────────────────────────────────────────
103 104 105 106 107 108 109 110 |
# File 'lib/crud_components/presenters/collection.rb', line 103 def cell(field, record) html = render_cell(field, record, surface: :collection, cell_context: cell_context) if label_link_field?(field) && (path = record_link(record)) view.link_to(html, path, class: css.record_link, data: { turbo_action: 'advance' }) else html end end |
#cell_context ⇒ Object
Click-to-filter context for value renderers — only when this collection actually has a live query.
114 115 116 117 118 |
# File 'lib/crud_components/presenters/collection.rb', line 114 def cell_context return nil if static? || query.nil? @cell_context ||= CellContext.new(view: view, query: query) end |
#collection_actions ⇒ Object
375 376 377 378 379 380 381 |
# File 'lib/crud_components/presenters/collection.rb', line 375 def collection_actions return nil unless @actions_enabled @collection_actions ||= Actions.new(view: view, subject: model, structure: structure, actions: structure.fieldset_actions(fieldset, on: :collection), owner: owner) end |
#column_header(field) ⇒ Object
The ‘<th>` title for `field`: a custom `header:` (a String — html_safe to carry markup — or a view-context block, e.g. a link) replaces the plain `human_name`; otherwise the `human_name` itself. `header:` substitutes only the name — the layout still wraps this in a sort link when the column is sortable, and appends any header actions.
141 142 143 144 145 146 147 148 |
# File 'lib/crud_components/presenters/collection.rb', line 141 def column_header(field) header = field.header case header when nil then field.human_name when Proc then view.instance_exec(&header) else header end end |
#column_header_actions(field) ⇒ Object
The header actions for ‘field` as an Actions presenter (collection-kind: they act on the column’s object × — for a :selection action — the ticked rows, not a single row), or nil. Each action’s path block closes over that object; the layout renders a :selection action as a select-form submitter and any other as a link/button.
155 156 157 158 159 160 161 |
# File 'lib/crud_components/presenters/collection.rb', line 155 def column_header_actions(field) return nil unless field.header_actions.any? (@column_header_actions ||= {})[field] ||= Actions.new(view: view, subject: model, structure: structure, actions: field.header_actions, owner: owner) end |
#column_param_name ⇒ Object
The checkbox param name the picker submits (respects param_prefix).
92 |
# File 'lib/crud_components/presenters/collection.rb', line 92 def column_param_name = "#{pn('cols')}[]" |
#column_picker? ⇒ Boolean
Whether to offer the column picker UI for this collection.
89 |
# File 'lib/crud_components/presenters/collection.rb', line 89 def column_picker? = @picker && available_fields.any? |
#column_selection_actions? ⇒ Boolean
A visible column may host an ‘on: :selection` action in its header (acting on the ticked rows × that column’s object). Like a toolbar selection action, it submits the shared select-form — so it needs the checkbox column + select-form and thus makes the collection selectable.
406 407 408 409 410 |
# File 'lib/crud_components/presenters/collection.rb', line 406 def column_selection_actions? fields.any? do |field| column_header_actions(field)&.items&.any? { |item| item.action.selection? } end end |
#columns_count ⇒ Object
423 424 425 |
# File 'lib/crud_components/presenters/collection.rb', line 423 def columns_count fields.size + (selectable? ? 1 : 0) + (trailing_column? ? 1 : 0) end |
#current_page ⇒ Object
323 |
# File 'lib/crud_components/presenters/collection.rb', line 323 def current_page = @relation.current_page |
#custom_actions_partial ⇒ Object
365 366 367 |
# File 'lib/crud_components/presenters/collection.rb', line 365 def custom_actions_partial fieldset.custom_actions_partial end |
#custom_header?(field) ⇒ Boolean
Whether ‘field` brings its own header markup or header actions.
132 133 134 |
# File 'lib/crud_components/presenters/collection.rb', line 132 def custom_header?(field) field.custom_header? end |
#filter_fields ⇒ Object
180 181 182 |
# File 'lib/crud_components/presenters/collection.rb', line 180 def filter_fields @filter_fields ||= static? ? [] : query.filter_fields end |
#filter_form_id ⇒ Object
188 189 190 191 |
# File 'lib/crud_components/presenters/collection.rb', line 188 def filter_form_id suffix = param_prefix ? "_#{param_prefix}" : '' "crud_filter_#{model.model_name.plural}#{suffix}" end |
#filterable? ⇒ Boolean
── filtering ────────────────────────────────────────────────────────
176 177 178 |
# File 'lib/crud_components/presenters/collection.rb', line 176 def filterable? !static? && query && filter_fields.any? end |
#filterable_field?(field) ⇒ Boolean
184 185 186 |
# File 'lib/crud_components/presenters/collection.rb', line 184 def filterable_field?(field) filter_fields.include?(field) end |
#filtered? ⇒ Boolean
206 207 208 |
# File 'lib/crud_components/presenters/collection.rb', line 206 def filtered? !static? && query&.active? end |
#group_open?(group) ⇒ Boolean
Default: every group open below the collapse threshold, only the first above it. Once ‘?open=` is set it is authoritative (and may open several).
292 293 294 295 296 297 298 |
# File 'lib/crud_components/presenters/collection.rb', line 292 def group_open?(group) if open_keys.nil? records.size < config.group_collapse_threshold || group == groups.first else open_keys.include?(group.key) end end |
#group_toggle_url(group) ⇒ Object
Toggle this group in ‘?open=`, materializing the current open set so the first click on a default view keeps the others as they are.
302 303 304 305 306 307 |
# File 'lib/crud_components/presenters/collection.rb', line 302 def group_toggle_url(group) current = groups.select { |g| group_open?(g) }.map(&:key) toggled = current.include?(group.key) ? current - [group.key] : current + [group.key] params = view.request.query_parameters.merge(pn('open') => toggled.join(',')) "#{view.request.path}?#{params.to_query}" end |
#grouped? ⇒ Boolean
280 |
# File 'lib/crud_components/presenters/collection.rb', line 280 def grouped? = !@group_by.nil? |
#groups ⇒ Object
The records split into groups, in group order (the relation is ordered by the group key first, so consecutive records form each group).
284 285 286 287 288 |
# File 'lib/crud_components/presenters/collection.rb', line 284 def groups @groups ||= records.group_by { |r| group_key_for(r) }.map do |key, recs| Group.new(key: key, label: group_label_for(recs.first), records: recs) end end |
#label_link_field?(field) ⇒ Boolean
120 121 122 |
# File 'lib/crud_components/presenters/collection.rb', line 120 def label_link_field?(field) field.name == structure.label_field_name end |
#label_link_present?(record) ⇒ Boolean
171 172 173 |
# File 'lib/crud_components/presenters/collection.rb', line 171 def label_link_present?(record) fields.any? { |f| label_link_field?(f) } && record_link(record).present? end |
#own_param_keys ⇒ Object
Every param key this collection owns (for reset).
234 235 236 237 |
# File 'lib/crud_components/presenters/collection.rb', line 234 def own_param_keys keys = filter_fields.flat_map { |f| [pn(f.name.to_s), pn("#{f.name}_geq"), pn("#{f.name}_leq")] } keys + %w[q sort dir page per].map { |k| pn(k) } end |
#page_scope ⇒ Object
The underlying (possibly paginated) relation, for custom layouts that would rather drive their own pager — e.g. hand it to kaminari’s ‘paginate` helper instead of rendering the gem’s _pager.
330 |
# File 'lib/crud_components/presenters/collection.rb', line 330 def page_scope = @relation |
#page_url(n) ⇒ Object
A URL for page n that keeps this collection’s filters/search/sort and every other collection’s params (only our own ‘page` changes) — so the pager composes with everything and respects `param_prefix:`.
335 336 337 338 |
# File 'lib/crud_components/presenters/collection.rb', line 335 def page_url(n) params = view.request.query_parameters.merge(pn('page') => n) "#{view.request.path}?#{params.to_query}" end |
#pager_pages(window: 2) ⇒ Object
Page numbers to show, with :gap markers for elided ranges: [1, :gap, 4, 5, 6, :gap, 10]. Always includes first/last and a window around the current page.
343 344 345 346 347 348 349 350 351 |
# File 'lib/crud_components/presenters/collection.rb', line 343 def pager_pages(window: 2) return [] if total_pages <= 1 shown = ([1, total_pages] + ((current_page - window)..(current_page + window)).to_a) .select { |p| p >= 1 && p <= total_pages }.uniq.sort shown.each_with_index.flat_map do |p, i| (i.positive? && p - shown[i - 1] > 1) ? [:gap, p] : [p] end end |
#paginated? ⇒ Boolean
── pagination ─────────────────────────────────────────────────────────We render a footer pager only when the relation handed to us is already paginated — i.e. the host called ‘.page` (kaminari / will_paginate, which decorate the relation). The gem never paginates on its own: no records arrive limited unless you asked for it. pagy keeps its state in a separate object, not on the relation, so it can’t be detected here —render ‘pagy_nav` yourself.
316 317 318 |
# File 'lib/crud_components/presenters/collection.rb', line 316 def paginated? @relation.respond_to?(:current_page) && @relation.respond_to?(:total_pages) end |
#picker_preserved_params ⇒ Object
Hidden inputs for the picker’s GET form: keep every other param (filters, search, sort, other collections) but drop our own cols (the checkboxes resubmit it) and page (a column change resets paging).
97 98 99 100 |
# File 'lib/crud_components/presenters/collection.rb', line 97 def picker_preserved_params drop = [pn('cols'), pn('page')] view.request.query_parameters.reject { |key, _| drop.include?(key) } end |
#preserved_params ⇒ Object
Hidden inputs for the filter form: keep this collection’s sort and every param that belongs to someone else (other prefixes, the page’s own params). Drop our own filter/search params — the controls themselves resubmit those.
227 228 229 230 231 |
# File 'lib/crud_components/presenters/collection.rb', line 227 def preserved_params own = filter_fields.flat_map { |f| [pn(f.name.to_s), pn("#{f.name}_geq"), pn("#{f.name}_leq")] } own += [pn('q'), pn('page'), pn('per')] view.request.query_parameters.reject { |key, _| own.include?(key) } end |
#record_link(record) ⇒ Object
163 164 165 166 167 168 169 |
# File 'lib/crud_components/presenters/collection.rb', line 163 def record_link(record) @record_links ||= {} return @record_links[record.id] if @record_links.key?(record.id) found = RouteResolver.record_path(view, record, owner: owner) @record_links[record.id] = found&.first end |
#records ⇒ Object
69 70 71 72 73 74 75 76 77 |
# File 'lib/crud_components/presenters/collection.rb', line 69 def records @records ||= begin rows = @relation.to_a # Prime each visible dynamic column's per-page cache once (no N+1); the # cell resolver then reads per row from what `preload:` returned. fields.each { |f| f.preload!(rows) if f.is_a?(Fields::DynamicField) } rows end end |
#reset_url ⇒ Object
Reset clears this collection’s filter/search/sort/page params and keeps everyone else’s (other prefixes, the page’s own params).
218 219 220 221 |
# File 'lib/crud_components/presenters/collection.rb', line 218 def reset_url kept = view.request.query_parameters.reject { |key, _| own_param_keys.include?(key) } kept.any? ? "#{view.request.path}?#{kept.to_query}" : view.request.path end |
#row_actions(record) ⇒ Object
369 370 371 372 373 |
# File 'lib/crud_components/presenters/collection.rb', line 369 def row_actions(record) Actions.new(view: view, subject: record, structure: structure, actions: row_action_definitions, owner: owner, suppress_show: label_link_present?(record)) end |
#search_param_name ⇒ Object
198 199 200 |
# File 'lib/crud_components/presenters/collection.rb', line 198 def search_param_name query.param_name('q') end |
#search_value ⇒ Object
202 203 204 |
# File 'lib/crud_components/presenters/collection.rb', line 202 def search_value query&.value('q') end |
#searchable? ⇒ Boolean
── header search (?q=) and reset ──────────────────────────────────────
194 195 196 |
# File 'lib/crud_components/presenters/collection.rb', line 194 def searchable? !static? && query && query.searchable? end |
#select_form_id ⇒ Object
412 413 414 415 |
# File 'lib/crud_components/presenters/collection.rb', line 412 def select_form_id suffix = param_prefix ? "_#{param_prefix}" : '' "crud_select_#{model.model_name.plural}#{suffix}" end |
#select_param_name ⇒ Object
The checkbox param name (respects param_prefix) — value is each row’s identify_by, resolved back with CrudComponents.selected.
419 |
# File 'lib/crud_components/presenters/collection.rb', line 419 def select_param_name = "#{pn('selected')}[]" |
#select_value(record) ⇒ Object
421 |
# File 'lib/crud_components/presenters/collection.rb', line 421 def select_value(record) = record.public_send(structure.identify_by).to_s |
#selectable? ⇒ Boolean
396 397 398 399 400 |
# File 'lib/crud_components/presenters/collection.rb', line 396 def selectable? return @selectable if defined?(@selectable) @selectable = @actions_enabled && (selection_actions.any? || column_selection_actions?) end |
#selection_actions ⇒ Object
── selection (bulk actions) ──────────────────────────────────────────Selection actions (‘action :x, on: :selection`) operate on the rows the user ticks. Rendered as submit buttons that post the checked `selected[]` slugs to the action path — no-JS works; the optional crud-select controller adds select-all / select-group / a live count.
388 389 390 391 392 393 394 |
# File 'lib/crud_components/presenters/collection.rb', line 388 def selection_actions return nil unless @actions_enabled @selection_actions ||= Actions.new(view: view, subject: model, structure: structure, actions: structure.fieldset_actions(fieldset, on: :selection), owner: owner) end |
#show_pager? ⇒ Boolean
Whether to draw the footer at all — a single page needs no pager.
321 |
# File 'lib/crud_components/presenters/collection.rb', line 321 def show_pager? = paginated? && total_pages > 1 |
#show_toolbar? ⇒ Boolean
Whether the toolbar (search + collection actions) has anything to show —lets a layout skip an empty header row.
212 213 214 |
# File 'lib/crud_components/presenters/collection.rb', line 212 def searchable? || collection_actions&.any? || selection_actions&.any? end |
#sort_active?(field) ⇒ Boolean
Is this the column the result is currently sorted by?
252 253 254 |
# File 'lib/crud_components/presenters/collection.rb', line 252 def sort_active?(field) !sort_direction(field).nil? end |
#sort_direction(field) ⇒ Object
The active sort direction for a column — :asc / :desc, or nil when the result isn’t sorted by it. The presenter holds no icon names: a layout turns this tri-state into whatever glyph it likes (see _table), pairing it with ‘sort_numeric?` to choose a numeric vs alphabetic icon.
260 261 262 263 264 265 |
# File 'lib/crud_components/presenters/collection.rb', line 260 def sort_direction(field) current, dir = query&.sort_state return nil unless current == field.name.to_s dir.to_s == 'desc' ? :desc : :asc end |
#sort_numeric?(field) ⇒ Boolean
Whether this column sorts numerically (vs alphabetically) — numbers and dates do — so a layout can pick a sort-numeric vs sort-alpha glyph.
269 270 271 |
# File 'lib/crud_components/presenters/collection.rb', line 269 def sort_numeric?(field) field.is_a?(Fields::NumericField) || field.is_a?(Fields::DateField) end |
#sort_url(field) ⇒ Object
244 245 246 247 248 249 |
# File 'lib/crud_components/presenters/collection.rb', line 244 def sort_url(field) current, dir = query.sort_state next_dir = current == field.name.to_s && dir == 'asc' ? 'desc' : 'asc' params = view.request.query_parameters.merge(pn('sort') => field.name.to_s, pn('dir') => next_dir) "#{view.request.path}?#{params.to_query}" end |
#sortable_field?(field) ⇒ Boolean
── sorting ──────────────────────────────────────────────────────────
240 241 242 |
# File 'lib/crud_components/presenters/collection.rb', line 240 def sortable_field?(field) !static? && query && query.sortable_fields.include?(field) end |
#static? ⇒ Boolean
66 |
# File 'lib/crud_components/presenters/collection.rb', line 66 def static? = !!@static |
#surface ⇒ Object
67 |
# File 'lib/crud_components/presenters/collection.rb', line 67 def surface = :collection |
#total_count ⇒ Object
325 |
# File 'lib/crud_components/presenters/collection.rb', line 325 def total_count = @relation.total_count |
#total_pages ⇒ Object
324 |
# File 'lib/crud_components/presenters/collection.rb', line 324 def total_pages = @relation.total_pages |
#trailing_column? ⇒ Boolean
The trailing column exists when there are row actions or a column picker (its gear lives in that column’s header cell) — so the header, rows and width all agree even on a picker-only, action-less table.
361 362 363 |
# File 'lib/crud_components/presenters/collection.rb', line 361 def trailing_column? actions_column? || column_picker? end |