datagrid 1.5.6 → 1.6.1

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: de5cf9444ec74f75f3238dcdd239daf3fcf3782e
4
- data.tar.gz: 026fd1c07e87df9f44d30ced49cfffb4e33c0775
2
+ SHA256:
3
+ metadata.gz: 76bece54343c202c79e7ca4d5e90ae1cc91d2c5a77b965a175b36df801e10bd1
4
+ data.tar.gz: 68e58ec9dec5f010b43a7e078fdbf2c3c1b0923c9f2ab38c327d3665570d08fa
5
5
  SHA512:
6
- metadata.gz: f5a5ef91ad59f2cb24cde7ef914e2dbc85149f828983746563d27df21f3c5a5b1ee724924d512fa5b1feb8fda26beab0fab54239f12fadc8a106185e7d232234
7
- data.tar.gz: 66b23c02db354d88e6128ac0eaaf8fcdba5d7a45699d024a67606371f13b4a27e052decc582b83c47b933d37ae766a7c0c3340fc4f6201fed7d0a24db7210be9
6
+ metadata.gz: 9aeb7a29ea7df278090a6417e1f940dfe9f8b1aa57dd907f9f739c4d2bc3e613be66be28635c5cf51a70b9067a7f7da4a00e7adaf09ae8ddea0247c7f34a56b1
7
+ data.tar.gz: 8660381aa1d508c624b0bc6d1c6e71ca3e6c1e89cad518733aeaee31d1968dc6382c45d1d06cbb60cd33ea1407d3e79e92e5920d93483bdfd47a31ffa1e23cef
@@ -1,9 +1,12 @@
1
1
  language: ruby
2
2
  #bundler_args: --without development
3
3
  rvm:
4
- - 2.2.2
5
- - 2.3.0
6
- - 2.4.1
4
+ - 2.2
5
+ - 2.3
6
+ - 2.4
7
+ - 2.5
8
+ - 2.6
9
+ - 2.7
7
10
  #- jruby
8
11
  #- jruby-head
9
12
  #env: JRUBY_OPTS="--server -J-Xms512m -J-Xmx1024m"
data/Gemfile CHANGED
@@ -6,17 +6,21 @@ group :development do
6
6
 
7
7
  gem "bundler"
8
8
  if RUBY_VERSION >= "2.3"
9
- gem "jeweler", ">= 2.1.2", platform: [:ruby_23, :ruby_24]
9
+ gem "jeweler", ">= 2.1.2", platform: :mri, github: 'technicalpickles/jeweler'
10
10
  end
11
11
 
12
12
 
13
13
  #gem "json", ">= 1.9"
14
- gem "pry-byebug", :platform => [:ruby_20, :ruby_21, :ruby_22, :ruby_23] & Bundler::Dsl::VALID_PLATFORMS
14
+ gem "pry-byebug"
15
15
 
16
16
  gem "rspec", ">= 3"
17
17
  gem "nokogiri" # used to test html output
18
18
 
19
- gem "sqlite3"
19
+ if RUBY_VERSION >= "2.5"
20
+ gem "sqlite3", "~> 1.4", platform: :mri
21
+ else
22
+ gem "sqlite3", "~> 1.3.6"
23
+ end
20
24
  gem "sequel"
21
25
 
22
26
  group :mongo do
@@ -2,6 +2,8 @@
2
2
 
