avo 1.17.1 → 1.18.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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +13 -13
  4. data/app/components/avo/fields/common/multiple_file_viewer_component.rb +2 -1
  5. data/app/components/avo/fields/common/single_file_viewer_component.rb +2 -1
  6. data/app/components/avo/fields/file_field/edit_component.html.erb +1 -1
  7. data/app/components/avo/fields/files_field/edit_component.html.erb +3 -1
  8. data/app/packs/entrypoints/application.css +1 -0
  9. data/app/packs/entrypoints/application.js +3 -0
  10. data/app/packs/js/active-storage.js +45 -0
  11. data/app/packs/stylesheets/active-storage.css +37 -0
  12. data/config/routes.rb +1 -0
  13. data/lib/avo/app.rb +2 -2
  14. data/lib/avo/engine.rb +5 -1
  15. data/lib/avo/fields/date_time_field.rb +1 -1
  16. data/lib/avo/fields/file_field.rb +2 -0
  17. data/lib/avo/fields/files_field.rb +7 -0
  18. data/lib/avo/version.rb +1 -1
  19. data/lib/generators/avo/templates/filters/boolean_filter.tt +1 -1
  20. data/public/avo-packs/css/{application-2b4685ca.css → application-f9191617.css} +39 -1
  21. data/public/avo-packs/css/application-f9191617.css.br +0 -0
  22. data/public/avo-packs/css/application-f9191617.css.gz +0 -0
  23. data/public/avo-packs/css/application-f9191617.css.map +1 -0
  24. data/public/avo-packs/css/application-f9191617.css.map.br +0 -0
  25. data/public/avo-packs/css/application-f9191617.css.map.gz +0 -0
  26. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js +26 -0
  27. data/public/avo-packs/js/{application-1f1c66b45a54b2d06bfe.js.LICENSE.txt → application-cc89f096028eb1d4d971.js.LICENSE.txt} +0 -0
  28. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.br +0 -0
  29. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.gz +0 -0
  30. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.map +1 -0
  31. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.map.br +0 -0
  32. data/public/avo-packs/js/application-cc89f096028eb1d4d971.js.map.gz +0 -0
  33. data/public/avo-packs/manifest.json +15 -15
  34. metadata +17 -15
  35. data/public/avo-packs/css/application-2b4685ca.css.br +0 -0
  36. data/public/avo-packs/css/application-2b4685ca.css.gz +0 -0
  37. data/public/avo-packs/css/application-2b4685ca.css.map +0 -1
  38. data/public/avo-packs/css/application-2b4685ca.css.map.br +0 -0
  39. data/public/avo-packs/css/application-2b4685ca.css.map.gz +0 -0
  40. data/public/avo-packs/js/application-1f1c66b45a54b2d06bfe.js +0 -26
  41. data/public/avo-packs/js/application-1f1c66b45a54b2d06bfe.js.br +0 -0
  42. data/public/avo-packs/js/application-1f1c66b45a54b2d06bfe.js.gz +0 -0
  43. data/public/avo-packs/js/application-1f1c66b45a54b2d06bfe.js.map +0 -1
  44. data/public/avo-packs/js/application-1f1c66b45a54b2d06bfe.js.map.br +0 -0
  45. data/public/avo-packs/js/application-1f1c66b45a54b2d06bfe.js.map.gz +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f979b13adfa02e58a8d2b3b4f6463d0fcef9200cdc4a4dee76b268ebc5a5e8b0
4
- data.tar.gz: acdddcbb5516ffd36f1538877472f4f8a4ec5f2423a4ddea69b7eed5b156c308
3
+ metadata.gz: f0537914efac67cf9b88d78b687484938f146e5e0941fbace1a7d8fb507c115f
4
+ data.tar.gz: 15e9f8ebdf9b38aaf727154852f9ebf03d56447fc1d47dfa6fab9131557df4ee
5
5
  SHA512:
6
- metadata.gz: '050786326a44c661a9c3467cf9f5b3ed5df27a8b713040a9126be15f96b3fcf553b8cd7c7f23fe01339665eac1f41d2a203fca4c3c671676c28b9c6efaf18cb9'
7
- data.tar.gz: 417a94817cdad9255904bbff41dc5aa911b2dfa02c31ac2f1d2deb46c6038e7a563d802ad0d2b4533e6001e06d455b2fd9cf48a47c2556539e143f48b95ff6ee
6
+ metadata.gz: 5d862bdd263cc44b4e0832e2aeb8bbd3a086a8dd7f8eb9d730401bf5fe809aec7aef021fd449fe7251f75c79648a62c3454c6554bf01948db58f03e974c4a165
7
+ data.tar.gz: ba4787b27586038cfce9d08f7bac3e9143a81c38f978b2c5aa32a48d32bbcf0aee9383e87154f24f243dab74b959a5d33cbc435115a8e39e4660879a69048945
data/Gemfile CHANGED
@@ -115,7 +115,7 @@ gem "hotwire-rails"
115
115
 
