avo 2.0.0 → 2.1.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 +1 -1
- data/Gemfile.lock +3 -3
- data/app/assets/svgs/save.svg +8 -1
- data/app/components/avo/actions_component.html.erb +1 -1
- data/app/components/avo/alert_component.rb +5 -5
- data/app/components/avo/blank_field_component.html.erb +0 -0
- data/app/components/avo/blank_field_component.rb +4 -0
- data/app/components/avo/fields/badge_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/boolean_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/external_image_field/index_component.html.erb +1 -2
- data/app/components/avo/fields/file_field/index_component.html.erb +3 -3
- data/app/components/avo/fields/file_field/index_component.rb +11 -0
- data/app/components/avo/fields/gravatar_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/progress_bar_field/index_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 -1
- data/app/components/avo/index/resource_controls_component.html.erb +5 -1
- data/app/components/avo/index/resource_table_component.html.erb +1 -1
- data/app/components/avo/panel_component.html.erb +10 -2
- data/app/components/avo/panel_component.rb +9 -0
- data/app/components/avo/referrer_params_component.html.erb +4 -0
- data/app/components/avo/referrer_params_component.rb +9 -0
- data/app/components/avo/sidebar_component.rb +3 -1
- data/app/components/avo/views/resource_edit_component.html.erb +14 -1
- data/app/components/avo/views/resource_new_component.html.erb +13 -0
- data/app/components/avo/views/resource_show_component.html.erb +1 -0
- data/app/controllers/avo/application_controller.rb +1 -1
- data/app/controllers/avo/base_controller.rb +57 -27
- data/app/controllers/avo/dashboards_controller.rb +1 -1
- data/app/controllers/avo/search_controller.rb +5 -1
- data/app/javascript/avo.js +4 -3
- data/app/views/avo/actions/show.html.erb +1 -0
- data/app/views/avo/associations/new.html.erb +1 -0
- data/app/views/avo/home/failed_to_load.html.erb +21 -1
- data/app/views/layouts/avo/application.html.erb +7 -0
- data/bin/dev +7 -6
- data/lib/avo/app.rb +8 -1
- data/lib/avo/base_action.rb +4 -4
- data/lib/avo/base_resource.rb +26 -7
- data/lib/avo/configuration.rb +2 -0
- data/lib/avo/dashboards/base_dashboard.rb +17 -0
- data/lib/avo/dashboards/chartkick_card.rb +1 -1
- data/lib/avo/fields/base_field.rb +19 -6
- data/lib/avo/fields/belongs_to_field.rb +1 -1
- data/lib/avo/fields/external_image_field.rb +2 -2
- data/lib/avo/hosts/dashboard_visibility.rb +19 -0
- data/lib/avo/licensing/pro_license.rb +1 -0
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/templates/dashboards/dashboard.tt +4 -1
- data/public/avo-assets/avo.css +37 -21
- data/public/avo-assets/avo.js +166 -165
- data/public/avo-assets/avo.js.map +3 -3
- metadata +7 -3
- data/app/views/avo/partials/_failed_state.html.erb +0 -16
data/bin/dev
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
#!/usr/bin/env bash
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
echo "Installing foreman..."
|
6
|
-
gem install foreman
|
7
|
-
fi
|
3
|
+
PORT="${PORT:-3030}"
|
4
|
+
export PORT
|
8
5
|
|
9
|
-
|
6
|
+
if command -v overmind &> /dev/null; then
|
7
|
+
overmind start -f Procfile.dev "$@"
|
8
|
+
else
|
9
|
+
foreman start -f Procfile.dev "$@"
|
10
|
+
fi
|
data/lib/avo/app.rb
CHANGED
@@ -10,6 +10,8 @@ module Avo
|
|
10
10
|
class_attribute :current_user, default: nil
|
11
11
|
class_attribute :root_path, default: nil
|
12
12
|
class_attribute :view_context, default: nil
|
13
|
+
class_attribute :params, default: {}
|
14
|
+
class_attribute :translation_enabled, default: false
|
13
15
|
|
14
16
|
class << self
|
15
17
|
def boot
|
@@ -24,14 +26,16 @@ module Avo
|
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
27
|
-
def init(request:, context:, current_user:, root_path:, view_context:)
|
29
|
+
def init(request:, context:, current_user:, root_path:, view_context:, params:)
|
28
30
|
self.request = request
|
29
31
|
self.context = context
|
30
32
|
self.current_user = current_user
|
31
33
|
self.root_path = root_path
|
32
34
|
self.view_context = view_context
|
35
|
+
self.params = params
|
33
36
|
|
34
37
|
self.license = Licensing::LicenseManager.new(Licensing::HQ.new(request).response).license
|
38
|
+
self.translation_enabled = license.has(:localization)
|
35
39
|
|
36
40
|
# Set the current host for ActiveStorage
|
37
41
|
begin
|
@@ -89,6 +93,9 @@ module Avo
|
|
89
93
|
.select do |dashboard|
|
90
94
|
dashboard != Dashboards::BaseDashboard
|
91
95
|
end
|
96
|
+
.uniq do |dashboard|
|
97
|
+
dashboard.id
|
98
|
+
end
|
92
99
|
end
|
93
100
|
|
94
101
|
# Returns the Avo dashboard by id
|
data/lib/avo/base_action.rb
CHANGED
@@ -27,16 +27,16 @@ module Avo
|
|
27
27
|
def form_data_attributes
|
28
28
|
# We can't respond with a file download from Turbo se we disable it on the form
|
29
29
|
if may_download_file
|
30
|
-
{
|
30
|
+
{turbo: false, remote: false}
|
31
31
|
else
|
32
|
-
{
|
32
|
+
{"turbo-frame": "_top", "action-target": "form"}
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
# We can't respond with a file download from Turbo se we disable close the modal manually after a while (it's a hack, we know)
|
37
37
|
def submit_button_data_attributes
|
38
38
|
if may_download_file
|
39
|
-
{
|
39
|
+
{action: "click->modal#delayedClose"}
|
40
40
|
else
|
41
41
|
{}
|
42
42
|
end
|
@@ -109,7 +109,7 @@ module Avo
|
|
109
109
|
args = {
|
110
110
|
fields: processed_fields,
|
111
111
|
current_user: current_user,
|
112
|
-
resource: resource
|
112
|
+
resource: resource
|
113
113
|
}
|
114
114
|
|
115
115
|
args[:models] = models unless standalone
|
data/lib/avo/base_resource.rb
CHANGED
@@ -11,6 +11,7 @@ module Avo
|
|
11
11
|
delegate :avo, to: :view_context
|
12
12
|
delegate :resource_path, to: :view_context
|
13
13
|
delegate :resources_path, to: :view_context
|
14
|
+
delegate :t, to: ::I18n
|
14
15
|
|
15
16
|
attr_accessor :view
|
16
17
|
attr_accessor :model
|
@@ -26,7 +27,7 @@ module Avo
|
|
26
27
|
class_attribute :includes, default: []
|
27
28
|
class_attribute :model_class
|
28
29
|
class_attribute :translation_key
|
29
|
-
class_attribute :translation_enabled
|
30
|
+
class_attribute :translation_enabled, default: false
|
30
31
|
class_attribute :default_view_type, default: :table
|
31
32
|
class_attribute :devise_password_optional, default: false
|
32
33
|
class_attribute :actions_loader
|
@@ -38,8 +39,11 @@ module Avo
|
|
38
39
|
class_attribute :resolve_query_scope
|
39
40
|
class_attribute :resolve_find_scope
|
40
41
|
class_attribute :ordering
|
42
|
+
class_attribute :search_hide_from_global_search, default: false
|
41
43
|
|
42
44
|
class << self
|
45
|
+
delegate :t, to: ::I18n
|
46
|
+
|
43
47
|
def grid(&block)
|
44
48
|
grid_collector = GridCollector.new
|
45
49
|
grid_collector.instance_eval(&block)
|
@@ -96,6 +100,8 @@ module Avo
|
|
96
100
|
self.class.model_class = model_class.base_class
|
97
101
|
end
|
98
102
|
end
|
103
|
+
|
104
|
+
self.class.translation_enabled = ::Avo::App.translation_enabled
|
99
105
|
end
|
100
106
|
|
101
107
|
def hydrate(model: nil, view: nil, user: nil, params: nil)
|
@@ -215,7 +221,7 @@ module Avo
|
|
215
221
|
when :edit
|
216
222
|
model_title
|
217
223
|
when :new
|
218
|
-
|
224
|
+
t("avo.create_new_item", item: name.downcase).upcase_first
|
219
225
|
end
|
220
226
|
end
|
221
227
|
|
@@ -244,9 +250,18 @@ module Avo
|
|
244
250
|
class_name_without_resource.safe_constantize
|
245
251
|
end
|
246
252
|
|
253
|
+
def model_id
|
254
|
+
@model.send id
|
255
|
+
end
|
256
|
+
|
247
257
|
def model_title
|
248
|
-
return
|
258
|
+
return name if @model.nil?
|
249
259
|
|
260
|
+
the_title = @model.send title
|
261
|
+
return the_title if the_title.present?
|
262
|
+
|
263
|
+
model_id
|
264
|
+
rescue
|
250
265
|
name
|
251
266
|
end
|
252
267
|
|
@@ -267,11 +282,13 @@ module Avo
|
|
267
282
|
end
|
268
283
|
|
269
284
|
def name
|
285
|
+
default = class_name_without_resource.titlecase
|
286
|
+
|
270
287
|
return @name if @name.present?
|
271
288
|
|
272
|
-
return
|
289
|
+
return t(translation_key, count: 1, default: default).capitalize if translation_key
|
273
290
|
|
274
|
-
|
291
|
+
default
|
275
292
|
end
|
276
293
|
|
277
294
|
def singular_name
|
@@ -279,9 +296,11 @@ module Avo
|
|
279
296
|
end
|
280
297
|
|
281
298
|
def plural_name
|
282
|
-
|
299
|
+
default = name.pluralize
|
300
|
+
|
301
|
+
return t(translation_key, count: 2, default: default).capitalize if translation_key
|
283
302
|
|
284
|
-
|
303
|
+
default
|
285
304
|
end
|
286
305
|
|
287
306
|
def underscore_name
|
data/lib/avo/configuration.rb
CHANGED
@@ -28,6 +28,7 @@ module Avo
|
|
28
28
|
attr_accessor :current_user_resource_name
|
29
29
|
attr_accessor :raise_error_on_missing_policy
|
30
30
|
attr_accessor :disabled_features
|
31
|
+
attr_accessor :buttons_on_form_footers
|
31
32
|
|
32
33
|
def initialize
|
33
34
|
@root_path = "/avo"
|
@@ -68,6 +69,7 @@ module Avo
|
|
68
69
|
@current_user_resource_name = "user"
|
69
70
|
@raise_error_on_missing_policy = false
|
70
71
|
@disabled_features = []
|
72
|
+
@buttons_on_form_footers = false
|
71
73
|
end
|
72
74
|
|
73
75
|
def locale_tag
|
@@ -8,6 +8,7 @@ module Avo
|
|
8
8
|
class_attribute :description
|
9
9
|
class_attribute :items_holder
|
10
10
|
class_attribute :grid_cols, default: 3
|
11
|
+
class_attribute :visible, default: true
|
11
12
|
|
12
13
|
class << self
|
13
14
|
def card(klass)
|
@@ -48,6 +49,22 @@ module Avo
|
|
48
49
|
def navigation_path
|
49
50
|
"#{Avo::App.root_path}/dashboards/#{id}"
|
50
51
|
end
|
52
|
+
|
53
|
+
def is_visible?
|
54
|
+
# Default is true
|
55
|
+
return true if visible == true
|
56
|
+
|
57
|
+
# Hide if false
|
58
|
+
return false if visible == false
|
59
|
+
|
60
|
+
if visible.respond_to? :call
|
61
|
+
::Avo::Hosts::DashboardVisibility.new(block: visible, dashboard: self).handle
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def is_hidden?
|
66
|
+
!is_visible?
|
67
|
+
end
|
51
68
|
end
|
52
69
|
end
|
53
70
|
end
|
@@ -10,6 +10,7 @@ module Avo
|
|
10
10
|
delegate :view_context, to: "Avo::App"
|
11
11
|
delegate :main_app, to: :view_context
|
12
12
|
delegate :avo, to: :view_context
|
13
|
+
delegate :t, to: ::I18n
|
13
14
|
|
14
15
|
attr_reader :id
|
15
16
|
attr_reader :block
|
@@ -48,7 +49,7 @@ module Avo
|
|
48
49
|
@id = id
|
49
50
|
@name = args[:name]
|
50
51
|
@translation_key = args[:translation_key]
|
51
|
-
@translation_enabled =
|
52
|
+
@translation_enabled = ::Avo::App.translation_enabled
|
52
53
|
@block = block
|
53
54
|
@required = args[:required] || false
|
54
55
|
@readonly = args[:readonly] || false
|
@@ -94,18 +95,26 @@ module Avo
|
|
94
95
|
@translation_key
|
95
96
|
end
|
96
97
|
|
98
|
+
# Getting the name of the resource (user/users, post/posts)
|
99
|
+
# We'll first check to see if the user passed a name
|
100
|
+
# Secondly we'll try to find a translation key
|
101
|
+
# We'll fallback to humanizing the id
|
97
102
|
def name
|
103
|
+
default = @id.to_s.humanize(keep_id_suffix: true)
|
104
|
+
|
98
105
|
return @name if @name.present?
|
99
106
|
|
100
|
-
return
|
107
|
+
return t(translation_key, count: 1, default: default).capitalize if @translation_key
|
101
108
|
|
102
|
-
|
109
|
+
default
|
103
110
|
end
|
104
111
|
|
105
112
|
def plural_name
|
106
|
-
|
113
|
+
default = name.pluralize
|
114
|
+
|
115
|
+
return t(translation_key, count: 2, default: default).capitalize if @translation_key
|
107
116
|
|
108
|
-
|
117
|
+
default
|
109
118
|
end
|
110
119
|
|
111
120
|
def placeholder
|
@@ -181,8 +190,12 @@ module Avo
|
|
181
190
|
"#{type.camelize}Field"
|
182
191
|
end
|
183
192
|
|
193
|
+
# Try and build the component class or fallback to a blank one
|
184
194
|
def component_for_view(view = :index)
|
185
|
-
"Avo::Fields::#{view_component_name}::#{view.to_s.camelize}Component"
|
195
|
+
component_class = "::Avo::Fields::#{view_component_name}::#{view.to_s.camelize}Component"
|
196
|
+
component_class.constantize
|
197
|
+
rescue
|
198
|
+
::Avo::BlankFieldComponent
|
186
199
|
end
|
187
200
|
|
188
201
|
def model_errors
|
@@ -11,8 +11,8 @@ module Avo
|
|
11
11
|
|
12
12
|
@link_to_resource = args[:link_to_resource].present? ? args[:link_to_resource] : false
|
13
13
|
|
14
|
-
@width = args[:width].present? ? args[:width] :
|
15
|
-
@height = args[:height].present? ? args[:height] :
|
14
|
+
@width = args[:width].present? ? args[:width] : 40
|
15
|
+
@height = args[:height].present? ? args[:height] : 40
|
16
16
|
@radius = args[:radius].present? ? args[:radius] : 0
|
17
17
|
end
|
18
18
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "dry-initializer"
|
2
|
+
|
3
|
+
module Avo
|
4
|
+
module Hosts
|
5
|
+
class DashboardVisibility
|
6
|
+
extend Dry::Initializer
|
7
|
+
|
8
|
+
option :block, default: proc { proc {} }
|
9
|
+
option :current_user, default: proc { ::Avo::App.current_user }
|
10
|
+
option :context, default: proc { ::Avo::App.context }
|
11
|
+
option :dashboard
|
12
|
+
option :params, default: proc { ::Avo::App.params }
|
13
|
+
|
14
|
+
def handle
|
15
|
+
instance_exec(&block)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/avo/version.rb
CHANGED
@@ -3,7 +3,10 @@ class <%= class_name.camelize %> < Avo::Dashboards::BaseDashboard
|
|
3
3
|
self.name = "<%= name.underscore.humanize %>"
|
4
4
|
# self.description = "Tiny dashboard description"
|
5
5
|
# self.grid_cols = 3
|
6
|
+
# self.visible = -> do
|
7
|
+
# true
|
8
|
+
# end
|
6
9
|
|
7
10
|
# cards go here
|
8
|
-
# card
|
11
|
+
# card UsersCount
|
9
12
|
end
|
data/public/avo-assets/avo.css
CHANGED
@@ -6220,10 +6220,6 @@ progress[value]::-moz-progress-bar{
|
|
6220
6220
|
left:0px
|
6221
6221
|
}
|
6222
6222
|
|
6223
|
-
.bottom-0{
|
6224
|
-
bottom:0px
|
6225
|
-
}
|
6226
|
-
|
6227
6223
|
.left-1\/2{
|
6228
6224
|
left:50%
|
6229
6225
|
}
|
@@ -6232,6 +6228,10 @@ progress[value]::-moz-progress-bar{
|
|
6232
6228
|
top:50%
|
6233
6229
|
}
|
6234
6230
|
|
6231
|
+
.bottom-0{
|
6232
|
+
bottom:0px
|
6233
|
+
}
|
6234
|
+
|
6235
6235
|
.left-auto{
|
6236
6236
|
left:auto
|
6237
6237
|
}
|
@@ -6377,14 +6377,6 @@ progress[value]::-moz-progress-bar{
|
|
6377
6377
|
margin-top:0.25rem
|
6378
6378
|
}
|
6379
6379
|
|
6380
|
-
.mb-4{
|
6381
|
-
margin-bottom:1rem
|
6382
|
-
}
|
6383
|
-
|
6384
|
-
.mr-1{
|
6385
|
-
margin-right:0.25rem
|
6386
|
-
}
|
6387
|
-
|
6388
6380
|
.-ml-20{
|
6389
6381
|
margin-left:-5rem
|
6390
6382
|
}
|
@@ -6413,6 +6405,14 @@ progress[value]::-moz-progress-bar{
|
|
6413
6405
|
margin-top:-2.5rem
|
6414
6406
|
}
|
6415
6407
|
|
6408
|
+
.mb-4{
|
6409
|
+
margin-bottom:1rem
|
6410
|
+
}
|
6411
|
+
|
6412
|
+
.mr-1{
|
6413
|
+
margin-right:0.25rem
|
6414
|
+
}
|
6415
|
+
|
6416
6416
|
.mr-4{
|
6417
6417
|
margin-right:1rem
|
6418
6418
|
}
|
@@ -6437,6 +6437,10 @@ progress[value]::-moz-progress-bar{
|
|
6437
6437
|
margin-bottom:0.5rem
|
6438
6438
|
}
|
6439
6439
|
|
6440
|
+
.mt-6{
|
6441
|
+
margin-top:1.5rem
|
6442
|
+
}
|
6443
|
+
|
6440
6444
|
.mt-3{
|
6441
6445
|
margin-top:0.75rem
|
6442
6446
|
}
|
@@ -6545,10 +6549,6 @@ progress[value]::-moz-progress-bar{
|
|
6545
6549
|
height:100%
|
6546
6550
|
}
|
6547
6551
|
|
6548
|
-
.h-6{
|
6549
|
-
height:1.5rem
|
6550
|
-
}
|
6551
|
-
|
6552
6552
|
.h-40{
|
6553
6553
|
height:10rem
|
6554
6554
|
}
|
@@ -6561,6 +6561,10 @@ progress[value]::-moz-progress-bar{
|
|
6561
6561
|
height:2rem
|
6562
6562
|
}
|
6563
6563
|
|
6564
|
+
.h-6{
|
6565
|
+
height:1.5rem
|
6566
|
+
}
|
6567
|
+
|
6564
6568
|
.h-\[250px\]{
|
6565
6569
|
height:250px
|
6566
6570
|
}
|
@@ -6991,6 +6995,10 @@ progress[value]::-moz-progress-bar{
|
|
6991
6995
|
border-width:1px
|
6992
6996
|
}
|
6993
6997
|
|
6998
|
+
.border-b-2{
|
6999
|
+
border-bottom-width:2px
|
7000
|
+
}
|
7001
|
+
|
6994
7002
|
.border-b{
|
6995
7003
|
border-bottom-width:1px
|
6996
7004
|
}
|
@@ -7007,6 +7015,10 @@ progress[value]::-moz-progress-bar{
|
|
7007
7015
|
border-left-width:1px
|
7008
7016
|
}
|
7009
7017
|
|
7018
|
+
.border-dashed{
|
7019
|
+
border-style:dashed
|
7020
|
+
}
|
7021
|
+
|
7010
7022
|
.border-slate-500{
|
7011
7023
|
--tw-border-opacity:1;
|
7012
7024
|
border-color:rgb(100 116 139 / var(--tw-border-opacity))
|
@@ -7314,6 +7326,11 @@ progress[value]::-moz-progress-bar{
|
|
7314
7326
|
padding-right:0px
|
7315
7327
|
}
|
7316
7328
|
|
7329
|
+
.py-12{
|
7330
|
+
padding-top:3rem;
|
7331
|
+
padding-bottom:3rem
|
7332
|
+
}
|
7333
|
+
|
7317
7334
|
.py-6{
|
7318
7335
|
padding-top:1.5rem;
|
7319
7336
|
padding-bottom:1.5rem
|
@@ -7324,11 +7341,6 @@ progress[value]::-moz-progress-bar{
|
|
7324
7341
|
padding-right:1.5rem
|
7325
7342
|
}
|
7326
7343
|
|
7327
|
-
.py-12{
|
7328
|
-
padding-top:3rem;
|
7329
|
-
padding-bottom:3rem
|
7330
|
-
}
|
7331
|
-
|
7332
7344
|
.py-0\.5{
|
7333
7345
|
padding-top:0.125rem;
|
7334
7346
|
padding-bottom:0.125rem
|
@@ -8712,6 +8724,10 @@ trix-editor {
|
|
8712
8724
|
}
|
8713
8725
|
|
8714
8726
|
@media (min-width: 1280px){
|
8727
|
+
.xl\:right-0{
|
8728
|
+
right:0px
|
8729
|
+
}
|
8730
|
+
|
8715
8731
|
.xl\:mt-0{
|
8716
8732
|
margin-top:0px
|
8717
8733
|
}
|