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.

Files changed (133) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -2
  3. data/Gemfile.lock +1 -1
  4. data/app/components/avo/index/grid_item_component.html.erb +8 -8
  5. data/app/components/avo/index/grid_item_component.rb +6 -12
  6. data/app/components/avo/index/resource_table_component.html.erb +1 -1
  7. data/app/components/avo/index/table_row_component.html.erb +1 -1
  8. data/app/controllers/avo/actions_controller.rb +2 -4
  9. data/app/controllers/avo/application_controller.rb +6 -3
  10. data/app/controllers/avo/base_controller.rb +0 -3
  11. data/app/controllers/avo/relations_controller.rb +1 -1
  12. data/app/controllers/avo/search_controller.rb +1 -1
  13. data/app/frontend/packs/application.js +1 -1
  14. data/app/views/avo/base/_actions.html.erb +0 -6
  15. data/app/views/avo/base/_boolean_filter.html.erb +1 -1
  16. data/app/views/avo/base/_filters.html.erb +3 -11
  17. data/app/views/avo/base/_select_filter.html.erb +1 -1
  18. data/app/views/avo/home/_resources.html.erb +0 -1
  19. data/app/views/layouts/avo/_filter_wrapper.html.erb +1 -1
  20. data/app/views/layouts/avo/application.html.erb +5 -0
  21. data/config/webpacker.yml +10 -23
  22. data/lib/avo.rb +5 -16
  23. data/lib/avo/app.rb +190 -0
  24. data/lib/avo/base_action.rb +115 -0
  25. data/lib/avo/base_resource.rb +321 -0
  26. data/lib/avo/configuration.rb +6 -0
  27. data/lib/avo/engine.rb +12 -31
  28. data/lib/avo/{app/fields → fields}/badge_field.rb +1 -1
  29. data/lib/avo/{app/fields/field.rb → fields/base_field.rb} +3 -7
  30. data/lib/avo/{app/fields/belongs_to.rb → fields/belongs_to_field.rb} +3 -3
  31. data/lib/avo/{app/fields → fields}/boolean_field.rb +1 -1
  32. data/lib/avo/{app/fields → fields}/boolean_group_field.rb +1 -1
  33. data/lib/avo/{app/fields → fields}/code_field.rb +1 -1
  34. data/lib/avo/{app/fields → fields}/country_field.rb +1 -1
  35. data/lib/avo/{app/fields → fields}/currency_field.rb +1 -1
  36. data/lib/avo/{app/fields → fields}/date_field.rb +0 -2
  37. data/lib/avo/{app/fields → fields}/date_time_field.rb +0 -2
  38. data/lib/avo/{app/fields → fields}/external_image_field.rb +1 -1
  39. data/lib/avo/{app/fields → fields}/field_extensions/has_field_name.rb +0 -0
  40. data/lib/avo/{app/fields → fields}/field_extensions/visible_in_different_views.rb +1 -1
  41. data/lib/avo/{app/fields → fields}/file_field.rb +1 -2
  42. data/lib/avo/{app/fields → fields}/files_field.rb +1 -2
  43. data/lib/avo/{app/fields → fields}/gravatar_field.rb +1 -1
  44. data/lib/avo/{app/fields/has_and_belongs_to_many.rb → fields/has_and_belongs_to_many_field.rb} +1 -1
  45. data/lib/avo/{app/fields/has_many.rb → fields/has_many_field.rb} +1 -1
  46. data/lib/avo/{app/fields/has_one.rb → fields/has_one_field.rb} +1 -1
  47. data/lib/avo/{app/fields → fields}/heading_field.rb +1 -1
  48. data/lib/avo/{app/fields → fields}/hidden_field.rb +0 -2
  49. data/lib/avo/{app/fields → fields}/id_field.rb +1 -1
  50. data/lib/avo/{app/fields → fields}/key_value_field.rb +1 -1
  51. data/lib/avo/{app/fields → fields}/markdown_field.rb +1 -3
  52. data/lib/avo/{app/fields → fields}/number_field.rb +0 -2
  53. data/lib/avo/{app/fields → fields}/password_field.rb +0 -2
  54. data/lib/avo/{app/fields → fields}/select_field.rb +1 -1
  55. data/lib/avo/{app/fields → fields}/status_field.rb +1 -1
  56. data/lib/avo/{app/fields → fields}/text_field.rb +1 -1
  57. data/lib/avo/{app/fields → fields}/textarea_field.rb +0 -2
  58. data/lib/avo/{app/fields → fields}/trix_field.rb +1 -3
  59. data/lib/avo/filters/base_filter.rb +20 -0
  60. data/lib/avo/filters/boolean_filter.rb +7 -0
  61. data/lib/avo/filters/select_filter.rb +7 -0
  62. data/lib/avo/{app/grid_fields → grid_fields}/body_field.rb +0 -2
  63. data/lib/avo/{app/grid_fields → grid_fields}/grid_field.rb +0 -0
  64. data/lib/avo/{app/grid_fields → grid_fields}/preview_field.rb +0 -2
  65. data/lib/avo/{app/grid_fields → grid_fields}/title_field.rb +0 -2
  66. data/lib/avo/licensing/community_license.rb +6 -0
  67. data/lib/avo/licensing/h_q.rb +88 -0
  68. data/lib/avo/licensing/license.rb +50 -0
  69. data/lib/avo/licensing/license_manager.rb +22 -0
  70. data/lib/avo/licensing/null_license.rb +14 -0
  71. data/lib/avo/licensing/pro_license.rb +11 -0
  72. data/lib/avo/loaders/actions_loader.rb +6 -0
  73. data/lib/avo/loaders/fields_loader.rb +27 -0
  74. data/lib/avo/loaders/filters_loader.rb +6 -0
  75. data/lib/avo/loaders/loader.rb +15 -0
  76. data/lib/avo/services/authorization_service.rb +93 -0
  77. data/lib/avo/services/panel_service.rb +27 -0
  78. data/lib/avo/{app/tools_manager.rb → tools_manager.rb} +0 -0
  79. data/lib/avo/version.rb +1 -1
  80. data/lib/generators/avo/action_generator.rb +11 -5
  81. data/lib/generators/avo/controller_generator.rb +14 -8
  82. data/lib/generators/avo/filter_generator.rb +14 -8
  83. data/lib/generators/avo/install_generator.rb +14 -10
  84. data/lib/generators/avo/locales_generator.rb +11 -7
  85. data/lib/generators/avo/partials_generator.rb +11 -5
  86. data/lib/generators/avo/resource_generator.rb +33 -15
  87. data/lib/generators/avo/templates/{action.rb → action.tt} +2 -4
  88. data/lib/generators/avo/templates/filters/boolean_filter.tt +11 -0
  89. data/lib/generators/avo/templates/filters/select_filter.tt +11 -0
  90. data/lib/generators/avo/templates/initializer/{avo.rb → avo.tt} +6 -0
  91. data/lib/generators/avo/templates/resource/controller.tt +2 -0
  92. data/lib/generators/avo/templates/resource/resource.tt +17 -0
  93. data/public/avo-packs/css/{application-3598cfbb.css → application-c75ac28c.css} +1 -1
  94. data/public/avo-packs/css/application-c75ac28c.css.br +0 -0
  95. data/public/avo-packs/css/{application-3598cfbb.css.gz → application-c75ac28c.css.gz} +0 -0
  96. data/public/avo-packs/js/{application-6ba2bd1bca05d69b96e0.js → application-8849c6e2c8f75d55c666.js} +3 -3
  97. data/public/avo-packs/js/{application-6ba2bd1bca05d69b96e0.js.LICENSE.txt → application-8849c6e2c8f75d55c666.js.LICENSE.txt} +0 -0
  98. data/public/avo-packs/js/application-8849c6e2c8f75d55c666.js.br +0 -0
  99. data/public/avo-packs/js/application-8849c6e2c8f75d55c666.js.gz +0 -0
  100. data/public/avo-packs/js/{application-6ba2bd1bca05d69b96e0.js.map → application-8849c6e2c8f75d55c666.js.map} +1 -1
  101. data/public/avo-packs/js/application-8849c6e2c8f75d55c666.js.map.br +0 -0
  102. data/public/avo-packs/js/{application-6ba2bd1bca05d69b96e0.js.map.gz → application-8849c6e2c8f75d55c666.js.map.gz} +0 -0
  103. data/public/avo-packs/manifest.json +6 -6
  104. data/public/avo-packs/manifest.json.br +0 -0
  105. data/public/avo-packs/manifest.json.gz +0 -0
  106. metadata +72 -73
  107. data/config/webpacker_packed.yml +0 -86
  108. data/lib/avo/app/action.rb +0 -145
  109. data/lib/avo/app/actions_loader.rb +0 -11
  110. data/lib/avo/app/app.rb +0 -183
  111. data/lib/avo/app/fields_loader.rb +0 -29
  112. data/lib/avo/app/filter.rb +0 -23
  113. data/lib/avo/app/filters/boolean_filter.rb +0 -13
  114. data/lib/avo/app/filters/select_filter.rb +0 -13
  115. data/lib/avo/app/licensing/community_license.rb +0 -4
  116. data/lib/avo/app/licensing/hq.rb +0 -86
  117. data/lib/avo/app/licensing/license.rb +0 -48
  118. data/lib/avo/app/licensing/license_manager.rb +0 -25
  119. data/lib/avo/app/licensing/null_license.rb +0 -12
  120. data/lib/avo/app/licensing/pro_license.rb +0 -9
  121. data/lib/avo/app/resource.rb +0 -299
  122. data/lib/avo/app/resource_grid_fields.rb +0 -30
  123. data/lib/avo/app/services/authorization_service.rb +0 -110
  124. data/lib/avo/app/services/panel_service.rb +0 -25
  125. data/lib/avo/app/tool.rb +0 -5
  126. data/lib/generators/avo/templates/filters/boolean_filter.rb +0 -17
  127. data/lib/generators/avo/templates/filters/select_filter.rb +0 -17
  128. data/lib/generators/avo/templates/resource/%plural_name%_controller.tt +0 -2
  129. data/lib/generators/avo/templates/resource/%singular_name%.tt +0 -20
  130. data/public/avo-packs/css/application-3598cfbb.css.br +0 -0
  131. data/public/avo-packs/js/application-6ba2bd1bca05d69b96e0.js.br +0 -0
  132. data/public/avo-packs/js/application-6ba2bd1bca05d69b96e0.js.gz +0 -0
  133. 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: 274e5f99538c656daae6caef5484cd7f9864b4cdd8ca39a616084d73f0c66d29
