effective_datatables 2.6.13 → 2.6.14

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dbedb70b17b8aaafe9d68c0b32257e91ebca11e1
4
- data.tar.gz: 661091c0e5b7ec23b9be50f63dd92f85f8c4de6a
3
+ metadata.gz: e74b48943a26fed6030dccee8555337684bc4c49
4
+ data.tar.gz: ef20573e54accb0e2135e66a6c9f77a8720c51af
5
5
  SHA512:
6
- metadata.gz: a38284cf5ad1da7d474151355b8179da9788beef16e087bc3a4af453d089fdf47b14d505e7ff12875a0a401c6870972bbe015f29103fb066b5cdeba475c9d21a
7
- data.tar.gz: fd5bebb9d4114a6d7bc03eb5a4c6142bbf8056e8d52fd3fca011f8972b61c2abc65d1ce1d57987e1cda12404c96c30e8136d690207d06220d11626a34a2db0fc
6
+ metadata.gz: 01980cdb85274c5cf73a7131bbbe8ef9b1873930eb61a03b23bcec45b62e97f4c79bd3e59c9fa298306da752de323127cf556670fe351de2e69f77f33c516ff7
7
+ data.tar.gz: b163136bc40e04ec0cc698b9ff20c58e97402573071ee47a67513d710140fbb00e031e5388b9c34a1140af4a232d3751fccb3823aa239406551b43f3614f078b
@@ -1,13 +1,40 @@
1
+ # These are expected to be called by a developer. They are part of the datatables DSL.
1
2
  module EffectiveDatatablesHelper
3
+
2
4
  def render_datatable(datatable, input_js_options = nil)
3
- return if datatable.nil?
5
+ raise 'expected datatable to be present' unless datatable
6
+
4
7
  datatable.view ||= self
5
8
 
9
+ begin
10
+ EffectiveDatatables.authorized?(controller, :index, datatable.try(:collection_class) || datatable.try(:class)) || raise('unauthorized')
11
+ rescue => e
12
+ return content_tag(:p, "You are not authorized to view this datatable. (cannot :index, #{datatable.try(:collection_class) || datatable.try(:class)})")
13
+ end
14
+
6
15
  render partial: 'effective/datatables/datatable',
7
16
  locals: { datatable: datatable, input_js_options: input_js_options.try(:to_json) }
8
17
  end
9
18
 
19
+ def render_simple_datatable(datatable, input_js_options = nil)
20
+ raise 'expected datatable to be present' unless datatable
21
+
22
+ datatable.view ||= self
23
+ datatable.simple = true
24
+
25
+ begin
26
+ EffectiveDatatables.authorized?(controller, :index, datatable.try(:collection_class) || datatable.try(:class)) || raise('unauthorized')
27
+ rescue => e
28
+ return content_tag(:p, "You are not authorized to view this datatable. (cannot :index, #{datatable.try(:collection_class) || datatable.try(:class)})")
29
+ end
30
+
31
+ render partial: 'effective/datatables/datatable',
32
+ locals: {datatable: datatable, input_js_options: input_js_options.try(:to_json) }
33
+ end
34
+
10
35
  def render_datatable_scopes(datatable)
36
+ raise 'expected datatable to be present' unless datatable
37
+
11
38
  return unless datatable.scopes.present?
12
39
  datatable.view ||= self
13
40
 
@@ -15,6 +42,8 @@ module EffectiveDatatablesHelper
15
42
  end
16
43
 
17
44
  def render_datatable_charts(datatable)
45
+ raise 'expected datatable to be present' unless datatable
46
+
18
47
  return unless datatable.charts.present?
19
48
  datatable.view ||= self
20
49
 
@@ -22,6 +51,8 @@ module EffectiveDatatablesHelper
22
51
  end
23
52
 
24
53
  def render_datatable_chart(datatable, name)
54
+ raise 'expected datatable to be present' unless datatable
55
+
25
56
  return unless datatable.charts.present?
26
57
  return unless datatable.charts[name].present?
