avo 2.5.2.pre.4 → 2.5.2.pre.7

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.

Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +4 -1
  4. data/app/assets/builds/avo.css +764 -166
  5. data/app/assets/builds/avo.js +212 -123
  6. data/app/assets/builds/avo.js.map +3 -3
  7. data/app/assets/stylesheets/avo.css +3 -33
  8. data/app/assets/stylesheets/css/alerts.css +35 -0
  9. data/app/assets/stylesheets/css/search.css +1 -1
  10. data/app/assets/stylesheets/css/tags.css +16 -0
  11. data/app/assets/svgs/heroicons/solid/user-remove.svg +1 -1
  12. data/app/components/avo/actions_component.html.erb +1 -2
  13. data/app/components/avo/alert_component.html.erb +1 -1
  14. data/app/components/avo/alert_component.rb +5 -24
  15. data/app/components/avo/button_component.rb +0 -2
  16. data/app/components/avo/fields/tags_field/edit_component.html.erb +27 -0
  17. data/app/components/avo/fields/tags_field/edit_component.rb +4 -0
  18. data/app/components/avo/fields/tags_field/index_component.html.erb +14 -0
  19. data/app/components/avo/fields/tags_field/index_component.rb +7 -0
  20. data/app/components/avo/fields/tags_field/show_component.html.erb +7 -0
  21. data/app/components/avo/fields/tags_field/show_component.rb +11 -0
  22. data/app/components/avo/fields/tags_field/tag_component.html.erb +9 -0
  23. data/app/components/avo/fields/tags_field/tag_component.rb +11 -0
  24. data/app/components/avo/filters_component.html.erb +1 -1
  25. data/app/components/avo/index/field_wrapper_component.html.erb +1 -1
  26. data/app/components/avo/index/grid_cover_empty_state_component.html.erb +1 -1
  27. data/app/components/avo/index/resource_table_component.html.erb +1 -1
  28. data/app/components/avo/panel_component.html.erb +3 -3
  29. data/app/components/avo/panel_component.rb +1 -1
  30. data/app/components/avo/resource_component.rb +0 -50
  31. data/app/components/avo/sidebar/heading_component.html.erb +1 -1
  32. data/app/components/avo/sidebar/link_component.rb +1 -1
  33. data/app/components/avo/sidebar_component.html.erb +13 -5
  34. data/app/components/avo/sidebar_profile_component.html.erb +1 -1
  35. data/app/components/avo/views/resource_edit_component.html.erb +3 -28
  36. data/app/components/avo/views/resource_edit_component.rb +6 -4
  37. data/app/components/avo/views/resource_index_component.html.erb +7 -15
  38. data/app/components/avo/views/resource_new_component.html.erb +2 -8
  39. data/app/components/avo/views/resource_show_component.html.erb +5 -15
  40. data/app/components/avo/views/resource_show_component.rb +45 -0
  41. data/app/controllers/avo/actions_controller.rb +8 -23
  42. data/app/controllers/avo/associations_controller.rb +3 -3
  43. data/app/controllers/avo/base_controller.rb +16 -25
  44. data/app/controllers/avo/search_controller.rb +2 -2
  45. data/app/helpers/avo/application_helper.rb +1 -1
  46. data/app/javascript/js/application.js +1 -1
  47. data/app/javascript/js/controllers/alerts_controller.js +26 -0
  48. data/app/javascript/js/controllers/base_controller.js +22 -0
  49. data/app/javascript/js/controllers/fields/key_value_controller.js +1 -1
  50. data/app/javascript/js/controllers/fields/tags_field_controller.js +86 -0
  51. data/app/javascript/js/controllers/fields/tags_field_helpers.js +47 -0
  52. data/app/javascript/js/controllers/filter_controller.js +1 -4
  53. data/app/javascript/js/controllers.js +4 -0
  54. data/app/views/avo/actions/show.html.erb +2 -5
  55. data/app/views/avo/partials/_logo.html.erb +1 -1
  56. data/app/views/avo/partials/_navbar.html.erb +6 -12
  57. data/app/views/avo/private/_links_and_buttons.html.erb +1 -1
  58. data/app/views/layouts/avo/application.html.erb +53 -50
  59. data/db/factories.rb +2 -0
  60. data/lib/avo/base_action.rb +6 -24
  61. data/lib/avo/base_resource.rb +6 -0
  62. data/lib/avo/concerns/handles_field_args.rb +36 -0
  63. data/lib/avo/engine.rb +1 -1
  64. data/lib/avo/fields/base_field.rb +2 -1
  65. data/lib/avo/fields/belongs_to_field.rb +4 -4
  66. data/lib/avo/fields/has_and_belongs_to_many_field.rb +2 -2
  67. data/lib/avo/fields/has_base_field.rb +0 -2
  68. data/lib/avo/fields/has_many_field.rb +2 -2
  69. data/lib/avo/fields/has_one_field.rb +2 -2
  70. data/lib/avo/fields/tags_field.rb +82 -0
  71. data/lib/avo/hosts/record_host.rb +7 -0
  72. data/lib/avo/licensing/pro_license.rb +2 -1
  73. data/lib/avo/version.rb +1 -1
  74. data/lib/generators/avo/templates/locales/avo.en.yml +4 -0
  75. data/public/avo-assets/avo.css +812 -214
  76. data/public/avo-assets/avo.js +212 -123
  77. data/public/avo-assets/avo.js.map +3 -3
  78. metadata +19 -2
