pagy 43.4.3 → 43.5.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 +1 -1
- data/apps/demo.ru +2 -2
- data/apps/keynav+root_key.ru +1 -1
- data/apps/keynav.ru +3 -3
- data/apps/keyset.ru +3 -3
- data/apps/keyset_sequel.ru +2 -2
- data/apps/rails.ru +2 -2
- data/apps/repro.ru +3 -3
- data/config/pagy.rb +4 -4
- data/javascripts/pagy.js +20 -12
- data/javascripts/pagy.min.js +1 -1
- data/javascripts/pagy.mjs +18 -10
- data/lib/pagy/classes/calendar/calendar.rb +6 -8
- data/lib/pagy/classes/calendar/unit.rb +10 -10
- data/lib/pagy/classes/exceptions.rb +3 -3
- data/lib/pagy/classes/keyset/adapters/active_record.rb +6 -8
- data/lib/pagy/classes/keyset/adapters/sequel.rb +9 -12
- data/lib/pagy/classes/keyset/keynav.rb +6 -6
- data/lib/pagy/classes/keyset/keyset.rb +7 -8
- data/lib/pagy/classes/offset/countless.rb +5 -10
- data/lib/pagy/classes/offset/offset.rb +2 -1
- data/lib/pagy/classes/offset/search.rb +1 -1
- data/lib/pagy/classes/request.rb +4 -1
- data/lib/pagy/deprecated.rb +84 -0
- data/lib/pagy/modules/abilities/configurable.rb +1 -7
- data/lib/pagy/modules/abilities/countable.rb +1 -2
- data/lib/pagy/modules/abilities/linkable.rb +6 -5
- data/lib/pagy/modules/abilities/rangeable.rb +1 -2
- data/lib/pagy/modules/console.rb +1 -1
- data/lib/pagy/modules/i18n/i18n.rb +1 -1
- data/lib/pagy/modules/searcher.rb +0 -1
- data/lib/pagy/next.rb +25 -0
- data/lib/pagy/tasks/sync.rb +1 -0
- data/lib/pagy/toolbox/helpers/anchor_tags.rb +0 -2
- data/lib/pagy/toolbox/helpers/bootstrap/input_nav_js.rb +0 -1
- data/lib/pagy/toolbox/helpers/bootstrap/previous_next_html.rb +0 -1
- data/lib/pagy/toolbox/helpers/bootstrap/series_nav.rb +0 -1
- data/lib/pagy/toolbox/helpers/bootstrap/series_nav_js.rb +0 -1
- data/lib/pagy/toolbox/helpers/bulma/input_nav_js.rb +0 -1
- data/lib/pagy/toolbox/helpers/bulma/previous_next_html.rb +0 -1
- data/lib/pagy/toolbox/helpers/bulma/series_nav.rb +0 -1
- data/lib/pagy/toolbox/helpers/bulma/series_nav_js.rb +0 -1
- data/lib/pagy/toolbox/helpers/headers_hash.rb +1 -1
- data/lib/pagy/toolbox/helpers/info_tag.rb +2 -2
- data/lib/pagy/toolbox/helpers/input_nav_js.rb +0 -1
- data/lib/pagy/toolbox/helpers/limit_tag_js.rb +3 -4
- data/lib/pagy/toolbox/helpers/loaders.rb +1 -1
- data/lib/pagy/toolbox/helpers/page_url.rb +0 -1
- data/lib/pagy/toolbox/helpers/series_nav.rb +0 -1
- data/lib/pagy/toolbox/helpers/series_nav_js.rb +0 -1
- data/lib/pagy/toolbox/helpers/support/a_lambda.rb +2 -3
- data/lib/pagy/toolbox/helpers/support/data_pagy_attribute.rb +0 -1
- data/lib/pagy/toolbox/helpers/support/nav_aria_label_attribute.rb +0 -2
- data/lib/pagy/toolbox/helpers/support/series.rb +2 -2
- data/lib/pagy/toolbox/helpers/support/wrap_input_nav_js.rb +1 -2
- data/lib/pagy/toolbox/helpers/support/wrap_series_nav.rb +1 -2
- data/lib/pagy/toolbox/helpers/support/wrap_series_nav_js.rb +3 -3
- data/lib/pagy/toolbox/helpers/urls_hash.rb +0 -1
- data/lib/pagy/toolbox/paginators/calendar.rb +1 -1
- data/lib/pagy/toolbox/paginators/countish.rb +0 -1
- data/lib/pagy/toolbox/paginators/countless.rb +0 -1
- data/lib/pagy/toolbox/paginators/elasticsearch_rails.rb +2 -3
- data/lib/pagy/toolbox/paginators/keynav_js.rb +0 -2
- data/lib/pagy/toolbox/paginators/keyset.rb +0 -1
- data/lib/pagy/toolbox/paginators/meilisearch.rb +0 -1
- data/lib/pagy/toolbox/paginators/method.rb +1 -1
- data/lib/pagy/toolbox/paginators/offset.rb +0 -1
- data/lib/pagy/toolbox/paginators/searchkick.rb +0 -1
- data/lib/pagy/toolbox/paginators/typesense_rails.rb +0 -1
- data/lib/pagy.rb +6 -16
- metadata +5 -4
- data/sig/pagy.rbs +0 -315
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
class Pagy
|
|
4
4
|
class Keyset
|
|
5
5
|
module Adapters
|
|
6
|
-
# Keyset adapter for
|
|
6
|
+
# Keyset adapter for Sequel ORM
|
|
7
7
|
module Sequel
|
|
8
|
-
# Extract the keyset from the set
|
|
9
8
|
def extract_keyset
|
|
10
9
|
return {} unless @set.opts[:order]
|
|
11
10
|
|
|
@@ -21,27 +20,26 @@ class Pagy
|
|
|
21
20
|
end
|
|
22
21
|
end
|
|
23
22
|
|
|
24
|
-
# Get the keyset attributes from a record
|
|
25
23
|
def keyset_attributes_from(record)
|
|
26
24
|
record.to_hash.slice(*@keyset.keys)
|
|
27
25
|
end
|
|
28
26
|
|
|
29
|
-
# Get the hash of quoted keyset identifiers
|
|
30
27
|
def quoted_identifiers(table)
|
|
31
28
|
db = @set.db
|
|
32
29
|
@keyset.to_h { |column| [column, "#{db.quote_identifier(table)}.#{db.quote_identifier(column)}"] }
|
|
33
30
|
end
|
|
34
31
|
|
|
35
|
-
# Typecast the attributes
|
|
36
32
|
def typecast(attributes)
|
|
37
|
-
model = @set.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
model = @set.model
|
|
34
|
+
db = @set.db
|
|
35
|
+
{}.tap do |result|
|
|
36
|
+
@keyset.each_key do |k|
|
|
37
|
+
type = model.db_schema[k].fetch(:type)
|
|
38
|
+
result[k] = db.typecast_value(type, attributes[k])
|
|
39
|
+
end
|
|
40
|
+
end
|
|
42
41
|
end
|
|
43
42
|
|
|
44
|
-
# Append the missing keyset keys, if the set is restricted by select
|
|
45
43
|
def ensure_select
|
|
46
44
|
return if @set.opts[:select].nil?
|
|
47
45
|
|
|
@@ -49,7 +47,6 @@ class Pagy
|
|
|
49
47
|
@set = @set.select_append(*@keyset.keys.reject { |c| selected.include?(c) })
|
|
50
48
|
end
|
|
51
49
|
|
|
52
|
-
# Apply the where predicate to the set
|
|
53
50
|
def apply_where(predicate, arguments)
|
|
54
51
|
@set = @set.where(::Sequel.lit(predicate, **arguments))
|
|
55
52
|
end
|
|
@@ -2,14 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
class Pagy
|
|
4
4
|
class Keyset
|
|
5
|
-
#
|
|
5
|
+
# Keyset pagination with broad UI support
|
|
6
6
|
class Keynav < Keyset
|
|
7
7
|
# Avoid conflicts between filter arguments in composite SQL fragments
|
|
8
8
|
PRIOR_PREFIX = 'prior_'
|
|
9
9
|
PAGE_PREFIX = 'page_'
|
|
10
10
|
|
|
11
|
-
# Define empty subclasses to allow specific typing without triggering autoload
|
|
12
|
-
# The .new factory in Keyset will handle mixing in the adapter logic from Pagy::Keyset::Adapters.
|
|
11
|
+
# Define empty subclasses to allow specific typing without triggering autoload
|
|
13
12
|
class ActiveRecord < self; end
|
|
14
13
|
class Sequel < self; end
|
|
15
14
|
|
|
@@ -18,8 +17,7 @@ class Pagy
|
|
|
18
17
|
# Finalize the instance variables needed for the UI
|
|
19
18
|
def initialize(set, **)
|
|
20
19
|
super
|
|
21
|
-
|
|
22
|
-
self.next
|
|
20
|
+
|
|
23
21
|
@previous = @page - 1 unless @page == 1
|
|
24
22
|
@in = @records.size
|
|
25
23
|
end
|
|
@@ -31,7 +29,7 @@ class Pagy
|
|
|
31
29
|
def next
|
|
32
30
|
records
|
|
33
31
|
@count = 0 if !@more && @page == 1 # empty records (trigger the right info message for known 0 count)
|
|
34
|
-
return
|
|
32
|
+
return unless @more
|
|
35
33
|
|
|
36
34
|
@next ||= begin
|
|
37
35
|
unless @page_cutoff
|
|
@@ -80,6 +78,8 @@ class Pagy
|
|
|
80
78
|
@more = true # not the last page
|
|
81
79
|
@set.limit(nil).to_a # replaced by the compound predicate
|
|
82
80
|
end
|
|
81
|
+
|
|
82
|
+
prepend Deprecated::Keynav if defined?(Deprecated::Keynav)
|
|
83
83
|
end
|
|
84
84
|
end
|
|
85
85
|
end
|
|
@@ -4,9 +4,9 @@ require 'json'
|
|
|
4
4
|
require_relative '../../modules/b64'
|
|
5
5
|
|
|
6
6
|
class Pagy
|
|
7
|
-
#
|
|
7
|
+
# Fast keyset pagination for big data
|
|
8
8
|
class Keyset < Pagy
|
|
9
|
-
# Autoload adapters
|
|
9
|
+
# Autoload adapters only when const_get accesses them
|
|
10
10
|
module Adapters
|
|
11
11
|
path = Pathname.new(__dir__)
|
|
12
12
|
autoload :ActiveRecord, path.join('adapters/active_record')
|
|
@@ -21,7 +21,7 @@ class Pagy
|
|
|
21
21
|
|
|
22
22
|
class TypeError < ::TypeError; end
|
|
23
23
|
|
|
24
|
-
# Factory method:
|
|
24
|
+
# Factory method: detect the set type, configure the subclass, and instantiate.
|
|
25
25
|
def self.new(set, **)
|
|
26
26
|
# 1. Handle direct subclass usage (e.g. Pagy::Keyset::ActiveRecord.new)
|
|
27
27
|
if /::(?:ActiveRecord|Sequel)$/.match?(name)
|
|
@@ -42,7 +42,7 @@ class Pagy
|
|
|
42
42
|
const_get(adapter).tap { _1.mix_in_adapter(adapter) }.new(set, **)
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
#
|
|
45
|
+
# Lazy-include the adapter module
|
|
46
46
|
def self.mix_in_adapter(adapter)
|
|
47
47
|
adapter_module = Adapters.const_get(adapter)
|
|
48
48
|
include(adapter_module) unless self < adapter_module
|
|
@@ -61,7 +61,7 @@ class Pagy
|
|
|
61
61
|
self.next
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
#
|
|
64
|
+
# The array of records for the current page
|
|
65
65
|
def records
|
|
66
66
|
@records ||= begin
|
|
67
67
|
ensure_select
|
|
@@ -69,7 +69,7 @@ class Pagy
|
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
-
#
|
|
72
|
+
# The next page (i.e., the cutoff of the current page)
|
|
73
73
|
def next
|
|
74
74
|
records
|
|
75
75
|
return unless @more
|
|
@@ -135,13 +135,12 @@ class Pagy
|
|
|
135
135
|
"#{hint} AND (#{query})"
|
|
136
136
|
end
|
|
137
137
|
|
|
138
|
-
#
|
|
138
|
+
# The prefixed arguments from a cutoff
|
|
139
139
|
def arguments_from(cutoff, prefix = nil)
|
|
140
140
|
attributes = typecast(@keyset.keys.zip(cutoff).to_h)
|
|
141
141
|
prefix ? attributes.transform_keys { |key| :"#{prefix}#{key}" } : attributes
|
|
142
142
|
end
|
|
143
143
|
|
|
144
|
-
# Extract the cutoff from the last record (only called if @more)
|
|
145
144
|
def extract_cutoff
|
|
146
145
|
attributes = keyset_attributes_from(@records.last)
|
|
147
146
|
@options[:pre_serialize]&.(attributes)
|
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
class Pagy
|
|
4
4
|
class Offset
|
|
5
|
-
# Offset pagination without
|
|
5
|
+
# Offset pagination without any COUNT query
|
|
6
6
|
class Countless < Offset
|
|
7
7
|
def initialize(**)
|
|
8
8
|
assign_options(**)
|
|
9
9
|
assign_and_check(limit: 1, page: 1)
|
|
10
|
-
@
|
|
11
|
-
@last = upto_max_pages(@options[:last]) unless @options[:headless]
|
|
10
|
+
@last = @options[:last] unless @options[:headless]
|
|
12
11
|
assign_offset
|
|
13
12
|
end
|
|
14
13
|
|
|
@@ -24,12 +23,6 @@ class Pagy
|
|
|
24
23
|
|
|
25
24
|
def countless? = true
|
|
26
25
|
|
|
27
|
-
def upto_max_pages(value)
|
|
28
|
-
return value unless value && @options[:max_pages]
|
|
29
|
-
|
|
30
|
-
[value, @options[:max_pages]].min
|
|
31
|
-
end
|
|
32
|
-
|
|
33
26
|
# Finalize the instance variables based on the fetched size
|
|
34
27
|
def finalize(fetched_size)
|
|
35
28
|
# empty records (trigger the right info message for known 0 count)
|
|
@@ -42,7 +35,7 @@ class Pagy
|
|
|
42
35
|
|
|
43
36
|
past = @last && @page < @last # current page is before the known last page
|
|
44
37
|
more = fetched_size > @limit # more pages after this one
|
|
45
|
-
@last =
|
|
38
|
+
@last = (more ? @page + 1 : @page) unless past && more
|
|
46
39
|
@in = [fetched_size, @limit].min
|
|
47
40
|
@from = @in.zero? ? 0 : @offset + 1
|
|
48
41
|
@to = @offset + @in
|
|
@@ -63,6 +56,8 @@ class Pagy
|
|
|
63
56
|
def compose_page_param(page)
|
|
64
57
|
EscapedValue.new("#{page || 1}+#{@last}")
|
|
65
58
|
end
|
|
59
|
+
|
|
60
|
+
prepend Deprecated::Countless if defined?(Deprecated::Countless)
|
|
66
61
|
end
|
|
67
62
|
end
|
|
68
63
|
end
|
|
@@ -46,7 +46,6 @@ class Pagy
|
|
|
46
46
|
|
|
47
47
|
def assign_last
|
|
48
48
|
@last = [(@count.to_f / @limit).ceil, 1].max
|
|
49
|
-
@last = @options[:max_pages] if @options[:max_pages] && @last > @options[:max_pages]
|
|
50
49
|
end
|
|
51
50
|
|
|
52
51
|
def assign_offset
|
|
@@ -58,5 +57,7 @@ class Pagy
|
|
|
58
57
|
@in = @from = @to = 0 # options relative to the actual page
|
|
59
58
|
@previous = @last # @previous relative to the actual page
|
|
60
59
|
end
|
|
60
|
+
|
|
61
|
+
prepend Deprecated::Offset if defined?(Deprecated::Offset)
|
|
61
62
|
end
|
|
62
63
|
end
|
|
@@ -15,7 +15,7 @@ class Pagy
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
# Search classes do not use OFFSET for querying a DB;
|
|
18
|
-
# however, they use the same positional technique used by Offset
|
|
18
|
+
# however, they use the same positional technique used by Offset.
|
|
19
19
|
class SearchBase < Offset
|
|
20
20
|
DEFAULT = { search_method: :search }.freeze
|
|
21
21
|
|
data/lib/pagy/classes/request.rb
CHANGED
|
@@ -28,7 +28,7 @@ class Pagy
|
|
|
28
28
|
|
|
29
29
|
def resolve_limit
|
|
30
30
|
default = @options[:limit] || DEFAULT[:limit]
|
|
31
|
-
max_limit = @options[:
|
|
31
|
+
max_limit = @options[:max_limit]
|
|
32
32
|
return default unless max_limit
|
|
33
33
|
|
|
34
34
|
limit_key = @options[:limit_key] || DEFAULT[:limit_key]
|
|
@@ -38,8 +38,11 @@ class Pagy
|
|
|
38
38
|
|
|
39
39
|
private
|
|
40
40
|
|
|
41
|
+
# Overriding support
|
|
41
42
|
def get_params(request)
|
|
42
43
|
request.GET.merge(request.POST).to_h.freeze
|
|
43
44
|
end
|
|
45
|
+
|
|
46
|
+
prepend Deprecated::Request if defined?(Deprecated::Request)
|
|
44
47
|
end
|
|
45
48
|
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This file relegates all the deprecation warnings and code.
|
|
4
|
+
# Pagy already implements the next code and this file works as a compatibility layer
|
|
5
|
+
# to avoid breaking changes in the current version, respecting the Semantic Version contract.
|
|
6
|
+
class Pagy
|
|
7
|
+
module Deprecated
|
|
8
|
+
def self.client_max_limit(options)
|
|
9
|
+
if (max_limit = options.delete(:client_max_limit))
|
|
10
|
+
options[:max_limit] ||= max_limit
|
|
11
|
+
warn '[PAGY] the :client_max_limit option is deprecated: use :max_limit instead.'
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module Pagy
|
|
16
|
+
def assign_options(**options)
|
|
17
|
+
if options.key?(:max_pages)
|
|
18
|
+
warn '[PAGY] the :max_pages option is deprecated: ' \
|
|
19
|
+
'use https://ddnexus.github.io/pagy/guides/how-to/#paginate-only-max-records instead.'
|
|
20
|
+
end
|
|
21
|
+
Deprecated.client_max_limit(options) # if used without Request#resolve_limit
|
|
22
|
+
super
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
##### Enabled from the autoloaded class #####
|
|
27
|
+
|
|
28
|
+
module Request # :client_max_limit option
|
|
29
|
+
def resolve_limit
|
|
30
|
+
Deprecated.client_max_limit(@options)
|
|
31
|
+
super
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
module Offset
|
|
36
|
+
def assign_last
|
|
37
|
+
super
|
|
38
|
+
@last = @options[:max_pages] if @options[:max_pages] && @last > @options[:max_pages]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
module Countless
|
|
43
|
+
def initialize(**)
|
|
44
|
+
super
|
|
45
|
+
@page = upto_max_pages(@page)
|
|
46
|
+
@last = upto_max_pages(@last) unless @options[:headless]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def finalize(fetched_size)
|
|
50
|
+
super
|
|
51
|
+
@last = upto_max_pages(@last)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def upto_max_pages(value)
|
|
55
|
+
return value unless value && @options[:max_pages]
|
|
56
|
+
|
|
57
|
+
[value, @options[:max_pages]].min
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
module Keynav
|
|
62
|
+
def next
|
|
63
|
+
records
|
|
64
|
+
super unless @options[:max_pages] && @page >= @options[:max_pages]
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
prepend Deprecated::Pagy
|
|
70
|
+
|
|
71
|
+
# Reopen the module and add the deprecated methods
|
|
72
|
+
module Configurable
|
|
73
|
+
def options
|
|
74
|
+
OPTIONS.tap do
|
|
75
|
+
warn "[PAGY] 'Pagy.options' is deprecated: use 'Pagy::OPTIONS directly'"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def sync_javascript(...)
|
|
80
|
+
warn "[PAGY] 'Pagy.sync_javascript(...)' is deprecated: use 'Pagy.sync(:javascript, ...)' instead."
|
|
81
|
+
sync(:javascript, ...)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Pagy
|
|
4
|
-
#
|
|
4
|
+
# Configuration methods
|
|
5
5
|
module Configurable
|
|
6
|
-
# Deprecated: Sync the pagy javascript targets. Use sync(:javascripts, ...) instead.
|
|
7
|
-
def sync_javascript(...)
|
|
8
|
-
warn "[PAGY] 'Pagy.sync_javascript(...)' is deprecated: use 'Pagy.sync(:javascript, ...)' instead."
|
|
9
|
-
sync(:javascript, ...)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
6
|
# Sync the pagy resource targets.
|
|
13
7
|
def sync(resource, destination, *targets)
|
|
14
8
|
files = ROOT.join("#{resource}s").glob("{#{targets.join(',')}}")
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Pagy
|
|
4
|
-
#
|
|
4
|
+
# Count a collection
|
|
5
5
|
module Countable
|
|
6
6
|
module_function
|
|
7
7
|
|
|
8
|
-
# Get the collection count
|
|
9
8
|
def get_count(collection, options)
|
|
10
9
|
return collection.size if collection.instance_of?(Array)
|
|
11
10
|
return collection.count unless defined?(::ActiveRecord) && collection.is_a?(::ActiveRecord::Relation)
|
|
@@ -6,13 +6,13 @@ class Pagy
|
|
|
6
6
|
# Support spaces in placeholder params
|
|
7
7
|
class EscapedValue < String; end
|
|
8
8
|
|
|
9
|
-
#
|
|
9
|
+
# Handle the url and anchor
|
|
10
10
|
module Linkable
|
|
11
11
|
module QueryUtils
|
|
12
12
|
module_function
|
|
13
13
|
|
|
14
|
-
# Extracted from Rack::Utils and reformatted for rubocop
|
|
15
|
-
# Allow unescaped Pagy::RawQueryValue
|
|
14
|
+
# Extracted from Rack::Utils and reformatted for rubocop.
|
|
15
|
+
# Allow unescaped Pagy::RawQueryValue.
|
|
16
16
|
def build_nested_query(value, prefix = nil)
|
|
17
17
|
case value
|
|
18
18
|
when Array
|
|
@@ -38,7 +38,7 @@ class Pagy
|
|
|
38
38
|
|
|
39
39
|
protected
|
|
40
40
|
|
|
41
|
-
#
|
|
41
|
+
# Overriding support for classes with composite page param
|
|
42
42
|
def compose_page_param(page) = page
|
|
43
43
|
|
|
44
44
|
# Return the URL for the page, relying on the Pagy::Request
|
|
@@ -53,7 +53,7 @@ class Pagy
|
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
{ opts[:page_key] => compose_page_param(page),
|
|
56
|
-
opts[:limit_key] => opts[:
|
|
56
|
+
opts[:limit_key] => opts[:max_limit] && opts[:limit] }.each do |k, v|
|
|
57
57
|
v ? container[k] = v : container.delete(k)
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -63,6 +63,7 @@ class Pagy
|
|
|
63
63
|
compose_url(opts[:absolute], opts[:path], params, fragment)
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
+
# Overriding support
|
|
66
67
|
def compose_url(absolute, path, params, fragment)
|
|
67
68
|
query_string = QueryUtils.build_nested_query(params).sub(/\A(?=.)/, '?') # conditionally prepend '?'
|
|
68
69
|
"#{@request.base_url if absolute}#{path || @request.path}#{query_string}#{fragment}"
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Pagy
|
|
4
|
-
#
|
|
4
|
+
# Support range checking, error and rescue
|
|
5
5
|
module Rangeable
|
|
6
|
-
# Check if in range
|
|
7
6
|
def in_range?
|
|
8
7
|
return @in_range if defined?(@in_range)
|
|
9
8
|
return true if (@in_range = yield)
|
data/lib/pagy/modules/console.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Pagy
|
|
4
|
-
#
|
|
4
|
+
# Ready to use pagy environment when included in irb/rails console
|
|
5
5
|
module Console
|
|
6
6
|
class Collection < Array
|
|
7
7
|
def initialize(arr = Array(1..1000))
|
|
@@ -4,7 +4,7 @@ require 'yaml'
|
|
|
4
4
|
require_relative 'p11n'
|
|
5
5
|
|
|
6
6
|
class Pagy
|
|
7
|
-
# Pagy i18n implementation, compatible with the I18n gem
|
|
7
|
+
# Faster and lighter Pagy i18n implementation, compatible with the I18n gem
|
|
8
8
|
module I18n
|
|
9
9
|
class KeyError < KeyError; end
|
|
10
10
|
|
data/lib/pagy/next.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# See https://ddnexus.github.io/pagy/guides/pagy-next/
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
ENV['PAGY_NEXT'] = 'true'
|
|
5
|
+
# :nocov:
|
|
6
|
+
require_relative '../pagy' unless defined?(Pagy) # avoid circular require (also from pagy itself)
|
|
7
|
+
# :nocov:
|
|
8
|
+
|
|
9
|
+
class Pagy
|
|
10
|
+
VERSION = "#{remove_const(:VERSION)}.next".freeze
|
|
11
|
+
|
|
12
|
+
class NextError < ArgumentError; end
|
|
13
|
+
|
|
14
|
+
module Discontinued
|
|
15
|
+
# Ensure a discontinued option won't pass unnoticed shadowing a bug
|
|
16
|
+
def assign_options(**options)
|
|
17
|
+
discontinued = options.keys & %i[max_pages client_max_limit]
|
|
18
|
+
return super if discontinued.empty?
|
|
19
|
+
|
|
20
|
+
raise NextError, "discontinued #{discontinued.map(&:inspect).join(', ')}: " \
|
|
21
|
+
'check https://ddnexus.github.io/pagy/changelog/#deprecations for alternatives'
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
prepend Discontinued
|
|
25
|
+
end
|
data/lib/pagy/tasks/sync.rb
CHANGED
|
@@ -4,11 +4,9 @@ require_relative 'support/a_lambda' # inheritable
|
|
|
4
4
|
|
|
5
5
|
class Pagy
|
|
6
6
|
module NumericHelpers
|
|
7
|
-
# Return the enabled/disabled previous page anchor tag
|
|
8
7
|
def previous_tag(...) = anchor_tag_for(:previous, ...)
|
|
9
8
|
end
|
|
10
9
|
|
|
11
|
-
# Return the enabled/disabled next page anchor tag
|
|
12
10
|
def next_tag(...) = anchor_tag_for(:next, ...)
|
|
13
11
|
|
|
14
12
|
private
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
class Pagy
|
|
4
4
|
module NumericHelpers
|
|
5
|
-
# Instances with count return "Displaying items 41-60 of 324 in total" or "Displaying Products 41-60 of 324 in total"
|
|
6
|
-
# Instances with no count return only page info: "Page 3 of 100"
|
|
5
|
+
# Instances with count return "Displaying items 41-60 of 324 in total" or "Displaying Products 41-60 of 324 in total".
|
|
6
|
+
# Instances with no count return only page info: "Page 3 of 100".
|
|
7
7
|
def info_tag(id: nil, item_name: nil)
|
|
8
8
|
i18n_key = if @count.nil?
|
|
9
9
|
'pagy.info_tag.no_count'
|
|
@@ -4,7 +4,6 @@ require_relative 'support/wrap_input_nav_js'
|
|
|
4
4
|
|
|
5
5
|
class Pagy
|
|
6
6
|
module NumericHelpers
|
|
7
|
-
# JavaScript input pagination: it returns a nav with a data-pagy attribute used by the pagy.js file
|
|
8
7
|
def input_nav_js(style = nil, **)
|
|
9
8
|
return send(:"#{style}_input_nav_js", **) if style && style.to_s != 'pagy'
|
|
10
9
|
|
|
@@ -4,11 +4,10 @@ require_relative 'support/data_pagy_attribute'
|
|
|
4
4
|
|
|
5
5
|
class Pagy
|
|
6
6
|
module NumericHelpers
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
raise OptionError.new(self, :client_max_limit, 'to be truthy', client_max_limit) unless client_max_limit
|
|
7
|
+
def limit_tag_js(id: nil, item_name: nil, max_limit: @options[:max_limit], **)
|
|
8
|
+
raise OptionError.new(self, :max_limit, 'to be truthy', max_limit) unless max_limit
|
|
10
9
|
|
|
11
|
-
limit_input = %(<input name="limit" type="number" min="1" max="#{
|
|
10
|
+
limit_input = %(<input name="limit" type="number" min="1" max="#{max_limit}" value="#{
|
|
12
11
|
@limit}" style="padding: 0; text-align: center; width: #{@limit.to_s.length + 1}rem;">#{A_TAG})
|
|
13
12
|
|
|
14
13
|
url_token = compose_page_url(PAGE_TOKEN, limit: LIMIT_TOKEN)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
class Pagy
|
|
4
4
|
# The aliaser defines loader methods and aliases them.
|
|
5
|
-
# When a method is called for the first time, its loader will load the full implementation
|
|
5
|
+
# When a method is called for the first time, its loader will load the full implementation,
|
|
6
6
|
# which will overwrite the alias and will be executed.
|
|
7
7
|
# Subsequent calls will run the full implementation directly.
|
|
8
8
|
aliaser = lambda do |receiver, paths|
|
|
@@ -4,7 +4,6 @@ require_relative 'support/wrap_series_nav_js'
|
|
|
4
4
|
|
|
5
5
|
class Pagy
|
|
6
6
|
module NumericHelpers
|
|
7
|
-
# Return a nav with a data-pagy attribute used by the pagy.js file
|
|
8
7
|
def series_nav_js(style = nil, **)
|
|
9
8
|
return send(:"#{style}_series_nav_js", **) if style && style.to_s != 'pagy'
|
|
10
9
|
|