avo 2.27.2.pre.pr1606 → 2.28.1.pre.pr1642

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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +73 -73
  3. data/README.md +23 -9
  4. data/app/components/avo/fields/common/single_file_viewer_component.html.erb +2 -2
  5. data/app/components/avo/fields/common/single_file_viewer_component.rb +3 -2
  6. data/app/components/avo/fields/file_field/edit_component.html.erb +3 -1
  7. data/app/components/avo/fields/file_field/edit_component.rb +1 -0
  8. data/app/components/avo/fields/files_field/edit_component.html.erb +3 -1
  9. data/app/components/avo/fields/files_field/edit_component.rb +1 -0
  10. data/app/components/avo/views/resource_index_component.html.erb +1 -1
  11. data/app/components/avo/views/resource_index_component.rb +12 -3
  12. data/app/controllers/avo/application_controller.rb +6 -2
  13. data/app/controllers/avo/attachments_controller.rb +10 -0
  14. data/app/controllers/avo/search_controller.rb +9 -2
  15. data/app/views/avo/partials/_javascript.html.erb +1 -1
  16. data/lib/avo/base_resource.rb +1 -0
  17. data/lib/avo/engine.rb +2 -0
  18. data/lib/avo/fields/belongs_to_field.rb +5 -0
  19. data/lib/avo/fields/concerns/file_authorization.rb +31 -0
  20. data/lib/avo/fields/concerns/use_resource.rb +13 -0
  21. data/lib/avo/fields/date_field.rb +16 -3
  22. data/lib/avo/fields/has_base_field.rb +2 -4
  23. data/lib/avo/fields/tags_field.rb +11 -0
  24. data/lib/avo/hosts/base_host.rb +2 -0
  25. data/lib/avo/services/authorization_service.rb +8 -0
  26. data/lib/avo/version.rb +1 -1
  27. data/lib/generators/avo/resource_generator.rb +16 -1
  28. data/lib/generators/avo/templates/initializer/avo.tt +1 -1
  29. data/lib/generators/avo/templates/locales/avo.ar.yml +126 -0
  30. data/public/avo-assets/avo.base.js +98 -98
  31. data/public/avo-assets/avo.base.js.map +2 -2
  32. metadata +5 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 161deecc8d313c1254a3be834d954d88d6a20b5d9d9ba68f17b38eed7eb05de7
4
- data.tar.gz: 9f78a084bf9129ed2789c412ed9836d940f372563d8a0ae715df52e3edce0874
3
+ metadata.gz: d3bb2ce2c32ddbba4f8bbeb6106e8bba29345090ccb6fb373372bd8d23afa5cf
4
+ data.tar.gz: 6230460ca9c90b5195b384df63d96feac645e863c3821648425eb7ee2d108c11
5
5
  SHA512:
6
- metadata.gz: 3dd2b783c45b8d836c0715e8677dbcd253d94ac9f59ef3ee9f230464564915bc2730b35e77e2a60626db2fe0131fdbb9f9b467205e66528926392bc5e6376b73
7
- data.tar.gz: 4cc9d8b35be4eebec0323721dce5573ba74e5a2dc2bbbbf16d0a2c0634ecc21b1b20f9ef3e272a3eaf50733694c62437905d94fdd0578cef2032df087474152f
6
+ metadata.gz: 0d91aceda8772221c07996c3c1538b378451a8cf0726ad93ef593394335d833070135ef5412fdc40f09024805c2c05582a70d7cca481ee0e28d03aacd350ac5d
7
+ data.tar.gz: 5f7a86dc730ddb524274a91d0ec6781e02b9e2a93867c02e798f70c838081305140f5a70fdab806c023fed3ec91e018759a86f74eb639b47dd7f83f74c5c9fd4
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- avo (2.27.2.pre.pr1606)
4
+ avo (2.28.1.pre.pr1642)
5
5
  actionview (>= 6.0)
6
6
  active_link_to
7
7
  activerecord (>= 6.0)
@@ -19,40 +19,40 @@ PATH
19
19
  GEM