@@ -1,57 +1,60 @@
1
1
  <!DOCTYPE html>
2
2
  <html>
3
- <head>
4
- <meta name="viewport" content="width=device-width, initial-scale=1">
5
- <%= display_meta_tags site: Avo.configuration.app_name, reverse: true, separator: "—" %>
6
- <%= csrf_meta_tags %>
7
- <%= csp_meta_tag %>
8
- <%= render partial: 'avo/partials/javascript' %>
9
- <%= render partial: 'avo/partials/head' %>
10
- <% if Avo::PACKED %>
11
- <%= javascript_include_tag "/avo-assets/avo", "data-turbo-track": "reload", defer: true %>
12
- <%= stylesheet_link_tag "/avo-assets/avo", "data-turbo-track": "reload", defer: true %>
13
- <% else %>
14
- <%= javascript_include_tag "avo", "data-turbo-track": "reload", defer: true %>
15
- <%= stylesheet_link_tag "avo", "data-turbo-track": "reload", defer: true %>
16
- <% if Rails.env.development? %>
17
- <%= javascript_include_tag "hotwire-livereload", defer: true %>
18
- <% end %>
3
+ <head>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1">
5
+ <%= display_meta_tags site: Avo.configuration.app_name, reverse: true, separator: "—" %>
6
+
7
+ <%= csrf_meta_tags %>
8
+ <%= csp_meta_tag %>
9
+
10
+ <%= render partial: 'avo/partials/javascript' %>
11
+ <%= render partial: 'avo/partials/head' %>
12
+
13
+ <% if Avo::PACKED %>
14
+ <%= javascript_include_tag "/avo-assets/avo", "data-turbo-track": "reload", defer: true %>
15
+ <%= stylesheet_link_tag "/avo-assets/avo", "data-turbo-track": "reload", defer: true %>
16
+ <% else %>
17
+ <%= javascript_include_tag "avo", "data-turbo-track": "reload", defer: true %>
18
+ <%= stylesheet_link_tag "avo", "data-turbo-track": "reload", defer: true %>
19
+ <% if Rails.env.development? %>
20
+ <%= javascript_include_tag "hotwire-livereload", defer: true %>
19
21
  <% end %>
20
- </head>
21
- <body class="bg-gray-25 os-mac">
22
- <div class="relative flex flex-1 w-full min-h-full" data-controller="mobile">
23
- <div class="flex-1 flex flex-col max-w-full">
24
- <%= render partial: "avo/partials/navbar" %>
25
- <div class="flex-1 flex pt-16 relative">
26
- <%= render Avo::SidebarComponent.new %>
27
- <div class="lg:pl-64 flex-1 flex flex-col min-h-full max-w-full">
28
- <div class="content py-4 lg:py-8 px-4 lg:px-8 flex-1 flex flex-col justify-between items-stretch <%= @container_classes %>">
29
- <%= render partial: "avo/partials/custom_tools_alert" if @custom_tools_alert_visible %>
30
- <div class="flex flex-1 flex-col justify-between items-stretch space-y-8">
31
- <%= yield %>
32
- <%= render partial: "avo/partials/footer" %>
33
- </div>
34
- </div>
35
- </div>
36
- </div>
22
+ <% end %>
23
+ </head>
24
+ <body class="bg-application os-mac">
25
+ <div class="relative flex flex-1 w-full min-h-full" data-controller="mobile">
26
+ <%= render Avo::SidebarComponent.new %>
27
+
28
+ <div class="lg:pl-64 flex-1 flex flex-col min-h-full max-w-full">
29
+ <%= render partial: "avo/partials/navbar" %>
30
+
31
+ <div class="content py-4 lg:py-8 px-4 lg:px-8 flex-1 flex flex-col justify-between items-stretch <%= @container_classes %>">
32
+ <%= render partial: "avo/partials/custom_tools_alert" if @custom_tools_alert_visible %>
33
+
34
+ <div class="flex flex-1 flex-col justify-between items-stretch space-y-8">
35
+ <%= yield %>
36
+ <%= render partial: "avo/partials/footer" %>
37
37
  </div>