27
58
  datatable.view ||= self
@@ -40,116 +71,6 @@ module EffectiveDatatablesHelper
40
71
  locals: { datatable: datatable, chart: chart }
41
72
  end
42
73
 
43
- def render_simple_datatable(datatable, input_js_options = nil)
44
- return if datatable.nil?
45
- datatable.view ||= self
46
- datatable.simple = true
47
-
48
- render partial: 'effective/datatables/datatable',
49
- locals: {datatable: datatable, input_js_options: input_js_options.try(:to_json) }
50
- end
51
-
52
- def datatable_default_order(datatable)
53
- [datatable.order_index, datatable.order_direction.downcase].to_json()
54
- end
55
-
56
- # https://datatables.net/reference/option/columns
57
- def datatable_columns(datatable)
58
- form = nil
59
- simple_form_for(:datatable_filter, url: '#', html: {id: "#{datatable.to_param}-form"}) { |f| form = f }
60
-
61
- datatable.table_columns.map do |name, options|
62
- {
63
- name: options[:name],
64
- title: content_tag(:span, options[:label], class: 'filter-label'),
65
- className: options[:class],
66
- width: options[:width],
67
- responsivePriority: (options[:responsivePriority] || 10000), # 10,000 is datatables default
68
- sortable: (options[:sortable] && !datatable.simple?),
69
- visible: (options[:visible].respond_to?(:call) ? datatable.instance_exec(&options[:visible]) : options[:visible]),
70
- filterHtml: (datatable_header_filter(form, name, datatable.search_terms[name], options) unless datatable.simple?),
71
- filterSelectedValue: options[:filter][:selected]
72
- }
73
- end.to_json()
74
- end
75
-
76
- def datatable_bulk_actions(datatable)
77
- bulk_actions_column = datatable.table_columns.find { |_, options| options[:bulk_actions_column] }.try(:second)
78
- return false unless bulk_actions_column
79
-
80
- {
81
- dropdownHtml: render(
82
- partial: bulk_actions_column[:dropdown_partial],
83
- locals: { datatable: datatable, dropdown_block: bulk_actions_column[:dropdown_block] }.merge(bulk_actions_column[:partial_locals])
84
- )
85
- }.to_json()
86
- end
87
-
88
- def datatable_header_filter(form, name, value, opts)
89
- return render(partial: opts[:header_partial], locals: {form: form, name: (opts[:label] || name), column: opts}) if opts[:header_partial].present?
90
-
91
- include_blank = opts[:filter].key?(:include_blank) ? opts[:filter][:include_blank] : (opts[:label] || name.titleize)
92
- pattern = opts[:filter].key?(:pattern) ? opts[:filter][:pattern] : nil
93
- placeholder = opts[:filter].key?(:placeholder) ? opts[:filter][:placeholder] : (opts[:label] || name.titleize)
94
- title = opts[:filter].key?(:title) ? opts[:filter][:title] : (opts[:label] || name.titleize)
95
-
96
- case opts[:filter][:as]
97
- when :string, :text, :number
98
- form.input name, label: false, required: false, value: value,
99
- as: :string,
100
- placeholder: placeholder,
101
- input_html: { name: nil, value: value, title: title, pattern: pattern, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index]} }
102
- when :obfuscated_id
103
- pattern ||= "[0-9]{3}-?[0-9]{4}-?[0-9]{3}"
104
- title = opts[:filter].key?(:title) ? opts[:filter][:title] : "Expected format: XXX-XXXX-XXX"
105
-
106
- form.input name, label: false, required: false, value: value,
107
- as: :string,
108
- placeholder: placeholder,
109
- input_html: { name: nil, value: value, title: title, pattern: pattern, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index]} }
110
- when :date
111
- form.input name, label: false, required: false, value: value,
112
- as: (ActionView::Helpers::FormBuilder.instance_methods.include?(:effective_date_picker) ? :effective_date_picker : :string),
113
- placeholder: placeholder,
114
- input_group: false,
115
- input_html: { name: nil, value: value, title: title, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index]} },
116
- input_js: { useStrict: true, keepInvalid: true }
117
- when :datetime
118
- form.input name, label: false, required: false, value: value,
119
- as: (ActionView::Helpers::FormBuilder.instance_methods.include?(:effective_date_time_picker) ? :effective_date_time_picker : :string),
120
- placeholder: placeholder,
121
- input_group: false,
122
- input_html: { name: nil, value: value, title: title, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index]} },
123
- input_js: { useStrict: true, keepInvalid: true } # Keep invalid format like "2015-11" so we can still filter by year, month or day
124
- when :select, :boolean
125
- form.input name, label: false, required: false, value: value,
126
- as: (ActionView::Helpers::FormBuilder.instance_methods.include?(:effective_select) ? :effective_select : :select),
127
- collection: opts[:filter][:collection],
128
- selected: opts[:filter][:selected],
129
- multiple: opts[:filter][:multiple] == true,
130
- include_blank: include_blank,
131
- input_html: { name: nil, value: value, title: title, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index]} },
132
- input_js: { placeholder: placeholder }
133
- when :grouped_select
134
- form.input name, label: false, required: false, value: value,
135
- as: (ActionView::Helpers::FormBuilder.instance_methods.include?(:effective_select) ? :effective_select : :grouped_select),
136
- collection: opts[:filter][:collection],
137
- selected: opts[:filter][:selected],
138
- multiple: opts[:filter][:multiple] == true,
139
- include_blank: include_blank,
140
- grouped: true,
141
- polymorphic: opts[:filter][:polymorphic] == true,
142
- group_label_method: opts[:filter][:group_label_method] || :first,
143
- group_method: opts[:filter][:group_method] || :last,
144
- input_html: { name: nil, value: value, title: title, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index]} },
145
- input_js: { placeholder: placeholder }
146
- when :bulk_actions_column
147
- form.input name, label: false, required: false, value: nil,
148
- as: :boolean,
149
- input_html: { name: nil, value: nil, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index], 'role' => 'bulk-actions-all'} }
150
- end
151
- end
152
-
153
74
  def datatables_admin_path?
