avo 1.18.0 → 1.19.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 (106) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -3
  3. data/Gemfile.lock +195 -169
  4. data/app/components/avo/fields/belongs_to_field/index_component.html.erb +1 -1
  5. data/app/components/avo/fields/belongs_to_field/show_component.html.erb +1 -1
  6. data/app/components/avo/fields/common/multiple_file_viewer_component.html.erb +1 -1
  7. data/app/components/avo/fields/common/single_file_viewer_component.html.erb +1 -2
  8. data/app/components/avo/fields/has_one_field/index_component.html.erb +1 -1
  9. data/app/components/avo/fields/has_one_field/show_component.html.erb +1 -1
  10. data/app/components/avo/fields/has_one_field/show_component.rb +6 -1
  11. data/app/components/avo/fields/index_component.rb +2 -2
  12. data/app/components/avo/fields/text_field/index_component.html.erb +5 -1
  13. data/app/components/avo/fields/text_field/show_component.html.erb +5 -1
  14. data/app/components/avo/fields/trix_field/edit_component.html.erb +1 -1
  15. data/app/components/avo/index/grid_item_component.html.erb +4 -4
  16. data/app/components/avo/index/resource_controls_component.html.erb +1 -1
  17. data/app/components/avo/index/resource_controls_component.rb +23 -7
  18. data/app/components/avo/index/resource_table_component.html.erb +1 -1
  19. data/app/components/avo/panel_component.rb +3 -4
  20. data/app/components/avo/resource_component.rb +5 -1
  21. data/app/components/avo/views/resource_edit_component.html.erb +2 -2
  22. data/app/components/avo/views/resource_edit_component.rb +3 -3
  23. data/app/components/avo/views/resource_index_component.html.erb +2 -8
  24. data/app/components/avo/views/resource_index_component.rb +7 -15
  25. data/app/components/avo/views/resource_new_component.html.erb +2 -2
  26. data/app/components/avo/views/resource_new_component.rb +6 -2
  27. data/app/components/avo/views/resource_show_component.html.erb +5 -4
  28. data/app/components/avo/views/resource_show_component.rb +11 -6
  29. data/app/controllers/avo/actions_controller.rb +1 -1
  30. data/app/controllers/avo/application_controller.rb +4 -77
  31. data/app/controllers/avo/attachments_controller.rb +3 -2
  32. data/app/controllers/avo/base_controller.rb +28 -21
  33. data/app/controllers/avo/home_controller.rb +5 -1
  34. data/app/controllers/avo/relations_controller.rb +3 -3
  35. data/app/controllers/avo/search_controller.rb +1 -1
  36. data/app/helpers/avo/application_helper.rb +12 -0
  37. data/app/helpers/avo/resources_helper.rb +1 -1
  38. data/app/helpers/avo/url_helpers.rb +77 -0
  39. data/app/packs/entrypoints/application.css +1 -0
  40. data/app/packs/entrypoints/application.js +7 -0
  41. data/app/packs/js/controllers/loading_button_controller.js +22 -0
  42. data/app/packs/stylesheets/components/status.css +22 -15
  43. data/app/packs/stylesheets/spinner.css +49 -0
  44. data/app/views/avo/actions/show.html.erb +2 -2
  45. data/app/views/avo/base/_actions.html.erb +3 -3
  46. data/app/views/avo/base/_filters.html.erb +1 -1
  47. data/app/views/avo/home/failed_to_load.html.erb +3 -0
  48. data/app/views/avo/partials/_failed_state.html.erb +16 -0
  49. data/app/views/avo/partials/_paginator.html.erb +2 -2
  50. data/app/views/avo/partials/_profile_dropdown.html.erb +7 -5
  51. data/app/views/avo/relations/new.html.erb +0 -2
  52. data/app/views/avo/sidebar/_sidebar.html.erb +1 -1
  53. data/app/views/kaminari/_page.html.erb +1 -1
  54. data/config/routes.rb +7 -5
  55. data/db/factories.rb +9 -0
  56. data/lib/avo/app.rb +12 -12
  57. data/lib/avo/base_action.rb +9 -1
  58. data/lib/avo/base_resource.rb +41 -8
  59. data/lib/avo/configuration.rb +4 -0
  60. data/lib/avo/fields/base_field.rb +8 -2
  61. data/lib/avo/fields/files_field.rb +0 -2
  62. data/lib/avo/fields/has_and_belongs_to_many_field.rb +1 -19
  63. data/lib/avo/fields/has_base_field.rb +35 -0
  64. data/lib/avo/fields/has_many_field.rb +1 -19
  65. data/lib/avo/fields/has_one_field.rb +3 -19
  66. data/lib/avo/fields/text_field.rb +2 -0
  67. data/lib/avo/services/authorization_service.rb +8 -4
  68. data/lib/avo/version.rb +1 -1
  69. data/lib/generators/avo/templates/locales/avo.en.yml +2 -0
  70. data/public/avo-packs/css/{application-f9191617.css → application-c3b50b28.css} +54 -12
  71. data/public/avo-packs/css/application-c3b50b28.css.br +0 -0
  72. data/public/avo-packs/css/{application-f9191617.css.gz → application-c3b50b28.css.gz} +0 -0
  73. data/public/avo-packs/css/application-c3b50b28.css.map +1 -0
  74. data/public/avo-packs/css/application-c3b50b28.css.map.br +0 -0
  75. data/public/avo-packs/css/application-c3b50b28.css.map.gz +0 -0
  76. data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js +2 -0
  77. data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js.br +0 -0
  78. data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js.gz +0 -0
  79. data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js.map +1 -0
  80. data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js.map.br +0 -0
  81. data/public/avo-packs/js/actioncable-7119dbc1a908641fb263.chunk.js.map.gz +0 -0
  82. data/public/avo-packs/js/application-6fc968cfa52976c4582b.js +26 -0
  83. data/public/avo-packs/js/{application-cc89f096028eb1d4d971.js.LICENSE.txt → application-6fc968cfa52976c4582b.js.LICENSE.txt} +0 -0
  84. data/public/avo-packs/js/application-6fc968cfa52976c4582b.js.br +0 -0
  85. data/public/avo-packs/js/application-6fc968cfa52976c4582b.js.gz +0 -0
  86. data/public/avo-packs/js/application-6fc968cfa52976c4582b.js.map +1 -0
  87. data/public/avo-packs/js/application-6fc968cfa52976c4582b.js.map.br +0 -0
  88. data/public/avo-packs/js/application-6fc968cfa52976c4582b.js.map.gz +0 -0
  89. data/public/avo-packs/manifest.json +21 -21
  90. metadata +28 -22
  91. data/public/avo-packs/css/application-f9191617.css.br +0 -0
  92. data/public/avo-packs/css/application-f9191617.css.map +0 -1
  93. data/public/avo-packs/css/application-f9191617.css.map.br +0 -0
  94. data/public/avo-packs/css/application-f9191617.css.map.gz +0 -0
  95. data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js +0 -2
  96. data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js.br +0 -0
  97. data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js.gz +0 -0
  98. data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js.map +0 -1
  99. data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js.map.br +0 -0
  100. data/public/avo-packs/js/219-9aa2b689f44613118203.chunk.js.map.gz +0 -0
  101. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js +0 -26
  102. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.br +0 -0
  103. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.gz +0 -0
  104. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.map +0 -1
  105. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.map.br +0 -0
  106. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.map.gz +0 -0
