effective_datatables 4.3.6 → 4.3.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0cdb353b5057246c492c440966e1de63df4b70b7
4
- data.tar.gz: 98cacf4aadcf11b4e831b00afabff3177a3e8559
3
+ metadata.gz: 4642aa5881ff3eb183f287db8c42b61c5ec18a3d
4
+ data.tar.gz: ac20c253b356faf06abba201e3f705b81d64e5e4
5
5
  SHA512:
6
- metadata.gz: 3ae86ea4a56ef6818ba3d450edd70e0ee86206a36ce99adee3947ce5951fb63c1e353c11d80077cd1beb4b15b0900e8d97fb477a720bce9114fbbda443da84d7
7
- data.tar.gz: d948ae33fc177a660554876724ffd9ae94d5b418428c3b9cef2bbe22465661740e5c490b12a29670851b0757fcc54aed54fef9722b1cf7f899f8cddb5b8e0915
6
+ metadata.gz: 309b3348a5507dd365dd6349b472301c29ca39ffd1cf77e516d031ed7a4c0c7a52b6fffe3cece2e59525acd1e412956cb26f645d13994287a2c898f7416fd573
7
+ data.tar.gz: 4b79372f60d9a26baeae025a63a84f2318d600adacc73b48525a463f21a6cc7b44bb7f066fdf53b6da7c11e36ee4ea8899a9458fcc407b966465a454d474d585
data/README.md CHANGED
@@ -454,7 +454,7 @@ These settings are loosely based on the regular datatypes, with some custom effe
454
454
  - `:currency` expects the underlying datatype to be a Float.
455
455
  - `:duration` expects the underlying datatype to be an Integer representing the number of minutes. 120 == 2 hours
456
456
  - `:email` expects the underlying datatype to be a String
457
- - `:percentage` expects the underlying datatype to be an Integer or a Float. 75 == 0.75 == 75%
457
+ - `:percent` expects the underlying datatype to be an Integer * 1000. 50000 == 50%. 50125 == 50.125%.
458
458
  - `:price` expects the underlying datatype to be an Integer representing the number of cents. 5000 == $50.00
459
459
  - `:resource` can be used for an Array based collection which includes an ActiveRecord object
460
460
 
@@ -3,7 +3,6 @@ initializeDataTables = ->
3
3
  datatable = $(this)
4
4
  options = datatable.data('options') || {}
5
5
  buttons_export_columns = options['buttons_export_columns'] || ':not(.col-actions)'
6
- simple = ('' + datatable.data('simple') == 'true')
7
6
  reorder = datatable.data('reorder')
8
7
 
9
8
  if options['buttons'] == false
@@ -49,7 +48,6 @@ initializeDataTables = ->
49
48
  deferLoading: [datatable.data('display-records'), datatable.data('total-records')]
50
49
  deferRender: true
51
50
  displayStart: datatable.data('display-start')
52
- dom: "<'row'<'col-sm-12 dataTables_buttons'B>><'row'<'col-sm-12'tr>><'row'<'col-sm-6 dataTables_entries'il><'col-sm-6'p>>"
53
51
  iDisplayLength: datatable.data('display-length')
54
52
  language: { 'lengthMenu': '&nbsp;with _MENU_ per page'}
55
53
  lengthMenu: [[5, 10, 25, 50, 100, 250, 500, 9999999], ['5', '10', '25', '50', '100', '250', '500', 'All']]
@@ -161,10 +159,6 @@ initializeDataTables = ->
161
159
  table = $input.closest('table.dataTable')
162
160
  table.DataTable().column("#{$input.data('column-name')}:name").search($input.val()).draw()
163
161
 
164
- if simple
165
- init_options['dom'] = "<'row'<'col-sm-12'tr>>" # Just show the table
166
- datatable.addClass('simple')
167
-
168
162
  if reorder
169
163
  init_options['rowReorder'] = { selector: 'td.col-_reorder', snapX: true, dataSrc: datatable.data('reorder-index') }
170
164
 
@@ -36,7 +36,7 @@ $(document).on 'ajax:success', '.dataTables_wrapper .col-actions', (event) ->
36
36
  true
37
37
 
38
38
  # The inline form has been submitted successfully
39
- $(document).on '.dataTables_wrapper .col-inline-form effective-form:success', (event, flash) ->
39
+ $(document).on 'effective-form:success', '.dataTables_wrapper .col-inline-form', (event, flash) ->
40
40
  $action = $(event.target)
41
41
 
42
42
  $tr = $action.closest('tr')
@@ -120,7 +120,7 @@ afterAction = ($action) ->
120
120
  buildRow = (length, payload) ->
121
121
  "<td class='col-inline-form' colspan='#{length-1}'><div class='container'>#{payload}</div></td>" +
