avo 2.9.1.pre7 → 2.10.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.

Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +5 -7
  3. data/README.md +4 -0
  4. data/app/assets/stylesheets/css/buttons.css +4 -1
  5. data/app/components/avo/base_component.rb +2 -0
  6. data/app/components/avo/button_component.rb +3 -1
  7. data/app/components/avo/fields/edit_component.rb +5 -0
  8. data/app/components/avo/fields/show_component.rb +1 -1
  9. data/app/components/avo/index/ordering/button_component.rb +3 -5
  10. data/app/components/avo/index/resource_table_component.html.erb +1 -1
  11. data/app/components/avo/index/table_row_component.html.erb +1 -1
  12. data/app/components/avo/item_switcher_component.html.erb +19 -0
  13. data/app/components/avo/item_switcher_component.rb +45 -0
  14. data/app/components/avo/panel_component.html.erb +23 -24
  15. data/app/components/avo/panel_component.rb +8 -5
  16. data/app/components/avo/tab_group_component.html.erb +53 -0
  17. data/app/components/avo/tab_group_component.rb +51 -0
  18. data/app/components/avo/tab_switcher_component.html.erb +21 -0
  19. data/app/components/avo/tab_switcher_component.rb +86 -0
  20. data/app/components/avo/views/resource_edit_component.html.erb +34 -56
  21. data/app/components/avo/views/resource_edit_component.rb +10 -0
  22. data/app/components/avo/views/resource_index_component.html.erb +1 -1
  23. data/app/components/avo/views/resource_index_component.rb +1 -1
  24. data/app/components/avo/views/resource_show_component.html.erb +58 -89
  25. data/app/components/avo/views/resource_show_component.rb +2 -2
  26. data/app/controllers/avo/actions_controller.rb +1 -1
  27. data/app/controllers/avo/application_controller.rb +6 -10
  28. data/app/helpers/avo/application_helper.rb +0 -6
  29. data/app/helpers/avo/url_helpers.rb +1 -1
  30. data/app/javascript/js/controllers/loading_button_controller.js +25 -21
  31. data/app/javascript/js/controllers/tabs_controller.js +9 -3
  32. data/app/javascript/js/controllers.js +2 -0
  33. data/app/views/avo/base/index.html.erb +1 -1
  34. data/app/views/avo/base/show.html.erb +1 -1
  35. data/app/views/avo/cards/show.html.erb +1 -1
  36. data/app/views/avo/debug/index.html.erb +1 -1
  37. data/app/views/avo/home/_actions.html.erb +1 -1
  38. data/app/views/avo/home/_dashboards.html.erb +19 -0
  39. data/app/views/avo/home/_filters.html.erb +1 -1
  40. data/app/views/avo/home/_resources.html.erb +1 -1
  41. data/app/views/avo/home/failed_to_load.html.erb +1 -1
  42. data/app/views/avo/home/index.html.erb +14 -2
  43. data/app/views/avo/partials/_tabs_toggle.html.erb +20 -0
  44. data/app/views/avo/private/design.html.erb +1 -1
  45. data/lib/avo/base_action.rb +2 -19
  46. data/lib/avo/base_resource.rb +0 -94
  47. data/lib/avo/base_resource_tool.rb +3 -1
  48. data/lib/avo/concerns/has_fields.rb +247 -50
  49. data/lib/avo/concerns/has_html_attributes.rb +1 -1
  50. data/lib/avo/concerns/is_resource_item.rb +36 -0
  51. data/lib/avo/dsl/field_parser.rb +83 -0
  52. data/lib/avo/fields/base_field.rb +19 -2
  53. data/lib/avo/fields/field_extensions/visible_in_different_views.rb +18 -1
  54. data/lib/avo/fields/has_base_field.rb +18 -1
  55. data/lib/avo/grid_collector.rb +6 -3
  56. data/lib/avo/items_holder.rb +68 -0
  57. data/lib/avo/licensing/h_q.rb +10 -0
  58. data/lib/avo/main_panel.rb +3 -0
  59. data/lib/avo/menu/builder.rb +6 -6
  60. data/lib/avo/panel.rb +25 -0
  61. data/lib/avo/panel_builder.rb +23 -0
  62. data/lib/avo/tab.rb +78 -0
  63. data/lib/avo/tab_builder.rb +25 -0
  64. data/lib/avo/tab_group.rb +40 -0
  65. data/lib/avo/tab_group_builder.rb +43 -0
  66. data/lib/avo/version.rb +1 -1
  67. data/lib/generators/avo/templates/resource/controller.tt +2 -0
  68. data/lib/generators/avo/templates/resource_tools/partial.tt +1 -1
  69. data/lib/generators/avo/templates/tool/view.tt +1 -1
  70. data/public/avo-assets/avo.css +27 -3
  71. data/public/avo-assets/avo.js +73 -73
  72. data/public/avo-assets/avo.js.map +3 -3
  73. metadata +22 -5
  74. data/lib/avo/concerns/has_tools.rb +0 -47
