avo 3.0.0.pre12 → 3.0.0.pre15

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 (143) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +2 -1
  4. data/app/assets/stylesheets/avo.base.css +1 -1
  5. data/app/components/avo/actions_component.html.erb +1 -1
  6. data/app/components/avo/actions_component.rb +40 -16
  7. data/app/components/avo/alert_component.html.erb +1 -1
  8. data/app/components/avo/base_component.rb +7 -7
  9. data/app/components/avo/field_wrapper_component.html.erb +2 -2
  10. data/app/components/avo/field_wrapper_component.rb +1 -1
  11. data/app/components/avo/fields/area_field/edit_component.html.erb +1 -1
  12. data/app/components/avo/fields/belongs_to_field/edit_component.html.erb +5 -5
  13. data/app/components/avo/fields/belongs_to_field/edit_component.rb +4 -4
  14. data/app/components/avo/fields/boolean_field/edit_component.html.erb +1 -0
  15. data/app/components/avo/fields/boolean_group_field/edit_component.html.erb +1 -1
  16. data/app/components/avo/fields/code_field/edit_component.html.erb +1 -0
  17. data/app/components/avo/fields/common/heading_component.html.erb +1 -1
  18. data/app/components/avo/fields/country_field/edit_component.html.erb +1 -0
  19. data/app/components/avo/fields/file_field/index_component.rb +2 -2
  20. data/app/components/avo/fields/has_one_field/show_component.html.erb +1 -0
  21. data/app/components/avo/fields/index_component.rb +1 -0
  22. data/app/components/avo/fields/location_field/show_component.html.erb +1 -1
  23. data/app/components/avo/fields/markdown_field/edit_component.html.erb +4 -3
  24. data/app/components/avo/fields/markdown_field/show_component.html.erb +3 -3
  25. data/app/components/avo/fields/number_field/edit_component.html.erb +1 -0
  26. data/app/components/avo/fields/password_field/edit_component.html.erb +1 -0
  27. data/app/components/avo/fields/progress_bar_field/edit_component.html.erb +1 -0
  28. data/app/components/avo/fields/status_field/edit_component.html.erb +1 -1
  29. data/app/components/avo/fields/text_field/edit_component.html.erb +1 -1
  30. data/app/components/avo/fields/textarea_field/edit_component.html.erb +1 -0
  31. data/app/components/avo/fields/trix_field/edit_component.html.erb +2 -1
  32. data/app/components/avo/fields/trix_field/show_component.html.erb +1 -1
  33. data/app/components/avo/index/field_wrapper_component.html.erb +1 -1
  34. data/app/components/avo/index/grid_item_component.html.erb +9 -35
  35. data/app/components/avo/index/grid_item_component.rb +36 -10
  36. data/app/components/avo/index/resource_controls_component.rb +6 -6
  37. data/app/components/avo/index/resource_table_component.rb +1 -1
  38. data/app/components/avo/item_switcher_component.html.erb +9 -4
  39. data/app/components/avo/item_switcher_component.rb +2 -1
  40. data/app/components/avo/panel_component.html.erb +1 -1
  41. data/app/components/avo/profile_item_component.html.erb +17 -2
  42. data/app/components/avo/profile_item_component.rb +13 -1
  43. data/app/components/avo/resource_component.rb +6 -3
  44. data/app/components/avo/resource_sidebar_component.rb +1 -1
  45. data/app/components/avo/row_component.html.erb +3 -0
  46. data/app/components/avo/row_component.rb +12 -0
  47. data/app/components/avo/sidebar/link_component.html.erb +2 -0
  48. data/app/components/avo/sidebar/link_component.rb +5 -3
  49. data/app/components/avo/sidebar_component.html.erb +3 -3
  50. data/app/components/avo/sidebar_component.rb +4 -4
  51. data/app/components/avo/sidebar_profile_component.html.erb +27 -27
  52. data/app/components/avo/views/resource_edit_component.rb +1 -1
  53. data/app/components/avo/views/resource_index_component.html.erb +1 -1
  54. data/app/components/avo/views/resource_index_component.rb +8 -8
  55. data/app/controllers/avo/actions_controller.rb +16 -8
  56. data/app/controllers/avo/application_controller.rb +71 -66
  57. data/app/controllers/avo/associations_controller.rb +4 -6
  58. data/app/controllers/avo/attachments_controller.rb +1 -1
  59. data/app/controllers/avo/base_controller.rb +39 -27
  60. data/app/controllers/avo/home_controller.rb +1 -1
  61. data/app/controllers/avo/search_controller.rb +18 -20
  62. data/app/controllers/concerns/avo/initializes_avo.rb +3 -6
  63. data/app/javascript/js/controllers/fields/{simple_mde_controller.js → easy_mde_controller.js} +4 -3
  64. data/app/javascript/js/controllers/search_controller.js +3 -1
  65. data/app/javascript/js/controllers.js +2 -2
  66. data/app/views/avo/actions/show.html.erb +2 -1
  67. data/app/views/avo/associations/new.html.erb +1 -1
  68. data/app/views/avo/debug/status.html.erb +1 -1
  69. data/app/views/avo/partials/_custom_tools_alert.html.erb +2 -2
  70. data/app/views/avo/partials/_footer.html.erb +1 -1
  71. data/app/views/avo/partials/_javascript.html.erb +1 -1
  72. data/app/views/avo/partials/_navbar.html.erb +1 -1
  73. data/app/views/avo/partials/_profile_menu_extra.html.erb +2 -0
  74. data/app/views/layouts/avo/application.html.erb +2 -2
  75. data/avo.gemspec +1 -0
  76. data/config/initializers/pagy.rb +12 -10
  77. data/config/routes.rb +3 -3
  78. data/db/factories.rb +2 -1
  79. data/lib/avo/base_action.rb +12 -3
  80. data/lib/avo/base_resource.rb +183 -181
  81. data/lib/avo/concerns/filters_session_handler.rb +0 -1
  82. data/lib/avo/concerns/has_item_type.rb +4 -0
  83. data/lib/avo/concerns/has_items.rb +28 -23
  84. data/lib/avo/concerns/model_class_constantized.rb +0 -2
  85. data/lib/avo/configuration.rb +6 -2
  86. data/lib/avo/current.rb +29 -2
  87. data/lib/avo/dsl/field_parser.rb +1 -1
  88. data/lib/avo/dynamic_router.rb +12 -1
  89. data/lib/avo/engine.rb +8 -6
  90. data/lib/avo/execution_context.rb +1 -1
  91. data/lib/avo/fields/base_field.rb +25 -7
  92. data/lib/avo/fields/belongs_to_field.rb +20 -13
  93. data/lib/avo/fields/concerns/is_searchable.rb +1 -1
  94. data/lib/avo/fields/concerns/use_resource.rb +1 -1
  95. data/lib/avo/fields/field_manager.rb +13 -3
  96. data/lib/avo/fields/has_base_field.rb +5 -5
  97. data/lib/avo/fields/has_one_field.rb +1 -1
  98. data/lib/avo/fields/location_field.rb +18 -1
  99. data/lib/avo/filters/base_filter.rb +3 -1
  100. data/lib/avo/html/builder.rb +3 -1
  101. data/lib/avo/licensing/h_q.rb +11 -6
  102. data/lib/avo/licensing/license.rb +1 -1
  103. data/lib/avo/licensing/license_manager.rb +1 -1
  104. data/lib/avo/licensing/{null_license.rb → nil_license.rb} +1 -1
  105. data/lib/avo/loaders/fields_loader.rb +7 -1
  106. data/lib/avo/plugin_manager.rb +2 -4
  107. data/lib/avo/reloader.rb +1 -1
  108. data/lib/avo/resources/controls/actions_list.rb +2 -1
  109. data/lib/avo/resources/items/holder.rb +5 -1
  110. data/lib/avo/resources/items/item_group.rb +1 -0
  111. data/lib/avo/resources/items/row.rb +54 -0
  112. data/lib/avo/resources/resource_manager.rb +4 -7
  113. data/lib/avo/services/debug_service.rb +6 -6
  114. data/lib/avo/services/telemetry_service.rb +3 -3
  115. data/lib/avo/version.rb +1 -1
  116. data/lib/avo.rb +107 -25
  117. data/lib/generators/avo/action_generator.rb +8 -8
  118. data/lib/generators/avo/card_generator.rb +27 -0
  119. data/lib/generators/avo/eject_generator.rb +1 -0
  120. data/lib/generators/avo/filter_generator.rb +8 -8
  121. data/lib/generators/avo/install_generator.rb +0 -1
  122. data/lib/generators/avo/resource_generator.rb +4 -1
  123. data/lib/generators/avo/templates/action.tt +3 -3
  124. data/lib/generators/avo/templates/cards/chartkick_card.tt +1 -1
  125. data/lib/generators/avo/templates/cards/chartkick_card_sample.tt +1 -1
  126. data/lib/generators/avo/templates/cards/metric_card.tt +1 -1
  127. data/lib/generators/avo/templates/cards/metric_card_sample.tt +1 -1
  128. data/lib/generators/avo/templates/cards/partial_card.tt +1 -1
  129. data/lib/generators/avo/templates/cards/partial_card_sample.tt +1 -1
  130. data/lib/generators/avo/templates/dashboards/dashboard.tt +1 -1
  131. data/lib/generators/avo/templates/resource/resource.tt +3 -4
  132. data/lib/generators/avo/templates/scope.tt +1 -1
  133. data/lib/tasks/avo_tasks.rake +1 -1
  134. data/public/avo-assets/avo.base.css +295 -165
  135. data/public/avo-assets/avo.base.js +307 -278
  136. data/public/avo-assets/avo.base.js.map +3 -3
  137. metadata +23 -10
  138. data/lib/avo/app.rb +0 -170
  139. data/lib/avo/grid_collector.rb +0 -40
  140. data/lib/generators/avo/card/chartkick_generator.rb +0 -18
  141. data/lib/generators/avo/card/metric_generator.rb +0 -18
  142. data/lib/generators/avo/card/partial_generator.rb +0 -19
  143. data/lib/generators/avo/templates/standalone_action.tt +0 -15