data/lib/avo/app.rb CHANGED
@@ -8,6 +8,7 @@ module Avo
8
8
  class_attribute :license, default: nil
9
9
  class_attribute :current_user, default: nil
10
10
  class_attribute :root_path, default: nil
11
+ class_attribute :view_context, default: nil
11
12
 
12
13
  class << self
13
14
  def boot
@@ -22,17 +23,22 @@ module Avo
22
23
  end
23
24
  end
24
25
 
25
- def init(request:, context:, current_user:, root_path:)
26
+ def init(request:, context:, current_user:, root_path:, view_context:)
26
27
  self.request = request
27
28
  self.context = context
28
29
  self.current_user = current_user
29
30
  self.root_path = root_path
31
+ self.view_context = view_context
30
32
 
31
33
  self.license = Licensing::LicenseManager.new(Licensing::HQ.new(request).response).license
32
34
 
33
35
  # Set the current host for ActiveStorage
34
36
  begin
35
- ActiveStorage::Current.url_options = request.base_url
37
+ if Rails::VERSION::MAJOR === 6
38
+ ActiveStorage::Current.host = request.base_url
39
+ elsif Rails::VERSION::MAJOR === 7
40
+ ActiveStorage::Current.url_options = request.base_url
41
+ end
36
42
  rescue => exception
