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.

Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +4 -6
  3. data/app/assets/images/avo/logo.png +0 -0
  4. data/app/assets/stylesheets/avo.css +1 -1
  5. data/app/assets/stylesheets/css/fonts.css +0 -53
  6. data/app/assets/stylesheets/css/pagination.css +9 -9
  7. data/app/assets/stylesheets/css/search.css +2 -3
  8. data/app/components/avo/fields/belongs_to_field/autocomplete_component.rb +19 -19
  9. data/app/components/avo/fields/belongs_to_field/edit_component.html.erb +16 -8
  10. data/app/components/avo/fields/boolean_field/index_component.html.erb +1 -1
  11. data/app/components/avo/fields/select_field/edit_component.html.erb +3 -3
  12. data/app/components/avo/index/field_wrapper_component.html.erb +2 -8
  13. data/app/components/avo/index/field_wrapper_component.rb +1 -2
  14. data/app/components/avo/index/resource_table_component.html.erb +3 -3
  15. data/app/components/avo/index/table_row_component.html.erb +1 -1
  16. data/app/components/avo/navigation_heading_component.html.erb +2 -2
  17. data/app/components/avo/navigation_heading_component.rb +1 -5
  18. data/app/components/avo/navigation_link_component.html.erb +2 -2
  19. data/app/components/avo/navigation_link_component.rb +2 -6
  20. data/app/components/avo/panel_component.html.erb +3 -5
  21. data/app/components/avo/views/resource_index_component.html.erb +7 -8
  22. data/app/components/avo/views/resource_show_component.html.erb +0 -10
  23. data/app/controllers/avo/application_controller.rb +16 -14
  24. data/app/controllers/avo/base_controller.rb +2 -4
  25. data/app/controllers/avo/relations_controller.rb +1 -4
  26. data/app/helpers/avo/application_helper.rb +5 -7
  27. data/app/helpers/avo/resources_helper.rb +2 -2
  28. data/app/javascript/avo.js +1 -0
  29. data/app/javascript/js/controllers/fields/belongs_to_field_controller.js +23 -15
  30. data/app/views/avo/base/_actions.html.erb +3 -4
  31. data/app/views/avo/base/_filters.html.erb +1 -3
  32. data/app/views/avo/partials/_global_search.html.erb +2 -2
  33. data/app/views/avo/partials/_logo.html.erb +1 -1
  34. data/app/views/avo/partials/_paginator.html.erb +3 -4
  35. data/app/views/avo/partials/_profile_dropdown.html.erb +25 -0
  36. data/app/views/avo/partials/_resource_search.html.erb +1 -1
  37. data/app/views/avo/partials/_table_header.html.erb +3 -3
  38. data/app/views/avo/partials/_turbo_frame_wrap.html.erb +1 -1
  39. data/app/views/avo/partials/_view_toggle_button.html.erb +16 -22
  40. data/app/views/avo/relations/new.html.erb +1 -1
  41. data/app/views/avo/{partials → sidebar}/_sidebar.html.erb +10 -14
  42. data/app/views/layouts/avo/application.html.erb +13 -3
  43. data/db/factories.rb +2 -2
  44. data/lib/avo/app.rb +3 -4
  45. data/lib/avo/fields/base_field.rb +7 -4
  46. data/lib/avo/fields/belongs_to_field.rb +92 -11
  47. data/lib/avo/fields/key_value_field.rb +28 -8
  48. data/lib/avo/version.rb +1 -1
  49. data/lib/generators/avo/templates/locales/avo.en.yml +1 -0
  50. data/lib/generators/avo/templates/locales/avo.nb-NO.yml +1 -0
  51. data/lib/generators/avo/templates/locales/avo.pt-BR.yml +1 -0
  52. data/lib/generators/avo/templates/locales/avo.ro.yml +1 -0
  53. data/public/avo-assets/avo.css +224 -405
  54. data/public/avo-assets/avo.js +24 -12
  55. data/public/avo-assets/avo.js.map +2 -2
  56. data/public/avo-assets/logo.png +0 -0
  57. metadata +7 -37
  58. data/app/assets/builds/avo.css +0 -8787
  59. data/app/assets/builds/avo.js +0 -87848
  60. data/app/assets/builds/avo.js.map +0 -7
  61. data/app/assets/svgs/dashboards-icon.svg +0 -6
  62. data/app/assets/svgs/resources-icon.svg +0 -13
  63. data/app/assets/svgs/three-dots.svg +0 -5
  64. data/app/assets/svgs/tools-icon.svg +0 -3
  65. data/app/components/avo/button_component.html.erb +0 -1
  66. data/app/components/avo/button_component.rb +0 -111
  67. data/app/components/avo/sidebar_profile_component.html.erb +0 -28
  68. data/app/components/avo/sidebar_profile_component.rb +0 -43
  69. data/app/views/avo/partials/_navbar.html.erb +0 -11
  70. data/public/avo-assets/fonts/inter-v7-latin-500.eot +0 -0
  71. data/public/avo-assets/fonts/inter-v7-latin-500.svg +0 -351
  72. data/public/avo-assets/fonts/inter-v7-latin-500.ttf +0 -0
  73. data/public/avo-assets/fonts/inter-v7-latin-500.woff +0 -0
  74. data/public/avo-assets/fonts/inter-v7-latin-500.woff2 +0 -0
  75. data/public/avo-assets/fonts/inter-v7-latin-600.eot +0 -0
  76. data/public/avo-assets/fonts/inter-v7-latin-600.svg +0 -351
  77. data/public/avo-assets/fonts/inter-v7-latin-600.ttf +0 -0
  78. data/public/avo-assets/fonts/inter-v7-latin-600.woff +0 -0
  79. data/public/avo-assets/fonts/inter-v7-latin-600.woff2 +0 -0
  80. data/public/avo-assets/fonts/inter-v7-latin-700.eot +0 -0
  81. data/public/avo-assets/fonts/inter-v7-latin-700.svg +0 -352
  82. data/public/avo-assets/fonts/inter-v7-latin-700.ttf +0 -0
  83. data/public/avo-assets/fonts/inter-v7-latin-700.woff +0 -0
  84. data/public/avo-assets/fonts/inter-v7-latin-700.woff2 +0 -0
  85. data/public/avo-assets/fonts/inter-v7-latin-regular.eot +0 -0
  86. data/public/avo-assets/fonts/inter-v7-latin-regular.svg +0 -351
  87. data/public/avo-assets/fonts/inter-v7-latin-regular.ttf +0 -0
  88. data/public/avo-assets/fonts/inter-v7-latin-regular.woff +0 -0
  89. 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: 10a2613406476740ca5a3cff815bce94c985676c702f530a4c22d0b0607384f3
