avo 3.27.0 → 3.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +11 -11
  3. data/app/assets/stylesheets/avo.base.css +1 -0
  4. data/app/assets/stylesheets/css/fields/stars.css +13 -0
  5. data/app/components/avo/field_wrapper_component.rb +1 -5
  6. data/app/components/avo/fields/boolean_field/edit_component.html.erb +2 -1
  7. data/app/components/avo/fields/boolean_field/index_component.html.erb +1 -1
  8. data/app/components/avo/fields/boolean_field/show_component.html.erb +1 -1
  9. data/app/components/avo/fields/common/boolean_check_component.html.erb +2 -1
  10. data/app/components/avo/fields/common/boolean_check_component.rb +26 -6
  11. data/app/components/avo/fields/common/stars_component.html.erb +8 -0
  12. data/app/components/avo/fields/common/stars_component.rb +4 -0
  13. data/app/components/avo/fields/stars_field/edit_component.html.erb +23 -0
  14. data/app/components/avo/fields/stars_field/edit_component.rb +2 -0
  15. data/app/components/avo/fields/stars_field/index_component.html.erb +3 -0
  16. data/app/components/avo/fields/stars_field/index_component.rb +2 -0
  17. data/app/components/avo/fields/stars_field/show_component.html.erb +3 -0
  18. data/app/components/avo/fields/stars_field/show_component.rb +2 -0
  19. data/app/components/avo/index/field_wrapper_component.rb +1 -5
  20. data/app/components/avo/resource_component.rb +1 -17
  21. data/app/components/avo/views/resource_index_component.rb +1 -3
  22. data/app/javascript/js/controllers/fields/key_value_controller.js +11 -1
  23. data/app/javascript/js/controllers/fields/stars_field_controller.js +55 -0
  24. data/app/javascript/js/controllers/search_controller.js +1 -1
  25. data/app/javascript/js/controllers.js +2 -0
  26. data/lib/avo/fields/boolean_field.rb +4 -0
  27. data/lib/avo/fields/key_value_field.rb +28 -1
  28. data/lib/avo/fields/stars_field.rb +13 -0
  29. data/lib/avo/media_library/configuration.rb +4 -5
  30. data/lib/avo/version.rb +1 -1
  31. data/lib/generators/avo/templates/cards/partial_card_partial.tt +3 -1
  32. data/lib/generators/avo/templates/locales/avo.ar.yml +2 -0
  33. data/lib/generators/avo/templates/locales/avo.de.yml +2 -0
  34. data/lib/generators/avo/templates/locales/avo.en.yml +2 -0
  35. data/lib/generators/avo/templates/locales/avo.es.yml +2 -0
  36. data/lib/generators/avo/templates/locales/avo.fr.yml +2 -0
  37. data/lib/generators/avo/templates/locales/avo.it.yml +2 -0
  38. data/lib/generators/avo/templates/locales/avo.ja.yml +2 -0
  39. data/lib/generators/avo/templates/locales/avo.nb.yml +2 -0
  40. data/lib/generators/avo/templates/locales/avo.nl.yml +2 -0
  41. data/lib/generators/avo/templates/locales/avo.nn.yml +2 -0
  42. data/lib/generators/avo/templates/locales/avo.pl.yml +2 -0
  43. data/lib/generators/avo/templates/locales/avo.pt-BR.yml +2 -0
  44. data/lib/generators/avo/templates/locales/avo.pt.yml +2 -0
  45. data/lib/generators/avo/templates/locales/avo.ro.yml +2 -0
  46. data/lib/generators/avo/templates/locales/avo.ru.yml +2 -0
  47. data/lib/generators/avo/templates/locales/avo.tr.yml +2 -0
  48. data/lib/generators/avo/templates/locales/avo.uk.yml +2 -0
  49. data/lib/generators/avo/templates/locales/avo.zh-TW.yml +2 -0
  50. data/lib/generators/avo/templates/locales/avo.zh.yml +2 -0
  51. data/public/avo-assets/avo.base.css +68 -39
  52. data/public/avo-assets/avo.base.js +181 -180
  53. data/public/avo-assets/avo.base.js.map +4 -4
  54. metadata +12 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 867fef6728ec2a3fddeea7b24f28821dfbd5f395b7df861e386201b748561d87
