avo 3.0.0.beta1 → 3.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of avo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +5 -5
- data/Gemfile.lock +81 -92
- data/{public/avo-assets/avo.css → app/assets/builds/avo.base.css} +686 -728
- data/app/assets/builds/avo.base.js +93804 -0
- data/app/assets/builds/avo.base.js.map +7 -0
- data/app/assets/stylesheets/avo.base.css +2 -1
- data/app/assets/svgs/failed_to_load.svg +1 -0
- data/app/assets/svgs/grid-empty-state.svg +1 -0
- data/app/assets/svgs/table-empty-state.svg +1 -0
- data/app/assets/svgs/triangle-up.svg +1 -1
- data/app/components/avo/actions_component.html.erb +1 -1
- data/app/components/avo/actions_component.rb +16 -42
- data/app/components/avo/alert_component.html.erb +1 -1
- data/app/components/avo/base_component.rb +7 -7
- data/app/components/avo/field_wrapper_component.html.erb +4 -4
- data/app/components/avo/field_wrapper_component.rb +1 -1
- data/app/components/avo/fields/belongs_to_field/edit_component.html.erb +5 -5
- data/app/components/avo/fields/belongs_to_field/edit_component.rb +4 -8
- data/app/components/avo/fields/boolean_field/edit_component.html.erb +0 -1
- data/app/components/avo/fields/boolean_group_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/code_field/edit_component.html.erb +0 -1
- data/app/components/avo/fields/common/files_list_viewer_component.html.erb +5 -0
- data/app/components/avo/fields/common/files_list_viewer_component.rb +8 -0
- data/app/components/avo/fields/common/heading_component.html.erb +1 -1
- data/app/components/avo/fields/common/single_file_viewer_component.html.erb +56 -0
- data/app/components/avo/fields/common/single_file_viewer_component.rb +55 -0
- data/app/components/avo/fields/country_field/edit_component.html.erb +1 -3
- data/app/components/avo/fields/file_field/edit_component.html.erb +2 -4
- data/app/components/avo/fields/file_field/edit_component.rb +0 -1
- data/app/components/avo/fields/file_field/index_component.rb +2 -2
- data/app/components/avo/fields/file_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/files_field/edit_component.html.erb +2 -4
- data/app/components/avo/fields/files_field/edit_component.rb +0 -1
- data/app/components/avo/fields/files_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/has_many_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/has_one_field/show_component.html.erb +4 -5
- data/app/components/avo/fields/has_one_field/show_component.rb +2 -6
- data/app/components/avo/fields/index_component.rb +0 -1
- data/app/components/avo/fields/markdown_field/edit_component.html.erb +3 -4
- data/app/components/avo/fields/markdown_field/show_component.html.erb +3 -3
- data/app/components/avo/fields/number_field/edit_component.html.erb +1 -3
- data/app/components/avo/fields/password_field/edit_component.html.erb +1 -3
- data/app/components/avo/fields/progress_bar_field/edit_component.html.erb +0 -1
- data/app/components/avo/fields/select_field/edit_component.html.erb +1 -2
- data/app/components/avo/fields/status_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/text_field/edit_component.html.erb +2 -3
- data/app/components/avo/fields/textarea_field/edit_component.html.erb +0 -1
- data/app/components/avo/fields/trix_field/edit_component.html.erb +1 -2
- data/app/components/avo/fields/trix_field/show_component.html.erb +1 -1
- data/app/components/avo/index/field_wrapper_component.html.erb +1 -1
- data/app/components/avo/index/field_wrapper_component.rb +12 -0
- data/app/components/avo/index/grid_item_component.html.erb +35 -9
- data/app/components/avo/index/grid_item_component.rb +10 -36
- data/app/components/avo/index/resource_controls_component.rb +11 -8
- data/app/components/avo/index/resource_table_component.rb +1 -1
- data/app/components/avo/item_switcher_component.html.erb +5 -10
- data/app/components/avo/item_switcher_component.rb +1 -2
- data/app/components/avo/modal_component.html.erb +1 -1
- data/app/components/avo/panel_component.html.erb +1 -6
- data/app/components/avo/panel_component.rb +0 -1
- data/app/components/avo/profile_item_component.html.erb +2 -17
- data/app/components/avo/profile_item_component.rb +1 -13
- data/app/components/avo/referrer_params_component.html.erb +0 -2
- data/app/components/avo/resource_component.rb +6 -69
- data/app/components/avo/resource_sidebar_component.rb +1 -1
- data/app/components/avo/sidebar/link_component.html.erb +0 -2
- data/app/components/avo/sidebar/link_component.rb +3 -5
- data/app/components/avo/sidebar_component.html.erb +3 -3
- data/app/components/avo/sidebar_component.rb +4 -4
- data/app/components/avo/sidebar_profile_component.html.erb +27 -27
- data/app/components/avo/views/resource_edit_component.html.erb +5 -5
- data/app/components/avo/views/resource_edit_component.rb +1 -1
- data/app/components/avo/views/resource_index_component.html.erb +10 -19
- data/app/components/avo/views/resource_index_component.rb +16 -22
- data/app/components/avo/views/resource_show_component.html.erb +4 -4
- data/app/controllers/avo/actions_controller.rb +20 -20
- data/app/controllers/avo/application_controller.rb +67 -90
- data/app/controllers/avo/associations_controller.rb +7 -5
- data/app/controllers/avo/attachments_controller.rb +7 -22
- data/app/controllers/avo/base_controller.rb +35 -47
- data/app/controllers/avo/home_controller.rb +1 -1
- data/app/controllers/avo/search_controller.rb +16 -20
- data/app/controllers/concerns/avo/initializes_avo.rb +8 -3
- data/app/helpers/avo/application_helper.rb +6 -13
- data/app/javascript/js/application.js +0 -2
- data/app/javascript/js/controllers/fields/{easy_mde_controller.js → simple_mde_controller.js} +3 -4
- data/app/javascript/js/controllers/search_controller.js +1 -3
- data/app/javascript/js/controllers.js +2 -2
- data/app/views/avo/actions/show.html.erb +3 -5
- data/app/views/avo/associations/new.html.erb +3 -3
- data/app/views/avo/debug/status.html.erb +5 -6
- data/app/views/avo/home/index.html.erb +1 -1
- data/app/views/avo/partials/_custom_tools_alert.html.erb +2 -2
- data/app/views/avo/partials/_footer.html.erb +1 -1
- data/app/views/avo/partials/_javascript.html.erb +1 -1
- data/app/views/avo/partials/_navbar.html.erb +1 -1
- data/app/views/avo/partials/_table_header.html.erb +8 -0
- data/app/views/avo/partials/_view_toggle_button.html.erb +0 -9
- data/app/views/avo/private/design.html.erb +2 -2
- data/app/views/layouts/avo/application.html.erb +3 -2
- data/avo.gemspec +1 -2
- data/config/initializers/pagy.rb +10 -12
- data/config/routes.rb +5 -5
- data/db/factories.rb +0 -17
- data/lib/avo/app.rb +165 -0
- data/lib/avo/base_action.rb +18 -31
- data/lib/avo/base_resource.rb +213 -238
- data/lib/avo/concerns/breadcrumbs.rb +2 -2
- data/lib/avo/concerns/can_replace_items.rb +7 -3
- data/lib/avo/concerns/filters_session_handler.rb +4 -5
- data/lib/avo/concerns/has_item_type.rb +0 -4
- data/lib/avo/concerns/has_items.rb +115 -93
- data/lib/avo/concerns/is_visible.rb +1 -1
- data/lib/avo/concerns/model_class_constantized.rb +2 -0
- data/lib/avo/configuration.rb +8 -9
- data/lib/avo/current.rb +1 -35
- data/lib/avo/dsl/field_parser.rb +1 -1
- data/lib/avo/dynamic_router.rb +2 -13
- data/lib/avo/engine.rb +13 -11
- data/lib/avo/execution_context.rb +2 -4
- data/lib/avo/fields/base_field.rb +14 -51
- data/lib/avo/fields/belongs_to_field.rb +13 -20
- data/lib/avo/fields/concerns/is_searchable.rb +1 -1
- data/lib/avo/fields/concerns/use_resource.rb +1 -1
- data/lib/avo/fields/date_field.rb +3 -16
- data/lib/avo/fields/field_manager.rb +3 -13
- data/lib/avo/fields/file_field.rb +0 -2
- data/lib/avo/fields/files_field.rb +0 -6
- data/lib/avo/fields/has_base_field.rb +5 -5
- data/lib/avo/fields/has_one_field.rb +1 -2
- data/lib/avo/fields/id_field.rb +1 -2
- data/lib/avo/filters/base_filter.rb +0 -9
- data/lib/avo/grid_collector.rb +40 -0
- data/lib/avo/html/builder.rb +1 -3
- data/lib/avo/licensing/h_q.rb +6 -11
- data/lib/avo/licensing/license.rb +1 -1
- data/lib/avo/licensing/license_manager.rb +1 -1
- data/lib/avo/licensing/{nil_license.rb → null_license.rb} +1 -1
- data/lib/avo/loaders/fields_loader.rb +1 -7
- data/lib/avo/plugin.rb +0 -10
- data/lib/avo/plugin_manager.rb +4 -2
- data/lib/avo/reloader.rb +1 -1
- data/lib/avo/resources/controls/actions_list.rb +1 -2
- data/lib/avo/resources/controls/create_button.rb +1 -1
- data/lib/avo/resources/controls/delete_button.rb +1 -1
- data/lib/avo/resources/controls/detach_button.rb +1 -1
- data/lib/avo/resources/controls/edit_button.rb +1 -1
- data/lib/avo/resources/controls/show_button.rb +1 -1
- data/lib/avo/resources/items/holder.rb +5 -13
- data/lib/avo/resources/items/item_group.rb +0 -1
- data/lib/avo/resources/resource_manager.rb +18 -11
- data/lib/avo/services/debug_service.rb +5 -6
- data/lib/avo/services/telemetry_service.rb +2 -3
- data/lib/avo/version.rb +1 -1
- data/lib/avo.rb +25 -109
- data/lib/generators/avo/action_generator.rb +8 -8
- data/lib/generators/avo/card/chartkick_generator.rb +18 -0
- data/lib/generators/avo/card/metric_generator.rb +18 -0
- data/lib/generators/avo/card/partial_generator.rb +19 -0
- data/lib/generators/avo/eject_generator.rb +0 -1
- data/lib/generators/avo/filter_generator.rb +8 -8
- data/lib/generators/avo/install_generator.rb +1 -11
- data/lib/generators/avo/resource_generator.rb +4 -22
- data/lib/generators/avo/tailwindcss/install_generator.rb +1 -4
- data/lib/generators/avo/templates/action.tt +5 -7
- data/lib/generators/avo/templates/cards/chartkick_card.tt +1 -1
- data/lib/generators/avo/templates/cards/chartkick_card_sample.tt +1 -1
- data/lib/generators/avo/templates/cards/metric_card.tt +1 -1
- data/lib/generators/avo/templates/cards/metric_card_sample.tt +1 -1
- data/lib/generators/avo/templates/cards/partial_card.tt +1 -1
- data/lib/generators/avo/templates/cards/partial_card_sample.tt +1 -1
- data/lib/generators/avo/templates/dashboards/dashboard.tt +3 -5
- data/lib/generators/avo/templates/initializer/avo.tt +2 -4
- data/lib/generators/avo/templates/resource/resource.tt +6 -6
- data/lib/generators/avo/templates/scope.tt +1 -1
- data/lib/generators/avo/templates/standalone_action.tt +8 -0
- data/lib/generators/avo/templates/tailwindcss/Procfile.dev +1 -1
- data/lib/tasks/avo_tasks.rake +0 -5
- metadata +19 -56
- data/app/assets/svgs/map-empty-state.svg +0 -35
- data/app/assets/svgs/map-view-type.svg +0 -3
- data/app/components/avo/fields/area_field/edit_component.html.erb +0 -7
- data/app/components/avo/fields/area_field/edit_component.rb +0 -4
- data/app/components/avo/fields/area_field/show_component.html.erb +0 -8
- data/app/components/avo/fields/area_field/show_component.rb +0 -4
- data/app/components/avo/fields/common/files/controls_component.html.erb +0 -29
- data/app/components/avo/fields/common/files/controls_component.rb +0 -19
- data/app/components/avo/fields/common/files/list_viewer_component.html.erb +0 -20
- data/app/components/avo/fields/common/files/list_viewer_component.rb +0 -41
- data/app/components/avo/fields/common/files/view_type/grid_component.html.erb +0 -27
- data/app/components/avo/fields/common/files/view_type/grid_component.rb +0 -51
- data/app/components/avo/fields/common/files/view_type/list_component.html.erb +0 -22
- data/app/components/avo/fields/common/files/view_type/list_component.rb +0 -15
- data/app/components/avo/fields/location_field/edit_component.html.erb +0 -22
- data/app/components/avo/fields/location_field/edit_component.rb +0 -4
- data/app/components/avo/fields/location_field/show_component.html.erb +0 -7
- data/app/components/avo/fields/location_field/show_component.rb +0 -4
- data/app/components/avo/index/resource_map_component.html.erb +0 -16
- data/app/components/avo/index/resource_map_component.rb +0 -109
- data/app/components/avo/row_component.html.erb +0 -3
- data/app/components/avo/row_component.rb +0 -12
- data/app/views/avo/attachments/destroy.turbo_stream.erb +0 -7
- data/app/views/avo/partials/_profile_menu_extra.html.erb +0 -2
- data/lib/avo/concerns/has_description.rb +0 -23
- data/lib/avo/fields/area_field.rb +0 -39
- data/lib/avo/fields/concerns/file_authorization.rb +0 -31
- data/lib/avo/fields/location_field.rb +0 -86
- data/lib/avo/resources/items/row.rb +0 -54
- data/lib/generators/avo/card_generator.rb +0 -27
- data/public/avo-assets/avo.base.css +0 -10542
- data/public/avo-assets/avo.base.js +0 -949
- data/public/avo-assets/avo.base.js.map +0 -7
- data/public/avo-assets/avo.js +0 -513
- data/public/avo-assets/avo.js.map +0 -7
@@ -20,14 +20,7 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def can_detach?
|
23
|
-
|
24
|
-
|
25
|
-
# If the inverse_of is a belongs_to, we need to check if it's optional in order to know if we can detach it.
|
26
|
-
if inverse_of.is_a?(ActiveRecord::Reflection::BelongsToReflection)
|
27
|
-
inverse_of.options[:optional]
|
28
|
-
else
|
29
|
-
true
|
30
|
-
end
|
23
|
+
authorize_association_for(:detach)
|
31
24
|
end
|
32
25
|
|
33
26
|
def detach_path
|
@@ -109,7 +102,7 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
109
102
|
end
|
110
103
|
|
111
104
|
def sidebar
|
112
|
-
return if Avo.license.lacks_with_trial(:resource_sidebar)
|
105
|
+
return if Avo::App.license.lacks_with_trial(:resource_sidebar)
|
113
106
|
|
114
107
|
@sidebar ||= search_for_sidebar
|
115
108
|
end
|
@@ -120,15 +113,14 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
120
113
|
|
121
114
|
def has_reflection_and_is_read_only
|
122
115
|
if @reflection.present? && @reflection.active_record.name && @reflection.name
|
123
|
-
|
124
|
-
fields = resource.get_field_definitions
|
116
|
+
fields = ::Avo::App.resources.get_resource_by_model_class(@reflection.active_record.name).get_field_definitions
|
125
117
|
filtered_fields = fields.filter { |f| f.id == @reflection.name }
|
126
118
|
else
|
127
119
|
return false
|
128
120
|
end
|
129
121
|
|
130
122
|
if filtered_fields.present?
|
131
|
-
filtered_fields.find { |f| f.id == @reflection.name }.
|
123
|
+
filtered_fields.find { |f| f.id == @reflection.name }.readonly
|
132
124
|
else
|
133
125
|
false
|
134
126
|
end
|
@@ -173,7 +165,6 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
173
165
|
resource: @resource,
|
174
166
|
view: @view,
|
175
167
|
exclude: actions_list.exclude,
|
176
|
-
include: actions_list.include,
|
177
168
|
style: actions_list.style,
|
178
169
|
color: actions_list.color,
|
179
170
|
label: actions_list.label,
|
@@ -244,7 +235,7 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
244
235
|
data: {
|
245
236
|
confirm: "Are you sure you want to detach this #{title}."
|
246
237
|
} do
|
247
|
-
control.label || t("avo.detach_item", item: title).
|
238
|
+
control.label || t("avo.detach_item", item: title).capitalize
|
248
239
|
end
|
249
240
|
end
|
250
241
|
|
@@ -254,6 +245,7 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
254
245
|
a_link create_path,
|
255
246
|
color: :primary,
|
256
247
|
style: :primary,
|
248
|
+
target: "_top",
|
257
249
|
icon: "heroicons/outline/plus",
|
258
250
|
data: {
|
259
251
|
target: :create
|
@@ -277,62 +269,7 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
277
269
|
end
|
278
270
|
end
|
279
271
|
|
280
|
-
def render_link_to(link)
|
281
|
-
a_link link.path,
|
282
|
-
color: link.color,
|
283
|
-
style: link.style,
|
284
|
-
icon: link.icon,
|
285
|
-
icon_class: link.icon_class,
|
286
|
-
title: link.title, target: link.target,
|
287
|
-
class: link.classes,
|
288
|
-
size: link.size,
|
289
|
-
data: {
|
290
|
-
**link.data,
|
291
|
-
tippy: link.title ? :tooltip : nil,
|
292
|
-
} do
|
293
|
-
link.label
|
294
|
-
end
|
295
|
-
end
|
296
|
-
|
297
|
-
def render_action(action)
|
298
|
-
return if !can_see_the_actions_button?
|
299
|
-
return if !action.action.visible_in_view(parent_resource: @parent_resource)
|
300
|
-
|
301
|
-
a_link action.path,
|
302
|
-
color: action.color,
|
303
|
-
style: action.style,
|
304
|
-
icon: action.icon,
|
305
|
-
icon_class: action.icon_class,
|
306
|
-
title: action.title,
|
307
|
-
size: action.size,
|
308
|
-
data: {
|
309
|
-
turbo_frame: "actions_show",
|
310
|
-
action_name: action.action.action_name,
|
311
|
-
tippy: action.title ? :tooltip : nil,
|
312
|
-
action: "click->actions-picker#visitAction",
|
313
|
-
} do
|
314
|
-
action.label
|
315
|
-
end
|
316
|
-
end
|
317
|
-
|
318
272
|
def is_a_related_resource?
|
319
273
|
@reflection.present? && @resource.record.present?
|
320
274
|
end
|
321
|
-
|
322
|
-
def inverse_of
|
323
|
-
current_reflection = @reflection.active_record.reflect_on_all_associations.find do |reflection|
|
324
|
-
reflection.name == @reflection.name.to_sym
|
325
|
-
end
|
326
|
-
|
327
|
-
inverse_of = current_reflection.inverse_of
|
328
|
-
|
329
|
-
if inverse_of.blank? && Rails.env.development?
|
330
|
-
puts "WARNING! Avo uses the 'inverse_of' option to determine the inverse association and figure out if the association permit or not detaching."
|
331
|
-
# Ex: Please configure the 'inverse_of' option for the ':users' association on the 'Project' model.
|
332
|
-
puts "Please configure the 'inverse_of' option for the '#{current_reflection.macro} :#{current_reflection.name}' association on the '#{current_reflection.active_record.name}' model."
|
333
|
-
puts "Otherwise the detach button will be visible by default.\n\n"
|
334
|
-
end
|
335
|
-
|
336
|
-
inverse_of
|
337
|
-
end
|
338
275
|
end
|
@@ -1,6 +1,5 @@
|
|
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? %>
|
4
3
|
<%= label %>
|
5
4
|
<% if target == :_blank %>
|
6
5
|
<%= helpers.svg('heroicons/outline/external-link', class: 'self-center ml-auto h-3 mr-2') %>
|
@@ -8,7 +7,6 @@
|
|
8
7
|
<% end %>
|
9
8
|
<% else %>
|
10
9
|
<%= 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? %>
|
12
10
|
<%= label %>
|
13
11
|
<% end %>
|
14
12
|
<% end %>
|
@@ -6,20 +6,18 @@ 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
|
10
9
|
|
11
|
-
def initialize(label: nil, path: nil, active: :inclusive, target: nil, data: {}
|
10
|
+
def initialize(label: nil, path: nil, active: :inclusive, target: nil, data: {})
|
12
11
|
@label = label
|
13
12
|
@path = path
|
14
13
|
@active = active
|
15
14
|
@target = target
|
16
15
|
@data = data
|
17
|
-
@icon = icon
|
18
16
|
end
|
19
17
|
|
20
18
|
def is_external?
|
21
19
|
# If the path contains the scheme, check if it includes the root path or not
|
22
|
-
return !path.include?(Avo.mount_path) if URI(path).scheme.present?
|
20
|
+
return !path.include?(Avo::App.mount_path) if URI(path).scheme.present?
|
23
21
|
|
24
22
|
false
|
25
23
|
end
|
@@ -30,6 +28,6 @@ class Avo::Sidebar::LinkComponent < ViewComponent::Base
|
|
30
28
|
end
|
31
29
|
|
32
30
|
def classes
|
33
|
-
"px-4 pr-0 flex-1 flex mx-6 leading-none py-2 text-black rounded font-medium hover:bg-gray-100
|
31
|
+
"px-4 pr-0 flex-1 flex mx-6 leading-none py-2 text-black rounded font-medium hover:bg-gray-100"
|
34
32
|
end
|
35
33
|
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?(
|
17
|
-
<% Avo.main_menu.items.each do |item| %>
|
16
|
+
<% if Avo.plugin_manager.installed?(:avo_menu) && Avo::App.has_main_menu? %>
|
17
|
+
<% Avo::App.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_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.instance.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
|
10
|
+
return [] unless defined?(AvoDashboards)
|
11
11
|
|
12
|
-
|
12
|
+
AvoDashboards.dashboard_manager.dashboards_for_navigation
|
13
13
|
end
|
14
14
|
|
15
15
|
def resources
|
16
|
-
Avo.resource_manager.resources_for_navigation helpers._current_user
|
16
|
+
Avo::Current.app.resource_manager.resources_for_navigation helpers._current_user
|
17
17
|
end
|
18
18
|
|
19
19
|
def tools
|
20
|
-
Avo.
|
20
|
+
Avo::App.tools.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
|
-
|
20
|
-
<
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
<%
|
37
|
-
|
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 %>
|
38
40
|
<% end %>
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
<%#= render Avo::ProfileItemComponent.new label: 'Profile', path: '/profile', icon: 'user-circle' %>
|
44
|
-
<% if can_destroy_user? %>
|
41
|
+
</div>
|
42
|
+
<% end %>
|
43
|
+
<%# Example link below %>
|
44
|
+
<%#= render Avo::ProfileItemComponent.new label: 'Profile', path: '/profile', icon: 'user-circle' %>
|
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
|
-
|
55
|
+
</div>
|
56
56
|
</div>
|
57
|
-
|
57
|
+
<% end %>
|
58
58
|
</div>
|
@@ -18,8 +18,8 @@
|
|
18
18
|
multipart: true do |form| %>
|
19
19
|
<%= render Avo::ReferrerParamsComponent.new back_path: back_path %>
|
20
20
|
<%= content_tag :div, class: 'space-y-12' do %>
|
21
|
-
<%= render Avo::PanelComponent.new(name: title, description: @resource.
|
22
|
-
<% c.
|
21
|
+
<%= render Avo::PanelComponent.new(name: title, description: @resource.resource_description, display_breadcrumbs: @reflection.blank?, index: 0, data: { panel_id: "main" }) do |c| %>
|
22
|
+
<% c.tools do %>
|
23
23
|
<% @resource.render_edit_controls.each do |control| %>
|
24
24
|
<%= render_control control %>
|
25
25
|
<% end %>
|
@@ -27,7 +27,7 @@
|
|
27
27
|
<%# Extract the main panel and display the fields here. %>
|
28
28
|
<%# This way we'll be able to render the footer buttons under the main fields. %>
|
29
29
|
<% if main_panel.present? %>
|
30
|
-
<% c.
|
30
|
+
<% c.body do %>
|
31
31
|
<div class="divide-y">
|
32
32
|
<% main_panel.items.each_with_index do |field, index| %>
|
33
33
|
<%= render field
|
@@ -40,12 +40,12 @@
|
|
40
40
|
<% end %>
|
41
41
|
<% end %>
|
42
42
|
<% if sidebar.present? %>
|
43
|
-
<% c.
|
43
|
+
<% c.sidebar do %>
|
44
44
|
<%= render sidebar_component form: form %>
|
45
45
|
<% end %>
|
46
46
|
<% end %>
|
47
47
|
<% if Avo.configuration.buttons_on_form_footers %>
|
48
|
-
<% c.
|
48
|
+
<% c.footer_tools do %>
|
49
49
|
<div class="mt-4">
|
50
50
|
<%= a_link back_path,
|
51
51
|
style: :text,
|
@@ -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?
|
82
|
+
(field.is_a? Avo::Fields::TrixField) && field.is_readonly? ? :show : view
|
83
83
|
end
|
84
84
|
end
|
@@ -6,22 +6,22 @@
|
|
6
6
|
**@resource.stimulus_data_attributes
|
7
7
|
} do %>
|
8
8
|
<%= render Avo::PanelComponent.new(name: title, description: description, data: { component: 'resources-index' }, display_breadcrumbs: @reflection.blank?) do |c| %>
|
9
|
-
<% c.
|
9
|
+
<% c.tools do %>
|
10
10
|
<% @resource.render_index_controls(item: singular_resource_name.downcase).each do |control| %>
|
11
11
|
<%= render_control control %>
|
12
12
|
<% end %>
|
13
13
|
<% end %>
|
14
|
-
<% c.
|
14
|
+
<% c.body do %>
|
15
15
|
<div class="flex flex-col">
|
16
16
|
<%= render scopes_list if can_render_scopes? %>
|
17
|
-
<div class="flex flex-col">
|
18
|
-
<div class="flex flex-col xs:flex-row xs:justify-between space-y-2 xs:space-y-0
|
17
|
+
<div class="flex flex-col py-4 gap-4">
|
18
|
+
<div class="flex flex-col xs:flex-row xs:justify-between space-y-2 xs:space-y-0 <%= 'hidden' unless header_visible? %>">
|
19
19
|
<div class="flex items-center px-4 w-64">
|
20
|
-
<% if
|
21
|
-
<%= render partial: 'avo/partials/resource_search', locals: {resource: @resource.route_key, via_reflection: via_reflection} %>
|
22
|
-
<% else %>
|
20
|
+
<% if hide_search_input %>
|
23
21
|
<%# Offset for the space-y-2 property when the search is missing %>
|
24
22
|
<div class="-mb-2"></div>
|
23
|
+
<% else %>
|
24
|
+
<%= render partial: 'avo/partials/resource_search', locals: {resource: @resource.route_key, via_reflection: via_reflection} %>
|
25
25
|
<% end %>
|
26
26
|
</div>
|
27
27
|
|
@@ -34,7 +34,7 @@
|
|
34
34
|
</div>
|
35
35
|
</div>
|
36
36
|
<% if Avo.avo_filters_installed? && resource.has_filters? %>
|
37
|
-
<%= render
|
37
|
+
<%= render AvoFilters::FiltersComponent.new resource: resource %>
|
38
38
|
<% end %>
|
39
39
|
</div>
|
40
40
|
</div>
|
@@ -48,17 +48,8 @@
|
|
48
48
|
<% end %>
|
49
49
|
<% end %>
|
50
50
|
<% end %>
|
51
|
-
<% c.
|
52
|
-
|
53
|
-
<% if @resources.present? %>
|
54
|
-
<div>
|
55
|
-
<%= render(Avo::Index::ResourceMapComponent.new(resources: @resources, resource: @resource, reflection: @reflection, parent_record: @parent_record, parent_resource: @parent_resource, pagy: @pagy, query: @query)) %>
|
56
|
-
</div>
|
57
|
-
<% else %>
|
58
|
-
<%= helpers.empty_state by_association: params[:related_name].present?, view_type: view_type, add_background: true %>
|
59
|
-
<% end %>
|
60
|
-
<% end %>
|
61
|
-
<% if view_type.to_sym == :table || view_type.to_sym == :map %>
|
51
|
+
<% c.bare_content do %>
|
52
|
+
<% if view_type.to_sym == :table %>
|
62
53
|
<% if @records.present? %>
|
63
54
|
<div class="mt-4">
|
64
55
|
<%= render Avo::PaginatorComponent.new pagy: @pagy, turbo_frame: turbo_frame || 'none', index_params: @index_params, resource: @resource, parent_record: parent_record, discreet_pagination: field&.discreet_pagination %>
|
@@ -89,6 +89,10 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
89
89
|
args[:via_relation] = @reflection.name
|
90
90
|
end
|
91
91
|
|
92
|
+
if @reflection.parent_reflection.present? && @reflection.parent_reflection.inverse_of.present?
|
93
|
+
args[:via_relation] = @reflection.parent_reflection.inverse_of.name
|
94
|
+
end
|
95
|
+
|
92
96
|
if @reflection.inverse_of.present?
|
93
97
|
args[:via_relation] = @reflection.inverse_of.name
|
94
98
|
end
|
@@ -100,7 +104,7 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
100
104
|
def attach_path
|
101
105
|
current_path = CGI.unescape(request.env["PATH_INFO"]).split("/").select(&:present?)
|
102
106
|
|
103
|
-
Avo.root_path(paths: [*current_path, "new"])
|
107
|
+
Avo::App.root_path(paths: [*current_path, "new"])
|
104
108
|
end
|
105
109
|
|
106
110
|
def singular_resource_name
|
@@ -121,29 +125,19 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
121
125
|
return
|
122
126
|
end
|
123
127
|
|
124
|
-
@resource.
|
125
|
-
end
|
126
|
-
|
127
|
-
def show_search_input
|
128
|
-
return false unless authorized_to_search?
|
129
|
-
return false unless resource.class.search_query.present?
|
130
|
-
return false if field&.hide_search_input
|
131
|
-
|
132
|
-
true
|
128
|
+
@resource.resource_description
|
133
129
|
end
|
134
130
|
|
135
|
-
def
|
136
|
-
|
137
|
-
return true unless resource.authorization.respond_to?(:has_action_method?)
|
138
|
-
return true unless resource.authorization.has_action_method?("search")
|
131
|
+
def hide_search_input
|
132
|
+
return true unless @resource.search_query.present?
|
139
133
|
|
140
|
-
|
134
|
+
field&.hide_search_input || false
|
141
135
|
end
|
142
136
|
|
143
137
|
def render_dynamic_filters_button
|
144
138
|
return unless Avo.avo_filters_installed?
|
145
139
|
return unless resource.has_filters?
|
146
|
-
return if
|
140
|
+
return if AvoFilters.configuration.always_expanded
|
147
141
|
|
148
142
|
a_button size: :sm,
|
149
143
|
color: :primary,
|
@@ -152,21 +146,21 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
152
146
|
controller: "avo-filters",
|
153
147
|
action: "click->avo-filters#toggleFiltersArea",
|
154
148
|
} do
|
155
|
-
|
149
|
+
AvoFilters.configuration.button_label
|
156
150
|
end
|
157
151
|
end
|
158
152
|
|
159
153
|
def scopes_list
|
160
|
-
|
154
|
+
AvoPro::Scopes::ListComponent.new(
|
161
155
|
scopes: scopes,
|
162
156
|
resource: resource,
|
163
157
|
turbo_frame: turbo_frame,
|
164
|
-
parent_record: parent_record
|
158
|
+
parent_record: parent_record,
|
165
159
|
)
|
166
160
|
end
|
167
161
|
|
168
162
|
def can_render_scopes?
|
169
|
-
defined?(
|
163
|
+
defined?(AvoPro)
|
170
164
|
end
|
171
165
|
|
172
166
|
private
|
@@ -191,11 +185,11 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
191
185
|
end
|
192
186
|
|
193
187
|
def header_visible?
|
194
|
-
search_query_present? || filters_present? || has_many_view_types? || (Avo.avo_filters_installed? && resource.has_filters? &&
|
188
|
+
search_query_present? || filters_present? || has_many_view_types? || (Avo.avo_filters_installed? && resource.has_filters? && AvoFilters.configuration.always_expanded)
|
195
189
|
end
|
196
190
|
|
197
191
|
def search_query_present?
|
198
|
-
@resource.
|
192
|
+
@resource.search_query.present?
|
199
193
|
end
|
200
194
|
|
201
195
|
def filters_present?
|
@@ -7,14 +7,14 @@
|
|
7
7
|
selected_resources: [@resource.record.id],
|
8
8
|
**@resource.stimulus_data_attributes
|
9
9
|
} do %>
|
10
|
-
<%= render Avo::PanelComponent.new(name: title, description: @resource.
|
11
|
-
<% c.
|
10
|
+
<%= render Avo::PanelComponent.new(name: title, description: @resource.resource_description, display_breadcrumbs: @reflection.blank?, index: 0, data: { panel_id: "main" }) do |c| %>
|
11
|
+
<% c.tools do %>
|
12
12
|
<% @resource.render_show_controls.each do |control| %>
|
13
13
|
<%= render_control control %>
|
14
14
|
<% end %>
|
15
15
|
<% end %>
|
16
16
|
<% if main_panel.present? %>
|
17
|
-
<% c.
|
17
|
+
<% c.body do %>
|
18
18
|
<%# the overflow helps with long values %>
|
19
19
|
<div class="divide-y overflow-auto">
|
20
20
|
<% main_panel.items.each_with_index do |field, index| %>
|
@@ -28,7 +28,7 @@
|
|
28
28
|
<% end %>
|
29
29
|
<% end %>
|
30
30
|
<% if sidebar.present? %>
|
31
|
-
<% c.
|
31
|
+
<% c.sidebar do %>
|
32
32
|
<%= render sidebar_component %>
|
33
33
|
<% end %>
|
34
34
|
<% end %>
|
@@ -31,10 +31,12 @@ module Avo
|
|
31
31
|
resource: resource
|
32
32
|
}
|
33
33
|
|
34
|
-
|
35
|
-
@
|
36
|
-
|
37
|
-
|
34
|
+
unless @action.standalone
|
35
|
+
args[:models] = 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
|
38
40
|
end
|
39
41
|
|
40
42
|
performed_action = @action.handle_action(**args)
|
@@ -45,7 +47,7 @@ module Avo
|
|
45
47
|
private
|
46
48
|
|
47
49
|
def action_params
|
48
|
-
params.permit(:authenticity_token, :resource_name, :action_id,
|
50
|
+
params.permit(:authenticity_token, :resource_name, :action_id, fields: {})
|
49
51
|
end
|
50
52
|
|
51
53
|
def set_action
|
@@ -53,14 +55,17 @@ module Avo
|
|
53
55
|
record: @record,
|
54
56
|
resource: @resource,
|
55
57
|
user: _current_user,
|
56
|
-
view:
|
57
|
-
arguments:
|
58
|
+
view: @view,
|
59
|
+
arguments: @resource.get_action_arguments(action_class)
|
58
60
|
)
|
59
61
|
end
|
60
62
|
|
61
63
|
def action_class
|
64
|
+
klass_name = params[:action_id].gsub("avo_actions_", "").camelize
|
65
|
+
klass_name = "Avo::Actions::#{klass_name}"
|
66
|
+
|
62
67
|
Avo::BaseAction.descendants.find do |action|
|
63
|
-
action.to_s ==
|
68
|
+
action.to_s == klass_name
|
64
69
|
end
|
65
70
|
end
|
66
71
|
|
@@ -80,8 +85,13 @@ module Avo
|
|
80
85
|
flash_messages messages
|
81
86
|
|
82
87
|
if response[:type] == :redirect
|
83
|
-
|
84
|
-
|
88
|
+
path = response[:path]
|
89
|
+
|
90
|
+
if path.respond_to? :call
|
91
|
+
path = instance_eval(&path)
|
92
|
+
end
|
93
|
+
|
94
|
+
redirect_to path
|
85
95
|
elsif response[:type] == :reload
|
86
96
|
redirect_back fallback_location: resources_path(resource: @resource)
|
87
97
|
end
|
@@ -112,16 +122,6 @@ module Avo
|
|
112
122
|
)
|
113
123
|
end
|
114
124
|
|
115
|
-
def decrypted_arguments
|
116
|
-
arguments = params[:arguments] || params.dig(:fields, :arguments)
|
117
|
-
return if arguments.blank?
|
118
|
-
|
119
|
-
Avo::Services::EncryptionService.decrypt(
|
120
|
-
message: Base64.decode64(arguments),
|
121
|
-
purpose: :action_arguments
|
122
|
-
)
|
123
|
-
end
|
124
|
-
|
125
125
|
def flash_messages(messages)
|
126
126
|
messages.each do |message|
|
127
127
|
flash[message[:type]] = message[:body]
|