avo 3.0.1.beta1 → 3.0.1.beta3

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.

@@ -1,2 +1,2 @@
1
- <%= render Avo::Views::ResourceEditComponent.new(resource: @resource, record: @record, view: @view, actions: @actions) %>
1
+ <%= render @component.new(resource: @resource, record: @record, view: @view, actions: @actions) %>
2
2
 
@@ -1,5 +1,5 @@
1
1
  <%= render Avo::TurboFrameWrapperComponent.new(params[:turbo_frame]) do %>
2
- <%= render Avo::Views::ResourceShowComponent.new(
2
+ <%= render @component.new(
3
3
  resource: @resource,
4
4
  reflection: @reflection,
5
5
  actions: @actions,
@@ -65,6 +65,7 @@ module Avo
65
65
  class_attribute :extra_params
66
66
  class_attribute :link_to_child_resource, default: false
67
67
  class_attribute :map_view
68
+ class_attribute :components, default: {}
68
69
 
69
70
  # EXTRACT:
70
71
  class_attribute :ordering
@@ -293,7 +294,11 @@ module Avo
293
294
 
294
295
  # def get_action_arguments / def get_filter_arguments / def get_scope_arguments
295
296
  define_method "get_#{entity}_arguments" do |entity_class|
296
- send("get_#{plural_entity}").find { |entity| entity[:class].to_s == entity_class.to_s }[:arguments]
297
+ klass = send("get_#{plural_entity}").find { |entity| entity[:class].to_s == entity_class.to_s }
298
+
299
+ raise "Couldn't find '#{entity_class}' in the 'def #{plural_entity}' method on your '#{self.class}' resource." if klass.nil?
300
+
301
+ klass[:arguments]
297
302
  end
298
303
  end
299
304
 
@@ -43,6 +43,7 @@ module Avo
43
43
  attr_accessor :sign_out_path_name
44
44
  attr_accessor :resources
45
45
  attr_accessor :prefix_path
46
+ attr_accessor :resource_parent_controller
46
47
 
47
48
  def initialize
48
49
  @root_path = "/avo"
@@ -93,6 +94,7 @@ module Avo
93
94
  @authorization_client = :pundit
94
95
  @field_wrapper_layout = :inline
95
96
  @resources = nil
97
+ @resource_parent_controller = "Avo::ResourcesController"
96
98
  end
97
99
 
98
100
  def current_user_method(&block)
@@ -47,7 +47,7 @@ module Avo
47
47
  else
48
48
  # The symbol can be transformed to a class and found.
49
49
  class_name = as.to_s.camelize
50
- field_class = "#{class_name}Field"
50
+ field_class = "Avo::Fields::#{class_name}Field"
51
51
 
52
52
  # Discover & load custom field classes
53
53
  if Object.const_defined? field_class
@@ -5,7 +5,7 @@ module Avo
5
5
  attr_accessor :cache_store
6
6
 
7
7
  # ENDPOINT = "https://v3.avohq.io/api/v1/licenses/check".freeze unless const_defined?(:ENDPOINT)
8
- # ENDPOINT = "https://avohq.io/api/v1/licenses/check".freeze unless const_defined?(:ENDPOINT)
8
+ ENDPOINT = "https://avohq.io/api/v1/licenses/check".freeze unless const_defined?(:ENDPOINT)
9
9
  REQUEST_TIMEOUT = 5 unless const_defined?(:REQUEST_TIMEOUT) # seconds
10
10
  CACHE_TIME = 3600 unless const_defined?(:CACHE_TIME) # seconds
11
11
 
data/lib/avo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "3.0.1.beta1" unless const_defined?(:VERSION)
2
+ VERSION = "3.0.1.beta3" unless const_defined?(:VERSION)
3
3
  end
@@ -0,0 +1,20 @@
1
+ module Generators
2
+ module Avo
3
+ module Concerns
4
+ module ParentController
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ class_option "parent-controller",
9
+ desc: "The name of the parent controller.",
10
+ type: :string,
11
+ required: false
12
+ end
13
+
14
+ def parent_controller
15
+ options["parent-controller"] || ::Avo.configuration.resource_parent_controller
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,8 +1,11 @@
1
1
  require_relative "named_base_generator"
2
+ require_relative "concerns/parent_controller"
2
3
 
3
4
  module Generators
4
5
  module Avo
5
6
  class ControllerGenerator < NamedBaseGenerator
7
+ include Generators::Avo::Concerns::ParentController
8
+
6
9
  source_root File.expand_path("templates", __dir__)
7
10
 
8
11
  namespace "avo:controller"
@@ -3,7 +3,20 @@ require_relative "base_generator"
3
3
  module Generators
4
4
  module Avo
5
5
  class EjectGenerator < BaseGenerator
6
- argument :filename, type: :string, required: true
6
+ class_option :partial,
7
+ desc: "The partial to eject. Example: ':logo', 'app/views/layouts/avo/application.html.erb'",
8
+ type: :string,
9
+ required: false
10
+
11
+ class_option :component,
12
+ desc: "The component to eject. Example: 'Avo::Index::TableRowComponent', 'avo/index/table_row_component'",
13
+ type: :string,
14
+ required: false
15
+
16
+ class_option :scope,
17
+ desc: "The scope of the component. Example: 'users', 'admins'",
18
+ type: :string,
19
+ required: false
7
20
 
8
21
  source_root ::Avo::Engine.root
9
22
 
@@ -21,19 +34,18 @@ module Generators
21
34
  }
22
35
 
23
36
  def handle
24
- if @filename.starts_with?(":")
25
- template_id = path_to_sym @filename
26
- template_path = TEMPLATES[template_id]
27
-
28
- if path_exists? template_path
29
- eject template_path
30
- else
31
- say("Failed to find the `#{template_id.to_sym}` template.", :yellow)
32
- end
33
- elsif path_exists? @filename
34
- eject @filename
37
+ if options[:partial].present?
38
+ eject_partial
39
+ elsif options[:component].present?
40
+ eject_component
35
41
  else
36
- say("Failed to find the `#{@filename}` template.", :yellow)
42
+ say "Please specify a partial or a component to eject.\n" \
43
+ "Examples: rails g avo:eject --partial :logo\n" \
44
+ " rails g avo:eject --partial app/views/layouts/avo/application.html.erb\n" \
45
+ " rails g avo:eject --component Avo::Index::TableRowComponent\n" \
46
+ " rails g avo:eject --component avo/index/table_row_component\n" \
47
+ " rails g avo:eject --component Avo::Views::ResourceIndexComponent --scope users\n" \
48
+ " rails g avo:eject --component avo/views/resource_index_component --scope users", :yellow
37
49
  end
38
50
  end
39
51
 
@@ -48,8 +60,84 @@ module Generators
48
60
  path.present? && File.file?(::Avo::Engine.root.join(path))
49
61
  end
50
62
 
51
- def eject(path)
52
- copy_file ::Avo::Engine.root.join(path), ::Rails.root.join(path)
63
+ def eject(path, dest_path = nil)
64
+ copy_file ::Avo::Engine.root.join(path), ::Rails.root.join(dest_path || path)
65
+ end
66
+
67
+ def eject_partial
68
+ if options[:partial].starts_with?(":")
69
+ template_id = path_to_sym options[:partial]
70
+ template_path = TEMPLATES[template_id]
71
+
72
+ if path_exists? template_path
73
+ return unless confirm_ejection_on template_path
74
+ eject template_path
75
+ else
76
+ say("Failed to find the `#{template_id.to_sym}` template.", :yellow)
77
+ end
78
+ elsif path_exists? options[:partial]
79
+ return unless confirm_ejection_on template_path
80
+ eject options[:partial]
81
+ else
82
+ say("Failed to find the `#{options[:partial]}` template.", :yellow)
83
+ end
84
+ end
85
+
86
+ def eject_component
87
+ # Underscore the component name
88
+ # Example: Avo::Views::ResourceIndexComponent => avo/views/resource_index_component
89
+ component = options[:component].underscore
90
+
91
+ # Get the component path for both, the rb and erb files
92
+ rb, erb = ["app/components/#{component}.rb", "app/components/#{component}.html.erb"]
93
+
94
+ # Return if one of the components doesn't exist
95
+ if !path_exists?(rb) || !path_exists?(erb)
96
+ return say("Failed to find the `#{options[:component]}` component.", :yellow)
97
+ end
98
+
99
+ # Add the scope to the component if it's possible
100
+ if add_scope? component
101
+ component = component.gsub("avo/views/", "avo/views/#{options[:scope]}/")
102
+ added_scope = true
103
+ end
104
+
105
+ # Confirm the ejection
106
+ return unless confirm_ejection_on component.camelize
107
+
108
+ # Get the destination path for both, the rb and erb files
109
+ dest_rb = "#{::Avo.configuration.view_component_path}/#{component}.rb"
110
+ dest_erb = "#{::Avo.configuration.view_component_path}/#{component}.html.erb"
111
+
112
+ # Eject the component
113
+ eject rb, dest_rb
114
+ eject erb, dest_erb
115
+
116
+ # Remame the component class if scope was added
117
+ # Example: Avo::Views::ResourceIndexComponent => Avo::Views::Admins::ResourceIndexComponent
118
+ if added_scope
119
+ [dest_rb, dest_erb].each do |path|
120
+ modified_content = File.read(path).gsub("Avo::Views::", "Avo::Views::#{options[:scope].camelize}::")
121
+
122
+ File.open(path, "w") do |file|
123
+ file.puts modified_content
124
+ end
125
+ end
126
+
127
+ say "You can now use this component on any resource by configuring the 'self.components' option.\n" \
128
+ " self.components = {\n" \
129
+ " #{component.split("/").last}: #{component.camelize}\n" \
130
+ " }", :green
131
+ end
132
+ end
133
+
134
+ def confirm_ejection_on(path)
135
+ say("By ejecting the '#{path}' \033[1myou'll take on the responsibility for maintain it.", :yellow)
136
+ yes?("Are you sure you want to eject the '#{path}'? [y/N]", :yellow)
137
+ end
138
+
139
+ def add_scope?(component)
140
+ component.starts_with?("avo/views/") && options[:scope].present?
53
141
  end
54
142
  end
55
143
  end
@@ -8,9 +8,56 @@ module Generators
8
8
  namespace "avo:field"
9
9
  desc "Add a custom Avo field to your project."
10
10
 
11
+ class_option "field-template", type: :string, required: false
12
+
11
13
  def handle
12
- directory "field/components", "#{::Avo.configuration.view_component_path}/avo/fields/#{singular_name}_field"
13
- template "field/%singular_name%_field.rb.tt", "app/avo/fields/#{singular_name}_field.rb"
14
+ return field_from_template if field_template.present?
15
+
16
+ directory "field/components", destination_components_path
17
+ template "field/%singular_name%_field.rb.tt", destination_field_path
18
+ end
19
+
20
+ no_tasks do
21
+ def field_from_template
22
+ if !File.file? ::Avo::Engine.root.join(template_field_path)
23
+ return say("Failed to find the `#{field_template}` template field.", :yellow)
24
+ end
25
+
26
+ if !Dir.exist? ::Avo::Engine.root.join(template_components_path)
27
+ return say("Failed to find the `#{field_template}` template field components.", :yellow)
28
+ end
29
+
30
+ directory ::Avo::Engine.root.join(template_components_path), destination_components_path
31
+ copy_file ::Avo::Engine.root.join(template_field_path), destination_field_path
32
+
33
+ Dir.glob("#{destination_components_path}/*").push(destination_field_path).each do |file|
34
+ modified_content = File.read(file).gsub("#{field_template.camelize}Field", "#{singular_name.camelize}Field")
35
+
36
+ File.open(file, "w") do |open_file|
37
+ open_file.puts modified_content
38
+ end
39
+ end
40
+ end
41
+
42
+ def field_template
43
+ options["field-template"]
44
+ end
45
+
46
+ def template_field_path
47
+ "lib/avo/fields/#{field_template}_field.rb"
48
+ end
49
+
50
+ def template_components_path
51
+ "app/components/avo/fields/#{field_template}_field"
52
+ end
53
+
54
+ def destination_components_path
55
+ "#{::Avo.configuration.view_component_path}/avo/fields/#{singular_name}_field"
56
+ end
57
+
58
+ def destination_field_path
59
+ "app/avo/fields/#{singular_name}_field.rb"
60
+ end
14
61
  end
15
62
  end
16
63
  end
@@ -1,16 +1,19 @@
1
1
  require_relative "named_base_generator"
2
+ require_relative "concerns/parent_controller"
2
3
 
3
4
  module Generators
4
5
  module Avo
5
6
  class ResourceGenerator < NamedBaseGenerator
7
+ include Generators::Avo::Concerns::ParentController
8
+
6
9
  source_root File.expand_path("templates", __dir__)
7
10
 
8
11
  namespace "avo:resource"
9
12
 
10
13
  class_option "model-class",
14
+ desc: "The name of the model.",
11
15
  type: :string,
12
- required: false,
13
- desc: "The name of the model."
16
+ required: false
14
17
 
15
18
  def create
16
19
  template "resource/resource.tt", "app/avo/resources/#{resource_name}.rb"
@@ -66,6 +66,7 @@ Avo.configure do |config|
66
66
  # config.disabled_features = []
67
67
  # config.buttons_on_form_footers = true
68
68
  # config.field_wrapper_layout = true
69
+ # config.resource_parent_controller = "Avo::ResourcesController"
69
70
 
70
71
  ## == Branding ==
71
72
  # config.branding = {
@@ -1,4 +1,4 @@
1
1
  # This controller has been generated to enable Rails' resource routes.
2
2
  # More information on https://docs.avohq.io/2.0/controllers.html
3
- class <%= controller_class %> < Avo::ResourcesController
3
+ class <%= controller_class %> < <%= parent_controller %>
4
4
  end