pagy 8.4.5 → 8.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/pagy/calendar.rb CHANGED
@@ -1,122 +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
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
- raise OverflowError.new(self, :page, "in 1..#{@last}", @page) if @page > @last
32
-
33
- @prev = (@page - 1 unless @page == 1)
34
- @next = @page == @last ? (1 if @vars[:cycle]) : @page + 1
35
- end
36
-
37
- # The label for the current page (it can pass along the I18n gem opts when it's used with the i18n extra)
38
- def label(opts = {})
39
- label_for(@page, opts)
40
- end
41
-
42
- # The label for any page (it can pass along the I18n gem opts when it's used with the i18n extra)
43
- def label_for(page, opts = {})
44
- opts[:format] ||= @vars[:format]
45
- localize(starting_time_for(page.to_i), opts) # page could be a string
46
- end
47
-
48
- protected
16
+ class << self
17
+ private
49
18
 
50
- # The page that includes time
51
- # In case of out of range time, the :fit_time option avoids the outOfRangeError
52
- # and returns the closest page to the passed time argument (first or last page)
53
- def page_at(time, **opts)
54
- fit_time = time
55
- fit_final = @final - 1
56
- unless time.between?(@initial, fit_final)
57
- 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)
58
22
 
59
- if time < @final
60
- fit_time = @initial
61
- ordinal = 'first'
62
- else
63
- fit_time = fit_final
64
- ordinal = 'last'
65
- end
66
- 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)
67
26
  end
68
- offset = page_offset_at(fit_time) # offset starts from 0
69
- @order == :asc ? offset + 1 : @last - offset
70
- end
71
27
 
72
- # Base class method for the setup of the unit variables (subclasses must implement it and call super)
73
- def setup_unit_vars
74
- raise VariableError.new(self, :format, 'to be a strftime format', @vars[:format]) unless @vars[:format].is_a?(String)
75
- raise VariableError.new(self, :order, 'to be in [:asc, :desc]', @order) \
76
- unless %i[asc desc].include?(@order = @vars[:order])
77
-
78
- @starting, @ending = @vars[:period]
79
- raise VariableError.new(self, :period, 'to be a an Array of min and max TimeWithZone instances', @vars[:period]) \
80
- unless @starting.is_a?(ActiveSupport::TimeWithZone) \
81
- && @ending.is_a?(ActiveSupport::TimeWithZone) && @starting <= @ending
82
- end
83
-
84
- # Apply the strftime format to the time (overridden by the i18n extra when localization is required)
85
- def localize(time, opts)
86
- time.strftime(opts[:format])
87
- end
88
-
89
- # Number of time units to offset from the @initial time, in order to get the ordered starting time for the page.
90
- # Used in starting_time_for(page) where page starts from 1 (e.g. page to starting_time means subtracting 1)
91
- def time_offset_for(page)
92
- @order == :asc ? page - 1 : @last - page
93
- end
94
-
95
- # Period of the active page (used internally for nested units)
96
- def active_period
97
- [[@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
98
32
  end
99
33
 
100
- # :nocov:
101
- # This method must be implemented by the unit subclass
102
- def starting_time_for(*)
103
- 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
104
37
  end
105
38
 
106
- # This method must be implemented by the unit subclass
107
- def page_offset_at(*)
108
- 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]
109
64
  end
110
- # :nocov:
111
-
112
- class << self
113
- # Create a subclass instance by unit name (internal use)
114
- def create(unit, vars)
115
- raise InternalError, "unit must be in #{UNITS.inspect}; got #{unit}" unless UNITS.include?(unit)
116
65
 
117
- name = unit.to_s
118
- name[0] = name[0].capitalize
119
- 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])
120
77
  end
121
78
  end
122
79
  end
@@ -3,7 +3,7 @@
3
3
 
4
4
  require_relative '../pagy'
5
5
 
6
- class Pagy
6
+ class Pagy # :nodoc:
7
7
  # No need to know the count to paginate
8
8
  class Countless < Pagy
9
9
  # Merge and validate the options, do some simple arithmetic and set a few instance variables
@@ -29,11 +29,14 @@ class Pagy
29
29
  @next = @page == @last ? (1 if @vars[:cycle]) : @page + 1
30
30
  self
31
31
  end
32
+ end
32
33
 
34
+ module SeriesOverride # :nodoc:
33
35
  # Override the original series.
