avo 2.21.1.pre.pr1476 → 2.21.2.pre.pr1486

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/app/components/avo/empty_state_component.html.erb +1 -1
  4. data/app/components/avo/empty_state_component.rb +12 -10
  5. data/app/components/avo/fields/belongs_to_field/edit_component.rb +1 -1
  6. data/app/components/avo/fields/boolean_field/edit_component.html.erb +1 -1
  7. data/app/components/avo/fields/boolean_group_field/edit_component.html.erb +1 -1
  8. data/app/components/avo/fields/code_field/edit_component.html.erb +2 -2
  9. data/app/components/avo/fields/country_field/edit_component.html.erb +1 -1
  10. data/app/components/avo/fields/date_field/edit_component.html.erb +2 -2
  11. data/app/components/avo/fields/date_time_field/edit_component.html.erb +2 -2
  12. data/app/components/avo/fields/edit_component.rb +4 -0
  13. data/app/components/avo/fields/external_image_field/edit_component.html.erb +1 -1
  14. data/app/components/avo/fields/file_field/edit_component.html.erb +1 -1
  15. data/app/components/avo/fields/files_field/edit_component.html.erb +1 -1
  16. data/app/components/avo/fields/has_one_field/show_component.html.erb +3 -3
  17. data/app/components/avo/fields/markdown_field/edit_component.html.erb +1 -1
  18. data/app/components/avo/fields/markdown_field/show_component.html.erb +1 -1
  19. data/app/components/avo/fields/number_field/edit_component.html.erb +1 -1
  20. data/app/components/avo/fields/password_field/edit_component.html.erb +1 -1
  21. data/app/components/avo/fields/progress_bar_field/edit_component.html.erb +1 -1
  22. data/app/components/avo/fields/select_field/edit_component.html.erb +1 -1
  23. data/app/components/avo/fields/show_component.rb +4 -0
  24. data/app/components/avo/fields/status_field/edit_component.html.erb +1 -1
  25. data/app/components/avo/fields/tags_field/edit_component.html.erb +2 -2
  26. data/app/components/avo/fields/text_field/edit_component.html.erb +1 -1
  27. data/app/components/avo/fields/textarea_field/edit_component.html.erb +1 -1
  28. data/app/components/avo/fields/time_field/edit_component.html.erb +2 -2
  29. data/app/components/avo/fields/trix_field/edit_component.html.erb +1 -1
  30. data/app/components/avo/index/resource_grid_component.html.erb +1 -1
  31. data/app/components/avo/paginator_component.html.erb +1 -5
  32. data/app/components/avo/paginator_component.rb +8 -0
  33. data/app/components/avo/resource_component.rb +15 -2
  34. data/app/components/avo/views/resource_index_component.html.erb +1 -1
  35. data/app/controllers/avo/base_controller.rb +8 -2
  36. data/app/javascript/js/controllers/fields/trix_field_controller.js +12 -1
  37. data/app/views/avo/base/_multiple_select_filter.html.erb +1 -1
  38. data/app/views/avo/partials/_resource_search.html.erb +1 -1
  39. data/config/i18n-tasks.yml +1 -1
  40. data/config/initializers/pagy.rb +16 -0
  41. data/lib/avo/fields/base_field.rb +2 -0
  42. data/lib/avo/fields/concerns/is_disabled.rb +19 -0
  43. data/lib/avo/services/authorization_service.rb +1 -2
  44. data/lib/avo/version.rb +1 -1
  45. data/lib/generators/avo/templates/field/components/edit_component.html.erb.tt +1 -1
  46. data/lib/generators/avo/templates/locales/avo.en.yml +3 -2
  47. data/lib/generators/avo/templates/locales/avo.fr.yml +3 -2
  48. data/lib/generators/avo/templates/locales/avo.nb.yml +3 -2
  49. data/lib/generators/avo/templates/locales/avo.nn.yml +3 -2
  50. data/lib/generators/avo/templates/locales/avo.pt-BR.yml +3 -2
  51. data/lib/generators/avo/templates/locales/avo.pt.yml +120 -0
  52. data/lib/generators/avo/templates/locales/avo.ro.yml +56 -55
  53. data/lib/generators/avo/templates/locales/avo.tr.yml +3 -2
  54. data/lib/generators/avo/templates/locales/pagy/nn.yml +1 -1
  55. data/lib/generators/avo/templates/locales/pagy/ro.yml +17 -0
  56. data/public/avo-assets/avo.base.js +65 -65
  57. data/public/avo-assets/avo.base.js.map +2 -2
  58. metadata +5 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f832c5802957b7d88c4271b886cfcb0a727ad98b1d200dc1f8e6d7a5a779067