122
122
  "<td class='col-actions col-actions-inline-form'>" +
123
- "<a href='#' class='btn btn-outline-primary' title='Cancel' data-role='inline-form-cancel'>Cancel</a>" +
123
+ "<a href='#' class='btn btn-sm btn-outline-primary' title='Cancel' data-role='inline-form-cancel'>Cancel</a>" +
124
124
  "</td>"
125
125
 
126
126
  expand = ($table) ->
@@ -139,12 +139,17 @@ div.dataTables_wrapper div.dataTables_processing {
139
139
  }
140
140
 
141
141
  // Simple styles
142
- table.dataTable.simple > thead {
142
+ table.dataTable.hide-sort > thead {
143
143
  .sorting { background-image: none; cursor: default; }
144
144
  .sorting_asc { background-image: none; cursor: default; }
145
145
  .sorting_desc { background-image: none; cursor: default; }
146
+ }
146
147
 
148
+ table.dataTable.hide-search > thead {
147
149
  .form-group { display: none; }
150
+ }
151
+
152
+ table.dataTable.hide-buttons {
148
153
  .col-bulk_actions { display: none; }
149
154
  }
150
155
 
@@ -1,11 +1,15 @@
1
1
  # These are expected to be called by a developer. They are part of the datatables DSL.
2
2
  module EffectiveDatatablesHelper
3
3
 
4
- def render_datatable(datatable, input_js: {}, buttons: true, charts: true, filters: true, simple: false, inline: false)
4
+ def render_datatable(datatable, input_js: {}, buttons: true, charts: true, entries: true, filters: true, inline: false, pagination: true, search: true, simple: false, sort: true)
5
5
  raise 'expected datatable to be present' unless datatable
6
6
 
7
- datatable.attributes[:simple] = true if simple
7
+ if simple
8
+ buttons = charts = entries = filters = pagination = search = sort = false
9
+ end
10
+
8
11
  datatable.attributes[:inline] = true if inline
12
+ datatable.attributes[:sortable] = false unless sort
9
13
 
10
14
  datatable.view ||= self
11
15
 
@@ -16,11 +20,25 @@ module EffectiveDatatablesHelper
16
20
  charts = charts && datatable._charts.present?
17
21
  filters = filters && (datatable._scopes.present? || datatable._filters.present?)
18
22
 
19
- input_js[:buttons] = false if simple || !buttons
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
20
38
 
21
39
  effective_datatable_params = {
22
40
  id: datatable.to_param,
23
- class: ('effective-datatable ' + Array(datatable.table_html_class).join(' ')),
41
+ class: html_class,
24
42
  data: {
25
43
  'bulk-actions' => datatable_bulk_actions(datatable),
26
44
  'columns' => datatable_columns(datatable),
@@ -29,19 +47,19 @@ module EffectiveDatatablesHelper
29
47
  'display-order' => datatable_display_order(datatable),
30
48
  'display-records' => datatable.to_json[:recordsFiltered],
31
49
  'display-start' => datatable.display_start,
32
- 'inline' => datatable.inline?.to_s,
50
+ 'inline' => inline.to_s,
33
51
  'options' => (input_js || {}).to_json.html_safe,
34
- 'reset' => datatable_reset(datatable),
52
+ 'reset' => (datatable_reset(datatable) if search),
35
53
  'reorder' => datatable_reorder(datatable),
36
54
  'reorder-index' => (datatable.columns[:_reorder][:index] if datatable.reorder?).to_s,
37
- 'simple' => datatable.simple?.to_s,
55
+ 'simple' => simple.to_s,
38
56
  'spinner' => icon('spinner'), # effective_bootstrap
39
57
  'source' => effective_datatables.datatable_path(datatable, {format: 'json'}),
40
58
  'total-records' => datatable.to_json[:recordsTotal]
41
59
  }
42
60
  }
43
61
 
44
- if (charts || filters) && !simple
62
+ if (charts || filters)
45
63
  output = ''.html_safe
46
64
 
47
65
  if charts
@@ -69,23 +87,7 @@ module EffectiveDatatablesHelper
69
87
  end
70
88
 
71
89
  def render_simple_datatable(datatable)
72
- raise 'expected datatable to be present' unless datatable
73
-
74
- datatable.view ||= self
75
-
76
- unless EffectiveDatatables.authorized?(controller, :index, datatable.collection_class)
77
- return content_tag(:p, "You are not authorized to view this datatable. (cannot :index, #{datatable.collection_class})")
78
- end
79
-
80
- effective_datatable_params = {
81
- id: datatable.to_param,
82
- class: ('effective-datatable simple ' + Array(datatable.table_html_class).join(' ')),
83
- data: {}
84
- }
85
-
86
- render(partial: 'effective/datatables/datatable',
87
- locals: { datatable: datatable, effective_datatable_params: effective_datatable_params }
88
- )
90
+ render_datatable(datatable, simple: true)
89
91
  end
90
92
 
91
93
  def inline_datatable?
@@ -40,7 +40,7 @@ module EffectiveDatatablesPrivateHelper
40
40
 
41
41
  def datatable_new_resource_button(datatable, name, column)
42
42
  if column[:inline] && column[:actions][:new] != false
43
- actions = {'New' => { action: :new, class: 'btn btn-outline-primary', 'data-remote': true } }
43
+ actions = {'New' => { action: :new, class: ['btn', column[:btn_class].presence].compact.join(' '), 'data-remote': true } }
44
44
  render_resource_actions(datatable.resource.klass, actions: actions, effective_resource: datatable.resource) # Will only work if permitted
45
45
  end
46
46
  end
@@ -122,24 +122,18 @@ module Effective
122
122
  )
