avo 2.8.0 → 2.9.1.pre2

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/README.md +11 -0
  4. data/app/assets/builds/action_cable.js +2 -0
  5. data/app/assets/builds/action_cable.js.map +7 -0
  6. data/app/assets/builds/application.js +2 -0
  7. data/app/assets/builds/application.js.map +7 -0
  8. data/app/assets/builds/avo.css +9028 -0
  9. data/app/assets/builds/avo.js +512 -0
  10. data/app/assets/builds/avo.js.map +7 -0
  11. data/app/assets/builds/avo_custom.js +6 -0
  12. data/app/assets/builds/avo_custom.js.map +7 -0
  13. data/app/assets/stylesheets/avo.css +4 -4
  14. data/app/assets/stylesheets/css/{components → fields}/code.css +0 -0
  15. data/app/assets/stylesheets/css/{components → fields}/progress.css +0 -0
  16. data/app/assets/stylesheets/css/{components → fields}/status.css +0 -0
  17. data/app/assets/stylesheets/css/fields/trix.css +17 -0
  18. data/app/components/avo/actions_component.html.erb +5 -13
  19. data/app/components/avo/actions_component.rb +39 -1
  20. data/app/components/avo/common_field_wrapper_component.html.erb +1 -1
  21. data/app/components/avo/fields/belongs_to_field/edit_component.rb +1 -1
  22. data/app/components/avo/fields/trix_field/edit_component.html.erb +1 -0
  23. data/app/components/avo/fields/trix_field/show_component.html.erb +1 -1
  24. data/app/components/avo/sidebar/item_switcher_component.html.erb +2 -2
  25. data/app/components/avo/views/resource_edit_component.html.erb +6 -4
  26. data/app/components/avo/views/resource_edit_component.rb +32 -4
  27. data/app/components/avo/views/resource_index_component.html.erb +1 -1
  28. data/app/components/avo/views/resource_show_component.html.erb +2 -2
  29. data/app/controllers/avo/base_controller.rb +11 -6
  30. data/app/helpers/avo/url_helpers.rb +8 -9
  31. data/app/javascript/js/controllers.js +0 -2
  32. data/app/views/avo/base/edit.html.erb +2 -1
  33. data/app/views/avo/base/new.html.erb +1 -1
  34. data/app/views/avo/partials/_custom_tools_alert.html.erb +21 -7
  35. data/app/views/avo/partials/_table_header.html.erb +9 -1
  36. data/bin/test +1 -0
  37. data/lib/avo/app.rb +18 -1
  38. data/lib/avo/base_action.rb +7 -2
  39. data/lib/avo/base_resource.rb +7 -2
  40. data/lib/avo/concerns/fetches_things.rb +19 -12
  41. data/lib/avo/concerns/has_model.rb +11 -0
  42. data/lib/avo/concerns/model_class_constantized.rb +23 -0
  43. data/lib/avo/dynamic_router.rb +1 -1
  44. data/lib/avo/engine.rb +1 -3
  45. data/lib/avo/fields/base_field.rb +1 -0
  46. data/lib/avo/fields/concerns/is_required.rb +17 -0
  47. data/lib/avo/hosts/view_record_host.rb +7 -0
  48. data/lib/avo/menu/base_item.rb +4 -0
  49. data/lib/avo/menu/dashboard.rb +5 -0
  50. data/lib/avo/menu/resource.rb +5 -0
  51. data/lib/avo/version.rb +1 -1
  52. data/lib/avo.rb +1 -0
  53. data/lib/generators/avo/install_generator.rb +1 -4
  54. data/public/avo-assets/avo.css +467 -1069
  55. data/public/avo-assets/avo.js +70 -70
  56. data/public/avo-assets/avo.js.map +3 -3
  57. metadata +21 -10
  58. data/app/components/avo/views/resource_new_component.html.erb +0 -60
  59. data/app/components/avo/views/resource_new_component.rb +0 -39
  60. data/app/javascript/js/controllers/custom/course_resource_controller.js +0 -102
@@ -4,9 +4,13 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
4
4
  include Avo::ResourcesHelper