4
- data.tar.gz: bb639aec120f3881847aa5ce53bd4bc399da0ae3fde37d01aad77ef13c017cbc
3
+ metadata.gz: f5460c088fcdb06944cf17960a56317ca92ce641858d0be2ae930dddbe527bd0
4
+ data.tar.gz: e2973cb82ccd2a68c857be57bd18a73c45656d340574c00bb135e67ee3c999b0
5
5
  SHA512:
6
- metadata.gz: 53180bdf4636c4dffd120fb8bb0f9ab0dacbbb9aad7e5ac3b906329144510b12b719591ebedb1dd2fb20d81a69d3a4932933d6500b4451e46947e9c3261885f0
7
- data.tar.gz: 16f6f89ae35d3b8d1c491af4d3b35eee7148d56ee2dcfcdd7ec3a0b0bd16919a0f0424d93c6863f3a1d22acbb1d2be6cf02007122804fed43a11bd6229de491f
6
+ metadata.gz: 47a6063f100b7ba2a49aac977b6d6e6961d75c3af62befac1d3e8de2154c84396021d37cae03cacc74a872f72172c9a506af332e3c2c6b025f2f9ff45f3743c3
7
+ data.tar.gz: a6112c2759fddc32613f17eba6cf6ae7c3049c0abfb89ce50c314b2cd7f89d5df6b1e743fcf44663fc1f4fcfdc92f85368464ec9a13bb5b29b12b03d5ade27d5
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- avo (2.21.1.pre.pr1476)
4
+ avo (2.21.2.pre.pr1486)
5
5
  actionview (>= 6.0)
6
6
  active_link_to
7
7
  activerecord (>= 6.0)
@@ -409,7 +409,7 @@ GEM
409
409
  tzinfo (2.0.5)
410
410
  concurrent-ruby (~> 1.0)
411
411
  unicode-display_width (2.2.0)
412
- view_component (2.77.0)
412
+ view_component (2.78.0)
413
413
  activesupport (>= 5.0.0, < 8.0)
414
414
  concurrent-ruby (~> 1.0)
415
415
  method_source (~> 1.0)
@@ -4,7 +4,7 @@
4
4
  <div class="relative flex-1 flex flex-col items-center justify-center space-y-12 py-24">
5
5
  <%= helpers.svg view_type_svg, class: 'h-[250px]' %>
6
6
  <div class="text-gray-500 text-center">
7
- <%= message %>
7
+ <%= text %>
8
8
  </div>
9
9
  </div>
10
10
  <% if @add_background %>
@@ -1,24 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Avo::EmptyStateComponent < ViewComponent::Base
4
- def initialize(message: nil, resource_name: nil, related_name: nil, view_type: :table, add_background: false)
4
+ attr_reader :message, :view_type, :add_background, :by_association
5
+
6
+ def initialize(message: nil, view_type: :table, add_background: false, by_association: false)
5
7
  @message = message
6
8
  @view_type = view_type
7
- @related_name = related_name
8
- @resource_name = resource_name
9
9
  @add_background = add_background
10
+ @by_association = by_association
10
11
  end
11
12
 
12
- def message
13
- return @message if @message.present?
14
-
15
- translation_tag = @related_name.present? ? 'avo.no_related_item_found' : 'avo.no_item_found'
16
- helpers.t translation_tag, item: @resource_name
13
+ def text
14
+ message || locale_message
17
15
  end
18
16
 
19
17
  def view_type_svg
20
- return "grid-empty-state" if @view_type.to_sym == :grid
18
+ "#{view_type}-empty-state"
19
+ end
20
+
21
+ private
21
22
 
