avo 3.0.0.pre13 → 3.0.0.pre14
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 +1 -1
- data/Gemfile.lock +2 -1
- data/app/components/avo/alert_component.html.erb +1 -1
- data/app/components/avo/base_component.rb +7 -7
- data/app/components/avo/field_wrapper_component.rb +1 -1
- data/app/components/avo/fields/area_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/belongs_to_field/edit_component.html.erb +5 -5
- data/app/components/avo/fields/belongs_to_field/edit_component.rb +4 -4
- data/app/components/avo/fields/boolean_field/edit_component.html.erb +1 -0
- 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 +1 -0
- data/app/components/avo/fields/country_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/file_field/index_component.rb +2 -2
- data/app/components/avo/fields/has_one_field/show_component.html.erb +1 -0
- data/app/components/avo/fields/index_component.rb +1 -0
- data/app/components/avo/fields/location_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/markdown_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/number_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/password_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/progress_bar_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/status_field/edit_component.html.erb +1 -1
- 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 -0
- data/app/components/avo/fields/trix_field/edit_component.html.erb +2 -1
- data/app/components/avo/fields/trix_field/show_component.html.erb +1 -1
- data/app/components/avo/index/resource_controls_component.rb +6 -6
- data/app/components/avo/item_switcher_component.html.erb +9 -4
- data/app/components/avo/item_switcher_component.rb +2 -1
- data/app/components/avo/resource_component.rb +5 -3
- data/app/components/avo/resource_sidebar_component.rb +1 -1
- data/app/components/avo/row_component.html.erb +3 -0
- data/app/components/avo/row_component.rb +12 -0
- data/app/components/avo/sidebar/link_component.html.erb +2 -0
- data/app/components/avo/sidebar/link_component.rb +5 -3
- data/app/components/avo/sidebar_component.html.erb +3 -3
- data/app/components/avo/sidebar_component.rb +4 -4
- data/app/components/avo/sidebar_profile_component.html.erb +3 -3
- data/app/components/avo/views/resource_edit_component.rb +1 -1
- data/app/components/avo/views/resource_index_component.html.erb +1 -1
- data/app/components/avo/views/resource_index_component.rb +8 -8
- data/app/controllers/avo/actions_controller.rb +11 -7
- data/app/controllers/avo/application_controller.rb +71 -66
- data/app/controllers/avo/associations_controller.rb +4 -6
- data/app/controllers/avo/attachments_controller.rb +1 -1
- data/app/controllers/avo/base_controller.rb +22 -15
- data/app/controllers/avo/home_controller.rb +1 -1
- data/app/controllers/avo/search_controller.rb +14 -12
- data/app/controllers/concerns/avo/initializes_avo.rb +2 -5
- data/app/javascript/js/controllers/fields/easy_mde_controller.js +1 -0
- data/app/views/avo/associations/new.html.erb +1 -1
- data/app/views/avo/debug/status.html.erb +1 -1
- data/app/views/avo/partials/_custom_tools_alert.html.erb +2 -2
- data/app/views/avo/partials/_footer.html.erb +1 -1
- data/app/views/avo/partials/_javascript.html.erb +1 -1
- data/app/views/avo/partials/_navbar.html.erb +1 -1
- data/app/views/layouts/avo/application.html.erb +2 -2
- data/avo.gemspec +1 -0
- data/config/initializers/pagy.rb +12 -10
- data/config/routes.rb +3 -3
- data/db/factories.rb +2 -1
- data/lib/avo/base_action.rb +4 -1
- data/lib/avo/base_resource.rb +118 -89
- data/lib/avo/concerns/has_item_type.rb +4 -0
- data/lib/avo/concerns/has_items.rb +20 -15
- data/lib/avo/concerns/model_class_constantized.rb +0 -2
- data/lib/avo/current.rb +22 -1
- data/lib/avo/dsl/field_parser.rb +1 -1
- data/lib/avo/dynamic_router.rb +12 -1
- data/lib/avo/engine.rb +4 -7
- data/lib/avo/fields/base_field.rb +25 -3
- data/lib/avo/fields/belongs_to_field.rb +8 -7
- data/lib/avo/fields/concerns/is_searchable.rb +1 -1
- data/lib/avo/fields/concerns/use_resource.rb +1 -1
- data/lib/avo/fields/field_manager.rb +13 -3
- data/lib/avo/fields/has_base_field.rb +4 -4
- data/lib/avo/fields/has_one_field.rb +1 -1
- data/lib/avo/fields/location_field.rb +18 -1
- data/lib/avo/licensing/h_q.rb +11 -6
- data/lib/avo/licensing/license.rb +1 -1
- data/lib/avo/licensing/license_manager.rb +1 -1
- data/lib/avo/licensing/{null_license.rb → nil_license.rb} +1 -1
- data/lib/avo/loaders/fields_loader.rb +7 -1
- data/lib/avo/plugin_manager.rb +2 -4
- data/lib/avo/reloader.rb +1 -1
- data/lib/avo/resources/items/holder.rb +5 -1
- data/lib/avo/resources/items/item_group.rb +1 -0
- data/lib/avo/resources/items/row.rb +54 -0
- data/lib/avo/resources/resource_manager.rb +4 -7
- data/lib/avo/services/debug_service.rb +6 -6
- data/lib/avo/services/telemetry_service.rb +3 -3
- data/lib/avo/version.rb +1 -1
- data/lib/avo.rb +107 -25
- data/lib/generators/avo/action_generator.rb +8 -8
- data/lib/generators/avo/card_generator.rb +27 -0
- data/lib/generators/avo/filter_generator.rb +8 -8
- data/lib/generators/avo/templates/action.tt +3 -3
- data/lib/generators/avo/templates/cards/chartkick_card.tt +1 -1
- data/lib/generators/avo/templates/cards/chartkick_card_sample.tt +1 -1
- data/lib/generators/avo/templates/cards/metric_card.tt +1 -1
- data/lib/generators/avo/templates/cards/metric_card_sample.tt +1 -1
- data/lib/generators/avo/templates/cards/partial_card.tt +1 -1
- data/lib/generators/avo/templates/cards/partial_card_sample.tt +1 -1
- data/lib/generators/avo/templates/dashboards/dashboard.tt +1 -1
- data/lib/generators/avo/templates/scope.tt +1 -1
- data/lib/tasks/avo_tasks.rake +1 -28
- data/public/avo-assets/avo.base.css +26 -31
- data/public/avo-assets/avo.base.js +281 -280
- data/public/avo-assets/avo.base.js.map +3 -3
- metadata +21 -8
- data/lib/avo/app.rb +0 -170
- data/lib/generators/avo/card/chartkick_generator.rb +0 -18
- data/lib/generators/avo/card/metric_generator.rb +0 -18
- data/lib/generators/avo/card/partial_generator.rb +0 -19
- data/lib/generators/avo/templates/standalone_action.tt +0 -15
@@ -100,7 +100,7 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
100
100
|
def attach_path
|
101
101
|
current_path = CGI.unescape(request.env["PATH_INFO"]).split("/").select(&:present?)
|
102
102
|
|
103
|
-
Avo
|
103
|
+
Avo.root_path(paths: [*current_path, "new"])
|
104
104
|
end
|
105
105
|
|
106
106
|
def singular_resource_name
|
@@ -126,7 +126,7 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
126
126
|
|
127
127
|
def show_search_input
|
128
128
|
return false unless authorized_to_search?
|
129
|
-
return false unless resource.search_query.present?
|
129
|
+
return false unless resource.class.search_query.present?
|
130
130
|
return false if field&.hide_search_input
|
131
131
|
|
132
132
|
true
|
@@ -143,7 +143,7 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
143
143
|
def render_dynamic_filters_button
|
144
144
|
return unless Avo.avo_filters_installed?
|
145
145
|
return unless resource.has_filters?
|
146
|
-
return if
|
146
|
+
return if Avo::DynamicFilters.configuration.always_expanded
|
147
147
|
|
148
148
|
a_button size: :sm,
|
149
149
|
color: :primary,
|
@@ -152,12 +152,12 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
152
152
|
controller: "avo-filters",
|
153
153
|
action: "click->avo-filters#toggleFiltersArea",
|
154
154
|
} do
|
155
|
-
|
155
|
+
Avo::DynamicFilters.configuration.button_label
|
156
156
|
end
|
157
157
|
end
|
158
158
|
|
159
159
|
def scopes_list
|
160
|
-
|
160
|
+
Avo::Pro::Scopes::ListComponent.new(
|
161
161
|
scopes: scopes,
|
162
162
|
resource: resource,
|
163
163
|
turbo_frame: turbo_frame,
|
@@ -166,7 +166,7 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
166
166
|
end
|
167
167
|
|
168
168
|
def can_render_scopes?
|
169
|
-
defined?(
|
169
|
+
defined?(Avo::Pro)
|
170
170
|
end
|
171
171
|
|
172
172
|
private
|
@@ -191,11 +191,11 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
|
|
191
191
|
end
|
192
192
|
|
193
193
|
def header_visible?
|
194
|
-
search_query_present? || filters_present? || has_many_view_types? || (Avo.avo_filters_installed? && resource.has_filters? &&
|
194
|
+
search_query_present? || filters_present? || has_many_view_types? || (Avo.avo_filters_installed? && resource.has_filters? && Avo::DynamicFilters.configuration.always_expanded)
|
195
195
|
end
|
196
196
|
|
197
197
|
def search_query_present?
|
198
|
-
@resource.search_query.present?
|
198
|
+
@resource.class.search_query.present?
|
199
199
|
end
|
200
200
|
|
201
201
|
def filters_present?
|
@@ -20,10 +20,14 @@ module Avo
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def handle
|
23
|
+
# puts ["action_params->", action_params].inspect
|
23
24
|
resource_ids = action_params[:fields][:avo_resource_ids].split(",")
|
24
25
|
@selected_query = action_params[:fields][:avo_selected_query]
|
25
26
|
|
27
|
+
# puts ["action_params[:fields]->", action_params[:fields]].inspect
|
28
|
+
|
26
29
|
fields = action_params[:fields].except(:avo_resource_ids, :avo_selected_query)
|
30
|
+
# puts ["fields->", fields.to_h].inspect
|
27
31
|
|
28
32
|
args = {
|
29
33
|
fields: fields,
|
@@ -31,14 +35,14 @@ module Avo
|
|
31
35
|
resource: resource
|
32
36
|
}
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
@resource.find_record resource_ids, params: params
|
39
|
-
end
|
38
|
+
args[:records] = if @selected_query.present?
|
39
|
+
@resource.model_class.find_by_sql decrypted_query
|
40
|
+
else
|
41
|
+
@resource.find_record resource_ids, params: params
|
40
42
|
end
|
41
43
|
|
44
|
+
puts ["args->", args].inspect
|
45
|
+
|
42
46
|
performed_action = @action.handle_action(**args)
|
43
47
|
|
44
48
|
respond performed_action.response
|
@@ -47,7 +51,7 @@ module Avo
|
|
47
51
|
private
|
48
52
|
|
49
53
|
def action_params
|
50
|
-
params.permit(:authenticity_token, :resource_name, :action_id, fields: {})
|
54
|
+
params.permit(:authenticity_token, :resource_name, :action_id, :button, fields: {})
|
51
55
|
end
|
52
56
|
|
53
57
|
def set_action
|
@@ -7,10 +7,10 @@ module Avo
|
|
7
7
|
end
|
8
8
|
|
9
9
|
include Avo::InitializesAvo
|
10
|
-
include Pagy::Backend
|
11
10
|
include Avo::ApplicationHelper
|
12
11
|
include Avo::UrlHelpers
|
13
12
|
include Avo::Concerns::Breadcrumbs
|
13
|
+
include Pagy::Backend
|
14
14
|
|
15
15
|
protect_from_forgery with: :exception
|
16
16
|
around_action :set_avo_locale
|
@@ -61,6 +61,49 @@ module Avo
|
|
61
61
|
|
62
62
|
private
|
63
63
|
|
64
|
+
# Get the pluralized resource name for this request
|
65
|
+
# Ex: projects, teams, users
|
66
|
+
def resource_name
|
67
|
+
return params[:resource_name] if params[:resource_name].present?
|
68
|
+
|
69
|
+
return controller_name if controller_name.present?
|
70
|
+
|
71
|
+
begin
|
72
|
+
request.path
|
73
|
+
.match(/\/?#{Avo.root_path.delete('/')}\/resources\/([a-z1-9\-_]*)\/?/mi)
|
74
|
+
.captures
|
75
|
+
.first
|
76
|
+
rescue
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def related_resource_name
|
81
|
+
params[:related_name]
|
82
|
+
end
|
83
|
+
|
84
|
+
# Gets the Avo resource for this request based on the request from the `resource_name` "param"
|
85
|
+
# Ex: Avo::Resources::Project, Avo::Resources::Team, Avo::Resources::User
|
86
|
+
def resource
|
87
|
+
resource = Avo.resource_manager.get_resource @resource_name.to_s.camelize.singularize
|
88
|
+
|
89
|
+
return resource if resource.present?
|
90
|
+
|
91
|
+
Avo.resource_manager.get_resource_by_controller_name @resource_name
|
92
|
+
end
|
93
|
+
|
94
|
+
def related_resource
|
95
|
+
# Find the field from the parent resource
|
96
|
+
field = @resource.get_field params[:related_name]
|
97
|
+
|
98
|
+
return field.use_resource if field&.use_resource.present?
|
99
|
+
|
100
|
+
reflection = @record._reflections[params[:related_name]]
|
101
|
+
|
102
|
+
reflected_model = reflection.klass
|
103
|
+
|
104
|
+
Avo.resource_manager.get_resource_by_model_class reflected_model
|
105
|
+
end
|
106
|
+
|
64
107
|
def set_resource_name
|
65
108
|
@resource_name = resource_name
|
66
109
|
end
|
@@ -72,23 +115,18 @@ module Avo
|
|
72
115
|
def set_resource
|
73
116
|
raise ActionController::RoutingError.new "No route matches" if resource.nil?
|
74
117
|
|
75
|
-
@resource = resource.
|
118
|
+
@resource = resource.new(view: action_name.to_sym, user: _current_user, params: params)
|
119
|
+
|
120
|
+
set_authorization
|
76
121
|
end
|
77
122
|
|
78
123
|
def set_related_resource
|
79
|
-
@related_resource = related_resource.
|
124
|
+
@related_resource = related_resource.new(params: params, view: action_name.to_sym, user: _current_user, record: @related_record)
|
80
125
|
end
|
81
126
|
|
82
127
|
def set_record
|
83
128
|
@record = @resource.find_record(params[:id], query: model_find_scope, params: params)
|
84
|
-
|
85
|
-
|
86
|
-
def model_find_scope
|
87
|
-
eager_load_files(@resource, model_scope)
|
88
|
-
end
|
89
|
-
|
90
|
-
def model_scope
|
91
|
-
@resource.class.find_scope
|
129
|
+
@resource.hydrate(record: @record)
|
92
130
|
end
|
93
131
|
|
94
132
|
def set_related_record
|
@@ -98,6 +136,16 @@ module Avo
|
|
98
136
|
else
|
99
137
|
@related_resource.find_record params[:related_id], query: eager_load_files(@related_resource, @record.send(association_name)), params: params
|
100
138
|
end
|
139
|
+
@related_resource.hydrate(record: @related_record)
|
140
|
+
end
|
141
|
+
|
142
|
+
def model_find_scope
|
143
|
+
eager_load_files(@resource, model_scope)
|
144
|
+
end
|
145
|
+
|
146
|
+
def model_scope
|
147
|
+
# abort @resource.inspect
|
148
|
+
@resource.class.find_scope
|
101
149
|
end
|
102
150
|
|
103
151
|
def set_view
|
@@ -110,6 +158,7 @@ module Avo
|
|
110
158
|
|
111
159
|
# If resource.record is nil, most likely the user is creating a new record.
|
112
160
|
# In that case, to access resource.record in visible and readonly blocks we hydrate the resource with a new record.
|
161
|
+
# TODO: commented this
|
113
162
|
@resource.hydrate(record: @record_to_fill) if @resource.record.nil?
|
114
163
|
end
|
115
164
|
|
@@ -136,14 +185,6 @@ module Avo
|
|
136
185
|
end
|
137
186
|
end
|
138
187
|
|
139
|
-
def hydrate_resource
|
140
|
-
@resource.hydrate(view: action_name.to_sym, user: _current_user, record: @record)
|
141
|
-
end
|
142
|
-
|
143
|
-
def hydrate_related_resource
|
144
|
-
@related_resource.hydrate(view: action_name.to_sym, user: _current_user, record: @related_record)
|
145
|
-
end
|
146
|
-
|
147
188
|
def authorize_base_action
|
148
189
|
class_to_authorize = @record || @resource.model_class
|
149
190
|
|
@@ -157,52 +198,16 @@ module Avo
|
|
157
198
|
@authorization.set_record(class_to_authorize).authorize_action action_to_authorize.to_sym
|
158
199
|
end
|
159
200
|
|
160
|
-
# Get the pluralized resource name for this request
|
161
|
-
# Ex: projects, teams, users
|
162
|
-
def resource_name
|
163
|
-
return params[:resource_name] if params[:resource_name].present?
|
164
|
-
|
165
|
-
return controller_name if controller_name.present?
|
166
|
-
|
167
|
-
begin
|
168
|
-
request.path
|
169
|
-
.match(/\/?#{Avo::App.root_path.delete('/')}\/resources\/([a-z1-9\-_]*)\/?/mi)
|
170
|
-
.captures
|
171
|
-
.first
|
172
|
-
rescue
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
def related_resource_name
|
177
|
-
params[:related_name]
|
178
|
-
end
|
179
|
-
|
180
|
-
# Gets the Avo resource for this request based on the request from the `resource_name` "param"
|
181
|
-
# Ex: Avo::Resources::Project, Avo::Resources::Team, Avo::Resources::User
|
182
|
-
def resource
|
183
|
-
resource = Avo::App.resources.get_resource @resource_name.to_s.camelize.singularize
|
184
|
-
|
185
|
-
return resource if resource.present?
|
186
|
-
|
187
|
-
Avo::App.resources.get_resource_by_controller_name @resource_name
|
188
|
-
end
|
189
|
-
|
190
|
-
def related_resource
|
191
|
-
# Find the field from the parent resource
|
192
|
-
field = @resource.get_field params[:related_name]
|
193
|
-
|
194
|
-
return field.use_resource if field&.use_resource.present?
|
195
|
-
|
196
|
-
reflection = @record._reflections[params[:related_name]]
|
197
|
-
|
198
|
-
reflected_model = reflection.klass
|
199
|
-
|
200
|
-
Avo::App.resources.get_resource_by_model_class reflected_model
|
201
|
-
end
|
202
|
-
|
203
201
|
def eager_load_files(resource, query)
|
204
|
-
|
205
|
-
|
202
|
+
# Get the non-computed file fields and try to eager load them
|
203
|
+
attachment_fields = resource
|
204
|
+
.attachment_fields
|
205
|
+
.reject do |field|
|
206
|
+
field.computed
|
207
|
+
end
|
208
|
+
|
209
|
+
if attachment_fields.present?
|
210
|
+
attachment_fields.map do |field|
|
206
211
|
attachment = case field.class.to_s
|
207
212
|
when "Avo::Fields::FileField"
|
208
213
|
"attachment"
|
@@ -238,8 +243,8 @@ module Avo
|
|
238
243
|
def set_authorization
|
239
244
|
# We need to set @resource_name for the #resource method to work properly
|
240
245
|
set_resource_name
|
241
|
-
@authorization = if resource
|
242
|
-
resource.authorization(user: _current_user)
|
246
|
+
@authorization = if @resource
|
247
|
+
@resource.authorization(user: _current_user)
|
243
248
|
else
|
244
249
|
Services::AuthorizationService.new _current_user
|
245
250
|
end
|
@@ -3,13 +3,11 @@ require_dependency "avo/base_controller"
|
|
3
3
|
module Avo
|
4
4
|
class AssociationsController < BaseController
|
5
5
|
before_action :set_record, only: [:show, :index, :new, :create, :destroy]
|
6
|
-
before_action :hydrate_resource, only: [:show, :index, :new, :create, :destroy]
|
7
6
|
before_action :set_related_resource_name
|
8
7
|
before_action :set_related_resource, only: [:show, :index, :new, :create, :destroy]
|
9
8
|
before_action :set_related_authorization
|
10
9
|
before_action :set_reflection_field
|
11
10
|
before_action :set_related_record, only: [:show]
|
12
|
-
before_action :hydrate_related_resource, only: [:show, :index, :create, :destroy]
|
13
11
|
before_action :set_reflection
|
14
12
|
before_action :set_attachment_class, only: [:show, :index, :new, :create, :destroy]
|
15
13
|
before_action :set_attachment_resource, only: [:show, :index, :new, :create, :destroy]
|
@@ -54,7 +52,7 @@ module Avo
|
|
54
52
|
end
|
55
53
|
|
56
54
|
@options = query.all.map do |record|
|
57
|
-
[@attachment_resource.
|
55
|
+
[@attachment_resource.new(record: record).record_title, record.id]
|
58
56
|
end
|
59
57
|
end
|
60
58
|
end
|
@@ -102,7 +100,7 @@ module Avo
|
|
102
100
|
end
|
103
101
|
|
104
102
|
def set_attachment_resource
|
105
|
-
@attachment_resource = @field.use_resource || (Avo
|
103
|
+
@attachment_resource = @field.use_resource || (Avo.resource_manager.get_resource_by_model_class @attachment_class)
|
106
104
|
end
|
107
105
|
|
108
106
|
def set_attachment_record
|
@@ -151,8 +149,8 @@ module Avo
|
|
151
149
|
private
|
152
150
|
|
153
151
|
def set_related_authorization
|
154
|
-
@related_authorization = if related_resource
|
155
|
-
related_resource.authorization(user: _current_user)
|
152
|
+
@related_authorization = if @related_resource.present?
|
153
|
+
@related_resource.authorization(user: _current_user)
|
156
154
|
else
|
157
155
|
Services::AuthorizationService.new _current_user
|
158
156
|
end
|
@@ -7,7 +7,7 @@ module Avo
|
|
7
7
|
before_action :set_record, only: [:destroy, :create]
|
8
8
|
|
9
9
|
def create
|
10
|
-
blob = ActiveStorage::Blob.create_and_upload! io: params[:file], filename: params[:filename]
|
10
|
+
blob = ActiveStorage::Blob.create_and_upload! io: params[:file].to_io, filename: params[:filename]
|
11
11
|
association_name = BaseResource.valid_attachment_name(@record, params[:attachment_key])
|
12
12
|
|
13
13
|
if association_name.blank?
|
@@ -6,7 +6,6 @@ module Avo
|
|
6
6
|
|
7
7
|
before_action :set_resource_name
|
8
8
|
before_action :set_resource
|
9
|
-
before_action :hydrate_resource
|
10
9
|
before_action :set_applied_filters, only: :index
|
11
10
|
before_action :set_record, only: [:show, :edit, :destroy, :update, :preview]
|
12
11
|
before_action :set_record_to_fill
|
@@ -69,9 +68,9 @@ module Avo
|
|
69
68
|
|
70
69
|
safe_call :set_and_apply_scopes
|
71
70
|
|
72
|
-
if Avo.avo_filters_installed? && params[
|
71
|
+
if Avo.avo_filters_installed? && params[Avo::DynamicFilters.configuration.param_key].present?
|
73
72
|
# Apply dynamic filters
|
74
|
-
query_builder =
|
73
|
+
query_builder = Avo::DynamicFilters::QueryBuilder.new(resource: @resource, params: params, query: @query)
|
75
74
|
@query = @query.ransack(**query_builder.ransack_query)
|
76
75
|
end
|
77
76
|
|
@@ -98,9 +97,9 @@ module Avo
|
|
98
97
|
|
99
98
|
# If we're accessing this resource via another resource add the parent to the breadcrumbs.
|
100
99
|
if params[:via_resource_class].present? && params[:via_record_id].present?
|
101
|
-
via_resource = Avo
|
100
|
+
via_resource = Avo.resource_manager.get_resource(params[:via_resource_class])
|
102
101
|
via_record = via_resource.find_record params[:via_record_id], params: params
|
103
|
-
via_resource.
|
102
|
+
via_resource = via_resource.new record: via_record
|
104
103
|
|
105
104
|
add_breadcrumb via_resource.plural_name, resources_path(resource: via_resource)
|
106
105
|
add_breadcrumb via_resource.record_title, resource_path(record: via_record, resource: via_resource)
|
@@ -121,9 +120,9 @@ module Avo
|
|
121
120
|
@page_title = @resource.default_panel_name.to_s
|
122
121
|
|
123
122
|
if is_associated_record?
|
124
|
-
via_resource = Avo
|
123
|
+
via_resource = Avo.resource_manager.get_resource_by_model_class(params[:via_relation_class])
|
125
124
|
via_record = via_resource.find_record params[:via_record_id], params: params
|
126
|
-
via_resource.
|
125
|
+
via_resource = via_resource.new record: via_record
|
127
126
|
|
128
127
|
add_breadcrumb via_resource.plural_name, resources_path(resource: via_resource)
|
129
128
|
add_breadcrumb via_resource.record_title, resource_path(record: via_record, resource: via_resource)
|
@@ -146,7 +145,7 @@ module Avo
|
|
146
145
|
# Fills in the required infor for belongs_to and has_many
|
147
146
|
# Get the foreign key and set it to the id we received in the params
|
148
147
|
if @reflection.is_a?(ActiveRecord::Reflection::BelongsToReflection) || @reflection.is_a?(ActiveRecord::Reflection::HasManyReflection)
|
149
|
-
related_resource = Avo
|
148
|
+
related_resource = Avo.resource_manager.get_resource_by_model_class params[:via_relation_class]
|
150
149
|
related_record = related_resource.find_record params[:via_record_id], params: params
|
151
150
|
|
152
151
|
@record.send("#{@reflection.foreign_key}=", related_record.id)
|
@@ -156,7 +155,7 @@ module Avo
|
|
156
155
|
# For when working with has_one, has_one_through, has_many_through, has_and_belongs_to_many, polymorphic
|
157
156
|
if @reflection.is_a? ActiveRecord::Reflection::ThroughReflection
|
158
157
|
# find the record
|
159
|
-
via_resource =
|
158
|
+
via_resource = Avo.resource_manager.get_resource_by_model_class(params[:via_relation_class])
|
160
159
|
@related_record = via_resource.find_record params[:via_record_id], params: params
|
161
160
|
association_name = BaseResource.valid_association_name(@record, params[:via_relation])
|
162
161
|
|
@@ -215,16 +214,24 @@ module Avo
|
|
215
214
|
|
216
215
|
def save_record
|
217
216
|
perform_action_and_record_errors do
|
218
|
-
|
217
|
+
save_record_action
|
219
218
|
end
|
220
219
|
end
|
221
220
|
|
221
|
+
def save_record_action
|
222
|
+
@record.save!
|
223
|
+
end
|
224
|
+
|
222
225
|
def destroy_model
|
223
226
|
perform_action_and_record_errors do
|
224
|
-
|
227
|
+
destroy_record_action
|
225
228
|
end
|
226
229
|
end
|
227
230
|
|
231
|
+
def destroy_record_action
|
232
|
+
@record.destroy!
|
233
|
+
end
|
234
|
+
|
228
235
|
def perform_action_and_record_errors(&block)
|
229
236
|
begin
|
230
237
|
succeeded = block.call
|
@@ -253,7 +260,7 @@ module Avo
|
|
253
260
|
end
|
254
261
|
|
255
262
|
def permitted_params
|
256
|
-
@resource.get_field_definitions.select(&:updatable).map(&:to_permitted_param).concat
|
263
|
+
@resource.get_field_definitions.select(&:updatable).map(&:to_permitted_param).concat(extra_params).uniq
|
257
264
|
end
|
258
265
|
|
259
266
|
def extra_params
|
@@ -404,9 +411,9 @@ module Avo
|
|
404
411
|
last_crumb_args = {}
|
405
412
|
# If we're accessing this resource via another resource add the parent to the breadcrumbs.
|
406
413
|
if params[:via_resource_class].present? && params[:via_record_id].present?
|
407
|
-
via_resource = Avo
|
414
|
+
via_resource = Avo.resource_manager.get_resource(params[:via_resource_class])
|
408
415
|
via_record = via_resource.find_record params[:via_record_id], params: params
|
409
|
-
via_resource.
|
416
|
+
via_resource = via_resource.new record: via_record
|
410
417
|
|
411
418
|
add_breadcrumb via_resource.plural_name, resources_path(resource: @resource)
|
412
419
|
add_breadcrumb via_resource.record_title, resource_path(record: via_record, resource: via_resource)
|
@@ -447,7 +454,7 @@ module Avo
|
|
447
454
|
def after_create_path
|
448
455
|
# If this is an associated record return to the association show page
|
449
456
|
if is_associated_record?
|
450
|
-
parent_resource =
|
457
|
+
parent_resource = Avo.resource_manager.get_resource_by_model_class(params[:via_relation_class])
|
451
458
|
association_name = BaseResource.valid_association_name(@record, params[:via_relation])
|
452
459
|
|
453
460
|
return resource_view_path(
|
@@ -14,7 +14,7 @@ module Avo
|
|
14
14
|
redirect_to computed_path
|
15
15
|
elsif !Rails.env.development?
|
16
16
|
@page_title = "Get started"
|
17
|
-
resource = Avo
|
17
|
+
resource = Avo.resource_manager.all.min_by { |resource| resource.model_key }
|
18
18
|
redirect_to resources_path(resource: resource)
|
19
19
|
end
|
20
20
|
end
|
@@ -37,7 +37,7 @@ module Avo
|
|
37
37
|
query = Avo::ExecutionContext.new(
|
38
38
|
target: resource.search_query,
|
39
39
|
params: params,
|
40
|
-
query: resource.
|
40
|
+
query: resource.query_scope
|
41
41
|
).handle
|
42
42
|
|
43
43
|
# Get the count
|
@@ -101,18 +101,21 @@ module Avo
|
|
101
101
|
# This scope is applied if the search is being performed on a has_many association
|
102
102
|
def apply_has_many_scope
|
103
103
|
association_name = BaseResource.valid_association_name(parent, params[:via_association_id])
|
104
|
+
|
105
|
+
# Get association records
|
104
106
|
query = parent.send(association_name)
|
105
107
|
|
106
|
-
|
108
|
+
# Apply policy scope if authorization is present
|
109
|
+
query = resource.authorization&.apply_policy query
|
110
|
+
|
111
|
+
Avo::ExecutionContext.new(target: @resource.class.search_query, params: params, query: query).handle
|
107
112
|
end
|
108
113
|
|
109
114
|
def apply_search_metadata(records, avo_resource)
|
110
115
|
records.map do |record|
|
111
|
-
|
112
|
-
# resource = avo_resource.dup.hydrate(record: record).hydrate_fields
|
113
|
-
resource = avo_resource.dup.hydrate(record: record)
|
116
|
+
resource = avo_resource.new(record: record)
|
114
117
|
|
115
|
-
fetch_result_information record, resource, resource.fetch_search(:item)
|
118
|
+
fetch_result_information record, resource, resource.class.fetch_search(:item, record: record)
|
116
119
|
end
|
117
120
|
end
|
118
121
|
|
@@ -122,12 +125,12 @@ module Avo
|
|
122
125
|
{
|
123
126
|
_id: record.id,
|
124
127
|
_label: item&.dig(:title) || resource.record_title,
|
125
|
-
_url: resource.fetch_search(:result_path) || resource.record_path
|
128
|
+
_url: resource.class.fetch_search(:result_path, record: resource.record) || resource.record_path
|
126
129
|
}
|
127
130
|
end
|
128
131
|
|
129
132
|
def should_apply_has_many_scope?
|
130
|
-
params[:via_association] == "has_many" && @resource.search_query.present?
|
133
|
+
params[:via_association] == "has_many" && @resource.class.search_query.present?
|
131
134
|
end
|
132
135
|
|
133
136
|
def should_apply_attach_scope?
|
@@ -151,16 +154,15 @@ module Avo
|
|
151
154
|
end
|
152
155
|
|
153
156
|
def fetch_field
|
154
|
-
fields =
|
157
|
+
fields = Avo.resource_manager.get_resource_by_model_class(params[:via_reflection_class]).new.get_field_definitions
|
155
158
|
fields.find { |f| f.id.to_s == params[:via_association_id] }
|
156
159
|
end
|
157
160
|
|
158
161
|
def fetch_parent
|
159
162
|
return unless params[:via_reflection_id].present?
|
160
163
|
|
161
|
-
|
162
|
-
|
163
|
-
parent_class.find params[:via_reflection_id]
|
164
|
+
parent_resource = Avo.resource_manager.get_resource_by_model_class params[:via_reflection_class]
|
165
|
+
parent_resource.find_record params[:via_reflection_id], params: params
|
164
166
|
end
|
165
167
|
end
|
166
168
|
end
|
@@ -1,16 +1,13 @@
|
|
1
1
|
module Avo
|
2
2
|
module InitializesAvo
|
3
3
|
def init_app
|
4
|
-
Avo::Current.license = Avo::Licensing::
|
4
|
+
Avo::Current.license = Avo::Licensing::NilLicense.new
|
5
5
|
Avo::Current.context = context
|
6
6
|
Avo::Current.current_user = _current_user
|
7
7
|
Avo::Current.view_context = view_context
|
8
|
-
Avo
|
9
|
-
Avo::Current.app.init
|
8
|
+
Avo.init
|
10
9
|
Avo::Current.license = Licensing::LicenseManager.new(Licensing::HQ.new(request).response).license
|
11
10
|
Avo.plugin_manager.init_plugins
|
12
|
-
|
13
|
-
@license = Avo::App.license
|
14
11
|
end
|
15
12
|
|
16
13
|
def _current_user
|
@@ -17,7 +17,7 @@
|
|
17
17
|
|
18
18
|
<div class="flex-1 flex items-center justify-center px-0 lg:px-8 text-lg mt-8 mb-12">
|
19
19
|
<% if @field.is_searchable? %>
|
20
|
-
<%= render
|
20
|
+
<%= render Avo::Pro::SearchableAssociations::AutocompleteComponent.new form: form,
|
21
21
|
classes: input_classes("w-full"),
|
22
22
|
field: @field,
|
23
23
|
model_key: @field.target_resource&.model_key,
|
@@ -5,8 +5,8 @@
|
|
5
5
|
</a>
|
6
6
|
</div>
|
7
7
|
<% end %>
|
8
|
-
<% if Avo
|
9
|
-
<% Avo
|
8
|
+
<% if Avo.error_manager.has_errors?.present? %>
|
9
|
+
<% Avo.error_manager.all.each do |error| %>
|
10
10
|
<% if error.is_a? Hash %>
|
11
11
|
<%
|
12
12
|
url, message, target = error.values_at :url, :message, :target
|
@@ -1,3 +1,3 @@
|
|
1
1
|
<div class="text-center text-sm text-gray-700 <%= 'print:hidden' if Avo.configuration.hide_layout_when_printing %>">
|
2
|
-
<a href="https://avohq.io/" target="_blank">Avo</a> · © <%= Date.today.year %> AvoHQ · <span title="<%= Avo
|
2
|
+
<a href="https://avohq.io/" target="_blank">Avo</a> · © <%= Date.today.year %> AvoHQ · <span title="<%= Avo.license.valid ? 'valid' : 'invalid'%> <%= Avo.license.id %> license">v<%= Avo::VERSION %></span>
|
3
3
|
</div>
|
@@ -6,7 +6,7 @@
|
|
6
6
|
Avo.configuration.cookies_key = '<%= Avo::COOKIES_KEY %>'
|
7
7
|
<% if Avo.avo_filters_installed? %>
|
8
8
|
Avo.configuration.avo_filters = {
|
9
|
-
param_key: '<%=
|
9
|
+
param_key: '<%= Avo::DynamicFilters.configuration.param_key %>'
|
10
10
|
}
|
11
11
|
<% end %>
|
12
12
|
<% end %>
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<%= render partial: "avo/partials/logo" %>
|
11
11
|
</div>
|
12
12
|
<div class="flex-1 flex items-center justify-between lg:justify-start space-x-2 sm:space-x-8 lg:px-2">
|
13
|
-
<%= render
|
13
|
+
<%= render Avo::Pro::GlobalSearchComponent.new rescue nil %>
|
14
14
|
<div class="m-0">
|
15
15
|
<%= render partial: "avo/partials/header" %>
|
16
16
|
</div>
|
@@ -60,8 +60,8 @@
|
|
60
60
|
<%= render partial: "avo/partials/scripts" %>
|
61
61
|
<!-- Avo version: <%= Avo::VERSION %> -->
|
62
62
|
<!-- Environment: <%= Rails.env %> -->
|
63
|
-
<!-- License ID: <%= Avo
|
64
|
-
<!-- License valid?: <%= Avo
|
63
|
+
<!-- License ID: <%= Avo.license.id %> -->
|
64
|
+
<!-- License valid?: <%= Avo.license.valid ? "valid" : "invalid" %> -->
|
65
65
|
</body>
|
66
66
|
</html>
|
67
67
|
<!-- ✨ Built with Avo • https://www.avohq.io/ -->
|
data/avo.gemspec
CHANGED
@@ -33,6 +33,7 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.files = Dir["{bin,app,config,db,lib,public}/**/*", "MIT-LICENSE", "Rakefile", "README.md", "avo.gemspec", "Gemfile", "Gemfile.lock"]
|
34
34
|
|
35
35
|
spec.add_dependency "activerecord", ">= 6.1"
|
36
|
+
spec.add_dependency "activesupport", ">= 6.1"
|
36
37
|
spec.add_dependency "actionview", ">= 6.1"
|
37
38
|
spec.add_dependency "pagy"
|
38
39
|
spec.add_dependency "zeitwerk", ">= 2.6.2"
|