avo 2.19.0 → 2.21.0

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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -2
  3. data/Gemfile.lock +6 -6
  4. data/app/components/avo/card_component.html.erb +15 -15
  5. data/app/components/avo/card_component.rb +7 -5
  6. data/app/components/avo/empty_state_component.html.erb +1 -1
  7. data/app/components/avo/empty_state_component.rb +12 -10
  8. data/app/components/avo/fields/belongs_to_field/edit_component.rb +1 -1
  9. data/app/components/avo/fields/boolean_field/edit_component.html.erb +1 -1
  10. data/app/components/avo/fields/boolean_group_field/edit_component.html.erb +1 -1
  11. data/app/components/avo/fields/code_field/edit_component.html.erb +2 -2
  12. data/app/components/avo/fields/country_field/edit_component.html.erb +1 -1
  13. data/app/components/avo/fields/date_field/edit_component.html.erb +2 -2
  14. data/app/components/avo/fields/date_time_field/edit_component.html.erb +2 -2
  15. data/app/components/avo/fields/edit_component.rb +4 -0
  16. data/app/components/avo/fields/external_image_field/edit_component.html.erb +1 -1
  17. data/app/components/avo/fields/file_field/edit_component.html.erb +1 -1
  18. data/app/components/avo/fields/files_field/edit_component.html.erb +1 -1
  19. data/app/components/avo/fields/has_one_field/show_component.html.erb +3 -3
  20. data/app/components/avo/fields/markdown_field/edit_component.html.erb +1 -1
  21. data/app/components/avo/fields/markdown_field/show_component.html.erb +1 -1
  22. data/app/components/avo/fields/number_field/edit_component.html.erb +1 -1
  23. data/app/components/avo/fields/password_field/edit_component.html.erb +1 -1
  24. data/app/components/avo/fields/progress_bar_field/edit_component.html.erb +1 -1
  25. data/app/components/avo/fields/select_field/edit_component.html.erb +2 -2
  26. data/app/components/avo/fields/show_component.rb +4 -0
  27. data/app/components/avo/fields/status_field/edit_component.html.erb +1 -1
  28. data/app/components/avo/fields/tags_field/edit_component.html.erb +2 -2
  29. data/app/components/avo/fields/text_field/edit_component.html.erb +1 -1
  30. data/app/components/avo/fields/textarea_field/edit_component.html.erb +1 -1
  31. data/app/components/avo/fields/time_field/edit_component.html.erb +2 -2
  32. data/app/components/avo/fields/trix_field/edit_component.html.erb +3 -2
  33. data/app/components/avo/fields/trix_field/edit_component.rb +5 -1
  34. data/app/components/avo/index/resource_grid_component.html.erb +1 -1
  35. data/app/components/avo/index/resource_table_component.rb +3 -3
  36. data/app/components/avo/paginator_component.html.erb +1 -5
  37. data/app/components/avo/paginator_component.rb +8 -0
  38. data/app/components/avo/panel_component.html.erb +1 -1
  39. data/app/components/avo/resource_component.rb +17 -2
  40. data/app/components/avo/sidebar/group_component.html.erb +18 -12
  41. data/app/components/avo/sidebar/heading_component.html.erb +17 -10
  42. data/app/components/avo/views/resource_index_component.html.erb +1 -1
  43. data/app/controllers/avo/actions_controller.rb +27 -5
  44. data/app/controllers/avo/application_controller.rb +3 -2
  45. data/app/controllers/avo/associations_controller.rb +2 -1
  46. data/app/controllers/avo/attachments_controller.rb +4 -0
  47. data/app/controllers/avo/base_controller.rb +27 -16
  48. data/app/controllers/avo/dashboards/cards_controller.rb +1 -1
  49. data/app/controllers/avo/dashboards_controller.rb +1 -0
  50. data/app/controllers/avo/search_controller.rb +11 -5
  51. data/app/javascript/js/controllers/fields/trix_field_controller.js +6 -3
  52. data/app/javascript/js/controllers/item_select_all_controller.js +7 -4
  53. data/app/views/avo/actions/keep_modal_open.turbo_stream.erb +5 -0
  54. data/app/views/avo/actions/show.html.erb +3 -2
  55. data/app/views/avo/base/_multiple_select_filter.html.erb +1 -1
  56. data/app/views/avo/partials/_resource_search.html.erb +1 -1
  57. data/app/views/layouts/avo/application.html.erb +1 -1
  58. data/avo.gemspec +0 -1
  59. data/config/i18n-tasks.yml +1 -1
  60. data/config/initializers/pagy.rb +16 -0
  61. data/lib/avo/app.rb +4 -1
  62. data/lib/avo/base_action.rb +25 -4
  63. data/lib/avo/base_card.rb +8 -3
  64. data/lib/avo/base_resource.rb +21 -6
  65. data/lib/avo/concerns/breadcrumbs.rb +96 -0
  66. data/lib/avo/concerns/handles_field_args.rb +8 -1
  67. data/lib/avo/concerns/has_html_attributes.rb +14 -16
  68. data/lib/avo/dashboards/base_dashboard.rb +7 -1
  69. data/lib/avo/fields/base_field.rb +2 -1
  70. data/lib/avo/fields/concerns/is_disabled.rb +19 -0
  71. data/lib/avo/fields/select_field.rb +39 -34
  72. data/lib/avo/filters/base_filter.rb +9 -3
  73. data/lib/avo/hosts/resource_record_host.rb +7 -0
  74. data/lib/avo/hosts/visibility_host.rb +2 -1
  75. data/lib/avo/services/authorization_service.rb +2 -2
  76. data/lib/avo/version.rb +1 -1
  77. data/lib/generators/avo/templates/field/components/edit_component.html.erb.tt +1 -1
  78. data/lib/generators/avo/templates/locales/avo.en.yml +3 -2
  79. data/lib/generators/avo/templates/locales/avo.fr.yml +3 -2
  80. data/lib/generators/avo/templates/locales/avo.nb.yml +3 -2
  81. data/lib/generators/avo/templates/locales/avo.nn.yml +3 -2
  82. data/lib/generators/avo/templates/locales/avo.pt-BR.yml +3 -2
  83. data/lib/generators/avo/templates/locales/avo.pt.yml +120 -0
  84. data/lib/generators/avo/templates/locales/avo.ro.yml +56 -55
  85. data/lib/generators/avo/templates/locales/avo.tr.yml +3 -2
  86. data/lib/generators/avo/templates/locales/pagy/nn.yml +15 -0
  87. data/lib/generators/avo/templates/locales/pagy/ro.yml +17 -0
  88. data/public/avo-assets/avo.base.css +4 -4
  89. data/public/avo-assets/avo.base.js +2 -2
  90. data/public/avo-assets/avo.base.js.map +2 -2
  91. metadata +9 -16
