datagrid 1.8.2 → 2.0.0.pre.alpha
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 +4 -4
- data/CHANGELOG.md +11 -1
- data/{Readme.markdown → README.md} +44 -27
- data/app/assets/stylesheets/datagrid.css +145 -0
- data/app/views/datagrid/_enum_checkboxes.html.erb +5 -3
- data/app/views/datagrid/_form.html.erb +4 -4
- data/app/views/datagrid/_head.html.erb +26 -3
- data/app/views/datagrid/_range_filter.html.erb +5 -3
- data/app/views/datagrid/_row.html.erb +12 -1
- data/app/views/datagrid/_table.html.erb +4 -4
- data/datagrid.gemspec +6 -6
- data/lib/datagrid/active_model.rb +9 -17
- data/lib/datagrid/base.rb +39 -0
- data/lib/datagrid/column_names_attribute.rb +9 -11
- data/lib/datagrid/columns/column.rb +155 -133
- data/lib/datagrid/columns.rb +254 -45
- data/lib/datagrid/configuration.rb +23 -10
- data/lib/datagrid/core.rb +89 -54
- data/lib/datagrid/deprecated_object.rb +20 -0
- data/lib/datagrid/drivers/abstract_driver.rb +12 -23
- data/lib/datagrid/drivers/active_record.rb +24 -26
- data/lib/datagrid/drivers/array.rb +22 -14
- data/lib/datagrid/drivers/mongo_mapper.rb +15 -14
- data/lib/datagrid/drivers/mongoid.rb +15 -17
- data/lib/datagrid/drivers/sequel.rb +14 -19
- data/lib/datagrid/drivers.rb +2 -1
- data/lib/datagrid/engine.rb +11 -3
- data/lib/datagrid/filters/base_filter.rb +166 -142
- data/lib/datagrid/filters/boolean_filter.rb +19 -5
- data/lib/datagrid/filters/date_filter.rb +33 -35
- data/lib/datagrid/filters/date_time_filter.rb +24 -16
- data/lib/datagrid/filters/default_filter.rb +9 -3
- data/lib/datagrid/filters/dynamic_filter.rb +151 -105
- data/lib/datagrid/filters/enum_filter.rb +43 -19
- data/lib/datagrid/filters/extended_boolean_filter.rb +39 -30
- data/lib/datagrid/filters/float_filter.rb +16 -5
- data/lib/datagrid/filters/integer_filter.rb +21 -10
- data/lib/datagrid/filters/ranged_filter.rb +66 -45
- data/lib/datagrid/filters/select_options.rb +58 -49
- data/lib/datagrid/filters/string_filter.rb +9 -4
- data/lib/datagrid/filters.rb +190 -57
- data/lib/datagrid/form_builder.rb +116 -128
- data/lib/datagrid/generators/scaffold.rb +185 -0
- data/lib/datagrid/generators/views.rb +20 -0
- data/lib/datagrid/helper.rb +397 -22
- data/lib/datagrid/ordering.rb +26 -29
- data/lib/datagrid/rspec.rb +6 -10
- data/lib/datagrid/utils.rb +37 -30
- data/lib/datagrid/version.rb +3 -1
- data/lib/datagrid.rb +18 -28
- data/templates/base.rb.erb +6 -4
- data/templates/grid.rb.erb +1 -1
- metadata +15 -16
- data/app/assets/stylesheets/datagrid.sass +0 -134
- data/lib/datagrid/filters/composite_filters.rb +0 -49
- data/lib/datagrid/renderer.rb +0 -157
- data/lib/datagrid/scaffold.rb +0 -129
- data/lib/tasks/datagrid_tasks.rake +0 -15
- data/templates/controller.rb.erb +0 -6
- data/templates/index.html.erb +0 -5
data/lib/datagrid/columns.rb
CHANGED
@@ -1,13 +1,208 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "datagrid/utils"
|
2
4
|
require "active_support/core_ext/class/attribute"
|
3
5
|
|
4
6
|
module Datagrid
|
5
|
-
|
7
|
+
# Defines a column to be used for displaying data in a Datagrid.
|
8
|
+
#
|
9
|
+
# class UserGrid < ApplicationGrid
|
10
|
+
# scope do
|
11
|
+
# User.order("users.created_at desc").joins(:group)
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# column(:name)
|
15
|
+
# column(:group, order: "groups.name") do
|
16
|
+
# self.group.name
|
17
|
+
# end
|
18
|
+
# column(:active, header: "Activated") do |user|
|
19
|
+
# !user.disabled
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# Each column is used to generate data for the grid.
|
24
|
+
#
|
25
|
+
# To create a grid displaying all users:
|
26
|
+
#
|
27
|
+
# grid = UserGrid.new
|
28
|
+
# grid.header # => ["Group", "Name", "Disabled"]
|
29
|
+
# grid.rows # => [
|
30
|
+
# # ["Steve", "Spammers", true],
|
31
|
+
# # ["John", "Spoilers", true],
|
32
|
+
# # ["Berry", "Good people", false]
|
33
|
+
# # ]
|
34
|
+
# grid.data # => Header & Rows
|
35
|
+
# grid.data_hash # => [
|
36
|
+
# # { name: "Steve", group: "Spammers", active: true },
|
37
|
+
# # { name: "John", group: "Spoilers", active: true },
|
38
|
+
# # { name: "Berry", group: "Good people", active: false },
|
39
|
+
# # ]
|
40
|
+
# }
|
41
|
+
#
|
42
|
+
# ## Column Value
|
43
|
+
#
|
44
|
+
# The value of a column can be defined by passing a block to `Datagrid.column`.
|
45
|
+
#
|
46
|
+
# ### Basic Column Value
|
47
|
+
#
|
48
|
+
# If no block is provided, the column value is generated automatically by sending the column name method to the model.
|
49
|
+
#
|
50
|
+
# column(:name) # => asset.name
|
51
|
+
#
|
52
|
+
# Using <tt>instance_eval</tt>:
|
53
|
+
#
|
54
|
+
# column(:completed) { completed? }
|
55
|
+
#
|
56
|
+
# Using the asset as an argument:
|
57
|
+
#
|
58
|
+
# column(:completed) { |asset| asset.completed? }
|
59
|
+
#
|
60
|
+
# ### Advanced Column Value
|
61
|
+
#
|
62
|
+
# You can also pass the Datagrid object itself to define more complex column values.
|
63
|
+
#
|
64
|
+
# Using filters with columns:
|
65
|
+
#
|
66
|
+
# filter(:category) do |value|
|
67
|
+
# where("category LIKE '%#{value}%'")
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# column(:exactly_matches_category) do |asset, grid|
|
71
|
+
# asset.category == grid.category
|
72
|
+
# end
|
73
|
+
#
|
74
|
+
# Combining columns:
|
75
|
+
#
|
76
|
+
# column(:total_sales) do |merchant|
|
77
|
+
# merchant.purchases.sum(:subtotal)
|
78
|
+
# end
|
79
|
+
# column(:number_of_sales) do |merchant|
|
80
|
+
# merchant.purchases.count
|
81
|
+
# end
|
82
|
+
# column(:average_order_value) do |_, _, row|
|
83
|
+
# row.total_sales / row.number_of_sales
|
84
|
+
# end
|
85
|
+
#
|
86
|
+
# ## Using Database Expressions
|
87
|
+
#
|
88
|
+
# Columns can use database expressions to directly manipulate data in the database.
|
89
|
+
#
|
90
|
+
# column(:count_of_users, 'count(user_id)')
|
91
|
+
# column(:uppercase_name, 'upper(name)')
|
92
|
+
#
|
93
|
+
# ## HTML Columns
|
94
|
+
#
|
95
|
+
# Columns can have different formats for HTML and non-HTML representations.
|
96
|
+
#
|
97
|
+
# column(:name) do |asset|
|
98
|
+
# format(asset.name) do |value|
|
99
|
+
# content_tag(:strong, value)
|
100
|
+
# end
|
101
|
+
# end
|
102
|
+
#
|
103
|
+
# ## Column Value Cache
|
104
|
+
#
|
105
|
+
# Enables grid-level caching for column values.
|
106
|
+
#
|
107
|
+
# self.cached = true
|
108
|
+
#
|
109
|
+
# ## Ordering
|
110
|
+
#
|
111
|
+
# Columns can specify SQL ordering expressions using the `:order` and `:order_desc` options.
|
112
|
+
#
|
113
|
+
# Basic ordering:
|
114
|
+
#
|
115
|
+
# column(:group_name, order: "groups.name") { self.group.name }
|
116
|
+
#
|
117
|
+
# In example above descending order is automatically inherited from ascending order specified.
|
118
|
+
# When such default is not enough, specify both options together:
|
119
|
+
#
|
120
|
+
# column(
|
121
|
+
# :priority,
|
122
|
+
# # models with null priority are always on bottom
|
123
|
+
# # no matter if sorting ascending or descending
|
124
|
+
# order: "priority is not null desc, priority",
|
125
|
+
# order_desc: "priority is not null desc, priority desc"
|
126
|
+
# )
|
127
|
+
#
|
128
|
+
# Disable order like this:
|
129
|
+
#
|
130
|
+
# column(:title, order: false)
|
131
|
+
#
|
132
|
+
# Order by joined table
|
133
|
+
# Allows to join specified table only when order is enabled
|
134
|
+
# for performance:
|
135
|
+
#
|
136
|
+
# column(:profile_updated_at, order: proc { |scope|
|
137
|
+
# scope.joins(:profile).order("profiles.updated_at")
|
138
|
+
# }) do |model|
|
139
|
+
# model.profile.updated_at.to_date
|
140
|
+
# end
|
141
|
+
#
|
142
|
+
# Order by a calculated value
|
143
|
+
#
|
144
|
+
# column(
|
145
|
+
# :duration_request,
|
146
|
+
# order: "(requests.finished_at - requests.accepted_at)"
|
147
|
+
# ) do |model|
|
148
|
+
# Time.at(model.finished_at - model.accepted_at).strftime("%H:%M:%S")
|
149
|
+
# end
|
150
|
+
#
|
151
|
+
# ## Default Column Options
|
152
|
+
#
|
153
|
+
# Default options for all columns in a grid can be set using `default_column_options`.
|
154
|
+
#
|
155
|
+
# self.default_column_options = { order: false }
|
156
|
+
#
|
157
|
+
# ## Columns Visibility
|
158
|
+
#
|
159
|
+
# Columns can be dynamically shown or hidden based on the grid's `column_names` accessor.
|
160
|
+
#
|
161
|
+
# grid.column_names = [:id, :name]
|
162
|
+
#
|
163
|
+
# ## Dynamic Columns
|
164
|
+
#
|
165
|
+
# Columns can be defined dynamically on a grid instance or based on data.
|
166
|
+
#
|
167
|
+
# Adding a dynamic column:
|
168
|
+
#
|
169
|
+
# grid.column(:extra_data) do |model|
|
170
|
+
# model.extra_data
|
171
|
+
# end
|
172
|
+
#
|
173
|
+
# ## Localization
|
174
|
+
#
|
175
|
+
# Column headers can be localized using the `:header` option or through i18n files.
|
176
|
+
#
|
177
|
+
# column(:active, header: Proc.new { I18n.t("activated") })
|
178
|
+
#
|
179
|
+
# ## Preloading Associations
|
180
|
+
#
|
181
|
+
# Preload database associations for better performance.
|
182
|
+
#
|
183
|
+
# Automatic association preloading:
|
184
|
+
#
|
185
|
+
# column(:group) do |user|
|
186
|
+
# user.group.name
|
187
|
+
# end
|
188
|
+
#
|
189
|
+
# Custom preloading:
|
190
|
+
#
|
191
|
+
# column(:account_name, preload: { |s| s.includes(:account) })
|
192
|
+
#
|
193
|
+
# ## Decorator
|
194
|
+
#
|
195
|
+
# A decorator or presenter class can be used around each object in the `scope`.
|
196
|
+
#
|
197
|
+
# decorate { UserPresenter }
|
198
|
+
# column(:created_at) do |presenter|
|
199
|
+
# presenter.user.created_at
|
200
|
+
# end
|
6
201
|
module Columns
|
7
202
|
require "datagrid/columns/column"
|
8
203
|
|
9
|
-
# @!method default_column_options=
|
10
|
-
# @param
|
204
|
+
# @!method default_column_options=(value)
|
205
|
+
# @param [Hash] value default options passed to #column method call
|
11
206
|
# @return [Hash] default options passed to #column method call
|
12
207
|
# @example
|
13
208
|
# # Disable default order
|
@@ -19,8 +214,8 @@ module Datagrid
|
|
19
214
|
# @return [Hash]
|
20
215
|
# @see #default_column_options=
|
21
216
|
|
22
|
-
# @!method batch_size=
|
23
|
-
# @param
|
217
|
+
# @!method batch_size=(value)
|
218
|
+
# @param [Integer] value Specify a default batch size when generating CSV or just data. Default: 1000
|
24
219
|
# @return [Integer] Specify a default batch size when generating CSV or just data.
|
25
220
|
# @example
|
26
221
|
# self.batch_size = 500
|
@@ -33,8 +228,9 @@ module Datagrid
|
|
33
228
|
# @see #batch_size=
|
34
229
|
|
35
230
|
# @visibility private
|
231
|
+
# @param [Object] base
|
36
232
|
def self.included(base)
|
37
|
-
base.extend
|
233
|
+
base.extend ClassMethods
|
38
234
|
base.class_eval do
|
39
235
|
include Datagrid::Core
|
40
236
|
|
@@ -47,7 +243,6 @@ module Datagrid
|
|
47
243
|
end
|
48
244
|
|
49
245
|
module ClassMethods
|
50
|
-
|
51
246
|
# @param data [Boolean] if true returns only columns with data representation. Default: false.
|
52
247
|
# @param html [Boolean] if true returns only columns with html columns. Default: false.
|
53
248
|
# @param column_names [Array<String>] list of column names if you want to limit data only to specified columns
|
@@ -62,7 +257,7 @@ module Datagrid
|
|
62
257
|
#
|
63
258
|
# @param name [Symbol] column name
|
64
259
|
# @param query [String, nil] a string representing the query to select this column (supports only ActiveRecord)
|
65
|
-
# @param options [Hash
|
260
|
+
# @param options [Hash{Symbol => Object}] hash of options
|
66
261
|
# @param block [Block] proc to calculate a column value
|
67
262
|
# @return [Datagrid::Columns::Column]
|
68
263
|
#
|
@@ -71,7 +266,7 @@ module Datagrid
|
|
71
266
|
# * <tt>html</tt> - determines if current column should be present in html table and how is it formatted
|
72
267
|
# * <tt>order</tt> - determines if this column could be sortable and how.
|
73
268
|
# The value of order is explicitly passed to ORM ordering method.
|
74
|
-
#
|
269
|
+
# Example: <tt>"created_at, id"</tt> for ActiveRecord, <tt>[:created_at, :id]</tt> for Mongoid
|
75
270
|
# * <tt>order_desc</tt> - determines a descending order for given column
|
76
271
|
# (only in case when <tt>:order</tt> can not be easily reversed by ORM)
|
77
272
|
# * <tt>order_by_value</tt> - used in case it is easier to perform ordering at ruby level not on database level.
|
@@ -85,6 +280,8 @@ module Datagrid
|
|
85
280
|
# * <tt>if</tt> - the column is shown if the reult of calling this argument is true
|
86
281
|
# * <tt>unless</tt> - the column is shown unless the reult of calling this argument is true
|
87
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" }`
|
88
285
|
#
|
89
286
|
# @see https://github.com/bogdan/datagrid/wiki/Columns
|
90
287
|
def column(name, query = nil, **options, &block)
|
@@ -115,7 +312,7 @@ module Datagrid
|
|
115
312
|
# @example
|
116
313
|
# column(:name) do |model|
|
117
314
|
# format(model.name) do |value|
|
118
|
-
#
|
315
|
+
# tag.strong(value)
|
119
316
|
# end
|
120
317
|
# end
|
121
318
|
def format(value, &block)
|
@@ -146,23 +343,25 @@ module Datagrid
|
|
146
343
|
end
|
147
344
|
return self.decorator = block unless model
|
148
345
|
return model unless decorator
|
346
|
+
|
149
347
|
presenter = ::Datagrid::Utils.apply_args(model, &decorator)
|
150
|
-
presenter = presenter.
|
348
|
+
presenter = presenter.new(model) if presenter.is_a?(Class)
|
151
349
|
block_given? ? yield(presenter) : presenter
|
152
350
|
end
|
153
351
|
|
154
352
|
# @!visibility private
|
155
353
|
def inherited(child_class)
|
156
|
-
super
|
157
|
-
child_class.columns_array =
|
354
|
+
super
|
355
|
+
child_class.columns_array = columns_array.clone
|
158
356
|
end
|
159
357
|
|
160
358
|
# @!visibility private
|
161
359
|
def filter_columns(columns_array, *names, data: false, html: false)
|
162
360
|
names.compact!
|
163
|
-
if names.size >= 1 && names.all? {|n| n.is_a?(Datagrid::Columns::Column) && n.grid_class == self.class}
|
361
|
+
if names.size >= 1 && names.all? { |n| n.is_a?(Datagrid::Columns::Column) && n.grid_class == self.class }
|
164
362
|
return names
|
165
363
|
end
|
364
|
+
|
166
365
|
names.map!(&:to_sym)
|
167
366
|
columns_array.select do |column|
|
168
367
|
(!data || column.data?) &&
|
@@ -186,21 +385,21 @@ module Datagrid
|
|
186
385
|
end
|
187
386
|
|
188
387
|
# @!visibility private
|
189
|
-
def find_column_by_name(columns,name)
|
388
|
+
def find_column_by_name(columns, name)
|
190
389
|
return name if name.is_a?(Datagrid::Columns::Column)
|
390
|
+
|
191
391
|
columns.find do |col|
|
192
392
|
col.name.to_sym == name.to_sym
|
193
393
|
end
|
194
394
|
end
|
195
|
-
|
196
395
|
end
|
197
396
|
|
198
397
|
# @!visibility private
|
199
398
|
def assets
|
200
399
|
append_column_preload(
|
201
400
|
driver.append_column_queries(
|
202
|
-
super, columns.select(&:query)
|
203
|
-
)
|
401
|
+
super, columns.select(&:query),
|
402
|
+
),
|
204
403
|
)
|
205
404
|
end
|
206
405
|
|
@@ -223,7 +422,7 @@ module Datagrid
|
|
223
422
|
# @return [Hash] A mapping where keys are column names and values are column values for the given asset
|
224
423
|
def hash_for(asset)
|
225
424
|
result = {}
|
226
|
-
|
425
|
+
data_columns.each do |column|
|
227
426
|
result[column.name] = data_value(column, asset)
|
228
427
|
end
|
229
428
|
result
|
@@ -233,18 +432,17 @@ module Datagrid
|
|
233
432
|
# @return [Array<Array<Object>>] with data for each row in datagrid assets without header
|
234
433
|
def rows(*column_names)
|
235
434
|
map_with_batches do |asset|
|
236
|
-
|
435
|
+
row_for(asset, *column_names)
|
237
436
|
end
|
238
437
|
end
|
239
438
|
|
240
439
|
# @param column_names [Array<String>] list of column names if you want to limit data only to specified columns
|
241
440
|
# @return [Array<Array<Object>>] data for each row in datagrid assets with header.
|
242
441
|
def data(*column_names)
|
243
|
-
|
442
|
+
rows(*column_names).unshift(header(*column_names))
|
244
443
|
end
|
245
444
|
|
246
|
-
#
|
247
|
-
# for each row in filtered datagrid relation.
|
445
|
+
# @return [Array<Hash{Symbol => Object}>] an array of hashes representing the rows in the filtered datagrid relation
|
248
446
|
#
|
249
447
|
# @example
|
250
448
|
# class MyGrid
|
@@ -274,9 +472,9 @@ module Datagrid
|
|
274
472
|
def to_csv(*column_names, **options)
|
275
473
|
require "csv"
|
276
474
|
CSV.generate(
|
277
|
-
headers:
|
475
|
+
headers: header(*column_names),
|
278
476
|
write_headers: true,
|
279
|
-
**options
|
477
|
+
**options,
|
280
478
|
) do |csv|
|
281
479
|
each_with_batches do |asset|
|
282
480
|
csv << row_for(asset, *column_names)
|
@@ -284,8 +482,9 @@ module Datagrid
|
|
284
482
|
end
|
285
483
|
end
|
286
484
|
|
287
|
-
|
288
485
|
# @param column_names [Array<Symbol, String>]
|
486
|
+
# @param [Boolean] data return only data columns
|
487
|
+
# @param [Boolean] html return only HTML columns
|
289
488
|
# @return [Array<Datagrid::Columns::Column>] all columns selected in grid instance
|
290
489
|
# @example
|
291
490
|
# MyGrid.new.columns # => all defined columns
|
@@ -294,22 +493,25 @@ module Datagrid
|
|
294
493
|
# grid.columns(:id, :category) # => id and category column
|
295
494
|
def columns(*column_names, data: false, html: false)
|
296
495
|
self.class.filter_columns(
|
297
|
-
columns_array, *column_names, data: data, html: html
|
496
|
+
columns_array, *column_names, data: data, html: html,
|
298
497
|
).select do |column|
|
299
498
|
column.enabled?(self)
|
300
499
|
end
|
301
500
|
end
|
302
501
|
|
303
|
-
# @param column_names [Array<String, Symbol>] list of column names
|
304
|
-
#
|
305
|
-
|
306
|
-
|
502
|
+
# @param column_names [Array<String, Symbol>] list of column names
|
503
|
+
# if you want to limit data only to specified columns
|
504
|
+
# @param [Boolean] html return only HTML columns
|
505
|
+
# @return [Array<Datagrid::Columns::Column>] columns that can be represented in plain data(non-html) way
|
506
|
+
def data_columns(*column_names, html: false)
|
507
|
+
columns(*column_names, html: html, data: true)
|
307
508
|
end
|
308
509
|
|
309
510
|
# @param column_names [Array<String>] list of column names if you want to limit data only to specified columns
|
511
|
+
# @param [Boolean] data return only data columns
|
310
512
|
# @return all columns that can be represented in HTML table
|
311
|
-
def html_columns(*column_names,
|
312
|
-
|
513
|
+
def html_columns(*column_names, data: false)
|
514
|
+
columns(*column_names, data: data, html: true)
|
313
515
|
end
|
314
516
|
|
315
517
|
# Finds a column definition by name
|
@@ -324,7 +526,7 @@ module Datagrid
|
|
324
526
|
# @example
|
325
527
|
# column(:name) do |model|
|
326
528
|
# format(model.name) do |value|
|
327
|
-
#
|
529
|
+
# tag.strong(value)
|
328
530
|
# end
|
329
531
|
# end
|
330
532
|
#
|
@@ -374,7 +576,8 @@ module Datagrid
|
|
374
576
|
super
|
375
577
|
end
|
376
578
|
|
377
|
-
# @return [Array<Datagrid::Columns::Column>] all columns
|
579
|
+
# @return [Array<Datagrid::Columns::Column>] all columns
|
580
|
+
# that are possible to be displayed for the current grid object
|
378
581
|
#
|
379
582
|
# @example
|
380
583
|
# class MyGrid
|
@@ -402,6 +605,7 @@ module Datagrid
|
|
402
605
|
column = column_by_name(column_name)
|
403
606
|
cache(column, asset, :data_value) do
|
404
607
|
raise "no data value for #{column.name} column" unless column.data?
|
608
|
+
|
405
609
|
result = generic_value(column, asset)
|
406
610
|
result.is_a?(Datagrid::Columns::Column::ResponseFormat) ? result.call_data : result
|
407
611
|
end
|
@@ -409,7 +613,7 @@ module Datagrid
|
|
409
613
|
|
410
614
|
# @return [Object] a cell HTML value for given column name and asset and view context
|
411
615
|
def html_value(column_name, context, asset)
|
412
|
-
column
|
616
|
+
column = column_by_name(column_name)
|
413
617
|
cache(column, asset, :html_value) do
|
414
618
|
if column.html? && column.html_block
|
415
619
|
value_from_html_block(context, asset, column)
|
@@ -462,9 +666,8 @@ module Datagrid
|
|
462
666
|
return yield
|
463
667
|
end
|
464
668
|
key = cache_key(asset)
|
465
|
-
unless key
|
466
|
-
|
467
|
-
end
|
669
|
+
raise(Datagrid::CacheKeyError, "Datagrid Cache key is #{key.inspect} for #{asset.inspect}.") unless key
|
670
|
+
|
468
671
|
@cache[column.name] ||= {}
|
469
672
|
@cache[column.name][key] ||= {}
|
470
673
|
@cache[column.name][key][type] ||= yield
|
@@ -477,10 +680,12 @@ module Datagrid
|
|
477
680
|
driver.default_cache_key(asset)
|
478
681
|
end
|
479
682
|
rescue NotImplementedError
|
480
|
-
raise Datagrid::ConfigurationError,
|
683
|
+
raise Datagrid::ConfigurationError,
|
684
|
+
<<~MSG
|
685
|
+
#{self} is setup to use cache. But there was appropriate cache key found for #{asset.inspect}.
|
686
|
+
MSG
|
481
687
|
end
|
482
688
|
|
483
|
-
|
484
689
|
def map_with_batches(&block)
|
485
690
|
result = []
|
486
691
|
each_with_batches do |asset|
|
@@ -490,7 +695,7 @@ module Datagrid
|
|
490
695
|
end
|
491
696
|
|
492
697
|
def each_with_batches(&block)
|
493
|
-
if batch_size
|
698
|
+
if batch_size&.positive?
|
494
699
|
driver.batch_each(assets, batch_size, &block)
|
495
700
|
else
|
496
701
|
assets.each(&block)
|
@@ -500,7 +705,7 @@ module Datagrid
|
|
500
705
|
def value_from_html_block(context, asset, column)
|
501
706
|
args = []
|
502
707
|
remaining_arity = column.html_block.arity
|
503
|
-
remaining_arity = 1 if remaining_arity
|
708
|
+
remaining_arity = 1 if remaining_arity.negative?
|
504
709
|
|
505
710
|
asset = decorate(asset)
|
506
711
|
|
@@ -509,7 +714,7 @@ module Datagrid
|
|
509
714
|
remaining_arity -= 1
|
510
715
|
end
|
511
716
|
|
512
|
-
args << asset if remaining_arity
|
717
|
+
args << asset if remaining_arity.positive?
|
513
718
|
args << self if remaining_arity > 1
|
514
719
|
|
515
720
|
context.instance_exec(*args, &column.html_block)
|
@@ -523,9 +728,13 @@ module Datagrid
|
|
523
728
|
@model = model
|
524
729
|
end
|
525
730
|
|
526
|
-
def method_missing(meth, *
|
731
|
+
def method_missing(meth, *_args)
|
527
732
|
@grid.data_value(meth, @model)
|
528
733
|
end
|
734
|
+
|
735
|
+
def respond_to_missing?(meth, include_private = false)
|
736
|
+
!!@grid.column_by_name(meth) || super
|
737
|
+
end
|
529
738
|
end
|
530
739
|
end
|
531
740
|
end
|
@@ -1,14 +1,27 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
def self.configuration
|
4
|
-
@configuration ||= Configuration.new
|
5
|
-
end
|
1
|
+
# frozen_string_literal: true
|
6
2
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
#
|
3
|
+
module Datagrid
|
4
|
+
# ## Configuration
|
5
|
+
#
|
6
|
+
# Datagrid provides several configuration options.
|
7
|
+
#
|
8
|
+
# Here is the API reference and a description of the available options:
|
9
|
+
#
|
10
|
+
# ``` ruby
|
11
|
+
# Datagrid.configure do |config|
|
12
|
+
# # Defines date formats that can be used to parse dates.
|
13
|
+
# # 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"]
|
16
|
+
#
|
17
|
+
# # Defines timestamp formats that can be used to parse timestamps.
|
18
|
+
# # 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).
|
20
|
+
# config.datetime_formats = ["%m/%d/%Y %h:%M", "%Y-%m-%d %h:%M:%s"]
|
21
|
+
# end
|
22
|
+
# ```
|
23
|
+
#
|
24
|
+
# These options can be set globally in your application to customize Datagrid’s behavior.
|
12
25
|
class Configuration
|
13
26
|
# @return [Array<String>] Date parsing formats
|
14
27
|
attr_accessor :date_formats
|