effective_datatables 4.7.16 → 4.15.1

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +278 -24
  4. data/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee +32 -9
  5. data/app/assets/javascripts/effective_datatables/download.js.coffee +10 -0
  6. data/app/assets/javascripts/effective_datatables/flash.js.coffee +1 -1
  7. data/app/assets/javascripts/effective_datatables/initialize.js.coffee +22 -13
  8. data/app/assets/javascripts/effective_datatables/inline_crud.js.coffee +42 -13
  9. data/app/assets/javascripts/effective_datatables/reorder.js.coffee +8 -2
  10. data/app/assets/javascripts/effective_datatables/reset.js.coffee +23 -2
  11. data/app/assets/javascripts/vendor/jquery.delayedChange.js +1 -2
  12. data/app/assets/stylesheets/dataTables/dataTables.bootstrap4.scss +1 -3
  13. data/app/controllers/effective/datatables_controller.rb +34 -0
  14. data/app/helpers/effective_datatables_controller_helper.rb +2 -0
  15. data/app/helpers/effective_datatables_helper.rb +22 -6
  16. data/app/helpers/effective_datatables_private_helper.rb +30 -20
  17. data/app/models/effective/datatable.rb +57 -4
  18. data/app/models/effective/datatable_column.rb +2 -0
  19. data/app/models/effective/datatable_column_tool.rb +5 -3
  20. data/app/models/effective/datatable_dsl_tool.rb +7 -5
  21. data/app/models/effective/datatable_value_tool.rb +9 -8
  22. data/app/models/effective/effective_datatable/attributes.rb +21 -0
  23. data/app/models/effective/effective_datatable/collection.rb +3 -1
  24. data/app/models/effective/effective_datatable/compute.rb +11 -7
  25. data/app/models/effective/effective_datatable/cookie.rb +6 -0
  26. data/app/models/effective/effective_datatable/csv.rb +71 -0
  27. data/app/models/effective/effective_datatable/dsl/bulk_actions.rb +3 -1
  28. data/app/models/effective/effective_datatable/dsl/charts.rb +2 -0
  29. data/app/models/effective/effective_datatable/dsl/datatable.rb +20 -6
  30. data/app/models/effective/effective_datatable/dsl/filters.rb +3 -1
  31. data/app/models/effective/effective_datatable/dsl.rb +7 -3
  32. data/app/models/effective/effective_datatable/format.rb +52 -24
  33. data/app/models/effective/effective_datatable/hooks.rb +2 -0
  34. data/app/models/effective/effective_datatable/params.rb +9 -2
  35. data/app/models/effective/effective_datatable/resource.rb +26 -13
  36. data/app/models/effective/effective_datatable/state.rb +4 -2
  37. data/app/views/effective/datatables/_active_storage_column.html.haml +4 -0
  38. data/app/views/effective/datatables/_bulk_actions_dropdown.html.haml +3 -2
  39. data/app/views/effective/datatables/_buttons.html.haml +14 -0
  40. data/config/effective_datatables.rb +8 -1
  41. data/config/locales/en.yml +4 -1
  42. data/config/locales/es.yml +4 -1
  43. data/config/locales/nl.yml +4 -1
  44. data/config/routes.rb +1 -0
  45. data/lib/effective_datatables/engine.rb +6 -4
  46. data/lib/effective_datatables/version.rb +1 -1
  47. data/lib/effective_datatables.rb +5 -0
  48. metadata +11 -10
  49. data/app/datatables/effective_style_guide_datatable.rb +0 -47
  50. data/app/models/effective/access_denied.rb +0 -17
  51. data/app/views/effective/style_guide/_effective_datatables.html.haml +0 -1
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Effective
2
4
  module EffectiveDatatable
3
5
  module Resource
4
6
  AGGREGATE_SQL_FUNCTIONS = ['ARRAY_AGG(', 'AVG(', 'COUNT(', 'MAX(', 'MIN(', 'STRING_AGG(', 'SUM(']
5
7
 
6
8
  def admin_namespace?
7
- controller_namespace == 'admin'
9
+ [:admin, 'admin'].include?(controller_namespace)
8
10
  end
9
11
 
