pagy 8.4.5 → 8.6.1

Sign up to get free protection for your applications and to get access to all the features.
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