37
43
  Rails.logger.debug "[Avo] Failed to set ActiveStorage::Current.url_options, #{exception.inspect}"
38
44
  end
@@ -121,8 +127,8 @@ module Avo
121
127
 
122
128
  def get_available_resources(user = nil)
123
129
  resources.select do |resource|
124
- Services::AuthorizationService.authorize user, resource.model_class, Avo.configuration.authorization_methods.stringify_keys["index"], raise_exception: false
125
- end
130
+ Services::AuthorizationService.authorize user, resource.model_class, Avo.configuration.authorization_methods.stringify_keys["index"], raise_exception: false
131
+ end
126
132
  .sort_by { |r| r.name }
127
133
  end
128
134
 
@@ -145,7 +151,7 @@ module Avo
145
151
  # remove the leading underscore (_)
146
152
  filename[0] = ""
147
153
  # remove the extension
148
- filename.gsub!('.html.erb', '')
154
+ filename.gsub!(".html.erb", "")
149
155
  filename
150
156
  end
151
157
  end
@@ -163,13 +169,7 @@ module Avo
163
169
  resource.is_a? Class
164
170
  end
165
171
  .map do |resource|
166
- route_key = if resource.model_class.present?
167
- resource.model_class.model_name.plural.to_sym
168
- else
169
- resource.to_s.underscore.gsub("_resource", "").downcase.pluralize.to_sym
170
- end
171
-
172
- resources route_key
172
+ resources resource.new.model_key
173
173
  end
174
174
  end
175
175
  end
@@ -14,6 +14,7 @@ module Avo
14
14
  class_attribute :resource
15
15
  class_attribute :fields
16
16
  class_attribute :standalone, default: false
17
+ class_attribute :visible
17
18
 
18
19
  attr_accessor :response
19
20
  attr_accessor :model
@@ -27,10 +28,11 @@ module Avo
27
28
  self.class.to_s.demodulize.underscore.humanize(keep_id_suffix: true)
28
29
  end
29
30
 
30
- def initialize(model: nil, resource: nil, user: nil)
31
+ def initialize(model: nil, resource: nil, user: nil, view: nil)
31
32
  self.class.model = model if model.present?
32
33
  self.class.resource = resource if resource.present?
33
34
  self.class.user = user if user.present?
35
+ self.class.view = view if view.present?
34
36
 
35
37
  self.class.message ||= I18n.t("avo.are_you_sure_you_want_to_run_this_option")
36
38
  self.class.confirm_button_label ||= I18n.t("avo.run")
@@ -96,6 +98,12 @@ module Avo
96
98
  self
97
99
  end
98
100
 
101
+ def visible_in_view
102
+ return true unless visible.present?
103
+
104
+ instance_exec(resource: self.class.resource, view: view, &visible)
105
+ end
106
+
99
107
  def param_id
100
108
  self.class.to_s.demodulize.underscore.tr "/", "_"
101
109
  end
@@ -4,6 +4,14 @@ module Avo
4
4
  extend FieldsCollector
5
5
  extend HasContext
6
6
 