22
- "table-empty-state"
23
+ def locale_message
24
+ helpers.t by_association ? 'avo.no_related_item_found' : 'avo.no_item_found'
23
25
  end
24
26
  end
@@ -8,7 +8,7 @@ class Avo::Fields::BelongsToField::EditComponent < Avo::Fields::EditComponent
8
8
  end
9
9
 
10
10
  def disabled
11
- return true if @field.is_readonly?
11
+ return true if @field.is_readonly? || @field.is_disabled?
12
12
 
13
13
  # When visiting the record through it's association we keep the field disabled by default
14
14
  # We make an exception when the user deliberately instructs Avo to allow detaching in this scenario
@@ -4,7 +4,7 @@
4
4
  checked: @field.value,
5
5
  class: "text-lg h-4 w-4 checked:bg-primary-400 focus:checked:!bg-primary-400 #{@field.get_html(:classes, view: view, element: :input)}",
6
6
  data: @field.get_html(:data, view: view, element: :input),
7
- disabled: @field.is_readonly?,
7
+ disabled: disabled?,
8
8
  style: @field.get_html(:style, view: view, element: :input)
9
9
  %>
10
10
  </div>
@@ -20,7 +20,7 @@
20
20
  <%= check_box_tag "#{model_param_key}[#{@field.id}][]", id, checked, {
21
21
  class: "w-4 h-4 #{@field.get_html(:classes, view: view, element: :input)}",
22
22
  data: @field.get_html(:data, view: view, element: :input),
23
- disabled: @field.is_readonly?,
23
+ disabled: disabled?,
24
24
  id: "#{model_param_key}_#{@field.id}_#{id}",
25
25
  style: @field.get_html(:style, view: view, element: :input)
26
26
  } %> <%= label %>
@@ -8,12 +8,12 @@
8
8
  language: @field.language,
9
9
  theme: @field.theme,
10
10
  'tab-size': @field.tab_size,
11
- 'read-only': @field.is_readonly?,
11
+ 'read-only': disabled?,
12
12
  'indent-with-tabs': @field.indent_with_tabs,
13
13
  'line-wrapping': @field.line_wrapping,
14
14
  **@field.get_html(:data, view: view, element: :input),
15
15
  },
16
- disabled: @field.is_readonly?,
16
+ disabled: disabled?,
17
17
  placeholder: @field.placeholder,
18
18
  style: @field.get_html(:style, view: view, element: :input)
19
19
  %>
@@ -8,7 +8,7 @@
8
8
  },
9
9
  class: classes("w-full"),
10
10
  data: @field.get_html(:data, view: view, element: :input),
11
- disabled: @field.is_readonly?,
11
+ disabled: disabled?,
12
12
  style: @field.get_html(:style, view: view, element: :input),
13
13
  placeholder: @field.include_blank.present? ? nil : @field.placeholder
14
14
  %>
@@ -18,7 +18,7 @@
18
18
  placeholder: @field.placeholder,
19
19
  **@field.get_html(:data, view: view, element: :input)
20
20
  },
21
- disabled: @field.is_readonly?,
21
+ disabled: disabled?,
22
22
  placeholder: @field.placeholder,
23
23
  style: @field.get_html(:style, view: view, element: :input)
24
24
  %>
@@ -30,7 +30,7 @@
30
30
  placeholder: @field.placeholder,
31
31
  **@field.get_html(:data, view: view, element: :input)
32
32
  },
33
- disabled: @field.is_readonly?,
33
+ disabled: disabled?,
34
34
  placeholder: @field.placeholder,
35
35
  style: @field.get_html(:style, view: view, element: :input)
36
36
  %>
@@ -20,7 +20,7 @@
20
20
  placeholder: @field.placeholder,
21
21
  **@field.get_html(:data, view: view, element: :input)
22
22
  },
23
- disabled: @field.is_readonly?,
23
+ disabled: disabled?,
24
24
  placeholder: @field.placeholder,
25
25
  style: @field.get_html(:style, view: view, element: :input)
26
26
  %>
@@ -32,7 +32,7 @@
32
32
  placeholder: @field.placeholder,
33
33
  **@field.get_html(:data, view: view, element: :input)
34
34
  },