34
36
  # Return nil if :countless_minimal is enabled
35
37
  def series(*, **)
36
38
  super unless @vars[:countless_minimal]
37
39
  end
38
40
  end
41
+ prepend SeriesOverride
39
42
  end
@@ -2,7 +2,6 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require_relative '../calendar'
5
- require_relative '../calendar/helper'
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,8 +19,13 @@ 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
30
  pagy, results = send(conf[:pagy][:backend] || :pagy, collection, conf[:pagy]) # use backend: :pagy when omitted
27
31
  [calendar, pagy, results]
@@ -40,6 +44,32 @@ 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)
51
+ return super unless (counts = pagy.vars[:counts])
52
+
53
+ a_string = pagy.vars[:anchor_string]
54
+ a_string = %( #{a_string}) if a_string
55
+ left, right = %(<a#{a_string} href="#{pagy_url_for(pagy, PAGE_TOKEN)}").split(PAGE_TOKEN, 2)
56
+ # lambda used by all the helpers
57
+ lambda do |page, text = pagy.label_for(page), classes: nil, aria_label: nil|
58
+ count = counts[page - 1]
59
+ item_name = pagy_t('pagy.item_name', count:)
60
+ if count.zero?
61
+ classes = "#{classes && (classes + ' ')}empty-page"
62
+ title = %( title="#{pagy_t('pagy.info.no_items', item_name:, count:)}")
63
+ else
64
+ title = %( title="#{pagy_t('pagy.info.single_page', item_name:, count:)}")
65
+ end
66
+ classes = %( class="#{classes}") if classes
67
+ aria_label = %( aria-label="#{aria_label}") if aria_label
68
+ %(#{left}#{page}#{right}#{title}#{classes}#{aria_label}>#{text}</a>)
69
+ end
70
+ end
71
+ end
72
+
43
73
  # Additions for the Frontend module
44
74
  module UrlHelperAddOn
45
75
  # Return the url for the calendar page at time
@@ -49,5 +79,5 @@ class Pagy # :nodoc:
49
79
  end
50
80
  end
51
81
  Backend.prepend CalendarExtra::BackendAddOn, CalendarExtra::UrlHelperAddOn
52
- Frontend.prepend CalendarExtra::UrlHelperAddOn
82
+ Frontend.prepend CalendarExtra::UrlHelperAddOn, CalendarExtra::FrontendOverride
53
83
  end
@@ -19,7 +19,7 @@ class Pagy # :nodoc:
19
19
  end
20
20
  end
21
21
  end
22
- Calendar.prepend I18nExtra::CalendarOverride if defined?(Calendar)
22
+ Calendar::Unit.prepend I18nExtra::CalendarOverride if defined?(Calendar::Unit)
23
23
 
24
24
  # Add the pagy locales to the I18n.load_path
25
25
  ::I18n.load_path += Dir[Pagy.root.join('locales', '*.yml')]
@@ -42,7 +42,7 @@ class Pagy # :nodoc:
42
42
  end
43
43
  end
44
44
  end
45
- Calendar.prepend CalendarOverride if defined?(Calendar)
45
+ Calendar::Unit.prepend CalendarOverride if defined?(Calendar::Unit)
46
46
 
47
47
  # Additions for the Frontend
48
48
  module FrontendAddOn
@@ -17,7 +17,11 @@ class Pagy # :nodoc:
17
17
  def pagy_metadata(pagy, absolute: nil)
18
18
  scaffold_url = pagy_url_for(pagy, PAGE_TOKEN, absolute:)
19
19
  {}.tap do |metadata|
20
- keys = defined?(Calendar) && pagy.is_a?(Calendar) ? pagy.vars[:metadata] - %i[count items] : pagy.vars[:metadata]
20
+ keys = if defined?(Calendar::Unit) && pagy.is_a?(Calendar::Unit)
21
+ pagy.vars[:metadata] - %i[count items]
22
+ else
23
+ pagy.vars[:metadata]
24
+ end
21
25
  keys.each do |key|
22
26
  metadata[key] = case key
23
27
  when :scaffold_url then scaffold_url
@@ -28,7 +28,8 @@ class Pagy # :nodoc:
28
28
  @vars[:page] = requested_page # restore the requested page
29
29
  when :empty_page
30
30
  @offset = @items = @in = @from = @to = 0 # vars relative to the actual page
31
- if defined?(Calendar) && is_a?(Calendar) # only for Calendar instances
31
+ if defined?(Calendar::Unit) \
32
+ && is_a?(Calendar::Unit) # only for Calendar::Units instances
32
33
  edge = @order == :asc ? @final : @initial # get the edge of the overflow side (neat, but any time would do)
33
34
  @from = @to = edge # set both to the edge utc time (a >=&&< query will get no records)
34
35
  end
@@ -51,7 +52,7 @@ class Pagy # :nodoc:
51
52
  end
52
53
  end
53
54
  Pagy.prepend PagyOverride
54
- Pagy::Calendar.prepend PagyOverride if defined?(Calendar)
55
+ Pagy::Calendar::Unit.prepend PagyOverride if defined?(Calendar::Unit)
55
56
 
56
57
  # Support for Pagy::Countless class
57
58
  module CountlessOverride
@@ -0,0 +1,40 @@
1
+ # See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/size
2
+ # frozen_string_literal: true
3
+
4
+ class Pagy # :nodoc:
5
+ # Implement the legacy bar using the array size.
6
+ # Unless you have very specific requirements, use the faster and better looking default bar.
7
+ module SizeExtra
8
+ # Setup @items based on the :gearbox_items variable
9
+ def series(size: @vars[:size], **_)
10
+ return super unless size.is_a?(Array)
11
+ return [] if size == []
12
+ raise VariableError.new(self, :size, 'to be an Array of 4 Integers or []', size) \
13
+ unless size.is_a?(Array) && size.size == 4 && size.all? { |num| !num.negative? rescue false } # rubocop:disable Style/RescueModifier
14
+
15
+ [].tap do |series|
16
+ # This algorithm is up to ~5x faster and ~2.3x lighter than the previous one (pagy < 4.3)
17
+ # However the behavior of the legacy nav bar was taken straight from WillPaginate and Kaminari:
18
+ # it's ill-concieved and complicates the experience of devs and users.
19
+ left_gap_start = 1 + size[0]
20
+ left_gap_end = @page - size[1] - 1
21
+ right_gap_start = @page + size[2] + 1
22
+ right_gap_end = @last - size[3]
23
+ left_gap_end = right_gap_end if left_gap_end > right_gap_end
24
+ right_gap_start = left_gap_start if left_gap_start > right_gap_start
25
+ start = 1
26
+ if (left_gap_end - left_gap_start).positive?
27
+ series.push(*start...left_gap_start, :gap)
28
+ start = left_gap_end + 1
29
+ end
30
+ if (right_gap_end - right_gap_start).positive?
31
+ series.push(*start...right_gap_start, :gap)
32
+ start = right_gap_end + 1
33
+ end
34
+ series.push(*start..@last)
35
+ series[series.index(@page)] = @page.to_s
36
+ end
37
+ end
38
+ end
39
+ prepend SizeExtra
40
+ end
data/lib/pagy/frontend.rb CHANGED
@@ -20,7 +20,7 @@ class Pagy
20
20
  a = pagy_anchor(pagy)
21
21
 
22
22
  html = %(<nav#{id} class="pagy nav" #{nav_aria_label(pagy, aria_label:)}>#{
23
- prev_a(pagy, a)})
23
+ prev_a(pagy, a)})
24
24
  pagy.series(**vars).each do |item| # series example: [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
