pagy 8.0.0 → 9.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/apps/calendar.ru +745 -0
  3. data/{lib/apps → apps}/demo.ru +35 -52
  4. data/apps/keyset_ar.ru +236 -0
  5. data/apps/keyset_s.ru +238 -0
  6. data/{lib/apps → apps}/rails.ru +40 -33
  7. data/{lib/apps → apps}/repro.ru +33 -24
  8. data/apps/tmp/calendar.sqlite3 +0 -0
  9. data/apps/tmp/calendar.sqlite3-shm +0 -0
  10. data/apps/tmp/calendar.sqlite3-wal +0 -0
  11. data/apps/tmp/local_secret.txt +1 -0
  12. data/apps/tmp/pagy-keyset-ar.sqlite3 +0 -0
  13. data/apps/tmp/pagy-keyset-ar.sqlite3-shm +0 -0
  14. data/apps/tmp/pagy-keyset-ar.sqlite3-wal +0 -0
  15. data/apps/tmp/pagy-keyset-s.sqlite3 +0 -0
  16. data/{lib/bin → bin}/pagy +36 -17
  17. data/{lib/config → config}/pagy.rb +37 -68
  18. data/javascripts/pagy-module.js +100 -0
  19. data/javascripts/pagy.js +4 -0
  20. data/javascripts/pagy.min.js +4 -0
  21. data/javascripts/pagy.min.js.map +10 -0
  22. data/javascripts/pagy.mjs +100 -0
  23. data/lib/optimist.rb +1 -1
  24. data/lib/pagy/b64.rb +33 -0
  25. data/lib/pagy/backend.rb +24 -15
  26. data/lib/pagy/calendar/day.rb +5 -4
  27. data/lib/pagy/calendar/month.rb +5 -4
  28. data/lib/pagy/calendar/quarter.rb +5 -4
  29. data/lib/pagy/calendar/unit.rb +103 -0
  30. data/lib/pagy/calendar/week.rb +4 -4
  31. data/lib/pagy/calendar/year.rb +5 -4
  32. data/lib/pagy/calendar.rb +55 -99
  33. data/lib/pagy/console.rb +2 -2
  34. data/lib/pagy/countless.rb +17 -16
  35. data/lib/pagy/extras/arel.rb +8 -10
  36. data/lib/pagy/extras/array.rb +4 -6
  37. data/lib/pagy/extras/bootstrap.rb +7 -7
  38. data/lib/pagy/extras/bulma.rb +13 -9
  39. data/lib/pagy/extras/calendar.rb +35 -6
  40. data/lib/pagy/extras/countless.rb +7 -14
  41. data/lib/pagy/extras/elasticsearch_rails.rb +15 -15
  42. data/lib/pagy/extras/gearbox.rb +36 -35
  43. data/lib/pagy/extras/headers.rb +26 -25
  44. data/lib/pagy/extras/i18n.rb +1 -1
  45. data/lib/pagy/extras/js_tools.rb +12 -9
  46. data/lib/pagy/extras/jsonapi.rb +27 -17
  47. data/lib/pagy/extras/keyset.rb +26 -0
  48. data/lib/pagy/extras/limit.rb +63 -0
  49. data/lib/pagy/extras/meilisearch.rb +11 -11
  50. data/lib/pagy/extras/metadata.rb +7 -3
  51. data/lib/pagy/extras/overflow.rb +9 -8
  52. data/lib/pagy/extras/pagy.rb +18 -18
  53. data/lib/pagy/extras/searchkick.rb +11 -11
  54. data/lib/pagy/extras/size.rb +40 -0
  55. data/lib/pagy/extras/standalone.rb +8 -8
  56. data/lib/pagy/extras/trim.rb +3 -3
  57. data/lib/pagy/frontend.rb +39 -37
  58. data/lib/pagy/i18n.rb +1 -1
  59. data/lib/pagy/keyset/active_record.rb +38 -0
  60. data/lib/pagy/keyset/sequel.rb +51 -0
  61. data/lib/pagy/keyset.rb +99 -0
  62. data/lib/pagy/url_helpers.rb +11 -11
  63. data/lib/pagy.rb +96 -120
  64. data/{lib/locales → locales}/ar.yml +9 -10
  65. data/{lib/locales → locales}/be.yml +2 -2
  66. data/{lib/locales → locales}/bg.yml +2 -2
  67. data/{lib/locales → locales}/bs.yml +2 -2
  68. data/{lib/locales → locales}/ca.yml +5 -7
  69. data/{lib/locales → locales}/ckb.yml +2 -2
  70. data/{lib/locales → locales}/cs.yml +2 -2
  71. data/{lib/locales → locales}/da.yml +5 -7
  72. data/{lib/locales → locales}/de.yml +2 -2
  73. data/{lib/locales → locales}/en.yml +2 -2
  74. data/{lib/locales → locales}/es.yml +2 -2
  75. data/{lib/locales → locales}/fr.yml +2 -2
  76. data/{lib/locales → locales}/hr.yml +2 -2
  77. data/{lib/locales → locales}/id.yml +2 -2
  78. data/{lib/locales → locales}/it.yml +2 -2
  79. data/{lib/locales → locales}/ja.yml +2 -2
  80. data/{lib/locales → locales}/km.yml +2 -2
  81. data/{lib/locales → locales}/ko.yml +3 -5
  82. data/{lib/locales → locales}/nb.yml +2 -2
  83. data/{lib/locales → locales}/nl.yml +2 -2
  84. data/{lib/locales → locales}/nn.yml +2 -2
  85. data/{lib/locales → locales}/pl.yml +2 -2
  86. data/{lib/locales → locales}/pt-BR.yml +2 -2
  87. data/{lib/locales → locales}/pt.yml +2 -2
  88. data/{lib/locales → locales}/ru.yml +7 -9
  89. data/{lib/locales → locales}/sr.yml +2 -2
  90. data/{lib/locales → locales}/sv-SE.yml +2 -2
  91. data/{lib/locales → locales}/sv.yml +2 -2
  92. data/{lib/locales → locales}/sw.yml +2 -2
  93. data/{lib/locales → locales}/ta.yml +2 -2
  94. data/{lib/locales → locales}/tr.yml +2 -2
  95. data/{lib/locales → locales}/uk.yml +2 -2
  96. data/{lib/locales → locales}/vi.yml +2 -2
  97. data/{lib/locales → locales}/zh-CN.yml +2 -2
  98. data/{lib/locales → locales}/zh-HK.yml +2 -2
  99. data/{lib/locales → locales}/zh-TW.yml +2 -2
  100. data/pkg/pagy-9.0.0.gem +0 -0
  101. metadata +75 -70
  102. data/lib/apps/calendar.ru +0 -2196
  103. data/lib/javascripts/pagy-dev.js +0 -112
  104. data/lib/javascripts/pagy-module.js +0 -111
  105. data/lib/javascripts/pagy.js +0 -1
  106. data/lib/pagy/calendar/helper.rb +0 -65
  107. data/lib/pagy/extras/foundation.rb +0 -93
  108. data/lib/pagy/extras/items.rb +0 -64
  109. data/lib/pagy/extras/materialize.rb +0 -97
  110. data/lib/pagy/extras/semantic.rb +0 -91
  111. data/lib/pagy/extras/uikit.rb +0 -96
  112. /data/{lib/javascripts/pagy-module.d.ts → javascripts/pagy.d.ts} +0 -0
  113. /data/{lib/stylesheets → stylesheets}/pagy.css +0 -0
  114. /data/{lib/stylesheets → stylesheets}/pagy.scss +0 -0
  115. /data/{lib/stylesheets → stylesheets}/pagy.tailwind.css +0 -0