5
5
  include Avo::ApplicationHelper
6
6
 
7
- def initialize(resource: nil)
7
+ attr_reader :view
8
+
9
+ def initialize(resource: nil, model: nil, actions: [], view: :edit)
8
10
  @resource = resource
9
- @view = :edit
11
+ @model = model
12
+ @actions = actions
13
+ @view = view
10
14
 
11
15
  split_panel_fields
12
16
  end
@@ -17,14 +21,18 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
17
21
  elsif via_index?
18
22
  helpers.resources_path(resource: @resource)
19
23
  else # via resource show page
20
- helpers.resource_path(model: @resource.model, resource: @resource)
24
+ if is_edit?
25
+ helpers.resource_path(model: @resource.model, resource: @resource)
26
+ else
27
+ helpers.resources_path(resource: @resource)
28
+ end
21
29
  end
22
30
  end
23
31
 
24
32
  # The save button is dependent on the edit? policy method.
25
33
  # The update? method should be called only when the user clicks the Save button so the developer gets access to the params from the form.
26
34
  def can_see_the_save_button?
27
- @resource.authorization.authorize_action :edit, raise_exception: false
35
+ @resource.authorization.authorize_action @view, raise_exception: false
28
36
  end
29
37
 
30
38
  private
@@ -32,4 +40,24 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
32
40
  def via_index?
33
41
  params[:via_view] == "index"
34
42
  end
43
+
44
+ def is_edit?
45
+ view == :edit
46
+ end
47
+
48
+ def form_url
49
+ if is_edit?
50
+ helpers.resource_path(
51
+ model: @resource.model,
52
+ resource: @resource
53
+ )
54
+ else
55
+ helpers.resources_path(
56
+ resource: @resource,
57
+ via_relation_class: params[:via_relation_class],
58
+ via_relation: params[:via_relation],
59
+ via_resource_id: params[:via_resource_id]
60
+ )
61
+ end
62
+ end
35
63
  end
@@ -15,7 +15,7 @@
15
15
  <% end %>
16
16
  <% end %>
17
17
  <% if can_see_the_actions_button? %>
18
- <%= render Avo::ActionsComponent.new actions: @actions, resource: @resource %>
18
+ <%= render Avo::ActionsComponent.new actions: @actions, resource: @resource, view: @view %>
19
19
  <% end %>
20
20
  <% if can_see_the_create_button? %>
21
21
  <%= a_link create_path,
@@ -22,7 +22,7 @@
22
22
  } do %>
23
23
  <%= t('avo.detach_item', item: title).capitalize %>
24
24
  <% end %>
25
- <%= render Avo::ActionsComponent.new actions: @actions, resource: @resource %>
25
+ <%= render Avo::ActionsComponent.new actions: @actions, resource: @resource, view: @view %>
26
26
  <% end %>
27
27
  <% if can_see_the_edit_button? %>
28
28
  <%= a_link edit_path,
@@ -57,7 +57,7 @@
57
57
  <%= t('avo.delete').capitalize %>
58
58
  <% end %>
59
59
  <% end %>
60
- <%= render Avo::ActionsComponent.new actions: @actions, resource: @resource %>
60
+ <%= render Avo::ActionsComponent.new actions: @actions, resource: @resource, view: @view %>
61
61
  <% if @resource.authorization.authorize_action(:edit, raise_exception: false) %>
62
62
  <%= a_link edit_path,
63
63
  color: :primary,
@@ -76,7 +76,7 @@ module Avo
76
76
 
77
77
  def show
78
78
  @resource.hydrate(model: @model, view: :show, user: _current_user, params: params)
79
-
79
+
80
80
  set_actions
81
81
 
82
82
  @page_title = @resource.default_panel_name.to_s
@@ -101,6 +101,8 @@ module Avo
101
101
  @model = @resource.model_class.new
102
102
  @resource = @resource.hydrate(model: @model, view: :new, user: _current_user)
103
103
 
104
+ set_actions
105
+
104
106
  @page_title = @resource.default_panel_name.to_s
105
107
 
106
108
  if params[:via_relation_class].present? && params[:via_resource_id].present?
