avo 1.18.2.pre.0 → 1.19.1.pre.2

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 (106) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -3
  3. data/Gemfile.lock +9 -8
  4. data/app/components/avo/fields/belongs_to_field/index_component.html.erb +1 -1
  5. data/app/components/avo/fields/belongs_to_field/show_component.html.erb +1 -1
  6. data/app/components/avo/fields/common/multiple_file_viewer_component.html.erb +1 -1
  7. data/app/components/avo/fields/common/single_file_viewer_component.html.erb +1 -2
  8. data/app/components/avo/fields/has_one_field/index_component.html.erb +1 -1
  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 +6 -1
  11. data/app/components/avo/fields/index_component.rb +2 -2
  12. data/app/components/avo/fields/text_field/index_component.html.erb +5 -1
  13. data/app/components/avo/fields/text_field/show_component.html.erb +5 -1
  14. data/app/components/avo/fields/trix_field/edit_component.html.erb +1 -1
  15. data/app/components/avo/index/grid_item_component.html.erb +4 -4
  16. data/app/components/avo/index/resource_controls_component.html.erb +1 -1
  17. data/app/components/avo/index/resource_controls_component.rb +22 -6
  18. data/app/components/avo/index/resource_table_component.html.erb +1 -1
  19. data/app/components/avo/panel_component.rb +3 -4
  20. data/app/components/avo/resource_component.rb +5 -1
  21. data/app/components/avo/views/resource_edit_component.html.erb +2 -2
  22. data/app/components/avo/views/resource_edit_component.rb +3 -3
  23. data/app/components/avo/views/resource_index_component.html.erb +2 -8
  24. data/app/components/avo/views/resource_index_component.rb +7 -15
  25. data/app/components/avo/views/resource_new_component.html.erb +2 -2
  26. data/app/components/avo/views/resource_new_component.rb +6 -2
  27. data/app/components/avo/views/resource_show_component.html.erb +5 -4
  28. data/app/components/avo/views/resource_show_component.rb +11 -6
  29. data/app/controllers/avo/actions_controller.rb +1 -1
  30. data/app/controllers/avo/application_controller.rb +17 -61
  31. data/app/controllers/avo/attachments_controller.rb +3 -2
  32. data/app/controllers/avo/base_controller.rb +30 -25
  33. data/app/controllers/avo/home_controller.rb +5 -1
  34. data/app/controllers/avo/relations_controller.rb +3 -3
  35. data/app/controllers/avo/search_controller.rb +1 -1
  36. data/app/helpers/avo/application_helper.rb +5 -11
  37. data/app/helpers/avo/resources_helper.rb +1 -1
  38. data/app/helpers/avo/url_helpers.rb +77 -0
  39. data/app/packs/entrypoints/application.css +1 -0
  40. data/app/packs/entrypoints/application.js +7 -0
  41. data/app/packs/js/controllers/loading_button_controller.js +22 -0
  42. data/app/packs/stylesheets/components/status.css +22 -15
  43. data/app/packs/stylesheets/spinner.css +49 -0
  44. data/app/views/avo/actions/show.html.erb +2 -2
  45. data/app/views/avo/base/_actions.html.erb +3 -3
  46. data/app/views/avo/base/_filters.html.erb +1 -1
  47. data/app/views/avo/home/failed_to_load.html.erb +3 -0
  48. data/app/views/avo/partials/_failed_state.html.erb +16 -0
  49. data/app/views/avo/partials/_paginator.html.erb +2 -2
  50. data/app/views/avo/partials/_profile_dropdown.html.erb +7 -5
  51. data/app/views/avo/relations/new.html.erb +0 -2
  52. data/app/views/avo/sidebar/_sidebar.html.erb +1 -1
  53. data/app/views/kaminari/_page.html.erb +1 -1
  54. data/config/routes.rb +7 -5
  55. data/lib/avo/app.rb +12 -12
  56. data/lib/avo/base_action.rb +9 -1
  57. data/lib/avo/base_resource.rb +33 -7
  58. data/lib/avo/configuration.rb +4 -0
  59. data/lib/avo/fields/base_field.rb +15 -4
  60. data/lib/avo/fields/has_and_belongs_to_many_field.rb +1 -19
  61. data/lib/avo/fields/has_base_field.rb +35 -0
  62. data/lib/avo/fields/has_many_field.rb +1 -19
  63. data/lib/avo/fields/has_one_field.rb +3 -19
  64. data/lib/avo/fields/key_value_field.rb +4 -4
  65. data/lib/avo/fields/text_field.rb +2 -0
  66. data/lib/avo/services/authorization_service.rb +8 -4
  67. data/lib/avo/version.rb +1 -1
  68. data/lib/generators/avo/templates/locales/avo.en.yml +12 -3
  69. data/lib/generators/avo/templates/locales/avo.ro.yml +7 -0
  70. data/public/avo-packs/css/{application-f9191617.css → application-c3b50b28.css} +54 -12
  71. data/public/avo-packs/css/application-c3b50b28.css.br +0 -0
  72. data/public/avo-packs/css/{application-f9191617.css.gz → application-c3b50b28.css.gz} +0 -0
  73. data/public/avo-packs/css/application-c3b50b28.css.map +1 -0
  74. data/public/avo-packs/css/application-c3b50b28.css.map.br +0 -0
  75. data/public/avo-packs/css/application-c3b50b28.css.map.gz +0 -0
  76. data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js +2 -0
  77. data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js.br +0 -0
  78. data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js.gz +0 -0
  79. data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js.map +1 -0
  80. data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js.map.br +0 -0
  81. data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js.map.gz +0 -0
  82. data/public/avo-packs/js/application-6fc968cfa52976c4582b.js +26 -0
  83. data/public/avo-packs/js/{application-cc89f096028eb1d4d971.js.LICENSE.txt → application-6fc968cfa52976c4582b.js.LICENSE.txt} +0 -0
  84. data/public/avo-packs/js/application-6fc968cfa52976c4582b.js.br +0 -0
  85. data/public/avo-packs/js/application-6fc968cfa52976c4582b.js.gz +0 -0
  86. data/public/avo-packs/js/application-6fc968cfa52976c4582b.js.map +1 -0
  87. data/public/avo-packs/js/application-6fc968cfa52976c4582b.js.map.br +0 -0
  88. data/public/avo-packs/js/application-6fc968cfa52976c4582b.js.map.gz +0 -0
  89. data/public/avo-packs/manifest.json +21 -21
  90. metadata +27 -21
  91. data/public/avo-packs/css/application-f9191617.css.br +0 -0
  92. data/public/avo-packs/css/application-f9191617.css.map +0 -1
  93. data/public/avo-packs/css/application-f9191617.css.map.br +0 -0
  94. data/public/avo-packs/css/application-f9191617.css.map.gz +0 -0
  95. data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js +0 -2
  96. data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js.br +0 -0
  97. data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js.gz +0 -0
  98. data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js.map +0 -1
  99. data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js.map.br +0 -0
  100. data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js.map.gz +0 -0
  101. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js +0 -26
  102. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.br +0 -0
  103. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.gz +0 -0
  104. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.map +0 -1
  105. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.map.br +0 -0
  106. 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: 88cca5eb20b3bf2b5ffec2d183425a17397af2e2348f75f77b04eba1b7273f42