20
20
  remote: https://rubygems.org/
21
21
  specs:
22
- actioncable (6.1.7.2)
23
- actionpack (= 6.1.7.2)
24
- activesupport (= 6.1.7.2)
22
+ actioncable (6.1.7.3)
23
+ actionpack (= 6.1.7.3)
24
+ activesupport (= 6.1.7.3)
25
25
  nio4r (~> 2.0)
26
26
  websocket-driver (>= 0.6.1)
27
- actionmailbox (6.1.7.2)
28
- actionpack (= 6.1.7.2)
29
- activejob (= 6.1.7.2)
30
- activerecord (= 6.1.7.2)
31
- activestorage (= 6.1.7.2)
32
- activesupport (= 6.1.7.2)
27
+ actionmailbox (6.1.7.3)
28
+ actionpack (= 6.1.7.3)
29
+ activejob (= 6.1.7.3)
30
+ activerecord (= 6.1.7.3)
31
+ activestorage (= 6.1.7.3)
32
+ activesupport (= 6.1.7.3)
33
33
  mail (>= 2.7.1)
34
- actionmailer (6.1.7.2)
35
- actionpack (= 6.1.7.2)
36
- actionview (= 6.1.7.2)
37
- activejob (= 6.1.7.2)
38
- activesupport (= 6.1.7.2)
34
+ actionmailer (6.1.7.3)
35
+ actionpack (= 6.1.7.3)
36
+ actionview (= 6.1.7.3)
37
+ activejob (= 6.1.7.3)
38
+ activesupport (= 6.1.7.3)
39
39
  mail (~> 2.5, >= 2.5.4)
40
40
  rails-dom-testing (~> 2.0)
41
- actionpack (6.1.7.2)
42
- actionview (= 6.1.7.2)
43
- activesupport (= 6.1.7.2)
41
+ actionpack (6.1.7.3)
42
+ actionview (= 6.1.7.3)
43
+ activesupport (= 6.1.7.3)
44
44
  rack (~> 2.0, >= 2.0.9)
45
45
  rack-test (>= 0.6.3)
46
46
  rails-dom-testing (~> 2.0)
47
47
  rails-html-sanitizer (~> 1.0, >= 1.2.0)
48
- actiontext (6.1.7.2)
49
- actionpack (= 6.1.7.2)
50
- activerecord (= 6.1.7.2)
51
- activestorage (= 6.1.7.2)
52
- activesupport (= 6.1.7.2)
48
+ actiontext (6.1.7.3)
49
+ actionpack (= 6.1.7.3)
50
+ activerecord (= 6.1.7.3)
51
+ activestorage (= 6.1.7.3)
52
+ activesupport (= 6.1.7.3)
53
53
  nokogiri (>= 1.8.5)
54
- actionview (6.1.7.2)
55
- activesupport (= 6.1.7.2)
54
+ actionview (6.1.7.3)
55
+ activesupport (= 6.1.7.3)
56
56
  builder (~> 3.1)
57
57
  erubi (~> 1.4)
58
58
  rails-dom-testing (~> 2.0)
@@ -62,22 +62,22 @@ GEM
62
62
  addressable
63
63
  active_median (0.3.3)
64
64
  activesupport (>= 5.2)
65
- activejob (6.1.7.2)
66
- activesupport (= 6.1.7.2)
65
+ activejob (6.1.7.3)
66
+ activesupport (= 6.1.7.3)
67
67
  globalid (>= 0.3.6)
68
- activemodel (6.1.7.2)
69
- activesupport (= 6.1.7.2)
70
- activerecord (6.1.7.2)
71
- activemodel (= 6.1.7.2)
72
- activesupport (= 6.1.7.2)
73
- activestorage (6.1.7.2)
74
- actionpack (= 6.1.7.2)
75
- activejob (= 6.1.7.2)
76
- activerecord (= 6.1.7.2)
77
- activesupport (= 6.1.7.2)
68
+ activemodel (6.1.7.3)
69
+ activesupport (= 6.1.7.3)
70
+ activerecord (6.1.7.3)
71
+ activemodel (= 6.1.7.3)
72
+ activesupport (= 6.1.7.3)
73
+ activestorage (6.1.7.3)
74
+ actionpack (= 6.1.7.3)
75
+ activejob (= 6.1.7.3)
76
+ activerecord (= 6.1.7.3)
77
+ activesupport (= 6.1.7.3)
78
78
  marcel (~> 1.0)
