avo 1.22.0.pre.1 → 1.22.1
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.lock +4 -6
- data/app/assets/images/avo/logo.png +0 -0
- data/app/assets/stylesheets/avo.css +1 -1
- data/app/assets/stylesheets/css/fonts.css +0 -53
- data/app/assets/stylesheets/css/pagination.css +9 -9
- data/app/assets/stylesheets/css/search.css +2 -3
- data/app/components/avo/fields/belongs_to_field/autocomplete_component.rb +19 -19
- data/app/components/avo/fields/belongs_to_field/edit_component.html.erb +16 -8
- data/app/components/avo/fields/boolean_field/index_component.html.erb +1 -1
- data/app/components/avo/fields/select_field/edit_component.html.erb +3 -3
- data/app/components/avo/index/field_wrapper_component.html.erb +2 -8
- data/app/components/avo/index/field_wrapper_component.rb +1 -2
- data/app/components/avo/index/resource_table_component.html.erb +3 -3
- data/app/components/avo/index/table_row_component.html.erb +1 -1
- data/app/components/avo/navigation_heading_component.html.erb +2 -2
- data/app/components/avo/navigation_heading_component.rb +1 -5
- data/app/components/avo/navigation_link_component.html.erb +2 -2
- data/app/components/avo/navigation_link_component.rb +2 -6
- data/app/components/avo/panel_component.html.erb +3 -5
- data/app/components/avo/views/resource_index_component.html.erb +7 -8
- data/app/components/avo/views/resource_show_component.html.erb +0 -10
- data/app/controllers/avo/application_controller.rb +16 -14
- data/app/controllers/avo/base_controller.rb +2 -4
- data/app/controllers/avo/relations_controller.rb +1 -4
- data/app/helpers/avo/application_helper.rb +5 -7
- data/app/helpers/avo/resources_helper.rb +2 -2
- data/app/javascript/avo.js +1 -0
- data/app/javascript/js/controllers/fields/belongs_to_field_controller.js +23 -15
- data/app/views/avo/base/_actions.html.erb +3 -4
- data/app/views/avo/base/_filters.html.erb +1 -3
- data/app/views/avo/partials/_global_search.html.erb +2 -2
- data/app/views/avo/partials/_logo.html.erb +1 -1
- data/app/views/avo/partials/_paginator.html.erb +3 -4
- data/app/views/avo/partials/_profile_dropdown.html.erb +25 -0
- data/app/views/avo/partials/_resource_search.html.erb +1 -1
- data/app/views/avo/partials/_table_header.html.erb +3 -3
- data/app/views/avo/partials/_turbo_frame_wrap.html.erb +1 -1
- data/app/views/avo/partials/_view_toggle_button.html.erb +16 -22
- data/app/views/avo/relations/new.html.erb +1 -1
- data/app/views/avo/{partials → sidebar}/_sidebar.html.erb +10 -14
- data/app/views/layouts/avo/application.html.erb +13 -3
- data/db/factories.rb +2 -2
- data/lib/avo/app.rb +3 -4
- data/lib/avo/fields/base_field.rb +7 -4
- data/lib/avo/fields/belongs_to_field.rb +92 -11
- data/lib/avo/fields/key_value_field.rb +28 -8
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/templates/locales/avo.en.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.nb-NO.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.pt-BR.yml +1 -0
- data/lib/generators/avo/templates/locales/avo.ro.yml +1 -0
- data/public/avo-assets/avo.css +224 -405
- data/public/avo-assets/avo.js +24 -12
- data/public/avo-assets/avo.js.map +2 -2
- data/public/avo-assets/logo.png +0 -0
- metadata +7 -37
- data/app/assets/builds/avo.css +0 -8787
- data/app/assets/builds/avo.js +0 -87848
- data/app/assets/builds/avo.js.map +0 -7
- data/app/assets/svgs/dashboards-icon.svg +0 -6
- data/app/assets/svgs/resources-icon.svg +0 -13
- data/app/assets/svgs/three-dots.svg +0 -5
- data/app/assets/svgs/tools-icon.svg +0 -3
- data/app/components/avo/button_component.html.erb +0 -1
- data/app/components/avo/button_component.rb +0 -111
- data/app/components/avo/sidebar_profile_component.html.erb +0 -28
- data/app/components/avo/sidebar_profile_component.rb +0 -43
- data/app/views/avo/partials/_navbar.html.erb +0 -11
- data/public/avo-assets/fonts/inter-v7-latin-500.eot +0 -0
- data/public/avo-assets/fonts/inter-v7-latin-500.svg +0 -351
- data/public/avo-assets/fonts/inter-v7-latin-500.ttf +0 -0
- data/public/avo-assets/fonts/inter-v7-latin-500.woff +0 -0
- data/public/avo-assets/fonts/inter-v7-latin-500.woff2 +0 -0
- data/public/avo-assets/fonts/inter-v7-latin-600.eot +0 -0
- data/public/avo-assets/fonts/inter-v7-latin-600.svg +0 -351
- data/public/avo-assets/fonts/inter-v7-latin-600.ttf +0 -0
- data/public/avo-assets/fonts/inter-v7-latin-600.woff +0 -0
- data/public/avo-assets/fonts/inter-v7-latin-600.woff2 +0 -0
- data/public/avo-assets/fonts/inter-v7-latin-700.eot +0 -0
- data/public/avo-assets/fonts/inter-v7-latin-700.svg +0 -352
- data/public/avo-assets/fonts/inter-v7-latin-700.ttf +0 -0
- data/public/avo-assets/fonts/inter-v7-latin-700.woff +0 -0
- data/public/avo-assets/fonts/inter-v7-latin-700.woff2 +0 -0
- data/public/avo-assets/fonts/inter-v7-latin-regular.eot +0 -0
- data/public/avo-assets/fonts/inter-v7-latin-regular.svg +0 -351
- data/public/avo-assets/fonts/inter-v7-latin-regular.ttf +0 -0
- data/public/avo-assets/fonts/inter-v7-latin-regular.woff +0 -0
- data/public/avo-assets/fonts/inter-v7-latin-regular.woff2 +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '04783e6660bd1ebada3544318b2f48082e3e43eb4bc7ee3df2986a9951d04090'
|
4
|
+
data.tar.gz: 6e997ae6e0dbb4eaa7828b669b73efd811370c0cfb5213d405f15bdd41bb9240
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d61380b2f4c216d4ff1bd4e3e2f882500ba5e09835712d0661e8a79afd505f4b308ab7f30b41fcd95750e061003ca79a25b826e94eb9d007ba786923ce18740c
|
7
|
+
data.tar.gz: 383afdfdc9eaaa92e00b6b91895a1b14ebff2d1655e3c605e39838e6640e9ff9f74eebef1f0322d2eedd402b11060b2b02d4d933a7823edbd7343f47e3a5cd35
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
avo (1.22.
|
4
|
+
avo (1.22.1)
|
5
5
|
active_link_to
|
6
6
|
addressable
|
7
7
|
breadcrumbs_on_rails
|
@@ -215,7 +215,7 @@ GEM
|
|
215
215
|
mime-types-data (3.2022.0105)
|
216
216
|
mini_magick (4.11.0)
|
217
217
|
mini_mime (1.1.2)
|
218
|
-
mini_portile2 (2.
|
218
|
+
mini_portile2 (2.8.0)
|
219
219
|
minitest (5.15.0)
|
220
220
|
msgpack (1.4.4)
|
221
221
|
multi_xml (0.6.0)
|
@@ -227,10 +227,8 @@ GEM
|
|
227
227
|
net-protocol
|
228
228
|
timeout
|
229
229
|
nio4r (2.5.8)
|
230
|
-
nokogiri (1.13.
|
231
|
-
mini_portile2 (~> 2.
|
232
|
-
racc (~> 1.4)
|
233
|
-
nokogiri (1.13.1-x86_64-linux)
|
230
|
+
nokogiri (1.13.3)
|
231
|
+
mini_portile2 (~> 2.8.0)
|
234
232
|
racc (~> 1.4)
|
235
233
|
orm_adapter (0.5.0)
|
236
234
|
pagy (5.10.1)
|
Binary file
|
@@ -24,56 +24,3 @@
|
|
24
24
|
url('/avo-assets/fonts/nunito-v16-latin-700.ttf') format('truetype'), /* Safari, Android, iOS */
|
25
25
|
url('/avo-assets/fonts/nunito-v16-latin-700.svg#Nunito') format('svg'); /* Legacy iOS */
|
26
26
|
}
|
27
|
-
|
28
|
-
/* inter-regular - latin */
|
29
|
-
@font-face {
|
30
|
-
font-family: 'Inter';
|
31
|
-
font-style: normal;
|
32
|
-
font-weight: 400;
|
33
|
-
src: url('/avo-assets/fonts/inter-v7-latin-regular.eot'); /* IE9 Compat Modes */
|
34
|
-
src: local(''),
|
35
|
-
url('/avo-assets/fonts/inter-v7-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
36
|
-
url('/avo-assets/fonts/inter-v7-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
|
37
|
-
url('/avo-assets/fonts/inter-v7-latin-regular.woff') format('woff'), /* Modern Browsers */
|
38
|
-
url('/avo-assets/fonts/inter-v7-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
|
39
|
-
url('/avo-assets/fonts/inter-v7-latin-regular.svg#Inter') format('svg'); /* Legacy iOS */
|
40
|
-
}
|
41
|
-
/* inter-500 - latin */
|
42
|
-
@font-face {
|
43
|
-
font-family: 'Inter';
|
44
|
-
font-style: normal;
|
45
|
-
font-weight: 500;
|
46
|
-
src: url('/avo-assets/fonts/inter-v7-latin-500.eot'); /* IE9 Compat Modes */
|
47
|
-
src: local(''),
|
48
|
-
url('/avo-assets/fonts/inter-v7-latin-500.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
49
|
-
url('/avo-assets/fonts/inter-v7-latin-500.woff2') format('woff2'), /* Super Modern Browsers */
|
50
|
-
url('/avo-assets/fonts/inter-v7-latin-500.woff') format('woff'), /* Modern Browsers */
|
51
|
-
url('/avo-assets/fonts/inter-v7-latin-500.ttf') format('truetype'), /* Safari, Android, iOS */
|
52
|
-
url('/avo-assets/fonts/inter-v7-latin-500.svg#Inter') format('svg'); /* Legacy iOS */
|
53
|
-
}
|
54
|
-
/* inter-600 - latin */
|
55
|
-
@font-face {
|
56
|
-
font-family: 'Inter';
|
57
|
-
font-style: normal;
|
58
|
-
font-weight: 600;
|
59
|
-
src: url('/avo-assets/fonts/inter-v7-latin-600.eot'); /* IE9 Compat Modes */
|
60
|
-
src: local(''),
|
61
|
-
url('/avo-assets/fonts/inter-v7-latin-600.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
62
|
-
url('/avo-assets/fonts/inter-v7-latin-600.woff2') format('woff2'), /* Super Modern Browsers */
|
63
|
-
url('/avo-assets/fonts/inter-v7-latin-600.woff') format('woff'), /* Modern Browsers */
|
64
|
-
url('/avo-assets/fonts/inter-v7-latin-600.ttf') format('truetype'), /* Safari, Android, iOS */
|
65
|
-
url('/avo-assets/fonts/inter-v7-latin-600.svg#Inter') format('svg'); /* Legacy iOS */
|
66
|
-
}
|
67
|
-
/* inter-700 - latin */
|
68
|
-
@font-face {
|
69
|
-
font-family: 'Inter';
|
70
|
-
font-style: normal;
|
71
|
-
font-weight: 700;
|
72
|
-
src: url('/avo-assets/fonts/inter-v7-latin-700.eot'); /* IE9 Compat Modes */
|
73
|
-
src: local(''),
|
74
|
-
url('/avo-assets/fonts/inter-v7-latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
75
|
-
url('/avo-assets/fonts/inter-v7-latin-700.woff2') format('woff2'), /* Super Modern Browsers */
|
76
|
-
url('/avo-assets/fonts/inter-v7-latin-700.woff') format('woff'), /* Modern Browsers */
|
77
|
-
url('/avo-assets/fonts/inter-v7-latin-700.ttf') format('truetype'), /* Safari, Android, iOS */
|
78
|
-
url('/avo-assets/fonts/inter-v7-latin-700.svg#Inter') format('svg'); /* Legacy iOS */
|
79
|
-
}
|
@@ -21,18 +21,18 @@
|
|
21
21
|
.pagy-nav-js .page a,
|
22
22
|
.pagy-combo-nav-js .page a,
|
23
23
|
.pagy-combo-nav-js .pagy-combo-input a {
|
24
|
-
@apply rounded-lg px-3 py-1 text-sm text-gray-500 font-semibold bg-
|
24
|
+
@apply rounded-lg px-3 py-1 text-sm text-gray-500 font-semibold bg-gray-200 shadow-md;
|
25
25
|
|
26
26
|
&:focus{
|
27
27
|
@apply border-blue-300;
|
28
28
|
}
|
29
29
|
|
30
30
|
&:hover{
|
31
|
-
@apply bg-gray-
|
31
|
+
@apply bg-gray-300;
|
32
32
|
}
|
33
33
|
|
34
34
|
&:active{
|
35
|
-
@apply bg-gray-
|
35
|
+
@apply bg-gray-400 text-white;
|
36
36
|
}
|
37
37
|
}
|
38
38
|
|
@@ -42,26 +42,26 @@
|
|
42
42
|
.pagy-nav .page.next.disabled,
|
43
43
|
.pagy-nav-js .page.next.disabled,
|
44
44
|
.pagy-combo-nav-js .page.next.disabled {
|
45
|
-
@apply text-gray-
|
45
|
+
@apply text-gray-400 cursor-default;
|
46
46
|
|
47
47
|
&:hover {
|
48
|
-
@apply text-gray-
|
48
|
+
@apply text-gray-400 bg-gray-200;
|
49
49
|
}
|
50
50
|
|
51
51
|
&:active {
|
52
|
-
@apply text-gray-
|
52
|
+
@apply text-gray-400 bg-gray-200;
|
53
53
|
}
|
54
54
|
}
|
55
55
|
|
56
56
|
.pagy-nav .page.active,
|
57
57
|
.pagy-nav-js .page.active {
|
58
|
-
@apply text-white cursor-default bg-gray-
|
58
|
+
@apply text-white cursor-default bg-gray-400;
|
59
59
|
|
60
60
|
&:hover {
|
61
|
-
@apply text-white bg-gray-
|
61
|
+
@apply text-white bg-gray-400;
|
62
62
|
}
|
63
63
|
|
64
64
|
&:active {
|
65
|
-
@apply bg-gray-
|
65
|
+
@apply bg-gray-400 text-white;
|
66
66
|
}
|
67
67
|
}
|
@@ -1,14 +1,13 @@
|
|
1
1
|
:root {
|
2
2
|
--aa-primary-color: --tw-ring-color;
|
3
3
|
--aa-selected-color: --tw-ring-color;
|
4
|
-
--aa-primary-color-rgb:
|
4
|
+
--aa-primary-color-rgb: 5, 150, 105;
|
5
5
|
}
|
6
6
|
|
7
7
|
.global-search {
|
8
8
|
.aa-DetachedSearchButton:focus,
|
9
9
|
.aa-DetachedSearchButton {
|
10
10
|
border: none !important;
|
11
|
-
@apply text-gray-500;
|
12
11
|
}
|
13
12
|
}
|
14
13
|
|
@@ -18,7 +17,7 @@
|
|
18
17
|
}
|
19
18
|
|
20
19
|
.aa-DetachedSearchButton {
|
21
|
-
@apply rounded border-gray-300
|
20
|
+
@apply rounded-full border-gray-300;
|
22
21
|
}
|
23
22
|
}
|
24
23
|
|
@@ -13,35 +13,35 @@ class Avo::Fields::BelongsToField::AutocompleteComponent < ViewComponent::Base
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def field_label
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
@field.value&.class == @type ? @field.field_label : nil
|
22
|
-
end
|
23
|
-
else
|
24
|
-
@field.field_label
|
16
|
+
result = @field.field_label
|
17
|
+
|
18
|
+
# New records won't have the value (instantiated model) present but the polymorphic_type and polymorphic_id prefilled
|
19
|
+
if should_prefill?
|
20
|
+
result = @field.value&.class == @type ? @field.field_label : nil
|
25
21
|
end
|
22
|
+
|
23
|
+
result
|
26
24
|
end
|
27
25
|
|
28
26
|
def field_value
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@field.value&.class == @type ? @field.field_value : nil
|
35
|
-
end
|
36
|
-
else
|
37
|
-
@field.field_value
|
27
|
+
result = @field.field_value
|
28
|
+
|
29
|
+
# New records won't have the value (instantiated model) present but the polymorphic_type and polymorphic_id prefilled
|
30
|
+
if should_prefill?
|
31
|
+
result = @field.value&.class == @type ? @field.field_value : nil
|
38
32
|
end
|
33
|
+
|
34
|
+
result
|
39
35
|
end
|
40
36
|
|
41
37
|
private
|
42
38
|
|
39
|
+
def should_prefill?
|
40
|
+
@field.is_polymorphic? && searchable? && !(new_record? && has_polymorphic_association?)
|
41
|
+
end
|
42
|
+
|
43
43
|
def searchable?
|
44
|
-
@
|
44
|
+
@field.searchable
|
45
45
|
end
|
46
46
|
|
47
47
|
def new_record?
|
@@ -13,7 +13,7 @@
|
|
13
13
|
data-association-class="<%= @field&.target_resource&.model_class || nil %>"
|
14
14
|
>
|
15
15
|
<%= edit_field_wrapper field: @field, index: @index, form: @form, resource: @resource, displayed_in_modal: @displayed_in_modal do %>
|
16
|
-
<%= @form.select
|
16
|
+
<%= @form.select @field.type_input_foreign_key, @field.types.map { |type| [type.to_s.underscore.humanize, type.to_s] },
|
17
17
|
{
|
18
18
|
value: @field.value,
|
19
19
|
include_blank: @field.placeholder,
|
@@ -29,7 +29,7 @@
|
|
29
29
|
# If the select field is disabled, no value will be sent. It's how HTML works.
|
30
30
|
# Thus the extra hidden field to actually send the related id to the server.
|
31
31
|
if disabled %>
|
32
|
-
<%= @form.hidden_field
|
32
|
+
<%= @form.hidden_field @field.type_input_foreign_key %>
|
33
33
|
<% end %>
|
34
34
|
<% end %>
|
35
35
|
<% @field.types.each do |type| %>
|
@@ -43,15 +43,16 @@
|
|
43
43
|
field: @field,
|
44
44
|
type: type,
|
45
45
|
model_key: model_keys[type.to_s],
|
46
|
-
foreign_key:
|
46
|
+
foreign_key: @field.id_input_foreign_key,
|
47
47
|
resource: @resource,
|
48
48
|
disabled: disabled,
|
49
49
|
polymorphic_record: polymorphic_record
|
50
50
|
%>
|
51
51
|
<% else %>
|
52
|
-
<%= @form.select
|
52
|
+
<%= @form.select @field.id_input_foreign_key,
|
53
|
+
options_for_select(@field.values_for_type(type), @resource.present? && @resource.model.present? ? @resource.model[@field.id_input_foreign_key] : nil),
|
53
54
|
{
|
54
|
-
value: @resource.model[
|
55
|
+
value: @resource.model[@field.id_input_foreign_key].to_s,
|
55
56
|
include_blank: @field.placeholder,
|
56
57
|
},
|
57
58
|
{
|
@@ -59,6 +60,12 @@
|
|
59
60
|
disabled: disabled
|
60
61
|
}
|
61
62
|
%>
|
63
|
+
<%
|
64
|
+
# If the select field is disabled, no value will be sent. It's how HTML works.
|
65
|
+
# Thus the extra hidden field to actually send the related id to the server.
|
66
|
+
if disabled %>
|
67
|
+
<%= @form.hidden_field @field.id_input_foreign_key %>
|
68
|
+
<% end %>
|
62
69
|
<% end %>
|
63
70
|
<% end %>
|
64
71
|
</div>
|
@@ -70,14 +77,15 @@
|
|
70
77
|
<%= render Avo::Fields::BelongsToField::AutocompleteComponent.new form: @form,
|
71
78
|
field: @field,
|
72
79
|
model_key: @field.target_resource&.model_key,
|
73
|
-
foreign_key: @field.
|
80
|
+
foreign_key: @field.id_input_foreign_key,
|
74
81
|
resource: @resource,
|
75
82
|
disabled: disabled
|
76
83
|
%>
|
77
84
|
<% else %>
|
78
|
-
<%= @form.select @field.
|
85
|
+
<%= @form.select @field.id_input_foreign_key, @field.options,
|
79
86
|
{
|
80
87
|
include_blank: @field.placeholder,
|
88
|
+
value: @field.value
|
81
89
|
},
|
82
90
|
{
|
83
91
|
class: helpers.input_classes('w-full', has_error: @field.model_errors.include?(@field.id)),
|
@@ -88,7 +96,7 @@
|
|
88
96
|
# If the select field is disabled, no value will be sent. It's how HTML works.
|
89
97
|
# Thus the extra hidden field to actually send the related id to the server.
|
90
98
|
if disabled %>
|
91
|
-
<%= @form.hidden_field @field.
|
99
|
+
<%= @form.hidden_field @field.id_input_foreign_key %>
|
92
100
|
<% end %>
|
93
101
|
<% end %>
|
94
102
|
<% end %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<%= edit_field_wrapper field: @field, index: @index, form: @form, resource: @resource, displayed_in_modal: @displayed_in_modal do %>
|
2
2
|
<%= @form.select @field.id, @field.options_for_select, { selected: @field.value, prompt: @field.placeholder }, {
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
class: helpers.input_classes(' w-full', has_error: @field.model_errors.include?(@field.id)),
|
4
|
+
disabled: @field.readonly,
|
5
|
+
value: @field.model.present? ? @field.model[@field.id] : @field.value } %>
|
6
6
|
<% end %>
|
@@ -1,13 +1,7 @@
|
|
1
|
-
<td class="px-4 py-
|
1
|
+
<td class="px-4 py-2 leading-tight whitespace-nowrap h-12 text-slate-800 <%= @classes %>" data-field-id="<%= @field.id %>" data-field-type="<%= @field.type %>">
|
2
2
|
<% if @field.value.blank? && @dash_if_blank %>
|
3
3
|
—
|
4
4
|
<% else %>
|
5
|
-
|
6
|
-
<div class="flex items-center justify-center">
|
7
|
-
<%= content %>
|
8
|
-
</div>
|
9
|
-
<% else %>
|
10
|
-
<%= content %>
|
11
|
-
<% end %>
|
5
|
+
<%= content %>
|
12
6
|
<% end %>
|
13
7
|
</td>
|
@@ -1,10 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Avo::Index::FieldWrapperComponent < ViewComponent::Base
|
4
|
-
def initialize(field: nil, dash_if_blank: true,
|
4
|
+
def initialize(field: nil, dash_if_blank: true, **args)
|
5
5
|
@field = field
|
6
6
|
@dash_if_blank = dash_if_blank
|
7
|
-
@center_content = center_content
|
8
7
|
@classes = args[:class].present? ? args[:class] : ""
|
9
8
|
@args = args
|
10
9
|
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
<div class="w-full
|
1
|
+
<div class="w-full">
|
2
2
|
<% if @resources.present?%>
|
3
|
-
<table class="w-full px-4 overflow-hidden
|
3
|
+
<table class="w-full px-4 overflow-hidden" data-resource-name='<%= @resource.model_key %>' data-controller='item-select-all'>
|
4
4
|
<%= render partial: 'avo/partials/table_header', locals: {fields: @resource.get_fields(reflection: @reflection)} %>
|
5
|
-
<tbody
|
5
|
+
<tbody>
|
6
6
|
<% @resources.each_with_index do |resource, index| %>
|
7
7
|
<% cache_if Avo.configuration.cache_resources_on_index_view, resource.cache_hash(@parent_model) do %>
|
8
8
|
<%= render Avo::Index::TableRowComponent.new(resource: resource, reflection: @reflection, parent_model: @parent_model) %>
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<div class="flex items-center p-
|
2
|
-
|
1
|
+
<div class="flex items-center my-2 p-3 text-gray-500 font-bold text-sm -mb-1 leading-none">
|
2
|
+
<div class="w-4"></div> <%= @label %>
|
3
3
|
</div>
|
@@ -1,3 +1,3 @@
|
|
1
|
-
<%= active_link_to @path, class: 'px-4 block
|
2
|
-
<%= @label %>
|
1
|
+
<%= active_link_to @path, class: 'text-gray-800 py-2 px-4 block font-normal hover:bg-gray-100 rounded-md mb-1 mx-3 text-sm leading-none', active: @active, target: @target do %>
|
2
|
+
<div class="w-4"></div> <%= @label %>
|
3
3
|
<% end %>
|
@@ -1,15 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class Avo::NavigationLinkComponent < ViewComponent::Base
|
4
|
-
|
5
|
-
attr_reader :path
|
6
|
-
attr_reader :active
|
7
|
-
attr_reader :size
|
8
|
-
|
9
|
-
def initialize(label: nil, path: nil, active: :inclusive, size: :md)
|
4
|
+
def initialize(label: nil, path: nil, active: :inclusive, size: :md, target: "_self")
|
10
5
|
@label = label
|
11
6
|
@path = path
|
12
7
|
@active = active
|
13
8
|
@size = size
|
9
|
+
@target = target
|
14
10
|
end
|
15
11
|
end
|
@@ -6,12 +6,10 @@
|
|
6
6
|
<%= helpers.render_breadcrumbs(separator: helpers.svg('chevron-right', class: 'inline-block h-3 stroke-current relative top-[-1px] ml-1' )) if Avo.configuration.display_breadcrumbs %>
|
7
7
|
</div>
|
8
8
|
<% end %>
|
9
|
-
|
10
|
-
<div class="text-2xl tracking-normal font-semibold text-gray-800 truncate" data-target="title">
|
9
|
+
<div class="text-2xl tracking-normal font-bold text-gray-800 truncate" data-target="title">
|
11
10
|
<%= @title %>
|
12
11
|
</div>
|
13
|
-
|
14
|
-
<div class="text-base tracking-normal font-medium text-gray-600" data-target="description">
|
12
|
+
<div class="text-sm tracking-normal text-gray-600" data-target="description">
|
15
13
|
<%== description %>
|
16
14
|
</div>
|
17
15
|
</div>
|
@@ -23,7 +21,7 @@
|
|
23
21
|
</div>
|
24
22
|
</div>
|
25
23
|
|
26
|
-
<div class="relative bg-white rounded-
|
24
|
+
<div class="relative bg-white rounded-xl shadow-xl mb-8 <%= @body_classes %>">
|
27
25
|
<%= body %>
|
28
26
|
</div>
|
29
27
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
<div>
|
2
|
-
<%= render Avo::PanelComponent.new(title: title, description: description, body_classes: 'py-
|
2
|
+
<%= render Avo::PanelComponent.new(title: title, description: description, body_classes: 'py-4', data: { component: 'resources-index' }, display_breadcrumbs: @reflection.blank?) do |c| %>
|
3
3
|
<% c.tools do %>
|
4
4
|
<% if can_see_the_actions_button? %>
|
5
5
|
<%= render 'actions' %>
|
6
6
|
<% end %>
|
7
7
|
|
8
8
|
<% if can_see_the_create_button? %>
|
9
|
-
<%= a_link create_path, 'data-target': 'create'
|
9
|
+
<%= a_link create_path, 'data-target': 'create' do %>
|
10
10
|
<%= svg 'plus' %> <%= t('avo.create_new_item', item: singular_resource_name.downcase ) %>
|
11
11
|
<% end %>
|
12
12
|
<% end %>
|
@@ -19,7 +19,7 @@
|
|
19
19
|
<% end %>
|
20
20
|
|
21
21
|
<% c.body do %>
|
22
|
-
<div class="flex justify-between min-h-16"
|
22
|
+
<div class="flex justify-between pt-2 pb-2 min-h-16"
|
23
23
|
data-selected-resources-name="<%= @resource.model_key %>"
|
24
24
|
data-selected-resources="[]"
|
25
25
|
>
|
@@ -27,14 +27,11 @@
|
|
27
27
|
<%= render partial: 'avo/partials/resource_search', locals: {resource: @resource.model_key} if @resource.search_query.present? %>
|
28
28
|
</div>
|
29
29
|
<div class="flex justify-end items-center px-6 space-x-3">
|
30
|
-
<%= render 'filters' if @filters.present? %>
|
31
|
-
|
32
30
|
<%= render partial: 'avo/partials/view_toggle_button', locals: { available_view_types: available_view_types, view_type: view_type, turbo_frame: @turbo_frame } if @models.present? %>
|
31
|
+
<%= render 'filters' if @filters.present? %>
|
33
32
|
</div>
|
34
33
|
</div>
|
35
|
-
<% end %>
|
36
34
|
|
37
|
-
<% c.bare_content do %>
|
38
35
|
<% if view_type.to_sym == :table %>
|
39
36
|
<div class="w-full overflow-auto flex flex-col mt-4">
|
40
37
|
<div class="relative flex-1 flex">
|
@@ -48,11 +45,13 @@
|
|
48
45
|
<% end %>
|
49
46
|
</div>
|
50
47
|
<% end %>
|
48
|
+
<% end %>
|
51
49
|
|
50
|
+
<% c.bare_content do %>
|
52
51
|
<% if view_type.to_sym == :grid %>
|
53
52
|
<%= render Avo::Index::ResourceGridComponent.new(resources: @resources, resource: @resource, reflection: @reflection, parent_model: @parent_model) %>
|
54
53
|
|
55
|
-
<div class="mt-8 py-6">
|
54
|
+
<div class="bg-white rounded-xl shadow-xl mt-8 py-6">
|
56
55
|
<%= render partial: 'avo/partials/paginator', locals: { pagy: @pagy, turbo_frame: @turbo_frame || 'none' } %>
|
57
56
|
</div>
|
58
57
|
<% end %>
|
@@ -24,16 +24,6 @@
|
|
24
24
|
<%= svg 'arrow-left' %> <%= t('avo.go_back') %>
|
25
25
|
<% end %>
|
26
26
|
|
27
|
-
<%# -- %>
|
28
|
-
|
29
|
-
<%#= render Avo::ButtonComponent.new(icon: svg('arrow-left'), is_link: true, href: back_path) do %>
|
30
|
-
<%#= t('avo.go_back') %>
|
31
|
-
<%# end %>
|
32
|
-
|
33
|
-
<%#= render Avo::ButtonComponent.new(color: 'green', spinner: true, type: :submit, icon: svg('save')) do %>
|
34
|
-
<%#= t('avo.save').capitalize %>
|
35
|
-
<%# end %>
|
36
|
-
|
37
27
|
<% if can_see_the_destroy_button? %>
|
38
28
|
<%= form_with url: helpers.resource_path(model: @resource.model, resource: @resource), method: :delete, html: { 'data-turbo-frame': params[:turbo_frame] } do |form| %>
|
39
29
|
<%= a_button title: t('avo.delete_item', item: @resource.model.model_name.name.downcase).capitalize,
|
@@ -1,6 +1,11 @@
|
|
1
1
|
module Avo
|
2
2
|
class ApplicationController < ::ActionController::Base
|
3
|
-
|
3
|
+
if defined?(Pundit::Authorization)
|
4
|
+
include Pundit::Authorization
|
5
|
+
else
|
6
|
+
include Pundit
|
7
|
+
end
|
8
|
+
|
4
9
|
include Pagy::Backend
|
5
10
|
include Avo::ApplicationHelper
|
6
11
|
include Avo::UrlHelpers
|
@@ -111,7 +116,12 @@ module Avo
|
|
111
116
|
end
|
112
117
|
|
113
118
|
def fill_model
|
114
|
-
|
119
|
+
# We have to skip filling the the model if this is an attach action
|
120
|
+
is_attach_action = params[model_param_key].blank? && params[:related_name].present? && params[:fields].present?
|
121
|
+
|
122
|
+
unless is_attach_action
|
123
|
+
@model = @resource.fill_model(@model_to_fill, cast_nullable(model_params))
|
124
|
+
end
|
115
125
|
end
|
116
126
|
|
117
127
|
def hydrate_resource
|
@@ -187,18 +197,6 @@ module Avo
|
|
187
197
|
query
|
188
198
|
end
|
189
199
|
|
190
|
-
# def authorize_user
|
191
|
-
# return if params[:controller] == 'avo/search'
|
192
|
-
|
193
|
-
# model = record = resource.model
|
194
|
-
|
195
|
-
# if ['show', 'edit', 'update'].include?(params[:action]) && params[:controller] == 'avo/resources'
|
196
|
-
# record = resource
|
197
|
-
# end
|
198
|
-
|
199
|
-
# # AuthorizationService::authorize_action _current_user, record, params[:action] return render_unauthorized unless
|
200
|
-
# end
|
201
|
-
|
202
200
|
def _authenticate!
|
203
201
|
instance_eval(&Avo.configuration.authenticate)
|
204
202
|
end
|
@@ -243,5 +241,9 @@ module Avo
|
|
243
241
|
def on_api_path
|
244
242
|
request.original_url.match?(/.*#{Avo::App.root_path}\/avo_api\/.*/)
|
245
243
|
end
|
244
|
+
|
245
|
+
def model_param_key
|
246
|
+
@resource.form_scope
|
247
|
+
end
|
246
248
|
end
|
247
249
|
end
|
@@ -7,6 +7,7 @@ module Avo
|
|
7
7
|
before_action :hydrate_resource
|
8
8
|
before_action :set_model, only: [:show, :edit, :destroy, :update]
|
9
9
|
before_action :set_model_to_fill
|
10
|
+
before_action :fill_model, only: [:create, :update]
|
10
11
|
before_action :authorize_action
|
11
12
|
before_action :reset_pagination_if_filters_changed, only: :index
|
12
13
|
before_action :cache_applied_filters, only: :index
|
@@ -83,6 +84,7 @@ module Avo
|
|
83
84
|
def new
|
84
85
|
@model = @resource.model_class.new
|
85
86
|
@resource = @resource.hydrate(model: @model, view: :new, user: _current_user)
|
87
|
+
# abort @model.course.inspect
|
86
88
|
|
87
89
|
@page_title = @resource.default_panel_name
|
88
90
|
add_breadcrumb resource_name.humanize, resources_path(resource: @resource)
|
@@ -112,7 +114,6 @@ module Avo
|
|
112
114
|
|
113
115
|
def create
|
114
116
|
# model gets instantiated and filled in the fill_model method
|
115
|
-
fill_model
|
116
117
|
saved = @model.save
|
117
118
|
@resource.hydrate(model: @model, view: :new, user: _current_user)
|
118
119
|
|
@@ -166,7 +167,6 @@ module Avo
|
|
166
167
|
|
167
168
|
def update
|
168
169
|
# model gets instantiated and filled in the fill_model method
|
169
|
-
fill_model
|
170
170
|
saved = @model.save
|
171
171
|
@resource = @resource.hydrate(model: @model, view: :edit, user: _current_user)
|
172
172
|
|
@@ -194,8 +194,6 @@ module Avo
|
|
194
194
|
private
|
195
195
|
|
196
196
|
def model_params
|
197
|
-
model_param_key = @resource.form_scope
|
198
|
-
|
199
197
|
request_params = params.require(model_param_key).permit(permitted_params)
|
200
198
|
|
201
199
|
if @resource.devise_password_optional && request_params[:password].blank? && request_params[:password_confirmation].blank?
|
@@ -37,10 +37,7 @@ module Avo
|
|
37
37
|
query = @authorization.apply_policy @attachment_class
|
38
38
|
|
39
39
|
@options = query.all.map do |model|
|
40
|
-
|
41
|
-
value: model.id,
|
42
|
-
label: model.send(@attachment_resource.class.title)
|
43
|
-
}
|
40
|
+
[model.send(@attachment_resource.class.title), model.id]
|
44
41
|
end
|
45
42
|
end
|
46
43
|
|