pagy 7.0.11 → 43.5.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.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/apps/calendar.ru +741 -0
  4. data/apps/demo.ru +513 -0
  5. data/apps/enable_rails_page_segment.rb +54 -0
  6. data/apps/index.rb +9 -0
  7. data/apps/keynav+root_key.ru +316 -0
  8. data/apps/keynav.ru +255 -0
  9. data/apps/keyset.ru +219 -0
  10. data/apps/keyset_sequel.ru +212 -0
  11. data/apps/rails.ru +216 -0
  12. data/apps/repro.ru +185 -0
  13. data/bin/pagy +5 -0
  14. data/config/pagy.rb +46 -0
  15. data/javascripts/ai_widget.js +90 -0
  16. data/javascripts/pagy.js +168 -0
  17. data/javascripts/pagy.min.js +2 -0
  18. data/javascripts/pagy.mjs +161 -0
  19. data/javascripts/wand.js +1172 -0
  20. data/lib/pagy/classes/calendar/calendar.rb +101 -0
  21. data/lib/pagy/{calendar → classes/calendar}/day.rb +9 -12
  22. data/lib/pagy/{calendar → classes/calendar}/month.rb +7 -11
  23. data/lib/pagy/{calendar → classes/calendar}/quarter.rb +12 -16
  24. data/lib/pagy/classes/calendar/unit.rb +93 -0
  25. data/lib/pagy/{calendar → classes/calendar}/week.rb +7 -11
  26. data/lib/pagy/{calendar → classes/calendar}/year.rb +9 -9
  27. data/lib/pagy/classes/exceptions.rb +26 -0
  28. data/lib/pagy/classes/keyset/adapters/active_record.rb +50 -0
  29. data/lib/pagy/classes/keyset/adapters/sequel.rb +62 -0
  30. data/lib/pagy/classes/keyset/keynav.rb +85 -0
  31. data/lib/pagy/classes/keyset/keyset.rb +150 -0
  32. data/lib/pagy/classes/offset/countish.rb +17 -0
  33. data/lib/pagy/classes/offset/countless.rb +63 -0
  34. data/lib/pagy/classes/offset/offset.rb +63 -0
  35. data/lib/pagy/classes/offset/search.rb +34 -0
  36. data/lib/pagy/classes/request.rb +48 -0
  37. data/lib/pagy/cli.rb +122 -0
  38. data/lib/pagy/console.rb +5 -20
  39. data/lib/pagy/deprecated.rb +84 -0
  40. data/lib/pagy/modules/abilities/configurable.rb +37 -0
  41. data/lib/pagy/modules/abilities/countable.rb +23 -0
  42. data/lib/pagy/modules/abilities/linkable.rb +72 -0
  43. data/lib/pagy/modules/abilities/rangeable.rb +14 -0
  44. data/lib/pagy/modules/abilities/shiftable.rb +12 -0
  45. data/lib/pagy/modules/b64.rb +35 -0
  46. data/lib/pagy/modules/console.rb +33 -0
  47. data/lib/pagy/modules/i18n/i18n.rb +72 -0
  48. data/lib/pagy/modules/i18n/p11n/arabic.rb +30 -0
  49. data/lib/pagy/modules/i18n/p11n/east_slavic.rb +27 -0
  50. data/lib/pagy/modules/i18n/p11n/one_other.rb +15 -0
  51. data/lib/pagy/modules/i18n/p11n/one_upto_two_other.rb +15 -0
  52. data/lib/pagy/modules/i18n/p11n/other.rb +13 -0
  53. data/lib/pagy/modules/i18n/p11n/polish.rb +27 -0
  54. data/lib/pagy/modules/i18n/p11n/west_slavic.rb +22 -0
  55. data/lib/pagy/modules/i18n/p11n.rb +16 -0
  56. data/lib/pagy/modules/searcher.rb +20 -0
  57. data/lib/pagy/next.rb +25 -0
  58. data/lib/pagy/tasks/sync.rb +20 -0
  59. data/lib/pagy/toolbox/helpers/anchor_tags.rb +21 -0
  60. data/lib/pagy/toolbox/helpers/bootstrap/input_nav_js.rb +28 -0
  61. data/lib/pagy/toolbox/helpers/bootstrap/previous_next_html.rb +19 -0
  62. data/lib/pagy/toolbox/helpers/bootstrap/series_nav.rb +32 -0
  63. data/lib/pagy/toolbox/helpers/bootstrap/series_nav_js.rb +24 -0
  64. data/lib/pagy/toolbox/helpers/bulma/input_nav_js.rb +25 -0
  65. data/lib/pagy/toolbox/helpers/bulma/previous_next_html.rb +20 -0
  66. data/lib/pagy/toolbox/helpers/bulma/series_nav.rb +31 -0
  67. data/lib/pagy/toolbox/helpers/bulma/series_nav_js.rb +23 -0
  68. data/lib/pagy/toolbox/helpers/data_hash.rb +29 -0
  69. data/lib/pagy/toolbox/helpers/headers_hash.rb +30 -0
  70. data/lib/pagy/toolbox/helpers/info_tag.rb +30 -0
  71. data/lib/pagy/toolbox/helpers/input_nav_js.rb +22 -0
  72. data/lib/pagy/toolbox/helpers/limit_tag_js.rb +25 -0
  73. data/lib/pagy/toolbox/helpers/loaders.rb +55 -0
  74. data/lib/pagy/toolbox/helpers/page_url.rb +16 -0
  75. data/lib/pagy/toolbox/helpers/series_nav.rb +30 -0
  76. data/lib/pagy/toolbox/helpers/series_nav_js.rb +20 -0
  77. data/lib/pagy/toolbox/helpers/support/a_lambda.rb +36 -0
  78. data/lib/pagy/toolbox/helpers/support/data_pagy_attribute.rb +19 -0
  79. data/lib/pagy/toolbox/helpers/support/nav_aria_label_attribute.rb +10 -0
  80. data/lib/pagy/toolbox/helpers/support/series.rb +37 -0
  81. data/lib/pagy/toolbox/helpers/support/wrap_input_nav_js.rb +19 -0
  82. data/lib/pagy/toolbox/helpers/support/wrap_series_nav.rb +17 -0
  83. data/lib/pagy/toolbox/helpers/support/wrap_series_nav_js.rb +42 -0
  84. data/lib/pagy/toolbox/helpers/urls_hash.rb +12 -0
  85. data/lib/pagy/toolbox/paginators/calendar.rb +34 -0
  86. data/lib/pagy/toolbox/paginators/countish.rb +38 -0
  87. data/lib/pagy/toolbox/paginators/countless.rb +22 -0
  88. data/lib/pagy/toolbox/paginators/elasticsearch_rails.rb +56 -0
  89. data/lib/pagy/toolbox/paginators/keynav_js.rb +26 -0
  90. data/lib/pagy/toolbox/paginators/keyset.rb +15 -0
  91. data/lib/pagy/toolbox/paginators/meilisearch.rb +34 -0
  92. data/lib/pagy/toolbox/paginators/method.rb +38 -0
  93. data/lib/pagy/toolbox/paginators/offset.rb +24 -0
  94. data/lib/pagy/toolbox/paginators/searchkick.rb +34 -0
  95. data/lib/pagy/toolbox/paginators/typesense_rails.rb +34 -0
  96. data/lib/pagy.rb +67 -131
  97. data/locales/ar.yml +32 -0
  98. data/locales/be.yml +28 -0
  99. data/locales/bg.yml +24 -0
  100. data/locales/bs.yml +28 -0
  101. data/locales/ca.yml +24 -0
  102. data/locales/ckb.yml +20 -0
  103. data/locales/cs.yml +26 -0
  104. data/locales/da.yml +24 -0
  105. data/locales/de.yml +24 -0
  106. data/locales/dz.yml +20 -0
  107. data/locales/en.yml +24 -0
  108. data/{lib/locales → locales}/es.yml +9 -6
  109. data/locales/fr.yml +24 -0
  110. data/locales/hr.yml +28 -0
  111. data/locales/id.yml +20 -0
  112. data/locales/it.yml +24 -0
  113. data/locales/ja.yml +20 -0
  114. data/locales/km.yml +20 -0
  115. data/locales/ko.yml +20 -0
  116. data/locales/nb.yml +24 -0
  117. data/locales/nl.yml +24 -0
  118. data/locales/nn.yml +24 -0
  119. data/locales/pl.yml +28 -0
  120. data/{lib/locales → locales}/pt-BR.yml +10 -7
  121. data/{lib/locales → locales}/pt.yml +10 -7
  122. data/locales/ru.yml +28 -0
  123. data/locales/sk.yml +26 -0
  124. data/locales/sr.yml +28 -0
  125. data/locales/sv-SE.yml +24 -0
  126. data/locales/sv.yml +24 -0
  127. data/locales/sw.yml +28 -0
  128. data/locales/ta.yml +24 -0
  129. data/locales/tr.yml +24 -0
  130. data/locales/uk.yml +28 -0
  131. data/locales/vi.yml +20 -0
  132. data/locales/zh-CN.yml +20 -0
  133. data/locales/zh-HK.yml +20 -0
  134. data/locales/zh-TW.yml +20 -0
  135. data/stylesheets/pagy-tailwind.css +68 -0
  136. data/stylesheets/pagy.css +83 -0
  137. metadata +185 -94
  138. data/lib/config/pagy.rb +0 -258
  139. data/lib/javascripts/pagy-dev.js +0 -112
  140. data/lib/javascripts/pagy-module.js +0 -111
  141. data/lib/javascripts/pagy.js +0 -1
  142. data/lib/locales/ar.yml +0 -30
  143. data/lib/locales/be.yml +0 -25
  144. data/lib/locales/bg.yml +0 -21
  145. data/lib/locales/bs.yml +0 -25
  146. data/lib/locales/ca.yml +0 -23
  147. data/lib/locales/ckb.yml +0 -18
  148. data/lib/locales/cs.yml +0 -23
  149. data/lib/locales/da.yml +0 -23
  150. data/lib/locales/de.yml +0 -21
  151. data/lib/locales/en.yml +0 -21
  152. data/lib/locales/fr.yml +0 -21
  153. data/lib/locales/hr.yml +0 -25
  154. data/lib/locales/id.yml +0 -19
  155. data/lib/locales/it.yml +0 -21
  156. data/lib/locales/ja.yml +0 -19
  157. data/lib/locales/km.yml +0 -19
  158. data/lib/locales/ko.yml +0 -19
  159. data/lib/locales/nb.yml +0 -21
  160. data/lib/locales/nl.yml +0 -21
  161. data/lib/locales/nn.yml +0 -21
  162. data/lib/locales/pl.yml +0 -25
  163. data/lib/locales/ru.yml +0 -27
  164. data/lib/locales/sr.yml +0 -25
  165. data/lib/locales/sv-SE.yml +0 -21
  166. data/lib/locales/sv.yml +0 -21
  167. data/lib/locales/sw.yml +0 -23
  168. data/lib/locales/ta.yml +0 -23
  169. data/lib/locales/tr.yml +0 -19
  170. data/lib/locales/uk.yml +0 -25
  171. data/lib/locales/vi.yml +0 -17
  172. data/lib/locales/zh-CN.yml +0 -19
  173. data/lib/locales/zh-HK.yml +0 -19
  174. data/lib/locales/zh-TW.yml +0 -19
  175. data/lib/pagy/backend.rb +0 -39
  176. data/lib/pagy/calendar/helper.rb +0 -65
  177. data/lib/pagy/calendar.rb +0 -126
  178. data/lib/pagy/countless.rb +0 -37
  179. data/lib/pagy/exceptions.rb +0 -25
  180. data/lib/pagy/extras/arel.rb +0 -36
  181. data/lib/pagy/extras/array.rb +0 -24
  182. data/lib/pagy/extras/bootstrap.rb +0 -108
  183. data/lib/pagy/extras/bulma.rb +0 -105
  184. data/lib/pagy/extras/calendar.rb +0 -53
  185. data/lib/pagy/extras/countless.rb +0 -37
  186. data/lib/pagy/extras/elasticsearch_rails.rb +0 -80
  187. data/lib/pagy/extras/foundation.rb +0 -105
  188. data/lib/pagy/extras/frontend_helpers.rb +0 -67
  189. data/lib/pagy/extras/gearbox.rb +0 -54
  190. data/lib/pagy/extras/headers.rb +0 -53
  191. data/lib/pagy/extras/i18n.rb +0 -26
  192. data/lib/pagy/extras/items.rb +0 -61
  193. data/lib/pagy/extras/jsonapi.rb +0 -79
  194. data/lib/pagy/extras/materialize.rb +0 -96
  195. data/lib/pagy/extras/meilisearch.rb +0 -65
  196. data/lib/pagy/extras/metadata.rb +0 -38
  197. data/lib/pagy/extras/navs.rb +0 -51
  198. data/lib/pagy/extras/overflow.rb +0 -80
  199. data/lib/pagy/extras/searchkick.rb +0 -67
  200. data/lib/pagy/extras/semantic.rb +0 -95
  201. data/lib/pagy/extras/standalone.rb +0 -60
  202. data/lib/pagy/extras/support.rb +0 -40
  203. data/lib/pagy/extras/trim.rb +0 -29
  204. data/lib/pagy/extras/uikit.rb +0 -97
  205. data/lib/pagy/frontend.rb +0 -114
  206. data/lib/pagy/i18n.rb +0 -165
  207. data/lib/pagy/url_helpers.rb +0 -27
  208. data/lib/stylesheets/pagy.css +0 -61
  209. data/lib/stylesheets/pagy.scss +0 -50
  210. data/lib/stylesheets/pagy.tailwind.scss +0 -24
  211. /data/{lib/javascripts/pagy-module.d.ts → javascripts/pagy.d.ts} +0 -0