data/lib/avo/base_card.rb CHANGED
@@ -15,10 +15,15 @@ module Avo
15
15
 
16
16
  attr_accessor :dashboard
17
17
  attr_accessor :options
18
+ attr_accessor :arguments
18
19
  attr_accessor :index
19
20
  attr_accessor :params
20
21
 
21
22
  delegate :context, to: ::Avo::App
23
+ delegate :current_user, to: ::Avo::App
24
+ delegate :view_context, to: ::Avo::App
25
+ delegate :params, to: ::Avo::App
26
+ delegate :request, to: ::Avo::App
22
27
 
23
28
  class << self
24
29
  def query(&block)
@@ -26,9 +31,10 @@ module Avo
26
31
  end
27
32
  end
28
33
 
29
- def initialize(dashboard:, options: {}, index: 0, cols: nil, rows: nil, label: nil, description: nil, refresh_every: nil)
34
+ def initialize(dashboard:, options: {}, arguments: {}, index: 0, cols: nil, rows: nil, label: nil, description: nil, refresh_every: nil)
30
35
  @dashboard = dashboard
31
36
  @options = options
37
+ @arguments = arguments
32
38
  @index = index
33
39
  @cols = cols
34
40
  @rows = rows
@@ -104,9 +110,8 @@ module Avo
104
110
  self
105
111
  end
106
112
 
107
- def hydrate(dashboard: nil, params: nil)
113
+ def hydrate(dashboard: nil)
108
114
  @dashboard = dashboard if dashboard.present?
109
- @params = params if params.present?
110
115
 
111
116
  self
112
117
  end
@@ -62,16 +62,18 @@ module Avo
62
62
  self.grid_loader = grid_collector
