datagrid 1.8.1 → 2.0.0.pre.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -7
- data/{Readme.markdown → README.md} +46 -29
- 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 -5
- 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 +8 -8
- data/lib/datagrid/active_model.rb +9 -17
- data/lib/datagrid/base.rb +39 -0
- data/lib/datagrid/column_names_attribute.rb +12 -12
- data/lib/datagrid/columns/column.rb +155 -133
- data/lib/datagrid/columns.rb +495 -282
- data/lib/datagrid/configuration.rb +23 -10
- data/lib/datagrid/core.rb +184 -150
- data/lib/datagrid/deprecated_object.rb +20 -0
- data/lib/datagrid/drivers/abstract_driver.rb +13 -25
- data/lib/datagrid/drivers/active_record.rb +24 -26
- data/lib/datagrid/drivers/array.rb +26 -17
- data/lib/datagrid/drivers/mongo_mapper.rb +15 -14
- data/lib/datagrid/drivers/mongoid.rb +16 -18
- 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 -27
- 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 +234 -106
- 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 +81 -87
- data/lib/datagrid/rspec.rb +8 -12
- data/lib/datagrid/utils.rb +42 -38
- data/lib/datagrid/version.rb +3 -1
- data/lib/datagrid.rb +18 -28
- data/templates/base.rb.erb +33 -7
- data/templates/grid.rb.erb +1 -1
- metadata +18 -19
- 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/ordering.rb
CHANGED
@@ -1,132 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "datagrid/columns"
|
2
4
|
|
3
5
|
module Datagrid
|
4
6
|
# Raised when grid order value is incorrect
|
5
7
|
class OrderUnsupported < StandardError
|
6
8
|
end
|
7
|
-
module Ordering
|
8
9
|
|
10
|
+
# Module adds support for ordering by defined columns for Datagrid.
|
11
|
+
module Ordering
|
9
12
|
# @!visibility private
|
10
13
|
def self.included(base)
|
11
|
-
base.extend
|
14
|
+
base.extend ClassMethods
|
12
15
|
base.class_eval do
|
13
16
|
include Datagrid::Columns
|
14
17
|
|
15
18
|
datagrid_attribute :order do |value|
|
16
|
-
if value.present?
|
17
|
-
value.to_sym
|
18
|
-
else
|
19
|
-
nil
|
20
|
-
end
|
21
|
-
|
19
|
+
value.to_sym if value.present?
|
22
20
|
end
|
23
21
|
|
24
22
|
datagrid_attribute :descending do |value|
|
25
23
|
Datagrid::Utils.booleanize(value)
|
26
24
|
end
|
27
|
-
|
28
|
-
|
25
|
+
alias_method :descending?, :descending
|
29
26
|
end
|
30
|
-
base.include InstanceMethods
|
31
27
|
end
|
32
28
|
|
33
29
|
# @!visibility private
|
34
30
|
module ClassMethods
|
35
31
|
def order_unsupported(name, reason)
|
36
|
-
raise Datagrid::OrderUnsupported, "Can not sort #{
|
32
|
+
raise Datagrid::OrderUnsupported, "Can not sort #{inspect} by ##{name}: #{reason}"
|
37
33
|
end
|
38
34
|
end
|
39
35
|
|
40
|
-
|
36
|
+
# @!visibility private
|
37
|
+
def assets
|
38
|
+
check_order_valid!
|
39
|
+
apply_order(super)
|
40
|
+
end
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
42
|
+
# @return [Datagrid::Columns::Column, nil] a column definition that is currently used to order assets
|
43
|
+
# @example
|
44
|
+
# class MyGrid
|
45
|
+
# scope { Model }
|
46
|
+
# column(:id)
|
47
|
+
# column(:name)
|
48
|
+
# end
|
49
|
+
# MyGrid.new(order: "name").order_column # => #<Column name: "name", ...>
|
50
|
+
def order_column
|
51
|
+
order ? column_by_name(order) : nil
|
52
|
+
end
|
47
53
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
# MyGrid.new(order: "name").order_column # => #<Column name: "name", ...>
|
56
|
-
def order_column
|
57
|
-
order ? column_by_name(order) : nil
|
58
|
-
end
|
54
|
+
# @param column [String, Datagrid::Columns::Column]
|
55
|
+
# @param desc [nil, Boolean] confirm order direction as well if specified
|
56
|
+
# @return [Boolean] true if given grid is ordered by given column.
|
57
|
+
def ordered_by?(column, desc = nil)
|
58
|
+
order_column == column_by_name(column) &&
|
59
|
+
(desc.nil? || (desc ? descending? : !descending?))
|
60
|
+
end
|
59
61
|
|
60
|
-
|
61
|
-
# @return [Boolean] true if given grid is ordered by given column.
|
62
|
-
def ordered_by?(column)
|
63
|
-
order_column == column_by_name(column)
|
64
|
-
end
|
62
|
+
private
|
65
63
|
|
66
|
-
|
64
|
+
def apply_order(assets)
|
65
|
+
return assets unless order
|
67
66
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
67
|
+
if order_column.order_by_value?
|
68
|
+
assets = assets.sort_by do |asset|
|
69
|
+
order_column.order_by_value(asset, self)
|
70
|
+
end
|
71
|
+
descending? ? assets.reverse : assets
|
72
|
+
elsif descending?
|
73
|
+
if order_column.order_desc
|
74
|
+
apply_asc_order(assets, order_column.order_desc)
|
75
75
|
else
|
76
|
-
|
77
|
-
if order_column.order_desc
|
78
|
-
apply_asc_order(assets, order_column.order_desc)
|
79
|
-
else
|
80
|
-
apply_desc_order(assets, order_column.order)
|
81
|
-
end
|
82
|
-
else
|
83
|
-
apply_asc_order(assets, order_column.order)
|
84
|
-
end
|
76
|
+
apply_desc_order(assets, order_column.order)
|
85
77
|
end
|
78
|
+
else
|
79
|
+
apply_asc_order(assets, order_column.order)
|
86
80
|
end
|
81
|
+
end
|
87
82
|
|
88
|
-
|
89
|
-
|
90
|
-
column = column_by_name(order)
|
91
|
-
unless column
|
92
|
-
self.class.order_unsupported(order, "no column #{order} in #{self.class}")
|
93
|
-
end
|
94
|
-
unless column.supports_order?
|
95
|
-
self.class.order_unsupported(column.name, "column don't support order" )
|
96
|
-
end
|
97
|
-
end
|
83
|
+
def check_order_valid!
|
84
|
+
return unless order
|
98
85
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
else
|
103
|
-
driver.asc(assets, order)
|
104
|
-
end
|
105
|
-
end
|
86
|
+
column = column_by_name(order)
|
87
|
+
self.class.order_unsupported(order, "no column #{order} in #{self.class}") unless column
|
88
|
+
return if column.supports_order?
|
106
89
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
90
|
+
self.class.order_unsupported(column.name, "column don't support order")
|
91
|
+
end
|
92
|
+
|
93
|
+
def apply_asc_order(assets, order)
|
94
|
+
if order.respond_to?(:call)
|
95
|
+
apply_block_order(assets, order)
|
96
|
+
else
|
97
|
+
driver.asc(assets, order)
|
113
98
|
end
|
99
|
+
end
|
114
100
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
101
|
+
def apply_desc_order(assets, order)
|
102
|
+
if order.respond_to?(:call)
|
103
|
+
reverse_order(apply_asc_order(assets, order))
|
104
|
+
else
|
105
|
+
driver.desc(assets, order)
|
119
106
|
end
|
107
|
+
end
|
120
108
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
109
|
+
def reverse_order(assets)
|
110
|
+
driver.reverse_order(assets)
|
111
|
+
rescue NotImplementedError
|
112
|
+
self.class.order_unsupported(order_column.name,
|
113
|
+
"Your ORM do not support reverse order: please specify :order_desc option manually",)
|
114
|
+
end
|
115
|
+
|
116
|
+
def apply_block_order(assets, order)
|
117
|
+
case order.arity
|
118
|
+
when -1, 0
|
119
|
+
assets.instance_eval(&order)
|
120
|
+
when 1
|
121
|
+
order.call(assets)
|
122
|
+
else
|
123
|
+
self.class.order_unsupported(order_column.name, "Order option proc can not handle more than one argument")
|
130
124
|
end
|
131
125
|
end
|
132
126
|
end
|
data/lib/datagrid/rspec.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "datagrid"
|
2
4
|
|
3
|
-
#TODO: refactor this experimental shit
|
5
|
+
# TODO: refactor this experimental shit
|
4
6
|
shared_examples_for "Datagrid" do
|
5
7
|
describe "as Datagrid" do
|
6
|
-
|
7
8
|
it "should have at least one entry if assets" do
|
8
9
|
subject.assets.should_not be_empty
|
9
10
|
end
|
10
11
|
|
11
|
-
described_class.columns(:
|
12
|
+
described_class.columns(data: true).each do |column|
|
12
13
|
describe "column ##{column.name}" do
|
13
|
-
|
14
14
|
it "should has value in #data_hash" do
|
15
15
|
subject.data_hash.first.should have_key(column.name)
|
16
16
|
end
|
@@ -25,14 +25,11 @@ shared_examples_for "Datagrid" do
|
|
25
25
|
subject.assets.first.should_not be_nil
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
29
28
|
end
|
30
29
|
|
31
30
|
described_class.filters.each do |filter|
|
32
31
|
describe "filter ##{filter.name}" do
|
33
|
-
|
34
32
|
let(:filter_value) do
|
35
|
-
|
36
33
|
case Datagrid::Filters::FILTER_TYPES.invert[filter.class]
|
37
34
|
when :default, :string
|
38
35
|
"text"
|
@@ -46,23 +43,22 @@ shared_examples_for "Datagrid" do
|
|
46
43
|
1
|
47
44
|
when :enum
|
48
45
|
select = subject.select_options(filter)
|
49
|
-
select.first
|
46
|
+
select.first&.last
|
50
47
|
else
|
51
48
|
raise "unknown filter type: #{filter.class}"
|
52
49
|
end.to_s
|
53
50
|
end
|
54
51
|
|
55
52
|
before(:each) do
|
56
|
-
subject.attributes = {filter.name => filter_value}
|
57
|
-
subject.
|
53
|
+
subject.attributes = { filter.name => filter_value }
|
54
|
+
subject.public_send(filter.name).should_not be_nil
|
58
55
|
end
|
59
56
|
|
60
57
|
it "should be supported" do
|
61
58
|
subject.assets.should_not be_nil
|
62
|
-
#TODO: better matcher.
|
59
|
+
# TODO: better matcher.
|
63
60
|
end
|
64
61
|
end
|
65
62
|
end
|
66
|
-
|
67
63
|
end
|
68
64
|
end
|
data/lib/datagrid/utils.rb
CHANGED
@@ -1,52 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Datagrid
|
2
4
|
# @!visibility private
|
3
|
-
module Utils
|
5
|
+
module Utils
|
4
6
|
class << self
|
5
|
-
|
6
|
-
|
7
|
-
TRUTH = [true, 1, "1", "true", "yes", "on"]
|
7
|
+
TRUTH = [true, 1, "1", "true", "yes", "on"].freeze
|
8
8
|
|
9
9
|
def booleanize(value)
|
10
|
-
if value.respond_to?(:downcase)
|
11
|
-
value = value.downcase
|
12
|
-
end
|
10
|
+
value = value.downcase if value.respond_to?(:downcase)
|
13
11
|
TRUTH.include?(value)
|
14
12
|
end
|
15
13
|
|
16
14
|
def translate_from_namespace(namespace, grid_class, key)
|
17
|
-
|
18
15
|
lookups = []
|
19
16
|
namespaced_key = "#{namespace}.#{key}"
|
20
17
|
|
21
18
|
grid_class.ancestors.each do |ancestor|
|
22
|
-
if ancestor.respond_to?(:model_name)
|
23
|
-
lookups << :"datagrid.#{ancestor.model_name.i18n_key}.#{namespaced_key}"
|
24
|
-
end
|
19
|
+
lookups << :"datagrid.#{ancestor.model_name.i18n_key}.#{namespaced_key}" if ancestor.respond_to?(:model_name)
|
25
20
|
end
|
26
21
|
lookups << :"datagrid.defaults.#{namespaced_key}"
|
27
22
|
lookups << key.to_s.humanize
|
28
23
|
I18n.t(lookups.shift, default: lookups).presence
|
29
24
|
end
|
30
25
|
|
26
|
+
def deprecator
|
27
|
+
if defined?(Rails) && Rails.version >= "7.1.0"
|
28
|
+
Rails.deprecator
|
29
|
+
else
|
30
|
+
ActiveSupport::Deprecation
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
31
34
|
def warn_once(message, delay = 5)
|
32
35
|
@warnings ||= {}
|
33
36
|
timestamp = @warnings[message]
|
34
37
|
return false if timestamp && timestamp >= Time.now - delay
|
35
|
-
|
38
|
+
|
39
|
+
deprecator.warn(message)
|
36
40
|
@warnings[message] = Time.now
|
37
41
|
true
|
38
42
|
end
|
39
43
|
|
40
44
|
def add_html_classes(options, *classes)
|
45
|
+
return options if classes.empty?
|
46
|
+
|
41
47
|
options = options.clone
|
42
|
-
options[:class] ||=
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
# suppose that it is a String
|
47
|
-
options[:class] += " " unless options[:class].blank?
|
48
|
-
options[:class] += classes.join(" ")
|
49
|
-
end
|
48
|
+
options[:class] ||= []
|
49
|
+
array = options[:class].is_a?(Array)
|
50
|
+
value = [*options[:class], *classes]
|
51
|
+
options[:class] = array ? value : value.join(" ")
|
50
52
|
options
|
51
53
|
end
|
52
54
|
|
@@ -55,41 +57,42 @@ module Datagrid
|
|
55
57
|
end
|
56
58
|
|
57
59
|
def extract_position_from_options(array, options)
|
58
|
-
before
|
59
|
-
|
60
|
-
|
61
|
-
end
|
60
|
+
before = options[:before]
|
61
|
+
after = options[:after]
|
62
|
+
raise Datagrid::ConfigurationError, "Options :before and :after can not be used together" if before && after
|
62
63
|
# Consider as before all
|
63
64
|
return 0 if before == true
|
65
|
+
|
64
66
|
if before
|
65
67
|
before = before.to_sym
|
66
|
-
array.index {|c| c.name.to_sym == before }
|
68
|
+
array.index { |c| c.name.to_sym == before }
|
67
69
|
elsif after
|
68
70
|
after = after.to_sym
|
69
|
-
array.index {|c| c.name.to_sym == after } + 1
|
71
|
+
array.index { |c| c.name.to_sym == after } + 1
|
70
72
|
else
|
71
73
|
-1
|
72
74
|
end
|
73
75
|
end
|
74
76
|
|
75
77
|
def apply_args(*args, &block)
|
76
|
-
size = block.arity
|
78
|
+
size = block.arity.negative? ? args.size : block.arity
|
77
79
|
block.call(*args.slice(0, size))
|
78
80
|
end
|
79
81
|
|
80
82
|
def parse_date(value)
|
81
83
|
return nil if value.blank?
|
82
84
|
return value if value.is_a?(Range)
|
85
|
+
|
83
86
|
if value.is_a?(String)
|
84
87
|
Array(Datagrid.configuration.date_formats).each do |format|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
end
|
88
|
+
return Date.strptime(value, format)
|
89
|
+
rescue ::ArgumentError
|
90
|
+
nil
|
89
91
|
end
|
90
92
|
end
|
91
93
|
return Date.parse(value) if value.is_a?(String)
|
92
94
|
return value.to_date if value.respond_to?(:to_date)
|
95
|
+
|
93
96
|
value
|
94
97
|
rescue ::ArgumentError
|
95
98
|
nil
|
@@ -98,16 +101,18 @@ module Datagrid
|
|
98
101
|
def parse_datetime(value)
|
99
102
|
return nil if value.blank?
|
100
103
|
return value if value.is_a?(Range)
|
104
|
+
return value if defined?(ActiveSupport::TimeWithZone) && value.is_a?(ActiveSupport::TimeWithZone)
|
105
|
+
|
101
106
|
if value.is_a?(String)
|
102
107
|
Array(Datagrid.configuration.datetime_formats).each do |format|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
108
|
+
return Time.strptime(value, format)
|
109
|
+
rescue ::ArgumentError
|
110
|
+
nil
|
107
111
|
end
|
108
112
|
end
|
109
113
|
return Time.parse(value) if value.is_a?(String)
|
110
114
|
return value.to_time if value.respond_to?(:to_time)
|
115
|
+
|
111
116
|
value
|
112
117
|
rescue ::ArgumentError
|
113
118
|
nil
|
@@ -116,10 +121,8 @@ module Datagrid
|
|
116
121
|
def format_date_as_timestamp(value)
|
117
122
|
if !value
|
118
123
|
value
|
119
|
-
elsif value.is_a?(Array)
|
120
|
-
[value.first.try(:beginning_of_day), value.last.try(:end_of_day)]
|
121
124
|
elsif value.is_a?(Range)
|
122
|
-
|
125
|
+
value.begin&.beginning_of_day..value.end&.end_of_day
|
123
126
|
else
|
124
127
|
value.beginning_of_day..value.end_of_day
|
125
128
|
end
|
@@ -135,6 +138,7 @@ module Datagrid
|
|
135
138
|
end
|
136
139
|
|
137
140
|
protected
|
141
|
+
|
138
142
|
def property_availability(grid, option, default)
|
139
143
|
case option
|
140
144
|
when nil
|
data/lib/datagrid/version.rb
CHANGED
data/lib/datagrid.rb
CHANGED
@@ -1,49 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "action_view"
|
2
4
|
require "datagrid/configuration"
|
5
|
+
require "datagrid/engine"
|
3
6
|
|
7
|
+
# @main README.md
|
4
8
|
module Datagrid
|
5
|
-
|
6
|
-
extend ActiveSupport::Autoload
|
7
|
-
|
8
|
-
autoload :Core
|
9
|
-
autoload :ActiveModel
|
10
|
-
autoload :Filters
|
11
|
-
autoload :Columns
|
12
|
-
autoload :ColumnNamesAttribute
|
13
|
-
autoload :Ordering
|
14
|
-
autoload :Configuration
|
15
|
-
|
16
|
-
autoload :Helper
|
17
|
-
ActionView::Base.send(:include, Datagrid::Helper)
|
18
|
-
|
19
|
-
autoload :FormBuilder
|
20
|
-
ActionView::Helpers::FormBuilder.send(:include, Datagrid::FormBuilder)
|
21
|
-
|
22
|
-
autoload :Renderer
|
23
|
-
|
24
|
-
autoload :Engine
|
25
|
-
|
26
9
|
# @!visibility private
|
27
10
|
def self.included(base)
|
11
|
+
Utils.warn_once("Including Datagrid is deprecated. Inherit Datagrid::Base instead.")
|
28
12
|
base.class_eval do
|
29
|
-
|
30
13
|
include ::Datagrid::Core
|
31
14
|
include ::Datagrid::ActiveModel
|
32
15
|
include ::Datagrid::Filters
|
33
16
|
include ::Datagrid::Columns
|
34
17
|
include ::Datagrid::ColumnNamesAttribute
|
35
18
|
include ::Datagrid::Ordering
|
36
|
-
|
37
19
|
end
|
38
20
|
end
|
39
21
|
|
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
|
+
|
40
31
|
class ConfigurationError < StandardError; end
|
41
32
|
class ArgumentError < ::ArgumentError; end
|
42
33
|
class ColumnUnavailableError < StandardError; end
|
43
|
-
|
44
34
|
end
|
45
35
|
|
46
|
-
require "datagrid/
|
47
|
-
|
48
|
-
|
49
|
-
|
36
|
+
require "datagrid/base"
|
37
|
+
require "datagrid/generators/scaffold"
|
38
|
+
require "datagrid/generators/views"
|
39
|
+
I18n.load_path << File.expand_path("datagrid/locale/en.yml", __dir__)
|
data/templates/base.rb.erb
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
class
|
2
|
-
|
3
|
-
include Datagrid
|
4
|
-
|
1
|
+
class ApplicationGrid < Datagrid::Base
|
5
2
|
self.default_column_options = {
|
6
3
|
# Uncomment to disable the default order
|
7
4
|
# order: false,
|
@@ -11,11 +8,40 @@ class BaseGrid
|
|
11
8
|
# Enable forbidden attributes protection
|
12
9
|
# self.forbidden_attributes_protection = true
|
13
10
|
|
14
|
-
|
11
|
+
# Makes a date column
|
12
|
+
# @param name [Symbol] Column name
|
13
|
+
# @param args [Array] Other column helper arguments
|
14
|
+
# @example
|
15
|
+
# date_column(:created_at)
|
16
|
+
# date_column(:owner_registered_at) do |model|
|
17
|
+
# model.owner.registered_at
|
18
|
+
# end
|
19
|
+
def self.date_column(name, *args, &block)
|
15
20
|
column(name, *args) do |model|
|
16
|
-
format(
|
17
|
-
date
|
21
|
+
format(block ? block.call(model) : model.public_send(name)) do |date|
|
22
|
+
date&.strftime("%m/%d/%Y") || "—".html_safe
|
18
23
|
end
|
19
24
|
end
|
20
25
|
end
|
26
|
+
|
27
|
+
# Makes a boolean YES/NO column
|
28
|
+
# @param name [Symbol] Column name
|
29
|
+
# @param args [Array] Other column helper arguments
|
30
|
+
# @example
|
31
|
+
# boolean_column(:approved)
|
32
|
+
# boolean_column(:has_tasks, preload: :tasks) do |model|
|
33
|
+
# model.tasks.unfinished.any?
|
34
|
+
# end
|
35
|
+
def self.boolean_column(name, *args, &block)
|
36
|
+
column(name, *args) do |model|
|
37
|
+
value = block ? block.call(model) : model.public_send(name)
|
38
|
+
value ? "Yes" : "No"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Uncomment to shorten URL query string for all grids.
|
43
|
+
# May cause collisions if multiple grids are used on the same page.
|
44
|
+
# def param_name
|
45
|
+
# 'grid'
|
46
|
+
# end
|
21
47
|
end
|
data/templates/grid.rb.erb
CHANGED