effective_datatables 3.7.10 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/MIT-LICENSE +1 -1
- data/README.md +32 -32
- data/app/assets/images/dataTables/sort-down.svg +1 -0
- data/app/assets/images/dataTables/sort-up.svg +1 -0
- data/app/assets/images/dataTables/sort.svg +1 -0
- data/app/assets/javascripts/dataTables/buttons/{buttons.bootstrap.js → buttons.bootstrap4.js} +7 -15
- data/app/assets/javascripts/dataTables/dataTables.bootstrap4.js +184 -0
- data/app/assets/javascripts/dataTables/responsive/dataTables.responsive.js +30 -11
- data/app/assets/javascripts/dataTables/responsive/{responsive.bootstrap.js → responsive.bootstrap4.js} +6 -6
- data/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee +43 -43
- data/app/assets/javascripts/effective_datatables/events.js.coffee +7 -4
- data/app/assets/javascripts/effective_datatables/filters.js.coffee +0 -1
- data/app/assets/javascripts/effective_datatables/initialize.js.coffee +45 -49
- data/app/assets/javascripts/effective_datatables/overrides.js +12 -0
- data/app/assets/javascripts/effective_datatables/reset.js.coffee +1 -1
- data/app/assets/javascripts/effective_datatables.js +4 -4
- data/app/assets/stylesheets/dataTables/buttons/{buttons.bootstrap.scss → buttons.bootstrap4.css} +68 -1
- data/app/assets/stylesheets/dataTables/{dataTables.bootstrap.scss → dataTables.bootstrap4.css} +44 -29
- data/app/assets/stylesheets/dataTables/responsive/{responsive.bootstrap.scss → responsive.bootstrap4.css} +3 -3
- data/app/assets/stylesheets/effective_datatables/_overrides.scss +72 -152
- data/app/assets/stylesheets/effective_datatables.scss +3 -4
- data/app/controllers/effective/datatables_controller.rb +6 -39
- data/app/helpers/effective_datatables_helper.rb +55 -50
- data/app/helpers/effective_datatables_private_helper.rb +47 -179
- data/app/models/effective/datatable.rb +16 -44
- data/app/models/effective/datatable_column.rb +0 -1
- data/app/models/effective/datatable_column_tool.rb +2 -4
- data/app/models/effective/datatable_dsl_tool.rb +3 -11
- data/app/models/effective/datatable_value_tool.rb +23 -23
- data/app/models/effective/effective_datatable/attributes.rb +13 -5
- data/app/models/effective/effective_datatable/collection.rb +3 -18
- data/app/models/effective/effective_datatable/compute.rb +6 -17
- data/app/models/effective/effective_datatable/cookie.rb +20 -19
- data/app/models/effective/effective_datatable/dsl/bulk_actions.rb +25 -14
- data/app/models/effective/effective_datatable/dsl/datatable.rb +28 -70
- data/app/models/effective/effective_datatable/dsl/filters.rb +5 -5
- data/app/models/effective/effective_datatable/dsl.rb +3 -8
- data/app/models/effective/effective_datatable/format.rb +50 -95
- data/app/models/effective/effective_datatable/params.rb +3 -8
- data/app/models/effective/effective_datatable/resource.rb +76 -137
- data/app/models/effective/effective_datatable/state.rb +15 -30
- data/app/views/effective/datatables/_actions_column.html.haml +8 -1
- data/app/views/effective/datatables/_bulk_actions_column.html.haml +1 -1
- data/app/views/effective/datatables/_filters.html.haml +11 -12
- data/app/views/effective/datatables/_resource_column.html.haml +8 -11
- data/config/effective_datatables.rb +14 -12
- data/config/routes.rb +0 -1
- data/lib/effective_datatables/engine.rb +4 -14
- data/lib/effective_datatables/version.rb +1 -1
- data/lib/effective_datatables.rb +4 -57
- metadata +20 -31
- data/app/assets/config/effective_datatables_manifest.js +0 -3
- data/app/assets/images/dataTables/sort_asc.png +0 -0
- data/app/assets/images/dataTables/sort_both.png +0 -0
- data/app/assets/images/dataTables/sort_desc.png +0 -0
- data/app/assets/javascripts/dataTables/dataTables.bootstrap.js +0 -182
- data/app/assets/javascripts/dataTables/locales/en.lang +0 -33
- data/app/assets/javascripts/dataTables/locales/es.lang +0 -36
- data/app/assets/javascripts/dataTables/locales/nl.lang +0 -30
- data/app/assets/javascripts/effective_datatables/flash.js.coffee +0 -31
- data/app/assets/javascripts/effective_datatables/inline_crud.js.coffee +0 -217
- data/app/assets/javascripts/effective_datatables/overrides.js.coffee +0 -7
- data/app/assets/javascripts/effective_datatables/reorder.js.coffee +0 -43
- data/app/assets/stylesheets/effective_datatables/_filters.scss +0 -7
- data/app/views/effective/datatables/_reorder_column.html.haml +0 -5
- data/config/locales/en.yml +0 -12
- data/config/locales/es.yml +0 -12
- data/config/locales/nl.yml +0 -12
@@ -14,14 +14,11 @@ module Effective
|
|
14
14
|
@total_records = (active_record_collection? ? column_tool.size(col) : value_tool.size(col))
|
15
15
|
|
16
16
|
# Apply scope
|
17
|
-
col = column_tool.scope(col)
|
17
|
+
col = column_tool.scope(col)
|
18
18
|
|
19
19
|
# Apply column searching
|
20
20
|
col = column_tool.search(col)
|
21
|
-
|
22
|
-
unless value_tool.searched.present? || (column_tool.scoped.blank? && column_tool.searched.blank?)
|
23
|
-
@display_records = column_tool.size(col)
|
24
|
-
end
|
21
|
+
@display_records = column_tool.size(col) unless value_tool.searched.present?
|
25
22
|
|
26
23
|
# Apply column ordering
|
27
24
|
col = column_tool.order(col)
|
@@ -64,15 +61,11 @@ module Effective
|
|
64
61
|
if state[:visible][name] == false && (name != order_name) # Sort by invisible array column
|
65
62
|
BLANK
|
66
63
|
elsif opts[:compute]
|
67
|
-
|
68
|
-
dsl_tool.instance_exec(obj, obj[opts[:index]], &opts[:compute])
|
69
|
-
else
|
70
|
-
dsl_tool.instance_exec(obj, collection, &opts[:compute])
|
71
|
-
end
|
64
|
+
dsl_tool.instance_exec(obj, (active_record_collection? ? collection : obj[opts[:index]]), &opts[:compute])
|
72
65
|
elsif (opts[:partial] || opts[:format])
|
73
|
-
|
66
|
+
active_record_collection? ? obj : obj[opts[:index]]
|
74
67
|
elsif opts[:resource]
|
75
|
-
resource =
|
68
|
+
resource = active_record_collection? ? obj : obj[opts[:index]]
|
76
69
|
|
77
70
|
if opts[:resource_field]
|
78
71
|
(associated, field) = name.to_s.split('.').first(2)
|
@@ -82,8 +75,6 @@ module Effective
|
|
82
75
|
resource.send(name)
|
83
76
|
end
|
84
77
|
|
85
|
-
elsif opts[:as] == :actions
|
86
|
-
obj
|
87
78
|
elsif opts[:as] == :effective_obfuscation
|
88
79
|
obj.to_param
|
89
80
|
elsif array_collection?
|
@@ -135,11 +126,9 @@ module Effective
|
|
135
126
|
length = values.length
|
136
127
|
values = values.reject { |value| value.nil? }
|
137
128
|
|
138
|
-
return BLANK if [:id, :year].include?(column[:name])
|
139
|
-
|
140
129
|
case aggregate[:name]
|
141
130
|
when :total
|
142
|
-
if [:
|
131
|
+
if [:percentage].include?(column[:as])
|
143
132
|
BLANK
|
144
133
|
elsif values.all? { |value| value.kind_of?(Numeric) }
|
145
134
|
values.sum
|
@@ -1,20 +1,32 @@
|
|
1
1
|
module Effective
|
2
2
|
module EffectiveDatatable
|
3
3
|
module Cookie
|
4
|
+
MAX_COOKIE_SIZE = 2500 # String size. Real byte size is about 1.5 times bigger.
|
5
|
+
|
4
6
|
def cookie
|
5
7
|
@cookie
|
6
8
|
end
|
7
9
|
|
10
|
+
def cookie_key
|
11
|
+
@cookie_key ||= (datatables_ajax_request? ? view.params[:cookie] : cookie_param)
|
12
|
+
end
|
13
|
+
|
14
|
+
# All possible dt cookie keys. Used to make sure the datatable has a cookie set for this session.
|
15
|
+
def cookie_keys
|
16
|
+
@cookie_keys ||= Array(@dt_cookie).compact.map(&:first)
|
17
|
+
end
|
18
|
+
|
19
|
+
def cookie_param
|
20
|
+
[self.class, attributes].hash.to_s.last(12)
|
21
|
+
end
|
22
|
+
|
8
23
|
private
|
9
24
|
|
10
25
|
def load_cookie!
|
11
|
-
return unless EffectiveDatatables.save_state
|
12
|
-
|
13
26
|
@dt_cookie = view.cookies.signed['_effective_dt']
|
14
27
|
|
15
28
|
# Load global datatables cookie
|
16
29
|
if @dt_cookie.present?
|
17
|
-
|
18
30
|
@dt_cookie = Marshal.load(Base64.decode64(@dt_cookie))
|
19
31
|
raise 'invalid datatables cookie' unless @dt_cookie.kind_of?(Array)
|
20
32
|
|
@@ -27,33 +39,21 @@ module Effective
|
|
27
39
|
if @cookie.kind_of?(Array)
|
28
40
|
@cookie = initial_state.keys.zip(@cookie.second).to_h
|
29
41
|
end
|
30
|
-
|
31
42
|
end
|
32
43
|
|
33
44
|
def save_cookie!
|
34
|
-
return unless EffectiveDatatables.save_state
|
35
|
-
|
36
45
|
@dt_cookie ||= []
|
37
46
|
@dt_cookie << [cookie_key, cookie_payload]
|
38
47
|
|
39
|
-
while @dt_cookie.to_s.size >
|
48
|
+
while @dt_cookie.to_s.size > MAX_COOKIE_SIZE
|
40
49
|
@dt_cookie.shift((@dt_cookie.length / 3) + 1)
|
41
50
|
end
|
42
51
|
|
43
|
-
|
44
|
-
domain = EffectiveDatatables.cookie_domain || :all
|
45
|
-
tld_length = EffectiveDatatables.cookie_tld_length
|
46
|
-
tld_length ||= (view.request.host == 'localhost' ? nil : view.request.host.to_s.split('.').count)
|
47
|
-
|
48
|
-
view.cookies.signed['_effective_dt'] = { value: Base64.encode64(Marshal.dump(@dt_cookie)), domain: domain, tld_length: tld_length }.compact
|
49
|
-
end
|
50
|
-
|
51
|
-
def cookie_key
|
52
|
-
@cookie_key ||= to_param
|
52
|
+
view.cookies.signed['_effective_dt'] = Base64.encode64(Marshal.dump(@dt_cookie))
|
53
53
|
end
|
54
54
|
|
55
55
|
def cookie_payload
|
56
|
-
payload = state.except(:visible)
|
56
|
+
payload = state.except(:attributes, :visible)
|
57
57
|
|
58
58
|
# Turn visible into a bitmask. This is undone in load_columns!
|
59
59
|
payload[:vismask] = (
|
@@ -62,7 +62,8 @@ module Effective
|
|
62
62
|
end
|
63
63
|
)
|
64
64
|
|
65
|
-
|
65
|
+
# Just store the values
|
66
|
+
[attributes.delete_if { |k, v| v.nil? }] + payload.values
|
66
67
|
end
|
67
68
|
|
68
69
|
end
|
@@ -3,12 +3,12 @@ module Effective
|
|
3
3
|
module Dsl
|
4
4
|
module BulkActions
|
5
5
|
|
6
|
-
def bulk_action(
|
7
|
-
datatable._bulk_actions.push(link_to_bulk_action(
|
6
|
+
def bulk_action(*args)
|
7
|
+
datatable._bulk_actions.push(link_to_bulk_action(*args))
|
8
8
|
end
|
9
9
|
|
10
|
-
def bulk_download(
|
11
|
-
datatable._bulk_actions.push(link_to_bulk_action(
|
10
|
+
def bulk_download(*args)
|
11
|
+
datatable._bulk_actions.push(link_to_bulk_action(*args.merge('data-authenticity-token' => form_authenticity_token)))
|
12
12
|
end
|
13
13
|
|
14
14
|
def bulk_action_divider
|
@@ -22,19 +22,30 @@ module Effective
|
|
22
22
|
private
|
23
23
|
|
24
24
|
# We can't let any data-method be applied to the link, or jquery_ujs does the wrong thing with it
|
25
|
-
def link_to_bulk_action(
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
def link_to_bulk_action(*args)
|
26
|
+
args.map! do |arg|
|
27
|
+
if arg.kind_of?(Hash)
|
28
|
+
data_method = (
|
29
|
+
arg.delete(:'data-method') ||
|
30
|
+
arg.delete('data-method') ||
|
31
|
+
(arg[:data] || {}).delete('method') ||
|
32
|
+
(arg[:data] || {}).delete(:method)
|
33
|
+
)
|
34
|
+
|
35
|
+
# But if the data-method was :get, we add bulk-actions-get-link = true
|
36
|
+
if data_method.to_s == 'get'
|
37
|
+
arg[:data].present? ? arg[:data]['bulk-actions-get'] = true : arg['data-bulk-actions-get'] = true
|
38
|
+
end
|
39
|
+
|
40
|
+
arg[:class] = [arg[:class], 'dropdown-item'].compact.join(' ')
|
41
|
+
end
|
42
|
+
|
43
|
+
arg
|
30
44
|
end
|
31
45
|
|
32
|
-
|
33
|
-
opts['data-ajax-method'] = verbs[opts.delete('data-method').to_s.upcase] || 'POST'
|
34
|
-
|
35
|
-
opts[:class] = [opts[:class], 'dropdown-item'].compact.join(' ')
|
46
|
+
args << { class: 'dropdown-item' } if args.none? { |arg| arg.kind_of?(Hash) }
|
36
47
|
|
37
|
-
|
48
|
+
link_to(*args)
|
38
49
|
end
|
39
50
|
|
40
51
|
end
|
@@ -3,11 +3,6 @@ module Effective
|
|
3
3
|
module Dsl
|
4
4
|
module Datatable
|
5
5
|
# Instance Methods inside the datatable do .. end block
|
6
|
-
def length(length)
|
7
|
-
raise 'length must be 5, 10, 25, 50, 100, 250, 500, :all' unless [5, 10, 25, 50, 100, 250, 500, :all].include?(length)
|
8
|
-
datatable.state[:length] ||= (length == :all ? 9999999 : length)
|
9
|
-
end
|
10
|
-
|
11
6
|
def order(name, dir = nil)
|
12
7
|
raise 'order direction must be :asc or :desc' unless [nil, :asc, :desc].include?(dir)
|
13
8
|
|
@@ -15,13 +10,9 @@ module Effective
|
|
15
10
|
datatable.state[:order_dir] ||= dir
|
16
11
|
end
|
17
12
|
|
18
|
-
def
|
19
|
-
raise '
|
20
|
-
|
21
|
-
datatable.state[:order_name] = :_reorder
|
22
|
-
datatable.state[:order_dir] = dir
|
23
|
-
|
24
|
-
reorder_col(name)
|
13
|
+
def length(length)
|
14
|
+
raise 'length must be 5, 10, 25, 50, 100, 250, 500, :all' unless [5, 10, 25, 50, 100, 250, 500, :all].include?(length)
|
15
|
+
datatable.state[:length] ||= (length == :all ? 9999999 : length)
|
25
16
|
end
|
26
17
|
|
27
18
|
# A col has its internal values sorted/searched before the block is run
|
@@ -34,7 +25,7 @@ module Effective
|
|
34
25
|
name = name.to_sym unless name.to_s.include?('.')
|
35
26
|
|
36
27
|
datatable._columns[name] = Effective::DatatableColumn.new(
|
37
|
-
action: action,
|
28
|
+
action: action, # resource columns only
|
38
29
|
as: as,
|
39
30
|
compute: nil,
|
40
31
|
col_class: col_class,
|
@@ -62,7 +53,7 @@ module Effective
|
|
62
53
|
name = name.to_sym unless name.to_s.include?('.')
|
63
54
|
|
64
55
|
datatable._columns[name] = Effective::DatatableColumn.new(
|
65
|
-
action: action,
|
56
|
+
action: action, # Resource columns only
|
66
57
|
as: as,
|
67
58
|
compute: (compute if block_given?),
|
68
59
|
col_class: col_class,
|
@@ -82,48 +73,8 @@ module Effective
|
|
82
73
|
)
|
83
74
|
end
|
84
75
|
|
85
|
-
def
|
86
|
-
raise 'You can only have one actions column' if datatable.columns[:
|
87
|
-
|
88
|
-
datatable._columns[:_actions] = Effective::DatatableColumn.new(
|
89
|
-
action: false,
|
90
|
-
as: :actions,
|
91
|
-
compute: nil,
|
92
|
-
btn_class: (btn_class || 'btn-sm btn-outline-primary'),
|
93
|
-
col_class: col_class,
|
94
|
-
format: (format if block_given?),
|
95
|
-
index: nil,
|
96
|
-
inline: (inline.nil? ? datatable.inline? : inline),
|
97
|
-
label: false,
|
98
|
-
name: :actions,
|
99
|
-
partial: partial,
|
100
|
-
partial_as: partial_as,
|
101
|
-
actions_partial: (actions_partial || :glyphicons),
|
102
|
-
responsive: responsive,
|
103
|
-
search: false,
|
104
|
-
sort: false,
|
105
|
-
sql_column: nil,
|
106
|
-
th: nil,
|
107
|
-
th_append: nil,
|
108
|
-
visible: visible,
|
109
|
-
|
110
|
-
# { approve: false }. These args are passed to effective_resources render_resource_actions
|
111
|
-
actions: actions
|
112
|
-
)
|
113
|
-
end
|
114
|
-
|
115
|
-
def aggregate(name, label: nil, &compute)
|
116
|
-
datatable._aggregates[name.to_sym] = {
|
117
|
-
compute: (compute if block_given?),
|
118
|
-
label: label || name.to_s.titleize,
|
119
|
-
name: name.to_sym,
|
120
|
-
}
|
121
|
-
end
|
122
|
-
|
123
|
-
# Called automatically after bulk_actions do ... end
|
124
|
-
# Call again if you want to change the position of the bulk_actions_col
|
125
|
-
def bulk_actions_col(col_class: nil, input_name: nil, partial: nil, partial_as: nil, responsive: 5000)
|
126
|
-
datatable._columns.delete(:_bulk_actions) if datatable.columns[:_bulk_actions]
|
76
|
+
def bulk_actions_col(col_class: nil, partial: nil, partial_as: nil, responsive: 5000)
|
77
|
+
raise 'You can only have one bulk actions column' if datatable.columns[:_bulk_actions].present?
|
127
78
|
|
128
79
|
datatable._columns[:_bulk_actions] = Effective::DatatableColumn.new(
|
129
80
|
action: false,
|
@@ -132,7 +83,6 @@ module Effective
|
|
132
83
|
col_class: col_class,
|
133
84
|
format: nil,
|
134
85
|
index: nil,
|
135
|
-
input_name: (input_name || 'bulk_actions_resources'),
|
136
86
|
label: false,
|
137
87
|
name: :bulk_actions,
|
138
88
|
partial: partial || '/effective/datatables/bulk_actions_column',
|
@@ -147,33 +97,41 @@ module Effective
|
|
147
97
|
)
|
148
98
|
end
|
149
99
|
|
150
|
-
|
151
|
-
|
152
|
-
def reorder_col(name, col_class: nil, partial: nil, partial_as: nil, sql_column: nil, responsive: 5000)
|
153
|
-
datatable._columns.delete(:_reorder) if datatable.columns[:_reorder]
|
100
|
+
def actions_col(show: true, edit: true, destroy: true, col_class: nil, partial: nil, partial_as: nil, responsive: 5000, visible: true, &format)
|
101
|
+
raise 'You can only have one actions column' if datatable.columns[:_actions].present?
|
154
102
|
|
155
|
-
datatable._columns[:
|
103
|
+
datatable._columns[:_actions] = Effective::DatatableColumn.new(
|
156
104
|
action: false,
|
157
|
-
as: :
|
105
|
+
as: :actions,
|
158
106
|
compute: nil,
|
159
107
|
col_class: col_class,
|
160
|
-
format:
|
108
|
+
format: (format if block_given?),
|
161
109
|
index: nil,
|
162
110
|
label: false,
|
163
|
-
name: :
|
164
|
-
partial: partial || '/effective/datatables/
|
111
|
+
name: :actions,
|
112
|
+
partial: partial || '/effective/datatables/actions_column',
|
165
113
|
partial_as: partial_as,
|
166
|
-
reorder: name,
|
167
114
|
responsive: responsive,
|
168
115
|
search: false,
|
169
|
-
sort:
|
170
|
-
sql_column:
|
116
|
+
sort: false,
|
117
|
+
sql_column: nil,
|
171
118
|
th: nil,
|
172
119
|
th_append: nil,
|
173
|
-
visible:
|
120
|
+
visible: visible,
|
121
|
+
|
122
|
+
show: show,
|
123
|
+
edit: edit,
|
124
|
+
destroy: destroy
|
174
125
|
)
|
175
126
|
end
|
176
127
|
|
128
|
+
def aggregate(name, label: nil, &compute)
|
129
|
+
datatable._aggregates[name.to_sym] = {
|
130
|
+
compute: (compute if block_given?),
|
131
|
+
label: label || name.to_s.titleize,
|
132
|
+
name: name.to_sym,
|
133
|
+
}
|
134
|
+
end
|
177
135
|
end
|
178
136
|
end
|
179
137
|
end
|
@@ -5,7 +5,7 @@ module Effective
|
|
5
5
|
def filter(name = nil, value = :_no_value, as: nil, label: nil, parse: nil, required: false, **input_html)
|
6
6
|
return datatable.filter if (name == nil && value == :_no_value) # This lets block methods call 'filter' and get the values
|
7
7
|
|
8
|
-
raise 'expected second argument to be a value
|
8
|
+
raise 'expected second argument to be a value' if value == :_no_value
|
9
9
|
raise 'parse must be a Proc' if parse.present? && !parse.kind_of?(Proc)
|
10
10
|
|
11
11
|
# Merge search
|
@@ -17,19 +17,19 @@ module Effective
|
|
17
17
|
as ||= (
|
18
18
|
if input_html.key?(:collection)
|
19
19
|
:select
|
20
|
-
elsif value
|
20
|
+
elsif value.present?
|
21
21
|
Effective::Attribute.new(value).type
|
22
22
|
end
|
23
|
-
)
|
23
|
+
)
|
24
24
|
|
25
25
|
datatable._filters[name.to_sym] = {
|
26
26
|
value: value,
|
27
27
|
as: as,
|
28
|
-
label: label,
|
28
|
+
label: label || (label == false ? false : name.to_s.titleize),
|
29
29
|
name: name.to_sym,
|
30
30
|
parse: parse,
|
31
31
|
required: required,
|
32
|
-
}.
|
32
|
+
}.reverse_merge(input_html)
|
33
33
|
end
|
34
34
|
|
35
35
|
def scope(name = nil, *args, default: nil, label: nil)
|
@@ -3,20 +3,15 @@ module Effective
|
|
3
3
|
module Dsl
|
4
4
|
|
5
5
|
def bulk_actions(&block)
|
6
|
-
define_method('initialize_bulk_actions') { dsl_tool.instance_exec(&block)
|
6
|
+
define_method('initialize_bulk_actions') { dsl_tool.instance_exec(&block) }
|
7
7
|
end
|
8
8
|
|
9
9
|
def charts(&block)
|
10
10
|
define_method('initialize_charts') { dsl_tool.instance_exec(&block) }
|
11
11
|
end
|
12
12
|
|
13
|
-
def collection(
|
14
|
-
define_method('initialize_collection') {
|
15
|
-
self._collection_apply_belongs_to = apply_belongs_to
|
16
|
-
self._collection_apply_scope = apply_scope
|
17
|
-
|
18
|
-
self._collection = dsl_tool.instance_exec(&block)
|
19
|
-
}
|
13
|
+
def collection(&block)
|
14
|
+
define_method('initialize_collection') { self._collection = dsl_tool.instance_exec(&block) }
|
20
15
|
end
|
21
16
|
|
22
17
|
def datatable(&block)
|
@@ -2,9 +2,6 @@ module Effective
|
|
2
2
|
module EffectiveDatatable
|
3
3
|
module Format
|
4
4
|
BLANK = ''.freeze
|
5
|
-
NONVISIBLE = '...'.freeze
|
6
|
-
SPACER = 'EFFECTIVEDATATABLESSPACER'.freeze
|
7
|
-
SPACER_TEMPLATE = '/effective/datatables/spacer_template'.freeze
|
8
5
|
|
9
6
|
private
|
10
7
|
|
@@ -13,10 +10,12 @@ module Effective
|
|
13
10
|
rendered = {}
|
14
11
|
|
15
12
|
columns.each do |name, opts|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
if opts[:partial] && state[:visible][name]
|
14
|
+
locals = {
|
15
|
+
datatable: self,
|
16
|
+
column: columns[name],
|
17
|
+
controller_namespace: controller_namespace
|
18
|
+
}.merge(actions_col_locals(opts)).merge(resource_col_locals(opts))
|
20
19
|
|
21
20
|
rendered[name] = (view.render(
|
22
21
|
partial: opts[:partial],
|
@@ -24,42 +23,20 @@ module Effective
|
|
24
23
|
collection: collection.map { |row| row[opts[:index]] },
|
25
24
|
formats: :html,
|
26
25
|
locals: locals,
|
27
|
-
spacer_template:
|
28
|
-
) || '').split(
|
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
|
-
locals = { datatable: self, column: opts, spacer_template: SPACER_TEMPLATE }
|
32
|
-
|
33
|
-
atts = {
|
34
|
-
actions: actions_col_actions(opts),
|
35
|
-
btn_class: opts[:btn_class],
|
36
|
-
effective_resource: effective_resource,
|
37
|
-
locals: locals,
|
38
|
-
partial: opts[:actions_partial],
|
39
|
-
}.compact.merge(opts[:actions])
|
40
|
-
|
41
|
-
rendered[name] = if effective_resource.blank?
|
42
|
-
resources.map do |resource|
|
43
|
-
polymorphic_resource = Effective::Resource.new(resource, namespace: controller_namespace)
|
44
|
-
(view.render_resource_actions(resource, atts.merge(effective_resource: polymorphic_resource), &opts[:format]) || '')
|
45
|
-
end
|
46
|
-
else
|
47
|
-
(view.render_resource_actions(resources, atts, &opts[:format]) || '').split(SPACER)
|
48
|
-
end
|
26
|
+
spacer_template: '/effective/datatables/spacer_template',
|
27
|
+
) || '').split('EFFECTIVEDATATABLESSPACER')
|
49
28
|
end
|
50
29
|
end
|
51
30
|
|
52
31
|
collection.each_with_index do |row, row_index|
|
53
32
|
columns.each do |name, opts|
|
33
|
+
next unless state[:visible][name]
|
34
|
+
|
54
35
|
index = opts[:index]
|
55
36
|
value = row[index]
|
56
37
|
|
57
38
|
row[index] = (
|
58
|
-
if
|
59
|
-
NONVISIBLE
|
60
|
-
elsif opts[:as] == :actions
|
61
|
-
rendered[name][row_index]
|
62
|
-
elsif opts[:format] && rendered.key?(name)
|
39
|
+
if opts[:format] && rendered.key?(name)
|
63
40
|
dsl_tool.instance_exec(value, row, rendered[name][row_index], &opts[:format])
|
64
41
|
elsif opts[:format]
|
65
42
|
dsl_tool.instance_exec(value, row, &opts[:format])
|
@@ -81,22 +58,23 @@ module Effective
|
|
81
58
|
end
|
82
59
|
|
83
60
|
case column[:as]
|
84
|
-
when :actions
|
85
|
-
raise("please use actions_col instead of col(#{name}, as: :actions)")
|
86
61
|
when :boolean
|
87
|
-
|
62
|
+
case value
|
63
|
+
when true ; 'Yes'
|
64
|
+
when false ; 'No'
|
65
|
+
end
|
88
66
|
when :currency
|
89
67
|
view.number_to_currency(value)
|
90
68
|
when :date
|
91
|
-
|
69
|
+
(value.strftime('%F') rescue BLANK)
|
92
70
|
when :datetime
|
93
|
-
|
71
|
+
(value.strftime('%F %H:%M') rescue BLANK)
|
94
72
|
when :decimal
|
95
73
|
value
|
96
74
|
when :duration
|
97
75
|
view.number_to_duration(value)
|
98
76
|
when :effective_addresses
|
99
|
-
|
77
|
+
value.to_html
|
100
78
|
when :effective_obfuscation
|
101
79
|
value
|
102
80
|
when :effective_roles
|
@@ -105,10 +83,10 @@ module Effective
|
|
105
83
|
view.mail_to(value)
|
106
84
|
when :integer
|
107
85
|
value
|
108
|
-
when :
|
86
|
+
when :percentage
|
109
87
|
case value
|
110
|
-
when Integer ;
|
111
|
-
when Numeric ; view.number_to_percentage(value, precision:
|
88
|
+
when Integer ; "#{value}%"
|
89
|
+
when Numeric ; view.number_to_percentage(value * 100, precision: 2)
|
112
90
|
end
|
113
91
|
when :price
|
114
92
|
case value
|
@@ -116,74 +94,51 @@ module Effective
|
|
116
94
|
when Numeric ; view.number_to_currency(value)
|
117
95
|
end
|
118
96
|
when :time
|
119
|
-
|
97
|
+
(value.strftime('%H:%M') rescue BLANK)
|
120
98
|
else
|
121
99
|
value.to_s
|
122
100
|
end
|
123
101
|
end
|
124
102
|
|
125
|
-
|
126
|
-
|
127
|
-
# Merges in any extra attributes when passed as a Hash
|
128
|
-
def actions_col_actions(column)
|
129
|
-
resource_actions = (effective_resource.try(:resource_actions) || fallback_effective_resource.fallback_resource_actions)
|
130
|
-
|
131
|
-
actions = if column[:inline]
|
132
|
-
resource_actions.transform_values { |opts| opts['data-remote'] = true; opts }
|
133
|
-
else
|
134
|
-
resource_actions.transform_values { |opts| opts['data-remote'] = true if opts['data-method']; opts }
|
135
|
-
end
|
136
|
-
|
137
|
-
# Merge local options. Special behaviour for remote: false
|
138
|
-
if column[:actions].kind_of?(Hash)
|
139
|
-
column[:actions].each do |action, opts|
|
140
|
-
next unless opts.kind_of?(Hash)
|
141
|
-
|
142
|
-
existing = actions.find { |_, v| v[:action] == action }.try(:first)
|
143
|
-
next unless existing.present?
|
103
|
+
def actions_col_locals(opts)
|
104
|
+
return {} unless opts[:as] == :actions
|
144
105
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
(
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
106
|
+
locals = {
|
107
|
+
show_action: (
|
108
|
+
active_record_collection? && opts[:show] && resource.routes[:show] &&
|
109
|
+
EffectiveDatatables.authorized?(view.controller, :show, collection_class)
|
110
|
+
),
|
111
|
+
edit_action: (
|
112
|
+
active_record_collection? && opts[:edit] && resource.routes[:edit] &&
|
113
|
+
EffectiveDatatables.authorized?(view.controller, :edit, collection_class)
|
114
|
+
),
|
115
|
+
destroy_action: (
|
116
|
+
active_record_collection? && opts[:destroy] && resource.routes[:destroy] &&
|
117
|
+
EffectiveDatatables.authorized?(view.controller, :destroy, collection_class)
|
118
|
+
),
|
119
|
+
effective_resource: resource
|
120
|
+
}
|
158
121
|
end
|
159
122
|
|
160
123
|
def resource_col_locals(opts)
|
161
|
-
return {} unless (
|
162
|
-
|
163
|
-
associated = associated_resource.macros.include?(opts[:as])
|
164
|
-
polymorphic = (opts[:as] == :belongs_to_polymorphic)
|
165
|
-
|
166
|
-
resource_name = opts[:name] if associated
|
167
|
-
resource_to_s = opts[:name] unless associated || array_collection?
|
124
|
+
return {} unless (resource = opts[:resource]).present?
|
168
125
|
|
169
|
-
locals = {
|
170
|
-
resource_name: resource_name,
|
171
|
-
resource_to_s: resource_to_s,
|
172
|
-
effective_resource: associated_resource,
|
173
|
-
show_action: false,
|
174
|
-
edit_action: false
|
175
|
-
}
|
126
|
+
locals = { name: opts[:name], effective_resource: resource, show_action: false, edit_action: false }
|
176
127
|
|
177
128
|
case opts[:action]
|
178
129
|
when :edit
|
179
|
-
locals[:edit_action] = (
|
130
|
+
locals[:edit_action] = (resource.routes[:edit] && EffectiveDatatables.authorized?(view.controller, :edit, resource.klass))
|
180
131
|
when :show
|
181
|
-
locals[:show_action] = (
|
132
|
+
locals[:show_action] = (resource.routes[:show] && EffectiveDatatables.authorized?(view.controller, :show, resource.klass))
|
182
133
|
when false
|
183
|
-
# Nothing
|
134
|
+
# Nothing
|
184
135
|
else
|
185
|
-
|
186
|
-
|
136
|
+
# Fallback to defaults - check edit then show
|
137
|
+
if resource.routes[:edit] && EffectiveDatatables.authorized?(view.controller, :edit, resource.klass)
|
138
|
+
locals[:edit_action] = true
|
139
|
+
elsif resource.routes[:show] && EffectiveDatatables.authorized?(view.controller, :show, resource.klass)
|
140
|
+
locals[:show_action] = true
|
141
|
+
end
|
187
142
|
end
|
188
143
|
|
189
144
|
locals
|
@@ -7,13 +7,8 @@ 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 =
|
11
|
-
|
12
|
-
|
13
|
-
def datatables_inline_request?
|
14
|
-
return @_datatables_inline_request unless @_datatables_inline_request.nil?
|
15
|
-
|
16
|
-
@_datatables_inline_request = (view.present? && view.params[:_datatable_id].to_s.split('-')[0...-1] == to_param.split('-')[0...-1])
|
10
|
+
@_datatables_ajax_request =
|
11
|
+
(view && view.params[:draw] && view.params[:columns] && cookie_keys.include?(view.params[:cookie])) == true
|
17
12
|
end
|
18
13
|
|
19
14
|
def params
|
@@ -34,7 +29,7 @@ module Effective
|
|
34
29
|
|
35
30
|
def search_params
|
36
31
|
params.select do |name, value|
|
37
|
-
columns.key?(name) &&
|
32
|
+
columns.key?(name) && (name != :id) && !value.kind_of?(Hash) && value.class.name != 'ActionController::Parameters'.freeze
|
38
33
|
end
|
39
34
|
end
|
40
35
|
end
|