@@ -161,6 +163,7 @@ module Avo
161
163
  end
162
164
 
163
165
  def edit
166
+ set_actions
164
167
  end
165
168
 
166
169
  def update
@@ -391,20 +394,22 @@ module Avo
391
394
  return resource_path(model: params[:via_relation_class].safe_constantize, resource: parent_resource, resource_id: params[:via_resource_id])
392
395
  end
393
396
 
394
- redirect_path_from_resource_option || resource_path(model: @model, resource: @resource)
397
+ redirect_path_from_resource_option(:after_create_path) || resource_path(model: @model, resource: @resource)
395
398
  end
396
399
 
397
400
  def after_update_path
398
401
  return params[:referrer] if params[:referrer].present?
399
402
 
400
- redirect_path_from_resource_option || resource_path(model: @model, resource: @resource)
403
+ redirect_path_from_resource_option(:after_update_path) || resource_path(model: @model, resource: @resource)
401
404
  end
402
405
 
403
- def redirect_path_from_resource_option
404
- return nil if @resource.class.after_update_path.blank?
406
+ def redirect_path_from_resource_option(action = :after_update_path)
407
+ return nil if @resource.class.send(action).blank?
405
408
 
406
- if @resource.class.after_create_path == :index
409
+ if @resource.class.send(action) == :index
407
410
  resources_path(resource: @resource)
411
+ elsif @resource.class.send(action) == :edit
412
+ edit_resource_path(resource: @resource, model: @resource.model)
408
413
  else
409
414
  resource_path(model: @model, resource: @resource)
410
415
  end
@@ -12,10 +12,9 @@ module Avo
12
12
  end
13
13
  end
14
14
 
15
- # Create the `route_key` from the model key so the namespaced models get the proper path (SomeModule::Post -> some_module_post).
16
- # Add the `_index` suffix for the uncountable models so they get the correct path (`fish_index`)
17
- route_key = resource.model_key
18
- route_key << "_index" if resource.model_name.singular == resource.model_name.plural
15
+ route_key = resource.route_key
16
+ # Add the `_index` suffix for the uncountable names so they get the correct path (`fish_index`)
17
+ route_key << "_index" if resource.route_key == resource.singular_route_key
19
18
 
20
19
  avo.send :"resources_#{route_key}_path", **existing_params, **args
21
20
  end
@@ -33,19 +32,19 @@ module Avo
33
32
  id = resource_id
34
33
  end
35
34
 
36
- avo.send :"resources_#{resource.singular_model_key}_path", id, **args
35
+ avo.send :"resources_#{resource.singular_route_key}_path", id, **args
37
36
  end
38
37
 
39
38
  def new_resource_path(model:, resource:, **args)
40
- avo.send :"new_resources_#{resource.singular_model_key}_path", **args
39
+ avo.send :"new_resources_#{resource.singular_route_key}_path", **args
41
40
  end
42
41
 
43
42
  def edit_resource_path(model:, resource:, **args)
44
- avo.send :"edit_resources_#{resource.singular_model_key}_path", model, **args
43
+ avo.send :"edit_resources_#{resource.singular_route_key}_path", model, **args
45
44
  end
46
45
 
47
46
  def resource_attach_path(resource, model_id, related_name, related_id = nil)
48
- helpers.avo.resources_associations_new_path(resource.singular_model_key, model_id, related_name)
47
+ helpers.avo.resources_associations_new_path(resource.singular_route_key, model_id, related_name)
49
48
  end
50
49
 