25
25
  html << case item
26
26
  when Integer
data/lib/pagy.rb CHANGED
@@ -5,7 +5,7 @@ require 'pathname'
5
5
 
6
6
  # Core class
7
7
  class Pagy
8
- VERSION = '8.4.5'
8
+ VERSION = '8.6.1'
9
9
 
10
10
  # Gem root pathname to get the path of Pagy files stylesheets, javascripts, apps, locales, etc.
11
11
  def self.root
@@ -17,6 +17,7 @@ class Pagy
17
17
  items: 20,
18
18
  outset: 0,
19
19
  size: 7,
20
+ ends: true,
20
21
  count_args: [:all], # AR friendly
21
22
  page_param: :page }
22
23
 
@@ -39,46 +40,35 @@ class Pagy
39
40
  @next = @page == @last ? (1 if @vars[:cycle]) : @page + 1
40
41
  end
41
42
 
42
- # Return the array of page numbers and :gap items e.g. [1, :gap, 7, 8, "9", 10, 11, :gap, 36]
43
+ # Return the array of page numbers and :gap items e.g. [1, :gap, 8, "9", 10, :gap, 36]
43
44
  def series(size: @vars[:size], **_)
44
- series = []
45
- if size.is_a?(Array) && size.size == 4 && size.all? { |num| !num.negative? rescue false } # rubocop:disable Style/RescueModifier
46
- # This algorithm is up to ~5x faster and ~2.3x lighter than the previous one (pagy < 4.3)
47
- left_gap_start = 1 + size[0]
48
- left_gap_end = @page - size[1] - 1
49
- right_gap_start = @page + size[2] + 1
50
- right_gap_end = @last - size[3]
51
- left_gap_end = right_gap_end if left_gap_end > right_gap_end
52
- right_gap_start = left_gap_start if left_gap_start > right_gap_start
53
- start = 1
54
- if (left_gap_end - left_gap_start).positive?
55
- series.push(*start...left_gap_start, :gap)
56
- start = left_gap_end + 1
45
+ raise VariableError.new(self, :size, 'to be an Integer >= 0', size) \
46
+ unless size.is_a?(Integer)
47
+ return [] if size.zero?
48
+
49
+ [].tap do |series|
50
+ if size >= @last
51
+ series.push(*1..@last)
52
+ else
53
+ left = ((size - 1) / 2.0).floor # left half might be 1 page shorter for even size
54
+ start = if @page <= left # beginning pages
55
+ 1
56
+ elsif @page > @last - (size - left) # end pages
57
+ @last - size + 1
58
+ else # intermediate pages
59
+ @page - left
60
+ end
61
+ series.push(*start...start + size)
62
+ # Insert first and last ends plus gaps when needed
63
+ if vars[:ends] && size >= 7
64
+ series[0] = 1 unless series[0] == 1
65
+ series[1] = :gap unless series[1] == 2
66
+ series[-2] = :gap unless series[-2] == @last - 1
67
+ series[-1] = @last unless series[-1] == @last
68
+ end
57
69
  end