@@ -2,30 +2,26 @@
2
2
 
3
3
  class Avo::Index::GridItemComponent < Avo::BaseComponent
4
4
  include Avo::ResourcesHelper
5
+ include Avo::Fields::Concerns::HasHTMLAttributes
5
6
 
6
7
  attr_reader :parent_resource, :actions
7
8
 
8
9
  def initialize(resource: nil, reflection: nil, parent_record: nil, parent_resource: nil, actions: nil)
9
10
  @resource = resource
10
11
  @reflection = reflection
11
- @grid_fields = resource.get_grid_fields
12
12
  @parent_record = parent_record
13
13
  @parent_resource = parent_resource
14
14
  @actions = actions
15
+ @card = Avo::ExecutionContext.new(target: resource.grid_view[:card], resource: resource, record: resource.record).handle
16
+ @whole_html = Avo::ExecutionContext.new(target: resource.grid_view[:html], resource: resource, record: resource.record).handle
15
17
  end
16
18
 
17
19
  private
18
20
 
19
- def cover
20
- @grid_fields.cover_field
21
- end
22
-
23
- def title
24
- @grid_fields.title_field
25
- end
21
+ def html(element, type)
22
+ return "" if @whole_html.nil? || (@html = @whole_html[element]).nil?
26
23
 
