pagy 9.4.0 → 43.2.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 +548 -552
- data/apps/demo.ru +224 -181
- data/apps/index.rb +3 -1
- data/apps/keynav+root_key.ru +321 -0
- data/apps/keynav.ru +260 -0
- data/apps/{keyset_ar.ru → keyset.ru} +26 -32
- data/apps/{keyset_s.ru → keyset_sequel.ru} +23 -29
- data/apps/rails.ru +51 -48
- data/apps/repro.ru +51 -47
- data/bin/pagy +20 -21
- data/config/pagy.rb +35 -207
- data/javascripts/ai_widget.js +90 -0
- data/javascripts/pagy.js +153 -0
- data/javascripts/pagy.js.map +10 -0
- data/javascripts/pagy.min.js +2 -4
- data/javascripts/pagy.mjs +113 -63
- data/javascripts/wand.js +1172 -0
- data/lib/pagy/classes/calendar/calendar.rb +96 -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 +93 -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 +25 -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 +79 -0
- data/lib/pagy/classes/keyset/keyset.rb +126 -0
- data/lib/pagy/classes/keyset/sequel.rb +11 -0
- data/lib/pagy/classes/offset/countish.rb +17 -0
- data/lib/pagy/classes/offset/countless.rb +61 -0
- data/lib/pagy/classes/offset/offset.rb +56 -0
- data/lib/pagy/classes/offset/search.rb +32 -0
- data/lib/pagy/classes/request.rb +36 -0
- data/lib/pagy/console.rb +3 -20
- data/lib/pagy/modules/abilities/configurable.rb +36 -0
- data/lib/pagy/modules/abilities/countable.rb +23 -0
- data/lib/pagy/modules/abilities/linkable.rb +60 -0
- data/lib/pagy/modules/abilities/rangeable.rb +16 -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 +24 -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 +17 -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 +27 -0
- data/lib/pagy/toolbox/helpers/headers_hash.rb +29 -0
- data/lib/pagy/toolbox/helpers/info_tag.rb +26 -0
- data/lib/pagy/toolbox/helpers/input_nav_js.rb +18 -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 +18 -0
- data/lib/pagy/toolbox/helpers/series_nav.rb +28 -0
- data/lib/pagy/toolbox/helpers/series_nav_js.rb +18 -0
- data/lib/pagy/toolbox/helpers/support/a_lambda.rb +35 -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 +37 -0
- data/lib/pagy/toolbox/helpers/urls_hash.rb +13 -0
- data/lib/pagy/toolbox/paginators/calendar.rb +29 -0
- data/lib/pagy/toolbox/paginators/countish.rb +37 -0
- data/lib/pagy/toolbox/paginators/countless.rb +20 -0
- data/lib/pagy/toolbox/paginators/elasticsearch_rails.rb +50 -0
- data/lib/pagy/toolbox/paginators/keynav_js.rb +26 -0
- data/lib/pagy/toolbox/paginators/keyset.rb +15 -0
- data/lib/pagy/toolbox/paginators/meilisearch.rb +31 -0
- data/lib/pagy/toolbox/paginators/method.rb +35 -0
- data/lib/pagy/toolbox/paginators/offset.rb +18 -0
- data/lib/pagy/toolbox/paginators/searchkick.rb +31 -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 +10 -9
- data/locales/it.yml +9 -6
- data/locales/ja.yml +10 -9
- data/locales/km.yml +10 -9
- 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/sk.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 +9 -6
- data/locales/tr.yml +17 -12
- 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 +118 -52
- 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/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 -88
- 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 -167
- data/lib/pagy/keyset/active_record.rb +0 -44
- data/lib/pagy/keyset/sequel.rb +0 -57
- 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
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# DESCRIPTION
|
|
4
|
+
# Showcase the Keynav pagination with independent instances
|
|
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 keynav
|
|
14
|
+
# pagy ./keynav.ru
|
|
15
|
+
#
|
|
16
|
+
# URL
|
|
17
|
+
# http://127.0.0.1:8000
|
|
18
|
+
|
|
19
|
+
VERSION = '43.2.0'
|
|
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 PagyKeynav < Sinatra::Base
|
|
39
|
+
include Pagy::Method
|
|
40
|
+
|
|
41
|
+
get('/javascripts/:file') do
|
|
42
|
+
format = params[:file].split('.').last
|
|
43
|
+
if format == 'js'
|
|
44
|
+
content_type 'application/javascript'
|
|
45
|
+
elsif format == 'map'
|
|
46
|
+
content_type 'application/json'
|
|
47
|
+
end
|
|
48
|
+
send_file Pagy::ROOT.join('javascripts', params[:file])
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Root route/action
|
|
52
|
+
get '/' do
|
|
53
|
+
Time.zone = 'UTC'
|
|
54
|
+
|
|
55
|
+
@order = { animal: :asc, name: :asc, birthdate: :desc, id: :asc }
|
|
56
|
+
@pagy1, @pets1 = pagy(:keynav_js, Pet.order(@order), limit: 4, root_key: 'animal1')
|
|
57
|
+
@ids1 = @pets1.pluck(:id)
|
|
58
|
+
@pagy2, @pets2 = pagy(:keynav_js, Pet.order(@order), limit: 4, root_key: 'animal2')
|
|
59
|
+
@ids2 = @pets2.pluck(:id)
|
|
60
|
+
erb :main
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
helpers do
|
|
64
|
+
def order_symbol(dir)
|
|
65
|
+
{ asc: '↗', desc: '↘' }[dir]
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Views
|
|
70
|
+
template :layout do
|
|
71
|
+
<<~ERB
|
|
72
|
+
<!DOCTYPE html>
|
|
73
|
+
<html lang="en">
|
|
74
|
+
<html>
|
|
75
|
+
<head>
|
|
76
|
+
<title>Pagy Keynav (root_key) App</title>
|
|
77
|
+
<script src="javascripts/pagy.js"></script>
|
|
78
|
+
<script>
|
|
79
|
+
window.addEventListener("load", Pagy.init);
|
|
80
|
+
</script>
|
|
81
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
82
|
+
<style type="text/css">
|
|
83
|
+
@media screen { html, body {
|
|
84
|
+
font-size: 1rem;
|
|
85
|
+
line-height: 1.2s;
|
|
86
|
+
padding: 0;
|
|
87
|
+
margin: 0;
|
|
88
|
+
} }
|
|
89
|
+
body {
|
|
90
|
+
background: white !important;
|
|
91
|
+
margin: 0 !important;
|
|
92
|
+
font-family: sans-serif !important;
|
|
93
|
+
}
|
|
94
|
+
.main-content {
|
|
95
|
+
padding: 1rem 1.5rem 2rem !important;
|
|
96
|
+
}
|
|
97
|
+
#content {
|
|
98
|
+
display: flex; /* Enables Flexbox */
|
|
99
|
+
flex-wrap: wrap; /* Allows stacking */
|
|
100
|
+
gap: 20px; /* Gap between items */
|
|
101
|
+
/* Just for visual clarity of the container boundaries */
|
|
102
|
+
/*padding: 10px;
|
|
103
|
+
background-color: #e0e7ff;
|
|
104
|
+
border-radius: 8px;
|
|
105
|
+
border: 2px dashed #6366f1; */
|
|
106
|
+
}
|
|
107
|
+
.box {
|
|
108
|
+
flex: 1; /* Grow to fill space */
|
|
109
|
+
min-width: 300px; /* Stack if space < 300px */
|
|
110
|
+
/* Visual Styling */
|
|
111
|
+
background-color: white;
|
|
112
|
+
padding: 25px;
|
|
113
|
+
border-radius: 6px;
|
|
114
|
+
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
|
115
|
+
border: 1px solid #ddd;
|
|
116
|
+
}
|
|
117
|
+
.pagy {
|
|
118
|
+
padding: .5em;
|
|
119
|
+
margin: .3em 0;
|
|
120
|
+
width: fit-content;
|
|
121
|
+
box-shadow: 5px 5px 10px 0px rgba(0,0,0,0.2);
|
|
122
|
+
}
|
|
123
|
+
<%= Pagy::ROOT.join('stylesheets/pagy.css').read %>
|
|
124
|
+
</style>
|
|
125
|
+
</head>
|
|
126
|
+
<body>
|
|
127
|
+
<%= yield %>
|
|
128
|
+
</body>
|
|
129
|
+
</html>
|
|
130
|
+
ERB
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
template :main do
|
|
134
|
+
<<~ERB
|
|
135
|
+
<div class="main-content">
|
|
136
|
+
<h1>Pagy Keynav App</h1>
|
|
137
|
+
<p>Self-contained, standalone app usable to easily reproduce any Keynav related pagy issue
|
|
138
|
+
with ActiveRecord sets.</p>
|
|
139
|
+
<p>The panels below show how to use the <code>:root_key</code> option for independent instances in the same request.</p>
|
|
140
|
+
|
|
141
|
+
<p>Notice that Keynav works also with Sequel sets.</p>
|
|
142
|
+
|
|
143
|
+
<h2>Versions</h2>
|
|
144
|
+
<ul>
|
|
145
|
+
<li>Ruby: <%= RUBY_VERSION %></li>
|
|
146
|
+
<li>Rack: <%= Rack::RELEASE %></li>
|
|
147
|
+
<li>Sinatra: <%= Sinatra::VERSION %></li>
|
|
148
|
+
<li>Pagy: <%= Pagy::VERSION %></li>
|
|
149
|
+
</ul>
|
|
150
|
+
|
|
151
|
+
<div id="content">
|
|
152
|
+
<div class="box">
|
|
153
|
+
<h3>Collection 1</h3>
|
|
154
|
+
<p id="records">@ids: <%= @ids1.join(',') %></p>
|
|
155
|
+
<div class="collection">
|
|
156
|
+
<table border="1" style="border-collapse: collapse; border-spacing: 0; padding: 0.2rem;">
|
|
157
|
+
<tr>
|
|
158
|
+
<th scope="col">animal <%= order_symbol(@order[:animal]) %></th>
|
|
159
|
+
<th scope="col">name <%= order_symbol(@order[:name]) %></th>
|
|
160
|
+
<th scope="col">birthdate <%= order_symbol(@order[:birthdate]) %></th>
|
|
161
|
+
<th scope="col">id <%= order_symbol(@order[:id]) %></th>
|
|
162
|
+
</tr>
|
|
163
|
+
<% @pets1.each do |pet| %>
|
|
164
|
+
<tr>
|
|
165
|
+
<td><%= pet.animal %></td>
|
|
166
|
+
<td><%= pet.name %></td>
|
|
167
|
+
<td><%= pet.birthdate %></td>
|
|
168
|
+
<td><%= pet.id %></td>
|
|
169
|
+
</tr>
|
|
170
|
+
<% end %>
|
|
171
|
+
</table>
|
|
172
|
+
</div>
|
|
173
|
+
|
|
174
|
+
<h4>@pagy.series_nav</h4>
|
|
175
|
+
<%= @pagy1.series_nav(id: 'series-nav',
|
|
176
|
+
aria_label: 'Pages (nav)') %>
|
|
177
|
+
|
|
178
|
+
<h4>@pagy.series_nav_js (responsive)</h4>
|
|
179
|
+
<%= @pagy1.series_nav_js(id: 'series-nav-js-responsive',
|
|
180
|
+
aria_label: 'Pages (nav_js_responsive)',
|
|
181
|
+
steps: { 0 => 5, 500 => 7, 750 => 9, 1000 => 11 }) %>
|
|
182
|
+
<h4>@pagy.input_nav_js</h4>
|
|
183
|
+
<%= @pagy1.input_nav_js(id: 'input-nav-js',
|
|
184
|
+
aria_label: 'Pages (input_nav_js)') %>
|
|
185
|
+
|
|
186
|
+
<h4>@pagy.info_tag</h4>
|
|
187
|
+
<%= @pagy1.info_tag(id: 'pagy-info') %>
|
|
188
|
+
</div>
|
|
189
|
+
|
|
190
|
+
<div class="box">
|
|
191
|
+
<h3>Collection 2</h3>
|
|
192
|
+
<p id="records">@ids: <%= @ids2.join(',') %></p>
|
|
193
|
+
<div class="collection">
|
|
194
|
+
<table border="1" style="border-collapse: collapse; border-spacing: 0; padding: 0.2rem;">
|
|
195
|
+
<tr>
|
|
196
|
+
<th scope="col">animal <%= order_symbol(@order[:animal]) %></th>
|
|
197
|
+
<th scope="col">name <%= order_symbol(@order[:name]) %></th>
|
|
198
|
+
<th scope="col">birthdate <%= order_symbol(@order[:birthdate]) %></th>
|
|
199
|
+
<th scope="col">id <%= order_symbol(@order[:id]) %></th>
|
|
200
|
+
</tr>
|
|
201
|
+
<% @pets2.each do |pet| %>
|
|
202
|
+
<tr>
|
|
203
|
+
<td><%= pet.animal %></td>
|
|
204
|
+
<td><%= pet.name %></td>
|
|
205
|
+
<td><%= pet.birthdate %></td>
|
|
206
|
+
<td><%= pet.id %></td>
|
|
207
|
+
</tr>
|
|
208
|
+
<% end %>
|
|
209
|
+
</table>
|
|
210
|
+
</div>
|
|
211
|
+
|
|
212
|
+
<h4>@pagy.series_nav</h4>
|
|
213
|
+
<%= @pagy2.series_nav(id: 'series-nav',
|
|
214
|
+
aria_label: 'Pages (nav)') %>
|
|
215
|
+
|
|
216
|
+
<h4>@pagy.series_nav_js (responsive)</h4>
|
|
217
|
+
<%= @pagy2.series_nav_js(id: 'series-nav-js-responsive',
|
|
218
|
+
aria_label: 'Pages (nav_js_responsive)',
|
|
219
|
+
steps: { 0 => 5, 500 => 7, 750 => 9, 1000 => 11 }) %>
|
|
220
|
+
<h4>@pagy.input_nav_js</h4>
|
|
221
|
+
<%= @pagy2.input_nav_js(id: 'input-nav-js',
|
|
222
|
+
aria_label: 'Pages (input_nav_js)') %>
|
|
223
|
+
|
|
224
|
+
<h4>@pagy.info_tag</h4>
|
|
225
|
+
<%= @pagy2.info_tag(id: 'pagy-info') %>
|
|
226
|
+
</div>
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
ERB
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# ActiveRecord setup
|
|
234
|
+
require 'active_record'
|
|
235
|
+
|
|
236
|
+
# Match the microsecods with the strings stored into the time columns of SQLite
|
|
237
|
+
# ActiveSupport::JSON::Encoding.time_precision = 6
|
|
238
|
+
|
|
239
|
+
# Log
|
|
240
|
+
output = ENV['APP_ENV'].equal?('showcase') ? IO::NULL : $stdout
|
|
241
|
+
ActiveRecord::Base.logger = Logger.new(output)
|
|
242
|
+
# SQLite DB files
|
|
243
|
+
dir = ENV['APP_ENV'].equal?('development') ? '.' : Dir.pwd # app dir in dev or pwd otherwise
|
|
244
|
+
abort "ERROR: Cannot create DB files: the directory #{dir.inspect} is not writable." \
|
|
245
|
+
unless File.writable?(dir)
|
|
246
|
+
# Connection
|
|
247
|
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: "#{dir}/tmp/pagy-keyset-ar.sqlite3")
|
|
248
|
+
# Schema
|
|
249
|
+
ActiveRecord::Schema.define do
|
|
250
|
+
create_table :pets, force: true do |t|
|
|
251
|
+
t.string :animal
|
|
252
|
+
t.string :name
|
|
253
|
+
t.date :birthdate
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Models
|
|
258
|
+
class Pet < ActiveRecord::Base; end
|
|
259
|
+
|
|
260
|
+
data = <<~DATA
|
|
261
|
+
Luna | dog | 2018-03-10
|
|
262
|
+
Coco | cat | 2019-05-15
|
|
263
|
+
Dodo | dog | 2020-06-25
|
|
264
|
+
Wiki | bird | 2018-03-12
|
|
265
|
+
Baby | rabbit | 2020-01-13
|
|
266
|
+
Neki | horse | 2021-07-20
|
|
267
|
+
Tino | donkey | 2019-06-18
|
|
268
|
+
Plot | cat | 2022-09-21
|
|
269
|
+
Riki | cat | 2018-09-14
|
|
270
|
+
Susi | horse | 2018-10-26
|
|
271
|
+
Coco | pig | 2020-08-29
|
|
272
|
+
Momo | bird | 2023-08-25
|
|
273
|
+
Lili | cat | 2021-07-22
|
|
274
|
+
Beli | pig | 2020-07-26
|
|
275
|
+
Rocky | bird | 2022-08-19
|
|
276
|
+
Vyvy | dog | 2018-05-16
|
|
277
|
+
Susi | horse | 2024-01-25
|
|
278
|
+
Ella | cat | 2020-02-20
|
|
279
|
+
Rocky | dog | 2019-09-19
|
|
280
|
+
Juni | rabbit | 2020-08-24
|
|
281
|
+
Coco | bird | 2021-03-17
|
|
282
|
+
Susi | dog | 2021-07-28
|
|
283
|
+
Luna | horse | 2023-05-14
|
|
284
|
+
Gigi | pig | 2022-05-19
|
|
285
|
+
Coco | cat | 2020-02-20
|
|
286
|
+
Nino | donkey | 2019-06-17
|
|
287
|
+
Luna | cat | 2022-02-09
|
|
288
|
+
Popi | dog | 2020-09-26
|
|
289
|
+
Lili | pig | 2022-06-18
|
|
290
|
+
Mina | horse | 2021-04-21
|
|
291
|
+
Susi | rabbit | 2023-05-18
|
|
292
|
+
Toni | donkey | 2018-06-22
|
|
293
|
+
Rocky | horse | 2019-09-28
|
|
294
|
+
Lili | cat | 2019-03-18
|
|
295
|
+
Roby | cat | 2022-06-19
|
|
296
|
+
Anto | horse | 2022-08-18
|
|
297
|
+
Susi | pig | 2021-04-21
|
|
298
|
+
Boly | bird | 2020-03-29
|
|
299
|
+
Sky | cat | 2023-07-19
|
|
300
|
+
Lili | dog | 2020-01-28
|
|
301
|
+
Fami | snake | 2023-04-27
|
|
302
|
+
Lopi | pig | 2019-06-19
|
|
303
|
+
Rocky | snake | 2022-03-13
|
|
304
|
+
Denis | dog | 2022-06-19
|
|
305
|
+
Maca | cat | 2022-06-19
|
|
306
|
+
Luna | dog | 2022-08-15
|
|
307
|
+
Jeme | horse | 2019-08-08
|
|
308
|
+
Sary | bird | 2023-04-29
|
|
309
|
+
Rocky | bird | 2023-05-14
|
|
310
|
+
Coco | dog | 2023-05-27
|
|
311
|
+
DATA
|
|
312
|
+
|
|
313
|
+
# DB seed
|
|
314
|
+
pets = []
|
|
315
|
+
data.each_line(chomp: true) do |pet|
|
|
316
|
+
name, animal, birthdate = pet.split('|').map(&:strip)
|
|
317
|
+
pets << { name:, animal:, birthdate: }
|
|
318
|
+
end
|
|
319
|
+
Pet.insert_all(pets)
|
|
320
|
+
|
|
321
|
+
run PagyKeynav
|
data/apps/keynav.ru
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# DESCRIPTION
|
|
4
|
+
# Showcase the Keynav 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 keynav
|
|
14
|
+
# pagy ./keynav.ru
|
|
15
|
+
#
|
|
16
|
+
# URL
|
|
17
|
+
# http://127.0.0.1:8000
|
|
18
|
+
|
|
19
|
+
VERSION = '43.2.0'
|
|
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 PagyKeynav < Sinatra::Base
|
|
39
|
+
include Pagy::Method
|
|
40
|
+
|
|
41
|
+
get('/javascripts/:file') do
|
|
42
|
+
format = params[:file].split('.').last
|
|
43
|
+
if format == 'js'
|
|
44
|
+
content_type 'application/javascript'
|
|
45
|
+
elsif format == 'map'
|
|
46
|
+
content_type 'application/json'
|
|
47
|
+
end
|
|
48
|
+
send_file Pagy::ROOT.join('javascripts', params[:file])
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Root route/action
|
|
52
|
+
get '/' do
|
|
53
|
+
Time.zone = 'UTC'
|
|
54
|
+
|
|
55
|
+
@order = { animal: :asc, name: :asc, birthdate: :desc, id: :asc }
|
|
56
|
+
@pagy, @pets = pagy(:keynav_js, Pet.order(@order), limit: 4, client_max_limit: 100)
|
|
57
|
+
# Support also root_key for replacing url in javascript
|
|
58
|
+
# @pagy, @pets = pagy(:keynav_js, Pet.order(@order), limit: 4, client_max_limit: 100, root_key: 'animal')
|
|
59
|
+
@ids = @pets.pluck(:id)
|
|
60
|
+
erb :main
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
helpers do
|
|
64
|
+
def order_symbol(dir)
|
|
65
|
+
{ asc: '↗', desc: '↘' }[dir]
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Views
|
|
70
|
+
template :layout do
|
|
71
|
+
<<~ERB
|
|
72
|
+
<!DOCTYPE html>
|
|
73
|
+
<html lang="en">
|
|
74
|
+
<html>
|
|
75
|
+
<head>
|
|
76
|
+
<title>Pagy Keynav App</title>
|
|
77
|
+
<script src="javascripts/pagy.js"></script>
|
|
78
|
+
<script>
|
|
79
|
+
window.addEventListener("load", Pagy.init);
|
|
80
|
+
</script>
|
|
81
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
82
|
+
<style type="text/css">
|
|
83
|
+
@media screen { html, body {
|
|
84
|
+
font-size: 1rem;
|
|
85
|
+
line-height: 1.2s;
|
|
86
|
+
padding: 0;
|
|
87
|
+
margin: 0;
|
|
88
|
+
} }
|
|
89
|
+
body {
|
|
90
|
+
background: white !important;
|
|
91
|
+
margin: 0 !important;
|
|
92
|
+
font-family: sans-serif !important;
|
|
93
|
+
}
|
|
94
|
+
.main-content {
|
|
95
|
+
padding: 1rem 1.5rem 2rem !important;
|
|
96
|
+
}
|
|
97
|
+
.pagy {
|
|
98
|
+
padding: .5em;
|
|
99
|
+
margin: .3em 0;
|
|
100
|
+
width: fit-content;
|
|
101
|
+
box-shadow: 5px 5px 10px 0px rgba(0,0,0,0.2);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
<%= Pagy::ROOT.join('stylesheets/pagy.css').read %>
|
|
106
|
+
</style>
|
|
107
|
+
</head>
|
|
108
|
+
<body>
|
|
109
|
+
<%= yield %>
|
|
110
|
+
</body>
|
|
111
|
+
</html>
|
|
112
|
+
ERB
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
template :main do
|
|
116
|
+
<<~ERB
|
|
117
|
+
<div class="main-content">
|
|
118
|
+
<h1>Pagy Keynav App</h1>
|
|
119
|
+
<p>Self-contained, standalone app usable to easily reproduce any Keynav related pagy issue
|
|
120
|
+
with ActiveRecord sets.</p>
|
|
121
|
+
|
|
122
|
+
<p>Notice that Keynav works also with Sequel sets.</p>
|
|
123
|
+
|
|
124
|
+
<h2>Versions</h2>
|
|
125
|
+
<ul>
|
|
126
|
+
<li>Ruby: <%= RUBY_VERSION %></li>
|
|
127
|
+
<li>Rack: <%= Rack::RELEASE %></li>
|
|
128
|
+
<li>Sinatra: <%= Sinatra::VERSION %></li>
|
|
129
|
+
<li>Pagy: <%= Pagy::VERSION %></li>
|
|
130
|
+
</ul>
|
|
131
|
+
|
|
132
|
+
<h3>Collection</h3>
|
|
133
|
+
<p id="records">@ids: <%= @ids.join(',') %></p>
|
|
134
|
+
<div class="collection">
|
|
135
|
+
<table border="1" style="border-collapse: collapse; border-spacing: 0; padding: 0.2rem;">
|
|
136
|
+
<tr>
|
|
137
|
+
<th scope="col">animal <%= order_symbol(@order[:animal]) %></th>
|
|
138
|
+
<th scope="col">name <%= order_symbol(@order[:name]) %></th>
|
|
139
|
+
<th scope="col">birthdate <%= order_symbol(@order[:birthdate]) %></th>
|
|
140
|
+
<th scope="col">id <%= order_symbol(@order[:id]) %></th>
|
|
141
|
+
</tr>
|
|
142
|
+
<% @pets.each do |pet| %>
|
|
143
|
+
<tr>
|
|
144
|
+
<td><%= pet.animal %></td>
|
|
145
|
+
<td><%= pet.name %></td>
|
|
146
|
+
<td><%= pet.birthdate %></td>
|
|
147
|
+
<td><%= pet.id %></td>
|
|
148
|
+
</tr>
|
|
149
|
+
<% end %>
|
|
150
|
+
</table>
|
|
151
|
+
</div>
|
|
152
|
+
|
|
153
|
+
<h4>@pagy.series_nav</h4>
|
|
154
|
+
<%= @pagy.series_nav(id: 'series-nav',
|
|
155
|
+
aria_label: 'Pages (nav)') %>
|
|
156
|
+
|
|
157
|
+
<h4>@pagy.series_nav_js (responsive)</h4>
|
|
158
|
+
<%= @pagy.series_nav_js(id: 'series-nav-js-responsive',
|
|
159
|
+
aria_label: 'Pages (nav_js_responsive)',
|
|
160
|
+
steps: { 0 => 5, 500 => 7, 750 => 9, 1000 => 11 }) %>
|
|
161
|
+
<h4>@pagy.input_nav_js</h4>
|
|
162
|
+
<%= @pagy.input_nav_js(id: 'input-nav-js',
|
|
163
|
+
aria_label: 'Pages (input_nav_js)') %>
|
|
164
|
+
|
|
165
|
+
<h4>@pagy.info_tag</h4>
|
|
166
|
+
<%= @pagy.info_tag(id: 'pagy-info') %>
|
|
167
|
+
</div>
|
|
168
|
+
ERB
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# ActiveRecord setup
|
|
173
|
+
require 'active_record'
|
|
174
|
+
|
|
175
|
+
# Match the microsecods with the strings stored into the time columns of SQLite
|
|
176
|
+
# ActiveSupport::JSON::Encoding.time_precision = 6
|
|
177
|
+
|
|
178
|
+
# Log
|
|
179
|
+
output = ENV['APP_ENV'].equal?('showcase') ? IO::NULL : $stdout
|
|
180
|
+
ActiveRecord::Base.logger = Logger.new(output)
|
|
181
|
+
# SQLite DB files
|
|
182
|
+
dir = ENV['APP_ENV'].equal?('development') ? '.' : Dir.pwd # app dir in dev or pwd otherwise
|
|
183
|
+
abort "ERROR: Cannot create DB files: the directory #{dir.inspect} is not writable." \
|
|
184
|
+
unless File.writable?(dir)
|
|
185
|
+
# Connection
|
|
186
|
+
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: "#{dir}/tmp/pagy-keyset-ar.sqlite3")
|
|
187
|
+
# Schema
|
|
188
|
+
ActiveRecord::Schema.define do
|
|
189
|
+
create_table :pets, force: true do |t|
|
|
190
|
+
t.string :animal
|
|
191
|
+
t.string :name
|
|
192
|
+
t.date :birthdate
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Models
|
|
197
|
+
class Pet < ActiveRecord::Base; end
|
|
198
|
+
|
|
199
|
+
data = <<~DATA
|
|
200
|
+
Luna | dog | 2018-03-10
|
|
201
|
+
Coco | cat | 2019-05-15
|
|
202
|
+
Dodo | dog | 2020-06-25
|
|
203
|
+
Wiki | bird | 2018-03-12
|
|
204
|
+
Baby | rabbit | 2020-01-13
|
|
205
|
+
Neki | horse | 2021-07-20
|
|
206
|
+
Tino | donkey | 2019-06-18
|
|
207
|
+
Plot | cat | 2022-09-21
|
|
208
|
+
Riki | cat | 2018-09-14
|
|
209
|
+
Susi | horse | 2018-10-26
|
|
210
|
+
Coco | pig | 2020-08-29
|
|
211
|
+
Momo | bird | 2023-08-25
|
|
212
|
+
Lili | cat | 2021-07-22
|
|
213
|
+
Beli | pig | 2020-07-26
|
|
214
|
+
Rocky | bird | 2022-08-19
|
|
215
|
+
Vyvy | dog | 2018-05-16
|
|
216
|
+
Susi | horse | 2024-01-25
|
|
217
|
+
Ella | cat | 2020-02-20
|
|
218
|
+
Rocky | dog | 2019-09-19
|
|
219
|
+
Juni | rabbit | 2020-08-24
|
|
220
|
+
Coco | bird | 2021-03-17
|
|
221
|
+
Susi | dog | 2021-07-28
|
|
222
|
+
Luna | horse | 2023-05-14
|
|
223
|
+
Gigi | pig | 2022-05-19
|
|
224
|
+
Coco | cat | 2020-02-20
|
|
225
|
+
Nino | donkey | 2019-06-17
|
|
226
|
+
Luna | cat | 2022-02-09
|
|
227
|
+
Popi | dog | 2020-09-26
|
|
228
|
+
Lili | pig | 2022-06-18
|
|
229
|
+
Mina | horse | 2021-04-21
|
|
230
|
+
Susi | rabbit | 2023-05-18
|
|
231
|
+
Toni | donkey | 2018-06-22
|
|
232
|
+
Rocky | horse | 2019-09-28
|
|
233
|
+
Lili | cat | 2019-03-18
|
|
234
|
+
Roby | cat | 2022-06-19
|
|
235
|
+
Anto | horse | 2022-08-18
|
|
236
|
+
Susi | pig | 2021-04-21
|
|
237
|
+
Boly | bird | 2020-03-29
|
|
238
|
+
Sky | cat | 2023-07-19
|
|
239
|
+
Lili | dog | 2020-01-28
|
|
240
|
+
Fami | snake | 2023-04-27
|
|
241
|
+
Lopi | pig | 2019-06-19
|
|
242
|
+
Rocky | snake | 2022-03-13
|
|
243
|
+
Denis | dog | 2022-06-19
|
|
244
|
+
Maca | cat | 2022-06-19
|
|
245
|
+
Luna | dog | 2022-08-15
|
|
246
|
+
Jeme | horse | 2019-08-08
|
|
247
|
+
Sary | bird | 2023-04-29
|
|
248
|
+
Rocky | bird | 2023-05-14
|
|
249
|
+
Coco | dog | 2023-05-27
|
|
250
|
+
DATA
|
|
251
|
+
|
|
252
|
+
# DB seed
|
|
253
|
+
pets = []
|
|
254
|
+
data.each_line(chomp: true) do |pet|
|
|
255
|
+
name, animal, birthdate = pet.split('|').map(&:strip)
|
|
256
|
+
pets << { name:, animal:, birthdate: }
|
|
257
|
+
end
|
|
258
|
+
Pet.insert_all(pets)
|
|
259
|
+
|
|
260
|
+
run PagyKeynav
|