123
123
  end
124
124
 
125
- # When simple only a table will be rendered with
126
- # no sorting, no filtering, no export buttons, no pagination, no per page, no colReorder
127
- # default sorting only, default visibility only, all records returned, and responsive enabled
128
- def simple?
129
- attributes[:simple] == true
130
- end
131
-
132
125
  # Inline crud
133
126
  def inline?
134
127
  attributes[:inline] == true
135
128
  end
136
129
 
130
+ # Reordering
137
131
  def reorder?
138
132
  columns.key?(:_reorder)
139
133
  end
140
134
 
141
135
  def sortable?
142
- !simple? && !reorder?
136
+ !reorder? && attributes[:sortable] != false
143
137
  end
144
138
 
145
139
  # Whether the filters must be rendered as a <form> or we can keep the normal <div> behaviour
@@ -147,8 +141,8 @@ module Effective
147
141
  _form[:verb].present?
148
142
  end
149
143
 
150
- def table_html_class
151
- attributes[:class] || EffectiveDatatables.html_class
144
+ def html_class
145
+ Array(attributes[:class] || EffectiveDatatables.html_class).join(' ').presence
152
146
  end
153
147
 
154
148
  def to_param
@@ -132,7 +132,7 @@ module Effective
132
132
 
133
133
  case aggregate[:name]
134
134
  when :total
135
- if [:percentage].include?(column[:as])
135
+ if [:percent].include?(column[:as])
136
136
  BLANK
137
137
  elsif values.all? { |value| value.kind_of?(Numeric) }
138
138
  values.sum
@@ -82,13 +82,14 @@ module Effective
82
82
  )
83
83
  end
84
84
 
85
- def actions_col(col_class: nil, inline: nil, partial: nil, partial_as: nil, actions_partial: nil, responsive: 5000, visible: true, **actions, &format)
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
86
  raise 'You can only have one actions column' if datatable.columns[:_actions].present?
87
87
 