51
50
  def resource_detach_path(
@@ -79,7 +78,7 @@ module Avo
79
78
  end
80
79
 
81
80
  def order_up_resource_path(model:, resource:, **args)
82
- avo.send :"order_up_resources_#{resource.singular_model_key}_path", model, **args
81
+ avo.send :"order_up_resources_#{resource.singular_route_key}_path", model, **args
83
82
  end
84
83
  end
85
84
  end
@@ -7,7 +7,6 @@ import BelongsToFieldController from './controllers/fields/belongs_to_field_cont
7
7
  import BooleanFilterController from './controllers/boolean_filter_controller'
8
8
  import CodeFieldController from './controllers/fields/code_field_controller'
9
9
  import CopyToClipboardController from './controllers/copy_to_clipboard_controller'
10
- import CourseResourceController from './controllers/custom/course_resource_controller'
11
10
  import DashboardCardController from './controllers/dashboard_card_controller'
12
11
  import DateFieldController from './controllers/fields/date_field_controller'
13
12
  import FilterController from './controllers/filter_controller'
@@ -70,4 +69,3 @@ application.register('simple-mde', SimpleMdeController)
70
69
  application.register('trix-field', TrixFieldController)
71
70
 
72
71
  // Custom controllers
73
- application.register('course-resource', CourseResourceController)
@@ -1 +1,2 @@
1
- <%= render Avo::Views::ResourceEditComponent.new(resource: @resource) %>
1
+ <%= render Avo::Views::ResourceEditComponent.new(resource: @resource, view: @view, actions: @actions) %>
2
+
@@ -1 +1 @@
1
- <%= render Avo::Views::ResourceNewComponent.new(resource: @resource, model: @model) %>
1
+ <%= render Avo::Views::ResourceEditComponent.new(resource: @resource, model: @model, view: @view, actions: @actions) %>
@@ -5,13 +5,27 @@
5
5
  </a>
6
6
  </div>
7
7
  <% end %>
8
-
9
8
  <% if Avo::App.error_messages.present? %>
10
- <% Avo::App.error_messages.each do |message| %>
11
- <div class="w-full inset-auto bottom-0 z-50 mb-4 opacity-75 hover:opacity-100 transition-opacity duration-150">
12
- <a href="https://avohq.io/pricing" target="_blank" class="rounded bg-orange-700 text-white py-2 px-4 text-sm block items-center flex leading-tight">
13
- <%= svg "exclamation", class: "h-6 inline mr-2 text-bold flex-shrink-0 mr-1" %> <%= message %>
14
- </a>
15
- </div>
9
+ <% Avo::App.error_messages.each do |error| %>
10
+ <% if error.is_a? Hash %>
11
+ <%
12
+ url, message, target = error.values_at :url, :message, :target
13
+ %>
14
+ <div class="w-full inset-auto bottom-0 z-50 mb-4 opacity-75 hover:opacity-100 transition-opacity duration-150">
15
+ <a href="<%= url %>" target="<%= target %>" class="rounded bg-orange-700 text-white py-2 px-4 text-sm items-center flex leading-tight space-x-2">
16
+ <%= svg "exclamation", class: "h-6 inline mr-2 text-bold flex-shrink-0 mr-1" %>
17
+ <div>
18
+ <%= simple_format message %>
19
+ </div>
20
+ </a>
21
+ </div>
22
+ <% elsif error.is_a? String %>
23
+ <div class="w-full inset-auto bottom-0 z-50 mb-4 opacity-75 hover:opacity-100 transition-opacity duration-150">
24
+ <div class="rounded bg-orange-700 text-white py-2 px-4 text-sm items-center flex leading-tight space-x-2">
25
+ <%= svg "exclamation", class: "h-6 inline mr-2 text-bold flex-shrink-0 mr-1" %>
26
+ <div><%= simple_format error %></div>
27
+ </div>
28
+ </div>
29
+ <% end %>
16
30
  <% end %>
17
31
  <% end %>
@@ -30,6 +30,14 @@
30
30
  sort_direction = 'desc'
31
31
  end
32
32
  classes = "text-gray-500 tracking-tight leading-tight text-xs font-semibold"
33
+ classes += case field.index_text_align.to_sym
34
+ when :right
35
+ " text-right"
36
+ when :center
37
+ " text-center"
38
+ else
39
+ ""
40
+ end
33
41
  %>
34
42
  <th class="text-left uppercase px-3 py-2 whitespace-nowrap rounded-l">
35
43
  <% if field.sortable %>
@@ -38,7 +46,7 @@
38
46
  <%= render partial: 'avo/partials/sortable_component', locals: {field: field} %>
39
47
  <% end %>
40
48
  <% else %>
41
- <div class="flex items-center <%= classes %>">
49
+ <div class="block w-full <%= classes %>">
42
50
  <%= field.name %>
43
51
  </div>
44
52
  <% end %>
data/bin/test CHANGED
@@ -12,6 +12,7 @@ fi;
12
12
  # Run system tests
13
13
  if [[ -z "$1" ]] || [[ "$1" == "system" ]]; then
14
14
  yarn build:js
15
+ yarn build:custom-js
15
16
  yarn build:css
16
17
  bundle exec rspec ./spec --tag type:system
17
18
  fi;
data/lib/avo/app.rb CHANGED
@@ -14,7 +14,7 @@ module Avo
14
14
  class_attribute :view_context, default: nil
15
15
  class_attribute :params, default: {}
16
16
  class_attribute :translation_enabled, default: false
17
- class_attribute :error_messages, default: []
17
+ class_attribute :error_messages
18
18
 
19
19
  class << self
20
20
  def boot
@@ -52,6 +52,7 @@ module Avo
52
52
  Rails.logger.debug "[Avo] Failed to set ActiveStorage::Current.url_options, #{exception.inspect}"
53
53
  end
54
54
 
55
+ check_bad_resources
55
56
  init_resources
56
57
  init_dashboards if license.has_with_trial(:dashboards)
57
58
  end
@@ -80,6 +81,22 @@ module Avo
80
81
  )