154
75
  @datatables_admin_path ||= (
155
76
  path = request.path.to_s.downcase.chomp('/') + '/'
@@ -163,4 +84,56 @@ module EffectiveDatatablesHelper
163
84
  attributes[:active_admin_path] rescue false
164
85
  end
165
86
 
87
+ ### Icon Helpers for actions_column or elsewhere
88
+ def show_icon_to(path, options = {})
89
+ glyphicon_to('eye-open', path, {title: 'Show'}.merge(options))
90
+ end
91
+
92
+ def edit_icon_to(path, options = {})
93
+ glyphicon_to('edit', path, {title: 'Edit'}.merge(options))
94
+ end
95
+
96
+ def destroy_icon_to(path, options = {})
97
+ defaults = {title: 'Destroy', data: {method: :delete, confirm: 'Delete this item?'}}
98
+ glyphicon_to('trash', path, defaults.merge(options))
99
+ end
100
+
101
+ def archive_icon_to(path, options = {})
102
+ defaults = {title: 'Archive', data: {method: :delete, confirm: 'Archive this item?'}}
103
+ glyphicon_to('trash', path, defaults.merge(options))
104
+ end
105
+
106
+ def unarchive_icon_to(path, options = {})
107
+ defaults = {title: 'Unarchive', data: {confirm: 'Unarchive this item?'}}
108
+ glyphicon_to('retweet', path, defaults.merge(options))
109
+ end
110
+
111
+ def settings_icon_to(path, options = {})
112
+ glyphicon_to('cog', path, {title: 'Settings'}.merge(options))
113
+ end
114
+
115
+ def ok_icon_to(path, options = {})
116
+ glyphicon_to('ok', path, {title: 'OK'}.merge(options))
117
+ end
118
+
119
+ def approve_icon_to(path, options = {})
120
+ glyphicon_to('ok', path, {title: 'Approve'}.merge(options))
121
+ end
122
+
123
+ def remove_icon_to(path, options = {})
124
+ glyphicon_to('remove', path, {title: 'Remove'}.merge(options))
125
+ end
126
+
127
+ def glyphicon_to(icon, path, options = {})
128
+ content_tag(:a, options.merge(href: path)) do
129
+ if icon.start_with?('glyphicon-')
130
+ content_tag(:span, '', class: "glyphicon #{icon}")
131
+ else
132
+ content_tag(:span, '', class: "glyphicon glyphicon-#{icon}")
133
+ end
134
+ end
135
+ end
136
+ alias_method :bootstrap_icon_to, :glyphicon_to
137
+ alias_method :glyph_icon_to, :glyphicon_to
138
+
166
139
  end
@@ -0,0 +1,106 @@
1
+ # These aren't expected to be called by a developer.
2
+ # They are internal datatables methods, but you could still call them on the view.
3
+ module EffectiveDatatablesPrivateHelper
4
+
5
+ def datatable_default_order(datatable)
6
+ [datatable.order_index, datatable.order_direction.downcase].to_json()
7
+ end
8
+
9
+ # https://datatables.net/reference/option/columns
10
+ def datatable_columns(datatable)
11
+ form = nil
12
+ simple_form_for(:datatable_filter, url: '#', html: {id: "#{datatable.to_param}-form"}) { |f| form = f }
13
+
14
+ datatable.table_columns.map do |name, options|
15
+ {
16
+ name: options[:name],
17
+ title: content_tag(:span, options[:label], class: 'filter-label'),
18
+ className: options[:class],
19
+ width: options[:width],
20
+ responsivePriority: (options[:responsivePriority] || 10000), # 10,000 is datatables default
21
+ sortable: (options[:sortable] && !datatable.simple?),
22
+ visible: (options[:visible].respond_to?(:call) ? datatable.instance_exec(&options[:visible]) : options[:visible]),
23
+ filterHtml: (datatable_header_filter(form, name, datatable.search_terms[name], options) unless datatable.simple?),
24
+ filterSelectedValue: options[:filter][:selected]
25
+ }
26
+ end.to_json()
27
+ end
28
+
29
+ def datatable_bulk_actions(datatable)
30
+ bulk_actions_column = datatable.table_columns.find { |_, options| options[:bulk_actions_column] }.try(:second)
31
+ return false unless bulk_actions_column
32
+
33
+ {
34
+ dropdownHtml: render(
35
+ partial: bulk_actions_column[:dropdown_partial],
36
+ locals: { datatable: datatable, dropdown_block: bulk_actions_column[:dropdown_block] }.merge(bulk_actions_column[:partial_locals])
37
+ )
38
+ }.to_json()
39
+ end
40
+
41
+ def datatable_header_filter(form, name, value, opts)
42
+ return render(partial: opts[:header_partial], locals: {form: form, name: (opts[:label] || name), column: opts}) if opts[:header_partial].present?
43
+
44
+ include_blank = opts[:filter].key?(:include_blank) ? opts[:filter][:include_blank] : (opts[:label] || name.titleize)
45
+ pattern = opts[:filter].key?(:pattern) ? opts[:filter][:pattern] : nil
46
+ placeholder = opts[:filter].key?(:placeholder) ? opts[:filter][:placeholder] : (opts[:label] || name.titleize)
47
+ title = opts[:filter].key?(:title) ? opts[:filter][:title] : (opts[:label] || name.titleize)
48
+
49
+ case opts[:filter][:as]
50
+ when :string, :text, :number
51
+ form.input name, label: false, required: false, value: value,
52
+ as: :string,
53
+ placeholder: placeholder,
54
+ input_html: { name: nil, value: value, title: title, pattern: pattern, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index]} }
55
+ when :obfuscated_id
56
+ pattern ||= '[0-9]{3}-?[0-9]{4}-?[0-9]{3}'
57
+ title = opts[:filter].key?(:title) ? opts[:filter][:title] : 'Expected format: XXX-XXXX-XXX'
58
+
59
+ form.input name, label: false, required: false, value: value,
60
+ as: :string,
61
+ placeholder: placeholder,
62
+ input_html: { name: nil, value: value, title: title, pattern: pattern, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index]} }
63
+ when :date
64
+ form.input name, label: false, required: false, value: value,
65
+ as: (ActionView::Helpers::FormBuilder.instance_methods.include?(:effective_date_picker) ? :effective_date_picker : :string),
66
+ placeholder: placeholder,
67
+ input_group: false,
68
+ input_html: { name: nil, value: value, title: title, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index]} },
69
+ input_js: { useStrict: true, keepInvalid: true }
70
+ when :datetime
71
+ form.input name, label: false, required: false, value: value,
72
+ as: (ActionView::Helpers::FormBuilder.instance_methods.include?(:effective_date_time_picker) ? :effective_date_time_picker : :string),
73
+ placeholder: placeholder,
74
+ input_group: false,
75
+ input_html: { name: nil, value: value, title: title, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index]} },
76
+ input_js: { useStrict: true, keepInvalid: true } # Keep invalid format like "2015-11" so we can still filter by year, month or day
77
+ when :select, :boolean
78
+ form.input name, label: false, required: false, value: value,
79
+ as: (ActionView::Helpers::FormBuilder.instance_methods.include?(:effective_select) ? :effective_select : :select),
80
+ collection: opts[:filter][:collection],
81
+ selected: opts[:filter][:selected],
82
+ multiple: opts[:filter][:multiple] == true,
83
+ include_blank: include_blank,
84
+ input_html: { name: nil, value: value, title: title, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index]} },
85
+ input_js: { placeholder: placeholder }
86
+ when :grouped_select
87
+ form.input name, label: false, required: false, value: value,
88
+ as: (ActionView::Helpers::FormBuilder.instance_methods.include?(:effective_select) ? :effective_select : :grouped_select),
89
+ collection: opts[:filter][:collection],
90
+ selected: opts[:filter][:selected],
91
+ multiple: opts[:filter][:multiple] == true,
92
+ include_blank: include_blank,
93
+ grouped: true,
94
+ polymorphic: opts[:filter][:polymorphic] == true,
95
+ group_label_method: opts[:filter][:group_label_method] || :first,
96
+ group_method: opts[:filter][:group_method] || :last,
97
+ input_html: { name: nil, value: value, title: title, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index]} },
98
+ input_js: { placeholder: placeholder }
99
+ when :bulk_actions_column
100
+ form.input name, label: false, required: false, value: nil,
101
+ as: :boolean,
102
+ input_html: { name: nil, value: nil, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index], 'role' => 'bulk-actions-all'} }
103
+ end
104
+ end
105
+
106
+ end
@@ -13,7 +13,7 @@ module Effective
13
13
 