79
79
  mini_mime (>= 1.1.0)
80
- activesupport (6.1.7.2)
80
+ activesupport (6.1.7.3)
81
81
  concurrent-ruby (~> 1.0, >= 1.0.2)
82
82
  i18n (>= 1.6, < 2)
83
83
  minitest (>= 5.1)
@@ -85,7 +85,7 @@ GEM
85
85
  zeitwerk (~> 2.3)
86
86
  acts-as-taggable-on (9.0.1)
87
87
  activerecord (>= 6.0, < 7.1)
88
- acts_as_list (1.0.4)
88
+ acts_as_list (1.1.0)
89
89
  activerecord (>= 4.2)
90
90
  addressable (2.8.1)
91
91
  public_suffix (>= 2.0.2, < 6.0)
@@ -124,7 +124,7 @@ GEM
124
124
  parser (>= 2.4)
125
125
  smart_properties
126
126
  bindex (0.8.1)
127
- bootsnap (1.15.0)
127
+ bootsnap (1.16.0)
128
128
  msgpack (~> 1.2)
129
129
  brakeman (5.4.0)
130
130
  builder (3.2.4)
@@ -141,7 +141,8 @@ GEM
141
141
  regexp_parser (>= 1.5, < 3.0)
142
142
  xpath (~> 3.2)
143
143
  chartkick (4.2.1)
144
- concurrent-ruby (1.2.0)
144
+ childprocess (4.1.0)
145
+ concurrent-ruby (1.2.2)
145
146
  countries (4.2.3)
146
147
  i18n_data (~> 0.16.0)
147
148
  sixarm_ruby_unaccent (~> 1.1)
@@ -157,7 +158,7 @@ GEM
157
158
  database_cleaner-core (~> 2.0.0)
158
159
  database_cleaner-core (2.0.1)
159
160
  date (3.3.3)
160
- devise (4.8.1)
161
+ devise (4.9.0)
161
162
  bcrypt (~> 3.0)
162
163
  orm_adapter (~> 0.1)
163
164
  railties (>= 4.1.0)
@@ -238,7 +239,7 @@ GEM
238
239
  loofah (2.19.1)
239
240
  crass (~> 1.0.2)
240
241
  nokogiri (>= 1.5.9)
241
- mail (2.8.0.1)
242
+ mail (2.8.1)
242
243
  mini_mime (>= 0.1.1)
243
244
  net-imap
244
245
  net-pop
@@ -254,7 +255,7 @@ GEM
254
255
  mini_magick (4.12.0)
255
256
  mini_mime (1.1.2)
256
257
  mini_portile2 (2.8.1)
257
- minitest (5.17.0)
258
+ minitest (5.18.0)
258
259
  msgpack (1.5.6)
259
260
  multi_xml (0.6.0)
260
261
  net-imap (0.3.4)
@@ -262,7 +263,7 @@ GEM
262
263
  net-protocol
263
264
  net-pop (0.1.2)
264
265
  net-protocol
265
- net-protocol (0.1.3)
266
+ net-protocol (0.2.1)
266
267
  timeout
267
268
  net-smtp (0.3.3)
268
269
  net-protocol
@@ -277,8 +278,8 @@ GEM
277
278
  parallel (1.22.1)
278
279
  parser (3.2.0.0)
279
280
  ast (~> 2.4.1)
280
- pg (1.4.5)
281
- prefixed_ids (1.3.0)
281
+ pg (1.4.6)
282
+ prefixed_ids (1.4.0)
282
283
  hashids (>= 1.0.0, < 2.0.0)