data/apps/keyset.ru ADDED
@@ -0,0 +1,219 @@
1
+ # frozen_string_literal: true
2
+
3
+ # DESCRIPTION
4
+ # Showcase the Keyset pagination (ActiveRecord example)
5
+ #
6
+ # DOC
7
+ # https://ddnexus.github.io/pagy/playground/#keyset-apps
8
+ #
9
+ # BIN HELP
10
+ # pagy -h
11
+ #
12
+ # DEV USAGE
13
+ # pagy clone keyset
14
+ # pagy ./keyset.ru
15
+ #
16
+ # URL
17
+ # http://127.0.0.1:8000
18
+
19
+ VERSION = '43.5.1'
20
+
21
+ if VERSION != Pagy::VERSION
22
+ Warning.warn("\n>>> WARNING! '#{File.basename(__FILE__)}-#{VERSION}' running with 'pagy-#{Pagy::VERSION}'! <<< \n\n")
23
+ end
24
+
25
+ # Bundle
26
+ require 'bundler/inline'
27
+ gemfile(!Pagy::ROOT.join('pagy.gemspec').exist?) do
28
+ source 'https://rubygems.org'
29
+ gem 'activerecord'
30
+ gem 'puma'
31
+ gem 'sinatra'
32
+ gem 'sqlite3'
33
+ end
34
+
35
+ # Sinatra setup
36
+ require 'sinatra/base'
37
+ # Sinatra application
38
+ class PagyKeyset < Sinatra::Base
39
+ include Pagy::Method
40
+
41
+ # Root route/action
42
+ get '/' do
43
+ Time.zone = 'UTC'
44
+
45
+ @order = { animal: :asc, name: :asc, birthdate: :desc, id: :asc }.freeze
46
+ @pagy, @pets = pagy(:keyset, Pet.order(@order), limit: 10, max_limit: 100)
47
+ # @pagy, @pets = pagy(:keyset, Pet.order(@order),
48
+ # jsonapi: true, page_key: 'number', limit_key: 'size', # very customized jsonapi
49
+ # limit: 10, max_limit: 100)
50
+ # response.headers.merge!(@pagy.headers_hash)
51
+ erb :main
52
+ end
53
+
54
+ helpers do
55
+ def order_symbol(dir)
56
+ { asc: '&#x2197;', desc: '&#x2198;' }[dir]
57
+ end
58
+ end
59
+
60
+ # Views
61
+ template :layout do
62
+ <<~ERB
63
+ <!DOCTYPE html>
64
+ <html lang="en">
65
+ <head>
66
+ <title>Pagy Keyset App</title>
67
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
68
+ <style type="text/css">
69
+ @media screen { html, body {
70
+ font-size: 1rem;
71
+ line-height: 1.2;
72
+ padding: 0;
73
+ margin: 0;
74
+ } }
75
+ body {
76
+ background: white !important;
77
+ margin: 0 !important;
78
+ font-family: sans-serif !important;
79
+ }
80
+ .main-content {
81
+ padding: 1rem 1.5rem 2rem !important;
82
+ }
83
+
84
+ <%= Pagy::ROOT.join('stylesheets/pagy.css').read %>
85
+ </style>
86
+ </head>
87
+ <body>
88
+ <%= yield %>
89
+ </body>
90
+ </html>
91
+ ERB
92
+ end
93
+
94
+ template :main do
95
+ <<~ERB
96
+ <div class="main-content">
97
+ <h1>Pagy Keyset App</h1>
98
+ <p>Self-contained, standalone app usable to easily reproduce any Keyset related pagy issue with ActiveRecord sets.</p>
99
+
100
+ <h2>Versions</h2>
101
+ <ul>
102
+ <li>Ruby: <%= RUBY_VERSION %></li>
103
+ <li>Rack: <%= Rack::RELEASE %></li>
104
+ <li>Sinatra: <%= Sinatra::VERSION %></li>
105
+ <li>Pagy: <%= Pagy::VERSION %></li>
106
+ </ul>
107
+
108
+ <h3>Collection</h3>
109
+ <div id="records" class="collection">
110
+ <table border="1" style="border-collapse: collapse; border-spacing: 0; padding: 0.2rem;">
111
+ <tr>
112
+ <th scope="col">animal <%= order_symbol(@order[:animal]) %></th>
113
+ <th scope="col">name <%= order_symbol(@order[:name]) %></th>
114
+ <th scope="col">birthdate <%= order_symbol(@order[:birthdate]) %></th>
115
+ <th scope="col">id <%= order_symbol(@order[:id]) %></th>
116
+ </tr>
117
+ <% @pets.each do |pet| %>
118
+ <tr>
119
+ <td><%= pet.animal %></td>
120
+ <td><%= pet.name %></td>
121
+ <td><%= pet.birthdate %></td>
122
+ <td><%= pet.id %></td>
123
+ </tr>
124
+ <% end %>
125
+ </table>
126
+ </div>
127
+ <nav class="pagy" id="next" aria-label="Pagy next">
128
+ <%= @pagy.next_tag(text: 'Next page &gt;') %>
129
+ </nav>
130
+ </div>
131
+ ERB
132
+ end
133
+ end
134
+
135
+ # ActiveRecord setup
136
+ require 'active_record'
137
+
138
+ # Match the microsecods with the strings stored into the time columns of SQLite
139
+ # ActiveSupport::JSON::Encoding.time_precision = 6
140
+
141
+ # Log
142
+ output = ENV['APP_ENV'].equal?('showcase') ? IO::NULL : $stdout
143
+ ActiveRecord::Base.logger = Logger.new(output)
144
+ # Connection
145
+ ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'file:memdb1?mode=memory&cache=shared')
146
+ # Schema
147
+ ActiveRecord::Schema.define do
148
+ create_table :pets, force: true do |t|
149
+ t.string :animal
150
+ t.string :name
151
+ t.date :birthdate
152
+ end
153
+ end
154
+
155
+ # Models
156
+ class Pet < ActiveRecord::Base; end
157
+
158
+ data = <<~DATA
159
+ Luna | dog | 2018-03-10
160
+ Coco | cat | 2019-05-15
161
+ Dodo | dog | 2020-06-25
162
+ Wiki | bird | 2018-03-12
163
+ Baby | rabbit | 2020-01-13
164
+ Neki | horse | 2021-07-20
165
+ Tino | donkey | 2019-06-18
166
+ Plot | cat | 2022-09-21
167
+ Riki | cat | 2018-09-14
168
+ Susi | horse | 2018-10-26
169
+ Coco | pig | 2020-08-29
170
+ Momo | bird | 2023-08-25
171
+ Lili | cat | 2021-07-22
172
+ Beli | pig | 2020-07-26
173
+ Rocky | bird | 2022-08-19
174
+ Vyvy | dog | 2018-05-16
175
+ Susi | horse | 2024-01-25
176
+ Ella | cat | 2020-02-20
177
+ Rocky | dog | 2019-09-19
178
+ Juni | rabbit | 2020-08-24
179
+ Coco | bird | 2021-03-17
180
+ Susi | dog | 2021-07-28
181
+ Luna | horse | 2023-05-14
182
+ Gigi | pig | 2022-05-19
183
+ Coco | cat | 2020-02-20
184
+ Nino | donkey | 2019-06-17
185
+ Luna | cat | 2022-02-09
186
+ Popi | dog | 2020-09-26
187
+ Lili | pig | 2022-06-18
188
+ Mina | horse | 2021-04-21
189
+ Susi | rabbit | 2023-05-18
190
+ Toni | donkey | 2018-06-22
191
+ Rocky | horse | 2019-09-28
192
+ Lili | cat | 2019-03-18
193
+ Roby | cat | 2022-06-19
194
+ Anto | horse | 2022-08-18
195
+ Susi | pig | 2021-04-21
196
+ Boly | bird | 2020-03-29
197
+ Sky | cat | 2023-07-19
198
+ Lili | dog | 2020-01-28
199
+ Fami | snake | 2023-04-27
200
+ Lopi | pig | 2019-06-19
201
+ Rocky | snake | 2022-03-13
202
+ Denis | dog | 2022-06-19
203
+ Maca | cat | 2022-06-19
204
+ Luna | dog | 2022-08-15
205
+ Jeme | horse | 2019-08-08
206
+ Sary | bird | 2023-04-29
207
+ Rocky | bird | 2023-05-14
208
+ Coco | dog | 2023-05-27
209
+ DATA
210
+
211
+ # DB seed
212
+ pets = []
213
+ data.each_line(chomp: true) do |pet|
214
+ name, animal, birthdate = pet.split('|').map(&:strip)
215
+ pets << { name:, animal:, birthdate: }
216
+ end
217
+ Pet.insert_all(pets)
218
+
219
+ run PagyKeyset
@@ -0,0 +1,212 @@
1
+ # frozen_string_literal: true
2
+
3
+ # DESCRIPTION
4
+ # Showcase the Keyset pagination (Sequel example)
5
+ #
6
+ # DOC
7
+ # https://ddnexus.github.io/pagy/playground/#keyset-apps
8
+ #
9
+ # BIN HELP
10
+ # pagy -h
11
+ #
12
+ # DEV USAGE
13
+ # pagy clone keyset_sequel
14
+ # pagy ./keyset_sequel.ru
15
+ #
16
+ # URL
17
+ # http://127.0.0.1:8000
18
+
19
+ VERSION = '43.5.1'
20
+
21
+ if VERSION != Pagy::VERSION
22
+ Warning.warn("\n>>> WARNING! '#{File.basename(__FILE__)}-#{VERSION}' running with 'pagy-#{Pagy::VERSION}'! <<< \n\n")
23
+ end
24
+
25
+ # Bundle
26
+ require 'bundler/inline'
27
+ gemfile(!Pagy::ROOT.join('pagy.gemspec').exist?) do
28
+ source 'https://rubygems.org'
29
+ gem 'puma'
30
+ gem 'sequel'
31
+ gem 'sinatra'
32
+ gem 'sqlite3'
33
+ end
34
+
35
+ # Sinatra setup
36
+ require 'sinatra/base'
37
+ require 'logger'
38
+ # Sinatra application
39
+ class PagyKeysetSequel < Sinatra::Base
40
+ include Pagy::Method
41
+
42
+ # Root route/action
43
+ get '/' do
44
+ @order = { animal: :asc, name: :asc, birthdate: :desc, id: :asc }.freeze
45
+ @pagy, @pets = pagy(:keyset, Pet.order(:animal, :name, Sequel.desc(:birthdate), :id),
46
+ limit: 10, max_limit: 100)
47
+ erb :main
48
+ end
49
+
50
+ helpers do
51
+ def order_symbol(dir)
52
+ { asc: '&#x2197;', desc: '&#x2198;' }[dir]
53
+ end
54
+ end
55
+
56
+ # Views
57
+ template :layout do
58
+ <<~ERB
59
+ <!DOCTYPE html>
60
+ <html lang="en">
61
+ <head>
62
+ <title>Pagy Keyset App</title>
63
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
64
+ <style type="text/css">
65
+ @media screen { html, body {
66
+ font-size: 1rem;
67
+ line-height: 1.2;
68
+ padding: 0;
69
+ margin: 0;
70
+ } }
71
+ body {
72
+ background: white !important;
73
+ margin: 0 !important;
74
+ font-family: sans-serif !important;
75
+ }
76
+ .main-content {
77
+ padding: 1rem 1.5rem 2rem !important;
78
+ }
79
+
80
+ <%= Pagy::ROOT.join('stylesheets/pagy.css').read %>
81
+ </style>
82
+ </head>
83
+ <body>
84
+ <%= yield %>
85
+ </body>
86
+ </html>
87
+ ERB
88
+ end
89
+
90
+ template :main do
91
+ <<~ERB
92
+ <div class="main-content">
93
+ <h1>Pagy Keyset App</h1>
94
+ <p>Self-contained, standalone app usable to easily reproduce any Keyset related pagy issue with Sequel sets.</p>
95
+
96
+ <h2>Versions</h2>
97
+ <ul>
98
+ <li>Ruby: <%= RUBY_VERSION %></li>
99
+ <li>Rack: <%= Rack::RELEASE %></li>
100
+ <li>Sinatra: <%= Sinatra::VERSION %></li>
101
+ <li>Pagy: <%= Pagy::VERSION %></li>
102
+ </ul>
103
+
104
+ <h3>Collection</h3>
105
+ <div id="records" class="collection">
106
+ <table border="1" cellspacing="0" cellpadding="3">
107
+ <tr>
108
+ <th>animal <%= order_symbol(@order[:animal]) %></th>
109
+ <th>name <%= order_symbol(@order[:name]) %></th>
110
+ <th>birthdate <%= order_symbol(@order[:birthdate]) %></th>
111
+ <th>id <%= order_symbol(@order[:id]) %></th>
112
+ </tr>
113
+ <% @pets.each do |pet| %>
114
+ <tr>
115
+ <td><%= pet.animal %></td>
116
+ <td><%= pet.name %></td>
117
+ <td><%= pet.birthdate %></td>
118
+ <td><%= pet.id %></td>
119
+ </tr>
120
+ <% end %>
121
+ </table>
122
+ </div>
123
+ <nav class="pagy" id="next" aria-label="Pagy next">
124
+ <%= @pagy.next_tag(text: 'Next page &gt;') %>
125
+ </nav>
126
+ </div>
127
+ ERB
128
+ end
129
+ end
130
+
131
+ # Sequel setup
132
+ require 'sequel'
133
+ Sequel.default_timezone = :utc
134
+ # Connection
135
+ output = ENV['APP_ENV'].equal?('showcase') ? IO::NULL : $stdout
136
+ # Use 'sqlite' adapter (Sequel uses 'sqlite', AR uses 'sqlite3')
137
+ # Use the same shared memory URI string for the database
138
+ DB = Sequel.connect(adapter: 'sqlite',
139
+ database: 'file:memdb1?mode=memory&cache=shared',
140
+ max_connections: 10,
141
+ loggers: [Logger.new(output)])
142
+ # Schema
143
+ DB.create_table! :pets do
144
+ primary_key :id
145
+ String :animal, unique: false, null: false
146
+ String :name, unique: false, null: false
147
+ Date :birthdate, unique: false, null: false
148
+ end
149
+
150
+ # Models
151
+ class Pet < Sequel::Model; end
152
+
153
+ data = <<~DATA
154
+ Luna | dog | 2018-03-10
155
+ Coco | cat | 2019-05-15
156
+ Dodo | dog | 2020-06-25
157
+ Wiki | bird | 2018-03-12
158
+ Baby | rabbit | 2020-01-13
159
+ Neki | horse | 2021-07-20
160
+ Tino | donkey | 2019-06-18
161
+ Plot | cat | 2022-09-21
162
+ Riki | cat | 2018-09-14
163
+ Susi | horse | 2018-10-26
164
+ Coco | pig | 2020-08-29
165
+ Momo | bird | 2023-08-25
166
+ Lili | cat | 2021-07-22
167
+ Beli | pig | 2020-07-26
168
+ Rocky | bird | 2022-08-19
169
+ Vyvy | dog | 2018-05-16
170
+ Susi | horse | 2024-01-25
171
+ Ella | cat | 2020-02-20
172
+ Rocky | dog | 2019-09-19
173
+ Juni | rabbit | 2020-08-24
174
+ Coco | bird | 2021-03-17
175
+ Susi | dog | 2021-07-28
176
+ Luna | horse | 2023-05-14
177
+ Gigi | pig | 2022-05-19
178
+ Coco | cat | 2020-02-20
179
+ Nino | donkey | 2019-06-17
180
+ Luna | cat | 2022-02-09
181
+ Popi | dog | 2020-09-26
182
+ Lili | pig | 2022-06-18
183
+ Mina | horse | 2021-04-21
184
+ Susi | rabbit | 2023-05-18
185
+ Toni | donkey | 2018-06-22
186
+ Rocky | horse | 2019-09-28
187
+ Lili | cat | 2019-03-18
188
+ Roby | cat | 2022-06-19
189
+ Anto | horse | 2022-08-18
190
+ Susi | pig | 2021-04-21
191
+ Boly | bird | 2020-03-29
192
+ Sky | cat | 2023-07-19
193
+ Lili | dog | 2020-01-28
194
+ Fami | snake | 2023-04-27
195
+ Lopi | pig | 2019-06-19
196
+ Rocky | snake | 2022-03-13
197
+ Denis | dog | 2022-06-19
198
+ Maca | cat | 2022-06-19
199
+ Luna | dog | 2022-08-15
200
+ Jeme | horse | 2019-08-08
201
+ Sary | bird | 2023-04-29
202
+ Rocky | bird | 2023-05-14
203
+ Coco | dog | 2023-05-27
204
+ DATA
205
+
206
+ dataset = DB[:pets]
207
+ data.each_line(chomp: true) do |pet|
208
+ name, animal, birthdate = pet.split('|').map(&:strip)
209
+ dataset.insert(name:, animal:, birthdate:)
210
+ end
211
+
212
+ run PagyKeysetSequel
data/apps/rails.ru ADDED
@@ -0,0 +1,216 @@
1
+ # frozen_string_literal: true
2
+
3
+ # DESCRIPTION
4
+ # Reproduce rails related issues
5
+ #
6
+ # DOC
7
+ # https://ddnexus.github.io/pagy/playground/#rails-app
8
+ #
9
+ # BIN HELP
10
+ # pagy -h
11
+ #
12
+ # DEV USAGE
13
+ # pagy clone rails
14
+ # pagy ./rails.ru
15
+ #
16
+ # URL
17
+ # http://127.0.0.1:8000
18
+
19
+ VERSION = '43.5.1'
20
+
21
+ if VERSION != Pagy::VERSION
22
+ Warning.warn("\n>>> WARNING! '#{File.basename(__FILE__)}-#{VERSION}' running with 'pagy-#{Pagy::VERSION}'! <<< \n\n")
23
+ end
24
+
25
+ # Bundle
26
+ require 'bundler/inline'
27
+ gemfile(!Pagy::ROOT.join('pagy.gemspec').exist?) do
28
+ source 'https://rubygems.org'
29
+ gem 'oj'
30
+ gem 'puma'
31
+ gem 'rails', '~> 8.0'
32
+ gem 'sqlite3'
33
+ end
34
+
35
+ # require 'rails/all' # too much stuff
36
+ require 'action_controller/railtie'
37
+ require 'active_record'
38
+
39
+ OUTPUT = Rails.env.showcase? ? IO::NULL : $stdout
40
+
41
+ # Rails config
42
+ class PagyRails < Rails::Application # :nodoc:
43
+ config.root = __dir__
44
+ config.session_store :cookie_store, key: 'cookie_store_key'
45
+ Rails.application.credentials.secret_key_base = 'absolute_secret'
46
+
47
+ config.logger = Logger.new(OUTPUT)
48
+ Rails.logger = config.logger
49
+
50
+ # Pagy initializer
51
+ # require Pagy::ROOT.join('apps/enable_rails_page_segment.rb') # Uncomment to test the enable_rails_page_segment.rb override
52
+
53
+ routes.draw do
54
+ root to: 'comments#index'
55
+ # get '/comments(/:page)', to: 'comments#index' # Uncomment to test the enable_rails_page_segment.rb override
56
+ get '/javascripts/:file', to: 'pagy#javascripts', file: /.*/
57
+ end
58
+ end
59
+
60
+ # Activerecord initializer
61
+ ActiveRecord::Base.logger = Logger.new(OUTPUT)
62
+ ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: 'file:memdb1?mode=memory&cache=shared')
63
+ ActiveRecord::Schema.define do
64
+ create_table :posts, force: true do |t|
65
+ t.string :title
66
+ end
67
+
68
+ create_table :comments, force: true do |t|
69
+ t.string :body
70
+ t.integer :post_id
71
+ end
72
+ end
73
+
74
+ # Models
75
+ class Post < ActiveRecord::Base # :nodoc:
76
+ has_many :comments
77
+ end
78
+
79
+ # :nodoc:
80
+
81
+ class Comment < ActiveRecord::Base # :nodoc:
82
+ belongs_to :post
83
+ end
84
+
85
+ # :nodoc:
86
+
87
+ # Unused model, useful to test overriding conflicts
88
+ module Calendar
89
+ end
90
+
91
+ # DB seed
92
+ 1.upto(11) do |pi|
93
+ Post.create(title: "Post #{pi + 1}")
94
+ end
95
+ Post.all.each_with_index do |post, pi|
96
+ 2.times { |ci| Comment.create(post:, body: "Comment #{ci + 1} to Post #{pi + 1}") }
97
+ end
98
+
99
+ # Controllers
100
+ class CommentsController < ActionController::Base # :nodoc:
101
+ include Rails.application.routes.url_helpers
102
+ include Pagy::Method
103
+
104
+ def index
105
+ @pagy, @comments = pagy(:offset, Comment.all, limit: 10, max_limit: 100)
106
+ # Reload the page in the network tab of the Chrome Inspector to check
107
+ # response.headers.merge!(@pagy.headers_hash)
108
+ render inline: TEMPLATE
109
+ end
110
+ end
111
+
112
+ # You don't need this in real rails apps (see https://ddnexus.github.io/pagy/resources/javascripts)
113
+ class PagyController < ActionController::Base
114
+ def javascripts
115
+ format = params[:file].split('.').last
116
+ if format == 'js'
117
+ render js: Pagy::ROOT.join('javascripts', params[:file]).read
118
+ elsif format == 'map'
119
+ render json: Pagy::ROOT.join('javascripts', params[:file]).read
120
+ end
121
+ end
122
+ end
123
+
124
+ run PagyRails
125
+
126
+ TEMPLATE = <<~ERB
127
+ <!DOCTYPE html>
128
+ <html lang="en">
129
+ <head>
130
+ <title>Pagy Rails App</title>
131
+ <script src="/javascripts/pagy.js"></script>
132
+ <script>
133
+ window.addEventListener("load", Pagy.init);
134
+ </script>
135
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
136
+ <style type="text/css">
137
+ @media screen { html, body {
138
+ font-size: 1rem;
139
+ line-height: 1.2;
140
+ padding: 0;
141
+ margin: 0;
142
+ } }
143
+ body {
144
+ background: white !important;
145
+ margin: 0 !important;
146
+ font-family: sans-serif !important;
147
+ }
148
+ .main-content {
149
+ padding: 1rem 1.5rem 2rem !important;
150
+ }
151
+ .pagy, .pagy-bootstrap, .pagy-bulma {
152
+ padding: .5em;
153
+ margin: .3em 0;
154
+ width: fit-content;
155
+ box-shadow: 5px 5px 10px 0px rgba(0,0,0,0.2);
156
+ }
157
+
158
+ /* Quick demo for overriding the element style attribute of certain pagy helpers
159
+ .pagy input[style] {
160
+ width: 5rem !important;
161
+ }
162
+ */
163
+
164
+ /*
165
+ If you want to customize the style,
166
+ please replace the line below with the actual file content
167
+ */
168
+ <%== Pagy::ROOT.join('stylesheets/pagy.css').read %>
169
+ </style>
170
+ </head>
171
+
172
+ <body>
173
+
174
+ <div class="main-content">
175
+ <h1>Pagy Rails App</h1>
176
+ <p> Self-contained, standalone Rails app usable to easily reproduce any rails related pagy issue.</p>
177
+
178
+ <h2>Versions</h2>
179
+ <ul>
180
+ <li>Ruby: <%== RUBY_VERSION %></li>
181
+ <li>Rack: <%== Rack::RELEASE %></li>
182
+ <li>Rails: <%== Rails.version %></li>
183
+ <li>Pagy: <%== Pagy::VERSION %></li>
184
+ </ul>
185
+
186
+ <h3>Collection</h3>
187
+ <div id="records" class="collection">
188
+ <% @comments.each do |comment| %>
189
+ <p style="margin: 0;"><%= comment.body %></p>
190
+ <% end %>
191
+ </div>
192
+
193
+ <hr>
194
+
195
+ <h4>@pagy.series_nav</h4>
196
+ <%== @pagy.series_nav(id: 'series-nav',
197
+ aria_label: 'Pages nav') %>
198
+
199
+ <h4>@pagy.series_nav_js</h4>
200
+ <%== @pagy.series_nav_js(id: 'series-nav-js',
201
+ aria_label: 'Pages nav_js') %>
202
+
203
+ <h4>@pagy.input_nav_js</h4>
204
+ <%== @pagy.input_nav_js(id: 'input-nav-js',
205
+ aria_label: 'Pages input_nav_js') %>
206
+
207
+ <h4>@pagy.limit_tag_js</h4>
208
+ <%== @pagy.limit_tag_js(id: 'limit-tag-js') %>
209
+
210
+ <h4>@pagy.info_tag</h4>
211
+ <%== @pagy.info_tag(id: 'pagy-info') %>
212
+ </div>
213
+
214
+ </body>
215
+ </html>
216
+ ERB