27
- def body
28
- @grid_fields.body_field
24
+ get_html(type, view: :index, element: :wrapper)
29
25
  end
30
26
 
31
27
  def resource_view_path
@@ -40,4 +36,34 @@ class Avo::Index::GridItemComponent < Avo::BaseComponent
40
36
 
41
37
  helpers.resource_view_path(record: @resource.record, resource: parent_or_child_resource, **args)
42
38
  end
39
+
40
+ def render_cover
41
+ return link_to_cover if @card[:cover_url].present?
42
+
43
+ link_to resource_view_path do
44
+ render Avo::Index::GridCoverEmptyStateComponent.new
45
+ end
46
+ end
47
+
48
+ def link_to_cover
49
+ classes = "absolute h-full w-full object-cover"
50
+
51
+ link_to image_tag(@card[:cover_url], class: classes), resource_view_path, class: classes, title: @card[:title]
52
+ end
53
+
54
+ def render_title
55
+ return if @card[:title].blank?
56
+
57
+ content_tag :div, class: "grid font-semibold leading-tight text-lg mb-2 #{html(:title, :classes)}", style: html(:title, :style) do
58
+ link_to @card[:title], resource_view_path
59
+ end
60
+ end
61
+
62
+ def render_body
63
+ return if @card[:body].blank?
64
+
65
+ content_tag :div, class: "text-sm break-words text-gray-500 #{html(:body, :classes)}", style: html(:body, :style) do
66
+ @card[:body]
67
+ end
68
+ end
43
69
  end
@@ -44,7 +44,7 @@ class Avo::Index::ResourceControlsComponent < Avo::ResourceComponent
44
44
  }
45
45
  end
46
46
 
47
- helpers.resource_path(record: @resource.record, resource: parent_or_child_resource , **args)
47
+ helpers.resource_path(record: @resource.record, resource: parent_or_child_resource, **args)
48
48
  end
49
49
 
50
50
  def edit_path
@@ -73,7 +73,7 @@ class Avo::Index::ResourceControlsComponent < Avo::ResourceComponent
73
73
  return @parent_resource if @parent_resource.present?
74
74
  return nil if @parent_record.blank?
75
75
 
76
- ::Avo::App.resources.get_resource_by_model_class @parent_record.class
76
+ Avo.resource_manager.get_resource_by_model_class @parent_record.class
77
77
  end
78
78
 
79
79
  def is_has_many_association
