avo 3.0.0.pre12 → 3.0.0.pre15
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 +1 -1
- data/Gemfile.lock +2 -1
- data/app/assets/stylesheets/avo.base.css +1 -1
- data/app/components/avo/actions_component.html.erb +1 -1
- data/app/components/avo/actions_component.rb +40 -16
- data/app/components/avo/alert_component.html.erb +1 -1
- data/app/components/avo/base_component.rb +7 -7
- data/app/components/avo/field_wrapper_component.html.erb +2 -2
- data/app/components/avo/field_wrapper_component.rb +1 -1
- data/app/components/avo/fields/area_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/belongs_to_field/edit_component.html.erb +5 -5
- data/app/components/avo/fields/belongs_to_field/edit_component.rb +4 -4
- data/app/components/avo/fields/boolean_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/boolean_group_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/code_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/common/heading_component.html.erb +1 -1
- data/app/components/avo/fields/country_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/file_field/index_component.rb +2 -2
- data/app/components/avo/fields/has_one_field/show_component.html.erb +1 -0
- data/app/components/avo/fields/index_component.rb +1 -0
- data/app/components/avo/fields/location_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/markdown_field/edit_component.html.erb +4 -3
- data/app/components/avo/fields/markdown_field/show_component.html.erb +3 -3
- data/app/components/avo/fields/number_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/password_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/progress_bar_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/status_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/text_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/textarea_field/edit_component.html.erb +1 -0
- data/app/components/avo/fields/trix_field/edit_component.html.erb +2 -1
- data/app/components/avo/fields/trix_field/show_component.html.erb +1 -1
- data/app/components/avo/index/field_wrapper_component.html.erb +1 -1
- data/app/components/avo/index/grid_item_component.html.erb +9 -35
- data/app/components/avo/index/grid_item_component.rb +36 -10
- data/app/components/avo/index/resource_controls_component.rb +6 -6
- data/app/components/avo/index/resource_table_component.rb +1 -1
- data/app/components/avo/item_switcher_component.html.erb +9 -4
- data/app/components/avo/item_switcher_component.rb +2 -1
- data/app/components/avo/panel_component.html.erb +1 -1
- data/app/components/avo/profile_item_component.html.erb +17 -2
- data/app/components/avo/profile_item_component.rb +13 -1
- data/app/components/avo/resource_component.rb +6 -3
- data/app/components/avo/resource_sidebar_component.rb +1 -1
- data/app/components/avo/row_component.html.erb +3 -0
- data/app/components/avo/row_component.rb +12 -0
- data/app/components/avo/sidebar/link_component.html.erb +2 -0
- data/app/components/avo/sidebar/link_component.rb +5 -3
- data/app/components/avo/sidebar_component.html.erb +3 -3
- data/app/components/avo/sidebar_component.rb +4 -4
- data/app/components/avo/sidebar_profile_component.html.erb +27 -27
- data/app/components/avo/views/resource_edit_component.rb +1 -1
- data/app/components/avo/views/resource_index_component.html.erb +1 -1
- data/app/components/avo/views/resource_index_component.rb +8 -8
- data/app/controllers/avo/actions_controller.rb +16 -8
- data/app/controllers/avo/application_controller.rb +71 -66
- data/app/controllers/avo/associations_controller.rb +4 -6
- data/app/controllers/avo/attachments_controller.rb +1 -1
- data/app/controllers/avo/base_controller.rb +39 -27
- data/app/controllers/avo/home_controller.rb +1 -1
- data/app/controllers/avo/search_controller.rb +18 -20
- data/app/controllers/concerns/avo/initializes_avo.rb +3 -6
- data/app/javascript/js/controllers/fields/{simple_mde_controller.js → easy_mde_controller.js} +4 -3
- data/app/javascript/js/controllers/search_controller.js +3 -1
- data/app/javascript/js/controllers.js +2 -2
- data/app/views/avo/actions/show.html.erb +2 -1
- data/app/views/avo/associations/new.html.erb +1 -1
- data/app/views/avo/debug/status.html.erb +1 -1
- data/app/views/avo/partials/_custom_tools_alert.html.erb +2 -2
- data/app/views/avo/partials/_footer.html.erb +1 -1
- data/app/views/avo/partials/_javascript.html.erb +1 -1
- data/app/views/avo/partials/_navbar.html.erb +1 -1
- data/app/views/avo/partials/_profile_menu_extra.html.erb +2 -0
- data/app/views/layouts/avo/application.html.erb +2 -2
- data/avo.gemspec +1 -0
- data/config/initializers/pagy.rb +12 -10
- data/config/routes.rb +3 -3
- data/db/factories.rb +2 -1
- data/lib/avo/base_action.rb +12 -3
- data/lib/avo/base_resource.rb +183 -181
- data/lib/avo/concerns/filters_session_handler.rb +0 -1
- data/lib/avo/concerns/has_item_type.rb +4 -0
- data/lib/avo/concerns/has_items.rb +28 -23
- data/lib/avo/concerns/model_class_constantized.rb +0 -2
- data/lib/avo/configuration.rb +6 -2
- data/lib/avo/current.rb +29 -2
- data/lib/avo/dsl/field_parser.rb +1 -1
- data/lib/avo/dynamic_router.rb +12 -1
- data/lib/avo/engine.rb +8 -6
- data/lib/avo/execution_context.rb +1 -1
- data/lib/avo/fields/base_field.rb +25 -7
- data/lib/avo/fields/belongs_to_field.rb +20 -13
- data/lib/avo/fields/concerns/is_searchable.rb +1 -1
- data/lib/avo/fields/concerns/use_resource.rb +1 -1
- data/lib/avo/fields/field_manager.rb +13 -3
- data/lib/avo/fields/has_base_field.rb +5 -5
- data/lib/avo/fields/has_one_field.rb +1 -1
- data/lib/avo/fields/location_field.rb +18 -1
- data/lib/avo/filters/base_filter.rb +3 -1
- data/lib/avo/html/builder.rb +3 -1
- data/lib/avo/licensing/h_q.rb +11 -6
- data/lib/avo/licensing/license.rb +1 -1
- data/lib/avo/licensing/license_manager.rb +1 -1
- data/lib/avo/licensing/{null_license.rb → nil_license.rb} +1 -1
- data/lib/avo/loaders/fields_loader.rb +7 -1
- data/lib/avo/plugin_manager.rb +2 -4
- data/lib/avo/reloader.rb +1 -1
- data/lib/avo/resources/controls/actions_list.rb +2 -1
- data/lib/avo/resources/items/holder.rb +5 -1
- data/lib/avo/resources/items/item_group.rb +1 -0
- data/lib/avo/resources/items/row.rb +54 -0
- data/lib/avo/resources/resource_manager.rb +4 -7
- data/lib/avo/services/debug_service.rb +6 -6
- data/lib/avo/services/telemetry_service.rb +3 -3
- data/lib/avo/version.rb +1 -1
- data/lib/avo.rb +107 -25
- data/lib/generators/avo/action_generator.rb +8 -8
- data/lib/generators/avo/card_generator.rb +27 -0
- data/lib/generators/avo/eject_generator.rb +1 -0
- data/lib/generators/avo/filter_generator.rb +8 -8
- data/lib/generators/avo/install_generator.rb +0 -1
- data/lib/generators/avo/resource_generator.rb +4 -1
- data/lib/generators/avo/templates/action.tt +3 -3
- data/lib/generators/avo/templates/cards/chartkick_card.tt +1 -1
- data/lib/generators/avo/templates/cards/chartkick_card_sample.tt +1 -1
- data/lib/generators/avo/templates/cards/metric_card.tt +1 -1
- data/lib/generators/avo/templates/cards/metric_card_sample.tt +1 -1
- data/lib/generators/avo/templates/cards/partial_card.tt +1 -1
- data/lib/generators/avo/templates/cards/partial_card_sample.tt +1 -1
- data/lib/generators/avo/templates/dashboards/dashboard.tt +1 -1
- data/lib/generators/avo/templates/resource/resource.tt +3 -4
- data/lib/generators/avo/templates/scope.tt +1 -1
- data/lib/tasks/avo_tasks.rake +1 -1
- data/public/avo-assets/avo.base.css +295 -165
- data/public/avo-assets/avo.base.js +307 -278
- data/public/avo-assets/avo.base.js.map +3 -3
- metadata +23 -10
- data/lib/avo/app.rb +0 -170
- data/lib/avo/grid_collector.rb +0 -40
- data/lib/generators/avo/card/chartkick_generator.rb +0 -18
- data/lib/generators/avo/card/metric_generator.rb +0 -18
- data/lib/generators/avo/card/partial_generator.rb +0 -19
- data/lib/generators/avo/templates/standalone_action.tt +0 -15
data/lib/avo/licensing/h_q.rb
CHANGED
@@ -4,6 +4,7 @@ module Avo
|
|
4
4
|
attr_accessor :current_request
|
5
5
|
attr_accessor :cache_store
|
6
6
|
|
7
|
+
# ENDPOINT = "https://v3.avohq.io/api/v1/licenses/check".freeze unless const_defined?(:ENDPOINT)
|
7
8
|
ENDPOINT = "https://avohq.io/api/v1/licenses/check".freeze unless const_defined?(:ENDPOINT)
|
8
9
|
REQUEST_TIMEOUT = 5 unless const_defined?(:REQUEST_TIMEOUT) # seconds
|
9
10
|
CACHE_TIME = 3600 unless const_defined?(:CACHE_TIME) # seconds
|
@@ -16,7 +17,7 @@ module Avo
|
|
16
17
|
|
17
18
|
def initialize(current_request = nil)
|
18
19
|
@current_request = current_request
|
19
|
-
@cache_store = Avo
|
20
|
+
@cache_store = Avo.cache_store
|
20
21
|
end
|
21
22
|
|
22
23
|
def response
|
@@ -69,10 +70,10 @@ module Avo
|
|
69
70
|
app_name: app_name
|
70
71
|
}
|
71
72
|
|
72
|
-
metadata = Avo::Services::DebugService.avo_metadata
|
73
|
-
if metadata[:resources_count] != 0
|
74
|
-
|
75
|
-
end
|
73
|
+
# metadata = Avo::Services::DebugService.avo_metadata
|
74
|
+
# if metadata[:resources_count] != 0
|
75
|
+
# result[:avo_metadata] = "metadata"
|
76
|
+
# end
|
76
77
|
|
77
78
|
result
|
78
79
|
end
|
@@ -149,7 +150,11 @@ module Avo
|
|
149
150
|
def perform_request
|
150
151
|
Avo.logger.debug "Performing request to avohq.io API to check license availability." if Rails.env.development?
|
151
152
|
|
152
|
-
|
153
|
+
if Rails.env.test?
|
154
|
+
OpenStruct.new({code: 200, parsed_response: {id: "pro", valid: true}})
|
155
|
+
else
|
156
|
+
HTTParty.post ENDPOINT, body: payload.to_json, headers: {"Content-type": "application/json"}, timeout: REQUEST_TIMEOUT
|
157
|
+
end
|
153
158
|
end
|
154
159
|
|
155
160
|
def app_name
|
@@ -6,7 +6,7 @@ module Avo
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def method_missing(method, *args, &block)
|
9
|
-
matched_field = Avo
|
9
|
+
matched_field = Avo.field_manager.find do |field|
|
10
10
|
field[:name].to_s == method.to_s
|
11
11
|
end
|
12
12
|
|
@@ -22,6 +22,12 @@ module Avo
|
|
22
22
|
add_field field
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
def respond_to_missing?(method)
|
27
|
+
Avo.field_manager.find do |field|
|
28
|
+
field[:name].to_s == method.to_s
|
29
|
+
end
|
30
|
+
end
|
25
31
|
end
|
26
32
|
end
|
27
33
|
end
|
data/lib/avo/plugin_manager.rb
CHANGED
@@ -25,15 +25,13 @@ module Avo
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def register_field(method_name, klass)
|
28
|
-
Avo
|
28
|
+
Avo.field_manager.load_field method_name, klass
|
29
29
|
end
|
30
30
|
|
31
31
|
def register_resource_tool
|
32
|
-
# puts ["register_resource_tool->"].inspect
|
33
32
|
end
|
34
33
|
|
35
34
|
def register_tool
|
36
|
-
# puts ["register_tool->"].inspect
|
37
35
|
end
|
38
36
|
|
39
37
|
def as_json(*arg)
|
@@ -47,7 +45,7 @@ module Avo
|
|
47
45
|
|
48
46
|
def installed?(name)
|
49
47
|
plugins.any? do |plugin|
|
50
|
-
plugin.klass.to_s.
|
48
|
+
plugin.klass.to_s.chomp("::Plugin").underscore.tr("/", "-") == name.to_s
|
51
49
|
end
|
52
50
|
end
|
53
51
|
end
|
data/lib/avo/reloader.rb
CHANGED
@@ -46,7 +46,7 @@ class Avo::Reloader
|
|
46
46
|
if reload_lib?
|
47
47
|
dirs[Avo::Engine.root.join("lib", "avo").to_s] = ["rb"]
|
48
48
|
if Avo.avo_filters_installed?
|
49
|
-
dirs[
|
49
|
+
dirs[Avo::DynamicFilters::Engine.root.join("lib", "avo", "dynamic_filters").to_s] = ["rb"]
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -2,13 +2,14 @@ module Avo
|
|
2
2
|
module Resources
|
3
3
|
module Controls
|
4
4
|
class ActionsList < BaseControl
|
5
|
-
attr_reader :color, :exclude, :style
|
5
|
+
attr_reader :color, :exclude, :include, :style
|
6
6
|
|
7
7
|
def initialize(**args)
|
8
8
|
super(**args)
|
9
9
|
|
10
10
|
@color = args[:color] || :primary
|
11
11
|
@exclude = args[:exclude] || []
|
12
|
+
@include = args[:include] || []
|
12
13
|
@style = args[:style] || :outline
|
13
14
|
end
|
14
15
|
end
|
@@ -22,7 +22,7 @@ class Avo::Resources::Items::Holder
|
|
22
22
|
name: field_name,
|
23
23
|
as: as,
|
24
24
|
# resource: resource_class.name,
|
25
|
-
message: "There's an invalid field configuration for this resource. <br/> <code class='px-1 py-px rounded bg-red-600'>field :#{field_name}, as:
|
25
|
+
message: "There's an invalid field configuration for this resource. <br/> <code class='px-1 py-px rounded bg-red-600'>field :#{field_name}, as: :#{as}</code>"
|
26
26
|
})
|
27
27
|
end
|
28
28
|
|
@@ -41,6 +41,10 @@ class Avo::Resources::Items::Holder
|
|
41
41
|
add_item Avo::Resources::Items::Tab::Builder.parse_block(name: name, **args, &block)
|
42
42
|
end
|
43
43
|
|
44
|
+
def row(**args, &block)
|
45
|
+
add_item Avo::Resources::Items::Row::Builder.parse_block(**args, &block)
|
46
|
+
end
|
47
|
+
|
44
48
|
def tool(klass, **args)
|
45
49
|
instance = klass.new(**args)
|
46
50
|
add_item instance
|
@@ -0,0 +1,54 @@
|
|
1
|
+
class Avo::Resources::Items::Row
|
2
|
+
include Avo::Concerns::IsResourceItem
|
3
|
+
include Avo::Concerns::HasItems
|
4
|
+
include Avo::Concerns::HasItemType
|
5
|
+
include Avo::Concerns::IsVisible
|
6
|
+
|
7
|
+
class_attribute :item_type, default: :row
|
8
|
+
|
9
|
+
attr_reader :view
|
10
|
+
attr_accessor :items_holder
|
11
|
+
|
12
|
+
delegate :items, :add_item, to: :items_holder
|
13
|
+
|
14
|
+
def initialize(view: nil)
|
15
|
+
@view = view
|
16
|
+
@items_holder = Avo::Resources::Items::Holder.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def hydrate(view: nil, resource: nil, **args)
|
20
|
+
@view = view
|
21
|
+
@resource = resource
|
22
|
+
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def has_items?
|
27
|
+
@items.present?
|
28
|
+
end
|
29
|
+
|
30
|
+
class Builder
|
31
|
+
class << self
|
32
|
+
def parse_block(**args, &block)
|
33
|
+
Docile.dsl_eval(new(**args), &block).build
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_reader :items_holder
|
38
|
+
|
39
|
+
delegate :field, to: :items_holder
|
40
|
+
delegate :tool, to: :items_holder
|
41
|
+
delegate :items, to: :items_holder
|
42
|
+
|
43
|
+
def initialize(**args)
|
44
|
+
@row = Avo::Resources::Items::Row.new(**args)
|
45
|
+
@items_holder = Avo::Resources::Items::Holder.new
|
46
|
+
end
|
47
|
+
|
48
|
+
# Fetch the tab
|
49
|
+
def build
|
50
|
+
@row.items_holder = @items_holder
|
51
|
+
@row
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -66,9 +66,6 @@ module Avo
|
|
66
66
|
# We need to de-duplicate them
|
67
67
|
klass.name
|
68
68
|
end
|
69
|
-
.map do |resource|
|
70
|
-
resource.new if resource.is_a? Class
|
71
|
-
end
|
72
69
|
end
|
73
70
|
|
74
71
|
def check_bad_resources
|
@@ -76,13 +73,13 @@ module Avo
|
|
76
73
|
has_model = resource.model_class.present?
|
77
74
|
|
78
75
|
unless has_model
|
79
|
-
possible_model = resource.
|
76
|
+
possible_model = resource.to_s.gsub "Avo::Resources::", ""
|
80
77
|
possible_model = possible_model.gsub "Resource", ""
|
81
78
|
|
82
|
-
Avo
|
79
|
+
Avo.error_manager.add({
|
83
80
|
url: "https://docs.avohq.io/2.0/resources.html#custom-model-class",
|
84
81
|
target: "_blank",
|
85
|
-
message: "#{resource
|
82
|
+
message: "#{resource} 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"
|
86
83
|
})
|
87
84
|
end
|
88
85
|
end
|
@@ -100,7 +97,7 @@ module Avo
|
|
100
97
|
resource = "Avo::Resources::#{resource}" unless resource.to_s.starts_with?("Avo::Resources::")
|
101
98
|
|
102
99
|
resources.find do |available_resource|
|
103
|
-
resource.to_s == available_resource.
|
100
|
+
resource.to_s == available_resource.to_s
|
104
101
|
end
|
105
102
|
end
|
106
103
|
|
@@ -12,7 +12,7 @@ class Avo::Services::DebugService
|
|
12
12
|
payload[:hq_payload] = hq&.payload
|
13
13
|
payload[:thread_count] = get_thread_count
|
14
14
|
payload[:license_abilities] = Avo::Current&.license&.abilities
|
15
|
-
payload[:cache_store] = Avo
|
15
|
+
payload[:cache_store] = Avo.cache_store&.class&.to_s
|
16
16
|
payload[:avo_metadata] = avo_metadata
|
17
17
|
payload[:app_timezone] = Time.current.zone
|
18
18
|
payload[:cache_key] = Avo::Licensing::HQ.cache_key
|
@@ -31,8 +31,8 @@ class Avo::Services::DebugService
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def avo_metadata
|
34
|
-
resources = Avo
|
35
|
-
dashboards = defined?(
|
34
|
+
resources = Avo.resource_manager.all
|
35
|
+
dashboards = defined?(Avo::Dashboards) ? Avo::Dashboards.dashboard_manager.all : []
|
36
36
|
field_definitions = resources.map(&:get_field_definitions)
|
37
37
|
fields_count = field_definitions.map(&:count).sum
|
38
38
|
fields_per_resource = sprintf("%0.01f", fields_count / (resources.count + 0.0))
|
@@ -55,11 +55,11 @@ class Avo::Services::DebugService
|
|
55
55
|
fields_per_resource: fields_per_resource,
|
56
56
|
custom_fields_count: custom_fields_count,
|
57
57
|
field_types: field_types,
|
58
|
-
**other_metadata(:actions),
|
58
|
+
# **other_metadata(:actions), # TODO: this is fetching actions without hydration
|
59
59
|
**other_metadata(:filters),
|
60
60
|
main_menu_present: Avo.configuration.main_menu.present?,
|
61
61
|
profile_menu_present: Avo.configuration.profile_menu.present?,
|
62
|
-
cache_store: Avo
|
62
|
+
cache_store: Avo.cache_store&.class&.to_s,
|
63
63
|
**config_metadata
|
64
64
|
}
|
65
65
|
# rescue => error
|
@@ -69,7 +69,7 @@ class Avo::Services::DebugService
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def other_metadata(type = :actions)
|
72
|
-
resources = Avo
|
72
|
+
resources = Avo.resource_manager.all
|
73
73
|
|
74
74
|
types = resources.map(&:"get_#{type}")
|
75
75
|
type_count = types.flatten.uniq.count
|
@@ -23,7 +23,7 @@ class Avo::Services::TelemetryService
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def avo_metadata
|
26
|
-
resources = Avo
|
26
|
+
resources = Avo.resource_manager.all
|
27
27
|
dashboards = Avo::Current.app.dashboard_manager.all
|
28
28
|
field_definitions = resources.map(&:get_field_definitions)
|
29
29
|
fields_count = field_definitions.map(&:count).sum
|
@@ -51,7 +51,7 @@ class Avo::Services::TelemetryService
|
|
51
51
|
**other_metadata(:filters),
|
52
52
|
main_menu_present: Avo.configuration.main_menu.present?,
|
53
53
|
profile_menu_present: Avo.configuration.profile_menu.present?,
|
54
|
-
cache_store: Avo
|
54
|
+
cache_store: Avo.cache_store&.class&.to_s,
|
55
55
|
**config_metadata
|
56
56
|
}
|
57
57
|
# rescue => error
|
@@ -61,7 +61,7 @@ class Avo::Services::TelemetryService
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def other_metadata(type = :actions)
|
64
|
-
resources = Avo
|
64
|
+
resources = Avo.resource_manager.all
|
65
65
|
|
66
66
|
types = resources.map(&:"get_#{type}")
|
67
67
|
type_count = types.flatten.uniq.count
|
data/lib/avo/version.rb
CHANGED
data/lib/avo.rb
CHANGED
@@ -11,31 +11,9 @@ loader.inflector.inflect(
|
|
11
11
|
loader.ignore("#{__dir__}/generators")
|
12
12
|
loader.setup
|
13
13
|
|
14
|
-
# .//*,,.....,,*/(*
|
15
|
-
# **,,..............,*#.
|
16
|
-
# ,*,,..... .....*/#.
|
17
|
-
# **,,.... ....,*/%%
|
18
|
-
# ,**,,....... . ....*/#&%
|
19
|
-
# **,,,...... . . ....*/#&&%
|
20
|
-
# **,,........ . . ...,//#&&&.
|
21
|
-
# */*,,..*//***,,,,*/(,.. .. .....*//%&%&*
|
22
|
-
# ,/**,..**/******,,***/(###,...........,//(%&&%.
|
23
|
-
# /**,,..((//*****////((##%%%%%*.........*//%%&&%
|
24
|
-
# ****,...#/**,,,*,*/(#%##%%%%&&&(*,.....,*/(%&&&/
|
25
|
-
# /**,....(/*,,,,,,,*(##%%%%%&&&&&(,.....,*(#&&&&.
|
26
|
-
# ,//*,.....(/*,,**//(##%%%%&&&&@&&%/,....,*((&&&&*
|
27
|
-
# .//*,,.....(((//(((##%%%&&&&&&&&@#/,....,*/#%&&&#
|
28
|
-
# (/**,,......###%%%%%&&&&&&&&&&@#/,,...,,*/#&&&&&
|
29
|
-
# (/**,,........%%%%%&&&&&&&&@%(*,...,,,*//(&&&&%.
|
30
|
-
# ///*,,,.........,*#&&&&#(/,,.....,,,*//(%&&&&%*
|
31
|
-
# (//**,,,.....................,,,,*//(%&&&&&&*
|
32
|
-
# *(///**,,,,............,,,,,,**/((&&&&&&&%.
|
33
|
-
# ((///*****,,,,,,,,,,,,***//((&&&&&%&%&#
|
34
|
-
# .((((////********///(((%&%&&&&%%%%%
|
35
|
-
# (############%%%%%%%%%%%%%%%*
|
36
|
-
# ,(############%%%%%#*
|
37
|
-
|
38
14
|
module Avo
|
15
|
+
extend ActiveSupport::LazyLoadHooks
|
16
|
+
|
39
17
|
ROOT_PATH = Pathname.new(File.join(__dir__, ".."))
|
40
18
|
IN_DEVELOPMENT = ENV["AVO_IN_DEVELOPMENT"] == "1"
|
41
19
|
PACKED = !IN_DEVELOPMENT
|
@@ -64,8 +42,112 @@ module Avo
|
|
64
42
|
class DeprecatedAPIError < StandardError; end
|
65
43
|
|
66
44
|
class << self
|
45
|
+
attr_reader :logger
|
46
|
+
attr_reader :cache_store
|
47
|
+
attr_reader :field_manager
|
48
|
+
|
49
|
+
delegate :license, :app, :error_manager, :tool_manager, :resource_manager, to: Avo::Current
|
50
|
+
|
51
|
+
def boot
|
52
|
+
boot_logger
|
53
|
+
boot_fields
|
54
|
+
@cache_store = get_cache_store
|
55
|
+
plugin_manager.boot_plugins
|
56
|
+
Avo.run_load_hooks(:boot, self)
|
57
|
+
end
|
58
|
+
|
59
|
+
def init
|
60
|
+
Avo::Current.error_manager = Avo::ErrorManager.build
|
61
|
+
Avo::Current.resource_manager = Avo::Resources::ResourceManager.build
|
62
|
+
Avo::Current.tool_manager = Avo::Tools::ToolManager.build
|
63
|
+
|
64
|
+
Avo.run_load_hooks(:init, self)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Renerate a dynamic root path using the URIService
|
68
|
+
def root_path(paths: [], query: {}, **args)
|
69
|
+
Avo::Services::URIService.parse(Avo::Current.view_context.avo.root_url.to_s)
|
70
|
+
.append_paths(paths)
|
71
|
+
.append_query(query)
|
72
|
+
.to_s
|
73
|
+
end
|
74
|
+
|
75
|
+
def mount_path
|
76
|
+
Avo::Engine.routes.find_script_name({})
|
77
|
+
end
|
78
|
+
|
79
|
+
def main_menu
|
80
|
+
return unless Avo.plugin_manager.installed?("avo-menu")
|
81
|
+
|
82
|
+
# Return empty menu if the app doesn't have the profile menu configured
|
83
|
+
return Avo::Menu::Builder.new.build unless has_main_menu?
|
84
|
+
|
85
|
+
Avo::Menu::Builder.parse_menu(&Avo.configuration.main_menu)
|
86
|
+
end
|
87
|
+
|
88
|
+
def profile_menu
|
89
|
+
return unless Avo.plugin_manager.installed?("avo-menu")
|
90
|
+
|
91
|
+
# Return empty menu if the app doesn't have the profile menu configured
|
92
|
+
return Avo::Menu::Builder.new.build unless has_profile_menu?
|
93
|
+
|
94
|
+
Avo::Menu::Builder.parse_menu(&Avo.configuration.profile_menu)
|
95
|
+
end
|
96
|
+
|
97
|
+
def app_status
|
98
|
+
license.valid?
|
99
|
+
end
|
100
|
+
|
67
101
|
def avo_filters_installed?
|
68
|
-
defined?(
|
102
|
+
defined?(Avo::DynamicFilters).present?
|
103
|
+
end
|
104
|
+
|
105
|
+
def has_main_menu?
|
106
|
+
return false if Avo.license.lacks_with_trial(:menu_editor)
|
107
|
+
return false if Avo.configuration.main_menu.nil?
|
108
|
+
|
109
|
+
true
|
110
|
+
end
|
111
|
+
|
112
|
+
def has_profile_menu?
|
113
|
+
return false if Avo.license.lacks_with_trial(:menu_editor)
|
114
|
+
return false if Avo.configuration.profile_menu.nil?
|
115
|
+
|
116
|
+
true
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def boot_logger
|
122
|
+
file_logger = ActiveSupport::Logger.new(Rails.root.join("log", "avo.log"))
|
123
|
+
|
124
|
+
file_logger.datetime_format = "%Y-%m-%d %H:%M:%S"
|
125
|
+
file_logger.formatter = proc do |severity, time, progname, msg|
|
126
|
+
"[Avo] #{time}: #{msg}\n".tap do |i|
|
127
|
+
puts i
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
@logger = file_logger
|
132
|
+
end
|
133
|
+
|
134
|
+
def boot_fields
|
135
|
+
@field_manager = Avo::Fields::FieldManager.build
|
136
|
+
end
|
137
|
+
|
138
|
+
def get_cache_store
|
139
|
+
if Rails.env.production?
|
140
|
+
case Rails.cache.class.to_s
|
141
|
+
when "ActiveSupport::Cache::MemCacheStore", "ActiveSupport::Cache::RedisCacheStore"
|
142
|
+
Rails.cache
|
143
|
+
else
|
144
|
+
ActiveSupport::Cache.lookup_store(:file_store, Rails.root.join("tmp", "cache"))
|
145
|
+
end
|
146
|
+
elsif Rails.env.test?
|
147
|
+
Rails.cache
|
148
|
+
else
|
149
|
+
ActiveSupport::Cache.lookup_store(:memory_store)
|
150
|
+
end
|
69
151
|
end
|
70
152
|
end
|
71
153
|
end
|
@@ -5,20 +5,20 @@ module Generators
|
|
5
5
|
class ActionGenerator < NamedBaseGenerator
|
6
6
|
source_root File.expand_path("templates", __dir__)
|
7
7
|
|
8
|
-
class_option :standalone, type: :boolean
|
8
|
+
class_option :standalone, type: :boolean, default: false
|
9
|
+
class_option :name, type: :string
|
9
10
|
|
10
11
|
namespace "avo:action"
|
11
12
|
|
12
13
|
def create_resource_file
|
13
|
-
|
14
|
+
template "action.tt", "app/avo/actions/#{singular_name}.rb"
|
15
|
+
end
|
14
16
|
|
15
|
-
|
17
|
+
def configuration_options
|
18
|
+
configuration = " self.name = \"#{options[:name] || name.titleize}\""
|
19
|
+
configuration += "\n self.standalone = true" if options[:standalone]
|
16
20
|
|
17
|
-
|
18
|
-
template "standalone_action.tt", "app/avo/actions/#{singular_name}.rb"
|
19
|
-
else
|
20
|
-
template "action.tt", "app/avo/actions/#{singular_name}.rb"
|
21
|
-
end
|
21
|
+
configuration
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative "named_base_generator"
|
2
|
+
|
3
|
+
module Generators
|
4
|
+
module Avo
|
5
|
+
class Card < NamedBaseGenerator
|
6
|
+
namespace "avo:card"
|
7
|
+
source_root File.expand_path("templates", __dir__)
|
8
|
+
class_option :type, type: :string
|
9
|
+
|
10
|
+
def handle
|
11
|
+
raise "Invalid card type '#{options[:type]}'" unless card_types.include? options[:type]
|
12
|
+
|
13
|
+
template "cards/#{options[:type]}_card_sample.tt", "app/avo/cards/#{name.underscore}.rb"
|
14
|
+
|
15
|
+
if options[:type].to_sym == :partial
|
16
|
+
template "cards/partial_card_partial.tt", "app/views/avo/cards/_#{name.underscore}.html.erb"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def card_types
|
23
|
+
%w[metric chartkick partial]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -17,6 +17,7 @@ module Generators
|
|
17
17
|
pre_head: "app/views/avo/partials/_pre_head.html.erb",
|
18
18
|
scripts: "app/views/avo/partials/_scripts.html.erb",
|
19
19
|
sidebar_extra: "app/views/avo/partials/_sidebar_extra.html.erb",
|
20
|
+
profile_menu_extra: "app/views/avo/partials/_profile_menu_extra.html.erb",
|
20
21
|
}
|
21
22
|
|
22
23
|
def handle
|
@@ -5,20 +5,20 @@ module Generators
|
|
5
5
|
class FilterGenerator < NamedBaseGenerator
|
6
6
|
source_root File.expand_path("templates", __dir__)
|
7
7
|
|
8
|
-
class_option :
|
9
|
-
class_option :select, type: :boolean
|
10
|
-
class_option :text, type: :boolean
|
8
|
+
class_option :type, type: :string, default: "boolean"
|
11
9
|
|
12
10
|
namespace "avo:filter"
|
13
11
|
|
14
12
|
def create_resource_file
|
15
|
-
type
|
13
|
+
raise "Invalid filter type '#{options[:type]}'" unless filter_types.include? options[:type]
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
template "filters/#{options[:type]}_filter.tt", "app/avo/filters/#{singular_name}.rb"
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
20
19
|
|
21
|
-
|
20
|
+
def filter_types
|
21
|
+
%w[boolean select text multiple_select]
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -135,6 +135,9 @@ module Generators
|
|
135
135
|
fields_string = ""
|
136
136
|
|
137
137
|
fields.each do |field_name, field_options|
|
138
|
+
# if field_options are not available (likely a missing resource for an association), skip the field
|
139
|
+
fields_string += "\n # Could not generate a field for #{field_name}" and next unless field_options
|
140
|
+
|
138
141
|
options = ""
|
139
142
|
field_options[:options].each { |k, v| options += ", #{k}: #{v}" } if field_options[:options].present?
|
140
143
|
|
@@ -181,7 +184,7 @@ module Generators
|
|
181
184
|
end
|
182
185
|
|
183
186
|
def field_from_through_association(association)
|
184
|
-
if association.through_reflection.is_a? ActiveRecord::Reflection::
|
187
|
+
if association.through_reflection.is_a?(ActiveRecord::Reflection::HasManyReflection) || association.through_reflection.is_a?(ActiveRecord::Reflection::ThroughReflection)
|
185
188
|
{
|
186
189
|
field: "has_many",
|
187
190
|
options: {
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class Avo::Actions::<%= class_name.camelize %> < Avo::BaseAction
|
2
|
-
|
2
|
+
<%= configuration_options %>
|
3
3
|
# self.visible = -> do
|
4
4
|
# true
|
5
5
|
# end
|
@@ -8,8 +8,8 @@ class Avo::Actions::<%= class_name.camelize %> < Avo::BaseAction
|
|
8
8
|
# # Add Action fields here
|
9
9
|
# end
|
10
10
|
|
11
|
-
def handle(records:, fields:, current_user:, resource
|
12
|
-
records.each do |
|
11
|
+
def handle(records:, fields:, current_user:, resource:, **args)
|
12
|
+
records.each do |record|
|
13
13
|
# Do something with your records.
|
14
14
|
end
|
15
15
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Avo::Cards::<%= class_name.camelize %> <
|
1
|
+
class Avo::Cards::<%= class_name.camelize %> < Avo::Dashboards::ChartkickCard
|
2
2
|
self.id = "<%= name.underscore %>"
|
3
3
|
self.label = "<%= name.underscore.humanize %>"
|
4
4
|
self.chart_type = :area_chart
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Avo::Cards::<%= class_name.camelize %> <
|
1
|
+
class Avo::Cards::<%= class_name.camelize %> < Avo::Dashboards::ChartkickCard
|
2
2
|
self.id = "<%= name.underscore %>"
|
3
3
|
self.label = "<%= name.underscore.humanize %>"
|
4
4
|
self.chart_type = :area_chart
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Avo::Cards::<%= class_name.camelize %> <
|
1
|
+
class Avo::Cards::<%= class_name.camelize %> < Avo::Dashboards::MetricCard
|
2
2
|
self.id = "<%= name.underscore %>"
|
3
3
|
self.label = "<%= name.underscore.humanize %>"
|
4
4
|
# self.description = "Some description"
|