116
116
  gem "active_link_to"
117
117
 
118
- gem "view_component", require: "view_component/engine"
118
+ gem "view_component"
119
119
 
120
120
  gem "addressable"
121
121
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- avo (1.17.1)
4
+ avo (1.18.0)
5
5
  active_link_to
6
6
  addressable
7
7
  breadcrumbs_on_rails
@@ -107,7 +107,7 @@ GEM
107
107
  aws-eventstream (~> 1, >= 1.0.2)
108
108
  bcrypt (3.1.16)
109
109
  bindex (0.8.1)
110
- bootsnap (1.7.3)
110
+ bootsnap (1.9.3)
111
111
  msgpack (~> 1.0)
112
112
  breadcrumbs_on_rails (4.0.0)
113
113
  rails (>= 5.0)
@@ -123,7 +123,7 @@ GEM
123
123
  regexp_parser (~> 1.5)
124
124
  xpath (~> 3.2)
125
125
  childprocess (3.0.0)
126
- concurrent-ruby (1.1.8)
126
+ concurrent-ruby (1.1.9)
127
127
  countries (3.1.0)
128
128
  i18n_data (~> 0.11.0)
129
129
  sixarm_ruby_unaccent (~> 1.1)
@@ -131,7 +131,7 @@ GEM
131
131
  crack (0.4.4)
132
132
  crass (1.0.6)
133
133
  database_cleaner (1.8.5)
134
- devise (4.7.3)
134
+ devise (4.8.1)
135
135
  bcrypt (~> 3.0)
136
136
  orm_adapter (~> 0.1)
137
137
  railties (>= 4.1.0)
@@ -168,7 +168,7 @@ GEM
168
168
  httparty (0.18.1)
169
169
  mime-types (~> 3.0)
170
170
  multi_xml (>= 0.5.2)
171
- i18n (1.8.10)
171
+ i18n (1.8.11)
172
172
  concurrent-ruby (~> 1.0)
173
173
  i18n_data (0.11.0)
174
174
  image_processing (1.12.1)
@@ -184,7 +184,7 @@ GEM
184
184
  listen (3.5.1)
185
185
  rb-fsevent (~> 0.10, >= 0.10.3)
186
186
  rb-inotify (~> 0.9, >= 0.9.10)
187
- loofah (2.9.1)
187
+ loofah (2.13.0)
188
188
  crass (~> 1.0.2)
189
189
  nokogiri (>= 1.5.9)
190
190
  mail (2.7.1)
@@ -202,7 +202,7 @@ GEM
202
202
  mini_magick (4.11.0)
203
203
  mini_mime (1.0.3)
204
204
  mini_portile2 (2.6.1)
205
- minitest (5.14.4)
205
+ minitest (5.15.0)
206
206
  msgpack (1.4.2)
207
207
  multi_xml (0.6.0)
208
208
  nio4r (2.5.8)
@@ -210,7 +210,7 @@ GEM
210
210
  mini_portile2 (~> 2.6.1)
211
211
  racc (~> 1.4)
212
212
  orm_adapter (0.5.0)
213
- pagy (4.11.0)
213
+ pagy (5.6.10)
214
214
  parallel (1.20.1)
215
215
  parser (3.0.0.0)
216
216
  ast (~> 2.4.1)
@@ -220,7 +220,7 @@ GEM
220
220
  nio4r (~> 2.0)
221
221
  pundit (2.1.0)
222
222
  activesupport (>= 3.0.0)
223
- racc (1.5.2)
223
+ racc (1.6.0)
224
224
  rack (2.2.3)
225
225
  rack-proxy (0.6.5)
226
226
  rack
@@ -248,7 +248,7 @@ GEM
248
248
  rails-dom-testing (2.0.3)
249
249
  activesupport (>= 4.2.0)
250
250
  nokogiri (>= 1.6)
251
- rails-html-sanitizer (1.3.0)
251
+ rails-html-sanitizer (1.4.2)
252
252
  loofah (~> 2.3)
253
253
  railties (6.1.3.2)
254
254
  actionpack (= 6.1.3.2)
@@ -257,7 +257,7 @@ GEM
257
257
  rake (>= 0.8.7)
