avo 2.5.2.pre.6 → 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.

Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +4 -1
  4. data/app/assets/builds/avo.css +766 -301
  5. data/app/assets/builds/avo.js +212 -123
  6. data/app/assets/builds/avo.js.map +3 -3
  7. data/app/assets/stylesheets/avo.css +3 -33
  8. data/app/assets/stylesheets/css/alerts.css +35 -0
  9. data/app/assets/stylesheets/css/search.css +1 -1
  10. data/app/assets/stylesheets/css/tags.css +16 -0
  11. data/app/assets/svgs/heroicons/solid/user-remove.svg +1 -1
  12. data/app/components/avo/actions_component.html.erb +1 -2
  13. data/app/components/avo/alert_component.html.erb +1 -1
  14. data/app/components/avo/alert_component.rb +5 -24
  15. data/app/components/avo/button_component.rb +7 -46
  16. data/app/components/avo/fields/tags_field/edit_component.html.erb +27 -0
  17. data/app/components/avo/fields/tags_field/edit_component.rb +4 -0
  18. data/app/components/avo/fields/tags_field/index_component.html.erb +14 -0
  19. data/app/components/avo/fields/tags_field/index_component.rb +7 -0
  20. data/app/components/avo/fields/tags_field/show_component.html.erb +7 -0
  21. data/app/components/avo/fields/tags_field/show_component.rb +11 -0
  22. data/app/components/avo/fields/tags_field/tag_component.html.erb +9 -0
  23. data/app/components/avo/fields/tags_field/tag_component.rb +11 -0
  24. data/app/components/avo/filters_component.html.erb +1 -1
  25. data/app/components/avo/index/field_wrapper_component.html.erb +1 -1
  26. data/app/components/avo/index/grid_cover_empty_state_component.html.erb +1 -1
  27. data/app/components/avo/index/resource_table_component.html.erb +1 -1
  28. data/app/components/avo/index/table_row_component.html.erb +1 -1
  29. data/app/components/avo/panel_component.html.erb +3 -3
  30. data/app/components/avo/panel_component.rb +1 -1
  31. data/app/components/avo/resource_component.rb +0 -50
  32. data/app/components/avo/sidebar/group_component.html.erb +2 -4
  33. data/app/components/avo/sidebar/heading_component.html.erb +1 -1
  34. data/app/components/avo/sidebar/link_component.html.erb +1 -1
  35. data/app/components/avo/sidebar/link_component.rb +1 -1
  36. data/app/components/avo/sidebar_component.html.erb +13 -5
  37. data/app/components/avo/sidebar_profile_component.html.erb +1 -1
  38. data/app/components/avo/views/resource_edit_component.html.erb +3 -28
  39. data/app/components/avo/views/resource_edit_component.rb +6 -4
  40. data/app/components/avo/views/resource_index_component.html.erb +9 -17
  41. data/app/components/avo/views/resource_new_component.html.erb +2 -8
  42. data/app/components/avo/views/resource_show_component.html.erb +6 -16
  43. data/app/components/avo/views/resource_show_component.rb +45 -0
  44. data/app/controllers/avo/actions_controller.rb +8 -23
  45. data/app/controllers/avo/associations_controller.rb +3 -3
  46. data/app/controllers/avo/base_controller.rb +16 -25
  47. data/app/controllers/avo/private_controller.rb +0 -1
  48. data/app/controllers/avo/search_controller.rb +2 -2
  49. data/app/helpers/avo/application_helper.rb +1 -1
  50. data/app/javascript/js/application.js +1 -1
  51. data/app/javascript/js/controllers/alerts_controller.js +26 -0
  52. data/app/javascript/js/controllers/base_controller.js +22 -0
  53. data/app/javascript/js/controllers/fields/key_value_controller.js +1 -1
  54. data/app/javascript/js/controllers/fields/tags_field_controller.js +86 -0
  55. data/app/javascript/js/controllers/fields/tags_field_helpers.js +47 -0
  56. data/app/javascript/js/controllers/filter_controller.js +1 -4
  57. data/app/javascript/js/controllers.js +4 -0
  58. data/app/views/avo/actions/show.html.erb +2 -5
  59. data/app/views/avo/partials/_logo.html.erb +1 -1
  60. data/app/views/avo/partials/_navbar.html.erb +6 -9
  61. data/app/views/avo/partials/_table_header.html.erb +2 -3
  62. data/app/views/avo/private/_links_and_buttons.html.erb +2 -2
  63. data/app/views/layouts/avo/application.html.erb +53 -50
  64. data/db/factories.rb +2 -0
  65. data/lib/avo/base_action.rb +6 -24
  66. data/lib/avo/base_resource.rb +6 -0
  67. data/lib/avo/concerns/handles_field_args.rb +36 -0
  68. data/lib/avo/engine.rb +1 -1
  69. data/lib/avo/fields/base_field.rb +2 -1
  70. data/lib/avo/fields/belongs_to_field.rb +4 -4
  71. data/lib/avo/fields/has_and_belongs_to_many_field.rb +2 -2
  72. data/lib/avo/fields/has_base_field.rb +0 -2
  73. data/lib/avo/fields/has_many_field.rb +2 -2
  74. data/lib/avo/fields/has_one_field.rb +2 -2
  75. data/lib/avo/fields/tags_field.rb +82 -0
  76. data/lib/avo/hosts/record_host.rb +7 -0
  77. data/lib/avo/licensing/pro_license.rb +2 -1
  78. data/lib/avo/version.rb +1 -1
  79. data/lib/generators/avo/templates/locales/avo.en.yml +4 -0
  80. data/public/avo-assets/avo.css +825 -262
  81. data/public/avo-assets/avo.js +212 -123
  82. data/public/avo-assets/avo.js.map +3 -3
  83. 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