4
- data.tar.gz: 95f9929e160e72e1d3b1f2916e234c5aca8831951af44b262552c29418435776
3
+ metadata.gz: cf4fba75e7b0dc27c8417c9edd4e4d84c6221bc6f53f94ac7a5941012900fc96
4
+ data.tar.gz: 410b3f31f75a1088dd4ac06d337e088d35ecac039b675f65a68949fc381c0c29
5
5
  SHA512:
6
- metadata.gz: 84865027b7970efac44ab3899268123af6d081b59cd28781a26c5075c7ccff3197b6546f70bed48aa202ecdee3d7586f4356863908f42a462bf35871cd0d59ae
7
- data.tar.gz: 5dd638cd5699db08ab642cfc00523ff19f9cb8338408d9b38ba0b167ec23fab209529367be43f87ac117f2f9173fe498e5cdc37ec8533202135902a6b4a80b75
6
+ metadata.gz: 8d6b2e501c23ce7ef5f5e719cbc9a348dd2b538243fdf8fbab029409ed3935be58a75e097e695133251cf8a5f69571b0acdc51681f357a8795ad0402d5095af1
7
+ data.tar.gz: 1367f09a584c5ca37ffb9d0486c7df9f8a77b354d53fd25a000923aa0b771f59daeac146c67aff4e4199b3fb8a6a4cf7c99d1f8d5d91db569b69ec2ddcf4cd8a
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.6"
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", ">= 2.15"
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"
@@ -131,6 +131,6 @@ gem 'ransack'
131
131
 
132
132
  gem 'friendly_id', '~> 5.4.0'
133
133
 
134
- gem "aws-sdk-s3", require: false
134
+ gem 'aws-sdk-s3', require: false
135
135
 
136
136
  gem 'net-smtp', require: false
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- avo (1.18.2.pre.0)
4
+ avo (1.19.1.pre.2)
5
5
  active_link_to
6
6
  addressable
7
7
  breadcrumbs_on_rails
@@ -224,13 +224,14 @@ GEM
224
224
  net-protocol
225
225
  timeout
226
226
  nio4r (2.5.8)