@@ -81,11 +81,11 @@ class Avo::Index::ResourceControlsComponent < Avo::ResourceComponent
81
81
  end
82
82
 
83
83
  def referrer_path
84
- Avo::App.root_path(paths: ["resources", params[:resource_name], params[:id], params[:related_name]], query: request.query_parameters.to_h)
84
+ Avo.root_path(paths: ["resources", params[:resource_name], params[:id], params[:related_name]], query: request.query_parameters.to_h)
85
85
  end
86
86
 
87
87
  def can_reorder?
88
- return false unless Object.const_defined? "AvoPro::Ordering"
88
+ return false unless Object.const_defined? "Avo::Pro::Ordering"
89
89
 
90
90
  return authorize_association_for(:reorder) if @reflection.present?
91
91
 
@@ -167,13 +167,13 @@ class Avo::Index::ResourceControlsComponent < Avo::ResourceComponent
167
167
  target: "control:detach",
168
168
  control: :detach,
169
169
  "resource-id": @resource.record.id,
170
- "tippy": "tooltip",
170
+ tippy: :tooltip,
171
171
  }
172
172
  end
173
173
 
174
174
  def render_order_controls(control)
175
175
  if can_reorder?
176
- render AvoPro::Ordering::ButtonsComponent.new resource: @resource, reflection: @reflection, view_type: @view_type
176
+ render Avo::Pro::Ordering::ButtonsComponent.new resource: @resource, reflection: @reflection, view_type: @view_type
177
177
  end
178
178
  end
179
179
 
@@ -17,7 +17,7 @@ class Avo::Index::ResourceTableComponent < ViewComponent::Base
17
17
 
18
18
  def encrypted_query
19
19
  # TODO: move this to the resource where we can apply the adapter pattern
20
- serialized_query = if query.instance_of?(Ransack::Search)
20
+ serialized_query = if Module.const_defined?("Ransack::Search") && query.instance_of?(Ransack::Search)
21
21
  query.context.object.to_sql
22
22
  else
23
23
  return :select_all_disabled if query.nil? || !query.respond_to?(:all) || !query.all.respond_to?(:to_sql)
@@ -7,10 +7,7 @@
7
7
  <% c.with_body do %>
8
8
  <div class="divide-y">
9
9
  <% item.visible_items.each_with_index do |field, index| %>
10
- <%= render field
11
- .hydrate(resource: @resource, record: @resource.record, user: resource.user, view: view)
12
- .component_for_view(view)
13
- .new(field: field, resource: @resource, index: index, form: form) %>
10
+ <%= render Avo::ItemSwitcherComponent.new resource: @resource, item: field, index: index, view: @view, form: form %>
14
11
  <% end %>
15
12
  </div>
16
13
  <% end %>
@@ -19,4 +16,12 @@
19
16
  <%= render tab_group_component %>
20
17
  <% elsif item.is_field? %>
21
18
  <%= render field_component %>
19
+ <% elsif item.is_row? %>
20
+ <%= render Avo::RowComponent.new do |c| %>
21
+ <% c.with_body do %>
22
+ <% item.visible_items.each_with_index do |field, index| %>
23
+ <%= render Avo::ItemSwitcherComponent.new resource: @resource, item: field, index: index, view: @view, form: form %>
24
+ <% end %>
25
+ <% end %>
26
+ <% end %>
22
27
  <% end %>
@@ -42,6 +42,7 @@ class Avo::ItemSwitcherComponent < Avo::BaseComponent
42
42
  end
43
43
 
44
44
  def field_component
45
- item.component_for_view(@view).new(field: item.hydrate(resource: @resource, view: @view, record: @resource.record), resource: @resource, index: index, form: form)
45
+ final_item = item.dup.hydrate(resource: @resource, record: @resource.record, user: resource.user, view: view)
46
+ final_item.component_for_view(@view).new(field: final_item, resource: @resource, index: index, form: form)
46
47
  end
47
48
  end
@@ -25,7 +25,7 @@
25
25
  <% end %>
26
26
  <% if body? %>
27
27
  <div data-target="panel-body" class="flex flex-col sm:flex-row space-y-4 sm:space-y-0 sm:gap-4 w-full">
28
- <div class="relative flex-1 <% if sidebar? %> w-2/3 <% else %> w-full <% end %>">
28
+ <div class="relative flex-1 w-full <% if sidebar? %> sm:w-2/3 <% end %>">
29
29
  <% # The body is wrapped inside another div in order to avoid long & tall panels next to sidebars when the sidebar taller. %>
30
30
  <div class="relative <%= white_panel_classes %> <%= @body_classes %>">
31
31
  <%= body %>