+ }
@@ -32,7 +32,7 @@
32
32
 
33
33
  .aa-DetachedFormContainer,
34
34
  .aa-DetachedContainer .aa-Panel {
35
- @apply bg-gray-50 border-b-0;
35
+ @apply bg-gray-100 border-b-0;
36
36
  }
37
37
 
38
38
  .aa-Form {
@@ -0,0 +1,16 @@
1
+ tags.tagify {
2
+ --tag-inset-shadow-size: 3em;
3
+ }
4
+
5
+ tags.tagify {
6
+ @apply !p-0;
7
+
8
+ span.tagify__input {
9
+ @apply my-1;
10
+ }
11
+ }
12
+
13
+ tag.tagify__tag {
14
+ @apply text-sm my-1 mb-0;
15
+ }
16
+
@@ -1,3 +1,3 @@
1
- or<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
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: :outline,
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 items-center">
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 "heroicons/solid/x-circle" if is_error?
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-600"
28
- elsif is_success?
29
- " bg-green-500 border-green-600"
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 || type.to_sym == :alert
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
@@ -38,15 +38,14 @@ class Avo::ButtonComponent < ViewComponent::Base
38
38
  end
39
39
 
40
40
  def button_classes
41
- classes = "button-component inline-flex flex-grow-0 items-center font-semibold leading-6 fill-current whitespace-nowrap transition duration-100 transform transition duration-100 cursor-pointer disabled:cursor-not-allowed disabled:opacity-70 border justify-center active:outline active:outline-1 #{@class}"
41
+ classes = "button-component inline-flex flex-grow-0 items-center text-sm font-semibold leading-6 fill-current whitespace-nowrap transition duration-100 transform transition duration-100 cursor-pointer disabled:cursor-not-allowed disabled:opacity-70 border justify-center active:outline active:outline-1 #{@class}"
42
42
 
43
43
  classes += " rounded" if @rounded.present?
44
44
 
45
45
  classes += style_classes
46
46
 
47
- classes += padding_classes
47
+ classes += @compact ? " px-1" : " px-4" # Same horizontal padding on all sizes
48
48
  classes += spacing_classes
49
- classes += text_size_classes
50
49
 
51
50
  classes
52
51
  end
@@ -58,14 +57,10 @@ class Avo::ButtonComponent < ViewComponent::Base
58
57
  def full_content
59
58
  result = ""
60
59
  icon_classes = @icon_class
61
- # space out the icon from the text if text is present
62
- icon_classes += " mr-1" if content.present?
63
- # add the icon height
64
- icon_classes += icon_size_classes
60
+ icon_classes += full_content_icon_classes
65
61
 
66
- # Add the icon
67
62
  result += helpers.svg(@icon, class: icon_classes) if @icon.present?
68
-
63
+ result += "<span class='w-0 m-0'>&nbsp;</span>"
69
64
  if content.present?
70
65
  result += "<span>#{content}</span>"
71
66
  end
@@ -108,58 +103,26 @@ class Avo::ButtonComponent < ViewComponent::Base
108
103
  when :sm
109
104
  " py-1"
110
105
  when :md
111
- " py-1.5"
112
- when :lg
113
106
  " py-2"
114
- when :xl
107
+ when :lg
115
108
  " py-3"
116
109
  else
117
110
  ""
118
111
  end
119
112
  end
120
113
 
121
- def padding_classes
122
- return " px-1" if @compact
123
-
124
- case @size.to_sym
125
- when :xs
126
- " px-2"
127
- when :sm
128
- " px-3"
129
- when :md
130
- " px-3"
131
- when :lg
132
- " px-5"
133
- when :xl
134
- " px-6"
135
- else
136
- "px-4"
137
- end
138
- end
139
-
140
- def text_size_classes
141
- case @size.to_sym
142
- when :xs
143
- " text-xs"
144
- else
145
- " text-sm"
146
- end
147
- end
148
-
149
114
  def style_classes
150
115
  case @style
151
116
  when :primary
152
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"
153
118
  when :outline
154
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"
155
- when :text
156
- " text-#{@color}-500 active:outline-#{@color}-500 hover:bg-gray-100 border-transparent"
157
120
  else
158
121
  ""
159
122
  end
160
123
  end
161
124
 
162
- def icon_size_classes
125
+ def full_content_icon_classes
163
126
  icon_classes = ""
164
127
 
165
128
  case @size
@@ -172,12 +135,10 @@ class Avo::ButtonComponent < ViewComponent::Base
172
135
  # When icon is solo we need to add an offset
173
136
  icon_classes += " my-1" if content.blank?
174
137
  when :md
175
- icon_classes += " h-4 my-1.5"
138
+ icon_classes += " h-5"
176
139
  # When icon is solo we need to add an offset
177
140
  icon_classes += " my-0.5" if content.blank?
178
141
  when :lg
179
- icon_classes += " h-5 my-2"
180
- when :xl
181
142
  icon_classes += " h-6"
182
143
  end
183
144
 
@@ -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,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Avo::Fields::TagsField::EditComponent < Avo::Fields::EditComponent
4
+ 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
+ # frozen_string_literal: true
2
+
3
+ class Avo::Fields::TagsField::IndexComponent < Avo::Fields::IndexComponent
4
+ def value
5
+ @field.field_value
6
+ end
7
+ 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 %>
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Avo::Fields::TagsField::ShowComponent < Avo::Fields::ShowComponent
4
+ def label_from_item(item)
5
+ if @field.acts_as_taggable_on.present?
6
+ item['value']
7
+ else
8
+ item
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ <div class="flex px-2 py-1 rounded bg-gray-200 text-sm text-gray-800 font-normal flex-shrink-0"
2
+ <% if title.present? %>
3
+ data-tippy="tooltip"
4
+ title="<%= title %>"
5
+ <% end %>
6
+ data-target="tag-component"
7
+ >
8
+ <%= label %>
9
+ </div>
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Avo::Fields::TagsField::TagComponent < ViewComponent::Base
4
+ attr_reader :label
5
+ attr_reader :title
6
+
7
+ def initialize(label: nil, title: nil)
8
+ @label = label
9
+ @title = title
10
+ end
11
+ 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] == '1' %>"
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 text-base <%= classes %>" data-field-id="<%= @field.id %>" data-field-type="<%= @field.type %>">
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,3 +1,3 @@
1
- <div class="absolute bg-gray-50 w-full h-full">
1
+ <div class="absolute bg-gray-100 w-full h-full">
2
2
  <%= helpers.svg 'avocado', class: 'relative transform -translate-x-1/2 -translate-y-1/2 h-20 text-gray-400 inset-auto top-1/2 left-1/2' %>
