effective_datatables 2.12.2 → 3.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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +632 -512
  3. data/app/assets/javascripts/dataTables/buttons/buttons.html5.js +176 -177
  4. data/app/assets/javascripts/dataTables/buttons/buttons.print.js +2 -0
  5. data/app/assets/javascripts/dataTables/buttons/dataTables.buttons.js +14 -14
  6. data/app/assets/javascripts/dataTables/dataTables.bootstrap.js +1 -1
  7. data/app/assets/javascripts/dataTables/jquery.dataTables.js +246 -217
  8. data/app/assets/javascripts/effective_datatables.js +2 -3
  9. data/app/assets/javascripts/effective_datatables/events.js.coffee +7 -0
  10. data/app/assets/javascripts/effective_datatables/filters.js.coffee +6 -0
  11. data/app/assets/javascripts/effective_datatables/initialize.js.coffee +42 -39
  12. data/app/assets/javascripts/effective_datatables/reset.js.coffee +7 -0
  13. data/app/assets/javascripts/vendor/jquery.delayedChange.js +1 -1
  14. data/app/assets/stylesheets/dataTables/dataTables.bootstrap.css +0 -1
  15. data/app/assets/stylesheets/effective_datatables.scss +1 -2
  16. data/app/assets/stylesheets/effective_datatables/{_scopes.scss → _filters.scss} +1 -1
  17. data/app/assets/stylesheets/effective_datatables/_overrides.scss +1 -1
  18. data/app/controllers/effective/datatables_controller.rb +2 -4
  19. data/app/helpers/effective_datatables_helper.rb +56 -91
  20. data/app/helpers/effective_datatables_private_helper.rb +55 -64
  21. data/app/models/effective/datatable.rb +103 -177
  22. data/app/models/effective/datatable_column.rb +28 -0
  23. data/app/models/effective/datatable_column_tool.rb +110 -0
  24. data/app/models/effective/datatable_dsl_tool.rb +28 -0
  25. data/app/models/effective/datatable_value_tool.rb +142 -0
  26. data/app/models/effective/effective_datatable/attributes.rb +25 -0
  27. data/app/models/effective/effective_datatable/collection.rb +38 -0
  28. data/app/models/effective/effective_datatable/compute.rb +154 -0
  29. data/app/models/effective/effective_datatable/cookie.rb +29 -0
  30. data/app/models/effective/effective_datatable/dsl.rb +14 -8
  31. data/app/models/effective/effective_datatable/dsl/bulk_actions.rb +5 -6
  32. data/app/models/effective/effective_datatable/dsl/charts.rb +7 -9
  33. data/app/models/effective/effective_datatable/dsl/datatable.rb +107 -57
  34. data/app/models/effective/effective_datatable/dsl/filters.rb +50 -0
  35. data/app/models/effective/effective_datatable/format.rb +157 -0
  36. data/app/models/effective/effective_datatable/hooks.rb +0 -18
  37. data/app/models/effective/effective_datatable/params.rb +34 -0
  38. data/app/models/effective/effective_datatable/resource.rb +108 -0
  39. data/app/models/effective/effective_datatable/state.rb +178 -0
  40. data/app/views/effective/datatables/_actions_column.html.haml +9 -42
  41. data/app/views/effective/datatables/_bulk_actions_column.html.haml +1 -1
  42. data/app/views/effective/datatables/_bulk_actions_dropdown.html.haml +2 -3
  43. data/app/views/effective/datatables/_chart.html.haml +1 -1
  44. data/app/views/effective/datatables/_datatable.html.haml +7 -25
  45. data/app/views/effective/datatables/_filters.html.haml +21 -0
  46. data/app/views/effective/datatables/_reset.html.haml +2 -0
  47. data/app/views/effective/datatables/_resource_column.html.haml +8 -0
  48. data/app/views/effective/datatables/index.html.haml +0 -1
  49. data/config/effective_datatables.rb +9 -32
  50. data/lib/effective_datatables.rb +2 -6
  51. data/lib/effective_datatables/engine.rb +1 -1
  52. data/lib/effective_datatables/version.rb +1 -1
  53. data/lib/generators/effective_datatables/install_generator.rb +2 -2
  54. metadata +39 -19
  55. data/app/assets/javascripts/dataTables/colreorder/dataTables.colReorder.js +0 -27
  56. data/app/assets/javascripts/dataTables/jszip/jszip.js +0 -9155
  57. data/app/assets/javascripts/effective_datatables/scopes.js.coffee +0 -9
  58. data/app/models/effective/active_record_datatable_tool.rb +0 -242
  59. data/app/models/effective/array_datatable_tool.rb +0 -97
  60. data/app/models/effective/effective_datatable/ajax.rb +0 -101
  61. data/app/models/effective/effective_datatable/charts.rb +0 -20
  62. data/app/models/effective/effective_datatable/dsl/scopes.rb +0 -23
  63. data/app/models/effective/effective_datatable/helpers.rb +0 -24
  64. data/app/models/effective/effective_datatable/options.rb +0 -309
  65. data/app/models/effective/effective_datatable/rendering.rb +0 -365
  66. data/app/views/effective/datatables/_scopes.html.haml +0 -21