14
14
  def table_column(name, options = {}, proc = nil, &block)
15
15
  if block_given?
16
- raise "You cannot use partial: ... with the block syntax" if options[:partial]
16
+ raise "You cannot use partial: ... with the block syntax" if options[:partial] && !options[:type] == :actions
17
17
  raise "You cannot use proc: ... with the block syntax" if options[:proc]
18
18
  options[:block] = block
19
19
  end
@@ -27,6 +27,8 @@ module Effective
27
27
  end
28
28
 
29
29
  def actions_column(options = {}, proc = nil, &block)
30
+ raise 'first parameter to actions_column should be a hash' unless options.kind_of?(Hash)
31
+
30
32
  show = options.fetch(:show, (EffectiveDatatables.actions_column[:show] rescue false))
31
33
  edit = options.fetch(:edit, (EffectiveDatatables.actions_column[:edit] rescue false))
32
34
  destroy = options.fetch(:destroy, (EffectiveDatatables.actions_column[:destroy] rescue false))
@@ -34,6 +36,7 @@ module Effective
34
36
  name = options.fetch(:name, 'actions')
35
37
 
36
38
  opts = {
39
+ type: :actions,
37
40
  sortable: false,
38
41
  filter: false,
39
42
  responsivePriority: 0,
@@ -41,12 +44,14 @@ module Effective
41
44
  }.merge(options)
