Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add multiselect option to dropdowns #10270

Merged
merged 7 commits into from
Feb 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions app/models/dialog.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,13 @@ def dialog_resources
end

def automate_values_hash
dialog_fields.each_with_object({}) { |df, result| result[df.automate_key_name] = df.automate_output_value }
dialog_fields.each_with_object({}) do |df, result|
if df.options.include?("multiple")
result[MiqAeEngine.create_automation_attribute_array_key(df.automate_key_name)] = df.automate_output_value
else
result[df.automate_key_name] = df.automate_output_value
end
end
end

def validate_children
Expand All @@ -61,7 +67,7 @@ def validate_children
next if dt.valid?
dt.errors.full_messages.each do |err_msg|
errors.add(:base, _("Dialog %{dialog_label} / %{error_message}") %
{:dialog_label => label, :error_message => err_msg})
{:dialog_label => label, :error_message => err_msg})
end
end
end
Expand All @@ -82,7 +88,7 @@ def validate_field_data
def init_fields_with_values(values)
dialog_field_hash.each do |key, field|
values[key] = field.value
field.dialog = self
field.dialog = self
end
dialog_field_hash.each { |key, field| values[key] = field.initialize_with_values(values) }
dialog_field_hash.each { |_key, field| field.update_values(values) }
Expand Down
49 changes: 49 additions & 0 deletions app/models/dialog_field_drop_down_list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,56 @@ def show_refresh_button?
!!show_refresh_button
end

def force_multi_value
return true if options[:force_multi_value].present? &&
options[:force_multi_value] != "null" &&
options[:force_multi_value]
end

def force_multi_value=(setting)
options[:force_multi_value] = setting
end

def initial_values
[[nil, "<None>"]]
end

def refresh_json_value(checked_value)
self.default_value = nil
@raw_values = nil

refreshed_values = values

selectbox_options = refreshed_values.collect { |value_pair| value_pair[0].to_s }

@value = if checked_value.kind_of?(Array) && (selectbox_options & checked_value).present?
# if checked value is [1,2,4] and the intersection is [1,2], removes non-valid option 4
# and does final check to make sure it's not returning [], otherwise, defaults
selectbox_options & checked_value
elsif selectbox_options.include?(checked_value)
# checks if [1,2,3].includes?(3)
checked_value
else
default_value
end
{:refreshed_values => refreshed_values, :checked_value => @value, :read_only => read_only?, :visible => visible?}
end

def automate_output_value
return super unless force_multi_value
a = if @value.kind_of?(Integer)
[@value]
elsif @value.kind_of?(Array)
@value
else
@value.blank? ? [] : @value.chomp.split(',')
end
automate_values = a.first.kind_of?(Integer) ? a.map(&:to_i) : a
MiqAeEngine.create_automation_attribute_array_value(automate_values)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mkanoor Can you verify that this is going to pass data to the automate engine as expect? This is the last part before merging this feature.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gmcculloug @d-m-u
MiqAeEngine.create_automation_attribute_array_value([1,2,3]) => gives you back 1,2,3

For Automate to use it as an array the keyname should be prefixed with Array::

We have a helper method that does that
MiqAeEngine.create_automation_attribute_array_key("my_key")
which returns Array::my_key

You have to use the key and value together

In https://github.com/ManageIQ/manageiq/blob/master/app/models/dialog.rb#L50
We would have to detect that if it is a multi value field it should use

result[MiqAeEngine.create_automation_attribute_array_key(df.automate_key_name)] = df.automate_output_value

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fixed this Sunday at 8:05 Mahwah time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@d-m-u Along with overriding the automate_output_value you need to override automate_key_name like we do here app/models/dialog_field_tag_control.rb#L78.

You need the same check for force_multi_value as above.

Something like this:

def automate_key_name
  return super unless force_multi_value
  MiqAeEngine.create_automation_attribute_array_key(super)
end

end

