effective_resources 0.9.5 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/concerns/effective/crud_controller.rb +23 -546
- data/app/controllers/concerns/effective/crud_controller/actions.rb +289 -0
- data/app/controllers/concerns/effective/crud_controller/dsl.rb +81 -0
- data/app/controllers/concerns/effective/crud_controller/paths.rb +87 -0
- data/app/controllers/concerns/effective/crud_controller/permitted_params.rb +66 -0
- data/app/controllers/concerns/effective/crud_controller/save.rb +77 -0
- data/app/controllers/concerns/effective/crud_controller/submits.rb +122 -0
- data/app/helpers/effective_resources_helper.rb +51 -52
- data/app/helpers/effective_resources_private_helper.rb +69 -0
- data/app/models/concerns/effective_resource.rb +24 -0
- data/app/models/effective/model_reader.rb +29 -0
- data/app/models/effective/resource.rb +6 -2
- data/app/models/effective/resources/actions.rb +10 -10
- data/app/models/effective/resources/associations.rb +5 -0
- data/app/models/effective/resources/attributes.rb +40 -27
- data/app/models/effective/resources/controller.rb +81 -0
- data/app/models/effective/resources/forms.rb +0 -51
- data/app/models/effective/resources/init.rb +19 -17
- data/app/models/effective/resources/klass.rb +6 -8
- data/app/models/effective/resources/model.rb +23 -0
- data/app/models/effective/resources/naming.rb +7 -3
- data/app/models/effective/resources/paths.rb +4 -63
- data/app/models/effective/resources/relation.rb +4 -1
- data/app/models/effective/resources/sql.rb +1 -1
- data/app/views/application/create.js.erb +1 -1
- data/app/views/application/edit.html.haml +2 -2
- data/app/views/application/index.html.haml +1 -1
- data/app/views/application/member_action.js.erb +1 -1
- data/app/views/application/new.html.haml +3 -1
- data/app/views/application/show.html.haml +1 -1
- data/app/views/application/update.js.erb +1 -1
- data/app/views/effective/resource/_actions.html.haml +3 -32
- data/app/views/effective/resource/_actions_dropleft.html.haml +4 -26
- data/app/views/effective/resource/_actions_glyphicons.html.haml +4 -10
- data/lib/effective_resources/engine.rb +1 -0
- data/lib/effective_resources/version.rb +1 -1
- metadata +14 -3
@@ -0,0 +1,66 @@
|
|
1
|
+
module Effective
|
2
|
+
module CrudController
|
3
|
+
module PermittedParams
|
4
|
+
BLACKLIST = [:created_at, :updated_at]
|
5
|
+
|
6
|
+
# This is only available to models that use the effective_resource do ... end attributes block
|
7
|
+
# It will be called last, and only for those resources
|
8
|
+
# params.require(effective_resource.name).permit!
|
9
|
+
def resource_permitted_params
|
10
|
+
raise 'expected resource class to have effective_resource do .. end' if effective_resource.model.blank?
|
11
|
+
|
12
|
+
permitted_params = permitted_params_for(resource)
|
13
|
+
|
14
|
+
if Rails.env.development?
|
15
|
+
Rails.logger.info "Effective::CrudController#resource_permitted_params:"
|
16
|
+
Rails.logger.info "params.require(:#{effective_resource.name}).permit(#{permitted_params.to_s[1...-1]})"
|
17
|
+
end
|
18
|
+
|
19
|
+
params.require(effective_resource.name).permit(*permitted_params)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def permitted_params_for(resource)
|
25
|
+
effective_resource = if resource.kind_of?(Class)
|
26
|
+
resource.effective_resource if resource.respond_to?(:effective_resource)
|
27
|
+
else
|
28
|
+
resource.class.effective_resource if resource.class.respond_to?(:effective_resource)
|
29
|
+
end
|
30
|
+
|
31
|
+
# That class doesn't implement effective_resource do .. end block
|
32
|
+
return [] unless effective_resource.present?
|
33
|
+
|
34
|
+
# This is :id, all belongs_to ids, and model attributes
|
35
|
+
permitted_params = effective_resource.permitted_attributes.select do |name, (_, atts)|
|
36
|
+
if BLACKLIST.include?(name)
|
37
|
+
false
|
38
|
+
elsif atts.blank? || !atts.key?(:permitted)
|
39
|
+
true # Default is true
|
40
|
+
else
|
41
|
+
permitted = (atts[:permitted].respond_to?(:call) ? instance_exec(&atts[:permitted]) : atts[:permitted])
|
42
|
+
|
43
|
+
if permitted == true || permitted == false
|
44
|
+
permitted
|
45
|
+
elsif permitted == nil || permitted == :blank
|
46
|
+
effective_resource.namespaces.length == 0
|
47
|
+
else # A symbol, string, or array of, representing the namespace
|
48
|
+
(effective_resource.namespaces & Array(permitted).map(&:to_s)).present?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end.keys
|
52
|
+
|
53
|
+
# Recursively add any accepts_nested_resources
|
54
|
+
effective_resource.nested_resources.each do |nested|
|
55
|
+
if (nested_params = permitted_params_for(nested.klass)).present?
|
56
|
+
nested_params.insert(nested_params.rindex { |obj| !obj.kind_of?(Hash)} + 1, :_destroy)
|
57
|
+
permitted_params << { "#{nested.plural_name}_attributes".to_sym => nested_params }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
permitted_params
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Effective
|
2
|
+
module CrudController
|
3
|
+
module Save
|
4
|
+
|
5
|
+
# Based on the incoming params[:commit] or passed action. Merges all options.
|
6
|
+
def commit_action(action = nil)
|
7
|
+
config = (['create', 'update'].include?(params[:action]) ? self.class.submits : self.class.buttons)
|
8
|
+
|
9
|
+
commit = if action.present?
|
10
|
+
config[action.to_s] || config.find { |_, v| v[:action] == action }.try(:last) || { action: action }
|
11
|
+
else
|
12
|
+
config[params[:commit].to_s] || config.find { |_, v| v[:action] == :save }.try(:last) || { action: :save }
|
13
|
+
end
|
14
|
+
|
15
|
+
commit.reverse_merge!(self.class.ons[commit[:action]]) if self.class.ons[commit[:action]]
|
16
|
+
|
17
|
+
commit
|
18
|
+
end
|
19
|
+
|
20
|
+
# This calls the appropriate member action, probably save!, on the resource.
|
21
|
+
def save_resource(resource, action = :save, &block)
|
22
|
+
raise "expected @#{resource_name} to respond to #{action}!" unless resource.respond_to?("#{action}!")
|
23
|
+
|
24
|
+
resource.current_user ||= current_user if resource.respond_to?(:current_user=)
|
25
|
+
|
26
|
+
ActiveRecord::Base.transaction do
|
27
|
+
begin
|
28
|
+
if resource.public_send("#{action}!") == false
|
29
|
+
raise("failed to #{action} #{resource}")
|
30
|
+
end
|
31
|
+
|
32
|
+
yield if block_given?
|
33
|
+
|
34
|
+
run_callbacks(:resource_save)
|
35
|
+
return true
|
36
|
+
rescue => e
|
37
|
+
Rails.logger.info "Failed to #{action}: #{e.message}" if Rails.env.development?
|
38
|
+
|
39
|
+
if resource.respond_to?(:restore_attributes) && resource.persisted?
|
40
|
+
resource.restore_attributes(['status', 'state'])
|
41
|
+
end
|
42
|
+
|
43
|
+
flash.delete(:success)
|
44
|
+
flash.now[:danger] = flash_danger(resource, action, e: e)
|
45
|
+
raise ActiveRecord::Rollback
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
run_callbacks(:resource_error)
|
50
|
+
false
|
51
|
+
end
|
52
|
+
|
53
|
+
def resource_flash(status, resource, action)
|
54
|
+
submit = commit_action(action)
|
55
|
+
message = submit[status].respond_to?(:call) ? instance_exec(&submit[status]) : submit[status]
|
56
|
+
return message if message.present?
|
57
|
+
|
58
|
+
case status
|
59
|
+
when :success then flash_success(resource, action)
|
60
|
+
when :danger then flash_danger(resource, action)
|
61
|
+
else
|
62
|
+
raise "unknown resource flash status: #{status}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def reload_resource
|
67
|
+
self.resource.reload if resource.respond_to?(:reload)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Should return a new resource based on the passed one
|
71
|
+
def duplicate_resource(resource)
|
72
|
+
resource.dup
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module Effective
|
2
|
+
module CrudController
|
3
|
+
module Submits
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
# { 'Save' => { action: save, ...}}
|
8
|
+
def submits
|
9
|
+
@_effective_submits ||= effective_resource.submits
|
10
|
+
end
|
11
|
+
|
12
|
+
# { 'Approve' => { action: approve, ...}}
|
13
|
+
def buttons
|
14
|
+
@_effective_buttons ||= effective_resource.buttons
|
15
|
+
end
|
16
|
+
|
17
|
+
# { :approve => { redirect: .. }}
|
18
|
+
def ons
|
19
|
+
@_effective_ons ||= effective_resource.ons
|
20
|
+
end
|
21
|
+
|
22
|
+
# :only, :except, :if, :unless, :redirect, :success, :danger, :class
|
23
|
+
def _insert_submit(action, label = nil, args = {})
|
24
|
+
raise 'expected args to be a Hash or false' unless args.kind_of?(Hash) || args == false
|
25
|
+
|
26
|
+
if label == false
|
27
|
+
submits.delete_if { |label, args| args[:action] == action }; return
|
28
|
+
end
|
29
|
+
|
30
|
+
if args == false
|
31
|
+
submits.delete(label); return
|
32
|
+
end
|
33
|
+
|
34
|
+
if label # Overwrite the default member action when given a custom submit
|
35
|
+
submits.delete_if { |label, args| args[:default] && args[:action] == action }
|
36
|
+
end
|
37
|
+
|
38
|
+
if args.key?(:if) && args[:if].respond_to?(:call) == false
|
39
|
+
raise "expected if: to be callable. Try submit :approve, 'Save and Approve', if: -> { finished? }"
|
40
|
+
end
|
41
|
+
|
42
|
+
if args.key?(:unless) && args[:unless].respond_to?(:call) == false
|
43
|
+
raise "expected unless: to be callable. Try submit :approve, 'Save and Approve', unless: -> { declined? }"
|
44
|
+
end
|
45
|
+
|
46
|
+
if args.key?(:only)
|
47
|
+
args[:only] = Array(args[:only])
|
48
|
+
raise "expected only: to be a symbol or array of symbols. Try submit :approve, 'Save and Approve', only: [:edit]" unless args[:only].all? { |v| v.kind_of?(Symbol) }
|
49
|
+
end
|
50
|
+
|
51
|
+
if args.key?(:except)
|
52
|
+
args[:except] = Array(args[:except])
|
53
|
+
raise "expected except: to be a symbol or array of symbols. Try submit :approve, 'Save and Approve', except: [:edit]" unless args[:except].all? { |v| v.kind_of?(Symbol) }
|
54
|
+
end
|
55
|
+
|
56
|
+
if args.key?(:redirect_to) # Normalize this option to redirect
|
57
|
+
args[:redirect] = args.delete(:redirect_to)
|
58
|
+
end
|
59
|
+
|
60
|
+
args[:action] = action
|
61
|
+
|
62
|
+
(submits[label] ||= {}).merge!(args)
|
63
|
+
end
|
64
|
+
|
65
|
+
def _insert_button(action, label = nil, args = {})
|
66
|
+
raise 'expected args to be a Hash or false' unless args.kind_of?(Hash) || args == false
|
67
|
+
|
68
|
+
if label == false
|
69
|
+
buttons.delete_if { |label, args| args[:action] == action }; return
|
70
|
+
end
|
71
|
+
|
72
|
+
if args == false
|
73
|
+
buttons.delete(label); return
|
74
|
+
end
|
75
|
+
|
76
|
+
if label # Overwrite the default member action when given a custom label
|
77
|
+
buttons.delete_if { |label, args| args[:default] && args[:action] == action }
|
78
|
+
end
|
79
|
+
|
80
|
+
if args.key?(:if) && args[:if].respond_to?(:call) == false
|
81
|
+
raise "expected if: to be callable. Try button :approve, 'Approve', if: -> { finished? }"
|
82
|
+
end
|
83
|
+
|
84
|
+
if args.key?(:unless) && args[:unless].respond_to?(:call) == false
|
85
|
+
raise "expected unless: to be callable. Try button :approve, 'Approve', unless: -> { declined? }"
|
86
|
+
end
|
87
|
+
|
88
|
+
if args.key?(:only)
|
89
|
+
args[:only] = Array(args[:only])
|
90
|
+
raise "expected only: to be a symbol or array of symbols. Try button :approve, 'Save and Approve', only: [:edit]" unless args[:only].all? { |v| v.kind_of?(Symbol) }
|
91
|
+
end
|
92
|
+
|
93
|
+
if args.key?(:except)
|
94
|
+
args[:except] = Array(args[:except])
|
95
|
+
raise "expected except: to be a symbol or array of symbols. Try button :approve, 'Save and Approve', except: [:edit]" unless args[:except].all? { |v| v.kind_of?(Symbol) }
|
96
|
+
end
|
97
|
+
|
98
|
+
if args.key?(:redirect_to) # Normalize this option to redirect
|
99
|
+
args[:redirect] = args.delete(:redirect_to)
|
100
|
+
end
|
101
|
+
|
102
|
+
args[:action] = action
|
103
|
+
|
104
|
+
(buttons[label] ||= {}).merge!(args)
|
105
|
+
end
|
106
|
+
|
107
|
+
def _insert_on(action, args = {})
|
108
|
+
raise 'expected args to be a Hash' unless args.kind_of?(Hash)
|
109
|
+
|
110
|
+
if args.key?(:redirect_to) # Normalize this option to redirect
|
111
|
+
args[:redirect] = args.delete(:redirect_to)
|
112
|
+
end
|
113
|
+
|
114
|
+
args[:action] = action
|
115
|
+
|
116
|
+
(ons[action] ||= {}).merge!(args)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -1,41 +1,49 @@
|
|
1
1
|
module EffectiveResourcesHelper
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
actions =
|
6
|
-
|
3
|
+
# effective_bootstrap
|
4
|
+
def effective_submit(form, options = {}, &block)
|
5
|
+
actions = (controller.respond_to?(:effective_resource) ? controller.class : find_effective_resource).submits
|
6
|
+
actions = permitted_resource_actions(form.object, actions)
|
7
|
+
|
8
|
+
submits = actions.map { |name, opts| form.save(name, opts.except(:action, :title, 'data-method', 'data-confirm')) }.join.html_safe
|
7
9
|
|
8
10
|
form.submit('', options) do
|
9
|
-
(block_given? ? capture(&block) : ''.html_safe) +
|
11
|
+
(block_given? ? capture(&block) : ''.html_safe) + submits
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
13
15
|
# effective_form_inputs
|
14
16
|
def simple_form_submit(form, options = {}, &block)
|
15
|
-
|
16
|
-
actions =
|
17
|
+
actions = (controller.respond_to?(:effective_resource) ? controller.class : find_effective_resource).submits
|
18
|
+
actions = permitted_resource_actions(form.object, actions)
|
17
19
|
|
18
|
-
|
20
|
+
submits = actions.map { |name, opts| form.button(:submit, name, opts.except(:action, :title, 'data-method', 'data-confirm')) }.join(' ').html_safe
|
19
21
|
|
20
22
|
# I think this is a bug. I can't override default button class when passing my own class: variable. it merges them.
|
21
|
-
if
|
22
|
-
|
23
|
+
if (btn_class = SimpleForm.button_class).present?
|
24
|
+
submits = submits.map { |submit| submit.sub(btn_class, '') }
|
23
25
|
end
|
24
26
|
|
25
27
|
wrapper_options = { class: 'form-actions' }.merge(options.delete(:wrapper_html) || {})
|
26
28
|
|
27
29
|
content_tag(:div, wrapper_options) do
|
28
|
-
(block_given? ? capture(&block) : ''.html_safe) +
|
30
|
+
(block_given? ? capture(&block) : ''.html_safe) + submits
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
32
|
-
def
|
33
|
-
|
34
|
-
|
34
|
+
def render_resource_buttons(resource, atts = {}, &block)
|
35
|
+
effective_resource = find_effective_resource
|
36
|
+
actions = (controller.respond_to?(:effective_resource) ? controller.class : effective_resource).buttons
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
+
actions = if resource.kind_of?(Class)
|
39
|
+
actions.select { |_, v| effective_resource.collection_get_actions.include?(v[:action]) }
|
40
|
+
elsif resource.respond_to?(:persisted?) && resource.persisted?
|
41
|
+
actions.select { |_, v| effective_resource.member_actions.include?(v[:action]) }
|
42
|
+
else
|
43
|
+
{}
|
38
44
|
end
|
45
|
+
|
46
|
+
render_resource_actions(resource, atts.merge(actions: actions), &block)
|
39
47
|
end
|
40
48
|
|
41
49
|
# Renders the effective/resource view partial for this resource
|
@@ -46,29 +54,34 @@ module EffectiveResourcesHelper
|
|
46
54
|
# partial: :dropleft|:glyphicons|string
|
47
55
|
# locals: {} render locals
|
48
56
|
# you can also pass all action names and true/false such as edit: true, show: false
|
49
|
-
def render_resource_actions(resource,
|
50
|
-
|
51
|
-
raise 'expected first argument to be an Effective::Resource' unless resource.kind_of?(Effective::Resource)
|
57
|
+
def render_resource_actions(resource, atts = {}, &block)
|
58
|
+
raise 'expected first argument to be an ActiveRecord::Base object or Array of objects' unless resource.kind_of?(ActiveRecord::Base) || resource.kind_of?(Class) || resource.kind_of?(Array)
|
52
59
|
raise 'expected attributes to be a Hash' unless atts.kind_of?(Hash)
|
53
60
|
|
54
61
|
locals = atts.delete(:locals) || {}
|
55
|
-
namespace = atts.delete(:namespace) || (resource.namespace.to_sym if resource.namespace)
|
56
62
|
partial = atts.delete(:partial)
|
57
63
|
spacer_template = locals.delete(:spacer_template)
|
58
64
|
|
59
|
-
|
60
|
-
|
65
|
+
effective_resource = (atts.delete(:effective_resource) || find_effective_resource)
|
66
|
+
actions = atts.delete(:actions) || effective_resource.resource_actions
|
67
|
+
namespace = atts.delete(:namespace) || (effective_resource.namespace.to_sym if effective_resource.namespace)
|
61
68
|
|
62
|
-
|
63
|
-
|
69
|
+
# Filter Actions
|
70
|
+
action_keys = actions.map { |_, v| v[:action] }
|
71
|
+
raise "unknown action for #{effective_resource.name}: #{(atts.keys - action_keys).join(' ')}." if (atts.keys - action_keys).present?
|
72
|
+
actions = actions.select { |_, v| atts[v[:action]].respond_to?(:call) ? instance_exec(&atts[v[:action]]) : (atts[v[:action]] != false) }
|
64
73
|
|
65
|
-
|
66
|
-
|
74
|
+
# Select Partial
|
75
|
+
partial = ['effective/resource/actions', partial.to_s].join('_') if partial.kind_of?(Symbol)
|
76
|
+
partial = (partial.presence || 'effective/resource/actions') + '.html'
|
67
77
|
|
68
|
-
|
78
|
+
# Assign Locals
|
79
|
+
locals = { resource: resource, effective_resource: effective_resource, namespace: namespace, actions: actions }.compact.merge(locals)
|
69
80
|
|
70
|
-
|
71
|
-
|
81
|
+
# Render
|
82
|
+
if resource.kind_of?(Array)
|
83
|
+
locals[:format_block] = block if block_given?
|
84
|
+
render(partial: partial, collection: resource, as: :resource, locals: locals.except(:resource), spacer_template: spacer_template)
|
72
85
|
elsif block_given?
|
73
86
|
render(partial, locals) { yield }
|
74
87
|
else
|
@@ -77,43 +90,29 @@ module EffectiveResourcesHelper
|
|
77
90
|
end
|
78
91
|
|
79
92
|
# When called from /admin/things/new.html.haml this will render 'admin/things/form', or 'things/form', or 'thing/form'
|
80
|
-
def render_resource_form(resource,
|
81
|
-
|
82
|
-
raise 'expected first argument to be an Effective::Resource' unless resource.kind_of?(Effective::Resource)
|
93
|
+
def render_resource_form(resource, atts = {})
|
94
|
+
raise 'expected first argument to be an ActiveRecord::Base object' unless resource.kind_of?(ActiveRecord::Base)
|
83
95
|
raise 'expected attributes to be a Hash' unless atts.kind_of?(Hash)
|
84
96
|
|
85
|
-
|
86
|
-
raise "unable to find resource instance. Either pass the instance as the second argument, or assign @#{resource.name}" unless instance
|
97
|
+
effective_resource = (atts.delete(:effective_resource) || find_effective_resource)
|
87
98
|
|
88
99
|
action = atts.delete(:action)
|
89
|
-
atts = { :namespace => (
|
100
|
+
atts = { :namespace => (effective_resource.namespace.to_sym if effective_resource.namespace), effective_resource.name.to_sym => resource }.compact.merge(atts)
|
90
101
|
|
91
102
|
if lookup_context.template_exists?("form_#{action}", controller._prefixes, :partial)
|
92
103
|
render "form_#{action}", atts
|
93
104
|
elsif lookup_context.template_exists?('form', controller._prefixes, :partial)
|
94
105
|
render 'form', atts
|
95
|
-
elsif lookup_context.template_exists?('form',
|
96
|
-
render "#{
|
97
|
-
elsif lookup_context.template_exists?('form',
|
98
|
-
render "#{
|
106
|
+
elsif lookup_context.template_exists?('form', effective_resource.plural_name, :partial)
|
107
|
+
render "#{effective_resource.plural_name}/form", atts
|
108
|
+
elsif lookup_context.template_exists?('form', effective_resource.name, :partial)
|
109
|
+
render "#{effective_resource.name}/form", atts
|
99
110
|
else
|
100
111
|
render 'form', atts # Will raise the regular error
|
101
112
|
end
|
102
113
|
end
|
103
114
|
|
104
|
-
|
105
|
-
duration = duration.to_i
|
106
|
-
value = duration.abs
|
107
|
-
|
108
|
-
[
|
109
|
-
('-' if duration < 0),
|
110
|
-
("#{value / 60}h " if value >= 60),
|
111
|
-
("#{'%0.2d' % (value % 60)}m" if value > 0),
|
112
|
-
('0m' if value == 0),
|
113
|
-
].compact.join
|
114
|
-
end
|
115
|
-
|
116
|
-
### Tableize attributes
|
115
|
+
# Tableize attributes
|
117
116
|
# This is used by effective_orders, effective_logging, effective_trash and effective_mergery
|
118
117
|
def tableize_hash(obj, table: 'table', th: true, sub_table: 'table', sub_th: true, flatten: true)
|
119
118
|
case obj
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module EffectiveResourcesPrivateHelper
|
2
|
+
REPLACE_PAGE_ACTIONS = {'update' => :edit, 'create' => :new}
|
3
|
+
|
4
|
+
def permitted_resource_actions(resource, actions, effective_resource = nil)
|
5
|
+
effective_resource ||= find_effective_resource
|
6
|
+
|
7
|
+
page_action = REPLACE_PAGE_ACTIONS[params[:action]] || params[:action]&.to_sym || :save
|
8
|
+
|
9
|
+
actions.select do |commit, args|
|
10
|
+
action = (args[:action] == :save ? (resource.new_record? ? :create : :update) : args[:action])
|
11
|
+
|
12
|
+
(args.key?(:only) ? args[:only].include?(page_action) : true) &&
|
13
|
+
(args.key?(:except) ? !args[:except].include?(page_action) : true) &&
|
14
|
+
(args.key?(:if) ? controller.instance_exec(&args[:if]) : true) &&
|
15
|
+
(args.key?(:unless) ? !controller.instance_exec(&args[:unless]) : true) &&
|
16
|
+
EffectiveResources.authorized?(controller, action, resource)
|
17
|
+
end.transform_values.with_index do |opts, index|
|
18
|
+
action = opts[:action]
|
19
|
+
|
20
|
+
# Transform data: { ... } hash into 'data-' keys
|
21
|
+
data.each { |k, v| opts["data-#{k}"] ||= v } if (data = opts.delete(:data))
|
22
|
+
|
23
|
+
# Assign data method and confirm
|
24
|
+
if effective_resource.member_post_actions.include?(action)
|
25
|
+
opts['data-method'] ||= :post
|
26
|
+
opts['data-confirm'] ||= "Really #{action} @resource?"
|
27
|
+
elsif effective_resource.member_delete_actions.include?(action)
|
28
|
+
opts['data-method'] ||= :delete
|
29
|
+
opts['data-confirm'] ||= "Really #{action == :destroy ? 'delete' : action.to_s.titleize} @resource?"
|
30
|
+
end
|
31
|
+
|
32
|
+
# Assign class
|
33
|
+
opts[:class] ||= (
|
34
|
+
if opts['data-method'] == :delete
|
35
|
+
'btn btn-danger'
|
36
|
+
elsif index == 0
|
37
|
+
'btn btn-primary'
|
38
|
+
elsif defined?(EffectiveBootstrap)
|
39
|
+
'btn btn-secondary'
|
40
|
+
else
|
41
|
+
'btn btn-default'
|
42
|
+
end
|
43
|
+
)
|
44
|
+
|
45
|
+
# Assign title
|
46
|
+
unless action == :save
|
47
|
+
opts[:title] ||= case action
|
48
|
+
when :edit then "Edit #{resource}"
|
49
|
+
when :show then "#{resource}"
|
50
|
+
when :destroy then "Delete #{resource}"
|
51
|
+
when :index then "All #{effective_resource.human_plural_name.titleize}"
|
52
|
+
else "#{action.to_s.titleize} #{resource}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Replace resource name in any token strings
|
57
|
+
if opts['data-confirm']
|
58
|
+
opts['data-confirm'].gsub!('@resource', (resource.to_s.presence || effective_resource.human_name))
|
59
|
+
end
|
60
|
+
|
61
|
+
opts.except(:default, :only, :except, :if, :unless, :redirect, :success, :danger)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def find_effective_resource
|
66
|
+
@_effective_resource ||= (controller.respond_to?(:effective_resource) ? controller.effective_resource : Effective::Resource.new(controller_path))
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|