From 43e78047de8aac24126983c475af89c9f7e22816 Mon Sep 17 00:00:00 2001
From: Paul Bob <69730720+Paul-Bob@users.noreply.github.com>
Date: Fri, 17 May 2024 11:30:50 +0300
Subject: [PATCH] fix: boolean group field on actions (#2767)
* fix: boolean group field on actions
* lint
* drop record dependency
* lint
* performance tweak
* fix when empty or unselect all
* keep comment
* fix dummy action
* fix actions spec
---
.../edit_component.html.erb | 33 ++++++++-----------
.../boolean_group_field/edit_component.rb | 19 +++++++++++
lib/avo/fields/boolean_group_field.rb | 16 ++++-----
.../dummy/app/avo/actions/sub/dummy_action.rb | 10 ++++++
spec/system/avo/actions_spec.rb | 14 ++++++++
5 files changed, 63 insertions(+), 29 deletions(-)
diff --git a/app/components/avo/fields/boolean_group_field/edit_component.html.erb b/app/components/avo/fields/boolean_group_field/edit_component.html.erb
index b57d3ec0c9..7b0991b0ac 100644
--- a/app/components/avo/fields/boolean_group_field/edit_component.html.erb
+++ b/app/components/avo/fields/boolean_group_field/edit_component.html.erb
@@ -1,29 +1,22 @@
<%= field_wrapper **field_wrapper_args do %>
- <% model_param_key = model_name_from_record_or_class(@resource.record).param_key %>
- <%= check_box_tag "#{model_param_key}[#{@field.id}][]", '', true, { class: "hidden" } %>
<% @field.options.each do |id, label| %>
- <%
- checked = false
-
- # Get the state of the checkboxes from either the form that returns a validation error or from the model itself.
- if params[model_param_key].present? && params[model_param_key][@field.id.to_s].present?
- checked = params[model_param_key][@field.id.to_s].include?(id.to_s)
- else
- if @field.value.present?
- checked = @field.value[id.to_s]
- end
- end
- %>
<% end %>
diff --git a/app/components/avo/fields/boolean_group_field/edit_component.rb b/app/components/avo/fields/boolean_group_field/edit_component.rb
index cfe7d14078..c72252907a 100644
--- a/app/components/avo/fields/boolean_group_field/edit_component.rb
+++ b/app/components/avo/fields/boolean_group_field/edit_component.rb
@@ -1,4 +1,23 @@
# frozen_string_literal: true
class Avo::Fields::BooleanGroupField::EditComponent < Avo::Fields::EditComponent
+ def initialize(...)
+ super(...)
+
+ # Initilize here to avoid multiple calls to @field.get_html for each option.
+ @classes = "w-4 h-4 rounded checked:bg-primary-400 focus:checked:!bg-primary-400" \
+ "#{@field.get_html(:classes, view: view, element: :input)}"
+ @data = @field.get_html(:data, view: view, element: :input)
+ @style = @field.get_html(:style, view: view, element: :input)
+ @form_scope = @form.object_name
+ end
+
+ # Get the state of each checkboxe from either the form that returns a validation error or from the model itself.
+ def checked?(id)
+ if params[@form_scope].present? && params[@form_scope][@field.id.to_s].present?
+ params[@form_scope][@field.id.to_s].include?(id.to_s)
+ elsif @field.value.present?
+ @field.value[id.to_s]
+ end
+ end
end
diff --git a/lib/avo/fields/boolean_group_field.rb b/lib/avo/fields/boolean_group_field.rb
index 8158b3d3f6..2fd5abeb5a 100644
--- a/lib/avo/fields/boolean_group_field.rb
+++ b/lib/avo/fields/boolean_group_field.rb
@@ -21,23 +21,21 @@ def to_permitted_param
["#{id}": []]
end
- def fill_field(model, key, value, params)
+ def fill_field(record, _, values, _)
new_value = {}
- # Filter out the empty ("") value boolean group generates
- value = value.filter do |arr_value|
- arr_value.present?
- end
+ # Reject empty values passed by hidden inputs
+ values.reject! { |value| value == "" }
# Cast values to booleans
- options.each do |id, label|
- new_value[id] = value.include? id.to_s
+ options.each do |key, _|
+ new_value[key] = values.include? key.to_s
end
# Don't override existing values unless specified in options
- model[id] = (model[id] || {}).merge(new_value)
+ record[id] = (record[id] || {}).merge(new_value)
- model
+ record
end
end
end
diff --git a/spec/dummy/app/avo/actions/sub/dummy_action.rb b/spec/dummy/app/avo/actions/sub/dummy_action.rb
index 7d3784525e..716eb51f69 100644
--- a/spec/dummy/app/avo/actions/sub/dummy_action.rb
+++ b/spec/dummy/app/avo/actions/sub/dummy_action.rb
@@ -25,6 +25,14 @@ def fields
# get_type(Avo::App.request.referer) # strip the type from the referer string
"users"
end
+
+ field :fun_switch,
+ as: :boolean_group,
+ options: {
+ yes: "Yes",
+ sure: "Sure",
+ why_not: "Why not"
+ }
end
def handle(**args)
@@ -39,6 +47,8 @@ def handle(**args)
if arguments[:special_message]
succeed "I love 🥑"
+ elsif (fun_switch = args[:fields][:fun_switch].reject! { |option| option == "" }).any?
+ succeed "#{fun_switch.map(&:humanize).join(", ")}, I love 🥑"
else
succeed "Success response ✌️"
end
diff --git a/spec/system/avo/actions_spec.rb b/spec/system/avo/actions_spec.rb
index a4248e4ca4..baf7d7a45e 100644
--- a/spec/system/avo/actions_spec.rb
+++ b/spec/system/avo/actions_spec.rb
@@ -238,6 +238,20 @@
end
end
+ describe "fields" do
+ context "boolean group fields" do
+ it "pass through fields params" do
+ visit avo.resources_users_path
+
+ open_panel_action(action_name: "Dummy action")
+ check("fields_fun_switch_sure")
+
+ run_action
+ expect(page).to have_text "Sure, I love 🥑"
+ end
+ end
+ end
+
# let!(:roles) { { admin: false, manager: false, writer: false } }
# let!(:user) { create :user, active: true, roles: roles }