datagrid 1.7.0 → 1.8.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
2
  SHA256:
3
- metadata.gz: cae619097e4bcae30de30bf2b5e9dc949f197146f3b17c01f5a2e4edb17e5ecc
4
- data.tar.gz: 61751f34844c4127b7fc47bbacdbb2656d61aa015f574855de2a23bfc2dffe4a
3
+ metadata.gz: 6b7756de5445c9c99d265a897b609b9f3dcf6dbf0b03e32455ca96518bf01eea
4
+ data.tar.gz: 7f748c1a7075331672e749d582145deacc1d38977ada1770b6d7b548d9bb17c9
5
5
  SHA512:
6
- metadata.gz: 8bcea069b9bafc8b573226366a1abf194910d3fa5798711568b7106428d94ec915b141f23986094d8579ce8450328e1eb5b71932646c4224c0f1f7ac01f9718b
7
- data.tar.gz: 7a40443171fe84d7b9f22daabdf2d1c182926fc69c9b47fde54e5a2271c394b8b5f7541a512e898c4e1472f93f4e94cf9cb90a7d47a9ad51113ee65efaf80610
6
+ metadata.gz: 8acee3003f7a9e63ec80808221667fa530f74d882c88d06ce20855b97bf75ec806a6eb5ddf89c9f47044d943238d74c33fcfd290c78d8d4e6e31a3081f4f6e83
7
+ data.tar.gz: 54d4cb553c0a82068d905e8367bffb18298d215b3a0ae09be4b09fa2f77dfe1cc299e019c080d3b689d897f2f38dba217bdef5200284bebadc8ccb1b9ce83644
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## master
2
+
3
+ ## 1.8.0
4
+
5
+ * Support `input_options: {type: "textarea"}` as `<textarea/>` tag
6
+ * Remove deprecated `eboolean` filter
7
+ * Fixed scope wrapping to be universal
8
+ * Deprecated `integer_range_filters` and `date_range_filters`. Use `filter(name, type, range: true)` instead.
9
+ * Add `original_scope` method that returns scope as it was defined without any wrapping [#313](https://github.com/bogdan/datagrid/pull/313)
10
+ * Add ability to specify `columns` option for `datagrid_row`. [#314](https://github.com/bogdan/datagrid/pull/314)
11
+
1
12
  ## 1.7.0
2
13
 
3
14
  * Depend on `railties` instead of `rails` to prevent loading of unnecessary frameworks
data/Readme.markdown CHANGED
@@ -4,9 +4,9 @@
4
4
 
5
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
6
 
7
- Ruby library that helps you to build and represent table-like data with:
7
+ A really mighty and flexible ruby library that generates reports including admin panels, analytics and data representation:
8
8
 
9
- * Customizable filtering
9
+ * Filtering
10
10
  * Columns
11
11
  * Sort order
12
12
  * Localization
@@ -54,7 +54,7 @@ class UsersGrid
54
54
  filter(:group_id, :integer, multiple: true)
55
55
  filter(:logins_count, :integer, range: true)
56
56
  filter(:group_name, :string, header: "Group") do |value|
57
- self.joins(:group).where(:groups => {:name => value})
57
+ self.joins(:group).where(groups: {name: value})
58
58
  end
59
59
 
60
60
  column(:name)
@@ -72,11 +72,11 @@ Basic grid api:
72
72
 
73
73
  ``` ruby
74
74
  report = UsersGrid.new(
75
- :group_id => [1,2],
76
- :logins_count => [1, nil],
77
- :category => "first",
78
- :order => :group,
79
- :descending => true
75
+ group_id: [1,2],
76
+ logins_count: [1, nil],
77
+ category: "first",
78
+ order: :group,
79
+ descending: true
80
80
  )
81
81
 
82
82
  report.assets # => Array of User instances:
@@ -145,7 +145,7 @@ Datagrid supports different type of filters including:
145
145
  Each column is represented by name and code block to calculate the value.
146
146
 
147
147
  ``` ruby
148
- column(:activated, :header => "Active", :order => "activated", :after => :name) do
148
+ column(:activated, header: "Active", order: "activated", after: :name) do
149
149
  self.activated?
150
150
  end
151
151
  ```
@@ -4,8 +4,8 @@ You can add indent if whitespace doesn't matter for you
4
4
  %>
5
5
  <%- elements.each do |value, text, checked| -%>
6
6
  <%- id = [form.object_name, filter.name, value].join('_').underscore -%>
7
- <%= form.label filter.name, options.merge(:for => id) do -%>
8
- <%= form.check_box(filter.name, {:multiple => true, :id => id, :checked => checked, :include_hidden => false}, value.to_s, nil) -%>
7
+ <%= form.label filter.name, options.merge(for: id) do -%>
8
+ <%= form.check_box(filter.name, {multiple: true, id: id, checked: checked, include_hidden: false}, value.to_s, nil) -%>
9
9
  <%= text -%>
10
10
  <%- end -%>
11
11
  <%- end -%>
@@ -6,9 +6,8 @@
6
6
  </div>
7
7
  <% end %>
8
8
  <div class="datagrid-actions">
9
- <%= f.submit I18n.t("datagrid.form.search").html_safe, :class => "datagrid-submit" %>
9
+ <%= f.submit I18n.t("datagrid.form.search").html_safe, class: "datagrid-submit" %>
10
10
  <%# https://github.com/rails/rails/pull/14949 -%>
11
- <% empty_parameter = Rails.version >= "4.1.0" && Rails.version <= '4.1.2' ? nil : {}-%>
12
- <%= link_to I18n.t('datagrid.form.reset').html_safe, url_for(grid.to_param => empty_parameter), :class => "datagrid-reset" %>
11
+ <%= link_to I18n.t('datagrid.form.reset').html_safe, url_for(grid.to_param => {}), class: "datagrid-reset" %>
13
12
  </div>
14
13
  <% end -%>
@@ -2,9 +2,9 @@
2
2
  <%= link_to(
3
3
  I18n.t("datagrid.table.order.asc").html_safe,
4
4
  datagrid_order_path(grid, column, false),
5
- :class => "asc") %>
5
+ class: "asc") %>
6
6
  <%= link_to(
7
7
  I18n.t("datagrid.table.order.desc").html_safe,
8
8
  datagrid_order_path(grid, column, true),
9
- :class => "desc") %>
9
+ class: "desc") %>
10
10
  </div>
@@ -1,3 +1,3 @@
1
- <%= form.text_field(filter.name, from_options) %>
2
- <span class="separator <%= filter.type %>"> - </span>
3
- <%= form.text_field(filter.name, to_options) %>
1
+ <%= form.datagrid_filter_input(filter, **from_options) %>
2
+ <span class="separator <%= filter.type %>"><%= I18n.t('datagrid.filters.range.separator') %></span>
3
+ <%= form.datagrid_filter_input(filter, **to_options) %>
@@ -17,7 +17,7 @@ module Datagrid
17
17
  # Adds a filter that acts like a column selection
18
18
  # All defined columns will be available to select/deselect
19
19
  # as a multi-select enum filter.
20
- # Columns with <tt>:mandatory => true</tt> option
20
+ # Columns with <tt>mandatory: true</tt> option
21
21
  # will always present in the grid table and won't be listed
22
22
  # in column names selection
23
23
  # Accepts same options as <tt>:enum</tt> filter
@@ -47,7 +47,7 @@ module Datagrid
47
47
  available_columns.select {|c| c.mandatory? }
48
48
  end
49
49
 
50
- # Returns a list of enabled columns without <tt>:mandatory => true</tt> option
50
+ # Returns a list of enabled columns without <tt>mandatory: true</tt> option
51
51
  # If no mandatory columns specified than all of them considered mandatory but not optional
52
52
  # @return [Array<Datagrid::Columns::Column>]
53
53
  def optional_columns
@@ -133,24 +133,24 @@ class Datagrid::Columns::Column
133
133
  grid.generic_value(self, model)
134
134
  end
135
135
 
136
- def append_preload(scope)
137
- return scope unless preload
136
+ def append_preload(relation)
137
+ return relation unless preload
138
138
  if preload.respond_to?(:call)
139
- return scope unless preload
139
+ return relation unless preload
140
140
  if preload.arity == 1
141
- preload.call(scope)
141
+ preload.call(relation)
142
142
  else
143
- scope.instance_exec(&preload)
143
+ relation.instance_exec(&preload)
144
144
  end
145
145
  else
146
- driver.default_preload(scope, preload)
146
+ driver.default_preload(relation, preload)
147
147
  end
148
148
  end
149
149
 
150
150
  def preload
151
151
  preload = options[:preload]
152
152
 
153
- if preload == true && driver.can_preload?(driver.to_scope(grid_class.scope), name)
153
+ if preload == true && driver.can_preload?(grid_class.scope, name)
154
154
  name
155
155
  else
156
156
  preload
@@ -44,13 +44,11 @@ module Datagrid
44
44
  class_attribute :cached, default: false
45
45
  class_attribute :decorator, instance_writer: false
46
46
  end
47
- base.send :include, InstanceMethods
47
+ base.include InstanceMethods
48
48
  end
49
49
 
50
50
  module ClassMethods
51
51
 
52
-
53
-
54
52
  # @param data [Boolean] if true returns only columns with data representation. Default: false.
55
53
  # @param html [Boolean] if true returns only columns with html columns. Default: false.
56
54
  # @param column_names [Array<String>] list of column names if you want to limit data only to specified columns
@@ -446,8 +444,8 @@ module Datagrid
446
444
 
447
445
  protected
448
446
 
449
- def append_column_preload(scope)
450
- columns.inject(scope) do |current, column|
447
+ def append_column_preload(relation)
448
+ columns.inject(relation) do |current, column|
451
449
  column.append_preload(current)
452
450
  end
453
451
  end
data/lib/datagrid/core.rb CHANGED
@@ -6,7 +6,7 @@ module Datagrid
6
6
 
7
7
  # @!visibility private
8
8
  def self.included(base)
9
- base.extend ClassMethods
9
+ base.extend ClassMethods
10
10
  base.class_eval do
11
11
  class_attribute :scope_value
12
12
 
@@ -20,7 +20,7 @@ module Datagrid
20
20
  include ::ActiveModel::AttributeAssignment
21
21
  end
22
22
  end
23
- base.send :include, InstanceMethods
23
+ base.include InstanceMethods
24
24
  end
25
25
 
26
26
  module ClassMethods
@@ -56,14 +56,20 @@ module Datagrid
56
56
  }
57
57
  self
58
58
  else
59
- check_scope_defined!
60
- scope_value.call
59
+ scope = original_scope
60
+ driver.to_scope(scope)
61
61
  end
62
62
  end
63
63
 
64
+ # @!visibility private
65
+ def original_scope
66
+ check_scope_defined!
67
+ scope_value.call
68
+ end
69
+
64
70
  # @!visibility private
65
71
  def driver
66
- @driver ||= Drivers::AbstractDriver.guess_driver(scope).new
72
+ @driver ||= Drivers::AbstractDriver.guess_driver(scope_value.call).new
67
73
  end
68
74
 
69
75
  # Allows dynamic columns definition, that could not be defined at class level
@@ -162,7 +168,7 @@ module Datagrid
162
168
 
163
169
  # @return [Object] a scope relation (e.g ActiveRecord::Relation) with all applied filters
164
170
  def assets
165
- driver.to_scope(scope)
171
+ scope
166
172
  end
167
173
 
168
174
  # Updates datagrid attributes with a passed hash argument
@@ -222,11 +228,17 @@ module Datagrid
222
228
  }
223
229
  self
224
230
  else
225
- check_scope_defined!
226
- scope_value.call
231
+ scope = original_scope
232
+ driver.to_scope(scope)
227
233
  end
228
234
  end
229
235
 
236
+ # @!visibility private
237
+ def original_scope
238
+ check_scope_defined!
239
+ scope_value.call
240
+ end
241
+
230
242
  # Resets current instance scope to default scope defined in a class
231
243
  # @return [void]
232
244
  def reset_scope
@@ -19,7 +19,7 @@ module Datagrid
19
19
  # We can only reveal it by checking if it respond to some specific
20
20
  # to ActiveRecord method like #scoped
21
21
  if scope.is_a?(Class)
22
- Rails.version >= "4.0" ? scope.all : scope.scoped({})
22
+ scope.all
23
23
  elsif scope.respond_to?(:scoped)
24
24
  scope.scoped
25
25
  else
@@ -43,7 +43,7 @@ module Datagrid
43
43
  end
44
44
 
45
45
  def asc(scope, order)
46
- # Rails 3.x.x don't able to override already applied order
46
+ # Relation#order isn't able to override already applied order
47
47
  # Using #reorder instead
48
48
  scope.reorder(order)
49
49
  end
@@ -82,8 +82,12 @@ module Datagrid
82
82
  end
83
83
 
84
84
  def batch_each(scope, batch_size, &block)
85
- scope.extension(:pagination).each_page(batch_size) do |page|
86
- page.each(&block)
85
+ if scope.opts[:limit]
86
+ scope.each(&block)
87
+ else
88
+ scope.extension(:pagination).each_page(batch_size) do |page|
89
+ page.each(&block)
90
+ end
87
91
  end
88
92
  end
89
93
 
@@ -6,6 +6,7 @@ end
6
6
  # @!visibility private
7
7
  class Datagrid::Filters::BaseFilter
8
8
 
9
+ class_attribute :input_helper_name, instance_writer: false
9
10
  attr_accessor :grid_class, :options, :block, :name
10
11
 
11
12
  def initialize(grid_class, name, options = {}, &block)
@@ -172,8 +173,8 @@ class Datagrid::Filters::BaseFilter
172
173
 
173
174
  def default_filter(value, scope, grid)
174
175
  return nil if dummy?
175
- if !driver.has_column?(scope, name) && driver.to_scope(scope).respond_to?(name)
176
- driver.to_scope(scope).send(name, value)
176
+ if !driver.has_column?(scope, name) && scope.respond_to?(name)
177
+ scope.send(name, value)
177
178
  else
178
179
  default_filter_where(scope, value)
179
180
  end
@@ -13,6 +13,7 @@ module Datagrid
13
13
  module ClassMethods
14
14
 
15
15
  def date_range_filters(field, from_options = {}, to_options = {})
16
+ Utils.warn_once('date_range_filters is deprecated in favor of range option for date filter')
16
17
  from_options = normalize_composite_filter_options(from_options, field)
17
18
  to_options = normalize_composite_filter_options(to_options, field)
18
19
 
@@ -25,6 +26,7 @@ module Datagrid
25
26
  end
26
27
 
27
28
  def integer_range_filters(field, from_options = {}, to_options = {})
29
+ Utils.warn_once('integer_range_filters is deprecated in favor of range option for integer filter')
28
30
  from_options = normalize_composite_filter_options(from_options, field)
29
31
  to_options = normalize_composite_filter_options(to_options, field)
30
32
  filter(from_options[:name] || :"from_#{field.to_s.tr('.', '_')}", :integer, **from_options) do |value, scope, grid|
@@ -37,7 +39,7 @@ module Datagrid
37
39
 
38
40
  def normalize_composite_filter_options(options, field)
39
41
  if options.is_a?(String) || options.is_a?(Symbol)
40
- options = {:name => options}
42
+ options = {name: options}
41
43
  end
42
44
  options
43
45
  end
@@ -80,7 +80,7 @@ class Datagrid::Filters::DynamicFilter < Datagrid::Filters::BaseFilter
80
80
 
81
81
  def operations_select
82
82
  operations.map do |operation|
83
- [I18n.t(operation, :scope => "datagrid.filters.dynamic.operations").html_safe, operation]
83
+ [I18n.t(operation, scope: "datagrid.filters.dynamic.operations").html_safe, operation]
84
84
  end
85
85
  end
86
86
 
@@ -5,7 +5,6 @@ module Datagrid
5
5
 
6
6
  require "datagrid/filters/base_filter"
7
7
  require "datagrid/filters/enum_filter"
8
- require "datagrid/filters/boolean_enum_filter"
9
8
  require "datagrid/filters/extended_boolean_filter"
10
9
  require "datagrid/filters/boolean_filter"
11
10
  require "datagrid/filters/date_filter"
@@ -18,24 +17,23 @@ module Datagrid
18
17
  require "datagrid/filters/dynamic_filter"
19
18
 
20
19
  FILTER_TYPES = {
21
- :date => Filters::DateFilter,
22
- :datetime => Filters::DateTimeFilter,
23
- :string => Filters::StringFilter,
24
- :default => Filters::DefaultFilter,
25
- :eboolean => Filters::BooleanEnumFilter ,
26
- :xboolean => Filters::ExtendedBooleanFilter ,
27
- :boolean => Filters::BooleanFilter ,
28
- :integer => Filters::IntegerFilter,
29
- :enum => Filters::EnumFilter,
30
- :float => Filters::FloatFilter,
31
- :dynamic => Filters::DynamicFilter
20
+ date: Filters::DateFilter,
21
+ datetime: Filters::DateTimeFilter,
22
+ string: Filters::StringFilter,
23
+ default: Filters::DefaultFilter,
24
+ xboolean: Filters::ExtendedBooleanFilter ,
25
+ boolean: Filters::BooleanFilter ,
26
+ integer: Filters::IntegerFilter,
27
+ enum: Filters::EnumFilter,
28
+ float: Filters::FloatFilter,
29
+ dynamic: Filters::DynamicFilter
32
30
  }
33
31
 
34
32
  DEFAULT_FILTER_BLOCK = Object.new
35
33
 
36
34
  # @!visibility private
37
35
  def self.included(base)
38
- base.extend ClassMethods
36
+ base.extend ClassMethods
39
37
  base.class_eval do
40
38
 
41
39
  include Datagrid::Core
@@ -44,7 +42,7 @@ module Datagrid
44
42
  self.filters_array = []
45
43
 
46
44
  end
47
- base.send :include, InstanceMethods
45
+ base.include InstanceMethods
48
46
  end
49
47
 
50
48
  module ClassMethods
@@ -95,7 +93,8 @@ module Datagrid
95
93
  # Accepts a block or a symbol with an instance method name
96
94
  # * <tt>:unless</tt> - specify the reverse condition when the filter can be dislayed and used.
97
95
  # Accepts a block or a symbol with an instance method name
98
- # * <tt>:input_options</tt> - options passed when rendering html input tag attributes
96
+ # * <tt>:input_options</tt> - options passed when rendering html input tag attributes.
97
+ # Use <tt>input_options.type</tt> to control input type including <tt>textarea</tt>.
99
98
  # * <tt>:label_options</tt> - options passed when rendering html label tag attributes
100
99
  #
101
100
  # See: https://github.com/bogdan/datagrid/wiki/Filters for examples
@@ -8,15 +8,14 @@ module Datagrid
8
8
  # * <tt>select</tt> for enum, xboolean filter types
9
9
  # * <tt>check_box</tt> for boolean filter type
10
10
  # * <tt>text_field</tt> for other filter types
11
- def datagrid_filter(filter_or_attribute, options = {}, &block)
11
+ def datagrid_filter(filter_or_attribute, partials: nil, **options, &block)
12
12
  filter = datagrid_get_filter(filter_or_attribute)
13
- options = {
13
+ self.send(
14
+ filter.form_builder_helper_name, filter,
14
15
  **filter.input_options,
15
16
  **add_html_classes(options, filter.name, datagrid_filter_html_class(filter)),
16
- }
17
- # Prevent partials option from appearing in HTML attributes
18
- options.delete(:partials) # Legacy option
19
- self.send(filter.form_builder_helper_name, filter, options, &block)
17
+ &block
18
+ )
20
19
  end
21
20
 
22
21
  # @param filter_or_attribute [Datagrid::Filters::BaseFilter, String, Symbol] filter object or filter name
@@ -28,11 +27,17 @@ module Datagrid
28
27
  label(filter.name, text || filter.header, **filter.label_options, **options, &block)
29
28
  end
30
29
 
31
- protected
32
- def datagrid_boolean_enum_filter(attribute_or_filter, options = {})
33
- datagrid_enum_filter(attribute_or_filter, options)
30
+ def datagrid_filter_input(attribute_or_filter, **options)
31
+ filter = datagrid_get_filter(attribute_or_filter)
32
+ value = object.filter_value_as_string(filter)
33
+ if options[:type]&.to_sym == :textarea
34
+ text_area filter.name, value: value, **options, type: nil
35
+ else
36
+ text_field filter.name, value: value, **options
37
+ end
34
38
  end
35
39
 
40
+ protected
36
41
  def datagrid_extended_boolean_filter(attribute_or_filter, options = {})
37
42
  datagrid_enum_filter(attribute_or_filter, options)
38
43
  end
@@ -50,27 +55,25 @@ module Datagrid
50
55
  end
51
56
 
52
57
  def datagrid_default_filter(attribute_or_filter, options = {})
53
- filter = datagrid_get_filter(attribute_or_filter)
54
- text_field filter.name, value: object.filter_value_as_string(filter), **options
58
+ datagrid_filter_input(attribute_or_filter, **options)
55
59
  end
56
60
 
57
61
  def datagrid_enum_filter(attribute_or_filter, options = {}, &block)
58
62
  filter = datagrid_get_filter(attribute_or_filter)
59
63
  if filter.checkboxes?
60
- partial = partial_path('enum_checkboxes')
61
64
  options = add_html_classes(options, 'checkboxes')
62
65
  elements = object.select_options(filter).map do |element|
63
66
  text, value = @template.send(:option_text_and_value, element)
64
67
  checked = enum_checkbox_checked?(filter, value)
65
68
  [value, text, checked]
66
69
  end
67
- @template.render(
68
- :partial => partial,
69
- :locals => {
70
- :elements => elements,
71
- :form => self,
72
- :filter => filter,
73
- :options => options,
70
+ render_partial(
71
+ 'enum_checkboxes',
72
+ {
73
+ elements: elements,
74
+ form: self,
75
+ filter: filter,
76
+ options: options,
74
77
  }
75
78
  )
76
79
  else
@@ -112,21 +115,26 @@ module Datagrid
112
115
  filter = datagrid_get_filter(attribute_or_filter)
113
116
  input_name = "#{object_name}[#{filter.name.to_s}][]"
114
117
  field, operation, value = object.filter_value(filter)
115
- options = options.merge(:name => input_name)
118
+ options = options.merge(name: input_name)
116
119
  field_input = dynamic_filter_select(
117
120
  filter.name,
118
121
  object.select_options(filter) || [],
119
122
  {
120
- :include_blank => filter.include_blank,
121
- :prompt => filter.prompt,
122
- :include_hidden => false,
123
- :selected => field
123
+ include_blank: filter.include_blank,
124
+ prompt: filter.prompt,
125
+ include_hidden: false,
126
+ selected: field
124
127
  },
125
128
  add_html_classes(options, "field")
126
129
  )
127
130
  operation_input = dynamic_filter_select(
128
131
  filter.name, filter.operations_select,
129
- {:include_blank => false, :include_hidden => false, :prompt => false, :selected => operation },
132
+ {
133
+ include_blank: false,
134
+ include_hidden: false,
135
+ prompt: false,
136
+ selected: operation,
137
+ },
130
138
  add_html_classes(options, "operation")
131
139
  )
132
140
  value_input = text_field(filter.name, **add_html_classes(options, "value"), value: value)
@@ -148,20 +156,19 @@ module Datagrid
148
156
  def datagrid_range_filter(type, attribute_or_filter, options = {})
149
157
  filter = datagrid_get_filter(attribute_or_filter)
150
158
  if filter.range?
151
- partial = partial_path('range_filter')
152
- options = options.merge(:multiple => true)
159
+ options = options.merge(multiple: true)
153
160
  from_options = datagrid_range_filter_options(object, filter, :from, options)
154
161
  to_options = datagrid_range_filter_options(object, filter, :to, options)
155
- @template.render :partial => partial, :locals => {
156
- :from_options => from_options, :to_options => to_options, :filter => filter, :form => self
162
+ render_partial 'range_filter', {
163
+ from_options: from_options, to_options: to_options, filter: filter, form: self
157
164
  }
158
165
  else
159
- datagrid_default_filter(filter, options)
166
+ datagrid_filter_input(filter, **options)
160
167
  end
161
168
  end
162
169
 
163
170
  def datagrid_range_filter_options(object, filter, type, options)
164
- type_method_map = {:from => :first, :to => :last}
171
+ type_method_map = {from: :first, to: :last}
165
172
  options = add_html_classes(options, type)
166
173
  options[:value] = filter.format(object[filter.name].try(type_method_map[type]))
167
174
  # In case of datagrid ranged filter
@@ -179,7 +186,7 @@ module Datagrid
179
186
  end
180
187
 
181
188
  def datagrid_string_filter(attribute_or_filter, options = {})
182
- datagrid_default_filter(attribute_or_filter, options)
189
+ datagrid_range_filter(:string, attribute_or_filter, options)
183
190
  end
184
191
 
185
192
  def datagrid_float_filter(attribute_or_filter, options = {})
@@ -218,6 +225,10 @@ module Datagrid
218
225
  File.join('datagrid', name)
219
226
  end
220
227
 
228
+ def render_partial(name, locals)
229
+ @template.render partial: partial_path(name), locals: locals
230
+ end
231
+
221
232
  class Error < StandardError
222
233
  end
223
234
  end
@@ -52,6 +52,9 @@ module Datagrid
52
52
  #
53
53
  # * <tt>:order</tt> - display ordering controls built-in into header
54
54
  # Default: true
55
+ # * <tt>:columns</tt> - Array of column names to display.
56
+ # Used in case when same grid class is used in different places
57
+ # and needs different columns. Default: all defined columns.
55
58
  # * <tt>:partials</tt> - Path for partials lookup.
56
59
  # Default: 'datagrid'.
57
60
  # @param grid [Datagrid] grid object
@@ -124,12 +127,10 @@ module Datagrid
124
127
  # <% row = datagrid_row(grid, user) %>
125
128
  # First Name: <%= row.first_name %>
126
129
  # Last Name: <%= row.last_name %>
127
- def datagrid_row(grid, asset, &block)
128
- HtmlRow.new(self, grid, asset).tap do |row|
129
- if block_given?
130
- return capture(row, &block)
131
- end
132
- end
130
+ # @example
131
+ # <%= datagrid_row(grid, user, columns: [:first_name, :last_name, :actions]) %>
132
+ def datagrid_row(grid, asset, **options, &block)
133
+ datagrid_renderer.row(grid, asset, **options, &block)
133
134
  end
134
135
 
135
136
  # Generates an ascending or descending order url for the given column
@@ -141,51 +142,6 @@ module Datagrid
141
142
  datagrid_renderer.order_path(grid, column, descending, request)
142
143
  end
143
144
 
144
- # Represents a datagrid row that provides access to column values for the given asset
145
- # @example
146
- # row = datagrid_row(grid, user)
147
- # row.class # => Datagrid::Helper::HtmlRow
148
- # row.first_name # => "<strong>Bogdan</strong>"
149
- # row.grid # => Grid object
150
- # row.asset # => User object
151
- # row.each do |value|
152
- # puts value
153
- # end
154
- class HtmlRow
155
-
156
- include Enumerable
157
-
158
- attr_reader :grid, :asset
159
-
160
- # @!visibility private
161
- def initialize(context, grid, asset)
162
- @context = context
163
- @grid = grid
164
- @asset = asset
165
- end
166
-
167
- # @return [Object] a column value for given column name
168
- def get(column)
169
- @context.datagrid_value(@grid, column, @asset)
170
- end
171
-
172
- # Iterates over all column values that are available in the row
173
- # param block [Proc] column value iterator
174
- def each(&block)
175
- @grid.columns.each do |column|
176
- block.call(get(column))
177
- end
178
- end
179
-
180
- protected
181
- def method_missing(method, *args, &blk)
182
- if column = @grid.column_by_name(method)
183
- get(column)
184
- else
185
- super
186
- end
187
- end
188
- end
189
145
 
190
146
  protected
191
147
 
@@ -2,22 +2,26 @@ en:
2
2
  datagrid:
3
3
  no_results:
4
4
  "――"
5
+
5
6
  table:
6
7
  order:
7
8
  asc: "↑"
8
9
  desc: "↓"
9
10
  no_columns: "No columns selected"
11
+
10
12
  form:
11
13
  search: "Search"
12
14
  reset: "Reset"
15
+
13
16
  filters:
14
17
  xboolean:
15
18
  "yes": "Yes"
16
19
  "no": "No"
17
-
18
20
  dynamic:
19
21
  operations:
20
22
  ">=": "≥"
21
23
  "<=": "≤"
22
24
  "=": "="
23
25
  "=~": "≈"
26
+ range:
27
+ separator: " - "
@@ -27,7 +27,7 @@ module Datagrid
27
27
  alias descending? descending
28
28
 
29
29
  end
30
- base.send :include, InstanceMethods
30
+ base.include InstanceMethods
31
31
  end
32
32
 
33
33
  # @!visibility private
@@ -41,9 +41,9 @@ module Datagrid
41
41
 
42
42
  _render_partial('table', options[:partials],
43
43
  {
44
- :grid => grid,
45
- :options => options,
46
- :assets => assets
44
+ grid: grid,
45
+ options: options,
46
+ assets: assets
47
47
  })
48
48
  end
49
49
 
@@ -56,22 +56,20 @@ module Datagrid
56
56
 
57
57
  def rows(grid, assets = grid.assets, **options, &block)
58
58
  result = assets.map do |asset|
59
- if block_given?
60
- @template.capture do
61
- yield(Datagrid::Helper::HtmlRow.new(@template, grid, asset))
62
- end
63
- else
64
- _render_partial( 'row', options[:partials], {
65
- :grid => grid,
66
- :options => options,
67
- :asset => asset
68
- })
69
- end
59
+ row(grid, asset, **options, &block)
70
60
  end.to_a.join
71
61
 
72
62
  _safe(result)
73
63
  end
74
64
 
65
+ def row(grid, asset, **options, &block)
66
+ Datagrid::Helper::HtmlRow.new(self, grid, asset, options).tap do |row|
67
+ if block_given?
68
+ return @template.capture(row, &block)
69
+ end
70
+ end
71
+ end
72
+
75
73
  def order_for(grid, column, options = {})
76
74
  _render_partial('order_for', options[:partials],
77
75
  { :grid => grid, :column => column })
@@ -99,4 +97,61 @@ module Datagrid
99
97
  })
100
98
  end
101
99
  end
100
+
101
+ module Helper
102
+ # Represents a datagrid row that provides access to column values for the given asset
103
+ # @example
104
+ # row = datagrid_row(grid, user)
105
+ # row.class # => Datagrid::Helper::HtmlRow
106
+ # row.first_name # => "<strong>Bogdan</strong>"
107
+ # row.grid # => Grid object
108
+ # row.asset # => User object
109
+ # row.each do |value|
110
+ # puts value
111
+ # end
112
+ class HtmlRow
113
+
114
+ include Enumerable
115
+
116
+ attr_reader :grid, :asset, :options
117
+
118
+ # @!visibility private
119
+ def initialize(renderer, grid, asset, options)
120
+ @renderer = renderer
121
+ @grid = grid
122
+ @asset = asset
123
+ @options = options
124
+ end
125
+
126
+ # @return [Object] a column value for given column name
127
+ def get(column)
128
+ @renderer.format_value(@grid, column, @asset)
129
+ end
130
+
131
+ # Iterates over all column values that are available in the row
132
+ # param block [Proc] column value iterator
133
+ def each(&block)
134
+ (@options[:columns] || @grid.html_columns).each do |column|
135
+ block.call(get(column))
136
+ end
137
+ end
138
+
139
+ def to_s
140
+ @renderer.send(:_render_partial, 'row', options[:partials], {
141
+ :grid => grid,
142
+ :options => options,
143
+ :asset => asset
144
+ })
145
+ end
146
+
147
+ protected
148
+ def method_missing(method, *args, &blk)
149
+ if column = @grid.column_by_name(method)
150
+ get(column)
151
+ else
152
+ super
153
+ end
154
+ end
155
+ end
156
+ end
102
157
  end
@@ -32,14 +32,14 @@ shared_examples_for "Datagrid" do
32
32
  describe "filter ##{filter.name}" do
33
33
 
34
34
  let(:filter_value) do
35
-
35
+
36
36
  case Datagrid::Filters::FILTER_TYPES.invert[filter.class]
37
37
  when :default, :string
38
38
  "text"
39
39
  when :date
40
40
  1.day.ago
41
- when :xboolean, :eboolean
42
- Datagrid::Filters::BooleanEnumFilter::YES
41
+ when :xboolean
42
+ Datagrid::Filters::ExtendedBooleanFilter::YES
43
43
  when :boolean
44
44
  true
45
45
  when :integer
@@ -58,7 +58,7 @@ shared_examples_for "Datagrid" do
58
58
  end
59
59
 
60
60
  it "should be supported" do
61
- subject.assets.should_not be_nil
61
+ subject.assets.should_not be_nil
62
62
  #TODO: better matcher.
63
63
  end
64
64
  end
@@ -1,3 +1,3 @@
1
1
  module Datagrid
2
- VERSION = "1.7.0"
2
+ VERSION = "1.8.0"
3
3
  end
@@ -5,7 +5,7 @@ class <%= grid_class_name %> < BaseGrid
5
5
  end
6
6
 
7
7
  filter(:id, :integer)
8
- filter(:created_at, :date, :range => true)
8
+ filter(:created_at, :date, range: true)
9
9
 
10
10
  column(:id)
11
11
  column(:name)
@@ -1,4 +1,4 @@
1
- <%%= datagrid_form_for @grid, :method => :get, :url => <%= grid_route_name %> %>
1
+ <%%= datagrid_form_for @grid, method: :get, url: <%= grid_route_name %> %>
2
2
 
3
3
  <%%= <%=pagination_helper_code%> %>
4
4
  <%%= datagrid_table @grid %>
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.7.0
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bogdan Gusiev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-22 00:00:00.000000000 Z
11
+ date: 2023-12-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -62,7 +62,6 @@ files:
62
62
  - lib/datagrid/engine.rb
63
63
  - lib/datagrid/filters.rb
64
64
  - lib/datagrid/filters/base_filter.rb
65
- - lib/datagrid/filters/boolean_enum_filter.rb
66
65
  - lib/datagrid/filters/boolean_filter.rb
67
66
  - lib/datagrid/filters/composite_filters.rb
68
67
  - lib/datagrid/filters/date_filter.rb
@@ -114,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
113
  - !ruby/object:Gem::Version
115
114
  version: '0'
116
115
  requirements: []
117
- rubygems_version: 3.3.7
116
+ rubygems_version: 3.4.15
118
117
  signing_key:
119
118
  specification_version: 4
120
119
  summary: Ruby gem to create datagrids
@@ -1,19 +0,0 @@
1
- # @!visibility private
2
- class Datagrid::Filters::BooleanEnumFilter < Datagrid::Filters::EnumFilter
3
-
4
- YES = "YES"
5
- NO = "NO"
6
-
7
- def initialize(report, attribute, options = {}, &block)
8
- Datagrid::Utils.warn_once("Datagrid eboolean filter is deprecated in favor of xboolean filter")
9
- options[:select] = [YES, NO].map do |key, value|
10
- [I18n.t("datagrid.filters.eboolean.#{key.downcase}", default: key.downcase.capitalize), key]
11
- end
12
- super(report, attribute, options, &block)
13
- end
14
-
15
-
16
- def checkbox_id(value)
17
- [object_name, name, value].join('_').underscore
18
- end
19
- end