avo 3.0.1.beta2 → 3.0.1.beta4
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.lock +1 -1
- data/app/components/avo/views/resource_show_component.html.erb +1 -1
- data/app/controllers/avo/base_controller.rb +38 -0
- data/app/helpers/avo/resources_helper.rb +1 -1
- data/app/views/avo/actions/show.html.erb +1 -1
- data/app/views/avo/base/edit.html.erb +1 -1
- data/app/views/avo/base/index.html.erb +1 -1
- data/app/views/avo/base/new.html.erb +1 -1
- data/app/views/avo/base/show.html.erb +1 -1
- data/lib/avo/base_resource.rb +6 -1
- data/lib/avo/configuration.rb +2 -0
- data/lib/avo/dsl/field_parser.rb +1 -1
- data/lib/avo/licensing/license_manager.rb +3 -0
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/concerns/parent_controller.rb +20 -0
- data/lib/generators/avo/controller_generator.rb +3 -0
- data/lib/generators/avo/eject_generator.rb +103 -15
- data/lib/generators/avo/field_generator.rb +49 -2
- data/lib/generators/avo/resource_generator.rb +5 -2
- data/lib/generators/avo/templates/initializer/avo.tt +1 -0
- data/lib/generators/avo/templates/resource/controller.tt +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 737f7485e4fbc1d44c4241c0f39010b74d078f58e0cc06279223bb81e9878079
|
4
|
+
data.tar.gz: b19cc62af7812c430274e0f0b002843a7601ef16e81fa32b0dfc2ae8d96ca304
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 995a9e1a12c9bce7368abdc7fb6b5cae46dff35603f3d7b51e4942a730d4f314f52fbfd04ee38948b3c919d3bf25440131559b5bed3a5af7331b608c50ef69d0
|
7
|
+
data.tar.gz: 8491c4c0b5a55144ee300574788591c45596b9b97e193e26688f01e8b319f0895eff3b3b55e9c7dca74bf18021f0cb00180f7d624bf22d4e7690daae1456c096
|
data/Gemfile.lock
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
resource_name: @resource.class.to_s,
|
5
5
|
record_id: @resource.record.id,
|
6
6
|
selected_resources_name: @resource.model_key,
|
7
|
-
selected_resources: [@resource.record.
|
7
|
+
selected_resources: [@resource.record.to_param],
|
8
8
|
**@resource.stimulus_data_attributes
|
9
9
|
} do %>
|
10
10
|
<%= render Avo::PanelComponent.new(name: title, description: @resource.description, display_breadcrumbs: @reflection.blank?, index: 0, data: { panel_id: "main" }) do |c| %>
|
@@ -75,6 +75,8 @@ module Avo
|
|
75
75
|
@resources = @records.map do |record|
|
76
76
|
@resource.hydrate(record: record, params: params).dup
|
77
77
|
end
|
78
|
+
|
79
|
+
set_component_for __method__
|
78
80
|
end
|
79
81
|
|
80
82
|
def show
|
@@ -98,6 +100,8 @@ module Avo
|
|
98
100
|
|
99
101
|
add_breadcrumb @resource.record_title
|
100
102
|
add_breadcrumb I18n.t("avo.details").upcase_first
|
103
|
+
|
104
|
+
set_component_for __method__
|
101
105
|
end
|
102
106
|
|
103
107
|
def new
|
@@ -119,6 +123,8 @@ module Avo
|
|
119
123
|
|
120
124
|
add_breadcrumb @resource.plural_name.humanize, resources_path(resource: @resource)
|
121
125
|
add_breadcrumb t("avo.new").humanize
|
126
|
+
|
127
|
+
set_component_for __method__, fallback_view: :edit
|
122
128
|
end
|
123
129
|
|
124
130
|
def create
|
@@ -161,6 +167,8 @@ module Avo
|
|
161
167
|
add_breadcrumb t("avo.new").humanize
|
162
168
|
set_actions
|
163
169
|
|
170
|
+
set_component_for :edit
|
171
|
+
|
164
172
|
if saved
|
165
173
|
create_success_action
|
166
174
|
else
|
@@ -170,6 +178,8 @@ module Avo
|
|
170
178
|
|
171
179
|
def edit
|
172
180
|
set_actions
|
181
|
+
|
182
|
+
set_component_for __method__
|
173
183
|
end
|
174
184
|
|
175
185
|
def update
|
@@ -178,6 +188,8 @@ module Avo
|
|
178
188
|
@resource = @resource.hydrate(record: @record, view: :edit, user: _current_user)
|
179
189
|
set_actions
|
180
190
|
|
191
|
+
set_component_for :edit
|
192
|
+
|
181
193
|
if saved
|
182
194
|
update_success_action
|
183
195
|
else
|
@@ -540,5 +552,31 @@ module Avo
|
|
540
552
|
def pagy_query
|
541
553
|
@query
|
542
554
|
end
|
555
|
+
|
556
|
+
# Set the view component for the current view
|
557
|
+
# It will try to use the custom component if it's set, otherwise it will use the default one
|
558
|
+
def set_component_for(view, fallback_view: nil)
|
559
|
+
# Fetch the components from the resource
|
560
|
+
components = Avo::ExecutionContext.new(
|
561
|
+
target: @resource.components,
|
562
|
+
resource: @resource,
|
563
|
+
record: @record,
|
564
|
+
view: @view
|
565
|
+
).handle
|
566
|
+
|
567
|
+
# If the component is not set, use the default one
|
568
|
+
if (custom_component = components.dig("resource_#{view}_component".to_sym)).nil?
|
569
|
+
return @component = "Avo::Views::Resource#{(fallback_view || view).to_s.classify}Component".constantize
|
570
|
+
end
|
571
|
+
|
572
|
+
# If the component is set, try to use it
|
573
|
+
@component = custom_component.to_s.safe_constantize
|
574
|
+
|
575
|
+
# If the component is not found, raise an error
|
576
|
+
if @component.nil?
|
577
|
+
raise "The component '#{custom_component}' was not found.\n" \
|
578
|
+
"That component was fetched from 'self.components' option inside '#{@resource.class}' resource."
|
579
|
+
end
|
580
|
+
end
|
543
581
|
end
|
544
582
|
end
|
@@ -38,7 +38,7 @@ module Avo
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def item_selector_init(resource)
|
41
|
-
"data-resource-name='#{resource.model_key}' data-resource-id='#{resource.record.
|
41
|
+
"data-resource-name='#{resource.model_key}' data-resource-id='#{resource.record.to_param}' data-controller='item-selector'"
|
42
42
|
end
|
43
43
|
|
44
44
|
def item_selector_input(floating: false, size: :md)
|
@@ -21,7 +21,7 @@
|
|
21
21
|
<%= @action.get_message %>
|
22
22
|
</div>
|
23
23
|
<%= hidden_field_tag :action_id, @action.param_id %>
|
24
|
-
<%= form.hidden_field :avo_resource_ids, value: params[:
|
24
|
+
<%= form.hidden_field :avo_resource_ids, value: params[:resource_ids], 'data-action-target': 'resourceIds' %>
|
25
25
|
<%= form.hidden_field :avo_selected_query, 'data-action-target': 'selectedAllQuery' %>
|
26
26
|
<%= form.hidden_field :arguments, value: params[:arguments] %>
|
27
27
|
<% if @action.get_fields.present? %>
|
@@ -1 +1 @@
|
|
1
|
-
<%= render
|
1
|
+
<%= render @component.new(resource: @resource, view: @view, actions: @actions) %>
|
@@ -1,2 +1,2 @@
|
|
1
|
-
<%= render
|
1
|
+
<%= render @component.new(resource: @resource, record: @record, view: @view, actions: @actions) %>
|
2
2
|
|
data/lib/avo/base_resource.rb
CHANGED
@@ -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 }
|
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
|
|
data/lib/avo/configuration.rb
CHANGED
@@ -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)
|
data/lib/avo/dsl/field_parser.rb
CHANGED
@@ -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 = "
|
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
|
data/lib/avo/version.rb
CHANGED
@@ -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
|
-
|
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
|
25
|
-
|
26
|
-
|
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
|
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
|
-
|
13
|
-
|
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"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: avo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.1.
|
4
|
+
version: 3.0.1.beta4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adrian Marin
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-08-
|
12
|
+
date: 2023-08-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -1846,6 +1846,7 @@ files:
|
|
1846
1846
|
- lib/generators/avo/action_generator.rb
|
1847
1847
|
- lib/generators/avo/base_generator.rb
|
1848
1848
|
- lib/generators/avo/card_generator.rb
|
1849
|
+
- lib/generators/avo/concerns/parent_controller.rb
|
1849
1850
|
- lib/generators/avo/controller_generator.rb
|
1850
1851
|
- lib/generators/avo/dashboard_generator.rb
|
1851
1852
|
- lib/generators/avo/eject_generator.rb
|