avo 1.9.0 → 1.11.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of avo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -3
- data/app/components/avo/fields/has_one_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/has_one_field/show_component.rb +15 -0
- data/app/components/avo/index/resource_controls_component.html.erb +6 -6
- data/app/components/avo/index/resource_controls_component.rb +10 -1
- data/app/components/avo/resource_component.rb +16 -0
- data/app/components/avo/views/resource_index_component.html.erb +2 -2
- data/app/components/avo/views/resource_index_component.rb +11 -3
- data/app/components/avo/views/resource_show_component.html.erb +5 -2
- data/app/components/avo/views/resource_show_component.rb +5 -1
- data/app/controllers/avo/actions_controller.rb +8 -2
- data/app/controllers/avo/relations_controller.rb +1 -2
- data/app/packs/js/controllers/actions_picker_controller.js +2 -0
- data/app/packs/js/controllers/item_selector_controller.js +18 -6
- data/app/views/avo/base/_actions.html.erb +10 -4
- data/avo.gemspec +0 -1
- data/lib/avo/base_action.rb +10 -2
- data/lib/avo/base_resource.rb +1 -1
- data/lib/avo/services/authorization_service.rb +17 -1
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/action_generator.rb +11 -1
- data/lib/generators/avo/templates/standalone_action.tt +8 -0
- data/public/avo-packs/css/application-797341b7.css.map +1 -1
- data/public/avo-packs/css/application-797341b7.css.map.br +0 -0
- data/public/avo-packs/css/application-797341b7.css.map.gz +0 -0
- data/public/avo-packs/js/application-feb7dddcfb6598273e06.js +26 -0
- data/public/avo-packs/js/{application-651ed7b9bc727c83f673.js.LICENSE.txt → application-feb7dddcfb6598273e06.js.LICENSE.txt} +0 -0
- data/public/avo-packs/js/application-feb7dddcfb6598273e06.js.br +0 -0
- data/public/avo-packs/js/application-feb7dddcfb6598273e06.js.gz +0 -0
- data/public/avo-packs/js/application-feb7dddcfb6598273e06.js.map +1 -0
- data/public/avo-packs/js/application-feb7dddcfb6598273e06.js.map.br +0 -0
- data/public/avo-packs/js/application-feb7dddcfb6598273e06.js.map.gz +0 -0
- data/public/avo-packs/manifest.json +8 -8
- metadata +10 -23
- data/public/avo-packs/js/application-651ed7b9bc727c83f673.js +0 -26
- data/public/avo-packs/js/application-651ed7b9bc727c83f673.js.br +0 -0
- data/public/avo-packs/js/application-651ed7b9bc727c83f673.js.gz +0 -0
- data/public/avo-packs/js/application-651ed7b9bc727c83f673.js.map +0 -1
- data/public/avo-packs/js/application-651ed7b9bc727c83f673.js.map.br +0 -0
- data/public/avo-packs/js/application-651ed7b9bc727c83f673.js.map.gz +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5162ebb15a5e800bfba0e8562395b2fa0c95f368fa22e52a66c276bed0b0e2a2
|
4
|
+
data.tar.gz: 67a79ac90458f4a5ade56121f48fedc402fa23642725b27f8f06882fbb19f948
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2ee41b521694c320cc77d8f534fc6ca1b1c1b13362a3bab671b5f24ffaf7053fb7492b29dab3a832f50577dfb5abcb60011c1eae3a96a8d76689577448eee6a9
|
7
|
+
data.tar.gz: fc53575ea78e71116ca5664ec73adc8069ee289f163f75234fd45ceb725828f29c84396862434a4bb4f661863108d257df8bef35e3be2cb8514f6863853c6f4e
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
avo (1.
|
4
|
+
avo (1.11.0)
|
5
5
|
active_link_to
|
6
6
|
addressable
|
7
7
|
breadcrumbs_on_rails
|
@@ -14,7 +14,6 @@ PATH
|
|
14
14
|
pagy
|
15
15
|
pundit
|
16
16
|
rails (>= 6.0)
|
17
|
-
ransack
|
18
17
|
view_component
|
19
18
|
zeitwerk
|
20
19
|
|
@@ -213,7 +212,7 @@ GEM
|
|
213
212
|
nokogiri (1.11.7-x86_64-linux)
|
214
213
|
racc (~> 1.4)
|
215
214
|
orm_adapter (0.5.0)
|
216
|
-
pagy (4.
|
215
|
+
pagy (4.10.0)
|
217
216
|
parallel (1.20.1)
|
218
217
|
parser (3.0.0.0)
|
219
218
|
ast (~> 2.4.1)
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<% else %>
|
6
6
|
<%= render Avo::PanelComponent.new(title: @field.id.capitalize) do |c| %>
|
7
7
|
<% c.tools do %>
|
8
|
-
<%
|
8
|
+
<% if !@field.readonly && can_attach? %>
|
9
9
|
<%= a_link helpers.resource_attach_path(@resource.model.model_name.route_key, @resource.model.id, @field.id), color: 'indigo', 'data-turbo-frame': 'attach_modal' do %>
|
10
10
|
<%= svg 'view-grid-add' %> <%= t('avo.attach_item', item: @field.id).capitalize %>
|
11
11
|
<% end %>
|
@@ -2,4 +2,19 @@
|
|
2
2
|
|
3
3
|
class Avo::Fields::HasOneField::ShowComponent < Avo::Fields::ShowComponent
|
4
4
|
include Avo::ApplicationHelper
|
5
|
+
|
6
|
+
def can_attach?
|
7
|
+
attach_policy = true
|
8
|
+
if @field.present?
|
9
|
+
reflection_resource = @field.target_resource
|
10
|
+
if reflection_resource.present? && @resource.present?
|
11
|
+
method_name = ('attach_' + reflection_resource.model_class.model_name.singular_route_key.underscore + '?').to_sym
|
12
|
+
defined_policy_methods = @resource.authorization.defined_methods(@resource.model_class, raise_exception: false)
|
13
|
+
if defined_policy_methods.present? && defined_policy_methods.include?(method_name)
|
14
|
+
attach_policy = @resource.authorization.authorize_action(method_name, raise_exception: false)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
attach_policy
|
19
|
+
end
|
5
20
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<% if can_view? %>
|
3
3
|
<%= link_to helpers.svg('eye', class: 'text-gray-400 h-6 hover:text-gray-600'),
|
4
4
|
show_path,
|
5
|
-
title: t('avo.view_item', item:
|
5
|
+
title: t('avo.view_item', item: singular_resource_name).capitalize,
|
6
6
|
data: {
|
7
7
|
control: :show,
|
8
8
|
'tippy': 'tooltip',
|
@@ -13,7 +13,7 @@
|
|
13
13
|
<% if can_edit? %>
|
14
14
|
<%= link_to helpers.svg('edit', class: 'text-gray-400 h-6 hover:text-gray-600'),
|
15
15
|
edit_path,
|
16
|
-
title: t('avo.edit_item', item:
|
16
|
+
title: t('avo.edit_item', item: singular_resource_name).capitalize,
|
17
17
|
data: {
|
18
18
|
control: :edit,
|
19
19
|
'resource-id': @resource.model.id,
|
@@ -27,10 +27,10 @@
|
|
27
27
|
'data-turbo-frame': params[:turbo_frame]
|
28
28
|
} do |form| %>
|
29
29
|
<%= form.button helpers.svg('trash-sm', class: 'text-gray-400 h-6 hover:text-gray-600'),
|
30
|
-
title: t('avo.detach_item', item:
|
30
|
+
title: t('avo.detach_item', item: singular_resource_name).capitalize,
|
31
31
|
type: :submit,
|
32
32
|
data: {
|
33
|
-
confirm: t('avo.are_you_sure_detach_item', item:
|
33
|
+
confirm: t('avo.are_you_sure_detach_item', item: singular_resource_name),
|
34
34
|
control: :detach,
|
35
35
|
'resource-id': @resource.model.id,
|
36
36
|
'tippy': 'tooltip',
|
@@ -46,10 +46,10 @@
|
|
46
46
|
'data-turbo-frame': params[:turbo_frame]
|
47
47
|
} do |form| %>
|
48
48
|
<%= form.button helpers.svg('trash', class: 'text-gray-400 h-6 hover:text-gray-600'),
|
49
|
-
title: t('avo.delete_item', item:
|
49
|
+
title: t('avo.delete_item', item: singular_resource_name).capitalize,
|
50
50
|
type: :submit,
|
51
51
|
data: {
|
52
|
-
confirm: t('avo.are_you_sure', item:
|
52
|
+
confirm: t('avo.are_you_sure', item: singular_resource_name),
|
53
53
|
control: :destroy,
|
54
54
|
'resource-id': @resource.model.id,
|
55
55
|
'tippy': 'tooltip',
|
@@ -10,7 +10,8 @@ class Avo::Index::ResourceControlsComponent < Avo::ResourceComponent
|
|
10
10
|
def can_detach?
|
11
11
|
@reflection.present? &&
|
12
12
|
@resource.model.present? &&
|
13
|
-
(@reflection.is_a?(::ActiveRecord::Reflection::HasManyReflection) || @reflection.is_a?(::ActiveRecord::Reflection::ThroughReflection))
|
13
|
+
(@reflection.is_a?(::ActiveRecord::Reflection::HasManyReflection) || @reflection.is_a?(::ActiveRecord::Reflection::ThroughReflection)) &&
|
14
|
+
authorize_association_for('detach')
|
14
15
|
end
|
15
16
|
|
16
17
|
def can_edit?
|
@@ -36,4 +37,12 @@ class Avo::Index::ResourceControlsComponent < Avo::ResourceComponent
|
|
36
37
|
helpers.edit_resource_path(@resource.model)
|
37
38
|
end
|
38
39
|
end
|
40
|
+
|
41
|
+
def singular_resource_name
|
42
|
+
if @reflection.present?
|
43
|
+
@reflection.name.to_s.downcase.singularize
|
44
|
+
else
|
45
|
+
@resource.singular_name.present? ? @resource.singular_name : @resource.model_class.model_name.name.downcase
|
46
|
+
end
|
47
|
+
end
|
39
48
|
end
|
@@ -7,6 +7,22 @@ class Avo::ResourceComponent < ViewComponent::Base
|
|
7
7
|
@resource.authorization.authorize_action(:destroy, raise_exception: false)
|
8
8
|
end
|
9
9
|
|
10
|
+
def authorize_association_for(policy_method)
|
11
|
+
association_policy = true
|
12
|
+
if @reflection.present?
|
13
|
+
reflection_resource = ::Avo::App.get_resource_by_model_name(@reflection.active_record.name)
|
14
|
+
if reflection_resource.present?
|
15
|
+
method_name = ("#{policy_method}_#{@reflection.name.to_s.underscore}?").to_sym
|
16
|
+
defined_policy_methods = reflection_resource.authorization.defined_methods(reflection_resource.model_class, raise_exception: false)
|
17
|
+
if defined_policy_methods.present? && defined_policy_methods.include?(method_name)
|
18
|
+
association_policy = reflection_resource.authorization.authorize_action(method_name, raise_exception: false)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
association_policy
|
24
|
+
end
|
25
|
+
|
10
26
|
private
|
11
27
|
|
12
28
|
def simple_relation?
|
@@ -11,13 +11,13 @@
|
|
11
11
|
|
12
12
|
<% if can_detach? %>
|
13
13
|
<%= a_link detach_path, color: 'indigo', method: :delete, data: { confirm: "Are you sure you want to detach this #{@resource.singular_name}." } do %>
|
14
|
-
<%= svg 'trash' %> <%= t('avo.detach_item', item:
|
14
|
+
<%= svg 'trash' %> <%= t('avo.detach_item', item: singular_resource_name).capitalize %>
|
15
15
|
<% end %>
|
16
16
|
<% end %>
|
17
17
|
|
18
18
|
<% if can_attach? %>
|
19
19
|
<%= a_link attach_path, color: 'indigo', 'data-turbo-frame': 'attach_modal' do %>
|
20
|
-
<%= svg 'view-grid-add' %> <%= t('avo.attach_item', item:
|
20
|
+
<%= svg 'view-grid-add' %> <%= t('avo.attach_item', item: singular_resource_name).capitalize %>
|
21
21
|
<% end %>
|
22
22
|
<% end %>
|
23
23
|
<% end %>
|
@@ -52,11 +52,11 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
52
52
|
klass = @reflection
|
53
53
|
klass = @reflection.through_reflection if klass.is_a? ::ActiveRecord::Reflection::ThroughReflection
|
54
54
|
|
55
|
-
@reflection.present? && klass.is_a?(::ActiveRecord::Reflection::HasManyReflection) && !has_reflection_and_is_read_only
|
55
|
+
@reflection.present? && klass.is_a?(::ActiveRecord::Reflection::HasManyReflection) && !has_reflection_and_is_read_only && authorize_association_for('attach')
|
56
56
|
end
|
57
57
|
|
58
58
|
def can_detach?
|
59
|
-
@reflection.present? && @reflection.is_a?(::ActiveRecord::Reflection::HasOneReflection) && @models.present? && !has_reflection_and_is_read_only
|
59
|
+
@reflection.present? && @reflection.is_a?(::ActiveRecord::Reflection::HasOneReflection) && @models.present? && !has_reflection_and_is_read_only && authorize_association_for('detach')
|
60
60
|
end
|
61
61
|
|
62
62
|
def has_reflection_and_is_read_only
|
@@ -67,7 +67,7 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
67
67
|
return false
|
68
68
|
end
|
69
69
|
|
70
|
-
if filtered_fields
|
70
|
+
if filtered_fields.present?
|
71
71
|
is_field_read_only = filtered_fields.filter{ |f| f.id == @reflection.name}[0].readonly
|
72
72
|
else
|
73
73
|
is_field_read_only = false
|
@@ -101,6 +101,14 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
101
101
|
helpers.resource_detach_path(via_resource_name, via_resource_id, via_relation_param, @models.first.id)
|
102
102
|
end
|
103
103
|
|
104
|
+
def singular_resource_name
|
105
|
+
if @reflection.present?
|
106
|
+
@reflection.name.to_s.downcase.singularize
|
107
|
+
else
|
108
|
+
@resource.singular_name.present? ? @resource.singular_name : @resource.model_class.model_name.name.downcase
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
104
112
|
private
|
105
113
|
|
106
114
|
def simple_relation?
|
@@ -8,9 +8,12 @@
|
|
8
8
|
<% if resource_panel[:name] == @resource.default_panel_name %>
|
9
9
|
<%= render 'actions' %>
|
10
10
|
|
11
|
+
|
11
12
|
<% if @reflection.present? && @resource.model.present? %>
|
12
|
-
|
13
|
-
<%=
|
13
|
+
<% if can_detach? %>
|
14
|
+
<%= a_link detach_path, color: 'indigo', method: :delete, data: { confirm: "Are you sure you want to detach this #{@reflection.name.to_s}." } do %>
|
15
|
+
<%= svg 'trash' %> <%= t('avo.detach_item', item: @reflection.name.to_s).capitalize %>
|
16
|
+
<% end %>
|
14
17
|
<% end %>
|
15
18
|
<% else %>
|
16
19
|
<%= a_link back_path do %>
|
@@ -30,13 +30,17 @@ class Avo::Views::ResourceShowComponent < Avo::ResourceComponent
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def detach_path
|
33
|
-
helpers.resource_detach_path(params[:resource_name], params[:id], @
|
33
|
+
helpers.resource_detach_path(params[:resource_name], params[:id], @reflection.name.to_s, @resource.model.id)
|
34
34
|
end
|
35
35
|
|
36
36
|
def destroy_path
|
37
37
|
helpers.resource_path(@resource.model)
|
38
38
|
end
|
39
39
|
|
40
|
+
def can_detach?
|
41
|
+
authorize_association_for('detach')
|
42
|
+
end
|
43
|
+
|
40
44
|
private
|
41
45
|
|
42
46
|
def via_resource?
|
@@ -11,14 +11,20 @@ module Avo
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def handle
|
14
|
-
resource_ids = action_params[:fields][:resource_ids].split(",")
|
14
|
+
resource_ids = action_params[:fields][:resource_ids].split(",")
|
15
15
|
models = @resource.class.find_scope.find resource_ids
|
16
16
|
|
17
17
|
fields = action_params[:fields].select do |key, value|
|
18
18
|
key != "resource_ids"
|
19
19
|
end
|
20
20
|
|
21
|
-
|
21
|
+
args = {
|
22
|
+
fields: fields
|
23
|
+
}
|
24
|
+
|
25
|
+
args[:models] = models unless @action.standalone
|
26
|
+
|
27
|
+
performed_action = @action.handle_action(**args)
|
22
28
|
|
23
29
|
respond performed_action.response
|
24
30
|
end
|
@@ -10,7 +10,7 @@ module Avo
|
|
10
10
|
before_action :set_attachment_class
|
11
11
|
before_action :set_attachment_resource
|
12
12
|
before_action :set_attachment_model, only: [:create, :destroy]
|
13
|
-
before_action :set_reflection, only: [:index]
|
13
|
+
before_action :set_reflection, only: [:index, :show]
|
14
14
|
|
15
15
|
def index
|
16
16
|
@parent_resource = @resource.dup
|
@@ -23,7 +23,6 @@ module Avo
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def show
|
26
|
-
@reflection = params[:related_name]
|
27
26
|
@resource, @model = @related_resource, @related_model
|
28
27
|
|
29
28
|
super
|
@@ -22,9 +22,9 @@ export default class extends Controller {
|
|
22
22
|
|
23
23
|
if (this.actionsPanelPresent) {
|
24
24
|
if (value.length > 0) {
|
25
|
-
this.
|
25
|
+
this.enableResourceActions()
|
26
26
|
} else {
|
27
|
-
this.
|
27
|
+
this.disableResourceActions()
|
28
28
|
}
|
29
29
|
}
|
30
30
|
}
|
@@ -58,11 +58,23 @@ export default class extends Controller {
|
|
58
58
|
}
|
59
59
|
}
|
60
60
|
|
61
|
-
|
62
|
-
|
61
|
+
enableResourceActions() {
|
62
|
+
(document.querySelectorAll('.js-actions-dropdown a[data-actions-picker-target="resourceAction"]'))
|
63
|
+
.forEach((link) => {
|
64
|
+
link.classList.add('text-gray-700')
|
65
|
+
link.classList.remove('text-gray-500')
|
66
|
+
link.setAttribute('data-href', link.getAttribute('href'))
|
67
|
+
link.dataset.disabled = false
|
68
|
+
})
|
63
69
|
}
|
64
70
|
|
65
|
-
|
66
|
-
|
71
|
+
disableResourceActions() {
|
72
|
+
(document.querySelectorAll('.js-actions-dropdown a[data-actions-picker-target="resourceAction"]'))
|
73
|
+
.forEach((link) => {
|
74
|
+
link.classList.remove('text-gray-700')
|
75
|
+
link.classList.add('text-gray-500')
|
76
|
+
link.setAttribute('href', link.getAttribute('data-href'))
|
77
|
+
link.dataset.disabled = true
|
78
|
+
})
|
67
79
|
}
|
68
80
|
}
|
@@ -1,10 +1,9 @@
|
|
1
1
|
<% if @actions.count > 0 %>
|
2
|
-
<div class="relative z-30" data-controller="toggle-panel actions-picker">
|
2
|
+
<div class="relative z-30 js-actions-dropdown" data-controller="toggle-panel actions-picker">
|
3
3
|
<%= a_button class: "focus:outline-none",
|
4
4
|
color: 'light-blue',
|
5
5
|
'data-action': "click->toggle-panel#togglePanel",
|
6
|
-
'data-actions-dropdown-button': @resource.plural_name.downcase
|
7
|
-
disabled: action_name != 'show' do
|
6
|
+
'data-actions-dropdown-button': @resource.plural_name.downcase do
|
8
7
|
%>
|
9
8
|
<%= svg 'arrow-left', class: 'h-4 mr-1 transform -rotate-90' %> <%= t 'avo.actions' %>
|
10
9
|
<% end %>
|
@@ -17,11 +16,18 @@
|
|
17
16
|
path = action_name == 'show' ?
|
18
17
|
"#{avo.root_path}resources/#{@resource.model_class.model_name.route_key}/#{@model.id}/actions/#{action.param_id}" :
|
19
18
|
"#{avo.root_path}resources/#{@resource.model_class.model_name.route_key}/actions/#{action.param_id}"
|
19
|
+
if action_name == 'show' || action.standalone
|
20
|
+
disabled = false
|
21
|
+
else
|
22
|
+
disabled = true
|
23
|
+
end
|
20
24
|
%>
|
21
25
|
<%= link_to path,
|
22
26
|
'data-turbo-frame': 'actions_show',
|
23
27
|
'data-action': 'click->actions-picker#visitAction',
|
24
|
-
|
28
|
+
'data-actions-picker-target': action.standalone ? 'standaloneAction' : 'resourceAction',
|
29
|
+
class: "flex items-center w-full py-2 px-4 font-bold text-gray-700 hover:text-white hover:bg-blue-500 #{disabled ? 'text-gray-500' : 'text-gray-700'}",
|
30
|
+
'data-disabled': disabled do %>
|
25
31
|
<%= svg 'play', class: 'h-5 mr-1 inline' %> <%= action.action_name %>
|
26
32
|
<% end %>
|
27
33
|
<% end %>
|
data/avo.gemspec
CHANGED
data/lib/avo/base_action.rb
CHANGED
@@ -13,6 +13,7 @@ module Avo
|
|
13
13
|
class_attribute :user
|
14
14
|
class_attribute :resource
|
15
15
|
class_attribute :fields
|
16
|
+
class_attribute :standalone, default: false
|
16
17
|
|
17
18
|
attr_accessor :response
|
18
19
|
attr_accessor :model
|
@@ -68,7 +69,8 @@ module Avo
|
|
68
69
|
.to_h
|
69
70
|
end
|
70
71
|
|
71
|
-
def handle_action(
|
72
|
+
def handle_action(**args)
|
73
|
+
models, fields = args.values_at(:models, :fields)
|
72
74
|
avo_fields = get_fields.map { |field| [field.id, field] }.to_h
|
73
75
|
|
74
76
|
if fields.present?
|
@@ -81,7 +83,13 @@ module Avo
|
|
81
83
|
processed_fields = {}
|
82
84
|
end
|
83
85
|
|
84
|
-
|
86
|
+
args = {
|
87
|
+
fields: processed_fields
|
88
|
+
}
|
89
|
+
|
90
|
+
args[:models] = models unless standalone
|
91
|
+
|
92
|
+
handle(**args)
|
85
93
|
|
86
94
|
self
|
87
95
|
end
|
data/lib/avo/base_resource.rb
CHANGED
@@ -33,6 +33,10 @@ module Avo
|
|
33
33
|
self.class.apply_policy(user, model)
|
34
34
|
end
|
35
35
|
|
36
|
+
def defined_methods(model, **args)
|
37
|
+
self.class.defined_methods(user, model, **args)
|
38
|
+
end
|
39
|
+
|
36
40
|
class << self
|
37
41
|
def authorize(user, record, action, **args)
|
38
42
|
return true if skip_authorization
|
@@ -56,7 +60,7 @@ module Avo
|
|
56
60
|
end
|
57
61
|
|
58
62
|
def authorize_action(user, record, action, **args)
|
59
|
-
action = Avo.configuration.authorization_methods.stringify_keys[action.to_s]
|
63
|
+
action = Avo.configuration.authorization_methods.stringify_keys[action.to_s] || action
|
60
64
|
|
61
65
|
return true if action.nil?
|
62
66
|
|
@@ -87,6 +91,18 @@ module Avo
|
|
87
91
|
def get_policy(user, record)
|
88
92
|
Pundit.policy user, record
|
89
93
|
end
|
94
|
+
|
95
|
+
def defined_methods(user, record, **args)
|
96
|
+
begin
|
97
|
+
Pundit.policy!(user, record).methods
|
98
|
+
rescue => error
|
99
|
+
if args[:raise_exception] == false
|
100
|
+
false
|
101
|
+
else
|
102
|
+
raise error
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
90
106
|
end
|
91
107
|
end
|
92
108
|
end
|