avo 2.5.2.pre.2 → 2.5.2.pre.5

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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -2
  3. data/Gemfile.lock +1 -4
  4. data/app/assets/builds/avo.css +284 -809
  5. data/app/assets/builds/avo.js +123 -212
  6. data/app/assets/builds/avo.js.map +3 -3
  7. data/app/assets/stylesheets/avo.css +33 -3
  8. data/app/assets/stylesheets/css/search.css +1 -1
  9. data/app/assets/svgs/heroicons/solid/user-remove.svg +1 -1
  10. data/app/components/avo/actions_component.html.erb +2 -1
  11. data/app/components/avo/alert_component.html.erb +1 -1
  12. data/app/components/avo/alert_component.rb +24 -5
  13. data/app/components/avo/button_component.rb +2 -0
  14. data/app/components/avo/filters_component.html.erb +1 -1
  15. data/app/components/avo/index/field_wrapper_component.html.erb +1 -1
  16. data/app/components/avo/index/grid_cover_empty_state_component.html.erb +1 -1
  17. data/app/components/avo/index/resource_table_component.html.erb +1 -1
  18. data/app/components/avo/index/table_row_component.html.erb +1 -1
  19. data/app/components/avo/panel_component.html.erb +3 -3
  20. data/app/components/avo/panel_component.rb +1 -1
  21. data/app/components/avo/resource_component.rb +50 -0
  22. data/app/components/avo/sidebar/group_component.html.erb +4 -2
  23. data/app/components/avo/sidebar/heading_component.html.erb +2 -2
  24. data/app/components/avo/sidebar/link_component.rb +1 -1
  25. data/app/components/avo/sidebar_component.html.erb +5 -13
  26. data/app/components/avo/sidebar_profile_component.html.erb +1 -1
  27. data/app/components/avo/views/resource_edit_component.html.erb +28 -3
  28. data/app/components/avo/views/resource_edit_component.rb +4 -6
  29. data/app/components/avo/views/resource_index_component.html.erb +15 -7
  30. data/app/components/avo/views/resource_new_component.html.erb +8 -2
  31. data/app/components/avo/views/resource_show_component.html.erb +15 -5
  32. data/app/components/avo/views/resource_show_component.rb +0 -45
  33. data/app/controllers/avo/actions_controller.rb +23 -8
  34. data/app/controllers/avo/associations_controller.rb +3 -3
  35. data/app/controllers/avo/base_controller.rb +25 -16
  36. data/app/controllers/avo/search_controller.rb +2 -2
  37. data/app/helpers/avo/application_helper.rb +1 -1
  38. data/app/javascript/js/application.js +1 -1
  39. data/app/javascript/js/controllers/fields/key_value_controller.js +1 -1
  40. data/app/javascript/js/controllers/filter_controller.js +4 -1
  41. data/app/javascript/js/controllers/menu_controller.js +2 -2
  42. data/app/javascript/js/controllers.js +0 -4
  43. data/app/views/avo/actions/show.html.erb +5 -2
  44. data/app/views/avo/partials/_logo.html.erb +1 -1
  45. data/app/views/avo/partials/_navbar.html.erb +9 -6
  46. data/app/views/avo/partials/_table_header.html.erb +3 -2
  47. data/app/views/avo/private/_links_and_buttons.html.erb +1 -1
  48. data/app/views/layouts/avo/application.html.erb +50 -53
  49. data/db/factories.rb +0 -2
  50. data/lib/avo/base_action.rb +24 -6
  51. data/lib/avo/base_resource.rb +0 -6
  52. data/lib/avo/engine.rb +1 -1
  53. data/lib/avo/fields/base_field.rb +1 -2
  54. data/lib/avo/fields/belongs_to_field.rb +4 -4
  55. data/lib/avo/fields/has_and_belongs_to_many_field.rb +2 -2
  56. data/lib/avo/fields/has_base_field.rb +2 -0
  57. data/lib/avo/fields/has_many_field.rb +2 -2
  58. data/lib/avo/fields/has_one_field.rb +2 -2
  59. data/lib/avo/licensing/pro_license.rb +1 -2
  60. data/lib/avo/version.rb +1 -1
  61. data/lib/generators/avo/templates/locales/avo.en.yml +0 -4
  62. data/public/avo-assets/avo.css +227 -821
  63. data/public/avo-assets/avo.js +123 -212
  64. data/public/avo-assets/avo.js.map +3 -3
  65. metadata +2 -19
  66. data/app/assets/stylesheets/css/alerts.css +0 -35
  67. data/app/assets/stylesheets/css/tags.css +0 -16
  68. data/app/components/avo/fields/tags_field/edit_component.html.erb +0 -27
  69. data/app/components/avo/fields/tags_field/edit_component.rb +0 -4
  70. data/app/components/avo/fields/tags_field/index_component.html.erb +0 -14
  71. data/app/components/avo/fields/tags_field/index_component.rb +0 -7
  72. data/app/components/avo/fields/tags_field/show_component.html.erb +0 -7
  73. data/app/components/avo/fields/tags_field/show_component.rb +0 -11
  74. data/app/components/avo/fields/tags_field/tag_component.html.erb +0 -9
  75. data/app/components/avo/fields/tags_field/tag_component.rb +0 -11
  76. data/app/javascript/js/controllers/alerts_controller.js +0 -26
  77. data/app/javascript/js/controllers/base_controller.js +0 -22
  78. data/app/javascript/js/controllers/fields/tags_field_controller.js +0 -86
  79. data/app/javascript/js/controllers/fields/tags_field_helpers.js +0 -47
  80. data/lib/avo/concerns/handles_field_args.rb +0 -36
  81. data/lib/avo/fields/tags_field.rb +0 -82
  82. data/lib/avo/hosts/record_host.rb +0 -7