63
63
  end
64
64
 
65
- def action(action_class)
65
+ def action(action_class, arguments: {})
66
66
  self.actions_loader ||= Avo::Loaders::Loader.new
67
67
 
68
- self.actions_loader.use action_class
68
+ action = { class: action_class, arguments: arguments }
69
+ self.actions_loader.use action
69
70
  end
70
71
 
71
- def filter(filter_class)
72
+ def filter(filter_class, arguments: {})
72
73
  self.filters_loader ||= Avo::Loaders::Loader.new
73
74
 
74
- self.filters_loader.use filter_class
75
+ filter = { class: filter_class , arguments: arguments }
76
+ self.filters_loader.use filter
75
77
  end
76
78
 
77
79
  # This is the search_query scope
@@ -115,9 +117,10 @@ module Avo
115
117
  end
116
118
 
117
119
  def valid_attachment_name(record, association_name)
118
- get_record_associations(record).keys.each do |name|
119
- return association_name if name == "#{association_name}_attachment" || name == "#{association_name}_attachments"
120
+ association_exists = get_record_associations(record).keys.any? do |name|
121
+ name == "#{association_name}_attachment" || name == "#{association_name}_attachments"
120
122
  end
123
+ return association_name if association_exists
121
124
  end
122
125
 
123
126
  def get_available_models
@@ -170,12 +173,24 @@ module Avo
170
173
  self.class.filters_loader.bag
171
174
  end
172
175
 
176
+ def get_filter_arguments(filter_class)
177
+ filter = get_filters.find { |filter| filter[:class] == filter_class.constantize }
178
+
179
+ filter[:arguments]
180
+ end
181
+
173
182
  def get_actions
174
183
  return [] if self.class.actions_loader.blank?
175
184
 
176
185
  self.class.actions_loader.bag
177
186
  end
178
187
 
188
+ def get_action_arguments(action_class)
189
+ action = get_actions.find { |action| action[:class].to_s == action_class.to_s }
190
+
191
+ action[:arguments]
192
+ end
193
+
179
194
  def default_panel_name
180
195
  return @params[:related_name].capitalize if @params.present? && @params[:related_name].present?
181
196
 
@@ -0,0 +1,96 @@
1
+ module Avo
2
+ module Concerns
3
+ # This is a custom implementation of breadcrumbs largely based on breadcrumbs_on_rails gem
4
+ # created by Simone Carletti (@weppos) and released on MIT license.
5
+ #
6
+ # https://github.com/weppos/breadcrumbs_on_rails
7
+ #
8
+ # The reason to use custom implementation is to
9
+ # * Avoid naming conflicts with other gems adding helpers like `breadcrumbs`
10
+ # * Reduce number of dependencies
11
+ module Breadcrumbs
12
+ extend ActiveSupport::Concern
13
+
14
+ included do |base|
15
+ helper HelperMethods
16
+ extend ClassMethods
17
+ helper_method :add_breadcrumb, :avo_breadcrumbs
18
+ end
19
+
20
+ Crumb = Struct.new(:name, :path) unless defined?(Crumb)
21
+
22
+ class Builder
23
+ DEFAULT_SEPARATOR = " &raquo; ".freeze unless defined?(DEFAULT_SEPARATOR)
24
+
25
+ attr_reader :context, :options
26
+
27
+ def initialize(context, options)
28
+ @context = context
29
+ @options = options
30
+ end
31
+
32
+ def render
33
+ separator = options.fetch(:separator, DEFAULT_SEPARATOR)
34
+ breadcrumbs.map(&method(:render_element)).join(separator)
35
+ end
36
+
37
+ private
38
+
39
+ def breadcrumbs
40
+ context.avo_breadcrumbs
41
+ end
42
+
43
+ def render_element(element)
44
+ content = element.path.nil? ? compute_name(element) : context.link_to_unless_current(compute_name(element), compute_path(element))
45
+ options[:tag] ? context.content_tag(options[:tag], content) : ERB::Util.h(content)
46
+ end
47
+
48
+ def compute_name(element)
49
+ case name = element.name
50
+ when Symbol
51
+ context.send(name)
52
+ when Proc
53
+ name.call(context)
54
+ else
55
+ name.to_s
56
+ end
57
+ end
58
+
59
+ def compute_path(element)
60
+ case path = element.path
61
+ when Symbol
62
+ context.send(path)
63
+ when Proc
64
+ path.call(context)
65
+ else
66
+ context.url_for(path)
67
+ end
68
+ end
69
+ end
70
+
71
+ module ClassMethods
72
+ def add_breadcrumb(name, path = nil)
73
+ before_action(filter_options) do |controller|
74
+ controller.send(:add_breadcrumb, name, path)
75
+ end
76
+ end
77
+ end
78
+
79
+ def add_breadcrumb(name, path = nil)
80
+ avo_breadcrumbs << Crumb.new(name, path)
81
+ end
82
+
83
+ def avo_breadcrumbs
84
+ @avo_breadcrumbs ||= []
85
+ end
86
+
87
+ module HelperMethods
88
+ def render_avo_breadcrumbs(options = {}, &block)
89
+ builder = Builder.new(self, options)
90
+ content = builder.render.html_safe
91
+ block_given? ? capture(content, &block) : content
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -12,7 +12,14 @@ module Avo
12
12
  value = default
