datagrid 1.6.3 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,143 +6,116 @@ module Datagrid
6
6
  module Columns
7
7
  require "datagrid/columns/column"
8
8
 
9
+ # @!method default_column_options=
10
+ # @param value [Hash] default options passed to #column method call
11
+ # @return [Hash] default options passed to #column method call
12
+ # @example
13
+ # # Disable default order
14
+ # self.default_column_options = { order: false }
15
+ # # Makes entire report HTML
16
+ # self.default_column_options = { html: true }
17
+
18
+ # @!method default_column_options
19
+ # @return [Hash]
20
+ # @see #default_column_options=
21
+
22
+ # @!method batch_size=
23
+ # @param value [Integer] Specify a default batch size when generating CSV or just data. Default: 1000
24
+ # @return [Integer] Specify a default batch size when generating CSV or just data.
25
+ # @example
26
+ # self.batch_size = 500
27
+ # # Disable batches
28
+ # self.batch_size = nil
29
+ #
30
+
31
+ # @!method batch_size
32
+ # @return [Integer]
33
+ # @see #batch_size=
34
+
35
+ # @visibility private
9
36
  def self.included(base)
10
37
  base.extend ClassMethods
11
38
  base.class_eval do
12
-
13
39
  include Datagrid::Core
14
40
 
15
- class_attribute :default_column_options, :instance_writer => false
16
- self.default_column_options = {}
17
-
18
- class_attribute :batch_size
19
- self.batch_size = 1000
20
-
21
- class_attribute :columns_array
22
- self.columns_array = []
23
-
24
- class_attribute :cached
25
- self.cached = false
26
-
27
-
41
+ class_attribute :default_column_options, instance_writer: false, default: {}
42
+ class_attribute :batch_size, default: 1000
43
+ class_attribute :columns_array, default: []
44
+ class_attribute :cached, default: false
28
45
  class_attribute :decorator, instance_writer: false
29
-
30
46
  end
31
47
  base.send :include, InstanceMethods
32
- end # self.included
48
+ end
33
49
 
34
50
  module ClassMethods
35
51
 
36
- ##
37
- # :method: batch_size=
38
- #
39
- # :call-seq: batch_size=(size)
40
- #
41
- # Specify a default batch size when generating CSV or just data
42
- # Default: 1000
43
- #
44
- # self.batch_size = 500
45
- # # Disable batches
46
- # self.batch_size = nil
47
- #
48
-
49
- ##
50
- # :method: batch_size
51
- #
52
- # :call-seq: batch_size
53
- #
54
- # Returns specified batch_size configuration variable
55
- # See <tt>batch_size=</tt> for more information
56
- #
57
-
58
- ##
59
- # :method: default_column_options=
60
- #
61
- # :call-seq: default_column_options=(options)
62
- #
63
- # Specifies default options for `column` method.
64
- # They still can be overwritten at column level.
65
- #
66
- # # Disable default order
67
- # self.default_column_options = { :order => false }
68
- # # Makes entire report HTML
69
- # self.default_column_options = { :html => true }
70
- #
71
52
 
72
- ##
73
- # :method: default_column_options
74
- #
75
- # :call-seq: default_column_options
76
- #
77
- # Returns specified default column options hash
78
- # See <tt>default_column_options=</tt> for more information
79
- #
80
53
 
81
- # Returns a list of columns defined.
82
- # All column definistion are returned by default
83
- # You can limit the output with only columns you need like:
84
- #
54
+ # @param data [Boolean] if true returns only columns with data representation. Default: false.
55
+ # @param html [Boolean] if true returns only columns with html columns. Default: false.
56
+ # @param column_names [Array<String>] list of column names if you want to limit data only to specified columns
57
+ # @return [Array<Datagrid::Columns::Column>] column definition objects
58
+ # @example
85
59
  # GridClass.columns(:id, :name)