@@ -0,0 +1,29 @@
1
+ module Effective
2
+ module EffectiveDatatable
3
+ module Cookie
4
+
5
+ def cookie_name
6
+ @cookie_name ||= "datatable-#{URI(datatables_ajax_request? ? view.request.referer : view.request.url).path}-#{to_param}".parameterize
7
+ end
8
+
9
+ private
10
+
11
+ def load_cookie!
12
+ @cookie ||= (
13
+ cookie = view.cookies.signed[cookie_name]
14
+
15
+ if cookie.present?
16
+ data = Marshal.load(Base64.decode64(cookie))
17
+ raise 'invalid cookie' unless [data, data[:attributes], data[:state]].all? { |obj| obj.kind_of?(Hash) }
18
+ data
19
+ end
20
+ )
21
+ end
22
+
23
+ def save_cookie!
24
+ view.cookies.signed[cookie_name] = Base64.encode64(Marshal.dump(attributes: attributes, state: state))
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -1,19 +1,25 @@
1
- # These are Class level methods.
2
-
3
1
  module Effective
4
2
  module EffectiveDatatable
5
3
  module Dsl
6
4
 
7
- def datatable(&block)
8
- define_method('initialize_datatable') { instance_exec(&block) }
5
+ def bulk_actions(&block)
6
+ define_method('initialize_bulk_actions') { dsl_tool.instance_exec(&block) }
9
7
  end
10
8
 
11
- def scopes(&block)
12
- define_method('initialize_scopes') { instance_exec(&block) }
9
+ def charts(&block)
10
+ define_method('initialize_charts') { dsl_tool.instance_exec(&block) }
13
11
  end
14
12
 
15
- def charts(&block)
16
- define_method('initialize_charts') { instance_exec(&block) }
13
+ def collection(&block)
14
+ define_method('initialize_collection') { self._collection = dsl_tool.instance_exec(&block) }
15
+ end
16
+
17
+ def datatable(&block)
18
+ define_method('initialize_datatable') { dsl_tool.instance_exec(&block) }
19
+ end
20
+
21
+ def filters(&block)
22
+ define_method('initialize_filters') { dsl_tool.instance_exec(&block) }
17
23
  end
18
24
 
19
25
  end
@@ -2,22 +2,21 @@ module Effective
2
2
  module EffectiveDatatable
3
3
  module Dsl
4
4
  module BulkActions
5
- # These get added into the view as helpers
6
- # To be called inside datatable { bulk_actions_column do .. end }
5
+
7
6
  def bulk_action(*args)
8
- concat content_tag(:li, link_to(*args))
7
+ datatable._bulk_actions.push(content_tag(:li, link_to(*args)))
9
8
  end
10
9
 
11
10
  def bulk_download(*args)
12
- concat content_tag(:li, link_to(*args), 'data-authenticity-token' => form_authenticity_token)
11
+ datatable._bulk_actions.push(content_tag(:li, link_to(*args), 'data-authenticity-token' => form_authenticity_token))
13
12
  end
14
13
 
15
14
  def bulk_action_divider
16
- concat content_tag(:li, '', class: 'divider', role: 'separator')
15
+ datatable._bulk_actions.push(content_tag(:li, '', class: 'divider', role: 'separator'))
17
16
  end
18
17
 
