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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -1
  3. data/{Readme.markdown → README.md} +44 -27
  4. data/app/assets/stylesheets/datagrid.css +145 -0
  5. data/app/views/datagrid/_enum_checkboxes.html.erb +5 -3
  6. data/app/views/datagrid/_form.html.erb +4 -4
  7. data/app/views/datagrid/_head.html.erb +26 -3
  8. data/app/views/datagrid/_range_filter.html.erb +5 -3
  9. data/app/views/datagrid/_row.html.erb +12 -1
  10. data/app/views/datagrid/_table.html.erb +4 -4
  11. data/datagrid.gemspec +6 -6
  12. data/lib/datagrid/active_model.rb +9 -17
  13. data/lib/datagrid/base.rb +39 -0
  14. data/lib/datagrid/column_names_attribute.rb +9 -11
  15. data/lib/datagrid/columns/column.rb +155 -133
  16. data/lib/datagrid/columns.rb +254 -45
  17. data/lib/datagrid/configuration.rb +23 -10
  18. data/lib/datagrid/core.rb +89 -54
  19. data/lib/datagrid/deprecated_object.rb +20 -0
  20. data/lib/datagrid/drivers/abstract_driver.rb +12 -23
  21. data/lib/datagrid/drivers/active_record.rb +24 -26
  22. data/lib/datagrid/drivers/array.rb +22 -14
  23. data/lib/datagrid/drivers/mongo_mapper.rb +15 -14
  24. data/lib/datagrid/drivers/mongoid.rb +15 -17
  25. data/lib/datagrid/drivers/sequel.rb +14 -19
  26. data/lib/datagrid/drivers.rb +2 -1
  27. data/lib/datagrid/engine.rb +11 -3
  28. data/lib/datagrid/filters/base_filter.rb +166 -142
  29. data/lib/datagrid/filters/boolean_filter.rb +19 -5
  30. data/lib/datagrid/filters/date_filter.rb +33 -35
  31. data/lib/datagrid/filters/date_time_filter.rb +24 -16
  32. data/lib/datagrid/filters/default_filter.rb +9 -3
  33. data/lib/datagrid/filters/dynamic_filter.rb +151 -105
  34. data/lib/datagrid/filters/enum_filter.rb +43 -19
  35. data/lib/datagrid/filters/extended_boolean_filter.rb +39 -30
  36. data/lib/datagrid/filters/float_filter.rb +16 -5
  37. data/lib/datagrid/filters/integer_filter.rb +21 -10
  38. data/lib/datagrid/filters/ranged_filter.rb +66 -45
  39. data/lib/datagrid/filters/select_options.rb +58 -49
  40. data/lib/datagrid/filters/string_filter.rb +9 -4
  41. data/lib/datagrid/filters.rb +190 -57
  42. data/lib/datagrid/form_builder.rb +116 -128
  43. data/lib/datagrid/generators/scaffold.rb +185 -0
  44. data/lib/datagrid/generators/views.rb +20 -0
  45. data/lib/datagrid/helper.rb +397 -22
  46. data/lib/datagrid/ordering.rb +26 -29
  47. data/lib/datagrid/rspec.rb +6 -10
  48. data/lib/datagrid/utils.rb +37 -30
  49. data/lib/datagrid/version.rb +3 -1
  50. data/lib/datagrid.rb +18 -28
  51. data/templates/base.rb.erb +6 -4
  52. data/templates/grid.rb.erb +1 -1
  53. metadata +15 -16
  54. data/app/assets/stylesheets/datagrid.sass +0 -134
  55. data/lib/datagrid/filters/composite_filters.rb +0 -49
  56. data/lib/datagrid/renderer.rb +0 -157
  57. data/lib/datagrid/scaffold.rb +0 -129
  58. data/lib/tasks/datagrid_tasks.rake +0 -15
  59. data/templates/controller.rb.erb +0 -6
  60. data/templates/index.html.erb +0 -5
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Datagrid
2
4
  module Drivers
3
5
  # @!visibility private
4
6
  class Mongoid < AbstractDriver
5
-
6
7
  def self.match?(scope)
7
8
  return false unless defined?(::Mongoid)
9
+
8
10
  if scope.is_a?(Class)
9
11
  scope.ancestors.include?(::Mongoid::Document)