@@ -1,3 +1,18 @@
1
- <%= link_to path, class: "flex-1 flex items-center justify-center bg-white text-left cursor-pointer text-gray-800 font-semibold hover:bg-primary-100 block px-4 py-1 w-full py-3 text-center rounded w-full", target: target, title: title do %>
2
- <%= helpers.svg(icon, class: 'h-4 mr-1') if icon.present? %> <%= label %>
1
+ <% if method.present? %>
2
+ <%= button_to path,
3
+ form_class: "flex-1 flex",
4
+ class: button_classes,
5
+ target: target,
6
+ title: title,
7
+ method: method,
8
+ params: params do %>
9
+ <%= helpers.svg(icon, class: 'h-4 mr-1') if icon.present? %> <%= label %>
10
+ <% end %>
11
+ <% else %>
12
+ <%= link_to path,
13
+ class: button_classes,
14
+ target: target,
15
+ title: title do %>
16
+ <%= helpers.svg(icon, class: 'h-4 mr-1') if icon.present? %> <%= label %>
17
+ <% end %>
3
18
  <% end %>
@@ -6,17 +6,29 @@ class Avo::ProfileItemComponent < ViewComponent::Base
6
6
  attr_reader :path
7
7
  attr_reader :active
8
8
  attr_reader :target
9
+ attr_reader :method
10
+ attr_reader :params
11
+ attr_reader :classes
9
12
 
10
- def initialize(label: nil, icon: nil, path: nil, active: :inclusive, target: nil, title: nil)
13
+ def initialize(label: nil, icon: nil, path: nil, active: :inclusive, target: nil, title: nil, method: nil, params: {}, classes: "")
11
14
  @label = label
12
15
  @icon = icon
13
16
  @path = path
14
17
  @active = active
15
18
  @target = target
16
19
  @title = title
20
+ @method = method
21
+ @params = params
22
+ @classes = classes
17
23
  end
18
24
 
19
25
  def title
20
26
  @title || @label
21
27
  end
28
+
29
+ private
30
+
31
+ def button_classes
32
+ "flex-1 flex items-center justify-center bg-white text-left cursor-pointer text-gray-800 font-semibold hover:bg-primary-100 block px-4 py-1 w-full py-3 text-center rounded w-full"
33
+ end
22
34
  end
@@ -102,7 +102,7 @@ class Avo::ResourceComponent < Avo::BaseComponent
102
102
  end
103
103
 
104
104
  def sidebar
105
- return if Avo::App.license.lacks_with_trial(:resource_sidebar)
105
+ return if Avo.license.lacks_with_trial(:resource_sidebar)
106
106
 
107
107
  @sidebar ||= search_for_sidebar
108
108
  end
@@ -113,7 +113,8 @@ class Avo::ResourceComponent < Avo::BaseComponent
113
113
 
114
114
  def has_reflection_and_is_read_only
115
115
  if @reflection.present? && @reflection.active_record.name && @reflection.name
116
- fields = ::Avo::App.resources.get_resource_by_model_class(@reflection.active_record.name).get_field_definitions
116
+ resource = Avo.resource_manager.get_resource_by_model_class(@reflection.active_record.name).new(params: helpers.params, view: view, user: helpers._current_user)
117
+ fields = resource.get_field_definitions
117
118
  filtered_fields = fields.filter { |f| f.id == @reflection.name }
118
119
  else
119
120
  return false
@@ -165,6 +166,7 @@ class Avo::ResourceComponent < Avo::BaseComponent
165
166
  resource: @resource,
166
167
  view: @view,
167
168
  exclude: actions_list.exclude,
169
+ include: actions_list.include,
168
170
  style: actions_list.style,
169
171
  color: actions_list.color,
170
172
  label: actions_list.label,
@@ -286,7 +288,8 @@ class Avo::ResourceComponent < Avo::BaseComponent
286
288
  end
287
289
 
288
290
  def render_action(action)
289
- return unless can_see_the_actions_button?
291
+ return if !can_see_the_actions_button?
292
+ return if !action.action.visible_in_view(parent_resource: @parent_resource)
290
293
 
291
294
  a_link action.path,
292
295
  color: action.color,
@@ -16,6 +16,6 @@ class Avo::ResourceSidebarComponent < ViewComponent::Base
16
16
  end
17
17
 
18
18
  def render?
19
- Avo::App.license.has_with_trial(:resource_sidebar)
19
+ Avo.license.has_with_trial(:resource_sidebar)
20
20
  end
21
21
  end