4
- data.tar.gz: 84b350b46c5cbef8823e6ae9a5e343938e3fae663bba8e407d836a3ff6721937
3
+ metadata.gz: 9ff86625a0129b2665d309e29ee6b0f5ad90feb33c0ff59d51bebce74b639687
4
+ data.tar.gz: f634f37c244df609bfae9e339b480a1bbe34cc400e76618320e07f42983feccf
5
5
  SHA512:
6
- metadata.gz: d71ba91f2bb012a65a44388c5ab1861df8a65339c0d9a125f1418a393e9d4815d1f7a00312a2c46812d2b46bd07ae34a64dbea0c37fbe7fb0ed3f1082d974085
7
- data.tar.gz: 56144157674c868c09d5c32fa1d04d754de3d4cbf7f8330e5c046d5d27ab5f3dbe3a93d02f38e80650c17e5755e9ad5cee0e798aaff823db6cc77c30ccc0699f
6
+ metadata.gz: 6d4cdab25e6cf1bc200643fcbe5d7319cc51db125226f0dd2c949b5d5bee5db01da0fa2e28763617a70abe73919417dc298fa6354289b08f8bb1761d566b1f03
7
+ data.tar.gz: a74f2e0c891b284eb17d19eae8f2b2f111895b20e56adefecb7bc5f3b6d2da00b1516eb42d998d05113568a7a0d286e8d48e9f29169d716273a735084f8b0cad
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- avo (3.27.0)
4
+ avo (3.29.0)
5
5
  actionview (>= 6.1)
6
6
  active_link_to
7
7
  activerecord (>= 6.1)
@@ -131,8 +131,8 @@ GEM
131
131
  money-rails (~> 1.12)
132
132
  avo-record_link_field (0.0.2)
133
133
  aws-eventstream (1.4.0)
134
- aws-partitions (1.1188.0)
135
- aws-sdk-core (3.239.2)
134
+ aws-partitions (1.1196.0)
135
+ aws-sdk-core (3.240.0)
136
136
  aws-eventstream (~> 1, >= 1.3.0)
137
137
  aws-partitions (~> 1, >= 1.992.0)
138
138
  aws-sigv4 (~> 1.9)
@@ -143,7 +143,7 @@ GEM
143
143
  aws-sdk-kms (1.118.0)
144
144
  aws-sdk-core (~> 3, >= 3.239.1)
145
145
  aws-sigv4 (~> 1.5)
146
- aws-sdk-s3 (1.205.0)
146
+ aws-sdk-s3 (1.208.0)
147
147
  aws-sdk-core (~> 3, >= 3.234.0)
148
148
  aws-sdk-kms (~> 1)
149
149
  aws-sigv4 (~> 1.5)
@@ -231,9 +231,9 @@ GEM
231
231
  warden (~> 1.2.3)
232
232
  diff-lcs (1.6.2)
233
233
  docile (1.4.1)
234
- dotenv (3.1.8)
235
- dotenv-rails (3.1.8)
236
- dotenv (= 3.1.8)
234
+ dotenv (3.2.0)
235
+ dotenv-rails (3.2.0)
236
+ dotenv (= 3.2.0)
237
237
  railties (>= 6.1)
238
238
  drb (2.2.3)
239
239
  dry-configurable (1.3.0)
@@ -282,7 +282,7 @@ GEM
282
282
  factory_bot_rails (6.5.1)
283
283
  factory_bot (~> 6.5)
284
284
  railties (>= 6.1.0)
