avo 3.10.10 → 3.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +3 -4
- data/Gemfile.lock +51 -49
- data/app/components/avo/actions_component.html.erb +10 -6
- data/app/components/avo/actions_component.rb +37 -55
- data/app/components/avo/button_component.rb +3 -3
- data/app/components/avo/fields/belongs_to_field/edit_component.html.erb +8 -4
- data/app/components/avo/fields/belongs_to_field/show_component.rb +1 -1
- data/app/components/avo/fields/common/files/list_viewer_component.rb +1 -1
- data/app/components/avo/fields/has_one_field/show_component.rb +3 -3
- data/app/components/avo/index/resource_controls_component.rb +9 -5
- data/app/components/avo/paginator_component.html.erb +1 -1
- data/app/components/avo/paginator_component.rb +1 -1
- data/app/components/avo/panel_component.html.erb +6 -4
- data/app/components/avo/resource_component.rb +3 -2
- data/app/components/avo/resource_sidebar_component.html.erb +1 -1
- data/app/components/avo/views/resource_edit_component.html.erb +2 -2
- data/app/components/avo/views/resource_index_component.html.erb +2 -2
- data/app/components/avo/views/resource_index_component.rb +17 -4
- data/app/components/avo/views/resource_show_component.html.erb +2 -2
- data/app/controllers/avo/actions_controller.rb +1 -1
- data/app/controllers/avo/application_controller.rb +1 -1
- data/app/controllers/avo/associations_controller.rb +55 -18
- data/app/controllers/avo/base_controller.rb +7 -2
- data/app/controllers/avo/search_controller.rb +1 -1
- data/app/helpers/avo/application_helper.rb +1 -1
- data/app/javascript/avo.base.js +8 -0
- data/app/views/avo/actions/show.html.erb +3 -3
- data/app/views/avo/associations/new.html.erb +45 -20
- data/app/views/avo/base/close_modal_and_reload_field.turbo_stream.erb +1 -1
- data/app/views/layouts/avo/application.html.erb +1 -2
- data/config/initializers/pagy.rb +1 -1
- data/lib/avo/base_action.rb +1 -0
- data/lib/avo/engine.rb +8 -4
- data/lib/avo/fields/base_field.rb +2 -2
- data/lib/avo/fields/belongs_to_field.rb +14 -8
- data/lib/avo/fields/concerns/is_required.rb +1 -1
- data/lib/avo/fields/has_base_field.rb +3 -1
- data/lib/avo/fields/has_one_field.rb +1 -1
- data/lib/avo/fields_execution_context.rb +13 -0
- data/lib/avo/resources/base.rb +32 -22
- data/lib/avo/version.rb +1 -1
- data/lib/avo.rb +10 -8
- data/lib/generators/avo/templates/initializer/avo.tt +3 -3
- data/lib/generators/avo/templates/locales/avo.ar.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.de.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.en.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.es.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.fr.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.it.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.ja.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.nb.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.nl.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.nn.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.pl.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.pt-BR.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.pt.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.ro.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.ru.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.tr.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.uk.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.zh.yml +1 -0
- data/lib/tasks/avo_tasks.rake +1 -1
- data/public/avo-assets/avo.base.css +49 -2
- data/public/avo-assets/avo.base.js +129 -129
- data/public/avo-assets/avo.base.js.map +3 -3
- data/tailwind.preset.js +2 -3
- metadata +4 -3
- /data/{lib → app}/avo/base_resource.rb +0 -0
@@ -1,8 +1,8 @@
|
|
1
|
-
<%= content_tag :div,
|
1
|
+
<%= content_tag :div, class: classes, data: data_attributes do %>
|
2
2
|
<%= render Avo::CoverPhotoComponent.new cover_photo: @cover_photo %>
|
3
3
|
|
4
4
|
<% if render_header? %>
|
5
|
-
<div data-target="panel-header" class="flex flex-col
|
5
|
+
<div data-target="panel-header" class="flex flex-col w-full mb-4">
|
6
6
|
<div class="flex justify-center sm:justify-start flex-col sm:flex-row w-full flex-1 has-cover-photo:mt-0">
|
7
7
|
<%= render Avo::ProfilePhotoComponent.new profile_photo: @profile_photo %>
|
8
8
|
<div class="flex flex-col flex-1 w-full">
|
@@ -55,9 +55,11 @@
|
|
55
55
|
</div>
|
56
56
|
<% end %>
|
57
57
|
<% if bare_content? %>
|
58
|
-
|
58
|
+
<%= content_tag :div, class: class_names("relative flex flex-1 flex-col", "has-sidebar": sidebar?), data: {
|
59
|
+
target: :"panel-bare-content"
|
60
|
+
} do %>
|
59
61
|
<%= bare_content %>
|
60
|
-
|
62
|
+
<% end %>
|
61
63
|
<% end %>
|
62
64
|
<% if footer_tools? %>
|
63
65
|
<div
|
@@ -36,7 +36,7 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
36
36
|
def detach_path
|
37
37
|
return "/" if @reflection.blank?
|
38
38
|
|
39
|
-
helpers.resource_detach_path(params[:resource_name], params[:id], @reflection.name.to_s, @resource.
|
39
|
+
helpers.resource_detach_path(params[:resource_name], params[:id], @reflection.name.to_s, @resource.record_param)
|
40
40
|
end
|
41
41
|
|
42
42
|
def can_see_the_edit_button?
|
@@ -149,6 +149,7 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
149
149
|
label: actions_list.label,
|
150
150
|
size: actions_list.size,
|
151
151
|
icon: actions_list.icon,
|
152
|
+
title: actions_list.title,
|
152
153
|
as_row_control: instance_of?(Avo::Index::ResourceControlsComponent)
|
153
154
|
)
|
154
155
|
end
|
@@ -174,7 +175,7 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
174
175
|
target: "control:destroy",
|
175
176
|
control: :destroy,
|
176
177
|
tippy: control.title ? :tooltip : nil,
|
177
|
-
"resource-id": @resource.
|
178
|
+
"resource-id": @resource.record_param,
|
178
179
|
} do
|
179
180
|
control.label
|
180
181
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
data-component-name="<%= self.class.to_s.underscore %>"
|
3
3
|
data-component-index="<%= index %>"
|
4
4
|
data-resource-name="<%= @resource.class.to_s %>"
|
5
|
-
data-record-id="<%= @resource.
|
5
|
+
data-record-id="<%= @resource.record_param %>"
|
6
6
|
>
|
7
7
|
<%= render Avo::Items::VisibleItemsComponent.new(
|
8
8
|
resource: @resource,
|
@@ -3,9 +3,9 @@
|
|
3
3
|
data: {
|
4
4
|
model_name: @resource.model_name.to_s,
|
5
5
|
resource_name: @resource.class.to_s,
|
6
|
-
record_id: @resource.
|
6
|
+
record_id: @resource.record_param,
|
7
7
|
selected_resources_name: @resource.model_key,
|
8
|
-
selected_resources: [@resource.
|
8
|
+
selected_resources: [@resource.record_param],
|
9
9
|
**@resource.stimulus_data_attributes
|
10
10
|
} do %>
|
11
11
|
<%= render_cards_component %>
|
@@ -11,7 +11,7 @@
|
|
11
11
|
description: description,
|
12
12
|
cover_photo: resource.cover_photo,
|
13
13
|
data: {component: "resources-index"},
|
14
|
-
display_breadcrumbs: @reflection.blank?
|
14
|
+
display_breadcrumbs: @reflection.blank? || (@reflection.present? && !helpers.turbo_frame_request?)
|
15
15
|
) do |c| %>
|
16
16
|
<% c.with_name_slot do %>
|
17
17
|
<%= render Avo::PanelNameComponent.new name: title, url: (params[:turbo_frame].present? && linkable?) ? field.frame_url(add_turbo_frame: false) : nil, target: :_blank do |panel_name_component| %>
|
@@ -78,7 +78,7 @@
|
|
78
78
|
<% end %>
|
79
79
|
<% if view_type.to_sym == :table || view_type.to_sym == :map %>
|
80
80
|
<% if @records.present? %>
|
81
|
-
<div class="mt-4">
|
81
|
+
<div class="mt-4 w-full">
|
82
82
|
<%= 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 %>
|
83
83
|
</div>
|
84
84
|
<% end %>
|
@@ -66,10 +66,20 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def can_attach?
|
69
|
-
|
70
|
-
klass = @reflection.through_reflection if klass.is_a? ::ActiveRecord::Reflection::ThroughReflection
|
69
|
+
return false if has_reflection_and_is_read_only
|
71
70
|
|
72
|
-
@reflection.
|
71
|
+
reflection_class = if @reflection.is_a?(::ActiveRecord::Reflection::ThroughReflection)
|
72
|
+
@reflection.through_reflection.class
|
73
|
+
else
|
74
|
+
@reflection.class
|
75
|
+
end
|
76
|
+
|
77
|
+
return false unless reflection_class.in? [
|
78
|
+
ActiveRecord::Reflection::HasManyReflection,
|
79
|
+
ActiveRecord::Reflection::HasAndBelongsToManyReflection
|
80
|
+
]
|
81
|
+
|
82
|
+
authorize_association_for(:attach)
|
73
83
|
end
|
74
84
|
|
75
85
|
def create_path
|
@@ -82,7 +92,10 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
82
92
|
via_record_id: @parent_record.to_param
|
83
93
|
}
|
84
94
|
|
85
|
-
if @reflection.
|
95
|
+
if @reflection.class.in? [
|
96
|
+
ActiveRecord::Reflection::ThroughReflection,
|
97
|
+
ActiveRecord::Reflection::HasAndBelongsToManyReflection
|
98
|
+
]
|
86
99
|
args[:via_relation] = params[:resource_name]
|
87
100
|
end
|
88
101
|
|
@@ -2,9 +2,9 @@
|
|
2
2
|
data: {
|
3
3
|
model_name: @resource.model_name.to_s,
|
4
4
|
resource_name: @resource.class.to_s,
|
5
|
-
record_id: @resource.
|
5
|
+
record_id: @resource.record_param,
|
6
6
|
selected_resources_name: @resource.model_key,
|
7
|
-
selected_resources: [@resource.
|
7
|
+
selected_resources: [@resource.record_param],
|
8
8
|
**@resource.stimulus_data_attributes
|
9
9
|
} do %>
|
10
10
|
<%= content_tag :div, class: 'space-y-12' do %>
|
@@ -4,7 +4,7 @@ module Avo
|
|
4
4
|
class ActionsController < ApplicationController
|
5
5
|
before_action :set_resource_name
|
6
6
|
before_action :set_resource
|
7
|
-
before_action :set_record, only: :show, if: ->(request) do
|
7
|
+
before_action :set_record, only: [:show, :handle], if: ->(request) do
|
8
8
|
# Try to se the record only if the user is on the record page.
|
9
9
|
# set_record will fail if it's tried to be used from the Index page.
|
10
10
|
request.params[:id].present?
|
@@ -89,7 +89,7 @@ module Avo
|
|
89
89
|
|
90
90
|
return field.use_resource if field&.use_resource.present?
|
91
91
|
|
92
|
-
reflection = @record.
|
92
|
+
reflection = @record.class.reflect_on_association(field&.for_attribute || params[:related_name])
|
93
93
|
|
94
94
|
reflected_model = reflection.klass
|
95
95
|
|
@@ -12,6 +12,7 @@ module Avo
|
|
12
12
|
before_action :set_attachment_class, only: [:show, :index, :new, :create, :destroy]
|
13
13
|
before_action :set_attachment_resource, only: [:show, :index, :new, :create, :destroy]
|
14
14
|
before_action :set_attachment_record, only: [:create, :destroy]
|
15
|
+
before_action :set_attach_fields, only: [:new, :create]
|
15
16
|
before_action :authorize_index_action, only: :index
|
16
17
|
before_action :authorize_attach_action, only: :new
|
17
18
|
before_action :authorize_detach_action, only: :destroy
|
@@ -54,7 +55,7 @@ module Avo
|
|
54
55
|
end
|
55
56
|
|
56
57
|
@options = query.all.map do |record|
|
57
|
-
[@attachment_resource.new(record: record).record_title, record.
|
58
|
+
[@attachment_resource.new(record: record).record_title, record.to_param]
|
58
59
|
end
|
59
60
|
end
|
60
61
|
end
|
@@ -67,6 +68,7 @@ module Avo
|
|
67
68
|
notice: t("avo.attachment_class_attached", attachment_class: @related_resource.name)
|
68
69
|
}
|
69
70
|
else
|
71
|
+
flash[:error] = t("avo.attachment_failed", attachment_class: @related_resource.name)
|
70
72
|
format.turbo_stream {
|
71
73
|
render turbo_stream: turbo_stream.append("alerts", partial: "avo/partials/all_alerts")
|
72
74
|
}
|
@@ -78,7 +80,9 @@ module Avo
|
|
78
80
|
association_name = BaseResource.valid_association_name(@record, association_from_params)
|
79
81
|
|
80
82
|
perform_action_and_record_errors do
|
81
|
-
if
|
83
|
+
if through_reflection? && additional_params.present?
|
84
|
+
new_join_record.save
|
85
|
+
elsif has_many_reflection? || through_reflection?
|
82
86
|
@record.send(association_name) << @attachment_record
|
83
87
|
else
|
84
88
|
@record.send(:"#{association_name}=", @attachment_record)
|
@@ -90,9 +94,9 @@ module Avo
|
|
90
94
|
def destroy
|
91
95
|
association_name = BaseResource.valid_association_name(@record, @field.for_attribute || params[:related_name])
|
92
96
|
|
93
|
-
if
|
97
|
+
if through_reflection?
|
94
98
|
join_record.destroy!
|
95
|
-
elsif
|
99
|
+
elsif has_many_reflection?
|
96
100
|
@record.send(association_name).delete @attachment_record
|
97
101
|
else
|
98
102
|
@record.send(:"#{association_name}=", nil)
|
@@ -106,7 +110,7 @@ module Avo
|
|
106
110
|
private
|
107
111
|
|
108
112
|
def set_reflection
|
109
|
-
@reflection = @record.
|
113
|
+
@reflection = @record.class.reflect_on_association(association_from_params)
|
110
114
|
end
|
111
115
|
|
112
116
|
def set_attachment_class
|
@@ -132,12 +136,11 @@ module Avo
|
|
132
136
|
end
|
133
137
|
|
134
138
|
def reflection_class
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
klass
|
139
|
+
if @reflection.is_a?(ActiveRecord::Reflection::ThroughReflection)
|
140
|
+
@reflection.through_reflection.class
|
141
|
+
else
|
142
|
+
@reflection.class
|
143
|
+
end
|
141
144
|
end
|
142
145
|
|
143
146
|
def authorize_if_defined(method, record = @record)
|
@@ -172,21 +175,55 @@ module Avo
|
|
172
175
|
@field&.for_attribute || params[:related_name]
|
173
176
|
end
|
174
177
|
|
175
|
-
def reflection
|
176
|
-
@record.class.reflections.with_indifferent_access[association_from_params]
|
177
|
-
end
|
178
|
-
|
179
178
|
def source_foreign_key
|
180
|
-
reflection.source_reflection.foreign_key
|
179
|
+
@reflection.source_reflection.foreign_key
|
181
180
|
end
|
182
181
|
|
183
182
|
def through_foreign_key
|
184
|
-
reflection.through_reflection.foreign_key
|
183
|
+
@reflection.through_reflection.foreign_key
|
185
184
|
end
|
186
185
|
|
187
186
|
def join_record
|
188
|
-
reflection.through_reflection.klass.find_by(source_foreign_key => @attachment_record.id,
|
187
|
+
@reflection.through_reflection.klass.find_by(source_foreign_key => @attachment_record.id,
|
189
188
|
through_foreign_key => @record.id)
|
190
189
|
end
|
190
|
+
|
191
|
+
def has_many_reflection?
|
192
|
+
reflection_class.in? [
|
193
|
+
ActiveRecord::Reflection::HasManyReflection,
|
194
|
+
ActiveRecord::Reflection::HasAndBelongsToManyReflection
|
195
|
+
]
|
196
|
+
end
|
197
|
+
|
198
|
+
def through_reflection?
|
199
|
+
@reflection.instance_of? ActiveRecord::Reflection::ThroughReflection
|
200
|
+
end
|
201
|
+
|
202
|
+
def additional_params
|
203
|
+
@additional_params ||= params[:fields].permit(@attach_fields&.map(&:id))
|
204
|
+
end
|
205
|
+
|
206
|
+
def set_attach_fields
|
207
|
+
@attach_fields = if @field.attach_fields.present?
|
208
|
+
Avo::FieldsExecutionContext.new(target: @field.attach_fields)
|
209
|
+
.detect_fields
|
210
|
+
.items_holder
|
211
|
+
.items
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def new_join_record
|
216
|
+
@resource.fill_record(
|
217
|
+
@reflection.through_reflection.klass.new,
|
218
|
+
additional_params.merge(
|
219
|
+
{
|
220
|
+
source_foreign_key => @attachment_record.id,
|
221
|
+
through_foreign_key => @record.id
|
222
|
+
}
|
223
|
+
),
|
224
|
+
fields: @attach_fields,
|
225
|
+
extra_params: [source_foreign_key, through_foreign_key]
|
226
|
+
)
|
227
|
+
end
|
191
228
|
end
|
192
229
|
end
|
@@ -18,6 +18,11 @@ module Avo
|
|
18
18
|
|
19
19
|
def index
|
20
20
|
@page_title = @resource.plural_name.humanize
|
21
|
+
|
22
|
+
if @reflection.present? && !turbo_frame_request?
|
23
|
+
add_breadcrumb @record.class.to_s.pluralize, resources_path(resource: @parent_resource)
|
24
|
+
add_breadcrumb @parent_resource.record_title, resource_path(record: @record, resource: @parent_resource)
|
25
|
+
end
|
21
26
|
add_breadcrumb @resource.plural_name.humanize
|
22
27
|
|
23
28
|
set_index_params
|
@@ -121,7 +126,7 @@ module Avo
|
|
121
126
|
def create
|
122
127
|
# This means that the record has been created through another parent record and we need to attach it somehow.
|
123
128
|
if params[:via_record_id].present? && params[:via_belongs_to_resource_class].nil?
|
124
|
-
@reflection = @record.
|
129
|
+
@reflection = @record.class.reflect_on_association(params[:via_relation])
|
125
130
|
# Figure out what kind of association does the record have with the parent record
|
126
131
|
|
127
132
|
# Fills in the required info for belongs_to and has_many
|
@@ -134,7 +139,7 @@ module Avo
|
|
134
139
|
end
|
135
140
|
|
136
141
|
# For when working with has_one, has_one_through, has_many_through, has_and_belongs_to_many, polymorphic
|
137
|
-
if @reflection.is_a? ActiveRecord::Reflection::
|
142
|
+
if @reflection.is_a?(ActiveRecord::Reflection::ThroughReflection) || @reflection.is_a?(ActiveRecord::Reflection::HasAndBelongsToManyReflection)
|
138
143
|
# find the record
|
139
144
|
via_resource = Avo.resource_manager.get_resource_by_model_class(params[:via_relation_class])
|
140
145
|
@related_record = via_resource.find_record params[:via_record_id], params: params
|
@@ -134,7 +134,7 @@ module Avo
|
|
134
134
|
end
|
135
135
|
|
136
136
|
def frame_id(resource)
|
137
|
-
["frame", resource.model_name.singular, resource.
|
137
|
+
["frame", resource.model_name.singular, resource.record_param].compact.join("-")
|
138
138
|
end
|
139
139
|
|
140
140
|
def chart_color(index)
|
data/app/javascript/avo.base.js
CHANGED
@@ -49,6 +49,14 @@ function initTippy() {
|
|
49
49
|
|
50
50
|
return title
|
51
51
|
},
|
52
|
+
onShow(tooltipInstance) {
|
53
|
+
// Don't render tooltip if there is no content.
|
54
|
+
if (tooltipInstance.props.content === null || tooltipInstance.props.content.length === 0) {
|
55
|
+
return false
|
56
|
+
}
|
57
|
+
|
58
|
+
return tooltipInstance
|
59
|
+
},
|
52
60
|
})
|
53
61
|
}
|
54
62
|
|
@@ -11,7 +11,7 @@
|
|
11
11
|
class="hidden text-slate-800"
|
12
12
|
>
|
13
13
|
<%= form_with scope: 'fields',
|
14
|
-
url:
|
14
|
+
url: @action.link_arguments(resource: @resource).first,
|
15
15
|
local: true,
|
16
16
|
html: {
|
17
17
|
novalidate: true,
|
@@ -29,7 +29,6 @@
|
|
29
29
|
<div class="flex-1 flex">
|
30
30
|
<%= @action.get_message %>
|
31
31
|
</div>
|
32
|
-
<%= hidden_field_tag :action_id, @action.to_param %>
|
33
32
|
<%= form.hidden_field :avo_resource_ids, value: params[:id] || params[:resource_ids], 'data-action-target': 'resourceIds' %>
|
34
33
|
<%= form.hidden_field :avo_selected_query, 'data-action-target': 'selectedAllQuery' %>
|
35
34
|
<%= form.hidden_field :arguments, value: params[:arguments] %>
|
@@ -58,7 +57,8 @@
|
|
58
57
|
size: :sm,
|
59
58
|
data: {
|
60
59
|
target: :submit_action,
|
61
|
-
},
|
60
|
+
},
|
61
|
+
autofocus: @fields.reject { |field| field.is_a?(Avo::Fields::HiddenField) }.empty? do %>
|
62
62
|
<%= @action.confirm_button_label %>
|
63
63
|
<% end %>
|
64
64
|
<% end %>
|
@@ -18,31 +18,56 @@
|
|
18
18
|
} do |form| %>
|
19
19
|
<%= render Avo::ModalComponent.new do |c| %>
|
20
20
|
<% c.with_heading do %>
|
21
|
-
<%= t 'avo.choose_item', item: @
|
21
|
+
<%= t 'avo.choose_item', item: @field.name.singularize.downcase %>
|
22
22
|
<% end %>
|
23
23
|
|
24
24
|
<div class="flex-1 flex items-center justify-center px-0 lg:px-8 text-lg mt-8 mb-12">
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
25
|
+
<div class="flex-1 flex flex-col items-center justify-center px-0 md:px-24 text-base">
|
26
|
+
<div class="w-full">
|
27
|
+
<% if @field.is_searchable? %>
|
28
|
+
<%= field_wrapper stacked: true,
|
29
|
+
field: @field,
|
30
|
+
view: Avo::ViewInquirer.new("edit"),
|
31
|
+
form:,
|
32
|
+
index: 0,
|
33
|
+
resource: @resource,
|
34
|
+
label_for: @field.id,
|
35
|
+
label: @field.name.singularize.downcase do %>
|
36
|
+
<%= render Avo::Pro::SearchableAssociations::AutocompleteComponent.new form: form,
|
37
|
+
classes: input_classes("w-full"),
|
38
|
+
field: @field,
|
39
|
+
model_key: @field.target_resource&.model_key,
|
40
|
+
foreign_key: 'related_id',
|
41
|
+
resource: @resource,
|
42
|
+
view: :new
|
43
|
+
%>
|
44
|
+
<% end %>
|
45
|
+
<% else %>
|
46
|
+
<%= avo_edit_field :related_id,
|
47
|
+
as: :select,
|
48
|
+
form: form,
|
49
|
+
name: @field.name.singularize,
|
50
|
+
options: options_for_select(@options,
|
51
|
+
nil),
|
38
52
|
include_blank: t('avo.choose_an_option'),
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
%>
|
53
|
+
stacked: true,
|
54
|
+
classes: 'w-full'
|
55
|
+
%>
|
56
|
+
<% end %>
|
57
|
+
<% @attach_fields&.each_with_index do |field, index| %>
|
58
|
+
<%= render(Avo::Items::SwitcherComponent.new(
|
59
|
+
resource: @related_resource,
|
60
|
+
item: field,
|
61
|
+
index: index + 1,
|
62
|
+
view: @view,
|
63
|
+
form: form,
|
64
|
+
field_component_extra_args: {
|
65
|
+
stacked: true,
|
66
|
+
classes: 'w-full'}
|
67
|
+
)) %>
|
68
|
+
<% end %>
|
44
69
|
</div>
|
45
|
-
|
70
|
+
</div>
|
46
71
|
</div>
|
47
72
|
|
48
73
|
<% c.with_controls do %>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
<turbo-stream action="update-belongs-to"
|
4
4
|
data-relation-name="<%= params[:via_relation] %>"
|
5
|
-
data-target-record-id="<%= @record.
|
5
|
+
data-target-record-id="<%= @record.to_param %>"
|
6
6
|
data-target-resource-label="<%= @resource.record_title %>"
|
7
7
|
data-target-resource-class="<%= @record.class.name %>">
|
8
8
|
</turbo-stream>
|
@@ -18,13 +18,12 @@
|
|
18
18
|
<%= javascript_include_tag "/avo-assets/avo.base", "data-turbo-track": "reload", defer: true %>
|
19
19
|
<% else %>
|
20
20
|
<%= javascript_include_tag "avo.base", "data-turbo-track": "reload", defer: true %>
|
21
|
-
<% if Rails.env.development? %>
|
21
|
+
<% if Rails.env.development? && defined?(Hotwire::Livereload) %>
|
22
22
|
<%= javascript_include_tag "hotwire-livereload", defer: true %>
|
23
23
|
<% end %>
|
24
24
|
<% end %>
|
25
25
|
<%= render Avo::AssetManager::JavascriptComponent.new asset_manager: Avo.asset_manager %>
|
26
26
|
<%= render partial: "avo/partials/head" %>
|
27
|
-
<%= turbo_refreshes_with method: :replace, scroll: :reset %>
|
28
27
|
<%= content_for :head %>
|
29
28
|
</head>
|
30
29
|
<body class="bg-application os-mac">
|
data/config/initializers/pagy.rb
CHANGED
data/lib/avo/base_action.rb
CHANGED
data/lib/avo/engine.rb
CHANGED
@@ -49,11 +49,15 @@ module Avo
|
|
49
49
|
# This undoes Rails' previous nested directories behavior in the `app` dir.
|
50
50
|
# More on this: https://github.com/fxn/zeitwerk/issues/250
|
51
51
|
avo_directory = Rails.root.join("app", "avo").to_s
|
52
|
-
|
52
|
+
engine_avo_directory = Avo::Engine.root.join("app", "avo").to_s
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
[avo_directory, engine_avo_directory].each do |directory_path|
|
55
|
+
ActiveSupport::Dependencies.autoload_paths.delete(directory_path)
|
56
|
+
|
57
|
+
if Dir.exist?(directory_path)
|
58
|
+
Rails.autoloaders.main.push_dir(directory_path, namespace: Avo)
|
59
|
+
app.config.watchable_dirs[directory_path] = [:rb]
|
60
|
+
end
|
57
61
|
end
|
58
62
|
end
|
59
63
|
|
@@ -242,7 +242,7 @@ module Avo
|
|
242
242
|
end
|
243
243
|
|
244
244
|
def record_errors
|
245
|
-
record.
|
245
|
+
record.present? ? record.errors : {}
|
246
246
|
end
|
247
247
|
|
248
248
|
def type
|
@@ -313,7 +313,7 @@ module Avo
|
|
313
313
|
def get_resource_by_model_class(model_class)
|
314
314
|
resource = Avo.resource_manager.get_resource_by_model_class(model_class)
|
315
315
|
|
316
|
-
resource || (raise Avo::MissingResourceError.new(model_class))
|
316
|
+
resource || (raise Avo::MissingResourceError.new(model_class, id))
|
317
317
|
end
|
318
318
|
end
|
319
319
|
end
|
@@ -125,7 +125,7 @@ module Avo
|
|
125
125
|
end
|
126
126
|
|
127
127
|
query.all.map do |record|
|
128
|
-
[resource.new(record: record).record_title, record.
|
128
|
+
[resource.new(record: record).record_title, record.to_param]
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
@@ -204,13 +204,19 @@ module Avo
|
|
204
204
|
record.send(:"#{polymorphic_as}_type=", valid_model_class)
|
205
205
|
|
206
206
|
# If the type is blank, reset the id too.
|
207
|
-
|
207
|
+
id_from_param = params["#{polymorphic_as}_id"]
|
208
|
+
|
209
|
+
if valid_model_class.blank? || id_from_param.blank?
|
208
210
|
record.send(:"#{polymorphic_as}_id=", nil)
|
209
211
|
else
|
210
|
-
record
|
212
|
+
record_id = target_resource(record:, polymorphic_model_class: value.safe_constantize).find_record(id_from_param).id
|
213
|
+
|
214
|
+
record.send(:"#{polymorphic_as}_id=", record_id)
|
211
215
|
end
|
212
216
|
else
|
213
|
-
record.
|
217
|
+
record_id = value.blank? ? value : target_resource(record:).find_record(value).id
|
218
|
+
|
219
|
+
record.send(:"#{key}=", record_id)
|
214
220
|
end
|
215
221
|
|
216
222
|
record
|
@@ -231,19 +237,19 @@ module Avo
|
|
231
237
|
id
|
232
238
|
end
|
233
239
|
|
234
|
-
def target_resource
|
240
|
+
def target_resource(record: @record, polymorphic_model_class: value&.class)
|
235
241
|
@target_resource ||= if use_resource.present?
|
236
242
|
use_resource
|
237
243
|
elsif is_polymorphic?
|
238
|
-
if
|
239
|
-
get_resource_by_model_class(
|
244
|
+
if polymorphic_model_class.present?
|
245
|
+
get_resource_by_model_class(polymorphic_model_class)
|
240
246
|
else
|
241
247
|
return nil
|
242
248
|
end
|
243
249
|
else
|
244
250
|
reflection_key = polymorphic_as || id
|
245
251
|
|
246
|
-
reflection_object =
|
252
|
+
reflection_object = record.class.reflect_on_association(reflection_key)
|
247
253
|
|
248
254
|
if reflection_object.klass.present?
|
249
255
|
get_resource_by_model_class(reflection_object.klass.to_s)
|
@@ -13,6 +13,7 @@ module Avo
|
|
13
13
|
attr_accessor :discreet_pagination
|
14
14
|
attr_accessor :hide_search_input
|
15
15
|
attr_reader :link_to_child_resource
|
16
|
+
attr_reader :attach_fields
|
16
17
|
|
17
18
|
def initialize(id, **args, &block)
|
18
19
|
super(id, **args, &block)
|
@@ -27,6 +28,7 @@ module Avo
|
|
27
28
|
@link_to_child_resource = args[:link_to_child_resource] || false
|
28
29
|
@reloadable = args[:reloadable].present? ? args[:reloadable] : false
|
29
30
|
@linkable = args[:linkable].present? ? args[:linkable] : false
|
31
|
+
@attach_fields = args[:attach_fields]
|
30
32
|
end
|
31
33
|
|
32
34
|
def field_resource
|
@@ -59,7 +61,7 @@ module Avo
|
|
59
61
|
end
|
60
62
|
|
61
63
|
def target_resource
|
62
|
-
reflection = @record.
|
64
|
+
reflection = @record.class.reflect_on_association(association_name)
|
63
65
|
|
64
66
|
if reflection.klass.present?
|
65
67
|
get_resource_by_model_class(reflection.klass.to_s)
|