@@ -0,0 +1,3 @@
1
+ <div class="flex flex-col sm:flex-row min-h-14 grow shrink-0" data-component="<%= self.class %>">
2
+ <%= body %>
3
+ </div>
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Avo::RowComponent < ViewComponent::Base
4
+ attr_reader :classes
5
+
6
+ renders_one :body
7
+
8
+ def initialize(classes: nil, data: {})
9
+ @classes = classes
10
+ @data = data
11
+ end
12
+ end
@@ -1,5 +1,6 @@
1
1
  <% if path.present? %>
2
2
  <%= send link_method, path, class: classes, active: active, target: target, data: data do %>
3
+ <%= helpers.svg icon, class: "h-4 text-gray-700" if icon.present? %>
3
4
  <%= label %>
4
5
  <% if target == :_blank %>
5
6
  <%= helpers.svg('heroicons/outline/external-link', class: 'self-center ml-auto h-3 mr-2') %>
@@ -7,6 +8,7 @@
7
8
  <% end %>
8
9
  <% else %>
9
10
  <%= content_tag :div, class: classes, active: active, target: target, data: data do %>
11
+ <%= helpers.svg icon, class: "h-4 text-gray-700" if icon.present? %>
10
12
  <%= label %>
11
13
  <% end %>
12
14
  <% end %>
@@ -6,18 +6,20 @@ class Avo::Sidebar::LinkComponent < ViewComponent::Base
6
6
  attr_reader :label
7
7
  attr_reader :path
8
8
  attr_reader :data
9
+ attr_reader :icon
9
10
 
10
- def initialize(label: nil, path: nil, active: :inclusive, target: nil, data: {})
11
+ def initialize(label: nil, path: nil, active: :inclusive, target: nil, data: {}, icon: nil)
11
12
  @label = label
12
13
  @path = path
13
14
  @active = active
14
15
  @target = target
15
16
  @data = data
17
+ @icon = icon
16
18
  end
17
19
 
18
20
  def is_external?
19
21
  # If the path contains the scheme, check if it includes the root path or not
20
- return !path.include?(Avo::App.mount_path) if URI(path).scheme.present?
22
+ return !path.include?(Avo.mount_path) if URI(path).scheme.present?
21
23
 
22
24
  false
23
25
  end
@@ -28,6 +30,6 @@ class Avo::Sidebar::LinkComponent < ViewComponent::Base
28
30
  end
29
31
 
30
32
  def classes
31
- "px-4 pr-0 flex-1 flex mx-6 leading-none py-2 text-black rounded font-medium hover:bg-gray-100"
33
+ "px-4 pr-0 flex-1 flex mx-6 leading-none py-2 text-black rounded font-medium hover:bg-gray-100 gap-1"
32
34
  end
33
35
  end
@@ -13,8 +13,8 @@
13
13
  <div class="space-y-6 mb-4">
14
14
  <%= 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
15
 
16
- <% if Avo.plugin_manager.installed?(:avo_menu) && Avo::App.has_main_menu? %>
17
- <% Avo::App.main_menu.items.each do |item| %>
16
+ <% if Avo.plugin_manager.installed?("avo-menu") && Avo.has_main_menu? %>
17
+ <% Avo.main_menu.items.each do |item| %>
18
18
  <%= render Avo::Sidebar::ItemSwitcherComponent.new item: item %>
19
19
  <% end %>
20
20
  <% else %>
@@ -60,7 +60,7 @@
60
60
  <% if Rails.env.development? %>
61
61
  <div class="p-4 border-t group">
62
62
  <%= link_to helpers.avo.avo_private_status_path, class: "block px-4 py-2 border rounded flex justify-between items-center w-full text-black text-sm" do %>
63
- <span>Avo Status</span> <span><div class="rounded-full w-4 h-4 <%= Avo::App.instance.app_status ? "bg-green-400" : "bg-orange-400" %>"></div></span>
63
+ <span>Avo Status</span> <span><div class="rounded-full w-4 h-4 <%= Avo.app_status ? "bg-green-400" : "bg-orange-400" %>"></div></span>
64
64
  <% end %>
65
65
  <div class="absolute text-xs text-gray-700 group-hover:block hidden text-center w-full -ml-4">👆Visible only in development👆</div>
66
66
  </div>
@@ -7,17 +7,17 @@ class Avo::SidebarComponent < ViewComponent::Base
7
7
  end
8
8
 
9
9
  def dashboards
10
- return [] unless defined?(AvoDashboards)
10
+ return [] unless defined?(Avo::Dashboards)
11
11
 
12
- AvoDashboards.dashboard_manager.dashboards_for_navigation
12
+ Avo::Dashboards.dashboard_manager.dashboards_for_navigation
13
13
  end
14
14
 
15
15
  def resources
16
- Avo::Current.app.resource_manager.resources_for_navigation helpers._current_user
16
+ Avo.resource_manager.resources_for_navigation helpers._current_user
17
17
  end