88
88
  datatable._columns[:_actions] = Effective::DatatableColumn.new(
89
89
  action: false,
90
90
  as: :actions,
91
91
  compute: nil,
92
+ btn_class: (btn_class || 'btn-sm btn-outline-primary'),
92
93
  col_class: col_class,
93
94
  format: (format if block_given?),
94
95
  index: nil,
@@ -29,7 +29,7 @@ module Effective
29
29
  elsif opts[:as] == :actions # This is actions_col and actions_col do .. end, but not actions_col partial: 'something'
30
30
  resources = collection.map { |row| row[opts[:index]] }
31
31
  locals = { datatable: self, column: opts, spacer_template: SPACER_TEMPLATE }
32
- atts = { actions: actions_col_actions(opts), effective_resource: resource, locals: locals, partial: opts[:actions_partial] }.merge(opts[:actions])
32
+ atts = { actions: actions_col_actions(opts), effective_resource: resource, locals: locals, partial: opts[:actions_partial], btn_class: opts[:btn_class] }.merge(opts[:actions])
33
33
 
34
34
  rendered[name] = (view.render_resource_actions(resources, atts, &opts[:format]) || '').split(SPACER)
35
35
  end
@@ -97,10 +97,10 @@ module Effective
97
97
  view.mail_to(value)
98
98
  when :integer
99
99
  value
100
- when :percentage
100
+ when :percent
101
101
  case value
102
- when Integer ; "#{value}%"
103
- when Numeric ; view.number_to_percentage(value * 100, precision: 2)
102
+ when Integer ; view.number_to_percentage(value / 1000.0, precision: 3).gsub('.000%', '%')
103
+ when Numeric ; view.number_to_percentage(value, precision: 3).gsub('.000%', '%')
104
104
  end
105
105
  when :price
106
106
  case value
@@ -127,22 +127,20 @@ module Effective
127
127
  def resource_col_locals(opts)
128
128
  return {} unless (resource = opts[:resource]).present?
129
129
 
130
+ polymorphic = (opts[:as] == :belongs_to_polymorphic)
131
+
130
132
  locals = { name: opts[:name], effective_resource: resource, show_action: false, edit_action: false }
131
133
 
132
134
  case opts[:action]
133
135
  when :edit
134
- locals[:edit_action] = (resource.routes[:edit] && EffectiveDatatables.authorized?(view.controller, :edit, resource.klass))
136
+ locals[:edit_action] = (resource.routes[:edit].present? || polymorphic)
135
137
  when :show
136
- locals[:show_action] = (resource.routes[:show] && EffectiveDatatables.authorized?(view.controller, :show, resource.klass))
138
+ locals[:show_action] = (resource.routes[:show].present? || polymorphic)
137
139
  when false
138
- # Nothing
140
+ # Nothing. Already false.
139
141
  else
140
- # Fallback to defaults - check edit then show
141
- if resource.routes[:edit] && EffectiveDatatables.authorized?(view.controller, :edit, resource.klass)
142
- locals[:edit_action] = true
143
- elsif resource.routes[:show] && EffectiveDatatables.authorized?(view.controller, :show, resource.klass)
144
- locals[:show_action] = true
145
- end
142
+ locals[:edit_action] = (resource.routes[:edit].present? || polymorphic)
143
+ locals[:show_action] = (resource.routes[:show].present? || polymorphic)
146
144
  end
147
145
 
148
146
  locals
@@ -140,7 +140,7 @@ module Effective
140
140
 
141
141
  search[:value] ||= search.delete(:selected) if search.key?(:selected)
142
142
 
143
- search[:as] ||= :select if (search.key?(:collection) && opts[:as] != :belongs_to_polymorphic)
143
+ search[:as] ||= :select if search.key?(:collection)
144
144
 
145
145
  search[:fuzzy] = true unless search.key?(:fuzzy)
146
146
 
@@ -149,6 +149,11 @@ module Effective
149
149
  elsif search[:as] != :string
150
150
  search.reverse_merge!(resource.search_form_field(name, opts[:as]))
151
151
  end
152
+
153
+ # Assign default include_null
154
+ if search[:as] == :select && !search.key?(:include_null)
155
+ search[:include_null] = true
156
+ end
152
157
  end
153
158
  end
154
159
 
@@ -160,10 +165,19 @@ module Effective
160
165
  next unless attribute.ends_with?('_id')
161
166
 
162
167
  associated = attribute.gsub(/_id\z/, '').to_sym # Replace last _id
163
- next unless columns[associated] && columns[associated][:as] == :belongs_to
164
168
 
165
- @_collection = @_collection.where(attribute => value)
166
- columns.delete(associated)
169
+ next unless columns[associated]
170
+
171
+ if columns[associated][:as] == :belongs_to
172
+ @_collection = @_collection.where(attribute => value)
173
+ columns.delete(associated)
174
+ elsif columns[associated][:as] == :belongs_to_polymorphic
175
+ associated_type = attributes["#{associated}_type".to_sym] || raise("Expected #{associated}_type attribute to be present when #{associated}_id is present on a polymorphic belongs to")
176
+
177
+ @_collection = @_collection.where(attribute => value).where("#{associated}_type" => associated_type)
178
+ columns.delete(associated)
179
+ end
180
+
167
181
  end.present?
168
182
 
169
183
  load_columns! if changed
@@ -1,8 +1,8 @@
1
1
  - Array(datatable.array_collection? ? resource : resource.send(name)).each do |resource|
2
2
  .col-resource_item
3
- - if show_action
4
- = link_to resource.to_s, effective_resource.action_path(:show, resource), title: resource.to_s
5
- - elsif edit_action
3
+ - if edit_action && EffectiveDatatables.authorized?(controller, :edit, resource)
6
4
  = link_to resource.to_s, effective_resource.action_path(:edit, resource), title: resource.to_s
5
+ - elsif show_action && EffectiveDatatables.authorized?(controller, :show, resource)
6
+ = link_to resource.to_s, effective_resource.action_path(:show, resource), title: resource.to_s
7
7
  - else
8
8
  = resource.to_s.html_safe
@@ -1,3 +1,3 @@
1
1
  module EffectiveDatatables
2
- VERSION = '4.3.6'.freeze
2
+ VERSION = '4.3.7'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_datatables
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.6
4
+ version: 4.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-29 00:00:00.000000000 Z
11
+ date: 2018-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails