datagrid 2.0.0.pre.alpha → 2.0.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
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'