10
12
  def controller_namespace
@@ -31,7 +33,7 @@ module Effective
31
33
  end
32
34
 
33
35
  def load_effective_resource!
34
- @effective_resource = if active_record_collection?
36
+ @effective_resource ||= if active_record_collection?
35
37
  Effective::Resource.new(collection_class, namespace: controller_namespace)
36
38
  end
37
39
  end
@@ -91,14 +93,18 @@ module Effective
91
93
  opts[:sql_column] = :effective_addresses
92
94
  when :effective_roles
93
95
  opts[:sql_column] = :effective_roles
96
+ when :active_storage
97
+ opts[:sql_column] = :active_storage
94
98
  when :string # This is the fallback
95
99
  # Anything that doesn't belong to the model or the sql table, we assume is a SELECT SUM|AVG|RANK() as fancy
96
100
  opts[:sql_as_column] = true if (effective_resource.table && effective_resource.column(name).blank?)
97
101
  end
98
102
 
99
- if opts[:sql_column].present? && AGGREGATE_SQL_FUNCTIONS.any? { |str| opts[:sql_column].to_s.start_with?(str) }
100
- opts[:sql_as_column] = true
103
+ if opts[:sql_column].present?
104
+ sql_column = opts[:sql_column].to_s
105
+ opts[:sql_as_column] = true if AGGREGATE_SQL_FUNCTIONS.any? { |str| sql_column.start_with?(str) }
101
106
  end
107
+
102
108
  end
103
109
  end
104
110
 
@@ -137,6 +143,10 @@ module Effective
137
143
  opts[:partial] ||= '/effective/datatables/resource_column'
138
144
  end
139
145
 
