effective_datatables 3.7.10 → 4.0.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.
Files changed (69) hide show
  1. checksums.yaml +5 -5
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +32 -32
  4. data/app/assets/images/dataTables/sort-down.svg +1 -0
  5. data/app/assets/images/dataTables/sort-up.svg +1 -0
  6. data/app/assets/images/dataTables/sort.svg +1 -0
  7. data/app/assets/javascripts/dataTables/buttons/{buttons.bootstrap.js → buttons.bootstrap4.js} +7 -15
  8. data/app/assets/javascripts/dataTables/dataTables.bootstrap4.js +184 -0
  9. data/app/assets/javascripts/dataTables/responsive/dataTables.responsive.js +30 -11
  10. data/app/assets/javascripts/dataTables/responsive/{responsive.bootstrap.js → responsive.bootstrap4.js} +6 -6
  11. data/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee +43 -43
  12. data/app/assets/javascripts/effective_datatables/events.js.coffee +7 -4
  13. data/app/assets/javascripts/effective_datatables/filters.js.coffee +0 -1
  14. data/app/assets/javascripts/effective_datatables/initialize.js.coffee +45 -49
  15. data/app/assets/javascripts/effective_datatables/overrides.js +12 -0
  16. data/app/assets/javascripts/effective_datatables/reset.js.coffee +1 -1
  17. data/app/assets/javascripts/effective_datatables.js +4 -4
  18. data/app/assets/stylesheets/dataTables/buttons/{buttons.bootstrap.scss → buttons.bootstrap4.css} +68 -1
  19. data/app/assets/stylesheets/dataTables/{dataTables.bootstrap.scss → dataTables.bootstrap4.css} +44 -29
  20. data/app/assets/stylesheets/dataTables/responsive/{responsive.bootstrap.scss → responsive.bootstrap4.css} +3 -3
  21. data/app/assets/stylesheets/effective_datatables/_overrides.scss +72 -152
  22. data/app/assets/stylesheets/effective_datatables.scss +3 -4
  23. data/app/controllers/effective/datatables_controller.rb +6 -39
  24. data/app/helpers/effective_datatables_helper.rb +55 -50
  25. data/app/helpers/effective_datatables_private_helper.rb +47 -179
  26. data/app/models/effective/datatable.rb +16 -44
  27. data/app/models/effective/datatable_column.rb +0 -1
  28. data/app/models/effective/datatable_column_tool.rb +2 -4
  29. data/app/models/effective/datatable_dsl_tool.rb +3 -11
  30. data/app/models/effective/datatable_value_tool.rb +23 -23
  31. data/app/models/effective/effective_datatable/attributes.rb +13 -5
  32. data/app/models/effective/effective_datatable/collection.rb +3 -18
  33. data/app/models/effective/effective_datatable/compute.rb +6 -17
  34. data/app/models/effective/effective_datatable/cookie.rb +20 -19
  35. data/app/models/effective/effective_datatable/dsl/bulk_actions.rb +25 -14
  36. data/app/models/effective/effective_datatable/dsl/datatable.rb +28 -70
  37. data/app/models/effective/effective_datatable/dsl/filters.rb +5 -5
  38. data/app/models/effective/effective_datatable/dsl.rb +3 -8
  39. data/app/models/effective/effective_datatable/format.rb +50 -95
  40. data/app/models/effective/effective_datatable/params.rb +3 -8
  41. data/app/models/effective/effective_datatable/resource.rb +76 -137
  42. data/app/models/effective/effective_datatable/state.rb +15 -30
  43. data/app/views/effective/datatables/_actions_column.html.haml +8 -1
  44. data/app/views/effective/datatables/_bulk_actions_column.html.haml +1 -1
  45. data/app/views/effective/datatables/_filters.html.haml +11 -12
  46. data/app/views/effective/datatables/_resource_column.html.haml +8 -11
  47. data/config/effective_datatables.rb +14 -12
  48. data/config/routes.rb +0 -1
  49. data/lib/effective_datatables/engine.rb +4 -14
  50. data/lib/effective_datatables/version.rb +1 -1
  51. data/lib/effective_datatables.rb +4 -57
  52. metadata +20 -31
  53. data/app/assets/config/effective_datatables_manifest.js +0 -3
  54. data/app/assets/images/dataTables/sort_asc.png +0 -0
  55. data/app/assets/images/dataTables/sort_both.png +0 -0
  56. data/app/assets/images/dataTables/sort_desc.png +0 -0
  57. data/app/assets/javascripts/dataTables/dataTables.bootstrap.js +0 -182
  58. data/app/assets/javascripts/dataTables/locales/en.lang +0 -33
  59. data/app/assets/javascripts/dataTables/locales/es.lang +0 -36
  60. data/app/assets/javascripts/dataTables/locales/nl.lang +0 -30
  61. data/app/assets/javascripts/effective_datatables/flash.js.coffee +0 -31
  62. data/app/assets/javascripts/effective_datatables/inline_crud.js.coffee +0 -217
  63. data/app/assets/javascripts/effective_datatables/overrides.js.coffee +0 -7
  64. data/app/assets/javascripts/effective_datatables/reorder.js.coffee +0 -43
  65. data/app/assets/stylesheets/effective_datatables/_filters.scss +0 -7
  66. data/app/views/effective/datatables/_reorder_column.html.haml +0 -5
  67. data/config/locales/en.yml +0 -12
  68. data/config/locales/es.yml +0 -12
  69. data/config/locales/nl.yml +0 -12
