avo 2.11.3.pre.3 → 2.12.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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -3
  3. data/app/components/avo/card_component.html.erb +8 -8
  4. data/app/components/avo/index/ordering/buttons_component.html.erb +1 -1
  5. data/app/components/avo/index/resource_controls_component.rb +1 -1
  6. data/app/components/avo/sidebar_component.html.erb +1 -1
  7. data/app/components/avo/views/resource_edit_component.rb +0 -20
  8. data/app/components/avo/views/resource_index_component.html.erb +49 -97
  9. data/app/components/avo/views/resource_index_component.rb +2 -0
  10. data/app/components/avo/views/resource_show_component.html.erb +0 -5
  11. data/app/controllers/avo/application_controller.rb +7 -3
  12. data/app/controllers/avo/associations_controller.rb +2 -2
  13. data/app/controllers/avo/base_controller.rb +3 -7
  14. data/app/controllers/avo/cards_controller.rb +5 -18
  15. data/app/controllers/avo/dashboards_controller.rb +2 -4
  16. data/app/javascript/js/controllers/{card_controller.js → dashboard_card_controller.js} +0 -0
  17. data/app/javascript/js/controllers.js +2 -2
  18. data/app/views/avo/cards/_metric_card.html.erb +2 -2
  19. data/app/views/avo/dashboards/show.html.erb +19 -2
  20. data/app/views/layouts/avo/application.html.erb +1 -1
  21. data/config/routes.rb +0 -3
  22. data/lib/avo/base_card.rb +21 -40
  23. data/lib/avo/base_resource.rb +0 -1
  24. data/lib/avo/dashboards/base_dashboard.rb +50 -15
  25. data/lib/avo/dashboards/base_divider.rb +1 -5
  26. data/lib/avo/dashboards/chartkick_card.rb +4 -5
  27. data/lib/avo/fields/base_field.rb +12 -6
  28. data/lib/avo/fields/field_extensions/visible_in_different_views.rb +1 -12
  29. data/lib/avo/fields/has_base_field.rb +16 -1
  30. data/lib/avo/hosts/dashboard_card.rb +1 -1
  31. data/lib/avo/tab.rb +1 -3
  32. data/lib/avo/version.rb +1 -1
  33. data/lib/generators/avo/templates/cards/partial_card_partial.tt +1 -1
  34. data/public/avo-assets/avo.css +34 -86
  35. data/public/avo-assets/avo.js +6 -6
  36. data/public/avo-assets/avo.js.map +3 -3
  37. metadata +5 -9
  38. data/app/components/avo/cards_list_component.html.erb +0 -16
  39. data/app/components/avo/cards_list_component.rb +0 -13
  40. data/lib/avo/concerns/has_cards.rb +0 -88
  41. data/lib/avo/concerns/styles_cards.rb +0 -48
data/lib/avo/base_card.rb CHANGED
@@ -1,11 +1,10 @@
1
1
  module Avo
2
2
  class BaseCard
3
- include Avo::Concerns::StylesCards
4
- include Avo::Fields::FieldExtensions::VisibleInDifferentViews
5
-
6
3
  class_attribute :id
7
4
  class_attribute :label
8
5
  class_attribute :description
6
+ class_attribute :cols, default: 1
7
+ class_attribute :rows, default: 1
9
8
  class_attribute :initial_range
10
9
  class_attribute :ranges, default: []
11
10
  class_attribute :refresh_every
@@ -14,7 +13,7 @@ module Avo
14
13
  class_attribute :result_data
15
14
  class_attribute :query_block
16
15
 
17
- attr_accessor :parent
16
+ attr_accessor :dashboard
18
17
  attr_accessor :options
19
18
  attr_accessor :index
20
19
  attr_accessor :params
@@ -27,8 +26,8 @@ module Avo
27
26
  end
28
27
  end
29
28
 
30
- def initialize(parent:, options: {}, index: 0, cols: nil, rows: nil, label: nil, description: nil, refresh_every: nil, **args)
31
- @parent = parent
29
+ def initialize(dashboard:, options: {}, index: 0, cols: nil, rows: nil, label: nil, description: nil, refresh_every: nil)
30
+ @dashboard = dashboard
32
31
  @options = options
33
32
  @index = index
34
33
  @cols = cols
