pagy 9.4.0 → 43.5.5

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.
Files changed (176) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/apps/calendar.ru +566 -562
  4. data/apps/demo.ru +246 -182
  5. data/apps/enable_rails_page_segment.rb +56 -0
  6. data/apps/index.rb +4 -2
  7. data/apps/keynav+root_key.ru +316 -0
  8. data/apps/keynav.ru +255 -0
  9. data/apps/{keyset_ar.ru → keyset.ru} +33 -42
  10. data/apps/{keyset_s.ru → keyset_sequel.ru} +32 -40
  11. data/apps/rails.ru +57 -58
  12. data/apps/repro.ru +54 -51
  13. data/bin/pagy +2 -95
  14. data/config/pagy.rb +33 -207
  15. data/javascripts/ai_widget.js +90 -0
  16. data/javascripts/pagy.js +166 -0
  17. data/javascripts/pagy.min.js +2 -4
  18. data/javascripts/pagy.mjs +126 -67
  19. data/javascripts/wand.js +1172 -0
  20. data/lib/pagy/classes/calendar/calendar.rb +101 -0
  21. data/lib/pagy/{calendar → classes/calendar}/day.rb +7 -11
  22. data/lib/pagy/{calendar → classes/calendar}/month.rb +5 -10
  23. data/lib/pagy/{calendar → classes/calendar}/quarter.rb +10 -15
  24. data/lib/pagy/classes/calendar/unit.rb +93 -0
  25. data/lib/pagy/{calendar → classes/calendar}/week.rb +5 -9
  26. data/lib/pagy/{calendar → classes/calendar}/year.rb +5 -6
  27. data/lib/pagy/classes/exceptions.rb +26 -0
  28. data/lib/pagy/classes/keyset/adapters/active_record.rb +50 -0
  29. data/lib/pagy/classes/keyset/adapters/sequel.rb +62 -0
  30. data/lib/pagy/classes/keyset/keynav.rb +85 -0
  31. data/lib/pagy/classes/keyset/keyset.rb +155 -0
  32. data/lib/pagy/classes/offset/countish.rb +17 -0
  33. data/lib/pagy/classes/offset/countless.rb +63 -0
  34. data/lib/pagy/classes/offset/offset.rb +63 -0
  35. data/lib/pagy/classes/offset/search.rb +34 -0
  36. data/lib/pagy/classes/request.rb +48 -0
  37. data/lib/pagy/cli.rb +122 -0
  38. data/lib/pagy/console.rb +5 -20
  39. data/lib/pagy/deprecated.rb +84 -0
  40. data/lib/pagy/modules/abilities/configurable.rb +37 -0
  41. data/lib/pagy/modules/abilities/countable.rb +23 -0
  42. data/lib/pagy/modules/abilities/linkable.rb +72 -0
  43. data/lib/pagy/modules/abilities/rangeable.rb +14 -0
  44. data/lib/pagy/modules/abilities/shiftable.rb +12 -0
  45. data/lib/pagy/{b64.rb → modules/b64.rb} +4 -2
  46. data/lib/pagy/modules/console.rb +33 -0
  47. data/lib/pagy/modules/i18n/i18n.rb +72 -0
  48. data/lib/pagy/modules/i18n/p11n/arabic.rb +30 -0
  49. data/lib/pagy/modules/i18n/p11n/east_slavic.rb +27 -0
  50. data/lib/pagy/modules/i18n/p11n/one_other.rb +15 -0
  51. data/lib/pagy/modules/i18n/p11n/one_upto_two_other.rb +15 -0
  52. data/lib/pagy/modules/i18n/p11n/other.rb +13 -0
  53. data/lib/pagy/modules/i18n/p11n/polish.rb +27 -0
  54. data/lib/pagy/modules/i18n/p11n/west_slavic.rb +22 -0
  55. data/lib/pagy/modules/i18n/p11n.rb +16 -0
  56. data/lib/pagy/modules/searcher.rb +20 -0
  57. data/lib/pagy/next.rb +25 -0
  58. data/lib/pagy/tasks/sync.rb +20 -0
  59. data/lib/pagy/toolbox/helpers/anchor_tags.rb +19 -0
  60. data/lib/pagy/toolbox/helpers/bootstrap/input_nav_js.rb +28 -0
  61. data/lib/pagy/toolbox/helpers/bootstrap/previous_next_html.rb +19 -0
  62. data/lib/pagy/toolbox/helpers/bootstrap/series_nav.rb +32 -0
  63. data/lib/pagy/toolbox/helpers/bootstrap/series_nav_js.rb +24 -0
  64. data/lib/pagy/toolbox/helpers/bulma/input_nav_js.rb +25 -0
  65. data/lib/pagy/toolbox/helpers/bulma/previous_next_html.rb +20 -0
  66. data/lib/pagy/toolbox/helpers/bulma/series_nav.rb +31 -0
  67. data/lib/pagy/toolbox/helpers/bulma/series_nav_js.rb +23 -0
  68. data/lib/pagy/toolbox/helpers/data_hash.rb +29 -0
  69. data/lib/pagy/toolbox/helpers/headers_hash.rb +30 -0
  70. data/lib/pagy/toolbox/helpers/info_tag.rb +30 -0
  71. data/lib/pagy/toolbox/helpers/input_nav_js.rb +22 -0
  72. data/lib/pagy/toolbox/helpers/limit_tag_js.rb +25 -0
  73. data/lib/pagy/toolbox/helpers/loaders.rb +58 -0
  74. data/lib/pagy/toolbox/helpers/page_url.rb +16 -0
  75. data/lib/pagy/toolbox/helpers/series_nav.rb +30 -0
  76. data/lib/pagy/toolbox/helpers/series_nav_js.rb +20 -0
  77. data/lib/pagy/toolbox/helpers/support/a_lambda.rb +36 -0
  78. data/lib/pagy/toolbox/helpers/support/data_pagy_attribute.rb +19 -0
  79. data/lib/pagy/toolbox/helpers/support/nav_aria_label_attribute.rb +10 -0
  80. data/lib/pagy/toolbox/helpers/support/series.rb +37 -0
  81. data/lib/pagy/toolbox/helpers/support/wrap_input_nav_js.rb +18 -0
  82. data/lib/pagy/toolbox/helpers/support/wrap_series_nav.rb +15 -0
  83. data/lib/pagy/toolbox/helpers/support/wrap_series_nav_js.rb +38 -0
  84. data/lib/pagy/toolbox/helpers/urls_hash.rb +12 -0
  85. data/lib/pagy/toolbox/paginators/calendar.rb +34 -0
  86. data/lib/pagy/toolbox/paginators/countish.rb +38 -0
  87. data/lib/pagy/toolbox/paginators/countless.rb +22 -0
  88. data/lib/pagy/toolbox/paginators/elasticsearch_rails.rb +56 -0
  89. data/lib/pagy/toolbox/paginators/keynav_js.rb +26 -0
  90. data/lib/pagy/toolbox/paginators/keyset.rb +15 -0
  91. data/lib/pagy/toolbox/paginators/meilisearch.rb +34 -0
  92. data/lib/pagy/toolbox/paginators/method.rb +38 -0
  93. data/lib/pagy/toolbox/paginators/offset.rb +24 -0
  94. data/lib/pagy/toolbox/paginators/searchkick.rb +34 -0
  95. data/lib/pagy/toolbox/paginators/typesense_rails.rb +34 -0
  96. data/lib/pagy.rb +79 -89
  97. data/locales/ar.yml +9 -6
  98. data/locales/be.yml +9 -6
  99. data/locales/bg.yml +9 -6
  100. data/locales/bs.yml +9 -6
  101. data/locales/ca.yml +9 -6
  102. data/locales/ckb.yml +8 -6
  103. data/locales/cs.yml +9 -6
  104. data/locales/da.yml +9 -6
  105. data/locales/de.yml +9 -6
  106. data/locales/dz.yml +9 -6
  107. data/locales/en.yml +9 -6
  108. data/locales/es.yml +9 -6
  109. data/locales/fr.yml +9 -6
  110. data/locales/hr.yml +9 -6
  111. data/locales/hu.yml +24 -0
  112. data/locales/id.yml +10 -9
  113. data/locales/it.yml +9 -6
  114. data/locales/ja.yml +10 -9
  115. data/locales/km.yml +10 -9
  116. data/locales/ko.yml +9 -6
  117. data/locales/nb.yml +9 -6
  118. data/locales/nl.yml +9 -6
  119. data/locales/nn.yml +9 -6
  120. data/locales/pl.yml +9 -6
  121. data/locales/pt-BR.yml +10 -7
  122. data/locales/pt.yml +10 -7
  123. data/locales/ru.yml +9 -6
  124. data/locales/sk.yml +9 -6
  125. data/locales/sr.yml +9 -6
  126. data/locales/sv-SE.yml +9 -6
  127. data/locales/sv.yml +9 -6
  128. data/locales/sw.yml +12 -9
  129. data/locales/ta.yml +9 -6
  130. data/locales/tr.yml +17 -12
  131. data/locales/uk.yml +9 -6
  132. data/locales/vi.yml +9 -6
  133. data/locales/zh-CN.yml +9 -6
  134. data/locales/zh-HK.yml +9 -6
  135. data/locales/zh-TW.yml +9 -6
  136. data/stylesheets/pagy-tailwind.css +68 -0
  137. data/stylesheets/pagy.css +64 -27
  138. metadata +134 -53
  139. data/javascripts/pagy.min.js.map +0 -10
  140. data/lib/optimist.rb +0 -1022
  141. data/lib/pagy/backend.rb +0 -44
  142. data/lib/pagy/calendar/unit.rb +0 -103
  143. data/lib/pagy/calendar.rb +0 -84
  144. data/lib/pagy/countless.rb +0 -38
  145. data/lib/pagy/exceptions.rb +0 -25
  146. data/lib/pagy/extras/arel.rb +0 -28
  147. data/lib/pagy/extras/array.rb +0 -19
  148. data/lib/pagy/extras/bootstrap.rb +0 -97
  149. data/lib/pagy/extras/bulma.rb +0 -93
  150. data/lib/pagy/extras/calendar.rb +0 -79
  151. data/lib/pagy/extras/countless.rb +0 -32
  152. data/lib/pagy/extras/elasticsearch_rails.rb +0 -71
  153. data/lib/pagy/extras/gearbox.rb +0 -55
  154. data/lib/pagy/extras/headers.rb +0 -54
  155. data/lib/pagy/extras/i18n.rb +0 -26
  156. data/lib/pagy/extras/js_tools.rb +0 -70
  157. data/lib/pagy/extras/jsonapi.rb +0 -88
  158. data/lib/pagy/extras/keyset.rb +0 -30
  159. data/lib/pagy/extras/limit.rb +0 -63
  160. data/lib/pagy/extras/meilisearch.rb +0 -57
  161. data/lib/pagy/extras/metadata.rb +0 -42
  162. data/lib/pagy/extras/overflow.rb +0 -81
  163. data/lib/pagy/extras/pagy.rb +0 -82
  164. data/lib/pagy/extras/searchkick.rb +0 -59
  165. data/lib/pagy/extras/size.rb +0 -40
  166. data/lib/pagy/extras/standalone.rb +0 -60
  167. data/lib/pagy/extras/trim.rb +0 -29
  168. data/lib/pagy/frontend.rb +0 -99
  169. data/lib/pagy/i18n.rb +0 -167
  170. data/lib/pagy/keyset/active_record.rb +0 -44
  171. data/lib/pagy/keyset/sequel.rb +0 -57
  172. data/lib/pagy/keyset.rb +0 -118
  173. data/lib/pagy/shared_methods.rb +0 -26
  174. data/lib/pagy/url_helpers.rb +0 -26
  175. data/stylesheets/pagy.scss +0 -48
  176. data/stylesheets/pagy.tailwind.css +0 -21
