avo 3.0.0.beta1 → 3.0.0.pre1
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 +5 -5
- data/Gemfile.lock +81 -92
- data/{public/avo-assets/avo.css → app/assets/builds/avo.base.css} +686 -728
- data/app/assets/builds/avo.base.js +93804 -0
- data/app/assets/builds/avo.base.js.map +7 -0
- data/app/assets/stylesheets/avo.base.css +2 -1
- data/app/assets/svgs/failed_to_load.svg +1 -0
- data/app/assets/svgs/grid-empty-state.svg +1 -0
- data/app/assets/svgs/table-empty-state.svg +1 -0
- data/app/assets/svgs/triangle-up.svg +1 -1
- data/app/components/avo/actions_component.html.erb +1 -1
- data/app/components/avo/actions_component.rb +16 -42
- 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 +4 -4
- data/app/components/avo/field_wrapper_component.rb +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 -8
- data/app/components/avo/fields/boolean_field/edit_component.html.erb +0 -1
- 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 +0 -1
- data/app/components/avo/fields/common/files_list_viewer_component.html.erb +5 -0
- data/app/components/avo/fields/common/files_list_viewer_component.rb +8 -0
- data/app/components/avo/fields/common/heading_component.html.erb +1 -1
- data/app/components/avo/fields/common/single_file_viewer_component.html.erb +56 -0
- data/app/components/avo/fields/common/single_file_viewer_component.rb +55 -0
- data/app/components/avo/fields/country_field/edit_component.html.erb +1 -3
- data/app/components/avo/fields/file_field/edit_component.html.erb +2 -4
- data/app/components/avo/fields/file_field/edit_component.rb +0 -1
- data/app/components/avo/fields/file_field/index_component.rb +2 -2
- data/app/components/avo/fields/file_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/files_field/edit_component.html.erb +2 -4
- data/app/components/avo/fields/files_field/edit_component.rb +0 -1
- data/app/components/avo/fields/files_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/has_many_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/has_one_field/show_component.html.erb +4 -5
- data/app/components/avo/fields/has_one_field/show_component.rb +2 -6
- data/app/components/avo/fields/index_component.rb +0 -1
- data/app/components/avo/fields/markdown_field/edit_component.html.erb +3 -4
- 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 -3
- data/app/components/avo/fields/password_field/edit_component.html.erb +1 -3
- data/app/components/avo/fields/progress_bar_field/edit_component.html.erb +0 -1
- data/app/components/avo/fields/select_field/edit_component.html.erb +1 -2
- data/app/components/avo/fields/status_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/text_field/edit_component.html.erb +2 -3
- data/app/components/avo/fields/textarea_field/edit_component.html.erb +0 -1
- data/app/components/avo/fields/trix_field/edit_component.html.erb +1 -2
- 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/field_wrapper_component.rb +12 -0
- data/app/components/avo/index/grid_item_component.html.erb +35 -9
- data/app/components/avo/index/grid_item_component.rb +10 -36
- data/app/components/avo/index/resource_controls_component.rb +11 -8
- data/app/components/avo/index/resource_table_component.rb +1 -1
- data/app/components/avo/item_switcher_component.html.erb +5 -10
- data/app/components/avo/item_switcher_component.rb +1 -2
- data/app/components/avo/modal_component.html.erb +1 -1
- data/app/components/avo/panel_component.html.erb +1 -6
- data/app/components/avo/panel_component.rb +0 -1
- data/app/components/avo/profile_item_component.html.erb +2 -17
- data/app/components/avo/profile_item_component.rb +1 -13
- data/app/components/avo/referrer_params_component.html.erb +0 -2
- data/app/components/avo/resource_component.rb +6 -69
- data/app/components/avo/resource_sidebar_component.rb +1 -1
- data/app/components/avo/sidebar/link_component.html.erb +0 -2
- data/app/components/avo/sidebar/link_component.rb +3 -5
- 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.html.erb +5 -5
- data/app/components/avo/views/resource_edit_component.rb +1 -1
- data/app/components/avo/views/resource_index_component.html.erb +10 -19
- data/app/components/avo/views/resource_index_component.rb +16 -22
- data/app/components/avo/views/resource_show_component.html.erb +4 -4
- data/app/controllers/avo/actions_controller.rb +20 -20
- data/app/controllers/avo/application_controller.rb +67 -90
- data/app/controllers/avo/associations_controller.rb +7 -5
- data/app/controllers/avo/attachments_controller.rb +7 -22
- data/app/controllers/avo/base_controller.rb +35 -47
- data/app/controllers/avo/home_controller.rb +1 -1
- data/app/controllers/avo/search_controller.rb +16 -20
- data/app/controllers/concerns/avo/initializes_avo.rb +8 -3
- data/app/helpers/avo/application_helper.rb +6 -13
- data/app/javascript/js/application.js +0 -2
- data/app/javascript/js/controllers/fields/{easy_mde_controller.js → simple_mde_controller.js} +3 -4
- data/app/javascript/js/controllers/search_controller.js +1 -3
- data/app/javascript/js/controllers.js +2 -2
- data/app/views/avo/actions/show.html.erb +3 -5
- data/app/views/avo/associations/new.html.erb +3 -3
- data/app/views/avo/debug/status.html.erb +5 -6
- data/app/views/avo/home/index.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/_table_header.html.erb +8 -0
- data/app/views/avo/partials/_view_toggle_button.html.erb +0 -9
- data/app/views/avo/private/design.html.erb +2 -2
- data/app/views/layouts/avo/application.html.erb +3 -2
- data/avo.gemspec +1 -2
- data/config/initializers/pagy.rb +10 -12
- data/config/routes.rb +5 -5
- data/db/factories.rb +0 -17
- data/lib/avo/app.rb +165 -0
- data/lib/avo/base_action.rb +18 -31
- data/lib/avo/base_resource.rb +213 -238
- data/lib/avo/concerns/breadcrumbs.rb +2 -2
- data/lib/avo/concerns/can_replace_items.rb +7 -3
- data/lib/avo/concerns/filters_session_handler.rb +4 -5
- data/lib/avo/concerns/has_item_type.rb +0 -4
- data/lib/avo/concerns/has_items.rb +115 -93
- data/lib/avo/concerns/is_visible.rb +1 -1
- data/lib/avo/concerns/model_class_constantized.rb +2 -0
- data/lib/avo/configuration.rb +8 -9
- data/lib/avo/current.rb +1 -35
- data/lib/avo/dsl/field_parser.rb +1 -1
- data/lib/avo/dynamic_router.rb +2 -13
- data/lib/avo/engine.rb +13 -11
- data/lib/avo/execution_context.rb +2 -4
- data/lib/avo/fields/base_field.rb +14 -51
- data/lib/avo/fields/belongs_to_field.rb +13 -20
- data/lib/avo/fields/concerns/is_searchable.rb +1 -1
- data/lib/avo/fields/concerns/use_resource.rb +1 -1
- data/lib/avo/fields/date_field.rb +3 -16
- data/lib/avo/fields/field_manager.rb +3 -13
- data/lib/avo/fields/file_field.rb +0 -2
- data/lib/avo/fields/files_field.rb +0 -6
- data/lib/avo/fields/has_base_field.rb +5 -5
- data/lib/avo/fields/has_one_field.rb +1 -2
- data/lib/avo/fields/id_field.rb +1 -2
- data/lib/avo/filters/base_filter.rb +0 -9
- data/lib/avo/grid_collector.rb +40 -0
- data/lib/avo/html/builder.rb +1 -3
- data/lib/avo/licensing/h_q.rb +6 -11
- data/lib/avo/licensing/license.rb +1 -1
- data/lib/avo/licensing/license_manager.rb +1 -1
- data/lib/avo/licensing/{nil_license.rb → null_license.rb} +1 -1
- data/lib/avo/loaders/fields_loader.rb +1 -7
- data/lib/avo/plugin.rb +0 -10
- data/lib/avo/plugin_manager.rb +4 -2
- data/lib/avo/reloader.rb +1 -1
- data/lib/avo/resources/controls/actions_list.rb +1 -2
- data/lib/avo/resources/controls/create_button.rb +1 -1
- data/lib/avo/resources/controls/delete_button.rb +1 -1
- data/lib/avo/resources/controls/detach_button.rb +1 -1
- data/lib/avo/resources/controls/edit_button.rb +1 -1
- data/lib/avo/resources/controls/show_button.rb +1 -1
- data/lib/avo/resources/items/holder.rb +5 -13
- data/lib/avo/resources/items/item_group.rb +0 -1
- data/lib/avo/resources/resource_manager.rb +18 -11
- data/lib/avo/services/debug_service.rb +5 -6
- data/lib/avo/services/telemetry_service.rb +2 -3
- data/lib/avo/version.rb +1 -1
- data/lib/avo.rb +25 -109
- data/lib/generators/avo/action_generator.rb +8 -8
- data/lib/generators/avo/card/chartkick_generator.rb +18 -0
- data/lib/generators/avo/card/metric_generator.rb +18 -0
- data/lib/generators/avo/card/partial_generator.rb +19 -0
- data/lib/generators/avo/eject_generator.rb +0 -1
- data/lib/generators/avo/filter_generator.rb +8 -8
- data/lib/generators/avo/install_generator.rb +1 -11
- data/lib/generators/avo/resource_generator.rb +4 -22
- data/lib/generators/avo/tailwindcss/install_generator.rb +1 -4
- data/lib/generators/avo/templates/action.tt +5 -7
- 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 +3 -5
- data/lib/generators/avo/templates/initializer/avo.tt +2 -4
- data/lib/generators/avo/templates/resource/resource.tt +6 -6
- data/lib/generators/avo/templates/scope.tt +1 -1
- data/lib/generators/avo/templates/standalone_action.tt +8 -0
- data/lib/generators/avo/templates/tailwindcss/Procfile.dev +1 -1
- data/lib/tasks/avo_tasks.rake +0 -5
- metadata +19 -56
- data/app/assets/svgs/map-empty-state.svg +0 -35
- data/app/assets/svgs/map-view-type.svg +0 -3
- data/app/components/avo/fields/area_field/edit_component.html.erb +0 -7
- data/app/components/avo/fields/area_field/edit_component.rb +0 -4
- data/app/components/avo/fields/area_field/show_component.html.erb +0 -8
- data/app/components/avo/fields/area_field/show_component.rb +0 -4
- data/app/components/avo/fields/common/files/controls_component.html.erb +0 -29
- data/app/components/avo/fields/common/files/controls_component.rb +0 -19
- data/app/components/avo/fields/common/files/list_viewer_component.html.erb +0 -20
- data/app/components/avo/fields/common/files/list_viewer_component.rb +0 -41
- data/app/components/avo/fields/common/files/view_type/grid_component.html.erb +0 -27
- data/app/components/avo/fields/common/files/view_type/grid_component.rb +0 -51
- data/app/components/avo/fields/common/files/view_type/list_component.html.erb +0 -22
- data/app/components/avo/fields/common/files/view_type/list_component.rb +0 -15
- data/app/components/avo/fields/location_field/edit_component.html.erb +0 -22
- data/app/components/avo/fields/location_field/edit_component.rb +0 -4
- data/app/components/avo/fields/location_field/show_component.html.erb +0 -7
- data/app/components/avo/fields/location_field/show_component.rb +0 -4
- data/app/components/avo/index/resource_map_component.html.erb +0 -16
- data/app/components/avo/index/resource_map_component.rb +0 -109
- data/app/components/avo/row_component.html.erb +0 -3
- data/app/components/avo/row_component.rb +0 -12
- data/app/views/avo/attachments/destroy.turbo_stream.erb +0 -7
- data/app/views/avo/partials/_profile_menu_extra.html.erb +0 -2
- data/lib/avo/concerns/has_description.rb +0 -23
- data/lib/avo/fields/area_field.rb +0 -39
- data/lib/avo/fields/concerns/file_authorization.rb +0 -31
- data/lib/avo/fields/location_field.rb +0 -86
- data/lib/avo/resources/items/row.rb +0 -54
- data/lib/generators/avo/card_generator.rb +0 -27
- data/public/avo-assets/avo.base.css +0 -10542
- data/public/avo-assets/avo.base.js +0 -949
- data/public/avo-assets/avo.base.js.map +0 -7
- data/public/avo-assets/avo.js +0 -513
- data/public/avo-assets/avo.js.map +0 -7
@@ -7,7 +7,7 @@ module Avo
|
|
7
7
|
|
8
8
|
@label = args[:label] || I18n.t("avo.edit").capitalize
|
9
9
|
if args[:item].present?
|
10
|
-
@title = I18n.t("avo.edit_item", item: args[:item]).
|
10
|
+
@title = I18n.t("avo.edit_item", item: args[:item]).capitalize if title.nil?
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -22,29 +22,21 @@ 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
|
|
29
29
|
add_item field_parser.instance
|
30
30
|
end
|
31
31
|
|
32
|
-
def tabs(
|
33
|
-
|
34
|
-
add_item tab
|
35
|
-
else
|
36
|
-
add_item Avo::Resources::Items::TabGroup::Builder.parse_block(**kwargs, &block)
|
37
|
-
end
|
32
|
+
def tabs(instance)
|
33
|
+
add_item instance
|
38
34
|
end
|
39
35
|
|
40
36
|
def tab(name, **args, &block)
|
41
37
|
add_item Avo::Resources::Items::Tab::Builder.parse_block(name: name, **args, &block)
|
42
38
|
end
|
43
39
|
|
44
|
-
def row(**args, &block)
|
45
|
-
add_item Avo::Resources::Items::Row::Builder.parse_block(**args, &block)
|
46
|
-
end
|
47
|
-
|
48
40
|
def tool(klass, **args)
|
49
41
|
instance = klass.new(**args)
|
50
42
|
add_item instance
|
@@ -62,8 +54,8 @@ class Avo::Resources::Items::Holder
|
|
62
54
|
add_item field
|
63
55
|
end
|
64
56
|
|
65
|
-
def sidebar(
|
66
|
-
add_item
|
57
|
+
def sidebar(instance)
|
58
|
+
add_item instance
|
67
59
|
end
|
68
60
|
|
69
61
|
def add_item(instance)
|
@@ -66,6 +66,9 @@ 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
|
69
72
|
end
|
70
73
|
|
71
74
|
def check_bad_resources
|
@@ -73,13 +76,13 @@ module Avo
|
|
73
76
|
has_model = resource.model_class.present?
|
74
77
|
|
75
78
|
unless has_model
|
76
|
-
possible_model = resource.to_s.gsub "Avo::Resources::", ""
|
79
|
+
possible_model = resource.class.to_s.gsub "Avo::Resources::", ""
|
77
80
|
possible_model = possible_model.gsub "Resource", ""
|
78
81
|
|
79
|
-
Avo.
|
82
|
+
Avo::App.errors.add({
|
80
83
|
url: "https://docs.avohq.io/2.0/resources.html#custom-model-class",
|
81
84
|
target: "_blank",
|
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"
|
85
|
+
message: "#{resource.class} 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"
|
83
86
|
})
|
84
87
|
end
|
85
88
|
end
|
@@ -87,23 +90,27 @@ module Avo
|
|
87
90
|
|
88
91
|
# Filters out the resources that are missing the model_class
|
89
92
|
def valid_resources
|
90
|
-
resources
|
93
|
+
resources
|
94
|
+
.select do |resource|
|
95
|
+
resource.model_class.present?
|
96
|
+
end
|
97
|
+
.sort_by(&:to_s)
|
91
98
|
end
|
92
99
|
|
93
100
|
# Returns the Avo resource by camelized name
|
94
101
|
#
|
95
|
-
# get_resource_by_name('User') =>
|
102
|
+
# get_resource_by_name('User') => Avo::Resources::User
|
96
103
|
def get_resource(resource)
|
97
104
|
resource = "Avo::Resources::#{resource}" unless resource.to_s.starts_with?("Avo::Resources::")
|
98
105
|
|
99
106
|
resources.find do |available_resource|
|
100
|
-
resource.to_s == available_resource.to_s
|
107
|
+
resource.to_s == available_resource.class.to_s
|
101
108
|
end
|
102
109
|
end
|
103
110
|
|
104
111
|
# Returns the Avo resource by singular snake_cased name
|
105
112
|
#
|
106
|
-
# get_resource_by_name('user') =>
|
113
|
+
# get_resource_by_name('user') => Avo::Resources::User
|
107
114
|
def get_resource_by_name(name)
|
108
115
|
get_resource name.singularize.camelize
|
109
116
|
end
|
@@ -111,8 +118,8 @@ module Avo
|
|
111
118
|
# Returns the Avo resource by singular snake_cased name
|
112
119
|
# From all the resources that use the same model_class, it will fetch the first one in alphabetical order
|
113
120
|
#
|
114
|
-
# get_resource_by_name('User') =>
|
115
|
-
# get_resource_by_name(User) =>
|
121
|
+
# get_resource_by_name('User') => Avo::Resources::User
|
122
|
+
# get_resource_by_name(User) => Avo::Resources::User
|
116
123
|
|
117
124
|
def get_resource_by_model_class(klass)
|
118
125
|
# Fetch the mappings imposed by the user.
|
@@ -128,8 +135,8 @@ module Avo
|
|
128
135
|
|
129
136
|
# Returns the Avo resource by singular snake_cased name
|
130
137
|
#
|
131
|
-
# get_resource_by_controller_name('delayed_backend_active_record_jobs') =>
|
132
|
-
# get_resource_by_controller_name('users') =>
|
138
|
+
# get_resource_by_controller_name('delayed_backend_active_record_jobs') => DelayedJobResource
|
139
|
+
# get_resource_by_controller_name('users') => Avo::Resources::User
|
133
140
|
def get_resource_by_controller_name(name)
|
134
141
|
valid_resources
|
135
142
|
.find do |resource|
|
@@ -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.cache_store&.class&.to_s
|
15
|
+
payload[:cache_store] = Avo::App.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.resource_manager.all
|
35
|
-
dashboards = defined?(
|
34
|
+
resources = Avo::Current.app.resource_manager.all
|
35
|
+
dashboards = defined?(AvoDashboards) ? AvoDashboards.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,10 @@ 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
|
-
|
58
|
+
**other_metadata(:actions),
|
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.cache_store&.class&.to_s,
|
63
62
|
**config_metadata
|
64
63
|
}
|
65
64
|
# rescue => error
|
@@ -69,7 +68,7 @@ class Avo::Services::DebugService
|
|
69
68
|
end
|
70
69
|
|
71
70
|
def other_metadata(type = :actions)
|
72
|
-
resources = Avo.resource_manager.all
|
71
|
+
resources = Avo::Current.app.resource_manager.all
|
73
72
|
|
74
73
|
types = resources.map(&:"get_#{type}")
|
75
74
|
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.resource_manager.all
|
26
|
+
resources = Avo::Current.app.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,6 @@ 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.cache_store&.class&.to_s,
|
55
54
|
**config_metadata
|
56
55
|
}
|
57
56
|
# rescue => error
|
@@ -61,7 +60,7 @@ class Avo::Services::TelemetryService
|
|
61
60
|
end
|
62
61
|
|
63
62
|
def other_metadata(type = :actions)
|
64
|
-
resources = Avo.resource_manager.all
|
63
|
+
resources = Avo::Current.app.resource_manager.all
|
65
64
|
|
66
65
|
types = resources.map(&:"get_#{type}")
|
67
66
|
type_count = types.flatten.uniq.count
|
data/lib/avo/version.rb
CHANGED
data/lib/avo.rb
CHANGED
@@ -11,9 +11,31 @@ loader.inflector.inflect(
|
|
11
11
|
loader.ignore("#{__dir__}/generators")
|
12
12
|
loader.setup
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
# .//*,,.....,,*/(*
|
15
|
+
# **,,..............,*#.
|
16
|
+
# ,*,,..... .....*/#.
|
17
|
+
# **,,.... ....,*/%%
|
18
|
+
# ,**,,....... . ....*/#&%
|
19
|
+
# **,,,...... . . ....*/#&&%
|
20
|
+
# **,,........ . . ...,//#&&&.
|
21
|
+
# */*,,..*//***,,,,*/(,.. .. .....*//%&%&*
|
22
|
+
# ,/**,..**/******,,***/(###,...........,//(%&&%.
|
23
|
+
# /**,,..((//*****////((##%%%%%*.........*//%%&&%
|
24
|
+
# ****,...#/**,,,*,*/(#%##%%%%&&&(*,.....,*/(%&&&/
|
25
|
+
# /**,....(/*,,,,,,,*(##%%%%%&&&&&(,.....,*(#&&&&.
|
26
|
+
# ,//*,.....(/*,,**//(##%%%%&&&&@&&%/,....,*((&&&&*
|
27
|
+
# .//*,,.....(((//(((##%%%&&&&&&&&@#/,....,*/#%&&&#
|
28
|
+
# (/**,,......###%%%%%&&&&&&&&&&@#/,,...,,*/#&&&&&
|
29
|
+
# (/**,,........%%%%%&&&&&&&&@%(*,...,,,*//(&&&&%.
|
30
|
+
# ///*,,,.........,*#&&&&#(/,,.....,,,*//(%&&&&%*
|
31
|
+
# (//**,,,.....................,,,,*//(%&&&&&&*
|
32
|
+
# *(///**,,,,............,,,,,,**/((&&&&&&&%.
|
33
|
+
# ((///*****,,,,,,,,,,,,***//((&&&&&%&%&#
|
34
|
+
# .((((////********///(((%&%&&&&%%%%%
|
35
|
+
# (############%%%%%%%%%%%%%%%*
|
36
|
+
# ,(############%%%%%#*
|
16
37
|
|
38
|
+
module Avo
|
17
39
|
ROOT_PATH = Pathname.new(File.join(__dir__, ".."))
|
18
40
|
IN_DEVELOPMENT = ENV["AVO_IN_DEVELOPMENT"] == "1"
|
19
41
|
PACKED = !IN_DEVELOPMENT
|
@@ -39,115 +61,9 @@ module Avo
|
|
39
61
|
|
40
62
|
class MissingGemError < StandardError; end
|
41
63
|
|
42
|
-
class DeprecatedAPIError < StandardError; end
|
43
|
-
|
44
64
|
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
|
-
|
101
65
|
def avo_filters_installed?
|
102
|
-
defined?(
|
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
|
66
|
+
defined?(AvoFilters).present?
|
151
67
|
end
|
152
68
|
end
|
153
69
|
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
|
9
|
-
class_option :name, type: :string
|
8
|
+
class_option :standalone, type: :boolean
|
10
9
|
|
11
10
|
namespace "avo:action"
|
12
11
|
|
13
12
|
def create_resource_file
|
14
|
-
|
15
|
-
end
|
13
|
+
type = "resource"
|
16
14
|
|
17
|
-
|
18
|
-
configuration = " self.name = \"#{options[:name] || name.titleize}\""
|
19
|
-
configuration += "\n self.standalone = true" if options[:standalone]
|
15
|
+
type = "standalone" if options[:standalone]
|
20
16
|
|
21
|
-
|
17
|
+
if type == "standalone"
|
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
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative "../named_base_generator"
|
2
|
+
|
3
|
+
module Generators
|
4
|
+
module Avo
|
5
|
+
module Card
|
6
|
+
class ChartkickGenerator < Generators::Avo::NamedBaseGenerator
|
7
|
+
source_root File.expand_path("../templates", __dir__)
|
8
|
+
|
9
|
+
namespace "avo:card:chartkick"
|
10
|
+
desc "Add a chartkick card for your Avo dashboard."
|
11
|
+
|
12
|
+
def handle
|
13
|
+
template "cards/chartkick_card_sample.tt", "app/avo/cards/#{name.underscore}.rb"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative "../named_base_generator"
|
2
|
+
|
3
|
+
module Generators
|
4
|
+
module Avo
|
5
|
+
module Card
|
6
|
+
class MetricGenerator < Generators::Avo::NamedBaseGenerator
|
7
|
+
source_root File.expand_path("../templates", __dir__)
|
8
|
+
|
9
|
+
namespace "avo:card:metric"
|
10
|
+
desc "Add a metric card for your Avo dashboard."
|
11
|
+
|
12
|
+
def handle
|
13
|
+
template "cards/metric_card_sample.tt", "app/avo/cards/#{name.underscore}.rb"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative "../named_base_generator"
|
2
|
+
|
3
|
+
module Generators
|
4
|
+
module Avo
|
5
|
+
module Card
|
6
|
+
class PartialGenerator < Generators::Avo::NamedBaseGenerator
|
7
|
+
source_root File.expand_path("../templates", __dir__)
|
8
|
+
|
9
|
+
namespace "avo:card:partial"
|
10
|
+
desc "Add a partial card for your Avo dashboard."
|
11
|
+
|
12
|
+
def handle
|
13
|
+
template "cards/partial_card_sample.tt", "app/avo/cards/#{name.underscore}.rb"
|
14
|
+
template "cards/partial_card_partial.tt", "app/views/avo/cards/_#{name.underscore}.html.erb"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -17,7 +17,6 @@ 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",
|
21
20
|
}
|
22
21
|
|
23
22
|
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 :
|
8
|
+
class_option :multiple_select, type: :boolean
|
9
|
+
class_option :select, type: :boolean
|
10
|
+
class_option :text, type: :boolean
|
9
11
|
|
10
12
|
namespace "avo:filter"
|
11
13
|
|
12
14
|
def create_resource_file
|
13
|
-
|
15
|
+
type = "boolean"
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
private
|
17
|
+
type = "multiple_select" if options[:multiple_select]
|
18
|
+
type = "select" if options[:select]
|
19
|
+
type = "text" if options[:text]
|
19
20
|
|
20
|
-
|
21
|
-
%w[boolean select text multiple_select]
|
21
|
+
template "filters/#{type}_filter.tt", "app/avo/filters/#{singular_name}.rb"
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -13,17 +13,7 @@ module Generators
|
|
13
13
|
route "mount Avo::Engine, at: Avo.configuration.root_path"
|
14
14
|
|
15
15
|
template "initializer/avo.tt", "config/initializers/avo.rb"
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
def create_resources
|
20
|
-
if defined?(User).present?
|
21
|
-
Rails::Generators.invoke("avo:resource", ["user", "-q"], {destination_root: Rails.root })
|
22
|
-
end
|
23
|
-
|
24
|
-
if defined?(Account).present?
|
25
|
-
Rails::Generators.invoke("avo:resource", ["account", "-q"], {destination_root: Rails.root })
|
26
|
-
end
|
16
|
+
directory File.join(__dir__, "templates", "locales"), "config/locales"
|
27
17
|
end
|
28
18
|
end
|
29
19
|
end
|
@@ -87,20 +87,12 @@ module Generators
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
-
def rich_texts
|
91
|
-
@rich_texts ||= reflections.select do |_, reflection|
|
92
|
-
reflection.options[:class_name] == "ActionText::RichText"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
90
|
def tags
|
97
91
|
@tags ||= reflections.select { |_, reflection| reflection.options[:as] == :taggable }
|
98
92
|
end
|
99
93
|
|
100
94
|
def associations
|
101
|
-
@associations ||= reflections.reject
|
102
|
-
attachments.key?(key) || tags.key?(key) || rich_texts.key?(key)
|
103
|
-
end
|
95
|
+
@associations ||= reflections.reject { |key| attachments.key?(key) || tags.key?(key) }
|
104
96
|
end
|
105
97
|
|
106
98
|
def fields
|
@@ -123,7 +115,6 @@ module Generators
|
|
123
115
|
fields_from_model_enums
|
124
116
|
fields_from_model_attachements
|
125
117
|
fields_from_model_associations
|
126
|
-
fields_from_model_rich_texts
|
127
118
|
fields_from_model_tags
|
128
119
|
|
129
120
|
generated_fields_template
|
@@ -132,12 +123,9 @@ module Generators
|
|
132
123
|
def generated_fields_template
|
133
124
|
return if fields.blank?
|
134
125
|
|
135
|
-
fields_string = ""
|
126
|
+
fields_string = "\n # Fields generated from the model"
|
136
127
|
|
137
128
|
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
|
-
|
141
129
|
options = ""
|
142
130
|
field_options[:options].each { |k, v| options += ", #{k}: #{v}" } if field_options[:options].present?
|
143
131
|
|
@@ -161,12 +149,6 @@ module Generators
|
|
161
149
|
generated_fields_template
|
162
150
|
end
|
163
151
|
|
164
|
-
def fields_from_model_rich_texts
|
165
|
-
rich_texts.each do |name, _|
|
166
|
-
fields[(name.delete_prefix("rich_text_"))] = {field: "trix"}
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
152
|
def fields_from_model_tags
|
171
153
|
tags.each do |name, _|
|
172
154
|
fields[(remove_last_word_from name).pluralize] = {field: "tags"}
|
@@ -184,7 +166,7 @@ module Generators
|
|
184
166
|
end
|
185
167
|
|
186
168
|
def field_from_through_association(association)
|
187
|
-
if association.through_reflection.is_a?
|
169
|
+
if association.through_reflection.is_a? ActiveRecord::Reflection::HasManyReflection
|
188
170
|
{
|
189
171
|
field: "has_many",
|
190
172
|
options: {
|
@@ -219,7 +201,7 @@ module Generators
|
|
219
201
|
fields[enum] = {
|
220
202
|
field: "select",
|
221
203
|
options: {
|
222
|
-
enum: "::#{model_class.
|
204
|
+
enum: "::#{model_class.capitalize}.#{enum.pluralize}"
|
223
205
|
}
|
224
206
|
}
|
225
207
|
end
|
@@ -21,7 +21,7 @@ module Generators
|
|
21
21
|
end
|
22
22
|
|
23
23
|
if Rails.root.join("Procfile.dev").exist?
|
24
|
-
append_to_file "Procfile.dev", "avo_css:
|
24
|
+
append_to_file "Procfile.dev", "avo_css: bin/rails avo:tailwindcss:watch\n"
|
25
25
|
else
|
26
26
|
say "Add default Procfile.dev"
|
27
27
|
copy_file template_path("Procfile.dev"), "Procfile.dev"
|
@@ -38,9 +38,6 @@ module Generators
|
|
38
38
|
|
39
39
|
say "Adding the CSS asset to the partial"
|
40
40
|
prepend_to_file Rails.root.join("app", "views", "avo", "partials", "_pre_head.html.erb"), "<%= stylesheet_link_tag \"avo.tailwind.css\", media: \"all\" %>"
|
41
|
-
|
42
|
-
say "Ensure you have the following script in your package.json file.", :yellow
|
43
|
-
say %("scripts": { "avo:tailwindcss": "tailwindcss -i ./app/assets/stylesheets/avo.tailwind.css -o ./app/assets/builds/avo.tailwind.css --minify" }), :green
|
44
41
|
end
|
45
42
|
|
46
43
|
no_tasks do
|
@@ -1,16 +1,14 @@
|
|
1
1
|
class Avo::Actions::<%= class_name.camelize %> < Avo::BaseAction
|
2
|
-
<%=
|
2
|
+
self.name = "<%= name.underscore.humanize %>"
|
3
3
|
# self.visible = -> do
|
4
4
|
# true
|
5
5
|
# end
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
# end
|
7
|
+
def handle(**args)
|
8
|
+
models, fields, current_user, resource = args.values_at(:models, :fields, :current_user, :resource)
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
# Do something with your records.
|
10
|
+
models.each do |model|
|
11
|
+
# Do something with your models.
|
14
12
|
end
|
15
13
|
end
|
16
14
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class Avo::Cards::<%= class_name.camelize %> <
|
1
|
+
class Avo::Cards::<%= class_name.camelize %> < AvoDashboards::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 %> < AvoDashboards::ChartkickCard
|
2
2
|
self.id = "<%= name.underscore %>"
|
3
3
|
self.label = "<%= name.underscore.humanize %>"
|
4
4
|
self.chart_type = :area_chart
|