data/lib/pagy/calendar.rb CHANGED
@@ -1,123 +1,79 @@
1
1
  # See Pagy::Countless API documentation: https://ddnexus.github.io/pagy/docs/api/calendar
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'active_support'
5
- require 'active_support/core_ext/time'
6
- require 'active_support/core_ext/date_and_time/calculations'
7
- require 'active_support/core_ext/numeric/time'
8
- require 'active_support/core_ext/integer/time'
9
-
10
- require 'pagy'
4
+ require_relative '../pagy'
5
+ require_relative 'calendar/unit'
11
6
 
12
7
  class Pagy # :nodoc:
13
- # Base class for time units subclasses (Year, Quarter, Month, Week, Day)
14
- class Calendar < Pagy
8
+ # Calendar class
9
+ class Calendar < Hash
15
10
  # Specific out of range error
16
11
  class OutOfRangeError < VariableError; end
17
12
 
18
13
  # List of units in desc order of duration. It can be used for custom units.
19
14
  UNITS = %i[year quarter month week day] # rubocop:disable Style/MutableConstant
20
15
 
21
- attr_reader :order, :from, :to
22
-
23
- # Merge and validate the options, do some simple arithmetic and set a few instance variables
24
- def initialize(vars) # rubocop:disable Lint/MissingSuper
25
- raise InternalError, 'Pagy::Calendar is a base class; use one of its subclasses' if instance_of?(Pagy::Calendar)
26
-
27
- vars = self.class::DEFAULT.merge(vars) # subclass specific default
28
- normalize_vars(vars) # general default
29
- setup_vars(page: 1)
30
- setup_unit_vars
31
- setup_params_var
32
- raise OverflowError.new(self, :page, "in 1..#{@last}", @page) if @page > @last
33
-
34
- @prev = (@page - 1 unless @page == 1)
35
- @next = @page == @last ? (1 if @vars[:cycle]) : @page + 1
36
- end
37
-
38
- # The label for the current page (it can pass along the I18n gem opts when it's used with the i18n extra)
39
- def label(opts = {})
40
- label_for(@page, opts)
41
- end
42
-
43
- # The label for any page (it can pass along the I18n gem opts when it's used with the i18n extra)
44
- def label_for(page, opts = {})
45
- opts[:format] ||= @vars[:format]
46
- localize(starting_time_for(page.to_i), opts) # page could be a string
47
- end
48
-
49
- protected
16
+ class << self
17
+ private
50
18
 
