effective_datatables 3.6.3 → 3.7.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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/app/assets/javascripts/dataTables/locales/en.lang +33 -0
  4. data/app/assets/javascripts/dataTables/locales/es.lang +36 -0
  5. data/app/assets/javascripts/dataTables/locales/nl.lang +30 -0
  6. data/app/assets/javascripts/effective_datatables/filters.js.coffee +1 -0
  7. data/app/assets/javascripts/effective_datatables/flash.js.coffee +31 -0
  8. data/app/assets/javascripts/effective_datatables/initialize.js.coffee +41 -53
  9. data/app/assets/javascripts/effective_datatables/inline_crud.js.coffee +217 -0
  10. data/app/assets/javascripts/effective_datatables/overrides.js.coffee +7 -0
  11. data/app/assets/javascripts/effective_datatables/reorder.js.coffee +43 -0
  12. data/app/assets/javascripts/effective_datatables/reset.js.coffee +1 -1
  13. data/app/assets/stylesheets/effective_datatables/_overrides.scss +28 -0
  14. data/app/controllers/effective/datatables_controller.rb +39 -6
  15. data/app/datatables/effective_style_guide_datatable.rb +47 -0
  16. data/app/helpers/effective_datatables_helper.rb +49 -56
  17. data/app/helpers/effective_datatables_private_helper.rb +137 -11
  18. data/app/models/effective/datatable.rb +36 -16
  19. data/app/models/effective/datatable_column.rb +1 -0
  20. data/app/models/effective/datatable_value_tool.rb +20 -20
  21. data/app/models/effective/effective_datatable/attributes.rb +5 -13
  22. data/app/models/effective/effective_datatable/collection.rb +18 -3
  23. data/app/models/effective/effective_datatable/compute.rb +15 -6
  24. data/app/models/effective/effective_datatable/cookie.rb +19 -18
  25. data/app/models/effective/effective_datatable/dsl.rb +8 -3
  26. data/app/models/effective/effective_datatable/dsl/bulk_actions.rb +16 -23
  27. data/app/models/effective/effective_datatable/dsl/datatable.rb +70 -28
  28. data/app/models/effective/effective_datatable/dsl/filters.rb +12 -4
  29. data/app/models/effective/effective_datatable/format.rb +1 -4
  30. data/app/models/effective/effective_datatable/params.rb +9 -4
  31. data/app/models/effective/effective_datatable/resource.rb +129 -74
  32. data/app/models/effective/effective_datatable/state.rb +30 -15
  33. data/app/views/effective/datatables/_bulk_actions_dropdown.html.haml +3 -5
  34. data/app/views/effective/datatables/_datatable.html.haml +3 -5
  35. data/app/views/effective/datatables/_filters.html.haml +4 -24
  36. data/app/views/effective/datatables/_reorder_column.html.haml +5 -0
  37. data/app/views/effective/style_guide/_effective_datatables.html.haml +1 -0
  38. data/config/effective_datatables.rb +8 -21
  39. data/config/locales/en.yml +12 -0
  40. data/config/locales/es.yml +12 -0
  41. data/config/locales/nl.yml +12 -0
  42. data/config/routes.rb +5 -4
  43. data/lib/effective_datatables.rb +49 -2
  44. data/lib/effective_datatables/engine.rb +4 -2
  45. data/lib/effective_datatables/version.rb +1 -1
  46. metadata +17 -5
  47. data/app/views/effective/datatables/_reset.html.haml +0 -2
@@ -55,7 +55,6 @@ module Effective
55
55
  # This is called first. Our initial state is set.
56
56
  def initial_state
