effective_datatables 4.7.16 → 4.8.16
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +215 -24
- data/app/assets/javascripts/effective_datatables/flash.js.coffee +1 -1
- data/app/assets/javascripts/effective_datatables/initialize.js.coffee +18 -5
- data/app/assets/javascripts/effective_datatables/inline_crud.js.coffee +42 -13
- data/app/assets/javascripts/effective_datatables/reorder.js.coffee +8 -2
- data/app/assets/javascripts/effective_datatables/reset.js.coffee +23 -2
- data/app/assets/javascripts/vendor/jquery.delayedChange.js +1 -2
- data/app/assets/stylesheets/dataTables/dataTables.bootstrap4.scss +1 -3
- data/app/helpers/effective_datatables_helper.rb +4 -1
- data/app/helpers/effective_datatables_private_helper.rb +12 -8
- data/app/models/effective/datatable.rb +34 -3
- data/app/models/effective/datatable_value_tool.rb +0 -6
- data/app/models/effective/effective_datatable/attributes.rb +1 -0
- data/app/models/effective/effective_datatable/compute.rb +6 -5
- data/app/models/effective/effective_datatable/cookie.rb +2 -0
- data/app/models/effective/effective_datatable/dsl/filters.rb +1 -1
- data/app/models/effective/effective_datatable/format.rb +9 -9
- data/app/models/effective/effective_datatable/params.rb +5 -0
- data/app/models/effective/effective_datatable/resource.rb +16 -9
- data/app/models/effective/effective_datatable/state.rb +1 -1
- data/app/views/effective/datatables/_active_storage_column.html.haml +4 -0
- data/app/views/effective/datatables/_bulk_actions_dropdown.html.haml +3 -2
- data/config/effective_datatables.rb +5 -1
- data/config/locales/en.yml +3 -1
- data/config/locales/es.yml +3 -1
- data/config/locales/nl.yml +3 -1
- data/lib/effective_datatables/version.rb +1 -1
- data/lib/effective_datatables.rb +4 -0
- metadata +7 -9
- data/app/datatables/effective_style_guide_datatable.rb +0 -47
- data/app/models/effective/access_denied.rb +0 -17
- data/app/views/effective/style_guide/_effective_datatables.html.haml +0 -1
@@ -162,9 +162,7 @@ div.dataTables_scrollFoot > .dataTables_scrollFootInner > table {
|
|
162
162
|
text-align: center;
|
163
163
|
}
|
164
164
|
}
|
165
|
-
|
166
|
-
padding-right: 20px;
|
167
|
-
}
|
165
|
+
|
168
166
|
table.dataTable.table-sm .sorting:before,
|
169
167
|
table.dataTable.table-sm .sorting_asc:before,
|
170
168
|
table.dataTable.table-sm .sorting_desc:before {
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# These are expected to be called by a developer. They are part of the datatables DSL.
|
2
2
|
module EffectiveDatatablesHelper
|
3
|
-
def render_datatable(datatable, input_js: {}, buttons: true, charts: true, entries: true, filters: true, inline: false, pagination: true, search: true, simple: false, sort: true)
|
3
|
+
def render_datatable(datatable, input_js: {}, buttons: true, charts: true, entries: true, filters: true, inline: false, namespace: nil, pagination: true, search: true, simple: false, sort: true)
|
4
4
|
raise 'expected datatable to be present' unless datatable
|
5
5
|
raise 'expected input_js to be a Hash' unless input_js.kind_of?(Hash)
|
6
6
|
|
@@ -10,6 +10,7 @@ module EffectiveDatatablesHelper
|
|
10
10
|
|
11
11
|
datatable.attributes[:inline] = true if inline
|
12
12
|
datatable.attributes[:sortable] = false unless sort
|
13
|
+
datatable.attributes[:namespace] = namespace if namespace
|
13
14
|
|
14
15
|
datatable.view ||= self
|
15
16
|
|
@@ -40,10 +41,12 @@ module EffectiveDatatablesHelper
|
|
40
41
|
id: datatable.to_param,
|
41
42
|
class: html_class,
|
42
43
|
data: {
|
44
|
+
'all-label' => I18n.t('effective_datatables.all'),
|
43
45
|
'attributes' => EffectiveDatatables.encrypt(datatable.attributes),
|
44
46
|
'authenticity-token' => form_authenticity_token,
|
45
47
|
'bulk-actions' => datatable_bulk_actions(datatable),
|
46
48
|
'columns' => datatable_columns(datatable),
|
49
|
+
'default-visibility' => datatable.default_visibility.to_json,
|
47
50
|
'display-length' => datatable.display_length,
|
48
51
|
'display-order' => datatable_display_order(datatable),
|
49
52
|
'display-records' => datatable.to_json[:recordsFiltered],
|
@@ -44,7 +44,7 @@ module EffectiveDatatablesPrivateHelper
|
|
44
44
|
action = { action: :new, class: ['btn', column[:btn_class].presence].compact.join(' '), 'data-remote': true }
|
45
45
|
|
46
46
|
if column[:actions][:new].kind_of?(Hash) # This might be active_record_array_collection?
|
47
|
-
action
|
47
|
+
action.merge!(column[:actions][:new])
|
48
48
|
|
49
49
|
effective_resource = (datatable.effective_resource || datatable.fallback_effective_resource)
|
50
50
|
klass = (column[:actions][:new][:klass] || effective_resource&.klass || datatable.collection_class)
|
@@ -84,7 +84,7 @@ module EffectiveDatatablesPrivateHelper
|
|
84
84
|
collection = opts[:search].delete(:collection)
|
85
85
|
value = datatable.state[:search][name]
|
86
86
|
|
87
|
-
options = opts[:search].
|
87
|
+
options = opts[:search].merge!(
|
88
88
|
name: nil,
|
89
89
|
feedback: false,
|
90
90
|
label: false,
|
@@ -92,24 +92,26 @@ module EffectiveDatatablesPrivateHelper
|
|
92
92
|
data: { 'column-name': name, 'column-index': opts[:index] }
|
93
93
|
)
|
94
94
|
|
95
|
+
options.delete(:fuzzy)
|
96
|
+
|
95
97
|
case options.delete(:as)
|
96
98
|
when :string, :text, :number
|
97
99
|
form.text_field name, options
|
98
100
|
when :date, :datetime
|
99
|
-
form.date_field name, options.reverse_merge(
|
101
|
+
form.date_field name, options.reverse_merge!(
|
100
102
|
date_linked: false, prepend: false, input_js: { useStrict: true, keepInvalid: true }
|
101
103
|
)
|
102
104
|
when :time
|
103
|
-
form.time_field name, options.reverse_merge(
|
105
|
+
form.time_field name, options.reverse_merge!(
|
104
106
|
date_linked: false, prepend: false, input_js: { useStrict: false, keepInvalid: true }
|
105
107
|
)
|
106
108
|
when :select, :boolean
|
107
|
-
options[:input_js] = (options[:input_js] || {}).reverse_merge(placeholder: '')
|
109
|
+
options[:input_js] = (options[:input_js] || {}).reverse_merge!(placeholder: '')
|
108
110
|
|
109
111
|
form.select name, collection, options
|
110
112
|
when :bulk_actions
|
111
113
|
options[:data]['role'] = 'bulk-actions'
|
112
|
-
form.check_box name, options.merge(label: ' ')
|
114
|
+
form.check_box name, options.merge!(label: ' ')
|
113
115
|
end
|
114
116
|
end
|
115
117
|
|
@@ -139,7 +141,7 @@ module EffectiveDatatablesPrivateHelper
|
|
139
141
|
placeholder: (opts[:label] || name.to_s.titleize),
|
140
142
|
value: value,
|
141
143
|
wrapper: { class: 'form-group col-auto'}
|
142
|
-
}.merge(opts.except(:as, :collection, :parse))
|
144
|
+
}.merge!(opts.except(:as, :collection, :parse, :value))
|
143
145
|
|
144
146
|
options[:name] = '' unless datatable._filters_form_required?
|
145
147
|
|
@@ -149,6 +151,8 @@ module EffectiveDatatablesPrivateHelper
|
|
149
151
|
elsif as == :boolean
|
150
152
|
collection ||= [true, false].map { |value| [t("effective_datatables.boolean_#{value}"), value] }
|
151
153
|
form.public_send(:select, name, collection, options) # boolean
|
154
|
+
elsif as == :string
|
155
|
+
form.public_send(:text_field, name, options)
|
152
156
|
elsif form.respond_to?(as)
|
153
157
|
form.public_send(as, name, options) # check_box, text_area
|
154
158
|
else
|
@@ -169,7 +173,7 @@ module EffectiveDatatablesPrivateHelper
|
|
169
173
|
label: false,
|
170
174
|
required: false,
|
171
175
|
wrapper: { class: 'form-group col-auto'}
|
172
|
-
}.merge(opts)
|
176
|
+
}.merge!(opts.except(:checked, :value))
|
173
177
|
|
174
178
|
form.radios :scope, collection, options
|
175
179
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Effective
|
2
2
|
class Datatable
|
3
3
|
attr_reader :attributes # Anything that we initialize our table with. That's it. Can't be changed by state.
|
4
|
-
attr_reader :effective_resource
|
5
4
|
attr_reader :state
|
5
|
+
attr_accessor :effective_resource
|
6
6
|
|
7
7
|
# Hashes of DSL options
|
8
8
|
attr_reader :_aggregates
|
@@ -33,7 +33,7 @@ module Effective
|
|
33
33
|
include Effective::EffectiveDatatable::Resource
|
34
34
|
include Effective::EffectiveDatatable::State
|
35
35
|
|
36
|
-
def initialize(view = nil, attributes = nil)
|
36
|
+
def initialize(view = nil, attributes = nil)
|
37
37
|
(attributes = view; view = nil) if view.kind_of?(Hash)
|
38
38
|
|
39
39
|
@attributes = (attributes || {})
|
@@ -49,13 +49,40 @@ module Effective
|
|
49
49
|
|
50
50
|
raise 'expected a hash of arguments' unless @attributes.kind_of?(Hash)
|
51
51
|
raise 'collection is defined as a method. Please use the collection do ... end syntax.' unless collection.nil?
|
52
|
+
|
52
53
|
self.view = view if view
|
53
54
|
end
|
54
55
|
|
56
|
+
def rendered(params = {})
|
57
|
+
raise('expected a hash of params') unless params.kind_of?(Hash)
|
58
|
+
|
59
|
+
view = ApplicationController.renderer.controller.helpers
|
60
|
+
|
61
|
+
view.class_eval do
|
62
|
+
attr_accessor :rendered_params
|
63
|
+
|
64
|
+
def current_user
|
65
|
+
rendered_params[:current_user]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
if params[:current_user_id]
|
70
|
+
params[:current_user] = User.find(params[:current_user_id])
|
71
|
+
end
|
72
|
+
|
73
|
+
view.rendered_params = params
|
74
|
+
|
75
|
+
self.view = view
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
55
79
|
# Once the view is assigned, we initialize everything
|
56
80
|
def view=(view)
|
57
81
|
@view = (view.respond_to?(:view_context) ? view.view_context : view)
|
58
|
-
|
82
|
+
|
83
|
+
unless @view.respond_to?(:params) || @view.respond_to?(:rendered_params)
|
84
|
+
raise 'expected view to respond to params'
|
85
|
+
end
|
59
86
|
|
60
87
|
assert_attributes!
|
61
88
|
load_attributes!
|
@@ -170,6 +197,10 @@ module Effective
|
|
170
197
|
@fallback_effective_resource ||= Effective::Resource.new('', namespace: controller_namespace)
|
171
198
|
end
|
172
199
|
|
200
|
+
def default_visibility
|
201
|
+
columns.values.inject({}) { |h, col| h[col[:index]] = col[:visible]; h }
|
202
|
+
end
|
203
|
+
|
173
204
|
private
|
174
205
|
|
175
206
|
def column_tool
|
@@ -36,6 +36,9 @@ module Effective
|
|
36
36
|
# Apply value ordering
|
37
37
|
col = value_tool.order(col)
|
38
38
|
|
39
|
+
# Charts too
|
40
|
+
@charts_data = chart(collection, col) if _charts.present?
|
41
|
+
|
39
42
|
# Apply pagination
|
40
43
|
col = col.kind_of?(Array) ? value_tool.paginate(col) : column_tool.paginate(col)
|
41
44
|
|
@@ -48,9 +51,6 @@ module Effective
|
|
48
51
|
# Compute aggregate data
|
49
52
|
@aggregates_data = aggregate(col) if _aggregates.present?
|
50
53
|
|
51
|
-
# Charts too
|
52
|
-
@charts_data = chart(col) if _charts.present?
|
53
|
-
|
54
54
|
# Format all results
|
55
55
|
format(col)
|
56
56
|
|
@@ -64,6 +64,7 @@ module Effective
|
|
64
64
|
if state[:visible][name] == false && (name != order_name) # Sort by invisible array column
|
65
65
|
BLANK
|
66
66
|
elsif opts[:compute]
|
67
|
+
|
67
68
|
if array_collection?
|
68
69
|
dsl_tool.instance_exec(obj, obj[opts[:index]], &opts[:compute])
|
69
70
|
else
|
@@ -161,11 +162,11 @@ module Effective
|
|
161
162
|
end || BLANK
|
162
163
|
end
|
163
164
|
|
164
|
-
def chart(collection)
|
165
|
+
def chart(collection, searched_collection)
|
165
166
|
_charts.inject({}) do |retval, (name, chart)|
|
166
167
|
retval[name] = {
|
167
168
|
as: chart[:as],
|
168
|
-
data: dsl_tool.instance_exec(collection, &chart[:compute]),
|
169
|
+
data: dsl_tool.instance_exec(collection, searched_collection, &chart[:compute]),
|
169
170
|
name: chart[:name],
|
170
171
|
options: chart[:options]
|
171
172
|
}
|
@@ -10,6 +10,7 @@ module Effective
|
|
10
10
|
|
11
11
|
def load_cookie!
|
12
12
|
return unless EffectiveDatatables.save_state
|
13
|
+
return unless view.respond_to?(:cookies)
|
13
14
|
|
14
15
|
@dt_cookie = view.cookies.signed['_effective_dt']
|
15
16
|
|
@@ -33,6 +34,7 @@ module Effective
|
|
33
34
|
|
34
35
|
def save_cookie!
|
35
36
|
return unless EffectiveDatatables.save_state
|
37
|
+
return unless view.respond_to?(:cookies)
|
36
38
|
|
37
39
|
@dt_cookie ||= []
|
38
40
|
@dt_cookie << [cookie_key, cookie_payload]
|
@@ -16,7 +16,7 @@ module Effective
|
|
16
16
|
next unless state[:visible][name]
|
17
17
|
|
18
18
|
if opts[:partial]
|
19
|
-
locals = { datatable: self, column: opts }.merge(resource_col_locals(opts))
|
19
|
+
locals = { datatable: self, column: opts }.merge!(resource_col_locals(opts))
|
20
20
|
|
21
21
|
rendered[name] = (view.render(
|
22
22
|
partial: opts[:partial],
|
@@ -27,7 +27,6 @@ module Effective
|
|
27
27
|
spacer_template: SPACER_TEMPLATE
|
28
28
|
) || '').split(SPACER)
|
29
29
|
elsif opts[:as] == :actions # This is actions_col and actions_col do .. end, but not actions_col partial: 'something'
|
30
|
-
resources = collection.map { |row| row[opts[:index]] }
|
31
30
|
locals = { datatable: self, column: opts, spacer_template: SPACER_TEMPLATE }
|
32
31
|
|
33
32
|
atts = {
|
@@ -36,16 +35,17 @@ module Effective
|
|
36
35
|
effective_resource: effective_resource,
|
37
36
|
locals: locals,
|
38
37
|
partial: opts[:actions_partial],
|
39
|
-
}.
|
38
|
+
}.merge!(opts[:actions]).tap(&:compact!)
|
40
39
|
|
41
40
|
rendered[name] = if effective_resource.blank?
|
42
|
-
|
41
|
+
collection.map { |row| row[opts[:index]] }.map do |resource|
|
43
42
|
polymorphic_resource = Effective::Resource.new(resource, namespace: controller_namespace)
|
44
43
|
(view.render_resource_actions(resource, atts.merge(effective_resource: polymorphic_resource), &opts[:format]) || '')
|
45
44
|
end
|
46
45
|
else
|
47
|
-
(view.render_resource_actions(
|
46
|
+
(view.render_resource_actions(collection.map { |row| row[opts[:index]] }, atts, &opts[:format]) || '').split(SPACER)
|
48
47
|
end
|
48
|
+
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -88,9 +88,9 @@ module Effective
|
|
88
88
|
when :currency
|
89
89
|
view.number_to_currency(value)
|
90
90
|
when :date
|
91
|
-
(value.strftime(
|
91
|
+
value.respond_to?(:strftime) ? value.strftime(EffectiveDatatables.format_date) : BLANK
|
92
92
|
when :datetime
|
93
|
-
(value.strftime(
|
93
|
+
value.respond_to?(:strftime) ? value.strftime(EffectiveDatatables.format_datetime) : BLANK
|
94
94
|
when :decimal
|
95
95
|
value
|
96
96
|
when :duration
|
@@ -116,7 +116,7 @@ module Effective
|
|
116
116
|
when Numeric ; view.number_to_currency(value)
|
117
117
|
end
|
118
118
|
when :time
|
119
|
-
(value.strftime(
|
119
|
+
value.respond_to?(:strftime) ? value.strftime(EffectiveDatatables.format_time) : BLANK
|
120
120
|
else
|
121
121
|
value.to_s
|
122
122
|
end
|
@@ -135,7 +135,7 @@ module Effective
|
|
135
135
|
end
|
136
136
|
|
137
137
|
# Merge local options. Special behaviour for remote: false
|
138
|
-
if column[:actions].kind_of?(Hash)
|
138
|
+
if column[:actions].present? && column[:actions].kind_of?(Hash)
|
139
139
|
column[:actions].each do |action, opts|
|
140
140
|
next unless opts.kind_of?(Hash)
|
141
141
|
|
@@ -6,18 +6,23 @@ module Effective
|
|
6
6
|
|
7
7
|
def datatables_ajax_request?
|
8
8
|
return @_datatables_ajax_request unless @_datatables_ajax_request.nil?
|
9
|
+
return unless view.respond_to?(:params)
|
9
10
|
|
10
11
|
@_datatables_ajax_request = (view.present? && view.params.key?(:draw) && view.params.key?(:columns))
|
11
12
|
end
|
12
13
|
|
13
14
|
def datatables_inline_request?
|
14
15
|
return @_datatables_inline_request unless @_datatables_inline_request.nil?
|
16
|
+
return unless view.respond_to?(:params)
|
15
17
|
|
16
18
|
@_datatables_inline_request = (view.present? && view.params[:_datatable_id].to_s.split('-')[0...-1] == to_param.split('-')[0...-1])
|
17
19
|
end
|
18
20
|
|
19
21
|
def params
|
20
22
|
return {} unless view.present?
|
23
|
+
return view.rendered_params if view.respond_to?(:rendered_params)
|
24
|
+
return {} unless view.respond_to?(:request)
|
25
|
+
|
21
26
|
@params ||= {}.tap do |params|
|
22
27
|
Rack::Utils.parse_query(URI(view.request.referer.presence || '/').query).each { |k, v| params[k.to_sym] = v }
|
23
28
|
view.params.each { |k, v| params[k.to_sym] = v }
|
@@ -4,7 +4,7 @@ module Effective
|
|
4
4
|
AGGREGATE_SQL_FUNCTIONS = ['ARRAY_AGG(', 'AVG(', 'COUNT(', 'MAX(', 'MIN(', 'STRING_AGG(', 'SUM(']
|
5
5
|
|
6
6
|
def admin_namespace?
|
7
|
-
|
7
|
+
[:admin, 'admin'].include?(controller_namespace)
|
8
8
|
end
|
9
9
|
|
10
10
|
def controller_namespace
|
@@ -31,7 +31,7 @@ module Effective
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def load_effective_resource!
|
34
|
-
@effective_resource
|
34
|
+
@effective_resource ||= if active_record_collection?
|
35
35
|
Effective::Resource.new(collection_class, namespace: controller_namespace)
|
36
36
|
end
|
37
37
|
end
|
@@ -91,14 +91,18 @@ module Effective
|
|
91
91
|
opts[:sql_column] = :effective_addresses
|
92
92
|
when :effective_roles
|
93
93
|
opts[:sql_column] = :effective_roles
|
94
|
+
when :active_storage
|
95
|
+
opts[:sql_column] = :active_storage
|
94
96
|
when :string # This is the fallback
|
95
97
|
# Anything that doesn't belong to the model or the sql table, we assume is a SELECT SUM|AVG|RANK() as fancy
|
96
98
|
opts[:sql_as_column] = true if (effective_resource.table && effective_resource.column(name).blank?)
|
97
99
|
end
|
98
100
|
|
99
|
-
if opts[:sql_column].present?
|
100
|
-
opts[:
|
101
|
+
if opts[:sql_column].present?
|
102
|
+
sql_column = opts[:sql_column].to_s
|
103
|
+
opts[:sql_as_column] = true if AGGREGATE_SQL_FUNCTIONS.any? { |str| sql_column.start_with?(str) }
|
101
104
|
end
|
105
|
+
|
102
106
|
end
|
103
107
|
end
|
104
108
|
|
@@ -137,6 +141,10 @@ module Effective
|
|
137
141
|
opts[:partial] ||= '/effective/datatables/resource_column'
|
138
142
|
end
|
139
143
|
|
144
|
+
if opts[:as] == :active_storage
|
145
|
+
opts[:partial] ||= '/effective/datatables/active_storage_column'
|
146
|
+
end
|
147
|
+
|
140
148
|
opts[:col_class] = [
|
141
149
|
"col-#{opts[:as]}",
|
142
150
|
"col-#{name.to_s.parameterize}",
|
@@ -194,6 +202,7 @@ module Effective
|
|
194
202
|
|
195
203
|
def load_resource_belongs_tos!
|
196
204
|
return unless active_record_collection?
|
205
|
+
return unless @_collection_apply_belongs_to
|
197
206
|
|
198
207
|
changed = attributes.select do |attribute, value|
|
199
208
|
attribute = attribute.to_s
|
@@ -204,7 +213,7 @@ module Effective
|
|
204
213
|
next unless columns[associated]
|
205
214
|
|
206
215
|
if columns[associated][:as] == :belongs_to
|
207
|
-
|
216
|
+
unless @_collection.where_values_hash.include?(attribute)
|
208
217
|
@_collection = @_collection.where(attribute => value)
|
209
218
|
end
|
210
219
|
|
@@ -212,10 +221,8 @@ module Effective
|
|
212
221
|
elsif columns[associated][:as] == :belongs_to_polymorphic
|
213
222
|
associated_type = attributes["#{associated}_type".to_sym] || raise("Expected #{associated}_type attribute to be present when #{associated}_id is present on a polymorphic belongs to")
|
214
223
|
|
215
|
-
|
216
|
-
|
217
|
-
@_collection = @_collection.where(attribute => value).where("#{associated}_type" => associated_type)
|
218
|
-
end
|
224
|
+
unless @_collection.where_values_hash.include?(attribute) || @_collection.where_values_hash.include?("#{associated}_type")
|
225
|
+
@_collection = @_collection.where(attribute => value).where("#{associated}_type" => associated_type)
|
219
226
|
end
|
220
227
|
|
221
228
|
columns.delete(associated)
|
@@ -198,7 +198,7 @@ module Effective
|
|
198
198
|
def parse_filter_value(filter, value)
|
199
199
|
return filter[:parse].call(value) if filter[:parse]
|
200
200
|
return nil if value.blank? && !filter[:required]
|
201
|
-
Effective::Attribute.new(filter[:value]).parse(value, name: filter[:name])
|
201
|
+
Effective::Attribute.new(filter[:as] || filter[:value] || :string).parse(value, name: filter[:name])
|
202
202
|
end
|
203
203
|
|
204
204
|
def cookie_state_params
|
@@ -1,8 +1,9 @@
|
|
1
1
|
.btn-group.buttons-bulk-actions
|
2
2
|
%button.btn.btn-link.btn-sm.dropdown-toggle{'type': 'button', 'data-toggle': 'dropdown', 'aria-haspopup': true, 'aria-expanded': false, 'disabled': 'disabled'}
|
3
|
-
|
3
|
+
= t('effective_datatables.bulk_actions')
|
4
4
|
.dropdown-menu
|
5
5
|
- if datatable._bulk_actions.present?
|
6
6
|
= datatable._bulk_actions.join.html_safe
|
7
7
|
- else
|
8
|
-
%a.dropdown-item{href: '#'}
|
8
|
+
%a.dropdown-item{href: '#'}
|
9
|
+
= t('effective_datatables.no_bulk_actions')
|
@@ -35,8 +35,12 @@ EffectiveDatatables.setup do |config|
|
|
35
35
|
config.save_state = true
|
36
36
|
|
37
37
|
# Configure the _effective_dt cookie.
|
38
|
-
config.cookie_max_size =
|
38
|
+
config.cookie_max_size = 1500 # String size. Final byte size is about 1.5 times bigger, after rails signs it
|
39
39
|
config.cookie_domain = :all # Should usually be :all
|
40
40
|
config.cookie_tld_length = nil # Leave nil to autodetect, or set to probably 2
|
41
41
|
|
42
|
+
# Date formatting
|
43
|
+
config.format_datetime = '%F %H:%M'
|
44
|
+
config.format_date = '%F'
|
45
|
+
config.format_time = '%H:%M'
|
42
46
|
end
|
data/config/locales/en.yml
CHANGED
data/config/locales/es.yml
CHANGED
data/config/locales/nl.yml
CHANGED
data/lib/effective_datatables.rb
CHANGED
@@ -16,6 +16,10 @@ module EffectiveDatatables
|
|
16
16
|
mattr_accessor :cookie_domain
|
17
17
|
mattr_accessor :cookie_tld_length
|
18
18
|
|
19
|
+
mattr_accessor :format_datetime
|
20
|
+
mattr_accessor :format_date
|
21
|
+
mattr_accessor :format_time
|
22
|
+
|
19
23
|
mattr_accessor :debug
|
20
24
|
|
21
25
|
alias_method :max_cookie_size, :cookie_max_size
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_datatables
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.8.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -129,11 +129,9 @@ files:
|
|
129
129
|
- app/assets/stylesheets/effective_datatables.scss
|
130
130
|
- app/assets/stylesheets/effective_datatables/_overrides.bootstrap4.scss
|
131
131
|
- app/controllers/effective/datatables_controller.rb
|
132
|
-
- app/datatables/effective_style_guide_datatable.rb
|
133
132
|
- app/helpers/effective_datatables_controller_helper.rb
|
134
133
|
- app/helpers/effective_datatables_helper.rb
|
135
134
|
- app/helpers/effective_datatables_private_helper.rb
|
136
|
-
- app/models/effective/access_denied.rb
|
137
135
|
- app/models/effective/datatable.rb
|
138
136
|
- app/models/effective/datatable_column.rb
|
139
137
|
- app/models/effective/datatable_column_tool.rb
|
@@ -153,6 +151,7 @@ files:
|
|
153
151
|
- app/models/effective/effective_datatable/params.rb
|
154
152
|
- app/models/effective/effective_datatable/resource.rb
|
155
153
|
- app/models/effective/effective_datatable/state.rb
|
154
|
+
- app/views/effective/datatables/_active_storage_column.html.haml
|
156
155
|
- app/views/effective/datatables/_bulk_actions_column.html.haml
|
157
156
|
- app/views/effective/datatables/_bulk_actions_dropdown.html.haml
|
158
157
|
- app/views/effective/datatables/_chart.html.haml
|
@@ -162,7 +161,6 @@ files:
|
|
162
161
|
- app/views/effective/datatables/_resource_column.html.haml
|
163
162
|
- app/views/effective/datatables/_spacer_template.html
|
164
163
|
- app/views/effective/datatables/index.html.haml
|
165
|
-
- app/views/effective/style_guide/_effective_datatables.html.haml
|
166
164
|
- config/effective_datatables.rb
|
167
165
|
- config/locales/en.yml
|
168
166
|
- config/locales/es.yml
|
@@ -177,7 +175,7 @@ homepage: https://github.com/code-and-effect/effective_datatables
|
|
177
175
|
licenses:
|
178
176
|
- MIT
|
179
177
|
metadata: {}
|
180
|
-
post_install_message:
|
178
|
+
post_install_message:
|
181
179
|
rdoc_options: []
|
182
180
|
require_paths:
|
183
181
|
- lib
|
@@ -192,8 +190,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
192
190
|
- !ruby/object:Gem::Version
|
193
191
|
version: '0'
|
194
192
|
requirements: []
|
195
|
-
rubygems_version: 3.
|
196
|
-
signing_key:
|
193
|
+
rubygems_version: 3.1.2
|
194
|
+
signing_key:
|
197
195
|
specification_version: 4
|
198
196
|
summary: Uniquely powerful server-side searching, sorting and filtering of any ActiveRecord
|
199
197
|
or Array collection as well as post-rendered content displayed as a frontend jQuery
|
@@ -1,47 +0,0 @@
|
|
1
|
-
class EffectiveStyleGuideDatatable < Effective::Datatable
|
2
|
-
datatable do
|
3
|
-
length 10
|
4
|
-
|
5
|
-
col :id
|
6
|
-
col :material, search: { collection: ['Stainless Steel', 'Copper', 'Cast Iron', 'Composite'] }
|
7
|
-
col :bowl, search: { collection: ['Single Bowl', 'Double Bowl', 'Triple Bowl'] }
|
8
|
-
col :name
|
9
|
-
col :date, as: :date
|
10
|
-
|
11
|
-
actions_col
|
12
|
-
end
|
13
|
-
|
14
|
-
# Set the permission check to the same as Effective::StyleGuide
|
15
|
-
def collection_class
|
16
|
-
defined?(Effective::StyleGuide) ? Effective::StyleGuide : super
|
17
|
-
end
|
18
|
-
|
19
|
-
collection do
|
20
|
-
now = Time.zone.now
|
21
|
-
[
|
22
|
-
[1, 'Stainless Steel', 'Single Bowl', 'KOHLER Staccato', (now + 1.day)],
|
23
|
-
[2, 'Stainless Steel', 'Double Bowl', 'KOHLER Vault Undercounter', (now + 1.day)],
|
24
|
-
[3, 'Stainless Steel', 'Triple Bowl', 'KRAUS All-In-One', (now + 1.day)],
|
25
|
-
[4, 'Stainless Steel', 'Single Bowl', 'KOHLER Vault Dual Mount', (now + 1.day)],
|
26
|
-
[5, 'Stainless Steel', 'Single Bowl', 'KRAUS All-In-One Undermount', (now + 2.days)],
|
27
|
-
[6, 'Stainless Steel', 'Double Bowl', 'Glacier Bay All-in-One', (now + 2.days)],
|
28
|
-
[7, 'Stainless Steel', 'Single Bowl', 'Elkay Neptune', (now + 2.days)],
|
29
|
-
[8, 'Copper', 'Single Bowl', 'ECOSINKS Apron Front Dual Mount', (now + 2.days)],
|
30
|
-
[9, 'Copper', 'Double Bowl', 'ECOSINKS Dual Mount Front Hammered', (now + 2.days)],
|
31
|
-
[10, 'Copper', 'Triple Bowl', 'Glarier Bay Undermount', (now + 3.days)],
|
32
|
-
[11, 'Copper', 'Single Bowl', 'Whitehaus Undermount', (now + 3.days)],
|
33
|
-
[12, 'Copper', 'Double Bowl', 'Belle Foret Apron Front', (now + 3.days)],
|
34
|
-
[13, 'Copper', 'Double Bowl', 'Pegasus Dual Mount', (now + 3.days)],
|
35
|
-
[14, 'Cast Iron', 'Double Bowl', 'KOHLER Whitehaven', (now + 3.days)],
|
36
|
-
[15, 'Cast Iron', 'Triple Bowl', 'KOHLER Hartland', (now + 3.days)],
|
37
|
-
[16, 'Cast Iron', 'Single Bowl', 'KOHLER Cape Dory Undercounter', (now + 4.days)],
|
38
|
-
[17, 'Cast Iron', 'Double Bowl', 'KOLER Bakersfield', (now + 4.days)],
|
39
|
-
[18, 'Cast Iron', 'Double Bowl', 'American Standard Offset', (now + 4.days)],
|
40
|
-
[19, 'Cast Iron', 'Single Bowl', 'Brookfield Top', (now + 4.days)],
|
41
|
-
[20, 'Composite', 'Single Bowl', 'Blanco Diamond Undermount', (now + 5.days)],
|
42
|
-
[21, 'Composite', 'Double Bowl', 'Mont Blanc Waterbrook', (now + 5.days)],
|
43
|
-
[22, 'Composite', 'Triple Bowl', 'Pegasus Triple Mount', (now + 5.days)],
|
44
|
-
[23, 'Composite', 'Single Bowl', 'Swanstone Dual Mount', (now + 5.days)]
|
45
|
-
]
|
46
|
-
end
|
47
|
-
end
|