283
284
  rails (>= 6.0.0)
284
285
  public_suffix (5.0.1)
@@ -287,23 +288,23 @@ GEM
287
288
  pundit (2.2.0)
288
289
  activesupport (>= 3.0.0)
289
290
  racc (1.6.2)
290
- rack (2.2.6.2)
291
- rack-test (2.0.2)
291
+ rack (2.2.6.4)
292
+ rack-test (2.1.0)
292
293
  rack (>= 1.3)
293
- rails (6.1.7.2)
294
- actioncable (= 6.1.7.2)
295
- actionmailbox (= 6.1.7.2)
296
- actionmailer (= 6.1.7.2)
297
- actionpack (= 6.1.7.2)
298
- actiontext (= 6.1.7.2)
299
- actionview (= 6.1.7.2)
300
- activejob (= 6.1.7.2)
301
- activemodel (= 6.1.7.2)
302
- activerecord (= 6.1.7.2)
303
- activestorage (= 6.1.7.2)
304
- activesupport (= 6.1.7.2)
294
+ rails (6.1.7.3)
295
+ actioncable (= 6.1.7.3)
296
+ actionmailbox (= 6.1.7.3)
297
+ actionmailer (= 6.1.7.3)
298
+ actionpack (= 6.1.7.3)
299
+ actiontext (= 6.1.7.3)
300
+ actionview (= 6.1.7.3)
301
+ activejob (= 6.1.7.3)
302
+ activemodel (= 6.1.7.3)
303
+ activerecord (= 6.1.7.3)
304
+ activestorage (= 6.1.7.3)
305
+ activesupport (= 6.1.7.3)
305
306
  bundler (>= 1.15.0)
306
- railties (= 6.1.7.2)
307
+ railties (= 6.1.7.3)
307
308
  sprockets-rails (>= 2.0.0)
308
309
  rails-controller-testing (1.0.5)
309
310
  actionpack (>= 5.0.1.rc1)
@@ -317,9 +318,9 @@ GEM
317
318
  rails-i18n (7.0.5)
318
319
  i18n (>= 0.7, < 2)
319
320
  railties (>= 6.0.0, < 8)
320
- railties (6.1.7.2)
321
- actionpack (= 6.1.7.2)
322
- activesupport (= 6.1.7.2)
321
+ railties (6.1.7.3)
322
+ actionpack (= 6.1.7.3)
323
+ activesupport (= 6.1.7.3)
323
324
  method_source
324
325
  rake (>= 12.2)
325
326
  thor (~> 1.0)
@@ -332,7 +333,7 @@ GEM
332
333
  rb-fsevent (0.11.1)
333
334
  rb-inotify (0.10.1)
334
335
  ffi (~> 1.0)
335
- redis (4.8.0)
336
+ redis (4.8.1)
336
337
  regexp_parser (2.7.0)
337
338
  responders (3.0.1)
338
339
  actionpack (>= 5.0)
@@ -378,10 +379,10 @@ GEM
378
379
  ruby-vips (2.1.4)
379
380
  ffi (~> 1.12)
380
381
  rubyzip (2.3.2)
381
- selenium-webdriver (4.8.1)
382
+ selenium-webdriver (4.1.0)
383
+ childprocess (>= 0.5, < 5.0)
382
384
  rexml (~> 3.2, >= 3.2.5)
383
- rubyzip (>= 1.2.2, < 3.0)
384
- websocket (~> 1.0)
385
+ rubyzip (>= 1.2.2)
385
386
  simple_po_parser (1.1.6)
386
387
  simplecov (0.22.0)
387
388
  docile (~> 1.1)
@@ -411,8 +412,8 @@ GEM
411
412
  unicode-display_width (>= 1.1.1, < 3)
412
413
  test-prof (1.0.10)
413
414
  thor (1.2.1)
414
- timeout (0.3.0)
415
- turbo-rails (1.3.3)
415
+ timeout (0.3.2)
416
+ turbo-rails (1.4.0)
416
417
  actionpack (>= 6.0.0)