51
- # The page that includes time
52
- # In case of out of range time, the :fit_time option avoids the outOfRangeError
53
- # and returns the closest page to the passed time argument (first or last page)
54
- def page_at(time, **opts)
55
- fit_time = time
56
- fit_final = @final - 1
57
- unless time.between?(@initial, fit_final)
58
- raise OutOfRangeError.new(self, :time, "between #{@initial} and #{fit_final}", time) unless opts[:fit_time]
19
+ # Create a unit subclass instance by using the unit name (internal use)
20
+ def create(unit, **vars)
21
+ raise InternalError, "unit must be in #{UNITS.inspect}; got #{unit}" unless UNITS.include?(unit)
59
22
 
60
- if time < @final
61
- fit_time = @initial
62
- ordinal = 'first'
63
- else
64
- fit_time = fit_final
65
- ordinal = 'last'
66
- end
67
- Warning.warn "Pagy::Calendar#page_at: Rescued #{time} out of range by returning the #{ordinal} page."
23
+ name = unit.to_s
24
+ name[0] = name[0].capitalize
25
+ Object.const_get("Pagy::Calendar::#{name}").new(**vars)
68
26
  end
69
- offset = page_offset_at(fit_time) # offset starts from 0
70
- @order == :asc ? offset + 1 : @pages - offset
71
- end
72
27
 
73
- # Base class method for the setup of the unit variables (subclasses must implement it and call super)
74
- def setup_unit_vars
75
- raise VariableError.new(self, :format, 'to be a strftime format', @vars[:format]) unless @vars[:format].is_a?(String)
76
- raise VariableError.new(self, :order, 'to be in [:asc, :desc]', @order) \
77
- unless %i[asc desc].include?(@order = @vars[:order])
78
-
79
- @starting, @ending = @vars[:period]
80
- raise VariableError.new(self, :period, 'to be a an Array of min and max TimeWithZone instances', @vars[:period]) \
81
- unless @starting.is_a?(ActiveSupport::TimeWithZone) \
82
- && @ending.is_a?(ActiveSupport::TimeWithZone) && @starting <= @ending
83
- end
84
-
85
- # Apply the strftime format to the time (overridden by the i18n extra when localization is required)
86
- def localize(time, opts)
87
- time.strftime(opts[:format])
88
- end
89
-
90
- # Number of time units to offset from the @initial time, in order to get the ordered starting time for the page.
91
- # Used in starting_time_for(page) where page starts from 1 (e.g. page to starting_time means subtracting 1)
92
- def time_offset_for(page)
93
- @order == :asc ? page - 1 : @pages - page
94
- end
95
-
96
- # Period of the active page (used internally for nested units)
97
- def active_period
98
- [[@starting, @from].max, [@to - 1, @ending].min] # -1 sec: include only last unit day
28
+ # Return calendar, from, to
29
+ def init(conf, period, params)
30
+ new.send(:init, conf, period, params)
31
+ end
99
32
  end
100
33
 
101
- # :nocov:
102
- # This method must be implemented by the unit subclass
103
- def starting_time_for(*)
104
- raise NoMethodError, 'the starting_time_for method must be implemented by the unit subclass'
34
+ # Return the current time of the smallest time unit shown
35
+ def showtime
36
+ self[@units.last].from
105
37
  end
106
38
 