3
3
  [![Build Status](https://travis-ci.org/bogdan/datagrid.svg?branch=master)](https://travis-ci.org/bogdan/datagrid)
4
4
 
5
+ [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fbogdan%2Fdatagrid.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fbogdan%2Fdatagrid?ref=badge_shield)
6
+
5
7
  Ruby library that helps you to build and represent table-like data with:
6
8
 
7
9
  * Customizable filtering
@@ -197,3 +199,7 @@ Like datagrid?
197
199
  Follow the repository on [GitHub](https://github.com/bogdan/datagrid).
198
200
 
199
201
  Read [author blog](http://gusiev.com).
202
+
203
+
204
+ ## License
205
+ [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fbogdan%2Fdatagrid.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fbogdan%2Fdatagrid?ref=badge_large)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.5.6
1
+ 1.6.1
@@ -11,7 +11,7 @@ Local variables:
11
11
  </thead>
12
12
  <tbody>
13
13
  <% if assets.any? %>
14
- <%= datagrid_rows(grid, assets, options) %>
14
+ <%= datagrid_rows(grid, assets, **options) %>
15
15
  <% else %>
16
16
  <tr><td class="noresults" colspan="100%"><%= I18n.t('datagrid.no_results').html_safe %></td></tr>
17
17
  <% end %>
@@ -2,20 +2,21 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: datagrid 1.5.6 ruby lib
5
+ # stub: datagrid 1.6.1 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "datagrid".freeze
9
- s.version = "1.5.6"
9
+ s.version = "1.6.1"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Bogdan Gusiev".freeze]
14
- s.date = "2017-10-30"
14
+ s.date = "2020-09-07"
15
15
  s.description = "This allows you to easily build datagrid aka data tables with sortable columns and filters".freeze
16
16
  s.email = "agresso@gmail.com".freeze
17
17
  s.extra_rdoc_files = [
18
- "LICENSE.txt"
18
+ "LICENSE.txt",
19
+ "Readme.markdown"
19
20
  ]
20
21
  s.files = [
21
22
  ".document",
@@ -130,7 +131,7 @@ Gem::Specification.new do |s|
130
131
  s.homepage = "http://github.com/bogdan/datagrid".freeze
131
132
  s.licenses = ["MIT".freeze]
132
133
  s.required_ruby_version = Gem::Requirement.new(">= 2.0".freeze)
133
- s.rubygems_version = "2.6.7".freeze
134
+ s.rubygems_version = "3.0.8".freeze
134
135
  s.summary = "Ruby gem to create datagrids".freeze
135
136
 
136
137
  if s.respond_to? :specification_version then
@@ -143,7 +144,7 @@ Gem::Specification.new do |s|
143
144
  s.add_development_dependency(%q<pry-byebug>.freeze, [">= 0"])
144
145
  s.add_development_dependency(%q<rspec>.freeze, [">= 3"])
145
146
  s.add_development_dependency(%q<nokogiri>.freeze, [">= 0"])
146
- s.add_development_dependency(%q<sqlite3>.freeze, [">= 0"])
147
+ s.add_development_dependency(%q<sqlite3>.freeze, ["~> 1.4"])
147
148
  s.add_development_dependency(%q<sequel>.freeze, [">= 0"])
148
149
  s.add_development_dependency(%q<mongoid>.freeze, [">= 0"])
149
150
  s.add_development_dependency(%q<bson>.freeze, [">= 0"])
@@ -155,7 +156,7 @@ Gem::Specification.new do |s|
155
156
  s.add_dependency(%q<pry-byebug>.freeze, [">= 0"])
156
157
  s.add_dependency(%q<rspec>.freeze, [">= 3"])
157
158
  s.add_dependency(%q<nokogiri>.freeze, [">= 0"])
158
- s.add_dependency(%q<sqlite3>.freeze, [">= 0"])
159
+ s.add_dependency(%q<sqlite3>.freeze, ["~> 1.4"])
159
160
  s.add_dependency(%q<sequel>.freeze, [">= 0"])
160
161
  s.add_dependency(%q<mongoid>.freeze, [">= 0"])
161
162
  s.add_dependency(%q<bson>.freeze, [">= 0"])
@@ -168,7 +169,7 @@ Gem::Specification.new do |s|
168
169
  s.add_dependency(%q<pry-byebug>.freeze, [">= 0"])
169
170
  s.add_dependency(%q<rspec>.freeze, [">= 3"])
170
171
  s.add_dependency(%q<nokogiri>.freeze, [">= 0"])
171
- s.add_dependency(%q<sqlite3>.freeze, [">= 0"])
172
+ s.add_dependency(%q<sqlite3>.freeze, ["~> 1.4"])
172
173
  s.add_dependency(%q<sequel>.freeze, [">= 0"])
173
174
  s.add_dependency(%q<mongoid>.freeze, [">= 0"])
174
175
  s.add_dependency(%q<bson>.freeze, [">= 0"])
@@ -16,6 +16,7 @@ module Datagrid
16
16
  self.default_column_options = {}
17
17
 
18
18
  class_attribute :batch_size
19
+ self.batch_size = 1000
19
20
 
20
21
  class_attribute :columns_array
21
22
  self.columns_array = []
@@ -313,10 +314,10 @@ module Datagrid
313
314
  # grid.to_csv(:id, :name)
314
315
  # grid.to_csv(:col_sep => ';')
315
316
  def to_csv(*column_names)
317
+ require "csv"
316
318
  options = column_names.extract_options!
317
- csv_class.generate(
318
- {:headers => self.header(*column_names), :write_headers => true}.merge!(options)
319
- ) do |csv|
319
+ options = {:headers => self.header(*column_names), :write_headers => true}.merge!(options)
320
+ CSV.generate(**options) do |csv|
320
321
  each_with_batches do |asset|
321
322
  csv << row_for(asset, *column_names)
322
323
  end
@@ -405,7 +406,7 @@ module Datagrid
405
406
  # Defines a column at instance level
406
407
  #
407
408
  # See Datagrid::Columns::ClassMethods#column for more info
408
- def column(name, options_or_query = {}, options = {}, &block) #:nodoc:
409
+ def column(name, options_or_query = {}, options = {}, &block)
409
410
  self.class.define_column(columns_array, name, options_or_query, options, &block)
410
411
  end
411
412
 
@@ -414,7 +415,7 @@ module Datagrid
414
415
  super
415
416
  end
416
417
 
417
- # Returns all columns available for current grid configuration.
418
+ # Returns all columns that are possible to be displayed for the current grid object
418
419
  #
419
420
  # class MyGrid
420
421
  # filter(:search) {|scope, value| scope.full_text_search(value)}
@@ -531,19 +532,12 @@ module Datagrid
531
532
  end
532
533
  end
533
534
 
534
- def csv_class
535
- if RUBY_VERSION >= "1.9"
536
- require 'csv'
537
- CSV
538
- else
539
- require "fastercsv"
540
- FasterCSV
541
- end
542
- end
543
-
544
535
  def value_from_html_block(context, asset, column)
545
536
  args = []
546
537
  remaining_arity = column.html_block.arity
538
+ remaining_arity = 1 if remaining_arity < 0
539
+
540
+ asset = decorate(asset)
547
541
 
548
542
  if column.data?
549
543
  args << data_value(column, asset)
@@ -123,11 +123,6 @@ class Datagrid::Columns::Column
123
123
  end
124
124
 
125
125
 
126
- def block
127
- Datagrid::Utils.warn_once("Datagrid::Columns::Column#block is deprecated. Use #html_block or #data_block instead")
128
- data_block
129
- end
130
-
131
126
  def generic_value(model, grid)
132
127
  grid.generic_value(self, model)
133
128
  end
@@ -149,7 +144,7 @@ class Datagrid::Columns::Column
149
144
  def preload
150
145
  preload = options[:preload]
151
146
 
152
- if [nil, true].include?(preload) && driver.can_preload?(driver.to_scope(grid_class.scope), name)
147
+ if preload == true && driver.can_preload?(driver.to_scope(grid_class.scope), name)
153
148
  name
154
149
  else
155
150
  preload
@@ -9,10 +9,12 @@ module Datagrid
9
9
  base.class_eval do
10
10
  class_attribute :scope_value
11
11
 
12
- class_attribute :datagrid_attributes
12
+ class_attribute :datagrid_attributes, instance_writer: false
13
13
  self.datagrid_attributes = []
14
14
 
15
15
  class_attribute :dynamic_block, :instance_writer => false
16
+ class_attribute :forbidden_attributes_protection, instance_writer: false
17
+ self.forbidden_attributes_protection = false
16
18
  if defined?(::ActiveModel::AttributeAssignment)
17
19
  include ::ActiveModel::AttributeAssignment
18
20
  end
@@ -148,6 +150,9 @@ module Datagrid
148
150
  # Updates datagrid attributes with a passed hash argument
149
151
  def attributes=(attributes)
150
152
  if respond_to?(:assign_attributes)
153
+ if !forbidden_attributes_protection && attributes.respond_to?(:permit!)
154
+ attributes.permit!
155
+ end
151
156
  assign_attributes(attributes)
152
157
  else
153
158
  attributes.each do |name, value|
@@ -158,6 +163,9 @@ module Datagrid
158
163
  end
159
164
 
160
165
  # Returns serializable query arguments skipping all nil values
166
+ #
167
+ # grid = ProductsGrid.new(category: 'dresses', available: true)
168
+ # grid.as_query # => {category: 'dresses', available: true}
161
169
  def as_query
162
170
  attributes = self.attributes.clone
163
171
  attributes.each do |key, value|
@@ -166,6 +174,15 @@ module Datagrid
166
174
  attributes
167
175
  end
168
176
 
177
+ # Returns query parameters to link this grid from a page
178
+ #
179
+ # grid = ProductsGrid.new(category: 'dresses', available: true)
180
+ # Rails.application.routes.url_helpers.products_path(grid.query_params)
181
+ # # => "/products?products_grid[category]=dresses&products_grid[available]=true"
182
+ def query_params(attributes = {})
183
+ { param_name.to_sym => as_query.merge(attributes) }
184
+ end
185
+
169
186
  # Redefines scope at instance level
170
187
  #
171
188
  # class MyGrid
@@ -223,7 +240,6 @@ module Datagrid
223
240
  attributes == other.attributes &&
224
241
  scope == other.scope
225
242
  end
226
-
227
243
  end # InstanceMethods
228
244
  end
229
245
  end
@@ -105,7 +105,8 @@ module Datagrid
105
105
  if scope.limit_value
106
106
  raise Datagrid::ConfigurationError, "ActiveRecord can not use batches in combination with SQL limit"
107
107
  end
108
- scope.find_each(batch_size ? { :batch_size => batch_size} : {}, &block)
108
+ options = batch_size ? { batch_size: batch_size } : {}
109
+ scope.find_each(**options, &block)
109
110
  end
110
111
 
111
112
  def default_cache_key(asset)
@@ -12,7 +12,11 @@ module Datagrid
12
12
  end
13
13
 
14
14
  def to_scope(scope)
15
- scope.where(nil)
15
+ if scope.respond_to?(:all)
16
+ scope.all
17
+ else
18
+ scope.where(nil)
19
+ end
16
20
  end
17
21
 
18
22
  def where(scope, attribute, value)
@@ -53,7 +53,7 @@ module Datagrid
53
53
  def filter_by_name(attribute)
54
54
  return attribute if attribute.is_a?(Datagrid::Filters::BaseFilter)
55
55
  self.filters.find do |filter|
56
- filter.name.to_sym == attribute.to_sym
56
+ filter.name == attribute.to_sym
57
57
  end
58
58
  end
59
59
 
@@ -7,7 +7,7 @@ class Datagrid::Filters::BaseFilter #:nodoc:
7
7
 
8
8
  def initialize(grid_class, name, options = {}, &block)
9
9
  self.grid_class = grid_class
10
- self.name = name
10
+ self.name = name.to_sym
11
11
  self.options = options
12
12
  self.block = block || default_filter_block
13
13
  end
@@ -61,18 +61,10 @@ class Datagrid::Filters::BaseFilter #:nodoc:
61
61
  end
62
62
  end
63
63
 
64
- def default(object = nil)
65
- unless object
66
- Datagrid::Utils.warn_once("#{self.class.name}#default without argument is deprecated")
67
- end
64
+ def default(object)
68
65
  default = self.options[:default]
69
66
  if default.is_a?(Symbol)
70
- if object.respond_to?(default)
71
- object.send(default)
72
- else
73
- Datagrid::Utils.warn_once(":default as a Symbol is now treated as a method name. Use String instead or -> { default } if you really want default value to be a Symbol but not a String.")
74
- default
75
- end
67
+ object.send(default)
76
68
  elsif default.respond_to?(:call)
77
69
  Datagrid::Utils.apply_args(object, &default)
78
70
  else
@@ -80,11 +72,6 @@ class Datagrid::Filters::BaseFilter #:nodoc:
80
72
  end
81
73
  end
82
74
 
83
- def multiple
84
- Datagrid::Utils.warn_once("Filter#multiple method is deprecated. Use Filter#multiple? instead")
85
- multiple?
86
- end
87
-
88
75
  def multiple?
89
76
  self.options[:multiple]
90
77
  end
@@ -4,12 +4,22 @@ class Datagrid::Filters::DynamicFilter < Datagrid::Filters::BaseFilter
4
4
 
5
5
  include Datagrid::Filters::SelectOptions
6
6
 
7
+ EQUAL_OPERATION = '='
8
+ LIKE_OPERATION = '=~'
9
+ MORE_EQUAL_OPERATION = '>='
10
+ LESS_EQUAL_OPERATION = '<='
11
+ DEFAULT_OPERATIONS = [
12
+ EQUAL_OPERATION,
13
+ LIKE_OPERATION,
14
+ MORE_EQUAL_OPERATION,
15
+ LESS_EQUAL_OPERATION,
16
+ ]
7
17
  AVAILABLE_OPERATIONS = %w(= =~ >= <=)
8
18
 
9
19
  def initialize(*)
10
20
  super
11
21
  options[:select] ||= default_select
12
- options[:operations] ||= AVAILABLE_OPERATIONS
22
+ options[:operations] ||= DEFAULT_OPERATIONS
13
23
  unless options.has_key?(:include_blank)
14
24
  options[:include_blank] = false
15
25
  end
@@ -35,12 +45,12 @@ class Datagrid::Filters::DynamicFilter < Datagrid::Filters::BaseFilter
35
45
  raise Datagrid::FilteringError, "Unknown operation: #{operation.inspect}. Available operations: #{operations.join(' ')}"
36
46
  end
37
47
  case operation
38
- when '='
48
+ when EQUAL_OPERATION
39
49
  if date_conversion
40
50
  value = Datagrid::Utils.format_date_as_timestamp(value)
41
51
  end
42
52
  driver.where(scope, field, value)
43
- when '=~'
53
+ when LIKE_OPERATION
44
54
  if column_type(field) == :string
45
55
  driver.contains(scope, field, value)
46
56
  else
@@ -49,12 +59,12 @@ class Datagrid::Filters::DynamicFilter < Datagrid::Filters::BaseFilter
49
59
  end
50
60
  driver.where(scope, field, value)
51
61
  end
52
- when '>='
62
+ when MORE_EQUAL_OPERATION
53
63
  if date_conversion
54
64
  value = value.beginning_of_day
55
65
  end
56
66
  driver.greater_equal(scope, field, value)
57
- when '<='
67
+ when LESS_EQUAL_OPERATION
58
68
  if date_conversion
59
69
  value = value.end_of_day
60
70
  end
@@ -1,9 +1,6 @@
1
1
  module Datagrid::Filters::SelectOptions
2
2
 
3
- def select(object = nil)
4
- unless object
5
- Datagrid::Utils.warn_once("#{self.class.name}#select without argument is deprecated")
6
- end
3
+ def select(object)
7
4
  select = self.options[:select]
8
5
  if select.is_a?(Symbol)
9
6
  object.send(select)
@@ -140,43 +140,16 @@ module Datagrid
140
140
  if filter.range?
141
141
  partial = partial_path('range_filter')
142
142
  options = options.merge(:multiple => true)
143
-
144
-
145
143
  from_options = datagrid_range_filter_options(object, filter, :from, options)
146
144
  to_options = datagrid_range_filter_options(object, filter, :to, options)
147
- from_input = text_field(filter.name, from_options)
148
- to_input = text_field(filter.name, to_options)
149
-
150
- format_key = "datagrid.filters.#{type}.range_format"
151
- separator_key = "datagrid.filters.#{type}.range_separator"
152
- # 2 inputs: "from date" and "to date" to specify a range
153
- if I18n.exists?(separator_key)
154
- # Support deprecated translation option: range_separator
155
- warn_deprecated_range_localization(separator_key)
156
- separator = I18n.t(separator_key, default: '').presence
157
- [from_input, separator, to_input].join.html_safe
158
- elsif I18n.exists?(format_key)
159
- # Support deprecated translation option: range_format
160
- warn_deprecated_range_localization(format_key)
161
- I18n.t(format_key, :from_input => from_input, :to_input => to_input).html_safe
162
- else
163
- # More flexible way to render via partial
164
- @template.render :partial => partial, :locals => {
165
- :from_options => from_options, :to_options => to_options, :filter => filter, :form => self
166
- }
167
- end
145
+ @template.render :partial => partial, :locals => {
146
+ :from_options => from_options, :to_options => to_options, :filter => filter, :form => self
147
+ }
168
148
  else
169
149
  datagrid_default_filter(filter, options)
170
150
  end
171
151
  end
172
152
 
173
- def warn_deprecated_range_localization(key)
174
- Datagrid::Utils.warn_once(
175
- "#{key} localization key is deprectated. " +
176
- "Customize formatting by rake datagrid:copy_partials and editing app/views/datagrid/range_filter partial."
177
- )
178
- end
179
-
180
153
  def datagrid_range_filter_options(object, filter, type, options)
181
154
  type_method_map = {:from => :first, :to => :last}
182
155
  options = add_html_classes(options, type)
@@ -73,7 +73,7 @@ module Datagrid
73
73
  # %td= row.project_name
74
74
  # %td.project-status{class: row.status}= row.status
75
75
  def datagrid_rows(grid, assets = grid.assets, **options, &block)
76
- datagrid_renderer.rows(grid, assets, options, &block)
76
+ datagrid_renderer.rows(grid, assets, **options, &block)
77
77
  end
78
78
 
79
79
  # Renders ordering controls for the given column name
@@ -1,11 +1,11 @@
1
1
  en:
2
2
  datagrid:
3
3
  no_results:
4
- "&mdash;&mdash;"
4
+ "――"
5
5
  table:
6
6
  order:
7
- asc: "&uarr;"
8
- desc: "&darr;"
7
+ asc: ""
8
+ desc: ""
9
9
  no_columns: "No columns selected"
10
10
  form:
11
11
  search: "Search"
@@ -17,7 +17,7 @@ en:
17
17
 
18
18
  dynamic:
19
19
  operations:
20
- ">=": "&ge;"
21
- "<=": "&le;"
20
+ ">=": ""
21
+ "<=": ""
22
22
  "=": "="
23
- "=~": "&asymp;"
23
+ "=~": ""
@@ -81,10 +81,9 @@ module Datagrid
81
81
  def order_path(grid, column, descending, request)
82
82
  column = grid.column_by_name(column)
83
83
  query = request ? request.query_parameters : {}
84
- order_parameter = {grid.param_name => grid.as_query.merge(:order => column.name, :descending => descending)}
85
84
  ActionDispatch::Http::URL.path_for(
86
85
  path: request ? request.path : '/',
87
- params: query.merge(order_parameter)
86
+ params: query.merge(grid.query_params(order: column.name, descending: descending))
88
87
  )
89
88
  end
90
89
 
@@ -84,10 +84,16 @@ class Datagrid::Scaffold < Rails::Generators::NamedBase
84
84
  def index_action
85
85
  indent(<<-RUBY)
86
86
  def index
87
- @grid = #{grid_class_name}.new(params[:#{grid_param_name}]) do |scope|
87
+ @grid = #{grid_class_name}.new(grid_params) do |scope|
88
88
  scope.page(params[:page])
89
89
  end
90
90
  end
91
+
92
+ protected
93
+
94
+ def grid_params
95
+ params.fetch(:#{grid_param_name}, {}).permit!
96
+ end
91
97
  RUBY
92
98
  end
93
99
 
@@ -72,12 +72,8 @@ module Datagrid
72
72
  end
73
73
 
74
74
  def apply_args(*args, &block)
75
- return block.call(*args) if block.arity < 0
76
- args = args.clone
77
- (args.size - block.arity).times do
78
- args.pop
79
- end
80
- block.call(*args)
75
+ size = block.arity < 0 ? args.size : block.arity
76
+ block.call(*args.slice(0, size))
81
77
  end
82
78
 
83
79
  def parse_date(value)
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require "action_controller/metal/strong_parameters"
2
3
 
3
4
  describe Datagrid::Core do
4
5
 
@@ -158,4 +159,52 @@ describe Datagrid::Core do
158
159
  expect(grid.assets.limit_value).to eq(2)
159
160
  end
160
161
  end
162
+
163
+ describe "ActionController::Parameters" do
164
+
165
+ let(:params) do
166
+ ::ActionController::Parameters.new(name: 'one')
167
+ end
168
+
169
+ it "permites all attributes by default" do
170
+ expect {
171
+ test_report(params) do
172
+ scope { Entry }
173
+ filter(:name)
174
+ end
175
+ }.to_not raise_error
176
+ end
177
+ it "doesn't permit attributes when forbidden_attributes_protection is set" do
178
+ expect {
179
+ test_report(params) do
180
+ scope { Entry }
181
+ self.forbidden_attributes_protection = true
182
+ filter(:name)
183
+ end
184
+ }.to raise_error(ActiveModel::ForbiddenAttributesError)
185
+ end
186
+ it "permits attributes when forbidden_attributes_protection is set and attributes are permitted" do
187
+ expect {
188
+ test_report(params.permit!) do
189
+ scope { Entry }
190
+ self.forbidden_attributes_protection = true
191
+ filter(:name)
192
+ end
193
+ }.to_not raise_error
194
+ end
195
+ end
196
+
197
+
198
+ describe ".query_param" do
199
+ it "works" do
200
+ grid = test_report(name: 'value') do
201
+ scope {Entry}
202
+ filter(:name)
203
+ def param_name
204
+ 'grid'
205
+ end
206
+ end
207
+ expect(grid.query_params).to eq({grid: {name: 'value'}})
208
+ end
209
+ end
161
210
  end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require "active_support/testing/time_helpers"
2
3
 
3
4
  describe Datagrid::Filters::DateFilter do
4
5
 
@@ -122,14 +123,16 @@ describe Datagrid::Filters::DateFilter do
122
123
 
123
124
 
124
125
  it "should support block" do
125
- report = test_report(:created_at => Date.today) do
126
+ date = Date.new(2018, 01, 07)
127
+ time = Time.utc(2018, 01, 07, 2, 2)
128
+ report = test_report(:created_at => date) do
126
129
  scope { Entry }
127
130
  filter(:created_at, :date, :range => true) do |value|
128
131
  where("created_at >= ?", value)
129
132
  end
130
133
  end
131
- expect(report.assets).not_to include(Entry.create!(:created_at => 1.day.ago))
132
- expect(report.assets).to include(Entry.create!(:created_at => Time.now))
134
+ expect(report.assets).not_to include(Entry.create!(:created_at => time - 1.day))
135
+ expect(report.assets).to include(Entry.create!(:created_at => time))
133
136
  end
134
137
 
135
138
 
@@ -1,5 +1,6 @@
1
1
  # encoding: UTF-8
2
2
  require 'spec_helper'
3
+ require "action_controller"
3
4
 
4
5
  class MyFormBuilder
5
6
  include Datagrid::FormBuilder
@@ -11,19 +12,15 @@ end
11
12
 
12
13
 
13
14
  describe Datagrid::FormBuilder do
14
-
15
15
  let(:template) do
16
- ActionView::Base.new.tap do |v|
17
- v.view_paths << File.expand_path("../../../app/views", __FILE__)
18
- v.view_paths << File.expand_path("../../support/test_partials", __FILE__)
19
- end
16
+ action_view_template
20
17
  end
18
+
21
19
  let(:view) { ActionView::Helpers::FormBuilder.new(:report, _grid, template, view_options)}
22
20
  let(:view_options) { {} }
23
21
 
24
22
 
25
23
  describe ".datagrid_filter" do
26
-
27
24
  it "should work for every filter type" do
28
25
  Datagrid::Filters::FILTER_TYPES.each do |type, klass|
29
26
  expect(Datagrid::FormBuilder.instance_methods.map(&:to_sym)).to include(klass.form_builder_helper_name)
@@ -154,34 +151,8 @@ describe Datagrid::FormBuilder do
154
151
  ) }
155
152
 
156
153
  end
157
-
158
- context "when deprecated format translation specified" do
159
- let(:_range) { nil }
160
- around(:each) do |example|
161
- store_translations(:en, datagrid: {filters: {integer: {range_format: "from %{from_input} to %{to_input}"}}}) do
162
- silence_warnings do
163
- example.run
164
- end
165
- end
166
- end
167
- it { should equal_to_dom(
168
- 'from <input class="group_id integer_filter from" multiple type="text" name="report[group_id][]"> to <input class="group_id integer_filter to" multiple type="text" name="report[group_id][]">'
169
- )}
170
- end
171
- context "when deprecated separator is specified" do
172
- let(:_range) { nil }
173
- around(:each) do |example|
174
- store_translations(:en, datagrid: {filters: {integer: {range_separator: " | "}}}) do
175
- silence_warnings do
176
- example.run
177
- end
178
- end
179
- end
180
- it { should equal_to_dom(
181
- '<input class="group_id integer_filter from" multiple type="text" name="report[group_id][]"> | <input class="group_id integer_filter to" multiple type="text" name="report[group_id][]">'
182
- )}
183
- end
184
154
  end
155
+
185
156
  context "with float filter type and range option" do
186
157
  let(:_filter) { :rating }
187
158
  let(:_grid) {
@@ -198,7 +169,6 @@ describe Datagrid::FormBuilder do
198
169
  )}
199
170
  end
200
171
 
201
-
202
172
  context "with date filter type and range option" do
203
173
  let(:_filter) { :created_at }
204
174
  let(:_grid) {
@@ -1,16 +1,13 @@
1
1
  require 'spec_helper'
2
2
  require "active_support/core_ext/hash"
3
3
  require "active_support/core_ext/object"
4
+ require "action_controller"
4
5
 
5
6
  require 'datagrid/renderer'
6
7
 
7
8
  describe Datagrid::Helper do
8
9
  subject do
9
- template = ActionView::Base.new
10
- allow(template).to receive(:protect_against_forgery?).and_return(false)
11
- template.view_paths << File.expand_path("../../../app/views", __FILE__)
12
- template.view_paths << File.expand_path("../../support/test_partials", __FILE__)
13
- template
10
+ action_view_template
14
11
  end
15
12
 
16
13
  before(:each) do
@@ -44,7 +41,7 @@ describe Datagrid::Helper do
44
41
  expect(datagrid_table).to match_css_pattern(
45
42
  "table.datagrid tr td.noresults" => 1
46
43
  )
47
- expect(datagrid_table).to include("&mdash;&mdash;")
44
+ expect(datagrid_table).to include(I18n.t("datagrid.no_results"))
48
45
  end
49
46
  end
50
47
 
@@ -248,6 +245,17 @@ describe Datagrid::Helper do
248
245
  )
249
246
  end
250
247
 
248
+ it "should render columns with &:symbol block" do
249
+ rp = test_report do
250
+ scope { Entry }
251
+ column(:name, &:name)
252
+ end
253
+
254
+ expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern(
255
+ "tr td.name" => "Star"
256
+ )
257
+ end
258
+
251
259
  it "should render html columns" do
252
260
  rp = test_report do
253
261
  scope { Entry }
@@ -260,6 +268,41 @@ describe Datagrid::Helper do
260
268
  )
261
269
  end
262
270
 
271
+ it "should render :html columns with &:symbol block" do
272
+ rp = test_report do
273
+ scope { Entry }
274
+ column(:name, :html => true, &:name)
275
+ end
276
+
277
+ expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern(
278
+ "tr td.name" => "Star"
279
+ )
280
+ end
281
+
282
+ it "should render format columns with &:symbol block" do
283
+ rp = test_report do
284
+ scope { Entry }
285
+ column(:name) do |record|
286
+ format(record, &:name)
287
+ end
288
+ end
289
+
290
+ expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern(
291
+ "tr td.name" => "Star"
292
+ )
293
+ end
294
+
295
+ it "should render :html columns with &:symbol block with a data attribute" do
296
+ rp = test_report do
297
+ scope { Entry }
298
+ column(:name, :html => true, data: 'DATA', &:name)
299
+ end
300
+
301
+ expect(subject.datagrid_rows(rp, [entry])).to match_css_pattern(
302
+ "tr td.name" => "Star"
303
+ )
304
+ end
305
+
263
306
  it "should render argument-based html columns" do
264
307
  rp = test_report do
265
308
  scope { Entry }
@@ -389,14 +432,14 @@ describe Datagrid::Helper do
389
432
  end
390
433
 
391
434
  it "should escape html" do
392
- entry.update_attributes!(:name => "<div>hello</div>")
435
+ entry.update!(:name => "<div>hello</div>")
393
436
  expect(subject.datagrid_rows(grid, [entry], :columns => [:name])).to equal_to_dom(<<-HTML)
394
437
  <tr><td class="name">&lt;div&gt;hello&lt;/div&gt;</td></tr>
395
438
  HTML
396
439
  end
397
440
 
398
441
  it "should not escape safe html" do
399
- entry.update_attributes!(:name => "<div>hello</div>")
442
+ entry.update!(:name => "<div>hello</div>")
400
443
  grid.column(:safe_name) do |model|
401
444
  model.name.html_safe
402
445
  end
@@ -599,6 +642,21 @@ describe Datagrid::Helper do
599
642
  expect(subject.datagrid_value(report, :name, entry)).to eq("<a href=\"/profile\">Star</a>")
600
643
  end
601
644
 
645
+ it "applies decorator" do
646
+ report = test_report do
647
+ scope {Entry}
648
+ decorate do |model|
649
+ Class.new(Struct.new(:model)) do
650
+ def name
651
+ model.name.upcase
652
+ end
653
+ end
654
+ end
655
+ column(:name, html: true)
656
+ end
657
+ entry = Entry.create!(name: 'hello')
658
+ expect(subject.datagrid_value(report, :name, entry)).to eq("HELLO")
659
+ end
602
660
  end
603
661
 
604
662
  describe ".datagrid_header" do
@@ -28,10 +28,16 @@ describe Datagrid::Scaffold do
28
28
  it "works" do
29
29
  expect(subject.index_action).to eq(<<-RUBY)
30
30
  def index
31
- @grid = UsersGrid.new(params[:users_grid]) do |scope|
31
+ @grid = UsersGrid.new(grid_params) do |scope|
32
32
  scope.page(params[:page])
33
33
  end
34
34
  end
35
+
36
+ protected
37
+
38
+ def grid_params
39
+ params.fetch(:users_grid, {}).permit!
40
+ end
35
41
  RUBY
36
42
  end
37
43
 
@@ -60,8 +60,8 @@ describe Datagrid do
60
60
 
61
61
  describe ".batch_size" do
62
62
  context "when not defined on class level" do
63
- it "returns nil" do
64
- expect(subject.batch_size).to eq(nil)
63
+ it "returns 1000" do
64
+ expect(subject.batch_size).to eq(1000)
65
65
  end
66
66
  end
67
67
 
@@ -77,6 +77,17 @@ describe Datagrid do
77
77
  end
78
78
  end
79
79
 
80
+ context "when set to nil in the grid class" do
81
+ subject do
82
+ test_report do
83
+ self.batch_size = nil
84
+ end
85
+ end
86
+
87
+ it "returns nil" do
88
+ expect(subject.batch_size).to eq(nil)
89
+ end
90
+ end
80
91
  end
81
92
 
82
93
 
@@ -17,7 +17,7 @@ require 'action_view'
17
17
  require "rails"
18
18
  require "mongoid"
19
19
  begin
20
- require 'mongo_mapper'
20
+ require 'mongo_mapper'
21
21
  rescue LoadError
22
22
  end
23
23
 
@@ -55,9 +55,11 @@ begin
55
55
  "database" =>"datagrid_mongoid",
56
56
  "autocreate_indexes" => true,
57
57
  "logger" => nil,
58
- "options" => {
59
- "connect_timeout" => 2,
60
- wait_queue_timeout: 2
58
+ options: {
59
+ connect_timeout: 2,
60
+ wait_queue_timeout: 2,
61
+ server_selection_timeout: 2,
62
+ socket_timeout: 1
61
63
  }
62
64
  }
63
65
  }
@@ -80,8 +82,6 @@ rescue Mongo::Error::NoServerAvailable
80
82
  end
81
83
 
82
84
  RSpec.configure do |config|
83
-
84
-
85
85
  config.after(:each) do
86
86
  #TODO better database truncation
87
87
  Group.delete_all
@@ -103,12 +103,21 @@ RSpec.configure do |config|
103
103
  #c.syntax = :expect
104
104
  c.syntax = [:should, :expect]
105
105
  end
106
+ end
106
107
 
108
+ def action_view_template
109
+ context = ActionView::LookupContext.new([
110
+ File.expand_path("../../app/views", __FILE__),
111
+ File.expand_path("../support/test_partials", __FILE__),
112
+ ], {})
113
+ klass = ActionView::Base.respond_to?(:with_empty_template_cache) ? ActionView::Base.with_empty_template_cache : ActionView::Base
114
+ template = klass.new(context, {}, ::ActionController::Base.new)
115
+ allow(template).to receive(:protect_against_forgery?).and_return(false)
116
+ template
107
117
  end
108
118
 
109
119
 
110
120
 
111
121
  # Requires supporting files with custom matchers and macros, etc,
112
122
  # in ./support/ and its subdirectories.
113
- Dir["#{File.dirname(__FILE__)}/support/schema.rb"].each {|f| require f}
114
123
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
@@ -1,3 +1,4 @@
1
+ require "sqlite3"
1
2
 
2
3
  ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
3
4
  #ActiveRecord::Base.configurations = true
@@ -45,7 +45,7 @@ class SimpleReport
45
45
  end
46
46
 
47
47
  column(:actions, :html => true) do |model|
48
- render :partial => "actions", :locals => {:model => model}
48
+ render :partial => "/actions", :locals => {:model => model}
49
49
  end
50
50
 
51
51
  column(:pet, :html => lambda {|data| content_tag :em, data}) do
@@ -2,10 +2,10 @@
2
2
  <p>Namespaced order_for partial.</p>
3
3
  <%= link_to(
4
4
  I18n.t("datagrid.table.order.asc").html_safe,
5
- url_for(grid.param_name => grid.as_query.merge(:order => column.name, :descending => false)),
5
+ url_for(grid.query_params(order: column.name, descending: false)),
6
6
  :class => "asc") %>
7
7
  <%= link_to(
8
8
  I18n.t("datagrid.table.order.desc").html_safe,
9
- url_for(grid.param_name => grid.as_query.merge(:order => column.name, :descending => true )),
9
+ url_for(grid.query_params(order: column.name, descending: true)),
10
10
  :class => "desc") %>
11
11
  </div>
@@ -13,7 +13,7 @@ Local variables:
13
13
  <% if assets.empty? %>
14
14
  <tr><td class="noresults" colspan="100%"><%= I18n.t('datagrid.no_results').html_safe %></td></tr>
15
15
  <% else %>
16
- <%= datagrid_rows(grid, assets, options) %>
16
+ <%= datagrid_rows(grid, assets, **options) %>
17
17
  <% end %>
18
18
  </tbody>
19
19
  <% end %>
@@ -8,6 +8,8 @@ class BaseGrid
8
8
  # Uncomment to make all columns HTML by default
9
9
  # html: true,
10
10
  }
