effective_datatables 3.6.3 → 3.7.0

Sign up to get free protection for your applications and to get access to all the features.
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