227
- nokogiri (1.13.0)
227
+ nokogiri (1.13.1)
228
228
  mini_portile2 (~> 2.7.0)
229
229
  racc (~> 1.4)
230
- nokogiri (1.13.0-x86_64-linux)
230
+ nokogiri (1.13.1-x86_64-linux)
231
231
  racc (~> 1.4)
232
232
  orm_adapter (0.5.0)
233
- pagy (5.7.1)
233
+ pagy (5.9.3)
234
+ activesupport
234
235
  parallel (1.21.0)
235
236
  parser (3.1.0.0)
236
237
  ast (~> 2.4.1)
@@ -396,7 +397,7 @@ GEM
396
397
  addressable (>= 2.8.0)
397
398
  crack (>= 0.3.2)
398
399
  hashdiff (>= 0.4.0, < 2.0.0)
399
- webpacker (6.0.0.rc.6)
400
+ webpacker (6.0.0.rc.2)
400
401
  activesupport (>= 5.2)
401
402
  rack-proxy (>= 0.6.1)
402
403
  railties (>= 5.2)
@@ -422,7 +423,7 @@ DEPENDENCIES
422
423
  breadcrumbs_on_rails
423
424
  bump
424
425
  byebug
425
- capybara (>= 2.15)
426
+ capybara (= 3.36)
426
427
  countries
427
428
  database_cleaner
428
429
  devise
@@ -463,8 +464,8 @@ DEPENDENCIES
463
464
  web-console (>= 3.3.0)
464
465
  webdrivers
465
466
  webmock
466
- webpacker (= 6.0.0.rc.6)
467
+ webpacker (= 6.0.0.rc.2)
467
468
  zeitwerk (~> 2.3)
468
469
 
469
470
  BUNDLED WITH
470
- 2.2.32
471
+ 2.3.5
@@ -1,3 +1,3 @@
1
1
  <%= index_field_wrapper field: @field do %>
2
- <%= link_to @field.label, helpers.resource_path(@field.value) %>
2
+ <%= link_to @field.label, helpers.resource_path(model: @field.value, resource: @field.target_resource) %>
3
3
  <% end %>
@@ -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 "#{Avo::App.root_path}/resources/#{@resource.model.model_name.route_key}/#{@resource.model.id}/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 %>
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 "#{Avo::App.root_path}/resources/#{@resource.model.model_name.route_key}/#{@resource.model.id
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 %>
@@ -1,3 +1,3 @@
1
1
  <%= index_field_wrapper field: @field do %>
2
- <%= link_to @field.label, helpers.resource_path(@field.value) %>
2
+ <%= link_to @field.label, helpers.resource_path(model: @field.value, resource: @field.target_resource) %>
3
3
  <% 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 helpers.resource_attach_path(@resource.model.model_name.route_key, @resource.model.id, @field.id), color: 'indigo', 'data-turbo-frame': 'attach_modal' do %>
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 = ('attach_' + reflection_resource.model_class.model_name.singular_route_key.underscore + '?').to_sym
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
@@ -1,3 +1,7 @@
1
1
  <%= index_field_wrapper field: @field do %>
2
- <%= link_to_if @field.link_to_resource, @field.value, resource_path %>
2
+ <% if @field.as_html %>
3
+ <%== @field.value %>
4
+ <% else %>
5
+ <%= link_to_if @field.link_to_resource, @field.value, resource_path %>
6
+ <% end %>
3
7
  <% end %>
@@ -1,3 +1,7 @@
1
1
  <%= show_field_wrapper field: @field, index: @index do %>
2
- <%= @field.value %>
2
+ <% if @field.as_html %>
3
+ <%== @field.value %>
4
+ <% else %>
5
+ <%= @field.value %>
6
+ <% end %>
3
7
  <% 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.model_class.model_name.route_key %>"
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
- helpers.resource_path(@resource.model, via_resource_class: @parent_model.class.base_class, via_resource_id: @parent_model.id)
28
- else
29
- helpers.resource_path(@resource.model)
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
- helpers.edit_resource_path(@resource.model, via_resource_class: @parent_model.class.base_class, via_resource_id: @parent_model.id)
36
- else
37
- helpers.edit_resource_path(@resource.model)
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.model_class.model_name.route_key %>' data-controller='item-select-all'>
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
- return if @data.blank?
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 = ("#{policy_method}_#{@reflection.name.to_s.underscore}?").to_sym
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| %>
@@ -11,7 +11,7 @@
11
11
  <% end %>
12
12
 
13
13
  <% if @resource.authorization.authorize_action :update, raise_exception: false %>
14
- <%= a_button color: 'green', variant: 'outlined', type: :submit do %>
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 < ViewComponent::Base
3
+ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
4
4
  include Avo::ResourcesHelper
5
5
  include Avo::ApplicationHelper