57
57
  {
58
- attributes: {},
59
58
  filter: {},
60
59
  length: nil,
61
60
  order_name: nil,
@@ -89,23 +88,27 @@ module Effective
89
88
 
90
89
  def load_state!
91
90
  if datatables_ajax_request?
91
+ load_cookie! # but not state.
92
92
  load_filter_params!
93
93
  load_ajax_state!
94
- elsif cookie.present? && cookie[:params] == params.length && EffectiveDatatables.save_state
95
- load_cookie_state!
94
+ elsif datatables_inline_request?
95
+ load_filter_params!
96
96
  else
97
- # Nothing to do for default state
97
+ load_cookie!
98
+ load_cookie_state! if cookie.present? && cookie[:params] == cookie_state_params
99
+ load_filter_params!
98
100
  end
99
101
 
100
- load_filter_params! unless datatables_ajax_request?
101
102
  fill_empty_filters!
102
103
  end
103
104
 
104
105
  def load_ajax_state!
105
106
  state[:length] = params[:length].to_i
106
107
 
107
- state[:order_dir] = (params[:order]['0'][:dir] == 'desc' ? :desc : :asc)
108
- state[:order_index] = params[:order]['0'][:column].to_i
108
+ if params[:order]
109
+ state[:order_dir] = (params[:order]['0'][:dir] == 'desc' ? :desc : :asc)
110
+ state[:order_index] = params[:order]['0'][:column].to_i
111
+ end
109
112
 
110
113
  state[:scope] = _scopes.keys.find { |name| params[:scope] == name.to_s }
111
114
  state[:start] = params[:start].to_i
@@ -130,7 +133,7 @@ module Effective
130
133
  state[:filter][name] = parse_filter_value(_filters[name], value)
131
134
  end
132
135
 
133
- state[:params] = cookie[:params]
136
+ state[:params] = cookie[:params] if cookie.present?
134
137
  end
135
138
 
136
139
  def load_cookie_state!
@@ -140,14 +143,21 @@ module Effective
140
143
  def load_columns!
141
144
  state[:length] ||= EffectiveDatatables.default_length
142
145
 
143
- if columns.present?
144
- columns.each_with_index { |(_, column), index| column[:index] = index }
146
+ (columns || {}).each_with_index { |(_, column), index| column[:index] = index }
145
147
 
146
- if order_index.present?
147
- state[:order_name] = columns.keys[order_index]
148
- end
148
+ if columns.present?
149
+ state[:order_name] = (
150
+ if columns.key?(:_reorder)
151
+ :_reorder
152
+ elsif order_index.present?
153
+ columns.keys[order_index]
154
+ elsif state[:order_name].present?
155
+ state[:order_name]
156
+ else
157
+ columns.find { |name, opts| opts[:sort] }.first
158
+ end
159
+ )
149
160
 
150
- state[:order_name] ||= columns.find { |name, opts| opts[:sort] }.first
151
161
  raise "order column :#{order_name} must exist as a col or val" unless columns[order_name]
152
162
 
153
163
  state[:order_index] = columns[order_name][:index]
@@ -176,7 +186,7 @@ module Effective
176
186
 
177
187
  unless datatables_ajax_request?
178
188
  search_params.each { |name, value| state[:search][name] = value }
179
- state[:params] = params.length
189
+ state[:params] = cookie_state_params
180
190
  end
181
191
 
182
192
  state[:visible].delete_if { |name, _| columns.key?(name) == false }
@@ -187,9 +197,14 @@ module Effective
187
197
  # When we parse an incoming filter term for this filter.
188
198
  def parse_filter_value(filter, value)
189
199
  return filter[:parse].call(value) if filter[:parse]
200
+ return nil if value.blank? && !filter[:required]
190
201
  Effective::Attribute.new(filter[:value]).parse(value, name: filter[:name])
191
202
  end
192
203
 
204
+ def cookie_state_params
205
+ params.hash.abs.to_s.last(12)
206
+ end
207
+
193
208
  end
194
209
  end
195
210
  end
@@ -1,10 +1,8 @@
1
1
  .btn-group.buttons-bulk-actions
2
- %button.btn.btn-default.dropdown-toggle{'type' => 'button', 'data-toggle' => 'dropdown', 'aria-haspopup' => true, 'aria-expanded' => false, 'disabled' => 'disabled'}
2
+ %button.btn.btn-link.btn-sm.dropdown-toggle{'type': 'button', 'data-toggle': 'dropdown', 'aria-haspopup': true, 'aria-expanded': false, 'disabled': 'disabled'}
3
3
  Bulk Actions
4
- %span.caret
5
- %ul.dropdown-menu
4
+ .dropdown-menu
6
5
  - if datatable._bulk_actions.present?
7
6
  = datatable._bulk_actions.join.html_safe
8
7
  - else
9
- %li
10
- %a{href: '#'} No bulk actions
8
+ %a.dropdown-item{href: '#'} No bulk actions
@@ -3,18 +3,16 @@
3
3
  - if datatable.columns.any? { |_, opts| opts[:th].present? } == false
4
4
  %tr
5
5
  - datatable.columns.each do |name, opts|
6
- %th= opts[:label] || name
6
+ %th{title: opts[:label].presence}= opts[:label]
7
7
  - else
8
8
  - max_depth = datatable.columns.map { |_, opts| opts[:th].try(:[], :depth) || 0 }.max
9
9
  - [*0..max_depth].each do |depth|
10
10
  %tr
11
11
  - columns = datatable.columns.select { |_, opts| (opts[:th].try(:[], :depth) || 0) == depth }
12
12
  - columns.each do |name, opts|
13
- %th{(opts[:th] || {}).merge(title: (opts[:label] || name))}
14
- = opts[:label] || name
13
+ %th{(opts[:th] || {}).merge(title: opts[:label].presence)}= opts[:label]
15
14
  - (opts[:th_append] || []).each do |faux_col|
16
- %th{(faux_col[:th] || {}).merge(title: faux_col[:label])}
17
- = faux_col[:label]
15
+ %th{(faux_col[:th] || {}).merge(title: faux_col[:label].presence)}= faux_col[:label]
18
16
 
19
17
  %tbody
20
18
  - datatable.to_json[:data].each do |row|
@@ -1,37 +1,17 @@
1
1
  .effective-datatables-filters{'aria-controls': datatable.to_param}
2
2
  = simple_form_for :filters, url: (datatable._form[:url] || '#'), method: datatable._form[:verb], html: { class: 'form-inline' } do |form|
3
-
4
3
  - if datatable._scopes.present?
5
4
  .effective-datatables-filters-scopes
6
- = form.input :scope, label: false, required: false, checked: datatable.state[:scope],
7
- as: (defined?(EffectiveFormInputs) ? :effective_radio_buttons : :radio_buttons),
8
- collection: datatable._scopes.map { |name, opts| [opts[:label], name] },
9
- buttons: true,
10
- wrapper_html: {class: 'btn-group-sm'}
5
+ = datatable_scope_tag(form, datatable)
11
6
 
12
7
  - if datatable._filters.present?
13
8
  .effective-datatables-filters-inputs
14
9
  - datatable._filters.each do |name, opts|
15
- = form.input name,
16
- label: opts[:label],
17
- required: opts[:input_html].delete(:required),
18
- value: datatable.state[:filter][name],
19
- selected: datatable.state[:filter][name],
20
- as: opts[:as],
21
- collection: opts[:input_html].delete(:collection),
22
- multiple: opts[:input_html].delete(:multiple),
23
- include_blank: opts[:input_html].delete(:include_blank),
24
- group_method: opts[:input_html].delete(:group_method),
25
- group_label_method: opts[:input_html].delete(:group_label_method),
26
- value_method: opts[:input_html].delete(:value_method),
27
- label_method: opts[:input_html].delete(:label_method),
28
- input_html: (({name: ''} unless datatable._filters_form_required?) || {}).merge(opts[:input_html]),
29
- input_js: ({ placeholder: ''} if opts[:as] == :effective_select),
30
- wrapper_html: {class: 'form-group-sm'}
10
+ = datatable_filter_tag(form, datatable, name, opts)
31
11
 
32
12
  - if datatable._scopes.present? || datatable._filters.present?
33
13
  .effective-datatables-filters-btn
34
14
  - if datatable._filters_form_required?
35
- = form.button :submit, 'Apply', 'data-disable-with': 'Applying...'
15
+ = form.button :submit, t('effective_datatables.apply'), 'data-disable-with': t('effective_datatables.applying')
36
16
  - else
37
- = link_to 'Apply', '#', class: 'btn btn-primary btn-sm btn-effective-datatables-filters', 'data-apply-effective-datatables-filters': true
17
+ = link_to t('effective_datatables.apply'), '#', class: 'btn btn-primary btn-sm btn-effective-datatables-filters', 'data-apply-effective-datatables-filters': true
@@ -0,0 +1,5 @@
1
+ - id = (resource.try(:to_param) || resource.try(:id) || resource.object_id)
2
+ - value = resource.send(column[:reorder])
3
+
4
+ %input{type: 'hidden', value: value, 'data-reorder-resource': id}
5
+ = glypicon('move')
@@ -0,0 +1 @@
1
+ = render_datatable(EffectiveStyleGuideDatatable.new)
@@ -26,30 +26,17 @@ EffectiveDatatables.setup do |config|
26
26
  config.default_length = 25
27
27
 
28
28
  # Default class used on the <table> tag
29
- config.html_class = 'table table-bordered table-striped'
30
-
31
- # If a user has previously visited this page and is returning, use the cookie to restore last session
32
- # Irregardless of this setting, effective_datatables still uses a cookie to function
33
- config.save_state = true
34
-
35
- # When using the actions_column DSL method, apply the following behavior
36
- # Valid values for each action are:
37
- # true - display this action if authorized?(:show, Post)
38
- # false - do not display this action
39
- # :authorize - display this action if authorized?(:show, Post<3>) (every instance is checked)
40
- #
41
- # You can override these defaults on a per-table basis
42
- # by calling `actions_column(show: false, edit: true, destroy: :authorize)`
43
- config.actions_column = {
44
- show: true,
45
- edit: true,
46
- destroy: true,
47
- }
29
+ config.html_class = 'table table-hover'
48
30
 
49
31
  # Log search/sort information to the console
50
32
  config.debug = true
51
33
 
52
- # String size. Final byte size is about 1.5 times bigger, after rails signs it
53
- config.max_cookie_size = 2000
34
+ # Use a cookie to save and restore state from previous page visits.
35
+ config.save_state = true
36
+
37
+ # Configure the _effective_dt cookie.
38
+ config.cookie_max_size = 2000 # String size. Final byte size is about 1.5 times bigger, after rails signs it
39
+ config.cookie_domain = :all # Should usually be :all
40
+ config.cookie_tld_length = nil # Leave nil to autodetect, or set to probably 2
54
41
 
55
42
  end
@@ -0,0 +1,12 @@
1
+ ---
2
+ en:
3
+ effective_datatables:
4
+ apply: Apply
5
+ reset: Reset
6
+ reorder: Reorder
7
+ new: New
8
+ actions: Actions
9
+ bulk_actions: Bulk Actions
10
+ applying: Applying...
11
+ boolean_true: 'Yes'
12
+ boolean_false: 'No'
@@ -0,0 +1,12 @@
1
+ ---
2
+ es:
3
+ effective_datatables:
4
+ apply: Filtrar
5
+ reset: Reiniciar
6
+ reorder: Reordenar
7
+ new: Nuevo
8
+ actions: Acciones
9
+ bulk_actions: Acciones en masa
10
+ applying: Filtrando...
11
+ boolean_true: 'Sí'
12
+ boolean_false: 'No'
@@ -0,0 +1,12 @@
1
+ ---
2
+ nl:
3
+ effective_datatables:
4
+ apply: Toepassen
5
+ reset: Reset
6
+ reorder: Opnieuw ordenen
7
+ new: Nieuwe
8
+ actions: Acties
9
+ bulk_actions: Bulkacties
10
+ applying: Toepassen...
11
+ boolean_true: 'Ja'
12
+ boolean_false: 'Nee'
data/config/routes.rb CHANGED
@@ -1,9 +1,10 @@
1
- Rails.application.routes.draw do
2
- mount EffectiveDatatables::Engine => '/', :as => 'effective_datatables'
3
- end
4
-
5
1
  EffectiveDatatables::Engine.routes.draw do
6
2
  scope :module => 'effective' do
7
3
  match 'datatables/:id(.:format)', to: 'datatables#show', via: [:get, :post], as: :datatable
4
+ match 'datatables/:id/reorder(.:format)', to: 'datatables#reorder', via: [:post], as: :reorder_datatable
8
5
  end
9
6
  end
7
+
8
+ Rails.application.routes.draw do
9
+ mount EffectiveDatatables::Engine => '/', :as => 'effective_datatables'
10
+ end
@@ -4,16 +4,23 @@ require 'effective_datatables/engine'
4
4
  require 'effective_datatables/version'
5
5
 
6
6
  module EffectiveDatatables
7
+ AVAILABLE_LOCALES = %w(en es nl)
8
+
7
9
  mattr_accessor :authorization_method
8
10
 
9
11
  mattr_accessor :default_length
10
12
  mattr_accessor :html_class
11
13
  mattr_accessor :save_state
12
- mattr_accessor :max_cookie_size
13
14
 
14
- mattr_accessor :actions_column # A Hash
15
+ mattr_accessor :cookie_max_size
16
+ mattr_accessor :cookie_domain
17
+ mattr_accessor :cookie_tld_length
18
+
15
19
  mattr_accessor :debug
16
20
 
21
+ alias_method :max_cookie_size, :cookie_max_size
22
+ alias_method :max_cookie_size=, :cookie_max_size=
23
+
17
24
  def self.setup
18
25
  yield self
19
26
  end
@@ -35,4 +42,44 @@ module EffectiveDatatables
35
42
  raise Effective::AccessDenied.new('Access Denied', action, resource) unless authorized?(controller, action, resource)
36
43
  end
37
44
 
45
+ def self.find(id, attributes = nil)
46
+ id = id.to_s.gsub(/-\d+\z/, '').gsub('-', '/')
47
+ klass = (id.classify.safe_constantize || id.classify.pluralize.safe_constantize)
48
+ attributes = decrypt(attributes) || {}
49
+
50
+ klass.try(:new, **attributes) || raise('unable to find datatable')
51
+ end
52
+
53
+ # Locale is coming from view. I think it can be dynamic.
54
+ # We currently support: en, es, nl
55
+ def self.language(locale)
56
+ @_languages ||= {}
57
+
58
+ locale = :en unless AVAILABLE_LOCALES.include?(locale.to_s)
59
+
60
+ @_languages[locale] ||= begin
61
+ path = Gem::Specification.find_by_name('effective_datatables').gem_dir + "/app/assets/javascripts/dataTables/locales/#{locale}.lang"
62
+ JSON.parse(File.read(path)).to_json
63
+ end
64
+ end
65
+
66
+ def self.encrypt(attributes)
67
+ payload = message_encrypter.encrypt_and_sign(attributes)
68
+ end
69
+
70
+ def self.decrypt(payload)
71
+ return unless payload.present?
72
+ return payload if payload.kind_of?(Hash)
73
+
74
+ attributes = message_encrypter.decrypt_and_verify(payload)
75
+
76
+ raise 'invalid decoded inline payload' unless attributes.kind_of?(Hash)
77
+
78
+ attributes
79
+ end
80
+
81
+ def self.message_encrypter
82
+ ActiveSupport::MessageEncryptor.new(Rails.application.secret_key_base.to_s.first(32))
83
+ end
84
+
38
85
  end
@@ -6,7 +6,10 @@ module EffectiveDatatables
6
6
 
7
7
  # Include Helpers to base application
8
8
  initializer 'effective_datatables.action_controller' do |app|
9
- ActiveSupport.on_load :action_controller do
9
+ ActiveSupport.on_load :action_controller_base do
10
+ helper EffectiveDatatablesHelper
11
+ helper EffectiveDatatablesPrivateHelper
12
+
10
13
  ActionController::Base.send :include, ::EffectiveDatatablesControllerHelper
11
14
  end
12
15
  end
@@ -15,6 +18,5 @@ module EffectiveDatatables
15
18
  initializer 'effective_datatables.defaults', before: :load_config_initializers do |app|
16
19
  eval File.read("#{config.root}/config/effective_datatables.rb")
17
20
  end
18
-
19
21
  end
20
22
  end
@@ -1,3 +1,3 @@
1
1
  module EffectiveDatatables
2
- VERSION = '3.6.3'.freeze
2
+ VERSION = '3.7.0'.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: 3.6.3
4
+ version: 3.7.0
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: 2019-08-07 00:00:00.000000000 Z
11
+ date: 2019-08-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 0.7.0
47
+ version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 0.7.0
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: sass
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -101,6 +101,9 @@ files:
101
101
  - app/assets/javascripts/dataTables/buttons/dataTables.buttons.js
102
102
  - app/assets/javascripts/dataTables/dataTables.bootstrap.js
103
103
  - app/assets/javascripts/dataTables/jquery.dataTables.js
104
+ - app/assets/javascripts/dataTables/locales/en.lang
105
+ - app/assets/javascripts/dataTables/locales/es.lang
106
+ - app/assets/javascripts/dataTables/locales/nl.lang
104
107
  - app/assets/javascripts/dataTables/responsive/dataTables.responsive.js
105
108
  - app/assets/javascripts/dataTables/responsive/responsive.bootstrap.js
106
109
  - app/assets/javascripts/effective_datatables.js
@@ -108,7 +111,11 @@ files:
108
111
  - app/assets/javascripts/effective_datatables/charts.js.coffee
109
112
  - app/assets/javascripts/effective_datatables/events.js.coffee
110
113
  - app/assets/javascripts/effective_datatables/filters.js.coffee
114
+ - app/assets/javascripts/effective_datatables/flash.js.coffee
111
115
  - app/assets/javascripts/effective_datatables/initialize.js.coffee
116
+ - app/assets/javascripts/effective_datatables/inline_crud.js.coffee
117
+ - app/assets/javascripts/effective_datatables/overrides.js.coffee
118
+ - app/assets/javascripts/effective_datatables/reorder.js.coffee
112
119
  - app/assets/javascripts/effective_datatables/reset.js.coffee
113
120
  - app/assets/javascripts/effective_datatables/responsive.js.coffee
114
121
  - app/assets/javascripts/vendor/jquery.delayedChange.js
@@ -120,6 +127,7 @@ files:
120
127
  - app/assets/stylesheets/effective_datatables/_filters.scss
121
128
  - app/assets/stylesheets/effective_datatables/_overrides.scss
122
129
  - app/controllers/effective/datatables_controller.rb
130
+ - app/datatables/effective_style_guide_datatable.rb
123
131
  - app/helpers/effective_datatables_controller_helper.rb
124
132
  - app/helpers/effective_datatables_helper.rb
125
133
  - app/helpers/effective_datatables_private_helper.rb
@@ -149,11 +157,15 @@ files:
149
157
  - app/views/effective/datatables/_chart.html.haml
150
158
  - app/views/effective/datatables/_datatable.html.haml
151
159
  - app/views/effective/datatables/_filters.html.haml
152
- - app/views/effective/datatables/_reset.html.haml
160
+ - app/views/effective/datatables/_reorder_column.html.haml
153
161
  - app/views/effective/datatables/_resource_column.html.haml
154
162
  - app/views/effective/datatables/_spacer_template.html
155
163
  - app/views/effective/datatables/index.html.haml
164
+ - app/views/effective/style_guide/_effective_datatables.html.haml
156
165
  - config/effective_datatables.rb
166
+ - config/locales/en.yml
167
+ - config/locales/es.yml
168
+ - config/locales/nl.yml
157
169
  - config/routes.rb
158
170
  - lib/effective_datatables.rb
159
171
  - lib/effective_datatables/engine.rb