3
3
  </div>
@@ -1,5 +1,5 @@
1
1
  <div class="w-full ">
2
- <table class="w-full px-4 bg-white rounded" data-resource-name='<%= @resource.model_key %>' data-controller='item-select-all'>
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,5 +1,5 @@
1
1
  <tr
2
- class="bg-white hover:bg-gray-50 hover:shadow-row hover:z-[21] relative z-20 border-b"
2
+ class="bg-white hover:bg-blue-50 hover:shadow-row hover:z-[21] relative z-20 border-b"
3
3
  <%== item_selector_init @resource %>
4
4
  >
5
5
  <% if @resource.record_selector %>
@@ -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">
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-sm tracking-normal font-medium text-gray-600" data-target="description">
16
+ <div class="text-base tracking-normal font-medium text-gray-600" data-target="description">
17
17
  <%== description %>
18
18
  </div>
19
19
  <% end %>
@@ -21,7 +21,7 @@ class Avo::PanelComponent < ViewComponent::Base
21
21
  private
22
22
 
23
23
  def white_panel_classes
24
- "bg-white rounded shadow"
24
+ 'bg-white rounded shadow'
25
25
  end
26
26
 
27
27
  def data_attributes
@@ -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
@@ -7,9 +7,7 @@
7
7
  <% end %>
