wor-paginate 0.1.10 → 0.2.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
- 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