18
18
 
19
19
  def tools
20
- Avo::App.tools.tools_for_navigation
20
+ Avo.tool_manager.tools_for_navigation
21
21
  end
22
22
 
23
23
  def stimulus_target
@@ -16,32 +16,32 @@
16
16
  <% end %>
17
17
  </div>
18
18
  </div>
19
- <% if can_destroy_user? %>
20
- <div class="relative" data-controller="toggle">
21
- <a class="flex items-center h-full cursor-pointer" data-control="profile-dots" data-action="click->toggle#togglePanel">
22
- <%= helpers.svg 'three-dots', class: 'h-4' %>
23
- </a>
24
- <div
25
- class="hidden absolute flex flex-col inset-auto right-0 -mt-12 bg-white rounded min-w-[200px] shadow-context -translate-y-full z-40"
26
- data-toggle-target="panel"
27
- data-transition-enter="transition ease-out duration-100"
28
- data-transition-enter-start="transform opacity-0 translate-y-1"
29
- data-transition-enter-end="transform opacity-100 translate-y-0"
30
- data-transition-leave="transition ease-in duration-75"
31
- data-transition-leave-start="transform opacity-100 translate-y-0"
32
- data-transition-leave-end="transform opacity-0 translate-y-1"
33
- >
34
- <% if Avo.plugin_manager.installed?(:avo_menu) && Avo::App.has_profile_menu? %>
35
- <div class="text-black space-y-4">
36
- <% Avo::App.profile_menu.items.each do |item| %>
37
- <% if item.is_a? AvoMenu::Link %>
38
- <%= render Avo::ProfileItemComponent.new label: item.name, path: item.path, icon: item.icon %>
39
- <% end %>
19
+ <div class="relative" data-controller="toggle">
20
+ <a class="flex items-center h-full cursor-pointer" data-control="profile-dots" data-action="click->toggle#togglePanel">
21
+ <%= helpers.svg 'three-dots', class: 'h-4' %>
22
+ </a>
23
+ <div
24
+ class="hidden absolute flex flex-col inset-auto right-0 -mt-12 bg-white rounded min-w-[200px] shadow-context -translate-y-full z-40"
25
+ data-toggle-target="panel"
26
+ data-transition-enter="transition ease-out duration-100"
27
+ data-transition-enter-start="transform opacity-0 translate-y-1"
28
+ data-transition-enter-end="transform opacity-100 translate-y-0"
29
+ data-transition-leave="transition ease-in duration-75"
30
+ data-transition-leave-start="transform opacity-100 translate-y-0"
31
+ data-transition-leave-end="transform opacity-0 translate-y-1"
32
+ >
33
+ <% if Avo.plugin_manager.installed?("avo-menu") && Avo.has_profile_menu? %>
34
+ <div class="text-black space-y-4">
35
+ <% Avo.profile_menu.items.each do |item| %>
36
+ <% if item.is_a? Avo::Menu::Link %>
37
+ <%= render Avo::ProfileItemComponent.new label: item.name, path: item.path, icon: item.icon, method: item.method, params: item.params %>
40
38
  <% end %>
41
- </div>
42
- <% end %>
43
- <%# Example link below %>
44
- <%#= render Avo::ProfileItemComponent.new label: 'Profile', path: '/profile', icon: 'user-circle' %>
39
+ <% end %>
40
+ </div>
41
+ <% end %>
42
+ <%# Example link below %>
43
+ <%#= render Avo::ProfileItemComponent.new label: 'Profile', path: '/profile', icon: 'user-circle' %>
44
+ <% if can_destroy_user? %>
45
45
  <%= button_to helpers.main_app.send(destroy_user_session_path),
46
46
  form: { "data-turbo" => "false" },
47
47
  method: :delete,
@@ -52,7 +52,7 @@
52
52
  form_class: 'flex-1' do %>
53
53
  <%= helpers.svg 'logout', class: 'h-4 mr-1' %> <%= t('avo.sign_out') %>
54
54
  <% end %>
55
- </div>
55
+ <% end %>
56
56
  </div>
57
- <% end %>
57
+ </div>
58
58
  </div>
@@ -79,6 +79,6 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
79
79
 
80
80
  # Render :show view for read only trix fields
81
81
  def view_for(field)
82
- (field.is_a? Avo::Fields::TrixField) && field.is_disabled? ? :show : view
82
+ field.is_a?(Avo::Fields::TrixField) && field.is_disabled? ? :show : view
83
83
  end
84
84
  end
@@ -34,7 +34,7 @@
34
34
  </div>
35
35
  </div>
36
36
  <% if Avo.avo_filters_installed? && resource.has_filters? %>