35
- disabled: @field.is_readonly?,
35
+ disabled: disabled?,
36
36
  placeholder: @field.placeholder,
37
37
  style: @field.get_html(:style, view: view, element: :input)
38
38
  %>
@@ -42,4 +42,8 @@ class Avo::Fields::EditComponent < ViewComponent::Base
42
42
  view: view
43
43
  }
44
44
  end
45
+
46
+ def disabled?
47
+ field.is_readonly? || field.is_disabled?
48
+ end
45
49
  end
@@ -2,7 +2,7 @@
2
2
  <%= @form.text_field @field.id,
3
3
  class: classes("w-full"),
4
4
  data: @field.get_html(:data, view: view, element: :input),
5
- disabled: @field.is_readonly?,
5
+ disabled: disabled?,
6
6
  placeholder: @field.placeholder,
7
7
  style: @field.get_html(:style, view: view, element: :input)
8
8
  %>
@@ -10,7 +10,7 @@
10
10
  accept: @field.accept,
11
11
  data: @field.get_html(:data, view: view, element: :input),
12
12
  direct_upload: @field.direct_upload,
13
- disabled: @field.is_readonly?,
13
+ disabled: disabled?,
14
14
  style: @field.get_html(:style, view: view, element: :input),
15
15
  class: "w-full"
16
16
  %>
@@ -7,7 +7,7 @@
7
7
  accept: @field.accept,
8
8
  data: @field.get_html(:data, view: view, element: :input),
9
9
  direct_upload: @field.direct_upload,
10
- disabled: @field.is_readonly?,
10
+ disabled: disabled?,
11
11
  multiple: true,
12
12
  style: @field.get_html(:style, view: view, element: :input),
13
13
  class: "w-full"
@@ -5,7 +5,7 @@
5
5
  <% else %>
6
6
  <%= render Avo::PanelComponent.new(name: @field.name) do |c| %>
7
7
  <% c.tools do %>
8
- <% if !@field.is_readonly? && can_attach? %>
8
+ <% if !@field.is_readonly? && !@field.is_disabled? && can_attach? %>
9
9
  <%= a_link attach_path,
10
10
  icon: 'heroicons/outline/link',
11
11
  color: :primary,
@@ -13,7 +13,7 @@
13
13
  <%= t('avo.attach_item', item: @field.name.downcase) %>
14
14
  <% end %>
15
15
  <% end %>
16
- <% if !@field.is_readonly? && can_see_the_create_button? %>
16
+ <% if !@field.is_readonly? && !@field.is_disabled? && can_see_the_create_button? %>
17
17
  <%= a_link create_path,
18
18
  icon: 'heroicons/outline/plus',
19
19
  'data-target': 'create',
@@ -27,7 +27,7 @@
27
27
 
28
28
  <% c.body do %>
29
29
  <div class="py-8 flex justify-center items-center">
30
- <%= empty_state resource_name: @field.id, related_name: params[:related_name] %>
30
+ <%= empty_state by_association: params[:related_name].present? %>
31
31
  </div>
32
32
  <% end %>
33
33
  <% end %>
@@ -7,7 +7,7 @@
7
7
  'simple-mde-target': 'element',
8
8
  'component-options': @field.options.to_json,
9
9
  },
10
- disabled: @field.is_readonly?,
10
+ disabled: disabled?,
11
11
  placeholder: @field.placeholder,
12
12
  style: @field.get_html(:style, view: view, element: :input)
13
13
  %>
@@ -3,7 +3,7 @@
3
3
  <%= text_area_tag @field.id, @field.value,
4
4
  class: helpers.input_classes('w-full js-has-simple-mde-editor'),
5
5
  placeholder: @field.placeholder,
6
- disabled: @field.is_readonly?,
6
+ disabled: disabled?,
7
7
  'data-simple-mde-target': 'element',
8
8
  'data-component-options': @field.options.to_json,
9
9
  'data-view': :show %>
@@ -2,7 +2,7 @@
2
2
  <%= @form.number_field @field.id,
3
3
  class: classes("w-full"),
4
4
  data: @field.get_html(:data, view: view, element: :input),
