avo 0.5.0.beta4 → 0.5.0.beta5
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 +4 -2
- data/Gemfile.lock +1 -1
- data/app/components/avo/index/grid_item_component.html.erb +8 -8
- data/app/components/avo/index/grid_item_component.rb +6 -12
- data/app/components/avo/index/resource_table_component.html.erb +1 -1
- data/app/components/avo/index/table_row_component.html.erb +1 -1
- data/app/controllers/avo/actions_controller.rb +2 -4
- data/app/controllers/avo/application_controller.rb +6 -3
- data/app/controllers/avo/base_controller.rb +0 -3
- data/app/controllers/avo/relations_controller.rb +1 -1
- data/app/controllers/avo/search_controller.rb +1 -1
- data/app/frontend/packs/application.js +1 -1
- data/app/views/avo/base/_actions.html.erb +0 -6
- data/app/views/avo/base/_boolean_filter.html.erb +1 -1
- data/app/views/avo/base/_filters.html.erb +3 -11
- data/app/views/avo/base/_select_filter.html.erb +1 -1
- data/app/views/avo/home/_resources.html.erb +0 -1
- data/app/views/layouts/avo/_filter_wrapper.html.erb +1 -1
- data/app/views/layouts/avo/application.html.erb +5 -0
- data/config/webpacker.yml +10 -23
- data/lib/avo.rb +5 -16
- data/lib/avo/app.rb +190 -0
- data/lib/avo/base_action.rb +115 -0
- data/lib/avo/base_resource.rb +321 -0
- data/lib/avo/configuration.rb +6 -0
- data/lib/avo/engine.rb +12 -31
- data/lib/avo/{app/fields → fields}/badge_field.rb +1 -1
- data/lib/avo/{app/fields/field.rb → fields/base_field.rb} +3 -7
- data/lib/avo/{app/fields/belongs_to.rb → fields/belongs_to_field.rb} +3 -3
- data/lib/avo/{app/fields → fields}/boolean_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/boolean_group_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/code_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/country_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/currency_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/date_field.rb +0 -2
- data/lib/avo/{app/fields → fields}/date_time_field.rb +0 -2
- data/lib/avo/{app/fields → fields}/external_image_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/field_extensions/has_field_name.rb +0 -0
- data/lib/avo/{app/fields → fields}/field_extensions/visible_in_different_views.rb +1 -1
- data/lib/avo/{app/fields → fields}/file_field.rb +1 -2
- data/lib/avo/{app/fields → fields}/files_field.rb +1 -2
- data/lib/avo/{app/fields → fields}/gravatar_field.rb +1 -1
- data/lib/avo/{app/fields/has_and_belongs_to_many.rb → fields/has_and_belongs_to_many_field.rb} +1 -1
- data/lib/avo/{app/fields/has_many.rb → fields/has_many_field.rb} +1 -1
- data/lib/avo/{app/fields/has_one.rb → fields/has_one_field.rb} +1 -1
- data/lib/avo/{app/fields → fields}/heading_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/hidden_field.rb +0 -2
- data/lib/avo/{app/fields → fields}/id_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/key_value_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/markdown_field.rb +1 -3
- data/lib/avo/{app/fields → fields}/number_field.rb +0 -2
- data/lib/avo/{app/fields → fields}/password_field.rb +0 -2
- data/lib/avo/{app/fields → fields}/select_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/status_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/text_field.rb +1 -1
- data/lib/avo/{app/fields → fields}/textarea_field.rb +0 -2
- data/lib/avo/{app/fields → fields}/trix_field.rb +1 -3
- data/lib/avo/filters/base_filter.rb +20 -0
- data/lib/avo/filters/boolean_filter.rb +7 -0
- data/lib/avo/filters/select_filter.rb +7 -0
- data/lib/avo/{app/grid_fields → grid_fields}/body_field.rb +0 -2
- data/lib/avo/{app/grid_fields → grid_fields}/grid_field.rb +0 -0
- data/lib/avo/{app/grid_fields → grid_fields}/preview_field.rb +0 -2
- data/lib/avo/{app/grid_fields → grid_fields}/title_field.rb +0 -2
- data/lib/avo/licensing/community_license.rb +6 -0
- data/lib/avo/licensing/h_q.rb +88 -0
- data/lib/avo/licensing/license.rb +50 -0
- data/lib/avo/licensing/license_manager.rb +22 -0
- data/lib/avo/licensing/null_license.rb +14 -0
- data/lib/avo/licensing/pro_license.rb +11 -0
- data/lib/avo/loaders/actions_loader.rb +6 -0
- data/lib/avo/loaders/fields_loader.rb +27 -0
- data/lib/avo/loaders/filters_loader.rb +6 -0
- data/lib/avo/loaders/loader.rb +15 -0
- data/lib/avo/services/authorization_service.rb +93 -0
- data/lib/avo/services/panel_service.rb +27 -0
- data/lib/avo/{app/tools_manager.rb → tools_manager.rb} +0 -0
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/action_generator.rb +11 -5
- data/lib/generators/avo/controller_generator.rb +14 -8
- data/lib/generators/avo/filter_generator.rb +14 -8
- data/lib/generators/avo/install_generator.rb +14 -10
- data/lib/generators/avo/locales_generator.rb +11 -7
- data/lib/generators/avo/partials_generator.rb +11 -5
- data/lib/generators/avo/resource_generator.rb +33 -15
- data/lib/generators/avo/templates/{action.rb → action.tt} +2 -4
- data/lib/generators/avo/templates/filters/boolean_filter.tt +11 -0
- data/lib/generators/avo/templates/filters/select_filter.tt +11 -0
- data/lib/generators/avo/templates/initializer/{avo.rb → avo.tt} +6 -0
- data/lib/generators/avo/templates/resource/controller.tt +2 -0
- data/lib/generators/avo/templates/resource/resource.tt +17 -0
- data/public/avo-packs/css/{application-3598cfbb.css → application-c75ac28c.css} +1 -1
- data/public/avo-packs/css/application-c75ac28c.css.br +0 -0
- data/public/avo-packs/css/{application-3598cfbb.css.gz → application-c75ac28c.css.gz} +0 -0
- data/public/avo-packs/js/{application-6ba2bd1bca05d69b96e0.js → application-8849c6e2c8f75d55c666.js} +3 -3
- data/public/avo-packs/js/{application-6ba2bd1bca05d69b96e0.js.LICENSE.txt → application-8849c6e2c8f75d55c666.js.LICENSE.txt} +0 -0
- data/public/avo-packs/js/application-8849c6e2c8f75d55c666.js.br +0 -0
- data/public/avo-packs/js/application-8849c6e2c8f75d55c666.js.gz +0 -0
- data/public/avo-packs/js/{application-6ba2bd1bca05d69b96e0.js.map → application-8849c6e2c8f75d55c666.js.map} +1 -1
- data/public/avo-packs/js/application-8849c6e2c8f75d55c666.js.map.br +0 -0
- data/public/avo-packs/js/{application-6ba2bd1bca05d69b96e0.js.map.gz → application-8849c6e2c8f75d55c666.js.map.gz} +0 -0
- data/public/avo-packs/manifest.json +6 -6
- data/public/avo-packs/manifest.json.br +0 -0
- data/public/avo-packs/manifest.json.gz +0 -0
- metadata +72 -73
- data/config/webpacker_packed.yml +0 -86
- data/lib/avo/app/action.rb +0 -145
- data/lib/avo/app/actions_loader.rb +0 -11
- data/lib/avo/app/app.rb +0 -183
- data/lib/avo/app/fields_loader.rb +0 -29
- data/lib/avo/app/filter.rb +0 -23
- data/lib/avo/app/filters/boolean_filter.rb +0 -13
- data/lib/avo/app/filters/select_filter.rb +0 -13
- data/lib/avo/app/licensing/community_license.rb +0 -4
- data/lib/avo/app/licensing/hq.rb +0 -86
- data/lib/avo/app/licensing/license.rb +0 -48
- data/lib/avo/app/licensing/license_manager.rb +0 -25
- data/lib/avo/app/licensing/null_license.rb +0 -12
- data/lib/avo/app/licensing/pro_license.rb +0 -9
- data/lib/avo/app/resource.rb +0 -299
- data/lib/avo/app/resource_grid_fields.rb +0 -30
- data/lib/avo/app/services/authorization_service.rb +0 -110
- data/lib/avo/app/services/panel_service.rb +0 -25
- data/lib/avo/app/tool.rb +0 -5
- data/lib/generators/avo/templates/filters/boolean_filter.rb +0 -17
- data/lib/generators/avo/templates/filters/select_filter.rb +0 -17
- data/lib/generators/avo/templates/resource/%plural_name%_controller.tt +0 -2
- data/lib/generators/avo/templates/resource/%singular_name%.tt +0 -20
- data/public/avo-packs/css/application-3598cfbb.css.br +0 -0
- data/public/avo-packs/js/application-6ba2bd1bca05d69b96e0.js.br +0 -0
- data/public/avo-packs/js/application-6ba2bd1bca05d69b96e0.js.gz +0 -0
- data/public/avo-packs/js/application-6ba2bd1bca05d69b96e0.js.map.br +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e9ed4bc1c98f78365b9b2a50dda9ed809b6c598c2d0b745e6f706f3456974532
|
4
|
+
data.tar.gz: 71cf2d32d71b19316e36cc2e4a7688d2581f668044ac2975a786c3ce753b11a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 19ecbf7fb7b632eb4e00d17c88eff0f613ed03051f9b527313515b953c31c847f6328a4faa58ae6a2eb87ceab94ab62cf4be3c0d89efd6f74669fa403bb73b74
|
7
|
+
data.tar.gz: 61d6eef278896616b12cc4b3d3b996de8068ba93e7017a06885871f7d8a15b365621762360c2577ec5691cd37ab643a8e34318efc7be3ee99429e38ce6947dc8
|
data/Gemfile
CHANGED
@@ -78,7 +78,6 @@ group :development do
|
|
78
78
|
# Release helper
|
79
79
|
gem 'bump', require: false
|
80
80
|
gem 'gem-release', require: false
|
81
|
-
gem 'faker', require: false
|
82
81
|
|
83
82
|
# gem 'rack-mini-profiler'
|
84
83
|
# gem 'memory_profiler'
|
@@ -89,6 +88,10 @@ group :development do
|
|
89
88
|
# gem 'pry-rails'
|
90
89
|
end
|
91
90
|
|
91
|
+
group :development, :test do
|
92
|
+
gem 'faker', require: false
|
93
|
+
end
|
94
|
+
|
92
95
|
group :test do
|
93
96
|
gem 'rspec-rails', '~> 4.0.0'
|
94
97
|
gem 'rails-controller-testing'
|
@@ -97,7 +100,6 @@ group :test do
|
|
97
100
|
gem 'selenium-webdriver'
|
98
101
|
# Easy installation and use of web drivers to run system tests with browsers
|
99
102
|
gem 'webdrivers'
|
100
|
-
# gem 'faker'
|
101
103
|
gem 'fuubar'
|
102
104
|
gem 'simplecov', require: false
|
103
105
|
gem 'simplecov-cobertura'
|
data/Gemfile.lock
CHANGED
@@ -4,19 +4,19 @@
|
|
4
4
|
<div class="relative w-full pb-3/4 rounded-t-xl overflow-hidden">
|
5
5
|
<%== item_selector_input floating: true, size: :lg %>
|
6
6
|
|
7
|
-
<% if
|
8
|
-
<%= link_to_if
|
9
|
-
<% elsif
|
10
|
-
<% if
|
11
|
-
<%= link_to_if
|
7
|
+
<% if cover.respond_to? :to_image %>
|
8
|
+
<%= link_to_if cover.link_to_resource, image_tag(cover.to_image, class: 'absolute h-full w-full object-cover'), helpers.resource_path(@resource.model), class: 'absolute h-full w-full object-cover', title: title.value %>
|
9
|
+
<% elsif cover.type == 'file_field' %>
|
10
|
+
<% if cover.value.attached? && cover.value.representable? %>
|
11
|
+
<%= link_to_if cover.link_to_resource, image_tag(cover.variant(resize_to_limit: [480, 480]), class: 'absolute h-full w-full object-cover'), helpers.resource_path(@resource.model), class: 'absolute h-full w-full object-cover', title: title.value %>
|
12
12
|
<% else %>
|
13
13
|
<div class="absolute bg-gray-100 w-full h-full">
|
14
14
|
<%= helpers.svg 'avocado', class: 'relative transform -translate-x-1/2 -translate-y-1/2 h-20 text-gray-400 inset-auto top-1/2 left-1/2' %>
|
15
15
|
</div>
|
16
16
|
<% end %>
|
17
17
|
<% else %>
|
18
|
-
<% if
|
19
|
-
<%= link_to_if
|
18
|
+
<% if cover.value.present? %>
|
19
|
+
<%= link_to_if cover.link_to_resource, image_tag(cover.value, class: 'absolute h-full w-full object-cover'), helpers.resource_path(@resource.model), class: 'absolute h-full w-full object-cover', title: title.value %>
|
20
20
|
<% else %>
|
21
21
|
<div class="absolute bg-gray-100 w-full h-full">
|
22
22
|
<%= helpers.svg 'avocado', class: 'relative transform -translate-x-1/2 -translate-y-1/2 h-20 text-gray-400 inset-auto top-1/2 left-1/2' %>
|
@@ -27,7 +27,7 @@
|
|
27
27
|
<div class="grid grid-cols-1 place-content-between p-4 h-full">
|
28
28
|
<div class="mb-4">
|
29
29
|
<div class="grid font-semibold leading-tight text-lg mb-2">
|
30
|
-
<%= link_to_if
|
30
|
+
<%= link_to_if title.link_to_resource, title.value, helpers.resource_path(@resource.model) if title.present? %>
|
31
31
|
</div>
|
32
32
|
<div class="text-sm break-words">
|
33
33
|
<%= body.value if body.present? %>
|
@@ -3,29 +3,23 @@
|
|
3
3
|
class Avo::Index::GridItemComponent < ViewComponent::Base
|
4
4
|
include Avo::ResourcesHelper
|
5
5
|
|
6
|
-
def initialize(resource:
|
6
|
+
def initialize(resource: nil, reflection: nil, parent_model: nil)
|
7
7
|
@resource = resource
|
8
8
|
@reflection = reflection
|
9
|
-
@grid_fields = resource.
|
9
|
+
@grid_fields = resource.get_grid_fields
|
10
10
|
@parent_model = parent_model
|
11
11
|
end
|
12
12
|
|
13
13
|
private
|
14
|
-
def
|
15
|
-
@grid_fields.
|
16
|
-
field.grid_position == :preview
|
17
|
-
end
|
14
|
+
def cover
|
15
|
+
@grid_fields[:cover].first
|
18
16
|
end
|
19
17
|
|
20
18
|
def title
|
21
|
-
@grid_fields.
|
22
|
-
field.grid_position == :title
|
23
|
-
end
|
19
|
+
@grid_fields[:title].first
|
24
20
|
end
|
25
21
|
|
26
22
|
def body
|
27
|
-
@grid_fields.
|
28
|
-
field.grid_position == :body
|
29
|
-
end
|
23
|
+
@grid_fields[:body].first
|
30
24
|
end
|
31
25
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<div class="w-full">
|
2
2
|
<% if @resources.present?%>
|
3
3
|
<table class="w-full px-4 overflow-hidden">
|
4
|
-
<%= render partial: 'avo/partials/table_header', locals: {fields: @resource.get_fields(
|
4
|
+
<%= render partial: 'avo/partials/table_header', locals: {fields: @resource.get_fields(reflection: @reflection)} %>
|
5
5
|
<tbody>
|
6
6
|
<% @resources.each_with_index do |resource, index| %>
|
7
7
|
<% cache_if Avo.configuration.cache_resources_on_index_view, resource.cache_hash(@parent_model) do %>
|
@@ -7,7 +7,7 @@
|
|
7
7
|
<%== item_selector_input floating: false %>
|
8
8
|
</div>
|
9
9
|
</td>
|
10
|
-
<% @resource.get_fields(
|
10
|
+
<% @resource.get_fields(reflection: @reflection).each_with_index do |field, index| %>
|
11
11
|
<%= index_field field, index, @resource %>
|
12
12
|
<% end %>
|
13
13
|
<td class="text-right whitespace-nowrap px-2">
|
@@ -27,15 +27,13 @@ module Avo
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def set_action
|
30
|
-
action_class = params[:action_id].gsub('avo_actions_', '').classify
|
31
|
-
action_name = "Avo::Actions::#{action_class}"
|
30
|
+
action_class = params[:action_id].gsub('avo_actions_', '').classify.safe_constantize
|
32
31
|
|
33
32
|
if params[:id].present?
|
34
33
|
model = @resource.model_class.find params[:id]
|
35
34
|
end
|
36
35
|
|
37
|
-
@action =
|
38
|
-
@action.configure
|
36
|
+
@action = action_class.new
|
39
37
|
@action.hydrate(model: model, resource: resource, user: _current_user)
|
40
38
|
@action.boot_fields request
|
41
39
|
end
|
@@ -15,8 +15,7 @@ module Avo
|
|
15
15
|
add_flash_types :info, :warning, :success, :error
|
16
16
|
|
17
17
|
def init_app
|
18
|
-
Avo::App.
|
19
|
-
Avo::App.init request
|
18
|
+
Avo::App.init request: request, context: context
|
20
19
|
|
21
20
|
@license = Avo::App.license
|
22
21
|
end
|
@@ -36,6 +35,10 @@ module Avo
|
|
36
35
|
instance_eval(&Avo.configuration.current_user)
|
37
36
|
end
|
38
37
|
|
38
|
+
def context
|
39
|
+
instance_eval(&Avo.configuration.context)
|
40
|
+
end
|
41
|
+
|
39
42
|
def resources_path(model, keep_query_params: false, **args)
|
40
43
|
return if model.nil?
|
41
44
|
|
@@ -221,7 +224,7 @@ module Avo
|
|
221
224
|
end
|
222
225
|
|
223
226
|
def set_authorization
|
224
|
-
@authorization = AuthorizationService.new _current_user
|
227
|
+
@authorization = Services::AuthorizationService.new _current_user
|
225
228
|
end
|
226
229
|
|
227
230
|
def set_container_classes
|
@@ -186,8 +186,6 @@ module Avo
|
|
186
186
|
@filters = @resource.get_filters.map do |filter_class|
|
187
187
|
filter = filter_class.new
|
188
188
|
|
189
|
-
filter.configure
|
190
|
-
|
191
189
|
filter
|
192
190
|
end
|
193
191
|
end
|
@@ -216,7 +214,6 @@ module Avo
|
|
216
214
|
|
217
215
|
@resource.get_filters.each do |filter_class|
|
218
216
|
filter = filter_class.new
|
219
|
-
filter.configure
|
220
217
|
|
221
218
|
if filter.default.present?
|
222
219
|
filter_defaults[filter_class.to_s] = filter.default
|
@@ -11,7 +11,7 @@ import tippy from 'tippy.js'
|
|
11
11
|
// Toastr alerts
|
12
12
|
import '../js/toastr'
|
13
13
|
|
14
|
-
Mousetrap.bind('r r r', () => Turbo.visit(window.location.href))
|
14
|
+
Mousetrap.bind('r r r', () => Turbo.visit(window.location.href, { action: "replace" }))
|
15
15
|
|
16
16
|
const application = Application.start()
|
17
17
|
|
@@ -14,12 +14,6 @@
|
|
14
14
|
>
|
15
15
|
<%
|
16
16
|
@actions.each_with_index do |action, index|
|
17
|
-
case action.class.superclass.to_s
|
18
|
-
when Avo::Filters::SelectFilter.to_s
|
19
|
-
template = 'select_action'
|
20
|
-
when Avo::Filters::BooleanFilter.to_s
|
21
|
-
template = 'boolean_action'
|
22
|
-
end
|
23
17
|
path = action_name == 'show' ?
|
24
18
|
"/avo/resources/#{@resource.model_class.model_name.route_key}/#{@model.id}/actions/#{action.param_id}" :
|
25
19
|
"/avo/resources/#{@resource.model_class.model_name.route_key}/actions/#{action.param_id}"
|
@@ -12,7 +12,7 @@
|
|
12
12
|
set_value = {} if set_value.nil?
|
13
13
|
%>
|
14
14
|
<div data-controller="boolean-filter">
|
15
|
-
<%= filter_wrapper name: filter.name
|
15
|
+
<%= filter_wrapper name: filter.name do %>
|
16
16
|
<div class="flex items-center">
|
17
17
|
<div class="space-y-2">
|
18
18
|
<% filter.options.each do |value, label| %>
|
@@ -10,19 +10,11 @@
|
|
10
10
|
<% end %>
|
11
11
|
|
12
12
|
<div
|
13
|
-
class="absolute block inset-auto right-0 top-full bg-white min-w-300px mt-2 z-20 shadow-context rounded-xl hidden"
|
13
|
+
class="absolute block inset-auto right-0 top-full bg-white min-w-300px mt-2 z-20 shadow-context rounded-xl hidden divide-y divide-gray-300"
|
14
14
|
data-toggle-panel-target="panel"
|
15
15
|
>
|
16
|
-
<%
|
17
|
-
|
18
|
-
case filter.class.superclass.to_s
|
19
|
-
when Avo::Filters::SelectFilter.to_s
|
20
|
-
template = 'avo/base/select_filter'
|
21
|
-
when Avo::Filters::BooleanFilter.to_s
|
22
|
-
template = 'avo/base/boolean_filter'
|
23
|
-
end
|
24
|
-
%>
|
25
|
-
<%= render partial: template, locals: {filter: filter, index: index} %>
|
16
|
+
<% @filters.each do |filter| %>
|
17
|
+
<%= render partial: filter.class.template, locals: {filter: filter} %>
|
26
18
|
<% end %>
|
27
19
|
|
28
20
|
<div class="p-4 border-gray-300 border-t">
|
@@ -7,7 +7,7 @@
|
|
7
7
|
end
|
8
8
|
%>
|
9
9
|
<div data-controller="select-filter">
|
10
|
-
<%= filter_wrapper name: filter.name
|
10
|
+
<%= filter_wrapper name: filter.name do %>
|
11
11
|
<%= select_tag filter.id, options_for_select(filter.options.invert, set_value),
|
12
12
|
class: input_classes('w-full mb-0'),
|
13
13
|
include_blank: '—',
|
@@ -8,6 +8,11 @@
|
|
8
8
|
|
9
9
|
<%= render partial: 'avo/partials/javascript' %>
|
10
10
|
|
11
|
+
<%# if Avo::PACKED %>
|
12
|
+
<%#= stylesheet_link_tag 'application', media: 'all', "data-turbo-track": "reload" %>
|
13
|
+
<%#= javascript_include_tag 'avo-packs/application', "data-turbo-track": "reload" %>
|
14
|
+
<%# else %>
|
15
|
+
<%# end %>
|
11
16
|
<%= javascript_pack_tag 'application' %>
|
12
17
|
<%= stylesheet_pack_tag 'application', media: 'all' %>
|
13
18
|
</head>
|
data/config/webpacker.yml
CHANGED
@@ -51,32 +51,19 @@ default: &default
|
|
51
51
|
- .jpeg
|
52
52
|
- .jpg
|
53
53
|
|
54
|
+
# We override the development env. when packed.
|
55
|
+
# Avo needs to be packed and compiled for when the dev uses it in his development env.
|
54
56
|
development:
|
55
57
|
<<: *default
|
56
|
-
compile: true
|
57
58
|
|
58
|
-
#
|
59
|
-
|
60
|
-
|
61
|
-
#
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
public: localhost:3039
|
67
|
-
hmr: true
|
68
|
-
# Inline should be set to true if using HMR
|
69
|
-
inline: true
|
70
|
-
overlay: true
|
71
|
-
compress: true
|
72
|
-
disable_host_check: true
|
73
|
-
use_local_ip: false
|
74
|
-
quiet: false
|
75
|
-
headers:
|
76
|
-
'Access-Control-Allow-Origin': '*'
|
77
|
-
watch_options:
|
78
|
-
ignored: '**/node_modules/**'
|
79
|
-
env_prefix: "AVO_WEBPACKER_DEV_SERVER"
|
59
|
+
# Production depends on precompilation of packs prior to booting for performance.
|
60
|
+
compile: false
|
61
|
+
|
62
|
+
# Extract and emit a css file
|
63
|
+
extract_css: true
|
64
|
+
|
65
|
+
# Cache manifest.json for performance
|
66
|
+
cache_manifest: true
|
80
67
|
|
81
68
|
test:
|
82
69
|
<<: *default
|
data/lib/avo.rb
CHANGED
@@ -1,20 +1,9 @@
|
|
1
|
-
|
1
|
+
require 'zeitwerk'
|
2
2
|
require_relative 'avo/version'
|
3
|
+
require_relative 'avo/engine' if defined?(Rails)
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
require_relative 'avo/app/action'
|
7
|
-
|
8
|
-
require_relative 'avo/app/filter'
|
9
|
-
require_relative 'avo/app/filters/boolean_filter'
|
10
|
-
require_relative 'avo/app/filters/select_filter'
|
11
|
-
|
12
|
-
require_relative 'avo/app/fields_loader'
|
13
|
-
require_relative 'avo/app/actions_loader'
|
14
|
-
# require_relative 'avo/app/fields_loader_helper'
|
15
|
-
require_relative 'avo/app/resource'
|
16
|
-
|
17
|
-
require_relative 'avo/app/licensing/license_manager'
|
5
|
+
loader = Zeitwerk::Loader.for_gem
|
6
|
+
loader.setup
|
18
7
|
|
19
8
|
module Avo
|
20
9
|
ROOT_PATH = Pathname.new(File.join(__dir__, '..'))
|
@@ -31,4 +20,4 @@ module Avo
|
|
31
20
|
end
|
32
21
|
end
|
33
22
|
|
34
|
-
|
23
|
+
loader.eager_load
|
data/lib/avo/app.rb
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
module Avo
|
2
|
+
class App
|
3
|
+
class_attribute :app, default: {
|
4
|
+
resources: [],
|
5
|
+
cache_store: nil
|
6
|
+
}
|
7
|
+
class_attribute :fields, default: []
|
8
|
+
class_attribute :request, default: nil
|
9
|
+
class_attribute :context, default: nil
|
10
|
+
class_attribute :license, default: nil
|
11
|
+
|
12
|
+
class << self
|
13
|
+
# def load_controllers
|
14
|
+
# BaseResource.descendants.each do |resource|
|
15
|
+
# controller_name = "#{resource.to_s.gsub('Resource', '').pluralize}Controller"
|
16
|
+
# puts controller_name.inspect
|
17
|
+
# # eval <<DYNAMIC
|
18
|
+
# # class #{controller_name} < Avo::ResourcesController
|
19
|
+
# # # title :Person
|
20
|
+
# # # attribute :name, String
|
21
|
+
# # # ...or substitute other stuff in here.
|
22
|
+
# # end
|
23
|
+
# # DYNAMIC
|
24
|
+
|
25
|
+
# Avo.const_set(controller_name.to_sym, Class.new(Avo::ResourcesController))
|
26
|
+
# # puts controller_name.inspect
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
|
30
|
+
def boot
|
31
|
+
init_fields
|
32
|
+
|
33
|
+
I18n.locale = Avo.configuration.language_code
|
34
|
+
|
35
|
+
if Rails.cache.class == ActiveSupport::Cache::NullStore
|
36
|
+
self.app[:cache_store] ||= ActiveSupport::Cache::MemoryStore.new
|
37
|
+
else
|
38
|
+
self.app[:cache_store] = Rails.cache
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def init(request:, context:)
|
43
|
+
self.request = request
|
44
|
+
self.context = context
|
45
|
+
|
46
|
+
# Set the current host for ActiveStorage
|
47
|
+
ActiveStorage::Current.host = request.base_url
|
48
|
+
|
49
|
+
init_resources
|
50
|
+
|
51
|
+
self.license = Licensing::LicenseManager.new(Licensing::HQ.new(request).response).license
|
52
|
+
end
|
53
|
+
|
54
|
+
def cache_store
|
55
|
+
self.app[:cache_store]
|
56
|
+
end
|
57
|
+
|
58
|
+
# This method will find all fields available in the Avo::Fields namespace and add them to the fields class_variable array
|
59
|
+
# so later we can instantiate them on our resources.
|
60
|
+
#
|
61
|
+
# If the field has their `def_method` set up it will follow that convention, if not it will snake_case the name:
|
62
|
+
#
|
63
|
+
# Avo::Fields::TextField -> text
|
64
|
+
# Avo::Fields::DateTimeField -> date_time
|
65
|
+
def init_fields
|
66
|
+
Avo::Fields::BaseField.descendants.each do |class_name|
|
67
|
+
next if class_name.to_s == 'BaseField'
|
68
|
+
|
69
|
+
if class_name.to_s.end_with? 'Field'
|
70
|
+
load_field class_name.get_field_name, class_name
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def load_field(method_name, klass)
|
76
|
+
self.fields.push(
|
77
|
+
name: method_name,
|
78
|
+
class: klass,
|
79
|
+
)
|
80
|
+
|
81
|
+
# Avo::Loaders::FieldsLoader.define_method method_name.to_sym do |*args, &block|
|
82
|
+
# puts ['Avo::Loaders::FieldsLoader.define_method->', args, block.present?].inspect
|
83
|
+
|
84
|
+
# if block.present?
|
85
|
+
# puts '111->'.inspect
|
86
|
+
# field = klass.new(args[0], **args[1] || {}, &block)
|
87
|
+
# else
|
88
|
+
# puts '222->'.inspect
|
89
|
+
# field = klass.new(args[0], **args[1] || {})
|
90
|
+
# end
|
91
|
+
|
92
|
+
# puts field.inspect
|
93
|
+
|
94
|
+
# self.bag.push field
|
95
|
+
|
96
|
+
# # field
|
97
|
+
# # if block.present?
|
98
|
+
# # field_class = klass::new(args[0], **args[1] || {}, &block)
|
99
|
+
# # else
|
100
|
+
# # field_class = klass::new(args[0], **args[1] || {})
|
101
|
+
# # end
|
102
|
+
|
103
|
+
# # klass_entity.add_field(self, field_class)
|
104
|
+
# end
|
105
|
+
end
|
106
|
+
|
107
|
+
def init_resources
|
108
|
+
self.app[:resources] = BaseResource.descendants
|
109
|
+
.select do |resource|
|
110
|
+
resource != BaseResource
|
111
|
+
end
|
112
|
+
.map do |resource|
|
113
|
+
if resource.is_a? Class
|
114
|
+
resource.new
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def get_resources
|
120
|
+
self.app[:resources]
|
121
|
+
end
|
122
|
+
|
123
|
+
# Returns the Avo resource by camelized name
|
124
|
+
#
|
125
|
+
# get_resource_by_name('User') => Avo::Resources::User
|
126
|
+
def get_resource(resource)
|
127
|
+
self.app[:resources].find do |available_resource|
|
128
|
+
"#{resource}Resource".safe_constantize == available_resource.class
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Returns the Avo resource by singular snake_cased name
|
133
|
+
#
|
134
|
+
# get_resource_by_name('user') => Avo::Resources::User
|
135
|
+
def get_resource_by_name(name)
|
136
|
+
self.get_resource name.singularize.camelize
|
137
|
+
end
|
138
|
+
|
139
|
+
# Returns the Avo resource by singular snake_cased name
|
140
|
+
#
|
141
|
+
# get_resource_by_name('User') => Avo::Resources::User
|
142
|
+
# get_resource_by_name(User) => Avo::Resources::User
|
143
|
+
def get_resource_by_model_name(name)
|
144
|
+
get_resources.find do |resource|
|
145
|
+
resource.model_class.model_name.name == name.to_s
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Returns the Rails model class by singular snake_cased name
|
150
|
+
#
|
151
|
+
# get_model_class_by_name('user') => User
|
152
|
+
def get_model_class_by_name(name)
|
153
|
+
name.to_s.camelize.singularize
|
154
|
+
end
|
155
|
+
|
156
|
+
def get_available_resources(user = nil)
|
157
|
+
App.get_resources
|
158
|
+
.select do |resource|
|
159
|
+
Services::AuthorizationService.authorize user, resource.model, Avo.configuration.authorization_methods.stringify_keys['index'], raise_exception: false
|
160
|
+
end
|
161
|
+
.sort_by { |r| r.name }
|
162
|
+
end
|
163
|
+
|
164
|
+
def get_navigation_items(user = nil)
|
165
|
+
get_available_resources(user).select do |resource|
|
166
|
+
resource.model_class.present?
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def draw_routes
|
171
|
+
# We should eager load all the classes so we find all descendants
|
172
|
+
Rails.application.eager_load!
|
173
|
+
|
174
|
+
Proc.new do
|
175
|
+
BaseResource.descendants
|
176
|
+
.select do |resource|
|
177
|
+
resource != :Resource
|
178
|
+
end
|
179
|
+
.map do |resource|
|
180
|
+
if resource.is_a? Class
|
181
|
+
route_key = resource.to_s.underscore.gsub('_resource', '').downcase.pluralize.to_sym
|
182
|
+
|
183
|
+
resources route_key
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|