285
- faker (3.5.2)
285
+ faker (3.5.3)
286
286
  i18n (>= 1.8.11, < 2)
287
287
  faraday (2.14.0)
288
288
  faraday-net_http (>= 2.0, < 3.5)
@@ -369,7 +369,7 @@ GEM
369
369
  jmespath (1.6.2)
370
370
  jsbundling-rails (1.3.1)
371
371
  railties (>= 6.0.0)
372
- json (2.16.0)
372
+ json (2.17.1)
373
373
  kramdown (2.5.1)
374
374
  rexml (>= 3.3.9)
375
375
  kramdown-parser-gfm (1.1.0)
@@ -519,7 +519,7 @@ GEM
519
519
  ffi (~> 1.0)
520
520
  rbs (3.9.5)
521
521
  logger
522
- rdoc (6.16.0)
522
+ rdoc (6.16.1)
523
523
  erb
524
524
  psych (>= 4.0.0)
525
525
  tsort
@@ -666,7 +666,7 @@ GEM
666
666
  standard-performance (1.8.0)
667
667
  lint_roller (~> 1.1)
668
668
  rubocop-performance (~> 1.25.0)
669
- stringio (3.1.8)
669
+ stringio (3.1.9)
670
670
  syntax_tree (6.3.0)
671
671
  prettier_print (>= 1.2.0)
672
672
  terminal-table (4.0.0)
@@ -26,6 +26,7 @@
26
26
  @import './css/fields/trix.css';
27
27
  @import './css/fields/tags.css';
28
28
  @import './css/fields/tiptap.css';
29
+ @import './css/fields/stars.css';
29
30
 
30
31
  @import 'tailwindcss/components';
31
32
 
@@ -0,0 +1,13 @@
1
+ [data-component="avo/fields/common/stars_component"] {
2
+ .star {
3
+ @apply h-5 w-5 text-gray-300 transition-colors;
4
+ }
5
+
6
+ .star.filled {
7
+ @apply text-yellow-400;
8
+ }
9
+
10
+ .rating-group {
11
+ @apply flex items-center gap-1;
12
+ }
13
+ }
@@ -114,10 +114,6 @@ class Avo::FieldWrapperComponent < Avo::BaseComponent
114
114
  end
115
115
 
116
116
  def render_dash?
117
- if @field.type == "boolean"
118
- @field.value.nil?
119
- else
120
- @field.value.blank? && @dash_if_blank
121
- end
117
+ @field.value.blank? && @dash_if_blank
122
118
  end
123
119
  end
@@ -1,6 +1,7 @@
1
1
  <%= field_wrapper(**field_wrapper_args) do %>
2
2
  <div class="h-8 flex items-center">
