avo 2.5.2.pre.4 → 2.5.2.pre.7
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 +2 -0
- data/Gemfile.lock +4 -1
- data/app/assets/builds/avo.css +764 -166
- data/app/assets/builds/avo.js +212 -123
- data/app/assets/builds/avo.js.map +3 -3
- data/app/assets/stylesheets/avo.css +3 -33
- data/app/assets/stylesheets/css/alerts.css +35 -0
- data/app/assets/stylesheets/css/search.css +1 -1
- data/app/assets/stylesheets/css/tags.css +16 -0
- data/app/assets/svgs/heroicons/solid/user-remove.svg +1 -1
- data/app/components/avo/actions_component.html.erb +1 -2
- data/app/components/avo/alert_component.html.erb +1 -1
- data/app/components/avo/alert_component.rb +5 -24
- data/app/components/avo/button_component.rb +0 -2
- data/app/components/avo/fields/tags_field/edit_component.html.erb +27 -0
- data/app/components/avo/fields/tags_field/edit_component.rb +4 -0
- data/app/components/avo/fields/tags_field/index_component.html.erb +14 -0
- data/app/components/avo/fields/tags_field/index_component.rb +7 -0
- data/app/components/avo/fields/tags_field/show_component.html.erb +7 -0
- data/app/components/avo/fields/tags_field/show_component.rb +11 -0
- data/app/components/avo/fields/tags_field/tag_component.html.erb +9 -0
- data/app/components/avo/fields/tags_field/tag_component.rb +11 -0
- data/app/components/avo/filters_component.html.erb +1 -1
- data/app/components/avo/index/field_wrapper_component.html.erb +1 -1
- data/app/components/avo/index/grid_cover_empty_state_component.html.erb +1 -1
- data/app/components/avo/index/resource_table_component.html.erb +1 -1
- data/app/components/avo/panel_component.html.erb +3 -3
- data/app/components/avo/panel_component.rb +1 -1
- data/app/components/avo/resource_component.rb +0 -50
- data/app/components/avo/sidebar/heading_component.html.erb +1 -1
- data/app/components/avo/sidebar/link_component.rb +1 -1
- data/app/components/avo/sidebar_component.html.erb +13 -5
- data/app/components/avo/sidebar_profile_component.html.erb +1 -1
- data/app/components/avo/views/resource_edit_component.html.erb +3 -28
- data/app/components/avo/views/resource_edit_component.rb +6 -4
- data/app/components/avo/views/resource_index_component.html.erb +7 -15
- data/app/components/avo/views/resource_new_component.html.erb +2 -8
- data/app/components/avo/views/resource_show_component.html.erb +5 -15
- data/app/components/avo/views/resource_show_component.rb +45 -0
- data/app/controllers/avo/actions_controller.rb +8 -23
- data/app/controllers/avo/associations_controller.rb +3 -3
- data/app/controllers/avo/base_controller.rb +16 -25
- data/app/controllers/avo/search_controller.rb +2 -2
- data/app/helpers/avo/application_helper.rb +1 -1
- data/app/javascript/js/application.js +1 -1
- data/app/javascript/js/controllers/alerts_controller.js +26 -0
- data/app/javascript/js/controllers/base_controller.js +22 -0
- data/app/javascript/js/controllers/fields/key_value_controller.js +1 -1
- data/app/javascript/js/controllers/fields/tags_field_controller.js +86 -0
- data/app/javascript/js/controllers/fields/tags_field_helpers.js +47 -0
- data/app/javascript/js/controllers/filter_controller.js +1 -4
- data/app/javascript/js/controllers.js +4 -0
- data/app/views/avo/actions/show.html.erb +2 -5
- data/app/views/avo/partials/_logo.html.erb +1 -1
- data/app/views/avo/partials/_navbar.html.erb +6 -12
- data/app/views/avo/private/_links_and_buttons.html.erb +1 -1
- data/app/views/layouts/avo/application.html.erb +53 -50
- data/db/factories.rb +2 -0
- data/lib/avo/base_action.rb +6 -24
- data/lib/avo/base_resource.rb +6 -0
- data/lib/avo/concerns/handles_field_args.rb +36 -0
- data/lib/avo/engine.rb +1 -1
- data/lib/avo/fields/base_field.rb +2 -1
- data/lib/avo/fields/belongs_to_field.rb +4 -4
- data/lib/avo/fields/has_and_belongs_to_many_field.rb +2 -2
- data/lib/avo/fields/has_base_field.rb +0 -2
- data/lib/avo/fields/has_many_field.rb +2 -2
- data/lib/avo/fields/has_one_field.rb +2 -2
- data/lib/avo/fields/tags_field.rb +82 -0
- data/lib/avo/hosts/record_host.rb +7 -0
- data/lib/avo/licensing/pro_license.rb +2 -1
- data/lib/avo/version.rb +1 -1
- data/lib/generators/avo/templates/locales/avo.en.yml +4 -0
- data/public/avo-assets/avo.css +812 -214
- data/public/avo-assets/avo.js +212 -123
- data/public/avo-assets/avo.js.map +3 -3
- metadata +19 -2
@@ -4,6 +4,7 @@
|
|
4
4
|
@import './../../../node_modules/trix/dist/trix.css';
|
5
5
|
@import './../../../node_modules/flatpickr/dist/flatpickr.css';
|
6
6
|
@import './../../../node_modules/@algolia/autocomplete-theme-classic/dist/theme.css';
|
7
|
+
@import './../../../node_modules/@yaireo/tagify/dist/tagify.css';
|
7
8
|
|
8
9
|
@import 'tailwindcss/base';
|
9
10
|
|
@@ -11,12 +12,14 @@
|
|
11
12
|
@import './css/buttons.css';
|
12
13
|
@import './css/typography.css';
|
13
14
|
@import './css/tooltips.css';
|
15
|
+
@import './css/alerts.css';
|
14
16
|
@import './css/loader.css';
|
15
17
|
@import './css/pagination.css';
|
16
18
|
@import './css/breadcrumbs.css';
|
17
19
|
@import './css/search.css';
|
18
20
|
@import './css/active-storage.css';
|
19
21
|
@import './css/spinner.css';
|
22
|
+
@import './css/tags.css';
|
20
23
|
|
21
24
|
@import './css/components/status.css';
|
22
25
|
@import './css/components/code.css';
|
@@ -88,36 +91,3 @@ trix-editor {
|
|
88
91
|
max-height: 320px !important;
|
89
92
|
overflow-y: auto;
|
90
93
|
}
|
91
|
-
|
92
|
-
.scroll-shadows {
|
93
|
-
background:
|
94
|
-
/* Shadow Cover TOP */
|
95
|
-
linear-gradient(
|
96
|
-
#F6F6F7 30%,
|
97
|
-
#F6F6F7
|
98
|
-
) center top,
|
99
|
-
|
100
|
-
/* Shadow Cover BOTTOM */
|
101
|
-
linear-gradient(
|
102
|
-
#F6F6F7,
|
103
|
-
#F6F6F7 70%
|
104
|
-
) center bottom,
|
105
|
-
|
106
|
-
/* Shadow TOP */
|
107
|
-
radial-gradient(
|
108
|
-
farthest-side at 50% 0,
|
109
|
-
rgba(0, 0, 0, 0.2),
|
110
|
-
rgba(0, 0, 0, 0)
|
111
|
-
) center top,
|
112
|
-
|
113
|
-
/* Shadow BOTTOM */
|
114
|
-
radial-gradient(
|
115
|
-
farthest-side at 50% 100%,
|
116
|
-
rgba(0, 0, 0, 0.2),
|
117
|
-
rgba(0, 0, 0, 0)
|
118
|
-
) center bottom;
|
119
|
-
|
120
|
-
background-repeat: no-repeat;
|
121
|
-
background-size: 100% 34px, 100% 34px, 100% 14px, 100% 14px;
|
122
|
-
background-attachment: local, local, scroll, scroll;
|
123
|
-
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#toast-container > div {
|
2
|
+
box-shadow: none;
|
3
|
+
background-size: 1.5rem;
|
4
|
+
background-position: 0.8rem 0.8rem;
|
5
|
+
width: 500px;
|
6
|
+
|
7
|
+
@apply shadow-md opacity-100 border border-gray-200 rounded-md pt-3 pr-3 pb-3 bg-white;
|
8
|
+
|
9
|
+
&:hover {
|
10
|
+
@apply shadow-xl;
|
11
|
+
}
|
12
|
+
|
13
|
+
.toast-title {
|
14
|
+
@apply text-gray-800;
|
15
|
+
}
|
16
|
+
.toast-message {
|
17
|
+
@apply text-gray-800;
|
18
|
+
}
|
19
|
+
|
20
|
+
&.toast-success {
|
21
|
+
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0iIzM4YTE2OSI+CiAgPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNi4yNjcgMy40NTVhMy4wNjYgMy4wNjYgMCAwMDEuNzQ1LS43MjMgMy4wNjYgMy4wNjYgMCAwMTMuOTc2IDAgMy4wNjYgMy4wNjYgMCAwMDEuNzQ1LjcyMyAzLjA2NiAzLjA2NiAwIDAxMi44MTIgMi44MTJjLjA1MS42NDMuMzA0IDEuMjU0LjcyMyAxLjc0NWEzLjA2NiAzLjA2NiAwIDAxMCAzLjk3NiAzLjA2NiAzLjA2NiAwIDAwLS43MjMgMS43NDUgMy4wNjYgMy4wNjYgMCAwMS0yLjgxMiAyLjgxMiAzLjA2NiAzLjA2NiAwIDAwLTEuNzQ1LjcyMyAzLjA2NiAzLjA2NiAwIDAxLTMuOTc2IDAgMy4wNjYgMy4wNjYgMCAwMC0xLjc0NS0uNzIzIDMuMDY2IDMuMDY2IDAgMDEtMi44MTItMi44MTIgMy4wNjYgMy4wNjYgMCAwMC0uNzIzLTEuNzQ1IDMuMDY2IDMuMDY2IDAgMDEwLTMuOTc2IDMuMDY2IDMuMDY2IDAgMDAuNzIzLTEuNzQ1IDMuMDY2IDMuMDY2IDAgMDEyLjgxMi0yLjgxMnptNy40NCA1LjI1MmExIDEgMCAwMC0xLjQxNC0xLjQxNEw5IDEwLjU4NiA3LjcwNyA5LjI5M2ExIDEgMCAwMC0xLjQxNCAxLjQxNGwyIDJhMSAxIDAgMDAxLjQxNCAwbDQtNHoiIGNsaXAtcnVsZT0iZXZlbm9kZCIgLz4KPC9zdmc+Cg==) !important;
|
22
|
+
}
|
23
|
+
|
24
|
+
&.toast-warning {
|
25
|
+
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0icmdiYSgyMTcsIDExOSwgNiwgMSkiPgogIDxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTguMjU3IDMuMDk5Yy43NjUtMS4zNiAyLjcyMi0xLjM2IDMuNDg2IDBsNS41OCA5LjkyYy43NSAxLjMzNC0uMjEzIDIuOTgtMS43NDIgMi45OEg0LjQyYy0xLjUzIDAtMi40OTMtMS42NDYtMS43NDMtMi45OGw1LjU4LTkuOTJ6TTExIDEzYTEgMSAwIDExLTIgMCAxIDEgMCAwMTIgMHptLTEtOGExIDEgMCAwMC0xIDF2M2ExIDEgMCAwMDIgMFY2YTEgMSAwIDAwLTEtMXoiIGNsaXAtcnVsZT0iZXZlbm9kZCIgLz4KPC9zdmc+Cg==) !important;
|
26
|
+
}
|
27
|
+
|
28
|
+
&.toast-info {
|
29
|
+
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0icmdiYSgzNywgOTksIDIzNSwgMSkiPgogIDxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTE4IDEwYTggOCAwIDExLTE2IDAgOCA4IDAgMDExNiAwem0tNy00YTEgMSAwIDExLTIgMCAxIDEgMCAwMTIgMHpNOSA5YTEgMSAwIDAwMCAydjNhMSAxIDAgMDAxIDFoMWExIDEgMCAxMDAtMnYtM2ExIDEgMCAwMC0xLTFIOXoiIGNsaXAtcnVsZT0iZXZlbm9kZCIgLz4KPC9zdmc+Cg==) !important;
|
30
|
+
}
|
31
|
+
|
32
|
+
&.toast-error {
|
33
|
+
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0icmdiYSgyMjAsIDM4LCAzOCwgMSkiPgogIDxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTE4IDEwYTggOCAwIDExLTE2IDAgOCA4IDAgMDExNiAwem0tNyA0YTEgMSAwIDExLTIgMCAxIDEgMCAwMTIgMHptLTEtOWExIDEgMCAwMC0xIDF2NGExIDEgMCAxMDIgMFY2YTEgMSAwIDAwLTEtMXoiIGNsaXAtcnVsZT0iZXZlbm9kZCIgLz4KPC9zdmc+Cg==) !important;
|
34
|
+
}
|
35
|
+
}
|
@@ -1,3 +1,3 @@
|
|
1
|
-
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
2
2
|
<path d="M11 6a3 3 0 11-6 0 3 3 0 016 0zM14 17a6 6 0 00-12 0h12zM13 8a1 1 0 100 2h4a1 1 0 100-2h-4z"/>
|
3
3
|
</svg>
|
@@ -3,8 +3,7 @@
|
|
3
3
|
data-actions-picker-enabled-class="text-black hover:bg-blue-500 hover:text-white"
|
4
4
|
data-actions-picker-disabled-class="cursor-wait text-gray-500"
|
5
5
|
>
|
6
|
-
<%= a_button style: :
|
7
|
-
color: :primary,
|
6
|
+
<%= a_button style: :primary,
|
8
7
|
class: "focus:outline-none",
|
9
8
|
icon: 'arrow-circle-right',
|
10
9
|
icon_class: 'transform rotate-90',
|
@@ -13,7 +13,7 @@
|
|
13
13
|
<%== message %>
|
14
14
|
</p>
|
15
15
|
</div>
|
16
|
-
<div class="ml-4 flex-shrink-0 flex
|
16
|
+
<div class="ml-4 flex-shrink-0 flex">
|
17
17
|
<button data-action="alert#close" class="inline-flex text-white focus:outline-none focus:text-gray-300 transition ease-in-out duration-150">
|
18
18
|
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
|
19
19
|
<path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd"/>
|
@@ -12,10 +12,7 @@ class Avo::AlertComponent < ViewComponent::Base
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def icon
|
15
|
-
return "
|
16
|
-
return "heroicons/solid/exclamation" if is_warning?
|
17
|
-
return "heroicons/solid/exclamation-circle" if is_info?
|
18
|
-
return "heroicons/solid/check-circle" if is_success?
|
15
|
+
return "x-circle" if is_error?
|
19
16
|
|
20
17
|
"check-circle"
|
21
18
|
end
|
@@ -24,31 +21,15 @@ class Avo::AlertComponent < ViewComponent::Base
|
|
24
21
|
result = "max-w-lg w-full shadow-lg rounded px-4 py-3 rounded relative border text-white pointer-events-auto"
|
25
22
|
|
26
23
|
result += if is_error?
|
27
|
-
" bg-red-400 border-red-
|
28
|
-
|
29
|
-
" bg-green-
|
30
|
-
elsif is_warning?
|
31
|
-
" bg-orange-400 border-orange-600"
|
32
|
-
elsif is_info?
|
33
|
-
" bg-blue-400 border-blue-600"
|
24
|
+
" bg-red-400 border-red-700"
|
25
|
+
else
|
26
|
+
" bg-green-400 border-green-700"
|
34
27
|
end
|
35
28
|
|
36
29
|
result
|
37
30
|
end
|
38
31
|
|
39
32
|
def is_error?
|
40
|
-
type.to_sym == :error
|
41
|
-
end
|
42
|
-
|
43
|
-
def is_success?
|
44
|
-
type.to_sym == :success
|
45
|
-
end
|
46
|
-
|
47
|
-
def is_info?
|
48
|
-
type.to_sym == :notice || type.to_sym == :info
|
49
|
-
end
|
50
|
-
|
51
|
-
def is_warning?
|
52
|
-
type.to_sym == :warning
|
33
|
+
type.to_sym == :error
|
53
34
|
end
|
54
35
|
end
|
@@ -117,8 +117,6 @@ class Avo::ButtonComponent < ViewComponent::Base
|
|
117
117
|
" bg-primary-500 text-white border-primary-500 hover:bg-primary-600 hover:border-primary-600 active:border-primary-700 active:outline-primary-700 active:bg-primary-600"
|
118
118
|
when :outline
|
119
119
|
" bg-white text-#{@color}-500 border-#{@color}-500 hover:bg-#{@color}-100 active:bg-#{@color}-100 active:border-#{@color}-500 active:outline-#{@color}-500"
|
120
|
-
when :text
|
121
|
-
" text-#{@color}-500 active:outline-#{@color}-500 border-none hover:bg-gray-100"
|
122
120
|
else
|
123
121
|
""
|
124
122
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<%= edit_field_wrapper field: @field, index: @index, form: @form, resource: @resource, displayed_in_modal: @displayed_in_modal do %>
|
2
|
+
<div data-controller="tags-field">
|
3
|
+
<%# dummy field %>
|
4
|
+
<%= text_field_tag "#{@field.id}-dummy", '',
|
5
|
+
class: helpers.input_classes('w-full', has_error: @field.model_errors.include?(@field.id)),
|
6
|
+
placeholder: @field.placeholder,
|
7
|
+
disabled: @field.readonly,
|
8
|
+
value: '',
|
9
|
+
data: {
|
10
|
+
'tags-field-target': 'fakeInput',
|
11
|
+
} %>
|
12
|
+
<%# real field %>
|
13
|
+
<%= @form.text_field @field.id,
|
14
|
+
class: helpers.input_classes('hidden w-full', has_error: @field.model_errors.include?(@field.id)),
|
15
|
+
placeholder: @field.placeholder,
|
16
|
+
disabled: @field.readonly,
|
17
|
+
value: @field.field_value.to_json,
|
18
|
+
data: {
|
19
|
+
'tags-field-target': 'input',
|
20
|
+
'whitelist-items': @field.suggestions.to_json,
|
21
|
+
'blacklist-items': @field.blacklist.to_json,
|
22
|
+
'enforce-suggestions': @field.enforce_suggestions ? 1 : 0,
|
23
|
+
'delimiters': @field.delimiters,
|
24
|
+
'close-on-select': @field.close_on_select ? 1 : 0,
|
25
|
+
} %>
|
26
|
+
</div>
|
27
|
+
<% end %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<%= index_field_wrapper field: @field do %>
|
2
|
+
<div class="flex gap-1 items-center flex-nowrap">
|
3
|
+
<% value.take(3).each do |item| %>
|
4
|
+
<% if @field.acts_as_taggable_on.present? %>
|
5
|
+
<%= render Avo::Fields::TagsField::TagComponent.new(label: item['value']) %>
|
6
|
+
<% else %>
|
7
|
+
<%= render Avo::Fields::TagsField::TagComponent.new(label: item) %>
|
8
|
+
<% end %>
|
9
|
+
<% end %>
|
10
|
+
<% if value.count > 3 %>
|
11
|
+
<%= render Avo::Fields::TagsField::TagComponent.new(label: '...', title: I18n.t('avo.x_items_more', count: value.count - 3)) %>
|
12
|
+
<% end %>
|
13
|
+
</div>
|
14
|
+
<% end %>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<%= show_field_wrapper field: @field, index: @index do %>
|
2
|
+
<div class="flex gap-1 items-center flex-wrap">
|
3
|
+
<% @field.field_value.each do |item| %>
|
4
|
+
<%= render Avo::Fields::TagsField::TagComponent.new(label: label_from_item(item)) %>
|
5
|
+
<% end %>
|
6
|
+
</div>
|
7
|
+
<% end %>
|
@@ -14,7 +14,7 @@
|
|
14
14
|
<% end %>
|
15
15
|
<% end %>
|
16
16
|
<div
|
17
|
-
class="absolute block inset-auto sm:right-0 top-full bg-white min-w-[300px] mt-2 z-20 shadow-modal rounded divide-y divide-gray-300 <%= 'hidden' unless params[:keep_filters_panel_open]
|
17
|
+
class="absolute block inset-auto sm:right-0 top-full bg-white min-w-[300px] mt-2 z-20 shadow-modal rounded divide-y divide-gray-300 <%= 'hidden' unless params[:keep_filters_panel_open] %>"
|
18
18
|
data-toggle-panel-target="panel"
|
19
19
|
>
|
20
20
|
<% @filters.each do |filter| %>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<td class="min-h-[3rem] px-3 leading-tight whitespace-nowrap h-full text-slate-800
|
1
|
+
<td class="min-h-[3rem] px-3 leading-tight whitespace-nowrap h-full 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 %>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<div class="w-full ">
|
2
|
-
<table class="w-full px-4 bg-white
|
2
|
+
<table class="w-full px-4 bg-white" data-resource-name='<%= @resource.model_key %>' data-controller='item-select-all'>
|
3
3
|
<%= render partial: 'avo/partials/table_header', locals: {fields: @resource.get_fields(reflection: @reflection)} %>
|
4
4
|
<tbody class="divide-y">
|
5
5
|
<% @resources.each_with_index do |resource, index| %>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<div <%== data_attributes %>>
|
2
2
|
<% if render_header? %>
|
3
|
-
<div class="flex-1 flex flex-col xl:flex-row justify-between mb-
|
4
|
-
<div class="overflow-hidden flex flex-col">
|
3
|
+
<div class="<%= white_panel_classes %> p-4 flex-1 flex flex-col xl:flex-row justify-between mb-6">
|
4
|
+
<div class="overflow-hidden mr-4 flex flex-col">
|
5
5
|
<% if display_breadcrumbs? %>
|
6
6
|
<div class="breadcrumbs truncate mb-2">
|
7
7
|
<%= 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 %>
|
@@ -13,7 +13,7 @@
|
|
13
13
|
</div>
|
14
14
|
|
15
15
|
<% if description.present? %>
|
16
|
-
<div class="text-
|
16
|
+
<div class="text-base tracking-normal font-medium text-gray-600" data-target="description">
|
17
17
|
<%== description %>
|
18
18
|
</div>
|
19
19
|
<% end %>
|
@@ -11,26 +11,6 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
11
11
|
@resource.authorization.authorize_action(:destroy, raise_exception: false)
|
12
12
|
end
|
13
13
|
|
14
|
-
def can_detach?
|
15
|
-
authorize_association_for("detach")
|
16
|
-
end
|
17
|
-
|
18
|
-
def can_see_the_edit_button?
|
19
|
-
@resource.authorization.authorize_action(:edit, raise_exception: false)
|
20
|
-
end
|
21
|
-
|
22
|
-
def can_see_the_destroy_button?
|
23
|
-
@resource.authorization.authorize_action(:destroy, raise_exception: false)
|
24
|
-
end
|
25
|
-
|
26
|
-
def detach_path
|
27
|
-
helpers.resource_detach_path(params[:resource_name], params[:id], @reflection.name.to_s, @resource.model.id)
|
28
|
-
end
|
29
|
-
|
30
|
-
def destroy_path
|
31
|
-
helpers.resource_path(model: @resource.model, resource: @resource)
|
32
|
-
end
|
33
|
-
|
34
14
|
def authorize_association_for(policy_method)
|
35
15
|
association_policy = true
|
36
16
|
|
@@ -50,34 +30,4 @@ class Avo::ResourceComponent < Avo::BaseComponent
|
|
50
30
|
|
51
31
|
association_policy
|
52
32
|
end
|
53
|
-
|
54
|
-
def split_panel_fields
|
55
|
-
initialize_panels
|
56
|
-
@resource.get_fields.each do |field|
|
57
|
-
case field.class.to_s
|
58
|
-
when "Avo::Fields::HasOneField"
|
59
|
-
@has_one_panels << field
|
60
|
-
when "Avo::Fields::HasManyField"
|
61
|
-
@has_many_panels << field
|
62
|
-
when "Avo::Fields::HasAndBelongsToManyField"
|
63
|
-
@has_as_belongs_to_many_panels << field
|
64
|
-
else
|
65
|
-
@fields_by_panel[field.panel_name] ||= []
|
66
|
-
@fields_by_panel[field.panel_name] << field
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
private
|
72
|
-
|
73
|
-
def initialize_panels
|
74
|
-
@fields_by_panel = {}
|
75
|
-
@has_one_panels = []
|
76
|
-
@has_many_panels = []
|
77
|
-
@has_as_belongs_to_many_panels = []
|
78
|
-
end
|
79
|
-
|
80
|
-
def via_resource?
|
81
|
-
params[:via_resource_class].present? && params[:via_resource_id].present?
|
82
|
-
end
|
83
33
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<div class="flex justify-between
|
1
|
+
<div class="flex justify-between p-4 py-2 text-gray-500">
|
2
2
|
<div class="flex items-center text-sm uppercase font-semibold leading-none space-x-1">
|
3
3
|
<span class="min-w-[20px]"><%= icon %></span> <span><%= label %></span>
|
4
4
|
</div>
|
@@ -23,6 +23,6 @@ class Avo::Sidebar::LinkComponent < ViewComponent::Base
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def classes
|
26
|
-
"px-4 flex-1 flex mx-6 leading-none py-2 text-black rounded font-medium hover:bg-gray-
|
26
|
+
"px-4 flex-1 flex mx-6 leading-none py-2 text-black rounded font-medium hover:bg-gray-150"
|
27
27
|
end
|
28
28
|
end
|
@@ -1,16 +1,24 @@
|
|
1
1
|
<div
|
2
|
-
class="fixed z-[60]
|
2
|
+
class="fixed z-[60] application-sidebar hidden lg:flex h-full bg-white text-white w-64 border-r <%= 'print:hidden' if Avo.configuration.hide_layout_when_printing %>"
|
3
3
|
data-mobile-target="sidebar"
|
4
4
|
>
|
5
5
|
<div class="flex flex-col w-full h-full">
|
6
|
-
<div class="flex
|
6
|
+
<div class="flex justify-between">
|
7
|
+
<%= render partial: "avo/partials/logo" %>
|
8
|
+
<div class="flex items-center mr-4">
|
9
|
+
<%= helpers.a_button class: "lg:hidden", icon: 'menu-back', data: { action: 'click->mobile#toggleSidebar' } %>
|
10
|
+
</div>
|
11
|
+
</div>
|
12
|
+
<div class="flex-1 flex flex-col justify-between overflow-auto mt-3">
|
7
13
|
<div class="space-y-6 mb-4">
|
8
14
|
<%= render Avo::Sidebar::LinkComponent.new label: 'Get started', path: helpers.avo.root_path, active: :exclusive if Rails.env.development? && Avo.configuration.home_path.nil? %>
|
9
15
|
|
10
16
|
<% if Avo::App.has_main_menu? %>
|
11
|
-
|
12
|
-
|
13
|
-
|
17
|
+
<div class="text-black">
|
18
|
+
<% Avo::App.main_menu.items.each do |item| %>
|
19
|
+
<%= render Avo::Sidebar::ItemSwitcherComponent.new item: item %>
|
20
|
+
<% end %>
|
21
|
+
</div>
|
14
22
|
<% else %>
|
15
23
|
|
16
24
|
<% if dashboards.present? %>
|
@@ -1,6 +1,4 @@
|
|
1
|
-
<div data-model-id="<%= @resource.model.id %>"
|
2
|
-
class="space-y-8"
|
3
|
-
>
|
1
|
+
<div data-model-id="<%= @resource.model.id %>">
|
4
2
|
<% @resource.panels.each do |resource_panel| %>
|
5
3
|
<%= form_with model: @resource.model,
|
6
4
|
scope: @resource.form_scope,
|
@@ -11,17 +9,11 @@
|
|
11
9
|
<%= render Avo::ReferrerParamsComponent.new back_path: back_path %>
|
12
10
|
<%= render Avo::PanelComponent.new(title: resource_panel[:name], description: @resource.resource_description, display_breadcrumbs: true) do |c| %>
|
13
11
|
<% c.tools do %>
|
14
|
-
<%= a_link back_path,
|
15
|
-
style: :text,
|
16
|
-
icon: 'arrow-left' do %>
|
12
|
+
<%= a_link back_path, icon: 'arrow-left' do %>
|
17
13
|
<%= t('avo.cancel').capitalize %>
|
18
14
|
<% end %>
|
19
15
|
<% if can_see_the_save_button? %>
|
20
|
-
<%= a_button color: :
|
21
|
-
style: :primary,
|
22
|
-
loading: true,
|
23
|
-
type: :submit,
|
24
|
-
icon: 'save' do %>
|
16
|
+
<%= a_button color: :green, loading: true, type: :submit, icon: 'save' do %>
|
25
17
|
<%= t('avo.save').capitalize %>
|
26
18
|
<% end %>
|
27
19
|
<% end %>
|
@@ -48,21 +40,4 @@
|
|
48
40
|
<% end %>
|
49
41
|
<% end %>
|
50
42
|
<% end %>
|
51
|
-
<% if @reflection.blank? %>
|
52
|
-
<% if has_one_panels.present? %>
|
53
|
-
<% has_one_panels.each_with_index do |field, index| %>
|
54
|
-
<%= render field.component_for_view(:show).new(field: field, resource: @resource, index: index) %>
|
55
|
-
<% end %>
|
56
|
-
<% end %>
|
57
|
-
<% if has_many_panels.present? %>
|
58
|
-
<% has_many_panels.each_with_index do |field, index| %>
|
59
|
-
<%= render field.component_for_view(:show).new(field: field, resource: @resource, index: index) %>
|
60
|
-
<% end %>
|
61
|
-
<% end %>
|
62
|
-
<% if has_as_belongs_to_many_panels.present? %>
|
63
|
-
<% has_as_belongs_to_many_panels.each_with_index do |field, index| %>
|
64
|
-
<%= render field.component_for_view(:show).new(field: field, resource: @resource, index: index) %>
|
65
|
-
<% end %>
|
66
|
-
<% end %>
|
67
|
-
<% end %>
|
68
43
|
</div>
|
@@ -4,12 +4,8 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
|
|
4
4
|
include Avo::ResourcesHelper
|
5
5
|
include Avo::ApplicationHelper
|
6
6
|
|
7
|
-
attr_reader :fields_by_panel, :has_one_panels, :has_many_panels, :has_as_belongs_to_many_panels
|
8
|
-
|
9
7
|
def initialize(resource: nil)
|
10
8
|
@resource = resource
|
11
|
-
|
12
|
-
split_panel_fields
|
13
9
|
end
|
14
10
|
|
15
11
|
def back_path
|
@@ -25,4 +21,10 @@ class Avo::Views::ResourceEditComponent < Avo::ResourceComponent
|
|
25
21
|
def can_see_the_save_button?
|
26
22
|
@resource.authorization.authorize_action :edit, raise_exception: false
|
27
23
|
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def via_resource?
|
28
|
+
params[:via_resource_class].present? && params[:via_resource_id].present?
|
29
|
+
end
|
28
30
|
end
|
@@ -1,28 +1,19 @@
|
|
1
1
|
<div>
|
2
2
|
<%= render Avo::PanelComponent.new(title: title, description: description, data: { component: 'resources-index' }, display_breadcrumbs: @reflection.blank?) do |c| %>
|
3
3
|
<% c.tools do %>
|
4
|
-
<% if can_attach? %>
|
5
|
-
<%= a_link attach_path,
|
6
|
-
icon: 'heroicons/outline/link',
|
7
|
-
color: :primary,
|
8
|
-
style: :text,
|
9
|
-
'data-turbo-frame': 'attach_modal',
|
10
|
-
'data-target': 'attach' do %>
|
11
|
-
<%= t('avo.attach_item', item: singular_resource_name).capitalize %>
|
12
|
-
<% end %>
|
13
|
-
<% end %>
|
14
4
|
<% if can_see_the_actions_button? %>
|
15
5
|
<%= render Avo::ActionsComponent.new actions: @actions, resource: @resource %>
|
16
6
|
<% end %>
|
17
7
|
<% if can_see_the_create_button? %>
|
18
|
-
<%= a_link create_path,
|
19
|
-
icon: 'heroicons/outline/plus',
|
20
|
-
'data-target': 'create',
|
21
|
-
style: :primary,
|
22
|
-
color: :primary do %>
|
8
|
+
<%= a_link create_path, icon: 'heroicons/outline/plus', 'data-target': 'create', color: :primary do %>
|
23
9
|
<%= t('avo.create_new_item', item: singular_resource_name.downcase ) %>
|
24
10
|
<% end %>
|
25
11
|
<% end %>
|
12
|
+
<% if can_attach? %>
|
13
|
+
<%= a_link attach_path, icon: 'heroicons/outline/link', color: :primary, 'data-turbo-frame': 'attach_modal', 'data-target': 'attach' do %>
|
14
|
+
<%= t('avo.attach_item', item: singular_resource_name).capitalize %>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
26
17
|
<% end %>
|
27
18
|
<% c.body do %>
|
28
19
|
<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 %>"
|
@@ -64,6 +55,7 @@
|
|
64
55
|
</div>
|
65
56
|
<% end %>
|
66
57
|
<% end %>
|
58
|
+
|
67
59
|
<% if view_type.to_sym == :grid %>
|
68
60
|
<%= render Avo::Index::ResourceGridComponent.new(resources: @resources, resource: @resource, reflection: @reflection, parent_model: @parent_model) %>
|
69
61
|
<div class="mt-14">
|
@@ -14,17 +14,11 @@
|
|
14
14
|
<%= render Avo::PanelComponent.new(title: resource_panel[:name], description: @resource.resource_description, display_breadcrumbs: true) do |c| %>
|
15
15
|
<% c.tools do %>
|
16
16
|
<div class="flex justify-end space-x-2">
|
17
|
-
<%= a_link back_path,
|
18
|
-
style: :text,
|
19
|
-
icon: 'arrow-left' do %>
|
17
|
+
<%= a_link back_path, icon: 'arrow-left' do %>
|
20
18
|
<%= t('avo.cancel').capitalize %>
|
21
19
|
<% end %>
|
22
20
|
<% if can_see_the_save_button? %>
|
23
|
-
<%= a_button color: :
|
24
|
-
style: :primary,
|
25
|
-
loading: true,
|
26
|
-
type: :submit,
|
27
|
-
icon: 'save' do %>
|
21
|
+
<%= a_button color: 'green', loading: true, type: :submit, icon: 'save' do %>
|
28
22
|
<%= t('avo.save').capitalize %>
|
29
23
|
<% end %>
|
30
24
|
<% end %>
|