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.
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