58
- if (right_gap_end - right_gap_start).positive?
59
- series.push(*start...right_gap_start, :gap)
60
- start = right_gap_end + 1
61
- end
62
- series.push(*start..@last)
63
- elsif size.is_a?(Integer) && size.positive? # only central series
64
- # The simplest and fastest algorithm
65
- size = @last if size > @last # reduce the max size to @last
66
- left = ((size - 1) / 2.0).floor # left half might be 1 page shorter for even size
67
- start = if @page <= left # beginning pages
68
- 1
69
- elsif @page > @last - (size - left) # end pages
70
- @last - size + 1
71
- else # intermediate pages
72
- @page - left
73
- end
74
- series = (start..start + size - 1).to_a
75
- else
76
- return [] if size.empty?
77
-
78
- raise VariableError.new(self, :size, 'to be a single positive Integer or an Array of 4', size)
70
+ series[series.index(@page)] = @page.to_s
79
71
  end
80
- series[series.index(@page)] = @page.to_s
81
- series
82
72
  end
83
73
 
84
74
  # Label for any page. Allow the customization of the output (overridden by the calendar extra)
@@ -124,6 +114,7 @@ class Pagy
124
114
  end
125
115
  end
126
116
 
117
+ require_relative 'pagy/extras/size' # will be opt in in v9.0
127
118
  require_relative 'pagy/backend'
128
119
  require_relative 'pagy/frontend'
129
120
  require_relative 'pagy/exceptions'
data/locales/ar.yml CHANGED
@@ -2,14 +2,12 @@
2
2
  ar:
3
3
  pagy:
4
4
  aria_label:
5
- # please add a comment in the https://github.com/ddnexus/pagy/issues/577
6
- # posting the translation of the following "Page"/"Pages" with the plurals for this locale
7
- nav: "Pages"
8
- # zero: ""
9
- # two: ""
10
- # few: ""
11
- # many: ""
12
- # other: ""
5
+ nav:
6
+ zero: "لا يوجد صفحات"
7
+ one: "صفحة"
8
+ two: "صفحتين"
9
+ few: "صفحات"
10
+ many: "صفحات"
13
11
  prev: "السابق"
14
12
  next: "التالي"