@@ -0,0 +1,83 @@
1
+ module Avo
2
+ module Dsl
3
+ class FieldParser
4
+ attr_reader :as
5
+ attr_reader :args
6
+ attr_reader :id
7
+ attr_reader :block
8
+ attr_reader :instance
9
+ attr_reader :order_index
10
+
11
+ def initialize(id:, order_index: 0, **args, &block)
12
+ @id = id
13
+ @as = args.fetch(:as, nil)
14
+ @order_index = order_index
15
+ @args = args
16
+ @block = block
17
+ @instance = nil
18
+ end
19
+
20
+ def valid?
21
+ instance.present?
22
+ end
23
+
24
+ def invalid?
25
+ !valid?
26
+ end
27
+
28
+ def parse
29
+ # The field is passed as a symbol eg: :text, :color_picker, :trix
30
+ @instance = if as.is_a? Symbol
31
+ parse_from_symbol
32
+ elsif as.is_a? Class
33
+ parse_from_class
34
+ end
35
+
36
+ self
37
+ end
38
+
39
+ private
40
+
41
+ def parse_from_symbol
42
+ field_class = field_class_from_symbol(as)
43
+
44
+ if field_class.present?
45
+ # The field has been registered before.
46
+ instantiate_field(id, klass: field_class, **args, &block)
47
+ else
48
+ # The symbol can be transformed to a class and found.
49
+ class_name = as.to_s.camelize
50
+ field_class = "#{class_name}Field"
51
+
52
+ # Discover & load custom field classes
53
+ if Object.const_defined? field_class
54
+ instantiate_field(id, klass: field_class.safe_constantize, **args, &block)
55
+ end
56
+ end
57
+ end
58
+
59
+ def parse_from_class
60
+ # The field has been passed as a class.
61
+ if Object.const_defined? as.to_s
62
+ instantiate_field(id, klass: as, **args, &block)
63
+ end
64
+ end
65
+
66
+ def instantiate_field(id, klass:, **args, &block)
67
+ if block
68
+ klass.new(id, **args || {}, &block)
69
+ else
70
+ klass.new(id, **args || {})
71
+ end
72
+ end
73
+
74
+ def field_class_from_symbol(symbol)
75
+ matched_field = Avo::App.fields.find do |field|
76
+ field[:name].to_s == symbol.to_s
77
+ end
78
+
79
+ return matched_field[:class] if matched_field.present? && matched_field[:class].present?
80
+ end
81
+ end
82
+ end
83
+ end
@@ -4,8 +4,11 @@ module Avo
4
4
  extend ActiveSupport::DescendantsTracker
5
5
  extend Avo::Fields::FieldExtensions::HasFieldName
6
6
 
7
- include Avo::Fields::FieldExtensions::VisibleInDifferentViews
7
+ include Avo::Concerns::IsResourceItem
8
+ include Avo::Concerns::HandlesFieldArgs
9
+
8
10
  include ActionView::Helpers::UrlHelper
11
+ include Avo::Fields::FieldExtensions::VisibleInDifferentViews
9
12
 