86
- #
87
- # Supported options:
88
- #
89
- # * :data - if true returns only columns with data representation. Default: false.
90
- # * :html - if true returns only columns with html columns. Default: false.
91
- def columns(*args, data: false, html: false)
92
- filter_columns(columns_array, *args, data: data, html: html)
60
+ def columns(*column_names, data: false, html: false)
61
+ filter_columns(columns_array, *column_names, data: data, html: html)
93
62
  end
94
63
 
95
64
  # Defines new datagrid column
96
65
  #
97
- # Arguments:
98
- #
99
- # * <tt>name</tt> - column name
100
- # * <tt>query</tt> - a string representing the query to select this column (supports only ActiveRecord)
101
- # * <tt>options</tt> - hash of options
102
- # * <tt>block</tt> - proc to calculate a column value
66
+ # @param name [Symbol] column name
67
+ # @param query [String, nil] a string representing the query to select this column (supports only ActiveRecord)
68
+ # @param options [Hash<Symbol, Object>] hash of options
69
+ # @param block [Block] proc to calculate a column value
70
+ # @return [Datagrid::Columns::Column]
103
71
  #
104
72
  # Available options:
105
73
  #
106
- # * <tt>:html</tt> - determines if current column should be present in html table and how is it formatted
107
- # * <tt>:order</tt> - determines if this column could be sortable and how.
74
+ # * <tt>html</tt> - determines if current column should be present in html table and how is it formatted
75
+ # * <tt>order</tt> - determines if this column could be sortable and how.
108
76
  # The value of order is explicitly passed to ORM ordering method.
109
77
  # Ex: <tt>"created_at, id"</tt> for ActiveRecord, <tt>[:created_at, :id]</tt> for Mongoid
110
- # * <tt>:order_desc</tt> - determines a descending order for given column
78
+ # * <tt>order_desc</tt> - determines a descending order for given column
111
79
  # (only in case when <tt>:order</tt> can not be easily reversed by ORM)
112
- # * <tt>:order_by_value</tt> - used in case it is easier to perform ordering at ruby level not on database level.
80
+ # * <tt>order_by_value</tt> - used in case it is easier to perform ordering at ruby level not on database level.
113
81
  # Warning: using ruby to order large datasets is very unrecommended.
114
82
  # If set to true - datagrid will use column value to order by this column
115
83
  # If block is given - datagrid will use value returned from block
116
- # * <tt>:mandatory</tt> - if true, column will never be hidden with #column_names selection
117
- # * <tt>:url</tt> - a proc with one argument, pass this option to easily convert the value into an URL
118
- # * <tt>:before</tt> - determines the position of this column, by adding it before the column passed here
119
- # * <tt>:after</tt> - determines the position of this column, by adding it after the column passed here
120
- # * <tt>:if</tt> - the column is shown if the reult of calling this argument is true
121
- # * <tt>:unless</tt> - the column is shown unless the reult of calling this argument is true
122
- # * <tt>:preload</tt> - spefies which associations of the scope should be preloaded for this column
123
- #
124
- # See: https://github.com/bogdan/datagrid/wiki/Columns for examples
84
+ # * <tt>mandatory</tt> - if true, column will never be hidden with #column_names selection
85
+ # * <tt>url</tt> - a proc with one argument, pass this option to easily convert the value into an URL
86
+ # * <tt>before</tt> - determines the position of this column, by adding it before the column passed here
87
+ # * <tt>after</tt> - determines the position of this column, by adding it after the column passed here
88
+ # * <tt>if</tt> - the column is shown if the reult of calling this argument is true
89
+ # * <tt>unless</tt> - the column is shown unless the reult of calling this argument is true
90
+ # * <tt>preload</tt> - spefies which associations of the scope should be preloaded for this column
91
+ #
92
+ # @see https://github.com/bogdan/datagrid/wiki/Columns
125
93
  def column(name, query = nil, **options, &block)
126
94
  define_column(columns_array, name, query, **options, &block)
