datagrid 1.7.0 → 1.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/Readme.markdown +9 -9
- data/app/views/datagrid/_enum_checkboxes.html.erb +2 -2
- data/app/views/datagrid/_form.html.erb +2 -3
- data/app/views/datagrid/_order_for.html.erb +2 -2
- data/app/views/datagrid/_range_filter.html.erb +3 -3
- data/lib/datagrid/column_names_attribute.rb +2 -2
- data/lib/datagrid/columns/column.rb +7 -7
- data/lib/datagrid/columns.rb +3 -5
- data/lib/datagrid/core.rb +20 -8
- data/lib/datagrid/drivers/active_record.rb +2 -2
- data/lib/datagrid/drivers/sequel.rb +6 -2
- data/lib/datagrid/filters/base_filter.rb +3 -2
- data/lib/datagrid/filters/composite_filters.rb +3 -1
- data/lib/datagrid/filters/dynamic_filter.rb +1 -1
- data/lib/datagrid/filters.rb +14 -15
- data/lib/datagrid/form_builder.rb +41 -34
- data/lib/datagrid/helper.rb +7 -51
- data/lib/datagrid/locale/en.yml +5 -1
- data/lib/datagrid/ordering.rb +1 -1
- data/lib/datagrid/renderer.rb +69 -14
- data/lib/datagrid/rspec.rb +4 -4
- data/lib/datagrid/version.rb +1 -1
- data/templates/grid.rb.erb +1 -1
- data/templates/index.html.erb +1 -1
- metadata +3 -4
- data/lib/datagrid/filters/boolean_enum_filter.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 701bbc42a7501aa45a10d3899b92c9d1f745dae75b0a7eb219db1c339c182cb8
|
4
|
+
data.tar.gz: cb309f1b9f08b3c1455c1b8650cf222867ba68721a9eb344b310bc5d7d5712e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bac4684420163514873a8a31bd06d182d216c8fff27f61d57368d605165838021a33d8603596ee04aee02e2b97a130308553bf36a8b6db0717f363b4c5ad472
|
7
|
+
data.tar.gz: 4f6190ffaadbf77d0bc39ca632de5df1bcd2ef716bff40a5074b48f710d8b2257e0a95759fe8465a756819deb5e9202abb92a64783eae2bd3804d6c5ddf02e8a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## master
|
2
|
+
|
3
|
+
## 1.8.1
|
4
|
+
|
5
|
+
* Prioritize `input_options` over generated by default. [#319](https://github.com/bogdan/datagrid/pull/319)
|
6
|
+
|
7
|
+
## 1.8.0
|
8
|
+
|
9
|
+
* Support `input_options: {type: "textarea"}` as `<textarea/>` tag
|
10
|
+
* Remove deprecated `eboolean` filter
|
11
|
+
* Fixed scope wrapping to be universal
|
12
|
+
* Deprecated `integer_range_filters` and `date_range_filters`. Use `filter(name, type, range: true)` instead.
|
13
|
+
* Add `original_scope` method that returns scope as it was defined without any wrapping [#313](https://github.com/bogdan/datagrid/pull/313)
|
14
|
+
* Add ability to specify `columns` option for `datagrid_row`. [#314](https://github.com/bogdan/datagrid/pull/314)
|
15
|
+
|
1
16
|
## 1.7.0
|
2
17
|
|
3
18
|
* Depend on `railties` instead of `rails` to prevent loading of unnecessary frameworks
|
data/Readme.markdown
CHANGED
@@ -4,9 +4,9 @@
|
|
4
4
|
|
5
5
|
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fbogdan%2Fdatagrid.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fbogdan%2Fdatagrid?ref=badge_shield)
|
6
6
|
|
7
|
-
|
7
|
+
A really mighty and flexible ruby library that generates reports including admin panels, analytics and data representation:
|
8
8
|
|
9
|
-
*
|
9
|
+
* Filtering
|
10
10
|
* Columns
|
11
11
|
* Sort order
|
12
12
|
* Localization
|
@@ -54,7 +54,7 @@ class UsersGrid
|
|
54
54
|
filter(:group_id, :integer, multiple: true)
|
55
55
|
filter(:logins_count, :integer, range: true)
|
56
56
|
filter(:group_name, :string, header: "Group") do |value|
|
57
|
-
self.joins(:group).where(:
|
57
|
+
self.joins(:group).where(groups: {name: value})
|
58
58
|
end
|
59
59
|
|
60
60
|
column(:name)
|
@@ -72,11 +72,11 @@ Basic grid api:
|
|
72
72
|
|
73
73
|
``` ruby
|
74
74
|
report = UsersGrid.new(
|
75
|
-
:
|
76
|
-
:
|
77
|
-
:
|
78
|
-
:
|
79
|
-
:
|
75
|
+
group_id: [1,2],
|
76
|
+
logins_count: [1, nil],
|
77
|
+
category: "first",
|
78
|
+
order: :group,
|
79
|
+
descending: true
|
80
80
|
)
|
81
81
|
|
82
82
|
report.assets # => Array of User instances:
|
@@ -145,7 +145,7 @@ Datagrid supports different type of filters including:
|
|
145
145
|
Each column is represented by name and code block to calculate the value.
|
146
146
|
|
147
147
|
``` ruby
|
148
|
-
column(:activated, :
|
148
|
+
column(:activated, header: "Active", order: "activated", after: :name) do
|
149
149
|
self.activated?
|
150
150
|
end
|
151
151
|
```
|
@@ -4,8 +4,8 @@ You can add indent if whitespace doesn't matter for you
|
|
4
4
|
%>
|
5
5
|
<%- elements.each do |value, text, checked| -%>
|
6
6
|
<%- id = [form.object_name, filter.name, value].join('_').underscore -%>
|
7
|
-
<%= form.label filter.name, options.merge(:
|
8
|
-
<%= form.check_box(filter.name, {:
|
7
|
+
<%= form.label filter.name, options.merge(for: id) do -%>
|
8
|
+
<%= form.check_box(filter.name, {multiple: true, id: id, checked: checked, include_hidden: false}, value.to_s, nil) -%>
|
9
9
|
<%= text -%>
|
10
10
|
<%- end -%>
|
11
11
|
<%- end -%>
|
@@ -6,9 +6,8 @@
|
|
6
6
|
</div>
|
7
7
|
<% end %>
|
8
8
|
<div class="datagrid-actions">
|
9
|
-
<%= f.submit I18n.t("datagrid.form.search").html_safe, :
|
9
|
+
<%= f.submit I18n.t("datagrid.form.search").html_safe, class: "datagrid-submit" %>
|
10
10
|
<%# https://github.com/rails/rails/pull/14949 -%>
|
11
|
-
|
12
|
-
<%= link_to I18n.t('datagrid.form.reset').html_safe, url_for(grid.to_param => empty_parameter), :class => "datagrid-reset" %>
|
11
|
+
<%= link_to I18n.t('datagrid.form.reset').html_safe, url_for(grid.to_param => {}), class: "datagrid-reset" %>
|
13
12
|
</div>
|
14
13
|
<% end -%>
|
@@ -2,9 +2,9 @@
|
|
2
2
|
<%= link_to(
|
3
3
|
I18n.t("datagrid.table.order.asc").html_safe,
|
4
4
|
datagrid_order_path(grid, column, false),
|
5
|
-
:
|
5
|
+
class: "asc") %>
|
6
6
|
<%= link_to(
|
7
7
|
I18n.t("datagrid.table.order.desc").html_safe,
|
8
8
|
datagrid_order_path(grid, column, true),
|
9
|
-
:
|
9
|
+
class: "desc") %>
|
10
10
|
</div>
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<%= form.
|
2
|
-
<span class="separator <%= filter.type %>"
|
3
|
-
<%= form.
|
1
|
+
<%= form.datagrid_filter_input(filter, **from_options) %>
|
2
|
+
<span class="separator <%= filter.type %>"><%= I18n.t('datagrid.filters.range.separator') %></span>
|
3
|
+
<%= form.datagrid_filter_input(filter, **to_options) %>
|
@@ -17,7 +17,7 @@ module Datagrid
|
|
17
17
|
# Adds a filter that acts like a column selection
|
18
18
|
# All defined columns will be available to select/deselect
|
19
19
|
# as a multi-select enum filter.
|
20
|
-
# Columns with <tt
|
20
|
+
# Columns with <tt>mandatory: true</tt> option
|
21
21
|
# will always present in the grid table and won't be listed
|
22
22
|
# in column names selection
|
23
23
|
# Accepts same options as <tt>:enum</tt> filter
|
@@ -47,7 +47,7 @@ module Datagrid
|
|
47
47
|
available_columns.select {|c| c.mandatory? }
|
48
48
|
end
|
49
49
|
|
50
|
-
# Returns a list of enabled columns without <tt
|
50
|
+
# Returns a list of enabled columns without <tt>mandatory: true</tt> option
|
51
51
|
# If no mandatory columns specified than all of them considered mandatory but not optional
|
52
52
|
# @return [Array<Datagrid::Columns::Column>]
|
53
53
|
def optional_columns
|
@@ -133,24 +133,24 @@ class Datagrid::Columns::Column
|
|
133
133
|
grid.generic_value(self, model)
|
134
134
|
end
|
135
135
|
|
136
|
-
def append_preload(
|
137
|
-
return
|
136
|
+
def append_preload(relation)
|
137
|
+
return relation unless preload
|
138
138
|
if preload.respond_to?(:call)
|
139
|
-
return
|
139
|
+
return relation unless preload
|
140
140
|
if preload.arity == 1
|
141
|
-
preload.call(
|
141
|
+
preload.call(relation)
|
142
142
|
else
|
143
|
-
|
143
|
+
relation.instance_exec(&preload)
|
144
144
|
end
|
145
145
|
else
|
146
|
-
driver.default_preload(
|
146
|
+
driver.default_preload(relation, preload)
|
147
147
|
end
|
148
148
|
end
|
149
149
|
|
150
150
|
def preload
|
151
151
|
preload = options[:preload]
|
152
152
|
|
153
|
-
if preload == true && driver.can_preload?(
|
153
|
+
if preload == true && driver.can_preload?(grid_class.scope, name)
|
154
154
|
name
|
155
155
|
else
|
156
156
|
preload
|
data/lib/datagrid/columns.rb
CHANGED
@@ -44,13 +44,11 @@ module Datagrid
|
|
44
44
|
class_attribute :cached, default: false
|
45
45
|
class_attribute :decorator, instance_writer: false
|
46
46
|
end
|
47
|
-
base.
|
47
|
+
base.include InstanceMethods
|
48
48
|
end
|
49
49
|
|
50
50
|
module ClassMethods
|
51
51
|
|
52
|
-
|
53
|
-
|
54
52
|
# @param data [Boolean] if true returns only columns with data representation. Default: false.
|
55
53
|
# @param html [Boolean] if true returns only columns with html columns. Default: false.
|
56
54
|
# @param column_names [Array<String>] list of column names if you want to limit data only to specified columns
|
@@ -446,8 +444,8 @@ module Datagrid
|
|
446
444
|
|
447
445
|
protected
|
448
446
|
|
449
|
-
def append_column_preload(
|
450
|
-
columns.inject(
|
447
|
+
def append_column_preload(relation)
|
448
|
+
columns.inject(relation) do |current, column|
|
451
449
|
column.append_preload(current)
|
452
450
|
end
|
453
451
|
end
|
data/lib/datagrid/core.rb
CHANGED
@@ -6,7 +6,7 @@ module Datagrid
|
|
6
6
|
|
7
7
|
# @!visibility private
|
8
8
|
def self.included(base)
|
9
|
-
base.extend
|
9
|
+
base.extend ClassMethods
|
10
10
|
base.class_eval do
|
11
11
|
class_attribute :scope_value
|
12
12
|
|
@@ -20,7 +20,7 @@ module Datagrid
|
|
20
20
|
include ::ActiveModel::AttributeAssignment
|
21
21
|
end
|
22
22
|
end
|
23
|
-
base.
|
23
|
+
base.include InstanceMethods
|
24
24
|
end
|
25
25
|
|
26
26
|
module ClassMethods
|
@@ -56,14 +56,20 @@ module Datagrid
|
|
56
56
|
}
|
57
57
|
self
|
58
58
|
else
|
59
|
-
|
60
|
-
|
59
|
+
scope = original_scope
|
60
|
+
driver.to_scope(scope)
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
+
# @!visibility private
|
65
|
+
def original_scope
|
66
|
+
check_scope_defined!
|
67
|
+
scope_value.call
|
68
|
+
end
|
69
|
+
|
64
70
|
# @!visibility private
|
65
71
|
def driver
|
66
|
-
@driver ||= Drivers::AbstractDriver.guess_driver(
|
72
|
+
@driver ||= Drivers::AbstractDriver.guess_driver(scope_value.call).new
|
67
73
|
end
|
68
74
|
|
69
75
|
# Allows dynamic columns definition, that could not be defined at class level
|
@@ -162,7 +168,7 @@ module Datagrid
|
|
162
168
|
|
163
169
|
# @return [Object] a scope relation (e.g ActiveRecord::Relation) with all applied filters
|
164
170
|
def assets
|
165
|
-
|
171
|
+
scope
|
166
172
|
end
|
167
173
|
|
168
174
|
# Updates datagrid attributes with a passed hash argument
|
@@ -222,11 +228,17 @@ module Datagrid
|
|
222
228
|
}
|
223
229
|
self
|
224
230
|
else
|
225
|
-
|
226
|
-
|
231
|
+
scope = original_scope
|
232
|
+
driver.to_scope(scope)
|
227
233
|
end
|
228
234
|
end
|
229
235
|
|
236
|
+
# @!visibility private
|
237
|
+
def original_scope
|
238
|
+
check_scope_defined!
|
239
|
+
scope_value.call
|
240
|
+
end
|
241
|
+
|
230
242
|
# Resets current instance scope to default scope defined in a class
|
231
243
|
# @return [void]
|
232
244
|
def reset_scope
|
@@ -19,7 +19,7 @@ module Datagrid
|
|
19
19
|
# We can only reveal it by checking if it respond to some specific
|
20
20
|
# to ActiveRecord method like #scoped
|
21
21
|
if scope.is_a?(Class)
|
22
|
-
|
22
|
+
scope.all
|
23
23
|
elsif scope.respond_to?(:scoped)
|
24
24
|
scope.scoped
|
25
25
|
else
|
@@ -43,7 +43,7 @@ module Datagrid
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def asc(scope, order)
|
46
|
-
#
|
46
|
+
# Relation#order isn't able to override already applied order
|
47
47
|
# Using #reorder instead
|
48
48
|
scope.reorder(order)
|
49
49
|
end
|
@@ -82,8 +82,12 @@ module Datagrid
|
|
82
82
|
end
|
83
83
|
|
84
84
|
def batch_each(scope, batch_size, &block)
|
85
|
-
scope.
|
86
|
-
|
85
|
+
if scope.opts[:limit]
|
86
|
+
scope.each(&block)
|
87
|
+
else
|
88
|
+
scope.extension(:pagination).each_page(batch_size) do |page|
|
89
|
+
page.each(&block)
|
90
|
+
end
|
87
91
|
end
|
88
92
|
end
|
89
93
|
|
@@ -6,6 +6,7 @@ end
|
|
6
6
|
# @!visibility private
|
7
7
|
class Datagrid::Filters::BaseFilter
|
8
8
|
|
9
|
+
class_attribute :input_helper_name, instance_writer: false
|
9
10
|
attr_accessor :grid_class, :options, :block, :name
|
10
11
|
|
11
12
|
def initialize(grid_class, name, options = {}, &block)
|
@@ -172,8 +173,8 @@ class Datagrid::Filters::BaseFilter
|
|
172
173
|
|
173
174
|
def default_filter(value, scope, grid)
|
174
175
|
return nil if dummy?
|
175
|
-
if !driver.has_column?(scope, name) &&
|
176
|
-
|
176
|
+
if !driver.has_column?(scope, name) && scope.respond_to?(name)
|
177
|
+
scope.send(name, value)
|
177
178
|
else
|
178
179
|
default_filter_where(scope, value)
|
179
180
|
end
|
@@ -13,6 +13,7 @@ module Datagrid
|
|
13
13
|
module ClassMethods
|
14
14
|
|
15
15
|
def date_range_filters(field, from_options = {}, to_options = {})
|
16
|
+
Utils.warn_once('date_range_filters is deprecated in favor of range option for date filter')
|
16
17
|
from_options = normalize_composite_filter_options(from_options, field)
|
17
18
|
to_options = normalize_composite_filter_options(to_options, field)
|
18
19
|
|
@@ -25,6 +26,7 @@ module Datagrid
|
|
25
26
|
end
|
26
27
|
|
27
28
|
def integer_range_filters(field, from_options = {}, to_options = {})
|
29
|
+
Utils.warn_once('integer_range_filters is deprecated in favor of range option for integer filter')
|
28
30
|
from_options = normalize_composite_filter_options(from_options, field)
|
29
31
|
to_options = normalize_composite_filter_options(to_options, field)
|
30
32
|
filter(from_options[:name] || :"from_#{field.to_s.tr('.', '_')}", :integer, **from_options) do |value, scope, grid|
|
@@ -37,7 +39,7 @@ module Datagrid
|
|
37
39
|
|
38
40
|
def normalize_composite_filter_options(options, field)
|
39
41
|
if options.is_a?(String) || options.is_a?(Symbol)
|
40
|
-
options = {:
|
42
|
+
options = {name: options}
|
41
43
|
end
|
42
44
|
options
|
43
45
|
end
|
@@ -80,7 +80,7 @@ class Datagrid::Filters::DynamicFilter < Datagrid::Filters::BaseFilter
|
|
80
80
|
|
81
81
|
def operations_select
|
82
82
|
operations.map do |operation|
|
83
|
-
[I18n.t(operation, :
|
83
|
+
[I18n.t(operation, scope: "datagrid.filters.dynamic.operations").html_safe, operation]
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
data/lib/datagrid/filters.rb
CHANGED
@@ -5,7 +5,6 @@ module Datagrid
|
|
5
5
|
|
6
6
|
require "datagrid/filters/base_filter"
|
7
7
|
require "datagrid/filters/enum_filter"
|
8
|
-
require "datagrid/filters/boolean_enum_filter"
|
9
8
|
require "datagrid/filters/extended_boolean_filter"
|
10
9
|
require "datagrid/filters/boolean_filter"
|
11
10
|
require "datagrid/filters/date_filter"
|
@@ -18,24 +17,23 @@ module Datagrid
|
|
18
17
|
require "datagrid/filters/dynamic_filter"
|
19
18
|
|
20
19
|
FILTER_TYPES = {
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
27
|
-
:
|
28
|
-
:
|
29
|
-
:
|
30
|
-
:
|
31
|
-
:dynamic => Filters::DynamicFilter
|
20
|
+
date: Filters::DateFilter,
|
21
|
+
datetime: Filters::DateTimeFilter,
|
22
|
+
string: Filters::StringFilter,
|
23
|
+
default: Filters::DefaultFilter,
|
24
|
+
xboolean: Filters::ExtendedBooleanFilter ,
|
25
|
+
boolean: Filters::BooleanFilter ,
|
26
|
+
integer: Filters::IntegerFilter,
|
27
|
+
enum: Filters::EnumFilter,
|
28
|
+
float: Filters::FloatFilter,
|
29
|
+
dynamic: Filters::DynamicFilter
|
32
30
|
}
|
33
31
|
|
34
32
|
DEFAULT_FILTER_BLOCK = Object.new
|
35
33
|
|
36
34
|
# @!visibility private
|
37
35
|
def self.included(base)
|
38
|
-
base.extend
|
36
|
+
base.extend ClassMethods
|
39
37
|
base.class_eval do
|
40
38
|
|
41
39
|
include Datagrid::Core
|
@@ -44,7 +42,7 @@ module Datagrid
|
|
44
42
|
self.filters_array = []
|
45
43
|
|
46
44
|
end
|
47
|
-
base.
|
45
|
+
base.include InstanceMethods
|
48
46
|
end
|
49
47
|
|
50
48
|
module ClassMethods
|
@@ -95,7 +93,8 @@ module Datagrid
|
|
95
93
|
# Accepts a block or a symbol with an instance method name
|
96
94
|
# * <tt>:unless</tt> - specify the reverse condition when the filter can be dislayed and used.
|
97
95
|
# Accepts a block or a symbol with an instance method name
|
98
|
-
# * <tt>:input_options</tt> - options passed when rendering html input tag attributes
|
96
|
+
# * <tt>:input_options</tt> - options passed when rendering html input tag attributes.
|
97
|
+
# Use <tt>input_options.type</tt> to control input type including <tt>textarea</tt>.
|
99
98
|
# * <tt>:label_options</tt> - options passed when rendering html label tag attributes
|
100
99
|
#
|
101
100
|
# See: https://github.com/bogdan/datagrid/wiki/Filters for examples
|
@@ -8,15 +8,10 @@ module Datagrid
|
|
8
8
|
# * <tt>select</tt> for enum, xboolean filter types
|
9
9
|
# * <tt>check_box</tt> for boolean filter type
|
10
10
|
# * <tt>text_field</tt> for other filter types
|
11
|
-
def datagrid_filter(filter_or_attribute,
|
11
|
+
def datagrid_filter(filter_or_attribute, partials: nil, **options, &block)
|
12
12
|
filter = datagrid_get_filter(filter_or_attribute)
|
13
|
-
options = {
|
14
|
-
|
15
|
-
**add_html_classes(options, filter.name, datagrid_filter_html_class(filter)),
|
16
|
-
}
|
17
|
-
# Prevent partials option from appearing in HTML attributes
|
18
|
-
options.delete(:partials) # Legacy option
|
19
|
-
self.send(filter.form_builder_helper_name, filter, options, &block)
|
13
|
+
options = add_html_classes({**filter.input_options, **options}, filter.name, datagrid_filter_html_class(filter))
|
14
|
+
self.send( filter.form_builder_helper_name, filter, **options, &block)
|
20
15
|
end
|
21
16
|
|
22
17
|
# @param filter_or_attribute [Datagrid::Filters::BaseFilter, String, Symbol] filter object or filter name
|
@@ -28,11 +23,17 @@ module Datagrid
|
|
28
23
|
label(filter.name, text || filter.header, **filter.label_options, **options, &block)
|
29
24
|
end
|
30
25
|
|
31
|
-
|
32
|
-
|
33
|
-
|
26
|
+
def datagrid_filter_input(attribute_or_filter, **options)
|
27
|
+
filter = datagrid_get_filter(attribute_or_filter)
|
28
|
+
value = object.filter_value_as_string(filter)
|
29
|
+
if options[:type]&.to_sym == :textarea
|
30
|
+
text_area filter.name, value: value, **options, type: nil
|
31
|
+
else
|
32
|
+
text_field filter.name, value: value, **options
|
33
|
+
end
|
34
34
|
end
|
35
35
|
|
36
|
+
protected
|
36
37
|
def datagrid_extended_boolean_filter(attribute_or_filter, options = {})
|
37
38
|
datagrid_enum_filter(attribute_or_filter, options)
|
38
39
|
end
|
@@ -50,27 +51,25 @@ module Datagrid
|
|
50
51
|
end
|
51
52
|
|
52
53
|
def datagrid_default_filter(attribute_or_filter, options = {})
|
53
|
-
|
54
|
-
text_field filter.name, value: object.filter_value_as_string(filter), **options
|
54
|
+
datagrid_filter_input(attribute_or_filter, **options)
|
55
55
|
end
|
56
56
|
|
57
57
|
def datagrid_enum_filter(attribute_or_filter, options = {}, &block)
|
58
58
|
filter = datagrid_get_filter(attribute_or_filter)
|
59
59
|
if filter.checkboxes?
|
60
|
-
partial = partial_path('enum_checkboxes')
|
61
60
|
options = add_html_classes(options, 'checkboxes')
|
62
61
|
elements = object.select_options(filter).map do |element|
|
63
62
|
text, value = @template.send(:option_text_and_value, element)
|
64
63
|
checked = enum_checkbox_checked?(filter, value)
|
65
64
|
[value, text, checked]
|
66
65
|
end
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
:
|
71
|
-
:
|
72
|
-
:
|
73
|
-
:
|
66
|
+
render_partial(
|
67
|
+
'enum_checkboxes',
|
68
|
+
{
|
69
|
+
elements: elements,
|
70
|
+
form: self,
|
71
|
+
filter: filter,
|
72
|
+
options: options,
|
74
73
|
}
|
75
74
|
)
|
76
75
|
else
|
@@ -112,21 +111,26 @@ module Datagrid
|
|
112
111
|
filter = datagrid_get_filter(attribute_or_filter)
|
113
112
|
input_name = "#{object_name}[#{filter.name.to_s}][]"
|
114
113
|
field, operation, value = object.filter_value(filter)
|
115
|
-
options = options.merge(:
|
114
|
+
options = options.merge(name: input_name)
|
116
115
|
field_input = dynamic_filter_select(
|
117
116
|
filter.name,
|
118
117
|
object.select_options(filter) || [],
|
119
118
|
{
|
120
|
-
:
|
121
|
-
:
|
122
|
-
:
|
123
|
-
:
|
119
|
+
include_blank: filter.include_blank,
|
120
|
+
prompt: filter.prompt,
|
121
|
+
include_hidden: false,
|
122
|
+
selected: field
|
124
123
|
},
|
125
124
|
add_html_classes(options, "field")
|
126
125
|
)
|
127
126
|
operation_input = dynamic_filter_select(
|
128
127
|
filter.name, filter.operations_select,
|
129
|
-
{
|
128
|
+
{
|
129
|
+
include_blank: false,
|
130
|
+
include_hidden: false,
|
131
|
+
prompt: false,
|
132
|
+
selected: operation,
|
133
|
+
},
|
130
134
|
add_html_classes(options, "operation")
|
131
135
|
)
|
132
136
|
value_input = text_field(filter.name, **add_html_classes(options, "value"), value: value)
|
@@ -148,20 +152,19 @@ module Datagrid
|
|
148
152
|
def datagrid_range_filter(type, attribute_or_filter, options = {})
|
149
153
|
filter = datagrid_get_filter(attribute_or_filter)
|
150
154
|
if filter.range?
|
151
|
-
|
152
|
-
options = options.merge(:multiple => true)
|
155
|
+
options = options.merge(multiple: true)
|
153
156
|
from_options = datagrid_range_filter_options(object, filter, :from, options)
|
154
157
|
to_options = datagrid_range_filter_options(object, filter, :to, options)
|
155
|
-
|
156
|
-
:
|
158
|
+
render_partial 'range_filter', {
|
159
|
+
from_options: from_options, to_options: to_options, filter: filter, form: self
|
157
160
|
}
|
158
161
|
else
|
159
|
-
|
162
|
+
datagrid_filter_input(filter, **options)
|
160
163
|
end
|
161
164
|
end
|
162
165
|
|
163
166
|
def datagrid_range_filter_options(object, filter, type, options)
|
164
|
-
type_method_map = {:
|
167
|
+
type_method_map = {from: :first, to: :last}
|
165
168
|
options = add_html_classes(options, type)
|
166
169
|
options[:value] = filter.format(object[filter.name].try(type_method_map[type]))
|
167
170
|
# In case of datagrid ranged filter
|
@@ -179,7 +182,7 @@ module Datagrid
|
|
179
182
|
end
|
180
183
|
|
181
184
|
def datagrid_string_filter(attribute_or_filter, options = {})
|
182
|
-
|
185
|
+
datagrid_range_filter(:string, attribute_or_filter, options)
|
183
186
|
end
|
184
187
|
|
185
188
|
def datagrid_float_filter(attribute_or_filter, options = {})
|
@@ -218,6 +221,10 @@ module Datagrid
|
|
218
221
|
File.join('datagrid', name)
|
219
222
|
end
|
220
223
|
|
224
|
+
def render_partial(name, locals)
|
225
|
+
@template.render partial: partial_path(name), locals: locals
|
226
|
+
end
|
227
|
+
|
221
228
|
class Error < StandardError
|
222
229
|
end
|
223
230
|
end
|
data/lib/datagrid/helper.rb
CHANGED
@@ -52,6 +52,9 @@ module Datagrid
|
|
52
52
|
#
|
53
53
|
# * <tt>:order</tt> - display ordering controls built-in into header
|
54
54
|
# Default: true
|
55
|
+
# * <tt>:columns</tt> - Array of column names to display.
|
56
|
+
# Used in case when same grid class is used in different places
|
57
|
+
# and needs different columns. Default: all defined columns.
|
55
58
|
# * <tt>:partials</tt> - Path for partials lookup.
|
56
59
|
# Default: 'datagrid'.
|
57
60
|
# @param grid [Datagrid] grid object
|
@@ -124,12 +127,10 @@ module Datagrid
|
|
124
127
|
# <% row = datagrid_row(grid, user) %>
|
125
128
|
# First Name: <%= row.first_name %>
|
126
129
|
# Last Name: <%= row.last_name %>
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
end
|
132
|
-
end
|
130
|
+
# @example
|
131
|
+
# <%= datagrid_row(grid, user, columns: [:first_name, :last_name, :actions]) %>
|
132
|
+
def datagrid_row(grid, asset, **options, &block)
|
133
|
+
datagrid_renderer.row(grid, asset, **options, &block)
|
133
134
|
end
|
134
135
|
|
135
136
|
# Generates an ascending or descending order url for the given column
|
@@ -141,51 +142,6 @@ module Datagrid
|
|
141
142
|
datagrid_renderer.order_path(grid, column, descending, request)
|
142
143
|
end
|
143
144
|
|
144
|
-
# Represents a datagrid row that provides access to column values for the given asset
|
145
|
-
# @example
|
146
|
-
# row = datagrid_row(grid, user)
|
147
|
-
# row.class # => Datagrid::Helper::HtmlRow
|
148
|
-
# row.first_name # => "<strong>Bogdan</strong>"
|
149
|
-
# row.grid # => Grid object
|
150
|
-
# row.asset # => User object
|
151
|
-
# row.each do |value|
|
152
|
-
# puts value
|
153
|
-
# end
|
154
|
-
class HtmlRow
|
155
|
-
|
156
|
-
include Enumerable
|
157
|
-
|
158
|
-
attr_reader :grid, :asset
|
159
|
-
|
160
|
-
# @!visibility private
|
161
|
-
def initialize(context, grid, asset)
|
162
|
-
@context = context
|
163
|
-
@grid = grid
|
164
|
-
@asset = asset
|
165
|
-
end
|
166
|
-
|
167
|
-
# @return [Object] a column value for given column name
|
168
|
-
def get(column)
|
169
|
-
@context.datagrid_value(@grid, column, @asset)
|
170
|
-
end
|
171
|
-
|
172
|
-
# Iterates over all column values that are available in the row
|
173
|
-
# param block [Proc] column value iterator
|
174
|
-
def each(&block)
|
175
|
-
@grid.columns.each do |column|
|
176
|
-
block.call(get(column))
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
protected
|
181
|
-
def method_missing(method, *args, &blk)
|
182
|
-
if column = @grid.column_by_name(method)
|
183
|
-
get(column)
|
184
|
-
else
|
185
|
-
super
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
189
145
|
|
190
146
|
protected
|
191
147
|
|
data/lib/datagrid/locale/en.yml
CHANGED
@@ -2,22 +2,26 @@ en:
|
|
2
2
|
datagrid:
|
3
3
|
no_results:
|
4
4
|
"――"
|
5
|
+
|
5
6
|
table:
|
6
7
|
order:
|
7
8
|
asc: "↑"
|
8
9
|
desc: "↓"
|
9
10
|
no_columns: "No columns selected"
|
11
|
+
|
10
12
|
form:
|
11
13
|
search: "Search"
|
12
14
|
reset: "Reset"
|
15
|
+
|
13
16
|
filters:
|
14
17
|
xboolean:
|
15
18
|
"yes": "Yes"
|
16
19
|
"no": "No"
|
17
|
-
|
18
20
|
dynamic:
|
19
21
|
operations:
|
20
22
|
">=": "≥"
|
21
23
|
"<=": "≤"
|
22
24
|
"=": "="
|
23
25
|
"=~": "≈"
|
26
|
+
range:
|
27
|
+
separator: " - "
|
data/lib/datagrid/ordering.rb
CHANGED
data/lib/datagrid/renderer.rb
CHANGED
@@ -41,9 +41,9 @@ module Datagrid
|
|
41
41
|
|
42
42
|
_render_partial('table', options[:partials],
|
43
43
|
{
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
44
|
+
grid: grid,
|
45
|
+
options: options,
|
46
|
+
assets: assets
|
47
47
|
})
|
48
48
|
end
|
49
49
|
|
@@ -56,22 +56,20 @@ module Datagrid
|
|
56
56
|
|
57
57
|
def rows(grid, assets = grid.assets, **options, &block)
|
58
58
|
result = assets.map do |asset|
|
59
|
-
|
60
|
-
@template.capture do
|
61
|
-
yield(Datagrid::Helper::HtmlRow.new(@template, grid, asset))
|
62
|
-
end
|
63
|
-
else
|
64
|
-
_render_partial( 'row', options[:partials], {
|
65
|
-
:grid => grid,
|
66
|
-
:options => options,
|
67
|
-
:asset => asset
|
68
|
-
})
|
69
|
-
end
|
59
|
+
row(grid, asset, **options, &block)
|
70
60
|
end.to_a.join
|
71
61
|
|
72
62
|
_safe(result)
|
73
63
|
end
|
74
64
|
|
65
|
+
def row(grid, asset, **options, &block)
|
66
|
+
Datagrid::Helper::HtmlRow.new(self, grid, asset, options).tap do |row|
|
67
|
+
if block_given?
|
68
|
+
return @template.capture(row, &block)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
75
73
|
def order_for(grid, column, options = {})
|
76
74
|
_render_partial('order_for', options[:partials],
|
77
75
|
{ :grid => grid, :column => column })
|
@@ -99,4 +97,61 @@ module Datagrid
|
|
99
97
|
})
|
100
98
|
end
|
101
99
|
end
|
100
|
+
|
101
|
+
module Helper
|
102
|
+
# Represents a datagrid row that provides access to column values for the given asset
|
103
|
+
# @example
|
104
|
+
# row = datagrid_row(grid, user)
|
105
|
+
# row.class # => Datagrid::Helper::HtmlRow
|
106
|
+
# row.first_name # => "<strong>Bogdan</strong>"
|
107
|
+
# row.grid # => Grid object
|
108
|
+
# row.asset # => User object
|
109
|
+
# row.each do |value|
|
110
|
+
# puts value
|
111
|
+
# end
|
112
|
+
class HtmlRow
|
113
|
+
|
114
|
+
include Enumerable
|
115
|
+
|
116
|
+
attr_reader :grid, :asset, :options
|
117
|
+
|
118
|
+
# @!visibility private
|
119
|
+
def initialize(renderer, grid, asset, options)
|
120
|
+
@renderer = renderer
|
121
|
+
@grid = grid
|
122
|
+
@asset = asset
|
123
|
+
@options = options
|
124
|
+
end
|
125
|
+
|
126
|
+
# @return [Object] a column value for given column name
|
127
|
+
def get(column)
|
128
|
+
@renderer.format_value(@grid, column, @asset)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Iterates over all column values that are available in the row
|
132
|
+
# param block [Proc] column value iterator
|
133
|
+
def each(&block)
|
134
|
+
(@options[:columns] || @grid.html_columns).each do |column|
|
135
|
+
block.call(get(column))
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def to_s
|
140
|
+
@renderer.send(:_render_partial, 'row', options[:partials], {
|
141
|
+
:grid => grid,
|
142
|
+
:options => options,
|
143
|
+
:asset => asset
|
144
|
+
})
|
145
|
+
end
|
146
|
+
|
147
|
+
protected
|
148
|
+
def method_missing(method, *args, &blk)
|
149
|
+
if column = @grid.column_by_name(method)
|
150
|
+
get(column)
|
151
|
+
else
|
152
|
+
super
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
102
157
|
end
|
data/lib/datagrid/rspec.rb
CHANGED
@@ -32,14 +32,14 @@ shared_examples_for "Datagrid" do
|
|
32
32
|
describe "filter ##{filter.name}" do
|
33
33
|
|
34
34
|
let(:filter_value) do
|
35
|
-
|
35
|
+
|
36
36
|
case Datagrid::Filters::FILTER_TYPES.invert[filter.class]
|
37
37
|
when :default, :string
|
38
38
|
"text"
|
39
39
|
when :date
|
40
40
|
1.day.ago
|
41
|
-
when :xboolean
|
42
|
-
Datagrid::Filters::
|
41
|
+
when :xboolean
|
42
|
+
Datagrid::Filters::ExtendedBooleanFilter::YES
|
43
43
|
when :boolean
|
44
44
|
true
|
45
45
|
when :integer
|
@@ -58,7 +58,7 @@ shared_examples_for "Datagrid" do
|
|
58
58
|
end
|
59
59
|
|
60
60
|
it "should be supported" do
|
61
|
-
subject.assets.should_not be_nil
|
61
|
+
subject.assets.should_not be_nil
|
62
62
|
#TODO: better matcher.
|
63
63
|
end
|
64
64
|
end
|
data/lib/datagrid/version.rb
CHANGED
data/templates/grid.rb.erb
CHANGED
data/templates/index.html.erb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: datagrid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bogdan Gusiev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -62,7 +62,6 @@ files:
|
|
62
62
|
- lib/datagrid/engine.rb
|
63
63
|
- lib/datagrid/filters.rb
|
64
64
|
- lib/datagrid/filters/base_filter.rb
|
65
|
-
- lib/datagrid/filters/boolean_enum_filter.rb
|
66
65
|
- lib/datagrid/filters/boolean_filter.rb
|
67
66
|
- lib/datagrid/filters/composite_filters.rb
|
68
67
|
- lib/datagrid/filters/date_filter.rb
|
@@ -114,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
114
113
|
- !ruby/object:Gem::Version
|
115
114
|
version: '0'
|
116
115
|
requirements: []
|
117
|
-
rubygems_version: 3.
|
116
|
+
rubygems_version: 3.4.15
|
118
117
|
signing_key:
|
119
118
|
specification_version: 4
|
120
119
|
summary: Ruby gem to create datagrids
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# @!visibility private
|
2
|
-
class Datagrid::Filters::BooleanEnumFilter < Datagrid::Filters::EnumFilter
|
3
|
-
|
4
|
-
YES = "YES"
|
5
|
-
NO = "NO"
|
6
|
-
|
7
|
-
def initialize(report, attribute, options = {}, &block)
|
8
|
-
Datagrid::Utils.warn_once("Datagrid eboolean filter is deprecated in favor of xboolean filter")
|
9
|
-
options[:select] = [YES, NO].map do |key, value|
|
10
|
-
[I18n.t("datagrid.filters.eboolean.#{key.downcase}", default: key.downcase.capitalize), key]
|
11
|
-
end
|
12
|
-
super(report, attribute, options, &block)
|
13
|
-
end
|
14
|
-
|
15
|
-
|
16
|
-
def checkbox_id(value)
|
17
|
-
[object_name, name, value].join('_').underscore
|
18
|
-
end
|
19
|
-
end
|