@@ -4,7 +4,6 @@
4
4
  @import './../../../node_modules/trix/dist/trix.css';
5
5
  @import './../../../node_modules/flatpickr/dist/flatpickr.css';
6
6
  @import './../../../node_modules/@algolia/autocomplete-theme-classic/dist/theme.css';
7
- @import './../../../node_modules/@yaireo/tagify/dist/tagify.css';
8
7
 
9
8
  @import 'tailwindcss/base';
10
9
 
@@ -12,14 +11,12 @@
12
11
  @import './css/buttons.css';
13
12
  @import './css/typography.css';
14
13
  @import './css/tooltips.css';
15
- @import './css/alerts.css';
16
14
  @import './css/loader.css';
17
15
  @import './css/pagination.css';
18
16
  @import './css/breadcrumbs.css';
19
17
  @import './css/search.css';
20
18
  @import './css/active-storage.css';
21
19
  @import './css/spinner.css';
22
- @import './css/tags.css';
23
20
 
24
21
  @import './css/components/status.css';
25
22
  @import './css/components/code.css';
@@ -91,3 +88,36 @@ trix-editor {
91
88
  max-height: 320px !important;
92
89
  overflow-y: auto;
93
90
  }
91
+
92
+ .scroll-shadows {
93
+ background:
94
+ /* Shadow Cover TOP */
95
+ linear-gradient(
96
+ #F6F6F7 30%,
97
+ #F6F6F7
98
+ ) center top,
99
+
100
+ /* Shadow Cover BOTTOM */
101
+ linear-gradient(
102
+ #F6F6F7,
103
+ #F6F6F7 70%
104
+ ) center bottom,
105
+
106
+ /* Shadow TOP */
107
+ radial-gradient(
108
+ farthest-side at 50% 0,
109
+ rgba(0, 0, 0, 0.2),
110
+ rgba(0, 0, 0, 0)
111
+ ) center top,
112
+
113
+ /* Shadow BOTTOM */
114
+ radial-gradient(
115
+ farthest-side at 50% 100%,
116
+ rgba(0, 0, 0, 0.2),
117
+ rgba(0, 0, 0, 0)
118
+ ) center bottom;
119
+
120
+ background-repeat: no-repeat;
121
+ background-size: 100% 34px, 100% 34px, 100% 14px, 100% 14px;
122
+ background-attachment: local, local, scroll, scroll;
123
+ }
@@ -32,7 +32,7 @@
32
32
 
33
33
  .aa-DetachedFormContainer,
34
34
  .aa-DetachedContainer .aa-Panel {
35
- @apply bg-gray-100 border-b-0;
35
+ @apply bg-gray-50 border-b-0;
36
36
  }
37
37
 