81
82
  end
82
83
 
84
+ def check_bad_resources
85
+ resources.each do |resource|
86
+ has_model = resource.model_class.present?
87
+
88
+ unless has_model
89
+ possible_model = resource.class.to_s.gsub 'Resource', ''
90
+
91
+ Avo::App.error_messages.push({
92
+ url: "https://docs.avohq.io/2.0/resources.html#custom-model-class",
93
+ target: "_blank",
94
+ message: "#{resource.class.to_s} does not have a valid model assigned. It failed to find the #{possible_model} model. \n\r Please create that model or assign one using self.model_class = YOUR_MODEL"
95
+ })
96
+ end
97
+ end
98
+ end
99
+
83
100
  def init_resources
84
101
  self.resources = BaseResource.descendants
85
102
  .select do |resource|
@@ -120,9 +120,14 @@ module Avo
120
120
  end
121
121
 
122
122
  def visible_in_view
123
- return true unless visible.present?
123
+ # Run the visible block if available
124
+ return instance_exec(resource: self.class.resource, view: view, &visible) if visible.present?
124
125
 
125
- instance_exec(resource: self.class.resource, view: view, &visible)
126
+ # Hide on the :new view by default
127
+ return false if view == :new
128
+
129
+ # Show on all other views
130
+ true
126
131
  end
127
132
 
128
133
  def param_id
@@ -5,8 +5,10 @@ module Avo
5
5
 
6
6
  include ActionView::Helpers::UrlHelper
7
7
  include Avo::Concerns::HasTools
8
+ include Avo::Concerns::HasModel
8
9
  include Avo::Concerns::HasFields
9
10
  include Avo::Concerns::HasStimulusControllers
11
+ include Avo::Concerns::ModelClassConstantized
10
12
 
11
13
  delegate :view_context, to: ::Avo::App
12
14
  delegate :simple_format, :content_tag, to: :view_context
@@ -28,7 +30,6 @@ module Avo
28
30
  class_attribute :search_query, default: nil
29
31
  class_attribute :search_query_help, default: ""
30
32
  class_attribute :includes, default: []
31
- class_attribute :model_class
32
33
  class_attribute :translation_key
33
34
  class_attribute :default_view_type, default: :table
34
35
  class_attribute :devise_password_optional, default: false
@@ -435,7 +436,11 @@ module Avo
435
436
  end
436
437
 
437
438
  def route_key
438
- model_class.model_name.route_key
439
+ class_name_without_resource.underscore.pluralize
440
+ end
441
+
442
+ def singular_route_key
443
+ route_key.singularize
439
444
  end
440
445
 
441
446
  # This is used as the model class ID