127
95
  end
128
96
 
129
97
  # Returns column definition with given name
98
+ # @return [Datagrid::Columns::Column, nil]
130
99
  def column_by_name(name)
131
100
  find_column_by_name(columns_array, name)
132
101
  end
133
102
 
134
103
  # Returns an array of all defined column names
104
+ # @return [Array<Datagrid::Columns::Column>]
135
105
  def column_names
136
106
  columns.map(&:name)
137
107
  end
138
108
 
139
- def respond_to(&block) #:nodoc:
109
+ # @!visibility private
110
+ def respond_to(&block)
140
111
  Datagrid::Columns::Column::ResponseFormat.new(&block)
141
112
  end
142
113
 
143
114
  # Formats column value for HTML.
144
115
  # Helps to distinguish formatting as plain data and HTML
145
- #
116
+ # @param value [Object] Value to be formatted
117
+ # @return [Datagrid::Columns::Column::ResponseFormat] Format object
118
+ # @example
146
119
  # column(:name) do |model|
147
120
  # format(model.name) do |value|
148
121
  # content_tag(:strong, value)
@@ -165,7 +138,8 @@ module Datagrid
165
138
 
166
139
  # Defines a model decorator that will be used to define a column value.
167
140
  # All column blocks will be given a decorated version of the model.
168
- #
141
+ # @return [void]
142
+ # @example
169
143
  # decorate { |user| UserPresenter.new(user) }
170
144
  #
171
145
  # decorate { UserPresenter } # a shortcut
@@ -180,12 +154,14 @@ module Datagrid
180
154
  block_given? ? yield(presenter) : presenter
181
155
  end
182
156
 
183
- def inherited(child_class) #:nodoc:
157
+ # @!visibility private
158
+ def inherited(child_class)
184
159
  super(child_class)
185
160
  child_class.columns_array = self.columns_array.clone
186
161
  end
187
162
 
188
- def filter_columns(columns_array, *names, data: false, html: false) #:nodoc:
163
+ # @!visibility private
164
+ def filter_columns(columns_array, *names, data: false, html: false)
189
165
  names.compact!
190
166
  names.map!(&:to_sym)
191
167
  columns_array.select do |column|
@@ -195,7 +171,8 @@ module Datagrid
195
171
  end
196
172
  end
197
173
 
198
- def define_column(columns, name, query = nil, **options, &block) #:nodoc:
174
+ # @!visibility private
175
+ def define_column(columns, name, query = nil, **options, &block)
199
176
  check_scope_defined!("Scope should be defined before columns")
200
177
  block ||= lambda do |model|
201
178
  model.send(name)
@@ -205,19 +182,22 @@ module Datagrid
205
182
  self, name, query, default_column_options.merge(options), &block
206
183
  )
207
184
  columns.insert(position, column)
185
+ column
208
186
  end
209
187
 
210
- def find_column_by_name(columns,name) #:nodoc:
188
+ # @!visibility private
189
+ def find_column_by_name(columns,name)
211
190
  return name if name.is_a?(Datagrid::Columns::Column)
212
191
  columns.find do |col|
213
192
  col.name.to_sym == name.to_sym
214
193
  end
215
194
  end
216
195
 
217
- end # ClassMethods
196
+ end
218
197
 
219
198
  module InstanceMethods
220
199
 
200
+ # @!visibility private
221
201
  def assets