13
13
 
14
14
  if type == :boolean
15
- value = args[name.to_sym] == true
15
+ case args[name.to_sym]
16
+ when nil
17
+ value = default
18
+ when false
19
+ value = false
20
+ when true
21
+ value = true
22
+ end
16
23
  else
17
24
  value = args[name.to_sym] unless args.dig(name.to_sym).nil?
18
25
  end
@@ -16,12 +16,14 @@ module Avo
16
16
  default_attribute_value name
17
17
  end
18
18
 
19
- attributes = if html_builder.is_a? Hash
20
- get_html_from_hash name, element: element, view: view
21
- elsif html_builder.is_a? Avo::HTML::Builder
22
- get_html_from_block name, element: element, view: view
23
- elsif html_builder.nil?
24
- # Handle empty html_builder by returning an empty state
19
+ parsed = parse_html
20
+
21
+ attributes = if parsed.is_a? Hash
22
+ get_html_from_hash name, element: element, hash: parsed, view: view
23
+ elsif parsed.is_a? Avo::HTML::Builder
24
+ get_html_from_block name, element: element, html_builder: parsed, view: view
25
+ elsif parsed.nil?
26
+ # Handle empty parsed by returning an empty state
25
27
  default_attribute_value name
26
28
  end
27
29
 
@@ -30,19 +32,15 @@ module Avo
30
32
 
31
33
  private
32
34
 
33
- def html_builder
34
- return @parsed_html if @parsed_html.present?
35
-
35
+ # Returns Hash, HTML::Builder, or nil.
36
+ def parse_html
36
37
  return if @html.nil?
37
38
 
38
- # Memoize the value
39
- @parsed_html = if @html.is_a? Hash
39
+ if @html.is_a? Hash
40
40
  @html
41
41
  elsif @html.respond_to? :call
42
42
  Avo::HTML::Builder.parse_block(record: model, resource: resource, &@html)
43
43
  end
44
-
45
- @parsed_html
46
44
  end
47
45
 
48
46
  def default_attribute_value(name)
@@ -64,7 +62,7 @@ module Avo
64
62
  end
65
63
  end
66
64
 
67
- def get_html_from_block(name = nil, element:, view:)
65
+ def get_html_from_block(name = nil, element:, html_builder:, view:)
68
66
  values = []
69
67
 
70
68
  # get view ancestor
@@ -83,9 +81,9 @@ module Avo
83
81
  merge_values_as(as: values_type, values: values)
84
82
  end
85
83
 
86
- def get_html_from_hash(name = nil, element:, view:)
84
+ def get_html_from_hash(name = nil, element:, hash:, view:)
87
85
  # @todo: what if this is not a Hash but a string?
88
- html_builder.dig(view, element, name) || {}
86
+ hash.dig(view, element, name) || {}
89
87
  end
90
88
 
91
89
  # Merge the values from all possible locations.
@@ -12,7 +12,12 @@ module Avo
12
12
  class_attribute :index, default: 0
13
13
 
14
14
  class << self
