avo 2.11.1.pre.2 → 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.lock +1 -1
- 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/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/resource_component.rb +11 -5
- data/app/components/avo/sidebar_component.html.erb +2 -2
- data/app/components/avo/tab_switcher_component.rb +4 -0
- data/app/components/avo/views/resource_edit_component.rb +4 -6
- 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 +1 -1
- data/app/components/avo/views/resource_show_component.rb +3 -1
- 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 +2 -1
- data/app/javascript/js/controllers/sidebar_controller.js +46 -0
- data/app/javascript/js/controllers.js +2 -2
- 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/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 +43 -11
- data/public/avo-assets/avo.js +68 -67
- data/public/avo-assets/avo.js.map +3 -3
- metadata +4 -3
- data/app/javascript/js/controllers/mobile_controller.js +0 -9
@@ -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">
|
@@ -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
data/lib/avo.rb
CHANGED
data/public/avo-assets/avo.css
CHANGED
@@ -4536,6 +4536,45 @@ input[type=file][data-direct-upload-url][disabled] {
|
|
4536
4536
|
display: none;
|
4537
4537
|
}
|
4538
4538
|
|
4539
|
+
.application-sidebar .active:hover, .application-sidebar .active{
|
4540
|
+
--tw-bg-opacity:1;
|
4541
|
+
background-color:rgb(206 231 248 / var(--tw-bg-opacity));
|
4542
|
+
--tw-text-opacity:1;
|
4543
|
+
color:rgb(8 134 222 / var(--tw-text-opacity))
|
4544
|
+
}
|
4545
|
+
|
4546
|
+
/* remove the left padding. */
|
4547
|
+
|
4548
|
+
@media (min-width: 1024px){
|
4549
|
+
.content-area .main-content-area{
|
4550
|
+
padding-left:0px
|
4551
|
+
}
|
4552
|
+
}
|
4553
|
+
|
4554
|
+
/* Hide the sidebar by default. */
|
4555
|
+
|
4556
|
+
@media (min-width: 1024px){
|
4557
|
+
.content-area .avo-sidebar{
|
4558
|
+
display:none
|
4559
|
+
}
|
4560
|
+
}
|
4561
|
+
|
4562
|
+
/* Add padding to the main area to allow for the sidebar to expand. */
|
4563
|
+
|
4564
|
+
@media (min-width: 1024px){
|
4565
|
+
.content-area.sidebar-open .main-content-area{
|
4566
|
+
padding-left:16rem
|
4567
|
+
}
|
4568
|
+
}
|
4569
|
+
|
4570
|
+
/* Show the sidebar. */
|
4571
|
+
|
4572
|
+
@media (min-width: 1024px){
|
4573
|
+
.content-area.sidebar-open .avo-sidebar{
|
4574
|
+
display:block
|
4575
|
+
}
|
4576
|
+
}
|
4577
|
+
|
4539
4578
|
.button-spinner {
|
4540
4579
|
width: 24px;
|
4541
4580
|
height: 24px;
|
@@ -8003,13 +8042,6 @@ html, body{
|
|
8003
8042
|
opacity:0
|
8004
8043
|
}
|
8005
8044
|
|
8006
|
-
.application-sidebar .active:hover, .application-sidebar .active{
|
8007
|
-
--tw-bg-opacity:1;
|
8008
|
-
background-color:rgb(206 231 248 / var(--tw-bg-opacity));
|
8009
|
-
--tw-text-opacity:1;
|
8010
|
-
color:rgb(8 134 222 / var(--tw-text-opacity))
|
8011
|
-
}
|
8012
|
-
|
8013
8045
|
.turbo-progress-bar{
|
8014
8046
|
--tw-bg-opacity:1;
|
8015
8047
|
background-color:rgb(57 158 229 / var(--tw-bg-opacity))
|
@@ -8913,6 +8945,10 @@ trix-editor {
|
|
8913
8945
|
margin-bottom:-1rem
|
8914
8946
|
}
|
8915
8947
|
|
8948
|
+
.lg\:block{
|
8949
|
+
display:block
|
8950
|
+
}
|
8951
|
+
|
8916
8952
|
.lg\:flex{
|
8917
8953
|
display:flex
|
8918
8954
|
}
|
@@ -8972,10 +9008,6 @@ trix-editor {
|
|
8972
9008
|
.lg\:pl-4{
|
8973
9009
|
padding-left:1rem
|
8974
9010
|
}
|
8975
|
-
|
8976
|
-
.lg\:pl-64{
|
8977
|
-
padding-left:16rem
|
8978
|
-
}
|
8979
9011
|
}
|
8980
9012
|
|
8981
9013
|
@media (min-width: 1280px){
|