@@ -36,8 +35,6 @@ module Avo
36
35
  @label = label
37
36
  @refresh_every = refresh_every
38
37
  @description = description
39
-
40
- initialize_visibility args
41
38
  end
42
39
 
43
40
  def label
@@ -56,21 +53,13 @@ module Avo
56
53
  end
57
54
 
58
55
  def turbo_frame
59
- if parent_is_dashboard?
60
- "#{parent.id}_#{id}"
61
- elsif parent_is_resource?
62
- "#{parent.id}_#{parent.model.id}_#{id}"
63
- end
56
+ "#{dashboard.id}_#{id}"
64
57
  end
65
58
 
66
59
  def frame_url(enforced_range: nil, params: {})
67
60
  enforced_range ||= initial_range || ranges.first
68
61
 
69
- if parent_is_dashboard?
70
- Avo::App.view_context.avo.dashboard_card_path(dashboard.id, id, turbo_frame: turbo_frame, index: index, range: enforced_range, **params.permit!.to_h)
71
- elsif parent_is_resource?
72
- Avo::App.root_path(paths: ["resources", parent.route_key, parent.model.id, "cards", id], query: {**params.permit!.to_h, turbo_frame: turbo_frame, index: index, range: enforced_range})
73
- end
62
+ Avo::App.view_context.avo.dashboard_card_path(dashboard.id, id, turbo_frame: turbo_frame, index: index, range: enforced_range, **params.permit!)
74
63
  end
75
64
 
76
65
  def card_classes
@@ -87,13 +76,14 @@ module Avo
87
76
  }
88
77
 
89
78
  classes_for_rows = {
90
- 1 => " min-h-[8rem] row-span-1",
91
- 2 => " min-h-[16rem] row-span-2",
92
- 3 => " min-h-[24rem] row-span-3",
93
- 4 => " min-h-[32rem] row-span-4",
94
- 5 => " min-h-[40rem] row-span-5",
95
- 6 => " min-h-[48rem] row-span-6"
79
+ 1 => " h-36",
80
+ 2 => " h-72",
81
+ 3 => " h-[27rem]",
82
+ 4 => " h-[36rem]",
83
+ 5 => " h-[45rem]",
84
+ 6 => " h-[54rem]"
96
85
  }
86
+ # puts ["cols->", cols, classes_for_cols, classes_for_rows, classes_for_cols[cols.to_i]].inspect
97
87
 
98
88
  result += classes_for_cols[cols.to_i] if classes_for_cols[cols.to_i].present?
99
89
  result += classes_for_rows[rows.to_i] if classes_for_rows[rows.to_i].present?
@@ -108,16 +98,15 @@ module Avo
108
98
  end
109
99
 
110
100
  def compute_result
111
- Avo::Hosts::DashboardCard.new(card: self, parent: parent, params: params, context: context, range: range, options: options)
101
+ Avo::Hosts::DashboardCard.new(card: self, dashboard: dashboard, params: params, context: context, range: range, options: options)
112
102
  .compute_result
113
103
 
114
104
  self
115
105
  end
116
106
 
117
- def hydrate(parent: nil, params: nil, view: nil)
118
- @parent = parent if parent.present?
107
+ def hydrate(dashboard: nil, params: nil)
108
+ @dashboard = dashboard if dashboard.present?
119
109
  @params = params if params.present?
120
- @view = view if view.present?
121
110
 
122
111
  self
123
112
  end
@@ -146,20 +135,12 @@ module Avo
146
135
 
147
136
  private
148
137
 
149
- def parent_is_dashboard?
150
- parent.class.superclass == Avo::Dashboards::BaseDashboard
151
- end
152
-
153
- def parent_is_resource?
154
- parent.class.superclass == Avo::BaseResource
155
- end
156
-
157
- def resource
158
- parent if parent_is_resource?
138
+ def cols
139
+ @cols || self.class.cols
159
140
  end
160
141
 
161
- def dashboard
162
- parent if parent_is_dashboard?
142
+ def rows
143
+ @rows || self.class.rows
163
144
  end
164
145
  end
165
146
  end
@@ -3,7 +3,6 @@ module Avo
3
3
  extend ActiveSupport::DescendantsTracker
4
4
 
5
5
  include ActionView::Helpers::UrlHelper