146
+ if opts[:as] == :active_storage
147
+ opts[:partial] ||= '/effective/datatables/active_storage_column'
148
+ end
149
+
140
150
  opts[:col_class] = [
141
151
  "col-#{opts[:as]}",
142
152
  "col-#{name.to_s.parameterize}",
@@ -148,7 +158,6 @@ module Effective
148
158
 
149
159
  def load_resource_search!
150
160
  columns.each do |name, opts|
151
-
152
161
  case opts[:search]
153
162
  when false
154
163
  opts[:search] = { as: :null }; next
@@ -166,13 +175,12 @@ module Effective
166
175
 
167
176
  # Parameterize collection
168
177
  if search[:collection].kind_of?(ActiveRecord::Relation)
169
- search[:collection] = search[:collection].map { |obj| [obj.to_s, obj.to_param] }
178
+ search[:collection] = search[:collection].map { |obj| [obj.to_s, obj.id] }
170
179
  elsif search[:collection].kind_of?(Array) && search[:collection].first.kind_of?(ActiveRecord::Base)
171
- search[:collection] = search[:collection].map { |obj| [obj.to_s, obj.to_param] }
180
+ search[:collection] = search[:collection].map { |obj| [obj.to_s, obj.id] }
172
181
  end
173
182
 
174
183
  search[:as] ||= :select if search.key?(:collection)
175
- search[:fuzzy] ||= true unless search.key?(:fuzzy)
176
184
  search[:value] ||= search.delete(:selected) if search.key?(:selected)
177
185
 
178
186
  # Merge with defaults
@@ -185,6 +193,12 @@ module Effective
185
193
  search.reverse_merge!(search_resource.search_form_field(name, opts[:as]))
186
194
  end
187
195
 
196
+ # Assign default search operation
197
+ search[:operation] ||= search.delete(:op)
198
+ search[:operation] ||= :matches if search[:fuzzy]
199
+ search[:operation] ||= :eq if search[:as] == :select
200
+ search[:operation] ||= search_resource.sql_operation(name, as: opts[:as])
201
+
188
202
  # Assign default include_null
189
203
  if search[:as] == :select && !search.key?(:include_null)
190
204
  search[:include_null] = true
@@ -194,6 +208,7 @@ module Effective
194
208
 
195
209
  def load_resource_belongs_tos!
196
210
  return unless active_record_collection?
211
+ return unless @_collection_apply_belongs_to
197
212
 
198
213
  changed = attributes.select do |attribute, value|
199
214
  attribute = attribute.to_s
@@ -204,7 +219,7 @@ module Effective
204
219
  next unless columns[associated]
205
220
 
206
221
  if columns[associated][:as] == :belongs_to
207
- if @_collection_apply_belongs_to && !@_collection.where_values_hash.include?(attribute)
222
+ unless @_collection.where_values_hash.include?(attribute)
208
223
  @_collection = @_collection.where(attribute => value)
209
224
  end
210
225
 
@@ -212,10 +227,8 @@ module Effective
212
227
  elsif columns[associated][:as] == :belongs_to_polymorphic
213
228
  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")
214
229
 
215
- if @_collection_apply_belongs_to
216
- if !@_collection.where_values_hash.include?(attribute) && !@_collection.where_values_hash.include?("#{associated}_type")
217
- @_collection = @_collection.where(attribute => value).where("#{associated}_type" => associated_type)
218
- end
230
+ unless @_collection.where_values_hash.include?(attribute) || @_collection.where_values_hash.include?("#{associated}_type")
231
+ @_collection = @_collection.where(attribute => value).where("#{associated}_type" => associated_type)
219
232
  end
220
233
 
221
234
  columns.delete(associated)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Effective
2
4
  module EffectiveDatatable
3
5
  module State
@@ -98,7 +100,7 @@ module Effective
98
100
  load_cookie_state! if cookie.present? && cookie[:params] == cookie_state_params
99
101
  load_filter_params!
100
102
  end
101
-
103
+
102
104
  fill_empty_filters!
103
105
  end
104
106
 
@@ -198,7 +200,7 @@ module Effective
198
200
  def parse_filter_value(filter, value)
199
201
  return filter[:parse].call(value) if filter[:parse]
200
202
  return nil if value.blank? && !filter[:required]
201
- Effective::Attribute.new(filter[:value]).parse(value, name: filter[:name])
203
+ Effective::Attribute.new(filter[:as] || filter[:value] || :string).parse(value, name: filter[:name])
202
204
  end
203
205
 
204
206
  def cookie_state_params
@@ -0,0 +1,4 @@
1
+ - Array(resource.public_send(column[:name])).each do |file|
2
+ .col-resource_item
3
+ - title = [file.content_type, number_to_human_size(file.byte_size)].map(&:presence).compact
4
+ = link_to(file.filename, url_for(file), title: title, target: '_blank')
@@ -1,8 +1,9 @@
1
1
  .btn-group.buttons-bulk-actions
2
2
  %button.btn.btn-link.btn-sm.dropdown-toggle{'type': 'button', 'data-toggle': 'dropdown', 'aria-haspopup': true, 'aria-expanded': false, 'disabled': 'disabled'}
3
- Bulk Actions
3
+ = t('effective_datatables.bulk_actions')
4
4
  .dropdown-menu
5
5
  - if datatable._bulk_actions.present?
6
6
  = datatable._bulk_actions.join.html_safe
7
7
  - else
8
- %a.dropdown-item{href: '#'} No bulk actions
8
+ %a.dropdown-item{href: '#'}
9
+ = t('effective_datatables.no_bulk_actions')
@@ -0,0 +1,14 @@
1
+ - if datatable._bulk_actions.present?
2
+ = render('/effective/datatables/bulk_actions_dropdown', datatable: datatable)
3
+
4
+ - if datatable.searchable?
5
+ = link_to '#', class: 'btn btn-link btn-sm buttons-reset-search' do
6
+ %span= t('effective_datatables.reset')
7
+
8
+ - if datatable.reorder? && EffectiveDatatables.authorized?(self, :update, datatable.collection_class)
9
+ = link_to '#', class: 'btn btn-link btn-sm buttons-reorder' do
10
+ %span= t('effective_datatables.reorder')
11
+
12
+ - if datatable.downloadable?
13
+ = link_to 'download.csv', class: 'btn btn-link btn-sm buttons-download', 'aria-controls': datatable.to_param do
14
+ %span= t('effective_datatables.download')
@@ -35,8 +35,15 @@ EffectiveDatatables.setup do |config|
35
35
  config.save_state = true
36
36
 
37
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
38
+ config.cookie_max_size = 1500 # String size. Final byte size is about 1.5 times bigger, after rails signs it
39
39
  config.cookie_domain = :all # Should usually be :all
40
40
  config.cookie_tld_length = nil # Leave nil to autodetect, or set to probably 2
41
41
 
42
+ # Date formatting
43
+ config.format_datetime = '%F %H:%M'
44
+ config.format_date = '%F'
45
+ config.format_time = '%H:%M'
46
+
47
+ # Enable the Download button which serves a CSV of your collection
48
+ config.download = false
42
49
  end
@@ -2,11 +2,14 @@
2
2
  en:
3
3
  effective_datatables:
4
4
  apply: Apply
5
+ download: Download
5
6
  reset: Reset
6
7
  reorder: Reorder
7
8
  new: New
8
9
  actions: Actions
9
10
  bulk_actions: Bulk Actions
11
+ no_bulk_actions: No bulk actions
10
12
  applying: Applying...
11
13
  boolean_true: 'Yes'
12
- boolean_false: 'No'
14
+ boolean_false: 'No'
15
+ all: All
@@ -2,11 +2,14 @@
2
2
  es:
3
3
  effective_datatables:
4
4
  apply: Filtrar
5
+ download: Download
5
6
  reset: Reiniciar
6
7
  reorder: Reordenar
7
8
  new: Nuevo
8
9
  actions: Acciones
9
10
  bulk_actions: Acciones en masa
11
+ no_bulk_actions: Sin acciones en masa
10
12
  applying: Filtrando...
11
13
  boolean_true: 'Sí'
12
- boolean_false: 'No'
14
+ boolean_false: 'No'
15
+ all: Todo
@@ -2,11 +2,14 @@
2
2
  nl:
3
3
  effective_datatables:
4
4
  apply: Toepassen
5
+ download: Download
5
6
  reset: Reset
6
7
  reorder: Opnieuw ordenen
7
8
  new: Nieuwe
8
9
  actions: Acties
9
10
  bulk_actions: Bulkacties
11
+ no_bulk_actions: Geen bulkacties
10
12
  applying: Toepassen...
11
13
  boolean_true: 'Ja'
12
- boolean_false: 'Nee'
14
+ boolean_false: 'Nee'
15
+ all: Te doen
data/config/routes.rb CHANGED
@@ -2,6 +2,7 @@ EffectiveDatatables::Engine.routes.draw do
2
2
  scope :module => 'effective' do
3
3
  match 'datatables/:id(.:format)', to: 'datatables#show', via: [:get, :post], as: :datatable
4
4
  match 'datatables/:id/reorder(.:format)', to: 'datatables#reorder', via: [:post], as: :reorder_datatable
5
+ match 'datatables/:id/download(.:format)', to: 'datatables#download', via: :get, as: :download_datatable
5
6
  end
6
7
  end
7
8
 
@@ -6,11 +6,13 @@ 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_base do
10
- helper EffectiveDatatablesHelper
11
- helper EffectiveDatatablesPrivateHelper
9
+ app.config.to_prepare do
10
+ ActiveSupport.on_load :action_controller_base do
11
+ helper EffectiveDatatablesHelper
12
+ helper EffectiveDatatablesPrivateHelper
12
13
 
13
- ActionController::Base.send :include, ::EffectiveDatatablesControllerHelper
14
+ ActionController::Base.send :include, ::EffectiveDatatablesControllerHelper
15
+ end
14
16
  end
15
17
  end
16
18
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveDatatables
2
- VERSION = '4.7.16'.freeze
2
+ VERSION = '4.15.1'.freeze
3
3
  end
@@ -16,7 +16,12 @@ module EffectiveDatatables
16
16
  mattr_accessor :cookie_domain
17
17
  mattr_accessor :cookie_tld_length
18
18
 
19
+ mattr_accessor :format_datetime
20
+ mattr_accessor :format_date
21
+ mattr_accessor :format_time
22
+
19
23
  mattr_accessor :debug
24
+ mattr_accessor :download
20
25
 
21
26
  alias_method :max_cookie_size, :cookie_max_size
22
27
  alias_method :max_cookie_size=, :cookie_max_size=
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.7.16
4
+ version: 4.15.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-23 00:00:00.000000000 Z
11
+ date: 2023-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: sass
70
+ name: sassc
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -111,6 +111,7 @@ files:
111
111
  - app/assets/javascripts/effective_datatables.js
112
112
  - app/assets/javascripts/effective_datatables/bulk_actions.js.coffee
113
113
  - app/assets/javascripts/effective_datatables/charts.js.coffee
114
+ - app/assets/javascripts/effective_datatables/download.js.coffee
114
115
  - app/assets/javascripts/effective_datatables/events.js.coffee
115
116
  - app/assets/javascripts/effective_datatables/filters.js.coffee
116
117
  - app/assets/javascripts/effective_datatables/flash.js.coffee
@@ -129,11 +130,9 @@ files:
129
130
  - app/assets/stylesheets/effective_datatables.scss
130
131
  - app/assets/stylesheets/effective_datatables/_overrides.bootstrap4.scss
131
132
  - app/controllers/effective/datatables_controller.rb
132
- - app/datatables/effective_style_guide_datatable.rb
133
133
  - app/helpers/effective_datatables_controller_helper.rb
134
134
  - app/helpers/effective_datatables_helper.rb
135
135
  - app/helpers/effective_datatables_private_helper.rb
136
- - app/models/effective/access_denied.rb
137
136
  - app/models/effective/datatable.rb
138
137
  - app/models/effective/datatable_column.rb
139
138
  - app/models/effective/datatable_column_tool.rb
@@ -143,6 +142,7 @@ files:
143
142
  - app/models/effective/effective_datatable/collection.rb
144
143
  - app/models/effective/effective_datatable/compute.rb
145
144
  - app/models/effective/effective_datatable/cookie.rb
145
+ - app/models/effective/effective_datatable/csv.rb
146
146
  - app/models/effective/effective_datatable/dsl.rb
147
147
  - app/models/effective/effective_datatable/dsl/bulk_actions.rb
148
148
  - app/models/effective/effective_datatable/dsl/charts.rb
@@ -153,8 +153,10 @@ files:
153
153
  - app/models/effective/effective_datatable/params.rb
154
154
  - app/models/effective/effective_datatable/resource.rb
155
155
  - app/models/effective/effective_datatable/state.rb
156
+ - app/views/effective/datatables/_active_storage_column.html.haml
156
157
  - app/views/effective/datatables/_bulk_actions_column.html.haml
157
158
  - app/views/effective/datatables/_bulk_actions_dropdown.html.haml
159
+ - app/views/effective/datatables/_buttons.html.haml
158
160
  - app/views/effective/datatables/_chart.html.haml
159
161
  - app/views/effective/datatables/_datatable.html.haml
160
162
  - app/views/effective/datatables/_filters.html.haml
@@ -162,7 +164,6 @@ files:
162
164
  - app/views/effective/datatables/_resource_column.html.haml
163
165
  - app/views/effective/datatables/_spacer_template.html
164
166
  - app/views/effective/datatables/index.html.haml
165
- - app/views/effective/style_guide/_effective_datatables.html.haml
166
167
  - config/effective_datatables.rb
167
168
  - config/locales/en.yml
168
169
  - config/locales/es.yml
@@ -177,7 +178,7 @@ homepage: https://github.com/code-and-effect/effective_datatables
177
178
  licenses:
178
179
  - MIT
179
180
  metadata: {}
180
- post_install_message:
181
+ post_install_message:
181
182
  rdoc_options: []
182
183
  require_paths:
183
184
  - lib
@@ -192,8 +193,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
192
193
  - !ruby/object:Gem::Version
193
194
  version: '0'
194
195
  requirements: []
195
- rubygems_version: 3.0.3
196
- signing_key:
196
+ rubygems_version: 3.1.2
197
+ signing_key:
197
198
  specification_version: 4
198
199
  summary: Uniquely powerful server-side searching, sorting and filtering of any ActiveRecord
199
200
  or Array collection as well as post-rendered content displayed as a frontend jQuery
@@ -1,47 +0,0 @@
1
- class EffectiveStyleGuideDatatable < Effective::Datatable
2
- datatable do
3
- length 10
4
-
5
- col :id
6
- col :material, search: { collection: ['Stainless Steel', 'Copper', 'Cast Iron', 'Composite'] }
7
- col :bowl, search: { collection: ['Single Bowl', 'Double Bowl', 'Triple Bowl'] }
8
- col :name
9
- col :date, as: :date
10
-
11
- actions_col
12
- end
13
-
14
- # Set the permission check to the same as Effective::StyleGuide
15
- def collection_class
16
- defined?(Effective::StyleGuide) ? Effective::StyleGuide : super
17
- end
18
-
19
- collection do
20
- now = Time.zone.now
21
- [
22
- [1, 'Stainless Steel', 'Single Bowl', 'KOHLER Staccato', (now + 1.day)],
23
- [2, 'Stainless Steel', 'Double Bowl', 'KOHLER Vault Undercounter', (now + 1.day)],
24
- [3, 'Stainless Steel', 'Triple Bowl', 'KRAUS All-In-One', (now + 1.day)],
25
- [4, 'Stainless Steel', 'Single Bowl', 'KOHLER Vault Dual Mount', (now + 1.day)],
26
- [5, 'Stainless Steel', 'Single Bowl', 'KRAUS All-In-One Undermount', (now + 2.days)],
27
- [6, 'Stainless Steel', 'Double Bowl', 'Glacier Bay All-in-One', (now + 2.days)],
28
- [7, 'Stainless Steel', 'Single Bowl', 'Elkay Neptune', (now + 2.days)],
29
- [8, 'Copper', 'Single Bowl', 'ECOSINKS Apron Front Dual Mount', (now + 2.days)],
30
- [9, 'Copper', 'Double Bowl', 'ECOSINKS Dual Mount Front Hammered', (now + 2.days)],
31
- [10, 'Copper', 'Triple Bowl', 'Glarier Bay Undermount', (now + 3.days)],
32
- [11, 'Copper', 'Single Bowl', 'Whitehaus Undermount', (now + 3.days)],
33
- [12, 'Copper', 'Double Bowl', 'Belle Foret Apron Front', (now + 3.days)],
34
- [13, 'Copper', 'Double Bowl', 'Pegasus Dual Mount', (now + 3.days)],
35
- [14, 'Cast Iron', 'Double Bowl', 'KOHLER Whitehaven', (now + 3.days)],
36
- [15, 'Cast Iron', 'Triple Bowl', 'KOHLER Hartland', (now + 3.days)],
37
- [16, 'Cast Iron', 'Single Bowl', 'KOHLER Cape Dory Undercounter', (now + 4.days)],
38
- [17, 'Cast Iron', 'Double Bowl', 'KOLER Bakersfield', (now + 4.days)],
39
- [18, 'Cast Iron', 'Double Bowl', 'American Standard Offset', (now + 4.days)],
40
- [19, 'Cast Iron', 'Single Bowl', 'Brookfield Top', (now + 4.days)],
41
- [20, 'Composite', 'Single Bowl', 'Blanco Diamond Undermount', (now + 5.days)],
42
- [21, 'Composite', 'Double Bowl', 'Mont Blanc Waterbrook', (now + 5.days)],
43
- [22, 'Composite', 'Triple Bowl', 'Pegasus Triple Mount', (now + 5.days)],
44
- [23, 'Composite', 'Single Bowl', 'Swanstone Dual Mount', (now + 5.days)]
45
- ]
46
- end
47
- end
@@ -1,17 +0,0 @@
1
- unless defined?(Effective::AccessDenied)
2
- module Effective
3
- class AccessDenied < StandardError
4
- attr_reader :action, :subject
5
-
6
- def initialize(message = nil, action = nil, subject = nil)
7
- @message = message
8
- @action = action
9
- @subject = subject
10
- end
11
-
12
- def to_s
13
- @message || I18n.t(:'unauthorized.default', :default => 'Access Denied')
14
- end
15
- end
16
- end
17
- end
@@ -1 +0,0 @@
1
- = render_datatable(EffectiveStyleGuideDatatable.new)