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
@@ -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) if @_collection_apply_scope
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
- if array_collection?
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
- array_collection? ? obj[opts[:index]] : obj
66
+ active_record_collection? ? obj : obj[opts[:index]]
74
67
  elsif opts[:resource]
75
- resource = array_collection? ? obj[opts[:index]] : obj
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 [:percent].include?(column[:as])
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 > EffectiveDatatables.cookie_max_size.to_i
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
- # Generate cookie
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
- payload.values # Just store the values
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(title, url, opts = {})
7
- datatable._bulk_actions.push(link_to_bulk_action(title, url, opts))
6
+ def bulk_action(*args)
7
+ datatable._bulk_actions.push(link_to_bulk_action(*args))
8
8
  end
9
9
 
10
- def bulk_download(title, url, opts = {})
11
- datatable._bulk_actions.push(link_to_bulk_action(title, url, opts.merge('data-bulk-download': true)))
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(title, url, opts = {})
26
-
27
- # Transform data: { ... } hash into 'data-' keys
28
- if (data = opts.delete(:data))
29
- data.each { |k, v| opts["data-#{k}"] ||= v }
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
- verbs = {'DELETE' => 'DELETE', 'GET' => 'GET'}
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
- content_tag(:li, link_to(title, url, opts))
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 reorder(name, dir = nil)
19
- raise 'order direction must be :asc or :desc' unless [nil, :asc, :desc].include?(dir)
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 actions_col(btn_class: nil, col_class: nil, inline: nil, partial: nil, partial_as: nil, actions_partial: nil, responsive: 5000, visible: true, **actions, &format)
86
- raise 'You can only have one actions column' if datatable.columns[:_actions].present?
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
- # Called automatically after reorder
151
- # Call again if you want to change the position of the reorder_col
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[:_reorder] = Effective::DatatableColumn.new(
103
+ datatable._columns[:_actions] = Effective::DatatableColumn.new(
156
104
  action: false,
157
- as: :reorder,
105
+ as: :actions,
158
106
  compute: nil,
159
107
  col_class: col_class,
160
- format: nil,
108
+ format: (format if block_given?),
161
109
  index: nil,
162
110
  label: false,
163
- name: :reorder,
164
- partial: partial || '/effective/datatables/reorder_column',
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: true,
170
- sql_column: (sql_column || name),
116
+ sort: false,
117
+ sql_column: nil,
171
118
  th: nil,
172
119
  th_append: nil,
173
- visible: false
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. the default value for this filter.' if value == :_no_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 != nil
20
+ elsif value.present?
21
21
  Effective::Attribute.new(value).type
22
22
  end
23
- ) || :text
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
- }.compact.reverse_merge(input_html)
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); dsl_tool.bulk_actions_col }
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(apply_belongs_to: true, apply_scope: true, &block)
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
- next unless state[:visible][name]
17
-
18
- if opts[:partial]
19
- locals = { datatable: self, column: opts }.merge(resource_col_locals(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))
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: SPACER_TEMPLATE
28
- ) || '').split(SPACER)
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 state[:visible][name] == false
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
- view.t("effective_datatables.boolean_#{value}")
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
- value.respond_to?(:strftime) ? value.strftime(EffectiveDatatables.format_date) : BLANK
69
+ (value.strftime('%F') rescue BLANK)
92
70
  when :datetime
93
- value.respond_to?(:strftime) ? value.strftime(EffectiveDatatables.format_datetime) : BLANK
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
- (value.respond_to?(:to_html) ? value.to_html : value).to_s
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 :percent
86
+ when :percentage
109
87
  case value
110
- when Integer ; view.number_to_percentage(value / 1000.0, precision: 3).gsub('.000%', '%')
111
- when Numeric ; view.number_to_percentage(value, precision: 3).gsub('.000%', '%')
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
- value.respond_to?(:strftime) ? value.strftime(EffectiveDatatables.format_time) : BLANK
97
+ (value.strftime('%H:%M') rescue BLANK)
120
98
  else
121
99
  value.to_s
122
100
  end
123
101
  end
124
102
 
125
- # Takes all default resource actions
126
- # Applies data-remote to anything that's data-method post or delete
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
- actions[existing]['data-remote'] = opts[:remote] if opts.key?(:remote)
146
- actions[existing]['data-remote'] = opts['remote'] if opts.key?('remote')
147
-
148
- actions[existing].merge!(opts.except(:remote, 'remote'))
149
- end
150
-
151
- actions = actions.sort do |(_, a), (_, b)|
152
- (column[:actions].keys.index(a[:action]) || 99) <=> (column[:actions].keys.index(b[:action]) || 99)
153
- end.to_h
154
-
155
- end
156
-
157
- actions
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 (associated_resource = opts[:resource]).present?
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] = (polymorphic || associated_resource.routes[:edit].present?)
130
+ locals[:edit_action] = (resource.routes[:edit] && EffectiveDatatables.authorized?(view.controller, :edit, resource.klass))
180
131
  when :show
181
- locals[:show_action] = (polymorphic || associated_resource.routes[:show].present?)
132
+ locals[:show_action] = (resource.routes[:show] && EffectiveDatatables.authorized?(view.controller, :show, resource.klass))
182
133
  when false
183
- # Nothing. Already false.
134
+ # Nothing
184
135
  else
185
- locals[:edit_action] = (polymorphic || associated_resource.routes[:edit].present?)
186
- locals[:show_action] = (polymorphic || associated_resource.routes[:show].present?)
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 = (view.present? && view.params.key?(:draw) && view.params.key?(:columns))
11
- end
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) && ![:id, :action].include?(name) && !value.kind_of?(Hash) && value.class.name != 'ActionController::Parameters'.freeze
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