4
- data.tar.gz: 3fca117d0c913546ba43493b3e80afa6584004fc1bd91d8452e2fd57160e2802
3
+ metadata.gz: e9ed4bc1c98f78365b9b2a50dda9ed809b6c598c2d0b745e6f706f3456974532
4
+ data.tar.gz: 71cf2d32d71b19316e36cc2e4a7688d2581f668044ac2975a786c3ce753b11a9
5
5
  SHA512:
6
- metadata.gz: 5a600bc88614730df27fd05a8a459ee70c8513a8c7a05df55f22e8679e151e857e866c07e9c35f16ae9d65c2843a21114d730622588e7375bebac9b1d49c8a9d
7
- data.tar.gz: b192141926944fd2f987f962eb073c01892bedde487a74d62818cf00fe1ae7aa2b6760de2843c01ddcd47f38015a1b42063ca3437d040f2a48088a6a2b8b13b2
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- avo (0.5.0.beta4)
4
+ avo (0.5.0.beta5)
5
5
  active_link_to
6
6
  countries
7
7
  hotwire-rails
@@ -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 preview.respond_to? :to_image %>
8
- <%= link_to_if preview.link_to_resource, image_tag(preview.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 preview.type == 'file_field' %>
10
- <% if preview.value.attached? && preview.value.representable? %>
11
- <%= link_to_if preview.link_to_resource, image_tag(preview.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 %>
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 preview.value.present? %>
19
- <%= link_to_if preview.link_to_resource, image_tag(preview.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 %>
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 preview.link_to_resource, title.value, helpers.resource_path(@resource.model) if title.present? %>
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: resource, reflection: reflection, parent_model: nil)
6
+ def initialize(resource: nil, reflection: nil, parent_model: nil)
7
7
  @resource = resource
8
8
  @reflection = reflection
9
- @grid_fields = resource.get_fields(view_type: :grid)
9
+ @grid_fields = resource.get_grid_fields
10
10
  @parent_model = parent_model
11
11
  end
12
12
 
13
13
  private
14
- def preview
15
- @grid_fields.detect do |field|
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.detect do |field|
22
- field.grid_position == :title
23
- end
19
+ @grid_fields[:title].first
24
20
  end
25
21
 
26
22
  def body
27
- @grid_fields.detect do |field|
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(view_type: :table, reflection: @reflection)} %>
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(view_type: :table, reflection: @reflection).each_with_index do |field, index| %>
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 = action_name.safe_constantize.new
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.boot if Avo::IN_DEVELOPMENT
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
@@ -35,7 +35,7 @@ module Avo
35
35
  @options = query.all.map do |model|
36
36
  {
37
37
  value: model.id,
38
- label: model.send(@attachment_resource.title)
38
+ label: model.send(@attachment_resource.class.title)
39
39
  }
40
40
  end
41
41
  end
@@ -35,7 +35,7 @@ module Avo
35
35
  resources.map do |model|
36
36
  {
37
37
  id: model.id,
38
- search_label: model.send(avo_resource.title),
38
+ search_label: model.send(avo_resource.class.title),
39
39
  link: "/resources/#{model.class.to_s.singularize.underscore}/#{model.id}",
40
40
  }
41
41
  end
@@ -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, index: index do %>
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
- @filters.each_with_index do |filter, index|
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, index: index do %>
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: '—',
@@ -1,5 +1,4 @@
1
1
  <%
2
- Rails.application.eager_load!
3
2
  models = ApplicationRecord.descendants
4
3
  %>
5
4
  <div>
@@ -1,4 +1,4 @@
1
- <div class="border-gray-300 <%= 'border-t' if index != 0 %>">
1
+ <div>
2
2
  <div class="p-4 pb-0 text-sm font-bold text-gray-600">
3
3
  <%= name %>
4
4
  </div>
@@ -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
- # Verifies that correct packages and versions are installed by inspecting package.json, yarn.lock, and node_modules
59
- check_yarn_integrity: true
60
-
61
- # Reference: https://webpack.js.org/configuration/dev-server/
62
- dev_server:
63
- https: false
64
- host: localhost
65
- port: 3039
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
- require_relative 'avo/configuration'
1
+ require 'zeitwerk'
2
2
  require_relative 'avo/version'
3
+ require_relative 'avo/engine' if defined?(Rails)
3
4
 
4
- require_relative 'avo/app/fields/field'
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
- require_relative 'avo/engine' if defined?(Rails)
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