38
38
  </div>
39
- <%= turbo_frame_tag 'actions_show' %>
40
- <%= turbo_frame_tag 'attach_modal' %>
41
- <%= turbo_frame_tag 'destroy_attachment_form' %>
42
- <%= turbo_frame_tag 'alerts', class: "fixed inset-0 bottom-0 flex flex-col space-y-4 items-end justify-right px-4 py-6 sm:p-6 justify-end z-50 pointer-events-none" do %>
43
- <%= render Avo::FlashAlertsComponent.new flashes: flash %>
44
- <% # In case we have other general error messages %>
45
- <% if @errors.present? %>
46
- <% @errors.each do |message| %>
47
- <%= render Avo::AlertComponent.new :error, message %>
48
- <% end %>
49
- <% end %>
39
+ </div>
40
+ </div>
41
+
42
+ <%= turbo_frame_tag 'actions_show' %>
43
+ <%= turbo_frame_tag 'attach_modal' %>
44
+ <%= turbo_frame_tag 'destroy_attachment_form' %>
45
+
46
+ <%= turbo_frame_tag 'alerts', class: "fixed inset-0 bottom-0 flex flex-col space-y-4 items-end justify-right px-4 py-6 sm:p-6 justify-end z-50 pointer-events-none" do %>
47
+ <%= render Avo::FlashAlertsComponent.new flashes: flash %>
48
+
49
+ <% # In case we have other general error messages %>
50
+ <% if @errors.present? %>
51
+ <% @errors.each do |message| %>
52
+ <%= render Avo::AlertComponent.new :error, message %>
50
53
  <% end %>
51
- <%= render partial: "avo/partials/scripts" %>
52
- <!-- Avo version: <%= Avo::VERSION %> -->
53
- <!-- Environment: <%= Rails.env %> -->
54
- <!-- License ID: <%= Avo::App.license.id %> -->
55
- <!-- License valid?: <%= Avo::App.license.valid ? "valid" : "invalid" %> -->
56
- </body>
54
+ <% end %>
55
+ <% end %>
56
+
57
+ <%= render partial: "avo/partials/scripts" %>
58
+ <!-- Avo version: <%= Avo::VERSION %> -->
59
+ </body>
57
60
  </html>
data/db/factories.rb CHANGED
@@ -25,6 +25,7 @@ FactoryBot.define do
25
25
  Time.now - rand(10...365).days
26
26
  end
27
27
  end
28
+ tag_list { ["1", "2", "five", "seven"].shuffle }
28
29
  status { ::Post.statuses.keys.sample }
29
30
  end
30
31
 
@@ -64,6 +65,7 @@ FactoryBot.define do
64
65
 
65
66
  factory :course do
66
67
  name { Faker::Educator.unique.course_name }
68
+ skills { [Faker::Educator.subject, Faker::Educator.subject, Faker::Educator.subject, Faker::Educator.subject, Faker::Educator.subject] }
67
69
  country { Course.countries.sample }
68
70
  city { Course.cities.stringify_keys[country].sample }
69
71
  end
@@ -61,7 +61,8 @@ module Avo
61
61
  self.class.cancel_button_label ||= I18n.t("avo.cancel")
62
62
 
63
63
  @response ||= {}
64
- @response[:messages] = []
64
+ @response[:message_type] ||= :notice
65
+ @response[:message] ||= I18n.t("avo.action_ran_successfully")
65
66
  end
66
67
 
67
68
  def context
@@ -130,25 +131,15 @@ module Avo
130
131
  end
131
132
 
132
133
  def succeed(text)
133
- add_message text, :success
134
+ response[:message_type] = :notice
135
+ response[:message] = text
134
136
 
135
137
  self
136
138
  end
137
139
 
138
140
  def fail(text)
139
- add_message text, :error
140
-
141
- self
142
- end
143
-
144
- def inform(text)
145
- add_message text, :info
146
-
147
- self
148
- end
149
-
150
- def warn(text)
151
- add_message text, :warning
141
+ response[:message_type] = :alert
142
+ response[:message] = text
152
143
 
153
144
  self
154
145
  end
@@ -177,14 +168,5 @@ module Avo
177
168
 
178
169
  self
179
170
  end
180
-
181
- private
182
-
183
- def add_message(body, type = :info)
184
- response[:messages] << {
185
- type: type,
186
- body: body
187
- }
188
- end
189
171
  end