107
- # This method must be implemented by the unit subclass
108
- def page_offset_at(*)
109
- raise NoMethodError, 'the page_offset_at method must be implemented by the unit subclass'
39
+ private
40
+
41
+ # Create the calendar
42
+ def init(conf, period, params)
43
+ @conf = Marshal.load(Marshal.dump(conf)) # store a copy
44
+ @units = Calendar::UNITS & @conf.keys # get the units in time length desc order
45
+ raise ArgumentError, 'no calendar unit found in pagy_calendar @configuration' if @units.empty?
46
+
47
+ @period = period
48
+ @params = params
49
+ @page_param = conf[:pagy][:page_param] || DEFAULT[:page_param]
50
+ @units.each do |unit| # set all the :page_param vars for later deletion
51
+ unit_page_param = :"#{unit}_#{@page_param}"
52
+ conf[unit][:page_param] = unit_page_param
53
+ conf[unit][:page] = @params[unit_page_param]
54
+ end
55
+ calendar = {}
56
+ object = nil
57
+ @units.each_with_index do |unit, index|
58
+ params_to_delete = @units[(index + 1), @units.size].map { |sub| conf[sub][:page_param] } + [@page_param]
59
+ conf[unit][:params] = lambda { |up| up.except(*params_to_delete.map(&:to_s)) } # rubocop:disable Style/Lambda
60
+ conf[unit][:period] = object&.send(:active_period) || @period
61
+ calendar[unit] = object = Calendar.send(:create, unit, **conf[unit])
62
+ end
63
+ [replace(calendar), object.from, object.to]
110
64
  end
111
- # :nocov:
112
65
 
113
- class << self
114
- # Create a subclass instance by unit name (internal use)
115
- def create(unit, vars)
116
- raise InternalError, "unit must be in #{UNITS.inspect}; got #{unit}" unless UNITS.include?(unit)
117
-
118
- name = unit.to_s
119
- name[0] = name[0].capitalize
120
- Object.const_get("Pagy::Calendar::#{name}").new(vars)
66
+ # Return the calendar object at time
67
+ def calendar_at(time, **opts)
68
+ conf = Marshal.load(Marshal.dump(@conf))
69
+ page_params = {}
70
+ @units.inject(nil) do |object, unit|
71
+ conf[unit][:period] = object&.send(:active_period) || @period
72
+ conf[unit][:page] = page_params[:"#{unit}_#{@page_param}"] \
73
+ = Calendar.send(:create, unit, **conf[unit]).send(:page_at, time, **opts)
74
+ conf[unit][:params] ||= {}
75
+ conf[unit][:params].merge!(page_params)
76
+ Calendar.send(:create, unit, **conf[unit])
121
77
  end
122
78
  end
123
79
  end
data/lib/pagy/console.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  # See Pagy::Console API documentation: https://ddnexus.github.io/pagy/docs/api/console
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'pagy' # so you can require just the extra in the console
5
- require 'pagy/extras/standalone'
4
+ require_relative '../pagy' # so you can require just the extra in the console
5
+ require_relative 'extras/standalone'
6
6
 
7
7
  class Pagy
8
8
  # Provide a ready to use pagy environment when included in irb/rails console
@@ -1,37 +1,38 @@
1
1
  # See Pagy::Countless API documentation: https://ddnexus.github.io/pagy/docs/api/countless
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'pagy'
5
-
6
- class Pagy
4
+ class Pagy # :nodoc:
7
5
  # No need to know the count to paginate
8
6
  class Countless < Pagy
9
7
  # Merge and validate the options, do some simple arithmetic and set a few instance variables
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
8
+ def initialize(**vars) # rubocop:disable Lint/MissingSuper
9
+ assign_vars(DEFAULT, vars)
10
+ assign_and_check(page: 1, outset: 0)
11
+ assign_limit
12
+ assign_offset
16
13
  end
17
14
 
18
15
  # Finalize the instance variables based on the fetched size
19
16
  def finalize(fetched_size)
20
17
  raise OverflowError.new(self, :page, "to be < #{@page}", @page) if fetched_size.zero? && @page > 1
21
18
 
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
19
+ @last = fetched_size > @limit ? @page + 1 : @page
20
+ @last = @vars[:max_pages] if @vars[:max_pages] && @last > @vars[:max_pages]
21
+ check_overflow
22
+ @in = [fetched_size, @limit].min
23
+ @from = @in.zero? ? 0 : @offset - @outset + 1
24
+ @to = @offset - @outset + @in
25
+ assign_prev_and_next
28
26
  self
29
27
  end
28
+ end
30
29
 
30
+ module SeriesOverride # :nodoc:
31
31
  # Override the original series.
32
32
  # Return nil if :countless_minimal is enabled
33
- def series(*, **)
33
+ def series(**)
34
34
  super unless @vars[:countless_minimal]
35
35
  end
36
36
  end
37
+ prepend SeriesOverride
37
38
  end
@@ -7,19 +7,11 @@ class Pagy # :nodoc:
7
7
  private
8
8
 
9
9
  # Return Pagy object and paginated collection/results
10
- def pagy_arel(collection, vars = {})
11
- pagy = Pagy.new(pagy_arel_get_vars(collection, vars))
10
+ def pagy_arel(collection, **vars)
11
+ pagy = Pagy.new(**pagy_arel_get_vars(collection, vars))
12
12
  [pagy, pagy_get_items(collection, pagy)]