11
+ # Enable forbidden attributes protection
12
+ # self.forbidden_attributes_protection = true
11
13
 
12
14
  def self.date_column(name, *args)
13
15
  column(name, *args) do |model|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datagrid
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.6
4
+ version: 1.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bogdan Gusiev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-30 00:00:00.000000000 Z
11
+ date: 2020-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -98,16 +98,16 @@ dependencies:
98
98
  name: sqlite3
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ">="
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '0'
103
+ version: '1.4'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ">="
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '0'
110
+ version: '1.4'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: sequel
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -171,6 +171,7 @@ executables: []
171
171
  extensions: []
172
172
  extra_rdoc_files:
173
173
  - LICENSE.txt
174
+ - Readme.markdown
174
175
  files:
175
176
  - ".document"
176
177
  - ".rspec"
@@ -284,7 +285,7 @@ homepage: http://github.com/bogdan/datagrid
284
285
  licenses:
285
286
  - MIT
286
287
  metadata: {}
287
- post_install_message:
288
+ post_install_message:
288
289
  rdoc_options: []
289
290
  require_paths:
290
291
  - lib
@@ -299,9 +300,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
299
300
  - !ruby/object:Gem::Version
300
301
  version: '0'
301
302
  requirements: []
302
- rubyforge_project:
303
- rubygems_version: 2.6.7
304
- signing_key:
303
+ rubygems_version: 3.0.8
304
+ signing_key:
305
305
  specification_version: 4
306
306
  summary: Ruby gem to create datagrids
307
307
  test_files: []