@@ -22,6 +22,13 @@ module Avo
22
22
  end
23
23
  end
24
24
 
25
+ # Filters out the resources that are missing the model_class
26
+ def valid_resources
27
+ resources.select do |resource|
28
+ resource.model_class.present?
29
+ end
30
+ end
31
+
25
32
  # Returns the Avo resource by camelized name
26
33
  #
27
34
  # get_resource_by_name('User') => UserResource
@@ -45,9 +52,10 @@ module Avo
45
52
  # get_resource_by_name('User') => UserResource
46
53
  # get_resource_by_name(User) => UserResource
47
54
  def get_resource_by_model_name(name)
48
- resources.find do |resource|
49
- resource.model_class.model_name.name == name.to_s
50
- end
55
+ valid_resources
56
+ .find do |resource|
57
+ resource.model_class.model_name.name == name.to_s
58
+ end
51
59
  end
52
60
 
53
61
  # Returns the Avo resource by singular snake_cased name
@@ -55,9 +63,10 @@ module Avo
55
63
  # get_resource_by_controller_name('delayed_backend_active_record_jobs') => DelayedJobResource
56
64
  # get_resource_by_controller_name('users') => UserResource
57
65
  def get_resource_by_controller_name(name)
58
- resources.find do |resource|
59
- resource.model_class.to_s.pluralize.underscore.tr("/", "_") == name.to_s
60
- end
66
+ valid_resources
67
+ .find do |resource|
68
+ resource.model_class.to_s.pluralize.underscore.tr("/", "_") == name.to_s
69
+ end
61
70
  end
62
71
 
63
72
  # Returns the Avo resource by some name
@@ -73,9 +82,10 @@ module Avo
73
82
  end
74
83
 
75
84
  def get_available_resources(user = nil)
76
- resources.select do |resource|
77
- Services::AuthorizationService.authorize user, resource.model_class, Avo.configuration.authorization_methods.stringify_keys["index"], raise_exception: false
78
- end
85
+ valid_resources
86
+ .select do |resource|
87
+ Services::AuthorizationService.authorize user, resource.model_class, Avo.configuration.authorization_methods.stringify_keys["index"], raise_exception: false
88
+ end
79
89
  .sort_by { |r| r.name }
80
90
  end
81
91
 
@@ -85,9 +95,6 @@ module Avo
85
95
 
86
96
  def resources_for_navigation(user = nil)
87
97
  get_available_resources(current_user)
88
- .select do |resource|
89
- resource.model_class.present?
90
- end
91
98
  .select do |resource|
92
99
  resource.visible_on_sidebar
93
100
  end
@@ -0,0 +1,11 @@
1
+ module Avo
2
+ module Concerns
3
+ module HasModel
4
+ extend ActiveSupport::Concern
5
+
6
+ def has_model_id?
7
+ model.present? && model.id.present?
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,23 @@
1
+ module Avo
2
+ module Concerns
3
+ module ModelClassConstantized
4
+ extend ActiveSupport::Concern
5
+
6
+ class_methods do
7
+ attr_reader :model_class
8
+
9
+ # Cast the model class to a constantized version and memoize it like that
10
+ def model_class=(value)
11
+ @model_class = case value
12
+ when Class
13
+ value
14
+ when String, Symbol
15
+ value.to_s.safe_constantize
16
+ else
17
+ raise ArgumentError.new "Failed to find a proper model class for #{self.to_s}"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -14,7 +14,7 @@ module Avo
14
14
  # resource.model_class.present?
15
15
  # end
16
16
  .map do |resource|
17
- router.resources resource.new.model_key
17
+ router.resources resource.new.route_key
18
18
  end
19
19
  end
20
20
  end
data/lib/avo/engine.rb CHANGED
@@ -17,8 +17,6 @@ module Avo
17
17
  ::Avo::App.boot
18
18
  end
19
19
 
20
- config.i18n.load_path += Dir[Avo::Engine.root.join("lib", "generators", "avo", "templates", "locales", "*.{rb,yml}")]
21
-
22
20
  initializer "avo.autoload" do |app|