13
13
  end
14
14
 
15
- # Sub-method called only by #pagy_arel: here for easy customization of variables by overriding
16
- def pagy_arel_get_vars(collection, vars)
17
- pagy_set_items_from_params(vars) if defined?(ItemsExtra)
18
- vars[:count] ||= pagy_arel_count(collection)
19
- vars[:page] ||= params[vars[:page_param] || DEFAULT[:page_param]]
20
- vars
21
- end
22
-
23
15
  # Count using Arel when grouping
24
16
  def pagy_arel_count(collection)
25
17
  if collection.group_values.empty?
@@ -31,6 +23,12 @@ class Pagy # :nodoc:
31
23
  collection.unscope(:order).limit(1).pluck(sql).first.to_i
32
24
  end
33
25
  end
26
+
27
+ # Sub-method called only by #pagy_arel: here for easy customization of variables by overriding
28
+ def pagy_arel_get_vars(collection, vars)
29
+ vars[:count] ||= pagy_arel_count(collection)
30
+ pagy_get_vars(collection, vars)
31
+ end
34
32
  end
35
33
  Backend.prepend ArelExtra
36
34
  end
@@ -7,17 +7,15 @@ class Pagy # :nodoc:
7
7
  private
8
8
 
9
9
  # Return Pagy object and paginated items
10
- def pagy_array(array, vars = {})
11
- pagy = Pagy.new(pagy_array_get_vars(array, vars))
12
- [pagy, array[pagy.offset, pagy.items]]
10
+ def pagy_array(array, **vars)
11
+ pagy = Pagy.new(**pagy_array_get_vars(array, vars))
12
+ [pagy, array[pagy.offset, pagy.limit]]
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?(ItemsExtra)
18
17
  vars[:count] ||= array.size
19
- vars[:page] ||= params[vars[:page_param] || DEFAULT[:page_param]]
20
- vars
18
+ pagy_get_vars(array, vars)
21
19
  end
22
20
  end
23
21
  Backend.prepend ArrayExtra
@@ -1,7 +1,7 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/bootstrap
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'pagy/extras/js_tools'
4
+ require_relative 'js_tools'
5
5
 
6
6
  class Pagy # :nodoc:
7
7
  # Frontend modules are specially optimized for performance.
@@ -10,7 +10,7 @@ class Pagy # :nodoc:
10
10
  # Pagination for bootstrap: it returns the html with the series of links to the pages
11
11
  def pagy_bootstrap_nav(pagy, id: nil, classes: 'pagination', aria_label: nil, **vars)
12
12
  id = %( id="#{id}") if id
13
- a = pagy_anchor(pagy)
13
+ a = pagy_anchor(pagy, **vars)
14
14
 
15
15
  html = %(<nav#{id} class="pagy-bootstrap nav" #{nav_aria_label(pagy, aria_label:)}><ul class="#{classes}">#{
16
16
  bootstrap_prev_html(pagy, a)})
@@ -34,7 +34,7 @@ class Pagy # :nodoc:
34
34
  def pagy_bootstrap_nav_js(pagy, id: nil, classes: 'pagination', aria_label: nil, **vars)
35
35
  sequels = pagy.sequels(**vars)
36
36
  id = %( id="#{id}") if id
37
- a = pagy_anchor(pagy)
37
+ a = pagy_anchor(pagy, **vars)
38
38
  tokens = { 'before' => %(<ul class="#{classes}">#{bootstrap_prev_html(pagy, a)}),
39
39
  'a' => %(<li class="page-item">#{a.(PAGE_TOKEN, LABEL_TOKEN, classes: 'page-link')}</li>),
40
40
  'current' => %(<li class="page-item active"><a role="link" class="page-link" ) +
@@ -50,18 +50,18 @@ class Pagy # :nodoc:
50
50
  end
51
51
 
52
52
  # Javascript combo pagination for bootstrap: it returns a nav with a data-pagy attribute used by the pagy.js file
53
- def pagy_bootstrap_combo_nav_js(pagy, id: nil, classes: 'pagination', aria_label: nil)
53
+ def pagy_bootstrap_combo_nav_js(pagy, id: nil, classes: 'pagination', aria_label: nil, **vars)
54
54
  id = %( id="#{id}") if id
55
- a = pagy_anchor(pagy)
55
+ a = pagy_anchor(pagy, **vars)
56
56
  pages = pagy.pages
57
57
 
58
58
  page_input = %(<input name="page" type="number" min="1" max="#{pages}" value="#{pagy.page}" aria-current="page" ) <<
59
59
  %(style="text-align: center; width: #{pages.to_s.length + 1}rem; padding: 0; ) <<
60
- %(border: none; display: inline-block;" class="page-link active">)
60
+ %(border: none; display: inline-block;" class="page-link active">#{JSTools::A_TAG})
61
61
 
62
62
  %(<nav#{id} class="pagy-bootstrap combo-nav-js" #{
63
63
  nav_aria_label(pagy, aria_label:)} #{
64
- pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))
64
+ pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN, **vars))
65
65
  }><ul class="#{classes}">#{
66
66
  bootstrap_prev_html(pagy, a)
67
67
  }<li class="page-item pagy-bootstrap"><label class="page-link">#{
