datagrid 1.8.2 → 2.0.0.pre.alpha

Sign up to get free protection for your applications and to get access to all the features.
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
-