10
12
  else
@@ -21,9 +23,7 @@ module Datagrid
21
23
  end
22
24
 
23
25
  def where(scope, attribute, value)
24
- if value.is_a?(Range)
25
- value = {"$gte" => value.first, "$lte" => value.last}
26
- end
26
+ value = { "$gte" => value.first, "$lte" => value.last } if value.is_a?(Range)
27
27
  scope.where(attribute => value)
28
28
  end
29
29
 
@@ -36,18 +36,18 @@ module Datagrid
36
36
  end
37
37
 
38
38
  def default_order(scope, column_name)
39
- has_column?(scope, column_name) ? column_name : nil
39
+ scope_has_column?(scope, column_name) ? column_name : nil
40
40
  end
41
41
 
42
42
  def greater_equal(scope, field, value)
43
- scope.where(field => {"$gte" => value})
43
+ scope.where(field => { "$gte" => value })
44
44
  end
45
45
 
46
46
  def less_equal(scope, field, value)
47
- scope.where(field => {"$lte" => value})
47
+ scope.where(field => { "$lte" => value })
48
48
  end
49
49
 
50
- def has_column?(scope, column_name)
50
+ def scope_has_column?(scope, column_name)
51
51
  column_names(scope).include?(column_name.to_s)
52
52
  end
53
53
 
@@ -62,8 +62,9 @@ module Datagrid
62
62
  def normalized_column_type(scope, field)
63
63
  type = to_scope(scope).klass.fields[field.to_s]&.type
64
64
  return nil unless type
65
+
65
66
  {
66
- [BigDecimal , String, Symbol, Range, Array, Hash, ] => :string,
67
+ [BigDecimal, String, Symbol, Range, Array, Hash] => :string,
67
68
  [::Mongoid::Boolean] => :boolean,
68
69
 
69
70
  [Date] => :date,
@@ -76,7 +77,7 @@ module Datagrid
76
77
  }.each do |keys, value|
77
78
  return value if keys.include?(type)
78
79
  end
79
- return :string
80
+ :string
80
81
  end
81
82
 
82
83
  def batch_each(scope, batch_size, &block)
@@ -84,10 +85,9 @@ module Datagrid
84
85
  loop do
85
86
  batch = scope.skip(current_page * batch_size).limit(batch_size).to_a
86
87
  return if batch.empty?
87
- scope.skip(current_page * batch_size).limit(batch_size).each do |item|
88
- yield(item)
89
- end
90
- current_page+=1
88
+
89
+ scope.skip(current_page * batch_size).limit(batch_size).each(&block)
90
+ current_page += 1
91
91
  end
92
92
  end
93
93
 
@@ -100,10 +100,8 @@ module Datagrid
100
100
  end
101
101
 
102
102
  def can_preload?(scope, association)
103
- !! scope.klass.reflect_on_association(association)
103
+ !!scope.klass.reflect_on_association(association)
104
104
  end
105
-
106
105
  end
107
106
  end
108
107
  end
109
-
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Datagrid
2
4
  module Drivers
3
5
  # @!visibility private
4
6
  class Sequel < AbstractDriver
5
-
6
7
  def self.match?(scope)
7
8
  return false unless defined?(::Sequel)
9
+
8
10
  if scope.is_a?(Class)
9
11
  scope.ancestors.include?(::Sequel::Model)
10
12
  else
@@ -14,11 +16,8 @@ module Datagrid
14
16
 
15
17
  def to_scope(scope)
16
18
  return scope if scope.is_a?(::Sequel::Dataset)
17
- scope.where({})
18
- end
19
19
 
20
- def append_column_queries(assets, columns)
21
- super
20
+ scope.where({})
22
21
  end
23
22
 
24
23
  def where(scope, attribute, value)
@@ -33,12 +32,8 @@ module Datagrid
33
32
  scope.order(::Sequel.desc(::Sequel.lit(order)))
34
33
  end
35
34
 
36
- def reverse_order(scope)
37
- super
38
- end
39
-
40
35
  def default_order(scope, column_name)
41
- has_column?(scope, column_name) ? ::Sequel.lit(prefix_table_name(scope, column_name)) : nil
36
+ scope_has_column?(scope, column_name) ? ::Sequel.lit(prefix_table_name(scope, column_name)) : nil
42
37
  end