23
21
  [
24
22
  ["app", "avo", "fields"],
@@ -73,7 +71,7 @@ module Avo
73
71
  begin
74
72
  Licensing::HQ.new.clear_response
75
73
  rescue => exception
76
- puts "Failed to clear Avo HQ response: #{e.message}"
74
+ puts "Failed to clear Avo HQ response: #{exception.message}"
77
75
  end
78
76
  end
79
77
  end
@@ -9,6 +9,7 @@ module Avo
9
9
 
10
10
  include Avo::Concerns::HandlesFieldArgs
11
11
  include Avo::Concerns::HasHTMLAttributes
12
+ include Avo::Fields::Concerns::IsRequired
12
13
 
13
14
  delegate :view_context, to: ::Avo::App
14
15
  delegate :simple_format, :content_tag, to: :view_context
@@ -0,0 +1,17 @@
1
+ module Avo
2
+ module Fields
3
+ module Concerns
4
+ module IsRequired
5
+ extend ActiveSupport::Concern
6
+
7
+ def is_required?
8
+ if required.respond_to? :call
9
+ Avo::Hosts::ViewRecordHost.new(block: required, record: model, view: view).handle
10
+ else
11
+ required
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,7 @@
1
+ module Avo
2
+ module Hosts
3
+ class ViewRecordHost < RecordHost
4
+ option :view
5
+ end
6
+ end
7
+ end
@@ -17,4 +17,8 @@ class Avo::Menu::BaseItem
17
17
  Avo::Hosts::BaseHost.new(block: visible).handle
18
18
  end
19
19
  end
20
+
21
+ def navigation_label
22
+ label || entity_label
23
+ end
20
24
  end
@@ -2,6 +2,7 @@ class Avo::Menu::Dashboard < Avo::Menu::BaseItem
2
2
  extend Dry::Initializer
3
3
 
4
4
  option :dashboard
5
+ option :label, optional: true
5
6
 
6
7
  def parsed_dashboard
7
8
  dashboard_by_id || dashboard_by_name
@@ -14,4 +15,8 @@ class Avo::Menu::Dashboard < Avo::Menu::BaseItem
14
15
  def dashboard_by_id
15
16
  Avo::App.get_dashboard_by_id dashboard.to_s
16
17
  end
18
+
19
+ def entity_label
20
+ parsed_dashboard.navigation_label
21
+ end
17
22
  end
@@ -2,8 +2,13 @@ class Avo::Menu::Resource < Avo::Menu::BaseItem
2
2
  extend Dry::Initializer
3
3
 
4
4
  option :resource
5
+ option :label, optional: true
5
6
 
6
7
  def parsed_resource
7
8
  Avo::App.guess_resource resource.to_s
8
9
  end
10
+
11
+ def entity_label
12
+ parsed_resource.navigation_label
13
+ end
9
14
  end
data/lib/avo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "2.8.0" unless const_defined?(:VERSION)
2
+ VERSION = "2.9.1.pre2" unless const_defined?(:VERSION)
3
3
  end
data/lib/avo.rb CHANGED
@@ -7,6 +7,7 @@ loader.inflector.inflect(
7
7
  "html" => "HTML",
8
8
  "has_html_attributes" => "HasHTMLAttributes"
9
9
  )
10
+ loader.ignore("#{__dir__}/generators")
10
11
  loader.setup
11
12
 
12
13
  # .//*,,.....,,*/(*
@@ -13,10 +13,7 @@ module Generators
13
13
  route "mount Avo::Engine, at: Avo.configuration.root_path"
14
14
 
15
15
  template "initializer/avo.tt", "config/initializers/avo.rb"
16
- template "locales/avo.en.yml", "config/locales/avo.en.yml"
17
- template "locales/avo.nb-NO.yml", "config/locales/avo.nb-NO.yml"
18
- template "locales/avo.pt-BR.yml", "config/locales/avo.pt-BR.yml"
19
- template "locales/avo.ro.yml", "config/locales/avo.ro.yml"
16
+ directory File.join(__dir__, "templates", "locales"), "config/locales"
20
17
  end
21
18
  end
22
19
  end