19
18
  def bulk_action_content(&block)
20
- concat block.call
19
+ datatable._bulk_actions.push(block.call)
21
20
  end
22
21
 
23
22
  end
@@ -3,17 +3,15 @@ module Effective
3
3
  module Dsl
4
4
  module Charts
5
5
  # Instance Methods inside the charts do .. end block
6
- def chart(name, type, options = {}, &block)
6
+ def chart(name, as = 'BarChart', label: nil, legend: true, partial: nil, **options, &compute)
7
+ raise 'expected a block returning an Array of Arrays' unless block_given?
7
8
 
8
- options[:title] ||= (options[:label] || name.to_s.titleize)
9
- options[:legend] = 'none' if options[:legend] == false
10
-
11
- (@charts ||= HashWithIndifferentAccess.new)[name] = {
9
+ datatable._charts[name.to_sym] = {
10
+ as: as,
11
+ compute: compute,
12
12
  name: name,
13
- type: type,
14
- partial: options.delete(:partial),
15
- options: options,
16
- block: (block if block_given?)
13
+ options: { label: (label || name.to_s.titleize), legend: (legend || 'none') }.merge(options),
14
+ partial: partial || '/effective/datatables/chart'
17
15
  }
18
16
  end
19
17
  end
@@ -3,80 +3,130 @@ module Effective
3
3
  module Dsl
4
4
  module Datatable
5
5
  # Instance Methods inside the datatable do .. end block
6
- def default_order(name, direction = :asc)
7
- @default_order = {name => direction}
8
- end
6
+ def order(name, dir = nil)
7
+ raise 'order direction must be :asc or :desc' unless [nil, :asc, :desc].include?(dir)
9
8
 
10
- def default_entries(entries)
11
- @default_entries = entries
9
+ datatable.state[:order_name] ||= name
10
+ datatable.state[:order_dir] ||= dir
12
11
  end
13
12
 
14
- def table_column(name, options = {}, proc = nil, &block)
15
- if block_given?
16
- raise "You cannot use partial: ... with the block syntax" if options[:partial] && !options[:type] == :actions
17
- raise "You cannot use proc: ... with the block syntax" if options[:proc]
18
- options[:block] = block
19
- end
20
- raise "You cannot use both partial: ... and proc: ..." if options[:partial] && options[:proc]
21
-
22
- (@table_columns ||= HashWithIndifferentAccess.new)[name] = options
13
+ def length(length)
14
+ raise 'length must be 10, 25, 50, 100, 250, 1000, :all' unless [10, 25, 50, 100, 250, 1000, :all].include?(length)
15
+ datatable.state[:length] ||= (length == :all ? 9999999 : length)
23
16
  end
24
17
 
25
- def array_column(name, options = {}, proc = nil, &block)
26
- table_column(name, options.merge!(array_column: true), proc, &block)
27
- end
18
+ # A col has its internal values sorted/searched before the block is run
19
+ # Anything done in the block, is purely a format on the after sorted/ordered value
20
+ # the original object == the computed value, which is yielded to the format block
21
+ # You can't do compute with .col
22
+ def col(name, action: nil, as: nil, col_class: nil, label: nil, partial: nil, partial_as: nil, responsive: 10000, search: {}, sort: true, sql_column: nil, th: nil, th_append: nil, visible: true, &format)
23
+ raise 'You cannot use partial: ... with the block syntax' if partial && block_given?
28
24
 
29
- def actions_column(options = {}, proc = nil, &block)
30
- raise 'first parameter to actions_column should be a hash' unless options.kind_of?(Hash)
25
+ datatable._columns[name.to_sym] = Effective::DatatableColumn.new(
26
+ action: action, # resource columns only
27
+ as: as,
28
+ compute: nil,
29
+ col_class: col_class,
30
+ format: (format if block_given?),
31
+ index: datatable.columns.length,
32
+ label: label || name.to_s.titleize,
33
+ name: name.to_sym,
34
+ partial: partial,
35
+ partial_as: partial_as,
36
+ responsive: responsive,
37
+ search: search,
38
+ sort: sort,
39
+ sql_column: sql_column,
40
+ th: th,
41
+ th_append: th_append,
42
+ visible: visible,
43
+ )
44
+ end
31
45
 
32
- show = options.fetch(:show, (EffectiveDatatables.actions_column[:show] rescue false))
33
- edit = options.fetch(:edit, (EffectiveDatatables.actions_column[:edit] rescue false))
34
- destroy = options.fetch(:destroy, (EffectiveDatatables.actions_column[:destroy] rescue false))
35
- unarchive = options.fetch(:unarchive, (EffectiveDatatables.actions_column[:unarchive] rescue false))
36
- name = options.fetch(:name, 'actions')
46
+ # A val is a computed value that is then sorted/searched after the block is run
47
+ # You can have another block by calling .format afterwards to work on the computed value itself
48
+ def val(name, action: nil, as: nil, col_class: nil, label: nil, partial: nil, partial_as: nil, responsive: 10000, search: {}, sort: true, sql_column: nil, th: nil, th_append: nil, visible: true, &compute)
49
+ raise 'You cannot use partial: ... with the block syntax' if partial && block_given?
37
50
 
38
- opts = {
39
- type: :actions,
40
- sortable: false,
41
- filter: false,
42
- responsivePriority: 0,
43
- partial_locals: { show_action: show, edit_action: edit, destroy_action: destroy, unarchive_action: unarchive },
44
- actions_block: block
45
- }.merge(options)
51
+ datatable._columns[name.to_sym] = Effective::DatatableColumn.new(
52
+ action: action, # Resource columns only
53
+ as: as,
54
+ compute: (compute if block_given?),
55
+ col_class: col_class,
56
+ format: nil,
57
+ index: datatable.columns.length,
58
+ label: label || name.to_s.titleize,
59
+ name: name.to_sym,
60
+ partial: partial,
61
+ partial_as: partial_as,
62
+ responsive: responsive,
63
+ search: search,
64
+ sort: sort,
65
+ sql_column: (block_given? ? false : sql_column),
66
+ th: th,
67
+ th_append: th_append,
68
+ visible: visible,
69
+ )
70
+ end
46
71
 
47
- opts[:partial_local] ||= :resource unless opts[:partial].present?
48
- opts[:partial] ||= '/effective/datatables/actions_column' unless proc.present?
72
+ def bulk_actions_col(col_class: nil, partial: nil, partial_as: nil, responsive: 5000)
73
+ raise 'You can only have one bulk actions column' if datatable.columns[:_bulk_actions].present?
49
74
 
50
- table_column(name, opts, proc)
75
+ datatable._columns[:_bulk_actions] = Effective::DatatableColumn.new(
76
+ action: false,
77
+ as: :bulk_actions,
78
+ compute: nil,
79
+ col_class: col_class,
80
+ format: nil,
81
+ index: datatable.columns.length,
82
+ label: '',
83
+ name: :bulk_actions,
84
+ partial: partial || '/effective/datatables/bulk_actions_column',
85
+ partial_as: partial_as,
86
+ responsive: responsive,
87
+ search: { as: :bulk_actions },
88
+ sort: false,
89
+ sql_column: nil,
90
+ th: nil,
91
+ th_append: nil,
92
+ visible: true,
93
+ )
51
94
  end
52
95
 
53
- def bulk_actions_column(options = {}, proc = nil, &block)
54
- raise 'first parameter to bulk_actions_column should be a hash' unless options.kind_of?(Hash)
96
+ def actions_col(show: true, edit: true, destroy: true, col_class: nil, partial: nil, partial_as: nil, responsive: 5000, visible: true, &format)
97
+ raise 'You can only have one actions column' if datatable.columns[:_actions].present?
55
98
 
56
- name = options.fetch(:name, 'bulk_actions')
57
- resource_method = options.fetch(:resource_method, :to_param)
58
-
59
- opts = {
60
- bulk_actions_column: true,
99
+ datatable._columns[:_actions] = Effective::DatatableColumn.new(
100
+ action: false,
101
+ as: :actions,
102
+ compute: nil,
103
+ col_class: col_class,
104
+ format: (format if block_given?),
105
+ index: datatable.columns.length,
61
106
  label: '',
62
- partial_local: :resource,
63
- partial: '/effective/datatables/bulk_actions_column',
64
- partial_locals: { resource_method: resource_method },
65
- sortable: false,
66
- dropdown_partial: '/effective/datatables/bulk_actions_dropdown',
67
- dropdown_block: block
68
- }.merge(options)
107
+ name: :actions,
108
+ partial: partial || '/effective/datatables/actions_column',
109
+ partial_as: partial_as,
110
+ responsive: responsive,
111
+ search: false,
112
+ sort: false,
113
+ sql_column: nil,
114
+ th: nil,
115
+ th_append: nil,
116
+ visible: visible,
69
117
 
70
- table_column(name, opts, proc)
118
+ show: show,
119
+ edit: edit,
120
+ destroy: destroy
121
+ )
71
122
  end
72
123
 
73
- def aggregate(name, options = {}, &block)
74
- if block_given?
75
- raise "You cannot use proc: ... with the block syntax" if options[:proc]
76
- options[:block] = block
77
- end
78
-
79
- (@aggregates ||= HashWithIndifferentAccess.new)[name] = options
124
+ def aggregate(name, label: nil, &compute)
125
+ datatable._aggregates[name.to_sym] = {
126
+ compute: (compute if block_given?),
127
+ label: label || name.to_s.titleize,
128
+ name: name.to_sym,
129
+ }
80
130
  end
81
131
  end
82
132
  end
@@ -0,0 +1,50 @@
1
+ module Effective
2
+ module EffectiveDatatable
3
+ module Dsl
4
+ module Filters
5
+ def filter(name = nil, value = :_no_value, as: nil, label: nil, parse: nil, required: false, **input_html)
6
+ return datatable.filter if (name == nil && value == :_no_value) # This lets block methods call 'filter' and get the values
7
+
8
+ raise 'expected second argument to be a value' if value == :_no_value
9
+ raise 'parse must be a Proc' if parse.present? && !parse.kind_of?(Proc)
10
+
11
+ datatable._filters[name.to_sym] = {
12
+ value: value,
13
+ as: as,
14
+ label: label || name.to_s.titleize,
15
+ name: name.to_sym,
16
+ parse: parse,
17
+ required: required,
18
+ input_html: input_html
19
+ }
20
+ end
21
+
22
+ def scope(name = nil, *args, default: nil, label: nil)
23
+ return datatable.scope unless name # This lets block methods call 'scope' and get the values
24
+
25
+ datatable._scopes[name.to_sym] = {
26
+ default: default,
27
+ label: label || name.to_s.titleize,
28
+ name: name.to_sym,
29
+ args: args.presence
30
+ }
31
+ end
32
+
33
+ # This changes the filters from using an AJAX, to a POST or GET
34
+ def form(url: nil, verb: nil)
35
+ url ||= request.path
36
+ verb ||= (Rails.application.routes.recognize_path(url, method: :post).present? rescue false) ? :post : :get
37
+
38
+ datatable._form[:url] = url
39
+ datatable._form[:verb] = verb
40
+ end
41
+
42
+ def changes_columns_count
43
+ form()
44
+ end
45
+ alias_method :changes_column_count, :changes_columns_count
46
+
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,157 @@
1
+ module Effective
2
+ module EffectiveDatatable
3
+ module Format
4
+ BLANK = ''.freeze
5
+
6
+ private
7
+
8
+ def format(collection)
9
+ # We want to use the render :collection for each column that renders partials
10
+ rendered = {}
11
+
12
+ columns.each do |name, opts|
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))
19
+
20
+ rendered[name] = (view.render(
21
+ partial: opts[:partial],
22
+ as: (opts[:partial_as] || :resource),
23
+ collection: collection.map { |row| row[opts[:index]] },
24
+ formats: :html,
25
+ locals: locals,
26
+ spacer_template: '/effective/datatables/spacer_template',
27
+ ) || '').split('EFFECTIVEDATATABLESSPACER')
28
+ end
29
+ end
30
+
31
+ collection.each_with_index do |row, row_index|
32
+ columns.each do |name, opts|
33
+ next unless state[:visible][name]
34
+
35
+ index = opts[:index]
36
+ value = row[index]
37
+
38
+ row[index] = (
39
+ if opts[:format] && opts[:as] == :actions
40
+ result = dsl_tool.instance_exec(value, row, &opts[:format])
41
+ "#{rendered[name][row_index]}#{result}"
42
+ elsif opts[:format]
43
+ dsl_tool.instance_exec(value, row, &opts[:format])
44
+ elsif opts[:partial]
45
+ rendered[name][row_index]
46
+ else
47
+ format_column(value, opts)
48
+ end
49
+ )
50
+ end
51
+ end
52
+ end
53
+
54
+ def format_column(value, column)
55
+ case column[:as]
56
+ when :boolean
57
+ case value
58
+ when true ; 'Yes'
59
+ when false ; 'No'
60
+ when String ; value
61
+ end
62
+ when :currency
63
+ view.number_to_currency(value) if value.present?
64
+ when :date
65
+ (value.strftime('%F') rescue BLANK) if value.present?
66
+ when :datetime
67
+ (value.strftime('%F %H:%M') rescue BLANK) if value.present?
68
+ when :decimal
69
+ value
70
+ when :duration
71
+ view.number_to_duration(value) if value.present?
72
+ when :effective_addresses
73
+ value.to_html if value.present?
74
+ when :effective_obfuscation
75
+ value
76
+ when :effective_roles
77
+ value.join(', ')
78
+ when :email
79
+ view.mail_to(value) if value.present?
80
+ when :integer
81
+ value
82
+ when :percentage
83
+ case value
84
+ when Integer ; "#{value}%"
85
+ when Numeric ; view.number_to_percentage(value * 100, precision: 2)
86
+ when String ; value
87
+ end
88
+ when :price
89
+ raise 'column type: price expects an Integer representing the number of cents' unless value.kind_of?(Integer)
90
+ view.number_to_currency(value / 100.0) if value.present?
91
+ else
92
+ value.to_s
93
+ end
94
+ end
95
+
96
+ def actions_col_locals(opts)
97
+ return {} unless opts[:as] == :actions
98
+ return { show_path: false, edit_path: false, destroy_path: false } unless active_record_collection?
99
+
100
+ locals = {}
101
+
102
+ locals[:show_action] = opts[:show]
103
+ locals[:edit_action] = opts[:edit]
104
+ locals[:destroy_action] = opts[:destroy]
105
+
106
+ if locals[:show_action] && (EffectiveDatatables.authorized?(view.controller, :show, collection_class) rescue false)
107
+ locals[:show_path] = resource.show_path(check: true)
108
+ else
109
+ locals[:show_path] = false
110
+ end
111
+
112
+ if locals[:edit_action] && (EffectiveDatatables.authorized?(view.controller, :edit, collection_class) rescue false)
113
+ locals[:edit_path] = resource.edit_path(check: true)
114
+ else
115
+ locals[:edit_path] = false
116
+ end
117
+
118
+ if locals[:destroy_action] && (EffectiveDatatables.authorized?(view.controller, :destroy, collection_class) rescue false)
119
+ locals[:destroy_path] = resource.destroy_path(check: true)
120
+ else
121
+ locals[:destroy_path] = false
122
+ end
123
+
124
+ locals
125
+ end
126
+
127
+ def resource_col_locals(opts)
128
+ return {} unless (resource = opts[:resource]).present?
129
+
130
+ locals = { name: opts[:name], macro: opts[:as], show_path: false, edit_path: false }
131
+
132
+ case opts[:action]
133
+ when :edit
134
+ if (EffectiveDatatables.authorized?(view.controller, :edit, resource.klass) rescue false)
135
+ locals[:edit_path] = resource.edit_path(check: true)
136
+ end
137
+ when :show
138
+ if (EffectiveDatatables.authorized?(view.controller, :show, resource.klass) rescue false)
139
+ locals[:show_path] = resource.show_path(check: true)
140
+ end
141
+ when false
142
+ # Nothing
143
+ else
144
+ # Fallback to defaults - check edit then show
145
+ if (EffectiveDatatables.authorized?(view.controller, :edit, resource.klass) rescue false)
146
+ locals[:edit_path] = resource.edit_path(check: true)
147
+ elsif (EffectiveDatatables.authorized?(view.controller, :show, resource.klass) rescue false)
148
+ locals[:show_path] = resource.show(check: true)
149
+ end
150
+ end
151
+
152
+ locals
153
+ end
154
+
155
+ end # / Rendering
156
+ end
157
+ end