pagy 43.0.7 → 43.1.1
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 +1 -1
- data/apps/demo.ru +1 -1
- data/apps/keynav+root_key.ru +321 -0
- data/apps/keynav.ru +3 -1
- data/apps/keyset.ru +1 -1
- data/apps/keyset_sequel.ru +1 -1
- data/apps/rails.ru +1 -1
- data/apps/repro.ru +1 -1
- data/bin/pagy +1 -1
- data/config/pagy.rb +1 -1
- data/javascripts/ai_widget.js +1 -1
- data/javascripts/pagy.js +11 -10
- data/javascripts/pagy.js.map +3 -3
- data/javascripts/pagy.min.js +1 -1
- data/javascripts/pagy.mjs +10 -9
- data/lib/pagy/classes/exceptions.rb +0 -8
- data/lib/pagy/classes/keyset/keynav.rb +1 -1
- data/lib/pagy/classes/request.rb +14 -15
- data/lib/pagy/modules/abilities/linkable.rb +12 -15
- data/lib/pagy/modules/console.rb +2 -16
- data/lib/pagy/modules/searcher.rb +5 -7
- data/lib/pagy/toolbox/helpers/support/a_lambda.rb +1 -1
- data/lib/pagy/toolbox/paginators/calendar.rb +0 -1
- data/lib/pagy/toolbox/paginators/countless.rb +11 -14
- data/lib/pagy/toolbox/paginators/elasticsearch_rails.rb +16 -19
- data/lib/pagy/toolbox/paginators/keynav_js.rb +13 -16
- data/lib/pagy/toolbox/paginators/keyset.rb +6 -9
- data/lib/pagy/toolbox/paginators/meilisearch.rb +16 -19
- data/lib/pagy/toolbox/paginators/method.rb +10 -3
- data/lib/pagy/toolbox/paginators/offset.rb +7 -10
- data/lib/pagy/toolbox/paginators/searchkick.rb +16 -19
- data/lib/pagy.rb +5 -3
- data/locales/id.yml +1 -3
- data/locales/ja.yml +1 -3
- data/locales/km.yml +1 -3
- data/locales/sw.yml +2 -2
- metadata +2 -1
data/javascripts/pagy.mjs
CHANGED
|
@@ -23,18 +23,18 @@ const Pagy = (() => {
|
|
|
23
23
|
}));
|
|
24
24
|
const B64SafeEncode = (unicode) => btoa(String.fromCharCode(...new TextEncoder().encode(unicode))).replace(/[+/=]/g, (m) => m == "+" ? "-" : m == "/" ? "_" : ""), B64Decode = (base64) => new TextDecoder().decode(Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)));
|
|
25
25
|
const randKey = () => Math.floor(Math.random() * 36 ** 3).toString(36);
|
|
26
|
-
const augmentKeynav = async (nav, [storageKey, pageKey, last, spliceArgs]) => {
|
|
27
|
-
let
|
|
26
|
+
const augmentKeynav = async (nav, [storageKey, rootKey, pageKey, last, spliceArgs]) => {
|
|
27
|
+
let augmentPage;
|
|
28
28
|
const browserKey = document.cookie.split(/;\s+/).find((row) => row.startsWith(pagy + "="))?.split("=")[1] ?? randKey();
|
|
29
29
|
document.cookie = pagy + "=" + browserKey;
|
|
30
30
|
if (storageKey && !(storageKey in storage)) {
|
|
31
31
|
sync.postMessage({ from: tabId, key: storageKey });
|
|
32
32
|
await new Promise((resolve) => setTimeout(() => resolve(""), 100));
|
|
33
33
|
if (!(storageKey in storage)) {
|
|
34
|
-
|
|
34
|
+
augmentPage = (page) => page + "+" + last;
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
if (!
|
|
37
|
+
if (!augmentPage) {
|
|
38
38
|
if (!storageKey) {
|
|
39
39
|
do {
|
|
40
40
|
storageKey = randKey();
|
|
@@ -45,7 +45,7 @@ const Pagy = (() => {
|
|
|
45
45
|
cutoffs.splice(...spliceArgs);
|
|
46
46
|
storage.setItem(storageKey, JSON.stringify(cutoffs));
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
augmentPage = (page) => {
|
|
49
49
|
const pageNum = parseInt(page);
|
|
50
50
|
return B64SafeEncode(JSON.stringify([
|
|
51
51
|
browserKey,
|
|
@@ -57,11 +57,12 @@ const Pagy = (() => {
|
|
|
57
57
|
]));
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
|
+
const search = rootKey ? `${rootKey}%5B${pageKey}%5D` : pageKey;
|
|
61
|
+
const re = new RegExp(`(?<=\\?.*)(\\b${search}=)(\\d+)`);
|
|
60
62
|
for (const a of nav.querySelectorAll("a[href]")) {
|
|
61
|
-
|
|
62
|
-
a.href = url.replace(re, pageKey + "=" + augment(url.match(re)[1]));
|
|
63
|
+
a.href = a.href.replace(re, (_match, prefix, digit) => `${prefix}${augmentPage(digit)}`);
|
|
63
64
|
}
|
|
64
|
-
return
|
|
65
|
+
return augmentPage;
|
|
65
66
|
};
|
|
66
67
|
const buildNavJs = (nav, [
|
|
67
68
|
[before, anchor, current, gap, after],
|
|
@@ -123,7 +124,7 @@ const Pagy = (() => {
|
|
|
123
124
|
});
|
|
124
125
|
};
|
|
125
126
|
return {
|
|
126
|
-
version: "43.
|
|
127
|
+
version: "43.1.1",
|
|
127
128
|
init(arg) {
|
|
128
129
|
const target = arg instanceof HTMLElement ? arg : document, elements = target.querySelectorAll("[data-pagy]");
|
|
129
130
|
for (const element of elements) {
|
|
@@ -22,12 +22,4 @@ class Pagy
|
|
|
22
22
|
|
|
23
23
|
# Generic internal error
|
|
24
24
|
class InternalError < StandardError; end
|
|
25
|
-
|
|
26
|
-
# JsonApi :page param error
|
|
27
|
-
class JsonapiReservedParamError < StandardError
|
|
28
|
-
# Inform about the actual value
|
|
29
|
-
def initialize(value)
|
|
30
|
-
super("expected reserved :page param to be nil or Hash-like; got #{value.inspect}")
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
25
|
end
|
data/lib/pagy/classes/request.rb
CHANGED
|
@@ -1,37 +1,36 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Pagy
|
|
4
|
-
# Decouple the
|
|
5
|
-
# Resolve :page and :limit
|
|
6
|
-
#
|
|
4
|
+
# Decouple the request from the env, allowing non-rack apps to use pagy by passing a hash.
|
|
5
|
+
# Resolve the :page and :limit options from params.
|
|
7
6
|
class Request
|
|
8
|
-
def initialize(
|
|
7
|
+
def initialize(options) # default empty options for test only
|
|
8
|
+
@options = options
|
|
9
|
+
request = @options[:request]
|
|
9
10
|
@base_url, @path, @params, @cookie =
|
|
10
11
|
if request.is_a?(Hash)
|
|
11
12
|
request.values_at(:base_url, :path, :params, :cookie)
|
|
12
13
|
else
|
|
13
14
|
[request.base_url, request.path, request.GET.merge(request.POST), request.cookies['pagy']]
|
|
14
15
|
end
|
|
15
|
-
@jsonapi = @params['page'] && options[:jsonapi]
|
|
16
|
-
raise JsonapiReservedParamError, @params['page'] if @jsonapi && !@params['page'].respond_to?(:fetch)
|
|
17
16
|
end
|
|
18
17
|
|
|
19
18
|
attr_reader :base_url, :path, :params, :cookie
|
|
20
19
|
|
|
21
|
-
def resolve_page(
|
|
22
|
-
page_key = options[:page_key] || DEFAULT[:page_key]
|
|
23
|
-
page = @
|
|
20
|
+
def resolve_page(force_integer: true)
|
|
21
|
+
page_key = @options[:page_key] || DEFAULT[:page_key]
|
|
22
|
+
page = @params.dig(@options[:root_key], page_key) || @params[page_key]
|
|
24
23
|
page = nil if page == '' # fix for app-generated queries like ?page=
|
|
25
24
|
force_integer ? (page || 1).to_i : page
|
|
26
25
|
end
|
|
27
26
|
|
|
28
|
-
def resolve_limit
|
|
29
|
-
limit_key = options[:limit_key] || DEFAULT[:limit_key]
|
|
30
|
-
return options[:limit] || DEFAULT[:limit] \
|
|
31
|
-
unless options[:client_max_limit] &&
|
|
32
|
-
(requested_limit = @
|
|
27
|
+
def resolve_limit
|
|
28
|
+
limit_key = @options[:limit_key] || DEFAULT[:limit_key]
|
|
29
|
+
return @options[:limit] || DEFAULT[:limit] \
|
|
30
|
+
unless @options[:client_max_limit] &&
|
|
31
|
+
(requested_limit = @params.dig(@options[:root_key], limit_key) || @params[limit_key])
|
|
33
32
|
|
|
34
|
-
[requested_limit.to_i, options[:client_max_limit]].min
|
|
33
|
+
[requested_limit.to_i, @options[:client_max_limit]].min
|
|
35
34
|
end
|
|
36
35
|
end
|
|
37
36
|
end
|
|
@@ -9,25 +9,22 @@ class Pagy
|
|
|
9
9
|
module_function
|
|
10
10
|
|
|
11
11
|
# Extracted from Rack::Utils and reformatted for rubocop
|
|
12
|
-
#
|
|
13
|
-
|
|
14
|
-
def build_nested_query(value, prefix = nil, unescaped = [])
|
|
12
|
+
# Skip escaping for Pagy::RawQueryValue
|
|
13
|
+
def build_nested_query(value, prefix = nil)
|
|
15
14
|
case value
|
|
16
15
|
when Array
|
|
17
|
-
value.map { |v| build_nested_query(v, "#{prefix}[]"
|
|
16
|
+
value.map { |v| build_nested_query(v, "#{prefix}[]") }.join('&')
|
|
18
17
|
when Hash
|
|
19
18
|
value.map do |k, v|
|
|
20
|
-
|
|
21
|
-
unescaped[unescaped.find_index(k)] = new_k if unescaped.size.positive? && new_k != k && unescaped.include?(k)
|
|
22
|
-
build_nested_query(v, new_k, unescaped)
|
|
19
|
+
build_nested_query(v, prefix ? "#{prefix}[#{k}]" : k)
|
|
23
20
|
end.delete_if(&:empty?).join('&')
|
|
24
21
|
when nil
|
|
25
22
|
escape(prefix)
|
|
26
23
|
else
|
|
27
24
|
raise ArgumentError, 'value must be a Hash' if prefix.nil?
|
|
28
|
-
return "#{escape(prefix)}=#{value}" if unescaped.include?(prefix)
|
|
29
25
|
|
|
30
|
-
|
|
26
|
+
final_value = value.is_a?(RawQueryValue) ? value.to_s : escape(value)
|
|
27
|
+
"#{escape(prefix)}=#{final_value}"
|
|
31
28
|
end
|
|
32
29
|
end
|
|
33
30
|
|
|
@@ -40,18 +37,18 @@ class Pagy
|
|
|
40
37
|
|
|
41
38
|
# Return the URL for the page, relying on the Pagy::Request
|
|
42
39
|
def compose_page_url(page, limit_token: nil, **options)
|
|
43
|
-
|
|
40
|
+
root_key, page_key, limit_key, limit, client_max_limit, querify, absolute, path, fragment =
|
|
44
41
|
@options.merge(options)
|
|
45
|
-
.values_at(:
|
|
42
|
+
.values_at(:root_key, :page_key, :limit_key, :limit, :client_max_limit, :querify, :absolute, :path, :fragment)
|
|
46
43
|
params = @request.params.clone(freeze: false)
|
|
47
|
-
params.delete(
|
|
44
|
+
params.delete(root_key || page_key)
|
|
48
45
|
factors = {}.tap do |h|
|
|
49
|
-
h[page_key] = countless? ? "#{page || 1}+#{@last}" : page
|
|
46
|
+
h[page_key] = countless? ? RawQueryValue.new("#{page || 1}+#{@last}") : page
|
|
50
47
|
h[limit_key] = limit_token || limit if client_max_limit
|
|
51
48
|
end.compact # No empty params
|
|
52
|
-
params.merge!(
|
|
49
|
+
params.merge!(root_key ? { root_key => factors } : factors) if factors.size.positive?
|
|
53
50
|
querify&.(params) # Must modify the params: the returned value is ignored
|
|
54
|
-
query_string = QueryUtils.build_nested_query(params
|
|
51
|
+
query_string = QueryUtils.build_nested_query(params)
|
|
55
52
|
query_string = "?#{query_string}" unless query_string.empty?
|
|
56
53
|
fragment &&= %(##{fragment}) unless fragment&.start_with?('#')
|
|
57
54
|
"#{@request.base_url if absolute}#{path || @request.path}#{query_string}#{fragment}"
|
data/lib/pagy/modules/console.rb
CHANGED
|
@@ -3,20 +3,6 @@
|
|
|
3
3
|
class Pagy
|
|
4
4
|
# Provide a ready to use pagy environment when included in irb/rails console
|
|
5
5
|
module Console
|
|
6
|
-
class Request
|
|
7
|
-
attr_accessor :base_url, :path, :params
|
|
8
|
-
|
|
9
|
-
def initialize
|
|
10
|
-
@base_url = 'http://www.example.com'
|
|
11
|
-
@path = '/path'
|
|
12
|
-
@params = { example: '123' }
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def GET = @params # rubocop:disable Naming/MethodName
|
|
16
|
-
|
|
17
|
-
def cookies = {}
|
|
18
|
-
end
|
|
19
|
-
|
|
20
6
|
class Collection < Array
|
|
21
7
|
def initialize(arr = Array(1..1000))
|
|
22
8
|
super
|
|
@@ -31,8 +17,8 @@ class Pagy
|
|
|
31
17
|
include Method
|
|
32
18
|
|
|
33
19
|
# Direct reference to request.params via a method
|
|
34
|
-
def
|
|
35
|
-
def
|
|
20
|
+
def request = @request ||= { base_url: 'http://www.example.com', path: '/path', params: { example: '123' } }
|
|
21
|
+
def params = request[:params]
|
|
36
22
|
def collection = Collection
|
|
37
23
|
end
|
|
38
24
|
end
|
|
@@ -6,13 +6,11 @@ class Pagy
|
|
|
6
6
|
module_function
|
|
7
7
|
|
|
8
8
|
# Common search logic
|
|
9
|
-
def wrap(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
pagy, results = yield
|
|
15
|
-
calling = pagy_search_args[4..]
|
|
9
|
+
def wrap(pagy_search_args, options)
|
|
10
|
+
options[:page] ||= options[:request].resolve_page
|
|
11
|
+
options[:limit] = options[:request].resolve_limit
|
|
12
|
+
pagy, results = yield
|
|
13
|
+
calling = pagy_search_args[4..]
|
|
16
14
|
[pagy, calling.empty? ? results : results.send(*calling)]
|
|
17
15
|
end
|
|
18
16
|
end
|
|
@@ -18,7 +18,7 @@ class Pagy
|
|
|
18
18
|
%( #{anchor_string}) if anchor_string}).split(PAGE_TOKEN, 2)
|
|
19
19
|
|
|
20
20
|
lambda do |page, text = page_label(page), classes: nil, aria_label: nil|
|
|
21
|
-
title = if (counts = @options[:counts]) # only for calendar
|
|
21
|
+
title = if (counts = @options[:counts]) # only for calendar with counts
|
|
22
22
|
count = counts[page - 1]
|
|
23
23
|
classes = classes ? "#{classes} empty-page" : 'empty-page' if count.zero?
|
|
24
24
|
info_key = count.zero? ? 'pagy.info_tag.no_items' : 'pagy.info_tag.single_page'
|
|
@@ -11,7 +11,6 @@ class Pagy
|
|
|
11
11
|
raise ArgumentError, "keys must be in #{allowed_options.inspect}" \
|
|
12
12
|
unless config.is_a?(Hash) && (config.keys - allowed_options).empty?
|
|
13
13
|
|
|
14
|
-
config[:request] = Request.new(config[:request] || request)
|
|
15
14
|
config[:offset] ||= {}
|
|
16
15
|
unless config[:disabled]
|
|
17
16
|
calendar, from, to =
|
|
@@ -4,22 +4,19 @@ class Pagy
|
|
|
4
4
|
module CountlessPaginator
|
|
5
5
|
module_function
|
|
6
6
|
|
|
7
|
-
# Return
|
|
8
|
-
def paginate(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if
|
|
12
|
-
|
|
13
|
-
if
|
|
14
|
-
|
|
15
|
-
options[:page] = p if p.positive?
|
|
16
|
-
options[:last] = l if l&.positive?
|
|
17
|
-
end
|
|
7
|
+
# Return the Offset::Countless instance and records
|
|
8
|
+
def paginate(collection, options)
|
|
9
|
+
if options[:page].nil?
|
|
10
|
+
page = options[:request].resolve_page(force_integer: false) # accept nil and strings
|
|
11
|
+
if page.is_a?(String)
|
|
12
|
+
p, l = page.split(/ /, 2).map(&:to_i) # decoded '+' added by the compose_page_url
|
|
13
|
+
options[:page] = p if p.positive?
|
|
14
|
+
options[:last] = l if l&.positive?
|
|
18
15
|
end
|
|
19
|
-
options[:limit] = request.resolve_limit(options)
|
|
20
|
-
pagy = Offset::Countless.new(**options, request:)
|
|
21
|
-
[pagy, pagy.records(collection)]
|
|
22
16
|
end
|
|
17
|
+
options[:limit] = options[:request].resolve_limit
|
|
18
|
+
pagy = Offset::Countless.new(**options)
|
|
19
|
+
[pagy, pagy.records(collection)]
|
|
23
20
|
end
|
|
24
21
|
end
|
|
25
22
|
end
|
|
@@ -7,26 +7,23 @@ class Pagy
|
|
|
7
7
|
module_function
|
|
8
8
|
|
|
9
9
|
# Paginate from the search object
|
|
10
|
-
def paginate(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
options[:count] = ElasticsearchRails.total_count(results)
|
|
21
|
-
[ElasticsearchRails.new(**options), results]
|
|
22
|
-
end
|
|
23
|
-
else
|
|
24
|
-
# The search is an elasticsearch_rails response
|
|
25
|
-
options[:limit] = search.search.options[:size] || 10
|
|
26
|
-
options[:page] = ((search.search.options[:from] || 0) / options[:limit]) + 1
|
|
27
|
-
options[:count] = ElasticsearchRails.total_count(search)
|
|
28
|
-
ElasticsearchRails.new(**options)
|
|
10
|
+
def paginate(search, options)
|
|
11
|
+
if search.is_a?(Search::Arguments)
|
|
12
|
+
# The search is the array of pagy_search arguments
|
|
13
|
+
Searcher.wrap(search, options) do
|
|
14
|
+
model, query_or_payload, search_options = search
|
|
15
|
+
search_options[:size] = options[:limit]
|
|
16
|
+
search_options[:from] = options[:limit] * ((options[:page] || 1) - 1)
|
|
17
|
+
results = model.send(ElasticsearchRails::DEFAULT[:search_method], query_or_payload, **search_options)
|
|
18
|
+
options[:count] = ElasticsearchRails.total_count(results)
|
|
19
|
+
[ElasticsearchRails.new(**options), results]
|
|
29
20
|
end
|
|
21
|
+
else
|
|
22
|
+
# The search is an elasticsearch_rails response
|
|
23
|
+
options[:limit] = search.search.options[:size] || 10
|
|
24
|
+
options[:page] = ((search.search.options[:from] || 0) / options[:limit]) + 1
|
|
25
|
+
options[:count] = ElasticsearchRails.total_count(search)
|
|
26
|
+
ElasticsearchRails.new(**options)
|
|
30
27
|
end
|
|
31
28
|
end
|
|
32
29
|
end
|
|
@@ -6,24 +6,21 @@ class Pagy
|
|
|
6
6
|
module KeynavJsPaginator
|
|
7
7
|
module_function
|
|
8
8
|
|
|
9
|
-
# Return Pagy::Keyset::Keynav
|
|
9
|
+
# Return the Pagy::Keyset::Keynav instance and paginated records.
|
|
10
10
|
# Fall back to :countless if the :page has no client data.
|
|
11
|
-
def paginate(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
# Restart the pagination from page 1 if the url has been requested from another browser
|
|
20
|
-
options[:page] = page_arguments if request.cookie == page_arguments.shift
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
options[:limit] = request.resolve_limit(options)
|
|
24
|
-
pagy = Keyset::Keynav.new(set, **options, request:)
|
|
25
|
-
[pagy, pagy.records]
|
|
11
|
+
def paginate(set, options)
|
|
12
|
+
page = options[:request].resolve_page(force_integer: false) # allow nil
|
|
13
|
+
if page&.match(' ') # countless page -> no augmentation -> fallback
|
|
14
|
+
return CountlessPaginator.paginate(set, page:, **options)
|
|
15
|
+
elsif page.is_a?(String) # keynav page param
|
|
16
|
+
page_arguments = JSON.parse(B64.urlsafe_decode(page))
|
|
17
|
+
# Restart the pagination from page 1/nil if the url has been requested from another browser
|
|
18
|
+
options[:page] = page_arguments if options[:request].cookie == page_arguments.shift
|
|
26
19
|
end
|
|
20
|
+
|
|
21
|
+
options[:limit] = options[:request].resolve_limit
|
|
22
|
+
pagy = Keyset::Keynav.new(set, **options)
|
|
23
|
+
[pagy, pagy.records]
|
|
27
24
|
end
|
|
28
25
|
end
|
|
29
26
|
end
|
|
@@ -4,15 +4,12 @@ class Pagy
|
|
|
4
4
|
module KeysetPaginator
|
|
5
5
|
module_function
|
|
6
6
|
|
|
7
|
-
# Return Pagy::Keyset
|
|
8
|
-
def paginate(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
pagy = Keyset.new(set, **options, request:)
|
|
14
|
-
[pagy, pagy.records]
|
|
15
|
-
end
|
|
7
|
+
# Return Pagy::Keyset instance and paginated records
|
|
8
|
+
def paginate(set, options)
|
|
9
|
+
options[:page] ||= options[:request].resolve_page(force_integer: false) # allow nil
|
|
10
|
+
options[:limit] = options[:request].resolve_limit
|
|
11
|
+
pagy = Keyset.new(set, **options)
|
|
12
|
+
[pagy, pagy.records]
|
|
16
13
|
end
|
|
17
14
|
end
|
|
18
15
|
end
|
|
@@ -7,26 +7,23 @@ class Pagy
|
|
|
7
7
|
module_function
|
|
8
8
|
|
|
9
9
|
# Paginate from the search object
|
|
10
|
-
def paginate(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
options[:count] = results.raw_answer['totalHits']
|
|
21
|
-
[Meilisearch.new(**options), results]
|
|
22
|
-
end
|
|
23
|
-
else
|
|
24
|
-
# The search is a meilisearch results object
|
|
25
|
-
options[:limit] = search.raw_answer['hitsPerPage']
|
|
26
|
-
options[:page] = search.raw_answer['page']
|
|
27
|
-
options[:count] = search.raw_answer['totalHits']
|
|
28
|
-
Meilisearch.new(**options)
|
|
10
|
+
def paginate(search, options)
|
|
11
|
+
if search.is_a?(Search::Arguments)
|
|
12
|
+
# The search is the array of pagy_search arguments
|
|
13
|
+
Searcher.wrap(search, options) do
|
|
14
|
+
model, term, search_options = search
|
|
15
|
+
search_options[:hits_per_page] = options[:limit]
|
|
16
|
+
search_options[:page] = options[:page]
|
|
17
|
+
results = model.send(Meilisearch::DEFAULT[:search_method], term, search_options)
|
|
18
|
+
options[:count] = results.raw_answer['totalHits']
|
|
19
|
+
[Meilisearch.new(**options), results]
|
|
29
20
|
end
|
|
21
|
+
else
|
|
22
|
+
# The search is a meilisearch results object
|
|
23
|
+
options[:limit] = search.raw_answer['hitsPerPage']
|
|
24
|
+
options[:page] = search.raw_answer['page']
|
|
25
|
+
options[:count] = search.raw_answer['totalHits']
|
|
26
|
+
Meilisearch.new(**options)
|
|
30
27
|
end
|
|
31
28
|
end
|
|
32
29
|
end
|
|
@@ -15,13 +15,20 @@ class Pagy
|
|
|
15
15
|
path = Pathname.new(__dir__)
|
|
16
16
|
paginators.each { |symbol, name| autoload name, path.join(symbol.to_s) }
|
|
17
17
|
|
|
18
|
-
#
|
|
18
|
+
# Pagy::Method defines the pagy method to be included in the app controller/view.
|
|
19
19
|
Method = Module.new do
|
|
20
20
|
protected
|
|
21
21
|
|
|
22
22
|
define_method :pagy do |paginator = :offset, collection, **options|
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
arguments = if paginator == :calendar
|
|
24
|
+
[self, collection, options]
|
|
25
|
+
else
|
|
26
|
+
[collection, options = Pagy.options.merge(options)]
|
|
27
|
+
end
|
|
28
|
+
options[:root_key] = 'page' if options[:jsonapi] # enforce 'page' root_key for JSON:API
|
|
29
|
+
options[:request] ||= request # user set request or self.request
|
|
30
|
+
options[:request] = Request.new(options) # Pagy::Request
|
|
31
|
+
Pagy.const_get(paginators[paginator]).paginate(*arguments)
|
|
25
32
|
end
|
|
26
33
|
end
|
|
27
34
|
end
|
|
@@ -4,16 +4,13 @@ class Pagy
|
|
|
4
4
|
module OffsetPaginator
|
|
5
5
|
module_function
|
|
6
6
|
|
|
7
|
-
# Return instance and
|
|
8
|
-
def paginate(
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
pagy = Offset.new(**options, request:)
|
|
15
|
-
[pagy, collection.instance_of?(Array) ? collection[pagy.offset, pagy.limit] : pagy.records(collection)]
|
|
16
|
-
end
|
|
7
|
+
# Return the Pagy::Offset instance and results
|
|
8
|
+
def paginate(collection, options)
|
|
9
|
+
options[:page] ||= options[:request].resolve_page
|
|
10
|
+
options[:limit] = options[:request].resolve_limit
|
|
11
|
+
options[:count] ||= collection.instance_of?(Array) ? collection.size : OffsetPaginator.get_count(collection, options)
|
|
12
|
+
pagy = Offset.new(**options)
|
|
13
|
+
[pagy, collection.instance_of?(Array) ? collection[pagy.offset, pagy.limit] : pagy.records(collection)]
|
|
17
14
|
end
|
|
18
15
|
|
|
19
16
|
# Get the collection count
|
|
@@ -7,26 +7,23 @@ class Pagy
|
|
|
7
7
|
module_function
|
|
8
8
|
|
|
9
9
|
# Paginate from the search object
|
|
10
|
-
def paginate(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
options[:count] = results.total_count
|
|
21
|
-
[Searchkick.new(**options), results]
|
|
22
|
-
end
|
|
23
|
-
else
|
|
24
|
-
# The search is a searchkick results object
|
|
25
|
-
options[:limit] = search.respond_to?(:options) ? search.options[:per_page] : search.per_page
|
|
26
|
-
options[:page] = search.respond_to?(:options) ? search.options[:page] : search.current_page
|
|
27
|
-
options[:count] = search.total_count
|
|
28
|
-
Searchkick.new(**options)
|
|
10
|
+
def paginate(search, options)
|
|
11
|
+
if search.is_a?(Search::Arguments)
|
|
12
|
+
# The search is the array of pagy_search arguments
|
|
13
|
+
Searcher.wrap(search, options) do
|
|
14
|
+
model, term, search_options, block = search
|
|
15
|
+
search_options[:per_page] = options[:limit]
|
|
16
|
+
search_options[:page] = options[:page]
|
|
17
|
+
results = model.send(Searchkick::DEFAULT[:search_method], term || '*', **search_options, &block)
|
|
18
|
+
options[:count] = results.total_count
|
|
19
|
+
[Searchkick.new(**options), results]
|
|
29
20
|
end
|
|
21
|
+
else
|
|
22
|
+
# The search is a searchkick results object
|
|
23
|
+
options[:limit] = search.respond_to?(:options) ? search.options[:per_page] : search.per_page
|
|
24
|
+
options[:page] = search.respond_to?(:options) ? search.options[:page] : search.current_page
|
|
25
|
+
options[:count] = search.total_count
|
|
26
|
+
Searchkick.new(**options)
|
|
30
27
|
end
|
|
31
28
|
end
|
|
32
29
|
end
|
data/lib/pagy.rb
CHANGED
|
@@ -8,11 +8,13 @@ require_relative 'pagy/toolbox/helpers/loader'
|
|
|
8
8
|
|
|
9
9
|
# Top superclass: it defines only what's common to all the subclasses
|
|
10
10
|
class Pagy
|
|
11
|
-
|
|
11
|
+
class RawQueryValue < String; end
|
|
12
|
+
|
|
13
|
+
VERSION = '43.1.1'
|
|
12
14
|
ROOT = Pathname.new(__dir__).parent.freeze
|
|
13
15
|
DEFAULT = { limit: 20, limit_key: 'limit', page_key: 'page' }.freeze
|
|
14
|
-
PAGE_TOKEN = 'P '
|
|
15
|
-
LIMIT_TOKEN = 'L '
|
|
16
|
+
PAGE_TOKEN = RawQueryValue.new('P ')
|
|
17
|
+
LIMIT_TOKEN = RawQueryValue.new('L ')
|
|
16
18
|
LABEL_TOKEN = 'L'
|
|
17
19
|
A_TAG = '<a style="display: none;">#</a>'
|
|
18
20
|
|
data/locales/id.yml
CHANGED
|
@@ -4,9 +4,7 @@ id:
|
|
|
4
4
|
pagy:
|
|
5
5
|
p11n: 'Other'
|
|
6
6
|
aria_label:
|
|
7
|
-
|
|
8
|
-
# posting the translation of the following "Page"/"Pages" with the plurals for this locale
|
|
9
|
-
nav: "Pages"
|
|
7
|
+
nav: "Halaman"
|
|
10
8
|
previous: "Sebelumnya"
|
|
11
9
|
next: "Selanjutnya"
|
|
12
10
|
previous: "<"
|
data/locales/ja.yml
CHANGED
|
@@ -4,9 +4,7 @@ ja:
|
|
|
4
4
|
pagy:
|
|
5
5
|
p11n: 'Other'
|
|
6
6
|
aria_label:
|
|
7
|
-
|
|
8
|
-
# posting the translation of the following "Page"/"Pages" with the plurals for this locale
|
|
9
|
-
nav: "Pages"
|
|
7
|
+
nav: "ページ"
|
|
10
8
|
previous: "前へ"
|
|
11
9
|
next: "次へ"
|
|
12
10
|
previous: "<"
|
data/locales/km.yml
CHANGED
|
@@ -4,9 +4,7 @@ km:
|
|
|
4
4
|
pagy:
|
|
5
5
|
p11n: 'Other'
|
|
6
6
|
aria_label:
|
|
7
|
-
|
|
8
|
-
# posting the translation of the following "Page"/"Pages" with the plurals for this locale
|
|
9
|
-
nav: "Pages"
|
|
7
|
+
nav: "ទំព័រ"
|
|
10
8
|
previous: "មុន"
|
|
11
9
|
next: "បន្ទាប់"
|
|
12
10
|
previous: "<"
|
data/locales/sw.yml
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pagy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 43.
|
|
4
|
+
version: 43.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Domizio Demichelis
|
|
@@ -49,6 +49,7 @@ files:
|
|
|
49
49
|
- apps/calendar.ru
|
|
50
50
|
- apps/demo.ru
|
|
51
51
|
- apps/index.rb
|
|
52
|
+
- apps/keynav+root_key.ru
|
|
52
53
|
- apps/keynav.ru
|
|
53
54
|
- apps/keyset.ru
|
|
54
55
|
- apps/keyset_sequel.ru
|