42
45
 
43
46
  opts[:partial_local] ||= :resource unless opts[:partial].present?
44
- opts[:partial] ||= '/effective/datatables/actions_column' unless (block_given? || proc.present?)
47
+ opts[:partial] ||= '/effective/datatables/actions_column' unless proc.present?
45
48
 
46
49
  table_column(name, opts, proc, &block)
47
50
  end
48
51
 
49
52
  def bulk_actions_column(options = {}, proc = nil, &block)
53
+ raise 'first parameter to bulk_actions_column should be a hash' unless options.kind_of?(Hash)
54
+
50
55
  name = options.fetch(:name, 'bulk_actions')
51
56
  resource_method = options.fetch(:resource_method, :to_param)
52
57
 
@@ -65,25 +65,7 @@ module Effective
65
65
 
66
66
  locals.merge!(opts[:partial_locals]) if opts[:partial_locals]
67
67
 
68
- if active_record_collection?
69
- if locals[:show_action] == :authorize
70
- locals[:show_action] = (EffectiveDatatables.authorized?(controller, :show, collection_class) rescue false)
71
- end
72
-
73
- if locals[:edit_action] == :authorize
74
- locals[:edit_action] = (EffectiveDatatables.authorized?(controller, :edit, collection_class) rescue false)
75
- end
76
-
77
- if locals[:destroy_action] == :authorize
78
- locals[:destroy_action] = (EffectiveDatatables.authorized?(controller, :destroy, collection_class) rescue false)
79
- end
80
-
81
- if locals[:unarchive_action] == :authorize
82
- locals[:unarchive_action] = (EffectiveDatatables.authorized?(controller, :unarchive, collection_class) rescue false)
83
- end
84
- end
85
-
86
- # If locals[:show_action] == :authorize_each, this will get run again.
68
+ add_actions_column_locals(locals) if opts[:type] == :actions
87
69
 
