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.

Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -2
  3. data/Gemfile.lock +7 -6
  4. data/app/assets/stylesheets/avo.css +1 -4
  5. data/app/assets/stylesheets/css/sidebar.css +28 -0
  6. data/app/components/avo/fields/date_field/show_component.html.erb +4 -0
  7. data/app/components/avo/fields/date_time_field/index_component.html.erb +1 -0
  8. data/app/components/avo/fields/date_time_field/show_component.html.erb +1 -0
  9. data/app/components/avo/fields/has_one_field/show_component.html.erb +1 -1
  10. data/app/components/avo/fields/has_one_field/show_component.rb +7 -6
  11. data/app/components/avo/fields/text_field/index_component.html.erb +2 -0
  12. data/app/components/avo/fields/text_field/show_component.html.erb +2 -0
  13. data/app/components/avo/index/field_wrapper_component.html.erb +4 -0
  14. data/app/components/avo/index/resource_controls_component.rb +7 -5
  15. data/app/components/avo/index/resource_table_component.html.erb +1 -1
  16. data/app/components/avo/index/resource_table_component.rb +2 -1
  17. data/app/components/avo/index/table_row_component.html.erb +1 -1
  18. data/app/components/avo/index/table_row_component.rb +2 -1
  19. data/app/components/avo/item_switcher_component.rb +2 -0
  20. data/app/components/avo/panel_component.html.erb +2 -4
  21. data/app/components/avo/panel_component.rb +0 -4
  22. data/app/components/avo/resource_component.rb +14 -27
  23. data/app/components/avo/sidebar/link_component.rb +4 -1
  24. data/app/components/avo/sidebar_component.html.erb +2 -2
  25. data/app/components/avo/tab_group_component.html.erb +1 -2
  26. data/app/components/avo/tab_switcher_component.rb +4 -0
  27. data/app/components/avo/views/resource_edit_component.html.erb +30 -8
  28. data/app/components/avo/views/resource_edit_component.rb +4 -8
  29. data/app/components/avo/views/resource_index_component.html.erb +1 -1
  30. data/app/components/avo/views/resource_index_component.rb +5 -3
  31. data/app/components/avo/views/resource_show_component.html.erb +14 -2
  32. data/app/components/avo/views/resource_show_component.rb +3 -3
  33. data/app/controllers/avo/application_controller.rb +24 -9
  34. data/app/controllers/avo/associations_controller.rb +38 -12
  35. data/app/controllers/avo/base_controller.rb +5 -3
  36. data/app/javascript/js/controllers/fields/date_field_controller.js +11 -1
  37. data/app/javascript/js/controllers/sidebar_controller.js +46 -0
  38. data/app/javascript/js/controllers.js +2 -2
  39. data/app/views/avo/base/edit.html.erb +0 -1
  40. data/app/views/avo/base/index.html.erb +1 -0
  41. data/app/views/avo/base/show.html.erb +7 -1
  42. data/app/views/avo/partials/_javascript.html.erb +1 -0
  43. data/app/views/avo/partials/_navbar.html.erb +5 -2
  44. data/app/views/layouts/avo/application.html.erb +3 -3
  45. data/avo.gemspec +1 -1
  46. data/lib/avo/base_action.rb +8 -6
  47. data/lib/avo/base_resource.rb +2 -5
  48. data/lib/avo/concerns/has_fields.rb +5 -0
  49. data/lib/avo/concerns/has_html_attributes.rb +1 -1
  50. data/lib/avo/fields/has_base_field.rb +11 -0
  51. data/lib/avo/fields/text_field.rb +4 -2
  52. data/lib/avo/services/authorization_service.rb +41 -37
  53. data/lib/avo/version.rb +1 -1
  54. data/lib/avo.rb +1 -0
  55. data/public/avo-assets/avo.css +51 -15
  56. data/public/avo-assets/avo.js +68 -67
  57. data/public/avo-assets/avo.js.map +3 -3
  58. metadata +10 -10
  59. data/app/javascript/js/controllers/mobile_controller.js +0 -9
  60. 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 = eager_load_files(@related_resource, @related_resource.class.find_scope).find params[:related_id]
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 authorize_action
162
- if @model.present?
163
- @authorization.set_record(@model).authorize_action action_name.to_sym
164
- else
165
- @authorization.set_record(@resource.model_class).authorize_action action_name.to_sym
166
- end
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
- { **super, force_locale: params[:force_locale] }
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 :hydrate_related_resource, only: [:show, :index, :new, :create, :destroy, :order]
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 :set_reflection, only: [:index, :show, :order]
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 = @model._reflections[params[:related_name].to_s].klass
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 = @model._reflections[params[:related_name].to_s].klass.find attachment_id
109
+ @attachment_model = @attachment_class.find attachment_id
106
110
  end
107
111
 
108
- def set_reflection
109
- @reflection = @model._reflections[params[:related_name].to_s]
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
- before_action :authorize_action
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 { |action| action.visible_in_view }
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
- this.context.element.innerText = this.parsedValue.setZone(this.displayTimezone).toFormat(this.formatValue)
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,2 +1 @@
1
1
  <%= render Avo::Views::ResourceEditComponent.new(resource: @resource, view: @view, actions: @actions) %>
2
-
@@ -10,6 +10,7 @@
10
10
  reflection: @reflection,
11
11
  turbo_frame: params[:turbo_frame],
12
12
  parent_model: @parent_model,
13
+ parent_resource: @parent_resource,
13
14
  applied_filters: @applied_filters,
14
15
  )
15
16
  %>
@@ -1,3 +1,9 @@
1
1
  <%= render Avo::TurboFrameWrapperComponent.new(params[:turbo_frame]) do %>
2
- <%= render Avo::Views::ResourceShowComponent.new(resource: @resource, reflection: @reflection, actions: @actions) %>
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 lg:space-x-0 w-auto lg:w-64 flex-shrink-0 h-full">
6
- <%= a_button class: 'lg:hidden', icon: 'menu', size: :xs, compact: true, style: :text, data: { action: 'click->mobile#toggleSidebar' } %>
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="mobile">
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="lg:pl-64 flex-1 flex flex-col min-h-full max-w-full">
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"
@@ -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]
@@ -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?
@@ -58,7 +58,7 @@ module Avo
58
58
  end
59
59
  .to_h
60
60
 
61
- extra_attributes.merge attributes
61
+ attributes.merge extra_attributes
62
62
  else
63
63
  attributes
64
64
  end
@@ -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
- @link_to_resource = args[:link_to_resource].present? ? args[:link_to_resource] : false
11
- @as_html = args[:as_html].present? ? args[:as_html] : false
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
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "2.11.0" unless const_defined?(:VERSION)
2
+ VERSION = "2.11.1.pre.3" unless const_defined?(:VERSION)
3
3
  end
data/lib/avo.rb CHANGED
@@ -39,6 +39,7 @@ module Avo
39
39
  ROOT_PATH = Pathname.new(File.join(__dir__, ".."))
40
40
  IN_DEVELOPMENT = ENV["AVO_IN_DEVELOPMENT"] == "1"
41
41
  PACKED = !IN_DEVELOPMENT
42
+ COOKIES_KEY = "avo"
42
43
 
43
44
  class LicenseVerificationTemperedError < StandardError; end
44
45