7
+ include ActionView::Helpers::UrlHelper
8
+
9
+ delegate :view_context, to: 'Avo::App'
10
+ delegate :main_app, to: :view_context
11
+ delegate :avo, to: :view_context
12
+ delegate :resource_path, to: :view_context
13
+ delegate :resources_path, to: :view_context
14
+
7
15
  attr_accessor :view
8
16
  attr_accessor :model
9
17
  attr_accessor :user
@@ -74,7 +82,9 @@ module Avo
74
82
  end
75
83
 
76
84
  def initialize
77
- self.class.model_class = model_class
85
+ unless self.class.model_class.present?
86
+ self.class.model_class = model_class.base_class
87
+ end
78
88
  end
79
89
 
80
90
  def hydrate(model: nil, view: nil, user: nil, params: nil)
@@ -198,10 +208,13 @@ module Avo
198
208
  end
199
209
 
200
210
  def model_class
211
+ # get the model class off of the static property
201
212
  return self.class.model_class if self.class.model_class.present?
202
213
 
203
- return @model.class if @model.present?
214
+ # get the model class off of the model
215
+ return @model.base_class if @model.present?
204
216
 
217
+ # generate a model class
205
218
  class_name_without_resource.safe_constantize
206
219
  end
207
220
 
@@ -253,10 +266,6 @@ module Avo
253
266
  view_types
254
267
  end
255
268
 
256
- def route_key
257
- model_class.model_name.route_key
258
- end
259
-
260
269
  def context
261
270
  self.class.context
262
271
  end
@@ -355,8 +364,28 @@ module Avo
355
364
  end
356
365
  end
357
366
 
358
- def avo_path
359
- "#{Avo::App.root_path}/resources/#{model_class.model_name.route_key}/#{model.id}"
367
+ def route_key
368
+ model_class.model_name.route_key
369
+ end
370
+
371
+ # This is used as the model class ID
372
+ # We use this instead of the route_key to maintain compatibility with uncountable models
373
+ # With uncountable models route key appends an _index suffix (Fish->fish_index)
374
+ # Example: User->users, MediaItem->medie_items, Fish->fish
375
+ def model_key
376
+ model_class.model_name.plural
377
+ end
378
+
379
+ def singular_model_key
380
+ model_class.model_name.singular
381
+ end
382
+
383
+ def record_path
384
+ resource_path(model: model, resource: self)
385
+ end
386
+
387
+ def records_path
388
+ resources_path(resource: self)
360
389
  end
361
390
 
362
391
  def label_field
@@ -410,5 +439,9 @@ module Avo
410
439
  rescue
411
440
  nil
412
441
  end
442
+
443
+ def form_scope
444
+ model.class.base_class.to_s.downcase
445
+ end
413
446
  end
414
447
  end
@@ -25,6 +25,8 @@ module Avo
25
25
  attr_accessor :search_debounce
26
26
  attr_accessor :view_component_path
27
27
  attr_accessor :display_license_request_timeout_error
28
+ attr_accessor :current_user_resource_name
29
+ attr_accessor :raise_error_on_missing_policy
28
30
 
29
31
  def initialize
30
32
  @root_path = "/avo"
@@ -62,6 +64,8 @@ module Avo
62
64
  @search_debounce = 300
63
65
  @view_component_path = "app/components"
64
66
  @display_license_request_timeout_error = true
67
+ @current_user_resource_name = "user"
68
+ @raise_error_on_missing_policy = false
65
69
  end
66
70
 
67
71
  def locale_tag
@@ -3,8 +3,14 @@ module Avo
3
3
  class BaseField
4
4
  extend ActiveSupport::DescendantsTracker
5
5
  extend Avo::Fields::FieldExtensions::HasFieldName
6
+
7
+ include ActionView::Helpers::UrlHelper
6
8
  include Avo::Fields::FieldExtensions::VisibleInDifferentViews
7
9
 
10
+ delegate :view_context, to: 'Avo::App'
11
+ delegate :main_app, to: :view_context
12
+ delegate :avo, to: :view_context
13
+
8
14
  attr_reader :id
