pagy 5.2.2 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5cb4539d68931db35f7f2f8c9d53d9e8a63541f402f23621b92a51e6a2e77386
4
- data.tar.gz: 4adbae6e3d5213c6628bec8a35a26c5e44ce09546fa6fdd74541d5bbf2feb63b
3
+ metadata.gz: 32d028f5c02fafb87cc0bb10f1b28ebf1f49b89babf4cfcf2099367b69cf88af
4
+ data.tar.gz: c5cf934095bfaed81c66afab017340855b8d7dcc1af5cc80c620e8fb62c70054
5
5
  SHA512:
6
- metadata.gz: 277754cc4da9b7bd70c173ad052c87658eda48c7a42ad28675e1b5ce3eafae09932bf3c2a1682715890bbb4039ce3484f0a1adc7f7223e6bd3702e3cfb9b0eab
7
- data.tar.gz: 9cb4995ece3b2fe8ab5625646cb1118080d27f52ce63af8efe5fd5178a6f8e8e77e9196a7f851780057fb315368622961f70eb65f808c460d011d5d890ff69bd
6
+ metadata.gz: 361df59b13de017f9bc99c7d4ed9c2316c265f0f50514fef3623c33f05095dbdbd8eee4be208bb420a3857ca4070dbebd75e6b30c0fc9ae827b1a7563e288aca
7
+ data.tar.gz: ba1ca8e50d010dea86cd05d65969f1815d9056e845dd0f23a17a78df6e59d7692619ae4c6899fd356bf14a8d0a5ff9dbd9ffb8ab545bad3653a10e8de0662823
data/lib/config/pagy.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Pagy initializer file (5.2.2)
3
+ # Pagy initializer file (5.4.0)
4
4
  # Customize only what you really need and notice that Pagy works also without any of the following lines.
5
5
  # Should you just cherry pick part of this file, please maintain the require-order of the extras
6
6
 
@@ -22,6 +22,7 @@
22
22
  # See https://ddnexus.github.io/pagy/api/pagy#other-variables
23
23
  # Pagy::DEFAULT[:size] = [1,4,4,1] # default
24
24
  # Pagy::DEFAULT[:page_param] = :page # default
25
+ # The :params can be also set as a lambda e.g ->(params){ params.exclude('useless').merge!('custom' => 'useful') }
25
26
  # Pagy::DEFAULT[:params] = {} # default
26
27
  # Pagy::DEFAULT[:fragment] = '#fragment' # example
27
28
  # Pagy::DEFAULT[:link_extra] = 'data-remote="true"' # example
@@ -42,14 +43,12 @@
42
43
  # Calendar extra: Paginate a collection by calendar Time unit (year, month, week or day)
43
44
  # See https://ddnexus.github.io/pagy/extras/calendar
44
45
  # require 'pagy/extras/calendar'
45
- # Pagy::DEFAULT[:local_minmax] = [] # Min and max local Time period must be set by the user (better not not as default)
46
- # Pagy::DEFAULT[:unit] = :month # Time unit allowed %i[year month week day]
47
- # Pagy::DEFAULT[:week_offset] = 0 # Day offset from Sunday (0: Sunday; 1: Monday;... 6: Saturday)
48
- # Pagy::DEFAULT[:order] = :asc # Time direction of pagination
49
- # Pagy::DEFAULT[:year_format] = '%Y' # strftime format for :year unit
50
- # Pagy::DEFAULT[:month_format] = '%Y-%m' # strftime format for :month unit
51
- # Pagy::DEFAULT[:week_format] = '%Y-%W' # strftime format for :week unit
52
- # Pagy::DEFAULT[:day_format] = '%Y-%m-%d' # strftime format for :day unit
46
+ # DEFAULT[:year_format] = '%Y' # strftime format for :year unit
47
+ # DEFAULT[:month_format] = '%Y-%m' # strftime format for :month unit
48
+ # DEFAULT[:week_format] = '%Y-%W' # strftime format for :week unit
49
+ # DEFAULT[:day_format] = '%Y-%m-%d' # strftime format for :day unit
50
+ # DEFAULT[:week_offset] = 0 # Day offset from Sunday (0: Sunday; 1: Monday;... 6: Saturday)
51
+ # DEFAULT[:time_order] = :asc # Time direction of pagination
53
52
 
