avo 2.18.1 → 2.19.0
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 +4 -5
- data/Gemfile.lock +75 -76
- data/app/components/avo/actions_component.html.erb +1 -1
- data/app/components/avo/actions_component.rb +4 -4
- data/app/components/avo/base_component.rb +17 -0
- data/app/components/avo/field_wrapper_component.rb +7 -1
- data/app/components/avo/fields/has_one_field/show_component.rb +1 -2
- data/app/components/avo/fields/index_component.rb +4 -3
- data/app/components/avo/filters_component.html.erb +1 -1
- data/app/components/avo/filters_component.rb +2 -2
- data/app/components/avo/index/grid_item_component.rb +2 -2
- data/app/components/avo/index/resource_controls_component.rb +2 -2
- data/app/components/avo/index/table_row_component.html.erb +1 -1
- data/app/components/avo/item_switcher_component.html.erb +1 -1
- data/app/components/avo/resource_component.rb +1 -1
- data/app/components/avo/resource_sidebar_component.rb +1 -6
- data/app/components/avo/sidebar_profile_component.rb +3 -1
- data/app/components/avo/tab_group_component.rb +1 -1
- data/app/components/avo/views/resource_show_component.html.erb +1 -1
- data/app/controllers/avo/application_controller.rb +6 -0
- data/app/controllers/avo/base_controller.rb +14 -7
- data/app/controllers/avo/dashboards/cards_controller.rb +37 -0
- data/app/helpers/avo/application_helper.rb +5 -1
- data/app/javascript/js/controllers/search_controller.js +11 -2
- data/app/views/avo/{cards → dashboards/cards}/_chartkick_card.html.erb +0 -0
- data/app/views/avo/{cards → dashboards/cards}/_metric_card.html.erb +0 -0
- data/app/views/avo/{cards → dashboards/cards}/chartkick_missing.html.erb +0 -0
- data/app/views/avo/{cards → dashboards/cards}/show.html.erb +0 -0
- data/app/views/avo/partials/_branding.html.erb +1 -0
- data/avo.gemspec +1 -1
- data/bin/init +11 -1
- data/bin/test +1 -0
- data/config/routes.rb +2 -2
- data/db/factories.rb +10 -0
- data/lib/avo/app.rb +11 -1
- data/lib/avo/base_action.rb +19 -9
- data/lib/avo/base_resource.rb +3 -6
- data/lib/avo/concerns/filters_session_handler.rb +43 -0
- data/lib/avo/concerns/has_fields.rb +2 -0
- data/lib/avo/concerns/visible_items.rb +44 -0
- data/lib/avo/configuration/branding.rb +10 -2
- data/lib/avo/configuration.rb +3 -0
- data/lib/avo/dynamic_router.rb +16 -15
- data/lib/avo/engine.rb +6 -9
- data/lib/avo/fields/base_field.rb +21 -12
- data/lib/avo/fields/concerns/has_default.rb +17 -0
- data/lib/avo/fields/concerns/is_readonly.rb +1 -1
- data/lib/avo/fields/concerns/is_required.rb +2 -2
- data/lib/avo/fields/has_base_field.rb +2 -0
- data/lib/avo/fields/key_value_field.rb +1 -1
- data/lib/avo/filters/base_filter.rb +17 -2
- data/lib/avo/hosts/resource_view_record_host.rb +7 -0
- data/lib/avo/hosts/visibility_host.rb +11 -0
- data/lib/avo/panel.rb +4 -1
- data/lib/avo/resources/controls/action.rb +1 -3
- data/lib/avo/sidebar.rb +1 -31
- data/lib/avo/tab.rb +5 -22
- data/lib/avo/version.rb +1 -1
- data/lib/avo.rb +9 -0
- data/lib/generators/avo/resource_generator.rb +281 -0
- data/lib/generators/avo/templates/action.tt +3 -0
- data/lib/generators/avo/templates/filters/boolean_filter.tt +3 -0
- data/lib/generators/avo/templates/filters/multiple_select_filter.tt +3 -0
- data/lib/generators/avo/templates/filters/select_filter.tt +3 -0
- data/lib/generators/avo/templates/filters/text_filter.tt +3 -0
- data/lib/generators/avo/templates/initializer/avo.tt +4 -0
- data/lib/generators/avo/templates/resource/controller.tt +1 -1
- data/lib/generators/avo/templates/resource/resource.tt +2 -2
- data/lib/generators/model_generator.rb +10 -0
- data/lib/generators/rails/avo_resource_generator.rb +11 -0
- data/public/avo-assets/avo.base.css +10 -10
- data/public/avo-assets/avo.base.js +1 -1
- data/public/avo-assets/avo.base.js.map +2 -2
- data/public/avo-assets/favicon.ico +0 -0
- data/{app/assets/svgs → public/avo-assets}/placeholder.svg +0 -0
- metadata +18 -11
- data/app/controllers/avo/cards_controller.rb +0 -35
- data/config/master.key +0 -1
@@ -1,5 +1,11 @@
|
|
1
1
|
module Avo
|
2
2
|
class ApplicationController < ::ActionController::Base
|
3
|
+
if defined?(Pundit::Authorization)
|
4
|
+
Avo::ApplicationController.include Pundit::Authorization
|
5
|
+
elsif defined?(Pundit)
|
6
|
+
Avo::ApplicationController.include Pundit
|
7
|
+
end
|
8
|
+
|
3
9
|
include Pagy::Backend
|
4
10
|
include Avo::ApplicationHelper
|
5
11
|
include Avo::UrlHelpers
|
@@ -2,6 +2,8 @@ require_dependency "avo/application_controller"
|
|
2
2
|
|
3
3
|
module Avo
|
4
4
|
class BaseController < ApplicationController
|
5
|
+
include Avo::Concerns::FiltersSessionHandler
|
6
|
+
|
5
7
|
before_action :set_resource_name
|
6
8
|
before_action :set_resource
|
7
9
|
before_action :hydrate_resource
|
@@ -302,11 +304,14 @@ module Avo
|
|
302
304
|
end
|
303
305
|
|
304
306
|
def set_filters
|
305
|
-
@filters = @resource
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
307
|
+
@filters = @resource
|
308
|
+
.get_filters
|
309
|
+
.map do |filter_class|
|
310
|
+
filter_class.new
|
311
|
+
end
|
312
|
+
.select do |filter|
|
313
|
+
filter.visible_in_view(resource: @resource, parent_model: @parent_model, parent_resource: @parent_resource)
|
314
|
+
end
|
310
315
|
end
|
311
316
|
|
312
317
|
def set_actions
|
@@ -316,12 +321,14 @@ module Avo
|
|
316
321
|
action.new(model: @model, resource: @resource, view: @view)
|
317
322
|
end
|
318
323
|
.select do |action|
|
319
|
-
action.visible_in_view
|
324
|
+
action.visible_in_view(parent_model: @parent_model, parent_resource: @parent_resource)
|
320
325
|
end
|
321
326
|
end
|
322
327
|
|
323
328
|
def set_applied_filters
|
324
|
-
|
329
|
+
reset_filters if params[:reset_filter]
|
330
|
+
|
331
|
+
@applied_filters = Avo::Filters::BaseFilter.decode_filters(fetch_filters)
|
325
332
|
|
326
333
|
# Some filters react to others and will have to be merged into this
|
327
334
|
@applied_filters = @applied_filters.merge reactive_filters
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require_dependency "avo/application_controller"
|
2
|
+
|
3
|
+
module Avo
|
4
|
+
module Dashboards
|
5
|
+
class CardsController < ApplicationController
|
6
|
+
before_action :set_dashboard
|
7
|
+
before_action :set_card
|
8
|
+
before_action :detect_chartkick
|
9
|
+
|
10
|
+
def show
|
11
|
+
render(:chartkick_missing) unless @chartkick_installed
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def set_dashboard
|
17
|
+
@dashboard = Avo::App.get_dashboard_by_id params[:dashboard_id]
|
18
|
+
|
19
|
+
raise ActionController::RoutingError.new("Not Found") if @dashboard.nil? || @dashboard.is_hidden?
|
20
|
+
end
|
21
|
+
|
22
|
+
def set_card
|
23
|
+
@card = @dashboard.item_at_index(params[:index].to_i).tap do |card|
|
24
|
+
card.hydrate(dashboard: @dashboard, params: params)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def detect_chartkick
|
29
|
+
@chartkick_installed = if @card.class.ancestors.map(&:to_s).include?("Avo::Dashboards::ChartkickCard")
|
30
|
+
defined?(Chartkick)
|
31
|
+
else
|
32
|
+
true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -102,7 +102,11 @@ module Avo
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def root_path_without_url
|
105
|
-
Avo::App.root_path
|
105
|
+
Avo::App.root_path
|
106
|
+
.to_s
|
107
|
+
.delete_prefix(request.base_url.to_s)
|
108
|
+
.delete_suffix("/")
|
109
|
+
.gsub("/?", "?")
|
106
110
|
rescue
|
107
111
|
Avo.configuration.root_path
|
108
112
|
end
|
@@ -76,7 +76,7 @@ export default class extends Controller {
|
|
76
76
|
// This line fixes a bug where the search box would be duplicated on back navigation.
|
77
77
|
this.autocompleteTarget.innerHTML = ''
|
78
78
|
|
79
|
-
autocomplete({
|
79
|
+
const { destroy } = autocomplete({
|
80
80
|
container: this.autocompleteTarget,
|
81
81
|
placeholder: this.translationKeys.placeholder,
|
82
82
|
translations: {
|
@@ -101,7 +101,7 @@ export default class extends Controller {
|
|
101
101
|
})
|
102
102
|
|
103
103
|
// document.addEventListener('turbo:before-render', destroy)
|
104
|
-
|
104
|
+
this.destroyMethod = destroy
|
105
105
|
|
106
106
|
// When using search for belongs-to
|
107
107
|
if (this.buttonTarget.dataset.shouldBeDisabled !== 'true') {
|
@@ -109,6 +109,15 @@ export default class extends Controller {
|
|
109
109
|
}
|
110
110
|
}
|
111
111
|
|
112
|
+
disconnect() {
|
113
|
+
// Don't leave open autocompletes around when disconnected. Otherwise it will still
|
114
|
+
// be visible when navigating back to this page.
|
115
|
+
if (this.destroyMethod) {
|
116
|
+
this.destroyMethod()
|
117
|
+
this.destroyMethod = null
|
118
|
+
}
|
119
|
+
}
|
120
|
+
|
112
121
|
addSource(resourceName, data) {
|
113
122
|
const that = this
|
114
123
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/avo.gemspec
CHANGED
@@ -35,7 +35,7 @@ Gem::Specification.new do |spec|
|
|
35
35
|
spec.add_dependency "activerecord", ">= 6.0"
|
36
36
|
spec.add_dependency "actionview", ">= 6.0"
|
37
37
|
spec.add_dependency "pagy"
|
38
|
-
spec.add_dependency "zeitwerk"
|
38
|
+
spec.add_dependency "zeitwerk", ">= 2.6.2"
|
39
39
|
spec.add_dependency "httparty"
|
40
40
|
spec.add_dependency "active_link_to"
|
41
41
|
spec.add_dependency "view_component"
|
data/bin/init
CHANGED
@@ -9,7 +9,17 @@ app_root do
|
|
9
9
|
)
|
10
10
|
|
11
11
|
header 'Configuring git'
|
12
|
-
|
12
|
+
target_upstream = "https://github.com/avo-hq/avo.git"
|
13
|
+
current_upstream = `git config --get remote.upstream.url`.chomp
|
14
|
+
if current_upstream.nil? || current_upstream.empty?
|
15
|
+
puts "Adding new remote 'upstream' to #{target_upstream}"
|
16
|
+
run! "git remote add upstream #{target_upstream}"
|
17
|
+
elsif current_upstream != target_upstream
|
18
|
+
puts "Updating existing remote 'upstream' to #{target_upstream}"
|
19
|
+
run! "git remote set-url upstream #{target_upstream}"
|
20
|
+
else
|
21
|
+
puts "Remote 'upstream' already points to #{target_upstream}, no change"
|
22
|
+
end
|
13
23
|
|
14
24
|
header 'Installing gems'
|
15
25
|
run! 'bundle install'
|
data/bin/test
CHANGED
data/config/routes.rb
CHANGED
@@ -7,7 +7,7 @@ Avo::Engine.routes.draw do
|
|
7
7
|
post "/rails/active_storage/direct_uploads", to: "/active_storage/direct_uploads#create"
|
8
8
|
|
9
9
|
resources :dashboards do
|
10
|
-
resources :cards
|
10
|
+
resources :cards, controller: "dashboards/cards"
|
11
11
|
end
|
12
12
|
|
13
13
|
scope "avo_api", as: "avo_api" do
|
@@ -33,7 +33,7 @@ Avo::Engine.routes.draw do
|
|
33
33
|
|
34
34
|
# Generate resource routes as below:
|
35
35
|
# resources :posts
|
36
|
-
Avo::DynamicRouter.routes
|
36
|
+
Avo::DynamicRouter.routes
|
37
37
|
|
38
38
|
# Associations
|
39
39
|
get "/:resource_name/:id/:related_name/new", to: "associations#new", as: "associations_new"
|
data/db/factories.rb
CHANGED
@@ -60,6 +60,16 @@ FactoryBot.define do
|
|
60
60
|
type { "Spouse" }
|
61
61
|
end
|
62
62
|
|
63
|
+
factory :sibling do
|
64
|
+
name { "#{Faker::Name.first_name} #{Faker::Name.last_name}" }
|
65
|
+
type { "Sibling" }
|
66
|
+
end
|
67
|
+
|
68
|
+
factory :brother do
|
69
|
+
name { "#{Faker::Name.first_name} #{Faker::Name.last_name}" }
|
70
|
+
type { "Brother" }
|
71
|
+
end
|
72
|
+
|
63
73
|
factory :fish do
|
64
74
|
name { %w[Tilapia Salmon Trout Catfish Pangasius Carp].sample }
|
65
75
|
end
|
data/lib/avo/app.rb
CHANGED
@@ -17,6 +17,14 @@ module Avo
|
|
17
17
|
class_attribute :error_messages
|
18
18
|
|
19
19
|
class << self
|
20
|
+
def eager_load(entity)
|
21
|
+
paths = Avo::ENTITIES.fetch entity
|
22
|
+
|
23
|
+
return unless paths.present?
|
24
|
+
|
25
|
+
Rails.autoloaders.main.eager_load_dir(Rails.root.join(*paths).to_s)
|
26
|
+
end
|
27
|
+
|
20
28
|
def boot
|
21
29
|
init_fields
|
22
30
|
|
@@ -91,7 +99,7 @@ module Avo
|
|
91
99
|
has_model = resource.model_class.present?
|
92
100
|
|
93
101
|
unless has_model
|
94
|
-
possible_model = resource.class.to_s.gsub
|
102
|
+
possible_model = resource.class.to_s.gsub "Resource", ""
|
95
103
|
|
96
104
|
Avo::App.error_messages.push({
|
97
105
|
url: "https://docs.avohq.io/2.0/resources.html#custom-model-class",
|
@@ -119,6 +127,8 @@ module Avo
|
|
119
127
|
end
|
120
128
|
|
121
129
|
def init_dashboards
|
130
|
+
eager_load :dashboards unless Rails.application.config.eager_load
|
131
|
+
|
122
132
|
self.dashboards = Dashboards::BaseDashboard.descendants
|
123
133
|
.select do |dashboard|
|
124
134
|
dashboard != Dashboards::BaseDashboard
|
data/lib/avo/base_action.rb
CHANGED
@@ -34,9 +34,9 @@ module Avo
|
|
34
34
|
def form_data_attributes
|
35
35
|
# We can't respond with a file download from Turbo se we disable it on the form
|
36
36
|
if may_download_file
|
37
|
-
{turbo: false, remote: false}
|
37
|
+
{turbo: false, remote: false, action_target: :form}
|
38
38
|
else
|
39
|
-
{
|
39
|
+
{turbo_frame: :_top, action_target: :form}
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -114,15 +114,25 @@ module Avo
|
|
114
114
|
self
|
115
115
|
end
|
116
116
|
|
117
|
-
def visible_in_view
|
118
|
-
|
119
|
-
|
117
|
+
def visible_in_view(parent_model: nil, parent_resource: nil)
|
118
|
+
if visible.blank?
|
119
|
+
# Hide on the :new view by default
|
120
|
+
return false if view == :new
|
120
121
|
|
121
|
-
|
122
|
-
|
122
|
+
# Show on all other views
|
123
|
+
return true
|
124
|
+
end
|
123
125
|
|
124
|
-
#
|
125
|
-
|
126
|
+
# Run the visible block if available
|
127
|
+
Avo::Hosts::VisibilityHost.new(
|
128
|
+
block: visible,
|
129
|
+
model: self.class.model,
|
130
|
+
params: params,
|
131
|
+
parent_model: parent_model,
|
132
|
+
parent_resource: parent_resource,
|
133
|
+
resource: self.class.resource,
|
134
|
+
view: self.class.view,
|
135
|
+
).handle
|
126
136
|
end
|
127
137
|
|
128
138
|
def param_id
|
data/lib/avo/base_resource.rb
CHANGED
@@ -49,6 +49,7 @@ module Avo
|
|
49
49
|
class_attribute :record_selector, default: true
|
50
50
|
class_attribute :keep_filters_panel_open, default: false
|
51
51
|
class_attribute :extra_params
|
52
|
+
class_attribute :link_to_child_resource, default: false
|
52
53
|
|
53
54
|
class << self
|
54
55
|
delegate :t, to: ::I18n
|
@@ -422,9 +423,7 @@ module Avo
|
|
422
423
|
end
|
423
424
|
|
424
425
|
def label
|
425
|
-
label_field
|
426
|
-
rescue
|
427
|
-
model_title
|
426
|
+
label_field&.value || model_title
|
428
427
|
end
|
429
428
|
|
430
429
|
def avatar_field
|
@@ -460,9 +459,7 @@ module Avo
|
|
460
459
|
end
|
461
460
|
|
462
461
|
def description
|
463
|
-
description_field
|
464
|
-
rescue
|
465
|
-
nil
|
462
|
+
description_field&.value
|
466
463
|
end
|
467
464
|
|
468
465
|
def form_scope
|
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
module Avo
|
3
|
+
module Concerns
|
4
|
+
module FiltersSessionHandler
|
5
|
+
def reset_filters
|
6
|
+
return unless cache_resource_filters?
|
7
|
+
|
8
|
+
session.delete(filters_session_key)
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch_filters
|
12
|
+
return filters_from_params unless cache_resource_filters?
|
13
|
+
|
14
|
+
(filters_from_params && save_filters_to_session) || filters_from_session
|
15
|
+
end
|
16
|
+
|
17
|
+
def filters_from_params
|
18
|
+
params[Avo::Filters::BaseFilter::PARAM_KEY].presence
|
19
|
+
end
|
20
|
+
|
21
|
+
def save_filters_to_session
|
22
|
+
session[filters_session_key] = params[Avo::Filters::BaseFilter::PARAM_KEY]
|
23
|
+
end
|
24
|
+
|
25
|
+
def filters_from_session
|
26
|
+
session[filters_session_key]
|
27
|
+
end
|
28
|
+
|
29
|
+
def filters_session_key
|
30
|
+
@filters_session_key ||= '/filters/' << %w[
|
31
|
+
turbo_frame controller resource_name related_name
|
32
|
+
action id
|
33
|
+
].map { |key| params[key] }.compact.join('/')
|
34
|
+
end
|
35
|
+
|
36
|
+
def cache_resource_filters?
|
37
|
+
return Avo.configuration.cache_resource_filters unless Avo.configuration.cache_resource_filters.is_a?(Proc)
|
38
|
+
|
39
|
+
Avo.configuration.cache_resource_filters.call(current_user: current_user, resource: @resource)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,44 @@
|
|
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
|
+
if items_holder.present?
|
8
|
+
items_holder.items
|
9
|
+
else
|
10
|
+
[]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def visible_items
|
15
|
+
items
|
16
|
+
.map do |item|
|
17
|
+
visible(item) ? item : nil
|
18
|
+
end
|
19
|
+
.compact
|
20
|
+
end
|
21
|
+
|
22
|
+
def visible(item)
|
23
|
+
if item.is_field?
|
24
|
+
item.visible? && item.visible_on?(view)
|
25
|
+
else
|
26
|
+
item.visible?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def visible?
|
31
|
+
any_item_visible = visible_items.any?
|
32
|
+
return any_item_visible unless respond_to?(:visible_on?)
|
33
|
+
|
34
|
+
visible_on?(view) && any_item_visible
|
35
|
+
end
|
36
|
+
|
37
|
+
def hydrate(view: nil)
|
38
|
+
@view = view
|
39
|
+
|
40
|
+
self
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
class Avo::Configuration::Branding
|
2
|
-
def initialize(colors: nil, chart_colors: nil, logo: nil, logomark: nil, placeholder: nil)
|
2
|
+
def initialize(colors: nil, chart_colors: nil, logo: nil, logomark: nil, placeholder: nil, favicon: nil)
|
3
3
|
@colors = colors || {}
|
4
4
|
@chart_colors = chart_colors
|
5
5
|
@logo = logo
|
6
6
|
@logomark = logomark
|
7
7
|
@placeholder = placeholder
|
8
|
+
@favicon = favicon
|
8
9
|
|
9
10
|
@default_colors = {
|
10
11
|
background: "#F6F6F7",
|
@@ -16,7 +17,8 @@ class Avo::Configuration::Branding
|
|
16
17
|
@default_chart_colors = ["#0B8AE2", "#34C683", "#2AB1EE", "#34C6A8"]
|
17
18
|
@default_logo = "/avo-assets/logo.png"
|
18
19
|
@default_logomark = "/avo-assets/logomark.png"
|
19
|
-
@default_placeholder = "placeholder.svg"
|
20
|
+
@default_placeholder = "/avo-assets/placeholder.svg"
|
21
|
+
@default_favicon = "/avo-assets/favicon.ico"
|
20
22
|
end
|
21
23
|
|
22
24
|
def css_colors
|
@@ -53,6 +55,12 @@ class Avo::Configuration::Branding
|
|
53
55
|
@chart_colors || @default_chart_colors
|
54
56
|
end
|
55
57
|
|
58
|
+
def favicon
|
59
|
+
return @default_favicon if Avo::App.license.lacks_with_trial(:branding)
|
60
|
+
|
61
|
+
@favicon || @default_favicon
|
62
|
+
end
|
63
|
+
|
56
64
|
private
|
57
65
|
|
58
66
|
def colors
|
data/lib/avo/configuration.rb
CHANGED
@@ -20,6 +20,7 @@ module Avo
|
|
20
20
|
attr_accessor :full_width_container
|
21
21
|
attr_accessor :full_width_index_view
|
22
22
|
attr_accessor :cache_resources_on_index_view
|
23
|
+
attr_accessor :cache_resource_filters
|
23
24
|
attr_accessor :context
|
24
25
|
attr_accessor :display_breadcrumbs
|
25
26
|
attr_accessor :hide_layout_when_printing
|
@@ -39,6 +40,7 @@ module Avo
|
|
39
40
|
attr_accessor :resource_default_view
|
40
41
|
attr_accessor :authorization_client
|
41
42
|
attr_accessor :field_wrapper_layout
|
43
|
+
attr_accessor :sign_out_path_name
|
42
44
|
attr_writer :branding
|
43
45
|
|
44
46
|
def initialize
|
@@ -68,6 +70,7 @@ module Avo
|
|
68
70
|
@full_width_container = false
|
69
71
|
@full_width_index_view = false
|
70
72
|
@cache_resources_on_index_view = Avo::PACKED
|
73
|
+
@cache_resource_filters = false
|
71
74
|
@context = proc {}
|
72
75
|
@initial_breadcrumbs = proc {
|
73
76
|
add_breadcrumb I18n.t("avo.home").humanize, avo.root_path
|
data/lib/avo/dynamic_router.rb
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
module Avo
|
2
|
-
|
3
|
-
def self.routes
|
4
|
-
|
2
|
+
class DynamicRouter
|
3
|
+
def self.routes
|
4
|
+
Avo::Engine.routes.draw do
|
5
|
+
scope "resources", as: "resources" do
|
6
|
+
Avo::App.eager_load(:resources) unless Rails.application.config.eager_load
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
.map do |resource|
|
17
|
-
router.resources resource.new.route_key
|
8
|
+
BaseResource.descendants
|
9
|
+
.select do |resource|
|
10
|
+
resource != :BaseResource
|
11
|
+
end
|
12
|
+
.select do |resource|
|
13
|
+
resource.is_a? Class
|
14
|
+
end
|
15
|
+
.map do |resource|
|
16
|
+
resources resource.new.route_key
|
17
|
+
end
|
18
18
|
end
|
19
|
+
end
|
19
20
|
end
|
20
21
|
end
|
21
22
|
end
|
data/lib/avo/engine.rb
CHANGED
@@ -27,15 +27,7 @@ module Avo
|
|
27
27
|
end
|
28
28
|
|
29
29
|
initializer "avo.autoload" do |app|
|
30
|
-
|
31
|
-
["app", "avo", "fields"],
|
32
|
-
["app", "avo", "filters"],
|
33
|
-
["app", "avo", "actions"],
|
34
|
-
["app", "avo", "resources"],
|
35
|
-
["app", "avo", "dashboards"],
|
36
|
-
["app", "avo", "cards"],
|
37
|
-
["app", "avo", "resource_tools"]
|
38
|
-
].each do |path_params|
|
30
|
+
Avo::ENTITIES.values.each do |path_params|
|
39
31
|
path = Rails.root.join(*path_params)
|
40
32
|
|
41
33
|
if File.directory? path.to_s
|
@@ -72,6 +64,11 @@ module Avo
|
|
72
64
|
g.test_framework :rspec, view_specs: false
|
73
65
|
end
|
74
66
|
|
67
|
+
generators do |app|
|
68
|
+
Rails::Generators.configure! app.config.generators
|
69
|
+
require_relative "../generators/model_generator"
|
70
|
+
end
|
71
|
+
|
75
72
|
# After deploy we want to make sure the license response is being cleared.
|
76
73
|
# We need a fresh license response.
|
77
74
|
# This is disabled in development because the initialization process might be triggered more than once.
|
@@ -14,6 +14,7 @@ module Avo
|
|
14
14
|
include Avo::Concerns::HasHTMLAttributes
|
15
15
|
include Avo::Fields::Concerns::IsRequired
|
16
16
|
include Avo::Fields::Concerns::IsReadonly
|
17
|
+
include Avo::Fields::Concerns::HasDefault
|
17
18
|
|
18
19
|
delegate :view_context, to: ::Avo::App
|
19
20
|
delegate :simple_format, :content_tag, to: :view_context
|
@@ -83,7 +84,7 @@ module Avo
|
|
83
84
|
|
84
85
|
@args = args
|
85
86
|
|
86
|
-
@updatable =
|
87
|
+
@updatable = !readonly
|
87
88
|
@computable = true
|
88
89
|
@computed = block.present?
|
89
90
|
@computed_value = nil
|
@@ -145,9 +146,11 @@ module Avo
|
|
145
146
|
end
|
146
147
|
|
147
148
|
def placeholder
|
148
|
-
|
149
|
+
if @placeholder.respond_to?(:call)
|
150
|
+
return Avo::Hosts::ResourceViewRecordHost.new(block: @placeholder, record: @model, resource: @resource, view: @view).handle
|
151
|
+
end
|
149
152
|
|
150
|
-
name
|
153
|
+
@placeholder || name
|
151
154
|
end
|
152
155
|
|
153
156
|
def visible?
|
@@ -166,15 +169,9 @@ module Avo
|
|
166
169
|
# Get model value
|
167
170
|
final_value = @model.send(property) if is_model?(@model) && @model.respond_to?(property)
|
168
171
|
|
169
|
-
# On new views and actions modals we need to prefill the fields
|
170
|
-
if
|
171
|
-
|
172
|
-
final_value = if default.respond_to?(:call)
|
173
|
-
default.call
|
174
|
-
else
|
175
|
-
default
|
176
|
-
end
|
177
|
-
end
|
172
|
+
# On new views and actions modals we need to prefill the fields with the default value
|
173
|
+
if should_fill_with_default_value? && default.present?
|
174
|
+
final_value = computed_default_value
|
178
175
|
end
|
179
176
|
|
180
177
|
# Run computable callback block if present
|
@@ -269,6 +266,18 @@ module Avo
|
|
269
266
|
def is_model?(model)
|
270
267
|
model_or_class(model) == "model"
|
271
268
|
end
|
269
|
+
|
270
|
+
def should_fill_with_default_value?
|
271
|
+
on_create? || in_action?
|
272
|
+
end
|
273
|
+
|
274
|
+
def on_create?
|
275
|
+
@view.in?([:new, :create])
|
276
|
+
end
|
277
|
+
|
278
|
+
def in_action?
|
279
|
+
@action.present?
|
280
|
+
end
|
272
281
|
end
|
273
282
|
end
|
274
283
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Avo
|
2
|
+
module Fields
|
3
|
+
module Concerns
|
4
|
+
module HasDefault
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
def computed_default_value
|
8
|
+
if default.respond_to? :call
|
9
|
+
Avo::Hosts::ResourceViewRecordHost.new(block: default, record: model, view: view, resource: resource).handle
|
10
|
+
else
|
11
|
+
default
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -6,7 +6,7 @@ module Avo
|
|
6
6
|
|
7
7
|
def is_readonly?
|
8
8
|
if readonly.respond_to? :call
|
9
|
-
Avo::Hosts::
|
9
|
+
Avo::Hosts::ResourceViewRecordHost.new(block: readonly, record: model, view: view, resource: resource).handle
|
10
10
|
else
|
11
11
|
readonly
|
12
12
|
end
|