avo 3.0.0.pre13 → 3.0.0.pre15
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/index/resource_table_component.rb +1 -1
- 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 +4 -4
- 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 +5 -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 +25 -25
- 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 +3 -6
- 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 -2
- data/lib/avo/base_resource.rb +123 -92
- 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 +29 -2
- 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/execution_context.rb +1 -1
- 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/filters/base_filter.rb +3 -1
- data/lib/avo/html/builder.rb +3 -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
data/config/initializers/pagy.rb
CHANGED
@@ -5,13 +5,15 @@ def pagy_locale_path(file_name)
|
|
5
5
|
Avo::Engine.root.join("lib", "generators", "avo", "templates", "locales", "pagy", file_name)
|
6
6
|
end
|
7
7
|
|
8
|
-
|
9
|
-
{
|
10
|
-
{
|
11
|
-
{
|
12
|
-
{
|
13
|
-
{
|
14
|
-
{
|
15
|
-
{
|
16
|
-
{
|
17
|
-
|
8
|
+
extra_locales = [
|
9
|
+
{locale: "en"},
|
10
|
+
{locale: "fr"},
|
11
|
+
{locale: "nb"},
|
12
|
+
{locale: "pt-BR"},
|
13
|
+
{locale: "pt"},
|
14
|
+
{locale: "tr"},
|
15
|
+
{locale: "nn", filepath: pagy_locale_path("nn.yml")},
|
16
|
+
{locale: "ro", filepath: pagy_locale_path("ro.yml")}
|
17
|
+
]
|
18
|
+
|
19
|
+
Pagy::I18n.send(:build, *extra_locales)
|
data/config/routes.rb
CHANGED
@@ -4,9 +4,9 @@ Avo::Engine.routes.draw do
|
|
4
4
|
get "resources", to: redirect(Avo.configuration.root_path)
|
5
5
|
get "dashboards", to: redirect(Avo.configuration.root_path)
|
6
6
|
|
7
|
-
mount
|
8
|
-
mount
|
9
|
-
mount
|
7
|
+
mount Avo::DynamicFilters::Engine, at: "/avo-dynamic_filters" if defined?(Avo::DynamicFilters::Engine)
|
8
|
+
mount Avo::Dashboards::Engine, at: "/dashboards" if defined?(Avo::Dashboards::Engine)
|
9
|
+
mount Avo::Pro::Engine, at: "/avo/avo-pro" if defined?(Avo::Pro::Engine)
|
10
10
|
|
11
11
|
post "/rails/active_storage/direct_uploads", to: "/active_storage/direct_uploads#create"
|
12
12
|
|
data/db/factories.rb
CHANGED
@@ -110,7 +110,8 @@ FactoryBot.define do
|
|
110
110
|
factory :city do
|
111
111
|
name { Faker::Address.city }
|
112
112
|
population { rand(10000..999000) }
|
113
|
-
|
113
|
+
latitude { Faker::Address.latitude }
|
114
|
+
longitude { Faker::Address.longitude }
|
114
115
|
is_capital { [true, false].sample }
|
115
116
|
features { Faker::Address.community }
|
116
117
|
metadata { Faker::Address.community }
|
data/lib/avo/base_action.rb
CHANGED
@@ -24,7 +24,9 @@ module Avo
|
|
24
24
|
delegate :view, to: :class
|
25
25
|
# TODO: find a differnet way to delegate this to the uninitialized Current variable
|
26
26
|
delegate :context, to: Avo::Current
|
27
|
-
|
27
|
+
def curent_user
|
28
|
+
Avo::Current.user
|
29
|
+
end
|
28
30
|
delegate :params, to: Avo::Current
|
29
31
|
delegate :view_context, to: Avo::Current
|
30
32
|
delegate :avo, to: :view_context
|
@@ -128,7 +130,7 @@ module Avo
|
|
128
130
|
resource: resource
|
129
131
|
}
|
130
132
|
|
131
|
-
args[:records] = records
|
133
|
+
args[:records] = records
|
132
134
|
|
133
135
|
handle(**args)
|
134
136
|
|
data/lib/avo/base_resource.rb
CHANGED
@@ -12,7 +12,9 @@ module Avo
|
|
12
12
|
|
13
13
|
# Avo::Current methods
|
14
14
|
delegate :context, to: Avo::Current
|
15
|
-
|
15
|
+
def curent_user
|
16
|
+
Avo::Current.user
|
17
|
+
end
|
16
18
|
delegate :params, to: Avo::Current
|
17
19
|
delegate :request, to: Avo::Current
|
18
20
|
delegate :view_context, to: Avo::Current
|
@@ -84,6 +86,8 @@ module Avo
|
|
84
86
|
end
|
85
87
|
|
86
88
|
# This resolves the scope when doing "where" queries (not find queries)
|
89
|
+
#
|
90
|
+
# It's used to apply the authorization feature.
|
87
91
|
def query_scope
|
88
92
|
authorization.apply_policy Avo::ExecutionContext.new(
|
89
93
|
target: index_query,
|
@@ -92,12 +96,14 @@ module Avo
|
|
92
96
|
end
|
93
97
|
|
94
98
|
# This resolves the scope when finding records (not "where" queries)
|
99
|
+
#
|
100
|
+
# It's used to apply the authorization feature.
|
95
101
|
def find_scope
|
96
102
|
authorization.apply_policy model_class
|
97
103
|
end
|
98
104
|
|
99
105
|
def authorization
|
100
|
-
Avo::Services::AuthorizationService.new Avo::Current.
|
106
|
+
Avo::Services::AuthorizationService.new Avo::Current.user, model_class, policy_class: authorization_policy
|
101
107
|
end
|
102
108
|
|
103
109
|
def get_record_associations(record)
|
@@ -127,8 +133,31 @@ module Avo
|
|
127
133
|
end
|
128
134
|
end
|
129
135
|
|
136
|
+
# Returns the model class being used for this resource.
|
137
|
+
#
|
138
|
+
# The Resource instance has a model_class method too so it can support the STI use cases
|
139
|
+
# where we figure out the model class from the record
|
140
|
+
def model_class(record_class: nil)
|
141
|
+
# get the model class off of the static property
|
142
|
+
return @model_class if @model_class.present?
|
143
|
+
|
144
|
+
# get the model class off of the record for STI models
|
145
|
+
return record_class if record_class.present?
|
146
|
+
|
147
|
+
# generate a model class
|
148
|
+
class_name.safe_constantize
|
149
|
+
end
|
150
|
+
|
151
|
+
# This is used as the model class ID
|
152
|
+
# We use this instead of the route_key to maintain compatibility with uncountable models
|
153
|
+
# With uncountable models route key appends an _index suffix (Fish->fish_index)
|
154
|
+
# Example: User->users, MediaItem->media_items, Fish->fish
|
155
|
+
def model_key
|
156
|
+
model_class.model_name.plural
|
157
|
+
end
|
158
|
+
|
130
159
|
def class_name
|
131
|
-
|
160
|
+
to_s.demodulize
|
132
161
|
end
|
133
162
|
|
134
163
|
def route_key
|
@@ -138,11 +167,81 @@ module Avo
|
|
138
167
|
def singular_route_key
|
139
168
|
route_key.singularize
|
140
169
|
end
|
170
|
+
|
171
|
+
def translation_key
|
172
|
+
@translation_key || "avo.resource_translations.#{class_name.underscore}"
|
173
|
+
end
|
174
|
+
|
175
|
+
def name
|
176
|
+
default = class_name.underscore.humanize
|
177
|
+
|
178
|
+
if translation_key
|
179
|
+
t(translation_key, count: 1, default: default).capitalize
|
180
|
+
else
|
181
|
+
default
|
182
|
+
end
|
183
|
+
end
|
184
|
+
alias_method :singular_name, :name
|
185
|
+
|
186
|
+
def plural_name
|
187
|
+
default = name.pluralize
|
188
|
+
|
189
|
+
if translation_key
|
190
|
+
t(translation_key, count: 2, default: default).capitalize
|
191
|
+
else
|
192
|
+
default
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def underscore_name
|
197
|
+
return @name if @name.present?
|
198
|
+
|
199
|
+
name.demodulize.underscore
|
200
|
+
end
|
201
|
+
|
202
|
+
def navigation_label
|
203
|
+
plural_name.humanize
|
204
|
+
end
|
205
|
+
|
206
|
+
def find_record(id, query: nil, params: nil)
|
207
|
+
Avo::ExecutionContext.new(
|
208
|
+
target: find_record_method,
|
209
|
+
query: query || find_scope, # If no record is given we'll use the default
|
210
|
+
id: id,
|
211
|
+
params: params
|
212
|
+
).handle
|
213
|
+
end
|
214
|
+
|
215
|
+
def search_query
|
216
|
+
search.dig(:query)
|
217
|
+
end
|
218
|
+
|
219
|
+
def fetch_search(key, record: nil)
|
220
|
+
# self.class.fetch_search
|
221
|
+
Avo::ExecutionContext.new(target: search[key], resource: self, record: record).handle
|
222
|
+
end
|
141
223
|
end
|
142
224
|
|
143
225
|
delegate :context, to: ::Avo::Current
|
226
|
+
delegate :name, to: :class
|
227
|
+
delegate :singular_name, to: :class
|
228
|
+
delegate :plural_name, to: :class
|
229
|
+
delegate :underscore_name, to: :class
|
230
|
+
delegate :underscore_name, to: :class
|
231
|
+
delegate :find_record, to: :class
|
232
|
+
delegate :model_key, to: :class
|
233
|
+
|
234
|
+
def initialize(record: nil, view: nil, user: nil, params: nil)
|
235
|
+
@view = view if view.present?
|
236
|
+
@user = user if user.present?
|
237
|
+
@params = params if params.present?
|
238
|
+
|
239
|
+
if record.present?
|
240
|
+
@record = record
|
241
|
+
|
242
|
+
hydrate_model_with_default_values if @view == :new
|
243
|
+
end
|
144
244
|
|
145
|
-
def initialize
|
146
245
|
detect_fields
|
147
246
|
|
148
247
|
unless self.class.model_class.present?
|
@@ -194,7 +293,7 @@ module Avo
|
|
194
293
|
|
195
294
|
# def get_action_arguments / def get_filter_arguments / def get_scope_arguments
|
196
295
|
define_method "get_#{entity}_arguments" do |entity_class|
|
197
|
-
send("get_#{plural_entity}").find { |entity| entity[:class] == entity_class.
|
296
|
+
send("get_#{plural_entity}").find { |entity| entity[:class].to_s == entity_class.to_s }[:arguments]
|
198
297
|
end
|
199
298
|
end
|
200
299
|
|
@@ -225,15 +324,14 @@ module Avo
|
|
225
324
|
end
|
226
325
|
end
|
227
326
|
|
327
|
+
# Returns the model class being used for this resource.
|
328
|
+
#
|
329
|
+
# We use the class method as a fallback but we pass it the record too so it can support the STI use cases
|
330
|
+
# where we figure out the model class from that record.
|
228
331
|
def model_class
|
229
|
-
|
230
|
-
return self.class.model_class if self.class.model_class.present?
|
231
|
-
|
232
|
-
# get the model class off of the record
|
233
|
-
return @record.base_class if @record.present?
|
332
|
+
record_class = @record&.class
|
234
333
|
|
235
|
-
|
236
|
-
class_name.safe_constantize
|
334
|
+
self.class.model_class record_class: record_class
|
237
335
|
end
|
238
336
|
|
239
337
|
def record_title
|
@@ -251,46 +349,6 @@ module Avo
|
|
251
349
|
end
|
252
350
|
end
|
253
351
|
|
254
|
-
def translation_key
|
255
|
-
self.class.translation_key || "avo.resource_translations.#{class_name.underscore}"
|
256
|
-
end
|
257
|
-
|
258
|
-
def name
|
259
|
-
return @name if @name.present?
|
260
|
-
|
261
|
-
default = class_name.underscore.humanize
|
262
|
-
|
263
|
-
if translation_key
|
264
|
-
t(translation_key, count: 1, default: default).capitalize
|
265
|
-
else
|
266
|
-
default
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
def singular_name
|
271
|
-
name
|
272
|
-
end
|
273
|
-
|
274
|
-
def plural_name
|
275
|
-
default = name.pluralize
|
276
|
-
|
277
|
-
if translation_key
|
278
|
-
t(translation_key, count: 2, default: default).capitalize
|
279
|
-
else
|
280
|
-
default
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
def underscore_name
|
285
|
-
return @name if @name.present?
|
286
|
-
|
287
|
-
self.class.name.demodulize.underscore
|
288
|
-
end
|
289
|
-
|
290
|
-
def navigation_label
|
291
|
-
plural_name.humanize
|
292
|
-
end
|
293
|
-
|
294
352
|
def available_view_types
|
295
353
|
if self.class.view_types.present?
|
296
354
|
return Array(
|
@@ -310,15 +368,15 @@ module Avo
|
|
310
368
|
view_types
|
311
369
|
end
|
312
370
|
|
313
|
-
def
|
371
|
+
def attachment_fields
|
314
372
|
get_field_definitions.select do |field|
|
315
373
|
[Avo::Fields::FileField, Avo::Fields::FilesField].include? field.class
|
316
374
|
end
|
317
375
|
end
|
318
376
|
|
319
|
-
|
320
|
-
|
321
|
-
|
377
|
+
# Map the received params to their actual fields
|
378
|
+
def fields_by_database_id
|
379
|
+
get_field_definitions
|
322
380
|
.reject do |field|
|
323
381
|
field.computed
|
324
382
|
end
|
@@ -326,7 +384,9 @@ module Avo
|
|
326
384
|
[field.database_id.to_s, field]
|
327
385
|
end
|
328
386
|
.to_h
|
387
|
+
end
|
329
388
|
|
389
|
+
def fill_record(record, params, extra_params: [])
|
330
390
|
# Write the field values
|
331
391
|
params.each do |key, value|
|
332
392
|
field = fields_by_database_id[key]
|
@@ -346,7 +406,7 @@ module Avo
|
|
346
406
|
end
|
347
407
|
|
348
408
|
def authorization(user: nil)
|
349
|
-
current_user = user || Avo::Current.
|
409
|
+
current_user = user || Avo::Current.user
|
350
410
|
Avo::Services::AuthorizationService.new(current_user, record || model_class, policy_class: authorization_policy)
|
351
411
|
end
|
352
412
|
|
@@ -383,20 +443,18 @@ module Avo
|
|
383
443
|
!field.computed
|
384
444
|
end
|
385
445
|
.map do |field|
|
386
|
-
id = field.id
|
387
446
|
value = field.value
|
388
447
|
|
389
448
|
if field.type == "belongs_to"
|
390
|
-
id = field.foreign_key.to_sym
|
391
449
|
|
392
450
|
reflection = @record._reflections[@params[:via_relation]]
|
393
451
|
|
394
452
|
if field.polymorphic_as.present? && field.types.map(&:to_s).include?(@params[:via_relation_class])
|
395
453
|
# set the value to the actual record
|
396
|
-
via_resource = Avo
|
454
|
+
via_resource = Avo.resource_manager.get_resource_by_model_class(@params[:via_relation_class])
|
397
455
|
value = via_resource.find_record(@params[:via_record_id])
|
398
456
|
elsif reflection.present? && reflection.foreign_key.present? && field.id.to_s == @params[:via_relation].to_s
|
399
|
-
resource = Avo
|
457
|
+
resource = Avo.resource_manager.get_resource_by_model_class params[:via_relation_class]
|
400
458
|
record = resource.find_record @params[:via_record_id], params: params
|
401
459
|
id_param = reflection.options[:primary_key] || :id
|
402
460
|
|
@@ -404,28 +462,18 @@ module Avo
|
|
404
462
|
end
|
405
463
|
end
|
406
464
|
|
407
|
-
[
|
465
|
+
[field, value]
|
408
466
|
end
|
409
467
|
.to_h
|
410
|
-
.select do |
|
468
|
+
.select do |_, value|
|
411
469
|
value.present?
|
412
470
|
end
|
413
471
|
|
414
|
-
default_values.each do |
|
415
|
-
|
416
|
-
@record.send("#{id}=", value)
|
417
|
-
end
|
472
|
+
default_values.each do |field, value|
|
473
|
+
field.assign_value record: @record, value: value
|
418
474
|
end
|
419
475
|
end
|
420
476
|
|
421
|
-
# This is used as the model class ID
|
422
|
-
# We use this instead of the route_key to maintain compatibility with uncountable models
|
423
|
-
# With uncountable models route key appends an _index suffix (Fish->fish_index)
|
424
|
-
# Example: User->users, MediaItem->media_items, Fish->fish
|
425
|
-
def model_key
|
426
|
-
model_class.model_name.plural
|
427
|
-
end
|
428
|
-
|
429
477
|
def model_name
|
430
478
|
model_class.model_name
|
431
479
|
end
|
@@ -474,15 +522,6 @@ module Avo
|
|
474
522
|
record.present? && record_id.present?
|
475
523
|
end
|
476
524
|
|
477
|
-
def find_record(id, query: nil, params: nil)
|
478
|
-
Avo::ExecutionContext.new(
|
479
|
-
target: self.class.find_record_method,
|
480
|
-
query: query || self.class.find_scope,
|
481
|
-
id: id,
|
482
|
-
params: params
|
483
|
-
).handle
|
484
|
-
end
|
485
|
-
|
486
525
|
def id_attribute
|
487
526
|
:id
|
488
527
|
end
|
@@ -499,14 +538,6 @@ module Avo
|
|
499
538
|
}
|
500
539
|
end
|
501
540
|
|
502
|
-
def search_query
|
503
|
-
self.class.search.dig(:query)
|
504
|
-
end
|
505
|
-
|
506
|
-
def fetch_search(key)
|
507
|
-
Avo::ExecutionContext.new(target: self.class.search[key], resource: self, record: record).handle
|
508
|
-
end
|
509
|
-
|
510
541
|
private
|
511
542
|
|
512
543
|
def entity_loader(entity)
|
@@ -18,6 +18,10 @@ module Avo
|
|
18
18
|
deprecated_dsl_api __method__, "fields"
|
19
19
|
end
|
20
20
|
|
21
|
+
def row(**args, &block)
|
22
|
+
deprecated_dsl_api __method__, "fields"
|
23
|
+
end
|
24
|
+
|
21
25
|
def tabs(**args, &block)
|
22
26
|
deprecated_dsl_api __method__, "fields"
|
23
27
|
end
|
@@ -42,6 +46,7 @@ module Avo
|
|
42
46
|
|
43
47
|
delegate :field, to: :items_holder
|
44
48
|
delegate :panel, to: :items_holder
|
49
|
+
delegate :row, to: :items_holder
|
45
50
|
delegate :tabs, to: :items_holder
|
46
51
|
delegate :tool, to: :items_holder
|
47
52
|
delegate :heading, to: :items_holder
|
@@ -96,6 +101,10 @@ module Avo
|
|
96
101
|
if item.is_field?
|
97
102
|
fields << item
|
98
103
|
end
|
104
|
+
|
105
|
+
if item.is_row?
|
106
|
+
fields << extract_fields_from_items(tab)
|
107
|
+
end
|
99
108
|
end
|
100
109
|
|
101
110
|
fields.flatten
|
@@ -213,8 +222,10 @@ module Avo
|
|
213
222
|
panelfull_items.grep(Avo::Resources::Items::TabGroup).each do |tab_group|
|
214
223
|
tab_group.items.grep(Avo::Resources::Items::Tab).each do |tab|
|
215
224
|
tab.items.grep(Avo::Resources::Items::Panel).each do |panel|
|
216
|
-
panel.items.grep(Avo::Fields::BelongsToField)
|
217
|
-
|
225
|
+
set_target_to_top panel.items.grep(Avo::Fields::BelongsToField)
|
226
|
+
|
227
|
+
panel.items.grep(Avo::Resources::Items::Row).each do |row|
|
228
|
+
set_target_to_top row.items.grep(Avo::Fields::BelongsToField)
|
218
229
|
end
|
219
230
|
end
|
220
231
|
end
|
@@ -250,9 +261,6 @@ module Avo
|
|
250
261
|
|
251
262
|
item
|
252
263
|
end
|
253
|
-
.select do |item|
|
254
|
-
item.visible_in_view?(view: view)
|
255
|
-
end
|
256
264
|
.select do |item|
|
257
265
|
item.visible?
|
258
266
|
end
|
@@ -264,7 +272,8 @@ module Avo
|
|
264
272
|
end
|
265
273
|
end
|
266
274
|
.select do |item|
|
267
|
-
|
275
|
+
# On location field we can have field coordinates and setters with different names like latitude and longitude
|
276
|
+
if !item.is_a?(Avo::Fields::LocationField) && !item.is_heading? && view.in?([:edit, :update, :new, :create])
|
268
277
|
if item.respond_to?(:id)
|
269
278
|
item.resource.record.respond_to?("#{item.id}=")
|
270
279
|
else
|
@@ -290,25 +299,21 @@ module Avo
|
|
290
299
|
visible_items.blank?
|
291
300
|
end
|
292
301
|
|
293
|
-
|
294
|
-
super(**args)
|
302
|
+
private
|
295
303
|
|
296
|
-
|
297
|
-
|
304
|
+
def set_target_to_top(fields)
|
305
|
+
fields.each do |field|
|
306
|
+
field.target = :_top
|
298
307
|
end
|
299
|
-
|
300
|
-
self
|
301
308
|
end
|
302
309
|
|
303
|
-
private
|
304
|
-
|
305
310
|
def extract_fields_from_items(thing)
|
306
311
|
fields = []
|
307
312
|
|
308
313
|
thing.items.each do |item|
|
309
314
|
if item.is_field?
|
310
315
|
fields << item
|
311
|
-
elsif item.is_panel?
|
316
|
+
elsif item.is_panel? || item.is_row?
|
312
317
|
fields << extract_fields_from_items(item)
|
313
318
|
end
|
314
319
|
end
|
data/lib/avo/current.rb
CHANGED
@@ -1,12 +1,39 @@
|
|
1
1
|
class Avo::Current < ActiveSupport::CurrentAttributes
|
2
|
+
# if Rails.env.development?
|
3
|
+
# singleton_class.attr_accessor :previous_attributes
|
4
|
+
# before_reset {
|
5
|
+
# puts ["before_reset->", self.previous_attributes].inspect
|
6
|
+
# if attributes.present?
|
7
|
+
# puts ["has attributes->"].inspect
|
8
|
+
# self.previous_attributes = attributes
|
9
|
+
# end
|
10
|
+
# puts ["before_reset->", self.previous_attributes].inspect
|
11
|
+
# }
|
12
|
+
|
13
|
+
# attr_accessor :previous_attributes
|
14
|
+
|
15
|
+
# def previous_attributes=(value)
|
16
|
+
# @previous_attributes = value
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
|
2
20
|
attribute :app
|
3
21
|
attribute :license
|
4
|
-
attribute :context, :
|
22
|
+
attribute :context, :user, :view_context
|
23
|
+
attribute :error_manager
|
24
|
+
attribute :resource_manager
|
25
|
+
attribute :tool_manager
|
26
|
+
attribute :plugin_manager
|
5
27
|
|
6
|
-
delegate :request, to: :view_context
|
7
28
|
delegate :params, to: :request
|
8
29
|
|
9
30
|
def request
|
10
31
|
view_context.request || ActionDispatch::Request.empty
|
11
32
|
end
|
33
|
+
|
34
|
+
def current_user
|
35
|
+
Rails.logger.warn "DEPRECATION WARNING: Avo::Current.current_user become deprecated and will become obsolete on futhure versions. Please use Avo::Current.user instead."
|
36
|
+
|
37
|
+
user
|
38
|
+
end
|
12
39
|
end
|
data/lib/avo/dsl/field_parser.rb
CHANGED
data/lib/avo/dynamic_router.rb
CHANGED
@@ -1,12 +1,23 @@
|
|
1
1
|
module Avo
|
2
2
|
class DynamicRouter
|
3
|
+
def self.eager_load(entity)
|
4
|
+
paths = Avo::ENTITIES.fetch entity
|
5
|
+
|
6
|
+
return unless paths.present?
|
7
|
+
|
8
|
+
pathname = Rails.root.join(*paths)
|
9
|
+
if pathname.directory?
|
10
|
+
Rails.autoloaders.main.eager_load_dir(pathname.to_s)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
3
14
|
def self.routes
|
4
15
|
Avo::Engine.routes.draw do
|
5
16
|
scope "resources", as: "resources" do
|
6
17
|
# Check if the user chose to manually register the resource files.
|
7
18
|
# If so, eager_load the resources dir.
|
8
19
|
if Avo.configuration.resources.nil?
|
9
|
-
Avo::
|
20
|
+
Avo::DynamicRouter.eager_load(:resources) unless Rails.application.config.eager_load
|
10
21
|
end
|
11
22
|
|
12
23
|
Avo::Resources::ResourceManager.fetch_resources
|
data/lib/avo/engine.rb
CHANGED
@@ -3,6 +3,8 @@ Gem.loaded_specs["avo"].dependencies.each do |d|
|
|
3
3
|
case d.name
|
4
4
|
when "activerecord"
|
5
5
|
require "active_record/railtie"
|
6
|
+
when "activesupport"
|
7
|
+
require "active_support/railtie"
|
6
8
|
when "actionview"
|
7
9
|
require "action_view/railtie"
|
8
10
|
when "activestorage"
|
@@ -23,7 +25,7 @@ module Avo
|
|
23
25
|
::Avo.asset_manager.reset
|
24
26
|
|
25
27
|
# Boot Avo
|
26
|
-
::Avo
|
28
|
+
::Avo.boot
|
27
29
|
|
28
30
|
# After deploy we want to make sure the license response is being cleared.
|
29
31
|
# We need a fresh license response.
|
@@ -40,7 +42,7 @@ module Avo
|
|
40
42
|
# Ensure we reboot the app when something changes
|
41
43
|
config.to_prepare do
|
42
44
|
# Boot Avo
|
43
|
-
::Avo
|
45
|
+
::Avo.boot
|
44
46
|
end
|
45
47
|
|
46
48
|
initializer "avo.autoload" do |app|
|
@@ -55,10 +57,6 @@ module Avo
|
|
55
57
|
end
|
56
58
|
end
|
57
59
|
|
58
|
-
initializer "avo.init_fields" do |app|
|
59
|
-
::Avo::App.init_fields
|
60
|
-
end
|
61
|
-
|
62
60
|
initializer "avo.reloader" do |app|
|
63
61
|
Avo::Reloader.new.tap do |reloader|
|
64
62
|
reloader.execute
|
@@ -94,7 +92,6 @@ module Avo
|
|
94
92
|
|
95
93
|
initializer "avo.locales" do |app|
|
96
94
|
I18n.load_path += Dir[Avo::Engine.root.join("lib", "generators", "avo", "templates", "locales", "*.{rb,yml}")]
|
97
|
-
I18n.load_path += Dir[Rails.root.join("config", "locales", "*.{rb,yml}")]
|
98
95
|
end
|
99
96
|
end
|
100
97
|
end
|
@@ -20,7 +20,7 @@ module Avo
|
|
20
20
|
|
21
21
|
# Set defaults on not initialized accessors
|
22
22
|
@context ||= Avo::Current.context
|
23
|
-
@current_user ||= Avo::Current.
|
23
|
+
@current_user ||= Avo::Current.user
|
24
24
|
@params ||= Avo::Current.params
|
25
25
|
@request ||= Avo::Current.request
|
26
26
|
@view_context ||= Avo::Current.view_context
|