54
53
  # Countless extra: Paginate without any count, saving one query per rendering
55
54
  # See https://ddnexus.github.io/pagy/extras/countless
@@ -1,9 +1,11 @@
1
1
  // See the Pagy documentation: https://ddnexus.github.io/pagy/extras#javascript
2
2
 
3
+ // This code should be OK also with very old browsers
4
+
3
5
  // Container of the whole pagy stuff
4
6
  function Pagy(){}
5
7
 
6
- Pagy.version = '5.2.2'
8
+ Pagy.version = '5.4.0'
7
9
 
8
10
  // Used by the waitForMe function
9
11
  Pagy.delay = 100
@@ -23,10 +25,11 @@ Pagy.init =
23
25
 
24
26
  // Power the pagy*_nav_js helpers
25
27
  Pagy.nav =
26
- function(pagyEl, tags, sequels, trimParam) {
27
- var lastWidth,
28
- pageREg = new RegExp(/__pagy_page__/g),
29
- widths = []
28
+ function(pagyEl, tags, sequels, label_sequels, trimParam ) {
29
+ label_sequels = (label_sequels === null) ? sequels : label_sequels
30
+ var widths = [], lastWidth,
31
+ fill = function(string, item, label) { return string.replace(/__pagy_page__/g, item)
32
+ .replace(/__pagy_label__/g, label) }
30
33
  for (var width in sequels) {
31
34
  if (sequels.hasOwnProperty(width)) { widths.push(parseInt(width, 10)) }
32
35
  }
@@ -40,13 +43,15 @@ Pagy.nav =
40
43
  }
41
44
  if (width !== lastWidth) {
42
45
  var html = tags.before,
43
- series = sequels[width]
46
+ series = sequels[width],
47
+ labels = label_sequels[width]
44
48
  for (i = 0, len = series.length; i < len; i++) {
45
- var item = series[i]
46
- if (typeof(trimParam) === 'string' && item === 1) { html += Pagy.trim(tags.link.replace(pageREg, item), trimParam) }
47
- else if (typeof(item) === 'number') { html += tags.link.replace(pageREg, item) }
49
+ var item = series[i],
50
+ label = labels[i]
51
+ if (typeof(trimParam) === 'string' && item === 1) { html += Pagy.trim(fill(tags.link, item, label), trimParam) }
52
+ else if (typeof(item) === 'number') { html += fill(tags.link, item, label) }
48
53
  else if (item === 'gap') { html += tags.gap }
49
- else if (typeof(item) === 'string') { html += tags.active.replace(pageREg, item) }
54
+ else if (typeof(item) === 'string') { html += fill(tags.active, item, label) }
50
55
  }
51
56
  html += tags.after
52
57
  this.insertAdjacentHTML('afterbegin', html)
data/lib/pagy/calendar.rb CHANGED
@@ -5,144 +5,183 @@ require 'pagy'
5
5
  require 'date'
6
6
 
7
7
  class Pagy # :nodoc:
8
- DEFAULT[:local_minmax] = [] # Min and max Time period must be set by the user
9
- DEFAULT[:unit] = :month # Time unit allowed %i[year month week day]
10
- DEFAULT[:week_offset] = 0 # Day offset from Sunday (0: Sunday; 1: Monday;... 6: Saturday)
11
- DEFAULT[:order] = :asc # Time direction of pagination
12
8
  DEFAULT[:year_format] = '%Y' # strftime format for :year unit
13
9
  DEFAULT[:month_format] = '%Y-%m' # strftime format for :month unit
14
10
  DEFAULT[:week_format] = '%Y-%W' # strftime format for :week unit
15
11
  DEFAULT[:day_format] = '%Y-%m-%d' # strftime format for :day unit
12
+ DEFAULT[:week_offset] = 0 # Day offset from Sunday (0: Sunday; 1: Monday;... 6: Saturday)
13
+ DEFAULT[:time_order] = :asc # Time direction of pagination
16
14
 
17
- # Paginate a Time period by units (year, month, week or day)
15
+ # Base class for time units subclasses (Year, Month, Week, Day)
18
16
  class Calendar < Pagy
19
- attr_reader :utc_from, :utc_to, :unit, :week_offset, :order
20
- attr_writer :count, :in
17
+ DAY = 60 * 60 * 24
18
+ WEEK = DAY * 7
19
+
20
+ attr_reader :utc_from, :utc_to, :time_order
21
+
22
+ # Create a subclass instance
23
+ def self.create(unit, vars)
24
+ raise InternalError, "unit must be in #{UNITS.keys.inspect}; got #{unit}" unless UNITS.key?(unit)
25
+
26
+ UNITS[unit].new(vars)
27
+ end
21
28
 
22
29
  # Merge and validate the options, do some simple arithmetic and set a few instance variables
23
30
  def initialize(vars) # rubocop:disable Lint/MissingSuper
31
+ raise InternalError, 'Pagy::Calendar is a base class; use one of its subclasses.' if instance_of?(Pagy::Calendar)
32
+
24
33
  normalize_vars(vars)
25
- setup_vars(page: 1, week_offset: 0)
34
+ setup_vars(page: 1)
26
35
  setup_unit_vars
36
+ setup_params_var
27
37
  raise OverflowError.new(self, :page, "in 1..#{@last}", @page) if @page > @last
28
38
 
29
39
  @prev = (@page - 1 unless @page == 1)
30
40
  @next = @page == @last ? (1 if @vars[:cycle]) : @page + 1
31
41
  end
32
42
 
33
- # Generate a label for each page, with the specific `Time` period it refers to
34
- def page_label(num = @page, format = nil)
35
- snap = snap(num.to_i)
36
- format ||= @vars[:"#{@unit}_format"]
37
- case @unit
38
- when :year then new_time(@initial.year + snap)
39
- when :month then bump_month(@initial, snap)
40
- when :week then @initial + (snap * WEEK)
41
- when :day then @initial + (snap * DAY)
42
- else raise InternalError, "expected @unit to be in [:year, :month, :week, :day]; got #{@unit.inspect}"
43
- end.strftime(format)
43
+ # The label for the current page (it can pass along the I18n gem opts when it's used with the i18n extra)
44
+ def label(**opts)
45
+ label_for(@page, **opts)
44
46
  end
45
47
 
46
- def current_page_label(format = nil)
47
- page_label(@page, format)
48
+ # Return the minmax of the current page/unit (used by the extra for the next level minmax)
49
+ def current_unit_minmax
50
+ [@utc_from.getlocal(@utc_offset), @utc_to.getlocal(@utc_offset)]
48
51
  end
49
52
 
50
- DAY = 60 * 60 * 24
51
- WEEK = DAY * 7
52
-
53
53
  protected
54
54
 
55
- def setup_unit_vars
56
- (units = %i[year month week day]).each do |unit|
57
- raise VariableError.new(self, :format, 'to be a strftime format', @vars[:"#{unit}_format"]) \
58
- unless @vars[:"#{unit}_format"].is_a?(String)
59
- end
60
- raise VariableError.new(self, :unit, "to be in #{units.inspect}", @unit) \
61
- unless units.include?(@unit = @vars[:unit])
62
- raise VariableError.new(self, :order, 'to be in [:asc, :desc]', @order) \
63
- unless %i[asc desc].include?(@order = @vars[:order])
64
-
65
- min, max = @vars[:local_minmax]
66
- raise VariableError.new(self, :local_minmax, 'to be a an Array of min and max local Time instances', @vars[:local_minmax]) \
67
- unless min.is_a?(Time) && max.is_a?(Time) && !min.utc? && !min.utc? && min <= max \
55
+ def setup_unit_vars(format)
56
+ raise VariableError.new(self, format, 'to be a strftime format', @vars[format]) unless @vars[format].is_a?(String)
57
+ raise VariableError.new(self, :time_order, 'to be in [:asc, :desc]', @time_order) \
58
+ unless %i[asc desc].include?(@time_order = @vars[:time_order])
59
+
60
+ min, max = @vars[:minmax]
61
+ raise VariableError.new(self, :minmax, 'to be a an Array of min and max local Time instances', @vars[:minmax]) \
62
+ unless min.is_a?(Time) && max.is_a?(Time) && !min.utc? && !max.utc? && min <= max \
68
63
  && (@utc_offset = min.utc_offset) == max.utc_offset
69
64
 
70
- send :"setup_#{@unit}_vars", min, max
65
+ [min, max]
71
66
  end
72
67
 
73
- # IMPORTANT: all the Time objects created and passed as arguments MUST be local!
74
-
75
- # @initial: beginning of the first day of the period that encloses the min local time
76
- # @final: beginning of the first day of the NEXT period AFTER the period that encloses the max local time
77
- # @utc_from: beginning of the first day of the period of the current page as UTC time
78
- # @utc_to: beginning of the first day of the NEXT period AFTER the current page as UTC time
79
-
80
- # Setup the calendar vars when the unit is :year
81
- def setup_year_vars(min, max)
82
- @initial = new_time(min.year)
83
- @final = new_time(max.year + 1)
84
- @pages = @last = @final.year - @initial.year
85
- @utc_from = new_time(@initial.year + snap).utc
86
- @utc_to = new_time(@initial.year + snap + 1).utc
68
+ # Apply the strftime format to the time (overridden by the i18n extra when localization is required)
69
+ def localize(time, opts)
70
+ time.strftime(opts[:format])
87
71
  end
88
72
 
89
- # Setup the calendar vars when the unit is :month
90
- def setup_month_vars(min, max)
91
- @initial = new_time(min.year, min.month)
92
- @final = bump_month(max)
93
- @pages = @last = months(@final) - months(@initial)
94
- @utc_from = bump_month(@initial, snap).utc
95
- @utc_to = bump_month(@initial, snap + 1).utc
73
+ # Simple trick to snap the page into its ordered position, without actually reordering anything in the internal structure
74
+ def snap(page = @page)
75
+ @time_order == :asc ? page - 1 : @pages - page
96
76
  end
97
77
 
98
- # Setup the calendar vars when the unit is :week
99
- def setup_week_vars(min, max)
100
- @initial = week_start(min)
101
- @final = week_start(max) + WEEK
102
- @pages = @last = (@final - @initial).to_i / WEEK
103
- @utc_from = (@initial + (snap * WEEK)).utc
104
- @utc_to = @utc_from + WEEK
78
+ # Create a new local time at the beginning of the day
79
+ def new_time(year, month = 1, day = 1)
80
+ Time.new(year, month, day, 0, 0, 0, @utc_offset)
105
81
  end
106
82
 
107
- # Setup the calendar vars when the unit is :day
108
- def setup_day_vars(min, max)
109
- @initial = new_time(min.year, min.month, min.day)
110
- @final = new_time(max.year, max.month, max.day) + DAY
111
- @pages = @last = (@final - @initial).to_i / DAY
112
- @utc_from = (@initial + (snap * DAY)).utc
113
- @utc_to = @utc_from + DAY
83
+ # Calendar year subclass
84
+ class Year < Calendar
85
+ # Setup the calendar vars when the unit is :year
86
+ def setup_unit_vars
87
+ min, max = super(:year_format)
88
+ @initial = new_time(min.year)
89
+ @final = new_time(max.year + 1)
90
+ @pages = @last = @final.year - @initial.year
91
+ @utc_from = new_time(@initial.year + snap).utc
92
+ @utc_to = new_time(@initial.year + snap + 1).utc
93
+ end
94
+
95
+ # Generate a label for each page (it can pass along the I18n gem opts when it's used with the i18n extra)
96
+ def label_for(page, **opts)
97
+ opts[:format] ||= @vars[:year_format]
98
+ localize(new_time(@initial.year + snap(page.to_i)), **opts)
99
+ end
114
100
  end
115
101
 
116
- private
102
+ # Calendar month subclass
103
+ class Month < Calendar
104
+ # Setup the calendar vars when the unit is :month
105
+ def setup_unit_vars
106
+ min, max = super(:month_format)
107
+ @initial = new_time(min.year, min.month)
108
+ @final = bump_month(max)
109
+ @pages = @last = months(@final) - months(@initial)
110
+ @utc_from = bump_month(@initial, snap).utc
111
+ @utc_to = bump_month(@initial, snap + 1).utc
112
+ end
117
113
 
118
- # Simple trick to snap the page into its ordered position,
119
- # without actually reordering anything in the internal structure
120
- def snap(page = @page)
121
- @order == :asc ? page - 1 : @pages - page
122
- end
114
+ # Generate a label for each page (it can pass along the I18n gem opts when it's used with the i18n extra)
115
+ def label_for(page, **opts)
116
+ opts[:format] ||= @vars[:month_format]
117
+ localize(bump_month(@initial, snap(page.to_i)), **opts)
118
+ end
123
119
 
124
- # Create a new local time at the beginning of the day
125
- def new_time(year, month = 1, day = 1)
126
- Time.new(year, month, day, 0, 0, 0, @utc_offset)
127
- end
120
+ private
121
+
122
+ # Months in local time
123
+ def months(time)
124
+ (time.year * 12) + time.month
125
+ end
128
126
 
129
- # Months in local time
130
- def months(time)
131
- (time.year * 12) + time.month
127
+ # Add 1 or more months to local time
128
+ def bump_month(time, months = 1)
129
+ months += months(time)
130
+ year = months / 12
131
+ month = months % 12
132
+ month.zero? ? new_time(year - 1, 12) : new_time(year, month)
133
+ end
132
134
  end
133
135
 
134
- # Add 1 or more months to local time
135
- def bump_month(time, months = 1)
136
- months += months(time)
137
- year = months / 12
138
- month = months % 12
139
- month.zero? ? new_time(year - 1, 12) : new_time(year, month)
136
+ # Calendar week subclass
137
+ class Week < Calendar
138
+ attr_reader :week_offset
139
+
140
+ # Setup the calendar vars when the unit is :week
141
+ def setup_unit_vars
142
+ setup_vars(week_offset: 0)
143
+ min, max = super(:week_format)
144
+ @initial = week_start(min)
145
+ @final = week_start(max) + WEEK
146
+ @pages = @last = (@final - @initial).to_i / WEEK
147
+ @utc_from = (@initial + (snap * WEEK)).utc
148
+ @utc_to = @utc_from + WEEK
149
+ end
150
+
151
+ # Generate a label for each page (it can pass along the I18n gem opts when it's used with the i18n extra)
152
+ def label_for(page, **opts)
153
+ opts[:format] ||= @vars[:week_format]
154
+ localize(@initial + (snap(page.to_i) * WEEK), **opts)
155
+ end
156
+
157
+ private
158
+
159
+ # Return the start of the week for local time
160
+ def week_start(time)
161
+ start = time - (((time.wday - @week_offset) * DAY) % WEEK)
162
+ new_time(start.year, start.month, start.day)
163
+ end
140
164
  end
141
165
 
142
- # Return the start of the week for local time
143
- def week_start(time)
144
- start = time - (((time.wday - @week_offset) * DAY) % WEEK)
145
- new_time(start.year, start.month, start.day)
166
+ # Calendar day subclass
167
+ class Day < Calendar
168
+ # Setup the calendar vars when the unit is :day
169
+ def setup_unit_vars
170
+ min, max = super(:day_format)
171
+ @initial = new_time(min.year, min.month, min.day)
172
+ @final = new_time(max.year, max.month, max.day) + DAY
173
+ @pages = @last = (@final - @initial).to_i / DAY
174
+ @utc_from = (@initial + (snap * DAY)).utc
175
+ @utc_to = @utc_from + DAY
176
+ end
177
+
178
+ # Generate a label for each page (it can pass along the I18n gem opts when it's used with the i18n extra)
179
+ def label_for(page, **opts)
180
+ opts[:format] ||= @vars[:day_format]
181
+ localize(@initial + (snap(page.to_i) * DAY), **opts)
182
+ end
146
183
  end
184
+ # After all the subclasses are defined
185
+ UNITS = { year: Year, month: Month, week: Week, day: Day }.freeze
147
186
  end
148
187
  end
@@ -11,6 +11,7 @@ class Pagy
11
11
  normalize_vars(vars)
12
12
  setup_vars(page: 1, outset: 0)
13
13
  setup_items_var
14
+ setup_params_var
14
15
  @offset = (@items * (@page - 1)) + @outset
15
16
  end
16
17
 
@@ -29,7 +30,7 @@ class Pagy
29
30
 
30
31
  # Override the original series.
31
32
  # Return nil if :countless_minimal is enabled
32
- def series(_size = @vars[:size])
33
+ def series(*)
33
34
  super unless @vars[:countless_minimal]
34
35
  end
35
36
  end
@@ -1,20 +1,20 @@
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/shared'
4
+ require 'pagy/extras/frontend_helpers'
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 BootstrapExtra
10
10
  # Pagination for bootstrap: it returns the html with the series of links to the pages
11
- def pagy_bootstrap_nav(pagy, pagy_id: nil, link_extra: '')
11
+ def pagy_bootstrap_nav(pagy, pagy_id: nil, link_extra: '', **vars)
12
12
  p_id = %( id="#{pagy_id}") if pagy_id
13
13
  link = pagy_link_proc(pagy, link_extra: %(class="page-link" #{link_extra}))
14
14
 
15
15
  html = +%(<nav#{p_id} class="pagy-bootstrap-nav" aria-label="pager"><ul class="pagination">)
16
16
  html << pagy_bootstrap_prev_html(pagy, link)
17
- 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]
18
18
  html << case item
19
19
  when Integer
20
20
  %(<li class="page-item">#{link.call item}</li>)
@@ -30,17 +30,17 @@ class Pagy # :nodoc:
30
30
  end
31
31
 
32
32
  # Javascript pagination for bootstrap: it returns a nav and a JSON tag used by the Pagy.nav javascript
33
- def pagy_bootstrap_nav_js(pagy, pagy_id: nil, link_extra: '', steps: nil)
33
+ def pagy_bootstrap_nav_js(pagy, pagy_id: nil, link_extra: '', **vars)
34
34
  p_id = %( id="#{pagy_id}") if pagy_id
35
35
  link = pagy_link_proc(pagy, link_extra: %(class="page-link" #{link_extra}))
36
36
  tags = { 'before' => %(<ul class="pagination">#{pagy_bootstrap_prev_html pagy, link}),
37
- 'link' => %(<li class="page-item">#{mark = link.call(PAGE_PLACEHOLDER)}</li>),
37
+ 'link' => %(<li class="page-item">#{mark = link.call(PAGE_PLACEHOLDER, LABEL_PLACEHOLDER)}</li>),
38
38
  'active' => %(<li class="page-item active">#{mark}</li>),
39
39
  'gap' => %(<li class="page-item gap disabled"><a href="#" class="page-link">#{pagy_t 'pagy.nav.gap'}</a></li>),
40
40
  'after' => %(#{pagy_bootstrap_next_html pagy, link}</ul>) }
41
41
 
42
42
  %(<nav#{p_id} class="pagy-njs pagy-bootstrap-nav-js" aria-label="pager" #{
43
- pagy_json_attr(pagy, :nav, tags, pagy.sequels(steps))}></nav>)
43
+ pagy_json_attr(pagy, :nav, tags, (sequels = pagy.sequels(**vars)), pagy.label_sequels(sequels))}></nav>)
44
44
  end
45
45
 
46
46
  # Javascript combo pagination for bootstrap: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
@@ -1,26 +1,26 @@
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/shared'
4
+ require 'pagy/extras/frontend_helpers'
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, pagy_id: nil, link_extra: '')
11
+ def pagy_bulma_nav(pagy, pagy_id: nil, link_extra: '', **vars)
12
12
  p_id = %( id="#{pagy_id}") if pagy_id
13
13
  link = pagy_link_proc(pagy, link_extra: link_extra)
14
14
 
15
15
  html = +%(<nav#{p_id} class="pagy-bulma-nav pagination is-centered" aria-label="pagination">)
16
16
  html << pagy_bulma_prev_next_html(pagy, link)
17
17
  html << %(<ul class="pagination-list">)
18
- 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]
19
19
  html << case item
20
20
  when Integer
21
- %(<li>#{link.call item, item, %(class="pagination-link" aria-label="goto page #{item}")}</li>)
21
+ %(<li>#{link.call item, pagy.label_for(item), %(class="pagination-link" aria-label="goto page #{item}")}</li>)
22
22
  when String
23
- %(<li>#{link.call item, item,
23
+ %(<li>#{link.call item, pagy.label_for(item),
24
24
  %(class="pagination-link is-current" aria-label="page #{item}" aria-current="page")}</li>)
25
25
  when :gap
26
26
  %(<li><span class="pagination-ellipsis">#{pagy_t 'pagy.nav.gap'}</span></li>)
@@ -30,21 +30,20 @@ class Pagy # :nodoc:
30
30
  html << %(</ul></nav>)
31
31
  end
32
32
 
33
- def pagy_bulma_nav_js(pagy, pagy_id: nil, link_extra: '', steps: nil)
33
+ def pagy_bulma_nav_js(pagy, pagy_id: nil, link_extra: '', **vars)
34
34
  p_id = %( id="#{pagy_id}") if pagy_id
35
35
  link = pagy_link_proc(pagy, link_extra: link_extra)
36
36
  tags = { 'before' => %(#{pagy_bulma_prev_next_html(pagy, link)}<ul class="pagination-list">),
37
- 'link' => %(<li>#{link.call PAGE_PLACEHOLDER, PAGE_PLACEHOLDER,
37
+ 'link' => %(<li>#{link.call PAGE_PLACEHOLDER, LABEL_PLACEHOLDER,
38
38
  %(class="pagination-link" aria-label="goto page #{PAGE_PLACEHOLDER}")}</li>),
39
- 'active' => %(<li>#{link.call PAGE_PLACEHOLDER, PAGE_PLACEHOLDER,
39
+ 'active' => %(<li>#{link.call PAGE_PLACEHOLDER, LABEL_PLACEHOLDER,
40
40
  %(class="pagination-link is-current" aria-current="page" aria-label="page #{
41
41
  PAGE_PLACEHOLDER}")}</li>),
42
42
  'gap' => %(<li><span class="pagination-ellipsis">#{pagy_t 'pagy.nav.gap'}</span></li>),
43
43
  'after' => '</ul>' }
44
44
 
45
- %(<nav#{p_id} class="pagy-njs pagy-bulma-nav-js pagination is-centered" aria-label="pagination" #{pagy_json_attr(
46
- pagy, :nav, tags, pagy.sequels(steps)
47
- )}></nav>)
45
+ %(<nav#{p_id} class="pagy-njs pagy-bulma-nav-js pagination is-centered" aria-label="pagination" #{
46
+ pagy_json_attr(pagy, :nav, tags, (sequels = pagy.sequels(**vars)), pagy.label_sequels(sequels))}></nav>)
48
47
  end
49
48
 
50
49
  # Javascript combo pagination for Bulma: it returns a nav and a JSON tag used by the Pagy.combo_nav javascript
@@ -4,43 +4,74 @@
4
4
  require 'pagy/calendar'
5
5
 
6
6
  class Pagy # :nodoc:
7
- # Paginate based on calendar periods (year month week day)
7
+ # Paginate based on calendar periods (year month week day) plus the regular pagination
8
8
  module CalendarExtra
9
9
  # Additions for the Backend module
10
10
  module Backend
11
+ CONF_KEYS = %i[year month week day pagy skip].freeze
12
+
11
13
  private
12
14
 
13
- # Return Pagy object and items
14
- def pagy_calendar(collection, vars = {})
15
- pagy = Calendar.new(pagy_calendar_get_vars(collection, vars))
16
- [pagy, pagy_calendar_get_items(collection, pagy)]
15
+ # Take a collection and a conf Hash with keys in [:year, :month: week, :day, :pagy] and Hash values of pagy variables
16
+ # Return a hash with 3 items:
17
+ # 0. Array of pagy calendar unit objects
18
+ # 1. Pagy object
19
+ # 2. Array of results
20
+ def pagy_calendar(collection, conf)
21
+ unless conf.is_a?(Hash) && (conf.keys - CONF_KEYS).empty? && conf.all? { |k, v| v.is_a?(Hash) || k == :skip }
22
+ raise ArgumentError, "keys must be in #{CONF_KEYS.inspect} and object values must be Hashes; got #{conf.inspect}"
23
+ end
24
+
25
+ conf[:pagy] = {} unless conf[:pagy] # use default Pagy object when omitted
26
+ calendar, collection = pagy_setup_calendar(collection, conf) unless conf[:skip]
27
+ pagy, result = send(conf[:pagy][:backend] || :pagy, collection, conf[:pagy]) # use backend: :pagy when omitted
28
+ [calendar, pagy, result]
17
29
  end
18
30
 
19
- # Sub-method called only by #pagy_calendar: here for easy customization of variables by overriding.
20
- # You may want to override it in order to implement the dynamic set of the :minmax variable.
21
- def pagy_calendar_get_vars(_collection, vars)
22
- # vars[:minmax] ||= your_own_method_to_get_the_period_from(collection)
23
- vars[:page] ||= params[vars[:page_param] || DEFAULT[:page_param]]
24
- vars
31
+ # Setup the calendar objects and return them with the filtered collection
32
+ def pagy_setup_calendar(collection, conf)
33
+ units = Calendar::UNITS.keys & conf.keys
34
+ page_param = conf[:pagy][:page_param] || DEFAULT[:page_param]
35
+ units.each do |unit| # set all the :page_param vars for later deletion
36
+ unit_page_param = :"#{unit}_#{page_param}"
37
+ conf[unit][:page_param] = unit_page_param
38
+ conf[unit][:page] = params[unit_page_param]
39
+ end
40
+ calendar = {}
41
+ last_calendar = nil
42
+ last_minmax = minmax = pagy_calendar_minmax(collection)
43
+ units.each_with_index do |unit, index|
44
+ params_to_delete = units[(index + 1), units.size].map { |sub| conf[sub][:page_param] } + [page_param]
45
+ conf[unit][:params] = lambda do |params| # delete page_param from the sub-units
46
+ params_to_delete.each { |p| params.delete(p.to_s) } # except implemented after 2.5
47
+ params
48
+ end
49
+ conf[unit][:minmax] = [[minmax.first, last_minmax.first].max, [minmax.last, last_minmax.last].min]
50
+ calendar[unit] = last_calendar = Calendar.create(unit, conf[unit])
51
+ last_minmax = calendar[unit].current_unit_minmax # set the minmax for the next unit
52
+ end
53
+ filtered = pagy_calendar_filtered(collection, last_calendar.utc_from, last_calendar.utc_to)
54
+ [calendar, filtered]
25
55
  end
26
56
 
27
- # This method should be implemented in the application and should return the records
28
- # for the unit by selecting the records with DateTime from pagy.from to pagy.to
29
- def pagy_calendar_get_items(_collection, _pagy)
30
- # collection.your_own_method_to_get_the_items_with(pagy.from, pagy.to)
31
- raise NoMethodError, 'The pagy_calendar_get_items method must be implemented in the application and must return ' \
32
- 'the items for the unit by selecting the records with Time from pagy.from to pagy.to'
57
+ # This method must be implemented by the application.
58
+ # It must return an Array with the minimum and maximum Time objects from the collection,
59
+ # converted to the local time of the user
60
+ def pagy_calendar_minmax(*)
61
+ # collection.your_own_method_to_get_the_minmax
62
+ raise NoMethodError, 'the pagy_calendar_minmax method must be implemented by the application and must return ' \
63
+ 'an Array with the minimum and maximum local Time objects of the collection'
33
64
  end
34
- end
35
65
 
36
- # Additions for the Frontend module
37
- module Frontend
38
- # Change the text shown in the nav bar links to the actual unit of each page.
39
- def pagy_labeler(pagy, num)
40
- pagy.is_a?(Calendar) ? pagy.page_label(num) : num
66
+ # This method must be implemented by the application.
67
+ # It receives the main collection argument and must return a filtered version of it.
68
+ # The filter logic must be equivalent to {utc_time >= pagy.utc_from && utc_time < pagy.utc_to}
69
+ def pagy_calendar_filtered(*)
70
+ # collection.your_own_method_to_filter_with(pagy.utc_from, pagy.utc_to)
71
+ raise NoMethodError, 'the pagy_calendar_filtered method must be implemented by the application and must return the ' \
72
+ 'collection filtered by a logic equivalent to {utc_time >= pagy.utc_from && utc_time < pagy.utc_to}'
41
73
  end
42
74
  end
43
75
  end
44
76
  Backend.prepend CalendarExtra::Backend
45
- Frontend.prepend CalendarExtra::Frontend
46
77
  end