258
258
  thor (~> 1.0)
259
259
  rainbow (3.0.0)
260
- rake (13.0.3)
260
+ rake (13.0.6)
261
261
  ransack (2.4.2)
262
262
  activerecord (>= 5.2.4)
263
263
  activesupport (>= 5.2.4)
@@ -379,7 +379,7 @@ GEM
379
379
  websocket-extensions (0.1.5)
380
380
  xpath (3.2.0)
381
381
  nokogiri (~> 1.8)
382
- zeitwerk (2.4.2)
382
+ zeitwerk (2.5.2)
383
383
 
384
384
  PLATFORMS
385
385
  ruby
@@ -439,4 +439,4 @@ DEPENDENCIES
439
439
  zeitwerk (~> 2.3)
440
440
 
441
441
  BUNDLED WITH
442
- 2.2.29
442
+ 2.2.32
@@ -3,10 +3,11 @@
3
3
  class Avo::Fields::Common::MultipleFileViewerComponent < ViewComponent::Base
4
4
  include Avo::ApplicationHelper
5
5
 
6
- def initialize(id:, file:, is_image:, resource:, button_size: :md)
6
+ def initialize(id:, file:, is_image:, direct_upload: false, resource:, button_size: :md)
7
7
  @id = id
8
8
  @file = file
9
9
  @is_image = is_image
10
+ @direct_upload = direct_upload
10
11
  @button_size = button_size
11
12
  @resource = resource
12
13
  end
@@ -3,10 +3,11 @@
3
3
  class Avo::Fields::Common::SingleFileViewerComponent < ViewComponent::Base
4
4
  include Avo::ApplicationHelper
5
5
 
6
- def initialize(id:, file:, is_image:, resource:, button_size: :md)
6
+ def initialize(id:, file:, is_image:, direct_upload: false, resource:, button_size: :md)
7
7
  @id = id
8
8
  @file = file
9
9
  @is_image = is_image
10
+ @direct_upload = direct_upload
10
11
  @button_size = button_size
11
12
  @resource = resource
12
13
  end
@@ -6,6 +6,6 @@
6
6
  <% end %>
7
7
 
8
8
  <% if @resource.authorization.authorize_action(:upload_attachments?, raise_exception: false) %>
9
- <%= @form.file_field @field.id, disabled: @field.readonly %>
9
+ <%= @form.file_field @field.id, disabled: @field.readonly, direct_upload: @field.direct_upload %>
10
10
  <% end %>
11
11
  <% end %>
@@ -2,6 +2,8 @@
2
2
  <%= render Avo::Fields::Common::FilesListViewerComponent.new(field: @field, resource: @resource) if @field.value.present? %>
3
3
 
4
4
  <% if @resource.authorization.authorize_action(:upload_attachments?, raise_exception: false) %>
5
- <%= @form.file_field @field.id, disabled: @field.readonly, multiple: true %>
5
+ <div class="mt-2">
6
+ <%= @form.file_field @field.id, disabled: @field.readonly, multiple: true, direct_upload: @field.direct_upload %>
7
+ </div>
6
8
  <% end %>
7
9
  <% end %>
@@ -16,6 +16,7 @@
16
16
  @import './../stylesheets/pagination.css';
17
17
  @import './../stylesheets/breadcrumbs.css';
18
18
  @import './../stylesheets/search.css';
19
+ @import './../stylesheets/active-storage.css';
19
20
 
20
21
  @import './../stylesheets/components/status.css';
21
22
  @import './../stylesheets/components/code.css';
@@ -2,6 +2,7 @@
2
2
  import 'core-js/stable'
3
3
  // eslint-disable-next-line import/no-extraneous-dependencies
4
4
  import 'regenerator-runtime/runtime'
5
+ import * as ActiveStorage from '@rails/activestorage'
5
6
  import * as Mousetrap from 'mousetrap'
6
7
  import { Application } from 'stimulus'
7
8
  import { Turbo } from '@hotwired/turbo-rails'
@@ -10,6 +11,7 @@ import Rails from '@rails/ujs'
10
11
  import tippy from 'tippy.js'
11
12
 
12
13
  // Toastr alerts
14
+ import '../js/active-storage'
13
15
  import '../js/toastr'
14
16
 
15
17
  Rails.start()
