avo 3.10.6 → 3.10.7
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.lock +2 -2
- data/README.md +4 -9
- 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.rb +1 -1
- data/app/components/avo/fields/common/boolean_group_component.html.erb +3 -6
- data/app/components/avo/resource_component.rb +0 -2
- data/app/components/avo/turbo_frame_wrapper_component.html.erb +1 -1
- data/app/controllers/avo/base_controller.rb +9 -2
- data/lib/avo/asset_manager.rb +8 -3
- data/lib/avo/base_resource.rb +2 -601
- data/lib/avo/fields/boolean_group_field.rb +1 -1
- data/lib/avo/licensing/request.rb +3 -1
- data/lib/avo/resources/base.rb +607 -0
- data/lib/avo/resources/items/item_group.rb +2 -0
- data/lib/avo/resources/items/tab.rb +2 -0
- data/lib/avo/version.rb +1 -1
- data/lib/avo.rb +1 -0
- data/lib/generators/avo/eject_generator.rb +1 -1
- data/lib/generators/avo/templates/locales/avo.de.yml +120 -0
- data/lib/generators/avo/templates/locales/avo.it.yml +120 -0
- data/lib/generators/avo/templates/locales/avo.nl.yml +120 -0
- data/lib/generators/avo/templates/locales/avo.pl.yml +120 -0
- data/lib/generators/avo/templates/locales/avo.ru.yml +120 -0
- data/lib/generators/avo/templates/locales/avo.uk.yml +120 -0
- data/lib/generators/avo/templates/locales/avo.zh.yml +120 -0
- data/public/avo-assets/avo.base.css +3 -71
- data/public/avo-assets/avo.base.js +230 -227
- data/public/avo-assets/avo.base.js.map +4 -4
- data/public/avo-assets/logo-on-white.png +0 -0
- metadata +10 -2
data/lib/avo/base_resource.rb
CHANGED
@@ -1,604 +1,5 @@
|
|
1
1
|
module Avo
|
2
|
-
class BaseResource
|
3
|
-
|
4
|
-
|
5
|
-
include ActionView::Helpers::UrlHelper
|
6
|
-
include Avo::Concerns::HasItems
|
7
|
-
include Avo::Concerns::CanReplaceItems
|
8
|
-
include Avo::Concerns::HasControls
|
9
|
-
include Avo::Concerns::HasResourceStimulusControllers
|
10
|
-
include Avo::Concerns::ModelClassConstantized
|
11
|
-
include Avo::Concerns::HasDescription
|
12
|
-
include Avo::Concerns::HasCoverPhoto
|
13
|
-
include Avo::Concerns::HasProfilePhoto
|
14
|
-
include Avo::Concerns::HasHelpers
|
15
|
-
include Avo::Concerns::Hydration
|
16
|
-
include Avo::Concerns::Pagination
|
17
|
-
|
18
|
-
# Avo::Current methods
|
19
|
-
delegate :context, to: Avo::Current
|
20
|
-
def current_user
|
21
|
-
Avo::Current.user
|
22
|
-
end
|
23
|
-
delegate :params, to: Avo::Current
|
24
|
-
delegate :request, to: Avo::Current
|
25
|
-
delegate :view_context, to: Avo::Current
|
26
|
-
|
27
|
-
# view_context methods
|
28
|
-
delegate :simple_format, :content_tag, to: :view_context
|
29
|
-
delegate :main_app, to: :view_context
|
30
|
-
delegate :avo, to: :view_context
|
31
|
-
delegate :resource_path, to: :view_context
|
32
|
-
delegate :resources_path, to: :view_context
|
33
|
-
|
34
|
-
# I18n methods
|
35
|
-
delegate :t, to: ::I18n
|
36
|
-
|
37
|
-
# class methods
|
38
|
-
delegate :class_name, to: :class
|
39
|
-
delegate :route_key, to: :class
|
40
|
-
delegate :singular_route_key, to: :class
|
41
|
-
|
42
|
-
attr_accessor :view
|
43
|
-
attr_accessor :reflection
|
44
|
-
attr_accessor :user
|
45
|
-
attr_accessor :record
|
46
|
-
|
47
|
-
class_attribute :id, default: :id
|
48
|
-
class_attribute :title
|
49
|
-
class_attribute :search, default: {}
|
50
|
-
class_attribute :includes, default: []
|
51
|
-
class_attribute :attachments, default: []
|
52
|
-
class_attribute :single_includes, default: []
|
53
|
-
class_attribute :single_attachments, default: []
|
54
|
-
class_attribute :authorization_policy
|
55
|
-
class_attribute :translation_key
|
56
|
-
class_attribute :default_view_type, default: :table
|
57
|
-
class_attribute :devise_password_optional, default: false
|
58
|
-
class_attribute :scopes_loader
|
59
|
-
class_attribute :filters_loader
|
60
|
-
class_attribute :view_types
|
61
|
-
class_attribute :grid_view
|
62
|
-
class_attribute :visible_on_sidebar, default: true
|
63
|
-
class_attribute :index_query, default: -> {
|
64
|
-
query
|
65
|
-
}
|
66
|
-
class_attribute :find_record_method, default: -> {
|
67
|
-
query.find id
|
68
|
-
}
|
69
|
-
class_attribute :after_create_path, default: :show
|
70
|
-
class_attribute :after_update_path, default: :show
|
71
|
-
class_attribute :record_selector, default: true
|
72
|
-
class_attribute :keep_filters_panel_open, default: false
|
73
|
-
class_attribute :extra_params
|
74
|
-
class_attribute :link_to_child_resource, default: false
|
75
|
-
class_attribute :map_view
|
76
|
-
class_attribute :components, default: {}
|
77
|
-
|
78
|
-
# EXTRACT:
|
79
|
-
class_attribute :ordering
|
80
|
-
|
81
|
-
class << self
|
82
|
-
delegate :t, to: ::I18n
|
83
|
-
delegate :context, to: ::Avo::Current
|
84
|
-
|
85
|
-
def action(action_class, arguments: {})
|
86
|
-
deprecated_dsl_api __method__, "actions"
|
87
|
-
end
|
88
|
-
|
89
|
-
def filter(filter_class, arguments: {})
|
90
|
-
deprecated_dsl_api __method__, "filters"
|
91
|
-
end
|
92
|
-
|
93
|
-
def scope(scope_class)
|
94
|
-
deprecated_dsl_api __method__, "scopes"
|
95
|
-
end
|
96
|
-
|
97
|
-
# This resolves the scope when doing "where" queries (not find queries)
|
98
|
-
#
|
99
|
-
# It's used to apply the authorization feature.
|
100
|
-
def query_scope
|
101
|
-
authorization.apply_policy Avo::ExecutionContext.new(
|
102
|
-
target: index_query,
|
103
|
-
query: model_class
|
104
|
-
).handle
|
105
|
-
end
|
106
|
-
|
107
|
-
# This resolves the scope when finding records (not "where" queries)
|
108
|
-
#
|
109
|
-
# It's used to apply the authorization feature.
|
110
|
-
def find_scope
|
111
|
-
authorization.apply_policy model_class
|
112
|
-
end
|
113
|
-
|
114
|
-
def authorization
|
115
|
-
Avo::Services::AuthorizationService.new Avo::Current.user, model_class, policy_class: authorization_policy
|
116
|
-
end
|
117
|
-
|
118
|
-
def valid_association_name(record, association_name)
|
119
|
-
association_name if record._reflections.with_indifferent_access[association_name].present?
|
120
|
-
end
|
121
|
-
|
122
|
-
def valid_attachment_name(record, association_name)
|
123
|
-
association_name if record.class.reflect_on_attachment(association_name).present?
|
124
|
-
end
|
125
|
-
|
126
|
-
def get_available_models
|
127
|
-
ApplicationRecord.descendants
|
128
|
-
end
|
129
|
-
|
130
|
-
def get_model_by_name(model_name)
|
131
|
-
get_available_models.find do |m|
|
132
|
-
m.to_s == model_name.to_s
|
133
|
-
end
|
134
|
-
end
|
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_key ||= model_class.model_name.plural
|
157
|
-
end
|
158
|
-
|
159
|
-
def class_name
|
160
|
-
@class_name ||= to_s.demodulize
|
161
|
-
end
|
162
|
-
|
163
|
-
def route_key
|
164
|
-
class_name.underscore.pluralize
|
165
|
-
end
|
166
|
-
|
167
|
-
def singular_route_key
|
168
|
-
route_key.singularize
|
169
|
-
end
|
170
|
-
|
171
|
-
def translation_key
|
172
|
-
@translation_key || "avo.resource_translations.#{class_name.underscore}"
|
173
|
-
end
|
174
|
-
|
175
|
-
def name
|
176
|
-
@name ||= name_from_translation_key(count: 1, default: class_name.underscore.humanize)
|
177
|
-
end
|
178
|
-
alias_method :singular_name, :name
|
179
|
-
|
180
|
-
def plural_name
|
181
|
-
name_from_translation_key(count: 2, default: name.pluralize)
|
182
|
-
end
|
183
|
-
|
184
|
-
# Get the name from the translation_key and fallback to default
|
185
|
-
# It can raise I18n::InvalidPluralizationData when using only resource_translation without pluralization keys like: one, two or other key
|
186
|
-
# Example:
|
187
|
-
# ---
|
188
|
-
# en:
|
189
|
-
# avo:
|
190
|
-
# resource_translations:
|
191
|
-
# product:
|
192
|
-
# save: "Save product"
|
193
|
-
def name_from_translation_key(count:, default:)
|
194
|
-
t(translation_key, count:, default:).humanize
|
195
|
-
rescue I18n::InvalidPluralizationData
|
196
|
-
default
|
197
|
-
end
|
198
|
-
|
199
|
-
def underscore_name
|
200
|
-
return @name if @name.present?
|
201
|
-
|
202
|
-
name.demodulize.underscore
|
203
|
-
end
|
204
|
-
|
205
|
-
def navigation_label
|
206
|
-
plural_name.humanize
|
207
|
-
end
|
208
|
-
|
209
|
-
def find_record(id, query: nil, params: nil)
|
210
|
-
query ||= find_scope # If no record is given we'll use the default
|
211
|
-
|
212
|
-
if single_includes.present?
|
213
|
-
query = query.includes(*single_includes)
|
214
|
-
end
|
215
|
-
|
216
|
-
if single_attachments.present?
|
217
|
-
single_attachments.each do |attachment|
|
218
|
-
query = query.send(:"with_attached_#{attachment}")
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
Avo::ExecutionContext.new(
|
223
|
-
target: find_record_method,
|
224
|
-
query: query,
|
225
|
-
id: id,
|
226
|
-
params: params
|
227
|
-
).handle
|
228
|
-
end
|
229
|
-
|
230
|
-
def search_query
|
231
|
-
search.dig(:query)
|
232
|
-
end
|
233
|
-
|
234
|
-
def search_results_count
|
235
|
-
search.dig(:results_count)
|
236
|
-
end
|
237
|
-
|
238
|
-
def fetch_search(key, record: nil)
|
239
|
-
# self.class.fetch_search
|
240
|
-
Avo::ExecutionContext.new(target: search[key], resource: self, record: record).handle
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
delegate :context, to: ::Avo::Current
|
245
|
-
delegate :name, to: :class
|
246
|
-
delegate :singular_name, to: :class
|
247
|
-
delegate :plural_name, to: :class
|
248
|
-
delegate :underscore_name, to: :class
|
249
|
-
delegate :to_param, to: :class
|
250
|
-
delegate :find_record, to: :class
|
251
|
-
delegate :model_key, to: :class
|
252
|
-
delegate :tab, to: :items_holder
|
253
|
-
|
254
|
-
def initialize(record: nil, view: nil, user: nil, params: nil)
|
255
|
-
@view = Avo::ViewInquirer.new(view) if view.present?
|
256
|
-
@user = user if user.present?
|
257
|
-
@params = params if params.present?
|
258
|
-
|
259
|
-
if record.present?
|
260
|
-
@record = record
|
261
|
-
|
262
|
-
hydrate_model_with_default_values if @view&.new?
|
263
|
-
end
|
264
|
-
|
265
|
-
unless self.class.model_class.present?
|
266
|
-
if model_class.present? && model_class.respond_to?(:base_class)
|
267
|
-
self.class.model_class = model_class.base_class
|
268
|
-
end
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
def detect_fields
|
273
|
-
self.items_holder = Avo::Resources::Items::Holder.new(parent: self)
|
274
|
-
|
275
|
-
# Used in testing to replace items
|
276
|
-
if temporary_items.present?
|
277
|
-
instance_eval(&temporary_items)
|
278
|
-
else
|
279
|
-
fetch_fields
|
280
|
-
end
|
281
|
-
|
282
|
-
self
|
283
|
-
end
|
284
|
-
|
285
|
-
VIEW_METHODS_MAPPING = {
|
286
|
-
index: [:index_fields, :display_fields],
|
287
|
-
show: [:show_fields, :display_fields],
|
288
|
-
edit: [:edit_fields, :form_fields],
|
289
|
-
update: [:edit_fields, :form_fields],
|
290
|
-
new: [:new_fields, :form_fields],
|
291
|
-
create: [:new_fields, :form_fields]
|
292
|
-
} unless defined? VIEW_METHODS_MAPPING
|
293
|
-
|
294
|
-
def fetch_fields
|
295
|
-
possible_methods_for_view = VIEW_METHODS_MAPPING[view.to_sym]
|
296
|
-
|
297
|
-
# Safe navigation operator is used because the view can be "destroy" or "preview"
|
298
|
-
possible_methods_for_view&.each do |method_for_view|
|
299
|
-
return send(method_for_view) if respond_to?(method_for_view)
|
300
|
-
end
|
301
|
-
|
302
|
-
fields
|
303
|
-
end
|
304
|
-
|
305
|
-
def fetch_cards
|
306
|
-
cards
|
307
|
-
end
|
308
|
-
|
309
|
-
def divider(label = nil)
|
310
|
-
entity_loader(:action).use({class: Divider, label: label}.compact)
|
311
|
-
end
|
312
|
-
|
313
|
-
# def fields / def cards
|
314
|
-
[:fields, :cards].each do |method_name|
|
315
|
-
define_method method_name do
|
316
|
-
# Empty method
|
317
|
-
end
|
318
|
-
end
|
319
|
-
|
320
|
-
[:action, :filter, :scope].each do |entity|
|
321
|
-
plural_entity = entity.to_s.pluralize
|
322
|
-
|
323
|
-
# def actions / def filters / def scopes
|
324
|
-
define_method plural_entity do
|
325
|
-
# blank entity method
|
326
|
-
end
|
327
|
-
|
328
|
-
# def action / def filter / def scope
|
329
|
-
define_method entity do |entity_class, arguments: {}, icon: nil|
|
330
|
-
entity_loader(entity).use({class: entity_class, arguments: arguments, icon: icon}.compact)
|
331
|
-
end
|
332
|
-
|
333
|
-
# def get_actions / def get_filters / def get_scopes
|
334
|
-
define_method "get_#{plural_entity}" do
|
335
|
-
return entity_loader(entity).bag if entity_loader(entity).present?
|
336
|
-
|
337
|
-
# ex: @actions_loader = Avo::Loaders::ActionsLoader.new
|
338
|
-
instance_variable_set(
|
339
|
-
"@#{plural_entity}_loader",
|
340
|
-
"Avo::Loaders::#{plural_entity.humanize}Loader".constantize.new
|
341
|
-
)
|
342
|
-
|
343
|
-
send plural_entity
|
344
|
-
|
345
|
-
entity_loader(entity).bag
|
346
|
-
end
|
347
|
-
|
348
|
-
# def get_action_arguments / def get_filter_arguments / def get_scope_arguments
|
349
|
-
define_method "get_#{entity}_arguments" do |entity_class|
|
350
|
-
klass = send("get_#{plural_entity}").find { |entity| entity[:class].to_s == entity_class.to_s }
|
351
|
-
|
352
|
-
raise "Couldn't find '#{entity_class}' in the 'def #{plural_entity}' method on your '#{self.class}' resource." if klass.nil?
|
353
|
-
|
354
|
-
klass[:arguments]
|
355
|
-
end
|
356
|
-
end
|
357
|
-
|
358
|
-
def hydrate(...)
|
359
|
-
super(...)
|
360
|
-
|
361
|
-
if @record.present?
|
362
|
-
hydrate_model_with_default_values if @view&.new?
|
363
|
-
end
|
364
|
-
|
365
|
-
self
|
366
|
-
end
|
367
|
-
|
368
|
-
def default_panel_name
|
369
|
-
return @params[:related_name].capitalize if @params.present? && @params[:related_name].present?
|
370
|
-
|
371
|
-
case @view.to_sym
|
372
|
-
when :show
|
373
|
-
record_title
|
374
|
-
when :edit
|
375
|
-
record_title
|
376
|
-
when :new
|
377
|
-
t("avo.create_new_item", item: name.humanize(capitalize: false)).upcase_first
|
378
|
-
end
|
379
|
-
end
|
380
|
-
|
381
|
-
# Returns the model class being used for this resource.
|
382
|
-
#
|
383
|
-
# We use the class method as a fallback but we pass it the record too so it can support the STI use cases
|
384
|
-
# where we figure out the model class from that record.
|
385
|
-
def model_class
|
386
|
-
record_class = @record&.class
|
387
|
-
|
388
|
-
self.class.model_class record_class: record_class
|
389
|
-
end
|
390
|
-
|
391
|
-
def record_title
|
392
|
-
return name if @record.nil?
|
393
|
-
|
394
|
-
# Get the title from the record if title is not set, try to get the name, title or label, or fallback to the id
|
395
|
-
return @record.try(:name) || @record.try(:title) || @record.try(:label) || @record.id if title.nil?
|
396
|
-
|
397
|
-
# If the title is a symbol, get the value from the record else execute the block/string
|
398
|
-
case title
|
399
|
-
when Symbol
|
400
|
-
@record.send title
|
401
|
-
when Proc
|
402
|
-
Avo::ExecutionContext.new(target: title, resource: self, record: @record).handle
|
403
|
-
end
|
404
|
-
end
|
405
|
-
|
406
|
-
def available_view_types
|
407
|
-
if self.class.view_types.present?
|
408
|
-
return Array(
|
409
|
-
Avo::ExecutionContext.new(
|
410
|
-
target: self.class.view_types,
|
411
|
-
resource: self,
|
412
|
-
record: record
|
413
|
-
).handle
|
414
|
-
)
|
415
|
-
end
|
416
|
-
|
417
|
-
view_types = [:table]
|
418
|
-
|
419
|
-
view_types << :grid if self.class.grid_view.present?
|
420
|
-
view_types << :map if map_view.present?
|
421
|
-
|
422
|
-
view_types
|
423
|
-
end
|
424
|
-
|
425
|
-
def attachment_fields
|
426
|
-
get_field_definitions.select do |field|
|
427
|
-
[Avo::Fields::FileField, Avo::Fields::FilesField].include? field.class
|
428
|
-
end
|
429
|
-
end
|
430
|
-
|
431
|
-
# Map the received params to their actual fields
|
432
|
-
def fields_by_database_id
|
433
|
-
get_field_definitions
|
434
|
-
.reject do |field|
|
435
|
-
field.computed
|
436
|
-
end
|
437
|
-
.map do |field|
|
438
|
-
[field.database_id.to_s, field]
|
439
|
-
end
|
440
|
-
.to_h
|
441
|
-
end
|
442
|
-
|
443
|
-
def fill_record(record, params, extra_params: [])
|
444
|
-
# Write the field values
|
445
|
-
params.each do |key, value|
|
446
|
-
field = fields_by_database_id[key]
|
447
|
-
|
448
|
-
next unless field.present?
|
449
|
-
|
450
|
-
record = field.fill_field record, key, value, params
|
451
|
-
end
|
452
|
-
|
453
|
-
# Write the user configured extra params to the record
|
454
|
-
if extra_params.present?
|
455
|
-
# Let Rails fill in the rest of the params
|
456
|
-
record.assign_attributes params.permit(extra_params)
|
457
|
-
end
|
458
|
-
|
459
|
-
record
|
460
|
-
end
|
461
|
-
|
462
|
-
def authorization(user: nil)
|
463
|
-
current_user = user || Avo::Current.user
|
464
|
-
Avo::Services::AuthorizationService.new(current_user, record || model_class, policy_class: authorization_policy)
|
465
|
-
end
|
466
|
-
|
467
|
-
def file_hash
|
468
|
-
content_to_be_hashed = ""
|
469
|
-
|
470
|
-
resource_path = Rails.root.join("app", "avo", "resources", "#{file_name}.rb").to_s
|
471
|
-
if File.file? resource_path
|
472
|
-
content_to_be_hashed += File.read(resource_path)
|
473
|
-
end
|
474
|
-
|
475
|
-
# policy file hash
|
476
|
-
policy_path = Rails.root.join("app", "policies", "#{file_name.gsub("_resource", "")}_policy.rb").to_s
|
477
|
-
if File.file? policy_path
|
478
|
-
content_to_be_hashed += File.read(policy_path)
|
479
|
-
end
|
480
|
-
|
481
|
-
Digest::MD5.hexdigest(content_to_be_hashed)
|
482
|
-
end
|
483
|
-
|
484
|
-
def file_name
|
485
|
-
@file_name ||= self.class.underscore_name.tr(" ", "_")
|
486
|
-
end
|
487
|
-
|
488
|
-
def cache_hash(parent_record)
|
489
|
-
result = [record, file_hash]
|
490
|
-
|
491
|
-
if parent_record.present?
|
492
|
-
result << parent_record
|
493
|
-
end
|
494
|
-
|
495
|
-
result
|
496
|
-
end
|
497
|
-
|
498
|
-
# We will not overwrite any attributes that come pre-filled in the record.
|
499
|
-
def hydrate_model_with_default_values
|
500
|
-
default_values = get_fields
|
501
|
-
.select do |field|
|
502
|
-
!field.computed && !field.is_a?(Avo::Fields::HeadingField)
|
503
|
-
end
|
504
|
-
.map do |field|
|
505
|
-
value = field.value
|
506
|
-
|
507
|
-
if field.type == "belongs_to"
|
508
|
-
|
509
|
-
reflection = @record._reflections.with_indifferent_access[@params[:via_relation]]
|
510
|
-
|
511
|
-
if field.polymorphic_as.present? && field.types.map(&:to_s).include?(@params[:via_relation_class])
|
512
|
-
# set the value to the actual record
|
513
|
-
via_resource = Avo.resource_manager.get_resource_by_model_class(@params[:via_relation_class])
|
514
|
-
value = via_resource.find_record(@params[:via_record_id])
|
515
|
-
elsif reflection.present? && reflection.foreign_key.present? && field.id.to_s == @params[:via_relation].to_s
|
516
|
-
resource = Avo.resource_manager.get_resource_by_model_class params[:via_relation_class]
|
517
|
-
record = resource.find_record @params[:via_record_id], params: params
|
518
|
-
id_param = reflection.options[:primary_key] || :id
|
519
|
-
|
520
|
-
value = record.send(id_param)
|
521
|
-
end
|
522
|
-
end
|
523
|
-
|
524
|
-
[field, value]
|
525
|
-
end
|
526
|
-
.to_h
|
527
|
-
.select do |_, value|
|
528
|
-
value.present?
|
529
|
-
end
|
530
|
-
|
531
|
-
default_values.each do |field, value|
|
532
|
-
field.assign_value record: @record, value: value
|
533
|
-
end
|
534
|
-
end
|
535
|
-
|
536
|
-
def model_name
|
537
|
-
model_class.model_name
|
538
|
-
end
|
539
|
-
|
540
|
-
def singular_model_key
|
541
|
-
model_class.model_name.singular
|
542
|
-
end
|
543
|
-
|
544
|
-
def record_path
|
545
|
-
resource_path(record: record, resource: self)
|
546
|
-
end
|
547
|
-
|
548
|
-
def records_path
|
549
|
-
resources_path(resource: self)
|
550
|
-
end
|
551
|
-
|
552
|
-
def avatar_field
|
553
|
-
get_field_definitions.find do |field|
|
554
|
-
field.as_avatar.present?
|
555
|
-
end
|
556
|
-
rescue
|
557
|
-
nil
|
558
|
-
end
|
559
|
-
|
560
|
-
def avatar
|
561
|
-
return avatar_field.to_image if avatar_field.respond_to? :to_image
|
562
|
-
|
563
|
-
return avatar_field.value.variant(resize_to_limit: [480, 480]) if avatar_field.type == "file"
|
564
|
-
|
565
|
-
avatar_field.value
|
566
|
-
rescue
|
567
|
-
nil
|
568
|
-
end
|
569
|
-
|
570
|
-
def avatar_type
|
571
|
-
avatar_field.as_avatar
|
572
|
-
rescue
|
573
|
-
nil
|
574
|
-
end
|
575
|
-
|
576
|
-
def form_scope
|
577
|
-
model_class.base_class.to_s.underscore.downcase
|
578
|
-
end
|
579
|
-
|
580
|
-
def has_record_id?
|
581
|
-
record.present? && record_id.present?
|
582
|
-
end
|
583
|
-
|
584
|
-
def id_attribute
|
585
|
-
:id
|
586
|
-
end
|
587
|
-
|
588
|
-
def record_id
|
589
|
-
record.send(id_attribute)
|
590
|
-
end
|
591
|
-
|
592
|
-
def description_attributes
|
593
|
-
{
|
594
|
-
view: view,
|
595
|
-
resource: self,
|
596
|
-
record: record
|
597
|
-
}
|
598
|
-
end
|
599
|
-
|
600
|
-
def entity_loader(entity)
|
601
|
-
instance_variable_get("@#{entity.to_s.pluralize}_loader")
|
602
|
-
end
|
2
|
+
class BaseResource < Avo::Resources::Base
|
3
|
+
# Users can override this class to add custom methods for all resources.
|
603
4
|
end
|
604
5
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "net/http"
|
2
|
+
|
1
3
|
module Avo
|
2
4
|
module Licensing
|
3
5
|
class Request
|
@@ -8,7 +10,7 @@ module Avo
|
|
8
10
|
http.use_ssl = (uri.scheme == "https")
|
9
11
|
http.read_timeout = timeout
|
10
12
|
http.open_timeout = timeout
|
11
|
-
request = Net::HTTP::Post.new(uri.request_uri, {
|
13
|
+
request = Net::HTTP::Post.new(uri.request_uri, {"Content-Type" => "application/json"})
|
12
14
|
request.body = body
|
13
15
|
http.request(request)
|
14
16
|
end
|