avo 1.18.2 → 1.19.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 +2 -2
- data/Gemfile.lock +10 -7
- data/app/components/avo/fields/belongs_to_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/belongs_to_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/common/multiple_file_viewer_component.html.erb +1 -1
- data/app/components/avo/fields/common/single_file_viewer_component.html.erb +1 -2
- data/app/components/avo/fields/has_one_field/index_component.html.erb +1 -1
- 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 +6 -1
- data/app/components/avo/fields/index_component.rb +2 -2
- data/app/components/avo/fields/trix_field/edit_component.html.erb +1 -1
- data/app/components/avo/index/grid_item_component.html.erb +4 -4
- data/app/components/avo/index/resource_controls_component.html.erb +1 -1
- data/app/components/avo/index/resource_controls_component.rb +22 -6
- data/app/components/avo/index/resource_table_component.html.erb +1 -1
- data/app/components/avo/panel_component.rb +3 -4
- data/app/components/avo/resource_component.rb +5 -1
- data/app/components/avo/views/resource_edit_component.html.erb +3 -3
- data/app/components/avo/views/resource_edit_component.rb +9 -3
- data/app/components/avo/views/resource_index_component.html.erb +3 -9
- data/app/components/avo/views/resource_index_component.rb +11 -17
- data/app/components/avo/views/resource_new_component.html.erb +6 -4
- data/app/components/avo/views/resource_new_component.rb +12 -2
- data/app/components/avo/views/resource_show_component.html.erb +7 -6
- data/app/components/avo/views/resource_show_component.rb +20 -7
- data/app/controllers/avo/actions_controller.rb +1 -1
- data/app/controllers/avo/application_controller.rb +17 -61
- data/app/controllers/avo/attachments_controller.rb +3 -2
- data/app/controllers/avo/base_controller.rb +30 -25
- data/app/controllers/avo/home_controller.rb +5 -1
- data/app/controllers/avo/relations_controller.rb +3 -3
- data/app/controllers/avo/search_controller.rb +1 -1
- data/app/helpers/avo/application_helper.rb +5 -11
- data/app/helpers/avo/resources_helper.rb +1 -1
- data/app/helpers/avo/url_helpers.rb +77 -0
- data/app/packs/entrypoints/application.css +1 -0
- data/app/packs/entrypoints/application.js +7 -0
- data/app/packs/js/controllers/loading_button_controller.js +22 -0
- data/app/packs/stylesheets/components/status.css +22 -15
- data/app/packs/stylesheets/spinner.css +49 -0
- data/app/views/avo/actions/show.html.erb +2 -2
- data/app/views/avo/base/_actions.html.erb +3 -3
- data/app/views/avo/base/_filters.html.erb +1 -1
- data/app/views/avo/home/failed_to_load.html.erb +3 -0
- data/app/views/avo/partials/_failed_state.html.erb +16 -0
- data/app/views/avo/partials/_paginator.html.erb +2 -2
- data/app/views/avo/relations/new.html.erb +0 -2
- data/app/views/avo/sidebar/_sidebar.html.erb +1 -1
- data/app/views/kaminari/_page.html.erb +1 -1
- data/config/routes.rb +7 -5
- data/lib/avo/app.rb +4 -8
- data/lib/avo/base_action.rb +9 -1
- data/lib/avo/base_resource.rb +33 -7
- data/lib/avo/configuration.rb +2 -0
- data/lib/avo/fields/base_field.rb +15 -4
- data/lib/avo/fields/has_and_belongs_to_many_field.rb +1 -19
- data/lib/avo/fields/has_base_field.rb +35 -0
- data/lib/avo/fields/has_many_field.rb +1 -19
- data/lib/avo/fields/has_one_field.rb +3 -19
- data/lib/avo/fields/key_value_field.rb +4 -4
- data/lib/avo/services/authorization_service.rb +8 -4
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/templates/locales/avo.en.yml +12 -3
- data/lib/generators/avo/templates/locales/avo.ro.yml +7 -0
- data/public/avo-packs/css/{application-f9191617.css → application-c3b50b28.css} +54 -12
- data/public/avo-packs/css/application-c3b50b28.css.br +0 -0
- data/public/avo-packs/css/{application-f9191617.css.gz → application-c3b50b28.css.gz} +0 -0
- data/public/avo-packs/css/application-c3b50b28.css.map +1 -0
- data/public/avo-packs/css/application-c3b50b28.css.map.br +0 -0
- data/public/avo-packs/css/application-c3b50b28.css.map.gz +0 -0
- data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js +2 -0
- data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js.br +0 -0
- data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js.gz +0 -0
- data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js.map +1 -0
- data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js.map.br +0 -0
- data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js.map.gz +0 -0
- data/public/avo-packs/js/application-6fc968cfa52976c4582b.js +26 -0
- data/public/avo-packs/js/{application-cc89f096028eb1d4d971.js.LICENSE.txt → application-6fc968cfa52976c4582b.js.LICENSE.txt} +0 -0
- data/public/avo-packs/js/application-6fc968cfa52976c4582b.js.br +0 -0
- data/public/avo-packs/js/application-6fc968cfa52976c4582b.js.gz +0 -0
- data/public/avo-packs/js/application-6fc968cfa52976c4582b.js.map +1 -0
- data/public/avo-packs/js/application-6fc968cfa52976c4582b.js.map.br +0 -0
- data/public/avo-packs/js/application-6fc968cfa52976c4582b.js.map.gz +0 -0
- data/public/avo-packs/manifest.json +21 -21
- metadata +29 -23
- data/public/avo-packs/css/application-f9191617.css.br +0 -0
- data/public/avo-packs/css/application-f9191617.css.map +0 -1
- data/public/avo-packs/css/application-f9191617.css.map.br +0 -0
- data/public/avo-packs/css/application-f9191617.css.map.gz +0 -0
- data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js +0 -2
- data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js.br +0 -0
- data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js.gz +0 -0
- data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js.map +0 -1
- data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js.map.br +0 -0
- data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js.map.gz +0 -0
- data/public/avo-packs/js/application-cc89f096028eb1d4d971.js +0 -26
- data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.br +0 -0
- data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.gz +0 -0
- data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.map +0 -1
- data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.map.br +0 -0
- data/public/avo-packs/js/application-cc89f096028eb1d4d971.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: f172a929188a46646390efd7beef272e1f791b99c48a095f1fdb9bc8d3e3ec3d
|
4
|
+
data.tar.gz: 701fde39cac34c8ba48fd3403631c22f4f9ff9f90d4d2ad15ceb648f1819b887
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c4a9071eeb4fd9034e3d3326e109432cb4efa949d78a77a7fb6eddf99c008225732a20f0ba1da98f2061f3affdddea52e199cb173180df7f675b365aadd26ea
|
7
|
+
data.tar.gz: 9a706c402ce0b27429c60b909af0db4ad143819f371112ad0cbb0b198912a626645ee758da5bf9d2d9615e12c2622e04296c818d703f84b942ffaa52b06c9981
|
data/Gemfile
CHANGED
@@ -15,7 +15,7 @@ gemspec
|
|
15
15
|
# gem 'byebug', group: [:development, :test]
|
16
16
|
|
17
17
|
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
|
18
|
-
gem "webpacker", "6.0.0.rc.
|
18
|
+
gem "webpacker", "6.0.0.rc.2"
|
19
19
|
|
20
20
|
gem "countries"
|
21
21
|
|
@@ -91,7 +91,7 @@ group :test do
|
|
91
91
|
gem "rspec-rails", "~> 4.0.0"
|
92
92
|
gem "rails-controller-testing"
|
93
93
|
# Adds support for Capybara system testing and selenium driver
|
94
|
-
gem "capybara", "
|
94
|
+
gem "capybara", "3.36"
|
95
95
|
gem "selenium-webdriver"
|
96
96
|
# Easy installation and use of web drivers to run system tests with browsers
|
97
97
|
gem "webdrivers"
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
avo (1.
|
4
|
+
avo (1.19.1.pre.3)
|
5
5
|
active_link_to
|
6
6
|
addressable
|
7
7
|
breadcrumbs_on_rails
|
@@ -224,11 +224,14 @@ GEM
|
|
224
224
|
net-protocol
|
225
225
|
timeout
|
226
226
|
nio4r (2.5.8)
|
227
|
-
nokogiri (1.13.
|
227
|
+
nokogiri (1.13.1)
|
228
228
|
mini_portile2 (~> 2.7.0)
|
229
229
|
racc (~> 1.4)
|
230
|
+
nokogiri (1.13.1-x86_64-linux)
|
231
|
+
racc (~> 1.4)
|
230
232
|
orm_adapter (0.5.0)
|
231
|
-
pagy (5.
|
233
|
+
pagy (5.9.3)
|
234
|
+
activesupport
|
232
235
|
parallel (1.21.0)
|
233
236
|
parser (3.1.0.0)
|
234
237
|
ast (~> 2.4.1)
|
@@ -394,7 +397,7 @@ GEM
|
|
394
397
|
addressable (>= 2.8.0)
|
395
398
|
crack (>= 0.3.2)
|
396
399
|
hashdiff (>= 0.4.0, < 2.0.0)
|
397
|
-
webpacker (6.0.0.rc.
|
400
|
+
webpacker (6.0.0.rc.2)
|
398
401
|
activesupport (>= 5.2)
|
399
402
|
rack-proxy (>= 0.6.1)
|
400
403
|
railties (>= 5.2)
|
@@ -420,7 +423,7 @@ DEPENDENCIES
|
|
420
423
|
breadcrumbs_on_rails
|
421
424
|
bump
|
422
425
|
byebug
|
423
|
-
capybara (
|
426
|
+
capybara (= 3.36)
|
424
427
|
countries
|
425
428
|
database_cleaner
|
426
429
|
devise
|
@@ -461,8 +464,8 @@ DEPENDENCIES
|
|
461
464
|
web-console (>= 3.3.0)
|
462
465
|
webdrivers
|
463
466
|
webmock
|
464
|
-
webpacker (= 6.0.0.rc.
|
467
|
+
webpacker (= 6.0.0.rc.2)
|
465
468
|
zeitwerk (~> 2.3)
|
466
469
|
|
467
470
|
BUNDLED WITH
|
468
|
-
2.
|
471
|
+
2.3.5
|
@@ -1,3 +1,3 @@
|
|
1
1
|
<%= show_field_wrapper field: @field, index: @index do %>
|
2
|
-
<%= link_to @field.label, helpers.resource_path(@field.value, via_resource_class: @resource.model_class, via_resource_id: @resource.model.id) %>
|
2
|
+
<%= link_to @field.label, helpers.resource_path(model: @field.value, resource: @field.target_resource, via_resource_class: @resource.model_class, via_resource_id: @resource.model.id) %>
|
3
3
|
<% end %>
|
@@ -23,7 +23,7 @@
|
|
23
23
|
</div>
|
24
24
|
<div>
|
25
25
|
<% if @resource.authorization.authorize_action(:delete_attachments?, raise_exception: false) %>
|
26
|
-
<%= a_link "#{
|
26
|
+
<%= a_link "#{@resource.record_path}/active_storage_attachments/#{@id}/#{@file.id}", color: :red, variant: :outlined, size: :xs, class: 'text-center', 'data-turbo-frame': 'destroy_attachment_form', data: { confirm: t('avo.are_you_sure')} do %>
|
27
27
|
<%= helpers.svg 'trash' %> <span class="hidden lg:block lg:flex-1"><%= t 'avo.delete_file', item: @file.filename %></span>
|
28
28
|
<% end %>
|
29
29
|
<% end %>
|
@@ -23,8 +23,7 @@
|
|
23
23
|
</div>
|
24
24
|
<div>
|
25
25
|
<% if @resource.authorization.authorize_action(:delete_attachments?, raise_exception: false) %>
|
26
|
-
<%= a_link "#{
|
27
|
-
}/active_storage_attachments/#{@id}/#{@file.blob_id}", color: :red, variant: :outlined, size: :md, class: '', 'data-turbo-frame': 'destroy_attachment_form', data: { confirm: t('avo.are_you_sure')} do %>
|
26
|
+
<%= a_link "#{@resource.record_path}/active_storage_attachments/#{@id}/#{@file.blob_id}", color: :red, variant: :outlined, size: :md, class: '', 'data-turbo-frame': 'destroy_attachment_form', data: { confirm: t('avo.are_you_sure')} do %>
|
28
27
|
<%= helpers.svg 'trash' %> <%= t 'avo.delete_file', item: @file.filename %>
|
29
28
|
<% end %>
|
30
29
|
<% end %>
|
@@ -6,7 +6,7 @@
|
|
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
|
-
<%= a_link
|
9
|
+
<%= a_link attach_path, 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 %>
|
12
12
|
<% end %>
|
@@ -8,8 +8,9 @@ class Avo::Fields::HasOneField::ShowComponent < Avo::Fields::ShowComponent
|
|
8
8
|
if @field.present?
|
9
9
|
reflection_resource = @field.target_resource
|
10
10
|
if reflection_resource.present? && @resource.present?
|
11
|
-
method_name = (
|
11
|
+
method_name = ("attach_#{reflection_resource.model_key}?").to_sym
|
12
12
|
defined_policy_methods = @resource.authorization.defined_methods(@resource.model_class, raise_exception: false)
|
13
|
+
|
13
14
|
if defined_policy_methods.present? && defined_policy_methods.include?(method_name)
|
14
15
|
attach_policy = @resource.authorization.authorize_action(method_name, raise_exception: false)
|
15
16
|
end
|
@@ -17,4 +18,8 @@ class Avo::Fields::HasOneField::ShowComponent < Avo::Fields::ShowComponent
|
|
17
18
|
end
|
18
19
|
attach_policy
|
19
20
|
end
|
21
|
+
|
22
|
+
def attach_path
|
23
|
+
helpers.avo.resources_associations_new_path(@resource.singular_model_key, @resource.model.id, @field.id)
|
24
|
+
end
|
20
25
|
end
|
@@ -12,9 +12,9 @@ class Avo::Fields::IndexComponent < ViewComponent::Base
|
|
12
12
|
|
13
13
|
def resource_path
|
14
14
|
if @parent_model.present?
|
15
|
-
helpers.resource_path(@resource.model, via_resource_class: @parent_model.class, via_resource_id: @parent_model.id)
|
15
|
+
helpers.resource_path(model: @resource.model, resource: @resource, via_resource_class: @parent_model.class, via_resource_id: @parent_model.id)
|
16
16
|
else
|
17
|
-
helpers.resource_path(@resource.model)
|
17
|
+
helpers.resource_path(model: @resource.model, resource: @resource)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<div
|
3
3
|
data-controller="trix-field"
|
4
4
|
data-trix-field-target="controller"
|
5
|
-
data-resource-name="<%= @resource.
|
5
|
+
data-resource-name="<%= @resource.model_key %>"
|
6
6
|
data-resource-id="<%= @resource.model.id %>"
|
7
7
|
data-attachments-disabled="<%= @field.attachments_disabled %>"
|
8
8
|
data-attachment-key="<%= @field.attachment_key %>"
|
@@ -7,17 +7,17 @@
|
|
7
7
|
<% if cover.blank? %>
|
8
8
|
<%= render Avo::Index::GridCoverEmptyStateComponent.new %>
|
9
9
|
<% elsif cover.respond_to?(:to_image) && cover.to_image.present? %>
|
10
|
-
<%= link_to_if cover.link_to_resource, image_tag(cover.to_image, class: 'absolute h-full w-full object-cover'), helpers.resource_path(@resource.model), class: 'absolute h-full w-full object-cover', title: title.value %>
|
10
|
+
<%= link_to_if cover.link_to_resource, image_tag(cover.to_image, class: 'absolute h-full w-full object-cover'), helpers.resource_path(model: @resource.model, resource: @resource), class: 'absolute h-full w-full object-cover', title: title.value %>
|
11
11
|
<% elsif cover.type == 'file' %>
|
12
12
|
<% if cover.value.attached? && cover.value.representable? %>
|
13
|
-
<%= link_to_if cover.link_to_resource, image_tag(helpers.main_app.url_for(cover.value.variant(resize_to_limit: [480, 480])), class: 'absolute h-full w-full object-cover'), helpers.resource_path(@resource.model), class: 'absolute h-full w-full object-cover', title: title.value %>
|
13
|
+
<%= link_to_if cover.link_to_resource, image_tag(helpers.main_app.url_for(cover.value.variant(resize_to_limit: [480, 480])), class: 'absolute h-full w-full object-cover'), helpers.resource_path(model: @resource.model, resource: @resource), class: 'absolute h-full w-full object-cover', title: title.value %>
|
14
14
|
<% else %>
|
15
15
|
<div class="absolute bg-gray-100 w-full h-full">
|
16
16
|
<%= helpers.svg 'avocado', class: 'relative transform -translate-x-1/2 -translate-y-1/2 h-20 text-gray-400 inset-auto top-1/2 left-1/2' %>
|
17
17
|
</div>
|
18
18
|
<% end %>
|
19
19
|
<% elsif cover.value.present? %>
|
20
|
-
<%= link_to_if cover.link_to_resource, image_tag(cover.value, class: 'absolute h-full w-full object-cover'), helpers.resource_path(@resource.model), class: 'absolute h-full w-full object-cover', title: title.value %>
|
20
|
+
<%= link_to_if cover.link_to_resource, image_tag(cover.value, class: 'absolute h-full w-full object-cover'), helpers.resource_path(model: @resource.model, resource: @resource), class: 'absolute h-full w-full object-cover', title: title.value %>
|
21
21
|
<% else %>
|
22
22
|
<%= render Avo::Index::GridCoverEmptyStateComponent.new %>
|
23
23
|
<% end %>
|
@@ -25,7 +25,7 @@
|
|
25
25
|
<div class="grid grid-cols-1 place-content-between p-4 h-full">
|
26
26
|
<div class="mb-4">
|
27
27
|
<div class="grid font-semibold leading-tight text-lg mb-2">
|
28
|
-
<%= link_to_if title.link_to_resource, title.value, helpers.resource_path(@resource.model) if title.present? %>
|
28
|
+
<%= link_to_if title.link_to_resource, title.value, helpers.resource_path(model: @resource.model, resource: @resource) if title.present? %>
|
29
29
|
</div>
|
30
30
|
<div class="text-sm break-words">
|
31
31
|
<%= body.value if body.present? %>
|
@@ -42,7 +42,7 @@
|
|
42
42
|
<% end %>
|
43
43
|
|
44
44
|
<% if can_delete? %>
|
45
|
-
<%= form_with url: helpers.resource_path(@resource.model), method: :delete, html: {
|
45
|
+
<%= form_with url: helpers.resource_path(model: @resource.model, resource: @resource), method: :delete, html: {
|
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'),
|
@@ -23,19 +23,29 @@ class Avo::Index::ResourceControlsComponent < Avo::ResourceComponent
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def show_path
|
26
|
+
args = {}
|
27
|
+
|
26
28
|
if @parent_model.present?
|
27
|
-
|
28
|
-
|
29
|
-
|
29
|
+
args = {
|
30
|
+
via_resource_class: parent_resource.model_class,
|
31
|
+
via_resource_id: @parent_model.id
|
32
|
+
}
|
30
33
|
end
|
34
|
+
|
35
|
+
helpers.resource_path(model: @resource.model, resource: @resource, **args)
|
31
36
|
end
|
32
37
|
|
33
38
|
def edit_path
|
39
|
+
args = {}
|
40
|
+
|
34
41
|
if @parent_model.present?
|
35
|
-
|
36
|
-
|
37
|
-
|
42
|
+
args = {
|
43
|
+
via_resource_class: parent_resource.model_class,
|
44
|
+
via_resource_id: @parent_model.id
|
45
|
+
}
|
38
46
|
end
|
47
|
+
|
48
|
+
helpers.edit_resource_path(model: @resource.model, resource: @resource, **args)
|
39
49
|
end
|
40
50
|
|
41
51
|
def singular_resource_name
|
@@ -45,4 +55,10 @@ class Avo::Index::ResourceControlsComponent < Avo::ResourceComponent
|
|
45
55
|
@resource.singular_name.present? ? @resource.singular_name : @resource.model_class.model_name.name.downcase
|
46
56
|
end
|
47
57
|
end
|
58
|
+
|
59
|
+
def parent_resource
|
60
|
+
return nil if @parent_model.blank?
|
61
|
+
|
62
|
+
::Avo::App.get_resource_by_model_name @parent_model.class
|
63
|
+
end
|
48
64
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="w-full">
|
2
2
|
<% if @resources.present?%>
|
3
|
-
<table class="w-full px-4 overflow-hidden" data-resource-name='<%= @resource.
|
3
|
+
<table class="w-full px-4 overflow-hidden" data-resource-name='<%= @resource.model_key %>' data-controller='item-select-all'>
|
4
4
|
<%= render partial: 'avo/partials/table_header', locals: {fields: @resource.get_fields(reflection: @reflection)} %>
|
5
5
|
<tbody>
|
6
6
|
<% @resources.each_with_index do |resource, index| %>
|
@@ -6,19 +6,18 @@ class Avo::PanelComponent < ViewComponent::Base
|
|
6
6
|
renders_one :bare_content
|
7
7
|
renders_one :footer
|
8
8
|
|
9
|
-
def initialize(title: nil, body_classes: nil, data: {}, display_breadcrumbs: false)
|
9
|
+
def initialize(title: nil, body_classes: nil, data: {}, display_breadcrumbs: false, index: nil)
|
10
10
|
@title = title
|
11
11
|
@body_classes = body_classes
|
12
12
|
@data = data
|
13
13
|
@display_breadcrumbs = display_breadcrumbs
|
14
|
+
@index = index
|
14
15
|
end
|
15
16
|
|
16
17
|
private
|
17
18
|
|
18
19
|
def data_attributes
|
19
|
-
|
20
|
-
|
21
|
-
@data.map do |key, value|
|
20
|
+
@data.merge({'panel-index': @index}).map do |key, value|
|
22
21
|
" data-#{key}=\"#{value}\""
|
23
22
|
end.join
|
24
23
|
end
|
@@ -12,7 +12,7 @@ class Avo::ResourceComponent < ViewComponent::Base
|
|
12
12
|
if @reflection.present?
|
13
13
|
reflection_resource = ::Avo::App.get_resource_by_model_name(@reflection.active_record.name)
|
14
14
|
if reflection_resource.present?
|
15
|
-
method_name =
|
15
|
+
method_name = "#{policy_method}_#{@reflection.name.to_s.underscore}?".to_sym
|
16
16
|
defined_policy_methods = reflection_resource.authorization.defined_methods(reflection_resource.model_class, raise_exception: false)
|
17
17
|
if defined_policy_methods.present? && defined_policy_methods.include?(method_name)
|
18
18
|
association_policy = reflection_resource.authorization.authorize_action(method_name, raise_exception: false)
|
@@ -28,4 +28,8 @@ class Avo::ResourceComponent < ViewComponent::Base
|
|
28
28
|
def simple_relation?
|
29
29
|
@reflection.is_a? ::ActiveRecord::Reflection::HasManyReflection
|
30
30
|
end
|
31
|
+
|
32
|
+
def relation_resource
|
33
|
+
::Avo::App.get_resource_by_model_name params[:via_resource_class].safe_constantize
|
34
|
+
end
|
31
35
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div data-model-id="<%= @resource.model.id %>">
|
2
2
|
<% @resource.panels.each do |resource_panel| %>
|
3
|
-
<%= form_with model: @resource.model, scope: @resource.form_scope, url: helpers.resource_path(@resource.model), method: :put, multipart: true do |form| %>
|
3
|
+
<%= form_with model: @resource.model, scope: @resource.form_scope, url: helpers.resource_path(model: @resource.model, resource: @resource), method: :put, multipart: true do |form| %>
|
4
4
|
<%= hidden_field_tag :referrer, back_path if params[:via_resource_class] %>
|
5
5
|
|
6
6
|
<%= render Avo::PanelComponent.new(title: resource_panel[:name], display_breadcrumbs: true) do |c| %>
|
@@ -10,8 +10,8 @@
|
|
10
10
|
<%= helpers.svg 'arrow-left' %> <%= t('avo.cancel').capitalize %>
|
11
11
|
<% end %>
|
12
12
|
|
13
|
-
<% if
|
14
|
-
<%= a_button color: 'green', variant: 'outlined', type: :submit do %>
|
13
|
+
<% if can_see_the_save_button? %>
|
14
|
+
<%= a_button color: 'green', variant: 'outlined', spinner: true, type: :submit do %>
|
15
15
|
<%= helpers.svg 'save' %> <%= t('avo.save').capitalize %>
|
16
16
|
<% end %>
|
17
17
|
<% end %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class Avo::Views::ResourceEditComponent <
|
3
|
+
class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
|
4
4
|
include Avo::ResourcesHelper
|
5
5
|
include Avo::ApplicationHelper
|
6
6
|
|
@@ -10,12 +10,18 @@ class Avo::Views::ResourceEditComponent < ViewComponent::Base
|
|
10
10
|
|
11
11
|
def back_path
|
12
12
|
if via_resource?
|
13
|
-
helpers.resource_path(params[:via_resource_class].safe_constantize, resource_id: params[:via_resource_id])
|
13
|
+
helpers.resource_path(model: params[:via_resource_class].safe_constantize, resource: relation_resource, resource_id: params[:via_resource_id])
|
14
14
|
else
|
15
|
-
helpers.resource_path(@resource.model)
|
15
|
+
helpers.resource_path(model: @resource.model, resource: @resource)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
# The save button is dependent on the edit? policy method.
|
20
|
+
# The update? method should be called only when the user clicks the Save button so the developer gets access to the params from the form.
|
21
|
+
def can_see_the_save_button?
|
22
|
+
@resource.authorization.authorize_action :edit, raise_exception: false
|
23
|
+
end
|
24
|
+
|
19
25
|
private
|
20
26
|
|
21
27
|
def via_resource?
|
@@ -3,18 +3,12 @@
|
|
3
3
|
<% c.tools do %>
|
4
4
|
<%= render 'actions' if @actions.present? %>
|
5
5
|
|
6
|
-
<% if
|
6
|
+
<% if can_see_the_create_button? %>
|
7
7
|
<%= a_link create_path do %>
|
8
8
|
<%= svg 'plus' %> <%= t('avo.create_new_item', item: singular_resource_name.downcase ) %>
|
9
9
|
<% end %>
|
10
10
|
<% end %>
|
11
11
|
|
12
|
-
<% if can_detach? %>
|
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: singular_resource_name).capitalize %>
|
15
|
-
<% end %>
|
16
|
-
<% end %>
|
17
|
-
|
18
12
|
<% if can_attach? %>
|
19
13
|
<%= a_link attach_path, color: 'indigo', 'data-turbo-frame': 'attach_modal' do %>
|
20
14
|
<%= svg 'view-grid-add' %> <%= t('avo.attach_item', item: singular_resource_name).capitalize %>
|
@@ -24,11 +18,11 @@
|
|
24
18
|
|
25
19
|
<% c.body do %>
|
26
20
|
<div class="flex justify-between pt-2 pb-2 min-h-16"
|
27
|
-
data-selected-resources-name="<%= @resource.
|
21
|
+
data-selected-resources-name="<%= @resource.model_key %>"
|
28
22
|
data-selected-resources="[]"
|
29
23
|
>
|
30
24
|
<div class="flex items-center px-6 w-64">
|
31
|
-
<%= render partial: 'avo/partials/resource_search', locals: {resource: @resource.
|
25
|
+
<%= render partial: 'avo/partials/resource_search', locals: {resource: @resource.model_class.model_name.plural} if @resource.search_query.present? %>
|
32
26
|
</div>
|
33
27
|
<div class="flex justify-end items-center px-6 space-x-3">
|
34
28
|
<%= render partial: 'avo/partials/view_toggle_button', locals: { available_view_types: available_view_types, view_type: view_type, turbo_frame: @turbo_frame } if @models.present? %>
|
@@ -44,8 +44,10 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
44
44
|
@index_params[:available_view_types]
|
45
45
|
end
|
46
46
|
|
47
|
-
|
48
|
-
|
47
|
+
# The Create button is dependent on the new? policy method.
|
48
|
+
# The create? should be called only when the user clicks the Save button so the developers gets access to the params from the form.
|
49
|
+
def can_see_the_create_button?
|
50
|
+
@resource.authorization.authorize_action(:new, raise_exception: false) && simple_relation? && !has_reflection_and_is_read_only
|
49
51
|
end
|
50
52
|
|
51
53
|
def can_attach?
|
@@ -55,10 +57,6 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
55
57
|
@reflection.present? && klass.is_a?(::ActiveRecord::Reflection::HasManyReflection) && !has_reflection_and_is_read_only && authorize_association_for("attach")
|
56
58
|
end
|
57
59
|
|
58
|
-
def can_detach?
|
59
|
-
@reflection.present? && @reflection.is_a?(::ActiveRecord::Reflection::HasOneReflection) && @models.present? && !has_reflection_and_is_read_only && authorize_association_for("detach")
|
60
|
-
end
|
61
|
-
|
62
60
|
def has_reflection_and_is_read_only
|
63
61
|
if @reflection.present? && @reflection.active_record.name && @reflection.name
|
64
62
|
fields = ::Avo::App.get_resource_by_model_name(@reflection.active_record.name).get_field_definitions
|
@@ -75,35 +73,31 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
75
73
|
end
|
76
74
|
|
77
75
|
def create_path
|
76
|
+
args = {}
|
77
|
+
|
78
78
|
if @reflection.present?
|
79
|
-
|
79
|
+
args = {
|
80
80
|
via_relation_class: @parent_model.model_name,
|
81
81
|
via_resource_id: @parent_model.id
|
82
82
|
}
|
83
83
|
|
84
84
|
if @reflection.inverse_of.present?
|
85
|
-
|
85
|
+
args[:via_relation] = @reflection.inverse_of.name
|
86
86
|
end
|
87
|
-
|
88
|
-
helpers.new_resource_path(@resource.model_class, **path_args)
|
89
|
-
else
|
90
|
-
helpers.new_resource_path(@resource.model_class)
|
91
87
|
end
|
88
|
+
|
89
|
+
helpers.new_resource_path(model: @resource.model_class, resource: @resource, **args)
|
92
90
|
end
|
93
91
|
|
94
92
|
def attach_path
|
95
93
|
"#{Avo::App.root_path}#{request.env["PATH_INFO"]}/new"
|
96
94
|
end
|
97
95
|
|
98
|
-
def detach_path
|
99
|
-
helpers.resource_detach_path(via_resource_name, via_resource_id, via_relation_param, @models.first.id)
|
100
|
-
end
|
101
|
-
|
102
96
|
def singular_resource_name
|
103
97
|
if @reflection.present?
|
104
98
|
::Avo::App.get_resource_by_model_name(@reflection.class_name).name
|
105
99
|
else
|
106
|
-
@resource.singular_name
|
100
|
+
@resource.singular_name || @resource.model_class.model_name.name.downcase
|
107
101
|
end
|
108
102
|
end
|
109
103
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div>
|
2
2
|
<% @resource.panels.each do |resource_panel| %>
|
3
|
-
<%= form_with model: @resource.model, url: helpers.resources_path(@resource
|
3
|
+
<%= form_with model: @resource.model, url: helpers.resources_path(resource: @resource, via_relation_class: params[:via_relation_class], via_resource_id: params[:via_resource_id]), local: true, multipart: true do |form| %>
|
4
4
|
<%= render Avo::PanelComponent.new(title: resource_panel[:name], display_breadcrumbs: true) do |c| %>
|
5
5
|
<% c.tools do %>
|
6
6
|
<div class="flex justify-end space-x-2">
|
@@ -8,9 +8,11 @@
|
|
8
8
|
<%= svg 'arrow-left' %> <%= t('avo.cancel').capitalize %>
|
9
9
|
<% end %>
|
10
10
|
|
11
|
-
|
12
|
-
<%=
|
13
|
-
|
11
|
+
<% if can_see_the_save_button? %>
|
12
|
+
<%= a_button color: 'green', spinner: true, type: :submit do %>
|
13
|
+
<%= svg 'save' %> <%= t('avo.save').capitalize %>
|
14
|
+
<% end %>
|
15
|
+
<% end %>
|
14
16
|
</div>
|
15
17
|
<% end %>
|
16
18
|
|
@@ -14,15 +14,25 @@ class Avo::Views::ResourceNewComponent < ViewComponent::Base
|
|
14
14
|
|
15
15
|
def back_path
|
16
16
|
if via_resource?
|
17
|
-
helpers.resource_path(params[:via_relation_class].safe_constantize, resource_id: params[:via_resource_id])
|
17
|
+
helpers.resource_path(model: params[:via_relation_class].safe_constantize, resource: relation_resource, resource_id: params[:via_resource_id])
|
18
18
|
else
|
19
|
-
helpers.resources_path(@resource
|
19
|
+
helpers.resources_path(resource: @resource)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
# The create button is dependent on the new? policy method.
|
24
|
+
# The create? should be called only when the user clicks the Save button so the developers gets access to the params from the form.
|
25
|
+
def can_see_the_save_button?
|
26
|
+
@resource.authorization.authorize_action :new, raise_exception: false
|
27
|
+
end
|
28
|
+
|
23
29
|
private
|
24
30
|
|
25
31
|
def via_resource?
|
26
32
|
params[:via_relation_class].present? && params[:via_resource_id].present?
|
27
33
|
end
|
34
|
+
|
35
|
+
def relation_resource
|
36
|
+
::Avo::App.get_resource_by_model_name params[:via_relation_class].safe_constantize
|
37
|
+
end
|
28
38
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
<div data-model-id="<%= @resource.model.id %>"
|
2
|
-
data-selected-resources-name="<%= @resource.
|
2
|
+
data-selected-resources-name="<%= @resource.model_key %>"
|
3
3
|
data-selected-resources='["<%= @resource.model.id %>"]'
|
4
4
|
>
|
5
|
-
<% @resource.panels.
|
6
|
-
<%= render Avo::PanelComponent.new(title: resource_panel[:name], display_breadcrumbs: @reflection.blank
|
5
|
+
<% @resource.panels.each_with_index do |resource_panel, index| %>
|
6
|
+
<%= render Avo::PanelComponent.new(title: resource_panel[:name], display_breadcrumbs: @reflection.blank?, index: index) do |c| %>
|
7
7
|
<% c.tools do %>
|
8
8
|
<% if resource_panel[:name] == @resource.default_panel_name %>
|
9
9
|
<%= render 'actions' %>
|
@@ -14,7 +14,7 @@
|
|
14
14
|
<%= svg 'trash' %> <%= t('avo.detach_item', item: @reflection.name.to_s).capitalize %>
|
15
15
|
<% end %>
|
16
16
|
<% end %>
|
17
|
-
<% if
|
17
|
+
<% if can_see_the_edit_button? %>
|
18
18
|
<%= a_link edit_path, color: 'indigo' do %>
|
19
19
|
<%= svg 'edit' %> <%= t('avo.edit').capitalize %>
|
20
20
|
<% end %>
|
@@ -24,9 +24,10 @@
|
|
24
24
|
<%= svg 'arrow-left' %> <%= t('avo.go_back') %>
|
25
25
|
<% end %>
|
26
26
|
|
27
|
-
<% if
|
28
|
-
<%= form_with url: helpers.resource_path(@resource.model), method: :delete, html: { 'data-turbo-frame': params[:turbo_frame] } do |form| %>
|
27
|
+
<% if can_see_the_destroy_button? %>
|
28
|
+
<%= form_with url: helpers.resource_path(model: @resource.model, resource: @resource), method: :delete, html: { 'data-turbo-frame': params[:turbo_frame] } do |form| %>
|
29
29
|
<%= a_button title: t('avo.delete_item', item: @resource.model.model_name.name.downcase).capitalize,
|
30
|
+
spinner: true,
|
30
31
|
color: 'red',
|
31
32
|
variant: 'outlined',
|
32
33
|
type: :submit,
|
@@ -15,18 +15,23 @@ class Avo::Views::ResourceShowComponent < Avo::ResourceComponent
|
|
15
15
|
|
16
16
|
def back_path
|
17
17
|
if via_resource?
|
18
|
-
helpers.resource_path(params[:via_resource_class].safe_constantize, resource_id: params[:via_resource_id])
|
18
|
+
helpers.resource_path(model: params[:via_resource_class].safe_constantize, resource: relation_resource, resource_id: params[:via_resource_id])
|
19
19
|
else
|
20
|
-
helpers.resources_path(@resource
|
20
|
+
helpers.resources_path(resource: @resource)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
def edit_path
|
25
|
+
args = {}
|
26
|
+
|
25
27
|
if via_resource?
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
args = {
|
29
|
+
via_resource_class: params[:via_resource_class],
|
30
|
+
via_resource_id: params[:via_resource_id]
|
31
|
+
}
|
29
32
|
end
|
33
|
+
|
34
|
+
helpers.edit_resource_path(model: @resource.model, resource: @resource, **args)
|
30
35
|
end
|
31
36
|
|
32
37
|
def detach_path
|
@@ -34,11 +39,19 @@ class Avo::Views::ResourceShowComponent < Avo::ResourceComponent
|
|
34
39
|
end
|
35
40
|
|
36
41
|
def destroy_path
|
37
|
-
helpers.resource_path(@resource.model)
|
42
|
+
helpers.resource_path(model: @resource.model, resource: @resource)
|
38
43
|
end
|
39
44
|
|
40
45
|
def can_detach?
|
41
|
-
authorize_association_for(
|
46
|
+
authorize_association_for("detach")
|
47
|
+
end
|
48
|
+
|
49
|
+
def can_see_the_edit_button?
|
50
|
+
@resource.authorization.authorize_action(:edit, raise_exception: false)
|
51
|
+
end
|
52
|
+
|
53
|
+
def can_see_the_destroy_button?
|
54
|
+
@resource.authorization.authorize_action(:destroy, raise_exception: false)
|
42
55
|
end
|
43
56
|
|
44
57
|
private
|
@@ -67,7 +67,7 @@ module Avo
|
|
67
67
|
|
68
68
|
redirect_to path, "#{response[:message_type]}": response[:message]
|
69
69
|
elsif response[:type] == :reload
|
70
|
-
redirect_back fallback_location: resources_path(@resource
|
70
|
+
redirect_back fallback_location: resources_path(resource: @resource), "#{response[:message_type]}": response[:message]
|
71
71
|
end
|
72
72
|
end
|
73
73
|
end
|