88
70
  rendered[name] = (render(
89
71
  :partial => opts[:partial],
@@ -101,12 +83,20 @@ module Effective
101
83
  begin
102
84
  if opts[:visible] == false
103
85
  BLANK
104
- elsif opts[:partial]
105
- rendered[name][index]
106
86
  elsif opts[:block]
107
- view.instance_exec(obj, collection, self, &opts[:block])
87
+ begin
88
+ view.instance_exec(obj, collection, self, &opts[:block])
89
+ rescue NoMethodError => e
90
+ if opts[:type] == :actions && e.message == 'super called outside of method'
91
+ rendered[name][index]
92
+ else
93
+ raise(e)
94
+ end
95
+ end
108
96
  elsif opts[:proc]
109
97
  view.instance_exec(obj, collection, self, &opts[:proc])
98
+ elsif opts[:partial]
99
+ rendered[name][index]
110
100
  elsif opts[:type] == :belongs_to
111
101
  (obj.send(name) rescue nil).to_s
112
102
  elsif opts[:type] == :belongs_to_polymorphic
@@ -224,6 +214,122 @@ module Effective
224
214
  end
225
215
  end
226
216
 
217
+ protected
218
+
219
+ def add_actions_column_locals(locals)
220
+ return unless active_record_collection?
221
+
222
+ # Consider authorization levels first
223
+
224
+ if locals[:show_action] == :authorize
225
+ locals[:show_action] = (EffectiveDatatables.authorized?(controller, :show, collection_class) rescue false)
226
+ end
227
+
228
+ if locals[:edit_action] == :authorize
229
+ locals[:edit_action] = (EffectiveDatatables.authorized?(controller, :edit, collection_class) rescue false)
230
+ end
231
+
232
+ if locals[:destroy_action] == :authorize
233
+ locals[:destroy_action] = (EffectiveDatatables.authorized?(controller, :destroy, collection_class) rescue false)
234
+ end
235
+
236
+ if locals[:unarchive_action] == :authorize
237
+ locals[:unarchive_action] = (EffectiveDatatables.authorized?(controller, :unarchive, collection_class) rescue false)
238
+ end
239
+
240
+ # Then we look at the routes to see if these actions _actually_ exist
241
+
242
+ routes = Rails.application.routes
243
+
244
+ begin
245
+ resource = collection_class.new(id: 123)
246
+ resource.define_singleton_method(:persisted?) { true } # We override persisted? to get the correct action urls
247
+ rescue => e
248
+ return
249
+ end
250
+
251
+ if (locals[:show_action] == true || locals[:show_action] == :authorize_each) && !locals[:show_path]
252
+ # Try our namespace
253
+ url = (view.polymorphic_path([*controller_namespace, resource]) rescue false)
254
+ url = false if url && !(routes.recognize_path(url) rescue false)
255
+
256
+ # Try no namespace
257
+ unless url
258
+ url = (view.polymorphic_path(resource) rescue false)
259
+ url = false if url && !(routes.recognize_path(url) rescue false)
260
+ end
261
+
262
+ # So if we have a URL, this is an action we can link to
263
+ if url
264
+ locals[:show_path] = url.gsub('123', ':to_param')
265
+ else
266
+ locals[:show_action] = false
267
+ end
268
+ end
269
+
270
+ if (locals[:edit_action] == true || locals[:edit_action] == :authorize_each) && !locals[:edit_path]
271
+ # Try our namespace
272
+ url = (view.edit_polymorphic_path([*controller_namespace, resource]) rescue false)
273
+ url = false if url && !(routes.recognize_path(url) rescue false)
274
+
275
+ # Try no namespace
276
+ unless url
277
+ url = (view.edit_polymorphic_path(resource) rescue false)
278
+ url = false if url && !(routes.recognize_path(url) rescue false)
279
+ end
280
+
281
+ # So if we have a URL, this is an action we can link to
282
+ if url
283
+ locals[:edit_path] = url.gsub('123', ':to_param')
284
+ else
285
+ locals[:edit_action] = false
286
+ end
287
+ end
288
+
289
+ if (locals[:destroy_action] == true || locals[:destroy_action] == :authorize_each) && !locals[:destroy_path]
290
+ # Try our namespace
291
+ url = (view.polymorphic_path([*controller_namespace, resource]) rescue false)
292
+ url = false if url && !(routes.recognize_path(url, method: :delete) rescue false)
293
+
294
+ # Try no namespace
295
+ unless url
296
+ url = (view.polymorphic_path(resource) rescue false)
297
+ url = false if url && !(routes.recognize_path(url, method: :delete) rescue false)
298
+ end
299
+
300
+ # So if we have a URL, this is an action we can link to
301
+ if url
302
+ locals[:destroy_path] = url.gsub('123', ':to_param')
303
+ else
304
+ locals[:destroy_action] = false
305
+ end
306
+ end
307
+
308
+ if resource.respond_to?(:archived?)
309
+ if (locals[:unarchive_action] == true || locals[:unarchive_action] == :authorize_each) && !locals[:unarchive_path]
310
+ # Try our namespace
311
+ url = (view.polymorphic_path([*controller_namespace, resource], action: :unarchive) rescue false)
312
+ url = false if url && !(routes.recognize_path(url) rescue false)
313
+
314
+ # Try no namespace
315
+ unless url
316
+ url = (view.polymorphic_path(resource, action: :unarchive) rescue false)
317
+ url = false if url && !(routes.recognize_path(url) rescue false)
318
+ end
319
+
320
+ # So if we have a URL, this is an action we can link to
321
+ if url
322
+ locals[:unarchive_path] = url.gsub('123', ':to_param')
323
+ else
324
+ locals[:unarchive_action] = false
325
+ end
326
+ end
327
+ else
328
+ locals[:unarchive_action] = false
329
+ end
330
+
331
+ end
332
+
227
333
  private
228
334
 
229
335
  def controller_namespace
@@ -23,30 +23,18 @@
23
23
  unarchive_action = instance_exec(resource, &unarchive_action)
24
24
  end
25
25
 
26
- - if show_action
27
- - url = (polymorphic_path([*controller_namespace, resource]) rescue nil) || (polymorphic_path(resource) rescue nil)
28
- - if url.present?
29
- %a{href: url, title: 'Show'}
30
- %span.glyphicon.glyphicon-eye-open
26
+ - if show_action && show_path
27
+ = show_icon_to show_path.gsub(':to_param', resource.to_param)
31
28
 
32
- - if edit_action
33
- - url = (edit_polymorphic_path([*controller_namespace, resource]) rescue nil) || (edit_polymorphic_path(resource) rescue nil)
34
- - if url.present?
35
- %a{href: url, title: 'Edit'}
36
- %span.glyphicon.glyphicon-edit
29
+ - if edit_action && edit_path
30
+ = edit_icon_to edit_path.gsub(':to_param', resource.to_param)
37
31
 
38
- - if destroy_action
39
- - url = (polymorphic_path([*controller_namespace, resource]) rescue nil) || (polymorphic_path(resource) rescue nil)
40
- - if url.present?
41
- - if resource.respond_to?(:archived?) && !resource.archived?
42
- %a{href: url, title: 'Archive', data: {method: :delete, confirm: "Are you sure you want to archive this item?"}}
43
- %span.glyphicon.glyphicon-trash
44
- - elsif resource.respond_to?(:archived?) == false
45
- %a{href: url, title: 'Delete', data: {method: :delete, confirm: "Are you sure you want to delete this item?"}}
46
- %span.glyphicon.glyphicon-trash
32
+ - if destroy_action && destroy_path
33
+ - if resource.respond_to?(:archived?) && !resource.archived?
34
+ = archive_icon_to destroy_path.gsub(':to_param', resource.to_param)
35
+ - elsif resource.respond_to?(:archived?) == false
36
+ = destroy_icon_to destroy_path.gsub(':to_param', resource.to_param)
47
37
 
48
- - if unarchive_action && resource.respond_to?(:archived?) && resource.archived?
49
- - url = (polymorphic_path([*controller_namespace, resource], action: :unarchive) rescue nil) || (polymorphic_path(resource, action: :unarchive) rescue nil)
50
- - if url.present?
51
- %a{href: url, title: 'Unarchive', data: {confirm: 'Are you sure you want to unarchive this item?'}}
52
- %span.glyphicon.glyphicon-retweet
38
+ - if unarchive_action && unarchive_path
39
+ - if resource.respond_to?(:archived?) && resource.archived?
40
+ = unarchive_icon_to unarchive_path.gsub(':to_param', resource.to_param)
@@ -8,6 +8,7 @@ module EffectiveDatatables
8
8
  initializer 'effective_datatables.action_controller' do |app|
9
9
  ActiveSupport.on_load :action_controller do
10
10
  helper EffectiveDatatablesHelper
11
+ helper EffectiveDatatablesPrivateHelper
11
12
  end
12
13
  end
13
14
 
@@ -1,3 +1,3 @@
1
1
  module EffectiveDatatables
2
- VERSION = '2.6.13'.freeze
2
+ VERSION = '2.6.14'.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: 2.6.13
4
+ version: 2.6.14
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: 2016-09-29 00:00:00.000000000 Z
11
+ date: 2016-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -135,6 +135,7 @@ files:
135
135
  - app/assets/stylesheets/effective_datatables/_overrides.scss.erb
136
136
  - app/controllers/effective/datatables_controller.rb
137
137
  - app/helpers/effective_datatables_helper.rb
138
+ - app/helpers/effective_datatables_private_helper.rb
138
139
  - app/models/effective/access_denied.rb
139
140
  - app/models/effective/active_record_datatable_tool.rb
140
141
  - app/models/effective/array_datatable_tool.rb