@@ -1,16 +1,17 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/bulma
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'pagy/extras/js_tools'
4
+ require_relative 'js_tools'
5
5
 
6
6
  class Pagy # :nodoc:
7
7
  # Frontend modules are specially optimized for performance.
8
8
  # The resulting code may not look very elegant, but produces the best benchmarks
9
9
  module BulmaExtra
10
10
  # Pagination for bulma: it returns the html with the series of links to the pages
11
- def pagy_bulma_nav(pagy, id: nil, classes: 'pagy-bulma nav pagination is-centered', aria_label: nil, **vars)
11
+ def pagy_bulma_nav(pagy, id: nil, classes: 'pagy-bulma nav pagination is-centered',
12
+ aria_label: nil, **vars)
12
13
  id = %( id="#{id}") if id
13
- a = pagy_anchor(pagy)
14
+ a = pagy_anchor(pagy, **vars)
14
15
 
15
16
  html = %(<nav#{id} class="#{classes}" #{nav_aria_label(pagy, aria_label:)}>)
16
17
  html << bulma_prev_next_html(pagy, a)
@@ -31,10 +32,11 @@ class Pagy # :nodoc:
31
32
  end
32
33
 
33
34
  # Javascript pagination for bulma: it returns a nav with a data-pagy attribute used by the Pagy.nav javascript
34
- def pagy_bulma_nav_js(pagy, id: nil, classes: 'pagy-bulma nav-js pagination is-centered', aria_label: nil, **vars)
35
+ def pagy_bulma_nav_js(pagy, id: nil, classes: 'pagy-bulma nav-js pagination is-centered',
36
+ aria_label: nil, **vars)
35
37
  sequels = pagy.sequels(**vars)
36
38
  id = %( id="#{id}") if id
37
- a = pagy_anchor(pagy)
39
+ a = pagy_anchor(pagy, **vars)
38
40
  tokens = { 'before' => %(#{bulma_prev_next_html(pagy, a)}<ul class="pagination-list">),
39
41
  'a' => %(<li>#{a.(PAGE_TOKEN, LABEL_TOKEN, classes: 'pagination-link')}</li>),
40
42
  'current' => %(<li><a role="link" class="pagination-link is-current" aria-current="page" aria-disabled="true">#{
@@ -49,18 +51,20 @@ class Pagy # :nodoc:
49
51
  end
50
52
 
51
53
  # Javascript combo pagination for bulma: it returns a nav with a data-pagy attribute used by the pagy.js file
52
- def pagy_bulma_combo_nav_js(pagy, id: nil, classes: 'pagy-bulma combo-nav-js pagination is-centered', aria_label: nil)
54
+ def pagy_bulma_combo_nav_js(pagy, id: nil, classes: 'pagy-bulma combo-nav-js pagination is-centered',
55
+ aria_label: nil, **vars)
53
56
  id = %( id="#{id}") if id
54
- a = pagy_anchor(pagy)
57
+ a = pagy_anchor(pagy, **vars)
55
58
  pages = pagy.pages
56
59
 
57
60
  page_input = %(<input name="page" type="number" min="1" max="#{pages}" value="#{pagy.page}" aria-current="page") <<
58
61
  %(style="text-align: center; width: #{pages.to_s.length + 1}rem; height: 1.7rem; margin:0 0.3rem; ) <<
59
- %(border: none; border-radius: 4px; padding: 0; font-size: 1.1rem; color: white; background-color: #485fc7;">)
62
+ %(border: none; border-radius: 4px; padding: 0; font-size: 1.1rem; color: white; ) <<
63
+ %(background-color: #485fc7;">#{JSTools::A_TAG})
60
64
 
61
65
  %(<nav#{id} class="#{classes}" #{
62
66
  nav_aria_label(pagy, aria_label:)} #{
63
- pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN))
67
+ pagy_data(pagy, :combo, pagy_url_for(pagy, PAGE_TOKEN, **vars))
64
68
  }>#{
65
69
  bulma_prev_next_html(pagy, a)
66
70
  }<ul class="pagination-list"><li class="pagination-link"><label>#{
@@ -1,8 +1,7 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/calendar
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'pagy/calendar'
5
- require 'pagy/calendar/helper'
4
+ require_relative '../calendar'
6
5
 
7
6
  class Pagy # :nodoc:
8
7
  # Add pagination filtering by calendar unit (:year, :quarter, :month, :week, :day) to the regular pagination
@@ -20,10 +19,15 @@ class Pagy # :nodoc:
20
19
 
21
20
  conf[:pagy] ||= {}
22
21
  unless conf.key?(:active) && !conf[:active]
23
- calendar, from, to = Calendar::Helper.send(:init, conf, pagy_calendar_period(collection), params)
24
- collection = pagy_calendar_filter(collection, from, to)
22
+ calendar, from, to = Calendar.send(:init, conf, pagy_calendar_period(collection), params)
23
+ if respond_to?(:pagy_calendar_counts)
24
+ calendar.each_key do |unit|
25
+ calendar[unit].vars[:counts] = pagy_calendar_counts(collection, unit, *calendar[unit].vars[:period])
26
+ end
27
+ end
28
+ collection = pagy_calendar_filter(collection, from, to)
25
29
  end
26
- pagy, results = send(conf[:pagy][:backend] || :pagy, collection, conf[:pagy]) # use backend: :pagy when omitted
30
+ pagy, results = send(conf[:pagy][:backend] || :pagy, collection, **conf[:pagy]) # use backend: :pagy when omitted
27
31
  [calendar, pagy, results]
28
32
  end
29
33
 
@@ -40,6 +44,31 @@ class Pagy # :nodoc:
40
44
  end
41
45
  end
42
46
 
47
+ # Override the pagy_anchor
48
+ module FrontendOverride
49
+ # Consider the vars[:count]
50
+ def pagy_anchor(pagy, anchor_string: nil)
51
+ return super unless (counts = pagy.vars[:counts])
52
+
53
+ anchor_string &&= %( #{anchor_string})
54
+ left, right = %(<a#{anchor_string} href="#{pagy_url_for(pagy, PAGE_TOKEN)}").split(PAGE_TOKEN, 2)
55
+ # lambda used by all the helpers
56
+ lambda do |page, text = pagy.label_for(page), classes: nil, aria_label: nil|
57
+ count = counts[page - 1]
58
+ item_name = pagy_t('pagy.item_name', count:)
59
+ if count.zero?
60
+ classes = "#{classes && (classes + ' ')}empty-page"
61
+ title = %( title="#{pagy_t('pagy.info.no_items', item_name:, count:)}")
62
+ else
63
+ title = %( title="#{pagy_t('pagy.info.single_page', item_name:, count:)}")
64
+ end
65
+ classes = %( class="#{classes}") if classes
66
+ aria_label = %( aria-label="#{aria_label}") if aria_label
67
+ %(#{left}#{page}#{right}#{title}#{classes}#{aria_label}>#{text}</a>)
68
+ end
69
+ end
70
+ end
71
+
43
72
  # Additions for the Frontend module
44
73
  module UrlHelperAddOn
45
74
  # Return the url for the calendar page at time
@@ -49,5 +78,5 @@ class Pagy # :nodoc:
49
78
  end
50
79
  end
51
80
  Backend.prepend CalendarExtra::BackendAddOn, CalendarExtra::UrlHelperAddOn
52
- Frontend.prepend CalendarExtra::UrlHelperAddOn
81
+ Frontend.prepend CalendarExtra::UrlHelperAddOn, CalendarExtra::FrontendOverride
53
82
  end
@@ -1,7 +1,7 @@
1
1
  # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/countless
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'pagy/countless'
4
+ require_relative '../countless'
5
5
 
6
6
  class Pagy # :nodoc:
7
7
  DEFAULT[:countless_minimal] = false
@@ -10,27 +10,20 @@ class Pagy # :nodoc:
10
10
  module CountlessExtra
11
11
  private
12
12
 
13
- # Return Pagy object and items
14
- def pagy_countless(collection, vars = {})
15
- pagy = Countless.new(pagy_countless_get_vars(collection, vars))
13
+ # Return Pagy object and records
14
+ def pagy_countless(collection, **vars)
15
+ pagy = Countless.new(**pagy_get_vars(collection, vars))
16
16
  [pagy, pagy_countless_get_items(collection, pagy)]
17
17
  end
18
18
 
19
- # Sub-method called only by #pagy_countless: here for easy customization of variables by overriding
20
- def pagy_countless_get_vars(_collection, vars)
21
- pagy_set_items_from_params(vars) if defined?(ItemsExtra)
22
- vars[:page] ||= params[vars[:page_param] || DEFAULT[:page_param]]
23
- vars
24
- end
25
-
26
19
  # Sub-method called only by #pagy_countless: here for easy customization of record-extraction by overriding
27
20
  # You may need to override this method for collections without offset|limit
28
21
  def pagy_countless_get_items(collection, pagy)
29
- return collection.offset(pagy.offset).limit(pagy.items) if pagy.vars[:countless_minimal]
22
+ return collection.offset(pagy.offset).limit(pagy.limit) if pagy.vars[:countless_minimal]
30
23
 
31
- fetched = collection.offset(pagy.offset).limit(pagy.items + 1).to_a # eager load items + 1
24
+ fetched = collection.offset(pagy.offset).limit(pagy.limit + 1).to_a # eager load limit + 1
32
25
  pagy.finalize(fetched.size) # finalize the pagy object
33
- fetched[0, pagy.items] # ignore eventual extra item
26
+ fetched[0, pagy.limit] # ignore eventual extra item
34
27
  end
35
28
  end
36
29
  Backend.prepend CountlessExtra
@@ -28,18 +28,18 @@ class Pagy # :nodoc:
28
28
  args.define_singleton_method(:method_missing) { |*a| args += a }
29
29
  end
30
30
  end
31
- alias_method Pagy::DEFAULT[:elasticsearch_rails_pagy_search], :pagy_elasticsearch_rails
31
+ alias_method DEFAULT[:elasticsearch_rails_pagy_search], :pagy_elasticsearch_rails
32
32
  end
33
33
  Pagy::ElasticsearchRails = ModelExtension
34
34
 
35
35
  # Additions for the Pagy class
36
36
  module PagyAddOn
37
37
  # Create a Pagy object from an Elasticsearch::Model::Response::Response object
38
- def new_from_elasticsearch_rails(response, vars = {})
39
- vars[:items] = response.search.options[:size] || 10
40
- vars[:page] = ((response.search.options[:from] || 0) / vars[:items]) + 1
38
+ def new_from_elasticsearch_rails(response, **vars)
39
+ vars[:limit] = response.search.options[:size] || 10
40
+ vars[:page] = ((response.search.options[:from] || 0) / vars[:limit]) + 1
41
41
  vars[:count] = ElasticsearchRailsExtra.total_count(response)
42
- new(vars)
42
+ Pagy.new(**vars)
43
43
  end
44
44
  end
45
45
  Pagy.extend PagyAddOn
@@ -48,19 +48,19 @@ class Pagy # :nodoc:
48
48
  module BackendAddOn
49
49
  private
50
50
 
51
- # Return Pagy object and items
52
- def pagy_elasticsearch_rails(pagy_search_args, vars = {})
51
+ # Return Pagy object and records
52
+ def pagy_elasticsearch_rails(pagy_search_args, **vars)
53
53
  model, query_or_payload,
54
54
  options, *called = pagy_search_args
55
55
  vars = pagy_elasticsearch_rails_get_vars(nil, vars)
56
- options[:size] = vars[:items]
57
- options[:from] = vars[:items] * (vars[:page] - 1)
56
+ options[:size] = vars[:limit]
57
+ options[:from] = vars[:limit] * ((vars[:page] || 1) - 1)
58
58
  response = model.send(DEFAULT[:elasticsearch_rails_search], query_or_payload, **options)
59
59
  vars[:count] = ElasticsearchRailsExtra.total_count(response)
60
60
 
61
- pagy = ::Pagy.new(vars)
61
+ pagy = ::Pagy.new(**vars)
62
62
  # with :last_page overflow we need to re-run the method in order to get the hits
63
- return pagy_elasticsearch_rails(pagy_search_args, vars.merge(page: pagy.page)) \
63
+ return pagy_elasticsearch_rails(pagy_search_args, **vars, page: pagy.page) \
64
64
  if defined?(::Pagy::OverflowExtra) && pagy.overflow? && pagy.vars[:overflow] == :last_page
65
65
 
66
66
  [pagy, called.empty? ? response : response.send(*called)]
@@ -69,10 +69,10 @@ class Pagy # :nodoc:
69
69
  # Sub-method called only by #pagy_elasticsearch_rails: here for easy customization of variables by overriding
70
70
  # the _collection argument is not available when the method is called
71
71
  def pagy_elasticsearch_rails_get_vars(_collection, vars)
72
- pagy_set_items_from_params(vars) if defined?(ItemsExtra)
73
- vars[:items] ||= DEFAULT[:items]
74
- vars[:page] ||= pagy_get_page(vars)
75
- vars
72
+ vars.tap do |v|
73
+ v[:page] ||= pagy_get_page(v)
74
+ v[:limit] ||= pagy_get_limit(v) || DEFAULT[:limit]
75
+ end
76
76
  end
77
77
  end
78
78
  Backend.prepend BackendAddOn