avo 2.11.0 → 2.11.1.pre.3
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 +0 -2
- data/Gemfile.lock +7 -6
- data/app/assets/stylesheets/avo.css +1 -4
- data/app/assets/stylesheets/css/sidebar.css +28 -0
- data/app/components/avo/fields/date_field/show_component.html.erb +4 -0
- data/app/components/avo/fields/date_time_field/index_component.html.erb +1 -0
- data/app/components/avo/fields/date_time_field/show_component.html.erb +1 -0
- 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 +7 -6
- data/app/components/avo/fields/text_field/index_component.html.erb +2 -0
- data/app/components/avo/fields/text_field/show_component.html.erb +2 -0
- data/app/components/avo/index/field_wrapper_component.html.erb +4 -0
- data/app/components/avo/index/resource_controls_component.rb +7 -5
- data/app/components/avo/index/resource_table_component.html.erb +1 -1
- data/app/components/avo/index/resource_table_component.rb +2 -1
- data/app/components/avo/index/table_row_component.html.erb +1 -1
- data/app/components/avo/index/table_row_component.rb +2 -1
- data/app/components/avo/item_switcher_component.rb +2 -0
- data/app/components/avo/panel_component.html.erb +2 -4
- data/app/components/avo/panel_component.rb +0 -4
- data/app/components/avo/resource_component.rb +14 -27
- data/app/components/avo/sidebar/link_component.rb +4 -1
- data/app/components/avo/sidebar_component.html.erb +2 -2
- data/app/components/avo/tab_group_component.html.erb +1 -2
- data/app/components/avo/tab_switcher_component.rb +4 -0
- data/app/components/avo/views/resource_edit_component.html.erb +30 -8
- data/app/components/avo/views/resource_edit_component.rb +4 -8
- data/app/components/avo/views/resource_index_component.html.erb +1 -1
- data/app/components/avo/views/resource_index_component.rb +5 -3
- data/app/components/avo/views/resource_show_component.html.erb +14 -2
- data/app/components/avo/views/resource_show_component.rb +3 -3
- data/app/controllers/avo/application_controller.rb +24 -9
- data/app/controllers/avo/associations_controller.rb +38 -12
- data/app/controllers/avo/base_controller.rb +5 -3
- data/app/javascript/js/controllers/fields/date_field_controller.js +11 -1
- data/app/javascript/js/controllers/sidebar_controller.js +46 -0
- data/app/javascript/js/controllers.js +2 -2
- data/app/views/avo/base/edit.html.erb +0 -1
- data/app/views/avo/base/index.html.erb +1 -0
- data/app/views/avo/base/show.html.erb +7 -1
- data/app/views/avo/partials/_javascript.html.erb +1 -0
- data/app/views/avo/partials/_navbar.html.erb +5 -2
- data/app/views/layouts/avo/application.html.erb +3 -3
- data/avo.gemspec +1 -1
- data/lib/avo/base_action.rb +8 -6
- data/lib/avo/base_resource.rb +2 -5
- data/lib/avo/concerns/has_fields.rb +5 -0
- data/lib/avo/concerns/has_html_attributes.rb +1 -1
- data/lib/avo/fields/has_base_field.rb +11 -0
- data/lib/avo/fields/text_field.rb +4 -2
- data/lib/avo/services/authorization_service.rb +41 -37
- data/lib/avo/version.rb +1 -1
- data/lib/avo.rb +1 -0
- data/public/avo-assets/avo.css +51 -15
- data/public/avo-assets/avo.js +68 -67
- data/public/avo-assets/avo.js.map +3 -3
- metadata +10 -10
- data/app/javascript/js/controllers/mobile_controller.js +0 -9
- data/lib/avo/has_context.rb +0 -7
@@ -21,6 +21,7 @@ module Avo
|
|
21
21
|
before_action :set_container_classes
|
22
22
|
before_action :add_initial_breadcrumbs
|
23
23
|
before_action :set_view
|
24
|
+
before_action :set_sidebar_open
|
24
25
|
|
25
26
|
rescue_from Pundit::NotAuthorizedError, with: :render_unauthorized
|
26
27
|
rescue_from ActiveRecord::RecordInvalid, with: :exception_logger
|
@@ -129,7 +130,11 @@ module Avo
|
|
129
130
|
end
|
130
131
|
|
131
132
|
def set_related_model
|
132
|
-
@related_model =
|
133
|
+
@related_model = if @field.is_a? Avo::Fields::HasOneField
|
134
|
+
@model.send params[:related_name]
|
135
|
+
else
|
136
|
+
eager_load_files(@related_resource, @model.send(params[:related_name])).find params[:related_id]
|
137
|
+
end
|
133
138
|
end
|
134
139
|
|
135
140
|
def set_view
|
@@ -155,15 +160,20 @@ module Avo
|
|
155
160
|
end
|
156
161
|
|
157
162
|
def hydrate_related_resource
|
158
|
-
@related_resource.hydrate(view: action_name.to_sym, user: _current_user)
|
163
|
+
@related_resource.hydrate(view: action_name.to_sym, user: _current_user, model: @model)
|
159
164
|
end
|
160
165
|
|
161
|
-
def
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
166
|
+
def authorize_base_action
|
167
|
+
class_to_authorize = @model || @resource.model_class
|
168
|
+
|
169
|
+
authorize_action class_to_authorize
|
170
|
+
end
|
171
|
+
|
172
|
+
def authorize_action(class_to_authorize, action = nil)
|
173
|
+
# Use the provided action or figure it out from the request
|
174
|
+
action_to_authorize = action || action_name
|
175
|
+
|
176
|
+
@authorization.set_record(class_to_authorize).authorize_action action_to_authorize.to_sym
|
167
177
|
end
|
168
178
|
|
169
179
|
# Get the pluralized resource name for this request
|
@@ -310,10 +320,15 @@ module Avo
|
|
310
320
|
|
311
321
|
def default_url_options
|
312
322
|
if params[:force_locale].present?
|
313
|
-
{
|
323
|
+
{**super, force_locale: params[:force_locale]}
|
314
324
|
else
|
315
325
|
super
|
316
326
|
end
|
317
327
|
end
|
328
|
+
|
329
|
+
def set_sidebar_open
|
330
|
+
value = cookies["#{Avo::COOKIES_KEY}.sidebar.open"]
|
331
|
+
@sidebar_open = value.blank? || value == '1'
|
332
|
+
end
|
318
333
|
end
|
319
334
|
end
|
@@ -5,12 +5,16 @@ module Avo
|
|
5
5
|
before_action :set_model, only: [:show, :index, :new, :create, :destroy, :order]
|
6
6
|
before_action :set_related_resource_name
|
7
7
|
before_action :set_related_resource, only: [:show, :index, :new, :create, :destroy, :order]
|
8
|
-
before_action :
|
8
|
+
before_action :set_reflection_field
|
9
|
+
before_action :hydrate_related_resource, only: [:show, :index, :create, :destroy, :order]
|
9
10
|
before_action :set_related_model, only: [:show, :order]
|
11
|
+
before_action :set_reflection
|
10
12
|
before_action :set_attachment_class, only: [:show, :index, :new, :create, :destroy, :order]
|
11
13
|
before_action :set_attachment_resource, only: [:show, :index, :new, :create, :destroy, :order]
|
12
14
|
before_action :set_attachment_model, only: [:create, :destroy, :order]
|
13
|
-
before_action :
|
15
|
+
before_action :authorize_index_action, only: :index
|
16
|
+
before_action :authorize_attach_action, only: :new
|
17
|
+
before_action :authorize_detach_action, only: :destroy
|
14
18
|
|
15
19
|
def index
|
16
20
|
@parent_resource = @resource.dup
|
@@ -28,6 +32,8 @@ module Avo
|
|
28
32
|
end
|
29
33
|
|
30
34
|
def show
|
35
|
+
@parent_resource, @parent_model = @resource, @model
|
36
|
+
|
31
37
|
@resource, @model = @related_resource, @related_model
|
32
38
|
|
33
39
|
super
|
@@ -36,12 +42,6 @@ module Avo
|
|
36
42
|
def new
|
37
43
|
@resource.hydrate(model: @model)
|
38
44
|
|
39
|
-
begin
|
40
|
-
@field = @resource.get_field_definitions.find { |f| f.id == @related_resource_name.to_sym }
|
41
|
-
@field.hydrate(resource: @resource, model: @model, view: :new)
|
42
|
-
rescue
|
43
|
-
end
|
44
|
-
|
45
45
|
if @field.present? && !@field.searchable
|
46
46
|
query = @authorization.apply_policy @attachment_class
|
47
47
|
|
@@ -93,8 +93,12 @@ module Avo
|
|
93
93
|
|
94
94
|
private
|
95
95
|
|
96
|
+
def set_reflection
|
97
|
+
@reflection = @model._reflections[params[:related_name].to_s]
|
98
|
+
end
|
99
|
+
|
96
100
|
def set_attachment_class
|
97
|
-
@attachment_class = @
|
101
|
+
@attachment_class = @reflection.klass
|
98
102
|
end
|
99
103
|
|
100
104
|
def set_attachment_resource
|
@@ -102,11 +106,13 @@ module Avo
|
|
102
106
|
end
|
103
107
|
|
104
108
|
def set_attachment_model
|
105
|
-
@attachment_model = @
|
109
|
+
@attachment_model = @attachment_class.find attachment_id
|
106
110
|
end
|
107
111
|
|
108
|
-
def
|
109
|
-
@
|
112
|
+
def set_reflection_field
|
113
|
+
@field = @resource.get_field_definitions.find { |f| f.id == @related_resource_name.to_sym }
|
114
|
+
@field.hydrate(resource: @resource, model: @model, view: :new)
|
115
|
+
rescue
|
110
116
|
end
|
111
117
|
|
112
118
|
def attachment_id
|
@@ -121,5 +127,25 @@ module Avo
|
|
121
127
|
|
122
128
|
klass
|
123
129
|
end
|
130
|
+
|
131
|
+
def authorize_if_defined(method)
|
132
|
+
@authorization.set_record(@model)
|
133
|
+
|
134
|
+
if @authorization.has_method?(method.to_sym)
|
135
|
+
@authorization.authorize_action method.to_sym
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def authorize_index_action
|
140
|
+
authorize_if_defined "view_#{@field.id}?"
|
141
|
+
end
|
142
|
+
|
143
|
+
def authorize_attach_action
|
144
|
+
authorize_if_defined "attach_#{@field.id}?"
|
145
|
+
end
|
146
|
+
|
147
|
+
def authorize_detach_action
|
148
|
+
authorize_if_defined "detach_#{@field.id}?"
|
149
|
+
end
|
124
150
|
end
|
125
151
|
end
|
@@ -10,7 +10,8 @@ module Avo
|
|
10
10
|
before_action :set_model_to_fill
|
11
11
|
before_action :set_edit_title_and_breadcrumbs, only: [:edit, :update]
|
12
12
|
before_action :fill_model, only: [:create, :update]
|
13
|
-
|
13
|
+
# Don't run base authorizations for associations
|
14
|
+
before_action :authorize_base_action, if: -> {controller_name != "associations"}
|
14
15
|
|
15
16
|
def index
|
16
17
|
@page_title = @resource.plural_name.humanize
|
@@ -320,7 +321,9 @@ module Avo
|
|
320
321
|
.map do |action|
|
321
322
|
action.new(model: @model, resource: @resource, view: @view)
|
322
323
|
end
|
323
|
-
.select
|
324
|
+
.select do |action|
|
325
|
+
action.visible_in_view
|
326
|
+
end
|
324
327
|
end
|
325
328
|
|
326
329
|
def set_applied_filters
|
@@ -380,7 +383,6 @@ module Avo
|
|
380
383
|
|
381
384
|
add_breadcrumb via_resource.plural_name, resources_path(resource: @resource)
|
382
385
|
add_breadcrumb via_resource.model_title, resource_path(model: via_model, resource: via_resource)
|
383
|
-
puts ["via_resource.model_title->", via_resource.model_title].inspect
|
384
386
|
|
385
387
|
last_crumb_args = {
|
386
388
|
via_resource_class: params[:via_resource_class],
|
@@ -68,7 +68,14 @@ export default class extends Controller {
|
|
68
68
|
|
69
69
|
// Turns the value in the controller wrapper into the timezone of the browser
|
70
70
|
initShow() {
|
71
|
-
|
71
|
+
let value = this.parsedValue
|
72
|
+
|
73
|
+
// Set the zone only if the type of field is date time.
|
74
|
+
if (this.enableTimeValue) {
|
75
|
+
value = value.setZone(this.displayTimezone)
|
76
|
+
}
|
77
|
+
|
78
|
+
this.context.element.innerText = value.toFormat(this.formatValue)
|
72
79
|
}
|
73
80
|
|
74
81
|
initEdit() {
|
@@ -99,10 +106,13 @@ export default class extends Controller {
|
|
99
106
|
|
100
107
|
// enable timezone display
|
101
108
|
if (this.enableTimeValue) {
|
109
|
+
console.log(1)
|
102
110
|
options.defaultDate = this.parsedValue.setZone(this.displayTimezone).toISO()
|
103
111
|
|
104
112
|
options.dateFormat = 'Y-m-d H:i:S'
|
105
113
|
} else {
|
114
|
+
console.log(2)
|
115
|
+
|
106
116
|
// Because the browser treats the date like a timestamp and updates it at 00:00 hour, when on a western timezone the date will be converted with one day offset.
|
107
117
|
// Ex: 2022-01-30 will render as 2022-01-29 on an American timezone
|
108
118
|
options.defaultDate = universalTimestamp(this.initialValue)
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus'
|
2
|
+
import Cookies from 'js-cookie'
|
3
|
+
|
4
|
+
export default class extends Controller {
|
5
|
+
static targets = ['sidebar', 'mainArea']
|
6
|
+
|
7
|
+
static values = {
|
8
|
+
open: Boolean,
|
9
|
+
}
|
10
|
+
|
11
|
+
get cookieKey() {
|
12
|
+
return `${window.Avo.configuration.cookies_key}.sidebar.open`
|
13
|
+
}
|
14
|
+
|
15
|
+
get sidebarOpen() {
|
16
|
+
return Cookies.get(this.cookieKey) === '1'
|
17
|
+
}
|
18
|
+
|
19
|
+
set cookie(state) {
|
20
|
+
Cookies.set(this.cookieKey, state === true ? 1 : 0)
|
21
|
+
}
|
22
|
+
|
23
|
+
markSidebarClosed() {
|
24
|
+
Cookies.set(this.cookieKey, '0')
|
25
|
+
this.openValue = false
|
26
|
+
this.mainAreaTarget.classList.remove('sidebar-open')
|
27
|
+
}
|
28
|
+
|
29
|
+
markSidebarOpen() {
|
30
|
+
Cookies.set(this.cookieKey, '1')
|
31
|
+
this.openValue = true
|
32
|
+
this.mainAreaTarget.classList.add('sidebar-open')
|
33
|
+
}
|
34
|
+
|
35
|
+
toggleSidebar() {
|
36
|
+
if (this.openValue) {
|
37
|
+
this.markSidebarClosed()
|
38
|
+
} else {
|
39
|
+
this.markSidebarOpen()
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
toggleSidebarOnMobile() {
|
44
|
+
this.sidebarTarget.classList.toggle('hidden')
|
45
|
+
}
|
46
|
+
}
|
@@ -16,7 +16,6 @@ import ItemSelectorController from './controllers/item_selector_controller'
|
|
16
16
|
import KeyValueController from './controllers/fields/key_value_controller'
|
17
17
|
import LoadingButtonController from './controllers/loading_button_controller'
|
18
18
|
import MenuController from './controllers/menu_controller'
|
19
|
-
import MobileController from './controllers/mobile_controller'
|
20
19
|
import ModalController from './controllers/modal_controller'
|
21
20
|
import MultipleSelectFilterController from './controllers/multiple_select_filter_controller'
|
22
21
|
import PerPageController from './controllers/per_page_controller'
|
@@ -26,6 +25,7 @@ import ResourceShowController from './controllers/resource_show_controller'
|
|
26
25
|
import SearchController from './controllers/search_controller'
|
27
26
|
import SelectController from './controllers/select_controller'
|
28
27
|
import SelectFilterController from './controllers/select_filter_controller'
|
28
|
+
import SidebarController from './controllers/sidebar_controller'
|
29
29
|
import SimpleMdeController from './controllers/fields/simple_mde_controller'
|
30
30
|
import TabsController from './controllers/tabs_controller'
|
31
31
|
import TagsFieldController from './controllers/fields/tags_field_controller'
|
@@ -46,7 +46,6 @@ application.register('item-select-all', ItemSelectAllController)
|
|
46
46
|
application.register('item-selector', ItemSelectorController)
|
47
47
|
application.register('loading-button', LoadingButtonController)
|
48
48
|
application.register('menu', MenuController)
|
49
|
-
application.register('mobile', MobileController)
|
50
49
|
application.register('modal', ModalController)
|
51
50
|
application.register('multiple-select-filter', MultipleSelectFilterController)
|
52
51
|
application.register('per-page', PerPageController)
|
@@ -56,6 +55,7 @@ application.register('resource-show', ResourceShowController)
|
|
56
55
|
application.register('search', SearchController)
|
57
56
|
application.register('select', SelectController)
|
58
57
|
application.register('select-filter', SelectFilterController)
|
58
|
+
application.register('sidebar', SidebarController)
|
59
59
|
application.register('tabs', TabsController)
|
60
60
|
application.register('tags-field', TagsFieldController)
|
61
61
|
application.register('text-filter', TextFilterController)
|
@@ -1,3 +1,9 @@
|
|
1
1
|
<%= render Avo::TurboFrameWrapperComponent.new(params[:turbo_frame]) do %>
|
2
|
-
<%= render Avo::Views::ResourceShowComponent.new(
|
2
|
+
<%= render Avo::Views::ResourceShowComponent.new(
|
3
|
+
resource: @resource,
|
4
|
+
reflection: @reflection,
|
5
|
+
actions: @actions,
|
6
|
+
parent_model: @parent_model,
|
7
|
+
parent_resource: @parent_resource,
|
8
|
+
) %>
|
3
9
|
<% end %>
|
@@ -3,4 +3,5 @@
|
|
3
3
|
Avo.configuration.timezone = '<%= Avo.configuration.timezone %>'
|
4
4
|
Avo.configuration.root_path = '<%= root_path_without_url %>'
|
5
5
|
Avo.configuration.search_debounce = '<%= Avo.configuration.search_debounce %>'
|
6
|
+
Avo.configuration.cookies_key = '<%= Avo::COOKIES_KEY %>'
|
6
7
|
<% end %>
|
@@ -2,8 +2,11 @@
|
|
2
2
|
class="fixed bg-white p-2 w-full flex flex-shrink-0 items-center z-50 px-4 lg:px-4 border-b space-x-4 lg:space-x-0 h-16 <%= 'print:hidden' if Avo.configuration.hide_layout_when_printing %>"
|
3
3
|
v-if="layout !== 'blank'"
|
4
4
|
>
|
5
|
-
<div class="flex items-center space-x-2
|
6
|
-
|
5
|
+
<div class="flex items-center space-x-2 w-auto lg:w-64 flex-shrink-0 h-full">
|
6
|
+
<div>
|
7
|
+
<%= a_button class: 'lg:hidden', icon: 'menu', size: :xs, compact: true, style: :text, data: { action: 'click->sidebar#toggleSidebarOnMobile' } %>
|
8
|
+
<%= a_button class: 'hidden lg:block', icon: 'menu', size: :xs, compact: true, style: :text, data: { action: 'click->sidebar#toggleSidebar' } %>
|
9
|
+
</div>
|
7
10
|
<%= render partial: "avo/partials/logo" %>
|
8
11
|
</div>
|
9
12
|
<div class="flex-1 flex items-center justify-between lg:justify-start space-x-2 sm:space-x-8 lg:pl-4">
|
@@ -19,12 +19,12 @@
|
|
19
19
|
<% end %>
|
20
20
|
</head>
|
21
21
|
<body class="bg-gray-25 os-mac">
|
22
|
-
<div class="relative flex flex-1 w-full min-h-full" data-controller="
|
22
|
+
<div class="relative flex flex-1 w-full min-h-full" data-controller="sidebar" data-sidebar-open-value="<%= @sidebar_open %>">
|
23
23
|
<div class="flex-1 flex flex-col max-w-full">
|
24
24
|
<%= render partial: "avo/partials/navbar" %>
|
25
|
-
<div class="flex-1 flex pt-16 relative">
|
25
|
+
<div data-sidebar-target="mainArea" class="content-area flex-1 flex pt-16 relative <%= 'sidebar-open' if @sidebar_open %>">
|
26
26
|
<%= render Avo::SidebarComponent.new %>
|
27
|
-
<div class="
|
27
|
+
<div class="main-content-area flex-1 flex flex-col min-h-full max-w-full">
|
28
28
|
<div class="content p-4 lg:p-6 flex-1 flex flex-col justify-between items-stretch <%= @container_classes %>">
|
29
29
|
<%= render partial: "avo/partials/custom_tools_alert" %>
|
30
30
|
<div class="flex flex-1 flex-col justify-between items-stretch space-y-8">
|
data/avo.gemspec
CHANGED
@@ -40,7 +40,7 @@ Gem::Specification.new do |spec|
|
|
40
40
|
spec.add_dependency "httparty"
|
41
41
|
spec.add_dependency "active_link_to"
|
42
42
|
spec.add_dependency "image_processing"
|
43
|
-
spec.add_dependency "view_component"
|
43
|
+
spec.add_dependency "view_component", "2.60"
|
44
44
|
spec.add_dependency "hotwire-rails"
|
45
45
|
spec.add_dependency "addressable"
|
46
46
|
spec.add_dependency "meta-tags"
|
data/lib/avo/base_action.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
module Avo
|
2
2
|
class BaseAction
|
3
|
-
extend HasContext
|
4
|
-
|
5
3
|
include Avo::Concerns::HasFields
|
6
4
|
|
7
5
|
class_attribute :name, default: nil
|
@@ -23,8 +21,16 @@ module Avo
|
|
23
21
|
attr_accessor :user
|
24
22
|
|
25
23
|
delegate :view, to: :class
|
24
|
+
delegate :context, to: ::Avo::App
|
25
|
+
delegate :current_user, to: ::Avo::App
|
26
|
+
delegate :params, to: ::Avo::App
|
27
|
+
delegate :view_context, to: ::Avo::App
|
28
|
+
delegate :avo, to: :view_context
|
29
|
+
delegate :main_app, to: :view_context
|
26
30
|
|
27
31
|
class << self
|
32
|
+
delegate :context, to: ::Avo::App
|
33
|
+
|
28
34
|
def form_data_attributes
|
29
35
|
# We can't respond with a file download from Turbo se we disable it on the form
|
30
36
|
if may_download_file
|
@@ -64,10 +70,6 @@ module Avo
|
|
64
70
|
@response[:messages] = []
|
65
71
|
end
|
66
72
|
|
67
|
-
def context
|
68
|
-
self.class.context
|
69
|
-
end
|
70
|
-
|
71
73
|
def get_attributes_for_action
|
72
74
|
get_fields.map do |field|
|
73
75
|
[field.id, field.value]
|
data/lib/avo/base_resource.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
module Avo
|
2
2
|
class BaseResource
|
3
3
|
extend ActiveSupport::DescendantsTracker
|
4
|
-
extend HasContext
|
5
4
|
|
6
5
|
include ActionView::Helpers::UrlHelper
|
7
6
|
include Avo::Concerns::HasModel
|
@@ -18,6 +17,7 @@ module Avo
|
|
18
17
|
delegate :resource_path, to: :view_context
|
19
18
|
delegate :resources_path, to: :view_context
|
20
19
|
delegate :t, to: ::I18n
|
20
|
+
delegate :context, to: ::Avo::App
|
21
21
|
|
22
22
|
attr_accessor :view
|
23
23
|
attr_accessor :model
|
@@ -50,6 +50,7 @@ module Avo
|
|
50
50
|
|
51
51
|
class << self
|
52
52
|
delegate :t, to: ::I18n
|
53
|
+
delegate :context, to: ::Avo::App
|
53
54
|
|
54
55
|
def grid(&block)
|
55
56
|
grid_collector = GridCollector.new
|
@@ -244,10 +245,6 @@ module Avo
|
|
244
245
|
view_types
|
245
246
|
end
|
246
247
|
|
247
|
-
def context
|
248
|
-
self.class.context
|
249
|
-
end
|
250
|
-
|
251
248
|
def attached_file_fields
|
252
249
|
get_field_definitions.select do |field|
|
253
250
|
[Avo::Fields::FileField, Avo::Fields::FilesField].include? field.class
|
@@ -252,9 +252,14 @@ module Avo
|
|
252
252
|
if item.respond_to? :visible_on?
|
253
253
|
next unless item.visible_on?(view)
|
254
254
|
end
|
255
|
+
# each field has it's own visibility checker
|
255
256
|
if item.respond_to? :visible?
|
256
257
|
next unless item.visible?
|
257
258
|
end
|
259
|
+
# check if the user is authorized to view it
|
260
|
+
if item.respond_to? :authorized?
|
261
|
+
next unless item.hydrate(model: @model).authorized?
|
262
|
+
end
|
258
263
|
|
259
264
|
if item.is_field?
|
260
265
|
if item.has_own_panel?
|
@@ -78,6 +78,17 @@ module Avo
|
|
78
78
|
|
79
79
|
super view
|
80
80
|
end
|
81
|
+
|
82
|
+
def authorized?
|
83
|
+
method = "view_#{id}?".to_sym
|
84
|
+
service = resource.authorization
|
85
|
+
|
86
|
+
if service.has_method? method
|
87
|
+
service.authorize_action(method, raise_exception: false)
|
88
|
+
else
|
89
|
+
true
|
90
|
+
end
|
91
|
+
end
|
81
92
|
end
|
82
93
|
end
|
83
94
|
end
|
@@ -3,12 +3,14 @@ module Avo
|
|
3
3
|
class TextField < BaseField
|
4
4
|
attr_reader :link_to_resource
|
5
5
|
attr_reader :as_html
|
6
|
+
attr_reader :protocol
|
6
7
|
|
7
8
|
def initialize(id, **args, &block)
|
8
9
|
super(id, **args, &block)
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
add_boolean_prop args, :link_to_resource
|
12
|
+
add_boolean_prop args, :as_html
|
13
|
+
add_string_prop args, :protocol
|
12
14
|
end
|
13
15
|
end
|
14
16
|
end
|
@@ -4,43 +4,6 @@ module Avo
|
|
4
4
|
attr_accessor :user
|
5
5
|
attr_accessor :record
|
6
6
|
|
7
|
-
def initialize(user = nil, record = nil)
|
8
|
-
@user = user
|
9
|
-
@record = record
|
10
|
-
end
|
11
|
-
|
12
|
-
def authorize(action, **args)
|
13
|
-
self.class.authorize(user, record, action, **args)
|
14
|
-
end
|
15
|
-
|
16
|
-
def set_record(record)
|
17
|
-
@record = record
|
18
|
-
|
19
|
-
self
|
20
|
-
end
|
21
|
-
|
22
|
-
def set_user(user)
|
23
|
-
@user = user
|
24
|
-
|
25
|
-
self
|
26
|
-
end
|
27
|
-
|
28
|
-
def authorize_action(action, **args)
|
29
|
-
self.class.authorize_action(user, record, action, **args)
|
30
|
-
end
|
31
|
-
|
32
|
-
def apply_policy(model)
|
33
|
-
self.class.apply_policy(user, model)
|
34
|
-
end
|
35
|
-
|
36
|
-
def defined_methods(model, **args)
|
37
|
-
self.class.defined_methods(user, model, **args)
|
38
|
-
end
|
39
|
-
|
40
|
-
def has_method?(method, **args)
|
41
|
-
self.class.defined_methods(user, record, **args).include? method.to_sym
|
42
|
-
end
|
43
|
-
|
44
7
|
class << self
|
45
8
|
def authorize(user, record, action, **args)
|
46
9
|
return true if skip_authorization
|
@@ -111,6 +74,10 @@ module Avo
|
|
111
74
|
|
112
75
|
def defined_methods(user, record, **args)
|
113
76
|
Pundit.policy!(user, record).methods
|
77
|
+
rescue Pundit::NotDefinedError => e
|
78
|
+
return [] unless Avo.configuration.raise_error_on_missing_policy
|
79
|
+
|
80
|
+
raise e
|
114
81
|
rescue => error
|
115
82
|
if args[:raise_exception] == false
|
116
83
|
[]
|
@@ -119,6 +86,43 @@ module Avo
|
|
119
86
|
end
|
120
87
|
end
|
121
88
|
end
|
89
|
+
|
90
|
+
def initialize(user = nil, record = nil)
|
91
|
+
@user = user
|
92
|
+
@record = record
|
93
|
+
end
|
94
|
+
|
95
|
+
def authorize(action, **args)
|
96
|
+
self.class.authorize(user, record, action, **args)
|
97
|
+
end
|
98
|
+
|
99
|
+
def set_record(record)
|
100
|
+
@record = record
|
101
|
+
|
102
|
+
self
|
103
|
+
end
|
104
|
+
|
105
|
+
def set_user(user)
|
106
|
+
@user = user
|
107
|
+
|
108
|
+
self
|
109
|
+
end
|
110
|
+
|
111
|
+
def authorize_action(action, **args)
|
112
|
+
self.class.authorize_action(user, record, action, **args)
|
113
|
+
end
|
114
|
+
|
115
|
+
def apply_policy(model)
|
116
|
+
self.class.apply_policy(user, model)
|
117
|
+
end
|
118
|
+
|
119
|
+
def defined_methods(model, **args)
|
120
|
+
self.class.defined_methods(user, model, **args)
|
121
|
+
end
|
122
|
+
|
123
|
+
def has_method?(method, **args)
|
124
|
+
defined_methods(record, **args).include? method.to_sym
|
125
|
+
end
|
122
126
|
end
|
123
127
|
end
|
124
128
|
end
|
data/lib/avo/version.rb
CHANGED