9
15
  attr_reader :block
10
16
  attr_reader :required
@@ -121,11 +127,11 @@ module Avo
121
127
 
122
128
  # Run callback block if present
123
129
  if computable && block.present?
124
- final_value = block.call @model, @resource, @view, self
130
+ final_value = instance_exec(@model, @resource, @view, self, &block)
125
131
  end
126
132
 
127
133
  # Run the value through resolver if present
128
- final_value = @format_using.call final_value if @format_using.present?
134
+ final_value = instance_exec(final_value, &@format_using) if @format_using.present?
129
135
 
130
136
  final_value
131
137
  end
@@ -25,8 +25,6 @@ module Avo
25
25
  value.each do |file|
26
26
  # Skip empty values
27
27
  next unless file.present?
28
- # Keep only String values
29
- next unless file.class === String
30
28
 
31
29
  model.send(key).attach file
32
30
  end
@@ -1,6 +1,6 @@
1
1
  module Avo
2
2
  module Fields
3
- class HasAndBelongsToManyField < BaseField
3
+ class HasAndBelongsToManyField < HasBaseField
4
4
  def initialize(id, **args, &block)
5
5
  args[:updatable] = false
6
6
 
@@ -13,24 +13,6 @@ module Avo
13
13
  def view_component_name
14
14
  "HasManyField"
15
15
  end
16
-
17
- def turbo_frame
18
- "#{self.class.name.demodulize.to_s.underscore}_#{id}"
19
- end
20
-
21
- def frame_url
22
- "#{Avo::App.root_path}/resources/#{@model.model_name.route_key}/#{@model.id}/#{id}?turbo_frame=#{turbo_frame}"
23
- end
24
-
25
- def target_resource
26
- if @model._reflections[id.to_s].klass.present?
27
- Avo::App.get_resource_by_model_name @model._reflections[id.to_s].klass.to_s
28
- elsif @model._reflections[id.to_s].options[:class_name].present?
29
- Avo::App.get_resource_by_model_name @model._reflections[id.to_s].options[:class_name]
30
- else
31
- Avo::App.get_resource_by_name id.to_s
32
- end
33
- end
34
16
  end
35
17
  end
36
18
  end
@@ -0,0 +1,35 @@
1
+ module Avo
2
+ module Fields
3
+ class HasBaseField < BaseField
4
+ attr_accessor :display
5
+
6
+ def initialize(id, **args, &block)
7
+ super(id, **args, &block)
8
+
9
+ @display = args[:display].present? ? args[:display] : :show
10
+ end
11
+
12
+ def resource
13
+ Avo::App.get_resource_by_model_name @model.class
14
+ end
15
+
16
+ def turbo_frame
17
+ "#{self.class.name.demodulize.to_s.underscore}_#{display}_#{id}"
18
+ end
19
+
20
+ def frame_url
21
+ "#{@resource.record_path}/#{id}?turbo_frame=#{turbo_frame}"
22
+ end
23
+
24
+ def target_resource
25
+ if @model._reflections[id.to_s].klass.present?
26
+ Avo::App.get_resource_by_model_name @model._reflections[id.to_s].klass.to_s
27
+ elsif @model._reflections[id.to_s].options[:class_name].present?
28
+ Avo::App.get_resource_by_model_name @model._reflections[id.to_s].options[:class_name]
29
+ else
30
+ Avo::App.get_resource_by_name id.to_s
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,6 +1,6 @@
1
1
  module Avo
2
2
  module Fields
3
- class HasManyField < BaseField
3
+ class HasManyField < HasBaseField
4
4
  def initialize(id, **args, &block)
5
5
  args[:updatable] = false
6
6
 
@@ -9,24 +9,6 @@ module Avo
9
9
  hide_on :all
10
10
  show_on :show
11
11
  end
