wor-paginate 0.1.10 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f09070288ef65ad8eb2bf6ba05b8eead1911ac05
4
- data.tar.gz: 2261daf2882a9452432b0eb59609f9ab89713463
2
+ SHA256:
3
+ metadata.gz: 2465192c522659e0f6e779d73cda2dfaa3fa47aca0966ebc9fd4292587143cea
4
+ data.tar.gz: d71ab589396a9f76e25849e63bec31a1fe5aafcd1dd54c3b9ca79104957cbee7
5
5
  SHA512:
6
- metadata.gz: f5aa479217e9dfa235b14c0a98678679b4c25e2fa997b470b204193bbb59ffaf670c6b33595e9d020a642064e86fd7f5348904e8724bbe10b1b755f60726dda5
7
- data.tar.gz: 5beb45a05d1d79ee1b215186463bfab3ca430dc92204ce6e2e0a321930144149b44bc9f5c6eda697bbaaebc025ea8e39fb6bd57dd8011af72c3154fe35e4322e
6
+ metadata.gz: 8ed75b64b43ffe168a35a09a054532c384d51470e3942964b8a60ac191644b264e8d42a59e73ceea3485a0cc7680162a74dcd9d81b5581a110bb8510f965dfcc
7
+ data.tar.gz: 93143a274cdbd3bbaffe3898fa4038de9173b6d916eab033e5ae13c8fcaceb63baefc8c7a4d0a6c6ffbb4fc2f6513c2d68769a533fdc05416d3d5336c256dfd8
@@ -4,6 +4,7 @@ rvm:
4
4
  - 2.4.7
5
5
  - 2.5.6
6
6
  - 2.6.4
7
+ - 2.7.0
7
8
  - ruby-head
8
9
 
9
10
  before_install:
@@ -1,5 +1,11 @@
1
1
  ## Change log
2
2
 