10
13
  include Avo::Concerns::HandlesFieldArgs
11
14
  include Avo::Concerns::HasHTMLAttributes
@@ -48,8 +51,9 @@ module Avo
48
51
  attr_reader :panel_name
49
52
 
50
53
  class_attribute :field_name_attribute
54
+ class_attribute :item_type, default: :field
51
55
 
52
- def initialize(id, _options: {}, **args, &block)
56
+ def initialize(id, **args, &block)
53
57
  super(id, **args, &block)
54
58
 
55
59
  @id = id
@@ -206,9 +210,14 @@ module Avo
206
210
 
207
211
  # Try and build the component class or fallback to a blank one
208
212
  def component_for_view(view = :index)
213
+ # Use the edit variant for all "update" views
214
+ view = :edit if view.in? [:new, :create, :update]
215
+
209
216
  component_class = "::Avo::Fields::#{view_component_name}::#{view.to_s.camelize}Component"
210
217
  component_class.constantize
211
218
  rescue
219
+ # When returning nil, a race condition happens and throws an error in some environments.
220
+ # See https://github.com/avo-hq/avo/pull/365
212
221
  ::Avo::BlankFieldComponent
213
222
  end
214
223
 
@@ -228,6 +237,14 @@ module Avo
228
237
  true
229
238
  end
230
239
 
240
+ def visible_in_reflection?
241
+ true
242
+ end
243
+
244
+ def hidden_in_reflection?
245
+ !visible_in_reflection?
246
+ end
247
+
231
248
  private
232
249
 
233
250
  def model_or_class(model)
@@ -7,13 +7,20 @@ module Avo
7
7
  attr_accessor :show_on_new
8
8
  attr_accessor :show_on_edit
9
9
 
10
- def initialize(id, **args, &block)
10
+ def initialize(id = nil, **args, &block)
11
11
  @show_on_index = @show_on_index.nil? ? true : @show_on_index
12
12
  @show_on_show = @show_on_show.nil? ? true : @show_on_show
13
13
  @show_on_new = @show_on_new.nil? ? true : @show_on_new
14
14
  @show_on_edit = @show_on_edit.nil? ? true : @show_on_edit
15
15
  end
16
16
 
17
+ # Validates if the field is visible on certain view
18
+ def visible_on?(view)
19
+ raise "No view specified on visibility check." if view.blank?
20
+
21
+ send :"show_on_#{view.to_s}"
22
+ end
23
+
17
24
  def show_on(*where)
18
25
  return show_on_all if where.include? :all
19
26
 
@@ -44,6 +51,16 @@ module Avo
44
51
  end
45
52
  end
46
53
 
54
+ # When submitting the form on creation, the new page will be create but we don't have a visibility marker for create so we'll default to new
55
+ def show_on_create
56
+ show_on_new
57
+ end
58
+
59
+ # When submitting the form on update, the new page will be create but we don't have a visibility marker for update so we'll default to edit
60
+ def show_on_update
61
+ show_on_edit
62
+ end
63
+
47
64
  private
48
65
 
49
66
  def show_on_view(view)
@@ -31,7 +31,8 @@ module Avo
31
31
  def frame_url
32
32
  Avo::Services::URIService.parse(@resource.record_path)
33
33
  .append_path(id.to_s)
34
- .append_query(turbo_frame: turbo_frame.to_s).to_s
34
+ .append_query(turbo_frame: turbo_frame.to_s)
35
+ .to_s
35
36
  end
36
37
 
37
38
  # The value
@@ -61,6 +62,22 @@ module Avo
61
62
  def placeholder
62
63
  @placeholder || I18n.t("avo.choose_an_option")
63
64
  end
65
+
66
+ def has_own_panel?
67
+ true
68
+ end
69
+
70
+ def visible_in_reflection?
71
+ false
72
+ end
73
+
74
+ # Adds the view override component
75
+ # has_one, has_many, has_and_belongs_to_many fields don't have edit views
76
+ def component_for_view(view = :index)
77
+ view = :show if view.in? [:new, :create, :update, :edit]
78
+
79
+ super view
80
+ end
64
81
  end
