avo 3.0.0.pre18 → 3.0.0.pre19
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 +2 -2
- data/Gemfile.lock +23 -25
- data/Rakefile +2 -0
- data/{public/avo-assets/avo.css → app/assets/builds/avo.base.css} +587 -3848
- data/app/assets/builds/avo.base.js +124556 -0
- data/app/assets/builds/avo.base.js.map +7 -0
- data/app/assets/builds/avo.custom.js +6 -0
- data/app/assets/builds/avo.custom.js.map +7 -0
- data/app/assets/stylesheets/avo.base.css +1 -0
- data/app/assets/stylesheets/css/fields/tags.css +32 -0
- data/app/components/avo/actions_component.rb +1 -1
- data/app/components/avo/field_wrapper_component.html.erb +1 -1
- data/app/components/avo/field_wrapper_component.rb +1 -7
- data/app/components/avo/fields/boolean_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/common/badge_viewer_component.html.erb +1 -24
- data/app/components/avo/fields/common/badge_viewer_component.rb +24 -0
- data/app/components/avo/fields/common/boolean_check_component.html.erb +1 -12
- data/app/components/avo/fields/common/boolean_check_component.rb +2 -1
- data/app/components/avo/fields/common/gravatar_viewer_component.html.erb +1 -1
- data/app/components/avo/fields/common/gravatar_viewer_component.rb +2 -2
- data/app/components/avo/fields/common/heading_component.html.erb +3 -8
- data/app/components/avo/fields/common/heading_component.rb +1 -3
- data/app/components/avo/fields/common/key_value_component.html.erb +2 -2
- data/app/components/avo/fields/common/key_value_component.rb +2 -2
- data/app/components/avo/fields/common/progress_bar_component.rb +3 -9
- data/app/components/avo/fields/common/status_viewer_component.html.erb +3 -0
- data/app/components/avo/fields/edit_component.rb +1 -1
- data/app/components/avo/fields/external_image_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/file_field/index_component.html.erb +2 -2
- data/app/components/avo/fields/gravatar_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/heading_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/heading_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/id_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/index_component.rb +1 -1
- data/app/components/avo/fields/show_component.rb +1 -1
- data/app/components/avo/fields/text_field/index_component.html.erb +1 -1
- data/app/components/avo/index/field_wrapper_component.rb +1 -1
- data/app/components/avo/index/resource_controls_component.rb +1 -1
- data/app/components/avo/index/resource_table_component.rb +3 -9
- data/app/components/avo/resource_component.rb +9 -4
- data/app/components/avo/sidebar_profile_component.html.erb +4 -4
- data/app/components/avo/tab_group_component.html.erb +1 -1
- data/app/components/avo/tab_switcher_component.rb +2 -2
- data/app/components/avo/views/resource_edit_component.html.erb +9 -20
- data/app/components/avo/views/resource_edit_component.rb +5 -5
- data/app/components/avo/views/resource_index_component.rb +1 -1
- data/app/components/avo/views/resource_show_component.html.erb +1 -1
- data/app/components/avo/views/resource_show_component.rb +1 -1
- data/app/controllers/avo/actions_controller.rb +9 -20
- data/app/controllers/avo/application_controller.rb +5 -5
- data/app/controllers/avo/base_controller.rb +39 -1
- data/app/controllers/avo/search_controller.rb +19 -2
- data/app/controllers/concerns/avo/initializes_avo.rb +1 -0
- data/app/helpers/avo/resources_helper.rb +1 -1
- data/app/helpers/avo/url_helpers.rb +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/app/views/layouts/avo/application.html.erb +10 -2
- data/bin/dev +2 -0
- data/config/routes.rb +4 -3
- data/db/factories.rb +1 -1
- data/lib/avo/base_action.rb +21 -26
- data/lib/avo/base_resource.rb +13 -7
- data/lib/avo/concerns/filters_session_handler.rb +3 -3
- data/lib/avo/concerns/has_helpers.rb +18 -0
- data/lib/avo/concerns/has_items.rb +1 -5
- data/lib/avo/concerns/visible_in_different_views.rb +7 -1
- data/lib/avo/concerns/visible_items.rb +43 -0
- data/lib/avo/configuration.rb +28 -4
- data/lib/avo/current.rb +1 -6
- data/lib/avo/dsl/field_parser.rb +1 -1
- data/lib/avo/execution_context.rb +4 -1
- data/lib/avo/fields/badge_field.rb +1 -1
- data/lib/avo/fields/base_field.rb +21 -44
- data/lib/avo/fields/belongs_to_field.rb +1 -1
- data/lib/avo/fields/concerns/has_html_attributes.rb +2 -0
- data/lib/avo/fields/concerns/use_view_components.rb +45 -0
- data/lib/avo/fields/external_image_field.rb +2 -2
- data/lib/avo/fields/file_field.rb +2 -2
- data/lib/avo/fields/gravatar_field.rb +2 -2
- data/lib/avo/fields/has_base_field.rb +2 -2
- data/lib/avo/fields/heading_field.rb +5 -13
- data/lib/avo/fields/id_field.rb +2 -2
- data/lib/avo/fields/status_field.rb +3 -1
- data/lib/avo/fields/text_field.rb +2 -2
- data/lib/avo/filters/base_filter.rb +1 -1
- data/lib/avo/html/builder.rb +1 -1
- data/lib/avo/licensing/license_manager.rb +1 -1
- data/lib/avo/resources/items/holder.rb +0 -6
- data/lib/avo/resources/items/item_group.rb +2 -2
- data/lib/avo/resources/items/row.rb +3 -3
- data/lib/avo/resources/items/sidebar.rb +1 -1
- data/lib/avo/resources/items/tab.rb +2 -2
- data/lib/avo/resources/items/tab_group.rb +1 -1
- data/lib/avo/resources/resource_manager.rb +6 -1
- data/lib/avo/version.rb +1 -1
- data/lib/avo/view_inquirer.rb +36 -0
- data/lib/avo.rb +9 -0
- 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 +180 -15
- data/lib/generators/avo/field_generator.rb +49 -2
- data/lib/generators/avo/js/install_generator.rb +2 -2
- data/lib/generators/avo/resource_generator.rb +10 -7
- data/lib/generators/avo/tailwindcss/install_generator.rb +58 -12
- data/lib/generators/avo/templates/initializer/avo.tt +6 -1
- data/lib/generators/avo/templates/resource/controller.tt +1 -1
- data/lib/generators/avo/templates/tailwindcss/avo.tailwind.css +5 -3
- data/lib/generators/avo/templates/tailwindcss/tailwind.config.js +11 -0
- data/lib/tasks/avo_tasks.rake +33 -5
- data/public/avo-assets/avo.base.css +75 -4146
- metadata +14 -6
- data/config/master.key +0 -1
- data/public/avo-assets/avo.js +0 -513
- data/public/avo-assets/avo.js.map +0 -7
@@ -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
|
@@ -517,7 +529,7 @@ module Avo
|
|
517
529
|
|
518
530
|
if @resource.class.send(action) == :index
|
519
531
|
resources_path(resource: @resource)
|
520
|
-
elsif @resource.class.send(action) == :edit || Avo.configuration.resource_default_view
|
532
|
+
elsif @resource.class.send(action) == :edit || Avo.configuration.resource_default_view.edit?
|
521
533
|
edit_resource_path(resource: @resource, record: @resource.record)
|
522
534
|
else
|
523
535
|
resource_path(record: @record, resource: @resource)
|
@@ -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
|
@@ -9,6 +9,8 @@ module Avo
|
|
9
9
|
|
10
10
|
def show
|
11
11
|
render json: search_resources([resource])
|
12
|
+
rescue => error
|
13
|
+
render_search_error(error)
|
12
14
|
end
|
13
15
|
|
14
16
|
private
|
@@ -40,14 +42,14 @@ module Avo
|
|
40
42
|
query: resource.query_scope
|
41
43
|
).handle
|
42
44
|
|
45
|
+
query = apply_scope(query) if should_apply_any_scope?
|
46
|
+
|
43
47
|
# Get the count
|
44
48
|
results_count = query.reselect(resource.model_class.primary_key).count
|
45
49
|
|
46
50
|
# Get the results
|
47
51
|
query = query.limit(8)
|
48
52
|
|
49
|
-
query = apply_scope(query) if should_apply_any_scope?
|
50
|
-
|
51
53
|
results = apply_search_metadata(query, resource)
|
52
54
|
|
53
55
|
header = resource.plural_name
|
@@ -164,5 +166,20 @@ module Avo
|
|
164
166
|
parent_resource = Avo.resource_manager.get_resource_by_model_class params[:via_reflection_class]
|
165
167
|
parent_resource.find_record params[:via_reflection_id], params: params
|
166
168
|
end
|
169
|
+
|
170
|
+
def render_search_error(error)
|
171
|
+
raise error unless Rails.env.development?
|
172
|
+
|
173
|
+
render json: {
|
174
|
+
error: {
|
175
|
+
header: "🚨 An error occurred while searching. 🚨",
|
176
|
+
help: "Please see the error and fix it before deploying.",
|
177
|
+
results: {
|
178
|
+
_label: error.message
|
179
|
+
},
|
180
|
+
count: 1
|
181
|
+
}
|
182
|
+
}, status: 500
|
183
|
+
end
|
167
184
|
end
|
168
185
|
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)
|
@@ -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
|
|
@@ -12,10 +12,18 @@
|
|
12
12
|
<%= render Avo::AssetManager::StylesheetComponent.new asset_manager: Avo.asset_manager %>
|
13
13
|
<% if Avo::PACKED %>
|
14
14
|
<%= javascript_include_tag "/avo-assets/avo.base", "data-turbo-track": "reload", defer: true %>
|
15
|
-
|
15
|
+
<% if Rails.root.join("config", "avo", "tailwind.config.js").exist? %>
|
16
|
+
<%= stylesheet_link_tag "avo.tailwind", "data-turbo-track": "reload", defer: true %>
|
17
|
+
<% else %>
|
18
|
+
<%= stylesheet_link_tag "/avo-assets/avo.base", "data-turbo-track": "reload", defer: true %>
|
19
|
+
<% end %>
|
16
20
|
<% else %>
|
17
21
|
<%= javascript_include_tag "avo.base", "data-turbo-track": "reload", defer: true %>
|
18
|
-
|
22
|
+
<% if Rails.root.join("config", "avo", "tailwind.config.js").exist? %>
|
23
|
+
<%= stylesheet_link_tag "avo.tailwind", "data-turbo-track": "reload", defer: true %>
|
24
|
+
<% else %>
|
25
|
+
<%= stylesheet_link_tag "avo.base", "data-turbo-track": "reload", defer: true %>
|
26
|
+
<% end %>
|
19
27
|
<% if Rails.env.development? %>
|
20
28
|
<%= javascript_include_tag "hotwire-livereload", defer: true %>
|
21
29
|
<% end %>
|
data/bin/dev
CHANGED
data/config/routes.rb
CHANGED
@@ -4,9 +4,10 @@ Avo::Engine.routes.draw do
|
|
4
4
|
get "resources", to: redirect(Avo.configuration.root_path)
|
5
5
|
get "dashboards", to: redirect(Avo.configuration.root_path)
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
# Mount Avo engines routes by default but leave it configurable in case the user wants to nest these under a scope.
|
8
|
+
if Avo.configuration.mount_avo_engines
|
9
|
+
instance_exec(&Avo.mount_engines)
|
10
|
+
end
|
10
11
|
|
11
12
|
post "/rails/active_storage/direct_uploads", to: "/active_storage/direct_uploads#create"
|
12
13
|
|
data/db/factories.rb
CHANGED
@@ -38,7 +38,7 @@ FactoryBot.define do
|
|
38
38
|
factory :project do
|
39
39
|
name { Faker::App.name }
|
40
40
|
status { ['closed', :rejected, :failed, 'loading', :running, :waiting].sample }
|
41
|
-
stage { ["Discovery", "Idea", "Done", "On hold", "Cancelled"].sample }
|
41
|
+
stage { ["Discovery", "Idea", "Done", "On hold", "Cancelled", "Drafting"].sample }
|
42
42
|
budget { Faker::Number.decimal(l_digits: 4) }
|
43
43
|
country { Faker::Address.country_code }
|
44
44
|
description { Faker::Markdown.sandwich(sentences: 5) }
|
data/lib/avo/base_action.rb
CHANGED
@@ -25,7 +25,7 @@ module Avo
|
|
25
25
|
delegate :view, to: :class
|
26
26
|
# TODO: find a differnet way to delegate this to the uninitialized Current variable
|
27
27
|
delegate :context, to: Avo::Current
|
28
|
-
def
|
28
|
+
def current_user
|
29
29
|
Avo::Current.user
|
30
30
|
end
|
31
31
|
delegate :params, to: Avo::Current
|
@@ -65,7 +65,7 @@ module Avo
|
|
65
65
|
self.class.record = record
|
66
66
|
self.class.resource = resource
|
67
67
|
self.class.user = user
|
68
|
-
self.class.view = view
|
68
|
+
self.class.view = Avo::ViewInquirer.new(view)
|
69
69
|
@arguments = arguments
|
70
70
|
|
71
71
|
self.class.message ||= I18n.t("avo.are_you_sure_you_want_to_run_this_option")
|
@@ -101,39 +101,34 @@ module Avo
|
|
101
101
|
end
|
102
102
|
|
103
103
|
def handle_action(**args)
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
104
|
+
processed_fields = if args[:fields].present?
|
105
|
+
# Fetching the field definitions and not the actual fields (get_fields) because they will break if the user uses a `visible` block and adds a condition using the `params` variable. The params are different in the show method and the handle method.
|
106
|
+
action_fields = get_field_definitions.map { |field| [field.id, field] }.to_h
|
107
|
+
|
108
|
+
# For some fields, like belongs_to, the id and database_id differ (user vs user_id).
|
109
|
+
# That's why we need to fetch the database_id for when we process the action.
|
110
|
+
action_fields_by_database_id = action_fields.map do |id, value|
|
111
|
+
[value.database_id.to_sym, value]
|
112
|
+
end.to_h
|
113
113
|
|
114
|
-
|
115
|
-
processed_fields = fields.to_unsafe_h.map do |name, value|
|
114
|
+
args[:fields].to_unsafe_h.map do |name, value|
|
116
115
|
field = action_fields_by_database_id[name.to_sym]
|
117
116
|
|
118
117
|
next if field.blank?
|
119
118
|
|
120
119
|
[name, field.resolve_attribute(value)]
|
121
|
-
end
|
122
|
-
|
123
|
-
processed_fields = processed_fields.reject(&:blank?).to_h
|
120
|
+
end.reject(&:blank?).to_h
|
124
121
|
else
|
125
|
-
|
122
|
+
{}
|
126
123
|
end
|
127
124
|
|
128
|
-
|
125
|
+
handle(
|
129
126
|
fields: processed_fields.with_indifferent_access,
|
130
|
-
current_user: current_user,
|
131
|
-
resource: resource
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
handle(**args)
|
127
|
+
current_user: args[:current_user],
|
128
|
+
resource: args[:resource],
|
129
|
+
records: args[:query],
|
130
|
+
query: args[:query]
|
131
|
+
)
|
137
132
|
|
138
133
|
self
|
139
134
|
end
|
@@ -141,7 +136,7 @@ module Avo
|
|
141
136
|
def visible_in_view(parent_resource: nil)
|
142
137
|
if visible.blank?
|
143
138
|
# Hide on the :new view by default
|
144
|
-
return false if view
|
139
|
+
return false if view.new?
|
145
140
|
|
146
141
|
# Show on all other views
|
147
142
|
return true
|
data/lib/avo/base_resource.rb
CHANGED
@@ -9,10 +9,11 @@ module Avo
|
|
9
9
|
include Avo::Concerns::HasStimulusControllers
|
10
10
|
include Avo::Concerns::ModelClassConstantized
|
11
11
|
include Avo::Concerns::HasDescription
|
12
|
+
include Avo::Concerns::HasHelpers
|
12
13
|
|
13
14
|
# Avo::Current methods
|
14
15
|
delegate :context, to: Avo::Current
|
15
|
-
def
|
16
|
+
def current_user
|
16
17
|
Avo::Current.user
|
17
18
|
end
|
18
19
|
delegate :params, to: Avo::Current
|
@@ -65,6 +66,7 @@ module Avo
|
|
65
66
|
class_attribute :extra_params
|
66
67
|
class_attribute :link_to_child_resource, default: false
|
67
68
|
class_attribute :map_view
|
69
|
+
class_attribute :components, default: {}
|
68
70
|
|
69
71
|
# EXTRACT:
|
70
72
|
class_attribute :ordering
|
@@ -232,14 +234,14 @@ module Avo
|
|
232
234
|
delegate :model_key, to: :class
|
233
235
|
|
234
236
|
def initialize(record: nil, view: nil, user: nil, params: nil)
|
235
|
-
@view = view if view.present?
|
237
|
+
@view = Avo::ViewInquirer.new(view) if view.present?
|
236
238
|
@user = user if user.present?
|
237
239
|
@params = params if params.present?
|
238
240
|
|
239
241
|
if record.present?
|
240
242
|
@record = record
|
241
243
|
|
242
|
-
hydrate_model_with_default_values if @view
|
244
|
+
hydrate_model_with_default_values if @view&.new?
|
243
245
|
end
|
244
246
|
|
245
247
|
detect_fields
|
@@ -293,19 +295,23 @@ module Avo
|
|
293
295
|
|
294
296
|
# def get_action_arguments / def get_filter_arguments / def get_scope_arguments
|
295
297
|
define_method "get_#{entity}_arguments" do |entity_class|
|
296
|
-
send("get_#{plural_entity}").find { |entity| entity[:class].to_s == entity_class.to_s }
|
298
|
+
klass = send("get_#{plural_entity}").find { |entity| entity[:class].to_s == entity_class.to_s }
|
299
|
+
|
300
|
+
raise "Couldn't find '#{entity_class}' in the 'def #{plural_entity}' method on your '#{self.class}' resource." if klass.nil?
|
301
|
+
|
302
|
+
klass[:arguments]
|
297
303
|
end
|
298
304
|
end
|
299
305
|
|
300
306
|
def hydrate(record: nil, view: nil, user: nil, params: nil)
|
301
|
-
@view = view if view.present?
|
307
|
+
@view = Avo::ViewInquirer.new(view) if view.present?
|
302
308
|
@user = user if user.present?
|
303
309
|
@params = params if params.present?
|
304
310
|
|
305
311
|
if record.present?
|
306
312
|
@record = record
|
307
313
|
|
308
|
-
hydrate_model_with_default_values if @view
|
314
|
+
hydrate_model_with_default_values if @view&.new?
|
309
315
|
end
|
310
316
|
|
311
317
|
self
|
@@ -440,7 +446,7 @@ module Avo
|
|
440
446
|
def hydrate_model_with_default_values
|
441
447
|
default_values = get_fields
|
442
448
|
.select do |field|
|
443
|
-
!field.computed
|
449
|
+
!field.computed && !field.is_a?(Avo::Fields::HeadingField)
|
444
450
|
end
|
445
451
|
.map do |field|
|
446
452
|
value = field.value
|
@@ -26,16 +26,16 @@ module Avo
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def filters_session_key
|
29
|
-
@filters_session_key ||=
|
29
|
+
@filters_session_key ||= "/filters/" << %w[
|
30
30
|
turbo_frame controller resource_name related_name
|
31
31
|
action id
|
32
|
-
].map { |key| params[key] }.compact.join(
|
32
|
+
].map { |key| params[key] }.compact.join("/")
|
33
33
|
end
|
34
34
|
|
35
35
|
def cache_resource_filters?
|
36
36
|
Avo::ExecutionContext.new(
|
37
37
|
target: Avo.configuration.cache_resource_filters,
|
38
|
-
current_user:
|
38
|
+
current_user: _current_user,
|
39
39
|
resource: @resource
|
40
40
|
).handle
|
41
41
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Avo
|
2
|
+
module Concerns
|
3
|
+
module HasHelpers
|
4
|
+
def helpers
|
5
|
+
@helpers ||= Class.new do
|
6
|
+
def initialize
|
7
|
+
helper_names = ActionController::Base.all_helpers_from_path Rails.root.join("app", "helpers")
|
8
|
+
helpers = ActionController::Base.modules_for_helpers helper_names
|
9
|
+
|
10
|
+
helpers.each do |helper|
|
11
|
+
extend helper
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end.new
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -30,10 +30,6 @@ module Avo
|
|
30
30
|
deprecated_dsl_api __method__, "fields"
|
31
31
|
end
|
32
32
|
|
33
|
-
def heading(body, **args)
|
34
|
-
deprecated_dsl_api __method__, "fields"
|
35
|
-
end
|
36
|
-
|
37
33
|
def sidebar(**args, &block)
|
38
34
|
deprecated_dsl_api __method__, "fields"
|
39
35
|
end
|
@@ -273,7 +269,7 @@ module Avo
|
|
273
269
|
end
|
274
270
|
.select do |item|
|
275
271
|
# On location field we can have field coordinates and setters with different names like latitude and longitude
|
276
|
-
if !item.is_a?(Avo::Fields::LocationField) && !item.is_heading? && view.in?([
|
272
|
+
if !item.is_a?(Avo::Fields::LocationField) && !item.is_heading? && view.in?(%w[edit update new create])
|
277
273
|
if item.respond_to?(:id)
|
278
274
|
item.resource.record.respond_to?("#{item.id}=")
|
279
275
|
else
|
@@ -61,7 +61,7 @@ module Avo
|
|
61
61
|
def except_on(*where)
|
62
62
|
show_on_all
|
63
63
|
normalize_views(where).flatten.each do |view|
|
64
|
-
|
64
|
+
hide_on_view view
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
@@ -113,12 +113,18 @@ module Avo
|
|
113
113
|
|
114
114
|
def normalize_views(*views_and_groups)
|
115
115
|
forms = views_and_groups.flatten! & [:forms]
|
116
|
+
display = views_and_groups & [:display]
|
116
117
|
|
117
118
|
if forms.present?
|
118
119
|
views_and_groups -= forms
|
119
120
|
views_and_groups += [:new, :edit]
|
120
121
|
end
|
121
122
|
|
123
|
+
if display.present?
|
124
|
+
views_and_groups -= display
|
125
|
+
views_and_groups += [:index, :show]
|
126
|
+
end
|
127
|
+
|
122
128
|
views_and_groups.flatten.uniq
|
123
129
|
end
|
124
130
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# This concern helps us figure out what items are visible for each tab, panel or sidebar
|
2
|
+
module Avo
|
3
|
+
module Concerns
|
4
|
+
module VisibleItems
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
def items
|
7
|
+
items_holder&.items || []
|
8
|
+
end
|
9
|
+
|
10
|
+
def visible_items
|
11
|
+
items
|
12
|
+
.select do |item|
|
13
|
+
if item.respond_to? :hydrate
|
14
|
+
item.hydrate(view: view, resource: resource)
|
15
|
+
end
|
16
|
+
|
17
|
+
visible(item)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def visible(item)
|
22
|
+
return item.visible? if !item.is_field?
|
23
|
+
|
24
|
+
return false if item.respond_to?(:authorized?) && item.resource.present? && !item.authorized?
|
25
|
+
|
26
|
+
item.visible? && item.visible_in_view?(view: view)
|
27
|
+
end
|
28
|
+
|
29
|
+
def visible?
|
30
|
+
any_item_visible = visible_items.any?
|
31
|
+
return any_item_visible if !respond_to?(:visible_on?)
|
32
|
+
|
33
|
+
visible_on?(view) && any_item_visible
|
34
|
+
end
|
35
|
+
|
36
|
+
def hydrate(view: nil)
|
37
|
+
@view = view
|
38
|
+
|
39
|
+
self
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/avo/configuration.rb
CHANGED
@@ -12,7 +12,6 @@ module Avo
|
|
12
12
|
attr_accessor :locale
|
13
13
|
attr_accessor :currency
|
14
14
|
attr_accessor :default_view_type
|
15
|
-
attr_accessor :license
|
16
15
|
attr_accessor :license_key
|
17
16
|
attr_accessor :authorization_methods
|
18
17
|
attr_accessor :authenticate
|
@@ -37,12 +36,14 @@ module Avo
|
|
37
36
|
attr_accessor :main_menu
|
38
37
|
attr_accessor :profile_menu
|
39
38
|
attr_accessor :model_resource_mapping
|
40
|
-
|
39
|
+
attr_reader :resource_default_view
|
41
40
|
attr_accessor :authorization_client
|
42
41
|
attr_accessor :field_wrapper_layout
|
43
42
|
attr_accessor :sign_out_path_name
|
44
43
|
attr_accessor :resources
|
45
44
|
attr_accessor :prefix_path
|
45
|
+
attr_accessor :resource_parent_controller
|
46
|
+
attr_accessor :mount_avo_engines
|
46
47
|
|
47
48
|
def initialize
|
48
49
|
@root_path = "/avo"
|
@@ -54,7 +55,6 @@ module Avo
|
|
54
55
|
@locale = nil
|
55
56
|
@currency = "USD"
|
56
57
|
@default_view_type = :table
|
57
|
-
@license = "community"
|
58
58
|
@license_key = nil
|
59
59
|
@current_user = proc {}
|
60
60
|
@authenticate = proc {}
|
@@ -89,10 +89,12 @@ module Avo
|
|
89
89
|
@main_menu = nil
|
90
90
|
@profile_menu = nil
|
91
91
|
@model_resource_mapping = {}
|
92
|
-
@resource_default_view =
|
92
|
+
@resource_default_view = Avo::ViewInquirer.new("show")
|
93
93
|
@authorization_client = :pundit
|
94
94
|
@field_wrapper_layout = :inline
|
95
95
|
@resources = nil
|
96
|
+
@resource_parent_controller = "Avo::ResourcesController"
|
97
|
+
@mount_avo_engines = true
|
96
98
|
end
|
97
99
|
|
98
100
|
def current_user_method(&block)
|
@@ -140,6 +142,28 @@ module Avo
|
|
140
142
|
def app_name
|
141
143
|
Avo::ExecutionContext.new(target: @app_name).handle
|
142
144
|
end
|
145
|
+
|
146
|
+
def license=(value)
|
147
|
+
if Rails.env.development?
|
148
|
+
puts "[Avo DEPRECATION WARNING]: The `config.license` configuration option is no longer supported and will be removed in future versions. Please discontinue its use and solely utilize the `license_key` instead."
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def license
|
153
|
+
gems = Gem::Specification.map {|gem| gem.name}
|
154
|
+
|
155
|
+
@license ||= if gems.include?("avo-advanced")
|
156
|
+
"advanced"
|
157
|
+
elsif gems.include?("avo-pro")
|
158
|
+
"pro"
|
159
|
+
elsif gems.include?("avo")
|
160
|
+
"community"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def resource_default_view=(view)
|
165
|
+
@resource_default_view = Avo::ViewInquirer.new(view.to_s)
|
166
|
+
end
|
143
167
|
end
|
144
168
|
|
145
169
|
def self.configuration
|
data/lib/avo/current.rb
CHANGED
@@ -24,16 +24,11 @@ class Avo::Current < ActiveSupport::CurrentAttributes
|
|
24
24
|
attribute :resource_manager
|
25
25
|
attribute :tool_manager
|
26
26
|
attribute :plugin_manager
|
27
|
+
attribute :locale
|
27
28
|
|
28
29
|
delegate :params, to: :request
|
29
30
|
|
30
31
|
def request
|
31
32
|
view_context.request || ActionDispatch::Request.empty
|
32
33
|
end
|
33
|
-
|
34
|
-
def current_user
|
35
|
-
Rails.logger.warn "DEPRECATION WARNING: Avo::Current.current_user become deprecated and will become obsolete on futhure versions. Please use Avo::Current.user instead."
|
36
|
-
|
37
|
-
user
|
38
|
-
end
|
39
34
|
end
|
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
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module Avo
|
2
2
|
class ExecutionContext
|
3
|
-
|
3
|
+
include Avo::Concerns::HasHelpers
|
4
|
+
|
5
|
+
attr_accessor :target, :context, :params, :view_context, :current_user, :request, :include, :main_app, :avo, :locale
|
4
6
|
|
5
7
|
def initialize(**args)
|
6
8
|
# Extend the class with custom modules if required.
|
@@ -24,6 +26,7 @@ module Avo
|
|
24
26
|
@params ||= Avo::Current.params
|
25
27
|
@request ||= Avo::Current.request
|
26
28
|
@view_context ||= Avo::Current.view_context
|
29
|
+
@locale ||= Avo::Current.locale
|
27
30
|
@main_app ||= @view_context.main_app
|
28
31
|
@avo ||= @view_context.avo
|
29
32
|
end
|