43
38
 
44
39
  def greater_equal(scope, field, value)
@@ -49,7 +44,7 @@ module Datagrid
49
44
  scope.where(::Sequel.lit("#{prefix_table_name(scope, field)} <= ?", value))
50
45
  end
51
46
 
52
- def has_column?(scope, column_name)
47
+ def scope_has_column?(scope, column_name)
53
48
  scope.columns.include?(column_name.to_sym)
54
49
  end
55
50
 
@@ -65,13 +60,14 @@ module Datagrid
65
60
  def normalized_column_type(scope, field)
66
61
  type = column_type(scope, field)
67
62
  return nil unless type
63
+
68
64
  {
69
- [:string, :blob, :time] => :string,
70
- [:integer, :primary_key] => :integer,
71
- [:float, :decimal] => :float,
65
+ %i[string blob time] => :string,
66
+ %i[integer primary_key] => :integer,
67
+ %i[float decimal] => :float,
72
68
  [:date] => :date,
73
69
  [:datetime] => :timestamp,
74
- [:boolean] => :boolean
70
+ [:boolean] => :boolean,
75
71
  }.each do |keys, value|
76
72
  return value if keys.include?(type)
77
73
  end
@@ -96,18 +92,17 @@ module Datagrid
96
92
  end
97
93
 
98
94
  def can_preload?(scope, association)
99
- !! scope.model.association_reflection(association)
95
+ !!scope.model.association_reflection(association)
100
96
  end
101
97
 
102
-
103
98
  protected
104
99
 
105
100
  def prefix_table_name(scope, field)
106
- has_column?(scope, field) ? [to_scope(scope).row_proc.table_name, field].join(".") : field
101
+ scope_has_column?(scope, field) ? [to_scope(scope).row_proc.table_name, field].join(".") : field
107
102
  end
108
103
 
109
104
  def column_type(scope, field)
110
- has_column?(scope, field) ? to_scope(scope).row_proc.db_schema[field.to_sym][:type] : nil
105
+ scope_has_column?(scope, field) ? to_scope(scope).row_proc.db_schema[field.to_sym][:type] : nil
111
106
  end
112
107
  end
113
108
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "datagrid/drivers/abstract_driver"
2
4
  require "datagrid/drivers/active_record"
3
5
  require "datagrid/drivers/array"
@@ -5,7 +7,6 @@ require "datagrid/drivers/mongoid"
5
7
  require "datagrid/drivers/mongo_mapper"
6
8
  require "datagrid/drivers/sequel"
7
9
 
8
-
9
10
  module Datagrid
10
11
  # @!visibility private
11
12
  module Drivers
@@ -1,12 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rails/engine"
4
+ require "datagrid/helper"
5
+ require "datagrid/form_builder"
2
6
 
3
7
  module Datagrid
4
- # @!private
8
+ # @!visibility private
5
9
  class Engine < ::Rails::Engine
10
+ def self.extend_modules
11
+ ActionView::Base.include(Datagrid::Helper)
12
+ ActionView::Helpers::FormBuilder.include(Datagrid::FormBuilder)
13
+ end
14
+
6
15
  initializer "datagrid.helpers" do
7
- #TODO: check why it doesn't work
8
16
  ActiveSupport.on_load :action_view do
9
- include Datagrid::Helper
17
+ Engine.extend_modules
10
18
  end
11
19
  end
12
20
  end
@@ -1,184 +1,208 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # An error raise when datagrid filter is defined incorrectly and
2
4
  # causes filtering chain to be broken
3
- class Datagrid::FilteringError < StandardError
5
+ module Datagrid
6
+ class FilteringError < StandardError
7
+ end
4
8
  end
5
9
 
6
10
  # @!visibility private
7
- class Datagrid::Filters::BaseFilter
11
+ module Datagrid
12
+ module Filters
13
+ class BaseFilter
14
+ attr_accessor :grid_class, :options, :block, :name
15
+
16
+ def initialize(grid_class, name, **options, &block)
17
+ self.grid_class = grid_class
18
+ self.name = name.to_sym
19
+ self.options = options
20
+ self.block = block
21
+ end
8
22
 
