pagy 4.11.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/lib/config/pagy.rb +119 -58
- data/lib/javascripts/pagy-dev.js +114 -0
- data/lib/javascripts/pagy-module.d.ts +5 -0
- data/lib/javascripts/pagy-module.js +113 -0
- data/lib/javascripts/pagy.js +1 -121
- data/lib/locales/de.yml +1 -1
- data/lib/locales/ko.yml +1 -1
- data/lib/locales/nn.yml +22 -0
- data/lib/locales/ta.yml +22 -0
- data/lib/pagy/backend.rb +10 -13
- data/lib/pagy/calendar/day.rb +39 -0
- data/lib/pagy/calendar/helper.rb +61 -0
- data/lib/pagy/calendar/month.rb +40 -0
- data/lib/pagy/calendar/quarter.rb +47 -0
- data/lib/pagy/calendar/week.rb +39 -0
- data/lib/pagy/calendar/year.rb +33 -0
- data/lib/pagy/calendar.rb +100 -0
- data/lib/pagy/console.rb +6 -4
- data/lib/pagy/countless.rb +22 -23
- data/lib/pagy/exceptions.rb +14 -16
- data/lib/pagy/extras/arel.rb +11 -7
- data/lib/pagy/extras/array.rb +9 -9
- data/lib/pagy/extras/bootstrap.rb +45 -38
- data/lib/pagy/extras/bulma.rb +50 -38
- data/lib/pagy/extras/calendar.rb +49 -0
- data/lib/pagy/extras/countless.rb +15 -18
- data/lib/pagy/extras/elasticsearch_rails.rb +67 -48
- data/lib/pagy/extras/foundation.rb +39 -35
- data/lib/pagy/extras/frontend_helpers.rb +72 -0
- data/lib/pagy/extras/gearbox.rb +54 -0
- data/lib/pagy/extras/headers.rb +30 -20
- data/lib/pagy/extras/i18n.rb +15 -13
- data/lib/pagy/extras/items.rb +42 -40
- data/lib/pagy/extras/materialize.rb +40 -38
- data/lib/pagy/extras/meilisearch.rb +53 -44
- data/lib/pagy/extras/metadata.rb +15 -20
- data/lib/pagy/extras/navs.rb +35 -34
- data/lib/pagy/extras/overflow.rb +62 -61
- data/lib/pagy/extras/searchkick.rb +54 -46
- data/lib/pagy/extras/semantic.rb +42 -40
- data/lib/pagy/extras/standalone.rb +50 -46
- data/lib/pagy/extras/support.rb +24 -16
- data/lib/pagy/extras/trim.rb +15 -14
- data/lib/pagy/extras/uikit.rb +41 -38
- data/lib/pagy/frontend.rb +36 -59
- data/lib/pagy/i18n.rb +164 -0
- data/lib/pagy/url_helpers.rb +24 -0
- data/lib/pagy.rb +90 -31
- data/lib/templates/bootstrap_nav.html.erb +2 -2
- data/lib/templates/bootstrap_nav.html.haml +2 -2
- data/lib/templates/bootstrap_nav.html.slim +2 -2
- data/lib/templates/foundation_nav.html.erb +1 -1
- data/lib/templates/foundation_nav.html.haml +1 -1
- data/lib/templates/foundation_nav.html.slim +1 -1
- data/lib/templates/nav.html.erb +1 -1
- data/lib/templates/nav.html.haml +1 -1
- data/lib/templates/nav.html.slim +1 -1
- data/lib/templates/uikit_nav.html.erb +2 -2
- data/lib/templates/uikit_nav.html.haml +1 -1
- data/lib/templates/uikit_nav.html.slim +2 -2
- metadata +29 -13
- data/lib/locales/utils/i18n.rb +0 -17
- data/lib/locales/utils/loader.rb +0 -31
- data/lib/locales/utils/p11n.rb +0 -112
- data/lib/pagy/deprecation.rb +0 -27
- data/lib/pagy/extras/shared.rb +0 -52
data/lib/pagy/countless.rb
CHANGED
@@ -1,38 +1,37 @@
|
|
1
|
+
# See Pagy::Countless API documentation: https://ddnexus.github.io/pagy/api/countless
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'pagy'
|
4
5
|
|
5
6
|
class Pagy
|
6
|
-
|
7
|
+
# No need to know the count to paginate
|
7
8
|
class Countless < Pagy
|
8
|
-
|
9
|
-
INSTANCE_VARS_MIN = { items: 1, page: 1, outset: 0 }.freeze
|
10
|
-
|
11
9
|
# Merge and validate the options, do some simple arithmetic and set a few instance variables
|
12
|
-
def initialize(vars={})
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
unless @vars[k] && instance_variable_set(:"@#{k}", @vars[k].to_i) >= min
|
19
|
-
end
|
20
|
-
@offset = @items * (@page - 1) + @outset # pagination offset + outset (initial offset)
|
10
|
+
def initialize(vars = {}) # rubocop:disable Lint/MissingSuper
|
11
|
+
normalize_vars(vars)
|
12
|
+
setup_vars(page: 1, outset: 0)
|
13
|
+
setup_items_var
|
14
|
+
setup_offset_var
|
15
|
+
setup_params_var
|
21
16
|
end
|
22
17
|
|
23
|
-
# Finalize the instance variables based on the fetched
|
24
|
-
def finalize(
|
25
|
-
raise OverflowError.new(self
|
26
|
-
if fetched.zero? && @page > 1
|
18
|
+
# Finalize the instance variables based on the fetched size
|
19
|
+
def finalize(fetched_size)
|
20
|
+
raise OverflowError.new(self, :page, "to be < #{@page}", @page) if fetched_size.zero? && @page > 1
|
27
21
|
|
28
|
-
@pages = @last = (
|
29
|
-
@
|
30
|
-
@from =
|
31
|
-
@to =
|
32
|
-
@prev = (@page-1 unless @page == 1)
|
33
|
-
@next = @page == @last ? (1 if @vars[:cycle]) : @page + 1
|
22
|
+
@pages = @last = (fetched_size > @items ? @page + 1 : @page)
|
23
|
+
@in = [fetched_size, @items].min
|
24
|
+
@from = @in.zero? ? 0 : @offset - @outset + 1
|
25
|
+
@to = @offset - @outset + @in
|
26
|
+
@prev = (@page - 1 unless @page == 1)
|
27
|
+
@next = @page == @last ? (1 if @vars[:cycle]) : @page + 1
|
34
28
|
self
|
35
29
|
end
|
36
30
|
|
31
|
+
# Override the original series.
|
32
|
+
# Return nil if :countless_minimal is enabled
|
33
|
+
def series(*, **)
|
34
|
+
super unless @vars[:countless_minimal]
|
35
|
+
end
|
37
36
|
end
|
38
37
|
end
|
data/lib/pagy/exceptions.rb
CHANGED
@@ -1,27 +1,25 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Pagy
|
4
|
-
|
5
|
-
# generic variable error
|
4
|
+
# Generic variable error
|
6
5
|
class VariableError < ArgumentError
|
7
|
-
attr_reader :pagy
|
8
|
-
|
9
|
-
def initialize(pagy)
|
10
|
-
super
|
11
|
-
@pagy = pagy
|
12
|
-
end
|
6
|
+
attr_reader :pagy, :variable, :value
|
13
7
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
pagy.vars[variable]
|
8
|
+
# Set the variables and prepare the message
|
9
|
+
def initialize(pagy, variable, description, value)
|
10
|
+
@pagy = pagy
|
11
|
+
@variable = variable
|
12
|
+
@value = value
|
13
|
+
super "expected :#{@variable} #{description}; got #{@value.inspect}"
|
21
14
|
end
|
22
15
|
end
|
23
16
|
|
24
|
-
#
|
17
|
+
# Specific overflow error
|
25
18
|
class OverflowError < VariableError; end
|
26
19
|
|
20
|
+
# I18n configuration error
|
21
|
+
class I18nError < StandardError; end
|
22
|
+
|
23
|
+
# Generic internal error
|
24
|
+
class InternalError < StandardError; end
|
27
25
|
end
|
data/lib/pagy/extras/arel.rb
CHANGED
@@ -1,22 +1,26 @@
|
|
1
1
|
# See the Pagy documentation: https://ddnexus.github.io/pagy/extras/arel
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
class Pagy
|
5
|
-
|
4
|
+
class Pagy # :nodoc:
|
5
|
+
# Better performance of grouped ActiveRecord collections
|
6
|
+
module ArelExtra
|
6
7
|
private
|
7
8
|
|
8
|
-
|
9
|
+
# Return Pagy object and paginated collection/results
|
10
|
+
def pagy_arel(collection, vars = {})
|
9
11
|
pagy = Pagy.new(pagy_arel_get_vars(collection, vars))
|
10
|
-
[
|
12
|
+
[pagy, pagy_get_items(collection, pagy)]
|
11
13
|
end
|
12
14
|
|
15
|
+
# Sub-method called only by #pagy_arel: here for easy customization of variables by overriding
|
13
16
|
def pagy_arel_get_vars(collection, vars)
|
14
|
-
pagy_set_items_from_params(vars) if defined?(
|
17
|
+
pagy_set_items_from_params(vars) if defined?(ItemsExtra)
|
15
18
|
vars[:count] ||= pagy_arel_count(collection)
|
16
|
-
vars[:page] ||= params[
|
19
|
+
vars[:page] ||= params[vars[:page_param] || DEFAULT[:page_param]]
|
17
20
|
vars
|
18
21
|
end
|
19
22
|
|
23
|
+
# Count using Arel when grouping
|
20
24
|
def pagy_arel_count(collection)
|
21
25
|
if collection.group_values.empty?
|
22
26
|
# COUNT(*)
|
@@ -27,6 +31,6 @@ class Pagy
|
|
27
31
|
collection.unscope(:order).limit(1).pluck(sql).first.to_i
|
28
32
|
end
|
29
33
|
end
|
30
|
-
|
31
34
|
end
|
35
|
+
Backend.prepend ArelExtra
|
32
36
|
end
|
data/lib/pagy/extras/array.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
# See the Pagy documentation: https://ddnexus.github.io/pagy/extras/array
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
class Pagy
|
5
|
-
#
|
6
|
-
module
|
4
|
+
class Pagy # :nodoc:
|
5
|
+
# Paginate arrays efficiently, avoiding expensive array-wrapping and without overriding
|
6
|
+
module ArrayExtra
|
7
7
|
private
|
8
8
|
|
9
|
-
# Return Pagy object and items
|
10
|
-
def pagy_array(array, vars={})
|
9
|
+
# Return Pagy object and paginated items
|
10
|
+
def pagy_array(array, vars = {})
|
11
11
|
pagy = Pagy.new(pagy_array_get_vars(array, vars))
|
12
|
-
[
|
12
|
+
[pagy, array[pagy.offset, pagy.items]]
|
13
13
|
end
|
14
14
|
|
15
15
|
# Sub-method called only by #pagy_array: here for easy customization of variables by overriding
|
16
16
|
def pagy_array_get_vars(array, vars)
|
17
|
-
pagy_set_items_from_params(vars) if defined?(
|
17
|
+
pagy_set_items_from_params(vars) if defined?(ItemsExtra)
|
18
18
|
vars[:count] ||= array.size
|
19
|
-
vars[:page] ||= params[
|
19
|
+
vars[:page] ||= params[vars[:page_param] || DEFAULT[:page_param]]
|
20
20
|
vars
|
21
21
|
end
|
22
|
-
|
23
22
|
end
|
23
|
+
Backend.prepend ArrayExtra
|
24
24
|
end
|
@@ -1,86 +1,93 @@
|
|
1
1
|
# See the Pagy documentation: https://ddnexus.github.io/pagy/extras/bootstrap
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require 'pagy/extras/
|
5
|
-
|
6
|
-
class Pagy
|
7
|
-
module Frontend
|
4
|
+
require 'pagy/extras/frontend_helpers'
|
8
5
|
|
6
|
+
class Pagy # :nodoc:
|
7
|
+
# Frontend modules are specially optimized for performance.
|
8
|
+
# The resulting code may not look very elegant, but produces the best benchmarks
|
9
|
+
module BootstrapExtra
|
9
10
|
# Pagination for bootstrap: it returns the html with the series of links to the pages
|
10
|
-
def pagy_bootstrap_nav(pagy, pagy_id: nil, link_extra: '')
|
11
|
+
def pagy_bootstrap_nav(pagy, pagy_id: nil, link_extra: '', **vars)
|
11
12
|
p_id = %( id="#{pagy_id}") if pagy_id
|
12
13
|
link = pagy_link_proc(pagy, link_extra: %(class="page-link" #{link_extra}))
|
13
14
|
|
14
|
-
html = +%(<nav#{p_id} class="pagy-bootstrap-nav"
|
15
|
+
html = +%(<nav#{p_id} class="pagy-bootstrap-nav"><ul class="pagination">)
|
15
16
|
html << pagy_bootstrap_prev_html(pagy, link)
|
16
|
-
pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
17
|
+
pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
17
18
|
html << case item
|
18
|
-
when Integer
|
19
|
-
|
20
|
-
when
|
19
|
+
when Integer
|
20
|
+
%(<li class="page-item">#{link.call item}</li>)
|
21
|
+
when String
|
22
|
+
%(<li class="page-item active">#{link.call item}</li>)
|
23
|
+
when :gap
|
24
|
+
%(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.gap'}</a></li>)
|
25
|
+
else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
|
21
26
|
end
|
22
27
|
end
|
23
28
|
html << pagy_bootstrap_next_html(pagy, link)
|
24
29
|
html << %(</ul></nav>)
|
25
30
|
end
|
26
31
|
|
27
|
-
# Javascript pagination for bootstrap: it returns a nav and a JSON tag used by the
|
28
|
-
def pagy_bootstrap_nav_js(pagy,
|
29
|
-
|
32
|
+
# Javascript pagination for bootstrap: it returns a nav and a JSON tag used by the pagy.js file
|
33
|
+
def pagy_bootstrap_nav_js(pagy, pagy_id: nil, link_extra: '', **vars)
|
34
|
+
sequels = pagy.sequels(**vars)
|
30
35
|
p_id = %( id="#{pagy_id}") if pagy_id
|
31
36
|
link = pagy_link_proc(pagy, link_extra: %(class="page-link" #{link_extra}))
|
32
37
|
tags = { 'before' => %(<ul class="pagination">#{pagy_bootstrap_prev_html pagy, link}),
|
33
|
-
'link' => %(<li class="page-item">#{mark = link.call(PAGE_PLACEHOLDER)}</li>),
|
38
|
+
'link' => %(<li class="page-item">#{mark = link.call(PAGE_PLACEHOLDER, LABEL_PLACEHOLDER)}</li>),
|
34
39
|
'active' => %(<li class="page-item active">#{mark}</li>),
|
35
40
|
'gap' => %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.gap'}</a></li>),
|
36
41
|
'after' => %(#{pagy_bootstrap_next_html pagy, link}</ul>) }
|
37
42
|
|
38
|
-
%(<nav#{p_id} class="pagy-
|
43
|
+
%(<nav#{p_id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-bootstrap-nav-js" #{
|
44
|
+
pagy_data(pagy, :nav, tags, sequels, pagy.label_sequels(sequels))}></nav>)
|
39
45
|
end
|
40
46
|
|
41
|
-
# Javascript combo pagination for bootstrap: it returns a nav and a JSON tag used by the
|
42
|
-
def pagy_bootstrap_combo_nav_js(pagy,
|
43
|
-
pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
|
47
|
+
# Javascript combo pagination for bootstrap: it returns a nav and a JSON tag used by the pagy.js file
|
48
|
+
def pagy_bootstrap_combo_nav_js(pagy, pagy_id: nil, link_extra: '')
|
44
49
|
p_id = %( id="#{pagy_id}") if pagy_id
|
45
50
|
link = pagy_link_proc(pagy, link_extra: link_extra)
|
46
51
|
p_page = pagy.page
|
47
52
|
p_pages = pagy.pages
|
48
|
-
input = %(<input type="number" min="1" max="#{p_pages}" value="#{
|
53
|
+
input = %(<input type="number" min="1" max="#{p_pages}" value="#{
|
54
|
+
p_page}" class="text-primary" style="padding: 0; border: none; text-align: center; width: #{
|
55
|
+
p_pages.to_s.length + 1}rem;">)
|
49
56
|
|
50
|
-
%(<nav#{p_id} class="pagy-bootstrap-combo-nav-js pagination"
|
51
|
-
|
52
|
-
}>#{
|
57
|
+
%(<nav#{p_id} class="pagy-bootstrap-combo-nav-js pagination"><div class="btn-group" role="group" #{
|
58
|
+
pagy_data(pagy, :combo, pagy_marked_link(link))}>#{
|
53
59
|
if (p_prev = pagy.prev)
|
54
60
|
link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous" class="prev btn btn-primary"'
|
55
61
|
else
|
56
62
|
%(<a class="prev btn btn-primary disabled" href="#">#{pagy_t('pagy.nav.prev')}</a>)
|
57
63
|
end
|
58
|
-
|
64
|
+
}<div class="pagy-combo-input btn btn-primary disabled" style="white-space: nowrap;">#{
|
65
|
+
pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages}</div>#{
|
59
66
|
if (p_next = pagy.next)
|
60
67
|
link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next" class="next btn btn-primary"'
|
61
68
|
else
|
62
|
-
%(<a class="next btn btn-primary disabled" href="#">#{pagy_t 'pagy.nav.next'
|
69
|
+
%(<a class="next btn btn-primary disabled" href="#">#{pagy_t 'pagy.nav.next'}</a>)
|
63
70
|
end
|
64
|
-
|
71
|
+
}</div></nav>)
|
65
72
|
end
|
66
73
|
|
67
74
|
private
|
68
75
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
76
|
+
def pagy_bootstrap_prev_html(pagy, link)
|
77
|
+
if (p_prev = pagy.prev)
|
78
|
+
%(<li class="page-item prev">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'aria-label="previous"'}</li>)
|
79
|
+
else
|
80
|
+
%(<li class="page-item prev disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.prev'}</a></li>)
|
75
81
|
end
|
82
|
+
end
|
76
83
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
end
|
84
|
+
def pagy_bootstrap_next_html(pagy, link)
|
85
|
+
if (p_next = pagy.next)
|
86
|
+
%(<li class="page-item next">#{link.call p_next, pagy_t('pagy.nav.next'), 'aria-label="next"'}</li>)
|
87
|
+
else
|
88
|
+
%(<li class="page-item next disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.next'}</a></li>)
|
83
89
|
end
|
84
|
-
|
90
|
+
end
|
85
91
|
end
|
92
|
+
Frontend.prepend BootstrapExtra
|
86
93
|
end
|
data/lib/pagy/extras/bulma.rb
CHANGED
@@ -1,82 +1,94 @@
|
|
1
1
|
# See the Pagy documentation: https://ddnexus.github.io/pagy/extras/bulma
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require 'pagy/extras/
|
4
|
+
require 'pagy/extras/frontend_helpers'
|
5
5
|
|
6
|
-
class Pagy
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
class Pagy # :nodoc:
|
7
|
+
# Frontend modules are specially optimized for performance.
|
8
|
+
# The resulting code may not look very elegant, but produces the best benchmarks
|
9
|
+
module BulmaExtra
|
10
|
+
# Pagination for bulma: it returns the html with the series of links to the pages
|
11
|
+
def pagy_bulma_nav(pagy, pagy_id: nil, link_extra: '', **vars)
|
11
12
|
p_id = %( id="#{pagy_id}") if pagy_id
|
12
13
|
link = pagy_link_proc(pagy, link_extra: link_extra)
|
13
14
|
|
14
15
|
html = +%(<nav#{p_id} class="pagy-bulma-nav pagination is-centered" aria-label="pagination">)
|
15
16
|
html << pagy_bulma_prev_next_html(pagy, link)
|
16
17
|
html << %(<ul class="pagination-list">)
|
17
|
-
pagy.series.each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
18
|
+
pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
|
18
19
|
html << case item
|
19
|
-
when Integer
|
20
|
-
|
21
|
-
when
|
20
|
+
when Integer
|
21
|
+
%(<li>#{link.call item, pagy.label_for(item), %(class="pagination-link" aria-label="goto page #{item}")}</li>)
|
22
|
+
when String
|
23
|
+
%(<li>#{link.call item, pagy.label_for(item),
|
24
|
+
%(class="pagination-link is-current" aria-label="page #{item}" aria-current="page")}</li>)
|
25
|
+
when :gap
|
26
|
+
%(<li><span class="pagination-ellipsis">#{pagy_t 'pagy.nav.gap'}</span></li>)
|
27
|
+
else raise InternalError, "expected item types in series to be Integer, String or :gap; got #{item.inspect}"
|
22
28
|
end
|
23
29
|
end
|
24
30
|
html << %(</ul></nav>)
|
25
31
|
end
|
26
32
|
|
27
|
-
|
28
|
-
|
33
|
+
# Javascript pagination for bulma: it returns a nav and a JSON tag used by the Pagy.nav javascript
|
34
|
+
def pagy_bulma_nav_js(pagy, pagy_id: nil, link_extra: '', **vars)
|
35
|
+
sequels = pagy.sequels(**vars)
|
29
36
|
p_id = %( id="#{pagy_id}") if pagy_id
|
30
37
|
link = pagy_link_proc(pagy, link_extra: link_extra)
|
31
38
|
tags = { 'before' => %(#{pagy_bulma_prev_next_html(pagy, link)}<ul class="pagination-list">),
|
32
|
-
'link' => %(<li>#{link.call PAGE_PLACEHOLDER,
|
33
|
-
|
34
|
-
'
|
39
|
+
'link' => %(<li>#{link.call PAGE_PLACEHOLDER, LABEL_PLACEHOLDER,
|
40
|
+
%(class="pagination-link" aria-label="goto page #{PAGE_PLACEHOLDER}")}</li>),
|
41
|
+
'active' => %(<li>#{link.call PAGE_PLACEHOLDER, LABEL_PLACEHOLDER,
|
42
|
+
%(class="pagination-link is-current" aria-current="page" aria-label="page #{
|
43
|
+
PAGE_PLACEHOLDER}")}</li>),
|
44
|
+
'gap' => %(<li><span class="pagination-ellipsis">#{pagy_t 'pagy.nav.gap'}</span></li>),
|
35
45
|
'after' => '</ul>' }
|
36
46
|
|
37
|
-
%(<nav#{p_id} class="pagy-
|
47
|
+
%(<nav#{p_id} class="#{'pagy-rjs ' if sequels.size > 1}pagy-bulma-nav-js pagination is-centered" aria-label="pagination" #{
|
48
|
+
pagy_data(pagy, :nav, tags, sequels, pagy.label_sequels(sequels))}></nav>)
|
38
49
|
end
|
39
50
|
|
40
|
-
# Javascript combo pagination for
|
41
|
-
def pagy_bulma_combo_nav_js(pagy,
|
42
|
-
pagy_id = Pagy.deprecated_arg(:id, deprecated_id, :pagy_id, pagy_id) if deprecated_id
|
51
|
+
# Javascript combo pagination for bulma: it returns a nav and a JSON tag used by the pagy.js file
|
52
|
+
def pagy_bulma_combo_nav_js(pagy, pagy_id: nil, link_extra: '')
|
43
53
|
p_id = %( id="#{pagy_id}") if pagy_id
|
44
54
|
link = pagy_link_proc(pagy, link_extra: link_extra)
|
45
55
|
p_page = pagy.page
|
46
56
|
p_pages = pagy.pages
|
47
|
-
input = %(<input class="input" type="number" min="1" max="#{p_pages}" value="#{
|
57
|
+
input = %(<input class="input" type="number" min="1" max="#{p_pages}" value="#{
|
58
|
+
p_page}" style="padding: 0; text-align: center; width: #{p_pages.to_s.length + 1}rem; margin:0 0.3rem;">)
|
48
59
|
|
49
|
-
%(<nav#{p_id} class="pagy-bulma-combo-nav-js" aria-label="pagination"
|
50
|
-
|
51
|
-
|
60
|
+
html = %(<nav#{p_id} class="pagy-bulma-combo-nav-js" aria-label="pagination">)
|
61
|
+
%(#{html}<div class="field is-grouped is-grouped-centered" role="group" #{
|
62
|
+
pagy_data(pagy, :combo, pagy_marked_link(link))}>#{
|
52
63
|
if (p_prev = pagy.prev)
|
53
64
|
%(<p class="control">#{link.call p_prev, pagy_t('pagy.nav.prev'), 'class="button" aria-label="previous page"'}</p>)
|
54
65
|
else
|
55
66
|
%(<p class="control"><a class="button" disabled>#{pagy_t 'pagy.nav.prev'}</a></p>)
|
56
67
|
end
|
57
|
-
|
68
|
+
}<div class="pagy-combo-input control level is-mobile">#{
|
69
|
+
pagy_t 'pagy.combo_nav_js', page_input: input, count: p_page, pages: p_pages}</div>#{
|
58
70
|
if (p_next = pagy.next)
|
59
71
|
%(<p class="control">#{link.call p_next, pagy_t('pagy.nav.next'), 'class="button" aria-label="next page"'}</p>)
|
60
72
|
else
|
61
73
|
%(<p class="control"><a class="button" disabled>#{pagy_t 'pagy.nav.next'}</a></p>)
|
62
74
|
end
|
63
|
-
|
75
|
+
}</div></nav>)
|
64
76
|
end
|
65
77
|
|
66
78
|
private
|
67
79
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
80
|
+
def pagy_bulma_prev_next_html(pagy, link)
|
81
|
+
html = +if (p_prev = pagy.prev)
|
82
|
+
link.call p_prev, pagy_t('pagy.nav.prev'), 'class="pagination-previous" aria-label="previous page"'
|
83
|
+
else
|
84
|
+
%(<a class="pagination-previous" disabled>#{pagy_t 'pagy.nav.prev'}</a>)
|
85
|
+
end
|
86
|
+
html << if (p_next = pagy.next)
|
87
|
+
link.call p_next, pagy_t('pagy.nav.next'), 'class="pagination-next" aria-label="next page"'
|
88
|
+
else
|
89
|
+
%(<a class="pagination-next" disabled>#{pagy_t 'pagy.nav.next'}</a>)
|
90
|
+
end
|
91
|
+
end
|
81
92
|
end
|
93
|
+
Frontend.prepend BulmaExtra
|
82
94
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# See the Pagy documentation: https://ddnexus.github.io/pagy/extras/calendar
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'pagy/calendar'
|
5
|
+
require 'pagy/calendar/helper'
|
6
|
+
|
7
|
+
class Pagy # :nodoc:
|
8
|
+
# Add pagination filtering by calendar unit (:year, :quarter, :month, :week, :day) to the regular pagination
|
9
|
+
module CalendarExtra
|
10
|
+
# Additions for the Backend module
|
11
|
+
module Backend
|
12
|
+
CONF_KEYS = (Calendar::UNITS + %i[pagy active]).freeze
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
# Take a collection and a conf Hash with keys in CONF_KEYS and return an array with 3 items: [calendar, pagy, results]
|
17
|
+
def pagy_calendar(collection, conf)
|
18
|
+
unless conf.is_a?(Hash) && (conf.keys - CONF_KEYS).empty? && conf.all? { |k, v| v.is_a?(Hash) || k == :active }
|
19
|
+
raise ArgumentError, "keys must be in #{CONF_KEYS.inspect} and object values must be Hashes; got #{conf.inspect}"
|
20
|
+
end
|
21
|
+
|
22
|
+
conf[:pagy] = {} unless conf[:pagy] # use default Pagy object when omitted
|
23
|
+
unless conf.key?(:active) && !conf[:active]
|
24
|
+
calendar, from, to = Calendar::Helper.send(:init, conf, pagy_calendar_period(collection), params)
|
25
|
+
collection = pagy_calendar_filter(collection, from, to)
|
26
|
+
end
|
27
|
+
pagy, results = send(conf[:pagy][:backend] || :pagy, collection, conf[:pagy]) # use backend: :pagy when omitted
|
28
|
+
[calendar, pagy, results]
|
29
|
+
end
|
30
|
+
|
31
|
+
def pagy_calendar_url_at(calendar, time)
|
32
|
+
pagy_url_for(calendar.send(:last_object_at, time), 1)
|
33
|
+
end
|
34
|
+
|
35
|
+
# This method must be implemented by the application
|
36
|
+
def pagy_calendar_period(*)
|
37
|
+
raise NoMethodError, 'the pagy_calendar_period method must be implemented by the application ' \
|
38
|
+
'(see https://ddnexus.github.io/pagy/extras/calendar#pagy_calendar_periodcollection)'
|
39
|
+
end
|
40
|
+
|
41
|
+
# This method must be implemented by the application
|
42
|
+
def pagy_calendar_filter(*)
|
43
|
+
raise NoMethodError, 'the pagy_calendar_filter method must be implemented by the application ' \
|
44
|
+
'(see https://ddnexus.github.io/pagy/extras/calendar#pagy_calendar_filtercollection-from-to)'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
Backend.prepend CalendarExtra::Backend
|
49
|
+
end
|
@@ -3,38 +3,35 @@
|
|
3
3
|
|
4
4
|
require 'pagy/countless'
|
5
5
|
|
6
|
-
class Pagy
|
6
|
+
class Pagy # :nodoc:
|
7
|
+
DEFAULT[:countless_minimal] = false
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
private # the whole module is private so no problem with including it in a controller
|
9
|
+
# Paginate without the need of any count, saving one query per rendering
|
10
|
+
module CountlessExtra
|
11
|
+
private
|
12
12
|
|
13
13
|
# Return Pagy object and items
|
14
|
-
def pagy_countless(collection, vars={})
|
15
|
-
pagy =
|
16
|
-
[
|
14
|
+
def pagy_countless(collection, vars = {})
|
15
|
+
pagy = Countless.new(pagy_countless_get_vars(collection, vars))
|
16
|
+
[pagy, pagy_countless_get_items(collection, pagy)]
|
17
17
|
end
|
18
18
|
|
19
19
|
# Sub-method called only by #pagy_countless: here for easy customization of variables by overriding
|
20
20
|
def pagy_countless_get_vars(_collection, vars)
|
21
|
-
pagy_set_items_from_params(vars) if defined?(
|
22
|
-
vars[:page] ||= params[
|
21
|
+
pagy_set_items_from_params(vars) if defined?(ItemsExtra)
|
22
|
+
vars[:page] ||= params[vars[:page_param] || DEFAULT[:page_param]]
|
23
23
|
vars
|
24
24
|
end
|
25
25
|
|
26
26
|
# Sub-method called only by #pagy_countless: here for easy customization of record-extraction by overriding
|
27
|
+
# You may need to override this method for collections without offset|limit
|
27
28
|
def pagy_countless_get_items(collection, pagy)
|
28
|
-
# This should work with ActiveRecord, Sequel, Mongoid...
|
29
29
|
return collection.offset(pagy.offset).limit(pagy.items) if pagy.vars[:countless_minimal]
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
# finalize may adjust pagy.items, so must be used after checking the size
|
35
|
-
pagy.finalize(items_size)
|
36
|
-
items
|
31
|
+
fetched = collection.offset(pagy.offset).limit(pagy.items + 1).to_a # eager load items + 1
|
32
|
+
pagy.finalize(fetched.size) # finalize the pagy object
|
33
|
+
fetched[0, pagy.items] # ignore eventual extra item
|
37
34
|
end
|
38
|
-
|
39
35
|
end
|
36
|
+
Backend.prepend CountlessExtra
|
40
37
|
end
|