pagy 9.3.3 → 43.0.0.rc1
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/LICENSE.txt +1 -1
- data/apps/calendar.ru +547 -551
- data/apps/demo.ru +221 -178
- data/apps/index.rb +3 -1
- data/apps/keynav.ru +258 -0
- data/apps/{keyset_ar.ru → keyset.ru} +27 -32
- data/apps/{keyset_s.ru → keyset_sequel.ru} +24 -29
- data/apps/rails.ru +51 -48
- data/apps/repro.ru +46 -43
- data/bin/pagy +22 -23
- data/config/pagy.rb +35 -207
- data/javascripts/ai_widget.js +76 -0
- data/javascripts/pagy.js +151 -0
- data/javascripts/pagy.js.map +10 -0
- data/javascripts/pagy.min.js +1 -4
- data/javascripts/pagy.mjs +111 -63
- data/javascripts/wand.js +1166 -0
- data/lib/pagy/classes/calendar/calendar.rb +98 -0
- data/lib/pagy/{calendar → classes/calendar}/day.rb +7 -11
- data/lib/pagy/{calendar → classes/calendar}/month.rb +5 -10
- data/lib/pagy/{calendar → classes/calendar}/quarter.rb +10 -15
- data/lib/pagy/classes/calendar/unit.rb +92 -0
- data/lib/pagy/{calendar → classes/calendar}/week.rb +5 -9
- data/lib/pagy/{calendar → classes/calendar}/year.rb +5 -6
- data/lib/pagy/classes/exceptions.rb +33 -0
- data/lib/pagy/classes/keyset/active_record.rb +11 -0
- data/lib/pagy/classes/keyset/adapters/active_record.rb +50 -0
- data/lib/pagy/classes/keyset/adapters/sequel.rb +63 -0
- data/lib/pagy/classes/keyset/keynav/active_record.rb +13 -0
- data/lib/pagy/classes/keyset/keynav/sequel.rb +13 -0
- data/lib/pagy/classes/keyset/keynav.rb +77 -0
- data/lib/pagy/classes/keyset/keyset.rb +126 -0
- data/lib/pagy/classes/keyset/sequel.rb +11 -0
- data/lib/pagy/classes/offset/countless.rb +56 -0
- data/lib/pagy/classes/offset/offset.rb +54 -0
- data/lib/pagy/classes/offset/search.rb +38 -0
- data/lib/pagy/classes/request.rb +36 -0
- data/lib/pagy/modules/abilities/configurable.rb +36 -0
- data/lib/pagy/modules/abilities/linkable.rb +59 -0
- data/lib/pagy/modules/abilities/rangeable.rb +15 -0
- data/lib/pagy/modules/abilities/shiftable.rb +12 -0
- data/lib/pagy/{b64.rb → modules/b64.rb} +3 -7
- data/lib/pagy/modules/console.rb +38 -0
- data/lib/pagy/modules/i18n/i18n.rb +48 -0
- data/lib/pagy/modules/i18n/p11n/arabic.rb +29 -0
- data/lib/pagy/modules/i18n/p11n/east_slavic.rb +26 -0
- data/lib/pagy/modules/i18n/p11n/one_other.rb +15 -0
- data/lib/pagy/modules/i18n/p11n/one_upto_two_other.rb +15 -0
- data/lib/pagy/modules/i18n/p11n/other.rb +13 -0
- data/lib/pagy/modules/i18n/p11n/polish.rb +26 -0
- data/lib/pagy/modules/i18n/p11n/west_slavic.rb +22 -0
- data/lib/pagy/modules/i18n/p11n.rb +16 -0
- data/lib/pagy/modules/searcher.rb +20 -0
- data/lib/pagy/toolbox/helpers/anchor_tags.rb +25 -0
- data/lib/pagy/toolbox/helpers/bootstrap/input_nav_js.rb +24 -0
- data/lib/pagy/toolbox/helpers/bootstrap/previous_next_html.rb +18 -0
- data/lib/pagy/toolbox/helpers/bootstrap/series_nav.rb +29 -0
- data/lib/pagy/toolbox/helpers/bootstrap/series_nav_js.rb +21 -0
- data/lib/pagy/toolbox/helpers/bulma/input_nav_js.rb +21 -0
- data/lib/pagy/toolbox/helpers/bulma/previous_next_html.rb +19 -0
- data/lib/pagy/toolbox/helpers/bulma/series_nav.rb +28 -0
- data/lib/pagy/toolbox/helpers/bulma/series_nav_js.rb +20 -0
- data/lib/pagy/toolbox/helpers/data_hash.rb +26 -0
- data/lib/pagy/toolbox/helpers/headers_hash.rb +20 -0
- data/lib/pagy/toolbox/helpers/info_tag.rb +26 -0
- data/lib/pagy/toolbox/helpers/input_nav_js.rb +19 -0
- data/lib/pagy/toolbox/helpers/limit_tag_js.rb +23 -0
- data/lib/pagy/toolbox/helpers/loader.rb +33 -0
- data/lib/pagy/toolbox/helpers/page_url.rb +23 -0
- data/lib/pagy/toolbox/helpers/series_nav.rb +29 -0
- data/lib/pagy/toolbox/helpers/series_nav_js.rb +19 -0
- data/lib/pagy/toolbox/helpers/support/a_lambda.rb +34 -0
- data/lib/pagy/toolbox/helpers/support/data_pagy_attribute.rb +15 -0
- data/lib/pagy/toolbox/helpers/support/nav_aria_label_attribute.rb +12 -0
- data/lib/pagy/toolbox/helpers/support/series.rb +38 -0
- data/lib/pagy/toolbox/helpers/support/wrap_input_nav_js.rb +20 -0
- data/lib/pagy/toolbox/helpers/support/wrap_series_nav.rb +17 -0
- data/lib/pagy/toolbox/helpers/support/wrap_series_nav_js.rb +36 -0
- data/lib/pagy/toolbox/helpers/urls_hash.rb +13 -0
- data/lib/pagy/toolbox/paginators/calendar.rb +30 -0
- data/lib/pagy/toolbox/paginators/countless.rb +25 -0
- data/lib/pagy/toolbox/paginators/elasticsearch_rails.rb +32 -0
- data/lib/pagy/toolbox/paginators/keynav_js.rb +29 -0
- data/lib/pagy/toolbox/paginators/keyset.rb +18 -0
- data/lib/pagy/toolbox/paginators/meilisearch.rb +32 -0
- data/lib/pagy/toolbox/paginators/method.rb +26 -0
- data/lib/pagy/toolbox/paginators/offset.rb +33 -0
- data/lib/pagy/toolbox/paginators/searchkick.rb +32 -0
- data/lib/pagy.rb +59 -97
- data/locales/ar.yml +9 -6
- data/locales/be.yml +9 -6
- data/locales/bg.yml +9 -6
- data/locales/bs.yml +9 -6
- data/locales/ca.yml +9 -6
- data/locales/ckb.yml +8 -6
- data/locales/cs.yml +9 -6
- data/locales/da.yml +9 -6
- data/locales/de.yml +9 -6
- data/locales/dz.yml +9 -6
- data/locales/en.yml +9 -6
- data/locales/es.yml +9 -6
- data/locales/fr.yml +9 -6
- data/locales/hr.yml +9 -6
- data/locales/id.yml +9 -6
- data/locales/it.yml +9 -6
- data/locales/ja.yml +9 -6
- data/locales/km.yml +9 -6
- data/locales/ko.yml +9 -6
- data/locales/nb.yml +9 -6
- data/locales/nl.yml +9 -6
- data/locales/nn.yml +9 -6
- data/locales/pl.yml +9 -6
- data/locales/pt-BR.yml +10 -7
- data/locales/pt.yml +10 -7
- data/locales/ru.yml +9 -6
- data/locales/sr.yml +9 -6
- data/locales/sv-SE.yml +9 -6
- data/locales/sv.yml +9 -6
- data/locales/sw.yml +12 -9
- data/locales/ta.yml +12 -9
- data/locales/tr.yml +9 -6
- data/locales/uk.yml +9 -6
- data/locales/vi.yml +9 -6
- data/locales/zh-CN.yml +9 -6
- data/locales/zh-HK.yml +9 -6
- data/locales/zh-TW.yml +9 -6
- data/stylesheets/pagy-tailwind.css +64 -0
- data/stylesheets/pagy.css +63 -27
- metadata +114 -56
- data/javascripts/pagy.min.js.map +0 -10
- data/lib/pagy/backend.rb +0 -44
- data/lib/pagy/calendar/unit.rb +0 -103
- data/lib/pagy/calendar.rb +0 -84
- data/lib/pagy/console.rb +0 -23
- data/lib/pagy/countless.rb +0 -38
- data/lib/pagy/exceptions.rb +0 -25
- data/lib/pagy/extras/arel.rb +0 -28
- data/lib/pagy/extras/array.rb +0 -19
- data/lib/pagy/extras/bootstrap.rb +0 -97
- data/lib/pagy/extras/bulma.rb +0 -93
- data/lib/pagy/extras/calendar.rb +0 -79
- data/lib/pagy/extras/countless.rb +0 -32
- data/lib/pagy/extras/elasticsearch_rails.rb +0 -71
- data/lib/pagy/extras/gearbox.rb +0 -55
- data/lib/pagy/extras/headers.rb +0 -54
- data/lib/pagy/extras/i18n.rb +0 -26
- data/lib/pagy/extras/js_tools.rb +0 -70
- data/lib/pagy/extras/jsonapi.rb +0 -86
- data/lib/pagy/extras/keyset.rb +0 -30
- data/lib/pagy/extras/limit.rb +0 -63
- data/lib/pagy/extras/meilisearch.rb +0 -57
- data/lib/pagy/extras/metadata.rb +0 -42
- data/lib/pagy/extras/overflow.rb +0 -81
- data/lib/pagy/extras/pagy.rb +0 -82
- data/lib/pagy/extras/searchkick.rb +0 -59
- data/lib/pagy/extras/size.rb +0 -40
- data/lib/pagy/extras/standalone.rb +0 -60
- data/lib/pagy/extras/trim.rb +0 -29
- data/lib/pagy/frontend.rb +0 -99
- data/lib/pagy/i18n.rb +0 -166
- data/lib/pagy/keyset/active_record.rb +0 -38
- data/lib/pagy/keyset/sequel.rb +0 -51
- data/lib/pagy/keyset.rb +0 -118
- data/lib/pagy/shared_methods.rb +0 -26
- data/lib/pagy/url_helpers.rb +0 -26
- data/stylesheets/pagy.scss +0 -48
- data/stylesheets/pagy.tailwind.css +0 -21
data/lib/pagy/i18n.rb
DELETED
@@ -1,166 +0,0 @@
|
|
1
|
-
# See Pagy::I18n API documentation https://ddnexus.github.io/pagy/docs/api/i18n
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require 'yaml'
|
5
|
-
|
6
|
-
class Pagy
|
7
|
-
# Pagy i18n implementation, compatible with the I18n gem, just a lot faster and lighter
|
8
|
-
module I18n
|
9
|
-
extend self
|
10
|
-
|
11
|
-
# Pluralization rules
|
12
|
-
module P11n
|
13
|
-
# Pluralization variables
|
14
|
-
from0to1 = (0..1).to_a.freeze
|
15
|
-
from2to4 = (2..4).to_a.freeze
|
16
|
-
from3to10 = (3..10).to_a.freeze
|
17
|
-
from5to9 = (5..9).to_a.freeze
|
18
|
-
from11to14 = (11..14).to_a.freeze
|
19
|
-
from11to99 = (11..99).to_a.freeze
|
20
|
-
from12to14 = (12..14).to_a.freeze
|
21
|
-
|
22
|
-
from0to1_from5to9 = from0to1 + from5to9
|
23
|
-
|
24
|
-
# Store the proc defining each pluralization RULE
|
25
|
-
# Logic adapted from https://github.com/svenfuchs/rails-i18n
|
26
|
-
RULE = {
|
27
|
-
arabic:
|
28
|
-
lambda do |n = 0|
|
29
|
-
mod100 = n % 100
|
30
|
-
case
|
31
|
-
when n == 0 then 'zero' # rubocop:disable Style/NumericPredicate
|
32
|
-
when n == 1 then 'one'
|
33
|
-
when n == 2 then 'two'
|
34
|
-
when from3to10.include?(mod100) then 'few'
|
35
|
-
when from11to99.include?(mod100) then 'many'
|
36
|
-
else 'other'
|
37
|
-
end
|
38
|
-
end,
|
39
|
-
|
40
|
-
east_slavic:
|
41
|
-
lambda do |n = 0|
|
42
|
-
mod10 = n % 10
|
43
|
-
mod100 = n % 100
|
44
|
-
case
|
45
|
-
when mod10 == 1 && mod100 != 11 then 'one'
|
46
|
-
when from2to4.include?(mod10) && !from12to14.include?(mod100) then 'few'
|
47
|
-
when mod10 == 0 || from5to9.include?(mod10) || from11to14.include?(mod100) then 'many' # rubocop:disable Style/NumericPredicate
|
48
|
-
else 'other'
|
49
|
-
end
|
50
|
-
end,
|
51
|
-
|
52
|
-
one_other:
|
53
|
-
->(n) { n == 1 ? 'one' : 'other' }, # default RULE
|
54
|
-
|
55
|
-
one_two_other:
|
56
|
-
lambda do |n|
|
57
|
-
case n
|
58
|
-
when 1 then 'one'
|
59
|
-
when 2 then 'two'
|
60
|
-
else 'other'
|
61
|
-
end
|
62
|
-
end,
|
63
|
-
|
64
|
-
one_upto_two_other:
|
65
|
-
->(n) { n && n >= 0 && n < 2 ? 'one' : 'other' },
|
66
|
-
|
67
|
-
other:
|
68
|
-
->(*) { 'other' },
|
69
|
-
|
70
|
-
polish:
|
71
|
-
lambda do |n = 0|
|
72
|
-
mod10 = n % 10
|
73
|
-
mod100 = n % 100
|
74
|
-
case
|
75
|
-
when n == 1 then 'one'
|
76
|
-
when from2to4.include?(mod10) && !from12to14.include?(mod100) then 'few'
|
77
|
-
when from0to1_from5to9.include?(mod10) || from12to14.include?(mod100) then 'many'
|
78
|
-
else 'other'
|
79
|
-
end
|
80
|
-
end,
|
81
|
-
|
82
|
-
west_slavic:
|
83
|
-
lambda do |n|
|
84
|
-
case n
|
85
|
-
when 1 then 'one'
|
86
|
-
when *from2to4 then 'few'
|
87
|
-
else 'other'
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
}.freeze
|
92
|
-
|
93
|
-
# Store the RULE to apply to each LOCALE
|
94
|
-
# the :one_other RULE is the default for locales missing from this list
|
95
|
-
LOCALE = Hash.new(RULE[:one_other]).tap do |hash|
|
96
|
-
hash['ar'] = RULE[:arabic]
|
97
|
-
hash['be'] = RULE[:east_slavic]
|
98
|
-
hash['bs'] = RULE[:east_slavic]
|
99
|
-
hash['ckb'] = RULE[:other]
|
100
|
-
hash['cs'] = RULE[:west_slavic]
|
101
|
-
hash['id'] = RULE[:other]
|
102
|
-
hash['fr'] = RULE[:one_upto_two_other]
|
103
|
-
hash['hr'] = RULE[:east_slavic]
|
104
|
-
hash['ja'] = RULE[:other]
|
105
|
-
hash['km'] = RULE[:other]
|
106
|
-
hash['ko'] = RULE[:other]
|
107
|
-
hash['pl'] = RULE[:polish]
|
108
|
-
hash['ru'] = RULE[:east_slavic]
|
109
|
-
hash['sr'] = RULE[:east_slavic]
|
110
|
-
hash['tr'] = RULE[:other]
|
111
|
-
hash['uk'] = RULE[:east_slavic]
|
112
|
-
hash['vi'] = RULE[:other]
|
113
|
-
hash['zh-CN'] = RULE[:other]
|
114
|
-
hash['zh-HK'] = RULE[:other]
|
115
|
-
hash['zh-TW'] = RULE[:other]
|
116
|
-
hash['dz'] = RULE[:other]
|
117
|
-
end.freeze
|
118
|
-
end
|
119
|
-
|
120
|
-
# Stores the i18n DATA structure for each loaded locale
|
121
|
-
# default on the first locale DATA
|
122
|
-
DATA = Hash.new { |hash,| hash.first[1] }
|
123
|
-
|
124
|
-
private
|
125
|
-
|
126
|
-
# Create a flat hash with dotted notation keys
|
127
|
-
def flatten(initial, prefix = '')
|
128
|
-
initial.each.reduce({}) do |hash, (key, value)|
|
129
|
-
hash.merge!(value.is_a?(Hash) ? flatten(value, "#{prefix}#{key}.") : { "#{prefix}#{key}" => value })
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
# Build the DATA hash out of the passed locales
|
134
|
-
def build(*locales)
|
135
|
-
locales.each do |locale|
|
136
|
-
locale[:filepath] ||= Pagy.root.join('locales', "#{locale[:locale]}.yml")
|
137
|
-
locale[:pluralize] ||= P11n::LOCALE[locale[:locale]]
|
138
|
-
dictionary = YAML.safe_load(File.read(locale[:filepath], encoding: 'UTF-8'))
|
139
|
-
raise I18nError, %(expected :locale "#{locale[:locale]}" not found in :filepath "#{locale[:filepath].inspect}") \
|
140
|
-
unless dictionary.key?(locale[:locale])
|
141
|
-
|
142
|
-
DATA[locale[:locale]] = [flatten(dictionary[locale[:locale]]), locale[:pluralize]]
|
143
|
-
end
|
144
|
-
end
|
145
|
-
# Build the default at require time
|
146
|
-
build(locale: 'en')
|
147
|
-
|
148
|
-
public
|
149
|
-
|
150
|
-
# Public method to configure the locales: overrides the default, build the DATA and freezes it
|
151
|
-
def load(*locales)
|
152
|
-
DATA.clear
|
153
|
-
build(*locales)
|
154
|
-
DATA.freeze
|
155
|
-
end
|
156
|
-
|
157
|
-
# Translate and pluralize the key with the locale DATA
|
158
|
-
def translate(locale, key, **opts)
|
159
|
-
data, pluralize = DATA[locale]
|
160
|
-
translation = data[key] || (opts[:count] && data[key += ".#{pluralize.call(opts[:count])}"]) \
|
161
|
-
or return %([translation missing: "#{key}"])
|
162
|
-
translation.gsub(/%{[^}]+?}/) { |match| opts[:"#{match[2..-2]}"] || match }
|
163
|
-
end
|
164
|
-
alias t translate
|
165
|
-
end
|
166
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# See Pagy API documentation: https://ddnexus.github.io/pagy/docs/api/keyset
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
class Pagy
|
5
|
-
class Keyset
|
6
|
-
# Keyset adapter for ActiveRecord
|
7
|
-
class ActiveRecord < Keyset
|
8
|
-
protected
|
9
|
-
|
10
|
-
# Get the keyset attributes from the record
|
11
|
-
def keyset_attributes_from(record) = record.slice(*@keyset.keys)
|
12
|
-
|
13
|
-
# Extract the keyset from the set
|
14
|
-
def extract_keyset
|
15
|
-
@set.order_values.each_with_object({}) do |node, keyset|
|
16
|
-
keyset[node.value.name.to_sym] = node.direction
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# Filter the newest records
|
21
|
-
def filter_newest = @set.where(filter_newest_query, **@latest)
|
22
|
-
|
23
|
-
# Append the missing keyset keys if the set is restricted by select
|
24
|
-
def apply_select
|
25
|
-
@set.select(*@keyset.keys)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Set with selected columns?
|
29
|
-
def select? = !@set.select_values.empty?
|
30
|
-
|
31
|
-
# Typecast the latest attributes
|
32
|
-
def typecast_latest(latest)
|
33
|
-
@set.model.new(latest).slice(latest.keys)
|
34
|
-
.to_hash.transform_keys(&:to_sym)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
data/lib/pagy/keyset/sequel.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
# See Pagy API documentation: https://ddnexus.github.io/pagy/docs/api/keyset
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
class Pagy
|
5
|
-
class Keyset
|
6
|
-
# Keyset adapter for sequel
|
7
|
-
class Sequel < Keyset
|
8
|
-
protected
|
9
|
-
|
10
|
-
# Get the keyset attributes from the record
|
11
|
-
def keyset_attributes_from(record) = record.to_hash.slice(*@keyset.keys)
|
12
|
-
|
13
|
-
# Extract the keyset from the set
|
14
|
-
def extract_keyset
|
15
|
-
return {} unless @set.opts[:order]
|
16
|
-
|
17
|
-
@set.opts[:order].each_with_object({}) do |item, keyset|
|
18
|
-
case item
|
19
|
-
when Symbol
|
20
|
-
keyset[item] = :asc
|
21
|
-
when ::Sequel::SQL::OrderedExpression
|
22
|
-
keyset[item.expression] = item.descending ? :desc : :asc
|
23
|
-
else
|
24
|
-
raise TypeError, "#{item.class.inspect} is not a supported Sequel::SQL::OrderedExpression"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
# Filter the newest records
|
30
|
-
def filter_newest = @set.where(::Sequel.lit(filter_newest_query, **@latest))
|
31
|
-
|
32
|
-
# Append the missing keyset keys if the set is restricted by select
|
33
|
-
def apply_select
|
34
|
-
selected = @set.opts[:select]
|
35
|
-
@set.select_append(*@keyset.keys.reject { |c| selected.include?(c) })
|
36
|
-
end
|
37
|
-
|
38
|
-
# Set with selected columns?
|
39
|
-
def select? = !@set.opts[:select].nil?
|
40
|
-
|
41
|
-
# Typecast the latest attributes
|
42
|
-
def typecast_latest(latest)
|
43
|
-
model = @set.opts[:model]
|
44
|
-
model.unrestrict_primary_key if (restricted_pk = model.restrict_primary_key?)
|
45
|
-
latest = model.new(latest).to_hash.slice(*latest.keys.map(&:to_sym))
|
46
|
-
model.restrict_primary_key if restricted_pk
|
47
|
-
latest
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
data/lib/pagy/keyset.rb
DELETED
@@ -1,118 +0,0 @@
|
|
1
|
-
# See Pagy API documentation: https://ddnexus.github.io/pagy/docs/api/keyset
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require 'json'
|
5
|
-
require_relative 'b64'
|
6
|
-
require_relative 'shared_methods'
|
7
|
-
|
8
|
-
class Pagy
|
9
|
-
# Implement wicked-fast keyset pagination for big data
|
10
|
-
class Keyset
|
11
|
-
class TypeError < ::TypeError; end
|
12
|
-
|
13
|
-
include SharedMethods
|
14
|
-
|
15
|
-
# Pick the right adapter for the set
|
16
|
-
def self.new(set, **vars)
|
17
|
-
if self == Pagy::Keyset
|
18
|
-
if defined?(::ActiveRecord) && set.is_a?(::ActiveRecord::Relation)
|
19
|
-
ActiveRecord
|
20
|
-
elsif defined?(::Sequel) && set.is_a?(::Sequel::Dataset)
|
21
|
-
Sequel
|
22
|
-
else
|
23
|
-
raise TypeError, "expected set to be an instance of ActiveRecord::Relation or Sequel::Dataset; got #{set.class}"
|
24
|
-
end.new(set, **vars)
|
25
|
-
else
|
26
|
-
allocate.tap { |instance| instance.send(:initialize, set, **vars) }
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
attr_reader :latest # Other readers from SharedMethods
|
31
|
-
|
32
|
-
def initialize(set, **vars)
|
33
|
-
default = DEFAULT.slice(:limit, :page_param, # from pagy
|
34
|
-
:headers, # from headers extra
|
35
|
-
:jsonapi, # from jsonapi extra
|
36
|
-
:limit_param, :limit_max, :limit_extra) # from limit_extra
|
37
|
-
assign_vars({ **default, page: nil }, vars)
|
38
|
-
assign_limit
|
39
|
-
@set = set
|
40
|
-
@page = @vars[:page]
|
41
|
-
@keyset = extract_keyset
|
42
|
-
raise InternalError, 'the set must be ordered' if @keyset.empty?
|
43
|
-
return unless @page
|
44
|
-
|
45
|
-
latest = JSON.parse(B64.urlsafe_decode(@page)).transform_keys(&:to_sym)
|
46
|
-
@latest = typecast_latest(latest)
|
47
|
-
raise InternalError, 'page and keyset are not consistent' \
|
48
|
-
unless @latest.keys == @keyset.keys
|
49
|
-
end
|
50
|
-
|
51
|
-
# Return the next page
|
52
|
-
def next
|
53
|
-
records
|
54
|
-
return unless @more
|
55
|
-
|
56
|
-
@next ||= begin
|
57
|
-
hash = keyset_attributes_from(@records.last)
|
58
|
-
json = @vars[:jsonify_keyset_attributes]&.(hash) || hash.to_json
|
59
|
-
B64.urlsafe_encode(json)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
# Fetch the array of records for the current page
|
64
|
-
def records
|
65
|
-
@records ||= begin
|
66
|
-
@set = apply_select if select?
|
67
|
-
if @latest
|
68
|
-
# :nocov:
|
69
|
-
@set = @vars[:after_latest]&.(@set, @latest) || # deprecated
|
70
|
-
# :nocov:
|
71
|
-
@vars[:filter_newest]&.(@set, @latest, @keyset) ||
|
72
|
-
filter_newest
|
73
|
-
end
|
74
|
-
records = @set.limit(@limit + 1).to_a
|
75
|
-
@more = records.size > @limit && !records.pop.nil?
|
76
|
-
records
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
protected
|
81
|
-
|
82
|
-
# Prepare the literal query string (complete with the placeholders for value interpolation)
|
83
|
-
# used to filter the newest records.
|
84
|
-
# For example:
|
85
|
-
# With a set like Pet.order(animal: :asc, name: :desc, id: :asc) it returns the following string:
|
86
|
-
# ( "pets"."animal" = :animal AND "pets"."name" = :name AND "pets"."id" > :id ) OR
|
87
|
-
# ( "pets"."animal" = :animal AND "pets"."name" < :name ) OR
|
88
|
-
# ( "pets"."animal" > :animal )
|
89
|
-
# When :tuple_comparison is enabled, and if the order is all :asc or all :desc,
|
90
|
-
# with a set like Pet.order(:animal, :name, :id) it returns the following string:
|
91
|
-
# ( "pets"."animal", "pets"."name", "pets"."id" ) > ( :animal, :name, :id )
|
92
|
-
def filter_newest_query
|
93
|
-
operator = { asc: '>', desc: '<' }
|
94
|
-
directions = @keyset.values
|
95
|
-
table = @set.model.table_name
|
96
|
-
name = @keyset.to_h { |column| [column, %("#{table}"."#{column}")] }
|
97
|
-
if @vars[:tuple_comparison] && (directions.all?(:asc) || directions.all?(:desc))
|
98
|
-
placeholders = @keyset.keys.map { |column| ":#{column}" }.join(', ')
|
99
|
-
"( #{name.values.join(', ')} ) #{operator[directions.first]} ( #{placeholders} )"
|
100
|
-
else
|
101
|
-
keyset = @keyset.to_a
|
102
|
-
where = []
|
103
|
-
until keyset.empty?
|
104
|
-
last_column, last_direction = keyset.pop
|
105
|
-
query = +'( '
|
106
|
-
query << (keyset.map { |column, _d| "#{name[column]} = :#{column}" } \
|
107
|
-
<< "#{name[last_column]} #{operator[last_direction]} :#{last_column}").join(' AND ')
|
108
|
-
query << ' )'
|
109
|
-
where << query
|
110
|
-
end
|
111
|
-
where.join(' OR ')
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
require_relative 'keyset/active_record'
|
118
|
-
require_relative 'keyset/sequel'
|
data/lib/pagy/shared_methods.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Pagy
|
4
|
-
# Shared with Keyset
|
5
|
-
module SharedMethods
|
6
|
-
attr_reader :page, :limit, :vars
|
7
|
-
|
8
|
-
# Validates and assign the passed vars: var must be present and value.to_i must be >= to min
|
9
|
-
def assign_and_check(name_min)
|
10
|
-
name_min.each do |name, min|
|
11
|
-
raise VariableError.new(self, name, ">= #{min}", @vars[name]) \
|
12
|
-
unless @vars[name]&.respond_to?(:to_i) && instance_variable_set(:"@#{name}", @vars[name].to_i) >= min
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
# Assign @limit (overridden by the gearbox extra)
|
17
|
-
def assign_limit
|
18
|
-
assign_and_check(limit: 1)
|
19
|
-
end
|
20
|
-
|
21
|
-
# Assign @vars
|
22
|
-
def assign_vars(default, vars)
|
23
|
-
@vars = { **default, **vars.delete_if { |k, v| default.key?(k) && (v.nil? || v == '') } }
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
data/lib/pagy/url_helpers.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Pagy
|
4
|
-
# Provide the helpers to handle the url in frontend and backend
|
5
|
-
module UrlHelpers
|
6
|
-
# Return the URL for the page, relying on the params method and Rack by default.
|
7
|
-
# It supports all Rack-based frameworks (Sinatra, Padrino, Rails, ...).
|
8
|
-
# For non-rack environments you can use the standalone extra
|
9
|
-
def pagy_url_for(pagy, page, absolute: false, fragment: nil, **_)
|
10
|
-
vars = pagy.vars
|
11
|
-
query_params = request.GET.clone(freeze: false)
|
12
|
-
query_params.merge!(vars[:params].transform_keys(&:to_s)) if vars[:params].is_a?(Hash)
|
13
|
-
pagy_set_query_params(page, vars, query_params)
|
14
|
-
query_params = vars[:params].(query_params) if vars[:params].is_a?(Proc)
|
15
|
-
query_string = "?#{Rack::Utils.build_nested_query(query_params)}"
|
16
|
-
"#{request.base_url if absolute}#{vars[:request_path] || request.path}#{query_string}#{fragment}"
|
17
|
-
end
|
18
|
-
|
19
|
-
# Add the page and limit params
|
20
|
-
# Overridable by the jsonapi extra
|
21
|
-
def pagy_set_query_params(page, vars, query_params)
|
22
|
-
query_params[vars[:page_param].to_s] = page
|
23
|
-
query_params[vars[:limit_param].to_s] = vars[:limit] if vars[:limit_extra]
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
data/stylesheets/pagy.scss
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
.pagy {
|
2
|
-
display: flex;
|
3
|
-
font-family: sans-serif;
|
4
|
-
font-size: 0.875rem;
|
5
|
-
line-height: 1.25rem;
|
6
|
-
font-weight: 600;
|
7
|
-
color: rgb(107 114 128);
|
8
|
-
& > :not([hidden]) ~ :not([hidden]) {
|
9
|
-
--space-reverse: 0;
|
10
|
-
margin-right: calc(0.25rem * var(--space-reverse));
|
11
|
-
margin-left: calc(0.25rem * calc(1 - var(--space-reverse)));
|
12
|
-
}
|
13
|
-
|
14
|
-
a:not(.gap) {
|
15
|
-
display: block;
|
16
|
-
text-decoration: none;
|
17
|
-
border-radius: 0.5rem;
|
18
|
-
background-color: rgb(229 231 235);
|
19
|
-
padding: 0.25rem 0.75rem;
|
20
|
-
color: inherit;
|
21
|
-
&:hover {
|
22
|
-
background-color: rgb(209 213 219);
|
23
|
-
}
|
24
|
-
&:not([href]) { /* disabled links */
|
25
|
-
cursor: default;
|
26
|
-
background-color: rgb(243 244 246);
|
27
|
-
color: rgb(209 213 219);
|
28
|
-
}
|
29
|
-
&.current {
|
30
|
-
background-color: rgb(156 163 175);
|
31
|
-
color: rgb(255 255 255);
|
32
|
-
}
|
33
|
-
}
|
34
|
-
|
35
|
-
label {
|
36
|
-
white-space: nowrap;
|
37
|
-
display: inline-block;
|
38
|
-
border-radius: 0.5rem;
|
39
|
-
background-color: rgb(229 231 235);
|
40
|
-
padding: 0.125rem 0.75rem;
|
41
|
-
input {
|
42
|
-
line-height: 1.5rem;
|
43
|
-
border-radius: 0.375rem;
|
44
|
-
border-style: none;
|
45
|
-
background-color: rgb(243 244 246);
|
46
|
-
}
|
47
|
-
}
|
48
|
-
}
|
@@ -1,21 +0,0 @@
|
|
1
|
-
.pagy {
|
2
|
-
@apply flex space-x-1 font-semibold text-sm text-gray-500;
|
3
|
-
a:not(.gap) {
|
4
|
-
@apply block rounded-lg px-3 py-1 bg-gray-200;
|
5
|
-
&:hover {
|
6
|
-
@apply bg-gray-300;
|
7
|
-
}
|
8
|
-
&:not([href]) { /* disabled links */
|
9
|
-
@apply text-gray-300 bg-gray-100 cursor-default;
|
10
|
-
}
|
11
|
-
&.current {
|
12
|
-
@apply text-white bg-gray-400;
|
13
|
-
}
|
14
|
-
}
|
15
|
-
label {
|
16
|
-
@apply inline-block whitespace-nowrap bg-gray-200 rounded-lg px-3 py-0.5;
|
17
|
-
input {
|
18
|
-
@apply bg-gray-100 border-none rounded-md;
|
19
|
-
}
|
20
|
-
}
|
21
|
-
}
|