15
- def card(klass, label: nil, description: nil, cols: nil, rows: nil, refresh_every: nil, options: {})
15
+ def options_deprecation_message
16
+ Rails.logger.warn "DEPRECATION WARNING: Card options parameter is deprecated in favor of arguments parameter and will be removed from Avo version 3.0.0"
17
+ end
18
+
19
+ def card(klass, label: nil, description: nil, cols: nil, rows: nil, refresh_every: nil, options: {}, arguments: {})
20
+ options_deprecation_message if options.present?
16
21
  self.items_holder ||= []
17
22
 
18
23
  self.items_holder << klass.new(dashboard: self,
@@ -22,6 +27,7 @@ module Avo
22
27
  rows: rows,
23
28
  refresh_every: refresh_every,
24
29
  options: options,
30
+ arguments: arguments,
25
31
  index: index
26
32
  )
27
33
  self.index += 1
@@ -10,10 +10,10 @@ module Avo
10
10
  include ActionView::Helpers::UrlHelper
11
11
  include Avo::Fields::FieldExtensions::VisibleInDifferentViews
12
12
 
13
- include Avo::Concerns::HandlesFieldArgs
14
13
  include Avo::Concerns::HasHTMLAttributes
15
14
  include Avo::Fields::Concerns::IsRequired
16
15
  include Avo::Fields::Concerns::IsReadonly
16
+ include Avo::Fields::Concerns::IsDisabled
17
17
  include Avo::Fields::Concerns::HasDefault
18
18
 
19
19
  delegate :view_context, to: ::Avo::App
@@ -65,6 +65,7 @@ module Avo
65
65
  @block = block
66
66
  @required = args.dig(:required) # Value if :required present on args, nil otherwise
67
67
  @readonly = args[:readonly] || false
68
+ @disabled = args[:disabled] || false
68
69
  @sortable = args[:sortable] || false
69
70
  @nullable = args[:nullable] || false
70
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
@@ -3,7 +3,7 @@ module Avo
3
3
  class SelectField < BaseField
4
4
  include Avo::Fields::FieldExtensions::HasIncludeBlank
5
5
 
6
- attr_reader :options
6
+ attr_reader :options_from_args
7
7
  attr_reader :enum
8
8
  attr_reader :display_value
9
9
 
@@ -12,51 +12,56 @@ module Avo
12
12
 
13
13
  super(id, **args, &block)
14
14
 
15
- @options = args[:options] || args[:enum]
16
- @options = ActiveSupport::HashWithIndifferentAccess.new @options if @options.is_a? Hash
15
+ @options_from_args = if args[:options].is_a? Hash
16
+ ActiveSupport::HashWithIndifferentAccess.new args[:options]
17
+ else
18
+ args[:options]
19
+ end
17
20
  @enum = args[:enum].present? ? args[:enum] : nil
18
21
  @display_value = args[:display_value].present? ? args[:display_value] : false
19
22
  end
20
23
 
21
24
  def options_for_select
22
- if options.respond_to? :call
23
- computed_options = options.call model: model, resource: resource, view: view, field: self
24
- if display_value
25
- computed_options.map { |label, value| [value, value] }.to_h
26
- else
27
- computed_options
28
- end
29
- elsif enum.present?
30
- if display_value
31
- options.invert
32
- else
33
- # We need to use the label attribute as the option value because Rails casts it like that
34
- options.map { |label, value| [label, label] }.to_h
35
- end
36
- elsif display_value
37
- options.map { |label, value| [value, value] }.to_h
38
- else
39
- options
25
+ # If options are array don't need any pre-process
26
+ return options if options.is_a?(Array)
27
+
28
+ # If options are enum we invert the enum if display value, else (see next comment)
29
+ if enum.present?
30
+ return enum.invert if display_value
31
+
32
+ # We need to use the label attribute as the option value because Rails casts it like that
33
+ return enum.map { |label, value| [label, label] }.to_h
40
34
  end
35
+
36
+ # When code arrive here it means options are Hash
37
+ # If display_value is true we only need to return the values of the Hash
38
+ display_value ? options.values : options
41
39
  end
42
40
 
43
41
  def label
