effective_datatables 4.6.2 → 4.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +1 -1
- data/app/assets/javascripts/effective_datatables/initialize.js.coffee +1 -1
- data/app/assets/javascripts/effective_datatables/inline_crud.js.coffee +2 -2
- data/app/assets/javascripts/effective_datatables/reorder.js.coffee +1 -1
- data/app/controllers/effective/datatables_controller.rb +2 -2
- data/app/helpers/effective_datatables_helper.rb +3 -3
- data/app/models/effective/datatable.rb +7 -6
- data/app/models/effective/effective_datatable/attributes.rb +5 -8
- data/app/models/effective/effective_datatable/cookie.rb +9 -32
- data/app/models/effective/effective_datatable/params.rb +2 -6
- data/app/models/effective/effective_datatable/state.rb +12 -9
- data/config/effective_datatables.rb +1 -2
- data/lib/effective_datatables.rb +22 -2
- data/lib/effective_datatables/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4470fed54cce153fddf79984ca733cfe00c3232cff43cce5b20d998b18a2f6b
|
4
|
+
data.tar.gz: 9357498f73ab31c491e28f09e9c6d4619c8960f26764210f04fbe700fa322744
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 96329fe58fe84c6594d99048be257d38645f78fa88eeac7a55f712383014295075cd40e2ab38cfbdb592d34e76c9466a98689511b09e49205a5e5fdf442f1409
|
7
|
+
data.tar.gz: d5db73e577df3a97abfe8eff01c81699f65617652b2d2ecf1e712e0e185c908d0d76bf293993020e98bf89f9faf32b9ed318de52551d9ec702df98f2f3b5d750
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -348,7 +348,7 @@ When initialized with a Hash, that hash is available throughout the entire datat
|
|
348
348
|
|
349
349
|
You can call the attributes from within the datatable as `attributes` or within a partial/view as `@datatable.attributes`.
|
350
350
|
|
351
|
-
These attributes are serialized and stored in an encrypted
|
351
|
+
These attributes are serialized and stored in an encrypted data attribute. Objects won't work. Keep it simple.
|
352
352
|
|
353
353
|
Attributes cannot be changed by search, filter, or state in any way. They're guaranteed to be the same as when first initialized.
|
354
354
|
|
@@ -60,7 +60,7 @@ initializeDataTables = (target) ->
|
|
60
60
|
$table = $(api.table().node())
|
61
61
|
$form = $(".effective-datatables-filters[aria-controls='#{$table.attr('id')}']").first()
|
62
62
|
|
63
|
-
params['
|
63
|
+
params['attributes'] = $table.data('attributes')
|
64
64
|
params['authenticity_token'] = $table.data('authenticity-token')
|
65
65
|
|
66
66
|
if $form.length > 0
|
@@ -8,7 +8,7 @@ $(document).on 'ajax:beforeSend', '.dataTables_wrapper .col-actions', (e, xhr, s
|
|
8
8
|
|
9
9
|
return true if ('' + $action.data('inline')) == 'false'
|
10
10
|
|
11
|
-
$params =
|
11
|
+
$params = $.param({_datatable_id: $table.attr('id'), _datatable_attributes: $table.data('attributes'), _datatable_action: true })
|
12
12
|
settings.url += (if settings.url.indexOf('?') == -1 then '?' else '&') + $params
|
13
13
|
|
14
14
|
if $action.closest('.effective-datatables-inline-row,table.dataTable').hasClass('effective-datatables-inline-row')
|
@@ -60,7 +60,7 @@ $(document).on 'ajax:error', '.dataTables_wrapper', (event) ->
|
|
60
60
|
$(document).on 'ajax:beforeSend', '.dataTables_wrapper .col-inline-form', (e, xhr, settings) ->
|
61
61
|
$table = $(e.target).closest('table')
|
62
62
|
|
63
|
-
$params =
|
63
|
+
$params = $.param({_datatable_id: $table.attr('id'), _datatable_attributes: $table.data('attributes') })
|
64
64
|
settings.url += (if settings.url.indexOf('?') == -1 then '?' else '&') + $params
|
65
65
|
|
66
66
|
true
|
@@ -8,7 +8,7 @@ reorder = (event, diff, edit) ->
|
|
8
8
|
return unless oldNode? && newNode?
|
9
9
|
|
10
10
|
url = @context[0].ajax.url.replace('.json', '/reorder.json')
|
11
|
-
data = {'reorder[id]': oldNode.data('reorder-resource'), 'reorder[old]': oldNode.val(), 'reorder[new]': newNode.val(),
|
11
|
+
data = {'reorder[id]': oldNode.data('reorder-resource'), 'reorder[old]': oldNode.val(), 'reorder[new]': newNode.val(), attributes: $table.data('attributes') }
|
12
12
|
|
13
13
|
@context[0].rowreorder.c.enable = false
|
14
14
|
|
@@ -5,7 +5,7 @@ module Effective
|
|
5
5
|
# This will respond to both a GET and a POST
|
6
6
|
def show
|
7
7
|
begin
|
8
|
-
@datatable = EffectiveDatatables.find(params[:id])
|
8
|
+
@datatable = EffectiveDatatables.find(params[:id], params[:attributes])
|
9
9
|
@datatable.view = view_context
|
10
10
|
|
11
11
|
EffectiveDatatables.authorize!(self, :index, @datatable.collection_class)
|
@@ -22,7 +22,7 @@ module Effective
|
|
22
22
|
|
23
23
|
def reorder
|
24
24
|
begin
|
25
|
-
@datatable = EffectiveDatatables.find(params[:id])
|
25
|
+
@datatable = EffectiveDatatables.find(params[:id], params[:attributes])
|
26
26
|
@datatable.view = view_context
|
27
27
|
|
28
28
|
EffectiveDatatables.authorize!(self, :index, @datatable.collection_class)
|
@@ -40,10 +40,10 @@ module EffectiveDatatablesHelper
|
|
40
40
|
id: datatable.to_param,
|
41
41
|
class: html_class,
|
42
42
|
data: {
|
43
|
+
'attributes' => EffectiveDatatables.encrypt(datatable.attributes),
|
43
44
|
'authenticity-token' => form_authenticity_token,
|
44
45
|
'bulk-actions' => datatable_bulk_actions(datatable),
|
45
46
|
'columns' => datatable_columns(datatable),
|
46
|
-
'cookie' => datatable.cookie_key,
|
47
47
|
'display-length' => datatable.display_length,
|
48
48
|
'display-order' => datatable_display_order(datatable),
|
49
49
|
'display-records' => datatable.to_json[:recordsFiltered],
|
@@ -93,14 +93,14 @@ module EffectiveDatatablesHelper
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def inline_datatable?
|
96
|
-
params[:_datatable_id].present?
|
96
|
+
params[:_datatable_id].present? && params[:_datatable_attributes].present?
|
97
97
|
end
|
98
98
|
|
99
99
|
def inline_datatable
|
100
100
|
return nil unless inline_datatable?
|
101
101
|
return @_inline_datatable if @_inline_datatable
|
102
102
|
|
103
|
-
datatable = EffectiveDatatables.find(params[:_datatable_id])
|
103
|
+
datatable = EffectiveDatatables.find(params[:_datatable_id], params[:_datatable_attributes])
|
104
104
|
datatable.view = self
|
105
105
|
|
106
106
|
EffectiveDatatables.authorize!(self, :index, datatable.collection_class)
|
@@ -31,10 +31,10 @@ module Effective
|
|
31
31
|
include Effective::EffectiveDatatable::Resource
|
32
32
|
include Effective::EffectiveDatatable::State
|
33
33
|
|
34
|
-
def initialize(view = nil, attributes =
|
34
|
+
def initialize(view = nil, attributes = nil)
|
35
35
|
(attributes = view; view = nil) if view.kind_of?(Hash)
|
36
36
|
|
37
|
-
@attributes =
|
37
|
+
@attributes = (attributes || {})
|
38
38
|
@state = initial_state
|
39
39
|
|
40
40
|
@_aggregates = {}
|
@@ -45,6 +45,7 @@ module Effective
|
|
45
45
|
@_form = {}
|
46
46
|
@_scopes = {}
|
47
47
|
|
48
|
+
raise 'expected a hash of arguments' unless @attributes.kind_of?(Hash)
|
48
49
|
raise 'collection is defined as a method. Please use the collection do ... end syntax.' unless collection.nil?
|
49
50
|
self.view = view if view
|
50
51
|
end
|
@@ -54,14 +55,14 @@ module Effective
|
|
54
55
|
@view = (view.respond_to?(:view_context) ? view.view_context : view)
|
55
56
|
raise 'expected view to respond to params' unless @view.respond_to?(:params)
|
56
57
|
|
57
|
-
|
58
|
-
assert_cookie!
|
58
|
+
assert_attributes!
|
59
59
|
load_attributes!
|
60
60
|
|
61
61
|
# We need early access to filter and scope, to define defaults from the model first
|
62
|
-
# This means filters do
|
62
|
+
# This means filters do know about attributes but not about columns.
|
63
63
|
initialize_filters if respond_to?(:initialize_filters)
|
64
64
|
load_filters!
|
65
|
+
|
65
66
|
load_state!
|
66
67
|
|
67
68
|
# Bulk actions called first so it can add the bulk_actions_col first
|
@@ -147,7 +148,7 @@ module Effective
|
|
147
148
|
end
|
148
149
|
|
149
150
|
def to_param
|
150
|
-
@to_param ||= "#{self.class.name.underscore.parameterize}-#{
|
151
|
+
@to_param ||= "#{self.class.name.underscore.parameterize}-#{[self.class, attributes].hash.abs.to_s.last(12)}"
|
151
152
|
end
|
152
153
|
|
153
154
|
def columns
|
@@ -4,17 +4,14 @@ module Effective
|
|
4
4
|
|
5
5
|
private
|
6
6
|
|
7
|
-
def
|
8
|
-
|
9
|
-
|
7
|
+
def assert_attributes!
|
8
|
+
if datatables_ajax_request? || datatables_inline_request?
|
9
|
+
raise 'expected attributes to be present' unless attributes.present?
|
10
|
+
end
|
10
11
|
end
|
11
12
|
|
12
13
|
def load_attributes!
|
13
|
-
|
14
|
-
@attributes = cookie.delete(:attributes)
|
15
|
-
else
|
16
|
-
@attributes[:_n] ||= view.controller_path.split('/')[0...-1].join('/').presence
|
17
|
-
end
|
14
|
+
@attributes[:_n] ||= view.controller_path.split('/')[0...-1].join('/').presence
|
18
15
|
end
|
19
16
|
|
20
17
|
end
|
@@ -6,39 +6,21 @@ module Effective
|
|
6
6
|
@cookie
|
7
7
|
end
|
8
8
|
|
9
|
-
def cookie_key
|
10
|
-
@cookie_key ||= (
|
11
|
-
if datatables_ajax_request?
|
12
|
-
view.params[:cookie]
|
13
|
-
elsif datatables_inline_request?
|
14
|
-
view.params[:_datatable_cookie]
|
15
|
-
else
|
16
|
-
cookie_param
|
17
|
-
end
|
18
|
-
)
|
19
|
-
end
|
20
|
-
|
21
|
-
# All possible dt cookie keys. Used to make sure the datatable has a cookie set for this session.
|
22
|
-
def cookie_keys
|
23
|
-
@cookie_keys ||= Array(@dt_cookie).compact.map(&:first)
|
24
|
-
end
|
25
|
-
|
26
|
-
def cookie_param
|
27
|
-
[self.class, attributes].hash.abs.to_s.last(12) # Not guaranteed to be 12 long
|
28
|
-
end
|
29
|
-
|
30
9
|
private
|
31
10
|
|
32
11
|
def load_cookie!
|
12
|
+
return unless EffectiveDatatables.save_state
|
13
|
+
|
33
14
|
@dt_cookie = view.cookies.signed['_effective_dt']
|
34
15
|
|
35
16
|
# Load global datatables cookie
|
36
17
|
if @dt_cookie.present?
|
18
|
+
|
37
19
|
@dt_cookie = Marshal.load(Base64.decode64(@dt_cookie))
|
38
20
|
raise 'invalid datatables cookie' unless @dt_cookie.kind_of?(Array)
|
39
21
|
|
40
22
|
# Assign individual cookie
|
41
|
-
index = @dt_cookie.rindex { |key, _| key ==
|
23
|
+
index = @dt_cookie.rindex { |key, _| key == to_param }
|
42
24
|
@cookie = @dt_cookie.delete_at(index) if index
|
43
25
|
end
|
44
26
|
|
@@ -46,18 +28,14 @@ module Effective
|
|
46
28
|
if @cookie.kind_of?(Array)
|
47
29
|
@cookie = initial_state.keys.zip(@cookie.second).to_h
|
48
30
|
end
|
49
|
-
end
|
50
31
|
|
51
|
-
def assert_cookie!
|
52
|
-
if datatables_ajax_request? || datatables_inline_request?
|
53
|
-
raise 'expected cookie to be present' unless cookie
|
54
|
-
raise 'expected attributes cookie to be present' unless cookie[:attributes]
|
55
|
-
end
|
56
32
|
end
|
57
33
|
|
58
34
|
def save_cookie!
|
35
|
+
return unless EffectiveDatatables.save_state
|
36
|
+
|
59
37
|
@dt_cookie ||= []
|
60
|
-
@dt_cookie << [
|
38
|
+
@dt_cookie << [to_param, cookie_payload]
|
61
39
|
|
62
40
|
while @dt_cookie.to_s.size > EffectiveDatatables.cookie_max_size.to_i
|
63
41
|
@dt_cookie.shift((@dt_cookie.length / 3) + 1)
|
@@ -72,7 +50,7 @@ module Effective
|
|
72
50
|
end
|
73
51
|
|
74
52
|
def cookie_payload
|
75
|
-
payload = state.except(:
|
53
|
+
payload = state.except(:visible)
|
76
54
|
|
77
55
|
# Turn visible into a bitmask. This is undone in load_columns!
|
78
56
|
payload[:vismask] = (
|
@@ -81,8 +59,7 @@ module Effective
|
|
81
59
|
end
|
82
60
|
)
|
83
61
|
|
84
|
-
# Just store the values
|
85
|
-
[attributes] + payload.values
|
62
|
+
payload.values # Just store the values
|
86
63
|
end
|
87
64
|
|
88
65
|
end
|
@@ -7,17 +7,13 @@ module Effective
|
|
7
7
|
def datatables_ajax_request?
|
8
8
|
return @_datatables_ajax_request unless @_datatables_ajax_request.nil?
|
9
9
|
|
10
|
-
@_datatables_ajax_request = (view.present? && view.params.key?(:draw) && view.params.key?(:columns)
|
10
|
+
@_datatables_ajax_request = (view.present? && view.params.key?(:draw) && view.params.key?(:columns))
|
11
11
|
end
|
12
12
|
|
13
13
|
def datatables_inline_request?
|
14
14
|
return @_datatables_inline_request unless @_datatables_inline_request.nil?
|
15
15
|
|
16
|
-
@_datatables_inline_request = (
|
17
|
-
view &&
|
18
|
-
view.params[:_datatable_id].to_s.split('-')[0...-1] == to_param.split('-')[0...-1] &&
|
19
|
-
cookie_keys.include?(view.params[:_datatable_cookie])
|
20
|
-
)
|
16
|
+
@_datatables_inline_request = (view.present? && view.params[:_datatable_id].to_s.split('-')[0...-1] == to_param.split('-')[0...-1])
|
21
17
|
end
|
22
18
|
|
23
19
|
def params
|
@@ -55,7 +55,6 @@ module Effective
|
|
55
55
|
# This is called first. Our initial state is set.
|
56
56
|
def initial_state
|
57
57
|
{
|
58
|
-
attributes: {},
|
59
58
|
filter: {},
|
60
59
|
length: nil,
|
61
60
|
order_name: nil,
|
@@ -89,17 +88,17 @@ module Effective
|
|
89
88
|
|
90
89
|
def load_state!
|
91
90
|
if datatables_ajax_request?
|
91
|
+
load_cookie! # but not state.
|
92
92
|
load_filter_params!
|
93
93
|
load_ajax_state!
|
94
94
|
elsif datatables_inline_request?
|
95
|
-
|
96
|
-
elsif cookie.present? && cookie[:params] == params.length && EffectiveDatatables.save_state
|
97
|
-
load_cookie_state!
|
95
|
+
load_filter_params!
|
98
96
|
else
|
99
|
-
|
97
|
+
load_cookie!
|
98
|
+
load_cookie_state! if cookie.present? && cookie[:params] == cookie_state_params
|
99
|
+
load_filter_params!
|
100
100
|
end
|
101
|
-
|
102
|
-
load_filter_params! unless datatables_ajax_request?
|
101
|
+
|
103
102
|
fill_empty_filters!
|
104
103
|
end
|
105
104
|
|
@@ -134,7 +133,7 @@ module Effective
|
|
134
133
|
state[:filter][name] = parse_filter_value(_filters[name], value)
|
135
134
|
end
|
136
135
|
|
137
|
-
state[:params] = cookie[:params]
|
136
|
+
state[:params] = cookie[:params] if cookie.present?
|
138
137
|
end
|
139
138
|
|
140
139
|
def load_cookie_state!
|
@@ -187,7 +186,7 @@ module Effective
|
|
187
186
|
|
188
187
|
unless datatables_ajax_request?
|
189
188
|
search_params.each { |name, value| state[:search][name] = value }
|
190
|
-
state[:params] =
|
189
|
+
state[:params] = cookie_state_params
|
191
190
|
end
|
192
191
|
|
193
192
|
state[:visible].delete_if { |name, _| columns.key?(name) == false }
|
@@ -202,6 +201,10 @@ module Effective
|
|
202
201
|
Effective::Attribute.new(filter[:value]).parse(value, name: filter[:name])
|
203
202
|
end
|
204
203
|
|
204
|
+
def cookie_state_params
|
205
|
+
params.hash.abs.to_s.last(12)
|
206
|
+
end
|
207
|
+
|
205
208
|
end
|
206
209
|
end
|
207
210
|
end
|
@@ -31,8 +31,7 @@ EffectiveDatatables.setup do |config|
|
|
31
31
|
# Log search/sort information to the console
|
32
32
|
config.debug = true
|
33
33
|
|
34
|
-
#
|
35
|
-
# Irregardless of this setting, effective_datatables still uses a cookie to function
|
34
|
+
# Use a cookie to save and restore state from previous page visits.
|
36
35
|
config.save_state = true
|
37
36
|
|
38
37
|
# Configure the _effective_dt cookie.
|
data/lib/effective_datatables.rb
CHANGED
@@ -42,11 +42,12 @@ module EffectiveDatatables
|
|
42
42
|
raise Effective::AccessDenied.new('Access Denied', action, resource) unless authorized?(controller, action, resource)
|
43
43
|
end
|
44
44
|
|
45
|
-
def self.find(id)
|
45
|
+
def self.find(id, attributes = nil)
|
46
46
|
id = id.to_s.gsub(/-\d+\z/, '').gsub('-', '/')
|
47
47
|
klass = (id.classify.safe_constantize || id.classify.pluralize.safe_constantize)
|
48
|
+
attributes = decrypt(attributes) || {}
|
48
49
|
|
49
|
-
klass.try(:new) || raise('unable to find datatable')
|
50
|
+
klass.try(:new, **attributes) || raise('unable to find datatable')
|
50
51
|
end
|
51
52
|
|
52
53
|
# Locale is coming from view. I think it can be dynamic.
|
@@ -62,4 +63,23 @@ module EffectiveDatatables
|
|
62
63
|
end
|
63
64
|
end
|
64
65
|
|
66
|
+
def self.encrypt(attributes)
|
67
|
+
payload = message_encrypter.encrypt_and_sign(attributes)
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.decrypt(payload)
|
71
|
+
return unless payload.present?
|
72
|
+
return payload if payload.kind_of?(Hash)
|
73
|
+
|
74
|
+
attributes = message_encrypter.decrypt_and_verify(payload)
|
75
|
+
|
76
|
+
raise 'invalid decoded inline payload' unless attributes.kind_of?(Hash)
|
77
|
+
|
78
|
+
attributes
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.message_encrypter
|
82
|
+
ActiveSupport::MessageEncryptor.new(Rails.application.secret_key_base.to_s.first(32))
|
83
|
+
end
|
84
|
+
|
65
85
|
end
|
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.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-06-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|