37
- <%= render AvoFilters::FiltersComponent.new resource: resource, turbo_frame: turbo_frame %>
37
+ <%= render Avo::DynamicFilters::FiltersComponent.new resource: resource, turbo_frame: turbo_frame %>
38
38
  <% end %>
39
39
  </div>
40
40
  </div>
@@ -100,7 +100,7 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
100
100
  def attach_path
101
101
  current_path = CGI.unescape(request.env["PATH_INFO"]).split("/").select(&:present?)
102
102
 
103
- Avo::App.root_path(paths: [*current_path, "new"])
103
+ Avo.root_path(paths: [*current_path, "new"])
104
104
  end
105
105
 
106
106
  def singular_resource_name
@@ -126,7 +126,7 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
126
126
 
127
127
  def show_search_input
128
128
  return false unless authorized_to_search?
129
- return false unless resource.search_query.present?
129
+ return false unless resource.class.search_query.present?
130
130
  return false if field&.hide_search_input
131
131
 
132
132
  true
@@ -143,7 +143,7 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
143
143
  def render_dynamic_filters_button
144
144
  return unless Avo.avo_filters_installed?
145
145
  return unless resource.has_filters?
146
- return if AvoFilters.configuration.always_expanded
146
+ return if Avo::DynamicFilters.configuration.always_expanded
147
147
 
148
148
  a_button size: :sm,
149
149
  color: :primary,
@@ -152,12 +152,12 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
152
152
  controller: "avo-filters",
153
153
  action: "click->avo-filters#toggleFiltersArea",
154
154
  } do
155
- AvoFilters.configuration.button_label
155
+ Avo::DynamicFilters.configuration.button_label
156
156
  end
157
157
  end
158
158
 
159
159
  def scopes_list
160
- AvoPro::Scopes::ListComponent.new(
160
+ Avo::Pro::Scopes::ListComponent.new(
161
161
  scopes: scopes,
162
162
  resource: resource,
163
163
  turbo_frame: turbo_frame,
@@ -166,7 +166,7 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
166
166
  end
167
167
 
168
168
  def can_render_scopes?
169
- defined?(AvoPro)
169
+ defined?(Avo::Pro)
170
170
  end
171
171
 
172
172
  private
@@ -191,11 +191,11 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
191
191
  end
192
192
 
193
193
  def header_visible?
194
- search_query_present? || filters_present? || has_many_view_types? || (Avo.avo_filters_installed? && resource.has_filters? && AvoFilters.configuration.always_expanded)
194
+ search_query_present? || filters_present? || has_many_view_types? || (Avo.avo_filters_installed? && resource.has_filters? && Avo::DynamicFilters.configuration.always_expanded)
195
195
  end
196
196
 
197
197
  def search_query_present?
198
- @resource.search_query.present?
198
+ @resource.class.search_query.present?
199
199
  end
200
200
 
201
201
  def filters_present?
@@ -31,12 +31,10 @@ module Avo
31
31
  resource: resource
32
32
  }
33
33
 
34
- unless @action.standalone
35
- args[:records] = if @selected_query.present?
36
- @resource.model_class.find_by_sql decrypted_query
37
- else
38
- @resource.find_record resource_ids, params: params
39
- end
34
+ args[:records] = if @selected_query.present?
35
+ @resource.model_class.find_by_sql decrypted_query
36
+ else
37
+ @resource.find_record resource_ids, params: params
40
38
  end
41
39
 
42
40
  performed_action = @action.handle_action(**args)
@@ -47,7 +45,7 @@ module Avo
47
45
  private
48
46
 
49
47
  def action_params
50
- params.permit(:authenticity_token, :resource_name, :action_id, fields: {})
48
+ params.permit(:authenticity_token, :resource_name, :action_id, :button, fields: {})
51
49
  end
52
50
 
53
51
  def set_action
@@ -56,7 +54,7 @@ module Avo
56
54
  resource: @resource,
57
55
  user: _current_user,
58
56
  view: @view,
59
- arguments: @resource.get_action_arguments(action_class)
57
+ arguments: decrypted_arguments || {}
60
58
  )
61
59
  end
62
60
 
@@ -113,6 +111,16 @@ module Avo
113
111
  )
114
112
  end
115
113
 
114
+ def decrypted_arguments
115
+ arguments = params[:arguments] || params.dig(:fields, :arguments)
116
+ return if arguments.blank?
117
+
118
+ Avo::Services::EncryptionService.decrypt(
119
+ message: Base64.decode64(arguments),
120
+ purpose: :action_arguments
121
+ )
122
+ end
123
+
116
124
  def flash_messages(messages)
117
125
  messages.each do |message|
118
126
  flash[message[:type]] = message[:body]