4
- data.tar.gz: 06c2d049cbbff831857d26d6985b6f430955d70342c83e813b9599fbd510f619
3
+ metadata.gz: '04783e6660bd1ebada3544318b2f48082e3e43eb4bc7ee3df2986a9951d04090'
4
+ data.tar.gz: 6e997ae6e0dbb4eaa7828b669b73efd811370c0cfb5213d405f15bdd41bb9240
5
5
  SHA512:
6
- metadata.gz: d7c1b1c2e51a5e0b6f5504090dda1b3853706204f107b5edc1fb76834b04b0c1da099fddeed4337a8ec92c5592f3774d22bb637f7bd1ff48db2bf8f9b86ff9b6
7
- data.tar.gz: cb7873e95cd907c54d6d5cb2d91c7e4af733f200a28ccf4e70a52a04f3db294047bbd7a02bfd74623cbdaa06fcddcf8f4e4ec777ac9d7769e25ef153977dce71
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.0.pre.1)
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.7.1)
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.1)
231
- mini_portile2 (~> 2.7.0)
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
@@ -70,7 +70,7 @@ body {
70
70
 
71
71
  .application-sidebar .active:hover,
72
72
  .application-sidebar .active {
73
- @apply bg-blue-100 text-blue-500;
73
+ @apply bg-gray-200;
74
74
  }
75
75
 
76
76
  .turbo-progress-bar {
@@ -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-white shadow-md;
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-200;
31
+ @apply bg-gray-300;
32
32
  }
33
33
 
34
34
  &:active{
35
- @apply bg-gray-200;
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-300 cursor-default;
45
+ @apply text-gray-400 cursor-default;
46
46
 
47
47
  &:hover {
48
- @apply text-gray-300 bg-white;
48
+ @apply text-gray-400 bg-gray-200;
49
49
  }
50
50
 
51
51
  &:active {
52
- @apply text-gray-300 bg-white;
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-500;
58
+ @apply text-white cursor-default bg-gray-400;
59
59
 
60
60
  &:hover {
61
- @apply text-white bg-gray-500;
61
+ @apply text-white bg-gray-400;
62
62
  }
63
63
 
64
64
  &:active {
65
- @apply bg-gray-500 text-white;
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: 117, 125, 138;
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
- if searchable?
17
- # New records won't have the value (instantiated model) present but the polymorphic_type and polymorphic_id prefilled
18
- if new_record? && has_polymorphic_association?
19
- @polymorphic_record.send(polymorphic_fields[:label])
20
- else
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
- if searchable?
30
- # New records won't have the value (instantiated model) present but the polymorphic_type and polymorphic_id prefilled
31
- if new_record? && has_polymorphic_association?
32
- @polymorphic_record.send(polymorphic_fields[:id])
33
- else
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
- @type.present?
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 "#{@field.foreign_key}_type", @field.types.map { |type| [type.to_s.underscore.humanize, type.to_s] },
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 "#{@field.foreign_key}_type" %>
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: "#{@field.foreign_key}_id",
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 "#{@field.foreign_key}_id", options_for_select(@field.values_for_type(type), @resource.present? && @resource.model.present? ? @resource.model["#{@field.foreign_key}_id"] : nil),
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["#{@field.foreign_key}_id"].to_s,
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.foreign_key,
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.foreign_key, @field.options.map { |o| [o[:label], o[:value]] },
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.foreign_key %>
99
+ <%= @form.hidden_field @field.id_input_foreign_key %>
92
100
  <% end %>
93
101
  <% end %>
94
102
  <% end %>
@@ -1,3 +1,3 @@
1
- <%= index_field_wrapper field: @field, dash_if_blank: false, center_content: true do %>
1
+ <%= index_field_wrapper field: @field, dash_if_blank: false do %>
2
2
  <%= render Avo::Fields::Common::BooleanCheckComponent.new checked: @field.value %>
3
3
  <% 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
- 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 } %>
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-3 leading-tight whitespace-nowrap h-full text-slate-800 <%= @classes %>" data-field-id="<%= @field.id %>" data-field-type="<%= @field.type %>">
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
- <% if @center_content %>
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, center_content: false, **args)
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 bg-white rounded shadow " data-resource-name='<%= @resource.model_key %>' data-controller='item-select-all'>
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 class="divide-y">
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,5 +1,5 @@
1
1
  <tr
2
- class="bg-white hover:bg-sky-50 hover:shadow-row relative z-20 border-b"
2
+ class="hover:bg-sky-50 hover:shadow-row relative z-20 border-b"
3
3
  <%== item_selector_init @resource %>
4
4
  >
5
5
  <td class="w-10">
@@ -1,3 +1,3 @@
1
- <div class="flex items-center p-4 text-gray-500 text-sm uppercase font-semibold leading-none">
2
- <%= icon %> <%= label %>
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,11 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Avo::NavigationHeadingComponent < ViewComponent::Base
4
- attr_reader :label
5
- attr_reader :icon
6
-
7
- def initialize(label: nil, icon: nil)
4
+ def initialize(label: nil)
8
5
  @label = label
9
- @icon = icon
10
6
  end
11
7
  end
@@ -1,3 +1,3 @@
1
- <%= active_link_to @path, class: 'px-4 block mx-6 leading-none py-3 text-black rounded font-medium hover:bg-blue-50', active: @active do %>
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
- attr_reader :label
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-lg shadow mb-8 <%= @body_classes %>">
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', data: { component: 'resources-index' }, display_breadcrumbs: @reflection.blank?) do |c| %>
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', color: :primary, variant: :outlined do %>
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
- include Pundit::Authorization
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
- @model = @resource.fill_model(@model_to_fill, cast_nullable(model_params))
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