6
- include Avo::Concerns::HasCards
7
6
  include Avo::Concerns::HasModel
8
7
  include Avo::Concerns::HasFields
9
8
  include Avo::Concerns::HasStimulusControllers
@@ -3,18 +3,63 @@ module Avo
3
3
  class BaseDashboard
4
4
  extend ActiveSupport::DescendantsTracker
5
5
 
6
- include Avo::Concerns::HasCards
7
-
8
6
  class_attribute :id
9
7
  class_attribute :name
10
8
  class_attribute :description
9
+ class_attribute :items_holder
10
+ class_attribute :grid_cols, default: 3
11
11
  class_attribute :visible, default: true
12
12
  class_attribute :index, default: 0
13
13
 
14
- attr_reader :view
15
- attr_reader :params
16
-
17
14
  class << self
15
+ def card(klass, label: nil, description: nil, cols: nil, rows: nil, refresh_every: nil, options: {})
16
+ self.items_holder ||= []
17
+
18
+ self.items_holder << klass.new(dashboard: self,
19
+ label: label,
20
+ description: description,
21
+ cols: cols,
22
+ rows: rows,
23
+ refresh_every: refresh_every,
24
+ options: options,
25
+ index: index
26
+ )
27
+ self.index += 1
28
+ end
29
+
30
+ def item_at_index(index)
31
+ items.find do |item|
32
+ next if item.index.blank?
33
+
34
+ item.index == index
35
+ end
36
+ end
37
+
38
+ def divider(**args)
39
+ self.items_holder ||= []
40
+
41
+ self.items_holder << BaseDivider.new(**args)
42
+ end
43
+
44
+ def items
45
+ self.items_holder
46
+ end
47
+
48
+ def classes
49
+ case grid_cols
50
+ when 3
51
+ "sm:grid-cols-3"
52
+ when 4
53
+ "sm:grid-cols-4"
54
+ when 5
55
+ "sm:grid-cols-5"
56
+ when 6
57
+ "sm:grid-cols-6"
58
+ else
59
+ "sm:grid-cols-3"
60
+ end
61
+ end
62
+
18
63
  def navigation_label
19
64
  name
20
65
  end
@@ -39,16 +84,6 @@ module Avo
39
84
  !is_visible?
40
85
  end
41
86
  end
42
-
43
- def initialize
44
- @view = :dashboard
45
- end
46
-
47
- def hydrate(params:)
48
- @params = params
49
-
50
- self
51
- end
52
87
  end
53
88
  end
54
89
  end
@@ -5,16 +5,12 @@ module Avo
5
5
  attr_reader :invisible
6
6
  attr_reader :index
7
7
 
8
- include Avo::Fields::FieldExtensions::VisibleInDifferentViews
9
-
10
8
  class_attribute :id
11
9
 
12
- def initialize(label: nil, invisible: false, index: nil, **args)
10
+ def initialize(label: nil, invisible: false, index: nil)
13
11
  @label = label
14
12
  @invisible = invisible
15
13
  @index = index
16
-
17
- initialize_visibility args
18
14
  end
19
15
 
20
16
  def is_divider?
@@ -23,12 +23,11 @@ module Avo
23
23
  end
24
24
 
25
25
  def chartkick_options
26
- card_height = 128
27
- card_heading = 32
26
+ card_height = 144
27
+ card_heading = 40
28
28
 