5
- disabled: @field.is_readonly?,
5
+ disabled: disabled?,
6
6
  max: @field.max,
7
7
  min: @field.min,
8
8
  placeholder: @field.placeholder,
@@ -2,7 +2,7 @@
2
2
  <%= @form.password_field @field.id,
3
3
  class: classes("w-full"),
4
4
  data: @field.get_html(:data, view: view, element: :input),
5
- disabled: @field.is_readonly?,
5
+ disabled: disabled?,
6
6
  placeholder: @field.placeholder,
7
7
  style: @field.get_html(:style, view: view, element: :input)
8
8
  %>
@@ -7,7 +7,7 @@
7
7
  <%= @form.range_field @field.id,
8
8
  class: "w-full #{@field.get_html(:classes, view: view, element: :input)}",
9
9
  data: @field.get_html(:data, view: view, element: :input),
10
- disabled: @field.is_readonly?,
10
+ disabled: disabled?,
11
11
  max: @field.max,
12
12
  min: 0,
13
13
  placeholder: @field.placeholder,
@@ -7,7 +7,7 @@
7
7
  },
8
8
  class: classes("w-full"),
9
9
  data: @field.get_html(:data, view: view, element: :input),
10
- disabled: @field.is_readonly?,
10
+ disabled: disabled?,
11
11
  style: @field.get_html(:style, view: view, element: :input),
12
12
  value: @field.model.present? ? @field.model[@field.id] : @field.value,
13
13
  placeholder: @field.include_blank.present? ? nil : @field.placeholder
@@ -52,4 +52,8 @@ class Avo::Fields::ShowComponent < ViewComponent::Base
52
52
  view: view
53
53
  }
54
54
  end
55
+
56
+ def disabled?
57
+ field.is_readonly? || field.is_disabled?
58
+ end
55
59
  end
@@ -2,7 +2,7 @@
2
2
  <%= @form.text_field @field.id,
3
3
  class: classes("w-full"),
4
4
  data: @field.get_html(:data, view: view, element: :input),
5
- disabled: @field.is_readonly?,
5
+ disabled: disabled?,
6
6
  placeholder: @field.placeholder,
7
7
  style: @field.get_html(:style, view: view, element: :input),
8
8
  value: @resource.model.present? ? @resource.model[@field.id] : @field.value
@@ -6,7 +6,7 @@
6
6
  data: {
7
7
  'tags-field-target': 'fakeInput',
8
8
  },
9
- disabled: @field.is_readonly?,
9
+ disabled: disabled?,
10
10
  placeholder: @field.placeholder,
11
11
  style: @field.get_html(:style, view: view, element: :input),
12
12
  value: ''
@@ -22,7 +22,7 @@
22
22
  'delimiters': @field.delimiters,
23
23
  'close-on-select': @field.close_on_select ? 1 : 0,
24
24
  },
25
- disabled: @field.is_readonly?,
25
+ disabled: disabled?,
26
26
  placeholder: @field.placeholder,
27
27
  style: @field.get_html(:style, view: view, element: :input),
28
28
  value: @field.field_value.to_json
@@ -2,7 +2,7 @@
2
2
  <%= form.text_field @field.id,
3
3
  class: classes("w-full"),
4
4
  data: @field.get_html(:data, view: view, element: :input),
5
- disabled: @field.is_readonly?,
5
+ disabled: disabled?,
6
6
  placeholder: @field.placeholder,
7
7
  style: @field.get_html(:style, view: view, element: :input),
8
8
  # value: @field.value,
@@ -2,7 +2,7 @@
2
2
  <%= @form.text_area @field.id,
3
3
  class: classes("w-full"),
4
4
  data: @field.get_html(:data, view: view, element: :input),
5
- disabled: @field.is_readonly?,
5
+ disabled: disabled?,
6
6
  placeholder: @field.placeholder,
7
7
  rows: @field.rows,
8
8
  style: @field.get_html(:style, view: view, element: :input)
@@ -20,7 +20,7 @@
20
20
  placeholder: @field.placeholder,
21
21
  **@field.get_html(:data, view: view, element: :input)
22
22
  },
23
- disabled: @field.is_readonly?,
23
+ disabled: disabled?,
24
24
  placeholder: @field.placeholder,