65
82
  end
66
83
  end
@@ -13,15 +13,18 @@ module Avo
13
13
  end
14
14
 
15
15
  def cover(field_name, as:, **args, &block)
16
- self.cover_field = self.class.parse_field(field_name, as: as, **args, &block)
16
+ field_parser = Avo::Dsl::FieldParser.new(id: field_name, as: as, order_index: items_index, **args, &block).parse
17
+ self.cover_field = field_parser.instance if field_parser.valid?
17
18
  end
18
19
 
19
20
  def title(field_name, as:, **args, &block)
20
- self.title_field = self.class.parse_field(field_name, as: as, **args, &block)
21
+ field_parser = Avo::Dsl::FieldParser.new(id: field_name, as: as, order_index: items_index, **args, &block).parse
22
+ self.title_field = field_parser.instance if field_parser.valid?
21
23
  end
22
24
 
23
25
  def body(field_name, as:, **args, &block)
24
- self.body_field = self.class.parse_field(field_name, as: as, **args, &block)
26
+ field_parser = Avo::Dsl::FieldParser.new(id: field_name, as: as, order_index: items_index, **args, &block).parse
27
+ self.body_field = field_parser.instance if field_parser.valid?
25
28
  end
26
29
 
27
30
  def hydrate(model:, view:, resource:)
@@ -0,0 +1,68 @@
1
+ module Avo
2
+ class ItemsHolder
3
+ attr_reader :tools
4
+ attr_accessor :items
5
+ attr_accessor :invalid_fields
6
+
7
+ def initialize
8
+ @items = []
9
+ @items_index = 0
10
+ @invalid_fields = []
11
+ end
12
+
13
+ # Adds a field to the bag
14
+ def field(field_name, **args, &block)
15
+ field_parser = Avo::Dsl::FieldParser.new(id: field_name, order_index: @items_index, **args, &block).parse
16
+
17
+ if field_parser.invalid?
18
+ as = args.fetch(:as, nil)
19
+
20
+ # End execution ehre and add the field to the invalid_fileds payload so we know to wanr the developer about that.
21
+ # @todo: Make sure this warning is still active
22
+ return add_invalid_field({
23
+ name: field_name,
24
+ as: as,
25
+ # resource: resource_class.name,
26
+ 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>"
27
+ })
28
+ end
29
+
30
+ add_item field_parser.instance
31
+ end
32
+
33
+ def tabs(instance)
34
+ add_item instance
35
+ end
36
+
37
+ def tab(name, **args, &block)
38
+ add_item Avo::TabBuilder.parse_block(name: name, **args, &block)
39
+ end
40
+
41
+ def tool(klass, **args)
42
+ instance = klass.new(**args)
43
+ add_item instance
44
+ end
45
+
46
+ def panel(panel_name = nil, **args, &block)
47
+ panel = Avo::PanelBuilder.parse_block(name: panel_name, **args, &block)
48
+
49
+ add_item panel
50
+ end
51
+
52
+ def add_item(instance)
53
+ @items << instance
54
+
55
+ increment_order_index
56
+ end
57
+
58
+ private
59
+
60
+ def add_invalid_field(payload)
61
+ @invalid_fields << payload
62
+ end
63
+
64
+ def increment_order_index
65
+ @items_index += 1
66
+ end
67
+ end
68
+ end
@@ -98,6 +98,7 @@ module Avo
98
98
  **other_metadata(:filters),
99
99
  main_menu_present: Avo.configuration.main_menu.present?,
100
100
  profile_menu_present: Avo.configuration.profile_menu.present?,
101
+ **config_metadata
101
102
  }
102
103
  rescue
103
104
  {}
@@ -178,6 +179,15 @@ module Avo
178
179
  }
179
180
  end
180
181
 