44
- if options.respond_to? :call
45
- computed_options = options.call model: model, resource: resource, view: view, field: self
42
+ # If options are array don't need any pre-process
43
+ return value if options.is_a?(Array)
44
+
45
+ # If options are enum and display_value is true we return the Value of that key-value pair, else return key of that key-value pair
46
+ # WARNING: value here is the DB stored value and not the value of a key-value pair.
47
+ if enum.present?
48
+ return enum[value] if display_value
49
+ return value
50
+ end
51
+
52
+ # When code arrive here it means options are Hash
53
+ # If display_value is true we only need to return the value stored in DB
54
+ display_value ? value : options.invert[value]
55
+ end
46
56
 
47
- return value if display_value
57
+ private
48
58
 
49
- computed_options.invert.stringify_keys[value]
50
- elsif enum.present?
51
- if display_value
52
- options[value]
53
- else
54
- value
55
- end
56
- elsif display_value
57
- value
59
+ # Cache options as options given on block or as options received from arguments
60
+ def options
61
+ if options_from_args.respond_to? :call
62
+ options_from_args.call model: model, resource: resource, view: view, field: self
58
63
  else
59
- options.invert.stringify_keys[value]
64
+ options_from_args
60
65
  end
61
66
  end
62
67
  end
@@ -10,6 +10,8 @@ module Avo
10
10
  class_attribute :template, default: "avo/base/select_filter"
11
11
  class_attribute :visible
12
12
 
13
+ attr_reader :arguments
14
+
13
15
  delegate :params, to: Avo::App
14
16
 
15
17
  class << self
@@ -24,6 +26,10 @@ module Avo
24
26
  end
25
27
  end
26
28
 
29
+ def initialize(arguments: {})
30
+ @arguments = arguments
31
+ end
32
+
27
33
  def apply_query(request, query, value)
28
34
  value.stringify_keys! if value.is_a? Hash
29
35
 
@@ -54,16 +60,16 @@ module Avo
54
60
  self.class.decode_filters params[PARAM_KEY]
55
61
  end
56
62
 
57
- def visible_in_view(resource: nil, parent_model: nil, parent_resource: nil)
63
+ def visible_in_view(resource: nil, parent_resource: nil)
58
64
  return true if visible.blank?
59
65
 
60
66
  # Run the visible block if available
61
67
  Avo::Hosts::VisibilityHost.new(
62
68
  block: visible,
63
69
  params: params,
64
- parent_model: parent_model,
65
70
  parent_resource: parent_resource,
66
- resource: resource
71
+ resource: resource,
72
+ arguments: arguments
67
73
  ).handle
68
74
 
69
75
  end
@@ -0,0 +1,7 @@
1
+ module Avo
2
+ module Hosts
3
+ class ResourceRecordHost < RecordHost
4
+ option :resource
5
+ end
6
+ end
7
+ end
@@ -1,9 +1,10 @@
1
1
  module Avo
2
2
  module Hosts
3
3
  class VisibilityHost < BaseHost
4
- option :parent_model
5
4
  option :parent_resource
6
5
  option :resource
6
+ option :arguments
7
+
7
8
  # View is optional because in filter context the view is always :index
8
9
  option :view, optional: true
9
10
  end
@@ -119,7 +119,7 @@ module Avo
119
119
  end
120
120
 
121
121
  def authorize_action(action, **args)
122
- self.class.authorize_action(user, record, action, policy_class: policy_class, **args)
122
+ self.class.authorize_action(user, args[:record] || record, action, policy_class: policy_class, **args)
123
123
  end
124
124
 
125
125
  def apply_policy(model)
@@ -131,7 +131,7 @@ module Avo
131
131
  end
132
132
 
133
133
  def has_method?(method, **args)
134
- defined_methods(record, **args).include? method.to_sym
134
+ defined_methods(args[:record] || record, **args).include? method.to_sym
135
135
  end
136
136
  end
137
137
  end
data/lib/avo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "2.19.0" unless const_defined?(:VERSION)
2
+ VERSION = "2.21.0" unless const_defined?(:VERSION)
3
3
  end
@@ -2,5 +2,5 @@
2
2
  <%%= @form.text_field @field.id,
3
3
  class: classes("w-full"),
4
4
  placeholder: @field.placeholder,
5
- disabled: @field.is_readonly? %>
5
+ disabled: disabled? %>
6
6
  <%% end %>
@@ -46,6 +46,7 @@ en:
46
46
  one: peep
47
47
  other: peeps
48
48
  zero: peeps