222
202
  append_column_preload(
223
203
  driver.append_column_queries(
@@ -226,27 +206,23 @@ module Datagrid
226
206
  )
227
207
  end
228
208
 
229
- # Returns <tt>Array</tt> of human readable column names. See also "Localization" section
230
- #
231
- # Arguments:
232
- #
233
- # * <tt>column_names</tt> - list of column names if you want to limit data only to specified columns
209
+ # @param column_names [Array<String>] list of column names if you want to limit data only to specified columns
210
+ # @return [Array<String>] human readable column names. See also "Localization" section
234
211
  def header(*column_names)
235
212
  data_columns(*column_names).map(&:header)
236
213
  end
237
214
 
238
- # Returns <tt>Array</tt> column values for given asset
239
- #
240
- # Arguments:
241
- #
242
- # * <tt>column_names</tt> - list of column names if you want to limit data only to specified columns
215
+ # @param asset [Object] asset from datagrid scope
216
+ # @param column_names [Array<String>] list of column names if you want to limit data only to specified columns
217
+ # @return [Array<Object>] column values for given asset
243
218
  def row_for(asset, *column_names)
244
219
  data_columns(*column_names).map do |column|
245
220
  data_value(column, asset)
246
221
  end
247
222
  end
248
223
 
249
- # Returns <tt>Hash</tt> where keys are column names and values are column values for the given asset
224
+ # @param asset [Object] asset from datagrid scope
225
+ # @return [Hash] A mapping where keys are column names and values are column values for the given asset
250
226
  def hash_for(asset)
251
227
  result = {}
252
228
  self.data_columns.each do |column|
@@ -255,22 +231,16 @@ module Datagrid
255
231
  result
256
232
  end
257
233
 
258
- # Returns Array of Arrays with data for each row in datagrid assets without header.
259
- #
260
- # Arguments:
261
- #
262
- # * <tt>column_names</tt> - list of column names if you want to limit data only to specified columns
234
+ # @param column_names [Array<String>] list of column names if you want to limit data only to specified columns
235
+ # @return [Array<Array<Object>>] with data for each row in datagrid assets without header
263
236
  def rows(*column_names)
264
237
  map_with_batches do |asset|
265
238
  self.row_for(asset, *column_names)
266
239
  end
267
240
  end
268
241
 
269
- # Returns Array of Arrays with data for each row in datagrid assets with header.
270
- #
271
- # Arguments:
272
- #
273
- # * <tt>column_names</tt> - list of column names if you want to limit data only to specified columns
242
+ # @param column_names [Array<String>] list of column names if you want to limit data only to specified columns
243
+ # @return [Array<Array<Object>>] data for each row in datagrid assets with header.
274
244
  def data(*column_names)
275
245
  self.rows(*column_names).unshift(self.header(*column_names))
276
246
  end
@@ -278,36 +248,31 @@ module Datagrid
278
248
  # Return Array of Hashes where keys are column names and values are column values
279
249
  # for each row in filtered datagrid relation.
280
250
  #
281
- # Example:
282
- #
283
- # class MyGrid
284
- # scope { Model }
285
- # column(:id)
286
- # column(:name)
287
- # end
288
- #
289
- # Model.create!(:name => "One")
290
- # Model.create!(:name => "Two")
251
+ # @example
252
+ # class MyGrid
253
+ # scope { Model }
254
+ # column(:id)
255
+ # column(:name)
256
+ # end
291
257
  #
292
- # MyGrid.new.data_hash # => [{:name => "One"}, {:name => "Two"}]
258
+ # Model.create!(name: "One")
259
+ # Model.create!(name: "Two")
293
260
  #
261
+ # MyGrid.new.data_hash # => [{name: "One"}, {name: "Two"}]
294
262
  def data_hash
295
263
  map_with_batches do |asset|
296
264
  hash_for(asset)
297
265
  end
298
266
  end
299
267
 
300
- # Returns a CSV representation of the data in the grid
301
- # You are able to specify which columns you want to see in CSV.
302
- # All data columns are included by default
303
- # Also you can specify options hash as last argument that is proxied to
304
- # Ruby CSV library.
305
- #
306
- # Example:
268
+ # @param column_names [Array<String>]
269
+ # @param options [Hash] CSV generation options
270
+ # @return [String] a CSV representation of the data in the grid
307
271
  #
272
+ # @example
308
273
  # grid.to_csv
309
274
  # grid.to_csv(:id, :name)
310
- # grid.to_csv(:col_sep => ';')
275
+ # grid.to_csv(col_sep: ';')
311
276
  def to_csv(*column_names, **options)
312
277
  require "csv"
313
278
  CSV.generate(
@@ -322,41 +287,43 @@ module Datagrid
322
287
  end
323
288
 
324
289
 
325
- # Returns all columns selected in grid instance
326
- #
327
- # Examples:
328
- #
290
+ # @param column_names [Array<Symbol, String>]
291
+ # @return [Array<Datagrid::Columns::Column>] all columns selected in grid instance
292
+ # @example
329
293
  # MyGrid.new.columns # => all defined columns
330
- # grid = MyGrid.new(:column_names => [:id, :name])
294
+ # grid = MyGrid.new(column_names: [:id, :name])
331
295
  # grid.columns # => id and name columns
332
296
  # grid.columns(:id, :category) # => id and category column
333
- def columns(*args, data: false, html: false)
297
+ def columns(*column_names, data: false, html: false)
334
298
  self.class.filter_columns(
335
- columns_array, *args, data: data, html: html
299
+ columns_array, *column_names, data: data, html: html
336
300
  ).select do |column|
337
301
  column.enabled?(self)
338
302
  end
339
303
  end
340
304
 
341
- # Returns all columns that can be represented in plain data(non-html) way
342
- def data_columns(*names, **options)
343
- self.columns(*names, **options, data: true)
305
+ # @param column_names [Array<String, Symbol>] list of column names if you want to limit data only to specified columns
306
+ # @return columns that can be represented in plain data(non-html) way
307
+ def data_columns(*column_names, **options)
308
+ self.columns(*column_names, **options, data: true)
344
309
  end
345
310
 
346
- # Returns all columns that can be represented in HTML table
347
- def html_columns(*names, **options)
348
- self.columns(*names, **options, html: true)
311
+ # @param column_names [Array<String>] list of column names if you want to limit data only to specified columns
312
+ # @return all columns that can be represented in HTML table
313
+ def html_columns(*column_names, **options)
314
+ self.columns(*column_names, **options, html: true)
349
315
  end
350
316
 
351
317
  # Finds a column definition by name
318
+ # @param name [String, Symbol] column name to be found
319
+ # @return [Datagrid::Columns::Column, nil]
352
320
  def column_by_name(name)
353
321
  self.class.find_column_by_name(columns_array, name)
354
322
  end
355
323
 
356
324
  # Gives ability to have a different formatting for CSV and HTML column value.
357
325
  #
358
- # Example:
359
- #
326
+ # @example
360
327
  # column(:name) do |model|
361
328
  # format(model.name) do |value|
362
329
  # content_tag(:strong, value)
@@ -365,9 +332,10 @@ module Datagrid
365
332
  #
366
333
  # column(:company) do |model|
367
334
  # format(model.company.name) do
368
- # render :partial => "company_with_logo", :locals => {:company => model.company }
335
+ # render partial: "company_with_logo", locals: {company: model.company }
369
336
  # end
370
337
  # end
338
+ # @return [Datagrid::Columns::Column::ResponseFormat] Format object
371
339
  def format(value, &block)
372
340
  if block_given?
373
341
  self.class.format(value, &block)
@@ -377,11 +345,8 @@ module Datagrid
377
345
  end
378
346
  end
379
347
 
380
- # Returns an object representing a grid row.
381
- # Allows to access column values
382
- #
383
- # Example:
384
- #
348
+ # @return [Datagrid::Columns::DataRow] an object representing a grid row.
349
+ # @example
385
350
  # class MyGrid
386
351
  # scope { User }
387
352
  # column(:id)
@@ -400,23 +365,25 @@ module Datagrid
400
365
 
401
366
  # Defines a column at instance level
402
367
  #
403
- # See Datagrid::Columns::ClassMethods#column for more info
368
+ # @see Datagrid::Columns::ClassMethods#column
404
369
  def column(name, query = nil, **options, &block)
405
370
  self.class.define_column(columns_array, name, query, **options, &block)
406
371
  end
407
372
 
408
- def initialize(*) #:nodoc:
373
+ # @!visibility private
374
+ def initialize(*)
409
375
  self.columns_array = self.class.columns_array.clone
410
376
  super
411
377
  end
412
378
 
413
- # Returns all columns that are possible to be displayed for the current grid object
379
+ # @return [Array<Datagrid::Columns::Column>] all columns that are possible to be displayed for the current grid object
414
380
  #
381
+ # @example
415
382
  # class MyGrid
416
383
  # filter(:search) {|scope, value| scope.full_text_search(value)}
417
384
  # column(:id)
418
- # column(:name, :mandatory => true)
419
- # column(:search_match, :if => proc {|grid| grid.search.present? }) do |model, grid|
385
+ # column(:name, mandatory: true)
386
+ # column(:search_match, if: proc {|grid| grid.search.present? }) do |model, grid|
420
387
  # search_match_line(model.searchable_content, grid.search)
421
388
  # end
422
389
  # end
@@ -426,14 +393,13 @@ module Datagrid
426
393
  # grid.available_columns # => [ #<Column:id>, #<Column:name> ]
427
394
  # grid.search = "keyword"
428
395
  # grid.available_columns # => [ #<Column:id>, #<Column:name>, #<Column:search_match> ]
429
- #
430
396
  def available_columns
431
397
  columns_array.select do |column|
432
398
  column.enabled?(self)
433
399
  end
434
400
  end
435
401
 
436
- # Return a cell data value for given column name and asset
402
+ # @return [Object] a cell data value for given column name and asset
437
403
  def data_value(column_name, asset)
438
404
  column = column_by_name(column_name)
439
405
  cache(column, asset, :data_value) do
@@ -443,7 +409,7 @@ module Datagrid
443
409
  end
444
410
  end
445
411
 
446
- # Return a cell HTML value for given column name and asset and view context
412
+ # @return [Object] a cell HTML value for given column name and asset and view context
447
413
  def html_value(column_name, context, asset)
448
414
  column = column_by_name(column_name)
449
415
  cache(column, asset, :html_value) do
@@ -456,12 +422,13 @@ module Datagrid
456
422
  end
457
423
  end
458
424
 
459
- # Returns a decorated version of given model if decorator is specified or the model otherwise.
425
+ # @return [Object] a decorated version of given model if decorator is specified or the model otherwise.
460
426
  def decorate(model)
461
427
  self.class.decorate(model)
462
428
  end
463
429
 
464
- def generic_value(column, model) #:nodoc:
430
+ # @!visibility private
431
+ def generic_value(column, model)
465
432
  cache(column, model, :generic_value) do
466
433
  presenter = decorate(model)
467
434
  unless column.enabled?(self)
@@ -544,10 +511,11 @@ module Datagrid
544
511
 
545
512
  context.instance_exec(*args, &column.html_block)
546
513
  end
547
- end # InstanceMethods
548
-
549
- class DataRow
514
+ end
550
515
 
516
+ # Object representing a single row of data when building a datagrid table
517
+ # @see Datagrid::Columns::InstanceMethods#data_row
518
+ class DataRow < BasicObject
551
519
  def initialize(grid, model)
552
520
  @grid = grid
553
521
  @model = model
@@ -8,6 +8,11 @@ module Datagrid
8
8
  yield(configuration)
9
9
  end
10
10
 
11
- class Configuration < Struct.new(:date_formats, :datetime_formats)
11
+ # Datagrid configuration object
12
+ class Configuration
13
+ # @return [Array<String>] Date parsing formats
14
+ attr_accessor :date_formats
15
+ # @return [Array<String>] Timestamp parsing formats
16
+ attr_accessor :datetime_formats
12
17
  end
13
18
  end