12
-
13
- def turbo_frame
14
- "#{self.class.name.demodulize.to_s.underscore}_#{id}"
15
- end
16
-
17
- def frame_url
18
- "#{Avo::App.root_path}/resources/#{@model.model_name.route_key}/#{@model.id}/#{id}?turbo_frame=#{turbo_frame}"
19
- end
20
-
21
- def target_resource
22
- if @model._reflections[id.to_s].klass.present?
23
- Avo::App.get_resource_by_model_name @model._reflections[id.to_s].klass.to_s
24
- elsif @model._reflections[id.to_s].options[:class_name].present?
25
- Avo::App.get_resource_by_model_name @model._reflections[id.to_s].options[:class_name]
26
- else
27
- Avo::App.get_resource_by_name id.to_s
28
- end
29
- end
30
12
  end
31
13
  end
32
14
  end
@@ -1,8 +1,7 @@
1
1
  module Avo
2
2
  module Fields
3
- class HasOneField < BaseField
3
+ class HasOneField < HasBaseField
4
4
  attr_accessor :relation_method
5
- attr_accessor :display
6
5
 
7
6
  def initialize(id, **args, &block)
8
7
  super(id, **args, &block)
@@ -12,7 +11,6 @@ module Avo
12
11
  @placeholder ||= I18n.t "avo.choose_an_option"
13
12
 
14
13
  @relation_method = name.to_s.parameterize.underscore
15
- @display = args[:display].present? ? args[:display] : :show
16
14
  end
17
15
 
18
16
  def label
@@ -20,25 +18,11 @@ module Avo
20
18
  end
21
19
 
22
20
  def resource
23
- target_resource
24
- end
25
-
26
- def turbo_frame
27
- "#{self.class.name.demodulize.to_s.underscore}_#{display}_#{id}"
21
+ Avo::App.get_resource_by_model_name @model.class
28
22
  end
29
23
 
30
24
  def frame_url
31
- "#{Avo::App.root_path}/resources/#{@model.model_name.route_key}/#{@model.id}/#{id}/#{value.id}?turbo_frame=#{turbo_frame}"
32
- end
33
-
34
- def target_resource
35
- if @model._reflections[id.to_s].klass.present?
36
- Avo::App.get_resource_by_model_name @model._reflections[id.to_s].klass.to_s
37
- elsif @model._reflections[id.to_s].options[:class_name].present?
38
- Avo::App.get_resource_by_model_name @model._reflections[id.to_s].options[:class_name]
39
- else
40
- Avo::App.get_resource_by_name id.to_s
41
- end
25
+ "#{@resource.record_path}/#{id}/#{value.id}?turbo_frame=#{turbo_frame}"
42
26
  end
43
27
 
44
28
  def fill_field(model, key, value, params)
@@ -2,11 +2,13 @@ module Avo
2
2
  module Fields
3
3
  class TextField < BaseField
4
4
  attr_reader :link_to_resource
5
+ attr_reader :as_html
5
6
 
6
7
  def initialize(id, **args, &block)
7
8
  super(id, **args, &block)
8
9
 
9
10
  @link_to_resource = args[:link_to_resource].present? ? args[:link_to_resource] : false
11
+ @as_html = args[:as_html].present? ? args[:as_html] : false
10
12
  end
11
13
  end
12
14
  end
@@ -48,8 +48,10 @@ module Avo
48
48
  end
49
49
 
50
50
  true
51
- rescue Pundit::NotDefinedError
52
- false
51
+ rescue Pundit::NotDefinedError => e
52
+ return false unless Avo.configuration.raise_error_on_missing_policy
53
+
54
+ raise e
53
55
  rescue => error
54
56
  if args[:raise_exception] == false
55
57
  false
@@ -73,8 +75,10 @@ module Avo
73
75
 
74
76
  begin
75
77
  Pundit.policy_scope! user, model
76
- rescue
77
- model
78
+ rescue Pundit::NotDefinedError => e
79
+ return model unless Avo.configuration.raise_error_on_missing_policy
80
+
81
+ raise e
78
82
  end
79
83
  end
80
84
 
data/lib/avo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "1.18.0"
2
+ VERSION = "1.19.0"
3
3
  end