417
418
  activejob (>= 6.0.0)
418
419
  railties (>= 6.0.0)
@@ -438,13 +439,12 @@ GEM
438
439
  addressable (>= 2.8.0)
439
440
  crack (>= 0.3.2)
440
441
  hashdiff (>= 0.4.0, < 2.0.0)
441
- websocket (1.2.9)
442
442
  websocket-driver (0.7.5)
443
443
  websocket-extensions (>= 0.1.0)
444
444
  websocket-extensions (0.1.5)
445
445
  xpath (3.2.0)
446
446
  nokogiri (~> 1.8)
447
- zeitwerk (2.6.6)
447
+ zeitwerk (2.6.7)
448
448
 
449
449
  PLATFORMS
450
450
  ruby
data/README.md CHANGED
@@ -72,19 +72,33 @@ Please read the [RELEASE.MD](./RELEASE.MD)
72
72
 
73
73
  # ✨ [Contributors](https://avohq.io/contributors)
74
74
 
75
- <a href="https://github.com/avo-hq/avo/graphs/contributors">
75
+ <a href="https://avohq.io/contributors">
76
76
  <img src="https://contrib.rocks/image?repo=avo-hq/avo" />
77
77
  </a>
78
78
  <!-- https://contrib.rocks -->
79
79
 
80
- # 🥇 Business & Agency Sponsors
81
-
82
- <a href="https://equipetechnique.com/?utm_source=github&utm_medium=link&utm_campaign=avo_code_without_borders" target="_blank">
83
- <picture>
84
- <source media="(prefers-color-scheme: dark)" srcset="https://avohq.io/img/sponsors/ET-dark.jpeg">
85
- <img alt="Equipe Technique Busines Sponsor" src="https://avohq.io/img/sponsors/ET-light.jpeg" width="240px">
86
- </picture>
87
- </a>
80
+ # 🥇 Sponsors
81
+
82
+ <table>
83
+ <tr>
84
+ <td>
85
+ <a href="https://equipetechnique.com/?utm_source=github&utm_medium=link&utm_campaign=avo" target="_blank">
86
+ <picture>
87
+ <source media="(prefers-color-scheme: dark)" srcset="https://avohq.io/img/sponsors/ET-dark.jpeg">
88
+ <img alt="Equipe Technique Busines Sponsor" src="https://avohq.io/img/sponsors/ET-light.jpeg" width="180px">
89
+ </picture>
90
+ </a>
91
+ </td>
92
+ <td>
93
+ <a href="https://www.greenhats.com/?utm_source=github&utm_medium=link&utm_campaign=avo" target="_blank">
94
+ <picture>
95
+ <source media="(prefers-color-scheme: dark)" srcset="https://avohq.io/img/sponsors/greenhats-dark.png">
96
+ <img alt="Greenhats Start-up Sponsor" src="https://avohq.io/img/sponsors/greenhats-light.png" width="360px">
97
+ </picture>
98
+ </a>
99
+ </td>
100
+ </tr>
101
+ </table>
88
102
 