38
38
  .aa-Form {
@@ -1,3 +1,3 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
1
+ or<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
2
2
  <path d="M11 6a3 3 0 11-6 0 3 3 0 016 0zM14 17a6 6 0 00-12 0h12zM13 8a1 1 0 100 2h4a1 1 0 100-2h-4z"/>
3
3
  </svg>
@@ -3,7 +3,8 @@
3
3
  data-actions-picker-enabled-class="text-black hover:bg-blue-500 hover:text-white"
4
4
  data-actions-picker-disabled-class="cursor-wait text-gray-500"
5
5
  >
6
- <%= a_button style: :primary,
6
+ <%= a_button style: :outline,
7
+ color: :primary,
7
8
  class: "focus:outline-none",
8
9
  icon: 'arrow-circle-right',
9
10
  icon_class: 'transform rotate-90',
@@ -13,7 +13,7 @@
13
13
  <%== message %>
14
14
  </p>
15
15
  </div>
16
- <div class="ml-4 flex-shrink-0 flex">
16
+ <div class="ml-4 flex-shrink-0 flex items-center">
17
17
  <button data-action="alert#close" class="inline-flex text-white focus:outline-none focus:text-gray-300 transition ease-in-out duration-150">
18
18
  <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
19
19
  <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
@@ -12,7 +12,10 @@ class Avo::AlertComponent < ViewComponent::Base
12
12
  end
13
13
 
14
14
  def icon
15
- return "x-circle" if is_error?
15
+ return "heroicons/solid/x-circle" if is_error?
16
+ return "heroicons/solid/exclamation" if is_warning?
17
+ return "heroicons/solid/exclamation-circle" if is_info?
18
+ return "heroicons/solid/check-circle" if is_success?
16
19
 
17
20
  "check-circle"
18
21
  end
@@ -21,15 +24,31 @@ class Avo::AlertComponent < ViewComponent::Base
21
24
  result = "max-w-lg w-full shadow-lg rounded px-4 py-3 rounded relative border text-white pointer-events-auto"
22
25
 
23
26
  result += if is_error?
24
- " bg-red-400 border-red-700"
25
- else
26
- " bg-green-400 border-green-700"
27
+ " bg-red-400 border-red-600"
28
+ elsif is_success?
29
+ " bg-green-500 border-green-600"
30
+ elsif is_warning?
31
+ " bg-orange-400 border-orange-600"
32
+ elsif is_info?
33
+ " bg-blue-400 border-blue-600"
27
34
  end
28
35
 
29
36
  result
30
37
  end
31
38
 
32
39
  def is_error?
33
- type.to_sym == :error
40
+ type.to_sym == :error || type.to_sym == :alert
41
+ end
42
+
43
+ def is_success?
44
+ type.to_sym == :success
45
+ end
46
+
47
+ def is_info?
48
+ type.to_sym == :notice || type.to_sym == :info
49
+ end
50
+
51
+ def is_warning?
52
+ type.to_sym == :warning
34
53
  end
35
54
  end
@@ -117,6 +117,8 @@ class Avo::ButtonComponent < ViewComponent::Base
117
117
  " bg-primary-500 text-white border-primary-500 hover:bg-primary-600 hover:border-primary-600 active:border-primary-700 active:outline-primary-700 active:bg-primary-600"
118
118
  when :outline
119
119
  " bg-white text-#{@color}-500 border-#{@color}-500 hover:bg-#{@color}-100 active:bg-#{@color}-100 active:border-#{@color}-500 active:outline-#{@color}-500"
120
+ when :text
121
+ " text-#{@color}-500 active:outline-#{@color}-500 border-none hover:bg-gray-100"
120
122
  else
121
123
  ""
122
124
  end
@@ -14,7 +14,7 @@
14
14
  <% end %>
15
15
  <% end %>
16
16
  <div
17
- class="absolute block inset-auto sm:right-0 top-full bg-white min-w-[300px] mt-2 z-20 shadow-modal rounded divide-y divide-gray-300 <%= 'hidden' unless params[:keep_filters_panel_open] %>"
17
+ class="absolute block inset-auto sm:right-0 top-full bg-white min-w-[300px] mt-2 z-20 shadow-modal rounded divide-y divide-gray-300 <%= 'hidden' unless params[:keep_filters_panel_open] == '1' %>"
18
18
  data-toggle-panel-target="panel"
19
19
  >
20
20
  <% @filters.each do |filter| %>
@@ -1,4 +1,4 @@
1
- <td class="min-h-[3rem] px-3 leading-tight whitespace-nowrap h-full text-slate-800 <%= classes %>" data-field-id="<%= @field.id %>" data-field-type="<%= @field.type %>">
1
+ <td class="min-h-[3rem] px-3 leading-tight whitespace-nowrap h-full text-slate-800 text-base <%= classes %>" data-field-id="<%= @field.id %>" data-field-type="<%= @field.type %>">
2
2
  <% if @field.value.blank? && @dash_if_blank %>
3
3
 
4
4
  <% else %>
@@ -1,3 +1,3 @@
1
- <div class="absolute bg-gray-100 w-full h-full">
1
+ <div class="absolute bg-gray-50 w-full h-full">
2
2
  <%= 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' %>
3
3
  </div>
@@ -1,5 +1,5 @@
1
1
  <div class="w-full ">
2
- <table class="w-full px-4 bg-white" data-resource-name='<%= @resource.model_key %>' data-controller='item-select-all'>
2
+ <table class="w-full px-4 bg-white rounded" data-resource-name='<%= @resource.model_key %>' data-controller='item-select-all'>
3
3
  <%= render partial: 'avo/partials/table_header', locals: {fields: @resource.get_fields(reflection: @reflection)} %>
4
4
  <tbody class="divide-y">
5
5
  <% @resources.each_with_index do |resource, index| %>
@@ -1,5 +1,5 @@
1
1
  <tr
2
- class="bg-white hover:bg-blue-50 hover:shadow-row hover:z-[21] relative z-20 border-b"
2
+ class="bg-white hover:bg-gray-50 hover:shadow-row hover:z-[21] relative z-20 border-b"
3
3
  <%== item_selector_init @resource %>
4
4
  >
5
5
  <% if @resource.record_selector %>
@@ -1,7 +1,7 @@
1
1
  <div <%== data_attributes %>>
2
2
  <% if render_header? %>
3
- <div class="<%= white_panel_classes %> p-4 flex-1 flex flex-col xl:flex-row justify-between mb-6">
4
- <div class="overflow-hidden mr-4 flex flex-col">
3
+ <div class="flex-1 flex flex-col xl:flex-row justify-between mb-4">
4
+ <div class="overflow-hidden flex flex-col">
5
5
  <% if display_breadcrumbs? %>
6
6
  <div class="breadcrumbs truncate mb-2">
7
7
  <%= helpers.render_breadcrumbs(separator: helpers.svg('chevron-right', class: 'inline-block h-3 stroke-current relative top-[-1px] ml-1' )) if Avo.configuration.display_breadcrumbs %>
@@ -13,7 +13,7 @@
13
13
  </div>
14
14
 
15
15
  <% if description.present? %>
16
- <div class="text-base tracking-normal font-medium text-gray-600" data-target="description">
16
+ <div class="text-sm tracking-normal font-medium text-gray-600" data-target="description">
17
17
  <%== description %>
18
18
  </div>
19
19
  <% end %>
@@ -21,7 +21,7 @@ class Avo::PanelComponent < ViewComponent::Base
21
21
  private
22
22
 
23
23
  def white_panel_classes
24
- 'bg-white rounded shadow'
24
+ "bg-white rounded shadow"
25
25
  end
26
26
 
27
27
  def data_attributes
@@ -11,6 +11,26 @@ class Avo::ResourceComponent < Avo::BaseComponent
11
11
  @resource.authorization.authorize_action(:destroy, raise_exception: false)
12
12
  end
13
13
 
14
+ def can_detach?
15
+ authorize_association_for("detach")
16
+ end
17
+
18
+ def can_see_the_edit_button?
19
+ @resource.authorization.authorize_action(:edit, raise_exception: false)
20
+ end
21
+
22
+ def can_see_the_destroy_button?
23
+ @resource.authorization.authorize_action(:destroy, raise_exception: false)
24
+ end
25
+
26
+ def detach_path
27
+ helpers.resource_detach_path(params[:resource_name], params[:id], @reflection.name.to_s, @resource.model.id)
28
+ end
29
+
30
+ def destroy_path
31
+ helpers.resource_path(model: @resource.model, resource: @resource)
32
+ end
33
+
14
34
  def authorize_association_for(policy_method)
15
35
  association_policy = true
16
36
 
@@ -30,4 +50,34 @@ class Avo::ResourceComponent < Avo::BaseComponent
30
50
 
31
51
  association_policy
32
52
  end
53
+
54
+ def split_panel_fields
55
+ initialize_panels
56
+ @resource.get_fields.each do |field|
57
+ case field.class.to_s
58
+ when "Avo::Fields::HasOneField"
59
+ @has_one_panels << field
60
+ when "Avo::Fields::HasManyField"
61
+ @has_many_panels << field
62
+ when "Avo::Fields::HasAndBelongsToManyField"
63
+ @has_as_belongs_to_many_panels << field
64
+ else
65
+ @fields_by_panel[field.panel_name] ||= []
66
+ @fields_by_panel[field.panel_name] << field
67
+ end
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ def initialize_panels
74
+ @fields_by_panel = {}
75
+ @has_one_panels = []
76
+ @has_many_panels = []
77
+ @has_as_belongs_to_many_panels = []
78
+ end
79
+
80
+ def via_resource?
81
+ params[:via_resource_class].present? && params[:via_resource_id].present?
82
+ end
33
83
  end
@@ -7,12 +7,14 @@
7
7
  <% end %>
8
8
  >
9
9
  <% if item.name.present? %>
10
- <div class="flex justify-between px-10 pt-2 pb-0 text-gray-600 ">
10
+ <div
11
+ class="flex justify-between px-10 pt-2 pb-0 text-gray-400"
12
+ >
11
13
  <div class="flex items-center text-xs uppercase font-semibold leading-none">
12
14
  <%= item.name %>
13
15
  </div>
14
16
  <% if collapsable %>
15
- <div class="cursor-pointer <%= 'rotate-90' if collapsed %>"
17
+ <div class="cursor-pointer <%= 'rotate-180' if collapsed %>"
16
18
  data-action="click->menu#triggerCollapse"
17
19
  data-menu-target="svg"
18
20
  data-menu-key-param="<%= key %>"
@@ -1,9 +1,9 @@
1
- <div class="flex justify-between p-4 py-2 text-gray-500">
1
+ <div class="flex justify-between px-6 py-2 text-gray-500">
2
2
  <div class="flex items-center text-sm uppercase font-semibold leading-none space-x-1">
3
3
  <span class="min-w-[20px]"><%= icon %></span> <span><%= label %></span>
4
4
  </div>
5
5
  <% if collapsable %>
6
- <div class="cursor-pointer <%= 'rotate-90' if collapsed %>"
6
+ <div class="cursor-pointer <%= 'rotate-180' if collapsed %>"
7
7
  data-action="click->menu#triggerCollapse"
8
8
  data-menu-key-param="<%= key %>"
9
9
  data-menu-target="svg"
@@ -23,6 +23,6 @@ class Avo::Sidebar::LinkComponent < ViewComponent::Base
23
23
  end
24
24
 
25
25
  def classes
26
- "px-4 flex-1 flex mx-6 leading-none py-2 text-black rounded font-medium hover:bg-gray-150"
26
+ "px-4 flex-1 flex mx-6 leading-none py-2 text-black rounded font-medium hover:bg-gray-100"
27
27
  end
28
28
  end
@@ -1,24 +1,16 @@
1
1
  <div
2
- class="fixed z-[60] application-sidebar hidden lg:flex h-full bg-white text-white w-64 border-r <%= 'print:hidden' if Avo.configuration.hide_layout_when_printing %>"
2
+ class="fixed z-[60] t-0 application-sidebar hidden lg:flex flex-1 border-r lg:border-none bg-none min-w-[16rem] h-[calc(100vh-4rem)] bg-gray-25 lg:bg-transparent <%= 'print:hidden' if Avo.configuration.hide_layout_when_printing %>"
3
3
  data-mobile-target="sidebar"
4
4
  >
5
5
  <div class="flex flex-col w-full h-full">
6
- <div class="flex justify-between">
7
- <%= render partial: "avo/partials/logo" %>
8
- <div class="flex items-center mr-4">
9
- <%= helpers.a_button class: "lg:hidden", icon: 'menu-back', data: { action: 'click->mobile#toggleSidebar' } %>
10
- </div>
11
- </div>
12
- <div class="flex-1 flex flex-col justify-between overflow-auto mt-3">
6
+ <div class="flex-1 flex flex-col justify-between overflow-auto h-full pt-3 scroll-shadows">
13
7
  <div class="space-y-6 mb-4">
14
8
  <%= render Avo::Sidebar::LinkComponent.new label: 'Get started', path: helpers.avo.root_path, active: :exclusive if Rails.env.development? && Avo.configuration.home_path.nil? %>
15
9
 
16
10
  <% if Avo::App.has_main_menu? %>
17
- <div class="text-black">
18
- <% Avo::App.main_menu.items.each do |item| %>
19
- <%= render Avo::Sidebar::ItemSwitcherComponent.new item: item %>
20
- <% end %>
21
- </div>
11
+ <% Avo::App.main_menu.items.each do |item| %>
12
+ <%= render Avo::Sidebar::ItemSwitcherComponent.new item: item %>
13
+ <% end %>
22
14
  <% else %>
23
15
 
24
16
  <% if dashboards.present? %>
@@ -1,4 +1,4 @@
1
- <div class="text-black border-t border-gray-200 p-4 flex">
1
+ <div class="text-black Xborder-t border-gray-200 p-4 flex">
2
2
  <div class="flex-1 flex space-x-4">
3
3
  <% if avatar.present? %>
4
4
  <div class="relative aspect-square w-10 h-10 overflow-hidden rounded">
@@ -1,4 +1,6 @@
1
- <div data-model-id="<%= @resource.model.id %>">
1
+ <div data-model-id="<%= @resource.model.id %>"
2
+ class="space-y-8"
3
+ >
2
4
  <% @resource.panels.each do |resource_panel| %>
3
5
  <%= form_with model: @resource.model,
4
6
  scope: @resource.form_scope,
@@ -9,11 +11,17 @@
9
11
  <%= render Avo::ReferrerParamsComponent.new back_path: back_path %>
10
12
  <%= render Avo::PanelComponent.new(title: resource_panel[:name], description: @resource.resource_description, display_breadcrumbs: true) do |c| %>
11
13
  <% c.tools do %>
12
- <%= a_link back_path, icon: 'arrow-left' do %>
14
+ <%= a_link back_path,
15
+ style: :text,
16
+ icon: 'arrow-left' do %>
13
17
  <%= t('avo.cancel').capitalize %>
14
18
  <% end %>
15
19
  <% if can_see_the_save_button? %>
16
- <%= a_button color: :green, loading: true, type: :submit, icon: 'save' do %>
20
+ <%= a_button color: :primary,
21
+ style: :primary,
22
+ loading: true,
23
+ type: :submit,
24
+ icon: 'save' do %>
17
25
  <%= t('avo.save').capitalize %>
18
26
  <% end %>
19
27
  <% end %>
@@ -40,4 +48,21 @@
40
48
  <% end %>
41
49
  <% end %>
42
50
  <% end %>
51
+ <% if @reflection.blank? %>
52
+ <% if has_one_panels.present? %>
53
+ <% has_one_panels.each_with_index do |field, index| %>
54
+ <%= render field.component_for_view(:show).new(field: field, resource: @resource, index: index) %>
55
+ <% end %>
56
+ <% end %>
57
+ <% if has_many_panels.present? %>
58
+ <% has_many_panels.each_with_index do |field, index| %>
59
+ <%= render field.component_for_view(:show).new(field: field, resource: @resource, index: index) %>
60
+ <% end %>
61
+ <% end %>
62
+ <% if has_as_belongs_to_many_panels.present? %>
63
+ <% has_as_belongs_to_many_panels.each_with_index do |field, index| %>
64
+ <%= render field.component_for_view(:show).new(field: field, resource: @resource, index: index) %>
65
+ <% end %>
66
+ <% end %>
67
+ <% end %>
43
68
  </div>
@@ -4,8 +4,12 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
4
4
  include Avo::ResourcesHelper
5
5
  include Avo::ApplicationHelper
6
6
 
7
+ attr_reader :fields_by_panel, :has_one_panels, :has_many_panels, :has_as_belongs_to_many_panels
8
+
7
9
  def initialize(resource: nil)
8
10
  @resource = resource
11
+
12
+ split_panel_fields
9
13
  end
10
14
 
11
15
  def back_path
@@ -21,10 +25,4 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
21
25
  def can_see_the_save_button?
22
26
  @resource.authorization.authorize_action :edit, raise_exception: false
23
27
  end
24
-
25
- private
26
-
27
- def via_resource?
28
- params[:via_resource_class].present? && params[:via_resource_id].present?
29
- end
30
28
  end
@@ -1,19 +1,28 @@
1
1
  <div>
2
2
  <%= render Avo::PanelComponent.new(title: title, description: description, data: { component: 'resources-index' }, display_breadcrumbs: @reflection.blank?) do |c| %>
3
3
  <% c.tools do %>
4
+ <% if can_attach? %>
5
+ <%= a_link attach_path,
6
+ icon: 'heroicons/outline/link',
7
+ color: :primary,
8
+ style: :text,
9
+ 'data-turbo-frame': 'attach_modal',
10
+ 'data-target': 'attach' do %>
11
+ <%= t('avo.attach_item', item: singular_resource_name).capitalize %>
12
+ <% end %>
13
+ <% end %>
4
14
  <% if can_see_the_actions_button? %>
5
15
  <%= render Avo::ActionsComponent.new actions: @actions, resource: @resource %>
6
16
  <% end %>
7
17
  <% if can_see_the_create_button? %>
8
- <%= a_link create_path, icon: 'heroicons/outline/plus', 'data-target': 'create', color: :primary do %>
18
+ <%= a_link create_path,
19
+ icon: 'heroicons/outline/plus',
20
+ 'data-target': 'create',
21
+ style: :primary,
22
+ color: :primary do %>
9
23
  <%= t('avo.create_new_item', item: singular_resource_name.downcase ) %>
10
24
  <% end %>
11
25
  <% end %>
12
- <% if can_attach? %>
13
- <%= a_link attach_path, icon: 'heroicons/outline/link', color: :primary, 'data-turbo-frame': 'attach_modal', 'data-target': 'attach' do %>
14
- <%= t('avo.attach_item', item: singular_resource_name).capitalize %>
15
- <% end %>
16
- <% end %>
17
26
  <% end %>
18
27
  <% c.body do %>
19
28
  <div class="flex flex-col xs:flex-row xs:justify-between space-y-2 xs:space-y-0 py-4 <%= 'hidden' if @resource.search_query.nil? && @filters.empty? && available_view_types.count <= 1 %>"
@@ -55,7 +64,6 @@
55
64
  </div>
56
65
  <% end %>
57
66
  <% end %>
58
-
59
67
  <% if view_type.to_sym == :grid %>
60
68
  <%= render Avo::Index::ResourceGridComponent.new(resources: @resources, resource: @resource, reflection: @reflection, parent_model: @parent_model) %>
61
69
  <div class="mt-14">
@@ -14,11 +14,17 @@
14
14
  <%= render Avo::PanelComponent.new(title: resource_panel[:name], description: @resource.resource_description, display_breadcrumbs: true) do |c| %>
15
15
  <% c.tools do %>
16
16
  <div class="flex justify-end space-x-2">
17
- <%= a_link back_path, icon: 'arrow-left' do %>
17
+ <%= a_link back_path,
18
+ style: :text,
19
+ icon: 'arrow-left' do %>
18
20
  <%= t('avo.cancel').capitalize %>
19
21
  <% end %>
20
22
  <% if can_see_the_save_button? %>
21
- <%= a_button color: 'green', loading: true, type: :submit, icon: 'save' do %>
23
+ <%= a_button color: :primary,
24
+ style: :primary,
25
+ loading: true,
26
+ type: :submit,
27
+ icon: 'save' do %>
22
28
  <%= t('avo.save').capitalize %>
23
29
  <% end %>
24
30
  <% end %>
@@ -8,32 +8,38 @@
8
8
  <% c.tools do %>
9
9
  <% if resource_panel[:name] == @resource.default_panel_name %>
10
10
  <% if @reflection.present? && @resource.model.present? %>
11
- <%= render Avo::ActionsComponent.new actions: @actions, resource: @resource %>
12
11
  <% if can_detach? %>
13
12
  <%= a_button url: detach_path,
14
13
  icon: 'detach',
15
14
  method: :delete,
16
15
  form_class: 'flex flex-col sm:flex-row sm:inline-flex',
16
+ style: :text,
17
17
  data: {
18
18
  confirm: "Are you sure you want to detach this #{@reflection.name.to_s}."
19
19
  } do %>
20
20
  <%= t('avo.detach_item', item: @reflection.name.to_s).capitalize %>
21
21
  <% end %>
22
+ <%= render Avo::ActionsComponent.new actions: @actions, resource: @resource %>
22
23
  <% end %>
23
24
  <% if can_see_the_edit_button? %>
24
- <%= a_link edit_path, color: :primary, icon: 'edit' do %>
25
+ <%= a_link edit_path,
26
+ color: :primary,
27
+ style: :primary,
28
+ icon: 'edit' do %>
25
29
  <%= t('avo.edit').capitalize %>
26
30
  <% end %>
27
31
  <% end %>
28
32
  <% else %>
29
- <%= a_link back_path, icon: 'arrow-left' do %>
33
+ <%= a_link back_path,
34
+ style: :text,
35
+ icon: 'arrow-left' do %>
30
36
  <%= t('avo.go_back') %>
31
37
  <% end %>
32
- <%= render Avo::ActionsComponent.new actions: @actions, resource: @resource %>
33
38
  <% if can_see_the_destroy_button? %>
34
39
  <%= a_button url: helpers.resource_path(model: @resource.model, resource: @resource),
35
40
  method: :delete,
36
41
  local: true,
42
+ style: :text,
37
43
  title: t('avo.delete_item', item: @resource.model.model_name.name.downcase).capitalize,
38
44
  loading: true,
39
45
  confirm: t('avo.are_you_sure', item: @resource.model.model_name.name.downcase),
@@ -48,8 +54,12 @@
48
54
  <%= t('avo.delete').capitalize %>
49
55
  <% end %>
50
56
  <% end %>
57
+ <%= render Avo::ActionsComponent.new actions: @actions, resource: @resource %>
51
58
  <% if @resource.authorization.authorize_action(:edit, raise_exception: false) %>
52
- <%= a_link edit_path, color: :primary, icon: 'edit' do %>
59
+ <%= a_link edit_path,
60
+ color: :primary,
61
+ style: :primary,
62
+ icon: 'edit' do %>
53
63
  <%= t('avo.edit').capitalize %>
54
64
  <% end %>
55
65
  <% end %>
@@ -44,53 +44,8 @@ class Avo::Views::ResourceShowComponent < Avo::ResourceComponent
44
44
  helpers.edit_resource_path(model: @resource.model, resource: @resource, **args)
45
45
  end
46
46
 
47
- def detach_path
48
- helpers.resource_detach_path(params[:resource_name], params[:id], @reflection.name.to_s, @resource.model.id)
49
- end
50
-
51
- def destroy_path
52
- helpers.resource_path(model: @resource.model, resource: @resource)
53
- end
54
-
55
- def can_detach?
56
- authorize_association_for("detach")
57
- end
58
-
59
- def can_see_the_edit_button?
60
- @resource.authorization.authorize_action(:edit, raise_exception: false)
61
- end
62
-
63
- def can_see_the_destroy_button?
64
- @resource.authorization.authorize_action(:destroy, raise_exception: false)
65
- end
66
-
67
47
  private
68
48
 
69
- def via_resource?
70
- params[:via_resource_class].present? && params[:via_resource_id].present?
71
- end
72
-
73
- def split_panel_fields
74
- @fields_by_panel = {}
75
- @has_one_panels = []
76
- @has_many_panels = []
77
- @has_as_belongs_to_many_panels = []
78
-
79
- @resource.get_fields.each do |field|
80
- case field.class.to_s
81
- when "Avo::Fields::HasOneField"
82
- @has_one_panels << field
83
- when "Avo::Fields::HasManyField"
84
- @has_many_panels << field
85
- when "Avo::Fields::HasAndBelongsToManyField"
86
- @has_as_belongs_to_many_panels << field
87
- else
88
- @fields_by_panel[field.panel_name] ||= []
89
- @fields_by_panel[field.panel_name] << field
90
- end
91
- end
92
- end
93
-
94
49
  # In development and test environments we shoudl show the invalid field errors
95
50
  def should_display_invalid_fields_errors?
96
51
  (Rails.env.development? || Rails.env.test?) && @resource.invalid_fields.present?