@@ -32,6 +34,7 @@ function initTippy() {
32
34
  window.initTippy = initTippy
33
35
 
34
36
  const application = Application.start()
37
+ ActiveStorage.start()
35
38
 
36
39
  const context = require.context('./../js/controllers', true, /\.js$/)
37
40
  application.load(definitionsFromContext(context))
@@ -0,0 +1,45 @@
1
+ document.addEventListener('direct-upload:initialize', (event) => {
2
+ const { target, detail } = event
3
+ const { id, file } = detail
4
+
5
+ target.insertAdjacentHTML(
6
+ 'beforebegin',
7
+ `
8
+ <div id="direct-upload-${id}" class="direct-upload direct-upload--pending">
9
+ <div id="direct-upload-progress-${id}" class="direct-upload__progress" style="width: 0%"></div>
10
+ <span class="direct-upload__filename"></span>
11
+ </div>
12
+ `,
13
+ )
14
+ target.previousElementSibling.querySelector(
15
+ '.direct-upload__filename',
16
+ ).textContent = file.name
17
+ })
18
+
19
+ document.addEventListener('direct-upload:start', (event) => {
20
+ const { id } = event.detail
21
+ const element = document.getElementById(`direct-upload-${id}`)
22
+ element.classList.remove('direct-upload--pending')
23
+ })
24
+
25
+ document.addEventListener('direct-upload:progress', (event) => {
26
+ const { id, progress } = event.detail
27
+ const progressElement = document.getElementById(
28
+ `direct-upload-progress-${id}`,
29
+ )
30
+ progressElement.style.width = `${progress}%`
31
+ })
32
+
33
+ document.addEventListener('direct-upload:error', (event) => {
34
+ event.preventDefault()
35
+ const { id, error } = event.detail
36
+ const element = document.getElementById(`direct-upload-${id}`)
37
+ element.classList.add('direct-upload--error')
38
+ element.setAttribute('title', error)
39
+ })
40
+
41
+ document.addEventListener('direct-upload:end', (event) => {
42
+ const { id } = event.detail
43
+ const element = document.getElementById(`direct-upload-${id}`)
44
+ element.classList.add('direct-upload--complete')
45
+ })
@@ -0,0 +1,37 @@
1
+ .direct-upload {
2
+ display: inline-block;
3
+ position: relative;
4
+ padding: 2px 4px;
5
+ margin: 0 3px 3px 0;
6
+ border: 1px solid rgba(0, 0, 0, 0.3);
7
+ border-radius: 3px;
8
+ font-size: 11px;
9
+ line-height: 13px;
10
+ }
11
+
12
+ .direct-upload--pending {
13
+ opacity: 0.6;
14
+ }
15
+
16
+ .direct-upload__progress {
17
+ position: absolute;
18
+ top: 0;
19
+ left: 0;
20
+ bottom: 0;
21
+ opacity: 0.2;
22
+ background: #0076ff;
23
+ transition: width 120ms ease-out, opacity 60ms 60ms ease-in;
24
+ transform: translate3d(0, 0, 0);
25
+ }
26
+
27
+ .direct-upload--complete .direct-upload__progress {
28
+ opacity: 0.4;
29
+ }
30
+
31
+ .direct-upload--error {
32
+ border-color: red;
33
+ }
34
+
35
+ input[type=file][data-direct-upload-url][disabled] {
36
+ display: none;
37
+ }
data/config/routes.rb CHANGED
@@ -2,6 +2,7 @@ Avo::Engine.routes.draw do
2
2
  root "home#index"
3
3
 
4
4
  get "resources", to: redirect("/admin")
5
+ post "/rails/active_storage/direct_uploads", to: "/active_storage/direct_uploads#create"
5
6
 
6
7
  scope "avo_api", as: "avo_api" do
7
8
  get "/search", to: "search#index"
data/lib/avo/app.rb CHANGED
@@ -32,9 +32,9 @@ module Avo
32
32
 
33
33
  # Set the current host for ActiveStorage
34
34
  begin
35
- ActiveStorage::Current.host = request.base_url
35
+ ActiveStorage::Current.url_options = request.base_url
36
36
  rescue => exception
37
- Rails.logger.debug "[Avo] Failed to set ActiveStorage::Current.host, #{exception.inspect}"
37
+ Rails.logger.debug "[Avo] Failed to set ActiveStorage::Current.url_options, #{exception.inspect}"
38
38
  end
39
39
 
40
40
  init_resources
data/lib/avo/engine.rb CHANGED
@@ -2,7 +2,11 @@
2
2
  Gem.loaded_specs["avo"].dependencies.each do |d|
3
3
  require d.name
4
4
  end
5
- require "view_component/engine"
5
+
6
+ # In development we should load the engine so we get the autoload for components
7
+ if ENV["RAILS_ENV"] === "development"
8
+ require "view_component/engine"
9
+ end
6
10
 
7
11
  module Avo
8
12
  class Engine < ::Rails::Engine
@@ -17,7 +17,7 @@ module Avo
17
17
  return nil if value.nil?
18
18
 
19
19
  if @format.is_a?(Symbol)
20
- value.to_time.in_time_zone(timezone).to_s(@format)
20
+ value.to_time.in_time_zone(timezone).to_formatted_s(@format)
21
21
  else
22
22
  value.to_time.in_time_zone(timezone).strftime(@format)
23
23
  end
@@ -4,6 +4,7 @@ module Avo
4
4
  attr_accessor :link_to_resource
5
5
  attr_accessor :is_avatar
6
6
  attr_accessor :is_image
7
+ attr_accessor :direct_upload
7
8
 
8
9
  def initialize(id, **args, &block)
9
10
  super(id, **args, &block)
@@ -11,6 +12,7 @@ module Avo
11
12
  @link_to_resource = args[:link_to_resource].present? ? args[:link_to_resource] : false
12
13
  @is_avatar = args[:is_avatar].present? ? args[:is_avatar] : false
13
14
  @is_image = args[:is_image].present? ? args[:is_image] : @is_avatar
15
+ @direct_upload = args[:direct_upload].present? ? args[:direct_upload] : false
14
16
  end
15
17
 
16
18
  def path
@@ -2,11 +2,13 @@ module Avo
2
2
  module Fields
3
3
  class FilesField < BaseField
4
4
  attr_accessor :is_image
5
+ attr_accessor :direct_upload
5
6
 
6
7
  def initialize(id, **args, &block)
7
8
  super(id, **args, &block)
8
9
 
9
10
  @is_image = args[:is_image].present? ? args[:is_image] : @is_avatar
11
+ @direct_upload = args[:direct_upload].present? ? args[:direct_upload] : false
10
12
  end
11
13
 
12
14
  def view_component_name
@@ -21,6 +23,11 @@ module Avo
21
23
  return model unless model.methods.include? key.to_sym
22
24
 
23
25
  value.each do |file|
26
+ # Skip empty values
27
+ next unless file.present?
28
+ # Keep only String values
29
+ next unless file.class === String
30
+
24
31
  model.send(key).attach file
25
32
  end
26
33
 
data/lib/avo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "1.17.1"
2
+ VERSION = "1.18.0"
3
3
  end
@@ -1,7 +1,7 @@
1
1
  class <%= class_name.camelize %> < Avo::Filters::BooleanFilter
2
2
  self.name = '<%= name.underscore.humanize %>'
3
3
 
4
- def apply(request, query, value)
4
+ def apply(request, query, values)
5
5
  query
6
6
  end
7
7
 
@@ -3220,6 +3220,44 @@ svg.tea #steamR {
3220
3220
  color: rgba(255, 255, 255, var(--tw-text-opacity));
3221
3221
  }
