avo 3.0.1.beta24 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of avo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +5 -5
- data/Gemfile.lock +164 -128
- data/README.md +19 -27
- data/app/components/avo/actions_component.rb +2 -2
- data/app/components/avo/fields/belongs_to_field/edit_component.html.erb +122 -104
- data/app/components/avo/fields/belongs_to_field/edit_component.rb +11 -0
- data/app/components/avo/fields/location_field/edit_component.html.erb +12 -10
- data/app/components/avo/index/grid_item_component.html.erb +1 -1
- data/app/components/avo/index/resource_table_component.html.erb +2 -2
- data/app/components/avo/index/resource_table_component.rb +16 -0
- data/app/components/avo/index/table_row_component.html.erb +1 -1
- data/app/components/avo/items/panel_component.html.erb +25 -0
- data/app/components/avo/items/panel_component.rb +43 -0
- data/app/components/avo/items/switcher_component.html.erb +17 -0
- data/app/components/avo/items/switcher_component.rb +79 -0
- data/app/components/avo/items/visible_items_component.html.erb +10 -0
- data/app/components/avo/items/visible_items_component.rb +11 -0
- data/app/components/avo/modal_component.html.erb +11 -7
- data/app/components/avo/modal_component.rb +21 -0
- data/app/components/avo/paginator_component.html.erb +29 -40
- data/app/components/avo/paginator_component.rb +18 -0
- data/app/components/avo/panel_component.html.erb +2 -2
- data/app/components/avo/referrer_params_component.html.erb +1 -0
- data/app/components/avo/resource_component.rb +8 -15
- data/app/components/avo/resource_sidebar_component.html.erb +11 -18
- data/app/components/avo/resource_sidebar_component.rb +4 -2
- data/app/components/avo/sidebar_profile_component.html.erb +1 -1
- data/app/components/avo/tab_group_component.html.erb +1 -1
- data/app/components/avo/views/resource_edit_component.html.erb +15 -32
- data/app/components/avo/views/resource_edit_component.rb +18 -6
- data/app/components/avo/views/resource_index_component.rb +1 -0
- data/app/components/avo/views/resource_show_component.html.erb +14 -33
- data/app/components/avo/views/resource_show_component.rb +11 -0
- data/app/controllers/avo/actions_controller.rb +6 -4
- data/app/controllers/avo/application_controller.rb +2 -33
- data/app/controllers/avo/base_controller.rb +25 -16
- data/app/helpers/avo/application_helper.rb +4 -0
- data/app/javascript/js/controllers/fields/reload_belongs_to_field_controller.js +51 -0
- data/app/javascript/js/controllers.js +2 -0
- data/app/views/avo/actions/show.html.erb +4 -3
- data/app/views/avo/base/_new_via_belongs_to.html.erb +12 -0
- data/app/views/avo/base/close_modal_and_reload_field.turbo_stream.erb +8 -0
- data/app/views/avo/base/create_fail_action.turbo_stream.erb +13 -0
- data/app/views/avo/partials/_flash_alerts.turbo_stream.erb +3 -0
- data/config/i18n-tasks.yml +1 -1
- data/config/initializers/pagy.rb +2 -0
- data/config/master.key +1 -0
- data/lib/avo/base_action.rb +44 -38
- data/lib/avo/base_resource.rb +7 -8
- data/lib/avo/concerns/borrow_items_holder.rb +35 -0
- data/lib/avo/concerns/has_items.rb +65 -47
- data/lib/avo/concerns/hydration.rb +17 -0
- data/lib/avo/concerns/is_resource_item.rb +2 -10
- data/lib/avo/concerns/pagination.rb +53 -0
- data/lib/avo/concerns/visible_items.rb +7 -30
- data/lib/avo/dsl/field_parser.rb +1 -1
- data/lib/avo/fields/concerns/is_searchable.rb +3 -1
- data/lib/avo/fields/location_field.rb +2 -2
- data/lib/avo/filters/base_filter.rb +1 -0
- data/lib/avo/html/builder.rb +1 -0
- data/lib/avo/licensing/h_q.rb +4 -6
- data/lib/avo/licensing/license.rb +4 -0
- data/lib/avo/plugin.rb +5 -1
- data/lib/avo/resources/items/holder.rb +29 -11
- data/lib/avo/resources/items/item_group.rb +4 -9
- data/lib/avo/resources/items/main_panel.rb +10 -0
- data/lib/avo/resources/items/row.rb +4 -16
- data/lib/avo/resources/items/sidebar.rb +9 -10
- data/lib/avo/resources/items/tab.rb +3 -9
- data/lib/avo/resources/items/tab_group.rb +6 -12
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/templates/locales/avo.ar.yml +7 -6
- data/lib/generators/avo/templates/locales/avo.en.yml +2 -0
- data/lib/generators/avo/templates/locales/avo.es.yml +127 -0
- data/lib/generators/avo/templates/locales/avo.fr.yml +2 -0
- data/lib/generators/avo/templates/locales/avo.nb.yml +2 -0
- data/lib/generators/avo/templates/locales/avo.nn.yml +2 -0
- data/lib/generators/avo/templates/locales/avo.pt-BR.yml +2 -0
- data/lib/generators/avo/templates/locales/avo.pt.yml +2 -0
- data/lib/generators/avo/templates/locales/avo.ro.yml +2 -0
- data/lib/generators/avo/templates/locales/avo.tr.yml +2 -0
- data/public/avo-assets/avo.base.css +121 -4
- data/public/avo-assets/avo.base.js +86 -86
- data/public/avo-assets/avo.base.js.map +3 -3
- data/public/avo-assets/avo.css +9744 -0
- data/public/avo-assets/avo.js +513 -0
- data/public/avo-assets/avo.js.map +7 -0
- metadata +23 -8
- data/app/components/avo/item_switcher_component.html.erb +0 -27
- data/app/components/avo/item_switcher_component.rb +0 -48
- data/app/views/avo/actions/keep_modal_open.turbo_stream.erb +0 -5
- data/lib/avo/action_model.rb +0 -20
@@ -1,47 +1,36 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
<div class="flex items-center">
|
17
|
-
<%= select_tag 'per_page',
|
18
|
-
options_for_select(per_page_options, index_params[:per_page]),
|
19
|
-
class: 'appearance-none inline-flex bg-white-100 disabled:bg-white-400 disabled:cursor-not-allowed focus:bg-white text-slate-700 disabled:text-slate-600 rounded-md py-1 px-2 leading-tight border border-slate-300 outline-none focus:border-slate-400 outline w-16 mr-1 text-sm',
|
20
|
-
data: {
|
21
|
-
'turbo-frame': turbo_frame,
|
22
|
-
'per-page-target': 'selector',
|
23
|
-
action: 'change->per-page#reload'
|
24
|
-
}
|
25
|
-
%> <%= t('avo.per_page').downcase %>
|
26
|
-
</div>
|
27
|
-
<% per_page_options.each do |option| %>
|
28
|
-
<%= link_to "Change to #{option} items per page", change_items_per_page_url(option), class: 'hidden', 'data-per-page-option': option, 'data-turbo-frame': turbo_frame %>
|
29
|
-
<% end %>
|
1
|
+
<div class="flex flex-col sm:flex-row items-center justify-between aborder-t aborder-slate-200 rounded-xl space-y-2 sm:space-y-0">
|
2
|
+
<div class="flex-2 sm:flex sm:items-center sm:justify-between">
|
3
|
+
<div>
|
4
|
+
<div class="text-sm leading-5 text-slate-600 flex items-center">
|
5
|
+
<div data-controller="per-page">
|
6
|
+
<div class="flex items-center">
|
7
|
+
<%= select_tag 'per_page',
|
8
|
+
options_for_select(per_page_options, index_params[:per_page]),
|
9
|
+
class: 'appearance-none inline-flex bg-white-100 disabled:bg-white-400 disabled:cursor-not-allowed focus:bg-white text-slate-700 disabled:text-slate-600 rounded-md py-1 px-2 leading-tight border border-slate-300 outline-none focus:border-slate-400 outline w-16 mr-1 text-sm',
|
10
|
+
data: {
|
11
|
+
'turbo-frame': turbo_frame,
|
12
|
+
'per-page-target': 'selector',
|
13
|
+
action: 'change->per-page#reload'
|
14
|
+
}
|
15
|
+
%> <%= t('avo.per_page').downcase %>
|
30
16
|
</div>
|
17
|
+
<% per_page_options.each do |option| %>
|
18
|
+
<%= link_to "Change to #{option} items per page", change_items_per_page_url(option), class: 'hidden', 'data-per-page-option': option, 'data-turbo-frame': turbo_frame %>
|
19
|
+
<% end %>
|
31
20
|
</div>
|
32
21
|
</div>
|
33
22
|
</div>
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
23
|
+
</div>
|
24
|
+
<div class="flex">
|
25
|
+
<div class="flex-2 sm:flex sm:items-center sm:justify-between space-y-2 sm:space-y-0 text-center sm:text-left">
|
26
|
+
<% if @resource.pagination_type.default? %>
|
27
|
+
<div class="text-sm text-slate-600 mr-4"><%== helpers.pagy_info @pagy %></div>
|
28
|
+
<% end %>
|
39
29
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
</div>
|
30
|
+
<% if @pagy.pages > 1 %>
|
31
|
+
<%# @todo: add first & last page. make the first and last buttons rounded %>
|
32
|
+
<%== helpers.pagy_nav @pagy %>
|
33
|
+
<% end %>
|
45
34
|
</div>
|
46
35
|
</div>
|
47
|
-
|
36
|
+
</div>
|
@@ -24,4 +24,22 @@ class Avo::PaginatorComponent < ViewComponent::Base
|
|
24
24
|
helpers.resources_path(resource: resource, per_page: option, keep_query_params: true, page: 1)
|
25
25
|
end
|
26
26
|
end
|
27
|
+
|
28
|
+
def render?
|
29
|
+
return false if discreet_pagination && pagy.pages <= 1
|
30
|
+
|
31
|
+
@pagy.items > 0
|
32
|
+
end
|
33
|
+
|
34
|
+
def per_page_options
|
35
|
+
@per_page_options ||= begin
|
36
|
+
options = [*Avo.configuration.per_page_steps, Avo.configuration.per_page.to_i, index_params[:per_page].to_i]
|
37
|
+
|
38
|
+
if parent_record.present?
|
39
|
+
options.prepend Avo.configuration.via_per_page
|
40
|
+
end
|
41
|
+
|
42
|
+
options.sort.uniq
|
43
|
+
end
|
44
|
+
end
|
27
45
|
end
|
@@ -32,12 +32,12 @@
|
|
32
32
|
</div>
|
33
33
|
</div>
|
34
34
|
<% if sidebar? %>
|
35
|
-
<div class="w-full sm:w-1/3 flex-shrink-0 h-full
|
35
|
+
<div class="max-w-full sm:w-1/3 flex-shrink-0 h-full">
|
36
36
|
<%= sidebar %>
|
37
37
|
</div>
|
38
38
|
<% end %>
|
39
39
|
<% if bare_sidebar? %>
|
40
|
-
<div class="w-full sm:w-1/3 flex-shrink-0 h-full">
|
40
|
+
<div class="max-w-full sm:w-1/3 flex-shrink-0 h-full">
|
41
41
|
<%= bare_sidebar %>
|
42
42
|
</div>
|
43
43
|
<% end %>
|
@@ -3,4 +3,5 @@
|
|
3
3
|
<%= hidden_field_tag :via_resource_class, params[:via_resource_class] if params[:via_resource_class] %>
|
4
4
|
<%= hidden_field_tag :via_record_id, params[:via_record_id] if params[:via_record_id] %>
|
5
5
|
<%= hidden_field_tag :via_relation, params[:via_relation] if params[:via_relation] %>
|
6
|
+
<%= hidden_field_tag :via_belongs_to_resource_class, params[:via_belongs_to_resource_class] if params[:via_belongs_to_resource_class] %>
|
6
7
|
<%= hidden_field_tag :referrer, back_path if params[:via_resource_class] %>
|
@@ -113,14 +113,15 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
-
def
|
116
|
+
def sidebars
|
117
117
|
return if Avo.license.lacks_with_trial(:resource_sidebar)
|
118
118
|
|
119
|
-
@
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
119
|
+
@item.items.select do |item|
|
120
|
+
item.is_sidebar?
|
121
|
+
end
|
122
|
+
.map do |sidebar|
|
123
|
+
sidebar.hydrate(view: view, resource: resource)
|
124
|
+
end
|
124
125
|
end
|
125
126
|
|
126
127
|
def has_reflection_and_is_read_only
|
@@ -155,16 +156,8 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
155
156
|
(params[:via_resource_class].present? || params[:via_relation_class].present?) && params[:via_record_id].present?
|
156
157
|
end
|
157
158
|
|
158
|
-
def search_for_sidebar
|
159
|
-
item = @resource.get_items.find do |item|
|
160
|
-
item.is_sidebar?
|
161
|
-
end
|
162
|
-
|
163
|
-
item&.hydrate(view: view)
|
164
|
-
end
|
165
|
-
|
166
159
|
def render_back_button(control)
|
167
|
-
return if is_a_related_resource?
|
160
|
+
return if back_path.blank? || is_a_related_resource?
|
168
161
|
|
169
162
|
tippy = control.title ? :tooltip : nil
|
170
163
|
a_link back_path,
|
@@ -1,23 +1,16 @@
|
|
1
1
|
<div class="resource-sidebar-component divide-y"
|
2
|
-
data-component-name="<%= self.class.to_s.underscore%>"
|
2
|
+
data-component-name="<%= self.class.to_s.underscore %>"
|
3
|
+
data-component-index="<%= index %>"
|
3
4
|
data-resource-name="<%= @resource.class.to_s %>"
|
4
5
|
data-record-id="<%= @resource.record.id %>"
|
5
6
|
>
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
field: field,
|
16
|
-
resource: resource,
|
17
|
-
form: form,
|
18
|
-
stacked: true,
|
19
|
-
index: index
|
20
|
-
)
|
21
|
-
%>
|
22
|
-
<% end %>
|
7
|
+
<%= render Avo::Items::VisibleItemsComponent.new(
|
8
|
+
resource: @resource,
|
9
|
+
item: @sidebar,
|
10
|
+
view: @view,
|
11
|
+
form: @form,
|
12
|
+
field_component_extra_args: {
|
13
|
+
stacked: true
|
14
|
+
}
|
15
|
+
)%>
|
23
16
|
</div>
|
@@ -6,13 +6,15 @@ class Avo::ResourceSidebarComponent < ViewComponent::Base
|
|
6
6
|
attr_reader :view
|
7
7
|
attr_reader :form
|
8
8
|
attr_reader :fields
|
9
|
+
attr_reader :index
|
9
10
|
|
10
|
-
def initialize(resource: nil,
|
11
|
+
def initialize(resource: nil, sidebar: nil, index: nil, params: nil, form: nil, view: nil)
|
11
12
|
@resource = resource
|
12
|
-
@
|
13
|
+
@sidebar = sidebar
|
13
14
|
@params = params
|
14
15
|
@view = view
|
15
16
|
@form = form
|
17
|
+
@index = index
|
16
18
|
end
|
17
19
|
|
18
20
|
def render?
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<div class="flex-1 flex space-x-4 w-full">
|
3
3
|
<% if avatar.present? %>
|
4
4
|
<div class="relative aspect-square w-10 h-10 overflow-hidden rounded shrink-0">
|
5
|
-
<%= image_tag avatar, class: "object-cover min-w-full min-h-full h-full" %>
|
5
|
+
<%= image_tag helpers.main_app.url_for(avatar), class: "object-cover min-w-full min-h-full h-full" %>
|
6
6
|
</div>
|
7
7
|
<% end %>
|
8
8
|
<div class="flex flex-col pr-3 min-w-0">
|
@@ -47,7 +47,7 @@
|
|
47
47
|
<% if !tab.is_empty? %>
|
48
48
|
<div class="space-y-12">
|
49
49
|
<% tab.visible_items.each do |item| %>
|
50
|
-
<%= render Avo::
|
50
|
+
<%= render Avo::Items::SwitcherComponent.new resource: resource, item: item, index: index, form: form, view: @view %>
|
51
51
|
<% end %>
|
52
52
|
</div>
|
53
53
|
<% end %>
|
@@ -1,4 +1,5 @@
|
|
1
1
|
<%= content_tag :div,
|
2
|
+
id: helpers.frame_id(@resource),
|
2
3
|
data: {
|
3
4
|
model_name: @resource.model_name.to_s,
|
4
5
|
resource_name: @resource.class.to_s,
|
@@ -19,39 +20,21 @@
|
|
19
20
|
multipart: true do |form| %>
|
20
21
|
<%= render Avo::ReferrerParamsComponent.new back_path: back_path %>
|
21
22
|
<%= content_tag :div, class: 'space-y-12' do %>
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
.hydrate(resource: @resource, record: @resource.record, user: @resource.user, view: view_for(field))
|
36
|
-
.component_for_view(view_for field)
|
37
|
-
.new(field: field, resource: @resource, index: index, form: form, compact: sidebar.present?)
|
38
|
-
%>
|
39
|
-
<% end %>
|
40
|
-
</div>
|
41
|
-
<% end %>
|
42
|
-
<% end %>
|
43
|
-
<% if sidebar.present? %>
|
44
|
-
<% c.with_sidebar do %>
|
45
|
-
<%= render sidebar_component form: form %>
|
46
|
-
<% end %>
|
47
|
-
<% end %>
|
48
|
-
<% end %>
|
49
|
-
<%= content_tag :div, class: 'space-y-12' do %>
|
50
|
-
<% @resource.get_items.each_with_index do |item, index| %>
|
51
|
-
<% next if item.nil? %>
|
52
|
-
<%= render Avo::ItemSwitcherComponent.new resource: @resource, item: item, index: index + 1, view: view, form: form %>
|
53
|
-
<% end %>
|
23
|
+
<% @resource.get_items.each_with_index do |item, index| %>
|
24
|
+
<%= render Avo::Items::SwitcherComponent.new(
|
25
|
+
resource: @resource,
|
26
|
+
reflection: @reflection,
|
27
|
+
item: item,
|
28
|
+
index: index + 1,
|
29
|
+
view: @view,
|
30
|
+
parent_resource: @parent_resource,
|
31
|
+
parent_record: @parent_record,
|
32
|
+
form: form,
|
33
|
+
parent_component: self,
|
34
|
+
actions: @actions
|
35
|
+
)%>
|
54
36
|
<% end %>
|
37
|
+
|
55
38
|
<% if Avo.configuration.buttons_on_form_footers %>
|
56
39
|
<%= render Avo::PanelComponent.new do |c| %>
|
57
40
|
<% c.with_footer_tools do %>
|
@@ -3,11 +3,14 @@
|
|
3
3
|
class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
|
4
4
|
include Avo::ApplicationHelper
|
5
5
|
|
6
|
-
|
6
|
+
attr_reader :actions, :display_breadcrumbs
|
7
|
+
|
8
|
+
def initialize(resource: nil, record: nil, actions: [], view: "edit", display_breadcrumbs: true)
|
7
9
|
@resource = resource
|
8
10
|
@record = record
|
9
11
|
@actions = actions
|
10
12
|
@view = Avo::ViewInquirer.new(view)
|
13
|
+
@display_breadcrumbs = @reflection.blank? && display_breadcrumbs
|
11
14
|
end
|
12
15
|
|
13
16
|
def title
|
@@ -15,6 +18,7 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
|
|
15
18
|
end
|
16
19
|
|
17
20
|
def back_path
|
21
|
+
return if via_belongs_to?
|
18
22
|
return resource_view_path if via_resource?
|
19
23
|
return resources_path if via_index?
|
20
24
|
|
@@ -45,12 +49,25 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
|
|
45
49
|
@resource.authorization.authorize_action @view, raise_exception: false
|
46
50
|
end
|
47
51
|
|
52
|
+
def controls
|
53
|
+
@resource.render_edit_controls
|
54
|
+
end
|
55
|
+
|
56
|
+
# Render :show view for read only trix fields
|
57
|
+
def view_for(field)
|
58
|
+
field.is_a?(Avo::Fields::TrixField) && field.is_disabled? ? :show : view
|
59
|
+
end
|
60
|
+
|
48
61
|
private
|
49
62
|
|
50
63
|
def via_index?
|
51
64
|
params[:via_view] == "index"
|
52
65
|
end
|
53
66
|
|
67
|
+
def via_belongs_to?
|
68
|
+
params[:via_belongs_to_resource_class].present?
|
69
|
+
end
|
70
|
+
|
54
71
|
def is_edit?
|
55
72
|
view.in?(%w[edit update])
|
56
73
|
end
|
@@ -76,9 +93,4 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
|
|
76
93
|
)
|
77
94
|
end
|
78
95
|
end
|
79
|
-
|
80
|
-
# Render :show view for read only trix fields
|
81
|
-
def view_for(field)
|
82
|
-
field.is_a?(Avo::Fields::TrixField) && field.is_disabled? ? :show : view
|
83
|
-
end
|
84
96
|
end
|
@@ -7,39 +7,20 @@
|
|
7
7
|
selected_resources: [@resource.record.to_param],
|
8
8
|
**@resource.stimulus_data_attributes
|
9
9
|
} do %>
|
10
|
-
<%=
|
11
|
-
|
12
|
-
<%
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
.component_for_view(view)
|
25
|
-
.new(field: field, resource: @resource, index: index, compact: sidebar.present?)
|
26
|
-
%>
|
27
|
-
<% end %>
|
28
|
-
</div>
|
29
|
-
<% end %>
|
30
|
-
<% end %>
|
31
|
-
<% if sidebar.present? %>
|
32
|
-
<% c.with_sidebar do %>
|
33
|
-
<%= render sidebar_component %>
|
34
|
-
<% end %>
|
35
|
-
<% end %>
|
36
|
-
<% end %>
|
37
|
-
<% if @reflection.blank? %>
|
38
|
-
<%= content_tag :div, class: 'space-y-12 mt-12' do %>
|
39
|
-
<% @resource.get_items.each_with_index do |item, index| %>
|
40
|
-
<% next if item.nil? %>
|
41
|
-
<%= render Avo::ItemSwitcherComponent.new resource: @resource, reflection: @reflection, item: item, index: index + 1, view: @view %>
|
42
|
-
<% end %>
|
10
|
+
<%= content_tag :div, class: 'space-y-12' do %>
|
11
|
+
<%= render_cards_component %>
|
12
|
+
<% @resource.get_items.each_with_index do |item, index| %>
|
13
|
+
<%= render Avo::Items::SwitcherComponent.new(
|
14
|
+
resource: @resource,
|
15
|
+
reflection: @reflection,
|
16
|
+
item: item,
|
17
|
+
index: index + 1,
|
18
|
+
view: @view,
|
19
|
+
parent_resource: @parent_resource,
|
20
|
+
parent_record: @parent_record,
|
21
|
+
parent_component: self,
|
22
|
+
actions: @actions
|
23
|
+
)%>
|
43
24
|
<% end %>
|
44
25
|
<% end %>
|
45
26
|
<% if should_display_invalid_fields_errors? %>
|
@@ -3,6 +3,8 @@
|
|
3
3
|
class Avo::Views::ResourceShowComponent < Avo::ResourceComponent
|
4
4
|
include Avo::ApplicationHelper
|
5
5
|
|
6
|
+
attr_reader :actions, :display_breadcrumbs
|
7
|
+
|
6
8
|
def initialize(resource: nil, reflection: nil, parent_resource: nil, parent_record: nil, resource_panel: nil, actions: [])
|
7
9
|
@resource = resource
|
8
10
|
@reflection = reflection
|
@@ -11,6 +13,7 @@ class Avo::Views::ResourceShowComponent < Avo::ResourceComponent
|
|
11
13
|
@parent_record = parent_record
|
12
14
|
@parent_resource = parent_resource
|
13
15
|
@view = Avo::ViewInquirer.new("show")
|
16
|
+
@display_breadcrumbs = reflection.blank?
|
14
17
|
end
|
15
18
|
|
16
19
|
def title
|
@@ -44,6 +47,14 @@ class Avo::Views::ResourceShowComponent < Avo::ResourceComponent
|
|
44
47
|
helpers.edit_resource_path(record: @resource.record, resource: @resource, **args)
|
45
48
|
end
|
46
49
|
|
50
|
+
def controls
|
51
|
+
@resource.render_show_controls
|
52
|
+
end
|
53
|
+
|
54
|
+
def view_for(field)
|
55
|
+
@view
|
56
|
+
end
|
57
|
+
|
47
58
|
private
|
48
59
|
|
49
60
|
# In development and test environments we should show the invalid field errors
|
@@ -10,13 +10,13 @@ module Avo
|
|
10
10
|
request.params[:id].present?
|
11
11
|
end
|
12
12
|
before_action :set_action, only: [:show, :handle]
|
13
|
+
before_action :verify_authorization, only: [:show, :handle]
|
13
14
|
|
14
15
|
def show
|
15
16
|
# Se the view to :new so the default value gets prefilled
|
16
17
|
@view = Avo::ViewInquirer.new("new")
|
17
18
|
|
18
19
|
@resource.hydrate(record: @record, view: @view, user: _current_user, params: params)
|
19
|
-
@record = ActionModel.new @action.get_attributes_for_action
|
20
20
|
end
|
21
21
|
|
22
22
|
def handle
|
@@ -83,8 +83,6 @@ module Avo
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
private
|
87
|
-
|
88
86
|
def get_messages(response)
|
89
87
|
default_message = {
|
90
88
|
type: :info,
|
@@ -126,9 +124,13 @@ module Avo
|
|
126
124
|
|
127
125
|
respond_to do |format|
|
128
126
|
format.turbo_stream do
|
129
|
-
render "
|
127
|
+
render partial: "avo/partials/flash_alerts"
|
130
128
|
end
|
131
129
|
end
|
132
130
|
end
|
131
|
+
|
132
|
+
def verify_authorization
|
133
|
+
raise Avo::NotAuthorizedError.new unless @action.authorized?
|
134
|
+
end
|
133
135
|
end
|
134
136
|
end
|
@@ -10,7 +10,6 @@ module Avo
|
|
10
10
|
include Avo::ApplicationHelper
|
11
11
|
include Avo::UrlHelpers
|
12
12
|
include Avo::Concerns::Breadcrumbs
|
13
|
-
include Pagy::Backend
|
14
13
|
|
15
14
|
protect_from_forgery with: :exception
|
16
15
|
around_action :set_avo_locale
|
@@ -130,7 +129,7 @@ module Avo
|
|
130
129
|
end
|
131
130
|
|
132
131
|
def set_record
|
133
|
-
@record = @resource.find_record(params[:id], query:
|
132
|
+
@record = @resource.find_record(params[:id], query: model_scope, params: params)
|
134
133
|
@resource.hydrate(record: @record)
|
135
134
|
end
|
136
135
|
|
@@ -139,15 +138,11 @@ module Avo
|
|
139
138
|
@related_record = if @field.is_a? Avo::Fields::HasOneField
|
140
139
|
@record.send association_name
|
141
140
|
else
|
142
|
-
@related_resource.find_record params[:related_id], query:
|
141
|
+
@related_resource.find_record params[:related_id], query: @record.send(association_name), params: params
|
143
142
|
end
|
144
143
|
@related_resource.hydrate(record: @related_record)
|
145
144
|
end
|
146
145
|
|
147
|
-
def model_find_scope
|
148
|
-
eager_load_files(@resource, model_scope)
|
149
|
-
end
|
150
|
-
|
151
146
|
def model_scope
|
152
147
|
# abort @resource.inspect
|
153
148
|
@resource.class.find_scope
|
@@ -203,32 +198,6 @@ module Avo
|
|
203
198
|
@authorization.set_record(class_to_authorize).authorize_action action_to_authorize.to_sym
|
204
199
|
end
|
205
200
|
|
206
|
-
def eager_load_files(resource, query)
|
207
|
-
# Get the non-computed file fields and try to eager load them
|
208
|
-
attachment_fields = resource
|
209
|
-
.attachment_fields
|
210
|
-
.reject do |field|
|
211
|
-
field.computed
|
212
|
-
end
|
213
|
-
|
214
|
-
if attachment_fields.present?
|
215
|
-
attachment_fields.map do |field|
|
216
|
-
attachment = case field.class.to_s
|
217
|
-
when "Avo::Fields::FileField"
|
218
|
-
"attachment"
|
219
|
-
when "Avo::Fields::FilesField"
|
220
|
-
"attachments"
|
221
|
-
else
|
222
|
-
"attachment"
|
223
|
-
end
|
224
|
-
|
225
|
-
return query.includes "#{field.id}_#{attachment}": :blob
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
query
|
230
|
-
end
|
231
|
-
|
232
201
|
def _authenticate!
|
233
202
|
instance_eval(&Avo.configuration.authenticate)
|
234
203
|
end
|
@@ -34,9 +34,6 @@ module Avo
|
|
34
34
|
@query = @query.includes(*@resource.includes)
|
35
35
|
end
|
36
36
|
|
37
|
-
# Eager load the active storage attachments
|
38
|
-
@query = eager_load_files(@resource, @query)
|
39
|
-
|
40
37
|
# Sort the items
|
41
38
|
if @index_params[:sort_by].present?
|
42
39
|
unless @index_params[:sort_by].eql? :created_at
|
@@ -60,17 +57,9 @@ module Avo
|
|
60
57
|
).apply_query request, @query, filter_value
|
61
58
|
end
|
62
59
|
|
63
|
-
extra_pagy_params = {}
|
64
|
-
|
65
|
-
# Reset open filters when a user navigates to a new page
|
66
|
-
extra_pagy_params[:keep_filters_panel_open] = if params[:keep_filters_panel_open] == "1"
|
67
|
-
"0"
|
68
|
-
end
|
69
|
-
|
70
60
|
safe_call :set_and_apply_scopes
|
71
61
|
safe_call :apply_dynamic_filters
|
72
|
-
|
73
|
-
@pagy, @records = pagy(pagy_query, items: @index_params[:per_page], link_extra: "data-turbo-frame=\"#{params[:turbo_frame]}\"", size: [1, 2, 2, 1], params: extra_pagy_params)
|
62
|
+
apply_pagination
|
74
63
|
|
75
64
|
# Create resources for each record
|
76
65
|
@resources = @records.map do |record|
|
@@ -109,6 +98,11 @@ module Avo
|
|
109
98
|
@record = @resource.model_class.new
|
110
99
|
@resource = @resource.hydrate(record: @record, view: :new, user: _current_user)
|
111
100
|
|
101
|
+
# Handle special cases when creating a new record via a belongs_to relationship
|
102
|
+
if params[:via_belongs_to_resource_class].present?
|
103
|
+
return render turbo_stream: turbo_stream.append('attach_modal', partial: 'avo/base/new_via_belongs_to')
|
104
|
+
end
|
105
|
+
|
112
106
|
set_actions
|
113
107
|
|
114
108
|
@page_title = @resource.default_panel_name.to_s
|
@@ -134,7 +128,7 @@ module Avo
|
|
134
128
|
@resource.hydrate(record: @record, view: :new, user: _current_user)
|
135
129
|
|
136
130
|
# This means that the record has been created through another parent record and we need to attach it somehow.
|
137
|
-
if params[:via_record_id].present?
|
131
|
+
if params[:via_record_id].present? && params[:via_belongs_to_resource_class].nil?
|
138
132
|
@reflection = @record._reflections[params[:via_relation]]
|
139
133
|
# Figure out what kind of association does the record have with the parent record
|
140
134
|
|
@@ -433,15 +427,19 @@ module Avo
|
|
433
427
|
end
|
434
428
|
|
435
429
|
def create_success_action
|
430
|
+
return render "close_modal_and_reload_field" if params[:via_belongs_to_resource_class].present?
|
431
|
+
|
436
432
|
respond_to do |format|
|
437
433
|
format.html { redirect_to after_create_path, notice: create_success_message}
|
438
434
|
end
|
439
435
|
end
|
440
436
|
|
441
437
|
def create_fail_action
|
438
|
+
flash.now[:error] = create_fail_message
|
439
|
+
|
442
440
|
respond_to do |format|
|
443
|
-
flash.now[:error] = create_fail_message
|
444
441
|
format.html { render :new, status: :unprocessable_entity }
|
442
|
+
format.turbo_stream { render "create_fail_action" }
|
445
443
|
end
|
446
444
|
end
|
447
445
|
|
@@ -456,7 +454,12 @@ module Avo
|
|
456
454
|
def after_create_path
|
457
455
|
# If this is an associated record return to the association show page
|
458
456
|
if is_associated_record?
|
459
|
-
parent_resource =
|
457
|
+
parent_resource = if params[:via_resource_class].present?
|
458
|
+
Avo.resource_manager.get_resource(params[:via_resource_class])
|
459
|
+
else
|
460
|
+
Avo.resource_manager.get_resource_by_model_class(params[:via_relation_class])
|
461
|
+
end
|
462
|
+
|
460
463
|
association_name = BaseResource.valid_association_name(@record, params[:via_relation])
|
461
464
|
|
462
465
|
return resource_view_path(
|
@@ -508,8 +511,10 @@ module Avo
|
|
508
511
|
end
|
509
512
|
|
510
513
|
def destroy_fail_action
|
514
|
+
flash[:error] = destroy_fail_message
|
515
|
+
|
511
516
|
respond_to do |format|
|
512
|
-
format.
|
517
|
+
format.turbo_stream { render partial: "avo/partials/flash_alerts" }
|
513
518
|
end
|
514
519
|
end
|
515
520
|
|
@@ -579,5 +584,9 @@ module Avo
|
|
579
584
|
"That component was fetched from 'self.components' option inside '#{@resource.class}' resource."
|
580
585
|
end
|
581
586
|
end
|
587
|
+
|
588
|
+
def apply_pagination
|
589
|
+
@pagy, @records = @resource.apply_pagination(index_params: @index_params, query: pagy_query)
|
590
|
+
end
|
582
591
|
end
|
583
592
|
end
|