avo 2.13.2.pre.2 → 2.13.3.pre.3
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.lock +5 -3
- data/app/assets/stylesheets/avo.css +1 -1
- data/app/assets/stylesheets/css/fields/progress.css +3 -3
- data/app/assets/stylesheets/css/pagination.css +4 -0
- data/app/assets/stylesheets/css/search.css +1 -1
- data/app/assets/stylesheets/css/sidebar.css +1 -1
- data/app/assets/stylesheets/css/tags.css +0 -7
- data/app/assets/svgs/arrow-circle-right.svg +1 -1
- data/app/assets/svgs/arrow-down.svg +1 -1
- data/app/assets/svgs/arrow-up.svg +1 -1
- data/app/assets/svgs/bell.svg +1 -1
- data/app/assets/svgs/chevron-right.svg +1 -1
- data/app/assets/svgs/exclamation.svg +1 -1
- data/app/assets/svgs/failed_to_load.svg +5 -4
- data/app/assets/svgs/grid-empty-state.svg +11 -10
- data/app/assets/svgs/information-circle.svg +1 -1
- data/app/assets/svgs/logout.svg +1 -1
- data/app/assets/svgs/menu.svg +1 -1
- data/app/assets/svgs/play.svg +1 -1
- data/app/assets/svgs/switch-vertical.svg +1 -1
- data/app/assets/svgs/table-empty-state.svg +12 -11
- data/app/assets/svgs/user-circle.svg +1 -1
- data/app/assets/svgs/x.svg +1 -1
- data/app/components/avo/actions_component.html.erb +2 -2
- data/app/components/avo/actions_component.rb +1 -1
- data/app/components/avo/button_component.html.erb +1 -0
- data/app/components/avo/button_component.rb +3 -3
- data/app/components/avo/card_component.html.erb +12 -11
- data/app/components/avo/common_field_wrapper_component.html.erb +1 -1
- data/app/components/avo/fields/belongs_to_field/edit_component.rb +1 -1
- data/app/components/avo/fields/boolean_field/edit_component.html.erb +2 -2
- data/app/components/avo/fields/boolean_group_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/code_field/edit_component.html.erb +2 -2
- data/app/components/avo/fields/country_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/date_field/edit_component.html.erb +2 -2
- data/app/components/avo/fields/date_time_field/edit_component.html.erb +2 -2
- data/app/components/avo/fields/external_image_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/file_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/files_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/has_one_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/markdown_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/markdown_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/number_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/password_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/progress_bar_field/edit_component.html.erb +1 -1
- 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 +1 -1
- data/app/components/avo/fields/status_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/tags_field/edit_component.html.erb +3 -3
- data/app/components/avo/fields/tags_field/show_component.rb +0 -2
- data/app/components/avo/fields/text_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/textarea_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/trix_field/edit_component.html.erb +1 -1
- data/app/components/avo/profile_item_component.html.erb +1 -1
- data/app/components/avo/resource_component.rb +23 -0
- data/app/components/avo/tab_group_component.html.erb +1 -1
- data/app/components/avo/tab_switcher_component.rb +2 -2
- data/app/components/avo/views/resource_edit_component.html.erb +3 -1
- data/app/components/avo/views/resource_edit_component.rb +1 -1
- data/app/components/avo/views/resource_index_component.html.erb +2 -2
- data/app/components/avo/views/resource_index_component.rb +17 -23
- data/app/components/avo/views/resource_show_component.html.erb +7 -4
- data/app/components/avo/views/resource_show_component.rb +8 -0
- data/app/controllers/avo/base_controller.rb +87 -33
- data/app/controllers/avo/search_controller.rb +57 -20
- data/app/helpers/avo/actions_helper.rb +4 -0
- data/app/helpers/avo/application_helper.rb +36 -44
- data/app/helpers/avo/attachments_helper.rb +4 -0
- data/app/helpers/avo/resources_helper.rb +2 -2
- data/app/javascript/avo.js +1 -0
- data/app/javascript/js/controllers/fields/trix_field_controller.js +3 -4
- data/app/javascript/js/controllers/item_selector_controller.js +1 -1
- data/app/javascript/js/controllers/menu_controller.js +2 -2
- data/app/javascript/js/controllers/search_controller.js +42 -15
- data/app/views/avo/associations/new.html.erb +3 -2
- data/app/views/avo/base/_multiple_select_filter.html.erb +1 -1
- data/app/views/avo/base/_text_filter.html.erb +1 -1
- data/app/views/avo/partials/_header.html.erb +1 -1
- data/app/views/avo/partials/_logo.html.erb +2 -2
- data/app/views/avo/partials/_resource_search.html.erb +6 -0
- data/app/views/avo/private/_links_and_buttons.html.erb +1 -1
- data/app/views/avo/private/design.html.erb +3 -3
- data/app/views/kaminari/_first_page.html.erb +3 -0
- data/app/views/kaminari/_last_page.html.erb +3 -0
- data/app/views/kaminari/_next_page.html.erb +9 -0
- data/app/views/kaminari/_page.html.erb +12 -0
- data/app/views/kaminari/_prev_page.html.erb +9 -0
- data/app/views/layouts/avo/application.html.erb +1 -1
- data/avo.gemspec +1 -0
- data/lib/avo/concerns/has_editable_controls.rb +1 -1
- data/lib/avo/configuration.rb +0 -5
- data/lib/avo/dashboards/chartkick_card.rb +1 -1
- data/lib/avo/engine.rb +3 -0
- data/lib/avo/fields/base_field.rb +2 -1
- data/lib/avo/fields/concerns/is_readonly.rb +17 -0
- data/lib/avo/fields/has_base_field.rb +2 -0
- data/lib/avo/hosts/search_scope_host.rb +7 -0
- data/lib/avo/licensing/pro_license.rb +0 -1
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/templates/field/components/edit_component.html.erb.tt +1 -1
- data/lib/generators/avo/templates/initializer/avo.tt +1 -15
- data/lib/generators/avo/templates/resource/resource.tt +1 -1
- data/public/avo-assets/avo.css +248 -286
- data/public/avo-assets/avo.js +47 -47
- data/public/avo-assets/avo.js.map +2 -2
- metadata +25 -3
- data/app/views/avo/partials/_branding.html.erb +0 -5
- data/lib/avo/configuration/branding.rb +0 -65
@@ -2,7 +2,7 @@
|
|
2
2
|
<%= @form.password_field @field.id,
|
3
3
|
class: classes("w-full"),
|
4
4
|
data: @field.get_html(:data, view: view, element: :input),
|
5
|
-
disabled: @field.
|
5
|
+
disabled: @field.is_readonly?,
|
6
6
|
placeholder: @field.placeholder,
|
7
7
|
style: @field.get_html(:style, view: view, element: :input)
|
8
8
|
%>
|
@@ -7,7 +7,7 @@
|
|
7
7
|
<%= @form.range_field @field.id,
|
8
8
|
class: "w-full #{@field.get_html(:classes, view: view, element: :input)}",
|
9
9
|
data: @field.get_html(:data, view: view, element: :input),
|
10
|
-
disabled: @field.
|
10
|
+
disabled: @field.is_readonly?,
|
11
11
|
max: @field.max,
|
12
12
|
min: 0,
|
13
13
|
placeholder: @field.placeholder,
|
@@ -4,5 +4,5 @@
|
|
4
4
|
<%= @field.value %><%= @field.value_suffix if @field.value_suffix.present? %>
|
5
5
|
</div>
|
6
6
|
<% end %>
|
7
|
-
<progress min="0" max="<%= @field.max %>" value="<%= @field.value %>" class="block w-
|
7
|
+
<progress min="0" max="<%= @field.max %>" value="<%= @field.value %>" class="block w-24"></progress>
|
8
8
|
<% end %>
|
@@ -4,5 +4,5 @@
|
|
4
4
|
<%= @field.value %><%= @field.value_suffix if @field.value_suffix.present? %>
|
5
5
|
</div>
|
6
6
|
<% end %>
|
7
|
-
<progress min="0" max="<%= @field.max %>" value="<%= @field.value %>" class="block
|
7
|
+
<progress min="0" max="<%= @field.max %>" value="<%= @field.value %>" class="block w-full"></progress>
|
8
8
|
<% end %>
|
@@ -8,7 +8,7 @@
|
|
8
8
|
},
|
9
9
|
class: classes("w-full"),
|
10
10
|
data: @field.get_html(:data, view: view, element: :input),
|
11
|
-
disabled: @field.
|
11
|
+
disabled: @field.is_readonly?,
|
12
12
|
style: @field.get_html(:style, view: view, element: :input),
|
13
13
|
value: @field.model.present? ? @field.model[@field.id] : @field.value,
|
14
14
|
placeholder: @field.include_blank.present? ? nil : @field.placeholder
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<%= @form.text_field @field.id,
|
3
3
|
class: classes("w-full"),
|
4
4
|
data: @field.get_html(:data, view: view, element: :input),
|
5
|
-
disabled: @field.
|
5
|
+
disabled: @field.is_readonly?,
|
6
6
|
placeholder: @field.placeholder,
|
7
7
|
style: @field.get_html(:style, view: view, element: :input),
|
8
8
|
value: @resource.model.present? ? @resource.model[@field.id] : @field.value
|
@@ -10,14 +10,14 @@
|
|
10
10
|
data: {
|
11
11
|
'tags-field-target': 'fakeInput',
|
12
12
|
},
|
13
|
-
disabled: @field.
|
13
|
+
disabled: @field.is_readonly?,
|
14
14
|
placeholder: @field.placeholder,
|
15
15
|
style: @field.get_html(:style, view: view, element: :input),
|
16
16
|
value: ''
|
17
17
|
%>
|
18
18
|
<%# real field %>
|
19
19
|
<%= @form.text_field @field.id,
|
20
|
-
class: classes("hidden w-full
|
20
|
+
class: classes("hidden w-full"),
|
21
21
|
data: {
|
22
22
|
'tags-field-target': 'input',
|
23
23
|
'whitelist-items': @field.suggestions.to_json,
|
@@ -26,7 +26,7 @@
|
|
26
26
|
'delimiters': @field.delimiters,
|
27
27
|
'close-on-select': @field.close_on_select ? 1 : 0,
|
28
28
|
},
|
29
|
-
disabled: @field.
|
29
|
+
disabled: @field.is_readonly?,
|
30
30
|
placeholder: @field.placeholder,
|
31
31
|
style: @field.get_html(:style, view: view, element: :input),
|
32
32
|
value: @field.field_value.to_json
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<%= @form.text_field @field.id,
|
3
3
|
class: classes("w-full"),
|
4
4
|
data: @field.get_html(:data, view: view, element: :input),
|
5
|
-
disabled: @field.
|
5
|
+
disabled: @field.is_readonly?,
|
6
6
|
placeholder: @field.placeholder,
|
7
7
|
style: @field.get_html(:style, view: view, element: :input)
|
8
8
|
%>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<%= @form.text_area @field.id,
|
3
3
|
class: classes("w-full"),
|
4
4
|
data: @field.get_html(:data, view: view, element: :input),
|
5
|
-
disabled: @field.
|
5
|
+
disabled: @field.is_readonly?,
|
6
6
|
placeholder: @field.placeholder,
|
7
7
|
rows: @field.rows,
|
8
8
|
style: @field.get_html(:style, view: view, element: :input)
|
@@ -24,7 +24,7 @@
|
|
24
24
|
<%= @form.text_area @field.id,
|
25
25
|
class: classes("w-full hidden"),
|
26
26
|
data: @field.get_html(:data, view: view, element: :input),
|
27
|
-
disabled: @field.
|
27
|
+
disabled: @field.is_readonly?,
|
28
28
|
id: trix_id,
|
29
29
|
placeholder: @field.placeholder,
|
30
30
|
style: @field.get_html(:style, view: view, element: :input)
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<%= link_to path, class: "flex-1 flex items-center justify-center bg-white text-left cursor-pointer text-gray-800 font-semibold hover:bg-
|
1
|
+
<%= link_to path, class: "flex-1 flex items-center justify-center bg-white text-left cursor-pointer text-gray-800 font-semibold hover:bg-blue-100 block px-4 py-1 w-full py-3 text-center rounded w-full", target: target, title: title do %>
|
2
2
|
<%= helpers.svg(icon, class: 'h-4 mr-1') if icon.present? %> <%= label %>
|
3
3
|
<% end %>
|
@@ -36,6 +36,14 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
36
36
|
@resource.authorization.authorize_action(:destroy, raise_exception: false)
|
37
37
|
end
|
38
38
|
|
39
|
+
def can_see_the_actions_button?
|
40
|
+
return false if @actions.blank?
|
41
|
+
|
42
|
+
return authorize_association_for(:act_on) if @reflection.present?
|
43
|
+
|
44
|
+
@resource.authorization.authorize_action(:act_on, raise_exception: false) && !has_reflection_and_is_read_only
|
45
|
+
end
|
46
|
+
|
39
47
|
def destroy_path
|
40
48
|
helpers.resource_path(model: @resource.model, resource: @resource)
|
41
49
|
end
|
@@ -72,6 +80,21 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
72
80
|
end
|
73
81
|
end
|
74
82
|
|
83
|
+
def has_reflection_and_is_read_only
|
84
|
+
if @reflection.present? && @reflection.active_record.name && @reflection.name
|
85
|
+
fields = ::Avo::App.get_resource_by_model_name(@reflection.active_record.name).get_field_definitions
|
86
|
+
filtered_fields = fields.filter { |f| f.id == @reflection.name }
|
87
|
+
else
|
88
|
+
return false
|
89
|
+
end
|
90
|
+
|
91
|
+
if filtered_fields.present?
|
92
|
+
filtered_fields.find { |f| f.id == @reflection.name }.readonly
|
93
|
+
else
|
94
|
+
false
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
75
98
|
private
|
76
99
|
|
77
100
|
def via_resource?
|
@@ -25,7 +25,7 @@
|
|
25
25
|
# On edit screens we want to load each tab because we wnst the DOM to have the fields present on form submission.
|
26
26
|
# If you have a field which is in the second tab and it's required, the form submission will fail because the required field is not in view, and we don't want that.
|
27
27
|
# We also want to load the current tab
|
28
|
-
should_lazy_load = if @view.to_s.in?(['edit', 'new'])
|
28
|
+
should_lazy_load = if @view.to_s.in?(['edit', 'new', 'update', 'create'])
|
29
29
|
false
|
30
30
|
else
|
31
31
|
!is_current_tab
|
@@ -22,7 +22,9 @@
|
|
22
22
|
icon: 'arrow-left' do %>
|
23
23
|
<%= t('avo.cancel').capitalize %>
|
24
24
|
<% end %>
|
25
|
-
|
25
|
+
<% if can_see_the_actions_button? %>
|
26
|
+
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource, view: @view %>
|
27
|
+
<% end %>
|
26
28
|
<% if can_see_the_save_button? %>
|
27
29
|
<%= a_button color: :primary,
|
28
30
|
style: :primary,
|
@@ -32,9 +32,9 @@
|
|
32
32
|
data-selected-resources-name="<%= @resource.model_key %>"
|
33
33
|
data-selected-resources="[]"
|
34
34
|
>
|
35
|
-
<%
|
35
|
+
<% unless hide_search_input %>
|
36
36
|
<div class="flex items-center px-4 w-64">
|
37
|
-
<%= render partial: 'avo/partials/resource_search', locals: {resource: @resource.route_key} %>
|
37
|
+
<%= render partial: 'avo/partials/resource_search', locals: {resource: @resource.route_key, via_reflection: via_reflection} %>
|
38
38
|
</div>
|
39
39
|
<% else %>
|
40
40
|
<%# Offset for the space-y-2 property when the search is missing %>
|
@@ -59,14 +59,6 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
59
59
|
@resource.authorization.authorize_action(:new, raise_exception: false) && !has_reflection_and_is_read_only
|
60
60
|
end
|
61
61
|
|
62
|
-
def can_see_the_actions_button?
|
63
|
-
return false if @actions.blank?
|
64
|
-
|
65
|
-
return authorize_association_for(:act_on) if @reflection.present?
|
66
|
-
|
67
|
-
@resource.authorization.authorize_action(:act_on, raise_exception: false) && !has_reflection_and_is_read_only
|
68
|
-
end
|
69
|
-
|
70
62
|
def can_attach?
|
71
63
|
klass = @reflection
|
72
64
|
klass = @reflection.through_reflection if klass.is_a? ::ActiveRecord::Reflection::ThroughReflection
|
@@ -74,21 +66,6 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
74
66
|
@reflection.present? && klass.is_a?(::ActiveRecord::Reflection::HasManyReflection) && !has_reflection_and_is_read_only && authorize_association_for(:attach)
|
75
67
|
end
|
76
68
|
|
77
|
-
def has_reflection_and_is_read_only
|
78
|
-
if @reflection.present? && @reflection.active_record.name && @reflection.name
|
79
|
-
fields = ::Avo::App.get_resource_by_model_name(@reflection.active_record.name).get_field_definitions
|
80
|
-
filtered_fields = fields.filter { |f| f.id == @reflection.name }
|
81
|
-
else
|
82
|
-
return false
|
83
|
-
end
|
84
|
-
|
85
|
-
if filtered_fields.present?
|
86
|
-
filtered_fields.find { |f| f.id == @reflection.name }.readonly
|
87
|
-
else
|
88
|
-
false
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
69
|
def create_path
|
93
70
|
args = {}
|
94
71
|
|
@@ -143,6 +120,12 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
143
120
|
@resource.resource_description
|
144
121
|
end
|
145
122
|
|
123
|
+
def hide_search_input
|
124
|
+
return true unless @resource.search_query.present?
|
125
|
+
|
126
|
+
field&.hide_search_input || false
|
127
|
+
end
|
128
|
+
|
146
129
|
private
|
147
130
|
|
148
131
|
def reflection_model_class
|
@@ -153,4 +136,15 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
153
136
|
field.custom_name? ? field.name : field.plural_name
|
154
137
|
end
|
155
138
|
|
139
|
+
def via_reflection
|
140
|
+
return unless @reflection.present?
|
141
|
+
|
142
|
+
{
|
143
|
+
association: 'has_many',
|
144
|
+
association_id: @reflection.name,
|
145
|
+
class: reflection_model_class,
|
146
|
+
id: @parent_model.id
|
147
|
+
}
|
148
|
+
end
|
149
|
+
|
156
150
|
end
|
@@ -36,9 +36,10 @@
|
|
36
36
|
tippy: control.title ? :tooltip : nil,
|
37
37
|
'resource-id': @resource.model.id,
|
38
38
|
} do %>
|
39
|
+
<%= control.label %>
|
39
40
|
<% end %>
|
40
41
|
<% end %>
|
41
|
-
<% elsif control.actions_list? %>
|
42
|
+
<% elsif can_see_the_actions_button? && control.actions_list? %>
|
42
43
|
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource, view: @view, exclude: control.exclude, style: control.style, color: control.color %>
|
43
44
|
<% elsif control.edit_button? %>
|
44
45
|
<% if @resource.authorization.authorize_action(:edit, raise_exception: false) %>
|
@@ -90,7 +91,7 @@
|
|
90
91
|
data: {
|
91
92
|
confirm: "Are you sure you want to detach this #{title}."
|
92
93
|
} do %>
|
93
|
-
<%=
|
94
|
+
<%= control.label %>
|
94
95
|
<% end %>
|
95
96
|
<% end %>
|
96
97
|
<% end %>
|
@@ -125,7 +126,7 @@
|
|
125
126
|
<%= t('avo.go_back') %>
|
126
127
|
<% end %>
|
127
128
|
<% if can_see_the_destroy_button? %>
|
128
|
-
<%= a_button url:
|
129
|
+
<%= a_button url: destroy_path,
|
129
130
|
method: :delete,
|
130
131
|
local: true,
|
131
132
|
style: :text,
|
@@ -141,7 +142,9 @@
|
|
141
142
|
<%= t('avo.delete').capitalize %>
|
142
143
|
<% end %>
|
143
144
|
<% end %>
|
144
|
-
|
145
|
+
<% if can_see_the_actions_button? %>
|
146
|
+
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource, view: @view %>
|
147
|
+
<% end %>
|
145
148
|
<% if @resource.authorization.authorize_action(:edit, raise_exception: false) %>
|
146
149
|
<%= a_link edit_path,
|
147
150
|
color: :primary,
|
@@ -45,6 +45,14 @@ class Avo::Views::ResourceShowComponent < Avo::ResourceComponent
|
|
45
45
|
helpers.edit_resource_path(model: @resource.model, resource: @resource, **args)
|
46
46
|
end
|
47
47
|
|
48
|
+
def destroy_path
|
49
|
+
if params[:via_resource_class].present?
|
50
|
+
helpers.resource_path(model: @resource.model, resource: @resource, referrer: back_path)
|
51
|
+
else
|
52
|
+
helpers.resource_path(model: @resource.model, resource: @resource)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
48
56
|
private
|
49
57
|
|
50
58
|
# In development and test environments we shoudl show the invalid field errors
|
@@ -115,7 +115,7 @@ module Avo
|
|
115
115
|
add_breadcrumb via_resource.model_title, resource_path(model: via_model, resource: via_resource)
|
116
116
|
end
|
117
117
|
|
118
|
-
add_breadcrumb @resource.plural_name.humanize
|
118
|
+
add_breadcrumb @resource.plural_name.humanize, resources_path(resource: @resource)
|
119
119
|
add_breadcrumb t("avo.new").humanize
|
120
120
|
end
|
121
121
|
|
@@ -129,21 +129,14 @@ module Avo
|
|
129
129
|
@reflection = @model._reflections[params[:via_relation]]
|
130
130
|
# Figure out what kind of association does the record have with the parent record
|
131
131
|
|
132
|
-
# belongs_to
|
133
|
-
# has_many
|
132
|
+
# Fills in the required infor for belongs_to and has_many
|
134
133
|
# Get the foreign key and set it to the id we received in the params
|
135
134
|
if @reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection) || @reflection.is_a?(ActiveRecord::Reflection::HasManyReflection)
|
136
|
-
|
137
|
-
@model.send("#{foreign_key}=", params[:via_resource_id])
|
135
|
+
@model.send("#{@reflection.foreign_key}=", params[:via_resource_id])
|
138
136
|
@model.save
|
139
137
|
end
|
140
138
|
|
141
|
-
# has_one
|
142
|
-
# has_one_through
|
143
|
-
|
144
|
-
# has_many_through
|
145
|
-
# has_and_belongs_to_many
|
146
|
-
# polymorphic
|
139
|
+
# For when working with has_one, has_one_through, has_many_through, has_and_belongs_to_many, polymorphic
|
147
140
|
if @reflection.is_a? ActiveRecord::Reflection::ThroughReflection
|
148
141
|
# find the record
|
149
142
|
via_resource = ::Avo::App.get_resource_by_model_name params[:via_relation_class]
|
@@ -153,13 +146,14 @@ module Avo
|
|
153
146
|
end
|
154
147
|
end
|
155
148
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
149
|
+
add_breadcrumb @resource.plural_name.humanize, resources_path(resource: @resource)
|
150
|
+
add_breadcrumb t("avo.new").humanize
|
151
|
+
set_actions
|
152
|
+
|
153
|
+
if saved
|
154
|
+
create_success_action
|
155
|
+
else
|
156
|
+
create_fail_action
|
163
157
|
end
|
164
158
|
end
|
165
159
|
|
@@ -171,26 +165,20 @@ module Avo
|
|
171
165
|
# model gets instantiated and filled in the fill_model method
|
172
166
|
saved = save_model
|
173
167
|
@resource = @resource.hydrate(model: @model, view: :edit, user: _current_user)
|
168
|
+
set_actions
|
174
169
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
flash.now[:error] = t "avo.you_missed_something_check_form"
|
180
|
-
format.html { render :edit, status: :unprocessable_entity }
|
181
|
-
end
|
170
|
+
if saved
|
171
|
+
update_success_action
|
172
|
+
else
|
173
|
+
update_fail_action
|
182
174
|
end
|
183
175
|
end
|
184
176
|
|
185
177
|
def destroy
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
error_message = @errors.present? ? @errors.first : t("avo.failed")
|
191
|
-
|
192
|
-
format.html { redirect_back fallback_location: params[:referrer] || resources_path(resource: @resource, turbo_frame: params[:turbo_frame], view_type: params[:view_type]), error: error_message }
|
193
|
-
end
|
178
|
+
if destroy_model
|
179
|
+
destroy_success_action
|
180
|
+
else
|
181
|
+
destroy_fail_action
|
194
182
|
end
|
195
183
|
end
|
196
184
|
|
@@ -401,6 +389,27 @@ module Avo
|
|
401
389
|
add_breadcrumb t("avo.edit").humanize
|
402
390
|
end
|
403
391
|
|
392
|
+
def create_success_action
|
393
|
+
respond_to do |format|
|
394
|
+
format.html { redirect_to after_create_path, notice: create_success_message}
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
def create_fail_action
|
399
|
+
respond_to do |format|
|
400
|
+
flash.now[:error] = create_fail_message
|
401
|
+
format.html { render :new, status: :unprocessable_entity }
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
def create_success_message
|
406
|
+
"#{@resource.name} #{t("avo.was_successfully_created")}."
|
407
|
+
end
|
408
|
+
|
409
|
+
def create_fail_message
|
410
|
+
t "avo.you_missed_something_check_form"
|
411
|
+
end
|
412
|
+
|
404
413
|
def after_create_path
|
405
414
|
# If this is an associated record return to the association show page
|
406
415
|
if params[:via_relation_class].present? && params[:via_resource_id].present?
|
@@ -412,12 +421,57 @@ module Avo
|
|
412
421
|
redirect_path_from_resource_option(:after_create_path) || resource_path(model: @model, resource: @resource)
|
413
422
|
end
|
414
423
|
|
424
|
+
def update_success_action
|
425
|
+
respond_to do |format|
|
426
|
+
format.html { redirect_to after_update_path, notice: update_success_message }
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
def update_fail_action
|
431
|
+
respond_to do |format|
|
432
|
+
flash.now[:error] = update_fail_message
|
433
|
+
format.html { render :edit, status: :unprocessable_entity }
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
def update_success_message
|
438
|
+
"#{@resource.name} #{t("avo.was_successfully_updated")}."
|
439
|
+
end
|
440
|
+
|
441
|
+
def update_fail_message
|
442
|
+
t "avo.you_missed_something_check_form"
|
443
|
+
end
|
444
|
+
|
415
445
|
def after_update_path
|
416
446
|
return params[:referrer] if params[:referrer].present?
|
417
447
|
|
418
448
|
redirect_path_from_resource_option(:after_update_path) || resource_path(model: @model, resource: @resource)
|
419
449
|
end
|
420
450
|
|
451
|
+
def destroy_success_action
|
452
|
+
respond_to do |format|
|
453
|
+
format.html { redirect_to after_destroy_path, notice: destroy_success_message }
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
def destroy_fail_action
|
458
|
+
respond_to do |format|
|
459
|
+
format.html { redirect_back fallback_location: params[:referrer] || resources_path(resource: @resource, turbo_frame: params[:turbo_frame], view_type: params[:view_type]), error: destroy_fail_message }
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
def destroy_success_message
|
464
|
+
t("avo.resource_destroyed", attachment_class: @attachment_class)
|
465
|
+
end
|
466
|
+
|
467
|
+
def destroy_fail_message
|
468
|
+
@errors.present? ? @errors.first : t("avo.failed")
|
469
|
+
end
|
470
|
+
|
471
|
+
def after_destroy_path
|
472
|
+
params[:referrer] || resources_path(resource: @resource, turbo_frame: params[:turbo_frame], view_type: params[:view_type])
|
473
|
+
end
|
474
|
+
|
421
475
|
def redirect_path_from_resource_option(action = :after_update_path)
|
422
476
|
return nil if @resource.class.send(action).blank?
|
423
477
|
|
@@ -44,10 +44,13 @@ module Avo
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def search_resource(resource)
|
47
|
-
query =
|
47
|
+
query = Avo::Hosts::SearchScopeHost.new(
|
48
|
+
block: resource.search_query,
|
49
|
+
params: params,
|
50
|
+
scope: resource.class.scope.limit(8)
|
51
|
+
).handle
|
48
52
|
|
49
|
-
|
50
|
-
query = apply_attach_scope query
|
53
|
+
query = apply_scope(query) if should_apply_any_scope?
|
51
54
|
|
52
55
|
results = apply_search_metadata(query, resource)
|
53
56
|
|
@@ -67,22 +70,19 @@ module Avo
|
|
67
70
|
[resource.name.pluralize.downcase, result_object]
|
68
71
|
end
|
69
72
|
|
70
|
-
#
|
71
|
-
#
|
72
|
-
def
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
# No need to modify the query if there's no attach_scope present.
|
79
|
-
return query if field.attach_scope.blank?
|
80
|
-
|
81
|
-
# Try to fetch the parent.
|
82
|
-
if params[:via_reflection_id].present?
|
83
|
-
parent = params[:via_reflection_class].safe_constantize.find params[:via_reflection_id]
|
73
|
+
# When searching in a `has_many` association and will scope out the records against the parent record.
|
74
|
+
# This is also used when looking for `belongs_to` associations, and this method applies the parents `attach_scope` if present.
|
75
|
+
def apply_scope(query)
|
76
|
+
if should_apply_has_many_scope?
|
77
|
+
apply_has_many_scope
|
78
|
+
elsif should_apply_attach_scope?
|
79
|
+
apply_attach_scope(query, parent)
|
84
80
|
end
|
81
|
+
end
|
85
82
|
|
83
|
+
# Parent passed as argument to be used as a variable instead of the method "def parent"
|
84
|
+
# Otherwise parent = params...safe_constantize... will try to call method "def parent="
|
85
|
+
def apply_attach_scope(query, parent)
|
86
86
|
# If the parent is nil it probably means that someone's creating the record so it's not attached yet.
|
87
87
|
# In these scenarios, try to find the grandparent for the new views where the parent is nil
|
88
88
|
# and initialize the parent record with the grandparent attached so the user has the required information
|
@@ -94,8 +94,13 @@ module Avo
|
|
94
94
|
)
|
95
95
|
end
|
96
96
|
|
97
|
-
|
98
|
-
|
97
|
+
Avo::Hosts::AssociationScopeHost.new(block: attach_scope, query: query, parent: parent).handle
|
98
|
+
end
|
99
|
+
|
100
|
+
def apply_has_many_scope
|
101
|
+
scope = parent.send(params[:via_association_id])
|
102
|
+
|
103
|
+
Avo::Hosts::SearchScopeHost.new(block: @resource.search_query, params: params, scope: scope).handle
|
99
104
|
end
|
100
105
|
|
101
106
|
def apply_search_metadata(models, avo_resource)
|
@@ -118,9 +123,41 @@ module Avo
|
|
118
123
|
end
|
119
124
|
end
|
120
125
|
|
121
|
-
|
126
|
+
private
|
127
|
+
|
128
|
+
def should_apply_has_many_scope?
|
129
|
+
params[:via_association] == "has_many" && @resource.search_query.present?
|
130
|
+
end
|
131
|
+
|
132
|
+
def should_apply_attach_scope?
|
133
|
+
params[:via_association] == "belongs_to" && attach_scope.present?
|
134
|
+
end
|
135
|
+
|
136
|
+
def should_apply_any_scope?
|
137
|
+
should_apply_has_many_scope? || should_apply_attach_scope?
|
138
|
+
end
|
139
|
+
|
140
|
+
def attach_scope
|
141
|
+
@attach_scope ||= field&.attach_scope
|
142
|
+
end
|
143
|
+
|
144
|
+
def field
|
145
|
+
@field ||= fetch_field
|
146
|
+
end
|
147
|
+
|
148
|
+
def parent
|
149
|
+
@parent ||= fetch_parent
|
150
|
+
end
|
151
|
+
|
152
|
+
def fetch_field
|
122
153
|
fields = ::Avo::App.get_resource_by_model_name(params[:via_reflection_class]).get_field_definitions
|
123
154
|
fields.find { |f| f.id.to_s == params[:via_association_id] }
|
124
155
|
end
|
156
|
+
|
157
|
+
def fetch_parent
|
158
|
+
return unless params[:via_reflection_id].present?
|
159
|
+
|
160
|
+
params[:via_reflection_class].safe_constantize.find params[:via_reflection_id]
|
161
|
+
end
|
125
162
|
end
|
126
163
|
end
|