avo 2.16.1.pre.1.nativefields → 2.17.1.pre.1.zeitwerk.eager.load.dir
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 +7 -3
- data/Gemfile.lock +43 -8
- data/README.md +1 -1
- data/app/assets/config/avo_manifest.js +1 -0
- data/app/assets/svgs/placeholder.svg +1 -0
- data/app/components/avo/actions_component.html.erb +3 -3
- data/app/components/avo/base_component.rb +7 -4
- data/app/components/avo/field_wrapper_component.html.erb +8 -10
- data/app/components/avo/field_wrapper_component.rb +14 -12
- data/app/components/avo/fields/badge_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/belongs_to_field/edit_component.rb +9 -3
- data/app/components/avo/fields/belongs_to_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/belongs_to_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/belongs_to_field/show_component.rb +1 -1
- data/app/components/avo/fields/boolean_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/boolean_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/boolean_group_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/boolean_group_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/code_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/common/heading_component.html.erb +5 -4
- data/app/components/avo/fields/common/heading_component.rb +6 -1
- data/app/components/avo/fields/country_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/date_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/date_time_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/edit_component.rb +6 -4
- data/app/components/avo/fields/external_image_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/file_field/edit_component.html.erb +2 -1
- data/app/components/avo/fields/file_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/files_field/edit_component.html.erb +2 -1
- data/app/components/avo/fields/files_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/files_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/gravatar_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/has_one_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/heading_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/heading_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/id_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/index_component.rb +11 -2
- data/app/components/avo/fields/number_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/progress_bar_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/select_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/show_component.rb +7 -1
- data/app/components/avo/fields/status_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/tags_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/text_field/edit_component.html.erb +3 -1
- data/app/components/avo/fields/text_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/trix_field/edit_component.html.erb +1 -1
- data/app/components/avo/filters_component.html.erb +2 -2
- data/app/components/avo/index/grid_cover_empty_state_component.html.erb +1 -1
- data/app/components/avo/index/grid_item_component.html.erb +15 -13
- data/app/components/avo/index/grid_item_component.rb +1 -1
- data/app/components/avo/index/ordering/buttons_component.html.erb +1 -1
- data/app/components/avo/index/resource_controls_component.rb +2 -2
- data/app/components/avo/index/table_row_component.html.erb +1 -1
- data/app/components/avo/panel_component.html.erb +9 -2
- data/app/components/avo/panel_component.rb +3 -4
- data/app/components/avo/resource_component.rb +18 -0
- data/app/components/avo/resource_sidebar_component.html.erb +19 -0
- data/app/components/avo/resource_sidebar_component.rb +26 -0
- data/app/components/avo/sidebar_profile_component.html.erb +1 -1
- data/app/components/avo/tab_switcher_component.html.erb +2 -2
- data/app/components/avo/tab_switcher_component.rb +2 -0
- data/app/components/avo/views/resource_edit_component.html.erb +31 -25
- data/app/components/avo/views/resource_edit_component.rb +1 -1
- data/app/components/avo/views/resource_show_component.html.erb +8 -2
- data/app/components/avo/views/resource_show_component.rb +1 -1
- data/app/controllers/avo/actions_controller.rb +10 -2
- data/app/controllers/avo/application_controller.rb +4 -2
- data/app/controllers/avo/associations_controller.rb +24 -5
- data/app/controllers/avo/attachments_controller.rb +2 -1
- data/app/controllers/avo/base_controller.rb +6 -4
- data/app/controllers/avo/search_controller.rb +13 -4
- data/app/helpers/avo/application_helper.rb +7 -3
- data/app/helpers/avo/resources_helper.rb +2 -2
- data/app/javascript/avo.base.js +3 -1
- data/app/javascript/js/controllers/action_controller.js +1 -4
- data/app/javascript/js/controllers/actions_picker_controller.js +8 -9
- data/app/javascript/js/controllers/tabs_controller.js +14 -27
- data/app/views/avo/actions/show.html.erb +2 -2
- data/app/views/avo/home/failed_to_load.html.erb +3 -2
- data/avo.gemspec +2 -2
- data/config/brakeman.ignore +40 -0
- data/config/i18n-tasks.yml +159 -0
- data/config/routes.rb +1 -1
- data/db/factories.rb +20 -0
- data/lib/avo/app.rb +6 -0
- data/lib/avo/base_resource.rb +26 -0
- data/lib/avo/concerns/fetches_things.rb +1 -1
- data/lib/avo/concerns/has_fields.rb +22 -0
- data/lib/avo/concerns/is_resource_item.rb +4 -0
- data/lib/avo/configuration/branding.rb +9 -1
- data/lib/avo/dynamic_router.rb +19 -15
- data/lib/avo/engine.rb +9 -0
- data/lib/avo/fields/belongs_to_field.rb +3 -0
- data/lib/avo/fields/heading_field.rb +15 -0
- data/lib/avo/items_holder.rb +4 -0
- data/lib/avo/licensing/pro_license.rb +1 -0
- data/lib/avo/menu/builder.rb +1 -1
- data/lib/avo/menu/menu.rb +0 -2
- data/lib/avo/reloader.rb +27 -26
- data/lib/avo/services/authorization_service.rb +17 -3
- data/lib/avo/services/encryption_service.rb +1 -1
- data/lib/avo/sidebar.rb +60 -0
- data/lib/avo/sidebar_builder.rb +24 -0
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/templates/field/components/index_component.html.erb.tt +1 -1
- data/lib/generators/avo/templates/initializer/avo.tt +2 -1
- data/lib/generators/avo/templates/locales/avo.en.yml +107 -107
- data/lib/generators/avo/templates/locales/avo.fr.yml +107 -107
- data/lib/generators/avo/templates/locales/avo.nb.yml +119 -0
- data/lib/generators/avo/templates/locales/avo.nn.yml +119 -0
- data/lib/generators/avo/templates/locales/avo.pt-BR.yml +109 -84
- data/lib/generators/avo/templates/locales/avo.ro.yml +109 -81
- data/lib/generators/avo/templates/locales/avo.tr.yml +119 -0
- data/public/avo-assets/avo.base.css +67 -79
- data/public/avo-assets/avo.base.js +63 -63
- data/public/avo-assets/avo.base.js.map +3 -3
- metadata +16 -22
- data/app/views/avo/home/failed_to_load.html copy.erb +0 -23
- data/lib/generators/avo/templates/locales/avo.nb-NO.yml +0 -93
@@ -1,3 +1,3 @@
|
|
1
1
|
<div <% if @index == 0 %> class="overflow-hidden rounded-t" <% end %> data-field-id="<%= @field.id %>">
|
2
|
-
<%= render Avo::Fields::Common::HeadingComponent.new value: @field.name, as_html: @field.as_html %>
|
2
|
+
<%= render Avo::Fields::Common::HeadingComponent.new value: @field.name, as_html: @field.as_html, empty: @field.empty %>
|
3
3
|
</div>
|
@@ -1,3 +1,3 @@
|
|
1
1
|
<div <% if @index == 0 %> class="overflow-hidden rounded-t" <% end %> data-field-id="<%= @field.id %>">
|
2
|
-
<%= render Avo::Fields::Common::HeadingComponent.new value: @field.name, as_html: @field.as_html %>
|
2
|
+
<%= render Avo::Fields::Common::HeadingComponent.new value: @field.name, as_html: @field.as_html, empty: @field.empty %>
|
3
3
|
</div>
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<%= index_field_wrapper
|
1
|
+
<%= index_field_wrapper **field_wrapper_args, class: 'whitespace-no-wrap w-[1%]' do %>
|
2
2
|
<% link_to_if (@field.link_to_resource or Avo.configuration.id_links_to_resource), @field.value, resource_view_path, title: t('avo.view_item', item: @resource.name).humanize %>
|
3
3
|
<% end %>
|
@@ -3,13 +3,15 @@
|
|
3
3
|
class Avo::Fields::IndexComponent < ViewComponent::Base
|
4
4
|
include Avo::ResourcesHelper
|
5
5
|
|
6
|
+
attr_reader :parent_resource
|
6
7
|
attr_reader :view
|
7
8
|
|
8
|
-
def initialize(field: nil, resource: nil, index: 0, parent_model: nil)
|
9
|
+
def initialize(field: nil, resource: nil, index: 0, parent_model: nil, parent_resource: nil)
|
9
10
|
@field = field
|
10
11
|
@resource = resource
|
11
12
|
@index = index
|
12
13
|
@parent_model = parent_model
|
14
|
+
@parent_resource = parent_resource
|
13
15
|
@view = :index
|
14
16
|
end
|
15
17
|
|
@@ -18,11 +20,18 @@ class Avo::Fields::IndexComponent < ViewComponent::Base
|
|
18
20
|
|
19
21
|
if @parent_model.present?
|
20
22
|
args = {
|
21
|
-
via_resource_class: @
|
23
|
+
via_resource_class: @parent_resource.class,
|
22
24
|
via_resource_id: @parent_model.id
|
23
25
|
}
|
24
26
|
end
|
25
27
|
|
26
28
|
helpers.resource_view_path(model: @resource.model, resource: @resource, **args)
|
27
29
|
end
|
30
|
+
|
31
|
+
def field_wrapper_args
|
32
|
+
{
|
33
|
+
field: @field,
|
34
|
+
resource: @resource
|
35
|
+
}
|
36
|
+
end
|
28
37
|
end
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<%= index_field_wrapper
|
1
|
+
<%= index_field_wrapper **field_wrapper_args, flush: true do %>
|
2
2
|
<%= render Avo::Fields::Common::ProgressBarComponent.new value: @field.value, display_value: @field.display_value, value_suffix: @field.value_suffix, max: @field.max, view: view %>
|
3
3
|
<% end %>
|
@@ -3,15 +3,19 @@
|
|
3
3
|
class Avo::Fields::ShowComponent < ViewComponent::Base
|
4
4
|
include Avo::ResourcesHelper
|
5
5
|
|
6
|
+
attr_reader :compact
|
6
7
|
attr_reader :field
|
7
8
|
attr_reader :index
|
8
9
|
attr_reader :resource
|
10
|
+
attr_reader :stacked
|
9
11
|
attr_reader :view
|
10
12
|
|
11
|
-
def initialize(field: nil, resource: nil, index: 0, form: nil)
|
13
|
+
def initialize(field: nil, resource: nil, index: 0, form: nil, compact: false, stacked: false)
|
14
|
+
@compact = compact
|
12
15
|
@field = field
|
13
16
|
@index = index
|
14
17
|
@resource = resource
|
18
|
+
@stacked = stacked
|
15
19
|
@view = :show
|
16
20
|
end
|
17
21
|
|
@@ -40,9 +44,11 @@ class Avo::Fields::ShowComponent < ViewComponent::Base
|
|
40
44
|
|
41
45
|
def field_wrapper_args
|
42
46
|
{
|
47
|
+
compact: compact,
|
43
48
|
field: field,
|
44
49
|
index: index,
|
45
50
|
resource: resource,
|
51
|
+
stacked: stacked,
|
46
52
|
view: view
|
47
53
|
}
|
48
54
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= index_field_wrapper
|
1
|
+
<%= index_field_wrapper **field_wrapper_args, flush: true do %>
|
2
2
|
<div class="flex gap-1 items-center flex-nowrap">
|
3
3
|
<% value.take(3).each do |item| %>
|
4
4
|
<%= render Avo::Fields::TagsField::TagComponent.new(label: label_from_item(item)) %>
|
@@ -4,6 +4,8 @@
|
|
4
4
|
data: @field.get_html(:data, view: view, element: :input),
|
5
5
|
disabled: @field.is_readonly?,
|
6
6
|
placeholder: @field.placeholder,
|
7
|
-
style: @field.get_html(:style, view: view, element: :input)
|
7
|
+
style: @field.get_html(:style, view: view, element: :input),
|
8
|
+
# value: @field.value,
|
9
|
+
multiple: multiple
|
8
10
|
%>
|
9
11
|
<% end %>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%=
|
1
|
+
<%= field_wrapper **field_wrapper_args, full_width: true do %>
|
2
2
|
<%= content_tag :div, class: "relative block overflow-x-auto max-w-full",
|
3
3
|
data: {
|
4
4
|
controller: "trix-field",
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<div data-controller="toggle-panel">
|
2
|
-
<div class="relative w-full flex justify-between
|
2
|
+
<div class="relative w-full flex justify-between">
|
3
3
|
<%= a_button class: 'focus:outline-none',
|
4
4
|
color: :primary,
|
5
5
|
size: :sm,
|
@@ -14,7 +14,7 @@
|
|
14
14
|
<% end %>
|
15
15
|
<% end %>
|
16
16
|
<div
|
17
|
-
class="absolute block inset-auto sm:right-0 top-full bg-white min-w-[300px] mt-2 z-
|
17
|
+
class="absolute block inset-auto sm:right-0 top-full bg-white min-w-[300px] mt-2 z-40 shadow-modal rounded divide-y divide-gray-300 <%= 'hidden' unless params[:keep_filters_panel_open] == '1' %>"
|
18
18
|
data-toggle-panel-target="panel"
|
19
19
|
>
|
20
20
|
<% @filters.each do |filter| %>
|
@@ -1,3 +1,3 @@
|
|
1
1
|
<div class="absolute bg-gray-50 w-full h-full">
|
2
|
-
<%=
|
2
|
+
<%= image_tag Avo.configuration.branding.placeholder, class: 'relative transform -translate-x-1/2 -translate-y-1/2 h-20 text-gray-400 inset-auto top-1/2 left-1/2' %>
|
3
3
|
</div>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
class="relative bg-white rounded shadow-modal flex flex-col group"
|
3
3
|
<%== item_selector_init @resource %>
|
4
4
|
>
|
5
|
-
|
5
|
+
<%= content_tag :div, class: "relative w-full pb-3/4 rounded-t overflow-hidden #{cover.present? ? cover.get_html(:classes, view: :index, element: :wrapper) : ""}", style: cover.present? ? cover.get_html(:style, view: :index, element: :wrapper) : "" do %>
|
6
6
|
<% if @resource.record_selector %>
|
7
7
|
<%== item_selector_input floating: true, size: :lg %>
|
8
8
|
<% end %>
|
@@ -17,9 +17,7 @@
|
|
17
17
|
<%= link_to_if cover.link_to_resource, image_tag(helpers.main_app.url_for(cover.value.variant(resize_to_limit: [480, 480])), class: 'absolute h-full w-full object-cover'), resource_view_path, class: 'absolute h-full w-full object-cover', title: title.value %>
|
18
18
|
<% else %>
|
19
19
|
<%= link_to resource_view_path do %>
|
20
|
-
|
21
|
-
<%= helpers.svg 'avocado', class: 'relative transform -translate-x-1/2 -translate-y-1/2 h-20 text-gray-400 inset-auto top-1/2 left-1/2' %>
|
22
|
-
</div>
|
20
|
+
<%= render Avo::Index::GridCoverEmptyStateComponent.new %>
|
23
21
|
<% end %>
|
24
22
|
<% end %>
|
25
23
|
<% elsif cover.value.present? %>
|
@@ -27,18 +25,22 @@
|
|
27
25
|
<% else %>
|
28
26
|
<%= render Avo::Index::GridCoverEmptyStateComponent.new %>
|
29
27
|
<% end %>
|
30
|
-
|
31
|
-
|
28
|
+
<% end %>
|
29
|
+
<%= content_tag :div, class: "grid grid-cols-1 place-content-between p-4 h-full" do %>
|
32
30
|
<div class="mb-4 h-full flex flex-col space-between">
|
33
|
-
|
34
|
-
<%=
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
31
|
+
<% if title.present? %>
|
32
|
+
<%= content_tag :div, class: "grid font-semibold leading-tight text-lg mb-2 #{title.get_html(:classes, view: :index, element: :wrapper)}", style: title.get_html(:style, view: :index, element: :wrapper) do %>
|
33
|
+
<%= link_to_if title.link_to_resource, title.value, resource_view_path %>
|
34
|
+
<% end %>
|
35
|
+
<% end %>
|
36
|
+
<% if body.present? %>
|
37
|
+
<%= content_tag :div, class: "text-sm break-words text-gray-500 #{body.get_html(:classes, view: :index, element: :wrapper)}", style: body.get_html(:style, view: :index, element: :wrapper) do %>
|
38
|
+
<%= body.value %>
|
39
|
+
<% end %>
|
40
|
+
<% end %>
|
39
41
|
</div>
|
40
42
|
<div class="w-full place-self-end">
|
41
43
|
<%= render(Avo::Index::ResourceControlsComponent.new(resource: @resource, reflection: @reflection, parent_model: @parent_model, parent_resource: @parent_resource, view_type: :grid)) %>
|
42
44
|
</div>
|
43
|
-
|
45
|
+
<% end %>
|
44
46
|
</div>
|
@@ -22,7 +22,7 @@
|
|
22
22
|
%>
|
23
23
|
<%= helpers.svg('switch-vertical', class: 'text-gray-400 h-6 hover:text-gray-600') %>
|
24
24
|
<% end %>
|
25
|
-
<div class="flex hidden absolute max-w-xs bg-white rounded p-2
|
25
|
+
<div class="flex hidden absolute max-w-xs bg-white rounded p-2" data-popover-target="content">
|
26
26
|
<%= render Avo::Index::Ordering::ButtonComponent.new resource: @resource, reflection: @reflection, direction: :higher, svg: 'arrow-up' %>
|
27
27
|
<%= render Avo::Index::Ordering::ButtonComponent.new resource: @resource, reflection: @reflection, direction: :lower, svg: 'arrow-down' %>
|
28
28
|
<%= render Avo::Index::Ordering::ButtonComponent.new resource: @resource, reflection: @reflection, direction: :to_top, svg: 'download-solid-reversed' %>
|
@@ -36,7 +36,7 @@ class Avo::Index::ResourceControlsComponent < Avo::ResourceComponent
|
|
36
36
|
|
37
37
|
if @parent_model.present?
|
38
38
|
args = {
|
39
|
-
via_resource_class: parent_resource.
|
39
|
+
via_resource_class: parent_resource.class.to_s,
|
40
40
|
via_resource_id: @parent_model.id
|
41
41
|
}
|
42
42
|
end
|
@@ -50,7 +50,7 @@ class Avo::Index::ResourceControlsComponent < Avo::ResourceComponent
|
|
50
50
|
|
51
51
|
if @parent_model.present?
|
52
52
|
args = {
|
53
|
-
via_resource_class: parent_resource.
|
53
|
+
via_resource_class: parent_resource.class.to_s,
|
54
54
|
via_resource_id: @parent_model.id
|
55
55
|
}
|
56
56
|
end
|
@@ -17,7 +17,7 @@
|
|
17
17
|
</td>
|
18
18
|
<% end %>
|
19
19
|
<% @resource.get_fields(reflection: @reflection, only_root: true).each_with_index do |field, index| %>
|
20
|
-
<%= render field.component_for_view(:index).new(field: field, resource: @resource, index: index, parent_model: @parent_model) %>
|
20
|
+
<%= render field.component_for_view(:index).new(field: field, resource: @resource, index: index, parent_model: @parent_model, parent_resource: @parent_resource) %>
|
21
21
|
<% end %>
|
22
22
|
<% if Avo.configuration.resource_controls_on_the_right? %>
|
23
23
|
<td class="text-right whitespace-nowrap px-2" data-control="resource-controls">
|
@@ -24,8 +24,15 @@
|
|
24
24
|
</div>
|
25
25
|
<% end %>
|
26
26
|
<% if body? %>
|
27
|
-
<div class="
|
28
|
-
<%=
|
27
|
+
<div 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 overflow-auto <%= white_panel_classes %> <%= @body_classes %> <% if sidebar? %> w-2/3 <% end %>">
|
29
|
+
<%= body %>
|
30
|
+
</div>
|
31
|
+
<% if sidebar? %>
|
32
|
+
<div class="w-full sm:w-1/3 flex-shrink-0 h-full <%= white_panel_classes %>">
|
33
|
+
<%= sidebar %>
|
34
|
+
</div>
|
35
|
+
<% end %>
|
29
36
|
</div>
|
30
37
|
<% end %>
|
31
38
|
<% if bare_content? %>
|
@@ -5,8 +5,11 @@ class Avo::PanelComponent < ViewComponent::Base
|
|
5
5
|
attr_reader :name
|
6
6
|
attr_reader :classes
|
7
7
|
|
8
|
+
delegate :white_panel_classes, to: :helpers
|
9
|
+
|
8
10
|
renders_one :tools
|
9
11
|
renders_one :body
|
12
|
+
renders_one :sidebar
|
10
13
|
renders_one :bare_content
|
11
14
|
renders_one :footer_tools
|
12
15
|
renders_one :footer
|
@@ -25,10 +28,6 @@ class Avo::PanelComponent < ViewComponent::Base
|
|
25
28
|
|
26
29
|
private
|
27
30
|
|
28
|
-
def white_panel_classes
|
29
|
-
"bg-white rounded shadow"
|
30
|
-
end
|
31
|
-
|
32
31
|
def data_attributes
|
33
32
|
@data.merge({"panel-index": @index})
|
34
33
|
end
|
@@ -85,6 +85,16 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
+
def sidebar
|
89
|
+
return if Avo::App.license.lacks_with_trial(:resource_sidebar)
|
90
|
+
|
91
|
+
@sidebar ||= search_for_sidebar
|
92
|
+
end
|
93
|
+
|
94
|
+
def sidebar_component(form: nil)
|
95
|
+
Avo::ResourceSidebarComponent.new resource: @resource, fields: sidebar.items, params: params, view: view, form: form
|
96
|
+
end
|
97
|
+
|
88
98
|
def has_reflection_and_is_read_only
|
89
99
|
if @reflection.present? && @reflection.active_record.name && @reflection.name
|
90
100
|
fields = ::Avo::App.get_resource_by_model_name(@reflection.active_record.name).get_field_definitions
|
@@ -105,4 +115,12 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
105
115
|
def via_resource?
|
106
116
|
(params[:via_resource_class].present? || params[:via_relation_class].present?) && params[:via_resource_id].present?
|
107
117
|
end
|
118
|
+
|
119
|
+
def search_for_sidebar
|
120
|
+
item = @resource.get_items.find do |item|
|
121
|
+
item.is_sidebar?
|
122
|
+
end
|
123
|
+
|
124
|
+
item&.hydrate(view: view)
|
125
|
+
end
|
108
126
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<div class="resource-sidebar-component divide-y">
|
2
|
+
<% fields.each_with_index do |field, index| %>
|
3
|
+
<%= render field
|
4
|
+
.hydrate(
|
5
|
+
resource: resource,
|
6
|
+
model: resource.model,
|
7
|
+
user: resource.user,
|
8
|
+
view: view
|
9
|
+
).component_for_view(view)
|
10
|
+
.new(
|
11
|
+
field: field,
|
12
|
+
resource: resource,
|
13
|
+
form: form,
|
14
|
+
stacked: true,
|
15
|
+
index: index
|
16
|
+
)
|
17
|
+
%>
|
18
|
+
<% end %>
|
19
|
+
</div>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Avo::ResourceSidebarComponent < ViewComponent::Base
|
4
|
+
attr_reader :resource
|
5
|
+
attr_reader :params
|
6
|
+
attr_reader :view
|
7
|
+
attr_reader :form
|
8
|
+
|
9
|
+
def initialize(resource: nil, fields: nil, index: nil, params: nil, form: nil, view: nil)
|
10
|
+
@resource = resource
|
11
|
+
@fields = fields
|
12
|
+
@params = params
|
13
|
+
@view = view
|
14
|
+
@form = form
|
15
|
+
end
|
16
|
+
|
17
|
+
def fields
|
18
|
+
@fields.filter do |field|
|
19
|
+
field.visible_on? view
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def render?
|
24
|
+
Avo::App.license.has_with_trial(:resource_sidebar)
|
25
|
+
end
|
26
|
+
end
|
@@ -22,7 +22,7 @@
|
|
22
22
|
<%= helpers.svg 'three-dots', class: 'h-4' %>
|
23
23
|
</a>
|
24
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"
|
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
26
|
data-toggle-panel-target="panel"
|
27
27
|
>
|
28
28
|
<% if Avo::App.has_profile_menu? %>
|
@@ -20,13 +20,13 @@
|
|
20
20
|
</div>
|
21
21
|
</div>
|
22
22
|
<% else %>
|
23
|
-
<div class="flex flex-wrap gap-2" data-target="tab-switcher" data-style="pills">
|
23
|
+
<div class="flex flex-wrap gap-2 p-2 <%= white_panel_classes %>" data-target="tab-switcher" data-style="pills">
|
24
24
|
<% visible_items.each do |tab| %>
|
25
25
|
<%= a_link tab_path(tab),
|
26
26
|
color: selected?(tab) ? :primary : :gray,
|
27
27
|
style: selected?(tab) ? :outline : :text,
|
28
28
|
size: :sm,
|
29
|
-
class: selected?(tab) ? "z-20" : "",
|
29
|
+
class: selected?(tab) ? "z-20 bg-primary-100" : "",
|
30
30
|
title: tab.description,
|
31
31
|
data: {
|
32
32
|
tippy: tab.description.present? ? 'tooltip' : '',
|
@@ -11,6 +11,8 @@ class Avo::TabSwitcherComponent < Avo::BaseComponent
|
|
11
11
|
attr_reader :view
|
12
12
|
attr_reader :style
|
13
13
|
|
14
|
+
delegate :white_panel_classes, to: :helpers
|
15
|
+
|
14
16
|
def initialize(resource:, group:, current_tab:, active_tab_name:, view:, style:)
|
15
17
|
@active_tab_name = active_tab_name
|
16
18
|
@resource = resource
|
@@ -19,12 +19,12 @@
|
|
19
19
|
<%= render Avo::PanelComponent.new(name: title, description: @resource.resource_description, display_breadcrumbs: @reflection.blank?, index: 0, data: { panel_id: "main" }) do |c| %>
|
20
20
|
<% c.tools do %>
|
21
21
|
<%= a_link back_path,
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
style: :text,
|
23
|
+
icon: 'arrow-left' do %>
|
24
|
+
<%= t('avo.cancel').capitalize %>
|
25
|
+
<% end %>
|
26
|
+
<% if can_see_the_destroy_button? %>
|
27
|
+
<%= a_link destroy_path,
|
28
28
|
method: :delete,
|
29
29
|
local: true,
|
30
30
|
style: :text,
|
@@ -37,36 +37,42 @@
|
|
37
37
|
control: :destroy,
|
38
38
|
'resource-id': @resource.model.id,
|
39
39
|
} do %>
|
40
|
-
|
40
|
+
<%= t('avo.delete').capitalize %>
|
41
|
+
<% end %>
|
41
42
|
<% end %>
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
<%= a_button color: :primary,
|
43
|
+
<% if can_see_the_actions_button? %>
|
44
|
+
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource, view: @view %>
|
45
|
+
<% end %>
|
46
|
+
<% if can_see_the_save_button? %>
|
47
|
+
<%= a_button color: :primary,
|
48
48
|
style: :primary,
|
49
49
|
loading: true,
|
50
50
|
type: :submit,
|
51
51
|
icon: 'save' do %>
|
52
|
-
|
52
|
+
<%= t('avo.save').capitalize %>
|
53
|
+
<% end %>
|
53
54
|
<% end %>
|
54
55
|
<% end %>
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
56
|
+
<%# Extract the main panel and display the fields here. %>
|
57
|
+
<%# This way we'll be able to render the footer buttons under the main fields. %>
|
58
|
+
<% if main_panel.present? %>
|
59
|
+
<% c.body do %>
|
60
|
+
<div class="divide-y">
|
61
|
+
<% main_panel.items.each_with_index do |field, index| %>
|
62
|
+
<%= render field
|
63
|
+
.hydrate(resource: @resource, model: @resource.model, user: @resource.user, view: view_for(field))
|
64
|
+
.component_for_view(view_for field)
|
65
|
+
.new(field: field, resource: @resource, index: index, form: form, compact: sidebar.present?)
|
66
|
+
%>
|
66
67
|
<% end %>
|
67
68
|
</div>
|
68
69
|
<% end %>
|
69
70
|
<% end %>
|
71
|
+
<% if sidebar.present? %>
|
72
|
+
<% c.sidebar do %>
|
73
|
+
<%= render sidebar_component form: form %>
|
74
|
+
<% end %>
|
75
|
+
<% end %>
|
70
76
|
<% if Avo.configuration.buttons_on_form_footers %>
|
71
77
|
<% c.footer_tools do %>
|
72
78
|
<div class="mt-4">
|
@@ -31,7 +31,7 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def resource_view_path
|
34
|
-
helpers.resource_view_path(model:
|
34
|
+
helpers.resource_view_path(model: association_resource.model, resource: association_resource)
|
35
35
|
end
|
36
36
|
|
37
37
|
def can_see_the_destroy_button?
|
@@ -160,14 +160,20 @@
|
|
160
160
|
<% c.body do %>
|
161
161
|
<div class="divide-y">
|
162
162
|
<% main_panel.items.each_with_index do |field, index| %>
|
163
|
-
<%= render field
|
163
|
+
<%= render field
|
164
|
+
.hydrate(resource: @resource, model: @resource.model, user: @resource.user, view: view)
|
164
165
|
.component_for_view(view)
|
165
|
-
.new(field: field, resource: @resource, index: index)
|
166
|
+
.new(field: field, resource: @resource, index: index, compact: sidebar.present?)
|
166
167
|
%>
|
167
168
|
<% end %>
|
168
169
|
</div>
|
169
170
|
<% end %>
|
170
171
|
<% end %>
|
172
|
+
<% if sidebar.present? %>
|
173
|
+
<% c.sidebar do %>
|
174
|
+
<%= render sidebar_component %>
|
175
|
+
<% end %>
|
176
|
+
<% end %>
|
171
177
|
<% end %>
|
172
178
|
<% if @reflection.blank? %>
|
173
179
|
<%= content_tag :div, class: 'space-y-12 mt-12' do %>
|
@@ -26,7 +26,7 @@ class Avo::Views::ResourceShowComponent < Avo::ResourceComponent
|
|
26
26
|
|
27
27
|
def back_path
|
28
28
|
if via_resource?
|
29
|
-
helpers.resource_path(model:
|
29
|
+
helpers.resource_path(model: association_resource.model_class, resource: association_resource, resource_id: params[:via_resource_id])
|
30
30
|
else
|
31
31
|
helpers.resources_path(resource: @resource)
|
32
32
|
end
|
@@ -48,11 +48,19 @@ module Avo
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def set_action
|
51
|
-
action_class = params[:action_id].gsub("avo_actions_", "").camelize.safe_constantize
|
52
|
-
|
53
51
|
@action = action_class.new(model: @model, resource: @resource, user: _current_user, view: :edit)
|
54
52
|
end
|
55
53
|
|
54
|
+
def action_class
|
55
|
+
klass_name = params[:action_id].gsub("avo_actions_", "").camelize
|
56
|
+
|
57
|
+
valid_klass = Avo::BaseAction.descendants.find do |action|
|
58
|
+
action.to_s == klass_name
|
59
|
+
end
|
60
|
+
|
61
|
+
valid_klass
|
62
|
+
end
|
63
|
+
|
56
64
|
def respond(response)
|
57
65
|
response[:type] ||= :reload
|
58
66
|
messages = get_messages response
|
@@ -143,10 +143,12 @@ module Avo
|
|
143
143
|
end
|
144
144
|
|
145
145
|
def set_related_model
|
146
|
+
association_name = BaseResource.valid_association_name(@model, params[:related_name])
|
147
|
+
|
146
148
|
@related_model = if @field.is_a? Avo::Fields::HasOneField
|
147
|
-
@model.send
|
149
|
+
@model.send association_name
|
148
150
|
else
|
149
|
-
eager_load_files(@related_resource, @model.send(
|
151
|
+
eager_load_files(@related_resource, @model.send(association_name)).find params[:related_id]
|
150
152
|
end
|
151
153
|
end
|
152
154
|
|