6
6
 
@@ -10,9 +10,9 @@ 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
 
@@ -9,12 +9,6 @@
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.model_class.model_name.route_key %>"
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.route_key} if @resource.search_query.present? %>
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? %>
@@ -55,10 +55,6 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
55
55
  @reflection.present? && klass.is_a?(::ActiveRecord::Reflection::HasManyReflection) && !has_reflection_and_is_read_only && authorize_association_for("attach")
56
56
  end
57
57
 
58
- 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
58
  def has_reflection_and_is_read_only
63
59
  if @reflection.present? && @reflection.active_record.name && @reflection.name
64
60
  fields = ::Avo::App.get_resource_by_model_name(@reflection.active_record.name).get_field_definitions
@@ -75,35 +71,31 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
75
71
  end
76
72
 
77
73
  def create_path
74
+ args = {}
75
+
78
76
  if @reflection.present?
79
- path_args = {
77
+ args = {
80
78
  via_relation_class: @parent_model.model_name,
81
79
  via_resource_id: @parent_model.id
82
80
  }
83
81
 
84
82
  if @reflection.inverse_of.present?
85
- path_args[:via_relation] = @reflection.inverse_of.name
83
+ args[:via_relation] = @reflection.inverse_of.name
86
84
  end
87
-
88
- helpers.new_resource_path(@resource.model_class, **path_args)
89
- else
90
- helpers.new_resource_path(@resource.model_class)
91
85
  end
86
+
87
+ helpers.new_resource_path(model: @resource.model_class, resource: @resource, **args)
92
88
  end
93
89
 
94
90
  def attach_path
95
91
  "#{Avo::App.root_path}#{request.env["PATH_INFO"]}/new"
96
92
  end
97
93
 
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
94
  def singular_resource_name
103
95
  if @reflection.present?
104
96
  ::Avo::App.get_resource_by_model_name(@reflection.class_name).name
105
97
  else
106
- @resource.singular_name.present? ? @resource.singular_name : @resource.model_class.model_name.name.downcase
98
+ @resource.singular_name || @resource.model_class.model_name.name.downcase
107
99
  end
108
100
  end
109
101
 
@@ -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.model, via_relation_class: params[:via_relation_class], via_resource_id: params[:via_resource_id]), local: true, multipart: true do |form| %>
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,7 +8,7 @@
8
8
  <%= svg 'arrow-left' %> <%= t('avo.cancel').capitalize %>
9
9
  <% end %>
10
10
 
11
- <%= a_button color: 'green', type: :submit do %>
11
+ <%= a_button color: 'green', spinner: true, type: :submit do %>
12
12
  <%= svg 'save' %> <%= t('avo.save').capitalize %>
13
13
  <% end if @resource.authorization.authorize_action :create, raise_exception: false %>
14
14
  </div>
@@ -14,9 +14,9 @@ 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.model)
19
+ helpers.resources_path(resource: @resource)
20
20
  end
21
21
  end
22
22
 
@@ -25,4 +25,8 @@ class Avo::Views::ResourceNewComponent < ViewComponent::Base
25
25
  def via_resource?
26
26
  params[:via_relation_class].present? && params[:via_resource_id].present?
27
27
  end
28
+
29
+ def relation_resource
30
+ ::Avo::App.get_resource_by_model_name params[:via_relation_class].safe_constantize
31
+ end
28
32
  end
@@ -1,9 +1,9 @@
1
1
  <div data-model-id="<%= @resource.model.id %>"
2
- data-selected-resources-name="<%= @resource.model.model_name.route_key %>"
2
+ data-selected-resources-name="<%= @resource.model_key %>"
3
3
  data-selected-resources='["<%= @resource.model.id %>"]'
4
4
  >
5
- <% @resource.panels.each do |resource_panel| %>
6
- <%= render Avo::PanelComponent.new(title: resource_panel[:name], display_breadcrumbs: @reflection.blank?) do |c| %>
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' %>
@@ -25,8 +25,9 @@
25
25
  <% end %>
26
26
 
27
27
  <% if @resource.authorization.authorize_action(:destroy, raise_exception: false) %>
28
- <%= form_with url: helpers.resource_path(@resource.model), method: :delete, html: { 'data-turbo-frame': params[:turbo_frame] } do |form| %>
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.model)
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
- helpers.edit_resource_path(@resource.model, via_resource_class: params[:via_resource_class], via_resource_id: params[:via_resource_id])
27
- else
28
- helpers.edit_resource_path(@resource.model)
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,7 +39,7 @@ 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?
@@ -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.model_class), "#{response[:message_type]}": response[:message]
70
+ redirect_back fallback_location: resources_path(resource: @resource), "#{response[:message_type]}": response[:message]
71
71
  end
72
72
  end
73
73
  end