effective_datatables 4.7.16 → 4.15.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +278 -24
- data/app/assets/javascripts/effective_datatables/bulk_actions.js.coffee +32 -9
- data/app/assets/javascripts/effective_datatables/download.js.coffee +10 -0
- data/app/assets/javascripts/effective_datatables/flash.js.coffee +1 -1
- data/app/assets/javascripts/effective_datatables/initialize.js.coffee +22 -13
- data/app/assets/javascripts/effective_datatables/inline_crud.js.coffee +42 -13
- data/app/assets/javascripts/effective_datatables/reorder.js.coffee +8 -2
- data/app/assets/javascripts/effective_datatables/reset.js.coffee +23 -2
- data/app/assets/javascripts/vendor/jquery.delayedChange.js +1 -2
- data/app/assets/stylesheets/dataTables/dataTables.bootstrap4.scss +1 -3
- data/app/controllers/effective/datatables_controller.rb +34 -0
- data/app/helpers/effective_datatables_controller_helper.rb +2 -0
- data/app/helpers/effective_datatables_helper.rb +22 -6
- data/app/helpers/effective_datatables_private_helper.rb +30 -20
- data/app/models/effective/datatable.rb +57 -4
- data/app/models/effective/datatable_column.rb +2 -0
- data/app/models/effective/datatable_column_tool.rb +5 -3
- data/app/models/effective/datatable_dsl_tool.rb +7 -5
- data/app/models/effective/datatable_value_tool.rb +9 -8
- data/app/models/effective/effective_datatable/attributes.rb +21 -0
- data/app/models/effective/effective_datatable/collection.rb +3 -1
- data/app/models/effective/effective_datatable/compute.rb +11 -7
- data/app/models/effective/effective_datatable/cookie.rb +6 -0
- data/app/models/effective/effective_datatable/csv.rb +71 -0
- data/app/models/effective/effective_datatable/dsl/bulk_actions.rb +3 -1
- data/app/models/effective/effective_datatable/dsl/charts.rb +2 -0
- data/app/models/effective/effective_datatable/dsl/datatable.rb +20 -6
- data/app/models/effective/effective_datatable/dsl/filters.rb +3 -1
- data/app/models/effective/effective_datatable/dsl.rb +7 -3
- data/app/models/effective/effective_datatable/format.rb +52 -24
- data/app/models/effective/effective_datatable/hooks.rb +2 -0
- data/app/models/effective/effective_datatable/params.rb +9 -2
- data/app/models/effective/effective_datatable/resource.rb +26 -13
- data/app/models/effective/effective_datatable/state.rb +4 -2
- data/app/views/effective/datatables/_active_storage_column.html.haml +4 -0
- data/app/views/effective/datatables/_bulk_actions_dropdown.html.haml +3 -2
- data/app/views/effective/datatables/_buttons.html.haml +14 -0
- data/config/effective_datatables.rb +8 -1
- data/config/locales/en.yml +4 -1
- data/config/locales/es.yml +4 -1
- data/config/locales/nl.yml +4 -1
- data/config/routes.rb +1 -0
- data/lib/effective_datatables/engine.rb +6 -4
- data/lib/effective_datatables/version.rb +1 -1
- data/lib/effective_datatables.rb +5 -0
- metadata +11 -10
- data/app/datatables/effective_style_guide_datatable.rb +0 -47
- data/app/models/effective/access_denied.rb +0 -17
- 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
|
-
|
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
|
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?
|
100
|
-
opts[:
|
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.
|
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.
|
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
|
-
|
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
|
-
|
216
|
-
|
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
|
@@ -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
|
-
|
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: '#'}
|
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 =
|
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
|
data/config/locales/en.yml
CHANGED
@@ -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
|
data/config/locales/es.yml
CHANGED
@@ -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
|
data/config/locales/nl.yml
CHANGED
@@ -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
|
-
|
10
|
-
|
11
|
-
|
9
|
+
app.config.to_prepare do
|
10
|
+
ActiveSupport.on_load :action_controller_base do
|
11
|
+
helper EffectiveDatatablesHelper
|
12
|
+
helper EffectiveDatatablesPrivateHelper
|
12
13
|
|
13
|
-
|
14
|
+
ActionController::Base.send :include, ::EffectiveDatatablesControllerHelper
|
15
|
+
end
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
data/lib/effective_datatables.rb
CHANGED
@@ -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.
|
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:
|
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:
|
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.
|
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)
|