avo 2.1.2.pre2 → 2.2.2
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 -2
- data/Gemfile.lock +11 -5
- data/app/assets/svgs/{dashboards-icon.svg → dashboards.svg} +1 -1
- data/app/assets/svgs/{resources-icon.svg → resources.svg} +0 -0
- data/app/assets/svgs/{tools-icon.svg → tools.svg} +0 -0
- data/app/components/avo/button_component.rb +6 -2
- data/app/components/avo/fields/belongs_to_field/autocomplete_component.html.erb +1 -0
- data/app/components/avo/fields/belongs_to_field/edit_component.rb +5 -2
- data/app/components/avo/index/field_wrapper_component.rb +13 -0
- data/app/components/avo/index/grid_item_component.html.erb +3 -1
- data/app/components/avo/index/table_row_component.html.erb +7 -5
- data/app/components/avo/panel_component.html.erb +4 -4
- data/app/components/avo/profile_item_component.html.erb +2 -2
- data/app/components/avo/profile_item_component.rb +6 -0
- data/app/components/avo/sidebar/base_item_component.rb +31 -0
- data/app/components/avo/sidebar/group_component.html.erb +28 -0
- data/app/components/avo/sidebar/group_component.rb +4 -0
- data/app/components/avo/sidebar/heading_component.html.erb +14 -0
- data/app/components/avo/sidebar/heading_component.rb +15 -0
- data/app/components/avo/sidebar/item_switcher_component.html.erb +16 -0
- data/app/components/avo/sidebar/item_switcher_component.rb +15 -0
- data/app/components/avo/sidebar/link_component.html.erb +12 -0
- data/app/components/avo/sidebar/link_component.rb +28 -0
- data/app/components/avo/sidebar/section_component.html.erb +15 -0
- data/app/components/avo/sidebar/section_component.rb +9 -0
- data/app/components/avo/sidebar_component.html.erb +33 -24
- data/app/components/avo/sidebar_component.rb +3 -9
- data/app/components/avo/sidebar_profile_component.html.erb +10 -1
- data/app/components/avo/views/resource_edit_component.html.erb +2 -2
- data/app/components/avo/views/resource_new_component.html.erb +2 -2
- data/app/components/avo/views/resource_show_component.html.erb +2 -2
- data/app/controllers/avo/application_controller.rb +1 -2
- data/app/controllers/avo/base_controller.rb +1 -1
- data/app/helpers/avo/application_helper.rb +2 -0
- data/app/javascript/js/controllers/loading_button_controller.js +47 -10
- data/app/javascript/js/controllers/menu_controller.js +60 -0
- data/app/javascript/js/controllers/search_controller.js +28 -10
- data/app/javascript/js/controllers.js +2 -0
- data/app/views/avo/base/_boolean_filter.html.erb +1 -1
- data/app/views/avo/base/_multiple_select_filter.html.erb +7 -4
- data/app/views/avo/base/_select_filter.html.erb +1 -1
- data/app/views/avo/base/_text_filter.html.erb +1 -1
- data/app/views/avo/partials/_table_header.html.erb +12 -13
- data/app/views/layouts/avo/application.html.erb +3 -0
- data/avo.gemspec +1 -0
- data/bin/helpers.rb +7 -1
- data/bin/init +2 -2
- data/lib/avo/app.rb +8 -86
- data/lib/avo/base_resource.rb +1 -3
- data/lib/avo/concerns/fetches_things.rb +127 -0
- data/lib/avo/configuration.rb +4 -0
- data/lib/avo/dynamic_router.rb +1 -1
- data/lib/avo/engine.rb +0 -1
- data/lib/avo/fields/base_field.rb +2 -0
- data/lib/avo/fields/belongs_to_field.rb +2 -0
- data/lib/avo/hosts/base_host.rb +20 -0
- data/lib/avo/licensing/pro_license.rb +2 -1
- data/lib/avo/menu/base_item.rb +20 -0
- data/lib/avo/menu/builder.rb +77 -0
- data/lib/avo/menu/dashboard.rb +17 -0
- data/lib/avo/menu/group.rb +2 -0
- data/lib/avo/menu/link.rb +4 -0
- data/lib/avo/menu/menu.rb +2 -0
- data/lib/avo/menu/resource.rb +9 -0
- data/lib/avo/menu/section.rb +2 -0
- data/lib/avo/reloader.rb +15 -7
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/filter_generator.rb +2 -0
- data/lib/generators/avo/templates/filters/boolean_filter.tt +1 -1
- data/lib/generators/avo/templates/filters/multiple_select_filter.tt +11 -0
- data/lib/generators/avo/templates/filters/select_filter.tt +1 -1
- data/lib/generators/avo/templates/filters/text_filter.tt +1 -1
- data/lib/generators/avo/templates/tool/sidebar_item.tt +1 -1
- data/public/avo-assets/avo.css +23 -6
- data/public/avo-assets/avo.js +63 -63
- data/public/avo-assets/avo.js.map +3 -3
- metadata +44 -14
- data/app/assets/builds/avo.css +0 -8810
- data/app/assets/builds/avo.js +0 -423
- data/app/assets/builds/avo.js.map +0 -7
- data/app/components/avo/sidebar_heading_component.html.erb +0 -3
- data/app/components/avo/sidebar_heading_component.rb +0 -11
- data/app/components/avo/sidebar_item_component.html.erb +0 -3
- data/app/components/avo/sidebar_item_component.rb +0 -10
data/lib/avo/configuration.rb
CHANGED
@@ -29,6 +29,8 @@ module Avo
|
|
29
29
|
attr_accessor :raise_error_on_missing_policy
|
30
30
|
attr_accessor :disabled_features
|
31
31
|
attr_accessor :buttons_on_form_footers
|
32
|
+
attr_accessor :main_menu
|
33
|
+
attr_accessor :profile_menu
|
32
34
|
|
33
35
|
def initialize
|
34
36
|
@root_path = "/avo"
|
@@ -70,6 +72,8 @@ module Avo
|
|
70
72
|
@raise_error_on_missing_policy = false
|
71
73
|
@disabled_features = []
|
72
74
|
@buttons_on_form_footers = false
|
75
|
+
@main_menu = nil
|
76
|
+
@profile_menu = nil
|
73
77
|
end
|
74
78
|
|
75
79
|
def locale_tag
|
data/lib/avo/dynamic_router.rb
CHANGED
data/lib/avo/engine.rb
CHANGED
@@ -19,7 +19,6 @@ module Avo
|
|
19
19
|
|
20
20
|
config.i18n.load_path += Dir[Avo::Engine.root.join('lib', 'generators', 'avo', 'templates', 'locales', '*.{rb,yml}')]
|
21
21
|
|
22
|
-
# initializer "avo.autoload", before: :set_autoload_paths do |app|
|
23
22
|
initializer "avo.autoload" do |app|
|
24
23
|
[
|
25
24
|
["app", "avo", "fields"],
|
@@ -26,6 +26,7 @@ module Avo
|
|
26
26
|
attr_reader :as_label
|
27
27
|
attr_reader :as_avatar
|
28
28
|
attr_reader :as_description
|
29
|
+
attr_reader :index_text_align
|
29
30
|
|
30
31
|
# Private options
|
31
32
|
attr_reader :updatable
|
@@ -64,6 +65,7 @@ module Avo
|
|
64
65
|
@as_label = args[:as_label] || false
|
65
66
|
@as_avatar = args[:as_avatar] || false
|
66
67
|
@as_description = args[:as_description] || false
|
68
|
+
@index_text_align = args[:index_text_align] || :left
|
67
69
|
|
68
70
|
@updatable = true
|
69
71
|
@computable = true
|
@@ -61,6 +61,7 @@ module Avo
|
|
61
61
|
attr_reader :polymorphic_as
|
62
62
|
attr_reader :relation_method
|
63
63
|
attr_reader :types # for Polymorphic associations
|
64
|
+
attr_reader :allow_via_detaching
|
64
65
|
|
65
66
|
def initialize(id, **args, &block)
|
66
67
|
args[:placeholder] ||= I18n.t("avo.choose_an_option")
|
@@ -71,6 +72,7 @@ module Avo
|
|
71
72
|
@polymorphic_as = args[:polymorphic_as]
|
72
73
|
@types = args[:types]
|
73
74
|
@relation_method = id.to_s.parameterize.underscore
|
75
|
+
@allow_via_detaching = args[:allow_via_detaching] == true
|
74
76
|
end
|
75
77
|
|
76
78
|
def searchable
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "dry-initializer"
|
2
|
+
|
3
|
+
# This object holds some data tha is usually needed to compute blocks around the app.
|
4
|
+
module Avo
|
5
|
+
module Hosts
|
6
|
+
class BaseHost
|
7
|
+
extend Dry::Initializer
|
8
|
+
|
9
|
+
option :context, default: proc { Avo::App.context }
|
10
|
+
option :params, default: proc { Avo::App.params }
|
11
|
+
option :view_context, default: proc { Avo::App.view_context }
|
12
|
+
option :current_user, default: proc { Avo::App.current_user }
|
13
|
+
option :block, optional: true
|
14
|
+
|
15
|
+
def handle
|
16
|
+
instance_exec(&block)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "dry-initializer"
|
2
|
+
|
3
|
+
class Avo::Menu::BaseItem
|
4
|
+
extend Dry::Initializer
|
5
|
+
|
6
|
+
option :collapsable, default: proc { false }
|
7
|
+
option :collapsed, default: proc { false }
|
8
|
+
option :icon, optional: true
|
9
|
+
option :items, default: proc { [] }
|
10
|
+
option :name, default: proc { "" }
|
11
|
+
option :visible, default: proc { true }
|
12
|
+
|
13
|
+
def visible?
|
14
|
+
return visible if visible.in? [true, false]
|
15
|
+
|
16
|
+
if visible.respond_to? :call
|
17
|
+
Avo::Hosts::BaseHost.new(block: visible).handle
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
class Avo::Menu::Builder
|
2
|
+
class << self
|
3
|
+
def parse_menu(&block)
|
4
|
+
Docile.dsl_eval(Avo::Menu::Builder.new, &block).build
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(name: nil, items: [])
|
9
|
+
@menu = Avo::Menu::Menu.new
|
10
|
+
|
11
|
+
@menu.name = name
|
12
|
+
@menu.items = items
|
13
|
+
end
|
14
|
+
|
15
|
+
# Adds a link
|
16
|
+
def link(name, **args)
|
17
|
+
@menu.items << Avo::Menu::Link.new(name: name, **args)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Validates and adds a resource
|
21
|
+
def resource(name, **args)
|
22
|
+
name = name.to_s.singularize
|
23
|
+
res = Avo::App.guess_resource(name)
|
24
|
+
|
25
|
+
if res.present?
|
26
|
+
@menu.items << Avo::Menu::Resource.new(resource: name, **args)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
alias_method :resources, :resource
|
30
|
+
|
31
|
+
# Adds a dashboard
|
32
|
+
def dashboard(dashboard, **args)
|
33
|
+
@menu.items << Avo::Menu::Dashboard.new(dashboard: dashboard, **args)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Adds a section
|
37
|
+
def section(name = nil, **args, &block)
|
38
|
+
@menu.items << Avo::Menu::Section.new(name: name, **args, items: self.class.parse_menu(&block).items)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Adds a group
|
42
|
+
def group(name = nil, **args, &block)
|
43
|
+
@menu.items << Avo::Menu::Group.new(name: name, **args, items: self.class.parse_menu(&block).items)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Add all the resources
|
47
|
+
def all_resources(**args)
|
48
|
+
Avo::App.resources_for_navigation.each do |res|
|
49
|
+
resource res.model_class, **args
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Add all the dashboards
|
54
|
+
def all_dashboards(**args)
|
55
|
+
Avo::App.dashboards_for_navigation.each do |dash|
|
56
|
+
dashboard dash.id, **args
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Add all the tools
|
61
|
+
def all_tools(**args)
|
62
|
+
Avo::App.tools_for_navigation.each do |tool|
|
63
|
+
link tool.humanize, path: "#{root_path}/#{tool}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Fetch the menu
|
68
|
+
def build
|
69
|
+
@menu
|
70
|
+
end
|
71
|
+
|
72
|
+
protected
|
73
|
+
|
74
|
+
def root_path
|
75
|
+
Avo::App.root_path
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Avo::Menu::Dashboard < Avo::Menu::BaseItem
|
2
|
+
extend Dry::Initializer
|
3
|
+
|
4
|
+
option :dashboard
|
5
|
+
|
6
|
+
def parsed_dashboard
|
7
|
+
dashboard_by_id || dashboard_by_name
|
8
|
+
end
|
9
|
+
|
10
|
+
def dashboard_by_name
|
11
|
+
Avo::App.get_dashboard_by_name dashboard.to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def dashboard_by_id
|
15
|
+
Avo::App.get_dashboard_by_id dashboard.to_s
|
16
|
+
end
|
17
|
+
end
|
data/lib/avo/reloader.rb
CHANGED
@@ -3,31 +3,39 @@ class Avo::Reloader
|
|
3
3
|
|
4
4
|
def reload!
|
5
5
|
# reload all files declared in paths
|
6
|
-
|
6
|
+
files.each do |file|
|
7
|
+
if File.exist? file
|
8
|
+
load file
|
9
|
+
end
|
10
|
+
end
|
7
11
|
|
8
12
|
# reload all files declared in each directory
|
9
13
|
directories.keys.each do |dir|
|
10
|
-
Dir.glob("#{dir}/**/*.rb".to_s).each
|
14
|
+
Dir.glob("#{dir}/**/*.rb".to_s).each do |file|
|
15
|
+
if File.exist? file
|
16
|
+
load file
|
17
|
+
end
|
18
|
+
end
|
11
19
|
end
|
12
20
|
end
|
13
21
|
|
14
22
|
private
|
15
23
|
def updater
|
16
|
-
@updater ||= config.file_watcher.new(
|
24
|
+
@updater ||= config.file_watcher.new(files, directories) { reload! }
|
17
25
|
end
|
18
26
|
|
19
|
-
def
|
27
|
+
def files
|
20
28
|
# we want to watch some files no matter what
|
21
|
-
|
29
|
+
paths = [
|
22
30
|
Rails.root.join("config", "initializers", "avo.rb"),
|
23
31
|
]
|
24
32
|
|
25
33
|
# we want to watch some files only in Avo development
|
26
34
|
if reload_lib?
|
27
|
-
|
35
|
+
paths += []
|
28
36
|
end
|
29
37
|
|
30
|
-
|
38
|
+
paths
|
31
39
|
end
|
32
40
|
|
33
41
|
def directories
|
data/lib/avo/version.rb
CHANGED
@@ -4,6 +4,7 @@ module Generators
|
|
4
4
|
module Avo
|
5
5
|
class FilterGenerator < ::Rails::Generators::NamedBase
|
6
6
|
source_root File.expand_path("templates", __dir__)
|
7
|
+
class_option :multiple_select, type: :boolean
|
7
8
|
class_option :select, type: :boolean
|
8
9
|
class_option :text, type: :boolean
|
9
10
|
|
@@ -12,6 +13,7 @@ module Generators
|
|
12
13
|
def create_resource_file
|
13
14
|
type = "boolean"
|
14
15
|
|
16
|
+
type = "multiple_select" if options[:multiple_select]
|
15
17
|
type = "select" if options[:select]
|
16
18
|
type = "text" if options[:text]
|
17
19
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class <%= class_name.camelize %> < Avo::Filters::TextFilter
|
2
|
-
self.name =
|
2
|
+
self.name = "<%= name.underscore.humanize %>"
|
3
3
|
self.button_label = 'Filter by <%= class_name.underscore.humanize.downcase.gsub(' filter', '') %>'
|
4
4
|
|
5
5
|
def apply(request, query, value)
|
@@ -1 +1 @@
|
|
1
|
-
<%%= render Avo::
|
1
|
+
<%%= render Avo::Sidebar::LinkComponent.new label: '<%= human_name %>', path: "#{avo.root_path}<%= file_name %>" %>
|
data/public/avo-assets/avo.css
CHANGED
@@ -6449,6 +6449,10 @@ progress[value]::-moz-progress-bar{
|
|
6449
6449
|
margin-left:50%
|
6450
6450
|
}
|
6451
6451
|
|
6452
|
+
.ml-auto{
|
6453
|
+
margin-left:auto
|
6454
|
+
}
|
6455
|
+
|
6452
6456
|
.-mb-2{
|
6453
6457
|
margin-bottom:-0.5rem
|
6454
6458
|
}
|
@@ -6677,6 +6681,10 @@ progress[value]::-moz-progress-bar{
|
|
6677
6681
|
min-width:200px
|
6678
6682
|
}
|
6679
6683
|
|
6684
|
+
.min-w-\[20px\]{
|
6685
|
+
min-width:20px
|
6686
|
+
}
|
6687
|
+
|
6680
6688
|
.max-w-168{
|
6681
6689
|
max-width:42rem
|
6682
6690
|
}
|
@@ -7381,6 +7389,11 @@ progress[value]::-moz-progress-bar{
|
|
7381
7389
|
padding-bottom:6rem
|
7382
7390
|
}
|
7383
7391
|
|
7392
|
+
.px-10{
|
7393
|
+
padding-left:2.5rem;
|
7394
|
+
padding-right:2.5rem
|
7395
|
+
}
|
7396
|
+
|
7384
7397
|
.py-8{
|
7385
7398
|
padding-top:2rem;
|
7386
7399
|
padding-bottom:2rem
|
@@ -7418,6 +7431,10 @@ progress[value]::-moz-progress-bar{
|
|
7418
7431
|
padding-bottom:75%
|
7419
7432
|
}
|
7420
7433
|
|
7434
|
+
.pt-2{
|
7435
|
+
padding-top:0.5rem
|
7436
|
+
}
|
7437
|
+
|
7421
7438
|
.text-left{
|
7422
7439
|
text-align:left
|
7423
7440
|
}
|
@@ -8007,14 +8024,14 @@ trix-editor {
|
|
8007
8024
|
background-color:rgb(6 95 158 / var(--tw-bg-opacity))
|
8008
8025
|
}
|
8009
8026
|
|
8010
|
-
.hover\:bg-
|
8027
|
+
.hover\:bg-blue-50:hover{
|
8011
8028
|
--tw-bg-opacity:1;
|
8012
|
-
background-color:rgb(
|
8029
|
+
background-color:rgb(251 253 255 / var(--tw-bg-opacity))
|
8013
8030
|
}
|
8014
8031
|
|
8015
|
-
.hover\:bg-
|
8032
|
+
.hover\:bg-gray-150:hover{
|
8016
8033
|
--tw-bg-opacity:1;
|
8017
|
-
background-color:rgb(
|
8034
|
+
background-color:rgb(233 234 236 / var(--tw-bg-opacity))
|
8018
8035
|
}
|
8019
8036
|
|
8020
8037
|
.hover\:text-gray-500:hover{
|
@@ -8484,8 +8501,8 @@ trix-editor {
|
|
8484
8501
|
opacity:0.5
|
8485
8502
|
}
|
8486
8503
|
|
8487
|
-
.disabled\:opacity-
|
8488
|
-
opacity:0.
|
8504
|
+
.disabled\:opacity-70:disabled{
|
8505
|
+
opacity:0.7
|
8489
8506
|
}
|
8490
8507
|
|
8491
8508
|
.group:hover .group-hover\:block{
|