3222
3222
 
3223
+ .direct-upload {
3224
+ display: inline-block;
3225
+ position: relative;
3226
+ padding: 2px 4px;
3227
+ margin: 0 3px 3px 0;
3228
+ border: 1px solid rgba(0, 0, 0, 0.3);
3229
+ border-radius: 3px;
3230
+ font-size: 11px;
3231
+ line-height: 13px;
3232
+ }
3233
+
3234
+ .direct-upload--pending {
3235
+ opacity: 0.6;
3236
+ }
3237
+
3238
+ .direct-upload__progress {
3239
+ position: absolute;
3240
+ top: 0;
3241
+ left: 0;
3242
+ bottom: 0;
3243
+ opacity: 0.2;
3244
+ background: #0076ff;
3245
+ transition: width 120ms ease-out, opacity 60ms 60ms ease-in;
3246
+ transform: translate3d(0, 0, 0);
3247
+ }
3248
+
3249
+ .direct-upload--complete .direct-upload__progress {
3250
+ opacity: 0.4;
3251
+ }
3252
+
3253
+ .direct-upload--error {
3254
+ border-color: red;
3255
+ }
3256
+
3257
+ input[type=file][data-direct-upload-url][disabled] {
3258
+ display: none;
3259
+ }
3260
+
3223
3261
  .spinner {
3224
3262
  width: 16px;
3225
3263
  height: 16px;
@@ -6246,4 +6284,4 @@ html, body{
6246
6284
  }
6247
6285
 
6248
6286
 
6249
- /*# sourceMappingURL=application-2b4685ca.css.map*/
6287
+ /*# sourceMappingURL=application-f9191617.css.map*/