9
- class_attribute :input_helper_name, instance_writer: false
10
- attr_accessor :grid_class, :options, :block, :name
23
+ def parse(value)
24
+ raise NotImplementedError, "#parse(value) suppose to be overwritten"
25
+ end
11
26
 
12
- def initialize(grid_class, name, options = {}, &block)
13
- self.grid_class = grid_class
14
- self.name = name.to_sym
15
- self.options = options
16
- self.block = block || default_filter_block
17
- end
27
+ def default_input_options
28
+ { type: "text" }
29
+ end
18
30
 
19
- def parse(value)
20
- raise NotImplementedError, "#parse(value) suppose to be overwritten"
21
- end
31
+ def unapplicable_value?(value)
32
+ value.nil? ? !allow_nil? : value.blank? && !allow_blank?
33
+ end
22
34
 
23
- def unapplicable_value?(value)
24
- value.nil? ? !allow_nil? : value.blank? && !allow_blank?
25
- end
35
+ def apply(grid_object, scope, value)
36
+ return scope if unapplicable_value?(value)
26
37
 
27
- def apply(grid_object, scope, value)
28
- return scope if unapplicable_value?(value)
38
+ result = execute(value, scope, grid_object)
29
39
 
30
- result = execute(value, scope, grid_object)
40
+ return scope unless result
31
41
 
32
- return scope unless result
33
- if result == Datagrid::Filters::DEFAULT_FILTER_BLOCK
34
- result = default_filter(value, scope, grid_object)
35
- end
36
- unless grid_object.driver.match?(result)
37
- raise Datagrid::FilteringError, "Can not apply #{name.inspect} filter: result #{result.inspect} no longer match #{grid_object.driver.class}."
38
- end
42
+ result = default_filter(value, scope) if result == Datagrid::Filters::DEFAULT_FILTER_BLOCK
43
+ unless grid_object.driver.match?(result)
44
+ raise(
45
+ Datagrid::FilteringError,
46
+ "Filter #{name.inspect} unapplicable: result no longer match #{grid_object.driver.class}.",
47
+ )
48
+ end
39
49
 
40
- result
41
- end
50
+ result
51
+ end
42
52
 
43
- def parse_values(value)
44
- if multiple?
45
- return nil if value.nil?
46
- normalize_multiple_value(value).map do |v|
47
- parse(v)
53
+ def parse_values(value)
54
+ if multiple?
55
+ return nil if value.nil?
56
+
57
+ return normalize_multiple_value(value).map do |v|
58
+ parse(v)
59
+ end
60
+ end
61
+
62
+ case value
63
+ when Array
64
+ raise Datagrid::ArgumentError,
65
+ "#{grid_class}##{name} filter can not accept Array argument. Use :multiple option."
66
+ when Range
67
+ raise Datagrid::ArgumentError,
68
+ "#{grid_class}##{name} filter can not accept Range argument. Use :range option."
69
+ else
70
+ parse(value)
71
+ end
48
72
  end
49
- elsif value.is_a?(Array)
50
- raise Datagrid::ArgumentError, "#{grid_class}##{name} filter can not accept Array argument. Use :multiple option."
51
- else
52
- parse(value)
53
- end
54
- end
55
73
 
56
- def separator
57
- options[:multiple].is_a?(String) ? options[:multiple] : default_separator
58
- end
74
+ def separator
75
+ options[:multiple].is_a?(String) ? options[:multiple] : default_separator
76
+ end
59
77
 
60
- def header
61
- if header = options[:header]
62
- Datagrid::Utils.callable(header)
63
- else
64
- Datagrid::Utils.translate_from_namespace(:filters, grid_class, name)
65
- end
66
- end
78
+ def header
79
+ if (header = options[:header])
80
+ Datagrid::Utils.callable(header)
81
+ else
82
+ Datagrid::Utils.translate_from_namespace(:filters, grid_class, name)
83
+ end
84
+ end
67
85
 
68
- def default(object)
69
- default = self.options[:default]
70
- if default.is_a?(Symbol)
71
- object.send(default)
72
- elsif default.respond_to?(:call)
73
- Datagrid::Utils.apply_args(object, &default)
74
- else
75
- default
76
- end
77
- end
86
+ def default(object)
87
+ default = options[:default]
88
+ if default.is_a?(Symbol)
89
+ object.send(default)
90
+ elsif default.respond_to?(:call)
91
+ Datagrid::Utils.apply_args(object, &default)
92
+ else
93
+ default
94
+ end
95
+ end
78
96
 