data/lib/pagy/keyset.rb DELETED
@@ -1,118 +0,0 @@
1
- # See Pagy API documentation: https://ddnexus.github.io/pagy/docs/api/keyset
2
- # frozen_string_literal: true
3
-
4
- require 'json'
5
- require_relative 'b64'
6
- require_relative 'shared_methods'
7
-
8
- class Pagy
9
- # Implement wicked-fast keyset pagination for big data
10
- class Keyset
11
- class TypeError < ::TypeError; end
12
-
13
- include SharedMethods
14
-
15
- # Pick the right adapter for the set
16
- def self.new(set, **vars)
17
- if self == Pagy::Keyset
18
- if defined?(::ActiveRecord) && set.is_a?(::ActiveRecord::Relation)
19
- ActiveRecord
20
- elsif defined?(::Sequel) && set.is_a?(::Sequel::Dataset)
21
- Sequel
22
- else
23
- raise TypeError, "expected set to be an instance of ActiveRecord::Relation or Sequel::Dataset; got #{set.class}"
24
- end.new(set, **vars)
25
- else
26
- allocate.tap { |instance| instance.send(:initialize, set, **vars) }
27
- end
28
- end
29
-
30
- attr_reader :latest # Other readers from SharedMethods
31
-
32
- def initialize(set, **vars)
33
- default = DEFAULT.slice(:limit, :page_param, # from pagy
34
- :headers, # from headers extra
35
- :jsonapi, # from jsonapi extra
36
- :limit_param, :limit_max, :limit_extra) # from limit_extra
37
- assign_vars({ **default, page: nil }, vars)
38
- assign_limit
39
- @set = set
40
- @page = @vars[:page]
41
- @keyset = extract_keyset
42
- raise InternalError, 'the set must be ordered' if @keyset.empty?
43
- return unless @page
44
-
45
- latest = JSON.parse(B64.urlsafe_decode(@page)).transform_keys(&:to_sym)
46
- @latest = typecast_latest(latest)
47
- raise InternalError, 'page and keyset are not consistent' \
48
- unless @latest.keys == @keyset.keys
49
- end
50
-
51
- # Return the next page
52
- def next
53
- records
54
- return unless @more
55
-
56
- @next ||= begin
57
- hash = keyset_attributes_from(@records.last)
58
- json = @vars[:jsonify_keyset_attributes]&.(hash) || hash.to_json
59
- B64.urlsafe_encode(json)
60
- end
61
- end
62
-
63
- # Fetch the array of records for the current page
64
- def records
65
- @records ||= begin
66
- @set = apply_select if select?
67
- if @latest
68
- # :nocov:
69
- @set = @vars[:after_latest]&.(@set, @latest) || # deprecated
70
- # :nocov:
71
- @vars[:filter_newest]&.(@set, @latest, @keyset) ||
72
- filter_newest
73
- end
74
- records = @set.limit(@limit + 1).to_a
75
- @more = records.size > @limit && !records.pop.nil?
76
- records
77
- end
78
- end
79
-
80
- protected
81
-
82
- # Prepare the literal query string (complete with the placeholders for value interpolation)
83
- # used to filter the newest records.
84
- # For example:
85
- # With a set like Pet.order(animal: :asc, name: :desc, id: :asc) it returns the following string:
86
- # ( "pets"."animal" = :animal AND "pets"."name" = :name AND "pets"."id" > :id ) OR
87
- # ( "pets"."animal" = :animal AND "pets"."name" < :name ) OR
88
- # ( "pets"."animal" > :animal )
89
- # When :tuple_comparison is enabled, and if the order is all :asc or all :desc,
90
- # with a set like Pet.order(:animal, :name, :id) it returns the following string:
91
- # ( "pets"."animal", "pets"."name", "pets"."id" ) > ( :animal, :name, :id )
92
- def filter_newest_query
93
- operator = { asc: '>', desc: '<' }
94
- directions = @keyset.values
95
- name = quoted_identifiers(@set.model.table_name)
96
-
97
- if @vars[:tuple_comparison] && (directions.all?(:asc) || directions.all?(:desc))
98
- placeholders = @keyset.keys.map { |column| ":#{column}" }.join(', ')
99
- "( #{name.values.join(', ')} ) #{operator[directions.first]} ( #{placeholders} )"
100
- else
101
- keyset = @keyset.to_a
102
- where = []
103
- until keyset.empty?
104
- last_column, last_direction = keyset.pop
105
- query = +'( '
106
- query << (keyset.map { |column, _d| "#{name[column]} = :#{column}" } \
107
- << "#{name[last_column]} #{operator[last_direction]} :#{last_column}").join(' AND ')
108
- query << ' )'
109
- where << query
110
- end
111
- where.join(' OR ')
112
- end
113
- end
114
- end
115
- end
116
-
117
- require_relative 'keyset/active_record'
118
- require_relative 'keyset/sequel'
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Pagy
4
- # Shared with Keyset
5
- module SharedMethods
6
- attr_reader :page, :limit, :vars
7
-
8
- # Validates and assign the passed vars: var must be present and value.to_i must be >= to min
9
- def assign_and_check(name_min)
10
- name_min.each do |name, min|
11
- raise VariableError.new(self, name, ">= #{min}", @vars[name]) \
12
- unless @vars[name]&.respond_to?(:to_i) && instance_variable_set(:"@#{name}", @vars[name].to_i) >= min
13
- end
14
- end
15
-
16
- # Assign @limit (overridden by the gearbox extra)
17
- def assign_limit
18
- assign_and_check(limit: 1)
19
- end
20
-
21
- # Assign @vars
22
- def assign_vars(default, vars)
23
- @vars = { **default, **vars.delete_if { |k, v| default.key?(k) && (v.nil? || v == '') } }
24
- end
25
- end
26
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Pagy
4
- # Provide the helpers to handle the url in frontend and backend
5
- module UrlHelpers
6
- # Return the URL for the page, relying on the params method and Rack by default.
7
- # It supports all Rack-based frameworks (Sinatra, Padrino, Rails, ...).
8
- # For non-rack environments you can use the standalone extra
9
- def pagy_url_for(pagy, page, absolute: false, fragment: nil, **_)
10
- vars = pagy.vars
11
- query_params = request.GET.clone(freeze: false)
12
- query_params.merge!(vars[:params].transform_keys(&:to_s)) if vars[:params].is_a?(Hash)
13
- pagy_set_query_params(page, vars, query_params)
14
- query_params = vars[:params].(query_params) if vars[:params].is_a?(Proc)
15
- query_string = "?#{Rack::Utils.build_nested_query(query_params)}"
16
- "#{request.base_url if absolute}#{vars[:request_path] || request.path}#{query_string}#{fragment}"
17
- end
18
-
19
- # Add the page and limit params
20
- # Overridable by the jsonapi extra
21
- def pagy_set_query_params(page, vars, query_params)
22
- query_params[vars[:page_param].to_s] = page
23
- query_params[vars[:limit_param].to_s] = vars[:limit] if vars[:limit_extra]
24
- end
25
- end
26
- end
@@ -1,48 +0,0 @@
1
- .pagy {
2
- display: flex;
3
- font-family: sans-serif;
4
- font-size: 0.875rem;
5
- line-height: 1.25rem;
6
- font-weight: 600;
7
- color: rgb(107 114 128);
8
- & > :not([hidden]) ~ :not([hidden]) {
9
- --space-reverse: 0;
10
- margin-right: calc(0.25rem * var(--space-reverse));
11
- margin-left: calc(0.25rem * calc(1 - var(--space-reverse)));
12
- }
13
-
14
- a:not(.gap) {
15
- display: block;
16
- text-decoration: none;
17
- border-radius: 0.5rem;
18
- background-color: rgb(229 231 235);
19
- padding: 0.25rem 0.75rem;
20
- color: inherit;
21
- &:hover {
22
- background-color: rgb(209 213 219);
23
- }
24
- &:not([href]) { /* disabled links */
25
- cursor: default;
26
- background-color: rgb(243 244 246);
27
- color: rgb(209 213 219);
28
- }
29
- &.current {
30
- background-color: rgb(156 163 175);
31
- color: rgb(255 255 255);
32
- }
33
- }
34
-
35
- label {
36
- white-space: nowrap;
37
- display: inline-block;
38
- border-radius: 0.5rem;
39
- background-color: rgb(229 231 235);
40
- padding: 0.125rem 0.75rem;
41
- input {
42
- line-height: 1.5rem;
43
- border-radius: 0.375rem;
44
- border-style: none;
45
- background-color: rgb(243 244 246);
46
- }
47
- }
48
- }
@@ -1,21 +0,0 @@
1
- .pagy {
2
- @apply flex space-x-1 font-semibold text-sm text-gray-500;
3
- a:not(.gap) {
4
- @apply block rounded-lg px-3 py-1 bg-gray-200;
5
- &:hover {
6
- @apply bg-gray-300;
7
- }
8
- &:not([href]) { /* disabled links */
9
- @apply text-gray-300 bg-gray-100 cursor-default;
10
- }
11
- &.current {
12
- @apply text-white bg-gray-400;
13
- }
14
- }
15
- label {
16
- @apply inline-block whitespace-nowrap bg-gray-200 rounded-lg px-3 py-0.5;
17
- input {
18
- @apply bg-gray-100 border-none rounded-md;
19
- }
20
- }
21
- }