15
13
  prev: "&lt;"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pagy
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.4.5
4
+ version: 8.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Domizio Demichelis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-19 00:00:00.000000000 Z
11
+ date: 2024-06-28 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Agnostic pagination in plain ruby. It does it all. Better.
14
14
  email:
@@ -23,6 +23,11 @@ files:
23
23
  - apps/demo.ru
24
24
  - apps/rails.ru
25
25
  - apps/repro.ru
26
+ - apps/tmp/calendar.sqlite3
27
+ - apps/tmp/calendar.sqlite3-shm
28
+ - apps/tmp/calendar.sqlite3-wal
29
+ - apps/tmp/local_secret.txt
30
+ - apps/tmp/pagy-rails.sqlite3
26
31
  - bin/pagy
27
32
  - config/pagy.rb
28
33
  - javascripts/pagy-module.js
@@ -36,9 +41,9 @@ files:
36
41
  - lib/pagy/backend.rb
37
42
  - lib/pagy/calendar.rb
38
43
  - lib/pagy/calendar/day.rb
39
- - lib/pagy/calendar/helper.rb
40
44
  - lib/pagy/calendar/month.rb
41
45
  - lib/pagy/calendar/quarter.rb
46
+ - lib/pagy/calendar/unit.rb
42
47
  - lib/pagy/calendar/week.rb
43
48
  - lib/pagy/calendar/year.rb
44
49
  - lib/pagy/console.rb
@@ -65,6 +70,7 @@ files:
65
70
  - lib/pagy/extras/pagy.rb
66
71
  - lib/pagy/extras/searchkick.rb
67
72
  - lib/pagy/extras/semantic.rb
73
+ - lib/pagy/extras/size.rb
68
74
  - lib/pagy/extras/standalone.rb
69
75
  - lib/pagy/extras/trim.rb
70
76
  - lib/pagy/extras/uikit.rb
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Pagy # :nodoc:
4
- class Calendar # :nodoc:
5
- # Initializes the calendar objects, reducing complexity in the extra
6
- # The returned calendar is a simple hash of units/objects
7
- class Helper < Hash
8
- class << self
9
- private
10
-
11
- def init(conf, period, params)
12
- new.send(:init, conf, period, params)
13
- end
14
- end
15
-
16
- private
17
-
18
- # Create the calendar
19
- def init(conf, period, params)
20
- @conf = Marshal.load(Marshal.dump(conf)) # store a copy
21
- @units = Calendar::UNITS & @conf.keys # get the units in time length desc order
22
- raise ArgumentError, 'no calendar unit found in pagy_calendar @configuration' if @units.empty?
23
-
24
- @period = period
25
- @params = params
26
- @page_param = conf[:pagy][:page_param] || DEFAULT[:page_param]
27
- @units.each do |unit| # set all the :page_param vars for later deletion
28
- unit_page_param = :"#{unit}_#{@page_param}"
29
- conf[unit][:page_param] = unit_page_param
30
- conf[unit][:page] = @params[unit_page_param]
31
- end
32
- calendar = {}
33
- object = nil
34
- @units.each_with_index do |unit, index|
35
- params_to_delete = @units[(index + 1), @units.size].map { |sub| conf[sub][:page_param] } + [@page_param]
36
- conf[unit][:params] = lambda { |up| up.except(*params_to_delete.map(&:to_s)) } # rubocop:disable Style/Lambda
37
- conf[unit][:period] = object&.send(:active_period) || @period
38
- calendar[unit] = object = Calendar.send(:create, unit, conf[unit])
39
- end
40
- [replace(calendar), object.from, object.to]
41
- end
42
-
43
- # Return the calendar object at time
44
- def calendar_at(time, **opts)
45
- conf = Marshal.load(Marshal.dump(@conf))
46
- page_params = {}
47
- @units.inject(nil) do |object, unit|
48
- conf[unit][:period] = object&.send(:active_period) || @period
49
- conf[unit][:page] = page_params[:"#{unit}_#{@page_param}"] \
50
- = Calendar.send(:create, unit, conf[unit]).send(:page_at, time, **opts)
51
- conf[unit][:params] ||= {}
52
- conf[unit][:params].merge!(page_params)
53
- Calendar.send(:create, unit, conf[unit])
54
- end
55
- end
56
-
57
- public
58
-
59
- # Return the current time of the smallest time unit shown
60
- def showtime
61
- self[@units.last].from
62
- end
63
- end
64
- end
65
- end