190
172
  end
@@ -136,6 +136,12 @@ module Avo
136
136
  end
137
137
  end
138
138
 
139
+ if Avo::App.license.lacks_with_trial(:advanced_fields)
140
+ fields = fields.reject do |field|
141
+ field.type == 'tags'
142
+ end
143
+ end
144
+
139
145
  fields
140
146
  end
141
147
 
@@ -0,0 +1,36 @@
1
+ module Avo
2
+ module Concerns
3
+ module HandlesFieldArgs
4
+ extend ActiveSupport::Concern
5
+
6
+ private
7
+
8
+ # Add an instance variable from args
9
+ # That may be a string, boolean, or array
10
+ # Each args should also have a default value
11
+ def add_prop_from_args(args = {}, name: nil, type: :string, default: nil)
12
+ value = default
13
+
14
+ if type == :boolean
15
+ value = args[name.to_sym] == true
16
+ else
17
+ value = args[name.to_sym] unless args.dig(name.to_sym).nil?
18
+ end
19
+
20
+ instance_variable_set(:"@#{name}", value)
21
+ end
22
+
23
+ def add_boolean_prop(args, name, default = false)
24
+ add_prop_from_args args, name: name, default: default, type: :boolean
25
+ end
26
+
27
+ def add_array_prop(args, name, default = [])
28
+ add_prop_from_args args, name: name, default: default, type: :array
29
+ end
30
+
31
+ def add_string_prop(args, name, default = [])
32
+ add_prop_from_args args, name: name, default: default, type: :string
33
+ end
34
+ end
35
+ end
36
+ end
data/lib/avo/engine.rb CHANGED
@@ -31,7 +31,7 @@ module Avo
31
31
  path = Rails.root.join(*path_params)
32
32
 
33
33
  if File.directory? path.to_s
34
- Rails.autoloaders.main.push_dir path.to_s
34
+ Rails.autoloaders.main.push_dir path
35
35
  end
36
36
  end
37
37
  end
@@ -4,8 +4,9 @@ module Avo
4
4
  extend ActiveSupport::DescendantsTracker
5
5
  extend Avo::Fields::FieldExtensions::HasFieldName
6
6
 
7
- include ActionView::Helpers::UrlHelper
8
7
  include Avo::Fields::FieldExtensions::VisibleInDifferentViews
8
+ include Avo::Concerns::HandlesFieldArgs
9
+ include ActionView::Helpers::UrlHelper
9
10
 
10
11
  delegate :view_context, to: "Avo::App"
11
12
  delegate :main_app, to: :view_context
@@ -62,7 +62,7 @@ module Avo
62
62
  attr_reader :relation_method
63
63
  attr_reader :types # for Polymorphic associations
64
64
  attr_reader :allow_via_detaching
65
- attr_reader :attach_scope
65
+ attr_reader :scope
66
66
  attr_reader :polymorphic_help
67
67
 
68
68
  def initialize(id, **args, &block)
@@ -75,7 +75,7 @@ module Avo
75
75
  @types = args[:types]
76
76
  @relation_method = id.to_s.parameterize.underscore
77
77
  @allow_via_detaching = args[:allow_via_detaching] == true
78
- @attach_scope = args[:attach_scope]
78
+ @scope = args[:scope]
79
79
  @polymorphic_help = args[:polymorphic_help]
80
80
  end
81
81
 
@@ -117,8 +117,8 @@ module Avo
117
117
 
118
118
  query = Avo::Services::AuthorizationService.apply_policy(user, resource.class.query_scope)
119
119
 
120
- if attach_scope.present?
121
- query = Avo::Hosts::AssociationScopeHost.new(block: attach_scope, query: query, parent: get_model).handle
120
+ if scope.present?
121
+ query = Avo::Hosts::AssociationScopeHost.new(block: scope, query: query, parent: get_model).handle
122
122
  end
123
123
 
124
124
  query.all.map do |model|
@@ -4,10 +4,10 @@ module Avo
4
4
  def initialize(id, **args, &block)
5
5
  args[:updatable] = false
6
6
 
7
+ super(id, **args, &block)
8
+
7
9
  hide_on :all
8
10
  show_on :show
9
-
10
- super(id, **args, &block)
11
11
  end
12
12
 
13
13
  def view_component_name
@@ -3,14 +3,12 @@ module Avo
3
3
  class HasBaseField < BaseField
4
4
  attr_accessor :display
5
5
  attr_accessor :scope
6
- attr_accessor :attach_scope
7
6
  attr_accessor :description
8
7
 
9
8
  def initialize(id, **args, &block)
