pagy 8.4.0 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/apps/calendar.ru +682 -2137
- data/apps/demo.ru +17 -13
- data/apps/keyset_ar.ru +236 -0
- data/apps/keyset_s.ru +238 -0
- data/apps/rails.ru +19 -15
- data/apps/repro.ru +17 -14
- data/apps/tmp/calendar.sqlite3 +0 -0
- data/apps/tmp/calendar.sqlite3-shm +0 -0
- data/apps/tmp/calendar.sqlite3-wal +0 -0
- data/apps/tmp/local_secret.txt +1 -0
- data/apps/tmp/pagy-keyset-ar.sqlite3 +0 -0
- data/apps/tmp/pagy-keyset-ar.sqlite3-shm +0 -0
- data/apps/tmp/pagy-keyset-ar.sqlite3-wal +0 -0
- data/apps/tmp/pagy-keyset-s.sqlite3 +0 -0
- data/bin/pagy +17 -12
- data/config/pagy.rb +32 -33
- data/javascripts/pagy-module.js +94 -107
- data/javascripts/pagy.js +4 -1
- data/javascripts/pagy.min.js +4 -0
- data/javascripts/pagy.min.js.map +10 -0
- data/javascripts/pagy.mjs +100 -0
- data/lib/optimist.rb +1 -1
- data/lib/pagy/b64.rb +33 -0
- data/lib/pagy/backend.rb +21 -17
- data/lib/pagy/calendar/day.rb +4 -3
- data/lib/pagy/calendar/month.rb +4 -3
- data/lib/pagy/calendar/quarter.rb +4 -3
- data/lib/pagy/calendar/unit.rb +103 -0
- data/lib/pagy/calendar/week.rb +3 -3
- data/lib/pagy/calendar/year.rb +4 -3
- data/lib/pagy/calendar.rb +54 -97
- data/lib/pagy/countless.rb +15 -16
- data/lib/pagy/extras/arel.rb +8 -10
- data/lib/pagy/extras/array.rb +4 -6
- data/lib/pagy/extras/bootstrap.rb +5 -5
- data/lib/pagy/extras/bulma.rb +10 -7
- data/lib/pagy/extras/calendar.rb +34 -5
- data/lib/pagy/extras/countless.rb +6 -13
- data/lib/pagy/extras/elasticsearch_rails.rb +15 -15
- data/lib/pagy/extras/gearbox.rb +26 -26
- data/lib/pagy/extras/headers.rb +25 -24
- data/lib/pagy/extras/i18n.rb +1 -1
- data/lib/pagy/extras/js_tools.rb +9 -9
- data/lib/pagy/extras/jsonapi.rb +26 -16
- data/lib/pagy/extras/keyset.rb +26 -0
- data/lib/pagy/extras/limit.rb +63 -0
- data/lib/pagy/extras/meilisearch.rb +11 -11
- data/lib/pagy/extras/metadata.rb +6 -2
- data/lib/pagy/extras/overflow.rb +9 -8
- data/lib/pagy/extras/pagy.rb +16 -16
- data/lib/pagy/extras/searchkick.rb +11 -11
- data/lib/pagy/extras/size.rb +40 -0
- data/lib/pagy/extras/standalone.rb +6 -6
- data/lib/pagy/extras/trim.rb +3 -3
- data/lib/pagy/frontend.rb +38 -36
- data/lib/pagy/i18n.rb +1 -1
- data/lib/pagy/keyset/active_record.rb +38 -0
- data/lib/pagy/keyset/sequel.rb +51 -0
- data/lib/pagy/keyset.rb +99 -0
- data/lib/pagy/url_helpers.rb +5 -5
- data/lib/pagy.rb +92 -94
- data/locales/ar.yml +9 -10
- data/locales/be.yml +2 -2
- data/locales/bg.yml +2 -2
- data/locales/bs.yml +2 -2
- data/locales/ca.yml +5 -7
- data/locales/ckb.yml +2 -2
- data/locales/cs.yml +2 -2
- data/locales/da.yml +2 -2
- data/locales/de.yml +2 -2
- data/locales/en.yml +2 -2
- data/locales/es.yml +2 -2
- data/locales/fr.yml +2 -2
- data/locales/hr.yml +2 -2
- data/locales/id.yml +2 -2
- data/locales/it.yml +2 -2
- data/locales/ja.yml +2 -2
- data/locales/km.yml +2 -2
- data/locales/ko.yml +2 -2
- data/locales/nb.yml +2 -2
- data/locales/nl.yml +2 -2
- data/locales/nn.yml +2 -2
- data/locales/pl.yml +2 -2
- data/locales/pt-BR.yml +2 -2
- data/locales/pt.yml +2 -2
- data/locales/ru.yml +2 -2
- data/locales/sr.yml +2 -2
- data/locales/sv-SE.yml +2 -2
- data/locales/sv.yml +2 -2
- data/locales/sw.yml +2 -2
- data/locales/ta.yml +2 -2
- data/locales/tr.yml +2 -2
- data/locales/uk.yml +2 -2
- data/locales/vi.yml +2 -2
- data/locales/zh-CN.yml +2 -2
- data/locales/zh-HK.yml +2 -2
- data/locales/zh-TW.yml +2 -2
- data/pkg/pagy-9.0.0.gem +0 -0
- metadata +27 -17
- data/javascripts/pagy-dev.js +0 -114
- data/lib/pagy/calendar/helper.rb +0 -65
- data/lib/pagy/extras/foundation.rb +0 -95
- data/lib/pagy/extras/items.rb +0 -64
- data/lib/pagy/extras/materialize.rb +0 -100
- data/lib/pagy/extras/semantic.rb +0 -94
- data/lib/pagy/extras/uikit.rb +0 -98
- /data/javascripts/{pagy-module.d.ts → pagy.d.ts} +0 -0
data/lib/pagy/extras/arel.rb
CHANGED
|
@@ -7,19 +7,11 @@ class Pagy # :nodoc:
|
|
|
7
7
|
private
|
|
8
8
|
|
|
9
9
|
# Return Pagy object and paginated collection/results
|
|
10
|
-
def pagy_arel(collection, vars
|
|
11
|
-
pagy = Pagy.new(pagy_arel_get_vars(collection, vars))
|
|
10
|
+
def pagy_arel(collection, **vars)
|
|
11
|
+
pagy = Pagy.new(**pagy_arel_get_vars(collection, vars))
|
|
12
12
|
[pagy, pagy_get_items(collection, pagy)]
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
# Sub-method called only by #pagy_arel: here for easy customization of variables by overriding
|
|
16
|
-
def pagy_arel_get_vars(collection, vars)
|
|
17
|
-
pagy_set_items_from_params(vars) if defined?(ItemsExtra)
|
|
18
|
-
vars[:count] ||= pagy_arel_count(collection)
|
|
19
|
-
vars[:page] ||= pagy_get_page(vars)
|
|
20
|
-
vars
|
|
21
|
-
end
|
|
22
|
-
|
|
23
15
|
# Count using Arel when grouping
|
|
24
16
|
def pagy_arel_count(collection)
|
|
25
17
|
if collection.group_values.empty?
|
|
@@ -31,6 +23,12 @@ class Pagy # :nodoc:
|
|
|
31
23
|
collection.unscope(:order).limit(1).pluck(sql).first.to_i
|
|
32
24
|
end
|
|
33
25
|
end
|
|
26
|
+
|
|
27
|
+
# Sub-method called only by #pagy_arel: here for easy customization of variables by overriding
|
|
28
|
+
def pagy_arel_get_vars(collection, vars)
|
|
29
|
+
vars[:count] ||= pagy_arel_count(collection)
|
|
30
|
+
pagy_get_vars(collection, vars)
|
|
31
|
+
end
|
|
34
32
|
end
|
|
35
33
|
Backend.prepend ArelExtra
|
|
36
34
|
end
|
data/lib/pagy/extras/array.rb
CHANGED
|
@@ -7,17 +7,15 @@ class Pagy # :nodoc:
|
|
|
7
7
|
private
|
|
8
8
|
|
|
9
9
|
# Return Pagy object and paginated items
|
|
10
|
-
def pagy_array(array, vars
|
|
11
|
-
pagy = Pagy.new(pagy_array_get_vars(array, vars))
|
|
12
|
-
[pagy, array[pagy.offset, pagy.
|
|
10
|
+
def pagy_array(array, **vars)
|
|
11
|
+
pagy = Pagy.new(**pagy_array_get_vars(array, vars))
|
|
12
|
+
[pagy, array[pagy.offset, pagy.limit]]
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
# Sub-method called only by #pagy_array: here for easy customization of variables by overriding
|
|
16
16
|
def pagy_array_get_vars(array, vars)
|
|
17
|
-
pagy_set_items_from_params(vars) if defined?(ItemsExtra)
|
|
18
17
|
vars[:count] ||= array.size
|
|
19
|
-
|
|
20
|
-
vars
|
|
18
|
+
pagy_get_vars(array, vars)
|
|
21
19
|
end
|
|
22
20
|
end
|
|
23
21
|
Backend.prepend ArrayExtra
|
|
@@ -10,7 +10,7 @@ class Pagy # :nodoc:
|
|
|
10
10
|
# Pagination for bootstrap: it returns the html with the series of links to the pages
|
|
11
11
|
def pagy_bootstrap_nav(pagy, id: nil, classes: 'pagination', aria_label: nil, **vars)
|
|
12
12
|
id = %( id="#{id}") if id
|
|
13
|
-
a = pagy_anchor(pagy)
|
|
13
|
+
a = pagy_anchor(pagy, **vars)
|
|
14
14
|
|
|
15
15
|
html = %(<nav#{id} class="pagy-bootstrap nav" #{nav_aria_label(pagy, aria_label:)}><ul class="#{classes}">#{
|
|
16
16
|
bootstrap_prev_html(pagy, a)})
|
|
@@ -34,7 +34,7 @@ class Pagy # :nodoc:
|
|
|
34
34
|
def pagy_bootstrap_nav_js(pagy, id: nil, classes: 'pagination', aria_label: nil, **vars)
|
|
35
35
|
sequels = pagy.sequels(**vars)
|
|
36
36
|
id = %( id="#{id}") if id
|
|
37
|
-
a = pagy_anchor(pagy)
|
|
37
|
+
a = pagy_anchor(pagy, **vars)
|
|
38
38
|
tokens = { 'before' => %(<ul class="#{classes}">#{bootstrap_prev_html(pagy, a)}),
|
|
39
39
|
'a' => %(<li class="page-item">#{a.(PAGE_TOKEN, LABEL_TOKEN, classes: 'page-link')}</li>),
|
|
40
40
|
'current' => %(<li class="page-item active"><a role="link" class="page-link" ) +
|
|
@@ -50,9 +50,9 @@ class Pagy # :nodoc:
|
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
# Javascript combo pagination for bootstrap: it returns a nav with a data-pagy attribute used by the pagy.js file
|
|
53
|
-
def pagy_bootstrap_combo_nav_js(pagy, id: nil, classes: 'pagination', aria_label: nil)
|
|
53
|
+
def pagy_bootstrap_combo_nav_js(pagy, id: nil, classes: 'pagination', aria_label: nil, **vars)
|
|
54
54
|
id = %( id="#{id}") if id
|
|
55
|
-
a = pagy_anchor(pagy)
|
|
55
|
+
a = pagy_anchor(pagy, **vars)
|
|
56
56
|
pages = pagy.pages
|
|
57
57
|
|
|
58
58
|
page_input = %(<input name="page" type="number" min="1" max="#{pages}" value="#{pagy.page}" aria-current="page" ) <<
|
|
@@ -61,7 +61,7 @@ class Pagy # :nodoc:
|
|
|
61
61
|
|
|
62
62
|
%(<nav#{id} class="pagy-bootstrap combo-nav-js" #{
|
|
63
63
|
nav_aria_label(pagy, aria_label:)} #{
|
|
64
|
-
pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))
|
|
64
|
+
pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN, **vars))
|
|
65
65
|
}><ul class="#{classes}">#{
|
|
66
66
|
bootstrap_prev_html(pagy, a)
|
|
67
67
|
}<li class="page-item pagy-bootstrap"><label class="page-link">#{
|
data/lib/pagy/extras/bulma.rb
CHANGED
|
@@ -8,9 +8,10 @@ class Pagy # :nodoc:
|
|
|
8
8
|
# The resulting code may not look very elegant, but produces the best benchmarks
|
|
9
9
|
module BulmaExtra
|
|
10
10
|
# Pagination for bulma: it returns the html with the series of links to the pages
|
|
11
|
-
def pagy_bulma_nav(pagy, id: nil, classes: 'pagy-bulma nav pagination is-centered',
|
|
11
|
+
def pagy_bulma_nav(pagy, id: nil, classes: 'pagy-bulma nav pagination is-centered',
|
|
12
|
+
aria_label: nil, **vars)
|
|
12
13
|
id = %( id="#{id}") if id
|
|
13
|
-
a = pagy_anchor(pagy)
|
|
14
|
+
a = pagy_anchor(pagy, **vars)
|
|
14
15
|
|
|
15
16
|
html = %(<nav#{id} class="#{classes}" #{nav_aria_label(pagy, aria_label:)}>)
|
|
16
17
|
html << bulma_prev_next_html(pagy, a)
|
|
@@ -31,10 +32,11 @@ class Pagy # :nodoc:
|
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
# Javascript pagination for bulma: it returns a nav with a data-pagy attribute used by the Pagy.nav javascript
|
|
34
|
-
def pagy_bulma_nav_js(pagy, id: nil, classes: 'pagy-bulma nav-js pagination is-centered',
|
|
35
|
+
def pagy_bulma_nav_js(pagy, id: nil, classes: 'pagy-bulma nav-js pagination is-centered',
|
|
36
|
+
aria_label: nil, **vars)
|
|
35
37
|
sequels = pagy.sequels(**vars)
|
|
36
38
|
id = %( id="#{id}") if id
|
|
37
|
-
a = pagy_anchor(pagy)
|
|
39
|
+
a = pagy_anchor(pagy, **vars)
|
|
38
40
|
tokens = { 'before' => %(#{bulma_prev_next_html(pagy, a)}<ul class="pagination-list">),
|
|
39
41
|
'a' => %(<li>#{a.(PAGE_TOKEN, LABEL_TOKEN, classes: 'pagination-link')}</li>),
|
|
40
42
|
'current' => %(<li><a role="link" class="pagination-link is-current" aria-current="page" aria-disabled="true">#{
|
|
@@ -49,9 +51,10 @@ class Pagy # :nodoc:
|
|
|
49
51
|
end
|
|
50
52
|
|
|
51
53
|
# Javascript combo pagination for bulma: it returns a nav with a data-pagy attribute used by the pagy.js file
|
|
52
|
-
def pagy_bulma_combo_nav_js(pagy, id: nil, classes: 'pagy-bulma combo-nav-js pagination is-centered',
|
|
54
|
+
def pagy_bulma_combo_nav_js(pagy, id: nil, classes: 'pagy-bulma combo-nav-js pagination is-centered',
|
|
55
|
+
aria_label: nil, **vars)
|
|
53
56
|
id = %( id="#{id}") if id
|
|
54
|
-
a = pagy_anchor(pagy)
|
|
57
|
+
a = pagy_anchor(pagy, **vars)
|
|
55
58
|
pages = pagy.pages
|
|
56
59
|
|
|
57
60
|
page_input = %(<input name="page" type="number" min="1" max="#{pages}" value="#{pagy.page}" aria-current="page") <<
|
|
@@ -61,7 +64,7 @@ class Pagy # :nodoc:
|
|
|
61
64
|
|
|
62
65
|
%(<nav#{id} class="#{classes}" #{
|
|
63
66
|
nav_aria_label(pagy, aria_label:)} #{
|
|
64
|
-
pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))
|
|
67
|
+
pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN, **vars))
|
|
65
68
|
}>#{
|
|
66
69
|
bulma_prev_next_html(pagy, a)
|
|
67
70
|
}<ul class="pagination-list"><li class="pagination-link"><label>#{
|
data/lib/pagy/extras/calendar.rb
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
require_relative '../calendar'
|
|
5
|
-
require_relative '../calendar/helper'
|
|
6
5
|
|
|
7
6
|
class Pagy # :nodoc:
|
|
8
7
|
# Add pagination filtering by calendar unit (:year, :quarter, :month, :week, :day) to the regular pagination
|
|
@@ -20,10 +19,15 @@ class Pagy # :nodoc:
|
|
|
20
19
|
|
|
21
20
|
conf[:pagy] ||= {}
|
|
22
21
|
unless conf.key?(:active) && !conf[:active]
|
|
23
|
-
calendar, from, to = Calendar
|
|
24
|
-
|
|
22
|
+
calendar, from, to = Calendar.send(:init, conf, pagy_calendar_period(collection), params)
|
|
23
|
+
if respond_to?(:pagy_calendar_counts)
|
|
24
|
+
calendar.each_key do |unit|
|
|
25
|
+
calendar[unit].vars[:counts] = pagy_calendar_counts(collection, unit, *calendar[unit].vars[:period])
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
collection = pagy_calendar_filter(collection, from, to)
|
|
25
29
|
end
|
|
26
|
-
pagy, results = send(conf[:pagy][:backend] || :pagy, collection, conf[:pagy]) # use backend: :pagy when omitted
|
|
30
|
+
pagy, results = send(conf[:pagy][:backend] || :pagy, collection, **conf[:pagy]) # use backend: :pagy when omitted
|
|
27
31
|
[calendar, pagy, results]
|
|
28
32
|
end
|
|
29
33
|
|
|
@@ -40,6 +44,31 @@ class Pagy # :nodoc:
|
|
|
40
44
|
end
|
|
41
45
|
end
|
|
42
46
|
|
|
47
|
+
# Override the pagy_anchor
|
|
48
|
+
module FrontendOverride
|
|
49
|
+
# Consider the vars[:count]
|
|
50
|
+
def pagy_anchor(pagy, anchor_string: nil)
|
|
51
|
+
return super unless (counts = pagy.vars[:counts])
|
|
52
|
+
|
|
53
|
+
anchor_string &&= %( #{anchor_string})
|
|
54
|
+
left, right = %(<a#{anchor_string} href="#{pagy_url_for(pagy, PAGE_TOKEN)}").split(PAGE_TOKEN, 2)
|
|
55
|
+
# lambda used by all the helpers
|
|
56
|
+
lambda do |page, text = pagy.label_for(page), classes: nil, aria_label: nil|
|
|
57
|
+
count = counts[page - 1]
|
|
58
|
+
item_name = pagy_t('pagy.item_name', count:)
|
|
59
|
+
if count.zero?
|
|
60
|
+
classes = "#{classes && (classes + ' ')}empty-page"
|
|
61
|
+
title = %( title="#{pagy_t('pagy.info.no_items', item_name:, count:)}")
|
|
62
|
+
else
|
|
63
|
+
title = %( title="#{pagy_t('pagy.info.single_page', item_name:, count:)}")
|
|
64
|
+
end
|
|
65
|
+
classes = %( class="#{classes}") if classes
|
|
66
|
+
aria_label = %( aria-label="#{aria_label}") if aria_label
|
|
67
|
+
%(#{left}#{page}#{right}#{title}#{classes}#{aria_label}>#{text}</a>)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
43
72
|
# Additions for the Frontend module
|
|
44
73
|
module UrlHelperAddOn
|
|
45
74
|
# Return the url for the calendar page at time
|
|
@@ -49,5 +78,5 @@ class Pagy # :nodoc:
|
|
|
49
78
|
end
|
|
50
79
|
end
|
|
51
80
|
Backend.prepend CalendarExtra::BackendAddOn, CalendarExtra::UrlHelperAddOn
|
|
52
|
-
Frontend.prepend CalendarExtra::UrlHelperAddOn
|
|
81
|
+
Frontend.prepend CalendarExtra::UrlHelperAddOn, CalendarExtra::FrontendOverride
|
|
53
82
|
end
|
|
@@ -10,27 +10,20 @@ class Pagy # :nodoc:
|
|
|
10
10
|
module CountlessExtra
|
|
11
11
|
private
|
|
12
12
|
|
|
13
|
-
# Return Pagy object and
|
|
14
|
-
def pagy_countless(collection, vars
|
|
15
|
-
pagy = Countless.new(
|
|
13
|
+
# Return Pagy object and records
|
|
14
|
+
def pagy_countless(collection, **vars)
|
|
15
|
+
pagy = Countless.new(**pagy_get_vars(collection, vars))
|
|
16
16
|
[pagy, pagy_countless_get_items(collection, pagy)]
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
# Sub-method called only by #pagy_countless: here for easy customization of variables by overriding
|
|
20
|
-
def pagy_countless_get_vars(_collection, vars)
|
|
21
|
-
pagy_set_items_from_params(vars) if defined?(ItemsExtra)
|
|
22
|
-
vars[:page] ||= pagy_get_page(vars)
|
|
23
|
-
vars
|
|
24
|
-
end
|
|
25
|
-
|
|
26
19
|
# Sub-method called only by #pagy_countless: here for easy customization of record-extraction by overriding
|
|
27
20
|
# You may need to override this method for collections without offset|limit
|
|
28
21
|
def pagy_countless_get_items(collection, pagy)
|
|
29
|
-
return collection.offset(pagy.offset).limit(pagy.
|
|
22
|
+
return collection.offset(pagy.offset).limit(pagy.limit) if pagy.vars[:countless_minimal]
|
|
30
23
|
|
|
31
|
-
fetched = collection.offset(pagy.offset).limit(pagy.
|
|
24
|
+
fetched = collection.offset(pagy.offset).limit(pagy.limit + 1).to_a # eager load limit + 1
|
|
32
25
|
pagy.finalize(fetched.size) # finalize the pagy object
|
|
33
|
-
fetched[0, pagy.
|
|
26
|
+
fetched[0, pagy.limit] # ignore eventual extra item
|
|
34
27
|
end
|
|
35
28
|
end
|
|
36
29
|
Backend.prepend CountlessExtra
|
|
@@ -28,18 +28,18 @@ class Pagy # :nodoc:
|
|
|
28
28
|
args.define_singleton_method(:method_missing) { |*a| args += a }
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
|
-
alias_method
|
|
31
|
+
alias_method DEFAULT[:elasticsearch_rails_pagy_search], :pagy_elasticsearch_rails
|
|
32
32
|
end
|
|
33
33
|
Pagy::ElasticsearchRails = ModelExtension
|
|
34
34
|
|
|
35
35
|
# Additions for the Pagy class
|
|
36
36
|
module PagyAddOn
|
|
37
37
|
# Create a Pagy object from an Elasticsearch::Model::Response::Response object
|
|
38
|
-
def new_from_elasticsearch_rails(response, vars
|
|
39
|
-
vars[:
|
|
40
|
-
vars[:page] = ((response.search.options[:from] || 0) / vars[:
|
|
38
|
+
def new_from_elasticsearch_rails(response, **vars)
|
|
39
|
+
vars[:limit] = response.search.options[:size] || 10
|
|
40
|
+
vars[:page] = ((response.search.options[:from] || 0) / vars[:limit]) + 1
|
|
41
41
|
vars[:count] = ElasticsearchRailsExtra.total_count(response)
|
|
42
|
-
new(vars)
|
|
42
|
+
Pagy.new(**vars)
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
Pagy.extend PagyAddOn
|
|
@@ -48,19 +48,19 @@ class Pagy # :nodoc:
|
|
|
48
48
|
module BackendAddOn
|
|
49
49
|
private
|
|
50
50
|
|
|
51
|
-
# Return Pagy object and
|
|
52
|
-
def pagy_elasticsearch_rails(pagy_search_args, vars
|
|
51
|
+
# Return Pagy object and records
|
|
52
|
+
def pagy_elasticsearch_rails(pagy_search_args, **vars)
|
|
53
53
|
model, query_or_payload,
|
|
54
54
|
options, *called = pagy_search_args
|
|
55
55
|
vars = pagy_elasticsearch_rails_get_vars(nil, vars)
|
|
56
|
-
options[:size] = vars[:
|
|
57
|
-
options[:from] = vars[:
|
|
56
|
+
options[:size] = vars[:limit]
|
|
57
|
+
options[:from] = vars[:limit] * ((vars[:page] || 1) - 1)
|
|
58
58
|
response = model.send(DEFAULT[:elasticsearch_rails_search], query_or_payload, **options)
|
|
59
59
|
vars[:count] = ElasticsearchRailsExtra.total_count(response)
|
|
60
60
|
|
|
61
|
-
pagy = ::Pagy.new(vars)
|
|
61
|
+
pagy = ::Pagy.new(**vars)
|
|
62
62
|
# with :last_page overflow we need to re-run the method in order to get the hits
|
|
63
|
-
return pagy_elasticsearch_rails(pagy_search_args, vars
|
|
63
|
+
return pagy_elasticsearch_rails(pagy_search_args, **vars, page: pagy.page) \
|
|
64
64
|
if defined?(::Pagy::OverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
|
|
65
65
|
|
|
66
66
|
[pagy, called.empty? ? response : response.send(*called)]
|
|
@@ -69,10 +69,10 @@ class Pagy # :nodoc:
|
|
|
69
69
|
# Sub-method called only by #pagy_elasticsearch_rails: here for easy customization of variables by overriding
|
|
70
70
|
# the _collection argument is not available when the method is called
|
|
71
71
|
def pagy_elasticsearch_rails_get_vars(_collection, vars)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
vars.tap do |v|
|
|
73
|
+
v[:page] ||= pagy_get_page(v)
|
|
74
|
+
v[:limit] ||= pagy_get_limit(v) || DEFAULT[:limit]
|
|
75
|
+
end
|
|
76
76
|
end
|
|
77
77
|
end
|
|
78
78
|
Backend.prepend BackendAddOn
|
data/lib/pagy/extras/gearbox.rb
CHANGED
|
@@ -3,27 +3,39 @@
|
|
|
3
3
|
|
|
4
4
|
class Pagy # :nodoc:
|
|
5
5
|
DEFAULT[:gearbox_extra] = true # extra enabled by default
|
|
6
|
-
DEFAULT[:
|
|
6
|
+
DEFAULT[:gearbox_limit] = [15, 30, 60, 100]
|
|
7
7
|
|
|
8
|
-
# Automatically change the
|
|
9
|
-
# accepts an array as the :
|
|
8
|
+
# Automatically change the limit depending on the page number
|
|
9
|
+
# accepts an array as the :gearbox_limit variable, that will determine the limit for the first pages
|
|
10
10
|
module GearboxExtra
|
|
11
|
-
#
|
|
12
|
-
def
|
|
13
|
-
return super if !@vars[:gearbox_extra] || @vars[:
|
|
11
|
+
# Assign @limit based on the :gearbox_limit variable
|
|
12
|
+
def assign_limit
|
|
13
|
+
return super if !@vars[:gearbox_extra] || @vars[:limit_extra]
|
|
14
14
|
|
|
15
|
-
gears = @vars[:
|
|
16
|
-
raise VariableError.new(self, :
|
|
15
|
+
gears = @vars[:gearbox_limit]
|
|
16
|
+
raise VariableError.new(self, :gearbox_limit, 'to be an Array of positives', gears) \
|
|
17
17
|
unless gears.is_a?(Array) && gears.all? { |num| num.positive? rescue false } # rubocop:disable Style/RescueModifier
|
|
18
18
|
|
|
19
|
-
@
|
|
19
|
+
@limit = gears[@page - 1] || gears.last
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
#
|
|
23
|
-
def
|
|
24
|
-
return super if !@vars[:gearbox_extra] || @vars[:
|
|
22
|
+
# Asgnsi @offset based on the :gearbox_limit variable
|
|
23
|
+
def assign_offset
|
|
24
|
+
return super if !@vars[:gearbox_extra] || @vars[:limit_extra]
|
|
25
25
|
|
|
26
|
-
gears
|
|
26
|
+
gears = @vars[:gearbox_limit]
|
|
27
|
+
@offset = if @page <= gears.count
|
|
28
|
+
gears[0, @page - 1].sum
|
|
29
|
+
else
|
|
30
|
+
gears.sum + (gears.last * (@page - gears.count - 1))
|
|
31
|
+
end + @outset
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Assign @last based on the :gearbox_limit variable and @count
|
|
35
|
+
def assign_last
|
|
36
|
+
return super if !@vars[:gearbox_extra] || @vars[:limit_extra]
|
|
37
|
+
|
|
38
|
+
gears = @vars[:gearbox_limit]
|
|
27
39
|
# This algorithm is thousands of times faster than the one in the geared_pagination gem
|
|
28
40
|
@last = (if count > (sum = gears.sum)
|
|
29
41
|
[((count - sum).to_f / gears.last).ceil, 1].max + gears.count
|
|
@@ -36,19 +48,7 @@ class Pagy # :nodoc:
|
|
|
36
48
|
end
|
|
37
49
|
[pages, 1].max
|
|
38
50
|
end)
|
|
39
|
-
@last = vars[:max_pages] if vars[:max_pages] && @last > vars[:max_pages]
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# Setup @offset based on the :gearbox_items variable
|
|
43
|
-
def setup_offset_var
|
|
44
|
-
return super if !@vars[:gearbox_extra] || @vars[:items_extra]
|
|
45
|
-
|
|
46
|
-
gears = @vars[:gearbox_items]
|
|
47
|
-
@offset = if @page <= gears.count
|
|
48
|
-
gears[0, @page - 1].sum
|
|
49
|
-
else
|
|
50
|
-
gears.sum + (gears.last * (@page - gears.count - 1))
|
|
51
|
-
end + @outset
|
|
51
|
+
@last = @vars[:max_pages] if @vars[:max_pages] && @last > @vars[:max_pages]
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
prepend GearboxExtra
|
data/lib/pagy/extras/headers.rb
CHANGED
|
@@ -5,7 +5,7 @@ require_relative '../url_helpers'
|
|
|
5
5
|
|
|
6
6
|
class Pagy # :nodoc:
|
|
7
7
|
DEFAULT[:headers] = { page: 'current-page',
|
|
8
|
-
|
|
8
|
+
limit: 'page-items',
|
|
9
9
|
count: 'total-count',
|
|
10
10
|
pages: 'total-pages' }
|
|
11
11
|
# Add specialized backend methods to add pagination response headers
|
|
@@ -21,32 +21,33 @@ class Pagy # :nodoc:
|
|
|
21
21
|
|
|
22
22
|
# Generate a hash of RFC-8288 compliant http headers
|
|
23
23
|
def pagy_headers(pagy)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
headers = pagy.vars[:headers]
|
|
25
|
+
{ 'link' => link(pagy) }.tap do |hash|
|
|
26
|
+
hash[headers[:page]] = pagy.page.to_s if pagy.page && headers[:page]
|
|
27
|
+
hash[headers[:limit]] = pagy.limit.to_s \
|
|
28
|
+
if headers[:limit] && !(defined?(Calendar) && pagy.is_a?(Calendar::Unit))
|
|
29
|
+
return hash if (defined?(Countless) && pagy.is_a?(Countless)) || \
|
|
30
|
+
(defined?(Keyset) && pagy.is_a?(Keyset))
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
def pagy_headers_hash(pagy)
|
|
31
|
-
countless = defined?(Countless) && pagy.is_a?(Countless)
|
|
32
|
-
rel = { 'first' => 1, 'prev' => pagy.prev, 'next' => pagy.next }
|
|
33
|
-
rel['last'] = pagy.last unless countless
|
|
34
|
-
url_str = pagy_url_for(pagy, PAGE_TOKEN, absolute: true)
|
|
35
|
-
link = rel.filter_map do |r, num|
|
|
36
|
-
next unless num # rubocop:disable Layout/EmptyLineAfterGuardClause
|
|
37
|
-
[r, url_str.sub(PAGE_TOKEN, num.to_s)]
|
|
38
|
-
end.compact.to_h
|
|
39
|
-
hash = { 'link' => link }
|
|
40
|
-
headers = pagy.vars[:headers]
|
|
41
|
-
hash[headers[:page]] = pagy.page.to_s if headers[:page]
|
|
42
|
-
if headers[:items] && !(defined?(Calendar) && pagy.is_a?(Calendar)) # items is not for Calendar
|
|
43
|
-
hash[headers[:items]] = pagy.vars[:items].to_s
|
|
44
|
-
end
|
|
45
|
-
unless countless
|
|
46
|
-
hash[headers[:pages]] = pagy.pages.to_s if headers[:pages]
|
|
32
|
+
hash[headers[:pages]] = pagy.last.to_s if headers[:pages]
|
|
47
33
|
hash[headers[:count]] = pagy.count.to_s if pagy.count && headers[:count] # count may be nil with Calendar
|
|
48
34
|
end
|
|
49
|
-
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def link(pagy)
|
|
38
|
+
[].tap do |link|
|
|
39
|
+
if defined?(Keyset) && pagy.is_a?(Keyset)
|
|
40
|
+
link << %(<#{pagy_url_for(pagy, nil, absolute: true)}>; rel="first")
|
|
41
|
+
link << %(<#{pagy_url_for(pagy, pagy.next, absolute: true)}>; rel="next") if pagy.next
|
|
42
|
+
else
|
|
43
|
+
url_str = pagy_url_for(pagy, PAGE_TOKEN, absolute: true)
|
|
44
|
+
link << %(<#{url_str.sub(PAGE_TOKEN, '1')}>; rel="first")
|
|
45
|
+
link << %(<#{url_str.sub(PAGE_TOKEN, pagy.prev.to_s)}>; rel="prev") if pagy.prev
|
|
46
|
+
link << %(<#{url_str.sub(PAGE_TOKEN, pagy.next.to_s)}>; rel="next") if pagy.next
|
|
47
|
+
link << %(<#{url_str.sub(PAGE_TOKEN, pagy.last.to_s)}>; rel="last") \
|
|
48
|
+
unless defined?(Countless) && pagy.is_a?(Countless)
|
|
49
|
+
end
|
|
50
|
+
end.join(', ')
|
|
50
51
|
end
|
|
51
52
|
end
|
|
52
53
|
Backend.prepend HeadersExtra
|
data/lib/pagy/extras/i18n.rb
CHANGED
|
@@ -19,7 +19,7 @@ class Pagy # :nodoc:
|
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
|
-
Calendar.prepend I18nExtra::CalendarOverride if defined?(Calendar)
|
|
22
|
+
Calendar::Unit.prepend I18nExtra::CalendarOverride if defined?(Calendar::Unit)
|
|
23
23
|
|
|
24
24
|
# Add the pagy locales to the I18n.load_path
|
|
25
25
|
::I18n.load_path += Dir[Pagy.root.join('locales', '*.yml')]
|
data/lib/pagy/extras/js_tools.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require_relative '../b64'
|
|
4
|
+
|
|
3
5
|
class Pagy # :nodoc:
|
|
4
6
|
DEFAULT[:steps] = false # default false will use {0 => @vars[:size]}
|
|
5
7
|
|
|
@@ -13,11 +15,11 @@ class Pagy # :nodoc:
|
|
|
13
15
|
# `Pagy` instance method used by the `pagy*_nav_js` helpers.
|
|
14
16
|
# It returns the sequels of width/series generated from the :steps hash
|
|
15
17
|
# Example:
|
|
16
|
-
# >> pagy = Pagy.new(count:1000, page: 20, steps: {0 =>
|
|
18
|
+
# >> pagy = Pagy.new(count:1000, page: 20, steps: {0 => 5, 350 => 7, 550 => 9})
|
|
17
19
|
# >> pagy.sequels
|
|
18
|
-
# #=> { "0" => [
|
|
19
|
-
# "350" => [1,
|
|
20
|
-
# "550" => [1
|
|
20
|
+
# #=> { "0" => [18, 19, "20", 21, 22],
|
|
21
|
+
# "350" => [1, :gap, 19, "20", 21, :gap, 50],
|
|
22
|
+
# "550" => [1 :gap, 18, 19, "20", 21, 22, :gap, 50] }
|
|
21
23
|
# Notice: if :steps is false it will use the single {0 => @vars[:size]} size
|
|
22
24
|
def sequels(steps: @vars[:steps] || { 0 => @vars[:size] }, **_)
|
|
23
25
|
raise VariableError.new(self, :steps, 'to define the 0 width', steps) unless steps.key?(0)
|
|
@@ -42,7 +44,7 @@ class Pagy # :nodoc:
|
|
|
42
44
|
end
|
|
43
45
|
end
|
|
44
46
|
end
|
|
45
|
-
Calendar.prepend CalendarOverride if defined?(Calendar)
|
|
47
|
+
Calendar::Unit.prepend CalendarOverride if defined?(Calendar::Unit)
|
|
46
48
|
|
|
47
49
|
# Additions for the Frontend
|
|
48
50
|
module FrontendAddOn
|
|
@@ -51,8 +53,7 @@ class Pagy # :nodoc:
|
|
|
51
53
|
# Base64 encoded JSON is smaller than HTML escaped JSON
|
|
52
54
|
def pagy_data(pagy, *args)
|
|
53
55
|
args << pagy.vars[:page_param] if pagy.vars[:trim_extra]
|
|
54
|
-
|
|
55
|
-
%(data-pagy="#{strict_base64_encoded}")
|
|
56
|
+
%(data-pagy="#{B64.encode(Oj.dump(args, mode: :strict))}")
|
|
56
57
|
end
|
|
57
58
|
else
|
|
58
59
|
require 'json'
|
|
@@ -60,8 +61,7 @@ class Pagy # :nodoc:
|
|
|
60
61
|
# Base64 encoded JSON is smaller than HTML escaped JSON
|
|
61
62
|
def pagy_data(pagy, *args)
|
|
62
63
|
args << pagy.vars[:page_param] if pagy.vars[:trim_extra]
|
|
63
|
-
|
|
64
|
-
%(data-pagy="#{strict_base64_encoded}")
|
|
64
|
+
%(data-pagy="#{B64.encode(args.to_json)}")
|
|
65
65
|
end
|
|
66
66
|
end
|
|
67
67
|
end
|
data/lib/pagy/extras/jsonapi.rb
CHANGED
|
@@ -24,10 +24,17 @@ class Pagy # :nodoc:
|
|
|
24
24
|
|
|
25
25
|
# Return the jsonapi links
|
|
26
26
|
def pagy_jsonapi_links(pagy, **opts)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
if defined?(Pagy::Keyset) && pagy.is_a?(Pagy::Keyset)
|
|
28
|
+
{ first: pagy_url_for(pagy, nil, **opts),
|
|
29
|
+
last: nil,
|
|
30
|
+
prev: nil,
|
|
31
|
+
next: pagy.next ? pagy_url_for(pagy, pagy.next, **opts) : nil }
|
|
32
|
+
else
|
|
33
|
+
{ first: pagy_url_for(pagy, 1, **opts),
|
|
34
|
+
last: pagy_url_for(pagy, pagy.last, **opts),
|
|
35
|
+
prev: pagy.prev ? pagy_url_for(pagy, pagy.prev, **opts) : nil,
|
|
36
|
+
next: pagy.next ? pagy_url_for(pagy, pagy.next, **opts) : nil }
|
|
37
|
+
end
|
|
31
38
|
end
|
|
32
39
|
|
|
33
40
|
# Should skip the jsonapi
|
|
@@ -40,38 +47,41 @@ class Pagy # :nodoc:
|
|
|
40
47
|
# Override the Backend method
|
|
41
48
|
def pagy_get_page(vars)
|
|
42
49
|
return super if pagy_skip_jsonapi?(vars)
|
|
43
|
-
return
|
|
50
|
+
return if params[:page].nil?
|
|
44
51
|
|
|
45
|
-
|
|
52
|
+
params[:page][vars[:page_param] || DEFAULT[:page_param]]
|
|
46
53
|
end
|
|
47
54
|
end
|
|
48
55
|
Backend.prepend BackendOverride
|
|
49
56
|
|
|
50
|
-
# Module overriding
|
|
51
|
-
module
|
|
57
|
+
# Module overriding LimitExtra
|
|
58
|
+
module LimitExtraOverride
|
|
52
59
|
private
|
|
53
60
|
|
|
54
|
-
# Override the
|
|
55
|
-
def
|
|
61
|
+
# Override the LimitExtra::Backend method
|
|
62
|
+
def pagy_get_limit_param(vars)
|
|
56
63
|
return super if pagy_skip_jsonapi?(vars)
|
|
57
64
|
return if params[:page].nil?
|
|
58
65
|
|
|
59
|
-
params[:page][vars[:
|
|
66
|
+
params[:page][vars[:limit_param] || DEFAULT[:limit_param]]
|
|
60
67
|
end
|
|
61
68
|
end
|
|
62
69
|
# :nocov:
|
|
63
|
-
|
|
70
|
+
LimitExtra::BackendAddOn.prepend LimitExtraOverride if defined?(LimitExtra::BackendAddOn)
|
|
64
71
|
# :nocov:
|
|
65
72
|
|
|
66
73
|
# Module overriding UrlHelper
|
|
67
74
|
module UrlHelperOverride
|
|
68
75
|
# Override UrlHelper method
|
|
69
|
-
def pagy_set_query_params(page, vars,
|
|
76
|
+
def pagy_set_query_params(page, vars, query_params)
|
|
70
77
|
return super unless vars[:jsonapi]
|
|
71
78
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
79
|
+
query_params['page'] ||= {}
|
|
80
|
+
query_params['page'][vars[:page_param].to_s] = page if page
|
|
81
|
+
query_params['page'][vars[:limit_param].to_s] = vars[:limit] if vars[:limit_extra]
|
|
82
|
+
# :nocov:
|
|
83
|
+
query_params.delete(:page) if query_params['page'].empty?
|
|
84
|
+
# :nocov:
|
|
75
85
|
end
|
|
76
86
|
end
|
|
77
87
|
UrlHelpers.prepend UrlHelperOverride
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/keyset
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require_relative '../keyset'
|
|
5
|
+
|
|
6
|
+
class Pagy # :nodoc:
|
|
7
|
+
# Add keyset pagination
|
|
8
|
+
module KeysetExtra
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
# Return Pagy::Keyset object and paginated records
|
|
12
|
+
def pagy_keyset(set, **vars)
|
|
13
|
+
pagy = Keyset.new(set, **pagy_keyset_get_vars(vars))
|
|
14
|
+
[pagy, pagy.records]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Sub-method called only by #pagy_keyset: here for easy customization of variables by overriding
|
|
18
|
+
def pagy_keyset_get_vars(vars)
|
|
19
|
+
vars.tap do |v|
|
|
20
|
+
v[:page] ||= pagy_get_page(v)
|
|
21
|
+
v[:limit] ||= pagy_get_limit(v)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
Backend.prepend KeysetExtra
|
|
26
|
+
end
|