182
+ def config_metadata
183
+ {
184
+ config: {
185
+ root_path: Avo.configuration.root_path,
186
+ app_name: Avo.configuration.app_name
187
+ }
188
+ }
189
+ end
190
+
181
191
  def cache_and_return_error(error, exception_message = "")
182
192
  cache_response response: {error: error, exception_message: exception_message}.stringify_keys, time: 5.minutes.to_i
183
193
  end
@@ -0,0 +1,3 @@
1
+ class Avo::MainPanel < Avo::Panel
2
+ class_attribute :item_type, default: :main_panel
3
+ end
@@ -5,12 +5,12 @@ class Avo::Menu::Builder
5
5
  end
6
6
  end
7
7
 
8
- delegate :context, to: Avo::App
9
- delegate :current_user, to: Avo::App
10
- delegate :params, to: Avo::App
11
- delegate :request, to: Avo::App
12
- delegate :root_path, to: Avo::App
13
- delegate :view_context, to: Avo::App
8
+ delegate :context, to: ::Avo::App
9
+ delegate :current_user, to: ::Avo::App
10
+ delegate :params, to: ::Avo::App
11
+ delegate :request, to: ::Avo::App
12
+ delegate :root_path, to: ::Avo::App
13
+ delegate :view_context, to: ::Avo::App
14
14
 
15
15
  def initialize(name: nil, items: [])
16
16
  @menu = Avo::Menu::Menu.new