49
+ filter_by: Filter by
49
50
  filters: Filters
50
51
  go_back: Go back
51
52
  grid_view: Grid view
@@ -62,9 +63,9 @@ en:
62
63
  new: new
63
64
  next_page: Next page
64
65
  no_cards_present: No cards present
65
- no_item_found: No %{item} found
66
+ no_item_found: No record found
66
67
  no_options_available: No options available
67
- no_related_item_found: No related %{item} found
68
+ no_related_item_found: No related record found
68
69
  not_authorized: You are not authorized to perform this action.
69
70
  number_of_items:
70
71
  one: one %{item}
@@ -46,6 +46,7 @@ fr:
46
46
  one: personne
47
47
  other: personnes
48
48
  zero: personne
49
+ filter_by: Filtrer par
49
50
  filters: Filtres
50
51
  go_back: Retourner en arrière
51
52
  grid_view: Vue grille
@@ -62,9 +63,9 @@ fr:
62
63
  new: Nouveau
63
64
  next_page: Page suivante
64
65
  no_cards_present: Aucune carte présente
65
- no_item_found: Aucun %{item} trouvé
66
+ no_item_found: Enregistrement non trouvé
66
67
  no_options_available: Aucune option disponible
67
- no_related_item_found: Aucun %{item} apparenté n'a été trouvé
68
+ no_related_item_found: Enregistrement connexe introuvable
68
69
  not_authorized: Vous n'êtes pas autorisé à effectuer cette action.
69
70
  number_of_items:
70
71
  one: un %{item}
@@ -46,6 +46,7 @@ nb:
46
46
  one: person
47
47
  other: personer
48
48
  zero: personer
49
+ filter_by: Filtrer etter
49
50
  filters: Filter
50
51
  go_back: Gå tilbake
51
52
  grid_view: Grid visning
@@ -62,9 +63,9 @@ nb:
62
63
  new: ny
63
64
  next_page: Neste side
64
65
  no_cards_present: Ingen kort til stede
65
- no_item_found: Ingen %{item} funnet
66
+ no_item_found: Ingen funnet
66
67
  no_options_available: Ingen tilgjengelige alternativer
67
- no_related_item_found: Ingen relaterte %{item} funnet
68
+ no_related_item_found: Ingen relaterte funnet
68
69
  not_authorized: Du er ikke autorisert til å gjøre denne handlingen.
69
70
  number_of_items:
70
71
  one: en %{item}
@@ -46,6 +46,7 @@ nn:
46
46
  one: person
47
47
  other: personar
48
48
  zero: personar
49
+ filter_by: Filtrer etter
49
50
  filters: Filter
50
51
  go_back: Gå tilbake
51
52
  grid_view: Gridvisning
@@ -62,9 +63,9 @@ nn:
62
63
  new: ny
63
64
  next_page: Neste side
64
65
  no_cards_present: Ingen kort til stades
65
- no_item_found: Fann ingen %{item}
66
+ no_item_found: Fann ingen
66
67
  no_options_available: Ingen tilgjengelege alternativ
67
- no_related_item_found: Fann ingen relaterte %{item}
68
+ no_related_item_found: Fann ingen relaterte
68
69
  not_authorized: Du er ikkje autorisert til å gjere denne handlinga.
69
70
  number_of_items:
70
71
  one: en %{item}
@@ -46,6 +46,7 @@ pt-BR:
46
46
  one: pessoa
47
47
  other: pessoas
48
48
  zero: ninguém
49
+ filter_by: Filtrar por
49
50
  filters: Filtros
50
51
  go_back: Voltar
51
52
  grid_view: Visualização em grade
@@ -62,9 +63,9 @@ pt-BR:
62
63
  new: novo
63
64
  next_page: Próxima página
64
65
  no_cards_present: Nenhum cartão presente
65
- no_item_found: Nenhum %{item} encontrado
66
+ no_item_found: Nenhum registro encontrado
66
67
  no_options_available: Nenhuma opção disponível
67
- no_related_item_found: Nenhum %{item} relacionado encontrado
68
+ no_related_item_found: Nenhum registro relacionado encontrado
68
69
  not_authorized: Você não está autorizado à executar essa ação.
69
70
  number_of_items:
70
71
  one: um %{item}