datagrid 2.0.0.pre.alpha → 2.0.1

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: 37409811e25a50a023aa095fb8854424fea3867e137b8d212d619ba191307abe
4
- data.tar.gz: 2485f8f3a8cf9d196011a584e680c345d147430ef3d263b151569ae10fc3ef69
3
+ metadata.gz: 73b5ec45b488122854f535af2e33440795923c7186f07195b1dd12c830656a83
4
+ data.tar.gz: 72b4cf51c6b47d6d3985bad16f0ca775b09b0770172c8ddaa67eb53091f50fb5
5
5
  SHA512:
6
- metadata.gz: 2974b76d03c7a3c014a3b853570ae0a11e2c137f0e4faea6be0dfcff45b49e4c64037298337e0f9e3028ecd64d938747770903469888339e6a43bbcc03330a59
7
- data.tar.gz: 52d188d5c0e6a41a3f44061274695b5eee22f7c669c1814f26ae38cfeee364b66c8437ca85c55fa3a73d8fe3333e6c9820fda9b1e2ccee770d48bcba7d72bfe3
6
+ metadata.gz: ebd3afee727b599bc3cfb1bb54aea656fb117edff207bfde118ef9fce36d716344ab7384dd2a801e3efd3d64e19fef419882b2a343a91408ce680755bfaf79bc
7
+ data.tar.gz: 3ee4d83c374287526c0f96a821c72d0254b2c1eed9d1cedef619c3bfd2425a2f21065b1571a7f065afebb6efe8c9c71ddf07f5e76678c755f5f5b99a3bfd4e06
data/.yardopts ADDED
@@ -0,0 +1,2 @@
1
+ --markup=markdown
2
+ --readme=README.md
data/CHANGELOG.md CHANGED
@@ -1,18 +1,65 @@
1
1
  # Changelog
2
2
 
