avo 2.29.1 → 2.32.5
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.
- checksums.yaml +4 -4
- data/Gemfile +3 -1
- data/Gemfile.lock +14 -12
- data/app/assets/stylesheets/avo.base.css +0 -1
- data/app/assets/svgs/failed_to_load.svg +0 -1
- data/app/assets/svgs/grid-empty-state.svg +0 -1
- data/app/assets/svgs/map-empty-state.svg +35 -0
- data/app/assets/svgs/map-view-type.svg +3 -0
- data/app/assets/svgs/table-empty-state.svg +0 -1
- data/app/components/avo/actions_component.rb +5 -3
- data/app/components/avo/field_wrapper_component.html.erb +2 -2
- data/app/components/avo/fields/area_field/edit_component.html.erb +7 -0
- data/app/components/avo/fields/area_field/edit_component.rb +4 -0
- data/app/components/avo/fields/area_field/show_component.html.erb +8 -0
- data/app/components/avo/fields/area_field/show_component.rb +4 -0
- data/app/components/avo/fields/common/files/controls_component.html.erb +29 -0
- data/app/components/avo/fields/common/files/controls_component.rb +19 -0
- data/app/components/avo/fields/common/files/list_viewer_component.html.erb +20 -0
- data/app/components/avo/fields/common/files/list_viewer_component.rb +41 -0
- data/app/components/avo/fields/common/files/view_type/grid_component.html.erb +27 -0
- data/app/components/avo/fields/common/{single_file_viewer_component.rb → files/view_type/grid_component.rb} +7 -12
- data/app/components/avo/fields/common/files/view_type/list_component.html.erb +22 -0
- data/app/components/avo/fields/common/files/view_type/list_component.rb +15 -0
- data/app/components/avo/fields/country_field/edit_component.html.erb +2 -1
- data/app/components/avo/fields/file_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/file_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/files_field/edit_component.html.erb +1 -1
- data/app/components/avo/fields/files_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/has_many_field/show_component.html.erb +1 -1
- data/app/components/avo/fields/has_one_field/show_component.html.erb +2 -2
- data/app/components/avo/fields/location_field/edit_component.html.erb +22 -0
- data/app/components/avo/fields/location_field/edit_component.rb +4 -0
- data/app/components/avo/fields/location_field/show_component.html.erb +7 -0
- data/app/components/avo/fields/location_field/show_component.rb +4 -0
- data/app/components/avo/fields/number_field/edit_component.html.erb +2 -1
- data/app/components/avo/fields/password_field/edit_component.html.erb +2 -1
- data/app/components/avo/fields/select_field/edit_component.html.erb +2 -1
- data/app/components/avo/fields/text_field/edit_component.html.erb +2 -1
- data/app/components/avo/index/resource_map_component.html.erb +16 -0
- data/app/components/avo/index/resource_map_component.rb +109 -0
- data/app/components/avo/item_switcher_component.html.erb +1 -1
- data/app/components/avo/resource_component.rb +1 -1
- data/app/components/avo/views/resource_edit_component.html.erb +4 -4
- data/app/components/avo/views/resource_index_component.html.erb +13 -4
- data/app/components/avo/views/resource_show_component.html.erb +3 -3
- data/app/controllers/avo/application_controller.rb +4 -0
- data/app/controllers/avo/attachments_controller.rb +16 -11
- data/app/helpers/avo/application_helper.rb +8 -0
- data/app/javascript/js/application.js +2 -0
- data/app/javascript/js/controllers/search_controller.js +3 -1
- data/app/views/avo/actions/show.html.erb +4 -3
- data/app/views/avo/associations/new.html.erb +2 -2
- data/app/views/avo/attachments/destroy.turbo_stream.erb +7 -0
- data/app/views/avo/dashboards/show.html.erb +2 -2
- data/app/views/avo/debug/index.html.erb +2 -2
- data/app/views/avo/home/index.html.erb +1 -1
- data/app/views/avo/partials/_view_toggle_button.html.erb +9 -0
- data/app/views/avo/private/design.html.erb +2 -2
- data/avo.gemspec +1 -1
- data/config/routes.rb +2 -2
- data/db/factories.rb +16 -0
- data/lib/avo/app.rb +19 -4
- data/lib/avo/base_action.rb +5 -5
- data/lib/avo/base_resource.rb +2 -0
- data/lib/avo/concerns/fetches_things.rb +8 -10
- data/lib/avo/concerns/policy_helpers.rb +31 -0
- data/lib/avo/engine.rb +0 -5
- data/lib/avo/fields/area_field.rb +39 -0
- data/lib/avo/fields/base_field.rb +10 -4
- data/lib/avo/fields/concerns/file_authorization.rb +1 -1
- data/lib/avo/fields/file_field.rb +2 -0
- data/lib/avo/fields/files_field.rb +6 -0
- data/lib/avo/fields/id_field.rb +2 -1
- data/lib/avo/fields/location_field.rb +69 -0
- data/lib/avo/filters/base_filter.rb +4 -0
- data/lib/avo/licensing/h_q.rb +1 -0
- data/lib/avo/resources/controls/action.rb +4 -1
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/install_generator.rb +11 -0
- data/lib/generators/avo/resource_generator.rb +1 -1
- data/lib/generators/avo/tailwindcss/install_generator.rb +4 -1
- data/lib/generators/avo/templates/resource_tools/partial.tt +2 -2
- data/lib/generators/avo/templates/tailwindcss/Procfile.dev +1 -1
- data/lib/generators/avo/templates/tool/view.tt +2 -2
- data/public/avo-assets/avo.base.css +49 -22
- data/public/avo-assets/avo.base.js +681 -185
- data/public/avo-assets/avo.base.js.map +3 -3
- metadata +28 -8
- data/app/components/avo/fields/common/files_list_viewer_component.html.erb +0 -5
- data/app/components/avo/fields/common/files_list_viewer_component.rb +0 -8
- data/app/components/avo/fields/common/single_file_viewer_component.html.erb +0 -55
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc2e0d4d0438f400a3ceb9929a504b9b9f42e760155a6321c9cbca07e575f52b
|
4
|
+
data.tar.gz: d023300fd0ca0d5484c05545da79f495fd1e2f47e2c8576353a4d87eec23dc9c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8335667ee5a3c608c6533d758fccc92508a20ca927c75acd890761ffe1ee2d3a1ebbb72c7ddb56e94162a0d72bd36eaf606ebfdf85217c33a971f9e26358c8c2
|
7
|
+
data.tar.gz: b2dbeb103ac187a839526bf614afdda7bf6fdfd73a242e2323308b8332df738575fe5469f87a85d7cab95be29ea75e47fc7118cfd54bfbcece6cd545978b63c2
|
data/Gemfile
CHANGED
@@ -75,7 +75,7 @@ group :development do
|
|
75
75
|
|
76
76
|
gem "htmlbeautifier"
|
77
77
|
|
78
|
-
gem "hotwire-livereload", "~> 1.
|
78
|
+
gem "hotwire-livereload", "~> 1.2"
|
79
79
|
|
80
80
|
gem "brakeman"
|
81
81
|
end
|
@@ -165,3 +165,5 @@ gem "sprockets-rails"
|
|
165
165
|
gem "image_processing", "~> 1.12"
|
166
166
|
|
167
167
|
gem "prefixed_ids"
|
168
|
+
|
169
|
+
gem "mapkick-rb", "~> 0.1.4"
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
avo (2.
|
4
|
+
avo (2.32.5)
|
5
5
|
actionview (>= 6.0)
|
6
6
|
active_link_to
|
7
7
|
activerecord (>= 6.0)
|
@@ -13,7 +13,7 @@ PATH
|
|
13
13
|
meta-tags
|
14
14
|
pagy
|
15
15
|
turbo-rails
|
16
|
-
view_component
|
16
|
+
view_component (>= 2.54.0)
|
17
17
|
zeitwerk (>= 2.6.2)
|
18
18
|
|
19
19
|
GEM
|
@@ -196,7 +196,7 @@ GEM
|
|
196
196
|
highline (2.1.0)
|
197
197
|
hightop (0.3.0)
|
198
198
|
activesupport (>= 5.2)
|
199
|
-
hotwire-livereload (1.2.
|
199
|
+
hotwire-livereload (1.2.3)
|
200
200
|
listen (>= 3.0.0)
|
201
201
|
rails (>= 6.0.0)
|
202
202
|
html_tokenizer (0.0.7)
|
@@ -233,10 +233,10 @@ GEM
|
|
233
233
|
json (2.6.2)
|
234
234
|
launchy (2.5.2)
|
235
235
|
addressable (~> 2.8)
|
236
|
-
listen (3.
|
236
|
+
listen (3.8.0)
|
237
237
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
238
238
|
rb-inotify (~> 0.9, >= 0.9.10)
|
239
|
-
loofah (2.
|
239
|
+
loofah (2.20.0)
|
240
240
|
crass (~> 1.0.2)
|
241
241
|
nokogiri (>= 1.5.9)
|
242
242
|
mail (2.8.1)
|
@@ -247,6 +247,7 @@ GEM
|
|
247
247
|
manifester (0.1.8)
|
248
248
|
rails (>= 6.0)
|
249
249
|
zeitwerk
|
250
|
+
mapkick-rb (0.1.4)
|
250
251
|
marcel (1.0.2)
|
251
252
|
matrix (0.4.2)
|
252
253
|
meta-tags (2.18.0)
|
@@ -267,14 +268,14 @@ GEM
|
|
267
268
|
timeout
|
268
269
|
net-smtp (0.3.3)
|
269
270
|
net-protocol
|
270
|
-
nio4r (2.5.
|
271
|
-
nokogiri (1.14.
|
271
|
+
nio4r (2.5.9)
|
272
|
+
nokogiri (1.14.3)
|
272
273
|
mini_portile2 (~> 2.8.0)
|
273
274
|
racc (~> 1.4)
|
274
|
-
nokogiri (1.14.
|
275
|
+
nokogiri (1.14.3-x86_64-linux)
|
275
276
|
racc (~> 1.4)
|
276
277
|
orm_adapter (0.5.0)
|
277
|
-
pagy (6.0.
|
278
|
+
pagy (6.0.4)
|
278
279
|
parallel (1.22.1)
|
279
280
|
parser (3.2.0.0)
|
280
281
|
ast (~> 2.4.1)
|
@@ -330,7 +331,7 @@ GEM
|
|
330
331
|
activerecord (>= 6.0.4)
|
331
332
|
activesupport (>= 6.0.4)
|
332
333
|
i18n
|
333
|
-
rb-fsevent (0.11.
|
334
|
+
rb-fsevent (0.11.2)
|
334
335
|
rb-inotify (0.10.1)
|
335
336
|
ffi (~> 1.0)
|
336
337
|
redis (4.8.1)
|
@@ -420,7 +421,7 @@ GEM
|
|
420
421
|
tzinfo (2.0.6)
|
421
422
|
concurrent-ruby (~> 1.0)
|
422
423
|
unicode-display_width (2.4.0)
|
423
|
-
view_component (
|
424
|
+
view_component (3.0.0)
|
424
425
|
activesupport (>= 5.2.0, < 8.0)
|
425
426
|
concurrent-ruby (~> 1.0)
|
426
427
|
method_source (~> 1.0)
|
@@ -482,7 +483,7 @@ DEPENDENCIES
|
|
482
483
|
gem-release
|
483
484
|
groupdate
|
484
485
|
hightop
|
485
|
-
hotwire-livereload (~> 1.
|
486
|
+
hotwire-livereload (~> 1.2)
|
486
487
|
htmlbeautifier
|
487
488
|
httparty
|
488
489
|
i18n-tasks (~> 1.0.12)
|
@@ -492,6 +493,7 @@ DEPENDENCIES
|
|
492
493
|
launchy
|
493
494
|
listen (>= 3.5.1)
|
494
495
|
manifester
|
496
|
+
mapkick-rb (~> 0.1.4)
|
495
497
|
meta-tags
|
496
498
|
net-smtp
|
497
499
|
pg (>= 0.18, < 2.0)
|
@@ -22,7 +22,6 @@
|
|
22
22
|
<feColorMatrix type="matrix" values="0 0 0 0 0.788235 0 0 0 0 0.803922 0 0 0 0 0.85098 0 0 0 0.349 0"/>
|
23
23
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_577_1090"/>
|
24
24
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_577_1090" result="shape"/>
|
25
|
-
</filter>
|
26
25
|
<filter id="filter1_d_577_1090" x="38.6401" y="0" width="170.72" height="78.1333" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
27
26
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
28
27
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<svg width="248" height="287" viewBox="0 0 248 287" fill="none" xmlns="http://www.w3.org/2000/svg" data-target="grid-empty-state-svg">
|
2
|
+
<path d="M124 270.227C192.483 270.227 248 214.71 248 146.227C248 77.7433 192.483 22.2266 124 22.2266C55.5167 22.2266 0 77.7433 0 146.227C0 214.71 55.5167 270.227 124 270.227Z" fill="rgb(var(--color-primary-100))"/>
|
3
|
+
<g filter="rgb(var(--color-primary-100))">
|
4
|
+
<path d="M195.093 93.3198H52.9068C48.3412 93.3198 44.6401 97.0209 44.6401 101.586V275.186C44.6401 279.752 48.3412 283.453 52.9068 283.453H195.093C199.659 283.453 203.36 279.752 203.36 275.186V101.586C203.36 97.0209 199.659 93.3198 195.093 93.3198Z" fill="white"/>
|
5
|
+
</g>
|
6
|
+
<path d="M107.467 118.12H64.48C61.7407 118.12 59.52 120.34 59.52 123.08C59.52 125.819 61.7407 128.04 64.48 128.04H107.467C110.206 128.04 112.427 125.819 112.427 123.08C112.427 120.34 110.206 118.12 107.467 118.12Z" fill="rgb(var(--color-primary-100))"/>
|
7
|
+
<path d="M137.227 139.613H64.48C61.7407 139.613 59.52 141.834 59.52 144.573C59.52 147.312 61.7407 149.533 64.48 149.533H137.227C139.966 149.533 142.187 147.312 142.187 144.573C142.187 141.834 139.966 139.613 137.227 139.613Z" fill="rgb(var(--color-primary-100))" opacity="0.6"/>
|
8
|
+
<path d="M107.467 162.76H64.48C61.7407 162.76 59.52 164.981 59.52 167.72C59.52 170.459 61.7407 172.68 64.48 172.68H107.467C110.206 172.68 112.427 170.459 112.427 167.72C112.427 164.981 110.206 162.76 107.467 162.76Z" fill="rgb(var(--color-primary-100))"/>
|
9
|
+
<path d="M137.227 184.253H64.48C61.7407 184.253 59.52 186.474 59.52 189.213C59.52 191.953 61.7407 194.173 64.48 194.173H137.227C139.966 194.173 142.187 191.953 142.187 189.213C142.187 186.474 139.966 184.253 137.227 184.253Z" fill="rgb(var(--color-primary-100))" opacity="0.6"/>
|
10
|
+
<path d="M107.467 207.4H64.48C61.7407 207.4 59.52 209.621 59.52 212.36C59.52 215.099 61.7407 217.32 64.48 217.32H107.467C110.206 217.32 112.427 215.099 112.427 212.36C112.427 209.621 110.206 207.4 107.467 207.4Z" fill="rgb(var(--color-primary-100))"/>
|
11
|
+
<path d="M137.227 228.893H64.48C61.7407 228.893 59.52 231.114 59.52 233.853C59.52 236.592 61.7407 238.813 64.48 238.813H137.227C139.966 238.813 142.187 236.592 142.187 233.853C142.187 231.114 139.966 228.893 137.227 228.893Z" fill="rgb(var(--color-primary-100))" opacity="0.6"/>
|
12
|
+
<g filter="url(#filter1_d_577_1090)">
|
13
|
+
<path d="M195.093 9H52.9068C48.3412 9 44.6401 12.7011 44.6401 17.2667V66.8667C44.6401 71.4322 48.3412 75.1333 52.9068 75.1333H195.093C199.659 75.1333 203.36 71.4322 203.36 66.8667V17.2667C203.36 12.7011 199.659 9 195.093 9Z" fill="rgb(var(--color-primary-500))"/>
|
14
|
+
</g>
|
15
|
+
<path d="M107.467 27.1865H64.48C61.7407 27.1865 59.52 29.4072 59.52 32.1465C59.52 34.8859 61.7407 37.1065 64.48 37.1065H107.467C110.206 37.1065 112.427 34.8859 112.427 32.1465C112.427 29.4072 110.206 27.1865 107.467 27.1865Z" fill="rgb(var(--color-primary-100))"/>
|
16
|
+
<path d="M137.227 48.6799H64.48C61.7407 48.6799 59.52 50.9006 59.52 53.6399C59.52 56.3793 61.7407 58.5999 64.48 58.5999H137.227C139.966 58.5999 142.187 56.3793 142.187 53.6399C142.187 50.9006 139.966 48.6799 137.227 48.6799Z" fill="white"/>
|
17
|
+
<defs>
|
18
|
+
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
19
|
+
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
20
|
+
<feOffset dy="-3"/>
|
21
|
+
<feGaussianBlur stdDeviation="3"/>
|
22
|
+
<feColorMatrix type="matrix" values="0 0 0 0 0.788235 0 0 0 0 0.803922 0 0 0 0 0.85098 0 0 0 0.349 0"/>
|
23
|
+
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_577_1090"/>
|
24
|
+
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_577_1090" result="shape"/>
|
25
|
+
<filter id="filter1_d_577_1090" x="38.6401" y="0" width="170.72" height="78.1333" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
26
|
+
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
27
|
+
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
28
|
+
<feOffset dy="-3"/>
|
29
|
+
<feGaussianBlur stdDeviation="3"/>
|
30
|
+
<feColorMatrix type="matrix" values="0 0 0 0 0.788235 0 0 0 0 0.803922 0 0 0 0 0.85098 0 0 0 0.349 0"/>
|
31
|
+
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_577_1090"/>
|
32
|
+
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_577_1090" result="shape"/>
|
33
|
+
</filter>
|
34
|
+
</defs>
|
35
|
+
</svg>
|
@@ -0,0 +1,3 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
2
|
+
<path stroke-linecap="round" stroke-linejoin="round" d="M9 6.75V15m6-6v8.25m.503 3.498l4.875-2.437c.381-.19.622-.58.622-1.006V4.82c0-.836-.88-1.38-1.628-1.006l-3.869 1.934c-.317.159-.69.159-1.006 0L9.503 3.252a1.125 1.125 0 00-1.006 0L3.622 5.689C3.24 5.88 3 6.27 3 6.695V19.18c0 .836.88 1.38 1.628 1.006l3.869-1.934c.317-.159.69-.159 1.006 0l4.994 2.497c.317.158.69.158 1.006 0z"/>
|
3
|
+
</svg>
|
@@ -11,7 +11,7 @@ class Avo::ActionsComponent < ViewComponent::Base
|
|
11
11
|
@exclude = exclude
|
12
12
|
@color = color
|
13
13
|
@style = style
|
14
|
-
@label = label || t("avo.actions")
|
14
|
+
@label = label || I18n.t("avo.actions")
|
15
15
|
end
|
16
16
|
|
17
17
|
def render?
|
@@ -53,13 +53,15 @@ class Avo::ActionsComponent < ViewComponent::Base
|
|
53
53
|
|
54
54
|
def single_record_path(id)
|
55
55
|
Avo::Services::URIService.parse(@resource.record_path)
|
56
|
-
.append_paths("actions"
|
56
|
+
.append_paths("actions")
|
57
|
+
.append_query("action_id": id)
|
57
58
|
.to_s
|
58
59
|
end
|
59
60
|
|
60
61
|
def many_records_path(id)
|
61
62
|
Avo::Services::URIService.parse(@resource.records_path)
|
62
|
-
.append_paths("actions"
|
63
|
+
.append_paths("actions")
|
64
|
+
.append_query("action_id": id)
|
63
65
|
.to_s
|
64
66
|
end
|
65
67
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
class: classes,
|
3
3
|
style: style,
|
4
4
|
data: data do %>
|
5
|
-
<div class="h-full <% if stacked? %> md:pt-4 <% else %> md:pt-0 md:h-14 <% end %> pt-4 flex self-start items-center <%= @field.get_html(:classes, view: view, element: :label) %> w-48 <% if compact? %> md:w-48 xl:w-64 <% else %> md:w-64 <% end %> px-6 uppercase font-semibold text-gray-500 text-sm" data-slot="label">
|
5
|
+
<div class="h-full <% if stacked? %> md:pt-4 <% else %> md:pt-0 md:h-14 <% end %> pt-4 flex self-start items-center flex-shrink-0 <%= @field.get_html(:classes, view: view, element: :label) %> w-48 <% if compact? %> md:w-48 xl:w-64 <% else %> md:w-64 <% end %> px-6 uppercase font-semibold text-gray-500 text-sm" data-slot="label">
|
6
6
|
<% if form.present? %>
|
7
7
|
<%= form.label field.id, label %>
|
8
8
|
<% else %>
|
@@ -11,7 +11,7 @@
|
|
11
11
|
<% if on_edit? && field.is_required? %> <span class="text-red-600 ml-1">*</span> <% end %>
|
12
12
|
</div>
|
13
13
|
<div class="flex-1 flex flex-row md:min-h-inherit py-2 <% if stacked? %> pb-4 <% else %><% end %> px-6 <%= @field.get_html(:classes, view: view, element: :content) %>" data-slot="value">
|
14
|
-
<div class="self-center <%
|
14
|
+
<div class="self-center w-full <% unless full_width? || compact? || stacked? %> md:w-8/12 <% end %>">
|
15
15
|
<% if on_show? %>
|
16
16
|
<% if field.value.blank? and dash_if_blank %>
|
17
17
|
—
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<div class="flex">
|
2
|
+
<% if can_download_file? %>
|
3
|
+
<%= a_link Rails.application.routes.url_helpers.rails_blob_path(file, only_path: true, disposition: :attachment),
|
4
|
+
icon: 'heroicons/outline/download',
|
5
|
+
color: :primary,
|
6
|
+
download: true,
|
7
|
+
class: 'text-center',
|
8
|
+
title: t('avo.download_file'),
|
9
|
+
data: { tippy: :tooltip },
|
10
|
+
compact: true,
|
11
|
+
size: :xs %>
|
12
|
+
<% end %>
|
13
|
+
</div>
|
14
|
+
<div>
|
15
|
+
<% if can_delete_file? %>
|
16
|
+
<%= a_link destroy_path,
|
17
|
+
icon: 'heroicons/outline/trash',
|
18
|
+
color: :red,
|
19
|
+
compact: true,
|
20
|
+
size: :xs,
|
21
|
+
class: 'text-center',
|
22
|
+
title: t('avo.delete_file', item: file.filename),
|
23
|
+
data: {
|
24
|
+
turbo_method: :delete,
|
25
|
+
turbo_confirm: t('avo.are_you_sure'),
|
26
|
+
tippy: :tooltip
|
27
|
+
} %>
|
28
|
+
<% end %>
|
29
|
+
</div>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Avo::Fields::Common::Files::ControlsComponent < ViewComponent::Base
|
4
|
+
include Avo::ApplicationHelper
|
5
|
+
include Avo::Fields::Concerns::FileAuthorization
|
6
|
+
|
7
|
+
attr_reader :file, :field, :resource
|
8
|
+
delegate :id, to: :field
|
9
|
+
|
10
|
+
def initialize(field:, file:, resource:)
|
11
|
+
@field = field
|
12
|
+
@file = file
|
13
|
+
@resource = resource
|
14
|
+
end
|
15
|
+
|
16
|
+
def destroy_path
|
17
|
+
Avo::Services::URIService.parse(@resource.record_path).append_paths("active_storage_attachments", id, file.id).to_s
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<%= content_tag :div, class: wrapper_classes do %>
|
2
|
+
<%= turbo_frame_tag @field.id do %>
|
3
|
+
<% unless @field.hide_view_type_switcher %>
|
4
|
+
<div class="justify-self-end flex justify-end items-center space-x-3">
|
5
|
+
<%= render partial: 'avo/partials/view_toggle_button',
|
6
|
+
locals: {
|
7
|
+
available_view_types: available_view_types,
|
8
|
+
view_type: view_type,
|
9
|
+
turbo_frame: @field.id,
|
10
|
+
}
|
11
|
+
%>
|
12
|
+
</div>
|
13
|
+
<% end %>
|
14
|
+
<div class="<%= classes %>">
|
15
|
+
<% @field.value.attachments.each do |file| %>
|
16
|
+
<%= render view_type_component(file) %>
|
17
|
+
<% end %>
|
18
|
+
</div>
|
19
|
+
<% end %>
|
20
|
+
<% end %>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Avo::Fields::Common::Files::ListViewerComponent < ViewComponent::Base
|
4
|
+
include Turbo::FramesHelper
|
5
|
+
|
6
|
+
attr_reader :field, :resource
|
7
|
+
|
8
|
+
def initialize(field:, resource:)
|
9
|
+
@field = field
|
10
|
+
@resource = resource
|
11
|
+
end
|
12
|
+
|
13
|
+
def classes
|
14
|
+
base_classes = "py-4 rounded-xl max-w-full"
|
15
|
+
|
16
|
+
view_type_classes = if view_type == :list
|
17
|
+
"flex flex-col space-y-2"
|
18
|
+
else
|
19
|
+
"relative grid xs:grid-cols-2 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-6 gap-6"
|
20
|
+
end
|
21
|
+
|
22
|
+
"#{base_classes} #{view_type_classes}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def wrapper_classes
|
26
|
+
(field.stacked && !field.hide_view_type_switcher) ? "-mt-9" : ""
|
27
|
+
end
|
28
|
+
|
29
|
+
def available_view_types
|
30
|
+
[:list, :grid]
|
31
|
+
end
|
32
|
+
|
33
|
+
def view_type_component(file)
|
34
|
+
component = "Avo::Fields::Common::Files::ViewType::#{view_type.to_s.capitalize}Component".constantize
|
35
|
+
component.new(field: field, resource: resource, file: file)
|
36
|
+
end
|
37
|
+
|
38
|
+
def view_type
|
39
|
+
(resource.params.dig(:view_type) || field.view_type).to_sym
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<div id="<%= dom_id file %>" class="relative min-h-full max-w-full flex-1 flex flex-col justify-between space-y-2">
|
2
|
+
<% if file.present? %>
|
3
|
+
<div class="flex flex-col justify-between h-full">
|
4
|
+
<% if file.representable? && is_image? %>
|
5
|
+
<%= image_tag helpers.main_app.url_for(file), class: 'rounded-lg object-cover w-full aspect-video' %>
|
6
|
+
<% elsif is_audio? %>
|
7
|
+
<%= audio_tag(helpers.main_app.url_for(file), controls: true, preload: false, class: 'w-full') %>
|
8
|
+
<% elsif is_video? %>
|
9
|
+
<%= video_tag(helpers.main_app.url_for(file), controls: true, preload: false, class: 'w-full') %>
|
10
|
+
<% else %>
|
11
|
+
<div class="relative flex flex-col justify-evenly items-center px-2 rounded-lg border bg-white border-gray-500 min-h-24">
|
12
|
+
<div class="flex flex-col justify-center items-center w-full">
|
13
|
+
<%= helpers.svg 'document-text', class: 'h-10 text-gray-600 mb-2' %>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
<% end %>
|
17
|
+
<% if field.display_filename %>
|
18
|
+
<span class="text-gray-500 mt-1 text-sm truncate" title="<%= file.filename %>"><%= file.filename %></span>
|
19
|
+
<% end %>
|
20
|
+
</div>
|
21
|
+
<div class="flex space-x-2">
|
22
|
+
<%= render Avo::Fields::Common::Files::ControlsComponent.new(field: field, file: file, resource: resource) %>
|
23
|
+
</div>
|
24
|
+
<% else %>
|
25
|
+
–
|
26
|
+
<% end %>
|
27
|
+
</div>
|
@@ -1,8 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
class Avo::Fields::Common::
|
4
|
-
|
5
|
-
include Avo::Fields::Concerns::FileAuthorization
|
3
|
+
class Avo::Fields::Common::Files::ViewType::GridComponent < ViewComponent::Base
|
4
|
+
attr_reader :field, :resource
|
6
5
|
|
7
6
|
def initialize(field:, resource:, file: nil)
|
8
7
|
@file = file
|
@@ -10,34 +9,30 @@ class Avo::Fields::Common::SingleFileViewerComponent < ViewComponent::Base
|
|
10
9
|
@resource = resource
|
11
10
|
end
|
12
11
|
|
13
|
-
def destroy_path
|
14
|
-
Avo::Services::URIService.parse(@resource.record_path).append_paths("active_storage_attachments", id, file.id).to_s
|
15
|
-
end
|
16
|
-
|
17
12
|
def id
|
18
|
-
|
13
|
+
field.id
|
19
14
|
end
|
20
15
|
|
21
16
|
def file
|
22
|
-
@file ||
|
17
|
+
@file || field.value.attachment
|
23
18
|
rescue
|
24
19
|
nil
|
25
20
|
end
|
26
21
|
|
27
22
|
def is_image?
|
28
|
-
file.image? ||
|
23
|
+
file.image? || field.is_image
|
29
24
|
rescue
|
30
25
|
false
|
31
26
|
end
|
32
27
|
|
33
28
|
def is_audio?
|
34
|
-
file.audio? ||
|
29
|
+
file.audio? || field.is_audio
|
35
30
|
rescue
|
36
31
|
false
|
37
32
|
end
|
38
33
|
|
39
34
|
def is_video?
|
40
|
-
file.video? ||
|
35
|
+
file.video? || field.is_video
|
41
36
|
rescue
|
42
37
|
false
|
43
38
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<div id="<%= dom_id file %>" class="relative min-h-full max-w-full flex-1 flex">
|
2
|
+
<% if file.present? %>
|
3
|
+
<div class="grid grid-cols-6 gap-2 items-center max-w-full w-full">
|
4
|
+
<div class="col-span-4 flex-1 flex flex-row items-center text-gray-700 overflow-x-auto mac-styled-scrollbar ">
|
5
|
+
<div class="rounded-full bg-slate-100 border border-gray-500 p-1.5 flex items-center justify-center">
|
6
|
+
<%= helpers.svg icon_for_file, class: "h-5 text-gray-600" %>
|
7
|
+
</div>
|
8
|
+
<p class="items-center h-full p-2 flex-shrink-0">
|
9
|
+
<%= file.filename %>
|
10
|
+
</p>
|
11
|
+
</div>
|
12
|
+
<div class="text-gray-700 flex-shrink-0 text-sm">
|
13
|
+
<%= helpers.number_to_human_size(file.byte_size) %>
|
14
|
+
</div>
|
15
|
+
<div class="flex space-x-2 justify-end col-span-1 flex-shrink-0">
|
16
|
+
<%= render Avo::Fields::Common::Files::ControlsComponent.new(field: field, file: file, resource: resource) %>
|
17
|
+
</div>
|
18
|
+
</div>
|
19
|
+
<% else %>
|
20
|
+
–
|
21
|
+
<% end %>
|
22
|
+
</div>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Avo::Fields::Common::Files::ViewType::ListComponent < Avo::Fields::Common::Files::ViewType::GridComponent
|
4
|
+
def icon_for_file
|
5
|
+
if is_image?
|
6
|
+
"photo"
|
7
|
+
elsif is_audio?
|
8
|
+
"speaker-wave"
|
9
|
+
elsif is_video?
|
10
|
+
"video-camera"
|
11
|
+
else
|
12
|
+
"document"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -10,6 +10,7 @@
|
|
10
10
|
data: @field.get_html(:data, view: view, element: :input),
|
11
11
|
disabled: disabled?,
|
12
12
|
style: @field.get_html(:style, view: view, element: :input),
|
13
|
-
placeholder: @field.include_blank.present? ? nil : @field.placeholder
|
13
|
+
placeholder: @field.include_blank.present? ? nil : @field.placeholder,
|
14
|
+
autocomplete: @field.autocomplete
|
14
15
|
%>
|
15
16
|
<% end %>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<%= field_wrapper **field_wrapper_args do %>
|
2
2
|
<% if @field.value.present? %>
|
3
3
|
<div class="mb-2">
|
4
|
-
<%= render Avo::Fields::Common::
|
4
|
+
<%= render Avo::Fields::Common::Files::ViewType::GridComponent.new resource: @resource, field: @field %>
|
5
5
|
</div>
|
6
6
|
<% end %>
|
7
7
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<%= field_wrapper **field_wrapper_args, full_width: true do %>
|
2
|
-
<%= render Avo::Fields::Common::
|
2
|
+
<%= render Avo::Fields::Common::Files::ListViewerComponent.new(field: @field, resource: @resource) if @field.value.present? %>
|
3
3
|
|
4
4
|
<% if can_upload_file? %>
|
5
5
|
<div class="mt-2">
|
@@ -1,3 +1,3 @@
|
|
1
1
|
<%= field_wrapper **field_wrapper_args, full_width: true do %>
|
2
|
-
<%= render Avo::Fields::Common::
|
2
|
+
<%= render Avo::Fields::Common::Files::ListViewerComponent.new(field: @field, resource: @resource) if @field.value.present? %>
|
3
3
|
<% end %>
|
@@ -4,7 +4,7 @@
|
|
4
4
|
</turbo-frame>
|
5
5
|
<% else %>
|
6
6
|
<%= render Avo::PanelComponent.new(name: @field.name) do |c| %>
|
7
|
-
<% c.
|
7
|
+
<% c.with_tools do %>
|
8
8
|
<% if !@field.is_readonly? && !@field.is_disabled? && can_attach? %>
|
9
9
|
<%= a_link attach_path,
|
10
10
|
icon: 'heroicons/outline/link',
|
@@ -25,7 +25,7 @@
|
|
25
25
|
<% end %>
|
26
26
|
<% end %>
|
27
27
|
|
28
|
-
<% c.
|
28
|
+
<% c.with_body do %>
|
29
29
|
<div class="py-8 flex justify-center items-center">
|
30
30
|
<%= empty_state by_association: params[:related_name].present? %>
|
31
31
|
</div>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<%= field_wrapper **field_wrapper_args do %>
|
2
|
+
<% if field.value_as_array? %>
|
3
|
+
<div class="flex gap-4">
|
4
|
+
<%= @form.text_field @field.as_lat_long_field_id(:lat),
|
5
|
+
value: @field.as_lat_long_value(:lat),
|
6
|
+
class: classes("w-full"),
|
7
|
+
placeholder: @field.as_lat_long_placeholder(:lat)
|
8
|
+
%>
|
9
|
+
<%= @form.text_field @field.as_lat_long_field_id(:long),
|
10
|
+
value: @field.as_lat_long_value(:long),
|
11
|
+
class: classes("w-full"),
|
12
|
+
placeholder: @field.as_lat_long_placeholder(:long)
|
13
|
+
%>
|
14
|
+
</div>
|
15
|
+
<% else %>
|
16
|
+
<%= @form.text_field @field.id,
|
17
|
+
value: @field.value,
|
18
|
+
class: classes("w-full"),
|
19
|
+
placeholder: @field.placeholder
|
20
|
+
%>
|
21
|
+
<% end %>
|
22
|
+
<% end %>
|
@@ -4,6 +4,7 @@
|
|
4
4
|
data: @field.get_html(:data, view: view, element: :input),
|
5
5
|
disabled: disabled?,
|
6
6
|
placeholder: @field.placeholder,
|
7
|
-
style: @field.get_html(:style, view: view, element: :input)
|
7
|
+
style: @field.get_html(:style, view: view, element: :input),
|
8
|
+
autocomplete: @field.autocomplete
|
8
9
|
%>
|
9
10
|
<% end %>
|