3
- <%= @form.label @field.id,
3
+ <%= content_tag :label,
4
+ for: "#{@form.object_name}_#{@field.id}",
4
5
  class: class_names(
5
6
  "relative flex items-center",
6
7
  "opacity-50": disabled?,
@@ -1,3 +1,3 @@
1
- <%= index_field_wrapper(**field_wrapper_args, flush: true) do %>
1
+ <%= index_field_wrapper(**field_wrapper_args, flush: true, dash_if_blank: @field.dash_if_blank?) do %>
2
2
  <%= render Avo::Fields::Common::BooleanCheckComponent.new checked: @field.value %>
3
3
  <% end %>
@@ -1,3 +1,3 @@
1
- <%= field_wrapper(**field_wrapper_args) do %>
1
+ <%= field_wrapper(**field_wrapper_args, dash_if_blank: @field.dash_if_blank?) do %>
2
2
  <%= render Avo::Fields::Common::BooleanCheckComponent.new checked: @field.value %>
3
3
  <% end %>
@@ -1 +1,2 @@
1
- <%= helpers.svg "#{@icon}.svg", class: classes %>
1
+ <%= content_tag :span, @checked.nil? ? "" : t("avo.#{@checked}"), class: 'sr-only' %>
2
+ <%= helpers.svg "#{@icon}.svg", class: classes, data: {checked_state: state} %>
@@ -1,18 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Avo::Fields::Common::BooleanCheckComponent < Avo::BaseComponent
4
- prop :checked, default: false
4
+ STATE_CONFIG = {
5
+ true => {
6
+ name: "checked",
7
+ icon: "heroicons/outline/check-circle",
8
+ color: "text-green-600"
9
+ },
10
+ false => {
11
+ name: "unchecked",
12
+ icon: "heroicons/outline/x-circle",
13
+ color: "text-red-600"
14
+ },
15
+ nil => {
16
+ name: "indeterminate",
17
+ icon: "heroicons/outline/minus-circle",
18
+ color: "text-gray-400"
19
+ }
20
+ }.freeze
21
+
22
+ prop :checked, default: nil
5
23
  prop :size, default: :md
6
- prop :icon do |value|
7
- @checked ? "heroicons/outline/check-circle" : "heroicons/outline/x-circle"
24
+ prop :icon do
25
+ STATE_CONFIG[@checked][:icon]
26
+ end
27
+
28
+ def state
29
+ STATE_CONFIG[@checked][:name]
8
30
  end
9
31
 
10
32
  def classes
11
- helpers.class_names({
33
+ helpers.class_names(STATE_CONFIG[@checked][:color], {
12
34
  "h-5": @size == :sm,
13
35
  "h-6": @size == :md,
14
- "text-green-600": @checked,
15
- "text-red-600": !@checked,
16
36
  })
17
37
  end
18
38
  end
@@ -0,0 +1,8 @@
1
+ <div class="rating-group" data-component="<%= component_name %>">
2
+ <% (1..@max).each do |rating_value| %>
3
+ <%= helpers.svg(
4
+ 'heroicons/solid/star',
5
+ class: class_names("star inline-block mr-0.5", filled: rating_value <= (@value || 0))
6
+ ) %>
7
+ <% end %>
8
+ </div>
@@ -0,0 +1,4 @@
1
+ class Avo::Fields::Common::StarsComponent < Avo::BaseComponent
2
+ prop :value
3
+ prop :max, default: 5
4
+ end
@@ -0,0 +1,23 @@
1
+ <%= field_wrapper(**field_wrapper_args) do %>
2
+ <div data-controller="stars-field">
3
+ <%= @form.hidden_field @field.id,
4
+ value: @field.value,
5
+ data: { stars_field_target: "valueInput" } %>
6
+
7
+ <div class="rating-group flex items-center gap-1 mb-3"
8
+ data-component="avo/fields/common/stars_component"
9
+ data-stars-field-target="starsContainer"
10
+ data-max="<%= @field.max %>"
11
+ data-current-value="<%= @field.value || 0 %>">
12
+ <% (1..@field.max).each do |rating_value| %>
13
+ <%= helpers.svg('heroicons/solid/star',
14
+ class: class_names("star inline-block mr-0.5", filled: rating_value <= (@value || 0)),
15
+ data: {
16
+ star_value: rating_value,
17
+ stars_field_target: "star",
18
+ action: "click->stars-field#setStar mouseenter->stars-field#hoverStar mouseleave->stars-field#unhoverStar"
19
+ }) %>
20
+ <% end %>
21
+ </div>
22
+ </div>
23
+ <% end %>
@@ -0,0 +1,2 @@
1
+ class Avo::Fields::StarsField::EditComponent < Avo::Fields::EditComponent
2
+ end
@@ -0,0 +1,3 @@
1
+ <%= index_field_wrapper(**field_wrapper_args, flush: true) do %>
2
+ <%= render Avo::Fields::Common::StarsComponent.new(value: @field.value, max: @field.max) %>
3
+ <% end %>
@@ -0,0 +1,2 @@
1
+ class Avo::Fields::StarsField::IndexComponent < Avo::Fields::IndexComponent
2
+ end
@@ -0,0 +1,3 @@
1
+ <%= field_wrapper(**field_wrapper_args) do %>
2
+ <%= render Avo::Fields::Common::StarsComponent.new value: @field.value, max: @field.max %>
3
+ <% end %>
@@ -0,0 +1,2 @@
1
+ class Avo::Fields::StarsField::ShowComponent < Avo::Fields::ShowComponent
2
+ end
@@ -45,10 +45,6 @@ class Avo::Index::FieldWrapperComponent < Avo::BaseComponent
45
45
  end
46
46
 
47
47
  def render_dash?
48
- if @field.type == "boolean"
49
- @field.value.nil?
50
- else
51
- @field.value.blank? && @dash_if_blank
52
- end
48
+ @field.value.blank? && @dash_if_blank
53
49
  end
54
50
  end
@@ -59,7 +59,7 @@ class Avo::ResourceComponent < Avo::BaseComponent
59
59
  def can_see_the_actions_button?
60
60
  return authorize_association_for(:act_on) if @reflection.present?
61
61
 
62
- @resource.authorization.authorize_action(:act_on, raise_exception: false) && !has_reflection_and_is_read_only
62
+ @resource.authorization.authorize_action(:act_on, raise_exception: false)
63
63
  end
64
64
 
65
65
  def destroy_path
@@ -93,22 +93,6 @@ class Avo::ResourceComponent < Avo::BaseComponent
93
93
  end
94
94
  end
95
95
 
96
- def has_reflection_and_is_read_only
97
- if @reflection.present? && @reflection.active_record.name && @reflection.name
98
- resource = Avo.resource_manager.get_resource_by_model_class(@reflection.active_record.name).new(params: helpers.params, view: view, user: helpers._current_user)
99
- fields = resource.get_field_definitions
100
- filtered_fields = fields.filter { |f| f.id == @reflection.name }
101
- else
102
- return false
103
- end
104
-
105
- if filtered_fields.present?
106
- filtered_fields.find { |f| f.id == @reflection.name }.is_disabled?
107
- else
108
- false
109
- end
110
- end
111
-
112
96
  def render_control(control)
113
97
  send :"render_#{control.type}", control
114
98
  end
@@ -37,12 +37,10 @@ class Avo::Views::ResourceIndexComponent < Avo::ResourceComponent
37
37
 
38
38
  return authorize_association_for(:create) if @reflection.present?
39
39
 
40
- @resource.authorization.authorize_action(:new, raise_exception: false) && !has_reflection_and_is_read_only
40
+ @resource.authorization.authorize_action(:new, raise_exception: false)
41
41
  end
42
42
 
43
43
  def can_attach?
44
- return false if has_reflection_and_is_read_only
45
-
46
44
  reflection_class = if @reflection.is_a?(::ActiveRecord::Reflection::ThroughReflection)
47
45
  @reflection.through_reflection.class
48
46
  else
@@ -23,7 +23,17 @@ export default class extends Controller {
23
23
  this.setOptions()
24
24
 
25
25
  try {
26
- const objectValue = JSON.parse(this.inputTarget.value)
26
+ const objectValue = JSON.parse(this.inputTarget.value, (key, value) => {
27
+ // convert primitives to string
28
+ if (
29
+ typeof value === "number" ||
30
+ typeof value === "boolean"
31
+ ) {
32
+ return String(value);
33
+ }
34
+ return value; // objects stay objects
35
+ });
36
+
27
37
  Object.keys(objectValue).forEach((key) => this.fieldValue.push([key, objectValue[key]]))
28
38
  } catch (error) {
29
39
  this.fieldValue = []
@@ -0,0 +1,55 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ // Connects to data-controller="stars-field"
4
+ export default class extends Controller {
5
+ static targets = ["valueInput", "starsContainer", "star"]
6
+
7
+ connect() {
8
+ this.maxValue = parseInt(this.starsContainerTarget.dataset.max)
9
+ this.currentValue = parseInt(this.starsContainerTarget.dataset.currentValue)
10
+ this.updateStarsDisplay(this.currentValue)
11
+ }
12
+
13
+ setStar(event) {
14
+ const starValue = parseInt(event.currentTarget.dataset.starValue)
15
+
16
+ // If clicking the same star that's already selected, set to 0 (no rating)
17
+ if (starValue === this.currentValue) {
18
+ this.currentValue = 0
19
+ } else {
20
+ this.currentValue = starValue
21
+ }
22
+
23
+ // Update the hidden input value
24
+ this.valueInputTarget.value = this.currentValue
25
+
26
+ // Update the visual display
27
+ this.updateStarsDisplay(this.currentValue)
28
+
29
+ // Trigger change event for form validation
30
+ this.valueInputTarget.dispatchEvent(new Event('change'))
31
+ }
32
+
33
+ hoverStar(event) {
34
+ const hoverValue = parseInt(event.currentTarget.dataset.starValue)
35
+ this.updateStarsDisplay(hoverValue, true)
36
+ }
37
+
38
+ unhoverStar(event) {
39
+ // Return to the actual selected value when not hovering
40
+ this.updateStarsDisplay(this.currentValue)
41
+ }
42
+
43
+ updateStarsDisplay(value, isHover = false) {
44
+ this.starTargets.forEach((star, index) => {
45
+ const starValue = index + 1
46
+
47
+ // Add appropriate class based on value
48
+ if (starValue <= value) {
49
+ star.classList.add('filled')
50
+ } else {
51
+ star.classList.remove('filled')
52
+ }
53
+ })
54
+ }
55
+ }
@@ -242,7 +242,7 @@ export default class extends Controller {
242
242
 
243
243
  return url.segment([window.Avo.configuration.root_path, ...this.searchSegments()])
244
244
  .search(this.searchParams(encodeURIComponent(query)))
245
- .readable().toString()
245
+ .toString()
246
246
  }
247
247
 
248
248
  searchSegments() {
@@ -52,6 +52,7 @@ import TiptapFieldController from './controllers/fields/tiptap_field_controller'
52
52
  import ToggleController from './controllers/toggle_controller'
53
53
  import TrixBodyController from './controllers/trix_body_controller'
54
54
  import TrixFieldController from './controllers/fields/trix_field_controller'
55
+ import StarsFieldController from './controllers/fields/stars_field_controller'
55
56
 
56
57
  application.register('action', ActionController)
57
58
  application.register('actions-overflow', ActionsOverflowController)
@@ -107,5 +108,6 @@ application.register('reload-belongs-to-field', ReloadBelongsToFieldController)
107
108
  application.register('tags-field', TagsFieldController)
108
109
  application.register('tiptap-field', TiptapFieldController)
109
110
  application.register('trix-field', TrixFieldController)
111
+ application.register('stars-field', StarsFieldController)
110
112
 
111
113
  // Custom controllers
@@ -28,6 +28,10 @@ module Avo
28
28
  end
29
29
 
30
30
  def as_toggle? = !!@args[:as_toggle]
31
+
32
+ def nil_as_indeterminate? = !!@args[:nil_as_indeterminate]
33
+
34
+ def dash_if_blank? = value.nil? && !nil_as_indeterminate?
31
35
  end
32
36
  end
33
37
  end
@@ -8,7 +8,7 @@ module Avo
8
8
  attr_reader :key_label, :value_label, :action_text
9
9
 
10
10
  def initialize(id, **args, &block)
11
- super(id, **args, &block)
11
+ super
12
12
 
13
13
  hide_on :index
14
14
 
@@ -69,6 +69,33 @@ module Avo
69
69
  new_value = {}
70
70
  end
71
71
 
72
+ # Try to cast the new values to the same class as the original value
73
+ old_key_value_hash = record.send(key)
74
+
75
+ if old_key_value_hash.is_a?(Hash)
76
+ old_key_value_hash.transform_keys!(&:to_s)
77
+
78
+ new_value.each do |key, value|
79
+ old_value = old_key_value_hash[key.to_s]
80
+
81
+ try do
82
+ new_value[key.to_s] = if [TrueClass, FalseClass].include?(old_value.class)
83
+ if value == "true"
84
+ true
85
+ elsif value == "false"
86
+ false
87
+ else
88
+ value
89
+ end
90
+ else
91
+ Kernel.public_send(old_value.class.name, value)
92
+ end
93
+ rescue
94
+ new_value[key.to_s] = value
95
+ end
96
+ end
97
+ end
98
+
72
99
  record.send(:"#{key}_will_change!") if record.respond_to?(:"#{key}_will_change!")
73
100
  record.send(:"#{key}=", new_value)
74
101
 
@@ -0,0 +1,13 @@
1
+ module Avo
2
+ module Fields
3
+ class StarsField < BaseField
4
+ attr_reader :max
5
+
6
+ def initialize(name, **args, &block)
7
+ super(name, **args, &block)
8
+
9
+ @max = args[:max] || 5
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,19 +1,18 @@
1
1
  module Avo
2
2
  module MediaLibrary
3
3
  class Configuration
4
- include ActiveSupport::Configurable
5
4
 
6
- config_accessor(:visible) { true }
7
- config_accessor(:enabled) { false }
5
+ class_attribute :visible, default: true
6
+ class_attribute :enabled, default: false
8
7
 
9
8
  def visible?
10
9
  return false if disabled?
11
10
 
12
- Avo::ExecutionContext.new(target: config[:visible]).handle
11
+ Avo::ExecutionContext.new(target: visible).handle
13
12
  end
14
13
 
15
14
  def enabled?
16
- Avo::ExecutionContext.new(target: config[:enabled]).handle
15
+ Avo::ExecutionContext.new(target: enabled).handle
17
16
  end
18
17
 
19
18
  def disabled? = !enabled?
data/lib/avo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "3.27.0" unless const_defined?(:VERSION)
2
+ VERSION = "3.29.0" unless const_defined?(:VERSION)
3
3
  end
@@ -1,6 +1,8 @@
1
1
  <div class="flex-1 flex p-4">
2
2
  <div class="place-self-end">
3
- Dashboard ID: <%%= @dashboard.id %>
3
+ @parent: <%%= @parent %><br />
4
+ @resource: <%%= @resource %><br />
5
+ @dashboard: <%%= @dashboard %>
4
6
  <br />
5
7
  <br />
6
8
  Customize this partial under <code class='p-1 rounded bg-gray-500 text-white text-sm'>app/views/avo/cards/_<%= name.underscore %>.html.erb</code>
@@ -51,6 +51,7 @@ ar:
51
51
  failed: فشل
52
52
  failed_to_find_attachment: فشل في العثور على المرفق
53
53
  failed_to_load: فشل التحميل
54
+ 'false': خطأ
54
55
  file:
55
56
  few: ملفات
56
57
  many: ملفات
@@ -126,6 +127,7 @@ ar:
126
127
  table_view: عرض الجدول
127
128
  this_field_has_attachments_disabled: هذا الحقل لديه المرفقات معطلة.
128
129
  tools: الأدوات
130
+ 'true': صحيح
129
131
  type_to_search: اكتب للبحث.
130
132
  unauthorized: غير مصرح به
131
133
  undo: تراجع
@@ -45,6 +45,7 @@ de:
45
45
  failed: Fehlgeschlagen
46
46
  failed_to_find_attachment: Anhang nicht gefunden
47
47
  failed_to_load: Laden fehlgeschlagen
48
+ 'false': Falsch
48
49
  file:
49
50
  one: Datei
50
51
  other: Dateien
@@ -116,6 +117,7 @@ de:
116
117
  table_view: Tabellenansicht
117
118
  this_field_has_attachments_disabled: Für dieses Feld sind Anhänge deaktiviert.
118
119
  tools: Werkzeuge
120
+ 'true': Wahr
119
121
  type_to_search: Tippen, um zu suchen.
120
122
  unauthorized: Nicht autorisiert
121
123
  undo: Rückgängig machen
@@ -45,6 +45,7 @@ en:
45
45
  failed: Failed
46
46
  failed_to_find_attachment: Failed to find attachment
47
47
  failed_to_load: Failed to load
48
+ 'false': 'False'
48
49
  file:
49
50
  one: file
50
51
  other: files
@@ -116,6 +117,7 @@ en:
116
117
  table_view: Table view
117
118
  this_field_has_attachments_disabled: This field has attachments disabled.
118
119
  tools: Tools
120
+ 'true': 'True'
119
121
  type_to_search: Type to search.
120
122
  unauthorized: Unauthorized
121
123
  undo: undo
@@ -47,6 +47,7 @@ es:
47
47
  failed: Fallo
48
48
  failed_to_find_attachment: No se ha encontrado el archivo adjunto
49
49
  failed_to_load: No se ha podido cargar
50
+ 'false': Falso
50
51
  file:
51
52
  one: archivo
52
53
  other: archivos
@@ -118,6 +119,7 @@ es:
118
119
  table_view: Vista en tabla
119
120
  this_field_has_attachments_disabled: Este campo tiene los adjuntos deshabilitados.
120
121
  tools: Herramientas
122
+ 'true': Verdadero
121
123
  type_to_search: Escribe para buscar.
122
124
  unauthorized: No autorizado
123
125
  undo: deshacer
@@ -47,6 +47,7 @@ fr:
47
47
  failed: Échec
48
48
  failed_to_find_attachment: Impossible de trouver la pièce jointe
49
49
  failed_to_load: Impossible de charger
50
+ 'false': Faux
50
51
  file:
51
52
  one: fichier
52
53
  other: fichiers
@@ -118,6 +119,7 @@ fr:
118
119
  table_view: Vue table
119
120
  this_field_has_attachments_disabled: Ce champ a les pièces jointes désactivées.
120
121
  tools: Outils
122
+ 'true': Vrai
121
123
  type_to_search: Type à rechercher.
122
124
  unauthorized: Non autorisé
123
125
  undo: annuler
@@ -45,6 +45,7 @@ it:
45
45
  failed: Fallito
46
46
  failed_to_find_attachment: Impossibile trovare l'allegato
47
47
  failed_to_load: Caricamento fallito
48
+ 'false': Falso
48
49
  file:
49
50
  one: file
50
51
  other: file
@@ -116,6 +117,7 @@ it:
116
117
  table_view: Vista tabella
117
118
  this_field_has_attachments_disabled: Gli allegati sono disabilitati per questo campo.
118
119
  tools: Strumenti
120
+ 'true': Vero
119
121
  type_to_search: Digita per cercare.
120
122
  unauthorized: Non autorizzato
121
123
  undo: Annulla
@@ -47,6 +47,7 @@ ja:
47
47
  failed: 失敗
48
48
  failed_to_find_attachment: アタッチメントを見つけるのに失敗
49
49
  failed_to_load: 読み込みに失敗
50
+ 'false': 偽
50
51
  file:
51
52
  one: ファイル
52
53
  other: ファイル
@@ -118,6 +119,7 @@ ja:
118
119
  table_view: テーブルビュー
119
120
  this_field_has_attachments_disabled: このフィールドには添付ファイルが無効になっています。
120
121
  tools: ツール
122
+ 'true': 真
121
123
  type_to_search: 検索する内容を入力してください。
122
124
  unauthorized: 許可されていません
123
125
  undo: 元に戻す