Skip to content

Commit

Permalink
fix: boolean group field on actions (#2767)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Paul-Bob authored May 17, 2024
1 parent 5fe1921 commit 43e7804
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -1,29 +1,22 @@
<%= field_wrapper **field_wrapper_args do %>
<div class="flex items-center">
<div class="space-y-2">
<% 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
%>
<label class="block">
<%= check_box_tag "#{model_param_key}[#{@field.id}][]", id, checked, {
class: "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),
<%= @form.check_box @field.id,
{
class: @classes,
data: @data,
disabled: disabled?,
id: "#{model_param_key}_#{@field.id}_#{id}",
style: @field.get_html(:style, view: view, element: :input)
} %> <%= label %>
id: "#{@form_scope}_#{@field.id}_#{id}",
style: @style,
multiple: true,
checked: checked?(id)
},
id,
""
%>
<%= label %>
</label>
<% end %>
</div>
Expand Down
19 changes: 19 additions & 0 deletions app/components/avo/fields/boolean_group_field/edit_component.rb
Original file line number Diff line number Diff line change
@@ -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
16 changes: 7 additions & 9 deletions lib/avo/fields/boolean_group_field.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions spec/dummy/app/avo/actions/sub/dummy_action.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down
14 changes: 14 additions & 0 deletions spec/system/avo/actions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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 }

Expand Down

0 comments on commit 43e7804

Please sign in to comment.