29
29
  default = {
30
- # figure our the available height for the chart.
31
- # It's not ideal to work with magic numbers, I know.
30
+ # figure our the available height for the chart
32
31
  height: "#{(rows * card_height) - card_heading}px",
33
32
  colors: %w[#0B8AE2 #34C683 #2AB1EE #34C6A8],
34
33
  library: {
@@ -36,7 +35,7 @@ module Avo
36
35
  points: false,
37
36
  animation: true
38
37
  },
39
- id: "#{parent.id}-#{rand(10_000..99_999)}"
38
+ id: "#{dashboard.id}-#{rand(10_000..99_999)}"
40
39
  }
41
40
 
42
41
  no_scale_options = {display: false}
@@ -54,7 +54,7 @@ module Avo
54
54
  class_attribute :item_type, default: :field
55
55
 
56
56
  def initialize(id, **args, &block)
57
- # super(id, **args, &block)
57
+ super(id, **args, &block)
58
58
 
59
59
  @id = id
60
60
  @name = args[:name]
@@ -83,7 +83,11 @@ module Avo
83
83
  @computed = block.present?
84
84
  @computed_value = nil
85
85
 
86
- initialize_visibility args
86
+ # Set the visibility
87
+ show_on args[:show_on] if args[:show_on].present?
88
+ hide_on args[:hide_on] if args[:hide_on].present?
89
+ only_on args[:only_on] if args[:only_on].present?
90
+ except_on args[:except_on] if args[:except_on].present?
87
91
  end
88
92
 
89
93
  def hydrate(model: nil, resource: nil, action: nil, view: nil, panel_name: nil, user: nil)
@@ -108,14 +112,12 @@ module Avo
108
112
  # Secondly we'll try to find a translation key
109
113
  # We'll fallback to humanizing the id
110
114
  def name
111
- default = @id.to_s.humanize(keep_id_suffix: true)
112
-
113
115
  return @name if custom_name?
114
116
 
115
117
  if translation_key && ::Avo::App.translation_enabled
116
- t(translation_key, count: 1, default: default).capitalize
118
+ t(translation_key, count: 1, default: default_name).capitalize
117
119
  else
118
- default
120
+ default_name
119
121
  end
120
122
  end
121
123
 
@@ -133,6 +135,10 @@ module Avo
133
135
  @name.present?
134
136
  end
135
137
 
138
+ def default_name
139
+ @id.to_s.humanize(keep_id_suffix: true)
140
+ end
141
+
136
142
  def placeholder
137
143
  return @placeholder if @placeholder.present?
138
144
 
@@ -6,21 +6,12 @@ module Avo
6
6
  attr_accessor :show_on_show
7
7
  attr_accessor :show_on_new
8
8
  attr_accessor :show_on_edit
9
- attr_accessor :show_on_dashboard
10
9
 
11
- def initialize_visibility(args = {})
12
- # def initialize(id = nil, **args, &block)
10
+ def initialize(id = nil, **args, &block)
13
11
  @show_on_index = @show_on_index.nil? ? true : @show_on_index
14
12
  @show_on_show = @show_on_show.nil? ? true : @show_on_show
15
13
  @show_on_new = @show_on_new.nil? ? true : @show_on_new
16
14
  @show_on_edit = @show_on_edit.nil? ? true : @show_on_edit
17
- @show_on_dashboard = @show_on_dashboard.nil? ? true : @show_on_dashboard
18
-
19
- # Set the visibility
20
- show_on args[:show_on] if args[:show_on].present?
21
- hide_on args[:hide_on] if args[:hide_on].present?
22
- only_on args[:only_on] if args[:only_on].present?
23
- except_on args[:except_on] if args[:except_on].present?
24
15
  end
25
16
 
26
17
  # Validates if the field is visible on certain view
@@ -91,7 +82,6 @@ module Avo
91
82
  end
92
83
 
93
84
  def show_on_all
94
- @show_on_dashboard = true
95
85
  @show_on_index = true
96
86
  @show_on_show = true
97
87
  @show_on_edit = true
@@ -99,7 +89,6 @@ module Avo
99
89
  end
100
90
 
101
91
  def hide_on_all
102
- @show_on_dashboard = false
103
92
  @show_on_index = false
104
93
  @show_on_show = false
105
94
  @show_on_edit = false
@@ -15,6 +15,7 @@ module Avo
15
15
  @display = args[:display].present? ? args[:display] : :show
16
16
  @searchable = args[:searchable] == true
17
17
  @description = args[:description]
18
+ @use_resource = args[:use_resource] || nil
18
19
  @discreet_pagination = args[:discreet_pagination] || false
19
20
  end
20
21
 
@@ -22,12 +23,16 @@ module Avo
22
23
  @searchable && ::Avo::App.license.has_with_trial(:searchable_associations)
23
24
  end
24
25
 
26
+ def use_resource
27
+ App.get_resource @use_resource
28
+ end
29
+
25
30
  def resource
26
31
  Avo::App.get_resource_by_model_name @model.class
27
32
  end
28
33
 
29
34
  def turbo_frame
30
- "#{self.class.name.demodulize.to_s.underscore}_#{display}_#{id}"
35
+ "#{self.class.name.demodulize.to_s.underscore}_#{display}_#{frame_id}"
31
36
  end
32
37
 
33
38
  def frame_url
@@ -91,6 +96,16 @@ module Avo
91
96
  true
92
97
  end
93
98
  end
99
+
100
+ def default_name
101
+ use_resource&.name || super
102
+ end
103
+
104
+ private
105
+
106
+ def frame_id
107
+ use_resource.present? ? use_resource.route_key.to_sym : @id
108
+ end
94
109
  end
95
110
  end
96
111
  end
@@ -7,7 +7,7 @@ module Avo
7
7
 
8
8
  option :context
9
9
  option :range
10
- option :parent
10
+ option :dashboard
11
11
  option :card
12
12
  option :params
13
13
  option :options
data/lib/avo/tab.rb CHANGED
@@ -13,7 +13,7 @@ class Avo::Tab
13
13
 
14
14
  def initialize(name: nil, description: nil, view: nil, holds_one_field: false, **args)
15
15
  # Initialize the visibility markers
16
- # super
16
+ super
17
17
 
18
18
  @name = name
19
19
  @description = description
@@ -25,8 +25,6 @@ class Avo::Tab
25
25
  hide_on args[:hide_on] if args[:hide_on].present?
26
26
  only_on args[:only_on] if args[:only_on].present?
27
27
  except_on args[:except_on] if args[:except_on].present?
28
-
29
- initialize_visibility args
30
28
  end
31
29
 
32
30
  def hydrate(view: nil)
data/lib/avo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "2.11.3.pre.3" unless const_defined?(:VERSION)
2
+ VERSION = "2.12.0" unless const_defined?(:VERSION)
3
3
  end
@@ -1,6 +1,6 @@
1
1
  <div class="flex-1 flex p-4">
2
2
  <div class="place-self-end">
3
- Parent ID: <%%= @parent.id %>
3
+ Dashboard ID: <%%= @dashboard.id %>
4
4
  <br />
5
5
  <br />
6
6
  Customize this partial under <code class='p-1 rounded bg-gray-500 text-white text-sm'>app/views/avo/cards/_<%= name.underscore %>.html.erb</code>
@@ -6359,30 +6359,6 @@ trix-editor .attachment__metadata .attachment__size {
6359
6359
  grid-column:1 / -1
6360
6360
  }
6361
6361
 
6362
- .row-span-1{
6363
- grid-row:span 1 / span 1
6364
- }
6365
-
6366
- .row-span-2{
6367
- grid-row:span 2 / span 2
6368
- }
6369
-
6370
- .row-span-3{
6371
- grid-row:span 3 / span 3
6372
- }
6373
-
6374
- .row-span-4{
6375
- grid-row:span 4 / span 4
6376
- }
6377
-
6378
- .row-span-5{
6379
- grid-row:span 5 / span 5
6380
- }
6381
-
6382
- .row-span-6{
6383
- grid-row:span 6 / span 6
6384
- }
6385
-
6386
6362
  .float-right{
6387
6363
  float:right
6388
6364
  }
@@ -6579,10 +6555,6 @@ trix-editor .attachment__metadata .attachment__size {
6579
6555
  margin-top:1.5rem
6580
6556
  }
6581
6557
 
6582
- .mb-6{
6583
- margin-bottom:1.5rem
6584
- }
6585
-
6586
6558
  .mr-px{
6587
6559
  margin-right:1px
6588
6560
  }
@@ -6635,6 +6607,30 @@ trix-editor .attachment__metadata .attachment__size {
6635
6607
  aspect-ratio:1 / 1
6636
6608
  }
6637
6609
 
6610
+ .h-36{
6611
+ height:9rem
6612
+ }
6613
+
6614
+ .h-72{
6615
+ height:18rem
6616
+ }
6617
+
6618
+ .h-\[27rem\]{
6619
+ height:27rem
6620
+ }
6621
+
6622
+ .h-\[36rem\]{
6623
+ height:36rem
6624
+ }
6625
+
6626
+ .h-\[45rem\]{
6627
+ height:45rem
6628
+ }
6629
+
6630
+ .h-\[54rem\]{
6631
+ height:54rem
6632
+ }
6633
+
6638
6634
  .h-5{
6639
6635
  height:1.25rem
6640
6636
  }
@@ -6699,30 +6695,6 @@ trix-editor .attachment__metadata .attachment__size {
6699
6695
  max-height:100%
6700
6696
  }
6701
6697
 
6702
- .min-h-\[8rem\]{
6703
- min-height:8rem
6704
- }
6705
-
6706
- .min-h-\[16rem\]{
6707
- min-height:16rem
6708
- }
6709
-
6710
- .min-h-\[24rem\]{
6711
- min-height:24rem
6712
- }
6713
-
6714
- .min-h-\[32rem\]{
6715
- min-height:32rem
6716
- }
6717
-
6718
- .min-h-\[40rem\]{
6719
- min-height:40rem
6720
- }
6721
-
6722
- .min-h-\[48rem\]{
6723
- min-height:48rem
6724
- }
6725
-
6726
6698
  .min-h-24{
6727
6699
  min-height:6rem
6728
6700
  }
@@ -7404,11 +7376,6 @@ trix-editor .attachment__metadata .attachment__size {
7404
7376
  background-color:rgb(21 128 61 / var(--tw-bg-opacity))
7405
7377
  }
7406
7378
 
7407
- .bg-application{
7408
- --tw-bg-opacity:1;
7409
- background-color:rgb(246 246 247 / var(--tw-bg-opacity))
7410
- }
7411
-
7412
7379
  .bg-red-400{
7413
7380
  --tw-bg-opacity:1;
7414
7381
  background-color:rgb(248 113 113 / var(--tw-bg-opacity))
@@ -7439,6 +7406,11 @@ trix-editor .attachment__metadata .attachment__size {
7439
7406
  background-color:rgb(47 50 55 / var(--tw-bg-opacity))
7440
7407
  }
7441
7408
 
7409
+ .bg-application{
7410
+ --tw-bg-opacity:1;
7411
+ background-color:rgb(229 235 240 / var(--tw-bg-opacity))
7412
+ }
7413
+
7442
7414
  .bg-gray-50{
7443
7415
  --tw-bg-opacity:1;
7444
7416
  background-color:rgb(241 242 243 / var(--tw-bg-opacity))
@@ -7922,11 +7894,6 @@ trix-editor .attachment__metadata .attachment__size {
7922
7894
  color:rgb(30 41 59 / var(--tw-text-opacity))
7923
7895
  }
7924
7896
 
7925
- .text-gray-800{
7926
- --tw-text-opacity:1;
7927
- color:rgb(47 50 55 / var(--tw-text-opacity))
7928
- }
7929
-
7930
7897
  .text-red-600{
7931
7898
  --tw-text-opacity:1;
7932
7899
  color:rgb(220 38 38 / var(--tw-text-opacity))
@@ -7962,6 +7929,11 @@ trix-editor .attachment__metadata .attachment__size {
7962
7929
  color:rgb(51 65 85 / var(--tw-text-opacity))
7963
7930
  }
7964
7931
 
7932
+ .text-gray-800{
7933
+ --tw-text-opacity:1;
7934
+ color:rgb(47 50 55 / var(--tw-text-opacity))
7935
+ }
7936
+
7965
7937
  .text-green-600{
7966
7938
  --tw-text-opacity:1;
7967
7939
  color:rgb(22 163 74 / var(--tw-text-opacity))
@@ -8880,30 +8852,6 @@ trix-editor {
8880
8852
  grid-column:span 6 / span 6
8881
8853
  }
8882
8854
 
8883
- .sm\:row-span-1{
8884
- grid-row:span 1 / span 1
8885
- }
8886
-
8887
- .sm\:row-span-2{
8888
- grid-row:span 2 / span 2
8889
- }
8890
-
8891
- .sm\:row-span-3{
8892
- grid-row:span 3 / span 3
8893
- }
8894
-
8895
- .sm\:row-span-4{
8896
- grid-row:span 4 / span 4
8897
- }
8898
-
8899
- .sm\:row-span-5{
8900
- grid-row:span 5 / span 5
8901
- }
8902
-
8903
- .sm\:row-span-6{
8904
- grid-row:span 6 / span 6
8905
- }
8906
-
8907
8855
  .sm\:block{
8908
8856
  display:block
8909
8857
  }