data/lib/avo/panel.rb ADDED
@@ -0,0 +1,25 @@
1
+ class Avo::Panel
2
+ include Avo::Concerns::IsResourceItem
3
+
4
+ class_attribute :item_type, default: :panel
5
+
6
+ attr_reader :name
7
+ attr_reader :description
8
+ attr_accessor :items_holder
9
+
10
+ delegate :items, :add_item, to: :items_holder
11
+
12
+ def initialize(name: nil, description: nil)
13
+ @name = name
14
+ @description = description
15
+ @items_holder = Avo::ItemsHolder.new
16
+ end
17
+
18
+ def add_item(item)
19
+ @items << item
20
+ end
21
+
22
+ def has_items?
23
+ @items.present?
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ class Avo::PanelBuilder
2
+ class << self
3
+ def parse_block(**args, &block)
4
+ Docile.dsl_eval(new(**args), &block).build
5
+ end
6
+ end
7
+
8
+ delegate :field, to: :items_holder
9
+ delegate :items, to: :items_holder
10
+
11
+ attr_reader :items_holder
12
+
13
+ def initialize(name: nil, **args)
14
+ @panel = Avo::Panel.new(name: name, **args)
15
+ @items_holder = Avo::ItemsHolder.new
16
+ end
17
+
18
+ # Fetch the tab
19
+ def build
20
+ @panel.items_holder = @items_holder
21
+ @panel
22
+ end
23
+ end
data/lib/avo/tab.rb ADDED
@@ -0,0 +1,78 @@
1
+ class Avo::Tab
2
+ include Avo::Concerns::IsResourceItem
3
+ include Avo::Fields::FieldExtensions::VisibleInDifferentViews
4
+
5
+ class_attribute :item_type, default: :tab
6
+ delegate :items, :add_item, to: :items_holder
7
+
8
+ attr_reader :name
9
+ attr_reader :view
10
+ attr_accessor :description
11
+ attr_accessor :items_holder
12
+ attr_accessor :holds_one_field
13
+
14
+ def initialize(name: nil, description: nil, view: nil, holds_one_field: false, **args)
15
+ # Initialize the visibility markers
16
+ super
17
+
18
+ @name = name
19
+ @description = description
20
+ @holds_one_field = holds_one_field
21
+ @items_holder = Avo::ItemsHolder.new
22
+ @view = view
23
+
24
+ show_on args[:show_on] if args[:show_on].present?
25
+ hide_on args[:hide_on] if args[:hide_on].present?
26
+ only_on args[:only_on] if args[:only_on].present?
27
+ except_on args[:except_on] if args[:except_on].present?
28
+ end
29
+
30
+ def hydrate(view: nil)
31
+ @view = view
32
+
33
+ self
34
+ end
35
+
36
+ def turbo_frame_id(parent: nil)
37
+ id = "#{Avo::Tab.to_s.parameterize} #{name}".parameterize
38
+
39
+ return id if parent.nil?
40
+
41
+ "#{parent.turbo_frame_id} #{id}".parameterize
42
+ end
43
+
44
+ def empty?
45
+ visible_items.blank?
46
+ end
47
+
48
+ # Checks for visibility on itself or on theone field it holds
49
+ def visible_on?(view)
50
+ if holds_one_field
51
+ super(view) && items.first.visible_on?(view)
52
+ else
53
+ super(view)
54
+ end
55
+ end
56
+
57
+ def items
58
+ if self.items_holder.present?
59
+ self.items_holder.items
60
+ else
61
+ []
62
+ end
63
+ end
64
+
65
+ def visible_items
66
+ items.map do |item|
67
+ if item.is_field?
68
+ visible = item.visible_on?(view)
69
+ # Remove the fields that shouldn't be visible in this view
70
+ # eg: has_many fields on edit
71
+ item = nil unless visible
72
+ end
73
+
74
+ item
75
+ end
76
+ .compact
77
+ end
78
+ end
@@ -0,0 +1,25 @@
1
+ class Avo::TabBuilder
2
+ class << self
3
+ def parse_block(**args, &block)
4
+ Docile.dsl_eval(new(**args), &block).build
5
+ end
6
+ end
7
+
8
+ attr_reader :items_holder
9
+
10
+ delegate :field, to: :items_holder
11
+ delegate :tool, to: :items_holder
12
+ delegate :panel, to: :items_holder
13
+ delegate :items, to: :items_holder
14
+
15
+ def initialize(name: nil, **args)
16
+ @tab = Avo::Tab.new(name: name, **args)
17
+ @items_holder = Avo::ItemsHolder.new
18
+ end
19
+
20
+ # Fetch the tab
21
+ def build
22
+ @tab.items_holder = @items_holder
23
+ @tab
24
+ end
25
+ end
@@ -0,0 +1,40 @@
1
+ class Avo::TabGroup
2
+ include Avo::Concerns::HasFields
3
+ include Avo::Concerns::IsResourceItem
4
+
5
+ class_attribute :item_type, default: :tab_group
6
+
7
+ attr_reader :view
8
+ attr_accessor :index
9
+ attr_accessor :items_holder
10
+
11
+ def initialize(index: 0, view: nil)
12
+ @index = index
13
+ @items_holder = Avo::ItemsHolder.new
14
+ @view = view
15
+ end
16
+
17
+ def hydrate(view: nil)
18
+ @view = view
19
+
20
+ self
21
+ end
22
+
23
+ def visible_items
24
+ items.map do |item|
25
+ item.hydrate view: view
26
+ end
27
+ .select do |item|
28
+ # Remove items hidden in this view
29
+ item.visible_on? view
30
+ end
31
+ .select do |item|
32
+ # Remove empty items
33
+ !item.empty?
34
+ end
35
+ end
36
+
37
+ def turbo_frame_id
38
+ "#{Avo::TabGroup.to_s.parameterize} #{index}".parameterize
39
+ end
40
+ end
@@ -0,0 +1,43 @@
1
+ class Avo::TabGroupBuilder
2
+ class << self
3
+ def parse_block(&block)
4
+ Docile.dsl_eval(new, &block).build
5
+ end
6
+ end
7
+
8
+ attr_reader :items_holder
9
+
10
+ delegate :tab, to: :items_holder
11
+
12
+ def initialize
13
+ @group = Avo::TabGroup.new
14
+ @items_holder = Avo::ItemsHolder.new
15
+ end
16
+
17
+ def field(field_name, **args, &block)
18
+ parsed = Avo::Dsl::FieldParser.new(id: field_name, order_index: @items_index, **args, &block).parse
19
+ field_instance = parsed.instance
20
+
21
+ name = field_instance.name
22
+ tab = Avo::Tab.new name: name
23
+
24
+ if field_instance.has_own_panel?
25
+ tab.items_holder.add_item parsed.instance
26
+ tab.holds_one_field = true
27
+ else
28
+ # If the field is not in a panel, create one and add it
29
+ panel = Avo::Panel.new name: name
30
+ panel.items_holder.add_item parsed.instance
31
+ # Add that panel to the bag
32
+ tab.items_holder.add_item panel
33
+ end
34
+
35
+ @items_holder.tabs tab
36
+ end
37
+
38
+ # Fetch the tab
39
+ def build
40
+ @group.items_holder = @items_holder
41
+ @group
42
+ end
43
+ end
data/lib/avo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "2.9.1.pre7" unless const_defined?(:VERSION)
2
+ VERSION = "2.10.0" unless const_defined?(:VERSION)
3
3
  end
