avo 2.7.0 → 2.9.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 +2 -0
- data/Gemfile.lock +6 -4
- data/README.md +11 -0
- data/app/assets/stylesheets/avo.css +4 -4
- data/app/assets/stylesheets/css/{components → fields}/code.css +0 -0
- data/app/assets/stylesheets/css/{components → fields}/progress.css +0 -0
- data/app/assets/stylesheets/css/{components → fields}/status.css +0 -0
- data/app/assets/stylesheets/css/fields/trix.css +17 -0
- data/app/assets/svgs/download-solid-reversed.svg +2 -2
- data/app/components/avo/actions_component.html.erb +5 -13
- data/app/components/avo/actions_component.rb +39 -1
- data/app/components/avo/alert_component.rb +6 -0
- data/app/components/avo/card_component.html.erb +2 -2
- data/app/components/avo/common_field_wrapper_component.html.erb +11 -4
- data/app/components/avo/common_field_wrapper_component.rb +27 -1
- data/app/components/avo/edit/field_wrapper_component.html.erb +1 -1
- data/app/components/avo/fields/badge_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/badge_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/belongs_to_field/autocomplete_component.html.erb +21 -10
- data/app/components/avo/fields/belongs_to_field/autocomplete_component.rb +7 -1
- data/app/components/avo/fields/belongs_to_field/edit_component.html.erb +27 -15
- data/app/components/avo/fields/belongs_to_field/edit_component.rb +4 -0
- 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/boolean_field/edit_component.html.erb +4 -2
- 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/edit_component.html.erb +7 -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/edit_component.html.erb +7 -5
- data/app/components/avo/fields/code_field/show_component.html.erb +2 -2
- data/app/components/avo/fields/common/key_value_component.html.erb +10 -4
- data/app/components/avo/fields/common/key_value_component.rb +2 -0
- data/app/components/avo/fields/country_field/edit_component.html.erb +4 -2
- data/app/components/avo/fields/country_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/country_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/date_field/edit_component.html.erb +6 -4
- data/app/components/avo/fields/date_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/date_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/date_time_field/edit_component.html.erb +6 -4
- data/app/components/avo/fields/date_time_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/date_time_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/edit_component.rb +7 -0
- data/app/components/avo/fields/external_image_field/edit_component.html.erb +5 -2
- data/app/components/avo/fields/external_image_field/index_component.html.erb +6 -4
- data/app/components/avo/fields/external_image_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/file_field/edit_component.html.erb +6 -1
- data/app/components/avo/fields/file_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/file_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/files_field/edit_component.html.erb +7 -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/gravatar_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/has_one_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/hidden_field/edit_component.html.erb +5 -1
- data/app/components/avo/fields/id_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/id_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/id_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/index_component.rb +3 -0
- data/app/components/avo/fields/key_value_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/key_value_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/markdown_field/edit_component.html.erb +8 -5
- data/app/components/avo/fields/markdown_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/number_field/edit_component.html.erb +7 -4
- data/app/components/avo/fields/number_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/number_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/password_field/edit_component.html.erb +4 -2
- data/app/components/avo/fields/progress_bar_field/edit_component.html.erb +7 -4
- data/app/components/avo/fields/progress_bar_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/progress_bar_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/select_field/edit_component.html.erb +9 -3
- data/app/components/avo/fields/select_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/select_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/show_component.rb +3 -0
- data/app/components/avo/fields/status_field/edit_component.html.erb +6 -3
- data/app/components/avo/fields/status_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/status_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/tags_field/edit_component.html.erb +19 -11
- data/app/components/avo/fields/tags_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/tags_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/text_field/edit_component.html.erb +5 -2
- data/app/components/avo/fields/text_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/text_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/textarea_field/edit_component.html.erb +6 -3
- data/app/components/avo/fields/textarea_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/trix_field/edit_component.html.erb +14 -4
- data/app/components/avo/fields/trix_field/edit_component.rb +3 -0
- data/app/components/avo/fields/trix_field/show_component.html.erb +2 -2
- data/app/components/avo/index/field_wrapper_component.html.erb +12 -5
- data/app/components/avo/index/field_wrapper_component.rb +27 -3
- data/app/components/avo/panel_component.rb +4 -3
- data/app/components/avo/resource_component.rb +1 -0
- data/app/components/avo/show/field_wrapper_component.html.erb +1 -1
- data/app/components/avo/show/field_wrapper_component.rb +2 -1
- data/app/components/avo/sidebar/item_switcher_component.html.erb +2 -2
- data/app/components/avo/views/resource_edit_component.html.erb +13 -8
- data/app/components/avo/views/resource_edit_component.rb +32 -3
- data/app/components/avo/views/resource_index_component.html.erb +7 -4
- data/app/components/avo/views/resource_index_component.rb +7 -1
- data/app/components/avo/views/resource_show_component.html.erb +11 -9
- data/app/components/avo/views/resource_show_component.rb +1 -0
- data/app/controllers/avo/actions_controller.rb +4 -1
- data/app/controllers/avo/base_controller.rb +24 -13
- data/app/controllers/avo/cards_controller.rb +25 -0
- data/app/controllers/avo/dashboards_controller.rb +2 -8
- data/app/controllers/avo/home_controller.rb +8 -1
- data/app/controllers/avo/search_controller.rb +7 -1
- data/app/helpers/avo/url_helpers.rb +8 -9
- data/app/javascript/js/controllers/fields/code_field_controller.js +7 -1
- data/app/javascript/js/controllers/fields/key_value_controller.js +1 -0
- data/app/javascript/js/controllers/fields/tags_field_controller.js +0 -1
- data/app/javascript/js/controllers/menu_controller.js +4 -3
- data/app/javascript/js/controllers/resource_edit_controller.js +72 -0
- data/app/javascript/js/controllers/resource_index_controller.js +4 -0
- data/app/javascript/js/controllers/resource_show_controller.js +4 -0
- data/app/javascript/js/controllers/search_controller.js +28 -5
- data/app/javascript/js/controllers.js +8 -0
- data/app/views/avo/associations/new.html.erb +2 -1
- data/app/views/avo/base/_select_filter.html.erb +1 -1
- data/app/views/avo/base/_text_filter.html.erb +1 -0
- data/app/views/avo/base/edit.html.erb +2 -1
- data/app/views/avo/base/new.html.erb +1 -1
- data/app/views/avo/{dashboards → cards}/_chartkick_card.html.erb +0 -0
- data/app/views/avo/{dashboards → cards}/_metric_card.html.erb +0 -0
- data/app/views/avo/{dashboards/card.html.erb → cards/show.html.erb} +0 -0
- data/app/views/avo/partials/_custom_tools_alert.html.erb +21 -7
- data/app/views/avo/partials/_logo.html.erb +3 -2
- data/app/views/avo/partials/_navbar.html.erb +1 -1
- data/app/views/avo/partials/_table_header.html.erb +9 -1
- data/bin/test +1 -0
- data/config/routes.rb +7 -4
- data/db/factories.rb +1 -0
- data/lib/avo/app.rb +18 -1
- data/lib/avo/base_action.rb +16 -4
- data/lib/avo/base_card.rb +0 -23
- data/lib/avo/base_resource.rb +23 -16
- data/lib/avo/concerns/fetches_things.rb +19 -12
- data/lib/avo/concerns/has_fields.rb +93 -0
- data/lib/avo/concerns/has_html_attributes.rb +110 -0
- data/lib/avo/concerns/has_model.rb +11 -0
- data/lib/avo/concerns/has_stimulus_controllers.rb +42 -0
- data/lib/avo/dynamic_router.rb +1 -1
- data/lib/avo/engine.rb +1 -3
- data/lib/avo/fields/base_field.rb +24 -13
- data/lib/avo/fields/concerns/is_required.rb +17 -0
- data/lib/avo/fields/select_field.rb +1 -1
- data/lib/avo/grid_collector.rb +4 -4
- data/lib/avo/hosts/view_record_host.rb +7 -0
- data/lib/avo/html/builder.rb +117 -0
- data/lib/avo/licensing/pro_license.rb +1 -0
- data/lib/avo/menu/base_item.rb +4 -0
- data/lib/avo/menu/dashboard.rb +5 -0
- data/lib/avo/menu/resource.rb +5 -0
- data/lib/avo/version.rb +1 -1
- data/lib/avo.rb +5 -0
- data/lib/generators/avo/install_generator.rb +1 -4
- data/lib/generators/avo/templates/cards/chartkick_card_sample.tt +11 -1
- data/lib/generators/avo/templates/cards/metric_card_sample.tt +11 -1
- data/lib/generators/avo/templates/field/components/edit_component.html.erb.tt +1 -1
- data/lib/generators/avo/templates/field/components/index_component.html.erb.tt +1 -1
- data/lib/generators/avo/templates/field/components/show_component.html.erb.tt +1 -1
- data/lib/generators/avo/templates/initializer/avo.tt +1 -1
- data/lib/generators/avo/templates/locales/avo.en.yml +3 -3
- data/public/avo-assets/avo.css +473 -1055
- data/public/avo-assets/avo.js +147 -147
- data/public/avo-assets/avo.js.map +3 -3
- data/public/avo-assets/logomark.png +0 -0
- metadata +21 -11
- data/app/components/avo/views/resource_new_component.html.erb +0 -55
- data/app/components/avo/views/resource_new_component.rb +0 -38
- data/lib/avo/fields_collector.rb +0 -70
|
@@ -11,13 +11,23 @@
|
|
|
11
11
|
data-hide-attachment-url="<%= @field.hide_attachment_url %>"
|
|
12
12
|
class="relative block overflow-x-auto max-w-full"
|
|
13
13
|
>
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
<%= content_tag 'trix-editor',
|
|
15
|
+
class: 'trix-content',
|
|
16
|
+
data: {
|
|
17
|
+
"trix-field-target": "editor",
|
|
18
|
+
**@field.get_html(:data, view: view, element: :input)
|
|
19
|
+
},
|
|
20
|
+
input: trix_id,
|
|
21
|
+
placeholder: @field.placeholder do %>
|
|
22
|
+
<%== @field.value %>
|
|
23
|
+
<% end %>
|
|
16
24
|
<%= @form.text_area @field.id,
|
|
25
|
+
class: classes("w-full hidden"),
|
|
26
|
+
data: @field.get_html(:data, view: view, element: :input),
|
|
27
|
+
disabled: @field.readonly,
|
|
17
28
|
id: trix_id,
|
|
18
|
-
class: helpers.input_classes('w-full hidden', has_error: (@resource.model.present? and @resource.model.errors.include?(@field.id))),
|
|
19
29
|
placeholder: @field.placeholder,
|
|
20
|
-
|
|
30
|
+
style: @field.get_html(:style, view: view, element: :input)
|
|
21
31
|
%>
|
|
22
32
|
</div>
|
|
23
33
|
<% end %>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<%= show_field_wrapper field: @field, index: @index do %>
|
|
1
|
+
<%= show_field_wrapper field: @field, resource: @resource, index: @index do %>
|
|
2
2
|
<%
|
|
3
|
-
content_classes = '
|
|
3
|
+
content_classes = 'trix-content py-2'
|
|
4
4
|
content_classes << ' hidden' unless @field.always_show
|
|
5
5
|
%>
|
|
6
6
|
<div data-controller="hidden-input">
|
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
<%= content_tag :td,
|
|
2
|
+
class: "min-h-[3rem] px-3 leading-tight whitespace-nowrap h-full text-slate-800 text-base #{classes}",
|
|
3
|
+
data: {
|
|
4
|
+
field_id: @field.id,
|
|
5
|
+
field_type: @field.type,
|
|
6
|
+
**stimulus_attributes
|
|
7
|
+
},
|
|
8
|
+
style: style do %>
|
|
2
9
|
<% if @field.value.blank? && @dash_if_blank %>
|
|
3
10
|
—
|
|
4
11
|
<% else %>
|
|
5
12
|
<% if @center_content %>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
13
|
+
<div class="flex items-center justify-center">
|
|
14
|
+
<%= content %>
|
|
15
|
+
</div>
|
|
9
16
|
<% else %>
|
|
10
17
|
<%= content %>
|
|
11
18
|
<% end %>
|
|
12
19
|
<% end %>
|
|
13
|
-
|
|
20
|
+
<% end %>
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Avo::Index::FieldWrapperComponent < ViewComponent::Base
|
|
4
|
-
|
|
4
|
+
attr_reader :view
|
|
5
|
+
|
|
6
|
+
def initialize(field: nil, resource: nil, dash_if_blank: true, center_content: false, flush: false, **args)
|
|
5
7
|
@field = field
|
|
8
|
+
@resource = resource
|
|
6
9
|
@dash_if_blank = dash_if_blank
|
|
7
10
|
@center_content = center_content
|
|
8
11
|
@classes = args[:class].present? ? args[:class] : ""
|
|
9
12
|
@args = args
|
|
10
13
|
@flush = flush
|
|
14
|
+
@view = :index
|
|
11
15
|
end
|
|
12
16
|
|
|
13
17
|
def classes
|
|
@@ -18,18 +22,38 @@ class Avo::Index::FieldWrapperComponent < ViewComponent::Base
|
|
|
18
22
|
end
|
|
19
23
|
|
|
20
24
|
result += " #{text_align_classes}"
|
|
25
|
+
result += " #{@field.get_html(:classes, view: view, element: :wrapper)}"
|
|
21
26
|
|
|
22
27
|
result
|
|
23
28
|
end
|
|
24
29
|
|
|
30
|
+
def style
|
|
31
|
+
@field.get_html(:style, view: view, element: :wrapper)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def stimulus_attributes
|
|
35
|
+
attributes = {}
|
|
36
|
+
|
|
37
|
+
@resource.get_stimulus_controllers.split(" ").each do |controller|
|
|
38
|
+
attributes["#{controller}-target"] = "#{@field.id.to_s.underscore}_#{@field.type.to_s.underscore}_wrapper".camelize(:lower)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
wrapper_data_attributes = @field.get_html :data, view: view, element: :wrapper
|
|
42
|
+
if wrapper_data_attributes.present?
|
|
43
|
+
attributes.merge! wrapper_data_attributes
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
attributes
|
|
47
|
+
end
|
|
48
|
+
|
|
25
49
|
private
|
|
26
50
|
|
|
27
51
|
def text_align_classes
|
|
28
52
|
case @field.index_text_align.to_sym
|
|
29
53
|
when :right
|
|
30
|
-
|
|
54
|
+
"text-right"
|
|
31
55
|
when :center
|
|
32
|
-
|
|
56
|
+
"text-center"
|
|
33
57
|
end
|
|
34
58
|
end
|
|
35
59
|
end
|
|
@@ -25,9 +25,10 @@ class Avo::PanelComponent < ViewComponent::Base
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def data_attributes
|
|
28
|
-
@data.merge({
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
@data.merge({"panel-index": @index})
|
|
29
|
+
.map do |key, value|
|
|
30
|
+
" data-#{key}=\"#{value}\""
|
|
31
|
+
end.join
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
def display_breadcrumbs?
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<%= render Avo::CommonFieldWrapperComponent.new(field: @field, dash_if_blank: @dash_if_blank, full_width: @full_width) do %>
|
|
1
|
+
<%= render Avo::CommonFieldWrapperComponent.new(field: @field, resource: @resource, dash_if_blank: @dash_if_blank, full_width: @full_width, view: :show) do %>
|
|
2
2
|
<div class="self-center <% if @full_width %> w-full <% else %> w-full md:w-8/12 <% end %>" data-slot="value">
|
|
3
3
|
<% if @field.value.blank? and @dash_if_blank %>
|
|
4
4
|
—
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
class Avo::Show::FieldWrapperComponent < ViewComponent::Base
|
|
4
|
-
def initialize(field: nil, dash_if_blank: true, full_width: false, **args)
|
|
4
|
+
def initialize(field: nil, resource: nil, dash_if_blank: true, full_width: false, **args)
|
|
5
5
|
@field = field
|
|
6
|
+
@resource = resource
|
|
6
7
|
@dash_if_blank = dash_if_blank
|
|
7
8
|
@classes = args[:class].present? ? args[:class] : ""
|
|
8
9
|
@args = args
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
<%= render Avo::Sidebar::LinkComponent.new label: item.name, path: item.path, target: item.target %>
|
|
3
3
|
<% end %>
|
|
4
4
|
<% if item.is_a? Avo::Menu::Resource %>
|
|
5
|
-
<%= render Avo::Sidebar::LinkComponent.new label:
|
|
5
|
+
<%= render Avo::Sidebar::LinkComponent.new label: item.navigation_label, path: helpers.resources_path(resource: resource) %>
|
|
6
6
|
<% end %>
|
|
7
7
|
<% if item.is_a? Avo::Menu::Dashboard %>
|
|
8
|
-
<%= render Avo::Sidebar::LinkComponent.new label:
|
|
8
|
+
<%= render Avo::Sidebar::LinkComponent.new label: item.navigation_label, path: dashboard.navigation_path %>
|
|
9
9
|
<% end %>
|
|
10
10
|
<% if item.is_a? Avo::Menu::Section %>
|
|
11
11
|
<%= render Avo::Sidebar::SectionComponent.new item: item %>
|
|
@@ -1,21 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
class
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
<%= content_tag :div,
|
|
2
|
+
class: "space-y-12",
|
|
3
|
+
data: {
|
|
4
|
+
'model-id': @resource.model.id,
|
|
5
|
+
selected_resources_name: @resource.model_key,
|
|
6
|
+
selected_resources: [@resource.model.id],
|
|
7
|
+
**@resource.stimulus_data_attributes
|
|
8
|
+
} do %>
|
|
9
|
+
<% @resource.panels.each_with_index do |resource_panel, index| %>
|
|
5
10
|
<%= form_with model: @resource.model,
|
|
6
11
|
scope: @resource.form_scope,
|
|
7
|
-
url:
|
|
8
|
-
method: :put,
|
|
12
|
+
url: form_url,
|
|
9
13
|
local: true,
|
|
10
14
|
multipart: true do |form| %>
|
|
11
15
|
<%= render Avo::ReferrerParamsComponent.new back_path: back_path %>
|
|
12
|
-
<%= render Avo::PanelComponent.new(title: resource_panel[:name], description: @resource.resource_description, display_breadcrumbs: true) do |c| %>
|
|
16
|
+
<%= render Avo::PanelComponent.new(title: resource_panel[:name], description: @resource.resource_description, display_breadcrumbs: true, index: index) do |c| %>
|
|
13
17
|
<% c.tools do %>
|
|
14
18
|
<%= a_link back_path,
|
|
15
19
|
style: :text,
|
|
16
20
|
icon: 'arrow-left' do %>
|
|
17
21
|
<%= t('avo.cancel').capitalize %>
|
|
18
22
|
<% end %>
|
|
23
|
+
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource, view: @view %>
|
|
19
24
|
<% if can_see_the_save_button? %>
|
|
20
25
|
<%= a_button color: :primary,
|
|
21
26
|
style: :primary,
|
|
@@ -70,4 +75,4 @@
|
|
|
70
75
|
<% end %>
|
|
71
76
|
<% end %>
|
|
72
77
|
<% end %>
|
|
73
|
-
|
|
78
|
+
<% end %>
|
|
@@ -4,8 +4,13 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
|
|
|
4
4
|
include Avo::ResourcesHelper
|
|
5
5
|
include Avo::ApplicationHelper
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
attr_reader :view
|
|
8
|
+
|
|
9
|
+
def initialize(resource: nil, model: nil, actions: [], view: :edit)
|
|
8
10
|
@resource = resource
|
|
11
|
+
@model = model
|
|
12
|
+
@actions = actions
|
|
13
|
+
@view = view
|
|
9
14
|
|
|
10
15
|
split_panel_fields
|
|
11
16
|
end
|
|
@@ -16,7 +21,11 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
|
|
|
16
21
|
elsif via_index?
|
|
17
22
|
helpers.resources_path(resource: @resource)
|
|
18
23
|
else # via resource show page
|
|
19
|
-
|
|
24
|
+
if is_edit?
|
|
25
|
+
helpers.resource_path(model: @resource.model, resource: @resource)
|
|
26
|
+
else
|
|
27
|
+
helpers.resources_path(resource: @resource)
|
|
28
|
+
end
|
|
20
29
|
end
|
|
21
30
|
end
|
|
22
31
|
|
|
@@ -29,6 +38,26 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
|
|
|
29
38
|
private
|
|
30
39
|
|
|
31
40
|
def via_index?
|
|
32
|
-
params[:via_view] ==
|
|
41
|
+
params[:via_view] == "index"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def is_edit?
|
|
45
|
+
view == :edit
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def form_url
|
|
49
|
+
if is_edit?
|
|
50
|
+
helpers.resource_path(
|
|
51
|
+
model: @resource.model,
|
|
52
|
+
resource: @resource
|
|
53
|
+
)
|
|
54
|
+
else
|
|
55
|
+
helpers.resources_path(
|
|
56
|
+
resource: @resource,
|
|
57
|
+
via_relation_class: params[:via_relation_class],
|
|
58
|
+
via_relation: params[:via_relation],
|
|
59
|
+
via_resource_id: params[:via_resource_id]
|
|
60
|
+
)
|
|
61
|
+
end
|
|
33
62
|
end
|
|
34
63
|
end
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
<%= content_tag :div,
|
|
2
|
+
data: {
|
|
3
|
+
**@resource.stimulus_data_attributes
|
|
4
|
+
} do %>
|
|
2
5
|
<%= render Avo::PanelComponent.new(title: title, description: description, data: { component: 'resources-index' }, display_breadcrumbs: @reflection.blank?) do |c| %>
|
|
3
6
|
<% c.tools do %>
|
|
4
7
|
<% if can_attach? %>
|
|
@@ -12,7 +15,7 @@
|
|
|
12
15
|
<% end %>
|
|
13
16
|
<% end %>
|
|
14
17
|
<% if can_see_the_actions_button? %>
|
|
15
|
-
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource %>
|
|
18
|
+
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource, view: @view %>
|
|
16
19
|
<% end %>
|
|
17
20
|
<% if can_see_the_create_button? %>
|
|
18
21
|
<%= a_link create_path,
|
|
@@ -31,7 +34,7 @@
|
|
|
31
34
|
>
|
|
32
35
|
<% if @resource.search_query.present? %>
|
|
33
36
|
<div class="flex items-center px-4 w-64">
|
|
34
|
-
<%= render partial: 'avo/partials/resource_search', locals: {resource: @resource.
|
|
37
|
+
<%= render partial: 'avo/partials/resource_search', locals: {resource: @resource.model_name.collection} %>
|
|
35
38
|
</div>
|
|
36
39
|
<% else %>
|
|
37
40
|
<%# Offset for the space-y-2 property when the serach is missing %>
|
|
@@ -72,4 +75,4 @@
|
|
|
72
75
|
<% end %>
|
|
73
76
|
<% end %>
|
|
74
77
|
<% end %>
|
|
75
|
-
|
|
78
|
+
<% end %>
|
|
@@ -28,11 +28,12 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
|
28
28
|
@turbo_frame = turbo_frame
|
|
29
29
|
@parent_model = parent_model
|
|
30
30
|
@applied_filters = applied_filters
|
|
31
|
+
@view = :index
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
def title
|
|
34
35
|
if @reflection.present?
|
|
35
|
-
return
|
|
36
|
+
return name if field.present?
|
|
36
37
|
|
|
37
38
|
reflection_resource.plural_name
|
|
38
39
|
else
|
|
@@ -143,4 +144,9 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
|
143
144
|
def reflection_model_class
|
|
144
145
|
@reflection.active_record.to_s
|
|
145
146
|
end
|
|
147
|
+
|
|
148
|
+
def name
|
|
149
|
+
field.custom_name? ? field.name : field.plural_name
|
|
150
|
+
end
|
|
151
|
+
|
|
146
152
|
end
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
data
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
<%= content_tag :div,
|
|
2
|
+
class: "space-y-12",
|
|
3
|
+
data: {
|
|
4
|
+
'model-id': @resource.model.id,
|
|
5
|
+
selected_resources_name: @resource.model_key,
|
|
6
|
+
selected_resources: [@resource.model.id],
|
|
7
|
+
**@resource.stimulus_data_attributes
|
|
8
|
+
} do %>
|
|
6
9
|
<% @resource.panels.each_with_index do |resource_panel, index| %>
|
|
7
10
|
<%= render Avo::PanelComponent.new(title: title, description: @resource.resource_description, display_breadcrumbs: @reflection.blank?, index: index) do |c| %>
|
|
8
11
|
<% c.tools do %>
|
|
@@ -19,7 +22,7 @@
|
|
|
19
22
|
} do %>
|
|
20
23
|
<%= t('avo.detach_item', item: title).capitalize %>
|
|
21
24
|
<% end %>
|
|
22
|
-
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource %>
|
|
25
|
+
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource, view: @view %>
|
|
23
26
|
<% end %>
|
|
24
27
|
<% if can_see_the_edit_button? %>
|
|
25
28
|
<%= a_link edit_path,
|
|
@@ -54,7 +57,7 @@
|
|
|
54
57
|
<%= t('avo.delete').capitalize %>
|
|
55
58
|
<% end %>
|
|
56
59
|
<% end %>
|
|
57
|
-
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource %>
|
|
60
|
+
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource, view: @view %>
|
|
58
61
|
<% if @resource.authorization.authorize_action(:edit, raise_exception: false) %>
|
|
59
62
|
<%= a_link edit_path,
|
|
60
63
|
color: :primary,
|
|
@@ -99,7 +102,6 @@
|
|
|
99
102
|
<% end %>
|
|
100
103
|
<% end %>
|
|
101
104
|
<% end %>
|
|
102
|
-
|
|
103
105
|
<% if should_display_invalid_fields_errors? %>
|
|
104
106
|
<turbo-stream action="append" target="alerts">
|
|
105
107
|
<template>
|
|
@@ -109,4 +111,4 @@
|
|
|
109
111
|
</template>
|
|
110
112
|
</turbo-stream>
|
|
111
113
|
<% end %>
|
|
112
|
-
|
|
114
|
+
<% end %>
|
|
@@ -75,10 +75,10 @@ module Avo
|
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
def show
|
|
78
|
-
set_actions
|
|
79
|
-
|
|
80
78
|
@resource.hydrate(model: @model, view: :show, user: _current_user, params: params)
|
|
81
79
|
|
|
80
|
+
set_actions
|
|
81
|
+
|
|
82
82
|
@page_title = @resource.default_panel_name.to_s
|
|
83
83
|
|
|
84
84
|
# If we're accessing this resource via another resource add the parent to the breadcrumbs.
|
|
@@ -101,8 +101,20 @@ module Avo
|
|
|
101
101
|
@model = @resource.model_class.new
|
|
102
102
|
@resource = @resource.hydrate(model: @model, view: :new, user: _current_user)
|
|
103
103
|
|
|
104
|
+
set_actions
|
|
105
|
+
|
|
104
106
|
@page_title = @resource.default_panel_name.to_s
|
|
105
|
-
|
|
107
|
+
|
|
108
|
+
if params[:via_relation_class].present? && params[:via_resource_id].present?
|
|
109
|
+
via_resource = Avo::App.get_resource_by_model_name params[:via_relation_class]
|
|
110
|
+
via_model = via_resource.class.find_scope.find params[:via_resource_id]
|
|
111
|
+
via_resource.hydrate model: via_model
|
|
112
|
+
|
|
113
|
+
add_breadcrumb via_resource.plural_name, resources_path(resource: via_resource)
|
|
114
|
+
add_breadcrumb via_resource.model_title, resource_path(model: via_model, resource: via_resource)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
add_breadcrumb @resource.plural_name.humanize
|
|
106
118
|
add_breadcrumb t("avo.new").humanize
|
|
107
119
|
end
|
|
108
120
|
|
|
@@ -151,6 +163,7 @@ module Avo
|
|
|
151
163
|
end
|
|
152
164
|
|
|
153
165
|
def edit
|
|
166
|
+
set_actions
|
|
154
167
|
end
|
|
155
168
|
|
|
156
169
|
def update
|
|
@@ -302,14 +315,10 @@ module Avo
|
|
|
302
315
|
end
|
|
303
316
|
|
|
304
317
|
def set_actions
|
|
305
|
-
if params[:resource_id].present?
|
|
306
|
-
model = @resource.class.find_scope.find params[:resource_id]
|
|
307
|
-
end
|
|
308
|
-
|
|
309
318
|
@actions = @resource
|
|
310
319
|
.get_actions
|
|
311
320
|
.map do |action|
|
|
312
|
-
action.new(model: model, resource: @resource, view: @view)
|
|
321
|
+
action.new(model: @model, resource: @resource, view: @view)
|
|
313
322
|
end
|
|
314
323
|
.select { |action| action.visible_in_view }
|
|
315
324
|
end
|
|
@@ -385,20 +394,22 @@ module Avo
|
|
|
385
394
|
return resource_path(model: params[:via_relation_class].safe_constantize, resource: parent_resource, resource_id: params[:via_resource_id])
|
|
386
395
|
end
|
|
387
396
|
|
|
388
|
-
redirect_path_from_resource_option || resource_path(model: @model, resource: @resource)
|
|
397
|
+
redirect_path_from_resource_option(:after_create_path) || resource_path(model: @model, resource: @resource)
|
|
389
398
|
end
|
|
390
399
|
|
|
391
400
|
def after_update_path
|
|
392
401
|
return params[:referrer] if params[:referrer].present?
|
|
393
402
|
|
|
394
|
-
redirect_path_from_resource_option || resource_path(model: @model, resource: @resource)
|
|
403
|
+
redirect_path_from_resource_option(:after_update_path) || resource_path(model: @model, resource: @resource)
|
|
395
404
|
end
|
|
396
405
|
|
|
397
|
-
def redirect_path_from_resource_option
|
|
398
|
-
return nil if @resource.class.
|
|
406
|
+
def redirect_path_from_resource_option(action = :after_update_path)
|
|
407
|
+
return nil if @resource.class.send(action).blank?
|
|
399
408
|
|
|
400
|
-
if @resource.class.
|
|
409
|
+
if @resource.class.send(action) == :index
|
|
401
410
|
resources_path(resource: @resource)
|
|
411
|
+
elsif @resource.class.send(action) == :edit
|
|
412
|
+
edit_resource_path(resource: @resource, model: @resource.model)
|
|
402
413
|
else
|
|
403
414
|
resource_path(model: @model, resource: @resource)
|
|
404
415
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require_dependency "avo/application_controller"
|
|
2
|
+
|
|
3
|
+
module Avo
|
|
4
|
+
class CardsController < ApplicationController
|
|
5
|
+
before_action :set_dashboard, only: :show
|
|
6
|
+
before_action :set_card, only: :show
|
|
7
|
+
|
|
8
|
+
def show
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def set_dashboard
|
|
14
|
+
@dashboard = Avo::App.get_dashboard_by_id params[:dashboard_id]
|
|
15
|
+
|
|
16
|
+
raise ActionController::RoutingError.new("Not Found") if @dashboard.nil? || @dashboard.is_hidden?
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def set_card
|
|
20
|
+
@card = @dashboard.item_at_index(params[:index].to_i).tap do |card|
|
|
21
|
+
card.hydrate(dashboard: @dashboard, params: params)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -2,21 +2,15 @@ require_dependency "avo/application_controller"
|
|
|
2
2
|
|
|
3
3
|
module Avo
|
|
4
4
|
class DashboardsController < ApplicationController
|
|
5
|
-
before_action :set_dashboard
|
|
5
|
+
before_action :set_dashboard, only: :show
|
|
6
6
|
|
|
7
7
|
def show
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
def card
|
|
11
|
-
@card = @dashboard.item_at_index(params[:index].to_i).tap do |card|
|
|
12
|
-
card.hydrate(dashboard: @dashboard, params: params)
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
10
|
private
|
|
17
11
|
|
|
18
12
|
def set_dashboard
|
|
19
|
-
@dashboard = Avo::App.get_dashboard_by_id params[:
|
|
13
|
+
@dashboard = Avo::App.get_dashboard_by_id params[:id]
|
|
20
14
|
|
|
21
15
|
raise ActionController::RoutingError.new("Not Found") if @dashboard.nil? || @dashboard.is_hidden?
|
|
22
16
|
end
|
|
@@ -4,7 +4,14 @@ module Avo
|
|
|
4
4
|
class HomeController < ApplicationController
|
|
5
5
|
def index
|
|
6
6
|
if Avo.configuration.home_path.present?
|
|
7
|
-
|
|
7
|
+
# If the home_path is a block run it, if not, just use it
|
|
8
|
+
computed_path = if Avo.configuration.home_path.respond_to? :call
|
|
9
|
+
instance_exec(&Avo.configuration.home_path)
|
|
10
|
+
else
|
|
11
|
+
Avo.configuration.home_path
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
redirect_to computed_path
|
|
8
15
|
elsif !Rails.env.development?
|
|
9
16
|
@page_title = "Get started"
|
|
10
17
|
resource = Avo::App.resources.min_by { |resource| resource.model_key }
|
|
@@ -51,8 +51,14 @@ module Avo
|
|
|
51
51
|
|
|
52
52
|
results = apply_search_metadata(query, resource)
|
|
53
53
|
|
|
54
|
+
header = resource.plural_name
|
|
55
|
+
|
|
56
|
+
if results.length > 0
|
|
57
|
+
header += " (#{results.length})"
|
|
58
|
+
end
|
|
59
|
+
|
|
54
60
|
result_object = {
|
|
55
|
-
header:
|
|
61
|
+
header: header,
|
|
56
62
|
help: resource.class.search_query_help,
|
|
57
63
|
results: results,
|
|
58
64
|
count: results.length
|
|
@@ -12,10 +12,9 @@ module Avo
|
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
# Add the `_index` suffix for the uncountable
|
|
17
|
-
route_key
|
|
18
|
-
route_key << "_index" if resource.model_name.singular == resource.model_name.plural
|
|
15
|
+
route_key = resource.route_key
|
|
16
|
+
# Add the `_index` suffix for the uncountable names so they get the correct path (`fish_index`)
|
|
17
|
+
route_key << "_index" if resource.route_key == resource.singular_route_key
|
|
19
18
|
|
|
20
19
|
avo.send :"resources_#{route_key}_path", **existing_params, **args
|
|
21
20
|
end
|
|
@@ -33,19 +32,19 @@ module Avo
|
|
|
33
32
|
id = resource_id
|
|
34
33
|
end
|
|
35
34
|
|
|
36
|
-
avo.send :"resources_#{resource.
|
|
35
|
+
avo.send :"resources_#{resource.singular_route_key}_path", id, **args
|
|
37
36
|
end
|
|
38
37
|
|
|
39
38
|
def new_resource_path(model:, resource:, **args)
|
|
40
|
-
avo.send :"new_resources_#{resource.
|
|
39
|
+
avo.send :"new_resources_#{resource.singular_route_key}_path", **args
|
|
41
40
|
end
|
|
42
41
|
|
|
43
42
|
def edit_resource_path(model:, resource:, **args)
|
|
44
|
-
avo.send :"edit_resources_#{resource.
|
|
43
|
+
avo.send :"edit_resources_#{resource.singular_route_key}_path", model, **args
|
|
45
44
|
end
|
|
46
45
|
|
|
47
46
|
def resource_attach_path(resource, model_id, related_name, related_id = nil)
|
|
48
|
-
helpers.avo.resources_associations_new_path(resource.
|
|
47
|
+
helpers.avo.resources_associations_new_path(resource.singular_route_key, model_id, related_name)
|
|
49
48
|
end
|
|
50
49
|
|
|
51
50
|
def resource_detach_path(
|
|
@@ -79,7 +78,7 @@ module Avo
|
|
|
79
78
|
end
|
|
80
79
|
|
|
81
80
|
def order_up_resource_path(model:, resource:, **args)
|
|
82
|
-
avo.send :"order_up_resources_#{resource.
|
|
81
|
+
avo.send :"order_up_resources_#{resource.singular_route_key}_path", model, **args
|
|
83
82
|
end
|
|
84
83
|
end
|
|
85
84
|
end
|
|
@@ -32,8 +32,14 @@ export default class extends Controller {
|
|
|
32
32
|
lineNumbers: true,
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
const vm = this
|
|
36
|
+
|
|
35
37
|
setTimeout(() => {
|
|
36
|
-
CodeMirror.fromTextArea(this.elementTarget, options)
|
|
38
|
+
CodeMirror.fromTextArea(this.elementTarget, options).on('change', (cm) => {
|
|
39
|
+
// Add this innerText change and dispatch an event to allow stimulus to pick up the input event.
|
|
40
|
+
vm.elementTarget.innerText = cm.getValue()
|
|
41
|
+
vm.elementTarget.dispatchEvent(new Event('input'))
|
|
42
|
+
})
|
|
37
43
|
}, 1)
|
|
38
44
|
}
|
|
39
45
|
}
|
|
@@ -72,6 +72,7 @@ export default class extends Controller {
|
|
|
72
72
|
result = Object.assign(...this.fieldValue.map(([key, val]) => ({ [key]: val })))
|
|
73
73
|
}
|
|
74
74
|
this.inputTarget.innerText = JSON.stringify(result)
|
|
75
|
+
this.inputTarget.dispatchEvent(new Event('input'))
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
updateKeyValueComponent() {
|