25
25
  style: @field.get_html(:style, view: view, element: :input)
26
26
  %>
@@ -32,7 +32,7 @@
32
32
  placeholder: @field.placeholder,
33
33
  **@field.get_html(:data, view: view, element: :input)
34
34
  },
35
- disabled: @field.is_readonly?,
35
+ disabled: disabled?,
36
36
  placeholder: @field.placeholder,
37
37
  style: @field.get_html(:style, view: view, element: :input)
38
38
  %>
@@ -25,7 +25,7 @@
25
25
  <%= @form.text_area @field.id,
26
26
  class: classes("w-full hidden"),
27
27
  data: @field.get_html(:data, view: view, element: :input),
28
- disabled: @field.is_readonly?,
28
+ disabled: disabled?,
29
29
  id: trix_id,
30
30
  placeholder: @field.placeholder,
31
31
  style: @field.get_html(:style, view: view, element: :input)
@@ -9,6 +9,6 @@
9
9
  </div>
10
10
  <% else %>
11
11
  <div class="bg-white rounded shadow-panel">
12
- <%= helpers.empty_state resource_name: @resource.name.downcase.pluralize, related_name: params[:related_name], view_type: :grid %>
12
+ <%= helpers.empty_state by_association: params[:related_name].present?, view_type: :grid %>
13
13
  </div>
14
14
  <% end %>
@@ -25,11 +25,7 @@
25
25
  %> <%= t('avo.per_page').downcase %>
26
26
  </div>
27
27
  <% per_page_options.each do |option| %>
28
- <% if parent_model.present? %>
29
- <%= link_to "Change to #{option} items per page", helpers.related_resources_path(parent_model, parent_model, per_page: option, keep_query_params: true, page: 1), class: 'hidden', 'data-per-page-option': option, 'data-turbo-frame': turbo_frame %>
30
- <% else %>
31
- <%= link_to "Change to #{option} items per page", helpers.resources_path(resource: resource, per_page: option, keep_query_params: true, page: 1), class: 'hidden', 'data-per-page-option': option, 'data-turbo-frame': turbo_frame %>
32
- <% end %>
28
+ <%= link_to "Change to #{option} items per page", change_items_per_page_url(option), class: 'hidden', 'data-per-page-option': option, 'data-turbo-frame': turbo_frame %>
33
29
  <% end %>
34
30
  </div>
35
31
  </div>
@@ -16,4 +16,12 @@ class Avo::PaginatorComponent < ViewComponent::Base
16
16
  @parent_model = parent_model
17
17
  @discreet_pagination = discreet_pagination
18
18
  end
19
+
20
+ def change_items_per_page_url(option)
21
+ if parent_model.present?
22
+ helpers.related_resources_path(parent_model, parent_model, per_page: option, keep_query_params: true, page: 1)
23
+ else
24
+ helpers.resources_path(resource: resource, per_page: option, keep_query_params: true, page: 1)
25
+ end
26
+ end
19
27
  end
@@ -68,12 +68,25 @@ class Avo::ResourceComponent < Avo::BaseComponent
68
68
 
69
69
  if association_name.present?
70
70
  method_name = "#{policy_method}_#{association_name}?".to_sym
71
+
71
72
  # Use the policy methods from the parent (Post)
72
73
  service = reflection_resource.authorization
73
74
 
74
75
  if service.has_method?(method_name, raise_exception: false)
75
- # Override the record with the child record (Comment not Post)
76
- policy_result = service.authorize_action(method_name, record: resource.model, raise_exception: false)
76
+ # Some policy methods should get the parent record in order to have the necessarry information to do the authorization
77
+ # Example: Post->has_many->Comments
78
+ # When you want to authorize the creation/attaching of a Comment, you don't have the Comment instance.
79
+ # But you do have the Post instance and you can get that in your policy to authorize against.
80
+ parent_policy_methods = [:view, :create, :attach, :act_on]
81
+
82
+ record = if parent_policy_methods.include?(policy_method)
83
+ # Use the parent record (Post)
84
+ reflection_resource.model
85
+ else
86
+ # Override the record with the child record (Comment)
87
+ resource.model
88
+ end
89
+ policy_result = service.authorize_action(method_name, record: record, raise_exception: false)
77
90
  end