8
8
  >
9
9
  <% if item.name.present? %>
10
- <div
11
- class="flex justify-between px-10 pr-2 pt-2 pb-0 text-gray-400"
12
- >
10
+ <div class="flex justify-between px-10 pt-2 pb-0 text-gray-600 ">
13
11
  <div class="flex items-center text-xs uppercase font-semibold leading-none">
14
12
  <%= item.name %>
15
13
  </div>
@@ -19,7 +17,7 @@
19
17
  data-menu-target="svg"
20
18
  data-menu-key-param="<%= key %>"
21
19
  >
22
- <%= helpers.svg 'heroicons/outline/chevron-down', class: "h-4 mr-0.5"%>
20
+ <%= helpers.svg 'heroicons/outline/chevron-down', class: "h-4"%>
23
21
  </div>
24
22
  <% end %>
25
23
  </div>
@@ -1,4 +1,4 @@
1
- <div class="flex justify-between px-4 pr-2 py-1 text-gray-500">
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>
@@ -2,7 +2,7 @@
2
2
  <%= send link_method, path, class: classes, active: active, target: target do %>
3
3
  <%= label %>
4
4
  <% if target == :_blank %>
5
- <%= helpers.svg('heroicons/outline/external-link', class: 'self-center ml-auto h-3 mr-2') %>
5
+ <%= helpers.svg('heroicons/outline/external-link', class: 'self-center ml-auto h-3') %>
6
6
  <% end %>
7
7
  <% end %>
8
8
  <% else %>
@@ -23,6 +23,6 @@ class Avo::Sidebar::LinkComponent < ViewComponent::Base
23
23
  end
24
24
 
25
25
  def classes
26
- "px-4 pr-0 flex-1 flex mx-6 leading-none py-2 text-black rounded font-medium hover:bg-gray-100"
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] t-0 application-sidebar hidden lg:flex flex-1 border-r lg:border-none bg-none min-w-[16rem] h-[calc(100vh-4rem)] bg-gray-25 lg:bg-transparent <%= 'print:hidden' if Avo.configuration.hide_layout_when_printing %>"
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-1 flex flex-col justify-between overflow-auto h-full pt-3 scroll-shadows">
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
- <% Avo::App.main_menu.items.each do |item| %>
12
- <%= render Avo::Sidebar::ItemSwitcherComponent.new item: item %>
13
- <% end %>
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,4 +1,4 @@
1
- <div class="text-black Xborder-t border-gray-200 p-4 flex">
1
+ <div class="text-black border-t border-gray-200 p-4 flex">
2
2
  <div class="flex-1 flex space-x-4">
3
3
  <% if avatar.present? %>
4
4
  <div class="relative aspect-square w-10 h-10 overflow-hidden rounded">