@@ -1,2 +1,4 @@
1
+ # This controller has been generated to enable Rails' resource routes.
2
+ # You shouldn't need to modify it in order to use Avo.
1
3
  class <%= controller_class %> < Avo::ResourcesController
2
4
  end
@@ -1,5 +1,5 @@
1
1
  <div class="flex flex-col">
2
- <%%= render Avo::PanelComponent.new title: "<%= human_name %>" do |c| %>
2
+ <%%= render Avo::PanelComponent.new(name: "<%= human_name %>") do |c| %>
3
3
  <%% c.tools do %>
4
4
  <%%= a_link('/avo', icon: 'heroicons/solid/academic-cap', style: :primary) do %>
5
5
  Dummy link
@@ -1,5 +1,5 @@
1
1
  <div class="flex flex-col">
2
- <%%= render Avo::PanelComponent.new title: '<%= human_name %>', display_breadcrumbs: true do |c| %>
2
+ <%%= render Avo::PanelComponent.new(name: '<%= human_name %>', display_breadcrumbs: true) do |c| %>
3
3
  <%% c.tools do %>
4
4
  <div class="text-sm italic">This is the panels tools section.</div>
5
5
  <%% end %>
@@ -3977,9 +3977,9 @@ a{
3977
3977
  display:flex;
3978
3978
  }
3979
3979
 
3980
- .button-group .button-component:first-child{
3981
- margin-right:-1px
3982
- }
3980
+ .button-group .button-component{
3981
+ margin-right:-1px
3982
+ }
3983
3983
 
3984
3984
  .button-group .button-component:first-child{
3985
3985
  border-top-left-radius:0.25rem;
@@ -6354,6 +6354,16 @@ trix-editor .attachment__metadata .attachment__size {
6354
6354
  margin-bottom:0px
6355
6355
  }
6356
6356
 
6357
+ .-mx-2{
6358
+ margin-left:-0.5rem;
6359
+ margin-right:-0.5rem
6360
+ }
6361
+
6362
+ .-my-2{
6363
+ margin-top:-0.5rem;
6364
+ margin-bottom:-0.5rem
6365
+ }
6366
+
6357
6367
  .mx-6{
6358
6368
  margin-left:1.5rem;
6359
6369
  margin-right:1.5rem
@@ -8885,6 +8895,16 @@ trix-editor {
8885
8895
  }
8886
8896
 
8887
8897
  @media (min-width: 1024px){
8898
+ .lg\:-mx-4{
8899
+ margin-left:-1rem;
8900
+ margin-right:-1rem
8901
+ }
8902
+
8903
+ .lg\:-my-4{
8904
+ margin-top:-1rem;
8905
+ margin-bottom:-1rem
8906
+ }
8907
+
8888
8908
  .lg\:flex{
8889
8909
  display:flex
8890
8910
  }
@@ -8927,6 +8947,10 @@ trix-editor {
8927
8947
  padding:1.5rem
8928
8948
  }
8929
8949
 
8950
+ .lg\:p-4{
8951
+ padding:1rem
8952
+ }
8953
+
8930
8954
  .lg\:px-8{
8931
8955
  padding-left:2rem;
8932
8956
  padding-right:2rem