10
9
  super(id, **args, &block)
11
10
 
12
11
  @scope = args[:scope].present? ? args[:scope] : nil
13
- @attach_scope = args[:attach_scope].present? ? args[:attach_scope] : nil
14
12
  @display = args[:display].present? ? args[:display] : :show
15
13
  @searchable = args[:searchable] == true
16
14
  @description = args[:description]
@@ -4,10 +4,10 @@ module Avo
4
4
  def initialize(id, **args, &block)
5
5
  args[:updatable] = false
6
6
 
7
+ super(id, **args, &block)
8
+
7
9
  hide_on :all
8
10
  show_on :show
9
-
10
- super(id, **args, &block)
11
11
  end
12
12
  end
13
13
  end
@@ -4,10 +4,10 @@ module Avo
4
4
  attr_accessor :relation_method
5
5
 
6
6
  def initialize(id, **args, &block)
7
- hide_on :new, :edit
8
-
9
7
  super(id, **args, &block)
10
8
 
9
+ hide_on :new, :edit
10
+
11
11
  @placeholder ||= I18n.t "avo.choose_an_option"
12
12
 
13
13
  @relation_method = name.to_s.parameterize.underscore
@@ -0,0 +1,82 @@
1
+ module Avo
2
+ module Fields
3
+ class TagsField < BaseField
4
+ attr_reader :acts_as_taggable_on
5
+ attr_reader :close_on_select
6
+ attr_reader :delimiters
7
+ attr_reader :enforce_suggestions
8
+
9
+ def initialize(id, **args, &block)
10
+ super(id, **args, &block)
11
+
12
+ add_boolean_prop args, :close_on_select
13
+ add_boolean_prop args, :enforce_suggestions
14
+ add_string_prop args, :acts_as_taggable_on
15
+ add_array_prop args, :blacklist
16
+ add_array_prop args, :delimiters, [","]
17
+ add_array_prop args, :suggestions
18
+ end
19
+
20
+ def field_value
21
+ return json_value if acts_as_taggable_on.present?
22
+
23
+ value || []
24
+ end
25
+
26
+ def json_value
27
+ value.map do |item|
28
+ {
29
+ value: item.name
30
+ }
31
+ end.as_json
32
+ end
33
+
34
+ def fill_field(model, key, value, params)
35
+ if acts_as_taggable_on.present?
36
+ model.send(act_as_taggable_attribute(key), parsed_value(value))
37
+ else
38
+ model.send("#{key}=", parsed_value(value))
39
+ end
40
+
41
+ model
42
+ end
43
+
44
+ def suggestions
45
+ return @suggestions if @suggestions.is_a? Array
46
+
47
+ if @suggestions.respond_to? :call
48
+ return Avo::Hosts::RecordHost.new(block: @suggestions, record: model).handle
49
+ end
50
+
51
+ []
52
+ end
53
+
54
+ def blacklist
55
+ return @blacklist if @blacklist.is_a? Array
56
+
57
+ if @blacklist.respond_to? :call
58
+ return Avo::Hosts::RecordHost.new(block: @blacklist, record: model).handle
59
+ end
60
+
61
+ []
62
+ end
63
+
64
+ private
65
+
66
+ def act_as_taggable_attribute(key)
67
+ "#{key.singularize}_list="
68
+ end
69
+
70
+ def parsed_value(value)
71
+ JSON.parse(value).pluck("value")
72
+ rescue
73
+ []
74
+ end
75
+
76
+ private
77
+
78
+ def parse_suggestions_from_args(args)
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,7 @@
1
+ module Avo
2
+ module Hosts
3
+ class RecordHost < BaseHost
4
+ option :record
5
+ end
6
+ end
7
+ end
@@ -12,7 +12,8 @@ module Avo
12
12
  :searchable_associations,
13
13
  :resource_ordering,
14
14
  :dashboards,
15
- :menu_editor
15
+ :menu_editor,
16
+ :advanced_fields
16
17
  ]
17
18
  end
18
19
  end
data/lib/avo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "2.5.2.pre.4" unless const_defined?(:VERSION)
2
+ VERSION = "2.5.2.pre.7" unless const_defined?(:VERSION)
3
3
  end
@@ -39,6 +39,10 @@ en:
39
39
  zero: 'no %{item}'
40
40
  one: 'one %{item}'
41
41
  other: '%{count} %{item}'
42
+ x_items_more:
43
+ zero: 'no more items'
44
+ one: 'one more item'
45
+ other: '%{count} more items'
42
46
  are_you_sure: 'Are you sure?'
43
47
  filters: 'Filters'
44
48
  per_page: 'Per page'