3
- ## 2.0.0
3
+ ## [2.0.1]
4
+
5
+ * Fixed `search` field type support [#330](https://github.com/bogdan/datagrid/issues/330)
6
+
7
+ ``` ruby
8
+ class UsersGrid < Datagrid::Base
9
+ scope { User }
10
+
11
+ filter(
12
+ :query, :string, input_options: { type: "search" }
13
+ ) do |value, scope|
14
+ scope.magic_search(value)
15
+ end
16
+ end
17
+ ```
18
+
19
+ Renders filter as:
20
+
21
+ ``` html
22
+ <input type="search" name="users_grid[query]" id="users_grid_query"/>
23
+ ```
24
+
25
+ * Added support for `default_filter_options` and added lambda support for `default_column_options` [#333](https://github.com/bogdan/datagrid/issues/333) by @tmikoss.
26
+
27
+ ``` ruby
28
+ class UsersGrid < Datagrid::Base
29
+ scope { User }
30
+
31
+ self.default_column_options = -> (column) {
32
+ {header: I18n.t("datagrid.keywords.#{column.name}")}
33
+ }
34
+
35
+ self.default_filter_options = -> (filter) {
36
+ {
37
+ header: I18n.t("datagrid.keywords.user.#{filter.name}"),
38
+ input_options: filter.type == :string ? {type: "textarea"} : {},
39
+ }
40
+ }
41
+
42
+ filter(:first_name, :string)
43
+ filter(:last_name, :string)
44
+
45
+ column(:first_name)
46
+ column(:last_name)
47
+ end
48
+ ```
49
+
50
+ ## [2.0.0]
4
51
 
5
52
  Version 2 is a major update implementing a lot of major improvements
6
53
  at the cost of backward compatibility.
7
54
 
8
55
  [Changes and migration guide](./version-2)
9
56
 
10
- ## 1.8.3
57
+ ## [1.8.3]
11
58
 
12
59
  * Fix rails hooking for version 7.1. [#327](https://github.com/bogdan/datagrid/issues/327)
13
60
  * Fix formatting of value for `date` and `datetime-local` input types
14
61
 
15
- ## 1.8.2
62
+ ## [1.8.2]
16
63
 
17
64
  * Treat true/false as YES/NO when assigned as strings for xboolean filter.
18
65
  * Support infinite ranges for date, datetime and integer filters.
@@ -20,11 +67,11 @@ at the cost of backward compatibility.
20
67
  * Add `Datagrid#reset` method to reset a column cache.
21
68
  * Drop support of Rails 6.0 [#326](https://github.com/bogdan/datagrid/pull/326)
22
69
 
23
- ## 1.8.1
70
+ ## [1.8.1]
24
71
 
25
72
  * Prioritize `input_options` over generated by default. [#319](https://github.com/bogdan/datagrid/pull/319)
26
73
 
27
- ## 1.8.0
74
+ ## [1.8.0]
28
75
 
29
76
  * Support `input_options: {type: "textarea"}` as `<textarea/>` tag
30
77
  * Remove deprecated `eboolean` filter
@@ -37,18 +84,18 @@ at the cost of backward compatibility.
37
84
  * Add ability to specify `columns` option for `datagrid_row`.
38
85
  [#314](https://github.com/bogdan/datagrid/pull/314)
39
86
 
40
- ## 1.7.0
87
+ ## [1.7.0]
41
88
 
42
89
  * Depend on `railties` instead of `rails` to prevent loading of unnecessary frameworks
43
90
  * Bugfix `File.exist?` usage for Ruby 3.0 [#307](https://github.com/bogdan/datagrid/issues/307)
44
91
  * Drop support of old Ruby versions (< 2.7) [#305](https://github.com/bogdan/datagrid/pull/305)
45
92
  * Drop support of old Rails versions (< 6.0) [#305](https://github.com/bogdan/datagrid/pull/305)
46
93
 
47
- ## 1.6.3
94
+ ## [1.6.3]
48
95
 
49
96
  * Fix usage of options spread operator for Ruby 3.0 [#296](https://github.com/bogdan/datagrid/issues/296)
50
97
 
51
- ## 1.6.2
98
+ ## [1.6.2]
52
99
 
53
100
  * Add `input_options` and `label_options` to `filter` method [#294](https://github.com/bogdan/datagrid/issues/294)
54
101
  * Fix `<option>` tag rendering for Rails 6.0
data/README.md CHANGED
@@ -23,8 +23,6 @@ including admin panels, analytics and data browsers:
23
23
  * Sequel
24
24
  * Array (in-memory data of smaller scale)
25
25
 
26
- [Create an issue](https://github.com/bogdan/datagrid/issues/new) if you want more.
27
-
28
26
  ## Datagrid Philosophy
29
27
 
30
28
  1. Expressive DSL complements OOD instead of replacing it.
@@ -164,7 +162,7 @@ end
164
162
  Some formatting options are also available.
165
163
  Each column is sortable.
166
164
 
167
- [More about columns](https://github.com/bogdan/datagrid/wiki/Columns)
165
+ [More about columns](https://rubydoc.info/gems/datagrid/Datagrid/Columns)
168
166
 
169
167
  ### Front end
170
168
 
@@ -198,7 +196,7 @@ rails g datagrid::views
198
196
 
199
197
  All advanced frontend things are described in:
200
198
 
201
- [Frontend section on wiki](https://rubydoc.info/gems/datagrid/Datagrid/Helper)
199
+ [Frontend documentation](https://rubydoc.info/gems/datagrid/Datagrid/Helper)
202
200
 
203
201
  ## Questions & Issues
204
202
 
data/datagrid.gemspec CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
19
19
  "CHANGELOG.md",
20
20
  "README.md",
21
21
  "datagrid.gemspec",
22
+ ".yardopts",
22
23
  ]
23
24
  s.files += `git ls-files | grep -E '^(app|lib|templates)'`.split("\n")
24
25
  s.homepage = "https://github.com/bogdan/datagrid"
@@ -27,7 +28,7 @@ Gem::Specification.new do |s|
27
28
  s.metadata = {
28
29
  "homepage_uri" => s.homepage,
29
30
  "bug_tracker_uri" => "#{s.homepage}/issues",
30
- "documentation_uri" => "#{s.homepage}/wiki",
31
+ "documentation_uri" => "https://rubydoc.info/gems/datagrid",
31
32
  "changelog_uri" => "#{s.homepage}/blob/main/CHANGELOG.md",
32
33
  "source_code_uri" => s.homepage,
33
34
  "rubygems_mfa_required" => "true",
@@ -8,37 +8,52 @@ module Datagrid
8
8
  class ResponseFormat
9
9
  attr_accessor :data_block, :html_block
10
10
 
11
+ # @!visibility private
11
12
  def initialize
12
13
  yield(self)
13
14
  end
14
15
 
16
+ # @!visibility private
15
17
  def data(&block)
16
18
  self.data_block = block
17
19
  end
18
20
 
21
+ # @!visibility private
19
22
  def html(&block)
20
23
  self.html_block = block
21
24
  end
22
25
 
26
+ # @!visibility private
23
27
  def call_data
24
28
  data_block.call
25
29
  end
26
30
 
31
+ # @!visibility private
27
32
  def to_s
28
33
  call_data.to_s
29
34
  end
30
35
 
36
+ # @!visibility private
31
37
  def call_html(context)
32
38
  context.instance_eval(&html_block)
33
39
  end
34
40
  end
35
41
 
36
- attr_accessor :grid_class, :options, :data_block, :name, :html_block, :query
42
+ # @attribute [r] grid_class
43
+ # @return [Class] grid class where column is defined
44
+ # @attribute [r] name
45
+ # @return [Symbol] column name
46
+ # @attribute [r] options
47
+ # @return [Hash<Symbol, Object>] column options
48
+ attr_reader :grid_class, :name, :query, :options, :data_block, :html_block
37
49
 
50
+ # @!visibility private
38
51
  def initialize(grid_class, name, query, options = {}, &block)
39
- self.grid_class = grid_class
40
- self.name = name.to_sym
41
- self.options = options
52
+ @grid_class = grid_class
53
+ @name = name.to_sym
54
+ @query = query
55
+ @options = Datagrid::Utils.callable(grid_class.default_column_options, self).merge(options)
56
+
42
57
  if options[:class]
43
58
  Datagrid::Utils.warn_once(
44
59
  "column[class] option is deprecated. Use {tag_options: {class: ...}} instead.",
@@ -49,24 +64,26 @@ module Datagrid
49
64
  }
50
65
  end
51
66
  if options[:html] == true
52
- self.html_block = block
67
+ @html_block = block
53
68
  else
54
- self.data_block = block
69
+ @data_block = block
55
70
 
56
- self.html_block = options[:html] if options[:html].is_a? Proc
71
+ @html_block = options[:html] if options[:html].is_a? Proc
57
72
  end
58
- self.query = query
59
73
  end
60
74
 
75
+ # @deprecated Use {Datagrid::Columns#data_value} instead
61
76
  def data_value(model, grid)
62
77
  # backward compatibility method
63
78
  grid.data_value(name, model)
64
79
  end
65
80
 
81
+ # @deprecated Use {#header} instead
66
82
  def label
67
83
  options[:label]
68
84
  end
69
85
 
86
+ # @return [String] column header
70
87
  def header
71
88
  if (header = options[:header])
72
89
  Datagrid::Utils.callable(header)
@@ -75,7 +92,9 @@ module Datagrid
75
92
  end
76
93
  end
77
94
 
95
+ # @return [Object] column order expression
78
96
  def order
97
+ return nil if options[:order] == false
79
98
  if options.key?(:order) && options[:order] != true
80
99
  options[:order]
81
100
  else
@@ -83,10 +102,12 @@ module Datagrid
83
102
  end
84
103
  end
85
104
 
105
+ # @return [Boolean] weather column support order
86
106
  def supports_order?
87
- order || order_by_value?
107
+ !!order || order_by_value?
88
108
  end
89
109
 
110
+ # @!visibility private
90
111
  def order_by_value(model, grid)
91
112
  if options[:order_by_value] == true
92
113
  grid.data_value(self, model)
@@ -95,6 +116,7 @@ module Datagrid
95
116
  end
96
117
  end
97
118
 
119
+ # @return [Boolean] weather a column should be ordered by value
98
120
  def order_by_value?
99
121
  !!options[:order_by_value]
100
122
  end
@@ -105,22 +127,27 @@ module Datagrid
105
127
  options[:order_desc]
106
128
  end
107
129
 
130
+ # @return [Boolean] weather a column should be displayed in HTML
108
131
  def html?
109
132
  options[:html] != false
110
133
  end
111
134
 
135
+ # @return [Boolean] weather a column should be displayed in data
112
136
  def data?
113
137
  data_block != nil
114
138
  end
115
139
 
140
+ # @return [Boolean] weather a column is explicitly marked mandatory
116
141
  def mandatory?
117
142
  !!options[:mandatory]
118
143
  end
119
144
 
145
+ # @return [Hash<Symbol, Object>] `tag_options` option value
120
146
  def tag_options
121
147
  options[:tag_options] || {}
122
148
  end
123
149
 
150
+ # @deprecated Use {#tag_options} instead.
124
151
  def html_class
125
152
  Datagrid::Utils.warn_once(
126
153
  "Column#html_class is deprecated. Use Column#tag_options instead.",
@@ -128,30 +155,38 @@ module Datagrid
128
155
  options[:class]
129
156
  end
130
157
 
158
+ # @return [Boolean] weather a `mandatory` option is explicitly set
131
159
  def mandatory_explicitly_set?
132
160
  options.key?(:mandatory)
133
161
  end
134
162
 
163
+ # @param [Datagrid::Base] grid object
164
+ # @return [Boolean] weather a column is available via `if` and `unless` options
135
165
  def enabled?(grid)
136
166
  ::Datagrid::Utils.process_availability(grid, options[:if], options[:unless])
137
167
  end
138
168
 
169
+ # @return [String] column console inspection
139
170
  def inspect
140
171
  "#<#{self.class} #{grid_class}##{name} #{options.inspect}>"
141
172
  end
142
173
 
174
+ # @return [String] column header
143
175
  def to_s
144
176
  header
145
177
  end
146
178
 
179
+ # @!visibility private
147
180
  def html_value(context, asset, grid)
148
181
  grid.html_value(name, context, asset)
149
182
  end
150
183
 
184
+ # @!visibility private
151
185
  def generic_value(model, grid)
152
186
  grid.generic_value(self, model)
153
187
  end
154
188
 
189
+ # @!visibility private
155
190
  def append_preload(relation)
156
191
  return relation unless preload
157
192
 
@@ -168,6 +203,7 @@ module Datagrid
168
203
  end
169
204
  end
170
205
 
206
+ # @return [Object] `preload` option value
171
207
  def preload
172
208
  preload = options[:preload]
173
209
 
@@ -178,6 +214,8 @@ module Datagrid
178
214
  end
179
215
  end
180
216
 
217
+ protected
218
+
181
219
  def driver
182
220
  grid_class.driver
183
221
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "datagrid/utils"
4
4
  require "active_support/core_ext/class/attribute"
5
+ require "datagrid/columns/column"
5
6
 
6
7
  module Datagrid
7
8
  # Defines a column to be used for displaying data in a Datagrid.
@@ -154,6 +155,10 @@ module Datagrid
154
155
  #
155
156
  # self.default_column_options = { order: false }
156
157
  #
158
+ # It can also accept a proc with the column instance as an argument:
159
+ #
160
+ # self.default_column_options = ->(column) { { order: column.name == :id } }
161
+ #
157
162
  # ## Columns Visibility
158
163
  #
159
164
  # Columns can be dynamically shown or hidden based on the grid's `column_names` accessor.
@@ -199,33 +204,34 @@ module Datagrid
199
204
  # presenter.user.created_at
200
205
  # end
201
206
  module Columns
202
- require "datagrid/columns/column"
203
-
204
207
  # @!method default_column_options=(value)
205
- # @param [Hash] value default options passed to #column method call
206
- # @return [Hash] default options passed to #column method call
207
- # @example
208
- # # Disable default order
209
- # self.default_column_options = { order: false }
210
- # # Makes entire report HTML
211
- # self.default_column_options = { html: true }
208
+ # @param [Hash,Proc] value default options passed to {#column} method call.
209
+ # When a proc is passed, it will be called with the column instance as an argument,
210
+ # and expected to produce the options hash.
211
+ # @return [Hash,Proc] default options passed to {#column} method call, or a proc that returns them.
212
+ # @example Disable default order
213
+ # self.default_column_options = { order: false }
214
+ # @example Makes entire report HTML
215
+ # self.default_column_options = { html: true }
216
+ # @example Set the default header for all columns
217
+ # self.default_column_options = ->(column) { { header: I18n.t(column.name, scope: 'my_scope.columns') } }
212
218
 
213
219
  # @!method default_column_options
214
- # @return [Hash]
215
- # @see #default_column_options=
220
+ # @return [Hash,Proc] default options passed to {#column} method call, or a proc that returns them.
221
+ # @see #default_column_options=
216
222
 
217
223
  # @!method batch_size=(value)
218
- # @param [Integer] value Specify a default batch size when generating CSV or just data. Default: 1000
219
- # @return [Integer] Specify a default batch size when generating CSV or just data.
220
- # @example
221
- # self.batch_size = 500
222
- # # Disable batches
223
- # self.batch_size = nil
224
- #
224
+ # Specify a default batch size when generating CSV or just data.
225
+ # @param [Integer] value a batch size when generating CSV or just data. Default: 1000
226
+ # @return [void]
227
+ # @example Set batch size to 500
228
+ # self.batch_size = 500
229
+ # @example Disable batches
230
+ # self.batch_size = nil
225
231
 
226
232
  # @!method batch_size
227
- # @return [Integer]
228
- # @see #batch_size=
233
+ # @return [Integer]
234
+ # @see #batch_size=
229
235
 
230
236
  # @visibility private
231
237
  # @param [Object] base
@@ -253,37 +259,31 @@ module Datagrid
253
259
  filter_columns(columns_array, *column_names, data: data, html: html)
254
260
  end
255
261
 
256
- # Defines new datagrid column
257
- #
262
+ # Defines a new datagrid column
258
263
  # @param name [Symbol] column name
259
264
  # @param query [String, nil] a string representing the query to select this column (supports only ActiveRecord)
260
- # @param options [Hash{Symbol => Object}] hash of options
261
265
  # @param block [Block] proc to calculate a column value
266
+ # @option options [Boolean, String] html Determines if the column should be present
267
+ # in the HTML table and how it is formatted.
268
+ # @option options [String, Array<Symbol>] order Determines if the column can be sortable and
269
+ # specifies the ORM ordering method.
270
+ # Example: `"created_at, id"` for ActiveRecord, `[:created_at, :id]` for Mongoid.
271
+ # @option options [String] order_desc Specifies a descending order for the column
272
+ # (used when `:order` cannot be easily reversed by the ORM).
273
+ # @option options [Boolean, Proc] order_by_value Enables Ruby-level ordering for the column.
274
+ # Warning: Sorting large datasets in Ruby is not recommended.
275
+ # If `true`, Datagrid orders by the column value.
276
+ # If a block is provided, Datagrid orders by the block's return value.
277
+ # @option options [Boolean] mandatory If `true`, the column will never be hidden by the `#column_names` selection.
278
+ # @option options [Symbol] before Places the column before the specified column when determining order.
279
+ # @option options [Symbol] after Places the column after the specified column when determining order.
280
+ # @option options [Boolean, Proc] if conditions when a column is available.
281
+ # @option options [Boolean, Proc] unless conditions when a column is not available.
282
+ # @option options [Symbol, Array<Symbol>] preload Specifies associations
283
+ # to preload for the column within the scope.
284
+ # @option options [Hash] tag_options Specifies HTML attributes for the `<td>` or `<th>` of the column.
285
+ # Example: `{ class: "content-align-right", "data-group": "statistics" }`.
262
286
  # @return [Datagrid::Columns::Column]
263
- #
264
- # Available options:
265
- #
266
- # * <tt>html</tt> - determines if current column should be present in html table and how is it formatted
267
- # * <tt>order</tt> - determines if this column could be sortable and how.
268
- # The value of order is explicitly passed to ORM ordering method.
269
- # Example: <tt>"created_at, id"</tt> for ActiveRecord, <tt>[:created_at, :id]</tt> for Mongoid
270
- # * <tt>order_desc</tt> - determines a descending order for given column
271
- # (only in case when <tt>:order</tt> can not be easily reversed by ORM)
272
- # * <tt>order_by_value</tt> - used in case it is easier to perform ordering at ruby level not on database level.
273
- # Warning: using ruby to order large datasets is very unrecommended.
274
- # If set to true - datagrid will use column value to order by this column
275
- # If block is given - datagrid will use value returned from block
276
- # * <tt>mandatory</tt> - if true, column will never be hidden with #column_names selection
277
- # * <tt>url</tt> - a proc with one argument, pass this option to easily convert the value into an URL
278
- # * <tt>before</tt> - determines the position of this column, by adding it before the column passed here
279
- # * <tt>after</tt> - determines the position of this column, by adding it after the column passed here
280
- # * <tt>if</tt> - the column is shown if the reult of calling this argument is true
281
- # * <tt>unless</tt> - the column is shown unless the reult of calling this argument is true
282
- # * <tt>preload</tt> - spefies which associations of the scope should be preloaded for this column
283
- # * `tag_options` - specify HTML attributes to be set for `<td>` or `<th>` of a column
284
- # Example: `{ class: "content-align-right", "data-group": "statistics" }`
285
- #
286
- # @see https://github.com/bogdan/datagrid/wiki/Columns
287
287
  def column(name, query = nil, **options, &block)
288
288
  define_column(columns_array, name, query, **options, &block)
289
289
  end
@@ -333,10 +333,10 @@ module Datagrid
333
333
  # Defines a model decorator that will be used to define a column value.
334
334
  # All column blocks will be given a decorated version of the model.
335
335
  # @return [void]
336
- # @example
336
+ # @example Wrapping a model with presenter
337
337
  # decorate { |user| UserPresenter.new(user) }
338
- #
339
- # decorate { UserPresenter } # a shortcut
338
+ # @example A shortcut for doing the same
339
+ # decorate { UserPresenter }
340
340
  def decorate(model = nil, &block)
341
341
  if !model && !block
342
342
  raise ArgumentError, "decorate needs either a block to define decoration or a model to decorate"
@@ -376,9 +376,10 @@ module Datagrid
376
376
  block ||= lambda do |model|
377
377
  model.public_send(name)
378
378
  end
379
+
379
380
  position = Datagrid::Utils.extract_position_from_options(columns, options)
380
381
  column = Datagrid::Columns::Column.new(
381
- self, name, query, default_column_options.merge(options), &block
382
+ self, name, query, options, &block
382
383
  )
383
384
  columns.insert(position, column)
384
385
  column
@@ -403,14 +404,16 @@ module Datagrid
403
404
  )
404
405
  end
405
406
 
406
- # @param column_names [Array<String>] list of column names if you want to limit data only to specified columns
407
+ # @param column_names [Array<String, Symbol>] list of column names
408
+ # if you want to limit data only to specified columns
407
409
  # @return [Array<String>] human readable column names. See also "Localization" section
408
410
  def header(*column_names)
409
411
  data_columns(*column_names).map(&:header)
410
412
  end
411
413
 
412
414
  # @param asset [Object] asset from datagrid scope
413
- # @param column_names [Array<String>] list of column names if you want to limit data only to specified columns
415
+ # @param column_names [Array<String, Symbol>] list of column names
416
+ # if you want to limit data only to specified columns
414
417
  # @return [Array<Object>] column values for given asset
415
418
  def row_for(asset, *column_names)
416
419
  data_columns(*column_names).map do |column|
@@ -419,7 +422,8 @@ module Datagrid
419
422
  end
420
423
 
421
424
  # @param asset [Object] asset from datagrid scope
422
- # @return [Hash] A mapping where keys are column names and values are column values for the given asset
425
+ # @return [Hash] A mapping where keys are column names and
426
+ # values are column values for the given asset
423
427
  def hash_for(asset)
424
428
  result = {}
425
429
  data_columns.each do |column|
@@ -428,7 +432,8 @@ module Datagrid
428
432
  result
429
433
  end
430
434
 
431
- # @param column_names [Array<String>] list of column names if you want to limit data only to specified columns
435
+ # @param column_names [Array<String,Symbol>] list of column names
436
+ # if you want to limit data only to specified columns
432
437
  # @return [Array<Array<Object>>] with data for each row in datagrid assets without header
433
438
  def rows(*column_names)
434
439
  map_with_batches do |asset|
@@ -436,7 +441,8 @@ module Datagrid
436
441
  end
437
442
  end
438
443
 
439
- # @param column_names [Array<String>] list of column names if you want to limit data only to specified columns
444
+ # @param column_names [Array<String, Symbol>] list of column names
445
+ # if you want to limit data only to specified columns.
440
446
  # @return [Array<Array<Object>>] data for each row in datagrid assets with header.
441
447
  def data(*column_names)
442
448
  rows(*column_names).unshift(header(*column_names))
@@ -461,7 +467,7 @@ module Datagrid
461
467
  end
462
468
  end
463
469
 
464
- # @param column_names [Array<String>]
470
+ # @param column_names [Array<String,Symbol>]
465
471
  # @param options [Hash] CSV generation options
466
472
  # @return [String] a CSV representation of the data in the grid
467
473
  #
@@ -514,7 +520,7 @@ module Datagrid
514
520
  columns(*column_names, data: data, html: true)
515
521
  end
516
522
 
517
- # Finds a column definition by name
523
+ # Finds a column by name
518
524
  # @param name [String, Symbol] column name to be found
519
525
  # @return [Datagrid::Columns::Column, nil]
520
526
  def column_by_name(name)
@@ -522,22 +528,21 @@ module Datagrid
522
528
  end
523
529
 
524
530
  # Gives ability to have a different formatting for CSV and HTML column value.
525
- #
526
- # @example
531
+ # @example Formating using Rails view helpers
527
532
  # column(:name) do |model|
528
533
  # format(model.name) do |value|
529
534
  # tag.strong(value)
530
535
  # end
531
536
  # end
532
- #
537
+ # @example Formatting using a separated view template
533
538
  # column(:company) do |model|
534
539
  # format(model.company.name) do
535
- # render partial: "company_with_logo", locals: {company: model.company }
540
+ # render partial: "companies/company_with_logo", locals: {company: model.company }
536
541
  # end
537
542
  # end
538
543
  # @return [Datagrid::Columns::Column::ResponseFormat] Format object
539
544
  def format(value, &block)
540
- if block_given?
545
+ if block
541
546
  self.class.format(value, &block)
542
547
  else
543
548
  # don't override Object#format method
@@ -545,26 +550,26 @@ module Datagrid
545
550
  end
546
551
  end
547
552
 
553
+ # @param [Object] asset one of the assets from grid scope
548
554
  # @return [Datagrid::Columns::DataRow] an object representing a grid row.
549
555
  # @example
550
- # class MyGrid
551
- # scope { User }
552
- # column(:id)
553
- # column(:name)
554
- # column(:number_of_purchases) do |user|
555
- # user.purchases.count
556
- # end
557
- # end
556
+ # class MyGrid
557
+ # scope { User }
558
+ # column(:id)
559
+ # column(:name)
560
+ # column(:number_of_purchases) do |user|
561
+ # user.purchases.count
562
+ # end
563
+ # end
558
564
  #
559
- # row = MyGrid.new.data_row(User.last)
560
- # row.id # => user.id
561
- # row.number_of_purchases # => user.purchases.count
565
+ # row = MyGrid.new.data_row(User.last)
566
+ # row.id # => user.id
567
+ # row.number_of_purchases # => user.purchases.count
562
568
  def data_row(asset)
563
569
  ::Datagrid::Columns::DataRow.new(self, asset)
564
570
  end
565
571
 
566
572
  # Defines a column at instance level
567
- #
568
573
  # @see Datagrid::Columns::ClassMethods#column
569
574
  def column(name, query = nil, **options, &block)
570
575
  self.class.define_column(columns_array, name, query, **options, &block)
@@ -578,7 +583,6 @@ module Datagrid
578
583
 
579
584
  # @return [Array<Datagrid::Columns::Column>] all columns
580
585
  # that are possible to be displayed for the current grid object
581
- #
582
586
  # @example
583
587
  # class MyGrid
584
588
  # filter(:search) {|scope, value| scope.full_text_search(value)}
@@ -600,6 +604,8 @@ module Datagrid
600
604
  end
601
605
  end
602
606
 
607
+ # @param [String,Symbol] column_name column name
608
+ # @param [Object] asset one of the assets from grid scope
603
609
  # @return [Object] a cell data value for given column name and asset
604
610
  def data_value(column_name, asset)
605
611
  column = column_by_name(column_name)
@@ -611,6 +617,9 @@ module Datagrid
611
617
  end
612
618
  end
613
619
 
620
+ # @param [String,Symbol] column_name column name
621
+ # @param [Object] asset one of the assets from grid scope
622
+ # @param [ActionView::Base] context view context object
614
623
  # @return [Object] a cell HTML value for given column name and asset and view context
615
624
  def html_value(column_name, context, asset)
616
625
  column = column_by_name(column_name)
@@ -624,6 +633,7 @@ module Datagrid
624
633
  end
625
634
  end
626
635
 
636
+ # @param [Object] model one of the assets from grid scope
627
637
  # @return [Object] a decorated version of given model if decorator is specified or the model otherwise.
628
638
  def decorate(model)
629
639
  self.class.decorate(model)
@@ -1,6 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Datagrid
4
+ # @return [Configuration] current Datagrid configuration
5
+ def self.configuration
6
+ @configuration ||= Configuration.new
7
+ end
8
+
9
+ # @yield block to configure
10
+ # @yieldparam [Configuration] configuration
11
+ # @yieldreturn [void]
12
+ # @return [void] configure datagrid
13
+ # @see Datagrid::Configuration
14
+ def self.configure(&block)
15
+ block.call(configuration)
16
+ end
17
+
4
18
  # ## Configuration
5
19
  #
6
20
  # Datagrid provides several configuration options.
@@ -11,12 +25,14 @@ module Datagrid
11
25
  # Datagrid.configure do |config|
12
26
  # # Defines date formats that can be used to parse dates.
13
27
  # # Note: Multiple formats can be specified. The first format is used to format dates as strings,
14
- # # while other formats are used only for parsing dates from strings (e.g., if your app supports multiple formats).
15
- # config.date_formats = ["%m/%d/%Y", "%Y-%m-%d"]
28
+ # # while other formats are used only for parsing dates
29
+ # # from strings (e.g., if your app supports multiple formats).
30
+ # config.date_formats = "%m/%d/%Y", "%Y-%m-%d"
16
31
  #
17
32
  # # Defines timestamp formats that can be used to parse timestamps.
18
33
  # # Note: Multiple formats can be specified. The first format is used to format timestamps as strings,
19
- # # while other formats are used only for parsing timestamps from strings (e.g., if your app supports multiple formats).
34
+ # # while other formats are used only for parsing timestamps
35
+ # # from strings (e.g., if your app supports multiple formats).
20
36
  # config.datetime_formats = ["%m/%d/%Y %h:%M", "%Y-%m-%d %h:%M:%s"]
21
37
  # end
22
38
  # ```
data/lib/datagrid/core.rb CHANGED
@@ -18,8 +18,7 @@ module Datagrid
18
18
  # Both having appropriate use cases
19
19
  #
20
20
  # @example Defining a scope in a grid class
21
- # class ProjectsGrid
22
- # include Datagrid
21
+ # class ProjectsGrid < ApplicationGrid
23
22
  # scope { Project.includes(:category) }
24
23
  # end
25
24
  #
@@ -53,6 +52,7 @@ module Datagrid
53
52
  class_attribute :datagrid_attributes, instance_writer: false, default: []
54
53
  class_attribute :dynamic_block, instance_writer: false
55
54
  class_attribute :forbidden_attributes_protection, instance_writer: false, default: false
55
+ class_attribute :default_filter_options, default: {}
56
56
  end
57
57
  end
58
58
 
@@ -7,7 +7,6 @@ module Datagrid
7
7
  end
8
8
  end
9
9
 
10
- # @!visibility private
11
10
  module Datagrid
12
11
  module Filters
13
12
  class BaseFilter
@@ -16,7 +15,7 @@ module Datagrid
16
15
  def initialize(grid_class, name, **options, &block)
17
16
  self.grid_class = grid_class
18
17
  self.name = name.to_sym
19
- self.options = options
18
+ self.options = Datagrid::Utils.callable(grid_class.default_filter_options, self).merge(options)
20
19
  self.block = block
21
20
  end
22
21
 
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # @!visibility private
4
3
  module Datagrid
5
4
  module Filters
6
5
  class ExtendedBooleanFilter < Datagrid::Filters::EnumFilter
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # @!visibility private
4
3
  module Datagrid
5
4
  module Filters
6
5
  class FloatFilter < Datagrid::Filters::BaseFilter
@@ -24,10 +24,10 @@ module Datagrid
24
24
  # grid = UserGrid.new(posts_count: 1, name: "John")
25
25
  # grid.assets # SELECT * FROM users WHERE users.posts_count > 1 AND name = 'John'
26
26
  #
27
- # # Filter Block
28
- #
29
27
  # Filter blocks should always return a chainable ORM object (e.g., `ActiveRecord::Relation`) rather than an `Array`.
30
28
  #
29
+ # # Filter Block
30
+ #
31
31
  # Filter blocks should have at least one argument representing the value assigned to the grid object attribute:
32
32
  #
33
33
  # filter(:name, :string) # { |value| where(name: value) }
@@ -123,6 +123,16 @@ module Datagrid
123
123
  # filter(:id, :integer, header: "Identifier")
124
124
  # filter(:created_at, :date, range: true, default: proc { 1.month.ago.to_date..Date.today })
125
125
  #
126
+ # ## Default Filter Options
127
+ #
128
+ # Default options for all filters in a grid can be set using `default_filter_options`.
129
+ #
130
+ # self.default_filter_options = { header: "" }
131
+ #
132
+ # It can also accept a proc with the filter instance as an argument:
133
+ #
134
+ # self.default_filter_options = ->(filter) { { header: I18n.t(filter.name, scope: 'filters') } }
135
+ #
126
136
  # # Localization
127
137
  #
128
138
  # Filter labels can be localized or specified via the `:header` option:
@@ -130,6 +140,18 @@ module Datagrid
130
140
  # filter(:created_at, :date, header: "Creation date")
131
141
  # filter(:created_at, :date, header: proc { I18n.t("creation_date") })
132
142
  module Filters
143
+ # @!method default_filter_options=(value)
144
+ # @param [Hash,Proc] value default options passed to {#filter} method call.
145
+ # When a proc is passed, it will be called with the filter instance as an argument,
146
+ # and expected to produce the options hash.
147
+ # @return [Hash,Proc] default options passed to {#filter} method call, or a proc that returns them.
148
+ # @example Set the default header for all filters
149
+ # self.default_filter_options = ->(filter) { { header: I18n.t(filter.name, scope: 'my_scope.filters') } }
150
+
151
+ # @!method default_filter_options
152
+ # @return [Hash,Proc] default options passed to {#filter} method call, or a proc that returns them.
153
+ # @see #default_filter_options=
154
+
133
155
  require "datagrid/filters/base_filter"
134
156
  require "datagrid/filters/enum_filter"
135
157
  require "datagrid/filters/extended_boolean_filter"
@@ -161,9 +183,9 @@ module Datagrid
161
183
 
162
184
  extend ActiveSupport::Concern
163
185
 
164
- # @!visibility private
165
186
  included do
166
187
  include Datagrid::Core
188
+ class_attribute :default_filter_options, instance_writer: false, default: {}
167
189
  class_attribute :filters_array, default: []
168
190
  end
169
191
 
@@ -190,37 +212,33 @@ module Datagrid
190
212
  # @param [Symbol] name filter name
191
213
  # @param [Symbol] type filter type that defines type case and GUI representation of a filter
192
214
  # @param [Hash] options hash of options
193
- # @param [Proc] block proc to apply the filter
215
+ # @yield [value, scope, grid] Block to apply the filter.
216
+ # @yieldparam [Object] value The value assigned to the filter.
217
+ # @yieldparam [Object] scope The current ORM scope being filtered.
218
+ # @yieldparam [Datagrid::Base] grid The datagrid instance.
194
219
  # @return [Datagrid::Filters::BaseFilter] Filter definition object
195
- # @see https://github.com/bogdan/datagrid/wiki/Filters
196
- #
197
- # Available options:
198
- #
199
- # * <tt>:header</tt> - determines the header of the filter
200
- # * <tt>:default</tt> - the default filter value.
201
- # Can be a <tt>Proc</tt> in case default should be recalculated.
202
- # * <tt>:range</tt> - if true, filter can accept two values that are treated
203
- # as a range that will be used for filtering.
204
- # Not all of the filter types support this option. Here are the list of types that do:
205
- # <tt>:integer</tt>, <tt>:float</tt>, <tt>:date</tt>, <tt>:datetime</tt>, <tt>:string</tt>
206
- # * <tt>:multiple</tt> - if true multiple values can be assigned to this filter.
207
- # If String is assigned as a filter value, it is parsed from string using a separator symbol (`,` by default).
208
- # But you can specify a different separator as option value. Default: false.
209
- # * <tt>:allow_nil</tt> - determines if the value can be nil
210
- # * <tt>:allow_blank</tt> - determines if the value can be blank
211
- # * <tt>:before</tt> - determines the position of this filter,
212
- # by adding it before the filter passed here (when using datagrid_form_with helper)
213
- # * <tt>:after</tt> - determines the position of this filter,
214
- # by adding it after the filter passed here (when using datagrid_form_with helper)
215
- # * <tt>:dummy</tt> - if true, this filter will not be applied automatically
216
- # and will be just displayed in form. In case you may want to apply it manually.
217
- # * <tt>:if</tt> - specify the condition when the filter can be dislayed and used.
218
- # Accepts a block or a symbol with an instance method name
219
- # * <tt>:unless</tt> - specify the reverse condition when the filter can be dislayed and used.
220
- # Accepts a block or a symbol with an instance method name
221
- # * <tt>:input_options</tt> - options passed when rendering html input tag attributes.
222
- # Use <tt>input_options.type</tt> to control input type including <tt>textarea</tt>.
223
- # * <tt>:label_options</tt> - options passed when rendering html label tag attributes
220
+ # @option options [String] header Determines the header of the filter.
221
+ # @option options [Object, Proc] default The default filter value. Accepts a `Proc` to allow dynamic calculation.
222
+ # @option options [Boolean] range Whether the filter accepts two values to define a range.
223
+ # Supported by types: `:integer`, `:float`, `:date`, `:datetime`, and `:string`.
224
+ # @option options [Boolean, String] multiple If true, allows multiple values for the filter.
225
+ # Strings are parsed using a separator (default: `,`). Can accept a custom separator. Default: `false`.
226
+ # @option options [Boolean] allow_nil Whether the filter value can be `nil`. Default: `false`.
227
+ # @option options [Boolean] allow_blank Whether the filter value can be blank. Default: `false`.
228
+ # @option options [Symbol] before Specifies the position of this filter by placing it before another filter.
229
+ # Used with the `datagrid_form_for` helper.
230
+ # @option options [Symbol] after Specifies the position of this filter by placing it after another filter.
231
+ # Used with the `datagrid_form_for` helper.
232
+ # @option options [Boolean] dummy If true, the filter is not applied automatically and
233
+ # is only displayed in the form. Useful for manual application.
234
+ # @option options [Proc, Symbol] if Specifies a condition under which the filter is displayed and used.
235
+ # Accepts a block or the name of an instance method.
236
+ # @option options [Proc, Symbol] unless Specifies a condition under which the filter is NOT displayed or used.
237
+ # Accepts a block or the name of an instance method.
238
+ # @option options [Hash] input_options Options passed to the HTML input tag for rendering attributes.
239
+ # Use `input_options[:type]` to control the input type (e.g., `textarea`).
240
+ # @option options [Hash] label_options Options passed to the HTML label tag for rendering attributes.
241
+ # @see Datagrid::Filters
224
242
  def filter(name, type = :default, **options, &block)
225
243
  klass = type.is_a?(Class) ? type : FILTER_TYPES[type]
226
244
  raise ConfigurationError, "filter class #{type.inspect} not found" unless klass
@@ -5,6 +5,14 @@ require "datagrid/deprecated_object"
5
5
 
6
6
  module Datagrid
7
7
  module FormBuilder
8
+ # @!visibility private
9
+ TYPE_METHOD_MAP = {
10
+ search: :search_field,
11
+ textarea: :text_area,
12
+ hidden: :hidden_field,
13
+ number: :number_field,
14
+ }.with_indifferent_access
15
+
8
16
  # @param filter_or_attribute [Datagrid::Filters::BaseFilter, String, Symbol] filter object or filter name
9
17
  # @param options [Hash] options of rails form input helper
10
18
  # @return [String] a form input html for the corresponding filter name
@@ -56,16 +64,12 @@ module Datagrid
56
64
  datetime_local_field filter.name, **options, &block
57
65
  when :date
58
66
  date_field filter.name, **options, &block
59
- when :textarea
60
- text_area filter.name, value: object.filter_value_as_string(filter), **options, &block
61
67
  when :checkbox
62
68
  value = options.fetch(:value, 1).to_s
63
- options = { checked: true, **options } if filter.enum_checkboxes? && enum_checkbox_checked?(filter, value)
69
+ if filter.enum_checkboxes? && enum_checkbox_checked?(filter, value) && !options.key?(:checked)
70
+ options[:checked] = true
71
+ end
64
72
  check_box filter.name, options, value
65
- when :hidden
66
- hidden_field filter.name, **options
67
- when :number
68
- number_field filter.name, **options
69
73
  when :select
70
74
  select(
71
75
  filter.name,
@@ -80,7 +84,13 @@ module Datagrid
80
84
  &block
81
85
  )
82
86
  else
83
- text_field filter.name, value: object.filter_value_as_string(filter), **options, &block
87
+ public_send(
88
+ TYPE_METHOD_MAP[type] || :text_field,
89
+ filter.name,
90
+ value: object.filter_value_as_string(filter),
91
+ **options,
92
+ &block
93
+ )
84
94
  end
85
95
  end
86
96
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  require "rails/generators"
4
4
 
5
- # @!visibility private
6
5
  module Datagrid
7
6
  # @!visibility private
8
7
  module Generators
@@ -17,7 +17,8 @@ module Datagrid
17
17
  # [built-in CSS](https://github.com/bogdan/datagrid/blob/master/app/assets/stylesheets/datagrid.sass).
18
18
  #
19
19
  # Datagrid includes helpers and a form builder for easy frontend generation.
20
- # If you need a fully-featured custom GUI, create your templates manually with the help of the {Datagrid::Columns} API.
20
+ # If you need a fully-featured custom GUI, create your templates manually
21
+ # with the help of the {Datagrid::Columns} API.
21
22
  #
22
23
  # ## Controller and Routing
23
24
  #
@@ -63,7 +64,8 @@ module Datagrid
63
64
  #
64
65
  # ### Advanced Method
65
66
  #
66
- # You can use Rails built-in tools to create a form. Additionally, Datagrid provides helpers to generate input/select elements for filters:
67
+ # You can use Rails built-in tools to create a form.
68
+ # Additionally, Datagrid provides helpers to generate input/select elements for filters:
67
69
  #
68
70
  # ``` haml
69
71
  # - form_with model: UserGrid.new, method: :get, url: users_path do |f|
@@ -169,7 +171,7 @@ module Datagrid
169
171
  #
170
172
  # To customize Datagrid views:
171
173
  #
172
- # rake datagrid:copy_partials
174
+ # rails g datagrid:views
173
175
  #
174
176
  # This creates files in `app/views/datagrid/`, which you can modify to suit your needs:
175
177
  #
@@ -240,7 +242,7 @@ module Datagrid
240
242
  #
241
243
  # https://github.com/bogdan/datagrid/blob/master/lib/datagrid/locale/en.yml
242
244
  module Helper
243
- # @param grid [Datagrid] grid object
245
+ # @param grid [Datagrid::Base] grid object
244
246
  # @param column [Datagrid::Columns::Column, String, Symbol] column name
245
247
  # @param model [Object] an object from grid scope
246
248
  # @return [Object] individual cell value from the given grid, column name and model
@@ -264,19 +266,16 @@ module Datagrid
264
266
  # Renders html table with columns defined in grid class.
265
267
  # In the most common used you need to pass paginated collection
266
268
  # to datagrid table because datagrid do not have pagination compatibilities:
267
- # Supported options:
268
- #
269
- # * <tt>:html</tt> - hash of attributes for <table> tag
270
- # * <tt>:order</tt> - If false do not generate ordering controlls.
271
- # Default: true.
272
- # * <tt>:columns</tt> - Array of column names to display.
273
- # Used in case when same grid class is used in different places
274
- # and needs different columns. Default: all defined columns.
275
- # * <tt>:partials</tt> - Path for partials lookup.
276
- # Default: 'datagrid'.
277
- # @param grid [Datagrid] grid object
269
+ # @param grid [Datagrid::Base] grid object
278
270
  # @param assets [Array] objects from grid scope
279
271
  # @param [Hash{Symbol => Object}] options HTML attributes to be passed to `<table>` tag
272
+ # @option options [Hash] html A hash of attributes for the `<table>` tag.
273
+ # @option options [Boolean] order Whether to generate ordering controls.
274
+ # If set to `false`, ordering controls are not generated. Default: `true`.
275
+ # @option options [Array<Symbol>] columns An array of column names to display.
276
+ # Use this when the same grid class is used in different contexts and requires different columns.
277
+ # Default: all defined columns.
278
+ # @option options [String] partials The path for partials lookup. Default: `'datagrid'`.
280
279
  # @return [String] table tag HTML markup
281
280
  # @example
282
281
  # assets = grid.assets.page(params[:page])
@@ -294,16 +293,14 @@ module Datagrid
294
293
 
295
294
  # Renders HTML table header for given grid instance using columns defined in it
296
295
  #
297
- # Supported options:
298
- #
299
- # * <tt>:order</tt> - display ordering controls built-in into header
300
- # Default: true
301
- # * <tt>:columns</tt> - Array of column names to display.
302
- # Used in case when same grid class is used in different places
303
- # and needs different columns. Default: all defined columns.
304
- # * <tt>:partials</tt> - Path for partials lookup.
305
- # Default: 'datagrid'.
306
- # @param grid [Datagrid] grid object
296
+ # @option options [Boolean] order Whether to display ordering controls built into the header.
297
+ # Default: `true`.
298
+ # @option options [Array<Symbol,String>] columns An array of column names to display.
299
+ # Use this when the same grid class is used in different contexts and requires different columns.
300
+ # Default: all defined columns.
301
+ # @option options [String] partials The path for partials lookup.
302
+ # Default: `'datagrid'`.
303
+ # @param grid [Datagrid::Base] grid object
307
304
  # @param [Object] opts (deprecated) pass keyword arguments instead
308
305
  # @param [Hash] options
309
306
  # @return [String] HTML table header tag markup
@@ -321,22 +318,21 @@ module Datagrid
321
318
  # Renders HTML table rows using given grid definition using columns defined in it.
322
319
  # Allows to provide a custom layout for each for in place with a block
323
320
  #
324
- # Supported options:
325
- #
326
- # * <tt>:columns</tt> - Array of column names to display.
327
- # Used in case when same grid class is used in different places
328
- # and needs different columns. Default: all defined columns.
329
- # * <tt>:partials</tt> - Path for partials lookup.
330
- # Default: 'datagrid'.
331
- #
321
+ # @option options [Array<Symbol>] columns An array of column names to display.
322
+ # Use this when the same grid class is used in different contexts and requires different columns.
323
+ # Default: all defined columns.
324
+ # @option options [String] partials The path for partials lookup.
325
+ # Default: `'datagrid'`.
332
326
  # @return [String]
333
- # @example
334
- # = datagrid_rows(grid) # Generic table rows Layout
335
- #
336
- # = datagrid_rows(grid) do |row| # Custom Layout
327
+ # @example Generic table rows Layout
328
+ # = datagrid_rows(grid)
329
+ # @example Custom Layout
330
+ # = datagrid_rows(grid) do |row|
337
331
  # %tr
338
332
  # %td= row.project_name
339
333
  # %td.project-status{class: row.status}= row.status
334
+ # @param [Datagrid::Base] grid datagrid object
335
+ # @param [Array<Object>] assets assets as per defined in grid scope
340
336
  def datagrid_rows(grid, assets = grid.assets, **options, &block)
341
337
  safe_join(
342
338
  assets.map do |asset|
@@ -346,11 +342,12 @@ module Datagrid
346
342
  end
347
343
 
348
344
  # @return [String] renders ordering controls for the given column name
349
- #
350
- # Supported options:
351
- #
352
- # * <tt>:partials</tt> - Path for partials lookup.
353
- # Default: 'datagrid'.
345
+ # @option options [String] partials The path for partials lookup.
346
+ # Default: `'datagrid'`.
347
+ # @param [Datagrid::Base] grid datagrid object
348
+ # @param [Datagrid::Columns::Column] column
349
+ # @deprecated Put necessary code inline inside datagrid/head partial.
350
+ # See built-in partial for example.
354
351
  def datagrid_order_for(grid, column, options = {})
355
352
  Datagrid::Utils.warn_once(<<~MSG)
356
353
  datagrid_order_for is deprecated.
@@ -362,15 +359,11 @@ module Datagrid
362
359
  end
363
360
 
364
361
  # Renders HTML for grid with all filters inputs and labels defined in it
365
- #
366
- # Supported options:
367
- #
368
- # * <tt>:partials</tt> - Path for form partial lookup.
369
- # Default: 'datagrid' results in using `app/views/datagrid/` partials.
370
- # Example: 'datagrid_admin' results in using `app/views/datagrid_admin` partials.
371
- # * <tt>:model</tt> - Datagrid object to be rendedred.
372
- # * All options supported by Rails <tt>form_with</tt> helper
373
- # @param grid [Datagrid] grid object
362
+ # @option options [String] partials Path for form partial lookup.
363
+ # Default: `'datagrid'`, which uses `app/views/datagrid/` partials.
364
+ # Example: `'datagrid_admin'` uses `app/views/datagrid_admin` partials.
365
+ # @option options [Datagrid::Base] model a Datagrid object to be rendered.
366
+ # @option options [Hash] All options supported by Rails `form_with` helper.
374
367
  # @param [Hash{Symbol => Object}] options
375
368
  # @return [String] form HTML tag markup
376
369
  def datagrid_form_with(**options)
@@ -390,7 +383,7 @@ module Datagrid
390
383
  # Default: 'datagrid'.
391
384
  # * All options supported by Rails <tt>form_with</tt> helper
392
385
  # @deprecated Use {#datagrid_form_with} instead.
393
- # @param grid [Datagrid] grid object
386
+ # @param grid [Datagrid::Base] grid object
394
387
  # @param [Hash] options
395
388
  # @return [String] form HTML tag markup
396
389
  def datagrid_form_for(grid, options = {})
@@ -409,25 +402,24 @@ module Datagrid
409
402
 
410
403
  # Provides access to datagrid columns data.
411
404
  # Used in case you want to build html table completelly manually
412
- # @param grid [Datagrid] grid object
405
+ # @param grid [Datagrid::Base] grid object
413
406
  # @param asset [Object] object from grid scope
414
407
  # @param block [Proc] block with Datagrid::Helper::HtmlRow as an argument returning a HTML markup as a String
415
408
  # @param [Hash{Symbol => Object}] options
416
409
  # @return [Datagrid::Helper::HtmlRow, String] captured HTML markup if block given otherwise row object
417
- # @example
418
- # # Suppose that grid has first_name and last_name columns
410
+ # @example Render default layout for row
411
+ # <%= datagrid_row(grid, user, columns: [:first_name, :last_name, :actions]) %>
412
+ # @example Rendering custom layout for `first_name` and `last_name` columns
419
413
  # <%= datagrid_row(grid, user) do |row| %>
420
414
  # <tr>
421
415
  # <td><%= row.first_name %></td>
422
416
  # <td><%= row.last_name %></td>
423
417
  # </tr>
424
418
  # <% end %>
425
- # @example
419
+ # @example Rendering custom layout passing a block
426
420
  # <% row = datagrid_row(grid, user) %>
427
421
  # First Name: <%= row.first_name %>
428
422
  # Last Name: <%= row.last_name %>
429
- # @example
430
- # <%= datagrid_row(grid, user, columns: [:first_name, :last_name, :actions]) %>
431
423
  def datagrid_row(grid, asset, **options, &block)
432
424
  Datagrid::Helper::HtmlRow.new(self, grid, asset, options).tap do |row|
433
425
  return capture(row, &block) if block_given?
@@ -435,7 +427,7 @@ module Datagrid
435
427
  end
436
428
 
437
429
  # Generates an ascending or descending order url for the given column
438
- # @param grid [Datagrid] grid object
430
+ # @param grid [Datagrid::Base] grid object
439
431
  # @param column [Datagrid::Columns::Column, String, Symbol] column name
440
432
  # @param descending [Boolean] order direction, descending if true, otherwise ascending.
441
433
  # @return [String] order layout HTML markup
@@ -475,7 +467,7 @@ module Datagrid
475
467
  # row = datagrid_row(grid, user)
476
468
  # row.class # => Datagrid::Helper::HtmlRow
477
469
  # row.first_name # => "<strong>Bogdan</strong>"
478
- # row.grid # => Grid object
470
+ # row.grid # => Datagrid::Base object
479
471
  # row.asset # => User object
480
472
  # row.each do |value|
481
473
  # puts value
@@ -33,6 +33,35 @@ module Datagrid
33
33
  end
34
34
  end
35
35
 
36
+ # @!method order=(value)
37
+ # Specify a column to be used to order the grid
38
+ # @param [Symbol, String] value column name
39
+ # @return [void]
40
+ # @example
41
+ # class MyGrid < ApplicationGrid
42
+ # scope { User }
43
+ # column(:name)
44
+ # end
45
+ #
46
+ # grid = MyGrid.new
47
+ # grid.order = :name
48
+ # grid.descending = true
49
+ # grid.assets # => SELECT * FROM users ORDER BY users.name DESC
50
+
51
+ # @!method order
52
+ # @return [Symbol, nil] specified order column name
53
+ # @see #order=
54
+
55
+ # @!method descending=(value)
56
+ # Specify an order direction for an order column
57
+ # @param [Boolean] value specify `true` for descending order` or `false` for ascending
58
+ # @return [void]
59
+ # @see #order=
60
+
61
+ # @!method descending?
62
+ # @return [Boolean] specified order direction
63
+ # @see #descending=
64
+
36
65
  # @!visibility private
37
66
  def assets
38
67
  check_order_valid!
@@ -133,8 +133,8 @@ module Datagrid
133
133
  !property_availability(grid, unless_option, false)
134
134
  end
135
135
 
136
- def callable(value)
137
- value.respond_to?(:call) ? value.call : value
136
+ def callable(value, *arguments)
137
+ value.respond_to?(:call) ? value.call(*arguments) : value
138
138
  end
139
139
 
140
140
  protected
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Datagrid
4
- VERSION = "2.0.0-alpha"
4
+ VERSION = "2.0.1"
5
5
  end
data/lib/datagrid.rb CHANGED
@@ -4,7 +4,6 @@ require "action_view"
4
4
  require "datagrid/configuration"
5
5
  require "datagrid/engine"
6
6
 
7
- # @main README.md
8
7
  module Datagrid
9
8
  # @!visibility private
10
9
  def self.included(base)
@@ -19,15 +18,6 @@ module Datagrid
19
18
  end
20
19
  end
21
20
 
22
- def self.configuration
23
- @configuration ||= Configuration.new
24
- end
25
-
26
- # Configure
27
- def self.configure(&block)
28
- block.call(configuration)
29
- end
30
-
31
21
  class ConfigurationError < StandardError; end
32
22
  class ArgumentError < ::ArgumentError; end
33
23
  class ColumnUnavailableError < StandardError; end
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: 2.0.0.pre.alpha
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bogdan Gusiev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-11-19 00:00:00.000000000 Z
11
+ date: 2025-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -33,6 +33,7 @@ extra_rdoc_files:
33
33
  - LICENSE.txt
34
34
  - README.md
35
35
  files:
36
+ - ".yardopts"
36
37
  - CHANGELOG.md
37
38
  - LICENSE.txt
38
39
  - README.md
@@ -93,7 +94,7 @@ licenses:
93
94
  metadata:
94
95
  homepage_uri: https://github.com/bogdan/datagrid
95
96
  bug_tracker_uri: https://github.com/bogdan/datagrid/issues
96
- documentation_uri: https://github.com/bogdan/datagrid/wiki
97
+ documentation_uri: https://rubydoc.info/gems/datagrid
97
98
  changelog_uri: https://github.com/bogdan/datagrid/blob/main/CHANGELOG.md
98
99
  source_code_uri: https://github.com/bogdan/datagrid
99
100
  rubygems_mfa_required: 'true'