3
+ ### V0.2.0
4
+ * [#95](https://github.com/Wolox/wor-paginate/pull/95) Added total_count option to overwrite the count in render_paginated - [@juanpablo-rojas](https://github.com/juanpablo-rojas).
5
+ * [#93](https://github.com/Wolox/wor-paginate/pull/93) Infinite scroll - [@mnmallea](https://github.com/mnmallea).
6
+ * [#92](https://github.com/Wolox/wor-paginate/pull/92) Ruby 2.7.0 support - [@mnmallea](https://github.com/mnmallea).
7
+ * [#91](https://github.com/Wolox/wor-paginate/pull/91) Navigation links - [@mnmallea](https://github.com/mnmallea).
8
+
3
9
  ### V0.1.10
4
10
  * [#90](https://github.com/Wolox/wor-paginate/pull/90) Verify that default adapter adapts - [@mtejedorwolox](https://github.com/mtejedorwolox).
5
11
 
data/Gemfile CHANGED
@@ -15,7 +15,7 @@ gemspec
15
15
 
16
16
  group :development, :test do
17
17
  gem 'active_model_serializers', '~> 0.10.0'
18
- gem 'bundler', '~> 2.0.1'
18
+ gem 'bundler', '>= 2.0.1'
19
19
  gem 'byebug', '~> 9.0'
20
20
  gem 'codeclimate-test-reporter', '~> 1.0.0'
21
21
  gem 'database_cleaner', '~> 1.6.0'
data/README.md CHANGED
@@ -89,7 +89,9 @@ The response to the index will then be:
89
89
  "total_count": 28,
90
90
  "current_page": 1,
91
91
  "previous_page": null,
92
- "next_page": 2
92
+ "next_page": 2,
93
+ "previous_page_url": null,
94
+ "next_page_url": "http://api.example.com/users?page=2
93
95
  }
94
96
  ```
95
97
 
@@ -131,6 +133,43 @@ class CustomSerializer < ActiveModel::Serializer
131
133
  end
132
134
  ```
133
135
 
136
+ ##### total_count
137
+ You can overwrite the `total_count` pagination param by passing it as a single option to the method. This could be used if the whole collection to be paginated is complex and has the risk to broke when counting all the records.
138
+
139
+ ```ruby
140
+ render_paginated DummyModel, total_count: 50
141
+ ```
142
+
143
+ ##### preserve_records
144
+ > WARNING: This option only works with an ActiveRecord collection.
145
+
146
+ Preserve records option can be added to `render_paginated` to mantain current records. This allow to navigate pages like an infinite scroll without adding new records when switching pages.
147
+
148
+ - Timestamp mode (default)
149
+ ```ruby
150
+ def index
151
+ render_paginated SomeModel, preserve_records: true
152
+ end
153
+
154
+ # You can customize the field used to preserve this records (default is 'created_at')
155
+ def index
156
+ render_paginated SomeModel, preserve_records: { by: :timestamp, field: :custom_time_field }
157
+ end
158
+ ```
159
+
160
+ - PK mode
161
+ ```ruby
162
+ def index
163
+ render_paginated SomeModel, preserve_records: { by: :id }
164
+ end
165
+
166
+ # You can customize the field used to preserve this records (default is 'id')
167
+ def index
168
+ render_paginated SomeModel, preserve_records: { by: :id, field: :my_custom_id_field }
169
+ end
170
+ ```
171
+
172
+
134
173
  #### Custom formatters
135
174
  A formatter is an object that defines the output of the render_paginated method. In case the application needs a different format for a request, it can be passed to the `render_paginated` method using the `formatter` option:
136
175
  ```ruby
@@ -209,7 +248,6 @@ end
209
248
  ## About ##
210
249
 
211
250
  The current maintainers of this gem are :
212
- * [Lucas Voboril](https://github.com/lucasVoboril)
213
251
  * [Martín Mallea](https://github.com/mnmallea)
214
252
 
215
253
  This project was developed by:
@@ -1,6 +1,9 @@
1
+ require_relative 'utils/uri_helper'
2
+
1
3
  module Wor
2
4
  module Paginate
3
5
  class Formatter
6
+ include Utils::UriHelper
4
7
  attr_accessor :adapter, :content, :formatter, :options
5
8
 
6
9
  def initialize(adapter, options = {})
@@ -8,15 +11,17 @@ module Wor
8
11
  @options = options
9
12
  end
10
13
 
11
- def format
14
+ def format # rubocop: disable Metrics/MethodLength
12
15
  {
13
16
  page: serialized_content,
14
17
  count: count,
15
18
  total_pages: total_pages,
16
- total_count: total_count,
19
+ total_count: options[:total_count] || total_count,
17
20
  current_page: current_page,
18
21
  previous_page: previous_page,
19
- next_page: next_page
22
+ next_page: next_page,
23
+ next_page_url: page_url(next_page),
24
+ previous_page_url: page_url(previous_page)
20
25
  }
21
26
  end
22
27
 
@@ -46,6 +51,16 @@ module Wor
46
51
  def serializer
47
52
  options[:each_serializer]
48
53
  end
54
+
55
+ def page_url(page)
56
+ return nil unless page
57
+
58
+ replace_query_params(current_url, page: page)
59
+ end
60
+
61
+ def current_url
62
+ options[:_current_url]
63
+ end
49
64
  end
50
65
  end
51
66
  end
@@ -1,3 +1,5 @@
1
+ require_relative 'utils/preserve_records_helper'
2
+
1
3
  module Wor
2
4
  module Paginate
3
5
  # The order of this array is important!
@@ -18,9 +20,19 @@ module Wor
18
20
  end
19
21
 
20
22
  def paginate(content, options = {})
23
+ current_url = request.original_url
24
+
25
+ if (preserve_records = options[:preserve_records])
26
+ content, current_url = Wor::Paginate::Utils::PreserveRecordsHelper
27
+ .new(content, current_url,
28
+ preserve_records.is_a?(Hash) ? preserve_records : {}).call
29
+ end
30
+
21
31
  adapter = find_adapter_for_content(content, options)
22
32
  raise Exceptions::NoPaginationAdapter if adapter.blank?
23
- formatter_class(options).new(adapter, options).format
33
+
34
+ formatter_class(options).new(adapter, options.merge(_current_url: current_url))
35
+ .format
24
36
  end
25
37
 
26
38
  def render_paginate_with_include(content, options)
@@ -44,15 +56,15 @@ module Wor
44
56
  end
45
57
 
46
58
  def option_limit(options)
47
- options[:limit].to_i unless options[:limit].nil?
59
+ options[:limit]&.to_i
48
60
  end
49
61
 
50
62
  def option_max_limit(options)
51
- options[:max_limit].to_i unless options[:max_limit].nil?
63
+ options[:max_limit]&.to_i
52
64
  end
53
65
 
54
66
  def param_limit
55
- params[Config.per_page_param].to_i unless params[Config.per_page_param].nil?
67
+ params[Config.per_page_param]&.to_i
56
68
  end
57
69
 
58
70
  def includes?(options)
@@ -30,7 +30,7 @@ RSpec::Matchers.define :be_paginated do
30
30
  match do |actual_response|
31
31
  response = parse_response(actual_response)
32
32
  formatter = @custom_formatter || Wor::Paginate::Formatter
33
- @formatted_keys = formatter.new(MockedAdapter.new).format.as_json.keys
33
+ @formatted_keys = formatter.new(MockedAdapter.new, _current_url: 'http://exaple.com/').format.as_json.keys
34
34
  response.keys == @formatted_keys
35
35
  end
36
36
 
@@ -0,0 +1,33 @@
1
+ module Wor
2
+ module Paginate
3
+ module Utils
4
+ module PreserveModes
5
+ module Timestamp
6
+ def self.default_field
7
+ :created_at
8
+ end
9
+
10
+ def self.last_value(query_param_value, _content, _field)
11
+ query_param_value ? Time.parse(query_param_value) : now_timestamp
12
+ end
13
+
14
+ private_class_method
15
+
16
+ def self.now_timestamp
17
+ Time.zone.now.iso8601(10)
18
+ end
19
+ end
20
+
21
+ module Id
22
+ def self.default_field
23
+ :id
24
+ end
25
+
26
+ def self.last_value(query_param_value, content, field)
27
+ query_param_value || content.maximum(field)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,49 @@
1
+ require_relative 'uri_helper'
2
+ require_relative 'preserve_modes'
3
+
4
+ module Wor
5
+ module Paginate
6
+ module Utils
7
+ class PreserveRecordsHelper
8
+ def initialize(content, url, options)
9
+ @content = content
10
+ @url = url
11
+ @options = options
12
+ end
13
+
14
+ def call
15
+ [content.where("#{field} <= :last_value", last_value: last_value),
16
+ UriHelper.replace_query_params(url, query_param_name => last_value)]
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :content, :url, :options
22
+
23
+ def by
24
+ @by ||= begin
25
+ by = options[:by]&.to_s || 'timestamp'
26
+ raise ArgumentError, "'by' option should be 'id' or 'timestamp'" unless
27
+ %w[timestamp id].include? by
28
+ "Wor::Paginate::Utils::PreserveModes::#{by.classify}".constantize
29
+ end
30
+ end
31
+
32
+ def field
33
+ @field ||= options[:field] || by.default_field
34
+ end
35
+
36
+ def last_value
37
+ @last_value ||= begin
38
+ query_param_value = UriHelper.query_params(url)[query_param_name]
39
+ by.last_value(query_param_value, content, field)
40
+ end
41
+ end
42
+
43
+ def query_param_name
44
+ @query_param_name ||= "#{field}_let"
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,20 @@
1
+ module Wor
2
+ module Paginate
3
+ module Utils
4
+ module UriHelper
5
+ def replace_query_params(uri_string, new_query)
6
+ uri = URI.parse(uri_string)
7
+ query = Rack::Utils.parse_query(uri.query)
8
+ uri.query = Rack::Utils.build_query(query.with_indifferent_access.merge(new_query))
9
+ uri.to_s
10
+ end
11
+
12
+ def query_params(uri_string)
13
+ Rack::Utils.parse_query(URI.parse(uri_string).query).with_indifferent_access
14
+ end
15
+
16
+ module_function :replace_query_params, :query_params
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,5 +1,5 @@
1
1
  module Wor
2
2
  module Paginate
3
- VERSION = '0.1.10'.freeze
3
+ VERSION = '0.2.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wor-paginate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.10
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - icoluccio
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2019-11-27 00:00:00.000000000 Z
14
+ date: 2020-02-13 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: railties
@@ -80,6 +80,9 @@ files:
80
80
  - lib/wor/paginate/formatter.rb
81
81
  - lib/wor/paginate/paginate.rb
82
82
  - lib/wor/paginate/rspec.rb
83
+ - lib/wor/paginate/utils/preserve_modes.rb
84
+ - lib/wor/paginate/utils/preserve_records_helper.rb
85
+ - lib/wor/paginate/utils/uri_helper.rb
83
86
  - lib/wor/paginate/version.rb
84
87
  - pull_request_template.md
85
88
  - test.sqlite3
@@ -103,8 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
106
  - !ruby/object:Gem::Version
104
107
  version: '0'
105
108
  requirements: []
106
- rubyforge_project:
107
- rubygems_version: 2.5.2.1
109
+ rubygems_version: 3.1.2
108
110
  signing_key:
109
111
  specification_version: 4
110
112
  summary: Simplified pagination for Rails API controllers