def automate_key_name
return super unless force_multi_value
MiqAeEngine.create_automation_attribute_array_key(super)
end
end
143 changes: 108 additions & 35 deletions spec/models/dialog_field_drop_down_list_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,51 +92,75 @@
describe "#refresh_json_value" do
let(:dialog_field) { described_class.new(:dynamic => dynamic, :read_only => true) }

context "when the dialog_field is dynamic" do
context "dynamic" do
let(:dynamic) { true }

before do
allow(DynamicDialogFieldValueProcessor).to receive(:values_from_automate).with(dialog_field).and_return(
[["123", 456], ["789", 101]]
)
dialog_field.value = "123"
context "array" do
context "included" do
# TODO
end
context "not-included" do
# TODO
end
end

it "sets the value" do
dialog_field.refresh_json_value("789")
expect(dialog_field.value).to eq("789")
end
context "not-array" do
before do
allow(DynamicDialogFieldValueProcessor).to receive(:values_from_automate).with(dialog_field).and_return(
[["123", 456], ["789", 101]]
)
dialog_field.value = "123"
end

it "returns the values from automate" do
expect(dialog_field.refresh_json_value("789")).to eq(
:refreshed_values => [["789", 101], ["123", 456]],
:checked_value => "789",
:read_only => true,
:visible => true
)
it "sets the value" do
dialog_field.refresh_json_value("789")
expect(dialog_field.value).to eq("789")
end

it "returns the values from automate" do
expect(dialog_field.refresh_json_value("789")).to eq(
:refreshed_values => [["789", 101], ["123", 456]],
:checked_value => "789",
:read_only => true,
:visible => true
)
end
end
end

context "when the dialog_field is not dynamic" do
context "non-dynamic" do
let(:dynamic) { false }

before do
dialog_field.values = [["123", 456], ["789", 101]]
dialog_field.value = "123"
end

it "sets the value" do
dialog_field.refresh_json_value("789")
expect(dialog_field.value).to eq("789")
context "array" do
context "included" do
# TODO
end
context "not-included" do
# TODO
end
end

it "returns the values" do
expect(dialog_field.refresh_json_value("789")).to eq(
:refreshed_values => [["789", 101], ["123", 456]],
:checked_value => "789",
:read_only => true,
:visible => true
)
context "not-array" do
context "when the dialog_field is not dynamic" do
let(:dynamic) { false }

before do
dialog_field.values = [["123", 456], ["789", 101]]
dialog_field.value = "123"
end

it "sets the value" do
dialog_field.refresh_json_value("789")
expect(dialog_field.value).to eq("789")
end

it "returns the values" do
expect(dialog_field.refresh_json_value("789")).to eq(
:refreshed_values => [["789", 101], ["123", 456]],
:checked_value => "789",
:read_only => true,
:visible => true
)
end
end
end
end
end
Expand Down Expand Up @@ -181,6 +205,55 @@
end
end

context "dialog field dropdown without options hash" do
before do
@df = FactoryGirl.create(:dialog_field_drop_down_list, :name => 'test drop down')
end

describe "#force_multi_value" do
context "when force_multi_value is present" do
context "when force_multi_value is null" do
it "multivalue false" do
expect(@df.force_multi_value).to be_falsey
end
end

context "when force_multi_value is not null" do
context "when force_multi_value is truthy" do
it "multivalue true" do
@df.force_multi_value = true
expect(@df.force_multi_value).to be_truthy
end
end

context "when force_multi_value is falsy" do
it "multivalue false" do
expect(@df.force_multi_value).to be_falsey
end
end
end
end

context "when force_multi_value is not present" do
it "multivalue false" do
expect(@df.force_multi_value).to be_falsey
end
end
end
end

context "dialog field dropdown with options hash" do
before do
@df = FactoryGirl.create(:dialog_field_drop_down_list,
:name => 'test drop down',
:options => {:force_multi_value => true})
end

it "#force_multi_value" do
expect(@df.force_multi_value).to be_truthy
end
end

context "when the raw values are not already set" do
before do
dialog_field.values = %w(original values)
Expand Down