79
- def multiple?
80
- self.options[:multiple]
81
- end
97
+ def multiple?
98
+ options[:multiple]
99
+ end
82
100
 
83
- def allow_nil?
84
- options.has_key?(:allow_nil) ? options[:allow_nil] : options[:allow_blank]
85
- end
101
+ def range?
102
+ false
103
+ end
86
104
 
87
- def allow_blank?
88
- options[:allow_blank]
89
- end
105
+ def allow_nil?
106
+ options.key?(:allow_nil) ? options[:allow_nil] : options[:allow_blank]
107
+ end
90
108
 
91
- def input_options
92
- options[:input_options] || {}
93
- end
109
+ def allow_blank?
110
+ options[:allow_blank]
111
+ end
94
112
 
95
- def label_options
96
- options[:label_options] || {}
97
- end
113
+ def input_options
114
+ options[:input_options] || {}
115
+ end
98
116
 
99
- def form_builder_helper_name
100
- self.class.form_builder_helper_name
101
- end
117
+ def label_options
118
+ options[:label_options] || {}
119
+ end
102
120
 
103
- def self.form_builder_helper_name
104
- :"datagrid_#{self.to_s.demodulize.underscore}"
105
- end
121
+ def form_builder_helper_name
122
+ self.class.form_builder_helper_name
123
+ end
106
124
 
107
- def default_filter_block
108
- filter = self
109
- lambda do |value, scope, grid|
110
- filter.default_filter(value, scope, grid)
111
- end
112
- end
125
+ def self.form_builder_helper_name
126
+ :"datagrid_#{to_s.demodulize.underscore}"
127
+ end
113
128
 
114
- def supports_range?
115
- self.class.ancestors.include?(::Datagrid::Filters::RangedFilter)
116
- end
129
+ def supports_range?
130
+ self.class.ancestors.include?(::Datagrid::Filters::RangedFilter)
131
+ end
117
132
 
118
- def format(value)
119
- value.nil? ? nil : value.to_s
120
- end
133
+ def format(value)
134
+ value&.to_s
135
+ end
121
136
 
122
- def dummy?
123
- options[:dummy]
124
- end
137
+ def dummy?
138
+ options[:dummy]
139
+ end
125
140
 
126
- def type
127
- Datagrid::Filters::FILTER_TYPES.each do |type, klass|
128
- if is_a?(klass)
129
- return type
141
+ def type
142
+ Datagrid::Filters::FILTER_TYPES.each do |type, klass|
143
+ return type if is_a?(klass)
144
+ end
145
+ raise "wtf is #{inspect}"
130
146
  end
131
- end
132
- raise "wtf is #{inspect}"
133
- end
134
147
 
135
- def enabled?(grid)
136
- ::Datagrid::Utils.process_availability(grid, options[:if], options[:unless])
137
- end
148
+ def enabled?(grid)
149
+ ::Datagrid::Utils.process_availability(grid, options[:if], options[:unless])
150
+ end
138
151
 
139
- protected
152
+ def enum_checkboxes?
153
+ false
154
+ end
140
155
 
141
- def default_filter_where(scope, value)
142
- driver.where(scope, name, value)
143
- end
156
+ def default_scope?
157
+ !block
158
+ end
144
159
 
145
- def execute(value, scope, grid_object)
146
- if block.arity == 1
147
- scope.instance_exec(value, &block)
148
- else
149
- Datagrid::Utils.apply_args(value, scope, grid_object, &block)
150
- end
151
- end
160
+ protected
152
161
 
153
- def normalize_multiple_value(value)
154
- case value
155
- when String
156
- value.split(separator)
157
- when Range
158
- [value.begin, value.end]
159
- when Array
160
- value
161
- else
162
- Array.wrap(value)
163
- end
164
- end
162
+ def default_filter_where(scope, value)
163
+ driver.where(scope, name, value)
164
+ end
165
165
 
166
- def default_separator
167
- ','
168
- end
166
+ def execute(value, scope, grid_object)
167
+ if block&.arity == 1
168
+ scope.instance_exec(value, &block)
169
+ elsif block
170
+ Datagrid::Utils.apply_args(value, scope, grid_object, &block)
171
+ else
172
+ default_filter(value, scope)
173
+ end
174
+ end
169
175
 