@@ -84,3 +84,5 @@ en:
84
84
  placeholder: 'Search'
85
85
  cancel_button: 'Cancel'
86
86
  sign_out: 'Sign out'
87
+ failed: 'Failed'
88
+ failed_to_load: 'Failed to load'
@@ -3258,6 +3258,43 @@ input[type=file][data-direct-upload-url][disabled] {
3258
3258
  display: none;
3259
3259
  }
3260
3260
 
3261
+ .button-spinner {
3262
+ width: 24px;
3263
+ height: 24px;
3264
+
3265
+ position: relative;
3266
+ margin: 100px auto;
3267
+ }
3268
+
3269
+ .button-spinner > .double-bounce1,
3270
+ .button-spinner > .double-bounce2 {
3271
+ width: 100%;
3272
+ height: 100%;
3273
+ border-radius: 50%;
3274
+ background-color: #333;
3275
+ opacity: 0.5;
3276
+ position: absolute;
3277
+ top: 0;
3278
+ left: 0;
3279
+ animation: sk-bounce 2s infinite ease-in-out;
3280
+ }
3281
+
3282
+ .button-spinner > .double-bounce2 {
3283
+ animation-delay: -1s;
3284
+ }
3285
+
3286
+ @keyframes sk-bounce {
3287
+ 0%,
3288
+ 100% {
3289
+ transform: scale(0);
3290
+ -webkit-transform: scale(0);
3291
+ }
3292
+ 50% {
3293
+ transform: scale(1);
3294
+ -webkit-transform: scale(1);
3295
+ }
3296
+ }
3297
+
3261
3298
  .spinner {
3262
3299
  width: 16px;
3263
3300
  height: 16px;
@@ -3265,8 +3302,8 @@ input[type=file][data-direct-upload-url][disabled] {
3265
3302
  position: relative;
3266
3303
  }
3267
3304
 
3268
-
3269
- .double-bounce1, .double-bounce2 {
3305
+ .spinner .double-bounce1,
3306
+ .spinner .double-bounce2 {
3270
3307
  width: 100%;
3271
3308
  height: 100%;
3272
3309
  border-radius: 50%;
@@ -3275,20 +3312,22 @@ input[type=file][data-direct-upload-url][disabled] {
3275
3312
  position: absolute;
3276
3313
  top: 0;
3277
3314
  left: 0;
3278
- animation: sk-bounce 2.0s infinite ease-in-out;
3315
+ animation: sk-bounce 2s infinite ease-in-out;
3279
3316
  }
3280
3317
 
3281
- .double-bounce2 {
3282
- animation-delay: -1.0s;
3318
+ .spinner .double-bounce2 {
3319
+ animation-delay: -1s;
3283
3320
  }
3284
3321
 
3285
3322
  @keyframes sk-bounce {
3286
- 0%, 100% {
3287
- transform: scale(0.0);
3288
- -webkit-transform: scale(0.0);
3289
- } 50% {
3290
- transform: scale(1.0);
3291
- -webkit-transform: scale(1.0);
3323
+ 0%,
3324
+ 100% {
3325
+ transform: scale(0);
3326
+ -webkit-transform: scale(0);
3327
+ }
3328
+ 50% {
3329
+ transform: scale(1);
3330
+ -webkit-transform: scale(1);
3292
3331
  }
3293
3332
  }
3294
3333
 
@@ -4997,6 +5036,9 @@ progress[value]::-moz-progress-bar {
4997
5036
  .h-8 {
4998
5037
  height: 2rem
4999
5038
  }
5039
+ .h-40 {
5040
+ height: 10rem
5041
+ }
5000
5042
  .h-full {
5001
5043
  height: 100%
5002
5044
  }
@@ -6284,4 +6326,4 @@ html, body{
6284
6326
  }
6285
6327
 
6286
6328
 
6287
- /*# sourceMappingURL=application-f9191617.css.map*/
6329
+ /*# sourceMappingURL=application-c3b50b28.css.map*/