78
91
  end
79
92
  end
@@ -52,7 +52,7 @@
52
52
  <%= render(Avo::Index::ResourceTableComponent.new(resources: @resources, resource: @resource, reflection: @reflection, parent_model: @parent_model, parent_resource: @parent_resource, pagy: @pagy, query: @query)) %>
53
53
  </div>
54
54
  <% else %>
55
- <%= helpers.empty_state resource_name: @resource.name.downcase.pluralize, related_name: params[:related_name], view_type: view_type, add_background: true %>
55
+ <%= helpers.empty_state by_association: params[:related_name].present?, view_type: view_type, add_background: true %>
56
56
  <% end %>
57
57
  <% end %>
58
58
  <% end %>
@@ -14,6 +14,7 @@ module Avo
14
14
  before_action :fill_model, only: [:create, :update]
15
15
  # Don't run base authorizations for associations
16
16
  before_action :authorize_base_action, if: -> { controller_name != "associations" }
17
+ before_action :set_pagy_locale, only: :index
17
18
 
18
19
  def index
19
20
  @page_title = @resource.plural_name.humanize
@@ -223,11 +224,11 @@ module Avo
223
224
  # In case there's an error somewhere else than the model
224
225
  # Example: When you save a license that should create a user for it and creating that user throws and error.
225
226
  # Example: When you Try to delete a record and has a foreign key constraint.
226
- @errors = Array.wrap(exception.message)
227
+ exception_message = exception.message
227
228
  end
228
229
 
229
230
  # Add the errors from the model
230
- @errors = Array.wrap([@errors, @model.errors.full_messages]).compact
231
+ @errors = @model.errors.full_messages.reject { |error| exception_message.include? error }.unshift exception_message
231
232
 
232
233
  succeeded
233
234
  end
@@ -510,5 +511,10 @@ module Avo
510
511
  def is_associated_record?
511
512
  params[:via_relation_class].present? && params[:via_resource_id].present?
512
513
  end
514
+
515
+ # Set pagy locale from params or from avo configuration, if both nil locale = "en"
516
+ def set_pagy_locale
517
+ @pagy_locale = locale.to_s || Avo.configuration.locale || "en"
518
+ end
513
519
  end
514
520
  end
@@ -1,5 +1,7 @@
1
1
  /* eslint-disable no-alert */
2
2
  import 'trix'
3
+ import URI from 'urijs'
4
+
3
5
  import { Controller } from '@hotwired/stimulus'
4
6
  import { castBoolean } from '../../helpers/cast_boolean'
5
7
 
@@ -35,7 +37,16 @@ export default class extends Controller {
35
37
  }
36
38
 
37
39
  get uploadUrl() {
38
- return `${window.location.origin}${window.Avo.configuration.root_path}/avo_api/resources/${this.resourceName}/${this.resourceId}/attachments`
40
+ // Parse the current URL
41
+ const url = new URI(window.location.origin)
42
+ // Parse the root path
43
+ const rootPath = new URI(window.Avo.configuration.root_path)
44
+ // Build the trix field path
45
+ url.path(`${rootPath.path()}/avo_api/resources/${this.resourceName}/${this.resourceId}/attachments`)
46
+ // Add the params back
47
+ url.query(rootPath.query())
48
+
49
+ return url.toString()
39
50
  }
40
51
 