170
- def driver
171
- grid_class.driver
172
- end
176
+ def normalize_multiple_value(value)
177
+ case value
178
+ when String
179
+ value.split(separator)
180
+ when Range
181
+ [value.begin, value.end]
182
+ when Array
183
+ value
184
+ else
185
+ Array.wrap(value)
186
+ end
187
+ end
173
188
 
174
- def default_filter(value, scope, grid)
175
- return nil if dummy?
176
- if !driver.has_column?(scope, name) && scope.respond_to?(name, true)
177
- scope.public_send(name, value)
178
- else
179
- default_filter_where(scope, value)
189
+ def default_separator
190
+ ","
191
+ end
192
+
193
+ def driver
194
+ grid_class.driver
195
+ end
196
+
197
+ def default_filter(value, scope)
198
+ return nil if dummy?
199
+
200
+ if !driver.scope_has_column?(scope, name) && scope.respond_to?(name, true)
201
+ scope.public_send(name, value)
202
+ else
203
+ default_filter_where(scope, value)
204
+ end
205
+ end
180
206
  end
181
207
  end
182
-
183
208
  end
184
-
@@ -1,9 +1,23 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "datagrid/utils"
2
- # @!visibility private
3
- class Datagrid::Filters::BooleanFilter < Datagrid::Filters::BaseFilter
4
4
 
5
- def parse(value)
6
- Datagrid::Utils.booleanize(value)
7
- end
5
+ module Datagrid
6
+ module Filters
7
+ class BooleanFilter < Datagrid::Filters::BaseFilter
8
+ # @!visibility private
9
+ def initialize(grid, name, **opts)
10
+ super
11
+ options[:default] ||= false
12
+ end
8
13
 
14
+ def default_input_options
15
+ { **super, type: "checkbox" }
16
+ end
17
+
18
+ def parse(value)
19
+ Datagrid::Utils.booleanize(value)
20
+ end
21
+ end
22
+ end
9
23
  end
@@ -1,40 +1,38 @@
1
- require "datagrid/filters/ranged_filter"
2
-
3
- class Datagrid::Filters::DateFilter < Datagrid::Filters::BaseFilter
4
-
5
- include Datagrid::Filters::RangedFilter
6
-
7
- def apply(grid_object, scope, value)
8
- if value.is_a?(Range)
9
- value = value.begin&.beginning_of_day..value.end&.end_of_day
10
- end
11
- super(grid_object, scope, value)
12
- end
13
-
14
- def parse(value)
15
- Datagrid::Utils.parse_date(value)
16
- end
1
+ # frozen_string_literal: true
17
2
 
3
+ require "datagrid/filters/ranged_filter"
18
4
 
19
- def format(value)
20
- if formats.any? && value
21
- value.strftime(formats.first)
22
- else
23
- super
24
- end
25
- end
26
-
27
- def default_filter_where(scope, value)
28
- if driver.is_timestamp?(scope, name)
29
- value = Datagrid::Utils.format_date_as_timestamp(value)
5
+ module Datagrid
6
+ module Filters
7
+ class DateFilter < Datagrid::Filters::BaseFilter
8
+ include Datagrid::Filters::RangedFilter
9
+
10
+ def default_input_options
11
+ { **super, type: "date" }
12
+ end
13
+
14
+ def apply(grid_object, scope, value)
15
+ value = Datagrid::Utils.format_date_as_timestamp(value) if grid_object.driver.timestamp_column?(scope, name)
16
+ super
17
+ end
18
+
19
+ def parse(value)
20
+ Datagrid::Utils.parse_date(value)
21
+ end
22
+
23
+ def format(value)
24
+ if formats.any? && value
25
+ value.strftime(formats.first)
26
+ else
27
+ super
28
+ end
29
+ end
30
+
31
+ protected
32
+
33
+ def formats
34
+ Array(Datagrid.configuration.date_formats)
35
+ end
30
36
  end
31
- super(scope, value)
32
- end
33
-
34
- protected
35
-
36
- def formats
37
- Array(Datagrid.configuration.date_formats)
38
37
  end
39
38
  end
40
-