89
103
  [Become a sponsor ](https://github.com/sponsors/adrianthedev)
90
104
 
@@ -20,7 +20,7 @@
20
20
  </div>
21
21
  <div class="flex space-x-2">
22
22
  <div class="flex">
23
- <% if @resource.authorization.authorize_action(:download_attachments?, raise_exception: false) %>
23
+ <% if can_download_file? %>
24
24
  <%= a_link Rails.application.routes.url_helpers.rails_blob_path(file, only_path: true, disposition: :attachment),
25
25
  icon: 'heroicons/outline/download',
26
26
  color: :primary,
@@ -33,7 +33,7 @@
33
33
  <% end %>
34
34
  </div>
35
35
  <div>
36
- <% if @resource.authorization.authorize_action(:delete_attachments?, raise_exception: false) %>
36
+ <% if can_delete_file? %>
37
37
  <%= a_link destroy_path,
38
38
  icon: 'heroicons/outline/trash',
39
39
  color: :red,
@@ -2,8 +2,9 @@
2
2
 
3
3
  class Avo::Fields::Common::SingleFileViewerComponent < ViewComponent::Base
4
4
  include Avo::ApplicationHelper
5
+ include Avo::Fields::Concerns::FileAuthorization
5
6
 
6
- def initialize(file: nil, field:, resource:)
7
+ def initialize(field:, resource:, file: nil)
7
8
  @file = file
8
9
  @field = field
9
10
  @resource = resource
@@ -45,7 +46,7 @@ class Avo::Fields::Common::SingleFileViewerComponent < ViewComponent::Base
45
46
  record_persisted?
46
47
  end
47
48
 
48
- # If model is not persistent blob is automatically destroyed otherwise it can be "lost" on storage
49
+ # If model is not persistent blob is automatically destroyed otherwise it can be "lost" on storage
49
50
  def record_persisted?
50
51
  return true if @resource.model.persisted?
51
52
 
@@ -5,7 +5,7 @@
5
5
  </div>
6
6
  <% end %>
7
7
 
8
- <% if @resource.authorization.authorize_action(:upload_attachments?, raise_exception: false) %>
8
+ <% if can_upload_file? %>
9
9
  <%= @form.file_field @field.id,
10
10
  accept: @field.accept,
11
11
  data: @field.get_html(:data, view: view, element: :input),
@@ -14,5 +14,7 @@
14
14
  style: @field.get_html(:style, view: view, element: :input),
15
15
  class: "w-full"
16
16
  %>
17
+ <% else %>
18
+
17
19
  <% end %>
18
20
  <% end %>
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Avo::Fields::FileField::EditComponent < Avo::Fields::EditComponent
4
+ include Avo::Fields::Concerns::FileAuthorization
4
5
  end
@@ -1,7 +1,7 @@
1
1
  <%= field_wrapper **field_wrapper_args, full_width: true do %>
2
2
  <%= render Avo::Fields::Common::FilesListViewerComponent.new(field: @field, resource: @resource) if @field.value.present? %>
3
3
 
4
- <% if @resource.authorization.authorize_action(:upload_attachments?, raise_exception: false) %>
4
+ <% if can_upload_file? %>
5
5
  <div class="mt-2">
6
6
  <%= @form.file_field @field.id,
7
7
  accept: @field.accept,
@@ -13,5 +13,7 @@
13
13
  class: "w-full"
14
14
  %>
15
15
  </div>
16
+ <% else %>
17
+
16
18
  <% end %>
17
19
  <% end %>
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Avo::Fields::FilesField::EditComponent < Avo::Fields::EditComponent
4
+ include Avo::Fields::Concerns::FileAuthorization
4
5
  end
@@ -31,7 +31,7 @@
31
31
  <% end %>
32
32
  <% c.body do %>
33
33
  <div class="flex flex-col xs:flex-row xs:justify-between space-y-2 xs:space-y-0 py-4 <%= 'hidden' if @resource.search_query.nil? && @filters.empty? && available_view_types.count <= 1 %>">
34
- <% unless hide_search_input %>
34
+ <% if show_search_input %>
35
35
  <div class="flex items-center px-4 w-64">
36
36
  <%= render partial: 'avo/partials/resource_search', locals: {resource: @resource.route_key, via_reflection: via_reflection} %>
37
37
  </div>
@@ -124,10 +124,19 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
124
124
  @resource.resource_description
125
125
  end
126
126
 
127
- def hide_search_input
128
- return true unless @resource.search_query.present?
127
+ def show_search_input
128
+ return false unless authorized_to_search?
129
+ return false unless @resource.search_query.present?
130
+ return false if field&.hide_search_input
129
131
 
130
- field&.hide_search_input || false
132
+ true
133
+ end
134
+
135
+ def authorized_to_search?
136
+ # Hide the search if the authorization prevents it
137
+ return true unless @resource.authorization.has_action_method?("search")
138
+
139
+ @resource.authorization.authorize_action("search", raise_exception: false)
131
140
  end
132
141
 
133
142
  private
@@ -18,8 +18,8 @@ module Avo
18
18
  before_action :init_app
19
19
  before_action :check_avo_license
20
20
  before_action :set_resource_name
21
- before_action :set_authorization
22
21
  before_action :_authenticate!
22
+ before_action :set_authorization
23
23
  before_action :set_container_classes
24
24
  before_action :add_initial_breadcrumbs
25
25
  before_action :set_view
@@ -28,7 +28,7 @@ module Avo
28
28
  rescue_from Avo::NotAuthorizedError, with: :render_unauthorized
29
29
  rescue_from ActiveRecord::RecordInvalid, with: :exception_logger
30
30
 
31
- helper_method :_current_user, :resources_path, :resource_path, :new_resource_path, :edit_resource_path, :resource_attach_path, :resource_detach_path, :related_resources_path, :turbo_frame_request?, :resource_view_path
31
+ helper_method :_current_user, :resources_path, :resource_path, :new_resource_path, :edit_resource_path, :resource_attach_path, :resource_detach_path, :related_resources_path, :turbo_frame_request?, :resource_view_path, :mount_path
32
32
  add_flash_types :info, :warning, :success, :error
33
33
 
34
34
  def init_app
@@ -101,6 +101,10 @@ module Avo
101
101
  instance_eval(&Avo.configuration.context)
102
102
  end
103
103
 
104
+ def mount_path
105
+ Avo::Engine.routes.find_script_name(params.permit!.to_h.symbolize_keys)
106
+ end
107
+
104
108
  # This is coming from Turbo::Frames::FrameRequest module.
105
109
  # Exposing it as public method
106
110
  def turbo_frame_request?
@@ -23,6 +23,8 @@ module Avo
23
23
  end
24
24
 
25
25
  def destroy
26
+ raise Avo::NotAuthorizedError.new unless authorized_to :delete
27
+
26
28
  attachment = ActiveStorage::Attachment.find(params[:attachment_id])
27
29
  path = resource_path(model: @model, resource: @resource)
28
30
 
@@ -34,5 +36,13 @@ module Avo
34
36
  redirect_back fallback_location: path, notice: t("avo.failed_to_find_attachment")
35
37
  end
36
38
  end
39
+
40
+ private
41
+
42
+ def authorized_to(action)
43
+ if @resource.authorization.authorize_action("#{action}_attachments?".to_sym, raise_exception: false)
44
+ @resource.authorization.authorize_action("#{action}_#{params[:attachment_name]}?", record: @model, raise_exception: false)
45
+ end
46
+ end
37
47
  end
38
48
  end
@@ -27,7 +27,8 @@ module Avo
27
27
  resources
28
28
  .map do |resource|
29
29
  # Apply authorization
30
- next unless @authorization.set_record(resource.model_class).authorize_action(:index, raise_exception: false)
30
+ next unless @authorization.set_record(resource.model_class).authorize_action(:search, raise_exception: false)
31
+
31
32
  # Filter out the models without a search_query
32
33
  next if resource.search_query.nil?
33
34
 
@@ -120,10 +121,16 @@ module Avo
120
121
  models.map do |model|
121
122
  resource = avo_resource.dup.hydrate(model: model).hydrate_fields(model: model)
122
123
 
124
+ record_path = if resource.search_result_path.present?
125
+ Avo::Hosts::ResourceRecordHost.new(block: resource.search_result_path, resource: resource, record: model).handle
126
+ else
127
+ resource.record_path
128
+ end
129
+
123
130
  result = {
124
131
  _id: model.id,
125
132
  _label: resource.label,
126
- _url: resource.record_path,
133
+ _url: record_path
127
134
  }
128
135
 
129
136
  if App.license.has_with_trial(:enhanced_search_results)
@@ -1,7 +1,7 @@
1
1
  <%= javascript_tag nonce: true do %>
2
2
  window.Avo = window.Avo || { configuration: {} }
3
3
  Avo.configuration.timezone = '<%= Avo.configuration.timezone %>'
4
- Avo.configuration.root_path = '<%= root_path_without_url %>'
4
+ Avo.configuration.root_path = '<%= mount_path %>'
5
5
  Avo.configuration.search_debounce = '<%= Avo.configuration.search_debounce %>'
6
6
  Avo.configuration.cookies_key = '<%= Avo::COOKIES_KEY %>'
7
7
  <% end %>
@@ -30,6 +30,7 @@ module Avo
30
30
  class_attribute :description, default: :id
31
31
  class_attribute :search_query, default: nil
32
32
  class_attribute :search_query_help, default: ""
33
+ class_attribute :search_result_path
33
34
  class_attribute :includes, default: []
34
35
  class_attribute :authorization_policy
35
36
  class_attribute :translation_key
data/lib/avo/engine.rb CHANGED
@@ -7,6 +7,8 @@ Gem.loaded_specs["avo"].dependencies.each do |d|
7
7
  require "action_view/railtie"
8
8
  when "activestorage"
9
9
  require "active_storage/engine"
10
+ when "actiontext"
11
+ require "action_text/engine"
10
12
  else
11
13
  require d.name
12
14
  end
@@ -57,6 +57,8 @@ module Avo
57
57
  # - is_disabled?
58
58
 
59
59
  class BelongsToField < BaseField
60
+ include Avo::Fields::Concerns::UseResource
61
+
60
62
  attr_accessor :target
61
63
 
62
64
  attr_reader :polymorphic_as
@@ -79,6 +81,7 @@ module Avo
79
81
  @attach_scope = args[:attach_scope]
80
82
  @polymorphic_help = args[:polymorphic_help]
81
83
  @target = args[:target]
84
+ @use_resource = args[:use_resource] || nil
82
85
  end
83
86
 
84
87
  def searchable
@@ -222,6 +225,8 @@ module Avo
222
225
  end
223
226
 
224
227
  def target_resource
228
+ return use_resource if use_resource.present?
229
+
225
230
  if is_polymorphic?
226
231
  if value.present?
227
232
  return App.get_resource_by_model_name(value.class)
@@ -0,0 +1,31 @@
1
+ module Avo
2
+ module Fields
3
+ module Concerns
4
+ module FileAuthorization
5
+ extend ActiveSupport::Concern
6
+
7
+ delegate :authorization, to: :@resource
8
+ delegate :authorize_action, to: :authorization
9
+ delegate :id, :model, to: :@field
10
+
11
+ def can_upload_file?
12
+ authorize_file_action(:upload)
13
+ end
14
+
15
+ def can_delete_file?
16
+ authorize_file_action(:delete)
17
+ end
18
+
19
+ def can_download_file?
20
+ authorize_file_action(:download)
21
+ end
22
+
23
+ private
24
+
25
+ def authorize_file_action(action)
26
+ authorize_action("#{action}_attachments?", raise_exception: false) || authorize_action("#{action}_#{id}?", record: model, raise_exception: false)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ module Avo
2
+ module Fields
3
+ module Concerns
4
+ module UseResource
5
+ extend ActiveSupport::Concern
6
+
7
+ def use_resource
8
+ App.get_resource @use_resource
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -20,13 +20,26 @@ module Avo
20
20
  def formatted_value
21
21
  return if value.blank?
22
22
 
23
- value.iso8601
23
+ try_iso8601
24
24
  end
25
25
 
26
26
  def edit_formatted_value
27
- return nil if value.nil?
27
+ formatted_value
28
+ end
29
+
30
+ private
28
31
 
29
- value.iso8601
32
+ def try_iso8601
33
+ if value.respond_to?(:iso8601)
34
+ value.iso8601
35
+ elsif value.is_a?(String)
36
+ parsed = DateTime.parse(value.dup)
37
+ if parsed.present?
38
+ parsed
39
+ end
40
+ else
41
+ value
42
+ end
30
43
  end
31
44
  end
32
45
  end