41
52
  connect() {
@@ -13,7 +13,7 @@
13
13
  %>
14
14
  <div class="flex justify-end">
15
15
  <%= a_button class: 'mt-4', color: :primary, size: :xs, data: { action: "multiple-select-filter#changeFilter" } do %>
16
- Filter by <%=filter.name %>
16
+ <%= "#{t("avo.filter_by")} #{filter.name}" %>
17
17
  <% end %>
18
18
  </div>
19
19
  <%= link_to 'url_redirect', request.url, data: { 'multiple-select-filter-target': 'urlRedirect', 'turbo-frame': params[:turbo_frame] }, style: 'hidden', class: 'hidden' %>
@@ -2,7 +2,7 @@
2
2
  <div class="w-full"
3
3
  data-search-target="autocomplete"
4
4
  data-search-resource="<%= resource %>"
5
- data-translation-keys='{"no_item_found": "<%= I18n.translate 'avo.no_item_found' %>"}'
5
+ data-translation-keys='{"no_item_found": "<%= I18n.translate 'avo.no_item_found' %>", "placeholder": "<%= I18n.translate 'avo.search.placeholder' %>", "cancel_button": "<%= I18n.translate 'avo.search.cancel_button' %>"}'
6
6
  <% if via_reflection.present? %>
7
7
  data-via-association="<%= via_reflection[:association] %>"
8
8
  data-via-association-id="<%= via_reflection[:association_id] %>"
@@ -3,7 +3,7 @@
3
3
  # The "main" locale.
4
4
  base_locale: en
5
5
  ## All available locales are inferred from the data by default. Alternatively, specify them explicitly:
6
- locales: [en, fr, nb, nn, pt-BR, ro, tr]
6
+ locales: [en, fr, nb, nn, pt-BR, pt, ro, tr]
7
7
  ## Reporting locale, default: en. Available: en, ru.
8
8
  # internal_locale: en
9
9
 
@@ -1 +1,17 @@
1
1
  require "pagy/extras/trim"
2
+
3
+ # For locales without native pagy i18n support
4
+ def pagy_locale_path(file_name)
5
+ Avo::Engine.root.join("lib", "generators", "avo", "templates", "locales", "pagy", file_name)
6
+ end
7
+
8
+ Pagy::I18n.load(
9
+ { locale: 'en' },
10
+ { locale: 'fr' },
11
+ { locale: 'nb' },
12
+ { locale: 'pt-BR' },
13
+ { locale: 'pt' },
14
+ { locale: 'tr' },
15
+ { locale: 'nn', filepath: pagy_locale_path("nn.yml") },
16
+ { locale: 'ro', filepath: pagy_locale_path("ro.yml") },
17
+ )
@@ -13,6 +13,7 @@ module Avo
13
13
  include Avo::Concerns::HasHTMLAttributes
14
14
  include Avo::Fields::Concerns::IsRequired
15
15
  include Avo::Fields::Concerns::IsReadonly
16
+ include Avo::Fields::Concerns::IsDisabled
16
17
  include Avo::Fields::Concerns::HasDefault
17
18
 
18
19
  delegate :view_context, to: ::Avo::App
@@ -64,6 +65,7 @@ module Avo
64
65
  @block = block
65
66
  @required = args.dig(:required) # Value if :required present on args, nil otherwise
66
67
  @readonly = args[:readonly] || false
68
+ @disabled = args[:disabled] || false
67
69
  @sortable = args[:sortable] || false
68
70
  @nullable = args[:nullable] || false
69
71
  @null_values = args[:null_values] || [nil, ""]
@@ -0,0 +1,19 @@
1
+ module Avo
2
+ module Fields
3
+ module Concerns
4
+ module IsDisabled
5
+ extend ActiveSupport::Concern
6
+
7
+ attr_reader :disabled
8
+
9
+ def is_disabled?
10
+ if disabled.respond_to? :call
11
+ Avo::Hosts::ResourceViewRecordHost.new(block: disabled, record: model, view: view, resource: resource).handle
12
+ else
13
+ disabled
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -29,7 +29,6 @@ module Avo
29
29
 
30
30
  def authorize(user, record, action, policy_class: nil, **args)
31
31
  return true if skip_authorization
32
- return true if user.nil?
33
32
 
34
33
  client.authorize user, record, action, policy_class: policy_class
35
34
 
@@ -64,7 +63,7 @@ module Avo
64
63
  end
65
64
 
66
65
  def apply_policy(user, model, policy_class: nil)
67
- return model if skip_authorization || user.nil?
66
+ return model if skip_authorization
68
67
 
69
68
  client.apply_policy(user, model, policy_class: policy_class)
70
69
  rescue NoPolicyError => error
data/lib/avo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "2.21.1.pre.pr1476" unless const_defined?(:VERSION)
2
+ VERSION = "2.21.2.pre.pr1486" unless const_defined?(:VERSION)
3
3
  end