@@ -1,73 +1,91 @@
1
- // Use asset-data-url to prevent 3 additional GET requests for icons
2
- table.dataTable thead .sorting {
3
- background-image: asset-data-url('dataTables/sort_both.png');
4
- background-position: right 0px bottom 14px;
1
+ // Override dataTables.bootstrap4.css defaults
2
+ table.dataTable { border-collapse: collapse !important; }
3
+
4
+ // Override default padding
5
+ table.dataTable thead > tr > th.sorting_asc, table.dataTable thead > tr > th.sorting_desc, table.dataTable thead > tr > th.sorting,
6
+ table.dataTable thead > tr > td.sorting_asc,
7
+ table.dataTable thead > tr > td.sorting_desc,
8
+ table.dataTable thead > tr > td.sorting { padding: 0.5em 0.5em 0.5em 0.5em; }
9
+
10
+ // Override default sort icons
11
+ table.dataTable thead .sorting:before,
12
+ table.dataTable thead .sorting_asc:before,
13
+ table.dataTable thead .sorting_desc:before,
14
+ table.dataTable thead .sorting_asc_disabled:before,
15
+ table.dataTable thead .sorting_desc_disabled:before,
16
+ table.dataTable thead .sorting:after,
17
+ table.dataTable thead .sorting_asc:after,
18
+ table.dataTable thead .sorting_desc:after,
19
+ table.dataTable thead .sorting_asc_disabled:after,
20
+ table.dataTable thead .sorting_desc_disabled:after { content: ''; }
21
+
22
+ table.dataTable > thead th {
23
+ vertical-align: top;
24
+ background-repeat: no-repeat;
25
+
26
+ > span { padding-right: 1rem; }
5
27
  }
6
28
 
7
- table.dataTable thead .sorting_asc {
8
- background-image: asset-data-url('dataTables/sort_asc.png');
9
- background-position: right 0px bottom 14px;
29
+ table.dataTable > thead .sorting {
30
+ background-image: asset-data-url('dataTables/sort.svg');
31
+ background-position: right 0.25rem top 0.25rem;
10
32
  }
11
33
 
12
- table.dataTable thead .sorting_desc {
13
- background-image: asset-data-url('dataTables/sort_desc.png');
14
- background-position: right 0px bottom 14px;
34
+ table.dataTable > thead .sorting_asc {
35
+ background-image: asset-data-url('dataTables/sort-up.svg');
36
+ background-position: right 0.25rem top 0.25rem;
15
37
  }
16
38
 
17
- // Override bootstrap default glyphicons
18
- table.dataTable thead .sorting:after { content: ''; }
19
- table.dataTable thead .sorting_asc:after { content: ''; }
20
- table.dataTable thead .sorting_desc:after { content: ''; }
39
+ table.dataTable > thead .sorting_desc {
40
+ background-image: asset-data-url('dataTables/sort-down.svg');
41
+ background-position: right 0.25rem top 0.25rem;
42
+ }
21
43
 
22
- // Table header
23
- table.dataTable thead > tr > th.sorting_asc,
24
- table.dataTable thead > tr > th.sorting_desc,
25
- table.dataTable thead > tr > th.sorting {
26
- background-repeat: no-repeat;
27
- padding-right: 18px;
44
+ // Collapsed Responsive View
45
+ table.dataTable > tbody > tr.child {
46
+ td, th { border: none; }
47
+
48
+ ul.dtr-details > li {
49
+ border-bottom: none;
50
+ padding-left: 0.5em;
51
+
52
+ &:hover { background-color: rgba(0, 0, 0, 0.075); }
53
+
54
+ span.dtr-title { min-width: 175px; margin-bottom: 0.25em; }
55
+ span.dtr-data { white-space: nowrap; }
56
+ .col-resource_item { margin-bottom: 0.25em; }
57
+ }
58
+ }
59
+
60
+ // Buttons
61
+ .dataTables_buttons {
62
+ text-align: right;
63
+ .btn { font-size: 0.75rem; }
28
64
  }
29
65
 
30
66
  // Search bar
31
- table.dataTable thead {
67
+ table.dataTable > thead {
32
68
  tr th {
33
- text-align: left;
34
- vertical-align: top;
35
69
  border-bottom: none;
36
70
  white-space: nowrap;
37
- padding: 6px;
38
71
 
39
- span { display: block; }
40
- }
72
+ .form-group {
73
+ font-weight: normal;
74
+ margin-bottom: 0em;
41
75
 
42
- .form-control, .form-group {
43
- width: 100%;
44
- font-weight: normal;
45
- margin: 0px;
76
+ input { max-height: 38px; }
77
+ }
46
78
  }
47
-
48
- .datatable_search__bulk_actions { margin-left: 5px; }
49
79
  }
50
80
 
51
81
  // Simple styles
52
- table.dataTable.simple {
53
- thead {
54
- .sorting { background-image: none; cursor: default; }
55
- .sorting_asc { background-image: none; cursor: default; }
56
- .sorting_desc { background-image: none; cursor: default; }
57
-
58
- .form-group { display: none; }
59
- .col-bulk_actions { display: none; }
60
- }
61
- }
82
+ table.dataTable.simple > thead {
83
+ .sorting { background-image: none; cursor: default; }
84
+ .sorting_asc { background-image: none; cursor: default; }
85
+ .sorting_desc { background-image: none; cursor: default; }
62
86
 
63
- // Processing popup
64
- div.dataTables_wrapper div.dataTables_processing {
65
- top: -10px;
66
- border: none;
67
- box-shadow: none;
68
- margin-left: -35%;
69
- margin-bottom: 0;
70
- width: 70%;
87
+ .form-group { display: none; }
88
+ .col-bulk_actions { display: none; }
71
89
  }
72
90
 
73
91
  // Datatables entries
@@ -82,7 +100,7 @@ div.dataTables_wrapper div.dataTables_processing {
82
100
  // Showing 1 to 2 of 2 entries (filtered from 10 total entries)
83
101
  div.dataTables_info {
84
102
  display: inline-block;
85
- padding: 5px 0px 6px 6px;
103
+ padding: 0.25em 0em 0.25em 0.25em;
86
104
  }
87
105
 
88
106
  // with 25 per page
@@ -95,7 +113,7 @@ div.dataTables_wrapper div.dataTables_processing {
95
113
  max-width: 45px;
96
114
 
97
115
  .select2-selection { border: none; }
98
- .select2-selection__rendered { padding: 0px; color: #909090; }
116
+ .select2-selection__rendered { padding: 0em; color: #909090; }
99
117
  }
100
118
 
101
119
  span.select2-container.select2-container--open { max-width: 60px; }
@@ -104,80 +122,8 @@ div.dataTables_wrapper div.dataTables_processing {
104
122
  }
105
123
  }
106
124
 
107
- // Buttons
108
- div.dt-buttons {
109
- float: right;
110
- display: inherit;
111
- width: auto;
112
- }
113
-
114
- .dt-buttons {
115
- a, button {
116
- border: none;
117
- color: #337ab7;
118
- border-color: transparent;
119
- background: #fff;
120
- font-size: 12px;
121
- padding: 6px;
122
- margin-right: 6px;
123
- float: none;
124
-
125
- &:hover,
126
- &:focus {
127
- border: none;
128
- border-color: transparent;
129
- background: #eee !important;
130
- }
131
-
132
- &:last-child { margin-right: 0px; }
133
-
134
- &.active {
135
- color: #fff;
136
- background: #03428d !important;
137
- }
138
-
139
- .caret {
140
- margin-bottom: 4px;
141
- }
142
- }
143
- }
144
-
145
- // Show / hide columns button
146
- ul.dt-button-collection {
147
- width: 400px;
148
-
149
- li {
150
- width: 198px;
151
- overflow: hidden;
152
- }
153
-
154
- li:nth-child(odd) {
155
- float: left;
156
- }
157
-
158
- li:nth-child(even) {
159
- float: right;
160
- }
161
-
162
- .buttons-colvisGroup {
163
- clear: left;
164
- border-top: 1px solid grey;
165
- }
166
-
167
- .buttons-colvisRestore {
168
- border-top: 1px solid grey;
169
- }
170
- }
171
-
172
- // Collapsed Responsive View
173
- table.dataTable > tbody > tr.child {
174
- span.dtr-title { min-width: 175px; margin-bottom: 4px; }
175
- span.dtr-data { white-space: nowrap; }
176
- .col-resource_item { margin-bottom: 4px; }
177
- }
178
-
179
125
  // Column specific adjustments
180
- table.dataTable {
126
+ table.dataTable > tbody {
181
127
  td.col-price { text-align: right; }
182
128
  td.col-decimal { text-align: right; }
183
129
  td.col-right { text-align: right; }
@@ -193,32 +139,6 @@ table.dataTable {
193
139
  td.col-resource_item { word-break: keep-all; }
194
140
 
195
141
  td {
196
- p { margin-bottom: 0px; }
142
+ p { margin-bottom: 0em; }
197
143
  }
198
144
  }
199
-
200
- // Simple styles
201
- table.dataTable.hide-sort > thead {
202
- .sorting { background-image: none; cursor: default; }
203
- .sorting_asc { background-image: none; cursor: default; }
204
- .sorting_desc { background-image: none; cursor: default; }
205
- }
206
-
207
- table.dataTable.hide-search > thead {
208
- .form-group { display: none; }
209
- }
210
-
211
- table.dataTable.hide-buttons {
212
- .col-bulk_actions { display: none; }
213
- }
214
-
215
- // Datatables entries
216
- @media screen and (max-width: 767px) {
217
- div.dataTables_wrapper div.dataTables_entries { text-align: center; }
218
- }
219
-
220
- .dataTables_buttons {
221
- .buttons-bulk-actions {
222
- button { font-size: 12px; }
223
- }
224
- }
@@ -1,7 +1,6 @@
1
- @import 'dataTables/dataTables.bootstrap';
1
+ @import 'dataTables/dataTables.bootstrap4';
2
2
 
3
- @import 'dataTables/buttons/buttons.bootstrap';
4
- @import 'dataTables/responsive/responsive.bootstrap';
3
+ @import 'dataTables/buttons/buttons.bootstrap4';
4
+ @import 'dataTables/responsive/responsive.bootstrap4';
5
5
 
6
- @import 'effective_datatables/filters';
7
6
  @import 'effective_datatables/overrides';
@@ -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], params[:attributes])
8
+ @datatable = find_datatable(params[:id]).try(:new) || raise('unable to find datatable')
9
9
  @datatable.view = view_context
10
10
 
11
11
  EffectiveDatatables.authorize!(self, :index, @datatable.collection_class)
@@ -13,51 +13,18 @@ module Effective
13
13
  render json: @datatable.to_json
14
14
  rescue => e
15
15
  EffectiveDatatables.authorized?(self, :index, @datatable.try(:collection_class))
16
- render json: error_json(e)
17
16
 
18
- ExceptionNotifier.notify_exception(e) if defined?(ExceptionNotifier)
19
- raise e if Rails.env.development?
17
+ render json: error_json(e)
20
18
  end
21
19
  end
22
20
 
23
- def reorder
24
- begin
25
- @datatable = EffectiveDatatables.find(params[:id], params[:attributes])
26
- @datatable.view = view_context
27
-
28
- EffectiveDatatables.authorize!(self, :index, @datatable.collection_class)
29
-
30
- @resource = @datatable.collection.find(params[:reorder][:id])
31
-
32
- EffectiveDatatables.authorize!(self, :update, @resource)
33
-
34
- attribute = @datatable.columns[:_reorder][:reorder]
35
- old_index = params[:reorder][:old].to_i
36
- new_index = params[:reorder][:new].to_i
37
-
38
- @resource.class.transaction do
39
- if new_index > old_index
40
- @datatable.collection.where("#{attribute} > ? AND #{attribute} <= ?", old_index, new_index).update_all("#{attribute} = #{attribute} - 1")
41
- @resource.update_column(attribute, new_index)
42
- end
43
-
44
- if old_index > new_index
45
- @datatable.collection.where("#{attribute} >= ? AND #{attribute} < ?", new_index, old_index).update_all("#{attribute} = #{attribute} + 1")
46
- @resource.update_column(attribute, new_index)
47
- end
48
- end
49
-
50
- render status: :ok, body: :ok
51
- rescue Effective::AccessDenied => e
52
- render(status: :unauthorized, body: 'Access Denied')
53
- rescue => e
54
- render(status: :error, body: 'Unexpected Error')
55
- end
21
+ private
56
22
 
23
+ def find_datatable(id)
24
+ id = id.to_s.gsub(/-\d{12}\z/, '').gsub('-', '/')
25
+ id.classify.safe_constantize || id.classify.pluralize.safe_constantize
57
26
  end
58
27
 
59
- private
60
-
61
28
  def error_json(e)
62
29
  {
63
30
  data: [],
@@ -1,15 +1,8 @@
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)
4
- raise 'expected datatable to be present' unless datatable
5
- raise 'expected input_js to be a Hash' unless input_js.kind_of?(Hash)
6
-
7
- if simple
8
- buttons = charts = entries = filters = pagination = search = sort = false
9
- end
10
3
 
11
- datatable.attributes[:inline] = true if inline
12
- datatable.attributes[:sortable] = false unless sort
4
+ def render_datatable(datatable, input_js: {}, buttons: true, charts: true, filters: true, simple: false)
5
+ raise 'expected datatable to be present' unless datatable
13
6
 
14
7
  datatable.view ||= self
15
8
 
@@ -20,48 +13,29 @@ module EffectiveDatatablesHelper
20
13
  charts = charts && datatable._charts.present?
21
14
  filters = filters && (datatable._scopes.present? || datatable._filters.present?)
22
15
 
23
- html_class = ['effective-datatable', datatable.html_class, ('hide-sort' unless sort), ('hide-search' unless search), ('hide-buttons' unless buttons)].compact.join(' ')
24
-
25
- if datatable.reorder? && !buttons
26
- buttons = true; input_js[:buttons] = false
27
- end
28
-
29
- # Build the datatables DOM option
30
- input_js[:dom] ||= [
31
- ("<'row'<'col-sm-12 dataTables_buttons'B>>" if buttons),
32
- "<'row'<'col-sm-12'tr>>",
33
- ("<'row'" if entries || pagination),
34
- ("<'col-sm-6 dataTables_entries'il>" if entries),
35
- ("<'col-sm-6'p>" if pagination),
36
- (">" if entries || pagination)
37
- ].compact.join
16
+ datatable.attributes[:simple] = true if simple
17
+ input_js[:buttons] = false if simple || !buttons
38
18
 
39
19
  effective_datatable_params = {
40
20
  id: datatable.to_param,
41
- class: html_class,
21
+ class: ('effective-datatable ' + Array(datatable.table_html_class).join(' ')),
42
22
  data: {
43
- 'attributes' => EffectiveDatatables.encrypt(datatable.attributes),
44
- 'authenticity-token' => form_authenticity_token,
45
23
  'bulk-actions' => datatable_bulk_actions(datatable),
46
24
  'columns' => datatable_columns(datatable),
25
+ 'cookie' => datatable.cookie_key,
47
26
  'display-length' => datatable.display_length,
48
- 'display-order' => datatable_display_order(datatable),
27
+ 'display-order' => [datatable.order_index, datatable.order_direction].to_json().html_safe,
49
28
  'display-records' => datatable.to_json[:recordsFiltered],
50
29
  'display-start' => datatable.display_start,
51
- 'inline' => inline.to_s,
52
- 'language' => EffectiveDatatables.language(I18n.locale),
53
- 'options' => input_js.to_json,
54
- 'reset' => (datatable_reset(datatable) if search),
55
- 'reorder' => datatable_reorder(datatable),
56
- 'reorder-index' => (datatable.columns[:_reorder][:index] if datatable.reorder?).to_s,
57
- 'simple' => simple.to_s,
58
- 'spinner' => '', # effective_bootstrap
30
+ 'options' => (input_js || {}).to_json.html_safe,
31
+ 'reset' => datatable_reset(datatable),
32
+ 'simple' => datatable.simple?.to_s,
59
33
  'source' => effective_datatables.datatable_path(datatable, {format: 'json'}),
60
34
  'total-records' => datatable.to_json[:recordsTotal]
61
35
  }
62
36
  }
63
37
 
64
- if (charts || filters)
38
+ if (charts || filters) && !simple
65
39
  output = ''.html_safe
66
40
 
67
41
  if charts
@@ -84,28 +58,59 @@ module EffectiveDatatablesHelper
84
58
  end
85
59
  end
86
60
 
87
- def render_inline_datatable(datatable)
88
- render_datatable(datatable, inline: true)
61
+ def render_simple_datatable(datatable)
62
+ raise 'expected datatable to be present' unless datatable
63
+
64
+ datatable.view ||= self
65
+
66
+ unless EffectiveDatatables.authorized?(controller, :index, datatable.collection_class)
67
+ return content_tag(:p, "You are not authorized to view this datatable. (cannot :index, #{datatable.collection_class})")
68
+ end
69
+
70
+ effective_datatable_params = {
71
+ id: datatable.to_param,
72
+ class: ('effective-datatable simple ' + Array(datatable.table_html_class).join(' ')),
73
+ data: {}
74
+ }
75
+
76
+ render(partial: 'effective/datatables/datatable',
77
+ locals: { datatable: datatable, effective_datatable_params: effective_datatable_params }
78
+ )
89
79
  end
90
80
 
91
- def render_simple_datatable(datatable)
92
- render_datatable(datatable, simple: true)
81
+ def render_datatable_filters(datatable)
82
+ raise 'expected datatable to be present' unless datatable
83
+
84
+ datatable.view ||= self
85
+ return unless datatable._scopes.present? || datatable._filters.present?
86
+
87
+ if datatable._filters_form_required?
88
+ render partial: 'effective/datatables/filters', locals: { datatable: datatable }
89
+ else
90
+ render(partial: 'effective/datatables/filters', locals: { datatable: datatable }).gsub('<form', '<div').gsub('/form>', '/div>').html_safe
91
+ end
92
+
93
93
  end
94
94
 
95
- def inline_datatable?
96
- params[:_datatable_id].present? && params[:_datatable_attributes].present?
95
+ def render_datatable_charts(datatable)
96
+ raise 'expected datatable to be present' unless datatable
97
+
98
+ datatable.view ||= self
99
+ return unless datatable._charts.present?
100
+
101
+ datatable._charts.map { |name, _| render_datatable_chart(datatable, name) }.join.html_safe
97
102
  end
98
103
 
99
- def inline_datatable
100
- return nil unless inline_datatable?
101
- return @_inline_datatable if @_inline_datatable
104
+ def render_datatable_chart(datatable, name)
105
+ raise 'expected datatable to be present' unless datatable
102
106
 
103
- datatable = EffectiveDatatables.find(params[:_datatable_id], params[:_datatable_attributes])
104
- datatable.view = self
107
+ datatable.view ||= self
108
+ return unless datatable._charts[name].present?
105
109
 
106
- EffectiveDatatables.authorize!(self, :index, datatable.collection_class)
110
+ chart = datatable._charts[name]
111
+ chart_data = datatable.to_json[:charts][name][:data]
107
112
 
108
- @_inline_datatable ||= datatable
113
+ render partial: chart[:partial], locals: { datatable: datatable, chart: chart, chart_data: chart_data }
109
114
  end
110
115
 
111
116
  end